lookatstudy-mobile 0.23.1 → 0.24.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 (141) hide show
  1. package/package.json +1 -1
  2. package/server.cjs +42 -1
  3. package/web/assets/{CanvasStage-Ba-21anG.js → CanvasStage-u_7YeGk1.js} +1 -1
  4. package/web/assets/{CommandPalette-SKnzQMcN.js → CommandPalette-Q5j7BQf4.js} +1 -1
  5. package/web/assets/{CourseSearchPanel-BW3fNReR.js → CourseSearchPanel-BYGHjhnk.js} +1 -1
  6. package/web/assets/{ExamView-BnH6BraN.js → ExamView-DU5X7LyZ.js} +1 -1
  7. package/web/assets/{MindmapView-B4SeCLQj.js → MindmapView-C61d4ddf.js} +3 -3
  8. package/web/assets/{ReviewPanel-DkGT8tNA.js → ReviewPanel-DoLMdlpR.js} +1 -1
  9. package/web/assets/SettingsView-CD9th6O0.js +7 -0
  10. package/web/assets/{VoicePanel-CxNeKn4V.js → VoicePanel-Cvl2BLq2.js} +1 -1
  11. package/web/assets/{abnfDiagram-N423BO3Z-B4kvB05N.js → abnfDiagram-N423BO3Z-BvTcLUtE.js} +1 -1
  12. package/web/assets/{abnfDiagram-VCTEODGH-ODA7YWAP-B5zhG8XJ.js → abnfDiagram-VCTEODGH-ODA7YWAP-NpbseUTF.js} +1 -1
  13. package/web/assets/{architectureDiagram-5GKGNRK7-C4PU3XN7-ybcWxxhr.js → architectureDiagram-5GKGNRK7-C4PU3XN7-DGtDmisd.js} +1 -1
  14. package/web/assets/{architectureDiagram-T3A2C74G-D5eb-etB.js → architectureDiagram-T3A2C74G-huu8moy9.js} +1 -1
  15. package/web/assets/{arrow-right-D4GV0Gpo.js → arrow-right-B0QrRNSR.js} +1 -1
  16. package/web/assets/{blockDiagram-NRAW4CY4-UMJ6PMQQ-DwEVReBp.js → blockDiagram-NRAW4CY4-UMJ6PMQQ-BxiaVwV9.js} +1 -1
  17. package/web/assets/{blockDiagram-VBNYF7ZC-DuM7ndnl.js → blockDiagram-VBNYF7ZC-BAnlmDNm.js} +1 -1
  18. package/web/assets/{c4Diagram-5PPSVZJV-BQkRaO7S.js → c4Diagram-5PPSVZJV-MUU8xp1X.js} +1 -1
  19. package/web/assets/{c4Diagram-UCG6FXSJ-75X3U2P3-Di1jNn7S.js → c4Diagram-UCG6FXSJ-75X3U2P3-7rpgYEob.js} +1 -1
  20. package/web/assets/channel-BJoUn5Z8.js +1 -0
  21. package/web/assets/{chunk-2GRJ4B5K-C7VAL2Yd.js → chunk-2GRJ4B5K-BZ6Sj0-3.js} +1 -1
  22. package/web/assets/{chunk-2Q5K7J3B-Jpo34qVL.js → chunk-2Q5K7J3B-BkOSQBqV.js} +1 -1
  23. package/web/assets/{chunk-5RXB4S5H-CrW8aZl4.js → chunk-5RXB4S5H-DgXJvWY0.js} +1 -1
  24. package/web/assets/{chunk-5VM5RSS4-Dv4MffdC.js → chunk-5VM5RSS4-D-BptZQ9.js} +1 -1
  25. package/web/assets/{chunk-6Q2QTUOP-CI07iNTB.js → chunk-6Q2QTUOP-DIJ0lWTD.js} +1 -1
  26. package/web/assets/{chunk-7XDTSPCN-DsQtrF-N.js → chunk-7XDTSPCN-vxuDBi1y.js} +1 -1
  27. package/web/assets/{chunk-CTNIYPP6-CpdWBpIN.js → chunk-CTNIYPP6-F5ZMIO6O.js} +1 -1
  28. package/web/assets/{chunk-CXNFBKHE-BDCDRaZC.js → chunk-CXNFBKHE-CFr1EfBh.js} +1 -1
  29. package/web/assets/{chunk-GF5L2VYU-DtpZkefy.js → chunk-GF5L2VYU-jqePwawx.js} +1 -1
  30. package/web/assets/{chunk-ISA7TJRJ-C3LgQ-bA.js → chunk-ISA7TJRJ-DiKuu0wz.js} +1 -1
  31. package/web/assets/{chunk-JWPE2WC7-DJM1SevB.js → chunk-JWPE2WC7-CLC3hqKr.js} +1 -1
  32. package/web/assets/{chunk-KBJHAD2P-7KeTMqC1.js → chunk-KBJHAD2P-DSEKcYpO.js} +1 -1
  33. package/web/assets/{chunk-LV3HUYFY-B2sGhGxz.js → chunk-LV3HUYFY-P2e0-qZ6.js} +1 -1
  34. package/web/assets/{chunk-M3IUQBOH-Dazbegdb.js → chunk-M3IUQBOH-Bdt4MjFy.js} +1 -1
  35. package/web/assets/{chunk-NDIOYS4C-Cx7mCz5-.js → chunk-NDIOYS4C-7HlPLAGd.js} +1 -1
  36. package/web/assets/{chunk-RE4WF27V-BNzpDJts.js → chunk-RE4WF27V-D4vIv_G3.js} +1 -1
  37. package/web/assets/{chunk-RYQCIY6F-Boq_29rU.js → chunk-RYQCIY6F-tTcuHeqw.js} +1 -1
  38. package/web/assets/{chunk-VII2H2IX-kQVDZD-x.js → chunk-VII2H2IX-BkXECJ1Z.js} +1 -1
  39. package/web/assets/{chunk-X5GNSKZ3-DT5Ja5IF.js → chunk-X5GNSKZ3-D7yjZGWk.js} +1 -1
  40. package/web/assets/{chunk-XCWWM2C3-BAq7zpgL.js → chunk-XCWWM2C3-C_es6n6S.js} +1 -1
  41. package/web/assets/{chunk-XXDRQBXY-D3vcLngc.js → chunk-XXDRQBXY-Bsuow-B8.js} +1 -1
  42. package/web/assets/classDiagram-DTDB5LWJ-LWRDKZ5K-B3DqqoSe.js +1 -0
  43. package/web/assets/classDiagram-JCYQIIEL-C2n-a_rM.js +1 -0
  44. package/web/assets/classDiagram-v2-JRS7N3AN-2BZHGRP2-B3DqqoSe.js +1 -0
  45. package/web/assets/classDiagram-v2-OCEON4UE-C2n-a_rM.js +1 -0
  46. package/web/assets/{core-4d9vIKK9.js → core-Bgf5ngI5.js} +1 -1
  47. package/web/assets/{cose-bilkent-JH36ORCC-OB24KH3T-DwFzf1xR.js → cose-bilkent-JH36ORCC-OB24KH3T-DM0H6Gci.js} +1 -1
  48. package/web/assets/{cose-bilkent-JH36ORCC-RoUdcSs7.js → cose-bilkent-JH36ORCC-x05QuEnY.js} +1 -1
  49. package/web/assets/{cynefin-OW5HDTMX-GVF3BKWE-Bdt2EF7g.js → cynefin-OW5HDTMX-GVF3BKWE-DY90g1OE.js} +1 -1
  50. package/web/assets/{cynefin-VYW2F7L2-Br1TXK2f.js → cynefin-VYW2F7L2-DjqH_9VW.js} +1 -1
  51. package/web/assets/{cynefinDiagram-5FMLGOSQ-H3WIRU3N-DFRlDIhn.js → cynefinDiagram-5FMLGOSQ-H3WIRU3N-DoaOZ7iJ.js} +1 -1
  52. package/web/assets/{cynefinDiagram-MW4NZA55-DeqLH2Db.js → cynefinDiagram-MW4NZA55-DI8ePik6.js} +1 -1
  53. package/web/assets/{dagre-3AP2YEHR-DCERTXHT-wbCkJQSQ.js → dagre-3AP2YEHR-DCERTXHT-BwLHkvZV.js} +1 -1
  54. package/web/assets/{dagre-VZM6K2ZE-X3laLObS.js → dagre-VZM6K2ZE-0zjstOys.js} +1 -1
  55. package/web/assets/{diagram-7IWD3JNH-8bZxUpBi.js → diagram-7IWD3JNH-CoRwcTua.js} +1 -1
  56. package/web/assets/{diagram-B4RE2ZJO-CsGnKBa4.js → diagram-B4RE2ZJO-Cau1H7nm.js} +1 -1
  57. package/web/assets/{diagram-LBJQPF4R-CxaNBwKI.js → diagram-LBJQPF4R-CZIgxCTB.js} +1 -1
  58. package/web/assets/{diagram-Q27KOJAE-CjVLD6gb.js → diagram-Q27KOJAE-B_LnuCra.js} +1 -1
  59. package/web/assets/{diagram-S7CK7UJ4-MULGZGEL-wKLcWkw4.js → diagram-S7CK7UJ4-MULGZGEL-C7lZT5bQ.js} +1 -1
  60. package/web/assets/{diagram-UB23O5K3-CUZ34yVE.js → diagram-UB23O5K3-qTFCSozX.js} +1 -1
  61. package/web/assets/{diagram-UQ7AKVKN-YQBY353J-B_ah6OV8.js → diagram-UQ7AKVKN-YQBY353J-CIootVI_.js} +1 -1
  62. package/web/assets/{diagram-VSXAHHWV-WLNH2ELY-BhbJ7E_e.js → diagram-VSXAHHWV-WLNH2ELY-BW8LpgQJ.js} +1 -1
  63. package/web/assets/{diagram-VX7I27RA-XW6YQV5G-DnFEyO87.js → diagram-VX7I27RA-XW6YQV5G-DfhGfGMR.js} +1 -1
  64. package/web/assets/{diagram-Z3DM3KII-HG7RF65D-Vughovua.js → diagram-Z3DM3KII-HG7RF65D-seunnnEY.js} +1 -1
  65. package/web/assets/{ebnfDiagram-BXEA7PRR-B2ehf44X.js → ebnfDiagram-BXEA7PRR-ksZAvx5f.js} +1 -1
  66. package/web/assets/{ebnfDiagram-PWID7BFC-OKY4VHYD-BjbgNq8R.js → ebnfDiagram-PWID7BFC-OKY4VHYD-Bvj1acAA.js} +1 -1
  67. package/web/assets/{elk.bundled-CktUbZ7z.js → elk.bundled-DP5Rghza.js} +1 -1
  68. package/web/assets/{erDiagram-JOGREHBK-9wI_YE-7.js → erDiagram-JOGREHBK-Dz3-stVV.js} +1 -1
  69. package/web/assets/{erDiagram-SSCWMZ5O-PIPKOIK7-V60k7zg6.js → erDiagram-SSCWMZ5O-PIPKOIK7-DoltPq2T.js} +1 -1
  70. package/web/assets/{flowDiagram-A5DVABFB-2Z4AVO5R-CJdwjvtN.js → flowDiagram-A5DVABFB-2Z4AVO5R-EXpUdCkE.js} +1 -1
  71. package/web/assets/{flowDiagram-UKHOOZJN-B3XmqjMH.js → flowDiagram-UKHOOZJN--KUxj2rZ.js} +1 -1
  72. package/web/assets/{ganttDiagram-EL5Y4UJY-JZNG7GOG-2a6TiXM3.js → ganttDiagram-EL5Y4UJY-JZNG7GOG-B3_qeHhv.js} +1 -1
  73. package/web/assets/{ganttDiagram-PKOTCBZU-B7B9nD6g.js → ganttDiagram-PKOTCBZU-DDw97tpG.js} +1 -1
  74. package/web/assets/{gitGraphDiagram-DS77QQ5N-VwKL0Ozk.js → gitGraphDiagram-DS77QQ5N-DXUcbzn4.js} +1 -1
  75. package/web/assets/{gitGraphDiagram-WWUBYQGX-DMWMLL3G-BMs5FYkE.js → gitGraphDiagram-WWUBYQGX-DMWMLL3G-BrLu7NzO.js} +1 -1
  76. package/web/assets/{index-DFryMRAp.js → index-BUFumkqO.js} +4 -4
  77. package/web/assets/{index-xynt7zMk.js → index-C-4sKCSr.js} +1 -1
  78. package/web/assets/{index-DkjixD09.js → index-CODVWHV0.js} +1 -1
  79. package/web/assets/{index-Vtc_VHiK.js → index-CRlVl931.js} +1 -1
  80. package/web/assets/{index-D0FRqjBW.js → index-CrB9w7Gs.js} +1 -1
  81. package/web/assets/{infoDiagram-6WML65LV-CD6GNI7J.js → infoDiagram-6WML65LV-rLhQ8DQz.js} +1 -1
  82. package/web/assets/{infoDiagram-RXCK75RN-HANS5KVC-k8vzCiSp.js → infoDiagram-RXCK75RN-HANS5KVC-BhbqgWa_.js} +1 -1
  83. package/web/assets/{ishikawaDiagram-5VMMS53U-7GCIT7WU-Ckl5jIU6.js → ishikawaDiagram-5VMMS53U-7GCIT7WU-DR-PXM0c.js} +1 -1
  84. package/web/assets/{ishikawaDiagram-WSZJBQD7-CEdvuK4K.js → ishikawaDiagram-WSZJBQD7-Bf-J9Ov1.js} +1 -1
  85. package/web/assets/{journeyDiagram-EYS64GPL-OAPELBT7-DtCRso4h.js → journeyDiagram-EYS64GPL-OAPELBT7-jFQUZit6.js} +1 -1
  86. package/web/assets/{journeyDiagram-NVQOT4AX-CxPjI9L-.js → journeyDiagram-NVQOT4AX-CWed0L5n.js} +1 -1
  87. package/web/assets/{kanban-definition-27J2QSJJ-DnuNCFkl.js → kanban-definition-27J2QSJJ-DhTIozq4.js} +1 -1
  88. package/web/assets/{kanban-definition-3QL26DDD-I7RKWQQY-yNRn2nj0.js → kanban-definition-3QL26DDD-I7RKWQQY-MOg0W8Vc.js} +1 -1
  89. package/web/assets/{katex-N6JRN4PM-B9dEOiMG.js → katex-N6JRN4PM-DUl1EV3T.js} +1 -1
  90. package/web/assets/{main-CGE6fm01.js → main-D3HpSUyK.js} +9 -9
  91. package/web/assets/{mermaid-layout-elk.core-BUAJJUsd.js → mermaid-layout-elk.core-KBAfwQxu.js} +2 -2
  92. package/web/assets/{mermaid.core-BD32Za4p.js → mermaid.core-BVbO1Vp8.js} +4 -4
  93. package/web/assets/{mindmap-definition-FAOFIHXS-DX6VEGs_.js → mindmap-definition-FAOFIHXS-UC1xDIuF.js} +1 -1
  94. package/web/assets/{mindmap-definition-FBJOCRG2-KIYZG64Y-DYiBZnHG.js → mindmap-definition-FBJOCRG2-KIYZG64Y-DyTkl7Qq.js} +1 -1
  95. package/web/assets/{pegDiagram-VL7TDLO6-Big72xut.js → pegDiagram-VL7TDLO6-D3DtO4SS.js} +1 -1
  96. package/web/assets/{pegDiagram-XKGWAZYB-OIP57N6J-N0pgSR7W.js → pegDiagram-XKGWAZYB-OIP57N6J-D6RFGa8P.js} +1 -1
  97. package/web/assets/{pet-DopPVlAf.js → pet-BawFRWlx.js} +1 -1
  98. package/web/assets/{pieDiagram-7S7Q4E2Y-BLXLqOCg.js → pieDiagram-7S7Q4E2Y-Bggk64R7.js} +1 -1
  99. package/web/assets/{pieDiagram-E7YTZNPT-2UOTW327-BuB4rTS2.js → pieDiagram-E7YTZNPT-2UOTW327-DbtP5dKZ.js} +1 -1
  100. package/web/assets/{quadrantDiagram-AXDQQJYC-SN3ASJJK-4S-5LgOz.js → quadrantDiagram-AXDQQJYC-SN3ASJJK-CbdnLdcx.js} +1 -1
  101. package/web/assets/{quadrantDiagram-CIZ2JOQS-BUwizsLb.js → quadrantDiagram-CIZ2JOQS-D8oWqljf.js} +1 -1
  102. package/web/assets/{railroadDiagram-AXF67PYL-D3qxyYSE.js → railroadDiagram-AXF67PYL-DqYMsbyG.js} +1 -1
  103. package/web/assets/{railroadDiagram-O6MQD6OU-34742W6X-CzT_bN34.js → railroadDiagram-O6MQD6OU-34742W6X-BxDZ-lKK.js} +1 -1
  104. package/web/assets/{render-O7CIS3YK-DhYmSGoI.js → render-O7CIS3YK-C5zxvpoJ.js} +7 -7
  105. package/web/assets/{requirementDiagram-EFPCY7ZU-NGAFFSMB-iWwnW8VG.js → requirementDiagram-EFPCY7ZU-NGAFFSMB-vkMFulyy.js} +1 -1
  106. package/web/assets/{requirementDiagram-LRYGKXZP-Cf95T2or.js → requirementDiagram-LRYGKXZP-4uQ-OIOg.js} +1 -1
  107. package/web/assets/{rotate-ccw-natFwqj6.js → rotate-ccw-C3k3pTDh.js} +1 -1
  108. package/web/assets/{sankeyDiagram-P5KCCOFB-3D3M4XPB-CjA_LC6M.js → sankeyDiagram-P5KCCOFB-3D3M4XPB-Ct2_9lW6.js} +1 -1
  109. package/web/assets/{sankeyDiagram-W5VNT64P-CeGCHk7F.js → sankeyDiagram-W5VNT64P-CdtMmhMM.js} +1 -1
  110. package/web/assets/{sequenceDiagram-SI44F4Z6-BDsExCj2.js → sequenceDiagram-SI44F4Z6-BTa9vGYr.js} +1 -1
  111. package/web/assets/{sequenceDiagram-WJ2MYXX4-Q2IOPB4R-DbWhuP8u.js → sequenceDiagram-WJ2MYXX4-Q2IOPB4R-Du5hMpfL.js} +1 -1
  112. package/web/assets/{sizeCapture-X5ZJPWSS-PSGVOMYM-DB5JtURh.js → sizeCapture-X5ZJPWSS-PSGVOMYM-Dv_CbP4j.js} +1 -1
  113. package/web/assets/{sizeCapture-X5ZJPWSS-_5trx7u2.js → sizeCapture-X5ZJPWSS-xJHPAAZ7.js} +1 -1
  114. package/web/assets/{stateDiagram-HBIQ2CUA-4M2S6MAN-CBEhL8_A.js → stateDiagram-HBIQ2CUA-4M2S6MAN-BhhZM57P.js} +1 -1
  115. package/web/assets/{stateDiagram-OKZ733FA-BPHwMfDA.js → stateDiagram-OKZ733FA-CHCQNs83.js} +1 -1
  116. package/web/assets/stateDiagram-v2-4QOOHH4V-LBBLA2WV-CNwPFEas.js +1 -0
  117. package/web/assets/stateDiagram-v2-UEYNNEHI-uaaN79rE.js +1 -0
  118. package/web/assets/{swimlanes-SLNWSIFB-CDgj9OM9.js → swimlanes-SLNWSIFB-Bste-JE-.js} +2 -2
  119. package/web/assets/{swimlanes-XN3QIQJK-N6N2CCQ6-D3F0tmOR.js → swimlanes-XN3QIQJK-N6N2CCQ6-03elMVxe.js} +1 -1
  120. package/web/assets/swimlanesDiagram-ULZ7WXOC-CNw-u2S_.js +8 -0
  121. package/web/assets/swimlanesDiagram-VK2B7HYN-E6N4H5SY-jhFh1EB2.js +8 -0
  122. package/web/assets/{timeline-definition-24CTP7MA-KN7RSRVM-C0Ufqqk-.js → timeline-definition-24CTP7MA-KN7RSRVM-Cba_QLsv.js} +1 -1
  123. package/web/assets/{timeline-definition-Z64GVDOM-81O3UI2y.js → timeline-definition-Z64GVDOM-nDvkF_F-.js} +1 -1
  124. package/web/assets/{vennDiagram-4TSXK5OY-AKJ7LXAN-Cwa7TjWJ.js → vennDiagram-4TSXK5OY-AKJ7LXAN-Bjm0zDVN.js} +1 -1
  125. package/web/assets/{vennDiagram-T6HMQDX7-BfOTIcvk.js → vennDiagram-T6HMQDX7-KudBxp6e.js} +1 -1
  126. package/web/assets/{wardleyDiagram-T6FBY63Y-CYCyu4_S.js → wardleyDiagram-T6FBY63Y-d1R0A5mS.js} +1 -1
  127. package/web/assets/{wardleyDiagram-VM6X3IG4-3B6A3BN5-CHXrbpNv.js → wardleyDiagram-VM6X3IG4-3B6A3BN5-BOTe--eD.js} +1 -1
  128. package/web/assets/{xychartDiagram-ELKLHX3M-7mp6PB7p.js → xychartDiagram-ELKLHX3M-ChfX530c.js} +1 -1
  129. package/web/assets/{xychartDiagram-S5SC5T6Z-OBDNV6WG-Ch73fB_B.js → xychartDiagram-S5SC5T6Z-OBDNV6WG-DcSRUgks.js} +1 -1
  130. package/web/index.html +2 -2
  131. package/web/pet.html +2 -2
  132. package/web/assets/SettingsView-dExmRnIv.js +0 -7
  133. package/web/assets/channel-KoPlHvUR.js +0 -1
  134. package/web/assets/classDiagram-DTDB5LWJ-LWRDKZ5K-P8Aw4zHn.js +0 -1
  135. package/web/assets/classDiagram-JCYQIIEL-Dm2NSERp.js +0 -1
  136. package/web/assets/classDiagram-v2-JRS7N3AN-2BZHGRP2-P8Aw4zHn.js +0 -1
  137. package/web/assets/classDiagram-v2-OCEON4UE-Dm2NSERp.js +0 -1
  138. package/web/assets/stateDiagram-v2-4QOOHH4V-LBBLA2WV-lZeXiw9L.js +0 -1
  139. package/web/assets/stateDiagram-v2-UEYNNEHI-cH9YNExR.js +0 -1
  140. package/web/assets/swimlanesDiagram-ULZ7WXOC-C3faa0-8.js +0 -8
  141. package/web/assets/swimlanesDiagram-VK2B7HYN-E6N4H5SY-D5nVBF4q.js +0 -8
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lookatstudy-mobile",
3
- "version": "0.23.1",
3
+ "version": "0.24.0",
4
4
  "description": "LookatStudy Termux portable bundle (server.cjs + web frontend)",
5
5
  "repository": {
6
6
  "type": "git",
package/server.cjs CHANGED
@@ -62420,6 +62420,9 @@ ${standaloneImages.map((img) => `- "${img.path}" (\u63CF\u8FF0: ${img.alt})`).jo
62420
62420
  - **\u7F51\u9875\u6765\u6E90\u7684\u6B63\u6587\u8FB9\u754C(2026-08-23)**:\u7F51\u9875\u62BD\u53D6\u7684\u6587\u4EF6(url/arXiv/\u6587\u7AE0\u7C7B)\u5C3E\u90E8\u5E38\u6B8B\u7559\u63A8\u5E7F\u6BB5\u3001\u5173\u6CE8\u5F15\u5BFC\u3001
62421
62421
  \u76F8\u5173\u9605\u8BFB\u7B49\u975E\u6B63\u6587\u5185\u5BB9\u3002\u5224\u65AD"\u5C3E\u90E8\u4E00\u6BB5\u662F\u5426\u5C5E\u4E8E\u6B63\u6587"\u662F\u8BED\u4E49\u5224\u65AD,\u4EA4\u7ED9\u4F60:\u660E\u663E\u662F\u4F5C\u8005\u884C\u6587\u4E00\u90E8\u5206\u7684\u4FDD\u7559;
62422
62422
  \u660E\u663E\u662F\u6A21\u677F\u6216\u4E0E\u4E3B\u9898\u65E0\u5173\u7684\u63A8\u5E7F\u5C0F\u6BB5,\u4E0D\u8981\u4E3A\u5B83\u5355\u72EC\u5EFA lesson,anchor \u4E5F\u4E0D\u8981\u622A\u5230\u5B83(\u6B63\u6587\u5728\u54EA\u7ED3\u675F\u4F60\u8BF4\u4E86\u7B97)
62423
+ - **\u4E66\u7C4D\u7684\u524D\u7F6E/\u5916\u56F4\u5C0F\u9875(2026-08-23)**:\u7535\u5B50\u4E66\u6765\u6E90\u53EF\u80FD\u6709\u51FA\u7248\u793E\u5BA3\u4F20\u9875\u3001\u4F5C\u8005/\u8BD1\u8005\u7B80\u4ECB\u3001Digital Lab \u4E4B\u7C7B
62424
+ \u7684\u51FA\u7248\u65B9\u4ECB\u7ECD\u9875\u2014\u2014\u6807\u9898\u53EB"\u672A\u547D\u540D\u7AE0\u8282"\u7684\u6587\u4EF6\u662F\u89E3\u6790\u5C42\u8BDA\u5B9E\u6807\u6CE8"\u65E0\u6807\u9898"(\u4E0D\u662F\u539F\u4E66\u6807\u9898),\u6309\u5185\u5BB9\u4E3B\u9898\u547D\u540D\u3002
62425
+ \u660E\u663E\u4E0E\u4E66\u7684\u5185\u5BB9\u65E0\u5173\u7684\u5916\u56F4\u5C0F\u9875(\u51FA\u7248\u65B9\u4ECB\u7ECD/\u5BA3\u4F20\u8BED),\u4E0D\u8981\u4E3A\u5B83\u5355\u72EC\u5EFA lesson,\u5E76\u5165\u9996\u7AE0\u6216\u5FFD\u7565
62423
62426
  - \u4EE3\u7801\u6587\u4EF6(.py/.js/.go \u7B49): \u6559\u7A0B\u578B\u4EE3\u7801(\u5E26\u8BE6\u7EC6\u6CE8\u91CA/docstring) \u2192 study world; \u5DE5\u5177/\u811A\u672C/\u7EC3\u4E60 \u2192 practice world
62424
62427
  - \u4EE3\u7801\u6587\u4EF6\u901A\u5E38\u65E0 H2/H3 \u6807\u9898\uFF0CtotalChars \u5C31\u662F\u6587\u4EF6\u5927\u5C0F\uFF0C\u4E0D\u62C6\u5206\uFF0C\u6574\u4F53\u4E00\u4E2A lesson
62425
62428
 
@@ -519065,6 +519068,7 @@ async function parseEpub(buf) {
519065
519068
  if (tocLabels.size === 0 && spineTocId && manifest.has(spineTocId)) {
519066
519069
  tocLabels = parseTocLabels(read2(resolveZipPath(opfPath, manifest.get(spineTocId).href)), true);
519067
519070
  }
519071
+ const UNTITLED_MARK = "\u672A\u547D\u540D\u7AE0\u8282";
519068
519072
  const opfDirKey = (href) => decodeURIComponent(href.split("#")[0] ?? href).replace(/\\/g, "/");
519069
519073
  const chapters = [];
519070
519074
  let n = 0;
@@ -519087,11 +519091,21 @@ async function parseEpub(buf) {
519087
519091
  n++;
519088
519092
  const body0 = md.startsWith("# ") && md.includes("\n") ? md.slice(md.indexOf("\n") + 1).trim() : md;
519089
519093
  const firstHeading = md.startsWith("# ") ? md.split("\n")[0].slice(2).trim() : "";
519090
- const fileTitle = tocLabels.get(opfDirKey(item.href)) || firstHeading || `\u7B2C ${n} \u7AE0`;
519094
+ const fileTitle = tocLabels.get(opfDirKey(item.href)) || firstHeading || UNTITLED_MARK;
519091
519095
  if (/^(contents|table of contents)$/i.test(fileTitle) && body0.replace(/\s/g, "").length < 4e3)
519092
519096
  continue;
519093
519097
  if (body0.replace(/\s/g, "").length < 1500 && /project gutenberg|copyright/i.test(body0))
519094
519098
  continue;
519099
+ if (/^(版权信息|版权|版权页|著作权|版權)/.test(fileTitle))
519100
+ continue;
519101
+ const colophonFields = (body0.match(/^(书名|作者|译者|编者|丛书|出版社|出版时间|出版年|ISBN|版次|定价|装帧|字数|品牌|出品方)[::]/gm) ?? []).length;
519102
+ if (colophonFields >= 3 && body0.replace(/\s/g, "").length < 2500)
519103
+ continue;
519104
+ if (/^目\s*录$/.test(fileTitle)) {
519105
+ const lines = body0.split("\n").map((l) => l.trim()).filter(Boolean);
519106
+ if (lines.length >= 3 && lines.filter((l) => l.includes("](")).length / lines.length >= 0.6)
519107
+ continue;
519108
+ }
519095
519109
  const body = sanitizeEpubBody(body0);
519096
519110
  if (body.replace(/\s/g, "").length < 8)
519097
519111
  continue;
@@ -519131,6 +519145,33 @@ ${body}`
519131
519145
  ${body}`
519132
519146
  });
519133
519147
  }
519148
+ const absorbed = /* @__PURE__ */ new Set();
519149
+ for (let i = 0; i + 1 < chapters.length; i++) {
519150
+ const stub = chapters[i];
519151
+ const next = chapters[i + 1];
519152
+ if (absorbed.has(stub.path))
519153
+ continue;
519154
+ const stubBody = stub.markdown.includes("\n") ? stub.markdown.slice(stub.markdown.indexOf("\n") + 1).trim() : "";
519155
+ if (stub.title === UNTITLED_MARK || stub.title === "\u9644\u5F55")
519156
+ continue;
519157
+ if (stubBody.replace(/\s/g, "").length > 300)
519158
+ continue;
519159
+ if (next.title !== UNTITLED_MARK)
519160
+ continue;
519161
+ const nextBody = next.markdown.includes("\n") ? next.markdown.slice(next.markdown.indexOf("\n") + 1).trim() : next.markdown;
519162
+ chapters[i] = {
519163
+ path: stub.path,
519164
+ title: stub.title,
519165
+ markdown: `# ${stub.title}
519166
+
519167
+ ${stubBody}
519168
+
519169
+ ${nextBody}`
519170
+ };
519171
+ absorbed.add(stub.path);
519172
+ chapters.splice(i + 1, 1);
519173
+ i--;
519174
+ }
519134
519175
  if (chapters.length === 0)
519135
519176
  throw new Error("epub \u91CC\u6CA1\u6709\u53EF\u8BC6\u522B\u7684\u7AE0\u8282\u6587\u672C");
519136
519177
  return { title: bookTitle, chapters };
@@ -1,4 +1,4 @@
1
- import{r,j as h}from"./index-xynt7zMk.js";import{c as T,u as L,P as D}from"./main-CGE6fm01.js";/**
1
+ import{r,j as h}from"./index-C-4sKCSr.js";import{c as T,u as L,P as D}from"./main-D3HpSUyK.js";/**
2
2
  * @license lucide-react v0.468.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
1
- import{r as s,j as t}from"./index-xynt7zMk.js";import{c as y,u as v,b as k,L as j,F as N,M as w,G as C,T as M,d as _}from"./main-CGE6fm01.js";/**
1
+ import{r as s,j as t}from"./index-C-4sKCSr.js";import{c as y,u as v,b as k,L as j,F as N,M as w,G as C,T as M,d as _}from"./main-D3HpSUyK.js";/**
2
2
  * @license lucide-react v0.468.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
1
- import{r as u,j as t}from"./index-xynt7zMk.js";import{c as C,U as I,u as y,a as L,d as S,X as N,g as M,T as E,C as R}from"./main-CGE6fm01.js";/**
1
+ import{r as u,j as t}from"./index-C-4sKCSr.js";import{c as C,U as I,u as y,a as L,d as S,X as N,g as M,T as E,C as R}from"./main-D3HpSUyK.js";/**
2
2
  * @license lucide-react v0.468.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
1
- import{r as o,k as U,j as e,c as ie}from"./index-xynt7zMk.js";import{c as te,u as ce,a as j,l as de,T as z,p as Y,L as V,k as oe,X as xe}from"./main-CGE6fm01.js";import{R as G}from"./rotate-ccw-natFwqj6.js";import{A as q}from"./arrow-right-D4GV0Gpo.js";/**
1
+ import{r as o,h as U,j as e,c as ie}from"./index-C-4sKCSr.js";import{c as te,u as ce,a as j,h as de,T as z,i as Y,L as V,j as oe,X as xe}from"./main-D3HpSUyK.js";import{R as G}from"./rotate-ccw-C3k3pTDh.js";import{A as q}from"./arrow-right-B0QrRNSR.js";/**
2
2
  * @license lucide-react v0.468.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
1
- const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["./index-DkjixD09.js","./index-CU6ublfJ.js","./index-xynt7zMk.js","./index-DjoBjasB.css","./index-H1bePBGl.js","./transform-CzGDKG_M.js","./min-tv6RD-6E.js","./ordinal-Cboi1Yqb.js","./init-Gi6I4Gst.js","./colors-Cc3OSVma.js"])))=>i.map(i=>d[i]);
2
- import{u as v,_ as d,B as _}from"./main-CGE6fm01.js";import{r as o,j as a}from"./index-xynt7zMk.js";import{C as w}from"./CanvasStage-Ba-21anG.js";function b(c){const e=[];let t=null,n=0;for(const r of c.split(`
1
+ const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["./index-CODVWHV0.js","./index-CU6ublfJ.js","./index-C-4sKCSr.js","./index-DjoBjasB.css","./index-H1bePBGl.js","./transform-CzGDKG_M.js","./min-tv6RD-6E.js","./ordinal-Cboi1Yqb.js","./init-Gi6I4Gst.js","./colors-Cc3OSVma.js"])))=>i.map(i=>d[i]);
2
+ import{u as v,_ as d,B as _}from"./main-D3HpSUyK.js";import{r as o,j as a}from"./index-C-4sKCSr.js";import{C as w}from"./CanvasStage-u_7YeGk1.js";function b(c){const e=[];let t=null,n=0;for(const r of c.split(`
3
3
  `)){const s=/^(\s*)(`{3,}|~{3,})/.exec(r);if(t==null){if(s){t=(s[2]??"")[0]??"`",n=(s[2]??"").length,e.push(`${s[1]??""}- 代码块`);continue}e.push(r)}else new RegExp(`^\\s*\\${t==="~"?"~":"`"}{${n},}\\s*$`).test(r)&&(t=null)}return e.join(`
4
- `).replace(/!\[([^\]]*)\]\([^)]*\)/g,"$1").replace(/<!--[\s\S]*?-->/g,"")}function E(){if(typeof document>"u")return["#58cc02","#1cb0f6","#ffc800","#a67cd8","#ff7a00"];const c=getComputedStyle(document.documentElement),e=(t,n)=>{const r=c.getPropertyValue(t).trim();return r?`rgb(${r})`:n};return[e("--brand-rgb","#58cc02"),e("--accent-rgb","#1cb0f6"),e("--gold-rgb","#ffc800"),"#a67cd8",e("--warning-rgb","#ff7a00")]}function P({markdown:c}){const e=v(),t=o.useRef(null),n=o.useRef(null),[r,s]=o.useState(!1),i=b(c);return o.useEffect(()=>{let l=!1;return(async()=>{try{const[{Transformer:p},{Markmap:g}]=await Promise.all([d(()=>import("./index-DkjixD09.js"),__vite__mapDeps([0,1,2,3]),import.meta.url),d(()=>import("./index-H1bePBGl.js"),__vite__mapDeps([4,1,5,6,7,8,9]),import.meta.url)]),u=t.current;if(!u||l)return;if(!n.current){const f=E();n.current=g.create(u,{autoFit:!1,duration:0,pan:!1,zoom:!1,initialExpandLevel:2,maxWidth:260,spacingVertical:10,spacingHorizontal:96,paddingX:12,color:h=>{var m;return f[(((m=h.state)==null?void 0:m.depth)??0)%f.length]??f[0]}})}const{root:x}=new p().transform(i);n.current.setData(x),n.current.fit()}catch{l||s(!0)}})(),()=>{l=!0}},[i]),r?a.jsxs("div",{className:"text-body text-ink-muted flex items-center gap-2 my-4",children:[a.jsx(_,{className:"w-4 h-4"}),e("notebook.content.render_failed")]}):a.jsx("div",{"data-testid":"mindmap-view",className:"mindmap-view h-[68vh] min-h-[420px] my-2",children:a.jsx(w,{grid:!0,testid:"mindmap-stage",children:a.jsx("div",{className:"w-[1280px] h-[760px]",children:a.jsx("svg",{ref:t,className:"w-full h-full block"})})})})}export{P as MindmapView};
4
+ `).replace(/!\[([^\]]*)\]\([^)]*\)/g,"$1").replace(/<!--[\s\S]*?-->/g,"")}function E(){if(typeof document>"u")return["#58cc02","#1cb0f6","#ffc800","#a67cd8","#ff7a00"];const c=getComputedStyle(document.documentElement),e=(t,n)=>{const r=c.getPropertyValue(t).trim();return r?`rgb(${r})`:n};return[e("--brand-rgb","#58cc02"),e("--accent-rgb","#1cb0f6"),e("--gold-rgb","#ffc800"),"#a67cd8",e("--warning-rgb","#ff7a00")]}function P({markdown:c}){const e=v(),t=o.useRef(null),n=o.useRef(null),[r,s]=o.useState(!1),i=b(c);return o.useEffect(()=>{let l=!1;return(async()=>{try{const[{Transformer:p},{Markmap:g}]=await Promise.all([d(()=>import("./index-CODVWHV0.js"),__vite__mapDeps([0,1,2,3]),import.meta.url),d(()=>import("./index-H1bePBGl.js"),__vite__mapDeps([4,1,5,6,7,8,9]),import.meta.url)]),u=t.current;if(!u||l)return;if(!n.current){const f=E();n.current=g.create(u,{autoFit:!1,duration:0,pan:!1,zoom:!1,initialExpandLevel:2,maxWidth:260,spacingVertical:10,spacingHorizontal:96,paddingX:12,color:h=>{var m;return f[(((m=h.state)==null?void 0:m.depth)??0)%f.length]??f[0]}})}const{root:x}=new p().transform(i);n.current.setData(x),n.current.fit()}catch{l||s(!0)}})(),()=>{l=!0}},[i]),r?a.jsxs("div",{className:"text-body text-ink-muted flex items-center gap-2 my-4",children:[a.jsx(_,{className:"w-4 h-4"}),e("notebook.content.render_failed")]}):a.jsx("div",{"data-testid":"mindmap-view",className:"mindmap-view h-[68vh] min-h-[420px] my-2",children:a.jsx(w,{grid:!0,testid:"mindmap-stage",children:a.jsx("div",{className:"w-[1280px] h-[760px]",children:a.jsx("svg",{ref:t,className:"w-full h-full block"})})})})}export{P as MindmapView};
@@ -1 +1 @@
1
- import{r,j as e,c as S}from"./index-xynt7zMk.js";import{u as y,a as j,S as M}from"./main-CGE6fm01.js";function A({tree:c,onReviewNode:d,progressMap:n}){const s=y(),[x,m]=r.useState([]),[u,f]=r.useState(!0),[l,v]=r.useState(null);r.useEffect(()=>{j.getAllSrsItems().then(t=>m(t)).catch(()=>m([])).finally(()=>f(!1))},[]);const N=r.useMemo(()=>new Map(c.map(t=>[t.id,t])),[c]),p=r.useMemo(()=>new Set(x.filter(t=>t.overdue).map(t=>t.nodeId)),[x]),i=r.useMemo(()=>{const t=c.filter(b=>{var w;const o=(w=n[b.id])==null?void 0:w.status;return b.type==="lesson"&&(o==="in_progress"||o==="mastered")}),a=new Map;for(const b of t){const o=b.parentId??"(root)";a.has(o)||a.set(o,[]),a.get(o).push(b)}return a},[c,n]),g=r.useMemo(()=>Array.from(i.values()).flat().filter(t=>p.has(t.id)).length,[i,p]),h=r.useMemo(()=>Array.from(i.values()).flat(),[i]);if(r.useEffect(()=>{if(i.size>0&&(!l||!i.has(l))){const t=i.keys().next().value;t&&v(t)}},[i,l]),u)return e.jsxs("div",{className:"text-center py-12 text-body text-ink-muted flex items-center justify-center gap-2",children:[e.jsx("span",{className:"typing-dot w-1.5 h-1.5 bg-brand rounded-full inline-block"}),s("review.loading")]});if(h.length===0)return e.jsxs("div",{className:"text-center py-16","data-testid":"review-empty",children:[e.jsx("div",{className:"text-4xl mb-3 opacity-30",children:"📖"}),e.jsx("div",{className:"text-body text-ink-muted",children:s("review.empty.title")}),e.jsx("div",{className:"text-label text-ink-faint mt-1",children:s("review.empty.desc")})]});const k=t=>{var a;return((a=N.get(t))==null?void 0:a.title)??t};return e.jsxs("div",{className:"p-5 max-w-2xl mx-auto","data-testid":"review-panel",children:[e.jsxs("div",{className:"flex items-center justify-between mb-4",children:[e.jsx("h2",{className:"text-title font-extrabold text-ink-strong",children:s("review.title")}),g>0&&e.jsxs("span",{className:"text-label font-bold text-review","data-testid":"review-due-count",children:[g," ",s("review.due.count")]})]}),e.jsxs("button",{onClick:()=>{const t=h[Math.floor(Math.random()*h.length)];t&&d(t.id)},"data-testid":"review-interleave",className:"btn-3d-neutral w-full py-2.5 text-body mb-5 flex items-center justify-center gap-1.5",children:[e.jsx(M,{className:"w-4 h-4"}),s("review.interleave")]}),e.jsx("div",{className:"text-label font-bold text-ink-muted mb-2",children:s("review.selectSection")}),e.jsx("div",{className:"flex flex-wrap gap-1.5 mb-4",children:Array.from(i.entries()).map(([t,a])=>e.jsxs("button",{onClick:()=>v(t),className:`px-2.5 py-1 rounded-full text-label font-bold transition-colors ${l===t?"bg-brand/15 text-brand ring-1 ring-brand/30":"bg-surface-3 text-ink-muted hover:text-ink-strong"}`,children:[k(t),e.jsxs("span",{className:"ml-1 opacity-60",children:["(",a.length,")"]})]},t))}),l&&i.has(l)&&e.jsx("div",{className:"space-y-1.5","data-testid":"review-lesson-list",children:i.get(l).map(t=>{const a=p.has(t.id);return e.jsxs("div",{className:`flex items-center justify-between gap-2 p-2.5 rounded-lg transition-colors ${a?"bg-review/8 ring-1 ring-review/20":"bg-surface-3 hover:bg-surface-3/80"}`,children:[e.jsxs("div",{className:"flex items-center gap-1.5 truncate flex-1",children:[a&&e.jsx("span",{className:"shrink-0 w-1.5 h-1.5 rounded-full bg-review"}),e.jsx("span",{className:"text-body text-ink-strong truncate",children:t.title})]}),e.jsx("button",{onClick:()=>d(t.id),"data-testid":`review-lesson-${t.id.slice(0,8)}`,className:"shrink-0 px-3 py-1 rounded-lg bg-brand/15 text-brand text-label font-bold hover:bg-brand/25 transition-colors",children:s("review.reviewLesson")})]},t.id)})})]})}function E({nodeId:c,onRated:d}){const n=y(),[s,x]=r.useState(!1),[m,u]=r.useState(!1),f=async l=>{if(!(s||m)){x(!0);try{await j.recordReview(c,l),u(!0),d==null||d(),S(l>=4?"correct":"wrong")}catch{}finally{x(!1)}}};return m?e.jsx("div",{className:"text-center text-body text-brand py-2","data-testid":"self-rated",children:n("review.selfrated")}):e.jsxs("div",{className:"border-t border-[var(--border-faint)] pt-3 mt-3","data-testid":"self-rating",children:[e.jsx("div",{className:"text-caption font-bold text-ink-muted uppercase tracking-wider mb-2 text-center",children:n("review.selfrate.title")}),e.jsxs("div",{className:"grid grid-cols-3 gap-2",children:[e.jsxs("button",{onClick:()=>f(1),disabled:s,"data-testid":"rate-again",className:"py-2 rounded-lg border border-warning/40 text-warning hover:bg-warning/10 transition-colors disabled:opacity-40 flex flex-col items-center gap-0.5",children:[e.jsx("span",{className:"text-body font-bold",children:n("review.selfrate.again")}),e.jsx("span",{className:"text-caption opacity-70",children:n("review.selfrate.again.hint")})]}),e.jsxs("button",{onClick:()=>f(4),disabled:s,"data-testid":"rate-remembered",className:"py-2 rounded-lg border border-accent/40 text-accent hover:bg-accent/10 transition-colors disabled:opacity-40 flex flex-col items-center gap-0.5",children:[e.jsx("span",{className:"text-body font-bold",children:n("review.selfrate.remembered")}),e.jsx("span",{className:"text-caption opacity-70",children:n("review.selfrate.remembered.hint")})]}),e.jsxs("button",{onClick:()=>f(5),disabled:s,"data-testid":"rate-mastered",className:"py-2 rounded-lg border border-brand/40 text-brand hover:bg-brand/10 transition-colors disabled:opacity-40 flex flex-col items-center gap-0.5",children:[e.jsx("span",{className:"text-body font-bold",children:n("review.selfrate.mastered")}),e.jsx("span",{className:"text-caption opacity-70",children:n("review.selfrate.mastered.hint")})]})]})]})}export{A as ReviewPanel,E as SelfRatingCard};
1
+ import{r,j as e,c as S}from"./index-C-4sKCSr.js";import{u as y,a as j,S as M}from"./main-D3HpSUyK.js";function A({tree:c,onReviewNode:d,progressMap:n}){const s=y(),[x,m]=r.useState([]),[u,f]=r.useState(!0),[l,v]=r.useState(null);r.useEffect(()=>{j.getAllSrsItems().then(t=>m(t)).catch(()=>m([])).finally(()=>f(!1))},[]);const N=r.useMemo(()=>new Map(c.map(t=>[t.id,t])),[c]),p=r.useMemo(()=>new Set(x.filter(t=>t.overdue).map(t=>t.nodeId)),[x]),i=r.useMemo(()=>{const t=c.filter(b=>{var w;const o=(w=n[b.id])==null?void 0:w.status;return b.type==="lesson"&&(o==="in_progress"||o==="mastered")}),a=new Map;for(const b of t){const o=b.parentId??"(root)";a.has(o)||a.set(o,[]),a.get(o).push(b)}return a},[c,n]),g=r.useMemo(()=>Array.from(i.values()).flat().filter(t=>p.has(t.id)).length,[i,p]),h=r.useMemo(()=>Array.from(i.values()).flat(),[i]);if(r.useEffect(()=>{if(i.size>0&&(!l||!i.has(l))){const t=i.keys().next().value;t&&v(t)}},[i,l]),u)return e.jsxs("div",{className:"text-center py-12 text-body text-ink-muted flex items-center justify-center gap-2",children:[e.jsx("span",{className:"typing-dot w-1.5 h-1.5 bg-brand rounded-full inline-block"}),s("review.loading")]});if(h.length===0)return e.jsxs("div",{className:"text-center py-16","data-testid":"review-empty",children:[e.jsx("div",{className:"text-4xl mb-3 opacity-30",children:"📖"}),e.jsx("div",{className:"text-body text-ink-muted",children:s("review.empty.title")}),e.jsx("div",{className:"text-label text-ink-faint mt-1",children:s("review.empty.desc")})]});const k=t=>{var a;return((a=N.get(t))==null?void 0:a.title)??t};return e.jsxs("div",{className:"p-5 max-w-2xl mx-auto","data-testid":"review-panel",children:[e.jsxs("div",{className:"flex items-center justify-between mb-4",children:[e.jsx("h2",{className:"text-title font-extrabold text-ink-strong",children:s("review.title")}),g>0&&e.jsxs("span",{className:"text-label font-bold text-review","data-testid":"review-due-count",children:[g," ",s("review.due.count")]})]}),e.jsxs("button",{onClick:()=>{const t=h[Math.floor(Math.random()*h.length)];t&&d(t.id)},"data-testid":"review-interleave",className:"btn-3d-neutral w-full py-2.5 text-body mb-5 flex items-center justify-center gap-1.5",children:[e.jsx(M,{className:"w-4 h-4"}),s("review.interleave")]}),e.jsx("div",{className:"text-label font-bold text-ink-muted mb-2",children:s("review.selectSection")}),e.jsx("div",{className:"flex flex-wrap gap-1.5 mb-4",children:Array.from(i.entries()).map(([t,a])=>e.jsxs("button",{onClick:()=>v(t),className:`px-2.5 py-1 rounded-full text-label font-bold transition-colors ${l===t?"bg-brand/15 text-brand ring-1 ring-brand/30":"bg-surface-3 text-ink-muted hover:text-ink-strong"}`,children:[k(t),e.jsxs("span",{className:"ml-1 opacity-60",children:["(",a.length,")"]})]},t))}),l&&i.has(l)&&e.jsx("div",{className:"space-y-1.5","data-testid":"review-lesson-list",children:i.get(l).map(t=>{const a=p.has(t.id);return e.jsxs("div",{className:`flex items-center justify-between gap-2 p-2.5 rounded-lg transition-colors ${a?"bg-review/8 ring-1 ring-review/20":"bg-surface-3 hover:bg-surface-3/80"}`,children:[e.jsxs("div",{className:"flex items-center gap-1.5 truncate flex-1",children:[a&&e.jsx("span",{className:"shrink-0 w-1.5 h-1.5 rounded-full bg-review"}),e.jsx("span",{className:"text-body text-ink-strong truncate",children:t.title})]}),e.jsx("button",{onClick:()=>d(t.id),"data-testid":`review-lesson-${t.id.slice(0,8)}`,className:"shrink-0 px-3 py-1 rounded-lg bg-brand/15 text-brand text-label font-bold hover:bg-brand/25 transition-colors",children:s("review.reviewLesson")})]},t.id)})})]})}function E({nodeId:c,onRated:d}){const n=y(),[s,x]=r.useState(!1),[m,u]=r.useState(!1),f=async l=>{if(!(s||m)){x(!0);try{await j.recordReview(c,l),u(!0),d==null||d(),S(l>=4?"correct":"wrong")}catch{}finally{x(!1)}}};return m?e.jsx("div",{className:"text-center text-body text-brand py-2","data-testid":"self-rated",children:n("review.selfrated")}):e.jsxs("div",{className:"border-t border-[var(--border-faint)] pt-3 mt-3","data-testid":"self-rating",children:[e.jsx("div",{className:"text-caption font-bold text-ink-muted uppercase tracking-wider mb-2 text-center",children:n("review.selfrate.title")}),e.jsxs("div",{className:"grid grid-cols-3 gap-2",children:[e.jsxs("button",{onClick:()=>f(1),disabled:s,"data-testid":"rate-again",className:"py-2 rounded-lg border border-warning/40 text-warning hover:bg-warning/10 transition-colors disabled:opacity-40 flex flex-col items-center gap-0.5",children:[e.jsx("span",{className:"text-body font-bold",children:n("review.selfrate.again")}),e.jsx("span",{className:"text-caption opacity-70",children:n("review.selfrate.again.hint")})]}),e.jsxs("button",{onClick:()=>f(4),disabled:s,"data-testid":"rate-remembered",className:"py-2 rounded-lg border border-accent/40 text-accent hover:bg-accent/10 transition-colors disabled:opacity-40 flex flex-col items-center gap-0.5",children:[e.jsx("span",{className:"text-body font-bold",children:n("review.selfrate.remembered")}),e.jsx("span",{className:"text-caption opacity-70",children:n("review.selfrate.remembered.hint")})]}),e.jsxs("button",{onClick:()=>f(5),disabled:s,"data-testid":"rate-mastered",className:"py-2 rounded-lg border border-brand/40 text-brand hover:bg-brand/10 transition-colors disabled:opacity-40 flex flex-col items-center gap-0.5",children:[e.jsx("span",{className:"text-body font-bold",children:n("review.selfrate.mastered")}),e.jsx("span",{className:"text-caption opacity-70",children:n("review.selfrate.mastered.hint")})]})]})]})}export{A as ReviewPanel,E as SelfRatingCard};
@@ -0,0 +1,7 @@
1
+ import{r as a,j as e,s as Ze,k as Qe,C as et,M as tt}from"./index-C-4sKCSr.js";import{c as st,u as de,k as ne,l as he,a as i,W as $e,P as nt,m as ze,s as at,j as it,h as lt,n as ot,o as dt,p as rt}from"./main-D3HpSUyK.js";/**
2
+ * @license lucide-react v0.468.0 - ISC
3
+ *
4
+ * This source code is licensed under the ISC license.
5
+ * See the LICENSE file in the root directory of this source tree.
6
+ */const ct=st("RotateCw",[["path",{d:"M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8",key:"1p45f6"}],["path",{d:"M21 3v5h-5",key:"1q7to0"}]]),xe="bg-ink/[0.04] text-ink-strong text-label rounded-lg border border-transparent focus:border-accent focus:bg-ink/[0.06] transition-colors placeholder:text-ink-faint";function we({kind:t,showProtocol:x=!0,testPrefix:b="custom",titleKey:p="settings.custom.form_title",modelPhKey:c="settings.custom.model_ph",testOverride:d,onSaved:r,onCancel:h}){const m=de(),[j,T]=a.useState(""),[g,S]=a.useState("openai-compatible"),[y,P]=a.useState(""),[o,_]=a.useState(""),[k,W]=a.useState(""),[B,V]=a.useState(!1),[I,D]=a.useState(!1),[A,z]=a.useState(null),L=async()=>{if(!(!y.trim()||!k.trim()||I)){D(!0),z(null);try{const l=d?await d({baseUrl:y.trim(),apiKey:o.trim(),model:k.trim()}):await i.testCustomProvider({label:j||m("settings.custom.test_label"),protocol:g,baseUrl:y.trim(),apiKey:o.trim()||void 0,defaultModel:k.trim()});z({ok:l.ok,detail:l.detail})}catch(l){z({ok:!1,detail:l instanceof Error?l.message:String(l)})}finally{D(!1)}}},N=async()=>{if(!(!j.trim()||!y.trim()||!k.trim()))try{const l=await i.createCustomProvider({label:j.trim(),kind:t,protocol:x?g:"openai-compatible",baseUrl:y.trim(),apiKey:o.trim()||void 0,defaultModel:k.trim(),vision:t==="llm"?B:void 0});r(l)}catch{}};return e.jsxs("div",{className:"space-y-2.5","data-testid":`${b}-provider-form`,children:[e.jsx("div",{className:"text-label font-bold text-ink-strong",children:m(p)}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx("input",{type:"text",value:j,onChange:l=>T(l.target.value),placeholder:m("settings.custom.label_ph"),"data-testid":`${b}-label`,className:`${xe} flex-1 px-2.5 py-1.5`}),x&&e.jsxs("select",{value:g,onChange:l=>S(l.target.value),"data-testid":`${b}-protocol`,className:`${xe} px-2 py-1.5`,children:[e.jsx("option",{value:"openai-compatible",children:m("settings.proto.openai")}),e.jsx("option",{value:"anthropic",children:"Anthropic"}),e.jsx("option",{value:"google",children:"Google"})]})]}),e.jsx("input",{type:"text",value:y,onChange:l=>P(l.target.value),placeholder:m("settings.custom.baseurl_ph"),"data-testid":`${b}-baseurl`,className:`${xe} w-full px-2.5 py-1.5 font-mono`}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx("input",{type:"text",value:k,onChange:l=>W(l.target.value),placeholder:m(c),"data-testid":`${b}-model`,className:`${xe} flex-1 px-2.5 py-1.5 font-mono`}),e.jsx("input",{type:"password",value:o,onChange:l=>_(l.target.value),placeholder:m("settings.custom.apikey_ph"),"data-testid":`${b}-apikey`,className:`${xe} flex-1 px-2.5 py-1.5`})]}),t==="llm"&&e.jsxs("label",{className:"inline-flex items-center gap-2 text-label cursor-pointer select-none","data-testid":`${b}-vision`,children:[e.jsx("input",{type:"checkbox",checked:B,onChange:l=>V(l.target.checked),className:"w-4 h-4 rounded accent-brand"}),e.jsx("span",{className:"text-ink-strong",children:m("settings.custom.vision")}),e.jsx("span",{className:"text-ink-faint",children:m("settings.custom.visionHint")})]}),A&&e.jsxs("div",{className:`text-label rounded p-2 inline-flex items-start gap-1.5 ${A.ok?"bg-brand/10 text-brand":"bg-warning/10 text-warning"}`,children:[A.ok?e.jsx(ne,{className:"w-4 h-4 mt-px shrink-0","aria-hidden":"true"}):e.jsx(he,{className:"w-4 h-4 mt-px shrink-0","aria-hidden":"true"}),e.jsx("span",{className:"break-words",children:A.detail})]}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx("button",{onClick:()=>void L(),disabled:!y.trim()||!k.trim()||I,"data-testid":`${b}-test`,className:"btn-3d-neutral px-3 py-1.5 text-label disabled:opacity-40",children:m(I?"settings.testing":"settings.test")}),e.jsx("button",{onClick:()=>void N(),disabled:!j.trim()||!y.trim()||!k.trim(),"data-testid":`${b}-save`,className:"btn-3d-brand px-3 py-1.5 text-label disabled:opacity-40",children:m("settings.custom.save")}),h&&e.jsx("button",{onClick:h,className:"text-label text-ink-muted hover:text-ink-strong px-3 py-1.5 transition-colors",children:m("action.cancel")})]})]})}const We="lookatstudy-theme",Ke="auto",Ue="(prefers-color-scheme: dark)";function _e(){return typeof window>"u"||window.matchMedia(Ue).matches?"dark":"light"}function mt(){if(typeof localStorage>"u")return Ke;const t=localStorage.getItem(We);return t==="auto"||t==="light"||t==="dark"?t:Ke}function Ce(t){const x=document.documentElement;x.classList.remove("dark","light"),x.classList.add(t),window.dispatchEvent(new CustomEvent("theme-changed",{detail:{resolved:t}}))}function ut(){const[t,x]=a.useState(()=>mt()),[b,p]=a.useState(()=>t==="auto"?_e():t),c=a.useCallback(d=>{x(d),localStorage.setItem(We,d);const r=d==="auto"?_e():d;p(r),Ce(r)},[]);return a.useEffect(()=>{if(t!=="auto")return;const d=window.matchMedia(Ue),r=h=>{const m=h.matches?"dark":"light";p(m),Ce(m)};return d.addEventListener("change",r),()=>d.removeEventListener("change",r)},[t]),a.useEffect(()=>{const d=t==="auto"?_e():t;p(d),Ce(d)},[t]),{mode:t,resolved:b,setMode:c}}const xt="0.24.0",ht={version:xt};function ke(){window.dispatchEvent(new Event(rt))}const G="bg-surface-1 text-ink text-body rounded-lg border border-[var(--border)] focus:border-brand focus:outline-none transition-colors placeholder:text-ink-faint",F="bg-surface-3 text-ink-muted hover:bg-surface-3 hover:bg-surface-3 hover:text-ink-strong",R="bg-brand text-white shadow-sm";function v(t){return t?"px-4 py-3.5 border-t border-[var(--border-faint)]":"px-4 py-3.5"}function wt(){const t=de(),[x,b]=a.useState([]),[p,c]=a.useState([]),[d,r]=a.useState("glm"),[h,m]=a.useState(""),[j,T]=a.useState(""),[g,S]=a.useState(null),[y,P]=a.useState(!1),[o,_]=a.useState(null),[k,W]=a.useState(!1),[B,V]=a.useState(!1),[I,D]=a.useState([]),[A,z]=a.useState(!1),[L,N]=a.useState(null),[l,H]=a.useState(null),[Q,re]=a.useState(""),[ge,ce]=a.useState(!1),ee=ut(),ie=async n=>{if($)try{await i.updateCustomProvider($.id,{vision:n}),await U()}catch{}},le=async()=>{z(!0),N(null);try{const n=await i.discoverModels();n.ok&&n.models?D(n.models):N(n.error||t("settings.discover_failed"))}catch(n){N(n instanceof Error?n.message:String(n))}finally{z(!1)}},U=a.useCallback(async()=>{try{const[n,f,E,J]=await Promise.all([i.getProviderPresets(),i.listCustomProviders(),i.getSetting("active_provider"),i.getSetting("active_model")]);b(n),c(f);const M=E??"glm";if(r(M),M.startsWith("custom-")){const w=f.find(C=>C.id===M);S(w!=null&&w.hasApiKey?t("settings.key.configured"):null)}else{const w=n.find(C=>C.id===M);if(w){const C=await i.getSetting(w.apiKeySetting);S(C?`${C.slice(0,4)}…${C.slice(-4)}`:null)}}if(M.startsWith("custom-")){const w=f.find(C=>C.id===M);m(J??(w==null?void 0:w.defaultModel)??"")}else{const w=n.find(C=>C.id===M);m(J??(w==null?void 0:w.defaultModel)??"")}}catch(n){console.error("[SettingsView] load() failed:",n)}},[t]);a.useEffect(()=>{U()},[U]);const me=async n=>{r(n),_(null),T("");const f=x.find(E=>E.id===n);if(f){const E=await i.getSetting(f.apiKeySetting);S(E?`${E.slice(0,4)}…${E.slice(-4)}`:null),m(h||f.defaultModel)}},pe=async()=>{W(!1);try{if(await i.setSetting("active_provider",d),await i.setSetting("active_model",h),j.trim()){const n=x.find(f=>f.id===d);n&&(await i.setSetting(n.apiKeySetting,j.trim()),S(`${j.trim().slice(0,4)}…${j.trim().slice(-4)}`),T(""))}W(!0),setTimeout(()=>W(!1),2e3),window.dispatchEvent(new Event("llm-config-changed"))}catch{}},O=async()=>{P(!0),_(null);try{const n=await i.testLlmConnection();_(n)}catch(n){_({ok:!1,detail:n instanceof Error?n.message:String(n),errorKind:"unknown"})}finally{P(!1)}},fe=async n=>{await i.setSetting("active_provider",n.id),await i.setSetting("active_model",n.defaultModel),r(n.id),m(n.defaultModel),V(!1),await U(),window.dispatchEvent(new Event("llm-config-changed"))},te=async n=>{try{await i.deleteCustomProvider(n),d===n&&(await i.setSetting("active_provider","glm"),r("glm")),await U()}catch{}},$=d.startsWith("custom-")?p.find(n=>n.id===d):null;a.useEffect(()=>{if(!$)return;const n=$.models.find(f=>f.id===h);re(n!=null&&n.contextWindow?String(n.contextWindow):"")},[$,h]);const be=async()=>{var M,w;if(!$)return;const n=Q.trim().replace(/[,\s_]/g,""),f=/^(\d+)([km]?)$/i.exec(n);if(n!==""&&!f)return;const E=((M=f==null?void 0:f[2])==null?void 0:M.toLowerCase())==="k"?1e3:((w=f==null?void 0:f[2])==null?void 0:w.toLowerCase())==="m"?1e6:1,J=n===""||!f?null:Math.max(1,Math.round(parseInt(f[1],10)*E));ce(!0);try{const C=$.models.map(q=>q.id===h?{...q,contextWindow:J}:q);await i.updateCustomProvider($.id,{models:C}),await U(),window.dispatchEvent(new Event("llm-config-changed"))}catch{}finally{ce(!1)}},Y=d.startsWith("custom-")?null:x.find(n=>n.id===d);return e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"px-5 pt-5 space-y-6",children:[e.jsxs("section",{children:[e.jsx("h3",{className:"text-label font-bold text-ink-muted mb-2 px-1",children:t("settings.group.ai")}),e.jsxs("div",{className:"surface-card overflow-hidden",children:[e.jsxs("div",{className:v(!1),children:[e.jsx("div",{className:"text-label font-medium text-ink-strong mb-2",children:t("settings.row.provider")}),e.jsxs("div",{className:"flex flex-wrap gap-1.5","data-testid":"provider-grid",children:[x.map(n=>e.jsx("button",{onClick:()=>me(n.id),"data-testid":`provider-card-${n.id}`,"aria-pressed":d===n.id,className:`px-3 py-1.5 rounded-lg text-label font-medium whitespace-nowrap transition-colors ${d===n.id?R:F}`,children:n.label},n.id)),p.filter(n=>n.kind==="llm").map(n=>e.jsxs("button",{onClick:()=>me(n.id),"data-testid":`provider-card-${n.id}`,"aria-pressed":d===n.id,className:`px-3 py-1.5 rounded-lg text-label font-medium whitespace-nowrap transition-colors inline-flex items-center gap-1 ${d===n.id?R:F}`,children:[e.jsx($e,{className:"w-3.5 h-3.5","aria-hidden":"true"}),n.label]},n.id)),e.jsxs("button",{onClick:()=>V(n=>!n),"data-testid":"add-custom-provider",className:"px-3 py-1.5 rounded-lg text-label whitespace-nowrap inline-flex items-center gap-1 border border-dashed border-[var(--border)] text-ink-muted hover:border-ink-muted hover:text-ink-strong transition-colors",children:[e.jsx(nt,{className:"w-3.5 h-3.5","aria-hidden":"true"}),t("settings.add_custom")]})]})]}),B&&e.jsx("div",{className:"px-4 py-3.5 bg-surface-1 border-t border-[var(--border-faint)]",children:e.jsx(we,{kind:"llm",testPrefix:"custom",onSaved:n=>void fe(n),onCancel:()=>V(!1)})}),p.length>0&&d.startsWith("custom-")&&e.jsx("div",{className:v(!0),children:e.jsx("button",{onClick:n=>{const f=n.currentTarget.getBoundingClientRect(),E=p.find(J=>J.id===d);E&&H({id:E.id,label:E.label,rect:f})},className:"text-label text-warning hover:underline",children:t("settings.delete_custom")})}),Y&&e.jsxs(e.Fragment,{children:[Y.baseUrl&&e.jsxs("div",{className:v(!0),children:[e.jsx("div",{className:"text-label font-medium text-ink-strong mb-1.5",children:"Base URL"}),e.jsx("code",{className:"text-label text-ink-faint font-mono break-all",children:Y.baseUrl})]}),e.jsxs("div",{className:v(!0),children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"text-label font-medium text-ink-strong shrink-0 w-14",children:t("settings.model")}),e.jsxs("div",{className:"flex-1 flex items-center gap-2",children:[e.jsxs("select",{value:h,onChange:n=>m(n.target.value),"data-testid":"model-select",className:`${G} flex-1 px-2.5 py-1.5`,children:[Y.models.map(n=>e.jsx("option",{value:n.id,children:n.id},n.id)),d==="openrouter"&&I.map(n=>e.jsx("option",{value:n.id,children:n.id},n.id))]}),d==="openrouter"&&e.jsxs("button",{onClick:le,disabled:A,"data-testid":"discover-models-btn",className:"text-label text-accent hover:underline disabled:opacity-40 whitespace-nowrap inline-flex items-center gap-1",children:[e.jsx(ct,{className:`w-3.5 h-3.5 ${A?"animate-spin":""}`,"aria-hidden":"true"}),t(A?"settings.discovering":"settings.refresh")]})]})]}),L&&e.jsx("div",{className:"text-label text-warning mt-1.5 ml-[68px]",children:L})]}),e.jsx("div",{className:v(!0),children:e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"text-label font-medium text-ink-strong shrink-0 w-14",children:t("settings.apikey")}),e.jsxs("div",{className:"flex-1 flex items-center gap-2",children:[g&&e.jsxs("span",{className:"text-label text-brand shrink-0 inline-flex items-center gap-1",children:[e.jsx(ne,{className:"w-3.5 h-3.5","aria-hidden":"true"}),g]}),e.jsx("input",{type:"password",value:j,onChange:n=>T(n.target.value),placeholder:t(g?"settings.key.overwrite_ph":"settings.key.paste_ph"),"data-testid":"settings-key-input",className:`${G} flex-1 px-2.5 py-1.5`}),e.jsx("a",{href:Y.keyUrl,target:"_blank",rel:"noopener noreferrer",className:"text-label text-brand hover:underline whitespace-nowrap",children:t("settings.key.get")})]})]})}),e.jsx("div",{className:v(!0),children:e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("button",{onClick:O,disabled:y,"data-testid":"test-connection-btn",className:"btn-3d-neutral px-3 py-1.5 text-label disabled:opacity-40",children:t(y?"settings.testing":"settings.test")}),o&&e.jsxs("span",{className:`text-label inline-flex items-center gap-1 ${o.ok?"text-brand":"text-warning"}`,children:[o.ok?e.jsx(ne,{className:"w-4 h-4","aria-hidden":"true"}):e.jsx(he,{className:"w-4 h-4","aria-hidden":"true"}),o.detail]})]})})]}),$&&!Y&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:v(!0),children:[e.jsx("div",{className:"text-label font-medium text-ink-strong mb-1.5",children:"Base URL"}),e.jsx("code",{className:"text-label text-ink-faint font-mono break-all",children:$.baseUrl})]}),e.jsx("div",{className:v(!0),children:e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"text-label font-medium text-ink-strong shrink-0 w-14",children:t("settings.model")}),$.models.length>1?e.jsx("select",{value:h,onChange:n=>m(n.target.value),"data-testid":"model-select-custom",className:`${G} flex-1 px-2.5 py-1.5`,children:$.models.map(n=>e.jsx("option",{value:n.id,children:n.id},n.id))}):e.jsx("input",{type:"text",value:h,onChange:n=>m(n.target.value),placeholder:t("settings.custom.model_ph"),"data-testid":"model-input-custom",className:`${G} flex-1 px-2.5 py-1.5 font-mono`})]})}),e.jsxs("div",{className:v(!0),children:[e.jsx("div",{className:"text-label font-medium text-ink-strong mb-1.5",children:t("settings.custom.windowLabel")}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("input",{type:"text",inputMode:"numeric",value:Q,onChange:n=>re(n.target.value),placeholder:t("settings.custom.windowPh"),"data-testid":"context-window-input",className:`${G} flex-1 px-2.5 py-1.5 font-mono tabular-nums`}),e.jsx("button",{onClick:be,disabled:ge,"data-testid":"context-window-save",className:"btn-3d-neutral px-3 py-1.5 text-label shrink-0 disabled:opacity-40",children:t("settings.custom.save")})]}),e.jsx("div",{className:"text-caption text-ink-faint mt-1",children:t("settings.custom.windowHint")})]}),e.jsx("div",{className:v(!0),children:e.jsxs("label",{className:"inline-flex items-center gap-2 text-label cursor-pointer select-none","data-testid":"custom-vision-toggle",children:[e.jsx("input",{type:"checkbox",checked:$.vision,onChange:n=>void ie(n.target.checked),className:"w-4 h-4 rounded accent-brand"}),e.jsx("span",{className:"text-ink-strong",children:t("settings.custom.vision")}),e.jsx("span",{className:"text-ink-faint",children:t("settings.custom.visionHint")})]})}),e.jsx("div",{className:v(!0),children:e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("button",{onClick:O,disabled:y,"data-testid":"test-connection-btn",className:"btn-3d-neutral px-3 py-1.5 text-label disabled:opacity-40",children:t(y?"settings.testing":"settings.test")}),o&&e.jsxs("span",{className:`text-label inline-flex items-center gap-1 ${o.ok?"text-brand":"text-warning"}`,children:[o.ok?e.jsx(ne,{className:"w-4 h-4","aria-hidden":"true"}):e.jsx(he,{className:"w-4 h-4","aria-hidden":"true"}),o.detail]})]})})]})]})]}),e.jsxs("section",{children:[e.jsx("h3",{className:"text-label font-bold text-ink-muted mb-2 px-1",children:t("settings.group.vision")}),e.jsx("div",{className:"surface-card overflow-hidden",children:e.jsx(pt,{activeProvider:d,activeModel:h,presets:x,customProviders:p})})]}),e.jsxs("section",{children:[e.jsx("h3",{className:"text-label font-bold text-ink-muted mb-2 px-1",children:t("settings.group.speech")}),e.jsx("div",{className:"surface-card overflow-hidden",children:e.jsx(Nt,{})})]}),e.jsxs("section",{children:[e.jsx("h3",{className:"text-label font-bold text-ink-muted mb-2 px-1",children:t("settings.group.memory")}),e.jsx("div",{className:"surface-card overflow-hidden",children:e.jsx(ft,{})})]}),e.jsxs("section",{children:[e.jsx("h3",{className:"text-label font-bold text-ink-muted mb-2 px-1",children:t("settings.group.companion")}),e.jsx("div",{className:"surface-card overflow-hidden",children:e.jsx(bt,{})})]}),e.jsxs("section",{children:[e.jsx("h3",{className:"text-label font-bold text-ink-muted mb-2 px-1",children:t("settings.group.appearance")}),e.jsxs("div",{className:"surface-card overflow-hidden",children:[e.jsxs("div",{className:v(!1),children:[e.jsx("div",{className:"text-label font-medium text-ink-strong mb-2",children:t("settings.row.theme")}),e.jsx("div",{className:"flex gap-2",children:[{mode:"auto",label:t("settings.theme.auto")},{mode:"light",label:t("settings.theme.light")},{mode:"dark",label:t("settings.theme.dark")}].map(({mode:n,label:f})=>e.jsx("button",{onClick:()=>ee.setMode(n),"data-testid":`theme-${n}`,"aria-pressed":ee.mode===n,className:`px-4 py-2 rounded-xl text-body font-bold transition-all ${ee.mode===n?R:F}`,children:f},n))}),e.jsx("p",{className:"text-label text-ink-muted mt-2",children:ee.mode==="auto"?t("settings.theme.following",{mode:t(`settings.theme.${ee.resolved}`)}):null})]}),e.jsxs("div",{className:v(!0),children:[e.jsx("div",{className:"text-label font-medium text-ink-strong mb-2",children:t("settings.row.interface_lang")}),e.jsx("div",{className:"flex gap-2",children:["zh-CN","en"].map(n=>e.jsx("button",{onClick:()=>at(n),"data-testid":`lang-${n}`,"aria-pressed":ze()===n,className:`px-4 py-2 rounded-xl text-body font-bold transition-all ${ze()===n?R:F}`,children:n==="zh-CN"?"中文":"English"},n))})]}),e.jsxs("div",{className:v(!0),children:[e.jsx("div",{className:"text-label font-medium text-ink-strong mb-2",children:t("settings.row.import_lang")}),e.jsx(gt,{})]})]})]}),e.jsxs("section",{children:[e.jsx("h3",{className:"text-label font-bold text-ink-muted mb-2 px-1",children:t("settings.group.about")}),e.jsx("div",{className:"surface-card overflow-hidden",children:e.jsxs("div",{className:v(!1),children:[e.jsxs("div",{className:"flex items-baseline justify-between gap-3",children:[e.jsx("div",{className:"text-label font-medium text-ink-strong",children:t("settings.row.version")}),e.jsxs("a",{href:"https://github.com/Kaiji-Z/LookatStudy/releases",target:"_blank",rel:"noopener noreferrer",className:"text-label font-mono text-brand hover:underline","data-testid":"settings-version",children:["v",ht.version]})]}),e.jsx("p",{className:"text-label text-ink-muted mt-2",children:t("settings.version.hint")})]})})]})]}),e.jsxs("div",{className:"sticky bottom-0 px-5 py-3 bg-surface-0 border-t border-[var(--border)] flex items-center justify-between gap-3",children:[e.jsx("span",{className:"text-label text-ink-muted",children:t("settings.footer.hint")}),e.jsxs("button",{onClick:pe,"data-testid":"settings-save",className:"btn-3d-brand px-5 py-2 text-body inline-flex items-center gap-1.5",children:[k&&e.jsx(it,{className:"w-4 h-4","aria-hidden":"true"}),t(k?"settings.saved_text":"settings.footer.save")]})]}),l&&e.jsx(lt,{anchorRect:l.rect,message:t("settings.delete_custom_confirm",{name:l.label}),danger:!0,confirmLabel:t("action.delete"),testid:"custom-provider-delete-confirm",onConfirm:()=>{te(l.id),H(null)},onCancel:()=>H(null)})]})}function gt(){const[t,x]=a.useState("en"),[b,p]=a.useState(!1);a.useEffect(()=>{i.getSetting("pref_lang").then(r=>{r&&x(r),p(!0)})},[]);const c=async r=>{x(r),await i.setSetting("pref_lang",r)},d=[{code:"en",label:"English"},{code:"zh-CN",label:"简体中文"},{code:"zh-TW",label:"繁體中文"}];return b?e.jsx("div",{className:"flex gap-2","data-testid":"pref-lang-options",children:d.map(r=>e.jsx("button",{onClick:()=>c(r.code),"data-testid":`pref-lang-${r.code}`,"aria-pressed":t===r.code,className:`px-4 py-2 rounded-xl text-body font-bold transition-all ${t===r.code?R:F}`,children:r.label},r.code))}):null}function pt({activeProvider:t,activeModel:x,presets:b,customProviders:p}){const c=de(),[d,r]=a.useState(!1),[h,m]=a.useState(!1),[j,T]=a.useState(""),[g,S]=a.useState(!1),[y,P]=a.useState(!1),[o,_]=a.useState(null),[k,W]=a.useState(!1);a.useEffect(()=>{Promise.all([i.getSetting("flag_multimodal_import"),i.getSetting("vision_provider_override"),i.getSetting("vision_model_override"),i.getSetting("flag_math_vision")]).then(([l,H,Q])=>{r(l==="true"),T(H??""),W(Q==="true"),m(!0)})},[]);const B=async()=>{const l=!d;r(l),await i.setSetting("flag_multimodal_import",String(l))},V=async()=>{const l=!k;W(l),await i.setSetting("flag_math_vision",String(l))},I=async l=>{await i.setSetting("vision_provider_override",l.id),await i.setSetting("vision_model_override",l.defaultModel),T(l.id),S(!1)},D=async()=>{await i.setSetting("vision_provider_override",""),await i.setSetting("vision_model_override",""),T(""),S(!1)},A=async()=>{if(!y){P(!0),_(null);try{const l=await i.testLlmConnection({vision:!0});_({ok:l.ok,detail:l.detail})}catch(l){_({ok:!1,detail:l instanceof Error?l.message:String(l)})}finally{P(!1)}}},z=p.filter(l=>l.kind==="vision"),L=j.startsWith("custom-")?p.find(l=>l.id===j):null,N=j&&!j.startsWith("custom-")?b.find(l=>l.id===j):null;return h?e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"px-4 py-3.5 flex items-center gap-3",children:[e.jsx(ae,{checked:d,onChange:B,label:c("settings.multimodal.toggle"),testid:"multimodal-toggle"}),e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsx("div",{className:"text-body font-medium text-ink-strong",children:c("settings.multimodal.toggle")}),e.jsx("div",{className:"text-label text-ink-muted",children:c("settings.multimodal.toggle.desc")})]})]}),e.jsxs("div",{className:"px-4 py-3.5 border-t border-[var(--border-faint)] space-y-3",children:[e.jsxs("div",{className:"text-label text-ink-muted bg-ink/5 rounded-lg p-3",children:[e.jsx("div",{className:"font-medium mb-1",children:c("settings.multimodal.current_model",{model:x||c("settings.multimodal.not_selected")})}),e.jsx("div",{children:t.startsWith("custom-")?c("settings.multimodal.hint_custom"):c("settings.multimodal.hint_preset")})]}),e.jsxs("div",{className:"bg-ink/5 rounded-lg p-3",children:[e.jsx("div",{className:"text-label font-medium text-ink-muted mb-2",children:c("settings.multimodal.override_title")}),e.jsx("div",{className:"text-caption text-ink-muted mb-2",children:c("settings.multimodal.override_bridge_hint")}),e.jsxs("div",{className:"space-y-3 mt-1",children:[L&&e.jsxs("div",{className:"space-y-2",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-2 text-label",children:[e.jsx($e,{className:"w-3.5 h-3.5 text-ink-faint shrink-0","aria-hidden":"true"}),e.jsx("span",{className:"font-medium text-ink-strong",children:L.label}),e.jsx("code",{className:"text-ink-faint font-mono break-all",children:L.defaultModel}),e.jsx("span",{className:"text-ink-faint break-all min-w-0",children:L.baseUrl})]}),e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx("button",{onClick:()=>void A(),disabled:y,"data-testid":"vision-override-test",className:"btn-3d-neutral px-4 py-1.5 text-label disabled:opacity-50",children:c(y?"settings.testing":"settings.multimodal.test_override")}),e.jsx("button",{onClick:()=>S(l=>!l),className:"text-label text-accent hover:underline",children:c("settings.multimodal.replace_custom")}),e.jsx("button",{onClick:()=>void D(),className:"text-label text-ink-muted hover:text-ink-strong",children:c("settings.multimodal.stop_override")}),o&&e.jsxs("span",{className:`text-label inline-flex items-center gap-1 ${o.ok?"text-brand":"text-warning"}`,children:[o.ok?e.jsx(ne,{className:"w-4 h-4","aria-hidden":"true"}):e.jsx(he,{className:"w-4 h-4","aria-hidden":"true"}),o.detail]})]})]}),N&&e.jsxs("div",{className:"flex flex-wrap items-center gap-2 text-label",children:[e.jsx("span",{className:"text-ink-muted",children:c("settings.multimodal.legacy_preset",{label:N.label})}),e.jsx("button",{onClick:()=>void D(),className:"text-label text-ink-muted hover:text-ink-strong underline",children:c("settings.multimodal.stop_override")})]}),!L&&!N&&e.jsxs(e.Fragment,{children:[z.map(l=>e.jsxs("button",{onClick:()=>void I(l),className:"w-full text-left px-3 py-2 rounded-lg bg-surface-1 hover:bg-surface-3 transition-colors","data-testid":`vision-pick-${l.id}`,children:[e.jsx("span",{className:"text-label font-medium text-ink-strong",children:l.label}),e.jsx("span",{className:"text-label text-ink-faint font-mono break-all ml-2",children:l.defaultModel})]},l.id)),(g||z.length===0)&&e.jsx(we,{kind:"vision",testPrefix:"vision-custom",titleKey:"settings.custom.form_title_vision",modelPhKey:"settings.custom.model_ph_vision",onSaved:l=>void I(l),onCancel:()=>S(!1)}),z.length>0&&e.jsx("button",{onClick:()=>S(l=>!l),className:"text-label text-accent hover:underline",children:c(g?"action.cancel":"settings.custom.new")})]})]})]}),e.jsxs("div",{className:"bg-ink/5 rounded-lg p-3 flex items-center gap-3",children:[e.jsx(ae,{checked:k,onChange:V,label:c("settings.mathvision.toggle"),testid:"math-vision-toggle"}),e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsx("div",{className:"text-label font-medium text-ink-strong",children:c("settings.mathvision.toggle")}),e.jsx("div",{className:"text-caption text-ink-muted",children:c("settings.mathvision.desc")})]})]})]})]}):null}function ft(){const t=de(),[x,b]=a.useState(!1),[p,c]=a.useState(!1);a.useEffect(()=>{i.getSetting("flag_memory_system").then(r=>{b(r==="true"),c(!0)})},[]);const d=async()=>{const r=!x;b(r),await i.setSetting("flag_memory_system",String(r))};return p?e.jsxs("div",{className:"px-4 py-3.5 flex items-center gap-3",children:[e.jsx(ae,{checked:x,onChange:d,label:t("settings.memory.toggle"),testid:"memory-toggle"}),e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsx("div",{className:"text-body font-medium text-ink-strong",children:t("settings.memory.toggle")}),e.jsx("div",{className:"text-label text-ink-muted",children:t("settings.memory.toggle.desc")})]})]}):null}function bt(){const t=de(),[x,b]=a.useState(!0),[p,c]=a.useState(!1),d=a.useSyncExternalStore(Ze,Qe),[r,h]=a.useState(!0),[m,j]=a.useState(!1),T=typeof window<"u"&&!!window.__lookatstudyWeb;a.useEffect(()=>{i.getSetting("companion_enabled").then(o=>{b(o!=="false"&&o!=="0"),c(!0)}),i.getSetting("companion_sfx").then(o=>{h(o!=="false"&&o!=="0")}),i.getSetting("companion_pet_mode").then(o=>{j(o==="1")})},[]);const g=async()=>{const o=!x;b(o),await i.setSetting("companion_enabled",String(o)),window.dispatchEvent(new Event("companion-config-changed"))},S=async()=>{const o=!r;h(o),await i.setSetting("companion_sfx",String(o)),window.dispatchEvent(new Event("companion-config-changed"))},y=async()=>{const o=!m;j(o),await i.setSetting("companion_pet_mode",o?"1":"0"),window.dispatchEvent(new Event("companion-config-changed"))},P=async o=>{o!==d.form&&(await i.setSetting("companion_form",o),window.dispatchEvent(new Event("companion-config-changed")))};return p?e.jsxs("div",{className:"px-4 py-3.5 flex flex-col gap-4",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx(ae,{checked:x,onChange:g,label:t("settings.companion.toggle"),testid:"companion-toggle"}),e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsx("div",{className:"text-body font-medium text-ink-strong",children:t("settings.companion.toggle")}),e.jsx("div",{className:"text-label text-ink-muted",children:t("settings.companion.toggle.desc")})]})]}),x&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx(ae,{checked:r,onChange:S,label:t("settings.companion.sfx"),testid:"companion-sfx-toggle"}),e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsx("div",{className:"text-body font-medium text-ink-strong",children:t("settings.companion.sfx")}),e.jsx("div",{className:"text-label text-ink-muted",children:t("settings.companion.sfx.desc")})]})]}),!T&&e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx(ae,{checked:m,onChange:y,label:t("settings.companion.pet"),testid:"companion-pet-toggle"}),e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsx("div",{className:"text-body font-medium text-ink-strong",children:t("settings.companion.pet")}),e.jsx("div",{className:"text-label text-ink-muted",children:t("settings.companion.pet.desc")})]})]}),e.jsxs("div",{children:[e.jsx("div",{className:"text-label text-ink-muted mb-2",children:t("settings.companion.form")}),e.jsx("div",{className:"grid grid-cols-5 gap-2",role:"radiogroup","aria-label":t("settings.companion.form"),children:et.map(o=>{const _=d.form===o;return e.jsxs("button",{type:"button",role:"radio","aria-checked":_,"data-testid":`companion-form-${o}`,onClick:()=>{P(o)},className:`flex flex-col items-center gap-0.5 rounded-xl p-1.5 border motion-safe:transition-colors
7
+ ${_?"border-[var(--accent)] bg-surface-2 shadow-card":"border-[var(--border-faint)] hover:bg-surface-2"}`,title:t(`companion.form.${o}.desc`),children:[e.jsx(tt,{form:o,expression:"happy",pose:"float",size:64}),e.jsx("span",{className:`text-label ${_?"text-ink-strong font-medium":"text-ink-muted"}`,children:t(`companion.form.${o}.name`)})]},o)})})]})]})]}):null}function ae({checked:t,onChange:x,label:b,testid:p}){return e.jsx("button",{type:"button",role:"switch","aria-checked":t,"aria-label":b,onClick:x,"data-testid":p,className:`relative w-12 h-6 rounded-full transition-colors shrink-0 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand/60 focus-visible:ring-offset-2 focus-visible:ring-offset-[var(--surface-2)] ${t?"bg-brand":"bg-ink/20 hover:bg-ink/25"}`,children:e.jsx("span",{className:`absolute left-0.5 top-1/2 -translate-y-1/2 w-5 h-5 rounded-full bg-white shadow transition-transform ${t?"translate-x-6":""}`})})}const vt=[{id:"zh-CN-XiaoxiaoNeural",label:"zh-CN · 晓晓(女)"},{id:"zh-CN-XiaoyiNeural",label:"zh-CN · 晓伊(女)"},{id:"zh-CN-YunxiNeural",label:"zh-CN · 云希(男)"},{id:"zh-CN-YunyangNeural",label:"zh-CN · 云扬(男·新闻)"},{id:"zh-CN-liaoning-XiaobeiNeural",label:"zh-CN · 晓北(女·东北)"},{id:"zh-CN-shaanxi-XiaoniNeural",label:"zh-CN · 晓妮(女·陕西)"},{id:"en-US-AriaNeural",label:"en-US · Aria(女)"},{id:"en-US-GuyNeural",label:"en-US · Guy(男)"},{id:"en-US-JennyNeural",label:"en-US · Jenny(女)"}],jt=[{sid:"45",label:"zf_xiaobei(女)"},{sid:"46",label:"zf_xiaoni(女)"},{sid:"47",label:"zf_xiaoxiao(女)"},{sid:"48",label:"zf_xiaoyi(女·默认)"},{sid:"49",label:"zm_yunjian(男)"},{sid:"50",label:"zm_yunxi(男)"},{sid:"51",label:"zm_yunxia(男)"},{sid:"52",label:"zm_yunyang(男)"}];function Nt(){const t=de(),[x,b]=a.useState([]),[p,c]=a.useState(null),[d,r]=a.useState(null),[h,m]=a.useState(null),[j,T]=a.useState(null),[g,S]=a.useState("edge"),[y,P]=a.useState("zh-CN-XiaoxiaoNeural"),[o,_]=a.useState("48"),[k,W]=a.useState("1.0"),[B,V]=a.useState(""),[I,D]=a.useState(""),[A,z]=a.useState([]),L=typeof window<"u"&&"speechSynthesis"in window,[N,l]=a.useState("local"),[H,Q]=a.useState("asr-whisper-turbo"),[re,ge]=a.useState(!0),[ce,ee]=a.useState([]),[ie,le]=a.useState(!1),[U,me]=a.useState(!1),[pe,O]=a.useState(!1),[fe,te]=a.useState(!1),[$,be]=a.useState(!1),[Y,n]=a.useState(null),[f,E]=a.useState(!1),[J,M]=a.useState(null),[w,C]=a.useState(null),q=a.useCallback(()=>{i.listCustomProviders().then(s=>ee(s.filter(u=>u.kind==="tts"||u.kind==="asr"))).catch(()=>{})},[]);a.useEffect(()=>{Promise.all([i.getSetting("tts_engine"),i.getSetting("tts_voice_edge"),i.getSetting("tts_sid_local"),i.getSetting("tts_speed"),i.getSetting("tts_custom_voice"),i.getSetting("tts_system_voice"),i.getSetting("asr_engine"),i.getSetting("asr_local_model"),i.getSetting("asr_auto_stop")]).then(([s,u,K,X,ye,Pe,Ae,Se,Je])=>{s&&S(s),u&&P(u),K&&_(K),X&&W(X),ye&&V(ye),Pe&&D(Pe),Ae&&l(Ae),(Se==="asr-whisper-turbo"||Se==="asr-whisper-small")&&Q(Se),ge(Je!=="0")}),q()},[q]),a.useEffect(()=>{if(typeof window>"u"||!("speechSynthesis"in window))return;const s=()=>z(dt(window.speechSynthesis.getVoices()));return s(),window.speechSynthesis.addEventListener("voiceschanged",s),()=>window.speechSynthesis.removeEventListener("voiceschanged",s)},[]);const ue=a.useCallback(()=>{window.api.getSpeechModelStatus().then(s=>b(s)).catch(()=>{})},[]);a.useEffect(()=>(ue(),window.api.on("speech:modelProgress",u=>{m({id:u.id,pct:Math.floor(u.progress*100),label:u.currentFile?u.currentFile.split("/").pop()??"":""})})),[ue]);const Fe=s=>{r(null),c(s),m({id:s,pct:0,label:""}),window.api.ensureSpeechModel(s).then(()=>{c(null),m(null),ue()}).catch(u=>{c(null),m(null),r(u instanceof Error?u.message:String(u)),ue()})},Re=s=>{c(s),T(null),window.api.deleteSpeechModel(s).then(ue).catch(u=>r(u instanceof Error?u.message:String(u))).finally(()=>c(null))},Ve=s=>t(s==="tts-kokoro"?"settings.speech.model.tts":s==="asr-whisper-turbo"?"settings.speech.model.asr_turbo":"settings.speech.model.asr_small"),Ie=s=>t(s==="asr-whisper-turbo"?"settings.speech.model.turbo_short":"settings.speech.model.small_short"),De=s=>s.startsWith("asr-whisper")?t("settings.speech.license_mit"):t("settings.speech.license"),Ee=s=>t(s==="ready"?"settings.speech.state.ready":s==="error"?"settings.speech.state.error":"settings.speech.state.absent"),Te=s=>{var u;return((u=x.find(K=>K.id===s))==null?void 0:u.state)??"absent"},oe=s=>{S(s),n(null),i.setSetting("tts_engine",s),ke()},Oe=s=>{D(s),i.setSetting("tts_system_voice",s),ke()},ve=s=>{l(s),M(null),i.setSetting("asr_engine",s)},je=ce.filter(s=>s.kind==="tts"),Ne=ce.filter(s=>s.kind==="asr"),Z=g.startsWith("custom-")?je.find(s=>s.id===g)??null:null,se=N.startsWith("custom-")?Ne.find(s=>s.id===N)??null:null,Ge=g==="azure",Be=N==="groq",qe=N==="azure",Xe=async()=>{if(!(!Z||$)){be(!0),n(null);try{n(await i.testCustomTts({providerId:Z.id}))}catch(s){n({ok:!1,detail:s instanceof Error?s.message:String(s)})}finally{be(!1)}}},He=async()=>{if(!(!se||f)){E(!0),M(null);try{M(await i.testCustomAsr({providerId:se.id}))}catch(s){M({ok:!1,detail:s instanceof Error?s.message:String(s)})}finally{E(!1)}}},Ye=async(s,u)=>{C(null);try{await i.deleteCustomProvider(s),u==="tts"&&g===s&&oe("edge"),u==="asr"&&N===s&&ve("local"),q()}catch{}},Me=s=>{const u=x.find(X=>X.id===s),K=(u==null?void 0:u.state)??"absent";return e.jsxs("div",{className:"flex items-center gap-3 flex-wrap",children:[e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsx("div",{className:"text-label font-medium text-ink-strong truncate",children:Ve(s)}),e.jsxs("div",{className:"text-caption text-ink-muted",children:[Ee(K)," · ",De(s)]}),p===s&&(h==null?void 0:h.id)===s&&e.jsx("div",{className:"mt-1.5 h-1.5 rounded-full bg-ink/[0.08] overflow-hidden","data-testid":`speech-dl-bar-${s}`,children:e.jsx("div",{className:"h-full bg-brand transition-all",style:{width:`${h.pct}%`}})}),p===s&&(h==null?void 0:h.id)===s&&e.jsxs("div",{className:"text-caption text-ink-faint mt-0.5","data-testid":`speech-dl-pct-${s}`,children:[h.pct,"%",h.label?` · ${h.label}`:""]})]}),K==="ready"?j===s?e.jsxs("div",{className:"flex items-center gap-1.5",children:[e.jsx("span",{className:"text-caption text-warning",children:t("settings.speech.confirm_del")}),e.jsx("button",{onClick:()=>Re(s),className:"text-label text-warning hover:underline","data-testid":`speech-del-confirm-${s}`,children:t("settings.speech.delete")}),e.jsx("button",{onClick:()=>T(null),className:"text-label text-ink-muted hover:text-ink-strong",children:t("action.cancel")})]}):e.jsx("button",{onClick:()=>T(s),disabled:p===s,className:"text-label text-ink-muted hover:text-warning disabled:opacity-40","data-testid":`speech-del-${s}`,children:t("settings.speech.delete")}):e.jsx("button",{onClick:()=>Fe(s),disabled:p!=null||K==="downloading",className:"btn-3d-brand px-3 py-1 text-label disabled:opacity-40","data-testid":`speech-dl-${s}`,children:t(p===s||K==="downloading"?"settings.speech.downloading":"settings.speech.download")})]},s)},Le=(s,u,K,X,ye)=>e.jsxs("div",{className:"space-y-2",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-2 text-label",children:[e.jsx($e,{className:"w-3.5 h-3.5 text-ink-faint shrink-0","aria-hidden":"true"}),e.jsx("span",{className:"font-medium text-ink-strong",children:s.label}),e.jsx("code",{className:"text-ink-faint font-mono break-all",children:s.defaultModel}),e.jsx("span",{className:"text-ink-faint break-all min-w-0",children:s.baseUrl}),s.hasApiKey&&e.jsxs("span",{className:"text-brand shrink-0 inline-flex items-center gap-0.5",children:[e.jsx(ne,{className:"w-3.5 h-3.5","aria-hidden":"true"}),t("settings.speech.key_saved")]})]}),e.jsxs("div",{className:"flex flex-wrap items-center gap-3",children:[e.jsx("button",{onClick:()=>void ye(),disabled:K,className:"btn-3d-neutral px-3 py-1 text-label disabled:opacity-40","data-testid":`${u}-custom-test`,children:t(K?"settings.testing":"settings.test")}),w===s.id?e.jsxs(e.Fragment,{children:[e.jsx("span",{className:"text-caption text-warning",children:t("settings.speech.confirm_del_custom")}),e.jsx("button",{onClick:()=>void Ye(s.id,u),className:"text-label text-warning hover:underline","data-testid":`${u}-custom-del-confirm`,children:t("settings.speech.delete")}),e.jsx("button",{onClick:()=>C(null),className:"text-label text-ink-muted hover:text-ink-strong",children:t("action.cancel")})]}):e.jsx("button",{onClick:()=>C(s.id),className:"text-label text-ink-muted hover:text-warning","data-testid":`${u}-custom-del`,children:t("settings.speech.delete")}),X&&e.jsxs("span",{className:`text-label inline-flex items-center gap-1 ${X.ok?"text-brand":"text-warning"}`,children:[X.ok?e.jsx(ne,{className:"w-4 h-4","aria-hidden":"true"}):e.jsx(he,{className:"w-4 h-4","aria-hidden":"true"}),X.detail]})]})]});return e.jsxs("div",{"data-testid":"settings-speech",children:[e.jsxs("div",{className:v(!1),children:[e.jsx("div",{className:"text-label font-medium text-ink-strong mb-2",children:t("settings.speech.tts_title")}),e.jsxs("div",{className:"flex gap-2 flex-wrap",children:[e.jsx("button",{onClick:()=>{oe("edge"),le(!1),O(!1)},"data-testid":"tts-engine-edge","aria-pressed":g==="edge",className:`px-4 py-2 rounded-xl text-body font-bold transition-all ${g==="edge"?R:F}`,children:t("settings.speech.engine.edge")}),e.jsxs("button",{onClick:()=>{oe("local"),le(!1),O(!1)},"data-testid":"tts-engine-local","aria-pressed":g==="local",className:`px-4 py-2 rounded-xl text-body font-bold transition-all ${g==="local"?R:F}`,children:[t("settings.speech.engine.local"),Te("tts-kokoro")!=="ready"?` · ${t("settings.speech.state.absent")}`:""]}),e.jsx("button",{onClick:()=>{oe("system"),le(!1),O(!1)},disabled:!L,"data-testid":"tts-engine-system","aria-pressed":g==="system",title:L?void 0:t("settings.speech.engine.system_unavailable"),className:`px-4 py-2 rounded-xl text-body font-bold transition-all ${g==="system"?R:F} ${L?"":"opacity-40 cursor-not-allowed"}`,children:t("settings.speech.engine.system")}),e.jsx("button",{onClick:()=>{le(s=>!s),ie||O(!1)},"data-testid":"tts-engine-custom","aria-pressed":g.startsWith("custom-")||ie,className:`px-4 py-2 rounded-xl text-body font-bold transition-all ${g.startsWith("custom-")||ie?R:F}`,children:t("settings.speech.engine.custom")}),Ge&&e.jsxs("button",{disabled:!0,"data-testid":"tts-engine-azure",className:"px-4 py-2 rounded-xl text-body font-bold opacity-50 cursor-not-allowed",children:["Azure · ",t("settings.speech.legacy")]})]}),g==="edge"&&e.jsx("p",{className:"text-label text-ink-muted mt-2",children:t("settings.speech.engine.edge_note")})]}),g==="edge"&&e.jsxs("div",{className:v(!1),children:[e.jsx("div",{className:"text-label font-medium text-ink-strong mb-1.5",children:t("settings.speech.voice")}),e.jsx("select",{value:y,onChange:s=>{P(s.target.value),i.setSetting("tts_voice_edge",s.target.value)},"data-testid":"tts-voice-select",className:`${G} w-full min-w-0 px-2.5 py-1.5`,children:vt.map(s=>e.jsx("option",{value:s.id,children:s.label},s.id))})]}),g==="local"&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:v(!1),children:[e.jsx("div",{className:"text-label font-medium text-ink-strong mb-1.5",children:t("settings.speech.voice")}),e.jsx("select",{value:o,onChange:s=>{_(s.target.value),i.setSetting("tts_sid_local",s.target.value)},"data-testid":"tts-sid-select",className:`${G} w-full min-w-0 px-2.5 py-1.5`,children:jt.map(s=>e.jsx("option",{value:s.sid,children:s.label},s.sid))})]}),e.jsx("div",{className:v(!1),children:Me("tts-kokoro")})]}),g==="system"&&e.jsx(e.Fragment,{children:e.jsxs("div",{className:v(!1),children:[e.jsx("div",{className:"text-label font-medium text-ink-strong mb-1.5",children:t("settings.speech.voice")}),e.jsxs("select",{value:I,onChange:s=>Oe(s.target.value),"data-testid":"tts-system-voice-select",className:`${G} w-full min-w-0 px-2.5 py-1.5`,children:[e.jsx("option",{value:"",children:t("settings.speech.voice_auto")}),A.map(s=>e.jsx("option",{value:s.name,children:ot(s)},s.voiceURI))]}),e.jsx("p",{className:"text-label text-ink-muted mt-2",children:t("settings.speech.engine.system_note")})]})}),ie&&e.jsx("div",{className:v(!1),children:e.jsxs("div",{className:"space-y-3",children:[Z&&Le(Z,"tts",$,Y,Xe),Z&&e.jsxs("div",{children:[e.jsx("div",{className:"text-label font-medium text-ink-strong mb-1.5",children:t("settings.speech.voice")}),e.jsx("input",{type:"text",value:B,onChange:s=>V(s.target.value),onBlur:()=>void i.setSetting("tts_custom_voice",B.trim()),placeholder:t("settings.speech.custom_voice_ph"),"data-testid":"tts-custom-voice",className:`${G} w-full min-w-0 px-2.5 py-1.5 font-mono`})]}),!Z&&je.map(s=>e.jsxs("button",{onClick:()=>oe(s.id),className:"w-full text-left px-3 py-2 rounded-lg bg-surface-1 hover:bg-surface-3 transition-colors","data-testid":`tts-pick-${s.id}`,children:[e.jsx("span",{className:"text-label font-medium text-ink-strong",children:s.label}),e.jsx("span",{className:"text-label text-ink-faint font-mono break-all ml-2",children:s.defaultModel})]},s.id)),(pe||!Z&&je.length===0)&&e.jsx(we,{kind:"tts",showProtocol:!1,testPrefix:"tts-custom",titleKey:"settings.custom.form_title_tts",modelPhKey:"settings.custom.model_ph_tts",testOverride:s=>i.testCustomTts({baseUrl:s.baseUrl,apiKey:s.apiKey||void 0,model:s.model}),onSaved:s=>{oe(s.id),O(!1),q()},onCancel:()=>O(!1)}),(Z||je.length>0)&&e.jsx("button",{onClick:()=>O(s=>!s),className:"text-label text-accent hover:underline",children:t(pe?"action.cancel":"settings.custom.new")})]})}),e.jsx("div",{className:v(!0),children:e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"text-label font-medium text-ink-strong shrink-0 w-14",children:t("settings.speech.speed")}),e.jsx("input",{type:"range",min:"0.5",max:"2",step:"0.05",value:k,onChange:s=>W(s.target.value),onPointerUp:()=>{i.setSetting("tts_speed",k),ke()},onKeyUp:()=>{i.setSetting("tts_speed",k),ke()},"data-testid":"tts-speed-range",className:"flex-1 min-w-0 accent-[var(--brand)]"}),e.jsxs("span",{className:"text-label text-ink-muted tabular-nums w-10 text-right","data-testid":"tts-speed-value",children:[Number(k).toFixed(2),"x"]})]})}),e.jsxs("div",{className:v(!0),children:[e.jsx("div",{className:"text-label font-medium text-ink-strong mb-2",children:t("settings.speech.asr_title")}),e.jsxs("div",{className:"flex gap-2 flex-wrap",children:[e.jsx("button",{onClick:()=>{ve("local"),me(!1),te(!1)},"data-testid":"asr-engine-local","aria-pressed":N==="local",className:`px-4 py-2 rounded-xl text-body font-bold transition-all ${N==="local"?R:F}`,children:t("settings.speech.asr_engine.local")}),e.jsx("button",{onClick:()=>{me(s=>!s),U||te(!1)},"data-testid":"asr-engine-custom","aria-pressed":N.startsWith("custom-")||U,className:`px-4 py-2 rounded-xl text-body font-bold transition-all ${N.startsWith("custom-")||U?R:F}`,children:t("settings.speech.engine.custom")}),Be&&e.jsxs("button",{disabled:!0,"data-testid":"asr-engine-groq",className:"px-4 py-2 rounded-xl text-body font-bold opacity-50 cursor-not-allowed",children:["Groq · ",t("settings.speech.legacy")]}),qe&&e.jsxs("button",{disabled:!0,"data-testid":"asr-engine-azure",className:"px-4 py-2 rounded-xl text-body font-bold opacity-50 cursor-not-allowed",children:["Azure · ",t("settings.speech.legacy")]})]}),N==="local"?e.jsx("p",{className:"text-label text-ink-muted mt-2",children:t("settings.speech.asr_engine.local_note")}):N.startsWith("custom-")&&e.jsx("p",{className:"text-label text-ink-muted mt-2",children:t("settings.speech.asr_engine.custom_note")})]}),N==="local"&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:v(!1),children:[e.jsx("div",{className:"text-label font-medium text-ink-strong mb-1.5",children:t("settings.model")}),e.jsx("select",{value:H,onChange:s=>{Q(s.target.value),i.setSetting("asr_local_model",s.target.value)},"data-testid":"asr-model-select",className:`${G} w-full min-w-0 px-2.5 py-1.5`,children:["asr-whisper-turbo","asr-whisper-small"].map(s=>e.jsxs("option",{value:s,children:[Ie(s)," · ",Ee(Te(s))]},s))})]}),e.jsx("div",{className:v(!1),children:Me(H)})]}),U&&e.jsx("div",{className:v(!1),children:e.jsxs("div",{className:"space-y-3",children:[se&&Le(se,"asr",f,J,He),!se&&Ne.map(s=>e.jsxs("button",{onClick:()=>ve(s.id),className:"w-full text-left px-3 py-2 rounded-lg bg-surface-1 hover:bg-surface-3 transition-colors","data-testid":`asr-pick-${s.id}`,children:[e.jsx("span",{className:"text-label font-medium text-ink-strong",children:s.label}),e.jsx("span",{className:"text-label text-ink-faint font-mono break-all ml-2",children:s.defaultModel})]},s.id)),(fe||!se&&Ne.length===0)&&e.jsx(we,{kind:"asr",showProtocol:!1,testPrefix:"asr-custom",titleKey:"settings.custom.form_title_asr",modelPhKey:"settings.custom.model_ph_asr",testOverride:s=>i.testCustomAsr({baseUrl:s.baseUrl,apiKey:s.apiKey||void 0,model:s.model}),onSaved:s=>{ve(s.id),te(!1),q()},onCancel:()=>te(!1)}),(se||Ne.length>0)&&e.jsx("button",{onClick:()=>te(s=>!s),className:"text-label text-accent hover:underline",children:t(fe?"action.cancel":"settings.custom.new")})]})}),e.jsxs("div",{className:v(!0),children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx(ae,{checked:re,onChange:()=>{const s=!re;ge(s),i.setSetting("asr_auto_stop",s?"1":"0")},label:t("settings.speech.asr_auto_stop"),testid:"asr-auto-stop-toggle"}),e.jsx("div",{className:"text-body font-medium text-ink-strong",children:t("settings.speech.asr_auto_stop")})]}),e.jsx("p",{className:"text-label text-ink-muted mt-2",children:t("settings.speech.asr_ux_note")})]}),d&&e.jsx("div",{className:"px-4 py-3 text-label text-warning break-all",role:"alert",children:d==="engine-unavailable"?t("chat.speech.engine_unavailable"):d})]})}export{wt as SettingsView};
@@ -1,4 +1,4 @@
1
- import{r as n,j as e}from"./index-xynt7zMk.js";import{c as f,u as h,e as b,f as g}from"./main-CGE6fm01.js";import{R as j}from"./rotate-ccw-natFwqj6.js";/**
1
+ import{r as n,j as e}from"./index-C-4sKCSr.js";import{c as f,u as h,e as b,f as g}from"./main-D3HpSUyK.js";import{R as j}from"./rotate-ccw-C3k3pTDh.js";/**
2
2
  * @license lucide-react v0.468.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1 +1 @@
1
- import{g as p,r as u,d as a}from"./chunk-6Q2QTUOP-CI07iNTB.js";import{p as f}from"./chunk-JWPE2WC7-DJM1SevB.js";import{_ as n,l as o}from"./mermaid.core-BD32Za4p.js";import"./transform-CzGDKG_M.js";import{M as c,b as d}from"./cynefin-VYW2F7L2-Br1TXK2f.js";import"./main-CGE6fm01.js";import"./index-xynt7zMk.js";import"./step-SI6FXFD6.js";var v=d().RailroadAbnf.parser.LangiumParser,i=n(e=>{const r=e.alternatives.map(g);return r.length===1?r[0]:{type:"choice",alternatives:r}},"transformAlternation"),g=n(e=>{const r=e.elements.map(y);return r.length===1?r[0]:{type:"sequence",elements:r}},"transformConcatenation"),b=n(e=>{if(e.includes("*")){const[t,s]=e.split("*"),m=t?parseInt(t,10):0,l=s?parseInt(s,10):1/0;return{min:m,max:l}}const r=parseInt(e,10);return{min:r,max:r}},"parseRepeat"),y=n(e=>{const r=A(e.primary);if(!e.repeat)return r;const{min:t,max:s}=b(e.repeat);return t===0&&s===1?{type:"optional",element:r}:{type:"repetition",element:r,min:t,max:s}},"transformElement"),A=n(e=>{switch(e.$type){case"AbnfStringLiteral":return{type:"terminal",value:e.value};case"AbnfNumVal":return{type:"terminal",value:e.value};case"AbnfRuleName":return{type:"nonterminal",name:e.name};case"AbnfGroup":return i(e.element);case"AbnfOptionalGroup":return{type:"optional",element:i(e.element)};default:throw new Error(`Unsupported ABNF primary node: ${e.$type}`)}},"transformPrimary"),P=n(e=>({name:e.name,definition:i(e.definition)}),"transformRule"),h=n(e=>{f(e,a),e.title&&a.setTitle(e.title),e.rules.map(r=>a.addRule(P(r)))},"populateDb"),R={parse:n(e=>{a.clear(),o.debug("[ABNF Parser] Starting Langium parse");const r=v.parse(e);if(r.lexerErrors.length>0||r.parserErrors.length>0)throw new c(r);const t=r.value;o.debug("[ABNF Parser] Parsed rules:",t.rules.length),h(t),o.debug("[ABNF Parser] Parse complete")},"parse"),parser:{yy:a}},C={parser:R,db:a,renderer:u,styles:p};export{C as diagram};
1
+ import{g as p,r as u,d as a}from"./chunk-6Q2QTUOP-DIJ0lWTD.js";import{p as f}from"./chunk-JWPE2WC7-CLC3hqKr.js";import{_ as n,l as o}from"./mermaid.core-BVbO1Vp8.js";import"./transform-CzGDKG_M.js";import{M as c,b as d}from"./cynefin-VYW2F7L2-DjqH_9VW.js";import"./main-D3HpSUyK.js";import"./index-C-4sKCSr.js";import"./step-SI6FXFD6.js";var v=d().RailroadAbnf.parser.LangiumParser,i=n(e=>{const r=e.alternatives.map(g);return r.length===1?r[0]:{type:"choice",alternatives:r}},"transformAlternation"),g=n(e=>{const r=e.elements.map(y);return r.length===1?r[0]:{type:"sequence",elements:r}},"transformConcatenation"),b=n(e=>{if(e.includes("*")){const[t,s]=e.split("*"),m=t?parseInt(t,10):0,l=s?parseInt(s,10):1/0;return{min:m,max:l}}const r=parseInt(e,10);return{min:r,max:r}},"parseRepeat"),y=n(e=>{const r=A(e.primary);if(!e.repeat)return r;const{min:t,max:s}=b(e.repeat);return t===0&&s===1?{type:"optional",element:r}:{type:"repetition",element:r,min:t,max:s}},"transformElement"),A=n(e=>{switch(e.$type){case"AbnfStringLiteral":return{type:"terminal",value:e.value};case"AbnfNumVal":return{type:"terminal",value:e.value};case"AbnfRuleName":return{type:"nonterminal",name:e.name};case"AbnfGroup":return i(e.element);case"AbnfOptionalGroup":return{type:"optional",element:i(e.element)};default:throw new Error(`Unsupported ABNF primary node: ${e.$type}`)}},"transformPrimary"),P=n(e=>({name:e.name,definition:i(e.definition)}),"transformRule"),h=n(e=>{f(e,a),e.title&&a.setTitle(e.title),e.rules.map(r=>a.addRule(P(r)))},"populateDb"),R={parse:n(e=>{a.clear(),o.debug("[ABNF Parser] Starting Langium parse");const r=v.parse(e);if(r.lexerErrors.length>0||r.parserErrors.length>0)throw new c(r);const t=r.value;o.debug("[ABNF Parser] Parsed rules:",t.rules.length),h(t),o.debug("[ABNF Parser] Parse complete")},"parse"),parser:{yy:a}},C={parser:R,db:a,renderer:u,styles:p};export{C as diagram};
@@ -1 +1 @@
1
- import{g as p,r as u,d as a}from"./chunk-XCWWM2C3-BAq7zpgL.js";import{p as f}from"./chunk-VII2H2IX-kQVDZD-x.js";import{M as c,b as d}from"./cynefin-OW5HDTMX-GVF3BKWE-Bdt2EF7g.js";import{_ as n,l as o}from"./render-O7CIS3YK-DhYmSGoI.js";import"./transform-CzGDKG_M.js";import"./mermaid-layout-elk.core-BUAJJUsd.js";import"./main-CGE6fm01.js";import"./index-xynt7zMk.js";import"./step-SI6FXFD6.js";import"./_commonjs-dynamic-modules-TDtrdbi3.js";var v=d().RailroadAbnf.parser.LangiumParser,i=n(e=>{const r=e.alternatives.map(g);return r.length===1?r[0]:{type:"choice",alternatives:r}},"transformAlternation"),g=n(e=>{const r=e.elements.map(y);return r.length===1?r[0]:{type:"sequence",elements:r}},"transformConcatenation"),b=n(e=>{if(e.includes("*")){const[t,s]=e.split("*"),m=t?parseInt(t,10):0,l=s?parseInt(s,10):1/0;return{min:m,max:l}}const r=parseInt(e,10);return{min:r,max:r}},"parseRepeat"),y=n(e=>{const r=A(e.primary);if(!e.repeat)return r;const{min:t,max:s}=b(e.repeat);return t===0&&s===1?{type:"optional",element:r}:{type:"repetition",element:r,min:t,max:s}},"transformElement"),A=n(e=>{switch(e.$type){case"AbnfStringLiteral":return{type:"terminal",value:e.value};case"AbnfNumVal":return{type:"terminal",value:e.value};case"AbnfRuleName":return{type:"nonterminal",name:e.name};case"AbnfGroup":return i(e.element);case"AbnfOptionalGroup":return{type:"optional",element:i(e.element)};default:throw new Error(`Unsupported ABNF primary node: ${e.$type}`)}},"transformPrimary"),P=n(e=>({name:e.name,definition:i(e.definition)}),"transformRule"),h=n(e=>{f(e,a),e.title&&a.setTitle(e.title),e.rules.map(r=>a.addRule(P(r)))},"populateDb"),R={parse:n(e=>{a.clear(),o.debug("[ABNF Parser] Starting Langium parse");const r=v.parse(e);if(r.lexerErrors.length>0||r.parserErrors.length>0)throw new c(r);const t=r.value;o.debug("[ABNF Parser] Parsed rules:",t.rules.length),h(t),o.debug("[ABNF Parser] Parse complete")},"parse"),parser:{yy:a}},L={parser:R,db:a,renderer:u,styles:p};export{L as diagram};
1
+ import{g as p,r as u,d as a}from"./chunk-XCWWM2C3-C_es6n6S.js";import{p as f}from"./chunk-VII2H2IX-BkXECJ1Z.js";import{M as c,b as d}from"./cynefin-OW5HDTMX-GVF3BKWE-DY90g1OE.js";import{_ as n,l as o}from"./render-O7CIS3YK-C5zxvpoJ.js";import"./transform-CzGDKG_M.js";import"./mermaid-layout-elk.core-KBAfwQxu.js";import"./main-D3HpSUyK.js";import"./index-C-4sKCSr.js";import"./step-SI6FXFD6.js";import"./_commonjs-dynamic-modules-TDtrdbi3.js";var v=d().RailroadAbnf.parser.LangiumParser,i=n(e=>{const r=e.alternatives.map(g);return r.length===1?r[0]:{type:"choice",alternatives:r}},"transformAlternation"),g=n(e=>{const r=e.elements.map(y);return r.length===1?r[0]:{type:"sequence",elements:r}},"transformConcatenation"),b=n(e=>{if(e.includes("*")){const[t,s]=e.split("*"),m=t?parseInt(t,10):0,l=s?parseInt(s,10):1/0;return{min:m,max:l}}const r=parseInt(e,10);return{min:r,max:r}},"parseRepeat"),y=n(e=>{const r=A(e.primary);if(!e.repeat)return r;const{min:t,max:s}=b(e.repeat);return t===0&&s===1?{type:"optional",element:r}:{type:"repetition",element:r,min:t,max:s}},"transformElement"),A=n(e=>{switch(e.$type){case"AbnfStringLiteral":return{type:"terminal",value:e.value};case"AbnfNumVal":return{type:"terminal",value:e.value};case"AbnfRuleName":return{type:"nonterminal",name:e.name};case"AbnfGroup":return i(e.element);case"AbnfOptionalGroup":return{type:"optional",element:i(e.element)};default:throw new Error(`Unsupported ABNF primary node: ${e.$type}`)}},"transformPrimary"),P=n(e=>({name:e.name,definition:i(e.definition)}),"transformRule"),h=n(e=>{f(e,a),e.title&&a.setTitle(e.title),e.rules.map(r=>a.addRule(P(r)))},"populateDb"),R={parse:n(e=>{a.clear(),o.debug("[ABNF Parser] Starting Langium parse");const r=v.parse(e);if(r.lexerErrors.length>0||r.parserErrors.length>0)throw new c(r);const t=r.value;o.debug("[ABNF Parser] Parsed rules:",t.rules.length),h(t),o.debug("[ABNF Parser] Parse complete")},"parse"),parser:{yy:a}},L={parser:R,db:a,renderer:u,styles:p};export{L as diagram};