@the-inclusionist/engine 10.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 (528) hide show
  1. package/README.md +32 -1
  2. package/app/css/style.css +216 -42
  3. package/app/public/vendor/fonts-licences/NOTICE.txt +166 -0
  4. package/app/public/vendor/fonts-licences/OFL-1.1.txt +86 -0
  5. package/app/public/vendor/fonts.css +11 -1175
  6. package/dist-pkg/boot/create-game.d.ts +84 -33
  7. package/dist-pkg/boot/create-game.js +708 -307
  8. package/dist-pkg/core/a11y-sr.d.ts +1 -1
  9. package/dist-pkg/core/a11y-sr.js +3 -5
  10. package/dist-pkg/core/accommodations.d.ts +26 -8
  11. package/dist-pkg/core/accommodations.js +27 -10
  12. package/dist-pkg/core/actions.d.ts +39 -10
  13. package/dist-pkg/core/actions.js +28 -6
  14. package/dist-pkg/core/contract.d.ts +0 -2
  15. package/dist-pkg/core/contract.js +0 -2
  16. package/dist-pkg/core/i18n.d.ts +36 -71
  17. package/dist-pkg/core/i18n.js +131 -198
  18. package/dist-pkg/core/session-clock.d.ts +23 -0
  19. package/dist-pkg/core/session-clock.js +37 -0
  20. package/dist-pkg/i18n/en.js +44 -49
  21. package/dist-pkg/i18n/es.js +44 -49
  22. package/dist-pkg/i18n/pt.js +49 -54
  23. package/dist-pkg/input/gamepad.d.ts +42 -11
  24. package/dist-pkg/input/gamepad.js +50 -15
  25. package/dist-pkg/input/key-default.d.ts +30 -0
  26. package/dist-pkg/input/key-default.js +60 -0
  27. package/dist-pkg/input/keyboard-runtime.d.ts +0 -4
  28. package/dist-pkg/input/keyboard.d.ts +0 -1
  29. package/dist-pkg/input/keydown.d.ts +5 -11
  30. package/dist-pkg/input/keydown.js +3 -3
  31. package/dist-pkg/input/latch-edge.d.ts +10 -2
  32. package/dist-pkg/input/latch-edge.js +4 -3
  33. package/dist-pkg/input/latch-scope.d.ts +27 -22
  34. package/dist-pkg/input/latch-scope.js +25 -37
  35. package/dist-pkg/input/latch-store.d.ts +9 -12
  36. package/dist-pkg/input/latch-store.js +13 -18
  37. package/dist-pkg/input/latch-sync.d.ts +5 -4
  38. package/dist-pkg/input/latch-sync.js +5 -5
  39. package/dist-pkg/input/pad-reading.js +7 -2
  40. package/dist-pkg/input/pad-wizard.d.ts +4 -1
  41. package/dist-pkg/input/pad-wizard.js +60 -9
  42. package/dist-pkg/input/switch-scan.d.ts +29 -12
  43. package/dist-pkg/input/switch-scan.js +15 -2
  44. package/dist-pkg/input/touch-bindings.d.ts +3 -6
  45. package/dist-pkg/input/touch.d.ts +17 -2
  46. package/dist-pkg/input/touch.js +55 -17
  47. package/dist-pkg/input/transport-in-use.d.ts +5 -5
  48. package/dist-pkg/input/transport-in-use.js +5 -5
  49. package/dist-pkg/input/transports.d.ts +0 -9
  50. package/dist-pkg/input/transports.js +1 -1
  51. package/dist-pkg/input/virtual-controller.d.ts +39 -3
  52. package/dist-pkg/input/virtual-controller.js +32 -4
  53. package/dist-pkg/input/voice-map.d.ts +27 -11
  54. package/dist-pkg/input/voice-map.js +41 -43
  55. package/dist-pkg/platform/audio-ambient.d.ts +0 -1
  56. package/dist-pkg/platform/audio-ambient.js +3 -1
  57. package/dist-pkg/platform/audio-mixer.js +4 -9
  58. package/dist-pkg/platform/audio-sonar.d.ts +8 -94
  59. package/dist-pkg/platform/audio-sonar.js +22 -207
  60. package/dist-pkg/platform/audio.d.ts +10 -1
  61. package/dist-pkg/platform/audio.js +35 -2
  62. package/dist-pkg/platform/choose-by-voice.d.ts +70 -0
  63. package/dist-pkg/platform/choose-by-voice.js +157 -0
  64. package/dist-pkg/platform/font-library.d.ts +77 -0
  65. package/dist-pkg/platform/font-library.js +98 -0
  66. package/dist-pkg/platform/font-library.json +721 -0
  67. package/dist-pkg/platform/heavy-catalogue.d.ts +46 -0
  68. package/dist-pkg/platform/heavy-catalogue.js +47 -14
  69. package/dist-pkg/platform/heavy-mirror.d.ts +3 -9
  70. package/dist-pkg/platform/heavy-mirror.js +14 -17
  71. package/dist-pkg/platform/heavy.d.ts +40 -8
  72. package/dist-pkg/platform/heavy.js +177 -22
  73. package/dist-pkg/platform/interruptible-speech.d.ts +15 -8
  74. package/dist-pkg/platform/interruptible-speech.js +37 -13
  75. package/dist-pkg/platform/listener-scope.js +22 -13
  76. package/dist-pkg/platform/locale-host.d.ts +7 -3
  77. package/dist-pkg/platform/locale-host.js +13 -2
  78. package/dist-pkg/platform/reading-in-worker.d.ts +24 -0
  79. package/dist-pkg/platform/reading-in-worker.js +38 -0
  80. package/dist-pkg/platform/reading-model.d.ts +21 -0
  81. package/dist-pkg/platform/reading-model.js +25 -0
  82. package/dist-pkg/platform/reading-runtime.js +13 -8
  83. package/dist-pkg/platform/reading.d.ts +12 -1
  84. package/dist-pkg/platform/reading.js +9 -1
  85. package/dist-pkg/platform/speech-recognition.d.ts +10 -1
  86. package/dist-pkg/platform/speech-recognition.js +29 -9
  87. package/dist-pkg/platform/speech.d.ts +10 -1
  88. package/dist-pkg/platform/speech.js +24 -13
  89. package/dist-pkg/platform/tts.d.ts +37 -4
  90. package/dist-pkg/platform/tts.js +279 -57
  91. package/dist-pkg/platform/voice-listener.d.ts +6 -2
  92. package/dist-pkg/platform/voice-listener.js +1 -1
  93. package/dist-pkg/platform/voice-plan.d.ts +13 -0
  94. package/dist-pkg/platform/voice-plan.js +57 -2
  95. package/dist-pkg/platform/vosk-runtime.d.ts +25 -0
  96. package/dist-pkg/platform/vosk-runtime.js +59 -1
  97. package/dist-pkg/platform/vosk-vocabulary.d.ts +6 -0
  98. package/dist-pkg/platform/vosk-vocabulary.js +178 -0
  99. package/dist-pkg/render/crt.d.ts +11 -9
  100. package/dist-pkg/render/crt.js +6 -10
  101. package/dist-pkg/render/cvd-matrices.d.ts +5 -1
  102. package/dist-pkg/render/cvd-matrices.js +5 -1
  103. package/dist-pkg/render/high-contrast.d.ts +1 -2
  104. package/dist-pkg/render/high-contrast.js +5 -1
  105. package/dist-pkg/render/viz-axes.d.ts +9 -0
  106. package/dist-pkg/render/viz-axes.js +15 -2
  107. package/dist-pkg/ui/aac-sets.d.ts +29 -24
  108. package/dist-pkg/ui/aac-sets.js +22 -30
  109. package/dist-pkg/ui/audio-choices.d.ts +10 -5
  110. package/dist-pkg/ui/audio-choices.js +14 -10
  111. package/dist-pkg/ui/camera-control.d.ts +47 -0
  112. package/dist-pkg/ui/camera-control.js +35 -1
  113. package/dist-pkg/ui/declared-words.d.ts +21 -0
  114. package/dist-pkg/ui/declared-words.js +66 -0
  115. package/dist-pkg/ui/drawing-problems.js +4 -3
  116. package/dist-pkg/ui/eye-control.js +17 -17
  117. package/dist-pkg/ui/face-control.js +15 -15
  118. package/dist-pkg/ui/fonts.d.ts +42 -8
  119. package/dist-pkg/ui/fonts.js +58 -24
  120. package/dist-pkg/ui/footer-scroll-driver.d.ts +14 -0
  121. package/dist-pkg/ui/footer-scroll-driver.js +201 -0
  122. package/dist-pkg/ui/footer-scroll.d.ts +38 -0
  123. package/dist-pkg/ui/footer-scroll.js +55 -0
  124. package/dist-pkg/ui/game-options.d.ts +14 -9
  125. package/dist-pkg/ui/game-options.js +41 -21
  126. package/dist-pkg/ui/hand-control.js +15 -15
  127. package/dist-pkg/ui/help-panel.d.ts +19 -8
  128. package/dist-pkg/ui/help-panel.js +15 -5
  129. package/dist-pkg/ui/hud-bands.d.ts +29 -12
  130. package/dist-pkg/ui/hud-bands.js +63 -25
  131. package/dist-pkg/ui/hud-row.d.ts +34 -0
  132. package/dist-pkg/ui/hud-row.js +80 -0
  133. package/dist-pkg/ui/hud.d.ts +0 -3
  134. package/dist-pkg/ui/layout.js +5 -2
  135. package/dist-pkg/ui/libras-avatar-clip.d.ts +30 -0
  136. package/dist-pkg/ui/libras-avatar-clip.js +86 -0
  137. package/dist-pkg/ui/libras-avatar-load.d.ts +52 -0
  138. package/dist-pkg/ui/libras-avatar-load.js +134 -0
  139. package/dist-pkg/ui/libras-avatar-plan.d.ts +102 -0
  140. package/dist-pkg/ui/libras-avatar-plan.js +211 -0
  141. package/dist-pkg/ui/libras-avatar-player.d.ts +28 -0
  142. package/dist-pkg/ui/libras-avatar-player.js +226 -0
  143. package/dist-pkg/ui/libras-avatar-stage.d.ts +37 -0
  144. package/dist-pkg/ui/libras-avatar-stage.js +208 -0
  145. package/dist-pkg/ui/libras-glosses.d.ts +28 -0
  146. package/dist-pkg/ui/libras-glosses.js +161 -0
  147. package/dist-pkg/ui/menu-intent.d.ts +29 -0
  148. package/dist-pkg/ui/menu-intent.js +35 -1
  149. package/dist-pkg/ui/menu-items.d.ts +10 -0
  150. package/dist-pkg/ui/menu-items.js +29 -0
  151. package/dist-pkg/ui/menu-nav.d.ts +40 -4
  152. package/dist-pkg/ui/menu-nav.js +132 -47
  153. package/dist-pkg/ui/panel-widgets.d.ts +34 -0
  154. package/dist-pkg/ui/panel-widgets.js +86 -0
  155. package/dist-pkg/ui/pause-icons.d.ts +30 -14
  156. package/dist-pkg/ui/pause-icons.js +106 -45
  157. package/dist-pkg/ui/scan-overlay.d.ts +3 -3
  158. package/dist-pkg/ui/scan-overlay.js +11 -3
  159. package/dist-pkg/ui/screen-text.d.ts +25 -0
  160. package/dist-pkg/ui/screen-text.js +152 -0
  161. package/dist-pkg/ui/session-clock.d.ts +32 -0
  162. package/dist-pkg/ui/session-clock.js +67 -0
  163. package/dist-pkg/ui/settings-aac.d.ts +3 -1
  164. package/dist-pkg/ui/settings-aac.js +32 -13
  165. package/dist-pkg/ui/settings-audio.d.ts +10 -5
  166. package/dist-pkg/ui/settings-audio.js +101 -35
  167. package/dist-pkg/ui/settings-controls.d.ts +0 -4
  168. package/dist-pkg/ui/settings-mobility.d.ts +3 -6
  169. package/dist-pkg/ui/settings-mobility.js +4 -46
  170. package/dist-pkg/ui/settings-motion.js +2 -2
  171. package/dist-pkg/ui/settings-panel.d.ts +10 -0
  172. package/dist-pkg/ui/settings-panel.js +25 -1
  173. package/dist-pkg/ui/settings-typo.d.ts +5 -6
  174. package/dist-pkg/ui/settings-typo.js +20 -11
  175. package/dist-pkg/ui/settings-visual.js +2 -2
  176. package/dist-pkg/ui/shell.d.ts +1 -3
  177. package/dist-pkg/ui/shell.js +8 -4
  178. package/dist-pkg/ui/title.d.ts +2 -11
  179. package/dist-pkg/ui/title.js +39 -6
  180. package/dist-pkg/ui/top-band.d.ts +5 -3
  181. package/dist-pkg/ui/top-band.js +21 -25
  182. package/dist-pkg/ui/typo-choices.d.ts +3 -3
  183. package/dist-pkg/ui/typo-choices.js +9 -8
  184. package/dist-pkg/ui/vlibras.d.ts +71 -27
  185. package/dist-pkg/ui/vlibras.js +116 -44
  186. package/dist-pkg/ui/voice-control.d.ts +23 -1
  187. package/dist-pkg/ui/voice-control.js +149 -16
  188. package/dist-pkg/ui/voice-settings.d.ts +2 -3
  189. package/dist-pkg/ui/voice-settings.js +53 -3
  190. package/dist-pkg/ui/where-the-child-is.js +2 -2
  191. package/docs/CREDITS.md +122 -10
  192. package/docs/LICENSES.md +36 -7
  193. package/package.json +34 -9
  194. package/scripts/check-cartridge.mjs +78 -0
  195. package/scripts/game-build.d.mts +25 -0
  196. package/scripts/game-build.mjs +144 -0
  197. package/scripts/heavy-into-the-delivery.mjs +284 -40
  198. package/scripts/libras-avatar.json +680 -0
  199. package/scripts/libras-avatar.mjs +246 -0
  200. package/scripts/libras-glosses/gloss.py +95 -0
  201. package/scripts/libras-glosses/pyproject.toml +32 -0
  202. package/scripts/libras-glosses/uv.lock +781 -0
  203. package/scripts/libras-glosses.mjs +351 -0
  204. package/scripts/licences/OFL-1.1.txt +86 -0
  205. package/scripts/licences/UFL-1.0.txt +96 -0
  206. package/scripts/licences/fonts.mjs +389 -0
  207. package/scripts/licences/third-party.mjs +35 -21
  208. package/app/public/vendor/fonts/bitter-var-ext.woff2 +0 -0
  209. package/app/public/vendor/fonts/bitter-var.woff2 +0 -0
  210. package/app/public/vendor/fonts/bodonimoda-var-ext.woff2 +0 -0
  211. package/app/public/vendor/fonts/bodonimoda-var.woff2 +0 -0
  212. package/app/public/vendor/fonts/cat-abril_fatface-400-ext.woff2 +0 -0
  213. package/app/public/vendor/fonts/cat-abril_fatface-400.woff2 +0 -0
  214. package/app/public/vendor/fonts/cat-adlam_display-400-ext.woff2 +0 -0
  215. package/app/public/vendor/fonts/cat-adlam_display-400.woff2 +0 -0
  216. package/app/public/vendor/fonts/cat-agu_display-400-ext.woff2 +0 -0
  217. package/app/public/vendor/fonts/cat-agu_display-400.woff2 +0 -0
  218. package/app/public/vendor/fonts/cat-alfa_slab_one-400-ext.woff2 +0 -0
  219. package/app/public/vendor/fonts/cat-alfa_slab_one-400.woff2 +0 -0
  220. package/app/public/vendor/fonts/cat-are_you_serious-400-ext.woff2 +0 -0
  221. package/app/public/vendor/fonts/cat-are_you_serious-400.woff2 +0 -0
  222. package/app/public/vendor/fonts/cat-asimovian-400-ext.woff2 +0 -0
  223. package/app/public/vendor/fonts/cat-asimovian-400.woff2 +0 -0
  224. package/app/public/vendor/fonts/cat-atkinson_hyperlegible_next-400-ext.woff2 +0 -0
  225. package/app/public/vendor/fonts/cat-atkinson_hyperlegible_next-400.woff2 +0 -0
  226. package/app/public/vendor/fonts/cat-bakbak_one-400-ext.woff2 +0 -0
  227. package/app/public/vendor/fonts/cat-bakbak_one-400.woff2 +0 -0
  228. package/app/public/vendor/fonts/cat-bangers-400-ext.woff2 +0 -0
  229. package/app/public/vendor/fonts/cat-bangers-400.woff2 +0 -0
  230. package/app/public/vendor/fonts/cat-barriecito-400-ext.woff2 +0 -0
  231. package/app/public/vendor/fonts/cat-barriecito-400.woff2 +0 -0
  232. package/app/public/vendor/fonts/cat-berkshire_swash-400-ext.woff2 +0 -0
  233. package/app/public/vendor/fonts/cat-berkshire_swash-400.woff2 +0 -0
  234. package/app/public/vendor/fonts/cat-bevan-400-ext.woff2 +0 -0
  235. package/app/public/vendor/fonts/cat-bevan-400.woff2 +0 -0
  236. package/app/public/vendor/fonts/cat-bitcount-400-ext.woff2 +0 -0
  237. package/app/public/vendor/fonts/cat-bitcount-400.woff2 +0 -0
  238. package/app/public/vendor/fonts/cat-bowlby_one_sc-400-ext.woff2 +0 -0
  239. package/app/public/vendor/fonts/cat-bowlby_one_sc-400.woff2 +0 -0
  240. package/app/public/vendor/fonts/cat-bungee_shade-400-ext.woff2 +0 -0
  241. package/app/public/vendor/fonts/cat-bungee_shade-400.woff2 +0 -0
  242. package/app/public/vendor/fonts/cat-charm-400-ext.woff2 +0 -0
  243. package/app/public/vendor/fonts/cat-charm-400.woff2 +0 -0
  244. package/app/public/vendor/fonts/cat-charm-700-ext.woff2 +0 -0
  245. package/app/public/vendor/fonts/cat-charm-700.woff2 +0 -0
  246. package/app/public/vendor/fonts/cat-cherry_bomb_one-400-ext.woff2 +0 -0
  247. package/app/public/vendor/fonts/cat-cherry_bomb_one-400.woff2 +0 -0
  248. package/app/public/vendor/fonts/cat-chokokutai-400-ext.woff2 +0 -0
  249. package/app/public/vendor/fonts/cat-chokokutai-400.woff2 +0 -0
  250. package/app/public/vendor/fonts/cat-chonburi-400-ext.woff2 +0 -0
  251. package/app/public/vendor/fonts/cat-chonburi-400.woff2 +0 -0
  252. package/app/public/vendor/fonts/cat-climate_crisis-400-ext.woff2 +0 -0
  253. package/app/public/vendor/fonts/cat-climate_crisis-400.woff2 +0 -0
  254. package/app/public/vendor/fonts/cat-cookie-400.woff2 +0 -0
  255. package/app/public/vendor/fonts/cat-dela_gothic_one-400-ext.woff2 +0 -0
  256. package/app/public/vendor/fonts/cat-dela_gothic_one-400.woff2 +0 -0
  257. package/app/public/vendor/fonts/cat-fascinate_inline-400-ext.woff2 +0 -0
  258. package/app/public/vendor/fonts/cat-fascinate_inline-400.woff2 +0 -0
  259. package/app/public/vendor/fonts/cat-ga_maamli-400-ext.woff2 +0 -0
  260. package/app/public/vendor/fonts/cat-ga_maamli-400.woff2 +0 -0
  261. package/app/public/vendor/fonts/cat-itim-400-ext.woff2 +0 -0
  262. package/app/public/vendor/fonts/cat-itim-400.woff2 +0 -0
  263. package/app/public/vendor/fonts/cat-jacquard_24-400-ext.woff2 +0 -0
  264. package/app/public/vendor/fonts/cat-jacquard_24-400.woff2 +0 -0
  265. package/app/public/vendor/fonts/cat-kablammo-400-ext.woff2 +0 -0
  266. package/app/public/vendor/fonts/cat-kablammo-400.woff2 +0 -0
  267. package/app/public/vendor/fonts/cat-kalam-400-ext.woff2 +0 -0
  268. package/app/public/vendor/fonts/cat-kalam-400.woff2 +0 -0
  269. package/app/public/vendor/fonts/cat-kalam-700-ext.woff2 +0 -0
  270. package/app/public/vendor/fonts/cat-kalam-700.woff2 +0 -0
  271. package/app/public/vendor/fonts/cat-katibeh-400-ext.woff2 +0 -0
  272. package/app/public/vendor/fonts/cat-katibeh-400.woff2 +0 -0
  273. package/app/public/vendor/fonts/cat-lemonada-400-ext.woff2 +0 -0
  274. package/app/public/vendor/fonts/cat-lemonada-400.woff2 +0 -0
  275. package/app/public/vendor/fonts/cat-lilita_one-400-ext.woff2 +0 -0
  276. package/app/public/vendor/fonts/cat-lilita_one-400.woff2 +0 -0
  277. package/app/public/vendor/fonts/cat-lobster-400-ext.woff2 +0 -0
  278. package/app/public/vendor/fonts/cat-lobster-400.woff2 +0 -0
  279. package/app/public/vendor/fonts/cat-luckiest_guy-400-ext.woff2 +0 -0
  280. package/app/public/vendor/fonts/cat-luckiest_guy-400.woff2 +0 -0
  281. package/app/public/vendor/fonts/cat-marhey-400-ext.woff2 +0 -0
  282. package/app/public/vendor/fonts/cat-marhey-400.woff2 +0 -0
  283. package/app/public/vendor/fonts/cat-modak-400-ext.woff2 +0 -0
  284. package/app/public/vendor/fonts/cat-modak-400.woff2 +0 -0
  285. package/app/public/vendor/fonts/cat-momo_signature-400-ext.woff2 +0 -0
  286. package/app/public/vendor/fonts/cat-momo_signature-400.woff2 +0 -0
  287. package/app/public/vendor/fonts/cat-monofett-400-ext.woff2 +0 -0
  288. package/app/public/vendor/fonts/cat-monofett-400.woff2 +0 -0
  289. package/app/public/vendor/fonts/cat-monomakh-400-ext.woff2 +0 -0
  290. package/app/public/vendor/fonts/cat-monomakh-400.woff2 +0 -0
  291. package/app/public/vendor/fonts/cat-monoton-400-ext.woff2 +0 -0
  292. package/app/public/vendor/fonts/cat-monoton-400.woff2 +0 -0
  293. package/app/public/vendor/fonts/cat-nerko_one-400-ext.woff2 +0 -0
  294. package/app/public/vendor/fonts/cat-nerko_one-400.woff2 +0 -0
  295. package/app/public/vendor/fonts/cat-noto_sans_adlam-400-ext.woff2 +0 -0
  296. package/app/public/vendor/fonts/cat-noto_sans_adlam-400.woff2 +0 -0
  297. package/app/public/vendor/fonts/cat-noto_sans_arabic-400-ext.woff2 +0 -0
  298. package/app/public/vendor/fonts/cat-noto_sans_arabic-400.woff2 +0 -0
  299. package/app/public/vendor/fonts/cat-noto_sans_devanagari-400-ext.woff2 +0 -0
  300. package/app/public/vendor/fonts/cat-noto_sans_devanagari-400.woff2 +0 -0
  301. package/app/public/vendor/fonts/cat-noto_sans_hebrew-400-ext.woff2 +0 -0
  302. package/app/public/vendor/fonts/cat-noto_sans_hebrew-400.woff2 +0 -0
  303. package/app/public/vendor/fonts/cat-noto_sans_jp-400-ext.woff2 +0 -0
  304. package/app/public/vendor/fonts/cat-noto_sans_jp-400.woff2 +0 -0
  305. package/app/public/vendor/fonts/cat-noto_sans_khmer-400-ext.woff2 +0 -0
  306. package/app/public/vendor/fonts/cat-noto_sans_khmer-400.woff2 +0 -0
  307. package/app/public/vendor/fonts/cat-noto_sans_kr-400-ext.woff2 +0 -0
  308. package/app/public/vendor/fonts/cat-noto_sans_kr-400.woff2 +0 -0
  309. package/app/public/vendor/fonts/cat-noto_sans_sc-400-ext.woff2 +0 -0
  310. package/app/public/vendor/fonts/cat-noto_sans_sc-400.woff2 +0 -0
  311. package/app/public/vendor/fonts/cat-noto_sans_thai-400-ext.woff2 +0 -0
  312. package/app/public/vendor/fonts/cat-noto_sans_thai-400.woff2 +0 -0
  313. package/app/public/vendor/fonts/cat-ole-400-ext.woff2 +0 -0
  314. package/app/public/vendor/fonts/cat-ole-400.woff2 +0 -0
  315. package/app/public/vendor/fonts/cat-pacifico-400-ext.woff2 +0 -0
  316. package/app/public/vendor/fonts/cat-pacifico-400.woff2 +0 -0
  317. package/app/public/vendor/fonts/cat-patrick_hand-400-ext.woff2 +0 -0
  318. package/app/public/vendor/fonts/cat-patrick_hand-400.woff2 +0 -0
  319. package/app/public/vendor/fonts/cat-petit_formal_script-400-ext.woff2 +0 -0
  320. package/app/public/vendor/fonts/cat-petit_formal_script-400.woff2 +0 -0
  321. package/app/public/vendor/fonts/cat-pixelify_sans-400-ext.woff2 +0 -0
  322. package/app/public/vendor/fonts/cat-pixelify_sans-400.woff2 +0 -0
  323. package/app/public/vendor/fonts/cat-plaster-400-ext.woff2 +0 -0
  324. package/app/public/vendor/fonts/cat-plaster-400.woff2 +0 -0
  325. package/app/public/vendor/fonts/cat-playwrite_ar_guides-400-0.woff2 +0 -0
  326. package/app/public/vendor/fonts/cat-playwrite_at-400-0.woff2 +0 -0
  327. package/app/public/vendor/fonts/cat-playwrite_at_guides-400-0.woff2 +0 -0
  328. package/app/public/vendor/fonts/cat-playwrite_au_nsw-400-0.woff2 +0 -0
  329. package/app/public/vendor/fonts/cat-playwrite_au_nsw_guides-400-0.woff2 +0 -0
  330. package/app/public/vendor/fonts/cat-playwrite_au_qld-400-0.woff2 +0 -0
  331. package/app/public/vendor/fonts/cat-playwrite_au_qld_guides-400-0.woff2 +0 -0
  332. package/app/public/vendor/fonts/cat-playwrite_au_sa-400-0.woff2 +0 -0
  333. package/app/public/vendor/fonts/cat-playwrite_au_sa_guides-400-0.woff2 +0 -0
  334. package/app/public/vendor/fonts/cat-playwrite_au_tas-400-0.woff2 +0 -0
  335. package/app/public/vendor/fonts/cat-playwrite_au_tas_guides-400-0.woff2 +0 -0
  336. package/app/public/vendor/fonts/cat-playwrite_au_vic-400-0.woff2 +0 -0
  337. package/app/public/vendor/fonts/cat-playwrite_au_vic_guides-400-0.woff2 +0 -0
  338. package/app/public/vendor/fonts/cat-playwrite_be_vlg-400-0.woff2 +0 -0
  339. package/app/public/vendor/fonts/cat-playwrite_be_vlg_guides-400-0.woff2 +0 -0
  340. package/app/public/vendor/fonts/cat-playwrite_be_wal-400-0.woff2 +0 -0
  341. package/app/public/vendor/fonts/cat-playwrite_be_wal_guides-400-0.woff2 +0 -0
  342. package/app/public/vendor/fonts/cat-playwrite_br_guides-400-0.woff2 +0 -0
  343. package/app/public/vendor/fonts/cat-playwrite_ca_guides-400-0.woff2 +0 -0
  344. package/app/public/vendor/fonts/cat-playwrite_cl_guides-400-0.woff2 +0 -0
  345. package/app/public/vendor/fonts/cat-playwrite_co_guides-400-0.woff2 +0 -0
  346. package/app/public/vendor/fonts/cat-playwrite_cu_guides-400-0.woff2 +0 -0
  347. package/app/public/vendor/fonts/cat-playwrite_cz-400-0.woff2 +0 -0
  348. package/app/public/vendor/fonts/cat-playwrite_cz_guides-400-0.woff2 +0 -0
  349. package/app/public/vendor/fonts/cat-playwrite_de_grund-400-0.woff2 +0 -0
  350. package/app/public/vendor/fonts/cat-playwrite_de_grund_guides-400-0.woff2 +0 -0
  351. package/app/public/vendor/fonts/cat-playwrite_de_la-400-0.woff2 +0 -0
  352. package/app/public/vendor/fonts/cat-playwrite_de_la_guides-400-0.woff2 +0 -0
  353. package/app/public/vendor/fonts/cat-playwrite_de_sas-400-0.woff2 +0 -0
  354. package/app/public/vendor/fonts/cat-playwrite_de_sas_guides-400-0.woff2 +0 -0
  355. package/app/public/vendor/fonts/cat-playwrite_de_va-400-0.woff2 +0 -0
  356. package/app/public/vendor/fonts/cat-playwrite_de_va_guides-400-0.woff2 +0 -0
  357. package/app/public/vendor/fonts/cat-playwrite_dk_loopet-400-0.woff2 +0 -0
  358. package/app/public/vendor/fonts/cat-playwrite_dk_loopet_guides-400-0.woff2 +0 -0
  359. package/app/public/vendor/fonts/cat-playwrite_dk_uloopet-400-0.woff2 +0 -0
  360. package/app/public/vendor/fonts/cat-playwrite_dk_uloopet_guides-400-0.woff2 +0 -0
  361. package/app/public/vendor/fonts/cat-playwrite_es_deco_guides-400-0.woff2 +0 -0
  362. package/app/public/vendor/fonts/cat-playwrite_es_guides-400-0.woff2 +0 -0
  363. package/app/public/vendor/fonts/cat-playwrite_fr_moderne-400-0.woff2 +0 -0
  364. package/app/public/vendor/fonts/cat-playwrite_fr_moderne_guides-400-0.woff2 +0 -0
  365. package/app/public/vendor/fonts/cat-playwrite_fr_trad-400-0.woff2 +0 -0
  366. package/app/public/vendor/fonts/cat-playwrite_fr_trad_guides-400-0.woff2 +0 -0
  367. package/app/public/vendor/fonts/cat-playwrite_gb_j_guides-400-0.woff2 +0 -0
  368. package/app/public/vendor/fonts/cat-playwrite_gb_s_guides-400-0.woff2 +0 -0
  369. package/app/public/vendor/fonts/cat-playwrite_hr-400-0.woff2 +0 -0
  370. package/app/public/vendor/fonts/cat-playwrite_hr_guides-400-0.woff2 +0 -0
  371. package/app/public/vendor/fonts/cat-playwrite_hr_lijeva-400-0.woff2 +0 -0
  372. package/app/public/vendor/fonts/cat-playwrite_hr_lijeva_guides-400-0.woff2 +0 -0
  373. package/app/public/vendor/fonts/cat-playwrite_hu-400-0.woff2 +0 -0
  374. package/app/public/vendor/fonts/cat-playwrite_hu_guides-400-0.woff2 +0 -0
  375. package/app/public/vendor/fonts/cat-playwrite_id-400-0.woff2 +0 -0
  376. package/app/public/vendor/fonts/cat-playwrite_id_guides-400-0.woff2 +0 -0
  377. package/app/public/vendor/fonts/cat-playwrite_ie-400-0.woff2 +0 -0
  378. package/app/public/vendor/fonts/cat-playwrite_ie_guides-400-0.woff2 +0 -0
  379. package/app/public/vendor/fonts/cat-playwrite_in-400-0.woff2 +0 -0
  380. package/app/public/vendor/fonts/cat-playwrite_in_guides-400-0.woff2 +0 -0
  381. package/app/public/vendor/fonts/cat-playwrite_is-400-0.woff2 +0 -0
  382. package/app/public/vendor/fonts/cat-playwrite_is_guides-400-0.woff2 +0 -0
  383. package/app/public/vendor/fonts/cat-playwrite_it_moderna-400-0.woff2 +0 -0
  384. package/app/public/vendor/fonts/cat-playwrite_it_moderna_guides-400-0.woff2 +0 -0
  385. package/app/public/vendor/fonts/cat-playwrite_it_trad-400-0.woff2 +0 -0
  386. package/app/public/vendor/fonts/cat-playwrite_it_trad_guides-400-0.woff2 +0 -0
  387. package/app/public/vendor/fonts/cat-playwrite_mx_guides-400-0.woff2 +0 -0
  388. package/app/public/vendor/fonts/cat-playwrite_ng_modern-400-0.woff2 +0 -0
  389. package/app/public/vendor/fonts/cat-playwrite_ng_modern_guides-400-0.woff2 +0 -0
  390. package/app/public/vendor/fonts/cat-playwrite_nl-400-0.woff2 +0 -0
  391. package/app/public/vendor/fonts/cat-playwrite_nl_guides-400-0.woff2 +0 -0
  392. package/app/public/vendor/fonts/cat-playwrite_no-400-0.woff2 +0 -0
  393. package/app/public/vendor/fonts/cat-playwrite_no_guides-400-0.woff2 +0 -0
  394. package/app/public/vendor/fonts/cat-playwrite_nz-400-0.woff2 +0 -0
  395. package/app/public/vendor/fonts/cat-playwrite_nz_basic-400-0.woff2 +0 -0
  396. package/app/public/vendor/fonts/cat-playwrite_nz_basic_guides-400-0.woff2 +0 -0
  397. package/app/public/vendor/fonts/cat-playwrite_nz_guides-400-0.woff2 +0 -0
  398. package/app/public/vendor/fonts/cat-playwrite_pe_guides-400-0.woff2 +0 -0
  399. package/app/public/vendor/fonts/cat-playwrite_pl-400-0.woff2 +0 -0
  400. package/app/public/vendor/fonts/cat-playwrite_pl_guides-400-0.woff2 +0 -0
  401. package/app/public/vendor/fonts/cat-playwrite_pt_guides-400-0.woff2 +0 -0
  402. package/app/public/vendor/fonts/cat-playwrite_ro-400-0.woff2 +0 -0
  403. package/app/public/vendor/fonts/cat-playwrite_ro_guides-400-0.woff2 +0 -0
  404. package/app/public/vendor/fonts/cat-playwrite_sk-400-0.woff2 +0 -0
  405. package/app/public/vendor/fonts/cat-playwrite_sk_guides-400-0.woff2 +0 -0
  406. package/app/public/vendor/fonts/cat-playwrite_tz-400-0.woff2 +0 -0
  407. package/app/public/vendor/fonts/cat-playwrite_tz_guides-400-0.woff2 +0 -0
  408. package/app/public/vendor/fonts/cat-playwrite_us_modern_guides-400-0.woff2 +0 -0
  409. package/app/public/vendor/fonts/cat-playwrite_us_trad_guides-400-0.woff2 +0 -0
  410. package/app/public/vendor/fonts/cat-playwrite_vn-400-0.woff2 +0 -0
  411. package/app/public/vendor/fonts/cat-playwrite_vn_guides-400-0.woff2 +0 -0
  412. package/app/public/vendor/fonts/cat-playwrite_za-400-0.woff2 +0 -0
  413. package/app/public/vendor/fonts/cat-playwrite_za_guides-400-0.woff2 +0 -0
  414. package/app/public/vendor/fonts/cat-potta_one-400-ext.woff2 +0 -0
  415. package/app/public/vendor/fonts/cat-potta_one-400.woff2 +0 -0
  416. package/app/public/vendor/fonts/cat-ranchers-400-ext.woff2 +0 -0
  417. package/app/public/vendor/fonts/cat-ranchers-400.woff2 +0 -0
  418. package/app/public/vendor/fonts/cat-ranga-400-ext.woff2 +0 -0
  419. package/app/public/vendor/fonts/cat-ranga-400.woff2 +0 -0
  420. package/app/public/vendor/fonts/cat-ranga-700-ext.woff2 +0 -0
  421. package/app/public/vendor/fonts/cat-ranga-700.woff2 +0 -0
  422. package/app/public/vendor/fonts/cat-risque-400-ext.woff2 +0 -0
  423. package/app/public/vendor/fonts/cat-risque-400.woff2 +0 -0
  424. package/app/public/vendor/fonts/cat-rowdies-400-ext.woff2 +0 -0
  425. package/app/public/vendor/fonts/cat-rowdies-400.woff2 +0 -0
  426. package/app/public/vendor/fonts/cat-rowdies-700-ext.woff2 +0 -0
  427. package/app/public/vendor/fonts/cat-rowdies-700.woff2 +0 -0
  428. package/app/public/vendor/fonts/cat-ruge_boogie-400-ext.woff2 +0 -0
  429. package/app/public/vendor/fonts/cat-ruge_boogie-400.woff2 +0 -0
  430. package/app/public/vendor/fonts/cat-ruslan_display-400-ext.woff2 +0 -0
  431. package/app/public/vendor/fonts/cat-ruslan_display-400.woff2 +0 -0
  432. package/app/public/vendor/fonts/cat-sacramento-400-ext.woff2 +0 -0
  433. package/app/public/vendor/fonts/cat-sacramento-400.woff2 +0 -0
  434. package/app/public/vendor/fonts/cat-sancreek-400-ext.woff2 +0 -0
  435. package/app/public/vendor/fonts/cat-sancreek-400.woff2 +0 -0
  436. package/app/public/vendor/fonts/cat-sankofa_display-400-ext.woff2 +0 -0
  437. package/app/public/vendor/fonts/cat-sankofa_display-400.woff2 +0 -0
  438. package/app/public/vendor/fonts/cat-sedgwick_ave_display-400-ext.woff2 +0 -0
  439. package/app/public/vendor/fonts/cat-sedgwick_ave_display-400.woff2 +0 -0
  440. package/app/public/vendor/fonts/cat-shantell_sans-400-ext.woff2 +0 -0
  441. package/app/public/vendor/fonts/cat-shantell_sans-400.woff2 +0 -0
  442. package/app/public/vendor/fonts/cat-smokum-400-ext.woff2 +0 -0
  443. package/app/public/vendor/fonts/cat-smokum-400.woff2 +0 -0
  444. package/app/public/vendor/fonts/cat-solitreo-400-ext.woff2 +0 -0
  445. package/app/public/vendor/fonts/cat-solitreo-400.woff2 +0 -0
  446. package/app/public/vendor/fonts/cat-spicy_rice-400-ext.woff2 +0 -0
  447. package/app/public/vendor/fonts/cat-spicy_rice-400.woff2 +0 -0
  448. package/app/public/vendor/fonts/cat-sriracha-400-ext.woff2 +0 -0
  449. package/app/public/vendor/fonts/cat-sriracha-400.woff2 +0 -0
  450. package/app/public/vendor/fonts/cat-srisakdi-400-ext.woff2 +0 -0
  451. package/app/public/vendor/fonts/cat-srisakdi-400.woff2 +0 -0
  452. package/app/public/vendor/fonts/cat-srisakdi-700-ext.woff2 +0 -0
  453. package/app/public/vendor/fonts/cat-srisakdi-700.woff2 +0 -0
  454. package/app/public/vendor/fonts/cat-stix_two_math-400-0.woff2 +0 -0
  455. package/app/public/vendor/fonts/cat-tillana-400-ext.woff2 +0 -0
  456. package/app/public/vendor/fonts/cat-tillana-400.woff2 +0 -0
  457. package/app/public/vendor/fonts/cat-tillana-700-ext.woff2 +0 -0
  458. package/app/public/vendor/fonts/cat-tillana-700.woff2 +0 -0
  459. package/app/public/vendor/fonts/cat-titan_one-400-ext.woff2 +0 -0
  460. package/app/public/vendor/fonts/cat-titan_one-400.woff2 +0 -0
  461. package/app/public/vendor/fonts/cat-yatra_one-400-ext.woff2 +0 -0
  462. package/app/public/vendor/fonts/cat-yatra_one-400.woff2 +0 -0
  463. package/app/public/vendor/fonts/cat-yomogi-400-ext.woff2 +0 -0
  464. package/app/public/vendor/fonts/cat-yomogi-400.woff2 +0 -0
  465. package/app/public/vendor/fonts/dmserifdisplay-400-ext.woff2 +0 -0
  466. package/app/public/vendor/fonts/dmserifdisplay-400.woff2 +0 -0
  467. package/app/public/vendor/fonts/domine-var-ext.woff2 +0 -0
  468. package/app/public/vendor/fonts/domine-var.woff2 +0 -0
  469. package/app/public/vendor/fonts/fondamento-400-ext.woff2 +0 -0
  470. package/app/public/vendor/fonts/fondamento-400.woff2 +0 -0
  471. package/app/public/vendor/fonts/fraunces-var-ext.woff2 +0 -0
  472. package/app/public/vendor/fonts/fraunces-var.woff2 +0 -0
  473. package/app/public/vendor/fonts/fredoka-var-ext.woff2 +0 -0
  474. package/app/public/vendor/fonts/fredoka-var.woff2 +0 -0
  475. package/app/public/vendor/fonts/inter-400.woff2 +0 -0
  476. package/app/public/vendor/fonts/inter-700.woff2 +0 -0
  477. package/app/public/vendor/fonts/jakarta-var-ext.woff2 +0 -0
  478. package/app/public/vendor/fonts/jakarta-var.woff2 +0 -0
  479. package/app/public/vendor/fonts/lato-400.woff2 +0 -0
  480. package/app/public/vendor/fonts/lato-700.woff2 +0 -0
  481. package/app/public/vendor/fonts/literata-400.woff2 +0 -0
  482. package/app/public/vendor/fonts/literata-700.woff2 +0 -0
  483. package/app/public/vendor/fonts/lora-var-ext.woff2 +0 -0
  484. package/app/public/vendor/fonts/lora-var.woff2 +0 -0
  485. package/app/public/vendor/fonts/merriweather-var-ext.woff2 +0 -0
  486. package/app/public/vendor/fonts/merriweather-var.woff2 +0 -0
  487. package/app/public/vendor/fonts/newsreader-400.woff2 +0 -0
  488. package/app/public/vendor/fonts/newsreader-700.woff2 +0 -0
  489. package/app/public/vendor/fonts/notosans-var-ext.woff2 +0 -0
  490. package/app/public/vendor/fonts/notosans-var.woff2 +0 -0
  491. package/app/public/vendor/fonts/nunito-var-ext.woff2 +0 -0
  492. package/app/public/vendor/fonts/nunito-var.woff2 +0 -0
  493. package/app/public/vendor/fonts/opendyslexic-400.woff2 +0 -0
  494. package/app/public/vendor/fonts/opensans-400.woff2 +0 -0
  495. package/app/public/vendor/fonts/opensans-700.woff2 +0 -0
  496. package/app/public/vendor/fonts/pinyon-400.woff2 +0 -0
  497. package/app/public/vendor/fonts/playfair-var-ext.woff2 +0 -0
  498. package/app/public/vendor/fonts/playfair-var.woff2 +0 -0
  499. package/app/public/vendor/fonts/pressstart-400.woff2 +0 -0
  500. package/app/public/vendor/fonts/quattro-400.woff2 +0 -0
  501. package/app/public/vendor/fonts/quattro-700.woff2 +0 -0
  502. package/app/public/vendor/fonts/quicksand-var-ext.woff2 +0 -0
  503. package/app/public/vendor/fonts/quicksand-var.woff2 +0 -0
  504. package/app/public/vendor/fonts/robotoflex-var-ext.woff2 +0 -0
  505. package/app/public/vendor/fonts/robotoflex-var.woff2 +0 -0
  506. package/app/public/vendor/fonts/sora-var-ext.woff2 +0 -0
  507. package/app/public/vendor/fonts/sora-var.woff2 +0 -0
  508. package/app/public/vendor/fonts/sourcesans-400.woff2 +0 -0
  509. package/app/public/vendor/fonts/sourcesans-700.woff2 +0 -0
  510. package/app/public/vendor/fonts/sourceserif-400.woff2 +0 -0
  511. package/app/public/vendor/fonts/sourceserif-700.woff2 +0 -0
  512. package/app/public/vendor/fonts/spacegrotesk-var-ext.woff2 +0 -0
  513. package/app/public/vendor/fonts/spacegrotesk-var.woff2 +0 -0
  514. package/app/public/vendor/fonts/spectral-400-ext.woff2 +0 -0
  515. package/app/public/vendor/fonts/spectral-400.woff2 +0 -0
  516. package/app/public/vendor/fonts/spectral-700-ext.woff2 +0 -0
  517. package/app/public/vendor/fonts/spectral-700.woff2 +0 -0
  518. package/app/public/vendor/fonts/teachers-var-ext.woff2 +0 -0
  519. package/app/public/vendor/fonts/teachers-var.woff2 +0 -0
  520. package/app/public/vendor/fonts/ubuntu-400-ext.woff2 +0 -0
  521. package/app/public/vendor/fonts/ubuntu-400.woff2 +0 -0
  522. package/app/public/vendor/fonts/ubuntu-700-ext.woff2 +0 -0
  523. package/app/public/vendor/fonts/ubuntu-700.woff2 +0 -0
  524. package/app/public/vendor/fonts/ufmag-400.woff2 +0 -0
  525. package/dist-pkg/platform/guide-intensity.d.ts +0 -39
  526. package/dist-pkg/platform/guide-intensity.js +0 -71
  527. package/dist-pkg/ui/latch-refusal.d.ts +0 -33
  528. package/dist-pkg/ui/latch-refusal.js +0 -60
@@ -29,10 +29,13 @@ const pt = {
29
29
  // de cima é para quem ESCUTA, esta diz QUAL botão, porque quem a lê tem outras pessoas à volta.
30
30
  'hud.waitBadge': 'Jogador {n}: aperte um botão do SEU teclado ou de um controle livre para entrar',
31
31
  'sr.libras.loading': 'Intérprete de Libras ainda carregando — tente de novo em instantes.',
32
- // ⚠️ Esta frase não é lida: é SINALIZADA. Ela vai para o widget do VLibras no instante em que o modo liga, e é a primeira
33
- // coisa que o intérprete diz a quem acabou de o chamar — curta de propósito, e uma saudação, não um estado de sistema.
34
- 'sr.libras.on': 'Olá! O intérprete de Libras está ligado.',
32
+ // told to a deaf child when the sonar asks for signing and no interpreter can sign: what she keeps matters as much as what
33
+ // she lost (ADR-0234)
34
+ 'sr.deaf.noSigning': 'Sem intérprete de Libras agora: as legendas e o texto continuam na tela.',
35
+ // the accessible name of the interpreter's frame, in front of the screen while it signs (ADR-0234)
36
+ 'sr.deaf.interpreter': 'Intérprete de Libras',
35
37
  'sr.eyes.needsInternet': 'O controle pelo olhar ainda não chegou a este aparelho: ele desce na primeira vez que o jogo abre com internet.',
38
+ 'sr.eyes.failed': 'O controle pelo olhar não conseguiu começar neste aparelho.',
36
39
  // the eye control's words over the game (ADR-0213 §6): a region tells a preparing look which way to go, the opposite of itself
37
40
  'gaze.lookHere': 'Olhe aqui',
38
41
  'gaze.loading': 'Carregando...',
@@ -44,6 +47,7 @@ const pt = {
44
47
  'sr.face.ready': 'Pronto: já pode jogar com o rosto.',
45
48
  'sr.face.noCamera': 'O controle pelo rosto precisa da câmera, e ela não abriu. Permita a câmera para esta página.',
46
49
  'sr.face.needsInternet': 'O controle pelo rosto ainda não chegou a este aparelho: ele desce na primeira vez que o jogo abre com internet.',
50
+ 'sr.face.failed': 'O controle pelo rosto não conseguiu começar neste aparelho.',
47
51
  'sr.face.stopped': 'O controle pelo rosto parou de receber imagens da câmera.',
48
52
  'sr.face.slow': 'O controle pelo rosto está lento neste aparelho e pode não responder.',
49
53
  'sr.eyes.lookMiddle': 'Olhe para o meio da tela e não mexa os olhos até eu dizer pronto.',
@@ -66,6 +70,13 @@ const pt = {
66
70
  'hud.barra': '{nome}: {azuis} de primeira, {verdes} com ajuda, {vermelhos} sem acertar',
67
71
  'hud.barra.sobe': 'o nível sobe',
68
72
  'hud.barra.desce': 'o nível desce',
73
+ // The score in the HUD row is drawn as five digits (ADR-0238, ADR-0239); a listener hears the number itself, not the zeros.
74
+ 'hud.points': '{count} {name}',
75
+ // The session clock's accessible name (ADR-0236): the time left in words, never «0:45». Rewritten each whole minute.
76
+ 'clock.left': 'Tempo de jogo: faltam {minutes} minutos',
77
+ 'clock.left.one': 'Tempo de jogo: falta 1 minuto',
78
+ 'clock.over': 'Tempo de jogo: acabou',
79
+ 'clock.label': 'TEMPO', // the small word over the clock's digits (ADR-0239)
69
80
  // O NOME do que este jogo junta. Currículo não se traduz (pilar 3), mas "moedas" não é currículo — é um
70
81
  // substantivo comum da interface, e a criança que joga em inglês tem de ouvir "coins". Por isso o nome
71
82
  // atravessa por `{nome}` JÁ RESOLVIDO pelo jogo, e a chave mora aqui.
@@ -144,6 +155,7 @@ const pt = {
144
155
  'pause.motivo.ajuda': 'Este jogo ainda não disse o que cada botão faz.',
145
156
  'pause.motivo.addplayer': 'Quem decide quantos jogadores podem jogar é o jogo.',
146
157
  'pause.motivo.opcoesdojogo': 'Este jogo não tem opções próprias.',
158
+ 'pause.motivo.caa': 'Menu desabilitado',
147
159
  // Acessibilidade (leitores de tela)
148
160
  // Controles de toque — rótulos das 9 posições e das 9 ações mapeáveis (painel #touchcfg) e os anúncios.
149
161
  // Rótulo é MOLDURA inteira: em inglês "(cima)" vira "(up)" e a seta fica onde está, então a seta viaja
@@ -243,6 +255,17 @@ const pt = {
243
255
  'input.standard': 'padrão',
244
256
  'input.sticky': 'não precisa segurar',
245
257
  'scan.nothing': 'cancelar',
258
+ // One-button scanning inside a menu: that menu's own steps (ADR-0218 erratum of 2026-09-26, interface log).
259
+ 'scan.menu.next': 'próximo',
260
+ 'scan.menu.confirm': 'confirmar',
261
+ 'scan.menu.back': 'voltar',
262
+ 'scan.menu.previous': 'anterior',
263
+ // ...and, on a control with a value, the sideways step (the interface log's entry on the sideways step).
264
+ 'scan.menu.increase': 'aumentar',
265
+ 'scan.menu.decrease': 'diminuir',
266
+ // ...and the engine's two doors, offered in play after the game's own words (ADR-0218 §3).
267
+ 'scan.door.menus': 'menu',
268
+ 'scan.door.pause': 'pausar',
246
269
  'input.scan': 'um botão só',
247
270
  'icon.contrast': 'Alto contraste',
248
271
  'icon.cvd': 'Correção de daltonismo',
@@ -254,7 +277,7 @@ const pt = {
254
277
  'icon.velocidade.valor': '{pct}%',
255
278
  'icon.blind.dica': 'Joga-se pelo som: a navegação sonora diz o que a tela mostra.',
256
279
  'icon.tts.dica': 'O jogo lê em voz alta o que está escrito na tela.',
257
- 'icon.libras.dica': 'Um intérprete de Libras mostra em sinais o que o jogo diz.',
280
+ 'icon.libras.dica': 'Os sons ganham legenda, e o sonar chama um intérprete de Libras para o que está na tela.',
258
281
  'icon.tea.dica': 'Deixa o jogo mais calmo ou em silêncio, para quem se sobrecarrega com estímulos.',
259
282
  'icon.altmove.dica': 'Como os seus toques são lidos: do jeito padrão; ou com um toque que liga e outro que desliga, sem segurar; ou com um botão só, em que o jogo mostra cada coisa por vez e você aperta na que quer.',
260
283
  'sr.icon.inputMode': 'Jeito de apertar: {v}.',
@@ -273,9 +296,11 @@ const pt = {
273
296
  'sr.voice.noMicrophone': 'O controle por voz precisa do microfone, e ele não abriu. Permita o microfone para esta página.',
274
297
  'sr.voice.failed': 'O comando de voz não conseguiu começar neste aparelho.',
275
298
  'sr.voice.needsInternet': 'O controle por voz ainda não chegou a este aparelho: ele desce na primeira vez que o jogo abre com internet.',
299
+ 'sr.reading.failed': 'A leitura em voz alta não conseguiu começar neste idioma, neste aparelho.',
276
300
  'sr.hands.ready': 'Pronto: já pode jogar com gestos das mãos.',
277
301
  'sr.hands.noCamera': 'O controle por gestos precisa da câmera, e ela não abriu. Permita a câmera para esta página.',
278
302
  'sr.hands.needsInternet': 'O controle por gestos ainda não chegou a este aparelho: ele desce na primeira vez que o jogo abre com internet.',
303
+ 'sr.hands.failed': 'O controle por gestos não conseguiu começar neste aparelho.',
279
304
  'sr.hands.stopped': 'O controle por gestos parou de receber imagens da câmera.',
280
305
  'sr.hands.slow': 'O controle por gestos está lento neste aparelho e pode não responder.',
281
306
  'icon.menu': 'Menu',
@@ -359,6 +384,8 @@ const pt = {
359
384
  'pad.glyph.square': 'quadrado',
360
385
  'pad.glyph.triangle': 'triângulo',
361
386
  'pad.wiz.step': '{n} de {total} — aperte: {acao}',
387
+ 'pad.wiz.stepStart': '{n} de {total} — aperte o botão que você quer como START (ele pausa o jogo)',
388
+ 'pad.wiz.stepSelect': '{n} de {total} — aperte o botão que você quer como SELECT (ele abre os menus)',
362
389
  'pad.wiz.mapped': 'Mapeados: {lista}',
363
390
  'pad.wiz.pressAny': 'Aperte QUALQUER botão no controle que deseja mapear.',
364
391
  'pad.wiz.detected': 'Controle novo detectado: {id}. O jogo pausou para você configurá-lo. SOLTE tudo para começar.',
@@ -413,6 +440,7 @@ const pt = {
413
440
  'audio.noSystemVoices': '(sem vozes do sistema)',
414
441
  'sr.tts.engineNoLanguage': 'Este motor ainda não fala este idioma — por enquanto, use a voz do navegador.',
415
442
  'sr.tts.noNeuralForLanguage': 'Ainda não há voz neural para este idioma — seguindo com a voz do navegador, que fala a língua certa.',
443
+ 'sr.tts.noVoiceForLanguage': 'Este aparelho não tem voz em {language}: essa parte não é lida em voz alta, mas continua na tela.',
416
444
  // ⚠️ NÃO diz «para este idioma» (ADR-0094): sem motor neural nesta montagem, não há voz neural em idioma
417
445
  // nenhum, e a outra frase faria a criança trocar de idioma à procura do que não está lá.
418
446
  'sr.tts.neuralNotBundled': 'Esta versão do jogo não traz voz neural — seguindo com a voz do navegador.',
@@ -495,12 +523,13 @@ const pt = {
495
523
  'audio.cat.earcons': 'Earcons',
496
524
  'audio.cat.tts': 'Narração',
497
525
  'audio.cat.sonar': 'Sonar',
498
- 'audio.cat.guard': 'Guarda de beirada',
499
- 'audio.cat.guide': 'Pista / guia auditivo',
500
526
  'audio.cat.volumeDe': 'Volume de {c}',
501
527
  'audio.navsound.grupo': 'Sons de navegação',
502
528
  'audio.cane': 'Batida da bengala',
503
529
  'audio.cane.dica': 'De quanto em quanto chão a bengala bate. Uma batida por bloco é mais calma; a cada meio bloco dá mais detalhe.',
530
+ // the two positions of the cycle row «◀ Batida da bengala: … ▶» (ADR-0130 rule 3)
531
+ 'audio.cane.block': 'uma por bloco',
532
+ 'audio.cane.halfBlock': 'a cada meio bloco',
504
533
  'audio.menuindex': 'Índice falado dos menus',
505
534
  'audio.menuindex.dica': 'O leitor de tela diz "3 de 7" ao andar num menu, para saber onde se está sem contar.',
506
535
  'audio.tts.dica': 'O jogo lê em voz alta o que está escrito na tela.',
@@ -528,6 +557,7 @@ const pt = {
528
557
  'audio.voz': 'Voz',
529
558
  'audio.voz.nenhuma': 'Nenhuma voz',
530
559
  'audio.semVoz': 'Não há voz que fale este idioma.',
560
+ 'audio.comVoz': 'Agora há uma voz que fala este idioma.',
531
561
  'sr.audio.voz': 'Voz: {nome}.',
532
562
  'audio.ttsTest': 'Testar a voz',
533
563
  'audio.ttsTest.dica': 'Fala uma frase de exemplo com a voz escolhida agora.',
@@ -551,59 +581,31 @@ const pt = {
551
581
  'aac.letras': 'Letras maiúsculas',
552
582
  'aac.letras.dica': 'Ligado: o jogo inteiro em caixa alta, como a alfabetização brasileira costuma começar. '
553
583
  + 'Desligado: maiúsculas e minúsculas, a escrita do dia a dia.',
554
- 'aac.emPreparo': 'em preparação',
555
- 'aac.aguardandoNegociacao': 'aguardando negociação',
584
+ 'aac.noLicence': 'sem licença',
556
585
  'aac.secao.agora': 'Disponível agora',
557
586
  'aac.secao.agoraTag': 'funciona sem rede',
558
- 'aac.secao.preparo': 'Em preparação',
559
- 'aac.secao.preparoTag': 'licença resolvida; falta o trabalho',
560
- 'aac.secao.negociacao': 'Aguardando negociação',
561
- 'aac.secao.negociacaoTag': 'a permissão não é nossa',
587
+ 'aac.section.pictograms': 'Pictogramas',
588
+ 'aac.section.pictogramsTag': 'cada um só com licença',
562
589
  'sr.aac.escolha': 'Comunicação: {v}.',
563
590
  'sr.aac.reset': 'Comunicação restaurada ao padrão: letras maiúsculas, como a alfabetização costuma começar.',
564
591
  'pause.caa': 'Comunicação',
565
592
  'sr.aac.caixaAltaOn': 'Letras maiúsculas ligadas: o jogo inteiro em caixa alta.',
566
593
  'sr.aac.caixaAltaOff': 'Letras maiúsculas desligadas: maiúsculas e minúsculas.',
567
- 'sr.quiz.bemVindo': 'Quiz. Use as setas para escolher e Enter para responder.',
594
+ // The quiz's welcome: the frame is here, the child's own keys cross as `{mover}`/`{responder}` (consumer-quiz `welcomeText`).
595
+ 'sr.quiz.bemVindo': 'Quiz. Use {mover} para escolher e {responder} para responder.',
596
+ 'sr.quiz.bemVindo.soEscolher': 'Quiz. Use {mover} para escolher.',
597
+ 'sr.quiz.bemVindo.soResponder': 'Quiz. Use {responder} para responder.',
598
+ 'sr.quiz.bemVindo.semTeclas': 'Quiz. Toque numa resposta para responder.',
599
+ 'sr.quiz.teclas.duas': '{a} e {b}',
568
600
  // AS PERGUNTAS DO QUIZ. O quiz NÃO é uma disciplina de idioma, logo nem a excepção do `CLAUDE.md` §A FRONTEIRA
569
601
  // se aplica: «o ENUNCIADO SEMPRE TRADUZ». Eram literais em pt-BR dentro do cartucho até 23/09, e trocar a
570
602
  // bandeira mudava a moldura da engine sem tocar na atividade (ADR-0225).
571
603
  'quiz.pageTitle': 'The Inclusionist — quiz de demonstração',
572
- 'quiz.p1': 'Qual animal põe ovos e tem bico?',
573
- 'quiz.p1.a': 'Gato',
574
- 'quiz.p1.b': 'Galinha',
575
- 'quiz.p1.c': 'Cavalo',
576
- 'quiz.p1.d': 'Peixe',
577
- 'quiz.p2': 'Quantos lados tem um triângulo?',
578
- 'quiz.p2.a': 'Três',
579
- 'quiz.p2.b': 'Quatro',
580
- 'quiz.p2.c': 'Cinco',
581
- 'quiz.p2.d': 'Dois',
582
- 'quiz.p3': 'Qual destas é uma fruta?',
583
- 'quiz.p3.a': 'Alface',
584
- 'quiz.p3.b': 'Cenoura',
585
- 'quiz.p3.c': 'Banana',
586
- 'quiz.p3.d': 'Batata',
587
- 'quiz.pos.up': 'Acima',
588
- 'quiz.pos.down': 'Abaixo',
589
- 'quiz.pos.confirm': 'Confirmar',
590
- 'quiz.comoJogar.ler': 'Leia a pergunta no alto da tela.',
591
- 'quiz.comoJogar.escolher': 'Escolha a resposta com as setas e confirme.',
592
- 'quiz.pos.back': 'Voltar',
593
- 'quiz.pos.sonar': 'Sonar',
594
- 'quiz.pos.falar': 'Dizer a resposta',
604
+ 'quiz.carregando': 'Carregando…',
595
605
  'quiz.ouvindo': 'Estou ouvindo. Diga a resposta.',
596
- 'quiz.naoEntendi': 'Ouvi «{texto}», que não é nenhuma das alternativas. Diga de novo ou escolha com as setas.',
597
606
  'quiz.ouviNada': 'Não ouvi nada. Diga de novo ou escolha com as setas.',
598
607
  'quiz.semLeitura': 'Este aparelho não consegue ouvir agora. Escolha com as setas.',
599
- 'quiz.resposta.certa': 'Certo! {certa}.',
600
- 'quiz.resposta.errada': 'Ainda não. A resposta certa é {certa}.',
601
- 'quiz.fim': 'Fim! {n} de {m}.',
602
608
  'quiz.alternativas': 'Alternativas',
603
- 'quiz.acom.hints': 'Dicas',
604
- 'quiz.acom.textPace': 'Ritmo do texto',
605
- 'quiz.acom.lexicalDifficulty': 'Dificuldade das palavras',
606
- 'quiz.acom.wordHighlight': 'Realce de palavras',
607
609
  'sr.nav.sonarFound': 'Sonar: {alvo} {lado}, {dist}.',
608
610
  // `sr.nav.coin` ficou para o JOGO nomear o alvo (item 19): o sonar recebe o nome por `nameAt`, campo 3 do
609
611
  // contrato. `sr.nav.target` e o que ele diz quando o jogo declara um alvo SEM nome — melhor uma palavra
@@ -686,13 +688,6 @@ const pt = {
686
688
  'sr.motor.easyOff': 'Modo Fácil desligado.',
687
689
  'sr.motor.toggleMoveOn': 'Não precisa segurar, ligado: um toque liga e outro desliga.',
688
690
  'sr.motor.toggleMoveOff': 'Não precisa segurar, desligado.',
689
- // ⚠️ O MOTIVO É UM FACTO SOBRE O APARELHO, NUNCA UMA REPREENSÃO (ADR-0113 cláusula 3). Estas frases
690
- // dizem por que o botão não responde; «não desligue isto» repreenderia uma criança por mexer num ajuste
691
- // de que ela depende. QUATRO chaves e não uma com `{aparelho}`: «os gestos» é plural e «o olhar» não.
692
- 'alt.exigida.olhos': 'O controle por olhar precisa das teclas de alternância para funcionar.',
693
- 'alt.exigida.rosto': 'O controle por rosto precisa das teclas de alternância para funcionar.',
694
- 'alt.exigida.gestos': 'Os gestos precisam das teclas de alternância para funcionar.',
695
- 'alt.exigida.fala': 'O comando de voz precisa das teclas de alternância para funcionar.',
696
691
  'sr.motor.toggleRunOn': 'Alternância do correr ligada.',
697
692
  'sr.motor.toggleRunOff': 'Alternância do correr desligada.',
698
693
  // ===================== AJUDA (menu de pausa) + rótulo de nível =====================
@@ -777,7 +772,6 @@ const pt = {
777
772
  'font.group.arcade': 'Arcade',
778
773
  'font.desc.atkinson': 'feita pelo Braille Institute para pessoas com baixa visão (padrão do jogo)',
779
774
  'font.desc.lexend': 'feita para reduzir stress visual e atender pessoas disléxicas (ativa o espaçamento extra)',
780
- 'font.desc.quattro': 'criada para diminuir a fadiga visual de quem passa muito tempo na tela',
781
775
  'font.desc.andika': 'baseada na Sassoon; fruto de pesquisa sobre como crianças leem e escrevem',
782
776
  'font.desc.opendyslexic': 'Letras com a base mais pesada, para não virarem de cabeça para baixo ao ler.',
783
777
  'font.desc.fondamento': 'Caligráfica de pena, para as atividades de escrita à mão.',
@@ -793,8 +787,9 @@ const pt = {
793
787
  // ⚠️ AS TRÊS PELO NOME, e não «uma fonte ronde» (ADR-0108 §4): um adulto não consegue agir sobre uma
794
788
  // categoria. A frase existe para ser executável — abrir o navegador, procurar UM destes três nomes,
795
789
  // instalar. Nomear a categoria seria a mesma linha morta que este catálogo já removeu duas vezes.
796
- 'font.off.ronde': 'Instale no aparelho uma destas três: Ronde Script, OPTIFrench-Script ou Merveille. '
797
- + 'Elas são gratuitas para uso pessoal, e por isso não podem vir dentro do jogo.',
790
+ 'font.notice.ronde': 'Instale no aparelho uma destas três: Ronde Script, OPTIFrench-Script ou Merveille. '
791
+ + 'Elas são gratuitas para uso pessoal, e por isso não podem vir dentro do jogo. '
792
+ + 'Sem elas, o jogo mostra a Cookie: uma letra ligada parecida, mas que não é a ronde da escola.',
798
793
  'font.desc.greatvibes': 'caligráfica inglesa',
799
794
  'font.desc.pinyon': 'caligráfica inglesa',
800
795
  'font.desc.ufcook': 'blackletter alemã',
@@ -5,7 +5,6 @@ import { type PadMaps } from './pad-wizard.js';
5
5
  import type { PadTableFor } from './pad-defaults.js';
6
6
  import type { LiveInput } from './state.js';
7
7
  import { type PadLike, type GetGamepads, type PadMap, type ActionKey } from './pad-reading.js';
8
- export type { DomQuery } from '../core/dom-query.js';
9
8
  /**
10
9
  * The ORDER in which the wizard asks. ONLY the order — the same list `input/pad-wizard` walks, where it lives apart
11
10
  * from any game (issue #182).
@@ -17,7 +16,8 @@ export type { DomQuery } from '../core/dom-query.js';
17
16
  *
18
17
  * ⚠️ AND AN ACTION THE GAME DOES NOT NAME IS NOT ASKED. `input/pad-wizard` skips it, because a game that does not use
19
18
  * the position has nothing to map on it — and asking would produce a mute step or, worse, a step saying `action7` out
20
- * loud.
19
+ * loud. The exception is the system's two: START and SELECT are always asked, in the engine's words, because no game may
20
+ * name them and no pad may lack them (ADR-0144, erratum of 2026-09-26).
21
21
  */
22
22
  export declare const PADWIZ_ORDER: readonly string[];
23
23
  interface WizBase {
@@ -46,15 +46,14 @@ export interface WizState {
46
46
  import type { NavKeys } from './edges.js';
47
47
  import type { ModalIntent } from './keydown.js';
48
48
  import type { DomQuery } from '../core/dom-query.js';
49
- export type { NavKeys } from './edges.js';
50
49
  /** The minimal player shape this module reads/writes — DERIVED from core/entity, not retyped. There is no `quiz`
51
50
  * here (ADR-0033): the question is `ctx.hasModal(i)` and the answer is an INTENT, so this module never reads the
52
51
  * game's object. */
53
52
  export type GamepadPlayer = PlayerView<'pad' | 'quit' | 'waiting' | 'easy' | 'jumpEdge' | 'runEdge' | 'leftEdge' | 'rightEdge' | 'swapEdge' | 'specialEdge'>;
54
53
  /**
55
54
  * WHAT ONLY THE CARTRIDGE KNOWS ABOUT ITS WORLD (ADR-0224). The engine mounts this transport — as it mounts touch, the
56
- * eyes, the face, the hands, the voice and the scan —, and 📏 of `GamepadCtx`'s 25 doors the root answers 23 with what
57
- * it already has. These are the ones left, and they are the ones nothing in the engine can know.
55
+ * eyes, the face, the hands, the voice and the scan —, and the root answers every door of `GamepadCtx` it can with what it
56
+ * already has. These are the ones left, and they are the ones nothing in the engine can know.
58
57
  *
59
58
  * 🎯 **ALL OPTIONAL, AND EVERY ABSENCE HAS A WRITTEN MEANING** — never guessed (ADR-0113 clause 3, ADR-0169). A
60
59
  * cartridge that declares nothing has a working pad; what depends on its world simply does not happen. Refusing the
@@ -154,9 +153,15 @@ export interface GamepadCtx {
154
153
  worldRunning: () => boolean;
155
154
  /** Is the pause menu open? (START here RESUMES.) */
156
155
  pauseMenu: () => boolean;
157
- /** Pause and resume. The root stacks the scene; only the intent leaves from here. */
156
+ /**
157
+ * Pause and resume. The root stacks the scene; only the intent leaves from here. ⚠️ `pause` carries no seat: it is the
158
+ * mapping wizard's, which stops everything while a pad is mapped. START in play is PRESSED for the pad's seat (`press`).
159
+ * `resume` names the seat whose START asks it — the wizard's own resume is seat 0's, whose quick pause `pause` opened —, because
160
+ * the root decides whether that seat's START reaches this screen's pause: on a shared screen only the first seat's does
161
+ * (ADR-0144, erratum of 2026-09-26).
162
+ */
158
163
  pause: () => void;
159
- resume: () => void;
164
+ resume: (seat: number) => void;
160
165
  /** Demonstration (attract) mode. */
161
166
  isAttractActive: () => boolean;
162
167
  stopAttract: () => void;
@@ -174,6 +179,12 @@ export interface GamepadCtx {
174
179
  navBar: (i: number, k: NavKeys, hasStart: boolean) => void;
175
180
  sharedDialogOpen: () => HTMLElement | null;
176
181
  navDialog: (dlg: HTMLElement, k: NavKeys) => void;
182
+ /**
183
+ * Does this seat's pad steer the menus open on this screen — the dialog on top and the pause card? On a screen several players
184
+ * share, only the first's does (ADR-0144, erratum of 2026-09-26): another seat's d-pad and buttons move, press and close
185
+ * nothing there. Absent: every seat's does — each has a screen of her own. The same question `ui/menu-nav` asks of a key.
186
+ */
187
+ leadsTheScreen?: (seat: number) => boolean;
177
188
  /** The player's pause screen. `HTMLElement` and not `{ hidden: boolean }`: the structural minimum works for READING,
178
189
  * but this module HANDS the menu to `navPause`, which needs the whole element — and in parameter position the
179
190
  * minimal slice inverts (ADR-0039). */
@@ -185,9 +196,10 @@ export interface GamepadCtx {
185
196
  * THIS EDGE IS THIS PLAYER'S, AND IT CAME FROM THE PAD (ADR-0113 clause 4, issue #127).
186
197
  *
187
198
  * 🔴 REQUIRED: without it the input state's `playerEdge` has no caller for the pad, so `inputOf(i).inUse` answers
188
- * `teclado` for everyone — and the latch read is the keyboard's even with the pad in hand. 📌 Pass
189
- * `createLatchedEdge(() => players, { store, input })` from `input/latch-edge`, not the raw one: it also resolves this
190
- * device's latch on the player.
199
+ * `teclado` for everyone — and the latch read is the keyboard's even with the pad in hand. 📌 The latch is resolved where the
200
+ * pad's press lands: the root's virtual controller tells `pressedBy`, which records this edge through `input/latch-edge` too,
201
+ * so the root passes the raw one here. A host whose `press` does not reach such a door passes
202
+ * `createLatchedEdge(() => players, { store, input, holdsKeys })` instead.
191
203
  *
192
204
  * ⚠️ The gamepad is the transport that stays identifiable without the key set — it goes through `padCur` —, and that
193
205
  * is exactly why a gap here is invisible: the module knows which pad the edge came from, and the automaton does not.
@@ -204,9 +216,17 @@ export interface GamepadCtx {
204
216
  * 📌 REQUIRED, and ADR-0223's erratum says why: an optional door is one more field a game can forget, and forgetting
205
217
  * it brings back the silence this work exists to end. The root passes its virtual controller's `press`.
206
218
  */
207
- press: (action: ActionKey, source: 'gamepad', player: number) => boolean;
219
+ press: (action: ActionKey | 'start' | 'select', source: 'gamepad', player: number) => boolean;
208
220
  /** Release the POSITION. The controller lets go of the key it held and delivers the release — only for a press the game heard. */
209
221
  release: (action: ActionKey, source: 'gamepad', player: number) => void;
222
+ /**
223
+ * ONE BUTTON ONLY (ADR-0218 §4): asked once per frame in which a button of a pad WENT DOWN — a position, START or SELECT.
224
+ * `true`: one-button scanning took it as «take the one shown», and nothing else of that pad's frame happens. It is the question
225
+ * the virtual controller asks of every press (`takeShown` there); the pad asks it too because it also steers the pause card,
226
+ * a panel, the quick bar and the title, and opens and leaves the pause, by itself and without pressing a position.
227
+ * Absent: every press is itself.
228
+ */
229
+ takeShown?: () => boolean;
210
230
  /**
211
231
  * The player's OWN modal: the engine delivers the INTENT, the game decides (ADR-0033).
212
232
  *
@@ -229,6 +249,16 @@ export interface GamepadCtx {
229
249
  wizardStep: (position: string | null) => void;
230
250
  /** One tick of the wizard's clock for that demonstration (`GamepadGameHooks.wizardTick`). */
231
251
  wizardTick: () => void;
252
+ /**
253
+ * THIS TRANSPORT'S OWN WIZARD HAS CLOSED (ADR-0248), whichever way it ended — saved, cancelled, or closed by the root. Called
254
+ * once per close, AFTER `#padwiz` is hidden and after the resume of a game the wizard paused, so whoever owns the focus
255
+ * returns it to what is really in front. The root answers by giving the focus back to whoever held it when the wizard
256
+ * opened (`overlays.restoreFocus('padwiz')`).
257
+ * 🔴 REQUIRED (ADR-0248, as ADR-0224 did for the door): the code that knows the wizard ended is this module, the code that owns
258
+ * the focus is the root — an optional port is one more field a game can forget, and forgetting it drops a screen-reader
259
+ * child's focus on `<body>`.
260
+ */
261
+ wizardClosed: () => void;
232
262
  }
233
263
  export interface GamepadApi {
234
264
  pollPads(): void;
@@ -241,3 +271,4 @@ export interface GamepadApi {
241
271
  getPadWiz(): WizState | null;
242
272
  }
243
273
  export declare function initGamepad(ctx: GamepadCtx): GamepadApi;
274
+ export {};
@@ -20,8 +20,8 @@ import { createPadWizard, PADWIZ_ORDER as ORDEM_DO_ASSISTENTE } from './pad-wiza
20
20
  // 🔴 WHAT A PAD IS DOING lives in `input/pad-reading`: it is the PURE half — buttons and axes in, positions out. Here
21
21
  // is the wiring, which can only be read with a ctx in hand: the conductor that polls the pads every frame and decides
22
22
  // where the reading goes.
23
- // ⚠️ NO ALIAS: a re-export would keep alive a path the surface snapshot does not see, and the migration note is what
24
- // says where each name went.
23
+ // ⚠️ NO ALIAS: a re-export would keep alive a published path nothing in the engine imports (issue #204), and the
24
+ // migration note is what says where each name went.
25
25
  import { padActions, oneButtonAtOnce, } from './pad-reading.js';
26
26
  // ---------------------------------------------------------------------------------------------
27
27
  // Wizard data (the ORDER of the steps; the WORDS and the demonstration come from the game)
@@ -37,7 +37,8 @@ import { padActions, oneButtonAtOnce, } from './pad-reading.js';
37
37
  *
38
38
  * ⚠️ AND AN ACTION THE GAME DOES NOT NAME IS NOT ASKED. `input/pad-wizard` skips it, because a game that does not use
39
39
  * the position has nothing to map on it — and asking would produce a mute step or, worse, a step saying `action7` out
40
- * loud.
40
+ * loud. The exception is the system's two: START and SELECT are always asked, in the engine's words, because no game may
41
+ * name them and no pad may lack them (ADR-0144, erratum of 2026-09-26).
41
42
  */
42
43
  export const PADWIZ_ORDER = ORDEM_DO_ASSISTENTE;
43
44
  /**
@@ -121,7 +122,7 @@ export function initGamepad(ctx) {
121
122
  const ov = ctx.$('#padwiz');
122
123
  if (ov)
123
124
  ov.hidden = true;
124
- // no phantom edges: the button still HELD from the last step (START) must not pause or act on resume
125
+ // no phantom edges: the button still HELD from the last step (SELECT) must not open the menus or act on resume
125
126
  try {
126
127
  const pads = ctx.getGamepads() ?? [];
127
128
  const gp = pads[gi];
@@ -136,8 +137,10 @@ export function initGamepad(ctx) {
136
137
  if (padWizAutoResume) {
137
138
  padWizAutoResume = false;
138
139
  if (ctx.pauseMenu())
139
- ctx.resume();
140
+ ctx.resume(0);
140
141
  }
142
+ // last: the overlay is hidden and the game resumed, so the focus goes back to what is really in front (ADR-0248)
143
+ ctx.wizardClosed();
141
144
  },
142
145
  });
143
146
  function openPadWiz() {
@@ -179,6 +182,7 @@ export function initGamepad(ctx) {
179
182
  const startEdge = cur._start && !padPrevStart[gi];
180
183
  padPrevStart[gi] = cur._start;
181
184
  const pauseEdge = cur._pause && !prev._pause;
185
+ const selectEdge = !!cur.select && !prev.select;
182
186
  const edge = (k) => cur[k] && !prev[k];
183
187
  const released = (k) => !!prev[k] && !cur[k];
184
188
  padCur[gi] = cur;
@@ -189,7 +193,7 @@ export function initGamepad(ctx) {
189
193
  yes: edge('action2') || (withStart && startEdge), no: edge('action3'),
190
194
  up: edge('up'), down: edge('down'), left: edge('left'), right: edge('right'),
191
195
  });
192
- return { gp, gi, owner, players, cur, startEdge, pauseEdge, edge, released, navKeys };
196
+ return { gp, gi, owner, players, cur, startEdge, pauseEdge, selectEdge, edge, released, navKeys };
193
197
  }
194
198
  /** Did any of the six menu intents happen this frame? */
195
199
  // 📌 The `!!` is what `NavKeys` asks for: its six fields are OPTIONAL, because not every transport produces them all.
@@ -227,21 +231,36 @@ export function initGamepad(ctx) {
227
231
  } // only P1 chooses
228
232
  ctx.navTitle(k); // the title menu, navigable by pad
229
233
  }
230
- /** The pause card: START resumes, and the d-pad navigates the shared dialog or the seat's own menu. */
234
+ /** A menu is open: START resumes, action 4 is pressed, and the d-pad navigates the quick bar, the shared dialog or the seat's own card. */
231
235
  function steerPause(f) {
236
+ const pi = f.owner < 0 ? 0 : f.owner;
232
237
  if (f.pauseEdge) {
233
- ctx.resume();
238
+ ctx.resume(pi);
239
+ return;
240
+ } // START resumes — if this seat's START reaches this screen's pause (the root's)
241
+ if (ctx.leadsTheScreen && !ctx.leadsTheScreen(pi))
242
+ return; // another seat of a shared screen steers none of its menus
243
+ // ACTION 4 IS PRESSED, as the keyboard's key rises: no menu intent reads it, and the controller hands it to the menus as the
244
+ // seat's key, which the root answers where it answers the keyboard's — in the quick pause, the menus' second door (ADR-0155
245
+ // erratum «Ambos»). The pad decides nothing about it; one frame, one door, as SELECT.
246
+ if (f.edge('action4')) {
247
+ ctx.press('action4', 'gamepad', pi);
234
248
  return;
235
- } // START resumes
249
+ }
236
250
  const k = f.navKeys();
237
251
  if (!anyIntent(k))
238
252
  return;
253
+ // THE QUICK BAR FIRST, in the order `ui/menu-nav` steers a key: the quick pause (ADR-0155 §1) is a menu, so its frames come
254
+ // HERE and never reach `steerGame`'s bar. START was answered above, so the bar's exits here are back, and START by `resume`.
255
+ if (ctx.onBar(pi)) {
256
+ ctx.navBar(pi, k, false);
257
+ return;
258
+ }
239
259
  const dlg = ctx.sharedDialogOpen();
240
260
  if (dlg) {
241
261
  ctx.navDialog(dlg, k);
242
262
  return;
243
263
  }
244
- const pi = f.owner < 0 ? 0 : f.owner;
245
264
  const menu = ctx.getPauseMenu(pi);
246
265
  if (menu && !menu.hidden)
247
266
  ctx.navPause(menu, pi, k);
@@ -297,11 +316,14 @@ export function initGamepad(ctx) {
297
316
  }
298
317
  /** The real game: START pauses, the modal eats the d-pad, and the rest becomes an action flag. */
299
318
  function playRound(f, p) {
319
+ // START IS PRESSED FOR THIS PAD'S SEAT, as SELECT is: the virtual controller hands it to the engine (`systemPress`), which
320
+ // answers it as that seat's START key — its own quick pause, and START again leaves it (ADR-0155, ADR-0144 §1 and its
321
+ // erratum of 2026-09-26). A seatless `pause()` here froze seat 0's quick pause whoever pressed.
300
322
  if (f.pauseEdge) {
301
- ctx.pause();
323
+ ctx.press('start', 'gamepad', f.owner);
302
324
  ctx.setPauseActor(f.owner);
303
325
  return;
304
- } // START pauses (everyone pauses; each screen navigates its own)
326
+ }
305
327
  if (ctx.hasModal(f.owner)) { // the pad navigates the player's OWN modal (the others' game goes on)
306
328
  // What left this module is the MEANING — the grid's ±1/±3 and the Braille detour, which are the game's decision.
307
329
  const hit = MODAL_BY_POSITION.find(([position]) => f.edge(position));
@@ -339,12 +361,14 @@ export function initGamepad(ctx) {
339
361
  // that is the game's, because while the mode is on nothing else from this pad is the game's.
340
362
  //
341
363
  // Both exits arrive together: `especial` (action 3) is the project's BACK — the east button: B on Xbox, ◯ on
342
- // PlayStation, A on Nintendo — and `startEdge` is the button that opens the pause, where this was entered. A child
364
+ // PlayStation, A on Nintendo — and `pauseEdge` is the button that opens the pause, where this was entered. A child
343
365
  // who is lost goes back the way they came, one who knows the game tries the usual back; both work.
366
+ // ⚠️ START ALONE, not `startEdge`: that one fires on action 2 too («close a dialog»), and passed here it made the confirm
367
+ // LEAVE the bar instead of pressing the icon under the cursor.
344
368
  if (f.owner >= 0 && ctx.onBar(f.owner)) {
345
369
  const k = f.navKeys();
346
- if (f.startEdge || anyIntent(k))
347
- ctx.navBar(f.owner, k, !!f.startEdge);
370
+ if (f.pauseEdge || anyIntent(k))
371
+ ctx.navBar(f.owner, k, f.pauseEdge);
348
372
  return;
349
373
  }
350
374
  if (f.owner < 0) {
@@ -367,6 +391,8 @@ export function initGamepad(ctx) {
367
391
  ctx.stopAttract();
368
392
  return true;
369
393
  }
394
+ /** Did a button go down on this frame — any position, START or SELECT? A button held is one press, not one a frame. */
395
+ const wentDown = (f) => f.startEdge || f.pauseEdge || f.selectEdge || PAD_POSITIONS.some((k) => f.edge(k));
370
396
  /** A physical button used -> the on-screen pad goes away (the keyboard's rule): any of the nine positions read. */
371
397
  function hideTouchPadIfHeld(f) {
372
398
  if (ctx.isTouchMode() && (f.cur._start || PAD_POSITIONS.some((k) => f.cur[k])))
@@ -378,6 +404,13 @@ export function initGamepad(ctx) {
378
404
  * screen), the pad should navigate as on the title — the safe behaviour — instead of doing nothing.
379
405
  */
380
406
  function steerFrame(f) {
407
+ // SELECT OPENS THE MENUS wherever the keyboard's F does — in play and in the quick pause (ADR-0155) — and it is PRESSED,
408
+ // not decided here: the virtual controller hands the position to the engine, which answers it as F (ADR-0144 §1). An open
409
+ // card or panel refuses it there. A pad nobody has seated yet is seat 0's, as on the pause card below.
410
+ if (f.selectEdge) {
411
+ ctx.press('select', 'gamepad', f.owner < 0 ? 0 : f.owner);
412
+ return;
413
+ }
381
414
  if (ctx.pauseMenu())
382
415
  steerPause(f);
383
416
  else if (ctx.worldRunning())
@@ -402,6 +435,8 @@ export function initGamepad(ctx) {
402
435
  const f = readPad(gp, ctx.getPlayers());
403
436
  releaseWhatCameUp(f); // before every branch: the finger leaves the button wherever it likes (ADR-0223)
404
437
  hideTouchPadIfHeld(f);
438
+ if (wentDown(f) && ctx.takeShown?.())
439
+ continue; // one button only: the button is the switch (ADR-0218 §4)
405
440
  if (!winOverlayTook(f))
406
441
  steerFrame(f);
407
442
  }
@@ -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,10 +2,6 @@
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. {action2:['KeyJ','Space']}. It lives in `core/entity`,
6
- * whose `ctrl: KeyScheme | null` makes it the owner — the same line was once written in six modules. Re-exported for
7
- * whoever already imported it from here. */
8
- export type { KeyScheme } from '../core/entity.js';
9
5
  /** `input/keyboard`'s `KBDefaults` ({solo,p2,p3,p4}), which owns it. The local name survives because consumers use it. */
10
6
  export type KeyboardConfig = KBDefaults;
11
7
  /** Minimal player shape this module needs: only `ctrl` is read/written — derived from core/entity.
@@ -6,7 +6,6 @@ import type { KeyScheme } from '../core/entity.js';
6
6
  * touches it, not a module import — a test hands in its own, and two roots never write each other's map.
7
7
  */
8
8
  export type KeyboardStore = Pick<Store, 'getJSON' | 'setJSON' | 'remove'>;
9
- export type { KeyScheme } from '../core/entity.js';
10
9
  /**
11
10
  * THE SET OF keyboard SCHEMES — solo plus those for 2, 3 and 4 players.
12
11
  *