@the-inclusionist/engine 10.0.0 → 11.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +32 -1
- package/app/css/style.css +216 -42
- package/app/public/vendor/fonts-licences/NOTICE.txt +166 -0
- package/app/public/vendor/fonts-licences/OFL-1.1.txt +86 -0
- package/app/public/vendor/fonts.css +11 -1175
- package/dist-pkg/boot/create-game.d.ts +84 -33
- package/dist-pkg/boot/create-game.js +708 -307
- package/dist-pkg/core/a11y-sr.d.ts +1 -1
- package/dist-pkg/core/a11y-sr.js +3 -5
- package/dist-pkg/core/accommodations.d.ts +26 -8
- package/dist-pkg/core/accommodations.js +27 -10
- package/dist-pkg/core/actions.d.ts +39 -10
- package/dist-pkg/core/actions.js +28 -6
- package/dist-pkg/core/contract.d.ts +0 -2
- package/dist-pkg/core/contract.js +0 -2
- package/dist-pkg/core/i18n.d.ts +36 -71
- package/dist-pkg/core/i18n.js +131 -198
- package/dist-pkg/core/session-clock.d.ts +23 -0
- package/dist-pkg/core/session-clock.js +37 -0
- package/dist-pkg/i18n/en.js +44 -49
- package/dist-pkg/i18n/es.js +44 -49
- package/dist-pkg/i18n/pt.js +49 -54
- package/dist-pkg/input/gamepad.d.ts +42 -11
- package/dist-pkg/input/gamepad.js +50 -15
- package/dist-pkg/input/key-default.d.ts +30 -0
- package/dist-pkg/input/key-default.js +60 -0
- package/dist-pkg/input/keyboard-runtime.d.ts +0 -4
- package/dist-pkg/input/keyboard.d.ts +0 -1
- package/dist-pkg/input/keydown.d.ts +5 -11
- package/dist-pkg/input/keydown.js +3 -3
- package/dist-pkg/input/latch-edge.d.ts +10 -2
- package/dist-pkg/input/latch-edge.js +4 -3
- package/dist-pkg/input/latch-scope.d.ts +27 -22
- package/dist-pkg/input/latch-scope.js +25 -37
- package/dist-pkg/input/latch-store.d.ts +9 -12
- package/dist-pkg/input/latch-store.js +13 -18
- package/dist-pkg/input/latch-sync.d.ts +5 -4
- package/dist-pkg/input/latch-sync.js +5 -5
- package/dist-pkg/input/pad-reading.js +7 -2
- package/dist-pkg/input/pad-wizard.d.ts +4 -1
- package/dist-pkg/input/pad-wizard.js +60 -9
- package/dist-pkg/input/switch-scan.d.ts +29 -12
- package/dist-pkg/input/switch-scan.js +15 -2
- package/dist-pkg/input/touch-bindings.d.ts +3 -6
- package/dist-pkg/input/touch.d.ts +17 -2
- package/dist-pkg/input/touch.js +55 -17
- package/dist-pkg/input/transport-in-use.d.ts +5 -5
- package/dist-pkg/input/transport-in-use.js +5 -5
- package/dist-pkg/input/transports.d.ts +0 -9
- package/dist-pkg/input/transports.js +1 -1
- package/dist-pkg/input/virtual-controller.d.ts +39 -3
- package/dist-pkg/input/virtual-controller.js +32 -4
- package/dist-pkg/input/voice-map.d.ts +27 -11
- package/dist-pkg/input/voice-map.js +41 -43
- package/dist-pkg/platform/audio-ambient.d.ts +0 -1
- package/dist-pkg/platform/audio-ambient.js +3 -1
- package/dist-pkg/platform/audio-mixer.js +4 -9
- package/dist-pkg/platform/audio-sonar.d.ts +8 -94
- package/dist-pkg/platform/audio-sonar.js +22 -207
- package/dist-pkg/platform/audio.d.ts +10 -1
- package/dist-pkg/platform/audio.js +35 -2
- package/dist-pkg/platform/choose-by-voice.d.ts +70 -0
- package/dist-pkg/platform/choose-by-voice.js +157 -0
- package/dist-pkg/platform/font-library.d.ts +77 -0
- package/dist-pkg/platform/font-library.js +98 -0
- package/dist-pkg/platform/font-library.json +721 -0
- package/dist-pkg/platform/heavy-catalogue.d.ts +46 -0
- package/dist-pkg/platform/heavy-catalogue.js +47 -14
- package/dist-pkg/platform/heavy-mirror.d.ts +3 -9
- package/dist-pkg/platform/heavy-mirror.js +14 -17
- package/dist-pkg/platform/heavy.d.ts +40 -8
- package/dist-pkg/platform/heavy.js +177 -22
- package/dist-pkg/platform/interruptible-speech.d.ts +15 -8
- package/dist-pkg/platform/interruptible-speech.js +37 -13
- package/dist-pkg/platform/listener-scope.js +22 -13
- package/dist-pkg/platform/locale-host.d.ts +7 -3
- package/dist-pkg/platform/locale-host.js +13 -2
- package/dist-pkg/platform/reading-in-worker.d.ts +24 -0
- package/dist-pkg/platform/reading-in-worker.js +38 -0
- package/dist-pkg/platform/reading-model.d.ts +21 -0
- package/dist-pkg/platform/reading-model.js +25 -0
- package/dist-pkg/platform/reading-runtime.js +13 -8
- package/dist-pkg/platform/reading.d.ts +12 -1
- package/dist-pkg/platform/reading.js +9 -1
- package/dist-pkg/platform/speech-recognition.d.ts +10 -1
- package/dist-pkg/platform/speech-recognition.js +29 -9
- package/dist-pkg/platform/speech.d.ts +10 -1
- package/dist-pkg/platform/speech.js +24 -13
- package/dist-pkg/platform/tts.d.ts +37 -4
- package/dist-pkg/platform/tts.js +279 -57
- package/dist-pkg/platform/voice-listener.d.ts +6 -2
- package/dist-pkg/platform/voice-listener.js +1 -1
- package/dist-pkg/platform/voice-plan.d.ts +13 -0
- package/dist-pkg/platform/voice-plan.js +57 -2
- package/dist-pkg/platform/vosk-runtime.d.ts +25 -0
- package/dist-pkg/platform/vosk-runtime.js +59 -1
- package/dist-pkg/platform/vosk-vocabulary.d.ts +6 -0
- package/dist-pkg/platform/vosk-vocabulary.js +178 -0
- package/dist-pkg/render/crt.d.ts +11 -9
- package/dist-pkg/render/crt.js +6 -10
- package/dist-pkg/render/cvd-matrices.d.ts +5 -1
- package/dist-pkg/render/cvd-matrices.js +5 -1
- package/dist-pkg/render/high-contrast.d.ts +1 -2
- package/dist-pkg/render/high-contrast.js +5 -1
- package/dist-pkg/render/viz-axes.d.ts +9 -0
- package/dist-pkg/render/viz-axes.js +15 -2
- package/dist-pkg/ui/aac-sets.d.ts +29 -24
- package/dist-pkg/ui/aac-sets.js +22 -30
- package/dist-pkg/ui/audio-choices.d.ts +10 -5
- package/dist-pkg/ui/audio-choices.js +14 -10
- package/dist-pkg/ui/camera-control.d.ts +47 -0
- package/dist-pkg/ui/camera-control.js +35 -1
- package/dist-pkg/ui/declared-words.d.ts +21 -0
- package/dist-pkg/ui/declared-words.js +66 -0
- package/dist-pkg/ui/drawing-problems.js +4 -3
- package/dist-pkg/ui/eye-control.js +17 -17
- package/dist-pkg/ui/face-control.js +15 -15
- package/dist-pkg/ui/fonts.d.ts +42 -8
- package/dist-pkg/ui/fonts.js +58 -24
- package/dist-pkg/ui/footer-scroll-driver.d.ts +14 -0
- package/dist-pkg/ui/footer-scroll-driver.js +201 -0
- package/dist-pkg/ui/footer-scroll.d.ts +38 -0
- package/dist-pkg/ui/footer-scroll.js +55 -0
- package/dist-pkg/ui/game-options.d.ts +14 -9
- package/dist-pkg/ui/game-options.js +41 -21
- package/dist-pkg/ui/hand-control.js +15 -15
- package/dist-pkg/ui/help-panel.d.ts +19 -8
- package/dist-pkg/ui/help-panel.js +15 -5
- package/dist-pkg/ui/hud-bands.d.ts +29 -12
- package/dist-pkg/ui/hud-bands.js +63 -25
- package/dist-pkg/ui/hud-row.d.ts +34 -0
- package/dist-pkg/ui/hud-row.js +80 -0
- package/dist-pkg/ui/hud.d.ts +0 -3
- package/dist-pkg/ui/layout.js +5 -2
- package/dist-pkg/ui/libras-avatar-clip.d.ts +30 -0
- package/dist-pkg/ui/libras-avatar-clip.js +86 -0
- package/dist-pkg/ui/libras-avatar-load.d.ts +52 -0
- package/dist-pkg/ui/libras-avatar-load.js +134 -0
- package/dist-pkg/ui/libras-avatar-plan.d.ts +102 -0
- package/dist-pkg/ui/libras-avatar-plan.js +211 -0
- package/dist-pkg/ui/libras-avatar-player.d.ts +28 -0
- package/dist-pkg/ui/libras-avatar-player.js +226 -0
- package/dist-pkg/ui/libras-avatar-stage.d.ts +37 -0
- package/dist-pkg/ui/libras-avatar-stage.js +208 -0
- package/dist-pkg/ui/libras-glosses.d.ts +28 -0
- package/dist-pkg/ui/libras-glosses.js +161 -0
- package/dist-pkg/ui/menu-intent.d.ts +29 -0
- package/dist-pkg/ui/menu-intent.js +35 -1
- package/dist-pkg/ui/menu-items.d.ts +10 -0
- package/dist-pkg/ui/menu-items.js +29 -0
- package/dist-pkg/ui/menu-nav.d.ts +40 -4
- package/dist-pkg/ui/menu-nav.js +132 -47
- package/dist-pkg/ui/panel-widgets.d.ts +34 -0
- package/dist-pkg/ui/panel-widgets.js +86 -0
- package/dist-pkg/ui/pause-icons.d.ts +30 -14
- package/dist-pkg/ui/pause-icons.js +106 -45
- package/dist-pkg/ui/scan-overlay.d.ts +3 -3
- package/dist-pkg/ui/scan-overlay.js +11 -3
- package/dist-pkg/ui/screen-text.d.ts +25 -0
- package/dist-pkg/ui/screen-text.js +152 -0
- package/dist-pkg/ui/session-clock.d.ts +32 -0
- package/dist-pkg/ui/session-clock.js +67 -0
- package/dist-pkg/ui/settings-aac.d.ts +3 -1
- package/dist-pkg/ui/settings-aac.js +32 -13
- package/dist-pkg/ui/settings-audio.d.ts +10 -5
- package/dist-pkg/ui/settings-audio.js +101 -35
- package/dist-pkg/ui/settings-controls.d.ts +0 -4
- package/dist-pkg/ui/settings-mobility.d.ts +3 -6
- package/dist-pkg/ui/settings-mobility.js +4 -46
- package/dist-pkg/ui/settings-motion.js +2 -2
- package/dist-pkg/ui/settings-panel.d.ts +10 -0
- package/dist-pkg/ui/settings-panel.js +25 -1
- package/dist-pkg/ui/settings-typo.d.ts +5 -6
- package/dist-pkg/ui/settings-typo.js +20 -11
- package/dist-pkg/ui/settings-visual.js +2 -2
- package/dist-pkg/ui/shell.d.ts +1 -3
- package/dist-pkg/ui/shell.js +8 -4
- package/dist-pkg/ui/title.d.ts +2 -11
- package/dist-pkg/ui/title.js +39 -6
- package/dist-pkg/ui/top-band.d.ts +5 -3
- package/dist-pkg/ui/top-band.js +21 -25
- package/dist-pkg/ui/typo-choices.d.ts +3 -3
- package/dist-pkg/ui/typo-choices.js +9 -8
- package/dist-pkg/ui/vlibras.d.ts +71 -27
- package/dist-pkg/ui/vlibras.js +116 -44
- package/dist-pkg/ui/voice-control.d.ts +23 -1
- package/dist-pkg/ui/voice-control.js +149 -16
- package/dist-pkg/ui/voice-settings.d.ts +2 -3
- package/dist-pkg/ui/voice-settings.js +53 -3
- package/dist-pkg/ui/where-the-child-is.js +2 -2
- package/docs/CREDITS.md +122 -10
- package/docs/LICENSES.md +36 -7
- package/package.json +34 -9
- package/scripts/check-cartridge.mjs +78 -0
- package/scripts/game-build.d.mts +25 -0
- package/scripts/game-build.mjs +144 -0
- package/scripts/heavy-into-the-delivery.mjs +284 -40
- package/scripts/libras-avatar.json +680 -0
- package/scripts/libras-avatar.mjs +246 -0
- package/scripts/libras-glosses/gloss.py +95 -0
- package/scripts/libras-glosses/pyproject.toml +32 -0
- package/scripts/libras-glosses/uv.lock +781 -0
- package/scripts/libras-glosses.mjs +351 -0
- package/scripts/licences/OFL-1.1.txt +86 -0
- package/scripts/licences/UFL-1.0.txt +96 -0
- package/scripts/licences/fonts.mjs +389 -0
- package/scripts/licences/third-party.mjs +35 -21
- package/app/public/vendor/fonts/bitter-var-ext.woff2 +0 -0
- package/app/public/vendor/fonts/bitter-var.woff2 +0 -0
- package/app/public/vendor/fonts/bodonimoda-var-ext.woff2 +0 -0
- package/app/public/vendor/fonts/bodonimoda-var.woff2 +0 -0
- package/app/public/vendor/fonts/cat-abril_fatface-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-abril_fatface-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-adlam_display-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-adlam_display-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-agu_display-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-agu_display-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-alfa_slab_one-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-alfa_slab_one-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-are_you_serious-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-are_you_serious-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-asimovian-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-asimovian-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-atkinson_hyperlegible_next-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-atkinson_hyperlegible_next-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-bakbak_one-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-bakbak_one-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-bangers-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-bangers-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-barriecito-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-barriecito-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-berkshire_swash-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-berkshire_swash-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-bevan-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-bevan-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-bitcount-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-bitcount-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-bowlby_one_sc-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-bowlby_one_sc-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-bungee_shade-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-bungee_shade-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-charm-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-charm-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-charm-700-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-charm-700.woff2 +0 -0
- package/app/public/vendor/fonts/cat-cherry_bomb_one-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-cherry_bomb_one-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-chokokutai-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-chokokutai-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-chonburi-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-chonburi-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-climate_crisis-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-climate_crisis-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-cookie-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-dela_gothic_one-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-dela_gothic_one-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-fascinate_inline-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-fascinate_inline-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-ga_maamli-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-ga_maamli-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-itim-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-itim-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-jacquard_24-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-jacquard_24-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-kablammo-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-kablammo-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-kalam-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-kalam-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-kalam-700-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-kalam-700.woff2 +0 -0
- package/app/public/vendor/fonts/cat-katibeh-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-katibeh-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-lemonada-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-lemonada-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-lilita_one-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-lilita_one-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-lobster-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-lobster-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-luckiest_guy-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-luckiest_guy-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-marhey-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-marhey-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-modak-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-modak-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-momo_signature-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-momo_signature-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-monofett-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-monofett-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-monomakh-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-monomakh-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-monoton-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-monoton-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-nerko_one-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-nerko_one-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-noto_sans_adlam-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-noto_sans_adlam-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-noto_sans_arabic-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-noto_sans_arabic-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-noto_sans_devanagari-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-noto_sans_devanagari-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-noto_sans_hebrew-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-noto_sans_hebrew-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-noto_sans_jp-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-noto_sans_jp-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-noto_sans_khmer-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-noto_sans_khmer-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-noto_sans_kr-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-noto_sans_kr-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-noto_sans_sc-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-noto_sans_sc-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-noto_sans_thai-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-noto_sans_thai-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-ole-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-ole-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-pacifico-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-pacifico-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-patrick_hand-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-patrick_hand-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-petit_formal_script-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-petit_formal_script-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-pixelify_sans-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-pixelify_sans-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-plaster-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-plaster-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_ar_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_at-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_at_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_au_nsw-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_au_nsw_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_au_qld-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_au_qld_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_au_sa-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_au_sa_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_au_tas-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_au_tas_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_au_vic-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_au_vic_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_be_vlg-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_be_vlg_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_be_wal-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_be_wal_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_br_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_ca_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_cl_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_co_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_cu_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_cz-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_cz_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_de_grund-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_de_grund_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_de_la-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_de_la_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_de_sas-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_de_sas_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_de_va-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_de_va_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_dk_loopet-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_dk_loopet_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_dk_uloopet-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_dk_uloopet_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_es_deco_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_es_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_fr_moderne-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_fr_moderne_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_fr_trad-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_fr_trad_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_gb_j_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_gb_s_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_hr-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_hr_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_hr_lijeva-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_hr_lijeva_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_hu-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_hu_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_id-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_id_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_ie-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_ie_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_in-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_in_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_is-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_is_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_it_moderna-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_it_moderna_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_it_trad-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_it_trad_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_mx_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_ng_modern-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_ng_modern_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_nl-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_nl_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_no-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_no_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_nz-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_nz_basic-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_nz_basic_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_nz_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_pe_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_pl-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_pl_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_pt_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_ro-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_ro_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_sk-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_sk_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_tz-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_tz_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_us_modern_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_us_trad_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_vn-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_vn_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_za-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_za_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-potta_one-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-potta_one-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-ranchers-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-ranchers-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-ranga-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-ranga-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-ranga-700-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-ranga-700.woff2 +0 -0
- package/app/public/vendor/fonts/cat-risque-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-risque-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-rowdies-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-rowdies-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-rowdies-700-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-rowdies-700.woff2 +0 -0
- package/app/public/vendor/fonts/cat-ruge_boogie-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-ruge_boogie-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-ruslan_display-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-ruslan_display-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-sacramento-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-sacramento-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-sancreek-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-sancreek-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-sankofa_display-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-sankofa_display-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-sedgwick_ave_display-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-sedgwick_ave_display-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-shantell_sans-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-shantell_sans-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-smokum-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-smokum-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-solitreo-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-solitreo-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-spicy_rice-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-spicy_rice-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-sriracha-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-sriracha-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-srisakdi-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-srisakdi-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-srisakdi-700-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-srisakdi-700.woff2 +0 -0
- package/app/public/vendor/fonts/cat-stix_two_math-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-tillana-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-tillana-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-tillana-700-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-tillana-700.woff2 +0 -0
- package/app/public/vendor/fonts/cat-titan_one-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-titan_one-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-yatra_one-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-yatra_one-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-yomogi-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-yomogi-400.woff2 +0 -0
- package/app/public/vendor/fonts/dmserifdisplay-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/dmserifdisplay-400.woff2 +0 -0
- package/app/public/vendor/fonts/domine-var-ext.woff2 +0 -0
- package/app/public/vendor/fonts/domine-var.woff2 +0 -0
- package/app/public/vendor/fonts/fondamento-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/fondamento-400.woff2 +0 -0
- package/app/public/vendor/fonts/fraunces-var-ext.woff2 +0 -0
- package/app/public/vendor/fonts/fraunces-var.woff2 +0 -0
- package/app/public/vendor/fonts/fredoka-var-ext.woff2 +0 -0
- package/app/public/vendor/fonts/fredoka-var.woff2 +0 -0
- package/app/public/vendor/fonts/inter-400.woff2 +0 -0
- package/app/public/vendor/fonts/inter-700.woff2 +0 -0
- package/app/public/vendor/fonts/jakarta-var-ext.woff2 +0 -0
- package/app/public/vendor/fonts/jakarta-var.woff2 +0 -0
- package/app/public/vendor/fonts/lato-400.woff2 +0 -0
- package/app/public/vendor/fonts/lato-700.woff2 +0 -0
- package/app/public/vendor/fonts/literata-400.woff2 +0 -0
- package/app/public/vendor/fonts/literata-700.woff2 +0 -0
- package/app/public/vendor/fonts/lora-var-ext.woff2 +0 -0
- package/app/public/vendor/fonts/lora-var.woff2 +0 -0
- package/app/public/vendor/fonts/merriweather-var-ext.woff2 +0 -0
- package/app/public/vendor/fonts/merriweather-var.woff2 +0 -0
- package/app/public/vendor/fonts/newsreader-400.woff2 +0 -0
- package/app/public/vendor/fonts/newsreader-700.woff2 +0 -0
- package/app/public/vendor/fonts/notosans-var-ext.woff2 +0 -0
- package/app/public/vendor/fonts/notosans-var.woff2 +0 -0
- package/app/public/vendor/fonts/nunito-var-ext.woff2 +0 -0
- package/app/public/vendor/fonts/nunito-var.woff2 +0 -0
- package/app/public/vendor/fonts/opendyslexic-400.woff2 +0 -0
- package/app/public/vendor/fonts/opensans-400.woff2 +0 -0
- package/app/public/vendor/fonts/opensans-700.woff2 +0 -0
- package/app/public/vendor/fonts/pinyon-400.woff2 +0 -0
- package/app/public/vendor/fonts/playfair-var-ext.woff2 +0 -0
- package/app/public/vendor/fonts/playfair-var.woff2 +0 -0
- package/app/public/vendor/fonts/pressstart-400.woff2 +0 -0
- package/app/public/vendor/fonts/quattro-400.woff2 +0 -0
- package/app/public/vendor/fonts/quattro-700.woff2 +0 -0
- package/app/public/vendor/fonts/quicksand-var-ext.woff2 +0 -0
- package/app/public/vendor/fonts/quicksand-var.woff2 +0 -0
- package/app/public/vendor/fonts/robotoflex-var-ext.woff2 +0 -0
- package/app/public/vendor/fonts/robotoflex-var.woff2 +0 -0
- package/app/public/vendor/fonts/sora-var-ext.woff2 +0 -0
- package/app/public/vendor/fonts/sora-var.woff2 +0 -0
- package/app/public/vendor/fonts/sourcesans-400.woff2 +0 -0
- package/app/public/vendor/fonts/sourcesans-700.woff2 +0 -0
- package/app/public/vendor/fonts/sourceserif-400.woff2 +0 -0
- package/app/public/vendor/fonts/sourceserif-700.woff2 +0 -0
- package/app/public/vendor/fonts/spacegrotesk-var-ext.woff2 +0 -0
- package/app/public/vendor/fonts/spacegrotesk-var.woff2 +0 -0
- package/app/public/vendor/fonts/spectral-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/spectral-400.woff2 +0 -0
- package/app/public/vendor/fonts/spectral-700-ext.woff2 +0 -0
- package/app/public/vendor/fonts/spectral-700.woff2 +0 -0
- package/app/public/vendor/fonts/teachers-var-ext.woff2 +0 -0
- package/app/public/vendor/fonts/teachers-var.woff2 +0 -0
- package/app/public/vendor/fonts/ubuntu-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/ubuntu-400.woff2 +0 -0
- package/app/public/vendor/fonts/ubuntu-700-ext.woff2 +0 -0
- package/app/public/vendor/fonts/ubuntu-700.woff2 +0 -0
- package/app/public/vendor/fonts/ufmag-400.woff2 +0 -0
- package/dist-pkg/platform/guide-intensity.d.ts +0 -39
- package/dist-pkg/platform/guide-intensity.js +0 -71
- package/dist-pkg/ui/latch-refusal.d.ts +0 -33
- package/dist-pkg/ui/latch-refusal.js +0 -60
|
@@ -0,0 +1,389 @@
|
|
|
1
|
+
// SPDX-License-Identifier: AGPL-3.0-or-later
|
|
2
|
+
//
|
|
3
|
+
// WHAT THE ENGINE OWES THE PEOPLE WHOSE FONTS IT CARRIES (the fonts' twin of `third-party.mjs`).
|
|
4
|
+
//
|
|
5
|
+
// Two homes, one set of readers (ADR-0255):
|
|
6
|
+
// · THE ENGINE'S OWN FACES — every family `app/public/vendor/fonts.css` declares: the typography button's cycle and the
|
|
7
|
+
// mathematics face. The PWA precaches them into each install and the npm package ships `app/public/vendor`, so every copy is a
|
|
8
|
+
// redistribution. `app/public/vendor/fonts-licences/`, beside `fonts/`, carries `NOTICE.txt` and the licence texts they use.
|
|
9
|
+
// · THE FONT LIBRARY — every other family, one folder per family in `the-inclusionist-lfs/fonts/`, catalogued (files, sha256,
|
|
10
|
+
// weights, licence) in `app/js/platform/font-library.json`. Each folder carries its licence text, a `NOTICE.txt` and a
|
|
11
|
+
// `SHA256SUMS`; `inclusionist-heavy --fonts` writes the same licence text and notice beside each family it delivers.
|
|
12
|
+
//
|
|
13
|
+
// SIL OFL 1.1 §2 lets a font travel «provided that each copy contains the above copyright notice and this license», as a
|
|
14
|
+
// stand-alone text file or as metadata «easily viewed by the user»; Apache-2.0 §4(a) asks for the licence text; the Ubuntu Font
|
|
15
|
+
// Licence 1.0 §1 asks for the notice and the licence as the OFL does. So each notice names every family, its files, its licence
|
|
16
|
+
// and its copyright line AS THE FONT ITSELF STATES IT (name ID 0 of its `name` table).
|
|
17
|
+
//
|
|
18
|
+
// 📏 MEASURED 2026-09-27 on the 346 files then packaged: every one kept its copyright line (name ID 0); only OpenDyslexic kept its
|
|
19
|
+
// licence description (name ID 13); 331 kept a licence URL (name ID 14). The web subsets strip the licence text, which is why the
|
|
20
|
+
// text has to travel as a file. Three families are NOT under the OFL — Luckiest Guy and Smokum (Apache-2.0) and Ubuntu (Ubuntu
|
|
21
|
+
// Font Licence 1.0) — although the typographic catalogue records «OFL 1.1» for all three.
|
|
22
|
+
//
|
|
23
|
+
// 📌 THE LICENCE IS READ FROM THE FONT, never from a list kept by hand: its URL (ID 14), its licence description (ID 13) and the
|
|
24
|
+
// words of its copyright line (ID 0). Where these disagree the family is refused; where the font says nothing, the family must be
|
|
25
|
+
// DECLARED below with the evidence, or it is refused too. `tests/font-licences.node.test.js` holds the committed `NOTICE.txt`
|
|
26
|
+
// equal to what this module builds, and the library's folders equal to what it writes.
|
|
27
|
+
//
|
|
28
|
+
// Use:
|
|
29
|
+
// `node scripts/licences/fonts.mjs` rewrites `app/public/vendor/fonts-licences/NOTICE.txt` from `fonts.css` and the fonts.
|
|
30
|
+
// `node scripts/licences/fonts.mjs --library <the-inclusionist-lfs>` rewrites, in every family folder of `<lfs>/fonts/`, the
|
|
31
|
+
// licence text, `NOTICE.txt` and `SHA256SUMS`, and `<lfs>/fonts/SHA256SUMS` — refusing a font whose bytes are not the ones the
|
|
32
|
+
// catalogue pins, and a family whose licence nobody can name.
|
|
33
|
+
|
|
34
|
+
import { readFileSync, writeFileSync, readdirSync, statSync } from 'node:fs';
|
|
35
|
+
import { join } from 'node:path';
|
|
36
|
+
import { createHash } from 'node:crypto';
|
|
37
|
+
import { brotliDecompressSync } from 'node:zlib';
|
|
38
|
+
import { fileURLToPath } from 'node:url';
|
|
39
|
+
import { LICENCE_TEXTS } from './third-party.mjs';
|
|
40
|
+
|
|
41
|
+
export const VENDOR = fileURLToPath(new URL('../../app/public/vendor/', import.meta.url));
|
|
42
|
+
export const FONTS_DIR = fileURLToPath(new URL('../../app/public/vendor/fonts/', import.meta.url));
|
|
43
|
+
export const NOTICE_FILE = 'NOTICE.txt';
|
|
44
|
+
/** Where the notice and the licence texts ship: beside `fonts/`, not in it — /vendor/fonts/* is cached for a year as immutable,
|
|
45
|
+
* and the notice changes whenever a family does (_headers gives this folder a rule that revalidates). */
|
|
46
|
+
export const LICENCES_DIR = fileURLToPath(new URL('../../app/public/vendor/fonts-licences/', import.meta.url));
|
|
47
|
+
/** The library's catalogue in the repository; the package carries the compiled copy at `dist-pkg/platform/font-library.json`. */
|
|
48
|
+
export const LIBRARY_CATALOGUE = fileURLToPath(new URL('../../app/js/platform/font-library.json', import.meta.url));
|
|
49
|
+
/** The folder of `the-inclusionist-lfs` the library lives in, one sub-folder per family. */
|
|
50
|
+
export const LIBRARY_FOLDER = 'fonts';
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* The licence texts, each kept HERE beside this module (the npm package ships `scripts/licences`, so a school's build machine has
|
|
54
|
+
* them) and pinned (sha256 of the copy, CRLF read as LF). The engine's faces ship the ones they use in `fonts-licences/`; every
|
|
55
|
+
* library folder and every delivered family gets its own.
|
|
56
|
+
* · OFL-1.1: the licence body — from the «SIL OPEN FONT LICENSE Version 1.1» banner to the end — of the licence field (name ID
|
|
57
|
+
* 13) of OpenDyslexic's `OpenDyslexic-Regular.woff2` (antijingoist/opendyslexic, now in the library). Byte-identical to the
|
|
58
|
+
* same body in three other local copies of upstream `OFL.txt` files (game-chess: Pecita, STIX Two Math, Noto Sans Symbols 2),
|
|
59
|
+
* and to a fourth (game-pinball's Press Start 2P) but for the final newline.
|
|
60
|
+
* · Apache-2.0: `scripts/licences/Apache-2.0.txt`, the same file and the same pin as the heavy files'.
|
|
61
|
+
* · Ubuntu-font-1.0: the `License: Ubuntu-Font-Licence-1.0` paragraph of the Debian package `fonts-ubuntu`'s
|
|
62
|
+
* `/usr/share/doc/fonts-ubuntu/copyright` (sha256 bca346a5…8ef8cf, the same in three WSL installs, packages 0.83-6ubuntu1 and
|
|
63
|
+
* 0.869+git20240321-0ubuntu1), decoded as the Debian copyright format writes it: one leading space removed from each line, a
|
|
64
|
+
* line holding only « .» read as an empty line. ✅ VERIFIED 2026-09-27 byte for byte (same sha256) against
|
|
65
|
+
* `google/fonts` `ufl/ubuntu/UFL.txt`, the licence that travels with the very files the library carries.
|
|
66
|
+
*/
|
|
67
|
+
export const FONT_LICENCE_TEXTS = Object.freeze({
|
|
68
|
+
'OFL-1.1': { file: 'OFL-1.1.txt', name: 'SIL Open Font License, Version 1.1',
|
|
69
|
+
sha256: 'f05e84c3000faf09cf8e445d35018b01fc0d6026953840e9398aeab501b86da2',
|
|
70
|
+
from: 'OpenDyslexic-Regular.woff2 (antijingoist/opendyslexic), name ID 13, from the «SIL OPEN FONT LICENSE Version 1.1» banner' },
|
|
71
|
+
'Apache-2.0': { file: 'Apache-2.0.txt', name: 'Apache License, Version 2.0',
|
|
72
|
+
sha256: LICENCE_TEXTS['Apache-2.0'].sha256,
|
|
73
|
+
from: 'scripts/licences/Apache-2.0.txt' },
|
|
74
|
+
'Ubuntu-font-1.0': { file: 'UFL-1.0.txt', name: 'Ubuntu Font Licence, Version 1.0',
|
|
75
|
+
sha256: '2f0015108d68627bd788d313f529c21ff4da2c2c42a5e1f3883acc83480f9002',
|
|
76
|
+
from: 'Debian package fonts-ubuntu, /usr/share/doc/fonts-ubuntu/copyright, the Ubuntu-Font-Licence-1.0 paragraph' },
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
/** A licence text as this module keeps it (beside it, in `scripts/licences/`). */
|
|
80
|
+
export function licenceText(spdx, texts = FONT_LICENCE_TEXTS) {
|
|
81
|
+
return readFileSync(new URL(texts[spdx].file, import.meta.url), 'utf8');
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Families whose files carry NO licence in their metadata, with the evidence the project holds instead. A family listed here
|
|
86
|
+
* whose font later names a licence is refused (the entry would be a second, older truth), and so is an entry no family uses.
|
|
87
|
+
*/
|
|
88
|
+
export const DECLARED_WITHOUT_METADATA = Object.freeze({
|
|
89
|
+
// none: the three faces that carried no licence in their files left the package (ADR-0251)
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
// ===================== READING A WOFF2's `name` TABLE =====================
|
|
93
|
+
|
|
94
|
+
// WOFF2's known-table index (the spec's table, in order); a flag of 63 means the tag follows as four bytes.
|
|
95
|
+
const KNOWN_TAGS = [
|
|
96
|
+
'cmap', 'head', 'hhea', 'hmtx', 'maxp', 'name', 'OS/2', 'post', 'cvt ', 'fpgm', 'glyf', 'loca', 'prep', 'CFF ', 'VORG', 'EBDT',
|
|
97
|
+
'EBLC', 'gasp', 'hdmx', 'kern', 'LTSH', 'PCLT', 'VDMX', 'vhea', 'vmtx', 'BASE', 'GDEF', 'GPOS', 'GSUB', 'EBSC', 'JSTF', 'MATH',
|
|
98
|
+
'CBDT', 'CBLC', 'COLR', 'CPAL', 'SVG ', 'sbix', 'acnt', 'avar', 'bdat', 'bloc', 'bsln', 'cvar', 'fdsc', 'feat', 'fmtx', 'fvar',
|
|
99
|
+
'gvar', 'hsty', 'just', 'lcar', 'mort', 'morx', 'opbd', 'prop', 'trak', 'Zapf', 'Silf', 'Glat', 'Gloc', 'Feat', 'Sill',
|
|
100
|
+
];
|
|
101
|
+
|
|
102
|
+
function uintBase128(buf, at) {
|
|
103
|
+
let value = 0;
|
|
104
|
+
for (let i = 0; i < 5; i++) {
|
|
105
|
+
const byte = buf[at.p++];
|
|
106
|
+
value = value * 128 + (byte & 0x7f);
|
|
107
|
+
if (!(byte & 0x80)) return value;
|
|
108
|
+
}
|
|
109
|
+
throw new Error('woff2: UIntBase128 longer than five bytes');
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* The tables of a WOFF2 file, decompressed: `[{ tag, transformed, data }]` in the file's order. A table written with a WOFF2
|
|
114
|
+
* transform (glyf/loca by default, hmtx optionally) is returned as the transformed stream and flagged, never reconstructed.
|
|
115
|
+
*/
|
|
116
|
+
export function woff2Tables(buf) {
|
|
117
|
+
if (buf.toString('latin1', 0, 4) !== 'wOF2') throw new Error('not a WOFF2 file');
|
|
118
|
+
if (buf.toString('latin1', 4, 8) === 'ttcf') throw new Error('woff2: font collections are not read here');
|
|
119
|
+
const numTables = buf.readUInt16BE(12);
|
|
120
|
+
const compressedLength = buf.readUInt32BE(20);
|
|
121
|
+
const at = { p: 48 };
|
|
122
|
+
const directory = [];
|
|
123
|
+
for (let i = 0; i < numTables; i++) {
|
|
124
|
+
const flags = buf[at.p++];
|
|
125
|
+
let tag = KNOWN_TAGS[flags & 0x3f];
|
|
126
|
+
if ((flags & 0x3f) === 63) { tag = buf.toString('latin1', at.p, at.p + 4); at.p += 4; }
|
|
127
|
+
const version = flags >> 6;
|
|
128
|
+
let length = uintBase128(buf, at);
|
|
129
|
+
const transformed = (tag === 'glyf' || tag === 'loca') ? version === 0 : version !== 0;
|
|
130
|
+
if (transformed) length = uintBase128(buf, at);
|
|
131
|
+
directory.push({ tag, transformed, length });
|
|
132
|
+
}
|
|
133
|
+
const stream = brotliDecompressSync(buf.subarray(at.p, at.p + compressedLength));
|
|
134
|
+
let offset = 0;
|
|
135
|
+
return directory.map(({ tag, transformed, length }) => {
|
|
136
|
+
const data = stream.subarray(offset, offset + length);
|
|
137
|
+
offset += length;
|
|
138
|
+
return { tag, transformed, data };
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Name IDs 0 (copyright), 1 (family), 13 (licence description) and 14 (licence URL) of a WOFF2 file, English (Windows) record
|
|
144
|
+
* preferred. The `name` table is never transformed in WOFF2, so the table directory and the Brotli stream are enough.
|
|
145
|
+
*/
|
|
146
|
+
export function readFontNames(buf) {
|
|
147
|
+
const table = woff2Tables(buf).find((t) => t.tag === 'name')?.data;
|
|
148
|
+
if (!table) throw new Error('woff2: no name table');
|
|
149
|
+
const count = table.readUInt16BE(2);
|
|
150
|
+
const strings = table.readUInt16BE(4);
|
|
151
|
+
const out = {};
|
|
152
|
+
for (let i = 0; i < count; i++) {
|
|
153
|
+
const r = 6 + i * 12;
|
|
154
|
+
const platform = table.readUInt16BE(r);
|
|
155
|
+
const language = table.readUInt16BE(r + 4);
|
|
156
|
+
const id = table.readUInt16BE(r + 6);
|
|
157
|
+
if (![0, 1, 13, 14].includes(id)) continue;
|
|
158
|
+
const start = strings + table.readUInt16BE(r + 10);
|
|
159
|
+
const raw = table.subarray(start, start + table.readUInt16BE(r + 8));
|
|
160
|
+
const text = platform === 1 ? raw.toString('latin1') : Buffer.from(raw).swap16().toString('utf16le');
|
|
161
|
+
if (!(id in out) || (platform === 3 && language === 0x409)) out[id] = text;
|
|
162
|
+
}
|
|
163
|
+
return out;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// ===================== WHICH LICENCE A FONT STATES =====================
|
|
167
|
+
|
|
168
|
+
/** Each signal a font can give, and the licence it names. A URL outside this list is refused, not guessed. */
|
|
169
|
+
const LICENCE_URLS = [
|
|
170
|
+
[/^https?:\/\/scripts\.sil\.org\/OFL\/?$/i, 'OFL-1.1'],
|
|
171
|
+
[/^https?:\/\/(www\.)?openfontlicense\.org\/?$/i, 'OFL-1.1'],
|
|
172
|
+
[/^https?:\/\/www\.apache\.org\/licenses\/LICENSE-2\.0(\.html)?$/i, 'Apache-2.0'],
|
|
173
|
+
];
|
|
174
|
+
const LICENCE_WORDS = [
|
|
175
|
+
[/SIL Open ?Font License,? (Version )?1\.1/i, 'OFL-1.1'],
|
|
176
|
+
[/Apache 2\.0 licen[cs]e/i, 'Apache-2.0'],
|
|
177
|
+
[/Ubuntu Font Licence 1\.0/i, 'Ubuntu-font-1.0'],
|
|
178
|
+
];
|
|
179
|
+
|
|
180
|
+
/** The licences a font's own metadata names, with where each was read: `[{ spdx, source }]`, possibly empty. */
|
|
181
|
+
export function licencesStated(names) {
|
|
182
|
+
const found = [];
|
|
183
|
+
const url = (names[14] || '').trim();
|
|
184
|
+
if (url) {
|
|
185
|
+
const hit = LICENCE_URLS.find(([re]) => re.test(url));
|
|
186
|
+
if (!hit) throw new Error(`licence URL «${url}» is not one this module knows — register it, do not guess`);
|
|
187
|
+
found.push({ spdx: hit[1], source: `licence URL (name ID 14): ${url}` });
|
|
188
|
+
}
|
|
189
|
+
for (const [id, label] of [[13, 'licence description (name ID 13)'], [0, 'copyright notice (name ID 0)']]) {
|
|
190
|
+
const hit = LICENCE_WORDS.find(([re]) => re.test(names[id] || ''));
|
|
191
|
+
if (hit) found.push({ spdx: hit[1], source: label });
|
|
192
|
+
}
|
|
193
|
+
return found;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// ===================== THE FAMILIES `fonts.css` DECLARES =====================
|
|
197
|
+
|
|
198
|
+
/** `[{ family, files: [...] }]` in the order `fonts.css` first declares each family; comments are not read. */
|
|
199
|
+
export function familiesOf(css) {
|
|
200
|
+
const families = new Map();
|
|
201
|
+
for (const [, body] of css.replace(/\/\*[\s\S]*?\*\//g, '').matchAll(/@font-face\s*\{([^}]*)\}/g)) {
|
|
202
|
+
const family = body.match(/font-family:\s*'([^']+)'/)?.[1];
|
|
203
|
+
if (!family) throw new Error(`an @font-face with no quoted font-family: ${body.slice(0, 80)}`);
|
|
204
|
+
if (!families.has(family)) families.set(family, []);
|
|
205
|
+
for (const [, file] of body.matchAll(/url\('fonts\/([^']+)'\)/g)) {
|
|
206
|
+
if (!families.get(family).includes(file)) families.get(family).push(file);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
return [...families].map(([family, files]) => ({ family, files }));
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* One entry per family: its files, its licence, where the licence was read, and its copyright line(s). THROWS — the refusal —
|
|
214
|
+
* for a family with no licence stated or declared, with two licences, with a licence no shipped text covers, with files that
|
|
215
|
+
* disagree about their copyright, or declared although its font now states a licence.
|
|
216
|
+
*/
|
|
217
|
+
function entryOf({ family, files }, { readNames, declared, texts }) {
|
|
218
|
+
const perFile = files.map((file) => ({ file, names: readNames(file, family) }));
|
|
219
|
+
const stated = perFile.flatMap(({ names }) => licencesStated(names));
|
|
220
|
+
const spdxStated = [...new Set(stated.map((s) => s.spdx))];
|
|
221
|
+
if (spdxStated.length > 1) throw new Error(`«${family}»: its files state more than one licence (${spdxStated.join(', ')})`);
|
|
222
|
+
if (spdxStated.length && declared[family]) {
|
|
223
|
+
throw new Error(`«${family}» is declared by hand although its font states ${spdxStated[0]} — delete the declaration`);
|
|
224
|
+
}
|
|
225
|
+
const spdx = spdxStated[0] ?? declared[family]?.spdx;
|
|
226
|
+
if (!spdx) throw new Error(`«${family}»: no licence stated in its files and none declared — refused`);
|
|
227
|
+
if (!texts[spdx]) throw new Error(`«${family}»: ${spdx} has no licence text shipped beside the fonts — refused`);
|
|
228
|
+
const copyrights = [...new Set(perFile.map(({ names }) => (names[0] || '').trim()))];
|
|
229
|
+
if (copyrights.length !== 1 || !copyrights[0]) {
|
|
230
|
+
throw new Error(`«${family}»: its files do not carry one copyright line (${copyrights.length} different)`);
|
|
231
|
+
}
|
|
232
|
+
const sources = spdxStated.length ? [...new Set(stated.map((s) => s.source))] : [declared[family].evidence];
|
|
233
|
+
// A licence field that holds a whole OFL.txt starts with the notice the licence calls «the above copyright notice»
|
|
234
|
+
// (OpenDyslexic's names its Reserved Font Name there and nowhere else): it travels too.
|
|
235
|
+
const headers = [...new Set(perFile.map(({ names }) => {
|
|
236
|
+
const at = (names[13] || '').indexOf('SIL OPEN FONT LICENSE Version 1.1');
|
|
237
|
+
return at < 0 ? '' : names[13].slice(0, at).replace(/-+\s*$/, '').trim();
|
|
238
|
+
}).filter(Boolean))];
|
|
239
|
+
return { family, files, spdx, sources, copyright: copyrights[0], licenceHeader: headers.join('\n\n') };
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
/** The engine's entries, one per family `fonts.css` declares (see `entryOf`); a hand declaration no family uses is refused. */
|
|
243
|
+
export function fontEntries({
|
|
244
|
+
css, readFont, declared = DECLARED_WITHOUT_METADATA, texts = FONT_LICENCE_TEXTS,
|
|
245
|
+
readNames = (file) => readFontNames(readFont(file)), // a case describes a font's `name` table without shipping one
|
|
246
|
+
}) {
|
|
247
|
+
const entries = familiesOf(css).map((f) => entryOf(f, { readNames, declared, texts }));
|
|
248
|
+
const unused = Object.keys(declared).filter((f) => !entries.some((e) => e.family === f));
|
|
249
|
+
if (unused.length) throw new Error(`declared without metadata but not in fonts.css: ${unused.join(', ')} — delete the entry`);
|
|
250
|
+
return entries;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
// A font's strings end lines in CR, LF or both (Luckiest Guy's copyright uses a lone CR): each becomes one line here.
|
|
254
|
+
const indent = (text) => text.replace(/\r\n?/g, '\n').split('\n').map((l) => ` ${l}`.trimEnd()).join('\n');
|
|
255
|
+
|
|
256
|
+
/** One family's block of a notice. `original` is where the files come from when they are the author's original, compressed. */
|
|
257
|
+
function familyBlock(e, texts, original) {
|
|
258
|
+
return [
|
|
259
|
+
'-------------------------------------------------------------------------------',
|
|
260
|
+
`Family: ${e.family}`,
|
|
261
|
+
`Files: ${e.files.join(', ')}`,
|
|
262
|
+
`Licence: ${texts[e.spdx].name} (${e.spdx}), see ${texts[e.spdx].file}`,
|
|
263
|
+
`Read from: ${e.sources.join('; ')}`,
|
|
264
|
+
...(original.length ? [`Original: ${original.join('; ')} — the author's file, compressed to WOFF2 and nothing else`] : []),
|
|
265
|
+
'Copyright:',
|
|
266
|
+
indent(e.copyright),
|
|
267
|
+
...(e.licenceHeader ? ['Notice at the head of its licence field (name ID 13):', indent(e.licenceHeader)] : []),
|
|
268
|
+
].join('\n');
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
/** The text of the engine's `NOTICE.txt` for these entries. */
|
|
272
|
+
export function noticeText(entries, texts = FONT_LICENCE_TEXTS) {
|
|
273
|
+
const files = entries.reduce((n, e) => n + e.files.length, 0);
|
|
274
|
+
const used = Object.keys(texts).filter((spdx) => entries.some((e) => e.spdx === spdx));
|
|
275
|
+
const head = [
|
|
276
|
+
'The fonts in vendor/fonts/: notices and licences',
|
|
277
|
+
'=============================================',
|
|
278
|
+
'',
|
|
279
|
+
`The Inclusionist engine redistributes ${entries.length} font families, in ${files} files, from this directory. Each`,
|
|
280
|
+
'family is listed below with the files it covers, its licence, where that licence was read, and its copyright',
|
|
281
|
+
'notice as the font\'s own `name` table states it (name ID 0). The licence texts sit beside this file:',
|
|
282
|
+
'',
|
|
283
|
+
...used.map((spdx) => {
|
|
284
|
+
const n = entries.filter((e) => e.spdx === spdx).length;
|
|
285
|
+
return ` ${texts[spdx].file.padEnd(16)}${texts[spdx].name} (${n} ${n === 1 ? 'family' : 'families'})`;
|
|
286
|
+
}),
|
|
287
|
+
'',
|
|
288
|
+
'Written by scripts/licences/fonts.mjs from vendor/fonts.css and the fonts themselves;',
|
|
289
|
+
'tests/font-licences.node.test.js refuses a family without an entry here or a licence without its text.',
|
|
290
|
+
'',
|
|
291
|
+
'Every other family The Inclusionist offers lives in its font library, one folder per family with its own notice',
|
|
292
|
+
'and licence, and reaches a game only through a delivery that carries it (ADR-0255).',
|
|
293
|
+
];
|
|
294
|
+
return `${[head.join('\n'), ...entries.map((e) => familyBlock(e, texts, []))].join('\n\n')}\n`;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
/** The notice as the repository's `fonts.css` and fonts make it today. */
|
|
298
|
+
export function currentNotice() {
|
|
299
|
+
const css = readFileSync(`${VENDOR}fonts.css`, 'utf8');
|
|
300
|
+
return noticeText(fontEntries({ css, readFont: (file) => readFileSync(`${FONTS_DIR}${file}`) }));
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
// ===================== THE FONT LIBRARY =====================
|
|
304
|
+
|
|
305
|
+
/** The library's catalogue: `{ mirror, ranges, families: { [family]: { folder, licence, faces: [...] } } }`. */
|
|
306
|
+
export function readLibrary(path = LIBRARY_CATALOGUE) {
|
|
307
|
+
return JSON.parse(readFileSync(path, 'utf8'));
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
const sha256 = (buf) => createHash('sha256').update(buf).digest('hex');
|
|
311
|
+
|
|
312
|
+
/**
|
|
313
|
+
* THE FILES A FAMILY'S FOLDER OWES ITS AUTHORS, beside its fonts: the licence text its fonts state and `NOTICE.txt` — the same
|
|
314
|
+
* two whether the folder is the library's or a delivery's (`inclusionist-heavy --fonts`). `readFont(file)` returns the font's
|
|
315
|
+
* bytes, which are read for their `name` table. THROWS when the fonts state no licence, another licence than the catalogue
|
|
316
|
+
* records, or one with no text here: a family nobody can account for is not written.
|
|
317
|
+
*/
|
|
318
|
+
export function familyLicenceFiles(family, entry, readFont, texts = FONT_LICENCE_TEXTS) {
|
|
319
|
+
const files = [...new Set(entry.faces.map((f) => f.file))]; // one file may serve two weights (a variable font's 400 and 700)
|
|
320
|
+
const e = entryOf({ family, files }, { readNames: (file) => readFontNames(readFont(file)), declared: {}, texts });
|
|
321
|
+
if (e.spdx !== entry.licence) throw new Error(`«${family}»: its fonts state ${e.spdx}, the catalogue records ${entry.licence}`);
|
|
322
|
+
const original = [...new Set(entry.faces.map((f) => f.from).filter(Boolean))];
|
|
323
|
+
const notice = [
|
|
324
|
+
[
|
|
325
|
+
`${family}: notice and licence`,
|
|
326
|
+
'='.repeat(family.length + 20),
|
|
327
|
+
'',
|
|
328
|
+
`The font family ${family}, in ${files.length} ${files.length === 1 ? 'file' : 'files'}, as The Inclusionist's font library`,
|
|
329
|
+
'distributes it (ADR-0255). Its licence, where that licence was read, and its copyright notice as the font\'s own',
|
|
330
|
+
`\`name\` table states it (name ID 0). The licence text sits beside this file: ${texts[e.spdx].file}.`,
|
|
331
|
+
'',
|
|
332
|
+
'Written by scripts/licences/fonts.mjs from the engine\'s font catalogue and the fonts themselves.',
|
|
333
|
+
].join('\n'),
|
|
334
|
+
familyBlock(e, texts, original),
|
|
335
|
+
].join('\n\n');
|
|
336
|
+
return { [texts[e.spdx].file]: licenceText(e.spdx, texts), [NOTICE_FILE]: `${notice}\n` };
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
/** `SHA256SUMS` in the mirror's format — `<sha256> <name>` per line, names in code-unit order. */
|
|
340
|
+
export function sha256Sums(files) {
|
|
341
|
+
return Object.keys(files).sort().map((name) => `${sha256(files[name])} ${name}\n`).join('');
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
/**
|
|
345
|
+
* A library folder as it must be: the catalogue's fonts, checked against their pinned sha256, then the licence text, the notice
|
|
346
|
+
* and `SHA256SUMS` over every other file in the folder. Returns `{ [name]: Buffer|string }` of what to write; THROWS on a font
|
|
347
|
+
* missing or whose bytes are not the pinned ones.
|
|
348
|
+
*/
|
|
349
|
+
export function libraryFolder(family, entry, dir) {
|
|
350
|
+
const read = (file) => readFileSync(join(dir, file));
|
|
351
|
+
for (const face of entry.faces) {
|
|
352
|
+
const got = sha256(read(face.file));
|
|
353
|
+
if (got !== face.sha256) throw new Error(`«${family}» ${face.file}: sha256 ${got}, the catalogue pins ${face.sha256}`);
|
|
354
|
+
}
|
|
355
|
+
const owed = familyLicenceFiles(family, entry, read);
|
|
356
|
+
const onDisk = Object.fromEntries(readdirSync(dir).filter((n) => n !== 'SHA256SUMS' && statSync(join(dir, n)).isFile())
|
|
357
|
+
.map((n) => [n, read(n)]));
|
|
358
|
+
const owedBytes = Object.fromEntries(Object.entries(owed).map(([n, text]) => [n, Buffer.from(text)]));
|
|
359
|
+
return { ...owed, SHA256SUMS: sha256Sums({ ...onDisk, ...owedBytes }) };
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
/** Writes every library folder's owed files, and `<lfs>/fonts/SHA256SUMS` over the whole library (the mirror's upload checks it). */
|
|
363
|
+
export function writeLibrary(lfs, library = readLibrary()) {
|
|
364
|
+
const root = join(lfs, LIBRARY_FOLDER);
|
|
365
|
+
const all = {};
|
|
366
|
+
for (const [family, entry] of Object.entries(library.families)) {
|
|
367
|
+
const dir = join(root, entry.folder);
|
|
368
|
+
const files = libraryFolder(family, entry, dir);
|
|
369
|
+
for (const [name, body] of Object.entries(files)) writeFileSync(join(dir, name), body);
|
|
370
|
+
for (const name of readdirSync(dir)) all[`${entry.folder}/${name}`] = readFileSync(join(dir, name));
|
|
371
|
+
}
|
|
372
|
+
const kept = readdirSync(root).filter((n) => statSync(join(root, n)).isFile() && n !== 'SHA256SUMS');
|
|
373
|
+
for (const name of kept) all[name] = readFileSync(join(root, name));
|
|
374
|
+
writeFileSync(join(root, 'SHA256SUMS'), sha256Sums(all));
|
|
375
|
+
return Object.keys(library.families).length;
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
if (process.argv[1] && fileURLToPath(import.meta.url) === process.argv[1]) {
|
|
379
|
+
const at = process.argv.indexOf('--library');
|
|
380
|
+
if (at >= 0) {
|
|
381
|
+
const lfs = process.argv[at + 1];
|
|
382
|
+
if (!lfs) { console.error('usage: node scripts/licences/fonts.mjs --library <the-inclusionist-lfs>'); process.exit(2); }
|
|
383
|
+
console.log(`wrote ${writeLibrary(lfs)} library folders under ${join(lfs, LIBRARY_FOLDER)}`);
|
|
384
|
+
} else {
|
|
385
|
+
const text = currentNotice();
|
|
386
|
+
writeFileSync(`${LICENCES_DIR}${NOTICE_FILE}`, text);
|
|
387
|
+
console.log(`wrote ${NOTICE_FILE}: ${Buffer.byteLength(text)} bytes`);
|
|
388
|
+
}
|
|
389
|
+
}
|
|
@@ -23,13 +23,20 @@ import { dirname, join } from 'node:path';
|
|
|
23
23
|
|
|
24
24
|
const HERE = new URL('./', import.meta.url);
|
|
25
25
|
|
|
26
|
+
// The eSpeak NG build the catalogue pins (`voz:runtime:fonemas`), made by `scripts/models/build-espeak-ng.ps1` (issue #192). The
|
|
27
|
+
// catalogue's address names the same folder, and `tests/heavy-licences.node.test.js` holds the two together.
|
|
28
|
+
const ESPEAK_NG_COMMIT = '530bf0abf4174dc9ca28dbacc11bd5e9ae6152cd';
|
|
29
|
+
const ESPEAK_NG_FOLDER = 'espeak-ng-530bf0a';
|
|
30
|
+
const ESPEAK_NG_MIRROR = `https://lfs-oinclusionista.jrocha.dev.br/${ESPEAK_NG_FOLDER}`;
|
|
31
|
+
|
|
26
32
|
/**
|
|
27
33
|
* The licence texts, each copied byte for byte from a local file (sha256 of the copy, with CRLF read as LF).
|
|
28
34
|
* · Apache-2.0: the vosk-browser upstream text as the mirror holds it; its terms match, word for word, the Apache-2.0 text of
|
|
29
35
|
* `node_modules/detect-libc/LICENSE` up to «END OF TERMS AND CONDITIONS» (the appendix, a how-to, is not in it).
|
|
30
36
|
* · MIT: the permission notice and disclaimer only — from «Permission is hereby granted» to the end — of
|
|
31
37
|
* `node_modules/pixi.js/LICENSE`. The copyright line above it is each project's own, written per group below.
|
|
32
|
-
* · GPL-3.0: the licence file of the `espeak-ng` 1.0.2 npm package
|
|
38
|
+
* · GPL-3.0: the licence file of the `espeak-ng` 1.0.2 npm package, the build the engine used before its own (the FSF's current
|
|
39
|
+
* text; eSpeak NG's `COPYING` is the same licence in the FSF's earlier wording, with `http://` addresses).
|
|
33
40
|
*/
|
|
34
41
|
export const LICENCE_TEXTS = Object.freeze({
|
|
35
42
|
'Apache-2.0': { file: 'Apache-2.0.txt', sha256: 'bb618af833c817ab01c1564bd3ec75ba4b4f9cf30910a4a2168e30a674ee8cc6',
|
|
@@ -69,34 +76,41 @@ export const THIRD_PARTY = Object.freeze([
|
|
|
69
76
|
{
|
|
70
77
|
key: 'espeak-ng',
|
|
71
78
|
ids: ['voz:runtime:fonemas'],
|
|
72
|
-
project: 'eSpeak NG,
|
|
73
|
-
version:
|
|
79
|
+
project: 'eSpeak NG, built for the browser (WebAssembly) by The Inclusionist',
|
|
80
|
+
version: `eSpeak NG commit ${ESPEAK_NG_COMMIT} (master of 2023-09-27, between the releases 1.51 and 1.52.0), Emscripten 3.1.49`,
|
|
74
81
|
spdx: 'GPL-3.0-or-later',
|
|
75
82
|
licence: 'GPL-3.0',
|
|
76
|
-
copyright: [
|
|
77
|
-
|
|
83
|
+
copyright: [
|
|
84
|
+
'Copyright (C) 2005 to 2007 by Jonathan Duddington', 'Copyright (C) 2005 to 2011 by Jonathan Duddington',
|
|
85
|
+
'Copyright (C) 2005 to 2013 by Jonathan Duddington', 'Copyright (C) 2005 to 2014 by Jonathan Duddington',
|
|
86
|
+
'Copyright (C) 2005 to 2015 by Jonathan Duddington', 'Copyright (C) 2006 to 2013 by Jonathan Duddington',
|
|
87
|
+
'Copyright (C) 2012-2018 Reece H. Dunn', 'Copyright (C) 2012-2018, 2021 Reece H. Dunn', 'Copyright (C) 2013-2016 Reece H. Dunn',
|
|
88
|
+
'Copyright (C) 2013-2017 Reece H. Dunn', 'Copyright (C) 2015-2016 Reece H. Dunn', 'Copyright (C) 2015-2016, 2020 Reece H. Dunn',
|
|
89
|
+
'Copyright (C) 2015-2017 Reece H. Dunn', 'Copyright (C) 2016 Reece H. Dunn', 'Copyright (C) 2017 Reece H. Dunn',
|
|
90
|
+
'Copyright (C) 2017-2018 Reece H. Dunn', 'Copyright (C) 2018 Juho Hiltunen', 'Copyright (C) 2021 Juho Hiltunen',
|
|
91
|
+
'Copyright (C) 2022 Juho Hiltunen', 'Copyright (C) 2022 Ulrich Müller <ulm@gentoo.org>',
|
|
92
|
+
],
|
|
93
|
+
copyrightFrom: 'the headers of the C files compiled into the binary at that commit — src/espeak-ng.c, the libespeak-ng files the build compiles and src/ucd-tools/src/*.c — each distinct line as written',
|
|
78
94
|
notice: [
|
|
79
|
-
|
|
80
|
-
'The
|
|
95
|
+
`CHANGED by The Inclusionist: the eSpeak NG command-line program compiled to WebAssembly from commit ${ESPEAK_NG_COMMIT} of https://github.com/espeak-ng/espeak-ng.git, unchanged, with the phoneme data and the pt, es, en, de and fr dictionaries embedded, and linked so that it never evaluates text as code (-s DYNAMIC_EXECUTION=0). Recipe: the engine's scripts/models/build-espeak-ng.ps1.`,
|
|
96
|
+
'The binary also contains ucd-tools (GPL-3.0-or-later) with tables generated from the Unicode Character Database (the Unicode licence, COPYING.UCD in the source), and the Emscripten runtime and musl (MIT).',
|
|
97
|
+
'Where its Corresponding Source is: SOURCE, beside this file.',
|
|
81
98
|
],
|
|
82
99
|
source: [
|
|
83
|
-
'eSpeak NG in WebAssembly: where the
|
|
84
|
-
'',
|
|
85
|
-
'The files here are dist/espeak-ng.js and dist/espeak-ng.wasm of the npm package espeak-ng, version 1.0.2, unchanged: the',
|
|
86
|
-
'build checks each against the sha256 pinned in The Inclusionist engine\'s heavy-file catalogue before writing it. They are',
|
|
87
|
-
'licensed under the GNU General Public License, version 3 or later: the full text is LICENSE, beside this file.',
|
|
100
|
+
'eSpeak NG in WebAssembly: where the Corresponding Source of the files in this folder is',
|
|
88
101
|
'',
|
|
89
|
-
'
|
|
90
|
-
'
|
|
91
|
-
' names no commit of it;',
|
|
92
|
-
'- the eSpeak NG source it compiles: https://github.com/espeak-ng/espeak-ng.git, cloned by the build recipe in the package\'s',
|
|
93
|
-
' README, which names no tag and no commit;',
|
|
94
|
-
'- the version the binary reports: the string "1.52-dev", read from espeak-ng.wasm.',
|
|
102
|
+
'The files here, espeak-ng.js and espeak-ng.wasm, are eSpeak NG built for the browser by The Inclusionist. They are licensed',
|
|
103
|
+
'under the GNU General Public License, version 3 or later: the full text is LICENSE, beside this file.',
|
|
95
104
|
'',
|
|
96
|
-
'
|
|
105
|
+
'Their Corresponding Source (GPL-3.0, section 6) is:',
|
|
106
|
+
`- eSpeak NG at commit ${ESPEAK_NG_COMMIT}, unchanged: https://github.com/espeak-ng/espeak-ng.git;`,
|
|
107
|
+
'- the build recipe, scripts/models/build-espeak-ng.ps1 in The Inclusionist engine, which pins that commit, the Emscripten',
|
|
108
|
+
' toolchain (the emscripten/emsdk 3.1.49 image, by digest), the data it embeds and every flag. Run as it is, it writes these',
|
|
109
|
+
' two files byte for byte: the build checks each against the sha256 in the engine\'s heavy-file catalogue before writing it.',
|
|
97
110
|
'',
|
|
98
|
-
'
|
|
99
|
-
|
|
111
|
+
'A copy of both is published beside the build, in',
|
|
112
|
+
`${ESPEAK_NG_MIRROR}/corresponding-source/ :`,
|
|
113
|
+
`the source at that commit (${ESPEAK_NG_FOLDER}.tar.gz, made with git archive) and the recipe (build-espeak-ng.ps1).`,
|
|
100
114
|
],
|
|
101
115
|
},
|
|
102
116
|
{
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|