@the-inclusionist/engine 9.0.0 → 11.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +120 -78
- package/app/css/style.css +761 -377
- 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-licences/NOTICE.txt +166 -0
- package/app/public/vendor/fonts-licences/OFL-1.1.txt +86 -0
- package/app/public/vendor/fonts.css +36 -84
- package/dist-pkg/boot/create-game.d.ts +499 -219
- package/dist-pkg/boot/create-game.js +3944 -562
- package/dist-pkg/core/a11y-sr.d.ts +25 -3
- package/dist-pkg/core/a11y-sr.js +38 -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 +125 -0
- package/dist-pkg/core/accommodations.js +195 -0
- package/dist-pkg/core/actions.d.ts +108 -55
- package/dist-pkg/core/actions.js +122 -71
- 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 +142 -164
- package/dist-pkg/core/contract.js +222 -208
- 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 +71 -60
- package/dist-pkg/core/i18n.js +186 -200
- 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/session-clock.d.ts +23 -0
- package/dist-pkg/core/session-clock.js +37 -0
- 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 +324 -223
- package/dist-pkg/i18n/es.js +323 -223
- package/dist-pkg/i18n/pt.js +348 -226
- 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 +195 -145
- package/dist-pkg/input/gamepad.js +383 -556
- 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/key-default.d.ts +30 -0
- package/dist-pkg/input/key-default.js +60 -0
- package/dist-pkg/input/keyboard-runtime.d.ts +15 -21
- package/dist-pkg/input/keyboard-runtime.js +23 -27
- package/dist-pkg/input/keyboard.d.ts +68 -63
- package/dist-pkg/input/keyboard.js +83 -105
- package/dist-pkg/input/keydown.d.ts +123 -137
- package/dist-pkg/input/keydown.js +284 -289
- package/dist-pkg/input/latch-edge.d.ts +33 -21
- package/dist-pkg/input/latch-edge.js +34 -35
- package/dist-pkg/input/latch-scope.d.ts +51 -50
- package/dist-pkg/input/latch-scope.js +61 -82
- package/dist-pkg/input/latch-store.d.ts +26 -30
- package/dist-pkg/input/latch-store.js +42 -50
- package/dist-pkg/input/latch-sync.d.ts +29 -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 +169 -0
- package/dist-pkg/input/pad-wizard.d.ts +99 -0
- package/dist-pkg/input/pad-wizard.js +256 -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 +59 -0
- package/dist-pkg/input/switch-scan.js +67 -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 -116
- package/dist-pkg/input/touch-bindings.js +158 -173
- package/dist-pkg/input/touch.d.ts +147 -72
- package/dist-pkg/input/touch.js +362 -126
- 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 +90 -117
- package/dist-pkg/input/transports.js +104 -106
- package/dist-pkg/input/virtual-controller.d.ts +82 -0
- package/dist-pkg/input/virtual-controller.js +69 -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 +59 -0
- package/dist-pkg/input/voice-map.js +123 -0
- package/dist-pkg/platform/audio-ambient.d.ts +13 -2
- package/dist-pkg/platform/audio-ambient.js +14 -14
- 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 +31 -39
- package/dist-pkg/platform/audio-sonar.d.ts +49 -152
- package/dist-pkg/platform/audio-sonar.js +124 -302
- package/dist-pkg/platform/audio.d.ts +62 -19
- package/dist-pkg/platform/audio.js +193 -168
- 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/flash-sampler.d.ts +19 -0
- package/dist-pkg/platform/flash-sampler.js +79 -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 +77 -0
- package/dist-pkg/platform/heavy-catalogue.js +256 -0
- package/dist-pkg/platform/heavy-mirror.d.ts +20 -0
- package/dist-pkg/platform/heavy-mirror.js +73 -0
- package/dist-pkg/platform/heavy.d.ts +136 -0
- package/dist-pkg/platform/heavy.js +324 -0
- package/dist-pkg/platform/interruptible-speech.d.ts +23 -16
- package/dist-pkg/platform/interruptible-speech.js +77 -54
- 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 +90 -0
- package/dist-pkg/platform/locale-host.d.ts +14 -0
- package/dist-pkg/platform/locale-host.js +45 -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 +64 -0
- package/dist-pkg/platform/reading-in-worker.js +125 -0
- package/dist-pkg/platform/reading-model.d.ts +94 -0
- package/dist-pkg/platform/reading-model.js +272 -0
- package/dist-pkg/platform/reading-runtime.d.ts +24 -0
- package/dist-pkg/platform/reading-runtime.js +164 -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 +80 -0
- package/dist-pkg/platform/reading.js +136 -0
- package/dist-pkg/platform/speech-recognition.d.ts +60 -0
- package/dist-pkg/platform/speech-recognition.js +104 -0
- package/dist-pkg/platform/speech.d.ts +23 -1
- package/dist-pkg/platform/speech.js +29 -18
- 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 +85 -39
- package/dist-pkg/platform/tts.js +447 -127
- 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 +40 -0
- package/dist-pkg/platform/voice-listener.js +88 -0
- package/dist-pkg/platform/voice-plan.d.ts +15 -98
- package/dist-pkg/platform/voice-plan.js +56 -143
- package/dist-pkg/platform/vosk-runtime.d.ts +96 -0
- package/dist-pkg/platform/vosk-runtime.js +151 -0
- package/dist-pkg/platform/vosk-vocabulary.d.ts +6 -0
- package/dist-pkg/platform/vosk-vocabulary.js +178 -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 +48 -12
- package/dist-pkg/render/crt.js +78 -80
- package/dist-pkg/render/cvd-matrices.d.ts +22 -18
- package/dist-pkg/render/cvd-matrices.js +37 -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 +67 -56
- package/dist-pkg/render/high-contrast.js +226 -217
- 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 +89 -86
- package/dist-pkg/render/viz-axes.js +128 -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 +45 -0
- package/dist-pkg/ui/aac-sets.js +41 -0
- package/dist-pkg/ui/audio-choices.d.ts +68 -0
- package/dist-pkg/ui/audio-choices.js +98 -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 +53 -0
- package/dist-pkg/ui/camera-control.js +48 -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/declared-words.d.ts +21 -0
- package/dist-pkg/ui/declared-words.js +66 -0
- 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 +94 -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 +157 -68
- package/dist-pkg/ui/fonts.js +305 -115
- 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 +47 -0
- package/dist-pkg/ui/game-options.js +158 -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 +87 -0
- package/dist-pkg/ui/help-panel.js +242 -0
- package/dist-pkg/ui/hud-bands.d.ts +62 -0
- package/dist-pkg/ui/hud-bands.js +146 -0
- 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 +73 -73
- 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/layout.d.ts +103 -28
- package/dist-pkg/ui/layout.js +117 -99
- 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/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 +61 -0
- package/dist-pkg/ui/menu-intent.js +88 -0
- package/dist-pkg/ui/menu-items.d.ts +20 -0
- package/dist-pkg/ui/menu-items.js +51 -0
- package/dist-pkg/ui/menu-nav.d.ts +98 -92
- package/dist-pkg/ui/menu-nav.js +398 -286
- 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 +150 -0
- package/dist-pkg/ui/panel-widgets.js +294 -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 +261 -347
- package/dist-pkg/ui/pause-icons.js +671 -601
- 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 +50 -0
- 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 +70 -0
- package/dist-pkg/ui/settings-aac.js +208 -0
- package/dist-pkg/ui/settings-audio.d.ts +97 -114
- package/dist-pkg/ui/settings-audio.js +493 -425
- package/dist-pkg/ui/settings-controls.d.ts +53 -96
- 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 +192 -0
- package/dist-pkg/ui/settings-mobility.js +332 -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 +58 -45
- package/dist-pkg/ui/settings-panel.js +189 -94
- package/dist-pkg/ui/settings-typo.d.ts +29 -78
- package/dist-pkg/ui/settings-typo.js +158 -129
- 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 +112 -135
- package/dist-pkg/ui/shell.js +148 -217
- 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 +3 -12
- package/dist-pkg/ui/title.js +49 -18
- package/dist-pkg/ui/top-band.d.ts +26 -0
- package/dist-pkg/ui/top-band.js +96 -0
- package/dist-pkg/ui/typo-choices.d.ts +71 -0
- package/dist-pkg/ui/typo-choices.js +85 -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 +77 -10
- package/dist-pkg/ui/vlibras.js +130 -81
- package/dist-pkg/ui/voice-control.d.ts +68 -0
- package/dist-pkg/ui/voice-control.js +276 -0
- package/dist-pkg/ui/voice-settings.d.ts +95 -0
- package/dist-pkg/ui/voice-settings.js +352 -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 +300 -44
- package/docs/LICENSES.md +189 -145
- package/package.json +51 -27
- 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 +388 -0
- 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/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/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 +301 -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/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/inter-400.woff2 +0 -0
- package/app/public/vendor/fonts/inter-700.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/newsreader-400.woff2 +0 -0
- package/app/public/vendor/fonts/newsreader-700.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/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/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/ufmag-400.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/guide-intensity.d.ts +0 -40
- package/dist-pkg/platform/guide-intensity.js +0 -73
- 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/latch-refusal.d.ts +0 -32
- package/dist-pkg/ui/latch-refusal.js +0 -60
- 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
|
@@ -1,125 +1,126 @@
|
|
|
1
1
|
// SPDX-License-Identifier: AGPL-3.0-or-later
|
|
2
|
-
// input/vocabulary-migration —
|
|
2
|
+
// input/vocabulary-migration — THE ONLY PLACE IN THE ENGINE ALLOWED TO SAY `jump`, AND FOR HOW LONG.
|
|
3
3
|
//
|
|
4
|
-
// =========================
|
|
5
|
-
//
|
|
6
|
-
//
|
|
7
|
-
//
|
|
4
|
+
// ========================= WHY THIS MODULE STANDS APART =========================
|
|
5
|
+
// The `action-vocabulary-boundary` gate fails the engine for naming the game's verbs, and it was right to fail
|
|
6
|
+
// this table when it was born inside `input/keyboard.ts`. But the table HAS to name them: translating the old
|
|
7
|
+
// vocabulary is literally its job.
|
|
8
8
|
//
|
|
9
|
-
// ⚠️
|
|
10
|
-
//
|
|
11
|
-
//
|
|
12
|
-
//
|
|
9
|
+
// ⚠️ AND THE WAY OUT WAS NOT RAISING THE CEILING. Raising a ceiling that "only shrinks" is the loosening the gate
|
|
10
|
+
// exists to prevent, and an exception with no address becomes a precedent for the next one. The way out was
|
|
11
|
+
// QUARANTINE: the whole coupling lives here, in a file whose name says it is historical, with a ceiling of its
|
|
12
|
+
// own and a date of death.
|
|
13
13
|
//
|
|
14
|
-
// ⚠️
|
|
15
|
-
//
|
|
16
|
-
//
|
|
14
|
+
// ⚠️ WHEN THIS GETS DELETED: when no data saved in the old format remains. The code side has no way to know that
|
|
15
|
+
// — the data is in each child's browser — so the criterion is time, and it is the Dev's. While any remains,
|
|
16
|
+
// deleting this file deletes the remapping of whoever made one.
|
|
17
17
|
//
|
|
18
|
-
// =========================
|
|
19
|
-
//
|
|
20
|
-
//
|
|
21
|
-
//
|
|
18
|
+
// ========================= WHAT IS LOST IF THIS IS WRONG =========================
|
|
19
|
+
// Whoever remapped keys usually remapped out of NEED — hand reach, a finger that does not stretch, a keyboard
|
|
20
|
+
// without a numpad. A saved scheme that stops matching raises no error: the keys simply stop responding, and the
|
|
21
|
+
// child concludes the game is broken. It is the loss of an adaptation, not of a preference.
|
|
22
22
|
/**
|
|
23
|
-
*
|
|
23
|
+
* Platform name → abstract position. **ADR-0086 §2**, not ADR-0074.
|
|
24
24
|
*
|
|
25
|
-
* ⚠️
|
|
26
|
-
* `run → action4`;
|
|
27
|
-
*
|
|
28
|
-
*
|
|
25
|
+
* ⚠️ THE DIFFERENCE BETWEEN THE TWO RECORDS IS THE CHILD'S KEY. ADR-0074 said `jump → action1` and
|
|
26
|
+
* `run → action4`; ADR-0086 corrected it to `run → action1` and `jump → action2`, having measured that the
|
|
27
|
+
* correction is the CONSERVATIVE reading — it leaves each verb on the key and the button it already held.
|
|
28
|
+
* Translating by mistake with 0074's table would raise no error at all: it would move jump from `J` to `U`
|
|
29
|
+
* silently.
|
|
29
30
|
*/
|
|
30
|
-
export const
|
|
31
|
+
export const OLD_VOCABULARY = Object.freeze({
|
|
31
32
|
run: 'action1',
|
|
32
33
|
jump: 'action2',
|
|
33
34
|
especial: 'action3',
|
|
34
35
|
swap: 'action4',
|
|
35
|
-
// ⚠️
|
|
36
|
-
//
|
|
37
|
-
//
|
|
38
|
-
//
|
|
39
|
-
//
|
|
36
|
+
// ⚠️ AND A FIFTH ENTRY THAT IS NOT A PLATFORM VERB. The touch layer called `pause` the position everything
|
|
37
|
+
// else calls `start` — two words for the same thing, and the touch one was the only one missing from the
|
|
38
|
+
// abstract set. A touch map saved before this has `start: 'pause'` in the START slot, and without this line
|
|
39
|
+
// that button would stop pausing: `decide()` now looks for `'start'` and would get `'pause'`, which is no
|
|
40
|
+
// longer anything — no error, no warning, and the only pause button a tablet has.
|
|
40
41
|
pause: 'start',
|
|
41
42
|
});
|
|
42
43
|
/**
|
|
43
|
-
* ⚠️
|
|
44
|
-
*
|
|
45
|
-
*
|
|
44
|
+
* ⚠️ THE SECOND SAVED DATA, and it nearly slipped through. The touch map (`incl_touchmap`) stores SLOT → ACTION,
|
|
45
|
+
* so the action name is in the VALUE and not the key: `{ b0: 'jump', b1: 'especial' }`. The keyboard scheme
|
|
46
|
+
* translator, which translates KEYS, would pass over it without touching anything.
|
|
46
47
|
*
|
|
47
|
-
* ⚠️
|
|
48
|
-
* `b0: 'jump'`
|
|
49
|
-
*
|
|
48
|
+
* ⚠️ AND THE DAMAGE WOULD BE WORSE THAN ON THE KEYBOARD. `normalizeTouchMap` merges what is stored OVER the
|
|
49
|
+
* default, so a saved `b0: 'jump'` would overwrite the correct `b0: 'action2'` — and the on-screen button would
|
|
50
|
+
* stop doing anything. On a public-school tablet, touch is not the alternative path: it is the only one.
|
|
50
51
|
*
|
|
51
|
-
*
|
|
52
|
-
*
|
|
52
|
+
* A BROWSER test found it (`tests/touch.browser.test.js`), after the `node` suite was already green — which is
|
|
53
|
+
* the argument for having both projects.
|
|
53
54
|
*/
|
|
54
|
-
export function
|
|
55
|
-
if (!
|
|
55
|
+
export function migrateTouchMap(touchMap) {
|
|
56
|
+
if (!touchMap)
|
|
56
57
|
return null;
|
|
57
|
-
const
|
|
58
|
-
for (const [slot,
|
|
59
|
-
|
|
58
|
+
const migrated = {};
|
|
59
|
+
for (const [slot, action] of Object.entries(touchMap)) {
|
|
60
|
+
migrated[slot] = OLD_VOCABULARY[action] ?? action;
|
|
60
61
|
}
|
|
61
|
-
return
|
|
62
|
+
return migrated;
|
|
62
63
|
}
|
|
63
64
|
/**
|
|
64
|
-
* ⚠️
|
|
65
|
-
*
|
|
66
|
-
*
|
|
67
|
-
*
|
|
65
|
+
* ⚠️ THE THIRD SAVED DATA, found by a sweep and not by accident. After the second turned up in a browser test,
|
|
66
|
+
* the right question stopped being "is this one migrated?" and became "HOW MANY persisted formats exist?". There
|
|
67
|
+
* are three, and this is the pad wizard's: `incl_padmap_<id>` stores ACTION → PHYSICAL BINDING,
|
|
68
|
+
* `{ jump: { b: 0 }, run: { b: 2 } }`, one per pad model.
|
|
68
69
|
*
|
|
69
|
-
* ⚠️
|
|
70
|
-
*
|
|
71
|
-
*
|
|
72
|
-
*
|
|
70
|
+
* ⚠️ AND IT IS THE MOST EXPENSIVE OF THE THREE TO LOSE. Such a map exists because the child (or whoever is with
|
|
71
|
+
* them) went through the wizard pressing button after button, one step per position the game names — probably
|
|
72
|
+
* because their pad is not "standard", and generic and adapted pads rarely are. Losing it sends that person back
|
|
73
|
+
* through the whole wizard.
|
|
73
74
|
*
|
|
74
|
-
* `_skip`
|
|
75
|
+
* `_skip` and any unknown key pass through, for the same reason as the other two migrations.
|
|
75
76
|
*/
|
|
76
|
-
export function
|
|
77
|
-
if (!
|
|
77
|
+
export function migrateControlMap(touchMap) {
|
|
78
|
+
if (!touchMap)
|
|
78
79
|
return null;
|
|
79
|
-
const
|
|
80
|
-
for (const [
|
|
81
|
-
|
|
80
|
+
const migrated = {};
|
|
81
|
+
for (const [key, value] of Object.entries(touchMap)) {
|
|
82
|
+
migrated[OLD_VOCABULARY[key] ?? key] = value;
|
|
82
83
|
}
|
|
83
|
-
return
|
|
84
|
+
return migrated;
|
|
84
85
|
}
|
|
85
86
|
/**
|
|
86
|
-
*
|
|
87
|
+
* Translates ONE saved scheme from the old vocabulary to the abstract one.
|
|
87
88
|
*
|
|
88
|
-
* ⚠️
|
|
89
|
-
*
|
|
90
|
-
*
|
|
91
|
-
*
|
|
92
|
-
*
|
|
89
|
+
* ⚠️ AN UNKNOWN KEY PASSES THROUGH UNTOUCHED, and that is a decision, not carelessness: `up`, `down`, `left` and
|
|
90
|
+
* `right` never changed names, and a scheme may carry a key this code does not know — data from a future
|
|
91
|
+
* version, or garbage. Deleting it would destroy data we do not understand, and it is what would make the four
|
|
92
|
+
* directions vanish. It is also what makes this function IDEMPOTENT: applied to an already migrated scheme, no
|
|
93
|
+
* key matches and the result equals the input, which matters because `loadKB` may run more than once a session.
|
|
93
94
|
*/
|
|
94
|
-
export function
|
|
95
|
-
if (!
|
|
95
|
+
export function migrateScheme(saved) {
|
|
96
|
+
if (!saved)
|
|
96
97
|
return null;
|
|
97
|
-
const
|
|
98
|
-
for (const [
|
|
99
|
-
const
|
|
100
|
-
// ⚠️
|
|
101
|
-
//
|
|
102
|
-
|
|
98
|
+
const migrated = {};
|
|
99
|
+
for (const [key, keys] of Object.entries(saved)) {
|
|
100
|
+
const newKey = OLD_VOCABULARY[key] ?? key;
|
|
101
|
+
// ⚠️ A HALF-migrated scheme (both keys present): the UNION, never the overwrite. Losing a key is the damage
|
|
102
|
+
// this module exists to prevent; having the same key twice is no damage at all.
|
|
103
|
+
migrated[newKey] = migrated[newKey] ? [...new Set([...migrated[newKey], ...keys])] : [...keys];
|
|
103
104
|
}
|
|
104
|
-
return
|
|
105
|
+
return migrated;
|
|
105
106
|
}
|
|
106
|
-
/**
|
|
107
|
-
export function
|
|
107
|
+
/** Translates the whole saved object — the solo scheme and the lists per player count. */
|
|
108
|
+
export function migrateSaved(s) {
|
|
108
109
|
if (!s)
|
|
109
110
|
return null;
|
|
110
|
-
const
|
|
111
|
+
const list = (arr) => (Array.isArray(arr) ? arr.map((m) => migrateScheme(m)) : undefined);
|
|
111
112
|
const out = {};
|
|
112
|
-
const solo =
|
|
113
|
+
const solo = migrateScheme(s.solo);
|
|
113
114
|
if (solo)
|
|
114
115
|
out.solo = solo;
|
|
115
116
|
for (const g of ['p2', 'p3', 'p4']) {
|
|
116
|
-
const v =
|
|
117
|
+
const v = list(s[g]);
|
|
117
118
|
if (v)
|
|
118
119
|
out[g] = v;
|
|
119
120
|
}
|
|
120
|
-
// `p34`
|
|
121
|
-
//
|
|
121
|
+
// `p34` migrates its VOCABULARY here and its SHAPE in `loadKB`, which already did that before this module
|
|
122
|
+
// existed. Without this line, the oldest data of all would be the only one to get lost.
|
|
122
123
|
if (Array.isArray(s.p34))
|
|
123
|
-
out.p34 = s.p34.map((m) =>
|
|
124
|
+
out.p34 = s.p34.map((m) => migrateScheme(m));
|
|
124
125
|
return out;
|
|
125
126
|
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
// SPDX-License-Identifier: AGPL-3.0-or-later
|
|
2
|
+
import type { Action } from '../core/actions.js';
|
|
3
|
+
/**
|
|
4
|
+
* Every word of one language, by position.
|
|
5
|
+
*
|
|
6
|
+
* ⚠️ WRITTEN AS THE RECOGNISER'S VOCABULARY SPELLS THEM — lowercase, with their accents (the Dev's words are «ação» and
|
|
7
|
+
* «Acción»): a grammar word the model does not know is dropped and its position goes mute (measured below). Comparing ignores
|
|
8
|
+
* accents: the reader (`platform/speech-recognition`) matches a heard sentence and a table entry by a key without them.
|
|
9
|
+
*/
|
|
10
|
+
export type VoiceWords = {
|
|
11
|
+
readonly [A in Action]?: readonly string[];
|
|
12
|
+
};
|
|
13
|
+
/** The table of the child's language. An unknown tag falls back to Portuguese, the project's base language (ADR-0010 pillar 3). */
|
|
14
|
+
export declare function voiceWordsFor(language: string): VoiceWords;
|
|
15
|
+
/**
|
|
16
|
+
* THE CLOSED GRAMMAR: every word the recogniser is allowed to return, and nothing else (ADR-0189, ADR-0193).
|
|
17
|
+
*
|
|
18
|
+
* 📌 A grammar is what makes 32 MiB answer in a quarter of a second, and it is also what makes it answer WRONG when a child
|
|
19
|
+
* says something that is not a command: the lab measured free speech being pushed to the nearest word («configurações de
|
|
20
|
+
* inclusão» → «quatro»). That is the cost of the closed list and the reason the words are short and unlike each other.
|
|
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 — 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.
|
|
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
|
+
};
|
|
36
|
+
export interface VoiceCommands {
|
|
37
|
+
/**
|
|
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.
|
|
44
|
+
* ⚠️ It answers on the PARTIAL and not at the end of the sentence (ADR-0193 erratum, the Dev's choice after running both):
|
|
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).
|
|
47
|
+
*/
|
|
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[];
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
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.
|
|
55
|
+
*
|
|
56
|
+
* 🎯 A PARTIAL GROWS, AND ONLY WHAT IS NEW FIRES. «acima» then «acima abaixo» is a child who said two words, and the second
|
|
57
|
+
* press must be `down`, not `up` all over again — the reader counts what it already answered for in each utterance.
|
|
58
|
+
*/
|
|
59
|
+
export declare function createVoiceCommands(language: string): VoiceCommands;
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
// SPDX-License-Identifier: AGPL-3.0-or-later
|
|
2
|
+
// input/voice-map — THE WORDS A CHILD SAYS, AND THE POSITION EACH ONE PRESSES (ADR-0204 erratum; issues #184, #190).
|
|
3
|
+
//
|
|
4
|
+
// This is the pure half of playing by voice: a table of words per language, a closed grammar built from it and the open menu's
|
|
5
|
+
// names, and what a heard phrase MEANS — a position, or an item by name (ADR-0194). WHEN a phrase is heard is the reader's
|
|
6
|
+
// (`platform/speech-recognition`). Nothing here opens a microphone or loads a model — the same division that let the gaze cycle
|
|
7
|
+
// be measured without a camera.
|
|
8
|
+
//
|
|
9
|
+
// 🎯 THE WORDS ARE THE DEV'S, checked by the Dev against what games use (racing R2 accelerate / L2 brake, shooters L2 aim / R2 fire)
|
|
10
|
+
// and then run in the lab's bar protocol in the three languages: pt 23/23, es 24/24, en 24/24 detected, all rated «ok».
|
|
11
|
+
// A position answers to ANY of its words, and L1/R1 are the ship's sides — his adaptation.
|
|
12
|
+
//
|
|
13
|
+
// ⚠️ ONE WORD IS KNOWN TO BE MISSING from a model's vocabulary: «boreste» is not in Vosk small pt (measured against its `Gr.fst`
|
|
14
|
+
// symbol table), so under that recogniser R1 answers only to «estibordo». It stays in the table because the browser's own
|
|
15
|
+
// recogniser has no closed vocabulary and does hear it — a word is dropped by the RECOGNISER that cannot hear it, never by this
|
|
16
|
+
// table, which is the Dev's decision written down.
|
|
17
|
+
import { spokenText, createCommandReader } from '../platform/speech-recognition.js';
|
|
18
|
+
const PT = {
|
|
19
|
+
up: ['acima'], down: ['abaixo'], left: ['esquerda'], right: ['direita'],
|
|
20
|
+
start: ['start'], select: ['select'],
|
|
21
|
+
// 🔴 `ação` WITH THE CEDILLA AND THE TILDE, measured in a browser: written `acao`, the pt model answered "Ignoring word
|
|
22
|
+
// missing in vocabulary: 'acao'" and the first position was MUTE — the child said the word and nothing happened. The
|
|
23
|
+
// spelling here is the recogniser's VOCABULARY's; whoever compares no longer looks at accents (the reader's key), so spelling it
|
|
24
|
+
// right costs nothing on the hearing side. ⚠️ `boreste` is still outside the small model's vocabulary (ADR-0204 erratum)
|
|
25
|
+
// and stays on the table on purpose: it is the Dev's word, and a larger model hears it.
|
|
26
|
+
action1: ['ação'], action2: ['confirma', 'pega', 'ativar', 'pulo'], action3: ['voltar', 'solta', 'cancelar', 'especial'],
|
|
27
|
+
action4: ['lista', 'troca'],
|
|
28
|
+
leftShoulder: ['bombordo'], leftTrigger: ['mira', 'freia'],
|
|
29
|
+
rightShoulder: ['estibordo', 'boreste'], rightTrigger: ['gatilho', 'acelera'],
|
|
30
|
+
};
|
|
31
|
+
const ES = {
|
|
32
|
+
up: ['arriba'], down: ['abajo'], left: ['izquierda'], right: ['derecha'],
|
|
33
|
+
start: ['start'], select: ['select'],
|
|
34
|
+
// `acción` with its accent, by the pt line's measurement: the model's vocabulary keeps the word as the language writes it.
|
|
35
|
+
action1: ['acción'], action2: ['confirma', 'recoger', 'activar', 'saltar'], action3: ['volver', 'soltar', 'cancelar', 'especial'],
|
|
36
|
+
action4: ['inventario', 'lista', 'cambiar'],
|
|
37
|
+
leftShoulder: ['babor'], leftTrigger: ['apuntar', 'frenar'],
|
|
38
|
+
rightShoulder: ['estribor'], rightTrigger: ['disparar', 'acelerar'],
|
|
39
|
+
};
|
|
40
|
+
const EN = {
|
|
41
|
+
up: ['up'], down: ['down'], left: ['left'], right: ['right'],
|
|
42
|
+
start: ['start'], select: ['select'],
|
|
43
|
+
action1: ['action'], action2: ['confirm', 'grab', 'pick up', 'activate', 'jump'], action3: ['back', 'drop', 'cancel', 'special'],
|
|
44
|
+
action4: ['inventory', 'swap'],
|
|
45
|
+
leftShoulder: ['port'], leftTrigger: ['aim', 'brake'],
|
|
46
|
+
rightShoulder: ['starboard'], rightTrigger: ['trigger', 'accelerate'],
|
|
47
|
+
};
|
|
48
|
+
const BY_LANGUAGE = { pt: PT, es: ES, en: EN };
|
|
49
|
+
/** The table of the child's language. An unknown tag falls back to Portuguese, the project's base language (ADR-0010 pillar 3). */
|
|
50
|
+
export function voiceWordsFor(language) {
|
|
51
|
+
return BY_LANGUAGE[language.split('-')[0].toLowerCase()] ?? PT;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* THE CLOSED GRAMMAR: every word the recogniser is allowed to return, and nothing else (ADR-0189, ADR-0193).
|
|
55
|
+
*
|
|
56
|
+
* 📌 A grammar is what makes 32 MiB answer in a quarter of a second, and it is also what makes it answer WRONG when a child
|
|
57
|
+
* says something that is not a command: the lab measured free speech being pushed to the nearest word («configurações de
|
|
58
|
+
* inclusão» → «quatro»). That is the cost of the closed list and the reason the words are short and unlike each other.
|
|
59
|
+
* ⚠️ `extra` is what the MENU is showing right now (ADR-0194): saying the name of an item activates it, so those words join the
|
|
60
|
+
* grammar while that menu is open and leave with it — AS THE LANGUAGE WRITES THEM (§1, «as shown»), accents kept: stripped,
|
|
61
|
+
* «configurações» is not in the model's vocabulary and the name goes mute, the same defect «acao» was.
|
|
62
|
+
*/
|
|
63
|
+
export function voiceGrammar(language, extra = []) {
|
|
64
|
+
const all = new Set();
|
|
65
|
+
for (const words of Object.values(voiceWordsFor(language)))
|
|
66
|
+
for (const p of words)
|
|
67
|
+
all.add(p.toLowerCase());
|
|
68
|
+
for (const e of extra) {
|
|
69
|
+
const clean = spokenText(e);
|
|
70
|
+
if (clean)
|
|
71
|
+
all.add(clean);
|
|
72
|
+
}
|
|
73
|
+
return [...all];
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* The Dev's words and the open menu's names, READ BY `platform/speech-recognition.createCommandReader` — the one reader of what
|
|
77
|
+
* was heard (ADR-0194 §2–§3); this adds only what a word MEANS here, the position it presses.
|
|
78
|
+
*
|
|
79
|
+
* 🎯 A PARTIAL GROWS, AND ONLY WHAT IS NEW FIRES. «acima» then «acima abaixo» is a child who said two words, and the second
|
|
80
|
+
* press must be `down`, not `up` all over again — the reader counts what it already answered for in each utterance.
|
|
81
|
+
*/
|
|
82
|
+
export function createVoiceCommands(language) {
|
|
83
|
+
const actionOf = new Map();
|
|
84
|
+
for (const [action, spoken] of Object.entries(voiceWordsFor(language))) {
|
|
85
|
+
for (const phrase of spoken)
|
|
86
|
+
if (!actionOf.has(spokenText(phrase)))
|
|
87
|
+
actionOf.set(spokenText(phrase), action);
|
|
88
|
+
}
|
|
89
|
+
const reader = createCommandReader([...actionOf.keys()]);
|
|
90
|
+
let names = [];
|
|
91
|
+
let utterance = 0;
|
|
92
|
+
let previous = [];
|
|
93
|
+
const meaning = (heard) => heard.flatMap((h) => {
|
|
94
|
+
if (h.kind === 'palavra') {
|
|
95
|
+
const action = actionOf.get(h.word);
|
|
96
|
+
return action ? [{ kind: 'position', action }] : [];
|
|
97
|
+
}
|
|
98
|
+
const name = names.find((n) => spokenText(n) === h.name);
|
|
99
|
+
return name === undefined ? [] : [{ kind: 'item', name }];
|
|
100
|
+
});
|
|
101
|
+
return {
|
|
102
|
+
items(n) { names = [...n]; reader.items(names); },
|
|
103
|
+
partial(text) {
|
|
104
|
+
const heard = spokenText(text).split(' ').filter(Boolean);
|
|
105
|
+
/*
|
|
106
|
+
* 🔴 A NEW UTTERANCE IS ONE THAT DOES NOT CONTINUE THE LAST, and counting words is not enough to see it: a recogniser
|
|
107
|
+
* starts a new partial without saying so — and does whenever the grammar changes, because a new grammar is a new
|
|
108
|
+
* recogniser — and «abaixo» after «acima abaixo» is shorter than what was already answered. What a partial of the same
|
|
109
|
+
* utterance always is, is the previous one plus more.
|
|
110
|
+
*/
|
|
111
|
+
if (!previous.every((p, i) => heard[i] === p))
|
|
112
|
+
utterance += 1;
|
|
113
|
+
previous = heard;
|
|
114
|
+
return meaning(reader.read(utterance, text, false));
|
|
115
|
+
},
|
|
116
|
+
final(text) {
|
|
117
|
+
const done = meaning(reader.read(utterance, text, true));
|
|
118
|
+
utterance += 1;
|
|
119
|
+
previous = [];
|
|
120
|
+
return done;
|
|
121
|
+
},
|
|
122
|
+
};
|
|
123
|
+
}
|
|
@@ -1,21 +1,32 @@
|
|
|
1
1
|
// SPDX-License-Identifier: AGPL-3.0-or-later
|
|
2
|
+
import type { Role, Spot } from '../core/contract.js';
|
|
2
3
|
interface Vec2 {
|
|
3
4
|
x: number;
|
|
4
5
|
y: number;
|
|
5
6
|
}
|
|
6
7
|
export interface AudioAmbientCtx {
|
|
8
|
+
/**
|
|
9
|
+
* WHERE THE WATER IS, ASKED OF THE GAME through the contract's `roleAt` — never read off a tile number. "Water is
|
|
10
|
+
* tile 3" is true of ONE map (the platformer's), not of the engine: a game with another numbering would hear a river
|
|
11
|
+
* in its lava and silence in its lake, with no error and no red test (ADR-0027's no. 1 coupling, the one
|
|
12
|
+
* `render/high-contrast` shed by receiving `roleOf`). `roleAt` and not a bespoke `isWater`, because every cartridge
|
|
13
|
+
* already answers it (`GameDeclaration.roleAt` is required) and 'water' is already a contract `Role`: a second
|
|
14
|
+
* question would be a second table to drift from the one that paints high contrast and routes the sonar. Asked in
|
|
15
|
+
* world units, at the corner of each cell of the neighbourhood (`TILE` per cell).
|
|
16
|
+
* ⚠️ REQUIRED, by ADR-0224's precedent: an optional port would let a game forget it, and forgetting it would silence
|
|
17
|
+
* the water without a word.
|
|
18
|
+
*/
|
|
19
|
+
roleAt: (at: Spot) => Role;
|
|
7
20
|
ensureAC: () => AudioContext | null;
|
|
8
21
|
getAudioCtx: () => AudioContext | null;
|
|
9
22
|
catNode: (cat: string) => AudioNode | null;
|
|
10
23
|
audioOut: () => AudioNode | null;
|
|
11
|
-
noiseBuffer: (ac: AudioContext) => AudioBuffer;
|
|
12
24
|
getSoundOn: () => boolean;
|
|
13
25
|
getVolume: () => number;
|
|
14
26
|
getAudioCat: () => Record<string, {
|
|
15
27
|
on: boolean;
|
|
16
28
|
}> | null;
|
|
17
29
|
getPlayers: () => Vec2[];
|
|
18
|
-
tileAt: (x: number, y: number) => number;
|
|
19
30
|
TILE: number;
|
|
20
31
|
getRainLevel: () => number;
|
|
21
32
|
}
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
// SPDX-License-Identifier: AGPL-3.0-or-later
|
|
2
|
-
// platform/audio-ambient —
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
//
|
|
6
|
-
//
|
|
7
|
-
//
|
|
8
|
-
|
|
9
|
-
// Extraído do game.js. Ver docs/5-Refactoring/plano-modularizacao-mapa.md (Tier 2, áudio rodada 4).
|
|
2
|
+
// platform/audio-ambient — a synthesised AMBIENT track (loops of filtered noise) + thunder. Only the SOUND lives here;
|
|
3
|
+
// the visual weather is the game's. The bridge to it: the rain level (0..1) is computed by the game's weather and READ
|
|
4
|
+
// here through a getter, so the rain's volume "follows the picture". Injection by closure.
|
|
5
|
+
// updateAmbient() — per frame: builds the track once (lazily) and sets the WATER gain (nearness of what the game
|
|
6
|
+
// calls 'water') and the RAIN gain (follows the rain level). Gated by audioCat.ambient.on.
|
|
7
|
+
// thunder(inten) — a synthesised low rumble (low-passed noise) of variable intensity; called by the weather.
|
|
8
|
+
import { noiseBuffer } from './audio.js';
|
|
10
9
|
export function createAudioAmbient(ctx) {
|
|
11
10
|
let _ambient = null;
|
|
12
11
|
function buildAmbient(ac) {
|
|
@@ -19,7 +18,7 @@ export function createAudioAmbient(ctx) {
|
|
|
19
18
|
const w = Math.random() * 2 - 1;
|
|
20
19
|
last = (last + 0.02 * w) / 1.02;
|
|
21
20
|
d[i] = last * 3.2;
|
|
22
|
-
} //
|
|
21
|
+
} // looping pink noise
|
|
23
22
|
const mk = (type, freq, q, vol) => {
|
|
24
23
|
const s = ac.createBufferSource();
|
|
25
24
|
s.buffer = buf;
|
|
@@ -38,7 +37,7 @@ export function createAudioAmbient(ctx) {
|
|
|
38
37
|
catch (e) { /* noop */ }
|
|
39
38
|
return g;
|
|
40
39
|
};
|
|
41
|
-
//
|
|
40
|
+
// traffic/rumble · leaves/wind · water (nearness) · rain (cycle)
|
|
42
41
|
return { hum: mk('lowpass', 480, 0, 0.055), wind: mk('highpass', 3200, 0, 0.028), water: mk('bandpass', 820, 1.4, 0), rain: mk('highpass', 1700, 0, 0) };
|
|
43
42
|
}
|
|
44
43
|
function updateAmbient() {
|
|
@@ -54,11 +53,11 @@ export function createAudioAmbient(ctx) {
|
|
|
54
53
|
let nearWater = 0;
|
|
55
54
|
for (let dx = -3; dx <= 3; dx++)
|
|
56
55
|
for (let dy = -3; dy <= 3; dy++) {
|
|
57
|
-
if (ctx.
|
|
56
|
+
if (ctx.roleAt({ x: (px + dx) * ctx.TILE, y: (py + dy) * ctx.TILE }) === 'water')
|
|
58
57
|
nearWater = Math.max(nearWater, 1 - Math.hypot(dx, dy) / 4.2);
|
|
59
58
|
}
|
|
60
59
|
_ambient.water.gain.setTargetAtTime(0.15 * nearWater, ac.currentTime, 0.3);
|
|
61
|
-
_ambient.rain.gain.setTargetAtTime(0.09 * ctx.getRainLevel(), ac.currentTime, 0.5); //
|
|
60
|
+
_ambient.rain.gain.setTargetAtTime(0.09 * ctx.getRainLevel(), ac.currentTime, 0.5); // the rain follows the rain level; 0 = full silence
|
|
62
61
|
}
|
|
63
62
|
function thunder(inten) {
|
|
64
63
|
if (!ctx.getSoundOn() || ctx.getVolume() <= 0)
|
|
@@ -68,8 +67,9 @@ export function createAudioAmbient(ctx) {
|
|
|
68
67
|
return;
|
|
69
68
|
try {
|
|
70
69
|
const vol = ctx.getVolume();
|
|
70
|
+
// the engine's own white noise (ADR-0258): a game could only ever hand back this same function
|
|
71
71
|
const src = ac.createBufferSource();
|
|
72
|
-
src.buffer =
|
|
72
|
+
src.buffer = noiseBuffer(ac);
|
|
73
73
|
src.loop = true;
|
|
74
74
|
const bq = ac.createBiquadFilter();
|
|
75
75
|
bq.type = 'lowpass';
|
|
@@ -83,7 +83,7 @@ export function createAudioAmbient(ctx) {
|
|
|
83
83
|
src.start(t);
|
|
84
84
|
src.stop(t + dur + 0.1);
|
|
85
85
|
}
|
|
86
|
-
catch (e) { /* Web Audio
|
|
86
|
+
catch (e) { /* no Web Audio */ }
|
|
87
87
|
}
|
|
88
88
|
return { updateAmbient, thunder };
|
|
89
89
|
}
|
|
@@ -1,39 +1,40 @@
|
|
|
1
1
|
// SPDX-License-Identifier: AGPL-3.0-or-later
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
3
|
+
* The definition of ONE earcon. The table is the GAME's; this is the shape the engine knows how to play.
|
|
4
4
|
*
|
|
5
|
-
* ⚠️
|
|
6
|
-
*
|
|
7
|
-
* consumidor redescobre por cópia é uma forma que diverge — foi assim que cinco cópias de `Gfx` divergiram
|
|
8
|
-
* nesta árvore, e está escrito noutro módulo.
|
|
5
|
+
* ⚠️ EXPORTED (#124), and its absence was an interface defect: a game declared its own copy of this type, word for word,
|
|
6
|
+
* because it had no way to name it. A shape each consumer rediscovers by copying is a shape that diverges.
|
|
9
7
|
*/
|
|
10
8
|
export interface SfxDef {
|
|
11
|
-
/**
|
|
9
|
+
/** The timbre. */
|
|
12
10
|
t: OscillatorType;
|
|
13
|
-
/**
|
|
11
|
+
/** The starting frequency, in hertz. */
|
|
14
12
|
f: number;
|
|
15
|
-
/**
|
|
13
|
+
/** The duration, in seconds. */
|
|
16
14
|
d: number;
|
|
17
|
-
/**
|
|
15
|
+
/** The caption's i18n KEY (deaf accessibility). Whoever shows it resolves it. */
|
|
18
16
|
cap?: string;
|
|
19
17
|
/**
|
|
20
|
-
*
|
|
18
|
+
* The FINAL frequency, in hertz. Absent = a held note, which is what there always was.
|
|
21
19
|
*
|
|
22
|
-
* ⚠️
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
20
|
+
* ⚠️ IT EXISTS BECAUSE AN EARCON HAS TO BE ABLE TO GO SOMEWHERE (#124). Measured building a football game: scoring and
|
|
21
|
+
* conceding must be told apart **by ear alone** — a blind child hears the room react and needs to know which way before
|
|
22
|
+
* the narration arrives. The obvious design is a figure that RISES for their goal and FALLS for the other's, and the
|
|
23
|
+
* table could not say it. What was left was high-and-long against low-and-short: distinguishable, and less information
|
|
24
|
+
* than the moment carries.
|
|
27
25
|
*
|
|
28
|
-
* ⚠️
|
|
29
|
-
*
|
|
26
|
+
* ⚠️ AND THE CAPABILITY WAS ALREADY IN THIS FILE, unreachable from the table: `doorSound` does exactly this with
|
|
27
|
+
* `frequency.exponentialRampToValueAtTime`. The fix was not new synthesis — it was opening the door.
|
|
30
28
|
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
29
|
+
* The ramp is EXPONENTIAL and not linear because pitch is perceived as a ratio, not a difference: a linear ramp from 200
|
|
30
|
+
* to 800 rises fast at the start and slowly at the end, and sounds crooked.
|
|
33
31
|
*/
|
|
34
32
|
f2?: number;
|
|
35
33
|
}
|
|
34
|
+
import type { Translate } from '../core/i18n.js';
|
|
36
35
|
export interface AudioEarconsCtx {
|
|
36
|
+
/** Translates in the page's language — the root's translator (ADR-0232 D3). REQUIRED: text built from nowhere is a raw key. */
|
|
37
|
+
t: Translate;
|
|
37
38
|
SFX: Record<string, SfxDef | undefined>;
|
|
38
39
|
ensureAC: () => AudioContext | null;
|
|
39
40
|
catNode: (cat: string) => AudioNode | null;
|