@mavea/mavea 1.2.1 → 2.0.1

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 (393) hide show
  1. package/CHANGELOG.md +107 -0
  2. package/PRIVACY.md +1 -0
  3. package/README.md +14 -6
  4. package/TERMS.md +1 -1
  5. package/THIRD-PARTY.txt +13 -5
  6. package/bin/mavea.mjs +181 -8
  7. package/dist/.vite/manifest.json +1459 -847
  8. package/dist/assets/AnnotationLayer-BsAcAd59.js +0 -0
  9. package/dist/assets/{AppCommandPalette-CgDUWU08.js → AppCommandPalette-Cucwjk5N.js} +1 -1
  10. package/dist/assets/AtlasView-B7yObdf8.css +1 -0
  11. package/dist/assets/{AtlasView-B82UfrEX.js → AtlasView-DO_p0TdZ.js} +1 -1
  12. package/dist/assets/BriefingPlayer-DHV4vMga.css +1 -0
  13. package/dist/assets/{CadenceCard-P4teI7Se.js → CadenceCard-DxceyiPA.js} +1 -1
  14. package/dist/assets/{CanvasSkeleton-CRGWlafo.js → CanvasSkeleton-BmGjJHUQ.js} +1 -1
  15. package/dist/assets/CanvasSkeleton-DYASkTjW.css +1 -0
  16. package/dist/assets/CardEditor-CiAfT78z.css +1 -0
  17. package/dist/assets/{CardEditor-DABIhGdQ.js → CardEditor-D4slxmIM.js} +1 -1
  18. package/dist/assets/{CheckLogRail-DO7sbZwC.js → CheckLogRail-vq2lZ7a5.js} +1 -1
  19. package/dist/assets/ConversationVideoStudio-CSO3jHXD.css +1 -0
  20. package/dist/assets/ConversationVideoStudio-Df892wqs.js +1 -0
  21. package/dist/assets/CourseLessonReader-DKQimh2S.js +2 -0
  22. package/dist/assets/{CourseRail-DXt3bzjU.js → CourseRail-BQmUsG6v.js} +1 -1
  23. package/dist/assets/CoursesApp-LeqL6dWT.js +2 -0
  24. package/dist/assets/CrossExamPanel-BafTqkbf.css +1 -0
  25. package/dist/assets/{DashPresent-B6MP1i_4.js → DashPresent-DZcRdu6R.js} +1 -1
  26. package/dist/assets/DashboardDetail-2XL-J4rS.js +2 -0
  27. package/dist/assets/DashboardLoopGate-B95S4oKR.js +2 -0
  28. package/dist/assets/DashboardLoopRuntime-Wzk85QXi.js +1 -0
  29. package/dist/assets/{DashboardSettings-CE0B2y2y.js → DashboardSettings-DJon1Q4o.js} +1 -1
  30. package/dist/assets/DashboardsApp-ZGuT2QBi.js +2 -0
  31. package/dist/assets/{DeepZoomApp-UEPtylG7.js → DeepZoomApp-CPOsar8c.js} +1 -1
  32. package/dist/assets/DeepZoomApp-CVwmnRGN.css +1 -0
  33. package/dist/assets/DelegatePanel-BkTtUMSl.js +33 -0
  34. package/dist/assets/DelegatePanel-D17XvWYd.css +1 -0
  35. package/dist/assets/DemoGallery-BcQ9yz2u.js +1 -0
  36. package/dist/assets/{DropSelect-DilESAgA.css → DropSelect-B4lqCEjw.css} +1 -1
  37. package/dist/assets/{DropSelect-QcBm3N4D.js → DropSelect-GKioj__f.js} +1 -1
  38. package/dist/assets/{ExportModal-Ya0VBbxa.js → ExportModal-1pWr-c7I.js} +1 -1
  39. package/dist/assets/{ExtractionPreview-BFrmqKDo.js → ExtractionPreview-TKyfEqwM.js} +1 -1
  40. package/dist/assets/{FeatureUseNotice-Dc3GNBvy.js → FeatureUseNotice-pQe4YHgJ.js} +1 -1
  41. package/dist/assets/{FlagshipCommandPalette-B1yHwI6V.js → FlagshipCommandPalette-D1pv3hfZ.js} +1 -1
  42. package/dist/assets/FlagshipShowcase-CCFFcaL7.js +1 -0
  43. package/dist/assets/{FlashcardsApp-DteNeHpz.js → FlashcardsApp-Dbe-8UkQ.js} +1 -1
  44. package/dist/assets/ForecastPanel-Cq_yDhNQ.css +1 -0
  45. package/dist/assets/GalleryApp-CCLYcEqn.js +1 -0
  46. package/dist/assets/{HonestByDesign-DZltb3Ss.js → HonestByDesign-ByOR1sRQ.js} +1 -1
  47. package/dist/assets/{HowItWorks-D-hgfN6a.js → HowItWorks-Dllc30ph.js} +1 -1
  48. package/dist/assets/{LegalApp-ChzcKiY0.js → LegalApp-CpblxmmB.js} +1 -1
  49. package/dist/assets/{LegalMarkdownDocument-j6UHhPnp.js → LegalMarkdownDocument-CmxHsXlb.js} +1 -1
  50. package/dist/assets/{LegalPageShell-Wcsviye1.js → LegalPageShell-CDD6D6T_.js} +1 -1
  51. package/dist/assets/LeverPanel-HOEwIr8k.css +1 -0
  52. package/dist/assets/{Library-DmdzY2se.js → Library-CVj7R6F4.js} +1 -1
  53. package/dist/assets/LibraryOverlay-BkPYm0Bs.css +1 -0
  54. package/dist/assets/{LibraryOverlay-YHBrdVKo.js → LibraryOverlay-CHmubwG3.js} +1 -1
  55. package/dist/assets/LiveApp-CSbjhgzM.js +79 -0
  56. package/dist/assets/LiveApp-CziqEsOb.css +1 -0
  57. package/dist/assets/LiveSettings-B4T6x41n.js +6 -0
  58. package/dist/assets/LiveSettings-Dho0OxlM.css +1 -0
  59. package/dist/assets/{MindMapViewerDrawer-DI_S7fRZ.js → MindMapViewerDrawer-BLRBWsTz.js} +1 -1
  60. package/dist/assets/MindShape-CaDuLyGa.js +1 -0
  61. package/dist/assets/MindShape-CozR9W8M.css +1 -0
  62. package/dist/assets/{PinToDashboard-BCiWaSg8.js → PinToDashboard-ChK2Ou73.js} +1 -1
  63. package/dist/assets/{PlanReview-BIERfK1t.js → PlanReview-Dg6VE0xF.js} +1 -1
  64. package/dist/assets/PresentationDeck-oEd6TXdN.js +1 -0
  65. package/dist/assets/PrismApp-Bju264hL.js +2 -0
  66. package/dist/assets/PrismAskController-68gbUO5u.css +1 -0
  67. package/dist/assets/{PrismAskController-Bt0k9hAA.js → PrismAskController-C4MuB8om.js} +1 -1
  68. package/dist/assets/{PrismBriefingPlayer-DLAPs6eZ.js → PrismBriefingPlayer-BY0RREUu.js} +2 -2
  69. package/dist/assets/PrismOverlay-BwnF4BEn.css +1 -0
  70. package/dist/assets/{PrismOverlay-DJDGPGxo.js → PrismOverlay-DOWyOUVW.js} +4 -4
  71. package/dist/assets/{PrismWorkbench-DHLvpguj.js → PrismWorkbench-9RonO2uv.js} +1 -1
  72. package/dist/assets/{PrivacyApp-uMjq2z14.js → PrivacyApp-CBPMqUEA.js} +2 -1
  73. package/dist/assets/{Recap-T9DtFaEk.js → Recap-BOl3SUh0.js} +1 -1
  74. package/dist/assets/Recap-D3NlzM1p.css +1 -0
  75. package/dist/assets/{ReplayCard-F7U3LYAg.js → ReplayCard-BnX73r9n.js} +2 -2
  76. package/dist/assets/{ReplayOverlay-BTldvkU7.js → ReplayOverlay-B-Ok0mEs.js} +1 -1
  77. package/dist/assets/{RewindOverlay-CousnxXo.js → RewindOverlay-BO7YgDsW.js} +1 -1
  78. package/dist/assets/RippleApp-BnIUhIA0.js +2 -0
  79. package/dist/assets/{RippleAskController-9SxpZnHX.js → RippleAskController-BzdwYcYY.js} +1 -1
  80. package/dist/assets/RippleOverlay-B3hg2KMN.css +1 -0
  81. package/dist/assets/RippleOverlay-C9W7uVOp.js +6 -0
  82. package/dist/assets/SeeDontRead-ByW9HnOj.js +1 -0
  83. package/dist/assets/ShareModal-I_sxHKLv.css +1 -0
  84. package/dist/assets/ShareModal-Mo-dkgAZ.js +2 -0
  85. package/dist/assets/{ShipCourse-Up9gRR07.js → ShipCourse-CT_F9oJH.js} +1 -1
  86. package/dist/assets/{SignatureLoop-Cq790dMw.js → SignatureLoop-DejFTZ-Y.js} +1 -1
  87. package/dist/assets/SrsReview-DmBcJCMa.css +1 -0
  88. package/dist/assets/{SrsReview-DhWNYYv7.js → SrsReview-Gr6Y0QTQ.js} +1 -1
  89. package/dist/assets/{SynthesisApp-4ZPLZgmJ.js → SynthesisApp-6W04mrMU.js} +2 -2
  90. package/dist/assets/{SynthesisOverlay-iesJ0hEt.js → SynthesisOverlay-DDyFFiO8.js} +1 -1
  91. package/dist/assets/{TermsApp-DL2hFKsv.js → TermsApp-ZzlhrXhd.js} +2 -2
  92. package/dist/assets/TopicCanvas-CkqP92SC.js +2 -0
  93. package/dist/assets/TopicCanvas-DWTm611H.css +1 -0
  94. package/dist/assets/{TourPrism-kInUOv-M.js → TourPrism-Cng4h9Ly.js} +1 -1
  95. package/dist/assets/{TrackerTile-BryDo0sm.js → TrackerTile-DuUsFQTj.js} +2 -2
  96. package/dist/assets/{TwoSurfaces-Cmj95ofx.js → TwoSurfaces-BeYMvVuX.js} +1 -1
  97. package/dist/assets/WhyMachineOverlay-Rav-cuMm.css +1 -0
  98. package/dist/assets/WorldOverlay-DeVpS8HE.js +2 -0
  99. package/dist/assets/{WowFeatures-DDICbxl_.js → WowFeatures-D58JgpLg.js} +1 -1
  100. package/dist/assets/{ZoomDeck-CKOjYS9z.js → ZoomDeck-CPG2XQhr.js} +1 -1
  101. package/dist/assets/ZoomDeck-DdLNsrHV.css +1 -0
  102. package/dist/assets/{annotationAuto-CDv6Es44.js → annotationAuto-B2UdfJNj.js} +1 -1
  103. package/dist/assets/{backup-ZrlVatXc.js → backup-CtEvuZoL.js} +1 -1
  104. package/dist/assets/canvas-Ct-O9Jok.js +1 -0
  105. package/dist/assets/capture-CgaD86-q.js +2 -0
  106. package/dist/assets/{catalog-Db9GWM6N.js → catalog-DfIYAG3v.js} +1 -1
  107. package/dist/assets/{chapters-Dqm4iLDa.js → chapters-CIvdCeBC.js} +1 -1
  108. package/dist/assets/{confirmAdd-DkmbWaSk.js → confirmAdd-CxWIORcu.js} +1 -1
  109. package/dist/assets/{dashboardEvents-D-XVj666.js → dashboardEvents-D1OP4ARB.js} +1 -1
  110. package/dist/assets/dashboards-Cvs28p3Z.css +1 -0
  111. package/dist/assets/deepen-BhP9OmH3.js +11 -0
  112. package/dist/assets/deepenStore-BWLLzLCY.js +1 -0
  113. package/dist/assets/effort-Bqti44UZ.js +39 -0
  114. package/dist/assets/{explode-BgZIWY9m.js → explode-CPnvJiTg.js} +1 -1
  115. package/dist/assets/{fitText-DQ2omSN0.js → fitText-DHbmSS-q.js} +1 -1
  116. package/dist/assets/{generate-Dl2EJ_SR.js → generate-COfYQFmT.js} +4 -4
  117. package/dist/assets/{generateBeats-DtptFLlG.js → generateBeats-CtffeoEa.js} +1 -1
  118. package/dist/assets/{generateCourse-C9qvaJRo.js → generateCourse-BldPpgdh.js} +1 -1
  119. package/dist/assets/generateLive-D5M8v38b.js +24 -0
  120. package/dist/assets/homeTarget-CwFsJYwb.js +1 -0
  121. package/dist/assets/index-BIUYTk1W.css +1 -0
  122. package/dist/assets/index-CdUH6Eo9.js +22 -0
  123. package/dist/assets/kokoro-D15HDMcP.js +1 -0
  124. package/dist/assets/ledger-BssK9Pv2.js +1 -0
  125. package/dist/assets/{lib-DMAxsZKm.css → lib-DP9Kuxqk.css} +1 -1
  126. package/dist/assets/{liveSchema-B4bQtO88.js → liveSchema-B8Y9HZxd.js} +2 -2
  127. package/dist/assets/{loader-DCA6Njbf.js → loader-ChcXMM9W.js} +2 -2
  128. package/dist/assets/localBudget-CxLP6bjE.js +1 -0
  129. package/dist/assets/{mastery-CUfDeuqO.js → mastery-DB5qpRAy.js} +1 -1
  130. package/dist/assets/{media-BvwzACIX.js → media-VLRh6CX2.js} +2 -2
  131. package/dist/assets/{model-BFRTN9Eh.js → model-CAewjw45.js} +1 -1
  132. package/dist/assets/{neighborhoods-D7QjURnE.js → neighborhoods-CqECCmo8.js} +1 -1
  133. package/dist/assets/{notes-B6eX5XWk.js → notes-BG5pIVAJ.js} +1 -1
  134. package/dist/assets/pen-DtEW1xf4.js +24 -0
  135. package/dist/assets/{perfProbe-CE7hsUEo.js → perfProbe-DaLsQQBb.js} +1 -1
  136. package/dist/assets/pin-BXyyKnci.css +1 -0
  137. package/dist/assets/{pin-BZuh1acO.js → pin-BcKMUOiV.js} +1 -1
  138. package/dist/assets/{planTracker-KKAtTBWs.js → planTracker-BwoKEftp.js} +1 -1
  139. package/dist/assets/portal-BIN_aqvw.js +1 -0
  140. package/dist/assets/{prewarm-uKxmzjjd.js → prewarm-CyvSJKv4.js} +1 -1
  141. package/dist/assets/providers-0DthJW_I.js +1 -0
  142. package/dist/assets/quietHours-D1nboK5q.js +1 -0
  143. package/dist/assets/{ready-jtAUOb62.js → ready-yBSGJubb.js} +1 -1
  144. package/dist/assets/{registry-BFrgx1tE.js → registry-B53EEn8S.js} +1 -1
  145. package/dist/assets/{registry-CPiwQhAm.js → registry-BDXwUn3i.js} +1 -1
  146. package/dist/assets/{registry-Dwbh-GWu.js → registry-BFQQpjO2.js} +1 -1
  147. package/dist/assets/{registry-B0GIHERt.js → registry-BQzvA61G.js} +1 -1
  148. package/dist/assets/{registry-D8O0apUT.js → registry-BdHj_oIs.js} +1 -1
  149. package/dist/assets/{registry-Dru0JcTa.css → registry-BgWzEkxc.css} +1 -1
  150. package/dist/assets/{registry-Vp8VuMV0.js → registry-Bl2qfp5V.js} +1 -1
  151. package/dist/assets/{registry-1wlTAh5b.js → registry-C8FuGbOr.js} +1 -1
  152. package/dist/assets/{registry-C28gYnVq.js → registry-CE1T0z9x.js} +1 -1
  153. package/dist/assets/{registry-ZOWzhOHk.css → registry-CGB0jkFI.css} +1 -1
  154. package/dist/assets/{registry-4mMEt1Xy.css → registry-CIcGBgtK.css} +1 -1
  155. package/dist/assets/{registry-DtV2UjBx.js → registry-CcHxIYQN.js} +1 -1
  156. package/dist/assets/{registry-BFbfXK-W.js → registry-Cgo4C0ux.js} +1 -1
  157. package/dist/assets/registry-CwRTUk0R.js +1 -0
  158. package/dist/assets/{registry-6DGRAB1m.js → registry-DPBJYRmC.js} +1 -1
  159. package/dist/assets/registry-Dbe9TQPw.css +1 -0
  160. package/dist/assets/registry-DdVZGvkL.js +48 -0
  161. package/dist/assets/{registry-B2QzCuWH.js → registry-DdgeK4fY.js} +1 -1
  162. package/dist/assets/registry-Diyud3DF.js +1 -0
  163. package/dist/assets/registry-DjvftnY2.css +1 -0
  164. package/dist/assets/registry-Dt0wu9rC.js +2 -0
  165. package/dist/assets/registry-QbArAJKB.js +1 -0
  166. package/dist/assets/registry-dmR14XnY.css +1 -0
  167. package/dist/assets/registry-g2sBcIrf.css +1 -0
  168. package/dist/assets/{registry-CcOO8UZr.js → registry-qRfnKTt4.js} +1 -1
  169. package/dist/assets/{relate-UW-sUlJH.js → relate-CqYpFpsO.js} +1 -1
  170. package/dist/assets/{replay-B5TkHPri.js → replay-NognvQfM.js} +1 -1
  171. package/dist/assets/route-CMdTFx0P.js +1 -0
  172. package/dist/assets/{run-Df10YPyB.js → run-CuHaB8wF.js} +1 -1
  173. package/dist/assets/{run-gmqUaxcL.js → run-CwMSPOps.js} +1 -1
  174. package/dist/assets/{run-DlvA3l28.js → run-DCQrxgHA.js} +1 -1
  175. package/dist/assets/select-Dp-OeZfq.js +3 -0
  176. package/dist/assets/shapes-BwoDrn09.js +1 -0
  177. package/dist/assets/shard000-Bx6Nmt0m.js +1 -0
  178. package/dist/assets/shard001-CL6O9SLr.js +1 -0
  179. package/dist/assets/shard002-vLQ0Ss-O.js +1 -0
  180. package/dist/assets/shard003-kKZdpzuh.js +1 -0
  181. package/dist/assets/shard004-CdVohAu1.js +1 -0
  182. package/dist/assets/shard005-CMzF_uJB.js +1 -0
  183. package/dist/assets/shard006-DQoDWuoN.js +1 -0
  184. package/dist/assets/shard007-Ck0N0IUk.js +1 -0
  185. package/dist/assets/shard008-Dt395x0Q.js +1 -0
  186. package/dist/assets/shard009-D_z8Lhqh.js +1 -0
  187. package/dist/assets/shard010-CQfR6lnk.js +1 -0
  188. package/dist/assets/shard011-l-w2t2Ie.js +1 -0
  189. package/dist/assets/shard012-BTw_UO1C.js +1 -0
  190. package/dist/assets/shard013-D8ZjKKYb.js +1 -0
  191. package/dist/assets/shard014-Cth_76It.js +1 -0
  192. package/dist/assets/shard015-DdYJVsHx.js +1 -0
  193. package/dist/assets/shard016-BdlBf9uZ.js +1 -0
  194. package/dist/assets/shard017-C3HTxh6t.js +1 -0
  195. package/dist/assets/shard018-Mf4wvqVk.js +1 -0
  196. package/dist/assets/shard019-Dpcy1Arx.js +1 -0
  197. package/dist/assets/shard020-BNvKfQld.js +1 -0
  198. package/dist/assets/shard021-D0kpI_PQ.js +1 -0
  199. package/dist/assets/shard022-Cjms7kAe.js +1 -0
  200. package/dist/assets/shard023-Bdwci7fy.js +1 -0
  201. package/dist/assets/shard024-BBoyPtpP.js +1 -0
  202. package/dist/assets/shard025-lMGpgN_0.js +3 -0
  203. package/dist/assets/shard026-Bp3UVI4_.js +1 -0
  204. package/dist/assets/shard027-C4HTpdeT.js +1 -0
  205. package/dist/assets/shard028-BsFTH3Sf.js +1 -0
  206. package/dist/assets/shard029-B3dEcXPy.js +1 -0
  207. package/dist/assets/shard030-DWwA-fNs.js +5 -0
  208. package/dist/assets/shard031-RhqA_0nH.js +1 -0
  209. package/dist/assets/shard032-BlZdG1Yi.js +1 -0
  210. package/dist/assets/shard033-Dmx2lOjI.js +1 -0
  211. package/dist/assets/shard034-BLOFKJT4.js +1 -0
  212. package/dist/assets/shard035-DMXdH733.js +1 -0
  213. package/dist/assets/shard036-DzOiEn23.js +1 -0
  214. package/dist/assets/shard037-BcHfVaYM.js +1 -0
  215. package/dist/assets/shard038-KozOx-Jh.js +1 -0
  216. package/dist/assets/shard039-apdILQwC.js +1 -0
  217. package/dist/assets/shard040-BrNXGaBi.js +1 -0
  218. package/dist/assets/shard041-D6eq9h1u.js +4 -0
  219. package/dist/assets/shard042-M-L34DbY.js +1 -0
  220. package/dist/assets/shard043-Ct6_C2pN.js +1 -0
  221. package/dist/assets/shard044-Bo0iaVHx.js +1 -0
  222. package/dist/assets/shard045-9ccZ4Y_N.js +1 -0
  223. package/dist/assets/shard046-eXoP478L.js +1 -0
  224. package/dist/assets/shard047-N56r6Lsz.js +1 -0
  225. package/dist/assets/shard048-BeKX7cI8.js +1 -0
  226. package/dist/assets/shard049-hPaNN2sL.js +1 -0
  227. package/dist/assets/shard050-B-YpP0B6.js +1 -0
  228. package/dist/assets/shard051-Bww5_KB2.js +1 -0
  229. package/dist/assets/shard052-DErwF8Df.js +1 -0
  230. package/dist/assets/shard053-C-qGH4jz.js +1 -0
  231. package/dist/assets/shard054-CNzJxw2V.js +1 -0
  232. package/dist/assets/shard054-kcSxZrSj.js +1 -0
  233. package/dist/assets/shard055-CsETBTqa.js +1 -0
  234. package/dist/assets/shard056-CdBR4qTC.js +1 -0
  235. package/dist/assets/shard057-yRUG8B9e.js +1 -0
  236. package/dist/assets/shard058-DeDAnECG.js +1 -0
  237. package/dist/assets/shard059-Dh6jbDnW.js +1 -0
  238. package/dist/assets/shard060-B5kpWrhW.js +1 -0
  239. package/dist/assets/shard061-BTnj5LZA.js +1 -0
  240. package/dist/assets/shard062-DC7LTaNc.js +1 -0
  241. package/dist/assets/shard063-C8SIGCfd.js +1 -0
  242. package/dist/assets/shard064-DLyASocW.js +1 -0
  243. package/dist/assets/shard065-Cy_yV4ry.js +1 -0
  244. package/dist/assets/shard066-BmjVQqFX.js +1 -0
  245. package/dist/assets/shard067-uZUJsqtF.js +1 -0
  246. package/dist/assets/shard068-CXVjyJU4.js +1 -0
  247. package/dist/assets/shard069-CyfmjAm-.js +4 -0
  248. package/dist/assets/shard070-CxN3xiuY.js +12 -0
  249. package/dist/assets/shard071-CP1WrYC-.js +1 -0
  250. package/dist/assets/shard072-D6L5Yr05.js +1 -0
  251. package/dist/assets/shard073-DFEzkwg2.js +1 -0
  252. package/dist/assets/shard074-BSv3rvRL.js +1 -0
  253. package/dist/assets/shard075-Bt0OjGVd.js +1 -0
  254. package/dist/assets/shard076-DZHs0uzd.js +1 -0
  255. package/dist/assets/{share-kW3pZ027.js → share--tpc1nLE.js} +1 -1
  256. package/dist/assets/speed-BOytg6bC.js +1 -0
  257. package/dist/assets/store-B2Rpbqgg.js +1 -0
  258. package/dist/assets/store-Ba9vzL4H.js +1 -0
  259. package/dist/assets/store-BwyOArJl.js +1 -0
  260. package/dist/assets/store-ruEsXJjU.js +1 -0
  261. package/dist/assets/streamParse-BX0bAppQ.js +2 -0
  262. package/dist/assets/{templates-DHeyJ32F.css → templates-BIkAr4YH.css} +1 -1
  263. package/dist/assets/{theme-7IrMJ70_.js → theme-D5D55hZi.js} +1 -1
  264. package/dist/assets/{threads-Cu2t3070.js → threads-DNfxMTwx.js} +1 -1
  265. package/dist/assets/{useDashboardLoop-BoVNM-pT.js → useDashboardLoop-C3iCNS8X.js} +3 -3
  266. package/dist/assets/{useDashboards-SRk8LqHe.js → useDashboards-lgQnk2Al.js} +1 -1
  267. package/dist/assets/useFocusTrap-CJmpNZv2.js +1 -0
  268. package/dist/assets/useInView-DsTvv7L_.js +1 -0
  269. package/dist/assets/useInterval-DDgFrel2.js +1 -0
  270. package/dist/assets/{useLiveConfig-Cpy0_E_-.js → useLiveConfig-B4CmBiAK.js} +1 -1
  271. package/dist/assets/useStudy-CwCIyiTb.js +1 -0
  272. package/dist/assets/{walkSync-CT8kmbzY.js → walkSync-DC9iE0BX.js} +1 -1
  273. package/dist/demo-assets/CREDITS.md +94 -50
  274. package/dist/demo-assets/images/arnel-lighthouse.avif +0 -0
  275. package/dist/demo-assets/images/cliff-fields.avif +0 -0
  276. package/dist/demo-assets/images/crater-panorama.avif +0 -0
  277. package/dist/demo-assets/images/furnas-lake.avif +0 -0
  278. package/dist/demo-assets/images/green-coast-raw.avif +0 -0
  279. package/dist/demo-assets/images/green-coast.avif +0 -0
  280. package/dist/demo-assets/images/island-coast-poster.avif +0 -0
  281. package/dist/demo-assets/images/nordeste-town.avif +0 -0
  282. package/dist/demo-assets/images/sea-cliffs.avif +0 -0
  283. package/dist/demo-assets/images/sete-cidades.avif +0 -0
  284. package/dist/demo-assets/images/tea-terraces.avif +0 -0
  285. package/dist/demo-assets/pdf/cfd-primer.pdf +0 -0
  286. package/dist/demo-assets/video/island-coast.webm +0 -0
  287. package/dist/fonts/fonts.css +18 -0
  288. package/dist/index.html +38 -10
  289. package/dist/legal/PRIVACY.md +1 -0
  290. package/dist/legal/TERMS.md +1 -1
  291. package/dist/legal/THIRD-PARTY.txt +13 -5
  292. package/package.json +3 -2
  293. package/dist/assets/AnnotationLayer-8JABh1Dm.js +0 -0
  294. package/dist/assets/AtlasView-B5fkQhO6.css +0 -1
  295. package/dist/assets/BriefingPlayer-TpFZB77N.css +0 -1
  296. package/dist/assets/CanvasSkeleton-iy6DBvde.css +0 -1
  297. package/dist/assets/CardEditor-BY1bZiV6.css +0 -1
  298. package/dist/assets/ConversationVideoStudio-CIAMxElj.css +0 -1
  299. package/dist/assets/ConversationVideoStudio-tpqQQnOs.js +0 -1
  300. package/dist/assets/CourseLessonReader-PFJn-4tj.js +0 -2
  301. package/dist/assets/CoursesApp-5pnHYJR8.js +0 -2
  302. package/dist/assets/CrossExamPanel-CZ0ShGma.css +0 -1
  303. package/dist/assets/DashboardDetail-DYFghZ4p.js +0 -2
  304. package/dist/assets/DashboardLoopGate-C0blM1w9.js +0 -2
  305. package/dist/assets/DashboardLoopRuntime-C9R-z9-o.js +0 -1
  306. package/dist/assets/DashboardsApp-Dh_jh1dF.js +0 -2
  307. package/dist/assets/DeepZoomApp-fRXCJHHZ.css +0 -1
  308. package/dist/assets/DelegatePanel-Cf85-0qE.css +0 -1
  309. package/dist/assets/DelegatePanel-DKWsRY9I.js +0 -33
  310. package/dist/assets/DemoGallery-CkuqAXje.js +0 -1
  311. package/dist/assets/FlagshipShowcase-BHAlRDAE.js +0 -1
  312. package/dist/assets/ForecastPanel-Da2ZBUrE.css +0 -1
  313. package/dist/assets/GalleryApp-DziLKFJZ.js +0 -1
  314. package/dist/assets/LeverPanel-DhpJY76O.css +0 -1
  315. package/dist/assets/LibraryOverlay-CnKWDMG_.css +0 -1
  316. package/dist/assets/LiveApp-C-OPBybd.css +0 -1
  317. package/dist/assets/LiveApp-D6vkyhZb.js +0 -79
  318. package/dist/assets/LiveSettings-C9cKOrSb.js +0 -6
  319. package/dist/assets/LiveSettings-CmgrMqvK.css +0 -1
  320. package/dist/assets/MindShape-C_Bo9hW9.js +0 -1
  321. package/dist/assets/MindShape-CaPeUo-a.css +0 -1
  322. package/dist/assets/PresentationDeck-BW_7qecK.js +0 -1
  323. package/dist/assets/PrismApp-BY71jJvW.js +0 -2
  324. package/dist/assets/PrismAskController-DBoxQSJR.css +0 -1
  325. package/dist/assets/PrismOverlay-BTfAicBt.css +0 -1
  326. package/dist/assets/Recap-DCiiWNiV.css +0 -1
  327. package/dist/assets/RippleApp-DZw8op-E.js +0 -2
  328. package/dist/assets/RippleOverlay-D7ItTvS-.js +0 -6
  329. package/dist/assets/RippleOverlay-_iiZsQVZ.css +0 -1
  330. package/dist/assets/SeeDontRead-DmmtWAzn.js +0 -1
  331. package/dist/assets/ShareModal-9jSn52Mw.js +0 -2
  332. package/dist/assets/ShareModal-D1QuQEko.css +0 -1
  333. package/dist/assets/SrsReview-B1B2VekR.css +0 -1
  334. package/dist/assets/TopicCanvas-DozfZFto.js +0 -2
  335. package/dist/assets/TopicCanvas-uRuHi99s.css +0 -1
  336. package/dist/assets/WhyMachineOverlay-BZk3PVTl.css +0 -1
  337. package/dist/assets/WorldOverlay-yhxq328s.js +0 -2
  338. package/dist/assets/ZoomDeck-B2SjNwY7.css +0 -1
  339. package/dist/assets/canvas-vqIFVmtP.js +0 -1
  340. package/dist/assets/capture-9OrAc1p2.js +0 -2
  341. package/dist/assets/dashboards-C1u2ks-d.css +0 -1
  342. package/dist/assets/generateLive-B6purd69.js +0 -51
  343. package/dist/assets/homeTarget-CsO8nY7z.js +0 -1
  344. package/dist/assets/index-DrzNHwlO.css +0 -1
  345. package/dist/assets/index-zIa6h_8b.js +0 -22
  346. package/dist/assets/kokoro-B3oG_8sd.js +0 -1
  347. package/dist/assets/layout-CEoNLr-w.js +0 -1
  348. package/dist/assets/pageVisibility-BxUVsw7Z.js +0 -1
  349. package/dist/assets/pen-DNMslo3e.js +0 -24
  350. package/dist/assets/pin-D-4Zjiik.css +0 -1
  351. package/dist/assets/portal-k_BMgWND.js +0 -1
  352. package/dist/assets/providers-BovElgRL.js +0 -1
  353. package/dist/assets/quietHours-DI1ayIIq.js +0 -1
  354. package/dist/assets/registry-BSX3aFUw.js +0 -1
  355. package/dist/assets/registry-Bv1f5UU4.js +0 -2
  356. package/dist/assets/registry-Cse2wF7x.css +0 -1
  357. package/dist/assets/registry-Dye5m3qt.css +0 -1
  358. package/dist/assets/registry-GeSy4i7R.css +0 -1
  359. package/dist/assets/registry-WHd1PwU3.js +0 -1
  360. package/dist/assets/registry-Xl8mAnKq.js +0 -1
  361. package/dist/assets/registry-tkd3UhWn.css +0 -1
  362. package/dist/assets/registry-w4R6c89s.js +0 -48
  363. package/dist/assets/shapes-Cx5SCKgj.js +0 -39
  364. package/dist/assets/shard054-BoC-LNYu.js +0 -1
  365. package/dist/assets/speed-K5_Ebj-8.js +0 -1
  366. package/dist/assets/store-BfHRbVKz.js +0 -1
  367. package/dist/assets/store-CsjDEADX.js +0 -1
  368. package/dist/assets/store-DpObYU1u.js +0 -1
  369. package/dist/assets/store-gohr8YVT.js +0 -1
  370. package/dist/assets/streamParse-B-Gjwa9T.js +0 -2
  371. package/dist/assets/useFocusTrap-DBtkeyRy.js +0 -1
  372. package/dist/assets/useInView-CXTOAEV3.js +0 -1
  373. package/dist/assets/useStudy-5CsF_L-s.js +0 -1
  374. package/dist/demo-assets/images/basalt-cliffs.jpg +0 -0
  375. package/dist/demo-assets/images/capelinhos.jpg +0 -0
  376. package/dist/demo-assets/images/cliff-fields.jpg +0 -0
  377. package/dist/demo-assets/images/crater-panorama.jpg +0 -0
  378. package/dist/demo-assets/images/furnas-lake.jpg +0 -0
  379. package/dist/demo-assets/images/green-coast.jpg +0 -0
  380. package/dist/demo-assets/images/overcast-coast.jpg +0 -0
  381. package/dist/demo-assets/images/patchwork-fields.jpg +0 -0
  382. package/dist/demo-assets/images/ponta-delgada.jpg +0 -0
  383. package/dist/demo-assets/images/sete-cidades.jpg +0 -0
  384. package/dist/demo-assets/images/village-street.jpg +0 -0
  385. package/dist/demo-assets/video/azores-film.webm +0 -0
  386. /package/dist/assets/{BriefingPlayer-C0D_2ILa.js → BriefingPlayer-74mRKyjl.js} +0 -0
  387. /package/dist/assets/{CrossExamPanel-CdIYUu-B.js → CrossExamPanel-BfeGr5iw.js} +0 -0
  388. /package/dist/assets/{ForecastPanel-zPUh2ClQ.js → ForecastPanel-OfW39WGS.js} +0 -0
  389. /package/dist/assets/{LeverPanel-D1SNRGdm.js → LeverPanel-vco5UK2U.js} +0 -0
  390. /package/dist/assets/{WhyMachineOverlay-ks9-rRiL.js → WhyMachineOverlay-D2K7y8SA.js} +0 -0
  391. /package/dist/assets/{lib-B7OE1ZQQ.js → lib-u95BsX_B.js} +0 -0
  392. /package/dist/assets/{registry-7poQfBaM.js → registry-C4Yh05pk.js} +0 -0
  393. /package/dist/assets/{registry-Daypk4uR.js → registry-S3j4OpCH.js} +0 -0
package/CHANGELOG.md CHANGED
@@ -6,6 +6,113 @@ All notable changes to Mavéa are documented here. The format is based on
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [2.0.1] - 2026-08-18
10
+
11
+ ### Fixed
12
+
13
+ - **A downloaded conversation video no longer ends inside a spotlight.** The closing beat hands
14
+ the canvas back and plays wide, carved out of the last scene so the cut still ends exactly
15
+ where the narration does; the closing caption and Pen marks stay.
16
+ - **A map now names its places.** Each pin's name and detail line render in a numbered list
17
+ beside the map — numbered to the circles themselves — instead of living only in a click-away
18
+ popup. The list survives a map that fails to load, the same way a route keeps its stops.
19
+ - **First run: the speech questions come before the browser opens.** The window used to open
20
+ over the terminal mid-prompt, so the voice and transcription setup was easy to never see and
21
+ the first impression was silently captions-only. `npx @mavea/mavea` now asks first, then opens.
22
+ - **`npx @mavea/mavea` no longer reports a running voice as missing.** The reachability probe
23
+ hit the service roots, and Kokoro's root answers 404 — so every start offered to set up
24
+ speech services that were already up. It probes the health endpoints now.
25
+ - **Repeat starts stop rebuilding speech images the machine already has.** Compose builds only a
26
+ missing image now (the whisper tag carries its version, so a version bump still builds), on
27
+ Docker and Podman alike.
28
+
29
+ ### Changed
30
+
31
+ - The README and setup guide say plainly what is free and what is metered: the model call is
32
+ billed by the provider under your key; the app and both speech services run locally at no
33
+ per-use cost, and published transcripts or voiced videos owe no fee and no credit line.
34
+
35
+ ## [2.0.0] - 2026-08-18
36
+
37
+ ### Added
38
+
39
+ - **What a session cost is now visible** (Settings → Model): tokens sent, how much of that was
40
+ billed at the cached rate, tokens written back, and which pass spent them. Mavéa is BYOK, so
41
+ every one of those calls was billed to your key — tokens only, never a guessed currency figure,
42
+ and nothing is stored or sent anywhere.
43
+ - The dock's explanation-level chip says what it is. It rendered a bare word ("Standard") beside
44
+ the voice and model chips, so the one control there that isn't self-evident read as a mystery.
45
+
46
+ ### Changed
47
+
48
+ - **The gap between speaking and being answered isn't blank any more.** When the mic closed, every
49
+ "I'm hearing you" indicator vanished at once while the words were still being transcribed —
50
+ which read as not having been heard. The face now holds a working state through it, the
51
+ listening card holds with its bars stilled instead of unmounting, and the mic button keeps a
52
+ slowed pulse rather than just dimming. It starts about 1.3 seconds earlier than it could have:
53
+ the mic reports that you have plainly stopped before its own hangover window closes the
54
+ utterance, and takes that back if you were only pausing mid-thought. A transcription that lands
55
+ inside 300ms changes nothing, so a fast machine never flashes.
56
+ - **A backgrounded tab stops animating.** Every ambient loop in the app — the landing's aurora, a
57
+ card's glow, a hundred-odd others — kept repainting for nobody while the tab sat behind another
58
+ window. They now pause while the tab is hidden, and a landing section pauses its own once it has
59
+ scrolled entirely out of view. Nothing you can see ever changes.
60
+ - The demo images ship as AVIF (2.2MB → 1.6MB), and the component reference examples load per
61
+ answer instead of arriving as one 390KB block held for the whole session (~19KB now stays
62
+ resident). Both make the first load smaller and the session lighter.
63
+ - Answers below the drawer are generated when you open it, not on every rich turn. Six blocks were
64
+ written into every answer whether or not anyone opened the drawer they live behind — the most
65
+ expensive tokens in a turn, spent on content nobody had asked to see. Opening it now generates
66
+ them once and caches them permanently.
67
+
68
+ - **A video export no longer takes exactly as long as the video.** Frames were stamped at real
69
+ elapsed time, so a machine that rasterised slowly stretched them into a slideshow and a fast one
70
+ gained nothing. The export now runs on its own clock — frame `n` belongs at `n/fps` whenever it
71
+ finishes — so a weak machine produces the same sharp file, just later, and a strong one finishes
72
+ ahead of real time. The face is drawn as its own small layer over a cached background, the
73
+ preview stops rendering a second full-size copy while a render is in flight, and a rasterizer
74
+ that fails now says so instead of quietly writing a blank video.
75
+ - **Audio is a choice in the export sheet**, on by default. Turning it off skips speech synthesis
76
+ entirely — captions still pace themselves from the same estimate that drives the duration meter
77
+ — which is also the cheapest path on a weak machine. Narration that does need synthesising is
78
+ now made two lines at a time instead of all at once, which is what used to peg the fan.
79
+ - The in-sheet Share button is gone. On desktop it was a share that silently downloaded, then said
80
+ it had shared; there is now one honest "Download video" action on both tabs.
81
+ - **What a turn costs the model has come down** without changing what it can do: only the leading
82
+ few components carry a worked example, the per-turn prompt now sits inside the cached prefix on
83
+ Anthropic instead of after it, a repair pass no longer resends the whole component menu, a
84
+ speculative glimpse is billed as a glimpse rather than at a reasoning model's floor, and a
85
+ prefetched suggestion is reused across turns instead of being thrown away and paid for twice.
86
+
87
+ ### Fixed
88
+
89
+ - **Local storage stops silently losing data.** Every store capped itself, but they share one
90
+ browser quota and the caps sum past it, so whichever store wrote last simply failed — and said
91
+ nothing. A refused write now sheds the oldest entry of the largest cache and retries, never
92
+ touching anything that isn't a cache, and says so once if it still cannot land.
93
+ - **The scrubber's waveform stops repainting itself sixty times a second** while a line plays: the
94
+ bars are drawn once per track and the playhead is a clip, so playback commits to React about
95
+ once a second instead of once a frame.
96
+ - Speech no longer wakes up ~470 times to ask whether it can queue the next window, and the audio
97
+ thread parks itself after 30 seconds of silence rather than idling for the whole session.
98
+ - **A streamed answer stops rebuilding itself as it arrives.** Each closed block used to land in
99
+ its own render, and a mid-stream flip (a new block family arriving, the first section-tagged
100
+ block landing) tore the whole grid down and replayed every card's entrance. Blocks now fold into
101
+ one paint per frame, the loading placeholders hand their grid cell to the real card instead of
102
+ being replaced wholesale, and the section decision is made once per answer.
103
+ - **A returning dark-mode reader no longer gets a light flash on load.** The boot splash had no
104
+ way to know the stored choice before the bundle ran; it now takes the system setting as its
105
+ guess and yields to the real choice the instant it's known.
106
+ - The hero no longer reflows when its display font lands: the fallback is now metric-matched to
107
+ Newsreader, so the text occupies the same box before and after.
108
+ - **The on-device semantic model (~7MB) is fetched when you reach for the composer**, not on the
109
+ first keystroke or click anywhere in Live. The behaviour its own comment described was never
110
+ what the code did — scrolling the page or dismissing a hint counted as "about to ask".
111
+ - Glass blur now goes away where it's supposed to. 29 stylesheets hardcoded their own blur radius
112
+ and so ignored the performance tier that exists to shed exactly that cost on weak machines.
113
+ - The face's mouth keeps moving on the main conversation surface when another surface is also
114
+ showing a face. Live was the one mount that never registered as a voice-energy target.
115
+
9
116
  ## [1.2.1] - 2026-08-17
10
117
 
11
118
  ### Fixed
package/PRIVACY.md CHANGED
@@ -25,6 +25,7 @@ Depending on the features you use, browser storage may contain:
25
25
  - drafts, tracked items, presentation settings, and recent feature state;
26
26
  - provider and model configuration;
27
27
  - remembered provider, search, or optional GitHub credentials;
28
+ - a short-lived cache of recent questions and the answers to them, kept on the device so that asking the same thing again does not bill your key a second time; it expires within a day, and it deliberately excludes any answer that drew on attachments, ink, filled-in blanks, cited sources, or your remembered facts;
28
29
  - temporary in-progress and finished video-export files in origin-private browser storage until the export is consumed or discarded; and
29
30
  - short-lived demo, tour, route, and in-progress session data.
30
31
 
package/README.md CHANGED
@@ -21,7 +21,7 @@ and evidence you can check, marking the exact figure each line is about.
21
21
  </p>
22
22
 
23
23
  ```sh
24
- npx @mavea/mavea
24
+ npx @mavea/mavea@latest
25
25
  ```
26
26
 
27
27
  Opens `http://localhost:4173` — no install, no account, no model key required.
@@ -32,12 +32,18 @@ Opens `http://localhost:4173` — no install, no account, no model key required.
32
32
 
33
33
  ## Get started
34
34
 
35
- All you need is **Node 20.19+**. That command above opens the tour and demo replays immediately
35
+ All you need is **Node 22.12+**. That command above opens the tour and demo replays immediately
36
36
  — nothing else to set up. Demo replays are fictional, curated prerecorded examples with scripted
37
37
  feature choreography; playback does not call a model provider.
38
38
 
39
+ The `@latest` tag matters: for a bare package name `npx` can reuse a previously cached copy rather
40
+ than fetching a newer one, so asking for `latest` is what reliably gets you the current release.
41
+ Prefer a pinned local copy? `npm install -g @mavea/mavea`, then run `mavea`.
42
+
39
43
  **To talk to a real model (Live):** click **"Open Mavéa"** and paste an Anthropic / OpenAI /
40
- Gemini / Grok / OpenRouter key. It stays in memory unless you opt into encrypted local
44
+ Gemini / Grok / OpenRouter key. Model usage is billed by that provider under your key, at its
45
+ rates — the model call is the part of a turn that costs money; the app and the speech services
46
+ run on your machine for free. The key stays in memory unless you opt into encrypted local
41
47
  remembering, and each provider request carries it through your same-origin proxy to that
42
48
  provider — your key and prompts never pass through Mavéa's own servers, because there aren't
43
49
  any. Full options — models, actions, hosting, and the trust boundary — are in
@@ -45,7 +51,9 @@ any. Full options — models, actions, hosting, and the trust boundary — are i
45
51
 
46
52
  **Local speech:** Mavéa speaks through Apache-2.0
47
53
  [Kokoro weights and wrapper](https://github.com/remsky/Kokoro-FastAPI) and transcribes through MIT-licensed
48
- [whisper.cpp](https://github.com/ggml-org/whisper.cpp). The defaults run on your machine through
54
+ [whisper.cpp](https://github.com/ggml-org/whisper.cpp). Both cost nothing per use, and what they
55
+ produce is yours: publishing a transcript, or a video spoken in Mavéa's voices, owes no fee and no
56
+ credit line — those licenses cover the software, not its output. The defaults run on your machine through
49
57
  loopback-only proxies; a deployment that overrides `WHISPER_URL` sends microphone audio to that
50
58
  configured endpoint. [Podman](https://podman.io/) is the recommended free/open-source
51
59
  container runtime. Docker also works, but Docker Desktop has separate commercial subscription
@@ -91,7 +99,7 @@ is in [docs/FEATURES.md](docs/FEATURES.md). In the app, press **⌘K**.
91
99
  ## What it looks like
92
100
 
93
101
  Twelve moments from the walkthrough and the recorded sessions. Every one replays with no key via
94
- `npx @mavea/mavea` — except the thought map, whose threads need a live model to draw.
102
+ `npx @mavea/mavea@latest` — except the thought map, whose threads need a live model to draw.
95
103
 
96
104
  <!-- Generated, never hand-captured: `pnpm gen:media` re-shoots these against the current build
97
105
  (scripts/capture-media.mts), so a UI change can't quietly leave the README a version behind.
@@ -128,7 +136,7 @@ Mavéa runs on your machine, not in a cloud.
128
136
  | **CPU** | 4 cores | 8 cores |
129
137
  | **RAM** | 8 GB | 16 GB |
130
138
  | **Disk** | 3 GB | 10 GB |
131
- | **Node** | 20.19+ | 20.19+ |
139
+ | **Node** | 22.12+ | 24.11+ |
132
140
 
133
141
  Any browser in [Baseline Widely Available](https://web.dev/baseline) — current Chrome, Edge,
134
142
  Safari, or Firefox — on macOS, Windows, or Linux. **Minimum** covers the app with voice off,
package/TERMS.md CHANGED
@@ -40,7 +40,7 @@ Mavéa can communicate with model, search, speech, media, hosting, OAuth, and ac
40
40
 
41
41
  You provide and control your own accounts, API keys, OAuth grants, and other credentials. Requests send relevant credentials and content through the deployment's same-origin proxy before reaching the selected third party. The proxy operator can access that material in transit. You must use a deployment operator you trust.
42
42
 
43
- All costs of using the Service are your responsibility, including hardware, electricity, network access, hosting, domains, model tokens, search requests, speech services, storage, OAuth applications, connected-account activity, taxes, and any other third-party charges. Labels such as "fast", "balanced", or "thorough" are relative product descriptions, not price quotes or spending limits. You are responsible for provider budgets, quotas, and billing alerts.
43
+ All costs of using the Service are your responsibility, including hardware, electricity, network access, hosting, domains, model tokens, search requests, speech services, storage, OAuth applications, connected-account activity, taxes, and any other third-party charges. Labels such as "fast", "balanced", or "thorough" are relative product descriptions, not price quotes or spending limits. Any token counts or usage figures the Service displays are informational only: they report what a provider stated for the current session in this browser, are not a billing record, and may be incomplete, unavailable, or wrong — your provider's own account is the authoritative measure of what you were charged. You are responsible for provider budgets, quotas, and billing alerts.
44
44
 
45
45
  The repository's container definitions can be used with compatible container engines, but the engine or desktop application you choose is separate software. In particular, Docker Desktop is not free for every commercial organization under Docker's current subscription terms. You are responsible for selecting and licensing your development, build, hosting, and container tools; Mavéa does not grant rights in them.
46
46
 
package/THIRD-PARTY.txt CHANGED
@@ -25244,7 +25244,9 @@ whisper.cpp v1.9.1 MIT https://github.com/ggml-org/whisper.cpp
25244
25244
  Whisper small.en-q5_1 MIT https://huggingface.co/ggerganov/whisper.cpp
25245
25245
  (local STT model; downloaded into a local volume and verified by SHA-256 before execution)
25246
25246
  Self-hosted fonts OFL-1.1 public/fonts/LICENSE.txt carries exact notices; OFL-1.1.txt carries the full license; PROVENANCE.md pins every shipped file
25247
- Demonstration media Pexels License / NASA public domain see public/demo-assets/CREDITS.md
25247
+ Demonstration media CC0-1.0 / NASA public domain see public/demo-assets/CREDITS.md
25248
+ (bundled demo photos and the film plate are Wikimedia Commons CC0 dedications, verified per file
25249
+ against the Commons API; the embedded report is a complete work of the US Government)
25248
25250
  Map rendering MapLibre GL JS (BSD-3-Clause) https://maplibre.org/maplibre-gl-js/
25249
25251
  Map tiles OpenFreeMap public service / MIT server https://openfreemap.org/
25250
25252
  (terms reviewed 2026-08-11 currently permit commercial use without request fees; attribution remains
@@ -25255,12 +25257,18 @@ PDF image decoders BSD-3-Clause / BSD-2-Clause / MIT https://github.com/mozilla/
25255
25257
  (jbig2.wasm from PDFium, openjpeg.wasm from OpenJPEG, and qcms_bg.wasm from Mozilla's qcms,
25256
25258
  redistributed via pdfjs-dist and served from dist/pdfjs/ so a scanned page renders; each carries
25257
25259
  its upstream notice beside it as dist/pdfjs/LICENSE_*)
25258
- Syntax-highlighting grammars & themes MIT and other permissive https://github.com/shikijs/textmate-grammars-themes
25259
- (TextMate grammars and GitHub themes redistributed via @shikijs/langs / @shikijs/themes; upstream
25260
- sources and per-grammar licenses are documented in that repository's tm-grammars / tm-themes metadata)
25260
+ Syntax-highlighting grammars & themes MIT, plus the textmate.org grant for yaml/toml https://github.com/shikijs/textmate-grammars-themes
25261
+ (25 TextMate grammars and the two GitHub themes redistributed via @shikijs/langs / @shikijs/themes.
25262
+ Resolved per grammar against that repository's tm-grammars / tm-themes metadata, 2026-08-17: 23 are
25263
+ MIT — 20 from microsoft/vscode, swift from jtbandes/swift-tmlanguage, kotlin from fwcd/vscode-kotlin,
25264
+ both themes from primer/github-vscode-theme. yaml and toml come from textmate/yaml.tmbundle and
25265
+ textmate/toml.tmbundle, which carry no SPDX tag but state in their bundle README: "Permission to
25266
+ copy, use, modify, sell and distribute this software is granted." That is an unrestricted permissive
25267
+ grant with no attribution clause; it is recorded here because an automated license scan reads it as
25268
+ null, not because anything about it is unresolved)
25261
25269
  Embedded tour documents per-document, see below src/tour/corpus/prism.generated.json
25262
25270
  (byte-for-byte copies embedded for the key-free tour's document-reading chapter; each license
25263
25271
  permits redistribution with this notice)
25264
- NASA CFD education report excerpt US-government work, public use permitted https://ntrs.nasa.gov/citations/19950004435
25272
+ NASA CFD education report (complete, 14pp) US-government work, public use permitted https://ntrs.nasa.gov/citations/19950004435
25265
25273
  react/README.md MIT https://github.com/facebook/react
25266
25274
  cars.json + seattle-weather.csv BSD-3-Clause https://github.com/vega/vega-datasets
package/bin/mavea.mjs CHANGED
@@ -14,6 +14,7 @@ import {
14
14
  renameSync,
15
15
  unlinkSync,
16
16
  realpathSync,
17
+ writeFileSync,
17
18
  } from 'node:fs';
18
19
  import { writeFile } from 'node:fs/promises';
19
20
  import { fileURLToPath } from 'node:url';
@@ -941,12 +942,159 @@ async function serviceReachable(url) {
941
942
  }
942
943
  }
943
944
 
944
- function startSpeechServices(runtime) {
945
+ // ---- Kokoro thread tuning ---------------------------------------------------
946
+ //
947
+ // The measured tuner `pnpm dev` runs (scripts/dev.mjs), ported here. Duplicated rather than
948
+ // imported on purpose: the published package ships bin/ and dist/, never the repo's scripts/, and
949
+ // this executable is deliberately dependency-free. Keep the two in step when either changes.
950
+ //
951
+ // There is no thread count that is right for every machine: the same 4 threads that leave a fast
952
+ // box idling at 4x realtime are barely enough on an older one, and the answer depends on per-core
953
+ // speed, which nothing in a compose file can see. Kokoro's throughput is near-linear in threads up
954
+ // to its measured peak (1.12x / 2.47x / 3.38x / 4.23x at 1-4 threads), so one probe at a known
955
+ // thread count yields per-thread speed, and the smallest count clearing the target follows.
956
+
957
+ /** Speech plays at 1x, so anything above it is only margin — but the margin has to absorb a busy
958
+ * machine mid-sentence, and falling behind is audible as a stutter. 2x is the smallest cushion. */
959
+ const VOICE_TARGET_REALTIME = 2;
960
+ /** The measured peak of Kokoro's thread-scaling curve; past this it gets slower AND hungrier. It
961
+ * is also the compose default, so a tuned machine only ever comes DOWN from it. */
962
+ const VOICE_MAX_THREADS = 4;
963
+ const VOICE_PROBE_TEXT =
964
+ 'Mavéa is a voice first thinking companion that draws what it means as it speaks.';
965
+ /** Kokoro emits 24kHz mono 16-bit PCM, so byte length converts straight to seconds of audio. */
966
+ const VOICE_PCM_BYTES_PER_SECOND = 24_000 * 2;
967
+ /** Kokoro loads its voice model on first run; a cold pull can take a while, so poll generously. */
968
+ const VOICE_READY_TIMEOUT_MS = 180_000;
969
+ const VOICE_POLL_MS = 1_000;
970
+
971
+ export function voiceThreadsCacheFile() {
972
+ return join(lazyCacheDir(), 'voice-threads.json');
973
+ }
974
+
975
+ /** The thread count this machine settled on last time, or null on a first run (or a cache written
976
+ * by a build that measured a different ceiling). */
977
+ export function readCachedVoiceThreads(file = voiceThreadsCacheFile()) {
978
+ try {
979
+ const { threads } = JSON.parse(readFileSync(file, 'utf8'));
980
+ return Number.isInteger(threads) && threads > 0 && threads <= VOICE_MAX_THREADS
981
+ ? threads
982
+ : null;
983
+ } catch {
984
+ return null;
985
+ }
986
+ }
987
+
988
+ export function rememberVoiceThreads(threads, realtimePerThread, file = voiceThreadsCacheFile()) {
989
+ try {
990
+ mkdirSync(dirname(file), { recursive: true });
991
+ writeFileSync(file, JSON.stringify({ threads, realtimePerThread }, null, 2));
992
+ return true;
993
+ } catch {
994
+ // A cache that cannot be written costs one probe per run, which is not worth failing over.
995
+ return false;
996
+ }
997
+ }
998
+
999
+ /** The smallest thread count that clears the realtime target at this machine's measured speed. */
1000
+ export function voiceThreadsFor(realtimePerThread) {
1001
+ if (!(realtimePerThread > 0)) return VOICE_MAX_THREADS;
1002
+ return Math.min(
1003
+ VOICE_MAX_THREADS,
1004
+ Math.max(1, Math.ceil(VOICE_TARGET_REALTIME / realtimePerThread)),
1005
+ );
1006
+ }
1007
+
1008
+ /** The environment a compose spawn runs with: the tuned thread count, or the compose default. */
1009
+ export function voiceThreadEnv(threads, env = process.env) {
1010
+ return threads ? { ...env, MAVEA_VOICE_THREADS: String(threads) } : env;
1011
+ }
1012
+
1013
+ /** Synthesize one clause and return how many seconds of audio came back per second of wall clock. */
1014
+ async function measureVoiceRealtime(kokoroUrl) {
1015
+ try {
1016
+ const started = performance.now();
1017
+ const res = await fetch(`${kokoroUrl}/v1/audio/speech`, {
1018
+ method: 'POST',
1019
+ headers: { 'Content-Type': 'application/json' },
1020
+ body: JSON.stringify({
1021
+ model: 'kokoro',
1022
+ input: VOICE_PROBE_TEXT,
1023
+ voice: 'af_heart',
1024
+ response_format: 'pcm',
1025
+ }),
1026
+ signal: AbortSignal.timeout(60_000),
1027
+ });
1028
+ if (!res.ok) return null;
1029
+ const bytes = (await res.arrayBuffer()).byteLength;
1030
+ const seconds = (performance.now() - started) / 1000;
1031
+ if (!bytes || seconds <= 0) return null;
1032
+ return bytes / VOICE_PCM_BYTES_PER_SECOND / seconds;
1033
+ } catch {
1034
+ return null;
1035
+ }
1036
+ }
1037
+
1038
+ /** Measure this machine and record the answer for next time.
1039
+ *
1040
+ * Deliberately does NOT restart the container to apply the new number now: a restart drops the
1041
+ * voice for as long as the model takes to reload, and the app probes speech availability once per
1042
+ * page session — a browser that asks during that window would go silent for the whole session
1043
+ * with nothing to show for it. The default is already safe; the tuned value takes effect on the
1044
+ * next run, so nobody waits and nothing goes quiet. */
1045
+ async function settleVoiceThreads(kokoroUrl, ranAt) {
1046
+ // Best of three, not an average: a busy moment can only ever make synthesis look slower, so the
1047
+ // fastest run is the one closest to what this machine can actually do. The first call also pays
1048
+ // for warmup, which the later ones do not.
1049
+ const runs = [];
1050
+ for (let i = 0; i < 3; i++) {
1051
+ const realtime = await measureVoiceRealtime(kokoroUrl);
1052
+ if (realtime !== null) runs.push(realtime);
1053
+ }
1054
+ if (!runs.length) return;
1055
+ const perThread = Math.max(...runs) / ranAt;
1056
+ const want = voiceThreadsFor(perThread);
1057
+ rememberVoiceThreads(want, Number(perThread.toFixed(3)));
1058
+ if (want === ranAt) return;
945
1059
  console.log(
946
- ' Starting Kokoro TTS + whisper.cpp STT. The first run builds/downloads pinned models…',
1060
+ ` Voice: this machine only needs ${want} core${want === 1 ? '' : 's'} — applied from the next run.`,
947
1061
  );
948
- spawn(runtime.command, [...runtime.prefix, '-f', COMPOSE_FILE, 'up', '-d', '--build'], {
1062
+ }
1063
+
1064
+ /** Wait for Kokoro to actually answer before probing it — the model load is what takes the time on
1065
+ * a first run, and a measurement taken through it would over-provision every later session. Runs
1066
+ * in the background: the app is already being served while this waits. */
1067
+ async function tuneVoiceWhenReady(kokoroUrl, ranAt) {
1068
+ const deadline = Date.now() + VOICE_READY_TIMEOUT_MS;
1069
+ while (Date.now() < deadline) {
1070
+ if (await serviceReachable(`${kokoroUrl}/health`)) {
1071
+ await settleVoiceThreads(kokoroUrl, ranAt);
1072
+ return;
1073
+ }
1074
+ await new Promise((resolvePoll) => setTimeout(resolvePoll, VOICE_POLL_MS));
1075
+ }
1076
+ }
1077
+
1078
+ /**
1079
+ * The compose invocation that starts speech, for whichever runtime is present — Docker, Podman and
1080
+ * podman-compose all take the same verbs, so the caching behaviour below is identical on each.
1081
+ *
1082
+ * `--build` is deliberately absent. It forces a build pass on EVERY run, which re-resolves the
1083
+ * whisper image on a machine that already has it; without it compose builds only when the image is
1084
+ * missing and reuses what is already there. That is safe because the tag carries the version
1085
+ * (`mavea-whisper-cpp:1.9.1` in docker-compose.yml), so a version bump is a new tag and does build,
1086
+ * while a repeat run on the same version costs nothing. Kokoro is pinned by digest and compose's
1087
+ * default `--pull missing` never re-pulls a digest it already holds.
1088
+ */
1089
+ export function composeUpArgs(runtime, composeFile = COMPOSE_FILE) {
1090
+ return [...runtime.prefix, '-f', composeFile, 'up', '-d'];
1091
+ }
1092
+
1093
+ function startSpeechServices(runtime, threads) {
1094
+ console.log(' Starting Kokoro TTS + whisper.cpp STT. The first run downloads pinned models…');
1095
+ spawn(runtime.command, composeUpArgs(runtime), {
949
1096
  stdio: 'inherit',
1097
+ env: voiceThreadEnv(threads),
950
1098
  });
951
1099
  }
952
1100
 
@@ -965,12 +1113,19 @@ const VOICE_INTRO =
965
1113
  '\n◌ Configured speech — Kokoro reads replies and whisper.cpp transcribes your mic.\n' +
966
1114
  ' The defaults are loopback-only. A custom WHISPER_URL receives microphone audio at that endpoint.\n';
967
1115
 
1116
+ /** A speech service's health endpoint. Probed instead of the root because the roots differ —
1117
+ * Kokoro's answers 404 (FastAPI routes /health, not /) — so a root probe reported a running
1118
+ * voice as missing on every start and offered to set up services that were already up. */
1119
+ export function speechHealthUrl(base) {
1120
+ return base.replace(/\/+$/, '') + '/health';
1121
+ }
1122
+
968
1123
  async function maybeOfferVoice() {
969
1124
  const kokoroUrl = process.env.KOKORO_URL || 'http://localhost:8880';
970
1125
  const whisperUrl = process.env.WHISPER_URL || 'http://localhost:8100';
971
1126
  const [kokoroReady, whisperReady] = await Promise.all([
972
- serviceReachable(kokoroUrl),
973
- serviceReachable(whisperUrl),
1127
+ serviceReachable(speechHealthUrl(kokoroUrl)),
1128
+ serviceReachable(speechHealthUrl(whisperUrl)),
974
1129
  ]);
975
1130
  if (kokoroReady && whisperReady) return;
976
1131
  if (!existsSync(COMPOSE_FILE) || !process.stdin.isTTY) {
@@ -1020,7 +1175,26 @@ async function maybeOfferVoice() {
1020
1175
  return;
1021
1176
  }
1022
1177
  }
1023
- startSpeechServices(runtime);
1178
+ const tuned = readCachedVoiceThreads();
1179
+ const startedAt = tuned ?? VOICE_MAX_THREADS;
1180
+ startSpeechServices(runtime, startedAt);
1181
+ // First run on this machine, and we are the ones bringing the voice up: measure it once it
1182
+ // answers and remember the answer for next time. A voice that was already running is left alone
1183
+ // — the probe costs real CPU, and nothing about it is urgent.
1184
+ if (tuned === null && !kokoroReady) void tuneVoiceWhenReady(kokoroUrl, startedAt);
1185
+ }
1186
+
1187
+ /**
1188
+ * Speech is settled BEFORE the browser opens, and the order is the whole point: the setup questions
1189
+ * live in this terminal, so a window opening over them is how a first run ends up permanently
1190
+ * without voice or transcription — the reader never sees the prompt, the answer falls to a default
1191
+ * nobody chose, and the experience they judge Mavéa on is the degraded one. Nothing here waits on
1192
+ * containers (the compose spawn is detached), so the cost is one reachability probe plus however
1193
+ * long the answers take.
1194
+ */
1195
+ export async function settleStartup(args, { offerVoice, openApp }) {
1196
+ if (args.voice) await offerVoice();
1197
+ if (args.open) openApp();
1024
1198
  }
1025
1199
 
1026
1200
  async function main() {
@@ -1087,8 +1261,7 @@ Podman is the recommended free/open-source container runtime. Docker Desktop has
1087
1261
  console.log(`Terms: ${base}/legal/TERMS.md`);
1088
1262
  console.log(`Privacy: ${base}/legal/PRIVACY.md`);
1089
1263
  console.log(`License: ${base}/legal/LICENSE.txt (PolyForm Noncommercial 1.0.0)`);
1090
- if (args.open) openBrowser(base);
1091
- if (args.voice) await maybeOfferVoice();
1264
+ await settleStartup(args, { offerVoice: maybeOfferVoice, openApp: () => openBrowser(base) });
1092
1265
  }
1093
1266
 
1094
1267
  // npm/npx installs `bin` entries as a symlink (node_modules/.bin/mavea -> ../@mavea/mavea/bin/