@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,39 +0,0 @@
1
- // SPDX-License-Identifier: AGPL-3.0-or-later
2
- export type CaaTier =
3
- /** CC BY-SA ou nosso: pode viajar dentro do jogo, funciona sem rede nenhuma. */
4
- 'bundled'
5
- /** A licença permite usar, não redistribuir: quem baixa é a pessoa, uma vez, e fica em cache. */
6
- | 'fetched'
7
- /** Falta permissão. Aparece no menu, não é escolhível. */
8
- | 'negotiating';
9
- export interface CaaSet {
10
- readonly key: string;
11
- readonly nome: string;
12
- readonly tier: CaaTier;
13
- /** Licença como ela foi VERIFICADA, ou null quando ainda não há. Texto curto, para caber na tela. */
14
- readonly licenca: string | null;
15
- /** Funciona NESTA build? Hoje só as letras — os pictogramas são arquivos que ainda não vieram. */
16
- readonly disponivel: boolean;
17
- /** Só para pictogramas: uma linha sobre a origem, quando ela muda o que a escolha significa. */
18
- readonly nota?: string;
19
- }
20
- export declare const CAA_SETS: readonly CaaSet[];
21
- export declare const CAA_BY_KEY: Readonly<Record<string, CaaSet>>;
22
- /** Quais CONJUNTOS a criança pode escolher hoje: nenhum. O menu não finge o contrário — os pictogramas são
23
- * milhares de arquivos que ainda não entraram no repositório, e quatro deles dependem de negociação. */
24
- export declare function caaDisponiveis(): CaaSet[];
25
- /**
26
- * Por que este conjunto não está disponível — chave i18n, nunca texto pronto.
27
- *
28
- * As duas respostas dizem coisas diferentes a quem lê, e é por isso que são duas: "em preparação" quer dizer
29
- * que a licença está resolvida e o trabalho é NOSSO; "aguardando negociação" quer dizer que a permissão é de
30
- * OUTRA PESSOA e nenhum esforço nosso a antecipa.
31
- *
32
- * E é por isso que os indisponíveis aparecem em vez de serem escondidos: são justamente os conjuntos que uma
33
- * escola brasileira tem mais chance de já usar em outro produto. O educador que procura PCS e não acha conclui
34
- * que o jogo não faz — quando o obstáculo é uma licença, não uma capacidade. Esconder responderia a pergunta
35
- * errada, e responderia errado.
36
- */
37
- export declare function caaMotivo(s: CaaSet): string | null;
38
- /** Rótulo pronto para a linha do menu: nome + o motivo, quando há um. */
39
- export declare function caaRotulo(s: CaaSet): string;
@@ -1,65 +0,0 @@
1
- // SPDX-License-Identifier: AGPL-3.0-or-later
2
- // ui/caa-sets.ts — O CATÁLOGO DA COMUNICAÇÃO AUMENTADA E ALTERNATIVA (ADR-0028). Módulo-folha: dados puros e
3
- // dois predicados, zero DOM, zero I/O. Quem desenha o menu é ui/settings-caa; quem decide o que ele oferece
4
- // é este arquivo, porque a decisão é de LICENÇA e não de interface.
5
- //
6
- // PARA QUEM ISTO EXISTE: há crianças que leem símbolos e não letras. Para elas, o pictograma não é um enfeite
7
- // nem uma muleta — é a escrita. Um jogo educativo que só sabe exibir letras simplesmente não fala com elas.
8
- //
9
- // A REGRA QUE ORGANIZA A LISTA: a camada de cada conjunto é decidida pela LICENÇA DELE e por mais nada — não
10
- // pela qualidade, não pelo tamanho, não pela facilidade de integrar. No instante em que um conjunto mudar de
11
- // camada por outro motivo, este arquivo terá deixado de ser verdadeiro.
12
- //
13
- // `tier` é o FATO JURÍDICO (podemos redistribuir? é preciso baixar? falta permissão?). `disponivel` é o FATO
14
- // DE HOJE (funciona nesta build?). São duas perguntas diferentes e o menu precisa das duas: a primeira diz
15
- // quem tem de agir, a segunda diz o que a criança consegue escolher agora.
16
- import { t } from '../core/i18n.js';
17
- // AS LETRAS NÃO ESTÃO NESTA LISTA, e a ausência é decisão do Dev. Elas eram duas entradas — "maiúsculas e
18
- // minúsculas" e "maiúsculas somente" — e viraram UM interruptor: "Letras maiúsculas", ligado ou desligado,
19
- // com o desligado significando as duas caixas. Uma escolha binária apresentada como duas opções faz a criança
20
- // comparar duas linhas para descobrir que são a mesma pergunta; um interruptor pergunta uma vez.
21
- //
22
- // Sobra aqui o que é de verdade uma LISTA: os conjuntos de pictogramas, entre os quais se escolhe um.
23
- export const CAA_SETS = [
24
- // --- PICTOGRAMAS que PODEM viajar com o jogo (CC BY-SA, verificado pelo Dev em 2026-08-24). ---
25
- { key: 'mulberry', nome: 'Mulberry Symbols', tier: 'bundled', licenca: 'CC BY-SA', disponivel: false },
26
- { key: 'blissymbolics', nome: 'Blissymbolics', tier: 'bundled', licenca: 'CC BY-SA 4.0', disponivel: false,
27
- nota: 'Escrita simbólica própria: os símbolos se combinam para formar sentidos novos.' },
28
- { key: 'tawasol', nome: 'Tawasol', tier: 'bundled', licenca: 'CC BY-SA 4.0', disponivel: false,
29
- nota: 'Desenhado na e para a cultura árabe. Um pictograma não é neutro — a criança reconhece mais depressa os objetos, as roupas e os rostos do próprio mundo.' },
30
- // --- PICTOGRAMA que precisa ser BAIXADO. ---
31
- { key: 'arasaac', nome: 'ARASAAC', tier: 'fetched', licenca: 'baixado à parte', disponivel: false },
32
- // --- AGUARDANDO NEGOCIAÇÃO. Ficam visíveis de propósito: ver `caaMotivo`. ---
33
- { key: 'sclera', nome: 'Sclera', tier: 'negotiating', licenca: null, disponivel: false },
34
- { key: 'pcs', nome: 'PCS', tier: 'negotiating', licenca: null, disponivel: false },
35
- { key: 'symbolstix', nome: 'SymbolStix', tier: 'negotiating', licenca: null, disponivel: false },
36
- { key: 'widgit', nome: 'Widgit Symbols', tier: 'negotiating', licenca: null, disponivel: false },
37
- ];
38
- export const CAA_BY_KEY = Object.fromEntries(CAA_SETS.map((s) => [s.key, s]));
39
- /** Quais CONJUNTOS a criança pode escolher hoje: nenhum. O menu não finge o contrário — os pictogramas são
40
- * milhares de arquivos que ainda não entraram no repositório, e quatro deles dependem de negociação. */
41
- export function caaDisponiveis() {
42
- return CAA_SETS.filter((s) => s.disponivel);
43
- }
44
- /**
45
- * Por que este conjunto não está disponível — chave i18n, nunca texto pronto.
46
- *
47
- * As duas respostas dizem coisas diferentes a quem lê, e é por isso que são duas: "em preparação" quer dizer
48
- * que a licença está resolvida e o trabalho é NOSSO; "aguardando negociação" quer dizer que a permissão é de
49
- * OUTRA PESSOA e nenhum esforço nosso a antecipa.
50
- *
51
- * E é por isso que os indisponíveis aparecem em vez de serem escondidos: são justamente os conjuntos que uma
52
- * escola brasileira tem mais chance de já usar em outro produto. O educador que procura PCS e não acha conclui
53
- * que o jogo não faz — quando o obstáculo é uma licença, não uma capacidade. Esconder responderia a pergunta
54
- * errada, e responderia errado.
55
- */
56
- export function caaMotivo(s) {
57
- if (s.disponivel)
58
- return null;
59
- return s.tier === 'negotiating' ? 'caa.aguardandoNegociacao' : 'caa.emPreparo';
60
- }
61
- /** Rótulo pronto para a linha do menu: nome + o motivo, quando há um. */
62
- export function caaRotulo(s) {
63
- const motivo = caaMotivo(s);
64
- return motivo ? `${s.nome} — ${t(motivo)}` : s.nome;
65
- }
@@ -1,32 +0,0 @@
1
- // SPDX-License-Identifier: AGPL-3.0-or-later
2
- /** Uma linha pronta a traduzir. `null` = há escolha, e não há nada a dizer. */
3
- export interface RecusaDaAlternancia {
4
- readonly chave: string;
5
- /** O transporte que a exige — fica disponível para quem quiser compor a frase de outro modo. */
6
- readonly transporte: string;
7
- }
8
- /**
9
- * A chave i18n do motivo, POR TRANSPORTE.
10
- *
11
- * ⚠️ QUATRO CHAVES E NÃO UMA COM `{aparelho}`, e a razão é de tradução e não de estilo: «os gestos» é plural
12
- * e «o olhar» não, logo uma frase única obrigaria cada idioma a montar concordância a partir de um
13
- * substantivo solto. É exactamente o defeito que o `sr.nav.clockOne` registou para «às 1 horas», e que o
14
- * `ui/simulation-refusal` já recusou pela mesma razão com os três eixos dele.
15
- */
16
- export declare const CHAVE_DA_RECUSA: Readonly<Record<string, string>>;
17
- /**
18
- * A alternância pode ser desligada neste aparelho? E se não, o que dizer.
19
- *
20
- * `null` = pode; a interface não mostra nada, porque um aviso que aparece sempre deixa de ser lido.
21
- */
22
- export declare function recusaDaAlternancia(transporte: string): RecusaDaAlternancia | null;
23
- /**
24
- * O controle continua NA TELA quando a alternância é exigida?
25
- *
26
- * ⚠️ SEMPRE, e é a metade «não some» da cláusula 3. Existe como função com nome próprio, e não como um
27
- * `!recusa` no ponto de uso, porque responde a outra pergunta: `recusaDaAlternancia` diz *por que* não dá;
28
- * esta diz *que a linha continua na tela*. Juntá-las faria «não há motivo» parecer «não desenhe a linha».
29
- */
30
- export declare function mostraMesmoExigida(): boolean;
31
- /** Os transportes que exigem alternância, para quem precisa de os enumerar. Vem da REGRA, não de uma cópia. */
32
- export declare const EXIGEM_ALTERNANCIA: ReadonlySet<string>;
@@ -1,60 +0,0 @@
1
- // SPDX-License-Identifier: AGPL-3.0-or-later
2
- // ui/latch-refusal.ts — QUANDO A ALTERNÂNCIA NÃO É UMA ESCOLHA, e o que se diz a quem carregou no botão.
3
- //
4
- // ========================= A CLÁUSULA 3 DO ADR-0113 =========================
5
- // «É impossível desligá-la em modos que não tem como funcionar sem ela (voz e câmera)» — a frase do Dev. Em
6
- // olhos, rosto, gestos e fala a alternância é o que faz a entrada funcionar: sem ela, um comando de cada vez
7
- // significa que a criança não consegue andar e agir.
8
- //
9
- // ⚠️ E O CONTROLE NÃO SOME — FICA DESABILITADO, COM O MOTIVO DITO. Sumir ensina que a coisa não existe: um
10
- // adulto conclui que ela foi retirada, não que a webcam a exige. É a mesma metade «never silently removed»
11
- // que o ADR-0076 escreveu para a simulação, e este ficheiro é o irmão do `ui/simulation-refusal` de propósito
12
- // — mesma forma, mesmo lugar na camada, e portanto conferível no project `node`, sem documento.
13
- //
14
- // 🔴 E O MOTIVO É UM FACTO SOBRE O APARELHO, NUNCA UMA REPREENSÃO. «O controle por olhar precisa das teclas de
15
- // alternância para funcionar» diz por que o botão não responde; «não desligue isto» repreende uma criança por
16
- // mexer num ajuste de que ela depende. O ADR-0076 já pagou esta distinção uma vez, e a mutação que a apanhou
17
- // trocava a frase por uma mais curta, mais clara e mais útil — que reprovava na mesma.
18
- //
19
- // Módulo-folha: importa só a regra pura da alternância.
20
- import { alternanciaEhEscolha, UM_COMANDO_DE_CADA_VEZ } from '../input/latch-scope.js';
21
- /**
22
- * A chave i18n do motivo, POR TRANSPORTE.
23
- *
24
- * ⚠️ QUATRO CHAVES E NÃO UMA COM `{aparelho}`, e a razão é de tradução e não de estilo: «os gestos» é plural
25
- * e «o olhar» não, logo uma frase única obrigaria cada idioma a montar concordância a partir de um
26
- * substantivo solto. É exactamente o defeito que o `sr.nav.clockOne` registou para «às 1 horas», e que o
27
- * `ui/simulation-refusal` já recusou pela mesma razão com os três eixos dele.
28
- */
29
- export const CHAVE_DA_RECUSA = Object.freeze({
30
- olhos: 'alt.exigida.olhos',
31
- rosto: 'alt.exigida.rosto',
32
- gestos: 'alt.exigida.gestos',
33
- fala: 'alt.exigida.fala',
34
- });
35
- /**
36
- * A alternância pode ser desligada neste aparelho? E se não, o que dizer.
37
- *
38
- * `null` = pode; a interface não mostra nada, porque um aviso que aparece sempre deixa de ser lido.
39
- */
40
- export function recusaDaAlternancia(transporte) {
41
- if (alternanciaEhEscolha(transporte))
42
- return null;
43
- const chave = CHAVE_DA_RECUSA[transporte];
44
- // 📌 Um transporte que exija alternância e não tenha frase seria um botão desabilitado SEM motivo — pior do
45
- // que o defeito que isto conserta, porque a criança deixa de saber sequer que há uma razão. O gate afirma
46
- // que os dois conjuntos coincidem; aqui a ausência degrada para «não recuso», que mantém o controle vivo.
47
- return chave ? { chave, transporte } : null;
48
- }
49
- /**
50
- * O controle continua NA TELA quando a alternância é exigida?
51
- *
52
- * ⚠️ SEMPRE, e é a metade «não some» da cláusula 3. Existe como função com nome próprio, e não como um
53
- * `!recusa` no ponto de uso, porque responde a outra pergunta: `recusaDaAlternancia` diz *por que* não dá;
54
- * esta diz *que a linha continua na tela*. Juntá-las faria «não há motivo» parecer «não desenhe a linha».
55
- */
56
- export function mostraMesmoExigida() {
57
- return true;
58
- }
59
- /** Os transportes que exigem alternância, para quem precisa de os enumerar. Vem da REGRA, não de uma cópia. */
60
- export const EXIGEM_ALTERNANCIA = UM_COMANDO_DE_CADA_VEZ;
@@ -1,56 +0,0 @@
1
- // SPDX-License-Identifier: AGPL-3.0-or-later
2
- import type { DomQuery } from '../core/dom-query.js';
3
- /** Assinatura mínima do seletor de DOM (a mesma de `ui/dom.ts`). */
4
- export type { DomQuery } from '../core/dom-query.js';
5
- /** Qual painel a linha abre. `null` = ainda não existe subsistema para abrir. */
6
- export type MapHubAction = 'options' | 'padwiz' | null;
7
- /** Uma linha do painel. */
8
- export interface MapHubRow {
9
- /** Rótulo com o emoji na frente — o emoji é o que `soonMessage` corta para falar. */
10
- lbl: string;
11
- /** Nº de telas exigido; `undefined` = vale em qualquer modo. */
12
- mode?: number;
13
- /** Em construção: aparece cinza, com "Em breve" no botão. */
14
- soon?: boolean;
15
- /** O painel que o botão abre, por nome. */
16
- act?: MapHubAction;
17
- }
18
- /**
19
- * A TABELA — congelada. A ordem é a da tela: os quatro modos de teclado, o gamepad, e as três promessas.
20
- * As três últimas são o roadmap deste jogo (webcam e fala), e é por causa delas que o módulo não é engine.
21
- */
22
- export declare const MAP_HUB_ROWS: readonly MapHubRow[];
23
- /** O estado visual de uma linha, para o número de telas atual. */
24
- export interface MapHubRowState {
25
- /** A linha exige um modo diferente do atual. */
26
- off: boolean;
27
- /** A linha está cinza (em construção OU modo errado) — é o que vira `row-off` + `disabled`. */
28
- dis: boolean;
29
- }
30
- /** O estado de cada linha em `np` telas. Fonte única do markup e das duas mensagens de `srAlert`. */
31
- export declare function mapHubStates(np: number, rows?: readonly MapHubRow[]): MapHubRowState[];
32
- /** O HTML do painel inteiro — cabeçalho + uma `.ctrl-row` por linha. */
33
- export declare function mapHubMarkup(np: number, rows?: readonly MapHubRow[]): string;
34
- /** O rótulo sem o emoji da frente — "👁 Mapear olhos e boca" → "Mapear olhos e boca". */
35
- export declare function soonName(lbl: string): string;
36
- /** O aviso falado de uma linha em construção. */
37
- export declare function soonMessage(lbl: string): string;
38
- /** O aviso falado de uma linha cujo modo não é o número de telas atual. */
39
- export declare function wrongModeMessage(mode: number): string;
40
- export interface MapHubCtx {
41
- /** Seletor de DOM injetado (`ui/dom.ts:$`) — o módulo nunca alcança `document` sozinho. */
42
- $: DomQuery;
43
- /** Anúncio assertivo ao leitor de tela (`core/a11y-sr.ts:srAlert`). */
44
- srAlert: (msg: string) => void;
45
- /** Nº de telas vivo (`core/state.ts:numPlayers`) — GETTER, porque é reatribuído. */
46
- getNumPlayers: () => number;
47
- /** Abre o painel de remapeamento de teclado (`openOptions` do main.js). */
48
- openOptions: () => void;
49
- /** Abre o assistente de gamepad (`input/gamepad.ts:openPadWiz`). */
50
- openPadWiz: () => void;
51
- }
52
- export interface MapHubApi {
53
- /** Redesenha `#map-hub` e reamarra os botões. Chamado por `openMovement`, a cada abertura do menu. */
54
- render(): void;
55
- }
56
- export declare function initMapHub(ctx: MapHubCtx): MapHubApi;
@@ -1,138 +0,0 @@
1
- // SPDX-License-Identifier: AGPL-3.0-or-later
2
- // ui/map-hub — O PAINEL "MAPEAR CONTROLES", dentro do menu de Movimento.
3
- //
4
- // Este módulo é o antigo `renderMapHub()` do main.js (mais o seu ajudante `mapSoon`, que não tinha outro
5
- // chamador). Ele desenha a lista de formas de comandar o jogo — teclado (uma linha por modo de 1 a 4 telas),
6
- // gamepad, e três entradas ainda por construir (olhos e boca, setores de olhar, palavras faladas) — e amarra
7
- // o botão de cada linha ao painel que ela abre.
8
- //
9
- // ======================= É DESTE JOGO, E NÃO ENGINE =======================
10
- // Um segundo jogo da coleção NÃO reusaria este arquivo, e a razão não é o assunto (mapear controles é
11
- // universal) — é o CONTEÚDO. Este painel enumera exatamente os subsistemas de entrada que *The Inclusionist*
12
- // tem hoje e os que ele PROMETE ter: a redação "em construção — chega junto com os subsistemas de webcam e
13
- // fala" é uma declaração de roadmap deste jogo, não uma capacidade do engine. Ele também depende do `#map-hub`
14
- // deste `index.html`, das classes `ctrl-row`/`mode-btn`/`row-off` desta folha de estilo, e de dois painéis
15
- // concretos (`openOptions`, `openPadWiz`). O que É engine já está extraído e mora noutro lugar:
16
- // `input/keyboard.ts` (o esquema), `input/gamepad.ts` (o assistente de mapeamento), `core/screens.ts` (a
17
- // grade). Aqui sobra a VITRINE — e vitrine é do jogo. Daí `ui/`, ao lado de `ui/settings-motor.ts`, que é o
18
- // resto do mesmo menu de Movimento.
19
- //
20
- // ======================= DECIDIR ≠ EXECUTAR =======================
21
- // Três coisas eram uma só, e as duas primeiras são puras:
22
- // · `MAP_HUB_ROWS` — a TABELA. Rótulo, modo exigido (ou nenhum) e a ação nomeada (`'options'`, `'padwiz'`
23
- // ou nada, para as três em construção). A ação virou um NOME e não uma função: é o que permite a tabela
24
- // ser um dado congelado, testável, e o `init` decidir qual painel cada nome abre.
25
- // · `mapHubStates(np)` / `mapHubMarkup(np)` — o estado de cada linha (desabilitada por estar em construção,
26
- // ou por o modo dela não ser o número de telas atual) e o HTML que sai disso. A regra que importa e que
27
- // ninguém via no meio da interpolação: "⌨ Mapear teclado para modo 3 jogadores" só habilita quando o jogo
28
- // ESTÁ em 3 telas — trocar o mapa de um modo em que você não está mostraria teclas que não valem.
29
- // · `initMapHub(ctx).render()` — a metade impura: `innerHTML`, `querySelectorAll`, `addEventListener`.
30
- //
31
- // ======================= O AVISO É A PARTE DE ACESSIBILIDADE =======================
32
- // Um botão `disabled` é invisível para quem navega por teclado com leitor de tela: o foco simplesmente pula.
33
- // Por isso as duas mensagens de `srAlert` existem, e por isso elas são exportadas como funções puras
34
- // (`soonMessage`, `wrongModeMessage`): quem clica na linha cinza — por toque, ou porque o leitor lê a linha
35
- // inteira e não só o botão — recebe o MOTIVO em palavras, não silêncio.
36
- // Já foi assim: os botões nasciam com o atributo `disabled`, o `click` deles não disparava, e as duas
37
- // mensagens eram inalcançáveis — medido no navegador: das oito linhas, seis ficavam fora da ordem de foco e
38
- // clicar nelas não dizia nada. Agora é `aria-disabled`, que anuncia o estado sem esconder o botão.
39
- //
40
- // ======================= O QUE FICOU DE FORA, E POR QUÊ =======================
41
- // · Abrir/fechar o overlay `#movement` (`openMovement`/`closeMovement`, `frontOverlay`, o foco no primeiro
42
- // botão) FICA no main.js: é a casca compartilhada por TODOS os painéis de configuração, não deste.
43
- // · `openOptions` e `gamepadApi.openPadWiz()` entram por injeção. O primeiro é do main.js (edita o controle
44
- // do jogador que abriu a pausa), o segundo é de `input/gamepad.ts`.
45
- // · O número de telas entra por GETTER (`getNumPlayers`) porque `numPlayers` é reatribuído por
46
- // `setNumPlayers` a cada troca — e é justamente ele que decide quais linhas ficam cinzas.
47
- //
48
- // ======================= ARMADILHAS DE ORDEM DE BOOT =======================
49
- // · Zero I/O no import: nada toca o DOM no corpo do módulo. `initMapHub` também não — ele só devolve
50
- // `render()`, e é `render()` que procura `#map-hub`. Se o elemento não existir, `render()` desiste em
51
- // silêncio (guard clause), como o original.
52
- // · `render()` é chamado de dentro de `openMovement`, que é uma DECLARAÇÃO DE FUNÇÃO içada e aparece ANTES
53
- // deste ponto no main.js. Não há TDZ: `openMovement` só roda a partir de um clique, muito depois do
54
- // módulo ter avaliado. Ainda assim, a religação deve manter um invólucro `function renderMapHub()` no
55
- // main.js — declaração içada, como manda a casa — para que a leitura de `openMovement` continue honesta.
56
- // · O `np` é lido UMA vez por `render()` e fica preso no manipulador de clique daquela renderização. Isso é
57
- // verbatim e é seguro hoje porque `openMovement` re-renderiza a cada abertura; se um dia o painel puder
58
- // ficar aberto enquanto o nº de telas muda, esta é a linha a mexer.
59
- /**
60
- * A TABELA — congelada. A ordem é a da tela: os quatro modos de teclado, o gamepad, e as três promessas.
61
- * As três últimas são o roadmap deste jogo (webcam e fala), e é por causa delas que o módulo não é engine.
62
- */
63
- export const MAP_HUB_ROWS = Object.freeze([
64
- { lbl: '⌨ Mapear teclado para modo 1 jogador', mode: 1, act: 'options' },
65
- { lbl: '⌨ Mapear teclado para modo 2 jogadores', mode: 2, act: 'options' },
66
- { lbl: '⌨ Mapear teclado para modo 3 jogadores', mode: 3, act: 'options' },
67
- { lbl: '⌨ Mapear teclado para modo 4 jogadores', mode: 4, act: 'options' },
68
- { lbl: '🎮 Mapear gamepad', act: 'padwiz' }, // L1: assistente (DirectInput e afins) — mapa salvo por modelo
69
- { lbl: '👁 Mapear olhos e boca', soon: true },
70
- { lbl: '🎯 Mapear setores de olhar', soon: true },
71
- { lbl: '🎤 Mapear palavras (fala)', soon: true },
72
- ].map((r) => Object.freeze(r)));
73
- /** O estado de cada linha em `np` telas. Fonte única do markup e das duas mensagens de `srAlert`. */
74
- export function mapHubStates(np, rows = MAP_HUB_ROWS) {
75
- return rows.map((r) => {
76
- const off = !!r.mode && r.mode !== np; // teclado: só o modo em que o jogo ESTÁ fica clicável
77
- return { off, dis: !!r.soon || off };
78
- });
79
- }
80
- /** O HTML do painel inteiro — cabeçalho + uma `.ctrl-row` por linha. */
81
- export function mapHubMarkup(np, rows = MAP_HUB_ROWS) {
82
- const st = mapHubStates(np, rows);
83
- return '<h3 class="panel-sub">Mapear controles <span class="panel-sub__tag">por jogador</span></h3>' +
84
- rows.map((it, i) => {
85
- const dis = st[i].dis;
86
- const note = it.soon ? ' <em style="opacity:.7">(em construção)</em>' : '';
87
- // `aria-disabled` e NAO `disabled`: o atributo real tira o botao da ordem de foco e engole o clique,
88
- // entao quem navega por teclado pulava seis das oito linhas e nunca ficava sabendo por que elas nao
89
- // funcionam — enquanto quem enxerga ve a linha cinza e o "(em construcao)". Com `aria-disabled` o
90
- // estado e anunciado, o botao continua alcancavel, e as duas frases de srAlert que ja existiam aqui
91
- // finalmente chegam a alguem. O visual nao muda: quem pinta a linha cinza e a classe `row-off`.
92
- return `<div class="ctrl-row${dis ? ' row-off' : ''}"><span>${it.lbl}${note}</span>` +
93
- `<button class="mode-btn" type="button" data-map="${i}"${dis ? ' aria-disabled="true"' : ''}>${it.soon ? 'Em breve' : 'Abrir'}</button></div>`;
94
- }).join('');
95
- }
96
- /** O rótulo sem o emoji da frente — "👁 Mapear olhos e boca" → "Mapear olhos e boca". */
97
- export function soonName(lbl) {
98
- return lbl.replace(/^\S+\s/, '');
99
- }
100
- /** O aviso falado de uma linha em construção. */
101
- export function soonMessage(lbl) {
102
- return soonName(lbl) + ': em construção — chega junto com os subsistemas de webcam e fala.';
103
- }
104
- /** O aviso falado de uma linha cujo modo não é o número de telas atual. */
105
- export function wrongModeMessage(mode) {
106
- return 'Disponível só no modo ' + mode + ' jogador' + (mode > 1 ? 'es' : '') + '. Troque o nº de telas na barra do topo.';
107
- }
108
- export function initMapHub(ctx) {
109
- /** Nome da ação → o painel de verdade. Fora da tabela, para a tabela poder ser dado congelado. */
110
- function run(act) {
111
- if (act === 'options')
112
- ctx.openOptions();
113
- else if (act === 'padwiz')
114
- ctx.openPadWiz();
115
- }
116
- function render() {
117
- const el = ctx.$('#map-hub');
118
- if (!el)
119
- return; // o painel não está neste documento — nada a fazer
120
- const np = ctx.getNumPlayers(); // lido UMA vez; preso no manipulador desta renderização (ver o cabeçalho)
121
- el.innerHTML = mapHubMarkup(np);
122
- el.querySelectorAll('button[data-map]').forEach((b) => b.addEventListener('click', () => {
123
- const it = MAP_HUB_ROWS[Number(b.dataset['map'])];
124
- if (!it)
125
- return;
126
- if (it.soon) {
127
- ctx.srAlert(soonMessage(it.lbl));
128
- return;
129
- } // em construção: diz o porquê
130
- if (it.mode && it.mode !== np) {
131
- ctx.srAlert(wrongModeMessage(it.mode));
132
- return;
133
- } // modo errado: idem
134
- run(it.act ?? null);
135
- }));
136
- }
137
- return { render };
138
- }
@@ -1,45 +0,0 @@
1
- // SPDX-License-Identifier: AGPL-3.0-or-later
2
- import type { LetterCase } from '../core/state.js';
3
- import { type CaaSet } from './caa-sets.js';
4
- /**
5
- * A linha das LETRAS é um INTERRUPTOR, não duas opções (decisão do Dev). Ligado = só maiúsculas; desligado =
6
- * maiúsculas e minúsculas. Uma pergunta binária apresentada como duas linhas obriga a criança a comparar as
7
- * duas para descobrir que são a mesma pergunta.
8
- */
9
- export declare function caixaAltaLigada(caso: LetterCase): boolean;
10
- /** O interruptor das letras. Sempre disponível: é o piso offline, e nunca dependeu de arquivo nenhum. */
11
- export declare function letrasRowHtml(ligado: boolean): string;
12
- /**
13
- * Uma linha do menu: RÓTULO CURTO e nada mais à vista.
14
- *
15
- * Tudo o que explica — nota, licença, situação — entra num único `.opt-hint`, que é o que a casca
16
- * (`fillExplain`) reconhece e MOVE para o rodapé. A primeira versão pendurava três blocos de prosa dentro da
17
- * linha, e o Dev viu o resultado: o menu virou um manual, mais parecido com um arquivo de configuração do que
18
- * com um menu de videogame. A explicação já tinha um lugar; eu é que não a pus lá.
19
- *
20
- * O `disabled` fica: a situação some do TEXTO, não do controle. E o `aria-label` guarda o motivo, para quem
21
- * navega por teclado ouvir por que a linha não responde sem precisar caçar o rodapé.
22
- */
23
- export declare function caaRowHtml(s: CaaSet, selecionada: boolean): string;
24
- /** O corpo do menu, em três seções — a seção diz de quem é a vez de agir. */
25
- export declare function caaListHtml(caso: LetterCase): string;
26
- export interface SettingsCaaCtx {
27
- $: <T extends Element = Element>(sel: string) => T | null;
28
- srSay: (msg: string) => void;
29
- /** Leitura viva de core/state `letterCase` (o binding é reatribuído pelo setter). */
30
- getLetterCase: () => LetterCase;
31
- /** `setLetterCaseValue` de core/state MAIS a reflexão que o jogo precisa (re-render do quiz, rótulos). */
32
- setLetterCase: (c: LetterCase) => void;
33
- frontOverlay: (el: HTMLElement | null) => void;
34
- /** Move a prosa das linhas para o rodapé (ui/settings-panel `fillExplain`). Chamado a CADA render, e não só
35
- * ao abrir: `render()` reconstrói as linhas, e sem esta chamada a explicação volta para dentro delas — foi
36
- * exatamente o que aconteceu, e o menu virou manual de novo ao primeiro clique. */
37
- fillExplain: (card: HTMLElement | null) => void;
38
- restoreFocus?: (id: string) => boolean;
39
- }
40
- export interface SettingsCaaApi {
41
- render: () => void;
42
- open: () => void;
43
- close: () => void;
44
- }
45
- export declare function initSettingsCaa(ctx: SettingsCaaCtx): SettingsCaaApi;
@@ -1,137 +0,0 @@
1
- // SPDX-License-Identifier: AGPL-3.0-or-later
2
- // ui/settings-caa.ts — O SÉTIMO MENU: COMUNICAÇÃO AUMENTADA E ALTERNATIVA (ADR-0028, issue #57).
3
- //
4
- // O catálogo (quem existe, sob qual licença, em qual camada) mora em ./caa-sets.js; aqui só a tela. DI por
5
- // ctx, como os seis painéis irmãos: nada de global fora do que for injetado.
6
- //
7
- // O QUE ESTE MENU É HOJE, dito sem maquiagem: um seletor de caixa de letra que já mostra, ao lado, os sete
8
- // conjuntos de pictogramas que virão. Só as duas caixas de letra funcionam — os pictogramas são milhares de
9
- // arquivos que ainda não entraram no repositório, e três deles dependem de negociação que não é nossa.
10
- //
11
- // Mostrar o que não funciona seria desonesto se o menu não dissesse POR QUE. Ele diz, e com duas respostas
12
- // diferentes de propósito: "em preparação" (a licença está resolvida, o trabalho é nosso) e "aguardando
13
- // negociação" (a permissão é de outra pessoa). Um educador que lê a primeira sabe esperar; que lê a segunda
14
- // sabe que esperar não adianta. Esconder tudo o que ainda não anda faria o educador concluir que o jogo não
15
- // faz pictograma nenhum — que é a conclusão errada, e a que mais custa a quem precisa deles.
16
- //
17
- // LETRA vs PICTOGRAMA: a escolha de caixa é `letterCase` (core/state). NÃO existe um `caaMode` paralelo, e
18
- // isso é decisão: enquanto só duas opções forem escolhíveis, uma segunda variável para a mesma pergunta
19
- // seria duplicação com aparência de arquitetura. Ver a nota em core/state.
20
- import { toggleLabel } from './dom.js';
21
- import { t } from '../core/i18n.js';
22
- import { DEFAULTS } from '../core/state.js';
23
- import { CAA_SETS, CAA_BY_KEY, caaMotivo } from './caa-sets.js';
24
- import { markChanged, markMenuChanged } from './changed-mark.js';
25
- /**
26
- * A linha das LETRAS é um INTERRUPTOR, não duas opções (decisão do Dev). Ligado = só maiúsculas; desligado =
27
- * maiúsculas e minúsculas. Uma pergunta binária apresentada como duas linhas obriga a criança a comparar as
28
- * duas para descobrir que são a mesma pergunta.
29
- */
30
- export function caixaAltaLigada(caso) {
31
- return caso === 'upper';
32
- }
33
- /** O interruptor das letras. Sempre disponível: é o piso offline, e nunca dependeu de arquivo nenhum. */
34
- export function letrasRowHtml(ligado) {
35
- return ('<div class="ctrl-row" id="caa-letras"><span><strong>Letras maiúsculas</strong>' +
36
- '<span class="opt-hint">Ligado: o jogo inteiro em caixa alta, como a alfabetização brasileira costuma ' +
37
- 'começar. Desligado: maiúsculas e minúsculas, a escrita do dia a dia.</span></span>' +
38
- `<button class="mode-btn switch${ligado ? ' is-on' : ''}" id="caa-caixa-alta" type="button"` +
39
- ` aria-pressed="${ligado}" aria-label="Letras maiúsculas">${toggleLabel(ligado)}</button></div>`);
40
- }
41
- /**
42
- * Uma linha do menu: RÓTULO CURTO e nada mais à vista.
43
- *
44
- * Tudo o que explica — nota, licença, situação — entra num único `.opt-hint`, que é o que a casca
45
- * (`fillExplain`) reconhece e MOVE para o rodapé. A primeira versão pendurava três blocos de prosa dentro da
46
- * linha, e o Dev viu o resultado: o menu virou um manual, mais parecido com um arquivo de configuração do que
47
- * com um menu de videogame. A explicação já tinha um lugar; eu é que não a pus lá.
48
- *
49
- * O `disabled` fica: a situação some do TEXTO, não do controle. E o `aria-label` guarda o motivo, para quem
50
- * navega por teclado ouvir por que a linha não responde sem precisar caçar o rodapé.
51
- */
52
- export function caaRowHtml(s, selecionada) {
53
- const motivo = caaMotivo(s);
54
- const explica = [s.nota, s.licenca ? `Licença: ${s.licenca}` : '', motivo ? t(motivo) : '']
55
- .filter(Boolean).join(' · ');
56
- const hint = explica ? `<span class="opt-hint">${explica}</span>` : '';
57
- const estado = toggleLabel(selecionada);
58
- return (`<div class="ctrl-row"><span><strong>${s.nome}</strong>${hint}</span>` +
59
- `<button class="mode-btn switch${selecionada ? ' is-on' : ''}" data-caa="${s.key}" type="button"` +
60
- `${s.disponivel ? '' : ' disabled'} aria-pressed="${selecionada}"` +
61
- ` aria-label="${s.nome}${motivo ? ', ' + t(motivo) : ''}">${estado}</button></div>`);
62
- }
63
- /** O corpo do menu, em três seções — a seção diz de quem é a vez de agir. */
64
- export function caaListHtml(caso) {
65
- const bloco = (titulo, tag, corpo) => corpo ? `<h3 class="panel-sub">${titulo} <span class="panel-sub__tag">${tag}</span></h3>${corpo}` : '';
66
- const sets = (f) => CAA_SETS.filter(f).map((s) => caaRowHtml(s, false)).join('');
67
- return (bloco(t('caa.secao.agora'), t('caa.secao.agoraTag'), letrasRowHtml(caixaAltaLigada(caso))) +
68
- bloco(t('caa.secao.preparo'), t('caa.secao.preparoTag'), sets((s) => s.tier !== 'negotiating')) +
69
- bloco(t('caa.secao.negociacao'), t('caa.secao.negociacaoTag'), sets((s) => s.tier === 'negotiating')));
70
- }
71
- export function initSettingsCaa(ctx) {
72
- function render() {
73
- const el = ctx.$('#caa-list');
74
- if (!el)
75
- return;
76
- el.innerHTML = caaListHtml(ctx.getLetterCase());
77
- const alta = el.querySelector('#caa-caixa-alta');
78
- if (alta)
79
- alta.addEventListener('click', () => {
80
- const ligar = !caixaAltaLigada(ctx.getLetterCase());
81
- ctx.setLetterCase(ligar ? 'upper' : 'mixed');
82
- render();
83
- ctx.srSay(t(ligar ? 'sr.caa.caixaAltaOn' : 'sr.caa.caixaAltaOff'));
84
- });
85
- el.querySelectorAll('button[data-caa]').forEach((b) => {
86
- b.addEventListener('click', () => {
87
- const set = b.dataset.caa ? CAA_BY_KEY[b.dataset.caa] : undefined;
88
- // Nenhum conjunto está disponível hoje, e todos vêm `disabled`. A guarda existe para o dia em que
89
- // alguém remover o atributo "só para testar": um conjunto que não está no jogo não pode virar a
90
- // escolha da criança por acidente, deixando a tela sem nada para desenhar.
91
- if (!set || !set.disponivel)
92
- return;
93
- });
94
- });
95
- ctx.fillExplain(ctx.$('#caa .overlay__card'));
96
- refreshMarks();
97
- }
98
- /** A marca de "saiu do padrão" (ADR-0029), na linha escolhida e no botão do menu. */
99
- function refreshMarks() {
100
- const mudou = ctx.getLetterCase() !== DEFAULTS.letterCase;
101
- markChanged(ctx.$('#caa-letras'), mudou);
102
- markMenuChanged(ctx.$('[data-act="caa"]'), [mudou]);
103
- }
104
- function open() {
105
- const ov = ctx.$('#caa');
106
- if (!ov)
107
- return;
108
- render();
109
- ov.hidden = false;
110
- ctx.frontOverlay(ov);
111
- const f = ov.querySelector('button');
112
- if (f)
113
- f.focus();
114
- }
115
- function close() {
116
- const ov = ctx.$('#caa');
117
- if (!ov)
118
- return;
119
- ov.hidden = true;
120
- ctx.restoreFocus?.('caa');
121
- }
122
- const closeBtn = ctx.$('#caa-close');
123
- if (closeBtn)
124
- closeBtn.addEventListener('click', close);
125
- // ---- restaurar os padrões DESTE menu (ADR-0028) ----
126
- // O menu tem uma escolha só, então o reset é uma linha — mas vale dizer para onde ele volta: maiúsculas, que
127
- // é onde a alfabetização brasileira costuma começar. Uma criança que trocou a caixa e não consegue mais ler
128
- // a tela precisa de um caminho de volta que termine no que a professora dela usa.
129
- const resetBtn = ctx.$('#caa-reset');
130
- if (resetBtn)
131
- resetBtn.addEventListener('click', () => {
132
- ctx.setLetterCase(DEFAULTS.letterCase);
133
- render();
134
- ctx.srSay(t('sr.caa.reset'));
135
- });
136
- return { render, open, close };
137
- }