@the-inclusionist/engine 10.0.0 → 11.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +32 -1
- package/app/css/style.css +216 -42
- package/app/public/vendor/fonts-licences/NOTICE.txt +166 -0
- package/app/public/vendor/fonts-licences/OFL-1.1.txt +86 -0
- package/app/public/vendor/fonts.css +11 -1175
- package/dist-pkg/boot/create-game.d.ts +84 -33
- package/dist-pkg/boot/create-game.js +708 -307
- package/dist-pkg/core/a11y-sr.d.ts +1 -1
- package/dist-pkg/core/a11y-sr.js +3 -5
- package/dist-pkg/core/accommodations.d.ts +26 -8
- package/dist-pkg/core/accommodations.js +27 -10
- package/dist-pkg/core/actions.d.ts +39 -10
- package/dist-pkg/core/actions.js +28 -6
- package/dist-pkg/core/contract.d.ts +0 -2
- package/dist-pkg/core/contract.js +0 -2
- package/dist-pkg/core/i18n.d.ts +36 -71
- package/dist-pkg/core/i18n.js +131 -198
- package/dist-pkg/core/session-clock.d.ts +23 -0
- package/dist-pkg/core/session-clock.js +37 -0
- package/dist-pkg/i18n/en.js +44 -49
- package/dist-pkg/i18n/es.js +44 -49
- package/dist-pkg/i18n/pt.js +49 -54
- package/dist-pkg/input/gamepad.d.ts +42 -11
- package/dist-pkg/input/gamepad.js +50 -15
- package/dist-pkg/input/key-default.d.ts +30 -0
- package/dist-pkg/input/key-default.js +60 -0
- package/dist-pkg/input/keyboard-runtime.d.ts +0 -4
- package/dist-pkg/input/keyboard.d.ts +0 -1
- package/dist-pkg/input/keydown.d.ts +5 -11
- package/dist-pkg/input/keydown.js +3 -3
- package/dist-pkg/input/latch-edge.d.ts +10 -2
- package/dist-pkg/input/latch-edge.js +4 -3
- package/dist-pkg/input/latch-scope.d.ts +27 -22
- package/dist-pkg/input/latch-scope.js +25 -37
- package/dist-pkg/input/latch-store.d.ts +9 -12
- package/dist-pkg/input/latch-store.js +13 -18
- package/dist-pkg/input/latch-sync.d.ts +5 -4
- package/dist-pkg/input/latch-sync.js +5 -5
- package/dist-pkg/input/pad-reading.js +7 -2
- package/dist-pkg/input/pad-wizard.d.ts +4 -1
- package/dist-pkg/input/pad-wizard.js +60 -9
- package/dist-pkg/input/switch-scan.d.ts +29 -12
- package/dist-pkg/input/switch-scan.js +15 -2
- package/dist-pkg/input/touch-bindings.d.ts +3 -6
- package/dist-pkg/input/touch.d.ts +17 -2
- package/dist-pkg/input/touch.js +55 -17
- package/dist-pkg/input/transport-in-use.d.ts +5 -5
- package/dist-pkg/input/transport-in-use.js +5 -5
- package/dist-pkg/input/transports.d.ts +0 -9
- package/dist-pkg/input/transports.js +1 -1
- package/dist-pkg/input/virtual-controller.d.ts +39 -3
- package/dist-pkg/input/virtual-controller.js +32 -4
- package/dist-pkg/input/voice-map.d.ts +27 -11
- package/dist-pkg/input/voice-map.js +41 -43
- package/dist-pkg/platform/audio-ambient.d.ts +0 -1
- package/dist-pkg/platform/audio-ambient.js +3 -1
- package/dist-pkg/platform/audio-mixer.js +4 -9
- package/dist-pkg/platform/audio-sonar.d.ts +8 -94
- package/dist-pkg/platform/audio-sonar.js +22 -207
- package/dist-pkg/platform/audio.d.ts +10 -1
- package/dist-pkg/platform/audio.js +35 -2
- package/dist-pkg/platform/choose-by-voice.d.ts +70 -0
- package/dist-pkg/platform/choose-by-voice.js +157 -0
- package/dist-pkg/platform/font-library.d.ts +77 -0
- package/dist-pkg/platform/font-library.js +98 -0
- package/dist-pkg/platform/font-library.json +721 -0
- package/dist-pkg/platform/heavy-catalogue.d.ts +46 -0
- package/dist-pkg/platform/heavy-catalogue.js +47 -14
- package/dist-pkg/platform/heavy-mirror.d.ts +3 -9
- package/dist-pkg/platform/heavy-mirror.js +14 -17
- package/dist-pkg/platform/heavy.d.ts +40 -8
- package/dist-pkg/platform/heavy.js +177 -22
- package/dist-pkg/platform/interruptible-speech.d.ts +15 -8
- package/dist-pkg/platform/interruptible-speech.js +37 -13
- package/dist-pkg/platform/listener-scope.js +22 -13
- package/dist-pkg/platform/locale-host.d.ts +7 -3
- package/dist-pkg/platform/locale-host.js +13 -2
- package/dist-pkg/platform/reading-in-worker.d.ts +24 -0
- package/dist-pkg/platform/reading-in-worker.js +38 -0
- package/dist-pkg/platform/reading-model.d.ts +21 -0
- package/dist-pkg/platform/reading-model.js +25 -0
- package/dist-pkg/platform/reading-runtime.js +13 -8
- package/dist-pkg/platform/reading.d.ts +12 -1
- package/dist-pkg/platform/reading.js +9 -1
- package/dist-pkg/platform/speech-recognition.d.ts +10 -1
- package/dist-pkg/platform/speech-recognition.js +29 -9
- package/dist-pkg/platform/speech.d.ts +10 -1
- package/dist-pkg/platform/speech.js +24 -13
- package/dist-pkg/platform/tts.d.ts +37 -4
- package/dist-pkg/platform/tts.js +279 -57
- package/dist-pkg/platform/voice-listener.d.ts +6 -2
- package/dist-pkg/platform/voice-listener.js +1 -1
- package/dist-pkg/platform/voice-plan.d.ts +13 -0
- package/dist-pkg/platform/voice-plan.js +57 -2
- package/dist-pkg/platform/vosk-runtime.d.ts +25 -0
- package/dist-pkg/platform/vosk-runtime.js +59 -1
- package/dist-pkg/platform/vosk-vocabulary.d.ts +6 -0
- package/dist-pkg/platform/vosk-vocabulary.js +178 -0
- package/dist-pkg/render/crt.d.ts +11 -9
- package/dist-pkg/render/crt.js +6 -10
- package/dist-pkg/render/cvd-matrices.d.ts +5 -1
- package/dist-pkg/render/cvd-matrices.js +5 -1
- package/dist-pkg/render/high-contrast.d.ts +1 -2
- package/dist-pkg/render/high-contrast.js +5 -1
- package/dist-pkg/render/viz-axes.d.ts +9 -0
- package/dist-pkg/render/viz-axes.js +15 -2
- package/dist-pkg/ui/aac-sets.d.ts +29 -24
- package/dist-pkg/ui/aac-sets.js +22 -30
- package/dist-pkg/ui/audio-choices.d.ts +10 -5
- package/dist-pkg/ui/audio-choices.js +14 -10
- package/dist-pkg/ui/camera-control.d.ts +47 -0
- package/dist-pkg/ui/camera-control.js +35 -1
- package/dist-pkg/ui/declared-words.d.ts +21 -0
- package/dist-pkg/ui/declared-words.js +66 -0
- package/dist-pkg/ui/drawing-problems.js +4 -3
- package/dist-pkg/ui/eye-control.js +17 -17
- package/dist-pkg/ui/face-control.js +15 -15
- package/dist-pkg/ui/fonts.d.ts +42 -8
- package/dist-pkg/ui/fonts.js +58 -24
- package/dist-pkg/ui/footer-scroll-driver.d.ts +14 -0
- package/dist-pkg/ui/footer-scroll-driver.js +201 -0
- package/dist-pkg/ui/footer-scroll.d.ts +38 -0
- package/dist-pkg/ui/footer-scroll.js +55 -0
- package/dist-pkg/ui/game-options.d.ts +14 -9
- package/dist-pkg/ui/game-options.js +41 -21
- package/dist-pkg/ui/hand-control.js +15 -15
- package/dist-pkg/ui/help-panel.d.ts +19 -8
- package/dist-pkg/ui/help-panel.js +15 -5
- package/dist-pkg/ui/hud-bands.d.ts +29 -12
- package/dist-pkg/ui/hud-bands.js +63 -25
- package/dist-pkg/ui/hud-row.d.ts +34 -0
- package/dist-pkg/ui/hud-row.js +80 -0
- package/dist-pkg/ui/hud.d.ts +0 -3
- package/dist-pkg/ui/layout.js +5 -2
- package/dist-pkg/ui/libras-avatar-clip.d.ts +30 -0
- package/dist-pkg/ui/libras-avatar-clip.js +86 -0
- package/dist-pkg/ui/libras-avatar-load.d.ts +52 -0
- package/dist-pkg/ui/libras-avatar-load.js +134 -0
- package/dist-pkg/ui/libras-avatar-plan.d.ts +102 -0
- package/dist-pkg/ui/libras-avatar-plan.js +211 -0
- package/dist-pkg/ui/libras-avatar-player.d.ts +28 -0
- package/dist-pkg/ui/libras-avatar-player.js +226 -0
- package/dist-pkg/ui/libras-avatar-stage.d.ts +37 -0
- package/dist-pkg/ui/libras-avatar-stage.js +208 -0
- package/dist-pkg/ui/libras-glosses.d.ts +28 -0
- package/dist-pkg/ui/libras-glosses.js +161 -0
- package/dist-pkg/ui/menu-intent.d.ts +29 -0
- package/dist-pkg/ui/menu-intent.js +35 -1
- package/dist-pkg/ui/menu-items.d.ts +10 -0
- package/dist-pkg/ui/menu-items.js +29 -0
- package/dist-pkg/ui/menu-nav.d.ts +40 -4
- package/dist-pkg/ui/menu-nav.js +132 -47
- package/dist-pkg/ui/panel-widgets.d.ts +34 -0
- package/dist-pkg/ui/panel-widgets.js +86 -0
- package/dist-pkg/ui/pause-icons.d.ts +30 -14
- package/dist-pkg/ui/pause-icons.js +106 -45
- package/dist-pkg/ui/scan-overlay.d.ts +3 -3
- package/dist-pkg/ui/scan-overlay.js +11 -3
- package/dist-pkg/ui/screen-text.d.ts +25 -0
- package/dist-pkg/ui/screen-text.js +152 -0
- package/dist-pkg/ui/session-clock.d.ts +32 -0
- package/dist-pkg/ui/session-clock.js +67 -0
- package/dist-pkg/ui/settings-aac.d.ts +3 -1
- package/dist-pkg/ui/settings-aac.js +32 -13
- package/dist-pkg/ui/settings-audio.d.ts +10 -5
- package/dist-pkg/ui/settings-audio.js +101 -35
- package/dist-pkg/ui/settings-controls.d.ts +0 -4
- package/dist-pkg/ui/settings-mobility.d.ts +3 -6
- package/dist-pkg/ui/settings-mobility.js +4 -46
- package/dist-pkg/ui/settings-motion.js +2 -2
- package/dist-pkg/ui/settings-panel.d.ts +10 -0
- package/dist-pkg/ui/settings-panel.js +25 -1
- package/dist-pkg/ui/settings-typo.d.ts +5 -6
- package/dist-pkg/ui/settings-typo.js +20 -11
- package/dist-pkg/ui/settings-visual.js +2 -2
- package/dist-pkg/ui/shell.d.ts +1 -3
- package/dist-pkg/ui/shell.js +8 -4
- package/dist-pkg/ui/title.d.ts +2 -11
- package/dist-pkg/ui/title.js +39 -6
- package/dist-pkg/ui/top-band.d.ts +5 -3
- package/dist-pkg/ui/top-band.js +21 -25
- package/dist-pkg/ui/typo-choices.d.ts +3 -3
- package/dist-pkg/ui/typo-choices.js +9 -8
- package/dist-pkg/ui/vlibras.d.ts +71 -27
- package/dist-pkg/ui/vlibras.js +116 -44
- package/dist-pkg/ui/voice-control.d.ts +23 -1
- package/dist-pkg/ui/voice-control.js +149 -16
- package/dist-pkg/ui/voice-settings.d.ts +2 -3
- package/dist-pkg/ui/voice-settings.js +53 -3
- package/dist-pkg/ui/where-the-child-is.js +2 -2
- package/docs/CREDITS.md +122 -10
- package/docs/LICENSES.md +36 -7
- package/package.json +34 -9
- package/scripts/check-cartridge.mjs +78 -0
- package/scripts/game-build.d.mts +25 -0
- package/scripts/game-build.mjs +144 -0
- package/scripts/heavy-into-the-delivery.mjs +284 -40
- package/scripts/libras-avatar.json +680 -0
- package/scripts/libras-avatar.mjs +246 -0
- package/scripts/libras-glosses/gloss.py +95 -0
- package/scripts/libras-glosses/pyproject.toml +32 -0
- package/scripts/libras-glosses/uv.lock +781 -0
- package/scripts/libras-glosses.mjs +351 -0
- package/scripts/licences/OFL-1.1.txt +86 -0
- package/scripts/licences/UFL-1.0.txt +96 -0
- package/scripts/licences/fonts.mjs +389 -0
- package/scripts/licences/third-party.mjs +35 -21
- 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/fondamento-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/fondamento-400.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/inter-400.woff2 +0 -0
- package/app/public/vendor/fonts/inter-700.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/lato-400.woff2 +0 -0
- package/app/public/vendor/fonts/lato-700.woff2 +0 -0
- package/app/public/vendor/fonts/literata-400.woff2 +0 -0
- package/app/public/vendor/fonts/literata-700.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/newsreader-400.woff2 +0 -0
- package/app/public/vendor/fonts/newsreader-700.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/opendyslexic-400.woff2 +0 -0
- package/app/public/vendor/fonts/opensans-400.woff2 +0 -0
- package/app/public/vendor/fonts/opensans-700.woff2 +0 -0
- package/app/public/vendor/fonts/pinyon-400.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/pressstart-400.woff2 +0 -0
- package/app/public/vendor/fonts/quattro-400.woff2 +0 -0
- package/app/public/vendor/fonts/quattro-700.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/sourcesans-400.woff2 +0 -0
- package/app/public/vendor/fonts/sourcesans-700.woff2 +0 -0
- package/app/public/vendor/fonts/sourceserif-400.woff2 +0 -0
- package/app/public/vendor/fonts/sourceserif-700.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/ufmag-400.woff2 +0 -0
- package/dist-pkg/platform/guide-intensity.d.ts +0 -39
- package/dist-pkg/platform/guide-intensity.js +0 -71
- package/dist-pkg/ui/latch-refusal.d.ts +0 -33
- package/dist-pkg/ui/latch-refusal.js +0 -60
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
import type { Action } from '../core/actions.js';
|
|
3
3
|
/** The safe item: taking it commands nothing. Same word the gaze cycle uses, and the same job. */
|
|
4
4
|
export declare const SCAN_CANCEL = "cancel";
|
|
5
|
-
|
|
5
|
+
/** What a scan offers: the items it was given — positions in play, a menu's steps in a menu — and «cancel» in front. */
|
|
6
|
+
export type ScanItem<T extends string = Action> = T | typeof SCAN_CANCEL;
|
|
6
7
|
export interface SwitchScanOptions {
|
|
7
8
|
/** How long each item is offered. 1 s is the gaze cycle's step, which the Dev ran for a day (ADR-0213). */
|
|
8
9
|
readonly stepMs?: number;
|
|
@@ -13,30 +14,46 @@ export declare const SWITCH_SCAN_DEFAULTS: {
|
|
|
13
14
|
readonly stepMs: 1000;
|
|
14
15
|
readonly pulseMs: 400;
|
|
15
16
|
};
|
|
17
|
+
/**
|
|
18
|
+
* THE ENGINE'S OWN DOORS, and whether each has something behind it (ADR-0218 §3). A door with nothing behind it is not offered:
|
|
19
|
+
* a cycle never stops on a position that does nothing (ADR-0155).
|
|
20
|
+
*/
|
|
21
|
+
export interface ScanDoors {
|
|
22
|
+
/** The card SELECT opens is mounted. */
|
|
23
|
+
readonly menus: boolean;
|
|
24
|
+
/** The quick pause START opens has its bar — the menu the scan steps there, and «back» is how it is left. */
|
|
25
|
+
readonly quickPause: boolean;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* What the scan offers IN PLAY after «cancel»: the game's named positions, then the doors in the order ADR-0218 §3 names them —
|
|
29
|
+
* the menus (SELECT), then the quick pause (START). Taking a door presses it on the virtual controller, which hands it to the
|
|
30
|
+
* engine as its keys are.
|
|
31
|
+
*/
|
|
32
|
+
export declare function playScanList(game: readonly Action[], doors: ScanDoors): readonly Action[];
|
|
16
33
|
export interface ScanFrame {
|
|
17
34
|
/** Her switch went down on this frame. Whatever sends it — a key, a touch, a gesture, a word. */
|
|
18
35
|
readonly press?: boolean;
|
|
19
36
|
}
|
|
20
|
-
export interface ScanOutput {
|
|
21
|
-
/** The
|
|
22
|
-
readonly pressed:
|
|
23
|
-
/** The
|
|
24
|
-
readonly commanded:
|
|
37
|
+
export interface ScanOutput<T extends string = Action> {
|
|
38
|
+
/** The item being pressed, for `pulseMs` after it was taken. */
|
|
39
|
+
readonly pressed: T | null;
|
|
40
|
+
/** The item taken on THIS frame — what a caller turns into a press. */
|
|
41
|
+
readonly commanded: T | null;
|
|
25
42
|
/** What is being offered right now, and where it sits in the list. Never `null`: something is always showing. */
|
|
26
43
|
readonly showing: {
|
|
27
|
-
readonly item: ScanItem
|
|
44
|
+
readonly item: ScanItem<T>;
|
|
28
45
|
readonly index: number;
|
|
29
46
|
};
|
|
30
47
|
}
|
|
31
|
-
export interface SwitchScan {
|
|
32
|
-
(nowMs: number, frame?: ScanFrame): ScanOutput
|
|
48
|
+
export interface SwitchScan<T extends string = Action> {
|
|
49
|
+
(nowMs: number, frame?: ScanFrame): ScanOutput<T>;
|
|
33
50
|
}
|
|
34
51
|
/**
|
|
35
|
-
* The scanner. `actions` is what
|
|
36
|
-
* front of them.
|
|
52
|
+
* The scanner. `actions` is what is offered now — in play this game's declared positions and the engine's own doors, in a menu
|
|
53
|
+
* that menu's steps — and `cancel` is put in front of them.
|
|
37
54
|
*
|
|
38
55
|
* ⚠️ An empty list is not an error: a game that declared nothing leaves a scan of one item, `cancel`, and a press takes nothing.
|
|
39
56
|
* The alternative — offering the whole controller to a game that reads none of it — is the dead button ADR-0106 §5 refuses, and
|
|
40
57
|
* here it would cost a child a full pass of fourteen items to reach the one thing that works.
|
|
41
58
|
*/
|
|
42
|
-
export declare function createSwitchScan(actions: readonly
|
|
59
|
+
export declare function createSwitchScan<T extends string = Action>(actions: readonly T[], options?: SwitchScanOptions): SwitchScan<T>;
|
|
@@ -19,8 +19,21 @@
|
|
|
19
19
|
export const SCAN_CANCEL = 'cancel';
|
|
20
20
|
export const SWITCH_SCAN_DEFAULTS = { stepMs: 1000, pulseMs: 400 };
|
|
21
21
|
/**
|
|
22
|
-
*
|
|
23
|
-
*
|
|
22
|
+
* What the scan offers IN PLAY after «cancel»: the game's named positions, then the doors in the order ADR-0218 §3 names them —
|
|
23
|
+
* the menus (SELECT), then the quick pause (START). Taking a door presses it on the virtual controller, which hands it to the
|
|
24
|
+
* engine as its keys are.
|
|
25
|
+
*/
|
|
26
|
+
export function playScanList(game, doors) {
|
|
27
|
+
const list = [...game];
|
|
28
|
+
if (doors.menus)
|
|
29
|
+
list.push('select');
|
|
30
|
+
if (doors.quickPause)
|
|
31
|
+
list.push('start');
|
|
32
|
+
return list;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* The scanner. `actions` is what is offered now — in play this game's declared positions and the engine's own doors, in a menu
|
|
36
|
+
* that menu's steps — and `cancel` is put in front of them.
|
|
24
37
|
*
|
|
25
38
|
* ⚠️ An empty list is not an error: a game that declared nothing leaves a scan of one item, `cancel`, and a press takes nothing.
|
|
26
39
|
* The alternative — offering the whole controller to a game that reads none of it — is the dead button ADR-0106 §5 refuses, and
|
|
@@ -5,9 +5,6 @@ import type { PlayerView } from '../core/entity.js';
|
|
|
5
5
|
import type { DomQuery } from '../core/dom-query.js';
|
|
6
6
|
import type { KeyScheme } from '../core/entity.js';
|
|
7
7
|
import { type Action } from '../core/actions.js';
|
|
8
|
-
export type { DomQuery } from '../core/dom-query.js';
|
|
9
|
-
/** action -> list of physical codes. */
|
|
10
|
-
export type { KeyScheme } from '../core/entity.js';
|
|
11
8
|
/** The six input edges touch raises on the player (consumed and cleared by the game's physics). */
|
|
12
9
|
export type EdgeFlag = 'jumpEdge' | 'runEdge' | 'leftEdge' | 'rightEdge' | 'swapEdge' | 'specialEdge';
|
|
13
10
|
/** An edge to raise: which player (POSITION in the array) and which flag. */
|
|
@@ -29,8 +26,6 @@ export interface TouchBindSnapshot {
|
|
|
29
26
|
/** `input/state.ts`'s `keys`: the keys held NOW (every transport's, mixed). */
|
|
30
27
|
heldKeys: ReadonlySet<string>;
|
|
31
28
|
}
|
|
32
|
-
/** Re-exported: the definition lives in `input/pointer-space`, with the arithmetic that uses it (issue #105). */
|
|
33
|
-
export type { RectLike } from './pointer-space.js';
|
|
34
29
|
/** The d-pad's four physical directions, on or off. */
|
|
35
30
|
export interface DirSet {
|
|
36
31
|
left: boolean;
|
|
@@ -188,7 +183,9 @@ export interface TouchBindingsCtx {
|
|
|
188
183
|
*
|
|
189
184
|
* 🔴 REQUIRED, and it is where the device switch becomes VISIBLE: touch is the transport the child uses beside the
|
|
190
185
|
* keyboard, and without this line the automaton answers `teclado` even with the finger on the screen — so the latch
|
|
191
|
-
* read would be the keyboard's, on the wrong device.
|
|
186
|
+
* read would be the keyboard's, on the wrong device. 📌 In the root the press has already recorded this edge and resolved
|
|
187
|
+
* touch's latch at the virtual controller's `pressedBy` (ADR-0109 rule 3); a host without that door passes the latched edge
|
|
188
|
+
* of `input/latch-edge` here.
|
|
192
189
|
*/
|
|
193
190
|
playerEdge: (player: number, source: TransportName) => void;
|
|
194
191
|
/**
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
// SPDX-License-Identifier: AGPL-3.0-or-later
|
|
2
2
|
import type { Translate } from '../core/i18n.js';
|
|
3
3
|
import type { DomQuery } from '../core/dom-query.js';
|
|
4
|
-
/** Minimal DOM-selector shape (matches ui/dom.ts's `$`). */
|
|
5
|
-
export type { DomQuery } from '../core/dom-query.js';
|
|
6
4
|
/** Minimal platform/storage.ts shape this module needs. */
|
|
7
5
|
export interface TouchStore {
|
|
8
6
|
get(key: string, fallback?: string | null): string | null;
|
|
@@ -78,6 +76,22 @@ export interface TouchCtx {
|
|
|
78
76
|
* root never handed in, which is what took down every boot in a fake document once this was wired to `createGame`.
|
|
79
77
|
*/
|
|
80
78
|
win: Pick<Window, 'addEventListener'> | null;
|
|
79
|
+
/**
|
|
80
|
+
* Draws ONE slot's choice by its size (ADR-0130 rule 3): five named positions or fewer are a cycle row, more a dropdown.
|
|
81
|
+
* Injected because the drawing lives in `ui/panel-widgets.mountChoice` and this module is a layer below it (ADR-0173);
|
|
82
|
+
* `createGame` hands it in. ABSENT, each slot stays a hand-built `<select>`, whatever its size — a host that builds its
|
|
83
|
+
* own touch panel keeps the control it always had.
|
|
84
|
+
*/
|
|
85
|
+
drawChoice?: (spec: TouchSlotChoice, pick: (action: string) => void) => HTMLElement;
|
|
86
|
+
}
|
|
87
|
+
/** What a slot's choice is drawn from: the slot's name, the game's positions in its words, and the one it carries now. */
|
|
88
|
+
export interface TouchSlotChoice {
|
|
89
|
+
readonly label: string;
|
|
90
|
+
readonly values: readonly {
|
|
91
|
+
readonly value: string;
|
|
92
|
+
readonly label: string;
|
|
93
|
+
}[];
|
|
94
|
+
readonly current: string;
|
|
81
95
|
}
|
|
82
96
|
export declare const IPHONE16_LONG_MM = 141.1;
|
|
83
97
|
export declare const IPHONE16_LONG_PX = 852;
|
|
@@ -194,6 +208,7 @@ export interface TouchMarkupSpec {
|
|
|
194
208
|
/** The d-pad's drawing: `cruz` (cross) or `analogico` (stick). It comes from the pad's persisted setting (`padDir`). */
|
|
195
209
|
readonly dpad?: 'cruz' | 'analogico';
|
|
196
210
|
}
|
|
211
|
+
export declare function buttonName(t: Translate, slotAction: string): string | null;
|
|
197
212
|
/**
|
|
198
213
|
* Builds (or reuses) `#touch-controls` and returns it.
|
|
199
214
|
*
|
package/dist-pkg/input/touch.js
CHANGED
|
@@ -107,10 +107,31 @@ export function initTouch(ctx) {
|
|
|
107
107
|
let padDir = ctx.store.get(KEYS.padDir, 'stick') || 'stick';
|
|
108
108
|
let _stickTravelPx = 42, _stickDeadPx = 12; // boot values; applyPadPhysical() sets the real ones
|
|
109
109
|
const touchMap = normalizeTouchMap(ctx.store.getJSON(KEYS.touchmap, null));
|
|
110
|
+
/** A slot's choice landed: store it, and say it in the game's word — never the abstract name. */
|
|
111
|
+
function slotChosen(slot, slotLabel, action) {
|
|
112
|
+
touchMap[slot] = action;
|
|
113
|
+
ctx.store.setJSON(KEYS.touchmap, touchMap);
|
|
114
|
+
// ⚠️ The spoken word is the SAME as the one read: it comes from the list that just built the control, so nothing has
|
|
115
|
+
// to make two tables agree.
|
|
116
|
+
const chosen = ctx.gameActions().find((x) => x.action === action);
|
|
117
|
+
const slotName = slotLabel || t('touch.slot.fallback');
|
|
118
|
+
// ⚠️ WITHOUT THE GAME'S WORD, THE ANNOUNCEMENT DROPS THE POSITION — IT DOES NOT FALL BACK TO THE ID. `action` is the
|
|
119
|
+
// ABSTRACT name (`action3`), and ADR-0074 says it never reaches a person; `7742ac0` already paid for this defect on the
|
|
120
|
+
// remapping screen and the way out is the same: a key of its own that says what matters.
|
|
121
|
+
// 📌 The fallback is reachable because `gameActions()` is a FUNCTION of the cartridge, reread on every choice: in an
|
|
122
|
+
// activity hub the list changes underneath and the control drawn before is orphaned.
|
|
123
|
+
ctx.srSay(chosen
|
|
124
|
+
? t('sr.touch.slotSet', { slot: slotName, acao: chosen.label })
|
|
125
|
+
: t('sr.touch.slotSetUnnamed', { slot: slotName }));
|
|
126
|
+
}
|
|
110
127
|
function renderTouchMap() {
|
|
111
128
|
const el = ctx.$('#touchmap-list');
|
|
112
129
|
if (!el)
|
|
113
130
|
return;
|
|
131
|
+
if (ctx.drawChoice) {
|
|
132
|
+
drawSlotChoices(el, ctx.drawChoice);
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
114
135
|
el.innerHTML = TOUCH_SLOTS.map((s) => `<div class="ctrl-row"><label for="tm-${s.k}">${t(s.lbl)}</label><select id="tm-${s.k}" class="vol" data-slot="${s.k}">` +
|
|
115
136
|
// ⚠️ THE OPTION IS BORN EMPTY and the `label` goes in just below through `textContent` (issue #106). It is the
|
|
116
137
|
// game's WORD — `gameActions()` comes from the preset —, and a game lives in another repository (ADR-0083), so
|
|
@@ -127,25 +148,41 @@ export function initTouch(ctx) {
|
|
|
127
148
|
}
|
|
128
149
|
el.querySelectorAll('select[data-slot]').forEach((sel) => {
|
|
129
150
|
sel.addEventListener('change', () => {
|
|
130
|
-
const slot = sel.dataset.slot || '';
|
|
131
|
-
touchMap[slot] = sel.value;
|
|
132
|
-
ctx.store.setJSON(KEYS.touchmap, touchMap);
|
|
133
151
|
const label = sel.previousElementSibling ? sel.previousElementSibling.textContent : null;
|
|
134
|
-
|
|
135
|
-
// nothing has to make two tables agree.
|
|
136
|
-
const chosen = ctx.gameActions().find((x) => x.action === sel.value);
|
|
137
|
-
const slotName = label || t('touch.slot.fallback');
|
|
138
|
-
// ⚠️ WITHOUT THE GAME'S WORD, THE ANNOUNCEMENT DROPS THE POSITION — IT DOES NOT FALL BACK TO THE ID. `sel.value`
|
|
139
|
-
// is the ABSTRACT name (`action3`), and ADR-0074 says it never reaches a person; `7742ac0` already paid for
|
|
140
|
-
// this defect on the remapping screen and the way out is the same: a key of its own that says what matters.
|
|
141
|
-
// 📌 The fallback is reachable because `gameActions()` is a FUNCTION of the cartridge, reread on every
|
|
142
|
-
// `change`: in an activity hub the list changes underneath and the `<option>` drawn before is orphaned.
|
|
143
|
-
ctx.srSay(chosen
|
|
144
|
-
? t('sr.touch.slotSet', { slot: slotName, acao: chosen.label })
|
|
145
|
-
: t('sr.touch.slotSetUnnamed', { slot: slotName }));
|
|
152
|
+
slotChosen(sel.dataset.slot || '', label, sel.value);
|
|
146
153
|
});
|
|
147
154
|
});
|
|
148
155
|
}
|
|
156
|
+
/**
|
|
157
|
+
* THE SLOTS DRAWN BY THEIR SIZE (ADR-0130 rule 3), node by node: each slot is a choice among the game's named positions,
|
|
158
|
+
* so a game naming five or fewer gets cycle rows «◀ Botão 0: Confirmar ▶», and one naming more gets dropdowns. The id
|
|
159
|
+
* (`#tm-<slot>`) and `data-slot` stay on the control in both shapes — they are how the root finds the slots it hides.
|
|
160
|
+
*/
|
|
161
|
+
function drawSlotChoices(el, draw) {
|
|
162
|
+
while (el.firstChild)
|
|
163
|
+
el.removeChild(el.firstChild);
|
|
164
|
+
const doc = el.ownerDocument;
|
|
165
|
+
const positions = ctx.gameActions().map(({ action, label }) => ({ value: action, label }));
|
|
166
|
+
for (const s of TOUCH_SLOTS) {
|
|
167
|
+
const slotName = t(s.lbl);
|
|
168
|
+
const control = draw({ label: slotName, values: positions, current: touchMap[s.k] ?? '' }, (action) => slotChosen(s.k, slotName, action));
|
|
169
|
+
control.id = `tm-${s.k}`;
|
|
170
|
+
control.dataset.slot = s.k;
|
|
171
|
+
const row = doc.createElement('div');
|
|
172
|
+
row.className = 'ctrl-row';
|
|
173
|
+
if (control.tagName === 'SELECT') {
|
|
174
|
+
// a dropdown keeps its name beside it; a cycle row already carries it in its own text
|
|
175
|
+
const name = doc.createElement('label');
|
|
176
|
+
name.htmlFor = control.id;
|
|
177
|
+
name.textContent = slotName;
|
|
178
|
+
row.appendChild(name);
|
|
179
|
+
}
|
|
180
|
+
else
|
|
181
|
+
row.classList.add('ctrl-row--passos');
|
|
182
|
+
row.appendChild(control);
|
|
183
|
+
el.appendChild(row);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
149
186
|
function openTouchCfg() {
|
|
150
187
|
const ov = ctx.$('#touchcfg');
|
|
151
188
|
if (!ov)
|
|
@@ -310,14 +347,15 @@ export function initTouch(ctx) {
|
|
|
310
347
|
}
|
|
311
348
|
/**
|
|
312
349
|
* A BUTTON'S NAME, from the position it fires (ADR-0165): the same in every game — 1 to 4, L1/L2/R1/R2, SELECT, START,
|
|
313
|
-
* and the four directions by their spoken name. The cartridge's word is the FUNCTION, and it never reaches the face.
|
|
350
|
+
* and the four directions by their spoken name. The cartridge's word is the FUNCTION, and it never reaches the face. The pad
|
|
351
|
+
* wizard asks by these names where the game names no position (`input/pad-wizard`, ADR-0144 erratum of 2026-09-26).
|
|
314
352
|
*/
|
|
315
353
|
const SLOT_NAME = {
|
|
316
354
|
action1: '1', action2: '2', action3: '3', action4: '4',
|
|
317
355
|
leftShoulder: 'L1', leftTrigger: 'L2', rightShoulder: 'R1', rightTrigger: 'R2',
|
|
318
356
|
select: 'SELECT', start: 'START',
|
|
319
357
|
};
|
|
320
|
-
function buttonName(t, slotAction) {
|
|
358
|
+
export function buttonName(t, slotAction) {
|
|
321
359
|
if (SLOT_NAME[slotAction])
|
|
322
360
|
return SLOT_NAME[slotAction];
|
|
323
361
|
return slotAction === 'up' || slotAction === 'down' || slotAction === 'left' || slotAction === 'right' ? t(`touch.nome.${slotAction}`) : null;
|
|
@@ -32,9 +32,9 @@ export declare function isTransportName(v: unknown): v is TransportName;
|
|
|
32
32
|
* THE FOUR THAT REQUIRE EXPLICIT ENABLING and, once enabled, rule over all the others (rule 4).
|
|
33
33
|
*
|
|
34
34
|
* ⚠️ It is the same list as `ONE_COMMAND_AT_A_TIME` in `input/latch-scope`, and the match is no accident: these
|
|
35
|
-
* are the transports
|
|
36
|
-
*
|
|
37
|
-
*
|
|
35
|
+
* are the transports that send one command at a time. What ADR-0109 added — that enabling them turns latching on
|
|
36
|
+
* for the rest — is the model of `latchNow`, which ADR-0113 superseded; since ADR-0249 their own latch starts as
|
|
37
|
+
* the game's `holdsKeys()` and the child may change it.
|
|
38
38
|
*/
|
|
39
39
|
export declare const NEED_ENABLING: ReadonlySet<TransportName>;
|
|
40
40
|
/** The transport that turns latching on by itself, with no priority involved (rule 2). */
|
|
@@ -78,8 +78,8 @@ export declare const DEFAULT_INPUT_STATE: InputState;
|
|
|
78
78
|
* `latch-scope.latchOf` returns `true`, because it reads what they saved.
|
|
79
79
|
*
|
|
80
80
|
* ⚠️ AND THE TOUCH CLAUSE FELL TOO: under ADR-0113 touch is a transport like the others — its value is a choice
|
|
81
|
-
* and is stored.
|
|
82
|
-
* `latch-scope.
|
|
81
|
+
* and is stored. Eyes, face, gestures and speech differ only in where their DEFAULT comes from — the game's
|
|
82
|
+
* `holdsKeys()` (ADR-0249, `latch-scope.latchDefaultFromGame`) — and their value is a choice too.
|
|
83
83
|
*
|
|
84
84
|
* **The right answer is `latch-scope.latchOf(inputState.inUse, reading)`.** The role left to this module is
|
|
85
85
|
* what its name says: WHICH transport is in use — which is what feeds that first argument.
|
|
@@ -53,9 +53,9 @@ export function isTransportName(v) {
|
|
|
53
53
|
* THE FOUR THAT REQUIRE EXPLICIT ENABLING and, once enabled, rule over all the others (rule 4).
|
|
54
54
|
*
|
|
55
55
|
* ⚠️ It is the same list as `ONE_COMMAND_AT_A_TIME` in `input/latch-scope`, and the match is no accident: these
|
|
56
|
-
* are the transports
|
|
57
|
-
*
|
|
58
|
-
*
|
|
56
|
+
* are the transports that send one command at a time. What ADR-0109 added — that enabling them turns latching on
|
|
57
|
+
* for the rest — is the model of `latchNow`, which ADR-0113 superseded; since ADR-0249 their own latch starts as
|
|
58
|
+
* the game's `holdsKeys()` and the child may change it.
|
|
59
59
|
*/
|
|
60
60
|
export const NEED_ENABLING = new Set(['olhos', 'rosto', 'gestos', 'fala']);
|
|
61
61
|
/** The transport that turns latching on by itself, with no priority involved (rule 2). */
|
|
@@ -89,8 +89,8 @@ export const DEFAULT_INPUT_STATE = Object.freeze({ inUse: 'teclado', assistedOn:
|
|
|
89
89
|
* `latch-scope.latchOf` returns `true`, because it reads what they saved.
|
|
90
90
|
*
|
|
91
91
|
* ⚠️ AND THE TOUCH CLAUSE FELL TOO: under ADR-0113 touch is a transport like the others — its value is a choice
|
|
92
|
-
* and is stored.
|
|
93
|
-
* `latch-scope.
|
|
92
|
+
* and is stored. Eyes, face, gestures and speech differ only in where their DEFAULT comes from — the game's
|
|
93
|
+
* `holdsKeys()` (ADR-0249, `latch-scope.latchDefaultFromGame`) — and their value is a choice too.
|
|
94
94
|
*
|
|
95
95
|
* **The right answer is `latch-scope.latchOf(inputState.inUse, reading)`.** The role left to this module is
|
|
96
96
|
* what its name says: WHICH transport is in use — which is what feeds that first argument.
|
|
@@ -81,15 +81,6 @@ export interface Transport {
|
|
|
81
81
|
}
|
|
82
82
|
/** Does this transport carry this set of actions? Arithmetic, as ADR-0079 §3 describes it. */
|
|
83
83
|
export declare function carries(t: Transport, actions: readonly Action[]): boolean;
|
|
84
|
-
/**
|
|
85
|
-
* Does this transport HOLD as many as the game asks at once? (ADR-0104 §A.)
|
|
86
|
-
*
|
|
87
|
-
* ⚠️ A TRANSPORT WITH NO DECLARED CEILING ANSWERS YES, and the choice is deliberate: an absent `holds` means "we did
|
|
88
|
-
* not measure this", and refusing for lack of a measure would turn ignorance into an accusation — keyboard and pad
|
|
89
|
-
* would fail every game for having no number at all. Where there is no decision, the model stays silent; touch is
|
|
90
|
-
* the one with a decision, and it alone can fail here.
|
|
91
|
-
*/
|
|
92
|
-
export declare function holds(t: Transport, asked: number): boolean;
|
|
93
84
|
/**
|
|
94
85
|
* The AVAILABLE transports that carry this set.
|
|
95
86
|
*
|
|
@@ -91,7 +91,7 @@ export function carries(t, actions) {
|
|
|
91
91
|
* would fail every game for having no number at all. Where there is no decision, the model stays silent; touch is
|
|
92
92
|
* the one with a decision, and it alone can fail here.
|
|
93
93
|
*/
|
|
94
|
-
|
|
94
|
+
function holds(t, asked) {
|
|
95
95
|
return t.holds === undefined || t.holds >= asked;
|
|
96
96
|
}
|
|
97
97
|
/**
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// SPDX-License-Identifier: AGPL-3.0-or-later
|
|
2
|
-
import type
|
|
2
|
+
import { type Action } from '../core/actions.js';
|
|
3
3
|
import type { KeyScheme } from '../core/entity.js';
|
|
4
4
|
import type { TransportName } from './transport-in-use.js';
|
|
5
5
|
export interface VirtualCommand {
|
|
@@ -30,17 +30,53 @@ export interface VirtualControllerDeps {
|
|
|
30
30
|
*/
|
|
31
31
|
readonly menuKey: (code: string, source: TransportName | undefined) => void;
|
|
32
32
|
readonly deliver: (command: VirtualCommand) => void;
|
|
33
|
+
/**
|
|
34
|
+
* A position the ENGINE answers itself while a menu is open, before it becomes a menu key: the sonar reads the menu in
|
|
35
|
+
* front (ADR-0234, `ui/screen-text.menuSonarPress`). Answers whether it took the press. Absent: every position is a key.
|
|
36
|
+
*/
|
|
37
|
+
readonly menuAnswers?: (action: Action, player: number) => boolean;
|
|
38
|
+
/**
|
|
39
|
+
* A SYSTEM position pressed, in play or with a menu open: the engine answers it for that seat as its keys do — `start` the
|
|
40
|
+
* quick pause (again: leaves it), `select` the menus (ADR-0144 §1 and its erratum of 2026-09-26, ADR-0155). Absent: it does
|
|
41
|
+
* nothing.
|
|
42
|
+
*
|
|
43
|
+
* ⚠️ The keyboard does not come here: its key is already in the world, and the engine's own key listeners answer it even for
|
|
44
|
+
* a cartridge with no `onCommand` — the host's keyboard conductor does not press these two, or one key would pause twice.
|
|
45
|
+
*/
|
|
46
|
+
readonly systemPress?: (action: Action, player: number) => void;
|
|
47
|
+
/**
|
|
48
|
+
* ONE BUTTON ONLY (ADR-0218 §4): asked FIRST, for every press from every transport that presses here — the eyes, the face,
|
|
49
|
+
* the hands, the voice, the on-screen pad, the gamepad. `true` means one-button scanning took the press as «take the one
|
|
50
|
+
* shown»: the position reaches nothing else — not play, not a menu, not the engine — and no release is owed for it. A press
|
|
51
|
+
* that lands on the scan's «cancel» is taken too, and means nothing. Absent: every press is itself.
|
|
52
|
+
*/
|
|
53
|
+
readonly takeShown?: (source: TransportName | undefined) => boolean;
|
|
54
|
+
/**
|
|
55
|
+
* A PRESS FROM A NAMED TRANSPORT, told FIRST — before one button only, a menu or play decides where it goes. This is the one
|
|
56
|
+
* place every position-pressing transport shares, so it is where «the child is using this device» can be heard for all of
|
|
57
|
+
* them (ADR-0109 rule 3), and where the root records that device's edge and resolves its latch before the press reaches the
|
|
58
|
+
* game (ADR-0113, ADR-0249). Not told for a press with no source: a key nobody stamped is nobody's edge — the real keyboard
|
|
59
|
+
* arrives here as `teclado`, read off the event by `input/synthetic-source.sourceOfEvent`. Absent: nothing is told.
|
|
60
|
+
*/
|
|
61
|
+
readonly pressedBy?: (source: TransportName, player: number) => void;
|
|
33
62
|
}
|
|
34
63
|
export interface VirtualController {
|
|
35
64
|
/**
|
|
36
|
-
* Presses a position. Answers whether it reached PLAY — `false` means a menu took it.
|
|
65
|
+
* Presses a position. Answers whether it reached PLAY — `false` means a menu took it, or it was held back (`toPlay`).
|
|
37
66
|
*
|
|
38
67
|
* 🔴 THE ANSWER EXISTS BECAUSE EVERY TRANSPORT NEEDS IT AND EACH WAS GUESSING IT (ADR-0223). The touch pad asked its own
|
|
39
68
|
* `emMenu()` before deciding what to do, which is the same question this function has just answered — and two answers to
|
|
40
69
|
* one question is how the two doors came to disagree about what happens with a menu open. A transport that raises an edge,
|
|
41
70
|
* or hides its tips, or announces something, does it only when the press reached the game; now it is told.
|
|
71
|
+
*
|
|
72
|
+
* `toPlay` false: in play the press belongs to something else — the keyboard knows what has the focus, a field being typed
|
|
73
|
+
* into or the engine's own control being pressed (`input/key-default`) — so it reaches nobody: nothing held, nothing delivered.
|
|
74
|
+
* With a menu open it is the menu's all the same, as every press is (ADR-0111 erratum of 2026-09-26: one press, one action).
|
|
75
|
+
*
|
|
76
|
+
* A system position (`start`, `select`) never reaches play and never becomes a menu key: it is the engine's (ADR-0144 §4), and
|
|
77
|
+
* it goes to `systemPress` — unless, in play, `toPlay` is false, when the press belongs to something else and reaches nobody.
|
|
42
78
|
*/
|
|
43
|
-
press(action: Action, source: TransportName | undefined, player?: number): boolean;
|
|
79
|
+
press(action: Action, source: TransportName | undefined, player?: number, toPlay?: boolean): boolean;
|
|
44
80
|
release(action: Action, source: TransportName | undefined, player?: number): void;
|
|
45
81
|
}
|
|
46
82
|
export declare function createVirtualController(d: VirtualControllerDeps): VirtualController;
|
|
@@ -4,22 +4,50 @@
|
|
|
4
4
|
// The Dev: «a engine lida com o hardware e passa para o jogo o nome virtual do botão, o jogo por sua vez devolve o nome do que é executado
|
|
5
5
|
// ao apertar cada botão… a engine leva o evento para o jogo». A transport that reads positions (the eyes, and later the face and the
|
|
6
6
|
// hands) presses and releases a position here, with its source; this decides what that reaches:
|
|
7
|
-
// · with a menu open, the position is the menu's key — the way the touch pad already moves menus (ADR-0157), since menus read keys
|
|
7
|
+
// · with a menu open, the position is the menu's key — the way the touch pad already moves menus (ADR-0157), since menus read keys —
|
|
8
|
+
// unless the engine answers it there itself (`menuAnswers`: the sonar reads the menu, ADR-0234);
|
|
8
9
|
// · in play, the child's key for that position is held (games that ask what is held keep answering), and the command is delivered to the
|
|
9
10
|
// cartridge: the position, pressed or released, the source, the seat. The cartridge's map (its `preset`) says what it executes.
|
|
10
11
|
// A position the child's scheme gives no key is still delivered: the map belongs to the game, not to the keyboard.
|
|
12
|
+
// 🔴 EXCEPT THE TWO SYSTEM POSITIONS, which never reach play (ADR-0144 §4, ADR-0155 §4): `start` is the quick pause and `select`
|
|
13
|
+
// opens the menus, a cartridge may not declare either, so the game has no word for them and nothing to do with them. 📏 Before
|
|
14
|
+
// this, Enter in play opened the quick pause AND the quiz's `onCommand` heard `start`; F opened the card AND it heard `select`.
|
|
15
|
+
// They go to the ENGINE instead (`systemPress`), so START and SELECT open the pause «from any transport» (ADR-0144 §1): the eyes,
|
|
16
|
+
// the face, the hands, the voice and the scan press here and have no key in the world for the engine to hear.
|
|
17
|
+
// 🔴 AND WITH A MENU OPEN TOO, never as a key (ADR-0144 erratum of 2026-09-26). The first key of `start` is whatever the child put
|
|
18
|
+
// first: with `start` remapped to `Enter`, a camera's START on the quick pause's bar was the bar's «confirm» and not the way out.
|
|
19
|
+
// The engine answers the POSITION the same way its key listeners do — START again leaves the quick pause, SELECT goes on to the
|
|
20
|
+
// card, and an open card or panel refuses both.
|
|
21
|
+
// 🔴 AND WITH ONE BUTTON ONLY ON, NONE OF THE ABOVE (ADR-0218 §4): every press here is the child's one switch, and it takes the
|
|
22
|
+
// item the scan shows (`takeShown`, asked before anything else). This is the one place every position-pressing transport shares.
|
|
23
|
+
import { SYSTEM } from '../core/actions.js';
|
|
24
|
+
/** The positions that are the engine's and never the game's (`core/actions.SYSTEM`). */
|
|
25
|
+
const ENGINE_POSITIONS = new Set(SYSTEM);
|
|
11
26
|
export function createVirtualController(d) {
|
|
12
27
|
// `${player}:${action}` → the key held for a press the game received (or null when the scheme has none), so the release lets go of the
|
|
13
28
|
// same key, and only a press the game heard is released to it
|
|
14
29
|
const held = new Map();
|
|
15
30
|
return {
|
|
16
|
-
press(action, source, player = 0) {
|
|
31
|
+
press(action, source, player = 0, toPlay = true) {
|
|
32
|
+
if (source)
|
|
33
|
+
d.pressedBy?.(source, player);
|
|
34
|
+
if (d.takeShown?.(source))
|
|
35
|
+
return false; // one button only: whatever was pressed, it was the switch (ADR-0218 §4)
|
|
36
|
+
const menu = d.menuOpen();
|
|
37
|
+
// the POSITION, not its first key: a key means what the child bound to it, and `Enter` on a menu is «confirm»
|
|
38
|
+
if (ENGINE_POSITIONS.has(action)) {
|
|
39
|
+
if (menu || toPlay)
|
|
40
|
+
d.systemPress?.(action, player);
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
17
43
|
const code = d.scheme(player)[action]?.[0];
|
|
18
|
-
if (
|
|
19
|
-
if (code)
|
|
44
|
+
if (menu) {
|
|
45
|
+
if (!d.menuAnswers?.(action, player) && code)
|
|
20
46
|
d.menuKey(code, source);
|
|
21
47
|
return false;
|
|
22
48
|
}
|
|
49
|
+
if (!toPlay)
|
|
50
|
+
return false;
|
|
23
51
|
if (code)
|
|
24
52
|
d.holdKey(code, source);
|
|
25
53
|
held.set(`${player}:${action}`, code ?? null);
|
|
@@ -5,7 +5,7 @@ import type { Action } from '../core/actions.js';
|
|
|
5
5
|
*
|
|
6
6
|
* ⚠️ WRITTEN AS THE RECOGNISER'S VOCABULARY SPELLS THEM — lowercase, with their accents (the Dev's words are «ação» and
|
|
7
7
|
* «Acción»): a grammar word the model does not know is dropped and its position goes mute (measured below). Comparing ignores
|
|
8
|
-
* accents
|
|
8
|
+
* accents: the reader (`platform/speech-recognition`) matches a heard sentence and a table entry by a key without them.
|
|
9
9
|
*/
|
|
10
10
|
export type VoiceWords = {
|
|
11
11
|
readonly [A in Action]?: readonly string[];
|
|
@@ -19,25 +19,41 @@ export declare function voiceWordsFor(language: string): VoiceWords;
|
|
|
19
19
|
* says something that is not a command: the lab measured free speech being pushed to the nearest word («configurações de
|
|
20
20
|
* inclusão» → «quatro»). That is the cost of the closed list and the reason the words are short and unlike each other.
|
|
21
21
|
* ⚠️ `extra` is what the MENU is showing right now (ADR-0194): saying the name of an item activates it, so those words join the
|
|
22
|
-
* grammar while that menu is open and leave with it
|
|
22
|
+
* grammar while that menu is open and leave with it — AS THE LANGUAGE WRITES THEM (§1, «as shown»), accents kept: stripped,
|
|
23
|
+
* «configurações» is not in the model's vocabulary and the name goes mute, the same defect «acao» was.
|
|
23
24
|
*/
|
|
24
25
|
export declare function voiceGrammar(language: string, extra?: readonly string[]): readonly string[];
|
|
26
|
+
/** What a heard phrase asks for: a position of the controller, or the item of the open menu that has this name (ADR-0194). */
|
|
27
|
+
export type VoiceCommand = {
|
|
28
|
+
readonly kind: 'position';
|
|
29
|
+
readonly action: Action;
|
|
30
|
+
}
|
|
31
|
+
/** `name` is the item's name exactly as it was handed to `items` — the name on screen, to find the item by. */
|
|
32
|
+
| {
|
|
33
|
+
readonly kind: 'item';
|
|
34
|
+
readonly name: string;
|
|
35
|
+
};
|
|
25
36
|
export interface VoiceCommands {
|
|
26
37
|
/**
|
|
27
|
-
*
|
|
38
|
+
* The names the open menu is showing, as shown (ADR-0194 §2): from now on, saying one is a command — until the next call.
|
|
39
|
+
* An empty list is a menu closed.
|
|
40
|
+
*/
|
|
41
|
+
items(names: readonly string[]): void;
|
|
42
|
+
/**
|
|
43
|
+
* What the recogniser has heard SO FAR in this utterance → the commands it completes that were not answered before.
|
|
28
44
|
* ⚠️ It answers on the PARTIAL and not at the end of the sentence (ADR-0193 erratum, the Dev's choice after running both):
|
|
29
|
-
* 0.25–0.45 s against 1.3–1.4 s, which is the difference between a command and a delay a child gives up on
|
|
45
|
+
* 0.25–0.45 s against 1.3–1.4 s, which is the difference between a command and a delay a child gives up on — except for a
|
|
46
|
+
* name another item's name continues, which waits for `final` (ADR-0194 §3).
|
|
30
47
|
*/
|
|
31
|
-
partial(text: string):
|
|
32
|
-
/** The utterance ended
|
|
33
|
-
|
|
48
|
+
partial(text: string): readonly VoiceCommand[];
|
|
49
|
+
/** The utterance ended with this text: what it completes that the partials held back. The next partial starts afresh. */
|
|
50
|
+
final(text: string): readonly VoiceCommand[];
|
|
34
51
|
}
|
|
35
52
|
/**
|
|
36
|
-
* The
|
|
53
|
+
* The Dev's words and the open menu's names, READ BY `platform/speech-recognition.createCommandReader` — the one reader of what
|
|
54
|
+
* was heard (ADR-0194 §2–§3); this adds only what a word MEANS here, the position it presses.
|
|
37
55
|
*
|
|
38
56
|
* 🎯 A PARTIAL GROWS, AND ONLY WHAT IS NEW FIRES. «acima» then «acima abaixo» is a child who said two words, and the second
|
|
39
|
-
* press must be `down`, not `up` all over again —
|
|
40
|
-
* 📌 The tail is matched LONGEST FIRST because a position may answer to a phrase: «pick up» is one command in English, and
|
|
41
|
-
* reading only the last word would make it `null` after having fired nothing.
|
|
57
|
+
* press must be `down`, not `up` all over again — the reader counts what it already answered for in each utterance.
|
|
42
58
|
*/
|
|
43
59
|
export declare function createVoiceCommands(language: string): VoiceCommands;
|