chatlab-cli 0.22.1 → 0.23.1

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 (80) hide show
  1. package/README.md +53 -30
  2. package/dist/{chunk-OC2W5Q5T.mjs → chunk-3MX7VF2B.mjs} +2 -2
  3. package/dist/chunk-5ADKYYNA.mjs +28 -0
  4. package/dist/chunk-5ADKYYNA.mjs.map +1 -0
  5. package/dist/{chunk-QRC3RSER.mjs → chunk-643S2N2U.mjs} +2 -2
  6. package/dist/{chunk-LZ3W6NS5.mjs → chunk-AHQQQ5HZ.mjs} +101 -69
  7. package/dist/chunk-AHQQQ5HZ.mjs.map +1 -0
  8. package/dist/{chunk-6NB475AA.mjs → chunk-FJ35V3TE.mjs} +2 -17
  9. package/dist/chunk-FJ35V3TE.mjs.map +1 -0
  10. package/dist/{chunk-SQKT45MM.mjs → chunk-G7Q7EQ3V.mjs} +546 -84
  11. package/dist/chunk-G7Q7EQ3V.mjs.map +1 -0
  12. package/dist/{chunk-XPBPKH6B.mjs → chunk-L37WJ33K.mjs} +134 -37
  13. package/dist/chunk-L37WJ33K.mjs.map +1 -0
  14. package/dist/{chunk-Z2LYMKCC.mjs → chunk-WTQ7LAZR.mjs} +2 -2
  15. package/dist/cli.mjs +4 -3
  16. package/dist/{http-O5P4BYXU.mjs → http-JDORENHT.mjs} +8 -7
  17. package/dist/{import-BDLL3DG7.mjs → import-LCBSBLYF.mjs} +4 -4
  18. package/dist/index.mjs +10 -9
  19. package/dist/{mcp-L2TPZFE7.mjs → mcp-AR7HBIK4.mjs} +8 -6
  20. package/dist/{mcp-L2TPZFE7.mjs.map → mcp-AR7HBIK4.mjs.map} +1 -1
  21. package/dist/service-WCGGRZTA.mjs +258 -0
  22. package/dist/service-WCGGRZTA.mjs.map +1 -0
  23. package/dist/{src-FVJL5ENA.mjs → src-EGXULYFQ.mjs} +2 -2
  24. package/dist/{stream-import-ZTEW3YVL.mjs → stream-import-QM5R5FDG.mjs} +3 -3
  25. package/dist/{update-checker-MQMQ6A4B.mjs → update-checker-JG5K67O2.mjs} +3 -2
  26. package/dist/{update-checker-MQMQ6A4B.mjs.map → update-checker-JG5K67O2.mjs.map} +1 -1
  27. package/dist-web/assets/{DebugToolsPanel-DkbsB6lr.css → DebugToolsPanel-Yzfz2ntn.css} +1 -1
  28. package/dist-web/assets/DebugToolsPanel.vue_vue_type_script_setup_true_lang-DXxg55kL.js +161 -0
  29. package/dist-web/assets/{EChartWordcloud-Ubal_aYg.js → EChartWordcloud-Cenbzcyj.js} +1 -1
  30. package/dist-web/assets/MessageExportModal-DMHA4X0b.js +1 -0
  31. package/dist-web/assets/electron-DpE69lO4.js +1 -0
  32. package/dist-web/assets/electron-SyPZX9OU.js +1 -0
  33. package/dist-web/assets/{fetch-BS4SlQjA.js → fetch-B7OBmANJ.js} +1 -1
  34. package/dist-web/assets/{fetch-o5NJ2uWE.js → fetch-BikSxuED.js} +1 -1
  35. package/dist-web/assets/fetch-BwMZFwbF.js +1 -0
  36. package/dist-web/assets/fetch-BxE8RQYE.js +1 -0
  37. package/dist-web/assets/fetch-CvfdN4gM.js +17 -0
  38. package/dist-web/assets/{fetch-W43zfemj.js → fetch-LBHcBBkv.js} +1 -1
  39. package/dist-web/assets/http-C741fIwb.js +1 -0
  40. package/dist-web/assets/index-BUfibEyG.css +1 -0
  41. package/dist-web/assets/{index-DOwQB7In.js → index-C2439065.js} +6 -6
  42. package/dist-web/assets/index-CD5Fz-JY.js +7 -0
  43. package/dist-web/assets/index-DC0LjKV6.js +2 -0
  44. package/dist-web/assets/index-Dl-X-izi.css +1 -0
  45. package/dist-web/assets/index-DywUneNT.css +1 -0
  46. package/dist-web/assets/index-JvmxkAGk.js +173 -0
  47. package/dist-web/assets/index-vEVpfw-R.js +163 -0
  48. package/dist-web/assets/model-catalog-DUuKjIVU.js +1 -0
  49. package/dist-web/assets/{vendor-nuxt-ui-7OAuiz_i.js → vendor-nuxt-ui-3XQAyMd0.js} +2 -2
  50. package/dist-web/assets/vendor-reka-ui-BrTYuIfH.js +11 -0
  51. package/dist-web/assets/{web-Cx5APyCN.js → web-Bm94rL5B.js} +1 -1
  52. package/dist-web/index.html +4 -4
  53. package/package.json +3 -2
  54. package/dist/chunk-6NB475AA.mjs.map +0 -1
  55. package/dist/chunk-LZ3W6NS5.mjs.map +0 -1
  56. package/dist/chunk-SQKT45MM.mjs.map +0 -1
  57. package/dist/chunk-XPBPKH6B.mjs.map +0 -1
  58. package/dist-web/assets/DebugToolsPanel.vue_vue_type_script_setup_true_lang-CqacsKDU.js +0 -147
  59. package/dist-web/assets/MessageExportModal-D1GY6WSV.js +0 -1
  60. package/dist-web/assets/electron-8qi0d92j.js +0 -1
  61. package/dist-web/assets/electron-CsUM2O_Y.js +0 -1
  62. package/dist-web/assets/fetch-BOogCPfg.js +0 -1
  63. package/dist-web/assets/fetch-CclRWOHf.js +0 -1
  64. package/dist-web/assets/fetch-CxwnEEqk.js +0 -17
  65. package/dist-web/assets/http-CeXMt-Fv.js +0 -1
  66. package/dist-web/assets/index-BE64tUWq.css +0 -1
  67. package/dist-web/assets/index-CM29Kc4p.js +0 -173
  68. package/dist-web/assets/index-CbQMfheg.css +0 -1
  69. package/dist-web/assets/index-D183wYuz.js +0 -7
  70. package/dist-web/assets/index-DSpvXged.css +0 -1
  71. package/dist-web/assets/index-DTxRy2FH.js +0 -163
  72. package/dist-web/assets/index-grds3iG-.js +0 -2
  73. package/dist-web/assets/vendor-reka-ui-CW2cIgMu.js +0 -11
  74. /package/dist/{chunk-OC2W5Q5T.mjs.map → chunk-3MX7VF2B.mjs.map} +0 -0
  75. /package/dist/{chunk-QRC3RSER.mjs.map → chunk-643S2N2U.mjs.map} +0 -0
  76. /package/dist/{chunk-Z2LYMKCC.mjs.map → chunk-WTQ7LAZR.mjs.map} +0 -0
  77. /package/dist/{http-O5P4BYXU.mjs.map → http-JDORENHT.mjs.map} +0 -0
  78. /package/dist/{import-BDLL3DG7.mjs.map → import-LCBSBLYF.mjs.map} +0 -0
  79. /package/dist/{src-FVJL5ENA.mjs.map → src-EGXULYFQ.mjs.map} +0 -0
  80. /package/dist/{stream-import-ZTEW3YVL.mjs.map → stream-import-QM5R5FDG.mjs.map} +0 -0
@@ -1,7 +0,0 @@
1
- const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/fetch-BS4SlQjA.js","assets/http-CeXMt-Fv.js","assets/fetch-o5NJ2uWE.js","assets/fetch-BOogCPfg.js","assets/vendor-reka-ui-CW2cIgMu.js","assets/vendor-nuxt-ui-7OAuiz_i.js","assets/vendor-snapdom-XnBoh1gd.js","assets/fetch-CxwnEEqk.js","assets/fetch-CclRWOHf.js","assets/fetch-W43zfemj.js","assets/index-CM29Kc4p.js","assets/index-DOwQB7In.js","assets/index-BKFGuwJu.css","assets/index-DTxRy2FH.js","assets/DebugToolsPanel.vue_vue_type_script_setup_true_lang-CqacsKDU.js","assets/vendor-echarts-wordcloud-CZ9gsX8l.js","assets/vendor-echarts-C5u62NnM.js","assets/vendor-zrender-DFl4U2Oe.js","assets/DebugToolsPanel-DkbsB6lr.css","assets/index-BE64tUWq.css","assets/index-grds3iG-.js","assets/index-CbQMfheg.css"])))=>i.map(i=>d[i]);
2
- import{h as G,i as Je,bw as ua,t as Gn,bp as Ct,m as ma,l as ga,e as pa,g as Xn,o as Yn,r as or,n as Xe,j as Qn,af as Jn,w as Ne,b as P,s as mt,p as $e,f as Ss,d as Qe,F as qt,D as Zn,L as v,bx as rr,Z as Me,G as b,P as A,U as ne,a5 as r,H as xe,u as o,K as re,Q as we,T as d,a3 as Be,R as J,a0 as Jt,O as ir,by as Zt,au as lr,J as cr,W as Ra,a9 as es,a as eo,c as dr,bz as ur,k as rt,q as mr,bA as gr,bB as pr,bC as fr,bD as fa,bE as to,bF as hr,I as vr,bG as yr}from"./vendor-reka-ui-CW2cIgMu.js";import{_ as ls,a as We,b as Ve,c as so,u as Cs,d as ha,e as lt,f as br,g as ht,h as cs,i as _r,j as Kt,k as va,l as xr,m as ao,n as no,o as kr,p as oo,q as wr,r as Sr,s as Cr,t as Mr,v as Ar,w as Tr,x as $r,y as Ir,z as Pr,A as Dr,B as Lr}from"./vendor-nuxt-ui-7OAuiz_i.js";import{_ as Ee,c as Er}from"./vendor-snapdom-XnBoh1gd.js";(function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const a of document.querySelectorAll('link[rel="modulepreload"]'))n(a);new MutationObserver(a=>{for(const i of a)if(i.type==="childList")for(const c of i.addedNodes)c.tagName==="LINK"&&c.rel==="modulepreload"&&n(c)}).observe(document,{childList:!0,subtree:!0});function s(a){const i={};return a.integrity&&(i.integrity=a.integrity),a.referrerPolicy&&(i.referrerPolicy=a.referrerPolicy),a.crossOrigin==="use-credentials"?i.credentials="include":a.crossOrigin==="anonymous"?i.credentials="omit":i.credentials="same-origin",i}function n(a){if(a.ep)return;a.ep=!0;const i=s(a);fetch(a.href,i)}})();let ro;const Ms=e=>ro=e,io=Symbol();function Xs(e){return e&&typeof e=="object"&&Object.prototype.toString.call(e)==="[object Object]"&&typeof e.toJSON!="function"}var Yt;(function(e){e.direct="direct",e.patchObject="patch object",e.patchFunction="patch function"})(Yt||(Yt={}));function Rr(){const e=pa(!0),t=e.run(()=>P({}));let s=[],n=[];const a=Jn({install(i){Ms(a),a._a=i,i.provide(io,a),i.config.globalProperties.$pinia=a,n.forEach(c=>s.push(c)),n=[]},use(i){return this._a?s.push(i):n.push(i),this},_p:s,_a:null,_e:e,_s:new Map,state:t});return a}const lo=()=>{};function Na(e,t,s,n=lo){e.add(t);const a=()=>{e.delete(t)&&n()};return!s&&Xn()&&Yn(a),a}function Ut(e,...t){e.forEach(s=>{s(...t)})}const Nr=e=>e(),Fa=Symbol(),Ns=Symbol();function Ys(e,t){e instanceof Map&&t instanceof Map?t.forEach((s,n)=>e.set(n,s)):e instanceof Set&&t instanceof Set&&t.forEach(e.add,e);for(const s in t){if(!t.hasOwnProperty(s))continue;const n=t[s],a=e[s];Xs(a)&&Xs(n)&&e.hasOwnProperty(s)&&!Je(n)&&!ua(n)?e[s]=Ys(a,n):e[s]=n}return e}const Fr=Symbol();function Ur(e){return!Xs(e)||!Object.prototype.hasOwnProperty.call(e,Fr)}const{assign:St}=Object;function Or(e){return!!(Je(e)&&e.effect)}function Hr(e,t,s,n){const{state:a,actions:i,getters:c}=t,l=s.state.value[e];let m;function u(){l||(s.state.value[e]=a?a():{});const f=Qn(s.state.value[e]);return St(f,i,Object.keys(c||{}).reduce((h,x)=>(h[x]=Jn(G(()=>{Ms(s);const S=s._s.get(e);return c[x].call(S,S)})),h),{}))}return m=co(e,u,t,s,n,!0),m}function co(e,t,s={},n,a,i){let c;const l=St({actions:{}},s),m={deep:!0};let u,f,h=new Set,x=new Set,S;const C=n.state.value[e];!i&&!C&&(n.state.value[e]={});let D;function M(ee){let V;u=f=!1,typeof ee=="function"?(ee(n.state.value[e]),V={type:Yt.patchFunction,storeId:e,events:S}):(Ys(n.state.value[e],ee),V={type:Yt.patchObject,payload:ee,storeId:e,events:S});const ie=D=Symbol();Xe().then(()=>{D===ie&&(u=!0)}),f=!0,Ut(h,V,n.state.value[e])}const g=i?function(){const{state:V}=s,ie=V?V():{};this.$patch(Q=>{St(Q,ie)})}:lo;function p(){c.stop(),h.clear(),x.clear(),n._s.delete(e)}const k=(ee,V="")=>{if(Fa in ee)return ee[Ns]=V,ee;const ie=function(){Ms(n);const Q=Array.from(arguments),Y=new Set,H=new Set;function B(le){Y.add(le)}function j(le){H.add(le)}Ut(x,{args:Q,name:ie[Ns],store:E,after:B,onError:j});let X;try{X=ee.apply(this&&this.$id===e?this:E,Q)}catch(le){throw Ut(H,le),le}return X instanceof Promise?X.then(le=>(Ut(Y,le),le)).catch(le=>(Ut(H,le),Promise.reject(le))):(Ut(Y,X),X)};return ie[Fa]=!0,ie[Ns]=V,ie},T={_p:n,$id:e,$onAction:Na.bind(null,x),$patch:M,$reset:g,$subscribe(ee,V={}){const ie=Na(h,ee,V.detached,()=>Q()),Q=c.run(()=>Ne(()=>n.state.value[e],Y=>{(V.flush==="sync"?f:u)&&ee({storeId:e,type:Yt.direct,events:S},Y)},St({},m,V)));return ie},$dispose:p},E=or(T);n._s.set(e,E);const N=(n._a&&n._a.runWithContext||Nr)(()=>n._e.run(()=>(c=pa()).run(()=>t({action:k}))));for(const ee in N){const V=N[ee];if(Je(V)&&!Or(V)||ua(V))i||(C&&Ur(V)&&(Je(V)?V.value=C[ee]:Ys(V,C[ee])),n.state.value[e][ee]=V);else if(typeof V=="function"){const ie=k(V,ee);N[ee]=ie,l.actions[ee]=V}}return St(E,N),St(Ct(E),N),Object.defineProperty(E,"$state",{get:()=>n.state.value[e],set:ee=>{M(V=>{St(V,ee)})}}),n._p.forEach(ee=>{St(E,c.run(()=>ee({store:E,app:n._a,pinia:n,options:l})))}),C&&i&&s.hydrate&&s.hydrate(E.$state,C),u=!0,f=!0,E}function wt(e,t,s){let n;const a=typeof t=="function";n=a?s:t;function i(c,l){const m=ga();return c=c||(m?ma(io,null):null),c&&Ms(c),c=ro,c._s.has(e)||(a?co(e,t,n,c):Hr(e,n,c)),c._s.get(e)}return i.$id=e,i}function Ge(e){const t=Ct(e),s={};for(const n in t){const a=t[n];a.effect?s[n]=G({get:()=>e[n],set(i){e[n]=i}}):(Je(a)||ua(a))&&(s[n]=Gn(e,n))}return s}function Vr(e,t){typeof console<"u"&&(console.warn("[intlify] "+e),t&&console.warn(t.stack))}const ws=typeof window<"u",Mt=(e,t=!1)=>t?Symbol.for(e):Symbol(e),zr=(e,t,s)=>Br({l:e,k:t,s}),Br=e=>JSON.stringify(e).replace(/\u2028/g,"\\u2028").replace(/\u2029/g,"\\u2029").replace(/\u0027/g,"\\u0027"),Ke=e=>typeof e=="number"&&isFinite(e),Wr=e=>ya(e)==="[object Date]",zt=e=>ya(e)==="[object RegExp]",As=e=>De(e)&&Object.keys(e).length===0,Ye=Object.assign,jr=Object.create,He=(e=null)=>jr(e);let Ua;const Lt=()=>Ua||(Ua=typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:typeof global<"u"?global:He());function Oa(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&apos;").replace(/\//g,"&#x2F;").replace(/=/g,"&#x3D;")}function Ha(e){return e.replace(/&(?![a-zA-Z0-9#]{2,6};)/g,"&amp;").replace(/"/g,"&quot;").replace(/'/g,"&apos;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function qr(e){return e=e.replace(/(\w+)\s*=\s*"([^"]*)"/g,(n,a,i)=>`${a}="${Ha(i)}"`),e=e.replace(/(\w+)\s*=\s*'([^']*)'/g,(n,a,i)=>`${a}='${Ha(i)}'`),/\s*on\w+\s*=\s*["']?[^"'>]+["']?/gi.test(e)&&(e=e.replace(/(\s+)(on)(\w+\s*=)/gi,"$1&#111;n$3")),[/(\s+(?:href|src|action|formaction)\s*=\s*["']?)\s*javascript:/gi,/(style\s*=\s*["'][^"']*url\s*\(\s*)javascript:/gi].forEach(n=>{e=e.replace(n,"$1javascript&#58;")}),e}const Kr=Object.prototype.hasOwnProperty;function pt(e,t){return Kr.call(e,t)}const je=Array.isArray,ze=e=>typeof e=="function",ye=e=>typeof e=="string",Fe=e=>typeof e=="boolean",Ue=e=>e!==null&&typeof e=="object",Gr=e=>Ue(e)&&ze(e.then)&&ze(e.catch),uo=Object.prototype.toString,ya=e=>uo.call(e),De=e=>ya(e)==="[object Object]",Xr=e=>e==null?"":je(e)||De(e)&&e.toString===uo?JSON.stringify(e,null,2):String(e);function ba(e,t=""){return e.reduce((s,n,a)=>a===0?s+n:s+t+n,"")}const us=e=>!Ue(e)||je(e);function hs(e,t){if(us(e)||us(t))throw new Error("Invalid value");const s=[{src:e,des:t}];for(;s.length;){const{src:n,des:a}=s.pop();Object.keys(n).forEach(i=>{i!=="__proto__"&&(Ue(n[i])&&!Ue(a[i])&&(a[i]=Array.isArray(n[i])?[]:He()),us(a[i])||us(n[i])?a[i]=n[i]:s.push({src:n[i],des:a[i]}))})}}function Yr(e,t,s){return{line:e,column:t,offset:s}}function Qs(e,t,s){return{start:e,end:t}}const Oe={EXPECTED_TOKEN:1,INVALID_TOKEN_IN_PLACEHOLDER:2,UNTERMINATED_SINGLE_QUOTE_IN_PLACEHOLDER:3,UNKNOWN_ESCAPE_SEQUENCE:4,INVALID_UNICODE_ESCAPE_SEQUENCE:5,UNBALANCED_CLOSING_BRACE:6,UNTERMINATED_CLOSING_BRACE:7,EMPTY_PLACEHOLDER:8,NOT_ALLOW_NEST_PLACEHOLDER:9,INVALID_LINKED_FORMAT:10,MUST_HAVE_MESSAGES_IN_PLURAL:11,UNEXPECTED_EMPTY_LINKED_MODIFIER:12,UNEXPECTED_EMPTY_LINKED_KEY:13,UNEXPECTED_LEXICAL_ANALYSIS:14},Qr=17;function Ts(e,t,s={}){const{domain:n,messages:a,args:i}=s,c=e,l=new SyntaxError(String(c));return l.code=e,t&&(l.location=t),l.domain=n,l}function Jr(e){throw e}const vt=" ",Zr="\r",et=`
3
- `,ei="\u2028",ti="\u2029";function si(e){const t=e;let s=0,n=1,a=1,i=0;const c=N=>t[N]===Zr&&t[N+1]===et,l=N=>t[N]===et,m=N=>t[N]===ti,u=N=>t[N]===ei,f=N=>c(N)||l(N)||m(N)||u(N),h=()=>s,x=()=>n,S=()=>a,C=()=>i,D=N=>c(N)||m(N)||u(N)?et:t[N],M=()=>D(s),g=()=>D(s+i);function p(){return i=0,f(s)&&(n++,a=0),c(s)&&s++,s++,a++,t[s]}function k(){return c(s+i)&&i++,i++,t[s+i]}function T(){s=0,n=1,a=1,i=0}function E(N=0){i=N}function I(){const N=s+i;for(;N!==s;)p();i=0}return{index:h,line:x,column:S,peekOffset:C,charAt:D,currentChar:M,currentPeek:g,next:p,peek:k,reset:T,resetPeek:E,skipToPeek:I}}const _t=void 0,ai=".",Va="'",ni="tokenizer";function oi(e,t={}){const s=t.location!==!1,n=si(e),a=()=>n.index(),i=()=>Yr(n.line(),n.column(),n.index()),c=i(),l=a(),m={currentType:13,offset:l,startLoc:c,endLoc:c,lastType:13,lastOffset:l,lastStartLoc:c,lastEndLoc:c,braceNest:0,inLinked:!1,text:""},u=()=>m,{onError:f}=t;function h(w,R,oe,...te){const q=u();if(R.column+=oe,R.offset+=oe,f){const ue=s?Qs(q.startLoc,R):null,U=Ts(w,ue,{domain:ni,args:te});f(U)}}function x(w,R,oe){w.endLoc=i(),w.currentType=R;const te={type:R};return s&&(te.loc=Qs(w.startLoc,w.endLoc)),oe!=null&&(te.value=oe),te}const S=w=>x(w,13);function C(w,R){return w.currentChar()===R?(w.next(),R):(h(Oe.EXPECTED_TOKEN,i(),0,R),"")}function D(w){let R="";for(;w.currentPeek()===vt||w.currentPeek()===et;)R+=w.currentPeek(),w.peek();return R}function M(w){const R=D(w);return w.skipToPeek(),R}function g(w){if(w===_t)return!1;const R=w.charCodeAt(0);return R>=97&&R<=122||R>=65&&R<=90||R===95}function p(w){if(w===_t)return!1;const R=w.charCodeAt(0);return R>=48&&R<=57}function k(w,R){const{currentType:oe}=R;if(oe!==2)return!1;D(w);const te=g(w.currentPeek());return w.resetPeek(),te}function T(w,R){const{currentType:oe}=R;if(oe!==2)return!1;D(w);const te=w.currentPeek()==="-"?w.peek():w.currentPeek(),q=p(te);return w.resetPeek(),q}function E(w,R){const{currentType:oe}=R;if(oe!==2)return!1;D(w);const te=w.currentPeek()===Va;return w.resetPeek(),te}function I(w,R){const{currentType:oe}=R;if(oe!==7)return!1;D(w);const te=w.currentPeek()===".";return w.resetPeek(),te}function N(w,R){const{currentType:oe}=R;if(oe!==8)return!1;D(w);const te=g(w.currentPeek());return w.resetPeek(),te}function ee(w,R){const{currentType:oe}=R;if(!(oe===7||oe===11))return!1;D(w);const te=w.currentPeek()===":";return w.resetPeek(),te}function V(w,R){const{currentType:oe}=R;if(oe!==9)return!1;const te=()=>{const ue=w.currentPeek();return ue==="{"?g(w.peek()):ue==="@"||ue==="|"||ue===":"||ue==="."||ue===vt||!ue?!1:ue===et?(w.peek(),te()):Q(w,!1)},q=te();return w.resetPeek(),q}function ie(w){D(w);const R=w.currentPeek()==="|";return w.resetPeek(),R}function Q(w,R=!0){const oe=(q=!1,ue="")=>{const U=w.currentPeek();return U==="{"||U==="@"||!U?q:U==="|"?!(ue===vt||ue===et):U===vt?(w.peek(),oe(!0,vt)):U===et?(w.peek(),oe(!0,et)):!0},te=oe();return R&&w.resetPeek(),te}function Y(w,R){const oe=w.currentChar();return oe===_t?_t:R(oe)?(w.next(),oe):null}function H(w){const R=w.charCodeAt(0);return R>=97&&R<=122||R>=65&&R<=90||R>=48&&R<=57||R===95||R===36}function B(w){return Y(w,H)}function j(w){const R=w.charCodeAt(0);return R>=97&&R<=122||R>=65&&R<=90||R>=48&&R<=57||R===95||R===36||R===45}function X(w){return Y(w,j)}function le(w){const R=w.charCodeAt(0);return R>=48&&R<=57}function F(w){return Y(w,le)}function _(w){const R=w.charCodeAt(0);return R>=48&&R<=57||R>=65&&R<=70||R>=97&&R<=102}function y(w){return Y(w,_)}function L(w){let R="",oe="";for(;R=F(w);)oe+=R;return oe}function $(w){let R="";for(;;){const oe=w.currentChar();if(oe==="{"||oe==="}"||oe==="@"||oe==="|"||!oe)break;if(oe===vt||oe===et)if(Q(w))R+=oe,w.next();else{if(ie(w))break;R+=oe,w.next()}else R+=oe,w.next()}return R}function z(w){M(w);let R="",oe="";for(;R=X(w);)oe+=R;const te=w.currentChar();if(te&&te!=="}"&&te!==_t&&te!==vt&&te!==et&&te!==" "){const q=he(w);return h(Oe.INVALID_TOKEN_IN_PLACEHOLDER,i(),0,oe+q),oe+q}return w.currentChar()===_t&&h(Oe.UNTERMINATED_CLOSING_BRACE,i(),0),oe}function ce(w){M(w);let R="";return w.currentChar()==="-"?(w.next(),R+=`-${L(w)}`):R+=L(w),w.currentChar()===_t&&h(Oe.UNTERMINATED_CLOSING_BRACE,i(),0),R}function W(w){return w!==Va&&w!==et}function se(w){M(w),C(w,"'");let R="",oe="";for(;R=Y(w,W);)R==="\\"?oe+=pe(w):oe+=R;const te=w.currentChar();return te===et||te===_t?(h(Oe.UNTERMINATED_SINGLE_QUOTE_IN_PLACEHOLDER,i(),0),te===et&&(w.next(),C(w,"'")),oe):(C(w,"'"),oe)}function pe(w){const R=w.currentChar();switch(R){case"\\":case"'":return w.next(),`\\${R}`;case"u":return me(w,R,4);case"U":return me(w,R,6);default:return h(Oe.UNKNOWN_ESCAPE_SEQUENCE,i(),0,R),""}}function me(w,R,oe){C(w,R);let te="";for(let q=0;q<oe;q++){const ue=y(w);if(!ue){h(Oe.INVALID_UNICODE_ESCAPE_SEQUENCE,i(),0,`\\${R}${te}${w.currentChar()}`);break}te+=ue}return`\\${R}${te}`}function ae(w){return w!=="{"&&w!=="}"&&w!==vt&&w!==et}function he(w){M(w);let R="",oe="";for(;R=Y(w,ae);)oe+=R;return oe}function ke(w){let R="",oe="";for(;R=B(w);)oe+=R;return oe}function ve(w){const R=oe=>{const te=w.currentChar();return te==="{"||te==="@"||te==="|"||te==="("||te===")"||!te||te===vt?oe:(oe+=te,w.next(),R(oe))};return R("")}function _e(w){M(w);const R=C(w,"|");return M(w),R}function be(w,R){let oe=null;switch(w.currentChar()){case"{":return R.braceNest>=1&&h(Oe.NOT_ALLOW_NEST_PLACEHOLDER,i(),0),w.next(),oe=x(R,2,"{"),M(w),R.braceNest++,oe;case"}":return R.braceNest>0&&R.currentType===2&&h(Oe.EMPTY_PLACEHOLDER,i(),0),w.next(),oe=x(R,3,"}"),R.braceNest--,R.braceNest>0&&M(w),R.inLinked&&R.braceNest===0&&(R.inLinked=!1),oe;case"@":return R.braceNest>0&&h(Oe.UNTERMINATED_CLOSING_BRACE,i(),0),oe=Le(w,R)||S(R),R.braceNest=0,oe;default:{let q=!0,ue=!0,U=!0;if(ie(w))return R.braceNest>0&&h(Oe.UNTERMINATED_CLOSING_BRACE,i(),0),oe=x(R,1,_e(w)),R.braceNest=0,R.inLinked=!1,oe;if(R.braceNest>0&&(R.currentType===4||R.currentType===5||R.currentType===6))return h(Oe.UNTERMINATED_CLOSING_BRACE,i(),0),R.braceNest=0,Ae(w,R);if(q=k(w,R))return oe=x(R,4,z(w)),M(w),oe;if(ue=T(w,R))return oe=x(R,5,ce(w)),M(w),oe;if(U=E(w,R))return oe=x(R,6,se(w)),M(w),oe;if(!q&&!ue&&!U)return oe=x(R,12,he(w)),h(Oe.INVALID_TOKEN_IN_PLACEHOLDER,i(),0,oe.value),M(w),oe;break}}return oe}function Le(w,R){const{currentType:oe}=R;let te=null;const q=w.currentChar();switch((oe===7||oe===8||oe===11||oe===9)&&(q===et||q===vt)&&h(Oe.INVALID_LINKED_FORMAT,i(),0),q){case"@":return w.next(),te=x(R,7,"@"),R.inLinked=!0,te;case".":return M(w),w.next(),x(R,8,".");case":":return M(w),w.next(),x(R,9,":");default:return ie(w)?(te=x(R,1,_e(w)),R.braceNest=0,R.inLinked=!1,te):I(w,R)||ee(w,R)?(M(w),Le(w,R)):N(w,R)?(M(w),x(R,11,ke(w))):V(w,R)?(M(w),q==="{"?be(w,R)||te:x(R,10,ve(w))):(oe===7&&h(Oe.INVALID_LINKED_FORMAT,i(),0),R.braceNest=0,R.inLinked=!1,Ae(w,R))}}function Ae(w,R){let oe={type:13};if(R.braceNest>0)return be(w,R)||S(R);if(R.inLinked)return Le(w,R)||S(R);switch(w.currentChar()){case"{":return be(w,R)||S(R);case"}":return h(Oe.UNBALANCED_CLOSING_BRACE,i(),0),w.next(),x(R,3,"}");case"@":return Le(w,R)||S(R);default:{if(ie(w))return oe=x(R,1,_e(w)),R.braceNest=0,R.inLinked=!1,oe;if(Q(w))return x(R,0,$(w));break}}return oe}function de(){const{currentType:w,offset:R,startLoc:oe,endLoc:te}=m;return m.lastType=w,m.lastOffset=R,m.lastStartLoc=oe,m.lastEndLoc=te,m.offset=a(),m.startLoc=i(),n.currentChar()===_t?x(m,13):Ae(n,m)}return{nextToken:de,currentOffset:a,currentPosition:i,context:u}}const ri="parser",ii=/(?:\\\\|\\'|\\u([0-9a-fA-F]{4})|\\U([0-9a-fA-F]{6}))/g;function li(e,t,s){switch(e){case"\\\\":return"\\";case"\\'":return"'";default:{const n=parseInt(t||s,16);return n<=55295||n>=57344?String.fromCodePoint(n):"�"}}}function ci(e={}){const t=e.location!==!1,{onError:s}=e;function n(g,p,k,T,...E){const I=g.currentPosition();if(I.offset+=T,I.column+=T,s){const N=t?Qs(k,I):null,ee=Ts(p,N,{domain:ri,args:E});s(ee)}}function a(g,p,k){const T={type:g};return t&&(T.start=p,T.end=p,T.loc={start:k,end:k}),T}function i(g,p,k,T){t&&(g.end=p,g.loc&&(g.loc.end=k))}function c(g,p){const k=g.context(),T=a(3,k.offset,k.startLoc);return T.value=p,i(T,g.currentOffset(),g.currentPosition()),T}function l(g,p){const k=g.context(),{lastOffset:T,lastStartLoc:E}=k,I=a(5,T,E);return I.index=parseInt(p,10),g.nextToken(),i(I,g.currentOffset(),g.currentPosition()),I}function m(g,p){const k=g.context(),{lastOffset:T,lastStartLoc:E}=k,I=a(4,T,E);return I.key=p,g.nextToken(),i(I,g.currentOffset(),g.currentPosition()),I}function u(g,p){const k=g.context(),{lastOffset:T,lastStartLoc:E}=k,I=a(9,T,E);return I.value=p.replace(ii,li),g.nextToken(),i(I,g.currentOffset(),g.currentPosition()),I}function f(g){const p=g.nextToken(),k=g.context(),{lastOffset:T,lastStartLoc:E}=k,I=a(8,T,E);return p.type!==11?(n(g,Oe.UNEXPECTED_EMPTY_LINKED_MODIFIER,k.lastStartLoc,0),I.value="",i(I,T,E),{nextConsumeToken:p,node:I}):(p.value==null&&n(g,Oe.UNEXPECTED_LEXICAL_ANALYSIS,k.lastStartLoc,0,yt(p)),I.value=p.value||"",i(I,g.currentOffset(),g.currentPosition()),{node:I})}function h(g,p){const k=g.context(),T=a(7,k.offset,k.startLoc);return T.value=p,i(T,g.currentOffset(),g.currentPosition()),T}function x(g){const p=g.context(),k=a(6,p.offset,p.startLoc);let T=g.nextToken();if(T.type===8){const E=f(g);k.modifier=E.node,T=E.nextConsumeToken||g.nextToken()}switch(T.type!==9&&n(g,Oe.UNEXPECTED_LEXICAL_ANALYSIS,p.lastStartLoc,0,yt(T)),T=g.nextToken(),T.type===2&&(T=g.nextToken()),T.type){case 10:T.value==null&&n(g,Oe.UNEXPECTED_LEXICAL_ANALYSIS,p.lastStartLoc,0,yt(T)),k.key=h(g,T.value||"");break;case 4:T.value==null&&n(g,Oe.UNEXPECTED_LEXICAL_ANALYSIS,p.lastStartLoc,0,yt(T)),k.key=m(g,T.value||"");break;case 5:T.value==null&&n(g,Oe.UNEXPECTED_LEXICAL_ANALYSIS,p.lastStartLoc,0,yt(T)),k.key=l(g,T.value||"");break;case 6:T.value==null&&n(g,Oe.UNEXPECTED_LEXICAL_ANALYSIS,p.lastStartLoc,0,yt(T)),k.key=u(g,T.value||"");break;default:{n(g,Oe.UNEXPECTED_EMPTY_LINKED_KEY,p.lastStartLoc,0);const E=g.context(),I=a(7,E.offset,E.startLoc);return I.value="",i(I,E.offset,E.startLoc),k.key=I,i(k,E.offset,E.startLoc),{nextConsumeToken:T,node:k}}}return i(k,g.currentOffset(),g.currentPosition()),{node:k}}function S(g){const p=g.context(),k=p.currentType===1?g.currentOffset():p.offset,T=p.currentType===1?p.endLoc:p.startLoc,E=a(2,k,T);E.items=[];let I=null;do{const V=I||g.nextToken();switch(I=null,V.type){case 0:V.value==null&&n(g,Oe.UNEXPECTED_LEXICAL_ANALYSIS,p.lastStartLoc,0,yt(V)),E.items.push(c(g,V.value||""));break;case 5:V.value==null&&n(g,Oe.UNEXPECTED_LEXICAL_ANALYSIS,p.lastStartLoc,0,yt(V)),E.items.push(l(g,V.value||""));break;case 4:V.value==null&&n(g,Oe.UNEXPECTED_LEXICAL_ANALYSIS,p.lastStartLoc,0,yt(V)),E.items.push(m(g,V.value||""));break;case 6:V.value==null&&n(g,Oe.UNEXPECTED_LEXICAL_ANALYSIS,p.lastStartLoc,0,yt(V)),E.items.push(u(g,V.value||""));break;case 7:{const ie=x(g);E.items.push(ie.node),I=ie.nextConsumeToken||null;break}}}while(p.currentType!==13&&p.currentType!==1);const N=p.currentType===1?p.lastOffset:g.currentOffset(),ee=p.currentType===1?p.lastEndLoc:g.currentPosition();return i(E,N,ee),E}function C(g,p,k,T){const E=g.context();let I=T.items.length===0;const N=a(1,p,k);N.cases=[],N.cases.push(T);do{const ee=S(g);I||(I=ee.items.length===0),N.cases.push(ee)}while(E.currentType!==13);return I&&n(g,Oe.MUST_HAVE_MESSAGES_IN_PLURAL,k,0),i(N,g.currentOffset(),g.currentPosition()),N}function D(g){const p=g.context(),{offset:k,startLoc:T}=p,E=S(g);return p.currentType===13?E:C(g,k,T,E)}function M(g){const p=oi(g,Ye({},e)),k=p.context(),T=a(0,k.offset,k.startLoc);return t&&T.loc&&(T.loc.source=g),T.body=D(p),e.onCacheKey&&(T.cacheKey=e.onCacheKey(g)),k.currentType!==13&&n(p,Oe.UNEXPECTED_LEXICAL_ANALYSIS,k.lastStartLoc,0,g[k.offset]||""),i(T,p.currentOffset(),p.currentPosition()),T}return{parse:M}}function yt(e){if(e.type===13)return"EOF";const t=(e.value||"").replace(/\r?\n/gu,"\\n");return t.length>10?t.slice(0,9)+"…":t}function di(e,t={}){const s={ast:e,helpers:new Set};return{context:()=>s,helper:i=>(s.helpers.add(i),i)}}function za(e,t){for(let s=0;s<e.length;s++)_a(e[s],t)}function _a(e,t){switch(e.type){case 1:za(e.cases,t),t.helper("plural");break;case 2:za(e.items,t);break;case 6:{_a(e.key,t),t.helper("linked"),t.helper("type");break}case 5:t.helper("interpolate"),t.helper("list");break;case 4:t.helper("interpolate"),t.helper("named");break}}function ui(e,t={}){const s=di(e);s.helper("normalize"),e.body&&_a(e.body,s);const n=s.context();e.helpers=Array.from(n.helpers)}function mi(e){const t=e.body;return t.type===2?Ba(t):t.cases.forEach(s=>Ba(s)),e}function Ba(e){if(e.items.length===1){const t=e.items[0];(t.type===3||t.type===9)&&(e.static=t.value,delete t.value)}else{const t=[];for(let s=0;s<e.items.length;s++){const n=e.items[s];if(!(n.type===3||n.type===9)||n.value==null)break;t.push(n.value)}if(t.length===e.items.length){e.static=ba(t);for(let s=0;s<e.items.length;s++){const n=e.items[s];(n.type===3||n.type===9)&&delete n.value}}}}function Vt(e){switch(e.t=e.type,e.type){case 0:{const t=e;Vt(t.body),t.b=t.body,delete t.body;break}case 1:{const t=e,s=t.cases;for(let n=0;n<s.length;n++)Vt(s[n]);t.c=s,delete t.cases;break}case 2:{const t=e,s=t.items;for(let n=0;n<s.length;n++)Vt(s[n]);t.i=s,delete t.items,t.static&&(t.s=t.static,delete t.static);break}case 3:case 9:case 8:case 7:{const t=e;t.value&&(t.v=t.value,delete t.value);break}case 6:{const t=e;Vt(t.key),t.k=t.key,delete t.key,t.modifier&&(Vt(t.modifier),t.m=t.modifier,delete t.modifier);break}case 5:{const t=e;t.i=t.index,delete t.index;break}case 4:{const t=e;t.k=t.key,delete t.key;break}}delete e.type}function gi(e,t){const{filename:s,breakLineCode:n,needIndent:a}=t,i=t.location!==!1,c={filename:s,code:"",column:1,line:1,offset:0,map:void 0,breakLineCode:n,needIndent:a,indentLevel:0};i&&e.loc&&(c.source=e.loc.source);const l=()=>c;function m(D,M){c.code+=D}function u(D,M=!0){const g=M?n:"";m(a?g+" ".repeat(D):g)}function f(D=!0){const M=++c.indentLevel;D&&u(M)}function h(D=!0){const M=--c.indentLevel;D&&u(M)}function x(){u(c.indentLevel)}return{context:l,push:m,indent:f,deindent:h,newline:x,helper:D=>`_${D}`,needIndent:()=>c.needIndent}}function pi(e,t){const{helper:s}=e;e.push(`${s("linked")}(`),Bt(e,t.key),t.modifier?(e.push(", "),Bt(e,t.modifier),e.push(", _type")):e.push(", undefined, _type"),e.push(")")}function fi(e,t){const{helper:s,needIndent:n}=e;e.push(`${s("normalize")}([`),e.indent(n());const a=t.items.length;for(let i=0;i<a&&(Bt(e,t.items[i]),i!==a-1);i++)e.push(", ");e.deindent(n()),e.push("])")}function hi(e,t){const{helper:s,needIndent:n}=e;if(t.cases.length>1){e.push(`${s("plural")}([`),e.indent(n());const a=t.cases.length;for(let i=0;i<a&&(Bt(e,t.cases[i]),i!==a-1);i++)e.push(", ");e.deindent(n()),e.push("])")}}function vi(e,t){t.body?Bt(e,t.body):e.push("null")}function Bt(e,t){const{helper:s}=e;switch(t.type){case 0:vi(e,t);break;case 1:hi(e,t);break;case 2:fi(e,t);break;case 6:pi(e,t);break;case 8:e.push(JSON.stringify(t.value),t);break;case 7:e.push(JSON.stringify(t.value),t);break;case 5:e.push(`${s("interpolate")}(${s("list")}(${t.index}))`,t);break;case 4:e.push(`${s("interpolate")}(${s("named")}(${JSON.stringify(t.key)}))`,t);break;case 9:e.push(JSON.stringify(t.value),t);break;case 3:e.push(JSON.stringify(t.value),t);break}}const yi=(e,t={})=>{const s=ye(t.mode)?t.mode:"normal",n=ye(t.filename)?t.filename:"message.intl";t.sourceMap;const a=t.breakLineCode!=null?t.breakLineCode:s==="arrow"?";":`
4
- `,i=t.needIndent?t.needIndent:s!=="arrow",c=e.helpers||[],l=gi(e,{filename:n,breakLineCode:a,needIndent:i});l.push(s==="normal"?"function __msg__ (ctx) {":"(ctx) => {"),l.indent(i),c.length>0&&(l.push(`const { ${ba(c.map(f=>`${f}: _${f}`),", ")} } = ctx`),l.newline()),l.push("return "),Bt(l,e),l.deindent(i),l.push("}"),delete e.helpers;const{code:m,map:u}=l.context();return{ast:e,code:m,map:u?u.toJSON():void 0}};function bi(e,t={}){const s=Ye({},t),n=!!s.jit,a=!!s.minify,i=s.optimize==null?!0:s.optimize,l=ci(s).parse(e);return n?(i&&mi(l),a&&Vt(l),{ast:l,code:""}):(ui(l,s),yi(l,s))}function _i(){typeof __INTLIFY_PROD_DEVTOOLS__!="boolean"&&(Lt().__INTLIFY_PROD_DEVTOOLS__=!1),typeof __INTLIFY_DROP_MESSAGE_COMPILER__!="boolean"&&(Lt().__INTLIFY_DROP_MESSAGE_COMPILER__=!1)}function bt(e){return Ue(e)&&xa(e)===0&&(pt(e,"b")||pt(e,"body"))}const mo=["b","body"];function xi(e){return At(e,mo)}const go=["c","cases"];function ki(e){return At(e,go,[])}const po=["s","static"];function wi(e){return At(e,po)}const fo=["i","items"];function Si(e){return At(e,fo,[])}const ho=["t","type"];function xa(e){return At(e,ho)}const vo=["v","value"];function ms(e,t){const s=At(e,vo);if(s!=null)return s;throw ts(t)}const yo=["m","modifier"];function Ci(e){return At(e,yo)}const bo=["k","key"];function Mi(e){const t=At(e,bo);if(t)return t;throw ts(6)}function At(e,t,s){for(let n=0;n<t.length;n++){const a=t[n];if(pt(e,a)&&e[a]!=null)return e[a]}return s}const _o=[...mo,...go,...po,...fo,...bo,...yo,...vo,...ho];function ts(e){return new Error(`unhandled node type: ${e}`)}function Fs(e){return s=>Ai(s,e)}function Ai(e,t){const s=xi(t);if(s==null)throw ts(0);if(xa(s)===1){const i=ki(s);return e.plural(i.reduce((c,l)=>[...c,Wa(e,l)],[]))}else return Wa(e,s)}function Wa(e,t){const s=wi(t);if(s!=null)return e.type==="text"?s:e.normalize([s]);{const n=Si(t).reduce((a,i)=>[...a,Js(e,i)],[]);return e.normalize(n)}}function Js(e,t){const s=xa(t);switch(s){case 3:return ms(t,s);case 9:return ms(t,s);case 4:{const n=t;if(pt(n,"k")&&n.k)return e.interpolate(e.named(n.k));if(pt(n,"key")&&n.key)return e.interpolate(e.named(n.key));throw ts(s)}case 5:{const n=t;if(pt(n,"i")&&Ke(n.i))return e.interpolate(e.list(n.i));if(pt(n,"index")&&Ke(n.index))return e.interpolate(e.list(n.index));throw ts(s)}case 6:{const n=t,a=Ci(n),i=Mi(n);return e.linked(Js(e,i),a?Js(e,a):void 0,e.type)}case 7:return ms(t,s);case 8:return ms(t,s);default:throw new Error(`unhandled node on format message part: ${s}`)}}const Ti=e=>e;let gs=He();function $i(e,t={}){let s=!1;const n=t.onError||Jr;return t.onError=a=>{s=!0,n(a)},{...bi(e,t),detectError:s}}function Ii(e,t){if(!__INTLIFY_DROP_MESSAGE_COMPILER__&&ye(e)){Fe(t.warnHtmlMessage)&&t.warnHtmlMessage;const n=(t.onCacheKey||Ti)(e),a=gs[n];if(a)return a;const{ast:i,detectError:c}=$i(e,{...t,location:!1,jit:!0}),l=Fs(i);return c?l:gs[n]=l}else{const s=e.cacheKey;if(s){const n=gs[s];return n||(gs[s]=Fs(e))}else return Fs(e)}}let ss=null;function Pi(e){ss=e}function Di(e,t,s){ss&&ss.emit("i18n:init",{timestamp:Date.now(),i18n:e,version:t,meta:s})}const Li=Ei("function:translate");function Ei(e){return t=>ss&&ss.emit(e,t)}const xt={INVALID_ARGUMENT:Qr,INVALID_DATE_ARGUMENT:18,INVALID_ISO_DATE_ARGUMENT:19,NOT_SUPPORT_LOCALE_PROMISE_VALUE:21,NOT_SUPPORT_LOCALE_ASYNC_FUNCTION:22,NOT_SUPPORT_LOCALE_TYPE:23},Ri=24;function kt(e){return Ts(e,null,void 0)}function ka(e,t){return t.locale!=null?ja(t.locale):ja(e.locale)}let Us;function ja(e){if(ye(e))return e;if(ze(e)){if(e.resolvedOnce&&Us!=null)return Us;if(e.constructor.name==="Function"){const t=e();if(Gr(t))throw kt(xt.NOT_SUPPORT_LOCALE_PROMISE_VALUE);return Us=t}else throw kt(xt.NOT_SUPPORT_LOCALE_ASYNC_FUNCTION)}else throw kt(xt.NOT_SUPPORT_LOCALE_TYPE)}function Ni(e,t,s){return[...new Set([s,...je(t)?t:Ue(t)?Object.keys(t):ye(t)?[t]:[s]])]}function xo(e,t,s){const n=ye(s)?s:as,a=e;a.__localeChainCache||(a.__localeChainCache=new Map);let i=a.__localeChainCache.get(n);if(!i){i=[];let c=[s];for(;je(c);)c=qa(i,c,t);const l=je(t)||!De(t)?t:t.default?t.default:null;c=ye(l)?[l]:l,je(c)&&qa(i,c,!1),a.__localeChainCache.set(n,i)}return i}function qa(e,t,s){let n=!0;for(let a=0;a<t.length&&Fe(n);a++){const i=t[a];ye(i)&&(n=Fi(e,t[a],s))}return n}function Fi(e,t,s){let n;const a=t.split("-");do{const i=a.join("-");n=Ui(e,i,s),a.splice(-1,1)}while(a.length&&n===!0);return n}function Ui(e,t,s){let n=!1;if(!e.includes(t)&&(n=!0,t)){n=t[t.length-1]!=="!";const a=t.replace(/!/g,"");e.push(a),(je(s)||De(s))&&s[a]&&(n=s[a])}return n}const Tt=[];Tt[0]={w:[0],i:[3,0],"[":[4],o:[7]};Tt[1]={w:[1],".":[2],"[":[4],o:[7]};Tt[2]={w:[2],i:[3,0],0:[3,0]};Tt[3]={i:[3,0],0:[3,0],w:[1,1],".":[2,1],"[":[4,1],o:[7,1]};Tt[4]={"'":[5,0],'"':[6,0],"[":[4,2],"]":[1,3],o:8,l:[4,0]};Tt[5]={"'":[4,0],o:8,l:[5,0]};Tt[6]={'"':[4,0],o:8,l:[6,0]};const Oi=/^\s?(?:true|false|-?[\d.]+|'[^']*'|"[^"]*")\s?$/;function Hi(e){return Oi.test(e)}function Vi(e){const t=e.charCodeAt(0),s=e.charCodeAt(e.length-1);return t===s&&(t===34||t===39)?e.slice(1,-1):e}function zi(e){if(e==null)return"o";switch(e.charCodeAt(0)){case 91:case 93:case 46:case 34:case 39:return e;case 95:case 36:case 45:return"i";case 9:case 10:case 13:case 160:case 65279:case 8232:case 8233:return"w"}return"i"}function Bi(e){const t=e.trim();return e.charAt(0)==="0"&&isNaN(parseInt(e))?!1:Hi(t)?Vi(t):"*"+t}function Wi(e){const t=[];let s=-1,n=0,a=0,i,c,l,m,u,f,h;const x=[];x[0]=()=>{c===void 0?c=l:c+=l},x[1]=()=>{c!==void 0&&(t.push(c),c=void 0)},x[2]=()=>{x[0](),a++},x[3]=()=>{if(a>0)a--,n=4,x[0]();else{if(a=0,c===void 0||(c=Bi(c),c===!1))return!1;x[1]()}};function S(){const C=e[s+1];if(n===5&&C==="'"||n===6&&C==='"')return s++,l="\\"+C,x[0](),!0}for(;n!==null;)if(s++,i=e[s],!(i==="\\"&&S())){if(m=zi(i),h=Tt[n],u=h[m]||h.l||8,u===8||(n=u[0],u[1]!==void 0&&(f=x[u[1]],f&&(l=i,f()===!1))))return;if(n===7)return t}}const Ka=new Map;function ji(e,t){return Ue(e)?e[t]:null}function qi(e,t){if(!Ue(e))return null;let s=Ka.get(t);if(s||(s=Wi(t),s&&Ka.set(t,s)),!s)return null;const n=s.length;let a=e,i=0;for(;i<n;){const c=s[i];if(_o.includes(c)&&bt(a))return null;const l=a[c];if(l===void 0||ze(a))return null;a=l,i++}return a}const Ki="11.2.8",$s=-1,as="en-US",Ga="",Xa=e=>`${e.charAt(0).toLocaleUpperCase()}${e.substr(1)}`;function Gi(){return{upper:(e,t)=>t==="text"&&ye(e)?e.toUpperCase():t==="vnode"&&Ue(e)&&"__v_isVNode"in e?e.children.toUpperCase():e,lower:(e,t)=>t==="text"&&ye(e)?e.toLowerCase():t==="vnode"&&Ue(e)&&"__v_isVNode"in e?e.children.toLowerCase():e,capitalize:(e,t)=>t==="text"&&ye(e)?Xa(e):t==="vnode"&&Ue(e)&&"__v_isVNode"in e?Xa(e.children):e}}let ko;function Xi(e){ko=e}let wo;function Yi(e){wo=e}let So;function Qi(e){So=e}let Co=null;const Ji=e=>{Co=e},Zi=()=>Co;let Mo=null;const Ya=e=>{Mo=e},el=()=>Mo;let Qa=0;function tl(e={}){const t=ze(e.onWarn)?e.onWarn:Vr,s=ye(e.version)?e.version:Ki,n=ye(e.locale)||ze(e.locale)?e.locale:as,a=ze(n)?as:n,i=je(e.fallbackLocale)||De(e.fallbackLocale)||ye(e.fallbackLocale)||e.fallbackLocale===!1?e.fallbackLocale:a,c=De(e.messages)?e.messages:Os(a),l=De(e.datetimeFormats)?e.datetimeFormats:Os(a),m=De(e.numberFormats)?e.numberFormats:Os(a),u=Ye(He(),e.modifiers,Gi()),f=e.pluralRules||He(),h=ze(e.missing)?e.missing:null,x=Fe(e.missingWarn)||zt(e.missingWarn)?e.missingWarn:!0,S=Fe(e.fallbackWarn)||zt(e.fallbackWarn)?e.fallbackWarn:!0,C=!!e.fallbackFormat,D=!!e.unresolving,M=ze(e.postTranslation)?e.postTranslation:null,g=De(e.processor)?e.processor:null,p=Fe(e.warnHtmlMessage)?e.warnHtmlMessage:!0,k=!!e.escapeParameter,T=ze(e.messageCompiler)?e.messageCompiler:ko,E=ze(e.messageResolver)?e.messageResolver:wo||ji,I=ze(e.localeFallbacker)?e.localeFallbacker:So||Ni,N=Ue(e.fallbackContext)?e.fallbackContext:void 0,ee=e,V=Ue(ee.__datetimeFormatters)?ee.__datetimeFormatters:new Map,ie=Ue(ee.__numberFormatters)?ee.__numberFormatters:new Map,Q=Ue(ee.__meta)?ee.__meta:{};Qa++;const Y={version:s,cid:Qa,locale:n,fallbackLocale:i,messages:c,modifiers:u,pluralRules:f,missing:h,missingWarn:x,fallbackWarn:S,fallbackFormat:C,unresolving:D,postTranslation:M,processor:g,warnHtmlMessage:p,escapeParameter:k,messageCompiler:T,messageResolver:E,localeFallbacker:I,fallbackContext:N,onWarn:t,__meta:Q};return Y.datetimeFormats=l,Y.numberFormats=m,Y.__datetimeFormatters=V,Y.__numberFormatters=ie,__INTLIFY_PROD_DEVTOOLS__&&Di(Y,s,Q),Y}const Os=e=>({[e]:He()});function wa(e,t,s,n,a){const{missing:i,onWarn:c}=e;if(i!==null){const l=i(e,s,t,a);return ye(l)?l:t}else return t}function Xt(e,t,s){const n=e;n.__localeChainCache=new Map,e.localeFallbacker(e,s,t)}function sl(e,t){return e===t?!1:e.split("-")[0]===t.split("-")[0]}function al(e,t){const s=t.indexOf(e);if(s===-1)return!1;for(let n=s+1;n<t.length;n++)if(sl(e,t[n]))return!0;return!1}function Ja(e,...t){const{datetimeFormats:s,unresolving:n,fallbackLocale:a,onWarn:i,localeFallbacker:c}=e,{__datetimeFormatters:l}=e,[m,u,f,h]=Zs(...t),x=Fe(f.missingWarn)?f.missingWarn:e.missingWarn;Fe(f.fallbackWarn)?f.fallbackWarn:e.fallbackWarn;const S=!!f.part,C=ka(e,f),D=c(e,a,C);if(!ye(m)||m==="")return new Intl.DateTimeFormat(C,h).format(u);let M={},g,p=null;const k="datetime format";for(let I=0;I<D.length&&(g=D[I],M=s[g]||{},p=M[m],!De(p));I++)wa(e,m,g,x,k);if(!De(p)||!ye(g))return n?$s:m;let T=`${g}__${m}`;As(h)||(T=`${T}__${JSON.stringify(h)}`);let E=l.get(T);return E||(E=new Intl.DateTimeFormat(g,Ye({},p,h)),l.set(T,E)),S?E.formatToParts(u):E.format(u)}const Ao=["localeMatcher","weekday","era","year","month","day","hour","minute","second","timeZoneName","formatMatcher","hour12","timeZone","dateStyle","timeStyle","calendar","dayPeriod","numberingSystem","hourCycle","fractionalSecondDigits"];function Zs(...e){const[t,s,n,a]=e,i=He();let c=He(),l;if(ye(t)){const m=t.match(/(\d{4}-\d{2}-\d{2})(T|\s)?(.*)/);if(!m)throw kt(xt.INVALID_ISO_DATE_ARGUMENT);const u=m[3]?m[3].trim().startsWith("T")?`${m[1].trim()}${m[3].trim()}`:`${m[1].trim()}T${m[3].trim()}`:m[1].trim();l=new Date(u);try{l.toISOString()}catch{throw kt(xt.INVALID_ISO_DATE_ARGUMENT)}}else if(Wr(t)){if(isNaN(t.getTime()))throw kt(xt.INVALID_DATE_ARGUMENT);l=t}else if(Ke(t))l=t;else throw kt(xt.INVALID_ARGUMENT);return ye(s)?i.key=s:De(s)&&Object.keys(s).forEach(m=>{Ao.includes(m)?c[m]=s[m]:i[m]=s[m]}),ye(n)?i.locale=n:De(n)&&(c=n),De(a)&&(c=a),[i.key||"",l,i,c]}function Za(e,t,s){const n=e;for(const a in s){const i=`${t}__${a}`;n.__datetimeFormatters.has(i)&&n.__datetimeFormatters.delete(i)}}function en(e,...t){const{numberFormats:s,unresolving:n,fallbackLocale:a,onWarn:i,localeFallbacker:c}=e,{__numberFormatters:l}=e,[m,u,f,h]=ea(...t),x=Fe(f.missingWarn)?f.missingWarn:e.missingWarn;Fe(f.fallbackWarn)?f.fallbackWarn:e.fallbackWarn;const S=!!f.part,C=ka(e,f),D=c(e,a,C);if(!ye(m)||m==="")return new Intl.NumberFormat(C,h).format(u);let M={},g,p=null;const k="number format";for(let I=0;I<D.length&&(g=D[I],M=s[g]||{},p=M[m],!De(p));I++)wa(e,m,g,x,k);if(!De(p)||!ye(g))return n?$s:m;let T=`${g}__${m}`;As(h)||(T=`${T}__${JSON.stringify(h)}`);let E=l.get(T);return E||(E=new Intl.NumberFormat(g,Ye({},p,h)),l.set(T,E)),S?E.formatToParts(u):E.format(u)}const To=["localeMatcher","style","currency","currencyDisplay","currencySign","useGrouping","minimumIntegerDigits","minimumFractionDigits","maximumFractionDigits","minimumSignificantDigits","maximumSignificantDigits","compactDisplay","notation","signDisplay","unit","unitDisplay","roundingMode","roundingPriority","roundingIncrement","trailingZeroDisplay"];function ea(...e){const[t,s,n,a]=e,i=He();let c=He();if(!Ke(t))throw kt(xt.INVALID_ARGUMENT);const l=t;return ye(s)?i.key=s:De(s)&&Object.keys(s).forEach(m=>{To.includes(m)?c[m]=s[m]:i[m]=s[m]}),ye(n)?i.locale=n:De(n)&&(c=n),De(a)&&(c=a),[i.key||"",l,i,c]}function tn(e,t,s){const n=e;for(const a in s){const i=`${t}__${a}`;n.__numberFormatters.has(i)&&n.__numberFormatters.delete(i)}}const nl=e=>e,ol=e=>"",rl="text",il=e=>e.length===0?"":ba(e),ll=Xr;function sn(e,t){return e=Math.abs(e),t===2?e?e>1?1:0:1:e?Math.min(e,2):0}function cl(e){const t=Ke(e.pluralIndex)?e.pluralIndex:-1;return e.named&&(Ke(e.named.count)||Ke(e.named.n))?Ke(e.named.count)?e.named.count:Ke(e.named.n)?e.named.n:t:t}function dl(e,t){t.count||(t.count=e),t.n||(t.n=e)}function ul(e={}){const t=e.locale,s=cl(e),n=Ue(e.pluralRules)&&ye(t)&&ze(e.pluralRules[t])?e.pluralRules[t]:sn,a=Ue(e.pluralRules)&&ye(t)&&ze(e.pluralRules[t])?sn:void 0,i=g=>g[n(s,g.length,a)],c=e.list||[],l=g=>c[g],m=e.named||He();Ke(e.pluralIndex)&&dl(s,m);const u=g=>m[g];function f(g,p){const k=ze(e.messages)?e.messages(g,!!p):Ue(e.messages)?e.messages[g]:!1;return k||(e.parent?e.parent.message(g):ol)}const h=g=>e.modifiers?e.modifiers[g]:nl,x=De(e.processor)&&ze(e.processor.normalize)?e.processor.normalize:il,S=De(e.processor)&&ze(e.processor.interpolate)?e.processor.interpolate:ll,C=De(e.processor)&&ye(e.processor.type)?e.processor.type:rl,M={list:l,named:u,plural:i,linked:(g,...p)=>{const[k,T]=p;let E="text",I="";p.length===1?Ue(k)?(I=k.modifier||I,E=k.type||E):ye(k)&&(I=k||I):p.length===2&&(ye(k)&&(I=k||I),ye(T)&&(E=T||E));const N=f(g,!0)(M),ee=E==="vnode"&&je(N)&&I?N[0]:N;return I?h(I)(ee,E):ee},message:f,type:C,interpolate:S,normalize:x,values:Ye(He(),c,m)};return M}const an=()=>"",dt=e=>ze(e);function nn(e,...t){const{fallbackFormat:s,postTranslation:n,unresolving:a,messageCompiler:i,fallbackLocale:c,messages:l}=e,[m,u]=ta(...t),f=Fe(u.missingWarn)?u.missingWarn:e.missingWarn,h=Fe(u.fallbackWarn)?u.fallbackWarn:e.fallbackWarn,x=Fe(u.escapeParameter)?u.escapeParameter:e.escapeParameter,S=!!u.resolvedMessage,C=ye(u.default)||Fe(u.default)?Fe(u.default)?i?m:()=>m:u.default:s?i?m:()=>m:null,D=s||C!=null&&(ye(C)||ze(C)),M=ka(e,u);x&&ml(u);let[g,p,k]=S?[m,M,l[M]||He()]:$o(e,m,M,c,h,f),T=g,E=m;if(!S&&!(ye(T)||bt(T)||dt(T))&&D&&(T=C,E=T),!S&&(!(ye(T)||bt(T)||dt(T))||!ye(p)))return a?$s:m;let I=!1;const N=()=>{I=!0},ee=dt(T)?T:Io(e,m,p,T,E,N);if(I)return T;const V=fl(e,p,k,u),ie=ul(V),Q=gl(e,ee,ie);let Y=n?n(Q,m):Q;if(x&&ye(Y)&&(Y=qr(Y)),__INTLIFY_PROD_DEVTOOLS__){const H={timestamp:Date.now(),key:ye(m)?m:dt(T)?T.key:"",locale:p||(dt(T)?T.locale:""),format:ye(T)?T:dt(T)?T.source:"",message:Y};H.meta=Ye({},e.__meta,Zi()||{}),Li(H)}return Y}function ml(e){je(e.list)?e.list=e.list.map(t=>ye(t)?Oa(t):t):Ue(e.named)&&Object.keys(e.named).forEach(t=>{ye(e.named[t])&&(e.named[t]=Oa(e.named[t]))})}function $o(e,t,s,n,a,i){const{messages:c,onWarn:l,messageResolver:m,localeFallbacker:u}=e,f=u(e,n,s);let h=He(),x,S=null;const C="translate";for(let D=0;D<f.length&&(x=f[D],h=c[x]||He(),(S=m(h,t))===null&&(S=h[t]),!(ye(S)||bt(S)||dt(S)));D++)if(!al(x,f)){const M=wa(e,t,x,i,C);M!==t&&(S=M)}return[S,x,h]}function Io(e,t,s,n,a,i){const{messageCompiler:c,warnHtmlMessage:l}=e;if(dt(n)){const u=n;return u.locale=u.locale||s,u.key=u.key||t,u}if(c==null){const u=(()=>n);return u.locale=s,u.key=t,u}const m=c(n,pl(e,s,a,n,l,i));return m.locale=s,m.key=t,m.source=n,m}function gl(e,t,s){return t(s)}function ta(...e){const[t,s,n]=e,a=He();if(!ye(t)&&!Ke(t)&&!dt(t)&&!bt(t))throw kt(xt.INVALID_ARGUMENT);const i=Ke(t)?String(t):(dt(t),t);return Ke(s)?a.plural=s:ye(s)?a.default=s:De(s)&&!As(s)?a.named=s:je(s)&&(a.list=s),Ke(n)?a.plural=n:ye(n)?a.default=n:De(n)&&Ye(a,n),[i,a]}function pl(e,t,s,n,a,i){return{locale:t,key:s,warnHtmlMessage:a,onError:c=>{throw i&&i(c),c},onCacheKey:c=>zr(t,s,c)}}function fl(e,t,s,n){const{modifiers:a,pluralRules:i,messageResolver:c,fallbackLocale:l,fallbackWarn:m,missingWarn:u,fallbackContext:f}=e,x={locale:t,modifiers:a,pluralRules:i,messages:(S,C)=>{let D=c(s,S);if(D==null&&(f||C)){const[,,M]=$o(f||e,S,t,l,m,u);D=c(M,S)}if(ye(D)||bt(D)){let M=!1;const p=Io(e,S,t,D,S,()=>{M=!0});return M?an:p}else return dt(D)?D:an}};return e.processor&&(x.processor=e.processor),n.list&&(x.list=n.list),n.named&&(x.named=n.named),Ke(n.plural)&&(x.pluralIndex=n.plural),x}_i();const hl="11.2.8";function vl(){typeof __VUE_I18N_FULL_INSTALL__!="boolean"&&(Lt().__VUE_I18N_FULL_INSTALL__=!0),typeof __VUE_I18N_LEGACY_API__!="boolean"&&(Lt().__VUE_I18N_LEGACY_API__=!0),typeof __INTLIFY_DROP_MESSAGE_COMPILER__!="boolean"&&(Lt().__INTLIFY_DROP_MESSAGE_COMPILER__=!1),typeof __INTLIFY_PROD_DEVTOOLS__!="boolean"&&(Lt().__INTLIFY_PROD_DEVTOOLS__=!1)}const it={UNEXPECTED_RETURN_TYPE:Ri,INVALID_ARGUMENT:25,MUST_BE_CALL_SETUP_TOP:26,NOT_INSTALLED:27,REQUIRED_VALUE:28,INVALID_VALUE:29,NOT_INSTALLED_WITH_PROVIDE:31,UNEXPECTED_ERROR:32};function ct(e,...t){return Ts(e,null,void 0)}const sa=Mt("__translateVNode"),aa=Mt("__datetimeParts"),na=Mt("__numberParts"),Po=Mt("__setPluralRules"),Do=Mt("__injectWithOption"),oa=Mt("__dispose");function ns(e){if(!Ue(e)||bt(e))return e;for(const t in e)if(pt(e,t))if(!t.includes("."))Ue(e[t])&&ns(e[t]);else{const s=t.split("."),n=s.length-1;let a=e,i=!1;for(let c=0;c<n;c++){if(s[c]==="__proto__")throw new Error(`unsafe key: ${s[c]}`);if(s[c]in a||(a[s[c]]=He()),!Ue(a[s[c]])){i=!0;break}a=a[s[c]]}if(i||(bt(a)?_o.includes(s[n])||delete e[t]:(a[s[n]]=e[t],delete e[t])),!bt(a)){const c=a[s[n]];Ue(c)&&ns(c)}}return e}function Sa(e,t){const{messages:s,__i18n:n,messageResolver:a,flatJson:i}=t,c=De(s)?s:je(n)?He():{[e]:He()};if(je(n)&&n.forEach(l=>{if("locale"in l&&"resource"in l){const{locale:m,resource:u}=l;m?(c[m]=c[m]||He(),hs(u,c[m])):hs(u,c)}else ye(l)&&hs(JSON.parse(l),c)}),a==null&&i)for(const l in c)pt(c,l)&&ns(c[l]);return c}function Lo(e){return e.type}function Eo(e,t,s){let n=Ue(t.messages)?t.messages:He();"__i18nGlobal"in s&&(n=Sa(e.locale.value,{messages:n,__i18n:s.__i18nGlobal}));const a=Object.keys(n);a.length&&a.forEach(i=>{e.mergeLocaleMessage(i,n[i])});{if(Ue(t.datetimeFormats)){const i=Object.keys(t.datetimeFormats);i.length&&i.forEach(c=>{e.mergeDateTimeFormat(c,t.datetimeFormats[c])})}if(Ue(t.numberFormats)){const i=Object.keys(t.numberFormats);i.length&&i.forEach(c=>{e.mergeNumberFormat(c,t.numberFormats[c])})}}}function on(e){return v(rr,null,e,0)}function os(){return Ss()}const rn="__INTLIFY_META__",ln=()=>[],yl=()=>!1;let cn=0;function dn(e){return((t,s,n,a)=>e(s,n,os()||void 0,a))}const bl=()=>{const e=os();let t=null;return e&&(t=Lo(e)[rn])?{[rn]:t}:null};function Ca(e={}){const{__root:t,__injectWithOption:s}=e,n=t===void 0,a=e.flatJson,i=ws?P:mt;let c=Fe(e.inheritLocale)?e.inheritLocale:!0;const l=i(t&&c?t.locale.value:ye(e.locale)?e.locale:as),m=i(t&&c?t.fallbackLocale.value:ye(e.fallbackLocale)||je(e.fallbackLocale)||De(e.fallbackLocale)||e.fallbackLocale===!1?e.fallbackLocale:l.value),u=i(Sa(l.value,e)),f=i(De(e.datetimeFormats)?e.datetimeFormats:{[l.value]:{}}),h=i(De(e.numberFormats)?e.numberFormats:{[l.value]:{}});let x=t?t.missingWarn:Fe(e.missingWarn)||zt(e.missingWarn)?e.missingWarn:!0,S=t?t.fallbackWarn:Fe(e.fallbackWarn)||zt(e.fallbackWarn)?e.fallbackWarn:!0,C=t?t.fallbackRoot:Fe(e.fallbackRoot)?e.fallbackRoot:!0,D=!!e.fallbackFormat,M=ze(e.missing)?e.missing:null,g=ze(e.missing)?dn(e.missing):null,p=ze(e.postTranslation)?e.postTranslation:null,k=t?t.warnHtmlMessage:Fe(e.warnHtmlMessage)?e.warnHtmlMessage:!0,T=!!e.escapeParameter;const E=t?t.modifiers:De(e.modifiers)?e.modifiers:{};let I=e.pluralRules||t&&t.pluralRules,N;N=(()=>{n&&Ya(null);const U={version:hl,locale:l.value,fallbackLocale:m.value,messages:u.value,modifiers:E,pluralRules:I,missing:g===null?void 0:g,missingWarn:x,fallbackWarn:S,fallbackFormat:D,unresolving:!0,postTranslation:p===null?void 0:p,warnHtmlMessage:k,escapeParameter:T,messageResolver:e.messageResolver,messageCompiler:e.messageCompiler,__meta:{framework:"vue"}};U.datetimeFormats=f.value,U.numberFormats=h.value,U.__datetimeFormatters=De(N)?N.__datetimeFormatters:void 0,U.__numberFormatters=De(N)?N.__numberFormatters:void 0;const K=tl(U);return n&&Ya(K),K})(),Xt(N,l.value,m.value);function V(){return[l.value,m.value,u.value,f.value,h.value]}const ie=G({get:()=>l.value,set:U=>{N.locale=U,l.value=U}}),Q=G({get:()=>m.value,set:U=>{N.fallbackLocale=U,m.value=U,Xt(N,l.value,U)}}),Y=G(()=>u.value),H=G(()=>f.value),B=G(()=>h.value);function j(){return ze(p)?p:null}function X(U){p=U,N.postTranslation=U}function le(){return M}function F(U){U!==null&&(g=dn(U)),M=U,N.missing=g}const _=(U,K,Ie,Te,Z,Ce)=>{V();let Ze;try{__INTLIFY_PROD_DEVTOOLS__,n||(N.fallbackContext=t?el():void 0),Ze=U(N)}finally{__INTLIFY_PROD_DEVTOOLS__,n||(N.fallbackContext=void 0)}if(Ie!=="translate exists"&&Ke(Ze)&&Ze===$s||Ie==="translate exists"&&!Ze){const[O,ge]=K();return t&&C?Te(t):Z(O)}else{if(Ce(Ze))return Ze;throw ct(it.UNEXPECTED_RETURN_TYPE)}};function y(...U){return _(K=>Reflect.apply(nn,null,[K,...U]),()=>ta(...U),"translate",K=>Reflect.apply(K.t,K,[...U]),K=>K,K=>ye(K))}function L(...U){const[K,Ie,Te]=U;if(Te&&!Ue(Te))throw ct(it.INVALID_ARGUMENT);return y(K,Ie,Ye({resolvedMessage:!0},Te||{}))}function $(...U){return _(K=>Reflect.apply(Ja,null,[K,...U]),()=>Zs(...U),"datetime format",K=>Reflect.apply(K.d,K,[...U]),()=>Ga,K=>ye(K)||je(K))}function z(...U){return _(K=>Reflect.apply(en,null,[K,...U]),()=>ea(...U),"number format",K=>Reflect.apply(K.n,K,[...U]),()=>Ga,K=>ye(K)||je(K))}function ce(U){return U.map(K=>ye(K)||Ke(K)||Fe(K)?on(String(K)):K)}const se={normalize:ce,interpolate:U=>U,type:"vnode"};function pe(...U){return _(K=>{let Ie;const Te=K;try{Te.processor=se,Ie=Reflect.apply(nn,null,[Te,...U])}finally{Te.processor=null}return Ie},()=>ta(...U),"translate",K=>K[sa](...U),K=>[on(K)],K=>je(K))}function me(...U){return _(K=>Reflect.apply(en,null,[K,...U]),()=>ea(...U),"number format",K=>K[na](...U),ln,K=>ye(K)||je(K))}function ae(...U){return _(K=>Reflect.apply(Ja,null,[K,...U]),()=>Zs(...U),"datetime format",K=>K[aa](...U),ln,K=>ye(K)||je(K))}function he(U){I=U,N.pluralRules=I}function ke(U,K){return _(()=>{if(!U)return!1;const Ie=ye(K)?K:l.value,Te=be(Ie),Z=N.messageResolver(Te,U);return bt(Z)||dt(Z)||ye(Z)},()=>[U],"translate exists",Ie=>Reflect.apply(Ie.te,Ie,[U,K]),yl,Ie=>Fe(Ie))}function ve(U){let K=null;const Ie=xo(N,m.value,l.value);for(let Te=0;Te<Ie.length;Te++){const Z=u.value[Ie[Te]]||{},Ce=N.messageResolver(Z,U);if(Ce!=null){K=Ce;break}}return K}function _e(U){const K=ve(U);return K??(t?t.tm(U)||{}:{})}function be(U){return u.value[U]||{}}function Le(U,K){if(a){const Ie={[U]:K};for(const Te in Ie)pt(Ie,Te)&&ns(Ie[Te]);K=Ie[U]}u.value[U]=K,N.messages=u.value}function Ae(U,K){u.value[U]=u.value[U]||{};const Ie={[U]:K};if(a)for(const Te in Ie)pt(Ie,Te)&&ns(Ie[Te]);K=Ie[U],hs(K,u.value[U]),N.messages=u.value}function de(U){return f.value[U]||{}}function w(U,K){f.value[U]=K,N.datetimeFormats=f.value,Za(N,U,K)}function R(U,K){f.value[U]=Ye(f.value[U]||{},K),N.datetimeFormats=f.value,Za(N,U,K)}function oe(U){return h.value[U]||{}}function te(U,K){h.value[U]=K,N.numberFormats=h.value,tn(N,U,K)}function q(U,K){h.value[U]=Ye(h.value[U]||{},K),N.numberFormats=h.value,tn(N,U,K)}cn++,t&&ws&&(Ne(t.locale,U=>{c&&(l.value=U,N.locale=U,Xt(N,l.value,m.value))}),Ne(t.fallbackLocale,U=>{c&&(m.value=U,N.fallbackLocale=U,Xt(N,l.value,m.value))}));const ue={id:cn,locale:ie,fallbackLocale:Q,get inheritLocale(){return c},set inheritLocale(U){c=U,U&&t&&(l.value=t.locale.value,m.value=t.fallbackLocale.value,Xt(N,l.value,m.value))},get availableLocales(){return Object.keys(u.value).sort()},messages:Y,get modifiers(){return E},get pluralRules(){return I||{}},get isGlobal(){return n},get missingWarn(){return x},set missingWarn(U){x=U,N.missingWarn=x},get fallbackWarn(){return S},set fallbackWarn(U){S=U,N.fallbackWarn=S},get fallbackRoot(){return C},set fallbackRoot(U){C=U},get fallbackFormat(){return D},set fallbackFormat(U){D=U,N.fallbackFormat=D},get warnHtmlMessage(){return k},set warnHtmlMessage(U){k=U,N.warnHtmlMessage=U},get escapeParameter(){return T},set escapeParameter(U){T=U,N.escapeParameter=U},t:y,getLocaleMessage:be,setLocaleMessage:Le,mergeLocaleMessage:Ae,getPostTranslationHandler:j,setPostTranslationHandler:X,getMissingHandler:le,setMissingHandler:F,[Po]:he};return ue.datetimeFormats=H,ue.numberFormats=B,ue.rt=L,ue.te=ke,ue.tm=_e,ue.d=$,ue.n=z,ue.getDateTimeFormat=de,ue.setDateTimeFormat=w,ue.mergeDateTimeFormat=R,ue.getNumberFormat=oe,ue.setNumberFormat=te,ue.mergeNumberFormat=q,ue[Do]=s,ue[sa]=pe,ue[aa]=ae,ue[na]=me,ue}function _l(e){const t=ye(e.locale)?e.locale:as,s=ye(e.fallbackLocale)||je(e.fallbackLocale)||De(e.fallbackLocale)||e.fallbackLocale===!1?e.fallbackLocale:t,n=ze(e.missing)?e.missing:void 0,a=Fe(e.silentTranslationWarn)||zt(e.silentTranslationWarn)?!e.silentTranslationWarn:!0,i=Fe(e.silentFallbackWarn)||zt(e.silentFallbackWarn)?!e.silentFallbackWarn:!0,c=Fe(e.fallbackRoot)?e.fallbackRoot:!0,l=!!e.formatFallbackMessages,m=De(e.modifiers)?e.modifiers:{},u=e.pluralizationRules,f=ze(e.postTranslation)?e.postTranslation:void 0,h=ye(e.warnHtmlInMessage)?e.warnHtmlInMessage!=="off":!0,x=!!e.escapeParameterHtml,S=Fe(e.sync)?e.sync:!0;let C=e.messages;if(De(e.sharedMessages)){const E=e.sharedMessages;C=Object.keys(E).reduce((N,ee)=>{const V=N[ee]||(N[ee]={});return Ye(V,E[ee]),N},C||{})}const{__i18n:D,__root:M,__injectWithOption:g}=e,p=e.datetimeFormats,k=e.numberFormats,T=e.flatJson;return{locale:t,fallbackLocale:s,messages:C,flatJson:T,datetimeFormats:p,numberFormats:k,missing:n,missingWarn:a,fallbackWarn:i,fallbackRoot:c,fallbackFormat:l,modifiers:m,pluralRules:u,postTranslation:f,warnHtmlMessage:h,escapeParameter:x,messageResolver:e.messageResolver,inheritLocale:S,__i18n:D,__root:M,__injectWithOption:g}}function ra(e={}){const t=Ca(_l(e)),{__extender:s}=e,n={id:t.id,get locale(){return t.locale.value},set locale(a){t.locale.value=a},get fallbackLocale(){return t.fallbackLocale.value},set fallbackLocale(a){t.fallbackLocale.value=a},get messages(){return t.messages.value},get datetimeFormats(){return t.datetimeFormats.value},get numberFormats(){return t.numberFormats.value},get availableLocales(){return t.availableLocales},get missing(){return t.getMissingHandler()},set missing(a){t.setMissingHandler(a)},get silentTranslationWarn(){return Fe(t.missingWarn)?!t.missingWarn:t.missingWarn},set silentTranslationWarn(a){t.missingWarn=Fe(a)?!a:a},get silentFallbackWarn(){return Fe(t.fallbackWarn)?!t.fallbackWarn:t.fallbackWarn},set silentFallbackWarn(a){t.fallbackWarn=Fe(a)?!a:a},get modifiers(){return t.modifiers},get formatFallbackMessages(){return t.fallbackFormat},set formatFallbackMessages(a){t.fallbackFormat=a},get postTranslation(){return t.getPostTranslationHandler()},set postTranslation(a){t.setPostTranslationHandler(a)},get sync(){return t.inheritLocale},set sync(a){t.inheritLocale=a},get warnHtmlInMessage(){return t.warnHtmlMessage?"warn":"off"},set warnHtmlInMessage(a){t.warnHtmlMessage=a!=="off"},get escapeParameterHtml(){return t.escapeParameter},set escapeParameterHtml(a){t.escapeParameter=a},get pluralizationRules(){return t.pluralRules||{}},__composer:t,t(...a){return Reflect.apply(t.t,t,[...a])},rt(...a){return Reflect.apply(t.rt,t,[...a])},te(a,i){return t.te(a,i)},tm(a){return t.tm(a)},getLocaleMessage(a){return t.getLocaleMessage(a)},setLocaleMessage(a,i){t.setLocaleMessage(a,i)},mergeLocaleMessage(a,i){t.mergeLocaleMessage(a,i)},d(...a){return Reflect.apply(t.d,t,[...a])},getDateTimeFormat(a){return t.getDateTimeFormat(a)},setDateTimeFormat(a,i){t.setDateTimeFormat(a,i)},mergeDateTimeFormat(a,i){t.mergeDateTimeFormat(a,i)},n(...a){return Reflect.apply(t.n,t,[...a])},getNumberFormat(a){return t.getNumberFormat(a)},setNumberFormat(a,i){t.setNumberFormat(a,i)},mergeNumberFormat(a,i){t.mergeNumberFormat(a,i)}};return n.__extender=s,n}function xl(e,t,s){return{beforeCreate(){const n=os();if(!n)throw ct(it.UNEXPECTED_ERROR);const a=this.$options;if(a.i18n){const i=a.i18n;if(a.__i18n&&(i.__i18n=a.__i18n),i.__root=t,this===this.$root)this.$i18n=un(e,i);else{i.__injectWithOption=!0,i.__extender=s.__vueI18nExtend,this.$i18n=ra(i);const c=this.$i18n;c.__extender&&(c.__disposer=c.__extender(this.$i18n))}}else if(a.__i18n)if(this===this.$root)this.$i18n=un(e,a);else{this.$i18n=ra({__i18n:a.__i18n,__injectWithOption:!0,__extender:s.__vueI18nExtend,__root:t});const i=this.$i18n;i.__extender&&(i.__disposer=i.__extender(this.$i18n))}else this.$i18n=e;a.__i18nGlobal&&Eo(t,a,a),this.$t=(...i)=>this.$i18n.t(...i),this.$rt=(...i)=>this.$i18n.rt(...i),this.$te=(i,c)=>this.$i18n.te(i,c),this.$d=(...i)=>this.$i18n.d(...i),this.$n=(...i)=>this.$i18n.n(...i),this.$tm=i=>this.$i18n.tm(i),s.__setInstance(n,this.$i18n)},mounted(){},unmounted(){const n=os();if(!n)throw ct(it.UNEXPECTED_ERROR);const a=this.$i18n;delete this.$t,delete this.$rt,delete this.$te,delete this.$d,delete this.$n,delete this.$tm,a.__disposer&&(a.__disposer(),delete a.__disposer,delete a.__extender),s.__deleteInstance(n),delete this.$i18n}}}function un(e,t){e.locale=t.locale||e.locale,e.fallbackLocale=t.fallbackLocale||e.fallbackLocale,e.missing=t.missing||e.missing,e.silentTranslationWarn=t.silentTranslationWarn||e.silentFallbackWarn,e.silentFallbackWarn=t.silentFallbackWarn||e.silentFallbackWarn,e.formatFallbackMessages=t.formatFallbackMessages||e.formatFallbackMessages,e.postTranslation=t.postTranslation||e.postTranslation,e.warnHtmlInMessage=t.warnHtmlInMessage||e.warnHtmlInMessage,e.escapeParameterHtml=t.escapeParameterHtml||e.escapeParameterHtml,e.sync=t.sync||e.sync,e.__composer[Po](t.pluralizationRules||e.pluralizationRules);const s=Sa(e.locale,{messages:t.messages,__i18n:t.__i18n});return Object.keys(s).forEach(n=>e.mergeLocaleMessage(n,s[n])),t.datetimeFormats&&Object.keys(t.datetimeFormats).forEach(n=>e.mergeDateTimeFormat(n,t.datetimeFormats[n])),t.numberFormats&&Object.keys(t.numberFormats).forEach(n=>e.mergeNumberFormat(n,t.numberFormats[n])),e}const Ma={tag:{type:[String,Object]},locale:{type:String},scope:{type:String,validator:e=>e==="parent"||e==="global",default:"parent"},i18n:{type:Object}};function kl({slots:e},t){return t.length===1&&t[0]==="default"?(e.default?e.default():[]).reduce((n,a)=>[...n,...a.type===Me?a.children:[a]],[]):t.reduce((s,n)=>{const a=e[n];return a&&(s[n]=a()),s},He())}function Ro(){return Me}const wl=$e({name:"i18n-t",props:Ye({keypath:{type:String,required:!0},plural:{type:[Number,String],validator:e=>Ke(e)||!isNaN(e)}},Ma),setup(e,t){const{slots:s,attrs:n}=t,a=e.i18n||Re({useScope:e.scope,__useComponent:!0});return()=>{const i=Object.keys(s).filter(h=>h[0]!=="_"),c=He();e.locale&&(c.locale=e.locale),e.plural!==void 0&&(c.plural=ye(e.plural)?+e.plural:e.plural);const l=kl(t,i),m=a[sa](e.keypath,l,c),u=Ye(He(),n),f=ye(e.tag)||Ue(e.tag)?e.tag:Ro();return Zn(f,u,m)}}}),mn=wl;function Sl(e){return je(e)&&!ye(e[0])}function No(e,t,s,n){const{slots:a,attrs:i}=t;return()=>{const c={part:!0};let l=He();e.locale&&(c.locale=e.locale),ye(e.format)?c.key=e.format:Ue(e.format)&&(ye(e.format.key)&&(c.key=e.format.key),l=Object.keys(e.format).reduce((x,S)=>s.includes(S)?Ye(He(),x,{[S]:e.format[S]}):x,He()));const m=n(e.value,c,l);let u=[c.key];je(m)?u=m.map((x,S)=>{const C=a[x.type],D=C?C({[x.type]:x.value,index:S,parts:m}):[x.value];return Sl(D)&&(D[0].key=`${x.type}-${S}`),D}):ye(m)&&(u=[m]);const f=Ye(He(),i),h=ye(e.tag)||Ue(e.tag)?e.tag:Ro();return Zn(h,f,u)}}const Cl=$e({name:"i18n-n",props:Ye({value:{type:Number,required:!0},format:{type:[String,Object]}},Ma),setup(e,t){const s=e.i18n||Re({useScope:e.scope,__useComponent:!0});return No(e,t,To,(...n)=>s[na](...n))}}),gn=Cl;function Ml(e,t){const s=e;if(e.mode==="composition")return s.__getInstance(t)||e.global;{const n=s.__getInstance(t);return n!=null?n.__composer:e.global.__composer}}function Al(e){const t=c=>{const{instance:l,value:m}=c;if(!l||!l.$)throw ct(it.UNEXPECTED_ERROR);const u=Ml(e,l.$),f=pn(m);return[Reflect.apply(u.t,u,[...fn(f)]),u]};return{created:(c,l)=>{const[m,u]=t(l);ws&&e.global===u&&(c.__i18nWatcher=Ne(u.locale,()=>{l.instance&&l.instance.$forceUpdate()})),c.__composer=u,c.textContent=m},unmounted:c=>{ws&&c.__i18nWatcher&&(c.__i18nWatcher(),c.__i18nWatcher=void 0,delete c.__i18nWatcher),c.__composer&&(c.__composer=void 0,delete c.__composer)},beforeUpdate:(c,{value:l})=>{if(c.__composer){const m=c.__composer,u=pn(l);c.textContent=Reflect.apply(m.t,m,[...fn(u)])}},getSSRProps:c=>{const[l]=t(c);return{textContent:l}}}}function pn(e){if(ye(e))return{path:e};if(De(e)){if(!("path"in e))throw ct(it.REQUIRED_VALUE,"path");return e}else throw ct(it.INVALID_VALUE)}function fn(e){const{path:t,locale:s,args:n,choice:a,plural:i}=e,c={},l=n||{};return ye(s)&&(c.locale=s),Ke(a)&&(c.plural=a),Ke(i)&&(c.plural=i),[t,l,c]}function Tl(e,t,...s){const n=De(s[0])?s[0]:{};(!Fe(n.globalInstall)||n.globalInstall)&&([mn.name,"I18nT"].forEach(i=>e.component(i,mn)),[gn.name,"I18nN"].forEach(i=>e.component(i,gn)),[vn.name,"I18nD"].forEach(i=>e.component(i,vn))),e.directive("t",Al(t))}const $l=Mt("global-vue-i18n");function Il(e={}){const t=__VUE_I18N_LEGACY_API__&&Fe(e.legacy)?e.legacy:__VUE_I18N_LEGACY_API__,s=Fe(e.globalInjection)?e.globalInjection:!0,n=new Map,[a,i]=Pl(e,t),c=Mt("");function l(h){return n.get(h)||null}function m(h,x){n.set(h,x)}function u(h){n.delete(h)}const f={get mode(){return __VUE_I18N_LEGACY_API__&&t?"legacy":"composition"},async install(h,...x){if(h.__VUE_I18N_SYMBOL__=c,h.provide(h.__VUE_I18N_SYMBOL__,f),De(x[0])){const D=x[0];f.__composerExtend=D.__composerExtend,f.__vueI18nExtend=D.__vueI18nExtend}let S=null;!t&&s&&(S=Ol(h,f.global)),__VUE_I18N_FULL_INSTALL__&&Tl(h,f,...x),__VUE_I18N_LEGACY_API__&&t&&h.mixin(xl(i,i.__composer,f));const C=h.unmount;h.unmount=()=>{S&&S(),f.dispose(),C()}},get global(){return i},dispose(){a.stop()},__instances:n,__getInstance:l,__setInstance:m,__deleteInstance:u};return f}function Re(e={}){const t=os();if(t==null)throw ct(it.MUST_BE_CALL_SETUP_TOP);if(!t.isCE&&t.appContext.app!=null&&!t.appContext.app.__VUE_I18N_SYMBOL__)throw ct(it.NOT_INSTALLED);const s=Dl(t),n=El(s),a=Lo(t),i=Ll(e,a);if(i==="global")return Eo(n,e,a),n;if(i==="parent"){let m=Rl(s,t,e.__useComponent);return m==null&&(m=n),m}const c=s;let l=c.__getInstance(t);if(l==null){const m=Ye({},e);"__i18n"in a&&(m.__i18n=a.__i18n),n&&(m.__root=n),l=Ca(m),c.__composerExtend&&(l[oa]=c.__composerExtend(l)),Fl(c,t,l),c.__setInstance(t,l)}return l}function Pl(e,t){const s=pa(),n=__VUE_I18N_LEGACY_API__&&t?s.run(()=>ra(e)):s.run(()=>Ca(e));if(n==null)throw ct(it.UNEXPECTED_ERROR);return[s,n]}function Dl(e){const t=ma(e.isCE?$l:e.appContext.app.__VUE_I18N_SYMBOL__);if(!t)throw ct(e.isCE?it.NOT_INSTALLED_WITH_PROVIDE:it.UNEXPECTED_ERROR);return t}function Ll(e,t){return As(e)?"__i18n"in t?"local":"global":e.useScope?e.useScope:"local"}function El(e){return e.mode==="composition"?e.global:e.global.__composer}function Rl(e,t,s=!1){let n=null;const a=t.root;let i=Nl(t,s);for(;i!=null;){const c=e;if(e.mode==="composition")n=c.__getInstance(i);else if(__VUE_I18N_LEGACY_API__){const l=c.__getInstance(i);l!=null&&(n=l.__composer,s&&n&&!n[Do]&&(n=null))}if(n!=null||a===i)break;i=i.parent}return n}function Nl(e,t=!1){return e==null?null:t&&e.vnode.ctx||e.parent}function Fl(e,t,s){Qe(()=>{},t),qt(()=>{const n=s;e.__deleteInstance(t);const a=n[oa];a&&(a(),delete n[oa])},t)}const Ul=["locale","fallbackLocale","availableLocales"],hn=["t","rt","d","n","tm","te"];function Ol(e,t){const s=Object.create(null);return Ul.forEach(a=>{const i=Object.getOwnPropertyDescriptor(t,a);if(!i)throw ct(it.UNEXPECTED_ERROR);const c=Je(i.value)?{get(){return i.value.value},set(l){i.value.value=l}}:{get(){return i.get&&i.get()}};Object.defineProperty(s,a,c)}),e.config.globalProperties.$i18n=s,hn.forEach(a=>{const i=Object.getOwnPropertyDescriptor(t,a);if(!i||!i.value)throw ct(it.UNEXPECTED_ERROR);Object.defineProperty(e.config.globalProperties,`$${a}`,i)}),()=>{delete e.config.globalProperties.$i18n,hn.forEach(a=>{delete e.config.globalProperties[`$${a}`]})}}const Hl=$e({name:"i18n-d",props:Ye({value:{type:[Number,Date],required:!0},format:{type:[String,Object]}},Ma),setup(e,t){const s=e.i18n||Re({useScope:e.scope,__useComponent:!0});return No(e,t,Ao,(...n)=>s[aa](...n))}}),vn=Hl;vl();Xi(Ii);Yi(qi);Qi(xo);if(__INTLIFY_PROD_DEVTOOLS__){const e=Lt();e.__INTLIFY__=!0,Pi(e.__INTLIFY_DEVTOOLS_GLOBAL_HOOK__)}const Vl={class:"title-bar"},zl={key:0,class:"traffic-light-spacer"},Bl={key:1,class:"window-controls"},Wl={key:0,width:"10",height:"10",viewBox:"0 0 10 10"},jl={key:1,width:"10",height:"10",viewBox:"0 0 10 10"},ql=$e({__name:"TitleBar",setup(e){const t=P(!1),s=P(!1),n=P(!1);Qe(()=>{t.value=navigator.platform.toLowerCase().includes("mac"),n.value=navigator.platform.toLowerCase().includes("win"),window.electron?.ipcRenderer?.on("windowState",(l,m)=>{s.value=m})});function a(){window.electron?.ipcRenderer?.send("window-min")}function i(){window.electron?.ipcRenderer?.send("window-maxOrRestore")}function c(){window.electron?.ipcRenderer?.send("window-close")}return(l,m)=>(b(),A("div",Vl,[t.value?(b(),A("div",zl)):ne("",!0),m[4]||(m[4]=r("div",{class:"drag-region"},null,-1)),!t.value&&!n.value?(b(),A("div",Bl,[r("button",{class:"control-btn",onClick:a},[...m[0]||(m[0]=[r("svg",{width:"10",height:"1",viewBox:"0 0 10 1"},[r("path",{d:"M0 0h10v1H0z",fill:"currentColor"})],-1)])]),r("button",{class:"control-btn",onClick:i},[s.value?(b(),A("svg",jl,[...m[2]||(m[2]=[r("path",{d:"M2 0v2H0v8h8V8h2V0H2zm1 3h5v5H1V3h2z",fill:"currentColor"},null,-1)])])):(b(),A("svg",Wl,[...m[1]||(m[1]=[r("path",{d:"M0 0v10h10V0H0zm1 1h8v8H1V1z",fill:"currentColor"},null,-1)])]))]),r("button",{class:"control-btn control-btn-close",onClick:c},[...m[3]||(m[3]=[r("svg",{width:"10",height:"10",viewBox:"0 0 10 10"},[r("path",{d:"M1.41 0L0 1.41 3.59 5 0 8.59 1.41 10 5 6.41 8.59 10 10 8.59 6.41 5 10 1.41 8.59 0 5 3.59z",fill:"currentColor"})],-1)])])])):ne("",!0)]))}}),Gt=(e,t)=>{const s=e.__vccOpts||e;for(const[n,a]of t)s[n]=a;return s},Kl=Gt(ql,[["__scopeId","data-v-62e80ad9"]]),$t=wt("layout",()=>{const e=P(!1),t=P(!1),s=P(null),n=P(!1),a=P(null),i=P(!1),c=P(!1),l=P("header"),m=P(!1),u=P(!1),f=P(!1),h=P("settings"),x=P(null);function S(){e.value=!e.value}function C(N){s.value=N,t.value=!0}function D(){t.value=!1,setTimeout(()=>{s.value=null},300)}function M(N){a.value=N,n.value=!0}function g(){n.value=!1,setTimeout(()=>{a.value=null},300)}function p(){i.value=!i.value}function k(){m.value=!m.value}function T(N,ee){h.value=N||"settings",x.value=ee||null,f.value=!0}function E(){f.value=!1}function I(){c.value=!c.value,c.value&&(i.value=!1)}return{isSidebarCollapsed:e,isToolsPanelLocked:i,isToolsPanelMini:c,toolsPanelPosition:l,isToolsPanelOpen:m,showScreenCaptureModal:t,screenCaptureImage:s,showChatRecordDrawer:n,chatRecordQuery:a,screenshotMobileAdapt:u,showSettings:f,settingsTab:h,settingsSubTab:x,toggleSidebar:S,toggleToolsPanelLock:p,toggleToolsPanelOpen:k,toggleToolsPanelMini:I,openScreenCaptureModal:C,closeScreenCaptureModal:D,openChatRecordDrawer:M,closeChatRecordDrawer:g,openSettings:T,closeSettings:E}},{persist:[{pick:["isSidebarCollapsed"],storage:sessionStorage},{pick:["screenshotMobileAdapt","isToolsPanelLocked","isToolsPanelMini","toolsPanelPosition"],storage:localStorage}]}),Gl={key:0,class:"truncate text-xs font-medium"},Fo=$e({__name:"SidebarButton",props:{icon:{},title:{},active:{type:Boolean,default:!1},tooltip:{default:""}},setup(e){const t=$t(),{isSidebarCollapsed:s}=Ge(t);return(n,a)=>{const i=Ve,c=We,l=ls;return b(),xe(l,{text:o(s)?e.tooltip||e.title:"",popper:{placement:"right"}},{default:re(()=>[v(c,{block:!o(s),class:we(["transition-all duration-200 rounded-xl hover:bg-gray-200/40 dark:hover:bg-gray-800/40 h-10 cursor-pointer",[o(s)?"flex w-10 items-center justify-center px-0 mx-auto":"justify-start pl-1.5",e.active?"bg-gray-200/50 dark:bg-gray-800/80 text-gray-900 dark:text-white font-medium":"text-gray-600 dark:text-gray-300"]]),color:"gray",variant:"ghost"},{default:re(()=>[v(i,{name:e.icon,class:we(["h-5 w-5 shrink-0",[o(s)?"":"mr-2.5"]])},null,8,["name","class"]),o(s)?ne("",!0):(b(),A("span",Gl,d(e.title),1))]),_:1},8,["block","class"])]),_:1},8,["text"])}}}),Xl=$e({__name:"SidebarFooter",setup(e){const{t}=Re(),s=$t(),{showSettings:n,isSidebarCollapsed:a}=Ge(s);return(i,c)=>(b(),A("div",{class:we(["py-2 dark:border-gray-800 space-y-2 mb-2",[o(a)?"px-3":"px-4"]])},[v(Fo,{icon:"i-heroicons-cog-6-tooth",title:o(t)("layout.footer.settings"),active:o(n),tooltip:o(t)("layout.footer.settings"),onClick:c[0]||(c[0]=l=>o(s).openSettings())},null,8,["title","active","tooltip"])],2))}}),Wt=!1;function Yl(){return"web-serve"}const Uo=new Map;let yn=!1;function nt(e,t){Uo.set(e,t)}function Nt(e){const t=Uo.get(e);if(!t)throw new Error(`[services] Adapter "${e}" not registered. Call initServices() first.`);return t}async function Ql(){if(yn)return;switch(Yl()){case"electron":await Jl();break;case"web-serve":await Zl();break;case"web-browser":await ac();break}yn=!0}async function Jl(){const{ElectronDataAdapter:e}=await Ee(async()=>{const{ElectronDataAdapter:l}=await import("./electron-DfpXsXsS.js");return{ElectronDataAdapter:l}},[]);nt("data",new e);const{ElectronImportAdapter:t}=await Ee(async()=>{const{ElectronImportAdapter:l}=await import("./electron-2m4Vdk2z.js");return{ElectronImportAdapter:l}},[]);nt("import",new t);const{ElectronSessionIndexAdapter:s}=await Ee(async()=>{const{ElectronSessionIndexAdapter:l}=await import("./electron-CsUM2O_Y.js");return{ElectronSessionIndexAdapter:l}},[]);nt("session-index",new s);const{ElectronMessageAdapter:n}=await Ee(async()=>{const{ElectronMessageAdapter:l}=await import("./electron-HoVzpIVc.js");return{ElectronMessageAdapter:l}},[]);nt("message",new n);const{ElectronPlatformAdapter:a}=await Ee(async()=>{const{ElectronPlatformAdapter:l}=await import("./electron-CRSL7qPM.js");return{ElectronPlatformAdapter:l}},[]);nt("platform",new a);const{ElectronAIAdapter:i}=await Ee(async()=>{const{ElectronAIAdapter:l}=await import("./electron-8qi0d92j.js");return{ElectronAIAdapter:l}},[]);nt("ai",new i);const{ElectronPreferencesAdapter:c}=await Ee(async()=>{const{ElectronPreferencesAdapter:l}=await import("./electron-DPsrYwTt.js");return{ElectronPreferencesAdapter:l}},[]);nt("preferences",new c)}async function Zl(){const{FetchDataAdapter:e}=await Ee(async()=>{const{FetchDataAdapter:l}=await import("./fetch-BS4SlQjA.js");return{FetchDataAdapter:l}},__vite__mapDeps([0,1]));nt("data",new e);const{FetchImportAdapter:t}=await Ee(async()=>{const{FetchImportAdapter:l}=await import("./fetch-o5NJ2uWE.js");return{FetchImportAdapter:l}},__vite__mapDeps([2,1]));nt("import",new t);const{FetchSessionIndexAdapter:s}=await Ee(async()=>{const{FetchSessionIndexAdapter:l}=await import("./fetch-BOogCPfg.js");return{FetchSessionIndexAdapter:l}},__vite__mapDeps([3,4,5,6]));nt("session-index",new s);const{FetchMessageAdapter:n}=await Ee(async()=>{const{FetchMessageAdapter:l}=await import("./fetch-CxwnEEqk.js");return{FetchMessageAdapter:l}},__vite__mapDeps([7,4,5,6]));nt("message",new n);const{WebPlatformAdapter:a}=await Ee(async()=>{const{WebPlatformAdapter:l}=await import("./web-Cx5APyCN.js");return{WebPlatformAdapter:l}},[]);nt("platform",new a);const{FetchAIAdapter:i}=await Ee(async()=>{const{FetchAIAdapter:l}=await import("./fetch-CclRWOHf.js");return{FetchAIAdapter:l}},__vite__mapDeps([8,1]));nt("ai",new i);const{FetchPreferencesAdapter:c}=await Ee(async()=>{const{FetchPreferencesAdapter:l}=await import("./fetch-W43zfemj.js");return{FetchPreferencesAdapter:l}},__vite__mapDeps([9,1]));nt("preferences",new c),await ec(),await tc(),await sc()}async function ec(){const{useDataService:e}=await Ee(async()=>{const{useDataService:n}=await Promise.resolve().then(()=>nc);return{useDataService:n}},void 0);window.chatApi||(window.chatApi={});const t=window.chatApi,s=e();t.pluginQuery=(n,a,i)=>s.pluginQuery(n,a,i),t.pluginCompute=(n,a)=>{const i=new Function("return "+n)();return Promise.resolve(i(a))},t.getMemberActivity=(n,a)=>s.getMemberActivity(n,a),t.getAvailableYears=n=>s.getAvailableYears(n)}async function tc(){const{get:e,post:t,del:s}=await Ee(async()=>{const{get:n,post:a,del:i}=await import("./http-CeXMt-Fv.js");return{get:n,post:a,del:i}},[]);window.nlpApi={getWordFrequency:n=>t("/nlp/word-frequency",n),segmentText:(n,a,i)=>t("/nlp/segment",{text:n,locale:a,minLength:i}),getPosTags:()=>e("/nlp/pos-tags"),getDictList:()=>e("/nlp/dicts"),isDictDownloaded:n=>e(`/nlp/dicts/${n}/status`),downloadDict:n=>t(`/nlp/dicts/${n}/download`),deleteDict:n=>s(`/nlp/dicts/${n}`)}}const at={success:!1,error:"Not available in web mode"};async function sc(){const{get:e}=await Ee(async()=>{const{get:l}=await import("./http-CeXMt-Fv.js");return{get:l}},[]);window.assistantApi={getAll:()=>e("/ai/assistants"),getConfig:l=>e(`/ai/assistants/${l}`),getBuiltinToolCatalog:()=>e("/ai/tools/catalog"),getBuiltinCatalog:()=>Promise.resolve([]),importFromMd:()=>Promise.resolve(at),update:()=>Promise.resolve(at),reset:()=>Promise.resolve(at),importAssistant:()=>Promise.resolve(at),reimportAssistant:()=>Promise.resolve(at),create:()=>Promise.resolve(at),delete:()=>Promise.resolve(at)},window.skillApi={getAll:()=>e("/ai/skills"),getConfig:l=>e(`/ai/skills/${l}`),getBuiltinCatalog:()=>Promise.resolve([]),importFromMd:()=>Promise.resolve(at),update:()=>Promise.resolve(at),create:()=>Promise.resolve(at),delete:()=>Promise.resolve(at),importSkill:()=>Promise.resolve(at),reimportSkill:()=>Promise.resolve(at)};let t=null;async function s(){return t||(t=await e("/ai/llm/configs")),t}window.llmApi={hasConfig:()=>e("/ai/llm/has-config"),getAllConfigs:async()=>(await s()).configs,getDefaultAssistantSlot:()=>e("/ai/llm/default-assistant-slot"),getFastModelSlot:()=>e("/ai/llm/fast-model-slot"),getProviders:()=>e("/ai/llm/providers"),getProviderRegistry:()=>e("/ai/llm/provider-registry"),getModelCatalog:()=>e("/ai/llm/model-catalog"),setDefaultAssistantModel:async(l,m)=>{const{put:u}=await Ee(async()=>{const{put:f}=await import("./http-CeXMt-Fv.js");return{put:f}},[]);return t=null,u("/ai/llm/default-assistant-slot",{configId:l,modelId:m})},setFastModel:async l=>{const{put:m}=await Ee(async()=>{const{put:u}=await import("./http-CeXMt-Fv.js");return{put:u}},[]);return t=null,m("/ai/llm/fast-model-slot",l)},deleteConfig:async l=>{if(!l)return at;const{del:m}=await Ee(async()=>{const{del:u}=await import("./http-CeXMt-Fv.js");return{del:u}},[]);return t=null,m(`/ai/llm/configs/${l}`)},addConfig:async l=>{const{post:m}=await Ee(async()=>{const{post:u}=await import("./http-CeXMt-Fv.js");return{post:u}},[]);return t=null,m("/ai/llm/configs",l)},updateConfig:async(l,m)=>{const{put:u}=await Ee(async()=>{const{put:f}=await import("./http-CeXMt-Fv.js");return{put:f}},[]);return t=null,u(`/ai/llm/configs/${l}`,m)},validateApiKey:async(l,m,u,f)=>{const{post:h}=await Ee(async()=>{const{post:x}=await import("./http-CeXMt-Fv.js");return{post:x}},[]);return h("/ai/llm/validate-key",{provider:l,apiKey:m,baseUrl:u,model:f})},fetchRemoteModels:async(l,m,u,f)=>{const{post:h}=await Ee(async()=>{const{post:x}=await import("./http-CeXMt-Fv.js");return{post:x}},[]);return h("/ai/llm/remote-models",{provider:l,apiKey:m,baseUrl:u,apiFormat:f})},chatStream:async(l,m,u)=>{try{const{fetchSSE:f}=await Ee(async()=>{const{fetchSSE:x}=await import("./sse-CACcGGWv.js");return{fetchSSE:x}},[]);let h="";return await f({url:"/_web/ai/llm/chat-stream",method:"POST",body:{messages:l,options:m},onEvent:({data:x})=>{try{const S=JSON.parse(x);S.error&&(h=S.error),u&&u(S)}catch{}}}),h?{success:!1,error:h}:{success:!0}}catch(f){return{success:!1,error:f instanceof Error?f.message:String(f)}}},addCustomModel:async l=>{const{post:m}=await Ee(async()=>{const{post:u}=await import("./http-CeXMt-Fv.js");return{post:u}},[]);return m("/ai/llm/custom-models",l)},updateCustomModel:async(l,m,u)=>{const{put:f}=await Ee(async()=>{const{put:h}=await import("./http-CeXMt-Fv.js");return{put:h}},[]);return f(`/ai/llm/custom-models/${l}/${encodeURIComponent(m)}`,u)},deleteCustomModel:async(l,m)=>{const{del:u}=await Ee(async()=>{const{del:f}=await import("./http-CeXMt-Fv.js");return{del:f}},[]);return u(`/ai/llm/custom-models/${l}/${encodeURIComponent(m)}`)}};const{fetchSSE:n}=await Ee(async()=>{const{fetchSSE:l}=await import("./sse-CACcGGWv.js");return{fetchSSE:l}},[]),{post:a}=await Ee(async()=>{const{post:l}=await import("./http-CeXMt-Fv.js");return{post:l}},[]),i={runStream:(l,m,u,f,h,x,S,C,D)=>{const M=`agent_${Date.now()}_${Math.random().toString(36).slice(2,8)}`;let g=M;const p=new AbortController,k=new Promise(T=>{let E="";const I=[];let N=0,ee,V=!1,ie;n({url:"/_web/ai/agent/stream",method:"POST",body:{userMessage:l,conversationId:m.conversationId,sessionId:m.sessionId,chatType:f||"group",locale:h||"zh-CN",assistantId:x,compressionConfig:D,ownerInfo:m.ownerInfo,mentionedMembers:m.mentionedMembers},signal:p.signal,onEvent:({event:Q,data:Y})=>{try{const H=JSON.parse(Y);if(Q==="meta"){g=H.requestId||M;return}switch(u&&u(H),Q){case"content":H.content&&(E+=H.content);break;case"tool_start":H.toolName&&I.push(H.toolName);break;case"tool_result":break;case"status":H.status?.round!==void 0&&(N=H.status.round);break;case"error":V=!0,ie=H.error;break;case"done":H.usage&&(ee=H.usage);break}}catch{}}}).then(()=>{T(V?{success:!1,error:ie}:{success:!0,result:{content:E,toolsUsed:I,toolRounds:N,totalUsage:ee}})}).catch(Q=>{p.signal.aborted?T({success:!1,error:{name:"AbortError",message:"Aborted"}}):T({success:!1,error:{name:"NetworkError",message:Q?.message||String(Q)}})})});return i._abortControllers=i._abortControllers||new Map,i._abortControllers.set(M,{abortController:p,serverRequestId:()=>g}),{requestId:M,promise:k}},abort:async l=>{const m=i._abortControllers,u=m?.get(l);if(u){u.abortController.abort(),m.delete(l);try{await a("/ai/agent/abort",{requestId:u.serverRequestId()})}catch{}}}};window.agentApi=i,window.chatApi||(window.chatApi={});const c=window.chatApi;c.exportSessionsToTempFiles=async l=>{try{const u=await(await fetch("/_web/sessions/export-for-merge",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({sessionIds:l})})).json();return u.success?{success:!0,tempFiles:u.handles.map(f=>f.handle)}:{success:!1,tempFiles:[],error:u.error}}catch(m){return{success:!1,tempFiles:[],error:m instanceof Error?m.message:String(m)}}},c.cleanupTempExportFiles=async l=>{try{for(const m of l)await fetch("/_web/merge/clear",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({handle:m})});return{success:!0}}catch(m){return{success:!1,error:m instanceof Error?m.message:String(m)}}},window.mergeApi={parseFileInfo:async l=>({name:"",format:"",platform:"",messageCount:0,memberCount:0,fileSize:0}),checkConflicts:async l=>{try{return await(await fetch("/_web/merge/conflicts",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({handles:l})})).json()}catch{return{conflicts:[],totalMessages:0}}},mergeFiles:async l=>{try{return await(await fetch("/_web/merge/execute",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({handles:l.filePaths,outputName:l.outputName,format:l.outputFormat||"json",andImport:l.andAnalyze??!1})})).json()}catch(m){return{success:!1,error:m instanceof Error?m.message:String(m)}}},clearCache:async l=>{try{return await fetch("/_web/merge/clear",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({handle:l})}),!0}catch{return!1}}},window.cacheApi={saveToDownloads:async(l,m)=>{try{return await(await fetch("/_web/cache/save-to-downloads",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({filename:l,dataUrl:m})})).json()}catch(u){return{success:!1,error:u instanceof Error?u.message:String(u)}}},showInFolder:async l=>{try{return await(await fetch("/_web/cache/show-in-folder",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({filePath:l})})).json()}catch(m){return{success:!1,error:m instanceof Error?m.message:String(m)}}},getInfo:async()=>{try{return await(await fetch("/_web/cache/info")).json()}catch{return{baseDir:"",directories:[],totalSize:0}}},clear:async l=>{try{return await(await fetch("/_web/cache/clear",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({cacheId:l})})).json()}catch(m){return{success:!1,error:m instanceof Error?m.message:String(m)}}},openDir:async l=>{try{return await(await fetch("/_web/cache/open-dir",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({cacheId:l})})).json()}catch(m){return{success:!1,error:m instanceof Error?m.message:String(m)}}},getLatestImportLog:async()=>{try{return await(await fetch("/_web/cache/latest-import-log")).json()}catch(l){return{success:!1,error:l instanceof Error?l.message:String(l)}}},getDataDir:async()=>{try{return await(await fetch("/_web/cache/data-dir")).json()}catch{return{path:"",isCustom:!1}}}}}async function ac(){throw new Error("[services] web-browser platform not yet supported")}function Et(){return Nt("data")}const nc=Object.freeze(Object.defineProperty({__proto__:null,useDataService:Et},Symbol.toStringTag,{value:"Module"}));function bn(){return Nt("import")}function tt(){return Nt("session-index")}function Ot(){return Nt("message")}function ft(){return Nt("platform")}function Ht(){return Nt("ai")}function oc(){return Nt("preferences")}const jt=P({default_session_tab:"overview",session_gap_threshold:1800,summary_strategy:"standard"});function _n(){return jt.value}function rc(e){jt.value=e}function xn(e){jt.value={...jt.value,...e}}function Rt(){return jt.value.session_gap_threshold}function Aa(){return jt.value.summary_strategy??"standard"}const ut=wt("session",()=>{const e=P([]),t=P(null),s=P(!1),n=P(null),a=P(!1),i=P(!1),c=P([]),l=P(!1),m=P(null),u=P(!1),f=P([]),h=P("parsing"),x=P(null),S=P(null),C=G(()=>t.value&&e.value.find(W=>W.id===t.value)||null),D=P(!1),M=P(0),g=P([]),p=P(!1);async function k(){return{needsMigration:!1,count:0,currentVersion:0,pendingMigrations:[]}}async function T(){p.value=!0;try{const W=await window.chatApi.runMigration();return W.success&&(D.value=!1,M.value=0),W}catch(W){return console.error("执行迁移失败:",W),{success:!1,error:String(W)}}finally{p.value=!1}}async function E(){try{const W=await Et().getSessions();e.value=W,t.value&&!W.find(se=>se.id===t.value)&&(t.value=null),a.value=!0}catch(W){console.error("加载会话列表失败:",W),a.value=!0}}async function I(){try{const W=await ft().showOpenDialog({properties:["openFile"],filters:[{name:"Chat Files",extensions:["json","jsonl","txt"]},{name:"All Files",extensions:["*"]}]});return W.canceled||W.filePaths.length===0?{success:!1,error:"error.no_file_selected"}:await N(W.filePaths[0])}catch(W){return{success:!1,error:String(W)}}}async function N(W){try{s.value=!0,n.value={stage:"detecting",progress:0,message:""};const se=[];let pe=!1,me="reading",ae=Date.now();const he=1e3,ke=async()=>{if(!pe){for(pe=!0;se.length>0;){const be=se[0];if(be.stage!==me){const Le=Date.now()-ae;Le<he&&await new Promise(Ae=>setTimeout(Ae,he-Le)),me=be.stage,ae=Date.now()}n.value=se.shift()}pe=!1}},ve=await bn().importFile(W,void 0,be=>{be.stage!=="done"&&(se.push(be),ke())});for(;se.length>0||pe;)await new Promise(be=>setTimeout(be,100));const _e=Date.now()-ae;if(_e<he&&await new Promise(be=>setTimeout(be,he-_e)),n.value&&(n.value.progress=100),await new Promise(be=>setTimeout(be,300)),ve.success&&ve.sessionId){await E(),t.value=ve.sessionId;try{await tt().generate(ve.sessionId,Rt())}catch(be){console.error("自动生成会话索引失败:",be)}return{success:!0,diagnostics:ve.diagnostics}}else return{success:!1,error:ve.error||"error.import_failed",diagnostics:ve.diagnostics}}catch(se){return{success:!1,error:String(se)}}finally{s.value=!1,setTimeout(()=>{n.value=null},500)}}async function ee(W){if(W.length===0)return{total:0,success:0,failed:0,cancelled:0,files:[]};i.value=!0,l.value=!1,m.value=null,c.value=W.map(ke=>({path:ke,name:ke.split("/").pop()||ke.split("\\").pop()||ke,status:"pending"}));let se=0,pe=0,me=0;const ae=ke=>{for(let ve=ke;ve<c.value.length;ve++)c.value[ve].status==="pending"&&(c.value[ve].status="cancelled",me++)};for(let ke=0;ke<c.value.length;ke++){if(l.value){ae(ke);break}const ve=c.value[ke];ve.status="importing",ve.progress={stage:"detecting",progress:0,message:""};try{const _e=[];let be=!1,Le="reading",Ae=Date.now();const de=300,w=async()=>{if(!be){for(be=!0;_e.length>0;){if(l.value){_e.length=0;break}const te=_e[0];if(te.stage!==Le){const q=Date.now()-Ae;q<de&&await new Promise(ue=>setTimeout(ue,de-q)),Le=te.stage,Ae=Date.now()}ve.progress=_e.shift()}be=!1}},R=await bn().importFile(ve.path,void 0,te=>{te.stage!=="done"&&(_e.push(te),w())});let oe=0;for(;(_e.length>0||be)&&!l.value&&oe<100;)await new Promise(te=>setTimeout(te,30)),oe++;if(l.value){if(R.success&&R.sessionId){ve.status="success",ve.sessionId=R.sessionId,se++;try{await tt().generate(R.sessionId,Rt())}catch(te){console.error("自动生成会话索引失败:",te)}}else ve.status="failed",ve.error=R.error||"error.import_failed",pe++;ae(ke+1);break}if(R.success&&R.sessionId){if(ve.status="success",ve.sessionId=R.sessionId,se++,!l.value)try{await tt().generate(R.sessionId,Rt())}catch(te){console.error("自动生成会话索引失败:",te)}}else ve.status="failed",ve.error=R.error||"error.import_failed",pe++}catch(_e){ve.status="failed",ve.error=String(_e),pe++}}await E();const he={total:W.length,success:se,failed:pe,cancelled:me,files:[...c.value]};return m.value=he,i.value=!1,he}function V(){l.value=!0}function ie(){m.value=null,c.value=[]}async function Q(W){if(W.length<2)return{success:!1,error:"合并导入至少需要2个文件"};const se=800;u.value=!0,x.value=null,S.value=null,h.value="parsing",f.value=W.map(me=>({path:me,name:me.split("/").pop()||me.split("\\").pop()||me,status:"pending"}));let pe=Date.now();try{for(let be=0;be<f.value.length;be++){const Le=f.value[be],Ae=Date.now();Le.status="parsing";try{const de=await window.mergeApi.parseFileInfo(Le.path);Le.info=de;const w=Date.now()-Ae,R=Math.max(300,se/W.length);w<R&&await new Promise(oe=>setTimeout(oe,R-w)),Le.status="done"}catch(de){throw new Error(`解析文件失败: ${Le.name} - ${de instanceof Error?de.message:String(de)}`)}}const me=Date.now()-pe;me<se&&await new Promise(be=>setTimeout(be,se-me)),pe=Date.now(),h.value="merging";const ae=f.value.map(be=>be.info?.name).filter(Boolean),he=[...new Set(ae)],ke=he.length===1?he[0]:ae[0]||"合并记录",ve=await window.mergeApi.mergeFiles({filePaths:W,outputName:ke,conflictResolutions:[],andAnalyze:!0});if(!ve.success)throw new Error(ve.error||"合并失败");await window.mergeApi.clearCache();const _e=Date.now()-pe;if(_e<se&&await new Promise(be=>setTimeout(be,se-_e)),h.value="done",S.value={success:!0,sessionId:ve.sessionId},await E(),ve.sessionId)try{await tt().generate(ve.sessionId,Rt())}catch(be){console.error("自动生成会话索引失败:",be)}return{success:!0,sessionId:ve.sessionId}}catch(me){h.value="error";const ae=me instanceof Error?me.message:String(me);return x.value=ae,S.value={success:!1,error:ae},await window.mergeApi.clearCache(),{success:!1,error:ae}}}function Y(){u.value=!1,f.value=[],S.value=null,x.value=null}function H(W){t.value=W}async function B(W){try{const se=await Et().deleteSession(W);if(se){const pe=e.value.findIndex(me=>me.id===W);pe!==-1&&e.value.splice(pe,1),t.value===W&&(t.value=null),await E()}return se}catch(se){return console.error("删除会话失败:",se),!1}}async function j(W,se){try{const pe=await Et().renameSession(W,se);if(pe){const me=e.value.find(ae=>ae.id===W);me&&(me.name=se)}return pe}catch(pe){return console.error("重命名会话失败:",pe),!1}}function X(){t.value=null}async function le(W,se){try{const pe=await Et().updateSessionOwnerId(W,se);if(pe){const me=e.value.find(ae=>ae.id===W);me&&(me.ownerId=se)}return pe}catch(pe){return console.error("更新会话所有者失败:",pe),!1}}const F=P([]),_=P("all"),y=P("importedAt"),L=P("desc"),$=G(()=>{let W=e.value;_.value!=="all"&&(W=W.filter(me=>me.type===_.value));const se=new Map(F.value.map((me,ae)=>[me,ae])),pe=L.value==="desc"?-1:1;return[...W].sort((me,ae)=>{const he=se.get(me.id),ke=se.get(ae.id),ve=he!==void 0,_e=ke!==void 0;if(ve&&_e)return ke-he;if(ve&&!_e)return-1;if(!ve&&_e)return 1;const be=y.value,Le=me[be]??0,Ae=ae[be]??0;return Le!==Ae?(Le-Ae)*pe:0})});function z(W){const se=F.value.indexOf(W);se!==-1?F.value.splice(se,1):F.value.push(W)}function ce(W){return F.value.includes(W)}return{sessions:e,sortedSessions:$,pinnedSessionIds:F,filterType:_,sortField:y,sortOrder:L,currentSessionId:t,isImporting:s,importProgress:n,isInitialized:a,currentSession:C,migrationNeeded:D,migrationCount:M,pendingMigrations:g,isMigrating:p,checkMigration:k,runMigration:T,loadSessions:E,importFile:I,importFileFromPath:N,selectSession:H,deleteSession:B,renameSession:j,clearSelection:X,updateSessionOwnerId:le,togglePinSession:z,isPinned:ce,isBatchImporting:i,batchFiles:c,batchImportCancelled:l,batchImportResult:m,importFilesFromPaths:ee,cancelBatchImport:V,clearBatchImportResult:ie,isMergeImporting:u,mergeFiles:f,mergeStage:h,mergeError:x,mergeResult:S,mergeImportFiles:Q,clearMergeImportResult:Y}},{persist:[{pick:["currentSessionId"],storage:sessionStorage},{pick:["filterType","sortField","sortOrder"],storage:localStorage}],backendPersist:{pick:["pinnedSessionIds"]}}),ic={class:"w-48 p-1.5 flex flex-col space-y-0.5"},lc={class:"px-2 pb-2 pt-1 text-xs font-semibold text-gray-500 dark:text-gray-400"},cc=["onClick"],dc=$e({__name:"SidebarSortPopover",setup(e){const{t}=Re(),s=ut(),{sortField:n,sortOrder:a}=Ge(s),i=P(!1),c=[{value:"importedAt",labelKey:"layout.sort.importedAt"},{value:"lastMessageTs",labelKey:"layout.sort.lastMessageTs"},{value:"messageCount",labelKey:"layout.sort.messageCount"}];function l(m){n.value===m?a.value=a.value==="desc"?"asc":"desc":(n.value=m,a.value="desc"),i.value=!1}return(m,u)=>{const f=We,h=ls,x=Ve,S=so;return b(),xe(S,{open:i.value,"onUpdate:open":u[0]||(u[0]=C=>i.value=C),ui:{content:"z-50 p-0"}},{content:re(()=>[r("div",ic,[r("div",lc,d(o(t)("layout.tooltip.sort")),1),(b(),A(Me,null,Be(c,C=>r("button",{key:C.value,class:we(["flex w-full items-center justify-between rounded-md px-2.5 py-2 text-sm transition-colors",o(n)===C.value?"bg-gray-100 text-gray-900 dark:bg-white/10 dark:text-white font-medium":"text-gray-600 hover:bg-gray-50 dark:text-gray-300 dark:hover:bg-white/5"]),onClick:D=>l(C.value)},[r("span",null,d(o(t)(C.labelKey)),1),o(n)===C.value?(b(),xe(x,{key:0,name:o(a)==="desc"?"i-heroicons-bars-arrow-down":"i-heroicons-bars-arrow-up",class:"h-4 w-4 opacity-70"},null,8,["name"])):ne("",!0)],10,cc)),64))])]),default:re(()=>[v(h,{text:o(t)("layout.tooltip.sort"),popper:{placement:"right"}},{default:re(()=>[v(f,{icon:o(a)==="desc"?"i-heroicons-bars-arrow-down":"i-heroicons-bars-arrow-up",color:"neutral",variant:"ghost",size:"xs"},null,8,["icon"])]),_:1},8,["text"])]),_:1},8,["open"])}}}),uc=["onClick"],Ta=$e({__name:"SubTabs",props:{modelValue:{},items:{},persistKey:{},orientation:{default:"horizontal"},size:{default:"md"},bordered:{type:Boolean}},emits:["update:modelValue","change"],setup(e,{emit:t}){const s=e,n=t,a=Cs(),i=ha(),c=G(()=>s.orientation==="vertical"),l=P({}),m=P(null),u=P({}),f=G({get:()=>s.modelValue,set:C=>{n("update:modelValue",C),n("change",C)}});function h(){const C=l.value[f.value];if(C&&m.value){const D=m.value.getBoundingClientRect(),M=C.getBoundingClientRect();c.value?u.value={top:`${M.top-D.top}px`,height:`${M.height}px`,right:"0px",width:"2px"}:u.value={left:`${M.left-D.left}px`,width:`${M.width}px`,bottom:"0px",height:"2px"}}}const x=C=>{f.value=C};function S(C,D){l.value[C]=D}return Qe(()=>{if(s.persistKey){const C=a.query[s.persistKey];C&&s.items.some(D=>D.id===C)&&(f.value=C)}Xe(()=>{h()})}),Ne(()=>s.modelValue,C=>{s.persistKey&&C&&i.replace({query:{...a.query,[s.persistKey]:C}}),Xe(()=>{h()})}),Ne(()=>s.items,()=>{Xe(()=>{h()})},{deep:!0}),(C,D)=>{const M=Ve;return b(),A("div",{class:we([c.value?["h-full",e.bordered!==!1?"border-r border-gray-200/50 dark:border-gray-700/50":""]:["flex items-center justify-between",e.bordered!==!1?"border-b border-gray-200/50 dark:border-gray-800/50":"",e.size==="sm"?"px-3":"px-6"]])},[r("div",{ref_key:"containerRef",ref:m,class:we(["relative",[c.value?"flex flex-col gap-1":"flex gap-1"]])},[(b(!0),A(Me,null,Be(e.items,g=>(b(),A("button",{key:g.id,ref_for:!0,ref:p=>S(g.id,p),class:we(["flex items-center font-medium transition-colors",[c.value?"justify-start gap-2 px-3 py-2 text-sm":e.size==="sm"?"gap-1.5 px-2 py-1.5 text-xs":"gap-2 px-4 py-3 text-sm",f.value===g.id?"text-primary-600 dark:text-primary-400":"text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-300"]]),onClick:p=>x(g.id)},[g.icon?(b(),xe(M,{key:0,name:g.icon,class:we(e.size==="sm"?"h-3.5 w-3.5":"h-4 w-4")},null,8,["name","class"])):ne("",!0),J(" "+d(g.label),1)],10,uc))),128)),r("div",{class:"absolute bg-primary-500 transition-all duration-300 ease-out",style:Jt(u.value)},null,4)],2),c.value?ne("",!0):ir(C.$slots,"right",{key:0})],2)}}}),kn="/assets/logo-DXIuG_WE.svg",mc={class:"flex flex-col p-4 pt-5"},gc={key:0,class:"ml-2 flex items-center"},pc=["src"],fc={class:"ml-2 text-2xl font-black tracking-tight text-pink-500"},hc={class:"ml-2 text-xs text-gray-400"},vc=["src"],yc={class:"flex-1 relative min-h-0 flex flex-col"},bc={key:0,class:"mb-2"},_c={class:"flex items-center gap-0.5"},xc={key:0,class:"mt-2 px-4"},kc={class:"flex-1 overflow-y-auto"},wc={key:0,class:"py-8 text-center text-sm text-gray-500"},Sc={key:1,class:"py-8 text-center text-sm text-gray-500"},Cc=["onClick"],Mc=["src","alt"],Ac={key:2,class:"min-w-0 flex-1"},Tc={class:"flex items-center justify-between gap-1.5"},$c={class:"truncate text-xs font-medium"},Ic={class:"truncate text-[10px] text-gray-400 dark:text-gray-500 mt-0.5 leading-none"},Pc={class:"p-4"},Dc={class:"mb-3 font-semibold text-gray-900 dark:text-white"},Lc={class:"flex justify-end gap-2"},Ec={class:"p-4"},Rc={class:"mb-3 font-semibold text-gray-900 dark:text-white"},Nc={class:"mb-4 text-sm text-gray-600 dark:text-gray-400"},Fc={class:"flex justify-end gap-2"},Uc=$e({__name:"Sidebar",setup(e){const{t}=Re(),s=ut(),n=$t(),{sessions:a,sortedSessions:i,filterType:c}=Ge(s),{isSidebarCollapsed:l}=Ge(n),{toggleSidebar:m}=n,u=ha(),f=Cs(),h=G(()=>f.path==="/"),x=P(!1),S=P(null),C=P(""),D=P(null),M=P(!1),g=P(null),p=P(""),k=P(!1),T=P(""),E=G(()=>[{id:"all",label:t("layout.filter.all")},{id:"private",label:t("layout.filter.private")},{id:"group",label:t("layout.filter.group")}]),I=G(()=>{if(!T.value.trim())return i.value;const L=T.value.toLowerCase().trim();return i.value.filter($=>$.name.toLowerCase().includes(L))});function N(){k.value=!k.value,k.value||(T.value="")}Qe(async()=>{s.loadSessions();try{p.value=await ft().getVersion()}catch(L){console.error("Failed to get version",L)}}),qt(()=>{});function ee(){u.push("/")}function V(L){S.value=L,C.value=L.name,x.value=!0,Xe(()=>{D.value?.focus(),D.value?.select()})}async function ie(){if(!S.value||!C.value.trim())return;await s.renameSession(S.value.id,C.value.trim())&&(x.value=!1,S.value=null,C.value="")}function Q(){x.value=!1,S.value=null,C.value=""}function Y(L){g.value=L,M.value=!0}async function H(){if(!g.value)return;const L=g.value.id,$=f.params.id===L;await s.deleteSession(L),M.value=!1,g.value=null,$&&u.push("/")}function B(){M.value=!1,g.value=null}function j(L){const $=s.isPinned(L.id);return[[{label:t($?"layout.contextMenu.unpin":"layout.contextMenu.pin"),class:"p-2",onSelect:()=>s.togglePinSession(L.id)},{label:t("layout.contextMenu.rename"),class:"p-2",onSelect:()=>V(L)},{label:t("layout.contextMenu.delete"),color:"error",class:"p-2",onSelect:()=>Y(L)}]]}function X(L){return L.type==="private"?"private-chat":"group-chat"}function le(L){return L.type==="private"}function F(L){const $=L.name||"";return $?le(L)?$.slice(-1):$.slice(0,1):"?"}function _(L){return le(L)?L.memberAvatar||null:L.groupAvatar||null}function y(L,$){if($)return le(L)?"bg-pink-500 text-white dark:bg-pink-600":"bg-primary-600 text-white dark:bg-primary-500";const z=[{bg:"bg-pink-50 dark:bg-pink-950/20",text:"text-pink-600 dark:text-pink-400"},{bg:"bg-blue-50 dark:bg-blue-950/20",text:"text-blue-600 dark:text-blue-400"},{bg:"bg-emerald-50 dark:bg-emerald-950/20",text:"text-emerald-600 dark:text-emerald-400"},{bg:"bg-purple-50 dark:bg-purple-950/20",text:"text-purple-600 dark:text-purple-400"},{bg:"bg-amber-50 dark:bg-amber-950/20",text:"text-amber-600 dark:text-amber-400"}],ce=L.id||"";let W=0;for(let pe=0;pe<ce.length;pe++)W=ce.charCodeAt(pe)+((W<<5)-W);const se=Math.abs(W)%z.length;return`${z[se].bg} ${z[se].text}`}return(L,$)=>{const z=Ve,ce=We,W=ls,se=lt,pe=br,me=ht;return b(),A("div",{class:we(["flex h-full flex-col border-r border-gray-200/50 transition-all duration-300 ease-in-out dark:border-gray-800/50",[o(l)?"w-20":"w-72",h.value?"":"bg-gray-50 dark:bg-gray-900"]])},[r("div",mc,[r("div",{class:we(["mb-2 flex items-center",[o(l)?"justify-center":"justify-between"]]),style:{"-webkit-app-region":"drag"}},[o(l)?(b(),A("div",{key:1,class:"group relative flex h-12 w-12 cursor-pointer items-center justify-center rounded-full hover:bg-gray-200/60 dark:hover:bg-gray-800",style:{"-webkit-app-region":"no-drag"},onClick:$[0]||($[0]=(...ae)=>o(m)&&o(m)(...ae))},[r("img",{src:o(kn),alt:"ChatLab",class:"size-6 select-none pointer-events-none group-hover:hidden"},null,8,vc),v(z,{name:"i-lucide-panel-right-open",class:"size-5 hidden group-hover:block scale-x-[-1]"})])):(b(),A("div",gc,[r("img",{src:o(kn),alt:"ChatLab",class:"h-6 w-6 select-none pointer-events-none"},null,8,pc),r("div",fc,d(o(t)("layout.brand")),1),r("span",hc,"v"+d(p.value),1)])),o(l)?ne("",!0):(b(),xe(W,{key:2,text:o(t)("layout.tooltip.collapse"),popper:{placement:"right"},style:{"-webkit-app-region":"no-drag"}},{default:re(()=>[v(ce,{color:"gray",variant:"ghost",size:"md",class:"group flex h-12 w-12 cursor-pointer items-center justify-center rounded-full hover:bg-gray-200/60 dark:hover:bg-gray-800",onClick:o(m)},{default:re(()=>[v(z,{name:"i-lucide-panel-right",class:"size-5 group-hover:hidden scale-x-[-1]"}),v(z,{name:"i-lucide-panel-right-close",class:"size-5 hidden group-hover:block scale-x-[-1]"})]),_:1},8,["onClick"])]),_:1},8,["text"]))],2),v(Fo,{icon:"i-heroicons-plus",title:o(t)("layout.newAnalysis"),onClick:ee},null,8,["title"])]),r("div",yc,[!o(l)&&o(a).length>0?(b(),A("div",bc,[v(Ta,{modelValue:o(c),"onUpdate:modelValue":$[2]||($[2]=ae=>Je(c)?c.value=ae:null),items:E.value,size:"sm",bordered:!1},{right:re(()=>[r("div",_c,[v(W,{text:o(t)("layout.tooltip.search"),popper:{placement:"right"}},{default:re(()=>[v(ce,{icon:k.value?"i-heroicons-x-mark":"i-heroicons-magnifying-glass",color:"neutral",variant:"ghost",size:"xs",onClick:N},null,8,["icon"])]),_:1},8,["text"]),v(dc),v(W,{text:o(t)("layout.manage"),popper:{placement:"right"}},{default:re(()=>[v(ce,{icon:"i-heroicons-rectangle-stack",color:"neutral",variant:"ghost",size:"xs",onClick:$[1]||($[1]=ae=>o(n).openSettings("data"))})]),_:1},8,["text"])])]),_:1},8,["modelValue","items"]),k.value?(b(),A("div",xc,[v(se,{modelValue:T.value,"onUpdate:modelValue":$[3]||($[3]=ae=>T.value=ae),placeholder:o(t)("layout.searchPlaceholder"),icon:"i-heroicons-magnifying-glass",size:"sm",autofocus:""},null,8,["modelValue","placeholder"])])):ne("",!0)])):ne("",!0),r("div",kc,[o(a).length===0&&!o(l)?(b(),A("div",wc,d(o(t)("layout.noRecords")),1)):I.value.length===0&&T.value.trim()&&!o(l)?(b(),A("div",Sc,d(o(t)("layout.noSearchResult")),1)):ne("",!0),r("div",{class:we(["space-y-1 pb-8",[o(l)?"px-3":"px-4"]])},[(b(!0),A(Me,null,Be(I.value,ae=>(b(),xe(pe,{key:ae.id,items:j(ae)},{default:re(()=>[v(W,{text:ae.name,disabled:!o(l)||!ae.name,popper:{placement:"right"}},{default:re(()=>[r("div",{class:we(["group relative flex items-center text-left transition-all duration-200 cursor-pointer",[o(f).params.id===ae.id?"bg-gray-200/50 dark:bg-gray-800/80 text-gray-900 dark:text-white font-medium":"text-gray-600 dark:text-gray-300 hover:bg-gray-200/30 dark:hover:bg-gray-800/30",o(l)?"justify-center h-10 w-10 rounded-xl mx-auto":"w-full rounded-xl p-1.5 px-2.5 pl-1.5"]]),onClick:he=>o(u).push({name:X(ae),params:{id:ae.id},query:o(f).query})},[r("div",{class:we(["absolute top-1/2 -translate-y-1/2 w-[3px] rounded-r-full bg-pink-500 dark:bg-pink-400 transition-all duration-200",[o(l)?"-left-3":"-left-4",o(f).params.id===ae.id?"h-4.5 opacity-100":"h-0 opacity-0 group-hover:h-2.5 group-hover:opacity-40"]])},null,2),_(ae)?(b(),A("img",{key:0,src:_(ae),alt:ae.name,class:we(["h-7 w-7 min-w-7 shrink-0 rounded-lg object-cover",[o(l)?"":"mr-2.5"]])},null,10,Mc)):(b(),A("div",{key:1,class:we(["flex h-7 w-7 shrink-0 items-center justify-center rounded-lg text-xs font-semibold select-none",[y(ae,o(f).params.id===ae.id),o(l)?"":"mr-2.5"]])},d(F(ae)),3)),o(l)?ne("",!0):(b(),A("div",Ac,[r("div",Tc,[r("p",$c,d(ae.name),1),o(s).isPinned(ae.id)?(b(),xe(z,{key:0,name:"i-lucide-pin",class:"h-3 w-3 shrink-0 text-gray-400/80 rotate-45"})):ne("",!0)]),r("p",Ic,d(o(t)("layout.sessionInfo",{count:ae.messageCount})),1)]))],10,Cc)]),_:2},1032,["text","disabled"])]),_:2},1032,["items"]))),128))],2)]),$[7]||($[7]=r("div",{class:"pointer-events-none absolute bottom-0 left-0 right-0 h-12 bg-gradient-to-t from-gray-50 to-transparent dark:from-gray-900"},null,-1))]),v(me,{open:x.value,"onUpdate:open":$[5]||($[5]=ae=>x.value=ae),ui:{content:"z-50"}},{content:re(()=>[r("div",Pc,[r("h3",Dc,d(o(t)("layout.renameModal.title")),1),v(se,{ref_key:"renameInputRef",ref:D,modelValue:C.value,"onUpdate:modelValue":$[4]||($[4]=ae=>C.value=ae),placeholder:o(t)("layout.renameModal.placeholder"),class:"mb-4 w-100",onKeydown:Zt(ie,["enter"])},null,8,["modelValue","placeholder"]),r("div",Lc,[v(ce,{variant:"soft",onClick:Q},{default:re(()=>[J(d(o(t)("common.cancel")),1)]),_:1}),v(ce,{color:"primary",disabled:!C.value.trim(),onClick:ie},{default:re(()=>[J(d(o(t)("common.confirm")),1)]),_:1},8,["disabled"])])])]),_:1},8,["open"]),v(me,{open:M.value,"onUpdate:open":$[6]||($[6]=ae=>M.value=ae),ui:{content:"z-50"}},{content:re(()=>[r("div",Ec,[r("h3",Rc,d(o(t)("layout.deleteModal.title")),1),r("p",Nc,d(o(t)("layout.deleteModal.message",{name:g.value?.name})),1),r("div",Fc,[v(ce,{variant:"soft",onClick:B},{default:re(()=>[J(d(o(t)("common.cancel")),1)]),_:1}),v(ce,{color:"error",onClick:H},{default:re(()=>[J(d(o(t)("common.delete")),1)]),_:1})])])]),_:1},8,["open"]),v(Xl)],2)}}}),Oc={class:"flex flex-col"},Hc={class:"flex items-center justify-between border-b border-gray-200 px-6 py-4 dark:border-gray-700"},Vc={class:"flex items-center gap-3"},zc={class:"flex h-10 w-10 items-center justify-center rounded-xl bg-gradient-to-br from-pink-400 to-pink-600"},Bc={class:"bg-gray-100 p-4 dark:bg-gray-800"},Wc={class:"mx-auto max-h-[60vh] overflow-auto rounded-lg bg-white shadow-lg dark:bg-gray-900"},jc=["src"],qc=$e({__name:"ScreenCaptureModal",props:{open:{type:Boolean},imageData:{}},emits:["update:open"],setup(e,{emit:t}){const s=e,n=t,a=G({get:()=>s.open,set:c=>n("update:open",c)});function i(){a.value=!1}return(c,l)=>{const m=Ve,u=We,f=ht;return b(),xe(f,{open:a.value,"onUpdate:open":l[0]||(l[0]=h=>a.value=h),ui:{content:"max-w-4xl z-100"}},{content:re(()=>[r("div",Oc,[r("div",Hc,[r("div",Vc,[r("div",zc,[v(m,{name:"i-heroicons-camera",class:"h-5 w-5 text-white"})]),l[1]||(l[1]=r("div",null,[r("h2",{class:"text-lg font-semibold text-gray-900 dark:text-white"},"截图预览")],-1))]),v(u,{icon:"i-heroicons-x-mark",variant:"ghost",color:"neutral",size:"sm",onClick:i})]),r("div",Bc,[r("div",Wc,[e.imageData?(b(),A("img",{key:0,src:e.imageData,alt:"截图预览",class:"block w-full"},null,8,jc)):ne("",!0)])])])]),_:1},8,["open"])}}}),Is=wt("llm",()=>{const e=P([]),t=P([]),s=P(null),n=P(null),a=P(!1),i=P(!1),c=P([]),l=P([]),m=G(()=>e.value.find(I=>I.id===s.value?.configId)||null),u=G(()=>e.value.find(I=>I.id===n.value?.configId)||null),f=G(()=>!!s.value),h=G(()=>e.value.length>=99);function x(I){return c.value.find(N=>N.id===I)}function S(I){return l.value.filter(N=>N.providerId===I)}function C(I,N){return l.value.find(ee=>ee.providerId===I&&ee.id===N)}function D(I){return l.value.find(N=>N.id===I)}async function M(){i.value||(await g(),i.value=!0)}async function g(){a.value=!0;try{const[I,N,ee,V,ie,Q]=await Promise.all([window.llmApi.getProviders(),window.llmApi.getProviderRegistry(),window.llmApi.getModelCatalog(),window.llmApi.getAllConfigs(),window.llmApi.getDefaultAssistantSlot(),window.llmApi.getFastModelSlot()]);t.value=I,c.value=N,l.value=ee,e.value=V,s.value=ie,n.value=Q}catch(I){console.error("[LLM Store] 加载配置失败:",I)}finally{a.value=!1}}async function p(I,N){try{const ee=await window.llmApi.setDefaultAssistantModel(I,N);return ee.success?(s.value={configId:I,modelId:N},!0):(console.error("[LLM Store] 设置默认助手模型失败:",ee.error),!1)}catch(ee){return console.error("[LLM Store] 设置默认助手模型失败:",ee),!1}}async function k(I){try{const N=await window.llmApi.setFastModel(I);return N.success?(n.value=I,!0):(console.error("[LLM Store] 设置快速模型失败:",N.error),!1)}catch(N){return console.error("[LLM Store] 设置快速模型失败:",N),!1}}async function T(){await g()}function E(I){const N=c.value.find(ee=>ee.id===I);return N?N.name:t.value.find(ee=>ee.id===I)?.name||I}return{configs:e,providers:t,providerRegistry:c,modelCatalog:l,defaultAssistant:s,fastModel:n,isLoading:a,isInitialized:i,defaultAssistantConfig:m,fastModelConfig:u,hasConfig:f,isMaxConfigs:h,init:M,loadConfigs:g,setDefaultAssistantModel:p,setFastModel:k,refreshConfigs:T,getProviderName:E,getProviderById:x,getModelsByProviderId:S,getModelById:C,findModelAcrossProviders:D}}),Kc=$e({__name:"Tabs",props:{modelValue:{},items:{},size:{}},emits:["update:modelValue"],setup(e,{emit:t}){const s=e,n=t,a=P(),i=P(),c=G({get:()=>s.modelValue,set:m=>n("update:modelValue",m)}),l=async()=>{if(await Xe(),!a.value||!i.value)return;const m=s.items.findIndex(g=>g.value===c.value);if(m<0)return;const h=i.value.$el.querySelectorAll('[role="tab"]')[m];if(!h)return;const x=a.value,S=x.clientWidth,C=h.offsetLeft,D=h.offsetWidth,M=C+D/2-S/2;x.scrollTo({left:Math.max(0,M),behavior:"smooth"})};return Ne(c,()=>{l()},{immediate:!1}),(m,u)=>{const f=cs;return b(),A("div",{ref_key:"scrollContainer",ref:a,class:"overflow-x-auto overflow-y-hidden scrollbar-hide"},[v(f,{ref_key:"tabsRef",ref:i,modelValue:c.value,"onUpdate:modelValue":u[0]||(u[0]=h=>c.value=h),size:e.size,items:e.items,content:!1,class:"min-w-max"},null,8,["modelValue","size","items"])],512)}}}),Dt=Gt(Kc,[["__scopeId","data-v-4a114c59"]]),Gc=["innerHTML"],Oo=$e({__name:"AlertTips",props:{icon:{},content:{},color:{}},setup(e){return(t,s)=>{const n=_r;return b(),xe(n,{color:e.color||"error",variant:"outline",icon:e.icon||"i-lucide-terminal",class:"p-2"},{title:re(()=>[r("p",{innerHTML:e.content},null,8,Gc)]),_:1},8,["color","icon"])}}}),Xc={key:0,class:"mb-2 block text-sm font-medium text-gray-700 dark:text-gray-300"},Yc={key:0,class:"font-normal text-gray-400"},Qc={class:"flex gap-2"},Jc={key:1,class:"mt-1 text-xs text-gray-500"},Zc={key:2,class:"mt-2"},ed={key:0,class:"flex items-center gap-1 text-sm text-green-600 dark:text-green-400"},td={key:1,class:"flex items-center gap-1 text-sm text-amber-600 dark:text-amber-400"},Hs=$e({__name:"ApiKeyInput",props:{modelValue:{},placeholder:{default:""},label:{default:"API Key"},optionalText:{default:""},hint:{default:""},validateLoading:{type:Boolean,default:!1},validateDisabled:{type:Boolean,default:!1},validateText:{default:""},validationResult:{default:"idle"},validationMessage:{default:""}},emits:["update:modelValue","validate"],setup(e,{emit:t}){const s=e,n=t,a=G(()=>!!s.validateText),i=P(!1);function c(l){n("update:modelValue",l)}return(l,m)=>{const u=We,f=lt,h=Ve;return b(),A("div",null,[e.label?(b(),A("label",Xc,[J(d(e.label)+" ",1),e.optionalText?(b(),A("span",Yc,d(e.optionalText),1)):ne("",!0)])):ne("",!0),r("div",Qc,[v(f,{"model-value":e.modelValue,type:i.value?"text":"password",placeholder:e.placeholder,ui:{trailing:"pe-1"},class:"flex-1","onUpdate:modelValue":c},lr({_:2},[e.modelValue?{name:"trailing",fn:re(()=>[v(u,{color:"neutral",variant:"link",size:"sm",icon:i.value?"i-heroicons-eye-slash":"i-heroicons-eye","aria-label":i.value?"Hide":"Show","aria-pressed":i.value,onClick:m[0]||(m[0]=x=>i.value=!i.value)},null,8,["icon","aria-label","aria-pressed"])]),key:"0"}:void 0]),1032,["model-value","type","placeholder"]),a.value?(b(),xe(u,{key:0,loading:e.validateLoading,disabled:e.validateDisabled,variant:"soft",onClick:m[1]||(m[1]=x=>n("validate"))},{default:re(()=>[J(d(e.validateText),1)]),_:1},8,["loading","disabled"])):ne("",!0)]),e.hint?(b(),A("p",Jc,d(e.hint),1)):ne("",!0),e.validationMessage?(b(),A("div",Zc,[e.validationResult==="valid"?(b(),A("div",ed,[v(h,{name:"i-heroicons-check-circle",class:"h-4 w-4"}),J(" "+d(e.validationMessage),1)])):e.validationResult==="invalid"?(b(),A("div",td,[v(h,{name:"i-heroicons-exclamation-triangle",class:"h-4 w-4"}),J(" "+d(e.validationMessage),1)])):ne("",!0)])):ne("",!0)])}}}),sd={class:"flex max-h-[80vh] min-h-[400px] flex-col p-6"},ad={class:"mb-4 flex items-center justify-between"},nd={class:"text-lg font-semibold text-gray-900 dark:text-white"},od={class:"flex items-center gap-2"},rd={class:"min-h-0 flex-1 overflow-y-auto"},id={key:0,class:"flex flex-col items-center justify-center py-12"},ld={class:"text-sm text-gray-500"},cd={key:1,class:"flex flex-col items-center justify-center py-12"},dd={class:"text-sm font-medium text-gray-700 dark:text-gray-300"},ud={class:"mt-1 max-w-sm text-center text-xs text-gray-500"},md={key:2,class:"flex flex-col items-center justify-center py-12"},gd={class:"text-sm text-gray-500"},pd={key:3,class:"space-y-1"},fd={class:"min-w-0 flex-1"},hd={class:"truncate text-sm font-medium text-gray-800 dark:text-gray-200"},vd={class:"flex items-center gap-2"},yd={key:0,class:"truncate text-xs text-gray-400"},bd={key:1,class:"shrink-0 rounded bg-gray-100 px-1.5 py-0.5 text-[10px] font-medium text-gray-500 dark:bg-gray-800 dark:text-gray-400"},_d={key:0,disabled:"",class:"ml-3 flex shrink-0 items-center gap-1 rounded-md px-2 py-1 text-xs text-green-500"},xd={class:"mt-4 flex items-center justify-between border-t border-gray-100 pt-4 dark:border-gray-800"},kd={class:"text-xs text-gray-400"},wd=$e({__name:"RemoteModelBrowser",props:Ra({models:{},loading:{type:Boolean},error:{},addedModelIds:{}},{open:{type:Boolean,required:!0},openModifiers:{}}),emits:Ra(["add","addAll","refresh"],["update:open"]),setup(e,{emit:t}){const{t:s}=Re(),n=cr(e,"open"),a=e,i=t,c=P(""),l=G(()=>{const f=c.value.toLowerCase().trim();return f?a.models.filter(h=>h.id.toLowerCase().includes(f)||h.name.toLowerCase().includes(f)||h.ownedBy&&h.ownedBy.toLowerCase().includes(f)):a.models}),m=G(()=>l.value.filter(f=>!a.addedModelIds.has(f.id)));function u(){i("addAll",m.value)}return(f,h)=>{const x=Ve,S=We,C=lt,D=ht;return b(),xe(D,{open:n.value,ui:{content:"max-w-2xl z-[102]",overlay:"z-[101]"},"onUpdate:open":h[4]||(h[4]=M=>n.value=M)},{content:re(()=>[r("div",sd,[r("div",ad,[r("h3",nd,d(o(s)("settings.aiConfig.modal.fetchModelsTitle")),1),r("div",od,[l.value.length>0&&m.value.length>0?(b(),xe(S,{key:0,size:"xs",variant:"soft",onClick:u},{default:re(()=>[v(x,{name:"i-heroicons-plus",class:"h-3.5 w-3.5"}),J(" "+d(o(s)("settings.aiConfig.modal.addAllModels"))+" ("+d(m.value.length)+") ",1)]),_:1})):ne("",!0),v(S,{size:"xs",variant:"ghost",loading:e.loading,onClick:h[0]||(h[0]=M=>i("refresh"))},{default:re(()=>[v(x,{name:"i-heroicons-arrow-path",class:"h-4 w-4"})]),_:1},8,["loading"])])]),v(C,{modelValue:c.value,"onUpdate:modelValue":h[1]||(h[1]=M=>c.value=M),placeholder:o(s)("settings.aiConfig.modal.searchModels"),class:"mb-3",ui:{leading:"pointer-events-none"}},{leading:re(()=>[v(x,{name:"i-heroicons-magnifying-glass",class:"h-4 w-4 text-gray-400"})]),_:1},8,["modelValue","placeholder"]),r("div",rd,[e.loading?(b(),A("div",id,[v(x,{name:"i-heroicons-arrow-path",class:"mb-3 h-8 w-8 animate-spin text-gray-400"}),r("p",ld,d(o(s)("settings.aiConfig.modal.fetchModelsLoading")),1)])):e.error?(b(),A("div",cd,[v(x,{name:"i-heroicons-exclamation-triangle",class:"mb-3 h-8 w-8 text-amber-400"}),r("p",dd,d(o(s)("settings.aiConfig.modal.fetchModelsError")),1),r("p",ud,d(e.error),1),v(S,{size:"xs",variant:"soft",class:"mt-3",onClick:h[2]||(h[2]=M=>i("refresh"))},{default:re(()=>[J(d(o(s)("common.retry")),1)]),_:1})])):l.value.length===0?(b(),A("div",md,[v(x,{name:"i-heroicons-cube-transparent",class:"mb-3 h-8 w-8 text-gray-300"}),r("p",gd,d(c.value?o(s)("common.noResults"):o(s)("settings.aiConfig.modal.fetchModelsEmpty")),1)])):(b(),A("div",pd,[(b(!0),A(Me,null,Be(l.value,M=>(b(),A("div",{key:M.id,class:"flex items-center justify-between rounded-lg px-3 py-2 transition-colors hover:bg-gray-50 dark:hover:bg-gray-800/50"},[r("div",fd,[r("p",hd,d(M.id),1),r("div",vd,[M.ownedBy?(b(),A("span",yd,d(M.ownedBy),1)):ne("",!0),M.contextWindow?(b(),A("span",bd,d(M.contextWindow>=1e6?(M.contextWindow/1048576).toFixed(1)+"M":Math.round(M.contextWindow/1024)+"K"),1)):ne("",!0)])]),e.addedModelIds.has(M.id)?(b(),A("button",_d,[v(x,{name:"i-heroicons-check",class:"h-3.5 w-3.5"}),J(" "+d(o(s)("settings.aiConfig.modal.modelAdded")),1)])):(b(),xe(S,{key:1,size:"xs",variant:"soft",class:"ml-3 shrink-0",onClick:g=>i("add",M)},{default:re(()=>[v(x,{name:"i-heroicons-plus",class:"h-3.5 w-3.5"}),J(" "+d(o(s)("common.add")),1)]),_:1},8,["onClick"]))]))),128))]))]),r("div",xd,[r("p",kd,d(o(s)("settings.aiConfig.modal.fetchModelsCount",{total:e.models.length,shown:l.value.length})),1),v(S,{variant:"soft",onClick:h[3]||(h[3]=M=>n.value=!1)},{default:re(()=>[J(d(o(s)("common.close")),1)]),_:1})])])]),_:1},8,["open"])}}});function Ho(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var vs={exports:{}},Sd=vs.exports,wn;function Ps(){return wn||(wn=1,(function(e,t){(function(s,n){e.exports=n()})(Sd,(function(){var s=1e3,n=6e4,a=36e5,i="millisecond",c="second",l="minute",m="hour",u="day",f="week",h="month",x="quarter",S="year",C="date",D="Invalid Date",M=/^(\d{4})[-/]?(\d{1,2})?[-/]?(\d{0,2})[Tt\s]*(\d{1,2})?:?(\d{1,2})?:?(\d{1,2})?[.:]?(\d+)?$/,g=/\[([^\]]+)]|Y{1,4}|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|SSS/g,p={name:"en",weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),ordinal:function(B){var j=["th","st","nd","rd"],X=B%100;return"["+B+(j[(X-20)%10]||j[X]||j[0])+"]"}},k=function(B,j,X){var le=String(B);return!le||le.length>=j?B:""+Array(j+1-le.length).join(X)+B},T={s:k,z:function(B){var j=-B.utcOffset(),X=Math.abs(j),le=Math.floor(X/60),F=X%60;return(j<=0?"+":"-")+k(le,2,"0")+":"+k(F,2,"0")},m:function B(j,X){if(j.date()<X.date())return-B(X,j);var le=12*(X.year()-j.year())+(X.month()-j.month()),F=j.clone().add(le,h),_=X-F<0,y=j.clone().add(le+(_?-1:1),h);return+(-(le+(X-F)/(_?F-y:y-F))||0)},a:function(B){return B<0?Math.ceil(B)||0:Math.floor(B)},p:function(B){return{M:h,y:S,w:f,d:u,D:C,h:m,m:l,s:c,ms:i,Q:x}[B]||String(B||"").toLowerCase().replace(/s$/,"")},u:function(B){return B===void 0}},E="en",I={};I[E]=p;var N="$isDayjsObject",ee=function(B){return B instanceof Y||!(!B||!B[N])},V=function B(j,X,le){var F;if(!j)return E;if(typeof j=="string"){var _=j.toLowerCase();I[_]&&(F=_),X&&(I[_]=X,F=_);var y=j.split("-");if(!F&&y.length>1)return B(y[0])}else{var L=j.name;I[L]=j,F=L}return!le&&F&&(E=F),F||!le&&E},ie=function(B,j){if(ee(B))return B.clone();var X=typeof j=="object"?j:{};return X.date=B,X.args=arguments,new Y(X)},Q=T;Q.l=V,Q.i=ee,Q.w=function(B,j){return ie(B,{locale:j.$L,utc:j.$u,x:j.$x,$offset:j.$offset})};var Y=(function(){function B(X){this.$L=V(X.locale,null,!0),this.parse(X),this.$x=this.$x||X.x||{},this[N]=!0}var j=B.prototype;return j.parse=function(X){this.$d=(function(le){var F=le.date,_=le.utc;if(F===null)return new Date(NaN);if(Q.u(F))return new Date;if(F instanceof Date)return new Date(F);if(typeof F=="string"&&!/Z$/i.test(F)){var y=F.match(M);if(y){var L=y[2]-1||0,$=(y[7]||"0").substring(0,3);return _?new Date(Date.UTC(y[1],L,y[3]||1,y[4]||0,y[5]||0,y[6]||0,$)):new Date(y[1],L,y[3]||1,y[4]||0,y[5]||0,y[6]||0,$)}}return new Date(F)})(X),this.init()},j.init=function(){var X=this.$d;this.$y=X.getFullYear(),this.$M=X.getMonth(),this.$D=X.getDate(),this.$W=X.getDay(),this.$H=X.getHours(),this.$m=X.getMinutes(),this.$s=X.getSeconds(),this.$ms=X.getMilliseconds()},j.$utils=function(){return Q},j.isValid=function(){return this.$d.toString()!==D},j.isSame=function(X,le){var F=ie(X);return this.startOf(le)<=F&&F<=this.endOf(le)},j.isAfter=function(X,le){return ie(X)<this.startOf(le)},j.isBefore=function(X,le){return this.endOf(le)<ie(X)},j.$g=function(X,le,F){return Q.u(X)?this[le]:this.set(F,X)},j.unix=function(){return Math.floor(this.valueOf()/1e3)},j.valueOf=function(){return this.$d.getTime()},j.startOf=function(X,le){var F=this,_=!!Q.u(le)||le,y=Q.p(X),L=function(ae,he){var ke=Q.w(F.$u?Date.UTC(F.$y,he,ae):new Date(F.$y,he,ae),F);return _?ke:ke.endOf(u)},$=function(ae,he){return Q.w(F.toDate()[ae].apply(F.toDate("s"),(_?[0,0,0,0]:[23,59,59,999]).slice(he)),F)},z=this.$W,ce=this.$M,W=this.$D,se="set"+(this.$u?"UTC":"");switch(y){case S:return _?L(1,0):L(31,11);case h:return _?L(1,ce):L(0,ce+1);case f:var pe=this.$locale().weekStart||0,me=(z<pe?z+7:z)-pe;return L(_?W-me:W+(6-me),ce);case u:case C:return $(se+"Hours",0);case m:return $(se+"Minutes",1);case l:return $(se+"Seconds",2);case c:return $(se+"Milliseconds",3);default:return this.clone()}},j.endOf=function(X){return this.startOf(X,!1)},j.$set=function(X,le){var F,_=Q.p(X),y="set"+(this.$u?"UTC":""),L=(F={},F[u]=y+"Date",F[C]=y+"Date",F[h]=y+"Month",F[S]=y+"FullYear",F[m]=y+"Hours",F[l]=y+"Minutes",F[c]=y+"Seconds",F[i]=y+"Milliseconds",F)[_],$=_===u?this.$D+(le-this.$W):le;if(_===h||_===S){var z=this.clone().set(C,1);z.$d[L]($),z.init(),this.$d=z.set(C,Math.min(this.$D,z.daysInMonth())).$d}else L&&this.$d[L]($);return this.init(),this},j.set=function(X,le){return this.clone().$set(X,le)},j.get=function(X){return this[Q.p(X)]()},j.add=function(X,le){var F,_=this;X=Number(X);var y=Q.p(le),L=function(ce){var W=ie(_);return Q.w(W.date(W.date()+Math.round(ce*X)),_)};if(y===h)return this.set(h,this.$M+X);if(y===S)return this.set(S,this.$y+X);if(y===u)return L(1);if(y===f)return L(7);var $=(F={},F[l]=n,F[m]=a,F[c]=s,F)[y]||1,z=this.$d.getTime()+X*$;return Q.w(z,this)},j.subtract=function(X,le){return this.add(-1*X,le)},j.format=function(X){var le=this,F=this.$locale();if(!this.isValid())return F.invalidDate||D;var _=X||"YYYY-MM-DDTHH:mm:ssZ",y=Q.z(this),L=this.$H,$=this.$m,z=this.$M,ce=F.weekdays,W=F.months,se=F.meridiem,pe=function(he,ke,ve,_e){return he&&(he[ke]||he(le,_))||ve[ke].slice(0,_e)},me=function(he){return Q.s(L%12||12,he,"0")},ae=se||function(he,ke,ve){var _e=he<12?"AM":"PM";return ve?_e.toLowerCase():_e};return _.replace(g,(function(he,ke){return ke||(function(ve){switch(ve){case"YY":return String(le.$y).slice(-2);case"YYYY":return Q.s(le.$y,4,"0");case"M":return z+1;case"MM":return Q.s(z+1,2,"0");case"MMM":return pe(F.monthsShort,z,W,3);case"MMMM":return pe(W,z);case"D":return le.$D;case"DD":return Q.s(le.$D,2,"0");case"d":return String(le.$W);case"dd":return pe(F.weekdaysMin,le.$W,ce,2);case"ddd":return pe(F.weekdaysShort,le.$W,ce,3);case"dddd":return ce[le.$W];case"H":return String(L);case"HH":return Q.s(L,2,"0");case"h":return me(1);case"hh":return me(2);case"a":return ae(L,$,!0);case"A":return ae(L,$,!1);case"m":return String($);case"mm":return Q.s($,2,"0");case"s":return String(le.$s);case"ss":return Q.s(le.$s,2,"0");case"SSS":return Q.s(le.$ms,3,"0");case"Z":return y}return null})(he)||y.replace(":","")}))},j.utcOffset=function(){return 15*-Math.round(this.$d.getTimezoneOffset()/15)},j.diff=function(X,le,F){var _,y=this,L=Q.p(le),$=ie(X),z=($.utcOffset()-this.utcOffset())*n,ce=this-$,W=function(){return Q.m(y,$)};switch(L){case S:_=W()/12;break;case h:_=W();break;case x:_=W()/3;break;case f:_=(ce-z)/6048e5;break;case u:_=(ce-z)/864e5;break;case m:_=ce/a;break;case l:_=ce/n;break;case c:_=ce/s;break;default:_=ce}return F?_:Q.a(_)},j.daysInMonth=function(){return this.endOf(h).$D},j.$locale=function(){return I[this.$L]},j.locale=function(X,le){if(!X)return this.$L;var F=this.clone(),_=V(X,le,!0);return _&&(F.$L=_),F},j.clone=function(){return Q.w(this.$d,this)},j.toDate=function(){return new Date(this.valueOf())},j.toJSON=function(){return this.isValid()?this.toISOString():null},j.toISOString=function(){return this.$d.toISOString()},j.toString=function(){return this.$d.toUTCString()},B})(),H=Y.prototype;return ie.prototype=H,[["$ms",i],["$s",c],["$m",l],["$H",m],["$W",u],["$M",h],["$y",S],["$D",C]].forEach((function(B){H[B[1]]=function(j){return this.$g(j,B[0],B[1])}})),ie.extend=function(B,j){return B.$i||(B(j,Y,ie),B.$i=!0),ie},ie.locale=V,ie.isDayjs=ee,ie.unix=function(B){return ie(1e3*B)},ie.en=I[E],ie.Ls=I,ie.p={},ie}))})(vs)),vs.exports}var Cd=Ps();const ot=Ho(Cd);var ys={exports:{}},Md=ys.exports,Sn;function Ad(){return Sn||(Sn=1,(function(e,t){(function(s,n){e.exports=n(Ps())})(Md,(function(s){function n(c){return c&&typeof c=="object"&&"default"in c?c:{default:c}}var a=n(s),i={name:"zh-cn",weekdays:"星期日_星期一_星期二_星期三_星期四_星期五_星期六".split("_"),weekdaysShort:"周日_周一_周二_周三_周四_周五_周六".split("_"),weekdaysMin:"日_一_二_三_四_五_六".split("_"),months:"一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月".split("_"),monthsShort:"1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月".split("_"),ordinal:function(c,l){return l==="W"?c+"周":c+"日"},weekStart:1,yearStart:4,formats:{LT:"HH:mm",LTS:"HH:mm:ss",L:"YYYY/MM/DD",LL:"YYYY年M月D日",LLL:"YYYY年M月D日Ah点mm分",LLLL:"YYYY年M月D日ddddAh点mm分",l:"YYYY/M/D",ll:"YYYY年M月D日",lll:"YYYY年M月D日 HH:mm",llll:"YYYY年M月D日dddd HH:mm"},relativeTime:{future:"%s内",past:"%s前",s:"几秒",m:"1 分钟",mm:"%d 分钟",h:"1 小时",hh:"%d 小时",d:"1 天",dd:"%d 天",M:"1 个月",MM:"%d 个月",y:"1 年",yy:"%d 年"},meridiem:function(c,l){var m=100*c+l;return m<600?"凌晨":m<900?"早上":m<1100?"上午":m<1300?"中午":m<1800?"下午":"晚上"}};return a.default.locale(i,null,!0),i}))})(ys)),ys.exports}Ad();var bs={exports:{}},Td=bs.exports,Cn;function $d(){return Cn||(Cn=1,(function(e,t){(function(s,n){e.exports=n(Ps())})(Td,(function(s){function n(c){return c&&typeof c=="object"&&"default"in c?c:{default:c}}var a=n(s),i={name:"zh-tw",weekdays:"星期日_星期一_星期二_星期三_星期四_星期五_星期六".split("_"),weekdaysShort:"週日_週一_週二_週三_週四_週五_週六".split("_"),weekdaysMin:"日_一_二_三_四_五_六".split("_"),months:"一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月".split("_"),monthsShort:"1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月".split("_"),ordinal:function(c,l){return l==="W"?c+"週":c+"日"},formats:{LT:"HH:mm",LTS:"HH:mm:ss",L:"YYYY/MM/DD",LL:"YYYY年M月D日",LLL:"YYYY年M月D日 HH:mm",LLLL:"YYYY年M月D日dddd HH:mm",l:"YYYY/M/D",ll:"YYYY年M月D日",lll:"YYYY年M月D日 HH:mm",llll:"YYYY年M月D日dddd HH:mm"},relativeTime:{future:"%s內",past:"%s前",s:"幾秒",m:"1 分鐘",mm:"%d 分鐘",h:"1 小時",hh:"%d 小時",d:"1 天",dd:"%d 天",M:"1 個月",MM:"%d 個月",y:"1 年",yy:"%d 年"},meridiem:function(c,l){var m=100*c+l;return m<600?"凌晨":m<900?"早上":m<1100?"上午":m<1300?"中午":m<1800?"下午":"晚上"}};return a.default.locale(i,null,!0),i}))})(bs)),bs.exports}$d();var _s={exports:{}},Id=_s.exports,Mn;function Pd(){return Mn||(Mn=1,(function(e,t){(function(s,n){e.exports=n()})(Id,(function(){return{name:"en",weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),ordinal:function(s){var n=["th","st","nd","rd"],a=s%100;return"["+s+(n[(a-20)%10]||n[a]||n[0])+"]"}}}))})(_s)),_s.exports}Pd();var xs={exports:{}},Dd=xs.exports,An;function Ld(){return An||(An=1,(function(e,t){(function(s,n){e.exports=n(Ps())})(Dd,(function(s){function n(c){return c&&typeof c=="object"&&"default"in c?c:{default:c}}var a=n(s),i={name:"ja",weekdays:"日曜日_月曜日_火曜日_水曜日_木曜日_金曜日_土曜日".split("_"),weekdaysShort:"日_月_火_水_木_金_土".split("_"),weekdaysMin:"日_月_火_水_木_金_土".split("_"),months:"1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月".split("_"),monthsShort:"1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月".split("_"),ordinal:function(c){return c+"日"},formats:{LT:"HH:mm",LTS:"HH:mm:ss",L:"YYYY/MM/DD",LL:"YYYY年M月D日",LLL:"YYYY年M月D日 HH:mm",LLLL:"YYYY年M月D日 dddd HH:mm",l:"YYYY/MM/DD",ll:"YYYY年M月D日",lll:"YYYY年M月D日 HH:mm",llll:"YYYY年M月D日(ddd) HH:mm"},meridiem:function(c){return c<12?"午前":"午後"},relativeTime:{future:"%s後",past:"%s前",s:"数秒",m:"1分",mm:"%d分",h:"1時間",hh:"%d時間",d:"1日",dd:"%d日",M:"1ヶ月",MM:"%dヶ月",y:"1年",yy:"%d年"}};return a.default.locale(i,null,!0),i}))})(xs)),xs.exports}Ld();const Ed="确定",Rd="取消",Nd="保存",Fd="编辑",Ud="添加",Od="重命名",Hd="截屏",Vd="关闭",zd="返回",Bd="完成",Wd="重试",jd="加载中...",qd="初始化中...",Kd="暂无数据",Gd="无匹配结果",Xd="导出成功",Yd="导出失败",Qd="生成中...",Jd="重新生成",Zd="打开目录",eu="请先在设置中配置 AI 服务",tu="重置",su={general:"操作失败,请重试",network:"网络错误",unknown:"未知错误"},au={image:"图片",video:"视频",audio:"音频",file:"文件",sticker:"贴纸",link:"链接"},nu={messages:"条消息",members:"个成员",days:"天"},ou={text:"文字",image:"图片",voice:"语音",video:"视频",file:"文件",emoji:"表情",link:"链接",location:"位置",redPacket:"红包",transfer:"转账",poke:"拍一拍",call:"通话",share:"分享",reply:"回复",forward:"转发",contact:"名片",system:"系统",recall:"撤回",other:"其他",unknown:"未知"},ru={mon:"周一",tue:"周二",wed:"周三",thu:"周四",fri:"周五",sat:"周六",sun:"周日"},iu={jan:"1月",feb:"2月",mar:"3月",apr:"4月",may:"5月",jun:"6月",jul:"7月",aug:"8月",sep:"9月",oct:"10月",nov:"11月",dec:"12月"},lu={title:"选择语言",subtitle:"请选择您偏好的界面语言",next:"下一步"},cu={title:"隐私政策与用户协议",subtitle:"使用前请仔细阅读",disagree:"我不同意",agree:"我已阅读并同意",updateNotice:"协议内容有重要更新,请重新阅读并确认"},du={selectDate:"选择日期",clearDate:"清空日期"},uu={mode:{recent:"最近",quarter:"按季",year:"按年",custom:"自定义"},recent:{halfYear:"近半年",oneYear:"近一年",twoYears:"近两年",fiveYears:"近五年",all:"全部"},display:{recent180:"最近半年",recent365:"最近一年",recent730:"最近两年",recent1825:"最近五年"},quarter:{label:"{year}年 第{quarter}季度"},year:{label:"{year}年"}},mu={allMembers:"全部成员"},gu={confirm:Ed,cancel:Rd,delete:"删除",save:Nd,edit:Fd,add:Ud,rename:Od,capture:Hd,close:Vd,back:zd,done:Bd,retry:Wd,loading:jd,initializing:qd,noData:Kd,noResults:Gd,export:"导出",exportSuccess:Xd,exportFailed:Yd,generating:Qd,regenerate:Jd,openFolder:Zd,errorNoAIConfig:eu,reset:tu,error:su,attachment:au,unit:nu,messageType:ou,weekday:ru,month:iu,languageSelect:lu,agreement:cu,datePicker:du,timeSelect:uu,userSelect:mu},pu="ChatLab",fu="分析新聊天",hu="实用工具",vu="聊天对话",yu="管理",bu="暂无记录",_u="搜索对话名称",xu="未找到匹配的聊天记录",ku={rename:"重命名",pin:"置顶",unpin:"取消置顶",delete:"删除"},wu={title:"重命名",placeholder:"请输入新名称"},Su={title:"确认删除",message:'确定要删除聊天记录 "{name}" 吗?此操作无法撤销。'},Cu={all:"全部",private:"私聊",group:"群聊"},Mu={importedAt:"导入时间",lastMessageTs:"最近对话",messageCount:"消息数量"},Au={expand:"展开侧边栏",collapse:"收起侧边栏",hint:"右键可删除或重命名聊天记录",search:"搜索聊天记录",sort:"排序"},Tu="{count} 条消息",$u={helpAndFeedback:"反馈和帮助",settings:"设置"},Iu={brand:pu,newAnalysis:fu,tools:hu,chatHistory:vu,manage:yu,noRecords:bu,searchPlaceholder:_u,noSearchResult:xu,contextMenu:ku,renameModal:wu,deleteModal:Su,filter:Cu,sort:Mu,tooltip:Au,sessionInfo:Tu,footer:$u},Pu="设置",Du={basic:"基础设置",ai:"AI 设置",aiConfig:"模型服务",aiDefaultModel:"默认模型",aiPrompt:"对话配置",aiPreprocess:"预处理",dataManage:"数据管理",storage:"存储管理",storageManage:"存储管理",sessionManage:"会话索引",about:"关于",api:"自动化",apiSubTabs:{autoSync:"自动同步",apiService:"API 服务",mcp:"MCP"}},Lu={general:{title:"常规"},preferences:{title:"偏好设置"},language:{title:"语言",description:"选择软件显示语言"},appearance:{title:"外观设置",themeMode:"主题模式",auto:"跟随系统",light:"浅色模式",dark:"深色模式"},defaultTab:{title:"默认标签页",description:"进入聊天对话后默认显示的页面",overview:"总览",aiChat:"AI 对话"},autoLaunch:{title:"启动设置",openAtLogin:"开机自启动",openAtLoginDesc:"系统启动时自动运行 ChatLab",devModeHint:"开发模式下不可用"},toolsPanel:{positionLabel:"快捷工具入口位置",positionDesc:"选择快捷工具面板的显示位置",positionSide:"右侧",positionHeader:"顶部"},screenshot:{title:"截图设置",mobileAdapt:"移动端适配",mobileAdaptDesc:"截图时自动缩放宽度,适合移动端查看"},network:{title:"网络设置",proxyMode:"代理模式",proxyModeDesc:"访问网络时使用的代理方式",modeOff:"关闭",modeSystem:"跟随系统",modeManual:"手动配置",proxyAddress:"代理地址",proxyPlaceholder:"http://127.0.0.1:7890",proxyHelp:"支持 HTTP/HTTPS 代理,格式如:http://127.0.0.1:7890",testConnection:"测试连接",testing:"测试中...",connectionSuccess:"代理连接成功!",connectionFailed:"连接失败",enterProxyFirst:"请先输入代理地址",invalidProxyUrl:"请输入有效的代理地址,格式如 http://127.0.0.1:7890",onlyHttpSupported:"仅支持 http:// 或 https:// 协议",saveFailed:"保存失败"}},Eu={title:"默认模型",noConfigs:"请先在「模型服务」中添加模型配置",selectProvider:"选择提供商",selectModel:"选择模型",assistantModel:{label:"默认助手模型",description:"用于 AI 对话、工具调用、SQL 助手、上下文压缩"},fastModel:{label:"快速模型",description:"用于会话摘要生成,未配置时使用默认助手模型",followAssistant:"跟随默认助手模型"}},Ru={title:"模型服务",providerTitle:"服务提供商",loading:"加载中...",inUse:"使用中",defaultModel:"默认模型",localService:"本地服务",edit:"编辑",delete:"删除",empty:{title:"还没有配置 AI 服务",description:"添加一个配置开始使用 AI 功能"},addConfig:"添加新服务",maxConfigs:"已达最大配置数量(10个)",modal:{addConfig:"添加新服务",editConfig:"编辑服务",officialApi:"官方API",officialApiDesc:"DeepSeek、Gemini 等",localService:"本地服务",localServiceDesc:"Ollama 等",openaiCompatible:"OpenAI 兼容",openaiCompatibleDesc:"自定义端点",configName:"配置名称",optional:"(选填)",configNamePlaceholderPreset:"留空将使用服务商名称",configNamePlaceholderCustom:"留空将使用 API 端点地址",aiProvider:"AI 服务商",apiKeyPlaceholder:"输入你的 API Key",apiKeyPlaceholderEdit:"输入新的 API Key(留空保持原有)",apiKeyPlaceholderLocal:"本地服务通常不需要",apiKeyHintLocal:"如果服务设置了认证,在此输入",validate:"验证",validationSuccess:"连接验证成功",validationFailed:"连接验证失败",validationFailedTitle:"API 连接验证失败",saveAnywayHint:"验证未通过,配置信息可能有误。是否仍然保存?",saveAnyway:"仍然保存",validationError:"验证失败:",model:"模型",modelName:"模型名称",modelNamePlaceholder:"如 gpt-4、claude-3",modelNamePlaceholderLocal:"如 qwen3、deepseek-r1",modelNameHint:"输入 API 支持的模型名称",modelNameHintLocal:"输入本地部署的模型名称",apiEndpoint:"API 地址",apiEndpointHint:"兼容 OpenAI 格式的 API 端点",resolvedUrl:"实际请求地址:",fetchModels:"从 API 获取",fetchModelsTitle:"浏览远程模型",fetchModelsLoading:"正在获取模型列表...",fetchModelsEmpty:"未获取到模型",fetchModelsError:"获取模型列表失败",fetchModelsCount:"共 {total} 个模型,当前显示 {shown} 个",modelAdded:"已添加",addAllModels:"全部添加",searchModels:"搜索模型...",apiEndpointOverrideHint:"默认地址已填入,可按需改为完整 URL",disableThinking:"禁用思考模式",disableThinkingDesc:"针对 Qwen3、DeepSeek-R1 等模型,禁用后使用标准工具调用格式",isReasoningModel:"推理模型",isReasoningModelDesc:"启用后将提取思考过程并禁用工具调用(如 DeepSeek-R1、QwQ 等)",advancedOptions:"高级选项",customService:"自定义服务",unnamedConfig:"未命名配置",visitWebsite:"访问官网",getApiKey:"获取 API Key",presetService:"预设服务",thirdPartyService:"第三方服务",customModelInput:"手动输入模型",selectFromList:"从列表选择",addCustomModel:"添加模型",deleteCustomModel:"删除选中",customModelId:"模型端点名",customModelIdHint:"API 调用时使用的模型标识符",customModelDisplayName:"显示名称",customModelDisplayNamePlaceholder:"自定义显示名",editModel:"编辑模型",contextWindow:"上下文窗口",contextWindowPlaceholder:"如 128000",contextWindowHint:"模型支持的最大上下文 token 数(用于上下文压缩)",contextWindowMissing:"未设置上下文窗口,将使用默认值,建议点击「编辑模型」手动填写",modelCapabilities:"模型能力标注",modelRequired:"至少添加一个模型才能保存",apiFormat:"API 接口类型",apiFormatOpenAI:"OpenAI Completions",apiFormatAnthropic:"Anthropic",apiFormatGemini:"Gemini",apiFormatOpenAIResponses:"OpenAI Responses"},providerKind:{official:"官方",aggregator:"聚合",custom:"自定义"},capabilities:{chat:"对话",reasoning:"推理",vision:"视觉",function_calling:"工具调用",embedding:"向量",ranking:"排序"}},Nu={title:"本地存储管理",description:"管理 ChatLab 在本地存储的数据文件",dataLocation:{title:"数据目录位置",description:"自定义本地数据与缓存的存放位置",choose:"选择位置",reset:"恢复默认",open:"打开",migrateHint:"检测到数据仍在旧位置,建议迁移至统一目录:",migrateAction:"一键迁移",restartTip:"切换目录后请重启应用,旧目录下缓存会跟随迁移",confirmTitle:"确认切换数据目录",confirmMessage:"您即将切换数据存储位置,现有数据将被迁移到新目录。",newPath:"新目录路径",defaultPath:"默认位置",confirmWarning:"重启应用后,旧数据目录将被自动删除。请确保新目录路径正确。",installDirForbidden:"不能将数据目录放在应用安装目录下,应用更新时该目录会被清空",cancel:"取消",confirm:"确认切换",migrationSuccessTitle:"数据迁移完成",migrationSuccessMessage:"应用需要重启以使更改生效。",relaunchNow:"立即重启"},openRootDir:"打开根目录",totalUsage:"总占用:",loading:"加载中...",files:"文件",notExist:"不存在",clear:"清理",open:"打开",cache:{databases:{name:"聊天记录数据库",description:"导入的聊天记录分析数据"},ai:{name:"AI 对话数据库",description:"AI 对话历史和配置文件"},downloads:{name:"下载目录",description:"包含截屏文件、分析结果等"},statsCache:{name:"缓存数据",description:"聊天记录的统计缓存,清理后会自动重建"},logs:{name:"日志文件",description:"软件的运行日志,包含导入、AI、错误等日志"}}},Fu={session:{title:"会话索引设置",description:"会话索引将聊天记录按时间间隔自动分割为对话段落,便于AI分析和浏览",defaultThreshold:"默认分割间隔",thresholdUnit:"分钟",thresholdHelp:"超过该时间间隔的消息将被分到新的会话段落",notGenerated:"尚未生成会话索引",generateHint:"生成索引后可让 AI 更精准地理解对话上下文",generate:"生成索引",regenerate:"重新生成",generating:"正在生成",sessionCount:"{count} 个会话",generated:"已生成会话索引",generateSuccess:"会话索引生成成功,共 {count} 个会话",generateError:"生成失败",batchTitle:"批量生成索引",totalSessions:"共 {count} 个聊天",generatedCount:"已生成 {count} 个",notGeneratedCount:"未生成 {count} 个",loadingStatus:"加载中...",batchGenerate:"生成未索引",batchRegenerate:"全部重新生成",summaryStrategy:"摘要详细程度",summaryStrategyHelp:"影响 AI 生成摘要时的详细程度",summaryBrief:"简要",summaryStandard:"标准"}},Uu={chatSettings:{title:"工具设置"},exportSettings:{title:"导出设置"},skillSettings:{title:"技能设置",enableAutoSkill:"AI 自主选择技能",enableAutoSkillDesc:"启用后,AI 会根据用户的问题自动匹配并激活合适的分析技能;关闭后仅在手动选择技能时生效"},maxMessages:{title:"发送条数限制",description:"每次提交给 AI 的最大消息数,数值越大 Token 消耗越多,分析也更准确(新手建议2000)"},searchContext:{title:"搜索上下文窗口",description:"搜索命中消息时自动携带前后的对话上下文,帮助 AI 理解消息背景。设为 0 则不携带上下文",before:"前",after:"后"},exportFormat:{title:"对话导出格式",description:"导出 AI 对话时使用的文件格式",txtLabel:"TXT"},sqlExportFormat:{title:"SQL Lab 导出格式",description:"导出 SQL 查询结果时使用的文件格式"},compression:{title:"上下文压缩",enable:"自动压缩上下文",enableDesc:"对话过长时自动压缩历史为摘要,保留关键信息的同时降低 Token 消耗",threshold:"压缩阈值",thresholdDesc:"上下文 Token 达到模型窗口的百分比时触发压缩",buffer:"缓冲区大小",bufferDesc:"保留最近消息原文的比例,不参与压缩",maxToolResultPercent:"工具结果上限",maxToolResultPercentDesc:"单次工具返回给 AI 的最大数据量占比(基于模型上下文窗口计算),超出部分会被智能截断"},presets:{title:"系统提示词",add:"添加预设",import:"导入预设",description:"提示词同时用于群聊和私聊分析,系统会自动根据分析类型调整相关内容"},preset:{builtIn:"内置",groupOnly:"仅群聊",privateOnly:"仅私聊",view:"查看",edit:"编辑",copy:"复制",delete:"删除"},modal:{editBuiltin:"编辑系统提示词",editCustom:"编辑自定义提示词",addCustom:"添加自定义提示词",presetName:"预设名称",presetNamePlaceholder:"为预设起个名字",applicableTo:"适用场景",applicableToHint:"(勾选后可在对应分析类型中使用)",groupChat:"群聊分析",privateChat:"私聊分析",systemPrompt:"系统提示词",systemPromptPlaceholder:"定义 AI 助手的角色、任务和回答要求...",preview:"完整提示词预览",previewHint:"(预览为群聊模式,实际会根据分析类型自动调整)",resetToDefault:"重置为默认",saveChanges:"保存修改",addPreset:"添加预设"},importPreset:{title:"导入预设",description:"从远程获取推荐的系统提示词预设",loading:"正在加载远程预设...",loadError:"加载远程预设失败",noPresets:"暂无可用的远程预设",commonPresets:"通用预设",groupPresets:"群聊专用预设",privatePresets:"私聊专用预设",add:"添加",added:"已添加",preview:"预览",systemPrompt:"系统提示词",noDescription:"暂无描述",fetchingContent:"正在加载内容...",fetchError:"加载内容失败"}},Ou={title:"关于 ChatLab",description:"本地化的聊天记录分析工具,通过 SQL 和 AI Agent 回顾你的社交记忆。",version:"版本",checkUpdate:"检查更新",checking:"检查中...",upToDate:"已是最新版本",newVersionAvailable:"发现新版本 {version}",updateNow:"立即更新",webUpdateHint:"请在终端运行 npm install -g chatlab-cli@latest 后重启服务。",updating:"更新中...",updateSuccess:"更新成功,请重启服务以生效",updateFailed:"更新失败:{error}",updateCheckFailed:"检查更新失败:{error}",unknown:"未知",privacy:{title:"隐私设置",analytics:"匿名使用统计",analyticsDesc:"开启后,软件会收集版本号、操作系统版本等非敏感数据,用于帮助优化产品"},developer:{title:"开发者选项",debugMode:"DEBUG 模式",debugModeDesc:"开启后,将显示调试面板和快捷调试工具,可用于查看数据库、运行测试工具,并记录更详细的调试日志。"}},Hu={title:"聊天记录预处理",description:"在聊天记录发送给 AI 前进行预处理,节省 Token 并过滤噪音。原始数据不会被修改。",dataCleaning:"数据清洗",dataCleaningDesc:"自动清理 XML 卡片消息(如分享链接、小程序等),提取有效内容,大幅节省 Token。建议保持开启。",mergeConsecutive:"合并连续发言",mergeConsecutiveDesc:"同一人在短时间内的连续消息合并为一条",mergeWindow:"合并时间窗口(秒)",denoise:"智能去噪",denoiseDesc:"过滤纯语气词、纯表情、系统占位符(如 [图片])等无意义消息",desensitize:"数据脱敏",desensitizeDesc:"根据规则将敏感信息(手机号、邮箱、证件号等)替换为占位符",desensitizeRules:"脱敏规则",desensitizeRulesDesc:"勾选需要启用的脱敏规则,按列表顺序优先匹配",desensitizeBuiltin:"预置规则",desensitizeCustom:"自定义规则",desensitizeAddCustom:"添加自定义规则",desensitizeRuleName:"规则名称",desensitizeRulePattern:"正则表达式",desensitizeRuleReplacement:"替换文本",desensitizeRuleAdd:"添加",desensitizeRuleInvalidRegex:"正则表达式语法错误",desensitizeRuleNamePlaceholder:"例如:员工工号",desensitizeRulePatternPlaceholder:"例如:EMP-\\d+",desensitizeRuleReplacementPlaceholder:"替换文本,如 [工号]",anonymizeNames:"昵称匿名化",anonymizeNamesDesc:"用编号(U1、U2…)替代真实昵称发送给 AI,减少幻觉并节省 Token",blacklist:"黑名单关键词",blacklistDesc:"包含以下任一关键词的消息将被整条过滤",blacklistPlaceholder:"输入关键词后按回车添加",blacklistAdd:"添加"},Vu={rules:{cn_phone:"中国手机号",cn_phone_desc:"1xx xxxx xxxx 格式的 11 位号码",cn_id_card:"中国身份证号",cn_id_card_desc:"18 位,末位可含 X",cn_bank_card:"中国银行卡号",cn_bank_card_desc:"16-19 位连续数字",cn_landline:"中国座机号",cn_landline_desc:"区号-号码,如 010-12345678",us_ssn:"美国社会安全号 (SSN)",us_ssn_desc:"XXX-XX-XXXX 格式",us_phone:"美国电话号码",us_phone_desc:"+1 (XXX) XXX-XXXX 格式",us_drivers_license:"美国驾照号",us_drivers_license_desc:"字母开头 + 7-8 位数字",jp_phone:"日本电话号码",jp_phone_desc:"0x0-XXXX-XXXX 格式",jp_my_number:"日本个人编号",jp_my_number_desc:"12 位数字(マイナンバー)",kr_phone:"韩国电话号码",kr_phone_desc:"01X-XXXX-XXXX 格式",kr_rrn:"韩国身份证号",kr_rrn_desc:"XXXXXX-XXXXXXX 格式(주민번호)",api_key_prefix:"API Key / Token(已知前缀)",api_key_prefix_desc:"sk-、ghp_、AKIA 等开头的长字符串",bearer_token:"Bearer Token",bearer_token_desc:"Bearer 后的授权令牌值",email:"邮箱地址",email_desc:"user{'@'}domain.com 标准格式",credit_card:"信用卡号",credit_card_desc:"Visa / MasterCard / AmEx 等卡号",ipv4:"IPv4 地址",ipv4_desc:"如 192.168.1.1",url:"URL 链接",url_desc:"http:// 或 https:// 开头的链接"}},zu={betaWarning:"当前 API 版本仅为测试版(Beta),接口可能会发生调整",service:{title:"API 服务",enable:"启用 API 服务",enableDesc:"开启后,外部工具可通过 HTTP API 查询、导出和导入聊天数据。仅本机可访问 (127.0.0.1)",portInUseHint:"端口被占用,请在下方修改端口或关闭占用该端口的程序后重试"},status:{running:"运行中",stopped:"已停止",starting:"启动中...",portInUse:"端口被占用",error:"启动失败"},port:{title:"端口配置",label:"监听端口",desc:"API 服务监听的本地端口号(1024-65535)",edit:"修改",save:"保存",cancel:"取消"},token:{title:"访问令牌",label:"Bearer Token",desc:"所有 API 请求需要在 Authorization 头中携带此 Token",noToken:"尚未生成 Token,请先启用服务",regenerate:"重新生成"},dataSources:{title:"数据源",desc:"配置外部数据源 URL,ChatLab 将按设定间隔自动拉取并导入聊天数据。",empty:"暂无数据源",noSessions:"暂无导入会话,点击上方「管理导入会话」添加",disabled:"已暂停",every:"每",minutes:"分钟",lastSync:"上次同步",syncing:"同步中",messages:"条消息",addBtn:"添加数据源",form:{modalTitle:"添加数据源",name:"名称",namePlaceholder:"例如:我的聊天服务器",url:"数据源 URL",token:"访问令牌(可选)",tokenPlaceholder:"远程 API 的 Bearer Token",interval:"拉取间隔(分钟)",pullLimit:"每次拉取消息数",pullLimitPlaceholder:"默认 1000",targetSession:"目标会话 ID(可选)",targetSessionPlaceholder:"留空则每次新建会话",add:"添加"},discovery:{directMode:"直接 URL",remoteMode:"远程服务器",baseUrl:"服务器地址",baseUrlPlaceholder:"示例:http://127.0.0.1:2333/api/v1",browse:"浏览远程会话",found:"发现 {count} 个会话",search:"搜索",searchPlaceholder:"按会话名称搜索",selectAll:"全选",deselectAll:"取消全选",selectByType:"会话类型",typeAll:"全部",typePrivate:"私聊",typeGroup:"群聊",typeOther:"其他",loadMore:"加载更多",subscribe:"订阅 {count} 个会话",messages:"条消息",error:"连接远程服务器失败",connectionCheckFailed:"无法连接到远程服务器,请检查地址和令牌是否正确"},edit:{title:"修改配置",save:"保存",cancel:"取消",editSource:"修改配置",manageSessions:"管理订阅",manageSessionsDesc:"重新选择要同步的远程会话",syncAll:"一键同步",subscribed:"已订阅"},deleteConfirm:{title:"删除数据源",message:"确认删除数据源「{name}」?该数据源下的所有导入配置将被移除。已导入的本地对话不会被删除。"},deleteSessionConfirm:{title:"删除订阅",message:"确认删除订阅「{name}」?",keepData:"仅删除订阅",deleteData:"同时删除导入的聊天"}},usage:{title:"使用说明",desc:"启用服务后,外部工具可通过 API 查询数据,或向 ChatLab 推送聊天记录。所有请求需携带 Bearer Token 认证。",authHint:"请求头示例:",docLink:"查看完整 API 文档"}},Bu={overview:{title:"MCP 概述",description:"MCP 让 AI 助手直接查询你的聊天记录。支持会话发现、关键词搜索、成员统计、时间分布等操作。",toolCount:"{count} 个工具",resourceCount:"{count} 个资源",installHint:"安装 chatlab-cli 后,在 AI 客户端中添加以下配置即可使用:"},clients:{other:"通用"},config:{title:"客户端配置",clientLabel:"MCP 客户端",copy:"复制",copied:"已复制",claudeHint:"将此配置添加到 ClaudeCode 的 MCP 配置中。",codexHint:"将此 TOML 配置添加到 ~/.codex/config.toml 文件中。",openclawHint:"将此配置添加到项目的 openclaw.json 文件中。",otherHint:"将此 JSON 配置添加到你的 MCP 客户端配置文件中。"},tips:{title:"使用提示",dataDir:"MCP 服务器读取 ~/.chatlab/ 目录下的聊天数据,与桌面应用共享同一份数据。",readOnly:"所有操作均为只读,不会修改你的聊天记录。",nodeRequired:"npx 和 CLI 方式需要 Node.js 20 或更高版本。",docs:"详细文档请访问 docs.chatlab.fun。"}},Wu={title:Pu,tabs:Du,basic:Lu,defaultModel:Eu,aiConfig:Ru,storage:Nu,ai:Fu,aiPrompt:Uu,about:Ou,aiPreprocess:Hu,desensitize:Vu,api:zu,mcp:Bu},ju="探索新的聊天记忆",qu={file:"文件导入",api:"自动同步",push:"API导入",apiDescription:"配置外部平台的数据源,让聊天记录定期自动同步到ChatLab。",apiButton:"去配置自动同步",pushDescription:"开启本地API服务,允许第三方工具/插件或脚本将聊天记录主动推送至ChatLab。",pushButton:"去开启 API 服务"},Ku={viewExample:"查看示例 Demo",downloading:"正在下载示例数据...",importing:"正在导入示例数据...",failed:"示例数据加载失败,请检查网络连接后重试"},Gu={title:"数据库需要升级",description:"检测到 {count} 个数据库需要升级以支持新功能。",note:"升级过程通常只需几秒钟,不会丢失任何数据。",upgradeContent:"本次升级内容:",upgradeNow:"立即升级",upgrading:"正在升级...",failed:"迁移失败",partialFailed:"部分数据库升级失败",errorHint:"这通常是因为数据库文件损坏。建议在侧边栏中删除失败的会话,然后重新导入。",close:"关闭",retry:"重试"},Xu={title:"选择要导入的聊天",scanning:"正在扫描聊天列表...",scanFailed:"扫描失败",retry:"重试",selectAll:"全选",chatCount:"共 {count} 个聊天",selected:"已选 {count} 个",messageCount:"{count} 条消息",import:"导入 ({count})",noChats:"未发现任何聊天"},Yu={title:"选择聊天记录格式",hint:"无法自动识别此文件的格式,请手动选择对应的聊天记录格式。",manualSelect:"手动选择格式",confirm:"使用此格式导入"},Qu={export:"新手引导",import:"支持哪些格式"},Ju={website:"官网",terms:"使用条款"},Zu={title:"版本日志",subtitle:"查看所有版本更新内容",viewChangelog:"版本日志",latest:"最新版本",current:"当前版本",total:"共 {count} 个版本",close:"关闭",loadError:"加载版本日志失败",retry:"重试",types:{feat:"新功能",fix:"问题修复",refactor:"重构优化",docs:"文档更新",chore:"其他优化",style:"样式优化",ci:"CI/构建"}},em={tagline:ju,tabs:qu,import:{dropHint:"松开鼠标导入文件",clickHint:"点击选择或拖拽聊天记录导入",multipleHint:"支持同时选择或拖拽多个文件",selectFiles:"选择聊天记录文件",selectFolder:"选择导出文件夹",importFolder:"导入文件夹",chatRecords:"聊天记录",allFiles:"所有文件",progress:{detecting:"正在检测格式...",reading:"正在读取文件...",parsing:"正在解析消息...",saving:"正在写入数据库...",done:"导入完成",error:"导入中断"},processed:"已处理 {count} 条消息",viewLog:"查看导入日志",cannotReadPath:"无法读取文件路径",preparing:"准备导入...",errors:{no_file_selected:"未选择文件",import_failed:"导入失败",unrecognized_format:"无法识别的文件格式",no_messages:"未解析到任何消息,请检查文件格式是否正确",actionHint:"你还可以尝试下方手动匹配或查看日志:"},diagnostics:{format:"检测格式:",received:"收到消息:",written:" / 写入:",skipped:" / 跳过:"},batch:{importing:"正在批量导入",progressCount:"第 {current} 个 / 共 {total} 个",cancel:"取消导入",waiting:"等待中",skipped:"已跳过",success:"导入成功",completed:"批量导入完成",summary:"成功 {success} 个,失败 {failed} 个,跳过 {cancelled} 个",view:"查看"},options:{title:"更多选项",mergeImport:"合并导入",mergeImportHint:"勾选后,多个文件将合并为一个聊天记录"},merge:{importing:"正在合并",parsing:"正在解析文件...",parsingFile:"正在解析: {name}",merging:"正在合并消息...",completed:"合并完成",completedHint:"{count} 个文件已合并",messageCount:"{count} 条消息",failed:"合并失败",cancel:"取消合并"}},demo:Ku,migration:Gu,chatSelector:Xu,formatSelector:Yu,quickStart:Qu,footer:Ju,changelog:Zu},tm={title:"群聊分析",loading:"加载分析数据...",loadError:"无法加载会话数据",description:"从 {startDate} 到 {endDate},你们共聊了 {messageCount} 条消息"},sm={title:"私聊分析",loading:"加载分析数据...",loadError:"无法加载会话数据",description:"从 {startDate} 到 {endDate},你们共聊了 {messageCount} 条消息"},am={overview:"总览",view:"洞察",ranking:"榜单",groupQuotes:"语录",quotes:"语录",members:"成员",member:"成员",ai:"AI实验室",aiChat:"AI对话",memory:"记忆",lab:"实验室",sqlLab:"SQL实验室",debug:"Debug"},nm={sqlTables:"SQL 表格",basicTools:"基础工具",tableBrowser:{chatDb:"聊天记录 DB",aiDb:"AI 对话 DB",selectTable:"选择表",rowCount:"共 {count} 行",page:"第 {current} / {total} 页",prevPage:"上一页",nextPage:"下一页",refresh:"刷新",noData:"暂无数据",editRow:"编辑行",deleteRow:"删除行",save:"保存",cancel:"取消",confirmDelete:"确认删除这行数据?",deleteSuccess:"删除成功",saveSuccess:"保存成功",operationFailed:"操作失败",allConversations:"全部对话",copyCell:"复制选中项",copyRow:"复制整行 (JSON)",clearDebugContext:"清除 Debug 上下文",confirmClearDebug:"确认清除所有消息的 debug_context 数据?此操作不可撤销。"}},om={comingSoon:"正在计划中,如果你对记忆功能有什么建议,欢迎加群讨论。",joinLink:"https://chatlab.fun/cn/other/community"},rm={allTime:"全部时间",year:"{year}年"},im={viewChatRecord:"查看聊天记录",sessionIndex:"会话索引",incrementalImport:"增量导入",memberManagement:"成员管理"},lm={title:"追加聊天记录",description:"选择要追加到「{name}」的聊天记录文件,系统会自动去重。",selectFile:"选择聊天记录文件",dropHint:"点击选择或拖拽文件到此处",analyzing:"正在分析文件...",totalInFile:"文件消息数",newMessages:"新增消息",duplicates:"重复消息",noNewMessages:"文件中没有新消息,所有消息都已存在",importing:"正在导入...",import:"确认导入 {count} 条消息",success:"导入成功",successDetail:"成功追加 {count} 条新消息",failed:"导入失败"},cm={view:{message:"消息",topic:"话题",interaction:"互动分析",groupRelationships:"群关系",ranking:"榜单",relationship:"关系",languagePreference:"语言偏好"},quotes:{wordcloud:"话题",hotRepeat:"最火复读",catchphrase:"口头禅",keywordAnalysis:"关键词分析",languagePreference:"语言偏好"},groupRelationships:{mentionGraph:"{'@'} 关系图",mentionRanking:"{'@'} 排行",proximity:"发言临近度"},member:{memberList:"成员列表",relationships:"群关系",cluster:"互动频率",nicknameHistory:"昵称变更"}},dm={messageTypeDistribution:"消息类型分布",memberDistribution:"成员消息占比",others:"其他人",messageRatio:"消息占比",messageUnit:"条",memberComparison:"双方消息占比",statCards:{dailyAvgMessages:"日均消息",messagesCount:"{count} 条",daysCount:"共 {count} 天",imageMessages:"图片消息",imagesCount:"{count} 张",peakHour:"最活跃时段:",mostActiveWeekday:"最活跃星期",messagesOnDay:"{count} 条消息",weekendActivity:"周末活跃度",weekendRatio:"周末消息占比",mostActiveDate:"最活跃日期",activeDays:"活跃天数",slashDays:"/ {count} 天",consecutiveStreak:"连续打卡",daysStreak:"{count} 天",longestStreak:"最长连续活跃",activityRate:"活跃率",activeDaysRatio:"有消息的天数占比",lateNightChat:"深夜聊天",lateNightRatio:"占总消息 {ratio}%"},dailyTrend:{title:"每日消息趋势"},identity:{privateChat:"私聊",groupChat:"群聊",analysisReport:"数据分析报告",totalMessages:"消息总数",durationDays:"跨度天数",activeDays:"活跃天数",dailyAvgMessages:"日均消息"},tools:"常用工具"},um={expand:"展开工具面板",collapse:"收起工具面板",lock:"锁定面板",unlock:"解锁面板",miniMode:"迷你模式",exitMini:"退出迷你模式"},mm={title:"导出聊天记录"},gm={title:"自定义筛选",conditionMode:"条件筛选",sessionMode:"会话筛选",history:"历史记录",execute:"开始筛选",export:"导出筛选结果",keywords:"关键词",keywordsHint:"支持多个关键词,或逻辑匹配",keywordPlaceholder:"输入关键词,回车添加",timeRange:"时间范围",allTime:"全部",today:"今天",lastWeek:"近7天",lastMonth:"近1个月",last3Months:"近3个月",lastYear:"近1年",customTime:"自定义",senders:"发送者",sendersHint:"可选,留空表示不限",searchMember:"搜索成员...",noMembers:"暂无成员",selectedCount:"已选择 {count} 位",contextSize:"上下文扩展",messages:"条消息",searchSession:"搜索日期...",selectedSessions:"已选择 {count} 个会话",noSessions:"暂无会话索引",filtering:"正在筛选...",emptyHint:"设置筛选条件后点击执行",noResults:"未找到匹配的消息",blockTitle:"对话块 {index}",stats:{blocks:"对话块",messages:"消息数",hits:"命中数",chars:"字符数"},historyTitle:"筛选历史",noHistory:"暂无历史记录",loadMore:"加载更多",allLoaded:"已加载全部",exportSuccess:"导出成功",exportFailed:"导出失败",exportPreparing:"正在准备导出..."},pm={groupChat:tm,privateChat:sm,tabs:am,debug:nm,memory:om,yearFilter:rm,tooltip:im,incremental:lm,subTabs:cm,overview:dm,toolsPanel:um,messageExport:mm,filter:gm},fm="管理",hm="聊天记录管理",vm={batchManage:"批量管理"},ym={title:"批量删除",description:"选择要删除的聊天记录",searchPlaceholder:"搜索对话名称",searchResult:"找到 {count} / {total} 个",noSearchResult:"未找到匹配的聊天记录",selectAll:"全选",shiftClickHint:"按住 Shift 点击可范围多选",selected:"已选 {count} 个",empty:"暂无聊天记录",delete:"删除选中",confirmTitle:"确认删除",confirmMessage:"确定要删除选中的 {count} 个聊天记录吗?此操作不可撤销。",deleting:"正在删除...",success:"成功删除 {count} 个聊天记录",error:"删除失败:{error}",messageCount:"{count} 条消息",importedAt:"导入于 {time}",columns:{name:"名称",platform:"平台",messages:"消息数",summaries:"AI摘要",aiChats:"AI 对话",importedAt:"导入时间"},clickToEdit:"点击编辑名称",merge:"合并选中",mergeHint:"选择 2 个以上同聊天类型的聊天记录才能合并",mergeConfirmTitle:"合并聊天记录",mergeConfirmMessage:"将合并选中的 {count} 个聊天记录,生成一条新的合并记录。",deleteOriginalsLabel:"合并后删除原聊天记录",mergeRiskWarning:"强提醒:删除后不可恢复,且由于跨平台上下文差异,聊天语义可能出现错位或混乱。请确认你已备份原始数据并理解风险。",mergeSteps:{exporting:"正在导出聊天记录...",parsing:"正在解析文件...",checking:"正在检测冲突...",merging:"正在合并数据...",cleaning:"正在清理临时文件..."},mergeSuccess:"成功合并 {count} 个聊天记录",mergeError:"合并失败:{error}",mergedSuffix:"合并"},bm={title:fm,description:hm,tabs:vm,batchManage:ym},_m={name:"DeepSeek",models:{"deepseek-v4-pro":"旗舰模型,1M 上下文,支持思考与非思考模式","deepseek-v4-flash":"高速模型,1M 上下文,支持思考与非思考模式"}},xm={name:"通义千问",models:{"qwen-turbo":"通义千问超大规模语言模型,速度快","qwen-plus":"通义千问超大规模语言模型,效果好","qwen-max":"通义千问千亿级别超大规模语言模型"}},km={name:"Gemini",models:{"gemini-3-flash-preview":"高速预览版","gemini-3-pro-preview":"专业预览版"}},wm={name:"MiniMax",models:{"MiniMax-M2":"旗舰模型","MiniMax-M2-Stable":"稳定版本"}},Sm={name:"GLM",models:{"glm-4-plus":"旗舰模型,效果最佳","glm-4-flash":"高速模型,性价比高","glm-4":"标准模型","glm-4v-plus":"多模态视觉模型","glm-4.6v-flash":"4.6V免费版模型","glm-4.5-flash":"4.5免费版模型"}},Cm={name:"Kimi",models:{"moonshot-v1-8k":"8K 上下文","moonshot-v1-32k":"32K 上下文","moonshot-v1-128k":"128K 超长上下文"}},Mm={name:"豆包",models:{"doubao-seed-1-6-lite-251015":"豆包1.6模型,性价比","doubao-seed-1-6-251015":"更强豆包1.6模型","doubao-seed-1-6-flash-250828":"更快的豆包1.6模型","doubao-1-5-lite-32k-250115":"豆包1.5Pro模型"}},Am={name:"硅基流动"},Tm={name:"Groq"},$m={name:"OpenRouter"},Im={name:"xAI"},Pm={deepseek:_m,qwen:xm,gemini:km,minimax:wm,glm:Sm,kimi:Cm,doubao:Mm,siliconflow:Am,groq:Tm,openrouter:$m,xai:Im,"openai-compatible":{name:"第三方服务"}},Dm={chatExplorer:"对话式探索",sqlLab:"SQL实验室",featureInDev:"{name}功能开发中",comingSoon:"敬请期待...",followNotice:"功能上线通知,欢迎关注我的小红书"},Lm={welcome:{configReady:"✅ AI 服务已配置,可以开始对话了!",configNeeded:"**注意**:使用前请先在侧边栏底部的「设置」中配置 AI 服务 ⚙️"},capture:"截屏对话",scrollToBottom:"返回底部",input:{placeholder:"输入你的问题...",placeholderWithSlash:"输入你的问题,或输入 / 选择技能、输入 {'@'} 选择成员...",placeholderWithActiveSkill:"已选择 /{name},请输入具体问题...",removeSkill:"移除当前技能",slashHint:"输入 / 选择技能",useSkill:"选择技能",mentionHint:"输入 {'@'} 选择成员",mentionEmpty:"没有匹配的成员",mentionEmptyHint:"可按昵称、别名或账号搜索",slashEmpty:"没有匹配的技能",slashEmptyHint:"打开技能管理导入内置技能,或创建一个自定义技能",manageSkills:"管理技能",previewTitle:"技能提示词",previewTagsLabel:"标签",previewToolsLabel:"工具",previewUnavailable:"暂无可预览的技能提示词",presetMore:"更多",presetCollapse:"收起",quickAsk:"快速提问",editQuickAsk:"编辑快速提问",send:"发送",needMoreThanSkill:"仅选择技能还不能发送,请继续输入具体问题",needQuestion:"请输入问题后再发送"},backgroundTask:{runningShort:"进行中",runningTitle:"AI 正在后台推理",runningDescription:"上一条问题仍在推理,请等待完成或先停止。",blockedAction:"当前回答仍在生成中,请先等待完成或手动停止。",return:"返回查看"},message:{userAvatar:"用户头像",calling:"调用",copy:{tooltip:"复制 Markdown",success:"Markdown 已复制到剪贴板",failed:"复制 Markdown 失败"},tools:{get_chat_overview:"获取聊天概览",search_messages:"搜索聊天记录",deep_search_messages:"深度搜索聊天记录",get_recent_messages:"获取最近消息",get_member_stats:"获取成员统计",get_time_stats:"获取时间分布",get_members:"获取成员列表",get_member_name_history:"获取昵称历史",get_conversation_between:"获取对话记录",get_message_context:"获取上下文",search_sessions:"搜索会话",get_session_messages:"获取会话消息",get_session_summaries:"获取会话摘要",response_time_analysis:"回复时间分析",keyword_frequency:"关键词频率分析",message_type_breakdown:"消息类型分布",peak_chat_hours_by_member:"成员活跃时段",member_activity_trend:"成员活跃趋势",silent_members:"沉默成员检测",reply_interaction_ranking:"回复互动排行",mutual_interaction_pairs:"互动频繁成员对",member_message_length_stats:"消息长度统计",daily_active_members:"每日活跃人数",conversation_initiator_stats:"话题发起者统计",activity_heatmap:"活跃度热力图",unanswered_messages:"未回复消息"},generating:"正在生成回复...",summary:{label:"上下文摘要",expand:"展开摘要",collapse:"收起摘要",info:"以上对话已被压缩为摘要以节省上下文空间"},think:{labels:{think:"已思考",analysis:"分析",reasoning:"推理",reflection:"反思",other:"思考({tag})"},loading:"思考中",duration:"耗时 {seconds}s"},toolParams:{keywords:"关键词",time:"时间",getMessages:"获取 {count} 条消息",limit:"限制 {count} 条",contextWithMessages:"{msgCount} 条消息的前后各 {contextSize} 条上下文",context:"前后各 {size} 条上下文",topMembers:"前 {count} 名成员",search:"搜索",getMemberList:"获取成员列表",memberId:"成员ID",timeStats:{hourly:"按小时",weekday:"按星期",daily:"按日期"}}},thinking:{processingResult:"处理结果中",called:"已调用:",analyzing:"正在分析问题...",compressing:"正在压缩上下文..."},statusBar:{preset:{default:"默认预设",groupTitle:"群聊提示词预设",privateTitle:"私聊提示词预设",manage:"管理提示词"},model:{title:"AI 模型配置",notConfigured:"AI 未配置",empty:"暂无配置",manage:"管理配置",switchFailed:"切换模型失败"},messageLimit:{label:"消息上限:",title:"每次发送的最大消息条数,点击配置"},agent:{label:"Agent",contextTokens:"上下文",stats:"段 {segment} · 标签 {tags}",phase:{compressing:"压缩上下文",preparing:"准备中",thinking:"思考中",tool_running:"调用工具",responding:"生成中",completed:"已完成",aborted:"已停止",error:"错误"},phaseShort:{compressing:"压缩",preparing:"准备",thinking:"思考",tool_running:"工具",responding:"生成",completed:"完成",aborted:"停止",error:"错误"}},tokenUsageTitle:"累计 Token 使用量",export:{label:"导出",title:"导出当前对话"},log:{label:"日志",title:"打开当前 AI 日志文件",openFailed:"打开日志失败",openFailedDesc:"请稍后重试"},compress:{label:"压缩",title:"手动压缩上下文",compressing:"正在压缩...",success:"上下文已压缩",successDesc:"{before} → {after} tokens",skipped:"跳过压缩",skippedDesc:"消息不足,无需压缩",failed:"压缩失败"},status:{connected:"AI 已连接",notConfigured:"请在全局设置中配置 AI 服务"}},conversation:{title:"AI对话记录",newChat:"新对话",newConversation:"新建对话",empty:"暂无历史记录",startNew:"开始新对话",titlePlaceholder:"输入标题...",group:{last7Days:"最近 7 天",last30Days:"最近 30 天"},rename:"重命名",delete:"删除",export:{createdAt:"创建时间",user:"用户",assistant:"AI 助手",noMessages:"对话没有消息"}},error:{title:"处理失败",detail:"错误详情",viewDetail:"查看详情",requestUrl:"请求路径",statusCode:"状态码",responseBody:"响应内容",responseHeaders:"响应头",requestBody:"请求体",name:"错误名称",message:"错误信息",stack:"堆栈信息",cause:"错误原因",provider:"服务商",copyAll:"复制全部",copied:"已复制到剪贴板",unknown:"未知错误"},dataSource:{title:"数据源",keywords:"关键词:",empty:"暂无数据",emptyHint:"发送问题后,相关记录会显示在这里",totalRecords:"共 {count} 条记录",loadMore:"加载更多"}},Em={editor:{errorEmptySQL:"请输入 SQL 语句",placeholder:"输入 SQL 查询语句...",promptTip:"用自然语言描述你的查询需求,系统会自动生成并执行 SQL",tip:"提示:双击左侧列名可插入到 SQL",history:"历史",aiGenerate:"AI 生成",generateAndRun:"生成并执行",switchToSQLMode:"切换为 SQL 输入模式",switchToPromptMode:"切换为 Prompt 输入模式",shortcut:"Ctrl/⌘ + Enter 执行",run:"运行"},schema:{tables:"数据表",doubleClickToInsert:"双击插入到 SQL",primaryKey:"主键"},result:{queryError:"查询错误",rows:"{count} 行",readableTime:"时间戳转日期",viewChat:"查看聊天记录",summarize:"总结一下",pageSize:"每页",pageInfo:"第 {current} / {total} 页",emptyResult:"查询结果为空",initialState:"输入 SQL 语句并运行查看结果",initialHint:"仅支持只读查询(SELECT / WITH),建议添加 LIMIT 以提升性能",summaryTitle:"AI 结果总结",analyzing:"AI 正在分析结果...",errorSummary:"总结失败"},generate:{title:"AI 生成 SQL",description:"用自然语言描述你想查询的内容,AI 将自动生成对应的 SQL 语句。",placeholder:"例如:查找发言最多的前 10 个成员、统计每天的消息数量、找出包含「买房」关键词的消息...",errorEmptyPrompt:"请输入查询需求",errorGenerate:"AI 生成失败",errorTokenLimit:"模型输出达到 token 上限,未能生成完整回复(可能思考消耗了过多 token)",aiOutput:"AI 输出",thinking:"思考中…",thinkingProcess:"思考过程",waitingAI:"等待 AI 响应...",sqlStatement:"SQL 语句",explanation:"说明",generateSQL:"生成 SQL",useSQL:"使用 SQL",run:"运行",defaultPromptPrivate:"请统计最近1年私聊中双方各自的:消息总数、消息占比、活跃天数、日均消息数(按活跃天计算)、首次发言时间、最近发言时间;按消息总数降序展示。",defaultPromptGroup:"请统计最近1年群聊中各成员的:消息总数、消息占比、活跃天数、日均消息数(按活跃天计算)、文本消息占比;显示成员名称并按消息总数降序,返回前20名。"},history:{title:"AI 生成历史",execute:"执行",empty:"暂无历史记录",justNow:"刚刚",minutesAgo:"{count} 分钟前",hoursAgo:"{count} 小时前",today:"今天"}},Rm={selector:{title:"选择一个助手开始对话",heroTitlePrefix:"使用",heroTitleSuffix:"开始对话",subtitle:"每个助手擅长不同类型的分析任务,选择最适合你需求的助手",noAssistants:"当前场景暂无可用助手",manage:"管理助手",addNew:"新增助手"},config:{viewTitle:"查看配置",createTitle:"新建助手",editTitle:"助手配置",betaWarning:"当前处于测试阶段,配置逻辑后续可能调整,请备份好提示词和相关配置。",tabs:{basic:"基础配置",tools:"工具管理"},name:"名称",systemPrompt:"系统提示词",chatType:"适用聊天类型",chatTypeAll:"全部",chatTypeGroup:"群聊",chatTypePrivate:"私聊",locale:"适用语言",localeHint:"不选 = 全语言",presetQuestions:"预设问题",addQuestion:"添加新问题...",builtinTools:"内置工具",coreTools:"核心工具",coreToolsHint:"基础数据获取工具,始终启用,不可关闭",analysisTools:"分析工具",analysisToolsHint:"按需开启的分析能力,勾选后才会对 AI 可用",selectAll:"全选",deselectAll:"全不选",builtinToolsHint:"不勾选任何工具 = 全部工具可用。勾选后仅开放已选工具。",toolGroupQuery:"数据查询工具",resetDefault:"恢复默认",create:"创建"},market:{title:"助手管理",tabs:{local:"本地助手",market:"助手市场"},localHint:"管理已导入的助手,可配置或删除",marketHint:"浏览助手市场,导入后即可使用和自由编辑",default:"默认",updateAvailable:"更新可用",reimport:"重新导入",imported:"已导入",import:"导入",importing:"导入中...",importSuccess:"导入成功",importFailed:"导入失败",viewConfig:"查看配置",duplicate:"复制",addAssistant:"新增助手",noLocal:"暂无已导入的助手",noCatalog:"暂无可用助手,请检查网络连接",loading:"加载中...",loadFailed:"加载失败,请检查网络连接",retry:"重试"},fallbackName:"助手",duplicateSuffix:"(副本)",toast:{loadFailed:"加载失败",createSuccess:"创建成功",createFailed:"创建失败",saveSuccess:"保存成功",saveFailed:"保存失败",resetSuccess:"已恢复默认",resetFailed:"恢复失败",unknownError:"未知错误"},builtinToolDesc:{get_chat_overview:"获取聊天概览信息",search_messages:"搜索聊天消息",deep_search_messages:"深度搜索聊天消息",get_recent_messages:"获取最近消息",get_message_context:"获取消息上下文",get_conversation_between:"获取两人对话",get_members:"获取成员列表",get_member_stats:"获取成员统计",get_member_name_history:"获取成员改名历史",get_time_stats:"获取时间统计",search_sessions:"搜索会话",get_session_messages:"获取会话消息",get_session_summaries:"获取会话摘要",message_type_breakdown:"消息类型分布",peak_chat_hours_by_member:"成员活跃时段",member_activity_trend:"成员活跃趋势",silent_members:"沉默成员检测",reply_interaction_ranking:"回复互动排行",mutual_interaction_pairs:"互动好友配对",member_message_length_stats:"消息长度统计",unanswered_messages:"未回复消息",daily_active_members:"每日活跃人数趋势",conversation_initiator_stats:"话题发起者统计",activity_heatmap:"活跃度热力图",response_time_analysis:"响应时间分析",keyword_frequency:"高频词统计"}},Nm={selector:{title:"选择技能",freeChat:"自由对话",freeChatDesc:"不使用预设技能,由 AI 自主回答",manage:"技能管理",incompatible:"与当前助手不兼容",noSkills:"暂无可用技能",noSkillsHint:"通过技能管理导入内置技能或创建自定义技能",autoSkill:"AI 自主选择技能",autoSkillHint:"开启后 AI 可根据问题自动选择合适的技能"},config:{createTitle:"新建技能",editTitle:"技能配置",name:"名称",description:"描述",tags:"标签",chatScope:"适用范围",chatScopeAll:"全部",chatScopeGroup:"群聊",chatScopePrivate:"私聊",prompt:"技能提示词",tools:"所需工具",rawEditor:"Markdown 编辑器",rawEditorHint:"直接编辑完整的技能 Markdown 文件(含 YAML frontmatter)",create:"创建",save:"保存"},market:{title:"技能管理",tabs:{local:"本地技能",market:"技能市场"},localHint:"管理已导入的技能,可配置或删除",marketHint:"浏览技能市场,导入后即可使用和自由编辑",updateAvailable:"更新可用",reimport:"重新导入",imported:"已导入",import:"导入",importing:"导入中...",importSuccess:"导入成功",importFailed:"导入失败",noLocal:"暂无已导入的技能",noCatalog:"暂无可用技能,请检查网络连接",addSkill:"新建自定义技能",loading:"加载中...",loadFailed:"加载失败,请检查网络连接",retry:"重试"},block:{label:"技能:{name}"},active:{label:"主动调用技能:{name}"},toast:{createSuccess:"技能创建成功",createFailed:"技能创建失败",saveSuccess:"技能保存成功",saveFailed:"技能保存失败",deleteSuccess:"技能已删除",deleteFailed:"删除失败"}},Fm={basicTools:"基础工具",toolTest:{selectTool:"选择工具",selectToolPlaceholder:"请选择一个工具...",coreTools:"核心工具",analysisTools:"分析工具",parameters:"参数",arrayPlaceholder:"多个值用逗号分隔",execute:"执行",cancel:"取消",elapsed:"耗时 {ms}ms",result:"执行结果",truncated:"结果过大,已截断显示。建议减小 limit 参数以获取完整数据。"}},Um={tab:Dm,chat:Lm,sqlLab:Em,assistant:Rm,skill:Nm,lab:Fm},Om={loading:"正在分析词频...",sidebar:{filter:"筛选配置",style:"样式设置"},stats:{messagesLabel:"消息数",wordsLabel:"总词数",uniqueLabel:"独立词",clickHint:"提示:点击词云可查看相关消息"},config:{maxWords:"显示词数",sizeScale:"字体大小",userFilter:"用户筛选",posFilter:"词性过滤",enableStopwords:"过滤停用词",dict:"分词词库",advanced:"高级设置"},size:{small:"小",medium:"中",large:"大",xlarge:"特大"},posFilter:{all:"全部词性",meaningful:"有意义",custom:"自定义",customHint:"自定义词性",selectMeaningful:"有意义",selectAll:"全选",clearAll:"清空"},empty:{title:"暂无词云数据",description:"当前筛选条件下没有足够的文本消息用于生成词云"},dict:{zhCN:"简体中文",zhTW:"繁体中文",download:"下载词库","download_zh-CN":"下载简体词库","download_zh-TW":"下载繁体词库",needDownload:"使用词云分析需要先下载分词词库",downloadHint:"~8MB",downloadSuccess:"词库下载成功",downloadFailed:"词库下载失败",promptTitle:"繁体中文词库",promptDescription:"检测到您使用繁体中文,词云分析需要繁体词库才能获得最佳效果。是否立即下载?(约 8MB)",promptDownload:"立即下载",promptLater:"稍后再说"}},Hm={title:"🔍 关键词排行",description:"分析群聊关键词使用排行,这里可以自定义多种榜单",countTemplate:"共 {count} 位成员",templateLabel:"模板:",newTemplate:"+ 新建",searchPlaceholder:"输入并搜索",clear:"清空",templateHint:"* 右键模板可编辑或删除",keyword:"关键词",ranking:"排行榜",multiColorMode:"多色模式",times:"{count}次",timesWithPercent:"次 ({percent}%)",loading:"正在分析数据...",empty:"暂无数据,请尝试添加关键词或切换模板",contextMenu:{edit:"编辑",delete:"删除"},modal:{createTitle:"创建模板",editTitle:"编辑模板",templateName:"模板名称",templateNamePlaceholder:"如:正能量",keywords:"关键词",keywordPlaceholder:"输入后回车添加",cancel:"取消",save:"保存",update:"更新"},templates:{laugh:{name:"含笑量",keywords:"哈哈,xswl,lol,笑死,233",description:"统计群内的快乐指数"},sad:{name:"沮丧量",keywords:"想死,难受,哭了,崩溃,裂开,无语,累了",description:"统计群内的负面情绪"},praise:{name:"捧哏",keywords:"牛逼,666,厉害,强,nb,大佬,羡慕,好强",description:"统计群内最会夸人的成员"},slacker:{name:"摸鱼",keywords:"摸鱼,下班,饿了,困了,不想上班,什么时候下班",description:"统计群内最想下班的打工人"},gossip:{name:"吃瓜",keywords:"吃瓜,细说,真的假的,展开说说,尊嘟假嘟,卧槽,离谱",description:"统计群内最爱吃瓜的成员"},polite:{name:"礼貌",keywords:"谢谢,麻烦,收到,好的,辛苦,打扰,请教",description:"统计群内最客气的成员"},curious:{name:"疑问",keywords:"为什么,啥,怎么,不懂,求教",description:"统计群内问题最多的成员"}}},Vm={title:"🔥 最火复读内容",loading:"正在加载复读数据...",description:"单次复读参与人数最多的内容",countTemplate:"共 {count} 条热门复读",people:"{count}人",times:"{count} 次",colon:":",viewChat:"查看聊天记录",empty:"暂无复读数据"},zm={dateAll:"全部消息",dateNow:"至今",heroPrefix:"共分析了",heroMiddle:"条消息,",heroMiddleSecond:"产生了",heroSuffix:"个不同词汇",topTopicsPrefix:"你们最爱聊:",topKeywords:"热门关键词",hotTopic:"热门话题",hotTopicDesc:"出现了 {count} 次",richness:"词汇丰富度",richnessValue:"{value}%",richnessDesc:"不重复词 {unique} / 总词数 {total}",chatStyle:"聊天风格",styleEncyclopedia:"百科全书型",styleEncyclopediaDesc:"名词占比高,爱聊人、地、事",styleAction:"行动派",styleActionDesc:"动词占比高,爱讨论做什么",styleExpressive:"表达派",styleExpressiveDesc:"形容词占比高,善于修饰表达",styleBalanced:"均衡型",styleBalancedDesc:"聊天内容多元,各类话题均衡",expressionStyle:"表达风格",expressionCasual:"简洁口语",expressionCasualDesc:"用词简短,轻松随意",expressionFormal:"正式书面",expressionFormalDesc:"用词考究,表达严谨",expressionMixed:"混合风格",expressionMixedDesc:"口语与书面兼顾",watermark:"话题画像 · Topic Profile",sharedTopics:"共同话题"},Bm={title:"💬 口头禅分析",loading:"正在分析口头禅数据...",description:"分析了 {count} 位成员的高频发言",countTemplate:"共 {count} 位成员",times:"{count}次",empty:{title:"暂无口头禅数据",description:"当前筛选条件下没有足够的重复发言用于生成词云"},stats:{phrasesLabel:"高频短语",totalLabel:"总使用次数",clickHint:"提示:点击可查看相关消息"},viewMode:{list:"列表",wordcloud:"词云"},phraseCount:"{count} 条口头禅",topN:"显示数量"},Wm={loading:"正在分析语言偏好...",empty:"暂无足够的文字消息进行语言分析",card:{sharedWordsLabel:"共同高频词",syncSubtext:"基于词性分布的说话方式相似度",warmthWarm:"暖",warmthCrisp:"干练",warmthBalanced:"自然",expressionLabel:"你们的表达充满了",diversityTitle:"词汇深度",diversityDesc:"不重复词汇占比",styleTitle:"聊天气质",styleDesc:"基于词性分布推导的表达风格",punctTitle:"标点性格",punctDesc:"最常用的标点风格",punctTopTitle:"标点符号 TOP5",punctTopDesc:"各自最常使用的标点符号",modalTopTitle:"语气词 TOP5",modalTopDesc:"各自最常使用的语气词",sharedWordsTitle:"共同高频词",sharedWordsDesc:"双方都高频使用的词汇",watermark:"语言偏好 · Language Preference",radarFactual:"事实性",radarActive:"行动感",radarDescriptive:"描述欲",radarAffable:"亲和力",radarIntense:"程度感",radarNoun:"名词",radarVerb:"动词",radarAdj:"形容词",radarModal:"语气词",radarAdv:"副词",topCatchphrases:"热门口头禅",languageProfiles:"语言画像"},catchphrasePK:{title:"口头禅 PK",sharedCount:"{count} 个共同口头禅",hint:"提示:点击可查看相关消息,粉框标记为共同口头禅"},pos:{title:"词性图谱",styleEncyclopedia:"百科全书派",styleAction:"行动派",styleExpressive:"感性派",styleBalanced:"均衡派"},modal:{title:"语气词画像",toneSoft:"软萌亲和",toneCurious:"好奇探索",toneCasual:"随和建议",toneCalm:"沉稳内敛",toneMixed:"多元风格",empty:"暂无语气词数据"},punctuation:{title:"标点性格",none:"无标点",personalityDeep:"深沉文学型",personalityPassionate:"情绪饱满型",personalityCurious:"好奇宝宝型",personalityCheerful:"心情愉悦型",personalityFreeflow:"意识流型",personalityPrecise:"严谨规范型",empty:"暂无标点数据"},sync:{title:"语言同频度",description:"基于词性分布的说话方式相似度",labelSoulmate:"灵魂伴侣",labelHighSync:"高度默契",labelUnique:"各有特色",labelDiverse:"风格迥异"}},jm={wordcloud:Om,keywords:Hm,hotRepeat:Vm,topicProfile:zm,catchphrase:Bm,languagePreference:Wm},qm={title:"选择你是谁",unset:"未设置",selectMember:"选择成员",currentOwner:"当前:{name}",hint:"1. 将会显示在聊天记录查看器中的右侧 2. AI对话中会标识你的身份"},Km={title:"成员管理",description:"共 {count} 位成员,可为成员添加别名备注或移除成员",searchPlaceholder:"搜索群昵称、账号名称、ID 或别名",noMatch:"没有找到匹配的成员",empty:"暂无成员数据",table:{accountName:"账号名称",groupNickname:"群昵称",messageCount:"消息数",customAlias:"自定义别名",actions:"操作"},aliasPlaceholder:"输入后回车添加",delete:"删除",mergeSelected:"合并选中",mergeSelectedCount:"已选 {count} 位成员",pagination:"显示 {start} - {end} 条,共 {total} 位成员",tip:"提示:添加别名可以更好地识别聊天记录中的对话对象,别名将用于搜索和 AI 分析中。",mergeModal:{title:"确认合并成员?",content:"将成员 {source}({sourceCount} 条消息)合并到 {target}({targetCount} 条消息)下。默认保留消息更多一方的名称。",hint:"合并后不可恢复,被合并成员的消息将全部归属到保留成员。",cancel:"取消",confirm:"确认合并"},modal:{title:"确认删除成员?",content:"即将删除成员 {name} 及其 {count} 条消息,此操作不可恢复。",cancel:"取消",confirm:"确认删除"}},Gm={note:"备注:QQ的旧版客户端支持导出聊天记录为txt版本,这个版本会获得最准确的昵称变更记录",title:"昵称变更记录",loading:"加载中...",hasChanges:"{count} 位成员曾修改过昵称",noChanges:"暂无成员修改昵称",current:"当前",empty:"该群组所有成员均未修改过昵称",loadingText:"正在加载昵称变更记录..."},Xm={loading:"正在分析 {'@'} 互动数据...",topMentioners:"📢 谁最喜欢 {'@'} 别人",totalMentions:"共 {count} 次 {'@'}",topMentioned:"🎯 谁最常被 {'@'}",popularMember:"群里的人气王",times:"次",oneWay:{title:"🐕 单向关注检测",description:"发现 {count} 对单向关注关系(一方 {'@'} 另一方占比 ≥80%)",neverRespond:"从不回应",reverse:"反向 {count} 次",ratio:"{value}% 单向"},twoWay:{title:"💕 双向奔赴检测",description:"发现 {count} 对互动频繁的 CP(互相 {'@'} 且平衡度 ≥30%)",interactions:"次互动",balance:"{value}% 平衡"},emptyTitle:"📱 {'@'} 互动分析",empty:"暂无 {'@'} 互动数据",modal:{title:"{name} 的 {'@'} 关系",topMentioned:"最常 {'@'} 的人",topMentioners:"最常 {'@'} TA 的人",timesCount:"{count} 次",close:"关闭"}},Ym={ownerSelector:qm,list:Km,nicknameHistory:Gm,relationships:Xm,private:{title:"对话成员",description:"共 {count} 位成员,可为成员添加别名备注用于搜索和 AI 分析",messageCount:"消息数",percentage:"占比 {value}%",customAlias:"自定义别名",aliasPlaceholder:"输入后回车添加别名",empty:"暂无成员数据",tipTitle:"提示",tipContent:"添加别名可以更好地识别聊天记录中的对话对象,别名将用于搜索和 AI 分析中。"}},Qm={title:"聊天记录查看器",loadedCount:"已加载 {count} 条消息"},Jm={loading:"加载中...",noMessages:"暂无消息",tryAdjustFilter:"尝试调整筛选条件",loadingMore:"加载更多...",scrollUpForMore:"↑ 向上滚动加载更多",scrollDownForMore:"↓ 向下滚动加载更多"},Zm={messageId:"消息 ID",memberNotSupported:"成员(暂不支持)",keywordsPlaceholder:"关键词,多个用逗号分隔,回车搜索",startDate:"起始日期",endDate:"结束日期",reset:"重置",filter:"筛选"},eg={timeline:"会话",noSessions:"暂无会话",generateSummary:"生成摘要",tooFewMessages:"消息太少"},tg="摘要生成失败",sg="未知错误",ag={title:"批量生成摘要",byRange:"按范围",byTime:"按时间",selectRange:"选择范围",rangeStart:"最早",rangeInfo:"约",sessionsUnit:"个会话",rangeEnd:"最近",timeRange:"选择时间范围",today:"今天",yesterday:"昨天",week:"最近7天",month:"最近30天",custom:"自定义",found:"找到",hasSummary:"个已有摘要",tooFewMessages:"个消息太少",pending:"待生成:",unit:"个",noPending:"没有可生成的会话",noSessions:"该时间范围内没有会话",checking:"检查中...",loading:"加载中...",progress:"进度",session:"会话",statusSuccess:"成功",statusSkipped:"跳过",statusFailed:"失败",success:"成功:",failed:"失败:",skipped:"跳过:",start:"开始生成",stop:"停止"},ng={viewContext:"查看上下文",contextTitle:"消息上下文(前后各10条)",noContext:"暂无上下文",replyTo:"回复"},og={title:"会话索引",subtitle:"用于聊天记录的时间线导航",notGenerated:"尚未生成会话索引",notGeneratedHint:"生成会话索引后,您可以在聊天记录查看器中使用时间线快速导航到不同的会话。",whatIsIt:"会话索引的作用:",benefit1:"根据消息时间间隔自动识别会话边界",benefit2:"在聊天记录查看器中提供时间线导航",benefit3:"为 AI 分析提供对话上下文理解能力",generated:"会话索引已生成",sessionCount:"共识别出 {count} 个会话",regenerateHint:"如果您调整了会话间隔阈值,可以重新生成索引。",generate:"生成索引",regenerate:"重新生成",generating:"生成中...",cancel:"取消"},rg={drawer:Qm,messageList:Jm,filter:Zm,timeline:eg,summaryFailed:tg,summaryUnknownError:sg,batchSummary:ag,messageItem:ng,sessionIndex:og},ig={title:"互动频率",rankingView:"排行视图",memberView:"成员视图",matrixView:"矩阵视图",modelSettings:"模型参数",lookAhead:"邻居数量",lookAheadDesc:"每条消息向后看几个发言者",decaySeconds:"时间衰减(秒)",decaySecondsDesc:"值越大,远距离消息权重越高",applySettings:"应用设置",noData:"暂无数据",selectMember:"选择成员",selectMemberHint:"请从左侧选择一个成员",msgCount:"发言数",relationCount:"关系数",relationsByIntimacy:"发言临近度排行",noRelations:"暂无关系数据",intimacy:"临近度",interactionRanking:"互动排行",score:"临近度",coOccurrence:"共现",times:"次",totalMembers:"群成员",totalMessages:"消息总数",involvedMembers:"参与成员",edgeCount:"关系数"},lg={typeDistribution:"消息类型分布",hourlyDistribution:"小时分布",weekdayDistribution:"星期分布",monthlyDistribution:"月份分布",yearlyDistribution:"年份分布",timeHeatmap:"时间热力图",heatmapHint:"展示聊天时间规律",calendarHeatmap:"消息日历",calendarHint:"每日消息分布",calendarTooltipMessages:"消息",lengthDetailTitle:"短消息分布 (1-25字)",lengthDetailHint:"逐字统计",lengthGroupedTitle:"长度区间分布",lengthGroupedHint:"每5字一组",noTextMessages:"暂无文字消息",noData:"暂无数据",profile:{totalMessages:"总消息",textMessages:"文字消息",avgLength:"平均长度",avgLengthUnit:"{count} 字/条",mediaRatio:"媒体占比",textExpression:"文字表达力",textExpressionDesc:"最长消息 {count} 字",mediaRichness:"媒体丰富度",shortMaster:"短消息达人",shortMasterDesc:"共 {count} 条 ≤5字",essayLover:"小作文爱好者",essayLoverDesc:"≥{threshold}字的消息",peakRecord:"巅峰记录",peakRecordDesc:"单日最多 {count} 条",topHours:"最活跃时段",images:"图片",emoji:"表情",voiceVideo:"语音/视频",typeDistribution:"消息类型",hourlyDistribution:"24h 活跃",watermark:"消息报告",heroLine1Prefix:"你们共留下了",heroLine1Suffix:"条消息",heroLine2Prefix:"每条平均",heroLine2Middle:"个字,其中",heroLine2Suffix:"是非文字消息"}},cg={mentionGraph:"艾特互动关系图",layout:"布局",circular:"环形",force:"力导向",directed:"有向",reset:"重置",graphHint:"共 {nodes} 位成员,{links} 条互动关系",noInteraction:"暂无艾特互动数据"},dg={loading:"正在分析关系动态…",noIndex:{title:"需要会话索引",description:"关系分析依赖会话索引数据,请先在总览页生成会话索引。"},empty:{title:"暂无关系数据",description:"当前时间范围内没有会话记录。"},overview:{title:"整体概览"},monthly:{title:"月度明细",totalSessionsPrefix:"共对话",totalSessionsSuffix:"次"},trend:{title:"主动性趋势",hint:"蓝色线为 {name} 的月度主动发起占比,50% 线为均衡基准"},hero:{monthPart:"{year}年{month}月",timeRange:{singleMonth:"在 {month} 中,",range:"在 {start} 至 {end} 期间,"},totalSessionsPrefix:"你们共进行了",totalSessionsSuffix:"次对话",initiativePrefix:"其中有",initiativeByPrefix:"的开场白由",initiativeBySuffix:"发起",initiateTimes:"次发起"},initiator:"发起话题",closer:"结束话题",closerTitle:"话题终结者",closerHint:"统计话题结束时最后发言的人。",initiated:"发起 {count} 次",closed:"结束 {count} 次",totalSessions:"共 {count} 次会话",times:"次",noActivity:"本月无互动",watermarkReport:"关系报告",monthFormat:"{year}年{month}月",monthShortFormat:"{month}月",monthDetail:"发起 {init} / 结束 {close}",iceBreaker:{title:"破冰达人",hint:"超过 24 小时沉默后主动打破僵局的次数",count:"{count} 次破冰",total:"共 {count} 次破冰"},responseLatency:{title:"回复速度",hint:"当对方发来消息后,平均多久回复",count:"{count} 次回复",seconds:"{n} 秒",minutes:"{n} 分钟",minutesSeconds:"{m}分{s}秒",hours:"{n} 小时",hoursMinutes:"{h} 小时 {m} 分钟"},perseverance:{title:"锲而不舍",hint:"对方还没回复就又发了一条消息的次数",hintWithThreshold:"对方{threshold}内还没回复就又发了一次消息的次数",thresholdMinutes:"{n}分钟",count:"{count} 次",total:"共 {count} 次",threshold:"间隔",empty:"在当前阈值下没有锲而不舍的记录"},labels:{mutualPursuit:"双向奔赴",silentGuardian:"默默守候",devotedHeart:"一往情深",distantBond:"若即若离",wellMatched:"势均力敌",missingYou:"{name} 在想念",monologue:"{name} 的独白",peacefulSilence:"各自安好",fleetingThoughts:"偶尔想起"}},ug={title:"时间线视图",description:"消息时间分布、活跃周期变化趋势等可视化内容"},mg={rankListPro:{fullRanking:"完整排行",memberCount:"共 {count} 位成员"},rankList:{unit:"条"},nicknameHistory:{periodToNow:"{start} ~ 至今",periodRange:"{start} ~ {end}",current:"当前",empty:"暂无昵称记录"},listPro:{countTemplate:"共 {count} 项",fullRanking:"完整排行",empty:"暂无数据"}},gg={cluster:ig,message:lg,interaction:cg,relationship:dg,timeline:ug,charts:mg},pg="关键词过滤",fg="方案列表",hg="方案名称",vg="请输入方案名称",yg="新方案",bg="新建方案",_g="删除方案",xg="设为默认",kg="默认方案",wg="关键词过滤",Sg="不过滤",Cg="管理方案",Mg="添加过滤词",Ag="输入词语后回车添加,支持空格或逗号分隔批量添加",Tg="添加",$g="过滤词列表",Ig="清空全部",Pg="暂无方案,点击 + 新建",Dg="暂无过滤词,在上方输入框添加",Lg="选择或创建一个过滤方案",Eg="已过滤 {count} 个词",Rg="关闭",Ng={title:pg,schemeList:fg,schemeName:hg,schemeNamePlaceholder:vg,defaultSchemeName:yg,createScheme:bg,deleteScheme:_g,setDefault:xg,isDefault:kg,filterScheme:wg,noFilter:Sg,manage:Cg,addWords:Mg,addWordsPlaceholder:Ag,add:Tg,wordList:$g,clearAll:Ig,emptyScheme:Pg,emptyWords:Dg,selectOrCreate:Lg,activeCount:Eg,close:Rg},Fg={common:gu,layout:Iu,settings:Wu,home:em,analysis:pm,tools:bm,providers:Pm,ai:Um,quotes:jm,members:Ym,records:rg,views:gg,wordFilter:Ng},Ug="OK",Og="Cancel",Hg="Save",Vg="Edit",zg="Add",Bg="Rename",Wg="Capture",jg="Close",qg="Back",Kg="Done",Gg="Retry",Xg="Loading...",Yg="Initializing...",Qg="No data",Jg="No results found",Zg="Export successful",ep="Export failed",tp="Generating...",sp="Regenerate",ap="Open Folder",np="Please configure AI service in Settings first",op="Reset",rp={general:"Operation failed, please try again",network:"Network error",unknown:"Unknown error"},ip={image:"Image",video:"Video",audio:"Audio",file:"File",sticker:"Sticker",link:"Link"},lp={messages:"messages",members:"members",days:"days"},cp={text:"Text",image:"Image",voice:"Voice",video:"Video",file:"File",emoji:"Emoji",link:"Link",location:"Location",redPacket:"Red Packet",transfer:"Transfer",poke:"Poke",call:"Call",share:"Share",reply:"Reply",forward:"Forward",contact:"Contact",system:"System",recall:"Recalled",other:"Other",unknown:"Unknown"},dp={mon:"Mon",tue:"Tue",wed:"Wed",thu:"Thu",fri:"Fri",sat:"Sat",sun:"Sun"},up={jan:"Jan",feb:"Feb",mar:"Mar",apr:"Apr",may:"May",jun:"Jun",jul:"Jul",aug:"Aug",sep:"Sep",oct:"Oct",nov:"Nov",dec:"Dec"},mp={title:"Select Language",subtitle:"Choose your preferred interface language",next:"Next"},gp={title:"Privacy Policy & User Agreement",subtitle:"Please read carefully before use",disagree:"I Disagree",agree:"I Have Read and Agree",updateNotice:"The agreement has important updates. Please read and confirm again."},pp={selectDate:"Select Date",clearDate:"Clear"},fp={mode:{recent:"Recent",quarter:"Quarter",year:"Year",custom:"Custom"},recent:{halfYear:"Last 6M",oneYear:"Last 1Y",twoYears:"Last 2Y",fiveYears:"Last 5Y",all:"All"},display:{recent180:"Last 6 months",recent365:"Last 1 year",recent730:"Last 2 years",recent1825:"Last 5 years"},quarter:{label:"{year} Q{quarter}"},year:{label:"{year}"}},hp={allMembers:"All Members"},vp={confirm:Ug,cancel:Og,delete:"Delete",save:Hg,edit:Vg,add:zg,rename:Bg,capture:Wg,close:jg,back:qg,done:Kg,retry:Gg,loading:Xg,initializing:Yg,noData:Qg,noResults:Jg,export:"Export",exportSuccess:Zg,exportFailed:ep,generating:tp,regenerate:sp,openFolder:ap,errorNoAIConfig:np,reset:op,error:rp,attachment:ip,unit:lp,messageType:cp,weekday:dp,month:up,languageSelect:mp,agreement:gp,datePicker:pp,timeSelect:fp,userSelect:hp},yp="ChatLab",bp="New Analysis",_p="Tools",xp="Chat History",kp="Manage",wp="No records",Sp="Search conversation name",Cp="No matching chat records found",Mp={rename:"Rename",pin:"Pin",unpin:"Unpin",delete:"Delete"},Ap={title:"Rename",placeholder:"Enter new name"},Tp={title:"Confirm Delete",message:'Are you sure you want to delete "{name}"? This action cannot be undone.'},$p={all:"All",private:"Private",group:"Group"},Ip={importedAt:"Import Time",lastMessageTs:"Last Message",messageCount:"Message Count"},Pp={expand:"Expand sidebar",collapse:"Collapse sidebar",hint:"Right-click to rename or delete",search:"Search chat records",sort:"Sort"},Dp="{count} messages",Lp={helpAndFeedback:"Help & Feedback",settings:"Settings"},Ep={brand:yp,newAnalysis:bp,tools:_p,chatHistory:xp,manage:kp,noRecords:wp,searchPlaceholder:Sp,noSearchResult:Cp,contextMenu:Mp,renameModal:Ap,deleteModal:Tp,filter:$p,sort:Ip,tooltip:Pp,sessionInfo:Dp,footer:Lp},Rp="Settings",Np={basic:"General",ai:"AI Settings",aiConfig:"Model Service",aiDefaultModel:"Default Model",aiPrompt:"Chat Config",aiPreprocess:"Preprocess",dataManage:"Data Management",storage:"Storage",storageManage:"Storage",sessionManage:"Session Index",about:"About",api:"Automation",apiSubTabs:{autoSync:"Auto Sync",apiService:"API Service",mcp:"MCP"}},Fp={general:{title:"General"},preferences:{title:"Preferences"},language:{title:"Language",description:"Choose language"},appearance:{title:"Appearance",themeMode:"Theme Mode",auto:"System",light:"Light",dark:"Dark"},defaultTab:{title:"Default Tab",description:"Default page when entering a chat conversation",overview:"Overview",aiChat:"AI Chat"},autoLaunch:{title:"Startup",openAtLogin:"Launch at Login",openAtLoginDesc:"Automatically start ChatLab when the system boots",devModeHint:"Not available in dev mode"},toolsPanel:{positionLabel:"Tools Panel Position",positionDesc:"Choose where the quick tools panel appears",positionSide:"Side",positionHeader:"Header"},screenshot:{title:"Screenshot",mobileAdapt:"Mobile Adaptation",mobileAdaptDesc:"Auto-scale width when taking screenshots for mobile viewing"},network:{title:"Network",proxyMode:"Proxy Mode",proxyModeDesc:"How to connect when accessing external services",modeOff:"Off",modeSystem:"System",modeManual:"Manual",proxyAddress:"Proxy Address",proxyPlaceholder:"http://127.0.0.1:7890",proxyHelp:"Supports HTTP/HTTPS proxy, e.g.: http://127.0.0.1:7890",testConnection:"Test Connection",testing:"Testing...",connectionSuccess:"Proxy connection successful!",connectionFailed:"Connection failed",enterProxyFirst:"Please enter proxy address first",invalidProxyUrl:"Please enter a valid proxy address, e.g. http://127.0.0.1:7890",onlyHttpSupported:"Only http:// or https:// protocols are supported",saveFailed:"Save failed"}},Up={title:"Default Model",noConfigs:'Please add a model configuration in "Model Service" first',selectProvider:"Select provider",selectModel:"Select model",assistantModel:{label:"Default Assistant Model",description:"Used for AI chat, tool calls, SQL assistant, and context compression"},fastModel:{label:"Fast Model",description:"Used for session summary generation. Falls back to the default assistant model if not set",followAssistant:"Follow default assistant model"}},Op={title:"Model Services",providerTitle:"Service Providers",loading:"Loading...",inUse:"Active",defaultModel:"Default Model",localService:"Local Service",edit:"Edit",delete:"Delete",empty:{title:"No AI service configured",description:"Add a configuration to start using AI features"},addConfig:"Add New Service",maxConfigs:"Maximum configurations reached (10)",modal:{addConfig:"Add New Service",editConfig:"Edit Service",officialApi:"Official API",officialApiDesc:"DeepSeek, Gemini, etc.",localService:"Local Service",localServiceDesc:"Ollama, etc.",openaiCompatible:"OpenAI Compatible",openaiCompatibleDesc:"Custom endpoint",configName:"Configuration Name",optional:" (Optional)",configNamePlaceholderPreset:"Leave empty to use provider name",configNamePlaceholderCustom:"Leave empty to use API endpoint",aiProvider:"AI Provider",apiKeyPlaceholder:"Enter your API Key",apiKeyPlaceholderEdit:"Enter new API Key (leave empty to keep current)",apiKeyPlaceholderLocal:"Usually not required for local services",apiKeyHintLocal:"Enter if the service requires authentication",validate:"Validate",validationSuccess:"Connection validated successfully",validationFailed:"Connection validation failed",validationFailedTitle:"API Connection Validation Failed",saveAnywayHint:"Validation did not pass. The configuration may be incorrect. Save anyway?",saveAnyway:"Save Anyway",validationError:"Validation failed: ",model:"Model",modelName:"Model Name",modelNamePlaceholder:"e.g. gpt-4, claude-3",modelNamePlaceholderLocal:"e.g. qwen3, deepseek-r1",modelNameHint:"Enter the model name supported by the API",modelNameHintLocal:"Enter the locally deployed model name",apiEndpoint:"API URL",apiEndpointHint:"OpenAI-compatible API endpoint",resolvedUrl:"Resolved URL:",fetchModels:"Fetch from API",fetchModelsTitle:"Browse Remote Models",fetchModelsLoading:"Fetching model list...",fetchModelsEmpty:"No models found",fetchModelsError:"Failed to fetch models",fetchModelsCount:"{total} models total, showing {shown}",modelAdded:"Added",addAllModels:"Add all",searchModels:"Search models...",apiEndpointOverrideHint:"Default URL is prefilled. Replace if needed",disableThinking:"Disable Thinking Mode",disableThinkingDesc:"For models like Qwen3, DeepSeek-R1. Uses standard tool calling format when disabled.",isReasoningModel:"Reasoning Model",isReasoningModelDesc:"Extracts thinking process and disables tool calling (e.g. DeepSeek-R1, QwQ)",advancedOptions:"Advanced Options",customService:"Custom Service",unnamedConfig:"Unnamed Configuration",visitWebsite:"Visit Website",getApiKey:"Get API Key",presetService:"Preset",thirdPartyService:"Third-party",customModelInput:"Enter model manually",selectFromList:"Select from list",addCustomModel:"Add Model",deleteCustomModel:"Delete Selected",customModelId:"Model Endpoint Name",customModelIdHint:"The model identifier used in API calls",customModelDisplayName:"Display Name",customModelDisplayNamePlaceholder:"Custom display name",editModel:"Edit Model",contextWindow:"Context Window",contextWindowPlaceholder:"e.g. 128000",contextWindowHint:"Maximum context tokens supported by this model (used for context compression)",contextWindowMissing:'Context window not set, will use default. Click "Edit Model" to set it manually',modelRequired:"Add at least one model to save",modelCapabilities:"Model Capabilities",apiFormat:"API Format",apiFormatOpenAI:"OpenAI Completions",apiFormatAnthropic:"Anthropic",apiFormatGemini:"Gemini",apiFormatOpenAIResponses:"OpenAI Responses"},providerKind:{official:"Official",aggregator:"Aggregator",custom:"Custom"},capabilities:{chat:"Chat",reasoning:"Reasoning",vision:"Vision",function_calling:"Function Calling",embedding:"Embedding",ranking:"Ranking"}},Hp={title:"Local Storage Management",description:"Manage data files stored locally by ChatLab",dataLocation:{title:"Data Directory",description:"Customize where local data and cache are stored",choose:"Choose",reset:"Reset",open:"Open",migrateHint:"Data is still at a legacy location. Migrate to the unified directory:",migrateAction:"Migrate Now",restartTip:"Please restart the app after switching. Data will be migrated from the old directory.",confirmTitle:"Confirm Directory Change",confirmMessage:"You are about to change the data storage location. Existing data will be migrated to the new directory.",newPath:"New directory path",defaultPath:"Default location",confirmWarning:"After restarting, the old data directory will be automatically deleted. Please ensure the new path is correct.",installDirForbidden:"Data directory cannot be placed inside the app installation directory, as it will be cleared during updates",cancel:"Cancel",confirm:"Confirm",migrationSuccessTitle:"Migration Complete",migrationSuccessMessage:"The app needs to restart for changes to take effect.",relaunchNow:"Restart Now"},openRootDir:"Open Root",totalUsage:"Total: ",loading:"Loading...",files:"files",notExist:"Not exist",clear:"Clear",open:"Open",cache:{databases:{name:"Chat Databases",description:"Imported chat analysis data"},ai:{name:"AI Chat Databases",description:"AI chat history and config files"},downloads:{name:"Downloads",description:"Screenshots, analysis results, etc."},statsCache:{name:"Cache Data",description:"Statistics cache for chat records, auto-rebuilt after clearing"},logs:{name:"Log Files",description:"App logs including import, AI, error logs"}}},Vp={session:{title:"Session Index Settings",description:"Session index splits chat history into conversation segments by time gaps for better AI analysis",defaultThreshold:"Default Gap Threshold",thresholdUnit:"minutes",thresholdHelp:"Messages exceeding this time gap will be split into a new session",notGenerated:"Session index not generated",generateHint:"Generate index to help AI better understand conversation context",generate:"Generate Index",regenerate:"Regenerate",generating:"Generating",sessionCount:"{count} sessions",generated:"Session index generated",generateSuccess:"Session index generated successfully, {count} sessions created",generateError:"Generation failed",batchTitle:"Batch Generate Index",totalSessions:"{count} chats total",generatedCount:"{count} generated",notGeneratedCount:"{count} not generated",loadingStatus:"Loading...",batchGenerate:"Generate Missing",batchRegenerate:"Regenerate All",summaryStrategy:"Summary Detail Level",summaryStrategyHelp:"Controls how detailed AI-generated summaries will be",summaryBrief:"Brief",summaryStandard:"Standard"}},zp={chatSettings:{title:"Tool Settings"},exportSettings:{title:"Export Settings"},skillSettings:{title:"Skill Settings",enableAutoSkill:"AI Auto-Select Skills",enableAutoSkillDesc:"When enabled, AI will automatically match and activate suitable analysis skills based on user queries; when disabled, skills only take effect when manually selected"},maxMessages:{title:"Max Messages per Request",description:"Max number of messages sent to AI per request. Higher values consume more tokens but provide more accurate context (recommended: 2000)."},searchContext:{title:"Search Context Window",description:"Automatically include surrounding messages for each search hit to help AI understand the context. Set to 0 to disable",before:"Before",after:"After"},exportFormat:{title:"Export Format",description:"File format for exporting AI conversations",txtLabel:"TXT"},sqlExportFormat:{title:"SQL Lab Export Format",description:"File format for exporting SQL query results"},compression:{title:"Context Compression",enable:"Auto-compress context",enableDesc:"Automatically compress long conversation history into summaries to reduce token usage",threshold:"Compression threshold",thresholdDesc:"Trigger compression when context tokens reach this percentage of the model's context window",buffer:"Buffer size",bufferDesc:"Percentage of recent messages to keep uncompressed",maxToolResultPercent:"Tool result limit",maxToolResultPercentDesc:"Maximum data percentage per tool call sent to AI (based on model context window). Excess results are intelligently truncated"},presets:{title:"System Prompts",add:"Add Preset",import:"Import Presets",description:"Prompts are used for both group and private chat analysis, system adjusts content based on analysis type"},preset:{builtIn:"Built-in",groupOnly:"Group Only",privateOnly:"Private Only",view:"View",edit:"Edit",copy:"Copy",delete:"Delete"},modal:{editBuiltin:"Edit System Prompt",editCustom:"Edit Custom Prompt",addCustom:"Add Custom Prompt",presetName:"Preset Name",presetNamePlaceholder:"Give your preset a name",applicableTo:"Applicable To",applicableToHint:" (Check to enable for corresponding analysis type)",groupChat:"Group Chat",privateChat:"Private Chat",systemPrompt:"System Prompt",systemPromptPlaceholder:"Define the AI assistant's role, tasks and response requirements...",preview:"Full Prompt Preview",previewHint:" (Preview shows group chat mode, actual will adjust based on analysis type)",resetToDefault:"Reset to Default",saveChanges:"Save Changes",addPreset:"Add Preset"},importPreset:{title:"Import Presets",description:"Get recommended system prompt presets from remote",loading:"Loading remote presets...",loadError:"Failed to load remote presets",noPresets:"No remote presets available",commonPresets:"Universal Presets",groupPresets:"Group Chat Only",privatePresets:"Private Chat Only",add:"Add",added:"Added",preview:"Preview",systemPrompt:"System Prompt",noDescription:"No description",fetchingContent:"Loading content...",fetchError:"Failed to load content"}},Bp={title:"About ChatLab",description:"Chat records analysis tool",version:"Version",checkUpdate:"Check for Updates",checking:"Checking...",upToDate:"You are up to date",newVersionAvailable:"New version {version} available",updateNow:"Update Now",webUpdateHint:"Run npm install -g chatlab-cli@latest in your terminal, then restart the service.",updating:"Updating...",updateSuccess:"Update successful, please restart the service to apply",updateFailed:"Update failed: {error}",updateCheckFailed:"Update check failed: {error}",unknown:"Unknown",privacy:{title:"Privacy Settings",analytics:"Anonymous Usage Statistics",analyticsDesc:"When enabled, the app collects non-sensitive data like version number and OS version to help improve the product"},developer:{title:"Developer Options",debugMode:"DEBUG Mode",debugModeDesc:"When enabled, the debug panel and quick debugging tools will be shown. You can use them to view databases, run testing tools, and record more detailed debug logs."}},Wp={title:"Chat Preprocessing",description:"Preprocess chat records before sending to AI to save tokens and filter noise. Original data is not modified.",dataCleaning:"Data Cleaning",dataCleaningDesc:"Automatically clean XML card messages (shared links, mini-programs, etc.), extracting useful content and significantly saving tokens. Recommended to keep enabled.",mergeConsecutive:"Merge Consecutive",mergeConsecutiveDesc:"Merge consecutive messages from the same sender within a short time window",mergeWindow:"Merge window (seconds)",denoise:"Smart Denoise",denoiseDesc:"Filter out meaningless messages like interjections, emojis, and system placeholders (e.g. [Image])",desensitize:"Data Masking",desensitizeDesc:"Replace sensitive information (phone numbers, emails, ID numbers, etc.) based on rules",desensitizeRules:"Masking Rules",desensitizeRulesDesc:"Check the rules to enable. Rules are matched in list order",desensitizeBuiltin:"Built-in Rules",desensitizeCustom:"Custom Rules",desensitizeAddCustom:"Add Custom Rule",desensitizeRuleName:"Rule Name",desensitizeRulePattern:"Regex Pattern",desensitizeRuleReplacement:"Replacement Text",desensitizeRuleAdd:"Add",desensitizeRuleInvalidRegex:"Invalid regex syntax",desensitizeRuleNamePlaceholder:"e.g. Employee ID",desensitizeRulePatternPlaceholder:"e.g. EMP-\\d+",desensitizeRuleReplacementPlaceholder:"Replacement, e.g. [EmpID]",anonymizeNames:"Anonymize Nicknames",anonymizeNamesDesc:"Replace real nicknames with IDs (U1, U2…) when sending to AI, reducing hallucinations and saving tokens",blacklist:"Blacklist Keywords",blacklistDesc:"Messages containing any of these keywords will be filtered out entirely",blacklistPlaceholder:"Type a keyword and press Enter to add",blacklistAdd:"Add"},jp={rules:{cn_phone:"China Mobile Number",cn_phone_desc:"11-digit starting with 1xx",cn_id_card:"China ID Card Number",cn_id_card_desc:"18-digit, may end with X",cn_bank_card:"China Bank Card Number",cn_bank_card_desc:"16-19 consecutive digits",cn_landline:"China Landline Number",cn_landline_desc:"Area code + number, e.g. 010-12345678",us_ssn:"US Social Security Number (SSN)",us_ssn_desc:"XXX-XX-XXXX format",us_phone:"US Phone Number",us_phone_desc:"+1 (XXX) XXX-XXXX format",us_drivers_license:"US Driver's License",us_drivers_license_desc:"Letter + 7-8 digits",jp_phone:"Japan Phone Number",jp_phone_desc:"0x0-XXXX-XXXX format",jp_my_number:"Japan My Number",jp_my_number_desc:"12-digit number (マイナンバー)",kr_phone:"Korea Phone Number",kr_phone_desc:"01X-XXXX-XXXX format",kr_rrn:"Korea Resident Registration Number",kr_rrn_desc:"XXXXXX-XXXXXXX format (주민번호)",api_key_prefix:"API Key / Token (Known Prefixes)",api_key_prefix_desc:"Strings starting with sk-, ghp_, AKIA, etc.",bearer_token:"Bearer Token",bearer_token_desc:"Authorization token after Bearer",email:"Email Address",email_desc:"Standard user{'@'}domain.com format",credit_card:"Credit Card Number",credit_card_desc:"Visa / MasterCard / AmEx card numbers",ipv4:"IPv4 Address",ipv4_desc:"e.g. 192.168.1.1",url:"URL Link",url_desc:"Links starting with http:// or https://"}},qp={betaWarning:"The current API version is in Beta, and endpoints may change at any time.",service:{title:"API Service",enable:"Enable API Service",enableDesc:"When enabled, external tools can query, export, and import chat data via HTTP API. Localhost only (127.0.0.1)",portInUseHint:"Port is in use. Please change the port below or close the program using this port"},status:{running:"Running",stopped:"Stopped",starting:"Starting...",portInUse:"Port in use",error:"Failed to start"},port:{title:"Port Configuration",label:"Listen Port",desc:"Local port for the API service (1024-65535)",edit:"Edit",save:"Save",cancel:"Cancel"},token:{title:"Access Token",label:"Bearer Token",desc:"All API requests must include this token in the Authorization header",noToken:"No token generated yet. Please enable the service first",regenerate:"Regenerate"},dataSources:{title:"Data Sources",desc:"Configure external data source URLs. ChatLab will automatically pull and import chat data at the specified interval.",empty:"No data sources",noSessions:'No import sessions. Click "Manage Sessions" above to add.',disabled:"Paused",every:"Every",minutes:"min",lastSync:"Last sync",syncing:"Syncing",messages:"messages",addBtn:"Add Data Source",form:{modalTitle:"Add Data Source",name:"Name",namePlaceholder:"e.g., My Chat Server",url:"Data Source URL",token:"Access Token (optional)",tokenPlaceholder:"Bearer Token for the remote API",interval:"Pull Interval (minutes)",pullLimit:"Messages per Pull",pullLimitPlaceholder:"Default 1000",targetSession:"Target Session ID (optional)",targetSessionPlaceholder:"Leave empty to create new session each time",add:"Add"},discovery:{directMode:"Direct URL",remoteMode:"Remote Server",baseUrl:"Server URL",baseUrlPlaceholder:"e.g. http://127.0.0.1:2333/api/v1",browse:"Browse Sessions",found:"Found {count} sessions",search:"Search",searchPlaceholder:"Search by session name",selectAll:"Select All",deselectAll:"Deselect All",selectByType:"Session type",typeAll:"All",typePrivate:"Private",typeGroup:"Group",typeOther:"Other",loadMore:"Load More",subscribe:"Subscribe {count} sessions",messages:"messages",error:"Failed to connect to remote server",connectionCheckFailed:"Cannot connect to the remote server. Please check the URL and token."},edit:{title:"Edit Data Source",save:"Save",cancel:"Cancel",editSource:"Edit Config",manageSessions:"Manage Subscriptions",manageSessionsDesc:"Re-select remote sessions to sync",syncAll:"Sync All",subscribed:"Subscribed"},deleteConfirm:{title:"Delete Data Source",message:'Are you sure you want to delete "{name}"? All import configurations under this data source will be removed. Already imported local conversations will not be deleted.'},deleteSessionConfirm:{title:"Delete Subscription",message:'Are you sure you want to delete "{name}"?',keepData:"Remove subscription only",deleteData:"Also delete imported chats"}},usage:{title:"Usage Guide",desc:"After enabling the service, external tools can query data or push chat records to ChatLab via API. All requests require Bearer Token authentication.",authHint:"Header example:",docLink:"View full API documentation"}},Kp={overview:{title:"MCP Overview",description:"MCP lets AI assistants directly query your chat records. Supports session discovery, keyword search, member stats, time distribution, and more.",toolCount:"{count} tools",resourceCount:"{count} resources",installHint:"Install chatlab-cli, then add the config below to your AI client:"},clients:{other:"Other"},config:{title:"Client Configuration",clientLabel:"MCP Client",copy:"Copy",copied:"Copied",claudeHint:"Add this config to ClaudeCode's MCP configuration.",codexHint:"Add this TOML config to your ~/.codex/config.toml file.",openclawHint:"Add this config to your project's openclaw.json file.",otherHint:"Add this JSON config to your MCP client configuration file."},tips:{title:"Tips",dataDir:"The MCP server reads chat data from ~/.chatlab/, sharing the same data as the desktop app.",readOnly:"All operations are read-only and will not modify your chat records.",nodeRequired:"npx and CLI modes require Node.js 20 or higher.",docs:"For detailed documentation, visit docs.chatlab.fun."}},Gp={title:Rp,tabs:Np,basic:Fp,defaultModel:Up,aiConfig:Op,storage:Hp,ai:Vp,aiPrompt:zp,about:Bp,aiPreprocess:Wp,desensitize:jp,api:qp,mcp:Kp},Xp="Explore New Chat Memories",Yp={file:"File Import",api:"Auto Sync",push:"API Import",apiDescription:"Connect external platform data sources to automatically sync chat records to ChatLab on a schedule.",apiButton:"Configure Auto Sync",pushDescription:"Start the local API server to let third-party tools, plugins, or scripts push chat records directly into ChatLab.",pushButton:"Configure API Server"},Qp={viewExample:"Try a Demo",downloading:"Downloading demo data...",importing:"Importing demo data...",failed:"Failed to load demo data. Please check your network and try again."},Jp={title:"Database upgrade required",description:"{count} database(s) need to be upgraded for new features.",note:"The upgrade usually takes only a few seconds and won't lose any data.",upgradeContent:"Upgrade content:",upgradeNow:"Upgrade Now",upgrading:"Upgrading...",failed:"Migration failed",partialFailed:"Some databases failed to upgrade",errorHint:"This is usually caused by corrupted database files. Please delete the failed sessions from the sidebar and re-import them.",close:"Close",retry:"Retry"},Zp={title:"Select chats to import",scanning:"Scanning chat list...",scanFailed:"Scan failed",retry:"Retry",selectAll:"Select all",chatCount:"{count} chats",selected:"{count} selected",messageCount:"{count} messages",import:"Import ({count})",noChats:"No chats found"},ef={title:"Select Chat Format",hint:"Unable to auto-detect the file format. Please manually select the corresponding chat format.",manualSelect:"Select format manually",confirm:"Import with this format"},tf={export:"Getting Started",import:"Supported formats"},sf={website:"Website",terms:"Terms of Use"},af={title:"Changelog",subtitle:"View all version updates",viewChangelog:"Changelog",latest:"Latest",current:"Current",total:"{count} versions in total",close:"Close",loadError:"Failed to load changelog",retry:"Retry",types:{feat:"Features",fix:"Bug Fixes",refactor:"Refactors",docs:"Docs",chore:"Other",style:"Style",ci:"CI"}},nf={tagline:Xp,tabs:Yp,import:{dropHint:"Drop to import files",clickHint:"Click to select or drag chat records to import",multipleHint:"Multiple files can be selected or dragged at once",selectFiles:"Select chat record files",selectFolder:"Select export folder",importFolder:"Import Folder",chatRecords:"Chat Records",allFiles:"All Files",progress:{detecting:"Detecting format...",reading:"Reading file...",parsing:"Parsing messages...",saving:"Saving to database...",done:"Import complete",error:"Import interrupted"},processed:"{count} messages processed",viewLog:"View import log",cannotReadPath:"Cannot read file path",preparing:"Preparing import...",errors:{no_file_selected:"No file selected",import_failed:"Import failed",unrecognized_format:"Unrecognized file format",no_messages:"No messages parsed. Please check if the file format is correct.",actionHint:"You can try manual format matching or view the log below:"},diagnostics:{format:"Format: ",received:"Received: ",written:" / Written: ",skipped:" / Skipped: "},batch:{importing:"Batch importing",progressCount:"{current} of {total}",cancel:"Cancel import",waiting:"Waiting",skipped:"Skipped",success:"Import successful",completed:"Batch import completed",summary:"{success} succeeded, {failed} failed, {cancelled} skipped",view:"View"},options:{title:"More Options",mergeImport:"Merge Import",mergeImportHint:"Multiple files will be merged into one chat record"},merge:{importing:"Merging",parsing:"Parsing files...",parsingFile:"Parsing: {name}",merging:"Merging messages...",completed:"Merge completed",completedHint:"{count} files merged",messageCount:"{count} messages",failed:"Merge failed",cancel:"Cancel merge"}},demo:Qp,migration:Jp,chatSelector:Zp,formatSelector:ef,quickStart:tf,footer:sf,changelog:af},of={title:"Group Chat Analysis",loading:"Loading analysis data...",loadError:"Unable to load session data",description:"You've exchanged {messageCount} messages between {startDate} and {endDate}"},rf={title:"Private Chat Analysis",loading:"Loading analysis data...",loadError:"Unable to load session data",description:"You've exchanged {messageCount} messages between {startDate} and {endDate}"},lf={overview:"Overview",view:"Insights",ranking:"Rankings",groupQuotes:"Quotes",quotes:"Quotes",members:"Members",member:"Members",ai:"AI Lab",aiChat:"AI Chat",memory:"Memory",lab:"Lab",sqlLab:"SQL Lab",debug:"Debug"},cf={sqlTables:"SQL Tables",basicTools:"Basic Tools",tableBrowser:{chatDb:"Chat DB",aiDb:"AI Chat DB",selectTable:"Select Table",rowCount:"{count} rows",page:"Page {current} / {total}",prevPage:"Previous",nextPage:"Next",refresh:"Refresh",noData:"No data",editRow:"Edit",deleteRow:"Delete Row",save:"Save",cancel:"Cancel",confirmDelete:"Are you sure you want to delete this row?",deleteSuccess:"Deleted successfully",saveSuccess:"Saved successfully",operationFailed:"Operation failed",allConversations:"All Conversations",copyCell:"Copy Selected",copyRow:"Copy Row (JSON)",clearDebugContext:"Clear Debug Context",confirmClearDebug:"Clear debug_context for all messages? This cannot be undone."}},df={comingSoon:"Memory feature coming soon, stay tuned"},uf={allTime:"All Time",year:"{year}"},mf={viewChatRecord:"View Chat History",sessionIndex:"Session Index",incrementalImport:"Import More",memberManagement:"Manage Member"},gf={title:"Append Chat Records",description:'Select chat record file to append to "{name}". Duplicates will be automatically removed.',selectFile:"Select chat record file",dropHint:"Click to select or drop file here",analyzing:"Analyzing file...",totalInFile:"Total in file",newMessages:"New messages",duplicates:"Duplicates",noNewMessages:"No new messages found, all messages already exist",importing:"Importing...",import:"Import {count} messages",success:"Import successful",successDetail:"Successfully appended {count} new messages",failed:"Import failed"},pf={view:{message:"Messages",topic:"Topics",interaction:"Interactions",groupRelationships:"Relationships",ranking:"Rankings",relationship:"Relationship",languagePreference:"Language Preference"},quotes:{wordcloud:"Topics",hotRepeat:"Hot Repeats",catchphrase:"Catchphrases",keywordAnalysis:"Keyword Analysis",languagePreference:"Language"},groupRelationships:{mentionGraph:"Mention Graph",mentionRanking:"Mention Ranking",proximity:"Proximity"},member:{memberList:"Member List",relationships:"Relationships",cluster:"Interaction",nicknameHistory:"Nickname History"}},ff={messageTypeDistribution:"Message Type Distribution",memberDistribution:"Member Activity Distribution",others:"Others",messageRatio:"Message Ratio",messageUnit:"messages",memberComparison:"Member Comparison",statCards:{dailyAvgMessages:"Daily Avg Messages",messagesCount:"{count} msgs",daysCount:"{count} days total",imageMessages:"Image Messages",imagesCount:"{count} images",peakHour:"Peak hour:",mostActiveWeekday:"Most Active Day",messagesOnDay:"{count} messages",weekendActivity:"Weekend Activity",weekendRatio:"Weekend message ratio",mostActiveDate:"Most Active Date",activeDays:"Active Days",slashDays:"/ {count} days",consecutiveStreak:"Streak",daysStreak:"{count} days",longestStreak:"Longest active streak",activityRate:"Activity Rate",activeDaysRatio:"Days with messages",lateNightChat:"Late Night Chat",lateNightRatio:"{ratio}% of all messages"},dailyTrend:{title:"Daily Message Trend"},identity:{privateChat:"Private",groupChat:"Group",analysisReport:"Analysis Report",totalMessages:"Total Messages",durationDays:"Duration Days",activeDays:"Active Days",dailyAvgMessages:"Daily Avg"},tools:"Quick Tools"},hf={expand:"Expand tools panel",collapse:"Collapse tools panel",lock:"Lock panel",unlock:"Unlock panel",miniMode:"Mini mode",exitMini:"Exit mini mode"},vf={title:"Export Records"},yf={title:"Filter Analysis",conditionMode:"Condition Filter",sessionMode:"Session Filter",history:"History",execute:"Execute Filter",export:"Export Feed Pack",keywords:"Keywords",keywordsHint:"Multiple keywords supported, OR logic",keywordPlaceholder:"Enter keyword, press Enter to add",timeRange:"Time Range",allTime:"All Time",today:"Today",lastWeek:"Last 7 Days",lastMonth:"Last Month",last3Months:"Last 3 Months",lastYear:"Last Year",customTime:"Custom",senders:"Senders",sendersHint:"Optional, leave empty for all",searchMember:"Search member...",noMembers:"No members",selectedCount:"{count} selected",contextSize:"Context Expansion",messages:"messages",searchSession:"Search date...",selectedSessions:"{count} sessions selected",noSessions:"No session index",filtering:"Filtering...",emptyHint:"Set filter conditions and click execute",noResults:"No matching messages found",blockTitle:"Context Block {index}",stats:{blocks:"Blocks",messages:"Messages",hits:"Hits",chars:"Characters"},historyTitle:"Filter History",noHistory:"No history records",loadMore:"Load More",allLoaded:"All loaded",exportSuccess:"Export successful",exportFailed:"Export failed",exportPreparing:"Preparing export..."},bf={groupChat:of,privateChat:rf,tabs:lf,debug:cf,memory:df,yearFilter:uf,tooltip:mf,incremental:gf,subTabs:pf,overview:ff,toolsPanel:hf,messageExport:vf,filter:yf},_f="Manage",xf="Chat record management",kf={batchManage:"Batch Manage"},wf={title:"Batch Delete",description:"Select chat records to delete",searchPlaceholder:"Search conversation name",searchResult:"Found {count} / {total}",noSearchResult:"No matching chat records found",selectAll:"Select All",shiftClickHint:"Hold Shift to select a range",selected:"{count} selected",empty:"No chat records",delete:"Delete Selected",confirmTitle:"Confirm Delete",confirmMessage:"Are you sure you want to delete {count} selected chat record(s)? This action cannot be undone.",deleting:"Deleting...",success:"Successfully deleted {count} chat record(s)",error:"Delete failed: {error}",messageCount:"{count} messages",importedAt:"Imported {time}",columns:{name:"Name",platform:"Platform",messages:"Messages",summaries:"AI Summaries",aiChats:"AI Chats",importedAt:"Imported"},clickToEdit:"Click to edit name",merge:"Merge Selected",mergeHint:"Select at least 2 chat records of the same chat type to merge",mergeConfirmTitle:"Merge Chat Records",mergeConfirmMessage:"This will merge {count} selected chat records into a new merged record.",deleteOriginalsLabel:"Delete original records after merge",mergeRiskWarning:"Critical warning: deletion cannot be undone, and cross-platform context differences may cause semantic confusion. Please back up your original data before continuing.",mergeSteps:{exporting:"Exporting chat records...",parsing:"Parsing files...",checking:"Checking conflicts...",merging:"Merging data...",cleaning:"Cleaning up temp files..."},mergeSuccess:"Successfully merged {count} chat records",mergeError:"Merge failed: {error}",mergedSuffix:"Merged"},Sf={title:_f,description:xf,tabs:kf,batchManage:wf},Cf={name:"DeepSeek",models:{"deepseek-v4-pro":"Flagship model, 1M context, thinking & non-thinking","deepseek-v4-flash":"Fast model, 1M context, thinking & non-thinking"}},Mf={name:"Qwen",models:{"qwen-turbo":"Large-scale model, fast speed","qwen-plus":"Large-scale model, better quality","qwen-max":"Massive-scale model"}},Af={name:"Gemini",models:{"gemini-3-flash-preview":"Fast preview version","gemini-3-pro-preview":"Professional preview version"}},Tf={name:"MiniMax",models:{"MiniMax-M2":"Flagship model","MiniMax-M2-Stable":"Stable version"}},$f={name:"GLM",models:{"glm-4-plus":"Flagship model, best performance","glm-4-flash":"Fast model, cost-effective","glm-4":"Standard model","glm-4v-plus":"Multimodal vision model","glm-4.6v-flash":"4.6V free version","glm-4.5-flash":"4.5 free version"}},If={name:"Kimi",models:{"moonshot-v1-8k":"8K context","moonshot-v1-32k":"32K context","moonshot-v1-128k":"128K ultra-long context"}},Pf={name:"Doubao",models:{"doubao-seed-1-6-lite-251015":"Doubao 1.6 model, cost-effective","doubao-seed-1-6-251015":"Enhanced Doubao 1.6 model","doubao-seed-1-6-flash-250828":"Faster Doubao 1.6 model","doubao-1-5-lite-32k-250115":"Doubao 1.5 Pro model"}},Df={name:"SiliconFlow"},Lf={name:"Groq"},Ef={name:"OpenRouter"},Rf={name:"xAI"},Nf={deepseek:Cf,qwen:Mf,gemini:Af,minimax:Tf,glm:$f,kimi:If,doubao:Pf,siliconflow:Df,groq:Lf,openrouter:Ef,xai:Rf,"openai-compatible":{name:"Third-party"}},Ff={chatExplorer:"Chat Explorer",sqlLab:"SQL Lab",featureInDev:"{name} is in development",comingSoon:"Coming soon...",followNotice:"Follow me on X for updates"},Uf={welcome:{configReady:"✅ AI service is configured and ready!",configNeeded:"**Note**: Please configure AI service in Settings (sidebar bottom) before using ⚙️"},capture:"Capture Chat",scrollToBottom:"Back to Bottom",input:{placeholder:"Enter your question...",placeholderWithSlash:"Enter your question, or type / for skills and {'@'} for members...",placeholderWithActiveSkill:"/{name} selected. Enter your specific question...",removeSkill:"Remove active skill",slashHint:"Type / to pick a skill",useSkill:"Choose Skill",mentionHint:"Type {'@'} to pick a member",mentionEmpty:"No matching members",mentionEmptyHint:"Search by nickname, alias, or account",slashEmpty:"No matching skills",slashEmptyHint:"Open Skill Manager to import built-in skills or create a custom one",manageSkills:"Manage Skills",previewTitle:"Skill Prompt",previewTagsLabel:"Tags",previewToolsLabel:"Tools",previewUnavailable:"No skill prompt available for preview",presetMore:"More",presetCollapse:"Collapse",quickAsk:"Quick Ask",editQuickAsk:"Edit Quick Ask",send:"Send",needMoreThanSkill:"Selecting a skill alone is not enough. Enter a specific question.",needQuestion:"Enter a question before sending"},backgroundTask:{runningShort:"Running",runningTitle:"AI is still thinking",runningDescription:"The previous question is still running. Please wait for it to finish or stop it first.",blockedAction:"The current answer is still being generated. Wait for it to finish or stop it first.",return:"Return"},message:{userAvatar:"User Avatar",calling:"Calling",copy:{tooltip:"Copy Markdown",success:"Markdown copied to clipboard",failed:"Failed to copy Markdown"},tools:{get_chat_overview:"Get Chat Overview",search_messages:"Search Messages",deep_search_messages:"Deep Search Messages",get_recent_messages:"Get Recent Messages",get_member_stats:"Get Member Stats",get_time_stats:"Get Time Stats",get_members:"Get Members",get_member_name_history:"Get Nickname History",get_conversation_between:"Get Conversation",get_message_context:"Get Message Context",search_sessions:"Search Sessions",get_session_messages:"Get Session Messages",get_session_summaries:"Get Session Summaries",response_time_analysis:"Response Time Analysis",keyword_frequency:"Keyword Frequency",message_type_breakdown:"Message Type Breakdown",peak_chat_hours_by_member:"Peak Hours by Member",member_activity_trend:"Member Activity Trend",silent_members:"Silent Members",reply_interaction_ranking:"Reply Interaction Ranking",mutual_interaction_pairs:"Mutual Interaction Pairs",member_message_length_stats:"Message Length Stats",daily_active_members:"Daily Active Members",conversation_initiator_stats:"Conversation Initiators",activity_heatmap:"Activity Heatmap",unanswered_messages:"Unanswered Messages"},generating:"Generating response...",summary:{label:"Context Summary",expand:"Expand summary",collapse:"Collapse summary",info:"Previous conversation has been compressed into a summary to save context space"},think:{labels:{think:"Thinking",analysis:"Analysis",reasoning:"Reasoning",reflection:"Reflection",other:"Thinking ({tag})"},loading:"Thinking",duration:"Took {seconds}s"},toolParams:{keywords:"Keywords",time:"Time",getMessages:"Get {count} messages",limit:"Limit {count}",contextWithMessages:"Context of {contextSize} messages around {msgCount} messages",context:"{size} messages context",topMembers:"Top {count} members",search:"Search",getMemberList:"Get member list",memberId:"Member ID",timeStats:{hourly:"Hourly",weekday:"By Weekday",daily:"Daily"}}},thinking:{processingResult:"Processing result",called:"Called:",analyzing:"Analyzing question...",compressing:"Compressing context..."},statusBar:{preset:{default:"Default Preset",groupTitle:"Group Chat Presets",privateTitle:"Private Chat Presets",manage:"Manage Presets"},model:{title:"AI Model Configs",notConfigured:"AI Not Configured",empty:"No configs",manage:"Manage Configs",switchFailed:"Failed to switch model"},messageLimit:{label:"Limit: ",title:"Max messages per request, click to configure"},agent:{label:"Agent",contextTokens:"Context",stats:"seg {segment} · tags {tags}",phase:{compressing:"Compressing",preparing:"Preparing",thinking:"Thinking",tool_running:"Running tool",responding:"Responding",completed:"Completed",aborted:"Stopped",error:"Error"},phaseShort:{compressing:"Compress",preparing:"Prep",thinking:"Think",tool_running:"Tool",responding:"Reply",completed:"Done",aborted:"Stop",error:"Err"}},tokenUsageTitle:"Total token usage",export:{label:"Export",title:"Export current conversation"},log:{label:"Logs",title:"Open current AI log file",openFailed:"Failed to open log",openFailedDesc:"Please try again later"},compress:{label:"Compress",title:"Manually compress context",compressing:"Compressing...",success:"Context compressed",successDesc:"{before} → {after} tokens",skipped:"Compression skipped",skippedDesc:"Not enough messages to compress",failed:"Compression failed"},status:{connected:"AI Connected",notConfigured:"Please configure AI service in Settings"}},conversation:{title:"AI Conversations",newChat:"New Chat",newConversation:"New Chat",empty:"No history yet",startNew:"Start New Chat",titlePlaceholder:"Enter title...",group:{last7Days:"Last 7 Days",last30Days:"Last 30 Days"},rename:"Rename",delete:"Delete",export:{createdAt:"Created",user:"User",assistant:"AI Assistant",noMessages:"No messages to export"}},error:{title:"Processing Failed",detail:"Error Details",viewDetail:"View Details",requestUrl:"Request URL",statusCode:"Status Code",responseBody:"Response Body",responseHeaders:"Response Headers",requestBody:"Request Body",name:"Error Name",message:"Error Message",stack:"Stack Trace",cause:"Error Cause",provider:"Provider",copyAll:"Copy All",copied:"Copied to clipboard",unknown:"Unknown error"},dataSource:{title:"Data Source",keywords:"Keywords:",empty:"No data",emptyHint:"Related records will appear here after asking questions",totalRecords:"{count} records",loadMore:"Load More"}},Of={editor:{errorEmptySQL:"Please enter an SQL statement",placeholder:"Enter SQL query...",promptTip:"Describe your query in natural language. SQL will be generated and executed automatically",tip:"Tip: Double-click column names to insert into SQL",history:"History",aiGenerate:"AI Generate",generateAndRun:"Generate and Run",switchToSQLMode:"Switch to SQL Mode",switchToPromptMode:"Switch to Prompt Mode",shortcut:"Ctrl/⌘ + Enter to run",run:"Run"},schema:{tables:"Tables",doubleClickToInsert:"Double-click to insert into SQL",primaryKey:"Primary Key"},result:{queryError:"Query Error",rows:"{count} rows",readableTime:"Readable time",viewChat:"View chat history",summarize:"Summarize",pageSize:"Per page",pageInfo:"Page {current} / {total}",emptyResult:"Query returned no results",initialState:"Enter SQL and run to see results",initialHint:"Only read-only queries are supported (SELECT / WITH). Add LIMIT for better performance",summaryTitle:"AI Result Summary",analyzing:"AI is analyzing results...",errorSummary:"Summary failed"},generate:{title:"AI Generate SQL",description:"Describe what you want to query in natural language, and AI will generate the corresponding SQL.",placeholder:"E.g.: Find top 10 members by message count, count daily messages, find messages containing 'keyword'...",errorEmptyPrompt:"Please enter your query requirement",errorGenerate:"AI generation failed",errorTokenLimit:"Model output reached token limit without generating a complete response (thinking may have consumed too many tokens)",aiOutput:"AI Output",thinking:"Thinking…",thinkingProcess:"Thinking process",waitingAI:"Waiting for AI response...",sqlStatement:"SQL Statement",explanation:"Explanation",generateSQL:"Generate SQL",useSQL:"Use SQL",run:"Run",defaultPromptPrivate:"For the last 1 year of this private chat, compare both participants by total messages, message share, active days, average messages per active day, first message time, and latest message time; sort by total messages desc.",defaultPromptGroup:"For the last 1 year of this group chat, rank members by total messages, message share, active days, average messages per active day, and text-message ratio; include display names and return top 20 by total messages desc."},history:{title:"AI Generation History",execute:"Execute",empty:"No history records",justNow:"Just now",minutesAgo:"{count} min ago",hoursAgo:"{count} hr ago",today:"Today"}},Hf={selector:{title:"Choose an assistant to start",heroTitlePrefix:"Chat with",heroTitleSuffix:"",subtitle:"Each assistant specializes in different types of analysis tasks. Pick the one that best fits your needs.",noAssistants:"No assistants available for this context",manage:"Manage Assistants",addNew:"New Assistant"},config:{viewTitle:"View Config",createTitle:"New Assistant",editTitle:"Assistant Config",betaWarning:"This feature is in beta. Configuration logic may change, so please back up your prompts.",tabs:{basic:"Basic",tools:"Tools"},name:"Name",systemPrompt:"System Prompt",chatType:"Chat Type",chatTypeAll:"All",chatTypeGroup:"Group",chatTypePrivate:"Private",locale:"Language",localeHint:"None selected = all languages",presetQuestions:"Preset Questions",addQuestion:"Add a question...",builtinTools:"Built-in Tools",coreTools:"Core Tools",coreToolsHint:"Essential data retrieval tools, always enabled",analysisTools:"Analysis Tools",analysisToolsHint:"Enable on demand. Only checked tools will be available to AI",selectAll:"Select All",deselectAll:"Deselect All",builtinToolsHint:"No selection = all tools available. Only checked tools will be enabled.",toolGroupQuery:"Data Query Tools",resetDefault:"Reset to Default",create:"Create"},market:{title:"Assistant Manager",tabs:{local:"Local",market:"Market"},localHint:"Manage imported assistants, configure or delete",marketHint:"Browse the assistant market, import to use and customize",default:"Default",updateAvailable:"Update Available",reimport:"Re-import",imported:"Imported",import:"Import",importing:"Importing...",importSuccess:"Import successful",importFailed:"Import failed",viewConfig:"View Config",duplicate:"Duplicate",addAssistant:"Add Assistant",noLocal:"No imported assistants yet",noCatalog:"No assistants available, please check your network",loading:"Loading...",loadFailed:"Failed to load, please check your network",retry:"Retry"},fallbackName:"Assistant",duplicateSuffix:" (Copy)",toast:{loadFailed:"Failed to load",createSuccess:"Created successfully",createFailed:"Failed to create",saveSuccess:"Saved successfully",saveFailed:"Failed to save",resetSuccess:"Reset to default",resetFailed:"Failed to reset",unknownError:"Unknown error"},builtinToolDesc:{get_chat_overview:"Get chat overview information",search_messages:"Search chat messages",deep_search_messages:"Deep search chat messages",get_recent_messages:"Get recent messages",get_message_context:"Get message context",get_conversation_between:"Get conversation between two members",get_members:"Get members",get_member_stats:"Get member statistics",get_member_name_history:"Get member name history",get_time_stats:"Get time statistics",search_sessions:"Search sessions",get_session_messages:"Get session messages",get_session_summaries:"Get session summaries",message_type_breakdown:"Message type distribution",peak_chat_hours_by_member:"Member peak hours",member_activity_trend:"Member activity trend",silent_members:"Silent member detection",reply_interaction_ranking:"Reply interaction ranking",mutual_interaction_pairs:"Mutual interaction pairs",member_message_length_stats:"Message length stats",unanswered_messages:"Unanswered messages",daily_active_members:"Daily active members",conversation_initiator_stats:"Conversation initiators",activity_heatmap:"Activity heatmap",response_time_analysis:"Response time analysis",keyword_frequency:"Keyword frequency"}},Vf={selector:{title:"Select Skill",freeChat:"Free Chat",freeChatDesc:"No preset skill, AI responds freely",manage:"Manage Skills",incompatible:"Incompatible with current assistant",noSkills:"No skills available",noSkillsHint:"Import built-in skills or create custom skills via Skill Manager",autoSkill:"AI auto-select skill",autoSkillHint:"When enabled, AI can automatically choose the best skill for your question"},config:{createTitle:"New Skill",editTitle:"Skill Config",name:"Name",description:"Description",tags:"Tags",chatScope:"Scope",chatScopeAll:"All",chatScopeGroup:"Group",chatScopePrivate:"Private",prompt:"Skill Prompt",tools:"Required Tools",rawEditor:"Markdown Editor",rawEditorHint:"Edit the full skill Markdown file (with YAML frontmatter)",create:"Create",save:"Save"},market:{title:"Skill Manager",tabs:{local:"Local",market:"Market"},localHint:"Manage imported skills, configure or delete",marketHint:"Browse the skill market, import to use and customize",updateAvailable:"Update Available",reimport:"Re-import",imported:"Imported",import:"Import",importing:"Importing...",importSuccess:"Import successful",importFailed:"Import failed",noLocal:"No imported skills yet",noCatalog:"No skills available, please check your network",addSkill:"Create Custom Skill",loading:"Loading...",loadFailed:"Failed to load, please check your network",retry:"Retry"},block:{label:"Skill: {name}"},active:{label:"Manually Invoked Skill: {name}"},toast:{createSuccess:"Skill created successfully",createFailed:"Failed to create skill",saveSuccess:"Skill saved successfully",saveFailed:"Failed to save skill",deleteSuccess:"Skill deleted",deleteFailed:"Failed to delete"}},zf={basicTools:"Basic Tools",toolTest:{selectTool:"Select Tool",selectToolPlaceholder:"Select a tool...",coreTools:"Core Tools",analysisTools:"Analysis Tools",parameters:"Parameters",arrayPlaceholder:"Separate values with commas",execute:"Execute",cancel:"Cancel",elapsed:"Elapsed {ms}ms",result:"Result",truncated:"Result too large, truncated. Try reducing the limit parameter for complete data."}},Bf={tab:Ff,chat:Uf,sqlLab:Of,assistant:Hf,skill:Vf,lab:zf},Wf={loading:"Analyzing word frequency...",sidebar:{filter:"Filters",style:"Style"},stats:{messagesLabel:"Messages",wordsLabel:"Total words",uniqueLabel:"Unique",clickHint:"Note: Click a word in the cloud to view related messages"},config:{maxWords:"Max words",sizeScale:"Font size",userFilter:"User filter",posFilter:"POS filter",enableStopwords:"Filter stopwords",dict:"Dictionary",advanced:"Advanced"},size:{small:"S",medium:"M",large:"L",xlarge:"XL"},posFilter:{all:"All",meaningful:"Meaningful",custom:"Custom",customHint:"Custom POS",selectMeaningful:"Meaningful",selectAll:"All",clearAll:"Clear"},empty:{title:"No word cloud data",description:"Not enough text messages to generate a word cloud with current filters"},dict:{zhCN:"Simplified Chinese",zhTW:"Traditional Chinese",download:"Download dictionary","download_zh-CN":"Download Simplified Chinese dict","download_zh-TW":"Download Traditional Chinese dict",needDownload:"Please download a dictionary to use word cloud analysis",downloadHint:"~8MB",downloadSuccess:"Dictionary downloaded successfully",downloadFailed:"Dictionary download failed",promptTitle:"Traditional Chinese Dictionary",promptDescription:"We detected you're using Traditional Chinese. For best word cloud results, a Traditional Chinese dictionary is recommended. Download now? (~8MB)",promptDownload:"Download now",promptLater:"Maybe later"}},jf={title:"🔍 Keyword Ranking",description:"Analyze keyword usage rankings in chats, customize your own lists",countTemplate:"{count} members",templateLabel:"Templates:",newTemplate:"+ New",searchPlaceholder:"Type to search",clear:"Clear",templateHint:"* Right-click template to edit or delete",keyword:"Keyword",ranking:" Ranking",multiColorMode:"Multi-color",times:"{count}x",timesWithPercent:"x ({percent}%)",loading:"Analyzing data...",empty:"No data available. Try adding keywords or switching templates.",contextMenu:{edit:"Edit",delete:"Delete"},modal:{createTitle:"Create Template",editTitle:"Edit Template",templateName:"Template Name",templateNamePlaceholder:"e.g. Positive",keywords:"Keywords",keywordPlaceholder:"Press Enter to add",cancel:"Cancel",save:"Save",update:"Update"},templates:{laugh:{name:"Laughter",keywords:"lol,lmao,haha,rofl,dying,hilarious",description:"Track happiness index in the group"},sad:{name:"Sadness",keywords:"sad,depressed,tired,exhausted,ugh,sucks,hate",description:"Track negative emotions in the group"},praise:{name:"Praise",keywords:"awesome,amazing,great,nice,cool,impressive,wow,goat",description:"Find members who give the most compliments"},slacker:{name:"Slacking",keywords:"bored,slacking,hungry,sleepy,friday yet,done for today,hate mondays",description:"Find members who want to leave work most"},gossip:{name:"Gossip",keywords:"omg,no way,really,spill,tea,wtf,insane,crazy",description:"Find members who love gossip the most"},polite:{name:"Polite",keywords:"thanks,please,sorry,appreciate,welcome,excuse me,thank you",description:"Find the most polite members"},curious:{name:"Questions",keywords:"why,how,what,confused,help,anyone know",description:"Find members who ask the most questions"}}},qf={title:"🔥 Hot Repeats",loading:"Loading repeat data...",description:"Content with most participants in single repeat chain",countTemplate:"{count} hot repeats",people:"{count} ppl",times:"{count}x",colon:": ",viewChat:"View chat history",empty:"No repeat data available"},Kf={dateAll:"All messages",dateNow:"Present",heroPrefix:"Analyzed",heroMiddle:"messages,",heroMiddleSecond:"yielding",heroSuffix:"unique words",topTopicsPrefix:"You love talking about:",topKeywords:"Top Keywords",hotTopic:"Hot Topic",hotTopicDesc:"Appeared {count} times",richness:"Lexical Diversity",richnessValue:"{value}%",richnessDesc:"Unique {unique} / Total {total}",chatStyle:"Chat Style",styleEncyclopedia:"Encyclopedia",styleEncyclopediaDesc:"Noun-heavy, loves discussing people, places & things",styleAction:"Action-Oriented",styleActionDesc:"Verb-heavy, loves discussing what to do",styleExpressive:"Expressive",styleExpressiveDesc:"Adjective-heavy, rich in emotional expression",styleBalanced:"Balanced",styleBalancedDesc:"Diverse topics, well-rounded conversations",expressionStyle:"Expression Style",expressionCasual:"Casual",expressionCasualDesc:"Short words, relaxed and informal",expressionFormal:"Formal",expressionFormalDesc:"Elaborate words, precise expression",expressionMixed:"Mixed",expressionMixedDesc:"A blend of casual and formal",watermark:"Topic Profile",sharedTopics:"Shared Topics"},Gf={title:"💬 Catchphrase Analysis",loading:"Analyzing catchphrases...",description:"Analyzed frequent phrases from {count} members",countTemplate:"{count} members",times:"{count}x",empty:{title:"No catchphrase data",description:"Not enough repeated phrases to generate a word cloud with current filters"},stats:{phrasesLabel:"Top phrases",totalLabel:"Total uses",clickHint:"Tip: Click a phrase to view related messages"},viewMode:{list:"List",wordcloud:"Word Cloud"},phraseCount:"{count} catchphrases",topN:"Show count"},Xf={loading:"Analyzing language preferences...",empty:"Not enough text messages for language analysis",card:{sharedWordsLabel:"Shared High-Frequency Words",syncSubtext:"Speaking style similarity based on POS distribution",warmthWarm:"Warm",warmthCrisp:"Crisp",warmthBalanced:"Balanced",expressionLabel:"Your expressions are full of",diversityTitle:"Lexical Depth",diversityDesc:"Unique word ratio",styleTitle:"Chat Style",styleDesc:"Expression style based on POS distribution",punctTitle:"Punctuation Style",punctDesc:"Most used punctuation personality",punctTopTitle:"Punctuation TOP5",punctTopDesc:"Most frequently used punctuation marks",modalTopTitle:"Modal Particles TOP5",modalTopDesc:"Most frequently used modal particles",sharedWordsTitle:"Shared Words",sharedWordsDesc:"High-frequency words used by both",watermark:"Language Preference",radarFactual:"Factual",radarActive:"Active",radarDescriptive:"Descriptive",radarAffable:"Affable",radarIntense:"Intense",radarNoun:"Noun",radarVerb:"Verb",radarAdj:"Adjective",radarModal:"Modal",radarAdv:"Adverb",topCatchphrases:"Top Catchphrases",languageProfiles:"Language Profiles"},catchphrasePK:{title:"Catchphrase Battle",sharedCount:"{count} shared catchphrases",hint:"Click to view messages. Pink outlines mark shared catchphrases."},pos:{title:"POS Portrait",styleEncyclopedia:"Encyclopedia",styleAction:"Action-oriented",styleExpressive:"Expressive",styleBalanced:"Balanced"},modal:{title:"Modal Particles",toneSoft:"Soft & Warm",toneCurious:"Curious",toneCasual:"Casual",toneCalm:"Calm & Steady",toneMixed:"Mixed Style",empty:"No modal particle data"},punctuation:{title:"Punctuation Personality",none:"No punct.",personalityDeep:"Deep Thinker",personalityPassionate:"Passionate",personalityCurious:"Curious Mind",personalityCheerful:"Cheerful",personalityFreeflow:"Free-flow",personalityPrecise:"Precise",empty:"No punctuation data"},sync:{title:"Language Sync",description:"Speaking style similarity based on POS distribution",labelSoulmate:"Soulmates",labelHighSync:"Highly Synced",labelUnique:"Unique Styles",labelDiverse:"Divergent"}},Yf={wordcloud:Wf,keywords:jf,hotRepeat:qf,topicProfile:Kf,catchphrase:Gf,languagePreference:Xf},Qf={title:"Select Your Identity",unset:"Not Set",selectMember:"Select Member",currentOwner:"Current: {name}",hint:"1. Shown on the right side of chat viewer 2. Identifies you in AI conversations"},Jf={title:"Group Member Management",description:"{count} members. Add aliases or remove members",searchPlaceholder:"Search nickname, account name, ID or alias",noMatch:"No matching members found",empty:"No member data available",table:{accountName:"Account Name",groupNickname:"Group Nickname",messageCount:"Messages",customAlias:"Custom Aliases",actions:"Actions"},aliasPlaceholder:"Press Enter to add",delete:"Delete",mergeSelected:"Merge Selected",mergeSelectedCount:"{count} members selected",pagination:"Showing {start} - {end} of {total} members",tip:"Tip: Adding aliases helps identify chat participants and improves search and AI analysis accuracy.",mergeModal:{title:"Merge Members?",content:"Merge {source} ({sourceCount} messages) into {target} ({targetCount} messages). By default, the merged name keeps the member with more messages.",hint:"This action cannot be undone. All messages from the merged member will be reassigned to the kept member.",cancel:"Cancel",confirm:"Confirm Merge"},modal:{title:"Delete Member?",content:"This will delete member {name} and their {count} messages. This action cannot be undone.",cancel:"Cancel",confirm:"Confirm Delete"}},Zf={note:"Note: QQ's legacy client can export chat history as txt format, which provides the most accurate nickname history",title:"Nickname History",loading:"Loading...",hasChanges:"{count} members have changed nicknames",noChanges:"No nickname changes",current:"Current",empty:"No members have changed their nicknames",loadingText:"Loading nickname history..."},eh={loading:"Analyzing {'@'} interaction data...",topMentioners:"📢 Top {'@'} Initiators",totalMentions:"{count} total {'@'}s",topMentioned:"🎯 Most {'@'} Mentioned",popularMember:"Most popular in the group",times:"times",oneWay:{title:"🐕 One-way Detection",description:"Found {count} one-way relationships (one party {'@'} another ≥80%)",neverRespond:"Never responds",reverse:"{count}x reverse",ratio:"{value}% one-way"},twoWay:{title:"💕 Mutual Detection",description:"Found {count} frequent CP pairs (mutual {'@'} with ≥30% balance)",interactions:"interactions",balance:"{value}% balanced"},emptyTitle:"📱 {'@'} Interaction Analysis",empty:"No {'@'} interaction data available",modal:{title:"{name}'s {'@'} Relationships",topMentioned:"Most frequently {'@'}s",topMentioners:"Most frequently {'@'}d by",timesCount:"{count}x",close:"Close"}},th={ownerSelector:Qf,list:Jf,nicknameHistory:Zf,relationships:eh,private:{title:"Chat Members",description:"{count} members. Add aliases for search and AI analysis",messageCount:"Messages",percentage:"{value}% of total",customAlias:"Custom Aliases",aliasPlaceholder:"Press Enter to add alias",empty:"No member data available",tipTitle:"Tip",tipContent:"Adding aliases helps identify chat participants and improves search and AI analysis accuracy."}},sh={title:"Chat Record Viewer",loadedCount:"{count} messages loaded"},ah={loading:"Loading...",noMessages:"No messages",tryAdjustFilter:"Try adjusting the filter",loadingMore:"Loading more...",scrollUpForMore:"↑ Scroll up to load more",scrollDownForMore:"↓ Scroll down to load more"},nh={messageId:"Message ID",memberNotSupported:"Member (not supported)",keywordsPlaceholder:"Keywords, comma separated, Enter to search",startDate:"Start Date",endDate:"End Date",reset:"Reset",filter:"Filter"},oh={timeline:"Sessions",noSessions:"No sessions",generateSummary:"Summarize",tooFewMessages:"Too few"},rh="Summary generation failed",ih="Unknown error",lh={title:"Batch Generate Summaries",byRange:"By Range",byTime:"By Time",selectRange:"Select Range",rangeStart:"Earliest",rangeInfo:"About",sessionsUnit:"sessions",rangeEnd:"Latest",timeRange:"Select Time Range",today:"Today",yesterday:"Yesterday",week:"Last 7 days",month:"Last 30 days",custom:"Custom",found:"Found",hasSummary:"already summarized",tooFewMessages:"too few messages",pending:"Pending:",unit:"",noPending:"No sessions to generate",noSessions:"No sessions in this time range",checking:"Checking...",loading:"Loading...",progress:"Progress",session:"Session",statusSuccess:"Success",statusSkipped:"Skipped",statusFailed:"Failed",success:"Success:",failed:"Failed:",skipped:"Skipped:",start:"Start",stop:"Stop"},ch={viewContext:"View Context",contextTitle:"Message Context (10 before and after)",noContext:"No context available",replyTo:"Reply to"},dh={title:"Session Index",subtitle:"For timeline navigation in chat records",notGenerated:"Session index not generated",notGeneratedHint:"After generating session index, you can use timeline navigation in the chat record viewer to quickly jump to different sessions.",whatIsIt:"What session index does:",benefit1:"Identify conversation boundaries based on message time gaps",benefit2:"Provide timeline navigation in chat record viewer",benefit3:"Enable AI analysis to understand conversation context",generated:"Session index generated",sessionCount:"{count} sessions identified",regenerateHint:"You can regenerate the index if you've adjusted the session gap threshold.",generate:"Generate Index",regenerate:"Regenerate",generating:"Generating...",cancel:"Cancel"},uh={drawer:sh,messageList:ah,filter:nh,timeline:oh,summaryFailed:rh,summaryUnknownError:ih,batchSummary:lh,messageItem:ch,sessionIndex:dh},mh={title:"Interaction Frequency",rankingView:"Ranking",memberView:"Member View",matrixView:"Matrix View",modelSettings:"Model Settings",lookAhead:"Look Ahead",lookAheadDesc:"Messages to look ahead per sender",decaySeconds:"Time Decay (sec)",decaySecondsDesc:"Higher = distant messages matter more",applySettings:"Apply",noData:"No data",selectMember:"Select Member",selectMemberHint:"Select a member from the left",msgCount:"Messages",relationCount:"Relations",relationsByIntimacy:"Proximity Ranking",noRelations:"No relations",intimacy:"Proximity",interactionRanking:"Interaction Ranking",score:"Proximity",coOccurrence:"Co-occur",times:" times",totalMembers:"Total Members",totalMessages:"Total Messages",involvedMembers:"Involved",edgeCount:"Relations"},gh={typeDistribution:"Message Type Distribution",hourlyDistribution:"Hourly Distribution",weekdayDistribution:"Weekday Distribution",monthlyDistribution:"Monthly Distribution",yearlyDistribution:"Yearly Distribution",timeHeatmap:"Time Heatmap",heatmapHint:"Shows chat time patterns",calendarHeatmap:"Message Calendar",calendarHint:"Daily message distribution",calendarTooltipMessages:"Messages",lengthDetailTitle:"Short Messages (1-25 chars)",lengthDetailHint:"Per character",lengthGroupedTitle:"Length Range Distribution",lengthGroupedHint:"Grouped by 5",noTextMessages:"No text messages",noData:"No data",profile:{totalMessages:"Total",textMessages:"Text Messages",avgLength:"Avg Length",avgLengthUnit:"{count} chars/msg",mediaRatio:"Media Ratio",textExpression:"Text Expression",textExpressionDesc:"Longest message {count} chars",mediaRichness:"Media Richness",shortMaster:"Short Msg Master",shortMasterDesc:"{count} msgs with ≤5 chars",essayLover:"Essay Lover",essayLoverDesc:"Messages with ≥{threshold} chars",peakRecord:"Peak Record",peakRecordDesc:"Max {count} msgs in a day",topHours:"Top Active Hours",images:"Images",emoji:"Emoji",voiceVideo:"Voice/Video",typeDistribution:"Msg Types",hourlyDistribution:"24h Activity",watermark:"Message Report",heroLine1Prefix:"A total of",heroLine1Suffix:"messages exchanged",heroLine2Prefix:"Averaging",heroLine2Middle:"chars each, with",heroLine2Suffix:"being non-text"}},ph={mentionGraph:"Mention Interaction Graph",layout:"Layout",circular:"Circular",force:"Force",directed:"Directed",reset:"Reset",graphHint:"{nodes} members, {links} interactions",noInteraction:"No mention interaction data"},fh={loading:"Analyzing relationship dynamics…",noIndex:{title:"Session Index Required",description:"Relationship analysis requires session index data. Please generate the session index from the overview page first."},empty:{title:"No Relationship Data",description:"No sessions found in the selected time range."},overview:{title:"Overall Summary"},monthly:{title:"Monthly Breakdown",totalSessionsPrefix:"Total",totalSessionsSuffix:"sessions"},trend:{title:"Initiative Trend",hint:"Blue line shows {name}'s monthly initiative ratio; 50% line is the balanced baseline"},hero:{monthPart:"{month}/{year}",timeRange:{singleMonth:"In {month},",range:"From {start} to {end},"},totalSessionsPrefix:"You had",totalSessionsSuffix:"conversations in total",initiativePrefix:"",initiativeByPrefix:"of opening messages were started by",initiativeBySuffix:"",initiateTimes:"starts"},initiator:"Start Conversations",closer:"End Conversations",closerTitle:"Conversation Closer",closerHint:"Shows who sends the last message when a topic ends.",initiated:"Initiated {count} times",closed:"Closed {count} times",totalSessions:"{count} total sessions",times:" times",noActivity:"No activity this month",watermarkReport:"Relationship Report",monthFormat:"{month}/{year}",monthShortFormat:"{month}",monthDetail:"Init {init} / Close {close}",iceBreaker:{title:"Ice Breaker",hint:"Times breaking silence after 24+ hours of inactivity",count:"{count} ice breaks",total:"{count} total ice breaks"},responseLatency:{title:"Reply Speed",hint:"Average time to reply after the other person sends a message",count:"{count} replies",seconds:"{n}s",minutes:"{n} min",minutesSeconds:"{m}m {s}s",hours:"{n}h",hoursMinutes:"{h}h {m}min"},perseverance:{title:"Perseverance",hint:"Times sending another message before the other person replied",hintWithThreshold:"Times sending another message when the other person hasn't replied within {threshold}",thresholdMinutes:"{n} min",count:"{count} times",total:"{count} total",threshold:"Gap",empty:"No perseverance records with this threshold"},labels:{mutualPursuit:"Mutual Pursuit",silentGuardian:"Silent Guardian",devotedHeart:"Devoted Heart",distantBond:"Distant Bond",wellMatched:"Well Matched",missingYou:"{name} Misses You",monologue:"{name}'s Monologue",peacefulSilence:"Peaceful Silence",fleetingThoughts:"Fleeting Thoughts"}},hh={title:"Timeline View",description:"Message time distribution, active period trends and other visualizations"},vh={rankListPro:{fullRanking:"Full Ranking",memberCount:"{count} members"},rankList:{unit:""},nicknameHistory:{periodToNow:"{start} ~ Now",periodRange:"{start} ~ {end}",current:"Current",empty:"No nickname history"},listPro:{countTemplate:"{count} items",fullRanking:"Full Ranking",empty:"No data"}},yh={cluster:mh,message:gh,interaction:ph,relationship:fh,timeline:hh,charts:vh},bh="Keyword Filter",_h="Schemes",xh="Scheme Name",kh="Enter scheme name",wh="New Scheme",Sh="New Scheme",Ch="Delete",Mh="Set as Default",Ah="Default",Th="Keyword Filter",$h="No Filter",Ih="Manage Schemes",Ph="Add Filter Words",Dh="Type and press Enter, separate with spaces or commas",Lh="Add",Eh="Filter Words",Rh="Clear All",Nh="No schemes yet. Click + to create one.",Fh="No filter words. Add some above.",Uh="Select or create a filter scheme",Oh="{count} words filtered",Hh="Close",Vh={title:bh,schemeList:_h,schemeName:xh,schemeNamePlaceholder:kh,defaultSchemeName:wh,createScheme:Sh,deleteScheme:Ch,setDefault:Mh,isDefault:Ah,filterScheme:Th,noFilter:$h,manage:Ih,addWords:Ph,addWordsPlaceholder:Dh,add:Lh,wordList:Eh,clearAll:Rh,emptyScheme:Nh,emptyWords:Fh,selectOrCreate:Uh,activeCount:Oh,close:Hh},zh={common:vp,layout:Ep,settings:Gp,home:nf,analysis:bf,tools:Sf,providers:Nf,ai:Bf,quotes:Yf,members:th,records:uh,views:yh,wordFilter:Vh},Bh="確定",Wh="取消",jh="儲存",qh="編輯",Kh="新增",Gh="重新命名",Xh="截圖",Yh="關閉",Qh="返回上一頁",Jh="完成",Zh="重試",ev="載入中...",tv="初始化中...",sv="暫無資料",av="無匹配結果",nv="匯出成功",ov="匯出失敗",rv="產生中...",iv="重新產生",lv="開啟資料夾",cv="請先在設定中設定 AI 服務",dv="重設",uv={general:"操作失敗,請重試",network:"網路錯誤",unknown:"未知錯誤"},mv={image:"圖片",video:"影片",audio:"音訊",file:"檔案",sticker:"貼圖",link:"連結"},gv={messages:"條訊息",members:"位成員",days:"天"},pv={text:"文字",image:"圖片",voice:"語音",video:"影片",file:"檔案",emoji:"表情",link:"連結",location:"位置",redPacket:"紅包",transfer:"轉帳",poke:"拍一拍",call:"通話",share:"分享",reply:"回覆",forward:"轉發",contact:"名片",system:"系統",recall:"收回",other:"其他",unknown:"未知"},fv={mon:"週一",tue:"週二",wed:"週三",thu:"週四",fri:"週五",sat:"週六",sun:"週日"},hv={jan:"1月",feb:"2月",mar:"3月",apr:"4月",may:"5月",jun:"6月",jul:"7月",aug:"8月",sep:"9月",oct:"10月",nov:"11月",dec:"12月"},vv={title:"選擇語言",subtitle:"請選擇您偏好的介面語言",next:"下一步"},yv={title:"隱私權政策與使用條款",subtitle:"使用前請先詳閱",disagree:"我不同意",agree:"我已閱讀並同意上述內容",updateNotice:"條款內容已更新,請重新閱讀並確認"},bv={selectDate:"選擇日期",clearDate:"清除日期"},_v={mode:{recent:"最近",quarter:"按季",year:"按年",custom:"自訂"},recent:{halfYear:"近半年",oneYear:"近一年",twoYears:"近兩年",fiveYears:"近五年",all:"全部"},display:{recent180:"最近半年",recent365:"最近一年",recent730:"最近兩年",recent1825:"最近五年"},quarter:{label:"{year}年 第{quarter}季"},year:{label:"{year}年"}},xv={allMembers:"全部成員"},kv={confirm:Bh,cancel:Wh,delete:"刪除",save:jh,edit:qh,add:Kh,rename:Gh,capture:Xh,close:Yh,back:Qh,done:Jh,retry:Zh,loading:ev,initializing:tv,noData:sv,noResults:av,export:"匯出",exportSuccess:nv,exportFailed:ov,generating:rv,regenerate:iv,openFolder:lv,errorNoAIConfig:cv,reset:dv,error:uv,attachment:mv,unit:gv,messageType:pv,weekday:fv,month:hv,languageSelect:vv,agreement:yv,datePicker:bv,timeSelect:_v,userSelect:xv},wv="ChatLab",Sv="分析新聊天",Cv="實用工具",Mv="聊天紀錄",Av="管理",Tv="暫無紀錄",$v="搜尋聊天名稱",Iv="未找到匹配的聊天紀錄",Pv={rename:"重新命名",pin:"置頂",unpin:"取消置頂",delete:"刪除"},Dv={title:"重新命名",placeholder:"請輸入新名稱"},Lv={title:"確認刪除",message:"確定要刪除聊天紀錄「{name}」嗎?此操作無法復原。"},Ev={all:"全部",private:"私聊",group:"群聊"},Rv={importedAt:"匯入時間",lastMessageTs:"最近對話",messageCount:"訊息數量"},Nv={expand:"展開側邊欄",collapse:"收起側邊欄",hint:"右鍵可刪除或重新命名聊天紀錄",search:"搜尋聊天紀錄",sort:"排序"},Fv="{count} 條訊息",Uv={helpAndFeedback:"回饋與協助",settings:"設定"},Ov={brand:wv,newAnalysis:Sv,tools:Cv,chatHistory:Mv,manage:Av,noRecords:Tv,searchPlaceholder:$v,noSearchResult:Iv,contextMenu:Pv,renameModal:Dv,deleteModal:Lv,filter:Ev,sort:Rv,tooltip:Nv,sessionInfo:Fv,footer:Uv},Hv="設定",Vv={basic:"基本設定",ai:"AI 設定",aiConfig:"模型服務",aiDefaultModel:"預設模型",aiPrompt:"聊天設定",aiPreprocess:"前處理",dataManage:"資料管理",storage:"儲存管理",storageManage:"儲存管理",sessionManage:"會話索引",about:"關於 ChatLab",api:"自動化",apiSubTabs:{autoSync:"自動同步",apiService:"API 服務",mcp:"MCP"}},zv={general:{title:"一般"},preferences:{title:"偏好設定"},language:{title:"語言",description:"選擇軟體顯示語言"},appearance:{title:"外觀設定",themeMode:"主題模式",auto:"依系統設定",light:"淺色模式",dark:"深色模式"},defaultTab:{title:"預設標籤頁",description:"進入聊天對話後預設顯示的頁面",overview:"總覽",aiChat:"AI 對話"},autoLaunch:{title:"啟動設定",openAtLogin:"開機自動啟動",openAtLoginDesc:"系統啟動時自動執行 ChatLab",devModeHint:"開發模式下不可用"},toolsPanel:{positionLabel:"快捷工具入口位置",positionDesc:"選擇快捷工具面板的顯示位置",positionSide:"右側",positionHeader:"頂部"},screenshot:{title:"截圖設定",mobileAdapt:"行動畫面適配",mobileAdaptDesc:"截圖時會自動縮放寬度,方便在行動裝置上查看"},network:{title:"網路設定",proxyMode:"代理模式",proxyModeDesc:"存取網路時使用的代理方式",modeOff:"關閉",modeSystem:"跟隨系統",modeManual:"手動設定",proxyAddress:"代理地址",proxyPlaceholder:"http://127.0.0.1:7890",proxyHelp:"支援 HTTP/HTTPS 代理,格式如:http://127.0.0.1:7890",testConnection:"測試連線",testing:"測試中...",connectionSuccess:"代理連線成功!",connectionFailed:"連線失敗",enterProxyFirst:"請先輸入代理地址",invalidProxyUrl:"請輸入有效的代理地址,格式如 http://127.0.0.1:7890",onlyHttpSupported:"僅支援 http:// 或 https:// 協定",saveFailed:"儲存失敗"}},Bv={title:"預設模型",noConfigs:"請先在「模型服務」中新增模型設定",selectProvider:"選擇提供商",selectModel:"選擇模型",assistantModel:{label:"預設助手模型",description:"用於 AI 對話、工具呼叫、SQL 助手、上下文壓縮"},fastModel:{label:"快速模型",description:"用於會話摘要生成,未設定時使用預設助手模型",followAssistant:"跟隨預設助手模型"}},Wv={title:"模型服務",providerTitle:"服務提供商",loading:"載入中...",inUse:"使用中",defaultModel:"預設模型",localService:"本機服務",edit:"編輯",delete:"刪除",empty:{title:"尚未設定 AI 服務",description:"新增一組設定後即可開始使用 AI 功能"},addConfig:"新增服務",maxConfigs:"已達設定上限(最多 10 組)",modal:{addConfig:"新增服務",editConfig:"編輯服務",officialApi:"官方API",officialApiDesc:"DeepSeek、Gemini 等",localService:"本機服務",localServiceDesc:"Ollama 等",openaiCompatible:"OpenAI 相容",openaiCompatibleDesc:"自訂端點",configName:"設定名稱",optional:"(選填)",configNamePlaceholderPreset:"留空則使用服務商名稱",configNamePlaceholderCustom:"留空則使用 API 端點網址",aiProvider:"AI 服務商",apiKeyPlaceholder:"輸入你的 API Key",apiKeyPlaceholderEdit:"輸入新的 API Key(留空保持原有)",apiKeyPlaceholderLocal:"本機服務通常不需要",apiKeyHintLocal:"如果服務設定了認證,在此輸入",validate:"驗證",validationSuccess:"連線驗證成功",validationFailed:"連線驗證失敗",validationFailedTitle:"API 連線驗證失敗",saveAnywayHint:"驗證未通過,設定資訊可能有誤。是否仍然儲存?",saveAnyway:"仍然儲存",validationError:"驗證失敗:",model:"模型",modelName:"模型名稱",modelNamePlaceholder:"如 gpt-4、claude-3",modelNamePlaceholderLocal:"如 qwen3、deepseek-r1",modelNameHint:"輸入 API 支援的模型名稱",modelNameHintLocal:"輸入本機部署的模型名稱",apiEndpoint:"API 位址",apiEndpointHint:"相容 OpenAI 格式的 API 端點",resolvedUrl:"實際請求地址:",fetchModels:"從 API 獲取",fetchModelsTitle:"瀏覽遠端模型",fetchModelsLoading:"正在獲取模型列表...",fetchModelsEmpty:"未獲取到模型",fetchModelsError:"獲取模型列表失敗",fetchModelsCount:"共 {total} 個模型,當前顯示 {shown} 個",modelAdded:"已添加",addAllModels:"全部添加",searchModels:"搜尋模型...",apiEndpointOverrideHint:"預設地址已填入,可按需改為完整 URL",disableThinking:"關閉思考模式",disableThinkingDesc:"針對 Qwen3、DeepSeek-R1 等模型,停用後使用標準工具呼叫格式",isReasoningModel:"推理模型",isReasoningModelDesc:"啟用後將提取思考過程並停用工具呼叫(如 DeepSeek-R1、QwQ 等)",advancedOptions:"進階設定",customService:"自訂服務",unnamedConfig:"未命名設定",visitWebsite:"訪問官網",getApiKey:"取得 API Key",presetService:"預設服務",thirdPartyService:"第三方服務",customModelInput:"手動輸入模型",selectFromList:"從列表選擇",addCustomModel:"新增模型",deleteCustomModel:"刪除選中",customModelId:"模型端點名稱",customModelIdHint:"API 呼叫時使用的模型識別碼",customModelDisplayName:"顯示名稱",customModelDisplayNamePlaceholder:"自訂顯示名稱",editModel:"編輯模型",contextWindow:"上下文視窗",contextWindowPlaceholder:"如 128000",contextWindowHint:"模型支援的最大上下文 token 數(用於上下文壓縮)",contextWindowMissing:"未設定上下文視窗,將使用預設值,建議點擊「編輯模型」手動填寫",modelRequired:"至少新增一個模型才能儲存",modelCapabilities:"模型能力標註",apiFormat:"API 介面類型",apiFormatOpenAI:"OpenAI Completions",apiFormatAnthropic:"Anthropic",apiFormatGemini:"Gemini",apiFormatOpenAIResponses:"OpenAI Responses"},providerKind:{official:"官方",aggregator:"聚合",custom:"自訂"},capabilities:{chat:"對話",reasoning:"推理",vision:"視覺",function_calling:"工具呼叫",embedding:"向量",ranking:"排序"}},jv={title:"本機儲存管理",description:"管理 ChatLab 在本機儲存的資料檔案",dataLocation:{title:"資料目錄位置",description:"自訂本機資料與快取的存放位置",choose:"選擇位置",reset:"還原預設",open:"開啟",migrateHint:"偵測到資料仍在舊位置,建議遷移至統一目錄:",migrateAction:"一鍵遷移",restartTip:"切換目錄後請重新啟動應用程式,舊目錄下快取會跟隨遷移",confirmTitle:"確認切換資料目錄",confirmMessage:"您即將切換資料儲存位置,現有資料將被遷移到新目錄。",newPath:"新目錄路徑",defaultPath:"預設位置",confirmWarning:"重新啟動應用程式後,舊資料目錄將被自動刪除。請確保新目錄路徑正確。",installDirForbidden:"不能將資料目錄放在應用程式安裝目錄下,應用程式更新時該目錄會被清空",cancel:"取消",confirm:"確認切換",migrationSuccessTitle:"資料遷移完成",migrationSuccessMessage:"應用程式需要重新啟動以使變更生效。",relaunchNow:"立即重新啟動"},openRootDir:"開啟根目錄",totalUsage:"總佔用:",loading:"載入中...",files:"檔案",notExist:"不存在",clear:"清理",open:"開啟",cache:{databases:{name:"聊天紀錄資料庫",description:"匯入的聊天紀錄分析資料"},ai:{name:"AI 對話資料庫",description:"AI 對話歷史與設定檔"},downloads:{name:"下載目錄",description:"包含截圖檔案、分析結果等"},statsCache:{name:"快取資料",description:"聊天記錄的統計快取,清理後會自動重建"},logs:{name:"日誌檔案",description:"軟體的執行日誌,包含匯入、AI、錯誤等日誌"}}},qv={session:{title:"會話索引設定",description:"會話索引會依時間間隔自動將聊天紀錄切分成對話段落,方便 AI 分析與瀏覽",defaultThreshold:"預設分割間隔",thresholdUnit:"分鐘",thresholdHelp:"超過該時間間隔的訊息將被分到新的會話段落",notGenerated:"尚未產生會話索引",generateHint:"產生索引後,可讓 AI 更精準地理解對話上下文",generate:"產生索引",regenerate:"重新產生",generating:"產生中",sessionCount:"{count} 個會話",generated:"已產生會話索引",generateSuccess:"會話索引已成功產生,共 {count} 個會話",generateError:"產生失敗",batchTitle:"批次產生索引",totalSessions:"共 {count} 個聊天",generatedCount:"已產生 {count} 個",notGeneratedCount:"未產生 {count} 個",loadingStatus:"載入中...",batchGenerate:"產生未索引項目",batchRegenerate:"全部重新產生",summaryStrategy:"摘要詳細程度",summaryStrategyHelp:"影響 AI 生成摘要時的詳細程度",summaryBrief:"簡要",summaryStandard:"標準"}},Kv={chatSettings:{title:"工具設定"},exportSettings:{title:"匯出設定"},skillSettings:{title:"技能設定",enableAutoSkill:"AI 自主選擇技能",enableAutoSkillDesc:"啟用後,AI 會根據使用者的問題自動匹配並啟用合適的分析技能;關閉後僅在手動選擇技能時生效"},maxMessages:{title:"傳送條數限制",description:"每次提交給 AI 的最大訊息數,數值越大 Token 消耗越多,分析也更準確(新手建議2000)"},searchContext:{title:"搜尋上下文視窗",description:"搜尋命中訊息時自動攜帶前後的對話上下文,幫助 AI 理解訊息背景。設為 0 則不攜帶上下文",before:"前",after:"後"},exportFormat:{title:"對話匯出格式",description:"匯出 AI 對話時使用的檔案格式",txtLabel:"TXT"},sqlExportFormat:{title:"SQL Lab 匯出格式",description:"匯出 SQL 查詢結果時使用的檔案格式"},compression:{title:"上下文壓縮",enable:"自動壓縮上下文",enableDesc:"對話過長時自動壓縮歷史為摘要,保留關鍵資訊的同時降低 Token 消耗",threshold:"壓縮閾值",thresholdDesc:"上下文 Token 達到模型視窗的百分比時觸發壓縮",buffer:"緩衝區大小",bufferDesc:"保留最近訊息原文的比例,不參與壓縮",maxToolResultPercent:"工具結果上限",maxToolResultPercentDesc:"單次工具回傳給 AI 的最大資料量占比(基於模型上下文視窗計算),超出部分會被智慧截斷"},presets:{title:"系統提示詞",add:"新增預設",import:"匯入預設",description:"提示詞同時用於群聊和私聊分析,系統會自動根據分析類型調整相關內容"},preset:{builtIn:"內建",groupOnly:"僅群聊",privateOnly:"僅私聊",view:"檢視",edit:"編輯",copy:"複製",delete:"刪除"},modal:{editBuiltin:"編輯系統提示詞",editCustom:"編輯自訂提示詞",addCustom:"新增自訂提示詞",presetName:"預設名稱",presetNamePlaceholder:"為預設取個名字",applicableTo:"適用場景",applicableToHint:"(勾選後可在對應分析類型中使用)",groupChat:"群聊分析",privateChat:"私聊分析",systemPrompt:"系統提示詞",systemPromptPlaceholder:"定義 AI 助手的角色、任務和回答要求...",preview:"完整提示詞預覽",previewHint:"(預覽為群聊模式,實際會根據分析類型自動調整)",resetToDefault:"還原為預設",saveChanges:"儲存修改",addPreset:"新增預設"},importPreset:{title:"匯入預設",description:"從遠端取得推薦的系統提示詞預設",loading:"正在載入遠端預設...",loadError:"載入遠端預設失敗",noPresets:"暫無可用的遠端預設",commonPresets:"通用預設",groupPresets:"群聊專用預設",privatePresets:"私聊專用預設",add:"新增",added:"已新增",preview:"預覽",systemPrompt:"系統提示詞",noDescription:"暫無描述",fetchingContent:"正在載入內容...",fetchError:"載入內容失敗"}},Gv={title:"關於 ChatLab",description:"在本機運作的聊天紀錄分析工具,透過 SQL 和 AI Agent 幫你回顧社交記憶。",version:"版本",checkUpdate:"檢查更新",checking:"檢查中...",upToDate:"已是最新版本",newVersionAvailable:"發現新版本 {version}",updateNow:"立即更新",webUpdateHint:"請在終端機執行 npm install -g chatlab-cli@latest 後重啟服務。",updating:"更新中...",updateSuccess:"更新成功,請重啟服務以生效",updateFailed:"更新失敗:{error}",updateCheckFailed:"檢查更新失敗:{error}",unknown:"未知",privacy:{title:"隱私設定",analytics:"匿名使用統計",analyticsDesc:"開啟後,軟體會收集版本號、作業系統版本等非敏感資料,用於幫助最佳化產品"},developer:{title:"開發者選項",debugMode:"DEBUG 模式",debugModeDesc:"開啟後,將顯示除錯面板和快捷除錯工具,可用於查看資料庫、執行測試工具,並記錄更詳細的除錯日誌。"}},Xv={title:"聊天紀錄預處理",description:"在聊天紀錄傳送給 AI 前進行預處理,節省 Token 並過濾雜訊。原始資料不會被修改。",dataCleaning:"資料清洗",dataCleaningDesc:"自動清理 XML 卡片訊息(如分享連結、小程式等),提取有效內容,大幅節省 Token。建議保持開啟。",mergeConsecutive:"合併連續發言",mergeConsecutiveDesc:"同一人在短時間內的連續訊息合併為一條",mergeWindow:"合併時間視窗(秒)",denoise:"智慧去雜訊",denoiseDesc:"過濾純語氣詞、純表情、系統佔位符(如 [圖片])等無意義訊息",desensitize:"資料脫敏",desensitizeDesc:"根據規則將敏感資訊(手機號、電子郵件、證件號等)替換為佔位符",desensitizeRules:"脫敏規則",desensitizeRulesDesc:"勾選需要啟用的脫敏規則,按清單順序優先匹配",desensitizeBuiltin:"預置規則",desensitizeCustom:"自訂規則",desensitizeAddCustom:"新增自訂規則",desensitizeRuleName:"規則名稱",desensitizeRulePattern:"正規表達式",desensitizeRuleReplacement:"替換文字",desensitizeRuleAdd:"新增",desensitizeRuleInvalidRegex:"正規表達式語法錯誤",desensitizeRuleNamePlaceholder:"例如:員工工號",desensitizeRulePatternPlaceholder:"例如:EMP-\\d+",desensitizeRuleReplacementPlaceholder:"替換文字,如 [工號]",anonymizeNames:"暱稱匿名化",anonymizeNamesDesc:"用編號(U1、U2…)替代真實暱稱傳送給 AI,減少幻覺並節省 Token",blacklist:"黑名單關鍵詞",blacklistDesc:"包含以下任一關鍵詞的訊息將被整條過濾",blacklistPlaceholder:"輸入關鍵詞後按 Enter 新增",blacklistAdd:"新增"},Yv={rules:{cn_phone:"中國手機號",cn_phone_desc:"1xx xxxx xxxx 格式的 11 位號碼",cn_id_card:"中國身份證號",cn_id_card_desc:"18 位,末位可含 X",cn_bank_card:"中國銀行卡號",cn_bank_card_desc:"16-19 位連續數字",cn_landline:"中國市話號碼",cn_landline_desc:"區號-號碼,如 010-12345678",us_ssn:"美國社會安全號 (SSN)",us_ssn_desc:"XXX-XX-XXXX 格式",us_phone:"美國電話號碼",us_phone_desc:"+1 (XXX) XXX-XXXX 格式",us_drivers_license:"美國駕照號",us_drivers_license_desc:"字母開頭 + 7-8 位數字",jp_phone:"日本電話號碼",jp_phone_desc:"0x0-XXXX-XXXX 格式",jp_my_number:"日本個人編號",jp_my_number_desc:"12 位數字(マイナンバー)",kr_phone:"韓國電話號碼",kr_phone_desc:"01X-XXXX-XXXX 格式",kr_rrn:"韓國身份證號",kr_rrn_desc:"XXXXXX-XXXXXXX 格式(주민번호)",api_key_prefix:"API Key / Token(已知前綴)",api_key_prefix_desc:"sk-、ghp_、AKIA 等開頭的長字串",bearer_token:"Bearer Token",bearer_token_desc:"Bearer 後的授權權杖值",email:"電子郵件地址",email_desc:"user{'@'}domain.com 標準格式",credit_card:"信用卡號",credit_card_desc:"Visa / MasterCard / AmEx 等卡號",ipv4:"IPv4 地址",ipv4_desc:"如 192.168.1.1",url:"URL 連結",url_desc:"http:// 或 https:// 開頭的連結"}},Qv={betaWarning:"當前 API 版本僅為測試版(Beta),介面可能會發生調整",service:{title:"API 服務",enable:"啟用 API 服務",enableDesc:"開啟後,外部工具可透過 HTTP API 查詢、匯出和匯入聊天數據。僅本機可存取 (127.0.0.1)",portInUseHint:"連接埠被佔用,請在下方修改連接埠或關閉佔用該連接埠的程式後重試"},status:{running:"執行中",stopped:"已停止",starting:"啟動中...",portInUse:"連接埠被佔用",error:"啟動失敗"},port:{title:"連接埠配置",label:"監聽連接埠",desc:"API 服務監聽的本機連接埠號(1024-65535)",edit:"修改",save:"儲存",cancel:"取消"},token:{title:"存取權杖",label:"Bearer Token",desc:"所有 API 請求需要在 Authorization 標頭中攜帶此 Token",noToken:"尚未產生 Token,請先啟用服務",regenerate:"重新產生"},dataSources:{title:"資料來源",desc:"設定外部資料來源 URL,ChatLab 將按設定間隔自動拉取並匯入聊天資料。",empty:"暫無資料來源",disabled:"已暫停",every:"每",minutes:"分鐘",lastSync:"上次同步",syncing:"同步中",messages:"則訊息",addBtn:"新增資料來源",form:{modalTitle:"新增資料來源",name:"名稱",namePlaceholder:"例如:我的聊天伺服器",url:"資料來源 URL",token:"存取權杖(可選)",tokenPlaceholder:"遠端 API 的 Bearer Token",interval:"拉取間隔(分鐘)",pullLimit:"每次拉取訊息數",pullLimitPlaceholder:"預設 1000",targetSession:"目標會話 ID(可選)",targetSessionPlaceholder:"留空則每次新建會話",add:"新增"},discovery:{directMode:"直接 URL",remoteMode:"遠端伺服器",baseUrl:"伺服器地址",baseUrlPlaceholder:"示例:http://127.0.0.1:2333/api/v1",browse:"瀏覽遠端會話",found:"發現 {count} 個會話",search:"搜尋",searchPlaceholder:"依會話名稱搜尋",selectAll:"全選",deselectAll:"取消全選",selectByType:"會話類型",typeAll:"全部",typePrivate:"私訊",typeGroup:"群組",typeOther:"其他",loadMore:"載入更多",subscribe:"訂閱 {count} 個會話",messages:"則訊息",error:"連線遠端伺服器失敗",connectionCheckFailed:"無法連線到遠端伺服器,請檢查地址和權杖是否正確"},noSessions:"暫無匯入會話,點擊上方「管理訂閱」新增",edit:{title:"修改配置",save:"儲存",cancel:"取消",editSource:"修改配置",manageSessions:"管理訂閱",manageSessionsDesc:"重新選擇要同步的遠端會話",syncAll:"一鍵同步",subscribed:"已訂閱"},deleteConfirm:{title:"刪除資料來源",message:"確認刪除資料來源「{name}」?該資料來源下的所有匯入配置將被移除。已匯入的本機對話不會被刪除。"},deleteSessionConfirm:{title:"刪除訂閱",message:"確認刪除訂閱「{name}」?",keepData:"僅刪除訂閱",deleteData:"同時刪除匯入的聊天"}},usage:{title:"使用說明",desc:"啟用服務後,外部工具可透過 API 查詢資料,或向 ChatLab 推送聊天記錄。所有請求需攜帶 Bearer Token 認證。",authHint:"請求標頭範例:",docLink:"查看完整 API 文件"}},Jv={overview:{title:"MCP 概述",description:"MCP 讓 AI 助手直接查詢你的聊天記錄。支援會話發現、關鍵字搜尋、成員統計、時間分佈等操作。",toolCount:"{count} 個工具",resourceCount:"{count} 個資源",installHint:"安裝 chatlab-cli 後,在 AI 用戶端中新增以下設定即可使用:"},clients:{other:"通用"},config:{title:"用戶端設定",clientLabel:"MCP 用戶端",copy:"複製",copied:"已複製",claudeHint:"將此設定新增至 ClaudeCode 的 MCP 設定中。",codexHint:"將此 TOML 設定新增至 ~/.codex/config.toml 檔案中。",openclawHint:"將此設定新增至專案的 openclaw.json 檔案中。",otherHint:"將此 JSON 設定新增到你的 MCP 用戶端設定檔中。"},tips:{title:"使用提示",dataDir:"MCP 伺服器讀取 ~/.chatlab/ 目錄下的聊天資料,與桌面應用程式共用同一份資料。",readOnly:"所有操作均為唯讀,不會修改你的聊天記錄。",nodeRequired:"npx 和 CLI 方式需要 Node.js 20 或更高版本。",docs:"詳細文件請造訪 docs.chatlab.fun。"}},Zv={title:Hv,tabs:Vv,basic:zv,defaultModel:Bv,aiConfig:Wv,storage:jv,ai:qv,aiPrompt:Kv,about:Gv,aiPreprocess:Xv,desensitize:Yv,api:Qv,mcp:Jv},ey="探索新的聊天記憶",ty={file:"檔案匯入",api:"自動同步",push:"API匯入",apiDescription:"設定外部平台的資料來源,讓聊天記錄定期自動同步到ChatLab。",apiButton:"前往設定自動同步",pushDescription:"開啟本地API服務,允許第三方工具/掛件或腳本將聊天記錄主動推送至ChatLab。",pushButton:"前往設定 API 服務"},sy={viewExample:"查看示例 Demo",downloading:"正在下載示例資料...",importing:"正在匯入示例資料...",failed:"示例資料載入失敗,請確認網路連線後重試"},ay={title:"資料庫需要更新",description:"偵測到 {count} 個資料庫需要升級以支援新功能。",note:"更新通常只需幾秒鐘,不會遺失任何資料。",upgradeContent:"本次升級內容:",upgradeNow:"立即升級",upgrading:"正在升級...",failed:"遷移失敗",partialFailed:"部分資料庫升級失敗",errorHint:"這通常是因為資料庫檔案損壞。建議在側邊欄中刪除失敗的會話,然後重新匯入。",close:"關閉",retry:"重試"},ny={title:"選擇要匯入的聊天",scanning:"正在掃描聊天列表...",scanFailed:"掃描失敗",retry:"重試",selectAll:"全選",chatCount:"共 {count} 個聊天",selected:"已選 {count} 個",messageCount:"{count} 條訊息",import:"匯入 ({count})",noChats:"未發現任何聊天"},oy={title:"選擇聊天記錄格式",hint:"無法自動識別此檔案的格式,請手動選擇對應的聊天記錄格式。",manualSelect:"手動選擇格式",confirm:"使用此格式匯入"},ry={export:"新手引導",import:"支援哪些格式"},iy={website:"官網",terms:"使用條款"},ly={title:"更新紀錄",subtitle:"查看所有版本更新內容",viewChangelog:"更新紀錄",latest:"最新版本",current:"目前版本",total:"共 {count} 個版本",close:"關閉",loadError:"載入更新紀錄失敗",retry:"重試",types:{feat:"新功能",fix:"問題修復",refactor:"重構優化",docs:"文件更新",chore:"其他優化",style:"樣式優化",ci:"CI/建置"}},cy={tagline:ey,tabs:ty,import:{dropHint:"鬆開滑鼠匯入檔案",clickHint:"點一下選擇,或直接拖曳聊天紀錄匯入",multipleHint:"支援同時選擇或拖曳多個檔案",selectFiles:"選擇聊天紀錄檔案",selectFolder:"選擇匯出資料夾",importFolder:"匯入資料夾",chatRecords:"聊天紀錄",allFiles:"所有檔案",progress:{detecting:"正在偵測格式...",reading:"正在讀取檔案...",parsing:"正在解析訊息...",saving:"正在寫入資料庫...",done:"匯入完成",error:"匯入中斷"},processed:"已處理 {count} 則訊息",viewLog:"檢視匯入日誌",cannotReadPath:"無法讀取檔案路徑",preparing:"準備匯入...",errors:{no_file_selected:"未選擇檔案",import_failed:"匯入失敗",unrecognized_format:"無法識別的檔案格式",no_messages:"未解析到任何訊息,請檢查檔案格式是否正確",actionHint:"你還可以嘗試下方手動匹配或查看日誌:"},diagnostics:{format:"偵測格式:",received:"收到訊息:",written:" / 寫入:",skipped:" / 跳過:"},batch:{importing:"批次匯入中",progressCount:"第 {current} / {total} 個",cancel:"取消匯入",waiting:"等待中",skipped:"已跳過",success:"匯入成功",completed:"批次匯入完成",summary:"成功 {success} 個,失敗 {failed} 個,跳過 {cancelled} 個",view:"檢視"},options:{title:"更多選項",mergeImport:"合併匯入",mergeImportHint:"勾選後,多個檔案會合併成同一份聊天紀錄"},merge:{importing:"正在合併",parsing:"正在解析檔案...",parsingFile:"正在解析:{name}",merging:"正在合併訊息...",completed:"合併完成",completedHint:"{count} 個檔案已合併",messageCount:"{count} 條訊息",failed:"合併失敗",cancel:"取消合併"}},demo:sy,migration:ay,chatSelector:ny,formatSelector:oy,quickStart:ry,footer:iy,changelog:ly},dy={title:"群聊分析",loading:"載入分析資料...",loadError:"無法載入聊天資料",description:"從 {startDate} 到 {endDate},你們一共聊了 {messageCount} 則訊息"},uy={title:"私聊分析",loading:"載入分析資料...",loadError:"無法載入聊天資料",description:"從 {startDate} 到 {endDate},你們一共聊了 {messageCount} 則訊息"},my={overview:"總覽",view:"洞察",ranking:"榜單",groupQuotes:"金句",quotes:"金句",members:"成員",member:"成員",ai:"AI 實驗室",aiChat:"AI 對話",memory:"記憶",lab:"實驗室",sqlLab:"SQL 實驗室",debug:"Debug"},gy={sqlTables:"SQL 表格",basicTools:"基礎工具",tableBrowser:{chatDb:"聊天記錄 DB",aiDb:"AI 對話 DB",selectTable:"選擇表",rowCount:"共 {count} 行",page:"第 {current} / {total} 頁",prevPage:"上一頁",nextPage:"下一頁",refresh:"重新整理",noData:"暫無資料",editRow:"編輯",deleteRow:"刪除行",save:"儲存",cancel:"取消",confirmDelete:"確認刪除這行資料?",deleteSuccess:"刪除成功",saveSuccess:"儲存成功",operationFailed:"操作失敗",allConversations:"全部對話",copyCell:"複製選取項",copyRow:"複製整行 (JSON)",clearDebugContext:"清除 Debug 上下文",confirmClearDebug:"確認清除所有訊息的 debug_context 資料?此操作不可撤銷。"}},py={comingSoon:"記憶功能即將上線,敬請期待"},fy={allTime:"全部時間",year:"{year}年"},hy={viewChatRecord:"查看聊天紀錄",sessionIndex:"會話索引",incrementalImport:"追加匯入",memberManagement:"成員管理"},vy={title:"新增聊天紀錄",description:"選擇要加入「{name}」的聊天紀錄檔案,系統會自動排除重複內容。",selectFile:"選擇聊天紀錄檔案",dropHint:"點擊選擇或拖曳檔案到此處",analyzing:"正在分析檔案...",totalInFile:"檔案訊息數",newMessages:"新增訊息",duplicates:"重複訊息",noNewMessages:"檔案中沒有新訊息,所有訊息都已存在",importing:"正在匯入...",import:"匯入 {count} 則訊息",success:"匯入成功",successDetail:"已新增 {count} 則新訊息",failed:"匯入失敗"},yy={view:{message:"訊息",topic:"話題",interaction:"互動分析",groupRelationships:"群關係",ranking:"榜單",relationship:"關係",languagePreference:"語言偏好"},quotes:{wordcloud:"話題",hotRepeat:"熱門複讀",catchphrase:"口頭禪",keywordAnalysis:"關鍵字分析",languagePreference:"語言偏好"},groupRelationships:{mentionGraph:"{'@'} 關係圖",mentionRanking:"{'@'} 排行",proximity:"發言臨近度"},member:{memberList:"成員列表",relationships:"互動關係",cluster:"互動頻率",nicknameHistory:"暱稱變更"}},by={messageTypeDistribution:"訊息類型分佈",memberDistribution:"成員訊息占比",others:"其他人",messageRatio:"訊息佔比",messageUnit:"條",memberComparison:"雙方訊息佔比",statCards:{dailyAvgMessages:"日均訊息",messagesCount:"{count} 條",daysCount:"共 {count} 天",imageMessages:"圖片訊息",imagesCount:"{count} 張",peakHour:"最活躍時段:",mostActiveWeekday:"最活躍星期",messagesOnDay:"{count} 條訊息",weekendActivity:"週末活躍度",weekendRatio:"週末訊息佔比",mostActiveDate:"最活躍日期",activeDays:"活躍天數",slashDays:"/ {count} 天",consecutiveStreak:"連續活躍",daysStreak:"{count} 天",longestStreak:"最長連續活躍",activityRate:"活躍率",activeDaysRatio:"有訊息的天數佔比",lateNightChat:"深夜聊天",lateNightRatio:"佔總訊息 {ratio}%"},dailyTrend:{title:"每日訊息趨勢"},identity:{privateChat:"私聊",groupChat:"群聊",analysisReport:"資料分析報告",totalMessages:"訊息總數",durationDays:"跨度天數",activeDays:"活躍天數",dailyAvgMessages:"日均訊息"},tools:"常用工具"},_y={expand:"展開工具面板",collapse:"收起工具面板",lock:"鎖定面板",unlock:"解鎖面板",miniMode:"迷你模式",exitMini:"退出迷你模式"},xy={title:"匯出聊天紀錄"},ky={title:"自訂篩選",conditionMode:"條件篩選",sessionMode:"會話篩選",history:"歷史紀錄",execute:"開始篩選",export:"匯出篩選結果",keywords:"關鍵字",keywordsHint:"支援多個關鍵字,並以 OR 邏輯比對",keywordPlaceholder:"輸入關鍵字,按 Enter 新增",timeRange:"時間範圍",allTime:"全部",today:"今天",lastWeek:"近7天",lastMonth:"近1個月",last3Months:"近3個月",lastYear:"近1年",customTime:"自訂",senders:"傳送者",sendersHint:"可選,留空表示不限",searchMember:"搜尋成員...",noMembers:"暫無成員",selectedCount:"已選 {count} 位",contextSize:"上下文延伸",messages:"條訊息",searchSession:"搜尋日期...",selectedSessions:"已選擇 {count} 個會話",noSessions:"暫無會話索引",filtering:"正在篩選...",emptyHint:"設定篩選條件後再按下開始篩選",noResults:"未找到匹配的訊息",blockTitle:"對話區塊 {index}",stats:{blocks:"對話區塊",messages:"訊息數",hits:"命中數",chars:"字元數"},historyTitle:"篩選歷史",noHistory:"暫無歷史紀錄",loadMore:"載入更多",allLoaded:"已載入全部",exportSuccess:"匯出成功",exportFailed:"匯出失敗",exportPreparing:"正在準備匯出..."},wy={groupChat:dy,privateChat:uy,tabs:my,debug:gy,memory:py,yearFilter:fy,tooltip:hy,incremental:vy,subTabs:yy,overview:by,toolsPanel:_y,messageExport:xy,filter:ky},Sy="管理",Cy="管理聊天紀錄",My={batchManage:"批次管理"},Ay={title:"批次刪除",description:"選擇要刪除的聊天紀錄",searchPlaceholder:"搜尋聊天名稱",searchResult:"找到 {count} / {total} 筆",noSearchResult:"未找到匹配的聊天紀錄",selectAll:"全選",shiftClickHint:"按住 Shift 點擊可範圍多選",selected:"已選 {count} 個",empty:"暫無聊天紀錄",delete:"刪除所選項目",confirmTitle:"確認刪除",confirmMessage:"確定要刪除選取的 {count} 個聊天紀錄嗎?此操作無法復原。",deleting:"正在刪除...",success:"成功刪除 {count} 個聊天紀錄",error:"刪除失敗:{error}",messageCount:"{count} 條訊息",importedAt:"匯入於 {time}",columns:{name:"名稱",platform:"平台",messages:"訊息數",summaries:"AI摘要",aiChats:"AI 對話",importedAt:"匯入時間"},clickToEdit:"點擊即可編輯名稱",merge:"合併所選項目",mergeHint:"選擇 2 個以上同聊天類型的聊天紀錄才能合併",mergeConfirmTitle:"合併聊天紀錄",mergeConfirmMessage:"即將合併所選的 {count} 個聊天紀錄,並建立一筆新的合併紀錄。",deleteOriginalsLabel:"合併後刪除原始聊天紀錄",mergeRiskWarning:"強提醒:刪除後無法復原,且跨平台上下文差異可能導致語意錯位或混亂。請先備份原始資料並確認你已理解風險。",mergeSteps:{exporting:"正在匯出聊天紀錄...",parsing:"正在解析檔案...",checking:"正在偵測衝突...",merging:"正在合併資料...",cleaning:"正在清理暫存檔案..."},mergeSuccess:"成功合併 {count} 個聊天紀錄",mergeError:"合併失敗:{error}",mergedSuffix:"合併"},Ty={title:Sy,description:Cy,tabs:My,batchManage:Ay},$y={name:"DeepSeek",models:{"deepseek-v4-pro":"旗艦模型,1M 上下文,支援思考與非思考模式","deepseek-v4-flash":"高速模型,1M 上下文,支援思考與非思考模式"}},Iy={name:"通義千問",models:{"qwen-turbo":"通義千問高速模型","qwen-plus":"通義千問高效能模型","qwen-max":"通義千問旗艦模型"}},Py={name:"Gemini",models:{"gemini-3-flash-preview":"高速預覽版","gemini-3-pro-preview":"進階預覽版"}},Dy={name:"MiniMax",models:{"MiniMax-M2":"旗艦模型","MiniMax-M2-Stable":"穩定版本"}},Ly={name:"GLM",models:{"glm-4-plus":"旗艦模型,整體表現最佳","glm-4-flash":"高速模型,性價比高","glm-4":"標準模型","glm-4v-plus":"多模態視覺模型","glm-4.6v-flash":"4.6V 免費模型","glm-4.5-flash":"4.5 免費模型"}},Ey={name:"Kimi",models:{"moonshot-v1-8k":"8K 上下文","moonshot-v1-32k":"32K 上下文","moonshot-v1-128k":"128K 超長上下文"}},Ry={name:"豆包",models:{"doubao-seed-1-6-lite-251015":"豆包 1.6 輕量模型,性價比高","doubao-seed-1-6-251015":"豆包 1.6 強化模型","doubao-seed-1-6-flash-250828":"豆包 1.6 高速模型","doubao-1-5-lite-32k-250115":"豆包 1.5 Pro 模型"}},Ny={name:"矽基流動"},Fy={name:"Groq"},Uy={name:"OpenRouter"},Oy={name:"xAI"},Hy={deepseek:$y,qwen:Iy,gemini:Py,minimax:Dy,glm:Ly,kimi:Ey,doubao:Ry,siliconflow:Ny,groq:Fy,openrouter:Uy,xai:Oy,"openai-compatible":{name:"第三方服務"}},Vy={chatExplorer:"對話式探索",sqlLab:"SQL 實驗室",featureInDev:"{name} 功能開發中",comingSoon:"敬請期待...",followNotice:"新功能上線通知,歡迎關注我的小紅書"},zy={welcome:{configReady:"✅ AI 服務已設定完成,可以開始對話了!",configNeeded:"**注意**:使用前請先在側邊欄底部的「設定」中設定 AI 服務 ⚙️"},capture:"截圖對話",scrollToBottom:"回到底部",input:{placeholder:"輸入你的問題...",placeholderWithSlash:"輸入你的問題,或輸入 / 選擇技能、輸入 {'@'} 選擇成員...",placeholderWithActiveSkill:"已選擇 /{name},請輸入具體問題...",removeSkill:"移除目前技能",slashHint:"輸入 / 選擇技能",useSkill:"選擇技能",mentionHint:"輸入 {'@'} 選擇成員",mentionEmpty:"沒有符合的成員",mentionEmptyHint:"可按暱稱、別名或帳號搜尋",slashEmpty:"沒有符合的技能",slashEmptyHint:"開啟技能管理匯入內建技能,或建立自訂技能",manageSkills:"管理技能",previewTitle:"技能提示詞",previewTagsLabel:"標籤",previewToolsLabel:"工具",previewUnavailable:"暫無可預覽的技能提示詞",presetMore:"更多",presetCollapse:"收起",quickAsk:"快速提問",editQuickAsk:"編輯快速提問",send:"送出",needMoreThanSkill:"只選擇技能還不能送出,請繼續輸入具體問題",needQuestion:"請輸入問題後再送出"},backgroundTask:{runningShort:"進行中",runningTitle:"AI 正在背景推理",runningDescription:"上一個問題仍在推理中,請等待完成或先停止。",blockedAction:"目前回答仍在生成中,請先等待完成或手動停止。",return:"返回查看"},message:{userAvatar:"使用者頭像",calling:"執行",copy:{tooltip:"複製 Markdown",success:"Markdown 已複製到剪貼簿",failed:"複製 Markdown 失敗"},tools:{get_chat_overview:"取得聊天概覽",search_messages:"搜尋聊天紀錄",deep_search_messages:"深度搜尋聊天紀錄",get_recent_messages:"取得最近訊息",get_member_stats:"取得成員統計",get_time_stats:"取得時間分佈",get_members:"取得成員列表",get_member_name_history:"取得暱稱歷史",get_conversation_between:"取得對話紀錄",get_message_context:"取得上下文",search_sessions:"搜尋會話",get_session_messages:"取得會話訊息",get_session_summaries:"取得會話摘要",response_time_analysis:"回覆時間分析",keyword_frequency:"關鍵詞頻率分析",message_type_breakdown:"訊息類型分佈",peak_chat_hours_by_member:"成員活躍時段",member_activity_trend:"成員活躍趨勢",silent_members:"沉默成員偵測",reply_interaction_ranking:"回覆互動排行",mutual_interaction_pairs:"互動頻繁成員對",member_message_length_stats:"訊息長度統計",daily_active_members:"每日活躍人數",conversation_initiator_stats:"話題發起者統計",activity_heatmap:"活躍度熱力圖",unanswered_messages:"未回覆訊息"},generating:"正在產生回覆...",summary:{label:"上下文摘要",expand:"展開摘要",collapse:"收起摘要",info:"以上對話已被壓縮為摘要以節省上下文空間"},think:{labels:{think:"已思考",analysis:"分析",reasoning:"推理",reflection:"反思",other:"思考({tag})"},loading:"思考中",duration:"耗時 {seconds} 秒"},toolParams:{keywords:"關鍵字",time:"時間",getMessages:"取得 {count} 則訊息",limit:"限制 {count} 則",contextWithMessages:"{msgCount} 則訊息的前後各 {contextSize} 則上下文",context:"前後各 {size} 則上下文",topMembers:"前 {count} 名成員",search:"搜尋",getMemberList:"取得成員列表",memberId:"成員 ID",timeStats:{hourly:"按小時",weekday:"按星期",daily:"按日期"}}},thinking:{processingResult:"正在整理結果",called:"已執行:",analyzing:"正在分析問題...",compressing:"正在壓縮上下文..."},statusBar:{preset:{default:"預設",groupTitle:"群聊提示詞預設",privateTitle:"私聊提示詞預設",manage:"管理提示詞"},model:{title:"AI 模型設定",notConfigured:"AI 尚未設定",empty:"尚無設定",manage:"管理模型",switchFailed:"切換模型失敗"},messageLimit:{label:"訊息上限:",title:"設定每次送出的最大訊息數"},agent:{label:"Agent",contextTokens:"上下文",stats:"段 {segment} · 標籤 {tags}",phase:{compressing:"壓縮上下文",preparing:"準備中",thinking:"思考中",tool_running:"工具執行中",responding:"回覆中",completed:"已完成",aborted:"已停止",error:"錯誤"},phaseShort:{compressing:"壓縮",preparing:"準備",thinking:"思考",tool_running:"工具",responding:"回覆",completed:"完成",aborted:"停止",error:"錯誤"}},tokenUsageTitle:"累計 Token 用量",export:{label:"匯出",title:"匯出當前對話"},log:{label:"日誌",title:"開啟當前 AI 日誌檔案",openFailed:"開啟日誌失敗",openFailedDesc:"請稍後重試"},compress:{label:"壓縮",title:"手動壓縮上下文",compressing:"正在壓縮...",success:"上下文已壓縮",successDesc:"{before} → {after} tokens",skipped:"跳過壓縮",skippedDesc:"訊息不足,無需壓縮",failed:"壓縮失敗"},status:{connected:"AI 已連線",notConfigured:"請先在全域設定中設定 AI 服務"}},conversation:{title:"AI 對話紀錄",newChat:"新對話",newConversation:"新建對話",empty:"暫無歷史紀錄",startNew:"開始新對話",titlePlaceholder:"輸入標題...",group:{last7Days:"最近 7 天",last30Days:"最近 30 天"},rename:"重新命名",delete:"刪除",export:{createdAt:"建立時間",user:"使用者",assistant:"AI 助手",noMessages:"對話沒有訊息"}},error:{title:"處理失敗",detail:"錯誤詳情",viewDetail:"查看詳情",requestUrl:"請求路徑",statusCode:"狀態碼",responseBody:"回應內容",responseHeaders:"回應標頭",requestBody:"請求主體",name:"錯誤名稱",message:"錯誤訊息",stack:"堆疊資訊",cause:"錯誤原因",provider:"服務商",copyAll:"複製全部",copied:"已複製到剪貼簿",unknown:"未知錯誤"},dataSource:{title:"資料來源",keywords:"關鍵字:",empty:"暫無資料",emptyHint:"傳送問題後,相關紀錄會顯示在這裡",totalRecords:"共 {count} 筆紀錄",loadMore:"載入更多"}},By={editor:{errorEmptySQL:"請輸入 SQL 語句",placeholder:"輸入 SQL 查詢語句...",promptTip:"用自然語言描述你的查詢需求,系統會自動生成並執行 SQL",tip:"提示:雙擊左側欄位名可插入到 SQL",history:"歷史",aiGenerate:"AI 產生",generateAndRun:"生成並執行",switchToSQLMode:"切換為 SQL 輸入模式",switchToPromptMode:"切換為 Prompt 輸入模式",shortcut:"Ctrl/⌘ + Enter 執行",run:"執行"},schema:{tables:"資料表",doubleClickToInsert:"雙擊插入到 SQL",primaryKey:"主鍵"},result:{queryError:"查詢錯誤",rows:"{count} 行",readableTime:"時間戳轉日期",viewChat:"檢視聊天紀錄",summarize:"整理摘要",pageSize:"每頁",pageInfo:"第 {current} / {total} 頁",emptyResult:"查詢結果為空",initialState:"輸入 SQL 語句後執行,即可查看結果",initialHint:"僅支援唯讀查詢(SELECT / WITH),建議添加 LIMIT 以提升效能",summaryTitle:"AI 分析摘要",analyzing:"AI 正在分析結果...",errorSummary:"總結失敗"},generate:{title:"AI 產生 SQL",description:"用自然語言描述你想查詢的內容,AI 會自動產生對應的 SQL 語句。",placeholder:"例如:查找發言最多的前 10 個成員、統計每天的訊息數量、找出包含「買房」關鍵字的訊息...",errorEmptyPrompt:"請輸入查詢需求",errorGenerate:"AI 產生失敗",errorTokenLimit:"模型輸出達到 token 上限,未能生成完整回覆(可能思考消耗了過多 token)",aiOutput:"AI 輸出",thinking:"思考中…",thinkingProcess:"思考過程",waitingAI:"等待 AI 回應...",sqlStatement:"SQL 語句",explanation:"說明",generateSQL:"產生 SQL",useSQL:"使用 SQL",run:"執行",defaultPromptPrivate:"請統計最近1年私聊中雙方各自的:訊息總數、訊息占比、活躍天數、日均訊息數(按活躍天計算)、首次發言時間、最近發言時間;依訊息總數降序顯示。",defaultPromptGroup:"請統計最近1年群聊中各成員的:訊息總數、訊息占比、活躍天數、日均訊息數(按活躍天計算)、文字訊息占比;顯示成員名稱並依訊息總數降序,返回前20名。"},history:{title:"AI 產生紀錄",execute:"執行",empty:"暫無歷史紀錄",justNow:"剛才",minutesAgo:"{count} 分鐘前",hoursAgo:"{count} 小時前",today:"今天"}},Wy={selector:{title:"選擇一個助手開始對話",heroTitlePrefix:"使用",heroTitleSuffix:"開始對話",subtitle:"每位助手都擅長不同分析任務,請選擇最符合需求的一位",noAssistants:"當前場景暫無可用助手",manage:"管理助手",addNew:"新增助手"},config:{viewTitle:"檢視設定",createTitle:"新增助手",editTitle:"編輯助手",betaWarning:"目前仍為測試功能,設定邏輯後續可能調整,請先備份提示詞與相關設定。",tabs:{basic:"基本設定",tools:"工具管理"},name:"名稱",systemPrompt:"系統提示詞",chatType:"適用聊天類型",chatTypeAll:"全部",chatTypeGroup:"群聊",chatTypePrivate:"私聊",locale:"適用語言",localeHint:"不選代表套用全部語言",presetQuestions:"預設問題",addQuestion:"新增問題...",builtinTools:"內建工具",coreTools:"核心工具",coreToolsHint:"基礎資料取得工具,始終啟用,無法關閉",analysisTools:"分析工具",analysisToolsHint:"按需開啟的分析能力,勾選後才會對 AI 可用",selectAll:"全選",deselectAll:"全不選",builtinToolsHint:"若未勾選任何工具,代表全部可用;勾選後僅開放所選工具。",toolGroupQuery:"資料查詢",resetDefault:"還原預設",create:"建立"},market:{title:"助手管理",tabs:{local:"本地助手",market:"助手市場"},localHint:"管理已導入的助手,可配置或刪除",marketHint:"瀏覽助手市場,導入後即可使用和自由編輯",default:"預設",updateAvailable:"更新可用",reimport:"重新導入",imported:"已導入",import:"導入",importing:"導入中...",importSuccess:"導入成功",importFailed:"導入失敗",viewConfig:"查看配置",duplicate:"複製",addAssistant:"新增助手",noLocal:"暫無已導入的助手",noCatalog:"暫無可用助手,請檢查網路連線",loading:"載入中...",loadFailed:"載入失敗,請檢查網路連線",retry:"重試"},fallbackName:"助手",duplicateSuffix:"(副本)",toast:{loadFailed:"載入失敗",createSuccess:"建立成功",createFailed:"建立失敗",saveSuccess:"儲存成功",saveFailed:"儲存失敗",resetSuccess:"已還原預設",resetFailed:"恢復失敗",unknownError:"未知錯誤"},builtinToolDesc:{get_chat_overview:"取得聊天概覽資訊",search_messages:"搜尋聊天訊息",deep_search_messages:"深度搜尋聊天訊息",get_recent_messages:"取得最近訊息",get_message_context:"取得訊息上下文",get_conversation_between:"取得兩人對話",get_members:"取得成員列表",get_member_stats:"取得成員統計",get_member_name_history:"取得成員改名歷史",get_time_stats:"取得時間統計",search_sessions:"搜尋會話",get_session_messages:"取得會話訊息",get_session_summaries:"取得會話摘要",message_type_breakdown:"訊息類型分佈",peak_chat_hours_by_member:"成員活躍時段",member_activity_trend:"成員活躍趨勢",silent_members:"沉默成員偵測",reply_interaction_ranking:"回覆互動排行",mutual_interaction_pairs:"互動好友配對",member_message_length_stats:"訊息長度統計",unanswered_messages:"未回覆訊息",daily_active_members:"每日活躍人數趨勢",conversation_initiator_stats:"話題發起者統計",activity_heatmap:"活躍度熱力圖",response_time_analysis:"回應時間分析",keyword_frequency:"高頻詞統計"}},jy={market:{title:"技能管理",tabs:{local:"本地技能",market:"技能市場"},localHint:"管理已導入的技能,可配置或刪除",marketHint:"瀏覽技能市場,導入後即可使用和自由編輯",updateAvailable:"更新可用",reimport:"重新導入",imported:"已導入",import:"導入",importing:"導入中...",importSuccess:"導入成功",importFailed:"導入失敗",noLocal:"暫無已導入的技能",noCatalog:"暫無可用技能,請檢查網路連線",addSkill:"新建自定義技能",loading:"載入中...",loadFailed:"載入失敗,請檢查網路連線",retry:"重試"},block:{label:"技能:{name}"},active:{label:"主動呼叫技能:{name}"}},qy={basicTools:"基礎工具",toolTest:{selectTool:"選擇工具",selectToolPlaceholder:"請選擇一個工具...",coreTools:"核心工具",analysisTools:"分析工具",parameters:"參數",arrayPlaceholder:"多個值用逗號分隔",execute:"執行",cancel:"取消",elapsed:"耗時 {ms}ms",result:"執行結果",truncated:"結果過大,已截斷顯示。建議減小 limit 參數以獲取完整資料。"}},Ky={tab:Vy,chat:zy,sqlLab:By,assistant:Wy,skill:jy,lab:qy},Gy={loading:"正在分析詞頻...",sidebar:{filter:"篩選條件",style:"樣式設定"},stats:{messagesLabel:"訊息數",wordsLabel:"總詞數",uniqueLabel:"不重複詞數",clickHint:"提示:點擊詞雲可查看相關訊息"},config:{maxWords:"顯示詞數",sizeScale:"字體大小",userFilter:"使用者篩選",posFilter:"詞性過濾",enableStopwords:"過濾停用詞",dict:"分詞詞庫",advanced:"進階設定"},size:{small:"小",medium:"中",large:"大",xlarge:"特大"},posFilter:{all:"全部詞性",meaningful:"常用詞性",custom:"自訂",customHint:"自選詞性",selectMeaningful:"常用詞性",selectAll:"全選",clearAll:"清空"},empty:{title:"暫無詞雲資料",description:"目前篩選條件下的文字訊息不足,無法產生詞雲"},dict:{zhCN:"簡體中文",zhTW:"繁體中文",download:"下載詞庫","download_zh-CN":"下載簡體詞庫","download_zh-TW":"下載繁體詞庫",needDownload:"使用詞雲分析需要先下載分詞詞庫",downloadHint:"~8MB",downloadSuccess:"詞庫下載成功",downloadFailed:"詞庫下載失敗",promptTitle:"繁體中文詞庫",promptDescription:"偵測到您使用繁體中文,詞雲分析需要繁體詞庫才能取得最佳效果。是否立即下載?(約 8MB)",promptDownload:"立即下載",promptLater:"稍後再說"}},Xy={title:"🔍 關鍵字排行榜",description:"分析群聊中的關鍵字使用情況,也能自訂不同榜單",countTemplate:"共 {count} 位成員",templateLabel:"範本:",newTemplate:"+ 新增範本",searchPlaceholder:"輸入後搜尋",clear:"清空",templateHint:"* 右鍵範本可編輯或刪除",keyword:"關鍵字",ranking:"排行榜",multiColorMode:"多色模式",times:"{count} 次",timesWithPercent:"次 ({percent}%)",loading:"正在分析資料...",empty:"暫無資料,請嘗試新增關鍵字或切換範本",contextMenu:{edit:"編輯",delete:"刪除"},modal:{createTitle:"建立範本",editTitle:"編輯範本",templateName:"範本名稱",templateNamePlaceholder:"如:正能量",keywords:"關鍵字",keywordPlaceholder:"輸入後按 Enter 新增",cancel:"取消",save:"儲存",update:"更新"},templates:{laugh:{name:"歡樂值",keywords:"哈哈,xswl,lol,笑死,233",description:"統計群內的快樂指數"},sad:{name:"沮喪量",keywords:"想死,難受,哭了,崩潰,裂開,無語,累了",description:"統計群內的負面情緒"},praise:{name:"捧哏",keywords:"牛逼,666,厲害,強,nb,大佬,羨慕,好強",description:"統計群內最會誇人的成員"},slacker:{name:"摸魚",keywords:"摸魚,下班,餓了,困了,不想上班,什麼時候下班",description:"統計群內最想下班的打工人"},gossip:{name:"吃瓜",keywords:"吃瓜,細說,真的假的,展開說說,尊嘟假嘟,臥槽,離譜",description:"統計群內最愛吃瓜的成員"},polite:{name:"禮貌",keywords:"謝謝,麻煩,收到,好的,辛苦,打擾,請教",description:"統計群內最客氣的成員"},curious:{name:"疑問",keywords:"為什麼,啥,怎麼,不懂,求教",description:"統計群內問題最多的成員"}}},Yy={title:"🔥 熱門複讀",loading:"正在載入複讀資料...",description:"單次複讀參與人數最多的內容",countTemplate:"共 {count} 筆熱門複讀",people:"{count}人",times:"{count} 次",colon:":",viewChat:"檢視聊天紀錄",empty:"暫無複讀資料"},Qy={dateAll:"全部訊息",dateNow:"至今",heroPrefix:"共分析了",heroMiddle:"則訊息,",heroMiddleSecond:"產生了",heroSuffix:"個不同詞彙",topTopicsPrefix:"你們最愛聊:",topKeywords:"熱門關鍵詞",hotTopic:"熱門話題",hotTopicDesc:"出現了 {count} 次",richness:"詞彙豐富度",richnessValue:"{value}%",richnessDesc:"不重複詞 {unique} / 總詞數 {total}",chatStyle:"聊天風格",styleEncyclopedia:"百科全書型",styleEncyclopediaDesc:"名詞佔比高,愛聊人、地、事",styleAction:"行動派",styleActionDesc:"動詞佔比高,愛討論做什麼",styleExpressive:"表達派",styleExpressiveDesc:"形容詞佔比高,善於修飾表達",styleBalanced:"均衡型",styleBalancedDesc:"聊天內容多元,各類話題均衡",expressionStyle:"表達風格",expressionCasual:"簡潔口語",expressionCasualDesc:"用詞簡短,輕鬆隨意",expressionFormal:"正式書面",expressionFormalDesc:"用詞考究,表達嚴謹",expressionMixed:"混合風格",expressionMixedDesc:"口語與書面兼顧",watermark:"話題畫像 · Topic Profile",sharedTopics:"共同話題"},Jy={title:"💬 口頭禪分析",loading:"正在分析口頭禪資料...",description:"已分析 {count} 位成員的高頻發言",countTemplate:"共 {count} 位成員",times:"{count} 次",empty:{title:"暫無口頭禪資料",description:"目前篩選條件下沒有足夠的重複發言用於產生詞雲"},stats:{phrasesLabel:"高頻短語",totalLabel:"總使用次數",clickHint:"提示:點擊可查看相關訊息"},viewMode:{list:"列表",wordcloud:"詞雲"},phraseCount:"{count} 條口頭禪",topN:"顯示數量"},Zy={loading:"正在分析語言偏好...",empty:"暫無足夠的文字訊息進行語言分析",card:{sharedWordsLabel:"共同高頻詞",syncSubtext:"基於詞性分佈的說話方式相似度",warmthWarm:"暖",warmthCrisp:"幹練",warmthBalanced:"自然",expressionLabel:"你們的表達充滿了",diversityTitle:"詞彙深度",diversityDesc:"不重複詞彙佔比",styleTitle:"聊天氣質",styleDesc:"基於詞性分佈推導的表達風格",punctTitle:"標點性格",punctDesc:"最常用的標點風格",punctTopTitle:"標點符號 TOP5",punctTopDesc:"各自最常使用的標點符號",modalTopTitle:"語氣詞 TOP5",modalTopDesc:"各自最常使用的語氣詞",sharedWordsTitle:"共同高頻詞",sharedWordsDesc:"雙方都高頻使用的詞彙",watermark:"語言偏好 · Language Preference",radarFactual:"事實性",radarActive:"行動感",radarDescriptive:"描述欲",radarAffable:"親和力",radarIntense:"程度感",radarNoun:"名詞",radarVerb:"動詞",radarAdj:"形容詞",radarModal:"語氣詞",radarAdv:"副詞",topCatchphrases:"熱門口頭禪",languageProfiles:"語言畫像"},catchphrasePK:{title:"口頭禪 PK",sharedCount:"{count} 個共同口頭禪",hint:"提示:點擊可查看相關訊息,粉框標記為共同口頭禪"},pos:{title:"詞性圖譜",styleEncyclopedia:"百科全書派",styleAction:"行動派",styleExpressive:"感性派",styleBalanced:"均衡派"},modal:{title:"語氣詞畫像",toneSoft:"軟萌親和",toneCurious:"好奇探索",toneCasual:"隨和建議",toneCalm:"沉穩內斂",toneMixed:"多元風格",empty:"暫無語氣詞資料"},punctuation:{title:"標點性格",none:"無標點",personalityDeep:"深沉文學型",personalityPassionate:"情緒飽滿型",personalityCurious:"好奇寶寶型",personalityCheerful:"心情愉悅型",personalityFreeflow:"意識流型",personalityPrecise:"嚴謹規範型",empty:"暫無標點資料"},sync:{title:"語言同頻度",description:"基於詞性分佈的說話方式相似度",labelSoulmate:"靈魂伴侶",labelHighSync:"高度默契",labelUnique:"各有特色",labelDiverse:"風格迥異"}},e0={wordcloud:Gy,keywords:Xy,hotRepeat:Yy,topicProfile:Qy,catchphrase:Jy,languagePreference:Zy},t0={title:"選擇你是誰",unset:"未設定",selectMember:"選擇成員",currentOwner:"目前:{name}",hint:"1. 會顯示在聊天紀錄檢視器右側 2. AI 對話中也會標示你的身分"},s0={title:"成員管理",description:"共 {count} 位成員,可為成員新增別名備註或移除成員",searchPlaceholder:"搜尋群暱稱、帳號名稱、ID 或別名",noMatch:"沒有找到符合的成員",empty:"暫無成員資料",table:{accountName:"帳號名稱",groupNickname:"群暱稱",messageCount:"訊息數",customAlias:"自訂別名",actions:"操作"},aliasPlaceholder:"輸入後按 Enter 新增",delete:"刪除",mergeSelected:"合併所選",mergeSelectedCount:"已選 {count} 位成員",pagination:"顯示第 {start} - {end} 筆,共 {total} 位成員",tip:"提示:新增別名後,搜尋與 AI 分析時會更容易辨識聊天對象。",mergeModal:{title:"確認合併成員?",content:"將成員 {source}({sourceCount} 則訊息)合併至 {target}({targetCount} 則訊息)下。預設保留訊息較多一方的名稱。",hint:"合併後無法復原,被合併成員的訊息將全部歸屬至保留成員。",cancel:"取消",confirm:"確認合併"},modal:{title:"確認刪除成員?",content:"即將刪除成員 {name} 及其 {count} 則訊息,此操作不可復原。",cancel:"取消",confirm:"確認刪除"}},a0={note:"備註:QQ 舊版客戶端支援匯出 txt 聊天紀錄,該版本能取得較完整的暱稱變更紀錄",title:"暱稱變更紀錄",loading:"載入中...",hasChanges:"{count} 位成員曾修改過暱稱",noChanges:"暫無成員修改暱稱",current:"當前",empty:"該群組所有成員均未修改過暱稱",loadingText:"正在載入暱稱變更紀錄..."},n0={loading:"正在分析 {'@'} 互動資料...",topMentioners:"📢 誰最喜歡 {'@'} 別人",totalMentions:"共 {count} 次 {'@'}",topMentioned:"🎯 誰最常被 {'@'}",popularMember:"群裡的人氣王",times:"次",oneWay:{title:"🐕 單向關注偵測",description:"發現 {count} 對單向關注關係(一方 {'@'} 另一方佔比 ≥80%)",neverRespond:"從不回應",reverse:"反向 {count} 次",ratio:"{value}% 單向"},twoWay:{title:"💕 雙向奔赴偵測",description:"發現 {count} 對互動頻繁的 CP(互相 {'@'} 且平衡度 ≥30%)",interactions:"次互動",balance:"{value}% 平衡"},emptyTitle:"📱 {'@'} 互動分析",empty:"暫無 {'@'} 互動資料",modal:{title:"{name} 的 {'@'} 關係",topMentioned:"最常 {'@'} 的人",topMentioners:"最常 {'@'} TA 的人",timesCount:"{count} 次",close:"關閉"}},o0={ownerSelector:t0,list:s0,nicknameHistory:a0,relationships:n0,private:{title:"對話成員",description:"共 {count} 位成員,可為成員新增別名備註用於搜尋和 AI 分析",messageCount:"訊息數",percentage:"佔比 {value}%",customAlias:"自訂別名",aliasPlaceholder:"輸入後按 Enter 新增別名",empty:"暫無成員資料",tipTitle:"提示",tipContent:"新增別名可以更好地識別聊天紀錄中的對話對象,別名將用於搜尋和 AI 分析中。"}},r0={title:"聊天紀錄檢視器",loadedCount:"已載入 {count} 條訊息"},i0={loading:"載入中...",noMessages:"暫無訊息",tryAdjustFilter:"嘗試調整篩選條件",loadingMore:"載入更多...",scrollUpForMore:"↑ 向上捲動載入更多",scrollDownForMore:"↓ 向下捲動載入更多"},l0={messageId:"訊息 ID",memberNotSupported:"成員(暫不支援)",keywordsPlaceholder:"關鍵字(多個請用逗號分隔,按 Enter 搜尋)",startDate:"起始日期",endDate:"結束日期",reset:"重置",filter:"篩選"},c0={timeline:"會話",noSessions:"暫無會話",generateSummary:"產生摘要",tooFewMessages:"訊息太少"},d0="摘要產生失敗",u0="未知錯誤",m0={title:"批次產生摘要",byRange:"依範圍",byTime:"依時間",selectRange:"選擇範圍",rangeStart:"最早",rangeInfo:"約",sessionsUnit:"個會話",rangeEnd:"最近",timeRange:"選擇時間範圍",today:"今天",yesterday:"昨天",week:"最近7天",month:"最近30天",custom:"自訂",found:"找到",hasSummary:"個已有摘要",tooFewMessages:"個訊息太少",pending:"待產生:",unit:"個",noPending:"沒有可產生摘要的會話",noSessions:"該時間範圍內沒有會話",checking:"檢查中...",loading:"載入中...",progress:"進度",session:"會話",statusSuccess:"成功",statusSkipped:"跳過",statusFailed:"失敗",success:"成功:",failed:"失敗:",skipped:"跳過:",start:"開始產生",stop:"停止"},g0={viewContext:"檢視上下文",contextTitle:"訊息上下文(前後各10條)",noContext:"暫無上下文",replyTo:"回覆"},p0={title:"會話索引",subtitle:"用於聊天紀錄的時間軸導覽",notGenerated:"尚未產生會話索引",notGeneratedHint:"產生會話索引後,您可以在聊天紀錄檢視器中透過時間軸快速切換到不同會話。",whatIsIt:"會話索引的作用:",benefit1:"根據訊息時間間隔自動識別會話邊界",benefit2:"在聊天紀錄檢視器中提供時間軸導覽",benefit3:"協助 AI 更理解對話上下文",generated:"會話索引已產生",sessionCount:"共識別出 {count} 個會話",regenerateHint:"如果您調整了會話間隔門檻,可重新產生索引。",generate:"產生索引",regenerate:"重新產生",generating:"產生中...",cancel:"取消"},f0={drawer:r0,messageList:i0,filter:l0,timeline:c0,summaryFailed:d0,summaryUnknownError:u0,batchSummary:m0,messageItem:g0,sessionIndex:p0},h0={title:"互動頻率",rankingView:"排行榜檢視",memberView:"成員檢視",matrixView:"矩陣檢視",modelSettings:"模型參數",lookAhead:"鄰近人數",lookAheadDesc:"每則訊息往後納入幾位發言者",decaySeconds:"時間衰減(秒)",decaySecondsDesc:"值越大,遠距離訊息權重越高",applySettings:"套用設定",noData:"暫無資料",selectMember:"選擇成員",selectMemberHint:"請從左側選擇一個成員",msgCount:"發言數",relationCount:"關係數",relationsByIntimacy:"發言鄰近度排行",noRelations:"暫無關係資料",intimacy:"鄰近度",interactionRanking:"互動排行榜",score:"鄰近度",coOccurrence:"共現",times:"次",totalMembers:"群成員",totalMessages:"訊息總數",involvedMembers:"參與成員",edgeCount:"關係數"},v0={typeDistribution:"訊息類型分佈",hourlyDistribution:"小時分佈",weekdayDistribution:"星期分佈",monthlyDistribution:"月份分佈",yearlyDistribution:"年份分佈",timeHeatmap:"時間熱力圖",heatmapHint:"顯示聊天時間分布規律",calendarHeatmap:"訊息日曆",calendarHint:"每日訊息分佈",calendarTooltipMessages:"訊息",lengthDetailTitle:"短訊息分佈 (1-25字)",lengthDetailHint:"逐字統計",lengthGroupedTitle:"長度區間分佈",lengthGroupedHint:"每5字一組",noTextMessages:"暫無文字訊息",noData:"暫無資料",profile:{totalMessages:"總訊息",textMessages:"文字訊息",avgLength:"平均長度",avgLengthUnit:"{count} 字/則",mediaRatio:"媒體佔比",textExpression:"文字表達力",textExpressionDesc:"最長訊息 {count} 字",mediaRichness:"媒體豐富度",shortMaster:"短訊息達人",shortMasterDesc:"共 {count} 則 ≤5字",essayLover:"小作文愛好者",essayLoverDesc:"≥{threshold}字的訊息",peakRecord:"巔峰紀錄",peakRecordDesc:"單日最多 {count} 則",topHours:"最活躍時段",images:"圖片",emoji:"表情",voiceVideo:"語音/影片",typeDistribution:"訊息類型",hourlyDistribution:"24h 活躍",watermark:"訊息報告",heroLine1Prefix:"你們共留下了",heroLine1Suffix:"則訊息",heroLine2Prefix:"每則平均",heroLine2Middle:"個字,其中",heroLine2Suffix:"是非文字訊息"}},y0={mentionGraph:"艾特互動關係圖",layout:"佈局",circular:"環形",force:"力導向",directed:"有向",reset:"重置",graphHint:"共 {nodes} 位成員,{links} 條互動關係",noInteraction:"暫無艾特互動資料"},b0={loading:"正在分析關係動態…",noIndex:{title:"需要對話索引",description:"關係分析依賴對話索引資料,請先在總覽頁面生成對話索引。"},empty:{title:"暫無關係資料",description:"目前時間範圍內沒有對話記錄。"},overview:{title:"整體概覽"},monthly:{title:"月度明細",totalSessionsPrefix:"共對話",totalSessionsSuffix:"次"},trend:{title:"主動性趨勢",hint:"藍色線為 {name} 的月度主動發起佔比,50% 線為均衡基準"},hero:{monthPart:"{year}年{month}月",timeRange:{singleMonth:"在 {month} 期間,",range:"在 {start} 至 {end} 期間,"},totalSessionsPrefix:"你們共進行了",totalSessionsSuffix:"次對話",initiativePrefix:"其中有",initiativeByPrefix:"的開場白由",initiativeBySuffix:"發起",initiateTimes:"次發起"},initiator:"發起話題",closer:"結束話題",closerTitle:"話題終結者",closerHint:"統計話題結束時最後發言的人。",initiated:"發起 {count} 次",closed:"結束 {count} 次",totalSessions:"共 {count} 次對話",times:"次",noActivity:"本月無互動",watermarkReport:"關係報告",monthFormat:"{year}年{month}月",monthShortFormat:"{month}月",monthDetail:"發起 {init} / 結束 {close}",iceBreaker:{title:"破冰達人",hint:"超過 24 小時沉默後主動打破僵局的次數",count:"{count} 次破冰",total:"共 {count} 次破冰"},responseLatency:{title:"回覆速度",hint:"收到對方訊息後平均多久回覆",count:"{count} 次回覆",seconds:"{n} 秒",minutes:"{n} 分鐘",minutesSeconds:"{m}分{s}秒",hours:"{n} 小時",hoursMinutes:"{h} 小時 {m} 分鐘"},perseverance:{title:"鍥而不捨",hint:"對方還沒回覆就又發了一則訊息的次數",hintWithThreshold:"對方{threshold}內還沒回覆就又發了一次訊息的次數",thresholdMinutes:"{n}分鐘",count:"{count} 次",total:"共 {count} 次",threshold:"間隔",empty:"在目前閾值下沒有鍥而不捨的記錄"},labels:{mutualPursuit:"雙向奔赴",silentGuardian:"默默守候",devotedHeart:"一往情深",distantBond:"若即若離",wellMatched:"勢均力敵",missingYou:"{name} 在想念",monologue:"{name} 的獨白",peacefulSilence:"各自安好",fleetingThoughts:"偶爾想起"}},_0={title:"時間軸檢視",description:"以視覺化方式呈現訊息時間分布與活躍週期變化"},x0={rankListPro:{fullRanking:"完整排行榜",memberCount:"共 {count} 位成員"},rankList:{unit:"條"},nicknameHistory:{periodToNow:"{start} ~ 至今",periodRange:"{start} ~ {end}",current:"目前",empty:"暫無暱稱紀錄"},listPro:{countTemplate:"共 {count} 項",fullRanking:"完整排行榜",empty:"暫無資料"}},k0={cluster:h0,message:v0,interaction:y0,relationship:b0,timeline:_0,charts:x0},w0="關鍵詞過濾",S0="方案列表",C0="方案名稱",M0="請輸入方案名稱",A0="新方案",T0="新建方案",$0="刪除方案",I0="設為預設",P0="預設方案",D0="關鍵詞過濾",L0="不過濾",E0="管理方案",R0="新增過濾詞",N0="輸入詞語後按 Enter 新增,支援空格或逗號分隔批量新增",F0="新增",U0="過濾詞列表",O0="清空全部",H0="尚無方案,點擊 + 新建",V0="尚無過濾詞,在上方輸入框新增",z0="選擇或建立一個過濾方案",B0="已過濾 {count} 個詞",W0="關閉",j0={title:w0,schemeList:S0,schemeName:C0,schemeNamePlaceholder:M0,defaultSchemeName:A0,createScheme:T0,deleteScheme:$0,setDefault:I0,isDefault:P0,filterScheme:D0,noFilter:L0,manage:E0,addWords:R0,addWordsPlaceholder:N0,add:F0,wordList:U0,clearAll:O0,emptyScheme:H0,emptyWords:V0,selectOrCreate:z0,activeCount:B0,close:W0},q0={common:kv,layout:Ov,settings:Zv,home:cy,analysis:wy,tools:Ty,providers:Hy,ai:Ky,quotes:e0,members:o0,records:f0,views:k0,wordFilter:j0},K0="確認",G0="キャンセル",X0="保存",Y0="編集",Q0="追加",J0="名前変更",Z0="スクリーンショット",eb="閉じる",tb="戻る",sb="完了",ab="リトライ",nb="読み込み中...",ob="初期化中...",rb="データがありません",ib="結果が見つかりません",lb="エクスポートに成功しました",cb="エクスポートに失敗しました",db="生成中...",ub="再生成",mb="フォルダーを開く",gb="先に設定でAIサービスを構成してください",pb="リセット",fb={general:"操作に失敗しました。再試行してください",network:"ネットワークエラー",unknown:"不明なエラー"},hb={image:"画像",video:"動画",audio:"音声",file:"ファイル",sticker:"スタンプ",link:"リンク"},vb={messages:"件のメッセージ",members:"人",days:"日"},yb={text:"テキスト",image:"画像",voice:"音声",video:"動画",file:"ファイル",emoji:"絵文字",link:"リンク",location:"位置情報",redPacket:"お年玉",transfer:"送金",poke:"ツンツン",call:"通話",share:"共有",reply:"返信",forward:"転送",contact:"連絡先カード",system:"システム",recall:"取り消し",other:"その他",unknown:"不明"},bb={mon:"月曜",tue:"火曜",wed:"水曜",thu:"木曜",fri:"金曜",sat:"土曜",sun:"日曜"},_b={jan:"1月",feb:"2月",mar:"3月",apr:"4月",may:"5月",jun:"6月",jul:"7月",aug:"8月",sep:"9月",oct:"10月",nov:"11月",dec:"12月"},xb={title:"言語を選択",subtitle:"ご希望のインターフェース言語を選択してください",next:"次へ"},kb={title:"プライバシーポリシーと利用規約",subtitle:"利用前に必ずお読みください",disagree:"同意しない",agree:"内容を確認して同意する",updateNotice:"規約内容が更新されました。再度お読みいただき、ご確認ください"},wb={selectDate:"日付を選択",clearDate:"日付をクリア"},Sb={mode:{recent:"最近",quarter:"四半期別",year:"年別",custom:"カスタム"},recent:{halfYear:"半年間",oneYear:"1年間",twoYears:"2年間",fiveYears:"5年間",all:"すべて"},display:{recent180:"最近半年間",recent365:"最近1年間",recent730:"最近2年間",recent1825:"最近5年間"},quarter:{label:"{year}年 第{quarter}四半期"},year:{label:"{year}年"}},Cb={allMembers:"すべてのメンバー"},Mb={confirm:K0,cancel:G0,delete:"削除",save:X0,edit:Y0,add:Q0,rename:J0,capture:Z0,close:eb,back:tb,done:sb,retry:ab,loading:nb,initializing:ob,noData:rb,noResults:ib,export:"エクスポート",exportSuccess:lb,exportFailed:cb,generating:db,regenerate:ub,openFolder:mb,errorNoAIConfig:gb,reset:pb,error:fb,attachment:hb,unit:vb,messageType:yb,weekday:bb,month:_b,languageSelect:xb,agreement:kb,datePicker:wb,timeSelect:Sb,userSelect:Cb},Ab="ChatLab",Tb="新しいチャットを分析",$b="ツール",Ib="チャット履歴",Pb="管理",Db="記録がありません",Lb="チャット名を検索",Eb="一致するチャット記録が見つかりません",Rb={rename:"名前変更",pin:"ピン留め",unpin:"ピン留め解除",delete:"削除"},Nb={title:"名前変更",placeholder:"新しい名前を入力してください"},Fb={title:"削除の確認",message:"チャット記録「{name}」を削除しますか?この操作は取り消せません。"},Ub={all:"すべて",private:"個人",group:"グループ"},Ob={importedAt:"インポート日時",lastMessageTs:"最新メッセージ",messageCount:"メッセージ数"},Hb={expand:"サイドバーを展開",collapse:"サイドバーを折りたたむ",hint:"右クリックでチャット記録の削除や名前変更ができます",search:"チャット記録を検索",sort:"並べ替え"},Vb="{count} 件のメッセージ",zb={helpAndFeedback:"フィードバックとヘルプ",settings:"設定"},Bb={brand:Ab,newAnalysis:Tb,tools:$b,chatHistory:Ib,manage:Pb,noRecords:Db,searchPlaceholder:Lb,noSearchResult:Eb,contextMenu:Rb,renameModal:Nb,deleteModal:Fb,filter:Ub,sort:Ob,tooltip:Hb,sessionInfo:Vb,footer:zb},Wb="設定",jb={basic:"基本設定",ai:"AI 設定",aiConfig:"モデルサービス",aiDefaultModel:"デフォルトモデル",aiPrompt:"チャット設定",aiPreprocess:"前処理",dataManage:"データ管理",storage:"ストレージ管理",storageManage:"ストレージ管理",sessionManage:"セッションインデックス",about:"ChatLabについて",api:"オートメーション",apiSubTabs:{autoSync:"自動同期",apiService:"API サービス",mcp:"MCP"}},qb={general:{title:"一般"},preferences:{title:"環境設定"},language:{title:"言語",description:"アプリの表示言語を選択します"},appearance:{title:"外観設定",themeMode:"テーマモード",auto:"システムに従う",light:"ライトモード",dark:"ダークモード"},defaultTab:{title:"デフォルトタブ",description:"チャットに入った時に表示するページ",overview:"概要",aiChat:"AI チャット"},autoLaunch:{title:"起動設定",openAtLogin:"ログイン時に自動起動",openAtLoginDesc:"システム起動時に ChatLab を自動的に実行します",devModeHint:"開発モードでは利用できません"},toolsPanel:{positionLabel:"ツールパネルの位置",positionDesc:"クイックツールパネルの表示位置を選択します",positionSide:"サイド",positionHeader:"ヘッダー"},screenshot:{title:"スクリーンショット設定",mobileAdapt:"モバイル対応",mobileAdaptDesc:"スクリーンショット時に幅を自動調整し、モバイル端末での閲覧に最適化します"},network:{title:"ネットワーク設定",proxyMode:"プロキシモード",proxyModeDesc:"ネットワークアクセス時に使用するプロキシ方式",modeOff:"オフ",modeSystem:"システムに従う",modeManual:"手動設定",proxyAddress:"プロキシアドレス",proxyPlaceholder:"http://127.0.0.1:7890",proxyHelp:"HTTP/HTTPS プロキシに対応。形式例:http://127.0.0.1:7890",testConnection:"接続テスト",testing:"テスト中...",connectionSuccess:"プロキシ接続に成功しました!",connectionFailed:"接続に失敗しました",enterProxyFirst:"先にプロキシアドレスを入力してください",invalidProxyUrl:"有効なプロキシアドレスを入力してください。形式例:http://127.0.0.1:7890",onlyHttpSupported:"http:// または https:// プロトコルのみ対応",saveFailed:"保存に失敗しました"}},Kb={title:"デフォルトモデル",noConfigs:"先に「モデルサービス」でモデル設定を追加してください",selectProvider:"プロバイダーを選択",selectModel:"モデルを選択",assistantModel:{label:"デフォルトアシスタントモデル",description:"AIチャット、ツール呼び出し、SQLアシスタント、コンテキスト圧縮に使用"},fastModel:{label:"高速モデル",description:"セッション要約生成に使用。未設定の場合はデフォルトアシスタントモデルを使用",followAssistant:"デフォルトアシスタントモデルに従う"}},Gb={title:"モデルサービス",providerTitle:"サービスプロバイダー",loading:"読み込み中...",inUse:"使用中",defaultModel:"デフォルトモデル",localService:"ローカルサービス",edit:"編集",delete:"削除",empty:{title:"AI サービスが未設定です",description:"設定を追加して AI を使い始めましょう"},addConfig:"サービスを追加",maxConfigs:"設定は最大 10 件までです",modal:{addConfig:"サービスを追加",editConfig:"サービスを編集",officialApi:"公式 API",officialApiDesc:"DeepSeek や Gemini など",localService:"ローカルサービス",localServiceDesc:"Ollama など",openaiCompatible:"OpenAI 互換",openaiCompatibleDesc:"カスタムエンドポイント",configName:"設定名",optional:"(任意)",configNamePlaceholderPreset:"空欄の場合、サービス名が使用されます",configNamePlaceholderCustom:"空欄の場合、API エンドポイントが使用されます",aiProvider:"AI プロバイダー",apiKeyPlaceholder:"API Key を入力",apiKeyPlaceholderEdit:"新しい API Key を入力(空欄で現在の値を維持)",apiKeyPlaceholderLocal:"ローカルサービスでは通常不要です",apiKeyHintLocal:"サービスに認証が設定されている場合はこちらに入力",validate:"接続確認",validationSuccess:"接続を確認しました",validationFailed:"接続の確認に失敗しました",validationFailedTitle:"API接続の検証に失敗しました",saveAnywayHint:"検証に通過しませんでした。設定が正しくない可能性があります。それでも保存しますか?",saveAnyway:"保存する",validationError:"検証に失敗:",model:"モデル",modelName:"モデル名",modelNamePlaceholder:"例: gpt-4、claude-3",modelNamePlaceholderLocal:"例: qwen3、deepseek-r1",modelNameHint:"API がサポートするモデル名を入力",modelNameHintLocal:"ローカルにデプロイしたモデル名を入力",apiEndpoint:"API URL",apiEndpointHint:"OpenAI 互換形式の API エンドポイント",resolvedUrl:"実際のリクエストURL:",fetchModels:"APIから取得",fetchModelsTitle:"リモートモデル一覧",fetchModelsLoading:"モデルリストを取得中...",fetchModelsEmpty:"モデルが見つかりません",fetchModelsError:"モデルリストの取得に失敗しました",fetchModelsCount:"全 {total} モデル、{shown} 件表示中",modelAdded:"追加済み",addAllModels:"すべて追加",searchModels:"モデルを検索...",apiEndpointOverrideHint:"デフォルトURLは入力済みです。必要に応じて変更してください",disableThinking:"思考モードをオフ",disableThinkingDesc:"Qwen3 や DeepSeek-R1 などのモデル向け。オフにすると標準のツール実行形式を使います",isReasoningModel:"推論モデル",isReasoningModelDesc:"有効にすると推論過程を抽出し、ツール実行を無効にします(DeepSeek-R1、QwQ など)",advancedOptions:"詳細設定",customService:"カスタムサービス",unnamedConfig:"名称未設定",visitWebsite:"公式サイト",getApiKey:"APIキーを取得",presetService:"プリセット",thirdPartyService:"サードパーティ",customModelInput:"モデルを手動入力",selectFromList:"リストから選択",addCustomModel:"モデルを追加",deleteCustomModel:"選択を削除",customModelId:"モデルエンドポイント名",customModelIdHint:"API呼び出しで使用されるモデル識別子",customModelDisplayName:"表示名",customModelDisplayNamePlaceholder:"カスタム表示名",editModel:"モデルを編集",contextWindow:"コンテキストウィンドウ",contextWindowPlaceholder:"例: 128000",contextWindowHint:"モデルがサポートする最大コンテキストトークン数(コンテキスト圧縮に使用)",contextWindowMissing:"コンテキストウィンドウが未設定です。デフォルト値が使用されます。「モデル編集」から手動で設定してください",modelRequired:"少なくとも 1 つのモデルを追加してから保存してください",modelCapabilities:"モデル能力ラベル",apiFormat:"API インターフェース",apiFormatOpenAI:"OpenAI Completions",apiFormatAnthropic:"Anthropic",apiFormatGemini:"Gemini",apiFormatOpenAIResponses:"OpenAI Responses"},providerKind:{official:"公式",aggregator:"アグリゲータ",custom:"カスタム"},capabilities:{chat:"チャット",reasoning:"推論",vision:"ビジョン",function_calling:"ツール呼出",embedding:"エンベディング",ranking:"ランキング"}},Xb={title:"ローカルストレージ管理",description:"ChatLab がローカルに保存したデータファイルを管理します",dataLocation:{title:"データディレクトリの場所",description:"ローカルデータとキャッシュの保存先をカスタマイズ",choose:"場所を選択",reset:"デフォルトに戻す",open:"開く",migrateHint:"データがまだ旧ディレクトリにあります。統一ディレクトリへの移行をお勧めします:",migrateAction:"今すぐ移行",restartTip:"ディレクトリ変更後はアプリを再起動してください。旧ディレクトリのキャッシュは自動で移行されます",confirmTitle:"データディレクトリの切り替えを確認",confirmMessage:"データの保存先を切り替えます。既存データは新しいディレクトリに移行されます。",newPath:"新しいディレクトリパス",defaultPath:"デフォルトの場所",confirmWarning:"アプリ再起動後、旧データディレクトリは自動的に削除されます。新しいディレクトリパスが正しいことを確認してください。",installDirForbidden:"データディレクトリをアプリのインストールディレクトリ内に配置することはできません。更新時にディレクトリが消去されます",cancel:"キャンセル",confirm:"切り替えを確認",migrationSuccessTitle:"データ移行が完了しました",migrationSuccessMessage:"変更を反映するにはアプリの再起動が必要です。",relaunchNow:"今すぐ再起動"},openRootDir:"ルートを開く",totalUsage:"合計使用量:",loading:"読み込み中...",files:"ファイル",notExist:"存在しません",clear:"クリア",open:"開く",cache:{databases:{name:"チャット履歴データベース",description:"インポートしたチャット履歴の分析データ"},ai:{name:"AI 会話データベース",description:"AI チャット履歴と設定ファイル"},downloads:{name:"ダウンロードディレクトリ",description:"スクリーンショットや分析結果などを含む"},statsCache:{name:"キャッシュデータ",description:"チャット記録の統計キャッシュ。クリア後に自動で再構築されます"},logs:{name:"ログファイル",description:"アプリの実行ログ(インポート、AI、エラーなどのログを含む)"}}},Yb={session:{title:"セッションインデックス設定",description:"セッションインデックスは時間間隔に応じてチャット履歴を自動で区切り、AI 分析や閲覧をしやすくします",defaultThreshold:"デフォルト分割間隔",thresholdUnit:"分",thresholdHelp:"この時間を超える間隔があるメッセージは新しいセッションに分割されます",notGenerated:"セッションインデックスが未生成です",generateHint:"生成すると、AI が会話の流れをより正確に把握できます",generate:"インデックスを生成",regenerate:"再生成",generating:"作成中",sessionCount:"{count} セッション",generated:"セッションインデックス生成済み",generateSuccess:"セッションインデックスの生成に成功しました。全 {count} セッション",generateError:"生成に失敗しました",batchTitle:"インデックスを一括生成",totalSessions:"全 {count} チャット",generatedCount:"生成済み {count} 件",notGeneratedCount:"未生成 {count} 件",loadingStatus:"読み込み中...",batchGenerate:"未生成分を作成",batchRegenerate:"すべて再生成",summaryStrategy:"要約の詳細度",summaryStrategyHelp:"AI が要約を生成する際の詳細さを設定します",summaryBrief:"簡潔",summaryStandard:"標準"}},Qb={chatSettings:{title:"ツール設定"},exportSettings:{title:"エクスポート設定"},skillSettings:{title:"スキル設定",enableAutoSkill:"AI 自動スキル選択",enableAutoSkillDesc:"有効にすると、AI がユーザーの質問に基づいて適切な分析スキルを自動的にマッチして有効化します。無効にすると、手動で選択した場合のみスキルが適用されます"},maxMessages:{title:"送信メッセージ数の上限",description:"1 回のリクエストで AI に送る最大メッセージ数です。増やすほど Token 消費は増えますが、分析精度も上がります(初めてなら 2000 推奨)"},searchContext:{title:"検索コンテキストウィンドウ",description:"検索ヒット時に前後の会話コンテキストを自動的に含めることで、AI がメッセージの背景を理解しやすくなります。0 に設定するとコンテキストなし",before:"前",after:"後"},exportFormat:{title:"会話エクスポート形式",description:"AI チャットをエクスポートする際のファイル形式",txtLabel:"TXT"},sqlExportFormat:{title:"SQL Lab エクスポート形式",description:"SQL クエリ結果をエクスポートする際のファイル形式"},compression:{title:"コンテキスト圧縮",enable:"コンテキストの自動圧縮",enableDesc:"会話が長くなった際に履歴を自動的に要約に圧縮し、トークン消費を削減します",threshold:"圧縮閾値",thresholdDesc:"コンテキストトークンがモデルウィンドウのこの割合に達したら圧縮を開始",buffer:"バッファサイズ",bufferDesc:"圧縮せずに保持する最新メッセージの割合",maxToolResultPercent:"ツール結果の上限",maxToolResultPercentDesc:"1回のツール呼び出しでAIに送信される最大データ割合(モデルのコンテキストウィンドウに基づいて計算)。超過分はスマートに切り捨てられます"},presets:{title:"システムプロンプト",add:"プリセットを追加",import:"プリセットをインポート",description:"プロンプトはグループチャットと個人チャットの両方の分析に使用されます。分析タイプに応じて内容が自動的に調整されます"},preset:{builtIn:"内蔵",groupOnly:"グループチャットのみ",privateOnly:"個人チャットのみ",view:"表示",edit:"編集",copy:"コピー",delete:"削除"},modal:{editBuiltin:"システムプロンプトを編集",editCustom:"カスタムプロンプトを編集",addCustom:"カスタムプロンプトを追加",presetName:"プリセット名",presetNamePlaceholder:"プリセットの名前を入力",applicableTo:"適用シーン",applicableToHint:"(チェックすると対応する分析タイプで使用可能になります)",groupChat:"グループチャット分析",privateChat:"個人チャット分析",systemPrompt:"システムプロンプト",systemPromptPlaceholder:"AI アシスタントの役割、タスク、回答要件を定義...",preview:"完全プロンプトプレビュー",previewHint:"(プレビューはグループチャットモードです。実際は分析タイプに応じて自動調整されます)",resetToDefault:"デフォルトに戻す",saveChanges:"変更を保存",addPreset:"プリセットを追加"},importPreset:{title:"プリセットをインポート",description:"リモートから推奨のシステムプロンプトプリセットを取得します",loading:"リモートプリセットを読み込み中...",loadError:"リモートプリセットの読み込みに失敗しました",noPresets:"利用可能なリモートプリセットがありません",commonPresets:"共通プリセット",groupPresets:"グループチャット専用プリセット",privatePresets:"個人チャット専用プリセット",add:"追加",added:"追加済み",preview:"プレビュー",systemPrompt:"システムプロンプト",noDescription:"説明がありません",fetchingContent:"コンテンツを読み込み中...",fetchError:"コンテンツの読み込みに失敗しました"}},Jb={title:"ChatLabについて",description:"ローカルで動くチャット履歴分析ツール。SQL と AI Agent で会話を振り返れます。",version:"バージョン",checkUpdate:"アップデートを確認",checking:"確認中...",upToDate:"最新バージョンです",newVersionAvailable:"新しいバージョン {version} があります",updateNow:"今すぐ更新",webUpdateHint:"ターミナルで npm install -g chatlab-cli@latest を実行し、サービスを再起動してください。",updating:"更新中...",updateSuccess:"更新が完了しました。サービスを再起動してください",updateFailed:"更新に失敗しました:{error}",updateCheckFailed:"更新確認に失敗しました:{error}",unknown:"不明",privacy:{title:"プライバシー設定",analytics:"匿名利用統計",analyticsDesc:"有効にすると、バージョン番号やOS情報などの非機密データを収集し、製品の改善に役立てます"},developer:{title:"開発者オプション",debugMode:"DEBUG モード",debugModeDesc:"有効にすると、デバッグパネルとクイックデバッグツールが表示されます。データベースの確認、テストツールの実行、より詳細なデバッグログの記録に使用できます。"}},Zb={title:"チャット履歴の前処理",description:"チャット履歴を AI に送信する前に前処理を行い、Token を節約しノイズを除去します。元のデータは変更されません。",dataCleaning:"データクリーニング",dataCleaningDesc:"XML カードメッセージ(共有リンク、ミニアプリなど)を自動クリーニングし、有効な内容を抽出します。Token を大幅に節約できます。オンのままにすることを推奨します。",mergeConsecutive:"連続発言の結合",mergeConsecutiveDesc:"同一人物の短時間内の連続メッセージを1つに結合します",mergeWindow:"結合タイムウィンドウ(秒)",denoise:"スマートノイズ除去",denoiseDesc:"感動詞のみ、絵文字のみ、システムプレースホルダー([画像] など)といった無意味なメッセージを除去します",desensitize:"データマスキング",desensitizeDesc:"ルールに基づいて機密情報(電話番号、メールアドレス、身分証番号など)をプレースホルダーに置換します",desensitizeRules:"マスキングルール",desensitizeRulesDesc:"有効にするマスキングルールにチェックを入れてください。リスト順に優先マッチングされます",desensitizeBuiltin:"プリセットルール",desensitizeCustom:"カスタムルール",desensitizeAddCustom:"カスタムルールを追加",desensitizeRuleName:"ルール名",desensitizeRulePattern:"正規表現",desensitizeRuleReplacement:"置換テキスト",desensitizeRuleAdd:"追加",desensitizeRuleInvalidRegex:"正規表現の構文エラー",desensitizeRuleNamePlaceholder:"例:社員番号",desensitizeRulePatternPlaceholder:"例:EMP-\\d+",desensitizeRuleReplacementPlaceholder:"置換テキスト。例:[社員番号]",anonymizeNames:"ニックネーム匿名化",anonymizeNamesDesc:"実際のニックネームの代わりに番号(U1、U2…)を AI に送信し、幻覚を減らして Token を節約します",blacklist:"ブラックリストキーワード",blacklistDesc:"以下のキーワードのいずれかを含むメッセージは丸ごと除外されます",blacklistPlaceholder:"キーワードを入力して Enter で追加",blacklistAdd:"追加"},e_={rules:{cn_phone:"中国の携帯電話番号",cn_phone_desc:"1xx xxxx xxxx 形式の11桁の番号",cn_id_card:"中国の身分証番号",cn_id_card_desc:"18桁、末尾に X を含む場合あり",cn_bank_card:"中国の銀行カード番号",cn_bank_card_desc:"16-19桁の連続数字",cn_landline:"中国の固定電話番号",cn_landline_desc:"市外局番-番号(例:010-12345678)",us_ssn:"米国社会保障番号(SSN)",us_ssn_desc:"XXX-XX-XXXX 形式",us_phone:"米国電話番号",us_phone_desc:"+1 (XXX) XXX-XXXX 形式",us_drivers_license:"米国運転免許証番号",us_drivers_license_desc:"アルファベット + 7-8桁の数字",jp_phone:"日本の電話番号",jp_phone_desc:"0x0-XXXX-XXXX 形式",jp_my_number:"マイナンバー",jp_my_number_desc:"12桁の数字(マイナンバー)",kr_phone:"韓国の電話番号",kr_phone_desc:"01X-XXXX-XXXX 形式",kr_rrn:"韓国の住民登録番号",kr_rrn_desc:"XXXXXX-XXXXXXX 形式(주민번호)",api_key_prefix:"API Key / Token(既知プレフィックス)",api_key_prefix_desc:"sk-、ghp_、AKIA などで始まる長い文字列",bearer_token:"Bearer Token",bearer_token_desc:"Bearer に続く認証トークン値",email:"メールアドレス",email_desc:"user{'@'}domain.com の標準形式",credit_card:"クレジットカード番号",credit_card_desc:"Visa / MasterCard / AmEx などのカード番号",ipv4:"IPv4 アドレス",ipv4_desc:"例:192.168.1.1",url:"URL リンク",url_desc:"http:// または https:// で始まるリンク"}},t_={betaWarning:"現在の API バージョンはベータ版であり、インターフェースが変更される可能性があります",service:{title:"API サービス",enable:"API サービスを有効化",enableDesc:"有効にすると、外部ツールが HTTP API 経由でチャットデータの照会・エクスポート・インポートができます。ローカルホストのみ (127.0.0.1)",portInUseHint:"ポートが使用中です。下のポートを変更するか、このポートを使用しているプログラムを終了してから再試行してください"},status:{running:"実行中",stopped:"停止中",starting:"起動中...",portInUse:"ポート使用中",error:"起動失敗"},port:{title:"ポート設定",label:"リッスンポート",desc:"API サービスのローカルポート番号(1024-65535)",edit:"編集",save:"保存",cancel:"キャンセル"},token:{title:"アクセストークン",label:"Bearer Token",desc:"すべての API リクエストは Authorization ヘッダーにこのトークンを含める必要があります",noToken:"トークンが未生成です。まずサービスを有効にしてください",regenerate:"再生成"},dataSources:{title:"データソース",desc:"外部データソースの URL を設定すると、ChatLab が指定間隔で自動的にチャットデータを取得・インポートします。",empty:"データソースなし",disabled:"一時停止中",every:"",minutes:"分ごと",lastSync:"最終同期",syncing:"同期中",messages:"件",addBtn:"データソースを追加",form:{modalTitle:"データソースを追加",name:"名前",namePlaceholder:"例:マイチャットサーバー",url:"データソース URL",token:"アクセストークン(任意)",tokenPlaceholder:"リモート API の Bearer Token",interval:"取得間隔(分)",pullLimit:"1回の取得メッセージ数",pullLimitPlaceholder:"デフォルト 1000",targetSession:"ターゲットセッション ID(任意)",targetSessionPlaceholder:"空欄の場合、毎回新規セッションを作成",add:"追加"},discovery:{directMode:"直接 URL",remoteMode:"リモートサーバー",baseUrl:"サーバーアドレス",baseUrlPlaceholder:"例:http://127.0.0.1:2333/api/v1",browse:"セッションを参照",found:"{count} 件のセッションが見つかりました",search:"検索",searchPlaceholder:"セッション名で検索",selectAll:"すべて選択",deselectAll:"選択解除",selectByType:"セッションタイプ",typeAll:"すべて",typePrivate:"個人チャット",typeGroup:"グループチャット",typeOther:"その他",loadMore:"さらに読み込む",subscribe:"{count} 件を購読",messages:"件のメッセージ",error:"リモートサーバーへの接続に失敗しました",connectionCheckFailed:"リモートサーバーに接続できません。URL とトークンを確認してください。"},noSessions:"インポートセッションがありません。上の「サブスクリプション管理」から追加してください",edit:{title:"設定を変更",save:"保存",cancel:"キャンセル",editSource:"設定を変更",manageSessions:"サブスクリプション管理",manageSessionsDesc:"同期するリモートセッションを再選択",syncAll:"一括同期",subscribed:"購読中"},deleteConfirm:{title:"データソースを削除",message:"データソース「{name}」を削除してもよろしいですか?このデータソース下のすべてのインポート設定が削除されます。既にインポート済みのローカル会話は削除されません。"},deleteSessionConfirm:{title:"サブスクリプションを削除",message:"「{name}」を削除してもよろしいですか?",keepData:"サブスクリプションのみ削除",deleteData:"インポートしたチャットも削除"}},usage:{title:"使用ガイド",desc:"サービスを有効にすると、外部ツールが API 経由でデータを照会したり、ChatLab にチャット記録をプッシュしたりできます。すべてのリクエストに Bearer Token 認証が必要です。",authHint:"ヘッダー例:",docLink:"API ドキュメントを見る"}},s_={overview:{title:"MCP 概要",description:"MCP により、AI アシスタントがチャット記録を直接クエリできます。セッション検出、キーワード検索、メンバー統計、時間分布などをサポートしています。",toolCount:"{count} 個のツール",resourceCount:"{count} 個のリソース",installHint:"chatlab-cli をインストール後、AI クライアントに以下の設定を追加してください:"},clients:{other:"その他"},config:{title:"クライアント設定",clientLabel:"MCP クライアント",copy:"コピー",copied:"コピー済み",claudeHint:"この設定を ClaudeCode の MCP 設定に追加してください。",codexHint:"この TOML 設定を ~/.codex/config.toml ファイルに追加してください。",openclawHint:"この設定をプロジェクトの openclaw.json ファイルに追加してください。",otherHint:"この JSON 設定を MCP クライアントの設定ファイルに追加してください。"},tips:{title:"ヒント",dataDir:"MCP サーバーは ~/.chatlab/ ディレクトリのチャットデータを読み取り、デスクトップアプリと同じデータを共有します。",readOnly:"すべての操作は読み取り専用で、チャット記録は変更されません。",nodeRequired:"npx および CLI モードには Node.js 20 以上が必要です。",docs:"詳細なドキュメントは docs.chatlab.fun をご覧ください。"}},a_={title:Wb,tabs:jb,basic:qb,defaultModel:Kb,aiConfig:Gb,storage:Xb,ai:Yb,aiPrompt:Qb,about:Jb,aiPreprocess:Zb,desensitize:e_,api:t_,mcp:s_},n_="新しいチャットの記憶を探索する",o_={file:"ファイルインポート",api:"自動同期",push:"APIインポート",apiDescription:"外部プラットフォームのデータソースを設定し、チャット履歴をChatLabへ定期的に自動同期します。",apiButton:"自動同期を設定する",pushDescription:"ローカルAPIサーバーを起動し、サードパーティのツール・プラグイン・スクリプトからChatLabへチャット履歴をプッシュできます。",pushButton:"APIサーバーを設定する"},r_={viewExample:"デモを試す",downloading:"デモデータをダウンロード中...",importing:"デモデータをインポート中...",failed:"デモデータの読み込みに失敗しました。ネットワーク接続を確認してから再試行してください。"},i_={title:"データベースのアップグレードが必要です",description:"新機能をサポートするため、{count} 件のデータベースをアップグレードする必要があります。",note:"アップグレードは通常数秒で完了し、データは失われません。",upgradeContent:"今回のアップグレード内容:",upgradeNow:"今すぐアップグレード",upgrading:"アップグレード中...",failed:"移行に失敗しました",partialFailed:"一部のデータベースのアップグレードに失敗しました",errorHint:"これは通常、データベースファイルの破損が原因です。サイドバーで失敗したセッションを削除し、再度インポートすることをお勧めします。",close:"閉じる",retry:"リトライ"},l_={title:"インポートするチャットを選択",scanning:"チャットリストをスキャン中...",scanFailed:"スキャンに失敗しました",retry:"リトライ",selectAll:"すべて選択",chatCount:"全 {count} 件のチャット",selected:"{count} 件を選択中",messageCount:"{count} 件のメッセージ",import:"インポート ({count})",noChats:"チャットが見つかりません"},c_={title:"チャット形式を選択",hint:"ファイル形式を自動検出できませんでした。対応するチャット形式を手動で選択してください。",manualSelect:"形式を手動で選択",confirm:"この形式でインポート"},d_={export:"初心者ガイド",import:"対応フォーマット一覧"},u_={website:"公式サイト",terms:"利用規約"},m_={title:"バージョン履歴",subtitle:"すべてのバージョン更新内容を確認",viewChangelog:"バージョン履歴",latest:"最新バージョン",current:"現在のバージョン",total:"全 {count} バージョン",close:"閉じる",loadError:"バージョン履歴の読み込みに失敗しました",retry:"リトライ",types:{feat:"新機能",fix:"バグ修正",refactor:"リファクタリング",docs:"ドキュメント更新",chore:"その他の改善",style:"スタイル改善",ci:"CI/ビルド"}},g_={tagline:n_,tabs:o_,import:{dropHint:"マウスを離してファイルをインポート",clickHint:"クリックして選択、またはチャット記録をドラッグ&ドロップでインポート",multipleHint:"複数ファイルの同時選択・ドラッグに対応しています",selectFiles:"チャット記録ファイルを選択",selectFolder:"エクスポートフォルダを選択",importFolder:"フォルダをインポート",chatRecords:"チャット記録",allFiles:"すべてのファイル",progress:{detecting:"フォーマットを検出中...",reading:"ファイルを読み込み中...",parsing:"メッセージを解析中...",saving:"データベースに書き込み中...",done:"インポート完了",error:"インポート中断"},processed:"{count} 件のメッセージを処理しました",viewLog:"インポートログを表示",cannotReadPath:"ファイルパスを読み取れません",preparing:"インポートを準備中...",errors:{no_file_selected:"ファイルが選択されていません",import_failed:"インポートに失敗しました",unrecognized_format:"認識できないファイル形式です",no_messages:"メッセージを検出できませんでした。ファイル形式が正しいか確認してください",actionHint:"下記の手動マッチングまたはログの確認をお試しください:"},diagnostics:{format:"検出フォーマット:",received:"受信メッセージ:",written:" / 書き込み:",skipped:" / スキップ:"},batch:{importing:"一括インポート中",progressCount:"{current} / {total} 件目",cancel:"インポートをキャンセル",waiting:"待機中",skipped:"スキップ済み",success:"インポート成功",completed:"一括インポート完了",summary:"成功 {success} 件、失敗 {failed} 件、スキップ {cancelled} 件",view:"表示"},options:{title:"その他のオプション",mergeImport:"結合インポート",mergeImportHint:"チェックすると、複数ファイルが1つのチャット記録に結合されます"},merge:{importing:"結合中",parsing:"ファイルを解析中...",parsingFile:"解析中: {name}",merging:"メッセージを結合中...",completed:"結合完了",completedHint:"{count} 件のファイルを結合しました",messageCount:"{count} 件のメッセージ",failed:"結合に失敗しました",cancel:"結合をキャンセル"}},demo:r_,migration:i_,chatSelector:l_,formatSelector:c_,quickStart:d_,footer:u_,changelog:m_},p_={title:"グループ分析",loading:"分析データを読み込み中...",loadError:"セッションデータを読み込めません",description:"{startDate} から {endDate} までの間に、{messageCount} 件のメッセージをやり取りしています"},f_={title:"個人チャット分析",loading:"分析データを読み込み中...",loadError:"セッションデータを読み込めません",description:"{startDate} から {endDate} までの間に、{messageCount} 件のメッセージをやり取りしています"},h_={overview:"概要",view:"インサイト",ranking:"ランキング",groupQuotes:"名言集",quotes:"名言集",members:"メンバー",member:"メンバー",ai:"AIラボ",aiChat:"AIチャット",memory:"メモリー",lab:"ラボ",sqlLab:"SQLラボ",debug:"Debug"},v_={sqlTables:"SQLテーブル",basicTools:"基本ツール",tableBrowser:{chatDb:"チャット DB",aiDb:"AI会話 DB",selectTable:"テーブルを選択",rowCount:"{count} 行",page:"{current} / {total} ページ",prevPage:"前へ",nextPage:"次へ",refresh:"更新",noData:"データなし",editRow:"編集",deleteRow:"行を削除",save:"保存",cancel:"キャンセル",confirmDelete:"この行を削除してもよろしいですか?",deleteSuccess:"削除しました",saveSuccess:"保存しました",operationFailed:"操作に失敗しました",allConversations:"すべての会話",copyCell:"選択項目をコピー",copyRow:"行をコピー (JSON)",clearDebugContext:"デバッグコンテキストをクリア",confirmClearDebug:"すべてのメッセージの debug_context を削除しますか?この操作は取り消せません。"}},y_={comingSoon:"メモリー機能は近日公開予定です。お楽しみに"},b_={allTime:"全期間",year:"{year}年"},__={viewChatRecord:"チャット履歴を見る",sessionIndex:"セッション索引",incrementalImport:"追加インポート",memberManagement:"メンバー管理"},x_={title:"チャット記録を追加",description:"「{name}」に追加するチャット履歴ファイルを選択してください。重複は自動で除外されます。",selectFile:"チャット記録ファイルを選択",dropHint:"クリックして選択、またはファイルをここにドラッグ",analyzing:"ファイルを分析中...",totalInFile:"ファイル内のメッセージ数",newMessages:"新規メッセージ",duplicates:"重複メッセージ",noNewMessages:"新しいメッセージはありません。すべて取り込み済みです",importing:"インポート中...",import:"{count} 件を取り込む",success:"インポート成功",successDetail:"{count} 件の新しいメッセージを追加しました",failed:"インポートに失敗しました"},k_={view:{message:"メッセージ",topic:"トピック",interaction:"インタラクション分析",groupRelationships:"グループ関係",ranking:"ランキング",relationship:"関係",languagePreference:"言語傾向"},quotes:{wordcloud:"トピック",hotRepeat:"盛り上がった復唱",catchphrase:"口癖",keywordAnalysis:"キーワード分析",languagePreference:"言語傾向"},groupRelationships:{mentionGraph:"{'@'} 関係図",mentionRanking:"{'@'} ランキング",proximity:"発言の近接度"},member:{memberList:"メンバー一覧",relationships:"関係性",cluster:"やり取り頻度",nicknameHistory:"ニックネーム変更履歴"}},w_={messageTypeDistribution:"メッセージタイプ分布",memberDistribution:"メンバー別発言割合",others:"その他",messageRatio:"メッセージ割合",messageUnit:"件",memberComparison:"双方のメッセージ割合",statCards:{dailyAvgMessages:"1日あたりのメッセージ",messagesCount:"{count} 件",daysCount:"合計 {count} 日間",imageMessages:"画像メッセージ",imagesCount:"{count} 枚",peakHour:"最も活発な時間帯:",mostActiveWeekday:"最も活発な曜日",messagesOnDay:"{count} 件のメッセージ",weekendActivity:"週末の活発度",weekendRatio:"週末メッセージの割合",mostActiveDate:"最も活発な日",activeDays:"アクティブ日数",slashDays:"/ {count} 日",consecutiveStreak:"連続日数",daysStreak:"{count} 日間",longestStreak:"最長連続アクティブ",activityRate:"アクティブ率",activeDaysRatio:"メッセージのある日の割合",lateNightChat:"深夜チャット",lateNightRatio:"全メッセージの {ratio}%"},dailyTrend:{title:"日別メッセージトレンド"},identity:{privateChat:"プライベートチャット",groupChat:"グループチャット",analysisReport:"分析レポート",totalMessages:"メッセージ総数",durationDays:"期間日数",activeDays:"アクティブ日数",dailyAvgMessages:"日平均メッセージ"},tools:"よく使うツール"},S_={expand:"ツールパネルを展開",collapse:"ツールパネルを折りたたむ",lock:"パネルを固定",unlock:"パネルの固定を解除",miniMode:"ミニモード",exitMini:"ミニモードを終了"},C_={title:"チャット記録をエクスポート"},M_={title:"詳細フィルター",conditionMode:"条件フィルター",sessionMode:"セッションフィルター",history:"履歴",execute:"絞り込む",export:"フィルター結果をエクスポート",keywords:"キーワード",keywordsHint:"複数のキーワードに対応、OR条件でマッチします",keywordPlaceholder:"キーワードを入力してEnterで追加",timeRange:"期間",allTime:"すべて",today:"今日",lastWeek:"過去7日間",lastMonth:"過去1ヶ月",last3Months:"過去3ヶ月",lastYear:"過去1年",customTime:"カスタム",senders:"送信者",sendersHint:"任意。空欄の場合は制限なし",searchMember:"メンバーを検索...",noMembers:"メンバーがいません",selectedCount:"{count} 人を選択済み",contextSize:"前後表示",messages:"件のメッセージ",searchSession:"日付を検索...",selectedSessions:"{count} 個のセッションを選択中",noSessions:"セッション索引がありません",filtering:"フィルター中...",emptyHint:"フィルター条件を設定してから実行してください",noResults:"一致するメッセージが見つかりません",blockTitle:"会話ブロック {index}",stats:{blocks:"会話ブロック",messages:"メッセージ数",hits:"ヒット数",chars:"文字数"},historyTitle:"フィルター履歴",noHistory:"履歴がありません",loadMore:"もっと読み込む",allLoaded:"すべて読み込み済み",exportSuccess:"エクスポートに成功しました",exportFailed:"エクスポートに失敗しました",exportPreparing:"エクスポート準備中..."},A_={groupChat:p_,privateChat:f_,tabs:h_,debug:v_,memory:y_,yearFilter:b_,tooltip:__,incremental:x_,subTabs:k_,overview:w_,toolsPanel:S_,messageExport:C_,filter:M_},T_="管理",$_="チャット履歴を管理",I_={batchManage:"一括管理"},P_={title:"一括削除",description:"削除するチャット履歴を選択してください",searchPlaceholder:"チャット名を検索",searchResult:"{count} / {total} 件を検出",noSearchResult:"一致するチャット履歴が見つかりません",selectAll:"すべて選択",shiftClickHint:"Shiftキーを押しながらクリックで範囲選択できます",selected:"{count} 件を選択中",empty:"チャット履歴がありません",delete:"選択した項目を削除",confirmTitle:"削除の確認",confirmMessage:"選択した {count} 件のチャット履歴を削除しますか?この操作は取り消せません。",deleting:"削除中...",success:"{count} 件のチャット履歴を削除しました",error:"削除に失敗しました:{error}",messageCount:"{count} 件のメッセージ",importedAt:"{time} にインポート",columns:{name:"名前",platform:"プラットフォーム",messages:"メッセージ数",summaries:"AI要約",aiChats:"AI チャット",importedAt:"インポート日時"},clickToEdit:"クリックして名前を編集",merge:"選択項目を結合",mergeHint:"結合するには同じチャット種別の履歴を 2 件以上選択してください",mergeConfirmTitle:"チャット履歴を結合",mergeConfirmMessage:"選択した {count} 件のチャット履歴を結合し、新しい統合履歴を作成します。",deleteOriginalsLabel:"結合後に元のチャット履歴を削除する",mergeRiskWarning:"重要な警告:削除は元に戻せず、プラットフォーム間の文脈差により意味が混在する可能性があります。続行前に元データをバックアップしてください。",mergeSteps:{exporting:"チャット履歴をエクスポート中...",parsing:"ファイルを解析中...",checking:"競合を検出中...",merging:"データを結合中...",cleaning:"一時ファイルを削除中..."},mergeSuccess:"{count} 件のチャット履歴を結合しました",mergeError:"結合に失敗しました:{error}",mergedSuffix:"結合"},D_={title:T_,description:$_,tabs:I_,batchManage:P_},L_={name:"DeepSeek",models:{"deepseek-v4-pro":"フラッグシップモデル、1M コンテキスト、思考・非思考モード対応","deepseek-v4-flash":"高速モデル、1M コンテキスト、思考・非思考モード対応"}},E_={name:"通義千問",models:{"qwen-turbo":"Qwen の高速モデル","qwen-plus":"Qwen の高性能モデル","qwen-max":"Qwen のフラッグシップモデル"}},R_={name:"Gemini",models:{"gemini-3-flash-preview":"高速プレビュー版","gemini-3-pro-preview":"高性能プレビュー版"}},N_={name:"MiniMax",models:{"MiniMax-M2":"フラッグシップモデル","MiniMax-M2-Stable":"安定版"}},F_={name:"GLM",models:{"glm-4-plus":"フラグシップモデル、最高性能","glm-4-flash":"高速モデル、コスト性能良好","glm-4":"標準モデル","glm-4v-plus":"マルチモーダルビジョンモデル","glm-4.6v-flash":"4.6V 無料モデル","glm-4.5-flash":"4.5 無料モデル"}},U_={name:"Kimi",models:{"moonshot-v1-8k":"8K コンテキスト","moonshot-v1-32k":"32K コンテキスト","moonshot-v1-128k":"128K 超ロングコンテキスト"}},O_={name:"豆包",models:{"doubao-seed-1-6-lite-251015":"Doubao 1.6 軽量モデル","doubao-seed-1-6-251015":"Doubao 1.6 高性能モデル","doubao-seed-1-6-flash-250828":"Doubao 1.6 高速モデル","doubao-1-5-lite-32k-250115":"Doubao 1.5 Pro モデル"}},H_={name:"SiliconFlow"},V_={name:"Groq"},z_={name:"OpenRouter"},B_={name:"xAI"},W_={deepseek:L_,qwen:E_,gemini:R_,minimax:N_,glm:F_,kimi:U_,doubao:O_,siliconflow:H_,groq:V_,openrouter:z_,xai:B_,"openai-compatible":{name:"サードパーティ"}},j_={chatExplorer:"対話で探索",sqlLab:"SQL ラボ",featureInDev:"{name}機能は開発中です",comingSoon:"近日公開...",followNotice:"新機能のお知らせは公式 Xiaohongshu で発信しています"},q_={welcome:{configReady:"✅ AI サービスの設定が完了しました。すぐにチャットを始められます。",configNeeded:"**ご注意**:ご利用前にサイドバー下部の「設定」から AI サービスを設定してください ⚙️"},capture:"会話を画像保存",scrollToBottom:"下へ移動",input:{placeholder:"質問を入力...",placeholderWithSlash:"質問を入力、または / でスキル、{'@'} でメンバーを選択...",placeholderWithActiveSkill:"/{name} を選択済みです。具体的な質問を入力してください...",removeSkill:"現在のスキルを解除",slashHint:"/ でスキルを選択",useSkill:"スキルを選ぶ",mentionHint:"{'@'} でメンバーを選択",mentionEmpty:"一致するメンバーがいません",mentionEmptyHint:"ニックネーム、別名、アカウントで検索できます",slashEmpty:"一致するスキルがありません",slashEmptyHint:"スキル管理を開いて内蔵スキルを読み込むか、カスタムスキルを作成してください",manageSkills:"スキルを管理",previewTitle:"スキルプロンプト",previewTagsLabel:"タグ",previewToolsLabel:"ツール",previewUnavailable:"プレビューできるスキルプロンプトがありません",presetMore:"もっと見る",presetCollapse:"折りたたむ",quickAsk:"クイック質問",editQuickAsk:"クイック質問を編集",send:"送信",needMoreThanSkill:"スキルを選んだだけでは送信できません。具体的な質問を入力してください。",needQuestion:"質問を入力してから送信してください"},backgroundTask:{runningShort:"進行中",runningTitle:"AI がバックグラウンドで推論中です",runningDescription:"前の質問がまだ処理中です。完了を待つか、先に停止してください。",blockedAction:"現在の回答はまだ生成中です。完了を待つか、手動で停止してください。",return:"戻って確認"},message:{userAvatar:"ユーザーアバター",calling:"実行中",copy:{tooltip:"Markdown をコピー",success:"Markdown をクリップボードにコピーしました",failed:"Markdown のコピーに失敗しました"},tools:{get_chat_overview:"チャット概要を取得",search_messages:"チャット履歴を検索",deep_search_messages:"チャット履歴を深層検索",get_recent_messages:"最近のメッセージを取得",get_member_stats:"メンバー統計を取得",get_time_stats:"時間分布を取得",get_members:"メンバー一覧を取得",get_member_name_history:"ニックネーム履歴を取得",get_conversation_between:"やり取り履歴を取得",get_message_context:"コンテキストを取得",search_sessions:"セッションを検索",get_session_messages:"セッションメッセージを取得",get_session_summaries:"セッション要約を取得",response_time_analysis:"応答時間分析",keyword_frequency:"キーワード頻度分析",message_type_breakdown:"メッセージ種別分布",peak_chat_hours_by_member:"メンバー活動時間帯",member_activity_trend:"メンバー活動傾向",silent_members:"休眠メンバー検出",reply_interaction_ranking:"返信インタラクションランキング",mutual_interaction_pairs:"頻繁なインタラクションペア",member_message_length_stats:"メッセージ長統計",daily_active_members:"日別アクティブ人数",conversation_initiator_stats:"話題開始者統計",activity_heatmap:"活動ヒートマップ",unanswered_messages:"未返信メッセージ"},generating:"回答を作成中...",summary:{label:"コンテキスト要約",expand:"要約を展開",collapse:"要約を折りたたむ",info:"以前の会話がコンテキスト節約のため要約に圧縮されました"},think:{labels:{think:"思考",analysis:"分析",reasoning:"推論",reflection:"振り返り",other:"思考({tag})"},loading:"思考中...",duration:"{seconds}秒"},toolParams:{keywords:"キーワード",time:"時間",getMessages:"{count} 件のメッセージを取得",limit:"{count} 件に制限",contextWithMessages:"{msgCount} 件のメッセージの前後各 {contextSize} 件のコンテキスト",context:"前後各 {size} 件のコンテキスト",topMembers:"上位 {count} 名のメンバー",search:"検索",getMemberList:"メンバー一覧を取得",memberId:"メンバーID",timeStats:{hourly:"時間別",weekday:"曜日別",daily:"日別"}}},thinking:{processingResult:"結果を整理中",called:"実行したツール:",analyzing:"問題を分析中...",compressing:"コンテキストを圧縮中..."},statusBar:{preset:{default:"既定",groupTitle:"グループチャット用プロンプト",privateTitle:"個人チャット用プロンプト",manage:"プロンプト管理"},model:{title:"AI モデル設定",notConfigured:"AI 未設定",empty:"設定がありません",manage:"設定を管理",switchFailed:"モデルの切り替えに失敗しました"},messageLimit:{label:"メッセージ上限:",title:"1回の送信で含む最大メッセージ数。クリックして設定"},agent:{label:"Agent",contextTokens:"コンテキスト",stats:"セグメント {segment} ・タグ {tags}",phase:{compressing:"圧縮中",preparing:"準備中",thinking:"思考中",tool_running:"ツール実行中",responding:"応答中",completed:"完了",aborted:"停止",error:"エラー"},phaseShort:{compressing:"圧縮",preparing:"準備",thinking:"思考",tool_running:"ツール",responding:"生成",completed:"完了",aborted:"停止",error:"エラー"}},tokenUsageTitle:"累計 Token 使用量",export:{label:"エクスポート",title:"現在のチャットをエクスポート"},log:{label:"ログ",title:"現在の AI ログファイルを開く",openFailed:"ログを開けませんでした",openFailedDesc:"しばらくしてから再度お試しください"},compress:{label:"圧縮",title:"手動でコンテキストを圧縮",compressing:"圧縮中...",success:"コンテキストが圧縮されました",successDesc:"{before} → {after} トークン",skipped:"圧縮をスキップ",skippedDesc:"圧縮に十分なメッセージがありません",failed:"圧縮に失敗しました"},status:{connected:"AI 接続中",notConfigured:"グローバル設定で AI サービスを設定してください"}},conversation:{title:"AI チャット履歴",newChat:"新規チャット",newConversation:"新規チャット",empty:"履歴はありません",startNew:"新しいチャットを始める",titlePlaceholder:"タイトルを入力...",group:{last7Days:"過去 7 日間",last30Days:"過去 30 日間"},rename:"名前を変更",delete:"削除",export:{createdAt:"作成日時",user:"ユーザー",assistant:"AI アシスタント",noMessages:"会話にメッセージがありません"}},error:{title:"処理に失敗しました",detail:"エラー詳細",viewDetail:"詳細を表示",requestUrl:"リクエストURL",statusCode:"ステータスコード",responseBody:"レスポンスボディ",responseHeaders:"レスポンスヘッダー",requestBody:"リクエストボディ",name:"エラー名",message:"エラーメッセージ",stack:"スタックトレース",cause:"エラー原因",provider:"プロバイダー",copyAll:"すべてコピー",copied:"クリップボードにコピーしました",unknown:"不明なエラー"},dataSource:{title:"データソース",keywords:"キーワード:",empty:"データがありません",emptyHint:"質問を送信すると、関連する記録がここに表示されます",totalRecords:"全 {count} 件の記録",loadMore:"さらに読み込む"}},K_={editor:{errorEmptySQL:"SQL 文を入力してください",placeholder:"SQL クエリを入力...",promptTip:"自然言語で要件を書くと、SQL を自動生成して実行します",tip:"ヒント:左側の列名をダブルクリックすると SQL に挿入できます",history:"履歴",aiGenerate:"AI 生成",generateAndRun:"生成して実行",switchToSQLMode:"SQL 入力モードに切り替え",switchToPromptMode:"Prompt 入力モードに切り替え",shortcut:"Ctrl/⌘ + Enter で実行",run:"実行"},schema:{tables:"テーブル",doubleClickToInsert:"ダブルクリックで SQL に挿入",primaryKey:"主キー"},result:{queryError:"クエリエラー",rows:"{count} 行",readableTime:"タイムスタンプを日付に変換",viewChat:"チャット履歴を見る",summarize:"要約する",pageSize:"表示件数",pageInfo:"{current} / {total} ページ",emptyResult:"クエリ結果が空です",initialState:"SQL 文を入力して実行すると結果が表示されます",initialHint:"読み取り専用クエリ(SELECT / WITH)のみ対応しています。速度向上のため LIMIT の指定をおすすめします",summaryTitle:"AI 結果サマリー",analyzing:"AI が結果を分析中...",errorSummary:"要約に失敗しました"},generate:{title:"AI で SQL 生成",description:"自然言語でクエリ内容を説明すると、AI が対応する SQL 文を自動生成します。",placeholder:"例:発言数が最も多い上位10名のメンバーを検索、1日あたりのメッセージ数を集計、「旅行」というキーワードを含むメッセージを検索...",errorEmptyPrompt:"クエリ要件を入力してください",errorGenerate:"AI 生成に失敗しました",errorTokenLimit:"モデル出力がトークン上限に達し、完全な応答を生成できませんでした(思考にトークンを消費しすぎた可能性があります)",aiOutput:"AI 出力",thinking:"思考中…",thinkingProcess:"思考プロセス",waitingAI:"AI の応答待ち...",sqlStatement:"SQL 文",explanation:"説明",generateSQL:"SQL を生成",useSQL:"SQL を使用",run:"実行",defaultPromptPrivate:"この個人チャットの直近1年間について、2人それぞれのメッセージ総数・割合・アクティブ日数・アクティブ日あたり平均件数・初回発言時刻・最終発言時刻を集計し、メッセージ総数の降順で表示してください。",defaultPromptGroup:"このグループチャットの直近1年間について、各メンバーのメッセージ総数・割合・アクティブ日数・アクティブ日あたり平均件数・テキスト比率を集計し、表示名付きでメッセージ総数の降順上位20名を返してください。"},history:{title:"AI 生成履歴",execute:"実行",empty:"履歴はありません",justNow:"たった今",minutesAgo:"{count} 分前",hoursAgo:"{count} 時間前",today:"今日"}},G_={selector:{title:"アシスタントを選んでチャットを始めましょう",heroTitlePrefix:"",heroTitleSuffix:"と話しかける",subtitle:"各アシスタントは得意分野が異なります。目的に合うものを選んでください",noAssistants:"現在のシーンで利用可能なアシスタントはありません",manage:"アシスタント管理",addNew:"アシスタントを追加"},config:{viewTitle:"設定を確認",createTitle:"アシスタントを作成",editTitle:"アシスタント設定",betaWarning:"現在はベータ版のため、設定仕様が今後変わる可能性があります。プロンプトや関連設定は控えを残してください。",tabs:{basic:"基本設定",tools:"ツール管理"},name:"名前",systemPrompt:"システムプロンプト",chatType:"対応チャットタイプ",chatTypeAll:"すべて",chatTypeGroup:"グループチャット",chatTypePrivate:"個人チャット",locale:"対応言語",localeHint:"未選択なら全言語が対象です",presetQuestions:"プリセット質問",addQuestion:"質問を追加...",builtinTools:"標準ツール",coreTools:"コアツール",coreToolsHint:"基本データ取得ツール、常に有効、無効化不可",analysisTools:"分析ツール",analysisToolsHint:"必要に応じて有効化。チェックしたツールのみ AI が利用可能",selectAll:"すべて選択",deselectAll:"すべて解除",builtinToolsHint:"何も選ばなければ全ツールを使います。選択した場合は、そのツールだけが有効になります。",toolGroupQuery:"データ検索ツール",resetDefault:"デフォルトに戻す",create:"作成"},market:{title:"アシスタント管理",tabs:{local:"ローカル",market:"マーケット"},localHint:"インポート済みのアシスタントを管理・設定・削除",marketHint:"アシスタントマーケットを閲覧し、インポートして使用・カスタマイズ",default:"デフォルト",updateAvailable:"更新あり",reimport:"再インポート",imported:"インポート済み",import:"インポート",importing:"インポート中...",importSuccess:"インポート成功",importFailed:"インポート失敗",viewConfig:"設定を見る",duplicate:"複製",addAssistant:"アシスタントを追加",noLocal:"インポート済みのアシスタントはありません",noCatalog:"利用可能なアシスタントがありません。ネットワーク接続を確認してください",loading:"読み込み中...",loadFailed:"読み込みに失敗しました。ネットワーク接続を確認してください",retry:"再試行"},fallbackName:"アシスタント",duplicateSuffix:"(コピー)",toast:{loadFailed:"読み込みに失敗しました",createSuccess:"作成しました",createFailed:"作成に失敗しました",saveSuccess:"保存しました",saveFailed:"保存に失敗しました",resetSuccess:"デフォルトに戻しました",resetFailed:"リセットに失敗しました",unknownError:"不明なエラー"},builtinToolDesc:{get_chat_overview:"チャット概要情報を取得",search_messages:"チャットメッセージを検索",deep_search_messages:"チャットメッセージを深層検索",get_recent_messages:"最近のメッセージを取得",get_message_context:"メッセージのコンテキストを取得",get_conversation_between:"2人のやり取りを取得",get_members:"メンバー一覧を取得",get_member_stats:"メンバー統計を取得",get_member_name_history:"メンバーの名前変更履歴を取得",get_time_stats:"時間統計を取得",search_sessions:"セッションを検索",get_session_messages:"セッションメッセージを取得",get_session_summaries:"セッション要約を取得",message_type_breakdown:"メッセージ種別分布",peak_chat_hours_by_member:"メンバー活動時間帯",member_activity_trend:"メンバー活動トレンド",silent_members:"沈黙メンバー検出",reply_interaction_ranking:"返信インタラクションランキング",mutual_interaction_pairs:"相互インタラクションペア",member_message_length_stats:"メッセージ長さ統計",unanswered_messages:"未返信メッセージ",daily_active_members:"日別アクティブ人数推移",conversation_initiator_stats:"話題開始者統計",activity_heatmap:"活性度ヒートマップ",response_time_analysis:"応答時間分析",keyword_frequency:"高頻度キーワード統計"}},X_={market:{title:"スキル管理",tabs:{local:"ローカル",market:"マーケット"},localHint:"インポート済みのスキルを管理・設定・削除",marketHint:"スキルマーケットを閲覧し、インポートして使用・カスタマイズ",updateAvailable:"更新あり",reimport:"再インポート",imported:"インポート済み",import:"インポート",importing:"インポート中...",importSuccess:"インポート成功",importFailed:"インポート失敗",noLocal:"インポート済みのスキルはありません",noCatalog:"利用可能なスキルがありません。ネットワーク接続を確認してください",addSkill:"カスタムスキルを作成",loading:"読み込み中...",loadFailed:"読み込みに失敗しました。ネットワーク接続を確認してください",retry:"再試行"},block:{label:"スキル:{name}"},active:{label:"手動呼び出しスキル:{name}"}},Y_={basicTools:"基本ツール",toolTest:{selectTool:"ツールを選択",selectToolPlaceholder:"ツールを選択してください...",coreTools:"コアツール",analysisTools:"分析ツール",parameters:"パラメータ",arrayPlaceholder:"カンマで区切って入力",execute:"実行",cancel:"キャンセル",elapsed:"所要時間 {ms}ms",result:"実行結果",truncated:"結果が大きすぎるため、切り捨てて表示しています。limit パラメータを小さくしてください。"}},Q_={tab:j_,chat:q_,sqlLab:K_,assistant:G_,skill:X_,lab:Y_},J_={loading:"単語頻度を分析中...",sidebar:{filter:"フィルター設定",style:"スタイル設定"},stats:{messagesLabel:"メッセージ数",wordsLabel:"総単語数",uniqueLabel:"ユニーク単語",clickHint:"ヒント:ワードクラウドをクリックすると関連メッセージを表示できます"},config:{maxWords:"表示単語数",sizeScale:"フォントサイズ",userFilter:"ユーザーフィルター",posFilter:"品詞フィルター",enableStopwords:"ストップワードを除外",dict:"辞書",advanced:"詳細設定"},size:{small:"小",medium:"中",large:"大",xlarge:"特大"},posFilter:{all:"すべての品詞",meaningful:"主要品詞",custom:"カスタム",customHint:"品詞を指定",selectMeaningful:"主要品詞",selectAll:"すべて選択",clearAll:"クリア"},empty:{title:"ワードクラウドデータがありません",description:"現在の絞り込み条件では、ワードクラウドを作れるほどテキストメッセージがありません"},dict:{zhCN:"簡体字中国語",zhTW:"繁体字中国語",download:"辞書をダウンロード","download_zh-CN":"簡体字辞書をダウンロード","download_zh-TW":"繁体字辞書をダウンロード",needDownload:"ワードクラウドを使用するには辞書のダウンロードが必要です",downloadHint:"~8MB",downloadSuccess:"辞書のダウンロードが完了しました",downloadFailed:"辞書のダウンロードに失敗しました",promptTitle:"繁体字中国語辞書",promptDescription:"繁体字中国語をご使用中です。ワードクラウドの精度を上げるため、繁体字辞書のダウンロードをお勧めします。今すぐダウンロードしますか?(約8MB)",promptDownload:"今すぐダウンロード",promptLater:"後で"}},Z_={title:"🔍 キーワードランキング",description:"グループチャットのキーワード使用ランキングを分析します。カスタムランキングも作成できます",countTemplate:"全 {count} 名のメンバー",templateLabel:"テンプレート:",newTemplate:"+ 新規作成",searchPlaceholder:"入力して検索",clear:"クリア",templateHint:"* テンプレートを右クリックで編集・削除できます",keyword:"キーワード",ranking:"ランキング",multiColorMode:"マルチカラーモード",times:"{count}回",timesWithPercent:"回 ({percent}%)",loading:"データを分析中...",empty:"データがありません。キーワードを追加するかテンプレートを切り替えてください",contextMenu:{edit:"編集",delete:"削除"},modal:{createTitle:"テンプレートを作成",editTitle:"テンプレートを編集",templateName:"テンプレート名",templateNamePlaceholder:"例:ポジティブ",keywords:"キーワード",keywordPlaceholder:"入力して Enter で追加",cancel:"キャンセル",save:"保存",update:"更新"},templates:{laugh:{name:"笑い度",keywords:"笑,ウケる,草,www,lol,ワロタ,233",description:"グループ内の笑い指数を集計"},sad:{name:"落ち込み度",keywords:"辛い,しんどい,泣いた,無理,きつい,疲れた",description:"グループ内のネガティブ感情を集計"},praise:{name:"褒め上手",keywords:"すごい,さすが,天才,神,やばい,尊い,最高",description:"グループで最も褒め上手なメンバーを集計"},slacker:{name:"サボり",keywords:"サボり,帰りたい,お腹空いた,眠い,仕事したくない,定時",description:"グループで最も退勤を待ち望んでいるメンバーを集計"},gossip:{name:"ゴシップ好き",keywords:"マジで,詳しく,本当に,えぇ,やばい,ありえない",description:"グループで最もゴシップ好きなメンバーを集計"},polite:{name:"礼儀正しさ",keywords:"ありがとう,すみません,了解,お疲れ様,よろしく,恐れ入ります",description:"グループで最も礼儀正しいメンバーを集計"},curious:{name:"質問好き",keywords:"なぜ,なんで,どうやって,わからない,教えて",description:"グループで最も質問が多いメンバーを集計"}}},ex={title:"🔥 盛り上がった復唱",loading:"リピートデータを読み込み中...",description:"1 回の復唱で最も多くの人が参加したフレーズ",countTemplate:"全 {count} 件の復唱",people:"{count}人",times:"{count} 回",colon:":",viewChat:"チャット履歴を見る",empty:"リピートデータがありません"},tx={dateAll:"すべてのメッセージ",dateNow:"現在まで",heroPrefix:"",heroMiddle:"件のメッセージを分析し、",heroMiddleSecond:"その結果、",heroSuffix:"個のユニークな単語が見つかりました",topTopicsPrefix:"よく話すトピック:",topKeywords:"人気キーワード",hotTopic:"注目トピック",hotTopicDesc:"{count} 回出現",richness:"語彙の豊かさ",richnessValue:"{value}%",richnessDesc:"ユニーク {unique} / 合計 {total}",chatStyle:"チャットスタイル",styleEncyclopedia:"百科事典タイプ",styleEncyclopediaDesc:"名詞が多く、人・場所・物の話題が中心",styleAction:"アクション派",styleActionDesc:"動詞が多く、行動や計画の話題が中心",styleExpressive:"表現豊かタイプ",styleExpressiveDesc:"形容詞が多く、感情表現が豊か",styleBalanced:"バランス型",styleBalancedDesc:"多様なトピックでバランスの取れた会話",expressionStyle:"表現スタイル",expressionCasual:"カジュアル",expressionCasualDesc:"短い言葉でリラックスした表現",expressionFormal:"フォーマル",expressionFormalDesc:"丁寧な言葉遣いで正確な表現",expressionMixed:"ミックス",expressionMixedDesc:"カジュアルとフォーマルの混合",watermark:"トピックプロフィール",sharedTopics:"共通のトピック"},sx={title:"💬 口癖分析",loading:"口癖データを分析中...",description:"{count} 名の高頻度フレーズを分析しました",countTemplate:"全 {count} 名のメンバー",times:"{count}回",empty:{title:"口癖データがありません",description:"現在の絞り込み条件では、ワードクラウドを生成できるほど繰り返しフレーズがありません"},stats:{phrasesLabel:"高頻度フレーズ",totalLabel:"合計使用回数",clickHint:"ヒント:クリックすると関連メッセージを表示できます"},viewMode:{list:"リスト",wordcloud:"ワードクラウド"},phraseCount:"{count} 件の口癖",topN:"表示数"},ax={loading:"言語傾向を分析中...",empty:"言語分析に十分なテキストメッセージがありません",card:{sharedWordsLabel:"共通の高頻度単語",syncSubtext:"品詞分布に基づく話し方の類似度",warmthWarm:"暖かい",warmthCrisp:"簡潔",warmthBalanced:"バランス",expressionLabel:"あなたたちの表現は",diversityTitle:"語彙の深さ",diversityDesc:"ユニーク単語の割合",styleTitle:"チャット気質",styleDesc:"品詞分布に基づく表現スタイル",punctTitle:"句読点パーソナリティ",punctDesc:"最も使われる句読点スタイル",punctTopTitle:"句読点 TOP5",punctTopDesc:"最もよく使う句読点",modalTopTitle:"終助詞 TOP5",modalTopDesc:"最もよく使う終助詞",sharedWordsTitle:"共通の高頻度単語",sharedWordsDesc:"二人とも高頻度で使う単語",watermark:"言語傾向 · Language Preference",radarFactual:"事実性",radarActive:"行動力",radarDescriptive:"描写力",radarAffable:"親和力",radarIntense:"強調度",radarNoun:"名詞",radarVerb:"動詞",radarAdj:"形容詞",radarModal:"終助詞",radarAdv:"副詞"},catchphrasePK:{title:"口癖バトル",sharedCount:"{count} 個の共通口癖",hint:"クリックで関連メッセージを表示。ピンク枠は共通の口癖です。"},pos:{title:"品詞ポートレート",styleEncyclopedia:"百科事典タイプ",styleAction:"行動派",styleExpressive:"感性派",styleBalanced:"バランス型"},modal:{title:"終助詞プロフィール",toneSoft:"やわらかい",toneCurious:"好奇心旺盛",toneCasual:"カジュアル",toneCalm:"落ち着き",toneMixed:"多彩なスタイル",empty:"終助詞データがありません"},punctuation:{title:"句読点パーソナリティ",none:"句読点なし",personalityDeep:"深い思考型",personalityPassionate:"情熱的",personalityCurious:"好奇心型",personalityCheerful:"明るい",personalityFreeflow:"自由型",personalityPrecise:"几帳面",empty:"句読点データがありません"},sync:{title:"言語シンクロ度",description:"品詞分布に基づく話し方の類似度",labelSoulmate:"ソウルメイト",labelHighSync:"高い同期",labelUnique:"それぞれの個性",labelDiverse:"対照的なスタイル"}},nx={wordcloud:J_,keywords:Z_,hotRepeat:ex,topicProfile:tx,catchphrase:sx,languagePreference:ax},ox={title:"あなたを選択してください",unset:"未設定",selectMember:"メンバーを選択",currentOwner:"現在:{name}",hint:"1. チャット履歴ビューアの右側に表示されます 2. AI との会話ではあなた本人として扱われます"},rx={title:"メンバー管理",description:"全 {count} 名のメンバー。別名の追加やメンバーの削除ができます",searchPlaceholder:"グループニックネーム、アカウント名、ID、または別名で検索",noMatch:"一致するメンバーが見つかりません",empty:"メンバーデータがありません",table:{accountName:"アカウント名",groupNickname:"グループニックネーム",messageCount:"メッセージ数",customAlias:"カスタム別名",actions:"操作"},aliasPlaceholder:"入力して Enter で追加",delete:"削除",mergeSelected:"選択を結合",mergeSelectedCount:"{count} 名を選択中",pagination:"{start} - {end} 件表示、全 {total} 名のメンバー",tip:"ヒント:別名を追加すると、チャット履歴の相手をより正確に識別できます。別名は検索や AI 分析で使用されます。",mergeModal:{title:"メンバーを結合しますか?",content:"{source}({sourceCount} 件)を {target}({targetCount} 件)へ結合します。結合後の名前は、メッセージ数が多い側を優先して保持します。",hint:"この操作は元に戻せません。結合される側のメッセージはすべて保持側に移動します。",cancel:"キャンセル",confirm:"結合を確認"},modal:{title:"メンバーを削除しますか?",content:"メンバー {name} とその {count} 件のメッセージを削除します。この操作は元に戻せません。",cancel:"キャンセル",confirm:"削除を確認"}},ix={note:"備考:QQ の旧バージョンクライアントはチャット履歴を txt 形式でエクスポートできます。この形式では最も正確なニックネーム変更履歴が取得できます",title:"ニックネーム変更履歴",loading:"読み込み中...",hasChanges:"{count} 名のメンバーがニックネームを変更しました",noChanges:"ニックネームを変更したメンバーはいません",current:"現在",empty:"このグループのすべてのメンバーはニックネームを変更していません",loadingText:"ニックネーム変更履歴を読み込み中..."},lx={loading:"{'@'} インタラクションデータを分析中...",topMentioners:"📢 最も {'@'} する人",totalMentions:"全 {count} 回の {'@'}",topMentioned:"🎯 最も {'@'} される人",popularMember:"グループの人気者",times:"回",oneWay:{title:"🐕 片思い検出",description:"{count} 組の片思い関係を発見(一方の {'@'} が80%以上を占める)",neverRespond:"返信なし",reverse:"逆方向 {count} 回",ratio:"{value}% 片方向"},twoWay:{title:"💕 両思い検出",description:"{count} 組の頻繁な相互やり取りを発見(互いに {'@'} かつバランス度 ≥30%)",interactions:"回のやり取り",balance:"{value}% バランス"},emptyTitle:"📱 {'@'} インタラクション分析",empty:"{'@'} インタラクションデータがありません",modal:{title:"{name} の {'@'} 関係",topMentioned:"最も {'@'} する相手",topMentioners:"最も {'@'} してくる相手",timesCount:"{count} 回",close:"閉じる"}},cx={ownerSelector:ox,list:rx,nicknameHistory:ix,relationships:lx,private:{title:"会話メンバー",description:"全 {count} 名のメンバー。検索や AI 分析に使用する別名を追加できます",messageCount:"メッセージ数",percentage:"割合 {value}%",customAlias:"カスタム別名",aliasPlaceholder:"入力して Enter で別名を追加",empty:"メンバーデータがありません",tipTitle:"ヒント",tipContent:"別名を追加すると、チャット履歴の相手をより正確に識別できます。別名は検索や AI 分析で使用されます。"}},dx={title:"チャット履歴ビューア",loadedCount:"{count} 件のメッセージを読み込みました"},ux={loading:"読み込み中...",noMessages:"メッセージがありません",tryAdjustFilter:"フィルター条件を調整してみてください",loadingMore:"さらに読み込み中...",scrollUpForMore:"↑ 上にスクロールしてさらに読み込む",scrollDownForMore:"↓ 下にスクロールしてさらに読み込む"},mx={messageId:"メッセージ ID",memberNotSupported:"メンバー(未対応)",keywordsPlaceholder:"キーワード(複数はカンマ区切り、Enter で検索)",startDate:"開始日",endDate:"終了日",reset:"リセット",filter:"フィルター"},gx={timeline:"セッション",noSessions:"セッションがありません",generateSummary:"要約を作成",tooFewMessages:"メッセージが少なすぎます"},px="要約の生成に失敗しました",fx="不明なエラー",hx={title:"要約をまとめて作成",byRange:"範囲で選択",byTime:"時間で選択",selectRange:"範囲を選択",rangeStart:"最古",rangeInfo:"約",sessionsUnit:"セッション",rangeEnd:"最新",timeRange:"時間範囲を選択",today:"今日",yesterday:"昨日",week:"直近7日間",month:"直近30日間",custom:"カスタム",found:"見つかった",hasSummary:"件は要約済み",tooFewMessages:"件はメッセージ不足",pending:"未生成:",unit:"件",noPending:"生成可能なセッションがありません",noSessions:"この時間範囲にセッションがありません",checking:"確認中...",loading:"読み込み中...",progress:"進捗",session:"セッション",statusSuccess:"成功",statusSkipped:"スキップ",statusFailed:"失敗",success:"成功:",failed:"失敗:",skipped:"スキップ:",start:"生成開始",stop:"停止"},vx={viewContext:"コンテキストを表示",contextTitle:"メッセージコンテキスト(前後各10件)",noContext:"コンテキストがありません",replyTo:"返信"},yx={title:"セッションインデックス",subtitle:"チャット履歴をタイムラインでたどれます",notGenerated:"セッションインデックスが未生成です",notGeneratedHint:"セッションインデックスを生成すると、チャット履歴ビューアーのタイムラインから各セッションにすばやくジャンプできます。",whatIsIt:"セッションインデックスの役割:",benefit1:"メッセージの時間間隔に基づいてセッション境界を自動識別",benefit2:"チャット履歴ビューアーにタイムラインナビゲーションを提供",benefit3:"AI が会話の文脈を理解しやすくなる",generated:"セッションインデックス生成済み",sessionCount:"全 {count} セッションを識別しました",regenerateHint:"セッション間隔のしきい値を調整した場合は、インデックスを再生成できます。",generate:"インデックスを生成",regenerate:"再生成",generating:"生成中...",cancel:"キャンセル"},bx={drawer:dx,messageList:ux,filter:mx,timeline:gx,summaryFailed:px,summaryUnknownError:fx,batchSummary:hx,messageItem:vx,sessionIndex:yx},_x={title:"やり取り頻度",rankingView:"ランキング表示",memberView:"メンバー表示",matrixView:"マトリクス表示",modelSettings:"モデル設定",lookAhead:"隣接数",lookAheadDesc:"各メッセージの後ろ側で何人分の発言を対象にするか",decaySeconds:"時間減衰(秒)",decaySecondsDesc:"値が大きいほど遠いメッセージの重みが高くなる",applySettings:"設定を適用",noData:"データがありません",selectMember:"メンバーを選択",selectMemberHint:"左側からメンバーを選択してください",msgCount:"発言数",relationCount:"関係数",relationsByIntimacy:"発言近接度ランキング",noRelations:"関係データがありません",intimacy:"近接度",interactionRanking:"やり取りランキング",score:"近接度",coOccurrence:"共起",times:"回",totalMembers:"グループメンバー",totalMessages:"メッセージ総数",involvedMembers:"参加メンバー",edgeCount:"関係数"},xx={typeDistribution:"メッセージタイプ分布",hourlyDistribution:"時間帯別分布",weekdayDistribution:"曜日別分布",monthlyDistribution:"月別分布",yearlyDistribution:"年別分布",timeHeatmap:"時間ヒートマップ",heatmapHint:"チャット時間帯の傾向を表示",calendarHeatmap:"メッセージカレンダー",calendarHint:"日別メッセージ分布",calendarTooltipMessages:"メッセージ",lengthDetailTitle:"短文メッセージ分布(1-25文字)",lengthDetailHint:"文字ごとの統計",lengthGroupedTitle:"文字数区間分布",lengthGroupedHint:"5文字ごとにグループ化",noTextMessages:"テキストメッセージがありません",noData:"データがありません",profile:{totalMessages:"総メッセージ",textMessages:"テキストメッセージ",avgLength:"平均文字数",avgLengthUnit:"{count} 文字/件",mediaRatio:"メディア比率",textExpression:"テキスト表現力",textExpressionDesc:"最長メッセージ {count} 文字",mediaRichness:"メディアの豊かさ",shortMaster:"短文マスター",shortMasterDesc:"5文字以下 {count} 件",essayLover:"長文好き",essayLoverDesc:"{threshold}文字以上のメッセージ",peakRecord:"ピーク記録",peakRecordDesc:"1日最多 {count} 件",topHours:"最もアクティブな時間帯",images:"画像",emoji:"スタンプ",voiceVideo:"音声/動画",typeDistribution:"メッセージ種類",hourlyDistribution:"24h アクティビティ",watermark:"メッセージレポート",heroLine1Prefix:"合計で",heroLine1Suffix:"件のメッセージを交わしました",heroLine2Prefix:"1件平均",heroLine2Middle:"文字、そのうち",heroLine2Suffix:"がテキスト以外"}},kx={mentionGraph:"メンション関係図",layout:"レイアウト",circular:"サークル",force:"フォースレイアウト",directed:"有向",reset:"リセット",graphHint:"全 {nodes} 名のメンバー、{links} 件のインタラクション",noInteraction:"メンションデータがありません"},wx={loading:"関係動態を分析中…",noIndex:{title:"セッションインデックスが必要です",description:"関係分析にはセッションインデックスが必要です。概要ページからセッションインデックスを生成してください。"},empty:{title:"関係データがありません",description:"選択した期間内にセッションが見つかりません。"},overview:{title:"全体概要"},monthly:{title:"月別明細",totalSessionsPrefix:"会話",totalSessionsSuffix:"回"},trend:{title:"主動性の推移",hint:"青い線は {name} の月別主動発起率。50% 線がバランス基準です"},hero:{monthPart:"{year}年{month}月",timeRange:{singleMonth:"{month}では、",range:"{start}から{end}までの期間では、"},totalSessionsPrefix:"2人の会話は合計",totalSessionsSuffix:"回",initiativePrefix:"",initiativeByPrefix:"の話題の切り出しは",initiativeBySuffix:"から始まりました",initiateTimes:"回発起"},initiator:"話題を始める",closer:"話題を終える",closerTitle:"会話の締め役",closerHint:"話題が終わるときに最後に発言した人を集計します。",initiated:"{count} 回発起",closed:"{count} 回終了",totalSessions:"合計 {count} セッション",times:"回",noActivity:"今月はやり取りなし",watermarkReport:"関係レポート",monthFormat:"{year}年{month}月",monthShortFormat:"{month}月",monthDetail:"発起 {init} / 終了 {close}",iceBreaker:{title:"アイスブレイカー",hint:"24時間以上の沈黙を破って話しかけた回数",count:"{count} 回の破氷",total:"合計 {count} 回の破氷"},responseLatency:{title:"返信速度",hint:"相手がメッセージを送った後、平均何分で返信するか",count:"{count} 回の返信",seconds:"{n} 秒",minutes:"{n} 分",minutesSeconds:"{m}分{s}秒",hours:"{n} 時間",hoursMinutes:"{h} 時間 {m} 分"},perseverance:{title:"粘り強さ",hint:"相手が返信する前にもう一通メッセージを送った回数",hintWithThreshold:"相手が{threshold}以内に返信しないうちに、もう一通メッセージを送った回数",thresholdMinutes:"{n}分",count:"{count} 回",total:"合計 {count} 回",threshold:"間隔",empty:"この閾値では粘り強さの記録がありません"},labels:{mutualPursuit:"双方向の想い",silentGuardian:"静かな守り手",devotedHeart:"一途な想い",distantBond:"遠い絆",wellMatched:"互角",missingYou:"{name} が恋しがっている",monologue:"{name} の独白",peacefulSilence:"穏やかな沈黙",fleetingThoughts:"ふとした思い出"}},Sx={title:"タイムライン表示",description:"メッセージの時間分布や活動周期の変化を可視化します"},Cx={rankListPro:{fullRanking:"全順位を表示",memberCount:"全 {count} 名のメンバー"},rankList:{unit:"件"},nicknameHistory:{periodToNow:"{start} 〜 現在",periodRange:"{start} 〜 {end}",current:"現在",empty:"ニックネーム履歴がありません"},listPro:{countTemplate:"全 {count} 件",fullRanking:"全順位を表示",empty:"データがありません"}},Mx={cluster:_x,message:xx,interaction:kx,relationship:wx,timeline:Sx,charts:Cx},Ax="キーワードフィルター",Tx="スキーム一覧",$x="スキーム名",Ix="スキーム名を入力",Px="新しいスキーム",Dx="新規作成",Lx="削除",Ex="デフォルトに設定",Rx="デフォルト",Nx="キーワードフィルター",Fx="フィルターなし",Ux="スキーム管理",Ox="フィルターワード追加",Hx="入力してEnterで追加、スペースまたはカンマ区切りで一括追加可能",Vx="追加",zx="フィルターワード一覧",Bx="すべてクリア",Wx="スキームがありません。+ をクリックして作成",jx="フィルターワードがありません。上の入力欄から追加してください",qx="フィルタースキームを選択または作成",Kx="{count} 個のワードをフィルター中",Gx="閉じる",Xx={title:Ax,schemeList:Tx,schemeName:$x,schemeNamePlaceholder:Ix,defaultSchemeName:Px,createScheme:Dx,deleteScheme:Lx,setDefault:Ex,isDefault:Rx,filterScheme:Nx,noFilter:Fx,manage:Ux,addWords:Ox,addWordsPlaceholder:Hx,add:Vx,wordList:zx,clearAll:Bx,emptyScheme:Wx,emptyWords:jx,selectOrCreate:qx,activeCount:Kx,close:Gx},Yx={common:Mb,layout:Bb,settings:a_,home:g_,analysis:A_,tools:D_,providers:W_,ai:Q_,quotes:nx,members:cx,records:bx,views:Mx,wordFilter:Xx},Vo=[{code:"en-US",name:"English (US)",nativeName:"English"},{code:"zh-CN",name:"Chinese (Simplified)",nativeName:"简体中文"},{code:"zh-TW",name:"Chinese (Traditional)",nativeName:"繁體中文"},{code:"ja-JP",name:"Japanese",nativeName:"日本語"}];new Set(Vo.map(e=>e.code));function Qx(){const e=navigator.language;return e==="zh-TW"||e==="zh-Hant"?"zh-TW":e.startsWith("zh")?"zh-CN":e.startsWith("ja")?"ja-JP":"en-US"}const Jx={"zh-CN":"zh-cn","zh-TW":"zh-tw","en-US":"en","ja-JP":"ja"};function Tn(e){return Jx[e]??"en"}const Zx={groupRanking:["zh-CN","zh-TW"]};function PE(e,t){const s=Zx[e];return!s||s.length===0?!0:s.includes(t)}function ek(){return Qx()}const Ds=Il({legacy:!1,locale:ek(),fallbackLocale:"en-US",messages:{"zh-CN":Fg,"en-US":zh,"zh-TW":q0,"ja-JP":Yx}});function $n(e){Ds.global.locale.value=e}function In(){return Ds.global.locale.value}const It=wt("settings",()=>{const e=P(In()),t=P("overview"),s=P(!1);function n(m){s.value=m,window.electron?.ipcRenderer.send("app:setDebugMode",m)}const a=P({dataCleaning:!0,mergeConsecutive:!1,mergeWindowSeconds:180,blacklistKeywords:[],denoise:!1,desensitize:!1,desensitizeRules:[],anonymizeNames:!1});async function i(){}async function c(m){e.value=m,$n(m),ot.locale(Tn(m)),window.electron?.ipcRenderer.send("locale:change",m)}async function l(){const m=In();e.value!==m&&$n(e.value),ot.locale(Tn(e.value)),await i(),window.electron?.ipcRenderer.send("app:setDebugMode",s.value)}return{locale:e,setLocale:c,initLocale:l,defaultSessionTab:t,debugMode:s,setDebugMode:n,aiPreprocessConfig:a,ensureDesensitizeRules:i}},{persist:{pick:["debugMode"],storage:localStorage},backendPersist:{pick:["aiPreprocessConfig"]}});function Vs(e){return e.provider==="openai-compatible"||e.provider.startsWith("custom:")?!e.apiKeySet||(e.baseUrl?.includes("localhost")??!1)?"local":"openai-compat":"preset"}function Pn(e){if(!(e.mode==="edit"&&!!e.existingApiKeySet&&!e.hasNewApiKey&&e.originalProvider===e.currentProvider&&e.originalConnectionMode===e.currentConnectionMode))return!1;if(e.currentConnectionMode==="openai-compat"){const s=n=>n?.trim().replace(/\/+$/,"")||"";return s(e.originalBaseUrl)===s(e.currentBaseUrl)}return!0}const Pt="openai-completions",tk=[{value:"openai-completions",labelKey:"settings.aiConfig.modal.apiFormatOpenAI"},{value:"anthropic-messages",labelKey:"settings.aiConfig.modal.apiFormatAnthropic"},{value:"google-generative-ai",labelKey:"settings.aiConfig.modal.apiFormatGemini"},{value:"openai-responses",labelKey:"settings.aiConfig.modal.apiFormatOpenAIResponses"}],sk=["doubao","siliconflow"];function ak(e){const{t,locale:s}=Re(),n=It(),a=Is();function i(O){const ge=`providers.${O}.name`,fe=t(ge);return fe===ge?O:fe}const c=G(()=>JSON.parse(localStorage.getItem(`chatlab_app_config_${s.value}`)||localStorage.getItem("chatlab_app_config")||"{}").aiTips||{}),l=P("preset"),m=G(()=>[{label:t("settings.aiConfig.modal.presetService"),value:"preset"},{label:t("settings.aiConfig.modal.thirdPartyService"),value:"openai-compat"},{label:t("settings.aiConfig.modal.localService"),value:"local"}]),u=P(!1),f=P(!1),h=P(!1),x=P(""),S=P(!1),C=P(""),D=P(""),M=P(void 0),g=P([]),p=P({provider:"",apiKey:"",model:"",baseUrl:"",apiFormat:Pt,customName:"",disableThinking:!0,isReasoningModel:!1}),k=P("idle"),T=P(""),E=G(()=>a.providerRegistry.filter(O=>!(!n.locale.startsWith("zh")&&sk.includes(O.id)))),I=G(()=>E.value.filter(O=>O.kind==="official"&&O.id!=="openai-compatible")),N=G(()=>E.value.filter(O=>!O.builtin)),ee=G(()=>a.providerRegistry.find(O=>O.id===p.value.provider)),V=G(()=>l.value==="local"),ie=G(()=>l.value==="openai-compat"),Q=G(()=>l.value==="preset"),Y=G(()=>V.value||ie.value),H=G(()=>p.value.provider?a.getModelsByProviderId(p.value.provider).filter(O=>!O.capabilities.includes("embedding")&&!O.capabilities.includes("ranking")):[]),B=G(()=>Y.value?g.value.map(O=>({label:O.name,value:O.id})):H.value.map(O=>({label:O.name,value:O.id}))),j=G(()=>{if(!p.value.model)return!1;if(Y.value)return g.value.some(ge=>ge.id===p.value.model);const O=H.value.find(ge=>ge.id===p.value.model);return O?!O.builtin:!1}),X=G(()=>{if(!p.value.model)return;const O=p.value.provider||"openai-compatible";return(a.getModelById(O,p.value.model)||a.findModelAcrossProviders(p.value.model))?.contextWindow}),le=G(()=>{const{provider:O,apiKey:ge,baseUrl:fe,model:Se}=p.value,qe=e.mode.value==="edit"&&Pn({mode:e.mode.value,existingApiKeySet:e.config.value?.apiKeySet,hasNewApiKey:!!ge.trim(),originalProvider:e.config.value?.provider,currentProvider:O,originalConnectionMode:e.config.value?Vs(e.config.value):void 0,currentConnectionMode:l.value,originalBaseUrl:e.config.value?.baseUrl,currentBaseUrl:fe.trim()||void 0});return V.value?fe.trim()&&Se.trim():ie.value?fe.trim()&&(ge.trim()||qe)&&Se.trim():O?ge.trim()||qe:!1}),F=G(()=>tk.map(O=>({label:t(O.labelKey),value:O.value}))),_=G(()=>e.mode.value==="add"?t("settings.aiConfig.modal.addConfig"):t("settings.aiConfig.modal.editConfig")),y={gemini:"google-generative-ai",anthropic:"anthropic-messages"},L={"openai-completions":"/chat/completions","openai-responses":"/responses","anthropic-messages":"/v1/messages"},$=G(()=>{const ge=p.value.baseUrl?.trim()||(Q.value?ee.value?.defaultBaseUrl:"");if(!ge)return"";const fe=Q.value?y[p.value.provider]||Pt:p.value.apiFormat||Pt,Se=ge.replace(/\/+$/,"");let Pe;if(fe==="anthropic-messages")Pe=Se.replace(/\/v1\/?$/,"");else if(fe==="openai-completions"||fe==="openai-responses")try{const st=new URL(Se);!Se.endsWith("/v1")&&(st.pathname==="/"||st.pathname==="")?Pe=Se+"/v1":Pe=Se}catch{Pe=Se}else Pe=Se;const qe=L[fe];return qe?Pe+qe:Pe});function z(){l.value="preset",g.value=[];const O=I.value[0]?.id||"",ge=O?a.getModelsByProviderId(O):[],fe=ge.find(Pe=>Pe.recommendedFor.includes("chat")),Se=O?a.providerRegistry.find(Pe=>Pe.id===O):null;p.value={provider:O,apiKey:"",model:fe?.id||ge[0]?.id||"",baseUrl:Se?.defaultBaseUrl||"",apiFormat:Pt,customName:"",disableThinking:!0,isReasoningModel:!1},k.value="idle",T.value=""}function ce(O){const ge=a.providerRegistry.find(Pe=>Pe.id===O.provider),fe=O.provider==="openai-compatible"||O.provider.startsWith("custom:"),Se=!!(O.model&&a.getModelById(O.provider,O.model));fe?(l.value=Vs(O),O.customModels&&O.customModels.length>0?g.value=[...O.customModels]:g.value=O.model?[{id:O.model,name:O.model}]:[]):(l.value="preset",g.value=[]),p.value={provider:O.provider,apiKey:O.apiKey||"",model:fe?O.model||"":Se&&O.model||"",baseUrl:O.baseUrl||ge?.defaultBaseUrl||"",apiFormat:O.apiFormat||Pt,customName:O.name||"",disableThinking:O.disableThinking??!0,isReasoningModel:O.isReasoningModel??!1},k.value="idle",T.value=""}function W(O){p.value.provider=O,k.value="idle",T.value="",p.value.baseUrl=a.providerRegistry.find(Se=>Se.id===O)?.defaultBaseUrl||"";const ge=a.getModelsByProviderId(O),fe=ge.filter(Se=>Se.recommendedFor.includes("chat"));p.value.model=fe[0]?.id||ge[0]?.id||"",p.value.apiKey=""}function se(O){if(l.value=O,k.value="idle",T.value="",O==="local")p.value.provider="openai-compatible",p.value.baseUrl="http://localhost:11434",p.value.model=g.value[0]?.id||"",p.value.apiKey="";else if(O==="openai-compat")p.value.provider="openai-compatible",p.value.baseUrl="",p.value.model=g.value[0]?.id||"",p.value.apiKey="";else{g.value=[];const ge=I.value[0]?.id||"";p.value.provider=ge,p.value.baseUrl=a.providerRegistry.find(Pe=>Pe.id===ge)?.defaultBaseUrl||"";const fe=ge?a.getModelsByProviderId(ge):[],Se=fe.filter(Pe=>Pe.recommendedFor.includes("chat"));p.value.model=Se[0]?.id||fe[0]?.id||"",p.value.apiKey=""}}const pe=P(!1),me=P([]),ae=P(""),he=P(!1),ke=G(()=>Y.value?new Set(g.value.map(O=>O.id)):new Set(H.value.map(O=>O.id))),ve=G(()=>Q.value?y[p.value.provider]||Pt:p.value.apiFormat||Pt),_e=G(()=>{if(ve.value==="anthropic-messages")return!1;const O=p.value.baseUrl||ee.value?.defaultBaseUrl||"",ge=p.value.apiKey||(V.value?"sk-no-key-required":"");return!!(O.trim()&&ge.trim())});async function be(){const O=p.value.baseUrl||ee.value?.defaultBaseUrl||"",ge=p.value.apiKey||(V.value?"sk-no-key-required":"");if(!(!O||!ge)){pe.value=!0,ae.value="",he.value=!0;try{const fe=await window.llmApi.fetchRemoteModels(p.value.provider||"openai-compatible",ge,O,ve.value);if(fe.success&&fe.models){const Se=p.value.provider||"openai-compatible";me.value=fe.models.map(Pe=>{if(Pe.contextWindow)return Pe;const qe=a.getModelById(Se,Pe.id)||a.findModelAcrossProviders(Pe.id);return qe?.contextWindow?{...Pe,contextWindow:qe.contextWindow}:Pe})}else ae.value=fe.error||t("settings.aiConfig.modal.fetchModelsError")}catch(fe){ae.value=String(fe)}finally{pe.value=!1}}}async function Le(O){if(Y.value){g.value.some(fe=>fe.id===O.id)||g.value.push({id:O.id,name:O.name});const ge=p.value.provider||"openai-compatible";if(O.contextWindow&&!a.getModelById(ge,O.id)?.contextWindow)try{await window.llmApi.addCustomModel({id:O.id,providerId:ge,name:O.name,contextWindow:O.contextWindow,capabilities:["chat"],recommendedFor:[],description:"",status:"stable"}),await a.refreshConfigs()}catch{}}else{const ge=p.value.provider||"openai-compatible";if(!H.value.some(fe=>fe.id===O.id))try{await window.llmApi.addCustomModel({id:O.id,providerId:ge,name:O.name,contextWindow:O.contextWindow||void 0,capabilities:["chat"],recommendedFor:[],description:"",status:"stable"}),await a.refreshConfigs()}catch{}}p.value.model||(p.value.model=O.id)}async function Ae(O){for(const ge of O)await Le(ge)}function de(){C.value="",D.value="",M.value=void 0,S.value=!0}async function w(){const O=D.value.trim(),ge=C.value.trim()||O;if(!O)return;if(Y.value){g.value.some(Se=>Se.id===O)||g.value.push({id:O,name:ge}),p.value.model=O,S.value=!1;return}const fe=p.value.provider||"openai-compatible";try{await window.llmApi.addCustomModel({id:O,providerId:fe,name:ge,contextWindow:M.value||void 0,capabilities:["chat"],recommendedFor:[],description:"",status:"stable"}),await a.refreshConfigs(),p.value.model=O,S.value=!1}catch(Se){console.error("添加自定义模型失败:",Se)}}const R=P(!1),oe=P(void 0),te=P("");function q(){const O=p.value.model;if(!O)return;const ge=p.value.provider||"openai-compatible",fe=a.getModelById(ge,O);oe.value=fe?.contextWindow??void 0,te.value=fe?.name??"",R.value=!0}async function ue(){const O=p.value.model;if(!O)return;const ge=p.value.provider||"openai-compatible";try{const fe={contextWindow:oe.value||void 0};te.value.trim()&&(fe.name=te.value.trim()),(await window.llmApi.updateCustomModel(ge,O,fe)).success||await window.llmApi.addCustomModel({id:O,providerId:ge,name:te.value.trim()||O,contextWindow:oe.value||void 0,capabilities:["chat"],recommendedFor:[],description:"",status:"stable"}),await a.refreshConfigs()}catch(fe){console.error("编辑模型失败:",fe)}R.value=!1}async function U(O){if(Y.value){const fe=g.value.findIndex(Se=>Se.id===O);fe!==-1&&g.value.splice(fe,1),p.value.model===O&&(p.value.model=g.value[0]?.id||"");return}const ge=p.value.provider||"openai-compatible";try{if(await window.llmApi.deleteCustomModel(ge,O),await a.refreshConfigs(),p.value.model===O){const fe=H.value;p.value.model=fe[0]?.id||""}}catch(fe){console.error("删除自定义模型失败:",fe)}}async function K(){const{provider:O,apiKey:ge,baseUrl:fe}=p.value;if(Q.value){if(!O||!ge){k.value="idle",T.value="";return}}else if(!fe||ie.value&&!ge)return;u.value=!0,k.value="idle";try{const Se=ge||"sk-no-key-required",Pe=await window.llmApi.validateApiKey(O||"openai-compatible",Se,fe||void 0,p.value.model||void 0);k.value=Pe.success?"valid":"invalid",Pe.success?T.value=t("settings.aiConfig.modal.validationSuccess"):T.value=Pe.error||t("settings.aiConfig.modal.validationFailed")}catch(Se){k.value="invalid",T.value=t("settings.aiConfig.modal.validationError")+String(Se)}finally{u.value=!1}}function Ie(){if(Y.value&&p.value.baseUrl)try{return new URL(p.value.baseUrl).hostname}catch{return t("settings.aiConfig.modal.customService")}const O=ee.value;if(O)return i(O.id)||O.name;const ge=e.providers.value.find(fe=>fe.id===p.value.provider);return ge?ge.name:p.value.baseUrl||t("settings.aiConfig.modal.customService")}async function Te(){f.value=!0;try{const O=p.value.provider;let ge=p.value.apiKey.trim();!ge&&V.value&&(ge="sk-no-key-required");const fe=p.value.customName.trim()||Ie(),Se=p.value.isReasoningModel,Pe=Y.value&&g.value.length>0?g.value.map(qe=>({id:qe.id,name:qe.name})):void 0;if(e.mode.value==="add"){const qe=Y.value&&p.value.apiFormat||void 0,st=await window.llmApi.addConfig({name:fe,provider:O,apiKey:ge,model:p.value.model.trim()||void 0,baseUrl:p.value.baseUrl.trim()||void 0,apiFormat:qe,disableThinking:Se?p.value.disableThinking:void 0,isReasoningModel:Se||void 0,customModels:Pe});st.success?(e.onClose(),e.onSaved()):console.error("添加配置失败:",st.error)}else{const qe=Y.value&&p.value.apiFormat||void 0,st={name:fe,provider:O,model:p.value.model.trim()||void 0,baseUrl:p.value.baseUrl.trim()||void 0,apiFormat:qe,disableThinking:Se?p.value.disableThinking:void 0,isReasoningModel:Se||void 0,customModels:Pe};(p.value.apiKey.trim()||V.value)&&(st.apiKey=ge);const Ft=await window.llmApi.updateConfig(e.config.value.id,st);Ft.success?(e.onClose(),e.onSaved()):console.error("更新配置失败:",Ft.error)}}catch(O){console.error("保存配置失败:",O)}finally{f.value=!1}}async function Z(){if(!le.value)return;if(k.value==="valid")return Te();const O=!!p.value.apiKey.trim();if(Pn({mode:e.mode.value,existingApiKeySet:e.config.value?.apiKeySet,hasNewApiKey:O,originalProvider:e.config.value?.provider,currentProvider:p.value.provider,originalConnectionMode:e.config.value?Vs(e.config.value):void 0,currentConnectionMode:l.value,originalBaseUrl:e.config.value?.baseUrl,currentBaseUrl:p.value.baseUrl.trim()||void 0}))return Te();u.value=!0;try{const fe=p.value.apiKey.trim()||"sk-no-key-required",Se=await window.llmApi.validateApiKey(p.value.provider||"openai-compatible",fe,p.value.baseUrl.trim()||void 0,p.value.model.trim()||void 0);if(Se.success)return k.value="valid",T.value="",Te();k.value="invalid",x.value=Se.error||t("settings.aiConfig.modal.validationFailed"),h.value=!0}catch(fe){x.value=String(fe),h.value=!0}finally{u.value=!1}}function Ce(){h.value=!1,Te()}function Ze(){h.value=!1}return Ne(e.open,O=>{O&&(e.mode.value==="edit"&&e.config.value?ce(e.config.value):z())}),Ne(()=>p.value.apiKey,()=>{k.value="idle",T.value=""}),{getLocalizedProviderName:i,aiTips:c,connectionMode:l,connectionModeItems:m,isValidating:u,isSaving:f,showValidationFailConfirm:h,validationFailMessage:x,showAddModelDialog:S,newModelName:C,newModelId:D,newModelContextWindow:M,formData:p,validationResult:k,validationMessage:T,officialProviders:I,customProviders:N,currentProviderDef:ee,isLocalMode:V,isOpenAICompat:ie,isPresetMode:Q,isCompatMode:Y,modelTabItems:B,selectedModelIsCustom:j,selectedModelContextWindow:X,canSave:le,apiFormatItems:F,modalTitle:_,resolvedApiUrl:$,isFetchingModels:pe,remoteModels:me,remoteModelsError:ae,showRemoteModelBrowser:he,addedModelIds:ke,canFetchModels:_e,showEditModelDialog:R,editModelContextWindow:oe,editModelName:te,selectProvider:W,onConnectionModeChange:se,openAddModelDialog:de,confirmAddModel:w,openEditModelDialog:q,confirmEditModel:ue,deleteCustomModel:U,validateKey:K,saveConfig:Z,confirmSaveAnyway:Ce,cancelSave:Ze,fetchRemoteModels:be,addRemoteModel:Le,addAllRemoteModels:Ae}}const nk={class:"flex min-h-[min(640px,80vh)] max-h-[80vh] flex-col p-6"},ok={class:"mb-4 text-lg font-semibold text-gray-900 dark:text-white"},rk={class:"min-h-0 flex-1 overflow-y-auto pr-1"},ik={class:"space-y-4"},lk={class:"mb-2 block text-sm font-medium text-gray-700 dark:text-gray-300"},ck={class:"flex flex-wrap gap-2"},dk=["onClick"],uk=["onClick"],mk={key:0,class:"mt-3 rounded-lg border border-gray-100 bg-gray-50/50 px-3 py-2 dark:border-gray-800 dark:bg-gray-800/50"},gk={class:"flex gap-3"},pk=["href"],fk=["href"],hk={class:"text-sm font-medium text-gray-700 dark:text-gray-300"},vk={class:"mt-1 text-[10px] text-gray-400"},yk={key:0,class:"mt-1.5 flex items-center gap-1 text-[11px] text-gray-400 dark:text-gray-500"},bk={class:"ml-0.5 break-all rounded bg-gray-100 px-1 py-0.5 font-mono text-[10px] text-gray-500 dark:bg-gray-800 dark:text-gray-400"},_k={class:"mb-2 block text-sm font-medium text-gray-700 dark:text-gray-300"},xk={key:1,class:"mt-2 text-xs text-gray-500 dark:text-gray-400"},kk={key:0,class:"ml-2"},wk={key:2,class:"mt-1 flex items-center gap-1 text-xs text-red-500 dark:text-red-400"},Sk={class:"mt-2 flex items-center gap-2"},Ck={class:"mb-2 block text-sm font-medium text-gray-700 dark:text-gray-300"},Mk={class:"flex gap-2"},Ak={key:0,class:"mt-1.5 flex items-center gap-1 text-[11px] text-gray-400 dark:text-gray-500"},Tk={class:"ml-0.5 break-all rounded bg-gray-100 px-1 py-0.5 font-mono text-[10px] text-gray-500 dark:bg-gray-800 dark:text-gray-400"},$k={class:"mb-2 block text-sm font-medium text-gray-700 dark:text-gray-300"},Ik={key:1,class:"flex items-center gap-1 text-xs text-red-500 dark:text-red-400"},Pk={key:2,class:"mt-2 text-xs text-gray-500 dark:text-gray-400"},Dk={key:0,class:"ml-2"},Lk={key:3,class:"mt-1 flex items-center gap-1 text-xs text-red-500 dark:text-red-400"},Ek={class:"mt-2 flex items-center gap-2"},Rk={key:0},Nk={key:0,class:"flex items-center gap-1 text-sm text-green-600 dark:text-green-400"},Fk={key:1,class:"flex items-center gap-1 text-sm text-amber-600 dark:text-amber-400"},Uk={class:"mb-2 block text-sm font-medium text-gray-700 dark:text-gray-300"},Ok={class:"mt-1 text-xs text-gray-500"},Hk={key:0,class:"mt-1.5 flex items-center gap-1 text-[11px] text-gray-400 dark:text-gray-500"},Vk={class:"ml-0.5 break-all rounded bg-gray-100 px-1 py-0.5 font-mono text-[10px] text-gray-500 dark:bg-gray-800 dark:text-gray-400"},zk={class:"mb-2 block text-sm font-medium text-gray-700 dark:text-gray-300"},Bk={key:1,class:"flex items-center gap-1 text-xs text-red-500 dark:text-red-400"},Wk={key:2,class:"mt-2 text-xs text-gray-500 dark:text-gray-400"},jk={key:0,class:"ml-2"},qk={key:3,class:"mt-1 flex items-center gap-1 text-xs text-red-500 dark:text-red-400"},Kk={class:"mt-2 flex items-center gap-2"},Gk={key:3},Xk={class:"mb-2 block text-sm font-medium text-gray-700 dark:text-gray-300"},Yk={key:4},Qk={class:"mb-2 block text-sm font-medium text-gray-700 dark:text-gray-300"},Jk={class:"font-normal text-gray-400"},Zk={class:"flex items-center justify-between rounded-lg bg-gray-50 p-3 dark:bg-gray-800"},ew={class:"text-sm font-medium text-gray-700 dark:text-gray-300"},tw={class:"text-xs text-gray-500 dark:text-gray-400"},sw={key:0,class:"flex items-center justify-between rounded-lg bg-gray-50 p-3 dark:bg-gray-800"},aw={class:"text-sm font-medium text-gray-700 dark:text-gray-300"},nw={class:"text-xs text-gray-500 dark:text-gray-400"},ow={class:"mt-4 flex shrink-0 justify-end gap-2 border-t border-gray-100 pt-4 dark:border-gray-800"},rw={class:"p-6"},iw={class:"mb-4 flex items-start gap-3"},lw={class:"font-medium text-gray-900 dark:text-white"},cw={class:"mt-1 text-sm text-gray-600 dark:text-gray-400"},dw={class:"mt-2 text-sm text-gray-500 dark:text-gray-400"},uw={class:"flex justify-end gap-2"},mw={class:"p-5"},gw={class:"mb-4 text-base font-semibold text-gray-900 dark:text-white"},pw={class:"space-y-3"},fw={class:"mb-1 block text-sm font-medium text-gray-700 dark:text-gray-300"},hw={class:"mt-1 text-[10px] text-gray-400"},vw={class:"mb-1 block text-sm font-medium text-gray-700 dark:text-gray-300"},yw={class:"font-normal text-gray-400"},bw={class:"mb-1 block text-sm font-medium text-gray-700 dark:text-gray-300"},_w={class:"flex items-center gap-2"},xw={class:"mt-1.5 flex flex-wrap gap-1"},kw=["onClick"],ww={class:"mt-1 text-[10px] text-gray-400"},Sw={class:"mt-4 flex justify-end gap-2"},Cw={class:"p-5"},Mw={class:"mb-4 text-base font-semibold text-gray-900 dark:text-white"},Aw={class:"space-y-3"},Tw={class:"mb-1 block text-sm font-medium text-gray-700 dark:text-gray-300"},$w={class:"text-sm text-gray-600 dark:text-gray-400"},Iw={class:"mb-1 block text-sm font-medium text-gray-700 dark:text-gray-300"},Pw={class:"font-normal text-gray-400"},Dw={class:"mb-1 block text-sm font-medium text-gray-700 dark:text-gray-300"},Lw={class:"flex items-center gap-2"},Ew={class:"mt-1.5 flex flex-wrap gap-1"},Rw=["onClick"],Nw={class:"mt-1 text-[10px] text-gray-400"},Fw={class:"mt-4 flex justify-end gap-2"},Uw=$e({__name:"AIModelEditModal",props:{open:{type:Boolean},mode:{},config:{},providers:{}},emits:["update:open","saved"],setup(e,{emit:t}){const{t:s}=Re(),n=e,a=t,{getLocalizedProviderName:i,aiTips:c,connectionMode:l,connectionModeItems:m,isValidating:u,isSaving:f,showValidationFailConfirm:h,validationFailMessage:x,showAddModelDialog:S,newModelName:C,newModelId:D,newModelContextWindow:M,formData:g,validationResult:p,validationMessage:k,officialProviders:T,customProviders:E,currentProviderDef:I,isLocalMode:N,isOpenAICompat:ee,isPresetMode:V,modelTabItems:ie,selectedModelIsCustom:Q,selectedModelContextWindow:Y,canSave:H,apiFormatItems:B,modalTitle:j,resolvedApiUrl:X,isFetchingModels:le,remoteModels:F,remoteModelsError:_,showRemoteModelBrowser:y,addedModelIds:L,canFetchModels:$,showEditModelDialog:z,editModelContextWindow:ce,editModelName:W,selectProvider:se,onConnectionModeChange:pe,openAddModelDialog:me,confirmAddModel:ae,openEditModelDialog:he,confirmEditModel:ke,deleteCustomModel:ve,validateKey:_e,saveConfig:be,confirmSaveAnyway:Le,cancelSave:Ae,fetchRemoteModels:de,addRemoteModel:w,addAllRemoteModels:R}=ak({...Qn(n),onClose:()=>a("update:open",!1),onSaved:()=>a("saved")});function oe(){a("update:open",!1)}return(te,q)=>{const ue=lt,U=Ve,K=We,Ie=Kt,Te=ht;return b(),A(Me,null,[v(Te,{open:e.open,ui:{content:"max-w-2xl z-[101]",overlay:"z-[100]"},"onUpdate:open":q[25]||(q[25]=Z=>a("update:open",Z))},{content:re(()=>[r("div",nk,[r("h3",ok,d(o(j)),1),r("div",rk,[r("div",ik,[v(Dt,{"model-value":o(l),items:o(m),size:"sm","onUpdate:modelValue":o(pe)},null,8,["model-value","items","onUpdate:modelValue"]),o(V)?(b(),A(Me,{key:0},[r("div",null,[r("label",lk,d(o(s)("settings.aiConfig.modal.aiProvider")),1),r("div",ck,[(b(!0),A(Me,null,Be(o(T),Z=>(b(),A("button",{key:Z.id,class:we(["rounded-lg border-2 px-3 py-1.5 text-xs font-medium transition-colors",[o(g).provider===Z.id?"border-transparent bg-primary-500 text-white hover:bg-primary-600 dark:bg-primary-500 dark:text-white dark:hover:bg-primary-400":"border-gray-200 bg-white text-gray-600 hover:border-gray-300 dark:border-gray-700 dark:bg-gray-900 dark:text-gray-400 dark:hover:border-gray-600"]]),onClick:Ce=>o(se)(Z.id)},d(o(i)(Z.id)||Z.name),11,dk))),128)),(b(!0),A(Me,null,Be(o(E),Z=>(b(),A("button",{key:Z.id,class:we(["rounded-lg border-2 px-3 py-1.5 text-xs font-medium transition-colors",[o(g).provider===Z.id?"border-transparent bg-primary-500 text-white hover:bg-primary-600 dark:bg-primary-500 dark:text-white dark:hover:bg-primary-400":"border-dashed border-gray-300 bg-white text-gray-500 hover:border-gray-400 dark:border-gray-600 dark:bg-gray-900 dark:text-gray-400"]]),onClick:Ce=>o(se)(Z.id)},d(Z.name),11,uk))),128))]),o(I)&&(o(I).website||o(I).consoleUrl)?(b(),A("div",mk,[r("div",gk,[o(I).website?(b(),A("a",{key:0,href:o(I).website,target:"_blank",rel:"noopener",class:"text-xs text-primary-500 hover:underline"},d(o(s)("settings.aiConfig.modal.visitWebsite")),9,pk)):ne("",!0),o(I).consoleUrl?(b(),A("a",{key:1,href:o(I).consoleUrl,target:"_blank",rel:"noopener",class:"text-xs text-primary-500 hover:underline"},d(o(s)("settings.aiConfig.modal.getApiKey")),9,fk)):ne("",!0)])])):ne("",!0)]),v(Hs,{modelValue:o(g).apiKey,"onUpdate:modelValue":q[0]||(q[0]=Z=>o(g).apiKey=Z),placeholder:e.mode==="edit"&&e.config?.apiKeySet?o(s)("settings.aiConfig.modal.apiKeyPlaceholderEdit"):o(s)("settings.aiConfig.modal.apiKeyPlaceholder"),"validate-loading":o(u),"validate-disabled":!o(g).apiKey,"validate-text":o(s)("settings.aiConfig.modal.validate"),"validation-result":o(p),"validation-message":o(k),onValidate:o(_e)},null,8,["modelValue","placeholder","validate-loading","validate-disabled","validate-text","validation-result","validation-message","onValidate"]),r("div",null,[r("label",hk,d(o(s)("settings.aiConfig.modal.apiEndpoint")),1),v(ue,{modelValue:o(g).baseUrl,"onUpdate:modelValue":q[1]||(q[1]=Z=>o(g).baseUrl=Z),class:"mt-2 w-full",placeholder:o(I)?.defaultBaseUrl||"https://api.example.com/v1"},null,8,["modelValue","placeholder"]),r("p",vk,d(o(s)("settings.aiConfig.modal.apiEndpointOverrideHint")),1),o(X)?(b(),A("p",yk,[v(U,{name:"i-heroicons-link",class:"h-3 w-3 shrink-0"}),r("span",null,d(o(s)("settings.aiConfig.modal.resolvedUrl")),1),r("code",bk,d(o(X)),1)])):ne("",!0)]),r("div",null,[r("label",_k,d(o(s)("settings.aiConfig.modal.model")),1),o(ie).length>0?(b(),xe(Dt,{key:0,modelValue:o(g).model,"onUpdate:modelValue":q[2]||(q[2]=Z=>o(g).model=Z),items:o(ie),size:"xs"},null,8,["modelValue","items"])):ne("",!0),o(g).model?(b(),A("p",xk,[J(d(o(s)("settings.aiConfig.modal.customModelId"))+": "+d(o(g).model)+" ",1),o(Y)?(b(),A("span",kk," · "+d(o(s)("settings.aiConfig.modal.contextWindow"))+": "+d(o(Y)>=1e6?(o(Y)/1048576).toFixed(1)+"M":Math.round(o(Y)/1024)+"K"),1)):ne("",!0)])):ne("",!0),o(g).model&&!o(Y)?(b(),A("p",wk,[v(U,{name:"i-heroicons-exclamation-triangle",class:"h-3.5 w-3.5 shrink-0"}),J(" "+d(o(s)("settings.aiConfig.modal.contextWindowMissing")),1)])):ne("",!0),r("div",Sk,[o($)?(b(),A("button",{key:0,class:"flex items-center gap-1 rounded-md border border-dashed border-primary-300 px-2 py-1 text-xs text-primary-500 transition-colors hover:border-primary-400 hover:text-primary-600 dark:border-primary-700 dark:text-primary-400 dark:hover:border-primary-500",onClick:q[3]||(q[3]=(...Z)=>o(de)&&o(de)(...Z))},[v(U,{name:"i-heroicons-cloud-arrow-down",class:"h-3.5 w-3.5"}),J(" "+d(o(s)("settings.aiConfig.modal.fetchModels")),1)])):ne("",!0),o(I)?.supportsCustomModels?(b(),A("button",{key:1,class:"flex items-center gap-1 rounded-md border border-dashed border-gray-300 px-2 py-1 text-xs text-gray-500 transition-colors hover:border-primary-400 hover:text-primary-500 dark:border-gray-600 dark:text-gray-400 dark:hover:border-primary-500 dark:hover:text-primary-400",onClick:q[4]||(q[4]=(...Z)=>o(me)&&o(me)(...Z))},[v(U,{name:"i-heroicons-plus",class:"h-3.5 w-3.5"}),J(" "+d(o(s)("settings.aiConfig.modal.addCustomModel")),1)])):ne("",!0),o(g).model?(b(),A("button",{key:2,class:"flex items-center gap-1 rounded-md border border-dashed border-gray-300 px-2 py-1 text-xs text-gray-500 transition-colors hover:border-primary-400 hover:text-primary-500 dark:border-gray-600 dark:text-gray-400 dark:hover:border-primary-500 dark:hover:text-primary-400",onClick:q[5]||(q[5]=(...Z)=>o(he)&&o(he)(...Z))},[v(U,{name:"i-heroicons-pencil-square",class:"h-3.5 w-3.5"}),J(" "+d(o(s)("settings.aiConfig.modal.editModel")),1)])):ne("",!0),o(Q)?(b(),A("button",{key:3,class:"flex items-center gap-1 rounded-md border border-dashed border-red-200 px-2 py-1 text-xs text-red-400 transition-colors hover:border-red-400 hover:text-red-500 dark:border-red-800 dark:hover:border-red-500",onClick:q[6]||(q[6]=Z=>o(ve)(o(g).model))},[v(U,{name:"i-heroicons-trash",class:"h-3.5 w-3.5"}),J(" "+d(o(s)("settings.aiConfig.modal.deleteCustomModel")),1)])):ne("",!0)])])],64)):o(N)?(b(),A(Me,{key:1},[v(Hs,{modelValue:o(g).apiKey,"onUpdate:modelValue":q[7]||(q[7]=Z=>o(g).apiKey=Z),placeholder:o(s)("settings.aiConfig.modal.apiKeyPlaceholderLocal"),"optional-text":o(s)("settings.aiConfig.modal.optional"),hint:o(s)("settings.aiConfig.modal.apiKeyHintLocal")},null,8,["modelValue","placeholder","optional-text","hint"]),r("div",null,[r("label",Ck,d(o(s)("settings.aiConfig.modal.apiEndpoint")),1),r("div",Mk,[v(ue,{modelValue:o(g).baseUrl,"onUpdate:modelValue":q[8]||(q[8]=Z=>o(g).baseUrl=Z),placeholder:"http://localhost:11434",class:"flex-1"},null,8,["modelValue"]),v(K,{loading:o(u),disabled:!o(g).baseUrl,variant:"soft",onClick:o(_e)},{default:re(()=>[J(d(o(s)("settings.aiConfig.modal.validate")),1)]),_:1},8,["loading","disabled","onClick"])]),o(X)?(b(),A("p",Ak,[v(U,{name:"i-heroicons-link",class:"h-3 w-3 shrink-0"}),r("span",null,d(o(s)("settings.aiConfig.modal.resolvedUrl")),1),r("code",Tk,d(o(X)),1)])):ne("",!0)]),r("div",null,[r("label",$k,d(o(s)("settings.aiConfig.modal.model")),1),o(ie).length>0?(b(),xe(Dt,{key:0,modelValue:o(g).model,"onUpdate:modelValue":q[9]||(q[9]=Z=>o(g).model=Z),items:o(ie),size:"xs"},null,8,["modelValue","items"])):(b(),A("p",Ik,[v(U,{name:"i-heroicons-exclamation-triangle",class:"h-3.5 w-3.5 shrink-0"}),J(" "+d(o(s)("settings.aiConfig.modal.modelRequired")),1)])),o(g).model?(b(),A("p",Pk,[J(d(o(s)("settings.aiConfig.modal.customModelId"))+": "+d(o(g).model)+" ",1),o(Y)?(b(),A("span",Dk," · "+d(o(s)("settings.aiConfig.modal.contextWindow"))+": "+d(o(Y)>=1e6?(o(Y)/1048576).toFixed(1)+"M":Math.round(o(Y)/1024)+"K"),1)):ne("",!0)])):ne("",!0),o(g).model&&!o(Y)?(b(),A("p",Lk,[v(U,{name:"i-heroicons-exclamation-triangle",class:"h-3.5 w-3.5 shrink-0"}),J(" "+d(o(s)("settings.aiConfig.modal.contextWindowMissing")),1)])):ne("",!0),r("div",Ek,[o($)?(b(),A("button",{key:0,class:"flex items-center gap-1 rounded-md border border-dashed border-primary-300 px-2 py-1 text-xs text-primary-500 transition-colors hover:border-primary-400 hover:text-primary-600 dark:border-primary-700 dark:text-primary-400 dark:hover:border-primary-500",onClick:q[10]||(q[10]=(...Z)=>o(de)&&o(de)(...Z))},[v(U,{name:"i-heroicons-cloud-arrow-down",class:"h-3.5 w-3.5"}),J(" "+d(o(s)("settings.aiConfig.modal.fetchModels")),1)])):ne("",!0),o(I)?.supportsCustomModels?(b(),A("button",{key:1,class:"flex items-center gap-1 rounded-md border border-dashed border-gray-300 px-2 py-1 text-xs text-gray-500 transition-colors hover:border-primary-400 hover:text-primary-500 dark:border-gray-600 dark:text-gray-400 dark:hover:border-primary-500 dark:hover:text-primary-400",onClick:q[11]||(q[11]=(...Z)=>o(me)&&o(me)(...Z))},[v(U,{name:"i-heroicons-plus",class:"h-3.5 w-3.5"}),J(" "+d(o(s)("settings.aiConfig.modal.addCustomModel")),1)])):ne("",!0),o(g).model?(b(),A("button",{key:2,class:"flex items-center gap-1 rounded-md border border-dashed border-gray-300 px-2 py-1 text-xs text-gray-500 transition-colors hover:border-primary-400 hover:text-primary-500 dark:border-gray-600 dark:text-gray-400 dark:hover:border-primary-500 dark:hover:text-primary-400",onClick:q[12]||(q[12]=(...Z)=>o(he)&&o(he)(...Z))},[v(U,{name:"i-heroicons-pencil-square",class:"h-3.5 w-3.5"}),J(" "+d(o(s)("settings.aiConfig.modal.editModel")),1)])):ne("",!0),o(Q)?(b(),A("button",{key:3,class:"flex items-center gap-1 rounded-md border border-dashed border-red-200 px-2 py-1 text-xs text-red-400 transition-colors hover:border-red-400 hover:text-red-500 dark:border-red-800 dark:hover:border-red-500",onClick:q[13]||(q[13]=Z=>o(ve)(o(g).model))},[v(U,{name:"i-heroicons-trash",class:"h-3.5 w-3.5"}),J(" "+d(o(s)("settings.aiConfig.modal.deleteCustomModel")),1)])):ne("",!0)])]),o(k)?(b(),A("div",Rk,[o(p)==="valid"?(b(),A("div",Nk,[v(U,{name:"i-heroicons-check-circle",class:"h-4 w-4"}),J(" "+d(o(k)),1)])):o(p)==="invalid"?(b(),A("div",Fk,[v(U,{name:"i-heroicons-exclamation-triangle",class:"h-4 w-4"}),J(" "+d(o(k)),1)])):ne("",!0)])):ne("",!0)],64)):o(ee)?(b(),A(Me,{key:2},[o(c).thirdPartyApi?.show?(b(),xe(Oo,{key:0,icon:"i-heroicons-exclamation-triangle",content:o(c).thirdPartyApi?.content},null,8,["content"])):ne("",!0),v(Hs,{modelValue:o(g).apiKey,"onUpdate:modelValue":q[14]||(q[14]=Z=>o(g).apiKey=Z),placeholder:e.mode==="edit"&&e.config?.apiKeySet?o(s)("settings.aiConfig.modal.apiKeyPlaceholderEdit"):o(s)("settings.aiConfig.modal.apiKeyPlaceholder"),"validate-loading":o(u),"validate-disabled":!o(g).apiKey||!o(g).baseUrl,"validate-text":o(s)("settings.aiConfig.modal.validate"),"validation-result":o(p),"validation-message":o(k),onValidate:o(_e)},null,8,["modelValue","placeholder","validate-loading","validate-disabled","validate-text","validation-result","validation-message","onValidate"]),r("div",null,[r("label",Uk,d(o(s)("settings.aiConfig.modal.apiEndpoint")),1),v(ue,{modelValue:o(g).baseUrl,"onUpdate:modelValue":q[15]||(q[15]=Z=>o(g).baseUrl=Z),class:"w-full",placeholder:"https://api.example.com"},null,8,["modelValue"]),r("p",Ok,d(o(s)("settings.aiConfig.modal.apiEndpointHint")),1),o(X)?(b(),A("p",Hk,[v(U,{name:"i-heroicons-link",class:"h-3 w-3 shrink-0"}),r("span",null,d(o(s)("settings.aiConfig.modal.resolvedUrl")),1),r("code",Vk,d(o(X)),1)])):ne("",!0)]),r("div",null,[r("label",zk,d(o(s)("settings.aiConfig.modal.model")),1),o(ie).length>0?(b(),xe(Dt,{key:0,modelValue:o(g).model,"onUpdate:modelValue":q[16]||(q[16]=Z=>o(g).model=Z),items:o(ie),size:"xs"},null,8,["modelValue","items"])):(b(),A("p",Bk,[v(U,{name:"i-heroicons-exclamation-triangle",class:"h-3.5 w-3.5 shrink-0"}),J(" "+d(o(s)("settings.aiConfig.modal.modelRequired")),1)])),o(g).model?(b(),A("p",Wk,[J(d(o(s)("settings.aiConfig.modal.customModelId"))+": "+d(o(g).model)+" ",1),o(Y)?(b(),A("span",jk," · "+d(o(s)("settings.aiConfig.modal.contextWindow"))+": "+d(o(Y)>=1e6?(o(Y)/1048576).toFixed(1)+"M":Math.round(o(Y)/1024)+"K"),1)):ne("",!0)])):ne("",!0),o(g).model&&!o(Y)?(b(),A("p",qk,[v(U,{name:"i-heroicons-exclamation-triangle",class:"h-3.5 w-3.5 shrink-0"}),J(" "+d(o(s)("settings.aiConfig.modal.contextWindowMissing")),1)])):ne("",!0),r("div",Kk,[o($)?(b(),A("button",{key:0,class:"flex items-center gap-1 rounded-md border border-dashed border-primary-300 px-2 py-1 text-xs text-primary-500 transition-colors hover:border-primary-400 hover:text-primary-600 dark:border-primary-700 dark:text-primary-400 dark:hover:border-primary-500",onClick:q[17]||(q[17]=(...Z)=>o(de)&&o(de)(...Z))},[v(U,{name:"i-heroicons-cloud-arrow-down",class:"h-3.5 w-3.5"}),J(" "+d(o(s)("settings.aiConfig.modal.fetchModels")),1)])):ne("",!0),o(I)?.supportsCustomModels?(b(),A("button",{key:1,class:"flex items-center gap-1 rounded-md border border-dashed border-gray-300 px-2 py-1 text-xs text-gray-500 transition-colors hover:border-primary-400 hover:text-primary-500 dark:border-gray-600 dark:text-gray-400 dark:hover:border-primary-500 dark:hover:text-primary-400",onClick:q[18]||(q[18]=(...Z)=>o(me)&&o(me)(...Z))},[v(U,{name:"i-heroicons-plus",class:"h-3.5 w-3.5"}),J(" "+d(o(s)("settings.aiConfig.modal.addCustomModel")),1)])):ne("",!0),o(g).model?(b(),A("button",{key:2,class:"flex items-center gap-1 rounded-md border border-dashed border-gray-300 px-2 py-1 text-xs text-gray-500 transition-colors hover:border-primary-400 hover:text-primary-500 dark:border-gray-600 dark:text-gray-400 dark:hover:border-primary-500 dark:hover:text-primary-400",onClick:q[19]||(q[19]=(...Z)=>o(he)&&o(he)(...Z))},[v(U,{name:"i-heroicons-pencil-square",class:"h-3.5 w-3.5"}),J(" "+d(o(s)("settings.aiConfig.modal.editModel")),1)])):ne("",!0),o(Q)?(b(),A("button",{key:3,class:"flex items-center gap-1 rounded-md border border-dashed border-red-200 px-2 py-1 text-xs text-red-400 transition-colors hover:border-red-400 hover:text-red-500 dark:border-red-800 dark:hover:border-red-500",onClick:q[20]||(q[20]=Z=>o(ve)(o(g).model))},[v(U,{name:"i-heroicons-trash",class:"h-3.5 w-3.5"}),J(" "+d(o(s)("settings.aiConfig.modal.deleteCustomModel")),1)])):ne("",!0)])])],64)):ne("",!0),o(V)?ne("",!0):(b(),A("div",Gk,[r("label",Xk,d(o(s)("settings.aiConfig.modal.apiFormat")),1),v(Dt,{modelValue:o(g).apiFormat,"onUpdate:modelValue":q[21]||(q[21]=Z=>o(g).apiFormat=Z),items:o(B),size:"xs"},null,8,["modelValue","items"])])),o(g).provider||!o(V)?(b(),A("div",Yk,[r("label",Qk,[J(d(o(s)("settings.aiConfig.modal.configName"))+" ",1),r("span",Jk,d(o(s)("settings.aiConfig.modal.optional")),1)]),v(ue,{modelValue:o(g).customName,"onUpdate:modelValue":q[22]||(q[22]=Z=>o(g).customName=Z),class:"w-full",placeholder:o(V)?o(s)("settings.aiConfig.modal.configNamePlaceholderPreset"):o(s)("settings.aiConfig.modal.configNamePlaceholderCustom")},null,8,["modelValue","placeholder"])])):ne("",!0),o(g).provider||!o(V)?(b(),A(Me,{key:5},[r("div",Zk,[r("div",null,[r("p",ew,d(o(s)("settings.aiConfig.modal.isReasoningModel")),1),r("p",tw,d(o(s)("settings.aiConfig.modal.isReasoningModelDesc")),1)]),v(Ie,{modelValue:o(g).isReasoningModel,"onUpdate:modelValue":q[23]||(q[23]=Z=>o(g).isReasoningModel=Z)},null,8,["modelValue"])]),o(g).isReasoningModel?(b(),A("div",sw,[r("div",null,[r("p",aw,d(o(s)("settings.aiConfig.modal.disableThinking")),1),r("p",nw,d(o(s)("settings.aiConfig.modal.disableThinkingDesc")),1)]),v(Ie,{modelValue:o(g).disableThinking,"onUpdate:modelValue":q[24]||(q[24]=Z=>o(g).disableThinking=Z)},null,8,["modelValue"])])):ne("",!0)],64)):ne("",!0)])]),r("div",ow,[v(K,{variant:"soft",onClick:oe},{default:re(()=>[J(d(o(s)("common.cancel")),1)]),_:1}),v(K,{color:"primary",disabled:!o(H),loading:o(f)||o(u),onClick:o(be)},{default:re(()=>[J(d(e.mode==="add"?o(s)("common.add"):o(s)("common.save")),1)]),_:1},8,["disabled","loading","onClick"])])])]),_:1},8,["open"]),v(Te,{open:o(h),ui:{content:"z-[102]",overlay:"z-[101]"},"onUpdate:open":q[26]||(q[26]=Z=>h.value=Z)},{content:re(()=>[r("div",rw,[r("div",iw,[v(U,{name:"i-heroicons-exclamation-triangle",class:"mt-0.5 h-6 w-6 shrink-0 text-amber-500"}),r("div",null,[r("h4",lw,d(o(s)("settings.aiConfig.modal.validationFailedTitle")),1),r("p",cw,d(o(x)),1),r("p",dw,d(o(s)("settings.aiConfig.modal.saveAnywayHint")),1)])]),r("div",uw,[v(K,{variant:"soft",onClick:o(Ae)},{default:re(()=>[J(d(o(s)("common.cancel")),1)]),_:1},8,["onClick"]),v(K,{color:"warning",onClick:o(Le)},{default:re(()=>[J(d(o(s)("settings.aiConfig.modal.saveAnyway")),1)]),_:1},8,["onClick"])])])]),_:1},8,["open"]),v(wd,{open:o(y),"onUpdate:open":q[27]||(q[27]=Z=>Je(y)?y.value=Z:null),models:o(F),loading:o(le),error:o(_),"added-model-ids":o(L),onAdd:o(w),onAddAll:o(R),onRefresh:o(de)},null,8,["open","models","loading","error","added-model-ids","onAdd","onAddAll","onRefresh"]),v(Te,{open:o(S),ui:{content:"z-[102]",overlay:"z-[101]"},"onUpdate:open":q[32]||(q[32]=Z=>S.value=Z)},{content:re(()=>[r("div",mw,[r("h4",gw,d(o(s)("settings.aiConfig.modal.addCustomModel")),1),r("div",pw,[r("div",null,[r("label",fw,d(o(s)("settings.aiConfig.modal.customModelId")),1),v(ue,{modelValue:o(D),"onUpdate:modelValue":q[28]||(q[28]=Z=>Je(D)?D.value=Z:null),class:"w-full",placeholder:"gpt-4o-custom, deepseek-r1, ..."},null,8,["modelValue"]),r("p",hw,d(o(s)("settings.aiConfig.modal.customModelIdHint")),1)]),r("div",null,[r("label",vw,[J(d(o(s)("settings.aiConfig.modal.customModelDisplayName"))+" ",1),r("span",yw,d(o(s)("settings.aiConfig.modal.optional")),1)]),v(ue,{modelValue:o(C),"onUpdate:modelValue":q[29]||(q[29]=Z=>Je(C)?C.value=Z:null),class:"w-full",placeholder:o(D)||o(s)("settings.aiConfig.modal.customModelDisplayNamePlaceholder")},null,8,["modelValue","placeholder"])]),r("div",null,[r("label",bw,d(o(s)("settings.aiConfig.modal.contextWindow")),1),r("div",_w,[v(ue,{"model-value":o(M)??"",class:"flex-1",type:"number",placeholder:o(s)("settings.aiConfig.modal.contextWindowPlaceholder"),"onUpdate:modelValue":q[30]||(q[30]=Z=>M.value=Z?Number(Z):void 0)},null,8,["model-value","placeholder"])]),r("div",xw,[(b(),A(Me,null,Be([{label:"64K",value:65536},{label:"128K",value:128e3},{label:"200K",value:2e5},{label:"1M",value:1048576}],Z=>r("button",{key:Z.value,class:we(["rounded border px-1.5 py-0.5 text-[10px] transition-colors",[o(M)===Z.value?"border-primary-400 bg-primary-50 text-primary-600 dark:border-primary-600 dark:bg-primary-900/30 dark:text-primary-400":"border-gray-200 text-gray-500 hover:border-gray-300 dark:border-gray-700 dark:text-gray-400 dark:hover:border-gray-600"]]),onClick:Ce=>M.value=Z.value},d(Z.label),11,kw)),64))]),r("p",ww,d(o(s)("settings.aiConfig.modal.contextWindowHint")),1)])]),r("div",Sw,[v(K,{variant:"soft",onClick:q[31]||(q[31]=Z=>S.value=!1)},{default:re(()=>[J(d(o(s)("common.cancel")),1)]),_:1}),v(K,{color:"primary",disabled:!o(D).trim(),onClick:o(ae)},{default:re(()=>[J(d(o(s)("common.add")),1)]),_:1},8,["disabled","onClick"])])])]),_:1},8,["open"]),v(Te,{open:o(z),ui:{content:"z-[102]",overlay:"z-[101]"},"onUpdate:open":q[36]||(q[36]=Z=>z.value=Z)},{content:re(()=>[r("div",Cw,[r("h4",Mw,d(o(s)("settings.aiConfig.modal.editModel")),1),r("div",Aw,[r("div",null,[r("label",Tw,d(o(s)("settings.aiConfig.modal.customModelId")),1),r("p",$w,d(o(g).model),1)]),r("div",null,[r("label",Iw,[J(d(o(s)("settings.aiConfig.modal.customModelDisplayName"))+" ",1),r("span",Pw,d(o(s)("settings.aiConfig.modal.optional")),1)]),v(ue,{modelValue:o(W),"onUpdate:modelValue":q[33]||(q[33]=Z=>Je(W)?W.value=Z:null),class:"w-full",placeholder:o(g).model||o(s)("settings.aiConfig.modal.customModelDisplayNamePlaceholder")},null,8,["modelValue","placeholder"])]),r("div",null,[r("label",Dw,d(o(s)("settings.aiConfig.modal.contextWindow")),1),r("div",Lw,[v(ue,{"model-value":o(ce)??"",class:"flex-1",type:"number",placeholder:o(s)("settings.aiConfig.modal.contextWindowPlaceholder"),"onUpdate:modelValue":q[34]||(q[34]=Z=>ce.value=Z?Number(Z):void 0)},null,8,["model-value","placeholder"])]),r("div",Ew,[(b(),A(Me,null,Be([{label:"64K",value:65536},{label:"128K",value:128e3},{label:"200K",value:2e5},{label:"1M",value:1048576}],Z=>r("button",{key:Z.value,class:we(["rounded border px-1.5 py-0.5 text-[10px] transition-colors",[o(ce)===Z.value?"border-primary-400 bg-primary-50 text-primary-600 dark:border-primary-600 dark:bg-primary-900/30 dark:text-primary-400":"border-gray-200 text-gray-500 hover:border-gray-300 dark:border-gray-700 dark:text-gray-400 dark:hover:border-gray-600"]]),onClick:Ce=>ce.value=Z.value},d(Z.label),11,Rw)),64))]),r("p",Nw,d(o(s)("settings.aiConfig.modal.contextWindowHint")),1)])]),r("div",Fw,[v(K,{variant:"soft",onClick:q[35]||(q[35]=Z=>z.value=!1)},{default:re(()=>[J(d(o(s)("common.cancel")),1)]),_:1}),v(K,{color:"primary",onClick:o(ke)},{default:re(()=>[J(d(o(s)("common.save")),1)]),_:1},8,["onClick"])])])]),_:1},8,["open"])],64)}}}),Ow={key:0,class:"flex items-center justify-center py-12"},Hw={key:1,class:"space-y-6"},Vw={class:"mb-3 flex items-center gap-2 text-sm font-semibold text-gray-900 dark:text-white"},zw={class:"rounded-lg border border-gray-200 bg-gray-50 dark:border-gray-700 dark:bg-gray-800/50"},Bw={key:0,class:"divide-y divide-gray-200 dark:divide-gray-700"},Ww={class:"flex items-center gap-3"},jw={class:"flex h-6 w-6 shrink-0 items-center justify-center rounded-full bg-gray-200 text-gray-500 dark:bg-gray-700 dark:text-gray-400"},qw={class:"flex min-w-0 items-center gap-2"},Kw={class:"w-28 shrink-0 truncate text-sm font-medium text-gray-900 dark:text-white"},Gw={class:"flex min-w-0 items-center gap-1.5 text-xs text-gray-500 dark:text-gray-400"},Xw={class:"truncate"},Yw={class:"truncate"},Qw={class:"flex items-center gap-1"},Jw={key:1,class:"flex flex-col items-center justify-center py-8"},Zw={class:"mt-2 text-sm text-gray-500 dark:text-gray-400"},e1={class:"text-xs text-gray-400 dark:text-gray-500"},t1={class:"border-t border-gray-200 px-4 py-3 dark:border-gray-700"},s1=$e({__name:"AIModelConfigTab",emits:["config-changed"],setup(e,{expose:t,emit:s}){const{t:n,locale:a}=Re(),i=s,c=G(()=>JSON.parse(localStorage.getItem(`chatlab_app_config_${a.value}`)||localStorage.getItem("chatlab_app_config")||"{}").aiTips||{}),l=Is(),{configs:m,providers:u,providerRegistry:f,isLoading:h,isMaxConfigs:x}=Ge(l),S=P(!1),C=P("add"),D=P(null);function M(){C.value="add",D.value=null,S.value=!0}function g(ee){C.value="edit",D.value=ee,S.value=!0}async function p(){await l.refreshConfigs(),i("config-changed")}async function k(ee){try{const V=await window.llmApi.deleteConfig(ee);V.success?(await l.refreshConfigs(),i("config-changed")):console.error("删除配置失败:",V.error)}catch(V){console.error("删除配置失败:",V)}}function T(ee){const V=`providers.${ee}.name`,ie=n(V);return ie!==V?ie:l.getProviderName(ee)}function E(ee){const V=f.value.find(ie=>ie.id===ee);return!V||V.kind==="official"||V.kind==="openai-compatible"?null:V.kind==="aggregator"?n("settings.aiConfig.providerKind.aggregator"):V.builtin?null:n("settings.aiConfig.providerKind.custom")}function I(ee,V){return V?l.getModelById(ee,V)?.name||V:n("settings.aiConfig.defaultModel")}function N(){l.refreshConfigs()}return t({refresh:N}),Qe(()=>{l.isInitialized?l.refreshConfigs():l.init()}),(ee,V)=>{const ie=Ve,Q=va,Y=We;return b(),A(Me,null,[o(h)?(b(),A("div",Ow,[v(ie,{name:"i-heroicons-arrow-path",class:"h-6 w-6 animate-spin text-gray-400"})])):(b(),A("div",Hw,[r("div",null,[r("h4",Vw,[v(ie,{name:"i-heroicons-sparkles",class:"h-4 w-4 text-violet-500"}),J(" "+d(o(n)("settings.aiConfig.title")),1)]),o(m).length===0&&c.value.configTab?.show?(b(),xe(Oo,{key:0,content:c.value.configTab?.content},null,8,["content"])):ne("",!0),r("div",zw,[o(m).length>0?(b(),A("div",Bw,[(b(!0),A(Me,null,Be(o(m),H=>(b(),A("div",{key:H.id,class:"group flex items-center justify-between px-4 py-2.5 transition-colors hover:bg-gray-100/50 dark:hover:bg-gray-700/30"},[r("div",Ww,[r("div",jw,[v(ie,{name:"i-heroicons-sparkles",class:"h-3.5 w-3.5"})]),r("div",qw,[r("span",Kw,d(H.name),1),V[2]||(V[2]=r("span",{class:"h-3.5 w-px shrink-0 bg-gray-200 dark:bg-gray-700"},null,-1)),r("span",Gw,[r("span",Xw,d(T(H.provider)),1),E(H.provider)?(b(),xe(Q,{key:0,color:"neutral",variant:"subtle",size:"xs"},{default:re(()=>[J(d(E(H.provider)),1)]),_:2},1024)):ne("",!0),V[1]||(V[1]=r("span",{class:"shrink-0"},"·",-1)),r("span",Yw,d(I(H.provider,H.model)),1)])])]),r("div",Qw,[v(Y,{size:"xs",color:"neutral",variant:"ghost",icon:"i-heroicons-pencil-square",onClick:B=>g(H)},null,8,["onClick"]),v(Y,{size:"xs",color:"error",variant:"ghost",icon:"i-heroicons-trash",onClick:B=>k(H.id)},null,8,["onClick"])])]))),128))])):(b(),A("div",Jw,[v(ie,{name:"i-heroicons-sparkles",class:"h-8 w-8 text-gray-300 dark:text-gray-600"}),r("p",Zw,d(o(n)("settings.aiConfig.empty.title")),1),r("p",e1,d(o(n)("settings.aiConfig.empty.description")),1)])),r("div",t1,[v(Y,{variant:"soft",disabled:o(x),size:"sm",onClick:M},{default:re(()=>[v(ie,{name:"i-heroicons-plus",class:"mr-1.5 h-3.5 w-3.5"}),J(" "+d(o(x)?o(n)("settings.aiConfig.maxConfigs"):o(n)("settings.aiConfig.addConfig")),1)]),_:1},8,["disabled"])])])])])),v(Uw,{open:S.value,"onUpdate:open":V[0]||(V[0]=H=>S.value=H),mode:C.value,config:D.value,providers:o(u),onSaved:p},null,8,["open","mode","config","providers"])],64)}}}),a1={class:"space-y-6"},n1={key:0,class:"rounded-lg border-2 border-dashed border-gray-200 py-8 text-center dark:border-gray-700"},o1={class:"text-sm text-gray-500 dark:text-gray-400"},r1={key:1},i1={class:"mb-3 flex items-center gap-2 text-sm font-semibold text-gray-900 dark:text-white"},l1={class:"space-y-5 rounded-lg border border-gray-200 bg-gray-50 p-4 dark:border-gray-700 dark:bg-gray-800/50"},c1={class:"mb-2"},d1={class:"text-sm font-medium text-gray-900 dark:text-white"},u1={class:"text-xs text-gray-500 dark:text-gray-400"},m1={class:"flex items-center gap-3"},g1={class:"flex-1"},p1={class:"mb-1 block text-xs text-gray-400 dark:text-gray-500"},f1={class:"flex-1"},h1={class:"mb-1 block text-xs text-gray-400 dark:text-gray-500"},v1={class:"mb-2"},y1={class:"text-sm font-medium text-gray-900 dark:text-white"},b1={class:"text-xs text-gray-500 dark:text-gray-400"},_1={class:"flex items-center gap-3"},x1={class:"flex-1"},k1={class:"mb-1 block text-xs text-gray-400 dark:text-gray-500"},w1={class:"flex-1"},S1={class:"mb-1 block text-xs text-gray-400 dark:text-gray-500"},zs="__follow__",C1=$e({__name:"AIDefaultModelTab",emits:["config-changed"],setup(e,{emit:t}){const{t:s}=Re(),n=t,a=Is(),{configs:i,defaultAssistant:c,fastModel:l,modelCatalog:m}=Ge(a);function u(k){const T=i.value.find(N=>N.id===k);if(!T)return[];if(T.customModels&&T.customModels.length>0)return T.customModels.map(N=>({label:N.name||N.id,value:N.id}));const I=m.value.filter(N=>N.providerId===T.provider&&!N.capabilities.includes("embedding")&&!N.capabilities.includes("ranking")).map(N=>({label:N.name||N.id,value:N.id}));return T.model&&!I.some(N=>N.value===T.model)&&I.unshift({label:T.model,value:T.model}),I}const f=G(()=>i.value.map(k=>({label:k.name,value:k.id}))),h=G(()=>{const k=c.value?.configId;return k?u(k):[]}),x=G({get:()=>c.value?.configId??"",set:k=>{if(!k)return;const E=u(k)[0]?.value??"";a.setDefaultAssistantModel(k,E),n("config-changed")}}),S=G({get:()=>c.value?.modelId??"",set:k=>{const T=c.value?.configId;T&&k&&(a.setDefaultAssistantModel(T,k),n("config-changed"))}}),C=G(()=>[{label:s("settings.defaultModel.fastModel.followAssistant"),value:zs},...f.value]),D=G(()=>{const k=l.value?.configId;return k?u(k):[]}),M=G(()=>l.value!==null),g=G({get:()=>l.value?.configId??zs,set:k=>{if(k===zs)a.setFastModel(null);else{const E=u(k)[0]?.value??"";a.setFastModel({configId:k,modelId:E})}n("config-changed")}}),p=G({get:()=>l.value?.modelId??"",set:k=>{const T=l.value?.configId;T&&k&&(a.setFastModel({configId:T,modelId:k}),n("config-changed"))}});return Qe(()=>{a.isInitialized||a.init()}),(k,T)=>{const E=Ve,I=xr;return b(),A("div",a1,[o(i).length===0?(b(),A("div",n1,[v(E,{name:"i-heroicons-cpu-chip",class:"mx-auto mb-2 h-8 w-8 text-gray-300 dark:text-gray-600"}),r("p",o1,d(o(s)("settings.defaultModel.noConfigs")),1)])):(b(),A("div",r1,[r("h4",i1,[v(E,{name:"i-heroicons-cpu-chip",class:"h-4 w-4 text-violet-500"}),J(" "+d(o(s)("settings.defaultModel.title")),1)]),r("div",l1,[r("div",null,[r("div",c1,[r("p",d1,d(o(s)("settings.defaultModel.assistantModel.label")),1),r("p",u1,d(o(s)("settings.defaultModel.assistantModel.description")),1)]),r("div",m1,[r("div",g1,[r("span",p1,d(o(s)("settings.defaultModel.selectProvider")),1),v(I,{modelValue:x.value,"onUpdate:modelValue":T[0]||(T[0]=N=>x.value=N),items:f.value,ui:{content:"z-[200]"},class:"w-full",size:"sm"},null,8,["modelValue","items"])]),r("div",f1,[r("span",h1,d(o(s)("settings.defaultModel.selectModel")),1),h.value.length>0?(b(),xe(I,{key:0,modelValue:S.value,"onUpdate:modelValue":T[1]||(T[1]=N=>S.value=N),items:h.value,ui:{content:"z-[200]"},class:"w-full",size:"sm"},null,8,["modelValue","items"])):(b(),xe(I,{key:1,items:[],disabled:"",class:"w-full",size:"sm"}))])])]),r("div",null,[r("div",v1,[r("p",y1,d(o(s)("settings.defaultModel.fastModel.label")),1),r("p",b1,d(o(s)("settings.defaultModel.fastModel.description")),1)]),r("div",_1,[r("div",x1,[r("span",k1,d(o(s)("settings.defaultModel.selectProvider")),1),v(I,{modelValue:g.value,"onUpdate:modelValue":T[2]||(T[2]=N=>g.value=N),items:C.value,ui:{content:"z-[200]"},class:"w-full",size:"sm"},null,8,["modelValue","items"])]),r("div",w1,[r("span",S1,d(o(s)("settings.defaultModel.selectModel")),1),M.value&&D.value.length>0?(b(),xe(I,{key:0,modelValue:p.value,"onUpdate:modelValue":T[3]||(T[3]=N=>p.value=N),items:D.value,ui:{content:"z-[200]"},class:"w-full",size:"sm"},null,8,["modelValue","items"])):(b(),xe(I,{key:1,items:[],disabled:"",class:"w-full",size:"sm"}))])])])])]))])}}}),Ls=wt("prompt",()=>{const e=P(0),t=P({maxMessagesPerRequest:1e3,exportFormat:"markdown",sqlExportFormat:"csv",enableAutoSkill:!0,searchContextBefore:2,searchContextAfter:2,contextCompression:{enabled:!0,tokenThresholdPercent:75,bufferSizePercent:20,maxToolResultPercent:50}}),s=P([]),n=P([]);function a(){e.value++}function i(f){const{contextCompression:h,...x}=f;t.value={...t.value,...x,contextCompression:h?{...t.value.contextCompression,...h}:t.value.contextCompression},a()}function c(f){s.value.push(f)}function l(f,h){const x=s.value.findIndex(S=>S.id===f);x!==-1&&(s.value[x]={...s.value[x],...h})}function m(f){const h=s.value.findIndex(x=>x.id===f);h!==-1&&s.value.splice(h,1)}function u(f){n.value.includes(f)||n.value.push(f)}return{aiConfigVersion:e,aiGlobalSettings:t,customKeywordTemplates:s,deletedPresetTemplateIds:n,notifyAIConfigChanged:a,updateAIGlobalSettings:i,addCustomKeywordTemplate:c,updateCustomKeywordTemplate:l,removeCustomKeywordTemplate:m,addDeletedPresetTemplateId:u}},{persist:!1,backendPersist:{pick:["aiGlobalSettings","customKeywordTemplates","deletedPresetTemplateIds"]}}),M1={class:"space-y-6"},A1={class:"mb-3 flex items-center gap-2 text-sm font-semibold text-gray-900 dark:text-white"},T1={class:"space-y-4 rounded-lg border border-gray-200 bg-gray-50 p-4 dark:border-gray-700 dark:bg-gray-800/50"},$1={class:"flex items-center justify-between"},I1={class:"flex-1 pr-4"},P1={class:"text-sm font-medium text-gray-900 dark:text-white"},D1={class:"text-xs text-gray-500 dark:text-gray-400"},L1={class:"mb-2"},E1={class:"text-sm font-medium text-gray-900 dark:text-white"},R1={class:"text-xs text-gray-500 dark:text-gray-400"},N1={class:"flex items-center gap-4"},F1={class:"flex items-center gap-2"},U1={class:"text-xs text-gray-500 dark:text-gray-400"},O1={class:"flex items-center gap-2"},H1={class:"text-xs text-gray-500 dark:text-gray-400"},V1={class:"mb-3 flex items-center gap-2 text-sm font-semibold text-gray-900 dark:text-white"},z1={class:"space-y-4 rounded-lg border border-gray-200 bg-gray-50 p-4 dark:border-gray-700 dark:bg-gray-800/50"},B1={class:"flex items-center justify-between"},W1={class:"flex-1 pr-4"},j1={class:"text-sm font-medium text-gray-900 dark:text-white"},q1={class:"text-xs text-gray-500 dark:text-gray-400"},K1={class:"mb-3 flex items-center gap-2 text-sm font-semibold text-gray-900 dark:text-white"},G1={class:"space-y-4 rounded-lg border border-gray-200 bg-gray-50 p-4 dark:border-gray-700 dark:bg-gray-800/50"},X1={class:"flex items-center justify-between"},Y1={class:"flex-1 pr-4"},Q1={class:"text-sm font-medium text-gray-900 dark:text-white"},J1={class:"text-xs text-gray-500 dark:text-gray-400"},Z1={class:"flex items-center justify-between"},eS={class:"flex-1 pr-4"},tS={class:"text-sm font-medium text-gray-900 dark:text-white"},sS={class:"text-xs text-gray-500 dark:text-gray-400"},aS={class:"flex items-center gap-1"},nS={class:"flex items-center justify-between"},oS={class:"flex-1 pr-4"},rS={class:"text-sm font-medium text-gray-900 dark:text-white"},iS={class:"text-xs text-gray-500 dark:text-gray-400"},lS={class:"flex items-center gap-1"},cS={class:"flex items-center justify-between"},dS={class:"flex-1 pr-4"},uS={class:"text-sm font-medium text-gray-900 dark:text-white"},mS={class:"text-xs text-gray-500 dark:text-gray-400"},gS={class:"flex items-center gap-1"},pS=$e({__name:"AIPromptConfigTab",props:{setSectionRef:{type:Function}},emits:["config-changed"],setup(e,{emit:t}){const{t:s}=Re(),n=Ls(),{aiGlobalSettings:a}=Ge(n),i=e,c=t;function l(M,g){i.setSectionRef?.(M,g)}const m=G({get:()=>a.value.maxMessagesPerRequest,set:M=>{const g=Math.max(0,Math.min(5e4,M||1e3));n.updateAIGlobalSettings({maxMessagesPerRequest:g}),c("config-changed")}}),u=G({get:()=>a.value.enableAutoSkill??!0,set:M=>{n.updateAIGlobalSettings({enableAutoSkill:M}),c("config-changed")}}),f=G({get:()=>a.value.searchContextBefore??3,set:M=>{const g=Math.max(0,Math.min(20,M??3));n.updateAIGlobalSettings({searchContextBefore:g}),c("config-changed")}}),h=G({get:()=>a.value.searchContextAfter??3,set:M=>{const g=Math.max(0,Math.min(20,M??3));n.updateAIGlobalSettings({searchContextAfter:g}),c("config-changed")}}),x=G({get:()=>a.value.contextCompression?.enabled??!1,set:M=>{n.updateAIGlobalSettings({contextCompression:{...a.value.contextCompression,enabled:M}}),c("config-changed")}}),S=G({get:()=>a.value.contextCompression?.tokenThresholdPercent??75,set:M=>{const g=Math.max(30,Math.min(95,M||75));n.updateAIGlobalSettings({contextCompression:{...a.value.contextCompression,tokenThresholdPercent:g}}),c("config-changed")}}),C=G({get:()=>a.value.contextCompression?.bufferSizePercent??20,set:M=>{const g=Math.max(5,Math.min(50,M||20));n.updateAIGlobalSettings({contextCompression:{...a.value.contextCompression,bufferSizePercent:g}}),c("config-changed")}}),D=G({get:()=>a.value.contextCompression?.maxToolResultPercent??50,set:M=>{const g=Math.max(10,Math.min(60,M||50));n.updateAIGlobalSettings({contextCompression:{...a.value.contextCompression,maxToolResultPercent:g}}),c("config-changed")}});return(M,g)=>{const p=Ve,k=ao,T=Kt;return b(),A("div",M1,[r("div",{ref:E=>l("chat",E)},[r("h4",A1,[v(p,{name:"i-heroicons-chat-bubble-left-right",class:"h-4 w-4 text-green-500"}),J(" "+d(o(s)("settings.aiPrompt.chatSettings.title")),1)]),r("div",T1,[r("div",$1,[r("div",I1,[r("p",P1,d(o(s)("settings.aiPrompt.maxMessages.title")),1),r("p",D1,d(o(s)("settings.aiPrompt.maxMessages.description")),1)]),v(k,{modelValue:m.value,"onUpdate:modelValue":g[0]||(g[0]=E=>m.value=E),min:0,max:5e4,class:"w-30"},null,8,["modelValue"])]),r("div",null,[r("div",L1,[r("p",E1,d(o(s)("settings.aiPrompt.searchContext.title")),1),r("p",R1,d(o(s)("settings.aiPrompt.searchContext.description")),1)]),r("div",N1,[r("div",F1,[r("span",U1,d(o(s)("settings.aiPrompt.searchContext.before")),1),v(k,{modelValue:f.value,"onUpdate:modelValue":g[1]||(g[1]=E=>f.value=E),min:0,max:20,class:"w-24"},null,8,["modelValue"])]),r("div",O1,[r("span",H1,d(o(s)("settings.aiPrompt.searchContext.after")),1),v(k,{modelValue:h.value,"onUpdate:modelValue":g[2]||(g[2]=E=>h.value=E),min:0,max:20,class:"w-24"},null,8,["modelValue"])])])])])],512),r("div",{ref:E=>l("skill",E)},[r("h4",V1,[v(p,{name:"i-heroicons-bolt",class:"h-4 w-4 text-amber-500"}),J(" "+d(o(s)("settings.aiPrompt.skillSettings.title")),1)]),r("div",z1,[r("div",B1,[r("div",W1,[r("p",j1,d(o(s)("settings.aiPrompt.skillSettings.enableAutoSkill")),1),r("p",q1,d(o(s)("settings.aiPrompt.skillSettings.enableAutoSkillDesc")),1)]),v(T,{modelValue:u.value,"onUpdate:modelValue":g[3]||(g[3]=E=>u.value=E)},null,8,["modelValue"])])])],512),r("div",{ref:E=>l("compression",E)},[r("h4",K1,[v(p,{name:"i-heroicons-archive-box-arrow-down",class:"h-4 w-4 text-purple-500"}),J(" "+d(o(s)("settings.aiPrompt.compression.title")),1)]),r("div",G1,[r("div",X1,[r("div",Y1,[r("p",Q1,d(o(s)("settings.aiPrompt.compression.enable")),1),r("p",J1,d(o(s)("settings.aiPrompt.compression.enableDesc")),1)]),v(T,{modelValue:x.value,"onUpdate:modelValue":g[4]||(g[4]=E=>x.value=E)},null,8,["modelValue"])]),r("div",Z1,[r("div",eS,[r("p",tS,d(o(s)("settings.aiPrompt.compression.maxToolResultPercent")),1),r("p",sS,d(o(s)("settings.aiPrompt.compression.maxToolResultPercentDesc")),1)]),r("div",aS,[v(k,{modelValue:D.value,"onUpdate:modelValue":g[5]||(g[5]=E=>D.value=E),min:10,max:60,class:"w-24"},null,8,["modelValue"]),g[8]||(g[8]=r("span",{class:"text-xs text-gray-400"},"%",-1))])]),x.value?(b(),A(Me,{key:0},[r("div",nS,[r("div",oS,[r("p",rS,d(o(s)("settings.aiPrompt.compression.threshold")),1),r("p",iS,d(o(s)("settings.aiPrompt.compression.thresholdDesc")),1)]),r("div",lS,[v(k,{modelValue:S.value,"onUpdate:modelValue":g[6]||(g[6]=E=>S.value=E),min:30,max:95,class:"w-24"},null,8,["modelValue"]),g[9]||(g[9]=r("span",{class:"text-xs text-gray-400"},"%",-1))])]),r("div",cS,[r("div",dS,[r("p",uS,d(o(s)("settings.aiPrompt.compression.buffer")),1),r("p",mS,d(o(s)("settings.aiPrompt.compression.bufferDesc")),1)]),r("div",gS,[v(k,{modelValue:C.value,"onUpdate:modelValue":g[7]||(g[7]=E=>C.value=E),min:5,max:50,class:"w-24"},null,8,["modelValue"]),g[10]||(g[10]=r("span",{class:"text-xs text-gray-400"},"%",-1))])])],64)):ne("",!0)])],512)])}}}),fS={class:"space-y-6"},hS={class:"mb-1 flex items-center gap-2 text-sm font-semibold text-gray-900 dark:text-white"},vS={class:"text-xs text-gray-500 dark:text-gray-400"},yS={class:"space-y-3 rounded-lg border border-gray-200 bg-gray-50 p-4 dark:border-gray-700 dark:bg-gray-800/50"},bS={class:"flex items-center justify-between"},_S={class:"flex-1 pr-4"},xS={class:"text-sm font-medium text-gray-900 dark:text-white"},kS={class:"text-xs text-gray-500 dark:text-gray-400"},wS={class:"flex items-center justify-between"},SS={class:"flex-1 pr-4"},CS={class:"text-sm font-medium text-gray-900 dark:text-white"},MS={class:"text-xs text-gray-500 dark:text-gray-400"},AS={key:0,class:"ml-6 flex items-center justify-between"},TS={class:"text-xs text-gray-500 dark:text-gray-400"},$S={class:"flex items-center justify-between"},IS={class:"flex-1 pr-4"},PS={class:"text-sm font-medium text-gray-900 dark:text-white"},DS={class:"text-xs text-gray-500 dark:text-gray-400"},LS={class:"flex items-center justify-between"},ES={class:"flex-1 pr-4"},RS={class:"text-sm font-medium text-gray-900 dark:text-white"},NS={class:"text-xs text-gray-500 dark:text-gray-400"},FS={class:"flex items-center justify-between"},US={class:"flex-1 pr-4"},OS={class:"text-sm font-medium text-gray-900 dark:text-white"},HS={class:"text-xs text-gray-500 dark:text-gray-400"},VS={key:1,class:"ml-4 space-y-3"},zS={key:0},BS={class:"mb-2 text-xs font-medium text-gray-500 dark:text-gray-400"},WS={class:"space-y-1.5"},jS=["checked","onChange"],qS={class:"flex-1 text-xs text-gray-700 dark:text-gray-300"},KS={key:0,class:"shrink-0 text-[10px] text-gray-400"},GS={class:"mb-2 text-xs font-medium text-gray-500 dark:text-gray-400"},XS={key:0,class:"mb-2 space-y-1.5"},YS=["checked","onChange"],QS={class:"flex-1 text-xs text-gray-700 dark:text-gray-300"},JS=["title"],ZS={class:"space-y-3 rounded-md border border-dashed border-gray-300 p-3 dark:border-gray-600"},eC={class:"text-xs font-medium text-gray-500 dark:text-gray-400"},tC={class:"grid grid-cols-[auto_1fr] items-center gap-x-3 gap-y-2"},sC={class:"text-[11px] text-gray-500 dark:text-gray-400 whitespace-nowrap"},aC={class:"text-[11px] text-gray-500 dark:text-gray-400 whitespace-nowrap"},nC={key:0,class:"mt-1 text-xs text-red-500"},oC={class:"text-[11px] text-gray-500 dark:text-gray-400 whitespace-nowrap"},rC={class:"mb-2 text-sm font-medium text-gray-900 dark:text-white"},iC={class:"mb-3 text-xs text-gray-500 dark:text-gray-400"},lC={class:"mb-3 flex gap-2"},cC={key:0,class:"flex flex-wrap gap-2"},dC=$e({__name:"AIPreprocessTab",setup(e){const{t,te:s}=Re(),n=It(),{aiPreprocessConfig:a}=Ge(n);Qe(()=>n.ensureDesensitizeRules());const i=P("");function c(){const g=i.value.trim();if(g){if(a.value.blacklistKeywords.includes(g)){i.value="";return}a.value.blacklistKeywords.push(g),i.value=""}}function l(g){a.value.blacklistKeywords.splice(g,1)}const m=G(()=>a.value.desensitizeRules.filter(g=>g.builtin)),u=G(()=>a.value.desensitizeRules.filter(g=>!g.builtin)),f=P({name:"",pattern:"",replacement:""}),h=P("");function x(g){const p=`settings.desensitize.rules.${g.id}`;return s(p)?t(p):g.label}function S(g){const p=`settings.desensitize.rules.${g.id}_desc`;return s(p)?t(p):""}function C(g){const p=a.value.desensitizeRules.find(k=>k.id===g);p&&(p.enabled=!p.enabled)}function D(){const g=f.value.name.trim(),p=f.value.pattern.trim(),k=f.value.replacement.trim();if(!(!g||!p||!k)){try{new RegExp(p),h.value=""}catch{h.value=t("settings.aiPreprocess.desensitizeRuleInvalidRegex");return}a.value.desensitizeRules.push({id:`custom_${Date.now()}_${Math.random().toString(36).slice(2,6)}`,label:g,pattern:p,replacement:k,enabled:!0,builtin:!1,locales:[]}),f.value={name:"",pattern:"",replacement:""}}}function M(g){const p=a.value.desensitizeRules.findIndex(k=>k.id===g);p!==-1&&a.value.desensitizeRules.splice(p,1)}return(g,p)=>{const k=Ve,T=Kt,E=ao,I=We,N=lt,ee=va;return b(),A("div",fS,[r("div",null,[r("h4",hS,[v(k,{name:"i-heroicons-funnel",class:"h-4 w-4 text-amber-500"}),J(" "+d(o(t)("settings.aiPreprocess.title")),1)]),r("p",vS,d(o(t)("settings.aiPreprocess.description")),1)]),r("div",yS,[r("div",bS,[r("div",_S,[r("p",xS,d(o(t)("settings.aiPreprocess.dataCleaning")),1),r("p",kS,d(o(t)("settings.aiPreprocess.dataCleaningDesc")),1)]),v(T,{modelValue:o(a).dataCleaning,"onUpdate:modelValue":p[0]||(p[0]=V=>o(a).dataCleaning=V)},null,8,["modelValue"])]),r("div",wS,[r("div",SS,[r("p",CS,d(o(t)("settings.aiPreprocess.mergeConsecutive")),1),r("p",MS,d(o(t)("settings.aiPreprocess.mergeConsecutiveDesc")),1)]),v(T,{modelValue:o(a).mergeConsecutive,"onUpdate:modelValue":p[1]||(p[1]=V=>o(a).mergeConsecutive=V)},null,8,["modelValue"])]),o(a).mergeConsecutive?(b(),A("div",AS,[r("p",TS,d(o(t)("settings.aiPreprocess.mergeWindow")),1),v(E,{modelValue:o(a).mergeWindowSeconds,"onUpdate:modelValue":p[2]||(p[2]=V=>o(a).mergeWindowSeconds=V),min:30,max:600,step:30,class:"w-28"},null,8,["modelValue"])])):ne("",!0),r("div",$S,[r("div",IS,[r("p",PS,d(o(t)("settings.aiPreprocess.denoise")),1),r("p",DS,d(o(t)("settings.aiPreprocess.denoiseDesc")),1)]),v(T,{modelValue:o(a).denoise,"onUpdate:modelValue":p[3]||(p[3]=V=>o(a).denoise=V)},null,8,["modelValue"])]),r("div",LS,[r("div",ES,[r("p",RS,d(o(t)("settings.aiPreprocess.anonymizeNames")),1),r("p",NS,d(o(t)("settings.aiPreprocess.anonymizeNamesDesc")),1)]),v(T,{modelValue:o(a).anonymizeNames,"onUpdate:modelValue":p[4]||(p[4]=V=>o(a).anonymizeNames=V)},null,8,["modelValue"])]),r("div",FS,[r("div",US,[r("p",OS,d(o(t)("settings.aiPreprocess.desensitize")),1),r("p",HS,d(o(t)("settings.aiPreprocess.desensitizeDesc")),1)]),v(T,{modelValue:o(a).desensitize,"onUpdate:modelValue":p[5]||(p[5]=V=>o(a).desensitize=V)},null,8,["modelValue"])]),o(a).desensitize?(b(),A("div",VS,[m.value.length>0?(b(),A("div",zS,[r("p",BS,d(o(t)("settings.aiPreprocess.desensitizeBuiltin")),1),r("div",WS,[(b(!0),A(Me,null,Be(m.value,V=>(b(),A("label",{key:V.id,class:"flex cursor-pointer items-center gap-2.5 rounded-md px-2 py-1.5 hover:bg-gray-100 dark:hover:bg-gray-700/50"},[r("input",{type:"checkbox",checked:V.enabled,class:"h-3.5 w-3.5 rounded border-gray-300 text-primary-500 focus:ring-primary-500",onChange:ie=>C(V.id)},null,40,jS),r("span",qS,d(x(V)),1),S(V)?(b(),A("span",KS,d(S(V)),1)):ne("",!0)]))),128))])])):ne("",!0),r("div",null,[r("p",GS,d(o(t)("settings.aiPreprocess.desensitizeCustom")),1),u.value.length>0?(b(),A("div",XS,[(b(!0),A(Me,null,Be(u.value,V=>(b(),A("div",{key:V.id,class:"flex items-center gap-2.5 rounded-md px-2 py-1.5 hover:bg-gray-100 dark:hover:bg-gray-700/50"},[r("input",{type:"checkbox",checked:V.enabled,class:"h-3.5 w-3.5 rounded border-gray-300 text-primary-500 focus:ring-primary-500",onChange:ie=>C(V.id)},null,40,YS),r("span",QS,d(V.label),1),r("code",{class:"max-w-40 shrink-0 truncate text-[10px] text-gray-400",title:V.pattern},d(V.pattern),9,JS),v(I,{icon:"i-heroicons-x-mark",variant:"ghost",size:"2xs",color:"error",onClick:ie=>M(V.id)},null,8,["onClick"])]))),128))])):ne("",!0),r("div",ZS,[r("p",eC,d(o(t)("settings.aiPreprocess.desensitizeAddCustom")),1),r("div",tC,[r("label",sC,d(o(t)("settings.aiPreprocess.desensitizeRuleName"))+": ",1),v(N,{modelValue:f.value.name,"onUpdate:modelValue":p[6]||(p[6]=V=>f.value.name=V),placeholder:o(t)("settings.aiPreprocess.desensitizeRuleNamePlaceholder"),size:"xs",class:"w-full"},null,8,["modelValue","placeholder"]),r("label",aC,d(o(t)("settings.aiPreprocess.desensitizeRulePattern"))+": ",1),r("div",null,[v(N,{modelValue:f.value.pattern,"onUpdate:modelValue":p[7]||(p[7]=V=>f.value.pattern=V),placeholder:o(t)("settings.aiPreprocess.desensitizeRulePatternPlaceholder"),size:"xs",class:"w-full font-mono"},null,8,["modelValue","placeholder"]),h.value?(b(),A("p",nC,d(h.value),1)):ne("",!0)]),r("label",oC,d(o(t)("settings.aiPreprocess.desensitizeRuleReplacement"))+": ",1),v(N,{modelValue:f.value.replacement,"onUpdate:modelValue":p[8]||(p[8]=V=>f.value.replacement=V),placeholder:o(t)("settings.aiPreprocess.desensitizeRuleReplacementPlaceholder"),size:"xs",class:"w-full"},null,8,["modelValue","placeholder"])]),v(I,{size:"xs",variant:"soft",block:"",disabled:!f.value.name.trim()||!f.value.pattern.trim()||!f.value.replacement.trim(),onClick:D},{default:re(()=>[J(d(o(t)("settings.aiPreprocess.desensitizeRuleAdd")),1)]),_:1},8,["disabled"])])])])):ne("",!0)]),r("div",null,[r("h4",rC,d(o(t)("settings.aiPreprocess.blacklist")),1),r("p",iC,d(o(t)("settings.aiPreprocess.blacklistDesc")),1),r("div",lC,[v(N,{modelValue:i.value,"onUpdate:modelValue":p[9]||(p[9]=V=>i.value=V),placeholder:o(t)("settings.aiPreprocess.blacklistPlaceholder"),class:"flex-1",size:"sm",onKeydown:Zt(es(c,["prevent"]),["enter"])},null,8,["modelValue","placeholder","onKeydown"]),v(I,{size:"sm",variant:"soft",disabled:!i.value.trim(),onClick:c},{default:re(()=>[J(d(o(t)("settings.aiPreprocess.blacklistAdd")),1)]),_:1},8,["disabled"])]),o(a).blacklistKeywords.length>0?(b(),A("div",cC,[(b(!0),A(Me,null,Be(o(a).blacklistKeywords,(V,ie)=>(b(),xe(ee,{key:V,variant:"subtle",color:"error",class:"cursor-pointer",onClick:Q=>l(ie)},{default:re(()=>[J(d(V)+" ",1),v(k,{name:"i-heroicons-x-mark",class:"ml-1 h-3 w-3"})]),_:2},1032,["onClick"]))),128))])):ne("",!0)])])}}}),uC={class:"mb-3 flex items-center gap-2 text-sm font-semibold text-gray-900 dark:text-white"},mC={class:"space-y-4 rounded-lg border border-gray-200 bg-gray-50 p-4 dark:border-gray-700 dark:bg-gray-800/50"},gC={class:"flex items-center justify-between"},pC={class:"flex-1 pr-4"},fC={class:"text-sm font-medium text-gray-900 dark:text-white"},hC={class:"text-xs text-gray-500 dark:text-gray-400"},vC={class:"flex items-center justify-between"},yC={class:"flex-1 pr-4"},bC={class:"text-sm font-medium text-gray-900 dark:text-white"},_C={class:"text-xs text-gray-500 dark:text-gray-400"},xC=$e({__name:"AIExportSettingsTab",emits:["config-changed"],setup(e,{emit:t}){const{t:s}=Re(),n=t,a=Ls(),{aiGlobalSettings:i}=Ge(a),c=G(()=>[{label:"Markdown",value:"markdown"},{label:s("settings.aiPrompt.exportFormat.txtLabel"),value:"txt"}]),l=G({get:()=>i.value.exportFormat??"markdown",set:f=>{a.updateAIGlobalSettings({exportFormat:f}),n("config-changed")}}),m=G(()=>[{label:"CSV",value:"csv"},{label:"JSON",value:"json"}]),u=G({get:()=>i.value.sqlExportFormat??"csv",set:f=>{a.updateAIGlobalSettings({sqlExportFormat:f}),n("config-changed")}});return(f,h)=>{const x=Ve,S=cs;return b(),A("div",null,[r("h4",uC,[v(x,{name:"i-heroicons-arrow-down-tray",class:"h-4 w-4 text-blue-500"}),J(" "+d(o(s)("settings.aiPrompt.exportSettings.title")),1)]),r("div",mC,[r("div",gC,[r("div",pC,[r("p",fC,d(o(s)("settings.aiPrompt.exportFormat.title")),1),r("p",hC,d(o(s)("settings.aiPrompt.exportFormat.description")),1)]),v(S,{modelValue:l.value,"onUpdate:modelValue":h[0]||(h[0]=C=>l.value=C),items:c.value,size:"xs"},null,8,["modelValue","items"])]),r("div",vC,[r("div",yC,[r("p",bC,d(o(s)("settings.aiPrompt.sqlExportFormat.title")),1),r("p",_C,d(o(s)("settings.aiPrompt.sqlExportFormat.description")),1)]),v(S,{modelValue:u.value,"onUpdate:modelValue":h[1]||(h[1]=C=>u.value=C),items:m.value,size:"xs"},null,8,["modelValue","items"])])])])}}}),kC={class:"space-y-6"},wC={class:"space-y-3"},SC={class:"flex items-center justify-between"},CC={class:"flex items-center gap-2 text-sm font-semibold text-gray-900 dark:text-white"},MC={class:"mt-0.5 text-xs text-gray-500 dark:text-gray-400"},AC={class:"flex items-center justify-between rounded-lg border border-gray-200 bg-gray-50 px-4 py-3 dark:border-gray-700 dark:bg-gray-800/50"},TC={class:"text-sm text-gray-700 dark:text-gray-300"},$C={class:"text-xs text-gray-400"},IC={class:"flex items-center justify-between rounded-lg border border-gray-200 bg-gray-50 px-4 py-3 dark:border-gray-700 dark:bg-gray-800/50"},PC={class:"text-sm text-gray-700 dark:text-gray-300"},DC={class:"text-xs text-gray-400"},LC={class:"flex items-center gap-2"},EC={class:"text-xs text-gray-500"},RC={class:"rounded-lg border border-gray-200 bg-gray-50 px-4 py-3 dark:border-gray-700 dark:bg-gray-800/50"},NC={class:"flex items-center justify-between"},FC={class:"text-sm text-gray-700 dark:text-gray-300"},UC={key:0,class:"mt-1 flex items-center gap-3 text-xs"},OC={class:"text-gray-500"},HC={class:"text-green-600 dark:text-green-400"},VC={key:0,class:"text-amber-600 dark:text-amber-400"},zC={key:1,class:"mt-1 flex items-center gap-1 text-xs text-gray-400"},BC={class:"flex items-center gap-2"},WC={key:0,class:"mt-3 space-y-2"},jC={class:"flex items-center justify-between text-xs"},qC={class:"text-gray-500"},KC={class:"font-medium text-gray-700 dark:text-gray-300"},GC=30,XC=$e({__name:"SessionIndexSection",setup(e){const{t}=Re(),s=P(GC),n=P("standard"),a=G(()=>[{label:t("settings.ai.session.summaryBrief"),value:"brief"},{label:t("settings.ai.session.summaryStandard"),value:"standard"}]),i=P([]),c=P(!1),l=P(!1),m=P({current:0,total:0,currentName:""}),u=G(()=>{const g=i.value.length,p=i.value.filter(T=>T.hasIndex).length,k=g-p;return{total:g,generated:p,notGenerated:k}}),f=G(()=>m.value.total===0?0:Math.round(m.value.current/m.value.total*100));function h(){s.value<1&&(s.value=1),s.value>1440&&(s.value=1440),xn({session_gap_threshold:s.value*60})}function x(){const g=Rt();s.value=Math.round(g/60)}function S(g){n.value=g,xn({summary_strategy:g})}async function C(){c.value=!0;try{const g=await Et().getSessions(),p=[];for(const k of g)try{const T=await tt().getStats(k.id);p.push({id:k.id,name:k.name,hasIndex:T.hasIndex,sessionCount:T.sessionCount})}catch{p.push({id:k.id,name:k.name,hasIndex:!1,sessionCount:0})}i.value=p}catch(g){console.error("加载会话索引状态失败:",g)}finally{c.value=!1}}async function D(){const g=i.value.filter(k=>!k.hasIndex);if(g.length===0)return;l.value=!0,m.value={current:0,total:g.length,currentName:""};const p=s.value*60;for(let k=0;k<g.length;k++){const T=g[k];m.value={current:k,total:g.length,currentName:T.name};try{const E=await tt().generate(T.id,p),I=i.value.find(N=>N.id===T.id);I&&(I.hasIndex=!0,I.sessionCount=E)}catch(E){console.error(`生成会话 ${T.name} 索引失败:`,E)}}m.value={current:g.length,total:g.length,currentName:""},l.value=!1}async function M(){if(i.value.length===0)return;l.value=!0,m.value={current:0,total:i.value.length,currentName:""};const g=s.value*60;for(let p=0;p<i.value.length;p++){const k=i.value[p];m.value={current:p,total:i.value.length,currentName:k.name};try{const T=await tt().generate(k.id,g);k.hasIndex=!0,k.sessionCount=T}catch(T){console.error(`生成会话 ${k.name} 索引失败:`,T)}}m.value={current:i.value.length,total:i.value.length,currentName:""},l.value=!1}return Qe(()=>{x(),n.value=Aa(),C()}),(g,p)=>{const k=Ve,T=We,E=lt,I=no;return b(),A("div",kC,[r("div",wC,[r("div",SC,[r("div",null,[r("h3",CC,[v(k,{name:"i-heroicons-clock",class:"h-4 w-4 text-blue-500"}),J(" "+d(o(t)("settings.ai.session.title")),1)]),r("p",MC,d(o(t)("settings.ai.session.description")),1)]),v(T,{icon:"i-heroicons-arrow-path",variant:"ghost",size:"xs",loading:c.value,onClick:C},null,8,["loading"])]),r("div",AC,[r("div",null,[r("span",TC,d(o(t)("settings.ai.session.summaryStrategy")),1),r("p",$C,d(o(t)("settings.ai.session.summaryStrategyHelp")),1)]),v(Dt,{"model-value":n.value,items:a.value,size:"xs","onUpdate:modelValue":S},null,8,["model-value","items"])]),r("div",IC,[r("div",null,[r("span",PC,d(o(t)("settings.ai.session.defaultThreshold")),1),r("p",DC,d(o(t)("settings.ai.session.thresholdHelp")),1)]),r("div",LC,[v(E,{modelValue:s.value,"onUpdate:modelValue":p[0]||(p[0]=N=>s.value=N),modelModifiers:{number:!0},type:"number",min:1,max:1440,size:"xs",class:"w-20",onBlur:h},null,8,["modelValue"]),r("span",EC,d(o(t)("settings.ai.session.thresholdUnit")),1)])]),r("div",RC,[r("div",NC,[r("div",null,[r("span",FC,d(o(t)("settings.ai.session.batchTitle")),1),c.value?(b(),A("div",zC,[v(k,{name:"i-heroicons-arrow-path",class:"h-3 w-3 animate-spin"}),J(" "+d(o(t)("settings.ai.session.loadingStatus")),1)])):(b(),A("div",UC,[r("span",OC,d(o(t)("settings.ai.session.totalSessions",{count:u.value.total})),1),r("span",HC,d(o(t)("settings.ai.session.generatedCount",{count:u.value.generated})),1),u.value.notGenerated>0?(b(),A("span",VC,d(o(t)("settings.ai.session.notGeneratedCount",{count:u.value.notGenerated})),1)):ne("",!0)]))]),r("div",BC,[u.value.notGenerated>0?(b(),xe(T,{key:0,size:"xs",color:"primary",loading:l.value,disabled:c.value,onClick:D},{default:re(()=>[l.value?ne("",!0):(b(),xe(k,{key:0,name:"i-heroicons-sparkles",class:"mr-1 h-3 w-3"})),J(" "+d(o(t)("settings.ai.session.batchGenerate")),1)]),_:1},8,["loading","disabled"])):ne("",!0),v(T,{size:"xs",variant:"soft",loading:l.value,disabled:c.value||u.value.total===0,onClick:M},{default:re(()=>[l.value?ne("",!0):(b(),xe(k,{key:0,name:"i-heroicons-arrow-path",class:"mr-1 h-3 w-3"})),J(" "+d(o(t)("settings.ai.session.batchRegenerate")),1)]),_:1},8,["loading","disabled"])])]),l.value?(b(),A("div",WC,[r("div",jC,[r("span",qC,d(o(t)("settings.ai.session.generating"))+" "+d(m.value.currentName),1),r("span",KC,d(m.value.current)+"/"+d(m.value.total)+" ("+d(f.value)+"%) ",1)]),v(I,{value:f.value,size:"sm"},null,8,["value"])])):ne("",!0)])])])}}});function YC(e){const t=P(e.value[0]?.id||""),s=P(!1),n=P(null),a=P({});function i(u,f){a.value[u]=f}function c(u){const f=a.value[u];f&&n.value&&(s.value=!0,f.scrollIntoView({behavior:"smooth",block:"start"}),setTimeout(()=>{s.value=!1},500))}function l(){if(s.value||!n.value)return;const u=n.value,f=u.getBoundingClientRect(),h=50;if(u.scrollHeight-u.scrollTop-u.clientHeight<5){const S=e.value[e.value.length-1];S&&(t.value=S.id);return}for(const S of e.value){const C=a.value[S.id];if(C){const D=C.getBoundingClientRect();if(D.top<=f.top+h&&D.bottom>f.top+h){t.value=S.id;break}}}}Qe(()=>{n.value?.addEventListener("scroll",l)}),qt(()=>{n.value?.removeEventListener("scroll",l)});function m(u){const f=a.value[u];f&&n.value&&(s.value=!0,f.scrollIntoView({behavior:"smooth",block:"start"}),t.value=u,setTimeout(()=>{s.value=!1},500))}return{activeNav:t,scrollContainerRef:n,sectionRefs:a,setSectionRef:i,handleNavChange:c,scrollToId:m}}const QC={class:"flex h-full gap-6"},JC={class:"w-28 shrink-0"},ZC={class:"space-y-8"},eM=$e({__name:"AISettingsTab",emits:["config-changed"],setup(e,{expose:t,emit:s}){const{t:n}=Re(),a=s,i=G(()=>[{id:"model",label:n("settings.tabs.aiConfig")},{id:"defaultModel",label:n("settings.tabs.aiDefaultModel")},{id:"chat",label:n("settings.aiPrompt.chatSettings.title")},{id:"skill",label:n("settings.aiPrompt.skillSettings.title")},{id:"compression",label:n("settings.aiPrompt.compression.title")},{id:"preprocess",label:n("settings.tabs.aiPreprocess")},{id:"sessionIndex",label:n("settings.tabs.sessionManage")},{id:"export",label:n("settings.aiPrompt.exportSettings.title")}]),{activeNav:c,scrollContainerRef:l,setSectionRef:m,handleNavChange:u,scrollToId:f}=YC(i);function h(){a("config-changed")}function x(C){f(C)}t({scrollToSection:x});const S=P(null);return S.value,(C,D)=>(b(),A("div",QC,[r("div",JC,[v(Ta,{modelValue:o(c),"onUpdate:modelValue":D[0]||(D[0]=M=>Je(c)?c.value=M:null),items:i.value,orientation:"vertical",onChange:o(u)},null,8,["modelValue","items","onChange"])]),r("div",{ref_key:"scrollContainerRef",ref:l,class:"min-w-0 flex-1 overflow-y-auto"},[r("div",ZC,[r("div",{ref:M=>o(m)("model",M)},[v(s1,{ref_key:"aiModelConfigRef",ref:S,onConfigChanged:h},null,512)],512),r("div",{ref:M=>o(m)("defaultModel",M)},[v(C1,{onConfigChanged:h})],512),v(pS,{"set-section-ref":o(m),onConfigChanged:h},null,8,["set-section-ref"]),r("div",{ref:M=>o(m)("preprocess",M)},[v(dC)],512),r("div",{ref:M=>o(m)("sessionIndex",M)},[v(XC)],512),r("div",{ref:M=>o(m)("export",M)},[v(xC,{onConfigChanged:h})],512)])],512)]))}});function zo(e){return Xn()?(Yn(e),!0):!1}const Bs=new WeakMap,tM=(...e)=>{var t;const s=e[0],n=(t=Ss())==null?void 0:t.proxy;if(n==null&&!ga())throw new Error("injectLocal must be called in setup");return n&&Bs.has(n)&&s in Bs.get(n)?Bs.get(n)[s]:ma(...e)},$a=typeof window<"u"&&typeof document<"u";typeof WorkerGlobalScope<"u"&&globalThis instanceof WorkerGlobalScope;const sM=Object.prototype.toString,aM=e=>sM.call(e)==="[object Object]",ia=()=>{};function Bo(...e){if(e.length!==1)return Gn(...e);const t=e[0];return typeof t=="function"?eo(dr(()=>({get:t,set:ia}))):P(t)}function Wo(e,t){function s(...n){return new Promise((a,i)=>{Promise.resolve(e(()=>t.apply(this,n),{fn:t,thisArg:this,args:n})).then(a).catch(i)})}return s}const jo=e=>e();function nM(e,t={}){let s,n,a=ia;const i=m=>{clearTimeout(m),a(),a=ia};let c;return m=>{const u=rt(e),f=rt(t.maxWait);return s&&i(s),u<=0||f!==void 0&&f<=0?(n&&(i(n),n=void 0),Promise.resolve(m())):new Promise((h,x)=>{a=t.rejectOnCancel?x:h,c=m,f&&!n&&(n=setTimeout(()=>{s&&i(s),n=void 0,h(c())},f)),s=setTimeout(()=>{n&&i(n),n=void 0,h(m())},u)})}}function oM(e=jo,t={}){const{initialState:s="active"}=t,n=Bo(s==="active");function a(){n.value=!1}function i(){n.value=!0}const c=(...l)=>{n.value&&e(...l)};return{isActive:eo(n),pause:a,resume:i,eventFilter:c}}function rM(e){let t;function s(){return t||(t=e()),t}return s.reset=async()=>{const n=t;t=void 0,n&&await n},s}function Dn(e){return e.endsWith("rem")?Number.parseFloat(e)*16:Number.parseFloat(e)}function Ws(e){return Array.isArray(e)?e:[e]}function iM(e){return Ss()}function lM(e,t=200,s={}){return Wo(nM(t,s),e)}function cM(e,t,s={}){const{eventFilter:n=jo,...a}=s;return Ne(e,Wo(n,t),a)}function dM(e,t,s={}){const{eventFilter:n,initialState:a="active",...i}=s,{eventFilter:c,pause:l,resume:m,isActive:u}=oM(n,{initialState:a});return{stop:cM(e,t,{...i,eventFilter:c}),pause:l,resume:m,isActive:u}}function qo(e,t=!0,s){iM()?Qe(e,s):t?e():Xe(e)}function uM(e,t,s={}){const{immediate:n=!0,immediateCallback:a=!1}=s,i=mt(!1);let c;function l(){c&&(clearTimeout(c),c=void 0)}function m(){i.value=!1,l()}function u(...f){a&&e(),l(),i.value=!0,c=setTimeout(()=>{i.value=!1,c=void 0,e(...f)},rt(t))}return n&&(i.value=!0,$a&&u()),zo(m),{isPending:ur(i),start:u,stop:m}}function DE(e=!1,t={}){const{truthyValue:s=!0,falsyValue:n=!1}=t,a=Je(e),i=mt(e);function c(l){if(arguments.length)return i.value=l,i.value;{const m=rt(s);return i.value=i.value===m?rt(n):m,i.value}}return a?c:[i,c]}function mM(e,t,s){return Ne(e,t,{...s,immediate:!0})}const rs=$a?window:void 0,Ko=$a?window.navigator:void 0;function Go(e){var t;const s=rt(e);return(t=s?.$el)!=null?t:s}function is(...e){const t=[],s=()=>{t.forEach(l=>l()),t.length=0},n=(l,m,u,f)=>(l.addEventListener(m,u,f),()=>l.removeEventListener(m,u,f)),a=G(()=>{const l=Ws(rt(e[0])).filter(m=>m!=null);return l.every(m=>typeof m!="string")?l:void 0}),i=mM(()=>{var l,m;return[(m=(l=a.value)==null?void 0:l.map(u=>Go(u)))!=null?m:[rs].filter(u=>u!=null),Ws(rt(a.value?e[1]:e[0])),Ws(o(a.value?e[2]:e[1])),rt(a.value?e[3]:e[2])]},([l,m,u,f])=>{if(s(),!l?.length||!m?.length||!u?.length)return;const h=aM(f)?{...f}:f;t.push(...l.flatMap(x=>m.flatMap(S=>u.map(C=>n(x,S,C,h)))))},{flush:"post"}),c=()=>{i(),s()};return zo(s),c}function gM(){const e=mt(!1),t=Ss();return t&&Qe(()=>{e.value=!0},t),e}function Ia(e){const t=gM();return G(()=>(t.value,!!e()))}const pM=Symbol("vueuse-ssr-width");function fM(){const e=ga()?tM(pM,null):null;return typeof e=="number"?e:void 0}function hM(e,t={}){const{window:s=rs,ssrWidth:n=fM()}=t,a=Ia(()=>s&&"matchMedia"in s&&typeof s.matchMedia=="function"),i=mt(typeof n=="number"),c=mt(),l=mt(!1),m=u=>{l.value=u.matches};return mr(()=>{if(i.value){i.value=!a.value;const u=rt(e).split(",");l.value=u.some(f=>{const h=f.includes("not all"),x=f.match(/\(\s*min-width:\s*(-?\d+(?:\.\d*)?[a-z]+\s*)\)/),S=f.match(/\(\s*max-width:\s*(-?\d+(?:\.\d*)?[a-z]+\s*)\)/);let C=!!(x||S);return x&&C&&(C=n>=Dn(x[1])),S&&C&&(C=n<=Dn(S[1])),h?!C:C});return}a.value&&(c.value=s.matchMedia(rt(e)),l.value=c.value.matches)}),is(c,"change",m,{passive:!0}),G(()=>l.value)}function Ln(e,t={}){const{controls:s=!1,navigator:n=Ko}=t,a=Ia(()=>n&&"permissions"in n),i=mt(),c=typeof e=="string"?{name:e}:e,l=mt(),m=()=>{var f,h;l.value=(h=(f=i.value)==null?void 0:f.state)!=null?h:"prompt"};is(i,"change",m,{passive:!0});const u=rM(async()=>{if(a.value){if(!i.value)try{i.value=await n.permissions.query(c)}catch{i.value=void 0}finally{m()}if(s)return Ct(i.value)}});return u(),s?{state:l,isSupported:a,query:u}:l}function vM(e={}){const{navigator:t=Ko,read:s=!1,source:n,copiedDuring:a=1500,legacy:i=!1}=e,c=Ia(()=>t&&"clipboard"in t),l=Ln("clipboard-read"),m=Ln("clipboard-write"),u=G(()=>c.value||i),f=mt(""),h=mt(!1),x=uM(()=>h.value=!1,a,{immediate:!1});async function S(){let p=!(c.value&&g(l.value));if(!p)try{f.value=await t.clipboard.readText()}catch{p=!0}p&&(f.value=M())}u.value&&s&&is(["copy","cut"],S,{passive:!0});async function C(p=rt(n)){if(u.value&&p!=null){let k=!(c.value&&g(m.value));if(!k)try{await t.clipboard.writeText(p)}catch{k=!0}k&&D(p),f.value=p,h.value=!0,x.start()}}function D(p){const k=document.createElement("textarea");k.value=p??"",k.style.position="absolute",k.style.opacity="0",document.body.appendChild(k),k.select(),document.execCommand("copy"),k.remove()}function M(){var p,k,T;return(T=(k=(p=document?.getSelection)==null?void 0:p.call(document))==null?void 0:k.toString())!=null?T:""}function g(p){return p==="granted"||p==="prompt"}return{isSupported:u,text:f,copied:h,copy:C}}const ps=typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{},fs="__vueuse_ssr_handlers__",yM=bM();function bM(){return fs in ps||(ps[fs]=ps[fs]||{}),ps[fs]}function Xo(e,t){return yM[e]||t}function _M(e){return hM("(prefers-color-scheme: dark)",e)}function xM(e){return e==null?"any":e instanceof Set?"set":e instanceof Map?"map":e instanceof Date?"date":typeof e=="boolean"?"boolean":typeof e=="string"?"string":typeof e=="object"?"object":Number.isNaN(e)?"any":"number"}const kM={boolean:{read:e=>e==="true",write:e=>String(e)},object:{read:e=>JSON.parse(e),write:e=>JSON.stringify(e)},number:{read:e=>Number.parseFloat(e),write:e=>String(e)},any:{read:e=>e,write:e=>String(e)},string:{read:e=>e,write:e=>String(e)},map:{read:e=>new Map(JSON.parse(e)),write:e=>JSON.stringify(Array.from(e.entries()))},set:{read:e=>new Set(JSON.parse(e)),write:e=>JSON.stringify(Array.from(e))},date:{read:e=>new Date(e),write:e=>e.toISOString()}},En="vueuse-storage";function wM(e,t,s,n={}){var a;const{flush:i="pre",deep:c=!0,listenToStorageChanges:l=!0,writeDefaults:m=!0,mergeDefaults:u=!1,shallow:f,window:h=rs,eventFilter:x,onError:S=B=>{console.error(B)},initOnMounted:C}=n,D=(f?mt:P)(typeof t=="function"?t():t),M=G(()=>rt(e));if(!s)try{s=Xo("getDefaultStorage",()=>{var B;return(B=rs)==null?void 0:B.localStorage})()}catch(B){S(B)}if(!s)return D;const g=rt(t),p=xM(g),k=(a=n.serializer)!=null?a:kM[p],{pause:T,resume:E}=dM(D,B=>ie(B),{flush:i,deep:c,eventFilter:x});Ne(M,()=>Y(),{flush:i});let I=!1;const N=B=>{C&&!I||Y(B)},ee=B=>{C&&!I||H(B)};h&&l&&(s instanceof Storage?is(h,"storage",N,{passive:!0}):is(h,En,ee)),C?qo(()=>{I=!0,Y()}):Y();function V(B,j){if(h){const X={key:M.value,oldValue:B,newValue:j,storageArea:s};h.dispatchEvent(s instanceof Storage?new StorageEvent("storage",X):new CustomEvent(En,{detail:X}))}}function ie(B){try{const j=s.getItem(M.value);if(B==null)V(j,null),s.removeItem(M.value);else{const X=k.write(B);j!==X&&(s.setItem(M.value,X),V(j,X))}}catch(j){S(j)}}function Q(B){const j=B?B.newValue:s.getItem(M.value);if(j==null)return m&&g!=null&&s.setItem(M.value,k.write(g)),g;if(!B&&u){const X=k.read(j);return typeof u=="function"?u(X,g):p==="object"&&!Array.isArray(X)?{...g,...X}:X}else return typeof j!="string"?j:k.read(j)}function Y(B){if(!(B&&B.storageArea!==s)){if(B&&B.key==null){D.value=g;return}if(!(B&&B.key!==M.value)){T();try{const j=k.write(D.value);(B===void 0||B?.newValue!==j)&&(D.value=Q(B))}catch(j){S(j)}finally{B?Xe(E):E()}}}}function H(B){Y(B.detail)}return D}const SM="*,*::before,*::after{-webkit-transition:none!important;-moz-transition:none!important;-o-transition:none!important;-ms-transition:none!important;transition:none!important}";function Yo(e={}){const{selector:t="html",attribute:s="class",initialValue:n="auto",window:a=rs,storage:i,storageKey:c="vueuse-color-scheme",listenToStorageChanges:l=!0,storageRef:m,emitAuto:u,disableTransition:f=!0}=e,h={auto:"",light:"light",dark:"dark",...e.modes||{}},x=_M({window:a}),S=G(()=>x.value?"dark":"light"),C=m||(c==null?Bo(n):wM(c,n,i,{window:a,listenToStorageChanges:l})),D=G(()=>C.value==="auto"?S.value:C.value),M=Xo("updateHTMLAttrs",(T,E,I)=>{const N=typeof T=="string"?a?.document.querySelector(T):Go(T);if(!N)return;const ee=new Set,V=new Set;let ie=null;if(E==="class"){const Y=I.split(/\s/g);Object.values(h).flatMap(H=>(H||"").split(/\s/g)).filter(Boolean).forEach(H=>{Y.includes(H)?ee.add(H):V.add(H)})}else ie={key:E,value:I};if(ee.size===0&&V.size===0&&ie===null)return;let Q;f&&(Q=a.document.createElement("style"),Q.appendChild(document.createTextNode(SM)),a.document.head.appendChild(Q));for(const Y of ee)N.classList.add(Y);for(const Y of V)N.classList.remove(Y);ie&&N.setAttribute(ie.key,ie.value),f&&(a.getComputedStyle(Q).opacity,document.head.removeChild(Q))});function g(T){var E;M(t,s,(E=h[T])!=null?E:T)}function p(T){e.onChanged?e.onChanged(T,g):g(T)}Ne(D,p,{flush:"post",immediate:!0}),qo(()=>p(D.value));const k=G({get(){return u?C.value:D.value},set(T){C.value=T}});return Object.assign(k,{store:C,system:S,state:D})}function LE(e={}){const{valueDark:t="dark",valueLight:s=""}=e,n=Yo({...e,onChanged:(c,l)=>{var m;e.onChanged?(m=e.onChanged)==null||m.call(e,c==="dark",l,c):l(c)},modes:{dark:t,light:s}}),a=G(()=>n.system.value);return G({get(){return n.value==="dark"},set(c){const l=c?"dark":"light";a.value===l?n.value="auto":n.value=l}})}const CM={class:"mb-3 flex items-center gap-2 text-sm font-semibold text-gray-900 dark:text-white"},MM={class:"rounded-lg border border-gray-200 bg-gray-50 p-4 dark:border-gray-700 dark:bg-gray-800/50"},AM={class:"flex items-center justify-between"},TM={class:"flex-1 pr-4"},$M={class:"text-sm font-medium text-gray-900 dark:text-white"},IM={class:"text-xs text-gray-500 dark:text-gray-400"},PM={class:"w-64"},DM={key:0,class:"mt-4 space-y-3"},LM={class:"mb-1.5 block text-xs font-medium text-gray-700 dark:text-gray-300"},EM={key:0,class:"mt-1 text-xs text-red-500"},RM={key:1,class:"mt-1 text-xs text-gray-400"},NM={class:"flex items-center gap-3"},FM={key:0,class:"flex items-center gap-1.5"},UM=$e({__name:"NetworkSettingsSection",setup(e){const{t}=Re(),s=P("system"),n=P(""),a=P(""),i=P(!1),c=P(!1),l=P(null),m=G(()=>[{label:t("settings.basic.network.modeOff"),value:"off"},{label:t("settings.basic.network.modeSystem"),value:"system"},{label:t("settings.basic.network.modeManual"),value:"manual"}]);async function u(){try{const M=await window.networkApi.getProxyConfig();s.value=M.mode||"system",n.value=M.url||""}catch(M){console.error("获取代理配置失败:",M)}}function f(M){if(!M)return a.value="",!0;try{const g=new URL(M);return["http:","https:"].includes(g.protocol)?(a.value="",!0):(a.value=t("settings.basic.network.onlyHttpSupported"),!1)}catch{return a.value=t("settings.basic.network.invalidProxyUrl"),!1}}async function h(){if(l.value=null,s.value==="manual"&&!n.value.trim()){a.value=t("settings.basic.network.enterProxyFirst");return}if(!(s.value==="manual"&&!f(n.value))){i.value=!0;try{const M=await window.networkApi.saveProxyConfig({mode:s.value,url:n.value.trim()});M.success||(a.value=M.error||t("settings.basic.network.saveFailed"))}catch(M){console.error("保存代理配置失败:",M),a.value=t("settings.basic.network.saveFailed")}finally{i.value=!1}}}async function x(M){const g=M;s.value=g,l.value=null,a.value="",g!=="manual"&&await h()}function S(){l.value=null,n.value?f(n.value):a.value=""}async function C(){s.value==="manual"&&n.value.trim()&&await h()}async function D(){if(!n.value.trim()){a.value=t("settings.basic.network.enterProxyFirst");return}if(f(n.value)){c.value=!0,l.value=null;try{const M=await window.networkApi.testProxyConnection(n.value.trim());l.value={success:M.success,message:M.success?t("settings.basic.network.connectionSuccess"):M.error||t("settings.basic.network.connectionFailed")}}catch(M){l.value={success:!1,message:t("settings.basic.network.connectionFailed")+": "+(M instanceof Error?M.message:String(M))}}finally{c.value=!1}}}return Qe(()=>{u()}),(M,g)=>{const p=Ve,k=cs,T=lt,E=We;return b(),A("div",null,[r("h3",CM,[v(p,{name:"i-heroicons-globe-alt",class:"h-4 w-4 text-cyan-500"}),J(" "+d(o(t)("settings.basic.network.title")),1)]),r("div",MM,[r("div",AM,[r("div",TM,[r("p",$M,d(o(t)("settings.basic.network.proxyMode")),1),r("p",IM,d(o(t)("settings.basic.network.proxyModeDesc")),1)]),r("div",PM,[v(k,{"model-value":s.value,size:"sm",class:"gap-0",items:m.value,"onUpdate:modelValue":x},null,8,["model-value","items"])])]),s.value==="manual"?(b(),A("div",DM,[r("div",null,[r("label",LM,d(o(t)("settings.basic.network.proxyAddress")),1),v(T,{modelValue:n.value,"onUpdate:modelValue":g[0]||(g[0]=I=>n.value=I),placeholder:o(t)("settings.basic.network.proxyPlaceholder"),color:a.value?"error":"neutral",size:"sm",class:"w-full",onInput:S,onBlur:C},null,8,["modelValue","placeholder","color"]),a.value?(b(),A("p",EM,d(a.value),1)):(b(),A("p",RM,d(o(t)("settings.basic.network.proxyHelp")),1))]),r("div",NM,[v(E,{loading:c.value,disabled:c.value||!n.value.trim(),color:"neutral",variant:"soft",size:"sm",onClick:D},{default:re(()=>[v(p,{name:"i-heroicons-signal",class:"mr-1 h-4 w-4"}),J(" "+d(c.value?o(t)("settings.basic.network.testing"):o(t)("settings.basic.network.testConnection")),1)]),_:1},8,["loading","disabled"]),l.value?(b(),A("div",FM,[v(p,{name:l.value.success?"i-heroicons-check-circle":"i-heroicons-x-circle",class:we(["h-4 w-4",l.value.success?"text-green-500":"text-red-500"])},null,8,["name","class"]),r("span",{class:we(["text-xs",l.value.success?"text-green-600 dark:text-green-400":"text-red-600 dark:text-red-400"])},d(l.value.message),3)])):ne("",!0)])])):ne("",!0)])])}}}),OM={class:"space-y-6 pb-6"},HM={class:"mb-3 flex items-center gap-2 text-sm font-semibold text-gray-900 dark:text-white"},VM={class:"rounded-lg border border-gray-200 bg-gray-50 dark:border-gray-700 dark:bg-gray-800/50"},zM={class:"flex items-center justify-between p-4"},BM={class:"flex-1 pr-4"},WM={class:"text-sm font-medium text-gray-900 dark:text-white"},jM={class:"w-72"},qM={class:"flex items-center justify-between p-4"},KM={class:"flex-1 pr-4"},GM={class:"text-sm font-medium text-gray-900 dark:text-white"},XM={class:"text-xs text-gray-500 dark:text-gray-400"},YM={class:"mb-3 flex items-center gap-2 text-sm font-semibold text-gray-900 dark:text-white"},QM={class:"rounded-lg border border-gray-200 bg-gray-50 p-4 dark:border-gray-700 dark:bg-gray-800/50"},JM={class:"flex items-center justify-between"},ZM={class:"flex-1 pr-4"},eA={class:"text-sm font-medium text-gray-900 dark:text-white"},tA={class:"w-64"},sA={class:"mb-3 flex items-center gap-2 text-sm font-semibold text-gray-900 dark:text-white"},aA={class:"rounded-lg border border-gray-200 bg-gray-50 dark:border-gray-700 dark:bg-gray-800/50"},nA={class:"flex items-center justify-between p-4"},oA={class:"flex-1 pr-4"},rA={class:"text-sm font-medium text-gray-900 dark:text-white"},iA={class:"w-64"},lA={class:"flex items-center justify-between p-4"},cA={class:"flex-1 pr-4"},dA={class:"text-sm font-medium text-gray-900 dark:text-white"},uA={class:"text-xs text-gray-500 dark:text-gray-400"},mA={class:"w-64"},gA={class:"flex items-center justify-between p-4"},pA={class:"flex-1 pr-4"},fA={class:"text-sm font-medium text-gray-900 dark:text-white"},hA={class:"text-xs text-gray-500 dark:text-gray-400"},vA=$e({__name:"BasicSettingsTab",setup(e){const{t}=Re(),s=$t(),n=It(),{screenshotMobileAdapt:a,toolsPanelPosition:i}=Ge(s),{locale:c,defaultSessionTab:l}=Ge(n),m=P(!1),u=P(!0);Qe(async()=>{{u.value=!1;return}});async function f(g){}const h=Yo({emitAuto:!0,initialValue:"light"}),x=G(()=>[{label:t("settings.basic.appearance.auto"),value:"auto"},{label:t("settings.basic.appearance.light"),value:"light"},{label:t("settings.basic.appearance.dark"),value:"dark"}]),S=G(()=>Vo.map(g=>({label:g.nativeName,value:g.code}))),C=G({get:()=>c.value,set:g=>n.setLocale(g)}),D=G(()=>[{label:t("settings.basic.defaultTab.overview"),value:"overview"},{label:t("settings.basic.defaultTab.aiChat"),value:"ai-chat"}]),M=G(()=>[{label:t("settings.basic.toolsPanel.positionHeader"),value:"header"},{label:t("settings.basic.toolsPanel.positionSide"),value:"side"}]);return Ne(h,g=>{},{immediate:!0}),(g,p)=>{const k=Ve,T=Kt,E=cs;return b(),A("div",OM,[r("div",null,[r("h3",HM,[v(k,{name:"i-heroicons-cog-6-tooth",class:"h-4 w-4 text-gray-500"}),J(" "+d(o(t)("settings.basic.general.title")),1)]),r("div",VM,[r("div",zM,[r("div",BM,[r("p",WM,d(o(t)("settings.basic.language.description")),1)]),r("div",jM,[v(Dt,{modelValue:C.value,"onUpdate:modelValue":p[0]||(p[0]=I=>C.value=I),size:"sm",class:"gap-0",items:S.value},null,8,["modelValue","items"])])]),o(Wt)?(b(),A(Me,{key:0},[p[6]||(p[6]=r("div",{class:"border-t border-gray-200 dark:border-gray-700"},null,-1)),r("div",qM,[r("div",KM,[r("p",GM,d(o(t)("settings.basic.autoLaunch.openAtLogin")),1),r("p",XM,d(u.value?o(t)("settings.basic.autoLaunch.openAtLoginDesc"):o(t)("settings.basic.autoLaunch.devModeHint")),1)]),v(T,{modelValue:m.value,"onUpdate:modelValue":[p[1]||(p[1]=I=>m.value=I),f],disabled:!u.value},null,8,["modelValue","disabled"])])],64)):ne("",!0)])]),r("div",null,[r("h3",YM,[v(k,{name:"i-heroicons-paint-brush",class:"h-4 w-4 text-pink-500"}),J(" "+d(o(t)("settings.basic.appearance.title")),1)]),r("div",QM,[r("div",JM,[r("div",ZM,[r("p",eA,d(o(t)("settings.basic.appearance.themeMode")),1)]),r("div",tA,[v(E,{modelValue:o(h),"onUpdate:modelValue":p[2]||(p[2]=I=>Je(h)?h.value=I:null),size:"sm",class:"gap-0",items:x.value},null,8,["modelValue","items"])])])])]),r("div",null,[r("h3",sA,[v(k,{name:"i-heroicons-adjustments-horizontal",class:"h-4 w-4 text-purple-500"}),J(" "+d(o(t)("settings.basic.preferences.title")),1)]),r("div",aA,[r("div",nA,[r("div",oA,[r("p",rA,d(o(t)("settings.basic.defaultTab.description")),1)]),r("div",iA,[v(E,{modelValue:o(l),"onUpdate:modelValue":p[3]||(p[3]=I=>Je(l)?l.value=I:null),size:"sm",class:"gap-0",items:D.value},null,8,["modelValue","items"])])]),p[7]||(p[7]=r("div",{class:"border-t border-gray-200 dark:border-gray-700"},null,-1)),r("div",lA,[r("div",cA,[r("p",dA,d(o(t)("settings.basic.toolsPanel.positionLabel")),1),r("p",uA,d(o(t)("settings.basic.toolsPanel.positionDesc")),1)]),r("div",mA,[v(E,{modelValue:o(i),"onUpdate:modelValue":p[4]||(p[4]=I=>Je(i)?i.value=I:null),size:"sm",class:"gap-0",items:M.value},null,8,["modelValue","items"])])]),p[8]||(p[8]=r("div",{class:"border-t border-gray-200 dark:border-gray-700"},null,-1)),r("div",gA,[r("div",pA,[r("p",fA,d(o(t)("settings.basic.screenshot.mobileAdapt")),1),r("p",hA,d(o(t)("settings.basic.screenshot.mobileAdaptDesc")),1)]),v(T,{modelValue:o(a),"onUpdate:modelValue":p[5]||(p[5]=I=>Je(a)?a.value=I:null)},null,8,["modelValue"])])])]),o(Wt)?(b(),xe(UM,{key:0})):ne("",!0)])}}}),yA=2e3;function Pa(){const e=kr();function t(c){e.add({...c,duration:c.duration??yA})}function s(c,l={}){t({title:c,color:"success",...l})}function n(c,l={}){t({title:c,color:"error",...l})}function a(c,l={}){t({title:c,color:"primary",...l})}function i(c,l={}){t({title:c,color:"warning",...l})}return{add:t,success:s,fail:n,info:a,warn:i}}var ks={exports:{}},bA=ks.exports,Rn;function _A(){return Rn||(Rn=1,(function(e,t){(function(s,n){e.exports=n()})(bA,(function(){return function(s,n,a){s=s||{};var i=n.prototype,c={future:"in %s",past:"%s ago",s:"a few seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"};function l(u,f,h,x){return i.fromToBase(u,f,h,x)}a.en.relativeTime=c,i.fromToBase=function(u,f,h,x,S){for(var C,D,M,g=h.$locale().relativeTime||c,p=s.thresholds||[{l:"s",r:44,d:"second"},{l:"m",r:89},{l:"mm",r:44,d:"minute"},{l:"h",r:89},{l:"hh",r:21,d:"hour"},{l:"d",r:35},{l:"dd",r:25,d:"day"},{l:"M",r:45},{l:"MM",r:10,d:"month"},{l:"y",r:17},{l:"yy",d:"year"}],k=p.length,T=0;T<k;T+=1){var E=p[T];E.d&&(C=x?a(u).diff(h,E.d,!0):h.diff(u,E.d,!0));var I=(s.rounding||Math.round)(Math.abs(C));if(M=C>0,I<=E.r||!E.r){I<=1&&T>0&&(E=p[T-1]);var N=g[E.l];S&&(I=S(""+I)),D=typeof N=="string"?N.replace("%d",I):N(I,f,E.l,M);break}}if(f)return D;var ee=M?g.future:g.past;return typeof ee=="function"?ee(D):ee.replace("%s",D)},i.to=function(u,f){return l(u,f,this,!0)},i.from=function(u,f){return l(u,f,this)};var m=function(u){return u.$u?a.utc():a()};i.toNow=function(u){return this.to(m(this),u)},i.fromNow=function(u){return this.from(m(this),u)}}}))})(ks)),ks.exports}var xA=_A();const kA=Ho(xA),wA={class:"flex h-full flex-col"},SA={class:"mb-4"},CA={class:"mb-4 flex items-center justify-between"},MA={class:"flex items-center gap-4"},AA={class:"text-xs text-gray-400 dark:text-gray-500"},TA={key:0,class:"text-sm text-gray-500 dark:text-gray-400"},$A={key:1,class:"text-sm text-gray-500 dark:text-gray-400"},IA={class:"flex gap-2"},PA={key:0,class:"flex flex-1 items-center justify-center"},DA={class:"text-center text-gray-500 dark:text-gray-400"},LA={key:1,class:"flex flex-1 items-center justify-center"},EA={class:"text-center text-gray-500 dark:text-gray-400"},RA={key:2,class:"flex-1 overflow-y-auto rounded-lg border border-gray-200/50 dark:border-gray-700/50"},NA={class:"sticky top-0 z-1 flex items-center gap-3 border-b border-gray-200 bg-gray-50 px-3 py-2 text-xs font-medium text-gray-500 dark:border-gray-700 dark:bg-gray-800/80 dark:text-gray-400"},FA=["onClick"],UA={class:"flex shrink-0 flex-col leading-none"},OA=["onClick"],HA={class:"w-6"},VA={class:"w-8"},zA=["src","alt"],BA={class:"min-w-0 flex-1"},WA={class:"flex items-center gap-1.5"},jA=["title","onClick"],qA={class:"w-20 text-center"},KA={class:"w-24 text-right text-sm text-gray-600 dark:text-gray-300"},GA={class:"w-16 text-right text-sm text-gray-600 dark:text-gray-300"},XA={class:"w-16 text-right text-sm text-gray-600 dark:text-gray-300"},YA={class:"w-28 text-right text-xs text-gray-500 dark:text-gray-400"},QA={class:"p-4"},JA={class:"mb-4 flex items-center gap-3"},ZA={class:"flex h-10 w-10 items-center justify-center rounded-full bg-blue-100 dark:bg-blue-900/30"},eT={class:"text-lg font-semibold text-gray-900 dark:text-white"},tT={class:"mb-4 text-gray-600 dark:text-gray-400"},sT={class:"mb-4 max-h-40 overflow-y-auto rounded-lg border border-gray-200 dark:border-gray-700"},aT={class:"text-sm text-gray-700 dark:text-gray-300"},nT={class:"text-xs text-gray-400"},oT={class:"mb-4"},rT={key:0,class:"mb-4 rounded-lg border border-red-200 bg-red-50 px-3 py-2 dark:border-red-800/50 dark:bg-red-900/20"},iT={class:"flex items-start gap-2"},lT={class:"text-xs leading-5 text-red-700 dark:text-red-300"},cT={key:1,class:"mb-4 rounded-lg bg-blue-50 px-4 py-3 dark:bg-blue-900/20"},dT={class:"flex items-center gap-2"},uT={class:"text-sm text-blue-700 dark:text-blue-300"},mT={class:"flex justify-end gap-2"},gT={class:"p-4"},pT={class:"mb-4 flex items-center gap-3"},fT={class:"flex h-10 w-10 items-center justify-center rounded-full bg-red-100 dark:bg-red-900/30"},hT={class:"text-lg font-semibold text-gray-900 dark:text-white"},vT={class:"mb-6 text-gray-600 dark:text-gray-400"},yT={class:"flex justify-end gap-2"},bT=$e({__name:"BatchManageTab",setup(e){ot.extend(kA);const t=Pa(),{t:s,locale:n}=Re(),a=ut(),{sessions:i}=Ge(a),c=P(""),l=G(()=>{if(!c.value.trim())return i.value;const de=c.value.toLowerCase().trim();return i.value.filter(w=>w.name.toLowerCase().includes(de)||w.platform.toLowerCase().includes(de))}),m=[{key:"spacer-select",type:"spacer",class:"w-6"},{key:"spacer-avatar",type:"spacer",class:"w-8"},{key:"name",type:"sortable",field:"name",labelKey:"tools.batchManage.columns.name",class:"min-w-0 flex-1",align:"left"},{key:"platform",type:"sortable",field:"platform",labelKey:"tools.batchManage.columns.platform",class:"w-20",align:"center"},{key:"messages",type:"sortable",field:"messageCount",labelKey:"tools.batchManage.columns.messages",class:"w-24",align:"right"},{key:"summaries",type:"static",labelKey:"tools.batchManage.columns.summaries",class:"w-16",align:"right"},{key:"aiChats",type:"static",labelKey:"tools.batchManage.columns.aiChats",class:"w-16",align:"right"},{key:"importedAt",type:"sortable",field:"importedAt",labelKey:"tools.batchManage.columns.importedAt",class:"w-28",align:"right"}],u=P({field:null,direction:null});function f(de){return"asc"}function h(de){if(u.value.field===de){u.value.direction==="asc"?u.value.direction="desc":u.value.direction==="desc"?u.value={field:null,direction:null}:u.value.direction="asc";return}u.value={field:de,direction:f()}}function x(de){return u.value.field!==de?null:u.value.direction}function S(de,w){return x(de)===w?"text-primary-500 dark:text-primary-400":"text-gray-300 dark:text-gray-600"}function C(de){return de==="left"?"justify-start text-left":de==="center"?"justify-center text-center":"justify-end text-right"}function D(de){return`${de.class} ${C(de.align)}`}function M(de){return`${de.class} flex items-center gap-1 transition-colors hover:text-gray-700 dark:hover:text-gray-200 ${C(de.align)}`}const g=G(()=>{const de=[...l.value],{field:w,direction:R}=u.value;if(!w||!R)return de;const oe=R==="asc"?1:-1;return de.sort((te,q)=>w==="name"?te.name.localeCompare(q.name,n.value)*oe:w==="platform"?z(te.platform).localeCompare(z(q.platform),n.value)*oe:w==="messageCount"?(te.messageCount-q.messageCount)*oe:(te.importedAt-q.importedAt)*oe),de}),p=P(new Set),k=P(!1),T=P(!1),E=P(null),I=P(""),N=G(()=>i.value.filter(de=>p.value.has(de.id))),ee=G(()=>new Set(N.value.map(de=>de.type))),V=G(()=>p.value.size<2?!1:ee.value.size===1),ie=G(()=>g.value.length>0&&g.value.every(de=>p.value.has(de.id))),Q=G(()=>{const de=g.value.filter(w=>p.value.has(w.id)).length;return de>0&&de<g.value.length});function Y(){if(ie.value){const de=new Set(g.value.map(w=>w.id));p.value=new Set([...p.value].filter(w=>!de.has(w)))}else{const de=new Set(p.value);for(const w of g.value)de.add(w.id);p.value=de}}const H=P(null);Ne(g,()=>{H.value=null});function B(de){const w=new Set(p.value);w.has(de)?w.delete(de):w.add(de),p.value=w}function j(de,w,R){if(R.shiftKey&&H.value!==null){const oe=Math.min(H.value,de),te=Math.max(H.value,de),q=new Set(p.value);for(let ue=oe;ue<=te;ue++){const U=g.value[ue];U&&q.add(U.id)}p.value=q}else B(w);H.value=de}function X(de){!de.shiftKey||de.target?.closest('input, textarea, [contenteditable="true"]')||de.preventDefault()}function le(de){return p.value.has(de)}function F(de){return ot.unix(de).locale({"zh-CN":"zh-cn","zh-TW":"zh-tw","ja-JP":"ja"}[n.value]??"en").fromNow()}function _(de){return de.type==="private"}function y(de){return _(de)?de.memberAvatar||null:de.groupAvatar||null}function L(de){const w=de.name||"";return w?_(de)?w.length<=2?w:w.slice(-2):w.length<=2?w:w.slice(0,2):"?"}const $={qq:{label:"QQ",class:"bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-300"},weixin:{label:"微信",class:"bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-300"},discord:{label:"Discord",class:"bg-indigo-100 text-indigo-700 dark:bg-indigo-900/30 dark:text-indigo-300"},whatsapp:{label:"WhatsApp",class:"bg-emerald-100 text-emerald-700 dark:bg-emerald-900/30 dark:text-emerald-300"},instagram:{label:"Instagram",class:"bg-pink-100 text-pink-700 dark:bg-pink-900/30 dark:text-pink-300"},line:{label:"LINE",class:"bg-lime-100 text-lime-700 dark:bg-lime-900/30 dark:text-lime-300"},unknown:{label:"未知",class:"bg-gray-100 text-gray-700 dark:bg-gray-700 dark:text-gray-300"}};function z(de){return $[de]?.label||de}function ce(de){return $[de]?.class||$.unknown.class}function W(de,w){w.stopPropagation(),E.value=de.id,I.value=de.name}async function se(){if(!E.value||!I.value.trim()){E.value=null,I.value="";return}const de=I.value.trim(),w=i.value.find(R=>R.id===E.value);w&&w.name!==de&&await a.renameSession(E.value,de),E.value=null,I.value=""}function pe(){E.value=null,I.value=""}function me(){p.value.size!==0&&(k.value=!0)}const ae=P(!1),he=P(!1),ke=P(""),ve=P(!1);async function _e(){V.value&&(ve.value=!1,ae.value=!0)}async function be(){if(!V.value)return;he.value=!0,ke.value=s("tools.batchManage.mergeSteps.exporting");const de=Array.from(p.value);let w=[];try{const R=await window.chatApi.exportSessionsToTempFiles(de);if(!R.success)throw new Error(R.error||"导出失败");w=R.tempFiles,ke.value=s("tools.batchManage.mergeSteps.parsing");for(const K of w)await window.mergeApi.parseFileInfo(K);ke.value=s("tools.batchManage.mergeSteps.checking");const oe=await window.mergeApi.checkConflicts(w);oe.conflicts.length>0&&console.log(`[BatchDelete] 检测到 ${oe.conflicts.length} 个冲突,使用默认解决方案`),ke.value=s("tools.batchManage.mergeSteps.merging");const ue=`${i.value.find(K=>p.value.has(K.id))?.name||"聊天记录"}(${s("tools.batchManage.mergedSuffix")})`,U=await window.mergeApi.mergeFiles({filePaths:w,outputName:ue,outputFormat:"json",conflictResolutions:oe.conflicts.map(K=>({id:K.id,resolution:"keep1"})),andAnalyze:!0});if(!U.success)throw new Error(U.error||"合并失败");if(ve.value){ke.value=s("tools.batchManage.mergeSteps.cleaning");for(const K of de)await a.deleteSession(K)}await window.chatApi.cleanupTempExportFiles(w),await a.loadSessions(),p.value=new Set,ae.value=!1,t.success(s("tools.batchManage.mergeSuccess",{count:de.length}))}catch(R){console.error("[BatchDelete] 合并失败:",R),t.fail(s("tools.batchManage.mergeError",{error:String(R)})),w.length>0&&await window.chatApi.cleanupTempExportFiles(w)}finally{he.value=!1,ke.value=""}}async function Le(){if(p.value.size!==0){T.value=!0;try{const de=Array.from(p.value);for(const w of de)await a.deleteSession(w);p.value=new Set,k.value=!1}catch(de){console.error("Batch delete failed:",de)}finally{T.value=!1}}}function Ae(){k.value=!1}return Qe(()=>{a.loadSessions()}),(de,w)=>{const R=lt,oe=oo,te=We,q=ls,ue=Ve,U=ht;return b(),A("div",wA,[r("div",SA,[v(R,{modelValue:c.value,"onUpdate:modelValue":w[0]||(w[0]=K=>c.value=K),placeholder:o(s)("tools.batchManage.searchPlaceholder"),icon:"i-heroicons-magnifying-glass",size:"md",class:"w-80"},null,8,["modelValue","placeholder"])]),r("div",CA,[r("div",MA,[v(oe,{"model-value":ie.value,indeterminate:Q.value,label:o(s)("tools.batchManage.selectAll"),"onUpdate:modelValue":Y},null,8,["model-value","indeterminate","label"]),r("span",AA,d(o(s)("tools.batchManage.shiftClickHint")),1),p.value.size>0?(b(),A("span",TA,d(o(s)("tools.batchManage.selected",{count:p.value.size})),1)):ne("",!0),c.value.trim()&&l.value.length!==o(i).length?(b(),A("span",$A,d(o(s)("tools.batchManage.searchResult",{count:l.value.length,total:o(i).length})),1)):ne("",!0)]),r("div",IA,[v(q,{text:V.value?"":o(s)("tools.batchManage.mergeHint")},{default:re(()=>[v(te,{color:"primary",disabled:!V.value,icon:"i-heroicons-document-duplicate",onClick:_e},{default:re(()=>[J(d(o(s)("tools.batchManage.merge")),1)]),_:1},8,["disabled"])]),_:1},8,["text"]),v(te,{color:"primary",disabled:p.value.size===0,icon:"i-heroicons-trash",onClick:me},{default:re(()=>[J(d(o(s)("tools.batchManage.delete")),1)]),_:1},8,["disabled"])])]),o(i).length===0?(b(),A("div",PA,[r("div",DA,[v(ue,{name:"i-heroicons-inbox",class:"mb-2 h-12 w-12"}),r("p",null,d(o(s)("tools.batchManage.empty")),1)])])):l.value.length===0?(b(),A("div",LA,[r("div",EA,[v(ue,{name:"i-heroicons-magnifying-glass",class:"mb-2 h-12 w-12"}),r("p",null,d(o(s)("tools.batchManage.noSearchResult")),1)])])):(b(),A("div",RA,[r("div",NA,[(b(),A(Me,null,Be(m,K=>(b(),A(Me,{key:K.key},[K.type==="spacer"?(b(),A("div",{key:0,class:we(K.class)},null,2)):K.type==="static"?(b(),A("div",{key:1,class:we(D(K))},d(o(s)(K.labelKey)),3)):(b(),A("button",{key:2,class:we(M(K)),onClick:Ie=>h(K.field)},[r("span",null,d(o(s)(K.labelKey)),1),r("span",UA,[v(ue,{name:"i-heroicons-chevron-up",class:we(["h-2.5 w-2.5",S(K.field,"asc")])},null,8,["class"]),v(ue,{name:"i-heroicons-chevron-down",class:we(["-mt-0.5 h-2.5 w-2.5",S(K.field,"desc")])},null,8,["class"])])],10,FA))],64))),64))]),(b(!0),A(Me,null,Be(g.value,(K,Ie)=>(b(),A("div",{key:K.id,class:we(["flex cursor-pointer items-center gap-3 px-3 py-2 transition-colors hover:bg-gray-100 dark:hover:bg-gray-800",[le(K.id)?"bg-pink-50 dark:bg-pink-900/20":"",Ie!==g.value.length-1?"border-b border-gray-100 dark:border-gray-800":""]]),onMousedown:X,onClick:Te=>j(Ie,K.id,Te)},[r("div",HA,[v(oe,{"model-value":le(K.id),onClick:es(Te=>j(Ie,K.id,Te),["stop"])},null,8,["model-value","onClick"])]),r("div",VA,[y(K)?(b(),A("img",{key:0,src:y(K),alt:K.name,class:"h-8 w-8 shrink-0 rounded-full object-cover"},null,8,zA)):(b(),A("div",{key:1,class:we(["flex h-8 w-8 shrink-0 items-center justify-center rounded-full text-[10px] font-bold",_(K)?"bg-pink-500 text-white":"bg-primary-500 text-white"])},d(L(K)),3))]),r("div",BA,[r("div",WA,[v(ue,{name:_(K)?"i-heroicons-user":"i-heroicons-user-group",class:"h-3.5 w-3.5 shrink-0 text-gray-400"},null,8,["name"]),E.value===K.id?gr((b(),A("input",{key:0,"onUpdate:modelValue":w[1]||(w[1]=Te=>I.value=Te),type:"text",class:"w-full rounded border border-pink-300 bg-white px-2 py-0.5 text-sm font-medium text-gray-900 focus:border-pink-500 focus:outline-none focus:ring-1 focus:ring-pink-500 dark:border-pink-600 dark:bg-gray-800 dark:text-white",autofocus:"",onBlur:se,onKeydown:[Zt(se,["enter"]),Zt(pe,["escape"])],onClick:w[2]||(w[2]=es(()=>{},["stop"]))},null,544)),[[pr,I.value]]):(b(),A("p",{key:1,class:"cursor-text truncate rounded px-1 text-sm font-medium text-gray-900 hover:bg-gray-200 dark:text-white dark:hover:bg-gray-700",title:o(s)("tools.batchManage.clickToEdit"),onClick:Te=>W(K,Te)},d(K.name),9,jA))])]),r("div",qA,[r("span",{class:we(["inline-flex items-center rounded-full px-2 py-0.5 text-xs font-medium",ce(K.platform)])},d(z(K.platform)),3)]),r("div",KA,d(K.messageCount.toLocaleString()),1),r("div",GA,d(K.summaryCount||0),1),r("div",XA,d(K.aiConversationCount||0),1),r("div",YA,d(F(K.importedAt)),1)],42,OA))),128))])),v(U,{open:ae.value,"onUpdate:open":w[5]||(w[5]=K=>ae.value=K),ui:{content:"z-[101]",overlay:"z-[100]"}},{content:re(()=>[r("div",QA,[r("div",JA,[r("div",ZA,[v(ue,{name:"i-heroicons-document-duplicate",class:"h-5 w-5 text-blue-600 dark:text-blue-400"})]),r("h3",eT,d(o(s)("tools.batchManage.mergeConfirmTitle")),1)]),r("p",tT,d(o(s)("tools.batchManage.mergeConfirmMessage",{count:p.value.size})),1),r("div",sT,[(b(!0),A(Me,null,Be(N.value,K=>(b(),A("div",{key:K.id,class:"flex items-center gap-2 border-b border-gray-100 px-3 py-2 last:border-b-0 dark:border-gray-800"},[v(ue,{name:_(K)?"i-heroicons-user":"i-heroicons-user-group",class:"h-4 w-4 text-gray-400"},null,8,["name"]),r("span",aT,d(K.name),1),r("span",nT,d(K.messageCount.toLocaleString())+" 条",1)]))),128))]),r("div",oT,[v(oe,{modelValue:ve.value,"onUpdate:modelValue":w[3]||(w[3]=K=>ve.value=K),label:o(s)("tools.batchManage.deleteOriginalsLabel")},null,8,["modelValue","label"])]),ve.value?(b(),A("div",rT,[r("div",iT,[v(ue,{name:"i-heroicons-exclamation-triangle",class:"mt-0.5 h-4 w-4 shrink-0 text-red-600"}),r("p",lT,d(o(s)("tools.batchManage.mergeRiskWarning")),1)])])):ne("",!0),he.value?(b(),A("div",cT,[r("div",dT,[v(ue,{name:"i-heroicons-arrow-path",class:"h-4 w-4 animate-spin text-blue-600 dark:text-blue-400"}),r("span",uT,d(ke.value),1)])])):ne("",!0),r("div",mT,[v(te,{variant:"soft",disabled:he.value,onClick:w[4]||(w[4]=K=>ae.value=!1)},{default:re(()=>[J(d(o(s)("common.cancel")),1)]),_:1},8,["disabled"]),v(te,{color:"primary",loading:he.value,onClick:be},{default:re(()=>[J(d(he.value?ke.value:o(s)("tools.batchManage.merge")),1)]),_:1},8,["loading"])])])]),_:1},8,["open"]),v(U,{open:k.value,"onUpdate:open":w[6]||(w[6]=K=>k.value=K),ui:{content:"z-[101]",overlay:"z-[100]"}},{content:re(()=>[r("div",gT,[r("div",pT,[r("div",fT,[v(ue,{name:"i-heroicons-exclamation-triangle",class:"h-5 w-5 text-red-600 dark:text-red-400"})]),r("h3",hT,d(o(s)("tools.batchManage.confirmTitle")),1)]),r("p",vT,d(o(s)("tools.batchManage.confirmMessage",{count:p.value.size})),1),r("div",yT,[v(te,{variant:"soft",disabled:T.value,onClick:Ae},{default:re(()=>[J(d(o(s)("common.cancel")),1)]),_:1},8,["disabled"]),v(te,{color:"error",loading:T.value,onClick:Le},{default:re(()=>[J(d(T.value?o(s)("tools.batchManage.deleting"):o(s)("common.delete")),1)]),_:1},8,["loading"])])])]),_:1},8,["open"])])}}}),_T={class:"space-y-6"},xT={class:"flex items-center justify-between"},kT={class:"flex items-center gap-2 text-sm font-semibold text-gray-900 dark:text-white"},wT={class:"mt-1 text-xs text-gray-500 dark:text-gray-400"},ST={class:"flex items-center gap-2"},CT={class:"rounded-lg bg-gray-100 px-3 py-1.5 dark:bg-gray-800"},MT={class:"text-xs text-gray-500 dark:text-gray-400"},AT={class:"text-sm font-semibold text-gray-900 dark:text-white"},TT={key:0,class:"flex items-center justify-center py-8"},$T={class:"ml-2 text-sm text-gray-500"},IT={key:1,class:"space-y-2"},PT={class:"flex items-center justify-between"},DT={class:"flex items-center gap-3"},LT={class:"flex items-center gap-2"},ET={class:"text-sm font-medium text-gray-900 dark:text-white"},RT={class:"text-xs text-gray-500 dark:text-gray-400"},NT={class:"flex items-center"},FT={class:"flex items-center gap-2 text-xs text-gray-400"},UT={class:"w-14 text-right"},OT={class:"w-16 text-right"},HT={class:"ml-4 flex w-36 shrink-0 items-center justify-end gap-1"},VT={class:"rounded-lg border border-gray-200 bg-gray-50 p-4 dark:border-gray-700 dark:bg-gray-800/50"},zT={class:"flex items-start justify-between gap-3"},BT={class:"min-w-0 flex-1"},WT={class:"text-sm font-medium text-gray-900 dark:text-white"},jT={class:"mt-0.5 text-xs text-gray-500 dark:text-gray-400"},qT={class:"shrink-0"},KT={class:"mt-3 flex items-center gap-2"},GT={key:0,class:"mt-3 flex items-center justify-between rounded-lg border border-blue-200 bg-blue-50 p-3 dark:border-blue-800/50 dark:bg-blue-900/20"},XT={class:"text-xs font-medium text-blue-700 dark:text-blue-300"},YT={class:"mt-0.5 font-mono text-xs text-blue-600 dark:text-blue-400"},QT={class:"mt-2 text-xs text-amber-600 dark:text-amber-400"},JT={key:1,class:"mt-1 text-xs text-red-500"},ZT={class:"p-5"},e$={class:"mb-4 flex items-center gap-3"},t$={class:"flex h-10 w-10 items-center justify-center rounded-full bg-amber-100 dark:bg-amber-900/30"},s$={class:"text-lg font-semibold text-gray-900 dark:text-white"},a$={class:"space-y-3 text-sm text-gray-600 dark:text-gray-400"},n$={class:"rounded-lg bg-gray-100 p-3 dark:bg-gray-800"},o$={class:"text-xs text-gray-500 dark:text-gray-400"},r$={class:"mt-1 font-mono text-sm text-gray-900 dark:text-white"},i$={class:"rounded-lg border border-amber-200 bg-amber-50 p-3 dark:border-amber-800/50 dark:bg-amber-900/20"},l$={class:"text-xs text-amber-700 dark:text-amber-400"},c$={class:"mt-5 flex justify-end gap-2"},d$={class:"p-5"},u$={class:"mb-4 flex items-center gap-3"},m$={class:"flex h-10 w-10 items-center justify-center rounded-full bg-green-100 dark:bg-green-900/30"},g$={class:"text-lg font-semibold text-gray-900 dark:text-white"},p$={class:"text-sm text-gray-600 dark:text-gray-400"},f$={class:"mt-5 flex justify-end"},h$=$e({__name:"StorageManageSection",setup(e,{expose:t}){const{t:s}=Re(),n=P(null),a=P(!1),i=P(null),c=P(""),l=P(""),m=P(!1),u=P(!1),f=P(null),h=P(!1),x=P(null),S=P(!1),C=P(!1);function D(H){if(H===0)return"0 B";const B=["B","KB","MB","GB"],j=Math.floor(Math.log(H)/Math.log(1024));return`${(H/Math.pow(1024,j)).toFixed(j>0?1:0)} ${B[j]}`}const M=G(()=>n.value?D(n.value.totalSize):"0 B");async function g(){a.value=!0;try{n.value=await window.cacheApi.getInfo()}catch(H){console.error("获取缓存信息失败:",H)}finally{a.value=!1}}const p=G(()=>Wt);async function k(H){i.value=H;try{const B=await window.cacheApi.clear(H);B.success?await g():console.error("清理缓存失败:",B.error)}catch(B){console.error("清理缓存失败:",B)}finally{i.value=null}}async function T(H){try{await window.cacheApi.openDir(H)}catch(B){console.error("打开目录失败:",B)}}async function E(){await T("base")}async function I(){f.value=null;try{const H=await window.cacheApi.selectDataDir();if(!H.success||!H.path){H.error==="INSTALL_DIR_FORBIDDEN"&&(f.value=s("settings.storage.dataLocation.installDirForbidden"));return}x.value=H.path,S.value=!0,h.value=!0}catch(H){f.value=H instanceof Error?H.message:String(H)}}async function N(){f.value=null,x.value=null,S.value=!0,h.value=!0}function ee(){f.value=null,x.value=null,S.value=!0,h.value=!0}async function V(){h.value=!1,await Q(x.value,S.value)}function ie(){h.value=!1,x.value=null,S.value=!1}async function Q(H,B){u.value=!0;try{const j=await window.cacheApi.setDataDir(H,B);if(!j.success){f.value=j.error||"设置失败";return}C.value=!0}catch(j){f.value=j instanceof Error?j.message:String(j)}finally{u.value=!1}}async function Y(){await ft().relaunch()}return Qe(()=>{g()}),t({refresh:g}),(H,B)=>{const j=Ve,X=We,le=va,F=lt,_=ht;return b(),A("div",_T,[r("div",xT,[r("div",null,[r("h3",kT,[v(j,{name:"i-heroicons-folder-open",class:"h-4 w-4 text-amber-500"}),J(" "+d(o(s)("settings.storage.title")),1)]),r("p",wT,d(o(s)("settings.storage.description")),1)]),r("div",ST,[n.value?.systemDir?(b(),xe(X,{key:0,icon:"i-heroicons-folder-open",variant:"ghost",size:"sm",onClick:B[0]||(B[0]=y=>T("system"))},{default:re(()=>[J(d(o(s)("settings.storage.openRootDir")),1)]),_:1})):ne("",!0),r("div",CT,[r("span",MT,d(o(s)("settings.storage.totalUsage")),1),r("span",AT,d(M.value),1)]),v(X,{icon:"i-heroicons-arrow-path",variant:"ghost",size:"sm",loading:a.value,onClick:g},null,8,["loading"])])]),a.value&&!n.value?(b(),A("div",TT,[v(j,{name:"i-heroicons-arrow-path",class:"h-5 w-5 animate-spin text-gray-400"}),r("span",$T,d(o(s)("settings.storage.loading")),1)])):n.value?(b(),A("div",IT,[(b(!0),A(Me,null,Be(n.value.directories,y=>(b(),A("div",{key:y.id,class:"rounded-lg border border-gray-200 bg-gray-50 px-3 py-2.5 transition-colors hover:bg-gray-100 dark:border-gray-700 dark:bg-gray-800/50 dark:hover:bg-gray-800"},[r("div",PT,[r("div",DT,[r("div",{class:we(["flex h-8 w-8 shrink-0 items-center justify-center rounded-lg",{"bg-green-100 dark:bg-green-900/30":y.id==="databases","bg-violet-100 dark:bg-violet-900/30":y.id==="ai","bg-cyan-100 dark:bg-cyan-900/30":y.id==="cache","bg-amber-100 dark:bg-amber-900/30":y.id==="downloads","bg-blue-100 dark:bg-blue-900/30":y.id==="logs"}])},[v(j,{name:y.icon,class:we(["h-4 w-4",{"text-green-600 dark:text-green-400":y.id==="databases","text-violet-600 dark:text-violet-400":y.id==="ai","text-cyan-600 dark:text-cyan-400":y.id==="cache","text-amber-600 dark:text-amber-400":y.id==="downloads","text-blue-600 dark:text-blue-400":y.id==="logs"}])},null,8,["name","class"])],2),r("div",null,[r("div",LT,[r("h4",ET,d(o(s)(y.name)),1),y.exists?ne("",!0):(b(),xe(le,{key:0,variant:"soft",color:"gray",size:"xs"},{default:re(()=>[J(d(o(s)("settings.storage.notExist")),1)]),_:1}))]),r("p",RT,d(o(s)(y.description)),1)])]),r("div",NT,[r("div",FT,[r("span",UT,d(y.fileCount)+" "+d(o(s)("settings.storage.files")),1),r("span",OT,d(D(y.size)),1)]),r("div",HT,[y.canClear&&y.size>0?(b(),xe(X,{key:0,icon:"i-heroicons-trash",variant:"soft",color:"red",size:"xs",loading:i.value===y.id,disabled:i.value!==null,onClick:L=>k(y.id)},{default:re(()=>[J(d(o(s)("settings.storage.clear")),1)]),_:1},8,["loading","disabled","onClick"])):ne("",!0),v(X,{icon:"i-heroicons-folder-open",variant:"ghost",size:"xs",onClick:L=>T(y.id)},{default:re(()=>[J(d(o(s)("settings.storage.open")),1)]),_:1},8,["onClick"])])])])]))),128))])):ne("",!0),o(Wt)?(b(),A(Me,{key:2},[r("div",VT,[r("div",zT,[r("div",BT,[r("p",WT,d(o(s)("settings.storage.dataLocation.title")),1),r("p",jT,d(o(s)("settings.storage.dataLocation.description")),1)]),r("div",qT,[v(X,{icon:"i-heroicons-folder-open",variant:"ghost",size:"xs",onClick:E},{default:re(()=>[J(d(o(s)("settings.storage.dataLocation.open")),1)]),_:1})])]),r("div",KT,[v(F,{modelValue:c.value,"onUpdate:modelValue":B[1]||(B[1]=y=>c.value=y),readonly:"",size:"sm",class:"min-w-0 flex-1"},null,8,["modelValue"]),v(X,{size:"sm",variant:"soft",loading:u.value,disabled:u.value,onClick:I},{default:re(()=>[J(d(o(s)("settings.storage.dataLocation.choose")),1)]),_:1},8,["loading","disabled"]),m.value?(b(),xe(X,{key:0,size:"sm",variant:"ghost",disabled:u.value,onClick:N},{default:re(()=>[J(d(o(s)("settings.storage.dataLocation.reset")),1)]),_:1},8,["disabled"])):ne("",!0)]),p.value?(b(),A("div",GT,[r("div",null,[r("p",XT,d(o(s)("settings.storage.dataLocation.migrateHint")),1),r("p",YT,d(l.value),1)]),v(X,{size:"sm",color:"primary",variant:"soft",loading:u.value,disabled:u.value,onClick:ee},{default:re(()=>[J(d(o(s)("settings.storage.dataLocation.migrateAction")),1)]),_:1},8,["loading","disabled"])])):ne("",!0),r("p",QT,d(o(s)("settings.storage.dataLocation.restartTip")),1),f.value?(b(),A("p",JT,d(f.value),1)):ne("",!0)]),v(_,{open:h.value,"onUpdate:open":B[2]||(B[2]=y=>h.value=y),ui:{content:"z-[101]",overlay:"z-[100]"}},{content:re(()=>[r("div",ZT,[r("div",e$,[r("div",t$,[v(j,{name:"i-heroicons-exclamation-triangle",class:"h-5 w-5 text-amber-600 dark:text-amber-400"})]),r("h3",s$,d(o(s)("settings.storage.dataLocation.confirmTitle")),1)]),r("div",a$,[r("p",null,d(o(s)("settings.storage.dataLocation.confirmMessage")),1),r("div",n$,[r("p",o$,d(o(s)("settings.storage.dataLocation.newPath")),1),r("p",r$,d(x.value||o(s)("settings.storage.dataLocation.defaultPath")),1)]),r("div",i$,[r("p",l$,d(o(s)("settings.storage.dataLocation.confirmWarning")),1)])]),r("div",c$,[v(X,{variant:"ghost",onClick:ie},{default:re(()=>[J(d(o(s)("settings.storage.dataLocation.cancel")),1)]),_:1}),v(X,{color:"primary",onClick:V},{default:re(()=>[J(d(o(s)("settings.storage.dataLocation.confirm")),1)]),_:1})])])]),_:1},8,["open"]),v(_,{open:C.value,"onUpdate:open":B[3]||(B[3]=y=>C.value=y),dismissible:!1,ui:{content:"z-[101]",overlay:"z-[100]"}},{content:re(()=>[r("div",d$,[r("div",u$,[r("div",m$,[v(j,{name:"i-heroicons-check-circle",class:"h-5 w-5 text-green-600 dark:text-green-400"})]),r("h3",g$,d(o(s)("settings.storage.dataLocation.migrationSuccessTitle")),1)]),r("p",p$,d(o(s)("settings.storage.dataLocation.migrationSuccessMessage")),1),r("div",f$,[v(X,{color:"primary",onClick:Y},{default:re(()=>[J(d(o(s)("settings.storage.dataLocation.relaunchNow")),1)]),_:1})])])]),_:1},8,["open"])],64)):ne("",!0)])}}}),v$={class:"h-full overflow-y-auto"},y$=$e({__name:"StorageTab",setup(e,{expose:t}){const s=P(null);return t({refresh:()=>s.value?.refresh()}),(n,a)=>(b(),A("div",v$,[v(h$,{ref_key:"storageManageRef",ref:s},null,512)]))}}),b$={class:"space-y-6 pr-1"},_$={class:"mb-3 flex items-center gap-2 text-sm font-semibold text-gray-900 dark:text-white"},x$={class:"rounded-lg border border-gray-200 bg-gray-50 p-4 dark:border-gray-700 dark:bg-gray-800/50"},k$={class:"flex items-center justify-between"},w$={class:"flex items-center gap-3"},S$={class:"flex h-12 w-12 items-center justify-center rounded-xl bg-linear-to-br from-pink-500 to-pink-600"},C$={class:"text-xs text-gray-500 dark:text-gray-400"},M$={class:"mt-1 text-xs text-gray-400"},A$={class:"mb-3 flex items-center gap-2 text-sm font-semibold text-gray-900 dark:text-white"},T$={class:"rounded-lg border border-gray-200 bg-gray-50 p-4 dark:border-gray-700 dark:bg-gray-800/50"},$$={class:"flex items-center justify-between"},I$={class:"text-sm font-medium text-gray-900 dark:text-white"},P$={class:"text-xs text-gray-500 dark:text-gray-400"},D$={class:"mb-3 flex items-center gap-2 text-sm font-semibold text-gray-900 dark:text-white"},L$={class:"rounded-lg border border-gray-200 bg-gray-50 p-4 dark:border-gray-700 dark:bg-gray-800/50"},E$={class:"flex items-center justify-between"},R$={class:"text-sm font-medium text-gray-900 dark:text-white"},N$={class:"text-xs text-gray-500 dark:text-gray-400"},F$=$e({__name:"AboutTab",setup(e){const{t}=Re(),s=Pa(),n=It(),{debugMode:a}=Ge(n),i=P(t("common.loading")),c=P(!1),l=P(!0);async function m(){try{i.value=await ft().getVersion()}catch(x){console.error("Failed to get version:",x),i.value=t("settings.about.unknown")}}async function u(){try{l.value=await ft().getAnalyticsEnabled()}catch(x){console.error("Failed to get analytics status:",x)}}async function f(x){try{await ft().setAnalyticsEnabled(x),l.value=x}catch(S){console.error("Failed to set analytics:",S)}}async function h(){c.value=!0;try{const x=await ft().checkUpdate();if(!x)return;x.error?s.fail(t("settings.about.updateCheckFailed",{error:x.error})):x.hasUpdate?s.success(t("settings.about.newVersionAvailable",{version:x.latestVersion}),{duration:15e3,description:Wt?void 0:t("settings.about.webUpdateHint")}):s.success(t("settings.about.upToDate"))}catch(x){console.error("Update check failed:",x)}finally{c.value=!1}}return Qe(()=>{m(),u()}),(x,S)=>{const C=Ve,D=We,M=Kt;return b(),A("div",b$,[r("div",null,[r("h3",_$,[v(C,{name:"i-heroicons-information-circle",class:"h-4 w-4 text-blue-500"}),J(" "+d(o(t)("settings.about.title")),1)]),r("div",x$,[r("div",k$,[r("div",w$,[r("div",S$,[v(C,{name:"i-heroicons-chat-bubble-left-right",class:"h-6 w-6 text-white"})]),r("div",null,[S[0]||(S[0]=r("p",{class:"text-sm font-semibold text-gray-900 dark:text-white"},"ChatLab",-1)),r("p",C$,d(o(t)("settings.about.description")),1),r("p",M$,d(o(t)("settings.about.version"))+" "+d(i.value),1)])]),v(D,{disabled:c.value,color:"primary",variant:"soft",size:"sm",onClick:h},{default:re(()=>[v(C,{name:"i-heroicons-arrow-path",class:we(["mr-1 h-4 w-4",{"animate-spin":c.value}])},null,8,["class"]),J(" "+d(c.value?o(t)("settings.about.checking"):o(t)("settings.about.checkUpdate")),1)]),_:1},8,["disabled"])])])]),r("div",null,[r("h3",A$,[v(C,{name:"i-heroicons-shield-check",class:"h-4 w-4 text-purple-500"}),J(" "+d(o(t)("settings.about.privacy.title")),1)]),r("div",T$,[r("div",$$,[r("div",null,[r("p",I$,d(o(t)("settings.about.privacy.analytics")),1),r("p",P$,d(o(t)("settings.about.privacy.analyticsDesc")),1)]),v(M,{"model-value":l.value,"onUpdate:modelValue":f},null,8,["model-value"])])])]),r("div",null,[r("h3",D$,[v(C,{name:"i-heroicons-wrench-screwdriver",class:"h-4 w-4 text-orange-500"}),J(" "+d(o(t)("settings.about.developer.title")),1)]),r("div",L$,[r("div",E$,[r("div",null,[r("p",R$,d(o(t)("settings.about.developer.debugMode")),1),r("p",N$,d(o(t)("settings.about.developer.debugModeDesc")),1)]),v(M,{"model-value":o(a),"onUpdate:modelValue":o(n).setDebugMode},null,8,["model-value","onUpdate:modelValue"])])])])])}}});function U$(){const e=()=>()=>{};async function t(s,n){const a=await fetch(s,n);if(!a.ok){const i=await a.json().catch(()=>({}));throw new Error(i?.error||`HTTP ${a.status}`)}return a.json()}return{getConfig:()=>t("/_web/automation/config"),getStatus:async()=>({running:!0,port:null,startedAt:null,error:null}),setEnabled:async()=>({running:!0,port:null,startedAt:null,error:null}),setPort:async()=>({running:!0,port:null,startedAt:null,error:null}),regenerateToken:async()=>t("/_web/automation/config"),onStartupError:e,getDataSources:()=>t("/_web/automation/data-sources"),addDataSource:s=>t("/_web/automation/data-sources",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(s)}),updateDataSource:(s,n)=>t(`/_web/automation/data-sources/${s}`,{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify(n)}),deleteDataSource:async s=>(await t(`/_web/automation/data-sources/${s}`,{method:"DELETE"})).success,addImportSessions:(s,n)=>t(`/_web/automation/data-sources/${s}/sessions`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({sessions:n})}),removeImportSession:async(s,n,a)=>(await t(`/_web/automation/data-sources/${s}/sessions/${n}${a?"?deleteData=true":""}`,{method:"DELETE"})).success,triggerPull:(s,n)=>t(`/_web/automation/data-sources/${s}/pull`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({sessionId:n})}),triggerPullAll:s=>t(`/_web/automation/data-sources/${s}/pull-all`,{method:"POST"}),onPullResult:e,fetchRemoteSessions:async(s,n,a)=>{const i=new URLSearchParams({baseUrl:s});return n&&i.set("token",n),a?.keyword&&i.set("keyword",a.keyword),a?.limit&&i.set("limit",String(a.limit)),a?.cursor&&i.set("cursor",a.cursor),t(`/_web/automation/remote-sessions?${i}`)}}}function O$(){return U$()}const Qo=wt("apiServer",()=>{const e=O$(),t=P({enabled:!1,port:5200,token:"",createdAt:0}),s=P({running:!1,port:null,startedAt:null,error:null}),n=P(!1),a=P([]),i=P(new Set),c=P(new Map),l=G(()=>!0),m=G(()=>s.value.running),u=G(()=>!!s.value.error),f=G(()=>s.value.error?.startsWith("PORT_IN_USE")??!1),h=G(()=>!Wt);async function x(){try{t.value=await e.getConfig()}catch(F){console.error("[ApiServerStore] Failed to fetch config:",F)}}async function S(){try{s.value=await e.getStatus()}catch(F){console.error("[ApiServerStore] Failed to fetch status:",F)}}async function C(){await Promise.all([x(),S(),k()])}async function D(F){n.value=!0;try{s.value=await e.setEnabled(F),await x()}catch(_){console.error("[ApiServerStore] Failed to set enabled:",_)}finally{n.value=!1}}async function M(F){n.value=!0;try{s.value=await e.setPort(F),await x()}catch(_){console.error("[ApiServerStore] Failed to set port:",_)}finally{n.value=!1}}async function g(){try{t.value=await e.regenerateToken()}catch(F){console.error("[ApiServerStore] Failed to regenerate token:",F)}}function p(){return e.onStartupError(F=>{s.value.error=F.error,s.value.running=!1})}async function k(){try{a.value=await e.getDataSources()}catch(F){console.error("[ApiServerStore] Failed to fetch data sources:",F)}}async function T(F){try{const _=await e.addDataSource(F);return a.value.push(_),_}catch(_){return console.error("[ApiServerStore] Failed to add data source:",_),null}}async function E(F,_){try{const y=await e.updateDataSource(F,_);if(y){const L=a.value.findIndex($=>$.id===F);L!==-1&&(a.value[L]=y)}return y}catch(y){return console.error("[ApiServerStore] Failed to update data source:",y),null}}async function I(F){try{const _=await e.deleteDataSource(F);return _&&(a.value=a.value.filter(y=>y.id!==F)),_}catch(_){return console.error("[ApiServerStore] Failed to delete data source:",_),!1}}async function N(F,_){try{const y=await e.addImportSessions(F,_);if(await k(),y.length>0){for(const L of y)i.value.add(L.id);i.value=new Set(i.value),ee(F,y.map(L=>L.id))}return y}catch(y){return console.error("[ApiServerStore] Failed to add import sessions:",y),[]}}function ee(F,_,y=24,L=5e3){let $=0;const z=setInterval(async()=>{$++,await Promise.all([k(),V()]);const ce=a.value.find(se=>se.id===F);if(_.filter(se=>{const pe=ce?.sessions.find(me=>me.id===se);return pe&&pe.lastStatus==="idle"}).length===0||$>=y){for(const se of _)i.value.delete(se),c.value.delete(se);i.value=new Set(i.value),c.value=new Map(c.value),clearInterval(z)}},L)}async function V(){if(h.value)try{const F=await fetch("/_web/automation/sync-progress").then(y=>y.json()),_=new Map;for(const y of F)y.done||_.set(y.sessionId,{current:y.current,pages:y.pages});c.value=_}catch{}}async function ie(F,_,y){try{const L=await e.removeImportSession(F,_,y);return L&&(await k(),y&&ut().loadSessions()),L}catch(L){return console.error("[ApiServerStore] Failed to remove import session:",L),!1}}async function Q(F,_){const y=_||F;i.value.add(y),i.value=new Set(i.value);const L=H();try{const $=await e.triggerPull(F,_);return await k(),await ut().loadSessions(),j(F,_),$}catch($){return console.error("[ApiServerStore] Failed to trigger pull:",$),{success:!1,error:String($)}}finally{clearInterval(L),i.value.delete(y),i.value=new Set(i.value),c.value.delete(y),c.value=new Map(c.value)}}async function Y(F){const _=a.value.find($=>$.id===F),y=[F,..._?.sessions.map($=>$.id)??[]];for(const $ of y)i.value.add($);i.value=new Set(i.value);const L=H();try{const $=await e.triggerPullAll(F);return await k(),await ut().loadSessions(),j(F),$}catch($){return console.error("[ApiServerStore] Failed to trigger pull all:",$),{success:!1,error:String($)}}finally{clearInterval(L);for(const $ of y)i.value.delete($),c.value.delete($);i.value=new Set(i.value),c.value=new Map(c.value)}}function H(){return setInterval(V,3e3)}function B(){return e.onPullResult(async()=>{await k(),await ut().loadSessions(),X()})}function j(F,_){const y=a.value.find(ce=>ce.id===F);if(!y)return;const L=_?y.sessions.filter(ce=>ce.id===_&&ce.targetSessionId):y.sessions.filter(ce=>ce.targetSessionId),$=tt(),z=Rt();for(const ce of L)$.generateIncremental(ce.targetSessionId,z).catch(()=>{})}function X(){const F=tt(),_=Rt();for(const y of a.value)for(const L of y.sessions)L.targetSessionId&&F.generateIncremental(L.targetSessionId,_).catch(()=>{})}async function le(F,_,y){return e.fetchRemoteSessions(F,_,y)}return{config:t,status:s,loading:n,dataSources:a,pullingIds:i,syncProgress:c,available:l,isRunning:m,hasError:u,isPortInUse:f,isWebMode:h,fetchConfig:x,fetchStatus:S,refresh:C,setEnabled:D,setPort:M,regenerateToken:g,listenStartupError:p,fetchDataSources:k,addDataSource:T,updateDataSource:E,deleteDataSource:I,addImportSessions:N,removeImportSession:ie,triggerPull:Q,triggerPullAll:Y,listenPullResult:B,fetchRemoteSessions:le}}),Jo={"en-US":"en","zh-CN":"cn","zh-TW":"tw","ja-JP":"ja"},Zo="/_proxy/chatlab.fun";function EE(e){return Jo[e]??""}function RE(e){const t=Jo[e];return t?`?lang=${t}`:""}const Nn=Zo,H$={"zh-CN":"cn","zh-TW":"cn","en-US":"en","ja-JP":"ja"},er=wt("assistant",()=>{const e=P([]),t=P(null),s=P(!1),n=P([]),a=P([]),i=P([]),c=P(!1),l=P(null),m=P("group"),u=P("zh-CN"),f=G(()=>t.value?e.value.find(F=>F.id===t.value)??null:null),h=G(()=>e.value.filter(F=>{const _=!F.applicableChatTypes?.length||F.applicableChatTypes.includes(m.value),y=!F.supportedLocales?.length||F.supportedLocales.some(L=>u.value.startsWith(L));return _&&y})),x=4,S=G(()=>h.value.slice(0,x)),C=G(()=>h.value.slice(x)),D=G(()=>h.value.length>x),M=G(()=>{const F=new Set(e.value.map(_=>_.id));return i.value.map(_=>({..._,imported:F.has(_.id)}))});function g(F,_){m.value=F,u.value=_}async function p(){try{e.value=await window.assistantApi.getAll(),s.value=!0}catch(F){console.error("[AssistantStore] Failed to load assistants:",F)}}async function k(){try{n.value=await window.assistantApi.getBuiltinCatalog()}catch(F){console.error("[AssistantStore] Failed to load builtin catalog:",F)}}async function T(){try{a.value=await window.assistantApi.getBuiltinToolCatalog()}catch(F){console.error("[AssistantStore] Failed to load builtin tool catalog:",F)}}async function E(F){const _=H$[F||u.value]??"en",y=`${Nn}/${_}/assistant.json`;c.value=!0,l.value=null;try{const L=await ft().fetchRemoteConfig(y);if(!L.success||!L.data){l.value=L.error||"Failed to fetch cloud catalog",i.value=[];return}const $=L.data;if(!Array.isArray($)){l.value="Invalid catalog format",i.value=[];return}i.value=$.filter(z=>z.id&&z.name&&z.path)}catch(L){l.value=String(L),i.value=[]}finally{c.value=!1}}async function I(F){const _=`${Nn}${F.path}`;try{const y=await ft().fetchRemoteConfig(_);if(!y.success||typeof y.data!="string")return{success:!1,error:y.error||"Failed to fetch assistant content"};const L=await window.assistantApi.importFromMd(y.data);return L.success&&await p(),L}catch(y){return{success:!1,error:String(y)}}}function N(F){return e.value.some(_=>_.id===F)}function ee(F){t.value=F}function V(){t.value=null}async function ie(F){try{return await window.assistantApi.getConfig(F)}catch(_){return console.error("[AssistantStore] Failed to get config:",_),null}}async function Q(F,_){try{const y=await window.assistantApi.update(F,_);return y.success&&await p(),y}catch(y){return{success:!1,error:String(y)}}}async function Y(F){try{const _=await window.assistantApi.reset(F);return _.success&&await p(),_}catch(_){return{success:!1,error:String(_)}}}async function H(F){try{const _=await window.assistantApi.importAssistant(F);return _.success&&(await p(),await k()),_}catch(_){return{success:!1,error:String(_)}}}async function B(F){try{const _=await window.assistantApi.reimportAssistant(F);return _.success&&(await p(),await k()),_}catch(_){return{success:!1,error:String(_)}}}async function j(F){try{const _=await window.assistantApi.create(F);return _.success&&await p(),_}catch(_){return{success:!1,error:String(_)}}}async function X(F){try{const _=await window.assistantApi.getConfig(F);if(!_)return{success:!1,error:"Assistant not found"};const{id:y,builtinId:L,...$}=_,z=await window.assistantApi.create({...$,name:`${_.name}${Ds.global.t("ai.assistant.duplicateSuffix")}`});return z.success&&await p(),z}catch(_){return{success:!1,error:String(_)}}}async function le(F){try{const _=await window.assistantApi.delete(F);return _.success&&await p(),_}catch(_){return{success:!1,error:String(_)}}}return{assistants:e,selectedAssistantId:t,selectedAssistant:f,isLoaded:s,builtinCatalog:n,builtinToolCatalog:a,cloudCatalog:i,cloudLoading:c,cloudError:l,cloudCatalogWithStatus:M,currentChatType:m,currentLocale:u,filteredAssistants:h,defaultAssistants:S,moreAssistants:C,hasMoreAssistants:D,loadAssistants:p,loadBuiltinCatalog:k,loadBuiltinToolCatalog:T,fetchCloudCatalog:E,importFromCloud:I,isCloudItemImported:N,selectAssistant:ee,clearSelection:V,setFilterContext:g,getAssistantConfig:ie,updateAssistant:Q,createAssistant:j,duplicateAssistant:X,resetAssistant:Y,importAssistant:H,reimportAssistant:B,deleteAssistant:le}}),Fn=Zo,V$={"zh-CN":"cn","zh-TW":"cn","en-US":"en","ja-JP":"ja"},z$=wt("skill",()=>{const e=P([]),t=P(null),s=P(!1),n=P([]),a=P([]),i=P(!1),c=P(null),l=P("group"),m=P("zh-CN"),u=G(()=>t.value?e.value.find(Q=>Q.id===t.value)??null:null),f=G(()=>e.value.filter(Q=>Q.chatScope==="all"||Q.chatScope===l.value)),h=G(()=>er().selectedAssistant?f.value.filter(H=>(H.tools.length,!0)):f.value),x=G(()=>{const Q={};for(const Y of h.value){const H=Y.tags[0]||"other";Q[H]||(Q[H]=[]),Q[H].push(Y)}return Q}),S=G(()=>{const Q=new Set(e.value.map(Y=>Y.id));return a.value.map(Y=>({...Y,imported:Q.has(Y.id)}))});function C(Q,Y){l.value=Q,Y&&(m.value=Y)}async function D(){try{e.value=await window.skillApi.getAll(),s.value=!0}catch(Q){console.error("[SkillStore] Failed to load skills:",Q)}}async function M(){try{n.value=await window.skillApi.getBuiltinCatalog()}catch(Q){console.error("[SkillStore] Failed to load builtin catalog:",Q)}}async function g(){const Q=V$[m.value]??"en",Y=`${Fn}/${Q}/skill.json`;i.value=!0,c.value=null;try{const H=await ft().fetchRemoteConfig(Y);if(!H.success||!H.data){c.value=H.error||"Failed to fetch cloud catalog",a.value=[];return}const B=H.data;if(!Array.isArray(B)){c.value="Invalid catalog format",a.value=[];return}a.value=B.filter(j=>j.id&&j.name&&j.path)}catch(H){c.value=String(H),a.value=[]}finally{i.value=!1}}async function p(Q){const Y=`${Fn}${Q.path}`;try{const H=await ft().fetchRemoteConfig(Y);if(!H.success||typeof H.data!="string")return{success:!1,error:H.error||"Failed to fetch skill content"};const B=await window.skillApi.importFromMd(H.data);return B.success&&await D(),B}catch(H){return{success:!1,error:String(H)}}}function k(Q){return e.value.some(Y=>Y.id===Q)}function T(Q){t.value=Q}async function E(Q){try{return await window.skillApi.getConfig(Q)}catch(Y){return console.error("[SkillStore] Failed to get skill config:",Y),null}}async function I(Q,Y){try{const H=await window.skillApi.update(Q,Y);return H.success&&await D(),H}catch(H){return{success:!1,error:String(H)}}}async function N(Q){try{const Y=await window.skillApi.create(Q);return Y.success&&await D(),Y}catch(Y){return{success:!1,error:String(Y)}}}async function ee(Q){try{const Y=await window.skillApi.delete(Q);return Y.success&&(t.value===Q&&(t.value=null),await D()),Y}catch(Y){return{success:!1,error:String(Y)}}}async function V(Q){try{const Y=await window.skillApi.importSkill(Q);return Y.success&&(await D(),await M()),Y}catch(Y){return{success:!1,error:String(Y)}}}async function ie(Q){try{const Y=await window.skillApi.reimportSkill(Q);return Y.success&&(await D(),await M()),Y}catch(Y){return{success:!1,error:String(Y)}}}return{skills:e,activeSkillId:t,builtinCatalog:n,isLoaded:s,currentChatType:l,currentLocale:m,activeSkill:u,scopedSkills:f,compatibleSkills:h,groupedSkills:x,cloudCatalog:a,cloudLoading:i,cloudError:c,cloudCatalogWithStatus:S,setFilterContext:C,loadSkills:D,loadBuiltinCatalog:M,fetchCloudCatalog:g,importFromCloud:p,isCloudItemImported:k,activateSkill:T,getSkillConfig:E,updateSkill:I,createSkill:N,deleteSkill:ee,importSkill:V,reimportSkill:ie}}),gt="__draft__";function Un(e){return e.startsWith("en")?"general_en":e.startsWith("ja")?"general_ja":"general_cn"}function B$(e){return e?`${e.startTs}_${e.endTs}`:"all"}function W$(e){return`${e.sessionId}:${e.chatType}:${B$(e.timeFilter)}`}function la(){return{promptTokens:0,completionTokens:0,totalTokens:0}}function ca(e=null){return{messages:[],sourceMessages:[],currentKeywords:[],assistantId:e,loaded:!1}}function j$(e){const t=ca(null);return{sessionId:e.sessionId,sessionName:e.sessionName,chatType:e.chatType,locale:e.locale,timeFilter:e.timeFilter,selectedAssistantId:null,messages:t.messages,sourceMessages:t.sourceMessages,currentKeywords:t.currentKeywords,isLoadingSource:!1,isAIThinking:!1,currentConversationId:null,currentToolStatus:null,toolsUsedInCurrentRound:[],sessionTokenUsage:la(),agentStatus:null,ownerInfo:void 0,ownerInfoInitialized:!1,isAborted:!1,currentRequestId:"",currentAgentRequestId:"",conversationBuffers:{[gt]:t}}}function js(e){return e.currentConversationId??gt}const q$=wt("aiChatRuntime",()=>{const e=P({}),t=P(null),s=Ls(),n=ut(),a=It(),i=er(),c=z$(),{aiGlobalSettings:l}=Ge(s);let m=!1;function u(_){return`${_}_${Date.now()}_${Math.random().toString(36).slice(2,8)}`}function f(_){const y=W$(_),L=e.value[y];if(L)return L.sessionName=_.sessionName,L.chatType=_.chatType,L.locale=_.locale,L.timeFilter=_.timeFilter,{chatKey:y,state:L};const $=j$(_);e.value[y]=$;const z=e.value[y];return g(y),{chatKey:y,state:z}}function h(_){return e.value[_]??null}function x(){return t.value?h(t.value.chatKey):null}function S(_,y,L=null){return _.conversationBuffers[y]||(_.conversationBuffers[y]=ca(L)),_.conversationBuffers[y]}function C(_,y){const L=_.currentConversationId??gt,$=_.conversationBuffers[L];$&&($.sessionTokenUsage={..._.sessionTokenUsage});const z=S(_,y);_.currentConversationId=y===gt?null:y,_.messages=z.messages,_.sourceMessages=z.sourceMessages,_.currentKeywords=z.currentKeywords,_.selectedAssistantId=z.assistantId,_.sessionTokenUsage=z.sessionTokenUsage?{...z.sessionTokenUsage}:la(),_.agentStatus=null}function D(_,y,L){const $=S(_,y);return _.conversationBuffers[L]=$,y!==L&&delete _.conversationBuffers[y],_.currentConversationId===null&&y===gt&&(_.currentConversationId=L),$}function M(_){const y=h(_);y&&(y.selectedAssistantId?i.selectAssistant(y.selectedAssistantId):i.clearSelection())}async function g(_){const y=h(_);if(!y)return;const $=n.sessions.find(z=>z.id===y.sessionId)?.ownerId;if(!$){y.ownerInfo=void 0,y.ownerInfoInitialized=!0;return}if(!(y.ownerInfoInitialized&&y.ownerInfo?.platformId===$))try{const ce=(await Et().getMembers(y.sessionId)).find(W=>W.platformId===$);y.ownerInfo=ce?{platformId:$,displayName:ce.groupNickname||ce.accountName||$}:{platformId:$,displayName:$},y.ownerInfoInitialized=!0}catch(z){console.error("[AI] 获取 Owner 信息失败:",z),y.ownerInfo=void 0,y.ownerInfoInitialized=!0}}function p(_,y,L,$=null){const z=h(_);z&&(t.value={requestId:L,chatKey:_,sessionId:z.sessionId,sessionName:z.sessionName,chatType:z.chatType,conversationId:$,questionPreview:y.trim().slice(0,80),startedAt:Date.now()})}function k(_,y){t.value&&t.value.chatKey===_&&(y&&t.value.requestId!==y||(t.value=null))}function T(_,y){t.value&&t.value.chatKey===_&&(t.value.conversationId=y)}function E(_){return{phase:"preparing",round:0,toolsUsed:_.toolsUsedInCurrentRound.length,contextTokens:0,totalUsage:{..._.sessionTokenUsage},updatedAt:Date.now()}}function I(_,y,L){const $=_.agentStatus?{..._.agentStatus}:E(_);_.agentStatus={...$,...L,phase:y,updatedAt:Date.now()}}function N(_,y){const L=h(_);if(!L||L.isAIThinking)return!1;const $=S(L,js(L),y);return $.assistantId=y,L.selectedAssistantId=y,i.selectAssistant(y),!0}async function ee(_,y){const L=h(_);if(!L)return!1;try{const $=await Ht().getConversation(y),z=S(L,y,$?.assistantId??null);if(!z.loaded){const[ce,W]=await Promise.all([Ht().getMessages(y),Ht().getConversationTokenUsage(y)]);z.messages.splice(0,z.messages.length,...ce.map(se=>({id:se.id,role:se.role,content:se.content,timestamp:se.timestamp*1e3,contentBlocks:se.contentBlocks}))),z.sourceMessages.splice(0,z.sourceMessages.length),z.currentKeywords.splice(0,z.currentKeywords.length),z.sessionTokenUsage=W,z.loaded=!0}return z.assistantId=$?.assistantId??z.assistantId??null,C(L,y),M(_),!0}catch($){return console.error("[AI] 加载对话历史失败:",$),!1}}function V(_,y){const L=h(_);if(!L)return!1;const $=y??gt;return L.conversationBuffers[$]?(C(L,$),M(_),!0):!1}function ie(){return t.value?(m=!0,V(t.value.chatKey,t.value.conversationId)):!1}async function Q(_){if(m){m=!1;return}const y=h(_);if(!(!y||y.isAIThinking)){if(i.isLoaded||await i.loadAssistants(),!y.selectedAssistantId){const L=Un(y.locale);N(_,L)}Y(_)}}function Y(_,y){const L=h(_);if(!L||L.isAIThinking)return!1;const $=ca(L.selectedAssistantId);return L.conversationBuffers[gt]=$,C(L,gt),L.currentToolStatus=null,L.toolsUsedInCurrentRound=[],L.isLoadingSource=!1,L.sessionTokenUsage=la(),L.agentStatus=null,L.isAborted=!1,L.currentRequestId="",L.currentAgentRequestId="",y&&$.messages.push({id:u("welcome"),role:"assistant",content:y,timestamp:Date.now()}),!0}async function H(){}async function B(){}async function j(_,y,L){const $=h(_);if(!$)return{success:!1,reason:"error"};if(!y.trim())return{success:!1,reason:"empty"};if($.isAIThinking||t.value)return{success:!1,reason:"busy",activeTask:t.value};const z=u("req"),ce=js($);let W=ce===gt?null:ce;const se=S($,ce,$.selectedAssistantId);let pe,me;se.assistantId=$.selectedAssistantId,se.loaded=!0,p(_,y,z,W),M(_),g(_);const ae=c.activeSkillId,he=c.activeSkill?.name,ke=l.value.enableAutoSkill??!0,ve=(L?.mentionedMembers??[]).map(_e=>({memberId:_e.memberId,platformId:_e.platformId,displayName:_e.displayName,aliases:[..._e.aliases],mentionText:_e.mentionText}));$.isAIThinking=!0,$.isLoadingSource=!0,$.currentToolStatus=null,$.toolsUsedInCurrentRound=[],$.agentStatus=null,$.isAborted=!1,$.currentRequestId=z,$.currentAgentRequestId="";try{const _e=await window.llmApi.hasConfig();if($.isAborted)return k(_,z),{success:!1,reason:"aborted"};if($.currentRequestId!==z)return k(_,z),{success:!1,reason:"busy",activeTask:t.value};if(!_e)return se.messages.push({id:u("error"),role:"assistant",content:"⚠️ 请先配置 AI 服务。点击左下角「设置」按钮前往「模型配置Tab」进行配置。",timestamp:Date.now()}),k(_,z),{success:!1,reason:"no_config"};const be={id:u("user"),role:"user",content:y,timestamp:Date.now(),toolCalls:[]};pe=be,se.messages.push(be);const Le={id:u("ai"),role:"assistant",content:"",timestamp:Date.now(),isStreaming:!0,contentBlocks:[]};ae&&he&&Le.contentBlocks.push({type:"skill",skillId:ae,skillName:he}),se.messages.push(Le);let Ae=se.messages.length-1,de=!1;const w=O=>{se.messages[Ae]={...se.messages[Ae],...O}},R=O=>{if(!O)return;const ge=se.messages[Ae].contentBlocks||[],fe=ge[ge.length-1];O.trim().length===0&&(!fe||fe.type!=="text")||(fe&&fe.type==="text"?fe.text+=O:ge.push({type:"text",text:O}),w({contentBlocks:[...ge],content:se.messages[Ae].content+O}))},oe=(O,ge,fe)=>{if(!O&&fe===void 0)return;const Se=se.messages[Ae].contentBlocks||[],Pe=ge||"think",qe=Se[Se.length-1];let st=qe;if(qe&&qe.type==="think"&&qe.tag===Pe)qe.text+=O;else if(O.trim().length>0)st={type:"think",tag:Pe,text:O},Se.push(st);else if(fe!==void 0)for(let Ft=Se.length-1;Ft>=0;Ft--){const Rs=Se[Ft];if(Rs.type==="think"&&Rs.tag===Pe){st=Rs;break}}fe!==void 0&&st&&st.type==="think"&&(st.durationMs=fe),w({contentBlocks:[...Se]})},te=(O,ge)=>{const fe=se.messages[Ae].contentBlocks||[];fe.push({type:"tool",tool:{name:O,displayName:O,status:"running",params:ge}}),w({contentBlocks:[...fe]})},q=(O,ge)=>{const fe=se.messages[Ae].contentBlocks||[];for(let Se=fe.length-1;Se>=0;Se--){const Pe=fe[Se];if(Pe.type==="tool"&&Pe.tool.name===O&&Pe.tool.status==="running"){Pe.tool.status=ge;break}}w({contentBlocks:[...fe]})},ue=se.assistantId??Un($.locale);if(!W){const O=y.slice(0,50)+(y.length>50?"...":""),ge=await Ht().createConversation($.sessionId,O,ue);if($.isAborted)return w({isStreaming:!1}),k(_,z),{success:!1,reason:"aborted"};if($.currentRequestId!==z)return w({isStreaming:!1}),k(_,z),{success:!1,reason:"busy",activeTask:t.value};W=ge.id,D($,gt,ge.id),se.assistantId=ue,T(_,ge.id)}const U=a.aiPreprocessConfig,Ie=U.dataCleaning||U.mergeConsecutive||U.blacklistKeywords.length>0||U.denoise||U.desensitize||U.anonymizeNames?{dataCleaning:U.dataCleaning,mergeConsecutive:U.mergeConsecutive,mergeWindowSeconds:U.mergeWindowSeconds,blacklistKeywords:[...U.blacklistKeywords],denoise:U.denoise,desensitize:U.desensitize,desensitizeRules:U.desensitizeRules.map(O=>({...O,locales:[...O.locales]})),anonymizeNames:U.anonymizeNames}:void 0,Te={sessionId:$.sessionId,conversationId:W,timeFilter:$.timeFilter?{startTs:$.timeFilter.startTs,endTs:$.timeFilter.endTs}:void 0,maxMessagesLimit:l.value.maxMessagesPerRequest,ownerInfo:$.ownerInfo?{platformId:$.ownerInfo.platformId,displayName:$.ownerInfo.displayName}:void 0,mentionedMembers:ve.length>0?ve:void 0,preprocessConfig:Ie,searchContextBefore:l.value.searchContextBefore,searchContextAfter:l.value.searchContextAfter},{requestId:Z,promise:Ce}=window.agentApi.runStream(y,Te,O=>{if(!($.isAborted||z!==$.currentRequestId))switch(O.type){case"content":O.content&&($.currentToolStatus=null,R(O.content));break;case"think":O.content?oe(O.content,O.thinkTag):O.thinkDurationMs!==void 0&&oe("",O.thinkTag,O.thinkDurationMs);break;case"tool_start":if(O.toolName){const ge=O.toolParams;$.currentToolStatus={name:O.toolName,displayName:O.toolName,status:"running"},$.toolsUsedInCurrentRound.push(O.toolName),te(O.toolName,ge)}break;case"tool_result":O.toolName&&($.currentToolStatus?.name===O.toolName&&($.currentToolStatus={...$.currentToolStatus,status:"done"}),q(O.toolName,"done")),$.isLoadingSource=!1;break;case"status":O.status&&(!$.agentStatus||O.status.updatedAt>=$.agentStatus.updatedAt)&&($.agentStatus=O.status);break;case"compression_done":if(O.compressionResult){const ge={id:`summary-${Date.now()}`,role:"summary",content:O.compressionResult.summaryContent,timestamp:O.compressionResult.timestamp},fe=Math.max(0,se.messages.length-1);se.messages.splice(fe,0,ge),Ae++}break;case"done":$.currentToolStatus=null,O.usage&&(me={...O.usage},$.sessionTokenUsage={promptTokens:$.sessionTokenUsage.promptTokens+O.usage.promptTokens,completionTokens:$.sessionTokenUsage.completionTokens+O.usage.completionTokens,totalTokens:$.sessionTokenUsage.totalTokens+O.usage.totalTokens}),I($,"completed",O.usage?{totalUsage:O.usage}:void 0);break;case"error":if($.currentToolStatus&&($.currentToolStatus={...$.currentToolStatus,status:"error"},q($.currentToolStatus.name,"error")),!de){de=!0;const ge=se.messages[Ae].contentBlocks||[];ge.push({type:"error",error:O.error||{name:null,message:"未知错误",stack:null}}),w({contentBlocks:[...ge],isStreaming:!1})}I($,"error");break}},$.chatType,$.locale,ue,ae,ae?void 0:ke,{enabled:l.value.contextCompression?.enabled??!1,tokenThresholdPercent:l.value.contextCompression?.tokenThresholdPercent??75,bufferSizePercent:l.value.contextCompression?.bufferSizePercent??20,maxToolResultPercent:l.value.contextCompression?.maxToolResultPercent??50});$.currentAgentRequestId=Z,p(_,y,Z,W);const Ze=await Ce;if($.isAborted)return k(_,Z),{success:!1,reason:"aborted"};if(z!==$.currentRequestId)return k(_,Z),{success:!1,reason:"busy",activeTask:t.value};if(Ze.success&&Ze.result)se.messages[Ae]={...se.messages[Ae],dataSource:{toolsUsed:Ze.result.toolsUsed,toolRounds:Ze.result.toolRounds},isStreaming:!1},await X(W,be,se.messages[Ae],me);else if(de)await X(W,be,se.messages[Ae],me);else{const O=se.messages[Ae].contentBlocks||[];O.push({type:"error",error:Ze.error||{name:null,message:"未知错误",stack:null}}),se.messages[Ae]={...se.messages[Ae],contentBlocks:[...O],isStreaming:!1},await X(W,be,se.messages[Ae],me)}return{success:!0}}catch(_e){console.error("[AI] 处理失败:",_e),$.agentStatus=null;const be=se.messages[se.messages.length-1];if(be&&be.role==="assistant"){const Le={name:_e instanceof Error?_e.name:null,message:_e instanceof Error?_e.message:String(_e),stack:_e instanceof Error?_e.stack??null:null},Ae=be.contentBlocks||[];Ae.push({type:"error",error:Le}),be.contentBlocks=[...Ae],be.isStreaming=!1;const de=pe||se.messages.findLast(w=>w.role==="user");de&&await X(W,de,be,me)}return{success:!1,reason:"error"}}finally{$.isAIThinking=!1,$.isLoadingSource=!1,$.currentToolStatus=null,$.isAborted=!1,$.currentRequestId="",$.currentAgentRequestId="",k(_)}}async function X(_,y,L,$){try{if(!_)return;await Ht().addMessage(_,"user",y.content);const z=L.contentBlocks?JSON.parse(JSON.stringify(L.contentBlocks)):void 0;await Ht().addMessage(_,"assistant",L.content,void 0,void 0,z,$)}catch(z){console.error("[AI] 保存对话失败:",z)}}async function le(_){const y=h(_);if(!y||!y.isAIThinking)return!1;y.isAborted=!0,y.isAIThinking=!1,y.isLoadingSource=!1,y.currentToolStatus=null,I(y,"aborted");const L=t.value?.chatKey===_?t.value.conversationId??gt:js(y),$=y.conversationBuffers[L],z=$?$.messages[$.messages.length-1]:void 0;if(z&&z.role==="assistant"&&z.isStreaming&&(z.isStreaming=!1,z.content+=`
5
-
6
- _(已停止生成)_`),y.currentAgentRequestId)try{await window.agentApi.abort(y.currentAgentRequestId)}catch(ce){console.error("[AI] 中止 Agent 请求失败:",ce)}return y.currentRequestId="",y.currentAgentRequestId="",k(_),!0}async function F(){return t.value?le(t.value.chatKey):!1}return{sessionStates:e,activeTask:t,ensureSessionState:f,getSessionState:h,getActiveTaskState:x,applySessionAssistantSelection:M,selectAssistantForSession:N,loadConversation:ee,focusConversation:V,focusActiveTaskConversation:ie,resetToSelectorOnEnter:Q,startNewConversation:Y,loadMoreSourceMessages:H,updateMaxMessages:B,sendMessage:j,stopGeneration:le,stopActiveTask:F}}),Da=document.createElement("canvas");Da.width=1;Da.height=1;const On=Da.getContext("2d",{willReadFrequently:!0});function K$(e){if(!On)return null;const t=On;t.clearRect(0,0,1,1),t.fillStyle="rgba(0, 0, 0, 0)",t.fillRect(0,0,1,1);try{t.fillStyle=e}catch{return null}t.fillRect(0,0,1,1);const[s,n,a,i]=t.getImageData(0,0,1,1).data;return i===0?null:{r:s,g:n,b:a,a:i/255}}function Hn(e,t){const s=e.a+t.a*(1-e.a);return s<=0?{r:0,g:0,b:0,a:0}:{r:(e.r*e.a+t.r*t.a*(1-e.a))/s,g:(e.g*e.a+t.g*t.a*(1-e.a))/s,b:(e.b*e.a+t.b*t.a*(1-e.a))/s,a:s}}function qs(e){return`rgb(${Math.round(e.r)}, ${Math.round(e.g)}, ${Math.round(e.b)})`}function G$(e){const t={r:17,g:17,b:17,a:1};let s=e,n=null;for(;s;){const a=window.getComputedStyle(s).backgroundColor,i=K$(a);if(i&&i.a>0&&(n=n?Hn(n,i):i,n.a>=.999))return qs(n);s=s.parentElement}return qs(n?Hn(n,t):t)}async function NE(e,t){const s=t?.maxExportWidth??2160,n=t?.minScale??1,a=t?.fullContent!==!1,i=t?.backgroundColor??G$(e),c=a?e.scrollWidth:e.getBoundingClientRect().width;let l=Math.min(1,s/Math.max(1,c));l=Math.max(n,l);const m={scale:l,embedFonts:t?.embedFonts??!1,compress:t?.compress??!0,backgroundColor:i,crossOrigin:t?.crossOrigin??"anonymous"},u=await Er(e,m);try{const f=await u.toCanvas();if(f&&f.toDataURL){const h=f,x=document.createElement("canvas"),S=h.width>s?s/h.width:1;x.width=Math.round(h.width*S),x.height=Math.round(h.height*S);const C=x.getContext("2d");if(C)return C.fillStyle=i,C.fillRect(0,0,x.width,x.height),C.drawImage(h,0,0,x.width,x.height),x.toDataURL("image/png")}}catch{}try{const f=await u.toPng({backgroundColor:i});if(f instanceof HTMLImageElement)return f.src;if(f instanceof Blob)return new Promise((h,x)=>{const S=new FileReader;S.onload=()=>h(S.result),S.onerror=x,S.readAsDataURL(f)});if(typeof f=="string")return f}catch{}try{return(await u.toImg()).src}catch(f){throw console.error("captureAsImageData: all export paths failed",f),new Error("Failed to capture image data")}}const X$={key:0,class:"px-2 pb-2"},Vn=$e({__name:"DatePicker",props:{modelValue:{},placeholder:{default:""},clearable:{type:Boolean,default:!0},widthClass:{default:"w-32"}},emits:["update:modelValue"],setup(e,{emit:t}){const{t:s,locale:n}=Re(),a=e,i=t,c=P(!1),l=G(()=>n.value.startsWith("zh")?"zh-CN":n.value==="ja-JP"?"ja-JP":"en-US");function m(S){if(!S)return;const C=ot(S);return new fr(C.year(),C.month()+1,C.date())}function u(S){return S?`${S.year}-${String(S.month).padStart(2,"0")}-${String(S.day).padStart(2,"0")}`:""}const f=G({get:()=>m(a.modelValue),set:S=>{i("update:modelValue",u(S)),S&&(c.value=!1)}}),h=G(()=>a.modelValue?ot(a.modelValue).format("YYYY/MM/DD"):"");function x(){i("update:modelValue",""),c.value=!1}return(S,C)=>{const D=We,M=wr,g=so;return b(),xe(g,{open:c.value,"onUpdate:open":C[1]||(C[1]=p=>c.value=p),ui:{content:"z-[100]"}},{content:re(()=>[v(M,{modelValue:f.value,"onUpdate:modelValue":C[0]||(C[0]=p=>f.value=p),"number-of-months":1,"fixed-weeks":!1,locale:l.value},null,8,["modelValue","locale"]),e.clearable?(b(),A("div",X$,[v(D,{variant:"ghost",size:"xs",color:"neutral",class:"w-full",onClick:x},{default:re(()=>[J(d(o(s)("common.datePicker.clearDate")),1)]),_:1})])):ne("",!0)]),default:re(()=>[v(D,{label:h.value||e.placeholder||o(s)("common.datePicker.selectDate"),icon:"i-heroicons-calendar-days",variant:"outline",color:"neutral",size:"sm",class:we([e.widthClass,"justify-start",{"text-gray-400":!h.value}])},null,8,["label","class"])]),_:1},8,["open"])}}});function Ks(e){const t=String(e.type||"").trim().toLowerCase(),s=String(e.id||"").trim().toLowerCase();return t==="group"||s.endsWith("@chatroom")?"group":t==="private"?"private":(t==="channel"||t==="official"||t==="other"||s.startsWith("gh_")||s.includes("@openim")||s.startsWith("weixin")&&s!=="weixin","other")}const Y$={class:"p-6",style:{"min-width":"480px","max-height":"80vh","overflow-y":"auto"}},Q$={class:"mb-4 text-lg font-semibold text-gray-900 dark:text-white"},J$={class:"space-y-4"},Z$={class:"mb-1 block text-xs font-medium text-gray-700 dark:text-gray-300"},eI={class:"mb-1 block text-xs font-medium text-gray-700 dark:text-gray-300"},tI={class:"mb-1 block text-xs font-medium text-gray-700 dark:text-gray-300"},sI={class:"grid grid-cols-2 gap-3"},aI={class:"mb-1 block text-xs font-medium text-gray-700 dark:text-gray-300"},nI={class:"mb-1 block text-xs font-medium text-gray-700 dark:text-gray-300"},oI={key:1,class:"rounded-md bg-red-50 p-3 text-xs text-red-600 dark:bg-red-900/20 dark:text-red-400"},rI={key:2},iI={class:"mb-2 flex items-center justify-between"},lI={class:"text-xs font-medium text-gray-700 dark:text-gray-300"},cI={class:"mb-3 flex items-center gap-2"},dI={class:"mb-2 flex flex-wrap items-center gap-2"},uI={class:"text-xs text-gray-500 dark:text-gray-400"},mI={class:"inline-flex rounded-lg bg-gray-100 p-0.5 dark:bg-gray-800"},gI=["disabled","onClick"],pI={key:0,class:"max-h-64 overflow-y-auto rounded-lg border border-gray-200 dark:border-gray-600"},fI=["onClick"],hI={class:"min-w-0 flex-1"},vI={class:"flex items-center gap-2 truncate text-sm font-medium text-gray-900 dark:text-white"},yI={key:0,class:"rounded-full bg-green-100 px-1.5 py-0.5 text-[10px] text-green-700 dark:bg-green-900/30 dark:text-green-400"},bI={class:"flex items-center gap-2 text-xs text-gray-500 dark:text-gray-400"},_I={class:"rounded bg-gray-100 px-1 dark:bg-gray-700"},xI={key:0},kI={key:1,class:"rounded-lg border border-dashed border-gray-200 px-3 py-6 text-center text-xs text-gray-500 dark:border-gray-700 dark:text-gray-400"},wI={key:2,class:"mt-3 flex justify-center"},SI={class:"flex justify-end gap-2 pt-2"},zn=200,CI=5e3,Bn=$e({__name:"DataSourceAddModal",props:{open:{type:Boolean},manageSource:{},subscribedRemoteIds:{}},emits:["update:open","sourceAdded","sessionsAdded"],setup(e,{emit:t}){const s=e,n=t,{t:a}=Re(),i=Qo(),c=G(()=>!!s.manageSource),l=P({name:"",baseUrl:"",token:"",intervalMinutes:60,pullLimit:1e3}),m=P([]),u=P(new Set),f=P(!1),h=P(!1),x=P(!1),S=P(""),C=P(""),D=P(),M=P(!1),g=P(!1),p=P("all");Ne(()=>s.open,async _=>{_&&(c.value&&s.manageSource?l.value={name:s.manageSource.name||"",baseUrl:s.manageSource.baseUrl,token:s.manageSource.token,intervalMinutes:s.manageSource.intervalMinutes,pullLimit:s.manageSource.pullLimit}:l.value={name:"",baseUrl:"",token:"",intervalMinutes:60,pullLimit:1e3},m.value=[],u.value=new Set,S.value="",C.value="",D.value=void 0,M.value=!1,g.value=!1,p.value="all",c.value&&await Y())},{immediate:!0});const k=G(()=>m.value.filter(_=>Ks(_)!=="other")),T=G(()=>p.value==="all"?k.value:k.value.filter(_=>Ks(_)===p.value)),E=G(()=>T.value.filter(_=>!s.subscribedRemoteIds?.has(_.id))),I=G(()=>E.value.length>0&&E.value.every(_=>u.value.has(_.id))),N=G(()=>[{value:"all",label:a("settings.api.dataSources.discovery.typeAll")},{value:"private",label:a("settings.api.dataSources.discovery.typePrivate")},{value:"group",label:a("settings.api.dataSources.discovery.typeGroup")}].map(_=>({..._,count:_.value==="all"?k.value.length:k.value.filter(y=>Ks(y)===_.value).length})));function ee(_){p.value=_}function V(){const _=E.value.map(y=>y.id);if(I.value){const y=new Set(u.value);for(const L of _)y.delete(L);u.value=y}else u.value=new Set([...u.value,..._])}function ie(_){if(s.subscribedRemoteIds?.has(_))return;const y=new Set(u.value);y.has(_)?y.delete(_):y.add(_),u.value=y}function Q(){n("update:open",!1)}async function Y(){await X({append:!1,resetSelection:!0})}async function H(){await X({append:!1,resetSelection:!0})}async function B(){!M.value||!D.value||await X({append:!0,resetSelection:!1})}function j(_,y){const L=new Map(_.map($=>[$.id,$]));for(const $ of y)L.set($.id,$);return[...L.values()]}async function X(_){if(l.value.baseUrl){_.append?h.value=!0:f.value=!0,g.value=!0,S.value="",_.append||(m.value=[],D.value=void 0,M.value=!1,p.value="all",_.resetSelection&&(u.value=new Set));try{const y=await i.fetchRemoteSessions(l.value.baseUrl,l.value.token,{keyword:C.value.trim()||void 0,limit:zn,cursor:_.append?D.value:void 0});if(!_.append&&!y.page&&y.sessions.length>=zn){const L=await i.fetchRemoteSessions(l.value.baseUrl,l.value.token,{keyword:C.value.trim()||void 0,limit:CI});m.value=L.sessions,M.value=!1,D.value=void 0}else m.value=_.append?j(m.value,y.sessions):y.sessions,M.value=!!y.page?.hasMore,D.value=y.page?.nextCursor}catch(y){S.value=y.message||a("settings.api.dataSources.discovery.error")}finally{f.value=!1,h.value=!1}}}async function le(){if(c.value){if(u.value.size===0||!s.manageSource)return;const _=m.value.filter(y=>u.value.has(y.id)).map(y=>({name:y.name,remoteSessionId:y.id}));n("sessionsAdded",s.manageSource.id,_),Q();return}x.value=!0,S.value="";try{await i.fetchRemoteSessions(l.value.baseUrl,l.value.token,{limit:1})}catch(_){S.value=_.message||a("settings.api.dataSources.discovery.connectionCheckFailed");return}finally{x.value=!1}x.value=!0;try{await i.addDataSource({name:l.value.name||void 0,baseUrl:l.value.baseUrl,token:l.value.token,intervalMinutes:l.value.intervalMinutes,pullLimit:l.value.pullLimit||void 0}),n("sourceAdded"),Q()}finally{x.value=!1}}function F(_){return _===void 0?"-":_>=1e4?`${(_/1e4).toFixed(1)}w`:_>=1e3?`${(_/1e3).toFixed(1)}k`:String(_)}return(_,y)=>{const L=lt,$=We,z=oo,ce=ht;return b(),xe(ce,{open:e.open,ui:{content:"z-[101]",overlay:"z-[100]"},"onUpdate:open":y[7]||(y[7]=W=>n("update:open",W))},{content:re(()=>[r("div",Y$,[r("h3",Q$,d(c.value?o(a)("settings.api.dataSources.edit.manageSessions"):o(a)("settings.api.dataSources.form.modalTitle")),1),r("div",J$,[c.value?ne("",!0):(b(),A(Me,{key:0},[r("div",null,[r("label",Z$,d(o(a)("settings.api.dataSources.form.name")),1),v(L,{modelValue:l.value.name,"onUpdate:modelValue":y[0]||(y[0]=W=>l.value.name=W),class:"w-full",placeholder:o(a)("settings.api.dataSources.form.namePlaceholder")},null,8,["modelValue","placeholder"])]),r("div",null,[r("label",eI,d(o(a)("settings.api.dataSources.discovery.baseUrl")),1),v(L,{modelValue:l.value.baseUrl,"onUpdate:modelValue":y[1]||(y[1]=W=>l.value.baseUrl=W),class:"w-full",placeholder:o(a)("settings.api.dataSources.discovery.baseUrlPlaceholder")},null,8,["modelValue","placeholder"])]),r("div",null,[r("label",tI,d(o(a)("settings.api.dataSources.form.token")),1),v(L,{modelValue:l.value.token,"onUpdate:modelValue":y[2]||(y[2]=W=>l.value.token=W),class:"w-full",placeholder:o(a)("settings.api.dataSources.form.tokenPlaceholder")},null,8,["modelValue","placeholder"])]),r("div",sI,[r("div",null,[r("label",aI,d(o(a)("settings.api.dataSources.form.interval")),1),v(L,{modelValue:l.value.intervalMinutes,"onUpdate:modelValue":y[3]||(y[3]=W=>l.value.intervalMinutes=W),modelModifiers:{number:!0},type:"number",min:1,class:"w-full"},null,8,["modelValue"])]),r("div",null,[r("label",nI,d(o(a)("settings.api.dataSources.form.pullLimit")),1),v(L,{modelValue:l.value.pullLimit,"onUpdate:modelValue":y[4]||(y[4]=W=>l.value.pullLimit=W),modelModifiers:{number:!0},type:"number",min:100,max:1e4,class:"w-full",placeholder:o(a)("settings.api.dataSources.form.pullLimitPlaceholder")},null,8,["modelValue","placeholder"])])])],64)),S.value?(b(),A("div",oI,d(S.value),1)):ne("",!0),c.value&&g.value?(b(),A("div",rI,[r("div",iI,[r("span",lI,d(o(a)("settings.api.dataSources.discovery.found",{count:k.value.length})),1),r("button",{class:"text-xs text-blue-500 hover:text-blue-700 dark:hover:text-blue-400",onClick:V},d(I.value?o(a)("settings.api.dataSources.discovery.deselectAll"):o(a)("settings.api.dataSources.discovery.selectAll")),1)]),r("div",cI,[v(L,{modelValue:C.value,"onUpdate:modelValue":y[5]||(y[5]=W=>C.value=W),class:"flex-1",placeholder:o(a)("settings.api.dataSources.discovery.searchPlaceholder"),onKeydown:Zt(es(H,["prevent"]),["enter"])},null,8,["modelValue","placeholder","onKeydown"]),v($,{color:"primary",variant:"soft",loading:f.value,onClick:H},{default:re(()=>[J(d(o(a)("settings.api.dataSources.discovery.search")),1)]),_:1},8,["loading"])]),r("div",dI,[r("span",uI,d(o(a)("settings.api.dataSources.discovery.selectByType")),1),r("div",mI,[(b(!0),A(Me,null,Be(N.value,W=>(b(),A("button",{key:W.value,type:"button",class:we(["rounded-md px-2.5 py-1 text-xs transition-colors",p.value===W.value?"bg-white text-blue-600 shadow-sm dark:bg-gray-700 dark:text-blue-300":"text-gray-600 hover:text-gray-900 dark:text-gray-400 dark:hover:text-gray-200"]),disabled:W.count===0,onClick:se=>ee(W.value)},d(W.label)+" ("+d(W.count)+") ",11,gI))),128))])]),k.value.length>0?(b(),A("div",pI,[(b(!0),A(Me,null,Be(T.value,W=>(b(),A("div",{key:W.id,class:we(["flex items-center gap-3 border-b border-gray-100 px-3 py-2 last:border-0",e.subscribedRemoteIds?.has(W.id)?"opacity-60":"cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-800"]),onClick:se=>ie(W.id)},[v(z,{"model-value":e.subscribedRemoteIds?.has(W.id)||u.value.has(W.id),disabled:e.subscribedRemoteIds?.has(W.id),onClick:y[6]||(y[6]=es(()=>{},["stop"])),"onUpdate:modelValue":se=>ie(W.id)},null,8,["model-value","disabled","onUpdate:modelValue"]),r("div",hI,[r("div",vI,[J(d(W.name)+" ",1),e.subscribedRemoteIds?.has(W.id)?(b(),A("span",yI,d(o(a)("settings.api.dataSources.edit.subscribed")),1)):ne("",!0)]),r("div",bI,[r("span",_I,d(W.platform),1),r("span",null,d(W.type),1),W.messageCount!==void 0?(b(),A("span",xI,d(F(W.messageCount))+" "+d(o(a)("settings.api.dataSources.discovery.messages")),1)):ne("",!0)])])],10,fI))),128))])):(b(),A("div",kI,d(o(a)("settings.api.dataSources.discovery.found",{count:0})),1)),M.value?(b(),A("div",wI,[v($,{color:"neutral",variant:"soft",loading:h.value,onClick:B},{default:re(()=>[J(d(o(a)("settings.api.dataSources.discovery.loadMore")),1)]),_:1},8,["loading"])])):ne("",!0)])):ne("",!0),r("div",SI,[v($,{variant:"soft",onClick:Q},{default:re(()=>[J(d(o(a)("common.cancel")),1)]),_:1}),c.value?(b(),xe($,{key:0,color:"primary",disabled:u.value.size===0,onClick:le},{default:re(()=>[J(d(o(a)("settings.api.dataSources.discovery.subscribe",{count:u.value.size})),1)]),_:1},8,["disabled"])):(b(),xe($,{key:1,color:"primary",disabled:!l.value.baseUrl,loading:x.value,onClick:le},{default:re(()=>[J(d(o(a)("settings.api.dataSources.addBtn")),1)]),_:1},8,["disabled","loading"]))])])])]),_:1},8,["open"])}}}),MI={class:"p-6",style:{"min-width":"420px"}},AI={class:"mb-4 text-lg font-semibold text-gray-900 dark:text-white"},TI={class:"space-y-4"},$I={class:"mb-1 block text-xs font-medium text-gray-700 dark:text-gray-300"},II={class:"mb-1 block text-xs font-medium text-gray-700 dark:text-gray-300"},PI={class:"mb-1 block text-xs font-medium text-gray-700 dark:text-gray-300"},DI={class:"grid grid-cols-2 gap-3"},LI={class:"mb-1 block text-xs font-medium text-gray-700 dark:text-gray-300"},EI={class:"mb-1 block text-xs font-medium text-gray-700 dark:text-gray-300"},RI={class:"flex justify-end gap-2 pt-2"},NI=$e({__name:"DataSourceEditModal",props:{open:{type:Boolean},dataSource:{}},emits:["update:open","saved"],setup(e,{emit:t}){const s=e,n=t,{t:a}=Re(),i=P({name:"",baseUrl:"",token:"",intervalMinutes:60,pullLimit:1e3});Ne(()=>s.open,l=>{l&&s.dataSource&&(i.value={name:s.dataSource.name,baseUrl:s.dataSource.baseUrl,token:s.dataSource.token,intervalMinutes:s.dataSource.intervalMinutes,pullLimit:s.dataSource.pullLimit})});function c(){n("saved",{name:i.value.name,baseUrl:i.value.baseUrl,token:i.value.token,intervalMinutes:i.value.intervalMinutes,pullLimit:i.value.pullLimit}),n("update:open",!1)}return(l,m)=>{const u=lt,f=We,h=ht;return b(),xe(h,{open:e.open,ui:{content:"z-[101]",overlay:"z-[100]"},"onUpdate:open":m[6]||(m[6]=x=>n("update:open",x))},{content:re(()=>[r("div",MI,[r("h3",AI,d(o(a)("settings.api.dataSources.edit.title")),1),r("div",TI,[r("div",null,[r("label",$I,d(o(a)("settings.api.dataSources.form.name")),1),v(u,{modelValue:i.value.name,"onUpdate:modelValue":m[0]||(m[0]=x=>i.value.name=x),class:"w-full",placeholder:o(a)("settings.api.dataSources.form.namePlaceholder")},null,8,["modelValue","placeholder"])]),r("div",null,[r("label",II,d(o(a)("settings.api.dataSources.discovery.baseUrl")),1),v(u,{modelValue:i.value.baseUrl,"onUpdate:modelValue":m[1]||(m[1]=x=>i.value.baseUrl=x),class:"w-full",placeholder:"https://example.com"},null,8,["modelValue"])]),r("div",null,[r("label",PI,d(o(a)("settings.api.dataSources.form.token")),1),v(u,{modelValue:i.value.token,"onUpdate:modelValue":m[2]||(m[2]=x=>i.value.token=x),class:"w-full",placeholder:o(a)("settings.api.dataSources.form.tokenPlaceholder")},null,8,["modelValue","placeholder"])]),r("div",DI,[r("div",null,[r("label",LI,d(o(a)("settings.api.dataSources.form.interval")),1),v(u,{modelValue:i.value.intervalMinutes,"onUpdate:modelValue":m[3]||(m[3]=x=>i.value.intervalMinutes=x),modelModifiers:{number:!0},type:"number",min:1,class:"w-full"},null,8,["modelValue"])]),r("div",null,[r("label",EI,d(o(a)("settings.api.dataSources.form.pullLimit")),1),v(u,{modelValue:i.value.pullLimit,"onUpdate:modelValue":m[4]||(m[4]=x=>i.value.pullLimit=x),modelModifiers:{number:!0},type:"number",min:100,max:1e4,class:"w-full",placeholder:o(a)("settings.api.dataSources.form.pullLimitPlaceholder")},null,8,["modelValue","placeholder"])])]),r("div",RI,[v(f,{variant:"soft",onClick:m[5]||(m[5]=x=>n("update:open",!1))},{default:re(()=>[J(d(o(a)("settings.api.dataSources.edit.cancel")),1)]),_:1}),v(f,{color:"primary",onClick:c},{default:re(()=>[J(d(o(a)("settings.api.dataSources.edit.save")),1)]),_:1})])])])]),_:1},8,["open"])}}}),FI={class:"space-y-6 pb-6"},UI={class:"mb-3 flex items-center gap-2 text-sm font-semibold text-gray-900 dark:text-white"},OI={class:"rounded-lg border border-gray-200 bg-gray-50 dark:border-gray-700 dark:bg-gray-800/50"},HI={class:"p-4"},VI={class:"text-sm text-gray-600 dark:text-gray-300"},zI={class:"mt-3 flex flex-wrap gap-2"},BI={class:"inline-flex items-center gap-1.5 rounded-full bg-emerald-100 px-2.5 py-1 text-xs font-medium text-emerald-700 dark:bg-emerald-900/30 dark:text-emerald-400"},WI={class:"inline-flex items-center gap-1.5 rounded-full bg-blue-100 px-2.5 py-1 text-xs font-medium text-blue-700 dark:bg-blue-900/30 dark:text-blue-400"},jI={class:"p-4"},qI={class:"text-sm text-gray-600 dark:text-gray-300"},KI={class:"mb-3 flex items-center gap-2 text-sm font-semibold text-gray-900 dark:text-white"},GI={class:"rounded-lg border border-gray-200 bg-gray-50 dark:border-gray-700 dark:bg-gray-800/50"},XI={class:"flex items-center justify-between p-4"},YI={class:"flex-1 pr-4"},QI={class:"text-sm font-medium text-gray-900 dark:text-white"},JI={class:"w-72"},ZI={class:"p-4"},eP={class:"relative"},tP={class:"overflow-x-auto rounded-lg bg-gray-900 p-4 text-xs leading-relaxed text-gray-100 dark:bg-gray-950"},sP={class:"mt-2 text-xs text-gray-500 dark:text-gray-400"},aP={class:"mb-3 flex items-center gap-2 text-sm font-semibold text-gray-900 dark:text-white"},nP={class:"rounded-lg border border-gray-200 bg-gray-50 p-4 dark:border-gray-700 dark:bg-gray-800/50"},oP={class:"space-y-2 text-xs text-gray-600 dark:text-gray-400"},rP={class:"flex items-start gap-2"},iP={class:"flex items-start gap-2"},lP={class:"flex items-start gap-2"},cP={class:"flex items-start gap-2"},dP=$e({__name:"McpSettingsTab",setup(e){const{t}=Re(),{copy:s,copied:n}=vM({copiedDuring:2e3}),a=P("claude"),i=G(()=>[{label:"ClaudeCode",value:"claude"},{label:"Codex",value:"codex"},{label:"OpenClaw",value:"openclaw"},{label:t("settings.mcp.clients.other"),value:"other"}]),c=G(()=>{const m="chatlab",u=["mcp"];switch(a.value){case"codex":return["[mcp_servers.chatlab]",`command = "${m}"`,`args = ["${u[0]}"]`].join(`
7
- `);case"openclaw":return JSON.stringify({mcp:{servers:{chatlab:{command:m,args:u}}}},null,2);case"claude":return JSON.stringify({mcpServers:{chatlab:{command:m,args:u}}},null,2);default:return JSON.stringify({command:m,args:u},null,2)}});function l(){s(c.value)}return(m,u)=>{const f=Ve,h=cs,x=We;return b(),A("div",FI,[r("div",null,[r("h3",UI,[v(f,{name:"i-heroicons-command-line",class:"h-4 w-4 text-emerald-500"}),J(" "+d(o(t)("settings.mcp.overview.title")),1)]),r("div",OI,[r("div",HI,[r("p",VI,d(o(t)("settings.mcp.overview.description")),1),r("div",zI,[r("span",BI,[u[1]||(u[1]=r("span",{class:"h-1.5 w-1.5 rounded-full bg-emerald-500"},null,-1)),J(" "+d(o(t)("settings.mcp.overview.toolCount",{count:33})),1)]),r("span",WI,[u[2]||(u[2]=r("span",{class:"h-1.5 w-1.5 rounded-full bg-blue-500"},null,-1)),J(" "+d(o(t)("settings.mcp.overview.resourceCount",{count:3})),1)]),u[3]||(u[3]=r("span",{class:"inline-flex items-center gap-1.5 rounded-full bg-purple-100 px-2.5 py-1 text-xs font-medium text-purple-700 dark:bg-purple-900/30 dark:text-purple-400"},[r("span",{class:"h-1.5 w-1.5 rounded-full bg-purple-500"}),J(" stdio ")],-1))])]),u[5]||(u[5]=r("div",{class:"border-t border-gray-200 dark:border-gray-700"},null,-1)),r("div",jI,[r("p",qI,d(o(t)("settings.mcp.overview.installHint")),1),u[4]||(u[4]=r("div",{class:"mt-2"},[r("code",{class:"inline-block rounded-md bg-gray-900 px-3 py-1.5 text-xs text-gray-100 dark:bg-gray-950"}," npm install -g chatlab-cli ")],-1))])])]),r("div",null,[r("h3",KI,[v(f,{name:"i-heroicons-clipboard-document",class:"h-4 w-4 text-pink-500"}),J(" "+d(o(t)("settings.mcp.config.title")),1)]),r("div",GI,[r("div",XI,[r("div",YI,[r("p",QI,d(o(t)("settings.mcp.config.clientLabel")),1)]),r("div",JI,[v(h,{modelValue:a.value,"onUpdate:modelValue":u[0]||(u[0]=S=>a.value=S),size:"sm",class:"gap-0",items:i.value},null,8,["modelValue","items"])])]),u[6]||(u[6]=r("div",{class:"border-t border-gray-200 dark:border-gray-700"},null,-1)),r("div",ZI,[r("div",eP,[r("pre",tP,[r("code",null,d(c.value),1)]),v(x,{icon:o(n)?"i-heroicons-check":"i-heroicons-clipboard",color:o(n)?"success":"neutral",variant:"soft",size:"xs",class:"absolute right-2 top-2",onClick:l},{default:re(()=>[J(d(o(n)?o(t)("settings.mcp.config.copied"):o(t)("settings.mcp.config.copy")),1)]),_:1},8,["icon","color"])]),r("p",sP,d(o(t)(`settings.mcp.config.${a.value}Hint`)),1)])])]),r("div",null,[r("h3",aP,[v(f,{name:"i-heroicons-light-bulb",class:"h-4 w-4 text-amber-500"}),J(" "+d(o(t)("settings.mcp.tips.title")),1)]),r("div",nP,[r("ul",oP,[r("li",rP,[u[7]||(u[7]=r("span",{class:"mt-0.5 text-gray-400"},"•",-1)),J(" "+d(o(t)("settings.mcp.tips.dataDir")),1)]),r("li",iP,[u[8]||(u[8]=r("span",{class:"mt-0.5 text-gray-400"},"•",-1)),J(" "+d(o(t)("settings.mcp.tips.readOnly")),1)]),r("li",lP,[u[9]||(u[9]=r("span",{class:"mt-0.5 text-gray-400"},"•",-1)),J(" "+d(o(t)("settings.mcp.tips.nodeRequired")),1)]),r("li",cP,[u[10]||(u[10]=r("span",{class:"mt-0.5 text-gray-400"},"•",-1)),J(" "+d(o(t)("settings.mcp.tips.docs")),1)])])])])])}}}),uP={class:"flex h-full flex-col -mx-6 -mt-6"},mP={class:"flex-1 min-h-0 overflow-auto"},gP={class:"space-y-6 px-6 pt-4 pb-6"},pP={key:0},fP={class:"mb-3 flex items-center gap-2 text-sm font-semibold text-gray-900 dark:text-white"},hP={class:"rounded-lg border border-gray-200 bg-gray-50 p-4 dark:border-gray-700 dark:bg-gray-800/50"},vP={class:"mb-3 text-xs text-gray-500 dark:text-gray-400"},yP={key:0,class:"mb-4 space-y-4"},bP={class:"flex items-center justify-between border-b border-gray-100 px-3 py-2 dark:border-gray-700"},_P={class:"flex items-center gap-2"},xP={key:0,class:"text-xs font-medium text-gray-700 dark:text-gray-300"},kP={class:"text-xs font-mono text-gray-500 dark:text-gray-400"},wP={key:1,class:"text-xs text-gray-400"},SP={class:"flex items-center gap-1"},CP={key:0,class:"max-h-80 overflow-y-auto"},MP={class:"flex items-center justify-between"},AP={class:"flex items-center gap-2"},TP={class:"text-sm font-medium text-gray-900 dark:text-white"},$P={class:"flex items-center gap-1"},IP={class:"mt-1 flex items-center gap-2 text-xs text-gray-500 dark:text-gray-400"},PP={key:0,class:"text-blue-500"},DP={key:1,class:"text-blue-500"},LP={key:2},EP={class:"text-gray-400"},RP={key:0,class:"text-green-500"},NP={key:1,class:"text-red-500"},FP={key:1,class:"px-3 py-4 text-center text-xs text-gray-400"},UP={key:1,class:"mb-4 py-4 text-center text-xs text-gray-400"},OP={key:0},HP={class:"mb-3 flex items-center gap-2 text-sm font-semibold text-gray-900 dark:text-white"},VP={class:"rounded-lg border border-gray-200 bg-gray-50 p-4 dark:border-gray-700 dark:bg-gray-800/50"},zP={class:"flex items-center gap-2"},BP={class:"text-xs text-green-500"},WP={class:"mt-3 space-y-2 border-t border-gray-200 pt-3 text-xs text-gray-600 dark:border-gray-700 dark:text-gray-400"},jP={class:"flex items-center justify-between"},qP={class:"font-mono text-gray-700 dark:text-gray-300"},KP={key:0,class:"flex items-center justify-between gap-2"},GP={class:"flex items-center gap-1"},XP={class:"rounded bg-gray-100 px-2 py-0.5 font-mono text-gray-700 dark:bg-gray-800 dark:text-gray-300"},YP={class:"mb-3 flex items-center gap-2 text-sm font-semibold text-gray-900 dark:text-white"},QP={class:"rounded-lg border border-gray-200 bg-gray-50 p-4 dark:border-gray-700 dark:bg-gray-800/50"},JP={class:"flex items-center justify-between"},ZP={class:"flex-1 pr-4"},eD={class:"text-sm font-medium text-gray-900 dark:text-white"},tD={class:"mt-1 text-xs text-gray-500 dark:text-gray-400"},sD={key:0,class:"mt-3 flex items-center gap-2 border-t border-gray-200 pt-3 dark:border-gray-700"},aD={key:0,class:"ml-auto text-xs text-gray-500 dark:text-gray-400"},nD={key:1,class:"mt-2 rounded-md bg-red-50 p-2 text-xs text-red-600 dark:bg-red-900/20 dark:text-red-400"},oD={class:"mb-3 flex items-center gap-2 text-sm font-semibold text-gray-900 dark:text-white"},rD={class:"rounded-lg border border-gray-200 bg-gray-50 p-4 dark:border-gray-700 dark:bg-gray-800/50"},iD={class:"flex items-center justify-between"},lD={class:"flex-1 pr-4"},cD={class:"text-sm font-medium text-gray-900 dark:text-white"},dD={class:"mt-1 text-xs text-gray-500 dark:text-gray-400"},uD={key:0,class:"flex items-center gap-2"},mD={key:1,class:"flex items-center gap-2"},gD={class:"font-mono text-sm text-gray-700 dark:text-gray-300"},pD={class:"mb-3 flex items-center gap-2 text-sm font-semibold text-gray-900 dark:text-white"},fD={class:"rounded-lg border border-gray-200 bg-gray-50 p-4 dark:border-gray-700 dark:bg-gray-800/50"},hD={class:"mb-2 text-sm font-medium text-gray-900 dark:text-white"},vD={class:"mb-3 text-xs text-gray-500 dark:text-gray-400"},yD={key:0,class:"flex items-center gap-2"},bD={class:"flex-1 rounded bg-gray-100 px-3 py-2 font-mono text-xs text-gray-700 dark:bg-gray-800 dark:text-gray-300"},_D={key:1,class:"text-xs text-gray-400"},xD={class:"mt-3"},kD={class:"mt-3 border-t border-gray-200 pt-3 dark:border-gray-700"},wD={class:"text-xs text-gray-500 dark:text-gray-400"},SD={class:"mt-1 rounded bg-gray-100 p-2 font-mono text-xs text-gray-700 dark:bg-gray-800 dark:text-gray-300"},CD={class:"mb-3 flex items-center gap-2 text-sm font-semibold text-gray-900 dark:text-white"},MD={class:"rounded-lg border border-gray-200 bg-gray-50 p-4 dark:border-gray-700 dark:bg-gray-800/50"},AD={class:"text-xs text-gray-600 dark:text-gray-400"},TD=["href"],$D={class:"p-4"},ID={class:"mb-3 font-semibold text-gray-900 dark:text-white"},PD={class:"mb-4 text-sm text-gray-600 dark:text-gray-400"},DD={class:"flex justify-end gap-2"},LD={class:"p-4"},ED={class:"mb-3 font-semibold text-gray-900 dark:text-white"},RD={class:"mb-4 text-sm text-gray-600 dark:text-gray-400"},ND={class:"flex justify-end gap-2"},FD=$e({__name:"ApiSettingsTab",setup(e){const{t,locale:s}=Re(),n=Qo(),{config:a,status:i,loading:c,isRunning:l,hasError:m,isPortInUse:u,dataSources:f,pullingIds:h,syncProgress:x,isWebMode:S}=Ge(n),C=P("sync"),D=$t();Ne(()=>D.settingsSubTab,te=>{D.settingsTab==="api"&&te&&["sync","api","mcp"].includes(te)&&(C.value=te)},{immediate:!0});const M=G(()=>[{id:"sync",label:t("settings.tabs.apiSubTabs.autoSync"),icon:"i-heroicons-cloud-arrow-down"},{id:"api",label:t("settings.tabs.apiSubTabs.apiService"),icon:"i-heroicons-server-stack"},{id:"mcp",label:t("settings.tabs.apiSubTabs.mcp"),icon:"i-heroicons-command-line"}]),g=P(!1),p=P(!1),k=P(5200),T=P(!1),E=P(!1),I=P(!1),N=P(null),ee=P(!1),V=P(null),ie=P(!1),Q=P(null),Y=P(!1),H=P(null);let B=null,j=null;Qe(async()=>{await n.refresh(),k.value=a.value.port,B=n.listenStartupError(),j=n.listenPullResult()}),qt(()=>{B?.(),j?.()});const X=G(()=>a.value.token?a.value.token.slice(0,8)+"••••••••••••••••":""),le=G(()=>c.value?t("settings.api.status.starting"):l.value?t("settings.api.status.running"):u.value?t("settings.api.status.portInUse"):m.value?t("settings.api.status.error"):t("settings.api.status.stopped")),F=G(()=>c.value?"text-yellow-500":l.value?"text-green-500":m.value?"text-red-500":"text-gray-400"),_=G(()=>`http://127.0.0.1:${i.value.port||a.value.port}/api/v1`),y=G(()=>s.value==="zh-CN"||s.value==="zh-TW"?"https://docs.chatlab.fun/cn/standard/chatlab-api":"https://docs.chatlab.fun/en/standard/chatlab-api");async function L(){await n.setEnabled(!a.value.enabled)}async function $(){const te=k.value;te<1024||te>65535||(await n.setPort(te),p.value=!1)}function z(){p.value=!0,k.value=a.value.port}function ce(){k.value=a.value.port,p.value=!1}async function W(){try{await navigator.clipboard.writeText(a.value.token),T.value=!0,setTimeout(()=>{T.value=!1},2e3)}catch{}}async function se(){await n.regenerateToken()}function pe(te){N.value=te,I.value=!0}async function me(te){N.value&&await n.updateDataSource(N.value.id,te)}function ae(te){V.value=te,ee.value=!0}async function he(te,q){await n.addImportSessions(te,q)}async function ke(te){await n.updateDataSource(te.id,{enabled:!te.enabled})}function ve(te){Q.value=te,ie.value=!0}async function _e(){if(!Q.value)return;const te=Q.value;te.enabled&&await n.updateDataSource(te.id,{enabled:!1}),await n.deleteDataSource(te.id),ie.value=!1,Q.value=null}function be(te,q){H.value={ds:te,sess:q},Y.value=!0}async function Le(){if(!H.value)return;const{ds:te,sess:q}=H.value;await n.removeImportSession(te.id,q.id,!1),Y.value=!1,H.value=null}async function Ae(){if(!H.value)return;const{ds:te,sess:q}=H.value;await n.removeImportSession(te.id,q.id,!0),Y.value=!1,H.value=null}async function de(te){await n.triggerPullAll(te.id)}async function w(te,q){await n.triggerPull(te.id,q.id)}function R(te){return te?new Date(te*1e3).toLocaleString():"-"}function oe(te){return new Set(te.sessions.map(q=>q.remoteSessionId))}return(te,q)=>{const ue=Ve,U=We,K=Kt,Ie=lt,Te=ht;return b(),A("div",uP,[v(o(Ta),{modelValue:C.value,"onUpdate:modelValue":q[0]||(q[0]=Z=>C.value=Z),items:M.value,"persist-key":"apiSubTab"},null,8,["modelValue","items"]),r("div",mP,[r("div",gP,[C.value==="sync"?(b(),A("div",pP,[r("h3",fP,[v(ue,{name:"i-heroicons-cloud-arrow-down",class:"h-4 w-4 text-indigo-500"}),J(" "+d(o(t)("settings.api.dataSources.title")),1)]),r("div",hP,[r("p",vP,d(o(t)("settings.api.dataSources.desc")),1),o(f).length>0?(b(),A("div",yP,[(b(!0),A(Me,null,Be(o(f),Z=>(b(),A("div",{key:Z.id,class:"rounded-lg border border-gray-200 bg-white dark:border-gray-600 dark:bg-gray-800"},[r("div",bP,[r("div",_P,[v(ue,{name:"i-heroicons-server-stack",class:"h-3.5 w-3.5 text-gray-500 dark:text-gray-400"}),Z.name?(b(),A("span",xP,d(Z.name),1)):ne("",!0),r("span",kP,d(Z.baseUrl),1),Z.enabled?ne("",!0):(b(),A("span",wP," ("+d(o(t)("settings.api.dataSources.disabled"))+") ",1))]),r("div",SP,[v(U,{size:"xs",variant:"ghost",onClick:Ce=>pe(Z)},{default:re(()=>[v(ue,{name:"i-heroicons-pencil-square",class:"mr-1 h-3.5 w-3.5"}),J(" "+d(o(t)("settings.api.dataSources.edit.editSource")),1)]),_:1},8,["onClick"]),v(U,{size:"xs",variant:"ghost",onClick:Ce=>ae(Z)},{default:re(()=>[v(ue,{name:"i-heroicons-queue-list",class:"mr-1 h-3.5 w-3.5"}),J(" "+d(o(t)("settings.api.dataSources.edit.manageSessions")),1)]),_:1},8,["onClick"]),v(U,{size:"xs",variant:"ghost",onClick:Ce=>ke(Z)},{default:re(()=>[v(ue,{name:Z.enabled?"i-heroicons-pause":"i-heroicons-play",class:"h-3.5 w-3.5"},null,8,["name"])]),_:2},1032,["onClick"]),v(U,{size:"xs",variant:"ghost",disabled:o(h).has(Z.id)||Z.sessions.some(Ce=>o(h).has(Ce.id)),onClick:Ce=>de(Z)},{default:re(()=>[v(ue,{name:"i-heroicons-arrow-path",class:we(["h-3.5 w-3.5",{"animate-spin":o(h).has(Z.id)||Z.sessions.some(Ce=>o(h).has(Ce.id))}])},null,8,["class"])]),_:2},1032,["disabled","onClick"]),v(U,{size:"xs",variant:"ghost",color:"error",disabled:Z.sessions.some(Ce=>o(h).has(Ce.id)),onClick:Ce=>ve(Z)},{default:re(()=>[v(ue,{name:"i-heroicons-trash",class:"h-3.5 w-3.5"})]),_:1},8,["disabled","onClick"])])]),Z.sessions.length>0?(b(),A("div",CP,[(b(!0),A(Me,null,Be(Z.sessions,Ce=>(b(),A("div",{key:Ce.id,class:"border-b border-gray-50 px-3 py-2.5 last:border-0 dark:border-gray-700/50"},[r("div",MP,[r("div",AP,[r("span",{class:we(["inline-block h-2 w-2 rounded-full",o(h).has(Ce.id)?"animate-pulse bg-blue-500":Ce.lastStatus==="success"?"bg-green-500":Ce.lastStatus==="error"?"bg-red-500":"bg-gray-400"])},null,2),r("span",TP,d(Ce.name),1)]),r("div",$P,[v(U,{size:"xs",variant:"ghost",disabled:o(h).has(Ce.id),onClick:Ze=>w(Z,Ce)},{default:re(()=>[v(ue,{name:"i-heroicons-arrow-path",class:we(["h-3.5 w-3.5",{"animate-spin":o(h).has(Ce.id)}])},null,8,["class"])]),_:2},1032,["disabled","onClick"]),v(U,{size:"xs",variant:"ghost",color:"error",disabled:o(h).has(Ce.id),onClick:Ze=>be(Z,Ce)},{default:re(()=>[v(ue,{name:"i-heroicons-trash",class:"h-3.5 w-3.5"})]),_:1},8,["disabled","onClick"])])]),r("div",IP,[o(x).get(Ce.id)?(b(),A("span",PP,d(o(t)("settings.api.dataSources.syncing"))+"... "+d(o(x).get(Ce.id).current)+" "+d(o(t)("settings.api.dataSources.messages")),1)):o(h).has(Ce.id)&&!o(x).get(Ce.id)?(b(),A("span",DP,d(o(t)("settings.api.dataSources.syncing"))+"...",1)):(b(),A("span",LP,d(o(t)("settings.api.dataSources.every"))+" "+d(Z.intervalMinutes)+" "+d(o(t)("settings.api.dataSources.minutes")),1)),!o(h).has(Ce.id)&&Ce.lastPullAt?(b(),A(Me,{key:3},[q[13]||(q[13]=r("span",{class:"text-gray-300 dark:text-gray-600"},"·",-1)),r("span",EP,d(o(t)("settings.api.dataSources.lastSync"))+": "+d(R(Ce.lastPullAt)),1),Ce.lastStatus==="success"?(b(),A("span",RP," (+"+d(Ce.lastNewMessages)+") ",1)):ne("",!0),Ce.lastStatus==="error"?(b(),A("span",NP,d(Ce.lastError),1)):ne("",!0)],64)):ne("",!0)])]))),128))])):(b(),A("div",FP,d(o(t)("settings.api.dataSources.noSessions")),1))]))),128))])):(b(),A("div",UP,d(o(t)("settings.api.dataSources.empty")),1)),v(U,{variant:"soft",onClick:q[1]||(q[1]=Z=>E.value=!0)},{default:re(()=>[v(ue,{name:"i-heroicons-plus",class:"mr-2 h-4 w-4"}),J(" "+d(o(t)("settings.api.dataSources.addBtn")),1)]),_:1})])])):ne("",!0),C.value==="api"?(b(),A(Me,{key:1},[o(S)?(b(),A("div",OP,[r("h3",HP,[v(ue,{name:"i-heroicons-server-stack",class:"h-4 w-4 text-blue-500"}),J(" "+d(o(t)("settings.api.service.title")),1)]),r("div",VP,[r("div",zP,[q[14]||(q[14]=r("span",{class:"inline-block h-2 w-2 rounded-full bg-green-500"},null,-1)),r("span",BP,d(o(t)("settings.api.status.running")),1)]),r("div",WP,[r("div",jP,[r("span",null,d(o(t)("settings.api.port.label")),1),r("span",qP,d(o(a).port||"-"),1)]),o(a).token?(b(),A("div",KP,[r("span",null,d(o(t)("settings.api.token.label")),1),r("div",GP,[r("code",XP,d(g.value?o(a).token:X.value),1),v(U,{size:"xs",variant:"ghost",onClick:q[2]||(q[2]=Z=>g.value=!g.value)},{default:re(()=>[v(ue,{name:g.value?"i-heroicons-eye-slash":"i-heroicons-eye",class:"h-3.5 w-3.5"},null,8,["name"])]),_:1}),v(U,{size:"xs",variant:"ghost",onClick:W},{default:re(()=>[v(ue,{name:T.value?"i-heroicons-check":"i-heroicons-clipboard",class:"h-3.5 w-3.5"},null,8,["name"])]),_:1})])])):ne("",!0)])])])):(b(),A(Me,{key:1},[r("div",null,[r("h3",YP,[v(ue,{name:"i-heroicons-server-stack",class:"h-4 w-4 text-blue-500"}),J(" "+d(o(t)("settings.api.service.title")),1)]),r("div",QP,[r("div",JP,[r("div",ZP,[r("p",eD,d(o(t)("settings.api.service.enable")),1),r("p",tD,d(o(t)("settings.api.service.enableDesc")),1)]),v(K,{"model-value":o(a).enabled,loading:o(c),"onUpdate:modelValue":L},null,8,["model-value","loading"])]),o(a).enabled?(b(),A("div",sD,[r("span",{class:we(["inline-block h-2 w-2 rounded-full",o(l)?"bg-green-500":o(m)?"bg-red-500":"bg-gray-400"])},null,2),r("span",{class:we(["text-xs",F.value])},d(le.value),3),o(l)&&o(i).port?(b(),A("span",aD,d(_.value),1)):ne("",!0)])):ne("",!0),o(u)?(b(),A("div",nD,d(o(t)("settings.api.service.portInUseHint")),1)):ne("",!0)])]),r("div",null,[r("h3",oD,[v(ue,{name:"i-heroicons-globe-alt",class:"h-4 w-4 text-purple-500"}),J(" "+d(o(t)("settings.api.port.title")),1)]),r("div",rD,[r("div",iD,[r("div",lD,[r("p",cD,d(o(t)("settings.api.port.label")),1),r("p",dD,d(o(t)("settings.api.port.desc")),1)]),p.value?(b(),A("div",uD,[v(Ie,{modelValue:k.value,"onUpdate:modelValue":q[3]||(q[3]=Z=>k.value=Z),modelModifiers:{number:!0},type:"number",min:1024,max:65535,size:"sm",class:"w-24"},null,8,["modelValue"]),v(U,{size:"xs",color:"primary",loading:o(c),onClick:$},{default:re(()=>[J(d(o(t)("settings.api.port.save")),1)]),_:1},8,["loading"]),v(U,{size:"xs",variant:"ghost",onClick:ce},{default:re(()=>[J(d(o(t)("settings.api.port.cancel")),1)]),_:1})])):(b(),A("div",mD,[r("span",gD,d(o(a).port),1),v(U,{size:"xs",variant:"ghost",onClick:z},{default:re(()=>[J(d(o(t)("settings.api.port.edit")),1)]),_:1})]))])])]),r("div",null,[r("h3",pD,[v(ue,{name:"i-heroicons-key",class:"h-4 w-4 text-amber-500"}),J(" "+d(o(t)("settings.api.token.title")),1)]),r("div",fD,[r("p",hD,d(o(t)("settings.api.token.label")),1),r("p",vD,d(o(t)("settings.api.token.desc")),1),o(a).token?(b(),A("div",yD,[r("code",bD,d(g.value?o(a).token:X.value),1),v(U,{size:"xs",variant:"ghost",onClick:q[4]||(q[4]=Z=>g.value=!g.value)},{default:re(()=>[v(ue,{name:g.value?"i-heroicons-eye-slash":"i-heroicons-eye",class:"h-4 w-4"},null,8,["name"])]),_:1}),v(U,{size:"xs",variant:"ghost",onClick:W},{default:re(()=>[v(ue,{name:T.value?"i-heroicons-check":"i-heroicons-clipboard",class:"h-4 w-4"},null,8,["name"])]),_:1})])):(b(),A("div",_D,d(o(t)("settings.api.token.noToken")),1)),r("div",xD,[v(U,{variant:"soft",color:"warning",onClick:se},{default:re(()=>[v(ue,{name:"i-heroicons-arrow-path",class:"mr-1 h-4 w-4"}),J(" "+d(o(t)("settings.api.token.regenerate")),1)]),_:1})]),r("div",kD,[r("p",wD,d(o(t)("settings.api.usage.authHint")),1),r("div",SD," Authorization: Bearer "+d(o(a).token?X.value:"clb_..."),1)])])])],64)),r("div",null,[r("h3",CD,[v(ue,{name:"i-heroicons-book-open",class:"h-4 w-4 text-teal-500"}),J(" "+d(o(t)("settings.api.usage.title")),1)]),r("div",MD,[r("p",AD,d(o(t)("settings.api.usage.desc")),1),r("a",{href:y.value,target:"_blank",class:"mt-2 inline-flex items-center gap-1 text-xs text-blue-500 hover:text-blue-600 dark:text-blue-400 dark:hover:text-blue-300"},[v(ue,{name:"i-heroicons-arrow-top-right-on-square",class:"h-3.5 w-3.5"}),J(" "+d(o(t)("settings.api.usage.docLink")),1)],8,TD)])])],64)):ne("",!0),C.value==="mcp"?(b(),xe(dP,{key:2})):ne("",!0)])]),v(Bn,{open:E.value,"onUpdate:open":q[5]||(q[5]=Z=>E.value=Z),onSourceAdded:q[6]||(q[6]=Z=>o(n).fetchDataSources())},null,8,["open"]),v(NI,{open:I.value,"onUpdate:open":q[7]||(q[7]=Z=>I.value=Z),"data-source":N.value,onSaved:me},null,8,["open","data-source"]),V.value?(b(),xe(Bn,{key:0,open:ee.value,"onUpdate:open":q[8]||(q[8]=Z=>ee.value=Z),"manage-source":V.value,"subscribed-remote-ids":oe(V.value),onSessionsAdded:he},null,8,["open","manage-source","subscribed-remote-ids"])):ne("",!0),v(Te,{open:ie.value,"onUpdate:open":q[10]||(q[10]=Z=>ie.value=Z),ui:{content:"z-[101]",overlay:"z-[100]"}},{content:re(()=>[r("div",$D,[r("h3",ID,d(o(t)("settings.api.dataSources.deleteConfirm.title")),1),r("p",PD,d(o(t)("settings.api.dataSources.deleteConfirm.message",{name:Q.value?.baseUrl})),1),r("div",DD,[v(U,{variant:"soft",onClick:q[9]||(q[9]=Z=>ie.value=!1)},{default:re(()=>[J(d(o(t)("common.cancel")),1)]),_:1}),v(U,{color:"error",onClick:_e},{default:re(()=>[J(d(o(t)("common.delete")),1)]),_:1})])])]),_:1},8,["open"]),v(Te,{open:Y.value,"onUpdate:open":q[12]||(q[12]=Z=>Y.value=Z),ui:{content:"z-[101]",overlay:"z-[100]"}},{content:re(()=>[r("div",LD,[r("h3",ED,d(o(t)("settings.api.dataSources.deleteSessionConfirm.title")),1),r("p",RD,d(o(t)("settings.api.dataSources.deleteSessionConfirm.message",{name:H.value?.sess.name})),1),r("div",ND,[v(U,{variant:"soft",onClick:q[11]||(q[11]=Z=>Y.value=!1)},{default:re(()=>[J(d(o(t)("common.cancel")),1)]),_:1}),v(U,{variant:"soft",onClick:Le},{default:re(()=>[J(d(o(t)("settings.api.dataSources.deleteSessionConfirm.keepData")),1)]),_:1}),v(U,{color:"error",onClick:Ae},{default:re(()=>[J(d(o(t)("settings.api.dataSources.deleteSessionConfirm.deleteData")),1)]),_:1})])])]),_:1},8,["open"])])}}}),UD={class:"flex min-h-[650px] h-[85vh] flex-col overflow-hidden"},OD={class:"shrink-0 border-b border-gray-200 px-6 pt-5 pb-0 dark:border-gray-800"},HD={class:"flex items-center justify-between"},VD={class:"flex items-center gap-3"},zD={class:"flex h-8 w-8 items-center justify-center rounded-lg bg-primary-600 dark:bg-primary-500"},BD={class:"text-lg font-semibold text-gray-900 dark:text-white"},WD={class:"mt-4 flex items-center gap-1 overflow-x-auto pb-3 scrollbar-hide"},jD=["onClick"],qD={class:"whitespace-nowrap"},KD={class:"relative flex-1"},GD={class:"absolute inset-0 p-6"},XD={key:"settings",class:"h-full overflow-y-auto"},YD={key:"about",class:"h-full overflow-y-auto"},QD=$e({__name:"SettingsModal",setup(e){const{t}=Re(),s=Ls(),n=$t(),{showSettings:a,settingsTab:i,settingsSubTab:c}=Ge(n),l=G(()=>[{id:"settings",label:t("settings.tabs.basic"),icon:"i-heroicons-cog-6-tooth"},{id:"ai",label:t("settings.tabs.ai"),icon:"i-heroicons-sparkles"},{id:"api",label:t("settings.tabs.api"),icon:"i-heroicons-server-stack"},{id:"data",label:t("settings.tabs.dataManage"),icon:"i-heroicons-rectangle-stack"},{id:"storage",label:t("settings.tabs.storage"),icon:"i-heroicons-folder-open"},{id:"about",label:t("settings.tabs.about"),icon:"i-heroicons-information-circle"}]),m=P("settings"),u=P({});function f(C,D){u.value[C]=D}function h(){s.notifyAIConfigChanged()}function x(C){m.value=C,Xe(()=>{u.value[C]?.refresh?.()})}function S(C){const D=u.value[m.value];D?.scrollToSection&&D.scrollToSection(C)}return Ne(a,async C=>{C&&(m.value=i.value||"settings",c.value&&(await Xe(),setTimeout(()=>S(c.value),100)),Xe(()=>{u.value[m.value]?.refresh?.()}))}),(C,D)=>{const M=Ve,g=We,p=ht;return b(),xe(p,{open:o(a),"onUpdate:open":D[1]||(D[1]=k=>Je(a)?a.value=k:null),ui:{content:"sm:max-w-[900px] z-[100]",overlay:"backdrop-blur-sm z-[99]"}},{content:re(()=>[r("div",UD,[r("div",OD,[r("div",HD,[r("div",VD,[r("div",zD,[v(M,{name:"i-heroicons-cog-6-tooth",class:"h-4 w-4 text-white"})]),r("h2",BD,d(o(t)("settings.title")),1)]),v(g,{icon:"i-heroicons-x-mark",color:"neutral",variant:"ghost",size:"sm",onClick:D[0]||(D[0]=k=>o(n).closeSettings())})]),r("div",WD,[(b(!0),A(Me,null,Be(l.value,k=>(b(),A("button",{key:k.id,class:we(["flex items-center gap-2 rounded-lg px-3 py-2 text-sm font-medium transition-all",[m.value===k.id?"bg-pink-500 text-white dark:bg-pink-900/30 dark:text-pink-300":"text-gray-600 hover:bg-gray-100 dark:text-gray-400 dark:hover:bg-gray-800"]]),onClick:T=>x(k.id)},[v(M,{name:k.icon,class:"h-4 w-4"},null,8,["name"]),r("span",qD,d(k.label),1)],10,jD))),128))])]),r("div",KD,[r("div",GD,[v(fa,{name:"tab-slide",mode:"out-in"},{default:re(()=>[m.value==="settings"?(b(),A("div",XD,[v(vA)])):m.value==="ai"?(b(),xe(eM,{key:"ai",ref:k=>f("ai",k),onConfigChanged:h},null,512)):m.value==="data"?(b(),xe(bT,{key:"data"})):m.value==="api"?(b(),xe(FD,{key:"api"})):m.value==="storage"?(b(),xe(y$,{key:"storage",ref:k=>f("storage",k)},null,512)):m.value==="about"?(b(),A("div",YD,[v(F$)])):ne("",!0)]),_:1})])])])]),_:1},8,["open"])}}}),JD=Gt(QD,[["__scopeId","data-v-a4459b10"]]),ZD={class:"border-b border-gray-200 px-4 py-3 dark:border-gray-800"},e2={class:"flex items-center gap-3"},t2={class:"flex items-center gap-2"},s2={class:"mt-2 flex items-center gap-3"},a2={class:"flex gap-2"},n2=$e({__name:"FilterPanel",props:{query:{}},emits:["apply","reset"],setup(e,{emit:t}){const{t:s}=Re(),n=e,a=t,i=P({messageId:"",memberName:"",keywords:"",startDate:"",endDate:""});Ne(()=>n.query,u=>{u&&(i.value={messageId:u.scrollToMessageId?.toString()||"",memberName:u.memberName||"",keywords:u.keywords?.join(", ")||"",startDate:u.startTs?ot.unix(u.startTs).format("YYYY-MM-DD"):"",endDate:u.endTs?ot.unix(u.endTs).format("YYYY-MM-DD"):""})},{immediate:!0});function c(){const u=i.value,f={},h=u.keywords&&u.keywords.trim();if(u.messageId&&!h){const x=parseInt(u.messageId,10);isNaN(x)||(f.scrollToMessageId=x)}if(u.memberName&&(f.memberName=u.memberName),h){const x=u.keywords.split(/[,,]/).map(S=>S.trim()).filter(S=>S);x.length>0&&(f.keywords=x,f.highlightKeywords=x,i.value.messageId="")}u.startDate&&(f.startTs=ot(u.startDate).startOf("day").unix()),u.endDate&&(f.endTs=ot(u.endDate).endOf("day").unix()),a("apply",f)}function l(u){u.key==="Enter"&&(u.preventDefault(),c())}function m(){i.value={messageId:"",memberName:"",keywords:"",startDate:"",endDate:""},a("reset")}return(u,f)=>{const h=lt,x=We;return b(),A("div",ZD,[r("div",e2,[v(h,{modelValue:i.value.messageId,"onUpdate:modelValue":f[0]||(f[0]=S=>i.value.messageId=S),type:"number",placeholder:o(s)("records.filter.messageId"),size:"sm",class:"w-24"},null,8,["modelValue","placeholder"]),v(h,{modelValue:i.value.memberName,"onUpdate:modelValue":f[1]||(f[1]=S=>i.value.memberName=S),placeholder:o(s)("records.filter.memberNotSupported"),size:"sm",class:"w-28",disabled:""},null,8,["modelValue","placeholder"]),r("div",t2,[v(o(Vn),{modelValue:i.value.startDate,"onUpdate:modelValue":f[2]||(f[2]=S=>i.value.startDate=S),placeholder:o(s)("records.filter.startDate")},null,8,["modelValue","placeholder"]),f[5]||(f[5]=r("span",{class:"text-xs text-gray-400"},"~",-1)),v(o(Vn),{modelValue:i.value.endDate,"onUpdate:modelValue":f[3]||(f[3]=S=>i.value.endDate=S),placeholder:o(s)("records.filter.endDate")},null,8,["modelValue","placeholder"])])]),r("div",s2,[v(h,{modelValue:i.value.keywords,"onUpdate:modelValue":f[4]||(f[4]=S=>i.value.keywords=S),placeholder:o(s)("records.filter.keywordsPlaceholder"),size:"sm",class:"flex-1",onKeydown:l},null,8,["modelValue","placeholder"]),r("div",a2,[v(x,{color:"neutral",variant:"ghost",size:"sm",onClick:m},{default:re(()=>[J(d(o(s)("records.filter.reset")),1)]),_:1}),v(x,{color:"primary",size:"sm",onClick:c},{default:re(()=>[J(d(o(s)("records.filter.filter")),1)]),_:1})])])])}}}),o2=["src","alt"],r2={key:1},i2={key:0,class:"mb-2 border-l-2 border-pink-400 dark:border-pink-500 pl-2.5 py-1 text-xs text-gray-500 dark:text-gray-400 bg-gray-500/5 dark:bg-white/5 rounded-r"},l2={class:"font-medium text-gray-600 dark:text-gray-300"},c2={key:0,class:"ml-1 font-semibold text-gray-700 dark:text-gray-200"},d2={key:1,class:"mt-1 line-clamp-2 italic text-gray-500 dark:text-gray-400 leading-normal"},u2=["innerHTML"],m2=["title"],g2=$e({__name:"MessageItem",props:{message:{},isTarget:{type:Boolean},highlightKeywords:{},isFiltered:{type:Boolean}},emits:["view-context"],setup(e,{emit:t}){const{t:s}=Re(),n=e,a=ut(),i=G(()=>{const D=a.currentSession?.ownerId;return D?n.message.senderPlatformId===D:!1}),c=G(()=>{const D=n.message.senderName||"";let M=0;for(let g=0;g<D.length;g++)M=D.charCodeAt(g)+((M<<5)-M);return Math.abs(M)%16}),l=[{avatar:"bg-rose-400 dark:bg-rose-500",name:"text-rose-600 dark:text-rose-400"},{avatar:"bg-pink-400 dark:bg-pink-500",name:"text-pink-600 dark:text-pink-400"},{avatar:"bg-fuchsia-400 dark:bg-fuchsia-500",name:"text-fuchsia-600 dark:text-fuchsia-400"},{avatar:"bg-purple-400 dark:bg-purple-500",name:"text-purple-600 dark:text-purple-400"},{avatar:"bg-violet-400 dark:bg-violet-500",name:"text-violet-600 dark:text-violet-400"},{avatar:"bg-indigo-400 dark:bg-indigo-500",name:"text-indigo-600 dark:text-indigo-400"},{avatar:"bg-blue-400 dark:bg-blue-500",name:"text-blue-600 dark:text-blue-400"},{avatar:"bg-sky-400 dark:bg-sky-500",name:"text-sky-600 dark:text-sky-400"},{avatar:"bg-cyan-400 dark:bg-cyan-500",name:"text-cyan-600 dark:text-cyan-400"},{avatar:"bg-teal-400 dark:bg-teal-500",name:"text-teal-600 dark:text-teal-400"},{avatar:"bg-emerald-400 dark:bg-emerald-500",name:"text-emerald-600 dark:text-emerald-400"},{avatar:"bg-green-400 dark:bg-green-500",name:"text-green-600 dark:text-green-400"},{avatar:"bg-lime-500 dark:bg-lime-600",name:"text-lime-600 dark:text-lime-400"},{avatar:"bg-amber-400 dark:bg-amber-500",name:"text-amber-600 dark:text-amber-400"},{avatar:"bg-orange-400 dark:bg-orange-500",name:"text-orange-600 dark:text-orange-400"},{avatar:"bg-red-400 dark:bg-red-500",name:"text-red-600 dark:text-red-400"}],m=G(()=>l[c.value]),u=G(()=>m.value.avatar),f=G(()=>m.value.name),h=G(()=>i.value?"bg-pink-50/80 dark:bg-pink-950/20":"bg-gray-100/80 dark:bg-gray-800/80"),x=G(()=>{const D=n.message.senderName||"",M=n.message.senderAliases||[];return M.length>0?`${D}(${M[0]})`:D}),S=G(()=>{const D=n.message.senderName||"";if(!D)return"?";try{const g=[...new Intl.Segmenter("zh",{granularity:"grapheme"}).segment(D)];if(g.length>0)return g[0].segment}catch{const M=[...D];if(M.length>0){const g=M[0];return/^[a-zA-Z]$/.test(g)?g.toUpperCase():g}}return"?"});function C(D){if(!n.highlightKeywords?.length||!D)return D;const M=n.highlightKeywords.map(p=>p.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")).join("|"),g=new RegExp(`(${M})`,"gi");return D.replace(g,'<mark class="bg-transparent border-b-2 border-yellow-400 dark:border-yellow-500">$1</mark>')}return(D,M)=>{const g=Ve;return b(),A("div",{class:we(["group px-4 py-2.5 transition-all duration-300",[e.isTarget?"bg-amber-500/5 dark:bg-amber-500/10":"hover:bg-gray-50/40 dark:hover:bg-gray-900/10"]])},[r("div",{class:we(["flex gap-3",i.value?"flex-row-reverse":""])},[r("div",{class:we(["flex h-9 w-9 shrink-0 items-center justify-center rounded-lg text-sm font-medium text-white overflow-hidden",e.message.senderAvatar?"":u.value])},[e.message.senderAvatar?(b(),A("img",{key:0,src:e.message.senderAvatar,alt:e.message.senderName,class:"h-full w-full object-cover"},null,8,o2)):(b(),A("span",r2,d(S.value),1))],2),r("div",{class:we(["min-w-0 flex-1",i.value?"flex flex-col items-end":""])},[r("div",{class:we(["mb-1 flex items-center gap-2",i.value?"flex-row-reverse":""])},[r("span",{class:we(["text-sm font-medium",f.value])},d(x.value),3)],2),r("div",{class:we(["flex items-start gap-1 max-w-[calc(100%-68px)]",i.value?"flex-row-reverse":""])},[r("div",{class:we(["relative inline-block rounded-2xl px-3.5 py-2.5 transition-all duration-300 border border-gray-100 dark:border-gray-800/40",[h.value,e.isTarget?"ring-2 ring-amber-400 dark:ring-amber-500":""]])},[e.message.replyToMessageId?(b(),A("div",i2,[r("span",l2,d(o(s)("records.messageItem.replyTo")),1),e.message.replyToSenderName?(b(),A("span",c2,d(e.message.replyToSenderName),1)):ne("",!0),e.message.replyToContent?(b(),A("p",d2,d(e.message.replyToContent),1)):ne("",!0)])):ne("",!0),r("p",{class:"whitespace-pre-wrap break-all text-sm text-gray-700 dark:text-gray-200",innerHTML:C(e.message.content||"")},null,8,u2)],2),e.isFiltered?(b(),A("button",{key:0,class:"mt-1 flex h-6 w-6 items-center justify-center rounded-lg opacity-0 transition-all duration-200 hover:bg-gray-100 dark:hover:bg-gray-800 hover:text-pink-500 dark:hover:text-pink-400 active:scale-95 group-hover:opacity-100 cursor-pointer",title:o(s)("records.messageItem.viewContext"),onClick:M[0]||(M[0]=p=>D.$emit("view-context",e.message.id))},[v(g,{name:"i-heroicons-chat-bubble-left-ellipsis",class:"h-4 w-4"})],8,m2)):ne("",!0)],2)],2)],2)],2)}}}),p2={class:"flex h-full flex-col overflow-hidden"},f2={key:0,class:"flex h-full items-center justify-center"},h2={class:"text-center"},v2={class:"mt-2 text-sm text-gray-500"},y2={key:1,class:"flex h-full items-center justify-center"},b2={class:"text-center"},_2={class:"mt-2 text-sm text-gray-500"},x2={class:"mt-1 text-xs text-gray-400"},k2={key:0,class:"flex justify-center py-2"},w2={key:0,class:"text-xs text-gray-400"},S2={key:1,class:"text-xs text-gray-400"},C2=["data-index"],M2={key:0,class:"flex items-center justify-center py-2"},A2={class:"flex items-center gap-2 text-xs text-gray-400"},T2={key:1,class:"flex justify-center py-2"},$2={key:0,class:"text-xs text-gray-400"},I2={key:1,class:"text-xs text-gray-400"},P2=300,Wn=80,D2=$e({__name:"MessageList",props:{query:{},externalMessages:{default:void 0},hitMessageIds:{default:()=>[]},externalScrollBehavior:{default:"top"}},emits:["count-change","visible-message-change","jump-to-message","reach-bottom","reach-top","message-timestamps-change"],setup(e,{expose:t,emit:s}){const{t:n}=Re(),a=e,i=s,c=ut(),l=G(()=>!!a.externalMessages?.length),m=G(()=>{if(l.value)return!1;const z=a.query;return!!(z.memberId||z.keywords?.length)}),u=P([]),f=P(!1),h=P(!1),x=P(!1),S=P(!1),C=P(!1),D=P(0),M=P(null),g=P(null),p=to(G(()=>({count:u.value.length,getScrollElement:()=>M.value,estimateSize:()=>Wn,overscan:10,getItemKey:z=>u.value[z]?.id??z}))),k=G(()=>p.value.getVirtualItems()),T=G(()=>p.value.getTotalSize());function E(z){return{filter:z.startTs||z.endTs?{startTs:z.startTs,endTs:z.endTs}:void 0,senderId:z.memberId,keywords:z.keywords?[...Ct(z.keywords)]:void 0}}function I(z){return z.map(ce=>({...ce,replyToMessageId:ce.replyToMessageId??null,replyToContent:ce.replyToContent??null,replyToSenderName:ce.replyToSenderName??null}))}let N=0;async function ee(){if(l.value){const ce=a.externalMessages.length,W=N>0&&ce>N;u.value=a.externalMessages,x.value=!1,S.value=!1,C.value=!1,i("count-change",u.value.length),N=ce,await Xe(),a.externalScrollBehavior==="preserve"&&W||V();return}const z=c.currentSessionId;if(!z){u.value=[],i("count-change",0);return}f.value=!0,u.value=[],g.value=null;try{const ce=Ct(a.query),{filter:W,senderId:se,keywords:pe}=E(ce),me=ce.scrollToMessageId;if(me){const he=Ot(),[ke,ve]=await Promise.all([he.getMessagesBefore(z,me,50,W,se,pe),he.getMessagesAfter(z,me,50,W,se,pe)]),_e=await he.getMessageContext(z,me,0);u.value=I([...ke.messages,..._e,...ve.messages]),x.value=ke.hasMore,S.value=ve.hasMore,g.value=me}else if(pe&&pe.length>0){C.value=!0,D.value=0;const he=await Ot().searchMessages(z,pe,W,100,0,se);u.value=I(he.messages),x.value=!1,S.value=he.messages.length>=100,D.value=he.messages.length,await Xe(),V()}else{C.value=!1,D.value=0;const he=await Ot().getAllRecentMessages(z,W,100);u.value=I(he.messages),x.value=he.messages.length>=100,S.value=!1,await Xe(),setTimeout(()=>{ie()},50)}i("count-change",u.value.length);const ae=u.value.map(he=>he.timestamp);i("message-timestamps-change",ae),g.value&&(await Xe(),setTimeout(()=>{g.value&&(H(g.value),g.value=null)},100))}catch(ce){console.error("加载消息失败:",ce),u.value=[],i("count-change",0)}finally{f.value=!1}}function V(){p.value.scrollToOffset(0)}function ie(){u.value.length!==0&&(p.value.scrollToIndex(u.value.length-1,{align:"end"}),requestAnimationFrame(()=>{const z=M.value;z&&(z.scrollTop=z.scrollHeight)}))}async function Q(){if(h.value||!x.value||u.value.length===0)return;const z=c.currentSessionId;if(!z)return;const ce=u.value[0];if(ce){h.value=!0;try{const W=Ct(a.query),{filter:se,senderId:pe,keywords:me}=E(W),ae=await Ot().getMessagesBefore(z,ce.id,50,se,pe,me);if(ae.messages.length>0){const he=p.value.scrollOffset??0,ke=[...I(ae.messages),...u.value];u.value=ke,await Xe();const _e=ae.messages.length*Wn;p.value.scrollToOffset(he+_e),i("count-change",u.value.length),i("message-timestamps-change",u.value.map(be=>be.timestamp))}x.value=ae.hasMore}catch(W){console.error("加载更早消息失败:",W)}finally{h.value=!1}}}async function Y(){if(h.value||!S.value||u.value.length===0)return;const z=c.currentSessionId;if(z){h.value=!0;try{const ce=Ct(a.query),{filter:W,senderId:se,keywords:pe}=E(ce);if(C.value&&pe&&pe.length>0){const me=await Ot().searchMessages(z,pe,W,50,D.value,se);me.messages.length>0&&(u.value=[...u.value,...I(me.messages)],D.value+=me.messages.length,i("count-change",u.value.length),i("message-timestamps-change",u.value.map(ae=>ae.timestamp))),S.value=me.messages.length>=50}else{const me=u.value[u.value.length-1];if(!me)return;const ae=await Ot().getMessagesAfter(z,me.id,50,W,se,pe);ae.messages.length>0&&(u.value=[...u.value,...I(ae.messages)],i("count-change",u.value.length),i("message-timestamps-change",u.value.map(he=>he.timestamp))),S.value=ae.hasMore}}catch(ce){console.error("加载更多消息失败:",ce)}finally{h.value=!1}}}function H(z){const ce=u.value.findIndex(W=>W.id===z);ce!==-1&&p.value.scrollToIndex(ce,{align:"center"})}function B(){const z=M.value;if(!z)return;const ce=z.scrollHeight-z.scrollTop-z.clientHeight;l.value&&(z.scrollTop<50&&i("reach-top"),ce<50&&i("reach-bottom")),!l.value&&!h.value&&(z.scrollTop<100&&x.value&&Q(),ce<100&&S.value&&Y()),le()}let j=null,X=0;function le(){j||(j=setTimeout(()=>{j=null,F()},150))}function F(){const z=k.value;if(z.length===0)return;const ce=Math.floor(z.length/2),W=z[ce];if(!W)return;const se=u.value[W.index];se&&se.id!==X&&(X=se.id,i("visible-message-change",{id:se.id,timestamp:se.timestamp}))}function _(z){return l.value&&a.hitMessageIds?.length?a.hitMessageIds.includes(z):z===a.query.scrollToMessageId}function y(z){const ce=u.value[z];if(!ce)return null;const W=z>0?u.value[z-1]:null;if(!W)return L(ce.timestamp);const se=ce.timestamp,pe=W.timestamp,me=se-pe,ae=ot.unix(se).startOf("day"),he=ot.unix(pe).startOf("day");return!ae.isSame(he)||me>=P2?L(se):null}function L(z){const ce=ot.unix(z),W=ot().startOf("day");return ce.isSame(W,"day")?ce.format("HH:mm"):ce.format("YYYY-MM-DD HH:mm")}function $(z){z&&p.value.measureElement(z)}return Ne(()=>a.query,()=>{l.value||ee()},{deep:!0}),Ne(()=>a.externalMessages,()=>{l.value&&ee()},{deep:!0,immediate:!0}),qt(()=>{j&&(clearTimeout(j),j=null)}),t({refresh:ee,scrollToMessage:H}),(z,ce)=>{const W=Ve;return b(),A("div",p2,[f.value?(b(),A("div",f2,[r("div",h2,[v(W,{name:"i-heroicons-arrow-path",class:"h-8 w-8 animate-spin text-gray-400"}),r("p",v2,d(o(n)("records.messageList.loading")),1)])])):u.value.length===0?(b(),A("div",y2,[r("div",b2,[v(W,{name:"i-heroicons-chat-bubble-left-right",class:"h-12 w-12 text-gray-300 dark:text-gray-600"}),r("p",_2,d(o(n)("records.messageList.noMessages")),1),r("p",x2,d(o(n)("records.messageList.tryAdjustFilter")),1)])])):(b(),A("div",{key:2,ref_key:"scrollContainerRef",ref:M,class:"h-full overflow-y-auto",onScroll:B},[x.value?(b(),A("div",k2,[h.value?(b(),A("span",w2,[v(W,{name:"i-heroicons-arrow-path",class:"mr-1 inline h-3 w-3 animate-spin"}),J(" "+d(o(n)("records.messageList.loadingMore")),1)])):(b(),A("span",S2,d(o(n)("records.messageList.scrollUpForMore")),1))])):ne("",!0),r("div",{class:"relative w-full",style:Jt({height:`${T.value}px`})},[(b(!0),A(Me,null,Be(k.value,se=>(b(),A("div",{key:String(se.key),ref_for:!0,ref:pe=>$(pe),class:"absolute left-0 top-0 w-full",style:Jt({transform:`translateY(${se.start}px)`}),"data-index":se.index},[y(se.index)?(b(),A("div",M2,[r("div",A2,[ce[1]||(ce[1]=r("div",{class:"h-px w-8 bg-gray-200 dark:bg-gray-700"},null,-1)),r("span",null,d(y(se.index)),1),ce[2]||(ce[2]=r("div",{class:"h-px w-8 bg-gray-200 dark:bg-gray-700"},null,-1))])])):ne("",!0),v(g2,{"data-message-id":u.value[se.index]?.id,message:u.value[se.index],"is-target":_(u.value[se.index]?.id??0),"highlight-keywords":e.query.highlightKeywords,"is-filtered":m.value,onViewContext:ce[0]||(ce[0]=pe=>i("jump-to-message",pe))},null,8,["data-message-id","message","is-target","highlight-keywords","is-filtered"])],12,C2))),128))],4),S.value?(b(),A("div",T2,[h.value?(b(),A("span",$2,[v(W,{name:"i-heroicons-arrow-path",class:"mr-1 inline h-3 w-3 animate-spin"}),J(" "+d(o(n)("records.messageList.loadingMore")),1)])):(b(),A("span",I2,d(o(n)("records.messageList.scrollDownForMore")),1))])):ne("",!0)],544))])}}});function L2(e){e.value=!0}function E2(e,t,s,n){return[e,t,s,!1,n]}const R2={class:"flex items-center justify-between"},N2={class:"text-lg font-semibold"},F2={class:"space-y-4"},U2={class:"flex gap-2 border-b border-gray-200 dark:border-gray-700 pb-3"},O2={key:0},H2={class:"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2"},V2={class:"space-y-3"},z2={class:"flex items-center gap-4"},B2={class:"text-lg font-semibold text-primary-600 dark:text-primary-400 min-w-[4rem] text-right"},W2={class:"text-xs text-gray-500 flex justify-between"},j2={key:0},q2={key:1},K2={class:"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2"},G2={class:"flex flex-wrap gap-2"},X2={key:0,class:"mt-3 flex items-center gap-2"},Y2={key:2,class:"text-sm text-gray-600 dark:text-gray-400"},Q2={key:0,class:"text-gray-500"},J2={key:0,class:"text-green-600 dark:text-green-400"},Z2={key:2,class:"text-gray-400"},eL={key:0,class:"mt-1 font-medium"},tL={key:1,class:"mt-1 text-gray-400"},sL={key:1,class:"text-gray-400"},aL={key:3,class:"flex items-center gap-2 text-sm text-gray-500"},nL={key:4,class:"flex items-center gap-2 text-sm text-gray-500"},oL={key:5,class:"space-y-2"},rL={class:"flex items-center justify-between text-sm"},iL={key:1,class:"h-2 w-full rounded-full bg-green-500"},lL={class:"flex items-center gap-2"},cL={class:"flex-1 font-medium"},dL={key:0,class:"pl-6 text-xs text-gray-600 dark:text-gray-400 line-clamp-2"},uL={key:1,class:"pl-6 text-xs text-red-500"},mL={key:2,class:"pl-6 text-xs text-gray-400 italic"},gL={key:7,class:"flex items-center gap-4 text-sm"},pL={class:"text-green-600 dark:text-green-400"},fL={key:0,class:"text-red-600 dark:text-red-400"},hL={key:1,class:"text-gray-500"},vL={class:"flex justify-end gap-2"},yL=$e({__name:"BatchSummaryModal",props:{open:{type:Boolean},sessionId:{}},emits:["update:open","completed"],setup(e,{emit:t}){const s=e,n=t,{t:a,locale:i}=Re(),c=G({get:()=>s.open,set:y=>n("update:open",y)}),l=P("range"),m=P(50),u=P(0),f=P("today"),h=P(""),x=P(""),S=P([]),C=P(!1),D=P(!1),M=P(0),g=P(0),p=P([]),k=P(!1);function T(y){return y.includes("少于3条")||y.includes("less than 3")||y.includes("无需生成摘要")}const E=P(null),I=G(()=>{const y=new Date,L=new Date(y.getFullYear(),y.getMonth(),y.getDate());switch(f.value){case"today":return{start:L.getTime(),end:y.getTime()};case"yesterday":{const $=new Date(L);return $.setDate($.getDate()-1),{start:$.getTime(),end:L.getTime()-1}}case"week":{const $=new Date(L);return $.setDate($.getDate()-7),{start:$.getTime(),end:y.getTime()}}case"month":{const $=new Date(L);return $.setMonth($.getMonth()-1),{start:$.getTime(),end:y.getTime()}}case"custom":if(h.value&&x.value){const $=new Date(h.value),z=new Date(x.value);return{start:$.getTime(),end:new Date(z.getTime()+1440*60*1e3-1).getTime()}}return null;default:return null}}),N=P({}),ee=P(!1),V=G(()=>S.value.filter(y=>y.summary?!1:N.value[y.id]?.canGenerate!==!1)),ie=G(()=>S.value.filter(y=>y.summary).length),Q=G(()=>S.value.filter(y=>y.summary?!1:N.value[y.id]?.canGenerate===!1).length),Y=G(()=>g.value===0?100:Math.round(M.value/g.value*100)),H=G(()=>{const y=p.value.filter(z=>z.status==="success").length,L=p.value.filter(z=>z.status==="failed").length,$=p.value.filter(z=>z.status==="skipped").length;return{success:y,failed:L,skipped:$}});async function B(){C.value=!0,N.value={};try{if(l.value==="range"){const y=await tt().getSessions(s.sessionId);u.value=y.length;const L=Math.ceil(y.length*(m.value/100));S.value=y.slice(-L)}else{if(!I.value){S.value=[];return}const y=Math.floor(I.value.start/1e3),L=Math.floor(I.value.end/1e3);S.value=await tt().getByTimeRange(s.sessionId,y,L)}S.value.length>0&&await j()}catch(y){console.error("查询会话失败:",y),S.value=[]}finally{C.value=!1}}async function j(){const y=S.value.filter(L=>!L.summary).map(L=>L.id);if(y.length!==0){ee.value=!0;try{N.value=await tt().checkCanGenerateSummary(s.sessionId,y)}catch(L){console.error("检查会话摘要失败:",L)}finally{ee.value=!1}}}const X=lM(()=>{B()},300);Ne(()=>[l.value,f.value,h.value,x.value],()=>{(l.value==="range"||f.value!=="custom"||h.value&&x.value)&&B()},{immediate:!0}),Ne(()=>m.value,()=>{l.value==="range"&&X()}),Ne(()=>s.open,y=>{y&&(D.value=!1,M.value=0,p.value=[],k.value=!1,B())});async function le(){const y=[...V.value];if(y.length!==0){D.value=!0,k.value=!1,M.value=0,g.value=y.length,p.value=[];try{for(const L of y){if(k.value)break;try{const $=await tt().generateSummary(s.sessionId,L.id,i.value,!1,Aa());if($.success){p.value.push({id:L.id,status:"success",summary:$.summary||""});const z=S.value.findIndex(ce=>ce.id===L.id);z!==-1&&(S.value[z].summary=$.summary||"")}else $.error&&T($.error)?p.value.push({id:L.id,status:"skipped",message:$.error}):p.value.push({id:L.id,status:"failed",message:$.error})}catch($){p.value.push({id:L.id,status:"failed",message:String($)})}M.value++,await Xe(),E.value&&(E.value.scrollTop=E.value.scrollHeight)}}finally{D.value=!1}H.value.success>0&&n("completed")}}function F(){L2(k)}function _(){D.value&&(k.value=!0),n("update:open",!1)}return(y,L)=>{const $=We,z=Cr,ce=lt,W=Ve,se=no,pe=Sr,me=ht;return b(),xe(me,{open:c.value,"onUpdate:open":L[5]||(L[5]=ae=>c.value=ae),ui:{overlay:"z-[10001]",content:"z-[10001]"}},{content:re(()=>[v(pe,null,{header:re(()=>[r("div",R2,[r("h3",N2,d(o(a)("records.batchSummary.title","批量生成摘要")),1),v($,{color:"neutral",variant:"ghost",icon:"i-heroicons-x-mark",size:"sm",onClick:_})])]),footer:re(()=>[r("div",vL,[v($,{color:"neutral",variant:"outline",disabled:D.value,onClick:_},{default:re(()=>[J(d(o(a)("common.close","关闭")),1)]),_:1},8,["disabled"]),D.value?(b(),xe($,{key:1,color:"error",onClick:F},{default:re(()=>[J(d(o(a)("records.batchSummary.stop","停止")),1)]),_:1})):(b(),xe($,{key:0,color:"primary",disabled:V.value.length===0||C.value,onClick:le},{default:re(()=>[J(d(o(a)("records.batchSummary.start","开始生成")),1)]),_:1},8,["disabled"]))])]),default:re(()=>[r("div",F2,[r("div",U2,[v($,{color:l.value==="range"?"primary":"neutral",variant:l.value==="range"?"solid":"ghost",size:"sm",disabled:D.value,onClick:L[0]||(L[0]=ae=>l.value="range")},{default:re(()=>[J(d(o(a)("records.batchSummary.byRange","按范围")),1)]),_:1},8,["color","variant","disabled"]),v($,{color:l.value==="time"?"primary":"neutral",variant:l.value==="time"?"solid":"ghost",size:"sm",disabled:D.value,onClick:L[1]||(L[1]=ae=>l.value="time")},{default:re(()=>[J(d(o(a)("records.batchSummary.byTime","按时间")),1)]),_:1},8,["color","variant","disabled"])]),l.value==="range"?(b(),A("div",O2,[r("label",H2,d(o(a)("records.batchSummary.selectRange","选择范围")),1),r("div",V2,[r("div",z2,[v(z,{modelValue:m.value,"onUpdate:modelValue":L[2]||(L[2]=ae=>m.value=ae),min:1,max:100,step:1,disabled:D.value,class:"flex-1"},null,8,["modelValue","disabled"]),r("span",B2,d(m.value)+"% ",1)]),r("div",W2,[r("span",null,d(o(a)("records.batchSummary.rangeStart","最早")),1),u.value>0?(b(),A("span",j2,d(o(a)("records.batchSummary.rangeInfo","约"))+" "+d(Math.ceil(u.value*m.value/100))+" / "+d(u.value)+" "+d(o(a)("records.batchSummary.sessionsUnit","个会话")),1)):ne("",!0),r("span",null,d(o(a)("records.batchSummary.rangeEnd","最近")),1)])])])):l.value==="time"?(b(),A("div",q2,[r("label",K2,d(o(a)("records.batchSummary.timeRange","选择时间范围")),1),r("div",G2,[(b(!0),A(Me,null,Be([{key:"today",label:o(a)("records.batchSummary.today","今天")},{key:"yesterday",label:o(a)("records.batchSummary.yesterday","昨天")},{key:"week",label:o(a)("records.batchSummary.week","最近7天")},{key:"month",label:o(a)("records.batchSummary.month","最近30天")},{key:"custom",label:o(a)("records.batchSummary.custom","自定义")}],ae=>(b(),xe($,{key:ae.key,color:f.value===ae.key?"primary":"neutral",variant:f.value===ae.key?"solid":"outline",size:"sm",disabled:D.value,onClick:he=>f.value=ae.key},{default:re(()=>[J(d(ae.label),1)]),_:2},1032,["color","variant","disabled","onClick"]))),128))]),f.value==="custom"?(b(),A("div",X2,[v(ce,{modelValue:h.value,"onUpdate:modelValue":L[3]||(L[3]=ae=>h.value=ae),type:"date",disabled:D.value,size:"sm"},null,8,["modelValue","disabled"]),L[6]||(L[6]=r("span",{class:"text-gray-500"},"—",-1)),v(ce,{modelValue:x.value,"onUpdate:modelValue":L[4]||(L[4]=ae=>x.value=ae),type:"date",disabled:D.value,size:"sm"},null,8,["modelValue","disabled"])])):ne("",!0)])):ne("",!0),!C.value&&!ee.value?(b(),A("div",Y2,[S.value.length>0?(b(),A(Me,{key:0},[r("p",null,[J(d(o(a)("records.batchSummary.found","找到"))+" "+d(S.value.length)+" "+d(o(a)("records.batchSummary.sessionsUnit","个会话"))+" ",1),ie.value>0||Q.value>0?(b(),A("span",Q2,[L[7]||(L[7]=J(" ( ",-1)),ie.value>0?(b(),A("span",J2,d(ie.value)+" "+d(o(a)("records.batchSummary.hasSummary","个已有摘要")),1)):ne("",!0),ie.value>0&&Q.value>0?(b(),A(Me,{key:1},[J(",")],64)):ne("",!0),Q.value>0?(b(),A("span",Z2,d(Q.value)+" "+d(o(a)("records.batchSummary.tooFewMessages","个消息太少")),1)):ne("",!0),L[8]||(L[8]=J(" ) ",-1))])):ne("",!0)]),V.value.length>0?(b(),A("p",eL,d(o(a)("records.batchSummary.pending","待生成:"))+" "+d(V.value.length)+" "+d(o(a)("records.batchSummary.unit","个")),1)):(b(),A("p",tL,d(o(a)("records.batchSummary.noPending","没有可生成的会话")),1))],64)):(b(),A("p",sL,d(o(a)("records.batchSummary.noSessions","该时间范围内没有会话")),1))])):ee.value?(b(),A("div",aL,[v(W,{name:"i-heroicons-arrow-path",class:"animate-spin"}),J(" "+d(o(a)("records.batchSummary.checking","检查中...")),1)])):(b(),A("div",nL,[v(W,{name:"i-heroicons-arrow-path",class:"animate-spin"}),J(" "+d(o(a)("records.batchSummary.loading","加载中...")),1)])),D.value||p.value.length>0?(b(),A("div",oL,[r("div",rL,[r("span",null,d(o(a)("records.batchSummary.progress","进度")),1),r("span",null,d(M.value)+" / "+d(g.value||V.value.length),1)]),D.value?(b(),xe(se,{key:0,value:Y.value},null,8,["value"])):(b(),A("div",iL))])):ne("",!0),p.value.length>0?(b(),A("div",{key:6,ref_key:"resultsContainer",ref:E,class:"max-h-64 overflow-y-auto rounded border border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-800/50"},[(b(!0),A(Me,null,Be(p.value,ae=>(b(),A("div",{key:ae.id,class:"flex flex-col gap-1 px-3 py-2 text-sm border-b border-gray-200 dark:border-gray-700 last:border-b-0"},[r("div",lL,[v(W,{name:ae.status==="success"?"i-heroicons-check-circle":ae.status==="skipped"?"i-heroicons-minus-circle":"i-heroicons-x-circle",class:we(["flex-shrink-0",{"text-green-500":ae.status==="success","text-gray-400":ae.status==="skipped","text-red-500":ae.status==="failed"}])},null,8,["name","class"]),r("span",cL,d(o(a)("records.batchSummary.session","会话"))+" #"+d(ae.id),1),r("span",{class:we(["flex-shrink-0 text-xs",{"text-green-600 dark:text-green-400":ae.status==="success","text-gray-500":ae.status==="skipped","text-red-600 dark:text-red-400":ae.status==="failed"}])},d(ae.status==="success"?o(a)("records.batchSummary.statusSuccess","成功"):ae.status==="skipped"?o(a)("records.batchSummary.statusSkipped","跳过"):o(a)("records.batchSummary.statusFailed","失败")),3)]),ae.summary?(b(),A("div",dL,d(ae.summary),1)):ae.status==="failed"&&ae.message?(b(),A("div",uL,d(ae.message),1)):ae.status==="skipped"?(b(),A("div",mL,d(o(a)("records.batchSummary.tooFewMessages","消息数量太少")),1)):ne("",!0)]))),128))],512)):ne("",!0),!D.value&&p.value.length>0?(b(),A("div",gL,[r("span",pL,[v(W,{name:"i-heroicons-check-circle",class:"mr-1"}),J(" "+d(o(a)("records.batchSummary.success","成功:"))+" "+d(H.value.success),1)]),H.value.failed>0?(b(),A("span",fL,[v(W,{name:"i-heroicons-x-circle",class:"mr-1"}),J(" "+d(o(a)("records.batchSummary.failed","失败:"))+" "+d(H.value.failed),1)])):ne("",!0),H.value.skipped>0?(b(),A("span",hL,[v(W,{name:"i-heroicons-minus-circle",class:"mr-1"}),J(" "+d(o(a)("records.batchSummary.skipped","跳过:"))+" "+d(H.value.skipped),1)])):ne("",!0)])):ne("",!0)])]),_:1})]),_:1},8,["open"])}}}),bL={key:0,class:"flex h-full w-10 flex-col items-center border-r border-gray-200 bg-gray-50 py-2 dark:border-gray-700 dark:bg-gray-800/50"},_L={class:"mt-2 flex flex-1 items-center"},xL={class:"vertical-text text-xs text-gray-400"},kL={key:1,class:"flex h-full w-56 flex-col border-r border-gray-200 bg-gray-50 dark:border-gray-700 dark:bg-gray-800/50"},wL={class:"flex items-center justify-between border-b border-gray-200 px-2 py-1.5 dark:border-gray-700"},SL={class:"text-xs font-medium text-gray-600 dark:text-gray-300"},CL={class:"flex items-center gap-0.5"},ML={key:0,class:"flex flex-1 items-center justify-center"},AL={key:1,class:"flex flex-1 items-center justify-center p-2"},TL={class:"text-xs text-gray-400"},$L={key:0,class:"flex w-full items-center gap-1 px-2 py-1"},IL={class:"text-xs font-medium text-gray-700 dark:text-gray-200"},PL={class:"text-xs text-gray-400"},DL={key:1,class:"px-1.5 py-0.5"},LL=["onClick"],EL={class:"flex-1 min-w-0"},RL={class:"flex items-center justify-between mb-0.5"},NL={class:"text-xs font-semibold text-gray-700 dark:text-gray-200"},FL={class:"font-mono text-[10px] px-1.5 py-0.5 rounded bg-gray-200/50 dark:bg-gray-700/50 text-gray-500 dark:text-gray-400 font-medium"},UL={class:"flex w-full items-center"},OL={class:"line-clamp-2 text-xs leading-normal text-gray-400 dark:text-gray-500 font-normal"},HL={class:"max-w-sm whitespace-pre-wrap text-sm leading-relaxed font-normal"},VL=["onClick"],zL={key:2,class:"text-xs italic text-gray-300 dark:text-gray-600"},BL=28,WL=52,jL=$e({__name:"SessionTimeline",props:{sessionId:{},activeSessionId:{},collapsed:{type:Boolean},filterStartTs:{},filterEndTs:{},filterMatchedSessionIds:{}},emits:["select","update:collapsed"],setup(e,{emit:t}){const s=e,n=t,{t:a,locale:i}=Re(),c=Pa(),l=P([]),m=P(!0),u=P(null),f=P(new Set),h=P(!1),x=G({get:()=>s.collapsed??!1,set:H=>n("update:collapsed",H)}),S=G(()=>{let H=l.value;return H.length===0?[]:(s.filterMatchedSessionIds&&s.filterMatchedSessionIds.size>0?H=H.filter(B=>s.filterMatchedSessionIds.has(B.id)):(s.filterStartTs||s.filterEndTs)&&(H=H.filter(B=>{const j=B.startTs,X=B.endTs;return!(s.filterStartTs&&X<s.filterStartTs||s.filterEndTs&&j>s.filterEndTs)})),H)}),C=G(()=>{const H=S.value;if(H.length===0)return[];const B=[],j=new Map;for(const le of H){const F=E(le.startTs);let _=j.get(F);_||(_={label:k(le.startTs),sessions:[]},j.set(F,_)),_.sessions.push(le)}const X=Array.from(j.entries()).sort((le,F)=>le[0].localeCompare(F[0]));for(const[le,F]of X){B.push({type:"date",date:le,label:F.label,count:F.sessions.length});const _=F.sessions.sort((y,L)=>y.startTs-L.startTs);for(const y of _)B.push({type:"session",session:y})}return B});function D(H){const B=["bg-pink-50 dark:bg-pink-950/30 text-pink-500 dark:text-pink-400","bg-blue-50 dark:bg-blue-950/30 text-blue-500 dark:text-blue-400","bg-emerald-50 dark:bg-emerald-950/30 text-emerald-500 dark:text-emerald-400","bg-violet-50 dark:bg-violet-950/30 text-violet-500 dark:text-violet-400","bg-amber-50 dark:bg-amber-950/30 text-amber-500 dark:text-amber-400"];return B[H%B.length]}const M=to(G(()=>({count:C.value.length,getScrollElement:()=>u.value,estimateSize:H=>C.value[H]?.type==="date"?BL:WL,overscan:10,getItemKey:H=>{const B=C.value[H];return B?B.type==="date"?`date-${B.date}`:`session-${B.session.id}`:H}}))),g=G(()=>M.value.getVirtualItems()),p=G(()=>M.value.getTotalSize());function k(H){return new Date(H*1e3).toLocaleDateString("zh-CN",{month:"2-digit",day:"2-digit"})}function T(H){return new Date(H*1e3).toLocaleTimeString("zh-CN",{hour:"2-digit",minute:"2-digit"})}function E(H){const B=new Date(H*1e3);return`${B.getFullYear()}-${String(B.getMonth()+1).padStart(2,"0")}-${String(B.getDate()).padStart(2,"0")}`}async function I(){if(s.sessionId){m.value=!0;try{const H=await tt().getSessions(s.sessionId);l.value=H,await Xe(),N()}catch(H){console.error("加载会话列表失败:",H)}finally{m.value=!1}}}function N(){C.value.length>0&&M.value.scrollToIndex(C.value.length-1,{align:"end"})}function ee(H){const B=C.value.findIndex(j=>j.type==="session"&&j.session.id===H);B!==-1&&M.value.scrollToIndex(B,{align:"center"})}function V(H){n("select",H.id,H.firstMessageId)}async function ie(H,B){if(B.stopPropagation(),B.preventDefault(),console.log("[SessionTimeline] 开始生成摘要:",H.id,s.sessionId),f.value.has(H.id)){console.log("[SessionTimeline] 已在生成中,跳过");return}f.value.add(H.id),console.log("[SessionTimeline] 正在生成中的会话:",Array.from(f.value));try{console.log("[SessionTimeline] 调用 IPC...");const j=await tt().generateSummary(...E2(s.sessionId,H.id,i.value,Aa()));if(console.log("[SessionTimeline] IPC 返回:",j),j.success&&j.summary){const X=l.value.findIndex(le=>le.id===H.id);X!==-1&&(l.value[X]={...l.value[X],summary:j.summary})}else c.fail(a("records.summaryFailed","摘要生成失败"),{description:j.error||a("records.summaryUnknownError","未知错误")})}catch(j){c.fail(a("records.summaryFailed","摘要生成失败"),{description:String(j)})}finally{f.value.delete(H.id),console.log("[SessionTimeline] 生成完成")}}function Q(H){return f.value.has(H)}function Y(H){H&&M.value.measureElement(H)}return Ne(()=>s.activeSessionId,H=>{H&&ee(H)}),Ne(()=>s.sessionId,()=>{I()},{immediate:!0}),(H,B)=>{const j=We,X=ls,le=Ve;return b(),A(Me,null,[x.value?(b(),A("div",bL,[v(j,{icon:"i-heroicons-chevron-right",variant:"ghost",size:"xs",onClick:B[0]||(B[0]=F=>x.value=!1)}),r("div",_L,[r("span",xL,d(o(a)("records.timeline.timeline")),1)])])):(b(),A("div",kL,[r("div",wL,[r("span",SL,d(o(a)("records.timeline.timeline")),1),r("div",CL,[v(X,{text:o(a)("records.batchSummary.title")},{default:re(()=>[v(j,{icon:"i-heroicons-sparkles",variant:"ghost",size:"xs",onClick:B[1]||(B[1]=F=>h.value=!0)})]),_:1},8,["text"]),v(j,{icon:"i-heroicons-chevron-left",variant:"ghost",size:"xs",onClick:B[2]||(B[2]=F=>x.value=!0)})])]),m.value?(b(),A("div",ML,[v(le,{name:"i-heroicons-arrow-path",class:"h-4 w-4 animate-spin text-gray-400"})])):l.value.length===0?(b(),A("div",AL,[r("span",TL,d(o(a)("records.timeline.noSessions")),1)])):(b(),A("div",{key:2,ref_key:"scrollContainerRef",ref:u,class:"flex-1 overflow-y-auto py-1"},[r("div",{class:"relative w-full",style:Jt({height:`${p.value}px`})},[(b(!0),A(Me,null,Be(g.value,F=>(b(),A("div",{key:String(F.key),ref_for:!0,ref:_=>Y(_),class:"absolute left-0 top-0 w-full",style:Jt({transform:`translateY(${F.start}px)`})},[C.value[F.index]?.type==="date"?(b(),A("div",$L,[r("span",IL,d(C.value[F.index].label),1),r("span",PL," ("+d(C.value[F.index].count)+") ",1)])):C.value[F.index]?.type==="session"?(b(),A("div",DL,[r("button",{class:we(["group relative flex w-full gap-2.5 items-center rounded-xl p-1.5 pl-2.5 text-left transition-all duration-200",[e.activeSessionId===C.value[F.index].session.id?"bg-pink-500/5 dark:bg-pink-500/10":"hover:bg-gray-100 dark:hover:bg-gray-800/60"]]),onClick:_=>V(C.value[F.index].session)},[r("div",{class:we(["absolute left-0 top-1/2 -translate-y-1/2 w-1 rounded-r-md transition-all duration-200",[e.activeSessionId===C.value[F.index].session.id?"h-5 bg-pink-500 dark:bg-pink-400 opacity-100":"h-0 bg-pink-500/40 dark:bg-pink-400/40 group-hover:h-3 group-hover:opacity-100 opacity-0"]])},null,2),r("div",{class:we(["w-7 h-7 rounded-lg flex items-center justify-center shrink-0 transition-colors",D(C.value[F.index].session.id)])},[v(le,{name:"i-heroicons-chat-bubble-oval-left",class:"w-3.5 h-3.5"})],2),r("div",EL,[r("div",RL,[r("span",NL,d(T(C.value[F.index].session.startTs)),1),r("span",FL,d(C.value[F.index].session.messageCount),1)]),r("div",UL,[C.value[F.index].session.summary?(b(),xe(X,{key:0,popper:{placement:"right"},ui:{content:"z-[10001] h-auto max-h-80 overflow-y-auto"}},{content:re(()=>[r("div",HL,d(C.value[F.index].session.summary),1)]),default:re(()=>[r("span",OL,d(C.value[F.index].session.summary),1)]),_:2},1024)):C.value[F.index].session.messageCount>=3?(b(),A("span",{key:1,class:"flex items-center gap-1 text-xs text-gray-400 hover:text-pink-500 dark:text-gray-500 dark:hover:text-pink-400 cursor-pointer",onClick:_=>ie(C.value[F.index].session,_)},[Q(C.value[F.index].session.id)?(b(),xe(le,{key:0,name:"i-heroicons-arrow-path",class:"h-3 w-3 animate-spin"})):(b(),xe(le,{key:1,name:"i-heroicons-sparkles",class:"h-3 w-3"})),r("span",null,d(o(a)("records.timeline.generateSummary")),1)],8,VL)):(b(),A("span",zL,d(o(a)("records.timeline.tooFewMessages")),1))])])],10,LL)])):ne("",!0)],4))),128))],4)],512))])),v(yL,{open:h.value,"onUpdate:open":B[3]||(B[3]=F=>h.value=F),"session-id":e.sessionId,onCompleted:I},null,8,["open","session-id"])],64)}}}),qL=Gt(jL,[["__scopeId","data-v-11c774e5"]]),KL={class:"flex h-full w-[750px] flex-col bg-white dark:bg-gray-900",style:{"-webkit-app-region":"no-drag"}},GL={class:"text-lg font-semibold text-gray-900 dark:text-white"},XL={class:"flex min-h-0 flex-1"},YL={class:"min-h-0 min-w-0 flex-1"},QL={key:0,class:"shrink-0 border-t border-gray-200 px-4 py-2 dark:border-gray-800"},JL={class:"text-xs text-gray-500"},ZL=$e({__name:"ChatRecordDrawer",setup(e){const{t}=Re(),s=$t(),n=ut(),{currentSessionId:a}=Ge(n),i=P(!1);Qe(()=>{i.value=navigator.platform.toLowerCase().includes("win")});const c=P(null),l=P({}),m=P(0),u=P(!1),f=P(void 0),h=P([]),x=P(void 0);function S(E){l.value=E}function C(){l.value={},x.value=void 0}function D(E){m.value=E}function M(E){if(!l.value.keywords?.length||!h.value.length){x.value=void 0;return}const I=new Set;for(const N of E)for(const ee of h.value)if(N>=ee.startTs&&N<=ee.endTs){I.add(ee.id);break}x.value=I.size>0?I:void 0}function g(E){if(!h.value.length)return;let I;for(const N of h.value)if(E.timestamp>=N.startTs&&E.timestamp<=N.endTs){I=N;break}if(!I)for(const N of h.value)if(N.firstMessageId<=E.id)I=N;else break;I&&I.id!==f.value&&(f.value=I.id)}function p(E,I){f.value=E,l.value={...l.value,scrollToMessageId:I}}function k(E){l.value={scrollToMessageId:E}}async function T(){if(a.value)try{const E=await tt().getSessions(a.value);h.value=E.map(I=>({id:I.id,startTs:I.startTs,endTs:I.endTs,firstMessageId:I.firstMessageId}))}catch{h.value=[]}}return Ne(()=>s.showChatRecordDrawer,async E=>{if(E){const I=Ct(s.chatRecordQuery);l.value=I?{...I}:{},await T(),h.value.length>0&&(f.value=h.value[h.value.length-1].id),await Xe(),c.value?.refresh()}else l.value={},m.value=0,f.value=void 0,h.value=[]}),(E,I)=>{const N=We,ee=Mr;return b(),xe(ee,{open:o(s).showChatRecordDrawer,"onUpdate:open":I[2]||(I[2]=V=>o(s).showChatRecordDrawer=V),direction:"right",handle:!1,ui:{content:"z-50"}},{content:re(()=>[r("div",KL,[r("div",{class:we(["flex items-center justify-between border-b border-gray-200 px-4 dark:border-gray-800",i.value?"pt-10 pb-3":"py-3"])},[r("h3",GL,d(o(t)("records.drawer.title")),1),v(N,{icon:"i-heroicons-x-mark",color:"neutral",variant:"ghost",size:"sm",onClick:I[0]||(I[0]=V=>o(s).closeChatRecordDrawer())})],2),v(n2,{query:l.value,onApply:S,onReset:C},null,8,["query"]),r("div",XL,[o(a)?(b(),xe(qL,{key:0,collapsed:u.value,"onUpdate:collapsed":I[1]||(I[1]=V=>u.value=V),"session-id":o(a),"active-session-id":f.value,"filter-start-ts":l.value.startTs,"filter-end-ts":l.value.endTs,"filter-matched-session-ids":x.value,onSelect:p},null,8,["collapsed","session-id","active-session-id","filter-start-ts","filter-end-ts","filter-matched-session-ids"])):ne("",!0),r("div",YL,[v(D2,{ref_key:"messageListRef",ref:c,query:l.value,onCountChange:D,onVisibleMessageChange:g,onJumpToMessage:k,onMessageTimestampsChange:M},null,8,["query"])])]),m.value>0?(b(),A("div",QL,[r("span",JL,d(o(t)("records.drawer.loadedCount",{count:m.value})),1)])):ne("",!0)])]),_:1},8,["open"])}}}),eE={key:0,class:"pointer-events-auto fixed right-4 bottom-[88px] z-40"},tE=["title"],sE={class:"flex h-6.5 w-6.5 shrink-0 items-center justify-center rounded-full bg-white text-primary-600 shadow-[0_2px_8px_rgba(255,255,255,0.28)]"},aE={class:"text-[11px] font-medium text-white"},nE=$e({__name:"GlobalTaskBar",setup(e){const{t}=Re(),s=Cs(),n=ha(),a=q$(),{activeTask:i}=Ge(a),c=G(()=>a.getActiveTaskState()),l=G(()=>{if(!i.value)return!1;const u=i.value.chatType==="group"?"group-chat":"private-chat";return s.name===u&&String(s.params.id??"")===i.value.sessionId&&s.query.tab==="ai-chat"?(c.value?.currentConversationId??null)!==(i.value.conversationId??null):!0});async function m(){i.value&&(a.focusActiveTaskConversation(),await n.push({name:i.value.chatType==="group"?"group-chat":"private-chat",params:{id:i.value.sessionId},query:{tab:"ai-chat"}}))}return(u,f)=>{const h=Ve;return b(),xe(fa,{name:"task-bar-fade"},{default:re(()=>[l.value?(b(),A("div",eE,[r("button",{class:"group flex h-9 items-center gap-1.5 overflow-hidden rounded-full bg-primary-500 px-2 shadow-[0_10px_24px_rgba(15,23,42,0.12)] transition-all hover:-translate-y-0.5 hover:bg-primary-600 hover:shadow-[0_16px_32px_rgba(15,23,42,0.16)] dark:bg-primary-500 dark:hover:bg-primary-400",title:`${o(t)("ai.chat.backgroundTask.return")} · ${o(i)?.sessionName??""}`,onClick:m},[r("div",sE,[v(h,{name:"i-heroicons-sparkles",class:"h-3 w-3 animate-pulse"})]),r("span",aE,d(o(t)("ai.chat.backgroundTask.runningShort")),1)],8,tE)])):ne("",!0)]),_:1})}}}),oE=Gt(nE,[["__scopeId","data-v-8ed6c70f"]]),tr=new Map;let da=null,Gs=null,Qt={};function rE(){if(!da||Object.keys(Qt).length===0)return;const e={...Qt};Qt={},da(e).catch(t=>{console.warn("[BackendPersist] Save failed:",t)})}function iE(){Gs&&clearTimeout(Gs),Gs=setTimeout(rE,500)}function lE(e,t){const s={};for(const n of t.pick)s[n]=JSON.parse(JSON.stringify(e[n]));t.key?Qt[t.key]=s:Object.assign(Qt,s),iE()}function cE(e){da=e}function dE(e){for(const[,{store:t,config:s}]of tr){const n=s.key?e[s.key]:e;if(!n||typeof n!="object")continue;const a={};for(const i of s.pick){const c=n[i];c!==void 0&&(a[i]=c)}Object.keys(a).length>0&&t.$patch(a)}}const uE=({store:e,options:t})=>{const s=t.backendPersist;if(s){tr.set(e.$id,{store:e,config:s});for(const n of s.pick)Ne(()=>e.$state[n],()=>lE(e.$state,s),{deep:!0})}};let jn=!1;async function mE(){if(jn)return;jn=!0;const e=oc();try{const[t,s,n]=await Promise.all([e.getPreferences(),e.getUiConfig(),e.getLocale()]);rc(s);const a=It();s.default_session_tab&&(a.defaultSessionTab=s.default_session_tab),n&&a.$patch({locale:n}),dE(t)}catch(t){console.warn("[PreferencesSync] Failed to load from backend, keeping default state:",t)}cE(t=>e.savePreferences(t)),gE(e)}function gE(e){const t=It();Ne(()=>t.defaultSessionTab,s=>{e.saveUiConfig({default_session_tab:s}).catch(n=>{console.warn("[PreferencesSync] Failed to save ui config:",n)})}),Ne(()=>_n().session_gap_threshold,s=>{e.saveUiConfig({session_gap_threshold:s}).catch(n=>{console.warn("[PreferencesSync] Failed to save ui config:",n)})}),Ne(()=>_n().summary_strategy,s=>{e.saveUiConfig({summary_strategy:s}).catch(n=>{console.warn("[PreferencesSync] Failed to save ui config:",n)})}),Ne(()=>t.locale,s=>{e.saveLocale(s).catch(n=>{console.warn("[PreferencesSync] Failed to save locale:",n)})})}const pE={class:"relative flex h-screen w-full overflow-hidden bg-gray-50 dark:bg-gray-900"},fE={key:0,class:"flex h-full w-full items-center justify-center"},hE={class:"flex flex-col items-center justify-center text-center"},vE={class:"mt-2 text-sm text-gray-500"},yE={class:"relative flex-1 overflow-hidden"},bE=$e({__name:"App",setup(e){const{t}=Re(),s=ut(),n=$t(),a=It(),i=Is(),{isInitialized:c}=Ge(s),l=Cs(),m={delayDuration:100},u={position:"top-center",progress:!1,duration:2e3};function f(h){(navigator.platform.toLowerCase().includes("mac")?h.metaKey:h.ctrlKey)&&h.key===","&&(h.preventDefault(),h.stopPropagation(),n.showSettings||n.openSettings())}return Qe(async()=>{window.addEventListener("keydown",f);const h=navigator.platform.toLowerCase();h.includes("win")?document.documentElement.classList.add("platform-windows"):h.includes("linux")&&document.documentElement.classList.add("platform-linux"),await Ql(),await mE(),await a.initLocale(),i.init(),await s.loadSessions()}),qt(()=>{window.removeEventListener("keydown",f)}),(h,x)=>{const S=Ve,C=hr("router-view"),D=Ar;return b(),xe(D,{tooltip:m,toaster:u},{default:re(()=>[v(Kl),r("div",pE,[o(c)?(b(),A(Me,{key:1},[v(Uc),r("main",yE,[v(C,null,{default:re(({Component:M})=>[v(fa,{name:"page-fade",mode:"out-in"},{default:re(()=>[(b(),xe(vr(M),{key:o(l).path}))]),_:2},1024)]),_:1})])],64)):(b(),A("div",fE,[r("div",hE,[v(S,{name:"i-heroicons-arrow-path",class:"h-8 w-8 animate-spin text-pink-500"}),r("p",vE,d(o(t)("common.initializing")),1)])]))]),v(qc,{open:o(n).showScreenCaptureModal,"image-data":o(n).screenCaptureImage,"onUpdate:open":x[0]||(x[0]=M=>M?null:o(n).closeScreenCaptureModal())},null,8,["open","image-data"]),v(JD),v(o(ZL)),v(oE)]),_:1})}}}),_E=Gt(bE,[["__scopeId","data-v-7834154b"]]),Es=Tr({routes:[{path:"/",name:"home",component:()=>Ee(()=>import("./index-CM29Kc4p.js"),__vite__mapDeps([10,5,4,11,6,12]))},{path:"/group-chat/:id",name:"group-chat",component:()=>Ee(()=>import("./index-DTxRy2FH.js"),__vite__mapDeps([13,6,5,4,11,14,15,16,17,18,19]))},{path:"/private-chat/:id",name:"private-chat",component:()=>Ee(()=>import("./index-grds3iG-.js"),__vite__mapDeps([20,6,5,4,11,14,15,16,17,18,21]))}],history:$r()});Es.beforeEach((e,t,s)=>{s()});Es.afterEach(e=>{document.body.id=`page-${e.name}`});function xE(){requestIdleCallback(()=>{Ee(()=>import("./index-DTxRy2FH.js"),__vite__mapDeps([13,6,5,4,11,14,15,16,17,18,19])),Ee(()=>import("./index-grds3iG-.js"),__vite__mapDeps([20,6,5,4,11,14,15,16,17,18,21]))})}Es.isReady().then(xE);function kE(e,t){if(e==null)return;let s=e;for(let n=0;n<t.length;n++){if(s===void 0||s[t[n]]===void 0)return;if(s===null||s[t[n]]===null)return null;s=s[t[n]]}return s}function La(e,t,s){if(s.length===0)return t;const n=s[0];return s.length>1&&(t=La(typeof e!="object"||e===null||!Object.prototype.hasOwnProperty.call(e,n)?Number.isInteger(Number(s[1]))?[]:{}:e[n],t,Array.prototype.slice.call(s,1))),Number.isInteger(Number(n))&&Array.isArray(e)?e.slice()[n]:Object.assign({},e,{[n]:t})}function sr(e,t){if(e==null||t.length===0)return e;if(t.length===1){if(e==null)return e;if(Number.isInteger(t[0])&&Array.isArray(e))return Array.prototype.slice.call(e,0).splice(t[0],1);const s={};for(const n in e)s[n]=e[n];return delete s[t[0]],s}if(e[t[0]]==null){if(Number.isInteger(t[0])&&Array.isArray(e))return Array.prototype.concat.call([],e);const s={};for(const n in e)s[n]=e[n];return s}return La(e,sr(e[t[0]],Array.prototype.slice.call(t,1)),[t[0]])}function ar(e,t){return t.map(s=>s.split(".")).map(s=>[s,kE(e,s)]).filter(s=>s[1]!==void 0).reduce((s,n)=>La(s,n[1],n[0]),{})}function nr(e,t){return t.map(s=>s.split(".")).reduce((s,n)=>sr(s,n),e)}function qn(e,{storage:t,serializer:s,key:n,debug:a,pick:i,omit:c,beforeHydrate:l,afterHydrate:m},u,f=!0){try{f&&l?.(u);const h=t.getItem(n);if(h){const x=s.deserialize(h),S=i?ar(x,i):x,C=c?nr(S,c):S;e.$patch(C)}f&&m?.(u)}catch(h){a&&console.error("[pinia-plugin-persistedstate]",h)}}function Kn(e,{storage:t,serializer:s,key:n,debug:a,pick:i,omit:c}){try{const l=i?ar(e,i):e,m=c?nr(l,c):l,u=s.serialize(m);t.setItem(n,u)}catch(l){a&&console.error("[pinia-plugin-persistedstate]",l)}}function wE(e,t){return typeof e=="function"?e(t):typeof e=="string"?e:t}function SE(e,t,s){const{pinia:n,store:a,options:{persist:i=s}}=e;if(!i)return;if(!(a.$id in n.state.value)){const l=n._s.get(a.$id.replace("__hot:",""));l&&Promise.resolve().then(()=>l.$persist());return}const c=(Array.isArray(i)?i:i===!0?[{}]:[i]).map(t);a.$hydrate=({runHooks:l=!0}={})=>{c.forEach(m=>{qn(a,m,e,l)})},a.$persist=()=>{c.forEach(l=>{Kn(a.$state,l)})},c.forEach(l=>{qn(a,l,e),a.$subscribe((m,u)=>Kn(u,l),{detached:!0})})}function CE(e={}){return function(t){SE(t,s=>{const n=wE(s.key,t.store.$id);return{key:(e.key?e.key:a=>a)(n),debug:s.debug??e.debug??!1,serializer:s.serializer??e.serializer??{serialize:a=>JSON.stringify(a),deserialize:a=>JSON.parse(a)},storage:s.storage??e.storage??window.localStorage,beforeHydrate:s.beforeHydrate??e.beforeHydrate,afterHydrate:s.afterHydrate??e.afterHydrate,pick:s.pick,omit:s.omit}},e.auto??!1)}}var ME=CE();const AE={install(e,t={}){e.use(Ir,t),e.use(Pr,t),e.use(Dr,t),e.use(Lr,t)}},ds=yr(_E),Ea=Rr();Ea.use(ME);Ea.use(uE);ds.use(Ea);ds.use(Es);ds.use(AE);ds.use(Ds);ds.mount("#app");export{Is as A,er as B,Zo as C,wt as D,DE as E,NE as F,Nt as G,D2 as H,Wt as I,Dt as T,Gt as _,It as a,oc as b,Vo as c,ut as d,bn as e,tt as f,Rt as g,Et as h,$t as i,ft as j,RE as k,EE as l,kn as m,LE as n,Yo as o,Ta as p,PE as q,q$ as r,Ge as s,ot as t,Re as u,Vn as v,Ht as w,Pa as x,z$ as y,Ls as z};