cotutor 0.4.3 → 0.4.4

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 (252) hide show
  1. package/CHANGELOG.md +39 -0
  2. package/README.md +32 -1
  3. package/dist/app/cli/root-ca.d.ts +8 -0
  4. package/dist/app/cli/root-ca.js +33 -0
  5. package/dist/app/cli/serve.d.ts +11 -2
  6. package/dist/app/cli/serve.js +49 -3
  7. package/dist/app/http/access.js +1 -1
  8. package/dist/app/http/app.js +4 -0
  9. package/dist/app/http/parent-home.js +5 -0
  10. package/dist/app/http/stage.js +2 -2
  11. package/dist/app/mock/mock.js +3 -0
  12. package/dist/stage/fonts/Assistant/Assistant-Bold.woff2 +0 -0
  13. package/dist/stage/fonts/Assistant/Assistant-Medium.woff2 +0 -0
  14. package/dist/stage/fonts/Assistant/Assistant-Regular.woff2 +0 -0
  15. package/dist/stage/fonts/Assistant/Assistant-SemiBold.woff2 +0 -0
  16. package/dist/stage/fonts/Cascadia/CascadiaCode-Regular.woff2 +0 -0
  17. package/dist/stage/fonts/ComicShanns/ComicShanns-Regular-279a7b317d12eb88de06167bd672b4b4.woff2 +0 -0
  18. package/dist/stage/fonts/ComicShanns/ComicShanns-Regular-6e066e8de2ac57ea9283adb9c24d7f0c.woff2 +0 -0
  19. package/dist/stage/fonts/ComicShanns/ComicShanns-Regular-dc6a8806fa96795d7b3be5026f989a17.woff2 +0 -0
  20. package/dist/stage/fonts/ComicShanns/ComicShanns-Regular-fcb0fc02dcbee4c9846b3e2508668039.woff2 +0 -0
  21. package/dist/stage/fonts/Excalifont/Excalifont-Regular-349fac6ca4700ffec595a7150a0d1e1d.woff2 +0 -0
  22. package/dist/stage/fonts/Excalifont/Excalifont-Regular-3f2c5db56cc93c5a6873b1361d730c16.woff2 +0 -0
  23. package/dist/stage/fonts/Excalifont/Excalifont-Regular-41b173a47b57366892116a575a43e2b6.woff2 +0 -0
  24. package/dist/stage/fonts/Excalifont/Excalifont-Regular-623ccf21b21ef6b3a0d87738f77eb071.woff2 +0 -0
  25. package/dist/stage/fonts/Excalifont/Excalifont-Regular-a88b72a24fb54c9f94e3b5fdaa7481c9.woff2 +0 -0
  26. package/dist/stage/fonts/Excalifont/Excalifont-Regular-b9dcf9d2e50a1eaf42fc664b50a3fd0d.woff2 +0 -0
  27. package/dist/stage/fonts/Excalifont/Excalifont-Regular-be310b9bcd4f1a43f571c46df7809174.woff2 +0 -0
  28. package/dist/stage/fonts/Liberation/LiberationSans-Regular.woff2 +0 -0
  29. package/dist/stage/fonts/Lilita/Lilita-Regular-i7dPIFZ9Zz-WBtRtedDbYE98RXi4EwSsbg.woff2 +0 -0
  30. package/dist/stage/fonts/Lilita/Lilita-Regular-i7dPIFZ9Zz-WBtRtedDbYEF8RXi4EwQ.woff2 +0 -0
  31. package/dist/stage/fonts/Nunito/Nunito-Regular-XRXI3I6Li01BKofiOc5wtlZ2di8HDIkhdTA3j6zbXWjgevT5.woff2 +0 -0
  32. package/dist/stage/fonts/Nunito/Nunito-Regular-XRXI3I6Li01BKofiOc5wtlZ2di8HDIkhdTQ3j6zbXWjgeg.woff2 +0 -0
  33. package/dist/stage/fonts/Nunito/Nunito-Regular-XRXI3I6Li01BKofiOc5wtlZ2di8HDIkhdTk3j6zbXWjgevT5.woff2 +0 -0
  34. package/dist/stage/fonts/Nunito/Nunito-Regular-XRXI3I6Li01BKofiOc5wtlZ2di8HDIkhdTo3j6zbXWjgevT5.woff2 +0 -0
  35. package/dist/stage/fonts/Nunito/Nunito-Regular-XRXI3I6Li01BKofiOc5wtlZ2di8HDIkhdTs3j6zbXWjgevT5.woff2 +0 -0
  36. package/dist/stage/fonts/Virgil/Virgil-Regular.woff2 +0 -0
  37. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-019d66dcad46dc156b162d267f981c20.woff2 +0 -0
  38. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-04b718e5623574919c8b0dea5f301444.woff2 +0 -0
  39. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-069e77aac84590e2e991d0a0176d34f2.woff2 +0 -0
  40. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-06c77b8c66e51ed6c63ccb502dd8b8af.woff2 +0 -0
  41. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-08e0dc436ad0ad61ba5558db0674d762.woff2 +0 -0
  42. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-093b9ef39a46ceae95a1df18a0a3a326.woff2 +0 -0
  43. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-095c169f3314805276f603a362766abd.woff2 +0 -0
  44. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-09850c4077f3fffe707905872e0e2460.woff2 +0 -0
  45. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-0986d134c05864f5025962eef9f994a0.woff2 +0 -0
  46. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-0b5d723fdc4e249c140f0909e87d03b4.woff2 +0 -0
  47. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-0f626226ba1272e832aea87bafd9720e.woff2 +0 -0
  48. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-0f7fb1e0d5015bb1371343153ecf7ce3.woff2 +0 -0
  49. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-0fa55a080fcd0f9dc2e0b0058b793df8.woff2 +0 -0
  50. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-0facdf1ea213ba40261022f5d5ed4493.woff2 +0 -0
  51. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-10a7ae9a371830a80c3d844acf1c02d7.woff2 +0 -0
  52. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-112c051027b2d766c19a519f6ee1f4f7.woff2 +0 -0
  53. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-11c345711937f0ba4b8f7b6b919c8440.woff2 +0 -0
  54. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-12b52b58eb3df36804b9a654ec9ee194.woff2 +0 -0
  55. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-13ae07ed2e272d26d59bc0691cd7117a.woff2 +0 -0
  56. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-13d2887ec8ee73c43acdabc52a05af7b.woff2 +0 -0
  57. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-145aa02cdd91946e67dc934e1acffe75.woff2 +0 -0
  58. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-15dc6d811c9cd078f9086a740d5a1038.woff2 +0 -0
  59. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-173945821411c09f70c95f98d590e697.woff2 +0 -0
  60. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-1b611157cd46bb184d4fa4dae2d6a2b8.woff2 +0 -0
  61. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-1e6fd68f1f3902ce48ce8c69df385622.woff2 +0 -0
  62. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-1ee544f0f1dac422545c505baa788992.woff2 +0 -0
  63. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-1fdc0c67ed57263a80fd108c1f6ccf24.woff2 +0 -0
  64. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-203b0e569e3b14aac86a003dc3fa523e.woff2 +0 -0
  65. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-20cc1bbf50e7efb442756cb605672c1f.woff2 +0 -0
  66. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-20e7bf72fa05de9adf7dbcc7bf51dde6.woff2 +0 -0
  67. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-21430ee05a1248901da8d0de08744d47.woff2 +0 -0
  68. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-23686f7f29da6e8008c36dd3a80c83d6.woff2 +0 -0
  69. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-23ad2d71b280f00b1363b95b7bea94eb.woff2 +0 -0
  70. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-23f228f3999c01983860012330e4be08.woff2 +0 -0
  71. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-24476a126f129212beb33f66853ea151.woff2 +0 -0
  72. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-24a21c1e4449222e8d1898d69ff3a404.woff2 +0 -0
  73. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-25b7f38e18f035f96cb5e547bd2bd08c.woff2 +0 -0
  74. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-29cec36cd205b211da97acabaa62f055.woff2 +0 -0
  75. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-2a26d20a23b00898ce82f09d2ee47c3f.woff2 +0 -0
  76. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-2adbc89c11e65905393d3dfc468b9d5b.woff2 +0 -0
  77. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-2b7441d46298788ac94e610ffcc709b6.woff2 +0 -0
  78. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-2b77e8ebfb2367ab2662396a60e7d320.woff2 +0 -0
  79. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-2cf96d082d35ea3d8106851223ad0d16.woff2 +0 -0
  80. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-2d43040e86ff03ba677f6f9c04cd0805.woff2 +0 -0
  81. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-2e33e8dc771ef5e1d9127d60a6b73679.woff2 +0 -0
  82. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-33432927cd87d40cfe393c7482bf221f.woff2 +0 -0
  83. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-353f33792a8f60dc69323ddf635a269e.woff2 +0 -0
  84. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-36925dfe329a45086cbb7fc5c20d45ac.woff2 +0 -0
  85. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-3717077e38f98d89eae729b6c14e56dc.woff2 +0 -0
  86. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-3756e81d3e149cf6099163ee79944fec.woff2 +0 -0
  87. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-395c35dd584b56b0789f58a0559beaf1.woff2 +0 -0
  88. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-3c9de2ae0ea4bc91a510942dfa4be8d2.woff2 +0 -0
  89. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-3cc70dbb64df5b21f1326cc24dee2195.woff2 +0 -0
  90. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-3e1f8f654357353bf0e04ba5c34b5f7f.woff2 +0 -0
  91. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-3e63ed8162808a9e425ed80a8bc79114.woff2 +0 -0
  92. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-3eaa538115d76932653c21d8dc28f207.woff2 +0 -0
  93. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-4095eb84ef3874e2600247bee0b04026.woff2 +0 -0
  94. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-41521fade99856108931b4768b1b2648.woff2 +0 -0
  95. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-450da755d5bcb70906e1295e559b9602.woff2 +0 -0
  96. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-452225341522a7942f0f6aab1a5c91a3.woff2 +0 -0
  97. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-4535823663ad81405188a528d8f2b1a2.woff2 +0 -0
  98. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-4806e761d750087c2d734fc64596eaff.woff2 +0 -0
  99. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-4a0fdb40036e87b40aa08dd30584cb85.woff2 +0 -0
  100. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-4a38cc3e9cf104e69ba246d37f8cf135.woff2 +0 -0
  101. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-4aca6a43e59aceee2166b0c7e4e85ef1.woff2 +0 -0
  102. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-4bfaa8ffa64c5ee560aa2daba7c9cbd3.woff2 +0 -0
  103. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-4dc6d5f188d5c96d44815cd1e81aa885.woff2 +0 -0
  104. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-4ddc14ed3eb0c3e46364317dfc0144a3.woff2 +0 -0
  105. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-4ee10ae43505e2e0bc62656ced49c0fa.woff2 +0 -0
  106. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-4f50e5136e136527280bc902c5817561.woff2 +0 -0
  107. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-51502f1206be09c565f1547c406e9558.woff2 +0 -0
  108. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-51a0e808bbc8361236ac521a119758a3.woff2 +0 -0
  109. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-52a84a22fd1369bffeaf21da2d6158dc.woff2 +0 -0
  110. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-5330a2119a716e4e7224ed108b085dac.woff2 +0 -0
  111. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-543fa46ace099a7099dad69123399400.woff2 +0 -0
  112. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-544fc28abe2c5c30e62383fd4dac255f.woff2 +0 -0
  113. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-54acdfc2166ad7fcbd074f75fd4a56ba.woff2 +0 -0
  114. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-5572b3513ba8df57a3d5d7303ee6b11b.woff2 +0 -0
  115. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-56467a5c8840c4d23a60b2f935114848.woff2 +0 -0
  116. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-56a32a7689abd0326e57c10c6c069bb4.woff2 +0 -0
  117. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-57862b464a55b18c7bf234ce22907d73.woff2 +0 -0
  118. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-583d166e56ba0de4b77eabb47ef67839.woff2 +0 -0
  119. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-5882ffa04f32584d26109137e2da4352.woff2 +0 -0
  120. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-58fd02350d0bc52cf1ca3bb32ce9766e.woff2 +0 -0
  121. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-5935a5775af3d5c6307ac667bd9ae74e.woff2 +0 -0
  122. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-59e9ff77b0efaf684bc09274fb6908c9.woff2 +0 -0
  123. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-5a1ce3117cfe90c48e8fb4a9a00f694d.woff2 +0 -0
  124. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-5a45d991244d4c7140217e1e5f5ca4f4.woff2 +0 -0
  125. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-5a7fac4b8b23a6e4e5ba0c9bf1756c91.woff2 +0 -0
  126. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-5b0ed6971aaab9c8ad563230bd5471a7.woff2 +0 -0
  127. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-5d2898fbc097a7e24c6f38d80587621e.woff2 +0 -0
  128. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-603aefd23e350ba7eb124273e3c9bcf1.woff2 +0 -0
  129. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-60a3089806700d379f11827ee9843b6b.woff2 +0 -0
  130. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-60a41c7e1c68f22424e6d22df544bc82.woff2 +0 -0
  131. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-642b26e2e5f5fb780b51b593dbc8c851.woff2 +0 -0
  132. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-66493ba5a8367f2928812f446f47b56a.woff2 +0 -0
  133. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-670ba603758d94268e8606f240a42e12.woff2 +0 -0
  134. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-671a2c20b1eb9e4ef8a192833940e319.woff2 +0 -0
  135. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-684d65f1793cac449dde5d59cb3c47fb.woff2 +0 -0
  136. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-69c09cc5fa3e55c74fc4821f76909cc3.woff2 +0 -0
  137. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-6ae5b42180ad70b971c91e7eefb8eba2.woff2 +0 -0
  138. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-6e092f71c1e634059ada0e52abadce67.woff2 +0 -0
  139. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-6f3256af8454371776bc46670d33cc65.woff2 +0 -0
  140. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-6fe5c5973cc06f74b2387a631ea36b88.woff2 +0 -0
  141. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-70c2eb8d64e71a42a834eb857ea9df51.woff2 +0 -0
  142. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-70e811fd7994e61f408c923de6ddd078.woff2 +0 -0
  143. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-7197d6fda6cba7c3874c53d6381ca239.woff2 +0 -0
  144. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-72252d73220fa3cd856677888cee1635.woff2 +0 -0
  145. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-72536a3d71b694a0d53dd90ddceae41e.woff2 +0 -0
  146. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-726303e0774b4e678bff8c2deb6ca603.woff2 +0 -0
  147. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-733171b4ffcd17ea1fe1c0ba627173bf.woff2 +0 -0
  148. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-739bc1a567439c7cffcd1614644593d2.woff2 +0 -0
  149. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-73e309718fd16cea44b4d54a33581811.woff2 +0 -0
  150. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-7494dc504ae00ee9cd0505f990f88c5d.woff2 +0 -0
  151. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-74e2263a91439c25b91d5132ce9f4d62.woff2 +0 -0
  152. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-761d05e3cd968cf574166867998ef06a.woff2 +0 -0
  153. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-7718fe60986d8b42b1be9c5ace5ccf25.woff2 +0 -0
  154. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-774d4f764a1299da5d28ec2f2ffe0d69.woff2 +0 -0
  155. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-79d494361ae093b69e74ee9dbe65bfd4.woff2 +0 -0
  156. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-79f007c1c6d07557120982951ea67998.woff2 +0 -0
  157. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-7a07ddc0f0c0f5f4a9bad6ee3dda66b5.woff2 +0 -0
  158. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-7ab2bed91166a9dca83a5ebfbe2a7f38.woff2 +0 -0
  159. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-7ccce86603f80a099ddb0cb21d4ae3e3.woff2 +0 -0
  160. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-7e4bde7e9c7f84cd34d8a845e384c746.woff2 +0 -0
  161. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-7e929f262f30c8ee78bf398150b1a7cd.woff2 +0 -0
  162. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-7eb9fffd1aa890d07d0f88cc82e6cfe4.woff2 +0 -0
  163. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-7f855356ab893b0d2b9c1c83b8116f0e.woff2 +0 -0
  164. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-829615148e6357d826b9242eb7fbbd1e.woff2 +0 -0
  165. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-866fa7613df6b3fd272bcfd4530c0bb9.woff2 +0 -0
  166. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-87599f94b6cc129d505b375798d0d751.woff2 +0 -0
  167. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-8c2f33cee3993174f7e87c28e4bf42ee.woff2 +0 -0
  168. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-8d3bcabb847b56243b16afe62adaaf21.woff2 +0 -0
  169. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-8de5b863cb50dfefdd07cb11c774d579.woff2 +0 -0
  170. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-8e9f97f01034820170065b2921b4fb5e.woff2 +0 -0
  171. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-8f476c4c99813d57cbe6eca4727388ad.woff2 +0 -0
  172. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-903bb6865f3452e2fda42e3a25547bc5.woff2 +0 -0
  173. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-91ddb2969bf2d31ba02ad82998d1314c.woff2 +0 -0
  174. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-938d90c10ff8c20386af7f242c05d6b0.woff2 +0 -0
  175. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-93fc8f28a33234bcadf1527cafabd502.woff2 +0 -0
  176. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-95429962233afd82db1c27df1500a28c.woff2 +0 -0
  177. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-9544732d2e62d1a429674f8ee41b5d3a.woff2 +0 -0
  178. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-9592bfc861f07bcb8d75c196b370e548.woff2 +0 -0
  179. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-95bfd249da4902577b4b7d76ebdd0b44.woff2 +0 -0
  180. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-968cffdc8ee679da094e77ebf50f58ef.woff2 +0 -0
  181. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-97f7f48ce90c9429bf32ae51469db74d.woff2 +0 -0
  182. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-982b630266d87db93d2539affb1275c6.woff2 +0 -0
  183. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-98f2ad84457de7f3740d9920b8fa8667.woff2 +0 -0
  184. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-99a16ef6a64934d5781933dbd9c46b2e.woff2 +0 -0
  185. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-9cfb2a77a4e45025105ad29a1748b90d.woff2 +0 -0
  186. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-9d81066dd2b337c938df6e90380a00dc.woff2 +0 -0
  187. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-9eb5a99df4e76ac3363453ac9ca288b1.woff2 +0 -0
  188. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-a004ddfcb26e67bd6e678c8ed19e25ce.woff2 +0 -0
  189. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-a0ca5df4258213d7fc9fce80f65ce760.woff2 +0 -0
  190. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-a1f916d6039285c4ffb900cd654e418f.woff2 +0 -0
  191. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-a203b91dad570bf05a58c3c3ddb529bf.woff2 +0 -0
  192. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-a365e82ed54697a52f27adcea1315fe8.woff2 +0 -0
  193. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-a4c34be6d42152e64b0df90bc4607f64.woff2 +0 -0
  194. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-a7accba310e821da5505f71c03b76bdb.woff2 +0 -0
  195. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-aa0d470430e6391eca720c7cfa44446f.woff2 +0 -0
  196. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-aa5c9ca6cf4fba00433b7aa3fa10671a.woff2 +0 -0
  197. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-ac9ceb44437becc3e9c4dbfebab7fc2d.woff2 +0 -0
  198. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-b1220a3c61f85cc0408deedb4c5f57a2.woff2 +0 -0
  199. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-b358f7a51ece39a3247942b1feabdb29.woff2 +0 -0
  200. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-b57aaedfd8ebdf3931f25119dc6a5eb2.woff2 +0 -0
  201. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-b5c1596551c256e0e9cf02028595b092.woff2 +0 -0
  202. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-b6d128682ee29e471486354d486a1b90.woff2 +0 -0
  203. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-b6fd38ca30869792244804b04bc058da.woff2 +0 -0
  204. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-b7d203b051eff504ff59ddca7576b6a9.woff2 +0 -0
  205. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-b96d9226ce77ec94ceca043d712182e6.woff2 +0 -0
  206. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-ba3de316d63c7e339987b16f41a0b879.woff2 +0 -0
  207. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-bafff7a14c27403dcc6cf1432e8ea836.woff2 +0 -0
  208. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-bd77e3c7f9e0b072d96af37f73d1aa32.woff2 +0 -0
  209. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-be549ab72f0719d606a5c01e2c0219b6.woff2 +0 -0
  210. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-c16ed9740b85badf16e86ea782a3062f.woff2 +0 -0
  211. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-c1f94158256bb1f3bf665b053d895af9.woff2 +0 -0
  212. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-c40533fdf4cc57177b12803598af7e59.woff2 +0 -0
  213. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-c4a687ac4f0c2766eefc9f77ed99cddf.woff2 +0 -0
  214. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-c69f61a4ab18d0488c8d1fc12e7028e8.woff2 +0 -0
  215. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-c8b71798409ccc126ee264a00aadcf21.woff2 +0 -0
  216. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-c99eda15fc26a2941579560f76c3a5cf.woff2 +0 -0
  217. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-cb17fc3db95f6d139afc9d31a8e93293.woff2 +0 -0
  218. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-cbaaefaaf326668277aa24dfa93c4d28.woff2 +0 -0
  219. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-cd145ce4a0ea18469358df53c207bc1b.woff2 +0 -0
  220. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-cdbce89e82cc1ab53a2decbf5819278f.woff2 +0 -0
  221. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-ce4884f96f11589608b76b726a755803.woff2 +0 -0
  222. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-cf2cc71752631e579e35b0e423bf2638.woff2 +0 -0
  223. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-cf6ff4e0f491ca0cf3038187a997b9b4.woff2 +0 -0
  224. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-cfb211578629b7e8153b37240de6a9d5.woff2 +0 -0
  225. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-d0cf73942fea1c74edbdf0b3011f4656.woff2 +0 -0
  226. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-d2666cbed13462c5dc36fa2f15c202ca.woff2 +0 -0
  227. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-d3716376641d615e2995605b29bca7b6.woff2 +0 -0
  228. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-dac48066b5883d8b4551fc584f0c2a3e.woff2 +0 -0
  229. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-dbea1af6dcd9860be40c3d18254338f5.woff2 +0 -0
  230. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-e11567fd2accf9957cd0d3c2be937d87.woff2 +0 -0
  231. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-e2ead7ea7da0437f085f42ffc05f8d13.woff2 +0 -0
  232. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-e3fcf5180fd466c8915c4e8069491054.woff2 +0 -0
  233. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-e480d9c614742d05f0e78f274f1e69e6.woff2 +0 -0
  234. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-e4bca6cfa53e499cae0a6be4894a90e9.woff2 +0 -0
  235. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-e51ef413167c6e14e0c0fdcc585f2fc9.woff2 +0 -0
  236. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-e5f453bb04da18eed01675eeebd88bf8.woff2 +0 -0
  237. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-e656f091b9dc4709722c9f4b84d3c797.woff2 +0 -0
  238. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-ec181b795ac1fb5a50d700b6e996d745.woff2 +0 -0
  239. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-ee8bae97908d5147b423f77ad0d3c1bb.woff2 +0 -0
  240. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-f0f13b5c60e0af5553bd359f5513be1b.woff2 +0 -0
  241. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-f2b54d4e7be0eaefe1c2c56836fa5368.woff2 +0 -0
  242. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-f56414bf9bced67990def8660e306759.woff2 +0 -0
  243. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-f5d079153c99a25b9be5b8583c4cc8a7.woff2 +0 -0
  244. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-f6032fc06eb20480f096199713f70885.woff2 +0 -0
  245. package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-f8ee5d36068a42b51d0e4a1116cfcec1.woff2 +0 -0
  246. package/dist/ui/kid/kid-page.js +2 -0
  247. package/dist/ui/kid/offline-sw.d.ts +1 -0
  248. package/dist/ui/kid/offline-sw.js +42 -0
  249. package/dist/ui/parent/parent-home-page.js +8 -5
  250. package/install.ps1 +66 -0
  251. package/install.sh +84 -0
  252. package/package.json +13 -10
@@ -3674,6 +3674,8 @@ __REEL_DOCK_JS__
3674
3674
  location.reload();
3675
3675
  };
3676
3676
  setInterval(() => { staleReload(); if (S.tutor) { if (!S.pending) loadDay(true); } else loadHome(); }, 5000);
3677
+ // 离线页(offline-sw.ts):电脑关了、睡着了时,点开主屏幕图标看到「老师们还没到」,不是浏览器的报错。只在 https(或 localhost)上有;回放、预览里不装
3678
+ if (!REEL && !PREVIEW && window.isSecureContext && 'serviceWorker' in navigator) navigator.serviceWorker.register('/sw.js').catch(() => {});
3677
3679
  document.addEventListener('visibilitychange', () => { if (!document.hidden) (S.tutor ? loadDay(true) : loadHome()); });
3678
3680
  // 孩子端刷新(手动的、Safari 自己重载的)回到手上这位老师;在首页刷新就回首页。只读回放不记(重载回来是今天的)
3679
3681
  if (!REEL && !PREVIEW) window.addEventListener('pagehide', () => { try { if (S.tutor && !S.readonly) sessionStorage.setItem('kid-resume', S.tutor.name); else sessionStorage.removeItem('kid-resume'); } catch {} });
@@ -0,0 +1 @@
1
+ export declare const KID_SW_JS: string;
@@ -0,0 +1,42 @@
1
+ /**
2
+ * 孩子端的离线页(Service Worker,GET /sw.js):电脑关了、睡着了、服务没在跑时,平板上打开孩子端看到的不是浏览器的报错,是「老师们休息中」。
3
+ * 和页面开着时断线的样子(kid-page 的 #rest)同一句:都是「电脑那边连不上」;「老师们还没到」是百炼没配好,另一回事。
4
+ * 孩子端永远没有错误:这一页只说老师们休息、叫爸爸妈妈,不说连接、不说服务器。
5
+ * 页面开着时断线由页面自己管(灰掉、「老师们休息中」);这一页只在重新打开(iPad 把网页 App 清出内存后再点开、刷新)时出现。
6
+ *
7
+ * 只接管孩子端那几页的打开(导航);接口、静态文件、别的页面一律不碰。不缓存任何东西:平时原样走网络,孩子看不到旧页面;
8
+ * 连不上或 12 秒没回应才给离线页,它每 5 秒问一次 /api/health,通了就自己刷新回去。
9
+ * Service Worker 只在安全上下文里有(https 且平板信任了根证书,或 localhost);http 时孩子端照旧,什么都不变。
10
+ * 改了这个文件就改 VERSION:平板上的旧 worker 靠脚本内容变了才换。
11
+ */
12
+ const VERSION = '2';
13
+ /** 离线页本身:没有网可取,样式、脚本都内联 */
14
+ const OFFLINE_HTML = [
15
+ '<!doctype html><html lang="zh-CN"><head><meta charset="utf-8">',
16
+ '<meta name="viewport" content="width=device-width,initial-scale=1,viewport-fit=cover">',
17
+ '<meta name="apple-mobile-web-app-capable" content="yes"><title>老师们休息中</title>',
18
+ '<style>html,body{height:100%;margin:0}body{display:flex;align-items:center;justify-content:center;background:#f7f3ea;color:#3a352c;',
19
+ 'font:22px/1.6 -apple-system,"PingFang SC","Microsoft YaHei",sans-serif;text-align:center;-webkit-user-select:none;user-select:none}',
20
+ 'p{margin:0 24px}small{display:block;margin-top:12px;font-size:17px;color:#8a8273}</style></head>',
21
+ '<body><p id="off">老师们休息中<small>叫爸爸妈妈来看一下:家里那台电脑是不是关了、睡着了</small></p>',
22
+ '<script>setInterval(function(){fetch("/api/health",{cache:"no-store"}).then(function(r){if(r.ok)location.reload()}).catch(function(){})},5000)</script>',
23
+ '</body></html>',
24
+ ].join('');
25
+ export const KID_SW_JS = `// cotutor 孩子端的离线页 v${VERSION}(src/ui/kid/offline-sw.ts)
26
+ const KID = new Set(['/', '/dictation', '/dictation/', '/talk', '/talk/']);
27
+ const WAIT_MS = 12000;
28
+ const OFFLINE = ${JSON.stringify(OFFLINE_HTML)};
29
+ self.addEventListener('install', () => { self.skipWaiting(); });
30
+ self.addEventListener('activate', (e) => { e.waitUntil(self.clients.claim()); });
31
+ self.addEventListener('fetch', (e) => {
32
+ const r = e.request;
33
+ if (r.mode !== 'navigate' || r.method !== 'GET') return;
34
+ const u = new URL(r.url);
35
+ if (u.origin !== self.location.origin || !KID.has(u.pathname)) return;
36
+ const offline = () => new Response(OFFLINE, { status: 200, headers: { 'content-type': 'text/html; charset=utf-8', 'cache-control': 'no-store' } });
37
+ e.respondWith(Promise.race([
38
+ fetch(r).catch(() => null),
39
+ new Promise((resolve) => { setTimeout(() => resolve(null), WAIT_MS); }),
40
+ ]).then((res) => res || offline()));
41
+ });
42
+ `;
@@ -365,24 +365,27 @@ ${pageDomJs(3200)}
365
365
  h('span', { style: 'flex:none;display:flex', html: QR_ICON }), h('span', { class: 'tx' }, h('b', {}, '扫码打开'), h('small', {}, seen)), h('span', { class: 'lnk', style: 'font-size:14px' }, '展开'))));
366
366
  return;
367
367
  }
368
- const kid = QR.to === 'kid', c = kid ? d : (d.parent || d);
368
+ if (QR.to === 'ca' && !d.ca) QR.to = 'kid';
369
+ const kid = QR.to === 'kid', ca = QR.to === 'ca', c = kid ? d : ca ? d.ca : (d.parent || d);
369
370
  const useIp = QR.ip && c.ip;
370
- const seg = h('div', { class: 'seg', role: 'group', 'aria-label': '给谁扫' }, ...[['kid', '孩子的平板'], ['parent', '我的手机']].map(([k, l]) =>
371
+ // 装证书(serve.ts 的 http 那一面给根证书):平板第一次用之前扫一次;有证书、找得到根证书才有这一格
372
+ const tabs = [['kid', '孩子的平板'], ['parent', '我的手机']].concat(d.ca ? [['ca', '装证书']] : []);
373
+ const seg = h('div', { class: 'seg', role: 'group', 'aria-label': '给谁扫' }, ...tabs.map(([k, l]) =>
371
374
  h('button', { type: 'button', class: QR.to === k ? 'on' : '', 'aria-pressed': QR.to === k ? 'true' : 'false', on: { click: () => { QR.to = k; qrDraw(); } } }, l)));
372
375
  const print = '/parent/qr?' + new URLSearchParams(Object.assign({}, useIp ? { via: 'ip' } : {}, kid ? {} : { to: 'parent' })).toString();
373
376
  qrEl.replaceChildren(
374
377
  h('div', { class: 'gh' }, h('span', {}, '扫码打开'), h('button', { type: 'button', class: 'x', 'aria-expanded': 'true', on: { click: () => qrToggle(false) } }, '收起')),
375
378
  h('div', { class: 'grp' }, h('div', { class: 'box' }, seg,
376
379
  h('div', { class: 'qrrow' }, h('div', { class: 'qrimg', html: (useIp ? c.svgIp : c.svg) || '' }),
377
- h('b', { style: 'font-weight:600' }, kid ? '用孩子平板的相机扫一下' : '用你自己的手机扫一下'),
378
- h('span', { class: 'lbl', style: 'line-height:1.5' }, kid ? '打开的就是孩子的首页。在 Safari 里「添加到主屏幕」,以后点图标就进来。' : '打开的是家长端:看记录、排首页。也可以添加到主屏幕。')),
380
+ h('b', { style: 'font-weight:600' }, kid ? '用孩子平板的相机扫一下' : ca ? '平板第一次用:先扫这张装证书' : '用你自己的手机扫一下'),
381
+ h('span', { class: 'lbl', style: 'line-height:1.5' }, kid ? '打开的就是孩子的首页。在 Safari 里「添加到主屏幕」,以后点图标就进来。' : ca ? '扫了点「允许」下载描述文件;到「设置」最上面点「已下载描述文件」装上;再到「设置 › 通用 › 关于本机 › 证书信任设置」把开关打开。装好再扫「孩子的平板」那张。每台平板做一次。' : '打开的是家长端:看记录、排首页。也可以添加到主屏幕。')),
379
382
  h('div', { class: 'qrurl' }, useIp ? c.ip : c.url),
380
383
  d.https ? null : h('div', { class: 'qrwarn' }, d.notes[0] || ''),
381
384
  h('div', { class: 'row2', style: 'font-size:14px' },
382
385
  c.ip ? h('button', { type: 'button', class: 'x', style: 'height:auto;padding:0;font-size:14px;text-align:left', on: { click: () => { QR.ip = !QR.ip; qrDraw(); } } }, useIp ? '换回 ' + host(c.url) : '扫了打不开?换成 ' + host(c.ip)) : h('span'),
383
386
  h('span', { style: 'display:flex;gap:14px;flex:none' },
384
387
  h('a', { class: 'lnk kidl', style: 'font-size:14px', href: '/', target: '_blank' }, '孩子端 ↗'),
385
- h('a', { class: 'lnk', style: 'font-size:14px', href: print, target: '_blank' }, '打印 ›'))))),
388
+ ca ? null : h('a', { class: 'lnk', style: 'font-size:14px', href: print, target: '_blank' }, '打印 ›'))))),
386
389
  h('div', { class: 'note' }, d.https ? (d.notes[0] || '') : '', d.devices ? '' : (d.https ? ' ' : '') + '还没有平板连进来过,所以这块先开着;连过以后自动收起。'));
387
390
  };
388
391
 
package/install.ps1 ADDED
@@ -0,0 +1,66 @@
1
+ # cotutor 一行安装(Windows,在 PowerShell 里粘贴):
2
+ # irm https://raw.githubusercontent.com/TarsLab/cotutor/main/install.ps1 | iex
3
+ # 连不上 GitHub 就换这个:
4
+ # irm https://cdn.jsdelivr.net/npm/cotutor@latest/install.ps1 | iex
5
+ # 顺手建好孩子的文件夹、装好后台服务(短名 称呼 年级):
6
+ # & ([scriptblock]::Create((irm https://raw.githubusercontent.com/TarsLab/cotutor/main/install.ps1))) ming 小明 2
7
+ #
8
+ # 只做这几件事:查 Node 的版本;npm 连不上就用国内镜像;装 cotutor。
9
+ # 不要管理员,不改执行策略:npm、cotutor 都用 .cmd 跑(PowerShell 缺省策略会拦 .ps1)。Node 没装或太旧时只说怎么装,不替你装。
10
+ $ErrorActionPreference = 'Stop'
11
+
12
+ function Say($text) { Write-Host $text }
13
+ function Stop-Here($text) { Write-Host $text; throw 'cotutor-install-stopped' }
14
+
15
+ $needMajor = 22
16
+ $needMinor = 18
17
+
18
+ try {
19
+ # ---- 1. Node ----
20
+ if (-not (Get-Command node -ErrorAction SilentlyContinue)) {
21
+ Stop-Here "这台电脑还没有 Node.js:到 https://nodejs.org 下载 LTS 版(Windows 安装程序)装上,或者跑 winget install OpenJS.NodeJS.LTS;装完重开 PowerShell 再跑这一行。"
22
+ }
23
+ $v = (& node -p 'process.versions.node').Trim()
24
+ $parts = $v.Split('.')
25
+ if ([int]$parts[0] -lt $needMajor -or ([int]$parts[0] -eq $needMajor -and [int]$parts[1] -lt $needMinor)) {
26
+ Stop-Here "Node.js 是 $v,cotutor 要 $needMajor.$needMinor 以上:到 https://nodejs.org 装新的 LTS 版,重开 PowerShell 再跑这一行。"
27
+ }
28
+ if (-not (Get-Command npm.cmd -ErrorAction SilentlyContinue)) { Stop-Here '有 Node.js 但找不到 npm:到 https://nodejs.org 重新装一次 LTS 版。' }
29
+ Say "Node.js $v"
30
+
31
+ # ---- 2. npm 连得上吗(国内常连不上,换镜像) ----
32
+ $registry = $null
33
+ try { Invoke-WebRequest -UseBasicParsing -TimeoutSec 8 'https://registry.npmjs.org/cotutor/latest' | Out-Null }
34
+ catch { $registry = 'https://registry.npmmirror.com'; Say "npm 连不上或太慢,用国内镜像 $registry" }
35
+
36
+ # ---- 3. 装 ----
37
+ Say '正在下载 cotutor,要一会儿……'
38
+ $npmArgs = @('i', '-g', 'cotutor', '--no-audit', '--no-fund')
39
+ if ($registry) { $npmArgs += "--registry=$registry" }
40
+ & npm.cmd @npmArgs
41
+ if ($LASTEXITCODE -ne 0) { Stop-Here 'npm 没装成:看上面的报错;连不上就过一会儿再试。' }
42
+ # 刚装上的 cotutor.cmd 在 npm 的全局目录里;这个窗口的 PATH 可能还没有它
43
+ $globalDir = (& npm.cmd prefix -g).Trim()
44
+ if (-not (Get-Command cotutor.cmd -ErrorAction SilentlyContinue)) { $env:Path = "$globalDir;$env:Path" }
45
+ if (-not (Get-Command cotutor.cmd -ErrorAction SilentlyContinue)) { Stop-Here "装好了但找不到 cotutor:重开 PowerShell 再试;还不行,把 $globalDir 加进 PATH。" }
46
+ Say ('cotutor ' + (& cotutor.cmd --version).Trim() + ' 装好了')
47
+
48
+ # ---- 4. 带了孩子的信息就接着建文件夹、装后台服务 ----
49
+ if ($args.Count -ge 1) {
50
+ $initArgs = @('init', $args[0])
51
+ if ($args.Count -ge 2 -and $args[1]) { $initArgs += @('--name', $args[1]) }
52
+ if ($args.Count -ge 3 -and $args[2]) { $initArgs += @('--grade', [string]$args[2]) }
53
+ & cotutor.cmd @initArgs
54
+ if ($LASTEXITCODE -ne 0) { Stop-Here '建孩子的文件夹没成:看上面的报错。' }
55
+ & cotutor.cmd service install
56
+ Say ''
57
+ Say '好了。家长端已经在浏览器里打开;以后点任务栏右下角 ^ 里的 cotutor 图标,或者跑 cotutor.cmd open。'
58
+ } else {
59
+ Say ''
60
+ Say '接下来(短名用小写字母,不用真名;年级 1 到 6):'
61
+ Say ' cotutor.cmd init ming --name 小明 --grade 2'
62
+ Say ' cotutor.cmd service install'
63
+ }
64
+ } catch {
65
+ if ($_.Exception.Message -ne 'cotutor-install-stopped') { Write-Host ('出错了:' + $_.Exception.Message) }
66
+ }
package/install.sh ADDED
@@ -0,0 +1,84 @@
1
+ #!/bin/sh
2
+ # cotutor 一行安装(macOS、Linux):
3
+ # curl -fsSL https://raw.githubusercontent.com/TarsLab/cotutor/main/install.sh | sh
4
+ # 连不上 GitHub 就换这个:
5
+ # curl -fsSL https://cdn.jsdelivr.net/npm/cotutor@latest/install.sh | sh
6
+ # 顺手建好孩子的文件夹、装好后台服务(短名 称呼 年级):
7
+ # curl -fsSL https://raw.githubusercontent.com/TarsLab/cotutor/main/install.sh | sh -s -- ming 小明 2
8
+ #
9
+ # 只做这几件事:查 Node 的版本;npm 连不上就用国内镜像;全局目录写不了就换到自己家目录下(不用 sudo);装 cotutor。
10
+ # 不用 sudo,不改系统设置。Node 没装或太旧时只说怎么装,不替你装。
11
+ set -eu
12
+
13
+ say() { printf '%s\n' "$*"; }
14
+ die() { say "$*"; exit 1; }
15
+
16
+ NEED_MAJOR=22
17
+ NEED_MINOR=18
18
+
19
+ # ---- 1. Node ----
20
+ command -v node >/dev/null 2>&1 || die "这台电脑还没有 Node.js:到 https://nodejs.org 下载 LTS 版装上,重开终端再跑这一行。"
21
+ v=$(node -p 'process.versions.node')
22
+ major=${v%%.*}
23
+ rest=${v#*.}
24
+ minor=${rest%%.*}
25
+ if [ "$major" -lt "$NEED_MAJOR" ] || { [ "$major" -eq "$NEED_MAJOR" ] && [ "$minor" -lt "$NEED_MINOR" ]; }; then
26
+ die "Node.js 是 $v,cotutor 要 $NEED_MAJOR.$NEED_MINOR 以上:到 https://nodejs.org 装新的 LTS 版,重开终端再跑这一行。"
27
+ fi
28
+ command -v npm >/dev/null 2>&1 || die "有 Node.js 但找不到 npm:到 https://nodejs.org 重新装一次 LTS 版。"
29
+ say "Node.js $v"
30
+
31
+ # ---- 2. npm 连得上吗(国内常连不上,换镜像) ----
32
+ REGISTRY=""
33
+ if ! curl -fsS -o /dev/null --max-time 8 https://registry.npmjs.org/cotutor/latest 2>/dev/null; then
34
+ REGISTRY="https://registry.npmmirror.com"
35
+ say "npm 连不上或太慢,用国内镜像 $REGISTRY"
36
+ fi
37
+
38
+ # ---- 3. 全局目录写得了吗(官网的 Mac 安装包装在 /usr/local,要 sudo 才能写;不用 sudo,换到家目录下) ----
39
+ root=$(npm root -g)
40
+ target=$root
41
+ [ -d "$target" ] || target=$(dirname "$target")
42
+ if [ ! -w "$target" ]; then
43
+ prefix="$HOME/.npm-global"
44
+ say "npm 的全局目录 $root 这个账户写不了,改装到 $prefix(不用 sudo)"
45
+ mkdir -p "$prefix"
46
+ npm config set prefix "$prefix"
47
+ case "${SHELL:-}" in
48
+ */zsh) rc="$HOME/.zshrc" ;;
49
+ */bash) if [ "$(uname)" = Darwin ]; then rc="$HOME/.bash_profile"; else rc="$HOME/.bashrc"; fi ;;
50
+ *) rc="$HOME/.profile" ;;
51
+ esac
52
+ line='export PATH="$HOME/.npm-global/bin:$PATH"'
53
+ if ! grep -qsF "$line" "$rc"; then
54
+ printf '\n# cotutor 安装脚本加的:npm 全局命令装在家目录下\n%s\n' "$line" >> "$rc"
55
+ say "在 $rc 里加了一行 PATH,新开的终端就认得 cotutor"
56
+ fi
57
+ PATH="$prefix/bin:$PATH"
58
+ export PATH
59
+ fi
60
+
61
+ # ---- 4. 装 ----
62
+ say "正在下载 cotutor,要一会儿……"
63
+ if [ -n "$REGISTRY" ]; then npm i -g cotutor --no-audit --no-fund --registry="$REGISTRY"; else npm i -g cotutor --no-audit --no-fund; fi
64
+ command -v cotutor >/dev/null 2>&1 || die "装好了但找不到 cotutor 命令:重开终端再试;还不行,把 $(npm prefix -g)/bin 加进 PATH。"
65
+ say "cotutor $(cotutor --version) 装好了"
66
+
67
+ # ---- 5. 带了孩子的信息就接着建文件夹、装后台服务 ----
68
+ if [ $# -ge 1 ]; then
69
+ slug=$1
70
+ set -- "$@" "" ""
71
+ name=$2
72
+ grade=$3
73
+ if [ -n "$name" ] && [ -n "$grade" ]; then cotutor init "$slug" --name "$name" --grade "$grade"
74
+ elif [ -n "$name" ]; then cotutor init "$slug" --name "$name"
75
+ else cotutor init "$slug"; fi
76
+ cotutor service install
77
+ say ""
78
+ say "好了。家长端已经在浏览器里打开;以后点菜单栏的 cotutor 图标,或在终端跑 cotutor open。"
79
+ else
80
+ say ""
81
+ say "接下来(短名用小写字母,不用真名;年级 1 到 6):"
82
+ say " cotutor init ming --name 小明 --grade 2"
83
+ say " cotutor service install"
84
+ fi