@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
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
// SPDX-License-Identifier: AGPL-3.0-or-later
|
|
2
|
+
// platform/vosk-vocabulary — THE WORDS A VOSK MODEL KNOWS, READ FROM ITS OWN ARCHIVE (ADR-0194 §4, ADR-0169).
|
|
3
|
+
//
|
|
4
|
+
// A menu item whose name has a word the model lacks cannot be said: Kaldi drops that word from the grammar and the item goes
|
|
5
|
+
// mute. The recogniser cannot tell the page so, and this was MEASURED in the delivery's runtime (`vosk-browser-dynamic-
|
|
6
|
+
// execution-0`), not assumed: the drop is a Kaldi warning («Ignoring word missing in vocabulary: 'acao'») written by the wasm to
|
|
7
|
+
// the WORKER's console, never posted to the page, and the bundle's API has no call that lists the vocabulary. So the page reads
|
|
8
|
+
// the list where the model keeps it — the output symbol table of its word graph `Gr.fst`, in the header, before any state — from
|
|
9
|
+
// the same archive the worker opens, and stops reading as soon as the table ends.
|
|
10
|
+
//
|
|
11
|
+
// 📏 In `vosk-model-small-pt-0.3.tar.gz` (the delivery's archive, sorted by `scripts/models/repack-vosk-models.py`) `Gr.fst` is
|
|
12
|
+
// the first entry and its table (99 105 words) ends 4 MB into the uncompressed tar; «configurações», «ação» and «estibordo» are
|
|
13
|
+
// in it, «configuracoes», «acao» and «boreste» are not — the same answers the earlier lab and browser measurements gave. The es
|
|
14
|
+
// and en archives were NOT on the machine that measured this; their `Gr.fst` should sit under `graph/`, after other entries,
|
|
15
|
+
// which the walk below passes over.
|
|
16
|
+
//
|
|
17
|
+
// ⚠️ A model with no `Gr.fst` answers `null` («cannot know»), not an empty set: such a model has no runtime grammar at all, and
|
|
18
|
+
// an empty set would report every word of every name as missing.
|
|
19
|
+
/** The magic numbers of an OpenFst binary file and of a symbol table written inside one (`fst/fst.h`, `fst/symbol-table.h`). */
|
|
20
|
+
const FST_MAGIC = 2125659606;
|
|
21
|
+
const SYMBOL_TABLE_MAGIC = 2125658996;
|
|
22
|
+
/** The header flags that say an input / output symbol table follows the header. */
|
|
23
|
+
const HAS_INPUT_SYMBOLS = 1;
|
|
24
|
+
const HAS_OUTPUT_SYMBOLS = 2;
|
|
25
|
+
const TAR_BLOCK = 512;
|
|
26
|
+
/** Guards against reading a corrupt length as a request for gigabytes. */
|
|
27
|
+
const MAX_STRING = 1 << 16;
|
|
28
|
+
const MAX_SYMBOLS = 5_000_000;
|
|
29
|
+
const UTF8 = new TextDecoder('utf-8');
|
|
30
|
+
const ASCII = new TextDecoder('latin1');
|
|
31
|
+
/** The archive ended, or a length in it cannot be true: whatever was being read cannot be known. */
|
|
32
|
+
class Unreadable extends Error {
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* A pull reader over a byte stream: takes exactly what it is asked for, across chunk boundaries, and THROWS `Unreadable` when the
|
|
36
|
+
* stream ends first — so a reader of a format states the format, and one `catch` answers every truncation.
|
|
37
|
+
*/
|
|
38
|
+
class Bytes {
|
|
39
|
+
chunks = [];
|
|
40
|
+
head = 0;
|
|
41
|
+
have = 0;
|
|
42
|
+
source;
|
|
43
|
+
constructor(source) { this.source = source; }
|
|
44
|
+
async fill(n) {
|
|
45
|
+
while (this.have < n) {
|
|
46
|
+
const { done, value } = await this.source.read();
|
|
47
|
+
if (done)
|
|
48
|
+
throw new Unreadable('the archive ended');
|
|
49
|
+
if (value.length) {
|
|
50
|
+
this.chunks.push(value);
|
|
51
|
+
this.have += value.length;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
drop(k) {
|
|
56
|
+
this.head += k;
|
|
57
|
+
this.have -= k;
|
|
58
|
+
if (this.head === this.chunks[0].length) {
|
|
59
|
+
this.chunks.shift();
|
|
60
|
+
this.head = 0;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
/** The next `n` bytes. */
|
|
64
|
+
async take(n) {
|
|
65
|
+
await this.fill(n);
|
|
66
|
+
const out = new Uint8Array(n);
|
|
67
|
+
for (let o = 0; o < n;) {
|
|
68
|
+
const k = Math.min(n - o, this.chunks[0].length - this.head);
|
|
69
|
+
out.set(this.chunks[0].subarray(this.head, this.head + k), o);
|
|
70
|
+
o += k;
|
|
71
|
+
this.drop(k);
|
|
72
|
+
}
|
|
73
|
+
return out;
|
|
74
|
+
}
|
|
75
|
+
/** Passes `n` bytes without keeping them. */
|
|
76
|
+
async skip(n) {
|
|
77
|
+
for (let left = n; left > 0;) {
|
|
78
|
+
await this.fill(1);
|
|
79
|
+
const k = Math.min(left, this.chunks[0].length - this.head);
|
|
80
|
+
left -= k;
|
|
81
|
+
this.drop(k);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
async int32() { return new DataView((await this.take(4)).buffer).getInt32(0, true); }
|
|
85
|
+
async int64() { return Number(new DataView((await this.take(8)).buffer).getBigInt64(0, true)); }
|
|
86
|
+
/** An OpenFst string: a 32-bit length, then that many bytes of UTF-8. */
|
|
87
|
+
async text() { return UTF8.decode(await this.take(bounded(await this.int32(), MAX_STRING))); }
|
|
88
|
+
}
|
|
89
|
+
/** A length read from the archive, refused when it cannot be one. */
|
|
90
|
+
function bounded(n, max) {
|
|
91
|
+
if (!Number.isFinite(n) || n < 0 || n > max)
|
|
92
|
+
throw new Unreadable(`a length of ${n}`);
|
|
93
|
+
return n;
|
|
94
|
+
}
|
|
95
|
+
/** A NUL-padded tar field as text. */
|
|
96
|
+
const field = (block, from, length) => ASCII.decode(block.subarray(from, from + length)).replace(/\0.*$/s, '');
|
|
97
|
+
/** The value of `path` in a pax extended header, if it sets one. */
|
|
98
|
+
const paxPath = (data) => /(?:^|\n)\d+ path=([^\n]*)\n/.exec(UTF8.decode(data))?.[1] ?? null;
|
|
99
|
+
/** The path a ustar header names: its prefix and its name. */
|
|
100
|
+
const headerPath = (header) => {
|
|
101
|
+
const prefix = field(header, 345, 155);
|
|
102
|
+
return prefix ? `${prefix}/${field(header, 0, 100)}` : field(header, 0, 100);
|
|
103
|
+
};
|
|
104
|
+
const isWordGraph = (type, path) => (type === '0' || type === '\0') && /(?:^|\/)Gr\.fst$/.test(path);
|
|
105
|
+
/**
|
|
106
|
+
* Walks the tar entries until one whose path ends in `/Gr.fst` and leaves the reader at its first byte. `false` when the archive
|
|
107
|
+
* ends without one. Pax (`x`) and GNU long-name (`L`) headers name the entry that follows them; a global pax header is skipped.
|
|
108
|
+
*/
|
|
109
|
+
async function toWordGraph(bytes) {
|
|
110
|
+
let named = null;
|
|
111
|
+
for (;;) {
|
|
112
|
+
const header = await bytes.take(TAR_BLOCK);
|
|
113
|
+
if (header.every((b) => b === 0))
|
|
114
|
+
return false;
|
|
115
|
+
const size = bounded(parseInt(field(header, 124, 12).trim() || '0', 8), Number.MAX_SAFE_INTEGER);
|
|
116
|
+
const padded = Math.ceil(size / TAR_BLOCK) * TAR_BLOCK;
|
|
117
|
+
const type = String.fromCharCode(header[156]);
|
|
118
|
+
if (type === 'x' || type === 'L') {
|
|
119
|
+
const data = (await bytes.take(padded)).subarray(0, size);
|
|
120
|
+
named = type === 'x' ? paxPath(data) : field(data, 0, size);
|
|
121
|
+
continue;
|
|
122
|
+
}
|
|
123
|
+
if (isWordGraph(type, named ?? headerPath(header)))
|
|
124
|
+
return true;
|
|
125
|
+
named = null;
|
|
126
|
+
await bytes.skip(padded);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
/** One symbol table, as `fst::SymbolTable::Write` lays it out: magic, name, available key, size, then (symbol, key) pairs. */
|
|
130
|
+
async function symbolTable(bytes) {
|
|
131
|
+
if ((await bytes.int32()) !== SYMBOL_TABLE_MAGIC)
|
|
132
|
+
throw new Unreadable('not a symbol table');
|
|
133
|
+
await bytes.text();
|
|
134
|
+
await bytes.int64();
|
|
135
|
+
const size = bounded(await bytes.int64(), MAX_SYMBOLS);
|
|
136
|
+
const words = new Set();
|
|
137
|
+
for (let i = 0; i < size; i++) {
|
|
138
|
+
words.add(await bytes.text());
|
|
139
|
+
await bytes.int64();
|
|
140
|
+
}
|
|
141
|
+
return words;
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* The OpenFst header up to its flags — magic, fst type, arc type, version, flags, properties, start, states, arcs — and the flags,
|
|
145
|
+
* leaving the reader at the first symbol table.
|
|
146
|
+
*/
|
|
147
|
+
async function fstFlags(bytes) {
|
|
148
|
+
if ((await bytes.int32()) !== FST_MAGIC)
|
|
149
|
+
throw new Unreadable('not an OpenFst file');
|
|
150
|
+
await bytes.text();
|
|
151
|
+
await bytes.text();
|
|
152
|
+
await bytes.int32();
|
|
153
|
+
const flags = await bytes.int32();
|
|
154
|
+
await bytes.skip(4 * 8);
|
|
155
|
+
return flags;
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* The words the model in this `.tar.gz` knows — the output symbol table of its `Gr.fst` — or `null` when that cannot be read
|
|
159
|
+
* (no word graph, a header that is not OpenFst's, a stream that ends early). Stops reading the archive once the table is read.
|
|
160
|
+
*/
|
|
161
|
+
export async function readModelVocabulary(archive) {
|
|
162
|
+
const reader = archive.pipeThrough(new DecompressionStream('gzip')).getReader();
|
|
163
|
+
const bytes = new Bytes(reader);
|
|
164
|
+
try {
|
|
165
|
+
if (!(await toWordGraph(bytes)))
|
|
166
|
+
return null;
|
|
167
|
+
const flags = await fstFlags(bytes);
|
|
168
|
+
const input = flags & HAS_INPUT_SYMBOLS ? await symbolTable(bytes) : null;
|
|
169
|
+
// the words a grammar is matched against are the OUTPUT side; an acceptor written with one table has it on both
|
|
170
|
+
return flags & HAS_OUTPUT_SYMBOLS ? await symbolTable(bytes) : input;
|
|
171
|
+
}
|
|
172
|
+
catch {
|
|
173
|
+
return null; // truncated, not OpenFst, not gzip: each is one more «cannot know»
|
|
174
|
+
}
|
|
175
|
+
finally {
|
|
176
|
+
reader.cancel().catch(() => { });
|
|
177
|
+
}
|
|
178
|
+
}
|
|
@@ -1,13 +1,19 @@
|
|
|
1
1
|
// SPDX-License-Identifier: AGPL-3.0-or-later
|
|
2
2
|
import * as PIXI from 'pixi.js';
|
|
3
|
-
|
|
3
|
+
/**
|
|
4
|
+
* The document a canvas is made in — only what `makeCanvas` touches. A PARAMETER and not the global `document`
|
|
5
|
+
* (ADR-0232, issue #207): these helpers hold nothing, so they stay functions and take what they use; a root that serves
|
|
6
|
+
* another document (a test, a second root) gets its canvases from that one.
|
|
7
|
+
*/
|
|
8
|
+
export type CanvasDoc = Pick<Document, 'createElement'>;
|
|
9
|
+
export declare const makeCanvas: (doc: CanvasDoc, w: number, h: number) => HTMLCanvasElement;
|
|
4
10
|
export declare const tex: (cv: HTMLCanvasElement) => PIXI.Texture;
|
|
5
11
|
export declare function pixDisc(c: CanvasRenderingContext2D, cx: number, cy: number, r: number, col: string, edge?: string): void;
|
|
6
|
-
/**
|
|
12
|
+
/** A filled-rectangle brush: paints `w×h` at `(x,y)` with `col`. It is the `px` every painter gets. */
|
|
7
13
|
export type PixelBrush = (x: number, y: number, w: number, h: number, col: string) => void;
|
|
8
|
-
/**
|
|
14
|
+
/** The body of a pixel-art painting: it gets the brush and draws. No return, no state of its own. */
|
|
9
15
|
export type PixelPainter = (px: PixelBrush) => void;
|
|
10
|
-
/**
|
|
11
|
-
export declare function pixelCanvas(w: number, h: number, paint: PixelPainter): HTMLCanvasElement;
|
|
12
|
-
/** `pixelCanvas` + `tex`:
|
|
13
|
-
export declare const pixelTexture: (w: number, h: number, paint: PixelPainter) => PIXI.Texture;
|
|
16
|
+
/** An offscreen `w×h` canvas made in `doc` and painted by `paint` — the routine those local helpers duplicated. */
|
|
17
|
+
export declare function pixelCanvas(doc: CanvasDoc, w: number, h: number, paint: PixelPainter): HTMLCanvasElement;
|
|
18
|
+
/** `pixelCanvas` + `tex`: a shortcut for whoever wants the NEAREST texture directly (sprite art with no post-processing). */
|
|
19
|
+
export declare const pixelTexture: (doc: CanvasDoc, w: number, h: number, paint: PixelPainter) => PIXI.Texture;
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
// SPDX-License-Identifier: AGPL-3.0-or-later
|
|
2
|
-
// render/canvas.ts —
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
import * as PIXI from 'pixi.js'; // 7.4.2
|
|
6
|
-
//
|
|
7
|
-
export const makeCanvas = (w, h) => { const c =
|
|
8
|
-
// Canvas → PIXI.Texture
|
|
2
|
+
// render/canvas.ts — leaf drawing primitives: offscreen canvas → PixiJS texture + a crisp pixel-art disc.
|
|
3
|
+
// The base of every procedural art a game draws. Depends only on PIXI (npm) and the document it is HANDED, ZERO game
|
|
4
|
+
// state. NEAREST everywhere (pixel art, no anti-aliasing).
|
|
5
|
+
import * as PIXI from 'pixi.js'; // 7.4.2 through npm (Vite bundles it)
|
|
6
|
+
// An offscreen canvas of the requested size (a procedural texture source), made in `doc`.
|
|
7
|
+
export const makeCanvas = (doc, w, h) => { const c = doc.createElement('canvas'); c.width = w; c.height = h; return c; };
|
|
8
|
+
// Canvas → PIXI.Texture with NEAREST scaling (crisp pixel art).
|
|
9
9
|
export const tex = (cv) => { const t = PIXI.Texture.from(cv); t.baseTexture.scaleMode = PIXI.SCALE_MODES.NEAREST; return t; };
|
|
10
|
-
//
|
|
10
|
+
// A disc of WHOLE pixels (crisp jagged edge, no anti-aliasing of vector arcs). edge = the border colour (optional).
|
|
11
11
|
export function pixDisc(c, cx, cy, r, col, edge) { for (let y = Math.floor(cy - r); y <= cy + r; y++)
|
|
12
12
|
for (let x = Math.floor(cx - r); x <= cx + r; x++) {
|
|
13
13
|
const d = Math.hypot(x - cx, y - cy);
|
|
@@ -16,11 +16,11 @@ export function pixDisc(c, cx, cy, r, col, edge) { for (let y = Math.floor(cy -
|
|
|
16
16
|
c.fillRect(x, y, 1, 1);
|
|
17
17
|
}
|
|
18
18
|
} }
|
|
19
|
-
/**
|
|
20
|
-
export function pixelCanvas(w, h, paint) {
|
|
21
|
-
const cv = makeCanvas(w, h), c = cv.getContext('2d');
|
|
19
|
+
/** An offscreen `w×h` canvas made in `doc` and painted by `paint` — the routine those local helpers duplicated. */
|
|
20
|
+
export function pixelCanvas(doc, w, h, paint) {
|
|
21
|
+
const cv = makeCanvas(doc, w, h), c = cv.getContext('2d');
|
|
22
22
|
paint((x, y, ww, hh, col) => { c.fillStyle = col; c.fillRect(x, y, ww, hh); });
|
|
23
23
|
return cv;
|
|
24
24
|
}
|
|
25
|
-
/** `pixelCanvas` + `tex`:
|
|
26
|
-
export const pixelTexture = (w, h, paint) => tex(pixelCanvas(w, h, paint));
|
|
25
|
+
/** `pixelCanvas` + `tex`: a shortcut for whoever wants the NEAREST texture directly (sprite art with no post-processing). */
|
|
26
|
+
export const pixelTexture = (doc, w, h, paint) => tex(pixelCanvas(doc, w, h, paint));
|
package/dist-pkg/render/crt.d.ts
CHANGED
|
@@ -1,19 +1,55 @@
|
|
|
1
1
|
// SPDX-License-Identifier: AGPL-3.0-or-later
|
|
2
|
-
type
|
|
2
|
+
import type { Store } from '../platform/storage.js';
|
|
3
|
+
export type CrtCfg = {
|
|
3
4
|
scan: number;
|
|
4
5
|
vig: number;
|
|
5
6
|
round: number;
|
|
6
7
|
};
|
|
7
|
-
/**
|
|
8
|
-
*
|
|
9
|
-
*
|
|
8
|
+
/** The factory CRT. Named because the menu's "restore defaults" (ADR-0028) needs the SAME value the boot load uses when
|
|
9
|
+
* nothing was saved — two copies would be two chances for the reset to return a CRT the game never showed. Frozen: a
|
|
10
|
+
* default someone can write at runtime is not a default. */
|
|
10
11
|
export declare const CRT_DEFAULT: Readonly<CrtCfg>;
|
|
11
|
-
/**
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
12
|
+
/** Where the CRT is kept: the page's store, built by the root (ADR-0232, issue #207). */
|
|
13
|
+
type CrtStore = Pick<Store, 'get' | 'setJSON'>;
|
|
14
|
+
export interface CrtCtx {
|
|
15
|
+
/** The element the classes go on (`#game-region`) — a GETTER, because a `mount()` may swap it; `null` = nothing to draw on. */
|
|
16
|
+
region: () => HTMLElement | null;
|
|
17
|
+
/** The window, for its pixel ratio only (the scanline period is one art pixel in REAL pixels). */
|
|
18
|
+
win: Pick<Window, 'devicePixelRatio'>;
|
|
19
|
+
/**
|
|
20
|
+
* THE PLAYER COUNT, as the GETTER of the round the root owns: the screen grid sets how many art lines tall the region is.
|
|
21
|
+
* A getter and not a number because players join and leave.
|
|
22
|
+
*/
|
|
23
|
+
numPlayers: () => number;
|
|
24
|
+
/**
|
|
25
|
+
* Does the SCANLINE yield now? The ROOT answers, because the root is where the visual modes are known (ADR-0232): under
|
|
26
|
+
* every visual accessibility mode but a colour-vision one on its own (ADR-0241). A correction or a simulation of colour
|
|
27
|
+
* blindness changes hue; a stripe costs a low-vision child half the vertical resolution of a glyph (ADR-0047).
|
|
28
|
+
*
|
|
29
|
+
* A question for the whole screen and not for "player 1": the CRT is GLOBAL decoration, and if it contradicts any
|
|
30
|
+
* child's accessibility, the decoration yields.
|
|
31
|
+
*/
|
|
32
|
+
scanlineYields: () => boolean;
|
|
33
|
+
/**
|
|
34
|
+
* Does the VIGNETTE yield now? Under EVERY visual accessibility mode, the colour-vision ones included (ADR-0047,
|
|
35
|
+
* kept by ADR-0241): darkened edges work against a mode that exists to raise contrast, whatever it does to hue.
|
|
36
|
+
*/
|
|
37
|
+
vignetteYields: () => boolean;
|
|
38
|
+
/** Where the CRT is read from at build and kept at every `apply()`. Required: a look read from nowhere resets each visit. */
|
|
39
|
+
store: CrtStore;
|
|
40
|
+
}
|
|
41
|
+
/** One root's CRT. */
|
|
42
|
+
export interface Crt {
|
|
43
|
+
/** The LIVE config, shared by reference with the motion panel: the stored CRT, or the factory one. */
|
|
44
|
+
readonly cfg: CrtCfg;
|
|
45
|
+
/** Applies the CRT CSS classes to the region and persists `cfg`. Called at boot and when the menu changes. */
|
|
46
|
+
apply(): void;
|
|
47
|
+
/** Re-anchors the scanline to real pixels — call it after every change of scale (a layout's `afterScale`). */
|
|
48
|
+
scanVars(): void;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Builds the CRT and READS the stored one into `cfg` — at build, never at import (ADR-0232). The config lives in this
|
|
52
|
+
* closure, so a second root on the page keeps its own.
|
|
53
|
+
*/
|
|
54
|
+
export declare function createCrt(ctx: CrtCtx): Crt;
|
|
19
55
|
export {};
|
package/dist-pkg/render/crt.js
CHANGED
|
@@ -1,92 +1,90 @@
|
|
|
1
1
|
// SPDX-License-Identifier: AGPL-3.0-or-later
|
|
2
|
-
// render/crt.ts —
|
|
3
|
-
//
|
|
4
|
-
// on/off)
|
|
5
|
-
// PIXELS
|
|
6
|
-
//
|
|
7
|
-
|
|
2
|
+
// render/crt.ts — the CRT look (visual sensitivity menu): scanlines/vignette/corners, CSS only (classes on the game
|
|
3
|
+
// region). `createCrt` builds one per root (ADR-0232 D4, issue #207): its `cfg` is the config {scan,vig,round} (0=off,1,2;
|
|
4
|
+
// scan/vig are on/off) read from the injected store at build, migrating the old boolean format. `scanVars` anchors the
|
|
5
|
+
// scanline to REAL PIXELS (recomputed from the region's real height + dpr → 1 line per art pixel, regular spacing).
|
|
6
|
+
// Everything it touches arrives by injection: the region, the window's pixel ratio, the player count, the two
|
|
7
|
+
// accessibility answers (does the scanline yield? does the vignette?) and the store.
|
|
8
8
|
import { screenGrid } from '../core/screens.js';
|
|
9
|
-
import
|
|
10
|
-
//
|
|
11
|
-
/**
|
|
12
|
-
*
|
|
13
|
-
*
|
|
9
|
+
import { KEYS } from '../platform/storage-keys.js';
|
|
10
|
+
// scanlines ON by default (the Dev's decision). Migrates incl_crt (boolean) → incl_crt2 (levels 0..2).
|
|
11
|
+
/** The factory CRT. Named because the menu's "restore defaults" (ADR-0028) needs the SAME value the boot load uses when
|
|
12
|
+
* nothing was saved — two copies would be two chances for the reset to return a CRT the game never showed. Frozen: a
|
|
13
|
+
* default someone can write at runtime is not a default. */
|
|
14
14
|
export const CRT_DEFAULT = Object.freeze({ scan: 1, vig: 0, round: 1 });
|
|
15
|
-
// A CONTAGEM DE JOGADORES entra por injeção desde 2026-08-26. Era `numPlayers`, um `let` de `core/state`
|
|
16
|
-
// importado como binding vivo — e um `let` de módulo é compartilhado por qualquer segundo jogo que a
|
|
17
|
-
// mesma página carregue (D13 do `demos`, ADR-0038). O que entra aqui é o GETTER da rodada que a raiz
|
|
18
|
-
// possui; o `let` que sobra guarda a função, não o número.
|
|
19
|
-
let _numJogadores = () => 1;
|
|
20
15
|
/**
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
* nunca tinha sido implementado, e a emenda de 2026-08-26 mediu: com a vinheta ligada, `crt-vig-1` sobrevivia
|
|
25
|
-
* em `hc-direto`, `fix-deuter`, `lv-blur` e `blind`. Uma vinheta escurecendo as bordas trabalha contra o modo
|
|
26
|
-
* que existe para AUMENTAR contraste.
|
|
27
|
-
*
|
|
28
|
-
* `ALGUM` e não "o jogador 1": o CRT é decoração GLOBAL, uma só para a tela inteira. Não há como escurecer as
|
|
29
|
-
* bordas de meia tela. Se a decoração e a acessibilidade de qualquer criança se contradizem, quem cede é a
|
|
30
|
-
* decoração — que é literalmente o que "precedência a11y > estética" quer dizer.
|
|
16
|
+
* The CRT a machine kept, from the two formats it may hold. The current one wins; the OLD one (all booleans) is migrated:
|
|
17
|
+
* the vignette and the corners come across, and the scanlines come back ON once, because they became the default after
|
|
18
|
+
* that format existed. Scanlines and vignette are on/off; only the corners have three levels.
|
|
31
19
|
*/
|
|
32
|
-
|
|
33
|
-
/** Liga a contagem de jogadores e a pergunta de a11y. Chamado uma vez pela raiz, antes do 1º `applyCrt()`. */
|
|
34
|
-
export function initCrt(deps) {
|
|
35
|
-
_numJogadores = deps.numJogadores;
|
|
36
|
-
_a11yVisualAtiva = deps.a11yVisualAtiva;
|
|
37
|
-
}
|
|
38
|
-
export const CRT = (() => {
|
|
20
|
+
function crtFromStored(current, legacy) {
|
|
39
21
|
const d = { ...CRT_DEFAULT };
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
if (
|
|
44
|
-
|
|
45
|
-
if (k in s) {
|
|
46
|
-
const v = s[k];
|
|
47
|
-
if (fresh && k === 'scan')
|
|
48
|
-
continue;
|
|
49
|
-
d[k] = v === true ? (k === 'round' ? 2 : 1) : v === false ? (k === 'round' ? 1 : 0) : Math.max(0, Math.min(2, v | 0));
|
|
50
|
-
}
|
|
22
|
+
const record = storedRecord(current, legacy);
|
|
23
|
+
const migrating = !current;
|
|
24
|
+
for (const k of Object.keys(d)) {
|
|
25
|
+
if (record && k in record && !(migrating && k === 'scan'))
|
|
26
|
+
d[k] = levelOf(k, record[k]);
|
|
51
27
|
}
|
|
52
|
-
catch (e) { /* noop: file:// / modo privado */ }
|
|
53
28
|
d.scan = d.scan ? 1 : 0;
|
|
54
|
-
d.vig = d.vig ? 1 : 0;
|
|
29
|
+
d.vig = d.vig ? 1 : 0;
|
|
55
30
|
return d;
|
|
56
|
-
})();
|
|
57
|
-
// Ancora a scanline em px REAIS: 1 linha por pixel de ARTE (kDev inteiro) → espaçamento SEMPRE regular em qualquer dpr.
|
|
58
|
-
export function crtScanVars() {
|
|
59
|
-
const g = $('#game-region');
|
|
60
|
-
if (!g || !CRT.scan)
|
|
61
|
-
return;
|
|
62
|
-
const { rows } = screenGrid(_numJogadores()), dpr = window.devicePixelRatio || 1;
|
|
63
|
-
const perDev = Math.max(2, Math.round((g.clientHeight || 360) * dpr / (180 * rows))); // kDev = px REAIS por linha de arte (INTEIRO)
|
|
64
|
-
g.style.setProperty('--scan-per', (perDev / dpr) + 'px'); // período = kDev px reais (1 linha de arte)
|
|
65
|
-
g.style.setProperty('--scan-line', (Math.max(1, Math.round(dpr)) / dpr) + 'px'); // linha = 1 px REAL
|
|
66
31
|
}
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
//
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
32
|
+
/** The record a machine kept, the current format first — or `null` where there is none a CRT can be read from. */
|
|
33
|
+
function storedRecord(current, legacy) {
|
|
34
|
+
try {
|
|
35
|
+
const s = JSON.parse(current || legacy || 'null');
|
|
36
|
+
// a number or a string is not a record: reading keys in it would throw, and the answer is the factory CRT
|
|
37
|
+
return s && typeof s === 'object' ? s : null;
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
return null;
|
|
41
|
+
} // a record that cannot be read is the factory CRT, never a broken boot
|
|
42
|
+
}
|
|
43
|
+
/** One stored value as a level: the old format's `true`/`false` mapped (round corners on are the ROUNDEST), the rest 0–2. */
|
|
44
|
+
function levelOf(k, v) {
|
|
45
|
+
if (v === true)
|
|
46
|
+
return k === 'round' ? 2 : 1;
|
|
47
|
+
if (v === false)
|
|
48
|
+
return k === 'round' ? 1 : 0;
|
|
49
|
+
return Math.max(0, Math.min(2, v | 0));
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Builds the CRT and READS the stored one into `cfg` — at build, never at import (ADR-0232). The config lives in this
|
|
53
|
+
* closure, so a second root on the page keeps its own.
|
|
54
|
+
*/
|
|
55
|
+
export function createCrt(ctx) {
|
|
56
|
+
const { store } = ctx;
|
|
57
|
+
const cfg = crtFromStored(store.get(KEYS.crt, null), store.get(KEYS.crtLegacy, null));
|
|
58
|
+
// Anchors the scanline to REAL px: 1 line per ART pixel (an integer kDev) → ALWAYS regular spacing at any dpr.
|
|
59
|
+
function scanVars() {
|
|
60
|
+
const g = ctx.region();
|
|
61
|
+
if (!g || !cfg.scan)
|
|
62
|
+
return;
|
|
63
|
+
const { rows } = screenGrid(ctx.numPlayers()), dpr = ctx.win.devicePixelRatio || 1;
|
|
64
|
+
const perDev = Math.max(2, Math.round((g.clientHeight || 360) * dpr / (180 * rows))); // kDev = REAL px per art line (INTEGER)
|
|
65
|
+
g.style.setProperty('--scan-per', (perDev / dpr) + 'px'); // period = kDev real px (1 art line)
|
|
66
|
+
g.style.setProperty('--scan-line', (Math.max(1, Math.round(dpr)) / dpr) + 'px'); // line = 1 REAL px
|
|
67
|
+
}
|
|
68
|
+
function apply() {
|
|
69
|
+
const g = ctx.region();
|
|
70
|
+
if (!g)
|
|
71
|
+
return;
|
|
72
|
+
['crt-scan-1', 'crt-vig-1', 'crt-round-0', 'crt-round-2'].forEach((c) => g.classList.remove(c));
|
|
73
|
+
// EACH EFFECT YIELDS TO ITS OWN ANSWER (ADR-0047, ADR-0241): the vignette to every visual mode, the scanline to every
|
|
74
|
+
// one but a colour-vision mode on its own. There is no escape switch for the child, by the Dev's decision (ADR-0047).
|
|
75
|
+
//
|
|
76
|
+
// The stored value is NOT changed: the preference stays and counts again by itself on leaving the accessibility
|
|
77
|
+
// mode. Suppressing is not turning off — it is the distinction that keeps the child from losing what they chose every
|
|
78
|
+
// time they turn high contrast on.
|
|
79
|
+
if (cfg.scan && !ctx.scanlineYields()) {
|
|
80
|
+
g.classList.add('crt-scan-' + cfg.scan);
|
|
81
|
+
scanVars();
|
|
82
|
+
}
|
|
83
|
+
if (cfg.vig && !ctx.vignetteYields())
|
|
84
|
+
g.classList.add('crt-vig-' + cfg.vig);
|
|
85
|
+
if (cfg.round !== 1)
|
|
86
|
+
g.classList.add('crt-round-' + cfg.round); // 1 = the default look (8px), no class
|
|
87
|
+
store.setJSON(KEYS.crt, cfg);
|
|
86
88
|
}
|
|
87
|
-
|
|
88
|
-
g.classList.add('crt-vig-' + CRT.vig);
|
|
89
|
-
if (CRT.round !== 1)
|
|
90
|
-
g.classList.add('crt-round-' + CRT.round); // 1 = visual padrão (8px), sem classe
|
|
91
|
-
store.setJSON(store.KEYS.crt, CRT);
|
|
89
|
+
return { cfg, apply, scanVars };
|
|
92
90
|
}
|
|
@@ -1,35 +1,39 @@
|
|
|
1
1
|
// SPDX-License-Identifier: AGPL-3.0-or-later
|
|
2
|
-
/**
|
|
2
|
+
/** The six colour-blindness mode keys — the SAME keys as `VIZ_MODES` in render/viz-modes. */
|
|
3
3
|
export type CvdKey = 'sim-protan' | 'sim-deuter' | 'sim-tritan' | 'fix-protan' | 'fix-deuter' | 'fix-tritan';
|
|
4
|
-
/**
|
|
4
|
+
/**
|
|
5
|
+
* Canonical order: the three simulations (what the person sees) before the three corrections (what helps them see).
|
|
6
|
+
* It is also THE list of colour-vision modes the rest of the engine asks about — `onlyColourVision` (render/viz-axes)
|
|
7
|
+
* reads it for the scanline that stays under them (ADR-0241).
|
|
8
|
+
*/
|
|
5
9
|
export declare const CVD_KEYS: readonly CvdKey[];
|
|
6
10
|
/**
|
|
7
|
-
*
|
|
11
|
+
* The matrices, 4×5 in row order. Row A = `0 0 0 1 0` in all of them: none of the six modes touches alpha.
|
|
8
12
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
+
* SIMULATION (Machado, Oliveira & Fernandes 2009, severity 1.0 — values checked on the authors' page, UFRGS).
|
|
14
|
+
* CORRECTION (canonical daltonisation): the R row is identity — there is no point modulating the channel the person
|
|
15
|
+
* cannot tell apart — and the error is reinjected into G and B, where there is discrimination; each row sums to 1, so
|
|
16
|
+
* white and greys are preserved.
|
|
13
17
|
*/
|
|
14
18
|
export declare const CVD_MATRIX: Record<CvdKey, readonly number[]>;
|
|
15
19
|
/**
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
20
|
+
* Mode → the SVG `<filter>` id. The ids are this module's PUBLIC API: `VIZ_FILTER` (render/viz-modes) asks for the
|
|
21
|
+
* filter by `url(#…)`, and this map is what promises the filter with that id will exist in the document. Renaming an id
|
|
22
|
+
* here without renaming it there blanks the canvas (a reference to a missing filter does not render).
|
|
19
23
|
*/
|
|
20
24
|
export declare const CVD_SVG_ID: Record<CvdKey, string>;
|
|
21
|
-
/**
|
|
25
|
+
/** A `<feColorMatrix>`'s `values` attribute: the 4 rows separated by a double space (readability). PURE. */
|
|
22
26
|
export declare function cvdMatrixValues(k: CvdKey): string;
|
|
23
27
|
/**
|
|
24
|
-
*
|
|
28
|
+
* Generates the six `<filter>`s INSIDE the given host (an SVG `<defs>`), from `CVD_MATRIX`.
|
|
25
29
|
*
|
|
26
|
-
*
|
|
27
|
-
* `createElementNS` (
|
|
28
|
-
*
|
|
30
|
+
* Why at boot and not written by hand in the HTML: that was exactly the second copy of the numbers. Built with
|
|
31
|
+
* `createElementNS` (and not `innerHTML`) because `<filter>`/`<feColorMatrix>` only work in the SVG namespace — with
|
|
32
|
+
* innerHTML the result depends on the browser's fragment algorithm.
|
|
29
33
|
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
34
|
+
* Idempotent: it empties the host before filling it, so calling twice does not duplicate ids (a duplicated id would make
|
|
35
|
+
* the browser pick the first — a silent failure again).
|
|
32
36
|
*
|
|
33
|
-
* @returns
|
|
37
|
+
* @returns how many filters were installed (0 = no host; the caller decides whether that is fatal).
|
|
34
38
|
*/
|
|
35
39
|
export declare function installCvdFilters(host: Element | null | undefined): number;
|