cotutor 0.1.0 → 0.3.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 (845) hide show
  1. package/LICENSE +247 -21
  2. package/NOTICE +42 -0
  3. package/README.md +107 -24
  4. package/bin/cotutor.js +4 -4
  5. package/cards/canvas/card.css +8 -0
  6. package/cards/canvas/card.md +68 -0
  7. package/cards/choice/card.css +18 -0
  8. package/cards/choice/card.md +55 -0
  9. package/cards/code/card.css +5 -0
  10. package/cards/code/card.md +46 -0
  11. package/cards/dictation/card.css +10 -0
  12. package/cards/dictation/card.md +97 -0
  13. package/cards/image/card.css +10 -0
  14. package/cards/image/card.md +52 -0
  15. package/cards/lecture/card.css +9 -0
  16. package/cards/lecture/card.md +69 -0
  17. package/cards/paint/card.css +20 -0
  18. package/cards/paint/card.md +77 -0
  19. package/cards/photo/card.css +15 -0
  20. package/cards/photo/card.md +61 -0
  21. package/cards/read/card.css +6 -0
  22. package/cards/read/card.md +51 -0
  23. package/cards/text/card.css +3 -0
  24. package/cards/text/card.md +69 -0
  25. package/cards/tianzige/card.css +17 -0
  26. package/cards/tianzige/card.md +78 -0
  27. package/cards/tutor/card.css +66 -0
  28. package/cards/tutor/card.md +148 -0
  29. package/cards/word/card.css +24 -0
  30. package/cards/word/card.md +91 -0
  31. package/cards//346/235/277/344/271/246/346/200/216/344/271/210/345/206/231.md +159 -0
  32. package/dist/app/activity-eval-rules.d.ts +62 -0
  33. package/dist/app/activity-eval-rules.js +276 -0
  34. package/dist/app/activity-eval.d.ts +65 -0
  35. package/dist/app/activity-eval.js +158 -0
  36. package/dist/app/build.d.ts +11 -0
  37. package/dist/app/build.js +45 -0
  38. package/dist/app/cli/activities.d.ts +63 -0
  39. package/dist/app/cli/activities.js +158 -0
  40. package/dist/app/cli/cert.d.ts +7 -0
  41. package/dist/app/cli/cert.js +36 -0
  42. package/dist/app/cli/chalk/bake.d.ts +10 -0
  43. package/dist/app/cli/chalk/bake.js +58 -0
  44. package/dist/app/cli/chalk/browser.d.ts +16 -0
  45. package/dist/app/cli/chalk/browser.js +142 -0
  46. package/dist/app/cli/chalk/build.d.ts +14 -0
  47. package/dist/app/cli/chalk/build.js +100 -0
  48. package/dist/app/cli/chalk/dub.d.ts +51 -0
  49. package/dist/app/cli/chalk/dub.js +106 -0
  50. package/dist/app/cli/chalk/load-scene.d.ts +34 -0
  51. package/dist/app/cli/chalk/load-scene.js +117 -0
  52. package/dist/app/cli/chalk/main.d.ts +7 -0
  53. package/dist/app/cli/chalk/main.js +198 -0
  54. package/dist/app/cli/chalk/serve.d.ts +4 -0
  55. package/dist/app/cli/chalk/serve.js +28 -0
  56. package/dist/app/cli/chalk/snap.d.ts +65 -0
  57. package/dist/app/cli/chalk/snap.js +103 -0
  58. package/dist/app/cli/chalk/typecheck.d.ts +7 -0
  59. package/dist/app/cli/chalk/typecheck.js +51 -0
  60. package/dist/app/cli/doctor.d.ts +23 -0
  61. package/dist/app/cli/doctor.js +617 -0
  62. package/dist/app/cli/grades.d.ts +14 -0
  63. package/dist/app/cli/grades.js +44 -0
  64. package/dist/{cli → app/cli}/init.d.ts +3 -1
  65. package/dist/app/cli/init.js +155 -0
  66. package/dist/app/cli/main.js +715 -0
  67. package/dist/app/cli/migrate.d.ts +58 -0
  68. package/dist/app/cli/migrate.js +253 -0
  69. package/dist/app/cli/serve.d.ts +37 -0
  70. package/dist/app/cli/serve.js +98 -0
  71. package/dist/app/cli/shipped.d.ts +30 -0
  72. package/dist/app/cli/shipped.js +47 -0
  73. package/dist/app/cli/skeleton.d.ts +38 -0
  74. package/dist/app/cli/skeleton.js +161 -0
  75. package/dist/app/cli/skills.d.ts +55 -0
  76. package/dist/app/cli/skills.js +189 -0
  77. package/dist/app/cli/themes.d.ts +52 -0
  78. package/dist/app/cli/themes.js +148 -0
  79. package/dist/app/cli/tutors.d.ts +73 -0
  80. package/dist/app/cli/tutors.js +250 -0
  81. package/dist/app/cli/usage.d.ts +2 -0
  82. package/dist/app/cli/usage.js +30 -0
  83. package/dist/app/dictation/recognize.d.ts +18 -0
  84. package/dist/app/dictation/recognize.js +6 -0
  85. package/dist/app/dictation/route.d.ts +52 -0
  86. package/dist/app/dictation/route.js +510 -0
  87. package/dist/app/diff.d.ts +11 -0
  88. package/dist/app/diff.js +71 -0
  89. package/dist/app/http/access.d.ts +62 -0
  90. package/dist/app/http/access.js +180 -0
  91. package/dist/app/http/app.d.ts +246 -0
  92. package/dist/app/http/app.js +1212 -0
  93. package/dist/app/http/dev-activities.d.ts +115 -0
  94. package/dist/app/http/dev-activities.js +193 -0
  95. package/dist/app/http/dev-overview.d.ts +108 -0
  96. package/dist/app/http/dev-overview.js +209 -0
  97. package/dist/app/http/dev-tutor-files.d.ts +80 -0
  98. package/dist/app/http/dev-tutor-files.js +151 -0
  99. package/dist/app/http/parent-home.d.ts +37 -0
  100. package/dist/app/http/parent-home.js +203 -0
  101. package/dist/app/http/range.d.ts +9 -0
  102. package/dist/app/http/range.js +19 -0
  103. package/dist/app/http/raw-view.d.ts +117 -0
  104. package/dist/app/http/raw-view.js +149 -0
  105. package/dist/app/http/send-file.d.ts +7 -0
  106. package/dist/app/http/send-file.js +29 -0
  107. package/dist/app/http/stage.d.ts +24 -0
  108. package/dist/app/http/stage.js +97 -0
  109. package/dist/app/http/theme.d.ts +13 -0
  110. package/dist/app/http/theme.js +41 -0
  111. package/dist/app/machine/bailian.d.ts +28 -0
  112. package/dist/app/machine/bailian.js +88 -0
  113. package/dist/app/mock/mock-live.d.ts +16 -0
  114. package/dist/app/mock/mock-live.js +140 -0
  115. package/dist/app/mock/mock.d.ts +89 -0
  116. package/dist/app/mock/mock.js +1117 -0
  117. package/dist/app/replay.d.ts +94 -0
  118. package/dist/app/replay.js +170 -0
  119. package/dist/app/skills/analyze-doc.d.ts +3 -0
  120. package/dist/app/skills/analyze-doc.js +47 -0
  121. package/dist/app/skills/home-doc.d.ts +5 -0
  122. package/dist/app/skills/home-doc.js +112 -0
  123. package/dist/app/skills/tune-doc.d.ts +3 -0
  124. package/dist/app/skills/tune-doc.js +80 -0
  125. package/dist/app/talk/list.d.ts +11 -0
  126. package/dist/app/talk/list.js +9 -0
  127. package/dist/app/talk/route.d.ts +16 -0
  128. package/dist/app/talk/route.js +142 -0
  129. package/dist/app/workspace.d.ts +58 -0
  130. package/dist/{cli → app}/workspace.js +82 -36
  131. package/dist/app/ws/route.d.ts +25 -0
  132. package/dist/app/ws/route.js +29 -0
  133. package/dist/app/ws/ws.d.ts +31 -0
  134. package/dist/app/ws/ws.js +169 -0
  135. package/dist/board/canvas-chat.d.ts +97 -0
  136. package/dist/board/canvas-chat.js +175 -0
  137. package/dist/board/card-guards.d.ts +15 -0
  138. package/dist/board/card-guards.js +38 -0
  139. package/dist/board/cards/canvas.d.ts +41 -0
  140. package/dist/board/cards/canvas.js +83 -0
  141. package/dist/board/cards/choice.d.ts +20 -0
  142. package/dist/board/cards/choice.js +64 -0
  143. package/dist/board/cards/code.d.ts +9 -0
  144. package/dist/board/cards/code.js +10 -0
  145. package/dist/board/cards/dictation.d.ts +42 -0
  146. package/dist/board/cards/dictation.js +105 -0
  147. package/dist/board/cards/docs.d.ts +47 -0
  148. package/dist/board/cards/docs.js +152 -0
  149. package/dist/board/cards/image.d.ts +13 -0
  150. package/dist/board/cards/image.js +26 -0
  151. package/dist/board/cards/index.d.ts +62 -0
  152. package/dist/board/cards/index.js +144 -0
  153. package/dist/board/cards/kind.d.ts +33 -0
  154. package/dist/board/cards/kind.js +9 -0
  155. package/dist/board/cards/lecture.d.ts +26 -0
  156. package/dist/board/cards/lecture.js +62 -0
  157. package/dist/board/cards/paint.d.ts +38 -0
  158. package/dist/board/cards/paint.js +85 -0
  159. package/dist/board/cards/photo.d.ts +15 -0
  160. package/dist/board/cards/photo.js +29 -0
  161. package/dist/board/cards/read.d.ts +8 -0
  162. package/dist/board/cards/read.js +18 -0
  163. package/dist/board/cards/text.d.ts +20 -0
  164. package/dist/board/cards/text.js +59 -0
  165. package/dist/board/cards/tianzige.d.ts +16 -0
  166. package/dist/board/cards/tianzige.js +64 -0
  167. package/dist/board/cards/tutor.d.ts +72 -0
  168. package/dist/board/cards/tutor.js +134 -0
  169. package/dist/board/cards/word.d.ts +20 -0
  170. package/dist/board/cards/word.js +76 -0
  171. package/dist/board/lecture.d.ts +100 -0
  172. package/dist/board/lecture.js +204 -0
  173. package/dist/board/paper.d.ts +20 -0
  174. package/dist/board/paper.js +76 -0
  175. package/dist/board/parse.d.ts +120 -0
  176. package/dist/board/parse.js +330 -0
  177. package/dist/board/presentation.d.ts +295 -0
  178. package/dist/board/presentation.js +615 -0
  179. package/dist/board/sections.d.ts +16 -0
  180. package/dist/board/sections.js +130 -0
  181. package/dist/brain/api-tools.d.ts +8 -0
  182. package/dist/brain/api-tools.js +190 -0
  183. package/dist/brain/api.d.ts +62 -0
  184. package/dist/brain/api.js +411 -0
  185. package/dist/brain/cli/adapters.d.ts +60 -0
  186. package/dist/brain/cli/adapters.js +91 -0
  187. package/dist/brain/cli/qwen.d.ts +11 -0
  188. package/dist/brain/cli/qwen.js +141 -0
  189. package/dist/brain/cli/run-plan.d.ts +59 -0
  190. package/dist/brain/cli/run-plan.js +71 -0
  191. package/dist/brain/cli/run.d.ts +35 -0
  192. package/dist/brain/cli/run.js +256 -0
  193. package/dist/brain/cli/stream-json.d.ts +18 -0
  194. package/dist/brain/cli/stream-json.js +86 -0
  195. package/dist/brain/cli/types.d.ts +144 -0
  196. package/dist/brain/cli/types.js +3 -0
  197. package/dist/brain/cli/warm.d.ts +53 -0
  198. package/dist/brain/cli/warm.js +103 -0
  199. package/dist/brain/index.d.ts +145 -0
  200. package/dist/brain/index.js +74 -0
  201. package/dist/brain/stream.d.ts +20 -0
  202. package/dist/brain/stream.js +70 -0
  203. package/dist/brain/transcript.d.ts +45 -0
  204. package/dist/brain/transcript.js +132 -0
  205. package/dist/chalk/actions.d.ts +37 -0
  206. package/dist/chalk/actions.js +69 -0
  207. package/dist/chalk/bundle.d.ts +26 -0
  208. package/dist/chalk/bundle.js +69 -0
  209. package/dist/chalk/check.d.ts +28 -0
  210. package/dist/chalk/check.js +291 -0
  211. package/dist/chalk/circle.d.ts +64 -0
  212. package/dist/chalk/circle.js +193 -0
  213. package/dist/chalk/clock.d.ts +84 -0
  214. package/dist/chalk/clock.js +84 -0
  215. package/dist/chalk/geometry.d.ts +44 -0
  216. package/dist/chalk/geometry.js +139 -0
  217. package/dist/chalk/glyphs/capitals.d.ts +12 -0
  218. package/dist/chalk/glyphs/capitals.js +264 -0
  219. package/dist/chalk/glyphs/index.d.ts +21 -0
  220. package/dist/chalk/glyphs/index.js +18 -0
  221. package/dist/chalk/glyphs/letters.d.ts +13 -0
  222. package/dist/chalk/glyphs/letters.js +280 -0
  223. package/dist/chalk/glyphs/metrics.d.ts +33 -0
  224. package/dist/chalk/glyphs/metrics.js +28 -0
  225. package/dist/chalk/glyphs/registry.d.ts +7 -0
  226. package/dist/chalk/glyphs/registry.js +8 -0
  227. package/dist/chalk/glyphs/sample.d.ts +32 -0
  228. package/dist/chalk/glyphs/sample.js +102 -0
  229. package/dist/chalk/glyphs/skeleton.d.ts +64 -0
  230. package/dist/chalk/glyphs/skeleton.js +126 -0
  231. package/dist/chalk/glyphs/types.d.ts +58 -0
  232. package/dist/chalk/glyphs/types.js +17 -0
  233. package/dist/chalk/index.d.ts +23 -0
  234. package/dist/chalk/index.js +15 -0
  235. package/dist/chalk/manifest.d.ts +41 -0
  236. package/dist/chalk/manifest.js +6 -0
  237. package/dist/chalk/paint.d.ts +180 -0
  238. package/dist/chalk/paint.js +210 -0
  239. package/dist/chalk/pointer.d.ts +8 -0
  240. package/dist/chalk/pointer.js +21 -0
  241. package/dist/chalk/prepare.d.ts +11 -0
  242. package/dist/chalk/prepare.js +15 -0
  243. package/dist/chalk/scene-schema.d.ts +199 -0
  244. package/dist/chalk/scene-schema.js +91 -0
  245. package/dist/chalk/seed.d.ts +3 -0
  246. package/dist/chalk/seed.js +10 -0
  247. package/dist/chalk/text-metrics.d.ts +8 -0
  248. package/dist/chalk/text-metrics.js +156 -0
  249. package/dist/chalk/timeline.d.ts +47 -0
  250. package/dist/chalk/timeline.js +84 -0
  251. package/dist/chalk/types.d.ts +150 -0
  252. package/dist/chalk/types.js +8 -0
  253. package/dist/lib/index.d.ts +14 -8
  254. package/dist/lib/index.js +14 -8
  255. package/dist/media/draw.d.ts +23 -0
  256. package/dist/media/draw.js +44 -0
  257. package/dist/media/mp3.d.ts +6 -0
  258. package/dist/media/mp3.js +58 -0
  259. package/dist/media/mp4.d.ts +1 -0
  260. package/dist/media/mp4.js +58 -0
  261. package/dist/media/tts-voices.d.ts +18 -0
  262. package/dist/media/tts-voices.js +606 -0
  263. package/dist/media/tts.d.ts +56 -0
  264. package/dist/media/tts.js +174 -0
  265. package/dist/media/vision.d.ts +25 -0
  266. package/dist/media/vision.js +71 -0
  267. package/dist/memory/commit.d.ts +67 -0
  268. package/dist/memory/commit.js +130 -0
  269. package/dist/memory/context.d.ts +86 -0
  270. package/dist/memory/context.js +97 -0
  271. package/dist/memory/diary.d.ts +84 -0
  272. package/dist/memory/diary.js +183 -0
  273. package/dist/memory/grade.d.ts +2 -0
  274. package/dist/memory/grade.js +7 -0
  275. package/dist/{lib → memory}/plan.d.ts +3 -1
  276. package/dist/{lib → memory}/plan.js +10 -1
  277. package/dist/memory/proposals.d.ts +11 -0
  278. package/dist/memory/proposals.js +43 -0
  279. package/dist/memory/retrieval.d.ts +44 -0
  280. package/dist/memory/retrieval.js +157 -0
  281. package/dist/memory/timetable.d.ts +19 -0
  282. package/dist/memory/timetable.js +95 -0
  283. package/dist/memory/vault-notes.d.ts +165 -0
  284. package/dist/memory/vault-notes.js +359 -0
  285. package/dist/memory/vault.d.ts +70 -0
  286. package/dist/memory/vault.js +169 -0
  287. package/dist/realtime/bailian.d.ts +120 -0
  288. package/dist/realtime/bailian.js +288 -0
  289. package/dist/realtime/cues.d.ts +51 -0
  290. package/dist/realtime/cues.js +94 -0
  291. package/dist/realtime/listen.d.ts +32 -0
  292. package/dist/realtime/listen.js +53 -0
  293. package/dist/realtime/preview.d.ts +23 -0
  294. package/dist/realtime/preview.js +38 -0
  295. package/dist/realtime/prompt.d.ts +8 -0
  296. package/dist/realtime/prompt.js +13 -0
  297. package/dist/realtime/voices.d.ts +19 -0
  298. package/dist/realtime/voices.js +71 -0
  299. package/dist/runtime/activities.d.ts +17 -0
  300. package/dist/runtime/activities.js +46 -0
  301. package/dist/runtime/activity-state.d.ts +22 -0
  302. package/dist/runtime/activity-state.js +83 -0
  303. package/dist/runtime/activity.d.ts +63 -0
  304. package/dist/runtime/activity.js +428 -0
  305. package/dist/runtime/agent-file.d.ts +24 -0
  306. package/dist/runtime/agent-file.js +59 -0
  307. package/dist/runtime/auto-bookkeep.d.ts +30 -0
  308. package/dist/runtime/auto-bookkeep.js +84 -0
  309. package/dist/{lib → runtime/context}/context-pack.d.ts +3 -3
  310. package/dist/runtime/context/context-pack.js +182 -0
  311. package/dist/runtime/context/thread-digest.d.ts +4 -0
  312. package/dist/runtime/context/thread-digest.js +35 -0
  313. package/dist/runtime/context/tutor-rules.d.ts +25 -0
  314. package/dist/runtime/context/tutor-rules.js +47 -0
  315. package/dist/runtime/delivery/delivery.d.ts +94 -0
  316. package/dist/runtime/delivery/delivery.js +145 -0
  317. package/dist/runtime/delivery/playback.d.ts +25 -0
  318. package/dist/runtime/delivery/playback.js +29 -0
  319. package/dist/runtime/delivery/player.d.ts +145 -0
  320. package/dist/runtime/delivery/player.js +221 -0
  321. package/dist/runtime/delivery/queue.d.ts +89 -0
  322. package/dist/runtime/delivery/queue.js +59 -0
  323. package/dist/runtime/home/edit.d.ts +39 -0
  324. package/dist/runtime/home/edit.js +132 -0
  325. package/dist/runtime/home/home.d.ts +180 -0
  326. package/dist/runtime/home/home.js +311 -0
  327. package/dist/runtime/home/store.d.ts +142 -0
  328. package/dist/runtime/home/store.js +440 -0
  329. package/dist/runtime/journal/conversation.d.ts +46 -0
  330. package/dist/runtime/journal/conversation.js +89 -0
  331. package/dist/runtime/journal/events.d.ts +27 -0
  332. package/dist/runtime/journal/events.js +136 -0
  333. package/dist/runtime/journal/kid-log.d.ts +105 -0
  334. package/dist/runtime/journal/kid-log.js +133 -0
  335. package/dist/runtime/journal/ledger.d.ts +17 -0
  336. package/dist/{lib → runtime/journal}/ledger.js +7 -32
  337. package/dist/runtime/journal/mix.d.ts +33 -0
  338. package/dist/runtime/journal/mix.js +88 -0
  339. package/dist/runtime/journal/mouth-index.d.ts +26 -0
  340. package/dist/runtime/journal/mouth-index.js +34 -0
  341. package/dist/runtime/journal/mouth.d.ts +54 -0
  342. package/dist/runtime/journal/mouth.js +102 -0
  343. package/dist/runtime/journal/recorder.d.ts +46 -0
  344. package/dist/runtime/journal/recorder.js +58 -0
  345. package/dist/runtime/journal/store.d.ts +123 -0
  346. package/dist/runtime/journal/store.js +316 -0
  347. package/dist/runtime/kid-input.d.ts +16 -0
  348. package/dist/runtime/kid-input.js +195 -0
  349. package/dist/runtime/kid-view.d.ts +124 -0
  350. package/dist/runtime/kid-view.js +157 -0
  351. package/dist/runtime/lecture.d.ts +86 -0
  352. package/dist/runtime/lecture.js +237 -0
  353. package/dist/runtime/live/call.d.ts +219 -0
  354. package/dist/runtime/live/call.js +1211 -0
  355. package/dist/runtime/live/turns.d.ts +48 -0
  356. package/dist/runtime/live/turns.js +102 -0
  357. package/dist/runtime/runner.d.ts +289 -0
  358. package/dist/runtime/runner.js +898 -0
  359. package/dist/runtime/talk-run.d.ts +21 -0
  360. package/dist/runtime/talk-run.js +34 -0
  361. package/dist/scenes/dictation/match.d.ts +57 -0
  362. package/dist/scenes/dictation/match.js +255 -0
  363. package/dist/scenes/dictation/recognize.d.ts +86 -0
  364. package/dist/scenes/dictation/recognize.js +163 -0
  365. package/dist/scenes/dictation/store.d.ts +112 -0
  366. package/dist/scenes/dictation/store.js +99 -0
  367. package/dist/scenes/look.d.ts +26 -0
  368. package/dist/scenes/look.js +1 -0
  369. package/dist/scenes/paint/painter.d.ts +84 -0
  370. package/dist/scenes/paint/painter.js +170 -0
  371. package/dist/scenes/paint/prompt.d.ts +23 -0
  372. package/dist/scenes/paint/prompt.js +36 -0
  373. package/dist/scenes/talk/en-words.d.ts +8 -0
  374. package/dist/scenes/talk/en-words.js +44 -0
  375. package/dist/scenes/talk/list.d.ts +44 -0
  376. package/dist/scenes/talk/list.js +88 -0
  377. package/dist/scenes/talk/store.d.ts +27 -0
  378. package/dist/scenes/talk/store.js +61 -0
  379. package/dist/scenes/talk/warmup.d.ts +16 -0
  380. package/dist/scenes/talk/warmup.js +39 -0
  381. package/dist/schema/activity.d.ts +149 -0
  382. package/dist/schema/activity.js +113 -0
  383. package/dist/schema/board.d.ts +200 -0
  384. package/dist/schema/board.js +42 -0
  385. package/dist/schema/config.d.ts +353 -80
  386. package/dist/schema/config.js +293 -76
  387. package/dist/schema/context-pack.d.ts +82 -13
  388. package/dist/schema/context-pack.js +97 -10
  389. package/dist/schema/conversation-files.d.ts +43 -0
  390. package/dist/schema/conversation-files.js +26 -0
  391. package/dist/schema/conversation.d.ts +459 -13
  392. package/dist/schema/conversation.js +148 -8
  393. package/dist/schema/events.d.ts +138 -0
  394. package/dist/schema/events.js +1 -0
  395. package/dist/schema/home.d.ts +46 -0
  396. package/dist/schema/home.js +30 -0
  397. package/dist/schema/index.d.ts +19 -4
  398. package/dist/schema/index.js +19 -4
  399. package/dist/schema/json-schema.d.ts +2 -0
  400. package/dist/schema/json-schema.js +23 -0
  401. package/dist/schema/kid-device.d.ts +20 -0
  402. package/dist/schema/kid-device.js +32 -0
  403. package/dist/schema/ledger.d.ts +9 -64
  404. package/dist/schema/ledger.js +7 -31
  405. package/dist/schema/memory.d.ts +73 -0
  406. package/dist/schema/memory.js +47 -0
  407. package/dist/schema/plan.d.ts +2 -2
  408. package/dist/schema/plan.js +2 -2
  409. package/dist/schema/sections.d.ts +32 -25
  410. package/dist/schema/sections.js +21 -22
  411. package/dist/schema/theme.d.ts +25 -0
  412. package/dist/schema/theme.js +26 -0
  413. package/dist/schema/timetable.d.ts +26 -0
  414. package/dist/schema/timetable.js +18 -0
  415. package/dist/schema/workspace.d.ts +41 -0
  416. package/dist/schema/workspace.js +9 -0
  417. package/dist/shared/errors.d.ts +8 -0
  418. package/dist/shared/errors.js +13 -0
  419. package/dist/shared/home.d.ts +2 -0
  420. package/dist/shared/home.js +16 -0
  421. package/dist/shared/human-notes.d.ts +5 -0
  422. package/dist/shared/human-notes.js +7 -0
  423. package/dist/shared/qianwen.d.ts +50 -0
  424. package/dist/shared/qianwen.js +109 -0
  425. package/dist/shared/time.d.ts +9 -0
  426. package/dist/shared/time.js +22 -0
  427. package/dist/shared/tokens.d.ts +18 -0
  428. package/dist/shared/tokens.js +11 -0
  429. package/dist/shared/wav.d.ts +10 -0
  430. package/dist/shared/wav.js +50 -0
  431. package/dist/stage/Assistant-Bold-ZDZZ6JHA.woff2 +0 -0
  432. package/dist/stage/Assistant-Medium-DZ25RZU3.woff2 +0 -0
  433. package/dist/stage/Assistant-Regular-PLF2XOGW.woff2 +0 -0
  434. package/dist/stage/Assistant-SemiBold-CZ5MX6FK.woff2 +0 -0
  435. package/dist/stage/chunk-226TNLQA.js +129 -0
  436. package/dist/stage/chunk-24LGQEKE.js +1 -0
  437. package/dist/stage/chunk-25XV6UY3.js +10 -0
  438. package/dist/stage/chunk-2AZI3NHJ.js +1 -0
  439. package/dist/stage/chunk-2BQZTTBE.js +1 -0
  440. package/dist/stage/chunk-2M7CGY3Y.js +11 -0
  441. package/dist/stage/chunk-2VR4WFQ7.js +10 -0
  442. package/dist/stage/chunk-2ZYXBUWG.js +9 -0
  443. package/dist/stage/chunk-32LAWMGY.js +1 -0
  444. package/dist/stage/chunk-3LEMTSOO.js +11 -0
  445. package/dist/stage/chunk-3QCKGZYE.js +32 -0
  446. package/dist/stage/chunk-44P66WFA.js +1 -0
  447. package/dist/stage/chunk-4AM6FRR6.js +7 -0
  448. package/dist/stage/chunk-4QDE4SUK.js +1 -0
  449. package/dist/stage/chunk-4QESHV3U.js +1 -0
  450. package/dist/stage/chunk-4SG5QPHB.js +2 -0
  451. package/dist/stage/chunk-4T4UVCOC.js +1 -0
  452. package/dist/stage/chunk-4WUEPPG3.js +34 -0
  453. package/dist/stage/chunk-4YCN6UZ5.js +99 -0
  454. package/dist/stage/chunk-5V7ZY2AP.js +1 -0
  455. package/dist/stage/chunk-5VS5Y2VJ.js +6 -0
  456. package/dist/stage/chunk-5W4NO2ZD.js +62 -0
  457. package/dist/stage/chunk-65CRNICM.js +1 -0
  458. package/dist/stage/chunk-66MULO7F.js +5 -0
  459. package/dist/stage/chunk-6COFQTBS.js +162 -0
  460. package/dist/stage/chunk-6VZG3M3I.js +8 -0
  461. package/dist/stage/chunk-7HVDH43T.js +1 -0
  462. package/dist/stage/chunk-7JLJN4EZ.js +8 -0
  463. package/dist/stage/chunk-7QDSP4LN.js +1 -0
  464. package/dist/stage/chunk-7R6OQAO3.js +1 -0
  465. package/dist/stage/chunk-7VTTHZKW.js +7 -0
  466. package/dist/stage/chunk-ATHR5KEN.js +10 -0
  467. package/dist/stage/chunk-B6R5LTP2.js +36 -0
  468. package/dist/stage/chunk-BD4WE264.js +1 -0
  469. package/dist/stage/chunk-BONANU47.js +206 -0
  470. package/dist/stage/chunk-BTVW7OFK.js +89 -0
  471. package/dist/stage/chunk-BUTJIDHG.js +8 -0
  472. package/dist/stage/chunk-C2IPYMML.js +84 -0
  473. package/dist/stage/chunk-C54FTPPV.js +9 -0
  474. package/dist/stage/chunk-C6LOUF2Z.js +90 -0
  475. package/dist/stage/chunk-CFF3PILO.js +339 -0
  476. package/dist/stage/chunk-CI2FQ2JY.js +9 -0
  477. package/dist/stage/chunk-CW5O4RV7.js +12 -0
  478. package/dist/stage/chunk-CYABNQYD.js +1 -0
  479. package/dist/stage/chunk-D7FFA4NS.js +15 -0
  480. package/dist/stage/chunk-DUNNXU6Z.js +8 -0
  481. package/dist/stage/chunk-E3E4Q6JF.js +6 -0
  482. package/dist/stage/chunk-EB3U3LH7.js +9 -0
  483. package/dist/stage/chunk-EGSZ736B.js +8 -0
  484. package/dist/stage/chunk-EOBXW5VQ.js +2 -0
  485. package/dist/stage/chunk-ERZC3B7Y.js +11 -0
  486. package/dist/stage/chunk-ESDOOBIH.js +11 -0
  487. package/dist/stage/chunk-EVU4QAL4.js +178 -0
  488. package/dist/stage/chunk-EVVZI2NY.js +39 -0
  489. package/dist/stage/chunk-FBKAZUKD.js +39 -0
  490. package/dist/stage/chunk-FDVKYQJN.js +1 -0
  491. package/dist/stage/chunk-FGPVYHVR.js +5 -0
  492. package/dist/stage/chunk-FHUD4AZC.js +1 -0
  493. package/dist/stage/chunk-FKUJ2DMY.js +96 -0
  494. package/dist/stage/chunk-FNZGVIJV.js +1 -0
  495. package/dist/stage/chunk-GBYSEGYM.js +78 -0
  496. package/dist/stage/chunk-GCO4TDHX.js +1 -0
  497. package/dist/stage/chunk-GKTML2LG.js +10 -0
  498. package/dist/stage/chunk-GMDIHHXQ.js +11 -0
  499. package/dist/stage/chunk-GOUNACI3.js +10 -0
  500. package/dist/stage/chunk-GXAYATPF.js +3 -0
  501. package/dist/stage/chunk-H2K2DDXV.js +8 -0
  502. package/dist/stage/chunk-H3UJI6ZY.js +13 -0
  503. package/dist/stage/chunk-H6PUGCME.js +7 -0
  504. package/dist/stage/chunk-HNBUIMIG.js +1 -0
  505. package/dist/stage/chunk-HRZY2BJQ.js +10 -0
  506. package/dist/stage/chunk-HSPJGALW.js +30 -0
  507. package/dist/stage/chunk-IBYORHIP.js +25 -0
  508. package/dist/stage/chunk-IHF4EWTY.js +1 -0
  509. package/dist/stage/chunk-ISBRPNKI.js +1 -0
  510. package/dist/stage/chunk-IZ3OI3C2.js +2 -0
  511. package/dist/stage/chunk-JEFZAC2R.js +1 -0
  512. package/dist/stage/chunk-JFIGRDPO.js +1 -0
  513. package/dist/stage/chunk-JFVYBOOC.js +9 -0
  514. package/dist/stage/chunk-JGD4TUTQ.js +1 -0
  515. package/dist/stage/chunk-JO4BEHDH.js +4 -0
  516. package/dist/stage/chunk-JOWBS42C.js +1 -0
  517. package/dist/stage/chunk-JP3TM2TG.js +1 -0
  518. package/dist/stage/chunk-JVK2C52O.js +1 -0
  519. package/dist/stage/chunk-K4I76XBX.js +14 -0
  520. package/dist/stage/chunk-KA6CZZ4M.js +1 -0
  521. package/dist/stage/chunk-KESSJ36M.js +1 -0
  522. package/dist/stage/chunk-LKATEVRU.js +1 -0
  523. package/dist/stage/chunk-LS4EJ2EI.js +1 -0
  524. package/dist/stage/chunk-LUKJQC2X.js +70 -0
  525. package/dist/stage/chunk-LWULR3SM.js +1 -0
  526. package/dist/stage/chunk-LWVRFMKX.js +2 -0
  527. package/dist/stage/chunk-LXC4ZBPZ.js +1 -0
  528. package/dist/stage/chunk-M2UP255H.js +1 -0
  529. package/dist/stage/chunk-MAPPXUZQ.js +231 -0
  530. package/dist/stage/chunk-MBMPW7Z5.js +1 -0
  531. package/dist/stage/chunk-MD3HMMTK.js +1 -0
  532. package/dist/stage/chunk-MLPCUIKR.js +17 -0
  533. package/dist/stage/chunk-MNQIRPDQ.js +8 -0
  534. package/dist/stage/chunk-MRG7MJVS.js +1 -0
  535. package/dist/stage/chunk-MU6EXW72.js +10 -0
  536. package/dist/stage/chunk-MVU2X6LU.js +4 -0
  537. package/dist/stage/chunk-N6UA5CZV.js +36 -0
  538. package/dist/stage/chunk-NLZIT2TJ.js +7 -0
  539. package/dist/stage/chunk-NOJR3J7M.js +1 -0
  540. package/dist/stage/chunk-NT7ARDOL.js +1 -0
  541. package/dist/stage/chunk-NWOGMPZH.js +1 -0
  542. package/dist/stage/chunk-NXE4KMG3.js +40 -0
  543. package/dist/stage/chunk-O4YCZXD2.js +257 -0
  544. package/dist/stage/chunk-OAJZ7HLK.js +1 -0
  545. package/dist/stage/chunk-OCFCFASO.js +1 -0
  546. package/dist/stage/chunk-ODGPG5RY.js +7 -0
  547. package/dist/stage/chunk-ODUEA52Q.js +3 -0
  548. package/dist/stage/chunk-OGDJ3FCI.js +1 -0
  549. package/dist/stage/chunk-OLDJ55TT.js +1 -0
  550. package/dist/stage/chunk-OOCL4ATI.js +2 -0
  551. package/dist/stage/chunk-OQEFDUDV.js +1 -0
  552. package/dist/stage/chunk-OQWVEWG7.js +4 -0
  553. package/dist/stage/chunk-OUIX6BGK.js +1 -0
  554. package/dist/stage/chunk-OV7OZYUO.js +7 -0
  555. package/dist/stage/chunk-PFGDY33O.js +1 -0
  556. package/dist/stage/chunk-PFJDUJB3.js +139 -0
  557. package/dist/stage/chunk-PGEW76ER.js +1 -0
  558. package/dist/stage/chunk-PP76TAQX.js +32 -0
  559. package/dist/stage/chunk-PTBOP4OT.js +2 -0
  560. package/dist/stage/chunk-PX2RVHCK.js +1 -0
  561. package/dist/stage/chunk-Q7K3PNAD.js +1 -0
  562. package/dist/stage/chunk-QDDPLZDB.js +1 -0
  563. package/dist/stage/chunk-QLGLZ77F.js +1 -0
  564. package/dist/stage/chunk-QOPFDFHI.js +1 -0
  565. package/dist/stage/chunk-QXT4KAEJ.js +1 -0
  566. package/dist/stage/chunk-R4YVZCIT.js +1 -0
  567. package/dist/stage/chunk-R6P6EHWA.js +62 -0
  568. package/dist/stage/chunk-RCH3OXBI.js +9 -0
  569. package/dist/stage/chunk-RHPE44I2.js +1 -0
  570. package/dist/stage/chunk-RJ2R4FVC.js +1 -0
  571. package/dist/stage/chunk-RJH2YVTD.js +1 -0
  572. package/dist/stage/chunk-RLWWW5OB.js +6 -0
  573. package/dist/stage/chunk-S3WO35Z7.js +120 -0
  574. package/dist/stage/chunk-S7ZGX6MW.js +1 -0
  575. package/dist/stage/chunk-SIAWX27B.js +1 -0
  576. package/dist/stage/chunk-SLG4X622.js +1 -0
  577. package/dist/stage/chunk-SLJRBC77.js +168 -0
  578. package/dist/stage/chunk-SRORWQJZ.js +1 -0
  579. package/dist/stage/chunk-STZTUIIF.js +2 -0
  580. package/dist/stage/chunk-SVQ6MWNV.js +9 -0
  581. package/dist/stage/chunk-TL3HLL2S.js +132 -0
  582. package/dist/stage/chunk-U3DOE6SF.js +24 -0
  583. package/dist/stage/chunk-UABQIZKW.js +6 -0
  584. package/dist/stage/chunk-UDK3R764.js +1 -0
  585. package/dist/stage/chunk-UFF4E54B.js +41 -0
  586. package/dist/stage/chunk-UFP5Q4AY.js +1 -0
  587. package/dist/stage/chunk-UMH2TSW2.js +72 -0
  588. package/dist/stage/chunk-UTASVNF5.js +10 -0
  589. package/dist/stage/chunk-UW7ML5ML.js +88 -0
  590. package/dist/stage/chunk-V3J7F6OP.js +1 -0
  591. package/dist/stage/chunk-VEHP5B5Q.js +5 -0
  592. package/dist/stage/chunk-VRXWB733.js +9 -0
  593. package/dist/stage/chunk-VVDHBBS5.js +5 -0
  594. package/dist/stage/chunk-VYFOH6FU.js +106 -0
  595. package/dist/stage/chunk-W3VZTLQS.js +3 -0
  596. package/dist/stage/chunk-W7WNRWTZ.js +8 -0
  597. package/dist/stage/chunk-WHUCV53C.js +1 -0
  598. package/dist/stage/chunk-WULMYHIF.js +1 -0
  599. package/dist/stage/chunk-X54EX7AW.js +9 -0
  600. package/dist/stage/chunk-X565ISZM.js +1 -0
  601. package/dist/stage/chunk-XGZMDECB.js +1 -0
  602. package/dist/stage/chunk-XHONC4RF.js +172 -0
  603. package/dist/stage/chunk-XIK4XQ6E.js +24 -0
  604. package/dist/stage/chunk-XJQQWFTE.js +1 -0
  605. package/dist/stage/chunk-XM4WOU3I.js +13 -0
  606. package/dist/stage/chunk-XM7Y5HP5.js +38 -0
  607. package/dist/stage/chunk-XNYYRGD5.js +292 -0
  608. package/dist/stage/chunk-XOYVR3SV.js +1 -0
  609. package/dist/stage/chunk-XQIW5HCE.js +1 -0
  610. package/dist/stage/chunk-YEWL7FUW.js +8 -0
  611. package/dist/stage/chunk-YI55PY3V.js +1 -0
  612. package/dist/stage/chunk-YM63HI6W.js +1 -0
  613. package/dist/stage/chunk-YNLGLU4P.js +9 -0
  614. package/dist/stage/chunk-YTNMNOWP.js +1 -0
  615. package/dist/stage/chunk-YV62XKTC.js +1 -0
  616. package/dist/stage/chunk-YVBA3QW6.js +1 -0
  617. package/dist/stage/chunk-Z2SY2HOC.js +1 -0
  618. package/dist/stage/chunk-ZBTCQEBK.js +10 -0
  619. package/dist/stage/chunk-ZCUFN74D.js +1 -0
  620. package/dist/stage/chunk-ZHOULXEJ.js +11 -0
  621. package/dist/stage/chunk-ZTRZIET2.js +1 -0
  622. package/dist/stage/index.html +11 -0
  623. package/dist/stage/stage.css +1 -0
  624. package/dist/stage/stage.js +1 -0
  625. package/dist/ui/dev/dev-page.d.ts +1 -0
  626. package/dist/ui/dev/dev-page.js +2248 -0
  627. package/dist/ui/dev/dev-theme.d.ts +6 -0
  628. package/dist/ui/dev/dev-theme.js +67 -0
  629. package/dist/ui/dev/qr-page.d.ts +8 -0
  630. package/dist/ui/dev/qr-page.js +61 -0
  631. package/dist/ui/dev/voice-gallery-page.d.ts +1 -0
  632. package/dist/ui/dev/voice-gallery-page.js +121 -0
  633. package/dist/ui/dev/voice-scenes.d.ts +21 -0
  634. package/dist/ui/dev/voice-scenes.js +30 -0
  635. package/dist/ui/dictation/en-box.d.ts +2 -0
  636. package/dist/ui/dictation/en-box.js +86 -0
  637. package/dist/ui/dictation/en-page.d.ts +1 -0
  638. package/dist/ui/dictation/en-page.js +484 -0
  639. package/dist/ui/dictation/page.d.ts +1 -0
  640. package/dist/ui/dictation/page.js +1084 -0
  641. package/dist/ui/dictation/parent-page.d.ts +1 -0
  642. package/dist/ui/dictation/parent-page.js +234 -0
  643. package/dist/ui/dictation/reel-mode.d.ts +1 -0
  644. package/dist/ui/dictation/reel-mode.js +87 -0
  645. package/dist/ui/dictation/reel-page.d.ts +1 -0
  646. package/dist/ui/dictation/reel-page.js +62 -0
  647. package/dist/ui/dictation/reel.d.ts +163 -0
  648. package/dist/ui/dictation/reel.js +436 -0
  649. package/dist/ui/dictation/ui.d.ts +44 -0
  650. package/dist/ui/dictation/ui.js +80 -0
  651. package/dist/ui/dictation/unlock.d.ts +7 -0
  652. package/dist/ui/dictation/unlock.js +16 -0
  653. package/dist/ui/kid/audio-client.d.ts +11 -0
  654. package/dist/ui/kid/audio-client.js +74 -0
  655. package/dist/ui/kid/board-mark-art.d.ts +37 -0
  656. package/dist/ui/kid/board-mark-art.js +5 -0
  657. package/dist/ui/kid/board-mark.d.ts +24 -0
  658. package/dist/ui/kid/board-mark.js +58 -0
  659. package/dist/ui/kid/kid-log.d.ts +15 -0
  660. package/dist/ui/kid/kid-log.js +87 -0
  661. package/dist/ui/kid/kid-nav.d.ts +11 -0
  662. package/dist/ui/kid/kid-nav.js +22 -0
  663. package/dist/ui/kid/kid-page.d.ts +9 -0
  664. package/dist/ui/kid/kid-page.js +3719 -0
  665. package/dist/ui/kid/letters.d.ts +26 -0
  666. package/dist/ui/kid/letters.js +51 -0
  667. package/dist/ui/kid/photo-edit.d.ts +83 -0
  668. package/dist/ui/kid/photo-edit.js +106 -0
  669. package/dist/ui/kid/photo-ui.d.ts +23 -0
  670. package/dist/ui/kid/photo-ui.js +60 -0
  671. package/dist/ui/kid/reel.d.ts +419 -0
  672. package/dist/ui/kid/reel.js +648 -0
  673. package/dist/ui/kid/tianzige.d.ts +8 -0
  674. package/dist/ui/kid/tianzige.js +45 -0
  675. package/dist/ui/kid/tutor-face.d.ts +35 -0
  676. package/dist/ui/kid/tutor-face.js +84 -0
  677. package/dist/ui/kid/voice-ui.d.ts +70 -0
  678. package/dist/ui/kid/voice-ui.js +316 -0
  679. package/dist/ui/kid/voice-view.d.ts +71 -0
  680. package/dist/ui/kid/voice-view.js +75 -0
  681. package/dist/ui/kid/word-draw.d.ts +2 -0
  682. package/dist/ui/kid/word-draw.js +107 -0
  683. package/dist/ui/kid/word-emoji.d.ts +10 -0
  684. package/dist/ui/kid/word-emoji.js +66 -0
  685. package/dist/ui/kid/word-layout.d.ts +25 -0
  686. package/dist/ui/kid/word-layout.js +29 -0
  687. package/dist/ui/parent/parent-home-page.d.ts +1 -0
  688. package/dist/ui/parent/parent-home-page.js +414 -0
  689. package/dist/ui/parent/parent-page.d.ts +2 -0
  690. package/dist/ui/parent/parent-page.js +507 -0
  691. package/dist/ui/shared/brand.d.ts +36 -0
  692. package/dist/ui/shared/brand.js +51 -0
  693. package/dist/ui/shared/favicon.d.ts +12 -0
  694. package/dist/ui/shared/favicon.js +96 -0
  695. package/dist/ui/shared/icon.d.ts +9 -0
  696. package/dist/ui/shared/icon.js +35 -0
  697. package/dist/ui/shared/inline-lib.d.ts +1 -0
  698. package/dist/ui/shared/inline-lib.js +28 -0
  699. package/dist/ui/shared/logo.d.ts +31 -0
  700. package/dist/ui/shared/logo.js +43 -0
  701. package/dist/ui/shared/page-dom.d.ts +12 -0
  702. package/dist/ui/shared/page-dom.js +36 -0
  703. package/dist/ui/shared/png.d.ts +1 -0
  704. package/dist/ui/shared/png.js +45 -0
  705. package/dist/ui/shared/qr-svg.d.ts +3 -0
  706. package/dist/ui/shared/qr-svg.js +32 -0
  707. package/dist/ui/shared/qr.d.ts +14 -0
  708. package/dist/ui/shared/qr.js +281 -0
  709. package/dist/ui/shared/reel-dock.d.ts +22 -0
  710. package/dist/ui/shared/reel-dock.js +365 -0
  711. package/dist/ui/shared/tutor-color.d.ts +15 -0
  712. package/dist/ui/shared/tutor-color.js +47 -0
  713. package/dist/ui/talk/page.d.ts +6 -0
  714. package/dist/ui/talk/page.js +294 -0
  715. package/grades/grade-2/README.md +11 -0
  716. package/grades/grade-2/VALIDATION.md +41 -0
  717. package/grades/grade-2/agents/chinese-tutor/activities//344/275/240/350/257/264/346/210/221/347/224/273.md +157 -0
  718. package/grades/grade-2/agents/chinese-tutor/activities//344/275/240/350/257/264/346/210/221/347/224/273./344/276/213/345/255/220.md +78 -0
  719. package/grades/grade-2/agents/chinese-tutor/activities//344/276/213/345/255/220/345/233/276//345/200/237/344/274/236.jpg +0 -0
  720. package/grades/grade-2/agents/chinese-tutor/activities//344/276/213/345/255/220/345/233/276//345/260/217/347/214/264/346/221/230/346/241/203.jpg +0 -0
  721. package/grades/grade-2/agents/chinese-tutor/activities//345/206/231/350/257/235.md +64 -0
  722. package/grades/grade-2/agents/chinese-tutor/activities//345/206/231/350/257/235./344/276/213/345/255/220.md +31 -0
  723. package/grades/grade-2/agents/chinese-tutor/activities//345/220/254/345/206/231.md +48 -0
  724. package/grades/grade-2/agents/chinese-tutor/activities//345/244/215/344/271/240.md +79 -0
  725. package/grades/grade-2/agents/chinese-tutor/activities//345/244/215/344/271/240./344/276/213/345/255/220.md +35 -0
  726. package/grades/grade-2/agents/chinese-tutor/activities//345/260/217/350/257/276/345/240/202.md +53 -0
  727. package/grades/grade-2/agents/chinese-tutor/activities//346/211/271/346/224/271.md +81 -0
  728. package/grades/grade-2/agents/chinese-tutor/activities//346/211/271/346/224/271./344/276/213/345/255/220.md +35 -0
  729. package/grades/grade-2/agents/chinese-tutor/activities//347/234/213/345/233/276/350/257/264/350/257/235.md +94 -0
  730. package/grades/grade-2/agents/chinese-tutor/activities//347/234/213/345/233/276/350/257/264/350/257/235./344/276/213/345/255/220.md +63 -0
  731. package/grades/grade-2/agents/chinese-tutor/activities//351/242/204/344/271/240.md +82 -0
  732. package/grades/grade-2/agents/chinese-tutor/activities//351/242/204/344/271/240./344/276/213/345/255/220.md +35 -0
  733. package/grades/grade-2/agents/chinese-tutor.md +59 -0
  734. package/grades/grade-2/agents/english-tutor/activities//345/217/243/350/257/255/350/257/276.md +149 -0
  735. package/grades/grade-2/agents/english-tutor/activities//345/217/243/350/257/255/350/257/276./344/276/213/345/255/220.md +13 -0
  736. package/grades/grade-2/agents/english-tutor/activities//345/220/254/345/206/231.md +47 -0
  737. package/grades/grade-2/agents/english-tutor/activities//345/244/215/344/271/240.md +78 -0
  738. package/grades/grade-2/agents/english-tutor/activities//345/244/215/344/271/240./344/276/213/345/255/220.md +35 -0
  739. package/grades/grade-2/agents/english-tutor/activities//345/260/217/350/257/276/345/240/202.md +53 -0
  740. package/grades/grade-2/agents/english-tutor/activities//346/211/271/346/224/271.md +80 -0
  741. package/grades/grade-2/agents/english-tutor/activities//346/211/271/346/224/271./344/276/213/345/255/220.md +35 -0
  742. package/grades/grade-2/agents/english-tutor/activities//351/242/204/344/271/240.md +86 -0
  743. package/grades/grade-2/agents/english-tutor/activities//351/242/204/344/271/240./344/276/213/345/255/220.md +35 -0
  744. package/grades/grade-2/agents/english-tutor.md +57 -0
  745. package/grades/grade-2/agents/math-tutor/activities//345/244/215/344/271/240.md +78 -0
  746. package/grades/grade-2/agents/math-tutor/activities//345/244/215/344/271/240./344/276/213/345/255/220.md +35 -0
  747. package/grades/grade-2/agents/math-tutor/activities//345/260/217/350/257/276/345/240/202.md +56 -0
  748. package/grades/grade-2/agents/math-tutor/activities//345/260/217/350/257/276/345/240/202./344/276/213/345/255/220.md +52 -0
  749. package/grades/grade-2/agents/math-tutor/activities//346/211/271/346/224/271.md +80 -0
  750. package/grades/grade-2/agents/math-tutor/activities//346/211/271/346/224/271./344/276/213/345/255/220.md +35 -0
  751. package/grades/grade-2/agents/math-tutor/activities//351/242/204/344/271/240.md +81 -0
  752. package/grades/grade-2/agents/math-tutor/activities//351/242/204/344/271/240./344/276/213/345/255/220.md +35 -0
  753. package/grades/grade-2/agents/math-tutor.md +51 -0
  754. package/grades/grade-2/examples/2026-10-27-pingjunfen/audio/index.json +44 -0
  755. package/grades/grade-2/examples/2026-10-27-pingjunfen/audio/step-1.mp3 +0 -0
  756. package/grades/grade-2/examples/2026-10-27-pingjunfen/audio/step-2.mp3 +0 -0
  757. package/grades/grade-2/examples/2026-10-27-pingjunfen/audio/step-3.mp3 +0 -0
  758. package/grades/grade-2/examples/2026-10-27-pingjunfen/audio/step-4.mp3 +0 -0
  759. package/grades/grade-2/examples/2026-10-27-pingjunfen/audio/step-5.mp3 +0 -0
  760. package/grades/grade-2/examples/2026-10-27-pingjunfen/bake.json +1 -0
  761. package/grades/grade-2/examples/2026-10-27-pingjunfen/manifest.json +63 -0
  762. package/grades/grade-2/examples/2026-10-27-pingjunfen/scene.json +247 -0
  763. package/grades/grade-2/examples/2026-10-27-pingjunfen.md +40 -0
  764. package/grades/grade-2/examples/2026-10-27-pingjunfen.ts +26 -0
  765. package/grades/grade-2/examples//345/271/263/345/235/207/345/210/206./344/276/213/345/255/220.md +24 -0
  766. package/grades/grade-2/examples//346/225/260/345/255/246/345/271/263/345/235/207/345/210/206.md +42 -0
  767. package/grades/grade-2/validation/2026-10-27.json +4410 -0
  768. package/package.json +32 -12
  769. package/skills/chalk-cli/SKILL.md +62 -0
  770. package/skills/chalk-scene/SKILL.md +91 -0
  771. package/skills/chalk-teaching/SKILL.md +82 -0
  772. package/skills/chalk-teaching/models//344/272/244/351/224/231/346/225/260/345/210/227/345/210/206/350/241/214.md +8 -0
  773. package/skills/chalk-teaching/models//345/207/221/345/215/201.md +7 -0
  774. package/skills/chalk-teaching/models//345/221/250/346/234/237/350/247/204/345/276/213.md +6 -0
  775. package/skills/chalk-teaching/models//345/256/236/347/211/251/345/233/276-/345/242/236/345/207/217.md +6 -0
  776. package/skills/chalk-teaching/models//345/256/236/347/211/251/345/233/276-/346/257/224/345/244/232/345/260/221-/346/261/202/345/244/247/346/225/260/346/261/202/345/260/217/346/225/260.md +7 -0
  777. package/skills/chalk-teaching/models//345/256/236/347/211/251/345/233/276-/346/257/224/345/244/232/345/260/221-/346/261/202/345/267/256.md +6 -0
  778. package/skills/chalk-teaching/models//345/260/217/346/243/222/350/277/233/344/275/215/345/212/240.md +7 -0
  779. package/skills/chalk-teaching/models//345/260/217/346/243/222/351/200/200/344/275/215/345/207/217.md +6 -0
  780. package/skills/chalk-teaching/models//346/216/222/351/230/237/347/202/271/351/230/265.md +7 -0
  781. package/skills/chalk-teaching/models//346/227/266/351/227/264/346/225/260/350/275/264.md +6 -0
  782. package/skills/chalk-teaching/models//346/245/274/345/261/202/351/227/264/351/232/224/345/233/276.md +7 -0
  783. package/skills/chalk-teaching/models//347/240/264/345/215/201.md +7 -0
  784. package/skills/chalk-teaching/models//347/253/226/345/274/217/351/200/200/344/275/215.md +6 -0
  785. package/skills/chalk-teaching/models//347/272/277/346/256/265/345/233/276.md +7 -0
  786. package/skills/chalk-teaching/models-index.md +24 -0
  787. package/skills/chalk-teaching/references//350/256/262/350/247/243/346/250/241/346/235/277/344/270/211/346/241/243.md +32 -0
  788. package/skills/chalk-teaching/references//350/257/264/346/230/216/346/226/207/344/273/266.md +102 -0
  789. package/skills/chalk-verify/SKILL.md +57 -0
  790. package/skills/chalk-verify/references//350/257/204/345/210/244/346/240/207/345/207/206.md +69 -0
  791. package/skills/cotutor-analyze/SKILL.md +106 -0
  792. package/skills/cotutor-analyze/references//345/221/275/344/273/244/344/270/216/346/226/207/344/273/266.md +31 -0
  793. package/skills/cotutor-board/SKILL.md +373 -0
  794. package/skills/cotutor-board/references/README.md +38 -0
  795. package/skills/cotutor-board/references/canvas.md +68 -0
  796. package/skills/cotutor-board/references/choice.md +55 -0
  797. package/skills/cotutor-board/references/code.md +46 -0
  798. package/skills/cotutor-board/references/image.md +52 -0
  799. package/skills/cotutor-board/references/lecture.md +69 -0
  800. package/skills/cotutor-board/references/paint.md +77 -0
  801. package/skills/cotutor-board/references/photo.md +61 -0
  802. package/skills/cotutor-board/references/read.md +51 -0
  803. package/skills/cotutor-board/references/text.md +69 -0
  804. package/skills/cotutor-board/references/tianzige.md +78 -0
  805. package/skills/cotutor-board/references/word.md +91 -0
  806. package/skills/cotutor-home/SKILL.md +169 -0
  807. package/skills/cotutor-home/references/dictation.md +97 -0
  808. package/skills/cotutor-home/references/tutor.md +148 -0
  809. package/skills/cotutor-home/references//345/221/275/344/273/244.md +21 -0
  810. package/skills/cotutor-home/references//351/246/226/351/241/265/350/257/255/346/263/225.md +142 -0
  811. package/skills/cotutor-tune/SKILL.md +147 -0
  812. package/skills/cotutor-tune/references//345/255/227/346/256/265.md +50 -0
  813. package/skills/cotutor-tutor/SKILL.md +261 -0
  814. package/skills/cotutor-tutor/references//344/270/212/344/270/213/346/226/207/345/214/205.md +78 -0
  815. package/themes/default/kid.css +86 -0
  816. package/themes/default/theme.json +26 -0
  817. package/agents/chinese-teacher.md +0 -19
  818. package/agents/homework-aide.md +0 -17
  819. package/agents/math-teacher.md +0 -19
  820. package/agents/planner.md +0 -18
  821. package/agents/reading-teacher.md +0 -19
  822. package/dist/cli/doctor.d.ts +0 -19
  823. package/dist/cli/doctor.js +0 -190
  824. package/dist/cli/init.js +0 -114
  825. package/dist/cli/main.js +0 -123
  826. package/dist/cli/serve.d.ts +0 -19
  827. package/dist/cli/serve.js +0 -22
  828. package/dist/cli/skeleton.d.ts +0 -21
  829. package/dist/cli/skeleton.js +0 -82
  830. package/dist/cli/workspace.d.ts +0 -61
  831. package/dist/lib/agent-file.d.ts +0 -10
  832. package/dist/lib/agent-file.js +0 -16
  833. package/dist/lib/context-pack.js +0 -46
  834. package/dist/lib/conversation.d.ts +0 -28
  835. package/dist/lib/conversation.js +0 -44
  836. package/dist/lib/kid-view.d.ts +0 -26
  837. package/dist/lib/kid-view.js +0 -38
  838. package/dist/lib/ledger.d.ts +0 -21
  839. package/dist/lib/sections.d.ts +0 -12
  840. package/dist/lib/sections.js +0 -151
  841. package/dist/lib/transcript.d.ts +0 -36
  842. package/dist/lib/transcript.js +0 -95
  843. package/dist/server/app.d.ts +0 -13
  844. package/dist/server/app.js +0 -45
  845. /package/dist/{cli → app/cli}/main.d.ts +0 -0
@@ -0,0 +1,58 @@
1
+ /**
2
+ * 字形资源包的数据面(小写拉丁字母,print 分写体)。
3
+ *
4
+ * 归一化坐标系与四线三格严格对齐(kid-canvas Write.tsx 的采集面同一套):
5
+ * x 高 = 1 个单位,基线 y = 0,y 向上为负。
6
+ *
7
+ * y = -2 top 升部顶(b d f h k l t)
8
+ * y = -1 xTop x 高顶
9
+ * y = 0 base 基线
10
+ * y = +1 bottom 降部底(g j p q y)
11
+ *
12
+ * 每个字形自己的左边界是 x = 0,advance 是墨迹宽度(不含字间距,
13
+ * 字间距由排版方按 letterSpacing 给)。消费方乘 xHeight 换算成 px。
14
+ *
15
+ * 笔画顺序 = 数组顺序 = 教学笔顺;一笔之内的段首尾相接。
16
+ */
17
+ /** 直线到 (x, y) */
18
+ export interface SegLine {
19
+ k: 'L';
20
+ to: readonly [number, number];
21
+ }
22
+ /**
23
+ * 椭圆弧。参数式 x = cx + rx·cos θ、y = cy + ry·sin θ(角度制)。
24
+ * 屏幕坐标 y 向下为正,故 θ 递增 = 顺时针,θ 递减 = 逆时针
25
+ * (写 o、a、c 的圈都是逆时针,即 a1 < a0)。
26
+ * 弧的起点必须与前一段的终点重合,由 letters.test.ts 的连续性断言把关。
27
+ */
28
+ export interface SegArc {
29
+ k: 'A';
30
+ cx: number;
31
+ cy: number;
32
+ rx: number;
33
+ ry: number;
34
+ /** 起始角(度) */
35
+ a0: number;
36
+ /** 终止角(度) */
37
+ a1: number;
38
+ }
39
+ /** 三次贝塞尔到 to,控制点 c1、c2(s、r、t 的钩这类不规则曲线用) */
40
+ export interface SegCubic {
41
+ k: 'C';
42
+ c1: readonly [number, number];
43
+ c2: readonly [number, number];
44
+ to: readonly [number, number];
45
+ }
46
+ export type Seg = SegLine | SegArc | SegCubic;
47
+ /** 一笔:从 start 起,依次走完 segs */
48
+ export interface GlyphStroke {
49
+ start: readonly [number, number];
50
+ segs: readonly Seg[];
51
+ }
52
+ export interface Glyph {
53
+ ch: string;
54
+ /** 墨迹宽度(x 高为 1 单位),排版按此前进 */
55
+ advance: number;
56
+ /** 笔画序列,数组顺序即笔顺 */
57
+ strokes: readonly GlyphStroke[];
58
+ }
@@ -0,0 +1,17 @@
1
+ /**
2
+ * 字形资源包的数据面(小写拉丁字母,print 分写体)。
3
+ *
4
+ * 归一化坐标系与四线三格严格对齐(kid-canvas Write.tsx 的采集面同一套):
5
+ * x 高 = 1 个单位,基线 y = 0,y 向上为负。
6
+ *
7
+ * y = -2 top 升部顶(b d f h k l t)
8
+ * y = -1 xTop x 高顶
9
+ * y = 0 base 基线
10
+ * y = +1 bottom 降部底(g j p q y)
11
+ *
12
+ * 每个字形自己的左边界是 x = 0,advance 是墨迹宽度(不含字间距,
13
+ * 字间距由排版方按 letterSpacing 给)。消费方乘 xHeight 换算成 px。
14
+ *
15
+ * 笔画顺序 = 数组顺序 = 教学笔顺;一笔之内的段首尾相接。
16
+ */
17
+ export {};
@@ -0,0 +1,23 @@
1
+ /**
2
+ * chalk —— 画面引擎(2026-10-31 从 drawtell 并进来,历史在 git log 里):纯计算,不碰 DOM、不带 React,服务端、命令、舞台都能 import。
3
+ * 时钟(课的第 t 毫秒是什么样)、几何(包围盒,文字按量好的字宽)、圈住了什么、擦掉与换画板、烤好的画面怎么逐笔露出来。
4
+ * 课包怎么读(parseBundle)、元素交给 excalidraw 前怎么预处理(prepareSkeletons)也在这里;场景检查在 check.ts,字母笔顺在 glyphs/。
5
+ * 只能在浏览器里跑的(画烤好的画面 mountBaked、用 excalidraw 烤)在 src/ui/stage/chalk/;做课包的命令在 src/app/cli/chalk/(cotutor chalk)。
6
+ */
7
+ export { lessonClock, clockAt, frameAt, elementsAtSvgTime, boardAtSvgTime } from './clock.ts';
8
+ export type { LessonClock, LessonSegment, LessonFrame, FrameElement, ElementWindow } from './clock.ts';
9
+ export { isAction, resolveActions, finalBoard } from './actions.ts';
10
+ export type { ResolvedActions, ResolvedBoard } from './actions.ts';
11
+ export { charEm, measureText, elementBounds, sceneBounds, unionBounds, boundsGap, samplePoints, insidePolygon, boundsOfPoints, pointsOf } from './geometry.ts';
12
+ export type { Bounds, BoundsTuple } from './geometry.ts';
13
+ export { circleHits, describeCircle, hitPhrase, colorWord } from './circle.ts';
14
+ export type { CircleHit, CircleResult, LessonPicture } from './circle.ts';
15
+ export { BAKE_VERSION, actionState, boardOf, paintElement, renderFrameSvg, bakedPaths, strokeGroups, progressMap, pointerBox, pictureHash, bakeMatches } from './paint.ts';
16
+ export type { ActionState, BakedBoard, BakedLesson, BakedPicture, BakedElement, BakedNode, ElementPaint, PathPaint, FrameProgress, RenderOptions } from './paint.ts';
17
+ export { parseBundle, assembleBundle, BundleError } from './bundle.ts';
18
+ export type { LessonBundle } from './bundle.ts';
19
+ export { prepareSkeletons, isEraser } from './prepare.ts';
20
+ export { CHAR_EM, CJK_EM, FALLBACK_EM, LINE_HEIGHT } from './text-metrics.ts';
21
+ export { computeStepWindows, durationOf, freezeTimeSec, FREEZE_EPS_MS, START_MS, stretchToAudio } from './timeline.ts';
22
+ export type { StretchInfo, StepWindow } from './timeline.ts';
23
+ export type { ChalkScene, ChalkSkeleton, ChalkErase, ChalkBoard, ChalkStep, ChalkBlock, ChalkGroup, ChalkSubscene, ChalkBackground } from './types.ts';
@@ -0,0 +1,15 @@
1
+ /**
2
+ * chalk —— 画面引擎(2026-10-31 从 drawtell 并进来,历史在 git log 里):纯计算,不碰 DOM、不带 React,服务端、命令、舞台都能 import。
3
+ * 时钟(课的第 t 毫秒是什么样)、几何(包围盒,文字按量好的字宽)、圈住了什么、擦掉与换画板、烤好的画面怎么逐笔露出来。
4
+ * 课包怎么读(parseBundle)、元素交给 excalidraw 前怎么预处理(prepareSkeletons)也在这里;场景检查在 check.ts,字母笔顺在 glyphs/。
5
+ * 只能在浏览器里跑的(画烤好的画面 mountBaked、用 excalidraw 烤)在 src/ui/stage/chalk/;做课包的命令在 src/app/cli/chalk/(cotutor chalk)。
6
+ */
7
+ export { lessonClock, clockAt, frameAt, elementsAtSvgTime, boardAtSvgTime } from "./clock.js";
8
+ export { isAction, resolveActions, finalBoard } from "./actions.js";
9
+ export { charEm, measureText, elementBounds, sceneBounds, unionBounds, boundsGap, samplePoints, insidePolygon, boundsOfPoints, pointsOf } from "./geometry.js";
10
+ export { circleHits, describeCircle, hitPhrase, colorWord } from "./circle.js";
11
+ export { BAKE_VERSION, actionState, boardOf, paintElement, renderFrameSvg, bakedPaths, strokeGroups, progressMap, pointerBox, pictureHash, bakeMatches } from "./paint.js";
12
+ export { parseBundle, assembleBundle, BundleError } from "./bundle.js";
13
+ export { prepareSkeletons, isEraser } from "./prepare.js";
14
+ export { CHAR_EM, CJK_EM, FALLBACK_EM, LINE_HEIGHT } from "./text-metrics.js";
15
+ export { computeStepWindows, durationOf, freezeTimeSec, FREEZE_EPS_MS, START_MS, stretchToAudio } from "./timeline.js";
@@ -0,0 +1,41 @@
1
+ /**
2
+ * 课包(lesson bundle)输出契约 —— build 的产物,serve/播放器的输入。
3
+ * 自包含目录:scene.json + manifest.json(+ audio/,TTS 就绪后)。
4
+ * 前身是 growth-apps packages/schema 的 LessonManifestDraft,随架构重设计迁入并定版 v1。
5
+ */
6
+ import type { ChalkBlock, ChalkGroup, ChalkScene, ChalkStep, ChalkSubscene } from './types.ts';
7
+ export interface SceneJson {
8
+ schema: 'chalk-scene';
9
+ version: 1;
10
+ id: string;
11
+ title: string;
12
+ problem: string;
13
+ model: string;
14
+ template: ChalkScene['template'];
15
+ subject?: string;
16
+ /** 背景图;src 相对课包目录(build 拷进来的 background.<ext>) */
17
+ background?: ChalkScene['background'];
18
+ skeletons: ChalkScene['skeletons'];
19
+ /** 元素分组(语义);画面的一部分,所以在 scene.json 不在 manifest */
20
+ groups?: ChalkGroup[];
21
+ /**
22
+ * build 时量好的每个元素的包围盒(场景坐标,[minX, minY, maxX, maxY]):文字按 core/text-metrics 的字宽算,
23
+ * 线按点、框按宽高。浏览器外的消费方(应用的服务端、检验)不用再估;播放器不读它。
24
+ */
25
+ bounds?: Record<string, [number, number, number, number]>;
26
+ }
27
+ /**
28
+ * 切分线:scene.json = 静态画面(家长在编辑器看到的),manifest = 怎么播、怎么交互。
29
+ * v2 新增的 blocks(圈词命中)与 subscenes(弹窗)都是交互,随 steps 落 manifest;
30
+ * 子场景连几何一起整体落这里——弹窗不属于主画面,拆两半反而破坏自包含。
31
+ * v1 课包(无 blocks/subscenes,steps 恒非空)读取路径不变,照常可播。
32
+ */
33
+ export interface LessonManifest {
34
+ schema: 'lesson-manifest';
35
+ version: 2;
36
+ steps: LessonStep[];
37
+ blocks?: ChalkBlock[];
38
+ subscenes?: ChalkSubscene[];
39
+ }
40
+ /** line 兼作字幕;audioSrc 指向课包内 audio/ 文件,audioDurationMs 是它的时长(dub 写入,与 audioSrc 同生命周期) */
41
+ export type LessonStep = Pick<ChalkStep, 'step' | 'elementIds' | 'line' | 'pauseAfter' | 'audioSrc' | 'audioDurationMs'>;
@@ -0,0 +1,6 @@
1
+ /**
2
+ * 课包(lesson bundle)输出契约 —— build 的产物,serve/播放器的输入。
3
+ * 自包含目录:scene.json + manifest.json(+ audio/,TTS 就绪后)。
4
+ * 前身是 growth-apps packages/schema 的 LessonManifestDraft,随架构重设计迁入并定版 v1。
5
+ */
6
+ export {};
@@ -0,0 +1,180 @@
1
+ /**
2
+ * 烤好的课包画面(bake.json,drawtell 重新设计的第 4 步):excalidraw 在 build 之后、在浏览器里只跑一次(cotutor chalk bake),
3
+ * 把每个元素的静态 SVG 节点、每条路径的长度、笔尖走的轨迹、内嵌字体存下来;播放时不再有 excalidraw 与 SMIL,
4
+ * 某一刻的画面 = 每个元素画了多少(frameAt 的 progress)→ 描边画到哪(stroke-dashoffset)、字露到哪(裁剪框)。
5
+ * 时长不进 bake:配音、拉伸只改时钟,画面变了才要重烤(source.hash 对不上)。
6
+ *
7
+ * 本文件纯计算:类型、一个元素在 progress p 时怎么画(paintElement)、整幅画面拼成 SVG 字符串(renderFrameSvg,服务端出缩略图用)。
8
+ * 浏览器里的增量渲染在 src/ui/stage/chalk/render.ts(同一份 paintElement)。
9
+ */
10
+ import type { LessonFrame } from './clock.ts';
11
+ /** 一个 SVG 节点(元素静态导出的样子,原样存属性);路径多存长度,好按描边揭示 */
12
+ export interface BakedNode {
13
+ tag: string;
14
+ attrs: Record<string, string>;
15
+ /** text / tspan 的字 */
16
+ text?: string;
17
+ children?: BakedNode[];
18
+ /** path 的总长(SVG 坐标):有描边的路径按它揭示 */
19
+ len?: number;
20
+ /**
21
+ * 同一笔的第几遍:手绘(rough.js)每一笔描两遍,bake 把两遍拆成两条 path,pass 相同的一起画(同 excalidraw-animate);
22
+ * 没有 = 自己一拨
23
+ */
24
+ pass?: number;
25
+ }
26
+ export interface BakedElement {
27
+ id: string;
28
+ /** 顶层节点(excalidraw 每个元素导出成一个 <g>) */
29
+ node: BakedNode;
30
+ /** 文字的揭示框(元素局部坐标,即 <g> transform 之内):从左往右露 */
31
+ reveal?: {
32
+ width: number;
33
+ height: number;
34
+ };
35
+ /** 笔尖走的轨迹(SVG 坐标):[x, y, 走到这里是全程的几分之几] */
36
+ track: [number, number, number][];
37
+ /** 橡皮那一笔:笔尖换成橡皮(擦除、换画板这两种动作也是) */
38
+ eraser?: boolean;
39
+ /**
40
+ * 笔顺里的动作(core/actions.ts):不画东西(node 是空的 <g>),轨迹是橡皮来回走的路。
41
+ * erase 做的时候 targets 渐渐淡掉、做完不见;board 一样擦掉 targets(旧板上的全部),做完换到下一块画板
42
+ */
43
+ action?: 'erase' | 'board';
44
+ targets?: string[];
45
+ }
46
+ /** 一块画板:自己的视口(SVG 坐标)与背景图 */
47
+ export interface BakedBoard {
48
+ viewBox: [number, number, number, number];
49
+ background?: {
50
+ src: string;
51
+ x: number;
52
+ y: number;
53
+ width: number;
54
+ height: number;
55
+ };
56
+ }
57
+ /**
58
+ * bake.json 的格式版本;画法变了就加一,旧的一律当没烤(应用后台重烤、snap 顺手重烤)。
59
+ * 2(2026-10-07):手绘一笔的两遍拆成两条 path、记 pass,一起画——1 的两遍先后画,笔画完一遍跳回起点再画,看着像抖
60
+ */
61
+ export declare const BAKE_VERSION = 2;
62
+ export interface BakedLesson {
63
+ /** 格式名照旧(并进 cotutor 之前就是它):改了已经烤好的课包全都要重烤 */
64
+ schema: 'drawtell-bake';
65
+ version: typeof BAKE_VERSION;
66
+ /** 烤它的 excalidraw 版本、画面的 hash(scene.json 的 skeletons 与 background;变了要重烤) */
67
+ source: {
68
+ excalidraw: string;
69
+ hash: string;
70
+ };
71
+ viewBox: [number, number, number, number];
72
+ /** 场景坐标 → SVG 坐标的平移(导出时留了白、整体挪过) */
73
+ offset: [number, number];
74
+ /** 导出时内嵌的字体(@font-face,data URI) */
75
+ fonts: string;
76
+ /** <defs> 里字体以外的东西(箭头的遮罩之类),原样 */
77
+ defs: string;
78
+ /** 背景图:src 相对课包目录,x/y/width/height 是 SVG 坐标 */
79
+ background?: {
80
+ src: string;
81
+ x: number;
82
+ y: number;
83
+ width: number;
84
+ height: number;
85
+ };
86
+ /**
87
+ * 换过画板的课才有:每块画板的视口与背景图(第 0 块 = 上面的 viewBox / background)。
88
+ * 所有画板的元素在同一个 SVG 坐标里(同一个 offset),换板只换视口与背景
89
+ */
90
+ boards?: BakedBoard[];
91
+ elements: BakedElement[];
92
+ }
93
+ /**
94
+ * 画面的指纹:scene.json 里决定画面的那几样(skeletons、background),按 JSON 原样算(FNV-1a,两路 32 位拼 16 位十六进制)。
95
+ * 纯 JS:播放页拿到 scene.json 与 bake.json 自己对一下,对不上(画面改过、没重烤)就别用这份烤好的。
96
+ */
97
+ export declare function pictureHash(sceneJson: {
98
+ skeletons?: unknown;
99
+ background?: unknown;
100
+ }): string;
101
+ /** 这份烤好的画面是不是这份 scene.json 的 */
102
+ export declare function bakeMatches(baked: unknown, sceneJson: {
103
+ skeletons?: unknown;
104
+ background?: unknown;
105
+ }): baked is BakedLesson;
106
+ /** 只要画面(不管是哪个 excalidraw 烤的、对的哪份画面):播放与出图只用到这些 */
107
+ export type BakedPicture = Omit<BakedLesson, 'source'>;
108
+ /** 一条路径在 progress p 时的样子 */
109
+ export interface PathPaint {
110
+ /** 描边揭示:dasharray = len,dashoffset = len × (1 − 画了多少);全画完 = 不设 */
111
+ dash?: {
112
+ len: number;
113
+ offset: number;
114
+ };
115
+ /** 没法描边揭示的(实心填充、虚线):淡入 */
116
+ opacity?: number;
117
+ }
118
+ /** 一个元素在 progress p 时的样子:visible = 开始画了;paths 按深度优先的顺序对着元素里的每条 path;clip = 文字露出的宽 */
119
+ export interface ElementPaint {
120
+ visible: boolean;
121
+ done: boolean;
122
+ paths: PathPaint[];
123
+ clip?: number;
124
+ /** 笔尖在哪(SVG 坐标);没在画 = 没有 */
125
+ pointer?: [number, number];
126
+ }
127
+ /** 元素里的 path,深度优先;stroke 继承父节点 */
128
+ export declare function bakedPaths(node: BakedNode): {
129
+ node: BakedNode;
130
+ stroke: boolean;
131
+ dashed: boolean;
132
+ }[];
133
+ /** 有描边的路径分拨:pass 相同、挨着的一拨一起画,拨与拨首尾相接;一拨的长度取最长的那条 */
134
+ export declare function strokeGroups(paths: readonly {
135
+ node: BakedNode;
136
+ stroke: boolean;
137
+ }[]): {
138
+ idx: number[];
139
+ len: number;
140
+ }[];
141
+ export declare function paintElement(el: BakedElement, p: number): ElementPaint;
142
+ /** 一刻的进度:frameAt 的结果(或只有 elements 的,如 { elements: elementsAtSvgTime(…) }),或 id → progress */
143
+ export type FrameProgress = Pick<LessonFrame, 'elements'> | ReadonlyMap<string, number>;
144
+ export declare function progressMap(frame: FrameProgress): ReadonlyMap<string, number>;
145
+ /**
146
+ * 动作做到哪,画面就怎样(只看 progress,渲染端各自算,和 core 的时钟同一个规矩):
147
+ * 在第几块画板(做完了几个换画板);谁正在被擦(还剩几成)、谁擦完了(0);旧板的背景图跟着淡掉。
148
+ */
149
+ export interface ActionState {
150
+ board: number;
151
+ /** 当前画板背景图的不透明度(换画板做着的时候 1 → 0) */
152
+ backgroundOpacity: number;
153
+ /** 被擦的元素 → 还剩几成(0 = 擦完了,不画);不在里面 = 没在擦 */
154
+ fade: Map<string, number>;
155
+ }
156
+ export declare function actionState(baked: Pick<BakedPicture, 'elements'>, prog: ReadonlyMap<string, number>): ActionState;
157
+ /** 第 k 块画板的视口与背景图(没换过画板的课只有第 0 块) */
158
+ export declare function boardOf(baked: Pick<BakedPicture, 'viewBox' | 'background' | 'boards'>, k: number): BakedBoard;
159
+ export interface RenderOptions {
160
+ /** 背景图的 URL(bake 里存的是相对课包目录的 src;服务端给 /api/bundles/<id>/…);只管第 0 块画板,换过画板的课用 assetHref */
161
+ backgroundHref?: string;
162
+ /** 课包里的文件(背景图的 src)→ URL;给了就用它,每块画板的背景图都能出 */
163
+ assetHref?: (src: string) => string | undefined;
164
+ /** 再叠一层(圈的卡:孩子的圈);SVG 坐标 */
165
+ overlay?: string;
166
+ /** 画不画笔尖(铅笔;橡皮那一笔是橡皮);缺省不画 */
167
+ pointer?: boolean;
168
+ }
169
+ /**
170
+ * 整幅画面在这一刻的 SVG 字符串(服务端出缩略图、测试用):没开始画的元素不出,画到一半的按 paintElement 揭示。
171
+ * 字体原样内嵌,<img> 里也显示得对。
172
+ */
173
+ export declare function renderFrameSvg(baked: BakedPicture, frame: FrameProgress, opts?: RenderOptions): string;
174
+ /** 笔尖:铅笔的尖在图片 (0,0);橡皮的擦除端在 (5,5)(pointer.ts) */
175
+ export declare function pointerBox(at: readonly [number, number], eraser: boolean): {
176
+ href: string;
177
+ x: number;
178
+ y: number;
179
+ size: number;
180
+ };
@@ -0,0 +1,210 @@
1
+ /**
2
+ * 烤好的课包画面(bake.json,drawtell 重新设计的第 4 步):excalidraw 在 build 之后、在浏览器里只跑一次(cotutor chalk bake),
3
+ * 把每个元素的静态 SVG 节点、每条路径的长度、笔尖走的轨迹、内嵌字体存下来;播放时不再有 excalidraw 与 SMIL,
4
+ * 某一刻的画面 = 每个元素画了多少(frameAt 的 progress)→ 描边画到哪(stroke-dashoffset)、字露到哪(裁剪框)。
5
+ * 时长不进 bake:配音、拉伸只改时钟,画面变了才要重烤(source.hash 对不上)。
6
+ *
7
+ * 本文件纯计算:类型、一个元素在 progress p 时怎么画(paintElement)、整幅画面拼成 SVG 字符串(renderFrameSvg,服务端出缩略图用)。
8
+ * 浏览器里的增量渲染在 src/ui/stage/chalk/render.ts(同一份 paintElement)。
9
+ */
10
+ import { DEFAULT_POINTER_IMG, ERASER_POINTER_IMG } from "./pointer.js";
11
+ /**
12
+ * bake.json 的格式版本;画法变了就加一,旧的一律当没烤(应用后台重烤、snap 顺手重烤)。
13
+ * 2(2026-10-07):手绘一笔的两遍拆成两条 path、记 pass,一起画——1 的两遍先后画,笔画完一遍跳回起点再画,看着像抖
14
+ */
15
+ export const BAKE_VERSION = 2;
16
+ /**
17
+ * 画面的指纹:scene.json 里决定画面的那几样(skeletons、background),按 JSON 原样算(FNV-1a,两路 32 位拼 16 位十六进制)。
18
+ * 纯 JS:播放页拿到 scene.json 与 bake.json 自己对一下,对不上(画面改过、没重烤)就别用这份烤好的。
19
+ */
20
+ export function pictureHash(sceneJson) {
21
+ const s = JSON.stringify({ skeletons: sceneJson.skeletons ?? [], background: sceneJson.background ?? null });
22
+ let a = 0x811c9dc5;
23
+ let b = 0x01000193 ^ s.length;
24
+ for (let i = 0; i < s.length; i++) {
25
+ const c = s.charCodeAt(i);
26
+ a = Math.imul(a ^ c, 0x01000193) >>> 0;
27
+ b = Math.imul(b ^ c, 0x5bd1e995) >>> 0;
28
+ }
29
+ return a.toString(16).padStart(8, '0') + b.toString(16).padStart(8, '0');
30
+ }
31
+ /** 这份烤好的画面是不是这份 scene.json 的 */
32
+ export function bakeMatches(baked, sceneJson) {
33
+ const b = baked;
34
+ return Boolean(b && b.schema === 'drawtell-bake' && b.version === BAKE_VERSION && b.source?.hash === pictureHash(sceneJson));
35
+ }
36
+ const isNone = (v) => v === undefined || v === 'none' || v === 'transparent' || v === '';
37
+ /** 元素里的 path,深度优先;stroke 继承父节点 */
38
+ export function bakedPaths(node) {
39
+ const out = [];
40
+ const walk = (n, stroke, dash) => {
41
+ const s = n.attrs.stroke ?? stroke;
42
+ const d = n.attrs['stroke-dasharray'] ?? dash;
43
+ if (n.tag === 'path')
44
+ out.push({ node: n, stroke: !isNone(s) && (n.len ?? 0) > 0, dashed: !isNone(d) });
45
+ for (const c of n.children ?? [])
46
+ walk(c, s, d);
47
+ };
48
+ walk(node, undefined, undefined);
49
+ return out;
50
+ }
51
+ /** 有描边的路径分拨:pass 相同、挨着的一拨一起画,拨与拨首尾相接;一拨的长度取最长的那条 */
52
+ export function strokeGroups(paths) {
53
+ const out = [];
54
+ paths.forEach((x, i) => {
55
+ if (!x.stroke)
56
+ return;
57
+ const last = out[out.length - 1];
58
+ const prev = last ? paths[last.idx[last.idx.length - 1]] : undefined;
59
+ if (last && x.node.pass !== undefined && last.pass === x.node.pass && prev && last.idx[last.idx.length - 1] === i - 1) {
60
+ last.idx.push(i);
61
+ last.len = Math.max(last.len, x.node.len ?? 0);
62
+ }
63
+ else
64
+ out.push({ idx: [i], len: x.node.len ?? 0, ...(x.node.pass !== undefined ? { pass: x.node.pass } : {}) });
65
+ });
66
+ return out.map(({ idx, len }) => ({ idx, len }));
67
+ }
68
+ /** 实心填充(没法描边揭示)从 progress 多少开始淡入 */
69
+ const FILL_FROM = 0.7;
70
+ /** 画到多少以后笔尖收起 */
71
+ const POINTER_UNTIL = 0.99;
72
+ const clamp01 = (x) => Math.max(0, Math.min(1, x));
73
+ export function paintElement(el, p) {
74
+ const paths = bakedPaths(el.node);
75
+ if (!(p > 0))
76
+ return { visible: false, done: false, paths: paths.map(() => ({})) };
77
+ const done = p >= 1;
78
+ if (done)
79
+ return { visible: true, done: true, paths: paths.map(() => ({})), ...(el.reveal ? { clip: el.reveal.width } : {}) };
80
+ // 有描边的路径(虚线也算)一拨一拨首尾相接,同一拨(同一笔的两遍)一起画;虚线没法描边揭示,轮到它就整条出现;
81
+ // 还没轮到的整条藏起来(round 线帽画零长的虚线会露一个点);实心填充最后一段淡入
82
+ const groups = strokeGroups(paths);
83
+ const total = groups.reduce((a, g) => a + g.len, 0);
84
+ const drawn = p * total;
85
+ const paints = paths.map(() => ({ opacity: total > 0 ? clamp01((p - FILL_FROM) / (1 - FILL_FROM)) : p }));
86
+ let at = 0;
87
+ for (const g of groups) {
88
+ const q = g.len > 0 ? clamp01((drawn - at) / g.len) : 1;
89
+ at += g.len;
90
+ for (const i of g.idx) {
91
+ const len = paths[i].node.len;
92
+ paints[i] = q <= 0 ? { opacity: 0 } : paths[i].dashed ? {} : q >= 1 ? {} : { dash: { len, offset: len * (1 - q) } };
93
+ }
94
+ }
95
+ // 笔尖只在真画着的时候出现:步尾定格停在画完前半毫秒(p ≈ 0.999),笔不该杵在那儿
96
+ return { visible: true, done: false, paths: paints, ...(el.reveal ? { clip: el.reveal.width * p } : {}), ...(p < POINTER_UNTIL ? (trackAt(el.track, p) ?? {}) : {}) };
97
+ }
98
+ /** 笔尖:轨迹上走到 p 的那一点 */
99
+ function trackAt(track, p) {
100
+ if (!track.length)
101
+ return null;
102
+ let i = track.findIndex((t) => t[2] >= p);
103
+ if (i < 0)
104
+ i = track.length - 1;
105
+ if (i === 0)
106
+ return { pointer: [track[0][0], track[0][1]] };
107
+ const [x0, y0, f0] = track[i - 1];
108
+ const [x1, y1, f1] = track[i];
109
+ const k = f1 > f0 ? (p - f0) / (f1 - f0) : 1;
110
+ return { pointer: [x0 + (x1 - x0) * k, y0 + (y1 - y0) * k] };
111
+ }
112
+ export function progressMap(frame) {
113
+ return 'elements' in frame ? new Map(frame.elements.map((e) => [e.id, e.progress])) : frame;
114
+ }
115
+ export function actionState(baked, prog) {
116
+ let board = 0;
117
+ let backgroundOpacity = 1;
118
+ const fade = new Map();
119
+ for (const el of baked.elements) {
120
+ if (!el.action)
121
+ continue;
122
+ const p = prog.get(el.id) ?? 0;
123
+ if (!(p > 0))
124
+ continue;
125
+ const left = p >= 1 ? 0 : 1 - p;
126
+ for (const id of el.targets ?? [])
127
+ fade.set(id, Math.min(fade.get(id) ?? 1, left));
128
+ if (el.action === 'board') {
129
+ if (p >= 1) {
130
+ board++;
131
+ backgroundOpacity = 1;
132
+ }
133
+ else
134
+ backgroundOpacity = left;
135
+ }
136
+ }
137
+ return { board, backgroundOpacity, fade };
138
+ }
139
+ /** 第 k 块画板的视口与背景图(没换过画板的课只有第 0 块) */
140
+ export function boardOf(baked, k) {
141
+ const b = baked.boards?.[k];
142
+ if (b)
143
+ return b;
144
+ return { viewBox: baked.viewBox, ...(baked.background ? { background: baked.background } : {}) };
145
+ }
146
+ const esc = (s) => s.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;');
147
+ const attrText = (attrs) => Object.entries(attrs).map(([k, v]) => ` ${k}="${esc(v)}"`).join('');
148
+ function nodeSvg(n, paintOf) {
149
+ const pp = paintOf.get(n);
150
+ const extra = {};
151
+ if (pp?.dash) {
152
+ extra['stroke-dasharray'] = `${round(pp.dash.len)} ${round(pp.dash.len)}`;
153
+ extra['stroke-dashoffset'] = String(round(pp.dash.offset));
154
+ }
155
+ if (pp?.opacity !== undefined && pp.opacity < 1)
156
+ extra.opacity = String(round(pp.opacity));
157
+ const inner = `${n.text !== undefined ? esc(n.text) : ''}${(n.children ?? []).map((c) => nodeSvg(c, paintOf)).join('')}`;
158
+ return `<${n.tag}${attrText({ ...n.attrs, ...extra })}>${inner}</${n.tag}>`;
159
+ }
160
+ const round = (n) => Math.round(n * 100) / 100;
161
+ /**
162
+ * 整幅画面在这一刻的 SVG 字符串(服务端出缩略图、测试用):没开始画的元素不出,画到一半的按 paintElement 揭示。
163
+ * 字体原样内嵌,<img> 里也显示得对。
164
+ */
165
+ export function renderFrameSvg(baked, frame, opts = {}) {
166
+ const prog = progressMap(frame);
167
+ const act = actionState(baked, prog);
168
+ const board = boardOf(baked, act.board);
169
+ const [vx, vy, vw, vh] = board.viewBox;
170
+ const clips = [];
171
+ const body = [];
172
+ let pointer;
173
+ for (const el of baked.elements) {
174
+ const left = act.fade.get(el.id) ?? 1;
175
+ if (!(left > 0))
176
+ continue;
177
+ const pnt = paintElement(el, prog.get(el.id) ?? 0);
178
+ if (!pnt.visible)
179
+ continue;
180
+ const at = body.length;
181
+ const paths = bakedPaths(el.node);
182
+ const paintOf = new Map(paths.map((x, i) => [x.node, pnt.paths[i]]));
183
+ if (pnt.clip !== undefined && !pnt.done && el.reveal) {
184
+ const cid = `clip-${el.id}`;
185
+ clips.push(`<clipPath id="${esc(cid)}"><rect x="-2" y="${round(-el.reveal.height * 0.5)}" width="${round(pnt.clip + 2)}" height="${round(el.reveal.height * 2)}"/></clipPath>`);
186
+ const { tag, attrs, children, text } = el.node;
187
+ body.push(`<${tag}${attrText(attrs)}><g clip-path="url(#${esc(cid)})">${text !== undefined ? esc(text) : ''}${(children ?? []).map((c) => nodeSvg(c, paintOf)).join('')}</g></${tag}>`);
188
+ }
189
+ else
190
+ body.push(nodeSvg(el.node, paintOf));
191
+ if (left < 1)
192
+ body[at] = `<g opacity="${round(left)}">${body[at]}</g>`;
193
+ if (pnt.pointer && !pnt.done)
194
+ pointer = { at: pnt.pointer, eraser: Boolean(el.eraser) };
195
+ }
196
+ const b = board.background;
197
+ const href = b ? (opts.assetHref ? opts.assetHref(b.src) : act.board === 0 ? opts.backgroundHref : undefined) : undefined;
198
+ const bgOpacity = act.backgroundOpacity < 1 ? ` opacity="${round(act.backgroundOpacity)}"` : '';
199
+ const bg = b && href ? `<image href="${esc(href)}" x="${b.x}" y="${b.y}" width="${b.width}" height="${b.height}" preserveAspectRatio="none"${bgOpacity}/>` : '';
200
+ const pen = opts.pointer && pointer ? pointerSvg(pointer.at, pointer.eraser) : '';
201
+ return `<svg xmlns="http://www.w3.org/2000/svg" viewBox="${vx} ${vy} ${vw} ${vh}"><defs><style>${baked.fonts}</style>${baked.defs}${clips.join('')}</defs>${bg}${body.join('')}${opts.overlay ?? ''}${pen}</svg>`;
202
+ }
203
+ /** 笔尖:铅笔的尖在图片 (0,0);橡皮的擦除端在 (5,5)(pointer.ts) */
204
+ export function pointerBox(at, eraser) {
205
+ return eraser ? { href: ERASER_POINTER_IMG, x: at[0] - 5, y: at[1] - 5, size: 36 } : { href: DEFAULT_POINTER_IMG, x: at[0], y: at[1], size: 30 };
206
+ }
207
+ function pointerSvg(at, eraser) {
208
+ const b = pointerBox(at, eraser);
209
+ return `<image href="${esc(b.href)}" x="${round(b.x)}" y="${round(b.y)}" width="${b.size}" height="${b.size}"/>`;
210
+ }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * 默认笔尖:内联 SVG 铅笔,笔尖落在图片 (0,0)——animateMotion 沿路径移动的是图片原点。
3
+ * 视觉与 kid-canvas 的铅笔单工具呼应;粉笔味交给纸面配色。
4
+ */
5
+ export declare const ERASER_POINTER_IMG: string;
6
+ /** 纸面底色:与 chalk-player.css 的 .chalk-stage 同值;橡皮笔画缺省用它盖住旧笔迹 */
7
+ export declare const PAPER_COLOR = "#fffdf7";
8
+ export declare const DEFAULT_POINTER_IMG: string;
@@ -0,0 +1,21 @@
1
+ /**
2
+ * 默认笔尖:内联 SVG 铅笔,笔尖落在图片 (0,0)——animateMotion 沿路径移动的是图片原点。
3
+ * 视觉与 kid-canvas 的铅笔单工具呼应;粉笔味交给纸面配色。
4
+ */
5
+ const PENCIL_SVG = `<svg xmlns="http://www.w3.org/2000/svg" width="30" height="30" viewBox="0 0 30 30">
6
+ <g>
7
+ <polygon points="0,0 9,3 3,9" fill="#4a4a4a"/>
8
+ <rect x="5" y="1" width="22" height="8" rx="2" fill="#f2b634" stroke="#b98a2e" stroke-width="1" transform="rotate(45 5 1)"/>
9
+ </g>
10
+ </svg>`;
11
+ /** 橡皮:擦除端的中点落在图片 (5,5),由 excalidraw-io 用 x/y = -5 对回路径 */
12
+ const ERASER_SVG = `<svg xmlns="http://www.w3.org/2000/svg" width="36" height="36" viewBox="0 0 36 36">
13
+ <g transform="translate(5 5) rotate(45)">
14
+ <rect x="0" y="-6" width="30" height="12" rx="2.5" fill="#f6a5b4" stroke="#c2687a" stroke-width="1"/>
15
+ <rect x="11" y="-6" width="19" height="12" rx="1.5" fill="#4c7fd0" stroke="#345a9c" stroke-width="1"/>
16
+ </g>
17
+ </svg>`;
18
+ export const ERASER_POINTER_IMG = `data:image/svg+xml,${encodeURIComponent(ERASER_SVG)}`;
19
+ /** 纸面底色:与 chalk-player.css 的 .chalk-stage 同值;橡皮笔画缺省用它盖住旧笔迹 */
20
+ export const PAPER_COLOR = '#fffdf7';
21
+ export const DEFAULT_POINTER_IMG = `data:image/svg+xml,${encodeURIComponent(PENCIL_SVG)}`;
@@ -0,0 +1,11 @@
1
+ /**
2
+ * 场景元素交给 excalidraw 之前的预处理(纯函数,不 import excalidraw):
3
+ * 没给 seed 的按 id 派生(手绘抖动每次一样),橡皮笔画补纸色、不抖。
4
+ * bake 用它;应用把课包放进 excalidraw 编辑器(画板的底图)也该先过它,否则橡皮成了一道黑线、抖动每次不一样。
5
+ */
6
+ import type { ChalkSkeleton } from './types.ts';
7
+ export declare const isEraser: (el: {
8
+ customData?: unknown;
9
+ }) => boolean;
10
+ /** 稳定 seed + 橡皮的缺省外观;作者显式给的值优先 */
11
+ export declare function prepareSkeletons<T extends ChalkSkeleton>(skeletons: readonly T[]): T[];
@@ -0,0 +1,15 @@
1
+ /**
2
+ * 场景元素交给 excalidraw 之前的预处理(纯函数,不 import excalidraw):
3
+ * 没给 seed 的按 id 派生(手绘抖动每次一样),橡皮笔画补纸色、不抖。
4
+ * bake 用它;应用把课包放进 excalidraw 编辑器(画板的底图)也该先过它,否则橡皮成了一道黑线、抖动每次不一样。
5
+ */
6
+ import { PAPER_COLOR } from "./pointer.js";
7
+ import { seedFromId } from "./seed.js";
8
+ export const isEraser = (el) => el.customData?.tool === 'eraser';
9
+ /** 稳定 seed + 橡皮的缺省外观;作者显式给的值优先 */
10
+ export function prepareSkeletons(skeletons) {
11
+ return skeletons.map((el) => {
12
+ const withSeed = typeof el.seed === 'number' ? el : { ...el, seed: seedFromId(el.id) };
13
+ return isEraser(el) ? { strokeColor: PAPER_COLOR, roughness: 0, ...withSeed } : withSeed;
14
+ });
15
+ }