lookatstudy-mobile 0.38.3 → 0.39.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.
- package/package.json +1 -1
- package/server.cjs +127 -13
- package/web/assets/{CanvasStage-w4ZeJwrQ.js → CanvasStage-x1i_1KCR.js} +1 -1
- package/web/assets/{CommandPalette-BM6fHoJ7.js → CommandPalette-CNu1g62R.js} +1 -1
- package/web/assets/{CompanionBotLab-DHmGbQJd.js → CompanionBotLab-C_wamdK2.js} +1 -1
- package/web/assets/{CourseSearchPanel-chOLEM5d.js → CourseSearchPanel-CaGhbaCn.js} +1 -1
- package/web/assets/{ExamView-hFAGAt4m.js → ExamView-BEGaBL8a.js} +1 -1
- package/web/assets/{MermaidArtifact-BtfzDUc2.js → MermaidArtifact-CREqYN_0.js} +3 -3
- package/web/assets/{ModelManagerModal-t24x8RiW.js → ModelManagerModal-CGDFmp1H.js} +1 -1
- package/web/assets/{PersonalProfileModal-C9R-U5ko.js → PersonalProfileModal-DyFCE3mL.js} +1 -1
- package/web/assets/{ReviewPanel-BbKE9VQ3.js → ReviewPanel-sna9HXbm.js} +1 -1
- package/web/assets/{SettingsView-CePUegaH.js → SettingsView-si6a_N9C.js} +2 -2
- package/web/assets/{Toggle-CEibZGBQ.js → Toggle-Dc2HPsMk.js} +1 -1
- package/web/assets/{VoicePanel-J1z6FBe_.js → VoicePanel-DRZYO5jG.js} +1 -1
- package/web/assets/{abnfDiagram-VCTEODGH-BxbIkM1L.js → abnfDiagram-VCTEODGH-DzCoe6HU.js} +1 -1
- package/web/assets/{abnfDiagram-VCTEODGH-ODA7YWAP-fRKkh3HS.js → abnfDiagram-VCTEODGH-ODA7YWAP--2ZIRaDM.js} +1 -1
- package/web/assets/{architectureDiagram-5GKGNRK7-C4PU3XN7-DFv0wzx5.js → architectureDiagram-5GKGNRK7-C4PU3XN7-BpqyfUQ2.js} +1 -1
- package/web/assets/{architectureDiagram-5GKGNRK7-CklerPXK.js → architectureDiagram-5GKGNRK7-D58Nv2lw.js} +1 -1
- package/web/assets/{blockDiagram-I7D4REHJ-CZMNIs1u.js → blockDiagram-I7D4REHJ-NkJTbPvA.js} +1 -1
- package/web/assets/{blockDiagram-NRAW4CY4-UMJ6PMQQ-BbKpMB5c.js → blockDiagram-NRAW4CY4-UMJ6PMQQ-CdUemdkc.js} +1 -1
- package/web/assets/{c4Diagram-7LVT6UL2-ymdQRNht.js → c4Diagram-7LVT6UL2-BFWN0wCw.js} +1 -1
- package/web/assets/{c4Diagram-UCG6FXSJ-75X3U2P3-ok_lhBVm.js → c4Diagram-UCG6FXSJ-75X3U2P3-Bycv6qNh.js} +1 -1
- package/web/assets/channel-BmHCUYqo.js +1 -0
- package/web/assets/{chunk-2Q5K7J3B-Cn7zPcaJ.js → chunk-2Q5K7J3B-G2Qv9ycY.js} +1 -1
- package/web/assets/{chunk-5VM5RSS4-Dxe5CD6c.js → chunk-5VM5RSS4--ECmiGI1.js} +1 -1
- package/web/assets/{chunk-7XDTSPCN-TnCUb370.js → chunk-7XDTSPCN-DMcMyJXw.js} +1 -1
- package/web/assets/{chunk-CTNIYPP6-CHE3_Njo.js → chunk-CTNIYPP6-HdVmHBlE.js} +1 -1
- package/web/assets/{chunk-CXNFBKHE-DBmJAlZJ.js → chunk-CXNFBKHE-B8zx0KTo.js} +1 -1
- package/web/assets/{chunk-F27PBJKO-B7CY6nEv.js → chunk-F27PBJKO-Doo67Rgm.js} +1 -1
- package/web/assets/{chunk-IMKFNOWR-D2aOJHTs.js → chunk-IMKFNOWR-BslLS5Nl.js} +1 -1
- package/web/assets/{chunk-ISA7TJRJ-DZXqmUMR.js → chunk-ISA7TJRJ-yMSJhRPF.js} +1 -1
- package/web/assets/{chunk-JWPE2WC7-tf0-quEp.js → chunk-JWPE2WC7-Bb_uu4Ps.js} +1 -1
- package/web/assets/{chunk-LV3HUYFY-B1bzmBj2.js → chunk-LV3HUYFY-DJsXZ03l.js} +1 -1
- package/web/assets/{chunk-M3IUQBOH-C2wfMx5k.js → chunk-M3IUQBOH-BLS06vYX.js} +1 -1
- package/web/assets/{chunk-NDIOYS4C-CURLPJwt.js → chunk-NDIOYS4C-CUGOWM3W.js} +1 -1
- package/web/assets/{chunk-POPQ4Y6H-aZiKp-fA.js → chunk-POPQ4Y6H-BLM3ULNo.js} +1 -1
- package/web/assets/{chunk-RE4WF27V-CBC0f21B.js → chunk-RE4WF27V-BMYpYKA4.js} +1 -1
- package/web/assets/{chunk-SVP7TREG-Buu4yZv5.js → chunk-SVP7TREG-DVrWeB8o.js} +1 -1
- package/web/assets/{chunk-TICWLB2K-tR6FMC3v.js → chunk-TICWLB2K-o6mdH-C9.js} +1 -1
- package/web/assets/{chunk-VII2H2IX-IGIGE2ZG.js → chunk-VII2H2IX-B1psLe3a.js} +1 -1
- package/web/assets/{chunk-X5GNSKZ3-C4Kk2u7a.js → chunk-X5GNSKZ3-rWhbJkjK.js} +1 -1
- package/web/assets/{chunk-XCWWM2C3-Cz8rOu4p.js → chunk-XCWWM2C3-Bc5yLm5N.js} +1 -1
- package/web/assets/{chunk-XXDRQBXY-CatzKTit.js → chunk-XXDRQBXY-CdjbZJJ3.js} +1 -1
- package/web/assets/classDiagram-DTDB5LWJ-LWRDKZ5K-Clg_pBP7.js +1 -0
- package/web/assets/classDiagram-ZZMXUADV-DURdktYj.js +1 -0
- package/web/assets/classDiagram-v2-JRS7N3AN-2BZHGRP2-Clg_pBP7.js +1 -0
- package/web/assets/classDiagram-v2-VYDZK3BY-DURdktYj.js +1 -0
- package/web/assets/{core-CRqJ4Q_E.js → core-BdQfSvug.js} +1 -1
- package/web/assets/{cose-bilkent-JH36ORCC-CkqCOeTo.js → cose-bilkent-JH36ORCC-CtjUxC8b.js} +1 -1
- package/web/assets/{cose-bilkent-JH36ORCC-OB24KH3T-juOdC4FR.js → cose-bilkent-JH36ORCC-OB24KH3T-DDjBiqs8.js} +1 -1
- package/web/assets/{cynefin-OW5HDTMX-BFgrQtp9.js → cynefin-OW5HDTMX-Bd6yfDs_.js} +1 -1
- package/web/assets/{cynefin-OW5HDTMX-GVF3BKWE-BOd2wBp9.js → cynefin-OW5HDTMX-GVF3BKWE-cynZE-Hg.js} +1 -1
- package/web/assets/{cynefinDiagram-5FMLGOSQ-BB2YPlQ9.js → cynefinDiagram-5FMLGOSQ-Bzxd2aGG.js} +1 -1
- package/web/assets/{cynefinDiagram-5FMLGOSQ-H3WIRU3N-Ck9-Pv8t.js → cynefinDiagram-5FMLGOSQ-H3WIRU3N-CAzI955y.js} +1 -1
- package/web/assets/{dagre-3AP2YEHR-DCERTXHT-CSU8gN1L.js → dagre-3AP2YEHR-DCERTXHT-CPuWupJf.js} +1 -1
- package/web/assets/{dagre-GXQ25YYZ-Mk7z790X.js → dagre-GXQ25YYZ-C-PgWPxB.js} +1 -1
- package/web/assets/{diagram-S7CK7UJ4-Bz52TUEp.js → diagram-S7CK7UJ4-BfglJki_.js} +1 -1
- package/web/assets/{diagram-S7CK7UJ4-MULGZGEL-BgGTSOao.js → diagram-S7CK7UJ4-MULGZGEL-VcggxA7L.js} +1 -1
- package/web/assets/{diagram-UQ7AKVKN-CVb_IQ6L.js → diagram-UQ7AKVKN-BLRECJ0V.js} +1 -1
- package/web/assets/{diagram-UQ7AKVKN-YQBY353J-CKMdDCHN.js → diagram-UQ7AKVKN-YQBY353J-D5j8jgEG.js} +1 -1
- package/web/assets/{diagram-VSXAHHWV-CWZZvHwV.js → diagram-VSXAHHWV-Ci58fess.js} +1 -1
- package/web/assets/{diagram-VSXAHHWV-WLNH2ELY-CbhSz0AY.js → diagram-VSXAHHWV-WLNH2ELY-Da7sTqrP.js} +1 -1
- package/web/assets/{diagram-VX7I27RA-50sXDHFK.js → diagram-VX7I27RA-BT8Rqi9Y.js} +1 -1
- package/web/assets/{diagram-VX7I27RA-XW6YQV5G-B48SGxWw.js → diagram-VX7I27RA-XW6YQV5G-9E6wuc38.js} +1 -1
- package/web/assets/{diagram-Z3DM3KII-Ma5O7Wvc.js → diagram-Z3DM3KII-DP0ouW_9.js} +1 -1
- package/web/assets/{diagram-Z3DM3KII-HG7RF65D-DZHe0N9Q.js → diagram-Z3DM3KII-HG7RF65D-CTC8Ho-N.js} +1 -1
- package/web/assets/{ebnfDiagram-PWID7BFC-E4R6x3BG.js → ebnfDiagram-PWID7BFC-MY0g-frt.js} +1 -1
- package/web/assets/{ebnfDiagram-PWID7BFC-OKY4VHYD-B_GNL-lf.js → ebnfDiagram-PWID7BFC-OKY4VHYD-Bh53lhE4.js} +1 -1
- package/web/assets/{elk.bundled-Cez1bZui.js → elk.bundled-BBYPM_mJ.js} +1 -1
- package/web/assets/{erDiagram-RLTQ6QDP-BEILk2jW.js → erDiagram-RLTQ6QDP-kcIC2Emq.js} +1 -1
- package/web/assets/{erDiagram-SSCWMZ5O-PIPKOIK7-dRh-n90X.js → erDiagram-SSCWMZ5O-PIPKOIK7-B5IhXeJm.js} +1 -1
- package/web/assets/{flowDiagram-A5DVABFB-2Z4AVO5R-CsnXAa8R.js → flowDiagram-A5DVABFB-2Z4AVO5R-E6W_sP1S.js} +1 -1
- package/web/assets/{flowDiagram-HODETNUW-D5iNQK_m.js → flowDiagram-HODETNUW-BGgGlacD.js} +1 -1
- package/web/assets/{ganttDiagram-EL5Y4UJY-D5Ul8pOV.js → ganttDiagram-EL5Y4UJY-DZd0UVmN.js} +1 -1
- package/web/assets/{ganttDiagram-EL5Y4UJY-JZNG7GOG-BUbATXbl.js → ganttDiagram-EL5Y4UJY-JZNG7GOG-CzH60Qln.js} +1 -1
- package/web/assets/{gitGraphDiagram-WWUBYQGX-D300RUA5.js → gitGraphDiagram-WWUBYQGX-CIWVlkyW.js} +1 -1
- package/web/assets/{gitGraphDiagram-WWUBYQGX-DMWMLL3G-B9UXyVFP.js → gitGraphDiagram-WWUBYQGX-DMWMLL3G-sJvH8Ysq.js} +1 -1
- package/web/assets/index-B7IHDZbN.css +1 -0
- package/web/assets/{index-DQE3KX7b.js → index-CsdO9A-v.js} +1 -1
- package/web/assets/{index-DAPahbzX.js → index-D0dPAwGk.js} +1 -1
- package/web/assets/{index-DiBF8331.js → index-DHYsjMlf.js} +3 -3
- package/web/assets/{infoDiagram-27XIBGKW-Cta6ZmOB.js → infoDiagram-27XIBGKW-lrcOZ9yQ.js} +1 -1
- package/web/assets/{infoDiagram-RXCK75RN-HANS5KVC-Cj6Eokea.js → infoDiagram-RXCK75RN-HANS5KVC-C_Gtz_ZE.js} +1 -1
- package/web/assets/{ishikawaDiagram-5VMMS53U-7GCIT7WU-B4XQCJUp.js → ishikawaDiagram-5VMMS53U-7GCIT7WU-nIUTVRQu.js} +1 -1
- package/web/assets/{ishikawaDiagram-5VMMS53U-BhZLGqyX.js → ishikawaDiagram-5VMMS53U-Dc9wIm4K.js} +1 -1
- package/web/assets/{journeyDiagram-3NMN7TZE-I7ckWi8V.js → journeyDiagram-3NMN7TZE-Ccog3mxG.js} +1 -1
- package/web/assets/{journeyDiagram-EYS64GPL-OAPELBT7-Bu5JWfMr.js → journeyDiagram-EYS64GPL-OAPELBT7-BvcBJ3Ys.js} +1 -1
- package/web/assets/{kanban-definition-3QL26DDD-I7RKWQQY-CF3_TQDj.js → kanban-definition-3QL26DDD-I7RKWQQY-CqVB3aR7.js} +1 -1
- package/web/assets/{kanban-definition-UXKFOSKX-D4wFp2-H.js → kanban-definition-UXKFOSKX-ClKi_l4Q.js} +1 -1
- package/web/assets/{katex-N6JRN4PM-Cbi2gBGQ.js → katex-N6JRN4PM-CvDb1Wha.js} +1 -1
- package/web/assets/{layout-fmIRuN-x.js → layout-DAuaYzvz.js} +1 -1
- package/web/assets/main-DYCYXJqp.js +554 -0
- package/web/assets/{mermaid-layout-elk.core-BP9RfmyE.js → mermaid-layout-elk.core-BxaTdUpV.js} +2 -2
- package/web/assets/{mermaid.core-CFB6SYUU.js → mermaid.core-BlnXIWO2.js} +5 -5
- package/web/assets/{mindmap-definition-FBJOCRG2-KIYZG64Y-BBlEaFu2.js → mindmap-definition-FBJOCRG2-KIYZG64Y-IfgrOEbr.js} +1 -1
- package/web/assets/{mindmap-definition-YA3MSWOX-DxLi9G-Q.js → mindmap-definition-YA3MSWOX-CICSJU__.js} +1 -1
- package/web/assets/{pegDiagram-XKGWAZYB-BYmlUVbe.js → pegDiagram-XKGWAZYB-CIM4OFw0.js} +1 -1
- package/web/assets/{pegDiagram-XKGWAZYB-OIP57N6J-D-sZdpuJ.js → pegDiagram-XKGWAZYB-OIP57N6J-qTBuOKky.js} +1 -1
- package/web/assets/{pet-7_82JHov.js → pet-B7T4HZar.js} +1 -1
- package/web/assets/{pieDiagram-E7YTZNPT-2UOTW327-CTWSlXqZ.js → pieDiagram-E7YTZNPT-2UOTW327-BokPxxaZ.js} +1 -1
- package/web/assets/{pieDiagram-E7YTZNPT-CQvUEqRo.js → pieDiagram-E7YTZNPT-DvrqcRv0.js} +1 -1
- package/web/assets/{quadrantDiagram-AXDQQJYC-Ked2QFzx.js → quadrantDiagram-AXDQQJYC-CtGa1VKp.js} +1 -1
- package/web/assets/{quadrantDiagram-AXDQQJYC-SN3ASJJK-BztrBW6X.js → quadrantDiagram-AXDQQJYC-SN3ASJJK-aVb8mDQ3.js} +1 -1
- package/web/assets/{railroadDiagram-O6MQD6OU-34742W6X-DDJXRDYw.js → railroadDiagram-O6MQD6OU-34742W6X-5shHro23.js} +1 -1
- package/web/assets/{railroadDiagram-O6MQD6OU-CKs6vckE.js → railroadDiagram-O6MQD6OU-Bp9tNp36.js} +1 -1
- package/web/assets/{render-O7CIS3YK-DrLxIH3C.js → render-O7CIS3YK-BtNfBcVh.js} +7 -7
- package/web/assets/{requirementDiagram-BXWQKSXE-Df5nIsY_.js → requirementDiagram-BXWQKSXE-Bn-Iyjue.js} +1 -1
- package/web/assets/{requirementDiagram-EFPCY7ZU-NGAFFSMB-BGzUUTlQ.js → requirementDiagram-EFPCY7ZU-NGAFFSMB-ZV4Zgm9x.js} +1 -1
- package/web/assets/{rotate-ccw-ChWz7hYv.js → rotate-ccw-DwFJJCY4.js} +1 -1
- package/web/assets/{sankeyDiagram-P5KCCOFB-3D3M4XPB-CYhPEOwJ.js → sankeyDiagram-P5KCCOFB-3D3M4XPB-BxAo2SE2.js} +1 -1
- package/web/assets/{sankeyDiagram-P5KCCOFB-CFl3aUTC.js → sankeyDiagram-P5KCCOFB-LJ7yOW9A.js} +1 -1
- package/web/assets/{sequenceDiagram-WJ2MYXX4-qUrCnsuJ.js → sequenceDiagram-WJ2MYXX4-8X7iHp4R.js} +1 -1
- package/web/assets/{sequenceDiagram-WJ2MYXX4-Q2IOPB4R-C9m9xSMo.js → sequenceDiagram-WJ2MYXX4-Q2IOPB4R-DNoijxAb.js} +1 -1
- package/web/assets/{sizeCapture-INFHLROL-RI5EIZzr.js → sizeCapture-INFHLROL-Bhuultdb.js} +1 -1
- package/web/assets/{sizeCapture-X5ZJPWSS-PSGVOMYM-DkjTfTNV.js → sizeCapture-X5ZJPWSS-PSGVOMYM-CjCuFNy9.js} +1 -1
- package/web/assets/{stateDiagram-D77RDMKH-OQpvIHR8.js → stateDiagram-D77RDMKH-DvAJSYG-.js} +1 -1
- package/web/assets/{stateDiagram-HBIQ2CUA-4M2S6MAN-C09CBNgu.js → stateDiagram-HBIQ2CUA-4M2S6MAN-CkC0VdGd.js} +1 -1
- package/web/assets/stateDiagram-v2-4QOOHH4V-LBBLA2WV-BUxaHuA0.js +1 -0
- package/web/assets/stateDiagram-v2-MP3YSRHH-BYCvOR8k.js +1 -0
- package/web/assets/{swimlanes-42K2YHIH-ZxQbibd3.js → swimlanes-42K2YHIH-DzLzaHma.js} +1 -1
- package/web/assets/{swimlanes-XN3QIQJK-N6N2CCQ6-5djqGOFq.js → swimlanes-XN3QIQJK-N6N2CCQ6-CV3RjRHG.js} +1 -1
- package/web/assets/swimlanesDiagram-VK2B7HYN-E6N4H5SY-6Os78ODV.js +8 -0
- package/web/assets/swimlanesDiagram-VR7AAH4N-AaM1658d.js +8 -0
- package/web/assets/{timeline-definition-24CTP7MA-BKQhun4x.js → timeline-definition-24CTP7MA-CMvJTsge.js} +1 -1
- package/web/assets/{timeline-definition-24CTP7MA-KN7RSRVM-BWTEPsS3.js → timeline-definition-24CTP7MA-KN7RSRVM-CC192RwQ.js} +1 -1
- package/web/assets/{vennDiagram-4TSXK5OY-AKJ7LXAN-CoRIQzN3.js → vennDiagram-4TSXK5OY-AKJ7LXAN-_GQh-UxA.js} +1 -1
- package/web/assets/{vennDiagram-4TSXK5OY-B0jff-Yf.js → vennDiagram-4TSXK5OY-B7fL1P_V.js} +1 -1
- package/web/assets/{wardleyDiagram-VM6X3IG4-3B6A3BN5-DTHtAh1_.js → wardleyDiagram-VM6X3IG4-3B6A3BN5-DXhPYQCK.js} +1 -1
- package/web/assets/{wardleyDiagram-VM6X3IG4-CCFEp1LK.js → wardleyDiagram-VM6X3IG4-DQsKC4jM.js} +1 -1
- package/web/assets/{xychartDiagram-S5SC5T6Z-DehkcgWB.js → xychartDiagram-S5SC5T6Z-Cu_o7fqg.js} +1 -1
- package/web/assets/{xychartDiagram-S5SC5T6Z-OBDNV6WG-CqYw05pP.js → xychartDiagram-S5SC5T6Z-OBDNV6WG-B6Z8COuj.js} +1 -1
- package/web/index.html +3 -3
- package/web/pet.html +3 -3
- package/web/assets/channel-BtlWkm43.js +0 -1
- package/web/assets/classDiagram-DTDB5LWJ-LWRDKZ5K-BSR-3up6.js +0 -1
- package/web/assets/classDiagram-ZZMXUADV-EyERu_sO.js +0 -1
- package/web/assets/classDiagram-v2-JRS7N3AN-2BZHGRP2-BSR-3up6.js +0 -1
- package/web/assets/classDiagram-v2-VYDZK3BY-EyERu_sO.js +0 -1
- package/web/assets/index-CS4Wtfwl.css +0 -1
- package/web/assets/main-BG2k-Vog.js +0 -537
- package/web/assets/stateDiagram-v2-4QOOHH4V-LBBLA2WV-B-9boNOx.js +0 -1
- package/web/assets/stateDiagram-v2-MP3YSRHH-BNdisWni.js +0 -1
- package/web/assets/swimlanesDiagram-VK2B7HYN-E6N4H5SY-aUoktW6T.js +0 -8
- package/web/assets/swimlanesDiagram-VR7AAH4N-Q0TWUgro.js +0 -8
- /package/web/assets/{index-jKxnKPxh.js → index-88125dOi.js} +0 -0
package/package.json
CHANGED
package/server.cjs
CHANGED
|
@@ -12945,6 +12945,7 @@ var init_schema = __esm({
|
|
|
12945
12945
|
/** 主焦点节点(可空,影响 AI 注入的节点上下文) */
|
|
12946
12946
|
focusNodeId: text("focus_node_id"),
|
|
12947
12947
|
status: text("status", { enum: ["active", "archived"] }).notNull().default("active"),
|
|
12948
|
+
kind: text("kind", { enum: ["chat", "review"] }).notNull().default("chat"),
|
|
12948
12949
|
createdAt: text("created_at").notNull().default(sql`(CURRENT_TIMESTAMP)`),
|
|
12949
12950
|
updatedAt: text("updated_at").notNull().default(sql`(CURRENT_TIMESTAMP)`),
|
|
12950
12951
|
messageCount: integer("message_count").notNull().default(0)
|
|
@@ -13329,6 +13330,7 @@ CREATE TABLE IF NOT EXISTS threads (
|
|
|
13329
13330
|
title TEXT, -- \u7528\u6237\u8D77\u7684\u540D,\u5982"\u6CE8\u610F\u529B\u673A\u5236\u6DF1\u6316"
|
|
13330
13331
|
focus_node_id TEXT, -- \u4E3B\u7126\u70B9\u8282\u70B9(\u53EF\u7A7A,\u5F71\u54CD AI \u6CE8\u5165\u7684\u8282\u70B9\u4E0A\u4E0B\u6587)
|
|
13331
13332
|
status TEXT NOT NULL DEFAULT 'active', -- active / archived
|
|
13333
|
+
kind TEXT NOT NULL DEFAULT 'chat', -- chat / review(\u590D\u4E60\u4F1A\u8BDD\u7EBF\u7A0B:\u5F15\u64CE\u6CE8\u5165\u590D\u4E60\u5BFC\u5E08\u59FF\u6001,tab \u52A0\u5FBD\u6807)
|
|
13332
13334
|
created_at TEXT NOT NULL DEFAULT (CURRENT_TIMESTAMP),
|
|
13333
13335
|
updated_at TEXT NOT NULL DEFAULT (CURRENT_TIMESTAMP),
|
|
13334
13336
|
message_count INTEGER NOT NULL DEFAULT 0
|
|
@@ -13502,6 +13504,7 @@ function runMigrations(db) {
|
|
|
13502
13504
|
addColumnIfMissing("canvas_items", "last_result", "TEXT");
|
|
13503
13505
|
addColumnIfMissing("canvas_items", "result_at", "TEXT");
|
|
13504
13506
|
addColumnIfMissing("chat_messages", "display_text", "TEXT");
|
|
13507
|
+
addColumnIfMissing("threads", "kind", "TEXT NOT NULL DEFAULT 'chat'");
|
|
13505
13508
|
ensureExamTypeAllowed(db);
|
|
13506
13509
|
migrateSoulRename(db);
|
|
13507
13510
|
}
|
|
@@ -527710,7 +527713,7 @@ init_drizzle_orm();
|
|
|
527710
527713
|
var import_node_crypto26 = require("node:crypto");
|
|
527711
527714
|
|
|
527712
527715
|
// package.json
|
|
527713
|
-
var version2 = "0.
|
|
527716
|
+
var version2 = "0.39.0";
|
|
527714
527717
|
|
|
527715
527718
|
// src/main/lib/update-check.ts
|
|
527716
527719
|
var RELEASES_PAGE = "https://github.com/Kaiji-Z/LookatStudy/releases";
|
|
@@ -529710,12 +529713,14 @@ function recordReviewDb(db, nodeId, quality) {
|
|
|
529710
529713
|
lastReviewedAt: nowIso
|
|
529711
529714
|
}).run();
|
|
529712
529715
|
}
|
|
529716
|
+
return result;
|
|
529713
529717
|
}
|
|
529714
529718
|
|
|
529715
529719
|
// src/main/services/srs.ts
|
|
529716
529720
|
function recordReview(nodeId, quality) {
|
|
529717
|
-
recordReviewDb(getDb(), nodeId, quality);
|
|
529721
|
+
const result = recordReviewDb(getDb(), nodeId, quality);
|
|
529718
529722
|
markDirty();
|
|
529723
|
+
return result;
|
|
529719
529724
|
}
|
|
529720
529725
|
function getDueReviewNodeIds(now2 = /* @__PURE__ */ new Date()) {
|
|
529721
529726
|
const db = getDb();
|
|
@@ -529966,6 +529971,7 @@ function createThread(input) {
|
|
|
529966
529971
|
title: input.title ?? null,
|
|
529967
529972
|
focusNodeId: input.focusNodeId ?? null,
|
|
529968
529973
|
status: "active",
|
|
529974
|
+
kind: input.kind ?? "chat",
|
|
529969
529975
|
createdAt: now2,
|
|
529970
529976
|
updatedAt: now2,
|
|
529971
529977
|
messageCount: 0
|
|
@@ -559287,6 +559293,49 @@ function buildSoulLangReminder(locale) {
|
|
|
559287
559293
|
const name19 = localeToLanguageName(locale);
|
|
559288
559294
|
return `Reminder: the persona body above defines teaching behavior only \u2014 ignore its language. Everything you output, tool parameters included, stays in ${name19}.`;
|
|
559289
559295
|
}
|
|
559296
|
+
function buildReviewTutorBlock(locale) {
|
|
559297
|
+
if (isZhLocale(locale)) {
|
|
559298
|
+
return "\u3010\u590D\u4E60\u5BFC\u5E08\u59FF\u6001\u3011\u8FD9\u573A\u4F1A\u8BDD\u662F\u95F4\u9694\u590D\u4E60\u2014\u2014\u5B66\u4E60\u8005\u5DF2\u7ECF\u5B66\u8FC7\u672C\u8BFE,\u73B0\u5728\u68C0\u9A8C\u5E76\u5DE9\u56FA\u8BB0\u5FC6,\u4E0D\u662F\u65B0\u6388\u8BFE:\n- \u5148\u5FC6\u540E\u770B:\u5F00\u573A\u4E0E\u6574\u4E2A\u590D\u4E60\u8FC7\u7A0B\u90FD\u4E0D\u8981\u4E3B\u52A8\u8D34\u51FA\u8BFE\u6587\u539F\u6587\u6216\u5927\u6BB5\u91CD\u8BB2\u3002\u5148\u7528 1 \u4E2A\u56DE\u5FC6\u6027\u95EE\u9898\u8BA9\u5B66\u4E60\u8005\u51ED\u8BB0\u5FC6\u4F5C\u7B54,\u6839\u636E\u56DE\u7B54\u51B3\u5B9A\u4E0B\u4E00\u6B65;\n- \u5BF9\u51C6\u5F31\u9879:\u4F18\u5148\u8003\u5BDF\u638C\u63E1\u5EA6\u504F\u4F4E\u7684\u77E5\u8BC6\u70B9(\u4E0A\u65B9\u6E05\u5355\u91CC\u6807\u6CE8\u504F\u4F4E\u7684)\u4E0E\u5B66\u4E60\u8005\u66FE\u7ECF\u7684\u5361\u70B9;\u4E0A\u4E00\u8F6E\u590D\u4E60\u6536\u675F\u8BB0\u5F55\u91CC\u7559\u4E0B\u7684\u8584\u5F31\u70B9\u662F\u7B2C\u4E00\u63D0\u95EE\u5BF9\u8C61;\n- \u9519\u4E86\u624D\u8BB2:\u5B66\u4E60\u8005\u7B54\u9519\u6216\u60F3\u4E0D\u8D77\u6765,\u624D\u9488\u5BF9\u90A3\u4E00\u4E2A\u7F3A\u53E3\u7B80\u77ED\u56DE\u8BB2,\u8BB2\u5B8C\u8BF7\u4ED6\u7528\u81EA\u5DF1\u7684\u8BDD\u590D\u8FF0\u4E00\u904D;\u7B54\u5BF9\u5C31\u786E\u8BA4\u5E76\u63A8\u8FDB,\u4E0D\u91CD\u590D\u8BB2\u89E3;\n- \u8BA1\u5206\u68C0\u9A8C:\u590D\u4E60\u4E2D\u9014\u7528 generate_quiz \u51FA 2~4 \u9898\u5C0F\u6D4B(\u5BF9\u51C6\u5F31\u9879),\u7B54\u9898\u4F1A\u88AB\u7CFB\u7EDF\u81EA\u52A8\u5224\u5206\u5E76\u8BA1\u5165\u638C\u63E1\u5EA6;\u81EA\u7531\u95EE\u7B54\u7684\u5224\u5206\u7528 record_answer;\n- \u9002\u65F6\u6536\u675F:\u590D\u4E60 3~6 \u8F6E\u540E,\u6216\u5B66\u4E60\u8005\u660E\u786E\u8868\u793A\u8981\u7ED3\u675F,\u8C03\u7528 end_review_session \u6536\u675F\u2014\u2014quality \u6309\u6807\u5C3A\u8BC4\u5B9A(1=\u51E0\u4E4E\u4E0D\u8BB0\u5F97/2=\u591A\u6570\u5FD8\u4E86/3=\u52C9\u5F3A\u60F3\u8D77/4=\u8BB0\u5F97/5=\u5F88\u719F),summary \u7528\u4E00\u4E24\u53E5\u6982\u62EC\u672C\u6B21\u8868\u73B0,weakPoints \u5217\u51FA\u4E0B\u6B21\u8981\u91CD\u70B9\u8003\u5BDF\u7684\u8584\u5F31\u70B9;\n- \u6536\u675F\u56DE\u5408\u653E\u5BBD\u5DE5\u5177\u9650\u5236:\u6700\u540E\u4E00\u6761\u56DE\u590D\u53EF\u4EE5\u540C\u65F6\u53D1 generate_quiz \u548C end_review_session;\u5176\u4F59\u56DE\u5408\u4ECD\u9075\u5B88\u300C\u4E00\u6B21\u56DE\u590D\u6700\u591A 1 \u4E2A\u5DE5\u5177\u300D;\n- \u590D\u4E60\u4F1A\u8BDD\u4E2D\u4E0D\u8981\u8C03\u7528 mark_mastered\u2014\u2014\u590D\u4E60\u4E0D\u53D1\u8D77\u6BD5\u4E1A\u5224\u5B9A,\u638C\u63E1\u5EA6\u4EA4\u7ED9\u7B54\u9898\u89C2\u6D4B\u81EA\u7136\u6F14\u8FDB\u3002";
|
|
559299
|
+
}
|
|
559300
|
+
return "[Review-tutor posture] This conversation is a spaced-review session \u2014 the learner has already studied this lesson; you are testing and consolidating memory, not teaching it fresh:\n- Recall first, reveal later: never open with the lesson text or a long re-teach \u2014 not at the start, not mid-session. Begin with one recall question and let the learner answer from memory; decide the next step from their answer;\n- Target weak spots: prioritize knowledge components marked low in the list above and the learner's past friction points; weak points left in the previous session's closing record are your first questions;\n- Explain only what failed: when the learner is wrong or cannot recall, give a short, targeted re-teach of exactly that gap, then ask them to restate it in their own words; when they're right, confirm and move on \u2014 no re-explaining;\n- Scored check: mid-session, use generate_quiz for a 2-4 question check (aimed at weak spots) \u2014 answers are auto-graded by the system and feed mastery; judge free-text answers via record_answer;\n- Close in time: after 3-6 rounds, or when the learner clearly wants to stop, call end_review_session \u2014 grade quality on the scale (1=remember almost nothing / 2=most of it gone / 3=barely recalled / 4=remembered / 5=solid), write a one-or-two-sentence summary, and list weakPoints to focus on next time;\n- The one-tool-per-reply limit is relaxed on the closing reply only: you may send generate_quiz together with end_review_session; other replies still respect the limit;\n- Do not call mark_mastered in a review session \u2014 reviews never initiate graduation; mastery evolves only through graded answer observations.";
|
|
559301
|
+
}
|
|
559302
|
+
|
|
559303
|
+
// shared/review-session.ts
|
|
559304
|
+
var REVIEW_END_TOOL_NAME = "end_review_session";
|
|
559305
|
+
var REVIEW_KICKOFF_MARKER = "[[review-kickoff]]";
|
|
559306
|
+
function reviewXpKindForQuality(quality) {
|
|
559307
|
+
if (quality >= 4)
|
|
559308
|
+
return "correct";
|
|
559309
|
+
if (quality <= 2)
|
|
559310
|
+
return "wrong";
|
|
559311
|
+
return null;
|
|
559312
|
+
}
|
|
559313
|
+
function reviewRoundState(messages) {
|
|
559314
|
+
for (let i = messages.length - 1; i >= 0; i--) {
|
|
559315
|
+
const m = messages[i];
|
|
559316
|
+
if (m.role === "assistant" && m.partsJson && partsHaveEnd(jsonParts(m.partsJson)))
|
|
559317
|
+
return "ended";
|
|
559318
|
+
if (m.role === "user" && m.content.includes(REVIEW_KICKOFF_MARKER))
|
|
559319
|
+
return "open";
|
|
559320
|
+
}
|
|
559321
|
+
return "open";
|
|
559322
|
+
}
|
|
559323
|
+
function jsonParts(partsJson) {
|
|
559324
|
+
try {
|
|
559325
|
+
const parts = JSON.parse(partsJson);
|
|
559326
|
+
return Array.isArray(parts) ? parts : [];
|
|
559327
|
+
} catch {
|
|
559328
|
+
return [];
|
|
559329
|
+
}
|
|
559330
|
+
}
|
|
559331
|
+
function partsHaveEnd(parts) {
|
|
559332
|
+
for (const part of parts) {
|
|
559333
|
+
if (part.type === "tool-call" && part.toolName === REVIEW_END_TOOL_NAME && part.state === "output-available") {
|
|
559334
|
+
return true;
|
|
559335
|
+
}
|
|
559336
|
+
}
|
|
559337
|
+
return false;
|
|
559338
|
+
}
|
|
559290
559339
|
|
|
559291
559340
|
// src/main/services/learner-model-service.ts
|
|
559292
559341
|
init_drizzle_orm();
|
|
@@ -559330,6 +559379,10 @@ function describeOne(toolName, output) {
|
|
|
559330
559379
|
const o = output ?? {};
|
|
559331
559380
|
const title = typeof o.title === "string" && o.title ? `\u300A${o.title}\u300B` : "";
|
|
559332
559381
|
switch (o.artifactType ?? toolName) {
|
|
559382
|
+
case REVIEW_END_TOOL_NAME: {
|
|
559383
|
+
const wp = Array.isArray(o.weakPoints) ? o.weakPoints.filter((w) => typeof w === "string") : [];
|
|
559384
|
+
return `\u5DF2\u6536\u675F\u672C\u8F6E\u590D\u4E60(\u8D28\u91CF ${o.quality ?? "?"}/5${wp.length > 0 ? `,\u4E0B\u6B21\u91CD\u70B9:${wp.join("\u3001")}` : ""})`;
|
|
559385
|
+
}
|
|
559333
559386
|
case "quiz":
|
|
559334
559387
|
return `\u5DF2\u5411\u5B66\u4E60\u8005\u53D1\u51FA\u4EA4\u4E92\u7B54\u9898\u5361${title}(\u5171 ${o.questions?.length ?? "?"} \u9898),\u5B66\u4E60\u8005\u53EF\u76F4\u63A5\u4F5C\u7B54`;
|
|
559335
559388
|
case "concept_map":
|
|
@@ -559418,7 +559471,7 @@ function extractInlineDataImages(content) {
|
|
|
559418
559471
|
out.push(m[1]);
|
|
559419
559472
|
return out;
|
|
559420
559473
|
}
|
|
559421
|
-
function assembleContextBlocks(db, nodeId, locale) {
|
|
559474
|
+
function assembleContextBlocks(db, nodeId, locale, opts) {
|
|
559422
559475
|
const node = db.select().from(contentNodes).where(eq(contentNodes.id, nodeId)).get();
|
|
559423
559476
|
const nodeProgress = db.select().from(progress).where(eq(progress.nodeId, nodeId)).get();
|
|
559424
559477
|
const courseId = node?.courseId;
|
|
@@ -559426,7 +559479,7 @@ function assembleContextBlocks(db, nodeId, locale) {
|
|
|
559426
559479
|
const outLang = resolveOutputLang(locale);
|
|
559427
559480
|
const system = buildSystemPrompt(
|
|
559428
559481
|
db,
|
|
559429
|
-
buildBaseAgentPrompt(outLang, course?.languageTarget ?? null),
|
|
559482
|
+
buildBaseAgentPrompt(outLang, course?.languageTarget ?? null) + (opts?.reviewMode ? "\n\n" + buildReviewTutorBlock(outLang) : ""),
|
|
559430
559483
|
buildSoulLangReminder(outLang)
|
|
559431
559484
|
);
|
|
559432
559485
|
const courseSections = courseId ? db.select().from(contentNodes).where(eq(contentNodes.courseId, courseId)).all().filter((n) => n.type === "section").sort((a, b) => a.orderIdx - b.orderIdx) : [];
|
|
@@ -559465,13 +559518,21 @@ ${kcContext}` : "") : "(\u65E0\u5F53\u524D\u8282\u70B9\u4E0A\u4E0B\u6587)";
|
|
|
559465
559518
|
);
|
|
559466
559519
|
return { system, nodeContext, learnerSnapshot, profileBlock, node, nodeProgress };
|
|
559467
559520
|
}
|
|
559468
|
-
async function runAgentTurn(db, nodeId, messages, events = {}, abortSignal, locale, attachments) {
|
|
559521
|
+
async function runAgentTurn(db, nodeId, messages, events = {}, abortSignal, locale, attachments, opts) {
|
|
559469
559522
|
const llm = resolveLlm(db);
|
|
559470
|
-
const
|
|
559523
|
+
const reviewMode = opts?.reviewMode === true;
|
|
559524
|
+
const { system, nodeContext, learnerSnapshot, profileBlock, node, nodeProgress } = assembleContextBlocks(
|
|
559525
|
+
db,
|
|
559526
|
+
nodeId,
|
|
559527
|
+
locale,
|
|
559528
|
+
{ reviewMode }
|
|
559529
|
+
);
|
|
559530
|
+
const systemPrompt = reviewMode && opts?.reviewAlreadyEnded ? system + "\n\n(\u7CFB\u7EDF\u63D0\u793A:\u672C\u590D\u4E60\u4F1A\u8BDD\u5DF2\u7ECF\u6536\u675F\u8FC7,\u73B0\u5728\u6B63\u5E38\u7B54\u7591\u5373\u53EF,\u4E0D\u8981\u518D\u8C03\u7528 end_review_session\u3002)" : system;
|
|
559471
559531
|
const mainVisionCapable = supportsVision(llm.provider, llm.model);
|
|
559472
559532
|
const routing = visionRouting(mainVisionCapable, getVisionOverride(db) !== null);
|
|
559473
559533
|
let recordAnswerCalls = 0;
|
|
559474
559534
|
const RECORD_ANSWER_TURN_LIMIT = 8;
|
|
559535
|
+
let endReviewCalls = 0;
|
|
559475
559536
|
const tools = {
|
|
559476
559537
|
get_node_info: tool({
|
|
559477
559538
|
description: "\u8BFB\u53D6\u5F53\u524D\u5B66\u4E60\u8282\u70B9\u7684\u8BE6\u7EC6\u4FE1\u606F\uFF08\u6807\u9898\u3001\u5185\u5BB9\u3001\u638C\u63E1\u5EA6\uFF09\u3002\u53EA\u8BFB\u3002",
|
|
@@ -559624,6 +559685,47 @@ async function runAgentTurn(db, nodeId, messages, events = {}, abortSignal, loca
|
|
|
559624
559685
|
return { proposalId: proposal.id, status: "pending", message: rationale };
|
|
559625
559686
|
}
|
|
559626
559687
|
}),
|
|
559688
|
+
// v0.39 复习会话收束工具(仅 kind=review 线程注册):AI 评定 quality 1~5 喂 SM-2 排期。
|
|
559689
|
+
// 纪律(srs:record Phase D 同口径):只写 SRS 排期 + XP + streak,不写 BKT 掌握度;
|
|
559690
|
+
// 掌握度只由客观答题观测(quiz/exercise/record_answer)驱动。
|
|
559691
|
+
...reviewMode ? {
|
|
559692
|
+
[REVIEW_END_TOOL_NAME]: tool({
|
|
559693
|
+
description: "\u6536\u675F\u672C\u6B21\u590D\u4E60\u4F1A\u8BDD:\u6309\u6807\u5C3A\u8BC4\u5B9A\u672C\u6B21\u590D\u4E60\u8D28\u91CF,\u7CFB\u7EDF\u4F1A\u636E\u6B64\u5B89\u6392\u4E0B\u6B21\u590D\u4E60\u65F6\u95F4(SM-2)\u3002\u6BCF\u573A\u4F1A\u8BDD\u53EA\u80FD\u8C03\u7528\u4E00\u6B21,\u6536\u675F\u540E\u6B63\u5E38\u9053\u522B\u5373\u53EF\u3002",
|
|
559694
|
+
inputSchema: external_exports2.object({
|
|
559695
|
+
quality: external_exports2.union([external_exports2.literal(1), external_exports2.literal(2), external_exports2.literal(3), external_exports2.literal(4), external_exports2.literal(5)]).describe("\u672C\u6B21\u590D\u4E60\u8D28\u91CF\u6807\u5C3A:1=\u51E0\u4E4E\u4E0D\u8BB0\u5F97/2=\u591A\u6570\u5FD8\u4E86/3=\u52C9\u5F3A\u60F3\u8D77/4=\u8BB0\u5F97/5=\u5F88\u719F"),
|
|
559696
|
+
summary: external_exports2.string().describe("\u4E00\u4E24\u53E5\u6982\u62EC\u672C\u6B21\u590D\u4E60\u8868\u73B0(\u4F1A\u5C55\u793A\u7ED9\u5B66\u4E60\u8005)"),
|
|
559697
|
+
weakPoints: external_exports2.array(external_exports2.string()).optional().describe("\u4E0B\u6B21\u590D\u4E60\u8981\u91CD\u70B9\u8003\u5BDF\u7684\u8584\u5F31\u70B9(\u6982\u5FF5\u540D\u5217\u8868)")
|
|
559698
|
+
}),
|
|
559699
|
+
execute: async (input) => {
|
|
559700
|
+
const { quality, summary, weakPoints } = input;
|
|
559701
|
+
if (++endReviewCalls > 1) {
|
|
559702
|
+
return { status: "rejected", message: "\u672C\u56DE\u5408\u5DF2\u6536\u675F\u8FC7,\u4E0D\u8981\u91CD\u590D\u8C03\u7528 end_review_session\u3002" };
|
|
559703
|
+
}
|
|
559704
|
+
if (opts?.reviewAlreadyEnded) {
|
|
559705
|
+
return { status: "rejected", message: "\u672C\u4F1A\u8BDD\u5DF2\u6536\u675F\u8FC7,\u4E0D\u80FD\u518D\u8C03\u7528 end_review_session\u3002" };
|
|
559706
|
+
}
|
|
559707
|
+
events.onToolCall?.(REVIEW_END_TOOL_NAME, { quality });
|
|
559708
|
+
const result = recordReview(nodeId, quality);
|
|
559709
|
+
const xpKind = reviewXpKindForQuality(quality);
|
|
559710
|
+
if (xpKind === "correct")
|
|
559711
|
+
addXpCorrect(db);
|
|
559712
|
+
else if (xpKind === "wrong")
|
|
559713
|
+
addXpWrong(db);
|
|
559714
|
+
else
|
|
559715
|
+
emitStateChange("xp");
|
|
559716
|
+
touchStreakToday();
|
|
559717
|
+
return {
|
|
559718
|
+
status: "ended",
|
|
559719
|
+
quality,
|
|
559720
|
+
summary,
|
|
559721
|
+
weakPoints: weakPoints ?? [],
|
|
559722
|
+
intervalDays: result.intervalDays,
|
|
559723
|
+
nextDueAt: result.dueAt,
|
|
559724
|
+
message: `\u590D\u4E60\u5DF2\u6536\u675F:\u8D28\u91CF ${quality}/5,\u4E0B\u6B21\u590D\u4E60\u7EA6 ${result.intervalDays} \u5929\u540E\u3002`
|
|
559725
|
+
};
|
|
559726
|
+
}
|
|
559727
|
+
})
|
|
559728
|
+
} : {},
|
|
559627
559729
|
update_learner_profile: tool({
|
|
559628
559730
|
description: "\u63D0\u8BAE\u66F4\u65B0\u5B66\u4E60\u8005\u753B\u50CF\uFF08\u79F0\u547C/MBTI/\u6559\u5B66\u98CE\u683C\u504F\u597D/\u5174\u8DA3\u70B9\uFF09\u3002\u751F\u6210 Proposal \u7B49\u4EBA\u786E\u8BA4\uFF08\u4EBA\u53EF\u4EE5\u62D2\u7EDD\uFF09\u3002\u63D0\u8BAE\u4E0D\u4F1A\u6253\u65AD\u5BF9\u8BDD\u2014\u2014\u5B83\u4F1A\u51FA\u73B0\u5728\u5B66\u4E60\u8005\u7684\u300C\u4E2A\u4EBA\u8D44\u6599\u300D\u7A97\u53E3\u91CC\uFF0C\u7531\u5B66\u4E60\u8005\u5728\u5176\u4E2D\u91C7\u7EB3\u6216\u5FFD\u7565\uFF1B\u53EA\u6709\u5F53\u4F60\u89C2\u5BDF\u5230\u4E0E\u73B0\u6709\u753B\u50CF\u4E0D\u7B26\u7684\u5B66\u4E60\u6A21\u5F0F\u3001\u4E14\u8BC1\u636E\u51FA\u73B0\u4E86\u81F3\u5C11 2 \u6B21\u65F6\u624D\u8C03\u7528\uFF0C\u5E76\u5728\u5B66\u4E60\u8005\u5B8C\u6210\u7B54\u9898/\u8282\u70B9\u6536\u5C3E\u7B49\u81EA\u7136\u505C\u987F\u5904\u53D1\u8D77\uFF0C\u4E0D\u8981\u5728\u8BB2\u89E3\u4E2D\u9014\u6253\u65AD\uFF1B\u63D0\u8BAE\u88AB\u5FFD\u7565\u540E\u4E0D\u8981\u5728\u540C\u4E00\u95EE\u9898\u4E0A\u91CD\u590D\u7EA0\u7F20\u3002",
|
|
559629
559731
|
inputSchema: external_exports2.object({
|
|
@@ -559993,7 +560095,7 @@ ${learnerSnapshot}` : ""}`
|
|
|
559993
560095
|
const result = streamText({
|
|
559994
560096
|
model: chatModel,
|
|
559995
560097
|
...providerOptions ? { providerOptions } : {},
|
|
559996
|
-
system: `${
|
|
560098
|
+
system: `${systemPrompt}
|
|
559997
560099
|
|
|
559998
560100
|
${nodeContext}${learnerSnapshot ? `
|
|
559999
560101
|
|
|
@@ -560221,6 +560323,8 @@ ${s}` : s;
|
|
|
560221
560323
|
);
|
|
560222
560324
|
const threadRow = db.select().from(threads).where(eq(threads.id, threadId)).get();
|
|
560223
560325
|
const focusNodeId = threadRow?.focusNodeId ?? threadId;
|
|
560326
|
+
const reviewMode = threadRow?.kind === "review";
|
|
560327
|
+
const reviewAlreadyEnded = reviewMode && reviewRoundState(rawMsgs) === "ended";
|
|
560224
560328
|
const ctrlKey = `thread:${threadId}`;
|
|
560225
560329
|
if (abortControllers.has(ctrlKey)) {
|
|
560226
560330
|
throw new Error("\u8BE5\u5BF9\u8BDD\u6B63\u5728\u56DE\u590D\u4E2D\uFF0C\u8BF7\u5148\u505C\u6B62\u6216\u7B49\u5F85\u672C\u8F6E\u7ED3\u675F");
|
|
@@ -560245,7 +560349,8 @@ ${s}` : s;
|
|
|
560245
560349
|
},
|
|
560246
560350
|
controller.signal,
|
|
560247
560351
|
locale,
|
|
560248
|
-
imageAtts.map((a) => ({ mediaType: a.mime, base64: a.data }))
|
|
560352
|
+
imageAtts.map((a) => ({ mediaType: a.mime, base64: a.data })),
|
|
560353
|
+
{ reviewMode, reviewAlreadyEnded }
|
|
560249
560354
|
);
|
|
560250
560355
|
} finally {
|
|
560251
560356
|
abortControllers.delete(ctrlKey);
|
|
@@ -560284,8 +560389,8 @@ init_llm_client();
|
|
|
560284
560389
|
init_llm_presets();
|
|
560285
560390
|
init_model_catalog();
|
|
560286
560391
|
init_custom_provider_service();
|
|
560287
|
-
function getContextUsage(db, nodeId, locale) {
|
|
560288
|
-
const blocks = assembleContextBlocks(db, nodeId, locale);
|
|
560392
|
+
function getContextUsage(db, nodeId, locale, reviewMode) {
|
|
560393
|
+
const blocks = assembleContextBlocks(db, nodeId, locale, { reviewMode });
|
|
560289
560394
|
if (!blocks.node)
|
|
560290
560395
|
return null;
|
|
560291
560396
|
const settings2 = readSettingsMap(db);
|
|
@@ -562371,11 +562476,20 @@ function registerSrsHandlers() {
|
|
|
562371
562476
|
handle(
|
|
562372
562477
|
"srs:record",
|
|
562373
562478
|
async (_e, nodeId, quality) => {
|
|
562374
|
-
recordReview(nodeId, quality);
|
|
562479
|
+
const result = recordReview(nodeId, quality);
|
|
562375
562480
|
if (quality >= 4)
|
|
562376
562481
|
addXpCorrect(getDb());
|
|
562377
562482
|
else if (quality <= 2)
|
|
562378
562483
|
addXpWrong(getDb());
|
|
562484
|
+
else
|
|
562485
|
+
emitStateChange("xp");
|
|
562486
|
+
touchStreakToday();
|
|
562487
|
+
return {
|
|
562488
|
+
ok: true,
|
|
562489
|
+
quality,
|
|
562490
|
+
intervalDays: result.intervalDays,
|
|
562491
|
+
nextDueAt: result.dueAt
|
|
562492
|
+
};
|
|
562379
562493
|
}
|
|
562380
562494
|
);
|
|
562381
562495
|
}
|
|
@@ -562536,8 +562650,8 @@ function registerAgentHandlers(deps) {
|
|
|
562536
562650
|
handle("agent:abortThread", async (_e, threadId) => {
|
|
562537
562651
|
abortAgentChatThread(threadId);
|
|
562538
562652
|
});
|
|
562539
|
-
handle("agent:getContextUsage", async (_e, nodeId, locale) => {
|
|
562540
|
-
return getContextUsage(getDb(), nodeId, locale);
|
|
562653
|
+
handle("agent:getContextUsage", async (_e, nodeId, locale, reviewMode) => {
|
|
562654
|
+
return getContextUsage(getDb(), nodeId, locale, reviewMode);
|
|
562541
562655
|
});
|
|
562542
562656
|
handle("attachment:getDataUrl", async (_e, file2) => {
|
|
562543
562657
|
return readAttachmentDataUrl(file2);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{r,j as h}from"./index-
|
|
1
|
+
import{r,j as h}from"./index-88125dOi.js";import{c as T,u as L,t as D}from"./main-DYCYXJqp.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-
|
|
1
|
+
import{r as s,j as t}from"./index-88125dOi.js";import{c as y,u as v,d as k,L as j,F as N,M as w,G as C,T as M,e as _}from"./main-DYCYXJqp.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{u as G,r as v,j as c,o as ie,p as ce,c as le}from"./index-
|
|
1
|
+
import{u as G,r as v,j as c,o as ie,p as ce,c as le}from"./index-88125dOi.js";function A(e,t){return{code:e,message:t}}function me(e,t={}){const n=t.minSide??256,u=t.maxSide??4096,i=t.marginRatio??.02,o=t.alphaThreshold??128,r=t.minBlobAreaRatio??.05,h=t.maxSamples??1e6,l=[],g=(s,p=0,w=0)=>({ok:!1,issues:s.map(([T,C])=>A(T,C)),opaqueRatio:p,blobCount:w}),{width:a,height:m,rgba:b}=e;if(!Number.isFinite(a)||!Number.isFinite(m)||a<=0||m<=0||!Number.isInteger(a)||!Number.isInteger(m))return g([["BAD_DIMENSIONS",`非法尺寸 ${a}x${m}`]]);if(Math.min(a,m)<n&&l.push(A("TOO_SMALL",`短边 ${Math.min(a,m)}px < ${n}px`)),Math.max(a,m)>u&&l.push(A("TOO_LARGE",`长边 ${Math.max(a,m)}px > ${u}px(导入时自动缩放)`)),!b||b.length!==a*m*4)return l.push(A("BAD_PIXEL_BUFFER",`rgba 长度 ${(b==null?void 0:b.length)??0} ≠ ${a}*${m}*4`)),{ok:!1,issues:l,opaqueRatio:0,blobCount:0};const x=Math.max(1,Math.ceil(Math.sqrt(a*m/h))),d=Math.floor((a-1)/x)+1,f=Math.floor((m-1)/x)+1,y=new Uint8Array(d*f);let L=0,M=0,N=255,S=d,R=-1,k=f,Y=-1;for(let s=0;s<f;s++){const p=s*x;for(let w=0;w<d;w++){const T=w*x,C=b[(p*a+T)*4+3];M++,C<N&&(N=C),C>=o&&(y[s*d+w]=1,L++,w<S&&(S=w),w>R&&(R=w),s<k&&(k=s),s>Y&&(Y=s))}}const J=M>0?L/M:0;if(L===0)return l.push(A("ALL_TRANSPARENT","整图无不透明像素(空图/坏抠图)")),{ok:l.length===0,issues:l,opaqueRatio:J,blobCount:0};if(N===255&&l.push(A("NO_ALPHA","未检出任何透明像素——需要透明底 PNG(可一键抠图/豆包抠图)")),S===0||k===0||R===d-1||Y===f-1){const s=a*i,p=m*i;(S*x<s||k*x<p||R*x+x-1>a-1-s||Y*x+x-1>m-1-p)&&l.push(A("EDGE_TOUCH","主体贴边——四周留 5~10% 空白,给跳跃/挤压变换留余地"))}const _=new Uint8Array(d*f),B=[],$=[];for(let s=0;s<y.length;s++){if(!y[s]||_[s])continue;let p=0,w=d,T=-1,C=f,O=-1;for($.push(s),_[s]=1;$.length>0;){const E=$.pop();p++;const P=E%d,X=(E-P)/d;P<w&&(w=P),P>T&&(T=P),X<C&&(C=X),X>O&&(O=X);const D=I=>{y[I]&&!_[I]&&(_[I]=1,$.push(I))};P>0&&D(E-1),P<d-1&&D(E+1),X>0&&D(E-d),X<f-1&&D(E+d)}B.push({area:p,minX:w,maxX:T,minY:C,maxY:O})}const se=B.length>0?Math.max(...B.map(s=>s.area)):0,Z=B.filter(s=>s.area>=se*r),re=(s,p)=>s.minX>=p.minX&&s.maxX<=p.maxX&&s.minY>=p.minY&&s.maxY<=p.maxY,oe=(s,p)=>{const w=Math.min(s.maxX,p.maxX)-Math.max(s.minX,p.minX),T=Math.min(s.maxY,p.maxY)-Math.max(s.minY,p.minY);if(w<=0||T<=0)return 0;const C=w*T,O=(s.maxX-s.minX+1)*(s.maxY-s.minY+1),E=(p.maxX-p.minX+1)*(p.maxY-p.minY+1);return C/Math.min(O,E)},F=Z.filter(s=>!Z.some(p=>p!==s&&p.area>=s.area&&(re(s,p)||oe(s,p)>=.4))).length;return F>=2&&l.push(A("MULTI_BLOB",`检出 ${F} 个独立主体——请裁剪到单角色`)),{ok:l.length===0,issues:l,opaqueRatio:J,blobCount:F}}function de(e){return typeof e.poseHoldMs=="number"?e.poseHoldMs:1200}const ue=""+new URL("alien-idle-D2VKjYsl.png",import.meta.url).href,fe=""+new URL("alien-happy-Ci3JfpxD.png",import.meta.url).href,he=""+new URL("alien-thinking-gWKA2xDz.png",import.meta.url).href,pe=""+new URL("alien-keyL-C_tZriGQ.png",import.meta.url).href,xe=""+new URL("alien-keyL-C_tZriGQ.png",import.meta.url).href,z=""+new URL("alien-head-CS10QxqG.png",import.meta.url).href,be=""+new URL("alien-body-DXq5WJRs.png",import.meta.url).href,j={head:{x:.3,y:.05,w:.4,h:.2726},body:{x:.3,y:.3226,w:.4,h:.2841}},ee={x:.5,y:.3226},ye={formatVersion:1,id:"lab-alien",name:"Lab 小宇航员(Kenney)",author:"Kenney",license:"CC0-1.0 (Kenney Platformer Characters)",tier:"bongo",states:{idle:"idle.png",keyL:"keyl.png",keyR:"keyr.png",happy:"happy.png",thinking:"thinking.png"},poseHoldMs:1100};async function ge(){const e={idle:ue,keyL:pe,keyR:xe,happy:fe,thinking:he},t=await we(z),n=document.createElement("canvas");n.width=512,n.height=512;const u=n.getContext("2d");u.drawImage(t,0,0);const i=u.getImageData(0,0,512,512),o=me({width:512,height:512,rgba:i.data});return{srcs:e,parts:{head:z,body:be},selfSpec:o}}function we(e){return new Promise((t,n)=>{const u=new Image;u.onload=()=>t(u),u.onerror=()=>n(new Error(`image load failed: ${e}`)),u.src=e})}function te(e,t,n){const{x:u,y:i,w:o,h:r,t:h,deform:l}=n,g=n.cols??6,a=n.rows??8,m=n.src??{x:0,y:0,w:t.width,h:t.height},b=[];for(let d=0;d<=a;d++)for(let f=0;f<=g;f++){const y=f/g,L=d/a,M=l(y,L,h);b.push([u+y*o+M.dx,i+L*r+M.dy])}const x=(d,f)=>b[f*(g+1)+d];for(let d=0;d<a;d++)for(let f=0;f<g;f++){const y=x(f,d),L=x(f+1,d),M=x(f,d+1),N=x(f+1,d+1),S=m.x+f/g*m.w,R=m.y+d/a*m.h,k=m.x+(f+1)/g*m.w,Y=m.y+(d+1)/a*m.h;ne(e,t,[S,R],[k,R],[S,Y],y,L,M),ne(e,t,[k,R],[k,Y],[S,Y],L,N,M)}}function ne(e,t,n,u,i,o,r,h){const l=(u[0]-n[0])*(i[1]-n[1])-(i[0]-n[0])*(u[1]-n[1]);if(Math.abs(l)<1e-8)return;const g=((r[0]-o[0])*(i[1]-n[1])-(h[0]-o[0])*(u[1]-n[1]))/l,a=((h[0]-o[0])*(u[0]-n[0])-(r[0]-o[0])*(i[0]-n[0]))/l,m=((r[1]-o[1])*(i[1]-n[1])-(h[1]-o[1])*(u[1]-n[1]))/l,b=((h[1]-o[1])*(u[0]-n[0])-(r[1]-o[1])*(i[0]-n[0]))/l,x=o[0]-g*n[0]-a*n[1],d=o[1]-m*n[0]-b*n[1];e.save(),e.beginPath(),e.moveTo(o[0],o[1]),e.lineTo(r[0],r[1]),e.lineTo(h[0],h[1]),e.closePath(),e.clip(),e.transform(g,m,a,b,x,d),e.drawImage(t,0,0),e.restore()}function K(e){const t=v.useRef(e);t.current=e,v.useEffect(()=>{const n={side:1},u=r=>{if(r.repeat)return;const h=ce(r.code,n.side);n.side=n.side===1?-1:1,t.current(h===1?"keyR":"keyL")},i=r=>t.current(r.detail?"thinking":"idle"),o=ie(r=>t.current(r.kind==="wrong"?"wrong":"happy"));return window.addEventListener("keydown",u,{passive:!0}),window.addEventListener("companion-streaming",i),()=>{window.removeEventListener("keydown",u),window.removeEventListener("companion-streaming",i),o()}},[])}function H(){const[e,t]=v.useState("idle"),n=v.useRef(null),u=v.useCallback((i,o=0)=>{n.current!==null&&window.clearTimeout(n.current),n.current=null,t(i);const r=o>0?o:0;r>0&&i!=="idle"&&(n.current=window.setTimeout(()=>t("idle"),r))},[]);return v.useEffect(()=>()=>{n.current!==null&&window.clearTimeout(n.current)},[]),{pose:e,setTimed:u}}function Q(e,t){t||!e||typeof e.animate!="function"||e.animate([{transform:"translateY(0)"},{transform:"translateY(-12%)"},{transform:"translateY(2%)"},{transform:"translateY(0)"}],{duration:380,easing:"cubic-bezier(0.2, 1.4, 0.4, 1)"})}function V(e,t){t||!e||typeof e.animate!="function"||e.animate([{transform:"rotate(0deg)"},{transform:"rotate(-6deg)"},{transform:"rotate(6deg)"},{transform:"rotate(0deg)"}],{duration:280})}function q(e,t){t||!e||typeof e.animate!="function"||e.animate([{transform:"translateY(0px) scale(1, 1)"},{transform:"translateY(2.5px) scale(1.045, 0.93)",offset:.42},{transform:"translateY(0px) scale(1, 1)"}],{duration:185,easing:"ease-out",composite:"add"})}const W=`
|
|
2
2
|
.cbot { position: relative; display: inline-block; line-height: 0;
|
|
3
3
|
animation: cbot-breath 3.4s ease-in-out infinite; transform-origin: 50% 62%; }
|
|
4
4
|
.cbot img, .cbot canvas { display: block; user-select: none; }
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{r as u,j as t}from"./index-
|
|
1
|
+
import{r as u,j as t}from"./index-88125dOi.js";import{c as I,U as C,u as y,a as L,e as S,X as N,B as M,T as E,h as R}from"./main-DYCYXJqp.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,h as U,j as e,c as ie}from"./index-
|
|
1
|
+
import{r as o,h as U,j as e,c as ie}from"./index-88125dOi.js";import{c as te,u as ce,a as j,n as de,T as z,q as Y,A as q,L as V,r as oe,X as xe}from"./main-DYCYXJqp.js";import{R as G}from"./rotate-ccw-DwFJJCY4.js";/**
|
|
2
2
|
* @license lucide-react v0.468.0 - ISC
|
|
3
3
|
*
|
|
4
4
|
* This source code is licensed under the ISC license.
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["./mermaid.core-
|
|
2
|
-
import{r as o,j as t}from"./index-
|
|
1
|
+
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["./mermaid.core-BlnXIWO2.js","./main-DYCYXJqp.js","./index-88125dOi.js","./index-B7IHDZbN.css","./main-D9IB7N5p.css","./transform-Bd_a5eGM.js","./mermaid-layout-elk.core-BxaTdUpV.js"])))=>i.map(i=>d[i]);
|
|
2
|
+
import{r as o,j as t}from"./index-88125dOi.js";import{c as K,_ as B,u as O,d as H,D as U,X,E as L}from"./main-DYCYXJqp.js";import{M as Y,C as G}from"./CanvasStage-x1i_1KCR.js";/**
|
|
3
3
|
* @license lucide-react v0.468.0 - ISC
|
|
4
4
|
*
|
|
5
5
|
* This source code is licensed under the ISC license.
|
|
6
6
|
* See the LICENSE file in the root directory of this source tree.
|
|
7
7
|
*/const J=K("Workflow",[["rect",{width:"8",height:"8",x:"3",y:"3",rx:"2",key:"by2w9f"}],["path",{d:"M7 11v4a2 2 0 0 0 2 2h4",key:"xkn7yn"}],["rect",{width:"8",height:"8",x:"13",y:"13",rx:"2",key:"1cgmvn"}]]);function Q(e){const i=e.split(`
|
|
8
8
|
`);for(let r=0;r<i.length;r++){const a=i[r]??"",s=a.trim();if(!(!s||s.startsWith("%%")))return/^flowchart-elk\b/i.test(s)?e:/^(flowchart|graph)\b/i.test(s)?(i[r]=a.replace(/^(\s*)(flowchart|graph)\b/i,"$1flowchart-elk"),i.join(`
|
|
9
|
-
`)):e}return e}let p=null;function ee(){return p||(p=B(()=>import("./mermaid.core-CFB6SYUU.js").then(e=>e.bI),__vite__mapDeps([0,1,2,3,4,5]),import.meta.url).then(async e=>{const i=e.default,{default:r}=await B(async()=>{const{default:a}=await import("./mermaid-layout-elk.core-BP9RfmyE.js").then(s=>s.m);return{default:a}},__vite__mapDeps([6,1,2,3,4]),import.meta.url);return i.registerLayoutLoaders(r),i.initialize({startOnLoad:!1,theme:"base",securityLevel:"strict",themeVariables:te(),flowchart:{useMaxWidth:!0,htmlLabels:!0,curve:"basis",nodeSpacing:42,rankSpacing:54,padding:10},sequence:{useMaxWidth:!0,boxMargin:8,noteMargin:8,messageMargin:32}}),i})),p}function te(){const e=(r,a)=>{if(typeof document>"u")return a;const s=getComputedStyle(document.documentElement).getPropertyValue(r).trim();return s?`rgb(${s})`:a};return{background:"transparent",fontFamily:typeof document<"u"&&getComputedStyle(document.body).fontFamily||"ui-sans-serif, system-ui, sans-serif",fontSize:"14px",primaryColor:e("--surface-3-rgb","rgb(42 43 46)"),primaryBorderColor:e("--border-rgb","rgb(37 38 41)"),primaryTextColor:e("--ink-strong-rgb","rgb(250 250 250)"),secondaryColor:e("--surface-2-rgb","rgb(32 33 36)"),secondaryBorderColor:e("--border-faint-rgb","rgb(26 26 29)"),secondaryTextColor:e("--ink-rgb","rgb(245 245 250)"),tertiaryColor:e("--surface-1-rgb","rgb(24 25 27)"),tertiaryBorderColor:e("--border-faint-rgb","rgb(26 26 29)"),tertiaryTextColor:e("--ink-rgb","rgb(245 245 250)"),lineColor:e("--ink-faint-rgb","rgb(117 117 126)"),textColor:e("--ink-rgb","rgb(245 245 250)"),edgeLabelBackground:e("--surface-0-rgb","rgb(12 13 15)"),clusterBkg:e("--surface-1-rgb","rgb(24 25 27)"),clusterBorder:e("--border-faint-rgb","rgb(26 26 29)"),nodeBorder:e("--border-rgb","rgb(37 38 41)"),mainBkg:e("--surface-3-rgb","rgb(42 43 46)"),nodeTextColor:e("--ink-rgb","rgb(245 245 250)"),arrowheadColor:e("--ink-faint-rgb","rgb(117 117 126)"),actorBkg:e("--surface-3-rgb","rgb(42 43 46)"),actorBorder:e("--border-rgb","rgb(37 38 41)"),actorTextColor:e("--ink-strong-rgb","rgb(250 250 250)"),activationBkgColor:e("--surface-3-rgb","rgb(42 43 46)"),activationBorderColor:e("--border-rgb","rgb(37 38 41)"),signalColor:e("--ink-rgb","rgb(245 245 250)"),signalTextColor:e("--ink-rgb","rgb(245 245 250)"),labelBoxBkgColor:e("--surface-2-rgb","rgb(32 33 36)"),labelBoxBorderColor:e("--border-rgb","rgb(37 38 41)"),labelTextColor:e("--ink-rgb","rgb(245 245 250)"),loopTextColor:e("--ink-strong-rgb","rgb(250 250 250)"),noteBkgColor:"rgb(255 200 0 / 0.12)",noteBorderColor:"rgb(255 200 0 / 0.4)",noteTextColor:e("--ink-rgb","rgb(245 245 250)")}}typeof window<"u"&&window.addEventListener("theme-changed",()=>{p=null});async function re(e,i){const r=await ee(),a=Q(i);try{await r.parse(a)}catch(c){throw new Error(`mermaid 语法校验失败: ${c instanceof Error?c.message:String(c)}`)}const{svg:s}=await r.render(e,a);if(s.includes('aria-roledescription="error"')||s.includes('class="error-text"')||s.includes("Syntax error"))throw new Error("mermaid 渲染失败(语法错误或节点 label 含未转义特殊字符)");return s}function ae({title:e,onClose:i,children:r}){const a=O(),s=o.useRef(null);return H(s,!0),o.useEffect(()=>{const c=d=>{d.key==="Escape"&&i()};return window.addEventListener("keydown",c),()=>window.removeEventListener("keydown",c)},[i]),U.createPortal(t.jsxs("div",{className:"fixed inset-0 z-50 flex flex-col bg-black/80","data-testid":"diagram-viewer-modal","data-noswipe":"",role:"dialog","aria-modal":"true","aria-label":e,children:[t.jsxs("div",{className:"flex items-center justify-between gap-3 px-4 py-2.5 shrink-0",onClick:c=>c.stopPropagation(),children:[t.jsx("h3",{className:"text-body font-bold text-white truncate",children:e}),t.jsxs("div",{className:"flex items-center gap-3 shrink-0",children:[t.jsx("span",{className:"text-caption text-white/50 hidden sm:inline",children:a("artifact.viewer.hint")}),t.jsx("button",{onClick:i,"data-testid":"diagram-viewer-close","aria-label":a("action.close"),"data-tooltip":a("action.close"),className:"text-white/70 hover:text-white w-9 h-9 flex items-center justify-center rounded-lg hover:bg-white/10 transition-colors",children:t.jsx(X,{className:"w-5 h-5"})})]})]}),t.jsx("div",{className:"flex-1 min-h-0 px-2 pb-2",onClick:i,children:t.jsx("div",{ref:s,className:"h-full w-full",onClick:c=>c.stopPropagation(),children:r})})]}),document.body)}function z(e){let i=5381;for(let r=0;r<e.length;r++)i=(i<<5)+i+e.charCodeAt(r)>>>0;return i.toString(36)}const v=.3,k=3,x=.2;function I({data:e,variant:i="card"}){const r=e,a=O(),s={flowchart:a("artifact.diagram.flowchart"),sequence:a("artifact.diagram.sequence"),state:a("artifact.diagram.state")},c=o.useId().replace(/[:]/g,"_"),[d,w]=o.useState({status:"loading"}),[u,A]=o.useState(()=>{try{return sessionStorage.getItem(`mmdfix:${r.mermaid.length}:${z(r.mermaid)}`)??r.mermaid}catch{return r.mermaid}}),[j,P]=o.useState(!1),[C,N]=o.useState(!1),[R,$]=o.useState(0);o.useEffect(()=>{const n=()=>$(l=>l+1);return window.addEventListener("theme-changed",n),()=>window.removeEventListener("theme-changed",n)},[]);const[m,M]=o.useState(null),[g,b]=o.useState(1),[F,y]=o.useState(!1);o.useEffect(()=>{let n=!1;return w({status:"loading"}),M(null),re(`mmd-${c}`,u).then(l=>{if(!n&&(w({status:"rendered",svg:l}),u!==r.mermaid))try{sessionStorage.setItem(`mmdfix:${r.mermaid.length}:${z(r.mermaid)}`,u)}catch{}}).catch(l=>{n||(console.error("[MermaidArtifact] render failed:",l),w({status:"error",message:l instanceof Error?l.message:String(l)}))}),()=>{n=!0}},[u,c,R,r.mermaid]),o.useEffect(()=>{var n;d.status!=="error"||j||(P(!0),u===r.mermaid&&(n=window.api)!=null&&n.repairMermaidDiagram&&(N(!0),window.api.repairMermaidDiagram({mermaid:u,errorMessage:d.message,diagramType:r.diagramType}).then(l=>{l.ok&&l.mermaid.trim()&&A(l.mermaid)}).catch(()=>{}).finally(()=>N(!1))))},[d,j,u,r.mermaid,r.diagramType]);const D=`https://mermaid.live/edit#${encodeURIComponent(u)}`,V=o.useCallback(()=>b(n=>Math.min(k,+(n+x).toFixed(2))),[]),W=o.useCallback(()=>b(n=>Math.max(v,+(n-x).toFixed(2))),[]),q=o.useCallback(()=>b(1),[]),Z=o.useCallback(n=>{if(!n.ctrlKey&&!n.metaKey)return;n.preventDefault();const l=n.deltaY>0?-x:x;b(h=>Math.min(k,Math.max(v,+(h+l).toFixed(2))))},[]),E=d.status==="rendered"?t.jsx("div",{ref:n=>{var l;if(n&&!m){const h=n.querySelector("svg");if(h){const S=h.getBoundingClientRect(),f=(l=h.viewBox)==null?void 0:l.baseVal,T=f&&f.width?f.width:S.width,_=f&&f.height?f.height:S.height;T>0&&_>0&&M({width:T,height:_})}}},style:{width:(m==null?void 0:m.width)??void 0,height:(m==null?void 0:m.height)??void 0},dangerouslySetInnerHTML:{__html:d.svg},"data-testid":"mermaid-svg"}):null;return i==="canvas"?t.jsx("div",{"data-testid":"mermaid-canvas-content",children:E}):t.jsxs("div",{className:"surface-card p-4","data-testid":"artifact-mermaid",children:[t.jsxs("div",{className:"flex items-center justify-between mb-3 gap-2",children:[t.jsxs("div",{className:"flex items-center gap-2 flex-1 min-w-0",children:[t.jsx(J,{className:"w-4 h-4 text-ink-muted shrink-0"}),t.jsx("h3",{className:"text-body font-bold text-ink truncate",children:r.title}),t.jsx("span",{className:"text-caption font-bold px-1.5 py-0.5 rounded bg-accent/15 text-accent shrink-0",children:s[r.diagramType]??r.diagramType})]}),t.jsxs("div",{className:"flex items-center gap-1.5 shrink-0",children:[d.status==="rendered"&&t.jsxs("div",{className:"flex items-center gap-1","data-testid":"mermaid-zoom-controls",children:[t.jsx("button",{onClick:W,disabled:g<=v,className:"w-6 h-6 rounded border border-[var(--border)] text-ink-muted hover:bg-surface-1 hover:bg-surface-3 disabled:opacity-30 text-label font-bold flex items-center justify-center",title:a("artifact.zoomOut"),"data-testid":"mermaid-zoom-out",children:"−"}),t.jsxs("button",{onClick:q,className:"px-1.5 h-6 rounded border border-[var(--border)] text-ink-muted hover:bg-surface-1 hover:bg-surface-3 text-caption font-bold tabular-nums",title:a("artifact.zoomReset"),"data-testid":"mermaid-zoom-reset",children:[Math.round(g*100),"%"]}),t.jsx("button",{onClick:V,disabled:g>=k,className:"w-6 h-6 rounded border border-[var(--border)] text-ink-muted hover:bg-surface-1 hover:bg-surface-3 disabled:opacity-30 text-label font-bold flex items-center justify-center",title:a("artifact.zoomIn"),"data-testid":"mermaid-zoom-in",children:"+"})]}),d.status==="rendered"&&t.jsx("button",{onClick:()=>y(!0),"data-testid":"mermaid-expand","aria-label":a("artifact.viewer.open"),"data-tooltip":a("artifact.viewer.open"),className:"w-6 h-6 rounded border border-[var(--border)] text-ink-muted hover:bg-surface-3 flex items-center justify-center",children:t.jsx(Y,{className:"w-3.5 h-3.5"})})]}),t.jsx("button",{onClick:()=>window.open(D,"_blank"),className:"text-caption text-accent hover:underline font-bold shrink-0","data-testid":"mermaid-open-live",title:a("artifact.mermaid.openLive"),children:"mermaid.live ↗"})]}),t.jsxs("div",{onClick:()=>{d.status==="rendered"&&y(!0)},onWheel:Z,className:"bg-surface-0/40 rounded-lg p-3 overflow-auto min-h-[120px] max-h-[500px] select-none",style:{touchAction:"pan-x pan-y"},"data-testid":"mermaid-render-area","data-noswipe":"",children:[d.status==="loading"&&t.jsxs("div",{className:"flex items-center gap-2 text-body text-ink-muted my-8 justify-center","data-testid":"mermaid-loading",children:[t.jsx("span",{className:"typing-dot w-1.5 h-1.5 bg-accent rounded-full inline-block"}),t.jsx("span",{children:a("artifact.mermaid.rendering")})]}),d.status==="rendered"&&t.jsx("div",{style:{width:m?m.width*g:"auto",height:m?m.height*g:"auto",margin:"0 auto"},children:t.jsx("div",{style:{transform:`scale(${g})`,transformOrigin:"top left"},children:E})}),d.status==="error"&&C&&t.jsxs("div",{className:"flex items-center gap-2 text-body text-ink-muted my-8 justify-center","data-testid":"mermaid-repairing",children:[t.jsx("span",{className:"typing-dot w-1.5 h-1.5 bg-accent rounded-full inline-block"}),t.jsx("span",{children:a("artifact.mermaid.repairing")})]}),d.status==="error"&&!C&&t.jsxs("div",{className:"w-full text-center my-4","data-testid":"mermaid-fallback",children:[t.jsxs("div",{className:"text-body text-warning mb-2 flex items-center justify-center gap-1.5",children:[t.jsx(L,{className:"w-4 h-4 shrink-0"}),t.jsx("span",{children:a("artifact.mermaid.renderFailed")})]}),t.jsx("pre",{className:"text-label bg-surface-1/60 rounded p-2 overflow-x-auto text-ink-muted font-mono text-left",children:u}),t.jsx("div",{className:"text-caption text-ink-muted mt-2",children:a("artifact.mermaid.errorPrefix",{msg:d.message})})]})]}),d.status==="rendered"&&t.jsx("div",{className:"mt-1.5 text-caption text-ink-muted flex items-center gap-2",children:t.jsx("span",{children:a("artifact.mermaid.hint")})}),F&&d.status==="rendered"&&t.jsx(ae,{title:r.title,onClose:()=>y(!1),children:t.jsx("div",{className:"h-full w-full rounded-xl overflow-hidden bg-surface-0/60",children:t.jsx(G,{testid:"mermaid-modal-stage",children:t.jsx(I,{data:e,variant:"canvas"})})})}),r.warnings&&r.warnings.length>0&&t.jsxs("div",{className:"mt-2 text-caption text-warning flex items-start gap-1","data-testid":"artifact-warnings",children:[t.jsx(L,{className:"w-3.5 h-3.5 shrink-0 mt-0.5"}),t.jsx("span",{children:r.warnings.join("; ")})]})]})}const oe=Object.freeze(Object.defineProperty({__proto__:null,MermaidArtifact:I},Symbol.toStringTag,{value:"Module"}));export{ae as D,I as M,oe as a};
|
|
9
|
+
`)):e}return e}let p=null;function ee(){return p||(p=B(()=>import("./mermaid.core-BlnXIWO2.js").then(e=>e.bI),__vite__mapDeps([0,1,2,3,4,5]),import.meta.url).then(async e=>{const i=e.default,{default:r}=await B(async()=>{const{default:a}=await import("./mermaid-layout-elk.core-BxaTdUpV.js").then(s=>s.m);return{default:a}},__vite__mapDeps([6,1,2,3,4]),import.meta.url);return i.registerLayoutLoaders(r),i.initialize({startOnLoad:!1,theme:"base",securityLevel:"strict",themeVariables:te(),flowchart:{useMaxWidth:!0,htmlLabels:!0,curve:"basis",nodeSpacing:42,rankSpacing:54,padding:10},sequence:{useMaxWidth:!0,boxMargin:8,noteMargin:8,messageMargin:32}}),i})),p}function te(){const e=(r,a)=>{if(typeof document>"u")return a;const s=getComputedStyle(document.documentElement).getPropertyValue(r).trim();return s?`rgb(${s})`:a};return{background:"transparent",fontFamily:typeof document<"u"&&getComputedStyle(document.body).fontFamily||"ui-sans-serif, system-ui, sans-serif",fontSize:"14px",primaryColor:e("--surface-3-rgb","rgb(42 43 46)"),primaryBorderColor:e("--border-rgb","rgb(37 38 41)"),primaryTextColor:e("--ink-strong-rgb","rgb(250 250 250)"),secondaryColor:e("--surface-2-rgb","rgb(32 33 36)"),secondaryBorderColor:e("--border-faint-rgb","rgb(26 26 29)"),secondaryTextColor:e("--ink-rgb","rgb(245 245 250)"),tertiaryColor:e("--surface-1-rgb","rgb(24 25 27)"),tertiaryBorderColor:e("--border-faint-rgb","rgb(26 26 29)"),tertiaryTextColor:e("--ink-rgb","rgb(245 245 250)"),lineColor:e("--ink-faint-rgb","rgb(117 117 126)"),textColor:e("--ink-rgb","rgb(245 245 250)"),edgeLabelBackground:e("--surface-0-rgb","rgb(12 13 15)"),clusterBkg:e("--surface-1-rgb","rgb(24 25 27)"),clusterBorder:e("--border-faint-rgb","rgb(26 26 29)"),nodeBorder:e("--border-rgb","rgb(37 38 41)"),mainBkg:e("--surface-3-rgb","rgb(42 43 46)"),nodeTextColor:e("--ink-rgb","rgb(245 245 250)"),arrowheadColor:e("--ink-faint-rgb","rgb(117 117 126)"),actorBkg:e("--surface-3-rgb","rgb(42 43 46)"),actorBorder:e("--border-rgb","rgb(37 38 41)"),actorTextColor:e("--ink-strong-rgb","rgb(250 250 250)"),activationBkgColor:e("--surface-3-rgb","rgb(42 43 46)"),activationBorderColor:e("--border-rgb","rgb(37 38 41)"),signalColor:e("--ink-rgb","rgb(245 245 250)"),signalTextColor:e("--ink-rgb","rgb(245 245 250)"),labelBoxBkgColor:e("--surface-2-rgb","rgb(32 33 36)"),labelBoxBorderColor:e("--border-rgb","rgb(37 38 41)"),labelTextColor:e("--ink-rgb","rgb(245 245 250)"),loopTextColor:e("--ink-strong-rgb","rgb(250 250 250)"),noteBkgColor:"rgb(255 200 0 / 0.12)",noteBorderColor:"rgb(255 200 0 / 0.4)",noteTextColor:e("--ink-rgb","rgb(245 245 250)")}}typeof window<"u"&&window.addEventListener("theme-changed",()=>{p=null});async function re(e,i){const r=await ee(),a=Q(i);try{await r.parse(a)}catch(c){throw new Error(`mermaid 语法校验失败: ${c instanceof Error?c.message:String(c)}`)}const{svg:s}=await r.render(e,a);if(s.includes('aria-roledescription="error"')||s.includes('class="error-text"')||s.includes("Syntax error"))throw new Error("mermaid 渲染失败(语法错误或节点 label 含未转义特殊字符)");return s}function ae({title:e,onClose:i,children:r}){const a=O(),s=o.useRef(null);return H(s,!0),o.useEffect(()=>{const c=d=>{d.key==="Escape"&&i()};return window.addEventListener("keydown",c),()=>window.removeEventListener("keydown",c)},[i]),U.createPortal(t.jsxs("div",{className:"fixed inset-0 z-50 flex flex-col bg-black/80","data-testid":"diagram-viewer-modal","data-noswipe":"",role:"dialog","aria-modal":"true","aria-label":e,children:[t.jsxs("div",{className:"flex items-center justify-between gap-3 px-4 py-2.5 shrink-0",onClick:c=>c.stopPropagation(),children:[t.jsx("h3",{className:"text-body font-bold text-white truncate",children:e}),t.jsxs("div",{className:"flex items-center gap-3 shrink-0",children:[t.jsx("span",{className:"text-caption text-white/50 hidden sm:inline",children:a("artifact.viewer.hint")}),t.jsx("button",{onClick:i,"data-testid":"diagram-viewer-close","aria-label":a("action.close"),"data-tooltip":a("action.close"),className:"text-white/70 hover:text-white w-9 h-9 flex items-center justify-center rounded-lg hover:bg-white/10 transition-colors",children:t.jsx(X,{className:"w-5 h-5"})})]})]}),t.jsx("div",{className:"flex-1 min-h-0 px-2 pb-2",onClick:i,children:t.jsx("div",{ref:s,className:"h-full w-full",onClick:c=>c.stopPropagation(),children:r})})]}),document.body)}function z(e){let i=5381;for(let r=0;r<e.length;r++)i=(i<<5)+i+e.charCodeAt(r)>>>0;return i.toString(36)}const v=.3,k=3,x=.2;function I({data:e,variant:i="card"}){const r=e,a=O(),s={flowchart:a("artifact.diagram.flowchart"),sequence:a("artifact.diagram.sequence"),state:a("artifact.diagram.state")},c=o.useId().replace(/[:]/g,"_"),[d,w]=o.useState({status:"loading"}),[u,A]=o.useState(()=>{try{return sessionStorage.getItem(`mmdfix:${r.mermaid.length}:${z(r.mermaid)}`)??r.mermaid}catch{return r.mermaid}}),[j,P]=o.useState(!1),[C,N]=o.useState(!1),[R,$]=o.useState(0);o.useEffect(()=>{const n=()=>$(l=>l+1);return window.addEventListener("theme-changed",n),()=>window.removeEventListener("theme-changed",n)},[]);const[m,M]=o.useState(null),[g,b]=o.useState(1),[F,y]=o.useState(!1);o.useEffect(()=>{let n=!1;return w({status:"loading"}),M(null),re(`mmd-${c}`,u).then(l=>{if(!n&&(w({status:"rendered",svg:l}),u!==r.mermaid))try{sessionStorage.setItem(`mmdfix:${r.mermaid.length}:${z(r.mermaid)}`,u)}catch{}}).catch(l=>{n||(console.error("[MermaidArtifact] render failed:",l),w({status:"error",message:l instanceof Error?l.message:String(l)}))}),()=>{n=!0}},[u,c,R,r.mermaid]),o.useEffect(()=>{var n;d.status!=="error"||j||(P(!0),u===r.mermaid&&(n=window.api)!=null&&n.repairMermaidDiagram&&(N(!0),window.api.repairMermaidDiagram({mermaid:u,errorMessage:d.message,diagramType:r.diagramType}).then(l=>{l.ok&&l.mermaid.trim()&&A(l.mermaid)}).catch(()=>{}).finally(()=>N(!1))))},[d,j,u,r.mermaid,r.diagramType]);const D=`https://mermaid.live/edit#${encodeURIComponent(u)}`,V=o.useCallback(()=>b(n=>Math.min(k,+(n+x).toFixed(2))),[]),W=o.useCallback(()=>b(n=>Math.max(v,+(n-x).toFixed(2))),[]),q=o.useCallback(()=>b(1),[]),Z=o.useCallback(n=>{if(!n.ctrlKey&&!n.metaKey)return;n.preventDefault();const l=n.deltaY>0?-x:x;b(h=>Math.min(k,Math.max(v,+(h+l).toFixed(2))))},[]),E=d.status==="rendered"?t.jsx("div",{ref:n=>{var l;if(n&&!m){const h=n.querySelector("svg");if(h){const S=h.getBoundingClientRect(),f=(l=h.viewBox)==null?void 0:l.baseVal,T=f&&f.width?f.width:S.width,_=f&&f.height?f.height:S.height;T>0&&_>0&&M({width:T,height:_})}}},style:{width:(m==null?void 0:m.width)??void 0,height:(m==null?void 0:m.height)??void 0},dangerouslySetInnerHTML:{__html:d.svg},"data-testid":"mermaid-svg"}):null;return i==="canvas"?t.jsx("div",{"data-testid":"mermaid-canvas-content",children:E}):t.jsxs("div",{className:"surface-card p-4","data-testid":"artifact-mermaid",children:[t.jsxs("div",{className:"flex items-center justify-between mb-3 gap-2",children:[t.jsxs("div",{className:"flex items-center gap-2 flex-1 min-w-0",children:[t.jsx(J,{className:"w-4 h-4 text-ink-muted shrink-0"}),t.jsx("h3",{className:"text-body font-bold text-ink truncate",children:r.title}),t.jsx("span",{className:"text-caption font-bold px-1.5 py-0.5 rounded bg-accent/15 text-accent shrink-0",children:s[r.diagramType]??r.diagramType})]}),t.jsxs("div",{className:"flex items-center gap-1.5 shrink-0",children:[d.status==="rendered"&&t.jsxs("div",{className:"flex items-center gap-1","data-testid":"mermaid-zoom-controls",children:[t.jsx("button",{onClick:W,disabled:g<=v,className:"w-6 h-6 rounded border border-[var(--border)] text-ink-muted hover:bg-surface-1 hover:bg-surface-3 disabled:opacity-30 text-label font-bold flex items-center justify-center",title:a("artifact.zoomOut"),"data-testid":"mermaid-zoom-out",children:"−"}),t.jsxs("button",{onClick:q,className:"px-1.5 h-6 rounded border border-[var(--border)] text-ink-muted hover:bg-surface-1 hover:bg-surface-3 text-caption font-bold tabular-nums",title:a("artifact.zoomReset"),"data-testid":"mermaid-zoom-reset",children:[Math.round(g*100),"%"]}),t.jsx("button",{onClick:V,disabled:g>=k,className:"w-6 h-6 rounded border border-[var(--border)] text-ink-muted hover:bg-surface-1 hover:bg-surface-3 disabled:opacity-30 text-label font-bold flex items-center justify-center",title:a("artifact.zoomIn"),"data-testid":"mermaid-zoom-in",children:"+"})]}),d.status==="rendered"&&t.jsx("button",{onClick:()=>y(!0),"data-testid":"mermaid-expand","aria-label":a("artifact.viewer.open"),"data-tooltip":a("artifact.viewer.open"),className:"w-6 h-6 rounded border border-[var(--border)] text-ink-muted hover:bg-surface-3 flex items-center justify-center",children:t.jsx(Y,{className:"w-3.5 h-3.5"})})]}),t.jsx("button",{onClick:()=>window.open(D,"_blank"),className:"text-caption text-accent hover:underline font-bold shrink-0","data-testid":"mermaid-open-live",title:a("artifact.mermaid.openLive"),children:"mermaid.live ↗"})]}),t.jsxs("div",{onClick:()=>{d.status==="rendered"&&y(!0)},onWheel:Z,className:"bg-surface-0/40 rounded-lg p-3 overflow-auto min-h-[120px] max-h-[500px] select-none",style:{touchAction:"pan-x pan-y"},"data-testid":"mermaid-render-area","data-noswipe":"",children:[d.status==="loading"&&t.jsxs("div",{className:"flex items-center gap-2 text-body text-ink-muted my-8 justify-center","data-testid":"mermaid-loading",children:[t.jsx("span",{className:"typing-dot w-1.5 h-1.5 bg-accent rounded-full inline-block"}),t.jsx("span",{children:a("artifact.mermaid.rendering")})]}),d.status==="rendered"&&t.jsx("div",{style:{width:m?m.width*g:"auto",height:m?m.height*g:"auto",margin:"0 auto"},children:t.jsx("div",{style:{transform:`scale(${g})`,transformOrigin:"top left"},children:E})}),d.status==="error"&&C&&t.jsxs("div",{className:"flex items-center gap-2 text-body text-ink-muted my-8 justify-center","data-testid":"mermaid-repairing",children:[t.jsx("span",{className:"typing-dot w-1.5 h-1.5 bg-accent rounded-full inline-block"}),t.jsx("span",{children:a("artifact.mermaid.repairing")})]}),d.status==="error"&&!C&&t.jsxs("div",{className:"w-full text-center my-4","data-testid":"mermaid-fallback",children:[t.jsxs("div",{className:"text-body text-warning mb-2 flex items-center justify-center gap-1.5",children:[t.jsx(L,{className:"w-4 h-4 shrink-0"}),t.jsx("span",{children:a("artifact.mermaid.renderFailed")})]}),t.jsx("pre",{className:"text-label bg-surface-1/60 rounded p-2 overflow-x-auto text-ink-muted font-mono text-left",children:u}),t.jsx("div",{className:"text-caption text-ink-muted mt-2",children:a("artifact.mermaid.errorPrefix",{msg:d.message})})]})]}),d.status==="rendered"&&t.jsx("div",{className:"mt-1.5 text-caption text-ink-muted flex items-center gap-2",children:t.jsx("span",{children:a("artifact.mermaid.hint")})}),F&&d.status==="rendered"&&t.jsx(ae,{title:r.title,onClose:()=>y(!1),children:t.jsx("div",{className:"h-full w-full rounded-xl overflow-hidden bg-surface-0/60",children:t.jsx(G,{testid:"mermaid-modal-stage",children:t.jsx(I,{data:e,variant:"canvas"})})})}),r.warnings&&r.warnings.length>0&&t.jsxs("div",{className:"mt-2 text-caption text-warning flex items-start gap-1","data-testid":"artifact-warnings",children:[t.jsx(L,{className:"w-3.5 h-3.5 shrink-0 mt-0.5"}),t.jsx("span",{children:r.warnings.join("; ")})]})]})}const oe=Object.freeze(Object.defineProperty({__proto__:null,MermaidArtifact:I},Symbol.toStringTag,{value:"Module"}));export{ae as D,I as M,oe as a};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{r,j as e}from"./index-
|
|
1
|
+
import{r,j as e}from"./index-88125dOi.js";import{c as ee,u as R,X as G,r as V,a as u,W as z,C as B,b as H,n as J,d as te,e as se,t as ae,v as ne}from"./main-DYCYXJqp.js";import{T as X,C as Y}from"./Toggle-Dc2HPsMk.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 n,j as e}from"./index-
|
|
1
|
+
import{r as n,j as e}from"./index-88125dOi.js";import{c as L,u as I,i as T,d as G,j as F,a as c,k as H,X as q,l as K,P as O,L as V,A as X,C as J,m as Q,n as U,o as W,s as Y,p as Z}from"./main-DYCYXJqp.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{r as a,j as e,c as S}from"./index-
|
|
1
|
+
import{r as a,j as e,c as S}from"./index-88125dOi.js";import{u as j,a as N,S as M}from"./main-DYCYXJqp.js";function A({tree:c,onReviewNode:d,progressMap:o}){const s=j(),[l,f]=a.useState([]),[b,h]=a.useState(!0),[n,x]=a.useState(null);a.useEffect(()=>{N.getAllSrsItems().then(t=>f(t)).catch(()=>f([])).finally(()=>h(!1))},[]);const p=a.useMemo(()=>new Map(c.map(t=>[t.id,t])),[c]),g=a.useMemo(()=>new Set(l.filter(t=>t.overdue).map(t=>t.nodeId)),[l]),i=a.useMemo(()=>{const t=c.filter(u=>{var y;const m=(y=o[u.id])==null?void 0:y.status;return u.type==="lesson"&&(m==="in_progress"||m==="mastered")}),r=new Map;for(const u of t){const m=u.parentId??"(root)";r.has(m)||r.set(m,[]),r.get(m).push(u)}return r},[c,o]),w=a.useMemo(()=>Array.from(i.values()).flat().filter(t=>g.has(t.id)).length,[i,g]),v=a.useMemo(()=>Array.from(i.values()).flat(),[i]);if(a.useEffect(()=>{if(i.size>0&&(!n||!i.has(n))){const t=i.keys().next().value;t&&x(t)}},[i,n]),b)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(v.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 r;return((r=p.get(t))==null?void 0:r.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")}),w>0&&e.jsxs("span",{className:"text-label font-bold text-review","data-testid":"review-due-count",children:[w," ",s("review.due.count")]})]}),e.jsxs("button",{onClick:()=>{const t=v[Math.floor(Math.random()*v.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,r])=>e.jsxs("button",{onClick:()=>x(t),className:`px-2.5 py-1 rounded-full text-label font-bold transition-colors ${n===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:["(",r.length,")"]})]},t))}),n&&i.has(n)&&e.jsx("div",{className:"space-y-1.5","data-testid":"review-lesson-list",children:i.get(n).map(t=>{const r=g.has(t.id);return e.jsxs("div",{className:`flex items-center justify-between gap-2 p-2.5 rounded-lg transition-colors ${r?"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:[r&&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 o=a.useRef(null),s=j(),[l,f]=a.useState(!1),[b,h]=a.useState(!1),n=async x=>{if(!(l||b)){f(!0);try{await N.recordReview(c,x),h(!0),d==null||d(),S(x>=4?"correct":"wrong",{origin:x>=4&&o.current?(()=>{const p=o.current.getBoundingClientRect();return{x:p.right-48,y:p.top+24}})():void 0})}catch{}finally{f(!1)}}};return b?e.jsx("div",{className:"text-center text-body text-brand py-2","data-testid":"self-rated",children:s("review.selfrated")}):e.jsxs("div",{ref:o,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:s("review.selfrate.title")}),e.jsxs("div",{className:"grid grid-cols-3 gap-2",children:[e.jsxs("button",{onClick:()=>n(1),disabled:l,"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:s("review.selfrate.again")}),e.jsx("span",{className:"text-caption opacity-70",children:s("review.selfrate.again.hint")})]}),e.jsxs("button",{onClick:()=>n(4),disabled:l,"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:s("review.selfrate.remembered")}),e.jsx("span",{className:"text-caption opacity-70",children:s("review.selfrate.remembered.hint")})]}),e.jsxs("button",{onClick:()=>n(5),disabled:l,"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:s("review.selfrate.mastered")}),e.jsx("span",{className:"text-caption opacity-70",children:s("review.selfrate.mastered.hint")})]})]})]})}export{A as ReviewPanel,E as SelfRatingCard};
|