@the-inclusionist/engine 8.0.0 → 10.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 (756) hide show
  1. package/README.md +89 -78
  2. package/app/css/style.css +584 -374
  3. package/app/public/vendor/fonts/bitter-var-ext.woff2 +0 -0
  4. package/app/public/vendor/fonts/bitter-var.woff2 +0 -0
  5. package/app/public/vendor/fonts/bodonimoda-var-ext.woff2 +0 -0
  6. package/app/public/vendor/fonts/bodonimoda-var.woff2 +0 -0
  7. package/app/public/vendor/fonts/cat-abril_fatface-400-ext.woff2 +0 -0
  8. package/app/public/vendor/fonts/cat-abril_fatface-400.woff2 +0 -0
  9. package/app/public/vendor/fonts/cat-adlam_display-400-ext.woff2 +0 -0
  10. package/app/public/vendor/fonts/cat-adlam_display-400.woff2 +0 -0
  11. package/app/public/vendor/fonts/cat-agu_display-400-ext.woff2 +0 -0
  12. package/app/public/vendor/fonts/cat-agu_display-400.woff2 +0 -0
  13. package/app/public/vendor/fonts/cat-alfa_slab_one-400-ext.woff2 +0 -0
  14. package/app/public/vendor/fonts/cat-alfa_slab_one-400.woff2 +0 -0
  15. package/app/public/vendor/fonts/cat-are_you_serious-400-ext.woff2 +0 -0
  16. package/app/public/vendor/fonts/cat-are_you_serious-400.woff2 +0 -0
  17. package/app/public/vendor/fonts/cat-asimovian-400-ext.woff2 +0 -0
  18. package/app/public/vendor/fonts/cat-asimovian-400.woff2 +0 -0
  19. package/app/public/vendor/fonts/cat-atkinson_hyperlegible_next-400-ext.woff2 +0 -0
  20. package/app/public/vendor/fonts/cat-atkinson_hyperlegible_next-400.woff2 +0 -0
  21. package/app/public/vendor/fonts/cat-bakbak_one-400-ext.woff2 +0 -0
  22. package/app/public/vendor/fonts/cat-bakbak_one-400.woff2 +0 -0
  23. package/app/public/vendor/fonts/cat-bangers-400-ext.woff2 +0 -0
  24. package/app/public/vendor/fonts/cat-bangers-400.woff2 +0 -0
  25. package/app/public/vendor/fonts/cat-barriecito-400-ext.woff2 +0 -0
  26. package/app/public/vendor/fonts/cat-barriecito-400.woff2 +0 -0
  27. package/app/public/vendor/fonts/cat-berkshire_swash-400-ext.woff2 +0 -0
  28. package/app/public/vendor/fonts/cat-berkshire_swash-400.woff2 +0 -0
  29. package/app/public/vendor/fonts/cat-bevan-400-ext.woff2 +0 -0
  30. package/app/public/vendor/fonts/cat-bevan-400.woff2 +0 -0
  31. package/app/public/vendor/fonts/cat-bitcount-400-ext.woff2 +0 -0
  32. package/app/public/vendor/fonts/cat-bitcount-400.woff2 +0 -0
  33. package/app/public/vendor/fonts/cat-bowlby_one_sc-400-ext.woff2 +0 -0
  34. package/app/public/vendor/fonts/cat-bowlby_one_sc-400.woff2 +0 -0
  35. package/app/public/vendor/fonts/cat-bungee_shade-400-ext.woff2 +0 -0
  36. package/app/public/vendor/fonts/cat-bungee_shade-400.woff2 +0 -0
  37. package/app/public/vendor/fonts/cat-charm-400-ext.woff2 +0 -0
  38. package/app/public/vendor/fonts/cat-charm-400.woff2 +0 -0
  39. package/app/public/vendor/fonts/cat-charm-700-ext.woff2 +0 -0
  40. package/app/public/vendor/fonts/cat-charm-700.woff2 +0 -0
  41. package/app/public/vendor/fonts/cat-cherry_bomb_one-400-ext.woff2 +0 -0
  42. package/app/public/vendor/fonts/cat-cherry_bomb_one-400.woff2 +0 -0
  43. package/app/public/vendor/fonts/cat-chokokutai-400-ext.woff2 +0 -0
  44. package/app/public/vendor/fonts/cat-chokokutai-400.woff2 +0 -0
  45. package/app/public/vendor/fonts/cat-chonburi-400-ext.woff2 +0 -0
  46. package/app/public/vendor/fonts/cat-chonburi-400.woff2 +0 -0
  47. package/app/public/vendor/fonts/cat-climate_crisis-400-ext.woff2 +0 -0
  48. package/app/public/vendor/fonts/cat-climate_crisis-400.woff2 +0 -0
  49. package/app/public/vendor/fonts/cat-cookie-400.woff2 +0 -0
  50. package/app/public/vendor/fonts/cat-dela_gothic_one-400-ext.woff2 +0 -0
  51. package/app/public/vendor/fonts/cat-dela_gothic_one-400.woff2 +0 -0
  52. package/app/public/vendor/fonts/cat-fascinate_inline-400-ext.woff2 +0 -0
  53. package/app/public/vendor/fonts/cat-fascinate_inline-400.woff2 +0 -0
  54. package/app/public/vendor/fonts/cat-ga_maamli-400-ext.woff2 +0 -0
  55. package/app/public/vendor/fonts/cat-ga_maamli-400.woff2 +0 -0
  56. package/app/public/vendor/fonts/cat-itim-400-ext.woff2 +0 -0
  57. package/app/public/vendor/fonts/cat-itim-400.woff2 +0 -0
  58. package/app/public/vendor/fonts/cat-jacquard_24-400-ext.woff2 +0 -0
  59. package/app/public/vendor/fonts/cat-jacquard_24-400.woff2 +0 -0
  60. package/app/public/vendor/fonts/cat-kablammo-400-ext.woff2 +0 -0
  61. package/app/public/vendor/fonts/cat-kablammo-400.woff2 +0 -0
  62. package/app/public/vendor/fonts/cat-kalam-400-ext.woff2 +0 -0
  63. package/app/public/vendor/fonts/cat-kalam-400.woff2 +0 -0
  64. package/app/public/vendor/fonts/cat-kalam-700-ext.woff2 +0 -0
  65. package/app/public/vendor/fonts/cat-kalam-700.woff2 +0 -0
  66. package/app/public/vendor/fonts/cat-katibeh-400-ext.woff2 +0 -0
  67. package/app/public/vendor/fonts/cat-katibeh-400.woff2 +0 -0
  68. package/app/public/vendor/fonts/cat-lemonada-400-ext.woff2 +0 -0
  69. package/app/public/vendor/fonts/cat-lemonada-400.woff2 +0 -0
  70. package/app/public/vendor/fonts/cat-lilita_one-400-ext.woff2 +0 -0
  71. package/app/public/vendor/fonts/cat-lilita_one-400.woff2 +0 -0
  72. package/app/public/vendor/fonts/cat-lobster-400-ext.woff2 +0 -0
  73. package/app/public/vendor/fonts/cat-lobster-400.woff2 +0 -0
  74. package/app/public/vendor/fonts/cat-luckiest_guy-400-ext.woff2 +0 -0
  75. package/app/public/vendor/fonts/cat-luckiest_guy-400.woff2 +0 -0
  76. package/app/public/vendor/fonts/cat-marhey-400-ext.woff2 +0 -0
  77. package/app/public/vendor/fonts/cat-marhey-400.woff2 +0 -0
  78. package/app/public/vendor/fonts/cat-modak-400-ext.woff2 +0 -0
  79. package/app/public/vendor/fonts/cat-modak-400.woff2 +0 -0
  80. package/app/public/vendor/fonts/cat-momo_signature-400-ext.woff2 +0 -0
  81. package/app/public/vendor/fonts/cat-momo_signature-400.woff2 +0 -0
  82. package/app/public/vendor/fonts/cat-monofett-400-ext.woff2 +0 -0
  83. package/app/public/vendor/fonts/cat-monofett-400.woff2 +0 -0
  84. package/app/public/vendor/fonts/cat-monomakh-400-ext.woff2 +0 -0
  85. package/app/public/vendor/fonts/cat-monomakh-400.woff2 +0 -0
  86. package/app/public/vendor/fonts/cat-monoton-400-ext.woff2 +0 -0
  87. package/app/public/vendor/fonts/cat-monoton-400.woff2 +0 -0
  88. package/app/public/vendor/fonts/cat-nerko_one-400-ext.woff2 +0 -0
  89. package/app/public/vendor/fonts/cat-nerko_one-400.woff2 +0 -0
  90. package/app/public/vendor/fonts/cat-noto_sans_adlam-400-ext.woff2 +0 -0
  91. package/app/public/vendor/fonts/cat-noto_sans_adlam-400.woff2 +0 -0
  92. package/app/public/vendor/fonts/cat-noto_sans_arabic-400-ext.woff2 +0 -0
  93. package/app/public/vendor/fonts/cat-noto_sans_arabic-400.woff2 +0 -0
  94. package/app/public/vendor/fonts/cat-noto_sans_devanagari-400-ext.woff2 +0 -0
  95. package/app/public/vendor/fonts/cat-noto_sans_devanagari-400.woff2 +0 -0
  96. package/app/public/vendor/fonts/cat-noto_sans_hebrew-400-ext.woff2 +0 -0
  97. package/app/public/vendor/fonts/cat-noto_sans_hebrew-400.woff2 +0 -0
  98. package/app/public/vendor/fonts/cat-noto_sans_jp-400-ext.woff2 +0 -0
  99. package/app/public/vendor/fonts/cat-noto_sans_jp-400.woff2 +0 -0
  100. package/app/public/vendor/fonts/cat-noto_sans_khmer-400-ext.woff2 +0 -0
  101. package/app/public/vendor/fonts/cat-noto_sans_khmer-400.woff2 +0 -0
  102. package/app/public/vendor/fonts/cat-noto_sans_kr-400-ext.woff2 +0 -0
  103. package/app/public/vendor/fonts/cat-noto_sans_kr-400.woff2 +0 -0
  104. package/app/public/vendor/fonts/cat-noto_sans_sc-400-ext.woff2 +0 -0
  105. package/app/public/vendor/fonts/cat-noto_sans_sc-400.woff2 +0 -0
  106. package/app/public/vendor/fonts/cat-noto_sans_thai-400-ext.woff2 +0 -0
  107. package/app/public/vendor/fonts/cat-noto_sans_thai-400.woff2 +0 -0
  108. package/app/public/vendor/fonts/cat-ole-400-ext.woff2 +0 -0
  109. package/app/public/vendor/fonts/cat-ole-400.woff2 +0 -0
  110. package/app/public/vendor/fonts/cat-pacifico-400-ext.woff2 +0 -0
  111. package/app/public/vendor/fonts/cat-pacifico-400.woff2 +0 -0
  112. package/app/public/vendor/fonts/cat-patrick_hand-400-ext.woff2 +0 -0
  113. package/app/public/vendor/fonts/cat-patrick_hand-400.woff2 +0 -0
  114. package/app/public/vendor/fonts/cat-petit_formal_script-400-ext.woff2 +0 -0
  115. package/app/public/vendor/fonts/cat-petit_formal_script-400.woff2 +0 -0
  116. package/app/public/vendor/fonts/cat-pixelify_sans-400-ext.woff2 +0 -0
  117. package/app/public/vendor/fonts/cat-pixelify_sans-400.woff2 +0 -0
  118. package/app/public/vendor/fonts/cat-plaster-400-ext.woff2 +0 -0
  119. package/app/public/vendor/fonts/cat-plaster-400.woff2 +0 -0
  120. package/app/public/vendor/fonts/cat-playwrite_ar_guides-400-0.woff2 +0 -0
  121. package/app/public/vendor/fonts/cat-playwrite_at-400-0.woff2 +0 -0
  122. package/app/public/vendor/fonts/cat-playwrite_at_guides-400-0.woff2 +0 -0
  123. package/app/public/vendor/fonts/cat-playwrite_au_nsw-400-0.woff2 +0 -0
  124. package/app/public/vendor/fonts/cat-playwrite_au_nsw_guides-400-0.woff2 +0 -0
  125. package/app/public/vendor/fonts/cat-playwrite_au_qld-400-0.woff2 +0 -0
  126. package/app/public/vendor/fonts/cat-playwrite_au_qld_guides-400-0.woff2 +0 -0
  127. package/app/public/vendor/fonts/cat-playwrite_au_sa-400-0.woff2 +0 -0
  128. package/app/public/vendor/fonts/cat-playwrite_au_sa_guides-400-0.woff2 +0 -0
  129. package/app/public/vendor/fonts/cat-playwrite_au_tas-400-0.woff2 +0 -0
  130. package/app/public/vendor/fonts/cat-playwrite_au_tas_guides-400-0.woff2 +0 -0
  131. package/app/public/vendor/fonts/cat-playwrite_au_vic-400-0.woff2 +0 -0
  132. package/app/public/vendor/fonts/cat-playwrite_au_vic_guides-400-0.woff2 +0 -0
  133. package/app/public/vendor/fonts/cat-playwrite_be_vlg-400-0.woff2 +0 -0
  134. package/app/public/vendor/fonts/cat-playwrite_be_vlg_guides-400-0.woff2 +0 -0
  135. package/app/public/vendor/fonts/cat-playwrite_be_wal-400-0.woff2 +0 -0
  136. package/app/public/vendor/fonts/cat-playwrite_be_wal_guides-400-0.woff2 +0 -0
  137. package/app/public/vendor/fonts/cat-playwrite_br_guides-400-0.woff2 +0 -0
  138. package/app/public/vendor/fonts/cat-playwrite_ca_guides-400-0.woff2 +0 -0
  139. package/app/public/vendor/fonts/cat-playwrite_cl_guides-400-0.woff2 +0 -0
  140. package/app/public/vendor/fonts/cat-playwrite_co_guides-400-0.woff2 +0 -0
  141. package/app/public/vendor/fonts/cat-playwrite_cu_guides-400-0.woff2 +0 -0
  142. package/app/public/vendor/fonts/cat-playwrite_cz-400-0.woff2 +0 -0
  143. package/app/public/vendor/fonts/cat-playwrite_cz_guides-400-0.woff2 +0 -0
  144. package/app/public/vendor/fonts/cat-playwrite_de_grund-400-0.woff2 +0 -0
  145. package/app/public/vendor/fonts/cat-playwrite_de_grund_guides-400-0.woff2 +0 -0
  146. package/app/public/vendor/fonts/cat-playwrite_de_la-400-0.woff2 +0 -0
  147. package/app/public/vendor/fonts/cat-playwrite_de_la_guides-400-0.woff2 +0 -0
  148. package/app/public/vendor/fonts/cat-playwrite_de_sas-400-0.woff2 +0 -0
  149. package/app/public/vendor/fonts/cat-playwrite_de_sas_guides-400-0.woff2 +0 -0
  150. package/app/public/vendor/fonts/cat-playwrite_de_va-400-0.woff2 +0 -0
  151. package/app/public/vendor/fonts/cat-playwrite_de_va_guides-400-0.woff2 +0 -0
  152. package/app/public/vendor/fonts/cat-playwrite_dk_loopet-400-0.woff2 +0 -0
  153. package/app/public/vendor/fonts/cat-playwrite_dk_loopet_guides-400-0.woff2 +0 -0
  154. package/app/public/vendor/fonts/cat-playwrite_dk_uloopet-400-0.woff2 +0 -0
  155. package/app/public/vendor/fonts/cat-playwrite_dk_uloopet_guides-400-0.woff2 +0 -0
  156. package/app/public/vendor/fonts/cat-playwrite_es_deco_guides-400-0.woff2 +0 -0
  157. package/app/public/vendor/fonts/cat-playwrite_es_guides-400-0.woff2 +0 -0
  158. package/app/public/vendor/fonts/cat-playwrite_fr_moderne-400-0.woff2 +0 -0
  159. package/app/public/vendor/fonts/cat-playwrite_fr_moderne_guides-400-0.woff2 +0 -0
  160. package/app/public/vendor/fonts/cat-playwrite_fr_trad-400-0.woff2 +0 -0
  161. package/app/public/vendor/fonts/cat-playwrite_fr_trad_guides-400-0.woff2 +0 -0
  162. package/app/public/vendor/fonts/cat-playwrite_gb_j_guides-400-0.woff2 +0 -0
  163. package/app/public/vendor/fonts/cat-playwrite_gb_s_guides-400-0.woff2 +0 -0
  164. package/app/public/vendor/fonts/cat-playwrite_hr-400-0.woff2 +0 -0
  165. package/app/public/vendor/fonts/cat-playwrite_hr_guides-400-0.woff2 +0 -0
  166. package/app/public/vendor/fonts/cat-playwrite_hr_lijeva-400-0.woff2 +0 -0
  167. package/app/public/vendor/fonts/cat-playwrite_hr_lijeva_guides-400-0.woff2 +0 -0
  168. package/app/public/vendor/fonts/cat-playwrite_hu-400-0.woff2 +0 -0
  169. package/app/public/vendor/fonts/cat-playwrite_hu_guides-400-0.woff2 +0 -0
  170. package/app/public/vendor/fonts/cat-playwrite_id-400-0.woff2 +0 -0
  171. package/app/public/vendor/fonts/cat-playwrite_id_guides-400-0.woff2 +0 -0
  172. package/app/public/vendor/fonts/cat-playwrite_ie-400-0.woff2 +0 -0
  173. package/app/public/vendor/fonts/cat-playwrite_ie_guides-400-0.woff2 +0 -0
  174. package/app/public/vendor/fonts/cat-playwrite_in-400-0.woff2 +0 -0
  175. package/app/public/vendor/fonts/cat-playwrite_in_guides-400-0.woff2 +0 -0
  176. package/app/public/vendor/fonts/cat-playwrite_is-400-0.woff2 +0 -0
  177. package/app/public/vendor/fonts/cat-playwrite_is_guides-400-0.woff2 +0 -0
  178. package/app/public/vendor/fonts/cat-playwrite_it_moderna-400-0.woff2 +0 -0
  179. package/app/public/vendor/fonts/cat-playwrite_it_moderna_guides-400-0.woff2 +0 -0
  180. package/app/public/vendor/fonts/cat-playwrite_it_trad-400-0.woff2 +0 -0
  181. package/app/public/vendor/fonts/cat-playwrite_it_trad_guides-400-0.woff2 +0 -0
  182. package/app/public/vendor/fonts/cat-playwrite_mx_guides-400-0.woff2 +0 -0
  183. package/app/public/vendor/fonts/cat-playwrite_ng_modern-400-0.woff2 +0 -0
  184. package/app/public/vendor/fonts/cat-playwrite_ng_modern_guides-400-0.woff2 +0 -0
  185. package/app/public/vendor/fonts/cat-playwrite_nl-400-0.woff2 +0 -0
  186. package/app/public/vendor/fonts/cat-playwrite_nl_guides-400-0.woff2 +0 -0
  187. package/app/public/vendor/fonts/cat-playwrite_no-400-0.woff2 +0 -0
  188. package/app/public/vendor/fonts/cat-playwrite_no_guides-400-0.woff2 +0 -0
  189. package/app/public/vendor/fonts/cat-playwrite_nz-400-0.woff2 +0 -0
  190. package/app/public/vendor/fonts/cat-playwrite_nz_basic-400-0.woff2 +0 -0
  191. package/app/public/vendor/fonts/cat-playwrite_nz_basic_guides-400-0.woff2 +0 -0
  192. package/app/public/vendor/fonts/cat-playwrite_nz_guides-400-0.woff2 +0 -0
  193. package/app/public/vendor/fonts/cat-playwrite_pe_guides-400-0.woff2 +0 -0
  194. package/app/public/vendor/fonts/cat-playwrite_pl-400-0.woff2 +0 -0
  195. package/app/public/vendor/fonts/cat-playwrite_pl_guides-400-0.woff2 +0 -0
  196. package/app/public/vendor/fonts/cat-playwrite_pt_guides-400-0.woff2 +0 -0
  197. package/app/public/vendor/fonts/cat-playwrite_ro-400-0.woff2 +0 -0
  198. package/app/public/vendor/fonts/cat-playwrite_ro_guides-400-0.woff2 +0 -0
  199. package/app/public/vendor/fonts/cat-playwrite_sk-400-0.woff2 +0 -0
  200. package/app/public/vendor/fonts/cat-playwrite_sk_guides-400-0.woff2 +0 -0
  201. package/app/public/vendor/fonts/cat-playwrite_tz-400-0.woff2 +0 -0
  202. package/app/public/vendor/fonts/cat-playwrite_tz_guides-400-0.woff2 +0 -0
  203. package/app/public/vendor/fonts/cat-playwrite_us_modern_guides-400-0.woff2 +0 -0
  204. package/app/public/vendor/fonts/cat-playwrite_us_trad_guides-400-0.woff2 +0 -0
  205. package/app/public/vendor/fonts/cat-playwrite_vn-400-0.woff2 +0 -0
  206. package/app/public/vendor/fonts/cat-playwrite_vn_guides-400-0.woff2 +0 -0
  207. package/app/public/vendor/fonts/cat-playwrite_za-400-0.woff2 +0 -0
  208. package/app/public/vendor/fonts/cat-playwrite_za_guides-400-0.woff2 +0 -0
  209. package/app/public/vendor/fonts/cat-potta_one-400-ext.woff2 +0 -0
  210. package/app/public/vendor/fonts/cat-potta_one-400.woff2 +0 -0
  211. package/app/public/vendor/fonts/cat-ranchers-400-ext.woff2 +0 -0
  212. package/app/public/vendor/fonts/cat-ranchers-400.woff2 +0 -0
  213. package/app/public/vendor/fonts/cat-ranga-400-ext.woff2 +0 -0
  214. package/app/public/vendor/fonts/cat-ranga-400.woff2 +0 -0
  215. package/app/public/vendor/fonts/cat-ranga-700-ext.woff2 +0 -0
  216. package/app/public/vendor/fonts/cat-ranga-700.woff2 +0 -0
  217. package/app/public/vendor/fonts/cat-risque-400-ext.woff2 +0 -0
  218. package/app/public/vendor/fonts/cat-risque-400.woff2 +0 -0
  219. package/app/public/vendor/fonts/cat-rowdies-400-ext.woff2 +0 -0
  220. package/app/public/vendor/fonts/cat-rowdies-400.woff2 +0 -0
  221. package/app/public/vendor/fonts/cat-rowdies-700-ext.woff2 +0 -0
  222. package/app/public/vendor/fonts/cat-rowdies-700.woff2 +0 -0
  223. package/app/public/vendor/fonts/cat-ruge_boogie-400-ext.woff2 +0 -0
  224. package/app/public/vendor/fonts/cat-ruge_boogie-400.woff2 +0 -0
  225. package/app/public/vendor/fonts/cat-ruslan_display-400-ext.woff2 +0 -0
  226. package/app/public/vendor/fonts/cat-ruslan_display-400.woff2 +0 -0
  227. package/app/public/vendor/fonts/cat-sacramento-400-ext.woff2 +0 -0
  228. package/app/public/vendor/fonts/cat-sacramento-400.woff2 +0 -0
  229. package/app/public/vendor/fonts/cat-sancreek-400-ext.woff2 +0 -0
  230. package/app/public/vendor/fonts/cat-sancreek-400.woff2 +0 -0
  231. package/app/public/vendor/fonts/cat-sankofa_display-400-ext.woff2 +0 -0
  232. package/app/public/vendor/fonts/cat-sankofa_display-400.woff2 +0 -0
  233. package/app/public/vendor/fonts/cat-sedgwick_ave_display-400-ext.woff2 +0 -0
  234. package/app/public/vendor/fonts/cat-sedgwick_ave_display-400.woff2 +0 -0
  235. package/app/public/vendor/fonts/cat-shantell_sans-400-ext.woff2 +0 -0
  236. package/app/public/vendor/fonts/cat-shantell_sans-400.woff2 +0 -0
  237. package/app/public/vendor/fonts/cat-smokum-400-ext.woff2 +0 -0
  238. package/app/public/vendor/fonts/cat-smokum-400.woff2 +0 -0
  239. package/app/public/vendor/fonts/cat-solitreo-400-ext.woff2 +0 -0
  240. package/app/public/vendor/fonts/cat-solitreo-400.woff2 +0 -0
  241. package/app/public/vendor/fonts/cat-spicy_rice-400-ext.woff2 +0 -0
  242. package/app/public/vendor/fonts/cat-spicy_rice-400.woff2 +0 -0
  243. package/app/public/vendor/fonts/cat-sriracha-400-ext.woff2 +0 -0
  244. package/app/public/vendor/fonts/cat-sriracha-400.woff2 +0 -0
  245. package/app/public/vendor/fonts/cat-srisakdi-400-ext.woff2 +0 -0
  246. package/app/public/vendor/fonts/cat-srisakdi-400.woff2 +0 -0
  247. package/app/public/vendor/fonts/cat-srisakdi-700-ext.woff2 +0 -0
  248. package/app/public/vendor/fonts/cat-srisakdi-700.woff2 +0 -0
  249. package/app/public/vendor/fonts/cat-stix_two_math-400-0.woff2 +0 -0
  250. package/app/public/vendor/fonts/cat-tillana-400-ext.woff2 +0 -0
  251. package/app/public/vendor/fonts/cat-tillana-400.woff2 +0 -0
  252. package/app/public/vendor/fonts/cat-tillana-700-ext.woff2 +0 -0
  253. package/app/public/vendor/fonts/cat-tillana-700.woff2 +0 -0
  254. package/app/public/vendor/fonts/cat-titan_one-400-ext.woff2 +0 -0
  255. package/app/public/vendor/fonts/cat-titan_one-400.woff2 +0 -0
  256. package/app/public/vendor/fonts/cat-yatra_one-400-ext.woff2 +0 -0
  257. package/app/public/vendor/fonts/cat-yatra_one-400.woff2 +0 -0
  258. package/app/public/vendor/fonts/cat-yomogi-400-ext.woff2 +0 -0
  259. package/app/public/vendor/fonts/cat-yomogi-400.woff2 +0 -0
  260. package/app/public/vendor/fonts/dmserifdisplay-400-ext.woff2 +0 -0
  261. package/app/public/vendor/fonts/dmserifdisplay-400.woff2 +0 -0
  262. package/app/public/vendor/fonts/domine-var-ext.woff2 +0 -0
  263. package/app/public/vendor/fonts/domine-var.woff2 +0 -0
  264. package/app/public/vendor/fonts/fraunces-var-ext.woff2 +0 -0
  265. package/app/public/vendor/fonts/fraunces-var.woff2 +0 -0
  266. package/app/public/vendor/fonts/fredoka-var-ext.woff2 +0 -0
  267. package/app/public/vendor/fonts/fredoka-var.woff2 +0 -0
  268. package/app/public/vendor/fonts/jakarta-var-ext.woff2 +0 -0
  269. package/app/public/vendor/fonts/jakarta-var.woff2 +0 -0
  270. package/app/public/vendor/fonts/lora-var-ext.woff2 +0 -0
  271. package/app/public/vendor/fonts/lora-var.woff2 +0 -0
  272. package/app/public/vendor/fonts/merriweather-var-ext.woff2 +0 -0
  273. package/app/public/vendor/fonts/merriweather-var.woff2 +0 -0
  274. package/app/public/vendor/fonts/notosans-var-ext.woff2 +0 -0
  275. package/app/public/vendor/fonts/notosans-var.woff2 +0 -0
  276. package/app/public/vendor/fonts/nunito-var-ext.woff2 +0 -0
  277. package/app/public/vendor/fonts/nunito-var.woff2 +0 -0
  278. package/app/public/vendor/fonts/playfair-var-ext.woff2 +0 -0
  279. package/app/public/vendor/fonts/playfair-var.woff2 +0 -0
  280. package/app/public/vendor/fonts/playwrite-cu.woff2 +0 -0
  281. package/app/public/vendor/fonts/playwrite-es-deco.woff2 +0 -0
  282. package/app/public/vendor/fonts/playwrite-es.woff2 +0 -0
  283. package/app/public/vendor/fonts/playwrite-gb-j.woff2 +0 -0
  284. package/app/public/vendor/fonts/playwrite-gb-s.woff2 +0 -0
  285. package/app/public/vendor/fonts/playwrite-pe.woff2 +0 -0
  286. package/app/public/vendor/fonts/playwrite-pt.woff2 +0 -0
  287. package/app/public/vendor/fonts/quicksand-var-ext.woff2 +0 -0
  288. package/app/public/vendor/fonts/quicksand-var.woff2 +0 -0
  289. package/app/public/vendor/fonts/robotoflex-var-ext.woff2 +0 -0
  290. package/app/public/vendor/fonts/robotoflex-var.woff2 +0 -0
  291. package/app/public/vendor/fonts/sora-var-ext.woff2 +0 -0
  292. package/app/public/vendor/fonts/sora-var.woff2 +0 -0
  293. package/app/public/vendor/fonts/spacegrotesk-var-ext.woff2 +0 -0
  294. package/app/public/vendor/fonts/spacegrotesk-var.woff2 +0 -0
  295. package/app/public/vendor/fonts/spectral-400-ext.woff2 +0 -0
  296. package/app/public/vendor/fonts/spectral-400.woff2 +0 -0
  297. package/app/public/vendor/fonts/spectral-700-ext.woff2 +0 -0
  298. package/app/public/vendor/fonts/spectral-700.woff2 +0 -0
  299. package/app/public/vendor/fonts/teachers-var-ext.woff2 +0 -0
  300. package/app/public/vendor/fonts/teachers-var.woff2 +0 -0
  301. package/app/public/vendor/fonts/ubuntu-400-ext.woff2 +0 -0
  302. package/app/public/vendor/fonts/ubuntu-400.woff2 +0 -0
  303. package/app/public/vendor/fonts/ubuntu-700-ext.woff2 +0 -0
  304. package/app/public/vendor/fonts/ubuntu-700.woff2 +0 -0
  305. package/app/public/vendor/fonts.css +1167 -51
  306. package/dist-pkg/boot/create-game.d.ts +467 -162
  307. package/dist-pkg/boot/create-game.js +3563 -426
  308. package/dist-pkg/core/a11y-sr.d.ts +25 -3
  309. package/dist-pkg/core/a11y-sr.js +40 -19
  310. package/dist-pkg/core/accessible-label.d.ts +17 -0
  311. package/dist-pkg/core/accessible-label.js +37 -0
  312. package/dist-pkg/core/accommodation-subjects.d.ts +26 -0
  313. package/dist-pkg/core/accommodation-subjects.js +32 -0
  314. package/dist-pkg/core/accommodations.d.ts +107 -0
  315. package/dist-pkg/core/accommodations.js +178 -0
  316. package/dist-pkg/core/actions.d.ts +75 -51
  317. package/dist-pkg/core/actions.js +98 -69
  318. package/dist-pkg/core/calm-mode.d.ts +31 -0
  319. package/dist-pkg/core/calm-mode.js +47 -0
  320. package/dist-pkg/core/camera-cycle.d.ts +15 -0
  321. package/dist-pkg/core/camera-cycle.js +7 -0
  322. package/dist-pkg/core/caption-duration.d.ts +15 -0
  323. package/dist-pkg/core/caption-duration.js +19 -0
  324. package/dist-pkg/core/cartridge-problems.d.ts +34 -0
  325. package/dist-pkg/core/cartridge-problems.js +53 -0
  326. package/dist-pkg/core/constants.d.ts +0 -54
  327. package/dist-pkg/core/constants.js +9 -76
  328. package/dist-pkg/core/contract.d.ts +143 -163
  329. package/dist-pkg/core/contract.js +223 -207
  330. package/dist-pkg/core/dom-query.d.ts +4 -4
  331. package/dist-pkg/core/dom-query.js +12 -20
  332. package/dist-pkg/core/entity.d.ts +62 -77
  333. package/dist-pkg/core/entity.js +18 -32
  334. package/dist-pkg/core/escape-html.d.ts +9 -10
  335. package/dist-pkg/core/escape-html.js +16 -20
  336. package/dist-pkg/core/flash-threshold.d.ts +17 -0
  337. package/dist-pkg/core/flash-threshold.js +113 -0
  338. package/dist-pkg/core/game-speed.d.ts +11 -0
  339. package/dist-pkg/core/game-speed.js +16 -0
  340. package/dist-pkg/core/genres.d.ts +20 -0
  341. package/dist-pkg/core/genres.js +44 -0
  342. package/dist-pkg/core/i18n.d.ts +87 -41
  343. package/dist-pkg/core/i18n.js +206 -153
  344. package/dist-pkg/core/loop.d.ts +17 -6
  345. package/dist-pkg/core/loop.js +26 -26
  346. package/dist-pkg/core/pause-icon-catalogue.d.ts +15 -0
  347. package/dist-pkg/core/pause-icon-catalogue.js +54 -0
  348. package/dist-pkg/core/ring.d.ts +17 -0
  349. package/dist-pkg/core/ring.js +29 -0
  350. package/dist-pkg/core/rng.d.ts +7 -12
  351. package/dist-pkg/core/rng.js +23 -53
  352. package/dist-pkg/core/route.d.ts +26 -26
  353. package/dist-pkg/core/route.js +126 -121
  354. package/dist-pkg/core/scenes.d.ts +37 -40
  355. package/dist-pkg/core/scenes.js +41 -43
  356. package/dist-pkg/core/screens.d.ts +4 -4
  357. package/dist-pkg/core/screens.js +11 -16
  358. package/dist-pkg/core/setting-defaults.d.ts +61 -0
  359. package/dist-pkg/core/setting-defaults.js +66 -0
  360. package/dist-pkg/core/speech-rate.d.ts +29 -0
  361. package/dist-pkg/core/speech-rate.js +47 -0
  362. package/dist-pkg/core/state.d.ts +118 -118
  363. package/dist-pkg/core/state.js +322 -297
  364. package/dist-pkg/core/visual-cycles.d.ts +30 -0
  365. package/dist-pkg/core/visual-cycles.js +52 -0
  366. package/dist-pkg/core/visual-state.d.ts +13 -0
  367. package/dist-pkg/core/visual-state.js +6 -0
  368. package/dist-pkg/educational/activities-registry.d.ts +1 -1
  369. package/dist-pkg/educational/activities-registry.js +9 -8
  370. package/dist-pkg/educational/adaptive-engine.d.ts +11 -11
  371. package/dist-pkg/educational/adaptive-engine.js +17 -17
  372. package/dist-pkg/educational/segment-bar.d.ts +12 -12
  373. package/dist-pkg/educational/segment-bar.js +9 -9
  374. package/dist-pkg/i18n/en.js +321 -215
  375. package/dist-pkg/i18n/es.js +320 -215
  376. package/dist-pkg/i18n/pt.js +342 -215
  377. package/dist-pkg/input/default-bindings.d.ts +37 -38
  378. package/dist-pkg/input/default-bindings.js +127 -144
  379. package/dist-pkg/input/devices.d.ts +7 -7
  380. package/dist-pkg/input/devices.js +17 -16
  381. package/dist-pkg/input/edges.d.ts +23 -32
  382. package/dist-pkg/input/edges.js +23 -28
  383. package/dist-pkg/input/empathy-filter.d.ts +22 -0
  384. package/dist-pkg/input/empathy-filter.js +34 -0
  385. package/dist-pkg/input/face-map.d.ts +96 -0
  386. package/dist-pkg/input/face-map.js +255 -0
  387. package/dist-pkg/input/face-signals.d.ts +40 -0
  388. package/dist-pkg/input/face-signals.js +48 -0
  389. package/dist-pkg/input/gamepad.d.ts +164 -145
  390. package/dist-pkg/input/gamepad.js +351 -559
  391. package/dist-pkg/input/gaze-cycle.d.ts +64 -0
  392. package/dist-pkg/input/gaze-cycle.js +133 -0
  393. package/dist-pkg/input/gaze-relative.d.ts +68 -0
  394. package/dist-pkg/input/gaze-relative.js +142 -0
  395. package/dist-pkg/input/hand-map.d.ts +28 -0
  396. package/dist-pkg/input/hand-map.js +142 -0
  397. package/dist-pkg/input/input-cooldown.d.ts +17 -0
  398. package/dist-pkg/input/input-cooldown.js +39 -0
  399. package/dist-pkg/input/keyboard-runtime.d.ts +18 -20
  400. package/dist-pkg/input/keyboard-runtime.js +23 -27
  401. package/dist-pkg/input/keyboard.d.ts +68 -62
  402. package/dist-pkg/input/keyboard.js +83 -105
  403. package/dist-pkg/input/keydown.d.ts +124 -132
  404. package/dist-pkg/input/keydown.js +283 -288
  405. package/dist-pkg/input/latch-edge.d.ts +25 -21
  406. package/dist-pkg/input/latch-edge.js +33 -35
  407. package/dist-pkg/input/latch-scope.d.ts +43 -47
  408. package/dist-pkg/input/latch-scope.js +66 -75
  409. package/dist-pkg/input/latch-store.d.ts +28 -29
  410. package/dist-pkg/input/latch-store.js +44 -47
  411. package/dist-pkg/input/latch-sync.d.ts +28 -29
  412. package/dist-pkg/input/latch-sync.js +25 -25
  413. package/dist-pkg/input/latch.d.ts +14 -17
  414. package/dist-pkg/input/latch.js +29 -37
  415. package/dist-pkg/input/pad-defaults.d.ts +13 -16
  416. package/dist-pkg/input/pad-defaults.js +21 -28
  417. package/dist-pkg/input/pad-reading.d.ts +76 -0
  418. package/dist-pkg/input/pad-reading.js +164 -0
  419. package/dist-pkg/input/pad-wizard.d.ts +96 -0
  420. package/dist-pkg/input/pad-wizard.js +205 -0
  421. package/dist-pkg/input/pointer-space.d.ts +19 -20
  422. package/dist-pkg/input/pointer-space.js +27 -32
  423. package/dist-pkg/input/pointer.d.ts +39 -40
  424. package/dist-pkg/input/pointer.js +42 -45
  425. package/dist-pkg/input/state.d.ts +101 -89
  426. package/dist-pkg/input/state.js +54 -134
  427. package/dist-pkg/input/switch-scan.d.ts +42 -0
  428. package/dist-pkg/input/switch-scan.js +54 -0
  429. package/dist-pkg/input/synthetic-source.d.ts +42 -0
  430. package/dist-pkg/input/synthetic-source.js +57 -0
  431. package/dist-pkg/input/touch-bindings.d.ts +127 -113
  432. package/dist-pkg/input/touch-bindings.js +158 -173
  433. package/dist-pkg/input/touch.d.ts +130 -70
  434. package/dist-pkg/input/touch.js +321 -123
  435. package/dist-pkg/input/transport-in-use.d.ts +107 -0
  436. package/dist-pkg/input/transport-in-use.js +130 -0
  437. package/dist-pkg/input/transports.d.ts +96 -114
  438. package/dist-pkg/input/transports.js +104 -106
  439. package/dist-pkg/input/virtual-controller.d.ts +46 -0
  440. package/dist-pkg/input/virtual-controller.js +41 -0
  441. package/dist-pkg/input/vocabulary-migration.d.ts +50 -49
  442. package/dist-pkg/input/vocabulary-migration.js +80 -79
  443. package/dist-pkg/input/voice-map.d.ts +43 -0
  444. package/dist-pkg/input/voice-map.js +125 -0
  445. package/dist-pkg/platform/audio-ambient.d.ts +13 -1
  446. package/dist-pkg/platform/audio-ambient.js +11 -13
  447. package/dist-pkg/platform/audio-earcons.d.ts +20 -19
  448. package/dist-pkg/platform/audio-earcons.js +51 -42
  449. package/dist-pkg/platform/audio-jingles.js +9 -10
  450. package/dist-pkg/platform/audio-mixer.d.ts +14 -2
  451. package/dist-pkg/platform/audio-mixer.js +36 -39
  452. package/dist-pkg/platform/audio-sonar.d.ts +96 -113
  453. package/dist-pkg/platform/audio-sonar.js +245 -238
  454. package/dist-pkg/platform/audio.d.ts +53 -19
  455. package/dist-pkg/platform/audio.js +161 -169
  456. package/dist-pkg/platform/flash-sampler.d.ts +19 -0
  457. package/dist-pkg/platform/flash-sampler.js +79 -0
  458. package/dist-pkg/platform/guide-intensity.d.ts +26 -27
  459. package/dist-pkg/platform/guide-intensity.js +50 -52
  460. package/dist-pkg/platform/heavy-catalogue.d.ts +31 -0
  461. package/dist-pkg/platform/heavy-catalogue.js +223 -0
  462. package/dist-pkg/platform/heavy-mirror.d.ts +26 -0
  463. package/dist-pkg/platform/heavy-mirror.js +76 -0
  464. package/dist-pkg/platform/heavy.d.ts +104 -0
  465. package/dist-pkg/platform/heavy.js +169 -0
  466. package/dist-pkg/platform/interruptible-speech.d.ts +16 -16
  467. package/dist-pkg/platform/interruptible-speech.js +50 -51
  468. package/dist-pkg/platform/kokoro-port.d.ts +27 -0
  469. package/dist-pkg/platform/kokoro-port.js +50 -0
  470. package/dist-pkg/platform/kokoro-runtime.d.ts +20 -0
  471. package/dist-pkg/platform/kokoro-runtime.js +52 -0
  472. package/dist-pkg/platform/kokoro.d.ts +70 -0
  473. package/dist-pkg/platform/kokoro.js +133 -0
  474. package/dist-pkg/platform/listener-scope.d.ts +12 -0
  475. package/dist-pkg/platform/listener-scope.js +81 -0
  476. package/dist-pkg/platform/locale-host.d.ts +10 -0
  477. package/dist-pkg/platform/locale-host.js +34 -0
  478. package/dist-pkg/platform/microphone.d.ts +51 -0
  479. package/dist-pkg/platform/microphone.js +118 -0
  480. package/dist-pkg/platform/onnx-runtime.d.ts +34 -0
  481. package/dist-pkg/platform/onnx-runtime.js +42 -0
  482. package/dist-pkg/platform/reading-in-worker.d.ts +40 -0
  483. package/dist-pkg/platform/reading-in-worker.js +87 -0
  484. package/dist-pkg/platform/reading-model.d.ts +73 -0
  485. package/dist-pkg/platform/reading-model.js +247 -0
  486. package/dist-pkg/platform/reading-runtime.d.ts +24 -0
  487. package/dist-pkg/platform/reading-runtime.js +159 -0
  488. package/dist-pkg/platform/reading-worker.d.ts +41 -0
  489. package/dist-pkg/platform/reading-worker.js +58 -0
  490. package/dist-pkg/platform/reading.d.ts +69 -0
  491. package/dist-pkg/platform/reading.js +128 -0
  492. package/dist-pkg/platform/speech-recognition.d.ts +51 -0
  493. package/dist-pkg/platform/speech-recognition.js +84 -0
  494. package/dist-pkg/platform/speech.d.ts +14 -1
  495. package/dist-pkg/platform/speech.js +13 -13
  496. package/dist-pkg/platform/storage-keys.d.ts +96 -0
  497. package/dist-pkg/platform/storage-keys.js +106 -0
  498. package/dist-pkg/platform/storage.d.ts +46 -111
  499. package/dist-pkg/platform/storage.js +104 -169
  500. package/dist-pkg/platform/tts.d.ts +51 -38
  501. package/dist-pkg/platform/tts.js +217 -119
  502. package/dist-pkg/platform/vision-loop.d.ts +23 -0
  503. package/dist-pkg/platform/vision-loop.js +56 -0
  504. package/dist-pkg/platform/vision.d.ts +132 -0
  505. package/dist-pkg/platform/vision.js +117 -0
  506. package/dist-pkg/platform/voice-listener.d.ts +36 -0
  507. package/dist-pkg/platform/voice-listener.js +88 -0
  508. package/dist-pkg/platform/voice-plan.d.ts +6 -102
  509. package/dist-pkg/platform/voice-plan.js +9 -151
  510. package/dist-pkg/platform/vosk-runtime.d.ts +71 -0
  511. package/dist-pkg/platform/vosk-runtime.js +93 -0
  512. package/dist-pkg/render/canvas.d.ts +13 -7
  513. package/dist-pkg/render/canvas.js +13 -13
  514. package/dist-pkg/render/crt.d.ts +46 -12
  515. package/dist-pkg/render/crt.js +82 -80
  516. package/dist-pkg/render/cvd-matrices.d.ts +18 -18
  517. package/dist-pkg/render/cvd-matrices.js +33 -38
  518. package/dist-pkg/render/hc-role-data.d.ts +7 -7
  519. package/dist-pkg/render/hc-role-data.js +14 -14
  520. package/dist-pkg/render/high-contrast.d.ts +66 -54
  521. package/dist-pkg/render/high-contrast.js +221 -216
  522. package/dist-pkg/render/low-vision-drawing.d.ts +5 -0
  523. package/dist-pkg/render/low-vision-drawing.js +46 -0
  524. package/dist-pkg/render/lq-filter.d.ts +32 -20
  525. package/dist-pkg/render/lq-filter.js +59 -65
  526. package/dist-pkg/render/port.d.ts +86 -88
  527. package/dist-pkg/render/port.js +17 -23
  528. package/dist-pkg/render/screen-pipeline.d.ts +42 -42
  529. package/dist-pkg/render/screen-pipeline.js +80 -87
  530. package/dist-pkg/render/sprite-fx.d.ts +2 -1
  531. package/dist-pkg/render/sprite-fx.js +16 -14
  532. package/dist-pkg/render/viewports.d.ts +20 -15
  533. package/dist-pkg/render/viewports.js +83 -114
  534. package/dist-pkg/render/viz-axes-labels.d.ts +47 -0
  535. package/dist-pkg/render/viz-axes-labels.js +88 -0
  536. package/dist-pkg/render/viz-axes.d.ts +80 -86
  537. package/dist-pkg/render/viz-axes.js +115 -116
  538. package/dist-pkg/render/viz-modes.d.ts +28 -29
  539. package/dist-pkg/render/viz-modes.js +40 -45
  540. package/dist-pkg/render/viz-refusal.d.ts +32 -0
  541. package/dist-pkg/render/viz-refusal.js +57 -0
  542. package/dist-pkg/render/viz-setters.d.ts +104 -66
  543. package/dist-pkg/render/viz-setters.js +182 -191
  544. package/dist-pkg/ui/aac-sets.d.ts +40 -0
  545. package/dist-pkg/ui/aac-sets.js +49 -0
  546. package/dist-pkg/ui/audio-choices.d.ts +63 -0
  547. package/dist-pkg/ui/audio-choices.js +94 -0
  548. package/dist-pkg/ui/audio-rows-that-apply.d.ts +12 -0
  549. package/dist-pkg/ui/audio-rows-that-apply.js +43 -0
  550. package/dist-pkg/ui/camera-control.d.ts +6 -0
  551. package/dist-pkg/ui/camera-control.js +14 -0
  552. package/dist-pkg/ui/changed-mark.d.ts +9 -8
  553. package/dist-pkg/ui/changed-mark.js +22 -53
  554. package/dist-pkg/ui/control-choices.d.ts +37 -0
  555. package/dist-pkg/ui/control-choices.js +84 -0
  556. package/dist-pkg/ui/debug-panel.d.ts +59 -43
  557. package/dist-pkg/ui/debug-panel.js +68 -69
  558. package/dist-pkg/ui/dom.d.ts +10 -14
  559. package/dist-pkg/ui/dom.js +10 -47
  560. package/dist-pkg/ui/drawing-problems.d.ts +25 -0
  561. package/dist-pkg/ui/drawing-problems.js +93 -0
  562. package/dist-pkg/ui/eye-control.d.ts +36 -0
  563. package/dist-pkg/ui/eye-control.js +178 -0
  564. package/dist-pkg/ui/face-control.d.ts +25 -0
  565. package/dist-pkg/ui/face-control.js +183 -0
  566. package/dist-pkg/ui/focus-trap.d.ts +39 -49
  567. package/dist-pkg/ui/focus-trap.js +56 -65
  568. package/dist-pkg/ui/fonts.d.ts +118 -63
  569. package/dist-pkg/ui/fonts.js +267 -111
  570. package/dist-pkg/ui/game-options.d.ts +42 -0
  571. package/dist-pkg/ui/game-options.js +138 -0
  572. package/dist-pkg/ui/gaze-overlay.d.ts +64 -0
  573. package/dist-pkg/ui/gaze-overlay.js +165 -0
  574. package/dist-pkg/ui/hand-control.d.ts +25 -0
  575. package/dist-pkg/ui/hand-control.js +143 -0
  576. package/dist-pkg/ui/help-panel.d.ts +76 -0
  577. package/dist-pkg/ui/help-panel.js +232 -0
  578. package/dist-pkg/ui/hud-bands.d.ts +45 -0
  579. package/dist-pkg/ui/hud-bands.js +108 -0
  580. package/dist-pkg/ui/hud.d.ts +73 -70
  581. package/dist-pkg/ui/hud.js +94 -98
  582. package/dist-pkg/ui/item-announcement.d.ts +13 -12
  583. package/dist-pkg/ui/item-announcement.js +25 -26
  584. package/dist-pkg/ui/latch-refusal.d.ts +22 -21
  585. package/dist-pkg/ui/latch-refusal.js +37 -37
  586. package/dist-pkg/ui/layout.d.ts +103 -28
  587. package/dist-pkg/ui/layout.js +114 -99
  588. package/dist-pkg/ui/locale-flags.d.ts +16 -0
  589. package/dist-pkg/ui/locale-flags.js +30 -0
  590. package/dist-pkg/ui/loop-crash.d.ts +17 -17
  591. package/dist-pkg/ui/loop-crash.js +33 -62
  592. package/dist-pkg/ui/menu-intent.d.ts +32 -0
  593. package/dist-pkg/ui/menu-intent.js +54 -0
  594. package/dist-pkg/ui/menu-items.d.ts +10 -0
  595. package/dist-pkg/ui/menu-items.js +22 -0
  596. package/dist-pkg/ui/menu-nav.d.ts +60 -90
  597. package/dist-pkg/ui/menu-nav.js +301 -274
  598. package/dist-pkg/ui/mobility-choices.d.ts +26 -0
  599. package/dist-pkg/ui/mobility-choices.js +41 -0
  600. package/dist-pkg/ui/motion-choices.d.ts +31 -0
  601. package/dist-pkg/ui/motion-choices.js +68 -0
  602. package/dist-pkg/ui/motion-scene.d.ts +24 -19
  603. package/dist-pkg/ui/motion-scene.js +29 -61
  604. package/dist-pkg/ui/mount-panel.d.ts +81 -0
  605. package/dist-pkg/ui/mount-panel.js +61 -0
  606. package/dist-pkg/ui/panel-shell.d.ts +65 -31
  607. package/dist-pkg/ui/panel-shell.js +92 -66
  608. package/dist-pkg/ui/panel-widgets.d.ts +116 -0
  609. package/dist-pkg/ui/panel-widgets.js +208 -0
  610. package/dist-pkg/ui/pause-buttons.d.ts +35 -0
  611. package/dist-pkg/ui/pause-buttons.js +66 -0
  612. package/dist-pkg/ui/pause-icons.d.ts +250 -343
  613. package/dist-pkg/ui/pause-icons.js +614 -605
  614. package/dist-pkg/ui/pause-markup.d.ts +86 -0
  615. package/dist-pkg/ui/pause-markup.js +125 -0
  616. package/dist-pkg/ui/reach-notice.d.ts +22 -23
  617. package/dist-pkg/ui/reach-notice.js +55 -58
  618. package/dist-pkg/ui/scan-overlay.d.ts +23 -0
  619. package/dist-pkg/ui/scan-overlay.js +42 -0
  620. package/dist-pkg/ui/settings-aac.d.ts +68 -0
  621. package/dist-pkg/ui/settings-aac.js +189 -0
  622. package/dist-pkg/ui/settings-audio.d.ts +91 -113
  623. package/dist-pkg/ui/settings-audio.js +407 -405
  624. package/dist-pkg/ui/settings-controls.d.ts +53 -92
  625. package/dist-pkg/ui/settings-controls.js +143 -215
  626. package/dist-pkg/ui/settings-empathy.d.ts +39 -30
  627. package/dist-pkg/ui/settings-empathy.js +53 -60
  628. package/dist-pkg/ui/settings-mobility.d.ts +195 -0
  629. package/dist-pkg/ui/settings-mobility.js +374 -0
  630. package/dist-pkg/ui/settings-motion.d.ts +91 -70
  631. package/dist-pkg/ui/settings-motion.js +287 -198
  632. package/dist-pkg/ui/settings-panel.d.ts +48 -45
  633. package/dist-pkg/ui/settings-panel.js +164 -93
  634. package/dist-pkg/ui/settings-typo.d.ts +28 -76
  635. package/dist-pkg/ui/settings-typo.js +145 -125
  636. package/dist-pkg/ui/settings-visual.d.ts +29 -87
  637. package/dist-pkg/ui/settings-visual.js +240 -193
  638. package/dist-pkg/ui/shell.d.ts +113 -134
  639. package/dist-pkg/ui/shell.js +143 -216
  640. package/dist-pkg/ui/simulation-list.d.ts +27 -0
  641. package/dist-pkg/ui/simulation-list.js +76 -0
  642. package/dist-pkg/ui/simulation-over-the-world.d.ts +23 -0
  643. package/dist-pkg/ui/simulation-over-the-world.js +131 -0
  644. package/dist-pkg/ui/simulation-refusal.d.ts +5 -31
  645. package/dist-pkg/ui/simulation-refusal.js +8 -56
  646. package/dist-pkg/ui/switchable-control.d.ts +11 -0
  647. package/dist-pkg/ui/switchable-control.js +19 -0
  648. package/dist-pkg/ui/title.d.ts +4 -4
  649. package/dist-pkg/ui/title.js +11 -13
  650. package/dist-pkg/ui/top-band.d.ts +24 -0
  651. package/dist-pkg/ui/top-band.js +100 -0
  652. package/dist-pkg/ui/typo-choices.d.ts +71 -0
  653. package/dist-pkg/ui/typo-choices.js +84 -0
  654. package/dist-pkg/ui/visual-axes-panel.d.ts +11 -47
  655. package/dist-pkg/ui/visual-axes-panel.js +12 -94
  656. package/dist-pkg/ui/visual-choices.d.ts +77 -0
  657. package/dist-pkg/ui/visual-choices.js +107 -0
  658. package/dist-pkg/ui/vlibras.d.ts +33 -10
  659. package/dist-pkg/ui/vlibras.js +58 -81
  660. package/dist-pkg/ui/voice-control.d.ts +46 -0
  661. package/dist-pkg/ui/voice-control.js +143 -0
  662. package/dist-pkg/ui/voice-settings.d.ts +96 -0
  663. package/dist-pkg/ui/voice-settings.js +302 -0
  664. package/dist-pkg/ui/where-the-child-is.d.ts +31 -0
  665. package/dist-pkg/ui/where-the-child-is.js +70 -0
  666. package/docs/CREDITS.md +198 -54
  667. package/docs/LICENSES.md +160 -145
  668. package/package.json +24 -25
  669. package/scripts/heavy-into-the-delivery.mjs +144 -0
  670. package/scripts/licences/Apache-2.0.txt +176 -0
  671. package/scripts/licences/GPL-3.0.txt +674 -0
  672. package/scripts/licences/MIT.txt +17 -0
  673. package/scripts/licences/third-party.mjs +287 -0
  674. package/scripts/licences/vosk-browser.NOTICE.txt +268 -0
  675. package/app/public/vendor/fonts/comicneue-400.woff2 +0 -0
  676. package/app/public/vendor/fonts/comicneue-700.woff2 +0 -0
  677. package/dist-pkg/core/anel.d.ts +0 -17
  678. package/dist-pkg/core/anel.js +0 -31
  679. package/dist-pkg/core/collision.d.ts +0 -21
  680. package/dist-pkg/core/collision.js +0 -62
  681. package/dist-pkg/core/layers.d.ts +0 -63
  682. package/dist-pkg/core/layers.js +0 -95
  683. package/dist-pkg/core/letter-grid.d.ts +0 -55
  684. package/dist-pkg/core/letter-grid.js +0 -116
  685. package/dist-pkg/core/password.d.ts +0 -34
  686. package/dist-pkg/core/password.js +0 -205
  687. package/dist-pkg/core/rotulo-acessivel.d.ts +0 -17
  688. package/dist-pkg/core/rotulo-acessivel.js +0 -41
  689. package/dist-pkg/core/run-state.d.ts +0 -115
  690. package/dist-pkg/core/run-state.js +0 -40
  691. package/dist-pkg/core/tiles.d.ts +0 -12
  692. package/dist-pkg/core/tiles.js +0 -61
  693. package/dist-pkg/core/world.d.ts +0 -4
  694. package/dist-pkg/core/world.js +0 -58
  695. package/dist-pkg/input/origem-sintetica.d.ts +0 -44
  696. package/dist-pkg/input/origem-sintetica.js +0 -60
  697. package/dist-pkg/input/transporte-em-uso.d.ts +0 -101
  698. package/dist-pkg/input/transporte-em-uso.js +0 -130
  699. package/dist-pkg/platform/audio-nav.d.ts +0 -51
  700. package/dist-pkg/platform/audio-nav.js +0 -99
  701. package/dist-pkg/platform/pesados-catalogo.d.ts +0 -14
  702. package/dist-pkg/platform/pesados-catalogo.js +0 -177
  703. package/dist-pkg/platform/pesados.d.ts +0 -31
  704. package/dist-pkg/platform/pesados.js +0 -75
  705. package/dist-pkg/platform/vozes-prontas.d.ts +0 -28
  706. package/dist-pkg/platform/vozes-prontas.js +0 -61
  707. package/dist-pkg/render/camera.d.ts +0 -58
  708. package/dist-pkg/render/camera.js +0 -105
  709. package/dist-pkg/render/cenario-data.d.ts +0 -127
  710. package/dist-pkg/render/cenario-data.js +0 -145
  711. package/dist-pkg/render/city-tex.d.ts +0 -63
  712. package/dist-pkg/render/city-tex.js +0 -228
  713. package/dist-pkg/render/city-tiles.d.ts +0 -11
  714. package/dist-pkg/render/city-tiles.js +0 -140
  715. package/dist-pkg/render/draw.d.ts +0 -149
  716. package/dist-pkg/render/draw.js +0 -231
  717. package/dist-pkg/render/fx.d.ts +0 -63
  718. package/dist-pkg/render/fx.js +0 -123
  719. package/dist-pkg/render/minimap.d.ts +0 -11
  720. package/dist-pkg/render/minimap.js +0 -94
  721. package/dist-pkg/render/parallax.d.ts +0 -85
  722. package/dist-pkg/render/parallax.js +0 -158
  723. package/dist-pkg/render/player-anim.d.ts +0 -71
  724. package/dist-pkg/render/player-anim.js +0 -152
  725. package/dist-pkg/render/recycling-tex.d.ts +0 -48
  726. package/dist-pkg/render/recycling-tex.js +0 -164
  727. package/dist-pkg/render/scene-city.d.ts +0 -77
  728. package/dist-pkg/render/scene-city.js +0 -181
  729. package/dist-pkg/render/scene-parallax.d.ts +0 -72
  730. package/dist-pkg/render/scene-parallax.js +0 -426
  731. package/dist-pkg/render/scene-sky.d.ts +0 -126
  732. package/dist-pkg/render/scene-sky.js +0 -295
  733. package/dist-pkg/render/set-cenario.d.ts +0 -54
  734. package/dist-pkg/render/set-cenario.js +0 -103
  735. package/dist-pkg/render/textures.d.ts +0 -75
  736. package/dist-pkg/render/textures.js +0 -240
  737. package/dist-pkg/render/title-scene.d.ts +0 -46
  738. package/dist-pkg/render/title-scene.js +0 -75
  739. package/dist-pkg/render/weather.d.ts +0 -96
  740. package/dist-pkg/render/weather.js +0 -171
  741. package/dist-pkg/render/wheelchair-sprites.d.ts +0 -32
  742. package/dist-pkg/render/wheelchair-sprites.js +0 -69
  743. package/dist-pkg/render/world-tex.d.ts +0 -18
  744. package/dist-pkg/render/world-tex.js +0 -87
  745. package/dist-pkg/ui/activities-menu.d.ts +0 -258
  746. package/dist-pkg/ui/activities-menu.js +0 -648
  747. package/dist-pkg/ui/caa-sets.d.ts +0 -39
  748. package/dist-pkg/ui/caa-sets.js +0 -65
  749. package/dist-pkg/ui/map-hub.d.ts +0 -56
  750. package/dist-pkg/ui/map-hub.js +0 -138
  751. package/dist-pkg/ui/settings-caa.d.ts +0 -45
  752. package/dist-pkg/ui/settings-caa.js +0 -137
  753. package/dist-pkg/ui/settings-motor.d.ts +0 -175
  754. package/dist-pkg/ui/settings-motor.js +0 -342
  755. package/dist-pkg/ui/webcam.d.ts +0 -7
  756. package/dist-pkg/ui/webcam.js +0 -93
@@ -1,131 +1,126 @@
1
1
  // SPDX-License-Identifier: AGPL-3.0-or-later
2
- // platform/audio-sonar — NAVEGAÇÃO SONORA, a metade de `audio-nav` que serve a QUALQUER gênero (item 19).
2
+ // platform/audio-sonar — NAVIGATION BY SOUND, the part of audio navigation that serves ANY genre (item 19).
3
3
  //
4
- // ========================= O ACHADO 9, VIRADO CORTE =========================
5
- // O segundo consumidor registrou, e não contornou:
4
+ // ========================= A FINDING, TURNED INTO A CUT =========================
5
+ // A second consumer recorded it and did not work around it: the sonar could not be used by anything but a platformer.
6
+ // Its context asked for tiles, a solid test, a hitbox, the tile size, a coin array and a scenery — a quiz would have had
7
+ // to invent fake tiles, a fake hitbox and a fake scenery to ask "point at the nearest option". The module was TWO
8
+ // modules under one name.
6
9
  //
7
- // "O SONAR NÃO PODE SER USADO POR QUEM NÃO É PLATAFORMA… O ctx de `platform/audio-nav` pede 19 coisas, e
8
- // seis delas são de plataforma pura — `tileAt`, `solidAt`, `BOX`, `TILE`, `getCoins`, `getCenario`. Um
9
- // quiz teria de inventar tiles falsos, uma caixa de colisão falsa e um cenário falso para pedir 'aponte
10
- // a alternativa mais próxima'. E o módulo é DOIS módulos com um nome só."
10
+ // This is one of them: what navigates by SOUND — pointing at the nearest target, the looping beacon, the pan by relative
11
+ // position and the question "does this child need audio cues?". The CANE and BLIND SWIMMING, which read tiles, floor and
12
+ // hitbox, are the platformer's and live in its repository (ADR-0228, note CC), and the audio guide is its decision.
11
13
  //
12
- // Estes são os dois. Aqui fica o que navega por SOM: apontar o alvo mais perto, o beacon em laço, o pan pela
13
- // posição relativa e a pergunta "esta criança precisa de pista sonora?". Em `audio-nav` ficam a BENGALA e o
14
- // NADO CEGO, que leem tile, chão e caixa de colisão — plataforma, e sem disfarce.
14
+ // ========================= WHAT REPLACED THE PLATFORMER THINGS =========================
15
+ // None of them crossed over. The sonar used to ask the game for an array of coins and filter by taken/owner; now it
16
+ // receives the CONTRACT (ADR-0030):
15
17
  //
16
- // ========================= O QUE SUBSTITUIU AS SEIS COISAS DE PLATAFORMA =========================
17
- // Nenhuma delas atravessou. O sonar perguntava ao jogo por um array de moedas e filtrava `taken`/`owner`;
18
- // agora ele recebe o CONTRATO (ADR-0030):
18
+ // · the coins + the filter → `targetsOf(i)`, the "target" half of field 5. The game hands over the spots that still
19
+ // count for that player, and never says what they are.
20
+ // · the tile size (the ruler of "near") → `topology()` + `distance()`, the metric declared in field 1. In a
21
+ // platformer it is pixels over `unit`; on a grid, king's steps; in a quiz, a difference of index.
22
+ // · the target's name → `nameAt(spot)`, field 3. It is what lets the announcement say "coin", "question" or "box"
23
+ // without the engine knowing any of the three.
19
24
  //
20
- // · `getCoins()` + o filtro → `targetsOf(i)`, a metade "alvo" do campo 5. O jogo entrega os pontos que
21
- // ainda contam para aquele jogador, e nunca diz o que eles são.
22
- // · `TILE` (a régua de "perto") → `topology()` + `distance()`, a métrica declarada no campo 1. Numa
23
- // plataforma são pixels sobre `unit`; numa grade, passos de rei; num quiz, diferença de índice.
24
- // · `t('sr.nav.coin')` (o nome do alvo) → `nameAt(spot)`, campo 3. É o que faz o anúncio dizer "moeda",
25
- // "pergunta" ou "caixa" sem a engine conhecer nenhum dos três.
25
+ // ⚠️ AND ONE WAS LEFT, THE LAST AND THE WORST: the pan measured the stereo width as `LOGICAL_W * 0.55` — the SCREEN's
26
+ // width. The `wx` it divides comes from the TOPOLOGY, and dividing a world measure by a screen's width only works when
27
+ // both use the same ruler. Measured building a football game (#121): on a 90-METRE pitch, a team-mate ten metres to the
28
+ // right gives `10 / 176 = 0.057` — mono, in practice. The sonar would be **right and inaudible**. For the platformer it
29
+ // was true by chance (its world is measured in pixels) and for `grid`/`hotspots` it was vacuous, which is why it was
30
+ // never seen.
26
31
  //
27
- // ⚠️ E SOBRAVA UMA, QUE ERA A ÚLTIMA E A PIOR: o pan media a largura do estéreo em `LOGICAL_W * 0.55` — a
28
- // largura da TELA. Escrevi aqui que ela era «da tela e não do gênero, e por isso entra por ctx». A frase
29
- // estava certa sobre a origem e errada sobre a consequência: o `wx` que ela divide vem da TOPOLOGIA, e
30
- // dividir uma medida de mundo pela largura de um ecrã só funciona quando as duas usam a mesma régua.
32
+ // The stereo width comes from the declared metric: `PAN_PACES * step`, where the step is the continuous space's `unit`,
33
+ // one cell on a grid, and nothing in a list — which has no space.
31
34
  //
32
- // Medido ao construir o `game-soccer` (#121): num campo de 90 METROS, um colega dez metros à direita dá
33
- // `10 / 176 = 0,057` — mono, na prática. O sonar ficaria **certo e inaudível**, que é a mesma classe de
34
- // defeito que o quiz registou como «certo e inútil». Para a plataforma era verdade por acaso (o mundo dela é
35
- // medido em pixels) e para `grid`/`hotspots` era vácuo, e é por isso que nunca se viu.
36
- //
37
- // A largura do estéreo passa a vir da métrica declarada: `PAN_PACES * passo`, onde o passo é o `unit` do
38
- // contínuo, uma célula na grade, e nada na lista — que não tem espaço.
39
- //
40
- // ========================= SEM I/O NO IMPORT =========================
41
- // Nada aqui toca `window` fora de `playerCtx`, que é chamada e não importada. Roda no project `node`.
35
+ // ========================= NO I/O AT IMPORT =========================
36
+ // Nothing here touches `window`: a player's own context comes from the injected `newContext` (ADR-0232 D4). It runs in the
37
+ // `node` project.
42
38
  import { distance, bearing } from '../core/contract.js';
43
- import { t } from '../core/i18n.js';
44
- // O GUIA (#84 item 2) é feito destes dois, e de mais nada: a ROTA diz quantos passos faltam contornando
45
- // parede, e a INTENSIDADE traduz esse número em brilho e volume. Nenhum dos dois toca no Web Audio; a fiação
46
- // — a única parte que toca — é o `updateGuide` lá em baixo, e é por isso que o desenho é conferível em `node`.
47
- import { rotaAte } from '../core/route.js';
48
- import { intensidadeDoGuia, CORTE_LONGE, PASSOS_ATE_O_FUNDO } from './guide-intensity.js';
39
+ // THE GUIDE (#84 item 2) is made of these two and nothing else: the ROUTE says how many steps remain going round walls,
40
+ // and the INTENSITY turns that number into brightness and volume. Neither touches Web Audio; the wiring — the only part
41
+ // that does — is `updateGuide` below, which is why the design can be checked in `node`.
42
+ import { routeTo } from '../core/route.js';
43
+ import { guideIntensity, FAR_CUT, STEPS_TO_FLOOR } from './guide-intensity.js';
49
44
  /**
50
- * Quantos PASSOS da métrica declarada saturam o estéreo. Além disto, "à direita" é só à direita.
45
+ * How many STEPS of the declared metric saturate the stereo. Beyond this, "to the right" is just to the right.
51
46
  *
52
- * ⚠️ ONZE NÃO É NÚMERO NOVO — é o que a plataforma sempre teve, relido na régua certa. O denominador antigo
53
- * era `LOGICAL_W * 0.55 = 320 × 0,55 = 176` pixels, e a plataforma declara `unit: TILE` = 16: são **exatamente
54
- * 11 tiles**. Reescrever em passos preserva o que essa criança já ouve, letra por letra, e passa a dizer o
55
- * mesmo em qualquer gênero — 11 casas num tabuleiro, 11 metros num campo.
47
+ * ⚠️ ELEVEN IS NOT A NEW NUMBER — it is what the platformer always had, reread on the right ruler. The old denominator was
48
+ * `LOGICAL_W * 0.55 = 320 × 0.55 = 176` pixels, and the platformer declares `unit: TILE` = 16: **exactly 11 tiles**.
49
+ * Rewriting it in steps keeps what that child already hears, and says the same in any genre — 11 squares on a board,
50
+ * 11 metres on a pitch.
56
51
  *
57
- * E encaixa na régua que o resto do módulo já usa: `chaveDeDistancia` corta "muito perto" em 4 passos e
58
- * "perto" em 9. O estéreo satura logo depois de a coisa passar a ser "longe", que é onde a direção deixa de
59
- * precisar de mais precisão.
52
+ * And it fits the ruler the rest of the module uses: `distanceKey` cuts "very near" at 4 steps and "near" at 9. The
53
+ * stereo saturates just after the thing becomes "far", which is where direction stops needing more precision.
60
54
  */
61
55
  export const PAN_PACES = 11;
62
56
  /**
63
- * Quanto vale UM passo, em unidades do mundo. Zero = este espaço não tem lado.
57
+ * What ONE step is worth, in world units. Zero = this space has no sides.
64
58
  *
65
- * Contínuo: o `unit` declarado. Grade: uma célula, por definição. Lista: nada — `hotspots` é uma ordem, não
66
- * uma geometria, e inventar-lhe uma largura de estéreo seria apontar para um lado que não existe.
59
+ * Continuous: the declared `unit`. Grid: one cell, by definition. List: nothing — `hotspots` is an order, not a geometry,
60
+ * and inventing a stereo width for it would point at a side that does not exist.
67
61
  */
68
- export function passoDoMundo(topo) {
69
- return topo.kind === 'continuous' ? topo.unit : topo.kind === 'grid' ? 1 : 0;
62
+ export function worldStep(shape) {
63
+ return shape.kind === 'continuous' ? shape.unit : shape.kind === 'grid' ? 1 : 0;
70
64
  }
71
65
  /**
72
- * ⚠️ O TIMBRE TEM DE TER HARMÓNICOS, e isto é requisito técnico, não gosto.
66
+ * ⚠️ THE TIMBRE MUST HAVE HARMONICS, and it is a technical requirement, not taste.
73
67
  *
74
- * O eixo do #84 item 2 é o BRILHO, e brilho é um passa-baixo a abrir e a fechar. **Um passa-baixo sobre uma
75
- * onda `sine` não faz absolutamente nada**: a senoide não tem nada acima da fundamental para o filtro cortar,
76
- * e o guia ficaria com um eixo morto e só o volume a trabalhar. A dente-de-serra é a mais rica das quatro
77
- * ondas do Web Audio — tem TODOS os harmónicos —, e é por isso que ela é a escolha.
68
+ * The axis of #84 item 2 is BRIGHTNESS, and brightness is a low-pass opening and closing. **A low-pass over a `sine` wave
69
+ * does absolutely nothing**: a sine has nothing above its fundamental for the filter to cut, and the guide would be left
70
+ * with a dead axis and only the volume working. The sawtooth is the richest of Web Audio's four waves — it has ALL the
71
+ * harmonics — which is why it is the choice.
78
72
  *
79
- * E ela resolve, de graça, a outra restrição do plano: o sonar e a bengala usam `sine`. Um timbre diferente
80
- * era exigência de não colidirem no mesmo canal; aqui o timbre diferente É o mecanismo.
73
+ * And it solves, for free, the plan's other constraint: the sonar and the cane use `sine`. A different timbre was
74
+ * required so they would not collide on one channel; here the different timbre IS the mechanism.
81
75
  */
82
- export const GUIA_TIPO = 'sawtooth';
76
+ export const GUIDE_WAVE = 'sawtooth';
83
77
  /**
84
- * A fundamental do guia, fixa.
78
+ * The guide's fundamental, fixed.
85
79
  *
86
- * ⚠️ FIXA DE PROPÓSITO: a ALTURA já é a linguagem do sonar (`380 + 740 * near`, mais perto = mais agudo). Se o
87
- * guia também subisse de tom, os dois estariam a dizer a mesma coisa pelo mesmo meio, e quem ouve os dois ao
88
- * mesmo tempo não teria como separá-los. O guia diz distância por brilho; o sonar, por altura.
80
+ * ⚠️ FIXED ON PURPOSE: PITCH is already the sonar's language (`380 + 740 * near`, nearer = higher). If the guide also
81
+ * rose in pitch, both would say the same thing through the same means, and whoever hears both at once could not tell them
82
+ * apart. The guide says distance by brightness; the sonar, by pitch.
89
83
  */
90
- export const GUIA_HZ = 220;
84
+ const GUIDE_HZ = 220;
91
85
  /**
92
- * Quantos quadros entre dois cálculos de rota.
86
+ * How many frames between two route computations.
93
87
  *
94
- * ⚠️ A ROTA É UMA BUSCA EM LARGURA, e o `__incl.update(dt)` conta QUADROS: correr uma BFS a cada quadro num
95
- * mapa de plataforma gasta o orçamento do quadro inteiro no aparelho-alvo (Positivo/Chromebook, pilar 1). Doze
96
- * quadros são ~0,2 s a 60 fps — mais depressa do que a criança anda um passo, e o som não espera por eles: a
97
- * intensidade é reescrita TODO quadro, com o `passos` que a última rota deixou.
88
+ * ⚠️ THE ROUTE IS A BREADTH-FIRST SEARCH, and `__incl.update(dt)` counts FRAMES: running a BFS every frame on a platform
89
+ * map spends the whole frame budget on the target device (Positivo/Chromebook, pillar 1). Twelve frames are ~0.2 s at
90
+ * 60 fps — faster than a child takes a step, and the sound does not wait for them: the intensity is rewritten EVERY
91
+ * frame, with the steps the last route left.
98
92
  */
99
- export const QUADROS_ENTRE_ROTAS = 12;
93
+ export const FRAMES_BETWEEN_ROUTES = 12;
100
94
  /**
101
- * O tecto de pontos da rota do guia. Bem abaixo dos 4096 do `core/route`, e o próprio módulo diz porquê:
102
- * «uma pista por quadro tolera muito menos do que um cálculo ao carregar a fase». Estourar devolve `null`, que
103
- * é «não sei» — e o guia cai na reta, que ainda soa.
95
+ * The ceiling of spots for the guide's route. Well below `core/route`'s 4096, and that module says why: a cue every
96
+ * frame tolerates far less than a calculation when a level loads. Hitting it returns `null`, which is "I cannot say" —
97
+ * and the guide falls back to the straight line, which still sounds.
104
98
  */
105
- export const ORCAMENTO_DA_ROTA = 1024;
99
+ const ROUTE_BUDGET = 1024;
106
100
  /**
107
- * O ganho de base do guia, antes de a intensidade e o volume mestre o multiplicarem.
101
+ * The guide's base gain, before the intensity and the master volume multiply it.
108
102
  *
109
- * ⚠️ MAIS BAIXO DO QUE O BIPE QUE ELE SUBSTITUI (0,11), e não por engano: um som que **nunca para** é
110
- * percebido como mais alto do que um transiente do mesmo pico, e cansa por permanência em vez de por
111
- * intensidade — exactamente o que o modo TEA existe para não fazer.
103
+ * ⚠️ LOWER THAN THE BEEP IT REPLACES (0.11), and not by mistake: a sound that **never stops** is perceived as louder
104
+ * than a transient of the same peak, and it tires by persistence rather than intensity — exactly what autism-support
105
+ * mode exists not to do.
112
106
  */
113
- export const GUIA_VOL = 0.06;
114
- /** Constante de tempo do `setTargetAtTime`. Curta o bastante para acompanhar o passo, longa o bastante para
115
- * que a mudança seja um deslize e não um degrau — um degrau a cada rota seria um bipe outra vez. */
116
- export const TAU_DO_GUIA = 0.08;
107
+ export const GUIDE_VOL = 0.06;
108
+ /** The `setTargetAtTime` time constant. Short enough to follow a step, long enough that a change is a glide and not a
109
+ * stair — a stair on every route would be a beep again. */
110
+ const GUIDE_TAU = 0.08;
117
111
  export function createAudioSonar(ctx) {
112
+ const { t } = ctx;
118
113
  let _sonarCount = 0, _guideCount = 0;
119
- /** AudioContext do jogador (para o `setSinkId` no dispositivo dele), ou null → contexto global. */
114
+ /** The player's AudioContext (for `setSinkId` on their device), or null → the global context. */
120
115
  function playerCtx(pl) {
121
116
  if (!pl || !pl.audioSink)
122
117
  return null;
123
118
  try {
124
119
  if (!pl._ac) {
125
- const AC = window.AudioContext || window.webkitAudioContext;
126
- if (!AC)
120
+ const ac = ctx.newContext();
121
+ if (!ac)
127
122
  return null;
128
- pl._ac = new AC();
123
+ pl._ac = ac;
129
124
  pl._acOut = pl._ac.createGain();
130
125
  pl._acOut.connect(pl._ac.destination);
131
126
  if (pl._ac.setSinkId)
@@ -140,242 +135,254 @@ export function createAudioSonar(ctx) {
140
135
  }
141
136
  }
142
137
  function panFor(wx, pl) {
143
- const passo = passoDoMundo(ctx.topology());
144
- // `hotspots` não tem espaço, logo não tem lado. O `bearing` já responde `none` pelo mesmo motivo, e
145
- // centrar é a única resposta honesta — um pan calculado sobre índices de lista aponta para nada.
146
- if (!(passo > 0))
138
+ const pace = worldStep(ctx.topology());
139
+ // `hotspots` has no space, so no side. `bearing` already answers `none` for the same reason, and centring is the only
140
+ // honest answer — a pan computed over list indices points at nothing.
141
+ if (!(pace > 0))
147
142
  return 0;
148
- return Math.max(-1, Math.min(1, (wx - pl.x) / (PAN_PACES * passo)));
143
+ return Math.max(-1, Math.min(1, (wx - pl.x) / (PAN_PACES * pace)));
149
144
  }
150
145
  /**
151
- * Visão comprometida? Guarda e guia só existem quando a resposta é sim (ou no modo cego).
146
+ * Impaired sight? The edge guard and the guide exist only when the answer is yes (or in blind mode).
152
147
  *
153
- * ⚠️ A METADE VISUAL PASSOU A SER INJECTADA (#104), e o módulo ficou MENOR em vez de migrado. Ele
154
- * consultava `ctx.VIZ_BY_KEY[pl.viz]` — uma tabela de modos de RENDER, atravessada por uma chave de
155
- * render, dentro de `platform/`. A #104 obrigava a escolher: ou este ficheiro passava a importar
156
- * `render/viz-axes` (uma aresta ao contrário: medido, `render/` importa de `platform/` em cinco pontos e o
157
- * inverso em nenhum), ou deixava de saber o que é um modo visual.
148
+ * ⚠️ THE VISUAL HALF IS INJECTED (#104), and the module got SMALLER instead of migrating. It used to consult a table of
149
+ * RENDER modes, walked with a render key, from inside `platform/`. The choice was: import `render/` (an edge the wrong
150
+ * way — `render/` imports `platform/`, never the reverse), or stop knowing what a visual mode is.
158
151
  *
159
- * A segunda é a certa, e é o movimento que o `touch.ts` já nomeia como «o mesmo do achado 10
160
- * (`isNavigable`): injetar o BOOLEANO, não o estado». O que este módulo precisa de saber é «esta criança
161
- * precisa de pista sonora», e isso não é uma pergunta sobre tabelas de filtro — é uma pergunta que a raiz
162
- * de composição responde, porque é ela que conhece os dois eixos.
152
+ * The second is right, and it is the move of `isNavigable`: inject the BOOLEAN, not the state. What this module needs to
153
+ * know is "does this child need audio cues", and that is not a question about filter tables — the composition root
154
+ * answers it, because it knows the two axes.
163
155
  *
164
- * O que FICA aqui é a regra que é mesmo deste módulo: **o modo cego liga as pistas para toda a gente**,
165
- * independentemente do que a visão diga.
156
+ * What STAYS here is the rule that really is this module's: **blind mode turns the cues on for everyone**, whatever
157
+ * sight says.
166
158
  */
167
159
  function needsAudioCues(pl) {
168
- return ctx.getModoCego() || ctx.visaoComprometida(pl);
160
+ return ctx.getBlindMode() || ctx.visionImpaired(pl);
169
161
  }
170
162
  /**
171
- * O alvo mais perto deste jogador, na MÉTRICA DECLARADA — e `null` se não houver nenhum.
172
- *
173
- * Era um laço sobre `getCoins()` com `if (cn.taken || cn.owner !== pl.i) continue` e `Math.hypot`. As três
174
- * coisas que ele sabia sobre o jogo (que alvos são moedas, que moedas têm dono, que distância é euclidiana
175
- * em pixels) viraram uma pergunta ao contrato e uma chamada a `distance`.
176
- */
177
- /**
178
- * O RUMO EM PALAVRAS, na língua de quem joga e no referencial que o JOGO declarou.
163
+ * THE BEARING IN WORDS, in the player's language and in the frame the GAME declared.
179
164
  *
180
- * ⚠️ O QUE ISTO SUBSTITUI ERA UM DEFEITO DE ACESSIBILIDADE, não um detalhe de estilo. O sonar calculava o
181
- * lado à mão, de `x` cru, com zona morta de ±4:
165
+ * ⚠️ WHAT THIS REPLACED WAS AN ACCESSIBILITY DEFECT, not a style detail. The sonar computed the side by hand, from a raw
166
+ * `x`, with a ±4 dead zone:
182
167
  *
183
- * alvo.at.x < pl.x - 4 ? 'left' : alvo.at.x > pl.x + 4 ? 'right' : 'ahead'
168
+ * target.at.x < pl.x - 4 ? 'left' : target.at.x > pl.x + 4 ? 'right' : 'ahead'
184
169
  *
185
- * Três palavras onde o contrato tem oito — e MISTURANDO REFERENCIAIS: *esquerda/direita* é relativo à TELA,
186
- * *à frente* é relativo ao CORPO, e quem ouve não tem como saber de que origem cada uma fala. Pior: tudo o
187
- * que estivesse acima ou abaixo da criança virava «à frente», que é justamente a informação que mais falta
188
- * a quem não vê a tela — apagada por uma zona morta.
170
+ * Three words where the contract has eight — and MIXING FRAMES: left/right is relative to the SCREEN, ahead is relative
171
+ * to the BODY, and a listener cannot know which origin each one speaks from. Worse: everything above or below the child
172
+ * became "ahead", exactly the information most missing for someone who cannot see the screen — erased by a dead zone.
189
173
  *
190
- * ⚠️ E O REFERENCIAL É DO JOGO. Num tabuleiro diz-se «a nordeste»; numa plataforma 2D vista de lado, norte
191
- * não quer dizer nada, e o que se diz é «às 2 horas».
174
+ * ⚠️ AND THE FRAME IS THE GAME'S. On a board one says "to the north-east"; in a 2D platformer seen from the side, north
175
+ * means nothing, and what one says is "at 2 o'clock".
192
176
  */
193
- function emPalavras(r) {
177
+ function inWords(r) {
194
178
  if (r.kind === 'none')
195
179
  return t('sr.nav.here');
196
- // Uma chave com `{h}` e não doze — mas a forma do singular é sua, porque «às 1 horas» não é português
197
- // (nem «a las 1» é espanhol). Em inglês as duas coincidem, e coincidir não é motivo para não a ter.
180
+ // One key with `{h}` and not twelve — but the singular has its own, because "at 1 hours" is not a sentence in any of
181
+ // the three languages the way the plural key would write it. Where two forms coincide, having both costs nothing.
198
182
  if (r.kind === 'clock')
199
183
  return r.hour === 1 ? t('sr.nav.clockOne') : t('sr.nav.clock', { h: r.hour });
200
184
  return t('sr.nav.dir.' + r.heading);
201
185
  }
202
- function alvoMaisProximo(pl) {
203
- const topo = ctx.topology();
204
- const aqui = { x: pl.x, y: pl.y };
205
- let melhor = null, bd = Infinity;
206
- for (const alvo of ctx.targetsOf(pl.i)) {
207
- const d = distance(topo, aqui, alvo);
186
+ /**
187
+ * This player's nearest target, in the DECLARED METRIC — and `null` if there is none.
188
+ *
189
+ * It was a loop over coins that skipped the taken and the unowned and measured with `Math.hypot`. The three things it
190
+ * knew about the game (that targets are coins, that coins have owners, that distance is Euclidean in pixels) became a
191
+ * question to the contract and a call to `distance`.
192
+ */
193
+ function nearestSpot(pl) {
194
+ const shape = ctx.topology();
195
+ const here = { x: pl.x, y: pl.y };
196
+ let nearest = null, bd = Infinity;
197
+ for (const target of ctx.targetsOf(pl.i)) {
198
+ const d = distance(shape, here, target);
208
199
  if (d < bd) {
209
200
  bd = d;
210
- melhor = alvo;
201
+ nearest = target;
211
202
  }
212
203
  }
213
- return melhor ? { at: melhor, d: bd } : null;
204
+ return nearest ? { at: nearest, d: bd } : null;
214
205
  }
215
206
  /**
216
- * "Perto" em PASSOS da métrica declarada, e não em pixels.
207
+ * "Near" in STEPS of the declared metric, not in pixels.
217
208
  *
218
- * Os limiares de 4 e 9 tiles do original viram 4 e 9 UNIDADES: numa plataforma com `unit = TILE` a conta é
219
- * a mesma de antes, letra por letra; numa grade são quatro e nove casas; num quiz, quatro e nove itens de
220
- * distância na lista. É a mesma frase para a criança em qualquer gênero, que é o ponto do contrato.
209
+ * The original thresholds of 4 and 9 tiles become 4 and 9 UNITS: in a platformer with `unit = TILE` the sum is the same
210
+ * as before; on a grid it is four and nine squares; in a quiz, four and nine items away in the list. The same sentence
211
+ * for the child in any genre, which is the contract's point.
221
212
  */
222
- const chaveDeDistancia = (d) => d < 4 ? 'sr.nav.veryClose' : d < 9 ? 'sr.nav.close' : 'sr.nav.far';
213
+ const distanceKey = (d) => d < 4 ? 'sr.nav.veryClose' : d < 9 ? 'sr.nav.close' : 'sr.nav.far';
223
214
  function sonar(pl) {
224
215
  _sonarCount++;
225
216
  const pc = playerCtx(pl);
226
- const alvo = alvoMaisProximo(pl);
227
- // A chave era `sr.nav.noCoinNear` — "Nenhuma moeda por perto." Um sonar que não sabe mais o que é o alvo
228
- // não pode dizer o nome dele no caso em que NÃO HÁ alvo nenhum: virou "Nada por perto.", que é verdade em
229
- // qualquer gênero. Foi o gate de fixtures que cobrou, ao acusar a palavra dentro do teste novo.
230
- if (!alvo) {
217
+ const target = nearestSpot(pl);
218
+ // A sonar that no longer knows what the target is cannot name it when there is NO target at all: it says "nothing
219
+ // nearby", which is true in any genre.
220
+ if (!target) {
231
221
  ctx.tonePan(300, 0.2, 'sonar', 0, 0.2, 'sine', pc);
232
222
  ctx.srSay(t('sr.nav.noTargetNear'));
233
223
  return;
234
224
  }
235
- const pan = panFor(alvo.at.x, pl), near = Math.max(0, 1 - alvo.d / 12);
236
- ctx.tonePan(380 + 740 * near, 0.16, 'sonar', pan, 0.26, 'sine', pc); // mais perto = mais agudo
237
- // O NOME vem do jogo (campo 3). Antes era `t('sr.nav.coin')` — a engine dizia "moeda" porque só conhecia
238
- // moedas. O fallback existe para o jogo que declara alvo sem nome: melhor "alvo" do que uma chave crua.
239
- const nome = ctx.nameAt(alvo.at);
240
- const corpo = t('sr.nav.sonarFound', {
241
- alvo: nome ? nome.text : t('sr.nav.target'),
242
- lado: emPalavras(bearing(ctx.topology(), { x: pl.x, y: pl.y }, alvo.at)),
243
- dist: t(chaveDeDistancia(alvo.d)),
225
+ const pan = panFor(target.at.x, pl), near = Math.max(0, 1 - target.d / 12);
226
+ ctx.tonePan(380 + 740 * near, 0.16, 'sonar', pan, 0.26, 'sine', pc); // nearer = higher
227
+ // The NAME comes from the game (field 3); the engine used to say "coin" because it only knew coins. The fallback is
228
+ // for a game that declares a target without a name: "target" is better than a raw key.
229
+ const name = ctx.nameAt(target.at);
230
+ const foundSentence = t('sr.nav.sonarFound', {
231
+ alvo: name ? name.text : t('sr.nav.target'),
232
+ lado: inWords(bearing(ctx.topology(), { x: pl.x, y: pl.y }, target.at)),
233
+ dist: t(distanceKey(target.d)),
244
234
  });
245
- const msg = (ctx.getNumPlayers() > 1 ? t('sr.player.prefix', { n: pl.i + 1 }) : '') + corpo;
235
+ const msg = (ctx.getNumPlayers() > 1 ? t('sr.player.prefix', { n: pl.i + 1 }) : '') + foundSentence;
246
236
  ctx.srSay(msg);
247
237
  ctx.narrate(msg);
248
238
  }
249
239
  /**
250
- * QUANTOS PASSOS FALTAM, e a resposta preferida é a que contorna parede.
240
+ * HOW MANY STEPS REMAIN, and the preferred answer is the one that goes round walls.
251
241
  *
252
- * ⚠️ AS DUAS RESPOSTAS JÁ ESTÃO NA MESMA UNIDADE, e é a única razão pela qual esta função é uma linha em vez
253
- * de uma conversão: `rotaAte().passos` conta passos por definição, e `distance()` também devolve passos em
254
- * TODA topologia — ela própria divide pela `unit` no ramo contínuo. Dividir aqui outra vez pelo passo do
255
- * mundo era o erro à espera de ser cometido, e num jogo com `unit = 16` ele poria o guia no brilho máximo
256
- * para sempre. É o mesmo defeito que a #121 tirou do `panFor`: misturar régua de mundo com régua de ecrã.
242
+ * ⚠️ BOTH ANSWERS ARE ALREADY IN THE SAME UNIT, which is the only reason this is a line and not a conversion: the route
243
+ * counts steps by definition, and `distance()` returns steps in EVERY topology — it divides by the `unit` itself in the
244
+ * continuous branch. Dividing again by the world step here was the mistake waiting to be made, and in a game with
245
+ * `unit = 16` it would put the guide at full brightness forever — the defect #121 took out of `panFor`: mixing a world
246
+ * ruler with a screen ruler.
257
247
  *
258
- * A rota perde-se de duas maneiras — jogo que não injectou `roleAt`, e orçamento estourado — e as duas caem
259
- * no mesmo recuo: a RETA. ⚠️ Ela mente atrás de parede (diz «perto» de um alvo que exige dar a volta), e é
260
- * por isso que é recuo e não escolha. Mas é o que o guia já dizia antes desta mudança, e continuar a dizê-lo
261
- * é estritamente melhor do que calar — calar afirmaria que não há alvo.
248
+ * The route is lost two ways — a game that did not inject `roleAt`, and a budget run out — and both fall back to the
249
+ * STRAIGHT LINE. ⚠️ It lies behind a wall (says "near" of a target that needs going round), which is why it is a
250
+ * fallback and not a choice. But continuing to say it is strictly better than going quiet — quiet would claim there is
251
+ * no target.
262
252
  */
263
- function passosAteOAlvo(pl, alvo) {
253
+ function stepsToTarget(pl, target) {
264
254
  const roleAt = ctx.roleAt;
265
255
  if (roleAt) {
266
- const rota = rotaAte({ topology: ctx.topology(), roleAt, orcamento: ORCAMENTO_DA_ROTA }, { x: pl.x, y: pl.y }, [alvo.at]);
267
- if (rota)
268
- return rota.passos;
256
+ const path = routeTo({ topology: ctx.topology(), roleAt, budget: ROUTE_BUDGET }, { x: pl.x, y: pl.y }, [target.at]);
257
+ if (path)
258
+ return path.steps;
269
259
  }
270
- return alvo.d;
260
+ return target.d;
271
261
  }
272
- /** Acende o grafo contínuo deste jogador. `null` = não deu (sem contexto, ou motor sem Web Audio). */
273
- function ligarGuia(pl) {
262
+ /** Lights this player's continuous graph. `null` = it could not (no context, or an engine without Web Audio). */
263
+ function startGuide(pl) {
274
264
  const pc = playerCtx(pl);
275
265
  const ac = pc ? pc.ac : ctx.getAudioCtx();
276
266
  if (!ac)
277
267
  return null;
278
268
  try {
279
- const osc = ac.createOscillator(), filtro = ac.createBiquadFilter(), ganho = ac.createGain();
280
- osc.type = GUIA_TIPO;
281
- osc.frequency.value = GUIA_HZ;
282
- filtro.type = 'lowpass';
283
- filtro.frequency.value = CORTE_LONGE; // nasce no fundo da escala e sobe; nascer aberto seria um susto
284
- ganho.gain.value = 0; // e nasce calado, para não estalar ao ligar
285
- let saida = ganho;
269
+ const osc = ac.createOscillator(), lowpass = ac.createBiquadFilter(), level = ac.createGain();
270
+ osc.type = GUIDE_WAVE;
271
+ osc.frequency.value = GUIDE_HZ;
272
+ lowpass.type = 'lowpass';
273
+ lowpass.frequency.value = FAR_CUT; // born at the bottom of the scale and rising; born open would be a fright
274
+ level.gain.value = 0; // and born quiet, so it does not click when it starts
275
+ let migrated = level;
286
276
  let panner = null;
287
277
  if (ac.createStereoPanner) {
288
278
  panner = ac.createStereoPanner();
289
- ganho.connect(panner);
290
- saida = panner;
279
+ level.connect(panner);
280
+ migrated = panner;
291
281
  }
292
- osc.connect(filtro).connect(ganho);
293
- saida.connect(pc ? pc.out : (ctx.catNode?.('guide') || ctx.audioOut?.() || ac.destination));
282
+ osc.connect(lowpass).connect(level);
283
+ migrated.connect(pc ? pc.out : (ctx.catNode?.('guide') || ctx.audioOut?.() || ac.destination));
294
284
  osc.start();
295
- // `desdeARota` nasce no tecto para que a PRIMEIRA volta já meça a rota, em vez de soar doze quadros
296
- // com um `passos` inventado.
297
- return { ac, osc, filtro, ganho, panner, desdeARota: QUADROS_ENTRE_ROTAS, passos: PASSOS_ATE_O_FUNDO, pan: 0 };
285
+ // `framesSinceRoute` is born at the ceiling so the FIRST pass measures the route, instead of sounding for twelve
286
+ // frames on invented steps.
287
+ return { ac, osc, filter: lowpass, gain: level, panner, framesSinceRoute: FRAMES_BETWEEN_ROUTES, steps: STEPS_TO_FLOOR, pan: 0 };
298
288
  }
299
289
  catch (e) {
300
290
  return null;
301
291
  }
302
292
  }
303
293
  /**
304
- * Apaga o grafo — e ele TEM de ser apagado, porque um oscilador que fica é a diferença entre esta forma e a
305
- * anterior. O bipe morria sozinho ao fim de 0,12 s; este toca até alguém o parar. Sem esta função, desligar
306
- * a categoria `guide` no mixer deixaria o som a tocar, e trocar de modo visual deixaria um segundo grafo a
307
- * somar-se ao primeiro.
294
+ * Puts the graph out — and it HAS to be put out, because an oscillator that stays is the difference between this shape
295
+ * and the old one. The beep died by itself; this plays until someone stops it. Without this, turning the `guide`
296
+ * category off in the mixer would leave the sound playing, and changing visual mode would leave a second graph adding
297
+ * to the first.
308
298
  *
309
- * Desce em rampa (não corta) porque um corte seco num oscilador vivo é um clique — um transiente, que é
310
- * precisamente o que este item existe para tirar do ouvido da criança.
299
+ * It ramps down (does not cut) because a dry cut on a live oscillator is a click — a transient, precisely what this item
300
+ * exists to take out of the child's ear.
311
301
  */
312
- function desligarGuia(pl) {
313
- const g = pl._guia;
302
+ function stopGuide(pl) {
303
+ const g = pl._guide;
314
304
  if (!g)
315
305
  return;
316
- pl._guia = null;
306
+ pl._guide = null;
317
307
  try {
318
- const agora = g.ac.currentTime;
319
- g.ganho.gain.setTargetAtTime(0, agora, 0.05);
320
- g.osc.stop(agora + 0.3);
308
+ const audioNow = g.ac.currentTime;
309
+ g.gain.gain.setTargetAtTime(0, audioNow, 0.05);
310
+ g.osc.stop(audioNow + 0.3);
321
311
  }
322
312
  catch (e) { /* noop */ }
323
313
  }
324
314
  /**
325
- * A PRESENÇA CONTÍNUA, um quadro de cada vez (#84 item 2).
315
+ * THE CONTINUOUS PRESENCE, one frame at a time (#84 item 2).
326
316
  *
327
- * ⚠️ O QUE SAIU DAQUI FOI UM BIPE: um `triangle` de 0,12 s a cada 48 quadros, para sempre, independente de a
328
- * criança se mexer ou de algo ter mudado. O veredicto do Dev: «um ping é a pior escolha possível, tenebroso
329
- * para quem tem TEA». O que entra não dispara nada — o som já está lá, e muda de brilho.
317
+ * ⚠️ WHAT LEFT HERE WAS A BEEP, forever, whether or not the child moved or anything changed. The Dev's verdict: «um
318
+ * ping é a pior escolha possível, tenebroso para quem tem TEA». What replaces it fires nothing — the sound is already
319
+ * there, and changes brightness.
330
320
  *
331
- * ⚠️ E CALAR CONTINUA A SER UMA AFIRMAÇÃO, com um significado só: NÃO HÁ ALVO. É por isso que «sem alvo»
332
- * apaga o grafo e «longe» não: o piso do `guide-intensity` (`VOL_LONGE`) existe exactamente para que a
333
- * criança não confunda «está longe» com «não há nada para achar».
321
+ * ⚠️ AND GOING QUIET IS STILL A STATEMENT, with one meaning only: THERE IS NO TARGET. That is why "no target" puts the
322
+ * graph out and "far" does not: `guide-intensity`'s floor (`FAR_VOL`) exists exactly so the child does not confuse "it
323
+ * is far" with "there is nothing to find".
334
324
  */
335
325
  function updateGuide() {
336
- const cat = ctx.getAudioCat();
337
- const ligado = !!ctx.getAudioCtx() && ctx.getSoundOn() && !!cat && !!cat.guide && cat.guide.on;
326
+ const audible = guideAudible();
338
327
  const vol = ctx.getVolume ? ctx.getVolume() : 1;
339
328
  for (const pl of ctx.getPlayers()) {
340
- if (!ligado || !needsAudioCues(pl)) {
341
- desligarGuia(pl);
329
+ if (!audible || !needsAudioCues(pl)) {
330
+ stopGuide(pl);
342
331
  continue;
343
332
  }
344
- let g = pl._guia;
345
- if (!g) {
346
- // ⚠️ A PERGUNTA «HÁ ALVO?» VEM ANTES DE ACENDER, e o gate cobrou-a: com o grafo a nascer primeiro, um
347
- // jogador sem alvo criava um oscilador, media a rota, não achava nada e apagava-o — SESSENTA VEZES
348
- // POR SEGUNDO. O bipe não tinha este problema porque não tinha nada que durasse; foi a permanência
349
- // que o trouxe. `alvoMaisProximo` é um laço sobre `targetsOf`, não a BFS: perguntar por quadro custa
350
- // zero quando a lista está vazia, que é exactamente o caso em questão.
351
- if (!alvoMaisProximo(pl))
352
- continue;
353
- g = pl._guia = ligarGuia(pl);
354
- if (!g)
355
- continue;
356
- }
357
- if (++g.desdeARota >= QUADROS_ENTRE_ROTAS) {
358
- g.desdeARota = 0;
359
- const alvo = alvoMaisProximo(pl);
360
- if (!alvo) {
361
- desligarGuia(pl);
362
- continue;
363
- }
364
- g.passos = passosAteOAlvo(pl, alvo);
365
- g.pan = panFor(alvo.at.x, pl);
366
- }
367
- // TODO quadro, e não só quando a rota é nova: é isto que faz a mudança ser um deslize.
368
- const i = intensidadeDoGuia(g.passos);
369
- try {
370
- const agora = g.ac.currentTime;
371
- g.filtro.frequency.setTargetAtTime(i.corte, agora, TAU_DO_GUIA);
372
- g.ganho.gain.setTargetAtTime(GUIA_VOL * i.volume * vol, agora, TAU_DO_GUIA);
373
- g.panner?.pan.setTargetAtTime(g.pan, agora, TAU_DO_GUIA);
333
+ // no guide lit (no target, or a device that refused it), or the target gone: silence says «nothing to find»
334
+ const g = liveGuide(pl);
335
+ if (!g || !remeasure(pl, g)) {
336
+ stopGuide(pl);
337
+ continue;
374
338
  }
375
- catch (e) { /* noop */ }
339
+ glide(g, vol);
376
340
  _guideCount++;
377
341
  }
378
342
  }
343
+ /** Can the guide be heard at all: the engine's audio started, the game's sound on, and a `guide` category that is on. */
344
+ function guideAudible() {
345
+ const cat = ctx.getAudioCat();
346
+ return !!ctx.getAudioCtx() && ctx.getSoundOn() && !!cat && !!cat.guide && cat.guide.on;
347
+ }
348
+ /** This player's live guide — lit here only if there is a target to point to, and `null` where it cannot be lit. */
349
+ function liveGuide(pl) {
350
+ if (pl._guide)
351
+ return pl._guide;
352
+ // ⚠️ THE QUESTION "IS THERE A TARGET?" COMES BEFORE LIGHTING, and the gate insisted: with the graph born first, a
353
+ // player with no target created an oscillator, measured the route, found nothing and put it out — SIXTY TIMES A
354
+ // SECOND. The beep did not have this problem because nothing of it lasted; permanence brought it. `nearestSpot` is a
355
+ // loop over `targetsOf`, not the BFS: asking every frame costs nothing when the list is empty, which is the case here.
356
+ if (!nearestSpot(pl))
357
+ return null;
358
+ return (pl._guide = startGuide(pl));
359
+ }
360
+ /**
361
+ * Every FRAMES_BETWEEN_ROUTES frames the route and the side are measured again — the BFS on a cadence, not sixty times a
362
+ * second. Answers `false` when the target is gone.
363
+ */
364
+ function remeasure(pl, g) {
365
+ if (++g.framesSinceRoute < FRAMES_BETWEEN_ROUTES)
366
+ return true;
367
+ g.framesSinceRoute = 0;
368
+ const target = nearestSpot(pl);
369
+ if (!target)
370
+ return false;
371
+ g.steps = stepsToTarget(pl, target);
372
+ g.pan = panFor(target.at.x, pl);
373
+ return true;
374
+ }
375
+ /** EVERY frame, not only when the route is new: this is what makes the change a glide. */
376
+ function glide(g, vol) {
377
+ const i = guideIntensity(g.steps);
378
+ try {
379
+ const audioNow = g.ac.currentTime;
380
+ g.filter.frequency.setTargetAtTime(i.cutoff, audioNow, GUIDE_TAU);
381
+ g.gain.gain.setTargetAtTime(GUIDE_VOL * i.volume * vol, audioNow, GUIDE_TAU);
382
+ g.panner?.pan.setTargetAtTime(g.pan, audioNow, GUIDE_TAU);
383
+ }
384
+ catch (e) { /* noop */ }
385
+ }
379
386
  return {
380
387
  playerCtx, panFor, needsAudioCues, sonar, updateGuide,
381
388
  get sonarCount() { return _sonarCount; },