@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,151 +1,149 @@
1
1
  // SPDX-License-Identifier: AGPL-3.0-or-later
2
- // input/transports — O REGISTRO DE TRANSPORTES (ADR-0079). Módulo-folha: só tipos e aritmética.
2
+ // input/transports — THE TRANSPORT REGISTRY (ADR-0079). A leaf module: only types and arithmetic.
3
3
  //
4
- // ========================= O QUE UM TRANSPORTE É =========================
5
- // Uma forma de alcançar as ações, e nada sobre significado. Ele declara o que OFERECE FISICAMENTE — quantos
6
- // lugares atribuíveis tem — e o jogador atribui a eles as ações do jogo. `TOUCH_DEFAULT` já era uma instância
7
- // disto antes de o modelo existir: uma atribuição padrão que a criança pode mudar.
4
+ // ========================= WHAT A TRANSPORT IS =========================
5
+ // A way of reaching the actions, and nothing about meaning. It declares what it OFFERS PHYSICALLY — how many
6
+ // assignable places it has — and the player assigns the game's actions to them. `TOUCH_DEFAULT` was already an
7
+ // instance of this before the model existed: a default assignment the child can change.
8
8
  //
9
- // ========================= A GARANTIA MUDOU DE FORMA =========================
10
- // ⚠️ NÃO é «todo transporte alcança toda ação». É: **para os transportes disponíveis a esta criança, PELO
11
- // MENOS UM carrega o conjunto de ações deste jogo.** A diferença é o que permite um transporte estreito
12
- // existir — um acionador de dois toques, um piscar — sem que ele reprove o produto inteiro.
9
+ // ========================= THE GUARANTEE CHANGED SHAPE =========================
10
+ // ⚠️ It is NOT "every transport reaches every action". It is: **of the transports available to this child, AT
11
+ // LEAST ONE carries this game's set of actions.** The difference is what lets a narrow transport exist — a
12
+ // two-tap switch, a blink — without it failing the whole product.
13
13
  //
14
- // ========================= E UM TRANSPORTE NUNCA REMOVE OUTRO =========================
15
- // Escolher o rato não desliga o teclado, o controle nem o toque. A engine OFERECE; quem escolhe é a criança
16
- // (ou quem a acompanha). Um método que exige coordenação fina não é exclusão enquanto os outros existirem —
17
- // a exclusão seria uma lista curta, não um item exigente numa lista longa.
14
+ // ========================= AND A TRANSPORT NEVER REMOVES ANOTHER =========================
15
+ // Choosing the mouse does not turn off the keyboard, the pad or touch. The engine OFFERS; the one who chooses is the
16
+ // child (or whoever is with them). A method that demands fine coordination is not exclusion while the others exist
17
+ // — exclusion would be a short list, not a demanding item in a long one.
18
18
  //
19
- // ========================= O QUE ESTE MÓDULO EXISTE PARA IMPEDIR =========================
20
- // ⚠️ Um jogo que precisa de doze ações e um transporte de nove lugares é uma combinação REAL — o controle de
21
- // tela tem nove slots desde sempre e o conjunto de ações passou a catorze em 2026-09-06. A resposta honesta é
22
- // UMA FRASE ANTES DE COMEÇAR, e não meia tela jogável: a criança que descobre no meio que não consegue
23
- // alcançar uma ação conclui que o jogo está partido, e ela não tem como saber que não está.
19
+ // ========================= WHAT THIS MODULE EXISTS TO PREVENT =========================
20
+ // ⚠️ A game that needs twelve actions and a transport with fewer places is a REAL combination — the on-screen
21
+ // control has thirteen slots and the action set has fourteen. The honest answer is ONE SENTENCE BEFORE STARTING,
22
+ // not half a playable screen: the child who discovers midway that they cannot reach an action concludes the game is
23
+ // broken, and they have no way of knowing it is not.
24
24
  import { ACTIONS } from '../core/actions.js';
25
25
  /**
26
- * QUANTOS LUGARES CADA TRANSPORTE REAL TEM, e de onde cada número vem. Estavam medidos e viviam só no teste;
27
- * um número que só existe num teste não chega a criança nenhuma.
26
+ * HOW MANY PLACES EACH REAL TRANSPORT HAS, and where each number comes from. They were measured and lived only in
27
+ * the test; a number that exists only in a test reaches no child.
28
28
  *
29
- * · `gamepad: 17` — a Gamepad API «standard» declara dezassete botões. Não é escolha nossa.
30
- * · `toque: 9` — `TOUCH_DEFAULT` (input/devices) nomeia nove slots, e são nove desde sempre.
31
- * · `teclado: ACTIONS.length` — ⚠️ e este é o que precisou de decisão.
29
+ * · `gamepad: 17` — the Gamepad API's "standard" mapping declares seventeen buttons. Not our choice.
30
+ * · `toque: 13` — `TOUCH_DEFAULT` (input/devices) names thirteen slots: the nine plus ADR-0160's four shoulders.
31
+ * · `teclado: ACTIONS.length` — ⚠️ and this is the one that needed a decision.
32
32
  *
33
- * ⚠️ O NÚMERO DO TECLADO NÃO É O NÚMERO DE TECLAS, e também não é o número de ligações do esquema atual. Não
34
- * é o de teclas porque cem teclas não são cem lugares que uma criança encontra e lembra; não é o do esquema
35
- * porque o esquema cresce, e o limite passaria a ser a configuração e não o aparelho.
33
+ * ⚠️ THE KEYBOARD'S NUMBER IS NOT THE NUMBER OF KEYS, nor the number of bindings in the current scheme. Not the keys,
34
+ * because a hundred keys are not a hundred places a child finds and remembers; not the scheme, because the scheme
35
+ * grows, and the limit would become the configuration instead of the device.
36
36
  *
37
- * É `ACTIONS.length` porque o que limita um teclado, na prática deste produto, é O VOCABULÁRIO QUE A ENGINE
38
- * SABE NOMEAR: um transporte que cobre todas as posições que existem não tem como ser o curto. Derivado e não
39
- * escrito à mão de propósito — quando o vocabulário crescer (foi de nove para catorze em 2026-09-06), este
40
- * número cresce com ele e nunca passa a mentir.
37
+ * It is `ACTIONS.length` because what limits a keyboard, in this product's practice, is THE VOCABULARY THE ENGINE
38
+ * CAN NAME: a transport that covers every position that exists cannot be the short one. Derived and not written by
39
+ * hand on purpose — when the vocabulary grows (it went from nine to fourteen), this number grows with it and never
40
+ * starts lying.
41
41
  */
42
- export const LUGARES = Object.freeze({ gamepad: 17, toque: 9, teclado: ACTIONS.length });
42
+ export const SLOTS = Object.freeze({ gamepad: 17, toque: 13, teclado: ACTIONS.length });
43
43
  /**
44
- * QUANTAS POSIÇÕES O CONTROLE DE TELA SEGURA AO MESMO TEMPO. Dois, e é uma DECLARAÇÃO (ADR-0104 §B).
44
+ * HOW MANY POSITIONS THE ON-SCREEN CONTROL HOLDS AT ONCE. Two, and it is a DECLARATION (ADR-0104 §B).
45
45
  *
46
- * ⚠️ E A DECISÃO É NÃO PERGUNTAR AO APARELHO. O `navigator.maxTouchPoints` existe, responde depressa, e
47
- * MENTE — mente para cima: muitos aparelhos anunciam cinco e reconhecem dois. Um modelo assente nele falha
48
- * exactamente no telemóvel barato da escola pública, que é o pilar 1 deste projeto, e falha em silêncio: a
49
- * criança tenta correr e pular ao mesmo tempo, não acontece nada, e ela conclui que o jogo está partido.
46
+ * ⚠️ AND THE DECISION IS NOT TO ASK THE DEVICE. `navigator.maxTouchPoints` exists, answers fast, and LIES — upwards:
47
+ * many devices announce five and recognise two. A model built on it fails exactly on the public school's cheap
48
+ * phone, which is this project's pillar 1, and fails silently: the child tries to run and jump at once, nothing
49
+ * happens, and they conclude the game is broken.
50
50
  *
51
- * Um piso declarado não pode errar para cima. Ele erra para baixo — um aparelho que segurava três fica
52
- * servido por dois —, e esse erro tem conserto: a opção do terceiro botão, PROVADA POR TESTE, porque um
53
- * gesto real é a única evidência que um aparelho não consegue falsificar. Nada é recusado e nada é assumido.
51
+ * A declared floor cannot err upwards. It errs downwards — a device that held three is served by two —, and that
52
+ * error has a fix: the third-button option, PROVEN BY A TEST, because a real gesture is the only evidence a device
53
+ * cannot fake. Nothing is refused and nothing is assumed.
54
54
  *
55
- * ⚠️ NÃO É UM REGISTO DE TETOS POR TRANSPORTE, e o ADR diz isso em `more-information`: só o toque tem número
56
- * declarado. O `holds` do `Transport` é opcional justamente por isso — ausente significa «não há tecto
57
- * conhecido», não «segura uma». Um registo de tetos para teclado e controle é uma mudança maior, e nada
58
- * precisa dela hoje.
55
+ * ⚠️ IT IS NOT A REGISTRY OF CEILINGS PER TRANSPORT, and the ADR says so in `more-information`: only touch has a
56
+ * declared number. `Transport.holds` is optional precisely for that — absent means "no known ceiling", not "holds
57
+ * one". A ceiling registry for keyboard and pad is a bigger change, and nothing needs it today.
59
58
  */
60
- export const SEGURA_TOQUE = 2;
59
+ const HOLDS_TOUCH = 2;
61
60
  /**
62
- * Os três transportes que esta engine sabe oferecer hoje.
61
+ * The three transports this engine knows how to offer today.
63
62
  *
64
- * ⚠️ A DETECÇÃO DO TECLADO É IMPRECISA E ISSO É ACEITÁVEL — mas só porque a tela que consome isto INFORMA em
65
- * vez de RECUSAR. Não há API que diga «há um teclado físico ligado»; o que o projeto já usa para a mesma
66
- * pergunta é `pointer:coarse && hover:none` (o `isCoarsePointer` do `game/session`), e um tablet COM teclado
67
- * responde «toque» a isso. Se a tela barrasse, esse tablet levaria uma recusa falsa num jogo que ele joga.
68
- * Como ela apenas diz o que falta e deixa continuar, o erro custa uma frase a mais e nunca uma porta fechada.
63
+ * ⚠️ THE KEYBOARD DETECTION IS IMPRECISE AND THAT IS ACCEPTABLE — but only because the screen that consumes this
64
+ * INFORMS instead of REFUSING. No API says "a physical keyboard is plugged in"; what the root asks is
65
+ * `pointer:coarse && hover:none`, and a tablet WITH a keyboard answers "touch" to that. If the screen blocked, that
66
+ * tablet would get a false refusal in a game it plays. Since it only says what is missing and lets the child go on,
67
+ * the error costs one extra sentence and never a closed door.
69
68
  */
70
- export function transportesPadrao(d) {
69
+ export function defaultTransports(d) {
71
70
  return [
72
- // ⚠️ O GAMEPAD NÃO DECLARA PONTEIRO, e a ausência é medida e não esquecimento: o stick tem o sinal
73
- // contínuo e a engine deita-o fora na fonte (`PAD_DEAD = 0.5`, `PadState = Record<string, boolean>`).
74
- // Ligá-lo ao ponteiro é possível e traz de volta uma pergunta que o ADR-0112 já deixou nomeada — metade
75
- // do curso morta é ergonomia certa para um BOTÃO e errada para um CURSOR.
76
- { id: 'gamepad', slots: LUGARES.gamepad, available: d.gamepad },
77
- // O teclado aponta QUANDO HÁ RATO — a cláusula do Dev, e a fundação dos transportes 8 e 9 do ADR-0074.
78
- { id: 'teclado', slots: LUGARES.teclado, available: d.teclado, aponta: d.rato },
79
- // O toque aponta por natureza: a superfície É o ponteiro, e é o mesmo dedo que carrega nos botões.
80
- { id: 'toque', slots: LUGARES.toque, holds: SEGURA_TOQUE, available: d.toque, aponta: d.toque },
71
+ // ⚠️ THE GAMEPAD DECLARES NO POINTER, and the absence is measured, not forgotten: the stick has the continuous
72
+ // signal and the engine throws it away at the source (`PAD_DEAD = 0.5`, `PadState = Record<string, boolean>`).
73
+ // Wiring it to the pointer is possible and brings back a question ADR-0112 already named — half the travel dead is
74
+ // the right ergonomics for a BUTTON and the wrong one for a CURSOR.
75
+ { id: 'gamepad', slots: SLOTS.gamepad, available: d.gamepad },
76
+ // The keyboard points WHEN THERE IS A MOUSE — the Dev's clause, and the foundation of ADR-0074's transports 8 and 9.
77
+ { id: 'teclado', slots: SLOTS.teclado, available: d.keyboard, points: d.mouse },
78
+ // Touch points by nature: the surface IS the pointer, and it is the same finger that presses the buttons.
79
+ { id: 'toque', slots: SLOTS.toque, holds: HOLDS_TOUCH, available: d.touch, points: d.touch },
81
80
  ];
82
81
  }
83
- /** Este transporte carrega este conjunto de ações? Aritmética, como o ADR-0079 §3 a descreve. */
84
- export function carries(t, acoes) {
85
- return t.slots >= acoes.length;
82
+ /** Does this transport carry this set of actions? Arithmetic, as ADR-0079 §3 describes it. */
83
+ export function carries(t, actions) {
84
+ return t.slots >= actions.length;
86
85
  }
87
86
  /**
88
- * Este transporte SEGURA quantas o jogo pede ao mesmo tempo? (ADR-0104 §A.)
87
+ * Does this transport HOLD as many as the game asks at once? (ADR-0104 §A.)
89
88
  *
90
- * ⚠️ TRANSPORTE SEM TECTO DECLARADO RESPONDE SIM, e a escolha é deliberada: o `holds` ausente quer dizer «não
91
- * medimos isto», e recusar por falta de medida transformaria uma ignorância em acusação — o teclado e o
92
- * controle passariam a reprovar todos os jogos por não terem número nenhum. Onde não há decisão, o modelo
93
- * cala; é o toque que tem decisão, e é só ele que pode reprovar aqui.
89
+ * ⚠️ A TRANSPORT WITH NO DECLARED CEILING ANSWERS YES, and the choice is deliberate: an absent `holds` means "we did
90
+ * not measure this", and refusing for lack of a measure would turn ignorance into an accusation — keyboard and pad
91
+ * would fail every game for having no number at all. Where there is no decision, the model stays silent; touch is
92
+ * the one with a decision, and it alone can fail here.
94
93
  */
95
- export function holds(t, pedidas) {
96
- return t.holds === undefined || t.holds >= pedidas;
94
+ function holds(t, asked) {
95
+ return t.holds === undefined || t.holds >= asked;
97
96
  }
98
97
  /**
99
- * Os transportes DISPONÍVEIS que carregam este conjunto.
98
+ * The AVAILABLE transports that carry this set.
100
99
  *
101
- * ⚠️ Disponibilidade e capacidade são conferidas nesta ordem de propósito: um transporte que caberia mas não
102
- * está ligado não é resposta para uma criança que está à frente do aparelho agora.
100
+ * ⚠️ Availability and capacity are checked in this order on purpose: a transport that would fit but is not plugged
101
+ * in is no answer for a child sitting at the device now.
103
102
  */
104
- export function carriedBy(lista, acoes) {
105
- return lista.filter((t) => t.available() && carries(t, acoes));
103
+ export function carriedBy(list, actions) {
104
+ return list.filter((t) => t.available() && carries(t, actions));
106
105
  }
107
106
  /**
108
- * A garantia do ADR-0079 §3, como pergunta de sim ou não.
107
+ * ADR-0079 §3's guarantee, as a yes-or-no question.
109
108
  *
110
- * ⚠️ CONJUNTO VAZIO DE AÇÕES DEVOLVE `false`, e não `true` por vacuidade. Um jogo que não declara ação
111
- * nenhuma não é um jogo que qualquer transporte serve — é um jogo que ninguém consegue jogar, e
112
- * `actionSetProblems` já o reprova. Devolver `true` aqui esconderia esse defeito atrás desta função.
109
+ * ⚠️ AN EMPTY SET OF ACTIONS RETURNS `false`, not a vacuous `true`. A game that declares no action is not a game any
110
+ * transport serves — it is a game nobody can play, and `actionSetProblems` already fails it. Returning `true` here
111
+ * would hide that defect behind this function.
113
112
  */
114
- export function reachable(lista, acoes) {
115
- return acoes.length > 0 && carriedBy(lista, acoes).length > 0;
113
+ export function reachable(list, actions) {
114
+ return actions.length > 0 && carriedBy(list, actions).length > 0;
116
115
  }
117
116
  /**
118
- * Mede o alcance ANTES de a criança começar.
117
+ * Measures the reach BEFORE the child starts.
119
118
  *
120
- * ⚠️ Devolve DADO e não texto. A frase é da interface e tem de passar por `t()`; devolver português daqui
121
- * repetiria o defeito que o `PADWIZ_STEPS` acabou de deixar de cometer.
119
+ * ⚠️ It returns DATA and not text. The sentence belongs to the interface and has to go through `t()`; returning
120
+ * prose from here would put a language in a module that has none.
122
121
  */
123
- export function alcance(lista, acoes, seguraPedidas, pedePonteiro = false) {
124
- const disponiveis = lista.filter((t) => t.available());
122
+ export function reach(list, actions, askedHolds, wantsPointer = false) {
123
+ const availableNow = list.filter((t) => t.available());
125
124
  /**
126
- * ⚠️ PADRÃO `false` E NÃO PARÂMETRO OBRIGATÓRIO: os trezentos jogos que não desenham não podem sentir esta
127
- * mudança, e um quarto argumento exigido faria cada chamador existente decidir hoje uma coisa que não lhe
128
- * diz respeito.
125
+ * ⚠️ A `false` DEFAULT AND NOT A REQUIRED PARAMETER: games that do not draw must not feel this change, and a
126
+ * required fourth argument would make every existing caller decide today something that is none of its business.
129
127
  */
130
- const apontaSeFor = (t) => !pedePonteiro || (!!t.aponta && t.aponta());
131
- // ⚠️ «Serve» passou a ser TRÊS coisas. Foi DUAS na #114 (o `ok` dizia sim a quem não segurava três dedos), e
132
- // é três desde o ADR-0112 — pela mesma razão das duas vezes: um `ok` verdadeiro sobre um jogo que a criança
133
- // não consegue jogar é a pior coisa que este campo pode fazer.
134
- const serve = (t) => carries(t, acoes) && holds(t, seguraPedidas) && apontaSeFor(t);
128
+ const pointsIfNeeded = (t) => !wantsPointer || (!!t.points && t.points());
129
+ // ⚠️ "Serves" became THREE things. It was TWO with #114 (`ok` said yes to whoever could not hold three fingers), and
130
+ // three since ADR-0112 — for the same reason both times: a true `ok` about a game the child cannot play is the worst
131
+ // thing this field can do.
132
+ const serve = (t) => carries(t, actions) && holds(t, askedHolds) && pointsIfNeeded(t);
135
133
  return {
136
- ok: acoes.length > 0 && disponiveis.some(serve),
137
- pedidas: acoes.length,
138
- seguraPedidas,
139
- pedePonteiro,
140
- serviriamSeLigados: lista.filter((t) => !t.available() && serve(t)).map((t) => t.id),
141
- curtos: disponiveis.filter((t) => !carries(t, acoes)).map((t) => ({ id: t.id, slots: t.slots })),
142
- naoApontam: disponiveis
143
- .filter((t) => carries(t, acoes) && holds(t, seguraPedidas) && !apontaSeFor(t))
134
+ ok: actions.length > 0 && availableNow.some(serve),
135
+ asked: actions.length,
136
+ holdsAsked: askedHolds,
137
+ needsPointer: wantsPointer,
138
+ wouldServeIfOn: list.filter((t) => !t.available() && serve(t)).map((t) => t.id),
139
+ short: availableNow.filter((t) => !carries(t, actions)).map((t) => ({ id: t.id, slots: t.slots })),
140
+ cannotPoint: availableNow
141
+ .filter((t) => carries(t, actions) && holds(t, askedHolds) && !pointsIfNeeded(t))
144
142
  .map((t) => t.id),
145
- // ⚠️ SÓ QUEM CHEGA, e não quem já reprovou por lugares. Um transporte que aparecesse nas duas listas
146
- // faria o cartão dizer duas coisas sobre o mesmo defeito, e a criança leria dois problemas onde há um.
147
- naoSeguram: disponiveis
148
- .filter((t) => carries(t, acoes) && !holds(t, seguraPedidas))
143
+ // ⚠️ ONLY THOSE THAT REACH, and not those already failed for places. A transport on both lists would make the card
144
+ // say two things about the same defect, and the child would read two problems where there is one.
145
+ cannotHold: availableNow
146
+ .filter((t) => carries(t, actions) && !holds(t, askedHolds))
149
147
  .map((t) => ({ id: t.id, holds: t.holds })),
150
148
  };
151
149
  }
@@ -0,0 +1,82 @@
1
+ // SPDX-License-Identifier: AGPL-3.0-or-later
2
+ import { type Action } from '../core/actions.js';
3
+ import type { KeyScheme } from '../core/entity.js';
4
+ import type { TransportName } from './transport-in-use.js';
5
+ export interface VirtualCommand {
6
+ readonly action: Action;
7
+ readonly pressed: boolean;
8
+ /** Who produced it (ADR-0111 §2); `undefined` when nobody said. */
9
+ readonly source: TransportName | undefined;
10
+ readonly player: number;
11
+ }
12
+ export interface VirtualControllerDeps {
13
+ readonly scheme: (player: number) => KeyScheme;
14
+ readonly menuOpen: () => boolean;
15
+ /**
16
+ * Holds the child's key for this position.
17
+ *
18
+ * ⚠️ `source` CAN BE UNDEFINED, and that is not sloppiness: a real key press carries no stamp, so the keyboard —
19
+ * the one transport whose native currency IS the key — arrives unsigned. `input/state` already has the narrow
20
+ * door for exactly that (`markKeyWithoutSource`), and the host wires this to it: a key whose producer nobody
21
+ * declared must ERASE the previous producer rather than inherit it (ADR-0109).
22
+ */
23
+ readonly holdKey: (code: string, source: TransportName | undefined) => void;
24
+ readonly releaseKey: (code: string) => void;
25
+ /**
26
+ * A menu is moved by its key, as the touch pad does, stamped with the transport that pressed it.
27
+ *
28
+ * 📌 This is the POSITION → KEY translator, and it exists for transports that do not produce keys. The keyboard
29
+ * does, so its key is already in the world before this is reached — the host's implementation says so.
30
+ */
31
+ readonly menuKey: (code: string, source: TransportName | undefined) => void;
32
+ readonly deliver: (command: VirtualCommand) => void;
33
+ /**
34
+ * A position the ENGINE answers itself while a menu is open, before it becomes a menu key: the sonar reads the menu in
35
+ * front (ADR-0234, `ui/screen-text.menuSonarPress`). Answers whether it took the press. Absent: every position is a key.
36
+ */
37
+ readonly menuAnswers?: (action: Action, player: number) => boolean;
38
+ /**
39
+ * A SYSTEM position pressed, in play or with a menu open: the engine answers it for that seat as its keys do — `start` the
40
+ * quick pause (again: leaves it), `select` the menus (ADR-0144 §1 and its erratum of 2026-09-26, ADR-0155). Absent: it does
41
+ * nothing.
42
+ *
43
+ * ⚠️ The keyboard does not come here: its key is already in the world, and the engine's own key listeners answer it even for
44
+ * a cartridge with no `onCommand` — the host's keyboard conductor does not press these two, or one key would pause twice.
45
+ */
46
+ readonly systemPress?: (action: Action, player: number) => void;
47
+ /**
48
+ * ONE BUTTON ONLY (ADR-0218 §4): asked FIRST, for every press from every transport that presses here — the eyes, the face,
49
+ * the hands, the voice, the on-screen pad, the gamepad. `true` means one-button scanning took the press as «take the one
50
+ * shown»: the position reaches nothing else — not play, not a menu, not the engine — and no release is owed for it. A press
51
+ * that lands on the scan's «cancel» is taken too, and means nothing. Absent: every press is itself.
52
+ */
53
+ readonly takeShown?: (source: TransportName | undefined) => boolean;
54
+ /**
55
+ * A PRESS FROM A NAMED TRANSPORT, told FIRST — before one button only, a menu or play decides where it goes. This is the one
56
+ * place every position-pressing transport shares, so it is where «the child is using this device» can be heard for all of
57
+ * them (ADR-0109 rule 3), and where the root records that device's edge and resolves its latch before the press reaches the
58
+ * game (ADR-0113, ADR-0249). Not told for a press with no source: a key nobody stamped is nobody's edge — the real keyboard
59
+ * arrives here as `teclado`, read off the event by `input/synthetic-source.sourceOfEvent`. Absent: nothing is told.
60
+ */
61
+ readonly pressedBy?: (source: TransportName, player: number) => void;
62
+ }
63
+ export interface VirtualController {
64
+ /**
65
+ * Presses a position. Answers whether it reached PLAY — `false` means a menu took it, or it was held back (`toPlay`).
66
+ *
67
+ * 🔴 THE ANSWER EXISTS BECAUSE EVERY TRANSPORT NEEDS IT AND EACH WAS GUESSING IT (ADR-0223). The touch pad asked its own
68
+ * `emMenu()` before deciding what to do, which is the same question this function has just answered — and two answers to
69
+ * one question is how the two doors came to disagree about what happens with a menu open. A transport that raises an edge,
70
+ * or hides its tips, or announces something, does it only when the press reached the game; now it is told.
71
+ *
72
+ * `toPlay` false: in play the press belongs to something else — the keyboard knows what has the focus, a field being typed
73
+ * into or the engine's own control being pressed (`input/key-default`) — so it reaches nobody: nothing held, nothing delivered.
74
+ * With a menu open it is the menu's all the same, as every press is (ADR-0111 erratum of 2026-09-26: one press, one action).
75
+ *
76
+ * A system position (`start`, `select`) never reaches play and never becomes a menu key: it is the engine's (ADR-0144 §4), and
77
+ * it goes to `systemPress` — unless, in play, `toPlay` is false, when the press belongs to something else and reaches nobody.
78
+ */
79
+ press(action: Action, source: TransportName | undefined, player?: number, toPlay?: boolean): boolean;
80
+ release(action: Action, source: TransportName | undefined, player?: number): void;
81
+ }
82
+ export declare function createVirtualController(d: VirtualControllerDeps): VirtualController;
@@ -0,0 +1,69 @@
1
+ // SPDX-License-Identifier: AGPL-3.0-or-later
2
+ // input/virtual-controller — THE ENGINE CARRIES THE VIRTUAL BUTTON TO THE GAME (ADR-0111 and its erratum of 2026-09-16; issue #197).
3
+ //
4
+ // The Dev: «a engine lida com o hardware e passa para o jogo o nome virtual do botão, o jogo por sua vez devolve o nome do que é executado
5
+ // ao apertar cada botão… a engine leva o evento para o jogo». A transport that reads positions (the eyes, and later the face and the
6
+ // hands) presses and releases a position here, with its source; this decides what that reaches:
7
+ // · with a menu open, the position is the menu's key — the way the touch pad already moves menus (ADR-0157), since menus read keys —
8
+ // unless the engine answers it there itself (`menuAnswers`: the sonar reads the menu, ADR-0234);
9
+ // · in play, the child's key for that position is held (games that ask what is held keep answering), and the command is delivered to the
10
+ // cartridge: the position, pressed or released, the source, the seat. The cartridge's map (its `preset`) says what it executes.
11
+ // A position the child's scheme gives no key is still delivered: the map belongs to the game, not to the keyboard.
12
+ // 🔴 EXCEPT THE TWO SYSTEM POSITIONS, which never reach play (ADR-0144 §4, ADR-0155 §4): `start` is the quick pause and `select`
13
+ // opens the menus, a cartridge may not declare either, so the game has no word for them and nothing to do with them. 📏 Before
14
+ // this, Enter in play opened the quick pause AND the quiz's `onCommand` heard `start`; F opened the card AND it heard `select`.
15
+ // They go to the ENGINE instead (`systemPress`), so START and SELECT open the pause «from any transport» (ADR-0144 §1): the eyes,
16
+ // the face, the hands, the voice and the scan press here and have no key in the world for the engine to hear.
17
+ // 🔴 AND WITH A MENU OPEN TOO, never as a key (ADR-0144 erratum of 2026-09-26). The first key of `start` is whatever the child put
18
+ // first: with `start` remapped to `Enter`, a camera's START on the quick pause's bar was the bar's «confirm» and not the way out.
19
+ // The engine answers the POSITION the same way its key listeners do — START again leaves the quick pause, SELECT goes on to the
20
+ // card, and an open card or panel refuses both.
21
+ // 🔴 AND WITH ONE BUTTON ONLY ON, NONE OF THE ABOVE (ADR-0218 §4): every press here is the child's one switch, and it takes the
22
+ // item the scan shows (`takeShown`, asked before anything else). This is the one place every position-pressing transport shares.
23
+ import { SYSTEM } from '../core/actions.js';
24
+ /** The positions that are the engine's and never the game's (`core/actions.SYSTEM`). */
25
+ const ENGINE_POSITIONS = new Set(SYSTEM);
26
+ export function createVirtualController(d) {
27
+ // `${player}:${action}` → the key held for a press the game received (or null when the scheme has none), so the release lets go of the
28
+ // same key, and only a press the game heard is released to it
29
+ const held = new Map();
30
+ return {
31
+ press(action, source, player = 0, toPlay = true) {
32
+ if (source)
33
+ d.pressedBy?.(source, player);
34
+ if (d.takeShown?.(source))
35
+ return false; // one button only: whatever was pressed, it was the switch (ADR-0218 §4)
36
+ const menu = d.menuOpen();
37
+ // the POSITION, not its first key: a key means what the child bound to it, and `Enter` on a menu is «confirm»
38
+ if (ENGINE_POSITIONS.has(action)) {
39
+ if (menu || toPlay)
40
+ d.systemPress?.(action, player);
41
+ return false;
42
+ }
43
+ const code = d.scheme(player)[action]?.[0];
44
+ if (menu) {
45
+ if (!d.menuAnswers?.(action, player) && code)
46
+ d.menuKey(code, source);
47
+ return false;
48
+ }
49
+ if (!toPlay)
50
+ return false;
51
+ if (code)
52
+ d.holdKey(code, source);
53
+ held.set(`${player}:${action}`, code ?? null);
54
+ d.deliver({ action, pressed: true, source, player });
55
+ return true;
56
+ },
57
+ release(action, source, player = 0) {
58
+ const key = `${player}:${action}`;
59
+ if (!held.has(key))
60
+ return;
61
+ const code = held.get(key);
62
+ held.delete(key);
63
+ if (code)
64
+ d.releaseKey(code);
65
+ // delivered even if a menu opened meanwhile: a game must never be left believing a button is still down
66
+ d.deliver({ action, pressed: false, source, player });
67
+ },
68
+ };
69
+ }
@@ -1,69 +1,70 @@
1
1
  // SPDX-License-Identifier: AGPL-3.0-or-later
2
2
  /**
3
- * ⚠️ O DADO SALVO NÃO É UM `KeyScheme`, e a issue #118 tornou isso um erro de compilação em vez de uma
4
- * suposição. Um `KeyScheme` é FECHADO nas quatorze posições e completo; o que está no navegador da criança é
5
- * uma SOBREPOSIÇÃO — parcial por construção (`loadKB` funde-a sobre os padrões com `Object.assign`) e capaz
6
- * de carregar chaves que este código não conhece, o que o cabeçalho de `migrarEsquema` já dizia com todas as
7
- * letras: «chave desconhecida atravessa intacta».
3
+ * ⚠️ THE SAVED DATA IS NOT A `KeyScheme`, and issue #118 made that a compile error instead of an assumption. A
4
+ * `KeyScheme` is CLOSED over the fourteen positions and complete; what sits in the child's browser is an
5
+ * OVERLAY — partial by construction (`loadKB` merges it over the defaults with `Object.assign`) and able to
6
+ * carry keys this code does not know, which the header of `migrateScheme` already says in so many words: an
7
+ * unknown key passes through untouched.
8
8
  *
9
- * Dar-lhe o tipo fechado obrigaria este ficheiro a inventar as posições que faltam no dado antigo — quer
10
- * dizer, a escrever teclas que a criança nunca escolheu, no exacto módulo que existe para não lhe perder o
11
- * remapeamento. O tipo aberto é o honesto aqui, e é só aqui.
9
+ * Giving it the closed type would force this file to invent the positions missing from the old data — that is,
10
+ * to write keys the child never chose, in the very module that exists so as not to lose their remapping. The
11
+ * open type is the honest one here, and only here.
12
12
  */
13
- export type EsquemaSalvo = Record<string, readonly string[]>;
13
+ export type SavedScheme = Record<string, readonly string[]>;
14
14
  /**
15
- * Nome de plataforma → posição abstrata. **ADR-0086 §2**, e não o ADR-0074.
15
+ * Platform name → abstract position. **ADR-0086 §2**, not ADR-0074.
16
16
  *
17
- * ⚠️ A DIFERENÇA ENTRE OS DOIS REGISTROS É A TECLA DA CRIANÇA. O ADR-0074 dizia `jump → action1` e
18
- * `run → action4`; o ADR-0086 corrigiu para `run → action1` e `jump → action2`, medindo que a correção é a
19
- * leitura CONSERVADORA — ela deixa cada verbo na tecla e no botão que já ocupava. Traduzir por engano pela
20
- * tabela do 0074 não daria erro nenhum: moveria o pulo de `J` para `U` em silêncio.
17
+ * ⚠️ THE DIFFERENCE BETWEEN THE TWO RECORDS IS THE CHILD'S KEY. ADR-0074 said `jump → action1` and
18
+ * `run → action4`; ADR-0086 corrected it to `run → action1` and `jump → action2`, having measured that the
19
+ * correction is the CONSERVATIVE reading — it leaves each verb on the key and the button it already held.
20
+ * Translating by mistake with 0074's table would raise no error at all: it would move jump from `J` to `U`
21
+ * silently.
21
22
  */
22
- export declare const VOCABULARIO_ANTIGO: Readonly<Record<string, string>>;
23
+ export declare const OLD_VOCABULARY: Readonly<Record<string, string>>;
23
24
  /**
24
- * ⚠️ O SEGUNDO DADO SALVO, e ele quase passou. O mapa de toque (`incl_touchmap`) guarda SLOT → AÇÃO, ou seja
25
- * o nome da ação está no VALOR e não na chave: `{ b0: 'jump', b1: 'especial' }`. O tradutor de esquemas de
26
- * teclado, que traduz CHAVES, passaria por cima dele sem tocar em nada.
25
+ * ⚠️ THE SECOND SAVED DATA, and it nearly slipped through. The touch map (`incl_touchmap`) stores SLOT → ACTION,
26
+ * so the action name is in the VALUE and not the key: `{ b0: 'jump', b1: 'especial' }`. The keyboard scheme
27
+ * translator, which translates KEYS, would pass over it without touching anything.
27
28
  *
28
- * ⚠️ E O DANO SERIA PIOR DO QUE NO TECLADO. `normalizeTouchMap` funde o guardado SOBRE o padrão, então um
29
- * `b0: 'jump'` gravado sobrescreveria o `b0: 'action2'` correto — e o botão da tela deixaria de fazer
30
- * qualquer coisa. Num tablet de escola pública o toque não é o caminho alternativo: é o único.
29
+ * ⚠️ AND THE DAMAGE WOULD BE WORSE THAN ON THE KEYBOARD. `normalizeTouchMap` merges what is stored OVER the
30
+ * default, so a saved `b0: 'jump'` would overwrite the correct `b0: 'action2'` — and the on-screen button would
31
+ * stop doing anything. On a public-school tablet, touch is not the alternative path: it is the only one.
31
32
  *
32
- * Foi um teste de NAVEGADOR que o encontrou (`tests/touch.browser.test.js`), depois de a suíte `node` já
33
- * estar verde — o que é o argumento para os dois projetos existirem.
33
+ * A BROWSER test found it (`tests/touch.browser.test.js`), after the `node` suite was already green — which is
34
+ * the argument for having both projects.
34
35
  */
35
- export declare function migrarMapaDeToque(mapa: Record<string, string> | null | undefined): Record<string, string> | null;
36
+ export declare function migrateTouchMap(touchMap: Record<string, string> | null | undefined): Record<string, string> | null;
36
37
  /**
37
- * ⚠️ O TERCEIRO DADO SALVO, encontrado por varredura e não por acidente. Depois de o segundo aparecer num
38
- * teste de navegador, a pergunta certa deixou de ser «este está migrado?» e passou a ser «QUANTOS formatos
39
- * persistidos existem?». São três, e este é o do assistente de controle: `incl_padmap_<id>` guarda
40
- * AÇÃO → BINDING FÍSICO, `{ jump: { b: 0 }, run: { b: 2 } }`, um por modelo de controle.
38
+ * ⚠️ THE THIRD SAVED DATA, found by a sweep and not by accident. After the second turned up in a browser test,
39
+ * the right question stopped being "is this one migrated?" and became "HOW MANY persisted formats exist?". There
40
+ * are three, and this is the pad wizard's: `incl_padmap_<id>` stores ACTION → PHYSICAL BINDING,
41
+ * `{ jump: { b: 0 }, run: { b: 2 } }`, one per pad model.
41
42
  *
42
- * ⚠️ E ELE É O MAIS CARO DE PERDER DOS TRÊS. Um mapa desses existe porque a criança (ou quem a acompanha)
43
- * passou por um assistente de nove passos apertando botão a botão, provavelmente porque o controle dela não
44
- * é «standard» — controles genéricos e adaptados raramente são. Perdê-lo manda essa pessoa de volta ao
45
- * assistente inteiro.
43
+ * ⚠️ AND IT IS THE MOST EXPENSIVE OF THE THREE TO LOSE. Such a map exists because the child (or whoever is with
44
+ * them) went through the wizard pressing button after button, one step per position the game names — probably
45
+ * because their pad is not "standard", and generic and adapted pads rarely are. Losing it sends that person back
46
+ * through the whole wizard.
46
47
  *
47
- * `_skip` e qualquer chave desconhecida atravessam, pela mesma razão das outras duas migrações.
48
+ * `_skip` and any unknown key pass through, for the same reason as the other two migrations.
48
49
  */
49
- export declare function migrarMapaDeControle<T>(mapa: Record<string, T> | null | undefined): Record<string, T> | null;
50
- /** O objeto salvo, tal como `input/keyboard` o persiste. `p34` é o formato mais antigo de todos. */
50
+ export declare function migrateControlMap<T>(touchMap: Record<string, T> | null | undefined): Record<string, T> | null;
51
+ /** The saved object, as `input/keyboard` persists it. `p34` is the oldest format of all. */
51
52
  export interface SavedKB {
52
- solo?: EsquemaSalvo;
53
- p2?: EsquemaSalvo[];
54
- p3?: EsquemaSalvo[];
55
- p4?: EsquemaSalvo[];
56
- p34?: (EsquemaSalvo | null)[];
53
+ solo?: SavedScheme;
54
+ p2?: SavedScheme[];
55
+ p3?: SavedScheme[];
56
+ p4?: SavedScheme[];
57
+ p34?: (SavedScheme | null)[];
57
58
  }
58
59
  /**
59
- * Traduz UM esquema salvo do vocabulário antigo para o abstrato.
60
+ * Translates ONE saved scheme from the old vocabulary to the abstract one.
60
61
  *
61
- * ⚠️ CHAVE DESCONHECIDA ATRAVESSA INTACTA, e é decisão e não descuido: `up`, `down`, `left` e `right` nunca
62
- * mudaram de nome, e um esquema pode carregar uma chave que este código não conhece — dado de uma versão
63
- * futura, ou lixo. Apagá-la seria destruir dado que não entendemos, e é o que faria as quatro direções
64
- * sumirem. É também o que torna esta função IDEMPOTENTE: aplicada sobre um esquema já migrado, nenhuma chave
65
- * casa e o resultado é igual à entrada, o que importa porque `loadKB` pode correr mais de uma vez na sessão.
62
+ * ⚠️ AN UNKNOWN KEY PASSES THROUGH UNTOUCHED, and that is a decision, not carelessness: `up`, `down`, `left` and
63
+ * `right` never changed names, and a scheme may carry a key this code does not know — data from a future
64
+ * version, or garbage. Deleting it would destroy data we do not understand, and it is what would make the four
65
+ * directions vanish. It is also what makes this function IDEMPOTENT: applied to an already migrated scheme, no
66
+ * key matches and the result equals the input, which matters because `loadKB` may run more than once a session.
66
67
  */
67
- export declare function migrarEsquema(esquema: EsquemaSalvo | null | undefined): EsquemaSalvo | null;
68
- /** Traduz o objeto salvo inteiro — o esquema solo e as listas por contagem de jogadores. */
69
- export declare function migrarSalvo(s: SavedKB | null | undefined): SavedKB | null;
68
+ export declare function migrateScheme(saved: SavedScheme | null | undefined): SavedScheme | null;
69
+ /** Translates the whole saved object — the solo scheme and the lists per player count. */
70
+ export declare function migrateSaved(s: SavedKB | null | undefined): SavedKB | null;