@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
@@ -0,0 +1,30 @@
1
+ // SPDX-License-Identifier: AGPL-3.0-or-later
2
+ /** The part of a key event's target this reads — an `Element` satisfies it; `window`/`document` have no `closest`. */
3
+ export interface KeyTargetLike {
4
+ readonly isContentEditable?: boolean;
5
+ closest?(selector: string): unknown;
6
+ }
7
+ /** The keys a focused button answers natively: Enter presses it on the key's press, Space on its release. */
8
+ export declare const BUTTON_ACTIVATION_KEYS: ReadonlySet<string>;
9
+ /**
10
+ * Whether a key pressed with the focus on `target` is being typed into a field — input, textarea, select or contenteditable, in
11
+ * the game region or anywhere on the page. Then every key is the field's: Enter and every character.
12
+ *
13
+ * 📌 ASKED BY THE ENGINE'S SYSTEM KEYS TOO, and not only by the delivery. START and SELECT never reach play, so they never pass
14
+ * through `keyGoesToGame`: their own listeners (`boot/create-game`) ask this. 📏 Before they did, Enter typed into a text field
15
+ * opened the quick pause, and «half» typed into one paused on the `h` and opened the menus on the `f`.
16
+ */
17
+ export declare function keyTypedIntoField(target: KeyTargetLike | null): boolean;
18
+ /**
19
+ * Whether the key `code` presses the engine's own control that has the focus (`ownControls`, a selector): Space or Enter on it.
20
+ *
21
+ * 📌 ASKED BY THE QUICK PAUSE TOO, and not only by the delivery. `Enter` is `start`, and START in play opens the quick pause — so
22
+ * Enter on a focused ☰ paused instead of pressing ☰, while Space pressed it (📏 measured on the served quiz). A focused button is
23
+ * activated by Enter as well as Space; that press is the button's, and the pause does not take it.
24
+ */
25
+ export declare function keyPressesOwnControl(code: string, target: KeyTargetLike | null, ownControls: string): boolean;
26
+ /**
27
+ * Whether the key `code`, pressed with the focus on `target`, is play's to hear. `false`: it belongs to what has the focus — a
28
+ * field, or the engine's own control it activates (`ownControls`, a selector) — and keeps its default.
29
+ */
30
+ export declare function keyGoesToGame(code: string, target: KeyTargetLike | null, ownControls: string): boolean;
@@ -0,0 +1,60 @@
1
+ // SPDX-License-Identifier: AGPL-3.0-or-later
2
+ // input/key-default — WHICH KEY THE GAME HEARS, AND WHICH KEEPS ITS BROWSER DEFAULT (ADR-0111 errata of 2026-09-26).
3
+ //
4
+ // The engine owns the keyboard (ADR-0111): it turns a key into a position and carries the position to the game. One key press
5
+ // is one action, and that makes two rules, which are one rule seen from two sides:
6
+ // · A KEY THE GAME HEARD IS SPENT. The keyboard conductor cancels its default, or Space on a focused `<button>` was the game's
7
+ // `action2` AND the button's click on the release.
8
+ // · A KEY THAT WENT TO SOMETHING ELSE IS NOT ALSO PLAYED. It keeps its default, and the game does not hear it. That is what
9
+ // this module answers, before the engine delivers:
10
+ // · a key typed into an editable field (input, textarea, select, contenteditable): typing is the field's;
11
+ // · a key that ACTIVATES one of the engine's own focused controls (`ownControls`, the accessibility bar, in the tab order
12
+ // in play): Space and Enter press a focused button, and that press is the control's.
13
+ // 📏 Both used to keep their default AND be delivered. On the served quiz, Space on ☰ opened the menus and answered a
14
+ // question; Space typed into a text field answered one too.
15
+ //
16
+ // 📌 ONLY THE ACTIVATION KEYS on the engine's control, and not every key: a focused button does nothing native with an arrow or
17
+ // a letter, so an arrow pressed after Tab left the focus on ☰ is still the child moving in the game — held back, it would be
18
+ // lost, and the game would stop answering until she clicked somewhere else.
19
+ //
20
+ // Not decided here: a key refused by an open menu, or consumed by the engine's menus, is the menus' (`input/virtual-controller`,
21
+ // `ui/menu-nav`); a key mapped to no position was never the game's.
22
+ //
23
+ // Pure: it is told the key and where the focus was; it answers a decision. No document, no event.
24
+ const EDITABLE = 'input, textarea, select';
25
+ /** The keys a focused button answers natively: Enter presses it on the key's press, Space on its release. */
26
+ export const BUTTON_ACTIVATION_KEYS = new Set(['Space', 'Enter', 'NumpadEnter']);
27
+ /**
28
+ * Whether a key pressed with the focus on `target` is being typed into a field — input, textarea, select or contenteditable, in
29
+ * the game region or anywhere on the page. Then every key is the field's: Enter and every character.
30
+ *
31
+ * 📌 ASKED BY THE ENGINE'S SYSTEM KEYS TOO, and not only by the delivery. START and SELECT never reach play, so they never pass
32
+ * through `keyGoesToGame`: their own listeners (`boot/create-game`) ask this. 📏 Before they did, Enter typed into a text field
33
+ * opened the quick pause, and «half» typed into one paused on the `h` and opened the menus on the `f`.
34
+ */
35
+ export function keyTypedIntoField(target) {
36
+ if (!target || typeof target.closest !== 'function')
37
+ return false;
38
+ return !!target.isContentEditable || !!target.closest(EDITABLE);
39
+ }
40
+ /**
41
+ * Whether the key `code` presses the engine's own control that has the focus (`ownControls`, a selector): Space or Enter on it.
42
+ *
43
+ * 📌 ASKED BY THE QUICK PAUSE TOO, and not only by the delivery. `Enter` is `start`, and START in play opens the quick pause — so
44
+ * Enter on a focused ☰ paused instead of pressing ☰, while Space pressed it (📏 measured on the served quiz). A focused button is
45
+ * activated by Enter as well as Space; that press is the button's, and the pause does not take it.
46
+ */
47
+ export function keyPressesOwnControl(code, target, ownControls) {
48
+ if (!target || typeof target.closest !== 'function')
49
+ return false;
50
+ return BUTTON_ACTIVATION_KEYS.has(code) && !!target.closest(ownControls);
51
+ }
52
+ /**
53
+ * Whether the key `code`, pressed with the focus on `target`, is play's to hear. `false`: it belongs to what has the focus — a
54
+ * field, or the engine's own control it activates (`ownControls`, a selector) — and keeps its default.
55
+ */
56
+ export function keyGoesToGame(code, target, ownControls) {
57
+ if (!target || typeof target.closest !== 'function')
58
+ return true; // no element had the focus: nothing else to go to
59
+ return !keyTypedIntoField(target) && !keyPressesOwnControl(code, target, ownControls);
60
+ }
@@ -2,25 +2,21 @@
2
2
  import type { ControlledPlayer } from '../core/entity.js';
3
3
  import type { KeyScheme } from '../core/entity.js';
4
4
  import type { KBDefaults } from '../input/keyboard.js';
5
- /** action -> list of physical key codes (KeyboardEvent.code), e.g. {jump:['KeyJ','Space']}. Mirrors the shape
6
- * ui/settings-controls.ts also defines locally (input/keyboard.ts's KeyScheme is not exported — each consumer
7
- * keeps its own structural copy rather than reaching across layers for a type alias). */
8
- export type { KeyScheme } from '../core/entity.js';
9
- /** input/keyboard.ts's KBDefaults shape ({solo,p2,p3,p4}) — the live `KB` value in game.js. */
10
- /** O `KBDefaults` de `input/keyboard`, que é o dono. O nome local sobrevive porque os consumidores o usam. */
5
+ /** `input/keyboard`'s `KBDefaults` ({solo,p2,p3,p4}), which owns it. The local name survives because consumers use it. */
11
6
  export type KeyboardConfig = KBDefaults;
12
7
  /** Minimal player shape this module needs: only `ctrl` is read/written — derived from core/entity.
13
8
  * `ControlledPlayer` rather than `Player` because this module runs after assignControls, so `ctrl` is no
14
9
  * longer null. That was already assumed here; now it is stated. */
15
10
  export type KeyboardRuntimePlayer = Pick<ControlledPlayer, 'ctrl'>;
16
11
  export interface KeyboardRuntimeCtx {
17
- /** The live keyboard config (game.js's `KB`), read fresh on every call — never cached. */
12
+ /** The live keyboard config, read fresh on every call — never cached. */
18
13
  getKB(): KeyboardConfig;
19
- /** Current player count (core/state.ts's `numPlayers`, read live via game.js). */
14
+ /** The current player count, read live. */
20
15
  getNumPlayers(): number;
21
- /** The live players array (core/state.ts's `players`, mutated in place — never reassigned). */
16
+ /** The live players array (mutated in place — never reassigned). */
22
17
  getPlayers(): KeyboardRuntimePlayer[];
23
18
  }
19
+ /** The controls state as a value: player 1's `controls` + its per-action aliases + the flattened list of game keys. */
24
20
  export interface ControlsState {
25
21
  controls: KeyScheme;
26
22
  action2: readonly string[];
@@ -32,24 +28,22 @@ export interface ControlsState {
32
28
  gameKeys: string[];
33
29
  }
34
30
  export interface KeyboardRuntime {
35
- /** The key scheme for player `playerIndex`, given the current KB config + player count (game.js's kbFor). */
31
+ /** The key scheme for player `playerIndex`, given the current config + player count. */
36
32
  kbFor(playerIndex: number): KeyScheme;
37
- /** Which action (if any) `code` triggers FOR that player, given their scheme (game.js's actionOf). */
33
+ /** Which action (if any) `code` triggers FOR that player, given their scheme. */
38
34
  actionOf(code: string, playerIndex: number): string | null;
39
- /** Which player (0-based) owns `code` among the active players; -1 if none (game.js's whichPlayer). */
35
+ /** Which player (0-based) owns `code` among the active players; -1 if none. */
40
36
  whichPlayer(code: string): number;
41
- /** Propagates `kb` -> each active player's `p.ctrl`, mutated in place (game.js's assignControls). */
37
+ /** Propagates the config -> each active player's `p.ctrl`, mutated in place. */
42
38
  assignControls(): void;
43
- /** Computes the P1-alias `controls` + `GAME_KEYS` (game.js's applyControls, minus the reassignment). */
39
+ /** Computes player 1's `controls` alias + the game keys. */
44
40
  computeControlsState(): ControlsState;
45
- /** O estado ATUAL, memorizado. Antes eram oito `let` no game.js (`controls`, `KJUMP`..`KRUN`, `GAME_KEYS`)
46
- * copiados de `computeControlsState()` por um `applyControls()` que existia só para fazer a cópia. Eram
47
- * derivados de `KB` + `players`, guardados em variável — a forma de estado que mais apodrece, porque nada
48
- * obriga a cópia a acompanhar a origem. Aqui a memória fica com quem é dono da conta, e a invalidação é
49
- * explícita e única: `refreshControls()`. NÃO recalcula a cada leitura de propósito — recalcular mudaria
50
- * o comportamento (passaria a enxergar remapeamento que ainda não foi aplicado), e isto é refatoração. */
41
+ /** The CURRENT state, memoised. It was a set of copies kept in variables, derived from the config + players — the
42
+ * kind of state that rots fastest, because nothing forces a copy to follow its source. Here the memo stays with
43
+ * whoever owns the sum, and invalidating it is explicit and single: `refreshControls()`. It does NOT recompute on
44
+ * every read, on purpose — that would change behaviour (it would see a remap not applied yet). */
51
45
  controlsState(): ControlsState;
52
- /** Recalcula e memoriza. É o `applyControls()` do game.js, agora do lado de cá. */
46
+ /** Recomputes and memoises. */
53
47
  refreshControls(): ControlsState;
54
48
  }
55
49
  /** Which action does `code` trigger in this ONE scheme? Pure — no player/KB involved. */
@@ -1,17 +1,14 @@
1
1
  // SPDX-License-Identifier: AGPL-3.0-or-later
2
2
  // input/keyboard-runtime.ts — keyboard ROUTING at play time: which key belongs to which player, which action
3
- // it fires. Extracted from game.js (kbFor/actionOf/whichPlayer/assignControls/applyControls). Pure logic, DI
4
- // via initKeyboardRuntime(ctx): reads the live KB config (input/keyboard.ts owns load/save/reset) and the live
5
- // numPlayers/players (still in game.js) through injected getters — never imports game.js, never touches
6
- // `document`. KJUMP/KLEFT/.../GAME_KEYS come back as a plain VALUE object (computeControlsState) instead of
7
- // being reassigned here: imported bindings can't be reassigned from outside their own module, so the game.js
8
- // wrapper is the one that copies the returned fields onto its own `let`s (same trap `core/state.ts` documents
9
- // for `coins`/`players`).
3
+ // it fires. Extracted from the monolith (kbFor/actionOf/whichPlayer/assignControls/applyControls). Pure logic, DI
4
+ // via initKeyboardRuntime(ctx), which `boot/create-game` calls: reads the live KB config (input/keyboard.ts owns
5
+ // load/save/reset) and the live player count and players through injected getters — never imports the composition
6
+ // root, never touches `document`. The per-action aliases and GAME_KEYS come back as a plain VALUE object
7
+ // (`ControlsState`) instead of exported `let`s, because imported bindings can't be reassigned from outside their own
8
+ // module; `controlsState()` memoises it and `refreshControls()` is the one way to recompute it.
10
9
  import { ACTIONS } from '../core/actions.js';
11
- /** Result of the old `applyControls()` mutation, as a value: `controls` + its per-action aliases (game.js's
12
- * KJUMP/KLEFT/KRIGHT/KUP/KDOWN/KRUN) + the flattened `GAME_KEYS` list. */
13
- /** A lista que uma posição SEM ALCANCE devolve. Congelada e partilhada: ninguém deve escrever nela. */
14
- const VAZIO = Object.freeze([]);
10
+ /** The list a position WITH NO REACH returns. Frozen and shared: nobody may write to it. */
11
+ const EMPTY = Object.freeze([]);
15
12
  // ---------------------------------------------------------------------------------------------
16
13
  // Pure logic (no ctx, no `document` — directly testable with plain KeyScheme fixtures)
17
14
  // ---------------------------------------------------------------------------------------------
@@ -19,10 +16,10 @@ const VAZIO = Object.freeze([]);
19
16
  * (mirrors ui/settings-controls.ts's keyUsedByOther: a Map built over the scheme, not a re-scan per query). */
20
17
  function buildActionIndex(scheme) {
21
18
  const index = new Map();
22
- // ⚠️ O LAÇO PASSOU A SER SOBRE `ACTIONS` E NÃO SOBRE AS CHAVES DO OBJETO (issue #118). São a mesma lista
23
- // agora que o `KeyScheme` é fechado — mas percorrer `ACTIONS` diz QUAL é a lista, e um esquema que ganhe
24
- // uma chave a mais por engano deixa de a ver. E o `?? []` é o que trata a AUSÊNCIA DECLARADA: um `null`
25
- // não é um esquema partido, é um teclado que não alcança aquela posição.
19
+ // ⚠️ THE LOOP IS OVER `ACTIONS` AND NOT OVER THE OBJECT'S KEYS (issue #118). They are the same list now that
20
+ // `KeyScheme` is closed — but walking `ACTIONS` says WHICH list it is, and a scheme that gains an extra key by mistake
21
+ // no longer sees it. And `?? []` handles the DECLARED ABSENCE: a `null` is not a broken scheme, it is a keyboard that
22
+ // does not reach that position.
26
23
  for (const action of ACTIONS) {
27
24
  for (const code of scheme[action] ?? []) {
28
25
  if (!index.has(code))
@@ -73,18 +70,17 @@ export function initKeyboardRuntime(ctx) {
73
70
  }
74
71
  function computeControlsState() {
75
72
  const kb = ctx.getKB();
76
- const controls = kb.solo; // alias do P1 — SEMPRE kb.solo, mesmo com numPlayers>1 (comportamento original; ver relato)
77
- // Os apelidos são LISTAS, nunca `null`: quem os lê faz `.includes(code)` sem perguntar. Uma posição que o
78
- // esquema não alcança vira lista vazia aqui — «não alcança» e «alcança com zero teclas» valem o mesmo
79
- // para quem só pergunta se a tecla está lá.
73
+ const controls = kb.solo; // player 1's alias — ALWAYS kb.solo, even with more players (the original behaviour)
74
+ // The aliases are LISTS, never `null`: whoever reads them does `.includes(code)` without asking. A position the
75
+ // scheme does not reach becomes an empty list here — "does not reach" and "reaches with zero keys" are worth the
76
+ // same to whoever only asks whether the key is there.
80
77
  //
81
- // ⚠️ E DEVOLVE A MESMA REFERÊNCIA, não uma cópia. A primeira versão fazia `[...]` e um caso reprovou por
82
- // identidade — corretamente: o apelido é o alias do P1, e um teste que afirma «é o mesmo array» está a
83
- // afirmar que ninguém interpôs uma cópia entre o esquema vivo e quem o lê. Copiar aqui não custaria nada
84
- // hoje e passaria a custar no dia em que alguém mutasse a lista no lugar.
85
- const lista = (a) => controls[a] ?? VAZIO;
86
- const action2 = lista('action2'), left = lista('left'), right = lista('right');
87
- const up = lista('up'), down = lista('down'), action1 = lista('action1');
78
+ // ⚠️ AND IT RETURNS THE SAME REFERENCE, not a copy. A case asserts "it is the same array", which is asserting that
79
+ // nobody put a copy between the live scheme and its reader. Copying would cost nothing today and would start costing
80
+ // the day someone mutated the list in place.
81
+ const list = (a) => controls[a] ?? EMPTY;
82
+ const action2 = list('action2'), left = list('left'), right = list('right');
83
+ const up = list('up'), down = list('down'), action1 = list('action1');
88
84
  const gameKeySet = new Set();
89
85
  ctx.getPlayers().forEach((_, i) => {
90
86
  const scheme = kbFor(i);
@@ -95,7 +91,7 @@ export function initKeyboardRuntime(ctx) {
95
91
  const gameKeys = gameKeySet.size ? [...gameKeySet] : [...action2, ...left, ...right, ...up, ...down];
96
92
  return { controls, action2, left, right, up, down, action1, gameKeys };
97
93
  }
98
- let cache = null; // memória do estado derivado; só refreshControls a invalida
94
+ let cache = null; // the derived state's memo; only refreshControls invalidates it
99
95
  function controlsState() { return cache ?? (cache = computeControlsState()); }
100
96
  function refreshControls() { cache = computeControlsState(); return cache; }
101
97
  return { kbFor, actionOf, whichPlayer, assignControls, computeControlsState, controlsState, refreshControls };
@@ -1,17 +1,22 @@
1
1
  // SPDX-License-Identifier: AGPL-3.0-or-later
2
+ import type { Store } from '../platform/storage.js';
2
3
  import type { KeyScheme } from '../core/entity.js';
3
- export type { KeyScheme } from '../core/entity.js';
4
4
  /**
5
- * O CONJUNTO DE ESQUEMAS de teclado — solo mais os de 2, 3 e 4 jogadores.
5
+ * What the key map is read and written through: the page's store (ADR-0232, issue #207). A PARAMETER of each function that
6
+ * touches it, not a module import — a test hands in its own, and two roots never write each other's map.
7
+ */
8
+ export type KeyboardStore = Pick<Store, 'getJSON' | 'setJSON' | 'remove'>;
9
+ /**
10
+ * THE SET OF keyboard SCHEMES — solo plus those for 2, 3 and 4 players.
6
11
  *
7
- * Exportado desde 2026-08-26, e o motivo é que ele já era copiado: `input/keyboard-runtime` e
8
- * `ui/settings-controls` declaravam cada um o seu `KeyboardConfig`, e AMBOS diziam no comentário que
9
- * era "a forma do KBDefaults de input/keyboard". Sabiam que eram cópia e copiavam mesmo assim.
12
+ * Exported because it was already being copied: `input/keyboard-runtime` and `ui/settings-controls` each
13
+ * declared their own `KeyboardConfig`, and BOTH said in a comment it was "the shape of input/keyboard's
14
+ * KBDefaults". They knew they were a copy and copied anyway.
10
15
  *
11
- * A de `settings-controls` era `Record<string, unknown>` — pensada como opaca, para o módulo não
12
- * depender da forma. Mas em posição de PARÂMETRO isso se inverte: para aceitar `(next: KBDefaults)`,
13
- * o tipo declarado tem de ser SUBTIPO, não supertipo. A opacidade se preserva por disciplina — não
14
- * indexar o valor — e não por escrever um tipo mais largo (ADR-0039).
16
+ * The `settings-controls` one was `Record<string, unknown>` — meant as opaque, so the module would not depend on
17
+ * the shape. But in PARAMETER position that inverts: to accept `(next: KBDefaults)`, the declared type has to be
18
+ * a SUBTYPE, not a supertype. Opacity is kept by discipline — not indexing the value — and not by writing a wider
19
+ * type (ADR-0039).
15
20
  */
16
21
  export type KBDefaults = {
17
22
  solo: KeyScheme;
@@ -19,69 +24,69 @@ export type KBDefaults = {
19
24
  p3: KeyScheme[];
20
25
  p4: KeyScheme[];
21
26
  };
22
- export declare const KB_SCHEMES4: KeyScheme[];
23
27
  /**
24
- * ⚠️ AS DUAS TABELAS DE TECLADO PASSARAM A SER UMA (issue #118). O solo e a dupla já não são escritos aqui:
25
- * são CÓPIAS VIVAS do que `input/default-bindings` declara, que é onde o ADR-0096 pôs a decisão.
28
+ * ⚠️ THE TWO KEYBOARD TABLES BECAME ONE (issue #118). Solo and duo are no longer written here: they are LIVE
29
+ * COPIES of what `input/default-bindings` declares, which is where ADR-0096 put the decision.
26
30
  *
27
- * Antes eram duas listas paralelas com oito posições cada, e as oito «coincidiam» — menos uma. A `Space` do
28
- * jogador 1 em dupla estava numa e não na outra, e o custo era concreto: `ui/webcam.ts` sintetiza `Space`
29
- * para «olhar para cima = pular», então entrar um segundo jogador tirava o PULO de quem joga com os olhos e
30
- * deixava o andar. Nada errava em voz alta. Derivar em vez de repetir torna essa divergência impossível de
31
- * voltar a existir, em vez de a apanhar depois de acontecer.
31
+ * They used to be two parallel lists of eight positions each, and all eight "matched" — but one. Player 1's
32
+ * `Space` in duo was in one list and not the other, and the cost was concrete: the webcam control of the time
33
+ * synthesised `Space` for "look up = jump", so a second player joining took JUMP away from whoever played with
34
+ * their eyes and left walking. Nothing failed out loud. Deriving instead of repeating makes that divergence
35
+ * impossible to come back, instead of catching it after it happens.
32
36
  */
33
37
  export declare const KB_DEFAULTS: KBDefaults;
34
38
  /**
35
- * O PADRÃO QUE O JOGO QUER, por número de jogadores e por assento (ADR-0115). Parcial: o que ele não disser
36
- * fica como a fábrica da engine o deixou.
37
- */
38
- export type MapeamentoDoTeclado = (jogadores: number, assento: number) => Partial<KeyScheme> | null;
39
- /**
40
- * REGISTA O PADRÃO DO JOGO. Chamado uma vez pelo arranque (`boot/create-game`), a partir da declaração.
41
- *
42
- * 🔴 REGISTO E NÃO PARÂMETRO, e a razão é um defeito medido em vez de uma preferência. Há DOIS sítios que
43
- * materializam padrões — `loadKB` e `resetKB` — e o segundo é chamado pelo painel de controles, que não tem a
44
- * declaração do jogo à mão. Um parâmetro que o painel não passasse faria «restaurar padrões» devolver o mapa
45
- * da ENGINE por cima do mapa do JOGO: a criança carrega no botão esperando voltar ao que o jogo lhe deu, e
46
- * volta para outra coisa — num jogo cujo autor escolheu o layout por uma razão de acessibilidade, ela perde
47
- * essa razão e nada o diz.
48
- *
49
- * 📌 É a mesma forma que o `kb` deste ficheiro já tem, e pela mesma justificação: o dono é evidente, e as
50
- * funções que o gerem vivem todas aqui.
51
- */
52
- export declare function registrarMapeamentoDoTeclado(f: MapeamentoDoTeclado | null): void;
53
- /**
54
- * A FÁBRICA COM O PADRÃO DO JOGO POR CIMA — a **única** resolução, usada pelo `loadKB` E pelo `resetKB`.
55
- *
56
- * ⚠️ Uma função só, e é o ponto inteiro: enquanto eram duas cópias do `JSON.parse(JSON.stringify(...))`, a do
57
- * `resetKB` não conhecia o jogo e a diferença só aparecia quando uma criança carregava em «restaurar».
39
+ * THE DEFAULT THE GAME WANTS, per player count and per seat (ADR-0115). Partial: whatever it does not say stays
40
+ * as the engine's factory left it.
58
41
  */
59
- export declare function fabricaComOJogo(): KBDefaults;
60
- export declare function loadKB(): KBDefaults;
61
- export declare function saveKB(kb: KBDefaults): void;
42
+ export type KeyboardMapping = (players: number, seat: number) => Partial<KeyScheme> | null;
62
43
  /**
63
- * O MAPA DE TECLAS VIVO. Migrado do composition root (#50): era um `let KB` do main.js com um envoltório
64
- * `setKB: (k) => { KB = k; }` fabricado à mão para o painel de controles reatribuí-lo.
65
- *
66
- * Mora AQUI, e não em core/state como os outros migrados, porque o dono é evidente: `loadKB`, `saveKB` e
67
- * `resetKB` já viviam neste arquivo. Separar o valor das três funções que o gerenciam seria mover o problema
68
- * de lugar em vez de resolvê-lo.
44
+ * THE FACTORY WITH THE GAME'S DEFAULT ON TOP — the **only** resolution, used by `loadKB` AND by the reset.
69
45
  *
70
- * NASCE COM OS PADRÕES E NÃO LÊ DISCO NO IMPORT. `initKB()` é quem lê, chamado uma vez pelo boot. A regra vale
71
- * para todo módulo do projeto, e aqui ela tem um custo concreto se for quebrada: um teste que importe qualquer
72
- * coisa deste arquivo passaria a depender do localStorage do ambiente, e um mapa de teclas herdado de outro
73
- * caso é uma falha que aparece longe da causa.
46
+ * ⚠️ One function, and that is the whole point: while there were two copies of `JSON.parse(JSON.stringify(...))`,
47
+ * the reset's did not know the game, and the difference only showed when a child pressed "restore".
48
+ * 📌 The mapping is a PARAMETER, `null` for a game with no opinion (ADR-0232 D4): as a module registration a second
49
+ * root would overwrite the first root's (D2b erratum). What once justified the registration — the controls panel
50
+ * resetting without the game's declaration at hand — is answered by `createKeyboardConfig`, which receives the
51
+ * mapping once and hands the panel a reset that already knows it.
74
52
  */
75
- export declare let kb: KBDefaults;
76
- /** Lê o mapa persistido para dentro de `kb`. O boot chama uma vez; devolve o valor para quem quiser encadear. */
77
- export declare function initKB(): KBDefaults;
78
- /** Troca o mapa inteiro. Só o "restaurar padrões" do painel de controles precisa disto — remapear uma tecla
79
- * MUTA o objeto, e reatribuir por engano faria as referências vivas apontarem para o mapa antigo. */
80
- export declare function setKB(next: KBDefaults): void;
53
+ export declare function factoryWithGame(mapping: KeyboardMapping | null): KBDefaults;
54
+ export declare function loadKB(store: KeyboardStore, mapping: KeyboardMapping | null): KBDefaults;
55
+ export declare function saveKB(store: KeyboardStore, kb: KBDefaults): void;
56
+ /** What one root's keyboard config is built from (ADR-0232 D4). Both required: see `createKeyboardConfig`. */
57
+ export interface KeyboardConfigOptions {
58
+ /** Where the child's remapping is kept — the page's store, built by the root. */
59
+ readonly store: KeyboardStore;
60
+ /** The GAME's default, `null` for a game with no opinion. Read on every factory resolution, so a root that mounts
61
+ * another cartridge can answer with the mounted one's. */
62
+ readonly mapping: KeyboardMapping | null;
63
+ }
64
+ /** ONE ROOT'S LIVE KEY MAP and the doors that manage it — what `Engine.keyboardConfig` is. */
65
+ export interface KeyboardConfigApi {
66
+ /** THE LIVE KEY MAP (#50). Remapping one key MUTATES this object; `set` is the only way to replace it. */
67
+ kb(): KBDefaults;
68
+ /** Replaces the whole map. Only "restore defaults" needs this — reassigning by mistake would leave live references
69
+ * pointing at the old map. */
70
+ set(next: KBDefaults): void;
71
+ /** Stores `conf` (the live map when omitted) in the store. */
72
+ save(conf?: KBDefaults): void;
73
+ /**
74
+ * "RESTORE DEFAULTS" — erases what the child stored and returns the GAME's default, not the engine's (ADR-0115).
75
+ * 🔴 Resetting to the engine's factory alone would silently erase the mapping the game chose. It does NOT replace
76
+ * the live map: the caller decides (`set`), as the controls panel does.
77
+ */
78
+ reset(): KBDefaults;
79
+ /** The engine's factory with this game's default on top — a fresh copy each call. */
80
+ factoryWithGame(): KBDefaults;
81
+ /** Reads the stored map into the live one and returns it. */
82
+ load(): KBDefaults;
83
+ }
81
84
  /**
82
- * «RESTAURAR PADRÕES» — e o padrão para onde ela volta é o DO JOGO, não o da engine (ADR-0115).
85
+ * BUILDS ONE ROOT'S KEYBOARD CONFIG (ADR-0232 D4). The mapping is a construction parameter and not a registration: a
86
+ * registration is module state a second root overwrites (D2b erratum), and the reset this object hands out already knows
87
+ * the game, which is what the registration existed to guarantee.
83
88
  *
84
- * 🔴 Esta linha era `JSON.parse(JSON.stringify(KB_DEFAULTS))`, e com o campo do jogo a existir isso passaria
85
- * a apagar em silêncio o mapeamento que o jogo escolheu. A criança espera voltar ao que o jogo lhe deu.
89
+ * ⚠️ IT DOES NOT READ THE STORE WHEN BUILT: the live map is born from the game's factory and `load()` is what reads, called
90
+ * once by the root. A test that builds one inherits nothing from any storage.
86
91
  */
87
- export declare function resetKB(): KBDefaults;
92
+ export declare function createKeyboardConfig(opts: KeyboardConfigOptions): KeyboardConfigApi;