luckytri 1.0.6 → 1.0.7

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 (155) hide show
  1. package/LICENSE +21 -21
  2. package/docs/en/CHANGELOG.md +25 -16
  3. package/docs/en/chat-style.md +28 -9
  4. package/docs/en/guide.md +5 -5
  5. package/docs/en/her-life.md +2 -2
  6. package/docs/en/webui.md +1 -1
  7. package/docs/zh/CHANGELOG.md +25 -16
  8. package/docs/zh/chat-style.md +30 -9
  9. package/docs/zh/guide.md +5 -5
  10. package/docs/zh/her-life.md +2 -2
  11. package/docs/zh/webui.md +1 -1
  12. package/package.json +1 -1
  13. package/public/app/assets/{ChatsPage-DCYMkJ91.js → ChatsPage-CshdtTzV.js} +2 -2
  14. package/public/app/assets/ChatsPage-DfyPCS9N.css +1 -0
  15. package/public/app/assets/{Empty-CLyZkxR5.js → Empty-C7yzOBzy.js} +1 -1
  16. package/public/app/assets/{Empty-DIobYG3x.css → Empty-DmUB2-Bk.css} +1 -1
  17. package/public/app/assets/{Field-BpaRwLI_.js → Field-BjFv4Rfn.js} +1 -1
  18. package/public/app/assets/HeartPage-Bft9wZp5.css +1 -0
  19. package/public/app/assets/{HeartPage-BIOMTiwr.js → HeartPage-eqo6ru16.js} +1 -1
  20. package/public/app/assets/LifePage-BUi5euBF.css +1 -0
  21. package/public/app/assets/{LifePage-BCgM4JkR.js → LifePage-CN8GE5NK.js} +1 -1
  22. package/public/app/assets/{MemoryPage-vShvRqMt.js → MemoryPage-CCpMN4Wg.js} +1 -1
  23. package/public/app/assets/MemoryPage-cZvXfkXb.css +1 -0
  24. package/public/app/assets/{NaturePage-Cy9ptr4G.js → NaturePage-C0JqdBTR.js} +2 -2
  25. package/public/app/assets/NaturePage-CHkpb5NK.css +1 -0
  26. package/public/app/assets/PeoplePage-BTU0H1pM.css +1 -0
  27. package/public/app/assets/{PeoplePage-CUZekB2E.js → PeoplePage-BXGBbO4u.js} +1 -1
  28. package/public/app/assets/{PluginsPage-1RM4rmJP.js → PluginsPage-Dksp5AV5.js} +1 -1
  29. package/public/app/assets/{SystemPage-BI2CB5Ig.css → SystemPage-BenIyTvk.css} +1 -1
  30. package/public/app/assets/{SystemPage-BeT5TmIV.js → SystemPage-Cd7aa8eE.js} +1 -1
  31. package/public/app/assets/TimePage-BOms_n4I.css +1 -0
  32. package/public/app/assets/{TimePage-taTmPMM8.js → TimePage-Bs_zImb4.js} +2 -2
  33. package/public/app/assets/{index-DY5AM0Hz.css → index-BHZcHUMh.css} +1 -1
  34. package/public/app/assets/{index-DdYwC5ZU.js → index-CyRtYxP3.js} +3 -3
  35. package/public/app/assets/{knowledge-DJmfu2KN.js → knowledge-BJOIyuJo.js} +1 -1
  36. package/public/app/assets/{media-BEtnE0Gv.js → media-Bwtx8blz.js} +1 -1
  37. package/public/app/assets/{mind-Dtiw0-QK.js → mind-DtTVrW6Z.js} +1 -1
  38. package/public/app/index.html +5 -6
  39. package/public/guide.en.html +3 -3
  40. package/public/guide.html +3 -3
  41. package/scripts/import-data.js +128 -128
  42. package/scripts/proxy-config.js +167 -167
  43. package/scripts/update-instance.js +201 -201
  44. package/server/channels/adapters.js +27 -27
  45. package/server/channels/onebot/adapter.js +288 -288
  46. package/server/channels/qqbot/adapter.js +253 -253
  47. package/server/channels/qqbot/api.js +199 -199
  48. package/server/channels/qqbot/credentials.js +11 -11
  49. package/server/channels/qqbot/gateway.js +274 -274
  50. package/server/channels/qqbot/index.js +389 -389
  51. package/server/channels/segments.js +40 -40
  52. package/server/channels/session-key.js +153 -153
  53. package/server/channels/state.js +42 -42
  54. package/server/core/api.js +564 -564
  55. package/server/core/context-builder.js +288 -288
  56. package/server/core/context-compactor.js +454 -454
  57. package/server/core/conversation-cues.js +365 -325
  58. package/server/core/conversation-grounding.js +178 -0
  59. package/server/core/conversation-manager.js +87 -87
  60. package/server/core/dialogue-context.js +52 -0
  61. package/server/core/feedback.js +8 -8
  62. package/server/core/group-style.js +72 -72
  63. package/server/core/initiative-context.js +66 -66
  64. package/server/core/input-budget.js +32 -32
  65. package/server/core/local-demo.js +98 -98
  66. package/server/core/message-manager.js +118 -118
  67. package/server/core/message-scheduler.js +78 -78
  68. package/server/core/model-json.js +190 -190
  69. package/server/core/model-presets.js +900 -900
  70. package/server/core/name-call.js +29 -29
  71. package/server/core/network.js +157 -157
  72. package/server/core/person-name.js +22 -22
  73. package/server/core/persona-manager.js +324 -269
  74. package/server/core/reply-delivery.js +472 -404
  75. package/server/core/reply-target-resolver.js +50 -50
  76. package/server/core/response-generator.js +58 -50
  77. package/server/core/response-validator.js +30 -27
  78. package/server/core/retired-prompts.js +51 -51
  79. package/server/core/sessions.js +109 -109
  80. package/server/core/speaker-names.js +92 -92
  81. package/server/core/topic-tracker.js +65 -65
  82. package/server/core/turn.js +42 -8
  83. package/server/http.js +18 -18
  84. package/server/i18n/decisions.js +209 -209
  85. package/server/i18n/index.js +144 -144
  86. package/server/i18n/labels.js +0 -5
  87. package/server/i18n/models.js +111 -111
  88. package/server/knowledge/api.js +342 -342
  89. package/server/knowledge/embedding-profile.js +114 -114
  90. package/server/knowledge/index.js +13 -13
  91. package/server/knowledge/retrieval.js +93 -93
  92. package/server/knowledge/schema.js +158 -158
  93. package/server/knowledge/vector-index.js +90 -90
  94. package/server/mind/affect.js +265 -265
  95. package/server/mind/attention.js +200 -200
  96. package/server/mind/bonds.js +565 -565
  97. package/server/mind/clock.js +83 -83
  98. package/server/mind/context-selection.js +16 -4
  99. package/server/mind/continuity.js +562 -562
  100. package/server/mind/conversation-origin.js +175 -175
  101. package/server/mind/days.js +210 -210
  102. package/server/mind/evidence-read.js +45 -45
  103. package/server/mind/faces.js +373 -373
  104. package/server/mind/guard.js +68 -60
  105. package/server/mind/initiative.js +338 -338
  106. package/server/mind/life/activities.js +21 -21
  107. package/server/mind/life/context.js +330 -330
  108. package/server/mind/life/growth.js +261 -261
  109. package/server/mind/life/presence.js +305 -305
  110. package/server/mind/meetings.js +1069 -1069
  111. package/server/mind/memory-policy.js +48 -48
  112. package/server/mind/memory.js +888 -888
  113. package/server/mind/nature.js +358 -358
  114. package/server/mind/novelty.js +19 -19
  115. package/server/mind/periods.js +118 -118
  116. package/server/mind/reading.js +120 -120
  117. package/server/mind/relationship-context.js +71 -71
  118. package/server/mind/relationships.js +390 -390
  119. package/server/mind/salience.js +201 -201
  120. package/server/mind/schema.js +567 -567
  121. package/server/mind/self.js +496 -484
  122. package/server/mind/thoughts.js +274 -274
  123. package/server/mind/time/agenda.js +242 -242
  124. package/server/mind/time/api.js +200 -200
  125. package/server/mind/time/attention.js +34 -34
  126. package/server/mind/time/delivery-links.js +130 -130
  127. package/server/mind/time/games.js +7 -3
  128. package/server/mind/time/index.js +3 -0
  129. package/server/mind/time/model-material.js +77 -77
  130. package/server/mind/time/presentation.js +35 -51
  131. package/server/mind/time/schedule.js +83 -83
  132. package/server/mind/time/schema.js +84 -84
  133. package/server/mind/time/search.js +383 -383
  134. package/server/mind/time/sharing.js +472 -472
  135. package/server/mind/time/task-links.js +311 -311
  136. package/server/mind/time/works.js +438 -432
  137. package/server/mind/traits.js +191 -191
  138. package/server/mind/view.js +43 -6
  139. package/server/runtime/installation.js +116 -116
  140. package/server/runtime/update-manager.js +140 -140
  141. package/server/storage/data-package.js +298 -298
  142. package/server/storage/data-transfer-api.js +50 -50
  143. package/server/storage/data-transfer-worker.js +18 -18
  144. package/server/storage/data-transfer.js +416 -416
  145. package/server/studio/display-names.js +139 -139
  146. package/server/studio/management.js +102 -102
  147. package/server/studio/updates.js +144 -144
  148. package/server/version.js +10 -10
  149. package/public/app/assets/ChatsPage-CFMVozoG.css +0 -1
  150. package/public/app/assets/HeartPage-C-2jvgzF.css +0 -1
  151. package/public/app/assets/LifePage-CG1OHbRK.css +0 -1
  152. package/public/app/assets/MemoryPage-C_Bu4rfb.css +0 -1
  153. package/public/app/assets/NaturePage-CPZlImT0.css +0 -1
  154. package/public/app/assets/PeoplePage-3RRUITDz.css +0 -1
  155. package/public/app/assets/TimePage-C-guwPk2.css +0 -1
@@ -1 +1 @@
1
- import{$ as e,Ct as t,D as n,E as r,Et as i,I as a,J as o,P as s,Q as c,St as l,Tt as u,U as d,V as f,W as p,X as m,Y as h,Z as g,_,ct as v,dt as y,et as b,gt as x,j as S,n as C,nt as w,o as T,q as E,s as D,t as O,ut as k,v as A,vt as j,wt as M,xt as N,yt as P}from"./Empty-CLyZkxR5.js";import{a as F,f as I,g as L,l as R,n as ee,o as z,r as B,s as V,t as te,u as H,v as U}from"./mind-Dtiw0-QK.js";import{a as W,b as G,c as K,f as q,h as J,l as Y,n as X,o as Z,p as Q,r as ne,v as re,x as ie}from"./index-DdYwC5ZU.js";import{l as ae}from"./knowledge-DJmfu2KN.js";var oe=[`aria-label`],se={class:`encounter-hero`},ce={class:`encounter-copy`},le={class:`eyebrow`},ue={class:`encounter-count`},de={class:`encounter-lens`,"aria-hidden":`true`},fe={class:`orb`},pe={class:`people-heading`},me={class:`encounter-grid`},he=[`data-person`,`aria-label`,`onClick`],ge={class:`avatar-wrap`},_e={class:`avatar`},ve={class:`person-copy`},ye=C(w({__name:`Galaxy`,props:{people:{},activity:{}},emits:[`open`,`list`],setup(n,{emit:r}){let s=n,l=r,d=E(()=>[...s.people].sort((e,t)=>(t.familiarity??0)-(e.familiarity??0))),f=E(()=>d.value.slice(0,12)),h=E(()=>Math.max(0,d.value.length-f.value.length));return(r,s)=>(k(),g(`section`,{class:`galaxy`,"aria-label":t(a)(`相遇之间:TA 认识的人`)},[o(`div`,se,[o(`div`,ce,[o(`span`,le,i(t(a)(`PEOPLE / 相遇之间`)),1),o(`h2`,null,[e(i(t(a)(`每一次相遇,`)),1),s[1]||=o(`br`,null,null,-1),o(`em`,null,i(t(a)(`都留下一点温度。`)),1)]),o(`p`,null,i(t(a)(`越熟悉离 TA 越近。这里先放着最近亲近的 {length} 个人,其他人也仍然在名单里。`,{length:f.value.length})),1),o(`div`,ue,[o(`b`,null,i(n.people.length),1),o(`span`,null,i(t(a)(`个相遇过的人`)),1)])]),o(`div`,de,[s[2]||=c(`<div class="lens-ring ring-a" data-v-5c7b6ec2></div><div class="lens-ring ring-b" data-v-5c7b6ec2></div><span class="lens-dot dot-a" data-v-5c7b6ec2></span><span class="lens-dot dot-b" data-v-5c7b6ec2></span><span class="lens-dot dot-c" data-v-5c7b6ec2></span>`,5),o(`div`,fe,[b(re,{mood:t(ie),activity:n.activity||`idle`,size:100},null,8,[`mood`,`activity`])])])]),o(`div`,pe,[o(`div`,null,[s[3]||=o(`span`,{class:`eyebrow`},`CLOSER TO HER`,-1),o(`h3`,null,i(t(a)(`最近靠近的人`)),1)]),o(`span`,null,i(t(a)(`点开一张光片,看看她记得什么`)),1)]),o(`div`,me,[(k(!0),g(p,null,y(f.value,(e,n)=>(k(),g(`button`,{key:e.userId,type:`button`,class:M([`person-node`,{away:(e.awayDays??0)>=14,tense:e.tension>=.3}]),"data-person":e.userId,style:u({"--hue":t(q)(e.name||e.userId),"--order":n}),"aria-label":`${e.name}:${e.feel||t(a)(`还在慢慢认识`)}`,onClick:t=>l(`open`,e.userId)},[o(`span`,ge,[o(`span`,_e,i(t(Q)(e.name)),1)]),o(`span`,ve,[o(`b`,null,i(e.name),1),o(`small`,null,`QQ `+i(e.userId),1),o(`small`,null,i(e.feel||t(a)(`还在慢慢认识`)),1)]),s[5]||=o(`span`,{class:`person-arrow`,"aria-hidden":`true`},`↗`,-1),o(`span`,{class:`familiarity`,style:u({"--amount":Math.round(Math.max(0,Math.min(1,e.familiarity??0))*100)+`%`}),"aria-hidden":`true`},[...s[4]||=[o(`i`,null,null,-1)]],4)],14,he))),128))]),h.value?(k(),g(`button`,{key:0,type:`button`,class:`more-people`,onClick:s[0]||=e=>l(`list`)},[e(i(t(a)(`在名单里看看另外 {hidden} 个人`,{hidden:h.value}))+` `,1),s[6]||=o(`span`,{"aria-hidden":`true`},`↗`,-1)])):m(``,!0)],8,oe))}}),[[`__scopeId`,`data-v-5c7b6ec2`]]),be=[`width`,`height`],xe=[`stroke-dasharray`,`transform`],Se={x:`22`,y:`25.5`,"text-anchor":`middle`},Ce={key:0},we=C(w({__name:`Ring`,props:{value:{},label:{},caption:{default:``},signed:{type:Boolean,default:!1},size:{default:64}},setup(e){let t=e,n=2*Math.PI*18,r=E(()=>{let e=Number(t.value)||0;return t.signed?Math.max(-1,Math.min(1,e)):Math.max(0,Math.min(1,e))}),a=E(()=>Math.abs(r.value)*n),s=E(()=>r.value<0);return(t,c)=>(k(),g(`figure`,{class:`ring`,style:u({width:e.size+`px`})},[(k(),g(`svg`,{width:e.size,height:e.size,viewBox:`0 0 44 44`,"aria-hidden":`true`},[c[0]||=o(`circle`,{class:`track`,cx:`22`,cy:`22`,r:`18`},null,-1),o(`circle`,{class:M([`arc`,{negative:s.value}]),cx:`22`,cy:`22`,r:`18`,"stroke-dasharray":`${a.value.toFixed(2)} ${n.toFixed(2)}`,transform:s.value?`translate(44 0) scale(-1 1) rotate(-90 22 22)`:`rotate(-90 22 22)`},null,10,xe),o(`text`,Se,i(Math.round(r.value*100)),1)],8,be)),o(`figcaption`,null,[o(`b`,null,i(e.label),1),e.caption?(k(),g(`small`,Ce,i(e.caption),1)):m(``,!0)])],4))}}),[[`__scopeId`,`data-v-a154f165`]]),Te={key:0,class:`error-text`},Ee={key:1,class:`person-sheet stack`},De={class:`who`},Oe={class:`feel`},ke={class:`qq`},Ae={class:`muted`},je={class:`rings`},Me={class:`stack tight`},Ne={class:`row`},Pe={class:`sheet-title`},Fe={key:0},Ie={key:1},Le={class:`list`},Re={class:`faint`},ze={key:0,class:`impression`},Be={key:1,class:`row`},Ve={class:`faint`},He={class:`sheet-title`},Ue={key:0,class:`list`},We=[`data-tone`],Ge={class:`grow`},Ke={class:`faint`},qe={key:0,class:`chip`,"data-tone":`quiet`},Je=[`onClick`],Ye={key:1,class:`muted`},Xe={key:2},Ze={class:`sheet-title`},Qe={class:`list`},$e=[`data-tone`],et={class:`grow`},tt={key:0,class:`faint`},nt={class:`faint`},rt=[`onClick`],it={class:`sheet-title`},at={key:0,class:`list`},ot={class:`faint`},st={key:0,class:`instant`},ct={class:`faint`},lt=[`onClick`],ut=[`onClick`],dt={key:1,class:`muted`},ft={class:`sheet-title`},pt={key:0,class:`list`},mt=[`data-tone`],ht={class:`grow`},gt={class:`faint`},_t=[`onClick`],vt={key:1,class:`muted`},yt=C(w({__name:`PersonSheet`,props:{id:{},now:{}},emits:[`close`,`changed`,`relationship`],setup(e,{emit:s}){let c=e,l=s,d=N(null),f=N(``),v=E(()=>d.value?.person),S=E(()=>{let e=v.value?.firstMetAt;return e?a(`认识 {v} 天`,{v:Math.max(1,Math.round(((c.now||Date.now())-e)/864e5))}):``});async function C(){if(!c.id)return;let e=c.id;d.value?.person?.userId!==e&&(d.value=_(`/mind/people/`+encodeURIComponent(e))||null),f.value=``;try{let t=await L.person(e);c.id===e&&(d.value=t)}catch(t){if(c.id!==e)return;d.value=null,f.value=t.message}}async function w(e){if(await r(a(`撤销这次「{v}」?TA 对这个人的感觉会重新计算。`,{v:B[e.change]||e.change}),{title:a(`撤销一次关系变化`),confirmText:a(`撤销`),danger:!0}))try{await L.revoke(`bond`,e.id),A(a(`已撤销`)),await C(),l(`changed`)}catch(e){A(e.message,!0)}}async function T(e){let t=await n(a(`撤销「{content}」?TA 之后不会再这样认为,整理记忆时也不会把它写回来。可以写下原因(可不填):`,{content:e.content}),{title:a(`撤销这条记忆`),confirmText:a(`撤销`),danger:!0,placeholder:a(`原因`)});if(t!==null)try{await L.revoke(`memory`,e.id,t),A(a(`已撤销`)),await C()}catch(e){A(e.message,!0)}}async function D(e,t){try{await ae(e.id,t),await C()}catch(e){A(e.message,!0)}}async function O(e){if(await r(a(`撤销这次相遇留下的意思?「{meant}」之后不会再回到 TA 心里,也不会再被当成变化的来源。`,{meant:e.meant}),{title:a(`撤销这次相遇`),confirmText:a(`撤销`),danger:!0}))try{await L.revoke(`meeting`,e.id),A(a(`已撤销`)),await C(),l(`changed`)}catch(e){A(e.message,!0)}}async function P(e){let t=await n(a(`撤销「{content}」?TA 不再惦记这件事,之后整理记忆时也不会把它写回来。可以写下原因(可不填):`,{content:e.content}),{title:a(`撤销这个约定`),confirmText:a(`撤销`),danger:!0,placeholder:a(`原因`)});if(t!==null)try{await L.revoke(`anticipation`,e.id,t),A(a(`已撤销`)),await C()}catch(e){A(e.message,!0)}}return x(()=>c.id,e=>{d.value=null,e&&C()},{immediate:!0}),(n,r)=>(k(),h(Z,{open:!!e.id,title:v.value?.name||t(a)(`正在想起…`),eyebrow:t(a)(`TA 认识的人`),width:`560px`,onClose:r[1]||=e=>l(`close`)},{default:j(()=>[f.value?(k(),g(`p`,Te,i(f.value),1)):v.value?(k(),g(`div`,Ee,[o(`header`,De,[o(`span`,{class:`avatar`,style:u({"--hue":t(q)(v.value.name||v.value.userId)})},i(t(Q)(v.value.name)),5),o(`div`,null,[o(`p`,Oe,i(v.value.feel),1),o(`small`,ke,`QQ `+i(v.value.userId),1),o(`small`,Ae,i([S.value,v.value.lastTalkedAt?t(a)(`上次说上话 {v}`,{v:t(Y)(v.value.lastTalkedAt,e.now)}):t(a)(`还没说上过话`),v.value.seenAt?t(a)(`上次见到 {v}`,{v:t(Y)(v.value.seenAt,e.now)}):``].filter(Boolean).join(` · `)),1)])]),o(`div`,je,[(k(!0),g(p,null,y(t(z),([e,t])=>(k(),h(we,{key:e,value:v.value[e],label:t},null,8,[`value`,`label`]))),128))]),o(`section`,Me,[o(`div`,Ne,[o(`h3`,Pe,i(t(a)(`彼此的关系`)),1),o(`button`,{class:`small`,onClick:r[0]||=e=>l(`relationship`,v.value.relationship,v.value.userId)},i(v.value.relationship?t(a)(`修改关系`):t(a)(`绑定关系`)),1)]),v.value.relationship?(k(),g(`p`,Fe,i(t(a)(`对方是我的 {peer},我是对方的 {self}`,{peer:t(I)[v.value.relationship.peerRole]||v.value.relationship.peerRole,self:t(I)[v.value.relationship.selfRole]||v.value.relationship.selfRole})),1)):m(``,!0),d.value.relationshipHistory?.length?(k(),g(`details`,Ie,[o(`summary`,null,i(t(a)(`关系变化记录`)),1),o(`ul`,Le,[(k(!0),g(p,null,y(d.value.relationshipHistory,e=>(k(),g(`li`,{key:e.id},[o(`small`,Re,i(t(U)(e.created))+` · `+i(e.status===`active`?t(a)(`设置关系`):t(a)(`解除关系`)),1),o(`p`,null,i(e.peer_role)+` · `+i(e.note),1)]))),128))])])):m(``,!0)]),v.value.impression?(k(),g(`p`,ze,i(t(a)(`印象:{impression}`,{impression:v.value.impression})),1)):m(``,!0),v.value.places?.length?(k(),g(`div`,Be,[o(`span`,Ve,i(t(a)(`在这些地方见过:`)),1),(k(!0),g(p,null,y(v.value.places,e=>(k(),g(`span`,{key:e.id,class:`chip`,"data-tone":`quiet`},i(e.name),1))),128))])):m(``,!0),o(`section`,null,[o(`h3`,He,i(t(a)(`这份感觉是怎么来的`)),1),d.value.changes.length?(k(),g(`ul`,Ue,[(k(!0),g(p,null,y(d.value.changes,e=>(k(),g(`li`,{key:e.id,class:M([`change`,{done:e.revoked}])},[o(`span`,{class:`chip`,"data-tone":e.revoked?`quiet`:t(F).has(e.change)?`danger`:void 0},i(t(B)[e.change]||e.change),9,We),o(`div`,Ge,[o(`p`,null,i(e.note||t(a)(`没有写原因`)),1),o(`small`,Ke,i(t(a)(`{v} · {v2} · {length} 处来源`,{v:t(U)(e.created),v2:t(H)[e.origin]||t(a)(`写日记时`),length:e.sources.length})),1)]),e.revoked?(k(),g(`span`,qe,i(t(a)(`已撤销`)),1)):(k(),g(`button`,{key:1,class:`text-button`,"data-revoke-change":``,onClick:t=>w(e)},i(t(a)(`撤销`)),9,Je))],2))),128))])):(k(),g(`p`,Ye,i(t(a)(`只是一起聊过天,还没有特别的变化。`)),1))]),d.value.meetings?.length?(k(),g(`section`,Xe,[o(`h3`,Ze,i(t(a)(`和{name}的相遇留下了什么`,{name:v.value.name})),1),o(`ul`,Qe,[(k(!0),g(p,null,y(d.value.meetings,e=>(k(),g(`li`,{key:e.id,class:`change`},[o(`span`,{class:`chip`,"data-tone":e.private?`quiet`:void 0},i(e.private?t(a)(`私下`):e.choice===`silent`?t(a)(`没出声`):t(a)(`出了声`)),9,$e),o(`div`,et,[o(`p`,null,i(e.meant),1),e.why?(k(),g(`small`,tt,i(t(a)(`当时:{why}`,{why:e.why})),1)):m(``,!0),o(`small`,nt,i(e.when)+` · `+i(e.sessionName),1)]),o(`button`,{class:`text-button`,"data-revoke-meeting":``,onClick:t=>O(e)},i(t(a)(`撤销`)),9,rt)]))),128))])])):m(``,!0),o(`section`,null,[o(`h3`,it,i(t(a)(`TA 记得关于{name}的事`,{name:v.value.name})),1),d.value.memories.length?(k(),g(`ul`,at,[(k(!0),g(p,null,y(d.value.memories,e=>(k(),g(`li`,{key:e.id,class:M([`memory-item`,{superseded:e.status===`superseded`}])},[o(`p`,null,i(e.content),1),o(`small`,ot,i(t(a)(`{v} · 在「{v2}」知道的 · {when}`,{v:t(R)[e.status]||e.status,v2:t(J)({name:e.sessionName,id:e.session_id||e.sessionId}),when:e.when})),1),e.status===`confirmed`?(k(),g(`div`,st,[o(`span`,ct,i(t(a)(`改完即生效`)),1),b(K,{"aria-label":t(a)(`分寸:`)+e.content,"model-value":e.discretion||`open`,options:Object.entries(t(V)).map(([e,t])=>({value:e,label:t})),"onUpdate:modelValue":t=>D(e,{discretion:t})},null,8,[`aria-label`,`model-value`,`options`,`onUpdate:modelValue`]),o(`button`,{class:`small`,onClick:t=>D(e,{locked:!e.locked})},i(e.locked?t(a)(`解锁`):t(a)(`锁定`)),9,lt),o(`button`,{class:`small danger`,onClick:t=>T(e)},i(t(a)(`撤销`)),9,ut)])):m(``,!0)],2))),128))])):(k(),g(`p`,dt,i(t(a)(`还没有记住关于这个人的事。`)),1))]),o(`section`,null,[o(`h3`,ft,i(t(a)(`和{name}有关的约定`,{name:v.value.name})),1),d.value.anticipations.length?(k(),g(`ul`,pt,[(k(!0),g(p,null,y(d.value.anticipations,e=>(k(),g(`li`,{key:e.id,class:M([`change`,{done:e.state!==`pending`}])},[o(`span`,{class:`chip`,"data-tone":e.state===`pending`?void 0:`quiet`},i(t(ee)[e.state]||e.state),9,mt),o(`div`,ht,[o(`p`,null,i(e.content),1),o(`small`,gt,i(t(te)[e.kind]||e.kind)+` · `+i(e.when),1)]),e.status===`revoked`?m(``,!0):(k(),g(`button`,{key:0,class:`text-button`,onClick:t=>P(e)},i(t(a)(`撤销`)),9,_t))],2))),128))])):(k(),g(`p`,vt,i(t(a)(`没有和这个人有关的约定。`)),1))])])):m(``,!0)]),_:1},8,[`open`,`title`,`eyebrow`]))}}),[[`__scopeId`,`data-v-eb4a3e1d`]]),bt={class:`faces`},xt={class:`faces-head`},St={class:`eyebrow`},Ct={class:`muted`},wt={class:`face-grid`},Tt={class:`badge`},Et={key:0,class:`qq`},Dt={class:`muted`},Ot={key:0,class:`place-notes compact`},kt={class:`face-excerpt`},At={key:1,class:`muted small-text`},jt=[`onClick`],Mt={key:0,class:`stack`},Nt={key:0,class:`place-notes`},Pt={key:0,class:`muted small-text`},Ft={class:`faint`},It={key:1,class:`muted`},Lt={key:2,class:`versions`},Rt={key:0},zt={key:1},Bt={key:0,class:`change-why`},Vt={key:4,class:`legacy-face`},Ht={class:`face-full`},Ut=[`onClick`],Wt={key:0,class:`muted`},Gt=C(w({__name:`GroupFaces`,props:{groups:{}},emits:[`changed`],setup(n,{emit:c}){let l=n,d=c,f=N(null),h=N({}),_=s({impression:S(`印象`),wish:S(`想做的事`),preference:S(`偏好`),question:S(`还在想的问题`),boundary:S(`相处的分寸`)}),v=s({add:S(`新增`),revise:S(`修改`),remove:S(`放下`)});x(()=>l.groups,e=>{f.value&&=e.find(e=>e.session===f.value.session)||null});async function C(e){if(!(h.value[e]&&h.value[e]?.[0]?.id===l.groups.find(t=>t.session===e)?.face?.id))try{h.value={...h.value,[e]:await L.faces(e)}}catch(e){A(e.message,!0)}}async function w(e,t){if(await r(a(`撤销这次想法更新?会恢复上一次保留的想法。`),{title:a(`撤销想法更新`),confirmText:a(`撤销`),danger:!0}))try{await L.revoke(`face`,t),h.value={...h.value,[e]:await L.faces(e)},A(a(`已撤销`)),d(`changed`)}catch(e){A(e.message,!0)}}return(r,s)=>(k(),g(`section`,bt,[o(`div`,xt,[o(`span`,St,i(t(a)(`在这里的想法`)),1),o(`h2`,null,i(t(a)(`同一个她,在不同的地方留下自己的想法。`)),1),o(`p`,Ct,i(t(a)(`她根据相处留下印象、愿望或疑问,选择什么时候新增、修改或放下。每次更新保留理由和来源。`)),1)]),o(`div`,wt,[(k(!0),g(p,null,y(n.groups,e=>(k(),g(`article`,{key:e.session,class:`card face-card`,style:u({"--hue":t(q)(e.session)})},[o(`header`,null,[o(`span`,Tt,i(e.kind===`private`?t(a)(`私`):t(a)(`群`)),1),o(`div`,null,[o(`h3`,null,i(t(J)({id:e.session,name:e.name,kind:e.kind})),1),e.kind===`private`?(k(),g(`small`,Et,`QQ `+i(String(e.session||``).split(`:`).pop()),1)):m(``,!0),o(`small`,Dt,i(e.kind===`private`?t(a)(`私聊`):t(a)(`群聊`))+i(e.bond?` · ${e.bond.feel}`:``),1)])]),e.face?.notes?.length?(k(),g(`ul`,Ot,[(k(!0),g(p,null,y(e.face.notes.slice(0,3),e=>(k(),g(`li`,{key:e.id},[o(`small`,null,i(t(_)[e.kind]||t(a)(`想法`)),1),o(`p`,kt,i(e.content),1)]))),128))])):(k(),g(`p`,At,i(t(a)(`还没有特别想留在这里的想法,之后由她自己选择。`)),1)),o(`button`,{class:`text-button`,onClick:t=>{f.value=e,C(e.session)}},i(t(a)(`查看想法与变化 ↗`)),9,jt)],4))),128))]),b(Z,{open:!!f.value,title:f.value?.name||t(a)(`在这里的想法`),eyebrow:t(a)(`PLACE NOTES / 在这里的想法`),width:`680px`,onClose:s[0]||=e=>f.value=null},{default:j(()=>[f.value?(k(),g(`div`,Mt,[f.value.face?.notes?.length?(k(),g(`ul`,Nt,[(k(!0),g(p,null,y(f.value.face.notes,e=>(k(),g(`li`,{key:e.id,class:`face-full`},[o(`small`,null,i(t(_)[e.kind]||t(a)(`想法`)),1),o(`p`,null,i(e.content),1),e.why?(k(),g(`p`,Pt,i(e.why),1)):m(``,!0),o(`small`,Ft,i(t(a)(`{n} 处来源`,{n:e.sources?.length||0})),1)]))),128))])):(k(),g(`p`,It,i(t(a)(`还没有特别想留在这里的想法,之后由她自己选择。`)),1)),o(`h3`,null,i(t(a)(`变化历史`)),1),h.value[f.value.session]?(k(),g(`ol`,Lt,[(k(!0),g(p,null,y(h.value[f.value.session],n=>(k(),g(`li`,{key:n.id,class:M({revoked:n.revoked})},[o(`time`,null,i(t(U)(n.created)),1),o(`span`,null,[n.revoked?(k(),g(`b`,Rt,i(t(a)(`已撤销 ·`)),1)):n.origin===`migration`?(k(),g(`b`,zt,i(t(a)(`旧版 ·`)),1)):m(``,!0),n.changes?.length?(k(!0),g(p,{key:2},y(n.changes,(n,r)=>(k(),g(`p`,{key:r},[o(`b`,null,i(t(v)[n.action])+` · `,1),e(i(n.content)+` `,1),n.why?(k(),g(`small`,Bt,i(n.why),1)):m(``,!0)]))),128)):n.notes?.length?(k(),g(p,{key:3},[e(i(n.notes.map(e=>e.content).join(`;`)),1)],64)):(k(),g(`details`,Vt,[o(`summary`,null,i(t(a)(`旧人格记录,仅保留历史`)),1),o(`p`,Ht,i(n.content||[n.role,n.tone,n.aspiration].filter(Boolean).join(`;`)),1)]))]),n.revoked?m(``,!0):(k(),g(`button`,{key:0,class:`text-button`,onClick:e=>w(f.value.session,n.id)},i(t(a)(`撤销`)),9,Ut))],2))),128)),h.value[f.value.session].length?m(``,!0):(k(),g(`li`,Wt,i(t(a)(`没有记录。`)),1))])):m(``,!0)])):m(``,!0)]),_:1},8,[`open`,`title`,`eyebrow`])]))}}),[[`__scopeId`,`data-v-e876a339`]]),Kt={class:`card relationships`},qt={class:`row`},Jt={class:`grow`},Yt={class:`muted`},Xt={key:0,class:`relationship-list`},Zt={class:`grow`},Qt=[`onClick`],$t={class:`chip`},en={class:`muted`},tn={key:0},nn={class:`faint`},rn={class:`row`},an=[`onClick`],on=[`onClick`],sn={key:1,class:`faint`},cn={class:`fields`},$=[`readonly`,`placeholder`],ln=[`placeholder`],un=[`placeholder`],dn={key:0},fn={key:1},pn=[`readonly`],mn=[`placeholder`],hn={class:`faint`},gn=[`disabled`],_n=C(w({__name:`RelationshipsPanel`,emits:[`changed`,`open`],setup(n,{expose:c,emit:l}){let u=l,h=N([]),_=N(!1),x=N(!1),C=N({}),w=s({妹妹:S(`妹妹`),姐姐:S(`姐姐`),弟弟:S(`弟弟`),哥哥:S(`哥哥`),朋友:S(`朋友`),伙伴:S(`伙伴`),custom:S(`其他关系`)}),T=N(`妹妹`);async function E(){h.value=(await L.relationships()).items}v(()=>E().catch(e=>A(e.message,!0)));function D(e,t=``){C.value=e?{...e,expectedId:e.id}:{subjectId:t,channel:`onebot`,accountId:`_`,kind:`human`,name:``,peerRole:`妹妹`,selfRole:``,note:``,discretion:`open`,expectedId:null},T.value=Object.hasOwn(w,C.value.peerRole)?C.value.peerRole:`custom`,_.value=!0}c({edit:D});async function O(){if(!x.value){x.value=!0;try{await L.saveRelationship({...C.value,peerRole:T.value===`custom`?C.value.peerRole:T.value}),_.value=!1,await E(),u(`changed`),A(a(`关系已保存`))}catch(e){A(e.message,!0)}finally{x.value=!1}}}async function M(e){if(await r(a(`解除这份关系?相处留下的记忆和感受仍会保留。`),{title:a(`解除关系`),confirmText:a(`解除`),danger:!0}))try{await L.endRelationship(e.subjectId,{channel:e.channel,accountId:e.accountId,expectedId:e.id}),await E(),u(`changed`)}catch(e){A(e.message,!0)}}return(n,r)=>(k(),g(p,null,[o(`section`,Kt,[o(`header`,qt,[o(`div`,Jt,[r[12]||=o(`span`,{class:`eyebrow`},`RELATIONSHIPS`,-1),o(`h2`,null,i(t(a)(`彼此的关系`)),1)]),o(`button`,{onClick:r[0]||=e=>D()},i(t(a)(`绑定关系`)),1)]),o(`p`,Yt,i(t(a)(`按账号认出人或另一位机器人;关系融入关心、打算与交流,感情仍随着相处生长。`)),1),h.value.length?(k(),g(`div`,Xt,[(k(!0),g(p,null,y(h.value,e=>(k(),g(`article`,{key:e.id,class:`relation`},[o(`div`,Zt,[o(`button`,{class:`text-button`,onClick:t=>u(`open`,e.subjectId)},i(e.name||e.subjectId),9,Qt),o(`span`,$t,i(t(w)[e.peerRole]||e.peerRole),1),o(`small`,en,i(e.kind===`bot`?t(a)(`另一位机器人`):t(a)(`人`))+` · `+i(e.subjectId),1),e.note?(k(),g(`p`,tn,i(e.note),1)):m(``,!0),o(`small`,nn,i(t(U)(e.created))+` · `+i(t(V)[e.discretion]),1)]),o(`div`,rn,[o(`button`,{class:`small`,onClick:t=>D(e)},i(t(a)(`修改`)),9,an),o(`button`,{class:`text-button`,onClick:t=>M(e)},i(t(a)(`解除`)),9,on)])]))),128))])):(k(),g(`p`,sn,i(t(a)(`还没有绑定关系,可以从一个准确的账号开始。`)),1))]),b(Z,{open:_.value,title:t(a)(`绑定关系`),eyebrow:t(a)(`彼此的关系`),width:`560px`,onClose:r[11]||=e=>_.value=!1},{default:j(()=>[o(`form`,{class:`stack`,onSubmit:d(O,[`prevent`])},[o(`div`,cn,[o(`label`,null,[e(i(t(a)(`平台`)),1),b(K,{modelValue:C.value.channel,"onUpdate:modelValue":r[1]||=e=>C.value.channel=e,disabled:!!C.value.id,options:[{value:`onebot`,label:`QQ / OneBot`},{value:`qqbot`,label:t(a)(`QQ 官方机器人`)}]},null,8,[`modelValue`,`disabled`,`options`])]),o(`label`,null,[e(i(t(a)(`对方账号`)),1),P(o(`input`,{"onUpdate:modelValue":r[2]||=e=>C.value.subjectId=e,required:``,readonly:!!C.value.id,maxlength:`128`,placeholder:t(a)(`QQ 号或平台用户 ID`)},null,8,$),[[f,C.value.subjectId]])]),o(`label`,null,[e(i(t(a)(`对象类型`)),1),b(K,{modelValue:C.value.kind,"onUpdate:modelValue":r[3]||=e=>C.value.kind=e,options:[{value:`human`,label:t(a)(`人`)},{value:`bot`,label:t(a)(`另一位机器人`)}]},null,8,[`modelValue`,`options`])]),o(`label`,null,[e(i(t(a)(`对方名字`)),1),P(o(`input`,{"onUpdate:modelValue":r[4]||=e=>C.value.name=e,maxlength:`40`,placeholder:t(a)(`可选,未填写时使用已认识的名字`)},null,8,ln),[[f,C.value.name]])]),o(`label`,null,[e(i(t(a)(`对方是我的`)),1),b(K,{modelValue:T.value,"onUpdate:modelValue":r[5]||=e=>T.value=e,options:Object.entries(t(w)).map(([e,t])=>({value:e,label:t}))},null,8,[`modelValue`,`options`])]),o(`label`,null,[e(i(t(a)(`我是对方的`)),1),P(o(`input`,{"onUpdate:modelValue":r[6]||=e=>C.value.selfRole=e,maxlength:`24`,placeholder:t(a)(`留空时按当前身份生成对应称呼`)},null,8,un),[[f,C.value.selfRole]])])]),T.value===`custom`?(k(),g(`label`,dn,[e(i(t(a)(`关系称呼`)),1),P(o(`input`,{"onUpdate:modelValue":r[7]||=e=>C.value.peerRole=e,required:``,maxlength:`24`},null,512),[[f,C.value.peerRole]])])):m(``,!0),C.value.channel===`qqbot`?(k(),g(`label`,fn,[e(i(t(a)(`应用账号`)),1),P(o(`input`,{"onUpdate:modelValue":r[8]||=e=>C.value.accountId=e,readonly:!!C.value.id,required:``,maxlength:`128`},null,8,pn),[[f,C.value.accountId]])])):m(``,!0),o(`label`,null,[e(i(t(a)(`关系公开范围`)),1),b(K,{modelValue:C.value.discretion,"onUpdate:modelValue":r[9]||=e=>C.value.discretion=e,options:Object.entries(t(V)).map(([e,t])=>({value:e,label:t}))},null,8,[`modelValue`,`options`])]),o(`label`,null,[e(i(t(a)(`这份关系的缘由`)),1),P(o(`textarea`,{"onUpdate:modelValue":r[10]||=e=>C.value.note=e,rows:`3`,maxlength:`300`,placeholder:t(a)(`可选,写下真实的安排或缘由`)},null,8,mn),[[f,C.value.note]])]),o(`p`,hn,i(t(a)(`绑定称呼不会凭空增加相处经历、信任或对方的同意。私下关系只在与对方的私聊中使用。`)),1),o(`button`,{class:`primary`,type:`submit`,disabled:x.value},i(x.value?t(a)(`正在保存…`):t(a)(`保存关系`)),9,gn)],32)]),_:1},8,[`open`,`title`,`eyebrow`])],64))}}),[[`__scopeId`,`data-v-95d2bc8d`]]),vn={class:`page people`},yn={class:`people-bar`},bn=[`placeholder`,`aria-label`],xn={class:`muted`},Sn={key:1,class:`people-list`},Cn=[`data-person`,`onClick`],wn={class:`qq`},Tn={class:`muted`},En={class:`stack tight`},Dn={class:`faint`},On=C(w({__name:`PeoplePage`,setup(e){let n=N(null),r=l(_(`/mind/bonds`)||null),s=N(`galaxy`),c=N(``),d=N(D.sub&&D.sub!==`list`?D.sub:null);D.sub===`list`&&(s.value=`list`);let v=E(()=>{let e=c.value.trim(),t=r.value?.people||[];return e?t.filter(t=>`${t.name}${t.userId}${t.impression||``}`.includes(e)):t}),S=0;async function C(){let e=++S,t=await L.bonds();e===S&&(r.value=t)}function w(e){d.value=e,T(e)}function A(){d.value=null,T(s.value===`list`?`list`:``)}return x(s,e=>{D.page===`people`&&(d.value||T(e===`list`?`list`:``))}),x(()=>[D.page,D.sub],([e,t])=>{e===`people`&&(t===`list`&&(s.value=`list`),d.value=t&&t!==`list`?t:null)}),W(`people`,C),(e,l)=>(k(),g(`div`,vn,[o(`div`,yn,[b(X,{modelValue:s.value,"onUpdate:modelValue":l[0]||=e=>s.value=e,label:t(a)(`人际的视图`),items:[{key:`galaxy`,label:t(a)(`相遇之间`),count:r.value?.people.length??``},{key:`list`,label:t(a)(`列表`)}]},null,8,[`modelValue`,`label`,`items`]),P(o(`input`,{"onUpdate:modelValue":l[1]||=e=>c.value=e,class:`people-search`,type:`search`,placeholder:t(a)(`找一个人`),"aria-label":t(a)(`找一个人`)},null,8,bn),[[f,c.value]]),o(`p`,xn,i(t(a)(`她记得相遇,也记得关系会随着时间改变。`)),1)]),r.value?(k(),g(p,{key:0},[b(_n,{ref_key:`relations`,ref:n,onChanged:C,onOpen:w},null,512),v.value.length?(k(),g(p,{key:0},[s.value===`galaxy`?(k(),h(ye,{key:0,people:v.value,activity:t(G).data?.activity?.kind,onOpen:w,onList:l[2]||=e=>s.value=`list`},null,8,[`people`,`activity`])):(k(),g(`div`,Sn,[(k(!0),g(p,null,y(v.value,e=>(k(),g(`button`,{key:e.userId,class:`card person-card`,"data-person":e.userId,onClick:t=>w(e.userId)},[o(`header`,null,[o(`span`,{class:`avatar`,style:u({"--hue":t(q)(e.name||e.userId)})},i(t(Q)(e.name)),5),o(`div`,null,[o(`h3`,null,i(e.name),1),o(`small`,wn,`QQ `+i(e.userId),1),o(`small`,Tn,i(e.feel),1)])]),o(`div`,En,[(k(!0),g(p,null,y(t(z),([t,n])=>(k(),h(ne,{key:t,label:n,value:e[t],warn:t===`tension`},null,8,[`label`,`value`,`warn`]))),128))]),o(`small`,Dn,i(t(a)(`在 {length} 个地方见过 · 上次说上话 {v}`,{length:e.sessions.length,v:e.lastTalkedAt?t(Y)(e.lastTalkedAt,t(G).data?.now):t(a)(`还没有`)})),1)],8,Cn))),128))]))],64)):(k(),h(O,{key:1,title:t(a)(`TA 还没有认识谁`),text:t(a)(`有人和 TA 说话、TA 细看过群聊之后,这里会出现 TA 对每个人的感觉。`)},null,8,[`title`,`text`])),b(Gt,{groups:r.value.groups,onChanged:C},null,8,[`groups`])],64)):m(``,!0),b(yt,{id:d.value,now:t(G).data?.now,onClose:A,onChanged:C,onRelationship:l[3]||=(e,t)=>{A(),n.value?.edit(e,t)}},null,8,[`id`,`now`])]))}}),[[`__scopeId`,`data-v-b04c8bec`]]);export{On as default};
1
+ import{$ as e,Ct as t,D as n,E as r,Et as i,I as a,J as o,P as s,Q as c,St as l,Tt as u,U as d,V as f,W as p,X as m,Y as h,Z as g,_,ct as v,dt as y,et as b,gt as x,j as S,n as C,nt as w,o as T,q as E,s as D,t as O,ut as k,v as A,vt as j,wt as M,xt as N,yt as P}from"./Empty-C7yzOBzy.js";import{a as F,f as I,g as L,l as R,n as ee,o as z,r as B,s as V,t as te,u as H,v as U}from"./mind-DtTVrW6Z.js";import{a as W,b as G,c as K,f as q,h as J,l as Y,n as X,o as Z,p as Q,r as ne,v as re,x as ie}from"./index-CyRtYxP3.js";import{l as ae}from"./knowledge-BJOIyuJo.js";var oe=[`aria-label`],se={class:`encounter-hero`},ce={class:`encounter-copy`},le={class:`eyebrow`},ue={class:`encounter-count`},de={class:`encounter-lens`,"aria-hidden":`true`},fe={class:`orb`},pe={class:`people-heading`},me={class:`encounter-grid`},he=[`data-person`,`aria-label`,`onClick`],ge={class:`avatar-wrap`},_e={class:`avatar`},ve={class:`person-copy`},ye=C(w({__name:`Galaxy`,props:{people:{},activity:{}},emits:[`open`,`list`],setup(n,{emit:r}){let s=n,l=r,d=E(()=>[...s.people].sort((e,t)=>(t.familiarity??0)-(e.familiarity??0))),f=E(()=>d.value.slice(0,12)),h=E(()=>Math.max(0,d.value.length-f.value.length));return(r,s)=>(k(),g(`section`,{class:`galaxy`,"aria-label":t(a)(`相遇之间:TA 认识的人`)},[o(`div`,se,[o(`div`,ce,[o(`span`,le,i(t(a)(`PEOPLE / 相遇之间`)),1),o(`h2`,null,[e(i(t(a)(`每一次相遇,`)),1),s[1]||=o(`br`,null,null,-1),o(`em`,null,i(t(a)(`都留下一点温度。`)),1)]),o(`p`,null,i(t(a)(`越熟悉离 TA 越近。这里先放着最近亲近的 {length} 个人,其他人也仍然在名单里。`,{length:f.value.length})),1),o(`div`,ue,[o(`b`,null,i(n.people.length),1),o(`span`,null,i(t(a)(`个相遇过的人`)),1)])]),o(`div`,de,[s[2]||=c(`<div class="lens-ring ring-a" data-v-c60042d4></div><div class="lens-ring ring-b" data-v-c60042d4></div><span class="lens-dot dot-a" data-v-c60042d4></span><span class="lens-dot dot-b" data-v-c60042d4></span><span class="lens-dot dot-c" data-v-c60042d4></span>`,5),o(`div`,fe,[b(re,{mood:t(ie),activity:n.activity||`idle`,size:100},null,8,[`mood`,`activity`])])])]),o(`div`,pe,[o(`div`,null,[s[3]||=o(`span`,{class:`eyebrow`},`CLOSER TO HER`,-1),o(`h3`,null,i(t(a)(`最近靠近的人`)),1)]),o(`span`,null,i(t(a)(`点开一张光片,看看她记得什么`)),1)]),o(`div`,me,[(k(!0),g(p,null,y(f.value,(e,n)=>(k(),g(`button`,{key:e.userId,type:`button`,class:M([`person-node`,{away:(e.awayDays??0)>=14,tense:e.tension>=.3}]),"data-person":e.userId,style:u({"--hue":t(q)(e.name||e.userId),"--order":n}),"aria-label":`${e.name}:${e.feel||t(a)(`还在慢慢认识`)}`,onClick:t=>l(`open`,e.userId)},[o(`span`,ge,[o(`span`,_e,i(t(Q)(e.name)),1)]),o(`span`,ve,[o(`b`,null,i(e.name),1),o(`small`,null,`QQ `+i(e.userId),1),o(`small`,null,i(e.feel||t(a)(`还在慢慢认识`)),1)]),s[5]||=o(`span`,{class:`person-arrow`,"aria-hidden":`true`},`↗`,-1),o(`span`,{class:`familiarity`,style:u({"--amount":Math.round(Math.max(0,Math.min(1,e.familiarity??0))*100)+`%`}),"aria-hidden":`true`},[...s[4]||=[o(`i`,null,null,-1)]],4)],14,he))),128))]),h.value?(k(),g(`button`,{key:0,type:`button`,class:`more-people`,onClick:s[0]||=e=>l(`list`)},[e(i(t(a)(`在名单里看看另外 {hidden} 个人`,{hidden:h.value}))+` `,1),s[6]||=o(`span`,{"aria-hidden":`true`},`↗`,-1)])):m(``,!0)],8,oe))}}),[[`__scopeId`,`data-v-c60042d4`]]),be=[`width`,`height`],xe=[`stroke-dasharray`,`transform`],Se={x:`22`,y:`25.5`,"text-anchor":`middle`},Ce={key:0},we=C(w({__name:`Ring`,props:{value:{},label:{},caption:{default:``},signed:{type:Boolean,default:!1},size:{default:64}},setup(e){let t=e,n=2*Math.PI*18,r=E(()=>{let e=Number(t.value)||0;return t.signed?Math.max(-1,Math.min(1,e)):Math.max(0,Math.min(1,e))}),a=E(()=>Math.abs(r.value)*n),s=E(()=>r.value<0);return(t,c)=>(k(),g(`figure`,{class:`ring`,style:u({width:e.size+`px`})},[(k(),g(`svg`,{width:e.size,height:e.size,viewBox:`0 0 44 44`,"aria-hidden":`true`},[c[0]||=o(`circle`,{class:`track`,cx:`22`,cy:`22`,r:`18`},null,-1),o(`circle`,{class:M([`arc`,{negative:s.value}]),cx:`22`,cy:`22`,r:`18`,"stroke-dasharray":`${a.value.toFixed(2)} ${n.toFixed(2)}`,transform:s.value?`translate(44 0) scale(-1 1) rotate(-90 22 22)`:`rotate(-90 22 22)`},null,10,xe),o(`text`,Se,i(Math.round(r.value*100)),1)],8,be)),o(`figcaption`,null,[o(`b`,null,i(e.label),1),e.caption?(k(),g(`small`,Ce,i(e.caption),1)):m(``,!0)])],4))}}),[[`__scopeId`,`data-v-bbca6071`]]),Te={key:0,class:`error-text`},Ee={key:1,class:`person-sheet stack`},De={class:`who`},Oe={class:`feel`},ke={class:`qq`},Ae={class:`muted`},je={class:`rings`},Me={class:`stack tight`},Ne={class:`row`},Pe={class:`sheet-title`},Fe={key:0},Ie={key:1},Le={class:`list`},Re={class:`faint`},ze={key:0,class:`impression`},Be={key:1,class:`row`},Ve={class:`faint`},He={class:`sheet-title`},Ue={key:0,class:`list`},We=[`data-tone`],Ge={class:`grow`},Ke={class:`faint`},qe={key:0,class:`chip`,"data-tone":`quiet`},Je=[`onClick`],Ye={key:1,class:`muted`},Xe={key:2},Ze={class:`sheet-title`},Qe={class:`list`},$e=[`data-tone`],et={class:`grow`},tt={key:0,class:`faint`},nt={class:`faint`},rt=[`onClick`],it={class:`sheet-title`},at={key:0,class:`list`},ot={class:`faint`},st={key:0,class:`instant`},ct={class:`faint`},lt=[`onClick`],ut=[`onClick`],dt={key:1,class:`muted`},ft={class:`sheet-title`},pt={key:0,class:`list`},mt=[`data-tone`],ht={class:`grow`},gt={class:`faint`},_t=[`onClick`],vt={key:1,class:`muted`},yt=C(w({__name:`PersonSheet`,props:{id:{},now:{}},emits:[`close`,`changed`,`relationship`],setup(e,{emit:s}){let c=e,l=s,d=N(null),f=N(``),v=E(()=>d.value?.person),S=E(()=>{let e=v.value?.firstMetAt;return e?a(`认识 {v} 天`,{v:Math.max(1,Math.round(((c.now||Date.now())-e)/864e5))}):``});async function C(){if(!c.id)return;let e=c.id;d.value?.person?.userId!==e&&(d.value=_(`/mind/people/`+encodeURIComponent(e))||null),f.value=``;try{let t=await L.person(e);c.id===e&&(d.value=t)}catch(t){if(c.id!==e)return;d.value=null,f.value=t.message}}async function w(e){if(await r(a(`撤销这次「{v}」?TA 对这个人的感觉会重新计算。`,{v:B[e.change]||e.change}),{title:a(`撤销一次关系变化`),confirmText:a(`撤销`),danger:!0}))try{await L.revoke(`bond`,e.id),A(a(`已撤销`)),await C(),l(`changed`)}catch(e){A(e.message,!0)}}async function T(e){let t=await n(a(`撤销「{content}」?TA 之后不会再这样认为,整理记忆时也不会把它写回来。可以写下原因(可不填):`,{content:e.content}),{title:a(`撤销这条记忆`),confirmText:a(`撤销`),danger:!0,placeholder:a(`原因`)});if(t!==null)try{await L.revoke(`memory`,e.id,t),A(a(`已撤销`)),await C()}catch(e){A(e.message,!0)}}async function D(e,t){try{await ae(e.id,t),await C()}catch(e){A(e.message,!0)}}async function O(e){if(await r(a(`撤销这次相遇留下的意思?「{meant}」之后不会再回到 TA 心里,也不会再被当成变化的来源。`,{meant:e.meant}),{title:a(`撤销这次相遇`),confirmText:a(`撤销`),danger:!0}))try{await L.revoke(`meeting`,e.id),A(a(`已撤销`)),await C(),l(`changed`)}catch(e){A(e.message,!0)}}async function P(e){let t=await n(a(`撤销「{content}」?TA 不再惦记这件事,之后整理记忆时也不会把它写回来。可以写下原因(可不填):`,{content:e.content}),{title:a(`撤销这个约定`),confirmText:a(`撤销`),danger:!0,placeholder:a(`原因`)});if(t!==null)try{await L.revoke(`anticipation`,e.id,t),A(a(`已撤销`)),await C()}catch(e){A(e.message,!0)}}return x(()=>c.id,e=>{d.value=null,e&&C()},{immediate:!0}),(n,r)=>(k(),h(Z,{open:!!e.id,title:v.value?.name||t(a)(`正在想起…`),eyebrow:t(a)(`TA 认识的人`),width:`560px`,onClose:r[1]||=e=>l(`close`)},{default:j(()=>[f.value?(k(),g(`p`,Te,i(f.value),1)):v.value?(k(),g(`div`,Ee,[o(`header`,De,[o(`span`,{class:`avatar`,style:u({"--hue":t(q)(v.value.name||v.value.userId)})},i(t(Q)(v.value.name)),5),o(`div`,null,[o(`p`,Oe,i(v.value.feel),1),o(`small`,ke,`QQ `+i(v.value.userId),1),o(`small`,Ae,i([S.value,v.value.lastTalkedAt?t(a)(`上次说上话 {v}`,{v:t(Y)(v.value.lastTalkedAt,e.now)}):t(a)(`还没说上过话`),v.value.seenAt?t(a)(`上次见到 {v}`,{v:t(Y)(v.value.seenAt,e.now)}):``].filter(Boolean).join(` · `)),1)])]),o(`div`,je,[(k(!0),g(p,null,y(t(z),([e,t])=>(k(),h(we,{key:e,value:v.value[e],label:t},null,8,[`value`,`label`]))),128))]),o(`section`,Me,[o(`div`,Ne,[o(`h3`,Pe,i(t(a)(`彼此的关系`)),1),o(`button`,{class:`small`,onClick:r[0]||=e=>l(`relationship`,v.value.relationship,v.value.userId)},i(v.value.relationship?t(a)(`修改关系`):t(a)(`绑定关系`)),1)]),v.value.relationship?(k(),g(`p`,Fe,i(t(a)(`对方是我的 {peer},我是对方的 {self}`,{peer:t(I)[v.value.relationship.peerRole]||v.value.relationship.peerRole,self:t(I)[v.value.relationship.selfRole]||v.value.relationship.selfRole})),1)):m(``,!0),d.value.relationshipHistory?.length?(k(),g(`details`,Ie,[o(`summary`,null,i(t(a)(`关系变化记录`)),1),o(`ul`,Le,[(k(!0),g(p,null,y(d.value.relationshipHistory,e=>(k(),g(`li`,{key:e.id},[o(`small`,Re,i(t(U)(e.created))+` · `+i(e.status===`active`?t(a)(`设置关系`):t(a)(`解除关系`)),1),o(`p`,null,i(e.peer_role)+` · `+i(e.note),1)]))),128))])])):m(``,!0)]),v.value.impression?(k(),g(`p`,ze,i(t(a)(`印象:{impression}`,{impression:v.value.impression})),1)):m(``,!0),v.value.places?.length?(k(),g(`div`,Be,[o(`span`,Ve,i(t(a)(`在这些地方见过:`)),1),(k(!0),g(p,null,y(v.value.places,e=>(k(),g(`span`,{key:e.id,class:`chip`,"data-tone":`quiet`},i(e.name),1))),128))])):m(``,!0),o(`section`,null,[o(`h3`,He,i(t(a)(`这份感觉是怎么来的`)),1),d.value.changes.length?(k(),g(`ul`,Ue,[(k(!0),g(p,null,y(d.value.changes,e=>(k(),g(`li`,{key:e.id,class:M([`change`,{done:e.revoked}])},[o(`span`,{class:`chip`,"data-tone":e.revoked?`quiet`:t(F).has(e.change)?`danger`:void 0},i(t(B)[e.change]||e.change),9,We),o(`div`,Ge,[o(`p`,null,i(e.note||t(a)(`没有写原因`)),1),o(`small`,Ke,i(t(a)(`{v} · {v2} · {length} 处来源`,{v:t(U)(e.created),v2:t(H)[e.origin]||t(a)(`写日记时`),length:e.sources.length})),1)]),e.revoked?(k(),g(`span`,qe,i(t(a)(`已撤销`)),1)):(k(),g(`button`,{key:1,class:`text-button`,"data-revoke-change":``,onClick:t=>w(e)},i(t(a)(`撤销`)),9,Je))],2))),128))])):(k(),g(`p`,Ye,i(t(a)(`只是一起聊过天,还没有特别的变化。`)),1))]),d.value.meetings?.length?(k(),g(`section`,Xe,[o(`h3`,Ze,i(t(a)(`和{name}的相遇留下了什么`,{name:v.value.name})),1),o(`ul`,Qe,[(k(!0),g(p,null,y(d.value.meetings,e=>(k(),g(`li`,{key:e.id,class:`change`},[o(`span`,{class:`chip`,"data-tone":e.private?`quiet`:void 0},i(e.private?t(a)(`私下`):e.choice===`silent`?t(a)(`没出声`):t(a)(`出了声`)),9,$e),o(`div`,et,[o(`p`,null,i(e.meant),1),e.why?(k(),g(`small`,tt,i(t(a)(`当时:{why}`,{why:e.why})),1)):m(``,!0),o(`small`,nt,i(e.when)+` · `+i(e.sessionName),1)]),o(`button`,{class:`text-button`,"data-revoke-meeting":``,onClick:t=>O(e)},i(t(a)(`撤销`)),9,rt)]))),128))])])):m(``,!0),o(`section`,null,[o(`h3`,it,i(t(a)(`TA 记得关于{name}的事`,{name:v.value.name})),1),d.value.memories.length?(k(),g(`ul`,at,[(k(!0),g(p,null,y(d.value.memories,e=>(k(),g(`li`,{key:e.id,class:M([`memory-item`,{superseded:e.status===`superseded`}])},[o(`p`,null,i(e.content),1),o(`small`,ot,i(t(a)(`{v} · 在「{v2}」知道的 · {when}`,{v:t(R)[e.status]||e.status,v2:t(J)({name:e.sessionName,id:e.session_id||e.sessionId}),when:e.when})),1),e.status===`confirmed`?(k(),g(`div`,st,[o(`span`,ct,i(t(a)(`改完即生效`)),1),b(K,{"aria-label":t(a)(`分寸:`)+e.content,"model-value":e.discretion||`open`,options:Object.entries(t(V)).map(([e,t])=>({value:e,label:t})),"onUpdate:modelValue":t=>D(e,{discretion:t})},null,8,[`aria-label`,`model-value`,`options`,`onUpdate:modelValue`]),o(`button`,{class:`small`,onClick:t=>D(e,{locked:!e.locked})},i(e.locked?t(a)(`解锁`):t(a)(`锁定`)),9,lt),o(`button`,{class:`small danger`,onClick:t=>T(e)},i(t(a)(`撤销`)),9,ut)])):m(``,!0)],2))),128))])):(k(),g(`p`,dt,i(t(a)(`还没有记住关于这个人的事。`)),1))]),o(`section`,null,[o(`h3`,ft,i(t(a)(`和{name}有关的约定`,{name:v.value.name})),1),d.value.anticipations.length?(k(),g(`ul`,pt,[(k(!0),g(p,null,y(d.value.anticipations,e=>(k(),g(`li`,{key:e.id,class:M([`change`,{done:e.state!==`pending`}])},[o(`span`,{class:`chip`,"data-tone":e.state===`pending`?void 0:`quiet`},i(t(ee)[e.state]||e.state),9,mt),o(`div`,ht,[o(`p`,null,i(e.content),1),o(`small`,gt,i(t(te)[e.kind]||e.kind)+` · `+i(e.when),1)]),e.status===`revoked`?m(``,!0):(k(),g(`button`,{key:0,class:`text-button`,onClick:t=>P(e)},i(t(a)(`撤销`)),9,_t))],2))),128))])):(k(),g(`p`,vt,i(t(a)(`没有和这个人有关的约定。`)),1))])])):m(``,!0)]),_:1},8,[`open`,`title`,`eyebrow`]))}}),[[`__scopeId`,`data-v-9ffb5e88`]]),bt={class:`faces`},xt={class:`faces-head`},St={class:`eyebrow`},Ct={class:`muted`},wt={class:`face-grid`},Tt={class:`badge`},Et={key:0,class:`qq`},Dt={class:`muted`},Ot={key:0,class:`place-notes compact`},kt={class:`face-excerpt`},At={key:1,class:`muted small-text`},jt=[`onClick`],Mt={key:0,class:`stack`},Nt={key:0,class:`place-notes`},Pt={key:0,class:`muted small-text`},Ft={class:`faint`},It={key:1,class:`muted`},Lt={key:2,class:`versions`},Rt={key:0},zt={key:1},Bt={key:0,class:`change-why`},Vt={key:4,class:`legacy-face`},Ht={class:`face-full`},Ut=[`onClick`],Wt={key:0,class:`muted`},Gt=C(w({__name:`GroupFaces`,props:{groups:{}},emits:[`changed`],setup(n,{emit:c}){let l=n,d=c,f=N(null),h=N({}),_=s({impression:S(`印象`),wish:S(`想做的事`),preference:S(`偏好`),question:S(`还在想的问题`),boundary:S(`相处的分寸`)}),v=s({add:S(`新增`),revise:S(`修改`),remove:S(`放下`)});x(()=>l.groups,e=>{f.value&&=e.find(e=>e.session===f.value.session)||null});async function C(e){if(!(h.value[e]&&h.value[e]?.[0]?.id===l.groups.find(t=>t.session===e)?.face?.id))try{h.value={...h.value,[e]:await L.faces(e)}}catch(e){A(e.message,!0)}}async function w(e,t){if(await r(a(`撤销这次想法更新?会恢复上一次保留的想法。`),{title:a(`撤销想法更新`),confirmText:a(`撤销`),danger:!0}))try{await L.revoke(`face`,t),h.value={...h.value,[e]:await L.faces(e)},A(a(`已撤销`)),d(`changed`)}catch(e){A(e.message,!0)}}return(r,s)=>(k(),g(`section`,bt,[o(`div`,xt,[o(`span`,St,i(t(a)(`在这里的想法`)),1),o(`h2`,null,i(t(a)(`同一个她,在不同的地方留下自己的想法。`)),1),o(`p`,Ct,i(t(a)(`她根据相处留下印象、愿望或疑问,选择什么时候新增、修改或放下。每次更新保留理由和来源。`)),1)]),o(`div`,wt,[(k(!0),g(p,null,y(n.groups,e=>(k(),g(`article`,{key:e.session,class:`card face-card`,style:u({"--hue":t(q)(e.session)})},[o(`header`,null,[o(`span`,Tt,i(e.kind===`private`?t(a)(`私`):t(a)(`群`)),1),o(`div`,null,[o(`h3`,null,i(t(J)({id:e.session,name:e.name,kind:e.kind})),1),e.kind===`private`?(k(),g(`small`,Et,`QQ `+i(String(e.session||``).split(`:`).pop()),1)):m(``,!0),o(`small`,Dt,i(e.kind===`private`?t(a)(`私聊`):t(a)(`群聊`))+i(e.bond?` · ${e.bond.feel}`:``),1)])]),e.face?.notes?.length?(k(),g(`ul`,Ot,[(k(!0),g(p,null,y(e.face.notes.slice(0,3),e=>(k(),g(`li`,{key:e.id},[o(`small`,null,i(t(_)[e.kind]||t(a)(`想法`)),1),o(`p`,kt,i(e.content),1)]))),128))])):(k(),g(`p`,At,i(t(a)(`还没有特别想留在这里的想法,之后由她自己选择。`)),1)),o(`button`,{class:`text-button`,onClick:t=>{f.value=e,C(e.session)}},i(t(a)(`查看想法与变化 ↗`)),9,jt)],4))),128))]),b(Z,{open:!!f.value,title:f.value?.name||t(a)(`在这里的想法`),eyebrow:t(a)(`PLACE NOTES / 在这里的想法`),width:`680px`,onClose:s[0]||=e=>f.value=null},{default:j(()=>[f.value?(k(),g(`div`,Mt,[f.value.face?.notes?.length?(k(),g(`ul`,Nt,[(k(!0),g(p,null,y(f.value.face.notes,e=>(k(),g(`li`,{key:e.id,class:`face-full`},[o(`small`,null,i(t(_)[e.kind]||t(a)(`想法`)),1),o(`p`,null,i(e.content),1),e.why?(k(),g(`p`,Pt,i(e.why),1)):m(``,!0),o(`small`,Ft,i(t(a)(`{n} 处来源`,{n:e.sources?.length||0})),1)]))),128))])):(k(),g(`p`,It,i(t(a)(`还没有特别想留在这里的想法,之后由她自己选择。`)),1)),o(`h3`,null,i(t(a)(`变化历史`)),1),h.value[f.value.session]?(k(),g(`ol`,Lt,[(k(!0),g(p,null,y(h.value[f.value.session],n=>(k(),g(`li`,{key:n.id,class:M({revoked:n.revoked})},[o(`time`,null,i(t(U)(n.created)),1),o(`span`,null,[n.revoked?(k(),g(`b`,Rt,i(t(a)(`已撤销 ·`)),1)):n.origin===`migration`?(k(),g(`b`,zt,i(t(a)(`旧版 ·`)),1)):m(``,!0),n.changes?.length?(k(!0),g(p,{key:2},y(n.changes,(n,r)=>(k(),g(`p`,{key:r},[o(`b`,null,i(t(v)[n.action])+` · `,1),e(i(n.content)+` `,1),n.why?(k(),g(`small`,Bt,i(n.why),1)):m(``,!0)]))),128)):n.notes?.length?(k(),g(p,{key:3},[e(i(n.notes.map(e=>e.content).join(`;`)),1)],64)):(k(),g(`details`,Vt,[o(`summary`,null,i(t(a)(`旧人格记录,仅保留历史`)),1),o(`p`,Ht,i(n.content||[n.role,n.tone,n.aspiration].filter(Boolean).join(`;`)),1)]))]),n.revoked?m(``,!0):(k(),g(`button`,{key:0,class:`text-button`,onClick:e=>w(f.value.session,n.id)},i(t(a)(`撤销`)),9,Ut))],2))),128)),h.value[f.value.session].length?m(``,!0):(k(),g(`li`,Wt,i(t(a)(`没有记录。`)),1))])):m(``,!0)])):m(``,!0)]),_:1},8,[`open`,`title`,`eyebrow`])]))}}),[[`__scopeId`,`data-v-a6532d0c`]]),Kt={class:`card relationships`},qt={class:`row`},Jt={class:`grow`},Yt={class:`muted`},Xt={key:0,class:`relationship-list`},Zt={class:`grow`},Qt=[`onClick`],$t={class:`chip`},en={class:`muted`},tn={key:0},nn={class:`faint`},rn={class:`row`},an=[`onClick`],on=[`onClick`],sn={key:1,class:`faint`},cn={class:`fields`},$=[`readonly`,`placeholder`],ln=[`placeholder`],un=[`placeholder`],dn={key:0},fn={key:1},pn=[`readonly`],mn=[`placeholder`],hn={class:`faint`},gn=[`disabled`],_n=C(w({__name:`RelationshipsPanel`,emits:[`changed`,`open`],setup(n,{expose:c,emit:l}){let u=l,h=N([]),_=N(!1),x=N(!1),C=N({}),w=s({妹妹:S(`妹妹`),姐姐:S(`姐姐`),弟弟:S(`弟弟`),哥哥:S(`哥哥`),朋友:S(`朋友`),伙伴:S(`伙伴`),custom:S(`其他关系`)}),T=N(`妹妹`);async function E(){h.value=(await L.relationships()).items}v(()=>E().catch(e=>A(e.message,!0)));function D(e,t=``){C.value=e?{...e,expectedId:e.id}:{subjectId:t,channel:`onebot`,accountId:`_`,kind:`human`,name:``,peerRole:`妹妹`,selfRole:``,note:``,discretion:`open`,expectedId:null},T.value=Object.hasOwn(w,C.value.peerRole)?C.value.peerRole:`custom`,_.value=!0}c({edit:D});async function O(){if(!x.value){x.value=!0;try{await L.saveRelationship({...C.value,peerRole:T.value===`custom`?C.value.peerRole:T.value}),_.value=!1,await E(),u(`changed`),A(a(`关系已保存`))}catch(e){A(e.message,!0)}finally{x.value=!1}}}async function M(e){if(await r(a(`解除这份关系?相处留下的记忆和感受仍会保留。`),{title:a(`解除关系`),confirmText:a(`解除`),danger:!0}))try{await L.endRelationship(e.subjectId,{channel:e.channel,accountId:e.accountId,expectedId:e.id}),await E(),u(`changed`)}catch(e){A(e.message,!0)}}return(n,r)=>(k(),g(p,null,[o(`section`,Kt,[o(`header`,qt,[o(`div`,Jt,[r[12]||=o(`span`,{class:`eyebrow`},`RELATIONSHIPS`,-1),o(`h2`,null,i(t(a)(`彼此的关系`)),1)]),o(`button`,{onClick:r[0]||=e=>D()},i(t(a)(`绑定关系`)),1)]),o(`p`,Yt,i(t(a)(`按账号认出人或另一位机器人;关系融入关心、打算与交流,感情仍随着相处生长。`)),1),h.value.length?(k(),g(`div`,Xt,[(k(!0),g(p,null,y(h.value,e=>(k(),g(`article`,{key:e.id,class:`relation`},[o(`div`,Zt,[o(`button`,{class:`text-button`,onClick:t=>u(`open`,e.subjectId)},i(e.name||e.subjectId),9,Qt),o(`span`,$t,i(t(w)[e.peerRole]||e.peerRole),1),o(`small`,en,i(e.kind===`bot`?t(a)(`另一位机器人`):t(a)(`人`))+` · `+i(e.subjectId),1),e.note?(k(),g(`p`,tn,i(e.note),1)):m(``,!0),o(`small`,nn,i(t(U)(e.created))+` · `+i(t(V)[e.discretion]),1)]),o(`div`,rn,[o(`button`,{class:`small`,onClick:t=>D(e)},i(t(a)(`修改`)),9,an),o(`button`,{class:`text-button`,onClick:t=>M(e)},i(t(a)(`解除`)),9,on)])]))),128))])):(k(),g(`p`,sn,i(t(a)(`还没有绑定关系,可以从一个准确的账号开始。`)),1))]),b(Z,{open:_.value,title:t(a)(`绑定关系`),eyebrow:t(a)(`彼此的关系`),width:`560px`,onClose:r[11]||=e=>_.value=!1},{default:j(()=>[o(`form`,{class:`stack`,onSubmit:d(O,[`prevent`])},[o(`div`,cn,[o(`label`,null,[e(i(t(a)(`平台`)),1),b(K,{modelValue:C.value.channel,"onUpdate:modelValue":r[1]||=e=>C.value.channel=e,disabled:!!C.value.id,options:[{value:`onebot`,label:`QQ / OneBot`},{value:`qqbot`,label:t(a)(`QQ 官方机器人`)}]},null,8,[`modelValue`,`disabled`,`options`])]),o(`label`,null,[e(i(t(a)(`对方账号`)),1),P(o(`input`,{"onUpdate:modelValue":r[2]||=e=>C.value.subjectId=e,required:``,readonly:!!C.value.id,maxlength:`128`,placeholder:t(a)(`QQ 号或平台用户 ID`)},null,8,$),[[f,C.value.subjectId]])]),o(`label`,null,[e(i(t(a)(`对象类型`)),1),b(K,{modelValue:C.value.kind,"onUpdate:modelValue":r[3]||=e=>C.value.kind=e,options:[{value:`human`,label:t(a)(`人`)},{value:`bot`,label:t(a)(`另一位机器人`)}]},null,8,[`modelValue`,`options`])]),o(`label`,null,[e(i(t(a)(`对方名字`)),1),P(o(`input`,{"onUpdate:modelValue":r[4]||=e=>C.value.name=e,maxlength:`40`,placeholder:t(a)(`可选,未填写时使用已认识的名字`)},null,8,ln),[[f,C.value.name]])]),o(`label`,null,[e(i(t(a)(`对方是我的`)),1),b(K,{modelValue:T.value,"onUpdate:modelValue":r[5]||=e=>T.value=e,options:Object.entries(t(w)).map(([e,t])=>({value:e,label:t}))},null,8,[`modelValue`,`options`])]),o(`label`,null,[e(i(t(a)(`我是对方的`)),1),P(o(`input`,{"onUpdate:modelValue":r[6]||=e=>C.value.selfRole=e,maxlength:`24`,placeholder:t(a)(`留空时按当前身份生成对应称呼`)},null,8,un),[[f,C.value.selfRole]])])]),T.value===`custom`?(k(),g(`label`,dn,[e(i(t(a)(`关系称呼`)),1),P(o(`input`,{"onUpdate:modelValue":r[7]||=e=>C.value.peerRole=e,required:``,maxlength:`24`},null,512),[[f,C.value.peerRole]])])):m(``,!0),C.value.channel===`qqbot`?(k(),g(`label`,fn,[e(i(t(a)(`应用账号`)),1),P(o(`input`,{"onUpdate:modelValue":r[8]||=e=>C.value.accountId=e,readonly:!!C.value.id,required:``,maxlength:`128`},null,8,pn),[[f,C.value.accountId]])])):m(``,!0),o(`label`,null,[e(i(t(a)(`关系公开范围`)),1),b(K,{modelValue:C.value.discretion,"onUpdate:modelValue":r[9]||=e=>C.value.discretion=e,options:Object.entries(t(V)).map(([e,t])=>({value:e,label:t}))},null,8,[`modelValue`,`options`])]),o(`label`,null,[e(i(t(a)(`这份关系的缘由`)),1),P(o(`textarea`,{"onUpdate:modelValue":r[10]||=e=>C.value.note=e,rows:`3`,maxlength:`300`,placeholder:t(a)(`可选,写下真实的安排或缘由`)},null,8,mn),[[f,C.value.note]])]),o(`p`,hn,i(t(a)(`绑定称呼不会凭空增加相处经历、信任或对方的同意。私下关系只在与对方的私聊中使用。`)),1),o(`button`,{class:`primary`,type:`submit`,disabled:x.value},i(x.value?t(a)(`正在保存…`):t(a)(`保存关系`)),9,gn)],32)]),_:1},8,[`open`,`title`,`eyebrow`])],64))}}),[[`__scopeId`,`data-v-a3d7a181`]]),vn={class:`page people`},yn={class:`people-bar`},bn=[`placeholder`,`aria-label`],xn={class:`muted`},Sn={key:1,class:`people-list`},Cn=[`data-person`,`onClick`],wn={class:`qq`},Tn={class:`muted`},En={class:`stack tight`},Dn={class:`faint`},On=C(w({__name:`PeoplePage`,setup(e){let n=N(null),r=l(_(`/mind/bonds`)||null),s=N(`galaxy`),c=N(``),d=N(D.sub&&D.sub!==`list`?D.sub:null);D.sub===`list`&&(s.value=`list`);let v=E(()=>{let e=c.value.trim(),t=r.value?.people||[];return e?t.filter(t=>`${t.name}${t.userId}${t.impression||``}`.includes(e)):t}),S=0;async function C(){let e=++S,t=await L.bonds();e===S&&(r.value=t)}function w(e){d.value=e,T(e)}function A(){d.value=null,T(s.value===`list`?`list`:``)}return x(s,e=>{D.page===`people`&&(d.value||T(e===`list`?`list`:``))}),x(()=>[D.page,D.sub],([e,t])=>{e===`people`&&(t===`list`&&(s.value=`list`),d.value=t&&t!==`list`?t:null)}),W(`people`,C),(e,l)=>(k(),g(`div`,vn,[o(`div`,yn,[b(X,{modelValue:s.value,"onUpdate:modelValue":l[0]||=e=>s.value=e,label:t(a)(`人际的视图`),items:[{key:`galaxy`,label:t(a)(`相遇之间`),count:r.value?.people.length??``},{key:`list`,label:t(a)(`列表`)}]},null,8,[`modelValue`,`label`,`items`]),P(o(`input`,{"onUpdate:modelValue":l[1]||=e=>c.value=e,class:`people-search`,type:`search`,placeholder:t(a)(`找一个人`),"aria-label":t(a)(`找一个人`)},null,8,bn),[[f,c.value]]),o(`p`,xn,i(t(a)(`她记得相遇,也记得关系会随着时间改变。`)),1)]),r.value?(k(),g(p,{key:0},[b(_n,{ref_key:`relations`,ref:n,onChanged:C,onOpen:w},null,512),v.value.length?(k(),g(p,{key:0},[s.value===`galaxy`?(k(),h(ye,{key:0,people:v.value,activity:t(G).data?.activity?.kind,onOpen:w,onList:l[2]||=e=>s.value=`list`},null,8,[`people`,`activity`])):(k(),g(`div`,Sn,[(k(!0),g(p,null,y(v.value,e=>(k(),g(`button`,{key:e.userId,class:`card person-card`,"data-person":e.userId,onClick:t=>w(e.userId)},[o(`header`,null,[o(`span`,{class:`avatar`,style:u({"--hue":t(q)(e.name||e.userId)})},i(t(Q)(e.name)),5),o(`div`,null,[o(`h3`,null,i(e.name),1),o(`small`,wn,`QQ `+i(e.userId),1),o(`small`,Tn,i(e.feel),1)])]),o(`div`,En,[(k(!0),g(p,null,y(t(z),([t,n])=>(k(),h(ne,{key:t,label:n,value:e[t],warn:t===`tension`},null,8,[`label`,`value`,`warn`]))),128))]),o(`small`,Dn,i(t(a)(`在 {length} 个地方见过 · 上次说上话 {v}`,{length:e.sessions.length,v:e.lastTalkedAt?t(Y)(e.lastTalkedAt,t(G).data?.now):t(a)(`还没有`)})),1)],8,Cn))),128))]))],64)):(k(),h(O,{key:1,title:t(a)(`TA 还没有认识谁`),text:t(a)(`有人和 TA 说话、TA 细看过群聊之后,这里会出现 TA 对每个人的感觉。`)},null,8,[`title`,`text`])),b(Gt,{groups:r.value.groups,onChanged:C},null,8,[`groups`])],64)):m(``,!0),b(yt,{id:d.value,now:t(G).data?.now,onClose:A,onChanged:C,onRelationship:l[3]||=(e,t)=>{A(),n.value?.edit(e,t)}},null,8,[`id`,`now`])]))}}),[[`__scopeId`,`data-v-4c6f1adb`]]);export{On as default};
@@ -1,2 +1,2 @@
1
- import{$ as e,Ct as t,Et as n,I as r,J as i,U as a,V as o,W as s,X as c,Y as l,Z as u,ct as d,dt as f,et as p,gt as m,lt as ee,m as h,n as te,nt as g,o as ne,q as re,s as _,t as v,ut as y,vt as b,xt as x,yt as S,z as ie}from"./Empty-CLyZkxR5.js";import{i as C,n as ae,o as oe}from"./index-DdYwC5ZU.js";import{t as w}from"./Field-BpaRwLI_.js";var se={class:`page plugins`},ce={class:`plugins-intro`},le={class:`eyebrow`},ue={key:0,class:`warn-text`,role:`alert`},de={key:1,class:`stack`},fe={class:`lead`},pe={class:`grid`},me={class:`muted`},he={key:0},ge={class:`row`},_e=[`onClick`],ve=[`onClick`],ye=[`onClick`],be={key:2,class:`grid`},T=[`onClick`],E={key:3,class:`grid`},D={class:`row`},O=[`onClick`],k=[`onClick`],A={key:4,class:`grid`},j={key:0,class:`switch`},M=[`onUpdate:modelValue`],N=[`onUpdate:modelValue`,`placeholder`],xe=[`onUpdate:modelValue`,`placeholder`],Se=[`onUpdate:modelValue`],Ce={class:`row`},we={class:`ghost`,type:`submit`},Te=[`src`],Ee={key:1,class:`row`},P=te(g({__name:`PluginsPage`,setup(te){let g=[`installed`,`market`,`actions`,`import`],P=x(g.includes(_.sub)?_.sub:`installed`),F=x([]),I=x([]),L=x(!1),R=x(!1),z=x([]),B=x(``),V=x(``),H=x(null),U=x({}),W=x({url:``,sha256:``}),G=x(``),K=x(``),q=x(``),J=x(null),Y=re(()=>F.value.find(e=>e.id===V.value));async function X(){F.value=(await h(`/plugins`)).plugins||[];try{z.value=(await h(`/plugins/actions/pending`)).actions||[]}catch{z.value=[]}}function Z(){R.value=!0,h(`/plugins/market`).then(e=>{I.value=e.plugins||[],L.value=!!e.unavailable}).catch(()=>{I.value=[],L.value=!0}).finally(()=>{R.value=!1})}m(P,e=>{ne(e),e===`market`&&Z()}),m(()=>_.sub,e=>{g.includes(e)&&(P.value=e)}),m(V,async e=>{if(!e)return;let t=await h(`/plugins/${e}/settings`),n={};for(let e of t.fields||[]){let r=t.values?.[e.key]??e.default;e.type===`boolean`?n[e.key]=r===!0:e.type===`urls`?n[e.key]=Array.isArray(r)?r.join(`
1
+ import{$ as e,Ct as t,Et as n,I as r,J as i,U as a,V as o,W as s,X as c,Y as l,Z as u,ct as d,dt as f,et as p,gt as m,lt as ee,m as h,n as te,nt as g,o as ne,q as re,s as _,t as v,ut as y,vt as b,xt as x,yt as S,z as ie}from"./Empty-C7yzOBzy.js";import{i as C,n as ae,o as oe}from"./index-CyRtYxP3.js";import{t as w}from"./Field-BjFv4Rfn.js";var se={class:`page plugins`},ce={class:`plugins-intro`},le={class:`eyebrow`},ue={key:0,class:`warn-text`,role:`alert`},de={key:1,class:`stack`},fe={class:`lead`},pe={class:`grid`},me={class:`muted`},he={key:0},ge={class:`row`},_e=[`onClick`],ve=[`onClick`],ye=[`onClick`],be={key:2,class:`grid`},T=[`onClick`],E={key:3,class:`grid`},D={class:`row`},O=[`onClick`],k=[`onClick`],A={key:4,class:`grid`},j={key:0,class:`switch`},M=[`onUpdate:modelValue`],N=[`onUpdate:modelValue`,`placeholder`],xe=[`onUpdate:modelValue`,`placeholder`],Se=[`onUpdate:modelValue`],Ce={class:`row`},we={class:`ghost`,type:`submit`},Te=[`src`],Ee={key:1,class:`row`},P=te(g({__name:`PluginsPage`,setup(te){let g=[`installed`,`market`,`actions`,`import`],P=x(g.includes(_.sub)?_.sub:`installed`),F=x([]),I=x([]),L=x(!1),R=x(!1),z=x([]),B=x(``),V=x(``),H=x(null),U=x({}),W=x({url:``,sha256:``}),G=x(``),K=x(``),q=x(``),J=x(null),Y=re(()=>F.value.find(e=>e.id===V.value));async function X(){F.value=(await h(`/plugins`)).plugins||[];try{z.value=(await h(`/plugins/actions/pending`)).actions||[]}catch{z.value=[]}}function Z(){R.value=!0,h(`/plugins/market`).then(e=>{I.value=e.plugins||[],L.value=!!e.unavailable}).catch(()=>{I.value=[],L.value=!0}).finally(()=>{R.value=!1})}m(P,e=>{ne(e),e===`market`&&Z()}),m(()=>_.sub,e=>{g.includes(e)&&(P.value=e)}),m(V,async e=>{if(!e)return;let t=await h(`/plugins/${e}/settings`),n={};for(let e of t.fields||[]){let r=t.values?.[e.key]??e.default;e.type===`boolean`?n[e.key]=r===!0:e.type===`urls`?n[e.key]=Array.isArray(r)?r.join(`
2
2
  `):r??``:n[e.key]=r??``}U.value=n});async function De(){Y.value&&(B.value=``,await h(`/plugins/${Y.value.id}/settings`,{method:`PUT`,body:JSON.stringify({values:U.value})}))}async function Oe(e){B.value=``;try{V.value===e.id&&await h(`/plugins/${e.id}/settings`,{method:`PUT`,body:JSON.stringify({values:U.value})}),await h(`/plugins/${e.id}/grant`,{method:`POST`,body:JSON.stringify({permissions:e.permissions})}),await h(`/plugins/${e.id}/enable`,{method:`POST`,body:`{}`}),await X()}catch(e){B.value=e.message}}async function Q(e,t){B.value=``;try{H.value=await h(e,{method:`POST`,body:JSON.stringify(t)})}catch(e){B.value=e.message}}async function ke(){if(!H.value)return;await h(`/plugins/import/commit`,{method:`POST`,body:JSON.stringify({token:H.value.token})});let e=H.value;H.value=null,await h(`/plugins/${e.manifest.id}/grant`,{method:`POST`,body:JSON.stringify({permissions:e.permissions})}),P.value=`installed`,await X()}function $(e){let t=e.data||{};if(t.luckytri!==1||!Y.value||e.source!==J.value?.contentWindow)return;let n=String(t.path||`/`);n.startsWith(`/`)&&h(`/plugins/${Y.value.id}/x${n}`,{method:t.method||`GET`,body:t.body?JSON.stringify(t.body):void 0}).then(e=>J.value?.contentWindow?.postMessage({id:t.id,ok:!0,result:e},location.origin)).catch(e=>J.value?.contentWindow?.postMessage({id:t.id,ok:!1,error:e.message},location.origin))}d(()=>{X().catch(e=>B.value=e.message),P.value===`market`&&Z(),window.addEventListener(`message`,$)}),ee(()=>window.removeEventListener(`message`,$));function Ae(e){return r(e===`high`?`高风险`:e===`medium`?`中风险`:`低风险`)}function je(e){return e.running?r(`运行中`):e.state===`error`?r(`出错`):e.enabled?r(`正在启动`):e.source===`builtin`?r(`内置,未启用`):r(`已安装,未启用`)}return(d,m)=>(y(),u(`div`,se,[i(`header`,ce,[i(`span`,le,n(t(r)(`THE WORLD SHE CAN TOUCH · 插件`)),1),i(`h1`,null,[e(n(t(r)(`核心是她。`)),1),i(`em`,null,n(t(r)(`插件是世界。`)),1)]),i(`p`,null,n(t(r)(`插件只能经她同意接触世界。它们读不到她的数据库,也不能替她开口。`)),1)]),B.value?(y(),u(`p`,ue,n(B.value),1)):c(``,!0),p(ae,{"model-value":P.value,"onUpdate:modelValue":m[0]||=e=>P.value=e,label:t(r)(`插件的分区`),items:[{key:`installed`,label:t(r)(`插件列表`)},{key:`market`,label:t(r)(`插件市场`)},{key:`actions`,label:t(r)(`她想做的事`),count:z.value.length},{key:`import`,label:t(r)(`导入与开发`)}]},null,8,[`model-value`,`label`,`items`]),P.value===`installed`?(y(),u(`section`,de,[i(`p`,fe,n(t(r)(`天气随 LuckyTri 附带,默认关闭。启用前会先列出它要的权限。`)),1),i(`div`,pe,[F.value.length?c(``,!0):(y(),l(v,{key:0,title:t(r)(`还没有接上插件`),text:t(r)(`内置的天气可以在这里启用,也可以从市场安装。`)},null,8,[`title`,`text`])),(y(!0),u(s,null,f(F.value,a=>(y(),l(C,{key:a.id,title:a.manifest.name||a.id},{default:b(()=>[i(`p`,null,n(a.manifest.description),1),i(`p`,me,[e(n(a.version)+` · `+n(je(a))+` `,1),a.status?.text?(y(),u(`span`,he,` · `+n(a.status.text),1)):c(``,!0)]),i(`div`,ge,[a.enabled?(y(),u(`button`,{key:1,class:`ghost`,onClick:e=>t(h)(`/plugins/${a.id}/disable`,{method:`POST`,body:`{}`}).then(X)},n(t(r)(`停用`)),9,ve)):(y(),u(`button`,{key:0,class:`primary`,onClick:e=>V.value=a.id},n(t(r)(`查看权限并启用`)),9,_e)),i(`button`,{class:`ghost`,onClick:e=>V.value=a.id},n(t(r)(`详情`)),9,ye)])]),_:2},1032,[`title`]))),128))])])):P.value===`market`?(y(),u(`section`,be,[R.value?(y(),l(v,{key:0,title:t(r)(`正在查看市场`),text:t(r)(`连不上的话,这里会说明,不会再显示一串英文错误。`)},null,8,[`title`,`text`])):I.value.length?c(``,!0):(y(),l(v,{key:1,title:t(r)(`市场暂时没有条目`),text:L.value?t(r)(`插件市场的索引还没有发布,或现在连不上。随程序附带的插件在「插件列表」里,默认关闭。`):t(r)(`索引仓库还是空的,或者现在连不上。你仍然可以导入一个插件包。`)},null,8,[`title`,`text`])),R.value?c(``,!0):(y(!0),u(s,{key:2},f(I.value,e=>(y(),l(C,{key:e.id||e.source,title:e.name||e.id},{default:b(()=>[i(`p`,null,n(e.description),1),e.latest?(y(),u(`button`,{key:0,class:`primary`,onClick:t=>Q(`/plugins/market/stage`,{url:e.latest.url,sha256:e.latest.sha256,id:e.id})},n(t(r)(`安装`))+` `+n(e.latest.version),9,T)):c(``,!0)]),_:2},1032,[`title`]))),128))])):P.value===`actions`?(y(),u(`section`,E,[z.value.length?c(``,!0):(y(),l(v,{key:0,title:t(r)(`没有等待同意的事`),text:t(r)(`高风险的行动会先停在这里,等你点头。过一天就不再算数。`)},null,8,[`title`,`text`])),(y(!0),u(s,null,f(z.value,e=>(y(),l(C,{key:e.id,title:e.label},{default:b(()=>[i(`p`,null,n(e.reason),1),i(`div`,D,[i(`button`,{class:`primary`,onClick:n=>t(h)(`/plugins/actions/${e.id}/approve`,{method:`POST`,body:`{}`}).then(X)},n(t(r)(`同意`)),9,O),i(`button`,{class:`ghost`,onClick:n=>t(h)(`/plugins/actions/${e.id}/reject`,{method:`POST`,body:`{}`}).then(X)},n(t(r)(`拒绝`)),9,k)])]),_:2},1032,[`title`]))),128))])):(y(),u(`section`,A,[p(C,{title:t(r)(`从链接导入`)},{default:b(()=>[p(w,{label:t(r)(`插件包地址`)},{default:b(()=>[S(i(`input`,{"onUpdate:modelValue":m[1]||=e=>W.value.url=e},null,512),[[o,W.value.url]])]),_:1},8,[`label`]),p(w,{label:t(r)(`校验值,可留空`)},{default:b(()=>[S(i(`input`,{"onUpdate:modelValue":m[2]||=e=>W.value.sha256=e},null,512),[[o,W.value.sha256]])]),_:1},8,[`label`]),i(`button`,{class:`primary`,onClick:m[3]||=e=>Q(`/plugins/import/url`,W.value)},n(t(r)(`检查这个包`)),1)]),_:1},8,[`title`]),p(C,{title:t(r)(`从 GitHub 导入`)},{default:b(()=>[p(w,{label:t(r)(`仓库地址`)},{default:b(()=>[S(i(`input`,{"onUpdate:modelValue":m[4]||=e=>G.value=e,placeholder:`https://github.com/owner/name`},null,512),[[o,G.value]])]),_:1},8,[`label`]),i(`button`,{class:`primary`,onClick:m[5]||=e=>Q(`/plugins/import/github`,{repository:G.value})},n(t(r)(`检查这个仓库`)),1)]),_:1},8,[`title`]),p(C,{title:t(r)(`本机目录(开发)`)},{default:b(()=>[p(w,{label:t(r)(`目录`)},{default:b(()=>[S(i(`input`,{"onUpdate:modelValue":m[6]||=e=>K.value=e},null,512),[[o,K.value]])]),_:1},8,[`label`]),i(`button`,{class:`ghost`,onClick:m[7]||=e=>Q(`/plugins/import/dir`,{dir:K.value})},n(t(r)(`按开发插件接上`)),1)]),_:1},8,[`title`]),p(C,{title:t(r)(`索引源`)},{default:b(()=>[p(w,{label:t(r)(`索引地址`)},{default:b(()=>[S(i(`input`,{"onUpdate:modelValue":m[8]||=e=>q.value=e},null,512),[[o,q.value]])]),_:1},8,[`label`]),i(`button`,{class:`ghost`,onClick:m[9]||=e=>t(h)(`/plugins/sources`,{method:`POST`,body:JSON.stringify({url:q.value})})},n(t(r)(`添加索引`)),1)]),_:1},8,[`title`])])),H.value?(y(),l(C,{key:5,title:t(r)(`先看清它要什么`)},{default:b(()=>[i(`p`,null,n(H.value.manifest?.name)+` `+n(H.value.manifest?.version)+` · `+n(H.value.trusted?t(r)(`校验通过`):t(r)(`未登记来源`)),1),i(`ul`,null,[(y(!0),u(s,null,f(H.value.permissions,e=>(y(),u(`li`,{key:e},n(e),1))),128))]),i(`button`,{class:`primary`,onClick:ke},n(t(r)(`同意这些权限并安装`)),1)]),_:1},8,[`title`])):c(``,!0),p(oe,{open:!!Y.value,title:Y.value?.manifest.name||``,onClose:m[13]||=e=>V.value=``},{default:b(()=>[Y.value?(y(),u(s,{key:0},[i(`p`,null,n(Y.value.manifest.description),1),i(`ul`,null,[(y(!0),u(s,null,f(Y.value.risk,e=>(y(),u(`li`,{key:e.name},n(Ae(e.risk))+` · `+n(e.label),1))),128))]),i(`form`,{class:`settings`,onSubmit:m[11]||=a(e=>De().catch(e=>B.value.value=e.message),[`prevent`])},[(y(!0),u(s,null,f(Y.value.manifest.settings||[],e=>(y(),u(s,{key:e.key},[e.type===`boolean`?(y(),u(`label`,j,[i(`span`,null,n(e.label),1),S(i(`input`,{"onUpdate:modelValue":t=>U.value[e.key]=t,type:`checkbox`},null,8,M),[[ie,U.value[e.key]]])])):(y(),l(w,{key:1,label:e.label},{default:b(()=>[e.type===`secret`?S((y(),u(`input`,{key:0,type:`password`,"onUpdate:modelValue":t=>U.value[e.key]=t,placeholder:t(r)(`已保存的不会回显`)},null,8,N)),[[o,U.value[e.key]]]):e.type===`textarea`||e.type===`urls`?S((y(),u(`textarea`,{key:1,"onUpdate:modelValue":t=>U.value[e.key]=t,rows:`4`,placeholder:e.type===`urls`?t(r)(`一行一个地址`):void 0},null,8,xe)),[[o,U.value[e.key]]]):S((y(),u(`input`,{key:2,"onUpdate:modelValue":t=>U.value[e.key]=t},null,8,Se)),[[o,U.value[e.key]]])]),_:2},1032,[`label`]))],64))),128)),i(`div`,Ce,[i(`button`,we,n(t(r)(`保存设置`)),1),Y.value.enabled?c(``,!0):(y(),u(`button`,{key:0,class:`primary`,type:`button`,onClick:m[10]||=e=>Oe(Y.value)},n(t(r)(`同意这些权限并启用`)),1))])],32),Y.value.enabled&&Y.value.manifest.contributes?.page?(y(),u(`iframe`,{key:0,ref_key:`frame`,ref:J,class:`plugin-frame`,sandbox:`allow-scripts allow-forms`,src:`/plugin-ui/${Y.value.id}/index.html`},null,8,Te)):c(``,!0),Y.value.source===`builtin`?c(``,!0):(y(),u(`div`,Ee,[i(`button`,{class:`ghost`,onClick:m[12]||=e=>{t(h)(`/plugins/${Y.value.id}`,{method:`DELETE`,body:`{}`}).then(()=>{V.value=``,X()})}},n(t(r)(`卸载`)),1)]))],64)):c(``,!0)]),_:1},8,[`open`,`title`])]))}}),[[`__scopeId`,`data-v-042ad318`]]);export{P as default};
@@ -1 +1 @@
1
- .connect[data-v-6f4553ed]{gap:var(--gap);grid-template-columns:minmax(0,1.25fr) minmax(290px,.9fr);align-items:start;display:grid}.connection[data-v-6f4553ed]{gap:20px;display:grid}.connection-details[data-v-6f4553ed]{gap:10px;display:grid}.detail[data-v-6f4553ed]{border:1px solid var(--line);background:color-mix(in srgb, var(--surface-strong) 70%, transparent);border-radius:14px;flex-wrap:wrap;justify-content:space-between;align-items:center;gap:8px 16px;padding:13px 16px;display:flex}.detail code[data-v-6f4553ed]{overflow-wrap:anywhere}.warn-text[data-v-6f4553ed]{color:var(--warn);overflow-wrap:anywhere}.instructions[data-v-6f4553ed]{gap:11px;margin:0;padding-left:22px;line-height:1.65;display:grid}.notes[data-v-6f4553ed]{gap:8px;margin:0;padding-left:20px;font-size:13px;line-height:1.6;display:grid}.note[data-v-6f4553ed]{margin:-8px 0 0;font-size:12px}.checks[data-v-6f4553ed]{gap:8px;margin:0;padding:0;list-style:none;display:grid}.checks li[data-v-6f4553ed]{background:color-mix(in srgb, var(--surface-strong) 70%, transparent);border:1px solid var(--line);border-radius:14px;align-items:center;gap:12px;padding:10px 12px;display:flex}.checks li>div[data-v-6f4553ed]{flex:1;min-width:0;display:grid}.checks small[data-v-6f4553ed]{font-size:12px}.mark[data-v-6f4553ed]{border:2px solid var(--line);border-radius:50%;flex:none;place-items:center;width:22px;height:22px;font-size:11px;font-weight:700;display:grid}.done .mark[data-v-6f4553ed]{border-color:var(--ok);background:var(--ok);color:var(--accent-ink)}@media (width<=1000px){.connect[data-v-6f4553ed]{grid-template-columns:minmax(0,1fr)}}.embedding-profile[data-v-ebda40d8]{min-width:0}.fields[data-v-ebda40d8]{grid-template-columns:repeat(auto-fit,minmax(min(220px,100%),1fr));gap:14px;margin:16px 0;display:grid}.save-bar[data-v-ebda40d8]{position:relative;bottom:auto}.library[data-v-db7bc4c1]{gap:var(--gap);grid-template-columns:minmax(0,1fr);display:grid}.model-workspace[data-v-db7bc4c1]{gap:var(--gap);grid-template-columns:minmax(260px,.32fr) minmax(0,1fr);align-items:start;display:grid}.shelf[data-v-db7bc4c1]{background:radial-gradient(ellipse at 0 0, color-mix(in srgb, var(--glow-a) 23%, transparent), transparent 56%), var(--surface);gap:15px;display:grid;position:sticky;top:14px}.detail[data-v-db7bc4c1]{background:radial-gradient(ellipse at 100% 0, color-mix(in srgb, var(--glow-b) 16%, transparent), transparent 47%), var(--surface)}.usage-panel[data-v-db7bc4c1]{background:radial-gradient(ellipse at 100% 0, color-mix(in srgb, var(--glow-a) 25%, transparent), transparent 42%), radial-gradient(ellipse at 0 100%, color-mix(in srgb, var(--glow-b) 20%, transparent), transparent 46%), var(--surface);grid-column:1/-1;gap:18px;display:grid;overflow:hidden}.usage-intro[data-v-db7bc4c1]{justify-content:space-between;align-items:end;gap:20px;display:flex}.usage-intro h2[data-v-db7bc4c1]{letter-spacing:-.04em;margin:5px 0 4px;font-size:22px}.usage-intro p[data-v-db7bc4c1],.usage-foot small[data-v-db7bc4c1]{color:var(--ink-soft);font-size:12px}.usage-total[data-v-db7bc4c1]{flex:none;justify-items:end;display:grid}.usage-total strong[data-v-db7bc4c1]{color:var(--accent);font:700 clamp(28px, 4vw, 42px) var(--font-display);letter-spacing:-.055em;font-variant-numeric:tabular-nums;line-height:1.05}.usage-total span[data-v-db7bc4c1]{color:var(--ink-soft);font-size:12px}.usage-detail[data-v-db7bc4c1]{grid-template-columns:repeat(4,minmax(0,1fr));gap:10px;display:grid}.usage-stat[data-v-db7bc4c1]{background:#ffffff5c;border:1px solid #ffffffc7;border-radius:18px;gap:5px;min-width:0;padding:14px 16px;display:grid;box-shadow:inset 0 1px #fff}.usage-stat span[data-v-db7bc4c1]{color:var(--ink-soft);font-size:12px}.usage-stat span small[data-v-db7bc4c1]{font-size:10px}.usage-stat b[data-v-db7bc4c1]{font-variant-numeric:tabular-nums;text-overflow:ellipsis;font-size:19px;overflow:hidden}.usage-foot[data-v-db7bc4c1]{flex-wrap:wrap;justify-content:space-between;align-items:center;gap:10px;display:flex}.usage-error[data-v-db7bc4c1]{color:var(--danger)!important}.usage-refresh[data-v-db7bc4c1]{color:var(--accent);font-size:12px}.shelf-head[data-v-db7bc4c1]{justify-content:space-between;align-items:center;gap:8px;display:flex}.shelf-head h2[data-v-db7bc4c1]{letter-spacing:-.04em;font-size:21px}.shelf-head small[data-v-db7bc4c1]{color:var(--ink-soft);font-size:12px}.rows[data-v-db7bc4c1]{gap:8px;max-height:520px;display:grid;overflow:auto}.saved-vendor[data-v-db7bc4c1]{background:#fff3;border:1px solid #ffffffad;border-radius:17px;overflow:hidden;box-shadow:inset 0 1px #ffffffb8}.saved-vendor>summary[data-v-db7bc4c1]{color:var(--ink);cursor:pointer;justify-content:space-between;align-items:center;gap:8px;padding:11px 13px;font-size:12px;font-weight:700;list-style:none;display:flex}.saved-vendor>summary[data-v-db7bc4c1]::-webkit-details-marker{display:none}.vendor-summary[data-v-db7bc4c1]::-webkit-details-marker{display:none}.saved-vendor>summary[data-v-db7bc4c1]:after{color:var(--accent);content:"⌄";transition:transform .24s var(--spring);font-size:15px}.saved-vendor[open]>summary[data-v-db7bc4c1]{background:#ffffff40;border-bottom:1px solid #fff9}.saved-vendor[open]>summary[data-v-db7bc4c1]:after{transform:rotate(180deg)}.saved-vendor>summary small[data-v-db7bc4c1]{color:var(--ink-soft);margin-left:auto;font-size:10px;font-weight:500}.vendor-models[data-v-db7bc4c1]{gap:6px;padding:7px;display:grid}.entity-row[data-v-db7bc4c1]{text-align:left;-webkit-backdrop-filter:blur(16px)saturate(1.5);backdrop-filter:blur(16px)saturate(1.5);width:100%;transition:transform .32s var(--spring), background-color .2s, box-shadow .25s;background:#ffffff5c;border:1px solid #ffffffbf;border-radius:18px;align-items:center;gap:10px;padding:11px 12px;display:flex;box-shadow:inset 0 1px #fff}.entity-row[data-v-db7bc4c1]:hover:not(:disabled){box-shadow:0 12px 22px -19px var(--accent);background:#ffffffa8;transform:translate(4px)scale(1.01)}.entity-row.selected[data-v-db7bc4c1]{border-color:color-mix(in srgb, var(--accent) 22%, white);background:linear-gradient(115deg, white, color-mix(in srgb, var(--accent-soft) 60%, white));box-shadow:inset 0 1px 0 white, 0 13px 23px -20px var(--accent)}.badge[data-v-db7bc4c1]{background:linear-gradient(145deg, white, hsl(var(--hue) 70% 88%));width:36px;height:36px;color:hsl(var(--hue) 45% 25%);box-shadow:inset 0 1px 0 white, 0 5px 13px -10px hsl(var(--hue) 45% 32%);border-radius:14px;flex:none;place-items:center;font-weight:700;display:grid}.who[data-v-db7bc4c1]{min-width:0;line-height:1.35;display:grid}.who b[data-v-db7bc4c1]{text-overflow:ellipsis;white-space:nowrap;font-size:13.5px;overflow:hidden}.who small[data-v-db7bc4c1]{color:var(--ink-soft);font-size:11.5px;font-weight:500}fieldset[data-v-db7bc4c1]{background:linear-gradient(142deg, #ffffffa1, #ffffff47), var(--surface);box-shadow:inset 0 1px 0 white, 0 14px 30px -27px var(--accent);-webkit-backdrop-filter:blur(20px)saturate(1.6);backdrop-filter:blur(20px)saturate(1.6);border:1px solid #ffffffcf;border-radius:24px;gap:10px;margin:0;padding:20px;display:grid}legend[data-v-db7bc4c1]{padding:0 8px;font-size:13px;font-weight:700}.advanced summary[data-v-db7bc4c1]{color:var(--accent);transition:transform .3s var(--spring), background-color .2s;background:#ffffff6b;border:1px solid #fffc;border-radius:14px;padding:12px 15px;font-weight:600;box-shadow:inset 0 1px #fff}.advanced summary[data-v-db7bc4c1]:hover{background:#ffffffa6;transform:translate(3px)}.advanced[open] summary[data-v-db7bc4c1]{margin-bottom:12px}.caps[data-v-db7bc4c1]{flex-wrap:wrap;gap:8px 18px;margin-top:10px;display:flex}.actions[data-v-db7bc4c1]{flex-wrap:wrap;gap:8px;display:flex}.actions .push[data-v-db7bc4c1]{margin-left:auto}.model-picker[data-v-db7bc4c1]{gap:16px;display:grid}.catalog-search[data-v-db7bc4c1]{color:var(--ink-soft);gap:6px;font-size:12px;font-weight:600;display:grid}.catalog-search input[data-v-db7bc4c1]{width:100%;min-height:42px;color:var(--ink);-webkit-backdrop-filter:blur(14px)saturate(1.4);backdrop-filter:blur(14px)saturate(1.4);background:#ffffff9e;border:1px solid #ffffffd9;border-radius:14px;outline:none;padding:0 13px;box-shadow:inset 0 1px #fff}.catalog-search input[data-v-db7bc4c1]:focus{border-color:color-mix(in srgb, var(--accent) 42%, white);box-shadow:0 0 0 3px color-mix(in srgb, var(--accent) 10%, transparent)}.vendor[data-v-db7bc4c1]{background:radial-gradient(ellipse at 100% 0, color-mix(in srgb, var(--glow-a) 13%, transparent), transparent 48%), #ffffff3b;-webkit-backdrop-filter:blur(18px)saturate(1.35);backdrop-filter:blur(18px)saturate(1.35);border:1px solid #ffffffb8;border-radius:21px;overflow:hidden;box-shadow:inset 0 1px #ffffffc7}.vendor-summary[data-v-db7bc4c1]{cursor:pointer;justify-content:space-between;align-items:center;gap:12px;min-height:62px;padding:12px 17px;list-style:none;transition:background-color .2s;display:flex}.vendor-summary[data-v-db7bc4c1]:hover{background:#ffffff57}.vendor-name[data-v-db7bc4c1]{align-items:center;gap:10px;min-width:0;display:flex}.vendor-name b[data-v-db7bc4c1]{font-size:13px}.vendor-name small[data-v-db7bc4c1]{color:var(--ink-soft);font-size:10px}.vendor-chevron[data-v-db7bc4c1]{color:var(--accent);transition:transform .28s var(--spring);font-size:20px;line-height:1}.vendor[open] .vendor-chevron[data-v-db7bc4c1]{transform:rotate(180deg)}.vendor[open] .presets[data-v-db7bc4c1]{animation:vendor-reveal-db7bc4c1 .24s var(--spring) both}@keyframes vendor-reveal-db7bc4c1{0%{opacity:0;transform:translateY(-5px)}to{opacity:1;transform:translateY(0)}}.search-empty[data-v-db7bc4c1]{margin:0}.presets[data-v-db7bc4c1]{grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:8px;padding:0 12px 12px;display:grid}.preset-card[data-v-db7bc4c1]{background:radial-gradient(ellipse at 100% 0, color-mix(in srgb, var(--glow-a) 22%, transparent), transparent 55%), #ffffff80;box-shadow:inset 0 1px 0 white, 0 12px 22px -20px var(--accent);text-align:left;-webkit-backdrop-filter:blur(16px)saturate(1.5);backdrop-filter:blur(16px)saturate(1.5);transition:transform .42s var(--spring), box-shadow .25s;border:1px solid #ffffffd1;border-radius:21px;justify-items:start;gap:3px;padding:17px;font-weight:500;display:grid}.preset-card[data-v-db7bc4c1]:hover:not(:disabled){box-shadow:inset 0 1px 0 white, 0 22px 33px -22px var(--accent);transform:translateY(-6px)rotate(-.5deg)scale(1.025)}.preset-card small[data-v-db7bc4c1]{color:var(--ink-soft);font-size:11.5px}@media (width<=900px){.model-workspace[data-v-db7bc4c1]{grid-template-columns:minmax(0,1fr)}.usage-panel[data-v-db7bc4c1]{grid-column:auto}.shelf[data-v-db7bc4c1]{position:static}}@media (width<=620px){.usage-intro[data-v-db7bc4c1]{flex-direction:column;align-items:start}.usage-total[data-v-db7bc4c1]{justify-items:start}.usage-detail[data-v-db7bc4c1]{grid-template-columns:repeat(2,minmax(0,1fr))}}.runtime-grid[data-v-1f197523]{gap:var(--gap);grid-template-columns:minmax(0,1.55fr) minmax(260px,.8fr);align-items:start;display:grid}.runtime-grid>.card[data-v-1f197523]{background:radial-gradient(ellipse at 90% 0, color-mix(in srgb, var(--glow-a) 20%, transparent), transparent 55%), var(--surface)}.runtime-grid .card-head h2[data-v-1f197523]{letter-spacing:-.035em;margin-top:5px;font-size:23px}.switches[data-v-1f197523]{gap:12px;margin-bottom:20px;display:grid}.switches[data-v-1f197523] .switch{box-shadow:inset 0 1px 0 white, 0 10px 22px -23px var(--accent);-webkit-backdrop-filter:blur(18px)saturate(1.5);backdrop-filter:blur(18px)saturate(1.5);transition:transform .35s var(--spring), background-color .2s;background:#ffffff69;border:1px solid #ffffffc7;border-radius:22px;align-items:flex-start;padding:18px}.switches[data-v-1f197523] .switch:hover{background:#ffffffa3;transform:translateY(-3px)scale(1.008)}.switches[data-v-1f197523] .switch>span{gap:2px;display:grid}.switches small[data-v-1f197523]{color:var(--ink-soft);font-size:12.5px;font-weight:400}.numbers[data-v-1f197523]{gap:12px;display:grid}.numbers button[data-v-1f197523],.numbers .stat[data-v-1f197523]{background:radial-gradient(ellipse at 100% 0, color-mix(in srgb, var(--glow-b) 24%, transparent), transparent 63%), #ffffff70;box-shadow:inset 0 1px 0 white, 0 12px 26px -24px var(--accent);text-align:left;-webkit-backdrop-filter:blur(18px)saturate(1.55);backdrop-filter:blur(18px)saturate(1.55);transition:transform .38s var(--spring), box-shadow .23s;border:1px solid #ffffffd4;border-radius:22px;justify-items:start;gap:2px;padding:20px 21px;display:grid}.numbers button[data-v-1f197523]:hover:not(:disabled){box-shadow:inset 0 1px 0 white, 0 18px 28px -22px var(--accent);transform:translate(5px)scale(1.018)}.numbers b[data-v-1f197523]{font:750 29px var(--font-display);color:var(--accent)}.numbers .stat.warn b[data-v-1f197523]{color:var(--warn)}.numbers .stat.danger b[data-v-1f197523]{color:var(--danger)}.numbers span[data-v-1f197523]{color:var(--ink-soft);font-size:12.5px;font-weight:500}@media (width<=900px){.runtime-grid[data-v-1f197523]{grid-template-columns:minmax(0,1fr)}}.search-profile[data-v-5135e471]{gap:16px;min-width:0;display:grid}.search-profile form[data-v-5135e471]{gap:18px;display:grid}.search-fields[data-v-5135e471]{grid-template-columns:repeat(2,minmax(0,1fr));gap:16px;display:grid}.search-fields label[data-v-5135e471]{gap:8px;min-width:0;display:grid}.search-fields input[data-v-5135e471],.search-fields .menu-select[data-v-5135e471]{width:100%;min-width:0}.search-usage[data-v-5135e471]{flex-wrap:wrap;align-items:center;gap:12px;display:flex}.search-result[data-v-5135e471]{border:1px solid var(--line);background:var(--surface);overflow-wrap:anywhere;border-radius:16px;padding:14px 16px}.search-result.failed[data-v-5135e471]{border-color:color-mix(in srgb, var(--warn) 40%, var(--line))}@media (width<=620px){.search-fields[data-v-5135e471]{grid-template-columns:minmax(0,1fr)}}.data-transfer[data-v-1a555eb4]{min-width:0}.data-transfer h2[data-v-1a555eb4]{margin:8px 0 14px;font-size:clamp(23px,3vw,32px)}.transfer-note[data-v-1a555eb4]{color:var(--ink-soft);overflow-wrap:anywhere;font-size:13px;line-height:1.7}.transfer-actions[data-v-1a555eb4]{flex-wrap:wrap;gap:10px;margin:18px 0;display:flex}.transfer-actions button[data-v-1a555eb4]{border-radius:16px;padding:11px 17px}.transfer-actions button[data-v-1a555eb4]:not(.primary){background:#ffffffb8}.transfer-file[data-v-1a555eb4]{display:none}.transfer-preview[data-v-1a555eb4]{overflow-wrap:anywhere;background:#fff6;border:1px solid #ffffffd9;border-radius:22px;margin-top:20px;padding:20px}.transfer-preview h3[data-v-1a555eb4]{margin:8px 0}.transfer-counts[data-v-1a555eb4]{flex-wrap:wrap;gap:10px;display:flex}.transfer-counts>div[data-v-1a555eb4]{background:#ffffffa6;border-radius:14px;gap:4px;min-width:70px;padding:12px;display:grid}.transfer-counts b[data-v-1a555eb4],.transfer-progress[data-v-1a555eb4]{color:var(--accent)}.transfer-counts span[data-v-1a555eb4]{color:var(--ink-soft);font-size:12px}.transfer-error[data-v-1a555eb4]{color:var(--danger);overflow-wrap:anywhere}.storage-page[data-v-4593780e]{gap:var(--gap);display:grid}.storage-page>.card[data-v-4593780e],.storage-grid>.card[data-v-4593780e]{background:radial-gradient(ellipse at 100% 0, color-mix(in srgb, var(--glow-a) 20%, transparent), transparent 60%), var(--surface)}.storage-overview h2[data-v-4593780e]{margin:8px 0;font-size:clamp(24px,3vw,36px)}.storage-overview p[data-v-4593780e],.storage-note[data-v-4593780e]{color:var(--ink-soft);font-size:13px;line-height:1.65}.storage-metrics[data-v-4593780e]{flex-wrap:wrap;gap:12px;margin-top:22px;display:flex}.storage-metrics>div[data-v-4593780e]{background:#ffffff6b;border:1px solid #fffc;border-radius:18px;gap:3px;min-width:150px;padding:15px 20px;display:grid}.storage-metrics b[data-v-4593780e]{color:var(--accent);font-size:23px}.storage-metrics span[data-v-4593780e]{color:var(--ink-soft);font-size:12px}.storage-grid[data-v-4593780e]{gap:var(--gap);grid-template-columns:minmax(270px,.8fr) minmax(0,1.5fr);align-items:start;display:grid}.storage-grid .card-head h2[data-v-4593780e]{margin:4px 0 16px;font-size:23px}.storage-check[data-v-4593780e]{align-items:center;gap:9px;margin-bottom:16px;display:flex}.storage-fields[data-v-4593780e]{gap:13px;display:grid}.storage-fields label[data-v-4593780e]{color:var(--ink-soft);gap:6px;font-size:12px;font-weight:700;display:grid}.storage-fields input[data-v-4593780e]{border:1px solid color-mix(in srgb, var(--accent) 25%, white);width:100%;min-width:0;color:var(--ink);background:#ffffffb3;border-radius:15px;padding:11px 13px}.storage-policy .primary[data-v-4593780e]{margin-top:14px}.storage-actions[data-v-4593780e]{flex-wrap:wrap;gap:8px;margin:16px 0;display:flex}.storage-actions button[data-v-4593780e]{background:#ffffffa6;border-radius:999px;padding:8px 12px}.storage-scroll[data-v-4593780e]{gap:7px;max-height:520px;padding:2px;display:grid;overflow:auto}.storage-row[data-v-4593780e]{cursor:pointer;background:#ffffff7a;border:1px solid #ffffffbf;border-radius:16px;align-items:center;gap:12px;min-width:0;padding:10px 12px;display:flex}.storage-row.protected[data-v-4593780e]{opacity:.7;cursor:default}.storage-item[data-v-4593780e]{flex:1;gap:3px;min-width:0;display:grid}.storage-item strong[data-v-4593780e]{text-overflow:ellipsis;white-space:nowrap;font-size:12px;overflow:hidden}.storage-item small[data-v-4593780e]{color:var(--ink-soft);font-size:11px}.storage-row>b[data-v-4593780e]{white-space:nowrap;color:var(--accent);font-size:12px}.storage-footer[data-v-4593780e]{color:var(--ink-soft);flex-wrap:wrap;justify-content:space-between;align-items:center;gap:10px;padding-top:18px;font-size:12px;display:flex}.storage-error[data-v-4593780e]{color:var(--danger);overflow-wrap:anywhere}@media (width<=900px){.storage-grid[data-v-4593780e]{grid-template-columns:minmax(0,1fr)}}@media (width<=560px){.storage-row[data-v-4593780e]{flex-wrap:wrap;align-items:flex-start}.storage-row>b[data-v-4593780e]{margin-left:26px}.storage-metrics>div[data-v-4593780e]{flex:1;min-width:130px}}.password-settings[data-v-36cd9f70]{margin-top:24px}form[data-v-36cd9f70]{gap:16px;max-width:520px;display:grid}label[data-v-36cd9f70]{gap:8px;display:grid}input[data-v-36cd9f70]{box-sizing:border-box;width:100%}.update-settings[data-v-950f6f7a]{gap:14px;display:grid}header[data-v-950f6f7a]{flex-wrap:wrap;justify-content:space-between;align-items:center;gap:14px;display:flex}h2[data-v-950f6f7a]{margin-top:5px}.version-state[data-v-950f6f7a]{font-weight:700}.version-state.available[data-v-950f6f7a]{color:var(--accent)}.small-text[data-v-950f6f7a]{font-size:12px}.update-how[data-v-950f6f7a]{border:1px solid var(--line);background:var(--surface);border-radius:18px;padding:14px}code[data-v-950f6f7a]{white-space:pre-wrap;overflow-wrap:anywhere;margin-top:9px;display:block}.update-links[data-v-950f6f7a]{gap:18px;font-size:13px;display:flex}.system[data-v-a12a372e]{gap:var(--gap);display:grid}.system-intro[data-v-a12a372e]{background:radial-gradient(ellipse at 90% 7%, color-mix(in srgb, var(--glow-a) 48%, transparent), transparent 51%), radial-gradient(ellipse at 62% 115%, color-mix(in srgb, var(--glow-b) 38%, transparent), transparent 55%), linear-gradient(115deg, #fffc, #ffffff4d);min-height:190px;box-shadow:inset 0 2px 0 white, 0 25px 54px -35px color-mix(in srgb, var(--accent) 43%, transparent);-webkit-backdrop-filter:blur(28px)saturate(1.8);backdrop-filter:blur(28px)saturate(1.8);border:1px solid #ffffffd9;border-radius:36px;flex-wrap:wrap;justify-content:space-between;align-items:end;gap:20px;padding:32px clamp(26px,5vw,60px);display:flex;position:relative;overflow:hidden}.system-intro[data-v-a12a372e]:before{content:"";width:350px;height:350px;box-shadow:0 0 0 29px #ffffff21, 0 0 0 58px color-mix(in srgb, var(--glow-b) 12%, transparent);pointer-events:none;border:1px solid #ffffffb8;border-radius:50%;animation:10s ease-in-out infinite alternate system-bob-a12a372e;position:absolute;top:-85%;right:13%}.system-intro h1[data-v-a12a372e]{letter-spacing:-.055em;margin:10px 0 7px;font-size:clamp(28px,3.25vw,42px)}.system-intro h1 em[data-v-a12a372e]{color:var(--accent);font-style:normal}.system-intro p[data-v-a12a372e]{max-width:560px;color:var(--ink-soft);font-size:13.5px;position:relative}.system-status[data-v-a12a372e]{z-index:1;box-shadow:inset 0 1px 0 white, 0 7px 19px -15px var(--accent);white-space:nowrap;-webkit-backdrop-filter:blur(20px);backdrop-filter:blur(20px);background:#ffffff87;border:1px solid #fff;border-radius:999px;align-items:center;gap:9px;padding:10px 16px;font-size:12.5px;font-weight:700;display:inline-flex}.system-status i[data-v-a12a372e]{background:var(--ok);width:9px;height:9px;box-shadow:0 0 0 4px color-mix(in srgb, var(--ok) 18%, transparent);border-radius:50%;animation:2.6s ease-in-out infinite pulse-soft}.system-status i.off[data-v-a12a372e]{background:var(--ink-faint);box-shadow:0 0 0 4px color-mix(in srgb, var(--ink-faint) 14%, transparent);animation:none}.system>.tabs[data-v-a12a372e]{box-shadow:inset 0 1px 0 white, 0 10px 30px -24px var(--accent);-webkit-backdrop-filter:blur(22px)saturate(1.7);backdrop-filter:blur(22px)saturate(1.7);border:1px solid #fffc;justify-self:start;padding:5px}.system[data-v-a12a372e]>.tabs button{transition:transform .35s var(--spring), background-color .2s, box-shadow .2s;border-radius:999px;padding:9px 18px}.system[data-v-a12a372e]>.tabs button:hover{transform:translateY(-2px)scale(1.03)}.system[data-v-a12a372e] .connect .step,.system[data-v-a12a372e] .connect .checks li{background:linear-gradient(145deg, #ffffffad, #ffffff47), var(--surface);box-shadow:inset 0 1px 0 white, 0 12px 24px -24px var(--accent);-webkit-backdrop-filter:blur(18px)saturate(1.55);backdrop-filter:blur(18px)saturate(1.55);transition:transform .35s var(--spring), box-shadow .25s;border:1px solid #ffffffd9;border-radius:22px}.system[data-v-a12a372e] .connect .step:hover,.system[data-v-a12a372e] .connect .checks li:hover{box-shadow:inset 0 1px 0 white, 0 16px 28px -21px var(--accent);transform:translateY(-3px)}.system[data-v-a12a372e] .connect .num{background:linear-gradient(145deg, white, color-mix(in srgb, var(--glow-a) 75%, white));box-shadow:inset 0 1px 0 white, 0 5px 14px -9px var(--accent);color:var(--accent);border:1px solid #fff}@keyframes system-bob-a12a372e{to{transform:translateY(22px)scale(1.08)}}@media (width<=760px){.system-intro[data-v-a12a372e]{min-height:0;padding:27px 23px}}
1
+ .connect[data-v-6f4553ed]{gap:var(--gap);grid-template-columns:minmax(0,1.25fr) minmax(290px,.9fr);align-items:start;display:grid}.connection[data-v-6f4553ed]{gap:20px;display:grid}.connection-details[data-v-6f4553ed]{gap:10px;display:grid}.detail[data-v-6f4553ed]{border:1px solid var(--line);background:color-mix(in srgb, var(--surface-strong) 70%, transparent);border-radius:14px;flex-wrap:wrap;justify-content:space-between;align-items:center;gap:8px 16px;padding:13px 16px;display:flex}.detail code[data-v-6f4553ed]{overflow-wrap:anywhere}.warn-text[data-v-6f4553ed]{color:var(--warn);overflow-wrap:anywhere}.instructions[data-v-6f4553ed]{gap:11px;margin:0;padding-left:22px;line-height:1.65;display:grid}.notes[data-v-6f4553ed]{gap:8px;margin:0;padding-left:20px;font-size:13px;line-height:1.6;display:grid}.note[data-v-6f4553ed]{margin:-8px 0 0;font-size:12px}.checks[data-v-6f4553ed]{gap:8px;margin:0;padding:0;list-style:none;display:grid}.checks li[data-v-6f4553ed]{background:color-mix(in srgb, var(--surface-strong) 70%, transparent);border:1px solid var(--line);border-radius:14px;align-items:center;gap:12px;padding:10px 12px;display:flex}.checks li>div[data-v-6f4553ed]{flex:1;min-width:0;display:grid}.checks small[data-v-6f4553ed]{font-size:12px}.mark[data-v-6f4553ed]{border:2px solid var(--line);border-radius:50%;flex:none;place-items:center;width:22px;height:22px;font-size:11px;font-weight:700;display:grid}.done .mark[data-v-6f4553ed]{border-color:var(--ok);background:var(--ok);color:var(--accent-ink)}@media (width<=1000px){.connect[data-v-6f4553ed]{grid-template-columns:minmax(0,1fr)}}.embedding-profile[data-v-6873efbb]{min-width:0}.fields[data-v-6873efbb]{grid-template-columns:repeat(auto-fit,minmax(min(220px,100%),1fr));gap:14px;margin:16px 0;display:grid}.save-bar[data-v-6873efbb]{position:relative;bottom:auto}.library[data-v-59f18516]{gap:var(--gap);grid-template-columns:minmax(0,1fr);display:grid}.model-workspace[data-v-59f18516]{gap:var(--gap);grid-template-columns:minmax(260px,.32fr) minmax(0,1fr);align-items:start;display:grid}.shelf[data-v-59f18516]{background:radial-gradient(ellipse at 0 0, color-mix(in srgb, var(--glow-a) 23%, transparent), transparent 56%), var(--surface);gap:15px;display:grid;position:sticky;top:14px}.detail[data-v-59f18516]{background:radial-gradient(ellipse at 100% 0, color-mix(in srgb, var(--glow-b) 16%, transparent), transparent 47%), var(--surface)}.usage-panel[data-v-59f18516]{background:radial-gradient(ellipse at 100% 0, color-mix(in srgb, var(--glow-a) 25%, transparent), transparent 42%), radial-gradient(ellipse at 0 100%, color-mix(in srgb, var(--glow-b) 20%, transparent), transparent 46%), var(--surface);grid-column:1/-1;gap:18px;display:grid;overflow:hidden}.usage-intro[data-v-59f18516]{justify-content:space-between;align-items:end;gap:20px;display:flex}.usage-intro h2[data-v-59f18516]{letter-spacing:-.04em;margin:5px 0 4px;font-size:22px}.usage-intro p[data-v-59f18516],.usage-foot small[data-v-59f18516]{color:var(--ink-soft);font-size:12px}.usage-total[data-v-59f18516]{flex:none;justify-items:end;display:grid}.usage-total strong[data-v-59f18516]{color:var(--accent);font:700 clamp(28px, 4vw, 42px) var(--font-display);letter-spacing:-.055em;font-variant-numeric:tabular-nums;line-height:1.05}.usage-total span[data-v-59f18516]{color:var(--ink-soft);font-size:12px}.usage-detail[data-v-59f18516]{grid-template-columns:repeat(4,minmax(0,1fr));gap:10px;display:grid}.usage-stat[data-v-59f18516]{background:#ffffff5c;border:1px solid #ffffffc7;border-radius:18px;gap:5px;min-width:0;padding:14px 16px;display:grid;box-shadow:inset 0 1px #fff}.usage-stat span[data-v-59f18516]{color:var(--ink-soft);font-size:12px}.usage-stat span small[data-v-59f18516]{font-size:10px}.usage-stat b[data-v-59f18516]{font-variant-numeric:tabular-nums;text-overflow:ellipsis;font-size:19px;overflow:hidden}.usage-foot[data-v-59f18516]{flex-wrap:wrap;justify-content:space-between;align-items:center;gap:10px;display:flex}.usage-error[data-v-59f18516]{color:var(--danger)!important}.usage-refresh[data-v-59f18516]{color:var(--accent);font-size:12px}.shelf-head[data-v-59f18516]{justify-content:space-between;align-items:center;gap:8px;display:flex}.shelf-head h2[data-v-59f18516]{letter-spacing:-.04em;font-size:21px}.shelf-head small[data-v-59f18516]{color:var(--ink-soft);font-size:12px}.rows[data-v-59f18516]{gap:8px;max-height:520px;display:grid;overflow:auto}.saved-vendor[data-v-59f18516]{background:#fff3;border:1px solid #ffffffad;border-radius:17px;overflow:hidden;box-shadow:inset 0 1px #ffffffb8}.saved-vendor>summary[data-v-59f18516]{color:var(--ink);cursor:pointer;justify-content:space-between;align-items:center;gap:8px;padding:11px 13px;font-size:12px;font-weight:700;list-style:none;display:flex}.saved-vendor>summary[data-v-59f18516]::-webkit-details-marker{display:none}.vendor-summary[data-v-59f18516]::-webkit-details-marker{display:none}.saved-vendor>summary[data-v-59f18516]:after{color:var(--accent);content:"⌄";transition:transform .24s var(--spring);font-size:15px}.saved-vendor[open]>summary[data-v-59f18516]{background:#ffffff40;border-bottom:1px solid #fff9}.saved-vendor[open]>summary[data-v-59f18516]:after{transform:rotate(180deg)}.saved-vendor>summary small[data-v-59f18516]{color:var(--ink-soft);margin-left:auto;font-size:10px;font-weight:500}.vendor-models[data-v-59f18516]{gap:6px;padding:7px;display:grid}.entity-row[data-v-59f18516]{text-align:left;-webkit-backdrop-filter:blur(16px)saturate(1.5);backdrop-filter:blur(16px)saturate(1.5);width:100%;transition:transform .32s var(--spring), background-color .2s, box-shadow .25s;background:#ffffff5c;border:1px solid #ffffffbf;border-radius:18px;align-items:center;gap:10px;padding:11px 12px;display:flex;box-shadow:inset 0 1px #fff}.entity-row[data-v-59f18516]:hover:not(:disabled){box-shadow:0 12px 22px -19px var(--accent);background:#ffffffa8;transform:translate(4px)scale(1.01)}.entity-row.selected[data-v-59f18516]{border-color:color-mix(in srgb, var(--accent) 22%, white);background:linear-gradient(115deg, white, color-mix(in srgb, var(--accent-soft) 60%, white));box-shadow:inset 0 1px 0 white, 0 13px 23px -20px var(--accent)}.badge[data-v-59f18516]{background:linear-gradient(145deg, white, hsl(var(--hue) 70% 88%));width:36px;height:36px;color:hsl(var(--hue) 45% 25%);box-shadow:inset 0 1px 0 white, 0 5px 13px -10px hsl(var(--hue) 45% 32%);border-radius:14px;flex:none;place-items:center;font-weight:700;display:grid}.who[data-v-59f18516]{min-width:0;line-height:1.35;display:grid}.who b[data-v-59f18516]{text-overflow:ellipsis;white-space:nowrap;font-size:13.5px;overflow:hidden}.who small[data-v-59f18516]{color:var(--ink-soft);font-size:11.5px;font-weight:500}fieldset[data-v-59f18516]{background:linear-gradient(142deg, #ffffffa1, #ffffff47), var(--surface);box-shadow:inset 0 1px 0 white, 0 14px 30px -27px var(--accent);-webkit-backdrop-filter:blur(20px)saturate(1.6);backdrop-filter:blur(20px)saturate(1.6);border:1px solid #ffffffcf;border-radius:24px;gap:10px;margin:0;padding:20px;display:grid}legend[data-v-59f18516]{padding:0 8px;font-size:13px;font-weight:700}.advanced summary[data-v-59f18516]{color:var(--accent);transition:transform .3s var(--spring), background-color .2s;background:#ffffff6b;border:1px solid #fffc;border-radius:14px;padding:12px 15px;font-weight:600;box-shadow:inset 0 1px #fff}.advanced summary[data-v-59f18516]:hover{background:#ffffffa6;transform:translate(3px)}.advanced[open] summary[data-v-59f18516]{margin-bottom:12px}.caps[data-v-59f18516]{flex-wrap:wrap;gap:8px 18px;margin-top:10px;display:flex}.actions[data-v-59f18516]{flex-wrap:wrap;gap:8px;display:flex}.actions .push[data-v-59f18516]{margin-left:auto}.model-picker[data-v-59f18516]{gap:16px;display:grid}.catalog-search[data-v-59f18516]{color:var(--ink-soft);gap:6px;font-size:12px;font-weight:600;display:grid}.catalog-search input[data-v-59f18516]{width:100%;min-height:42px;color:var(--ink);-webkit-backdrop-filter:blur(14px)saturate(1.4);backdrop-filter:blur(14px)saturate(1.4);background:#ffffff9e;border:1px solid #ffffffd9;border-radius:14px;outline:none;padding:0 13px;box-shadow:inset 0 1px #fff}.catalog-search input[data-v-59f18516]:focus{border-color:color-mix(in srgb, var(--accent) 42%, white);box-shadow:0 0 0 3px color-mix(in srgb, var(--accent) 10%, transparent)}.vendor[data-v-59f18516]{background:radial-gradient(ellipse at 100% 0, color-mix(in srgb, var(--glow-a) 13%, transparent), transparent 48%), #ffffff3b;-webkit-backdrop-filter:blur(18px)saturate(1.35);backdrop-filter:blur(18px)saturate(1.35);border:1px solid #ffffffb8;border-radius:21px;overflow:hidden;box-shadow:inset 0 1px #ffffffc7}.vendor-summary[data-v-59f18516]{cursor:pointer;justify-content:space-between;align-items:center;gap:12px;min-height:62px;padding:12px 17px;list-style:none;transition:background-color .2s;display:flex}.vendor-summary[data-v-59f18516]:hover{background:#ffffff57}.vendor-name[data-v-59f18516]{align-items:center;gap:10px;min-width:0;display:flex}.vendor-name b[data-v-59f18516]{font-size:13px}.vendor-name small[data-v-59f18516]{color:var(--ink-soft);font-size:10px}.vendor-chevron[data-v-59f18516]{color:var(--accent);transition:transform .28s var(--spring);font-size:20px;line-height:1}.vendor[open] .vendor-chevron[data-v-59f18516]{transform:rotate(180deg)}.vendor[open] .presets[data-v-59f18516]{animation:vendor-reveal-59f18516 .24s var(--spring) both}@keyframes vendor-reveal-59f18516{0%{opacity:0;transform:translateY(-5px)}to{opacity:1;transform:translateY(0)}}.search-empty[data-v-59f18516]{margin:0}.presets[data-v-59f18516]{grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:8px;padding:0 12px 12px;display:grid}.preset-card[data-v-59f18516]{background:radial-gradient(ellipse at 100% 0, color-mix(in srgb, var(--glow-a) 22%, transparent), transparent 55%), #ffffff80;box-shadow:inset 0 1px 0 white, 0 12px 22px -20px var(--accent);text-align:left;-webkit-backdrop-filter:blur(16px)saturate(1.5);backdrop-filter:blur(16px)saturate(1.5);transition:transform .42s var(--spring), box-shadow .25s;border:1px solid #ffffffd1;border-radius:21px;justify-items:start;gap:3px;padding:17px;font-weight:500;display:grid}.preset-card[data-v-59f18516]:hover:not(:disabled){box-shadow:inset 0 1px 0 white, 0 22px 33px -22px var(--accent);transform:translateY(-6px)rotate(-.5deg)scale(1.025)}.preset-card small[data-v-59f18516]{color:var(--ink-soft);font-size:11.5px}@media (width<=900px){.model-workspace[data-v-59f18516]{grid-template-columns:minmax(0,1fr)}.usage-panel[data-v-59f18516]{grid-column:auto}.shelf[data-v-59f18516]{position:static}}@media (width<=620px){.usage-intro[data-v-59f18516]{flex-direction:column;align-items:start}.usage-total[data-v-59f18516]{justify-items:start}.usage-detail[data-v-59f18516]{grid-template-columns:repeat(2,minmax(0,1fr))}}.runtime-grid[data-v-1f197523]{gap:var(--gap);grid-template-columns:minmax(0,1.55fr) minmax(260px,.8fr);align-items:start;display:grid}.runtime-grid>.card[data-v-1f197523]{background:radial-gradient(ellipse at 90% 0, color-mix(in srgb, var(--glow-a) 20%, transparent), transparent 55%), var(--surface)}.runtime-grid .card-head h2[data-v-1f197523]{letter-spacing:-.035em;margin-top:5px;font-size:23px}.switches[data-v-1f197523]{gap:12px;margin-bottom:20px;display:grid}.switches[data-v-1f197523] .switch{box-shadow:inset 0 1px 0 white, 0 10px 22px -23px var(--accent);-webkit-backdrop-filter:blur(18px)saturate(1.5);backdrop-filter:blur(18px)saturate(1.5);transition:transform .35s var(--spring), background-color .2s;background:#ffffff69;border:1px solid #ffffffc7;border-radius:22px;align-items:flex-start;padding:18px}.switches[data-v-1f197523] .switch:hover{background:#ffffffa3;transform:translateY(-3px)scale(1.008)}.switches[data-v-1f197523] .switch>span{gap:2px;display:grid}.switches small[data-v-1f197523]{color:var(--ink-soft);font-size:12.5px;font-weight:400}.numbers[data-v-1f197523]{gap:12px;display:grid}.numbers button[data-v-1f197523],.numbers .stat[data-v-1f197523]{background:radial-gradient(ellipse at 100% 0, color-mix(in srgb, var(--glow-b) 24%, transparent), transparent 63%), #ffffff70;box-shadow:inset 0 1px 0 white, 0 12px 26px -24px var(--accent);text-align:left;-webkit-backdrop-filter:blur(18px)saturate(1.55);backdrop-filter:blur(18px)saturate(1.55);transition:transform .38s var(--spring), box-shadow .23s;border:1px solid #ffffffd4;border-radius:22px;justify-items:start;gap:2px;padding:20px 21px;display:grid}.numbers button[data-v-1f197523]:hover:not(:disabled){box-shadow:inset 0 1px 0 white, 0 18px 28px -22px var(--accent);transform:translate(5px)scale(1.018)}.numbers b[data-v-1f197523]{font:750 29px var(--font-display);color:var(--accent)}.numbers .stat.warn b[data-v-1f197523]{color:var(--warn)}.numbers .stat.danger b[data-v-1f197523]{color:var(--danger)}.numbers span[data-v-1f197523]{color:var(--ink-soft);font-size:12.5px;font-weight:500}@media (width<=900px){.runtime-grid[data-v-1f197523]{grid-template-columns:minmax(0,1fr)}}.search-profile[data-v-e874d8b6]{gap:16px;min-width:0;display:grid}.search-profile form[data-v-e874d8b6]{gap:18px;display:grid}.search-fields[data-v-e874d8b6]{grid-template-columns:repeat(2,minmax(0,1fr));gap:16px;display:grid}.search-fields label[data-v-e874d8b6]{gap:8px;min-width:0;display:grid}.search-fields input[data-v-e874d8b6],.search-fields .menu-select[data-v-e874d8b6]{width:100%;min-width:0}.search-usage[data-v-e874d8b6]{flex-wrap:wrap;align-items:center;gap:12px;display:flex}.search-result[data-v-e874d8b6]{border:1px solid var(--line);background:var(--surface);overflow-wrap:anywhere;border-radius:16px;padding:14px 16px}.search-result.failed[data-v-e874d8b6]{border-color:color-mix(in srgb, var(--warn) 40%, var(--line))}@media (width<=620px){.search-fields[data-v-e874d8b6]{grid-template-columns:minmax(0,1fr)}}.data-transfer[data-v-ea16c0c1]{min-width:0}.data-transfer h2[data-v-ea16c0c1]{margin:8px 0 14px;font-size:clamp(23px,3vw,32px)}.transfer-note[data-v-ea16c0c1]{color:var(--ink-soft);overflow-wrap:anywhere;font-size:13px;line-height:1.7}.transfer-actions[data-v-ea16c0c1]{flex-wrap:wrap;gap:10px;margin:18px 0;display:flex}.transfer-actions button[data-v-ea16c0c1]{border-radius:16px;padding:11px 17px}.transfer-actions button[data-v-ea16c0c1]:not(.primary){background:#ffffffb8}.transfer-file[data-v-ea16c0c1]{display:none}.transfer-preview[data-v-ea16c0c1]{overflow-wrap:anywhere;background:#fff6;border:1px solid #ffffffd9;border-radius:22px;margin-top:20px;padding:20px}.transfer-preview h3[data-v-ea16c0c1]{margin:8px 0}.transfer-counts[data-v-ea16c0c1]{flex-wrap:wrap;gap:10px;display:flex}.transfer-counts>div[data-v-ea16c0c1]{background:#ffffffa6;border-radius:14px;gap:4px;min-width:70px;padding:12px;display:grid}.transfer-counts b[data-v-ea16c0c1],.transfer-progress[data-v-ea16c0c1]{color:var(--accent)}.transfer-counts span[data-v-ea16c0c1]{color:var(--ink-soft);font-size:12px}.transfer-error[data-v-ea16c0c1]{color:var(--danger);overflow-wrap:anywhere}.storage-page[data-v-4593780e]{gap:var(--gap);display:grid}.storage-page>.card[data-v-4593780e],.storage-grid>.card[data-v-4593780e]{background:radial-gradient(ellipse at 100% 0, color-mix(in srgb, var(--glow-a) 20%, transparent), transparent 60%), var(--surface)}.storage-overview h2[data-v-4593780e]{margin:8px 0;font-size:clamp(24px,3vw,36px)}.storage-overview p[data-v-4593780e],.storage-note[data-v-4593780e]{color:var(--ink-soft);font-size:13px;line-height:1.65}.storage-metrics[data-v-4593780e]{flex-wrap:wrap;gap:12px;margin-top:22px;display:flex}.storage-metrics>div[data-v-4593780e]{background:#ffffff6b;border:1px solid #fffc;border-radius:18px;gap:3px;min-width:150px;padding:15px 20px;display:grid}.storage-metrics b[data-v-4593780e]{color:var(--accent);font-size:23px}.storage-metrics span[data-v-4593780e]{color:var(--ink-soft);font-size:12px}.storage-grid[data-v-4593780e]{gap:var(--gap);grid-template-columns:minmax(270px,.8fr) minmax(0,1.5fr);align-items:start;display:grid}.storage-grid .card-head h2[data-v-4593780e]{margin:4px 0 16px;font-size:23px}.storage-check[data-v-4593780e]{align-items:center;gap:9px;margin-bottom:16px;display:flex}.storage-fields[data-v-4593780e]{gap:13px;display:grid}.storage-fields label[data-v-4593780e]{color:var(--ink-soft);gap:6px;font-size:12px;font-weight:700;display:grid}.storage-fields input[data-v-4593780e]{border:1px solid color-mix(in srgb, var(--accent) 25%, white);width:100%;min-width:0;color:var(--ink);background:#ffffffb3;border-radius:15px;padding:11px 13px}.storage-policy .primary[data-v-4593780e]{margin-top:14px}.storage-actions[data-v-4593780e]{flex-wrap:wrap;gap:8px;margin:16px 0;display:flex}.storage-actions button[data-v-4593780e]{background:#ffffffa6;border-radius:999px;padding:8px 12px}.storage-scroll[data-v-4593780e]{gap:7px;max-height:520px;padding:2px;display:grid;overflow:auto}.storage-row[data-v-4593780e]{cursor:pointer;background:#ffffff7a;border:1px solid #ffffffbf;border-radius:16px;align-items:center;gap:12px;min-width:0;padding:10px 12px;display:flex}.storage-row.protected[data-v-4593780e]{opacity:.7;cursor:default}.storage-item[data-v-4593780e]{flex:1;gap:3px;min-width:0;display:grid}.storage-item strong[data-v-4593780e]{text-overflow:ellipsis;white-space:nowrap;font-size:12px;overflow:hidden}.storage-item small[data-v-4593780e]{color:var(--ink-soft);font-size:11px}.storage-row>b[data-v-4593780e]{white-space:nowrap;color:var(--accent);font-size:12px}.storage-footer[data-v-4593780e]{color:var(--ink-soft);flex-wrap:wrap;justify-content:space-between;align-items:center;gap:10px;padding-top:18px;font-size:12px;display:flex}.storage-error[data-v-4593780e]{color:var(--danger);overflow-wrap:anywhere}@media (width<=900px){.storage-grid[data-v-4593780e]{grid-template-columns:minmax(0,1fr)}}@media (width<=560px){.storage-row[data-v-4593780e]{flex-wrap:wrap;align-items:flex-start}.storage-row>b[data-v-4593780e]{margin-left:26px}.storage-metrics>div[data-v-4593780e]{flex:1;min-width:130px}}.password-settings[data-v-36cd9f70]{margin-top:24px}form[data-v-36cd9f70]{gap:16px;max-width:520px;display:grid}label[data-v-36cd9f70]{gap:8px;display:grid}input[data-v-36cd9f70]{box-sizing:border-box;width:100%}.update-settings[data-v-0df58391]{gap:14px;display:grid}header[data-v-0df58391]{flex-wrap:wrap;justify-content:space-between;align-items:center;gap:14px;display:flex}h2[data-v-0df58391]{margin-top:5px}.version-state[data-v-0df58391]{font-weight:700}.version-state.available[data-v-0df58391]{color:var(--accent)}.small-text[data-v-0df58391]{font-size:12px}.update-how[data-v-0df58391]{border:1px solid var(--line);background:var(--surface);border-radius:18px;padding:14px}code[data-v-0df58391]{white-space:pre-wrap;overflow-wrap:anywhere;margin-top:9px;display:block}.update-links[data-v-0df58391]{gap:18px;font-size:13px;display:flex}.system[data-v-a12a372e]{gap:var(--gap);display:grid}.system-intro[data-v-a12a372e]{background:radial-gradient(ellipse at 90% 7%, color-mix(in srgb, var(--glow-a) 48%, transparent), transparent 51%), radial-gradient(ellipse at 62% 115%, color-mix(in srgb, var(--glow-b) 38%, transparent), transparent 55%), linear-gradient(115deg, #fffc, #ffffff4d);min-height:190px;box-shadow:inset 0 2px 0 white, 0 25px 54px -35px color-mix(in srgb, var(--accent) 43%, transparent);-webkit-backdrop-filter:blur(28px)saturate(1.8);backdrop-filter:blur(28px)saturate(1.8);border:1px solid #ffffffd9;border-radius:36px;flex-wrap:wrap;justify-content:space-between;align-items:end;gap:20px;padding:32px clamp(26px,5vw,60px);display:flex;position:relative;overflow:hidden}.system-intro[data-v-a12a372e]:before{content:"";width:350px;height:350px;box-shadow:0 0 0 29px #ffffff21, 0 0 0 58px color-mix(in srgb, var(--glow-b) 12%, transparent);pointer-events:none;border:1px solid #ffffffb8;border-radius:50%;animation:10s ease-in-out infinite alternate system-bob-a12a372e;position:absolute;top:-85%;right:13%}.system-intro h1[data-v-a12a372e]{letter-spacing:-.055em;margin:10px 0 7px;font-size:clamp(28px,3.25vw,42px)}.system-intro h1 em[data-v-a12a372e]{color:var(--accent);font-style:normal}.system-intro p[data-v-a12a372e]{max-width:560px;color:var(--ink-soft);font-size:13.5px;position:relative}.system-status[data-v-a12a372e]{z-index:1;box-shadow:inset 0 1px 0 white, 0 7px 19px -15px var(--accent);white-space:nowrap;-webkit-backdrop-filter:blur(20px);backdrop-filter:blur(20px);background:#ffffff87;border:1px solid #fff;border-radius:999px;align-items:center;gap:9px;padding:10px 16px;font-size:12.5px;font-weight:700;display:inline-flex}.system-status i[data-v-a12a372e]{background:var(--ok);width:9px;height:9px;box-shadow:0 0 0 4px color-mix(in srgb, var(--ok) 18%, transparent);border-radius:50%;animation:2.6s ease-in-out infinite pulse-soft}.system-status i.off[data-v-a12a372e]{background:var(--ink-faint);box-shadow:0 0 0 4px color-mix(in srgb, var(--ink-faint) 14%, transparent);animation:none}.system>.tabs[data-v-a12a372e]{box-shadow:inset 0 1px 0 white, 0 10px 30px -24px var(--accent);-webkit-backdrop-filter:blur(22px)saturate(1.7);backdrop-filter:blur(22px)saturate(1.7);border:1px solid #fffc;justify-self:start;padding:5px}.system[data-v-a12a372e]>.tabs button{transition:transform .35s var(--spring), background-color .2s, box-shadow .2s;border-radius:999px;padding:9px 18px}.system[data-v-a12a372e]>.tabs button:hover{transform:translateY(-2px)scale(1.03)}.system[data-v-a12a372e] .connect .step,.system[data-v-a12a372e] .connect .checks li{background:linear-gradient(145deg, #ffffffad, #ffffff47), var(--surface);box-shadow:inset 0 1px 0 white, 0 12px 24px -24px var(--accent);-webkit-backdrop-filter:blur(18px)saturate(1.55);backdrop-filter:blur(18px)saturate(1.55);transition:transform .35s var(--spring), box-shadow .25s;border:1px solid #ffffffd9;border-radius:22px}.system[data-v-a12a372e] .connect .step:hover,.system[data-v-a12a372e] .connect .checks li:hover{box-shadow:inset 0 1px 0 white, 0 16px 28px -21px var(--accent);transform:translateY(-3px)}.system[data-v-a12a372e] .connect .num{background:linear-gradient(145deg, white, color-mix(in srgb, var(--glow-a) 75%, white));box-shadow:inset 0 1px 0 white, 0 5px 14px -9px var(--accent);color:var(--accent);border:1px solid #fff}@keyframes system-bob-a12a372e{to{transform:translateY(22px)scale(1.08)}}@media (width<=760px){.system-intro[data-v-a12a372e]{min-height:0;padding:27px 23px}}
@@ -1 +1 @@
1
- import{$ as e,Ct as t,E as n,Et as r,I as i,J as a,M as o,N as s,P as c,S as l,T as u,Tt as d,U as f,V as p,W as m,X as h,Y as g,Z as _,a as v,b as y,bt as b,ct as x,dt as S,et as C,f as w,ft as T,gt as E,h as D,ht as O,i as k,j as A,lt as j,m as M,n as N,nt as P,o as F,ot as I,p as L,q as R,rt as z,s as B,t as ee,ut as V,v as H,vt as U,w as W,wt as G,xt as K,yt as q,z as J}from"./Empty-CLyZkxR5.js";import{v as te}from"./mind-Dtiw0-QK.js";import{c as Y,f as ne,l as re,n as X,o as ie}from"./index-DdYwC5ZU.js";var ae={class:`connect`},oe={class:`card connection`},Z={class:`card-head`},Q={class:`eyebrow`},se={class:`pill`},ce={key:0,class:`notice`,role:`note`},le={class:`muted`},ue={class:`connection-details`},de={class:`detail`},fe={class:`instructions`},pe={class:`muted`},me={class:`muted note`},$={key:0,class:`row`},he=[`disabled`],ge={class:`muted`},_e=[`disabled`,`placeholder`],ve={key:0,class:`faint`},ye=[`disabled`,`placeholder`],be={key:0,class:`faint`},xe={class:`row`},Se=[`disabled`],Ce={key:0,class:`faint`},we={key:0,class:`connection-details`},Te={class:`detail`},Ee={"data-state":``},De={key:0,class:`detail`},Oe={class:`warn-text`},ke={key:1,class:`detail`},Ae={class:`detail`},je={class:`detail`},Me={key:1,class:`notice`,role:`note`},Ne={class:`instructions`},Pe={class:`muted notes`},Fe={class:`card checklist`},Ie={class:`card-head`},Le={class:`eyebrow`},Re={class:`chip`},ze={class:`checks`},Be={class:`mark`,"aria-hidden":`true`},Ve={class:`muted`},He=[`data-fix`,`onClick`],Ue=N(P({__name:`ConnectQQ`,emits:[`open`],setup(o,{emit:s}){let l=s,u=R(()=>B.health.connection||{}),d=R(()=>u.value.channel===`qqbot`?`qqbot`:`onebot`),g=R(()=>!!u.value.locked),y=R(()=>!!u.value.online);R(()=>u.value.onebot||{});let x=R(()=>u.value.qqbot||{}),w=R(()=>String(B.health.settings.qqbotAppId||``)),T=R(()=>!!B.health.settings.hasQqbotSecret),D=K(d.value);E(d,e=>D.value=e);let O=R(()=>`${location.protocol===`https:`?`wss`:`ws`}://${location.host}/onebot/v11/ws`),N=R(()=>[{key:`onebot`,label:i(`OneBot 11`),count:d.value===`onebot`?i(`使用中`):``},{key:`qqbot`,label:i(`QQ 官方机器人`),count:d.value===`qqbot`?i(`使用中`):``}]),P=b({appId:w.value,secret:``}),F=K(!1),I=R(()=>P.appId.trim()!==w.value||!!P.secret.trim());E(I,e=>{B.dirty=e}),E(w,e=>{I.value||(P.appId=e)}),j(()=>{B.dirty=!1});let L=R(()=>!!P.appId.trim()&&(T.value||!!P.secret.trim())),z=c({idle:A(`未启用`),unconfigured:A(`尚未填写 AppID 与 AppSecret`),connecting:A(`正在连接开放平台`),ready:A(`已连接`),closed:A(`连接已断开,正在重连`),error:A(`连接出错`)}),ee=c({all:A(`全部群消息`),mentions:A(`只有 @ 她的消息`),unknown:A(`尚未收到群消息`)}),U=R(()=>z[x.value.state||`idle`]??z.idle),W=R(()=>ee[x.value.groupMessages||`unknown`]??ee.unknown),J=R(()=>d.value===`qqbot`&&x.value.groupMessages===`mentions`);async function te(e){if(F.value||g.value||e===d.value)return;let t=i(e===`qqbot`?`QQ 官方机器人`:`OneBot 11`);if(!y.value||await n(i(`切换后会断开当前连接。原来方式下的会话仍可查看,但不能再向它们发送消息。`),{title:i(`切换连接方式`),confirmText:i(`切换`),cancelText:i(`先不切换`)})){F.value=!0;try{await M(`/settings`,`PATCH`,{channel:e}),await v(),H(i(`已切换为 {name}`,{name:t}))}catch(e){H(e.message,!0)}finally{F.value=!1}}}async function Y(){if(!F.value){if(!L.value){H(i(`请填写 AppID 和 AppSecret`),!0);return}F.value=!0;try{let e={qqbotAppId:P.appId.trim()};P.secret.trim()&&(e.qqbotSecret=P.secret.trim()),d.value!==`qqbot`&&!g.value&&(e.channel=`qqbot`),await M(`/settings`,`PATCH`,e),P.secret=``,await v(),H(i(`已保存`))}catch(e){H(e.message,!0)}finally{F.value=!1}}}let ne={token:[``,`connect`],credentials:[``,`connect`],qq:[``,`connect`],model:[``,`models`],mode:[``,`runtime`],session:[`chats`,``],persona:[`nature`,``]};function ie(e){let[t,n]=ne[e]||[``,`connect`];t?k(t):l(`open`,n)}return(n,o)=>(V(),_(`div`,ae,[a(`section`,oe,[a(`div`,Z,[a(`div`,null,[a(`span`,Q,r(t(i)(`QQ`)),1),a(`h2`,null,r(t(i)(`连接 QQ`)),1),a(`p`,null,r(t(i)(`两种连接方式二选一,同一时间只使用一种。她的记忆、心情和行为完全一致,区别只在消息怎么到达。`)),1)]),a(`span`,se,[a(`span`,{class:G([`dot`,{off:!y.value}])},null,2),e(` `+r(y.value?t(i)(`QQ 已连接`):t(i)(`等待连接`)),1)])]),C(X,{modelValue:D.value,"onUpdate:modelValue":o[0]||=e=>D.value=e,label:t(i)(`连接方式`),items:N.value},null,8,[`modelValue`,`label`,`items`]),g.value?(V(),_(`p`,ce,r(t(i)(`连接方式由环境变量 LUCKYTRI_CHANNEL 指定,在这里不能更改。去掉该变量后即可在此选择。`)),1)):h(``,!0),D.value===`onebot`?(V(),_(m,{key:1},[a(`p`,le,r(t(i)(`自备接入端,通过反向 WebSocket 连接。能看到全部群消息。`)),1),a(`div`,ue,[a(`div`,de,[a(`span`,null,r(t(i)(`反向 WebSocket 地址`)),1),a(`code`,null,r(O.value),1)])]),a(`ol`,fe,[a(`li`,null,r(t(i)(`同一台电脑上的接入端无需单独配置连接令牌。`)),1),a(`li`,null,r(t(i)(`在接入端启用反向 WebSocket 客户端,填写上方地址,消息格式选择数组。已有的地址配置可以继续使用。`)),1),a(`li`,null,r(t(i)(`在接入端完成 QQ 登录。连接成功后,本页状态会更新;新会话仍需在「对话」中开启参与。`)),1)]),a(`p`,pe,r(t(i)(`远程接入时,连接密码使用管理密码;已有的远程连接令牌仍兼容。`)),1),a(`p`,me,r(t(i)(`LuckyTri 只负责接收,不提供、不安装也不管理接入端。`)),1),d.value===`onebot`?h(``,!0):(V(),_(`div`,$,[a(`button`,{class:`primary`,"data-use":`onebot`,disabled:F.value||g.value,onClick:o[1]||=e=>te(`onebot`)},r(t(i)(`改用这种方式`)),9,he)]))],64)):(V(),_(m,{key:2},[a(`p`,ge,r(t(i)(`只需 AppID 与 AppSecret,无需额外软件。群里默认只收到 @ 她的消息。`)),1),a(`form`,{class:`stack tight`,onSubmit:f(Y,[`prevent`])},[a(`label`,null,[e(r(t(i)(`AppID`))+` `,1),q(a(`input`,{"onUpdate:modelValue":o[2]||=e=>P.appId=e,name:`qqbotAppId`,autocomplete:`off`,inputmode:`numeric`,maxlength:`40`,disabled:F.value||x.value.appIdFromEnv,placeholder:t(i)(`机器人的 AppID`)},null,8,_e),[[p,P.appId]]),x.value.appIdFromEnv?(V(),_(`small`,ve,r(t(i)(`由环境变量指定,在这里不能修改`)),1)):h(``,!0)]),a(`label`,null,[e(r(t(i)(`AppSecret`))+` `,1),q(a(`input`,{"onUpdate:modelValue":o[3]||=e=>P.secret=e,name:`qqbotSecret`,type:`password`,autocomplete:`new-password`,maxlength:`200`,disabled:F.value||x.value.secretFromEnv,placeholder:T.value||x.value.secretFromEnv?t(i)(`已保存,留空保留`):t(i)(`机器人的 AppSecret`)},null,8,ye),[[p,P.secret]]),x.value.secretFromEnv?(V(),_(`small`,be,r(t(i)(`由环境变量指定,在这里不能修改`)),1)):h(``,!0)]),a(`div`,xe,[a(`button`,{class:`primary`,"data-save":`qqbot`,disabled:F.value||x.value.appIdFromEnv&&x.value.secretFromEnv},r(d.value===`qqbot`||g.value?t(i)(`保存`):t(i)(`保存并使用`)),9,Se),I.value?(V(),_(`span`,Ce,r(t(i)(`有尚未保存的修改`)),1)):h(``,!0)])],32),d.value===`qqbot`?(V(),_(`div`,we,[a(`div`,Te,[a(`span`,null,r(t(i)(`连接状态`)),1),a(`strong`,Ee,r(U.value),1)]),x.value.error?(V(),_(`div`,De,[o[4]||=a(`span`,null,null,-1),a(`small`,Oe,r(x.value.error),1)])):h(``,!0),x.value.botName?(V(),_(`div`,ke,[a(`span`,null,r(t(i)(`机器人`)),1),a(`strong`,null,r(x.value.botName),1)])):h(``,!0),a(`div`,Ae,[a(`span`,null,r(t(i)(`最近收到消息`)),1),a(`strong`,null,r(x.value.lastEventAt?t(re)(x.value.lastEventAt):t(i)(`还没有`)),1)]),a(`div`,je,[a(`span`,null,r(t(i)(`群消息范围`)),1),a(`strong`,null,r(W.value),1)])])):h(``,!0),J.value?(V(),_(`p`,Me,r(t(i)(`目前只收到 @ 她的群消息。想让她看到群里的全部消息,请在开放平台的机器人设置里开启「接收所有消息」。`)),1)):h(``,!0),a(`ol`,Ne,[a(`li`,null,r(t(i)(`在 QQ 开放平台创建机器人,取得 AppID 与 AppSecret。`)),1),a(`li`,null,r(t(i)(`把运行 LuckyTri 的这台机器的出口 IP 加入机器人的 IP 白名单。`)),1),a(`li`,null,r(t(i)(`可选:开启「接收所有消息」,她才能看到群里没有 @ 她的话;不开启时只会收到 @ 她的消息。`)),1),a(`li`,null,r(t(i)(`填写上方的 AppID 与 AppSecret 并保存。状态变为「已连接」后,在群里 @ 她或私聊她,新会话会出现在「对话」中。`)),1)]),a(`ul`,Pe,[a(`li`,null,r(t(i)(`官方平台不提供群名称:新会话以占位名出现,可以在「对话」中为它改名。`)),1),a(`li`,null,r(t(i)(`官方平台上,同一个人在不同的群里标识不同。像只在不同的房间见过对方一样,平台给出统一身份之前,她不会把两处的人当成同一个人。`)),1),a(`li`,null,r(t(i)(`对方关闭了机器人的主动消息时,她不会去打扰,会等对方来找她。`)),1)])],64))]),a(`section`,Fe,[a(`div`,Ie,[a(`div`,null,[a(`span`,Le,r(t(i)(`就绪检查`)),1),a(`h2`,null,r(t(i)(`还差哪一步`)),1)]),a(`span`,Re,r(t(B).health.readiness?.completed??0)+` / `+r(t(B).health.readiness?.total??0),1)]),a(`ol`,ze,[(V(!0),_(m,null,S(t(B).health.readiness?.checks||[],e=>(V(),_(`li`,{key:e.id,class:G({done:e.done})},[a(`span`,Be,r(e.done?`✓`:``),1),a(`div`,null,[a(`b`,null,r(e.name),1),a(`small`,Ve,r(e.detail),1)]),a(`button`,{class:`small`,"data-fix":e.id,onClick:t=>ie(e.id)},r(e.done?t(i)(`查看`):t(i)(`去处理`)),9,He)],2))),128))])])]))}}),[[`__scopeId`,`data-v-6f4553ed`]]);async function We(e){return M(`/core/models`,`PUT`,{models:e})}async function Ge(e){return M(`/core/models/`+encodeURIComponent(e),`DELETE`,{})}async function Ke(e){return M(`/model/test`,`POST`,{modelId:e})}var qe={class:`card embedding-profile`,"aria-labelledby":`embedding-title`},Je={id:`embedding-title`},Ye={class:`muted`},Xe={key:0,class:`faint`},Ze={class:`check`},Qe={class:`fields`},$e=[`required`],et=[`required`],tt=[`placeholder`],nt={class:`save-bar`},rt=[`disabled`],it=[`disabled`],at={class:`faint`},ot={key:2,role:`status`},st=N(P({__name:`EmbeddingProfile`,setup(n){let o=b({enabled:!1,label:i(`知识向量`),baseUrl:``,model:``,apiKey:``,dimensions:0,batchSize:32,timeoutMs:9e4}),s=K(!1),c=K(!1),l=K(!1),u=K(``);async function d(){try{Object.assign(o,await M(`/core/knowledge/embedding`),{apiKey:``}),l.value=!0}catch(e){u.value=e.message}}async function m(){s.value=!0;try{Object.assign(o,await M(`/core/knowledge/embedding`,`PATCH`,o),{apiKey:``}),c.value=!1,H(i(`知识向量模型已保存`))}catch(e){H(e.message,!0)}finally{s.value=!1}}async function g(){s.value=!0;try{let e=await M(`/core/knowledge/embedding/test`,`POST`,{});u.value=i(`连接成功,向量维度 {dimensions}`,{dimensions:e.dimensions})}catch(e){u.value=e.message}finally{s.value=!1}}return x(d),(n,d)=>(V(),_(`section`,qe,[a(`h2`,Je,r(t(i)(`知识向量模型`)),1),a(`p`,Ye,r(t(i)(`单独配置资料检索使用的模型。更换对话模型后仍使用这里的配置。更换向量模型后,可在资料书架逐份重建向量;原文仍能通过关键词检索。`)),1),l.value&&!o.configured?(V(),_(`p`,Xe,r(t(i)(`当前兼容旧配置,跟随默认模型。保存后改用独立配置。`)),1)):h(``,!0),l.value?(V(),_(`form`,{key:1,onSubmit:f(m,[`prevent`]),onInput:d[6]||=e=>c.value=!0,onChange:d[7]||=e=>c.value=!0},[a(`label`,Ze,[q(a(`input`,{"onUpdate:modelValue":d[0]||=e=>o.enabled=e,type:`checkbox`,name:`embeddingEnabled`},null,512),[[J,o.enabled]]),e(r(t(i)(`启用知识向量`)),1)]),a(`div`,Qe,[a(`label`,null,[e(r(t(i)(`API 地址`)),1),q(a(`input`,{"onUpdate:modelValue":d[1]||=e=>o.baseUrl=e,name:`embeddingBaseUrl`,type:`url`,required:o.enabled,placeholder:`https://example.com/v1`},null,8,$e),[[p,o.baseUrl]])]),a(`label`,null,[e(r(t(i)(`模型名称`)),1),q(a(`input`,{"onUpdate:modelValue":d[2]||=e=>o.model=e,name:`embeddingModelName`,required:o.enabled},null,8,et),[[p,o.model]])]),a(`label`,null,[e(r(t(i)(`独立 API Key`)),1),q(a(`input`,{"onUpdate:modelValue":d[3]||=e=>o.apiKey=e,name:`embeddingApiKey`,type:`password`,autocomplete:`new-password`,placeholder:o.hasApiKey?t(i)(`已保存,留空保留`):t(i)(`填写向量服务密钥`)},null,8,tt),[[p,o.apiKey]])]),a(`label`,null,[e(r(t(i)(`向量维度(0 表示自动)`)),1),q(a(`input`,{"onUpdate:modelValue":d[4]||=e=>o.dimensions=e,name:`embeddingDimensions`,type:`number`,min:`0`,max:`65536`},null,512),[[p,o.dimensions,void 0,{number:!0}]])]),a(`label`,null,[e(r(t(i)(`每批段落数`)),1),q(a(`input`,{"onUpdate:modelValue":d[5]||=e=>o.batchSize=e,name:`embeddingBatchSize`,type:`number`,min:`1`,max:`128`},null,512),[[p,o.batchSize,void 0,{number:!0}]])])]),a(`div`,nt,[a(`button`,{class:`primary`,disabled:s.value},r(t(i)(`保存向量模型`)),9,rt),a(`button`,{type:`button`,disabled:s.value||c.value||!o.enabled||!o.configured,onClick:g},r(t(i)(`测试向量连接`)),9,it),a(`small`,at,r(c.value?t(i)(`有未保存的修改`):t(i)(`配置已载入`)),1)])],32)):h(``,!0),u.value?(V(),_(`p`,ot,r(u.value),1)):h(``,!0)]))}}),[[`__scopeId`,`data-v-ebda40d8`]]),ct={class:`library`},lt={class:`model-workspace`},ut={class:`card shelf`},dt={class:`shelf-head`},ft={class:`faint`},pt={class:`rows`},mt={key:0,class:`muted`},ht=[`open`,`data-saved-vendor`,`onToggle`],gt={class:`vendor-models`},_t=[`onClick`],vt={class:`who`},yt={key:0,class:`card detail`},bt={class:`card-head`},xt={class:`eyebrow`},St=[`data-tone`],Ct={class:`form-grid`},wt={key:0},Tt=[`placeholder`],Et={class:`wide`},Dt=[`placeholder`],Ot={class:`faint`},kt={class:`form-grid`},At={key:0},jt={key:1},Mt={class:`advanced`},Nt={class:`form-grid`},Pt=[`placeholder`],Ft={class:`faint`},It={class:`caps`},Lt=[`onUpdate:modelValue`,`name`],Rt={key:0,id:`modelTestResult`,class:`notice`,role:`status`},zt={class:`actions`},Bt=[`disabled`],Vt={class:`faint`},Ht={key:0,class:`check`},Ut=[`checked`],Wt=[`disabled`],Gt={key:1,class:`card detail`},Kt={class:`card usage-panel`,"aria-labelledby":`token-usage-title`},qt={class:`usage-intro`},Jt={class:`eyebrow`},Yt={id:`token-usage-title`},Xt={class:`usage-total`},Zt={class:`usage-detail`},Qt={class:`usage-stat`},$t={class:`usage-stat`},en={class:`usage-stat cache-stat`},tn={class:`usage-stat`},nn={class:`usage-foot`},rn={key:0},an={key:1,class:`usage-error`},on={key:2},sn=[`disabled`],cn={class:`model-picker`},ln={class:`muted`},un={class:`catalog-search`},dn=[`placeholder`],fn=[`data-vendor`],pn={class:`vendor-summary`},mn={class:`vendor-name`},hn={class:`presets`},gn=[`data-preset`,`onClick`],_n={key:0,class:`muted search-empty`},vn=N(P({__name:`ModelLibrary`,setup(s){let c=R(()=>B.health?.modelCatalog||[]),l=R(()=>B.health?.effortLabels||{none:i(`关闭`),minimal:i(`极低`),low:i(`低`),medium:i(`中`),high:i(`高`),xhigh:i(`极高`),max:i(`最深`)}),u=K(B.core.models.map(e=>({...e}))),g=K(u.value.length?0:-1),y=K(u.value.length?Q(u.value[0]):``),w=K(!1),T=K(!1),D=K(!1),O=K(``),k=K(``),A=K(null),j=K(!1),N=K(``),P=b(Z());u.value[0]&&Object.assign(P,u.value[0],{apiKey:``});let F=R(()=>g.value>=0&&!!P.id),I=R(()=>{let e=[];for(let t of c.value){if(t.id===`custom`)continue;let n=e.find(e=>e.vendor===t.vendor);n||(n={vendor:t.vendor,models:[]},e.push(n)),n.models.push(t)}return e}),L=R(()=>{let e=O.value.trim().toLocaleLowerCase();return e?I.value.map(t=>({...t,models:t.models.filter(n=>[t.vendor,n.label,n.model,n.summary].filter(Boolean).join(` `).toLocaleLowerCase().includes(e))})).filter(e=>e.models.length):I.value}),z=R(()=>{let e=[];return u.value.forEach((t,n)=>{let r=Q(t),i=e.find(e=>e.vendor===r);i||(i={vendor:r,models:[]},e.push(i)),i.models.push({model:t,index:n})}),e}),W=R(()=>c.value.find(e=>e.id===`custom`)),te=R(()=>c.value.filter(e=>e.vendor&&e.vendor===P.vendor)),re=R(()=>c.value.find(e=>e.id===P.presetId)||c.value.find(e=>e.model&&e.model===P.model&&e.baseUrl===P.baseUrl)),X=R(()=>{let e=re.value?.contextWindows||[];if(e.length<2)return[];let t=Number(P.contextWindow);return e.some(e=>e.contextWindow===t)?e:[...e,{label:i(`已保存 {value}`,{value:fe(t)}),contextWindow:t,maxInputTokens:Number(P.maxInputTokens),maxOutputTokens:Number(P.maxOutputTokens)}]}),ae=R(()=>{let e=Array.isArray(P.reasoningEfforts)&&P.reasoningEfforts.length?[...P.reasoningEfforts]:[`none`,`minimal`,`low`,`medium`,`high`,`xhigh`,`max`];return P.reasoningEffort&&!e.includes(P.reasoningEffort)&&e.unshift(P.reasoningEffort),e}),oe=R(()=>B.core.models.some(e=>e.id===P.id));function Z(){return{id:``,presetId:``,label:``,provider:``,vendor:``,baseUrl:``,model:``,apiKey:``,hasApiKey:!1,contextWindow:128e3,maxInputTokens:119808,maxOutputTokens:8192,vision:!1,system:!0,json:!0,tools:!1,embedding:!1,embeddingModel:``,reasoningEffort:`none`,reasoningEfforts:[`none`,`low`,`medium`,`high`],thinkingStyle:`openai`,tokenField:`max_tokens`,omitSampling:!1,temperature:.85,topP:1,timeoutMs:9e4,isDefault:!1,enabled:!0}}function Q(e){let t={"volcengine-coding-plan":i(`火山方舟 Coding Plan`),"opencode-go":`OpenCode Go`,"opencode-zen":`OpenCode Zen`,deepseek:`DeepSeek`,openai:`OpenAI`,bedrock:i(`亚马逊 Bedrock`),qwen:i(`通义千问`),moonshot:`Kimi`,kimi:`Kimi`,zhipu:i(`智谱 GLM`),glm:i(`智谱 GLM`),mimo:i(`小米 MiMo`),siliconflow:`SiliconFlow`,openrouter:`OpenRouter`};return String(e?.vendor||``).trim()||t[String(e?.provider||``).toLowerCase()]||String(e?.provider||i(`自定义供应商`))}function se(e,t){let n=t.currentTarget;y.value=n.open?e:``}function ce(e){let{summary:t,contextWindows:n,...r}=e;return{...r,presetId:e.id}}function le(e){let{contextWindows:t,...n}=e;return n}function ue(e){let t=Number(e.contextWindow),n=Number(e.maxOutputTokens),r=Number(e.maxInputTokens);return(!Number.isFinite(t)||t<2)&&(t=2),(!Number.isFinite(n)||n<1)&&(n=1),n>=t&&(n=t-1),(!Number.isFinite(r)||r<1)&&(r=t-n),r+n>t&&(r=t-n),{contextWindow:t,maxInputTokens:r,maxOutputTokens:n}}function de(e){let t=Number(e.target.value),n=X.value.find(e=>e.contextWindow===t);n&&(P.contextWindow=n.contextWindow,P.maxInputTokens=n.maxInputTokens,P.maxOutputTokens=n.maxOutputTokens,B.dirty=!0)}function fe(e){let t=Number(e)||0;return t>=1e6?(t%1048576==0?t/1048576:Number((t/1e6).toFixed(2)))+`M`:t>=1e3?(t%1e3==0?t/1e3:t%1024==0?t/1024:Math.round(t/1e3))+`K`:String(t)}function pe(e){if(e.id===`openrouter`)return i(`按所选模型填写上下文和输出参数`);if(!e.model)return i(`填写模型 ID 和对应参数`);let t=e.contextWindows||[],n=t.length?t.map(e=>e.label).join(` / `):fe(e.contextWindow);return i(`上下文 {context} · 输出 {v}`,{context:n,v:fe(e.maxOutputTokens)})}function me(e){return[`mimo`,`qwen`,`kimi-toggle`].includes(P.thinkingStyle)?i(e===`none`?`关闭`:`开启`):`${l.value[e]||e} / ${e}`}function $(e){return new Intl.NumberFormat(o()).format(Number(e)||0)}async function he(){if(!j.value){j.value=!0;try{A.value=await M(`/core/usage`),N.value=``}catch(e){N.value=e.message}finally{j.value=!1}}}x(()=>void he()),E(()=>B.tick,()=>void he());async function ge(){return B.dirty?await n(i(`放弃当前模型草稿?`),{title:i(`草稿还没保存`),confirmText:i(`放弃`),cancelText:i(`留下`)})?(B.dirty=!1,!0):!1:!0}async function _e(e){let t=u.value[e];t&&t.id!==P.id&&await ge()&&(u.value=u.value.filter(e=>e.id===t.id||B.core.models.some(t=>t.id===e.id)),g.value=u.value.findIndex(e=>e.id===t.id),y.value=Q(t),Object.assign(P,Z(),t,{apiKey:``}),k.value=``)}async function ve(){if(!await ge())return;u.value=B.core.models.map(e=>({...e})),u.value.length?u.value.some(e=>e.id===P.id)||(g.value=0,Object.assign(P,Z(),u.value[0],{apiKey:``})):(g.value=-1,Object.assign(P,Z()));let e=u.value[g.value]||u.value[0];y.value=e?Q(e):``,O.value=``,D.value=!0}function ye(e){u.value=B.core.models.map(e=>({...e}));let t={...Z(),...ce(e),id:`model-`+Date.now(),apiKey:``,hasApiKey:!1,isDefault:u.value.length===0};u.value.push(t),g.value=u.value.length-1,y.value=Q(t),Object.assign(P,t),k.value=``,D.value=!1,B.dirty=!0}function be(e){let t=e.target.value,n=c.value.find(e=>e.id===t);if(!n)return;Object.assign(P,Z(),ce(n),{id:P.id,apiKey:P.apiKey,hasApiKey:P.hasApiKey,isDefault:P.isDefault});let r=u.value[g.value];r&&(r.label=P.label),B.dirty=!0}function xe(){for(let e of u.value)e.isDefault=e.id===P.id;P.isDefault=!0,B.dirty=!0}async function Se(){let e=ue(P),t=u.value.map((t,n)=>le(n===g.value?{...P,...e,isDefault:!!P.isDefault,enabled:P.isDefault?!0:P.enabled!==!1,timeoutMs:Number(P.timeoutMs),temperature:Number(P.temperature),topP:Number(P.topP)}:{...t,isDefault:!!t.isDefault&&t.id!==P.id}));if(!t.some(e=>e.isDefault)&&t.length&&(t[0].isDefault=!0),!w.value){w.value=!0;try{await We(t),B.dirty=!1,await v(),u.value=B.core.models.map(e=>({...e})),Object.assign(P,Z(),u.value[g.value],{apiKey:``}),H(i(`已保存并应用`))}catch(e){H(e.message,!0)}finally{w.value=!1}}}async function Ce(){if(await n(i(`确定删除这个模型?`),{title:i(`删除模型`),confirmText:i(`删除`),danger:!0})){if(B.core.models.some(e=>e.id===P.id)&&await Ge(P.id),B.dirty=!1,await v(),u.value=B.core.models.map(e=>({...e})),k.value=``,!u.value.length){g.value=-1,y.value=``,Object.assign(P,Z());return}g.value=0,y.value=Q(u.value[0]),Object.assign(P,Z(),u.value[0],{apiKey:``})}}async function we(){if(!(!oe.value||B.dirty||T.value)){T.value=!0,k.value=i(`正在测试「{v}」…`,{v:P.label||P.model});try{let e=await Ke(P.id);k.value=i(`✓ {v} 连接成功 · {latency} ms`,{v:P.label||e.model,latency:e.latency}),await v()}catch(e){k.value=e.message}finally{T.value=!1}}}return(n,s)=>(V(),_(`div`,ct,[a(`div`,lt,[a(`aside`,ut,[a(`div`,dt,[a(`h2`,null,[e(r(t(i)(`模型库`))+` `,1),a(`small`,null,r(u.value.length),1)]),a(`button`,{id:`addModel`,class:`small primary`,onClick:ve},r(t(i)(`+ 新增模型`)),1)]),a(`p`,ft,r(t(i)(`群聊、私聊和独处都使用默认模型。其余已启用的模型按这里的顺序作为备用。关掉的模型不会被调用。`)),1),a(`div`,pt,[u.value.length?h(``,!0):(V(),_(`p`,mt,r(t(i)(`还没有模型。`)),1)),(V(!0),_(m,null,S(z.value,e=>(V(),_(`details`,{key:e.vendor,class:`saved-vendor`,open:y.value===e.vendor,"data-saved-vendor":e.vendor,onToggle:t=>se(e.vendor,t)},[a(`summary`,null,[a(`span`,null,r(e.vendor),1),a(`small`,null,r(t(i)(`{length} 个模型`,{length:e.models.length})),1)]),a(`div`,gt,[(V(!0),_(m,null,S(e.models,e=>(V(),_(`button`,{key:e.model.id,class:G([`entity-row`,{selected:g.value===e.index}]),onClick:t=>_e(e.index)},[a(`span`,{class:`badge`,style:d({"--hue":t(ne)(e.model.label||e.model.model||e.model.id)})},r(String(e.model.label||e.model.model||`?`).slice(0,1).toUpperCase()),5),a(`span`,vt,[a(`b`,null,r(e.model.label||e.model.model),1),a(`small`,null,r(e.model.enabled===!1?t(i)(`已关闭`):e.model.isDefault?t(i)(`默认模型`):t(i)(`备用模型`)),1)])],10,_t))),128))])],40,ht))),128))])]),F.value?(V(),_(`section`,yt,[a(`div`,bt,[a(`div`,null,[a(`span`,xt,r(t(i)(`模型档案`)),1),a(`h2`,null,r(P.label||t(i)(`新模型`)),1)]),a(`span`,{class:`chip`,"data-tone":P.hasApiKey?`ok`:`warn`},r((P.isDefault?t(i)(`默认模型 · `):``)+(P.hasApiKey?t(i)(`密钥已保存`):t(i)(`待填写密钥`))),9,St)]),a(`form`,{id:`modelForm`,class:`stack`,onSubmit:f(Se,[`prevent`]),onInput:s[14]||=e=>t(B).dirty=!0},[a(`fieldset`,null,[a(`legend`,null,r(t(i)(`连接`)),1),a(`div`,Ct,[te.value.length>1?(V(),_(`label`,wt,[e(r(t(i)(`同厂商模型`))+` `,1),C(Y,{"model-value":P.presetId,"aria-label":t(i)(`同厂商模型`),options:te.value.map(e=>({value:e.id,label:e.label})),onChange:be},null,8,[`model-value`,`aria-label`,`options`])])):h(``,!0),a(`label`,null,[e(r(t(i)(`显示名称`)),1),q(a(`input`,{"onUpdate:modelValue":s[0]||=e=>P.label=e,name:`label`,required:``},null,512),[[p,P.label]])]),a(`label`,null,[e(r(t(i)(`供应商`)),1),q(a(`input`,{"onUpdate:modelValue":s[1]||=e=>P.provider=e,name:`provider`,placeholder:t(i)(`例如 deepseek、openai`)},null,8,Tt),[[p,P.provider]])]),a(`label`,null,[e(r(t(i)(`API 地址`)),1),q(a(`input`,{"onUpdate:modelValue":s[2]||=e=>P.baseUrl=e,name:`baseUrl`,type:`url`,required:``},null,512),[[p,P.baseUrl]])]),a(`label`,null,[e(r(t(i)(`模型名称`)),1),q(a(`input`,{"onUpdate:modelValue":s[3]||=e=>P.model=e,name:`model`,required:``},null,512),[[p,P.model]])]),a(`label`,Et,[s[18]||=e(` API Key `,-1),q(a(`input`,{"onUpdate:modelValue":s[4]||=e=>P.apiKey=e,name:`apiKey`,type:`password`,autocomplete:`new-password`,placeholder:P.hasApiKey?t(i)(`已保存,留空则保留`):t(i)(`填写供应商提供的密钥`)},null,8,Dt),[[p,P.apiKey]])])])]),a(`fieldset`,null,[a(`legend`,null,r(t(i)(`容量与思考`)),1),a(`p`,Ot,r(t(i)(`官方按输入长度分档计价的模型可以在标准和百万之间切换;输出上限默认是官方最大值,思考强度只列出这个模型支持的档位。`)),1),a(`div`,kt,[X.value.length?(V(),_(`label`,At,[e(r(t(i)(`上下文容量`))+` `,1),C(Y,{name:`contextWindow`,"model-value":P.contextWindow,options:X.value.map(e=>({value:e.contextWindow,label:e.label})),onChange:de},null,8,[`model-value`,`options`])])):(V(),_(`label`,jt,[e(r(t(i)(`上下文容量`)),1),q(a(`input`,{"onUpdate:modelValue":s[5]||=e=>P.contextWindow=e,name:`contextWindow`,type:`number`},null,512),[[p,P.contextWindow,void 0,{number:!0}]])])),a(`label`,null,[e(r(t(i)(`最大输入 Token`)),1),q(a(`input`,{"onUpdate:modelValue":s[6]||=e=>P.maxInputTokens=e,name:`maxInputTokens`,type:`number`},null,512),[[p,P.maxInputTokens,void 0,{number:!0}]])]),a(`label`,null,[e(r(t(i)(`最大输出 Token`)),1),q(a(`input`,{"onUpdate:modelValue":s[7]||=e=>P.maxOutputTokens=e,name:`maxOutputTokens`,type:`number`},null,512),[[p,P.maxOutputTokens,void 0,{number:!0}]])]),a(`label`,null,[e(r(t(i)(`思考强度`))+` `,1),C(Y,{modelValue:P.reasoningEffort,"onUpdate:modelValue":s[8]||=e=>P.reasoningEffort=e,name:`reasoningEffort`,"aria-label":t(i)(`思考强度`),options:ae.value.map(e=>({value:e,label:me(e)}))},null,8,[`modelValue`,`aria-label`,`options`])])])]),a(`details`,Mt,[a(`summary`,null,r(t(i)(`高级参数与模型能力`)),1),a(`div`,Nt,[a(`label`,null,[e(r(t(i)(`随机程度 Temperature`)),1),q(a(`input`,{"onUpdate:modelValue":s[9]||=e=>P.temperature=e,name:`temperature`,type:`number`,step:`0.05`},null,512),[[p,P.temperature,void 0,{number:!0}]])]),a(`label`,null,[e(r(t(i)(`采样范围 Top P`)),1),q(a(`input`,{"onUpdate:modelValue":s[10]||=e=>P.topP=e,name:`topP`,type:`number`,step:`0.05`},null,512),[[p,P.topP,void 0,{number:!0}]])]),a(`label`,null,[e(r(t(i)(`超时(毫秒)`)),1),q(a(`input`,{"onUpdate:modelValue":s[11]||=e=>P.timeoutMs=e,name:`timeoutMs`,type:`number`},null,512),[[p,P.timeoutMs,void 0,{number:!0}]])]),a(`label`,null,[e(r(t(i)(`知识检索模型`)),1),q(a(`input`,{"onUpdate:modelValue":s[12]||=e=>P.embeddingModel=e,name:`embeddingModel`,placeholder:t(i)(`留空跟随对话模型`)},null,8,Pt),[[p,P.embeddingModel]])])]),a(`p`,Ft,r(t(i)(`打开图片理解后,聊天里的图片会先在本机读取,再连同画面交给这个模型。主模型不能看图时,到会话设置另选一个打开了图片理解的视觉兼容模型。`)),1),a(`div`,It,[(V(!0),_(m,null,S({vision:t(i)(`图片理解`),system:`System Prompt`,json:t(i)(`JSON 输出`),tools:t(i)(`工具调用`),embedding:t(i)(`知识向量`)},(t,n)=>(V(),_(`label`,{key:n,class:`check`},[q(a(`input`,{"onUpdate:modelValue":e=>P[n]=e,name:n,type:`checkbox`},null,8,Lt),[[J,P[n]]]),e(r(t),1)]))),128))])]),k.value?(V(),_(`div`,Rt,r(k.value),1)):h(``,!0),a(`div`,zt,[a(`button`,{class:`primary`,disabled:w.value},r(w.value?t(i)(`正在保存…`):t(i)(`保存模型`)),9,Bt),a(`small`,Vt,r(t(B).dirty?t(i)(`有未保存的修改`):t(i)(`已保存的模型才会用来测试和回复`)),1),P.isDefault?h(``,!0):(V(),_(`label`,Ht,[a(`input`,{type:`checkbox`,checked:P.enabled!==!1,onChange:s[13]||=e=>{P.enabled=e.target.checked,t(B).dirty=!0}},null,40,Ut),e(r(t(i)(`启用这个备用模型`)),1)])),P.isDefault?h(``,!0):(V(),_(`button`,{key:1,id:`setDefaultModel`,type:`button`,onClick:xe},r(t(i)(`设为默认模型`)),1)),oe.value?(V(),_(`button`,{key:2,id:`testModel`,type:`button`,disabled:w.value||T.value||t(B).dirty,onClick:we},r(T.value?t(i)(`正在测试…`):t(B).dirty?t(i)(`保存后测试此模型`):t(i)(`测试此模型连接`)),9,Wt)):h(``,!0),a(`button`,{id:`deleteModel`,type:`button`,class:`danger push`,onClick:Ce},r(t(i)(`删除模型`)),1)])],32)])):(V(),_(`section`,Gt,[C(ee,{title:t(i)(`还没有模型`),text:t(i)(`常见厂商会预填模型参数;OpenRouter 可选 GPT-6 预设,也可用自选模型手动填写模型 ID 和参数。`)},{default:U(()=>[a(`button`,{class:`primary`,onClick:ve},r(t(i)(`+ 新增模型`)),1)]),_:1},8,[`title`,`text`])]))]),C(st),a(`section`,Kt,[a(`div`,qt,[a(`div`,null,[a(`span`,Jt,r(t(i)(`TOKEN LEDGER · 累计用量`)),1),a(`h2`,Yt,r(t(i)(`一路聊到现在`)),1),a(`p`,null,r(t(i)(`统计本机账本记录的模型调用;缓存 Token 已包含在输入量里。`)),1)]),a(`div`,Xt,[a(`strong`,null,r($(A.value?.total)),1),a(`span`,null,r(t(i)(`累计 Token`)),1)])]),a(`div`,Zt,[a(`div`,Qt,[a(`span`,null,r(t(i)(`输入`)),1),a(`b`,null,r($(A.value?.input)),1)]),a(`div`,$t,[a(`span`,null,r(t(i)(`输出`)),1),a(`b`,null,r($(A.value?.output)),1)]),a(`div`,en,[a(`span`,null,[e(r(t(i)(`缓存命中`))+` `,1),a(`small`,null,r(t(i)(`(输入子项)`)),1)]),a(`b`,null,r($(A.value?.cached)),1)]),a(`div`,tn,[a(`span`,null,r(t(i)(`调用次数`)),1),a(`b`,null,r($(A.value?.calls)),1)])]),a(`div`,nn,[A.value?.since?(V(),_(`small`,rn,[e(r(t(i)(`从 {v} 开始记录 · {v2} 为模型返回用量`,{v:new Date(A.value.since).toLocaleDateString(t(o)()),v2:$(A.value.reportedTokens)}))+` `,1),A.value.estimatedCalls?(V(),_(m,{key:0},[e(r(t(i)(`· {v} 次调用按文本估算`,{v:$(A.value.estimatedCalls)})),1)],64)):h(``,!0)])):N.value?(V(),_(`small`,an,r(N.value),1)):(V(),_(`small`,on,r(t(i)(`还没有模型调用记录。`)),1)),a(`button`,{type:`button`,class:`usage-refresh`,disabled:j.value,onClick:he},r(j.value?t(i)(`更新中…`):t(i)(`刷新统计 ↻`)),9,sn)])]),C(ie,{open:D.value,title:t(i)(`选择模型`),eyebrow:`MODELS`,width:`880px`,onClose:s[17]||=e=>D.value=!1},{default:U(()=>[a(`div`,cn,[a(`p`,ln,r(t(i)(`先选供应商,再挑具体模型;支持搜索。火山方舟 Coding Plan 已预填套餐专用接口与型号参数,请勿换成普通推理 API 地址。`)),1),a(`label`,un,[a(`span`,null,r(t(i)(`搜索模型或供应商`)),1),q(a(`input`,{"onUpdate:modelValue":s[15]||=e=>O.value=e,type:`search`,placeholder:t(i)(`例如:火山方舟、Kimi K3、DeepSeek`)},null,8,dn),[[p,O.value]])]),(V(!0),_(m,null,S(L.value,e=>(V(),_(`details`,{key:e.vendor,class:`vendor`,"data-vendor":e.vendor},[a(`summary`,pn,[a(`span`,mn,[a(`b`,null,r(e.vendor),1),a(`small`,null,r(t(i)(`{length} 个预设`,{length:e.models.length})),1)]),s[19]||=a(`span`,{class:`vendor-chevron`,"aria-hidden":`true`},`⌄`,-1)]),a(`div`,hn,[(V(!0),_(m,null,S(e.models,e=>(V(),_(`button`,{key:e.id,type:`button`,class:`preset-card`,"data-preset":e.id,onClick:t=>ye(e)},[a(`b`,null,r(e.label),1),a(`small`,null,r(e.model||t(i)(`填写你在 OpenRouter 选择的模型 ID`)),1),a(`small`,null,r(pe(e)),1),a(`small`,null,r(e.summary),1)],8,gn))),128))])],8,fn))),128)),L.value.length?h(``,!0):(V(),_(`p`,_n,r(t(i)(`没有找到匹配的模型预设。`)),1)),W.value?(V(),_(`button`,{key:1,type:`button`,class:`preset-card custom`,"data-preset":`custom`,onClick:s[16]||=e=>ye(W.value)},[a(`b`,null,r(W.value.label),1),a(`small`,null,r(W.value.summary),1)])):h(``,!0)])]),_:1},8,[`open`,`title`])]))}}),[[`__scopeId`,`data-v-db7bc4c1`]]),yn={class:`switch`},bn=[`name`,`disabled`],xn=P({__name:`Toggle`,props:z({name:{},disabled:{type:Boolean}},{modelValue:{type:Boolean,default:!1},modelModifiers:{}}),emits:[`update:modelValue`],setup(e){let t=O(e,`modelValue`);return(n,r)=>(V(),_(`label`,yn,[q(a(`input`,{"onUpdate:modelValue":r[0]||=e=>t.value=e,type:`checkbox`,name:e.name,disabled:e.disabled},null,8,bn),[[J,t.value]]),a(`span`,null,[T(n.$slots,`default`)])]))}}),Sn={class:`runtime-grid`},Cn={class:`card-head`},wn={class:`eyebrow`},Tn={class:`switches`},En={class:`save-bar`},Dn={class:`primary`,type:`submit`},On={class:`faint`},kn={class:`card numbers`},An=[`title`],jn=N(P({__name:`Runtime`,setup(e){let n=K(!!B.health.settings.enabled),o=K(!!B.health.settings.demo),s=R(()=>(B.core.sessions||[]).filter(e=>e.enabled&&!e.archived).length),c=R(()=>{let e=B.health.backup;if(!e)return null;if(!e.enabled)return{value:i(`已关闭`),caption:i(`自动备份`),tone:`warn`,title:``};if(e.lastError)return{value:i(`失败`),caption:i(`自动备份出错,稍后重试`),tone:`danger`,title:e.lastError.message};if(!e.latest)return{value:i(`还没有`),caption:i(`自动备份,运行一阵后会做第一份`),tone:``,title:``};let t=Math.max(1,Math.round(e.latest.bytes/1048576));return{value:re(e.latest.at),caption:i(`上次自动备份 · {mb} MB · 已留 {count}/{keep} 份`,{mb:t,count:e.count,keep:e.keep}),tone:``,title:e.latest.name}});async function l(){try{await L({enabled:n.value,demo:o.value}),B.dirty=!1,B.health=await w(),H(i(`已保存并应用`))}catch(e){H(e.message,!0)}}return(e,u)=>(V(),_(`div`,Sn,[a(`form`,{id:`runtime`,class:`card`,onSubmit:f(l,[`prevent`]),onChange:u[2]||=e=>t(B).dirty=!0},[a(`div`,Cn,[a(`div`,null,[a(`span`,wn,r(t(i)(`运行开关`)),1),a(`h2`,null,r(t(i)(`TA 现在可以说话吗`)),1)])]),a(`div`,Tn,[C(xn,{modelValue:n.value,"onUpdate:modelValue":u[0]||=e=>n.value=e,name:`enabled`},{default:U(()=>[a(`b`,null,r(t(i)(`允许参与聊天`)),1),a(`small`,null,r(t(i)(`总开关。关掉后 TA 不看也不回任何会话,心智照常保存。`)),1)]),_:1},8,[`modelValue`]),C(xn,{modelValue:o.value,"onUpdate:modelValue":u[1]||=e=>o.value=e,name:`demo`},{default:U(()=>[a(`b`,null,r(t(i)(`仅模拟运行,不向 QQ 发送`)),1),a(`small`,null,r(t(i)(`模拟模式下,「对话」里可以发模拟消息走完整流程;它们写进模拟会话,不进入真实记忆。`)),1)]),_:1},8,[`modelValue`])]),a(`div`,En,[a(`button`,Dn,r(t(i)(`保存运行状态`)),1),a(`small`,On,r(t(B).dirty?t(i)(`有未保存的修改`):t(i)(`已保存,立刻生效`)),1)])],32),a(`section`,kn,[a(`button`,{onClick:u[3]||=e=>t(k)(`chats`)},[a(`b`,null,r(s.value),1),a(`span`,null,r(t(i)(`参与中的会话`)),1)]),a(`button`,{onClick:u[4]||=e=>t(k)(`system`,`models`)},[a(`b`,null,r(t(B).core.models.length),1),a(`span`,null,r(t(i)(`可用模型`)),1)]),a(`button`,{onClick:u[5]||=e=>t(k)(`system`,`connect`)},[a(`b`,null,r(t(B).health.connection?.online?t(i)(`在线`):t(i)(`离线`)),1),a(`span`,null,r(t(i)(`QQ 连接`)),1)]),c.value?(V(),_(`button`,{key:0,class:G([`stat`,c.value.tone]),title:c.value.title,"data-testid":`backup-status`,type:`button`,onClick:u[6]||=e=>t(k)(`system`,`storage`)},[a(`b`,null,r(c.value.value),1),a(`span`,null,r(c.value.caption),1)],10,An)):h(``,!0)])]))}}),[[`__scopeId`,`data-v-1f197523`]]),Mn={class:`card search-profile`},Nn={class:`eyebrow`},Pn={class:`muted`},Fn={key:0,class:`faint`},In={class:`check`},Ln=[`disabled`],Rn={class:`search-fields`},zn=[`disabled`],Bn=[`disabled`,`placeholder`],Vn=[`disabled`],Hn=[`disabled`],Un=[`disabled`],Wn={class:`faint`},Gn={class:`search-usage`,role:`status`},Kn={class:`chip`},qn={class:`faint`},Jn={class:`faint`},Yn={class:`row`},Xn=[`disabled`],Zn=[`disabled`],Qn={key:0,class:`faint`},$n=[`role`],er=N(P({__name:`SearchProfile`,setup(n){let o=[`provider`,`enabled`,`baseUrl`,`timeoutMs`,`maxResults`,`dailyLimit`],s=b({provider:`tavily`,enabled:!0,baseUrl:``,apiKey:``,timeoutMs:2e4,maxResults:5,dailyLimit:12}),c=K(null),l=K(!1),u=K(!1),d=K(``),m=K(!1),g=new Map,v=`tavily`,y=R(()=>u.value&&(!!s.apiKey.trim()||o.some(e=>s[e]!==c.value?.[e]))),S=e=>e===`brave`?`Brave`:`Tavily`,w=R(()=>c.value?.dailyLimit===0?i(`不限`):c.value?.dailyLimit??12);E(y,e=>{B.dirty=e}),E(()=>[B.tick,B.pulse],()=>{u.value&&!l.value&&B.page===`system`&&B.sub===`search`&&T().catch(()=>{})});async function T(){c.value=await M(`/mind/time/search`)}async function D(){try{await T(),Object.assign(s,c.value,{apiKey:``}),v=s.provider,u.value=!0}catch(e){H(e.message,!0)}}async function O(){if(l.value)return;l.value=!0;let e=s.provider;g.set(v,{...s,provider:v});try{Object.assign(s,g.get(e)||{...await M(`/mind/time/search?provider=`+e),apiKey:``}),v=e,d.value=``}catch(e){s.provider=v,H(e.message,!0)}finally{l.value=!1}}function k(){return Object.fromEntries([...o,`apiKey`].map(e=>[e,s[e]]))}async function A(){if(!l.value){l.value=!0;try{let e=await M(`/mind/time/search`,`PATCH`,k());c.value=e,Object.assign(s,e,{apiKey:``}),g.set(s.provider,{...s}),v=s.provider,H(i(`搜索配置已保存并生效`))}catch(e){H(e.message,!0)}finally{l.value=!1}}}async function N(){if(!l.value){l.value=!0,d.value=``,m.value=!1;try{let e=await M(`/mind/time/search/test`,`POST`,k()),t={source:e.profile.mode===`web`?i(`{provider} 联网检索`,{provider:S(e.profile.provider)}):e.profile.materialLabel,count:e.results.length};d.value=y.value?i(`{source}测试通过,返回 {count} 条资料。测试不占用每日查询额度;当前填写的配置尚未保存。`,t):i(`{source}测试通过,返回 {count} 条资料。测试不占用每日查询额度。`,t)}catch(e){m.value=!0,d.value=i(`{error}。本次测试不占用每日查询额度。`,{error:e.message})}finally{try{await T()}catch{}l.value=!1}}}return x(D),j(()=>{B.dirty=!1}),(n,o)=>(V(),_(`section`,Mn,[a(`span`,Nn,r(t(i)(`SEARCH · 独立搜索`)),1),a(`h2`,null,r(t(i)(`接触世界的资料`)),1),a(`p`,Pn,r(t(i)(`配置后优先联网检索。未配置密钥或关闭独立搜索时,使用当前模型整理已有知识。`)),1),u.value?(V(),_(`p`,Fn,r(t(i)(`当前生效:{v}。表单修改保存后生效。`,{v:c.value.mode===`web`?t(i)(`{provider} · 联网检索资料`,{provider:S(c.value.provider)}):c.value.materialLabel})),1)):h(``,!0),u.value?(V(),_(`form`,{key:1,onSubmit:f(A,[`prevent`])},[a(`label`,In,[q(a(`input`,{"onUpdate:modelValue":o[0]||=e=>s.enabled=e,type:`checkbox`,disabled:l.value},null,8,Ln),[[J,s.enabled]]),e(r(t(i)(`启用独立搜索`)),1)]),a(`div`,Rn,[a(`label`,null,[e(r(t(i)(`提供方`)),1),C(Y,{modelValue:s.provider,"onUpdate:modelValue":o[1]||=e=>s.provider=e,"aria-label":t(i)(`搜索提供方`),disabled:l.value,options:[{value:`tavily`,label:`Tavily`},{value:`brave`,label:`Brave`}],onChange:O},null,8,[`modelValue`,`aria-label`,`disabled`])]),a(`label`,null,[e(r(t(i)(`搜索地址`)),1),q(a(`input`,{"onUpdate:modelValue":o[2]||=e=>s.baseUrl=e,type:`url`,required:``,name:`searchUrl`,disabled:l.value},null,8,zn),[[p,s.baseUrl]])]),a(`label`,null,[e(r(t(i)(`独立密钥`)),1),q(a(`input`,{"onUpdate:modelValue":o[3]||=e=>s.apiKey=e,type:`password`,autocomplete:`new-password`,name:`searchKey`,disabled:l.value,placeholder:s.hasApiKey?t(i)(`已保存,留空保留`):t(i)(`填写该提供方的搜索密钥`)},null,8,Bn),[[p,s.apiKey]])]),a(`label`,null,[e(r(t(i)(`超时(毫秒)`)),1),q(a(`input`,{"onUpdate:modelValue":o[4]||=e=>s.timeoutMs=e,type:`number`,min:`1000`,max:`120000`,disabled:l.value},null,8,Vn),[[p,s.timeoutMs,void 0,{number:!0}]])]),a(`label`,null,[e(r(t(i)(`每次结果数`)),1),q(a(`input`,{"onUpdate:modelValue":o[5]||=e=>s.maxResults=e,type:`number`,min:`1`,max:`20`,disabled:l.value},null,8,Hn),[[p,s.maxResults,void 0,{number:!0}]])]),a(`label`,null,[e(r(t(i)(`每日查询上限`)),1),q(a(`input`,{"onUpdate:modelValue":o[6]||=e=>s.dailyLimit=e,name:`searchDailyLimit`,type:`number`,min:`0`,max:`100000`,disabled:l.value},null,8,Un),[[p,s.dailyLimit,void 0,{number:!0}]]),a(`small`,Wn,r(t(i)(`可手动调整;0 表示不限。保存后立即生效。`)),1)])]),a(`div`,Gn,[a(`span`,Kn,r(t(i)(`今日有效查询 {v} / {limitLabel}`,{v:c.value.used||0,limitLabel:w.value})),1),a(`small`,qn,r(t(i)(`{v} 次进行中 · {v2} 次失败 · {v3} 次测试`,{v:c.value.usage?.running||0,v2:c.value.usage?.failed||0,v3:c.value.usage?.diagnostics||0})),1)]),a(`p`,Jn,r(t(i)(`测试当前填写的配置,不会自动保存。失败与连接测试不占本地每日额度;提供方的账户额度由提供方管理。`)),1),a(`div`,Yn,[a(`button`,{class:`primary`,disabled:l.value},r(t(i)(`保存搜索`)),9,Xn),a(`button`,{type:`button`,disabled:l.value,onClick:N},r(l.value?t(i)(`处理中…`):t(i)(`测试连接`)),9,Zn),y.value?(V(),_(`span`,Qn,r(t(i)(`有尚未保存的修改`)),1)):h(``,!0)]),d.value?(V(),_(`p`,{key:0,role:m.value?`alert`:`status`,class:G([`search-result`,{failed:m.value}])},r(d.value),11,$n)):h(``,!0)],32)):h(``,!0)]))}}),[[`__scopeId`,`data-v-5135e471`]]),tr={key:0,class:`card data-transfer`,"aria-labelledby":`data-transfer-title`},nr={class:`eyebrow`},rr={id:`data-transfer-title`},ir={class:`transfer-note`},ar={class:`transfer-note`},or={class:`transfer-actions`},sr=[`disabled`],cr=[`disabled`],lr=[`aria-label`],ur={class:`transfer-note`},dr={key:0,class:`transfer-progress`,role:`status`},fr={key:1,class:`transfer-error`,role:`alert`},pr={key:2,class:`transfer-note`},mr={key:3,class:`transfer-preview`},hr={class:`eyebrow`},gr={class:`transfer-note`},_r={class:`transfer-counts`},vr={class:`transfer-actions`},yr=[`disabled`],br=[`disabled`],xr=N(P({__name:`DataTransfer`,setup(e){let o=K(null),c=K(null),d=K(),f=K(``),p=K(``),g=!0,v=null,y=R(()=>!!f.value),b=R(()=>f.value===`restarting`?i(`正在保留快照并重启加载,请等待…`):f.value===`uploading`?i(`正在上传数据文件…`):f.value===`exporting`?i(`正在生成完整数据包…`):i(`正在校验数据文件…`)),C=R(()=>{let e=c.value?.summary?.tables||{};return[[i(`聊天记录`),e.core_events||e.messages||0],[i(`记忆`),e.core_memories||e.memories||0],[i(`待办`),e.mind_time_tasks||0],[i(`作品`),e.mind_time_works||0],[i(`日记`),e.mind_diary||0]]}),w=()=>new Promise(e=>setTimeout(e,800));async function T(e,t=!1){for(let n=0;n<4500&&g;n++){try{let n=await M(`/storage/transfer/jobs/`+e);if(n.status===`error`)throw Error(n.error||i(`数据处理失败`));if(n.status===(t?`done`:`ready`))return n;if(n.status===`expired`)throw Error(i(`数据文件已过期,请重新选择`))}catch(e){if(!t||!(e instanceof TypeError)&&e.message!==i(`请求失败`))throw e}await w()}throw Error(i(`等待数据处理超时,请检查实例运行状态`))}async function E(){if(!y.value){f.value=`exporting`,p.value=``;try{let e=await M(`/storage/transfer/export`,`POST`,{});if(await T(e.id),!g)return;let t=document.createElement(`a`);t.href=`/api/storage/transfer/download/`+e.id,t.download=``,document.body.appendChild(t),t.click(),t.remove(),H(i(`数据包已生成,浏览器将开始下载`))}catch(e){g&&(p.value=e.message)}finally{g&&(f.value=``)}}}async function O(e){let t=e.target,n=t.files?.[0];if(t.value=``,n&&!y.value){if(p.value=``,c.value=null,n.size>(o.value?.maxBytes||0)){p.value=i(`数据文件超过导入大小限制`);return}f.value=`uploading`,v=new AbortController;try{await u();let e=await fetch(`/api/storage/transfer/upload`,{method:`POST`,credentials:`same-origin`,headers:{"Content-Type":`application/octet-stream`,"X-LuckyTri-Filename":encodeURIComponent(n.name),"X-LuckyTri-Locale":s.value},body:n,signal:v.signal});if(e.status===401)throw l(),Error(i(`请先登录管理台`));let t=await e.json().catch(()=>({}));if(!e.ok)throw Error(t.error||i(`数据上传失败`));f.value=`checking`;let r=await T(t.id);g&&(c.value=r)}catch(e){g&&(p.value=e.message)}finally{v=null,g&&(f.value=``)}}}async function k(){if(c.value&&!y.value)try{await M(`/storage/transfer/jobs/`+c.value.id,`DELETE`),c.value=null}catch(e){p.value=e.message}}async function A(){if(!c.value||y.value||!await n(i(`用这份数据替换当前数据,并保留导入前快照。实例将重启,导入后自动回复关闭。本机管理密码与 QQ 连接配置保持不变。`),{title:i(`确认导入数据`),confirmText:i(`导入并重启`),danger:!0}))return;f.value=`restarting`,p.value=``;let e=c.value.id;try{if(await M(`/storage/transfer/import`,`POST`,{id:e}),await T(e,!0),!g)return;D(),location.reload()}catch(e){g&&(p.value=e.message)}finally{g&&(f.value=``)}}return x(async()=>{try{o.value=await M(`/storage/transfer`)}catch(e){g&&(p.value=e.message)}}),I(()=>{g=!1,v?.abort()}),(e,n)=>o.value?.available?(V(),_(`section`,tr,[a(`span`,nr,r(t(i)(`DATA · 导入与导出`)),1),a(`h2`,rr,r(t(i)(`带上记忆,继续生活。`)),1),a(`p`,ir,r(t(i)(`导出数据库内的聊天、记忆、待办、作品、知识与设置。插件文件、知识库原始文件和本机 .env 不在数据包中。`)),1),a(`p`,ar,r(t(i)(`数据包包含私聊内容和模型设置中的密钥,请存放在你信任的位置。导入前会校验,确认后才替换当前数据。`)),1),a(`div`,or,[a(`button`,{class:`primary`,type:`button`,disabled:y.value,onClick:E},r(t(i)(`导出数据包`)),9,sr),a(`button`,{type:`button`,disabled:y.value,onClick:n[0]||=e=>d.value?.click()},r(t(i)(`选择导入文件`)),9,cr),a(`input`,{ref_key:`input`,ref:d,class:`transfer-file`,type:`file`,accept:`.luckytri,.db,.sqlite,.sqlite3`,"aria-label":t(i)(`导入数据文件`),onChange:O},null,40,lr)]),a(`p`,ur,r(t(i)(`支持 .luckytri 数据包和已有 SQLite 备份,单个文件最多 {size} GiB。`,{size:(o.value.maxBytes/1073741824).toFixed(0)})),1),y.value?(V(),_(`p`,dr,r(b.value),1)):h(``,!0),p.value?(V(),_(`p`,fr,r(p.value),1)):h(``,!0),o.value.lastImport?.status===`done`?(V(),_(`p`,pr,r(t(i)(`上次数据导入已完成,自动回复在导入时关闭。请检查连接、模型和待办后再开启;插件需重新安装或确认权限。`)),1)):h(``,!0),c.value?(V(),_(`div`,mr,[a(`span`,hr,r(t(i)(`校验通过 · 尚未导入`)),1),a(`h3`,null,r(c.value.summary?.name),1),a(`p`,gr,r(c.value.name)+` · `+r(t(i)(`数据库版本 {from} → {to}`,{from:c.value.originalVersion,to:c.value.summary?.schemaVersion})),1),a(`div`,_r,[(V(!0),_(m,null,S(C.value,([e,t])=>(V(),_(`div`,{key:e},[a(`b`,null,r(t),1),a(`span`,null,r(e),1)]))),128))]),a(`div`,vr,[a(`button`,{class:`primary`,type:`button`,disabled:y.value,onClick:A},r(t(i)(`导入并重启`)),9,yr),a(`button`,{type:`button`,disabled:y.value,onClick:k},r(t(i)(`取消导入`)),9,br)])])):h(``,!0)])):h(``,!0)}}),[[`__scopeId`,`data-v-1a555eb4`]]),Sr={class:`storage-page`},Cr={class:`card storage-overview`},wr={class:`eyebrow`},Tr={key:0,class:`storage-metrics`},Er={key:0,class:`storage-error`,role:`alert`},Dr={key:1,class:`storage-grid`},Or={class:`card-head`},kr={class:`eyebrow`},Ar={class:`storage-check`},jr={class:`storage-fields`},Mr=[`aria-label`],Nr=[`aria-label`],Pr=[`aria-label`],Fr={class:`storage-note`},Ir={key:0,class:`storage-note`},Lr={key:1,class:`storage-error`},Rr=[`disabled`],zr={class:`card storage-list`},Br={class:`card-head`},Vr={class:`eyebrow`},Hr={class:`storage-note`},Ur={class:`storage-actions`},Wr=[`disabled`],Gr=[`disabled`],Kr=[`disabled`],qr={class:`storage-scroll`},Jr=[`checked`,`disabled`,`aria-label`,`onChange`],Yr={class:`storage-item`},Xr={key:0,class:`storage-error`,role:`alert`},Zr={class:`storage-footer`},Qr=[`disabled`],$r=N(P({__name:`BackupManager`,setup(s){let c=K(null),l=K({enabled:!0,time:`04:30`,retainDays:14,keepFull:2}),u=K([]),d=K(!1),g=K(``),v=K([]),y=!0,b=e=>`${e.scope}:${e.name}`,w=R(()=>c.value?.entries.filter(e=>u.value.includes(b(e)))||[]),T=R(()=>w.value.reduce((e,t)=>e+t.bytes,0)),E=e=>e===0?`0 B`:e>=1073741824?`${(e/1073741824).toFixed(2)} GiB`:`${Math.max(.01,e/1048576).toFixed(2)} MiB`,D=e=>new Date(e).toLocaleString(o()),O=e=>({auto:i(`自动备份`),full:i(`完整备份`),migration:i(`迁移快照`),legacy:i(`旧版本备份`),snapshot:i(`升级前快照`),import:i(`导入前快照`)})[e];async function k(e=!1){try{g.value=``;let t=await M(`/storage/cleanup`);if(!y)return;if(c.value=t,e)l.value={...c.value.policy},u.value=[],B.dirty=!1;else{let e=new Set(c.value.entries.filter(e=>!e.protected).map(b));u.value=u.value.filter(t=>e.has(t))}}catch(e){y&&(g.value=e.message)}}function A(){B.dirty=!0}function j(e){let t=b(e);u.value=u.value.includes(t)?u.value.filter(e=>e!==t):[...u.value,t]}function N(){u.value=(c.value?.plan.items||[]).map(b)}function P(){u.value=(c.value?.entries||[]).filter(e=>e.kind===`full`&&!e.protected).map(b)}async function F(){if(!d.value){d.value=!0;try{let e=await M(`/storage/cleanup`,`PATCH`,{enabled:l.value.enabled,time:l.value.time,retainDays:Number(l.value.retainDays),keepFull:Number(l.value.keepFull)});c.value=e,l.value={...e.policy},B.dirty=!1,H(i(`备份整理规则已保存`))}catch(e){H(e.message,!0)}finally{d.value=!1}}}async function L(){if(!w.value.length||d.value)return;let e=w.value.map(({scope:e,name:t,bytes:n,modified:r})=>({scope:e,name:t,bytes:n,modified:r}));if(await n(i(`将清理选中的 {count} 份备份,释放约 {size}。这些历史恢复点清理后无法从本机找回。`,{count:e.length,size:E(T.value)}),{title:i(`清理所选备份`),confirmText:i(`清理所选`),danger:!0})){d.value=!0;try{let t=await M(`/storage/cleanup/manual`,`POST`,{items:e});v.value=t.failures||[];let n=new Set((t.failures||[]).map(e=>`${e.scope}:${e.name}`));u.value=u.value.filter(e=>n.has(e)),await k(),H(i(`已清理 {count} 份备份,释放 {size}`,{count:t.removed.length,size:E(t.bytes)})+(v.value.length?i(`;部分未清理,详情见列表`):``),v.value.length>0)}catch(e){H(e.message,!0),await k()}finally{d.value=!1}}}return x(()=>k(!0)),I(()=>{y=!1}),(n,o)=>(V(),_(`div`,Sr,[a(`section`,Cr,[a(`span`,wr,r(t(i)(`DATA · 数据与备份`)),1),a(`h2`,null,r(t(i)(`留住重要的,整理重复的。`)),1),a(`p`,null,r(t(i)(`这里管理历史备份。聊天、记忆和作品仍在正在运行的数据库里,不会被列入清理。`)),1),c.value?(V(),_(`div`,Tr,[a(`div`,null,[a(`b`,null,r(E(c.value.totalBytes)),1),a(`span`,null,r(t(i)(`可管理的历史备份`)),1)]),a(`div`,null,[a(`b`,null,r(c.value.entries.length),1),a(`span`,null,r(t(i)(`份数据库副本`)),1)]),a(`div`,null,[a(`b`,null,r(E(c.value.plan.bytes)),1),a(`span`,null,r(t(i)(`按当前规则可定时整理`)),1)])])):h(``,!0)]),g.value?(V(),_(`p`,Er,r(g.value),1)):h(``,!0),C(xr),c.value?(V(),_(`div`,Dr,[a(`form`,{class:`card storage-policy`,onSubmit:f(F,[`prevent`])},[a(`div`,Or,[a(`div`,null,[a(`span`,kr,r(t(i)(`定时整理`)),1),a(`h2`,null,r(t(i)(`每天给备份留一点空间`)),1)])]),a(`label`,Ar,[q(a(`input`,{"onUpdate:modelValue":o[0]||=e=>l.value.enabled=e,type:`checkbox`,onChange:A},null,544),[[J,l.value.enabled]]),e(r(t(i)(`启用定时整理`)),1)]),a(`div`,jr,[a(`label`,null,[e(r(t(i)(`每天执行时间`)),1),q(a(`input`,{"onUpdate:modelValue":o[1]||=e=>l.value.time=e,type:`text`,inputmode:`numeric`,maxlength:`5`,placeholder:`04:30`,"aria-label":t(i)(`每天执行时间`),onInput:A},null,40,Mr),[[p,l.value.time]])]),a(`label`,null,[e(r(t(i)(`完整备份保留天数`)),1),q(a(`input`,{"onUpdate:modelValue":o[2]||=e=>l.value.retainDays=e,type:`number`,min:`1`,max:`3650`,"aria-label":t(i)(`完整备份保留天数`),onInput:A},null,40,Nr),[[p,l.value.retainDays,void 0,{number:!0}]])]),a(`label`,null,[e(r(t(i)(`完整备份最多保留份数`)),1),q(a(`input`,{"onUpdate:modelValue":o[3]||=e=>l.value.keepFull=e,type:`number`,min:`0`,max:`100`,"aria-label":t(i)(`完整备份最多保留份数`),onInput:A},null,40,Pr),[[p,l.value.keepFull,void 0,{number:!0}]])])]),a(`p`,Fr,r(t(i)(`时间按服务器本地时区 {zone}。完整备份超过保留天数或数量上限便会定时整理;数量填 0 表示不保留完整备份。手动清理可选择完整备份和迁移快照,执行前会校验同一实例的近期自动恢复点。`,{zone:c.value.serverTimeZone})),1),c.value.last?(V(),_(`p`,Ir,r(c.value.last.error&&c.value.last.removed===0?t(i)(`上次整理未执行:{error}`,{error:c.value.last.error}):t(i)(`上次整理:{time} · {count} 份 · {size}`,{time:D(c.value.last.at),count:c.value.last.removed,size:E(c.value.last.bytes)})),1)):h(``,!0),c.value.last?.error&&c.value.last.removed>0?(V(),_(`p`,Lr,r(c.value.last.error),1)):h(``,!0),a(`button`,{class:`primary`,type:`submit`,disabled:d.value},r(d.value?t(i)(`处理中…`):t(i)(`保存整理规则`)),9,Rr)],32),a(`section`,zr,[a(`div`,Br,[a(`div`,null,[a(`span`,Vr,r(t(i)(`手动整理`)),1),a(`h2`,null,r(t(i)(`挑选历史恢复点`)),1)])]),a(`p`,Hr,r(t(i)(`自动备份已有自己的轮换规则。迁移、旧版本和升级前快照只由你手动挑选;清理前会再次核对文件和恢复点。`)),1),a(`div`,Ur,[a(`button`,{type:`button`,disabled:d.value||!c.value.plan.items.length,onClick:N},r(t(i)(`选中规则建议`)),9,Wr),a(`button`,{type:`button`,disabled:d.value,onClick:P},r(t(i)(`选中完整备份`)),9,Gr),a(`button`,{type:`button`,disabled:d.value||!u.value.length,onClick:o[4]||=e=>u.value=[]},r(t(i)(`取消选择`)),9,Kr)]),a(`div`,qr,[(V(!0),_(m,null,S(c.value.entries,e=>(V(),_(`label`,{key:b(e),class:G([`storage-row`,{protected:e.protected}])},[a(`input`,{type:`checkbox`,checked:u.value.includes(b(e)),disabled:d.value||e.protected||c.value.running,"aria-label":e.name,onChange:t=>j(e)},null,40,Jr),a(`span`,Yr,[a(`strong`,null,r(e.name),1),a(`small`,null,r(O(e.kind))+` · `+r(D(e.at))+` · `+r(e.manifest?t(i)(`有校验清单`):t(i)(`旧备份无清单`))+r(e.protected?` · `+(e.protectionReason||t(i)(`保留恢复点`)):``),1)]),a(`b`,null,r(E(e.bytes)),1)],2))),128))]),v.value.length?(V(),_(`div`,Xr,[a(`p`,null,r(t(i)(`部分备份未清理,请刷新列表后重试`)),1),(V(!0),_(m,null,S(v.value,e=>(V(),_(`p`,{key:e.name},r(e.name)+` · `+r(e.error),1))),128))])):h(``,!0),a(`div`,Zr,[a(`span`,null,r(t(i)(`已选 {count} 份 · 约 {size}`,{count:w.value.length,size:E(T.value)})),1),a(`button`,{class:`primary`,type:`button`,disabled:d.value||c.value.running||!w.value.length,onClick:L},r(t(i)(`清理所选`)),9,Qr)])])])):h(``,!0)]))}}),[[`__scopeId`,`data-v-4593780e`]]),ei={class:`card password-settings`},ti={class:`row`},ni=[`disabled`],ri=N(P({__name:`PasswordSettings`,setup(n){let o=K(``),s=K(``),c=K(``),l=K(!1);async function u(){if(!l.value){if(s.value!==c.value){H(i(`两次输入的密码不一致`),!0);return}l.value=!0;try{await y(`password`,{currentPassword:o.value,password:s.value}),o.value=s.value=c.value=``,H(i(`管理密码已更新`))}catch(e){H(e.message,!0)}finally{l.value=!1}}}return(n,d)=>(V(),_(`section`,ei,[a(`h2`,null,r(t(i)(`管理密码`)),1),a(`p`,null,r(t(i)(`一个密码管理这个小世界。修改后,其他浏览器需要重新登录。`)),1),a(`form`,{onSubmit:f(u,[`prevent`])},[a(`label`,null,[e(r(t(i)(`当前密码`)),1),q(a(`input`,{"onUpdate:modelValue":d[0]||=e=>o.value=e,name:`currentPassword`,type:`password`,autocomplete:`current-password`,required:``},null,512),[[p,o.value]])]),a(`label`,null,[e(r(t(i)(`新密码`)),1),q(a(`input`,{"onUpdate:modelValue":d[1]||=e=>s.value=e,name:`newPassword`,type:`password`,autocomplete:`new-password`,minlength:`8`,maxlength:`256`,required:``},null,512),[[p,s.value]])]),a(`label`,null,[e(r(t(i)(`确认密码`)),1),q(a(`input`,{"onUpdate:modelValue":d[2]||=e=>c.value=e,name:`confirmNewPassword`,type:`password`,autocomplete:`new-password`,minlength:`8`,maxlength:`256`,required:``},null,512),[[p,c.value]])]),a(`div`,ti,[a(`button`,{class:`primary`,disabled:l.value},r(t(i)(`修改密码`)),9,ni),a(`button`,{type:`button`,onClick:d[3]||=(...e)=>t(W)&&t(W)(...e)},r(t(i)(`退出登录`)),1)])],32)]))}}),[[`__scopeId`,`data-v-36cd9f70`]]),ii={class:`card update-settings`,"aria-labelledby":`update-title`},ai={id:`update-title`},oi=[`disabled`],si={class:`kv`},ci={key:0,class:`muted`,role:`alert`},li={class:`muted small-text`},ui={key:1,class:`update-how stack tight`},di=[`disabled`],fi={key:1,role:`status`},pi={key:2,class:`error-text`,role:`alert`},mi={key:3,class:`muted`},hi={class:`update-links`},gi=[`href`],_i=[`href`],vi=N(P({__name:`UpdateSettings`,setup(e){let o=K(null),s=K(!1),l=K(!1),u,d=!1,f=c({queued:A(`更新已开始`),downloading:A(`正在下载新版本…`),checking:A(`正在检查新程序…`),stopping:A(`正在保存当下并停止实例…`),backup:A(`正在保留更新前的校验备份…`),restarting:A(`正在切换版本并重启…`),verifying:A(`正在确认新实例就绪…`),restoring:A(`正在恢复原版本和数据…`),done:A(`更新与重启已完成`),error:A(`更新未完成`)});function p(e){return e&&![`done`,`error`].includes(e.status)}async function g(){if(!d){try{let e=await M(`/system/update`);if(o.value=e,e.operation?.status===`done`){l.value=!1,location.reload();return}l.value=!!p(e.operation)}catch{}l.value&&!d&&(u=setTimeout(g,1800))}}j(()=>{d=!0,clearTimeout(u)});let v=c({unchecked:A(`尚未检查更新`),available:A(`有新版本可用`),current:A(`已是最新发布版本`),ahead:A(`当前版本领先于 npm 发布版本`),unavailable:A(`暂时无法检查更新`)});x(async()=>{try{o.value=await M(`/system/update`),l.value=!!p(o.value.operation),l.value&&(u=setTimeout(g,1800))}catch(e){H(e.message,!0)}});async function y(){if(!s.value){s.value=!0;try{o.value=await M(`/system/update/check`,`POST`,{})}catch(e){H(e.message,!0)}finally{s.value=!1}}}async function b(){if(!(l.value||s.value||o.value?.status!==`available`)&&await n(i(`更新到 {version} 并重启当前实例?先下载校验,再保留数据恢复点;启动失败时尝试恢复原版本。`,{version:o.value.latest}),{title:i(`更新并重启`),confirmText:i(`开始更新`)})){l.value=!0;try{o.value.operation=await M(`/system/update/install`,`POST`,{version:o.value.latest}),u=setTimeout(g,800)}catch(e){l.value=!1,H(e.message,!0)}}}return(e,n)=>(V(),_(`section`,ii,[a(`header`,null,[a(`div`,null,[n[0]||=a(`span`,{class:`eyebrow`},`LUCKYTRI / VERSION`,-1),a(`h2`,ai,r(t(i)(`版本与更新`)),1)]),a(`button`,{disabled:s.value||l.value||!o.value,onClick:y},r(s.value?t(i)(`正在检查…`):t(i)(`检查更新`)),9,oi)]),o.value?(V(),_(m,{key:0},[a(`p`,{class:G([`version-state`,{available:o.value.status===`available`}]),role:`status`},r(t(v)[o.value.status]||t(v).unchecked),3),a(`dl`,si,[a(`dt`,null,r(t(i)(`当前版本`)),1),a(`dd`,null,r(o.value.current),1),a(`dt`,null,r(t(i)(`npm 最新版本`)),1),a(`dd`,null,r(o.value.latest||`—`),1),a(`dt`,null,r(t(i)(`上次成功检查`)),1),a(`dd`,null,r(o.value.checkedAt?t(te)(o.value.checkedAt):`—`),1)]),o.value.error?(V(),_(`p`,ci,r(t(i)(`暂时无法连接 npm 或读取版本信息,请稍后重试。`)),1)):h(``,!0),a(`p`,li,r(t(i)(`点击时才检查,五分钟内复用结果。检查更新不会自动安装或重启。`)),1),o.value.status===`available`||o.value.operation?(V(),_(`div`,ui,[a(`p`,null,r(t(i)(`下载期间继续运行,切换前保留数据恢复点。更新完成后此页面会自动重新连接。`)),1),o.value.status===`available`?(V(),_(`button`,{key:0,class:`primary`,disabled:l.value||s.value,onClick:b},r(l.value?t(i)(`正在更新…`):t(i)(`更新并重启`)),9,di)):h(``,!0),o.value.operation?(V(),_(`p`,fi,r(t(f)[o.value.operation.status])+` · `+r(o.value.operation.version),1)):h(``,!0),o.value.operation?.error?(V(),_(`p`,pi,r(o.value.operation.error),1)):h(``,!0),o.value.operation?.restored?(V(),_(`p`,mi,r(t(i)(`已恢复原版本和更新前的数据。`)),1)):h(``,!0)])):h(``,!0),a(`nav`,hi,[a(`a`,{href:o.value.npmUrl,target:`_blank`,rel:`noopener noreferrer`},`npm`,8,gi),a(`a`,{href:o.value.releaseUrl,target:`_blank`,rel:`noopener noreferrer`},r(t(i)(`发布说明`))+` ↗`,9,_i)])],64)):h(``,!0)]))}}),[[`__scopeId`,`data-v-950f6f7a`]]),yi={class:`page system`},bi={class:`system-intro`},xi={class:`eyebrow`},Si={class:`system-status`},Ci=N(P({__name:`SystemPage`,setup(o){let s=[`connect`,`models`,`search`,`runtime`,`storage`],c=K(s.includes(B.sub)?B.sub:`connect`);async function l(e){e!==c.value&&(!B.dirty||await n(i(`当前设置还没保存,离开这个分区吗?`),{title:i(`未保存的修改`),confirmText:i(`放弃修改`),cancelText:i(`继续编辑`)}))&&(B.dirty=!1,c.value=e)}return E(c,e=>F(e)),E(()=>B.sub,e=>{s.includes(e)&&(c.value=e)}),(n,o)=>(V(),_(`div`,yi,[a(`header`,bi,[a(`div`,null,[a(`span`,xi,r(t(i)(`THE WORLD AROUND HER · 系统`)),1),a(`h1`,null,[e(r(t(i)(`让她与世界,`)),1),a(`em`,null,r(t(i)(`温柔相连。`)),1)]),a(`p`,null,r(t(i)(`连接、模型与运行方式都在这里。每一处改变,都可以看见结果。`)),1)]),a(`span`,Si,[a(`i`,{class:G({off:!t(B).health.connection?.online})},null,2),e(` `+r(t(B).health.connection?.online?t(i)(`正在与 QQ 相连`):t(i)(`等待 QQ 连接`)),1)])]),C(X,{"model-value":c.value,"onUpdate:modelValue":l,label:t(i)(`系统的分区`),items:[{key:`connect`,label:t(i)(`连接 QQ`)},{key:`models`,label:t(i)(`模型库`)},{key:`search`,label:t(i)(`独立搜索`)},{key:`runtime`,label:t(i)(`运行开关`)},{key:`storage`,label:t(i)(`数据与备份`)}]},null,8,[`model-value`,`label`,`items`]),c.value===`connect`?(V(),g(Ue,{key:0,onOpen:l})):c.value===`models`?(V(),g(vn,{key:1})):c.value===`search`?(V(),g(er,{key:2})):c.value===`runtime`?(V(),_(m,{key:3},[C(jn),C(vi),C(ri)],64)):(V(),g($r,{key:4}))]))}}),[[`__scopeId`,`data-v-a12a372e`]]);export{Ci as default};
1
+ import{$ as e,Ct as t,E as n,Et as r,I as i,J as a,M as o,N as s,P as c,S as l,T as u,Tt as d,U as f,V as p,W as m,X as h,Y as g,Z as _,a as v,b as y,bt as b,ct as x,dt as S,et as C,f as w,ft as T,gt as E,h as D,ht as O,i as k,j as A,lt as j,m as M,n as N,nt as P,o as F,ot as I,p as L,q as R,rt as z,s as B,t as ee,ut as V,v as H,vt as U,w as W,wt as G,xt as K,yt as q,z as J}from"./Empty-C7yzOBzy.js";import{v as te}from"./mind-DtTVrW6Z.js";import{c as Y,f as ne,l as re,n as X,o as ie}from"./index-CyRtYxP3.js";var ae={class:`connect`},oe={class:`card connection`},Z={class:`card-head`},Q={class:`eyebrow`},se={class:`pill`},ce={key:0,class:`notice`,role:`note`},le={class:`muted`},ue={class:`connection-details`},de={class:`detail`},fe={class:`instructions`},pe={class:`muted`},me={class:`muted note`},$={key:0,class:`row`},he=[`disabled`],ge={class:`muted`},_e=[`disabled`,`placeholder`],ve={key:0,class:`faint`},ye=[`disabled`,`placeholder`],be={key:0,class:`faint`},xe={class:`row`},Se=[`disabled`],Ce={key:0,class:`faint`},we={key:0,class:`connection-details`},Te={class:`detail`},Ee={"data-state":``},De={key:0,class:`detail`},Oe={class:`warn-text`},ke={key:1,class:`detail`},Ae={class:`detail`},je={class:`detail`},Me={key:1,class:`notice`,role:`note`},Ne={class:`instructions`},Pe={class:`muted notes`},Fe={class:`card checklist`},Ie={class:`card-head`},Le={class:`eyebrow`},Re={class:`chip`},ze={class:`checks`},Be={class:`mark`,"aria-hidden":`true`},Ve={class:`muted`},He=[`data-fix`,`onClick`],Ue=N(P({__name:`ConnectQQ`,emits:[`open`],setup(o,{emit:s}){let l=s,u=R(()=>B.health.connection||{}),d=R(()=>u.value.channel===`qqbot`?`qqbot`:`onebot`),g=R(()=>!!u.value.locked),y=R(()=>!!u.value.online);R(()=>u.value.onebot||{});let x=R(()=>u.value.qqbot||{}),w=R(()=>String(B.health.settings.qqbotAppId||``)),T=R(()=>!!B.health.settings.hasQqbotSecret),D=K(d.value);E(d,e=>D.value=e);let O=R(()=>`${location.protocol===`https:`?`wss`:`ws`}://${location.host}/onebot/v11/ws`),N=R(()=>[{key:`onebot`,label:i(`OneBot 11`),count:d.value===`onebot`?i(`使用中`):``},{key:`qqbot`,label:i(`QQ 官方机器人`),count:d.value===`qqbot`?i(`使用中`):``}]),P=b({appId:w.value,secret:``}),F=K(!1),I=R(()=>P.appId.trim()!==w.value||!!P.secret.trim());E(I,e=>{B.dirty=e}),E(w,e=>{I.value||(P.appId=e)}),j(()=>{B.dirty=!1});let L=R(()=>!!P.appId.trim()&&(T.value||!!P.secret.trim())),z=c({idle:A(`未启用`),unconfigured:A(`尚未填写 AppID 与 AppSecret`),connecting:A(`正在连接开放平台`),ready:A(`已连接`),closed:A(`连接已断开,正在重连`),error:A(`连接出错`)}),ee=c({all:A(`全部群消息`),mentions:A(`只有 @ 她的消息`),unknown:A(`尚未收到群消息`)}),U=R(()=>z[x.value.state||`idle`]??z.idle),W=R(()=>ee[x.value.groupMessages||`unknown`]??ee.unknown),J=R(()=>d.value===`qqbot`&&x.value.groupMessages===`mentions`);async function te(e){if(F.value||g.value||e===d.value)return;let t=i(e===`qqbot`?`QQ 官方机器人`:`OneBot 11`);if(!y.value||await n(i(`切换后会断开当前连接。原来方式下的会话仍可查看,但不能再向它们发送消息。`),{title:i(`切换连接方式`),confirmText:i(`切换`),cancelText:i(`先不切换`)})){F.value=!0;try{await M(`/settings`,`PATCH`,{channel:e}),await v(),H(i(`已切换为 {name}`,{name:t}))}catch(e){H(e.message,!0)}finally{F.value=!1}}}async function Y(){if(!F.value){if(!L.value){H(i(`请填写 AppID 和 AppSecret`),!0);return}F.value=!0;try{let e={qqbotAppId:P.appId.trim()};P.secret.trim()&&(e.qqbotSecret=P.secret.trim()),d.value!==`qqbot`&&!g.value&&(e.channel=`qqbot`),await M(`/settings`,`PATCH`,e),P.secret=``,await v(),H(i(`已保存`))}catch(e){H(e.message,!0)}finally{F.value=!1}}}let ne={token:[``,`connect`],credentials:[``,`connect`],qq:[``,`connect`],model:[``,`models`],mode:[``,`runtime`],session:[`chats`,``],persona:[`nature`,``]};function ie(e){let[t,n]=ne[e]||[``,`connect`];t?k(t):l(`open`,n)}return(n,o)=>(V(),_(`div`,ae,[a(`section`,oe,[a(`div`,Z,[a(`div`,null,[a(`span`,Q,r(t(i)(`QQ`)),1),a(`h2`,null,r(t(i)(`连接 QQ`)),1),a(`p`,null,r(t(i)(`两种连接方式二选一,同一时间只使用一种。她的记忆、心情和行为完全一致,区别只在消息怎么到达。`)),1)]),a(`span`,se,[a(`span`,{class:G([`dot`,{off:!y.value}])},null,2),e(` `+r(y.value?t(i)(`QQ 已连接`):t(i)(`等待连接`)),1)])]),C(X,{modelValue:D.value,"onUpdate:modelValue":o[0]||=e=>D.value=e,label:t(i)(`连接方式`),items:N.value},null,8,[`modelValue`,`label`,`items`]),g.value?(V(),_(`p`,ce,r(t(i)(`连接方式由环境变量 LUCKYTRI_CHANNEL 指定,在这里不能更改。去掉该变量后即可在此选择。`)),1)):h(``,!0),D.value===`onebot`?(V(),_(m,{key:1},[a(`p`,le,r(t(i)(`自备接入端,通过反向 WebSocket 连接。能看到全部群消息。`)),1),a(`div`,ue,[a(`div`,de,[a(`span`,null,r(t(i)(`反向 WebSocket 地址`)),1),a(`code`,null,r(O.value),1)])]),a(`ol`,fe,[a(`li`,null,r(t(i)(`同一台电脑上的接入端无需单独配置连接令牌。`)),1),a(`li`,null,r(t(i)(`在接入端启用反向 WebSocket 客户端,填写上方地址,消息格式选择数组。已有的地址配置可以继续使用。`)),1),a(`li`,null,r(t(i)(`在接入端完成 QQ 登录。连接成功后,本页状态会更新;新会话仍需在「对话」中开启参与。`)),1)]),a(`p`,pe,r(t(i)(`远程接入时,连接密码使用管理密码;已有的远程连接令牌仍兼容。`)),1),a(`p`,me,r(t(i)(`LuckyTri 只负责接收,不提供、不安装也不管理接入端。`)),1),d.value===`onebot`?h(``,!0):(V(),_(`div`,$,[a(`button`,{class:`primary`,"data-use":`onebot`,disabled:F.value||g.value,onClick:o[1]||=e=>te(`onebot`)},r(t(i)(`改用这种方式`)),9,he)]))],64)):(V(),_(m,{key:2},[a(`p`,ge,r(t(i)(`只需 AppID 与 AppSecret,无需额外软件。群里默认只收到 @ 她的消息。`)),1),a(`form`,{class:`stack tight`,onSubmit:f(Y,[`prevent`])},[a(`label`,null,[e(r(t(i)(`AppID`))+` `,1),q(a(`input`,{"onUpdate:modelValue":o[2]||=e=>P.appId=e,name:`qqbotAppId`,autocomplete:`off`,inputmode:`numeric`,maxlength:`40`,disabled:F.value||x.value.appIdFromEnv,placeholder:t(i)(`机器人的 AppID`)},null,8,_e),[[p,P.appId]]),x.value.appIdFromEnv?(V(),_(`small`,ve,r(t(i)(`由环境变量指定,在这里不能修改`)),1)):h(``,!0)]),a(`label`,null,[e(r(t(i)(`AppSecret`))+` `,1),q(a(`input`,{"onUpdate:modelValue":o[3]||=e=>P.secret=e,name:`qqbotSecret`,type:`password`,autocomplete:`new-password`,maxlength:`200`,disabled:F.value||x.value.secretFromEnv,placeholder:T.value||x.value.secretFromEnv?t(i)(`已保存,留空保留`):t(i)(`机器人的 AppSecret`)},null,8,ye),[[p,P.secret]]),x.value.secretFromEnv?(V(),_(`small`,be,r(t(i)(`由环境变量指定,在这里不能修改`)),1)):h(``,!0)]),a(`div`,xe,[a(`button`,{class:`primary`,"data-save":`qqbot`,disabled:F.value||x.value.appIdFromEnv&&x.value.secretFromEnv},r(d.value===`qqbot`||g.value?t(i)(`保存`):t(i)(`保存并使用`)),9,Se),I.value?(V(),_(`span`,Ce,r(t(i)(`有尚未保存的修改`)),1)):h(``,!0)])],32),d.value===`qqbot`?(V(),_(`div`,we,[a(`div`,Te,[a(`span`,null,r(t(i)(`连接状态`)),1),a(`strong`,Ee,r(U.value),1)]),x.value.error?(V(),_(`div`,De,[o[4]||=a(`span`,null,null,-1),a(`small`,Oe,r(x.value.error),1)])):h(``,!0),x.value.botName?(V(),_(`div`,ke,[a(`span`,null,r(t(i)(`机器人`)),1),a(`strong`,null,r(x.value.botName),1)])):h(``,!0),a(`div`,Ae,[a(`span`,null,r(t(i)(`最近收到消息`)),1),a(`strong`,null,r(x.value.lastEventAt?t(re)(x.value.lastEventAt):t(i)(`还没有`)),1)]),a(`div`,je,[a(`span`,null,r(t(i)(`群消息范围`)),1),a(`strong`,null,r(W.value),1)])])):h(``,!0),J.value?(V(),_(`p`,Me,r(t(i)(`目前只收到 @ 她的群消息。想让她看到群里的全部消息,请在开放平台的机器人设置里开启「接收所有消息」。`)),1)):h(``,!0),a(`ol`,Ne,[a(`li`,null,r(t(i)(`在 QQ 开放平台创建机器人,取得 AppID 与 AppSecret。`)),1),a(`li`,null,r(t(i)(`把运行 LuckyTri 的这台机器的出口 IP 加入机器人的 IP 白名单。`)),1),a(`li`,null,r(t(i)(`可选:开启「接收所有消息」,她才能看到群里没有 @ 她的话;不开启时只会收到 @ 她的消息。`)),1),a(`li`,null,r(t(i)(`填写上方的 AppID 与 AppSecret 并保存。状态变为「已连接」后,在群里 @ 她或私聊她,新会话会出现在「对话」中。`)),1)]),a(`ul`,Pe,[a(`li`,null,r(t(i)(`官方平台不提供群名称:新会话以占位名出现,可以在「对话」中为它改名。`)),1),a(`li`,null,r(t(i)(`官方平台上,同一个人在不同的群里标识不同。像只在不同的房间见过对方一样,平台给出统一身份之前,她不会把两处的人当成同一个人。`)),1),a(`li`,null,r(t(i)(`对方关闭了机器人的主动消息时,她不会去打扰,会等对方来找她。`)),1)])],64))]),a(`section`,Fe,[a(`div`,Ie,[a(`div`,null,[a(`span`,Le,r(t(i)(`就绪检查`)),1),a(`h2`,null,r(t(i)(`还差哪一步`)),1)]),a(`span`,Re,r(t(B).health.readiness?.completed??0)+` / `+r(t(B).health.readiness?.total??0),1)]),a(`ol`,ze,[(V(!0),_(m,null,S(t(B).health.readiness?.checks||[],e=>(V(),_(`li`,{key:e.id,class:G({done:e.done})},[a(`span`,Be,r(e.done?`✓`:``),1),a(`div`,null,[a(`b`,null,r(e.name),1),a(`small`,Ve,r(e.detail),1)]),a(`button`,{class:`small`,"data-fix":e.id,onClick:t=>ie(e.id)},r(e.done?t(i)(`查看`):t(i)(`去处理`)),9,He)],2))),128))])])]))}}),[[`__scopeId`,`data-v-6f4553ed`]]);async function We(e){return M(`/core/models`,`PUT`,{models:e})}async function Ge(e){return M(`/core/models/`+encodeURIComponent(e),`DELETE`,{})}async function Ke(e){return M(`/model/test`,`POST`,{modelId:e})}var qe={class:`card embedding-profile`,"aria-labelledby":`embedding-title`},Je={id:`embedding-title`},Ye={class:`muted`},Xe={key:0,class:`faint`},Ze={class:`check`},Qe={class:`fields`},$e=[`required`],et=[`required`],tt=[`placeholder`],nt={class:`save-bar`},rt=[`disabled`],it=[`disabled`],at={class:`faint`},ot={key:2,role:`status`},st=N(P({__name:`EmbeddingProfile`,setup(n){let o=b({enabled:!1,label:i(`知识向量`),baseUrl:``,model:``,apiKey:``,dimensions:0,batchSize:32,timeoutMs:9e4}),s=K(!1),c=K(!1),l=K(!1),u=K(``);async function d(){try{Object.assign(o,await M(`/core/knowledge/embedding`),{apiKey:``}),l.value=!0}catch(e){u.value=e.message}}async function m(){s.value=!0;try{Object.assign(o,await M(`/core/knowledge/embedding`,`PATCH`,o),{apiKey:``}),c.value=!1,H(i(`知识向量模型已保存`))}catch(e){H(e.message,!0)}finally{s.value=!1}}async function g(){s.value=!0;try{let e=await M(`/core/knowledge/embedding/test`,`POST`,{});u.value=i(`连接成功,向量维度 {dimensions}`,{dimensions:e.dimensions})}catch(e){u.value=e.message}finally{s.value=!1}}return x(d),(n,d)=>(V(),_(`section`,qe,[a(`h2`,Je,r(t(i)(`知识向量模型`)),1),a(`p`,Ye,r(t(i)(`单独配置资料检索使用的模型。更换对话模型后仍使用这里的配置。更换向量模型后,可在资料书架逐份重建向量;原文仍能通过关键词检索。`)),1),l.value&&!o.configured?(V(),_(`p`,Xe,r(t(i)(`当前兼容旧配置,跟随默认模型。保存后改用独立配置。`)),1)):h(``,!0),l.value?(V(),_(`form`,{key:1,onSubmit:f(m,[`prevent`]),onInput:d[6]||=e=>c.value=!0,onChange:d[7]||=e=>c.value=!0},[a(`label`,Ze,[q(a(`input`,{"onUpdate:modelValue":d[0]||=e=>o.enabled=e,type:`checkbox`,name:`embeddingEnabled`},null,512),[[J,o.enabled]]),e(r(t(i)(`启用知识向量`)),1)]),a(`div`,Qe,[a(`label`,null,[e(r(t(i)(`API 地址`)),1),q(a(`input`,{"onUpdate:modelValue":d[1]||=e=>o.baseUrl=e,name:`embeddingBaseUrl`,type:`url`,required:o.enabled,placeholder:`https://example.com/v1`},null,8,$e),[[p,o.baseUrl]])]),a(`label`,null,[e(r(t(i)(`模型名称`)),1),q(a(`input`,{"onUpdate:modelValue":d[2]||=e=>o.model=e,name:`embeddingModelName`,required:o.enabled},null,8,et),[[p,o.model]])]),a(`label`,null,[e(r(t(i)(`独立 API Key`)),1),q(a(`input`,{"onUpdate:modelValue":d[3]||=e=>o.apiKey=e,name:`embeddingApiKey`,type:`password`,autocomplete:`new-password`,placeholder:o.hasApiKey?t(i)(`已保存,留空保留`):t(i)(`填写向量服务密钥`)},null,8,tt),[[p,o.apiKey]])]),a(`label`,null,[e(r(t(i)(`向量维度(0 表示自动)`)),1),q(a(`input`,{"onUpdate:modelValue":d[4]||=e=>o.dimensions=e,name:`embeddingDimensions`,type:`number`,min:`0`,max:`65536`},null,512),[[p,o.dimensions,void 0,{number:!0}]])]),a(`label`,null,[e(r(t(i)(`每批段落数`)),1),q(a(`input`,{"onUpdate:modelValue":d[5]||=e=>o.batchSize=e,name:`embeddingBatchSize`,type:`number`,min:`1`,max:`128`},null,512),[[p,o.batchSize,void 0,{number:!0}]])])]),a(`div`,nt,[a(`button`,{class:`primary`,disabled:s.value},r(t(i)(`保存向量模型`)),9,rt),a(`button`,{type:`button`,disabled:s.value||c.value||!o.enabled||!o.configured,onClick:g},r(t(i)(`测试向量连接`)),9,it),a(`small`,at,r(c.value?t(i)(`有未保存的修改`):t(i)(`配置已载入`)),1)])],32)):h(``,!0),u.value?(V(),_(`p`,ot,r(u.value),1)):h(``,!0)]))}}),[[`__scopeId`,`data-v-6873efbb`]]),ct={class:`library`},lt={class:`model-workspace`},ut={class:`card shelf`},dt={class:`shelf-head`},ft={class:`faint`},pt={class:`rows`},mt={key:0,class:`muted`},ht=[`open`,`data-saved-vendor`,`onToggle`],gt={class:`vendor-models`},_t=[`onClick`],vt={class:`who`},yt={key:0,class:`card detail`},bt={class:`card-head`},xt={class:`eyebrow`},St=[`data-tone`],Ct={class:`form-grid`},wt={key:0},Tt=[`placeholder`],Et={class:`wide`},Dt=[`placeholder`],Ot={class:`faint`},kt={class:`form-grid`},At={key:0},jt={key:1},Mt={class:`advanced`},Nt={class:`form-grid`},Pt=[`placeholder`],Ft={class:`faint`},It={class:`caps`},Lt=[`onUpdate:modelValue`,`name`],Rt={key:0,id:`modelTestResult`,class:`notice`,role:`status`},zt={class:`actions`},Bt=[`disabled`],Vt={class:`faint`},Ht={key:0,class:`check`},Ut=[`checked`],Wt=[`disabled`],Gt={key:1,class:`card detail`},Kt={class:`card usage-panel`,"aria-labelledby":`token-usage-title`},qt={class:`usage-intro`},Jt={class:`eyebrow`},Yt={id:`token-usage-title`},Xt={class:`usage-total`},Zt={class:`usage-detail`},Qt={class:`usage-stat`},$t={class:`usage-stat`},en={class:`usage-stat cache-stat`},tn={class:`usage-stat`},nn={class:`usage-foot`},rn={key:0},an={key:1,class:`usage-error`},on={key:2},sn=[`disabled`],cn={class:`model-picker`},ln={class:`muted`},un={class:`catalog-search`},dn=[`placeholder`],fn=[`data-vendor`],pn={class:`vendor-summary`},mn={class:`vendor-name`},hn={class:`presets`},gn=[`data-preset`,`onClick`],_n={key:0,class:`muted search-empty`},vn=N(P({__name:`ModelLibrary`,setup(s){let c=R(()=>B.health?.modelCatalog||[]),l=R(()=>B.health?.effortLabels||{none:i(`关闭`),minimal:i(`极低`),low:i(`低`),medium:i(`中`),high:i(`高`),xhigh:i(`极高`),max:i(`最深`)}),u=K(B.core.models.map(e=>({...e}))),g=K(u.value.length?0:-1),y=K(u.value.length?Q(u.value[0]):``),w=K(!1),T=K(!1),D=K(!1),O=K(``),k=K(``),A=K(null),j=K(!1),N=K(``),P=b(Z());u.value[0]&&Object.assign(P,u.value[0],{apiKey:``});let F=R(()=>g.value>=0&&!!P.id),I=R(()=>{let e=[];for(let t of c.value){if(t.id===`custom`)continue;let n=e.find(e=>e.vendor===t.vendor);n||(n={vendor:t.vendor,models:[]},e.push(n)),n.models.push(t)}return e}),L=R(()=>{let e=O.value.trim().toLocaleLowerCase();return e?I.value.map(t=>({...t,models:t.models.filter(n=>[t.vendor,n.label,n.model,n.summary].filter(Boolean).join(` `).toLocaleLowerCase().includes(e))})).filter(e=>e.models.length):I.value}),z=R(()=>{let e=[];return u.value.forEach((t,n)=>{let r=Q(t),i=e.find(e=>e.vendor===r);i||(i={vendor:r,models:[]},e.push(i)),i.models.push({model:t,index:n})}),e}),W=R(()=>c.value.find(e=>e.id===`custom`)),te=R(()=>c.value.filter(e=>e.vendor&&e.vendor===P.vendor)),re=R(()=>c.value.find(e=>e.id===P.presetId)||c.value.find(e=>e.model&&e.model===P.model&&e.baseUrl===P.baseUrl)),X=R(()=>{let e=re.value?.contextWindows||[];if(e.length<2)return[];let t=Number(P.contextWindow);return e.some(e=>e.contextWindow===t)?e:[...e,{label:i(`已保存 {value}`,{value:fe(t)}),contextWindow:t,maxInputTokens:Number(P.maxInputTokens),maxOutputTokens:Number(P.maxOutputTokens)}]}),ae=R(()=>{let e=Array.isArray(P.reasoningEfforts)&&P.reasoningEfforts.length?[...P.reasoningEfforts]:[`none`,`minimal`,`low`,`medium`,`high`,`xhigh`,`max`];return P.reasoningEffort&&!e.includes(P.reasoningEffort)&&e.unshift(P.reasoningEffort),e}),oe=R(()=>B.core.models.some(e=>e.id===P.id));function Z(){return{id:``,presetId:``,label:``,provider:``,vendor:``,baseUrl:``,model:``,apiKey:``,hasApiKey:!1,contextWindow:128e3,maxInputTokens:119808,maxOutputTokens:8192,vision:!1,system:!0,json:!0,tools:!1,embedding:!1,embeddingModel:``,reasoningEffort:`none`,reasoningEfforts:[`none`,`low`,`medium`,`high`],thinkingStyle:`openai`,tokenField:`max_tokens`,omitSampling:!1,temperature:.85,topP:1,timeoutMs:9e4,isDefault:!1,enabled:!0}}function Q(e){let t={"volcengine-coding-plan":i(`火山方舟 Coding Plan`),"opencode-go":`OpenCode Go`,"opencode-zen":`OpenCode Zen`,deepseek:`DeepSeek`,openai:`OpenAI`,bedrock:i(`亚马逊 Bedrock`),qwen:i(`通义千问`),moonshot:`Kimi`,kimi:`Kimi`,zhipu:i(`智谱 GLM`),glm:i(`智谱 GLM`),mimo:i(`小米 MiMo`),siliconflow:`SiliconFlow`,openrouter:`OpenRouter`};return String(e?.vendor||``).trim()||t[String(e?.provider||``).toLowerCase()]||String(e?.provider||i(`自定义供应商`))}function se(e,t){let n=t.currentTarget;y.value=n.open?e:``}function ce(e){let{summary:t,contextWindows:n,...r}=e;return{...r,presetId:e.id}}function le(e){let{contextWindows:t,...n}=e;return n}function ue(e){let t=Number(e.contextWindow),n=Number(e.maxOutputTokens),r=Number(e.maxInputTokens);return(!Number.isFinite(t)||t<2)&&(t=2),(!Number.isFinite(n)||n<1)&&(n=1),n>=t&&(n=t-1),(!Number.isFinite(r)||r<1)&&(r=t-n),r+n>t&&(r=t-n),{contextWindow:t,maxInputTokens:r,maxOutputTokens:n}}function de(e){let t=Number(e.target.value),n=X.value.find(e=>e.contextWindow===t);n&&(P.contextWindow=n.contextWindow,P.maxInputTokens=n.maxInputTokens,P.maxOutputTokens=n.maxOutputTokens,B.dirty=!0)}function fe(e){let t=Number(e)||0;return t>=1e6?(t%1048576==0?t/1048576:Number((t/1e6).toFixed(2)))+`M`:t>=1e3?(t%1e3==0?t/1e3:t%1024==0?t/1024:Math.round(t/1e3))+`K`:String(t)}function pe(e){if(e.id===`openrouter`)return i(`按所选模型填写上下文和输出参数`);if(!e.model)return i(`填写模型 ID 和对应参数`);let t=e.contextWindows||[],n=t.length?t.map(e=>e.label).join(` / `):fe(e.contextWindow);return i(`上下文 {context} · 输出 {v}`,{context:n,v:fe(e.maxOutputTokens)})}function me(e){return[`mimo`,`qwen`,`kimi-toggle`].includes(P.thinkingStyle)?i(e===`none`?`关闭`:`开启`):`${l.value[e]||e} / ${e}`}function $(e){return new Intl.NumberFormat(o()).format(Number(e)||0)}async function he(){if(!j.value){j.value=!0;try{A.value=await M(`/core/usage`),N.value=``}catch(e){N.value=e.message}finally{j.value=!1}}}x(()=>void he()),E(()=>B.tick,()=>void he());async function ge(){return B.dirty?await n(i(`放弃当前模型草稿?`),{title:i(`草稿还没保存`),confirmText:i(`放弃`),cancelText:i(`留下`)})?(B.dirty=!1,!0):!1:!0}async function _e(e){let t=u.value[e];t&&t.id!==P.id&&await ge()&&(u.value=u.value.filter(e=>e.id===t.id||B.core.models.some(t=>t.id===e.id)),g.value=u.value.findIndex(e=>e.id===t.id),y.value=Q(t),Object.assign(P,Z(),t,{apiKey:``}),k.value=``)}async function ve(){if(!await ge())return;u.value=B.core.models.map(e=>({...e})),u.value.length?u.value.some(e=>e.id===P.id)||(g.value=0,Object.assign(P,Z(),u.value[0],{apiKey:``})):(g.value=-1,Object.assign(P,Z()));let e=u.value[g.value]||u.value[0];y.value=e?Q(e):``,O.value=``,D.value=!0}function ye(e){u.value=B.core.models.map(e=>({...e}));let t={...Z(),...ce(e),id:`model-`+Date.now(),apiKey:``,hasApiKey:!1,isDefault:u.value.length===0};u.value.push(t),g.value=u.value.length-1,y.value=Q(t),Object.assign(P,t),k.value=``,D.value=!1,B.dirty=!0}function be(e){let t=e.target.value,n=c.value.find(e=>e.id===t);if(!n)return;Object.assign(P,Z(),ce(n),{id:P.id,apiKey:P.apiKey,hasApiKey:P.hasApiKey,isDefault:P.isDefault});let r=u.value[g.value];r&&(r.label=P.label),B.dirty=!0}function xe(){for(let e of u.value)e.isDefault=e.id===P.id;P.isDefault=!0,B.dirty=!0}async function Se(){let e=ue(P),t=u.value.map((t,n)=>le(n===g.value?{...P,...e,isDefault:!!P.isDefault,enabled:P.isDefault?!0:P.enabled!==!1,timeoutMs:Number(P.timeoutMs),temperature:Number(P.temperature),topP:Number(P.topP)}:{...t,isDefault:!!t.isDefault&&t.id!==P.id}));if(!t.some(e=>e.isDefault)&&t.length&&(t[0].isDefault=!0),!w.value){w.value=!0;try{await We(t),B.dirty=!1,await v(),u.value=B.core.models.map(e=>({...e})),Object.assign(P,Z(),u.value[g.value],{apiKey:``}),H(i(`已保存并应用`))}catch(e){H(e.message,!0)}finally{w.value=!1}}}async function Ce(){if(await n(i(`确定删除这个模型?`),{title:i(`删除模型`),confirmText:i(`删除`),danger:!0})){if(B.core.models.some(e=>e.id===P.id)&&await Ge(P.id),B.dirty=!1,await v(),u.value=B.core.models.map(e=>({...e})),k.value=``,!u.value.length){g.value=-1,y.value=``,Object.assign(P,Z());return}g.value=0,y.value=Q(u.value[0]),Object.assign(P,Z(),u.value[0],{apiKey:``})}}async function we(){if(!(!oe.value||B.dirty||T.value)){T.value=!0,k.value=i(`正在测试「{v}」…`,{v:P.label||P.model});try{let e=await Ke(P.id);k.value=i(`✓ {v} 连接成功 · {latency} ms`,{v:P.label||e.model,latency:e.latency}),await v()}catch(e){k.value=e.message}finally{T.value=!1}}}return(n,s)=>(V(),_(`div`,ct,[a(`div`,lt,[a(`aside`,ut,[a(`div`,dt,[a(`h2`,null,[e(r(t(i)(`模型库`))+` `,1),a(`small`,null,r(u.value.length),1)]),a(`button`,{id:`addModel`,class:`small primary`,onClick:ve},r(t(i)(`+ 新增模型`)),1)]),a(`p`,ft,r(t(i)(`群聊、私聊和独处都使用默认模型。其余已启用的模型按这里的顺序作为备用。关掉的模型不会被调用。`)),1),a(`div`,pt,[u.value.length?h(``,!0):(V(),_(`p`,mt,r(t(i)(`还没有模型。`)),1)),(V(!0),_(m,null,S(z.value,e=>(V(),_(`details`,{key:e.vendor,class:`saved-vendor`,open:y.value===e.vendor,"data-saved-vendor":e.vendor,onToggle:t=>se(e.vendor,t)},[a(`summary`,null,[a(`span`,null,r(e.vendor),1),a(`small`,null,r(t(i)(`{length} 个模型`,{length:e.models.length})),1)]),a(`div`,gt,[(V(!0),_(m,null,S(e.models,e=>(V(),_(`button`,{key:e.model.id,class:G([`entity-row`,{selected:g.value===e.index}]),onClick:t=>_e(e.index)},[a(`span`,{class:`badge`,style:d({"--hue":t(ne)(e.model.label||e.model.model||e.model.id)})},r(String(e.model.label||e.model.model||`?`).slice(0,1).toUpperCase()),5),a(`span`,vt,[a(`b`,null,r(e.model.label||e.model.model),1),a(`small`,null,r(e.model.enabled===!1?t(i)(`已关闭`):e.model.isDefault?t(i)(`默认模型`):t(i)(`备用模型`)),1)])],10,_t))),128))])],40,ht))),128))])]),F.value?(V(),_(`section`,yt,[a(`div`,bt,[a(`div`,null,[a(`span`,xt,r(t(i)(`模型档案`)),1),a(`h2`,null,r(P.label||t(i)(`新模型`)),1)]),a(`span`,{class:`chip`,"data-tone":P.hasApiKey?`ok`:`warn`},r((P.isDefault?t(i)(`默认模型 · `):``)+(P.hasApiKey?t(i)(`密钥已保存`):t(i)(`待填写密钥`))),9,St)]),a(`form`,{id:`modelForm`,class:`stack`,onSubmit:f(Se,[`prevent`]),onInput:s[14]||=e=>t(B).dirty=!0},[a(`fieldset`,null,[a(`legend`,null,r(t(i)(`连接`)),1),a(`div`,Ct,[te.value.length>1?(V(),_(`label`,wt,[e(r(t(i)(`同厂商模型`))+` `,1),C(Y,{"model-value":P.presetId,"aria-label":t(i)(`同厂商模型`),options:te.value.map(e=>({value:e.id,label:e.label})),onChange:be},null,8,[`model-value`,`aria-label`,`options`])])):h(``,!0),a(`label`,null,[e(r(t(i)(`显示名称`)),1),q(a(`input`,{"onUpdate:modelValue":s[0]||=e=>P.label=e,name:`label`,required:``},null,512),[[p,P.label]])]),a(`label`,null,[e(r(t(i)(`供应商`)),1),q(a(`input`,{"onUpdate:modelValue":s[1]||=e=>P.provider=e,name:`provider`,placeholder:t(i)(`例如 deepseek、openai`)},null,8,Tt),[[p,P.provider]])]),a(`label`,null,[e(r(t(i)(`API 地址`)),1),q(a(`input`,{"onUpdate:modelValue":s[2]||=e=>P.baseUrl=e,name:`baseUrl`,type:`url`,required:``},null,512),[[p,P.baseUrl]])]),a(`label`,null,[e(r(t(i)(`模型名称`)),1),q(a(`input`,{"onUpdate:modelValue":s[3]||=e=>P.model=e,name:`model`,required:``},null,512),[[p,P.model]])]),a(`label`,Et,[s[18]||=e(` API Key `,-1),q(a(`input`,{"onUpdate:modelValue":s[4]||=e=>P.apiKey=e,name:`apiKey`,type:`password`,autocomplete:`new-password`,placeholder:P.hasApiKey?t(i)(`已保存,留空则保留`):t(i)(`填写供应商提供的密钥`)},null,8,Dt),[[p,P.apiKey]])])])]),a(`fieldset`,null,[a(`legend`,null,r(t(i)(`容量与思考`)),1),a(`p`,Ot,r(t(i)(`官方按输入长度分档计价的模型可以在标准和百万之间切换;输出上限默认是官方最大值,思考强度只列出这个模型支持的档位。`)),1),a(`div`,kt,[X.value.length?(V(),_(`label`,At,[e(r(t(i)(`上下文容量`))+` `,1),C(Y,{name:`contextWindow`,"model-value":P.contextWindow,options:X.value.map(e=>({value:e.contextWindow,label:e.label})),onChange:de},null,8,[`model-value`,`options`])])):(V(),_(`label`,jt,[e(r(t(i)(`上下文容量`)),1),q(a(`input`,{"onUpdate:modelValue":s[5]||=e=>P.contextWindow=e,name:`contextWindow`,type:`number`},null,512),[[p,P.contextWindow,void 0,{number:!0}]])])),a(`label`,null,[e(r(t(i)(`最大输入 Token`)),1),q(a(`input`,{"onUpdate:modelValue":s[6]||=e=>P.maxInputTokens=e,name:`maxInputTokens`,type:`number`},null,512),[[p,P.maxInputTokens,void 0,{number:!0}]])]),a(`label`,null,[e(r(t(i)(`最大输出 Token`)),1),q(a(`input`,{"onUpdate:modelValue":s[7]||=e=>P.maxOutputTokens=e,name:`maxOutputTokens`,type:`number`},null,512),[[p,P.maxOutputTokens,void 0,{number:!0}]])]),a(`label`,null,[e(r(t(i)(`思考强度`))+` `,1),C(Y,{modelValue:P.reasoningEffort,"onUpdate:modelValue":s[8]||=e=>P.reasoningEffort=e,name:`reasoningEffort`,"aria-label":t(i)(`思考强度`),options:ae.value.map(e=>({value:e,label:me(e)}))},null,8,[`modelValue`,`aria-label`,`options`])])])]),a(`details`,Mt,[a(`summary`,null,r(t(i)(`高级参数与模型能力`)),1),a(`div`,Nt,[a(`label`,null,[e(r(t(i)(`随机程度 Temperature`)),1),q(a(`input`,{"onUpdate:modelValue":s[9]||=e=>P.temperature=e,name:`temperature`,type:`number`,step:`0.05`},null,512),[[p,P.temperature,void 0,{number:!0}]])]),a(`label`,null,[e(r(t(i)(`采样范围 Top P`)),1),q(a(`input`,{"onUpdate:modelValue":s[10]||=e=>P.topP=e,name:`topP`,type:`number`,step:`0.05`},null,512),[[p,P.topP,void 0,{number:!0}]])]),a(`label`,null,[e(r(t(i)(`超时(毫秒)`)),1),q(a(`input`,{"onUpdate:modelValue":s[11]||=e=>P.timeoutMs=e,name:`timeoutMs`,type:`number`},null,512),[[p,P.timeoutMs,void 0,{number:!0}]])]),a(`label`,null,[e(r(t(i)(`知识检索模型`)),1),q(a(`input`,{"onUpdate:modelValue":s[12]||=e=>P.embeddingModel=e,name:`embeddingModel`,placeholder:t(i)(`留空跟随对话模型`)},null,8,Pt),[[p,P.embeddingModel]])])]),a(`p`,Ft,r(t(i)(`打开图片理解后,聊天里的图片会先在本机读取,再连同画面交给这个模型。主模型不能看图时,到会话设置另选一个打开了图片理解的视觉兼容模型。`)),1),a(`div`,It,[(V(!0),_(m,null,S({vision:t(i)(`图片理解`),system:`System Prompt`,json:t(i)(`JSON 输出`),tools:t(i)(`工具调用`),embedding:t(i)(`知识向量`)},(t,n)=>(V(),_(`label`,{key:n,class:`check`},[q(a(`input`,{"onUpdate:modelValue":e=>P[n]=e,name:n,type:`checkbox`},null,8,Lt),[[J,P[n]]]),e(r(t),1)]))),128))])]),k.value?(V(),_(`div`,Rt,r(k.value),1)):h(``,!0),a(`div`,zt,[a(`button`,{class:`primary`,disabled:w.value},r(w.value?t(i)(`正在保存…`):t(i)(`保存模型`)),9,Bt),a(`small`,Vt,r(t(B).dirty?t(i)(`有未保存的修改`):t(i)(`已保存的模型才会用来测试和回复`)),1),P.isDefault?h(``,!0):(V(),_(`label`,Ht,[a(`input`,{type:`checkbox`,checked:P.enabled!==!1,onChange:s[13]||=e=>{P.enabled=e.target.checked,t(B).dirty=!0}},null,40,Ut),e(r(t(i)(`启用这个备用模型`)),1)])),P.isDefault?h(``,!0):(V(),_(`button`,{key:1,id:`setDefaultModel`,type:`button`,onClick:xe},r(t(i)(`设为默认模型`)),1)),oe.value?(V(),_(`button`,{key:2,id:`testModel`,type:`button`,disabled:w.value||T.value||t(B).dirty,onClick:we},r(T.value?t(i)(`正在测试…`):t(B).dirty?t(i)(`保存后测试此模型`):t(i)(`测试此模型连接`)),9,Wt)):h(``,!0),a(`button`,{id:`deleteModel`,type:`button`,class:`danger push`,onClick:Ce},r(t(i)(`删除模型`)),1)])],32)])):(V(),_(`section`,Gt,[C(ee,{title:t(i)(`还没有模型`),text:t(i)(`常见厂商会预填模型参数;OpenRouter 可选 GPT-6 预设,也可用自选模型手动填写模型 ID 和参数。`)},{default:U(()=>[a(`button`,{class:`primary`,onClick:ve},r(t(i)(`+ 新增模型`)),1)]),_:1},8,[`title`,`text`])]))]),C(st),a(`section`,Kt,[a(`div`,qt,[a(`div`,null,[a(`span`,Jt,r(t(i)(`TOKEN LEDGER · 累计用量`)),1),a(`h2`,Yt,r(t(i)(`一路聊到现在`)),1),a(`p`,null,r(t(i)(`统计本机账本记录的模型调用;缓存 Token 已包含在输入量里。`)),1)]),a(`div`,Xt,[a(`strong`,null,r($(A.value?.total)),1),a(`span`,null,r(t(i)(`累计 Token`)),1)])]),a(`div`,Zt,[a(`div`,Qt,[a(`span`,null,r(t(i)(`输入`)),1),a(`b`,null,r($(A.value?.input)),1)]),a(`div`,$t,[a(`span`,null,r(t(i)(`输出`)),1),a(`b`,null,r($(A.value?.output)),1)]),a(`div`,en,[a(`span`,null,[e(r(t(i)(`缓存命中`))+` `,1),a(`small`,null,r(t(i)(`(输入子项)`)),1)]),a(`b`,null,r($(A.value?.cached)),1)]),a(`div`,tn,[a(`span`,null,r(t(i)(`调用次数`)),1),a(`b`,null,r($(A.value?.calls)),1)])]),a(`div`,nn,[A.value?.since?(V(),_(`small`,rn,[e(r(t(i)(`从 {v} 开始记录 · {v2} 为模型返回用量`,{v:new Date(A.value.since).toLocaleDateString(t(o)()),v2:$(A.value.reportedTokens)}))+` `,1),A.value.estimatedCalls?(V(),_(m,{key:0},[e(r(t(i)(`· {v} 次调用按文本估算`,{v:$(A.value.estimatedCalls)})),1)],64)):h(``,!0)])):N.value?(V(),_(`small`,an,r(N.value),1)):(V(),_(`small`,on,r(t(i)(`还没有模型调用记录。`)),1)),a(`button`,{type:`button`,class:`usage-refresh`,disabled:j.value,onClick:he},r(j.value?t(i)(`更新中…`):t(i)(`刷新统计 ↻`)),9,sn)])]),C(ie,{open:D.value,title:t(i)(`选择模型`),eyebrow:`MODELS`,width:`880px`,onClose:s[17]||=e=>D.value=!1},{default:U(()=>[a(`div`,cn,[a(`p`,ln,r(t(i)(`先选供应商,再挑具体模型;支持搜索。火山方舟 Coding Plan 已预填套餐专用接口与型号参数,请勿换成普通推理 API 地址。`)),1),a(`label`,un,[a(`span`,null,r(t(i)(`搜索模型或供应商`)),1),q(a(`input`,{"onUpdate:modelValue":s[15]||=e=>O.value=e,type:`search`,placeholder:t(i)(`例如:火山方舟、Kimi K3、DeepSeek`)},null,8,dn),[[p,O.value]])]),(V(!0),_(m,null,S(L.value,e=>(V(),_(`details`,{key:e.vendor,class:`vendor`,"data-vendor":e.vendor},[a(`summary`,pn,[a(`span`,mn,[a(`b`,null,r(e.vendor),1),a(`small`,null,r(t(i)(`{length} 个预设`,{length:e.models.length})),1)]),s[19]||=a(`span`,{class:`vendor-chevron`,"aria-hidden":`true`},`⌄`,-1)]),a(`div`,hn,[(V(!0),_(m,null,S(e.models,e=>(V(),_(`button`,{key:e.id,type:`button`,class:`preset-card`,"data-preset":e.id,onClick:t=>ye(e)},[a(`b`,null,r(e.label),1),a(`small`,null,r(e.model||t(i)(`填写你在 OpenRouter 选择的模型 ID`)),1),a(`small`,null,r(pe(e)),1),a(`small`,null,r(e.summary),1)],8,gn))),128))])],8,fn))),128)),L.value.length?h(``,!0):(V(),_(`p`,_n,r(t(i)(`没有找到匹配的模型预设。`)),1)),W.value?(V(),_(`button`,{key:1,type:`button`,class:`preset-card custom`,"data-preset":`custom`,onClick:s[16]||=e=>ye(W.value)},[a(`b`,null,r(W.value.label),1),a(`small`,null,r(W.value.summary),1)])):h(``,!0)])]),_:1},8,[`open`,`title`])]))}}),[[`__scopeId`,`data-v-59f18516`]]),yn={class:`switch`},bn=[`name`,`disabled`],xn=P({__name:`Toggle`,props:z({name:{},disabled:{type:Boolean}},{modelValue:{type:Boolean,default:!1},modelModifiers:{}}),emits:[`update:modelValue`],setup(e){let t=O(e,`modelValue`);return(n,r)=>(V(),_(`label`,yn,[q(a(`input`,{"onUpdate:modelValue":r[0]||=e=>t.value=e,type:`checkbox`,name:e.name,disabled:e.disabled},null,8,bn),[[J,t.value]]),a(`span`,null,[T(n.$slots,`default`)])]))}}),Sn={class:`runtime-grid`},Cn={class:`card-head`},wn={class:`eyebrow`},Tn={class:`switches`},En={class:`save-bar`},Dn={class:`primary`,type:`submit`},On={class:`faint`},kn={class:`card numbers`},An=[`title`],jn=N(P({__name:`Runtime`,setup(e){let n=K(!!B.health.settings.enabled),o=K(!!B.health.settings.demo),s=R(()=>(B.core.sessions||[]).filter(e=>e.enabled&&!e.archived).length),c=R(()=>{let e=B.health.backup;if(!e)return null;if(!e.enabled)return{value:i(`已关闭`),caption:i(`自动备份`),tone:`warn`,title:``};if(e.lastError)return{value:i(`失败`),caption:i(`自动备份出错,稍后重试`),tone:`danger`,title:e.lastError.message};if(!e.latest)return{value:i(`还没有`),caption:i(`自动备份,运行一阵后会做第一份`),tone:``,title:``};let t=Math.max(1,Math.round(e.latest.bytes/1048576));return{value:re(e.latest.at),caption:i(`上次自动备份 · {mb} MB · 已留 {count}/{keep} 份`,{mb:t,count:e.count,keep:e.keep}),tone:``,title:e.latest.name}});async function l(){try{await L({enabled:n.value,demo:o.value}),B.dirty=!1,B.health=await w(),H(i(`已保存并应用`))}catch(e){H(e.message,!0)}}return(e,u)=>(V(),_(`div`,Sn,[a(`form`,{id:`runtime`,class:`card`,onSubmit:f(l,[`prevent`]),onChange:u[2]||=e=>t(B).dirty=!0},[a(`div`,Cn,[a(`div`,null,[a(`span`,wn,r(t(i)(`运行开关`)),1),a(`h2`,null,r(t(i)(`TA 现在可以说话吗`)),1)])]),a(`div`,Tn,[C(xn,{modelValue:n.value,"onUpdate:modelValue":u[0]||=e=>n.value=e,name:`enabled`},{default:U(()=>[a(`b`,null,r(t(i)(`允许参与聊天`)),1),a(`small`,null,r(t(i)(`总开关。关掉后 TA 不看也不回任何会话,心智照常保存。`)),1)]),_:1},8,[`modelValue`]),C(xn,{modelValue:o.value,"onUpdate:modelValue":u[1]||=e=>o.value=e,name:`demo`},{default:U(()=>[a(`b`,null,r(t(i)(`仅模拟运行,不向 QQ 发送`)),1),a(`small`,null,r(t(i)(`模拟模式下,「对话」里可以发模拟消息走完整流程;它们写进模拟会话,不进入真实记忆。`)),1)]),_:1},8,[`modelValue`])]),a(`div`,En,[a(`button`,Dn,r(t(i)(`保存运行状态`)),1),a(`small`,On,r(t(B).dirty?t(i)(`有未保存的修改`):t(i)(`已保存,立刻生效`)),1)])],32),a(`section`,kn,[a(`button`,{onClick:u[3]||=e=>t(k)(`chats`)},[a(`b`,null,r(s.value),1),a(`span`,null,r(t(i)(`参与中的会话`)),1)]),a(`button`,{onClick:u[4]||=e=>t(k)(`system`,`models`)},[a(`b`,null,r(t(B).core.models.length),1),a(`span`,null,r(t(i)(`可用模型`)),1)]),a(`button`,{onClick:u[5]||=e=>t(k)(`system`,`connect`)},[a(`b`,null,r(t(B).health.connection?.online?t(i)(`在线`):t(i)(`离线`)),1),a(`span`,null,r(t(i)(`QQ 连接`)),1)]),c.value?(V(),_(`button`,{key:0,class:G([`stat`,c.value.tone]),title:c.value.title,"data-testid":`backup-status`,type:`button`,onClick:u[6]||=e=>t(k)(`system`,`storage`)},[a(`b`,null,r(c.value.value),1),a(`span`,null,r(c.value.caption),1)],10,An)):h(``,!0)])]))}}),[[`__scopeId`,`data-v-1f197523`]]),Mn={class:`card search-profile`},Nn={class:`eyebrow`},Pn={class:`muted`},Fn={key:0,class:`faint`},In={class:`check`},Ln=[`disabled`],Rn={class:`search-fields`},zn=[`disabled`],Bn=[`disabled`,`placeholder`],Vn=[`disabled`],Hn=[`disabled`],Un=[`disabled`],Wn={class:`faint`},Gn={class:`search-usage`,role:`status`},Kn={class:`chip`},qn={class:`faint`},Jn={class:`faint`},Yn={class:`row`},Xn=[`disabled`],Zn=[`disabled`],Qn={key:0,class:`faint`},$n=[`role`],er=N(P({__name:`SearchProfile`,setup(n){let o=[`provider`,`enabled`,`baseUrl`,`timeoutMs`,`maxResults`,`dailyLimit`],s=b({provider:`tavily`,enabled:!0,baseUrl:``,apiKey:``,timeoutMs:2e4,maxResults:5,dailyLimit:12}),c=K(null),l=K(!1),u=K(!1),d=K(``),m=K(!1),g=new Map,v=`tavily`,y=R(()=>u.value&&(!!s.apiKey.trim()||o.some(e=>s[e]!==c.value?.[e]))),S=e=>e===`brave`?`Brave`:`Tavily`,w=R(()=>c.value?.dailyLimit===0?i(`不限`):c.value?.dailyLimit??12);E(y,e=>{B.dirty=e}),E(()=>[B.tick,B.pulse],()=>{u.value&&!l.value&&B.page===`system`&&B.sub===`search`&&T().catch(()=>{})});async function T(){c.value=await M(`/mind/time/search`)}async function D(){try{await T(),Object.assign(s,c.value,{apiKey:``}),v=s.provider,u.value=!0}catch(e){H(e.message,!0)}}async function O(){if(l.value)return;l.value=!0;let e=s.provider;g.set(v,{...s,provider:v});try{Object.assign(s,g.get(e)||{...await M(`/mind/time/search?provider=`+e),apiKey:``}),v=e,d.value=``}catch(e){s.provider=v,H(e.message,!0)}finally{l.value=!1}}function k(){return Object.fromEntries([...o,`apiKey`].map(e=>[e,s[e]]))}async function A(){if(!l.value){l.value=!0;try{let e=await M(`/mind/time/search`,`PATCH`,k());c.value=e,Object.assign(s,e,{apiKey:``}),g.set(s.provider,{...s}),v=s.provider,H(i(`搜索配置已保存并生效`))}catch(e){H(e.message,!0)}finally{l.value=!1}}}async function N(){if(!l.value){l.value=!0,d.value=``,m.value=!1;try{let e=await M(`/mind/time/search/test`,`POST`,k()),t={source:e.profile.mode===`web`?i(`{provider} 联网检索`,{provider:S(e.profile.provider)}):e.profile.materialLabel,count:e.results.length};d.value=y.value?i(`{source}测试通过,返回 {count} 条资料。测试不占用每日查询额度;当前填写的配置尚未保存。`,t):i(`{source}测试通过,返回 {count} 条资料。测试不占用每日查询额度。`,t)}catch(e){m.value=!0,d.value=i(`{error}。本次测试不占用每日查询额度。`,{error:e.message})}finally{try{await T()}catch{}l.value=!1}}}return x(D),j(()=>{B.dirty=!1}),(n,o)=>(V(),_(`section`,Mn,[a(`span`,Nn,r(t(i)(`SEARCH · 独立搜索`)),1),a(`h2`,null,r(t(i)(`接触世界的资料`)),1),a(`p`,Pn,r(t(i)(`配置后优先联网检索。未配置密钥或关闭独立搜索时,使用当前模型整理已有知识。`)),1),u.value?(V(),_(`p`,Fn,r(t(i)(`当前生效:{v}。表单修改保存后生效。`,{v:c.value.mode===`web`?t(i)(`{provider} · 联网检索资料`,{provider:S(c.value.provider)}):c.value.materialLabel})),1)):h(``,!0),u.value?(V(),_(`form`,{key:1,onSubmit:f(A,[`prevent`])},[a(`label`,In,[q(a(`input`,{"onUpdate:modelValue":o[0]||=e=>s.enabled=e,type:`checkbox`,disabled:l.value},null,8,Ln),[[J,s.enabled]]),e(r(t(i)(`启用独立搜索`)),1)]),a(`div`,Rn,[a(`label`,null,[e(r(t(i)(`提供方`)),1),C(Y,{modelValue:s.provider,"onUpdate:modelValue":o[1]||=e=>s.provider=e,"aria-label":t(i)(`搜索提供方`),disabled:l.value,options:[{value:`tavily`,label:`Tavily`},{value:`brave`,label:`Brave`}],onChange:O},null,8,[`modelValue`,`aria-label`,`disabled`])]),a(`label`,null,[e(r(t(i)(`搜索地址`)),1),q(a(`input`,{"onUpdate:modelValue":o[2]||=e=>s.baseUrl=e,type:`url`,required:``,name:`searchUrl`,disabled:l.value},null,8,zn),[[p,s.baseUrl]])]),a(`label`,null,[e(r(t(i)(`独立密钥`)),1),q(a(`input`,{"onUpdate:modelValue":o[3]||=e=>s.apiKey=e,type:`password`,autocomplete:`new-password`,name:`searchKey`,disabled:l.value,placeholder:s.hasApiKey?t(i)(`已保存,留空保留`):t(i)(`填写该提供方的搜索密钥`)},null,8,Bn),[[p,s.apiKey]])]),a(`label`,null,[e(r(t(i)(`超时(毫秒)`)),1),q(a(`input`,{"onUpdate:modelValue":o[4]||=e=>s.timeoutMs=e,type:`number`,min:`1000`,max:`120000`,disabled:l.value},null,8,Vn),[[p,s.timeoutMs,void 0,{number:!0}]])]),a(`label`,null,[e(r(t(i)(`每次结果数`)),1),q(a(`input`,{"onUpdate:modelValue":o[5]||=e=>s.maxResults=e,type:`number`,min:`1`,max:`20`,disabled:l.value},null,8,Hn),[[p,s.maxResults,void 0,{number:!0}]])]),a(`label`,null,[e(r(t(i)(`每日查询上限`)),1),q(a(`input`,{"onUpdate:modelValue":o[6]||=e=>s.dailyLimit=e,name:`searchDailyLimit`,type:`number`,min:`0`,max:`100000`,disabled:l.value},null,8,Un),[[p,s.dailyLimit,void 0,{number:!0}]]),a(`small`,Wn,r(t(i)(`可手动调整;0 表示不限。保存后立即生效。`)),1)])]),a(`div`,Gn,[a(`span`,Kn,r(t(i)(`今日有效查询 {v} / {limitLabel}`,{v:c.value.used||0,limitLabel:w.value})),1),a(`small`,qn,r(t(i)(`{v} 次进行中 · {v2} 次失败 · {v3} 次测试`,{v:c.value.usage?.running||0,v2:c.value.usage?.failed||0,v3:c.value.usage?.diagnostics||0})),1)]),a(`p`,Jn,r(t(i)(`测试当前填写的配置,不会自动保存。失败与连接测试不占本地每日额度;提供方的账户额度由提供方管理。`)),1),a(`div`,Yn,[a(`button`,{class:`primary`,disabled:l.value},r(t(i)(`保存搜索`)),9,Xn),a(`button`,{type:`button`,disabled:l.value,onClick:N},r(l.value?t(i)(`处理中…`):t(i)(`测试连接`)),9,Zn),y.value?(V(),_(`span`,Qn,r(t(i)(`有尚未保存的修改`)),1)):h(``,!0)]),d.value?(V(),_(`p`,{key:0,role:m.value?`alert`:`status`,class:G([`search-result`,{failed:m.value}])},r(d.value),11,$n)):h(``,!0)],32)):h(``,!0)]))}}),[[`__scopeId`,`data-v-e874d8b6`]]),tr={key:0,class:`card data-transfer`,"aria-labelledby":`data-transfer-title`},nr={class:`eyebrow`},rr={id:`data-transfer-title`},ir={class:`transfer-note`},ar={class:`transfer-note`},or={class:`transfer-actions`},sr=[`disabled`],cr=[`disabled`],lr=[`aria-label`],ur={class:`transfer-note`},dr={key:0,class:`transfer-progress`,role:`status`},fr={key:1,class:`transfer-error`,role:`alert`},pr={key:2,class:`transfer-note`},mr={key:3,class:`transfer-preview`},hr={class:`eyebrow`},gr={class:`transfer-note`},_r={class:`transfer-counts`},vr={class:`transfer-actions`},yr=[`disabled`],br=[`disabled`],xr=N(P({__name:`DataTransfer`,setup(e){let o=K(null),c=K(null),d=K(),f=K(``),p=K(``),g=!0,v=null,y=R(()=>!!f.value),b=R(()=>f.value===`restarting`?i(`正在保留快照并重启加载,请等待…`):f.value===`uploading`?i(`正在上传数据文件…`):f.value===`exporting`?i(`正在生成完整数据包…`):i(`正在校验数据文件…`)),C=R(()=>{let e=c.value?.summary?.tables||{};return[[i(`聊天记录`),e.core_events||e.messages||0],[i(`记忆`),e.core_memories||e.memories||0],[i(`待办`),e.mind_time_tasks||0],[i(`作品`),e.mind_time_works||0],[i(`日记`),e.mind_diary||0]]}),w=()=>new Promise(e=>setTimeout(e,800));async function T(e,t=!1){for(let n=0;n<4500&&g;n++){try{let n=await M(`/storage/transfer/jobs/`+e);if(n.status===`error`)throw Error(n.error||i(`数据处理失败`));if(n.status===(t?`done`:`ready`))return n;if(n.status===`expired`)throw Error(i(`数据文件已过期,请重新选择`))}catch(e){if(!t||!(e instanceof TypeError)&&e.message!==i(`请求失败`))throw e}await w()}throw Error(i(`等待数据处理超时,请检查实例运行状态`))}async function E(){if(!y.value){f.value=`exporting`,p.value=``;try{let e=await M(`/storage/transfer/export`,`POST`,{});if(await T(e.id),!g)return;let t=document.createElement(`a`);t.href=`/api/storage/transfer/download/`+e.id,t.download=``,document.body.appendChild(t),t.click(),t.remove(),H(i(`数据包已生成,浏览器将开始下载`))}catch(e){g&&(p.value=e.message)}finally{g&&(f.value=``)}}}async function O(e){let t=e.target,n=t.files?.[0];if(t.value=``,n&&!y.value){if(p.value=``,c.value=null,n.size>(o.value?.maxBytes||0)){p.value=i(`数据文件超过导入大小限制`);return}f.value=`uploading`,v=new AbortController;try{await u();let e=await fetch(`/api/storage/transfer/upload`,{method:`POST`,credentials:`same-origin`,headers:{"Content-Type":`application/octet-stream`,"X-LuckyTri-Filename":encodeURIComponent(n.name),"X-LuckyTri-Locale":s.value},body:n,signal:v.signal});if(e.status===401)throw l(),Error(i(`请先登录管理台`));let t=await e.json().catch(()=>({}));if(!e.ok)throw Error(t.error||i(`数据上传失败`));f.value=`checking`;let r=await T(t.id);g&&(c.value=r)}catch(e){g&&(p.value=e.message)}finally{v=null,g&&(f.value=``)}}}async function k(){if(c.value&&!y.value)try{await M(`/storage/transfer/jobs/`+c.value.id,`DELETE`),c.value=null}catch(e){p.value=e.message}}async function A(){if(!c.value||y.value||!await n(i(`用这份数据替换当前数据,并保留导入前快照。实例将重启,导入后自动回复关闭。本机管理密码与 QQ 连接配置保持不变。`),{title:i(`确认导入数据`),confirmText:i(`导入并重启`),danger:!0}))return;f.value=`restarting`,p.value=``;let e=c.value.id;try{if(await M(`/storage/transfer/import`,`POST`,{id:e}),await T(e,!0),!g)return;D(),location.reload()}catch(e){g&&(p.value=e.message)}finally{g&&(f.value=``)}}return x(async()=>{try{o.value=await M(`/storage/transfer`)}catch(e){g&&(p.value=e.message)}}),I(()=>{g=!1,v?.abort()}),(e,n)=>o.value?.available?(V(),_(`section`,tr,[a(`span`,nr,r(t(i)(`DATA · 导入与导出`)),1),a(`h2`,rr,r(t(i)(`带上记忆,继续生活。`)),1),a(`p`,ir,r(t(i)(`导出数据库内的聊天、记忆、待办、作品、知识与设置。插件文件、知识库原始文件和本机 .env 不在数据包中。`)),1),a(`p`,ar,r(t(i)(`数据包包含私聊内容和模型设置中的密钥,请存放在你信任的位置。导入前会校验,确认后才替换当前数据。`)),1),a(`div`,or,[a(`button`,{class:`primary`,type:`button`,disabled:y.value,onClick:E},r(t(i)(`导出数据包`)),9,sr),a(`button`,{type:`button`,disabled:y.value,onClick:n[0]||=e=>d.value?.click()},r(t(i)(`选择导入文件`)),9,cr),a(`input`,{ref_key:`input`,ref:d,class:`transfer-file`,type:`file`,accept:`.luckytri,.db,.sqlite,.sqlite3`,"aria-label":t(i)(`导入数据文件`),onChange:O},null,40,lr)]),a(`p`,ur,r(t(i)(`支持 .luckytri 数据包和已有 SQLite 备份,单个文件最多 {size} GiB。`,{size:(o.value.maxBytes/1073741824).toFixed(0)})),1),y.value?(V(),_(`p`,dr,r(b.value),1)):h(``,!0),p.value?(V(),_(`p`,fr,r(p.value),1)):h(``,!0),o.value.lastImport?.status===`done`?(V(),_(`p`,pr,r(t(i)(`上次数据导入已完成,自动回复在导入时关闭。请检查连接、模型和待办后再开启;插件需重新安装或确认权限。`)),1)):h(``,!0),c.value?(V(),_(`div`,mr,[a(`span`,hr,r(t(i)(`校验通过 · 尚未导入`)),1),a(`h3`,null,r(c.value.summary?.name),1),a(`p`,gr,r(c.value.name)+` · `+r(t(i)(`数据库版本 {from} → {to}`,{from:c.value.originalVersion,to:c.value.summary?.schemaVersion})),1),a(`div`,_r,[(V(!0),_(m,null,S(C.value,([e,t])=>(V(),_(`div`,{key:e},[a(`b`,null,r(t),1),a(`span`,null,r(e),1)]))),128))]),a(`div`,vr,[a(`button`,{class:`primary`,type:`button`,disabled:y.value,onClick:A},r(t(i)(`导入并重启`)),9,yr),a(`button`,{type:`button`,disabled:y.value,onClick:k},r(t(i)(`取消导入`)),9,br)])])):h(``,!0)])):h(``,!0)}}),[[`__scopeId`,`data-v-ea16c0c1`]]),Sr={class:`storage-page`},Cr={class:`card storage-overview`},wr={class:`eyebrow`},Tr={key:0,class:`storage-metrics`},Er={key:0,class:`storage-error`,role:`alert`},Dr={key:1,class:`storage-grid`},Or={class:`card-head`},kr={class:`eyebrow`},Ar={class:`storage-check`},jr={class:`storage-fields`},Mr=[`aria-label`],Nr=[`aria-label`],Pr=[`aria-label`],Fr={class:`storage-note`},Ir={key:0,class:`storage-note`},Lr={key:1,class:`storage-error`},Rr=[`disabled`],zr={class:`card storage-list`},Br={class:`card-head`},Vr={class:`eyebrow`},Hr={class:`storage-note`},Ur={class:`storage-actions`},Wr=[`disabled`],Gr=[`disabled`],Kr=[`disabled`],qr={class:`storage-scroll`},Jr=[`checked`,`disabled`,`aria-label`,`onChange`],Yr={class:`storage-item`},Xr={key:0,class:`storage-error`,role:`alert`},Zr={class:`storage-footer`},Qr=[`disabled`],$r=N(P({__name:`BackupManager`,setup(s){let c=K(null),l=K({enabled:!0,time:`04:30`,retainDays:14,keepFull:2}),u=K([]),d=K(!1),g=K(``),v=K([]),y=!0,b=e=>`${e.scope}:${e.name}`,w=R(()=>c.value?.entries.filter(e=>u.value.includes(b(e)))||[]),T=R(()=>w.value.reduce((e,t)=>e+t.bytes,0)),E=e=>e===0?`0 B`:e>=1073741824?`${(e/1073741824).toFixed(2)} GiB`:`${Math.max(.01,e/1048576).toFixed(2)} MiB`,D=e=>new Date(e).toLocaleString(o()),O=e=>({auto:i(`自动备份`),full:i(`完整备份`),migration:i(`迁移快照`),legacy:i(`旧版本备份`),snapshot:i(`升级前快照`),import:i(`导入前快照`)})[e];async function k(e=!1){try{g.value=``;let t=await M(`/storage/cleanup`);if(!y)return;if(c.value=t,e)l.value={...c.value.policy},u.value=[],B.dirty=!1;else{let e=new Set(c.value.entries.filter(e=>!e.protected).map(b));u.value=u.value.filter(t=>e.has(t))}}catch(e){y&&(g.value=e.message)}}function A(){B.dirty=!0}function j(e){let t=b(e);u.value=u.value.includes(t)?u.value.filter(e=>e!==t):[...u.value,t]}function N(){u.value=(c.value?.plan.items||[]).map(b)}function P(){u.value=(c.value?.entries||[]).filter(e=>e.kind===`full`&&!e.protected).map(b)}async function F(){if(!d.value){d.value=!0;try{let e=await M(`/storage/cleanup`,`PATCH`,{enabled:l.value.enabled,time:l.value.time,retainDays:Number(l.value.retainDays),keepFull:Number(l.value.keepFull)});c.value=e,l.value={...e.policy},B.dirty=!1,H(i(`备份整理规则已保存`))}catch(e){H(e.message,!0)}finally{d.value=!1}}}async function L(){if(!w.value.length||d.value)return;let e=w.value.map(({scope:e,name:t,bytes:n,modified:r})=>({scope:e,name:t,bytes:n,modified:r}));if(await n(i(`将清理选中的 {count} 份备份,释放约 {size}。这些历史恢复点清理后无法从本机找回。`,{count:e.length,size:E(T.value)}),{title:i(`清理所选备份`),confirmText:i(`清理所选`),danger:!0})){d.value=!0;try{let t=await M(`/storage/cleanup/manual`,`POST`,{items:e});v.value=t.failures||[];let n=new Set((t.failures||[]).map(e=>`${e.scope}:${e.name}`));u.value=u.value.filter(e=>n.has(e)),await k(),H(i(`已清理 {count} 份备份,释放 {size}`,{count:t.removed.length,size:E(t.bytes)})+(v.value.length?i(`;部分未清理,详情见列表`):``),v.value.length>0)}catch(e){H(e.message,!0),await k()}finally{d.value=!1}}}return x(()=>k(!0)),I(()=>{y=!1}),(n,o)=>(V(),_(`div`,Sr,[a(`section`,Cr,[a(`span`,wr,r(t(i)(`DATA · 数据与备份`)),1),a(`h2`,null,r(t(i)(`留住重要的,整理重复的。`)),1),a(`p`,null,r(t(i)(`这里管理历史备份。聊天、记忆和作品仍在正在运行的数据库里,不会被列入清理。`)),1),c.value?(V(),_(`div`,Tr,[a(`div`,null,[a(`b`,null,r(E(c.value.totalBytes)),1),a(`span`,null,r(t(i)(`可管理的历史备份`)),1)]),a(`div`,null,[a(`b`,null,r(c.value.entries.length),1),a(`span`,null,r(t(i)(`份数据库副本`)),1)]),a(`div`,null,[a(`b`,null,r(E(c.value.plan.bytes)),1),a(`span`,null,r(t(i)(`按当前规则可定时整理`)),1)])])):h(``,!0)]),g.value?(V(),_(`p`,Er,r(g.value),1)):h(``,!0),C(xr),c.value?(V(),_(`div`,Dr,[a(`form`,{class:`card storage-policy`,onSubmit:f(F,[`prevent`])},[a(`div`,Or,[a(`div`,null,[a(`span`,kr,r(t(i)(`定时整理`)),1),a(`h2`,null,r(t(i)(`每天给备份留一点空间`)),1)])]),a(`label`,Ar,[q(a(`input`,{"onUpdate:modelValue":o[0]||=e=>l.value.enabled=e,type:`checkbox`,onChange:A},null,544),[[J,l.value.enabled]]),e(r(t(i)(`启用定时整理`)),1)]),a(`div`,jr,[a(`label`,null,[e(r(t(i)(`每天执行时间`)),1),q(a(`input`,{"onUpdate:modelValue":o[1]||=e=>l.value.time=e,type:`text`,inputmode:`numeric`,maxlength:`5`,placeholder:`04:30`,"aria-label":t(i)(`每天执行时间`),onInput:A},null,40,Mr),[[p,l.value.time]])]),a(`label`,null,[e(r(t(i)(`完整备份保留天数`)),1),q(a(`input`,{"onUpdate:modelValue":o[2]||=e=>l.value.retainDays=e,type:`number`,min:`1`,max:`3650`,"aria-label":t(i)(`完整备份保留天数`),onInput:A},null,40,Nr),[[p,l.value.retainDays,void 0,{number:!0}]])]),a(`label`,null,[e(r(t(i)(`完整备份最多保留份数`)),1),q(a(`input`,{"onUpdate:modelValue":o[3]||=e=>l.value.keepFull=e,type:`number`,min:`0`,max:`100`,"aria-label":t(i)(`完整备份最多保留份数`),onInput:A},null,40,Pr),[[p,l.value.keepFull,void 0,{number:!0}]])])]),a(`p`,Fr,r(t(i)(`时间按服务器本地时区 {zone}。完整备份超过保留天数或数量上限便会定时整理;数量填 0 表示不保留完整备份。手动清理可选择完整备份和迁移快照,执行前会校验同一实例的近期自动恢复点。`,{zone:c.value.serverTimeZone})),1),c.value.last?(V(),_(`p`,Ir,r(c.value.last.error&&c.value.last.removed===0?t(i)(`上次整理未执行:{error}`,{error:c.value.last.error}):t(i)(`上次整理:{time} · {count} 份 · {size}`,{time:D(c.value.last.at),count:c.value.last.removed,size:E(c.value.last.bytes)})),1)):h(``,!0),c.value.last?.error&&c.value.last.removed>0?(V(),_(`p`,Lr,r(c.value.last.error),1)):h(``,!0),a(`button`,{class:`primary`,type:`submit`,disabled:d.value},r(d.value?t(i)(`处理中…`):t(i)(`保存整理规则`)),9,Rr)],32),a(`section`,zr,[a(`div`,Br,[a(`div`,null,[a(`span`,Vr,r(t(i)(`手动整理`)),1),a(`h2`,null,r(t(i)(`挑选历史恢复点`)),1)])]),a(`p`,Hr,r(t(i)(`自动备份已有自己的轮换规则。迁移、旧版本和升级前快照只由你手动挑选;清理前会再次核对文件和恢复点。`)),1),a(`div`,Ur,[a(`button`,{type:`button`,disabled:d.value||!c.value.plan.items.length,onClick:N},r(t(i)(`选中规则建议`)),9,Wr),a(`button`,{type:`button`,disabled:d.value,onClick:P},r(t(i)(`选中完整备份`)),9,Gr),a(`button`,{type:`button`,disabled:d.value||!u.value.length,onClick:o[4]||=e=>u.value=[]},r(t(i)(`取消选择`)),9,Kr)]),a(`div`,qr,[(V(!0),_(m,null,S(c.value.entries,e=>(V(),_(`label`,{key:b(e),class:G([`storage-row`,{protected:e.protected}])},[a(`input`,{type:`checkbox`,checked:u.value.includes(b(e)),disabled:d.value||e.protected||c.value.running,"aria-label":e.name,onChange:t=>j(e)},null,40,Jr),a(`span`,Yr,[a(`strong`,null,r(e.name),1),a(`small`,null,r(O(e.kind))+` · `+r(D(e.at))+` · `+r(e.manifest?t(i)(`有校验清单`):t(i)(`旧备份无清单`))+r(e.protected?` · `+(e.protectionReason||t(i)(`保留恢复点`)):``),1)]),a(`b`,null,r(E(e.bytes)),1)],2))),128))]),v.value.length?(V(),_(`div`,Xr,[a(`p`,null,r(t(i)(`部分备份未清理,请刷新列表后重试`)),1),(V(!0),_(m,null,S(v.value,e=>(V(),_(`p`,{key:e.name},r(e.name)+` · `+r(e.error),1))),128))])):h(``,!0),a(`div`,Zr,[a(`span`,null,r(t(i)(`已选 {count} 份 · 约 {size}`,{count:w.value.length,size:E(T.value)})),1),a(`button`,{class:`primary`,type:`button`,disabled:d.value||c.value.running||!w.value.length,onClick:L},r(t(i)(`清理所选`)),9,Qr)])])])):h(``,!0)]))}}),[[`__scopeId`,`data-v-4593780e`]]),ei={class:`card password-settings`},ti={class:`row`},ni=[`disabled`],ri=N(P({__name:`PasswordSettings`,setup(n){let o=K(``),s=K(``),c=K(``),l=K(!1);async function u(){if(!l.value){if(s.value!==c.value){H(i(`两次输入的密码不一致`),!0);return}l.value=!0;try{await y(`password`,{currentPassword:o.value,password:s.value}),o.value=s.value=c.value=``,H(i(`管理密码已更新`))}catch(e){H(e.message,!0)}finally{l.value=!1}}}return(n,d)=>(V(),_(`section`,ei,[a(`h2`,null,r(t(i)(`管理密码`)),1),a(`p`,null,r(t(i)(`一个密码管理这个小世界。修改后,其他浏览器需要重新登录。`)),1),a(`form`,{onSubmit:f(u,[`prevent`])},[a(`label`,null,[e(r(t(i)(`当前密码`)),1),q(a(`input`,{"onUpdate:modelValue":d[0]||=e=>o.value=e,name:`currentPassword`,type:`password`,autocomplete:`current-password`,required:``},null,512),[[p,o.value]])]),a(`label`,null,[e(r(t(i)(`新密码`)),1),q(a(`input`,{"onUpdate:modelValue":d[1]||=e=>s.value=e,name:`newPassword`,type:`password`,autocomplete:`new-password`,minlength:`8`,maxlength:`256`,required:``},null,512),[[p,s.value]])]),a(`label`,null,[e(r(t(i)(`确认密码`)),1),q(a(`input`,{"onUpdate:modelValue":d[2]||=e=>c.value=e,name:`confirmNewPassword`,type:`password`,autocomplete:`new-password`,minlength:`8`,maxlength:`256`,required:``},null,512),[[p,c.value]])]),a(`div`,ti,[a(`button`,{class:`primary`,disabled:l.value},r(t(i)(`修改密码`)),9,ni),a(`button`,{type:`button`,onClick:d[3]||=(...e)=>t(W)&&t(W)(...e)},r(t(i)(`退出登录`)),1)])],32)]))}}),[[`__scopeId`,`data-v-36cd9f70`]]),ii={class:`card update-settings`,"aria-labelledby":`update-title`},ai={id:`update-title`},oi=[`disabled`],si={class:`kv`},ci={key:0,class:`muted`,role:`alert`},li={class:`muted small-text`},ui={key:1,class:`update-how stack tight`},di=[`disabled`],fi={key:1,role:`status`},pi={key:2,class:`error-text`,role:`alert`},mi={key:3,class:`muted`},hi={class:`update-links`},gi=[`href`],_i=[`href`],vi=N(P({__name:`UpdateSettings`,setup(e){let o=K(null),s=K(!1),l=K(!1),u,d=!1,f=c({queued:A(`更新已开始`),downloading:A(`正在下载新版本…`),checking:A(`正在检查新程序…`),stopping:A(`正在保存当下并停止实例…`),backup:A(`正在保留更新前的校验备份…`),restarting:A(`正在切换版本并重启…`),verifying:A(`正在确认新实例就绪…`),restoring:A(`正在恢复原版本和数据…`),done:A(`更新与重启已完成`),error:A(`更新未完成`)});function p(e){return e&&![`done`,`error`].includes(e.status)}async function g(){if(!d){try{let e=await M(`/system/update`);if(o.value=e,e.operation?.status===`done`){l.value=!1,location.reload();return}l.value=!!p(e.operation)}catch{}l.value&&!d&&(u=setTimeout(g,1800))}}j(()=>{d=!0,clearTimeout(u)});let v=c({unchecked:A(`尚未检查更新`),available:A(`有新版本可用`),current:A(`已是最新发布版本`),ahead:A(`当前版本领先于 npm 发布版本`),unavailable:A(`暂时无法检查更新`)});x(async()=>{try{o.value=await M(`/system/update`),l.value=!!p(o.value.operation),l.value&&(u=setTimeout(g,1800))}catch(e){H(e.message,!0)}});async function y(){if(!s.value){s.value=!0;try{o.value=await M(`/system/update/check`,`POST`,{})}catch(e){H(e.message,!0)}finally{s.value=!1}}}async function b(){if(!(l.value||s.value||o.value?.status!==`available`)&&await n(i(`更新到 {version} 并重启当前实例?先下载校验,再保留数据恢复点;启动失败时尝试恢复原版本。`,{version:o.value.latest}),{title:i(`更新并重启`),confirmText:i(`开始更新`)})){l.value=!0;try{o.value.operation=await M(`/system/update/install`,`POST`,{version:o.value.latest}),u=setTimeout(g,800)}catch(e){l.value=!1,H(e.message,!0)}}}return(e,n)=>(V(),_(`section`,ii,[a(`header`,null,[a(`div`,null,[n[0]||=a(`span`,{class:`eyebrow`},`LUCKYTRI / VERSION`,-1),a(`h2`,ai,r(t(i)(`版本与更新`)),1)]),a(`button`,{disabled:s.value||l.value||!o.value,onClick:y},r(s.value?t(i)(`正在检查…`):t(i)(`检查更新`)),9,oi)]),o.value?(V(),_(m,{key:0},[a(`p`,{class:G([`version-state`,{available:o.value.status===`available`}]),role:`status`},r(t(v)[o.value.status]||t(v).unchecked),3),a(`dl`,si,[a(`dt`,null,r(t(i)(`当前版本`)),1),a(`dd`,null,r(o.value.current),1),a(`dt`,null,r(t(i)(`npm 最新版本`)),1),a(`dd`,null,r(o.value.latest||`—`),1),a(`dt`,null,r(t(i)(`上次成功检查`)),1),a(`dd`,null,r(o.value.checkedAt?t(te)(o.value.checkedAt):`—`),1)]),o.value.error?(V(),_(`p`,ci,r(t(i)(`暂时无法连接 npm 或读取版本信息,请稍后重试。`)),1)):h(``,!0),a(`p`,li,r(t(i)(`点击时才检查,五分钟内复用结果。检查更新不会自动安装或重启。`)),1),o.value.status===`available`||o.value.operation?(V(),_(`div`,ui,[a(`p`,null,r(t(i)(`下载期间继续运行,切换前保留数据恢复点。更新完成后此页面会自动重新连接。`)),1),o.value.status===`available`?(V(),_(`button`,{key:0,class:`primary`,disabled:l.value||s.value,onClick:b},r(l.value?t(i)(`正在更新…`):t(i)(`更新并重启`)),9,di)):h(``,!0),o.value.operation?(V(),_(`p`,fi,r(t(f)[o.value.operation.status])+` · `+r(o.value.operation.version),1)):h(``,!0),o.value.operation?.error?(V(),_(`p`,pi,r(o.value.operation.error),1)):h(``,!0),o.value.operation?.restored?(V(),_(`p`,mi,r(t(i)(`已恢复原版本和更新前的数据。`)),1)):h(``,!0)])):h(``,!0),a(`nav`,hi,[a(`a`,{href:o.value.npmUrl,target:`_blank`,rel:`noopener noreferrer`},`npm`,8,gi),a(`a`,{href:o.value.releaseUrl,target:`_blank`,rel:`noopener noreferrer`},r(t(i)(`发布说明`))+` ↗`,9,_i)])],64)):h(``,!0)]))}}),[[`__scopeId`,`data-v-0df58391`]]),yi={class:`page system`},bi={class:`system-intro`},xi={class:`eyebrow`},Si={class:`system-status`},Ci=N(P({__name:`SystemPage`,setup(o){let s=[`connect`,`models`,`search`,`runtime`,`storage`],c=K(s.includes(B.sub)?B.sub:`connect`);async function l(e){e!==c.value&&(!B.dirty||await n(i(`当前设置还没保存,离开这个分区吗?`),{title:i(`未保存的修改`),confirmText:i(`放弃修改`),cancelText:i(`继续编辑`)}))&&(B.dirty=!1,c.value=e)}return E(c,e=>F(e)),E(()=>B.sub,e=>{s.includes(e)&&(c.value=e)}),(n,o)=>(V(),_(`div`,yi,[a(`header`,bi,[a(`div`,null,[a(`span`,xi,r(t(i)(`THE WORLD AROUND HER · 系统`)),1),a(`h1`,null,[e(r(t(i)(`让她与世界,`)),1),a(`em`,null,r(t(i)(`温柔相连。`)),1)]),a(`p`,null,r(t(i)(`连接、模型与运行方式都在这里。每一处改变,都可以看见结果。`)),1)]),a(`span`,Si,[a(`i`,{class:G({off:!t(B).health.connection?.online})},null,2),e(` `+r(t(B).health.connection?.online?t(i)(`正在与 QQ 相连`):t(i)(`等待 QQ 连接`)),1)])]),C(X,{"model-value":c.value,"onUpdate:modelValue":l,label:t(i)(`系统的分区`),items:[{key:`connect`,label:t(i)(`连接 QQ`)},{key:`models`,label:t(i)(`模型库`)},{key:`search`,label:t(i)(`独立搜索`)},{key:`runtime`,label:t(i)(`运行开关`)},{key:`storage`,label:t(i)(`数据与备份`)}]},null,8,[`model-value`,`label`,`items`]),c.value===`connect`?(V(),g(Ue,{key:0,onOpen:l})):c.value===`models`?(V(),g(vn,{key:1})):c.value===`search`?(V(),g(er,{key:2})):c.value===`runtime`?(V(),_(m,{key:3},[C(jn),C(vi),C(ri)],64)):(V(),g($r,{key:4}))]))}}),[[`__scopeId`,`data-v-a12a372e`]]);export{Ci as default};
@@ -0,0 +1 @@
1
+ .day-agenda[data-v-10b48f6c]{gap:18px;min-width:0;display:grid}.agenda-heading[data-v-10b48f6c]{flex-wrap:wrap;justify-content:space-between;align-items:center;gap:14px;display:flex}h2[data-v-10b48f6c]{margin:6px 0 0;font-size:24px}h3[data-v-10b48f6c]{font-size:16px}p[data-v-10b48f6c]{overflow-wrap:anywhere;line-height:1.7}.agenda-range[data-v-10b48f6c]{gap:6px;display:flex}.agenda-range button[data-v-10b48f6c]{padding:8px 12px;font-size:12px}.agenda-range button[aria-pressed=true][data-v-10b48f6c]{background:var(--accent);color:#fff}.agenda-legend[data-v-10b48f6c]{color:var(--muted);flex-wrap:wrap;gap:16px;font-size:12px;display:flex}.agenda-legend span[data-v-10b48f6c]:before{content:"";border-radius:3px;width:16px;height:8px;margin-right:6px;display:inline-block}.legend-actual[data-v-10b48f6c]:before{background:var(--accent)}.legend-plan[data-v-10b48f6c]:before{border:1px dashed var(--accent);background:var(--glow-b)}.legend-free[data-v-10b48f6c]:before{background:#7d789526}.legend-point[data-v-10b48f6c]{color:var(--accent)}.legend-point[data-v-10b48f6c]:before{display:none!important}.agenda-chart[data-v-10b48f6c]{min-width:0;padding:18px 0 0}.agenda-axis[data-v-10b48f6c]{height:28px;color:var(--muted);margin-left:60px;margin-right:12px;font-size:11px;position:relative}.agenda-axis time[data-v-10b48f6c]{white-space:nowrap;position:absolute;transform:translate(-50%)}.agenda-axis time[data-v-10b48f6c]:first-child{transform:none}.agenda-axis time[data-v-10b48f6c]:last-child{transform:translate(-100%)}.agenda-lane[data-v-10b48f6c]{grid-template-columns:60px minmax(0,1fr);align-items:center;gap:0;margin-bottom:14px;margin-right:12px;display:grid}.lane-label[data-v-10b48f6c]{color:var(--muted);font-size:11px}.lane-track[data-v-10b48f6c]{background:#8580950f;border-radius:8px;height:40px;position:relative}.gridline[data-v-10b48f6c]{pointer-events:none;border-left:1px solid #7d789526;position:absolute;top:0;bottom:0}.agenda-block[data-v-10b48f6c]{min-width:1px;height:26px;box-shadow:none;border-radius:5px;padding:0;position:absolute;top:7px}.actual[data-v-10b48f6c]{background:linear-gradient(100deg, var(--accent), var(--orb-b));border:none}.ongoing[data-v-10b48f6c]{outline:2px solid var(--accent);outline-offset:2px}.plan[data-v-10b48f6c]{border:1px dashed var(--accent);background:var(--glow-b)}.rest[data-v-10b48f6c],.free[data-v-10b48f6c]{background:#7d78951f}.free[data-v-10b48f6c]{background:repeating-linear-gradient(135deg,#0000,#0000 5px,#7d789514 5px 8px)}.sleep[data-v-10b48f6c]{background:#7274a140}.agenda-now[data-v-10b48f6c]{background:var(--accent);pointer-events:none;width:1px;position:absolute;top:-4px;bottom:-4px}.agenda-now small[data-v-10b48f6c]{color:var(--accent);white-space:nowrap;font-size:10px;position:absolute;top:-18px;transform:translate(-50%)}.agenda-interaction[data-v-10b48f6c]{background:var(--accent);border-radius:50%;width:5px;height:5px;position:absolute;bottom:0;transform:translate(-50%)}.agenda-itinerary[data-v-10b48f6c]{gap:0;margin:0;padding:0;list-style:none;display:grid}.agenda-itinerary li[data-v-10b48f6c]{border-bottom:1px solid #7d78951f;grid-template-columns:72px minmax(0,1fr);gap:18px;padding:14px 0;display:grid}.agenda-itinerary time[data-v-10b48f6c]{color:var(--muted);font-variant-numeric:tabular-nums;font-size:12px;line-height:1.9}.agenda-itinerary li>div[data-v-10b48f6c]{align-content:start;gap:5px;min-width:0;display:grid}.agenda-itinerary button[data-v-10b48f6c]{text-align:left;overflow-wrap:anywhere;white-space:normal;justify-self:start;line-height:1.6}.agenda-itinerary small[data-v-10b48f6c]{color:var(--muted);font-size:12px;line-height:1.8}.agenda-itinerary b[data-v-10b48f6c]{font-size:14px}.agenda-itinerary p[data-v-10b48f6c]{font-size:13px}.agenda-itinerary [data-kind=free][data-v-10b48f6c],.agenda-itinerary [data-kind=rest][data-v-10b48f6c]{color:var(--muted)}summary[data-v-10b48f6c]{color:var(--muted);cursor:pointer;font-size:13px}.agenda-history ol[data-v-10b48f6c],.agenda-waiting ul[data-v-10b48f6c]{margin-top:15px}.agenda-waiting ul[data-v-10b48f6c]{gap:16px;padding:0;list-style:none;display:grid}@media (width<=440px){.agenda-axis time[data-v-10b48f6c]:nth-child(2n){display:none}.agenda-axis[data-v-10b48f6c]{margin-left:46px}.agenda-lane[data-v-10b48f6c]{grid-template-columns:46px minmax(0,1fr)}.agenda-axis time[data-v-10b48f6c]{font-size:9px}.agenda-itinerary li[data-v-10b48f6c]{grid-template-columns:54px minmax(0,1fr);gap:12px}.agenda-heading h2[data-v-10b48f6c]{font-size:21px}.agenda-legend[data-v-10b48f6c]{gap:10px}}.experience-log[data-v-400cba84]{gap:28px;min-width:0;display:grid}.experience-intro[data-v-400cba84]{justify-content:space-between;align-items:end;gap:20px;padding:4px 4px 0;display:flex}.experience-intro h1[data-v-400cba84]{letter-spacing:-.03em;margin-top:8px;font-size:clamp(25px,2.4vw,32px)}.experience-intro p[data-v-400cba84]{max-width:330px;color:var(--muted);font-size:14px;line-height:1.7}.experience-day[data-v-400cba84]{gap:14px;min-width:0;display:grid}.experience-date[data-v-400cba84]{color:var(--muted);padding-left:4px;font-size:13px;font-weight:600}.experience-timeline[data-v-400cba84]{gap:18px;min-width:0;display:grid}.experience-entry[data-v-400cba84]{grid-template-columns:58px minmax(0,1fr);gap:18px;display:grid;position:relative}.experience-entry[data-v-400cba84]:before{content:"";background:var(--line);width:1px;position:absolute;top:48px;bottom:-18px;left:29px}.experience-entry[data-v-400cba84]:last-child:before{bottom:0}.experience-clock[data-v-400cba84]{font-variant-numeric:tabular-nums;text-align:center;color:var(--muted);padding-top:25px;font-size:13px}.experience-card.card[data-v-400cba84]{border-radius:24px;gap:12px;min-width:0;padding:24px 28px;display:grid}.experience-meta[data-v-400cba84]{flex-wrap:wrap;align-items:center;gap:8px 14px;font-size:12px;display:flex}.experience-kind[data-v-400cba84]{color:var(--accent);font-weight:600}.experience-card h3[data-v-400cba84]{overflow-wrap:anywhere;font-size:21px;line-height:1.45}.experience-summary[data-v-400cba84]{-webkit-line-clamp:4;white-space:normal;overflow-wrap:anywhere;-webkit-box-orient:vertical;font-size:14px;line-height:1.85;display:-webkit-box;overflow:hidden}.experience-project[data-v-400cba84],.experience-missing[data-v-400cba84]{overflow-wrap:anywhere;font-size:12px;line-height:1.7}.experience-actions[data-v-400cba84]{flex-wrap:wrap;align-items:center;gap:10px 20px;display:flex}.experience-actions button[data-v-400cba84]{font-size:13px}.experience-materials[data-v-400cba84]{border-top:1px solid var(--line);min-width:0;padding-top:12px}.experience-materials summary[data-v-400cba84]{color:var(--muted);cursor:pointer;font-size:12px}.experience-materials ul[data-v-400cba84]{gap:6px;margin:10px 0 0;padding-left:18px;display:grid}.experience-materials button[data-v-400cba84]{text-align:left;white-space:normal;overflow-wrap:anywhere;font-size:13px;line-height:1.7}.experience-capability[data-v-400cba84]{border:1px solid var(--line);border-radius:18px;margin-left:76px;padding:16px 20px;font-size:12px}.experience-capability summary[data-v-400cba84]{cursor:pointer}.experience-capability summary span[data-v-400cba84]{margin-left:12px}.experience-capability p[data-v-400cba84]{margin-top:12px;line-height:1.75}@media (width<=760px){.experience-intro[data-v-400cba84]{gap:10px;display:grid}.experience-intro p[data-v-400cba84]{max-width:none}.experience-entry[data-v-400cba84]{grid-template-columns:minmax(0,1fr);gap:8px}.experience-entry[data-v-400cba84]:before{display:none}.experience-clock[data-v-400cba84]{text-align:left;padding:0 4px}.experience-card.card[data-v-400cba84]{padding:20px}.experience-card h3[data-v-400cba84]{font-size:19px}.experience-capability[data-v-400cba84]{margin-left:0}}.time-page[data-v-6804b51c]{gap:var(--gap);min-width:0;display:grid}.time-intro[data-v-6804b51c]{background:linear-gradient(120deg, #ffffffd9, var(--glow-b));border:1px solid #fffc;border-radius:32px;justify-content:space-between;align-items:center;gap:24px;padding:32px clamp(24px,4vw,48px);display:flex}.time-intro h1[data-v-6804b51c]{letter-spacing:-.03em;font-size:clamp(25px,2.6vw,38px);line-height:1.35}.time-intro em[data-v-6804b51c]{color:var(--accent);font-style:normal}.time-intro p[data-v-6804b51c]{color:var(--muted);margin-top:14px}.time-clock[data-v-6804b51c]{text-align:center;background:linear-gradient(150deg, white, var(--orb-b));border:1px solid #fff;border-radius:50%;flex:none;place-content:center;width:140px;height:140px;display:grid;box-shadow:inset 0 0 0 9px #ffffff47}.time-clock span[data-v-6804b51c]{font-size:44px;font-weight:650}.time-clock small[data-v-6804b51c]{color:var(--muted);font-size:10px}.time-today[data-v-6804b51c],.work-grid[data-v-6804b51c]{gap:var(--gap);grid-template-columns:repeat(2,minmax(0,1fr));display:grid}.time-page .card[data-v-6804b51c]{align-content:start;gap:14px;min-width:0;display:grid}.time-page h2[data-v-6804b51c]{overflow-wrap:anywhere;font-size:22px;line-height:1.4}.time-page p[data-v-6804b51c],.time-page small[data-v-6804b51c]{overflow-wrap:anywhere;line-height:1.75}.time-cards[data-v-6804b51c]{gap:16px;display:grid}.time-page .time-task[data-v-6804b51c]{gap:12px}.time-filter[data-v-6804b51c]{flex-wrap:wrap;gap:12px;min-width:0;display:flex}.time-filter label[data-v-6804b51c]{flex-wrap:wrap;align-items:center;gap:12px;display:flex}.time-filter input[data-v-6804b51c]{min-width:0;max-width:100%}.work-card[data-v-6804b51c]{text-align:left;cursor:pointer;font:inherit;color:inherit;border:1px solid #ffffffe6;transition:transform .18s}.work-card[data-v-6804b51c]:hover{transform:translateY(-2px)}.time-settings form[data-v-6804b51c]{grid-template-columns:repeat(2,minmax(0,1fr));gap:15px;margin-top:18px;display:grid}.time-settings label[data-v-6804b51c]{gap:8px;min-width:0;display:grid}.time-settings input[data-v-6804b51c]{width:100%}.time-settings button[data-v-6804b51c]{justify-self:start}.time-pagination[data-v-6804b51c]{justify-content:center}.work-body[data-v-6804b51c]{white-space:pre-wrap;overflow-wrap:anywhere;padding:20px 0;font-size:16px;line-height:1.95}.share-status[data-v-6804b51c]{color:var(--accent)}.task-meta .task-priority[data-v-6804b51c]{color:var(--muted);white-space:nowrap;flex:none;align-items:center;gap:8px;font-size:12px;display:flex}.task-meta .task-priority span[data-v-6804b51c]{flex:none}.task-meta .task-priority .menu-select[data-v-6804b51c]{flex:none;width:100px;min-width:70px}.task-meta .task-priority[data-v-6804b51c] .menu-face{min-height:34px;padding:6px 10px}.task-sources summary[data-v-6804b51c]{color:var(--muted);font-size:12px}.time-page .list li[data-v-6804b51c]{overflow-wrap:anywhere;flex-wrap:wrap;align-items:center;gap:12px;display:flex}.time-page dl[data-v-6804b51c]{gap:12px;display:grid}.time-page dd[data-v-6804b51c]{overflow-wrap:anywhere;margin:0}@media (width<=760px){.time-today[data-v-6804b51c],.work-grid[data-v-6804b51c]{grid-template-columns:minmax(0,1fr)}.time-clock[data-v-6804b51c]{display:none}.time-intro[data-v-6804b51c]{padding:26px 22px}.time-settings form[data-v-6804b51c]{grid-template-columns:minmax(0,1fr)}}@media (width<=440px){.time-page .row[data-v-6804b51c]{gap:9px}.time-page h2[data-v-6804b51c]{font-size:20px}}