@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.
Files changed (528) hide show
  1. package/README.md +32 -1
  2. package/app/css/style.css +216 -42
  3. package/app/public/vendor/fonts-licences/NOTICE.txt +166 -0
  4. package/app/public/vendor/fonts-licences/OFL-1.1.txt +86 -0
  5. package/app/public/vendor/fonts.css +11 -1175
  6. package/dist-pkg/boot/create-game.d.ts +84 -33
  7. package/dist-pkg/boot/create-game.js +708 -307
  8. package/dist-pkg/core/a11y-sr.d.ts +1 -1
  9. package/dist-pkg/core/a11y-sr.js +3 -5
  10. package/dist-pkg/core/accommodations.d.ts +26 -8
  11. package/dist-pkg/core/accommodations.js +27 -10
  12. package/dist-pkg/core/actions.d.ts +39 -10
  13. package/dist-pkg/core/actions.js +28 -6
  14. package/dist-pkg/core/contract.d.ts +0 -2
  15. package/dist-pkg/core/contract.js +0 -2
  16. package/dist-pkg/core/i18n.d.ts +36 -71
  17. package/dist-pkg/core/i18n.js +131 -198
  18. package/dist-pkg/core/session-clock.d.ts +23 -0
  19. package/dist-pkg/core/session-clock.js +37 -0
  20. package/dist-pkg/i18n/en.js +44 -49
  21. package/dist-pkg/i18n/es.js +44 -49
  22. package/dist-pkg/i18n/pt.js +49 -54
  23. package/dist-pkg/input/gamepad.d.ts +42 -11
  24. package/dist-pkg/input/gamepad.js +50 -15
  25. package/dist-pkg/input/key-default.d.ts +30 -0
  26. package/dist-pkg/input/key-default.js +60 -0
  27. package/dist-pkg/input/keyboard-runtime.d.ts +0 -4
  28. package/dist-pkg/input/keyboard.d.ts +0 -1
  29. package/dist-pkg/input/keydown.d.ts +5 -11
  30. package/dist-pkg/input/keydown.js +3 -3
  31. package/dist-pkg/input/latch-edge.d.ts +10 -2
  32. package/dist-pkg/input/latch-edge.js +4 -3
  33. package/dist-pkg/input/latch-scope.d.ts +27 -22
  34. package/dist-pkg/input/latch-scope.js +25 -37
  35. package/dist-pkg/input/latch-store.d.ts +9 -12
  36. package/dist-pkg/input/latch-store.js +13 -18
  37. package/dist-pkg/input/latch-sync.d.ts +5 -4
  38. package/dist-pkg/input/latch-sync.js +5 -5
  39. package/dist-pkg/input/pad-reading.js +7 -2
  40. package/dist-pkg/input/pad-wizard.d.ts +4 -1
  41. package/dist-pkg/input/pad-wizard.js +60 -9
  42. package/dist-pkg/input/switch-scan.d.ts +29 -12
  43. package/dist-pkg/input/switch-scan.js +15 -2
  44. package/dist-pkg/input/touch-bindings.d.ts +3 -6
  45. package/dist-pkg/input/touch.d.ts +17 -2
  46. package/dist-pkg/input/touch.js +55 -17
  47. package/dist-pkg/input/transport-in-use.d.ts +5 -5
  48. package/dist-pkg/input/transport-in-use.js +5 -5
  49. package/dist-pkg/input/transports.d.ts +0 -9
  50. package/dist-pkg/input/transports.js +1 -1
  51. package/dist-pkg/input/virtual-controller.d.ts +39 -3
  52. package/dist-pkg/input/virtual-controller.js +32 -4
  53. package/dist-pkg/input/voice-map.d.ts +27 -11
  54. package/dist-pkg/input/voice-map.js +41 -43
  55. package/dist-pkg/platform/audio-ambient.d.ts +0 -1
  56. package/dist-pkg/platform/audio-ambient.js +3 -1
  57. package/dist-pkg/platform/audio-mixer.js +4 -9
  58. package/dist-pkg/platform/audio-sonar.d.ts +8 -94
  59. package/dist-pkg/platform/audio-sonar.js +22 -207
  60. package/dist-pkg/platform/audio.d.ts +10 -1
  61. package/dist-pkg/platform/audio.js +35 -2
  62. package/dist-pkg/platform/choose-by-voice.d.ts +70 -0
  63. package/dist-pkg/platform/choose-by-voice.js +157 -0
  64. package/dist-pkg/platform/font-library.d.ts +77 -0
  65. package/dist-pkg/platform/font-library.js +98 -0
  66. package/dist-pkg/platform/font-library.json +721 -0
  67. package/dist-pkg/platform/heavy-catalogue.d.ts +46 -0
  68. package/dist-pkg/platform/heavy-catalogue.js +47 -14
  69. package/dist-pkg/platform/heavy-mirror.d.ts +3 -9
  70. package/dist-pkg/platform/heavy-mirror.js +14 -17
  71. package/dist-pkg/platform/heavy.d.ts +40 -8
  72. package/dist-pkg/platform/heavy.js +177 -22
  73. package/dist-pkg/platform/interruptible-speech.d.ts +15 -8
  74. package/dist-pkg/platform/interruptible-speech.js +37 -13
  75. package/dist-pkg/platform/listener-scope.js +22 -13
  76. package/dist-pkg/platform/locale-host.d.ts +7 -3
  77. package/dist-pkg/platform/locale-host.js +13 -2
  78. package/dist-pkg/platform/reading-in-worker.d.ts +24 -0
  79. package/dist-pkg/platform/reading-in-worker.js +38 -0
  80. package/dist-pkg/platform/reading-model.d.ts +21 -0
  81. package/dist-pkg/platform/reading-model.js +25 -0
  82. package/dist-pkg/platform/reading-runtime.js +13 -8
  83. package/dist-pkg/platform/reading.d.ts +12 -1
  84. package/dist-pkg/platform/reading.js +9 -1
  85. package/dist-pkg/platform/speech-recognition.d.ts +10 -1
  86. package/dist-pkg/platform/speech-recognition.js +29 -9
  87. package/dist-pkg/platform/speech.d.ts +10 -1
  88. package/dist-pkg/platform/speech.js +24 -13
  89. package/dist-pkg/platform/tts.d.ts +37 -4
  90. package/dist-pkg/platform/tts.js +279 -57
  91. package/dist-pkg/platform/voice-listener.d.ts +6 -2
  92. package/dist-pkg/platform/voice-listener.js +1 -1
  93. package/dist-pkg/platform/voice-plan.d.ts +13 -0
  94. package/dist-pkg/platform/voice-plan.js +57 -2
  95. package/dist-pkg/platform/vosk-runtime.d.ts +25 -0
  96. package/dist-pkg/platform/vosk-runtime.js +59 -1
  97. package/dist-pkg/platform/vosk-vocabulary.d.ts +6 -0
  98. package/dist-pkg/platform/vosk-vocabulary.js +178 -0
  99. package/dist-pkg/render/crt.d.ts +11 -9
  100. package/dist-pkg/render/crt.js +6 -10
  101. package/dist-pkg/render/cvd-matrices.d.ts +5 -1
  102. package/dist-pkg/render/cvd-matrices.js +5 -1
  103. package/dist-pkg/render/high-contrast.d.ts +1 -2
  104. package/dist-pkg/render/high-contrast.js +5 -1
  105. package/dist-pkg/render/viz-axes.d.ts +9 -0
  106. package/dist-pkg/render/viz-axes.js +15 -2
  107. package/dist-pkg/ui/aac-sets.d.ts +29 -24
  108. package/dist-pkg/ui/aac-sets.js +22 -30
  109. package/dist-pkg/ui/audio-choices.d.ts +10 -5
  110. package/dist-pkg/ui/audio-choices.js +14 -10
  111. package/dist-pkg/ui/camera-control.d.ts +47 -0
  112. package/dist-pkg/ui/camera-control.js +35 -1
  113. package/dist-pkg/ui/declared-words.d.ts +21 -0
  114. package/dist-pkg/ui/declared-words.js +66 -0
  115. package/dist-pkg/ui/drawing-problems.js +4 -3
  116. package/dist-pkg/ui/eye-control.js +17 -17
  117. package/dist-pkg/ui/face-control.js +15 -15
  118. package/dist-pkg/ui/fonts.d.ts +42 -8
  119. package/dist-pkg/ui/fonts.js +58 -24
  120. package/dist-pkg/ui/footer-scroll-driver.d.ts +14 -0
  121. package/dist-pkg/ui/footer-scroll-driver.js +201 -0
  122. package/dist-pkg/ui/footer-scroll.d.ts +38 -0
  123. package/dist-pkg/ui/footer-scroll.js +55 -0
  124. package/dist-pkg/ui/game-options.d.ts +14 -9
  125. package/dist-pkg/ui/game-options.js +41 -21
  126. package/dist-pkg/ui/hand-control.js +15 -15
  127. package/dist-pkg/ui/help-panel.d.ts +19 -8
  128. package/dist-pkg/ui/help-panel.js +15 -5
  129. package/dist-pkg/ui/hud-bands.d.ts +29 -12
  130. package/dist-pkg/ui/hud-bands.js +63 -25
  131. package/dist-pkg/ui/hud-row.d.ts +34 -0
  132. package/dist-pkg/ui/hud-row.js +80 -0
  133. package/dist-pkg/ui/hud.d.ts +0 -3
  134. package/dist-pkg/ui/layout.js +5 -2
  135. package/dist-pkg/ui/libras-avatar-clip.d.ts +30 -0
  136. package/dist-pkg/ui/libras-avatar-clip.js +86 -0
  137. package/dist-pkg/ui/libras-avatar-load.d.ts +52 -0
  138. package/dist-pkg/ui/libras-avatar-load.js +134 -0
  139. package/dist-pkg/ui/libras-avatar-plan.d.ts +102 -0
  140. package/dist-pkg/ui/libras-avatar-plan.js +211 -0
  141. package/dist-pkg/ui/libras-avatar-player.d.ts +28 -0
  142. package/dist-pkg/ui/libras-avatar-player.js +226 -0
  143. package/dist-pkg/ui/libras-avatar-stage.d.ts +37 -0
  144. package/dist-pkg/ui/libras-avatar-stage.js +208 -0
  145. package/dist-pkg/ui/libras-glosses.d.ts +28 -0
  146. package/dist-pkg/ui/libras-glosses.js +161 -0
  147. package/dist-pkg/ui/menu-intent.d.ts +29 -0
  148. package/dist-pkg/ui/menu-intent.js +35 -1
  149. package/dist-pkg/ui/menu-items.d.ts +10 -0
  150. package/dist-pkg/ui/menu-items.js +29 -0
  151. package/dist-pkg/ui/menu-nav.d.ts +40 -4
  152. package/dist-pkg/ui/menu-nav.js +132 -47
  153. package/dist-pkg/ui/panel-widgets.d.ts +34 -0
  154. package/dist-pkg/ui/panel-widgets.js +86 -0
  155. package/dist-pkg/ui/pause-icons.d.ts +30 -14
  156. package/dist-pkg/ui/pause-icons.js +106 -45
  157. package/dist-pkg/ui/scan-overlay.d.ts +3 -3
  158. package/dist-pkg/ui/scan-overlay.js +11 -3
  159. package/dist-pkg/ui/screen-text.d.ts +25 -0
  160. package/dist-pkg/ui/screen-text.js +152 -0
  161. package/dist-pkg/ui/session-clock.d.ts +32 -0
  162. package/dist-pkg/ui/session-clock.js +67 -0
  163. package/dist-pkg/ui/settings-aac.d.ts +3 -1
  164. package/dist-pkg/ui/settings-aac.js +32 -13
  165. package/dist-pkg/ui/settings-audio.d.ts +10 -5
  166. package/dist-pkg/ui/settings-audio.js +101 -35
  167. package/dist-pkg/ui/settings-controls.d.ts +0 -4
  168. package/dist-pkg/ui/settings-mobility.d.ts +3 -6
  169. package/dist-pkg/ui/settings-mobility.js +4 -46
  170. package/dist-pkg/ui/settings-motion.js +2 -2
  171. package/dist-pkg/ui/settings-panel.d.ts +10 -0
  172. package/dist-pkg/ui/settings-panel.js +25 -1
  173. package/dist-pkg/ui/settings-typo.d.ts +5 -6
  174. package/dist-pkg/ui/settings-typo.js +20 -11
  175. package/dist-pkg/ui/settings-visual.js +2 -2
  176. package/dist-pkg/ui/shell.d.ts +1 -3
  177. package/dist-pkg/ui/shell.js +8 -4
  178. package/dist-pkg/ui/title.d.ts +2 -11
  179. package/dist-pkg/ui/title.js +39 -6
  180. package/dist-pkg/ui/top-band.d.ts +5 -3
  181. package/dist-pkg/ui/top-band.js +21 -25
  182. package/dist-pkg/ui/typo-choices.d.ts +3 -3
  183. package/dist-pkg/ui/typo-choices.js +9 -8
  184. package/dist-pkg/ui/vlibras.d.ts +71 -27
  185. package/dist-pkg/ui/vlibras.js +116 -44
  186. package/dist-pkg/ui/voice-control.d.ts +23 -1
  187. package/dist-pkg/ui/voice-control.js +149 -16
  188. package/dist-pkg/ui/voice-settings.d.ts +2 -3
  189. package/dist-pkg/ui/voice-settings.js +53 -3
  190. package/dist-pkg/ui/where-the-child-is.js +2 -2
  191. package/docs/CREDITS.md +122 -10
  192. package/docs/LICENSES.md +36 -7
  193. package/package.json +34 -9
  194. package/scripts/check-cartridge.mjs +78 -0
  195. package/scripts/game-build.d.mts +25 -0
  196. package/scripts/game-build.mjs +144 -0
  197. package/scripts/heavy-into-the-delivery.mjs +284 -40
  198. package/scripts/libras-avatar.json +680 -0
  199. package/scripts/libras-avatar.mjs +246 -0
  200. package/scripts/libras-glosses/gloss.py +95 -0
  201. package/scripts/libras-glosses/pyproject.toml +32 -0
  202. package/scripts/libras-glosses/uv.lock +781 -0
  203. package/scripts/libras-glosses.mjs +351 -0
  204. package/scripts/licences/OFL-1.1.txt +86 -0
  205. package/scripts/licences/UFL-1.0.txt +96 -0
  206. package/scripts/licences/fonts.mjs +389 -0
  207. package/scripts/licences/third-party.mjs +35 -21
  208. package/app/public/vendor/fonts/bitter-var-ext.woff2 +0 -0
  209. package/app/public/vendor/fonts/bitter-var.woff2 +0 -0
  210. package/app/public/vendor/fonts/bodonimoda-var-ext.woff2 +0 -0
  211. package/app/public/vendor/fonts/bodonimoda-var.woff2 +0 -0
  212. package/app/public/vendor/fonts/cat-abril_fatface-400-ext.woff2 +0 -0
  213. package/app/public/vendor/fonts/cat-abril_fatface-400.woff2 +0 -0
  214. package/app/public/vendor/fonts/cat-adlam_display-400-ext.woff2 +0 -0
  215. package/app/public/vendor/fonts/cat-adlam_display-400.woff2 +0 -0
  216. package/app/public/vendor/fonts/cat-agu_display-400-ext.woff2 +0 -0
  217. package/app/public/vendor/fonts/cat-agu_display-400.woff2 +0 -0
  218. package/app/public/vendor/fonts/cat-alfa_slab_one-400-ext.woff2 +0 -0
  219. package/app/public/vendor/fonts/cat-alfa_slab_one-400.woff2 +0 -0
  220. package/app/public/vendor/fonts/cat-are_you_serious-400-ext.woff2 +0 -0
  221. package/app/public/vendor/fonts/cat-are_you_serious-400.woff2 +0 -0
  222. package/app/public/vendor/fonts/cat-asimovian-400-ext.woff2 +0 -0
  223. package/app/public/vendor/fonts/cat-asimovian-400.woff2 +0 -0
  224. package/app/public/vendor/fonts/cat-atkinson_hyperlegible_next-400-ext.woff2 +0 -0
  225. package/app/public/vendor/fonts/cat-atkinson_hyperlegible_next-400.woff2 +0 -0
  226. package/app/public/vendor/fonts/cat-bakbak_one-400-ext.woff2 +0 -0
  227. package/app/public/vendor/fonts/cat-bakbak_one-400.woff2 +0 -0
  228. package/app/public/vendor/fonts/cat-bangers-400-ext.woff2 +0 -0
  229. package/app/public/vendor/fonts/cat-bangers-400.woff2 +0 -0
  230. package/app/public/vendor/fonts/cat-barriecito-400-ext.woff2 +0 -0
  231. package/app/public/vendor/fonts/cat-barriecito-400.woff2 +0 -0
  232. package/app/public/vendor/fonts/cat-berkshire_swash-400-ext.woff2 +0 -0
  233. package/app/public/vendor/fonts/cat-berkshire_swash-400.woff2 +0 -0
  234. package/app/public/vendor/fonts/cat-bevan-400-ext.woff2 +0 -0
  235. package/app/public/vendor/fonts/cat-bevan-400.woff2 +0 -0
  236. package/app/public/vendor/fonts/cat-bitcount-400-ext.woff2 +0 -0
  237. package/app/public/vendor/fonts/cat-bitcount-400.woff2 +0 -0
  238. package/app/public/vendor/fonts/cat-bowlby_one_sc-400-ext.woff2 +0 -0
  239. package/app/public/vendor/fonts/cat-bowlby_one_sc-400.woff2 +0 -0
  240. package/app/public/vendor/fonts/cat-bungee_shade-400-ext.woff2 +0 -0
  241. package/app/public/vendor/fonts/cat-bungee_shade-400.woff2 +0 -0
  242. package/app/public/vendor/fonts/cat-charm-400-ext.woff2 +0 -0
  243. package/app/public/vendor/fonts/cat-charm-400.woff2 +0 -0
  244. package/app/public/vendor/fonts/cat-charm-700-ext.woff2 +0 -0
  245. package/app/public/vendor/fonts/cat-charm-700.woff2 +0 -0
  246. package/app/public/vendor/fonts/cat-cherry_bomb_one-400-ext.woff2 +0 -0
  247. package/app/public/vendor/fonts/cat-cherry_bomb_one-400.woff2 +0 -0
  248. package/app/public/vendor/fonts/cat-chokokutai-400-ext.woff2 +0 -0
  249. package/app/public/vendor/fonts/cat-chokokutai-400.woff2 +0 -0
  250. package/app/public/vendor/fonts/cat-chonburi-400-ext.woff2 +0 -0
  251. package/app/public/vendor/fonts/cat-chonburi-400.woff2 +0 -0
  252. package/app/public/vendor/fonts/cat-climate_crisis-400-ext.woff2 +0 -0
  253. package/app/public/vendor/fonts/cat-climate_crisis-400.woff2 +0 -0
  254. package/app/public/vendor/fonts/cat-cookie-400.woff2 +0 -0
  255. package/app/public/vendor/fonts/cat-dela_gothic_one-400-ext.woff2 +0 -0
  256. package/app/public/vendor/fonts/cat-dela_gothic_one-400.woff2 +0 -0
  257. package/app/public/vendor/fonts/cat-fascinate_inline-400-ext.woff2 +0 -0
  258. package/app/public/vendor/fonts/cat-fascinate_inline-400.woff2 +0 -0
  259. package/app/public/vendor/fonts/cat-ga_maamli-400-ext.woff2 +0 -0
  260. package/app/public/vendor/fonts/cat-ga_maamli-400.woff2 +0 -0
  261. package/app/public/vendor/fonts/cat-itim-400-ext.woff2 +0 -0
  262. package/app/public/vendor/fonts/cat-itim-400.woff2 +0 -0
  263. package/app/public/vendor/fonts/cat-jacquard_24-400-ext.woff2 +0 -0
  264. package/app/public/vendor/fonts/cat-jacquard_24-400.woff2 +0 -0
  265. package/app/public/vendor/fonts/cat-kablammo-400-ext.woff2 +0 -0
  266. package/app/public/vendor/fonts/cat-kablammo-400.woff2 +0 -0
  267. package/app/public/vendor/fonts/cat-kalam-400-ext.woff2 +0 -0
  268. package/app/public/vendor/fonts/cat-kalam-400.woff2 +0 -0
  269. package/app/public/vendor/fonts/cat-kalam-700-ext.woff2 +0 -0
  270. package/app/public/vendor/fonts/cat-kalam-700.woff2 +0 -0
  271. package/app/public/vendor/fonts/cat-katibeh-400-ext.woff2 +0 -0
  272. package/app/public/vendor/fonts/cat-katibeh-400.woff2 +0 -0
  273. package/app/public/vendor/fonts/cat-lemonada-400-ext.woff2 +0 -0
  274. package/app/public/vendor/fonts/cat-lemonada-400.woff2 +0 -0
  275. package/app/public/vendor/fonts/cat-lilita_one-400-ext.woff2 +0 -0
  276. package/app/public/vendor/fonts/cat-lilita_one-400.woff2 +0 -0
  277. package/app/public/vendor/fonts/cat-lobster-400-ext.woff2 +0 -0
  278. package/app/public/vendor/fonts/cat-lobster-400.woff2 +0 -0
  279. package/app/public/vendor/fonts/cat-luckiest_guy-400-ext.woff2 +0 -0
  280. package/app/public/vendor/fonts/cat-luckiest_guy-400.woff2 +0 -0
  281. package/app/public/vendor/fonts/cat-marhey-400-ext.woff2 +0 -0
  282. package/app/public/vendor/fonts/cat-marhey-400.woff2 +0 -0
  283. package/app/public/vendor/fonts/cat-modak-400-ext.woff2 +0 -0
  284. package/app/public/vendor/fonts/cat-modak-400.woff2 +0 -0
  285. package/app/public/vendor/fonts/cat-momo_signature-400-ext.woff2 +0 -0
  286. package/app/public/vendor/fonts/cat-momo_signature-400.woff2 +0 -0
  287. package/app/public/vendor/fonts/cat-monofett-400-ext.woff2 +0 -0
  288. package/app/public/vendor/fonts/cat-monofett-400.woff2 +0 -0
  289. package/app/public/vendor/fonts/cat-monomakh-400-ext.woff2 +0 -0
  290. package/app/public/vendor/fonts/cat-monomakh-400.woff2 +0 -0
  291. package/app/public/vendor/fonts/cat-monoton-400-ext.woff2 +0 -0
  292. package/app/public/vendor/fonts/cat-monoton-400.woff2 +0 -0
  293. package/app/public/vendor/fonts/cat-nerko_one-400-ext.woff2 +0 -0
  294. package/app/public/vendor/fonts/cat-nerko_one-400.woff2 +0 -0
  295. package/app/public/vendor/fonts/cat-noto_sans_adlam-400-ext.woff2 +0 -0
  296. package/app/public/vendor/fonts/cat-noto_sans_adlam-400.woff2 +0 -0
  297. package/app/public/vendor/fonts/cat-noto_sans_arabic-400-ext.woff2 +0 -0
  298. package/app/public/vendor/fonts/cat-noto_sans_arabic-400.woff2 +0 -0
  299. package/app/public/vendor/fonts/cat-noto_sans_devanagari-400-ext.woff2 +0 -0
  300. package/app/public/vendor/fonts/cat-noto_sans_devanagari-400.woff2 +0 -0
  301. package/app/public/vendor/fonts/cat-noto_sans_hebrew-400-ext.woff2 +0 -0
  302. package/app/public/vendor/fonts/cat-noto_sans_hebrew-400.woff2 +0 -0
  303. package/app/public/vendor/fonts/cat-noto_sans_jp-400-ext.woff2 +0 -0
  304. package/app/public/vendor/fonts/cat-noto_sans_jp-400.woff2 +0 -0
  305. package/app/public/vendor/fonts/cat-noto_sans_khmer-400-ext.woff2 +0 -0
  306. package/app/public/vendor/fonts/cat-noto_sans_khmer-400.woff2 +0 -0
  307. package/app/public/vendor/fonts/cat-noto_sans_kr-400-ext.woff2 +0 -0
  308. package/app/public/vendor/fonts/cat-noto_sans_kr-400.woff2 +0 -0
  309. package/app/public/vendor/fonts/cat-noto_sans_sc-400-ext.woff2 +0 -0
  310. package/app/public/vendor/fonts/cat-noto_sans_sc-400.woff2 +0 -0
  311. package/app/public/vendor/fonts/cat-noto_sans_thai-400-ext.woff2 +0 -0
  312. package/app/public/vendor/fonts/cat-noto_sans_thai-400.woff2 +0 -0
  313. package/app/public/vendor/fonts/cat-ole-400-ext.woff2 +0 -0
  314. package/app/public/vendor/fonts/cat-ole-400.woff2 +0 -0
  315. package/app/public/vendor/fonts/cat-pacifico-400-ext.woff2 +0 -0
  316. package/app/public/vendor/fonts/cat-pacifico-400.woff2 +0 -0
  317. package/app/public/vendor/fonts/cat-patrick_hand-400-ext.woff2 +0 -0
  318. package/app/public/vendor/fonts/cat-patrick_hand-400.woff2 +0 -0
  319. package/app/public/vendor/fonts/cat-petit_formal_script-400-ext.woff2 +0 -0
  320. package/app/public/vendor/fonts/cat-petit_formal_script-400.woff2 +0 -0
  321. package/app/public/vendor/fonts/cat-pixelify_sans-400-ext.woff2 +0 -0
  322. package/app/public/vendor/fonts/cat-pixelify_sans-400.woff2 +0 -0
  323. package/app/public/vendor/fonts/cat-plaster-400-ext.woff2 +0 -0
  324. package/app/public/vendor/fonts/cat-plaster-400.woff2 +0 -0
  325. package/app/public/vendor/fonts/cat-playwrite_ar_guides-400-0.woff2 +0 -0
  326. package/app/public/vendor/fonts/cat-playwrite_at-400-0.woff2 +0 -0
  327. package/app/public/vendor/fonts/cat-playwrite_at_guides-400-0.woff2 +0 -0
  328. package/app/public/vendor/fonts/cat-playwrite_au_nsw-400-0.woff2 +0 -0
  329. package/app/public/vendor/fonts/cat-playwrite_au_nsw_guides-400-0.woff2 +0 -0
  330. package/app/public/vendor/fonts/cat-playwrite_au_qld-400-0.woff2 +0 -0
  331. package/app/public/vendor/fonts/cat-playwrite_au_qld_guides-400-0.woff2 +0 -0
  332. package/app/public/vendor/fonts/cat-playwrite_au_sa-400-0.woff2 +0 -0
  333. package/app/public/vendor/fonts/cat-playwrite_au_sa_guides-400-0.woff2 +0 -0
  334. package/app/public/vendor/fonts/cat-playwrite_au_tas-400-0.woff2 +0 -0
  335. package/app/public/vendor/fonts/cat-playwrite_au_tas_guides-400-0.woff2 +0 -0
  336. package/app/public/vendor/fonts/cat-playwrite_au_vic-400-0.woff2 +0 -0
  337. package/app/public/vendor/fonts/cat-playwrite_au_vic_guides-400-0.woff2 +0 -0
  338. package/app/public/vendor/fonts/cat-playwrite_be_vlg-400-0.woff2 +0 -0
  339. package/app/public/vendor/fonts/cat-playwrite_be_vlg_guides-400-0.woff2 +0 -0
  340. package/app/public/vendor/fonts/cat-playwrite_be_wal-400-0.woff2 +0 -0
  341. package/app/public/vendor/fonts/cat-playwrite_be_wal_guides-400-0.woff2 +0 -0
  342. package/app/public/vendor/fonts/cat-playwrite_br_guides-400-0.woff2 +0 -0
  343. package/app/public/vendor/fonts/cat-playwrite_ca_guides-400-0.woff2 +0 -0
  344. package/app/public/vendor/fonts/cat-playwrite_cl_guides-400-0.woff2 +0 -0
  345. package/app/public/vendor/fonts/cat-playwrite_co_guides-400-0.woff2 +0 -0
  346. package/app/public/vendor/fonts/cat-playwrite_cu_guides-400-0.woff2 +0 -0
  347. package/app/public/vendor/fonts/cat-playwrite_cz-400-0.woff2 +0 -0
  348. package/app/public/vendor/fonts/cat-playwrite_cz_guides-400-0.woff2 +0 -0
  349. package/app/public/vendor/fonts/cat-playwrite_de_grund-400-0.woff2 +0 -0
  350. package/app/public/vendor/fonts/cat-playwrite_de_grund_guides-400-0.woff2 +0 -0
  351. package/app/public/vendor/fonts/cat-playwrite_de_la-400-0.woff2 +0 -0
  352. package/app/public/vendor/fonts/cat-playwrite_de_la_guides-400-0.woff2 +0 -0
  353. package/app/public/vendor/fonts/cat-playwrite_de_sas-400-0.woff2 +0 -0
  354. package/app/public/vendor/fonts/cat-playwrite_de_sas_guides-400-0.woff2 +0 -0
  355. package/app/public/vendor/fonts/cat-playwrite_de_va-400-0.woff2 +0 -0
  356. package/app/public/vendor/fonts/cat-playwrite_de_va_guides-400-0.woff2 +0 -0
  357. package/app/public/vendor/fonts/cat-playwrite_dk_loopet-400-0.woff2 +0 -0
  358. package/app/public/vendor/fonts/cat-playwrite_dk_loopet_guides-400-0.woff2 +0 -0
  359. package/app/public/vendor/fonts/cat-playwrite_dk_uloopet-400-0.woff2 +0 -0
  360. package/app/public/vendor/fonts/cat-playwrite_dk_uloopet_guides-400-0.woff2 +0 -0
  361. package/app/public/vendor/fonts/cat-playwrite_es_deco_guides-400-0.woff2 +0 -0
  362. package/app/public/vendor/fonts/cat-playwrite_es_guides-400-0.woff2 +0 -0
  363. package/app/public/vendor/fonts/cat-playwrite_fr_moderne-400-0.woff2 +0 -0
  364. package/app/public/vendor/fonts/cat-playwrite_fr_moderne_guides-400-0.woff2 +0 -0
  365. package/app/public/vendor/fonts/cat-playwrite_fr_trad-400-0.woff2 +0 -0
  366. package/app/public/vendor/fonts/cat-playwrite_fr_trad_guides-400-0.woff2 +0 -0
  367. package/app/public/vendor/fonts/cat-playwrite_gb_j_guides-400-0.woff2 +0 -0
  368. package/app/public/vendor/fonts/cat-playwrite_gb_s_guides-400-0.woff2 +0 -0
  369. package/app/public/vendor/fonts/cat-playwrite_hr-400-0.woff2 +0 -0
  370. package/app/public/vendor/fonts/cat-playwrite_hr_guides-400-0.woff2 +0 -0
  371. package/app/public/vendor/fonts/cat-playwrite_hr_lijeva-400-0.woff2 +0 -0
  372. package/app/public/vendor/fonts/cat-playwrite_hr_lijeva_guides-400-0.woff2 +0 -0
  373. package/app/public/vendor/fonts/cat-playwrite_hu-400-0.woff2 +0 -0
  374. package/app/public/vendor/fonts/cat-playwrite_hu_guides-400-0.woff2 +0 -0
  375. package/app/public/vendor/fonts/cat-playwrite_id-400-0.woff2 +0 -0
  376. package/app/public/vendor/fonts/cat-playwrite_id_guides-400-0.woff2 +0 -0
  377. package/app/public/vendor/fonts/cat-playwrite_ie-400-0.woff2 +0 -0
  378. package/app/public/vendor/fonts/cat-playwrite_ie_guides-400-0.woff2 +0 -0
  379. package/app/public/vendor/fonts/cat-playwrite_in-400-0.woff2 +0 -0
  380. package/app/public/vendor/fonts/cat-playwrite_in_guides-400-0.woff2 +0 -0
  381. package/app/public/vendor/fonts/cat-playwrite_is-400-0.woff2 +0 -0
  382. package/app/public/vendor/fonts/cat-playwrite_is_guides-400-0.woff2 +0 -0
  383. package/app/public/vendor/fonts/cat-playwrite_it_moderna-400-0.woff2 +0 -0
  384. package/app/public/vendor/fonts/cat-playwrite_it_moderna_guides-400-0.woff2 +0 -0
  385. package/app/public/vendor/fonts/cat-playwrite_it_trad-400-0.woff2 +0 -0
  386. package/app/public/vendor/fonts/cat-playwrite_it_trad_guides-400-0.woff2 +0 -0
  387. package/app/public/vendor/fonts/cat-playwrite_mx_guides-400-0.woff2 +0 -0
  388. package/app/public/vendor/fonts/cat-playwrite_ng_modern-400-0.woff2 +0 -0
  389. package/app/public/vendor/fonts/cat-playwrite_ng_modern_guides-400-0.woff2 +0 -0
  390. package/app/public/vendor/fonts/cat-playwrite_nl-400-0.woff2 +0 -0
  391. package/app/public/vendor/fonts/cat-playwrite_nl_guides-400-0.woff2 +0 -0
  392. package/app/public/vendor/fonts/cat-playwrite_no-400-0.woff2 +0 -0
  393. package/app/public/vendor/fonts/cat-playwrite_no_guides-400-0.woff2 +0 -0
  394. package/app/public/vendor/fonts/cat-playwrite_nz-400-0.woff2 +0 -0
  395. package/app/public/vendor/fonts/cat-playwrite_nz_basic-400-0.woff2 +0 -0
  396. package/app/public/vendor/fonts/cat-playwrite_nz_basic_guides-400-0.woff2 +0 -0
  397. package/app/public/vendor/fonts/cat-playwrite_nz_guides-400-0.woff2 +0 -0
  398. package/app/public/vendor/fonts/cat-playwrite_pe_guides-400-0.woff2 +0 -0
  399. package/app/public/vendor/fonts/cat-playwrite_pl-400-0.woff2 +0 -0
  400. package/app/public/vendor/fonts/cat-playwrite_pl_guides-400-0.woff2 +0 -0
  401. package/app/public/vendor/fonts/cat-playwrite_pt_guides-400-0.woff2 +0 -0
  402. package/app/public/vendor/fonts/cat-playwrite_ro-400-0.woff2 +0 -0
  403. package/app/public/vendor/fonts/cat-playwrite_ro_guides-400-0.woff2 +0 -0
  404. package/app/public/vendor/fonts/cat-playwrite_sk-400-0.woff2 +0 -0
  405. package/app/public/vendor/fonts/cat-playwrite_sk_guides-400-0.woff2 +0 -0
  406. package/app/public/vendor/fonts/cat-playwrite_tz-400-0.woff2 +0 -0
  407. package/app/public/vendor/fonts/cat-playwrite_tz_guides-400-0.woff2 +0 -0
  408. package/app/public/vendor/fonts/cat-playwrite_us_modern_guides-400-0.woff2 +0 -0
  409. package/app/public/vendor/fonts/cat-playwrite_us_trad_guides-400-0.woff2 +0 -0
  410. package/app/public/vendor/fonts/cat-playwrite_vn-400-0.woff2 +0 -0
  411. package/app/public/vendor/fonts/cat-playwrite_vn_guides-400-0.woff2 +0 -0
  412. package/app/public/vendor/fonts/cat-playwrite_za-400-0.woff2 +0 -0
  413. package/app/public/vendor/fonts/cat-playwrite_za_guides-400-0.woff2 +0 -0
  414. package/app/public/vendor/fonts/cat-potta_one-400-ext.woff2 +0 -0
  415. package/app/public/vendor/fonts/cat-potta_one-400.woff2 +0 -0
  416. package/app/public/vendor/fonts/cat-ranchers-400-ext.woff2 +0 -0
  417. package/app/public/vendor/fonts/cat-ranchers-400.woff2 +0 -0
  418. package/app/public/vendor/fonts/cat-ranga-400-ext.woff2 +0 -0
  419. package/app/public/vendor/fonts/cat-ranga-400.woff2 +0 -0
  420. package/app/public/vendor/fonts/cat-ranga-700-ext.woff2 +0 -0
  421. package/app/public/vendor/fonts/cat-ranga-700.woff2 +0 -0
  422. package/app/public/vendor/fonts/cat-risque-400-ext.woff2 +0 -0
  423. package/app/public/vendor/fonts/cat-risque-400.woff2 +0 -0
  424. package/app/public/vendor/fonts/cat-rowdies-400-ext.woff2 +0 -0
  425. package/app/public/vendor/fonts/cat-rowdies-400.woff2 +0 -0
  426. package/app/public/vendor/fonts/cat-rowdies-700-ext.woff2 +0 -0
  427. package/app/public/vendor/fonts/cat-rowdies-700.woff2 +0 -0
  428. package/app/public/vendor/fonts/cat-ruge_boogie-400-ext.woff2 +0 -0
  429. package/app/public/vendor/fonts/cat-ruge_boogie-400.woff2 +0 -0
  430. package/app/public/vendor/fonts/cat-ruslan_display-400-ext.woff2 +0 -0
  431. package/app/public/vendor/fonts/cat-ruslan_display-400.woff2 +0 -0
  432. package/app/public/vendor/fonts/cat-sacramento-400-ext.woff2 +0 -0
  433. package/app/public/vendor/fonts/cat-sacramento-400.woff2 +0 -0
  434. package/app/public/vendor/fonts/cat-sancreek-400-ext.woff2 +0 -0
  435. package/app/public/vendor/fonts/cat-sancreek-400.woff2 +0 -0
  436. package/app/public/vendor/fonts/cat-sankofa_display-400-ext.woff2 +0 -0
  437. package/app/public/vendor/fonts/cat-sankofa_display-400.woff2 +0 -0
  438. package/app/public/vendor/fonts/cat-sedgwick_ave_display-400-ext.woff2 +0 -0
  439. package/app/public/vendor/fonts/cat-sedgwick_ave_display-400.woff2 +0 -0
  440. package/app/public/vendor/fonts/cat-shantell_sans-400-ext.woff2 +0 -0
  441. package/app/public/vendor/fonts/cat-shantell_sans-400.woff2 +0 -0
  442. package/app/public/vendor/fonts/cat-smokum-400-ext.woff2 +0 -0
  443. package/app/public/vendor/fonts/cat-smokum-400.woff2 +0 -0
  444. package/app/public/vendor/fonts/cat-solitreo-400-ext.woff2 +0 -0
  445. package/app/public/vendor/fonts/cat-solitreo-400.woff2 +0 -0
  446. package/app/public/vendor/fonts/cat-spicy_rice-400-ext.woff2 +0 -0
  447. package/app/public/vendor/fonts/cat-spicy_rice-400.woff2 +0 -0
  448. package/app/public/vendor/fonts/cat-sriracha-400-ext.woff2 +0 -0
  449. package/app/public/vendor/fonts/cat-sriracha-400.woff2 +0 -0
  450. package/app/public/vendor/fonts/cat-srisakdi-400-ext.woff2 +0 -0
  451. package/app/public/vendor/fonts/cat-srisakdi-400.woff2 +0 -0
  452. package/app/public/vendor/fonts/cat-srisakdi-700-ext.woff2 +0 -0
  453. package/app/public/vendor/fonts/cat-srisakdi-700.woff2 +0 -0
  454. package/app/public/vendor/fonts/cat-stix_two_math-400-0.woff2 +0 -0
  455. package/app/public/vendor/fonts/cat-tillana-400-ext.woff2 +0 -0
  456. package/app/public/vendor/fonts/cat-tillana-400.woff2 +0 -0
  457. package/app/public/vendor/fonts/cat-tillana-700-ext.woff2 +0 -0
  458. package/app/public/vendor/fonts/cat-tillana-700.woff2 +0 -0
  459. package/app/public/vendor/fonts/cat-titan_one-400-ext.woff2 +0 -0
  460. package/app/public/vendor/fonts/cat-titan_one-400.woff2 +0 -0
  461. package/app/public/vendor/fonts/cat-yatra_one-400-ext.woff2 +0 -0
  462. package/app/public/vendor/fonts/cat-yatra_one-400.woff2 +0 -0
  463. package/app/public/vendor/fonts/cat-yomogi-400-ext.woff2 +0 -0
  464. package/app/public/vendor/fonts/cat-yomogi-400.woff2 +0 -0
  465. package/app/public/vendor/fonts/dmserifdisplay-400-ext.woff2 +0 -0
  466. package/app/public/vendor/fonts/dmserifdisplay-400.woff2 +0 -0
  467. package/app/public/vendor/fonts/domine-var-ext.woff2 +0 -0
  468. package/app/public/vendor/fonts/domine-var.woff2 +0 -0
  469. package/app/public/vendor/fonts/fondamento-400-ext.woff2 +0 -0
  470. package/app/public/vendor/fonts/fondamento-400.woff2 +0 -0
  471. package/app/public/vendor/fonts/fraunces-var-ext.woff2 +0 -0
  472. package/app/public/vendor/fonts/fraunces-var.woff2 +0 -0
  473. package/app/public/vendor/fonts/fredoka-var-ext.woff2 +0 -0
  474. package/app/public/vendor/fonts/fredoka-var.woff2 +0 -0
  475. package/app/public/vendor/fonts/inter-400.woff2 +0 -0
  476. package/app/public/vendor/fonts/inter-700.woff2 +0 -0
  477. package/app/public/vendor/fonts/jakarta-var-ext.woff2 +0 -0
  478. package/app/public/vendor/fonts/jakarta-var.woff2 +0 -0
  479. package/app/public/vendor/fonts/lato-400.woff2 +0 -0
  480. package/app/public/vendor/fonts/lato-700.woff2 +0 -0
  481. package/app/public/vendor/fonts/literata-400.woff2 +0 -0
  482. package/app/public/vendor/fonts/literata-700.woff2 +0 -0
  483. package/app/public/vendor/fonts/lora-var-ext.woff2 +0 -0
  484. package/app/public/vendor/fonts/lora-var.woff2 +0 -0
  485. package/app/public/vendor/fonts/merriweather-var-ext.woff2 +0 -0
  486. package/app/public/vendor/fonts/merriweather-var.woff2 +0 -0
  487. package/app/public/vendor/fonts/newsreader-400.woff2 +0 -0
  488. package/app/public/vendor/fonts/newsreader-700.woff2 +0 -0
  489. package/app/public/vendor/fonts/notosans-var-ext.woff2 +0 -0
  490. package/app/public/vendor/fonts/notosans-var.woff2 +0 -0
  491. package/app/public/vendor/fonts/nunito-var-ext.woff2 +0 -0
  492. package/app/public/vendor/fonts/nunito-var.woff2 +0 -0
  493. package/app/public/vendor/fonts/opendyslexic-400.woff2 +0 -0
  494. package/app/public/vendor/fonts/opensans-400.woff2 +0 -0
  495. package/app/public/vendor/fonts/opensans-700.woff2 +0 -0
  496. package/app/public/vendor/fonts/pinyon-400.woff2 +0 -0
  497. package/app/public/vendor/fonts/playfair-var-ext.woff2 +0 -0
  498. package/app/public/vendor/fonts/playfair-var.woff2 +0 -0
  499. package/app/public/vendor/fonts/pressstart-400.woff2 +0 -0
  500. package/app/public/vendor/fonts/quattro-400.woff2 +0 -0
  501. package/app/public/vendor/fonts/quattro-700.woff2 +0 -0
  502. package/app/public/vendor/fonts/quicksand-var-ext.woff2 +0 -0
  503. package/app/public/vendor/fonts/quicksand-var.woff2 +0 -0
  504. package/app/public/vendor/fonts/robotoflex-var-ext.woff2 +0 -0
  505. package/app/public/vendor/fonts/robotoflex-var.woff2 +0 -0
  506. package/app/public/vendor/fonts/sora-var-ext.woff2 +0 -0
  507. package/app/public/vendor/fonts/sora-var.woff2 +0 -0
  508. package/app/public/vendor/fonts/sourcesans-400.woff2 +0 -0
  509. package/app/public/vendor/fonts/sourcesans-700.woff2 +0 -0
  510. package/app/public/vendor/fonts/sourceserif-400.woff2 +0 -0
  511. package/app/public/vendor/fonts/sourceserif-700.woff2 +0 -0
  512. package/app/public/vendor/fonts/spacegrotesk-var-ext.woff2 +0 -0
  513. package/app/public/vendor/fonts/spacegrotesk-var.woff2 +0 -0
  514. package/app/public/vendor/fonts/spectral-400-ext.woff2 +0 -0
  515. package/app/public/vendor/fonts/spectral-400.woff2 +0 -0
  516. package/app/public/vendor/fonts/spectral-700-ext.woff2 +0 -0
  517. package/app/public/vendor/fonts/spectral-700.woff2 +0 -0
  518. package/app/public/vendor/fonts/teachers-var-ext.woff2 +0 -0
  519. package/app/public/vendor/fonts/teachers-var.woff2 +0 -0
  520. package/app/public/vendor/fonts/ubuntu-400-ext.woff2 +0 -0
  521. package/app/public/vendor/fonts/ubuntu-400.woff2 +0 -0
  522. package/app/public/vendor/fonts/ubuntu-700-ext.woff2 +0 -0
  523. package/app/public/vendor/fonts/ubuntu-700.woff2 +0 -0
  524. package/app/public/vendor/fonts/ufmag-400.woff2 +0 -0
  525. package/dist-pkg/platform/guide-intensity.d.ts +0 -39
  526. package/dist-pkg/platform/guide-intensity.js +0 -71
  527. package/dist-pkg/ui/latch-refusal.d.ts +0 -33
  528. package/dist-pkg/ui/latch-refusal.js +0 -60
@@ -16,6 +16,9 @@
16
16
  // (`platform/heavy-mirror`); without one, from upstream. The sha256 check does not move: a base that serves other bytes writes
17
17
  // nothing, which is why pointing elsewhere is safe and needs no trust.
18
18
  //
19
+ // THE FONT LIBRARY TRAVELS THE SAME WAY (ADR-0255): `--fonts` puts the families the cartridges declare into `heavy/`, each face
20
+ // checked against the engine's font catalogue, each family with its licence text and notice (`licences/fonts.mjs`).
21
+ //
19
22
  // WHAT THE FILES OWE TRAVELS WITH THEM (`licences/third-party.mjs`): every folder of `heavy/` that holds a file also gets its
20
23
  // project's `LICENSE` and `NOTICE` (eSpeak NG's also a `SOURCE`), and `heavy/THIRD-PARTY-NOTICES.md` lists each project. A
21
24
  // catalogue entry whose licence nobody recorded there is refused like a file whose sha256 differs.
@@ -25,6 +28,9 @@ import { dirname, join } from 'node:path';
25
28
  import { createHash } from 'node:crypto';
26
29
  import { pathToFileURL, fileURLToPath } from 'node:url';
27
30
  import { THIRD_PARTY, groupOf, writeLicences } from './licences/third-party.mjs';
31
+ import { familyLicenceFiles } from './licences/fonts.mjs';
32
+ import { deliverLibrasGlosses, readTexts, runGlosser, setUpGlosser } from './libras-glosses.mjs';
33
+ import { deliverLibrasAvatar, readAvatarPins, stageChunkOf, writeAvatarList } from './libras-avatar.mjs';
28
34
 
29
35
  /** The compiled catalogue of the package this script ships in — beside it, whatever folder the build runs from. */
30
36
  export function moduloDoPacote() {
@@ -33,13 +39,94 @@ export function moduloDoPacote() {
33
39
 
34
40
  const sha256DoNode = (buf) => createHash('sha256').update(Buffer.from(buf)).digest('hex');
35
41
 
42
+ /**
43
+ * ONE FILE, FETCHED (or read from a local base), CHECKED AGAINST ITS PINNED SHA256 AND WRITTEN — or refused with the reason, and
44
+ * nothing written. The one rule the catalogue's files and the library's fonts go through.
45
+ */
46
+ async function trazerVerificado(p, alvo, { source, fetchFile, readLocal, sha256 }) {
47
+ try {
48
+ let corpo;
49
+ if (/^https?:\/\//i.test(source)) {
50
+ const resp = await fetchFile(source);
51
+ if (!resp.ok) return { id: p.id, outcome: 'falhou', error: `HTTP ${resp.status} — ${source}` };
52
+ corpo = await resp.arrayBuffer();
53
+ } else {
54
+ corpo = readLocal(source);
55
+ }
56
+ const obtido = sha256(corpo);
57
+ if (!p.sha256 || obtido !== p.sha256) {
58
+ return { id: p.id, outcome: 'falhou', error: `sha256 mismatch at ${source}: expected ${p.sha256}, got ${obtido} — not written` };
59
+ }
60
+ mkdirSync(dirname(alvo), { recursive: true });
61
+ writeFileSync(alvo, Buffer.from(corpo));
62
+ return { id: p.id, outcome: 'escrito', bytes: corpo.byteLength };
63
+ } catch (e) {
64
+ return { id: p.id, outcome: 'falhou', error: e instanceof Error ? e.message : String(e) };
65
+ }
66
+ }
67
+
68
+ /**
69
+ * THE FONT LIBRARY'S FAMILIES A DELIVERY CARRIES (ADR-0255), from `--fonts`: each value a family or a comma-separated list of
70
+ * them; `all` is every family of the library, `none` nothing. A family the library does not hold STOPS the command (exit 2),
71
+ * naming it, instead of delivering nothing for it in silence.
72
+ */
73
+ export function fontFamiliesOfTheDelivery(asked, library) {
74
+ const names = asked.flatMap((v) => v.split(',')).map((f) => f.trim()).filter(Boolean);
75
+ if (names.includes('all')) return Object.keys(library.families);
76
+ const named = [...new Set(names.filter((f) => f !== 'none'))];
77
+ const unknown = named.filter((f) => !library.families[f]);
78
+ if (unknown.length) {
79
+ throw new Error(`--fonts ${unknown.join(', ')}: the engine's font library has no ${unknown.length > 1 ? 'such families' : 'such family'} `
80
+ + '(app/js/platform/font-library.json). Name families as the library writes them — «Press Start 2P» — or `--fonts all`');
81
+ }
82
+ return named;
83
+ }
84
+
85
+ /**
86
+ * PUTS THE DECLARED FAMILIES OF THE FONT LIBRARY INTO THE DELIVERY (ADR-0255): each face is fetched (or read from a local base),
87
+ * checked against the sha256 the ENGINE'S catalogue pins, and written at `heavy/<host>/fonts/<folder>/<file>` — where the page
88
+ * asks for it. Beside each family whose every face is there, its licence text and `NOTICE.txt`, written from the delivered fonts'
89
+ * own `name` tables (`licences/fonts.mjs`, the same writer as the library's folders). A face refused leaves its family without a
90
+ * notice and the run not `ok`.
91
+ */
92
+ export async function levarFontesParaEntrega({ destino, families, library, deliveryPath, fetch: buscar = fetch, sha256 = sha256DoNode,
93
+ base = '', fonteDe = (url) => url, lerLocal = (caminho) => readFileSync(caminho), licenceFiles = familyLicenceFiles }) {
94
+ const linhas = [];
95
+ for (const family of families) {
96
+ const entry = library.families[family];
97
+ let whole = true;
98
+ let folder = '';
99
+ // one file may serve two weights (a variable font declared at 400 and 700): each file once
100
+ const faces = entry.faces.filter((f, i) => entry.faces.findIndex((g) => g.file === f.file) === i);
101
+ for (const face of faces) {
102
+ const url = `${library.mirror}/${entry.folder}/${face.file}`;
103
+ const p = { id: `font:${entry.folder}:${face.file}`, sha256: face.sha256 };
104
+ const alvo = join(destino, deliveryPath(url));
105
+ folder = dirname(alvo);
106
+ const linha = existsSync(alvo) && sha256(readFileSync(alvo)) === face.sha256
107
+ ? { id: p.id, outcome: 'ja-tinha' }
108
+ : await trazerVerificado(p, alvo, { source: fonteDe(url, base), fetchFile: buscar, readLocal: lerLocal, sha256 });
109
+ linhas.push(linha);
110
+ if (linha.outcome === 'falhou') whole = false;
111
+ }
112
+ if (!whole) continue;
113
+ try {
114
+ const owed = licenceFiles(family, entry, (file) => readFileSync(join(folder, file)));
115
+ for (const [name, text] of Object.entries(owed)) writeFileSync(join(folder, name), text);
116
+ } catch (e) {
117
+ linhas.push({ id: `font:${entry.folder}:licence`, outcome: 'falhou', error: e instanceof Error ? e.message : String(e) });
118
+ }
119
+ }
120
+ return { ok: linhas.every((l) => l.outcome !== 'falhou'), linhas };
121
+ }
122
+
36
123
  /**
37
124
  * Fetches, checks and writes every entry with an address, then the licence files beside them. Returns one line per entry and
38
125
  * the licence folders written (`licences`); `ok` is false when any file — or the licences — failed.
39
126
  * Everything is injected so a gate can run it without the network.
40
127
  */
41
128
  export async function levarPesadosParaEntrega({ destino, pesados, deliveryPath, fetch: buscar = fetch, sha256 = sha256DoNode,
42
- base = '', fonteDe = (url) => url, lerLocal = (caminho) => readFileSync(caminho), thirdParty = THIRD_PARTY }) {
129
+ base = '', fonteDe = (url) => url, lerLocal = (caminho) => readFileSync(caminho), thirdParty = THIRD_PARTY, catalogue = [] }) {
43
130
  const linhas = [];
44
131
  const present = [];
45
132
  for (const p of pesados) {
@@ -54,29 +141,18 @@ export async function levarPesadosParaEntrega({ destino, pesados, deliveryPath,
54
141
  present.push({ id: p.id, path: deliveryPath(p.url) });
55
142
  continue;
56
143
  }
57
- const fonte = fonteDe(p.url, base);
58
- const daRede = /^https?:\/\//i.test(fonte);
59
- try {
60
- let corpo;
61
- if (daRede) {
62
- const resp = await buscar(fonte);
63
- if (!resp.ok) { linhas.push({ id: p.id, outcome: 'falhou', error: `HTTP ${resp.status} — ${fonte}` }); continue; }
64
- corpo = await resp.arrayBuffer();
65
- } else {
66
- corpo = lerLocal(fonte);
67
- }
68
- const obtido = sha256(corpo);
69
- if (!p.sha256 || obtido !== p.sha256) {
70
- linhas.push({ id: p.id, outcome: 'falhou', error: `sha256 mismatch at ${fonte}: expected ${p.sha256}, got ${obtido} — not written` });
71
- continue;
72
- }
73
- mkdirSync(dirname(alvo), { recursive: true });
74
- writeFileSync(alvo, Buffer.from(corpo));
75
- linhas.push({ id: p.id, outcome: 'escrito', bytes: corpo.byteLength });
76
- present.push({ id: p.id, path: deliveryPath(p.url) });
77
- } catch (e) {
78
- linhas.push({ id: p.id, outcome: 'falhou', error: e instanceof Error ? e.message : String(e) });
79
- }
144
+ const escrito = await trazerVerificado(p, alvo, { source: fonteDe(p.url, base), fetchFile: buscar, readLocal: lerLocal, sha256 });
145
+ linhas.push(escrito);
146
+ if (escrito.outcome === 'escrito') present.push({ id: p.id, path: deliveryPath(p.url) });
147
+ }
148
+ // 📌 THE NOTICES SPEAK FOR THE WHOLE DELIVERY, not for this run: a delivery may be built by several runs (`--reading pt`, then
149
+ // `--kokoro`), and `THIRD-PARTY-NOTICES.md` is rewritten each time. So every catalogue file ALREADY in the delivery with its
150
+ // pinned bytes keeps its notice; a file whose bytes are not the pinned ones gets none from here.
151
+ const listed = new Set(present.map((f) => f.id));
152
+ for (const p of catalogue) {
153
+ if (listed.has(p.id) || !p.url || !p.sha256 || !groupOf(p.id, thirdParty)) continue;
154
+ const alvo = join(destino, deliveryPath(p.url));
155
+ if (existsSync(alvo) && sha256(readFileSync(alvo)) === p.sha256) present.push({ id: p.id, path: deliveryPath(p.url) });
80
156
  }
81
157
  let licences = [];
82
158
  try {
@@ -92,24 +168,118 @@ export async function levarPesadosParaEntrega({ destino, pesados, deliveryPath,
92
168
  *
93
169
  * · `--kokoro` for a game that declares `uses: { neuralVoice: true }` — without it Kokoro's model, voices and runtime stay out of
94
170
  * the delivery, as they stay out of the start's download.
95
- * · `--reading <pt|en|es>`, repeatable, for a game that declares `uses: { reading: true }`: each language named puts ITS model in
96
- * the delivery (pt 378 MiB, en 162, es 310). A delivery for a school that reads in one language carries one.
171
+ * · `--reading`, for a game that declares `uses: { reading: true }`: ALONE (or `--reading all`) it carries every language the
172
+ * catalogue has a reading model for — pt 378 MiB, en 162, es 310 — because the start of such a game asks for the three, and a
173
+ * child tries the three at once (ADR-0225 erratum, the Dev: «Negativo, baixar os três.»). `--reading <pt|en|es>`, repeatable,
174
+ * NARROWS to the languages named, with the same bytes as before; a language left out is a quiet 404 at the device's start and,
175
+ * when she reads in it, a sentence to her and a line of `problems` naming this fix. `--reading none` carries none, as no flag
176
+ * does. A language the catalogue has no reading model for STOPS the command (exit 2) instead of carrying nothing.
97
177
  * · `--commands <pt|en|es>`, repeatable: the voice COMMANDS (issue #184), 31–39 MiB a language plus 3.1 MiB of runtime. No game
98
- * declares this one — saying «menu» is a way into the controller, not a feature (ADR-0111) — so it is the DELIVERY that says
99
- * which languages it serves. Without it a child who speaks is told the delivery carries no model for her language.
178
+ * declares this one — saying «menu» is a way into the controller, not a feature (ADR-0111). WITHOUT THE FLAG THE DELIVERY
179
+ * CARRIES EVERY LANGUAGE the catalogue has a command model for — pt, en and es, 108 MiB (ADR-0225 erratum, the Dev: «A entrega
180
+ * leva as três línguas.») — because the child can switch language mid-game and her model must already be there. The flag
181
+ * NARROWS: the languages named, and only those; `--commands none` carries no command model at all. A language left out is
182
+ * said to the child who speaks it, and named in `problems` with this fix. A language the catalogue has no command model for
183
+ * STOPS the command (exit 2) instead of carrying the runtime alone.
184
+ * · `--libras`: the Libras player deaf mode's interpreter signs with (ADR-0234, route B) — LAViD-UFPB's signs exported to one
185
+ * avatar and 655 clips, the whole manual alphabet among them, 32.7 MiB, into `libras/avatar/`, each checked against
186
+ * `scripts/libras-avatar.json` (`scripts/libras-avatar.mjs`), from the pins' `source` or from their `mirror` folder under
187
+ * `--base`. No game declares it: deaf mode is the person's, like speaking is, so the DELIVERY says whether it can sign. Without
188
+ * it the sonar in deaf mode says «signing unavailable». The same step GLOSSES the text a child can be shown
189
+ * (`scripts/libras-glosses.mjs`): the engine's Portuguese dictionary, always, and the game's own with `--libras-texts <file>`,
190
+ * repeatable (which implies `--libras`); a token the avatar carries no clip for is fingerspelled as written. It needs the
191
+ * glosser's environment, built once by `--libras-setup`; without it the delivery STOPS instead of shipping a player with nothing
192
+ * to sign but letters. Last, it writes `libras/offline-avatar.json`, the list of the avatar, clips, manifest, glosses and the
193
+ * build's three.js chunk with their sha256, by which a device with deaf mode on keeps the player for the days without a
194
+ * network — run after the build, which is what names the chunk.
195
+ * · `--libras-setup`: builds that environment (uv and Python 3.12), and does nothing else.
196
+ * · `--fonts <family,…|all|none>`, repeatable: the font LIBRARY's families the cartridges declare in `uses.fonts` (ADR-0255) —
197
+ * the engine packages only its own faces. Each face checked against the engine's catalogue (`platform/font-library.json`), each
198
+ * family with its licence and notice. Without the flag the delivery carries no library font, and a game that declares one is
199
+ * told so in `problems`. A family the library does not hold STOPS the command (exit 2).
100
200
  */
101
201
  export function argumentosDaEntrega(args, ambiente = process.env) {
102
202
  // ⚠️ `--base <value>` eats the token after it: without that, the value was read as the delivery folder (caught by its case).
103
203
  let destino, base;
104
204
  const reading = [];
105
205
  const commands = [];
206
+ const fonts = [];
207
+ let libras = false;
208
+ const librasTexts = [];
106
209
  for (let i = 0; i < args.length; i++) {
210
+ if (args[i] === '--libras') { libras = true; continue; }
211
+ if (args[i] === '--libras-texts') { const v = args[++i]; if (v) { librasTexts.push(v); libras = true; } continue; }
107
212
  if (args[i] === '--base') { base = args[++i]; continue; }
108
- if (args[i] === '--reading') { const v = args[++i]; if (v) reading.push(v); continue; }
213
+ // `--reading` alone — last, or before another flag — is every language; a value after it is a language, never the folder
214
+ if (args[i] === '--reading') {
215
+ const v = args[i + 1];
216
+ if (v === undefined || v.startsWith('--')) reading.push('all'); else { reading.push(v); i++; }
217
+ continue;
218
+ }
109
219
  if (args[i] === '--commands') { const v = args[++i]; if (v) commands.push(v); continue; }
220
+ if (args[i] === '--fonts') { const v = args[++i]; if (v) fonts.push(v); continue; }
110
221
  if (!args[i].startsWith('--') && destino === undefined) destino = args[i];
111
222
  }
112
- return { destino, kokoro: args.includes('--kokoro'), reading, commands, base: base ?? ambiente.INCLUSIONIST_HEAVY_BASE ?? '' };
223
+ return { destino, kokoro: args.includes('--kokoro'), reading, commands, libras, librasTexts, librasSetup: args.includes('--libras-setup'),
224
+ fonts, base: base ?? ambiente.INCLUSIONIST_HEAVY_BASE ?? '' };
225
+ }
226
+
227
+ /**
228
+ * THE SPOKEN LANGUAGES A DELIVERY CARRIES: those `--commands` named (less `none`, which names nothing), or — when the flag was
229
+ * not given — every language the catalogue has a command model for (ADR-0225 erratum). `languageOf` is the catalogue's
230
+ * `commandsLanguageOf`, so a fourth language with a model is carried by default the day it enters the catalogue. Named languages
231
+ * are base languages (`pt-BR` is `pt`).
232
+ * ⚠️ A NAMED LANGUAGE WITH NO MODEL THROWS, naming it, as `--reading` does: `--commands xx` used to carry the command runtime and
233
+ * no model at all, in silence.
234
+ */
235
+ export function commandLanguagesOfTheDelivery(asked, catalogue, languageOf) {
236
+ const known = [...new Set(catalogue.map((p) => languageOf(p.id)).filter(Boolean))];
237
+ if (!asked.length) return known;
238
+ const base = (tag) => tag.split('-')[0].toLowerCase();
239
+ const named = asked.filter((lingua) => lingua !== 'none');
240
+ const unknown = named.filter((lingua) => !known.includes(base(lingua)));
241
+ if (unknown.length) {
242
+ throw new Error(`--commands ${unknown.join(', ')}: the catalogue has no command model for ${unknown.length > 1 ? 'these languages' : 'this language'} `
243
+ + `— it has ${known.join(', ')}. Name one of them, \`--commands none\` for no command model, or leave the flag out for every language`);
244
+ }
245
+ return [...new Set(named.map(base))];
246
+ }
247
+
248
+ /**
249
+ * THE READING LANGUAGES A DELIVERY CARRIES: none without `--reading` (a game that does not listen carries no model); every
250
+ * language the catalogue has a reading model for with `--reading` alone or `all` (ADR-0225 erratum); else those named, as base
251
+ * languages (`pt-BR` is `pt`), less `none`. `languageOf` is the catalogue's `readingLanguageOf`, so a fourth language with a model
252
+ * is carried by `all` the day it enters the catalogue.
253
+ * ⚠️ A NAMED LANGUAGE WITH NO MODEL THROWS, naming it: it used to carry nothing in silence — and a folder written after the flag
254
+ * (`--reading dist`) was read as a language and carried nothing just as quietly.
255
+ */
256
+ export function readingLanguagesOfTheDelivery(asked, catalogue, languageOf) {
257
+ const known = [...new Set(catalogue.map((p) => languageOf(p.id)).filter(Boolean))];
258
+ const named = asked.filter((lingua) => lingua !== 'none' && lingua !== 'all');
259
+ const base = (tag) => tag.split('-')[0].toLowerCase();
260
+ const unknown = named.filter((lingua) => !known.includes(base(lingua)));
261
+ if (unknown.length) {
262
+ throw new Error(`--reading ${unknown.join(', ')}: the catalogue has no reading model for ${unknown.length > 1 ? 'these languages' : 'this language'} `
263
+ + `— it has ${known.join(', ')}. Name one of them, or pass \`--reading\` alone for every language (the delivery folder goes `
264
+ + 'before the flag: `inclusionist-heavy dist --reading`)');
265
+ }
266
+ if (asked.includes('all')) return known;
267
+ return [...new Set(named.map(base))];
268
+ }
269
+
270
+ /**
271
+ * THE IDS A DELIVERY CARRIES, from the command's answers: the reading languages go in one list and the spoken ones in another,
272
+ * as the start asks for them. `readingLanguageOf` is needed only when `reading` names something.
273
+ */
274
+ export function idsOfTheDelivery({ kokoro, reading, commands, libras }, { heavyAtBoot, catalogue, commandsLanguageOf, readingLanguageOf }) {
275
+ const spoken = commandLanguagesOfTheDelivery(commands, catalogue, commandsLanguageOf);
276
+ const read = reading.length ? readingLanguagesOfTheDelivery(reading, catalogue, readingLanguageOf) : [];
277
+ return [...new Set([
278
+ ...heavyAtBoot({ kokoro }),
279
+ ...(read.length ? heavyAtBoot({ kokoro: false, reading: read }) : []),
280
+ ...heavyAtBoot({ kokoro: false, commands: spoken }),
281
+ ...(libras ? heavyAtBoot({ kokoro: false, libras: true }) : []),
282
+ ])];
113
283
  }
114
284
 
115
285
  /** A `.env` beside the build, if there is one: Node reads it into `process.env`, and the command line still wins. */
@@ -121,24 +291,98 @@ export function carregarEnv(caminho = join(process.cwd(), '.env'), carregar = pr
121
291
  const executado = (() => { try { return realpathSync(process.argv[1] ?? '') === realpathSync(fileURLToPath(import.meta.url)); } catch { return false; } })();
122
292
  if (executado) {
123
293
  carregarEnv();
124
- const { destino, kokoro, reading, commands, base } = argumentosDaEntrega(process.argv.slice(2));
125
- if (!destino) { console.error('usage: inclusionist-heavy <delivery folder, e.g. dist> [--kokoro] [--reading pt|en|es]… [--commands pt|en|es]…'); process.exit(2); }
294
+ const { destino, kokoro, reading, commands, libras, librasTexts, librasSetup, fonts, base } = argumentosDaEntrega(process.argv.slice(2));
295
+ if (librasSetup) {
296
+ try { console.log(`the Libras glosser's environment is ready: ${setUpGlosser()}`); process.exit(0); }
297
+ catch (e) { console.error(e instanceof Error ? e.message : String(e)); process.exit(1); }
298
+ }
299
+ if (!destino) {
300
+ console.error('usage: inclusionist-heavy <delivery folder, e.g. dist> [--kokoro] [--reading [all|pt|en|es|none]]… '
301
+ + '[--commands pt|en|es|none]… [--fonts <family,…|all|none>]… [--libras] [--libras-texts <file>]… | --libras-setup');
302
+ if (reading.some((v) => v !== 'all')) console.error(`(the value after --reading is read as a language: «${reading.join(' ')}» — put the folder first)`);
303
+ process.exit(2);
304
+ }
126
305
  const modulo = moduloDoPacote();
127
306
  if (!existsSync(fileURLToPath(modulo))) { console.error('dist-pkg/platform/heavy.js is missing beside this script: in the engine repository, run `npm run build:pkg` first'); process.exit(2); }
128
307
  const { HEAVY_FILES, deliveryPath, heavyAtBoot } = await import(modulo);
129
308
  const { heavySourceOf } = await import(new URL('../dist-pkg/platform/heavy-mirror.js', import.meta.url).href);
130
- // one pass per language, because the start asks for ONE and the delivery may hold several
131
- const ids = [...new Set([
132
- ...heavyAtBoot({ kokoro }),
133
- ...reading.flatMap((lingua) => heavyAtBoot({ kokoro: false, reading: lingua })),
134
- ...commands.flatMap((lingua) => heavyAtBoot({ kokoro: false, commands: lingua })),
135
- ])];
309
+ const { LIBRAS_AVATAR_FOLDER, LIBRAS_AVATAR_STAGE_CHUNK, DELIVERY_LISTS, commandsLanguageOf, readingLanguageOf } = await import(new URL('../dist-pkg/platform/heavy-catalogue.js', import.meta.url).href);
310
+ // 📌 THE LANGUAGES FIRST, reading and command, before a byte is downloaded: a language the catalogue has no model for stops
311
+ // here, named
312
+ let read, spoken, typefaces;
313
+ // the ENGINE's font catalogue, from the package beside this script — the sha256 every delivered face must have (ADR-0255)
314
+ const library = JSON.parse(readFileSync(new URL('../dist-pkg/platform/font-library.json', import.meta.url), 'utf8'));
315
+ try {
316
+ read = readingLanguagesOfTheDelivery(reading, HEAVY_FILES, readingLanguageOf);
317
+ spoken = commandLanguagesOfTheDelivery(commands, HEAVY_FILES, commandsLanguageOf);
318
+ typefaces = fontFamiliesOfTheDelivery(fonts, library);
319
+ } catch (e) {
320
+ console.error(e instanceof Error ? e.message : String(e));
321
+ process.exit(2);
322
+ }
323
+ let librasGlosses = '';
324
+ let stageChunk = '';
325
+ if (libras) {
326
+ const { LIBRAS_GLOSSES_FILE } = await import(new URL('../dist-pkg/ui/libras-glosses.js', import.meta.url).href);
327
+ const { default: enginePt } = await import(new URL('../dist-pkg/i18n/pt.js', import.meta.url).href);
328
+ try {
329
+ // 📌 THE STAGE CHUNK AND THE GLOSSES FIRST, before a byte is downloaded: a build that never emitted the player, or a build
330
+ // machine with no glosser, learns it in a second, not after 32 MiB
331
+ stageChunk = stageChunkOf(destino, LIBRAS_AVATAR_STAGE_CHUNK);
332
+ const games = await Promise.all(librasTexts.map((file) => readTexts(file)));
333
+ const made = await deliverLibrasGlosses({
334
+ destino, folder: LIBRAS_AVATAR_FOLDER, glossesFile: LIBRAS_GLOSSES_FILE, dictionaries: [enginePt, ...games],
335
+ translate: (inputs) => runGlosser(inputs),
336
+ });
337
+ console.log(`glosses ${made.path} — ${made.texts} texts (the engine's${games.length ? ` and ${games.length} of the game's` : ''}), `
338
+ + `${made.tokens} sign names`);
339
+ console.log(`signs ${made.signed.length} signed by the avatar's clips; ${made.fingerspelled.length} with no clip are fingerspelled `
340
+ + '(scripts/libras-avatar.json)');
341
+ const { spelled } = made;
342
+ console.log(`spelled ${spelled.tokens} tokens: ${spelled.asWritten} as written on the screen (${spelled.ambiguous} of them `
343
+ + `chosen by sentence order among several spellings, ${spelled.byStem} by the word's start), ${spelled.asTranslated} `
344
+ + 'as the translator wrote them (no written word gives them)');
345
+ librasGlosses = made.path;
346
+ } catch (e) {
347
+ console.error(e instanceof Error ? e.message : String(e));
348
+ console.error('the Libras glosses were not made: a delivery built with --libras is not written without them');
349
+ process.exit(1);
350
+ }
351
+ }
352
+ const ids = idsOfTheDelivery({ kokoro, reading, commands, libras },
353
+ { heavyAtBoot, catalogue: HEAVY_FILES, commandsLanguageOf, readingLanguageOf });
354
+ console.log(`commands ${spoken.length ? spoken.join(', ') : 'none'}${commands.length ? '' : ' (every language, the default)'}`);
355
+ console.log(`reading ${read.length ? read.join(', ') : 'none'}${reading.includes('all') ? ' (every language)' : ''}`);
136
356
  if (base) console.log(`base: ${base}`);
137
357
  const { ok, linhas, licences } = await levarPesadosParaEntrega({
138
- destino, pesados: HEAVY_FILES.filter((p) => ids.includes(p.id)), deliveryPath, base, fonteDe: heavySourceOf,
358
+ destino, pesados: HEAVY_FILES.filter((p) => ids.includes(p.id)), deliveryPath, base, fonteDe: heavySourceOf, catalogue: HEAVY_FILES,
139
359
  });
140
- for (const l of linhas) console.log(`${l.outcome.padEnd(9)} ${l.id}${l.error ? ` — ${l.error}` : ''}`);
360
+ for (const l of linhas) console.log(`${l.outcome.padEnd(9)} ${l.id}${(l.error ?? l.note) ? ` — ${l.error ?? l.note}` : ''}`);
141
361
  for (const l of licences) console.log(`licence ${l.key} — ${l.folders.length} folder(s)`);
142
362
  if (licences.length) console.log('notices heavy/THIRD-PARTY-NOTICES.md');
143
363
  if (!ok) { console.error('a heavy file failed: the delivery is incomplete, and nothing unchecked was written'); process.exit(1); }
364
+ if (typefaces.length) {
365
+ const made = await levarFontesParaEntrega({ destino, families: typefaces, library, deliveryPath, base, fonteDe: heavySourceOf });
366
+ const written = made.linhas.filter((l) => l.outcome === 'escrito');
367
+ for (const l of made.linhas.filter((x) => x.outcome === 'falhou')) console.log(`falhou ${l.id} — ${l.error}`);
368
+ console.log(`fonts ${typefaces.length} families of the library — ${written.length} faces written, `
369
+ + `${made.linhas.filter((l) => l.outcome === 'ja-tinha').length} already there, each checked by sha256`
370
+ + `${made.ok ? ', each family with its licence and NOTICE.txt' : ''}`);
371
+ if (!made.ok) { console.error('a library font failed: its family is not delivered whole, and nothing unchecked was written'); process.exit(1); }
372
+ }
373
+ if (libras) {
374
+ try {
375
+ const pins = readAvatarPins();
376
+ const { files, bytes } = await deliverLibrasAvatar({ destino, folder: LIBRAS_AVATAR_FOLDER, pins, base });
377
+ console.log(`avatar ${LIBRAS_AVATAR_FOLDER} — ${files} files, ${(bytes / 1048576).toFixed(1)} MiB (ADR-0234)`);
378
+ // LAST, so it names what is really on the disk: the list a device keeps the player offline by (pillar 8)
379
+ const list = DELIVERY_LISTS.find((l) => l.id === 'libras:avatar:delivery');
380
+ const listed = writeAvatarList({ destino, list, folder: LIBRAS_AVATAR_FOLDER, pins, stageChunk, glosses: librasGlosses });
381
+ console.log(`offline ${listed.path} — ${listed.files} files (${stageChunk} among them), ${listed.bytes} bytes, each with its sha256`);
382
+ } catch (e) {
383
+ console.error(e instanceof Error ? e.message : String(e));
384
+ console.error('the Libras player was not delivered: this delivery cannot sign');
385
+ process.exit(1);
386
+ }
387
+ }
144
388
  }