@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
@@ -0,0 +1,169 @@
1
+ // SPDX-License-Identifier: AGPL-3.0-or-later
2
+ // platform/heavy.ts — THE HEAVY THINGS, DOWNLOADED ON FIRST LOAD (ADR-0110, ADR-0116, ADR-0119).
3
+ //
4
+ // ========================= WHAT THIS IS =========================
5
+ // Pillar 8 says "PWA ONLINE on the first day, then OFFLINE-FIRST", and ADR-0116 removed the contradiction that blocked
6
+ // this: installing is already a network act, so fetching at install violates nothing. What was missing was someone
7
+ // fetching.
8
+ //
9
+ // ⚠️ AND IT DOES NOT BLOCK THE GAME. The child plays while the heavy files come down; what must not happen is them
10
+ // reaching the second day, offline, and finding the voice was never fetched.
11
+ //
12
+ // ========================= THE THREE RULES THE SHAPE IMPOSES =========================
13
+ // 1. **ONE AT A TIME.** Four 60 MB downloads in parallel on a school link fight for the same bandwidth and none
14
+ // finishes first — and the game, which needs the network for its own images, waits behind them.
15
+ // 2. **NEVER THROWS.** A network failure is REPORTED and the list goes on. A `throw` here would bring down a game's
16
+ // start over a resource it may not even use today.
17
+ // 3. **IDEMPOTENT.** What is already in Cache Storage is not fetched again — which is what makes this safe to call on
18
+ // every start instead of only "on the first", which nobody can detect honestly.
19
+ import { CACHE_HEAVY, HEAVY_FILES, readingLanguageOf, commandsLanguageOf } from './heavy-catalogue.js';
20
+ export { CACHE_HEAVY, HEAVY_FILES };
21
+ /**
22
+ * WHAT A GAME'S START FETCHES (ADR-0216 §3): the catalogue, less what this game did not ask for.
23
+ *
24
+ * · The neural voice — its model, its voices AND the runtime that speaks them: without that answer they are 372 MB taken from a
25
+ * school's link and a child's device for nothing.
26
+ * · The reading models: 850 MiB for the three languages, so `reading` is not a yes or no but a LANGUAGE — the child's, known at
27
+ * boot. A delivery may carry more than one; a device downloads the one being read in. A game that never listens gets none.
28
+ * · 🔴 THE GRAPH RUNTIME IS NOT THE VOICE'S, and its `voz:` name said otherwise. `platform/onnx-runtime` runs Kokoro AND the
29
+ * reading models, so a game that only LISTENS needs it: without this line its delivery carried a 378 MiB model and nothing
30
+ * able to open it, and the first `listen()` asked for a file the build never wrote. Measured on 2026-09-21, building the
31
+ * very delivery this exists to serve. The PHONEMIZER (`voz:runtime:fonemas`, 18.7 MiB) stays the voice's — nothing else
32
+ * turns letters into sounds.
33
+ * · The command models (issue #184): one per language too, 112 MiB for the three, and the runtime that loads them. Nothing in
34
+ * the game decides this — speaking instead of pressing is a way INTO the controller, and a cartridge does not get to close
35
+ * one (ADR-0111). What decides is the delivery: `inclusionist-heavy --commands pt` puts Portuguese in it.
36
+ */
37
+ export function heavyAtBoot(declared) {
38
+ const reading = declared.reading ? declared.reading.split('-')[0].toLowerCase() : null;
39
+ const commands = declared.commands ? declared.commands.split('-')[0].toLowerCase() : null;
40
+ return HEAVY_FILES.filter((p) => {
41
+ const language = readingLanguageOf(p.id);
42
+ if (language)
43
+ return language === reading;
44
+ // 📌 THE COMMAND MODELS ARE A TRANSPORT'S, not a game's: no cartridge declares them, because a child who speaks instead of
45
+ // pressing is reaching the controller, and a cartridge does not get to deny her a way in (ADR-0111). The LANGUAGE is still
46
+ // asked — 112 MiB for the three — and the runtime comes with whichever one does.
47
+ const commanded = commandsLanguageOf(p.id);
48
+ if (commanded)
49
+ return commanded === commands;
50
+ if (p.id.startsWith('commands:runtime'))
51
+ return !!commands;
52
+ if (p.id.startsWith('voz:runtime:onnx'))
53
+ return declared.kokoro || !!reading;
54
+ return declared.kokoro || !(p.id.startsWith('voz:kokoro:') || p.id.startsWith('voz:runtime:'));
55
+ }).map((p) => p.id);
56
+ }
57
+ /**
58
+ * WHERE THE DELIVERY SERVES A HEAVY FILE (ADR-0177, issue #173): `heavy/<host><path>` beside the page. The child's device
59
+ * reads it from the game's own origin; the upstream address is only where the build fetched it from.
60
+ * 📌 The upstream address stays the CACHE KEY: it is what the voice and vision libraries ask for, and the service worker answers
61
+ * them from the checked cache without a network request.
62
+ *
63
+ * 🔴 THE FOLDER WAS CALLED «pesados» UNTIL 2026-09-21 (ADR-0219). 📏 What that costs a school was measured before it changed:
64
+ * the entries are kept under the UPSTREAM address, so nothing is re-downloaded — what breaks is a delivery built by the old
65
+ * `bin` under a new engine, which asks for `heavy/…` and gets a 404 until the delivery is built again.
66
+ */
67
+ export function deliveryPath(url) {
68
+ const u = new URL(url);
69
+ return `heavy/${u.host}${u.pathname}`;
70
+ }
71
+ /**
72
+ * The inverse, for the service worker: a request for `…/heavy/<host><path>` is answered from the entry kept under
73
+ * `https://<host><path>`; any other address has no key (`null`). It is the route's `cacheKeyWillBeUsed` itself, so it also
74
+ * takes Workbox's `{ request }`. Self-contained on purpose — the PWA plugin copies this function's SOURCE into `sw.js`, where
75
+ * nothing else from this module exists.
76
+ *
77
+ * ⚠️ THE OFFSET COMES FROM THE FOLDER'S OWN LENGTH, and it is written this way because of what a blind rename would have done
78
+ * here: the old code advanced by 9, the length of the old folder's name with its slashes, and `/heavy/` is 7 — a text
79
+ * replacement of the name alone would
80
+ * have left every cache key with two characters of the host eaten, and the only symptom would be a cache that never hits.
81
+ */
82
+ export function deliveryCacheKey(urlOrRequest) {
83
+ const folder = '/heavy/';
84
+ const urlPath = new URL(typeof urlOrRequest === 'string' ? urlOrRequest : urlOrRequest.request.url).pathname;
85
+ const i = urlPath.indexOf(folder);
86
+ return i < 0 ? null : 'https://' + urlPath.slice(i + folder.length);
87
+ }
88
+ /**
89
+ * DOWNLOADS WHAT IS MISSING, ONE AT A TIME, AND RETURNS WHAT HAPPENED TO EACH.
90
+ *
91
+ * ⚠️ ENTRIES WITHOUT A `url` ARE NOT SKIPPED IN SILENCE — they return `sem-fonte`. It is the difference between "this
92
+ * subsystem has nowhere to come from yet" and "this subsystem is handled", exactly the distinction ADR-0119 measured as
93
+ * missing: the engine PROMISED four things and delivered one, with nothing saying so.
94
+ */
95
+ export async function downloadHeavy(options) {
96
+ const targets = options.only ? HEAVY_FILES.filter((p) => options.only.includes(p.id)) : HEAVY_FILES;
97
+ const out = [];
98
+ const record = (r) => { out.push(r); options.onProgress?.(r); };
99
+ const { cacheStorage, fetch: fetchFile, digest, base } = options;
100
+ if (!cacheStorage || !fetchFile) {
101
+ for (const p of targets)
102
+ record({ id: p.id, outcome: 'falhou', error: 'sem Cache Storage ou sem fetch' });
103
+ return out;
104
+ }
105
+ const tools = { cache: await cacheStorage.open(CACHE_HEAVY), fetchFile, digest, base };
106
+ for (const p of targets)
107
+ record(await fetchOne(p, tools));
108
+ return out;
109
+ }
110
+ /** One file's fate: already kept, fetched from the delivery and checked, or refused — always with the reason. */
111
+ async function fetchOne(p, t) {
112
+ if (!p.url)
113
+ return { id: p.id, outcome: 'sem-fonte', error: p.whyNoSource };
114
+ try {
115
+ if (await t.cache.match(p.url))
116
+ return { id: p.id, outcome: 'ja-tinha' };
117
+ // from the delivery's own origin, never from the upstream host (ADR-0177)
118
+ const resp = await t.fetchFile(new URL(deliveryPath(p.url), t.base).href);
119
+ if (!resp.ok)
120
+ return { id: p.id, outcome: 'falhou', error: `HTTP ${resp.status}` };
121
+ return await keepIfChecked(p, p.url, resp, t);
122
+ }
123
+ catch (e) {
124
+ return { id: p.id, outcome: 'falhou', error: e instanceof Error ? e.message : String(e) };
125
+ }
126
+ }
127
+ /**
128
+ * CHECKED BEFORE KEPT (issue #168; STRIDE client pass). What is kept runs in the child's page and is served offline from then
129
+ * on, so a body whose SHA-256 is not the measured one never enters the cache. It is kept under the UPSTREAM address, which is
130
+ * what the voice and vision libraries ask for.
131
+ */
132
+ async function keepIfChecked(p, url, resp, t) {
133
+ const refused = (reason) => ({ id: p.id, outcome: 'falhou', error: reason });
134
+ if (!p.sha256)
135
+ return refused('this entry pins its sha256 nowhere: there is nothing to check it against');
136
+ if (!t.digest)
137
+ return refused('this host cannot compute a sha256 (crypto.subtle needs a secure context)');
138
+ const body = await resp.arrayBuffer();
139
+ const got = await t.digest(body);
140
+ if (got !== p.sha256)
141
+ return refused(`sha256 mismatch: expected ${p.sha256}, got ${got} — not kept`);
142
+ await t.cache.put(url, new Response(body, { status: resp.status, statusText: resp.statusText, headers: resp.headers }));
143
+ return { id: p.id, outcome: 'baixado', bytes: p.bytes };
144
+ }
145
+ /**
146
+ * THE SHA-256 OF A BODY AS LOWERCASE HEX, by the `crypto.subtle` it is handed (issue #168) — or `null` when there is none,
147
+ * which is a host outside a secure context: the answer `HeavyOptions.digest` reads as «cannot hash, so keep nothing».
148
+ */
149
+ export function sha256With(subtle) {
150
+ if (!subtle)
151
+ return null;
152
+ return async (payload) => {
153
+ const bytes = new Uint8Array(await subtle.digest('SHA-256', payload));
154
+ return [...bytes].map((x) => x.toString(16).padStart(2, '0')).join('');
155
+ };
156
+ }
157
+ /**
158
+ * WHETHER A CATALOGUE FILE IS IN THE CHECKED CACHE, by its upstream address — what `platform/vision` and
159
+ * `platform/vosk-runtime` ask before loading anything. The host's `caches` is handed in; `undefined` (an insecure context)
160
+ * holds nothing, so every file is missing and the loader names them.
161
+ */
162
+ export function checkedCacheHas(cacheStorage) {
163
+ return async (url) => !!cacheStorage && !!(await (await cacheStorage.open(CACHE_HEAVY)).match(url));
164
+ }
165
+ /** The size of what is still missing, in bytes — so a notice can say how much is left before it starts. */
166
+ export function bytesLeftToDownload(soFar) {
167
+ const feitos = new Set(soFar.filter((r) => r.outcome === 'ja-tinha' || r.outcome === 'baixado').map((r) => r.id));
168
+ return HEAVY_FILES.filter((p) => p.url && !feitos.has(p.id)).reduce((s, p) => s + (p.bytes ?? 0), 0);
169
+ }
@@ -1,19 +1,19 @@
1
1
  // SPDX-License-Identifier: AGPL-3.0-or-later
2
- /** O que o chamador precisa fornecer. Nada aqui conhece PIPER, Web Audio ou o navegador. */
3
- export interface MotorDeFala<Audio, Fonte> {
4
- /** Texto → áudio. ASSÍNCRONO de propósito: é onde a síntese neural gasta o tempo dela. */
5
- sintetizar(texto: string): Promise<Audio>;
6
- /** Começa a tocar e devolve a fonte, para que ela possa ser parada. `null` = não deu para tocar agora. */
7
- tocar(audio: Audio, aoTerminar: () => void): Fonte | null;
8
- /** Cala a fonte. Chamado com o que `tocar` devolveu, e nunca com `null`. */
9
- parar(fonte: Fonte): void;
2
+ /** What the caller provides. Nothing here knows the neural engine, Web Audio or the browser. */
3
+ export interface SpeechEngine<Audio, Fonte> {
4
+ /** Text → audio. ASYNCHRONOUS on purpose: it is where neural synthesis spends its time. */
5
+ synthesize(text: string): Promise<Audio>;
6
+ /** Starts playing and returns the source, so it can be stopped. `null` = it could not play right now. */
7
+ play(audio: Audio, onEnded: () => void): Fonte | null;
8
+ /** Silences the source. Called with what `play` returned, and never with `null`. */
9
+ stop(playing: Fonte): void;
10
10
  }
11
- export interface FalaInterrompivel {
12
- /** Fala `texto`, CALANDO na hora o que estiver falando. Não enfileira: o último pedido é o que vale. */
13
- falar(texto: string): void;
14
- /** Cala e esquece. Usado ao fechar um menu ou ao desligar a narração. */
15
- calar(): void;
16
- /** Está tocando alguma coisa? Só para teste e depuração — a política não depende disto. */
17
- falando(): boolean;
11
+ export interface InterruptibleSpeech {
12
+ /** Speaks `text`, SILENCING at once whatever is speaking. It does not queue: the latest request is the one that counts. */
13
+ speak(text: string): void;
14
+ /** Silences and forgets. Used when a menu closes or narration is switched off. */
15
+ silence(): void;
16
+ /** Is anything playing? For tests and debugging only — the policy does not depend on it. */
17
+ speaking(): boolean;
18
18
  }
19
- export declare function criarFalaInterrompivel<Audio, Fonte>(motor: MotorDeFala<Audio, Fonte>): FalaInterrompivel;
19
+ export declare function createInterruptibleSpeech<Audio, Fonte>(engine: SpeechEngine<Audio, Fonte>): InterruptibleSpeech;
@@ -1,79 +1,78 @@
1
1
  // SPDX-License-Identifier: AGPL-3.0-or-later
2
- // platform/interruptible-speech — FALAR O ÚLTIMO PEDIDO, E CALAR O ANTERIOR NA HORA (ADR-0044, item 2).
2
+ // platform/interruptible-speech — SPEAK THE LATEST REQUEST, AND SILENCE THE PREVIOUS ONE AT ONCE (ADR-0044, item 2).
3
3
  //
4
- // ========================= O DEFEITO QUE ISTO SUBSTITUI =========================
5
- // O motor neural falava assim:
4
+ // ========================= THE DEFECT THIS REPLACES =========================
5
+ // The neural engine used to speak like this:
6
6
  //
7
- // speak: (text) => { if (busy) next = text; else speakNow(text); } // fila de 1
7
+ // speak: (text) => { if (busy) next = text; else speakNow(text); } // a queue of 1
8
8
  //
9
- // Uma FILA, e de tamanho um. Varrendo cinco itens de menu, a criança ouvia o PRIMEIRO inteiro e depois o
10
- // ÚLTIMO — os três do meio sumiam em silêncio, porque cada novo pedido sobrescrevia o `next`. É lento E
11
- // perde informação, e as duas coisas doem no mesmo lugar: a pessoa que não enxerga navega POR ESCUTA, e a
12
- // escuta estava vários itens atrás do foco.
9
+ // A QUEUE, of size one. Sweeping five menu items, the child heard the FIRST one whole and then the LAST — the three in
10
+ // between vanished in silence, because each new request overwrote `next`. It is slow AND it loses information, and both
11
+ // hurt in the same place: a person who cannot see navigates BY EAR, and the ear was several items behind the focus.
13
12
  //
14
- // A XAG 106 diz o que fazer, e diz por quê: se a narração do item em foco ainda está sendo lida e o foco
15
- // muda, "a narração do elemento original deve PARAR IMEDIATAMENTE, e a do novo elemento começar".
13
+ // XAG 106 says what to do, and why: if the focused item's narration is still being read when the focus moves, the
14
+ // original element's narration stops IMMEDIATELY and the new element's begins.
16
15
  //
17
- // ========================= AS DUAS COISAS QUE ISTO GARANTE =========================
16
+ // ========================= THE TWO THINGS THIS GUARANTEES =========================
18
17
  //
19
- // 1. CALA ANTES DE SINTETIZAR, não depois. Síntese neural leva tempo; parar só quando o áudio novo fica
20
- // pronto deixaria a voz velha falando durante a espera — o item errado, com convicção. Silêncio é a
21
- // resposta certa: a criança sabe que se moveu, e o silêncio confirma.
18
+ // 1. SILENCE BEFORE SYNTHESISING, not after. Neural synthesis takes time; stopping only once the new audio is ready would
19
+ // leave the old voice speaking during the wait — the wrong item, with conviction. Silence is the right answer: the
20
+ // child knows they moved, and the silence confirms it.
22
21
  //
23
- // 2. GERAÇÃO, e é o que impede a corrida. `sintetizar` é assíncrono, e dois pedidos podem terminar fora
24
- // de ordem: o segundo fica pronto primeiro, começa a tocar, e o primeiro chega depois e o atropela —
25
- // a criança ouviria o item que ela JÁ passou, por cima do atual. Cada pedido carrega o seu número; o
26
- // que voltar com número velho é descartado, em cada um dos dois `await`.
22
+ // 2. A GENERATION, which is what prevents the race. `synthesize` is asynchronous, and two requests can finish out of
23
+ // order: the second is ready first and starts playing, then the first arrives and runs it over — the child would
24
+ // hear the item they ALREADY passed, on top of the current one. Each request carries its number; whatever comes back
25
+ // with an old number is dropped, at each of the two `await`s.
27
26
  //
28
- // ========================= POR QUE É UM MÓDULO, E NÃO UMA LINHA NO `tts` =========================
29
- // Porque assim se pode PROVAR. O bloco neural vive dentro de um `import()` dinâmico que só resolve com o
30
- // runtime de 25,6 MB presente; testá-lo lá dentro exigiria o motor de verdade. Aqui a política é pura —
31
- // recebe "como sintetizar", "como tocar" e "como parar" — e o teste de node exercita a corrida e a
32
- // interrupção com falsos, em milissegundos.
33
- export function criarFalaInterrompivel(motor) {
34
- let tocando = null;
35
- let geracao = 0;
36
- /** Cala o que estiver tocando. O `try` existe porque parar uma fonte já terminada lança em alguns motores. */
37
- function pararTudo() {
38
- if (tocando !== null) {
27
+ // ========================= WHY A MODULE, AND NOT A LINE IN `tts` =========================
28
+ // Because this way it can be PROVEN. The neural block lives inside a dynamic `import()` that only resolves with the
29
+ // runtime present; testing it there would need the real engine. Here the policy is pure — it receives "how to
30
+ // synthesise", "how to play" and "how to stop" — and the node test exercises the race and the interruption with fakes,
31
+ // in milliseconds.
32
+ export function createInterruptibleSpeech(engine) {
33
+ let nowPlaying = null;
34
+ let currentTurn = 0;
35
+ /** Silences whatever is playing. The `try` exists because stopping an already finished source throws in some engines. */
36
+ function stopPlayback() {
37
+ if (nowPlaying !== null) {
39
38
  try {
40
- motor.parar(tocando);
39
+ engine.stop(nowPlaying);
41
40
  }
42
- catch (e) { /* fonte já encerrada — parar de novo não é erro */ }
43
- tocando = null;
41
+ catch (e) { /* the source already ended — stopping again is no error */ }
42
+ nowPlaying = null;
44
43
  }
45
44
  }
46
- async function falar(texto) {
47
- const minha = ++geracao; // reivindica a vez ANTES de qualquer espera
48
- pararTudo(); // garantia 1: silêncio imediato, não ao fim da síntese
49
- if (!texto)
45
+ async function speakNow(text) {
46
+ const myTurn = ++currentTurn; // claims the turn BEFORE any wait
47
+ stopPlayback(); // guarantee 1: immediate silence, not at the end of synthesis
48
+ if (!text)
50
49
  return;
51
50
  try {
52
- const audio = await motor.sintetizar(texto);
53
- if (minha !== geracao)
54
- return; // garantia 2: chegou tarde — outro pedido já assumiu
55
- pararTudo(); // de novo: alguém pode ter começado a tocar durante a espera
56
- const fonte = motor.tocar(audio, () => { if (tocando === fonte)
57
- tocando = null; });
58
- if (minha !== geracao) {
59
- if (fonte !== null) {
51
+ const audio = await engine.synthesize(text);
52
+ if (myTurn !== currentTurn)
53
+ return; // guarantee 2: it arrived late — another request already took over
54
+ stopPlayback(); // again: something may have started playing during the wait
55
+ const playing = engine.play(audio, () => { if (nowPlaying === playing)
56
+ nowPlaying = null; });
57
+ if (myTurn !== currentTurn) {
58
+ if (playing !== null) {
60
59
  try {
61
- motor.parar(fonte);
60
+ engine.stop(playing);
62
61
  }
63
62
  catch (e) { /* noop */ }
64
63
  }
65
64
  return;
66
65
  }
67
- tocando = fonte;
66
+ nowPlaying = playing;
68
67
  }
69
68
  catch (e) {
70
- // Síntese falhou para ESTE texto. Não é motivo para derrubar a narração inteira: o próximo pedido
71
- // tenta de novo, e o silêncio de um item é melhor que um motor morto.
69
+ // Synthesis failed for THIS text. No reason to bring the whole narration down: the next request tries again, and one
70
+ // silent item is better than a dead engine.
72
71
  }
73
72
  }
74
73
  return {
75
- falar: (texto) => { void falar(texto); },
76
- calar: () => { geracao++; pararTudo(); }, // o `++` invalida o que estiver sintetizando agora
77
- falando: () => tocando !== null,
74
+ speak: (text) => { void speakNow(text); },
75
+ silence: () => { currentTurn++; stopPlayback(); }, // the `++` invalidates whatever is being synthesised now
76
+ speaking: () => nowPlaying !== null,
78
77
  };
79
78
  }
@@ -0,0 +1,27 @@
1
+ // SPDX-License-Identifier: AGPL-3.0-or-later
2
+ import type { KokoroModule } from './kokoro.js';
3
+ import type { OnnxRuntime } from './onnx-runtime.js';
4
+ /** The file system espeak-ng's Emscripten module exposes — only what this uses. */
5
+ export interface EspeakFileSystem {
6
+ readonly writeFile: (path: string, text: string) => void;
7
+ readonly readFile: (path: string, options: {
8
+ encoding: 'utf8';
9
+ }) => string;
10
+ }
11
+ /** espeak-ng's module factory: one program run per call, with its arguments and the hooks run before `main`. */
12
+ export type EspeakFactory = (options: {
13
+ readonly arguments: readonly string[];
14
+ readonly preRun: readonly ((m: {
15
+ FS: EspeakFileSystem;
16
+ }) => void)[];
17
+ }) => Promise<{
18
+ FS: EspeakFileSystem;
19
+ }>;
20
+ export interface KokoroPortDeps {
21
+ readonly espeak: EspeakFactory;
22
+ readonly ort: OnnxRuntime;
23
+ readonly fetch: (url: string) => Promise<Response>;
24
+ /** The page's address `heavy/` is resolved against. */
25
+ readonly base: string;
26
+ }
27
+ export declare function createKokoroPort(d: KokoroPortDeps): KokoroModule;
@@ -0,0 +1,50 @@
1
+ // SPDX-License-Identifier: AGPL-3.0-or-later
2
+ import { KOKORO_MODEL_URL, URL_DO_TOKENIZADOR_KOKORO, kokoroVoiceUrl } from './kokoro.js';
3
+ import { deliveryPath } from './heavy.js';
4
+ const INPUT = 'entrada.txt';
5
+ const OUTPUT = 'fonemas.txt';
6
+ export function createKokoroPort(d) {
7
+ const fromDelivery = async (url) => {
8
+ const path = deliveryPath(url);
9
+ const r = await d.fetch(new URL(path, d.base).href);
10
+ if (!r.ok)
11
+ throw new Error(`Kokoro: HTTP ${r.status} for ${path} — the delivery does not carry it (inclusionist-heavy --kokoro)`);
12
+ return r;
13
+ };
14
+ let vocabulary = null;
15
+ // ⚠️ ONE COPY of the 325 MB model for every session: the engine tries WebGPU and may fall back to WASM
16
+ let model = null;
17
+ return {
18
+ async phonemize(text, espeak) {
19
+ // the sentence goes in as a FILE and never as an argument: a line starting with «-» would be read as an option
20
+ const e = await d.espeak({
21
+ arguments: ['-q', '--ipa', '--phonout', OUTPUT, '-v', espeak, '-f', INPUT],
22
+ preRun: [(m) => m.FS.writeFile(INPUT, text.replace(/\s+/g, ' '))],
23
+ });
24
+ return e.FS.readFile(OUTPUT, { encoding: 'utf8' }).trim().replace(/\s*\n\s*/g, ' ');
25
+ },
26
+ vocabulary() {
27
+ vocabulary ??= fromDelivery(URL_DO_TOKENIZADOR_KOKORO)
28
+ .then(async (r) => (await r.json()).model.vocab);
29
+ return vocabulary;
30
+ },
31
+ async voice(id) {
32
+ return new Float32Array(await (await fromDelivery(kokoroVoiceUrl(id))).arrayBuffer());
33
+ },
34
+ async session(device) {
35
+ model ??= fromDelivery(KOKORO_MODEL_URL).then(async (r) => new Uint8Array(await r.arrayBuffer()));
36
+ const s = await d.ort.InferenceSession.create(await model, { executionProviders: [device] });
37
+ const session = {
38
+ async synthesize(ids, style) {
39
+ const out = await s.run({
40
+ input_ids: new d.ort.Tensor('int64', BigInt64Array.from(ids, (id) => BigInt(id)), [1, ids.length]),
41
+ style: new d.ort.Tensor('float32', style, [1, style.length]),
42
+ speed: new d.ort.Tensor('float32', Float32Array.of(1), [1]), // the pace is the engine's, on playback (ADR-0196)
43
+ });
44
+ return out[s.outputNames[0]].data;
45
+ },
46
+ };
47
+ return session;
48
+ },
49
+ };
50
+ }
@@ -0,0 +1,20 @@
1
+ // SPDX-License-Identifier: AGPL-3.0-or-later
2
+ import type { KokoroModule } from './kokoro.js';
3
+ export interface KokoroRuntimeDeps {
4
+ /** The page's address, which `heavy/` is resolved against. */
5
+ readonly base: string;
6
+ /**
7
+ * The host's `fetch`, and the host's `WebAssembly.compile` and `instantiate` below: REQUIRED (ADR-0232 D4). The root lends
8
+ * them from `host.win`; a default would be the page's globals reached from `platform/`, and a case answers without a network.
9
+ */
10
+ readonly fetch: (url: string) => Promise<Response>;
11
+ /** `import()`, injected so a case can hand in the two modules without a network. Optional: `import()` is not a global. */
12
+ readonly importModule?: (url: string) => Promise<unknown>;
13
+ readonly compileWasm: (bytes: ArrayBuffer) => Promise<WebAssembly.Module>;
14
+ readonly instantiateWasm: (module: WebAssembly.Module, imports: WebAssembly.Imports) => Promise<WebAssembly.Instance>;
15
+ }
16
+ /**
17
+ * Builds the neural voice. Everything it needs is fetched from the delivery, so a device that never had a network day has it all
18
+ * or has none of it — and «none of it» is a refusal the caller reports, not a silence.
19
+ */
20
+ export declare function loadKokoroRuntime(d: KokoroRuntimeDeps): Promise<KokoroModule>;
@@ -0,0 +1,52 @@
1
+ // SPDX-License-Identifier: AGPL-3.0-or-later
2
+ // platform/kokoro-runtime — THE ENGINE LOADS THE NEURAL VOICE ITSELF (ADR-0216 and its erratum; issue #200).
3
+ //
4
+ // The Dev, 2026-09-21: «a engine deve oferecer objetos de leitura e TTS. O jogo não deve precisar saber como isso funciona». So the
5
+ // phonemizer and the ONNX runtime are no longer a game's dependency: they are catalogued heavy files (`voz:runtime:*`), the build
6
+ // puts them in the delivery, and this loads them from `heavy/` on the page's own origin — the same path the vision runtime
7
+ // already takes (ADR-0177, `platform/vision`).
8
+ //
9
+ // ⚠️ NOTHING HERE IS IMPORTED FROM npm, and that is the point: an `import 'espeak-ng'` would put the phonemizer in the bundle of
10
+ // every game that merely links the engine, and would need a bundler to resolve it. `import(url)` of an address on our own origin
11
+ // needs neither, and it happens only when a child picks a neural voice.
12
+ //
13
+ // · The wasm of espeak-ng is compiled ONCE and instantiated per sentence: its module runs one program and exits.
14
+ // · onnxruntime's threads load their own glue and wasm; they are pointed at `heavy/` too, because a worker that goes looking for
15
+ // them on a CDN finds nothing in a school with no network, and the child hears silence (measured in the quiz demo, #181).
16
+ import { createKokoroPort } from './kokoro-port.js';
17
+ import { atDelivery, loadOnnxRuntime } from './onnx-runtime.js';
18
+ // The addresses are the catalogue's, reached by id through `platform/onnx-runtime` — never written twice (ADR-0114, ADR-0177).
19
+ const ESPEAK_GLUE = 'voz:runtime:fonemas';
20
+ const ESPEAK_WASM = 'voz:runtime:fonemas:wasm';
21
+ /**
22
+ * Builds the neural voice. Everything it needs is fetched from the delivery, so a device that never had a network day has it all
23
+ * or has none of it — and «none of it» is a refusal the caller reports, not a silence.
24
+ */
25
+ export async function loadKokoroRuntime(d) {
26
+ const { compileWasm: compile, instantiateWasm: instantiate, fetch: get } = d;
27
+ const loadModule = d.importModule ?? ((url) => import(/* @vite-ignore */ url));
28
+ const espeakModule = await loadModule(atDelivery(ESPEAK_GLUE, d.base));
29
+ const factory = (typeof espeakModule === 'function' ? espeakModule : espeakModule.default);
30
+ if (typeof factory !== 'function')
31
+ throw new Error('Kokoro: espeak-ng did not load from the delivery (voz:runtime:fonemas)');
32
+ // by BYTES and not by stream: a server that sends the file without `application/wasm` must not break the voice
33
+ let compiled = null;
34
+ const espeak = (options) => {
35
+ compiled ??= get(atDelivery(ESPEAK_WASM, d.base)).then(async (r) => {
36
+ if (!r.ok)
37
+ throw new Error(`Kokoro: HTTP ${r.status} for espeak-ng's wasm — the delivery does not carry it`);
38
+ return compile(await r.arrayBuffer());
39
+ });
40
+ const module = compiled;
41
+ return factory({
42
+ ...options,
43
+ instantiateWasm: (imports, ready) => {
44
+ void module.then(async (m) => ready(await instantiate(m, imports), m));
45
+ return {};
46
+ },
47
+ });
48
+ };
49
+ // the runtime, and the rule about its threads, are `platform/onnx-runtime`'s — the reading loads the same one the same way
50
+ const ort = await loadOnnxRuntime({ base: d.base, importModule: loadModule });
51
+ return createKokoroPort({ espeak, ort, fetch: get, base: d.base });
52
+ }
@@ -0,0 +1,70 @@
1
+ // SPDX-License-Identifier: AGPL-3.0-or-later
2
+ import type { NeuralVoice } from './voice-plan.js';
3
+ /** A Kokoro inference session on one device: token ids and a style row in, a 24 kHz waveform out. */
4
+ export interface KokoroSession {
5
+ readonly synthesize: (ids: readonly number[], styleVector: Float32Array) => Promise<Float32Array>;
6
+ }
7
+ /**
8
+ * WHAT SPEAKING NEEDS OF KOKORO — `platform/kokoro-runtime` fills it from the delivery (ADR-0216 §1).
9
+ * `phonemize` is espeak-ng in the voice's language (`pt-br`, `es-419`, `en-us`, `en-gb`); `vocabulary` the model tokenizer's symbols;
10
+ * `voice` a voice's style table; `session` a session on WebGPU or WASM.
11
+ *
12
+ * 📌 IT LIVES IN THIS LEAF and not beside the speaking, so that the runtime that builds one can be reached from `platform/tts` by
13
+ * `import()` without the two naming each other — a cycle the direction gate (ADR-0173) refuses, and rightly: the loader must not
14
+ * have to load the speaker to be loaded by it.
15
+ */
16
+ export interface KokoroModule {
17
+ readonly phonemize: (text: string, espeak: string) => Promise<string>;
18
+ readonly vocabulary: () => Promise<Readonly<{
19
+ [symbol: string]: number;
20
+ }>>;
21
+ readonly voice: (id: string) => Promise<Float32Array>;
22
+ readonly session: (device: 'webgpu' | 'wasm') => Promise<KokoroSession>;
23
+ }
24
+ /** How the neural voice arrives. Until ADR-0216 every game wrote one of these; now the engine has its own. */
25
+ export type LoadKokoro = () => Promise<KokoroModule>;
26
+ /** A Kokoro voice of the engine's three languages. `recommended` marks the two the Dev rated good (ADR-0198 §3). */
27
+ export interface KokoroVoice extends NeuralVoice {
28
+ readonly engine: 'kokoro';
29
+ /** The espeak-ng voice that phonemizes this voice's text. */
30
+ readonly espeak: string;
31
+ readonly recommended: boolean;
32
+ }
33
+ /**
34
+ * Kokoro-82M v1.0's voices for Portuguese, Spanish and English, as the model repository lists them (read 2026-09-14). The model's
35
+ * first letter is the language — `p` Brazilian Portuguese, `e` Spanish, `a` American and `b` British English — and the second the
36
+ * voice's gender. The others (French, Hindi, Italian, Japanese, Chinese) are not the engine's languages.
37
+ */
38
+ export declare const KOKORO_VOICES: readonly KokoroVoice[];
39
+ export declare const KOKORO_MODEL_URL = "https://huggingface.co/onnx-community/Kokoro-82M-v1.0-ONNX/resolve/main/onnx/model.onnx";
40
+ export declare const URL_DO_TOKENIZADOR_KOKORO = "https://huggingface.co/onnx-community/Kokoro-82M-v1.0-ONNX/resolve/main/tokenizer.json";
41
+ export declare const kokoroVoiceUrl: (id: string) => string;
42
+ /**
43
+ * Each voice file's SHA-256 and size, read from the repository's LFS metadata on 2026-09-14 (all 522 240 bytes); `pf_dora` also
44
+ * measured on the downloaded file. The model: 325 532 232 bytes, measured on the file. Checked before anything is kept (#168).
45
+ */
46
+ export declare const KOKORO_VOICES_SHA256: Readonly<{
47
+ [id: string]: string;
48
+ }>;
49
+ export declare const KOKORO_VOICE_BYTES = 522240;
50
+ export declare const KOKORO_MODEL_SHA256 = "8fbea51ea711f2af382e88c833d9e288c6dc82ce5e98421ea61c058ce21a34cb";
51
+ export declare const KOKORO_MODEL_BYTES = 325532232;
52
+ export declare const SHA256_DO_TOKENIZADOR_KOKORO = "77a02c8e164413299b4b4c403b14f8e0e1c1b727db4d46a09d6327b861060a34";
53
+ export declare const BYTES_DO_TOKENIZADOR_KOKORO = 3497;
54
+ /** The model's context: ids between the two pad tokens. A longer sentence is cut here (the caller splits text by sentence). */
55
+ export declare const MAX_KOKORO_TOKENS = 510;
56
+ /** A voice file is a table of style rows, one per token count, 256 numbers each. */
57
+ export declare const STYLE_DIMENSION = 256;
58
+ /** The token ids of a phoneme string: each symbol the vocabulary knows, in order, between two pad tokens (id 0). */
59
+ export declare function tokenize(phonemes: string, symbolIds: Readonly<{
60
+ [symbol: string]: number;
61
+ }>): number[];
62
+ /** The style row a sentence of `tokens` ids (pads excluded) takes from a voice table. */
63
+ export declare function sentenceStyle(styleTable: Float32Array, tokens: number): Float32Array;
64
+ /**
65
+ * Is a synthesis speech? Measured on 2026-09-14: WebGPU on one AMD GPU gave a waveform whose samples ran to 2×10⁷ — noise a child
66
+ * would hear as a burst. A speech waveform stays within ±1 (a sample or two past it is clipping, not noise) and is not silent.
67
+ */
68
+ export declare function eFala(waveform: ArrayLike<number>): boolean;
69
+ /** A 16-bit mono PCM WAV of a waveform, clipped to ±1 — what the narration's media element plays. */
70
+ export declare function wavDe(waveform: ArrayLike<number>, sampleRate?: number): ArrayBuffer;