@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.
- package/README.md +89 -78
- package/app/css/style.css +584 -374
- package/app/public/vendor/fonts/bitter-var-ext.woff2 +0 -0
- package/app/public/vendor/fonts/bitter-var.woff2 +0 -0
- package/app/public/vendor/fonts/bodonimoda-var-ext.woff2 +0 -0
- package/app/public/vendor/fonts/bodonimoda-var.woff2 +0 -0
- package/app/public/vendor/fonts/cat-abril_fatface-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-abril_fatface-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-adlam_display-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-adlam_display-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-agu_display-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-agu_display-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-alfa_slab_one-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-alfa_slab_one-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-are_you_serious-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-are_you_serious-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-asimovian-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-asimovian-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-atkinson_hyperlegible_next-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-atkinson_hyperlegible_next-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-bakbak_one-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-bakbak_one-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-bangers-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-bangers-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-barriecito-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-barriecito-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-berkshire_swash-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-berkshire_swash-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-bevan-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-bevan-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-bitcount-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-bitcount-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-bowlby_one_sc-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-bowlby_one_sc-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-bungee_shade-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-bungee_shade-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-charm-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-charm-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-charm-700-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-charm-700.woff2 +0 -0
- package/app/public/vendor/fonts/cat-cherry_bomb_one-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-cherry_bomb_one-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-chokokutai-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-chokokutai-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-chonburi-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-chonburi-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-climate_crisis-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-climate_crisis-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-cookie-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-dela_gothic_one-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-dela_gothic_one-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-fascinate_inline-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-fascinate_inline-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-ga_maamli-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-ga_maamli-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-itim-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-itim-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-jacquard_24-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-jacquard_24-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-kablammo-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-kablammo-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-kalam-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-kalam-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-kalam-700-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-kalam-700.woff2 +0 -0
- package/app/public/vendor/fonts/cat-katibeh-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-katibeh-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-lemonada-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-lemonada-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-lilita_one-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-lilita_one-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-lobster-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-lobster-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-luckiest_guy-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-luckiest_guy-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-marhey-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-marhey-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-modak-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-modak-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-momo_signature-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-momo_signature-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-monofett-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-monofett-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-monomakh-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-monomakh-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-monoton-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-monoton-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-nerko_one-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-nerko_one-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-noto_sans_adlam-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-noto_sans_adlam-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-noto_sans_arabic-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-noto_sans_arabic-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-noto_sans_devanagari-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-noto_sans_devanagari-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-noto_sans_hebrew-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-noto_sans_hebrew-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-noto_sans_jp-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-noto_sans_jp-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-noto_sans_khmer-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-noto_sans_khmer-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-noto_sans_kr-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-noto_sans_kr-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-noto_sans_sc-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-noto_sans_sc-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-noto_sans_thai-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-noto_sans_thai-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-ole-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-ole-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-pacifico-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-pacifico-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-patrick_hand-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-patrick_hand-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-petit_formal_script-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-petit_formal_script-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-pixelify_sans-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-pixelify_sans-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-plaster-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-plaster-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_ar_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_at-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_at_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_au_nsw-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_au_nsw_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_au_qld-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_au_qld_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_au_sa-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_au_sa_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_au_tas-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_au_tas_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_au_vic-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_au_vic_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_be_vlg-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_be_vlg_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_be_wal-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_be_wal_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_br_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_ca_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_cl_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_co_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_cu_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_cz-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_cz_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_de_grund-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_de_grund_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_de_la-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_de_la_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_de_sas-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_de_sas_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_de_va-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_de_va_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_dk_loopet-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_dk_loopet_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_dk_uloopet-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_dk_uloopet_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_es_deco_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_es_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_fr_moderne-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_fr_moderne_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_fr_trad-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_fr_trad_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_gb_j_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_gb_s_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_hr-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_hr_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_hr_lijeva-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_hr_lijeva_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_hu-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_hu_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_id-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_id_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_ie-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_ie_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_in-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_in_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_is-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_is_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_it_moderna-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_it_moderna_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_it_trad-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_it_trad_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_mx_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_ng_modern-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_ng_modern_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_nl-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_nl_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_no-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_no_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_nz-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_nz_basic-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_nz_basic_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_nz_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_pe_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_pl-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_pl_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_pt_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_ro-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_ro_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_sk-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_sk_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_tz-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_tz_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_us_modern_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_us_trad_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_vn-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_vn_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_za-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_za_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-potta_one-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-potta_one-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-ranchers-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-ranchers-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-ranga-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-ranga-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-ranga-700-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-ranga-700.woff2 +0 -0
- package/app/public/vendor/fonts/cat-risque-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-risque-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-rowdies-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-rowdies-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-rowdies-700-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-rowdies-700.woff2 +0 -0
- package/app/public/vendor/fonts/cat-ruge_boogie-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-ruge_boogie-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-ruslan_display-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-ruslan_display-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-sacramento-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-sacramento-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-sancreek-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-sancreek-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-sankofa_display-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-sankofa_display-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-sedgwick_ave_display-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-sedgwick_ave_display-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-shantell_sans-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-shantell_sans-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-smokum-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-smokum-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-solitreo-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-solitreo-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-spicy_rice-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-spicy_rice-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-sriracha-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-sriracha-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-srisakdi-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-srisakdi-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-srisakdi-700-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-srisakdi-700.woff2 +0 -0
- package/app/public/vendor/fonts/cat-stix_two_math-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-tillana-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-tillana-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-tillana-700-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-tillana-700.woff2 +0 -0
- package/app/public/vendor/fonts/cat-titan_one-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-titan_one-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-yatra_one-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-yatra_one-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-yomogi-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-yomogi-400.woff2 +0 -0
- package/app/public/vendor/fonts/dmserifdisplay-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/dmserifdisplay-400.woff2 +0 -0
- package/app/public/vendor/fonts/domine-var-ext.woff2 +0 -0
- package/app/public/vendor/fonts/domine-var.woff2 +0 -0
- package/app/public/vendor/fonts/fraunces-var-ext.woff2 +0 -0
- package/app/public/vendor/fonts/fraunces-var.woff2 +0 -0
- package/app/public/vendor/fonts/fredoka-var-ext.woff2 +0 -0
- package/app/public/vendor/fonts/fredoka-var.woff2 +0 -0
- package/app/public/vendor/fonts/jakarta-var-ext.woff2 +0 -0
- package/app/public/vendor/fonts/jakarta-var.woff2 +0 -0
- package/app/public/vendor/fonts/lora-var-ext.woff2 +0 -0
- package/app/public/vendor/fonts/lora-var.woff2 +0 -0
- package/app/public/vendor/fonts/merriweather-var-ext.woff2 +0 -0
- package/app/public/vendor/fonts/merriweather-var.woff2 +0 -0
- package/app/public/vendor/fonts/notosans-var-ext.woff2 +0 -0
- package/app/public/vendor/fonts/notosans-var.woff2 +0 -0
- package/app/public/vendor/fonts/nunito-var-ext.woff2 +0 -0
- package/app/public/vendor/fonts/nunito-var.woff2 +0 -0
- package/app/public/vendor/fonts/playfair-var-ext.woff2 +0 -0
- package/app/public/vendor/fonts/playfair-var.woff2 +0 -0
- package/app/public/vendor/fonts/playwrite-cu.woff2 +0 -0
- package/app/public/vendor/fonts/playwrite-es-deco.woff2 +0 -0
- package/app/public/vendor/fonts/playwrite-es.woff2 +0 -0
- package/app/public/vendor/fonts/playwrite-gb-j.woff2 +0 -0
- package/app/public/vendor/fonts/playwrite-gb-s.woff2 +0 -0
- package/app/public/vendor/fonts/playwrite-pe.woff2 +0 -0
- package/app/public/vendor/fonts/playwrite-pt.woff2 +0 -0
- package/app/public/vendor/fonts/quicksand-var-ext.woff2 +0 -0
- package/app/public/vendor/fonts/quicksand-var.woff2 +0 -0
- package/app/public/vendor/fonts/robotoflex-var-ext.woff2 +0 -0
- package/app/public/vendor/fonts/robotoflex-var.woff2 +0 -0
- package/app/public/vendor/fonts/sora-var-ext.woff2 +0 -0
- package/app/public/vendor/fonts/sora-var.woff2 +0 -0
- package/app/public/vendor/fonts/spacegrotesk-var-ext.woff2 +0 -0
- package/app/public/vendor/fonts/spacegrotesk-var.woff2 +0 -0
- package/app/public/vendor/fonts/spectral-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/spectral-400.woff2 +0 -0
- package/app/public/vendor/fonts/spectral-700-ext.woff2 +0 -0
- package/app/public/vendor/fonts/spectral-700.woff2 +0 -0
- package/app/public/vendor/fonts/teachers-var-ext.woff2 +0 -0
- package/app/public/vendor/fonts/teachers-var.woff2 +0 -0
- package/app/public/vendor/fonts/ubuntu-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/ubuntu-400.woff2 +0 -0
- package/app/public/vendor/fonts/ubuntu-700-ext.woff2 +0 -0
- package/app/public/vendor/fonts/ubuntu-700.woff2 +0 -0
- package/app/public/vendor/fonts.css +1167 -51
- package/dist-pkg/boot/create-game.d.ts +467 -162
- package/dist-pkg/boot/create-game.js +3563 -426
- package/dist-pkg/core/a11y-sr.d.ts +25 -3
- package/dist-pkg/core/a11y-sr.js +40 -19
- package/dist-pkg/core/accessible-label.d.ts +17 -0
- package/dist-pkg/core/accessible-label.js +37 -0
- package/dist-pkg/core/accommodation-subjects.d.ts +26 -0
- package/dist-pkg/core/accommodation-subjects.js +32 -0
- package/dist-pkg/core/accommodations.d.ts +107 -0
- package/dist-pkg/core/accommodations.js +178 -0
- package/dist-pkg/core/actions.d.ts +75 -51
- package/dist-pkg/core/actions.js +98 -69
- package/dist-pkg/core/calm-mode.d.ts +31 -0
- package/dist-pkg/core/calm-mode.js +47 -0
- package/dist-pkg/core/camera-cycle.d.ts +15 -0
- package/dist-pkg/core/camera-cycle.js +7 -0
- package/dist-pkg/core/caption-duration.d.ts +15 -0
- package/dist-pkg/core/caption-duration.js +19 -0
- package/dist-pkg/core/cartridge-problems.d.ts +34 -0
- package/dist-pkg/core/cartridge-problems.js +53 -0
- package/dist-pkg/core/constants.d.ts +0 -54
- package/dist-pkg/core/constants.js +9 -76
- package/dist-pkg/core/contract.d.ts +143 -163
- package/dist-pkg/core/contract.js +223 -207
- package/dist-pkg/core/dom-query.d.ts +4 -4
- package/dist-pkg/core/dom-query.js +12 -20
- package/dist-pkg/core/entity.d.ts +62 -77
- package/dist-pkg/core/entity.js +18 -32
- package/dist-pkg/core/escape-html.d.ts +9 -10
- package/dist-pkg/core/escape-html.js +16 -20
- package/dist-pkg/core/flash-threshold.d.ts +17 -0
- package/dist-pkg/core/flash-threshold.js +113 -0
- package/dist-pkg/core/game-speed.d.ts +11 -0
- package/dist-pkg/core/game-speed.js +16 -0
- package/dist-pkg/core/genres.d.ts +20 -0
- package/dist-pkg/core/genres.js +44 -0
- package/dist-pkg/core/i18n.d.ts +87 -41
- package/dist-pkg/core/i18n.js +206 -153
- package/dist-pkg/core/loop.d.ts +17 -6
- package/dist-pkg/core/loop.js +26 -26
- package/dist-pkg/core/pause-icon-catalogue.d.ts +15 -0
- package/dist-pkg/core/pause-icon-catalogue.js +54 -0
- package/dist-pkg/core/ring.d.ts +17 -0
- package/dist-pkg/core/ring.js +29 -0
- package/dist-pkg/core/rng.d.ts +7 -12
- package/dist-pkg/core/rng.js +23 -53
- package/dist-pkg/core/route.d.ts +26 -26
- package/dist-pkg/core/route.js +126 -121
- package/dist-pkg/core/scenes.d.ts +37 -40
- package/dist-pkg/core/scenes.js +41 -43
- package/dist-pkg/core/screens.d.ts +4 -4
- package/dist-pkg/core/screens.js +11 -16
- package/dist-pkg/core/setting-defaults.d.ts +61 -0
- package/dist-pkg/core/setting-defaults.js +66 -0
- package/dist-pkg/core/speech-rate.d.ts +29 -0
- package/dist-pkg/core/speech-rate.js +47 -0
- package/dist-pkg/core/state.d.ts +118 -118
- package/dist-pkg/core/state.js +322 -297
- package/dist-pkg/core/visual-cycles.d.ts +30 -0
- package/dist-pkg/core/visual-cycles.js +52 -0
- package/dist-pkg/core/visual-state.d.ts +13 -0
- package/dist-pkg/core/visual-state.js +6 -0
- package/dist-pkg/educational/activities-registry.d.ts +1 -1
- package/dist-pkg/educational/activities-registry.js +9 -8
- package/dist-pkg/educational/adaptive-engine.d.ts +11 -11
- package/dist-pkg/educational/adaptive-engine.js +17 -17
- package/dist-pkg/educational/segment-bar.d.ts +12 -12
- package/dist-pkg/educational/segment-bar.js +9 -9
- package/dist-pkg/i18n/en.js +321 -215
- package/dist-pkg/i18n/es.js +320 -215
- package/dist-pkg/i18n/pt.js +342 -215
- package/dist-pkg/input/default-bindings.d.ts +37 -38
- package/dist-pkg/input/default-bindings.js +127 -144
- package/dist-pkg/input/devices.d.ts +7 -7
- package/dist-pkg/input/devices.js +17 -16
- package/dist-pkg/input/edges.d.ts +23 -32
- package/dist-pkg/input/edges.js +23 -28
- package/dist-pkg/input/empathy-filter.d.ts +22 -0
- package/dist-pkg/input/empathy-filter.js +34 -0
- package/dist-pkg/input/face-map.d.ts +96 -0
- package/dist-pkg/input/face-map.js +255 -0
- package/dist-pkg/input/face-signals.d.ts +40 -0
- package/dist-pkg/input/face-signals.js +48 -0
- package/dist-pkg/input/gamepad.d.ts +164 -145
- package/dist-pkg/input/gamepad.js +351 -559
- package/dist-pkg/input/gaze-cycle.d.ts +64 -0
- package/dist-pkg/input/gaze-cycle.js +133 -0
- package/dist-pkg/input/gaze-relative.d.ts +68 -0
- package/dist-pkg/input/gaze-relative.js +142 -0
- package/dist-pkg/input/hand-map.d.ts +28 -0
- package/dist-pkg/input/hand-map.js +142 -0
- package/dist-pkg/input/input-cooldown.d.ts +17 -0
- package/dist-pkg/input/input-cooldown.js +39 -0
- package/dist-pkg/input/keyboard-runtime.d.ts +18 -20
- package/dist-pkg/input/keyboard-runtime.js +23 -27
- package/dist-pkg/input/keyboard.d.ts +68 -62
- package/dist-pkg/input/keyboard.js +83 -105
- package/dist-pkg/input/keydown.d.ts +124 -132
- package/dist-pkg/input/keydown.js +283 -288
- package/dist-pkg/input/latch-edge.d.ts +25 -21
- package/dist-pkg/input/latch-edge.js +33 -35
- package/dist-pkg/input/latch-scope.d.ts +43 -47
- package/dist-pkg/input/latch-scope.js +66 -75
- package/dist-pkg/input/latch-store.d.ts +28 -29
- package/dist-pkg/input/latch-store.js +44 -47
- package/dist-pkg/input/latch-sync.d.ts +28 -29
- package/dist-pkg/input/latch-sync.js +25 -25
- package/dist-pkg/input/latch.d.ts +14 -17
- package/dist-pkg/input/latch.js +29 -37
- package/dist-pkg/input/pad-defaults.d.ts +13 -16
- package/dist-pkg/input/pad-defaults.js +21 -28
- package/dist-pkg/input/pad-reading.d.ts +76 -0
- package/dist-pkg/input/pad-reading.js +164 -0
- package/dist-pkg/input/pad-wizard.d.ts +96 -0
- package/dist-pkg/input/pad-wizard.js +205 -0
- package/dist-pkg/input/pointer-space.d.ts +19 -20
- package/dist-pkg/input/pointer-space.js +27 -32
- package/dist-pkg/input/pointer.d.ts +39 -40
- package/dist-pkg/input/pointer.js +42 -45
- package/dist-pkg/input/state.d.ts +101 -89
- package/dist-pkg/input/state.js +54 -134
- package/dist-pkg/input/switch-scan.d.ts +42 -0
- package/dist-pkg/input/switch-scan.js +54 -0
- package/dist-pkg/input/synthetic-source.d.ts +42 -0
- package/dist-pkg/input/synthetic-source.js +57 -0
- package/dist-pkg/input/touch-bindings.d.ts +127 -113
- package/dist-pkg/input/touch-bindings.js +158 -173
- package/dist-pkg/input/touch.d.ts +130 -70
- package/dist-pkg/input/touch.js +321 -123
- package/dist-pkg/input/transport-in-use.d.ts +107 -0
- package/dist-pkg/input/transport-in-use.js +130 -0
- package/dist-pkg/input/transports.d.ts +96 -114
- package/dist-pkg/input/transports.js +104 -106
- package/dist-pkg/input/virtual-controller.d.ts +46 -0
- package/dist-pkg/input/virtual-controller.js +41 -0
- package/dist-pkg/input/vocabulary-migration.d.ts +50 -49
- package/dist-pkg/input/vocabulary-migration.js +80 -79
- package/dist-pkg/input/voice-map.d.ts +43 -0
- package/dist-pkg/input/voice-map.js +125 -0
- package/dist-pkg/platform/audio-ambient.d.ts +13 -1
- package/dist-pkg/platform/audio-ambient.js +11 -13
- package/dist-pkg/platform/audio-earcons.d.ts +20 -19
- package/dist-pkg/platform/audio-earcons.js +51 -42
- package/dist-pkg/platform/audio-jingles.js +9 -10
- package/dist-pkg/platform/audio-mixer.d.ts +14 -2
- package/dist-pkg/platform/audio-mixer.js +36 -39
- package/dist-pkg/platform/audio-sonar.d.ts +96 -113
- package/dist-pkg/platform/audio-sonar.js +245 -238
- package/dist-pkg/platform/audio.d.ts +53 -19
- package/dist-pkg/platform/audio.js +161 -169
- package/dist-pkg/platform/flash-sampler.d.ts +19 -0
- package/dist-pkg/platform/flash-sampler.js +79 -0
- package/dist-pkg/platform/guide-intensity.d.ts +26 -27
- package/dist-pkg/platform/guide-intensity.js +50 -52
- package/dist-pkg/platform/heavy-catalogue.d.ts +31 -0
- package/dist-pkg/platform/heavy-catalogue.js +223 -0
- package/dist-pkg/platform/heavy-mirror.d.ts +26 -0
- package/dist-pkg/platform/heavy-mirror.js +76 -0
- package/dist-pkg/platform/heavy.d.ts +104 -0
- package/dist-pkg/platform/heavy.js +169 -0
- package/dist-pkg/platform/interruptible-speech.d.ts +16 -16
- package/dist-pkg/platform/interruptible-speech.js +50 -51
- package/dist-pkg/platform/kokoro-port.d.ts +27 -0
- package/dist-pkg/platform/kokoro-port.js +50 -0
- package/dist-pkg/platform/kokoro-runtime.d.ts +20 -0
- package/dist-pkg/platform/kokoro-runtime.js +52 -0
- package/dist-pkg/platform/kokoro.d.ts +70 -0
- package/dist-pkg/platform/kokoro.js +133 -0
- package/dist-pkg/platform/listener-scope.d.ts +12 -0
- package/dist-pkg/platform/listener-scope.js +81 -0
- package/dist-pkg/platform/locale-host.d.ts +10 -0
- package/dist-pkg/platform/locale-host.js +34 -0
- package/dist-pkg/platform/microphone.d.ts +51 -0
- package/dist-pkg/platform/microphone.js +118 -0
- package/dist-pkg/platform/onnx-runtime.d.ts +34 -0
- package/dist-pkg/platform/onnx-runtime.js +42 -0
- package/dist-pkg/platform/reading-in-worker.d.ts +40 -0
- package/dist-pkg/platform/reading-in-worker.js +87 -0
- package/dist-pkg/platform/reading-model.d.ts +73 -0
- package/dist-pkg/platform/reading-model.js +247 -0
- package/dist-pkg/platform/reading-runtime.d.ts +24 -0
- package/dist-pkg/platform/reading-runtime.js +159 -0
- package/dist-pkg/platform/reading-worker.d.ts +41 -0
- package/dist-pkg/platform/reading-worker.js +58 -0
- package/dist-pkg/platform/reading.d.ts +69 -0
- package/dist-pkg/platform/reading.js +128 -0
- package/dist-pkg/platform/speech-recognition.d.ts +51 -0
- package/dist-pkg/platform/speech-recognition.js +84 -0
- package/dist-pkg/platform/speech.d.ts +14 -1
- package/dist-pkg/platform/speech.js +13 -13
- package/dist-pkg/platform/storage-keys.d.ts +96 -0
- package/dist-pkg/platform/storage-keys.js +106 -0
- package/dist-pkg/platform/storage.d.ts +46 -111
- package/dist-pkg/platform/storage.js +104 -169
- package/dist-pkg/platform/tts.d.ts +51 -38
- package/dist-pkg/platform/tts.js +217 -119
- package/dist-pkg/platform/vision-loop.d.ts +23 -0
- package/dist-pkg/platform/vision-loop.js +56 -0
- package/dist-pkg/platform/vision.d.ts +132 -0
- package/dist-pkg/platform/vision.js +117 -0
- package/dist-pkg/platform/voice-listener.d.ts +36 -0
- package/dist-pkg/platform/voice-listener.js +88 -0
- package/dist-pkg/platform/voice-plan.d.ts +6 -102
- package/dist-pkg/platform/voice-plan.js +9 -151
- package/dist-pkg/platform/vosk-runtime.d.ts +71 -0
- package/dist-pkg/platform/vosk-runtime.js +93 -0
- package/dist-pkg/render/canvas.d.ts +13 -7
- package/dist-pkg/render/canvas.js +13 -13
- package/dist-pkg/render/crt.d.ts +46 -12
- package/dist-pkg/render/crt.js +82 -80
- package/dist-pkg/render/cvd-matrices.d.ts +18 -18
- package/dist-pkg/render/cvd-matrices.js +33 -38
- package/dist-pkg/render/hc-role-data.d.ts +7 -7
- package/dist-pkg/render/hc-role-data.js +14 -14
- package/dist-pkg/render/high-contrast.d.ts +66 -54
- package/dist-pkg/render/high-contrast.js +221 -216
- package/dist-pkg/render/low-vision-drawing.d.ts +5 -0
- package/dist-pkg/render/low-vision-drawing.js +46 -0
- package/dist-pkg/render/lq-filter.d.ts +32 -20
- package/dist-pkg/render/lq-filter.js +59 -65
- package/dist-pkg/render/port.d.ts +86 -88
- package/dist-pkg/render/port.js +17 -23
- package/dist-pkg/render/screen-pipeline.d.ts +42 -42
- package/dist-pkg/render/screen-pipeline.js +80 -87
- package/dist-pkg/render/sprite-fx.d.ts +2 -1
- package/dist-pkg/render/sprite-fx.js +16 -14
- package/dist-pkg/render/viewports.d.ts +20 -15
- package/dist-pkg/render/viewports.js +83 -114
- package/dist-pkg/render/viz-axes-labels.d.ts +47 -0
- package/dist-pkg/render/viz-axes-labels.js +88 -0
- package/dist-pkg/render/viz-axes.d.ts +80 -86
- package/dist-pkg/render/viz-axes.js +115 -116
- package/dist-pkg/render/viz-modes.d.ts +28 -29
- package/dist-pkg/render/viz-modes.js +40 -45
- package/dist-pkg/render/viz-refusal.d.ts +32 -0
- package/dist-pkg/render/viz-refusal.js +57 -0
- package/dist-pkg/render/viz-setters.d.ts +104 -66
- package/dist-pkg/render/viz-setters.js +182 -191
- package/dist-pkg/ui/aac-sets.d.ts +40 -0
- package/dist-pkg/ui/aac-sets.js +49 -0
- package/dist-pkg/ui/audio-choices.d.ts +63 -0
- package/dist-pkg/ui/audio-choices.js +94 -0
- package/dist-pkg/ui/audio-rows-that-apply.d.ts +12 -0
- package/dist-pkg/ui/audio-rows-that-apply.js +43 -0
- package/dist-pkg/ui/camera-control.d.ts +6 -0
- package/dist-pkg/ui/camera-control.js +14 -0
- package/dist-pkg/ui/changed-mark.d.ts +9 -8
- package/dist-pkg/ui/changed-mark.js +22 -53
- package/dist-pkg/ui/control-choices.d.ts +37 -0
- package/dist-pkg/ui/control-choices.js +84 -0
- package/dist-pkg/ui/debug-panel.d.ts +59 -43
- package/dist-pkg/ui/debug-panel.js +68 -69
- package/dist-pkg/ui/dom.d.ts +10 -14
- package/dist-pkg/ui/dom.js +10 -47
- package/dist-pkg/ui/drawing-problems.d.ts +25 -0
- package/dist-pkg/ui/drawing-problems.js +93 -0
- package/dist-pkg/ui/eye-control.d.ts +36 -0
- package/dist-pkg/ui/eye-control.js +178 -0
- package/dist-pkg/ui/face-control.d.ts +25 -0
- package/dist-pkg/ui/face-control.js +183 -0
- package/dist-pkg/ui/focus-trap.d.ts +39 -49
- package/dist-pkg/ui/focus-trap.js +56 -65
- package/dist-pkg/ui/fonts.d.ts +118 -63
- package/dist-pkg/ui/fonts.js +267 -111
- package/dist-pkg/ui/game-options.d.ts +42 -0
- package/dist-pkg/ui/game-options.js +138 -0
- package/dist-pkg/ui/gaze-overlay.d.ts +64 -0
- package/dist-pkg/ui/gaze-overlay.js +165 -0
- package/dist-pkg/ui/hand-control.d.ts +25 -0
- package/dist-pkg/ui/hand-control.js +143 -0
- package/dist-pkg/ui/help-panel.d.ts +76 -0
- package/dist-pkg/ui/help-panel.js +232 -0
- package/dist-pkg/ui/hud-bands.d.ts +45 -0
- package/dist-pkg/ui/hud-bands.js +108 -0
- package/dist-pkg/ui/hud.d.ts +73 -70
- package/dist-pkg/ui/hud.js +94 -98
- package/dist-pkg/ui/item-announcement.d.ts +13 -12
- package/dist-pkg/ui/item-announcement.js +25 -26
- package/dist-pkg/ui/latch-refusal.d.ts +22 -21
- package/dist-pkg/ui/latch-refusal.js +37 -37
- package/dist-pkg/ui/layout.d.ts +103 -28
- package/dist-pkg/ui/layout.js +114 -99
- package/dist-pkg/ui/locale-flags.d.ts +16 -0
- package/dist-pkg/ui/locale-flags.js +30 -0
- package/dist-pkg/ui/loop-crash.d.ts +17 -17
- package/dist-pkg/ui/loop-crash.js +33 -62
- package/dist-pkg/ui/menu-intent.d.ts +32 -0
- package/dist-pkg/ui/menu-intent.js +54 -0
- package/dist-pkg/ui/menu-items.d.ts +10 -0
- package/dist-pkg/ui/menu-items.js +22 -0
- package/dist-pkg/ui/menu-nav.d.ts +60 -90
- package/dist-pkg/ui/menu-nav.js +301 -274
- package/dist-pkg/ui/mobility-choices.d.ts +26 -0
- package/dist-pkg/ui/mobility-choices.js +41 -0
- package/dist-pkg/ui/motion-choices.d.ts +31 -0
- package/dist-pkg/ui/motion-choices.js +68 -0
- package/dist-pkg/ui/motion-scene.d.ts +24 -19
- package/dist-pkg/ui/motion-scene.js +29 -61
- package/dist-pkg/ui/mount-panel.d.ts +81 -0
- package/dist-pkg/ui/mount-panel.js +61 -0
- package/dist-pkg/ui/panel-shell.d.ts +65 -31
- package/dist-pkg/ui/panel-shell.js +92 -66
- package/dist-pkg/ui/panel-widgets.d.ts +116 -0
- package/dist-pkg/ui/panel-widgets.js +208 -0
- package/dist-pkg/ui/pause-buttons.d.ts +35 -0
- package/dist-pkg/ui/pause-buttons.js +66 -0
- package/dist-pkg/ui/pause-icons.d.ts +250 -343
- package/dist-pkg/ui/pause-icons.js +614 -605
- package/dist-pkg/ui/pause-markup.d.ts +86 -0
- package/dist-pkg/ui/pause-markup.js +125 -0
- package/dist-pkg/ui/reach-notice.d.ts +22 -23
- package/dist-pkg/ui/reach-notice.js +55 -58
- package/dist-pkg/ui/scan-overlay.d.ts +23 -0
- package/dist-pkg/ui/scan-overlay.js +42 -0
- package/dist-pkg/ui/settings-aac.d.ts +68 -0
- package/dist-pkg/ui/settings-aac.js +189 -0
- package/dist-pkg/ui/settings-audio.d.ts +91 -113
- package/dist-pkg/ui/settings-audio.js +407 -405
- package/dist-pkg/ui/settings-controls.d.ts +53 -92
- package/dist-pkg/ui/settings-controls.js +143 -215
- package/dist-pkg/ui/settings-empathy.d.ts +39 -30
- package/dist-pkg/ui/settings-empathy.js +53 -60
- package/dist-pkg/ui/settings-mobility.d.ts +195 -0
- package/dist-pkg/ui/settings-mobility.js +374 -0
- package/dist-pkg/ui/settings-motion.d.ts +91 -70
- package/dist-pkg/ui/settings-motion.js +287 -198
- package/dist-pkg/ui/settings-panel.d.ts +48 -45
- package/dist-pkg/ui/settings-panel.js +164 -93
- package/dist-pkg/ui/settings-typo.d.ts +28 -76
- package/dist-pkg/ui/settings-typo.js +145 -125
- package/dist-pkg/ui/settings-visual.d.ts +29 -87
- package/dist-pkg/ui/settings-visual.js +240 -193
- package/dist-pkg/ui/shell.d.ts +113 -134
- package/dist-pkg/ui/shell.js +143 -216
- package/dist-pkg/ui/simulation-list.d.ts +27 -0
- package/dist-pkg/ui/simulation-list.js +76 -0
- package/dist-pkg/ui/simulation-over-the-world.d.ts +23 -0
- package/dist-pkg/ui/simulation-over-the-world.js +131 -0
- package/dist-pkg/ui/simulation-refusal.d.ts +5 -31
- package/dist-pkg/ui/simulation-refusal.js +8 -56
- package/dist-pkg/ui/switchable-control.d.ts +11 -0
- package/dist-pkg/ui/switchable-control.js +19 -0
- package/dist-pkg/ui/title.d.ts +4 -4
- package/dist-pkg/ui/title.js +11 -13
- package/dist-pkg/ui/top-band.d.ts +24 -0
- package/dist-pkg/ui/top-band.js +100 -0
- package/dist-pkg/ui/typo-choices.d.ts +71 -0
- package/dist-pkg/ui/typo-choices.js +84 -0
- package/dist-pkg/ui/visual-axes-panel.d.ts +11 -47
- package/dist-pkg/ui/visual-axes-panel.js +12 -94
- package/dist-pkg/ui/visual-choices.d.ts +77 -0
- package/dist-pkg/ui/visual-choices.js +107 -0
- package/dist-pkg/ui/vlibras.d.ts +33 -10
- package/dist-pkg/ui/vlibras.js +58 -81
- package/dist-pkg/ui/voice-control.d.ts +46 -0
- package/dist-pkg/ui/voice-control.js +143 -0
- package/dist-pkg/ui/voice-settings.d.ts +96 -0
- package/dist-pkg/ui/voice-settings.js +302 -0
- package/dist-pkg/ui/where-the-child-is.d.ts +31 -0
- package/dist-pkg/ui/where-the-child-is.js +70 -0
- package/docs/CREDITS.md +198 -54
- package/docs/LICENSES.md +160 -145
- package/package.json +24 -25
- package/scripts/heavy-into-the-delivery.mjs +144 -0
- package/scripts/licences/Apache-2.0.txt +176 -0
- package/scripts/licences/GPL-3.0.txt +674 -0
- package/scripts/licences/MIT.txt +17 -0
- package/scripts/licences/third-party.mjs +287 -0
- package/scripts/licences/vosk-browser.NOTICE.txt +268 -0
- package/app/public/vendor/fonts/comicneue-400.woff2 +0 -0
- package/app/public/vendor/fonts/comicneue-700.woff2 +0 -0
- package/dist-pkg/core/anel.d.ts +0 -17
- package/dist-pkg/core/anel.js +0 -31
- package/dist-pkg/core/collision.d.ts +0 -21
- package/dist-pkg/core/collision.js +0 -62
- package/dist-pkg/core/layers.d.ts +0 -63
- package/dist-pkg/core/layers.js +0 -95
- package/dist-pkg/core/letter-grid.d.ts +0 -55
- package/dist-pkg/core/letter-grid.js +0 -116
- package/dist-pkg/core/password.d.ts +0 -34
- package/dist-pkg/core/password.js +0 -205
- package/dist-pkg/core/rotulo-acessivel.d.ts +0 -17
- package/dist-pkg/core/rotulo-acessivel.js +0 -41
- package/dist-pkg/core/run-state.d.ts +0 -115
- package/dist-pkg/core/run-state.js +0 -40
- package/dist-pkg/core/tiles.d.ts +0 -12
- package/dist-pkg/core/tiles.js +0 -61
- package/dist-pkg/core/world.d.ts +0 -4
- package/dist-pkg/core/world.js +0 -58
- package/dist-pkg/input/origem-sintetica.d.ts +0 -44
- package/dist-pkg/input/origem-sintetica.js +0 -60
- package/dist-pkg/input/transporte-em-uso.d.ts +0 -101
- package/dist-pkg/input/transporte-em-uso.js +0 -130
- package/dist-pkg/platform/audio-nav.d.ts +0 -51
- package/dist-pkg/platform/audio-nav.js +0 -99
- package/dist-pkg/platform/pesados-catalogo.d.ts +0 -14
- package/dist-pkg/platform/pesados-catalogo.js +0 -177
- package/dist-pkg/platform/pesados.d.ts +0 -31
- package/dist-pkg/platform/pesados.js +0 -75
- package/dist-pkg/platform/vozes-prontas.d.ts +0 -28
- package/dist-pkg/platform/vozes-prontas.js +0 -61
- package/dist-pkg/render/camera.d.ts +0 -58
- package/dist-pkg/render/camera.js +0 -105
- package/dist-pkg/render/cenario-data.d.ts +0 -127
- package/dist-pkg/render/cenario-data.js +0 -145
- package/dist-pkg/render/city-tex.d.ts +0 -63
- package/dist-pkg/render/city-tex.js +0 -228
- package/dist-pkg/render/city-tiles.d.ts +0 -11
- package/dist-pkg/render/city-tiles.js +0 -140
- package/dist-pkg/render/draw.d.ts +0 -149
- package/dist-pkg/render/draw.js +0 -231
- package/dist-pkg/render/fx.d.ts +0 -63
- package/dist-pkg/render/fx.js +0 -123
- package/dist-pkg/render/minimap.d.ts +0 -11
- package/dist-pkg/render/minimap.js +0 -94
- package/dist-pkg/render/parallax.d.ts +0 -85
- package/dist-pkg/render/parallax.js +0 -158
- package/dist-pkg/render/player-anim.d.ts +0 -71
- package/dist-pkg/render/player-anim.js +0 -152
- package/dist-pkg/render/recycling-tex.d.ts +0 -48
- package/dist-pkg/render/recycling-tex.js +0 -164
- package/dist-pkg/render/scene-city.d.ts +0 -77
- package/dist-pkg/render/scene-city.js +0 -181
- package/dist-pkg/render/scene-parallax.d.ts +0 -72
- package/dist-pkg/render/scene-parallax.js +0 -426
- package/dist-pkg/render/scene-sky.d.ts +0 -126
- package/dist-pkg/render/scene-sky.js +0 -295
- package/dist-pkg/render/set-cenario.d.ts +0 -54
- package/dist-pkg/render/set-cenario.js +0 -103
- package/dist-pkg/render/textures.d.ts +0 -75
- package/dist-pkg/render/textures.js +0 -240
- package/dist-pkg/render/title-scene.d.ts +0 -46
- package/dist-pkg/render/title-scene.js +0 -75
- package/dist-pkg/render/weather.d.ts +0 -96
- package/dist-pkg/render/weather.js +0 -171
- package/dist-pkg/render/wheelchair-sprites.d.ts +0 -32
- package/dist-pkg/render/wheelchair-sprites.js +0 -69
- package/dist-pkg/render/world-tex.d.ts +0 -18
- package/dist-pkg/render/world-tex.js +0 -87
- package/dist-pkg/ui/activities-menu.d.ts +0 -258
- package/dist-pkg/ui/activities-menu.js +0 -648
- package/dist-pkg/ui/caa-sets.d.ts +0 -39
- package/dist-pkg/ui/caa-sets.js +0 -65
- package/dist-pkg/ui/map-hub.d.ts +0 -56
- package/dist-pkg/ui/map-hub.js +0 -138
- package/dist-pkg/ui/settings-caa.d.ts +0 -45
- package/dist-pkg/ui/settings-caa.js +0 -137
- package/dist-pkg/ui/settings-motor.d.ts +0 -175
- package/dist-pkg/ui/settings-motor.js +0 -342
- package/dist-pkg/ui/webcam.d.ts +0 -7
- package/dist-pkg/ui/webcam.js +0 -93
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
// SPDX-License-Identifier: AGPL-3.0-or-later
|
|
2
|
+
import type { Translate } from '../core/i18n.js';
|
|
3
|
+
import type { VirtualController } from '../input/virtual-controller.js';
|
|
4
|
+
import { type VoskDeps, type VoskLoad } from '../platform/vosk-runtime.js';
|
|
5
|
+
import { type VoiceListener, type VoiceListenerDeps } from '../platform/voice-listener.js';
|
|
6
|
+
import type { SwitchableControl } from './switchable-control.js';
|
|
7
|
+
/** How long a spoken position stays pressed. The same pulse the scan uses: long enough for a game to see a press and a release. */
|
|
8
|
+
export declare const VOICE_PULSE_MS = 400;
|
|
9
|
+
export interface VoiceControlDeps {
|
|
10
|
+
/** Translates in the page's language — the root's translator (ADR-0232 D3). REQUIRED: text built from nowhere is a raw key. */
|
|
11
|
+
t: Translate;
|
|
12
|
+
readonly base: string;
|
|
13
|
+
/** The child's language (`core/i18n.bcp47`): it chooses the model AND the words. */
|
|
14
|
+
readonly language: () => string;
|
|
15
|
+
readonly controller: VirtualController;
|
|
16
|
+
/** The names the open menu is showing right now, if any (ADR-0194). */
|
|
17
|
+
readonly menuWords: () => readonly string[];
|
|
18
|
+
readonly say: (text: string) => void;
|
|
19
|
+
readonly alert: (text: string) => void;
|
|
20
|
+
readonly report: (line: string) => void;
|
|
21
|
+
/** Puts the 👄 back to off when nothing could start. */
|
|
22
|
+
readonly turnOff: () => void;
|
|
23
|
+
readonly after: (fn: () => void, ms: number) => void;
|
|
24
|
+
readonly hasFile: VoskDeps['hasFile'];
|
|
25
|
+
readonly loadBundle: VoskDeps['loadBundle'];
|
|
26
|
+
readonly getUserMedia: VoiceListenerDeps['getUserMedia'];
|
|
27
|
+
readonly createContext: VoiceListenerDeps['createContext'];
|
|
28
|
+
readonly loadRuntime?: (deps: VoskDeps) => Promise<VoskLoad>;
|
|
29
|
+
readonly listen?: (deps: VoiceListenerDeps) => Promise<VoiceListener>;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* 🎯 THE VOICE IS IN THE FAMILY AND NOT IN THE CAMERA'S CYCLE (ADR-0221 step 7f): it answers the 👄 and not the 📷, and has
|
|
33
|
+
* one more method. Declaring the family is what makes the compiler see it turns on and off like the other three.
|
|
34
|
+
*/
|
|
35
|
+
export interface VoiceControl extends SwitchableControl {
|
|
36
|
+
/** The open menu changed: the words it shows join the grammar, or leave it. */
|
|
37
|
+
refreshGrammar(): void;
|
|
38
|
+
/**
|
|
39
|
+
* THE CHILD'S LANGUAGE CHANGED (ADR-0225): the model, the vocabulary and the grammar are chosen again.
|
|
40
|
+
*
|
|
41
|
+
* 📌 A listening recogniser is restarted, which costs the model being opened once more; one that is off has nothing to do,
|
|
42
|
+
* because the next start already reads the new language.
|
|
43
|
+
*/
|
|
44
|
+
languageChanged(): Promise<void>;
|
|
45
|
+
}
|
|
46
|
+
export declare function createVoiceControl(d: VoiceControlDeps): VoiceControl;
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
// SPDX-License-Identifier: AGPL-3.0-or-later
|
|
2
|
+
// ui/voice-control — PLAYING BY VOICE, PUT TOGETHER (ADR-0189, ADR-0193, ADR-0194, ADR-0204 erratum; issues #184, #190).
|
|
3
|
+
//
|
|
4
|
+
// The four pieces that existed separately, joined: the Dev's vocabulary and the firing rule (`input/voice-map`), the recogniser
|
|
5
|
+
// opened from the delivery (`platform/vosk-runtime`), the microphone that stays open (`platform/voice-listener`), and the
|
|
6
|
+
// presses on the virtual controller with the source `fala` (ADR-0111). The 👄 of the quick bar drives it; what cannot start is
|
|
7
|
+
// SAID, written once in `problems`, and puts the icon back to off — a child must never meet a button that does nothing.
|
|
8
|
+
//
|
|
9
|
+
// 📌 THE GRAMMAR FOLLOWS THE MENU (ADR-0194): saying the name of an item activates it, so the words the open menu is showing
|
|
10
|
+
// join the closed grammar while it is open and leave with it.
|
|
11
|
+
//
|
|
12
|
+
// ⚠️ A SPOKEN COMMAND IS A TAP, NOT A HOLD. The word arrives, the position is pressed and let go — and the latch (ADR-0211,
|
|
13
|
+
// always on for speech) is what keeps a direction held afterwards. That division is the whole reason the latch is forced there:
|
|
14
|
+
// a child who says «acima» cannot also say «and keep holding it».
|
|
15
|
+
import { voiceGrammar, createVoiceCommands } from '../input/voice-map.js';
|
|
16
|
+
import { loadVoskRuntime } from '../platform/vosk-runtime.js';
|
|
17
|
+
import { startVoiceListening } from '../platform/voice-listener.js';
|
|
18
|
+
/** How long a spoken position stays pressed. The same pulse the scan uses: long enough for a game to see a press and a release. */
|
|
19
|
+
export const VOICE_PULSE_MS = 400;
|
|
20
|
+
export function createVoiceControl(d) {
|
|
21
|
+
const { t } = d;
|
|
22
|
+
const loadRuntime = d.loadRuntime ?? loadVoskRuntime;
|
|
23
|
+
const listen = d.listen ?? startVoiceListening;
|
|
24
|
+
const said = new Set();
|
|
25
|
+
let on = false, starting = null;
|
|
26
|
+
let listener = null;
|
|
27
|
+
let commands = null;
|
|
28
|
+
const grammarNow = () => voiceGrammar(d.language(), d.menuWords());
|
|
29
|
+
const command = (action) => {
|
|
30
|
+
d.controller.press(action, 'fala');
|
|
31
|
+
d.after(() => d.controller.release(action, 'fala'), VOICE_PULSE_MS);
|
|
32
|
+
};
|
|
33
|
+
const stop = () => {
|
|
34
|
+
const going = listener;
|
|
35
|
+
listener = null;
|
|
36
|
+
commands = null;
|
|
37
|
+
void going?.stop();
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* Nothing started: the child hears why, the adult reads it once, and the icon goes back to off. A failure that arrives after
|
|
41
|
+
* the 👄 was turned off (or the root disposed, ADR-0220) has nobody waiting for it and says and writes nothing.
|
|
42
|
+
*/
|
|
43
|
+
const failed = (kind, line, spoken) => {
|
|
44
|
+
if (!on)
|
|
45
|
+
return;
|
|
46
|
+
if (!said.has(kind)) {
|
|
47
|
+
said.add(kind);
|
|
48
|
+
d.report(line);
|
|
49
|
+
}
|
|
50
|
+
d.alert(spoken);
|
|
51
|
+
d.turnOff();
|
|
52
|
+
};
|
|
53
|
+
const start = async () => {
|
|
54
|
+
/*
|
|
55
|
+
* 🔴 THE LOAD IS INSIDE A `try` AND THIS WAS MEASURED, not foreseen: on 2026-09-21 the delivery's bundle turned out to be an
|
|
56
|
+
* ES module and the loader threw. Nothing here caught it, so the rejection died as an unhandled promise and the 👄 STAYED
|
|
57
|
+
* LIT over a microphone that had never opened — the exact defect this module exists to prevent, one layer above where it
|
|
58
|
+
* was being prevented. A failure that has no name is still a failure the child has to be told about.
|
|
59
|
+
*/
|
|
60
|
+
let load;
|
|
61
|
+
const language = d.language();
|
|
62
|
+
try {
|
|
63
|
+
load = await loadRuntime({ base: d.base, language, hasFile: d.hasFile, loadBundle: d.loadBundle });
|
|
64
|
+
}
|
|
65
|
+
catch (e) {
|
|
66
|
+
failed('runtime', `voice control: the recogniser did not open (${e instanceof Error ? e.message : String(e)}) — the child `
|
|
67
|
+
+ 'cannot play by speaking; check that the delivery carries the command files', t('sr.voice.failed'));
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
if (!load.ok) {
|
|
71
|
+
/*
|
|
72
|
+
* 📌 ONE LINE PER LANGUAGE, NAMING THAT LANGUAGE'S FIX (ADR-0225, ADR-0169). The install fetches the command model of the
|
|
73
|
+
* BOOT language only, so a child who switches can ask for one the delivery never carried; «open it online» alone sends
|
|
74
|
+
* the adult after a download that cannot happen. The reading's line names `--reading <language>` the same way.
|
|
75
|
+
*/
|
|
76
|
+
const lang = language.split('-')[0].toLowerCase();
|
|
77
|
+
failed(`files:${lang}`, `voice control: ${load.missing.join(', ')} not on this device for ${language} — the child cannot play `
|
|
78
|
+
+ `by speaking in this language; build the delivery with \`npx inclusionist-heavy --commands ${lang}\` and open the game `
|
|
79
|
+
+ 'once online in this language so the install fetches them', t('sr.voice.needsInternet'));
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
commands = createVoiceCommands(d.language());
|
|
83
|
+
try {
|
|
84
|
+
listener = await listen({
|
|
85
|
+
model: load.model,
|
|
86
|
+
grammar: grammarNow(),
|
|
87
|
+
getUserMedia: d.getUserMedia,
|
|
88
|
+
createContext: d.createContext,
|
|
89
|
+
onPartial: (text) => { const a = commands?.partial(text); if (a)
|
|
90
|
+
command(a); },
|
|
91
|
+
onFinal: () => commands?.reset(),
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
catch {
|
|
95
|
+
failed('microphone', 'voice control: the microphone did not open — the child cannot play by speaking; allow the microphone '
|
|
96
|
+
+ 'for this page, or plug one in', t('sr.voice.noMicrophone'));
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
// ⚠️ TURNED OFF WHILE IT WAS STARTING: the microphone opened after the child let go of the icon, and a listener nobody asked
|
|
100
|
+
// for would go on hearing her. The check is here and not only in `apply`, because starting is not instantaneous.
|
|
101
|
+
if (!on) {
|
|
102
|
+
stop();
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
d.say(t('sr.voice.ready'));
|
|
106
|
+
};
|
|
107
|
+
const api = {
|
|
108
|
+
async apply(next) {
|
|
109
|
+
on = next;
|
|
110
|
+
if (!next) {
|
|
111
|
+
stop();
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
if (listener || starting)
|
|
115
|
+
return;
|
|
116
|
+
starting = start().finally(() => { starting = null; });
|
|
117
|
+
await starting;
|
|
118
|
+
},
|
|
119
|
+
refreshGrammar() {
|
|
120
|
+
listener?.setGrammar(grammarNow());
|
|
121
|
+
},
|
|
122
|
+
async languageChanged() {
|
|
123
|
+
/*
|
|
124
|
+
* 🔴 THE RECOGNISER STOPS CHOOSING ITS LANGUAGE ONCE (ADR-0225). `start()` reads `d.language()` for the MODEL and for the
|
|
125
|
+
* vocabulary, and it used to read it only at the moment the 👄 was switched on — so a child who changed language while
|
|
126
|
+
* listening went on being heard in the old one.
|
|
127
|
+
* ⚠️ AND THAT IS WORSE THAN STOPPING, which is why this is not cosmetic: the grammar DOES follow, because it is rebuilt
|
|
128
|
+
* whenever a menu opens (ADR-0194). So after a change the new language's words were fed to the old language's model, and
|
|
129
|
+
* a closed grammar answers with the nearest candidate — measured in the lab on 2026-09-14, where «configurações de
|
|
130
|
+
* inclusão» came back as «quatro». A microphone that acts on a word the child did not say is the defect here.
|
|
131
|
+
* 📌 OFF IS ALREADY RIGHT: the next start reads the language then. This only has work to do while it is listening.
|
|
132
|
+
*/
|
|
133
|
+
if (!on)
|
|
134
|
+
return;
|
|
135
|
+
// ⚠️ A START IN FLIGHT IS IN THE OLD LANGUAGE. Letting it finish and replacing it costs one opening; skipping it would
|
|
136
|
+
// leave `starting` to install the old model on top of the new one, which is the race the `if (!on)` in `start` exists for.
|
|
137
|
+
await starting;
|
|
138
|
+
stop();
|
|
139
|
+
await api.apply(true);
|
|
140
|
+
},
|
|
141
|
+
};
|
|
142
|
+
return api;
|
|
143
|
+
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
// SPDX-License-Identifier: AGPL-3.0-or-later
|
|
2
|
+
import type { Translator } from '../core/i18n.js';
|
|
3
|
+
import type { DomQuery } from '../core/dom-query.js';
|
|
4
|
+
import { type AudioCatState } from './audio-choices.js';
|
|
5
|
+
export interface TtsPanelEngine {
|
|
6
|
+
id: string;
|
|
7
|
+
speak: (text: string) => void;
|
|
8
|
+
}
|
|
9
|
+
/** Minimal shape of the injected `tts` (platform/tts.ts's createTts() instance) this section drives. */
|
|
10
|
+
export interface TtsPanel {
|
|
11
|
+
getEngineSel: () => string;
|
|
12
|
+
setEngineSel: (v: string) => void;
|
|
13
|
+
getEngine: () => TtsPanelEngine | null;
|
|
14
|
+
getVoiceObj: () => SpeechSynthesisVoice | null;
|
|
15
|
+
setVoiceObj: (v: SpeechSynthesisVoice | null) => void;
|
|
16
|
+
loadTTS: () => void;
|
|
17
|
+
narrate: (text: string) => void;
|
|
18
|
+
/**
|
|
19
|
+
* Does this assembly have a neural engine (the game's Kokoro port, ADR-0198)? Optional, absent reads `true`: a panel test
|
|
20
|
+
* fake written before this field has no opinion on neural engines.
|
|
21
|
+
*/
|
|
22
|
+
neuralAvailable?: boolean;
|
|
23
|
+
/** The voices of the language (ADR-0185). Optional: a panel driven without them offers no «Voz» list and locks nothing. */
|
|
24
|
+
voices?: () => readonly PanelVoice[];
|
|
25
|
+
currentVoice?: () => PanelVoice | null;
|
|
26
|
+
setVoice?: (id: string) => boolean;
|
|
27
|
+
}
|
|
28
|
+
/** A voice as this panel lists it: `webspeech:<name>` for the browser's, `xx_name` for Kokoro's. */
|
|
29
|
+
export interface PanelVoice {
|
|
30
|
+
readonly voice: string;
|
|
31
|
+
readonly engine?: string;
|
|
32
|
+
readonly recommended?: boolean;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* The browser, as four functions.
|
|
36
|
+
*
|
|
37
|
+
* 🔴 A module that reaches `document` or `window` undoes a decision (ADR-0178), and the health ratchet refuses a NEW one that
|
|
38
|
+
* does. These four are what the voice section actually needs from the browser, and naming them is what makes the section
|
|
39
|
+
* testable: hand it a fake `doc`, a list of voices and two no-ops, and every branch below runs without a speech engine.
|
|
40
|
+
*/
|
|
41
|
+
export interface VoicePorts {
|
|
42
|
+
/** Makes one <option> — the only element this section builds. A FUNCTION and not the document: a port read at wiring
|
|
43
|
+
* time would make a panel unmountable where there is no document yet, and the node suite mounts exactly there. */
|
|
44
|
+
readonly newOption: () => HTMLOptionElement;
|
|
45
|
+
/** The system voices, or an empty list where the browser has none or throws. */
|
|
46
|
+
readonly systemVoices: () => readonly SpeechSynthesisVoice[];
|
|
47
|
+
/** Speak the sample through the BROWSER's own synthesiser — the neural engine speaks through `tts` instead. */
|
|
48
|
+
readonly speakSample: (text: string, chosen: SpeechSynthesisVoice | null) => void;
|
|
49
|
+
/** Called again whenever the browser finishes loading its voice list: they arrive late, and often empty first.
|
|
50
|
+
* ⚠️ The parameter is gain and not
|
|
51
|
+
un, which is a GAME ACTION word this layer does not say (the boundary of 2026-09-06). */
|
|
52
|
+
readonly whenVoicesChange: (again: () => void) => void;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* What this section needs from the panel's ctx.
|
|
56
|
+
*
|
|
57
|
+
* ⚠️ The store shape is written here and NOT imported from `ui/settings-audio`, which declares the same two methods: that
|
|
58
|
+
* module imports this one, and importing it back would be the cycle ADR-0173 forbids — for a type as much as for a value.
|
|
59
|
+
*/
|
|
60
|
+
/**
|
|
61
|
+
* THE SETTINGS THIS SECTION READS AND WRITES — the page's settings store, built by the root (ADR-0232 D2c, issue #207): the
|
|
62
|
+
* spoken index (ADR-0044 item 3) and the speech rate (ADR-0183). The names are `core/state`'s, so a root passes the store
|
|
63
|
+
* itself; the reads are LIVE, because the quick bar and a second screen change them too.
|
|
64
|
+
*/
|
|
65
|
+
export interface VoiceSettingsStore {
|
|
66
|
+
readonly menuIndexOn: boolean;
|
|
67
|
+
setMenuIndexOnValue(on: boolean): void;
|
|
68
|
+
readonly speechPpm: number;
|
|
69
|
+
setSpeechPpmValue(ppm: number): void;
|
|
70
|
+
}
|
|
71
|
+
export interface VoiceSettingsCtx {
|
|
72
|
+
/**
|
|
73
|
+
* The root's translator (ADR-0232 D3): its `t`, and the page's language as a BCP-47 tag, which picks the system voices the
|
|
74
|
+
* list offers. A Pick and not a bare `t`, because the voice list reads the language.
|
|
75
|
+
*/
|
|
76
|
+
translator: Pick<Translator, 't' | 'bcp47'>;
|
|
77
|
+
/** The page's settings store (see `VoiceSettingsStore`). REQUIRED: a section reading from nowhere would show the defaults. */
|
|
78
|
+
settings: VoiceSettingsStore;
|
|
79
|
+
$: DomQuery;
|
|
80
|
+
srSay: (msg: string) => void;
|
|
81
|
+
toggleBtn: (btn: HTMLElement, on: boolean) => void;
|
|
82
|
+
store: {
|
|
83
|
+
get(key: string, fallback?: string | null): string | null;
|
|
84
|
+
set(key: string, value: string | number | boolean): boolean;
|
|
85
|
+
};
|
|
86
|
+
tts: TtsPanel;
|
|
87
|
+
getAudioCat: () => Record<string, AudioCatState> | null;
|
|
88
|
+
setCatGain: (k: string) => void;
|
|
89
|
+
}
|
|
90
|
+
export interface VoiceSettings {
|
|
91
|
+
/** Everything the section shows, refreshed from the stored state. Called by the panel's own render. */
|
|
92
|
+
render: () => void;
|
|
93
|
+
/** Just the narration switch and the chosen engine. Exported because the quick bar's icon reflects it from outside. */
|
|
94
|
+
reflectTts: () => void;
|
|
95
|
+
}
|
|
96
|
+
export declare function createVoiceSettings(ctx: VoiceSettingsCtx, ports: VoicePorts): VoiceSettings;
|
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
// SPDX-License-Identifier: AGPL-3.0-or-later
|
|
2
|
+
// ui/voice-settings — THE VOICE SECTION of the hearing panel: the narration switch, the engine, the voice, the rate, the
|
|
3
|
+
// spoken index and the sample button (ADR-0221; issue #203).
|
|
4
|
+
//
|
|
5
|
+
// 🔴 WHY IT LEFT `ui/settings-audio`: that module was the third largest in the engine, and half of it was about SPEECH while
|
|
6
|
+
// the other half was about sound categories, the cane, blind mode and the audio outputs. The two halves never needed each
|
|
7
|
+
// other. What binds these seven pieces is one question — «what does the child hear when the engine talks, and what does she
|
|
8
|
+
// change to hear it differently».
|
|
9
|
+
//
|
|
10
|
+
// ⚠️ AND IT RECEIVES THE BROWSER INSTEAD OF REACHING IT, which the ratchet of ADR-0221 step 7d made compulsory rather than
|
|
11
|
+
// tasteful: a module born today that reaches a global is refused, because there the ceiling is ZERO and not a p90. So
|
|
12
|
+
// `document.createElement`, `speechSynthesis.getVoices`, the sample utterance and the `onvoiceschanged` subscription arrive
|
|
13
|
+
// as four ports. What that buys beyond the gate: the whole section can be exercised without a browser's speech engine.
|
|
14
|
+
//
|
|
15
|
+
// 📌 THE SPOKEN INDEX («6 of 10») LIVES HERE and not in a visual panel, by the decision of ADR-0044 item 3: it changes the
|
|
16
|
+
// NARRATION, and whoever turns it off is shortening what she hears at every step. She comes here when what she hears bothers
|
|
17
|
+
// her.
|
|
18
|
+
import { toggleLabel } from './dom.js';
|
|
19
|
+
import { SPEECH_RATES } from '../core/speech-rate.js';
|
|
20
|
+
import { volPercent, voiceEngineOptions, pickVoicesFor, voiceLabel, } from './audio-choices.js';
|
|
21
|
+
/** The name a child sees for a voice: the browser's name, or the name inside a Kokoro identifier — `pf_dora` is «Dora». */
|
|
22
|
+
function voiceName(v) {
|
|
23
|
+
// a browser voice is named by the browser (ADR-0200); Kokoro ids read `xx_name` (`pf_dora`)
|
|
24
|
+
// («Microsoft Maria - Portuguese (Brazil)» is «Microsoft Maria»: the language is already the list's, and no parentheses, ADR-0158)
|
|
25
|
+
if (v.voice.startsWith('webspeech:'))
|
|
26
|
+
return v.voice.slice('webspeech:'.length).replace(/\s*\([^)]*\)/g, '').split(' - ')[0].trim();
|
|
27
|
+
const name = v.voice.split('_')[1] ?? v.voice;
|
|
28
|
+
return name.charAt(0).toUpperCase() + name.slice(1);
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* What the list SHOWS: Kokoro's two good voices, Heart and Bella, carry a heart (ADR-0198 §3). Only SHOWN: what is said is
|
|
32
|
+
* the name alone (ADR-0159 rule 12, no glyph inside a spoken name).
|
|
33
|
+
*/
|
|
34
|
+
function panelVoiceLabel(v) {
|
|
35
|
+
return (v.recommended ? '❤️ ' : '') + voiceName(v);
|
|
36
|
+
}
|
|
37
|
+
/** The rows a missing voice locks (ADR-0185 §4): narration, its volume and rate, the spoken index, and the voice. */
|
|
38
|
+
const SPEECH_ROWS = ['#opt-tts', '#tts-vol', '#tts-ppm', '#opt-menuindex', '#tts-voz'];
|
|
39
|
+
export function createVoiceSettings(ctx, ports) {
|
|
40
|
+
const { t, bcp47 } = ctx.translator;
|
|
41
|
+
function reflectTts() {
|
|
42
|
+
const b = ctx.$('#opt-tts');
|
|
43
|
+
const cat = ctx.getAudioCat();
|
|
44
|
+
const on = !!(cat && cat.tts && cat.tts.on);
|
|
45
|
+
if (b) {
|
|
46
|
+
ctx.toggleBtn(b, on);
|
|
47
|
+
b.textContent = toggleLabel(t, on);
|
|
48
|
+
}
|
|
49
|
+
const e = ctx.$('#tts-engine');
|
|
50
|
+
if (e)
|
|
51
|
+
e.value = ctx.tts.getEngineSel();
|
|
52
|
+
}
|
|
53
|
+
function reflectMenuIndex() {
|
|
54
|
+
const b = ctx.$('#opt-menuindex');
|
|
55
|
+
if (b) {
|
|
56
|
+
ctx.toggleBtn(b, ctx.settings.menuIndexOn);
|
|
57
|
+
b.textContent = toggleLabel(t, ctx.settings.menuIndexOn);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
function populateTtsEngines() {
|
|
61
|
+
const sel = ctx.$('#tts-engine');
|
|
62
|
+
if (!sel || sel.dataset.filled)
|
|
63
|
+
return;
|
|
64
|
+
sel.dataset.filled = '1';
|
|
65
|
+
voiceEngineOptions(ctx.tts.neuralAvailable !== false).forEach(([v, l]) => {
|
|
66
|
+
const o = ports.newOption();
|
|
67
|
+
o.value = v;
|
|
68
|
+
o.textContent = t(l);
|
|
69
|
+
sel.appendChild(o);
|
|
70
|
+
});
|
|
71
|
+
sel.value = ctx.tts.getEngineSel();
|
|
72
|
+
}
|
|
73
|
+
function populateTtsVoices() {
|
|
74
|
+
const sel = ctx.$('#tts-voice');
|
|
75
|
+
if (!sel)
|
|
76
|
+
return;
|
|
77
|
+
const list = pickVoicesFor(ports.systemVoices(), bcp47());
|
|
78
|
+
sel.innerHTML = '';
|
|
79
|
+
if (!list.length) {
|
|
80
|
+
const o = ports.newOption();
|
|
81
|
+
o.textContent = t('audio.noSystemVoices');
|
|
82
|
+
sel.appendChild(o);
|
|
83
|
+
ctx.tts.setVoiceObj(null);
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
list.forEach((v) => {
|
|
87
|
+
const o = ports.newOption();
|
|
88
|
+
o.value = v.name;
|
|
89
|
+
o.textContent = voiceLabel(v);
|
|
90
|
+
sel.appendChild(o);
|
|
91
|
+
});
|
|
92
|
+
const saved = ctx.store.get('incl_tts_voice', null);
|
|
93
|
+
const pick = list.find((v) => v.name === saved) || list[0];
|
|
94
|
+
sel.value = pick.name;
|
|
95
|
+
ctx.tts.setVoiceObj(pick);
|
|
96
|
+
}
|
|
97
|
+
const noVoice = () => !!ctx.tts.voices && ctx.tts.voices().length === 0;
|
|
98
|
+
/** The speech rate list: each step «N PPM», the stored one selected (ADR-0183 §1, ADR-0196). */
|
|
99
|
+
function renderRate() {
|
|
100
|
+
const sel = ctx.$('#tts-ppm');
|
|
101
|
+
if (!sel)
|
|
102
|
+
return;
|
|
103
|
+
while (sel.firstChild)
|
|
104
|
+
sel.removeChild(sel.firstChild);
|
|
105
|
+
for (const ppm of SPEECH_RATES) {
|
|
106
|
+
const o = ports.newOption();
|
|
107
|
+
o.value = String(ppm);
|
|
108
|
+
o.textContent = t('visual.legenda.ppm', { n: ppm });
|
|
109
|
+
sel.appendChild(o);
|
|
110
|
+
}
|
|
111
|
+
sel.value = String(ctx.settings.speechPpm);
|
|
112
|
+
}
|
|
113
|
+
function renderVoiceList() {
|
|
114
|
+
const sel = ctx.$('#tts-voz');
|
|
115
|
+
if (!sel || !ctx.tts.voices)
|
|
116
|
+
return;
|
|
117
|
+
const list = ctx.tts.voices();
|
|
118
|
+
sel.replaceChildren(); // options built node by node: no markup sink
|
|
119
|
+
if (!list.length) {
|
|
120
|
+
const o = ports.newOption();
|
|
121
|
+
o.textContent = t('audio.voz.nenhuma');
|
|
122
|
+
sel.appendChild(o);
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
for (const v of list) {
|
|
126
|
+
const o = ports.newOption();
|
|
127
|
+
o.value = v.voice;
|
|
128
|
+
o.textContent = panelVoiceLabel(v);
|
|
129
|
+
sel.appendChild(o);
|
|
130
|
+
}
|
|
131
|
+
sel.value = ctx.tts.currentVoice?.()?.voice ?? list[0].voice;
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* No voice speaks the language (ADR-0185 §4): the five speech rows are LOCKED with the reason, never hidden (ADR-0161).
|
|
135
|
+
* `aria-disabled` and not `disabled`, so the keyboard still reaches the row and hears why.
|
|
136
|
+
*/
|
|
137
|
+
function lockSpeechRows() {
|
|
138
|
+
const lock = noVoice();
|
|
139
|
+
for (const id of SPEECH_ROWS) {
|
|
140
|
+
const el = ctx.$(id);
|
|
141
|
+
if (!el)
|
|
142
|
+
continue;
|
|
143
|
+
if (lock) {
|
|
144
|
+
el.setAttribute('aria-disabled', 'true');
|
|
145
|
+
el.dataset.motivo = t('audio.semVoz');
|
|
146
|
+
}
|
|
147
|
+
else {
|
|
148
|
+
el.removeAttribute('aria-disabled');
|
|
149
|
+
delete el.dataset.motivo;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
/*
|
|
154
|
+
* A LOCKED SPEECH ROW DOES NOTHING AND SAYS WHY (ADR-0185 §4). In the CAPTURE phase on the control itself, so it runs
|
|
155
|
+
* before the row's own listener and stops it; a moved range goes back to the stored volume, a changed list to the voice in
|
|
156
|
+
* use. The footer shows the reason when the row takes focus: the card hears `focusin` after the row's own explanation.
|
|
157
|
+
*/
|
|
158
|
+
/**
|
|
159
|
+
* What a refused control puts back, by row: the moved volume to the stored one, the picked voice and rate to the ones in use.
|
|
160
|
+
* A row not here has nothing to undo (a switch was never flipped). A table, as the other «which row does what» answers here.
|
|
161
|
+
*/
|
|
162
|
+
const UNDO_ON_REFUSAL = {
|
|
163
|
+
'#tts-vol': (el) => { const cat = ctx.getAudioCat(); if (cat?.tts)
|
|
164
|
+
el.value = String(volPercent(cat.tts.vol)); },
|
|
165
|
+
'#tts-voz': () => renderVoiceList(),
|
|
166
|
+
'#tts-ppm': () => renderRate(),
|
|
167
|
+
};
|
|
168
|
+
function refuseWhileLocked() {
|
|
169
|
+
for (const id of SPEECH_ROWS) {
|
|
170
|
+
const el = ctx.$(id);
|
|
171
|
+
if (!el)
|
|
172
|
+
continue;
|
|
173
|
+
const refuse = (e) => {
|
|
174
|
+
if (el.getAttribute('aria-disabled') !== 'true')
|
|
175
|
+
return;
|
|
176
|
+
e.stopImmediatePropagation();
|
|
177
|
+
e.preventDefault();
|
|
178
|
+
UNDO_ON_REFUSAL[id]?.(el);
|
|
179
|
+
ctx.srSay(el.dataset.motivo ?? t('audio.semVoz'));
|
|
180
|
+
};
|
|
181
|
+
for (const kind of ['click', 'input', 'change'])
|
|
182
|
+
el.addEventListener(kind, refuse, true);
|
|
183
|
+
el.closest('.overlay__card')?.addEventListener('focusin', (e) => {
|
|
184
|
+
if (e.target !== el || el.getAttribute('aria-disabled') !== 'true')
|
|
185
|
+
return;
|
|
186
|
+
const footer = el.closest('.overlay__card')?.querySelector('.opt-explain');
|
|
187
|
+
if (footer)
|
|
188
|
+
footer.textContent = el.dataset.motivo ?? '';
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
refuseWhileLocked();
|
|
193
|
+
/**
|
|
194
|
+
* THE SEVEN CONTROLS, wired where the page carries them: the voice list, the rate, the narration switch, the spoken
|
|
195
|
+
* index, and the three the engine never builds but a page may (the engine selector, the system voice, the sample).
|
|
196
|
+
* A page that lacks one simply has that row missing.
|
|
197
|
+
*/
|
|
198
|
+
function wireControls() {
|
|
199
|
+
const voiceSel = ctx.$('#tts-voz');
|
|
200
|
+
if (voiceSel)
|
|
201
|
+
voiceSel.addEventListener('change', () => {
|
|
202
|
+
if (!ctx.tts.setVoice?.(voiceSel.value)) {
|
|
203
|
+
renderVoiceList();
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
const v = ctx.tts.currentVoice?.();
|
|
207
|
+
if (v)
|
|
208
|
+
ctx.srSay(t('sr.audio.voz', { nome: voiceName(v) }));
|
|
209
|
+
});
|
|
210
|
+
const rateSel = ctx.$('#tts-ppm');
|
|
211
|
+
if (rateSel)
|
|
212
|
+
rateSel.addEventListener('change', () => {
|
|
213
|
+
ctx.settings.setSpeechPpmValue(Number(rateSel.value));
|
|
214
|
+
renderRate();
|
|
215
|
+
ctx.srSay(`${t('audio.ttsPpm')}: ${t('visual.legenda.ppm', { n: ctx.settings.speechPpm })}`);
|
|
216
|
+
});
|
|
217
|
+
const ttsBtn = ctx.$('#opt-tts');
|
|
218
|
+
if (ttsBtn)
|
|
219
|
+
ttsBtn.addEventListener('click', () => {
|
|
220
|
+
const cat = ctx.getAudioCat();
|
|
221
|
+
if (!cat)
|
|
222
|
+
return;
|
|
223
|
+
cat.tts.on = !cat.tts.on;
|
|
224
|
+
ctx.setCatGain('tts');
|
|
225
|
+
reflectTts();
|
|
226
|
+
ctx.srSay(t(cat.tts.on ? 'sr.audio.ttsOn' : 'sr.audio.ttsOff'));
|
|
227
|
+
if (cat.tts.on)
|
|
228
|
+
ctx.tts.narrate(t('sr.audio.ttsOnSpoken'));
|
|
229
|
+
});
|
|
230
|
+
const idxBtn = ctx.$('#opt-menuindex');
|
|
231
|
+
if (idxBtn)
|
|
232
|
+
idxBtn.addEventListener('click', () => {
|
|
233
|
+
ctx.settings.setMenuIndexOnValue(!ctx.settings.menuIndexOn);
|
|
234
|
+
reflectMenuIndex();
|
|
235
|
+
// The announcement of the change carries NO index: it is not an item of any list, and a «1 of 1» here would be noise at
|
|
236
|
+
// exactly the moment the child is judging whether the noise bothers her.
|
|
237
|
+
ctx.srSay(t(ctx.settings.menuIndexOn ? 'sr.menu.indexOn' : 'sr.menu.indexOff'));
|
|
238
|
+
});
|
|
239
|
+
const ttsEngSel = ctx.$('#tts-engine');
|
|
240
|
+
if (ttsEngSel)
|
|
241
|
+
ttsEngSel.addEventListener('change', () => {
|
|
242
|
+
ctx.tts.setEngineSel(ttsEngSel.value);
|
|
243
|
+
ctx.store.set('incl_tts_engine', ttsEngSel.value);
|
|
244
|
+
if (ttsEngSel.value !== 'webspeech')
|
|
245
|
+
ctx.tts.loadTTS();
|
|
246
|
+
const opt = ttsEngSel.options[ttsEngSel.selectedIndex];
|
|
247
|
+
ctx.tts.narrate(t('sr.audio.engineSet', { motor: opt ? opt.text : '' }));
|
|
248
|
+
});
|
|
249
|
+
const ttsVoiceSel = ctx.$('#tts-voice');
|
|
250
|
+
if (ttsVoiceSel)
|
|
251
|
+
ttsVoiceSel.addEventListener('change', () => {
|
|
252
|
+
ctx.tts.setVoiceObj(ports.systemVoices().find((v) => v.name === ttsVoiceSel.value) || null);
|
|
253
|
+
ctx.store.set('incl_tts_voice', ttsVoiceSel.value);
|
|
254
|
+
ctx.tts.narrate(t('sr.audio.voicePicked'));
|
|
255
|
+
});
|
|
256
|
+
const ttsTestBtn = ctx.$('#opt-tts-test');
|
|
257
|
+
if (ttsTestBtn)
|
|
258
|
+
ttsTestBtn.addEventListener('click', () => {
|
|
259
|
+
const sample = t('audio.voiceSample');
|
|
260
|
+
const engine = ctx.tts.getEngine();
|
|
261
|
+
if (ctx.tts.getEngineSel() !== 'webspeech' && engine && engine.speak) {
|
|
262
|
+
try {
|
|
263
|
+
engine.speak(sample);
|
|
264
|
+
}
|
|
265
|
+
catch (e) { /* noop */ } // the neural engine is already loaded
|
|
266
|
+
}
|
|
267
|
+
else {
|
|
268
|
+
ports.speakSample(sample, ctx.tts.getVoiceObj()); // audible fallback (volume 1) + starts the neural download
|
|
269
|
+
if (ctx.tts.getEngineSel() !== 'webspeech')
|
|
270
|
+
ctx.tts.loadTTS();
|
|
271
|
+
}
|
|
272
|
+
ctx.srSay(t('sr.audio.testingVoice'));
|
|
273
|
+
});
|
|
274
|
+
const ttsVolEl = ctx.$('#tts-vol');
|
|
275
|
+
if (ttsVolEl)
|
|
276
|
+
ttsVolEl.addEventListener('input', () => {
|
|
277
|
+
const cat = ctx.getAudioCat();
|
|
278
|
+
if (!cat)
|
|
279
|
+
return;
|
|
280
|
+
cat.tts.vol = (+ttsVolEl.value) / 100;
|
|
281
|
+
cat.tts.on = true;
|
|
282
|
+
ctx.setCatGain('tts');
|
|
283
|
+
reflectTts();
|
|
284
|
+
});
|
|
285
|
+
}
|
|
286
|
+
wireControls();
|
|
287
|
+
ports.whenVoicesChange(populateTtsVoices);
|
|
288
|
+
return {
|
|
289
|
+
render: () => {
|
|
290
|
+
reflectTts();
|
|
291
|
+
// 🔴 THIS ONE WAS MISSING, and only the case for the engine-mounted panel saw it (2026-09-12): the index is born ON, the
|
|
292
|
+
// button was born with no state, and the panel opened saying «off» — the control lying to the screen reader again.
|
|
293
|
+
reflectMenuIndex();
|
|
294
|
+
populateTtsEngines();
|
|
295
|
+
populateTtsVoices();
|
|
296
|
+
renderVoiceList();
|
|
297
|
+
renderRate();
|
|
298
|
+
lockSpeechRows();
|
|
299
|
+
},
|
|
300
|
+
reflectTts,
|
|
301
|
+
};
|
|
302
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
// SPDX-License-Identifier: AGPL-3.0-or-later
|
|
2
|
+
import type { Translate } from '../core/i18n.js';
|
|
3
|
+
export interface WhereTheChildIsCtx {
|
|
4
|
+
/** Translates in the page's language — the root's translator (ADR-0232 D3). REQUIRED: text built from nowhere is a raw key. */
|
|
5
|
+
t: Translate;
|
|
6
|
+
/** The overlay on top, if any — the same one the focus trap and the menu navigation treat as «the open menu». */
|
|
7
|
+
readonly topVisibleOverlay: () => HTMLElement | null;
|
|
8
|
+
/** The pause card, when it is showing. */
|
|
9
|
+
readonly pauseCard: () => HTMLElement | null;
|
|
10
|
+
/** Who has the focus right now: it decides WHICH item of a panel is named. */
|
|
11
|
+
readonly focused: () => Element | null;
|
|
12
|
+
/**
|
|
13
|
+
* Does this cartridge want «N of M» spoken (ADR-0167)? It is only ever SPOKEN — never drawn — and a cartridge may
|
|
14
|
+
* silence it.
|
|
15
|
+
*/
|
|
16
|
+
readonly withIndex: () => boolean;
|
|
17
|
+
}
|
|
18
|
+
/** Where the child is: a key to compare, and the sentence to say when it changed. */
|
|
19
|
+
export interface Place {
|
|
20
|
+
/** What «did she move?» is decided on. It names the panel or the card's open list, never just «a panel». */
|
|
21
|
+
readonly key: string;
|
|
22
|
+
/** What to say on arriving here — `null` in play, which is announced by the caller in its own words. */
|
|
23
|
+
readonly sentence: string | null;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* The place, in the order the screen reads: a panel sits over the card, the card sits over the game.
|
|
27
|
+
*
|
|
28
|
+
* 📌 PLAY HAS NO SENTENCE HERE and that is deliberate: «back to the game» is the caller's word for its own world, and
|
|
29
|
+
* this module has no business naming a game it does not know.
|
|
30
|
+
*/
|
|
31
|
+
export declare function whereTheChildIs(ctx: WhereTheChildIsCtx): Place;
|