diff --git a/intern-log/dist/assets/index-BYlgk7tc.js b/intern-log/dist/assets/index-2zIp9hhK.js similarity index 69% rename from intern-log/dist/assets/index-BYlgk7tc.js rename to intern-log/dist/assets/index-2zIp9hhK.js index 7b021d3..d211421 100644 --- a/intern-log/dist/assets/index-BYlgk7tc.js +++ b/intern-log/dist/assets/index-2zIp9hhK.js @@ -1,2 +1,2 @@ -const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["./web-KxR5SJwt.js","./index-CAFZD9Jo.js","./index-CDIr69jA.css"])))=>i.map(i=>d[i]); -import{r as s,_ as i}from"./index-CAFZD9Jo.js";var t;(function(e){e.Documents="DOCUMENTS",e.Data="DATA",e.Library="LIBRARY",e.Cache="CACHE",e.External="EXTERNAL",e.ExternalStorage="EXTERNAL_STORAGE"})(t||(t={}));var a;(function(e){e.UTF8="utf8",e.ASCII="ascii",e.UTF16="utf16"})(a||(a={}));const E=s("Filesystem",{web:()=>i(()=>import("./web-KxR5SJwt.js"),__vite__mapDeps([0,1,2]),import.meta.url).then(e=>new e.FilesystemWeb)});export{t as Directory,a as Encoding,E as Filesystem}; +const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["./web-DCXp8Rvi.js","./index-BztxiTek.js","./index-CkA9n_Ns.css"])))=>i.map(i=>d[i]); +import{r as s,_ as i}from"./index-BztxiTek.js";var t;(function(e){e.Documents="DOCUMENTS",e.Data="DATA",e.Library="LIBRARY",e.Cache="CACHE",e.External="EXTERNAL",e.ExternalStorage="EXTERNAL_STORAGE"})(t||(t={}));var a;(function(e){e.UTF8="utf8",e.ASCII="ascii",e.UTF16="utf16"})(a||(a={}));const E=s("Filesystem",{web:()=>i(()=>import("./web-DCXp8Rvi.js"),__vite__mapDeps([0,1,2]),import.meta.url).then(e=>new e.FilesystemWeb)});export{t as Directory,a as Encoding,E as Filesystem}; diff --git a/intern-log/dist/assets/index-BztxiTek.js b/intern-log/dist/assets/index-BztxiTek.js new file mode 100644 index 0000000..9829489 --- /dev/null +++ b/intern-log/dist/assets/index-BztxiTek.js @@ -0,0 +1,26 @@ +(function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const o of document.querySelectorAll('link[rel="modulepreload"]'))s(o);new MutationObserver(o=>{for(const a of o)if(a.type==="childList")for(const c of a.addedNodes)c.tagName==="LINK"&&c.rel==="modulepreload"&&s(c)}).observe(document,{childList:!0,subtree:!0});function n(o){const a={};return o.integrity&&(a.integrity=o.integrity),o.referrerPolicy&&(a.referrerPolicy=o.referrerPolicy),o.crossOrigin==="use-credentials"?a.credentials="include":o.crossOrigin==="anonymous"?a.credentials="omit":a.credentials="same-origin",a}function s(o){if(o.ep)return;o.ep=!0;const a=n(o);fetch(o.href,a)}})();/** +* @vue/shared v3.5.44 +* (c) 2018-present Yuxi (Evan) You and Vue contributors +* @license MIT +**/function qa(e){const t=Object.create(null);for(const n of e.split(","))t[n]=1;return n=>n in t}const ft={},Tr=[],En=()=>{},Uu=()=>!1,oi=e=>e.charCodeAt(0)===111&&e.charCodeAt(1)===110&&(e.charCodeAt(2)>122||e.charCodeAt(2)<97),ii=e=>e.startsWith("onUpdate:"),Et=Object.assign,Ha=(e,t)=>{const n=e.indexOf(t);n>-1&&e.splice(n,1)},od=Object.prototype.hasOwnProperty,it=(e,t)=>od.call(e,t),Ke=Array.isArray,tr=e=>Vs(e)==="[object Map]",Mr=e=>Vs(e)==="[object Set]",Jl=e=>Vs(e)==="[object Date]",Ge=e=>typeof e=="function",bt=e=>typeof e=="string",$n=e=>typeof e=="symbol",lt=e=>e!==null&&typeof e=="object",qu=e=>(lt(e)||Ge(e))&&Ge(e.then)&&Ge(e.catch),Hu=Object.prototype.toString,Vs=e=>Hu.call(e),id=e=>Vs(e).slice(8,-1),Wu=e=>Vs(e)==="[object Object]",Wa=e=>bt(e)&&e!=="NaN"&&e[0]!=="-"&&""+parseInt(e,10)===e,_s=qa(",key,ref,ref_for,ref_key,onVnodeBeforeMount,onVnodeMounted,onVnodeBeforeUpdate,onVnodeUpdated,onVnodeBeforeUnmount,onVnodeUnmounted"),ai=e=>{const t=Object.create(null);return n=>t[n]||(t[n]=e(n))},ad=/-\w/g,hn=ai(e=>e.replace(ad,t=>t.slice(1).toUpperCase())),ld=/\B([A-Z])/g,ur=ai(e=>e.replace(ld,"-$1").toLowerCase()),zu=ai(e=>e.charAt(0).toUpperCase()+e.slice(1)),ea=ai(e=>e?`on${zu(e)}`:""),Sn=(e,t)=>!Object.is(e,t),$o=(e,...t)=>{for(let n=0;n{Object.defineProperty(e,t,{configurable:!0,enumerable:!1,writable:s,value:n})},li=e=>{const t=parseFloat(e);return isNaN(t)?e:t},ud=e=>{const t=bt(e)?Number(e):NaN;return isNaN(t)?e:t};let Xl;const ui=()=>Xl||(Xl=typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:typeof global<"u"?global:{});function nr(e){if(Ke(e)){const t={};for(let n=0;nn.startsWith("/*")?"":n).split(cd).forEach(n=>{if(n){const s=n.split(fd);s.length>1&&(t[s[0].trim()]=s[1].trim())}}),t}function tt(e){let t="";if(bt(e))t=e;else if(Ke(e))for(let n=0;nsr(n,t))}const Ju=e=>!!(e&&e.__v_isRef===!0),se=e=>bt(e)?e:e==null?"":Ke(e)||lt(e)&&(e.toString===Hu||!Ge(e.toString))?Ju(e)?se(e.value):JSON.stringify(e,Xu,2):String(e),Xu=(e,t)=>Ju(t)?Xu(e,t.value):tr(t)?{[`Map(${t.size})`]:[...t.entries()].reduce((n,[s,o],a)=>(n[ta(s,a)+" =>"]=o,n),{})}:Mr(t)?{[`Set(${t.size})`]:[...t.values()].map(n=>ta(n))}:$n(t)?ta(t):lt(t)&&!Ke(t)&&!Wu(t)?String(t):t,ta=(e,t="")=>{var n;return $n(e)?`Symbol(${(n=e.description)!=null?n:t})`:e};/** +* @vue/reactivity v3.5.44 +* (c) 2018-present Yuxi (Evan) You and Vue contributors +* @license MIT +**/let Mt;class bd{constructor(t=!1){this.detached=t,this._active=!0,this._on=0,this.effects=[],this.cleanups=[],this._isPaused=!1,this._warnOnRun=!0,this.__v_skip=!0,!t&&Mt&&(Mt.active?(this.parent=Mt,this.index=(Mt.scopes||(Mt.scopes=[])).push(this)-1):(this._active=!1,this._warnOnRun=!1))}get active(){return this._active}pause(){if(this._active){this._isPaused=!0;let t,n;if(this.scopes){const s=this.scopes.slice();for(t=0,n=s.length;t0&&--this._on===0){if(Mt===this)Mt=this.prevScope;else{let t=Mt;for(;t;){if(t.prevScope===this){t.prevScope=this.prevScope;break}t=t.prevScope}}this.prevScope=void 0}}stop(t){if(this._active){this._active=!1;let n,s;for(n=0,s=this.effects.length;n0)return;if(xs){let t=xs;for(xs=void 0;t;){const n=t.next;t.next=void 0,t.flags&=-9,t=n}}let e;for(;ks;){let t=ks;for(ks=void 0;t;){const n=t.next;if(t.next=void 0,t.flags&=-9,t.flags&1)try{t.trigger()}catch(s){e||(e=s)}t=n}}if(e)throw e}function tc(e){for(let t=e.deps;t;t=t.nextDep)t.version=-1,t.prevActiveLink=t.dep.activeLink,t.dep.activeLink=t}function nc(e){let t,n=e.depsTail,s=n;for(;s;){const o=s.prevDep;s.version===-1?(s===n&&(n=o),Ya(s),_d(s)):t=s,s.dep.activeLink=s.prevActiveLink,s.prevActiveLink=void 0,s=o}e.deps=t,e.depsTail=n}function ma(e){for(let t=e.deps;t;t=t.nextDep)if(t.dep.version!==t.version||t.dep.computed&&(rc(t.dep.computed)||t.dep.version!==t.version))return!0;return!!e._dirty}function rc(e){if(e.flags&4&&!(e.flags&16)||(e.flags&=-17,e.globalVersion===As)||(e.globalVersion=As,!e.isSSR&&e.flags&128&&(!e.deps&&!e._dirty||!ma(e))))return;e.flags|=2;const t=e.dep,n=ht,s=vn;ht=e,vn=!0;try{tc(e);const o=e.fn(e._value);(t.version===0||Sn(o,e._value))&&(e.flags|=128,e._value=o,t.version++)}catch(o){throw t.version++,o}finally{ht=n,vn=s,nc(e),e.flags&=-3}}function Ya(e,t=!1){const{dep:n,prevSub:s,nextSub:o}=e;if(s&&(s.nextSub=o,e.prevSub=void 0),o&&(o.prevSub=s,e.nextSub=void 0),n.subs===e&&(n.subs=s,!s&&n.computed)){n.computed.flags&=-5;for(let a=n.computed.deps;a;a=a.nextDep)Ya(a,!0)}!t&&!--n.sc&&n.map&&n.map.delete(n.key)}function _d(e){const{prevDep:t,nextDep:n}=e;t&&(t.nextDep=n,e.prevDep=void 0),n&&(n.prevDep=t,e.nextDep=void 0)}let vn=!0;const sc=[];function Tn(){sc.push(vn),vn=!1}function Pn(){const e=sc.pop();vn=e===void 0?!0:e}function eu(e){const{cleanup:t}=e;if(e.cleanup=void 0,t){const n=ht;ht=void 0;try{t()}finally{ht=n}}}let As=0;class kd{constructor(t,n){this.sub=t,this.dep=n,this.version=n.version,this.nextDep=this.prevDep=this.nextSub=this.prevSub=this.prevActiveLink=void 0}}class Ja{constructor(t){this.computed=t,this.version=0,this.activeLink=void 0,this.subs=void 0,this.map=void 0,this.key=void 0,this.sc=0,this.__v_skip=!0}track(t){if(!ht||!vn||ht===this.computed)return;let n=this.activeLink;if(n===void 0||n.sub!==ht)n=this.activeLink=new kd(ht,this),ht.deps?(n.prevDep=ht.depsTail,ht.depsTail.nextDep=n,ht.depsTail=n):ht.deps=ht.depsTail=n,oc(n);else if(n.version===-1&&(n.version=this.version,n.nextDep)){const s=n.nextDep;s.prevDep=n.prevDep,n.prevDep&&(n.prevDep.nextDep=s),n.prevDep=ht.depsTail,n.nextDep=void 0,ht.depsTail.nextDep=n,ht.depsTail=n,ht.deps===n&&(ht.deps=s)}return n}trigger(t){this.version++,As++,this.notify(t)}notify(t){za();try{for(let n=this.subs;n;n=n.prevSub)n.sub.notify()&&n.sub.dep.notify()}finally{Ga()}}}function oc(e){if(e.dep.sc++,e.sub.flags&4){const t=e.dep.computed;if(t&&!e.dep.subs){t.flags|=20;for(let s=t.deps;s;s=s.nextDep)oc(s)}const n=e.dep.subs;n!==e&&(e.prevSub=n,n&&(n.nextSub=e)),e.dep.subs=e}}const ya=new WeakMap,Ar=Symbol(""),ga=Symbol(""),Os=Symbol("");function Ft(e,t,n){if(vn&&ht){let s=ya.get(e);s||ya.set(e,s=new Map);let o=s.get(n);o||(s.set(n,o=new Ja),o.map=s,o.key=n),o.track()}}function Ln(e,t,n,s,o,a){const c=ya.get(e);if(!c){As++;return}const d=h=>{h&&h.trigger()};if(za(),t==="clear")c.forEach(d);else{const h=Ke(e),y=h&&Wa(n);if(h&&n==="length"){const m=Number(s);c.forEach((w,C)=>{(C==="length"||C===Os||!$n(C)&&C>=m)&&d(w)})}else switch((n!==void 0||c.has(void 0))&&d(c.get(n)),y&&d(c.get(Os)),t){case"add":h?y&&d(c.get("length")):(d(c.get(Ar)),tr(e)&&d(c.get(ga)));break;case"delete":h||(d(c.get(Ar)),tr(e)&&d(c.get(ga)));break;case"set":tr(e)&&d(c.get(Ar));break}}Ga()}function Hr(e){const t=ot(e);return t===e||(Ft(t,"iterate",Os),un(e))?t:An(e)?rr(e)?t.map(n=>or(cn(n))):t.map(or):t.map(cn)}function ci(e){return Ft(e=ot(e),"iterate",Os),e}function kn(e,t){return An(e)?or(rr(e)?cn(t):t):cn(t)}const xd={__proto__:null,[Symbol.iterator](){return ra(this,Symbol.iterator,e=>kn(this,e))},concat(...e){return Hr(this).concat(...e.map(t=>Ke(t)?Hr(t):t))},entries(){return ra(this,"entries",e=>(e[1]=kn(this,e[1]),e))},every(e,t){return In(this,"every",e,t,void 0,arguments)},filter(e,t){return In(this,"filter",e,t,n=>n.map(s=>kn(this,s)),arguments)},find(e,t){return In(this,"find",e,t,n=>kn(this,n),arguments)},findIndex(e,t){return In(this,"findIndex",e,t,void 0,arguments)},findLast(e,t){return In(this,"findLast",e,t,n=>kn(this,n),arguments)},findLastIndex(e,t){return In(this,"findLastIndex",e,t,void 0,arguments)},forEach(e,t){return In(this,"forEach",e,t,void 0,arguments)},includes(...e){return sa(this,"includes",e)},indexOf(...e){return sa(this,"indexOf",e)},join(e){return Hr(this).join(e)},lastIndexOf(...e){return sa(this,"lastIndexOf",e)},map(e,t){return In(this,"map",e,t,void 0,arguments)},pop(){return vs(this,"pop")},push(...e){return vs(this,"push",e)},reduce(e,...t){return nu(this,"reduce",e,t)},reduceRight(e,...t){return nu(this,"reduceRight",e,t)},shift(){return vs(this,"shift")},some(e,t){return In(this,"some",e,t,void 0,arguments)},splice(...e){return vs(this,"splice",e)},toReversed(){return Hr(this).toReversed()},toSorted(e){return Hr(this).toSorted(e)},toSpliced(...e){return Hr(this).toSpliced(...e)},unshift(...e){return vs(this,"unshift",e)},values(){return ra(this,"values",e=>kn(this,e))}};function ra(e,t,n){const s=ci(e),o=s[t],a=o.call(s);if(s!==e&&!un(e)){if(a[Symbol.toStringTag]==="Array Iterator"){const c=Object.create(Object.getPrototypeOf(a));return c.next=()=>tu(a.next(),n),o!==ic[t]&&Object.defineProperties(c,{return:{get(){const d=a.return;return typeof d=="function"?d.bind(a):d}},throw:{get(){const d=a.throw;return typeof d=="function"?d.bind(a):d}}}),c}a._next=a.next,a.next=()=>tu(a._next(),n)}return a}function tu(e,t){return e.done||(e.value=t(e.value)),e}const ic=Array.prototype;function In(e,t,n,s,o,a){const c=ci(e),d=c!==e&&!un(e),h=c[t];if(h!==ic[t]){const w=h.apply(e,a);return d?cn(w):w}let y=n;c!==e&&(d?y=function(w,C){return n.call(this,kn(e,w),C,e)}:n.length>2&&(y=function(w,C){return n.call(this,w,C,e)}));const m=h.call(c,y,s);return d&&o?o(m):m}function nu(e,t,n,s){const o=ci(e),a=o!==e&&!un(e);let c=n,d=!1;o!==e&&(a?(d=s.length===0,c=function(y,m,w){return d&&(d=!1,y=kn(e,y)),n.call(this,y,kn(e,m),w,e)}):n.length>3&&(c=function(y,m,w){return n.call(this,y,m,w,e)}));const h=o[t](c,...s);return d?kn(e,h):h}function sa(e,t,n){const s=ot(e);Ft(s,"iterate",Os);const o=s[t](...n);return(o===-1||o===!1)&&el(n[0])?(n[0]=ot(n[0]),s[t](...n)):o}function vs(e,t,n=[]){Tn(),za();const s=ot(e)[t].apply(e,n);return Ga(),Pn(),s}const Cd=qa("__proto__,__v_isRef,__isVue"),ac=new Set(Object.getOwnPropertyNames(Symbol).filter(e=>e!=="arguments"&&e!=="caller").map(e=>Symbol[e]).filter($n));function Sd(e){$n(e)||(e=String(e));const t=ot(this);return Ft(t,"has",e),t.hasOwnProperty(e)}class lc{constructor(t=!1,n=!1){this._isReadonly=t,this._isShallow=n}get(t,n,s){if(n==="__v_skip")return t.__v_skip;const o=this._isReadonly,a=this._isShallow;if(n==="__v_isReactive")return!o;if(n==="__v_isReadonly")return o;if(n==="__v_isShallow")return a;if(n==="__v_raw")return s===(o?a?Dd:dc:a?fc:cc).get(t)||Object.getPrototypeOf(t)===Object.getPrototypeOf(s)?t:void 0;const c=Ke(t);if(!o){let h;if(c&&(h=xd[n]))return h;if(n==="hasOwnProperty")return Sd}const d=Reflect.get(t,n,Vt(t)?t:s);if(($n(n)?ac.has(n):Cd(n))||(o||Ft(t,"get",n),a))return d;if(Vt(d)){const h=c&&Wa(n)?d:d.value;return o&<(h)?wa(h):h}return lt(d)?o?wa(d):Qa(d):d}}class uc extends lc{constructor(t=!1){super(!1,t)}set(t,n,s,o){let a=t[n];const c=Ke(t)&&Wa(n);if(!this._isShallow){const y=An(a);if(!un(s)&&!An(s)&&(a=ot(a),s=ot(s)),!c&&Vt(a)&&!Vt(s))return y||(a.value=s),!0}const d=c?Number(n)e,wo=e=>Reflect.getPrototypeOf(e);function Ad(e,t,n){return function(...s){const o=this.__v_raw,a=ot(o),c=tr(a),d=e==="entries"||e===Symbol.iterator&&c,h=e==="keys"&&c,y=o[e](...s),m=n?ba:t?or:cn;return!t&&Ft(a,"iterate",h?ga:Ar),Et(Object.create(y),{next(){const{value:w,done:C}=y.next();return C?{value:w,done:C}:{value:d?[m(w[0]),m(w[1])]:m(w),done:C}}})}}function _o(e){return function(...t){return e==="delete"?!1:e==="clear"?void 0:this}}function Od(e,t){const n={get(o){const a=this.__v_raw,c=ot(a),d=ot(o);e||(Sn(o,d)&&Ft(c,"get",o),Ft(c,"get",d));const{has:h}=wo(c),y=t?ba:e?or:cn;if(h.call(c,o))return y(a.get(o));if(h.call(c,d))return y(a.get(d));a!==c&&a.get(o)},get size(){const o=this.__v_raw;return!e&&Ft(ot(o),"iterate",Ar),o.size},has(o){const a=this.__v_raw,c=ot(a),d=ot(o);return e||(Sn(o,d)&&Ft(c,"has",o),Ft(c,"has",d)),o===d?a.has(o):a.has(o)||a.has(d)},forEach(o,a){const c=this,d=c.__v_raw,h=ot(d),y=t?ba:e?or:cn;return!e&&Ft(h,"iterate",Ar),d.forEach((m,w)=>o.call(a,y(m),y(w),c))}};return Et(n,e?{add:_o("add"),set:_o("set"),delete:_o("delete"),clear:_o("clear")}:{add(o){const a=ot(this),c=wo(a),d=ot(o),h=!t&&!un(o)&&!An(o)?d:o;return c.has.call(a,h)||Sn(o,h)&&c.has.call(a,o)||Sn(d,h)&&c.has.call(a,d)||(a.add(h),Ln(a,"add",h,h)),this},set(o,a){!t&&!un(a)&&!An(a)&&(a=ot(a));const c=ot(this),{has:d,get:h}=wo(c);let y=d.call(c,o);y||(o=ot(o),y=d.call(c,o));const m=h.call(c,o);return c.set(o,a),y?Sn(a,m)&&Ln(c,"set",o,a):Ln(c,"add",o,a),this},delete(o){const a=ot(this),{has:c,get:d}=wo(a);let h=c.call(a,o);h||(o=ot(o),h=c.call(a,o)),d&&d.call(a,o);const y=a.delete(o);return h&&Ln(a,"delete",o,void 0),y},clear(){const o=ot(this),a=o.size!==0,c=o.clear();return a&&Ln(o,"clear",void 0,void 0),c}}),["keys","values","entries",Symbol.iterator].forEach(o=>{n[o]=Ad(o,e,t)}),n}function Xa(e,t){const n=Od(e,t);return(s,o,a)=>o==="__v_isReactive"?!e:o==="__v_isReadonly"?e:o==="__v_isShallow"?t:o==="__v_raw"?s:Reflect.get(it(n,o)&&o in s?n:s,o,a)}const Md={get:Xa(!1,!1)},Id={get:Xa(!1,!0)},jd={get:Xa(!0,!1)};const cc=new WeakMap,fc=new WeakMap,dc=new WeakMap,Dd=new WeakMap;function Ld(e){switch(e){case"Object":case"Array":return 1;case"Map":case"Set":case"WeakMap":case"WeakSet":return 2;default:return 0}}function Qa(e){return An(e)?e:Za(e,!1,$d,Md,cc)}function Rd(e){return Za(e,!1,Pd,Id,fc)}function wa(e){return Za(e,!0,Td,jd,dc)}function Za(e,t,n,s,o){if(!lt(e)||e.__v_raw&&!(t&&e.__v_isReactive)||e.__v_skip||!Object.isExtensible(e))return e;const a=o.get(e);if(a)return a;const c=Ld(id(e));if(c===0)return e;const d=new Proxy(e,c===2?s:n);return o.set(e,d),d}function rr(e){return An(e)?rr(e.__v_raw):!!(e&&e.__v_isReactive)}function An(e){return!!(e&&e.__v_isReadonly)}function un(e){return!!(e&&e.__v_isShallow)}function el(e){return e?!!e.__v_raw:!1}function ot(e){const t=e&&e.__v_raw;return t?ot(t):e}function Kd(e){return!it(e,"__v_skip")&&Object.isExtensible(e)&&Gu(e,"__v_skip",!0),e}const cn=e=>lt(e)?Qa(e):e,or=e=>lt(e)?wa(e):e;function Vt(e){return e?e.__v_isRef===!0:!1}function F(e){return Fd(e,!1)}function Fd(e,t){return Vt(e)?e:new Nd(e,t)}class Nd{constructor(t,n){this.dep=new Ja,this.__v_isRef=!0,this.__v_isShallow=!1,this._rawValue=n?t:ot(t),this._value=n?t:cn(t),this.__v_isShallow=n}get value(){return this.dep.track(),this._value}set value(t){const n=this._rawValue,s=this.__v_isShallow||un(t)||An(t);t=s?t:ot(t),Sn(t,n)&&(this._rawValue=t,this._value=s?t:cn(t),this.dep.trigger())}}function Zt(e){return Vt(e)?e.value:e}const Vd={get:(e,t,n)=>t==="__v_raw"?e:Zt(Reflect.get(e,t,n)),set:(e,t,n,s)=>{const o=e[t];return Vt(o)&&!Vt(n)?(o.value=n,!0):Reflect.set(e,t,n,s)}};function pc(e){return rr(e)?e:new Proxy(e,Vd)}class Bd{constructor(t,n,s){this.fn=t,this.setter=n,this._value=void 0,this.dep=new Ja(this),this.__v_isRef=!0,this.deps=void 0,this.depsTail=void 0,this.flags=16,this.globalVersion=As-1,this.next=void 0,this.effect=this,this.__v_isReadonly=!n,this.isSSR=s}notify(){if(this.flags|=16,!(this.flags&8)&&ht!==this)return ec(this,!0),!0}get value(){const t=this.dep.track();return rc(this),t&&(t.version=this.dep.version),this._value}set value(t){this.setter&&this.setter(t)}}function Ud(e,t,n=!1){let s,o;return Ge(e)?s=e:(s=e.get,o=e.set),new Bd(s,o,n)}const ko={},Ro=new WeakMap;let Cr;function qd(e,t=!1,n=Cr){if(n){let s=Ro.get(n);s||Ro.set(n,s=[]),s.push(e)}}function Hd(e,t,n=ft){const{immediate:s,deep:o,once:a,scheduler:c,augmentJob:d,call:h}=n,y=J=>o?J:un(J)||o===!1||o===0?Rn(J,1):Rn(J);let m,w,C,O,N=!1,ee=!1;if(Vt(e)?(w=()=>e.value,N=un(e)):rr(e)?(w=()=>y(e),N=!0):Ke(e)?(ee=!0,N=e.some(J=>rr(J)||un(J)),w=()=>e.map(J=>{if(Vt(J))return J.value;if(rr(J))return y(J);if(Ge(J))return h?h(J,2):J()})):Ge(e)?t?w=h?()=>h(e,2):e:w=()=>{if(C){Tn();try{C()}finally{Pn()}}const J=Cr;Cr=m;try{return h?h(e,3,[O]):e(O)}finally{Cr=J}}:w=En,t&&o){const J=w,ce=o===!0?1/0:o;w=()=>Rn(J(),ce)}const te=wd(),ue=()=>{m.stop(),te&&te.active&&Ha(te.effects,m)};if(a&&t){const J=t;t=(...ce)=>{try{return J(...ce)}finally{ue()}}}let P=ee?new Array(e.length).fill(ko):ko;const L=J=>{if(!(!(m.flags&1)||!m.dirty&&!J))if(t){const ce=m.run();if(J||o||N||(ee?ce.some((ie,Q)=>Sn(ie,P[Q])):Sn(ce,P))){const ie=Cr;Tn();try{C&&C(),Cr=m;const Q=[ce,P===ko?void 0:ee&&P[0]===ko?[]:P,O];P=ce,h?h(t,3,Q):t(...Q)}finally{Cr=ie,Pn()}}}else m.run()};return d&&d(L),m=new Qu(w),m.scheduler=c?()=>c(L,!1):L,O=J=>qd(J,!1,m),C=m.onStop=()=>{const J=Ro.get(m);if(J){if(h)h(J,4);else for(const ce of J)ce();Ro.delete(m)}},t?s?L(!0):P=m.run():c?c(L.bind(null,!0),!0):m.run(),ue.pause=m.pause.bind(m),ue.resume=m.resume.bind(m),ue.stop=ue,ue}function Rn(e,t=1/0,n){if(t<=0||!lt(e)||e.__v_skip||(n=n||new Map,(n.get(e)||0)>=t))return e;if(n.set(e,t),t--,Vt(e))Rn(e.value,t,n);else if(Ke(e))for(let s=0;s{Rn(s,t,n)});else if(Wu(e)){for(const s in e)Rn(e[s],t,n);for(const s of Object.getOwnPropertySymbols(e))Object.prototype.propertyIsEnumerable.call(e,s)&&Rn(e[s],t,n)}return e}/** +* @vue/runtime-core v3.5.44 +* (c) 2018-present Yuxi (Evan) You and Vue contributors +* @license MIT +**/function Bs(e,t,n,s){try{return s?e(...s):e()}catch(o){fi(o,t,n)}}function fn(e,t,n,s){if(Ge(e)){const o=Bs(e,t,n,s);return o&&qu(o)&&o.catch(a=>{fi(a,t,n)}),o}if(Ke(e)){const o=[];for(let a=0;a>>1,o=zt[s],a=Ms(o);a=Ms(n)?zt.push(e):zt.splice(zd(t),0,e),e.flags|=1,vc()}}function vc(){Ko||(Ko=hc.then(gc))}function Gd(e){if(!Ke(e))Zn&&e.id===-1?Zn.splice(Wr+1,0,e):e.flags&1||(xn.push(e),e.flags|=1);else for(let t=0;t=t))continue;zt.splice(s,1),s=e?s-1:pn,o.flags&4&&(o.flags&=-2),o(),o.flags&4||(o.flags&=-2)}}}function yc(e,t,n=0){if(xn.length){let s=xn,o=0;if(t){s=[];for(let c=0;cMs(c)-Ms(d));if(xn.length=o,Zn){for(let c=0;ce.id==null?e.flags&2?-1:1/0:e.id;function gc(e){try{for(pn=0;pn{s._d&&Uo(-1);const a=Fo(t),c=Or.length;let d;try{d=e(...o)}finally{for(let h=Or.length;h>c;h--)zc();Fo(a),s._d&&Uo(1)}return d};return s._n=!0,s._c=!0,s._d=!0,s}function Te(e,t){if(ln===null)return e;const n=yi(ln),s=e.dirs||(e.dirs=[]);for(let o=0;o1)return n&&Ge(t)?t.call(s&&s.proxy):t}}const Xd=Symbol.for("v-scx"),Qd=()=>To(Xd);function vt(e,t,n){return wc(e,t,n)}function wc(e,t,n=ft){const{immediate:s,deep:o,flush:a,once:c}=n,d=Et({},n),h=t&&s||!t&&a!=="post";let y;if(Ks){if(a==="sync"){const O=Qd();y=O.__watcherHandles||(O.__watcherHandles=[])}else if(!h){const O=()=>{};return O.stop=En,O.resume=En,O.pause=En,O}}const m=Gt;d.call=(O,N,ee)=>fn(O,m,N,ee);let w=!1;a==="post"?d.scheduler=O=>{O.i=m,Wt(O,m&&m.suspense)}:a!=="sync"&&(w=!0,d.scheduler=(O,N)=>{N?O():tl(O)}),d.augmentJob=O=>{t&&(O.flags|=4),w&&(O.flags|=2,m&&(O.id=m.uid,O.i=m))};const C=Hd(e,t,d);return Ks&&(y?y.push(C):h&&C()),C}function Zd(e,t,n){const s=this.proxy,o=bt(e)?e.includes(".")?_c(s,e):()=>s[e]:e.bind(s,s);let a;Ge(t)?a=t:(a=t.handler,n=t);const c=qs(this),d=wc(o,a.bind(s),n);return c(),d}function _c(e,t){const n=t.split(".");return()=>{let s=e;for(let o=0;oe.__isTeleport,Sr=e=>e&&(e.disabled||e.disabled===""),ep=e=>e&&(e.defer||e.defer===""),ru=e=>typeof SVGElement<"u"&&e instanceof SVGElement,su=e=>typeof MathMLElement=="function"&&e instanceof MathMLElement,_a=(e,t)=>{const n=e&&e.to;return bt(n)?t?t(n):null:n},tp={name:"Teleport",__isTeleport:!0,process(e,t,n,s,o,a,c,d,h,y){const{mc:m,pc:w,pbc:C,o:{insert:O,querySelector:N,createText:ee,createComment:te,parentNode:ue}}=y,P=Sr(t.props);let{dynamicChildren:L}=t;const J=(Q,A,S)=>{Q.shapeFlag&16&&m(Q.children,A,S,o,a,c,d,h)},ce=(Q=t)=>{const A=Sr(Q.props),S=Q.target=_a(Q.props,N),oe=ka(S,Q,ee,O);S&&(c!=="svg"&&ru(S)?c="svg":c!=="mathml"&&su(S)&&(c="mathml"),o&&o.isCE&&(o.ce._teleportTargets||(o.ce._teleportTargets=new Set)).add(S),A||(J(Q,S,oe),gs(Q,!1)))},ie=Q=>{const A=()=>{if(Xn.get(Q)===A){if(Xn.delete(Q),Sr(Q.props)){const S=ue(Q.el)||n;J(Q,S,Q.anchor),gs(Q,!0)}ce(Q)}};Xn.set(Q,A),Wt(A,a)};if(e==null){const Q=t.el=ee(""),A=t.anchor=ee("");if(O(Q,n,s),O(A,n,s),ep(t.props)||a&&a.pendingBranch){ie(t);return}P&&(J(t,n,A),gs(t,!0)),ce()}else{t.el=e.el;const Q=t.anchor=e.anchor,A=Xn.get(e);if(A){A.flags|=8,Xn.delete(e),ie(t);return}t.targetStart=e.targetStart;const S=t.target=e.target,oe=t.targetAnchor=e.targetAnchor,ge=Sr(e.props),Y=ge?n:S,xe=ge?Q:oe;if(c==="svg"||ru(S)?c="svg":(c==="mathml"||su(S))&&(c="mathml"),L?(C(e.dynamicChildren,L,Y,o,a,c,d),ol(e,t,!0)):h||w(e,t,Y,xe,o,a,c,d,!1),P)ge?t.props&&e.props&&t.props.to!==e.props.to&&(t.props.to=e.props.to):xo(t,n,Q,y,1);else if((t.props&&t.props.to)!==(e.props&&e.props.to)){const Fe=_a(t.props,N);Fe&&(t.target=Fe,xo(t,Fe,null,y,0))}else ge&&xo(t,S,oe,y,1);gs(t,P)}},remove(e,t,n,{um:s,o:{remove:o}},a){const{shapeFlag:c,children:d,anchor:h,targetStart:y,targetAnchor:m,target:w,props:C}=e,O=Sr(C),N=a||!O,ee=Xn.get(e);if(ee&&(ee.flags|=8,Xn.delete(e)),w&&(o(y),o(m)),a&&o(h),!ee&&(O||w)&&c&16)for(let te=0;te{e.isMounted=!0}),Ac(()=>{e.isUnmounting=!0}),e}const on=[Function,Array],Cc={mode:String,appear:Boolean,persisted:Boolean,onBeforeEnter:on,onEnter:on,onAfterEnter:on,onEnterCancelled:on,onBeforeLeave:on,onLeave:on,onAfterLeave:on,onLeaveCancelled:on,onBeforeAppear:on,onAppear:on,onAfterAppear:on,onAppearCancelled:on},rp={name:"BaseTransition",props:Cc,setup(e,{slots:t}){const n=il(),s=xc();return()=>{const o=t.default&&nl(t.default(),!0),a=o&&o.length?Sc(o):n.subTree?Ee():void 0;if(!a)return;const c=ot(e),{mode:d}=c;if(s.isLeaving)return ia(a);const h=No(a);if(!h)return ia(a);let y=Is(h,c,s,n,w=>y=w);h.type!==Nt&&ir(h,y);let m=n.subTree&&No(n.subTree);if(m&&m.type!==Nt&&!Er(m,h)&&js(n.subTree)){let w=Is(m,c,s,n);if(ir(m,w),d==="out-in"&&h.type!==Nt)return s.isLeaving=!0,w.afterLeave=()=>{s.isLeaving=!1,n.job.flags&8||n.update(),delete w.afterLeave,m=void 0},ia(a);d==="in-out"&&h.type!==Nt?w.delayLeave=(C,O,N)=>{const ee=Ec(s,m);ee[String(m.key)]=m,C[an]=()=>{O(),C[an]=void 0,delete y.delayedLeave,m=void 0},y.delayedLeave=()=>{N(),delete y.delayedLeave,m=void 0}}:m=void 0}else m&&(m=void 0);return a}}};function Sc(e){let t=e[0];if(e.length>1){for(const n of e)if(n.type!==Nt){t=n;break}}return t}const sp=rp;function Ec(e,t){const{leavingVNodes:n}=e;let s=n.get(t.type);return s||(s=Object.create(null),n.set(t.type,s)),s}function Is(e,t,n,s,o){const{appear:a,mode:c,persisted:d=!1,onBeforeEnter:h,onEnter:y,onAfterEnter:m,onEnterCancelled:w,onBeforeLeave:C,onLeave:O,onAfterLeave:N,onLeaveCancelled:ee,onBeforeAppear:te,onAppear:ue,onAfterAppear:P,onAppearCancelled:L}=t,J=String(e.key),ce=Ec(n,e),ie=(S,oe)=>{S&&fn(S,s,9,oe)},Q=(S,oe)=>{const ge=oe[1];ie(S,oe),Ke(S)?S.every(Y=>Y.length<=1)&&ge():S.length<=1&&ge()},A={mode:c,persisted:d,beforeEnter(S){let oe=h;if(!n.isMounted)if(a)oe=te||h;else return;S[an]&&S[an](!0);const ge=ce[J];if(ge&&Er(e,ge)){let Y=ge.el[an];if(!Y){const xe=js(ge);Y=xe&&xe.el[an]}Y&&Y()}ie(oe,[S])},enter(S){if(ce[J]===e)return;let oe=y,ge=m,Y=w;if(!n.isMounted)if(a)oe=ue||y,ge=P||m,Y=L||w;else return;let xe=!1;S[ms]=rt=>{xe||(xe=!0,rt?ie(Y,[S]):ie(ge,[S]),A.delayedLeave&&A.delayedLeave(),S[ms]=void 0)};const Fe=S[ms].bind(null,!1);oe?Q(oe,[S,Fe]):Fe()},leave(S,oe){const ge=String(e.key);if(S[ms]&&S[ms](!0),n.isUnmounting)return oe();ie(C,[S]);let Y=!1;S[an]=Fe=>{Y||(Y=!0,oe(),Fe?ie(ee,[S]):ie(N,[S]),S[an]=void 0,ce[ge]===e&&delete ce[ge])};const xe=S[an].bind(null,!1);ce[ge]=e,O?Q(O,[S,xe]):xe()},clone(S){const oe=Is(S,t,n,s,o);return o&&o(oe),oe}};return A}function ia(e){if(pi(e))return e=ar(e),e.children=null,e}function No(e){if(!pi(e))return di(e.type)&&e.children?Sc(e.children):e;if(e.component)return e.component.subTree;const{shapeFlag:t,children:n}=e;if(n){if(t&16)return n[0];if(t&32&&Ge(n.default))return n.default()}}function ir(e,t){if(e.shapeFlag&6&&e.component){e.transition=t;const n=e.component.subTree;ir(di(n.type)&&No(n)||n,t)}else if(e.shapeFlag&128)e.ssContent.transition=t.clone(e.ssContent),e.ssFallback.transition=t.clone(e.ssFallback);else if(e.transition=t,e.type===Re&&Ke(e.children)){const n=Dc(e.children,!1);n&&ir(n,t)}}function nl(e,t=!1,n){let s=[],o=0;for(let a=0;a1)for(let a=0;aCs(ee,t&&(Ke(t)?t[te]:t),n,s,o));return}if(Ss(s)&&!o){s.shapeFlag&512&&s.type.__asyncResolved&&s.component.subTree.component&&Cs(e,t,n,s.component.subTree);return}const a=s.shapeFlag&4?yi(s.component):s.el,c=o?null:a,{i:d,r:h}=e,y=t&&t.r,m=d.refs===ft?d.refs={}:d.refs,w=d.setupState,C=ot(w),O=w===ft?Uu:ee=>ou(m,ee)?!1:it(C,ee),N=(ee,te)=>!(te&&ou(m,te));if(y!=null&&y!==h){if(iu(t),bt(y))m[y]=null,O(y)&&(w[y]=null);else if(Vt(y)){const ee=t;N(y,ee.k)&&(y.value=null),ee.k&&(m[ee.k]=null)}}if(Ge(h))Bs(h,d,12,[c,m]);else{const ee=bt(h),te=Vt(h);if(ee||te){const ue=()=>{if(e.f){const P=ee?O(h)?w[h]:m[h]:N()||!e.k?h.value:m[e.k];if(o)Ke(P)&&Ha(P,a);else if(Ke(P))P.includes(a)||P.push(a);else if(ee)m[h]=[a],O(h)&&(w[h]=m[h]);else{const L=[a];N(h,e.k)&&(h.value=L),e.k&&(m[e.k]=L)}}else ee?(m[h]=c,O(h)&&(w[h]=c)):te&&(N(h,e.k)&&(h.value=c),e.k&&(m[e.k]=c))};if(c){const P=()=>{ue(),Vo.delete(e)};P.id=-1,Vo.set(e,P),Wt(P,n)}else iu(e),ue()}}}function iu(e){const t=Vo.get(e);t&&(t.flags|=8,Vo.delete(e))}ui().requestIdleCallback;ui().cancelIdleCallback;const Ss=e=>!!e.type.__asyncLoader,pi=e=>e.type.__isKeepAlive;function op(e,t){Tc(e,"a",t)}function ip(e,t){Tc(e,"da",t)}function Tc(e,t,n=Gt){const s=e.__wdc||(e.__wdc=()=>{let o=n;for(;o;){if(o.isDeactivated)return;o=o.parent}return e()});if(hi(t,s,n),n){let o=n.parent;for(;o&&o.parent;)pi(o.parent.vnode)&&ap(s,t,n,o),o=o.parent}}function ap(e,t,n,s){const o=hi(t,e,s,!0);fr(()=>{Ha(s[t],o)},n)}function hi(e,t,n=Gt,s=!1){if(n){const o=n[e]||(n[e]=[]),a=t.__weh||(t.__weh=(...c)=>{Tn();const d=qs(n),h=fn(t,n,e,c);return d(),Pn(),h});return s?o.unshift(a):o.push(a),a}}const Bn=e=>(t,n=Gt)=>{(!Ks||e==="sp")&&hi(e,(...s)=>t(...s),n)},lp=Bn("bm"),mn=Bn("m"),up=Bn("bu"),Pc=Bn("u"),Ac=Bn("bum"),fr=Bn("um"),cp=Bn("sp"),fp=Bn("rtg"),dp=Bn("rtc");function pp(e,t=Gt){hi("ec",e,t)}const hp=Symbol.for("v-ndc");function ct(e,t,n,s){let o;const a=n,c=Ke(e);if(c||bt(e)){const d=c&&rr(e);let h=!1,y=!1;d&&(h=!un(e),y=An(e),e=ci(e)),o=new Array(e.length);for(let m=0,w=e.length;mt(d,h,void 0,a));else{const d=Object.keys(e);o=new Array(d.length);for(let h=0,y=d.length;he?Xc(e)?yi(e):xa(e.parent):null,Es=Et(Object.create(null),{$:e=>e,$el:e=>e.vnode.el,$data:e=>e.data,$props:e=>e.props,$attrs:e=>e.attrs,$slots:e=>e.slots,$refs:e=>e.refs,$parent:e=>xa(e.parent),$root:e=>xa(e.root),$host:e=>e.ce,$emit:e=>e.emit,$options:e=>Mc(e),$forceUpdate:e=>e.f||(e.f=()=>{tl(e.update)}),$nextTick:e=>e.n||(e.n=rs.bind(e.proxy)),$watch:e=>Zd.bind(e)}),aa=(e,t)=>e!==ft&&!e.__isScriptSetup&&it(e,t),vp={get({_:e},t){if(t==="__v_skip")return!0;const{ctx:n,setupState:s,data:o,props:a,accessCache:c,type:d,appContext:h}=e;if(t[0]!=="$"){const C=c[t];if(C!==void 0)switch(C){case 1:return s[t];case 2:return o[t];case 4:return n[t];case 3:return a[t]}else{if(aa(s,t))return c[t]=1,s[t];if(o!==ft&&it(o,t))return c[t]=2,o[t];if(it(a,t))return c[t]=3,a[t];if(n!==ft&&it(n,t))return c[t]=4,n[t];Ca&&(c[t]=0)}}const y=Es[t];let m,w;if(y)return t==="$attrs"&&Ft(e.attrs,"get",""),y(e);if((m=d.__cssModules)&&(m=m[t]))return m;if(n!==ft&&it(n,t))return c[t]=4,n[t];if(w=h.config.globalProperties,it(w,t))return w[t]},set({_:e},t,n){const{data:s,setupState:o,ctx:a}=e;return aa(o,t)?(o[t]=n,!0):s!==ft&&it(s,t)?(s[t]=n,!0):it(e.props,t)||t[0]==="$"&&t.slice(1)in e?!1:(a[t]=n,!0)},has({_:{data:e,setupState:t,accessCache:n,ctx:s,appContext:o,props:a,type:c}},d){let h;return!!(n[d]||e!==ft&&d[0]!=="$"&&it(e,d)||aa(t,d)||it(a,d)||it(s,d)||it(Es,d)||it(o.config.globalProperties,d)||(h=c.__cssModules)&&h[d])},defineProperty(e,t,n){return n.get!=null?e._.accessCache[t]=0:it(n,"value")&&this.set(e,t,n.value,null),Reflect.defineProperty(e,t,n)}};function au(e){return Ke(e)?e.reduce((t,n)=>(t[n]=null,t),{}):e}let Ca=!0;function mp(e){const t=Mc(e),n=e.proxy,s=e.ctx;Ca=!1,t.beforeCreate&&lu(t.beforeCreate,e,"bc");const{data:o,computed:a,methods:c,watch:d,provide:h,inject:y,created:m,beforeMount:w,mounted:C,beforeUpdate:O,updated:N,activated:ee,deactivated:te,beforeDestroy:ue,beforeUnmount:P,destroyed:L,unmounted:J,render:ce,renderTracked:ie,renderTriggered:Q,errorCaptured:A,serverPrefetch:S,expose:oe,inheritAttrs:ge,components:Y,directives:xe,filters:Fe}=t;if(y&&yp(y,s,null),c)for(const Ye in c){const me=c[Ye];Ge(me)&&(s[Ye]=me.bind(n))}if(o){const Ye=o.call(n,n);lt(Ye)&&(e.data=Qa(Ye))}if(Ca=!0,a)for(const Ye in a){const me=a[Ye],Me=Ge(me)?me.bind(n,n):Ge(me.get)?me.get.bind(n,n):En,Ne=!Ge(me)&&Ge(me.set)?me.set.bind(n):En,De=at({get:Me,set:Ne});Object.defineProperty(s,Ye,{enumerable:!0,configurable:!0,get:()=>De.value,set:Ce=>De.value=Ce})}if(d)for(const Ye in d)Oc(d[Ye],s,n,Ye);if(h){const Ye=Ge(h)?h.call(n):h;Reflect.ownKeys(Ye).forEach(me=>{Jd(me,Ye[me])})}m&&lu(m,e,"c");function We(Ye,me){Ke(me)?me.forEach(Me=>Ye(Me.bind(n))):me&&Ye(me.bind(n))}if(We(lp,w),We(mn,C),We(up,O),We(Pc,N),We(op,ee),We(ip,te),We(pp,A),We(dp,ie),We(fp,Q),We(Ac,P),We(fr,J),We(cp,S),Ke(oe))if(oe.length){const Ye=e.exposed||(e.exposed={});oe.forEach(me=>{Object.defineProperty(Ye,me,{get:()=>n[me],set:Me=>n[me]=Me,enumerable:!0})})}else e.exposed||(e.exposed={});ce&&e.render===En&&(e.render=ce),ge!=null&&(e.inheritAttrs=ge),Y&&(e.components=Y),xe&&(e.directives=xe),S&&$c(e)}function yp(e,t,n=En){Ke(e)&&(e=Sa(e));for(const s in e){const o=e[s];let a;lt(o)?"default"in o?a=To(o.from||s,o.default,!0):a=To(o.from||s):a=To(o),Vt(a)?Object.defineProperty(t,s,{enumerable:!0,configurable:!0,get:()=>a.value,set:c=>a.value=c}):t[s]=a}}function lu(e,t,n){fn(Ke(e)?e.map(s=>s.bind(t.proxy)):e.bind(t.proxy),t,n)}function Oc(e,t,n,s){let o=s.includes(".")?_c(n,s):()=>n[s];if(bt(e)){const a=t[e];Ge(a)&&vt(o,a)}else if(Ge(e))vt(o,e.bind(n));else if(lt(e))if(Ke(e))e.forEach(a=>Oc(a,t,n,s));else{const a=Ge(e.handler)?e.handler.bind(n):t[e.handler];Ge(a)&&vt(o,a,e)}}function Mc(e){const t=e.type,{mixins:n,extends:s}=t,{mixins:o,optionsCache:a,config:{optionMergeStrategies:c}}=e.appContext,d=a.get(t);let h;return d?h=d:!o.length&&!n&&!s?h=t:(h={},o.length&&o.forEach(y=>Bo(h,y,c,!0)),Bo(h,t,c)),lt(t)&&a.set(t,h),h}function Bo(e,t,n,s=!1){const{mixins:o,extends:a}=t;a&&Bo(e,a,n,!0),o&&o.forEach(c=>Bo(e,c,n,!0));for(const c in t)if(!(s&&c==="expose")){const d=gp[c]||n&&n[c];e[c]=d?d(e[c],t[c]):t[c]}return e}const gp={data:uu,props:cu,emits:cu,methods:bs,computed:bs,beforeCreate:Ht,created:Ht,beforeMount:Ht,mounted:Ht,beforeUpdate:Ht,updated:Ht,beforeDestroy:Ht,beforeUnmount:Ht,destroyed:Ht,unmounted:Ht,activated:Ht,deactivated:Ht,errorCaptured:Ht,serverPrefetch:Ht,components:bs,directives:bs,watch:wp,provide:uu,inject:bp};function uu(e,t){return t?e?function(){return Et(Ge(e)?e.call(this,this):e,Ge(t)?t.call(this,this):t)}:t:e}function bp(e,t){return bs(Sa(e),Sa(t))}function Sa(e){if(Ke(e)){const t={};for(let n=0;nt==="modelValue"||t==="model-value"?e.modelModifiers:e[`${t}Modifiers`]||e[`${hn(t)}Modifiers`]||e[`${ur(t)}Modifiers`];function Cp(e,t,...n){if(e.isUnmounted)return;const s=e.vnode.props||ft;let o=n;const a=t.startsWith("update:"),c=a&&xp(s,t.slice(7));c&&(c.trim&&(o=n.map(m=>bt(m)?m.trim():m)),c.number&&(o=o.map(li)));let d,h=s[d=ea(t)]||s[d=ea(hn(t))];!h&&a&&(h=s[d=ea(ur(t))]),h&&fn(h,e,6,o);const y=s[d+"Once"];if(y){if(!e.emitted)e.emitted={};else if(e.emitted[d])return;e.emitted[d]=!0,fn(y,e,6,o)}}const Sp=new WeakMap;function jc(e,t,n=!1){const s=n?Sp:t.emitsCache,o=s.get(e);if(o!==void 0)return o;const a=e.emits;let c={},d=!1;if(!Ge(e)){const h=y=>{const m=jc(y,t,!0);m&&(d=!0,Et(c,m))};!n&&t.mixins.length&&t.mixins.forEach(h),e.extends&&h(e.extends),e.mixins&&e.mixins.forEach(h)}return!a&&!d?(lt(e)&&s.set(e,null),null):(Ke(a)?a.forEach(h=>c[h]=null):Et(c,a),lt(e)&&s.set(e,c),c)}function vi(e,t){return!e||!oi(t)?!1:(t=t.slice(2),t=t==="Once"?t:t.replace(/Once$/,""),it(e,t[0].toLowerCase()+t.slice(1))||it(e,ur(t))||it(e,t))}function fu(e){const{type:t,vnode:n,proxy:s,withProxy:o,propsOptions:[a],slots:c,attrs:d,emit:h,render:y,renderCache:m,props:w,data:C,setupState:O,ctx:N,inheritAttrs:ee}=e,te=Fo(e);let ue,P;try{if(n.shapeFlag&4){const J=o||s,ce=J;ue=Cn(y.call(ce,J,m,w,O,C,N)),P=d}else{const J=t;ue=Cn(J.length>1?J(w,{attrs:d,slots:c,emit:h}):J(w,null)),P=t.props?d:Ep(d)}}catch(J){Or.length=0,fi(J,e,1),ue=Oe(Nt)}let L=ue;if(P&&ee!==!1){const J=Object.keys(P),{shapeFlag:ce}=L;J.length&&ce&7&&(a&&J.some(ii)&&(P=$p(P,a)),L=ar(L,P,!1,!0))}if(n.dirs&&(L=ar(L,null,!1,!0),L.dirs=L.dirs?L.dirs.concat(n.dirs):n.dirs),n.transition){const J=di(L.type)&&No(L)||L;ir(J,n.transition)}return ue=L,Fo(te),ue}function Dc(e,t=!0){let n;for(let s=0;s{let t;for(const n in e)(n==="class"||n==="style"||oi(n))&&((t||(t={}))[n]=e[n]);return t},$p=(e,t)=>{const n={};for(const s in e)(!ii(s)||!(s.slice(9)in t))&&(n[s]=e[s]);return n};function Tp(e,t,n){const{props:s,children:o,component:a}=e,{props:c,children:d,patchFlag:h}=t,y=a.emitsOptions;if(t.dirs||t.transition)return!0;if(n&&h>=0){if(h&1024)return!0;if(h&16)return s?du(s,c,y):!!c;if(h&8){const m=t.dynamicProps;for(let w=0;wObject.create(Rc),Fc=e=>Object.getPrototypeOf(e)===Rc;function Ap(e,t,n,s=!1){const o={},a=Kc();e.propsDefaults=Object.create(null),Nc(e,t,o,a);for(const c in e.propsOptions[0])c in o||(o[c]=void 0);n?e.props=s?o:Rd(o):e.type.props?e.props=o:e.props=a,e.attrs=a}function Op(e,t,n,s){const{props:o,attrs:a,vnode:{patchFlag:c}}=e,d=ot(o),[h]=e.propsOptions;let y=!1;if((s||c>0)&&!(c&16)){if(c&8){const m=e.vnode.dynamicProps;for(let w=0;w{h=!0;const[C,O]=Vc(w,t,!0);Et(c,C),O&&d.push(...O)};!n&&t.mixins.length&&t.mixins.forEach(m),e.extends&&m(e.extends),e.mixins&&e.mixins.forEach(m)}if(!a&&!h)return lt(e)&&s.set(e,Tr),Tr;if(Ke(a))for(let m=0;me==="_"||e==="_ctx"||e==="$stable",sl=e=>Ke(e)?e.map(Cn):[Cn(e)],Ip=(e,t,n)=>{if(t._n)return t;const s=cr((...o)=>sl(t(...o)),n);return s._c=!1,s},Bc=(e,t,n)=>{const s=e._ctx;for(const o in e){if(rl(o))continue;const a=e[o];if(Ge(a))t[o]=Ip(o,a,s);else if(a!=null){const c=sl(a);t[o]=()=>c}}},Uc=(e,t)=>{const n=sl(t);e.slots.default=()=>n},qc=(e,t,n)=>{for(const s in t)(n||!rl(s))&&(e[s]=t[s])},jp=(e,t,n)=>{const s=e.slots=Kc();if(e.vnode.shapeFlag&32){const o=t._;o?(qc(s,t,n),n&&Gu(s,"_",o,!0)):Bc(t,s)}else t&&Uc(e,t)},Dp=(e,t,n)=>{const{vnode:s,slots:o}=e;let a=!0,c=ft;if(s.shapeFlag&32){const d=t._;d?n&&d===1?a=!1:qc(o,t,n):(a=!t.$stable,Bc(t,o)),c=t}else t&&(Uc(e,t),c={default:1});if(a)for(const d in o)!rl(d)&&c[d]==null&&delete o[d]},Wt=Np;function Lp(e){return Rp(e)}function Rp(e,t){const n=ui();n.__VUE__=!0;const{insert:s,remove:o,patchProp:a,createElement:c,createText:d,createComment:h,setText:y,setElementText:m,parentNode:w,nextSibling:C,setScopeId:O=En,insertStaticContent:N}=e,ee=(k,_,x,z=null,ne=null,le=null,be=void 0,ve=null,ae=!!_.dynamicChildren)=>{if(k===_)return;k&&!Er(k,_)&&(z=dt(k),Ce(k,ne,le,!0),k=null),_.patchFlag===-2&&(ae=!1,_.dynamicChildren=null),_.dynamicChildren&&k&&k.dynamicChildren&&k.dynamicChildren.hasOnce&&(_.dynamicChildren===Tr&&(_.dynamicChildren=[]),_.dynamicChildren.hasOnce=!0);const{type:U,ref:q,shapeFlag:G}=_;switch(U){case mi:te(k,_,x,z);break;case Nt:ue(k,_,x,z);break;case Po:k==null&&P(_,x,z,be);break;case Re:Y(k,_,x,z,ne,le,be,ve,ae);break;default:G&1?ce(k,_,x,z,ne,le,be,ve,ae):G&6?xe(k,_,x,z,ne,le,be,ve,ae):(G&64||G&128)&&U.process(k,_,x,z,ne,le,be,ve,ae,Xt)}q!=null&&ne?Cs(q,k&&k.ref,le,_||k,!_):q==null&&k&&k.ref!=null&&Cs(k.ref,null,le,k,!0)},te=(k,_,x,z)=>{if(k==null)s(_.el=d(_.children),x,z);else{const ne=_.el=k.el;_.children!==k.children&&y(ne,_.children)}},ue=(k,_,x,z)=>{k==null?s(_.el=h(_.children||""),x,z):_.el=k.el},P=(k,_,x,z)=>{[k.el,k.anchor]=N(k.children,_,x,z,k.el,k.anchor)},L=({el:k,anchor:_},x,z)=>{let ne;for(;k&&k!==_;)ne=C(k),s(k,x,z),k=ne;s(_,x,z)},J=({el:k,anchor:_})=>{let x;for(;k&&k!==_;)x=C(k),o(k),k=x;o(_)},ce=(k,_,x,z,ne,le,be,ve,ae)=>{if(_.type==="svg"?be="svg":_.type==="math"&&(be="mathml"),k==null)ie(_,x,z,ne,le,be,ve,ae);else{const U=k.el&&k.el._isVueCE?k.el:null;try{U&&U._beginPatch(),S(k,_,ne,le,be,ve,ae)}finally{U&&U._endPatch()}}},ie=(k,_,x,z,ne,le,be,ve)=>{let ae,U;const{props:q,shapeFlag:G,transition:$e,dirs:Ve}=k;if(ae=k.el=c(k.type,le,q&&q.is,q),G&8?m(ae,k.children):G&16&&A(k.children,ae,null,z,ne,la(k,le),be,ve),Ve&&_r(k,null,z,"created"),Q(ae,k,k.scopeId,be,z),q){for(const Xe in q)Xe!=="value"&&!_s(Xe)&&a(ae,Xe,null,q[Xe],le,z);"value"in q&&a(ae,"value",null,q.value,le),(U=q.onVnodeBeforeMount)&&bn(U,z,k)}Ve&&_r(k,null,z,"beforeMount");const Qe=Kp(ne,$e);Qe&&$e.beforeEnter(ae),s(ae,_,x),((U=q&&q.onVnodeMounted)||Qe||Ve)&&Wt(()=>{try{U&&bn(U,z,k),Qe&&$e.enter(ae),Ve&&_r(k,null,z,"mounted")}finally{}},ne)},Q=(k,_,x,z,ne)=>{if(x&&O(k,x),z)for(let le=0;le{for(let U=ae;U{const ve=_.el=k.el;let{patchFlag:ae,dynamicChildren:U,dirs:q}=_;ae|=k.patchFlag&16;const G=k.props||ft,$e=_.props||ft;let Ve;if(x&&kr(x,!1),(Ve=$e.onVnodeBeforeUpdate)&&bn(Ve,x,_,k),q&&_r(_,k,x,"beforeUpdate"),x&&kr(x,!0),U&&(!k.dynamicChildren||k.dynamicChildren.length!==U.length)&&(ae=0,be=!1,U=null),(G.innerHTML&&$e.innerHTML==null||G.textContent&&$e.textContent==null)&&m(ve,""),U?oe(k.dynamicChildren,U,ve,x,z,la(_,ne),le):be||me(k,_,ve,null,x,z,la(_,ne),le,!1),ae>0){if(ae&16)ge(ve,G,$e,x,ne);else if(ae&2&&G.class!==$e.class&&a(ve,"class",null,$e.class,ne),ae&4&&a(ve,"style",G.style,$e.style,ne),ae&8){const Qe=_.dynamicProps;for(let Xe=0;Xe{Ve&&bn(Ve,x,_,k),q&&_r(_,k,x,"updated")},z)},oe=(k,_,x,z,ne,le,be)=>{for(let ve=0;ve<_.length;ve++){const ae=k[ve],U=_[ve],q=ae.el||$a(ae),G=q&&(ae.type===Re||!Er(ae,U)||ae.shapeFlag&198)?w(q):x;ee(ae,U,G,null,z,ne,le,be,!0)}},ge=(k,_,x,z,ne)=>{if(_!==x){if(_!==ft)for(const le in _)!_s(le)&&!(le in x)&&a(k,le,_[le],null,ne,z);for(const le in x){if(_s(le))continue;const be=x[le],ve=_[le];be!==ve&&le!=="value"&&a(k,le,ve,be,ne,z)}"value"in x&&a(k,"value",_.value,x.value,ne)}},Y=(k,_,x,z,ne,le,be,ve,ae)=>{const U=_.el=k?k.el:d(""),q=_.anchor=k?k.anchor:d("");let{patchFlag:G,dynamicChildren:$e,slotScopeIds:Ve}=_;Ve&&(ve=ve?ve.concat(Ve):Ve),k==null?(s(U,x,z),s(q,x,z),A(_.children||[],x,q,ne,le,be,ve,ae)):G>0&&G&64&&$e&&k.dynamicChildren&&k.dynamicChildren.length===$e.length?(oe(k.dynamicChildren,$e,x,ne,le,be,ve),(_.key!=null||ne&&_===ne.subTree)&&ol(k,_,!0)):me(k,_,x,q,ne,le,be,ve,ae)},xe=(k,_,x,z,ne,le,be,ve,ae)=>{_.slotScopeIds=ve,k==null?_.shapeFlag&512?ne.ctx.activate(_,x,z,be,ae):Fe(_,x,z,ne,le,be,ae):rt(k,_,ae)},Fe=(k,_,x,z,ne,le,be)=>{const ve=k.component=zp(k,z,ne);if(pi(k)&&(ve.ctx.renderer=Xt),Gp(ve,!1,be),ve.asyncDep){if(ne&&ne.registerDep(ve,We,be,le),!k.el){const ae=ve.subTree=Oe(Nt);ue(null,ae,_,x),k.placeholder=ae.el}}else We(ve,k,_,x,ne,le,be)},rt=(k,_,x)=>{const z=_.component=k.component;if(Tp(k,_,x))if(z.asyncDep&&!z.asyncResolved){_.el=k.el,_.placeholder=k.placeholder,Ye(z,_,x);return}else z.next=_,z.update();else _.el=k.el,_.placeholder=k.placeholder,z.vnode=_},We=(k,_,x,z,ne,le,be)=>{const ve=()=>{if(k.isMounted){let{next:G,bu:$e,u:Ve,parent:Qe,vnode:Xe}=k;{const Ut=Hc(k);if(Ut){G&&(G.el=Xe.el,Ye(k,G,be)),Ut.asyncDep.then(()=>{Wt(()=>{k.isUnmounted||U()},ne)});return}}let Ze=G,mt;kr(k,!1),G?(G.el=Xe.el,Ye(k,G,be)):G=Xe,$e&&$o($e),(mt=G.props&&G.props.onVnodeBeforeUpdate)&&bn(mt,Qe,G,Xe),kr(k,!0);const kt=fu(k),Qt=k.subTree;k.subTree=kt,ee(Qt,kt,w(Qt.el),dt(Qt),k,ne,le),G.el=kt.el,Ze===null&&Pp(k,kt.el),Ve&&Wt(Ve,ne),(mt=G.props&&G.props.onVnodeUpdated)&&Wt(()=>bn(mt,Qe,G,Xe),ne)}else{let G;const{el:$e,props:Ve}=_,{bm:Qe,m:Xe,parent:Ze,root:mt,type:kt}=k,Qt=Ss(_);kr(k,!1),Qe&&$o(Qe),!Qt&&(G=Ve&&Ve.onVnodeBeforeMount)&&bn(G,Ze,_),kr(k,!0);{mt.ce&&mt.ce._hasShadowRoot()&&mt.ce._injectChildStyle(kt,k.parent?k.parent.type:void 0);const Ut=k.subTree=fu(k);ee(null,Ut,x,z,k,ne,le),_.el=Ut.el}if(Xe&&Wt(Xe,ne),!Qt&&(G=Ve&&Ve.onVnodeMounted)){const Ut=_;Wt(()=>bn(G,Ze,Ut),ne)}(_.shapeFlag&256||Ze&&Ss(Ze.vnode)&&Ze.vnode.shapeFlag&256)&&k.a&&Wt(k.a,ne),k.isMounted=!0,_=x=z=null}};k.scope.on();const ae=k.effect=new Qu(ve);k.scope.off();const U=k.update=ae.run.bind(ae),q=k.job=ae.runIfDirty.bind(ae);q.i=k,q.id=k.uid,ae.scheduler=()=>tl(q),kr(k,!0),U()},Ye=(k,_,x)=>{_.component=k;const z=k.vnode.props;k.vnode=_,k.next=null,Op(k,_.props,z,x),Dp(k,_.children,x),Tn(),mc(k),Pn()},me=(k,_,x,z,ne,le,be,ve,ae=!1)=>{const U=k&&k.children,q=k?k.shapeFlag:0,G=_.children,{patchFlag:$e,shapeFlag:Ve}=_;if($e>0){if($e&128){Ne(U,G,x,z,ne,le,be,ve,ae);return}else if($e&256){Me(U,G,x,z,ne,le,be,ve,ae);return}}Ve&8?(q&16&&Be(U,ne,le),G!==U&&m(x,G)):q&16?Ve&16?Ne(U,G,x,z,ne,le,be,ve,ae):Be(U,ne,le,!0):(q&8&&m(x,""),Ve&16&&A(G,x,z,ne,le,be,ve,ae))},Me=(k,_,x,z,ne,le,be,ve,ae)=>{k=k||Tr,_=_||Tr;const U=k.length,q=_.length,G=Math.min(U,q);let $e;for($e=0;$eq?Be(k,ne,le,!0,!1,G):A(_,x,z,ne,le,be,ve,ae,G)},Ne=(k,_,x,z,ne,le,be,ve,ae)=>{let U=0;const q=_.length;let G=k.length-1,$e=q-1;for(;U<=G&&U<=$e;){const Ve=k[U],Qe=_[U]=ae?Dn(_[U]):Cn(_[U]);if(Er(Ve,Qe))ee(Ve,Qe,x,null,ne,le,be,ve,ae);else break;U++}for(;U<=G&&U<=$e;){const Ve=k[G],Qe=_[$e]=ae?Dn(_[$e]):Cn(_[$e]);if(Er(Ve,Qe))ee(Ve,Qe,x,null,ne,le,be,ve,ae);else break;G--,$e--}if(U>G){if(U<=$e){const Ve=$e+1,Qe=Ve$e)for(;U<=G;)Ce(k[U],ne,le,!0),U++;else{const Ve=U,Qe=U,Xe=new Map;for(U=Qe;U<=$e;U++){const Ot=_[U]=ae?Dn(_[U]):Cn(_[U]);Ot.key!=null&&Xe.set(Ot.key,U)}let Ze,mt=0;const kt=$e-Qe+1;let Qt=!1,Ut=0;const en=new Array(kt);for(U=0;U=kt){Ce(Ot,ne,le,!0);continue}let $t;if(Ot.key!=null)$t=Xe.get(Ot.key);else for(Ze=Qe;Ze<=$e;Ze++)if(en[Ze-Qe]===0&&Er(Ot,_[Ze])){$t=Ze;break}$t===void 0?Ce(Ot,ne,le,!0):(en[$t-Qe]=U+1,$t>=Ut?Ut=$t:Qt=!0,ee(Ot,_[$t],x,null,ne,le,be,ve,ae),mt++)}const pr=Qt?Fp(en):Tr;for(Ze=pr.length-1,U=kt-1;U>=0;U--){const Ot=Qe+U,$t=_[Ot],Ie=_[Ot+1],Un=Ot+1{const{el:le,type:be,transition:ve,children:ae,shapeFlag:U}=k;if(U&6){De(k.component.subTree,_,x,z);return}if(U&128){k.suspense.move(_,x,z);return}if(U&64){be.move(k,_,x,Xt);return}if(be===Re){s(le,_,x);for(let G=0;Gve.enter(le),ne));else{const{leave:G,delayLeave:$e,afterLeave:Ve}=ve,Qe=()=>{k.ctx.isUnmounted?o(le):s(le,_,x)},Xe=()=>{const Ze=le._isLeaving||!!le[an];le._isLeaving&&le[an](!0),ve.persisted&&!Ze?Qe():G(le,()=>{Qe(),Ve&&Ve()})};$e?$e(le,Qe,Xe):Xe()}else s(le,_,x)},Ce=(k,_,x,z=!1,ne=!1)=>{const{type:le,props:be,ref:ve,children:ae,dynamicChildren:U,shapeFlag:q,patchFlag:G,dirs:$e,cacheIndex:Ve,memo:Qe}=k;if((G===-2||U&&U.hasOnce)&&(ne=!1),ve!=null&&(Tn(),Cs(ve,null,x,k,!0),Pn()),Ve!=null&&(!k.ctx||k.ctx===_)&&(_.renderCache[Ve]=void 0),q&256){_.ctx.deactivate(k);return}const Xe=q&1&&$e,Ze=!Ss(k);let mt;if(Ze&&(mt=be&&be.onVnodeBeforeUnmount)&&bn(mt,_,k),q&6)ke(k.component,x,z);else{if(q&128){k.suspense.unmount(x,z);return}Xe&&_r(k,null,_,"beforeUnmount"),q&64?k.type.remove(k,_,x,Xt,z):U&&!U.hasOnce&&(le!==Re||G>0&&G&64)?Be(U,_,x,!1,!0):(le===Re&&G&384||!ne&&q&16)&&Be(ae,_,x),z&&X(k)}const kt=Qe!=null&&Ve==null;(Ze&&(mt=be&&be.onVnodeUnmounted)||Xe||kt)&&Wt(()=>{mt&&bn(mt,_,k),Xe&&_r(k,null,_,"unmounted"),kt&&(k.el=null)},x)},X=k=>{const{type:_,el:x,anchor:z,transition:ne}=k,le=_===Re;if(le&&!ne){Z(x,z);return}if(_===Po){J(k),ne&&!ne.persisted&&ne.afterLeave&&ne.afterLeave();return}const be=le?js(k):k,ve=()=>{le?w(x)&&Z(x,z):o(x),ne&&!ne.persisted&&ne.afterLeave&&ne.afterLeave()};if(be&&be.shapeFlag&1&&ne&&!ne.persisted){const{leave:ae,delayLeave:U}=ne,q=be.el,G=()=>ae(q,ve);U?U(q,ve,G):G()}else ve()},Z=(k,_)=>{let x;for(;k!==_;)x=C(k),o(k),k=x;o(_)},ke=(k,_,x)=>{const{bum:z,scope:ne,job:le,subTree:be,um:ve,m:ae,a:U}=k;hu(ae),hu(U),z&&$o(z),ne.stop(),le?(le.flags|=8,Ce(be,k,_,x)):k.vnode.el&&be&&(be.transition=k.vnode.transition,Ce(be,k,_,x)),ve&&Wt(ve,_),Wt(()=>{k.isUnmounted=!0},_)},Be=(k,_,x,z=!1,ne=!1,le=0)=>{for(let be=le;be{if(k.shapeFlag&6)return dt(k.component.subTree);if(k.shapeFlag&128)return k.suspense.next();const _=C(k.anchor||k.el),x=_&&_[kc];return x?C(x):_},Jt=(k,_,x)=>{const z=k&&_._vnode?void 0:k&&k.component?k.component.uid:Wp();Yd(()=>{k==null?_._vnode&&Ce(_._vnode,null,null,!0):ee(_._vnode||null,k,_,null,null,null,x),_._vnode=k},z)},Xt={p:ee,um:Ce,m:De,r:X,mt:Fe,mc:A,pc:me,pbc:oe,n:dt,o:e};return{render:Jt,hydrate:void 0,createApp:kp(Jt)}}function la({type:e,props:t},n){return n==="svg"&&e==="foreignObject"||n==="mathml"&&e==="annotation-xml"&&t&&t.encoding&&t.encoding.includes("html")?void 0:n}function kr({effect:e,job:t},n){n?(e.flags|=32,t.flags|=4):(e.flags&=-33,t.flags&=-5)}function Kp(e,t){return(!e||e&&!e.pendingBranch)&&t&&!t.persisted}function ol(e,t,n=!1){const s=e.children,o=t.children;if(Ke(s)&&Ke(o))for(let a=0;a>1,e[n[d]]0&&(t[s]=n[a-1]),n[a]=s)}}for(a=n.length,c=n[a-1];a-- >0;)n[a]=c,c=t[c];return n}function Hc(e){const t=e.subTree.component;if(t)return t.asyncDep&&!t.asyncResolved?t:Hc(t)}function hu(e){if(e)for(let t=0;te.__isSuspense;function Np(e,t){t&&t.pendingBranch?Ke(e)?t.effects.push(...e):t.effects.push(e):Gd(e)}const Re=Symbol.for("v-fgt"),mi=Symbol.for("v-txt"),Nt=Symbol.for("v-cmt"),Po=Symbol.for("v-stc"),Or=[];let sn=null;function K(e=!1){Or.push(sn=e?null:[])}function zc(){Or.pop(),sn=Or[Or.length-1]||null}let Ds=1;function Uo(e,t=!1){Ds+=e,e<0&&sn&&t&&(sn.hasOnce=!0)}function Gc(e){return e.dynamicChildren=Ds>0?sn||Tr:null,zc(),Ds>0&&sn&&sn.push(e),e}function H(e,t,n,s,o,a){return Gc(u(e,t,n,s,o,a,!0))}function It(e,t,n,s,o){return Gc(Oe(e,t,n,s,o,!0))}function Ls(e){return e?e.__v_isVNode===!0:!1}function Er(e,t){return e.type===t.type&&e.key===t.key}const Yc=({key:e})=>e??null,Ao=({ref:e,ref_key:t,ref_for:n})=>(typeof e=="number"&&(e=""+e),e!=null?bt(e)||Vt(e)||Ge(e)?{i:ln,r:e,k:t,f:!!n}:e:null);function u(e,t=null,n=null,s=0,o=null,a=e===Re?0:1,c=!1,d=!1){const h={__v_isVNode:!0,__v_skip:!0,type:e,props:t,key:t&&Yc(t),ref:t&&Ao(t),scopeId:bc,slotScopeIds:null,children:n,component:null,suspense:null,ssContent:null,ssFallback:null,dirs:null,transition:null,el:null,anchor:null,target:null,targetStart:null,targetAnchor:null,staticCount:0,shapeFlag:a,patchFlag:s,dynamicProps:o,dynamicChildren:null,appContext:null,ctx:ln};return d?(qo(h,n),a&128&&e.normalize(h)):n&&(h.shapeFlag|=bt(n)?8:16),Ds>0&&!c&&sn&&(h.patchFlag>0||a&6)&&h.patchFlag!==32&&sn.push(h),h}const Oe=Vp;function Vp(e,t=null,n=null,s=0,o=null,a=!1){if((!e||e===hp)&&(e=Nt),Ls(e)){const d=ar(e,t,!0);return n&&qo(d,n),Ds>0&&!a&&sn&&(d.shapeFlag&6?sn[sn.indexOf(e)]=d:sn.push(d)),d.patchFlag=-2,d}if(Qp(e)&&(e=e.__vccOpts),t){t=Bp(t);let{class:d,style:h}=t;d&&!bt(d)&&(t.class=tt(d)),lt(h)&&(el(h)&&!Ke(h)&&(h=Et({},h)),t.style=nr(h))}const c=bt(e)?1:Wc(e)?128:di(e)?64:lt(e)?4:Ge(e)?2:0;return u(e,t,n,s,o,c,a,!0)}function Bp(e){return e?el(e)||Fc(e)?Et({},e):e:null}function ar(e,t,n=!1,s=!1){const{props:o,ref:a,patchFlag:c,children:d,transition:h}=e,y=t?qp(o||{},t):o,m={__v_isVNode:!0,__v_skip:!0,type:e.type,props:y,key:y&&Yc(y),ref:t&&t.ref?n&&a?Ke(a)?a.concat(Ao(t)):[a,Ao(t)]:Ao(t):a,scopeId:e.scopeId,slotScopeIds:e.slotScopeIds,children:d,target:e.target,targetStart:e.targetStart,targetAnchor:e.targetAnchor,staticCount:e.staticCount,shapeFlag:e.shapeFlag,patchFlag:t&&e.type!==Re?c===-1?16:c|16:c,dynamicProps:e.dynamicProps,dynamicChildren:e.dynamicChildren,appContext:e.appContext,dirs:e.dirs,transition:h,component:e.component,suspense:e.suspense,ssContent:e.ssContent&&ar(e.ssContent),ssFallback:e.ssFallback&&ar(e.ssFallback),placeholder:e.placeholder,el:e.el,anchor:e.anchor,ctx:e.ctx,ce:e.ce,cacheIndex:e.cacheIndex};return h&&s&&ir(m,h.clone(m)),m}function rn(e=" ",t=0){return Oe(mi,null,e,t)}function Up(e,t){const n=Oe(Po,null,e);return n.staticCount=t,n}function Ee(e="",t=!1){return t?(K(),It(Nt,null,e)):Oe(Nt,null,e)}function Cn(e){return e==null||typeof e=="boolean"?Oe(Nt):Ke(e)?Oe(Re,null,e.slice()):Ls(e)?Dn(e):Oe(mi,null,String(e))}function Dn(e){return e.el===null&&e.patchFlag!==-1||e.memo?e:ar(e)}function qo(e,t){let n=0;const{shapeFlag:s}=e;if(t==null)t=null;else if(Ke(t))n=16;else if(typeof t=="object")if(s&65){const o=t.default;o&&(o._c&&(o._d=!1),qo(e,o()),o._c&&(o._d=!0));return}else{n=32;const o=t._;!o&&!Fc(t)?t._ctx=ln:o===3&&ln&&(ln.slots._===1?t._=1:(t._=2,e.patchFlag|=1024))}else if(Ge(t)){if(s&65){qo(e,{default:t});return}t={default:t,_ctx:ln},n=32}else t=String(t),s&64?(n=16,t=[rn(t)]):n=8;e.children=t,e.shapeFlag|=n}function qp(...e){const t={};for(let n=0;nGt||ln;let Ho,Rs;{const e=ui(),t=(n,s)=>{let o;return(o=e[n])||(o=e[n]=[]),o.push(s),a=>{o.length>1?o.forEach(c=>c(a)):o[0](a)}};Ho=t("__VUE_INSTANCE_SETTERS__",n=>Gt=n),Rs=t("__VUE_SSR_SETTERS__",n=>Ks=n)}const qs=e=>{const t=Gt;return Ho(e),e.scope.on(),()=>{e.scope.off(),Ho(t)}},vu=()=>{Gt&&Gt.scope.off(),Ho(null)};function Xc(e){return e.vnode.shapeFlag&4}let Ks=!1;function Gp(e,t=!1,n=!1){t&&Rs(t);const{props:s,children:o}=e.vnode,a=Xc(e);Ap(e,s,a,t),jp(e,o,n||t);const c=a?Yp(e,t):void 0;return t&&Rs(!1),c}function Yp(e,t){const n=e.type;e.accessCache=Object.create(null),e.proxy=new Proxy(e.ctx,vp);const{setup:s}=n;if(s){Tn();const o=e.setupContext=s.length>1?Xp(e):null,a=qs(e),c=Bs(s,e,0,[e.props,o]),d=qu(c);if(Pn(),a(),(d||e.sp)&&!Ss(e)&&$c(e),d){if(c.then(vu,vu),t)return c.then(h=>{Rs(!0);try{mu(e,h,t)}finally{Rs(!1)}}).catch(h=>{fi(h,e,0)});e.asyncDep=c}else mu(e,c)}else Qc(e)}function mu(e,t,n){Ge(t)?e.type.__ssrInlineRender?e.ssrRender=t:e.render=t:lt(t)&&(e.setupState=pc(t)),Qc(e)}function Qc(e,t,n){const s=e.type;e.render||(e.render=s.render||En);{const o=qs(e);Tn();try{mp(e)}finally{Pn(),o()}}}const Jp={get(e,t){return Ft(e,"get",""),e[t]}};function Xp(e){const t=n=>{e.exposed=n||{}};return{attrs:new Proxy(e.attrs,Jp),slots:e.slots,emit:e.emit,expose:t}}function yi(e){return e.exposed?e.exposeProxy||(e.exposeProxy=new Proxy(pc(Kd(e.exposed)),{get(t,n){if(n in t)return t[n];if(n in Es)return Es[n](e)},has(t,n){return n in t||n in Es}})):e.proxy}function Qp(e){return Ge(e)&&"__vccOpts"in e}const at=(e,t)=>Ud(e,t,Ks);function Zp(e,t,n){try{Uo(-1);const s=arguments.length;return s===2?lt(t)&&!Ke(t)?Ls(t)?Oe(e,null,[t]):Oe(e,t):Oe(e,null,t):(s>3?n=Array.prototype.slice.call(arguments,2):s===3&&Ls(n)&&(n=[n]),Oe(e,t,n))}finally{Uo(1)}}const eh="3.5.44";/** +* @vue/runtime-dom v3.5.44 +* (c) 2018-present Yuxi (Evan) You and Vue contributors +* @license MIT +**/let Ta;const yu=typeof window<"u"&&window.trustedTypes;if(yu)try{Ta=yu.createPolicy("vue",{createHTML:e=>e})}catch{}const Zc=Ta?e=>Ta.createHTML(e):e=>e,th="http://www.w3.org/2000/svg",nh="http://www.w3.org/1998/Math/MathML",jn=typeof document<"u"?document:null,gu=jn&&jn.createElement("template"),rh={insert:(e,t,n)=>{t.insertBefore(e,n||null)},remove:e=>{const t=e.parentNode;t&&t.removeChild(e)},createElement:(e,t,n,s)=>{const o=t==="svg"?jn.createElementNS(th,e):t==="mathml"?jn.createElementNS(nh,e):n?jn.createElement(e,{is:n}):jn.createElement(e);return e==="select"&&s&&s.multiple!=null&&o.setAttribute("multiple",s.multiple),o},createText:e=>jn.createTextNode(e),createComment:e=>jn.createComment(e),setText:(e,t)=>{e.nodeValue=t},setElementText:(e,t)=>{e.textContent=t},parentNode:e=>e.parentNode,nextSibling:e=>e.nextSibling,querySelector:e=>jn.querySelector(e),setScopeId(e,t){e.setAttribute(t,"")},insertStaticContent(e,t,n,s,o,a){const c=n?n.previousSibling:t.lastChild;if(o&&(o===a||o.nextSibling))for(;t.insertBefore(o.cloneNode(!0),n),!(o===a||!(o=o.nextSibling)););else{gu.innerHTML=Zc(s==="svg"?`${e}`:s==="mathml"?`${e}`:e);const d=gu.content;if(s==="svg"||s==="mathml"){const h=d.firstChild;for(;h.firstChild;)d.appendChild(h.firstChild);d.removeChild(h)}t.insertBefore(d,n)}return[c?c.nextSibling:t.firstChild,n?n.previousSibling:t.lastChild]}},Jn="transition",ys="animation",Zr=Symbol("_vtc"),ef={name:String,type:String,css:{type:Boolean,default:!0},duration:[String,Number,Object],enterFromClass:String,enterActiveClass:String,enterToClass:String,appearFromClass:String,appearActiveClass:String,appearToClass:String,leaveFromClass:String,leaveActiveClass:String,leaveToClass:String},tf=Et({},Cc,ef),sh=e=>(e.displayName="Transition",e.props=tf,e),ss=sh((e,{slots:t})=>Zp(sp,nf(e),t)),xr=(e,t=[])=>{Ke(e)?e.forEach(n=>n(...t)):e&&e(...t)},bu=e=>e?Ke(e)?e.some(t=>t.length>1):e.length>1:!1;function nf(e){const t={};for(const Y in e)Y in ef||(t[Y]=e[Y]);if(e.css===!1)return t;const{name:n="v",type:s,duration:o,enterFromClass:a=`${n}-enter-from`,enterActiveClass:c=`${n}-enter-active`,enterToClass:d=`${n}-enter-to`,appearFromClass:h=a,appearActiveClass:y=c,appearToClass:m=d,leaveFromClass:w=`${n}-leave-from`,leaveActiveClass:C=`${n}-leave-active`,leaveToClass:O=`${n}-leave-to`}=e,N=oh(o),ee=N&&N[0],te=N&&N[1],{onBeforeEnter:ue,onEnter:P,onEnterCancelled:L,onLeave:J,onLeaveCancelled:ce,onBeforeAppear:ie=ue,onAppear:Q=P,onAppearCancelled:A=L}=t,S=(Y,xe,Fe,rt)=>{Y._enterCancelled=rt,Qn(Y,xe?m:d),Qn(Y,xe?y:c),Fe&&Fe()},oe=(Y,xe)=>{Y._isLeaving=!1,Qn(Y,w),Qn(Y,O),Qn(Y,C),xe&&xe()},ge=Y=>(xe,Fe)=>{const rt=Y?Q:P,We=()=>S(xe,Y,Fe);xr(rt,[xe,We]),wu(()=>{Qn(xe,Y?h:a),wn(xe,Y?m:d),bu(rt)||_u(xe,s,ee,We)})};return Et(t,{onBeforeEnter(Y){xr(ue,[Y]),wn(Y,a),wn(Y,c)},onBeforeAppear(Y){xr(ie,[Y]),wn(Y,h),wn(Y,y)},onEnter:ge(!1),onAppear:ge(!0),onLeave(Y,xe){Y._isLeaving=!0;const Fe=()=>oe(Y,xe);wn(Y,w),Y._enterCancelled?(wn(Y,C),Pa(Y)):(Pa(Y),wn(Y,C)),wu(()=>{Y._isLeaving&&(Qn(Y,w),wn(Y,O),bu(J)||_u(Y,s,te,Fe))}),xr(J,[Y,Fe])},onEnterCancelled(Y){S(Y,!1,void 0,!0),xr(L,[Y])},onAppearCancelled(Y){S(Y,!0,void 0,!0),xr(A,[Y])},onLeaveCancelled(Y){oe(Y),xr(ce,[Y])}})}function oh(e){if(e==null)return null;if(lt(e))return[ua(e.enter),ua(e.leave)];{const t=ua(e);return[t,t]}}function ua(e){return ud(e)}function wn(e,t){t.split(/\s+/).forEach(n=>n&&e.classList.add(n)),(e[Zr]||(e[Zr]=new Set)).add(t)}function Qn(e,t){t.split(/\s+/).forEach(s=>s&&e.classList.remove(s));const n=e[Zr];n&&(n.delete(t),n.size||(e[Zr]=void 0))}function wu(e){requestAnimationFrame(()=>{requestAnimationFrame(e)})}let ih=0;function _u(e,t,n,s){const o=e._endId=++ih,a=()=>{o===e._endId&&s()};if(n!=null)return setTimeout(a,n);const{type:c,timeout:d,propCount:h}=rf(e,t);if(!c)return s();const y=c+"end";let m=0;const w=()=>{e.removeEventListener(y,C),a()},C=O=>{O.target===e&&++m>=h&&w()};setTimeout(()=>{m(n[N]||"").split(", "),o=s(`${Jn}Delay`),a=s(`${Jn}Duration`),c=ku(o,a),d=s(`${ys}Delay`),h=s(`${ys}Duration`),y=ku(d,h);let m=null,w=0,C=0;t===Jn?c>0&&(m=Jn,w=c,C=a.length):t===ys?y>0&&(m=ys,w=y,C=h.length):(w=Math.max(c,y),m=w>0?c>y?Jn:ys:null,C=m?m===Jn?a.length:h.length:0);const O=m===Jn&&/\b(?:transform|all)(?:,|$)/.test(s(`${Jn}Property`).toString());return{type:m,timeout:w,propCount:C,hasTransform:O}}function ku(e,t){for(;e.lengthxu(n)+xu(e[s])))}function xu(e){return e==="auto"?0:Number(e.slice(0,-1).replace(",","."))*1e3}function Pa(e){return(e?e.ownerDocument:document).body.offsetHeight}function ah(e,t,n){const s=e[Zr];s&&(t=(t?[t,...s]:[...s]).join(" ")),t==null?e.removeAttribute("class"):n?e.setAttribute("class",t):e.className=t}const Cu=Symbol("_vod"),sf=Symbol("_vsh"),lh=Symbol(""),uh=/(?:^|;)\s*display\s*:/;function ch(e,t,n){const s=e.style,o=bt(n);let a=!1;if(n&&!o){if(t)if(bt(t))for(const c of t.split(";")){const d=c.slice(0,c.indexOf(":")).trim();n[d]==null&&ws(s,d,"")}else for(const c in t)n[c]==null&&ws(s,c,"");for(const c in n){c==="display"&&(a=!0);const d=n[c];d!=null?dh(e,c,!bt(t)&&t?t[c]:void 0,d)||ws(s,c,d):ws(s,c,"")}}else if(o){if(t!==n){const c=s[lh];c&&(n+=";"+c),s.cssText=n,a=uh.test(n)}}else t&&e.removeAttribute("style");Cu in e&&((!o||t!==n)&&(e[Cu]=a?s.display:""),e[sf]&&(s.display="none"))}const Co=/\s*!important$/;function ws(e,t,n){if(Ke(n))n.forEach(s=>ws(e,t,s));else if(n==null&&(n=""),t.startsWith("--"))Co.test(n)?e.setProperty(t,n.replace(Co,""),"important"):e.setProperty(t,n);else{const s=fh(e,t);Co.test(n)?e.setProperty(ur(s),n.replace(Co,""),"important"):e[s]=n}}const Su=["Webkit","Moz","ms"],ca={};function fh(e,t){const n=ca[t];if(n)return n;let s=hn(t);if(s!=="filter"&&s in e)return ca[t]=s;s=zu(s);for(let o=0;ofa||(gh.then(()=>fa=0),fa=Date.now());function wh(e,t){const n=s=>{if(!s._vts)s._vts=Date.now();else if(s._vts<=n.attached)return;const o=n.value;if(Ke(o)){const a=s.stopImmediatePropagation;s.stopImmediatePropagation=()=>{a.call(s),s._stopped=!0};const c=o.slice(),d=[s];for(let h=0;he.charCodeAt(0)===111&&e.charCodeAt(1)===110&&e.charCodeAt(2)>96&&e.charCodeAt(2)<123,_h=(e,t,n,s,o,a)=>{const c=o==="svg";t==="class"?ah(e,s,c):t==="style"?ch(e,n,s):oi(t)?ii(t)||hh(e,t,n,s,a):(t[0]==="."?(t=t.slice(1),!0):t[0]==="^"?(t=t.slice(1),!1):kh(e,t,s,c))?(Tu(e,t,s),!e.tagName.includes("-")&&(t==="value"||t==="checked"||t==="selected")&&$u(e,t,s,c,a,t!=="value")):e._isVueCE&&(xh(e,t)||e._def.__asyncLoader&&(/[A-Z]/.test(t)||!bt(s)))?Tu(e,hn(t),s,a,t):(t==="true-value"?e._trueValue=s:t==="false-value"&&(e._falseValue=s),$u(e,t,s,c))};function kh(e,t,n,s){if(s)return!!(t==="innerHTML"||t==="textContent"||t in e&&Au(t)&&Ge(n));if(t==="spellcheck"||t==="draggable"||t==="translate"||t==="autocorrect"||t==="sandbox"&&e.tagName==="IFRAME"||t==="form"||t==="list"&&e.tagName==="INPUT"||t==="type"&&e.tagName==="TEXTAREA")return!1;if(t==="width"||t==="height"){const o=e.tagName;if(o==="IMG"||o==="VIDEO"||o==="CANVAS"||o==="SOURCE")return!1}return Au(t)&&bt(n)?!1:t in e}function xh(e,t){const n=e._def.props;if(!n)return!1;const s=hn(t);return Array.isArray(n)?n.some(o=>hn(o)===s):Object.keys(n).some(o=>hn(o)===s)}const of=new WeakMap,af=new WeakMap,Wo=Symbol("_moveCb"),Ou=Symbol("_enterCb"),Aa=new WeakMap,Ch=e=>(delete e.props.mode,e),Sh=Ch({name:"TransitionGroup",props:Et({},tf,{tag:String,moveClass:String}),setup(e,{slots:t}){const n=il(),s=xc();let o,a,c,d;const h=()=>(d===void 0&&(d=o.length>0&&Ih(o[0].el,n.vnode.el,Mu(e))),d);return Pc(()=>{if(Aa.delete(n),!h()){o=[],c=void 0;return}const y=Mu(e);o.forEach($h);const m=c&&Mh(c,n.vnode.el);c=void 0,o.forEach(C=>Th(C,m));const w=o.filter(Ph);Pa(n.vnode.el),w.forEach(C=>{const O=C.el,N=O.style;wn(O,y),N.transform=N.webkitTransform=N.transitionDuration="";const ee=O[Wo]=te=>{te&&te.target!==O||(!te||te.propertyName.endsWith("transform"))&&(O.removeEventListener("transitionend",ee),O[Wo]=null,Qn(O,y))};O.addEventListener("transitionend",ee)}),o=[]}),()=>{const y=ot(e),m=nf(y);let w=y.tag||Re;if(o=[],d=void 0,a)for(let C=0;Cs.willMove()&&s.item.contains(t));return n&&gi(n.item,n)}function Ih(e,t,n){const s=e.cloneNode(),o=e[Zr];o&&o.forEach(d=>{d.split(/\s+/).forEach(h=>h&&s.classList.remove(h))}),n.split(/\s+/).forEach(d=>d&&s.classList.add(d)),s.style.display="none";const a=t.nodeType===1?t:t.parentNode;a.appendChild(s);const{hasTransform:c}=rf(s);return a.removeChild(s),c}const zo=e=>{const t=e.props["onUpdate:modelValue"]||!1;return Ke(t)?n=>$o(t,n):t};function jh(e){e.target.composing=!0}function Iu(e){const t=e.target;t.composing&&(t.composing=!1,t.dispatchEvent(new Event("input")))}const Pr=Symbol("_assign"),So=Symbol("_initialValue");function da(e,t,n){return t&&(e=e.trim()),n&&(e=li(e)),e}const Le={created(e,{modifiers:{lazy:t,trim:n,number:s}},o){e.parentNode&&(e.type==="text"?e[So]=e.defaultValue.replace(/[\r\n]/g,""):e.type==="textarea"&&(e[So]=e.defaultValue.replace(/\r\n?/g,` +`))),e[Pr]=zo(o);const a=s||o.props&&o.props.type==="number";$r(e,t?"change":"input",c=>{c.target.composing||e[Pr](da(e.value,n,a))}),(n||a)&&$r(e,"change",()=>{e.value=da(e.value,n,a)}),t||($r(e,"compositionstart",jh),$r(e,"compositionend",Iu),$r(e,"change",Iu))},mounted(e,{value:t,modifiers:{trim:n,number:s}}){const o=t??"",a=e[So];delete e[So],a!==void 0&&(e.type==="text"||e.type==="textarea")&&e.value!==a?e[Pr](da(e.value,n,s)):e.value=o},beforeUpdate(e,{value:t,oldValue:n,modifiers:{lazy:s,trim:o,number:a}},c){if(e[Pr]=zo(c),e.composing)return;const d=(a||e.type==="number")&&!/^0\d/.test(e.value)?li(e.value):e.value,h=t??"";if(d===h)return;const y=e.getRootNode();(y instanceof Document||y instanceof ShadowRoot)&&y.activeElement===e&&e.type!=="range"&&(s&&t===n||o&&e.value.trim()===h)||(e.value=h)}},Fn={deep:!0,created(e,{value:t,modifiers:{number:n}},s){e._modelValue=t,$r(e,"change",()=>{const o=Array.prototype.filter.call(e.options,h=>h.selected).map(h=>n?li(Go(h)):Go(h)),a=e.multiple,c=a?Mr(e._modelValue)?new Set(o):o:o[0],d=e._pendingValue=[a,a?Ke(c)?o.slice():o:c];try{e[Pr](c)}finally{rs(()=>{e._pendingValue===d&&(e._pendingValue=void 0)})}}),e[Pr]=zo(s)},mounted(e,{value:t}){ju(e,t)},beforeUpdate(e,{value:t},n){e._modelValue=t,e[Pr]=zo(n)},updated(e,{value:t}){const n=e._pendingValue;e._pendingValue=void 0,(!n||n[0]!==e.multiple||!Dh(t,n[1],n[0]))&&ju(e,t)}};function Dh(e,t,n){if(!n||Ke(e))return sr(e,t);if(Mr(e)){if(e.size!==t.length)return!1;for(const s of t)if(!e.has(s))return!1;return!0}return!1}function ju(e,t){const n=e.multiple,s=Ke(t);if(!(n&&!s&&!Mr(t))){for(let o=0,a=e.options.length;oString(y)===String(d)):c.selected=gd(t,d)>-1}else c.selected=t.has(d);else if(sr(Go(c),t)){e.selectedIndex!==o&&(e.selectedIndex=o);return}}!n&&e.selectedIndex!==-1&&(e.selectedIndex=-1)}}function Go(e){return"_value"in e?e._value:e.value}const Lh=["ctrl","shift","alt","meta"],Rh={stop:e=>e.stopPropagation(),prevent:e=>e.preventDefault(),self:e=>e.target!==e.currentTarget,ctrl:e=>!e.ctrlKey,shift:e=>!e.shiftKey,alt:e=>!e.altKey,meta:e=>!e.metaKey,left:e=>"button"in e&&e.button!==0,middle:e=>"button"in e&&e.button!==1,right:e=>"button"in e&&e.button!==2,exact:(e,t)=>Lh.some(n=>e[`${n}Key`]&&!t.includes(n))},Ir=(e,t)=>{if(!e)return e;const n=e._withMods||(e._withMods={}),s=t.join(".");return n[s]||(n[s]=(o,...a)=>{for(let c=0;c{const n=e._withKeys||(e._withKeys={}),s=t.join(".");return n[s]||(n[s]=o=>{if(!("key"in o))return;const a=ur(o.key);if(t.some(c=>c===a||Kh[c]===a))return e(o)})},Fh=Et({patchProp:_h},rh);let Du;function Nh(){return Du||(Du=Lp(Fh))}const Vh=(...e)=>{const t=Nh().createApp(...e),{mount:n}=t;return t.mount=s=>{const o=Uh(s);if(!o)return;const a=t._component;!Ge(a)&&!a.render&&!a.template&&(a.template=o.innerHTML),o.nodeType===1&&(o.textContent="");const c=n(o,!1,Bh(o));return o instanceof Element&&(o.removeAttribute("v-cloak"),o.setAttribute("data-v-app","")),c},t};function Bh(e){if(e instanceof SVGElement)return"svg";if(typeof MathMLElement=="function"&&e instanceof MathMLElement)return"mathml"}function Uh(e){return bt(e)?document.querySelector(e):e}function Tt(e){return''+e+""}const qh={calendar:Tt(''),clock:Tt(''),"check-circle":Tt(''),edit:Tt(''),tag:Tt(''),star:Tt(''),close:Tt(''),flag:Tt(''),chart:Tt(''),export:Tt(''),"chevron-left":Tt(''),"chevron-right":Tt(''),"chevron-down":Tt(''),plus:Tt(''),search:Tt(''),settings:Tt(''),memo:Tt(''),lock:Tt(''),wallet:Tt('')},Hh=["innerHTML"],ut=Bt({__name:"Icon",props:{name:{},size:{default:16}},setup(e){const t=e,n=at(()=>qh[t.name]||"");return(s,o)=>(K(),H("span",{class:"icon",style:nr({width:e.size+"px",height:e.size+"px"}),innerHTML:n.value},null,12,Hh))}}),Wh=["aria-label"],zh={class:"dialog-title"},Gh={class:"dialog-msg"},Yh={class:"dialog-btns"},Jh=Bt({__name:"ConfirmDialog",props:{open:{type:Boolean},title:{},message:{},confirmText:{default:"确认"},cancelText:{default:"取消"},danger:{type:Boolean,default:!1}},emits:["cancel","confirm"],setup(e,{emit:t}){const n=e,s=t;function o(a){n.open&&a.key==="Escape"&&s("cancel")}return vt(()=>n.open,a=>{a?window.addEventListener("keydown",o):window.removeEventListener("keydown",o)}),fr(()=>window.removeEventListener("keydown",o)),(a,c)=>(K(),It(Us,{to:"body"},[Oe(ss,{name:"modal"},{default:cr(()=>[e.open?(K(),H("div",{key:0,class:"mask",onClick:c[2]||(c[2]=Ir(d=>s("cancel"),["self"]))},[u("div",{class:"dialog",role:"dialog","aria-label":e.title},[u("div",zh,se(e.title),1),u("div",Gh,se(e.message),1),u("div",Yh,[u("button",{class:"btn btn-sm",onClick:c[0]||(c[0]=d=>s("cancel"))},se(e.cancelText),1),u("button",{class:tt(["btn btn-sm",e.danger?"btn-danger-solid":"btn-primary"]),onClick:c[1]||(c[1]=d=>s("confirm"))},se(e.confirmText),3)])],8,Wh)])):Ee("",!0)]),_:1})]))}}),Yt=(e,t)=>{const n=e.__vccOpts||e;for(const[s,o]of t)n[s]=o;return n},lr=Yt(Jh,[["__scopeId","data-v-f27041d4"]]);var Lu=typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{};function Xh(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var lf={exports:{}};(function(e,t){((n,s)=>{e.exports=s()})(Lu,function(){var n=function(r,i){return(n=Object.setPrototypeOf||({__proto__:[]}instanceof Array?function(l,f){l.__proto__=f}:function(l,f){for(var p in f)Object.prototype.hasOwnProperty.call(f,p)&&(l[p]=f[p])}))(r,i)},s=function(){return(s=Object.assign||function(r){for(var i,l=1,f=arguments.length;l"u"||a.Promise||(a.Promise=Promise);var y=Object.getPrototypeOf,m={}.hasOwnProperty;function w(r,i){return m.call(r,i)}function C(r,i){typeof i=="function"&&(i=i(y(r))),(typeof Reflect>"u"?c:Reflect.ownKeys)(i).forEach(function(l){N(r,l,i[l])})}var O=Object.defineProperty;function N(r,i,l,f){O(r,i,h(l&&w(l,"get")&&typeof l.get=="function"?{get:l.get,set:l.set,configurable:!0}:{value:l,configurable:!0,writable:!0},f))}function ee(r){return{from:function(i){return r.prototype=Object.create(i.prototype),N(r.prototype,"constructor",r),{extend:C.bind(null,r.prototype)}}}}var te=Object.getOwnPropertyDescriptor,ue=[].slice;function P(r,i,l){return ue.call(r,i,l)}function L(r,i){return i(r)}function J(r){if(!r)throw new Error("Assertion Failed")}function ce(r){a.setImmediate?setImmediate(r):setTimeout(r,0)}function ie(r,i){if(typeof i=="string"&&w(r,i))return r[i];if(!i)return r;if(typeof i!="string"){for(var l=[],f=0,p=i.length;f"u"?[]:(Xe=Promise.resolve(),typeof crypto<"u"&&crypto.subtle?[Qe=crypto.subtle.digest("SHA-512",new Uint8Array([0])),y(Qe),Xe]:[Xe,y(Xe),Xe]),Xe=Qe[0],Ur=Qe[1],Ur=Ur&&Ur.then,Ze=Xe&&Xe.constructor,mt=!!Qe[2],kt=function(r,i){Un.push([r,i]),Ut&&(queueMicrotask(Df),Ut=!1)},Qt=!0,Ut=!0,en=[],pr=[],Ot=x,$t={id:"global",global:!0,ref:0,unhandleds:[],onunhandled:_,pgp:!1,env:{},finalize:_},Ie=$t,Un=[],hr=0,Gs=[];function Se(r){if(typeof this!="object")throw new TypeError("Promises must be constructed via new");this._listeners=[],this._lib=!1;var i=this._PSD=Ie;if(typeof r!="function"){if(r!==$e)throw new TypeError("Not a function");this._state=arguments[1],this._value=arguments[2],this._state===!1&&Ci(this,this._value)}else this._state=null,this._value=null,++i.ref,function l(f,p){try{p(function(v){if(f._state===null){if(v===f)throw new TypeError("A promise cannot be resolved with itself.");var g=f._lib&&Rr();v&&typeof v.then=="function"?l(f,function(b,$){v instanceof Se?v._then(b,$):v.then(b,$)}):(f._state=!0,f._value=v,gl(f)),g&&Kr()}},Ci.bind(null,f))}catch(v){Ci(f,v)}}(this,r)}var xi={get:function(){var r=Ie,i=Qs;function l(f,p){var v=this,g=!r.global&&(r!==Ie||i!==Qs),b=g&&!Hn(),$=new Se(function(V,M){Si(v,new yl(wl(f,r,g,b),wl(p,r,g,b),V,M,r))});return this._consoleTask&&($._consoleTask=this._consoleTask),$}return l.prototype=$e,l},set:function(r){N(this,"then",r&&r.prototype===$e?xi:{get:function(){return r},set:xi.set})}};function yl(r,i,l,f,p){this.onFulfilled=typeof r=="function"?r:null,this.onRejected=typeof i=="function"?i:null,this.resolve=l,this.reject=f,this.psd=p}function Ci(r,i){var l,f;pr.push(i),r._state===null&&(l=r._lib&&Rr(),i=Ot(i),r._state=!1,r._value=i,f=r,en.some(function(p){return p._value===f._value})||en.push(f),gl(r),l)&&Kr()}function gl(r){var i=r._listeners;r._listeners=[];for(var l=0,f=i.length;l{for(var g=en.length;g;)if(en[--g]._value===v._value)return en.splice(g,1)})(i),l.resolve(f)}catch(v){l.reject(v)}finally{--hr==0&&Ei(),--l.psd.ref||l.psd.finalize()}}function Df(){vr($t,function(){Rr()&&Kr()})}function Rr(){var r=Qt;return Ut=Qt=!1,r}function Kr(){var r,i,l;do for(;0.",_l="String expected.",eo="__dbnames",Ti="readonly",Pi="readwrite";function yr(r,i){return r?i?function(){return r.apply(this,arguments)&&i.apply(this,arguments)}:r:i}var kl={type:3,lower:-1/0,lowerOpen:!1,upper:[[]],upperOpen:!1};function to(r){return typeof r!="string"||/\./.test(r)?function(i){return i}:function(i){return i[r]===void 0&&r in i&&delete(i=xe(i))[r],i}}function xl(){throw je.Type("Entity instances must never be new:ed. Instances are generated by the framework bypassing the constructor.")}function nt(r,i){try{var l=Cl(r),f=Cl(i);if(l!==f)return l==="Array"?1:f==="Array"?-1:l==="binary"?1:f==="binary"?-1:l==="string"?1:f==="string"?-1:l==="Date"?1:f!=="Date"?NaN:-1;switch(l){case"number":case"Date":case"string":return i{var b=M,$=g;if(typeof $!="function"&&$!==null)throw new TypeError("Class extends value "+String($)+" is not a constructor or null");function V(){this.constructor=b}function M(){return g!==null&&g.apply(this,arguments)||this}return n(b,$),b.prototype=$===null?Object.create($):(V.prototype=$.prototype,new V),Object.defineProperty(M.prototype,"db",{get:function(){return i},enumerable:!1,configurable:!0}),M.prototype.table=function(){return l},M})(r)),new Set),p=r.prototype;p;p=y(p))Object.getOwnPropertyNames(p).forEach(function(g){return f.add(g)});function v(g){if(!g)return g;var b,$=Object.create(r.prototype);for(b in g)if(!f.has(b))try{$[b]=g[b]}catch{}return $}return this.schema.readHook&&this.hook.reading.unsubscribe(this.schema.readHook),this.schema.readHook=v,this.hook("reading",v),r},pt.prototype.defineClass=function(){return this.mapToClass(function(r){h(this,r)})},pt.prototype.add=function(r,i){var l=this,f=this.schema.primKey,p=f.auto,v=f.keyPath,g=r;return v&&p&&(g=to(v)(r)),this._trans("readwrite",function(b){return l.core.mutate({trans:b,type:"add",keys:i!=null?[i]:null,values:[g]})}).then(function(b){return b.numFailures?Se.reject(b.failures[0]):b.lastResult}).then(function(b){if(v)try{Q(r,v,b)}catch{}return b})},pt.prototype.upsert=function(r,i){var l=this,f=this.schema.primKey.keyPath;return this._trans("readwrite",function(p){return l.core.get({trans:p,key:r}).then(function(v){var g=v??{};return $l(g,i),f&&Q(g,f,r),l.core.mutate({trans:p,type:"put",values:[g],keys:[r],upsert:!0,updates:{keys:[r],changeSpecs:[i]}}).then(function(b){return b.numFailures?Se.reject(b.failures[0]):!!v})})})},pt.prototype.update=function(r,i){return typeof r!="object"||d(r)?this.where(":id").equals(r).modify(i):(r=ie(r,this.schema.primKey.keyPath))===void 0?Ct(new je.InvalidArgument("Given object does not contain its primary key")):this.where(":id").equals(r).modify(i)},pt.prototype.put=function(r,i){var l=this,f=this.schema.primKey,p=f.auto,v=f.keyPath,g=r;return v&&p&&(g=to(v)(r)),this._trans("readwrite",function(b){return l.core.mutate({trans:b,type:"put",values:[g],keys:i!=null?[i]:null})}).then(function(b){return b.numFailures?Se.reject(b.failures[0]):b.lastResult}).then(function(b){if(v)try{Q(r,v,b)}catch{}return b})},pt.prototype.delete=function(r){var i=this;return this._trans("readwrite",function(l){return i.core.mutate({trans:l,type:"delete",keys:[r]}).then(function(f){return no(i,[r],f)}).then(function(f){return f.numFailures?Se.reject(f.failures[0]):void 0})})},pt.prototype.clear=function(){var r=this;return this._trans("readwrite",function(i){return r.core.mutate({trans:i,type:"deleteRange",range:kl}).then(function(l){return no(r,null,l)})}).then(function(i){return i.numFailures?Se.reject(i.failures[0]):void 0})},pt.prototype.bulkGet=function(r){var i=this;return this._trans("readonly",function(l){return i.core.getMany({keys:r,trans:l}).then(function(f){return f.map(function(p){return i.hook.reading.fire(p)})})})},pt.prototype.bulkAdd=function(r,i,l){var f=this,p=Array.isArray(i)?i:void 0,v=(l=l||(p?void 0:i))?l.allKeys:void 0;return this._trans("readwrite",function(g){var b=f.schema.primKey,V=b.auto,b=b.keyPath;if(b&&p)throw new je.InvalidArgument("bulkAdd(): keys argument invalid on tables with inbound keys");if(p&&p.length!==r.length)throw new je.InvalidArgument("Arguments objects and keys must have the same length");var $=r.length,V=b&&V?r.map(to(b)):r;return f.core.mutate({trans:g,type:"add",keys:p,values:V,wantResults:v}).then(function(M){var E=M.numFailures,T=M.failures;if(E===0)return v?M.results:M.lastResult;throw new dt("".concat(f.name,".bulkAdd(): ").concat(E," of ").concat($," operations failed"),T)})})},pt.prototype.bulkPut=function(r,i,l){var f=this,p=Array.isArray(i)?i:void 0,v=(l=l||(p?void 0:i))?l.allKeys:void 0;return this._trans("readwrite",function(g){var b=f.schema.primKey,V=b.auto,b=b.keyPath;if(b&&p)throw new je.InvalidArgument("bulkPut(): keys argument invalid on tables with inbound keys");if(p&&p.length!==r.length)throw new je.InvalidArgument("Arguments objects and keys must have the same length");var $=r.length,V=b&&V?r.map(to(b)):r;return f.core.mutate({trans:g,type:"put",keys:p,values:V,wantResults:v}).then(function(M){var E=M.numFailures,T=M.failures;if(E===0)return v?M.results:M.lastResult;throw new dt("".concat(f.name,".bulkPut(): ").concat(E," of ").concat($," operations failed"),T)})})},pt.prototype.bulkUpdate=function(r){var i=this,l=this.core,f=r.map(function(g){return g.key}),p=r.map(function(g){return g.changes}),v=[];return this._trans("readwrite",function(g){return l.getMany({trans:g,keys:f,cache:"clone"}).then(function(b){var $=[],V=[],M=(r.forEach(function(E,T){var R=E.key,j=E.changes,I=b[T];if(I){for(var D=0,W=Object.keys(j);DB+re&&D(B+V)})})}var W=Nr(l)&&l.limit===1/0&&(typeof r!="function"||j)&&{index:l.index,range:l.range};return D(0).then(function(){if(0{for(var He=Math.min(ye.length,Ae.length),Je=-1,et=0;et=T})).length===0?Se.resolve():(D.forEach(function(B){I.push(function(){var re,de,he,_e=W,ye=B._cfg.dbschema,Pe=(fo(E,_e,j),fo(E,ye,j),W=E._dbSchema=ye,Ri(_e,ye)),we=(Pe.add.forEach(function(Ae){Ki(j,Ae[0],Ae[1].primKey,Ae[1].indexes)}),Pe.change.forEach(function(Ae){if(Ae.recreate)throw new je.Upgrade("Not yet support for changing primary key");var pe=j.objectStore(Ae.name);Ae.add.forEach(function(qe){return uo(pe,qe)}),Ae.change.forEach(function(qe){pe.deleteIndex(qe.name),uo(pe,qe)}),Ae.del.forEach(function(qe){return pe.deleteIndex(qe)})}),B._cfg.contentUpgrade);if(we&&B._cfg.version>T)return ao(E,j),R._memoizedTables={},re=A(ye),Pe.del.forEach(function(Ae){re[Ae]=_e[Ae]}),Li(E,[E.Transaction.prototype]),lo(E,[E.Transaction.prototype],c(re),re),R.schema=re,(de=De(we))&&Fr(),ye=Se.follow(function(){var Ae;(he=we(R))&&de&&(Ae=Hn.bind(null,null),he.then(Ae,Ae))}),he&&typeof he.then=="function"?Se.resolve(he):ye.then(function(){return he})}),I.push(function(re){var de,he,_e=B._cfg.dbschema;de=_e,he=re,[].slice.call(he.db.objectStoreNames).forEach(function(ye){return de[ye]==null&&he.db.deleteObjectStore(ye)}),Li(E,[E.Transaction.prototype]),lo(E,[E.Transaction.prototype],E._storeNames,E._dbSchema),R.schema=E._dbSchema}),I.push(function(re){E.idbdb.objectStoreNames.contains("$meta")&&(Math.ceil(E.idbdb.version/10)===B._cfg.version?(E.idbdb.deleteObjectStore("$meta"),delete E._dbSchema.$meta,E._storeNames=E._storeNames.filter(function(de){return de!=="$meta"})):re.objectStore("$meta").put(B._cfg.version,"version"))})}),function B(){return I.length?Se.resolve(I.shift()(R.idbtrans)).then(B):Se.resolve()}().then(function(){Ll(W,j)}))}).catch(g);var $,V;c(p).forEach(function(M){Ki(l,M,p[M].primKey,p[M].indexes)}),ao(r,l),Se.follow(function(){return r.on.populate.fire(v)}).catch(g)})}function Gf(r,i){Ll(r._dbSchema,i),i.db.version%10!=0||i.objectStoreNames.contains("$meta")||i.db.createObjectStore("$meta").add(Math.ceil(i.db.version/10-1),"version");var l=co(0,r.idbdb,i);fo(r,r._dbSchema,i);for(var f=0,p=Ri(l,r._dbSchema).change;f{if(g.change.length||g.recreate)return console.warn("Unable to patch indexes of table ".concat(g.name," because it has changes on the type of index or primary key.")),{value:void 0};var b=i.objectStore(g.name);g.add.forEach(function($){q&&console.debug("Dexie upgrade patch: Creating missing index ".concat(g.name,".").concat($.src)),uo(b,$)})})(p[f]);if(typeof v=="object")return v.value}}function Ri(r,i){var l,f={del:[],add:[],change:[]};for(l in r)i[l]||f.del.push(l);for(l in i){var p=r[l],v=i[l];if(p){var g={name:l,def:v,recreate:!1,del:[],add:[],change:[]};if(""+(p.primKey.keyPath||"")!=""+(v.primKey.keyPath||"")||p.primKey.auto!==v.primKey.auto)g.recreate=!0,f.change.push(g);else{var b=p.idxByName,$=v.idxByName,V=void 0;for(V in b)$[V]||g.del.push(V);for(V in $){var M=b[V],E=$[V];M?M.src!==E.src&&g.change.push(E):g.add.push(E)}(0{var r,i,l;return typeof FinalizationRegistry<"u"&&typeof WeakRef<"u"?(r=new Set,i=new FinalizationRegistry(function(f){r.delete(f)}),{toArray:function(){return Array.from(r).map(function(f){return f.deref()}).filter(function(f){return f!==void 0})},add:function(f){var p=new WeakRef(f._novip);r.add(p),i.register(f._novip,p,p),r.size>f._options.maxConnections&&(p=r.values().next().value,r.delete(p),i.unregister(p))},remove:function(f){if(f)for(var p=r.values(),v=p.next();!v.done;){var g=v.value;if(g.deref()===f._novip)return r.delete(g),void i.unregister(g);v=p.next()}}}):(l=[],{toArray:function(){return l},add:function(f){l.push(f._novip)},remove:function(f){f&&(f=l.indexOf(f._novip))!==-1&&l.splice(f,1)}})})();function Fi(r,i){var l=r._dbNamesDB;return l||(l=r._dbNamesDB=new Mn(eo,{addons:[],indexedDB:r,IDBKeyRange:i})).version(1).stores({dbnames:"name"}),l.table("dbnames")}function Ni(r){return r&&typeof r.databases=="function"}function Vi(r){return qn(function(){return Ie.letThrough=!0,r()})}function Bi(r){return!("from"in r)}var Lt=function(r,i){var l;if(!this)return l=new Lt,r&&"d"in r&&h(l,r),l;h(this,arguments.length?{d:1,from:r,to:1Math.pow(2,62)?0:D.oldVersion,E=W<1,r.idbdb=I.result,v&&Gf(r,M),zf(r,W/10,M,R))},R),I.onsuccess=yt(function(){M=null;var D,W,B,re,de,he,_e=r.idbdb=I.result,ye=P(_e.objectStoreNames);if(0"u"?Se.resolve():!navigator.userAgentData&&/Safari\//.test(navigator.userAgent)&&!/Chrom(e|ium)\//.test(navigator.userAgent)&&indexedDB.databases?new Promise(function(T){function R(){return indexedDB.databases().finally(T)}$=setInterval(R,100),R()}).finally(function(){return clearInterval($)}):Promise.resolve()).then(b)]).then(function(){return g(),i.onReadyBeingFired=[],Se.resolve(Vi(function(){return r.on.ready.fire(r.vip)})).then(function T(){var R;if(0i.limit?f.length=i.limit:r.length===i.limit&&f.length{if(l===void 0)return f!==void 0?-1:0;if(f===void 0)return 1;if((l=nt(l,f))===0){if(p&&v)return 0;if(p)return 1;if(v)return-1}return l})(r.lower,i.lower,r.lowerOpen,i.lowerOpen)<=0&&0<=((l,f,p,v)=>{if(l===void 0)return f!==void 0?1:0;if(f===void 0)return-1;if((l=nt(l,f))===0){if(p&&v)return 0;if(p)return-1;if(v)return 1}return l})(r.upper,i.upper,r.upperOpen,i.upperOpen)}function nd(r,i,l,f){r.subscribers.add(l),f.addEventListener("abort",function(){var p,v;r.subscribers.delete(l),r.subscribers.size===0&&(p=r,v=i,setTimeout(function(){p.subscribers.size===0&&me(v,p)},3e3))})}var rd={stack:"dbcore",level:0,name:"Cache",create:function(r){var i=r.schema.name;return s(s({},r),{transaction:function(l,f,p){var v,g,b=r.transaction(l,f,p);return f==="readwrite"&&(p=(v=new AbortController).signal,b.addEventListener("abort",(g=function($){return function(){if(v.abort(),f==="readwrite"){for(var V=new Set,M=0,E=l;M{var W=gr["idb://".concat(R,"/").concat(j)];if(!W)return[];if(!(R=W.queries[I]))return[null,!1,W,null];var B=R[(D.query?D.query.index.name:null)||""];if(!B)return[null,!1,W,null];switch(I){case"query":var re=(de=D.direction)!=null?de:"next",de=B.find(function(he){var _e;return he.req.limit===D.limit&&he.req.values===D.values&&((_e=he.req.direction)!=null?_e:"next")===re&&zl(he.req.query.range,D.query.range)});return de?[de,!0,W,B]:[B.find(function(he){var _e;return("limit"in he.req?he.req.limit:1/0)>=D.limit&&((_e=he.req.direction)!=null?_e:"next")===re&&(!D.values||he.req.values)&&td(he.req.query.range,D.query.range)}),!1,W,B];case"count":return de=B.find(function(he){return zl(he.req.query.range,D.query.range)}),[de,!!de,W,B]}})(i,l,"query",v),T=E[0],V=E[2],M=E[3],T&&E[1]?T.obsSet=v.obsSet:(E=f.query(v).then(function(R){var j=R.result;if(T&&(T.res=j),g){for(var I=0,D=j.length;I{var de=Rr();try{v&&Fr();var he=qn(r,re);return he=v?he.finally(Hn):he}finally{de&&Kr()}})(W={subscr:D,signal:g.signal,requery:T,querier:r,trans:null}),E||(Gn.storagemutated.subscribe(j),E=!0),Promise.resolve(B).then(function(re){l=!0,i=re,b||W.signal.aborted||(R()||(V=D,R())?T():($={},$i(function(){return!b&&p.next&&p.next(re)})))},function(re){l=!1,["DatabaseClosedError","AbortError"].includes(re==null?void 0:re.name)||b||$i(function(){b||p.error&&p.error(re)})}))};return setTimeout(T,0),M});return f.hasValue=function(){return l},f.getValue=function(){return i},f}var br=Mn;function Qi(r){var i=Yn;try{Yn=!0,Gn.storagemutated.fire(r),Wi(r,!0)}finally{Yn=i}}C(br,s(s({},Ce),{delete:function(r){return new br(r,{addons:[]}).delete()},exists:function(r){return new br(r,{addons:[]}).open().then(function(i){return i.close(),!0}).catch("NoSuchDatabaseError",function(){return!1})},getDatabaseNames:function(r){try{return i=br.dependencies,l=i.indexedDB,i=i.IDBKeyRange,(Ni(l)?Promise.resolve(l.databases()).then(function(f){return f.map(function(p){return p.name}).filter(function(p){return p!==eo})}):Fi(l,i).toCollection().primaryKeys()).then(r)}catch{return Ct(new je.MissingAPI)}var i,l},defineClass:function(){return function(r){h(this,r)}},ignoreTransaction:function(r){return Ie.trans?vr(Ie.transless||$t,r):r()},vip:Vi,async:function(r){return function(){try{var i=zi(r.apply(this,arguments));return i&&typeof i.then=="function"?i:Se.resolve(i)}catch(l){return Ct(l)}}},spawn:function(r,i,l){try{var f=zi(r.apply(l,i||[]));return f&&typeof f.then=="function"?f:Se.resolve(f)}catch(p){return Ct(p)}},currentTransaction:{get:function(){return Ie.trans||null}},waitFor:function(r,i){return r=Se.resolve(typeof r=="function"?br.ignoreTransaction(r):r).timeout(i||6e4),Ie.trans?Ie.trans.waitFor(r):r},Promise:Se,debug:{get:function(){return q},set:function(r){G(r)}},derive:ee,extend:h,props:C,override:L,Events:as,on:Gn,liveQuery:Gl,extendObservabilitySet:ho,getByKeyPath:ie,setByKeyPath:Q,delByKeyPath:function(r,i){typeof i=="string"?Q(r,i,void 0):"length"in i&&[].map.call(i,function(l){Q(r,l,void 0)})},shallowClone:A,deepClone:xe,getObjectDiff:Gi,cmp:nt,asap:ce,minKey:-1/0,addons:[],connections:{get:ds.toArray},errnames:Jt,dependencies:go,cache:gr,semVer:"4.4.6",version:"4.4.6".split(".").map(function(r){return parseInt(r)}).reduce(function(r,i,l){return r+i/Math.pow(10,2*l)})})),br.maxKey=cs(br.dependencies.IDBKeyRange),typeof dispatchEvent<"u"&&typeof addEventListener<"u"&&(Gn(io,function(r){Yn||(r=new CustomEvent(Mi,{detail:r}),Yn=!0,dispatchEvent(r),Yn=!1)}),addEventListener(Mi,function(r){r=r.detail,Yn||Qi(r)}));var qr,Yn=!1,Yl=function(){};return typeof BroadcastChannel<"u"&&((Yl=function(){(qr=new BroadcastChannel(Mi)).onmessage=function(r){return r.data&&Qi(r.data)}})(),typeof qr.unref=="function"&&qr.unref(),Gn(io,function(r){Yn||qr.postMessage(r)})),typeof addEventListener<"u"&&(addEventListener("pagehide",function(r){if(!Mn.disableBfCache&&r.persisted){q&&console.debug("Dexie: handling persisted pagehide"),qr!=null&&qr.close();for(var i=0,l=ds.toArray();in.key===e);return t?t.label:"其他"}const rv={class:"dialog",role:"dialog","aria-label":"编辑工作记录"},sv={class:"dialog-head"},ov={key:0,class:"muted dialog-sub"},iv={class:"dialog-body"},av={class:"form-grid"},lv={class:"field span2"},uv={key:0,class:"form-error"},cv={class:"field"},fv=["value"],dv={class:"field"},pv=["value"],hv={class:"field"},vv={class:"field"},mv={class:"field span2"},yv={class:"field"},gv={class:"field"},bv={class:"dialog-btns"},wv=Bt({__name:"EditLogDialog",props:{open:{type:Boolean},item:{},projects:{},date:{}},emits:["cancel","save"],setup(e,{emit:t}){const n=e,s=t,o=F(""),a=F(null),c=F("dev"),d=F(null),h=F(""),y=F(""),m=F(0),w=F(0),C=F(""),O=F(null),N=at(()=>{var L;const ue=n.projects.filter(J=>J.archived!==1),P=(L=n.item)==null?void 0:L.project_id;if(P&&!ue.some(J=>J.id===P)){const J=n.projects.find(ie=>ie.id===P),ce=ue.slice();return J&&ce.unshift({...J,name:J.name+"(已归档)"}),ce}return ue});function ee(ue){n.open&&ue.key==="Escape"&&s("cancel")}vt(()=>n.open,async ue=>{var P;if(ue){const L=n.item;o.value=(L==null?void 0:L.content)??"",a.value=(L==null?void 0:L.project_id)??null,c.value=(L==null?void 0:L.category)??"dev",d.value=(L==null?void 0:L.minutes)??null,h.value=(L==null?void 0:L.takeaway)??"",y.value=(L==null?void 0:L.remark)??"",m.value=(L==null?void 0:L.is_milestone)??0,w.value=(L==null?void 0:L.needs_followup)??0,C.value="",window.addEventListener("keydown",ee),await rs(),(P=O.value)==null||P.focus()}else window.removeEventListener("keydown",ee)}),fr(()=>window.removeEventListener("keydown",ee)),vt(o,()=>{C.value&&(C.value="")});function te(){const ue=o.value.trim();if(!ue){C.value="请填写工作内容";return}if(!n.item||!n.item.id){s("cancel");return}s("save",{id:n.item.id,content:ue,project_id:a.value,category:c.value,minutes:d.value&&d.value>0?d.value:null,takeaway:h.value.trim()||null,remark:y.value.trim()||null,is_milestone:m.value?1:0,needs_followup:w.value?1:0})}return(ue,P)=>(K(),It(Us,{to:"body"},[Oe(ss,{name:"modal"},{default:cr(()=>[e.open?(K(),H("div",{key:0,class:"mask",onClick:P[10]||(P[10]=Ir(L=>s("cancel"),["self"]))},[u("div",rv,[u("div",sv,[u("div",null,[P[11]||(P[11]=u("div",{class:"dialog-title"},"编辑工作记录",-1)),e.date?(K(),H("div",ov,se(e.date),1)):Ee("",!0)]),u("button",{class:"icon-btn",title:"关闭",onClick:P[0]||(P[0]=L=>s("cancel"))},[Oe(ut,{name:"close",size:16})])]),u("div",iv,[u("div",av,[u("div",lv,[P[12]||(P[12]=u("label",null,"工作内容(必填)",-1)),Te(u("input",{ref_key:"contentInput",ref:O,class:tt(["input",{invalid:C.value}]),"onUpdate:modelValue":P[1]||(P[1]=L=>o.value=L),onKeydown:Dt(te,["enter"])},null,34),[[Le,o.value]]),C.value?(K(),H("div",uv,se(C.value),1)):Ee("",!0)]),u("div",cv,[P[14]||(P[14]=u("label",null,"所属项目",-1)),Te(u("select",{class:"select","onUpdate:modelValue":P[2]||(P[2]=L=>a.value=L)},[P[13]||(P[13]=u("option",{value:null},"无项目",-1)),(K(!0),H(Re,null,ct(N.value,L=>(K(),H("option",{key:L.id,value:L.id},se(L.name),9,fv))),128))],512),[[Fn,a.value]])]),u("div",dv,[P[15]||(P[15]=u("label",null,"工作分类",-1)),Te(u("select",{class:"select","onUpdate:modelValue":P[3]||(P[3]=L=>c.value=L)},[(K(!0),H(Re,null,ct(Zt(Hs),L=>(K(),H("option",{key:L.key,value:L.key},se(L.label),9,pv))),128))],512),[[Fn,c.value]])]),u("div",hv,[P[16]||(P[16]=u("label",null,"耗时(分钟)",-1)),Te(u("input",{class:"input",type:"number",min:"0","onUpdate:modelValue":P[4]||(P[4]=L=>d.value=L),placeholder:"选填"},null,512),[[Le,d.value,void 0,{number:!0}]])]),u("div",vv,[P[17]||(P[17]=u("label",null,"主要收获",-1)),Te(u("input",{class:"input","onUpdate:modelValue":P[5]||(P[5]=L=>h.value=L),placeholder:"一句话:学到了什么"},null,512),[[Le,h.value]])]),u("div",mv,[P[18]||(P[18]=u("label",null,"备注",-1)),Te(u("textarea",{class:"textarea","onUpdate:modelValue":P[6]||(P[6]=L=>y.value=L),placeholder:"背景、链接、未决事项(选填)"},null,512),[[Le,y.value]])]),u("div",yv,[P[19]||(P[19]=u("label",null,"成果标记",-1)),u("button",{class:tt(["toggle-btn",{on:m.value===1}]),onClick:P[7]||(P[7]=L=>m.value=m.value===1?0:1)},se(m.value===1?"已标记为成果":"未标记"),3)]),u("div",gv,[P[20]||(P[20]=u("label",null,"待跟进",-1)),u("button",{class:tt(["toggle-btn",{onwarn:w.value===1}]),onClick:P[8]||(P[8]=L=>w.value=w.value===1?0:1)},se(w.value===1?"需要跟进":"无需跟进"),3)])])]),u("div",bv,[u("button",{class:"btn btn-sm",onClick:P[9]||(P[9]=L=>s("cancel"))},"取消"),u("button",{class:"btn btn-primary btn-sm",onClick:te},"保存修改")])])])):Ee("",!0)]),_:1})]))}}),_v=Yt(wv,[["__scopeId","data-v-63bc0b48"]]);function $s(e){return e<10?"0"+e:String(e)}function Nn(e){return e.getFullYear()+"-"+$s(e.getMonth()+1)+"-"+$s(e.getDate())}function xt(){return Nn(new Date)}function wt(){const e=new Date;return Nn(e)+"T"+$s(e.getHours())+":"+$s(e.getMinutes())+":"+$s(e.getSeconds())}function Vn(e){if(!e)return"--:--";const t=e.indexOf("T");return t>=0?e.slice(t+1,t+6):e.slice(0,5)}function os(e){const t=e.split("-").map(Number);return new Date(t[0],t[1]-1,t[2])}function Kn(e,t){const n=os(e);return n.setDate(n.getDate()+t),Nn(n)}function Xo(e,t){const n=os(e),s=n.getDate();n.setDate(1),n.setMonth(n.getMonth()+t);const o=new Date(n.getFullYear(),n.getMonth()+1,0).getDate();return n.setDate(Math.min(s,o)),Nn(n)}function Ts(e){const t=os(e),n=(t.getDay()+6)%7;return t.setDate(t.getDate()-n),Nn(t)}function kv(e){const t=os(e).getDay();return t===0||t===6}function xv(e,t){return Math.round((new Date(t).getTime()-new Date(e).getTime())/6e4)}function uf(e){const t=os(e),n=["周日","周一","周二","周三","周四","周五","周六"];return t.getFullYear()+" 年 "+(t.getMonth()+1)+" 月 "+t.getDate()+" 日 "+n[t.getDay()]}const Cv=15e4;function Ma(e){const t=new Uint8Array(e);let n="";for(let s=0;s({}));if(!o.ok){const c=a&&a.error||"服务返回 "+o.status;throw e==="register"&&o.status===409?new Error("云端已有同名账号且密码一致,直接登录即可"):new Error(String(c))}if(!a.userId||!a.username)throw new Error("登录响应异常");return{userId:String(a.userId),username:String(a.username)}}async function pl(e,t,n){const s=await Nv(n,e,t);ni(s.userId);const o={userId:s.userId,username:s.username};return Kv(o),gf(s.username,t),o}async function Vv(e,t){const n=(e||"").trim();if(!n||!t)throw new Error("请输入用户名与密码");return pl(n,t,"login")}async function Bv(e,t,n){const s=(e||"").trim();if(s.length<2||s.length>20)throw new Error("用户名需 2 到 20 个字符");if(t.length<6)throw new Error("登录密码至少 6 位");return pl(s,t,"register")}async function Uv(){const e=dr();if(!e)return null;try{return await pl(e.username,e.password,"login")}catch{return null}}async function qv(){ei(),al(),ti=null,yf()}function Hv(){ei(),al(),ti=null,yf(),Fv()}async function Wv(e,t){if(!wi())throw new Error("未登录");if(t.length<6)throw new Error("新密码至少 6 位");const s=dr();if(!s||s.password!==e)throw new Error("旧密码不正确");const o=await Lr();let a;try{a=await fetch(o+"/api/auth/password",{method:"POST",headers:{"Content-Type":"application/json",Authorization:"Bearer "+bf()},body:JSON.stringify({oldPassword:e,newPassword:t})})}catch{throw new Error("无法连接同步服务器")}if(!a.ok){const c=await a.json().catch(()=>({}));throw new Error(c&&c.error||"修改失败 "+a.status)}gf(s.username,t)}async function zv(){if(!wi())throw new Error("未登录");const t=await Lr();let n;try{n=await fetch(t+"/api/auth/delete",{method:"POST",headers:{Authorization:"Bearer "+bf()}})}catch{throw new Error("无法连接同步服务器")}if(!n.ok){const s=await n.json().catch(()=>({}));throw new Error(s&&s.error||"删除失败 "+n.status)}Hv()}function bf(){return cl()}const Ra=F(null),Ka=F(null),Ws=F(0);function er(){Ws.value++}const Jr=F(""),Fs=["project","work_log","log_item","attendance","weekly_note","setting","memo","credential","transaction"],Gr=new Set(["sync_cursor","sync_last_time","sync_token","last_project","last_category"]),Gv=Lr;function Oo(e){return JSON.stringify(e)}async function Yv(e){return fe.table(e).toArray()}function Mo(e,t){return e==="setting"?t.key:t.id}async function Jv(){for(const e of Fs){const t=fe.table(e),n=await t.toArray();for(const s of n){if(e==="setting"&&Gr.has(s.key))continue;const o={};s.uuid||(o.uuid=Xv()),!s.updated_at&&s.created_at&&(o.updated_at=s.created_at),Object.keys(o).length&&await t.update(Mo(e,s),o)}}}function Xv(){return typeof crypto<"u"&&crypto.randomUUID?crypto.randomUUID():"u"+Date.now().toString(36)+Math.random().toString(36).slice(2,10)}async function Qv(){return dr()!=null}async function Zv(){try{return localStorage.getItem("dsh_last_sync")||""}catch{return""}}async function em(e){try{localStorage.setItem("dsh_last_sync",e)}catch{}}async function wf(e,t){const n=await fetch(e+"/api/auth/login",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({username:t.username.trim(),password:t.password})});if(!n.ok)throw new Error("云端账号或密码不正确");const s=await n.json();if(!s||!s.token)throw new Error("云端登录异常");return String(s.token)}async function tm(e,t){let n=cl();return n||(n=await wf(e,t),La(n),n)}async function _f(){const e=dr();if(!e)throw new Error("未登录");const t=await Lr(),n=await fetch(t+"/api/auth/login",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({username:e.username,password:e.password})});if(!n.ok)throw new Error("云端账号校验失败:"+n.status)}async function Fa(){const e=dr();if(!e)throw new Error("未登录,无法同步");return Sf({baseUrl:await Lr(),username:e.username,password:e.password})}async function kf(){try{await Fa()}catch(e){Jr.value=e instanceof Error?e.message:String(e);try{await Fa()}catch{}throw e}}function xf(e,t,n){const s={};for(const o of Object.keys(t))o!=="id"&&(s[o]=t[o]);if(e==="log_item"){delete s.work_log_id,delete s.project_id;const o=t.work_log_id?n.workLog.get(t.work_log_id):null;o&&o.uuid&&(s.wuuid=o.uuid);const a=t.project_id?n.project.get(t.project_id):null;a&&a.uuid&&(s.puuid=a.uuid)}return s}async function Cf(){const e=await fe.work_log.toArray(),t=await fe.project.toArray();return{workLog:new Map(e.map(n=>[n.id,n])),project:new Map(t.map(n=>[n.id,n]))}}let Ps=!1,Io=!1,Na=!1,Xr=null,_n=null,Va="",Ba=!1,jo=null;async function Qr(){if(Ps){Io=!0;return}try{if(!await Qv())return;await Sf(await nm()),Jr.value=""}catch(e){Jr.value=e instanceof Error?e.message:String(e)}}async function nm(){const e=dr();if(!e)throw new Error("未登录,无法同步");return{baseUrl:await Lr(),username:e.username,password:e.password}}function rm(){if(Ba)return;Ba=!0,jo=Zh(async()=>{const t={};for(const n of Fs)t[n]=await fe.table(n).count();return t}).subscribe({next:()=>{Na||Ps||(Xr&&globalThis.clearTimeout(Xr),Xr=globalThis.setTimeout(()=>{Qr()},3e3))},error:()=>{}})}function sm(){jo&&(jo.unsubscribe(),jo=null),_n&&(_n.close(),_n=null,Va=""),Xr&&(globalThis.clearTimeout(Xr),Xr=null),Ba=!1}function om(e,t){const n=e+"|"+t;if(!(_n&&Va===n)){_n&&(_n.close(),_n=null);try{_n=new EventSource(e+"/api/events?token="+encodeURIComponent(t)),Va=n,_n.onmessage=()=>{Qr()}}catch{_n=null}}}async function Sf(e){if(Ps)return Io=!0,{pushed:0,pulled:0,removed:0,errors:0,at:""};Ps=!0,Na=!0;try{const t=await im(e);return Io&&(Io=!1,globalThis.setTimeout(()=>{Qr()},800)),t}finally{Ps=!1,Na=!1}}async function im(e){const t=e.baseUrl.trim().replace(/\/+$/,"");if(!t)throw new Error("请先配置同步服务地址");await Jv();const n=await Cf(),s=await fe.sync_mirror.toArray(),o=new Map;for(const te of s)o.set(te.table+"|"+te.uuid,te);const a={},c=[];let d=0;for(const te of Fs){let ue=await Yv(te);te==="setting"&&(ue=ue.filter(L=>!Gr.has(L.key)));const P=new Map;for(const L of ue)P.set(L.uuid,L);for(const[L,J]of P){const ce=xf(te,J,n),ie=Oo(ce),Q=o.get(te+"|"+L);(!Q||Q.hash!==ie)&&(a[te]=a[te]||[],a[te].push(ce),d++)}for(const[L,J]of o)L.startsWith(te+"|")&&!P.has(J.uuid)&&c.push({table:te,uuid:J.uuid,deleted_at:wt()});a[te]=a[te]||[]}c.push(...fm());const h=await tm(t,e),y=te=>fetch(t+"/api/sync",{method:"POST",headers:{"Content-Type":"application/json",Authorization:"Bearer "+te},body:JSON.stringify({device:"client",tables:a,tombstones:c})});let m=await y(h);if(m.status===401){La("");const te=await wf(t,e);La(te),m=await y(te)}if(!m.ok)throw new Error("同步服务返回 "+m.status);const w=await m.json(),C=w.tables||{},O=w.tombstones||[],N=await um(C,O);om(t,cl()||h);const ee=wt();return await em(ee),(N.changed>0||N.removed>0||d>0)&&er(),{pushed:d,pulled:N.changed,removed:N.removed,errors:0,at:ee}}function Ef(){var t;return"dsh_idmap_"+(((t=dr())==null?void 0:t.username)||"anon")}function am(){try{const e=localStorage.getItem(Ef());if(e)return JSON.parse(e)}catch{}return{}}function lm(e){try{localStorage.setItem(Ef(),JSON.stringify(e))}catch{}}async function um(e,t){const n=am(),s=new Set(t.map(C=>C.table+"|"+C.uuid)),o=new Map;for(const C of await fe.sync_mirror.toArray())o.set(C.table+"|"+C.uuid,C);const a=new Set(Array.from(o.keys()).map(C=>C.split("|")[1]));let c=0,d=0;const h={},y={};for(const C of Fs){const O=fe.table(C),N=await O.toArray(),ee=new Map(N.map(S=>[Mo(C,S),S])),te=new Map(N.filter(S=>S.uuid).map(S=>[S.uuid,S])),ue=(e[C]||[]).filter(S=>!s.has(C+"|"+S.uuid)),P=ue.filter(S=>!(C==="setting"&&Gr.has(S.key))),L=ue.filter(S=>C==="setting"&&Gr.has(S.key));for(const S of L)cm(C,S.uuid);const J=C==="setting"?[]:N.filter(S=>S.uuid&&!a.has(S.uuid)&&!s.has(C+"|"+S.uuid)),ce={v:Math.max(0,...N.map(S=>Number(S.id)||0))};P.length;const ie=[];for(const S of P){const oe={...S};if(C==="log_item"){const xe=oe.wuuid?h[oe.wuuid]:void 0;if(!xe)continue;oe.work_log_id=xe,delete oe.wuuid,oe.project_id=oe.puuid?y[oe.puuid]??null:null,delete oe.puuid}let ge=Mo(C,S);if(C==="setting")ge=S.key;else{const xe=n[C]&&n[C][S.uuid],Fe=te.get(S.uuid);Fe&&Fe.id!=null?ge=Fe.id:typeof xe=="number"?ge=xe:ge=++ce.v}const Y={...oe,id:ge};C==="setting"&&Gr.has(Y.key)||(ie.push(Y),C==="work_log"&&(h[S.uuid]=ge),C==="project"&&(y[S.uuid]=ge))}const Q=ie.concat(J);for(const S of Q){const oe=ee.get(Mo(C,S));(!oe||Oo(oe)!==Oo(S))&&c++}d+=N.filter(S=>S.uuid&&!ie.some(oe=>oe.uuid===S.uuid)&&!s.has(C+"|"+S.uuid)).length,await O.clear(),Q.length&&await O.bulkPut(Q);const A={};for(const S of Q)S.uuid&&(A[S.uuid]=S.id);n[C]=A}lm(n);const m=await Cf(),w=[];for(const C of Fs){const O=await fe.table(C).toArray();for(const N of O)C==="setting"&&Gr.has(N.key)||N.uuid&&w.push({table:C,uuid:N.uuid,hash:Oo(xf(C,N,m))})}return await fe.sync_mirror.clear(),w.length&&await fe.sync_mirror.bulkAdd(w.map(C=>({...C}))),await fe.tombstone.clear(),{changed:c,removed:d+ri.length}}const ri=[];function cm(e,t){ri.some(n=>n.table===e&&n.uuid===t)||ri.push({table:e,uuid:t,deleted_at:wt()})}function fm(){return ri.splice(0)}const dm=new Set(["sync_cursor","sync_last_time","sync_token","last_project","last_category"]);async function _t(){await kf()}async function gt(e,t){const n=await fe.setting.get(e);return n?n.value:t}async function jt(e,t){await fe.setting.put({key:e,value:t}),dm.has(e)||await _t()}async function Dr(){const e=await Promise.all([gt("work_start","09:00"),gt("work_end","18:00"),gt("grace_minutes","10"),gt("lunch_minutes","60"),gt("remind_weekly","friday")]);return{work_start:e[0],work_end:e[1],grace_minutes:Number(e[2])||0,lunch_minutes:Number(e[3])||0,remind_weekly:e[4]}}async function pm(){const e=await gt("last_project",""),t=await gt("last_category","dev");return{project_id:e?Number(e):null,category:t||"dev"}}async function hm(){return gt("last_location","")}async function vm(e,t){const n=t.trim();await jt("last_location",n),n&&await si(n);let s=!1;const o=await yn(e);o&&o.id?(o.location||"")!==n&&(await fe.attendance.update(o.id,{location:n||null}),s=!0):n&&(await fe.attendance.add({date:e,clock_in_at:null,clock_out_at:null,kind:"normal",note:null,location:n,created_at:wt()}),s=!0),s&&await _t()}async function hl(){const e=await gt("location_presets","");if(!e)return Ku.slice();try{const t=JSON.parse(e);if(Array.isArray(t))return t.filter(n=>typeof n=="string"&&n.trim()).map(n=>n.trim())}catch{}return Ku.slice()}async function $f(e){const t=Array.from(new Set(e.map(n=>n.trim()).filter(Boolean)));await jt("location_presets",JSON.stringify(t))}async function si(e){const t=e.trim();if(!t)return;const n=await hl();n.includes(t)||await $f([...n,t])}async function Ns(e=!1){const t=await fe.project.orderBy("name").toArray();return e?t:t.filter(n=>n.archived!==1)}async function mm(e){await fe.project.add({name:e.trim(),archived:0,created_at:wt()}),await _t()}async function ym(e,t){await fe.project.update(e,{name:t.trim()}),await _t()}async function gm(e,t){await fe.project.update(e,{archived:t?1:0}),await _t()}async function yn(e){return fe.attendance.where("date").equals(e).first()}async function Tf(e,t){const n=((t===void 0?await gt("last_location",""):t)||"").trim();let s=!1;const o=await yn(e);if(o&&o.id){if(!o.clock_in_at){const a={clock_in_at:wt()};n&&(a.location=n),await fe.attendance.update(o.id,a),s=!0}n&&(await gt("last_location","")!==n&&await jt("last_location",n),await si(n)),s&&await _t();return}await fe.attendance.add({date:e,clock_in_at:wt(),clock_out_at:null,kind:"normal",note:null,location:n||null,created_at:wt()}),n&&(await jt("last_location",n),await si(n)),await _t()}async function bm(e){const t=await yn(e);t&&t.id&&t.clock_in_at&&!t.clock_out_at&&(await fe.attendance.update(t.id,{clock_out_at:wt()}),await _t())}async function wm(){const e=new Date,t=Nn(e);let n="";if(e.getHours()<4){const s=await yn(Kn(t,-1));s&&s.id&&s.clock_in_at&&!s.clock_out_at&&(await fe.attendance.update(s.id,{clock_out_at:wt()}),n=s.date)}if(!n){const s=await yn(t);s&&s.id&&s.clock_in_at&&!s.clock_out_at&&(await fe.attendance.update(s.id,{clock_out_at:wt()}),n=s.date)}if(!n)throw new Error("没有进行中的打卡");return await _t(),n}async function _m(e,t,n,s,o){(o||"").trim()&&await si(o);const a=await yn(e),c={date:e,clock_in_at:t,clock_out_at:n,kind:"makeup",note:s||null,location:(o||"").trim()||null,created_at:wt()};a&&a.id?await fe.attendance.update(a.id,c):await fe.attendance.add(c),await _t()}async function km(e,t,n){const s=(n||"").trim();if(!s)return;const o=await yn(e);o&&o.id&&(await fe.attendance.update(o.id,{[t]:e+"T"+s+":00"}),await _t())}async function _i(e,t){return fe.attendance.where("date").between(e,t,!0,!0).toArray()}async function xm(e,t){const n=await yn(e);if(t){const s={date:e,kind:"leave",clock_in_at:null,clock_out_at:null,created_at:wt()};n&&n.id?await fe.attendance.update(n.id,s):await fe.attendance.add({...s,note:null,location:null})}else n&&n.id&&await fe.attendance.update(n.id,{kind:"normal"});await _t()}async function Cm(e){const t=await fe.work_log.where("date").equals(e).first();return t||{id:await fe.work_log.add({date:e,created_at:wt()}),date:e,created_at:wt()}}async function Sm(e){return fe.work_log.where("date").equals(e).first()}async function Em(e){const t=await Sm(e);return!t||!t.id?[]:(await fe.log_item.where("work_log_id").equals(t.id).toArray()).sort((s,o)=>o.id-s.id)}async function $m(e,t){const n=await fe.work_log.where("date").equals(e).first();let s;n&&n.id?s=n:s=await Cm(e),await fe.table("log_item").add({work_log_id:s.id,content:t.content,project_id:t.project_id,category:t.category,minutes:t.minutes,is_milestone:0,needs_followup:0,takeaway:t.takeaway,remark:t.remark,sort_order:0,created_at:wt()});const o=t.project_id?String(t.project_id):"";await gt("last_project","")!==o&&await jt("last_project",o),await gt("last_category","")!==t.category&&await jt("last_category",t.category),await _t()}async function ha(e,t){await fe.table("log_item").update(e,t),await _t()}async function Tm(e){await fe.table("log_item").delete(e),await _t()}async function ki(e,t){const n=await fe.work_log.where("date").between(e,t,!0,!0).toArray();if(!n.length)return[];const s=new Map(n.map(a=>[a.id,a.date]));return(await fe.table("log_item").where("work_log_id").anyOf(n.map(a=>a.id)).toArray()).map(a=>({...a,date:s.get(a.work_log_id)||""})).sort((a,c)=>a.date===c.date?a.id-c.id:a.datet.updated_at[c.id,c.date]));return(await fe.table("log_item").toArray()).filter(c=>((c.content||"")+" "+(c.takeaway||"")+" "+(c.remark||"")).toLowerCase().includes(n)).sort((c,d)=>d.id-c.id).slice(0,t).map(c=>({...c,date:o.get(c.work_log_id)||""}))}async function Lm(e,t=4){const n=e.trim().toLowerCase();return n?(await fe.memo.toArray()).filter(o=>((o.title||"")+" "+(o.content||"")).toLowerCase().includes(n)).sort((o,a)=>o.updated_at{await Promise.all([fe.project.clear(),fe.work_log.clear(),s.clear(),fe.attendance.clear(),fe.weekly_note.clear(),fe.setting.clear(),fe.memo.clear(),fe.credential.clear(),o.clear()]),n.project&&n.project.length&&await fe.project.bulkAdd(n.project),n.work_log&&n.work_log.length&&await fe.work_log.bulkAdd(n.work_log),n.log_item&&n.log_item.length&&await s.bulkAdd(n.log_item),n.attendance&&n.attendance.length&&await fe.attendance.bulkAdd(n.attendance),n.weekly_note&&n.weekly_note.length&&await fe.weekly_note.bulkAdd(n.weekly_note),n.setting&&n.setting.length&&await fe.setting.bulkAdd(n.setting),n.memo&&n.memo.length&&await fe.memo.bulkAdd(n.memo),n.credential&&n.credential.length&&await fe.credential.bulkAdd(n.credential),n.transaction&&n.transaction.length&&await o.bulkAdd(n.transaction)}),await _t()}function Eo(e){const t=e.split(":");return Number(t[0])*60+Number(t[1])}function zs(e,t,n,s){if(e&&e.kind==="leave")return{status:"leave",label:"请假",makeup:!1,workedMinutes:null};if(kv(t))return{status:"rest",label:"休息日",makeup:!1,workedMinutes:null};if(!e||!e.clock_in_at)return s?{status:"none",label:"未打卡",makeup:!1,workedMinutes:null}:{status:"absent",label:"缺勤",makeup:!!(e&&e.kind==="makeup"),workedMinutes:null};const o=e.kind==="makeup";if(!e.clock_out_at)return{status:"incomplete",label:s?"进行中":"未完成",makeup:o,workedMinutes:null};const a=Eo(Vn(e.clock_in_at)),c=Eo(Vn(e.clock_out_at)),d=Eo(n.work_start),h=Eo(n.work_end);let y="normal";!o&&a>d+n.grace_minutes?y="late":!o&&c{Do.value=Do.value.filter(n=>n.id!==t)},2e3)}function Hm(){return Do}const Wm={class:"day-panel"},zm={class:"dp-head"},Gm={class:"dp-date"},Ym={class:"card sec"},Jm={class:"att-grid"},Xm={class:"att-cell"},Qm={key:0,class:"edit-row"},Zm={key:1,class:"att-val"},ey={class:"att-cell"},ty={key:0,class:"edit-row"},ny={key:1,class:"att-val"},ry={class:"att-cell"},sy=["list"],oy=["id"],iy=["value"],ay={class:"att-cell"},ly={class:"att-val status-val"},uy={key:0,class:"tag"},cy={key:1,class:"muted"},fy={key:0,class:"att-note muted"},dy={class:"att-actions"},py=["disabled"],hy=["disabled"],vy=["disabled"],my=["disabled"],yy={key:0,class:"card sec makeup"},gy={class:"form-grid"},by={class:"field"},wy={class:"field"},_y={class:"field span2"},ky=["list"],xy={class:"field span2"},Cy={key:0,class:"form-error"},Sy={class:"form-footer"},Ey={class:"card sec"},$y={class:"form-grid"},Ty={class:"field span2"},Py={key:0,class:"form-error"},Ay={class:"field"},Oy=["value"],My={class:"field"},Iy=["value"],jy={class:"field"},Dy={class:"field"},Ly={class:"field span2"},Ry={class:"form-footer"},Ky=["disabled"],Fy=["disabled"],Ny={class:"list-sec"},Vy={class:"sec-title"},By={key:0,class:"empty muted"},Uy={class:"item-main"},qy={class:"tag"},Hy=["onClick"],Wy={key:0,class:"muted item-meta"},zy={key:1,class:"muted num item-meta"},Gy=["onClick"],Yy=["onClick"],Jy=["onClick"],Xy=["onClick"],Qy={key:0,class:"item-sub"},Zy={key:0,class:"muted2"},eg={key:1,class:"muted"},tg={key:1,class:"dp-foot muted num"},ng=Bt({__name:"DayPanel",props:{date:{}},setup(e){const t=e,n=F(!0),s=F(null),o=F(void 0),a=F([]),c=F([]),d=F(""),h=F([]),y=at(()=>"loc-list-"+t.date),m=at(()=>t.date===xt());async function w(){n.value=!0,s.value=await Dr(),o.value=await yn(t.date),a.value=await Em(t.date),c.value=await Ns(!0),h.value=await hl(),d.value=o.value&&o.value.location||await hm(),n.value=!1}mn(w),vt(()=>t.date,w),vt(Ws,()=>{w()});const C=at(()=>c.value.filter(U=>U.archived!==1));function O(U){if(!U)return"";const q=c.value.find(G=>G.id===U);return q?q.name:"已删除项目"}const N=at(()=>s.value?zs(o.value,t.date,s.value,m.value):null),ee=at(()=>a.value.reduce((U,q)=>U+(q.minutes||0),0)),te=F(!1);async function ue(){te.value||(te.value=!0,await Tf(t.date,d.value),await w(),er(),Ue("上班打卡成功"),te.value=!1)}async function P(){te.value||(te.value=!0,await bm(t.date),await w(),er(),Ue("下班打卡成功"),te.value=!1)}async function L(){await vm(t.date,d.value),er(),Ue("地点已更新")}const J=F(!1),ce=at(()=>{var U;return((U=o.value)==null?void 0:U.kind)==="leave"});function ie(){if(o.value&&o.value.clock_in_at){J.value=!0;return}Q(!0)}async function Q(U){J.value=!1,await xm(t.date,U),await w(),er(),Ue(U?"已标记为休假":"已取消休假")}const A=F(null),S=F(""),oe=F(null);vt(A,async U=>{var q;U&&(await rs(),(q=oe.value)==null||q.focus())});function ge(U){var G,$e;const q=U==="in"?(G=o.value)==null?void 0:G.clock_in_at:($e=o.value)==null?void 0:$e.clock_out_at;A.value=U,S.value=q?Vn(q):U==="in"?"09:00":"18:00"}function Y(){A.value=null}async function xe(){const U=A.value;U&&(A.value=null,S.value&&(await km(t.date,U==="in"?"clock_in_at":"clock_out_at",S.value),await w(),er(),Ue("打卡时间已修改")))}const Fe=F(!1),rt=F("09:00"),We=F("18:00"),Ye=F(""),me=F(""),Me=F("");function Ne(){me.value=d.value,Me.value="",Fe.value=!Fe.value}async function De(){if(!rt.value||!We.value){Me.value="请填写上班与下班时间";return}await _m(t.date,t.date+"T"+rt.value+":00",t.date+"T"+We.value+":00",Ye.value.trim(),me.value),Fe.value=!1,Ye.value="",Me.value="",await w(),er(),Ue("补卡已保存")}const Ce=F(""),X=F("");vt(Ce,()=>{X.value&&(X.value="")});const Z=F(null),ke=F("dev"),Be=F(null),dt=F(""),Jt=F(""),Xt=F(!1),je=at(()=>!!(Ce.value.trim()||Be.value||dt.value.trim()||Jt.value.trim()));mn(async()=>{const U=await pm();Z.value=U.project_id,ke.value=U.category});function k(){Ce.value="",Be.value=null,dt.value="",Jt.value="",X.value=""}async function _(){const U=Ce.value.trim();if(!U){X.value="请填写工作内容";return}Xt.value||(Xt.value=!0,await $m(t.date,{content:U,project_id:Z.value,category:ke.value,minutes:Be.value&&Be.value>0?Be.value:null,takeaway:dt.value.trim()||null,remark:Jt.value.trim()||null}),k(),await w(),Ue("记录已添加"),Xt.value=!1)}const x=F(null);function z(U){x.value=U}async function ne(U){const q=U.id,G={content:U.content,project_id:U.project_id,category:U.category,minutes:U.minutes,takeaway:U.takeaway,remark:U.remark,is_milestone:U.is_milestone,needs_followup:U.needs_followup};await ha(q,G),x.value=null,await w(),Ue("修改已保存")}async function le(U){await ha(U.id,{is_milestone:U.is_milestone?0:1}),await w()}async function be(U){await ha(U.id,{needs_followup:U.needs_followup?0:1}),await w()}const ve=F(null);async function ae(){ve.value&&ve.value.id&&await Tm(ve.value.id),ve.value=null,await w(),Ue("记录已删除")}return(U,q)=>(K(),H("div",Wm,[u("div",zm,[u("div",Gm,se(Zt(uf)(e.date)),1)]),u("div",Ym,[q[25]||(q[25]=u("div",{class:"sec-title"},"出勤信息",-1)),u("div",Jm,[u("div",Xm,[q[21]||(q[21]=u("label",null,"上班时间",-1)),A.value==="in"?(K(),H("div",Qm,[Te(u("input",{ref_key:"timeInput",ref:oe,type:"time",class:"input time-input","onUpdate:modelValue":q[0]||(q[0]=G=>S.value=G),onKeydown:[Dt(xe,["enter"]),Dt(Y,["esc"])]},null,544),[[Le,S.value]]),u("button",{class:"btn btn-primary btn-sm",onClick:xe},"确认"),u("button",{class:"btn btn-sm",onClick:Y},"取消")])):(K(),H("div",Zm,[u("span",{class:tt(["num",{"val-empty":!(o.value&&o.value.clock_in_at)}])},se(o.value&&o.value.clock_in_at?Zt(Vn)(o.value.clock_in_at):"未打卡"),3),o.value&&o.value.id?(K(),H("button",{key:0,class:"icon-btn",title:"修改上班时间",onClick:q[1]||(q[1]=G=>ge("in"))},[Oe(ut,{name:"edit",size:13})])):Ee("",!0)]))]),u("div",ey,[q[22]||(q[22]=u("label",null,"下班时间",-1)),A.value==="out"?(K(),H("div",ty,[Te(u("input",{ref_key:"timeInput",ref:oe,type:"time",class:"input time-input","onUpdate:modelValue":q[2]||(q[2]=G=>S.value=G),onKeydown:[Dt(xe,["enter"]),Dt(Y,["esc"])]},null,544),[[Le,S.value]]),u("button",{class:"btn btn-primary btn-sm",onClick:xe},"确认"),u("button",{class:"btn btn-sm",onClick:Y},"取消")])):(K(),H("div",ny,[u("span",{class:tt(["num",{"val-empty":!(o.value&&o.value.clock_out_at)}])},se(o.value&&o.value.clock_out_at?Zt(Vn)(o.value.clock_out_at):"未打卡"),3),o.value&&o.value.id?(K(),H("button",{key:0,class:"icon-btn",title:"修改下班时间",onClick:q[3]||(q[3]=G=>ge("out"))},[Oe(ut,{name:"edit",size:13})])):Ee("",!0)]))]),u("div",ry,[q[23]||(q[23]=u("label",null,"上班地点",-1)),Te(u("input",{class:"input","onUpdate:modelValue":q[4]||(q[4]=G=>d.value=G),list:y.value,placeholder:"可直接输入",title:"上班地点,可自由输入",onChange:L},null,40,sy),[[Le,d.value]]),u("datalist",{id:y.value},[(K(!0),H(Re,null,ct(h.value,G=>(K(),H("option",{key:G,value:G},null,8,iy))),128))],8,oy)]),u("div",ay,[q[24]||(q[24]=u("label",null,"考勤状态",-1)),u("div",ly,[N.value?(K(),H(Re,{key:0},[u("span",{class:tt(["dot",N.value.status])},null,2),u("span",null,se(N.value.label),1),o.value&&o.value.kind==="makeup"?(K(),H("span",uy,"补卡")):Ee("",!0)],64)):(K(),H("span",cy,"--"))])])]),o.value&&o.value.note?(K(),H("div",fy,"补卡说明:"+se(o.value.note),1)):Ee("",!0),u("div",dy,[m.value&&(!o.value||!o.value.clock_in_at)?(K(),H("button",{key:0,class:"btn btn-primary btn-sm",disabled:te.value,onClick:ue},"上班打卡",8,py)):m.value&&o.value&&o.value.clock_in_at&&!o.value.clock_out_at?(K(),H("button",{key:1,class:"btn btn-primary btn-sm",disabled:te.value,onClick:P},"下班打卡",8,hy)):Ee("",!0),!m.value&&(!o.value||!o.value.clock_in_at)?(K(),H("button",{key:2,class:"btn btn-sm",onClick:Ne},"补卡")):Ee("",!0),ce.value?(K(),H("button",{key:4,class:"btn btn-sm",disabled:te.value,onClick:q[5]||(q[5]=G=>Q(!1))},"取消休假",8,my)):(K(),H("button",{key:3,class:"btn btn-sm",disabled:te.value,onClick:ie},"标记休假",8,vy))])]),Fe.value?(K(),H("div",yy,[q[30]||(q[30]=u("div",{class:"sec-title"},"补卡登记",-1)),u("div",gy,[u("div",by,[q[26]||(q[26]=u("label",null,"上班时间",-1)),Te(u("input",{type:"time",class:"input","onUpdate:modelValue":q[6]||(q[6]=G=>rt.value=G)},null,512),[[Le,rt.value]])]),u("div",wy,[q[27]||(q[27]=u("label",null,"下班时间",-1)),Te(u("input",{type:"time",class:"input","onUpdate:modelValue":q[7]||(q[7]=G=>We.value=G)},null,512),[[Le,We.value]])]),u("div",_y,[q[28]||(q[28]=u("label",null,"上班地点",-1)),Te(u("input",{class:"input",list:y.value,"onUpdate:modelValue":q[8]||(q[8]=G=>me.value=G),placeholder:"可直接输入"},null,8,ky),[[Le,me.value]])]),u("div",xy,[q[29]||(q[29]=u("label",null,"补卡原因",-1)),Te(u("input",{class:"input","onUpdate:modelValue":q[9]||(q[9]=G=>Ye.value=G),placeholder:"如:外出拜访客户忘记打卡"},null,512),[[Le,Ye.value]])])]),Me.value?(K(),H("div",Cy,se(Me.value),1)):Ee("",!0),u("div",Sy,[u("button",{class:"btn btn-sm",onClick:q[10]||(q[10]=G=>Fe.value=!1)},"取消"),u("button",{class:"btn btn-primary btn-sm",onClick:De},"保存补卡")])])):Ee("",!0),u("div",Ey,[q[38]||(q[38]=u("div",{class:"sec-head"},[u("span",{class:"sec-title"},"新增工作记录"),u("span",{class:"muted form-hint"},"内容必填,其余选填")],-1)),u("div",$y,[u("div",Ty,[q[31]||(q[31]=u("label",null,"工作内容(必填)",-1)),Te(u("input",{class:tt(["input",{invalid:X.value}]),"onUpdate:modelValue":q[11]||(q[11]=G=>Ce.value=G),placeholder:"做了什么,一句话一条",onKeydown:Dt(_,["enter"])},null,34),[[Le,Ce.value]]),X.value?(K(),H("div",Py,se(X.value),1)):Ee("",!0)]),u("div",Ay,[q[33]||(q[33]=u("label",null,"所属项目",-1)),Te(u("select",{class:"select","onUpdate:modelValue":q[12]||(q[12]=G=>Z.value=G)},[q[32]||(q[32]=u("option",{value:null},"无项目",-1)),(K(!0),H(Re,null,ct(C.value,G=>(K(),H("option",{key:G.id,value:G.id},se(G.name),9,Oy))),128))],512),[[Fn,Z.value]])]),u("div",My,[q[34]||(q[34]=u("label",null,"工作分类",-1)),Te(u("select",{class:"select","onUpdate:modelValue":q[13]||(q[13]=G=>ke.value=G)},[(K(!0),H(Re,null,ct(Zt(Hs),G=>(K(),H("option",{key:G.key,value:G.key},se(G.label),9,Iy))),128))],512),[[Fn,ke.value]])]),u("div",jy,[q[35]||(q[35]=u("label",null,"耗时(分钟)",-1)),Te(u("input",{class:"input",type:"number",min:"0","onUpdate:modelValue":q[14]||(q[14]=G=>Be.value=G),placeholder:"选填"},null,512),[[Le,Be.value,void 0,{number:!0}]])]),u("div",Dy,[q[36]||(q[36]=u("label",null,"主要收获",-1)),Te(u("input",{class:"input","onUpdate:modelValue":q[15]||(q[15]=G=>dt.value=G),placeholder:"一句话:学到了什么"},null,512),[[Le,dt.value]])]),u("div",Ly,[q[37]||(q[37]=u("label",null,"备注",-1)),Te(u("textarea",{class:"textarea","onUpdate:modelValue":q[16]||(q[16]=G=>Jt.value=G),placeholder:"背景、链接、未决事项(选填)"},null,512),[[Le,Jt.value]])])]),u("div",Ry,[u("button",{class:"btn btn-sm",disabled:!je.value,onClick:k},"重置",8,Ky),u("button",{class:"btn btn-primary btn-sm",disabled:Xt.value,onClick:_},"添加记录",8,Fy)])]),u("div",Ny,[u("div",Vy,"工作记录("+se(a.value.length)+")",1),!a.value.length&&!n.value?(K(),H("div",By,"暂无记录")):Ee("",!0),(K(!0),H(Re,null,ct(a.value,G=>(K(),H("div",{key:G.id,class:"item"},[u("div",Uy,[u("span",qy,se(Zt(ll)(G.category)),1),u("span",{class:"item-content",title:"点击编辑",onClick:$e=>z(G)},se(G.content),9,Hy),G.project_id?(K(),H("span",Wy,se(O(G.project_id)),1)):Ee("",!0),G.minutes?(K(),H("span",zy,se(G.minutes)+" 分钟",1)):Ee("",!0),q[39]||(q[39]=u("span",{class:"flex1"},null,-1)),u("button",{class:"icon-btn",title:"编辑完整信息",onClick:$e=>z(G)},[Oe(ut,{name:"edit",size:14})],8,Gy),u("button",{class:tt(["icon-btn",{active:G.is_milestone===1}]),title:"成果标记",onClick:$e=>le(G)},[Oe(ut,{name:"star",size:14})],10,Yy),u("button",{class:tt(["icon-btn",{"active-warn":G.needs_followup===1}]),title:"待跟进",onClick:$e=>be(G)},[Oe(ut,{name:"flag",size:14})],10,Jy),u("button",{class:"icon-btn",title:"删除",onClick:$e=>ve.value=G},[Oe(ut,{name:"close",size:14})],8,Xy)]),G.takeaway||G.remark?(K(),H("div",Qy,[G.takeaway?(K(),H("div",Zy,"收获:"+se(G.takeaway),1)):Ee("",!0),G.remark?(K(),H("div",eg,"备注:"+se(G.remark),1)):Ee("",!0)])):Ee("",!0)]))),128)),a.value.length?(K(),H("div",tg,[rn(" 共 "+se(a.value.length)+" 条事项 ",1),ee.value?(K(),H(Re,{key:0},[rn(" · "+se((ee.value/60).toFixed(1))+" 小时",1)],64)):Ee("",!0)])):Ee("",!0)]),Oe(lr,{open:!!ve.value,title:"删除确认",message:ve.value?"将删除工作记录「"+ve.value.content+"」。删除后不可恢复。":"","confirm-text":"删除",danger:"",onCancel:q[17]||(q[17]=G=>ve.value=null),onConfirm:ae},null,8,["open","message"]),Oe(lr,{open:J.value,title:"标记休假确认",message:"该日已有打卡记录,标记休假将清空上下班时间。是否继续?","confirm-text":"标记休假",danger:"",onCancel:q[18]||(q[18]=G=>J.value=!1),onConfirm:q[19]||(q[19]=G=>Q(!0))},null,8,["open"]),Oe(_v,{open:!!x.value,item:x.value,projects:c.value,date:e.date,onCancel:q[20]||(q[20]=G=>x.value=null),onSave:ne},null,8,["open","item","projects","date"])]))}}),Pf=Yt(ng,[["__scopeId","data-v-2e90c9d8"]]),rg={class:"cal-page"},sg={class:"cal-toolbar"},og={class:"cal-title num"},ig={class:"cal-head"},ag={class:"cal-grid"},lg=["title","onClick"],ug={class:"cal-marks"},cg={key:0,class:"drawer"},fg={class:"drawer-head"},dg={class:"drawer-body"},pg=Bt({__name:"CalendarView",setup(e){const t=F(xt()),n=at(()=>Number(t.value.slice(0,4))),s=at(()=>Number(t.value.slice(5,7))-1),o=at(()=>n.value+" 年 "+(s.value+1)+" 月"),a=["一","二","三","四","五","六","日"],c=at(()=>{const J=(new Date(n.value,s.value,1).getDay()+6)%7,ce=new Date(n.value,s.value+1,0).getDate(),ie=[];for(let Q=0;Q[ge.date,ge])),A=ce[2],S=new Map;for(const ge of c.value){if(!ge.inMonth)continue;const Y=zs(Q.get(ge.date),ge.date,ie,ge.date===h),xe=A.filter(Fe=>Fe.date===ge.date);S.set(ge.date,{status:Y.status,label:Y.label,location:((oe=Q.get(ge.date))==null?void 0:oe.location)||"",hasLog:xe.length>0,hasMilestone:xe.some(Fe=>Fe.is_milestone===1)})}d.value=S}vt([n,s],y,{immediate:!0}),vt(Ws,()=>{y()});function m(L){var J;return((J=d.value.get(L))==null?void 0:J.status)??""}function w(L){const J=d.value.get(L);return J?L+" · "+J.label+(J.location?" · "+J.location:""):L}function C(L){var J;return!!((J=d.value.get(L))!=null&&J.hasLog)}function O(L){var J;return!!((J=d.value.get(L))!=null&&J.hasMilestone)}function N(){t.value=Xo(t.value,-1)}function ee(){t.value=Xo(t.value,1)}function te(){t.value=xt()}const ue=F(null);function P(L,J){J&&(ue.value=L)}return vt(Ra,L=>{L&&(t.value=L,ue.value=L,Ra.value=null)},{immediate:!0}),(L,J)=>(K(),H("div",rg,[u("div",sg,[u("button",{class:"icon-btn",onClick:N},[Oe(ut,{name:"chevron-left",size:16})]),u("span",og,se(o.value),1),u("button",{class:"icon-btn",onClick:ee},[Oe(ut,{name:"chevron-right",size:16})]),u("button",{class:"btn btn-sm",onClick:te},"回到今天")]),u("div",ig,[(K(),H(Re,null,ct(a,ce=>u("span",{key:ce,class:"cal-week muted"},se(ce),1)),64))]),u("div",ag,[(K(!0),H(Re,null,ct(c.value,(ce,ie)=>(K(),H("button",{key:ie,class:tt(["cal-cell",{blank:!ce.inMonth,weekend:ce.weekend,selected:ue.value===ce.date}]),title:ce.inMonth?w(ce.date):void 0,onClick:Q=>P(ce.date,ce.inMonth)},[ce.inMonth?(K(),H(Re,{key:0},[u("span",{class:tt(["daynum num",{today:ce.date===Zt(h)}])},se(Number(ce.date.slice(8,10))),3),u("span",ug,[m(ce.date)?(K(),H("span",{key:0,class:tt(["dot",m(ce.date)])},null,2)):Ee("",!0),C(ce.date)?(K(),It(ut,{key:1,name:"check-circle",size:12,class:"mark-log"})):Ee("",!0),O(ce.date)?(K(),It(ut,{key:2,name:"star",size:12,class:"mark-star"})):Ee("",!0)])],64)):Ee("",!0)],10,lg))),128))]),Oe(ss,{name:"drawer"},{default:cr(()=>[ue.value?(K(),H("aside",cg,[u("div",fg,[J[1]||(J[1]=u("span",{class:"drawer-title"},"当日详情",-1)),u("button",{class:"icon-btn",onClick:J[0]||(J[0]=ce=>ue.value=null)},[Oe(ut,{name:"close",size:16})])]),u("div",dg,[Oe(Pf,{date:ue.value},null,8,["date"])])])):Ee("",!0)]),_:1})]))}}),hg=Yt(pg,[["__scopeId","data-v-2404dfbe"]]),vg={class:"detail-page"},mg={class:"detail-toolbar"},yg=["value"],gg=["disabled"],bg=Bt({__name:"TodayView",setup(e){const t=F(xt()),n=at(()=>t.value===xt());function s(){t.value=Kn(t.value,-1)}function o(){t.value=Kn(t.value,1)}function a(){t.value=xt()}function c(d){const h=d.target.value;h&&(t.value=h)}return(d,h)=>(K(),H("div",vg,[u("div",mg,[u("button",{class:"icon-btn",title:"前一天",onClick:s},[Oe(ut,{name:"chevron-left",size:16})]),u("span",{class:tt(["date-title num",{"is-today":n.value}])},se(Zt(uf)(t.value)),3),u("button",{class:"icon-btn",title:"后一天",onClick:o},[Oe(ut,{name:"chevron-right",size:16})]),u("input",{type:"date",class:"input w-date",value:t.value,onChange:c},null,40,yg),u("button",{class:"btn btn-sm",disabled:n.value,onClick:a},"回到今天",8,gg)]),Oe(Pf,{date:t.value},null,8,["date"])]))}}),wg=Yt(bg,[["__scopeId","data-v-76243d98"]]),_g={class:"stats"},kg={class:"cards"},xg={class:"card stat-card"},Cg={class:"stat-num num"},Sg={class:"card stat-card"},Eg={class:"stat-num num"},$g={class:"card stat-card"},Tg={class:"stat-num num"},Pg={class:"card stat-card"},Ag={class:"stat-num num"},Og={class:"card section"},Mg={class:"heat"},Ig=["title"],jg={class:"two-col"},Dg={class:"card section"},Lg={class:"bar-label"},Rg={class:"bar-track"},Kg={class:"muted num bar-num"},Fg={key:0,class:"muted"},Ng={class:"card section"},Vg={class:"bar-label"},Bg={class:"bar-track"},Ug={class:"muted num bar-num"},qg={key:0,class:"muted"},Hg={class:"card section"},Wg={class:"bar-label loc-label"},zg={class:"bar-track"},Gg={class:"muted num bar-num"},Yg={key:0,class:"muted"},Jg=Bt({__name:"StatsView",setup(e){const t=F({attendDays:0,totalHours:"0",itemCount:0,streak:0}),n=F([]),s=F([]),o=F([]),a=F([]);async function c(){const y=xt(),m="2000-01-01",w=await Promise.all([Dr(),_i(m,y),ki(m,y),Ns(!0)]),C=w[0],O=w[1],N=w[2],ee=w[3],te=O.filter(Y=>Y.clock_in_at||Y.kind==="makeup");let ue=0;for(const Y of te){const xe=zs(Y,Y.date,C,Y.date===y);ue+=xe.workedMinutes??0}const P=new Set(N.map(Y=>Y.date));let L=0,J=y;for(P.has(J)||(J=Kn(y,-1));P.has(J);)L++,J=Kn(J,-1);t.value={attendDays:te.length,totalHours:(ue/60).toFixed(1),itemCount:N.length,streak:L};const ce=new Map;for(const Y of te){const xe=Y.location||"未记录";ce.set(xe,(ce.get(xe)||0)+1)}a.value=Array.from(ce.entries()).map(Y=>({name:Y[0],count:Y[1],percent:Math.round(Y[1]/(te.length||1)*100)})).sort((Y,xe)=>xe.count-Y.count);const ie=N.length||1;s.value=Hs.map(Y=>{const xe=N.filter(Fe=>Fe.category===Y.key).length;return{key:Y.key,label:Y.label,count:xe,percent:Math.round(xe/ie*100)}}).filter(Y=>Y.count>0).sort((Y,xe)=>xe.count-Y.count);const Q=new Map(ee.map(Y=>[Y.id,Y.name])),A=new Map;for(const Y of N){const xe=Y.project_id?Q.get(Y.project_id)||"已删除项目":"无项目";A.set(xe,(A.get(xe)||0)+1)}o.value=Array.from(A.entries()).map(Y=>({name:Y[0],count:Y[1],percent:Math.round(Y[1]/ie*100)})).sort((Y,xe)=>xe.count-Y.count);const S=new Map;for(const Y of N)S.set(Y.date,(S.get(Y.date)||0)+1);const oe=Ts(y),ge=[];for(let Y=11;Y>=0;Y--){const xe=Kn(oe,-7*Y),Fe=[];for(let rt=0;rt<7;rt++){const We=Kn(xe,rt);Fe.push({date:We,count:S.get(We)||0})}ge.push(Fe)}n.value=ge}mn(async()=>{await c()}),vt(Ws,()=>{c()});function d(y){return y===0?0:y===1?1:y<=3?2:y<=5?3:4}function h(y,m){return y+" · "+(m?m+" 条":"无记录")}return(y,m)=>(K(),H("div",_g,[u("div",kg,[u("div",xg,[m[0]||(m[0]=u("div",{class:"muted"},"出勤天数",-1)),u("div",Cg,se(t.value.attendDays),1)]),u("div",Sg,[m[1]||(m[1]=u("div",{class:"muted"},"累计工时(小时)",-1)),u("div",Eg,se(t.value.totalHours),1)]),u("div",$g,[m[2]||(m[2]=u("div",{class:"muted"},"记录条数",-1)),u("div",Tg,se(t.value.itemCount),1)]),u("div",Pg,[m[3]||(m[3]=u("div",{class:"muted"},"连续记录(天)",-1)),u("div",Ag,se(t.value.streak),1)])]),u("div",Og,[m[4]||(m[4]=u("div",{class:"section-title"},"记录热力图(近 12 周)",-1)),u("div",Mg,[(K(!0),H(Re,null,ct(n.value,(w,C)=>(K(),H("div",{key:C,class:"heat-col"},[(K(!0),H(Re,null,ct(w,O=>(K(),H("span",{key:O.date,class:tt(["heat-cell","lv"+d(O.count)]),title:h(O.date,O.count)},null,10,Ig))),128))]))),128))]),m[5]||(m[5]=Up('
少多
',1))]),u("div",jg,[u("div",Dg,[m[6]||(m[6]=u("div",{class:"section-title"},"分类分布",-1)),(K(!0),H(Re,null,ct(s.value,w=>(K(),H("div",{key:w.key,class:"bar-row"},[u("span",Lg,se(w.label),1),u("span",Rg,[u("span",{class:"bar-fill",style:nr({width:w.percent+"%"})},null,4)]),u("span",Kg,se(w.count)+" 条 · "+se(w.percent)+"%",1)]))),128)),s.value.length?Ee("",!0):(K(),H("div",Fg,"暂无数据"))]),u("div",Ng,[m[7]||(m[7]=u("div",{class:"section-title"},"项目投入",-1)),(K(!0),H(Re,null,ct(o.value,w=>(K(),H("div",{key:w.name,class:"bar-row"},[u("span",Vg,se(w.name),1),u("span",Bg,[u("span",{class:"bar-fill",style:nr({width:w.percent+"%"})},null,4)]),u("span",Ug,se(w.count)+" 条 · "+se(w.percent)+"%",1)]))),128)),o.value.length?Ee("",!0):(K(),H("div",qg,"暂无数据"))])]),u("div",Hg,[m[8]||(m[8]=u("div",{class:"section-title"},"地点分布(按出勤天)",-1)),(K(!0),H(Re,null,ct(a.value,w=>(K(),H("div",{key:w.name,class:"bar-row"},[u("span",Wg,se(w.name),1),u("span",zg,[u("span",{class:"bar-fill",style:nr({width:w.percent+"%"})},null,4)]),u("span",Gg,se(w.count)+" 天 · "+se(w.percent)+"%",1)]))),128)),a.value.length?Ee("",!0):(K(),H("div",Yg,"暂无数据"))])]))}}),Xg=Yt(Jg,[["__scopeId","data-v-73e5ba49"]]);async function Qg(e,t,n){const s=xt(),o=await Promise.all([Dr(),_i(e,t),ki(e,t),Ns(!0),Am(e,t)]),a=o[0],c=o[1],d=o[2],h=o[3],y=o[4];let m=0,w=0,C=0;for(const A of c){(A.clock_in_at||A.kind==="makeup")&&m++,A.kind==="makeup"&&C++;const S=zs(A,A.date,a,A.date===s);w+=S.workedMinutes??0}const O=new Map;for(const A of c){if(!(A.clock_in_at||A.kind==="makeup"))continue;const S=A.location||"未记录";O.set(S,(O.get(S)||0)+1)}const N=Array.from(O.entries()).map(A=>({name:A[0],count:A[1]})).sort((A,S)=>S.count-A.count),ee=d.length||1,te=Hs.map(A=>{const S=d.filter(oe=>oe.category===A.key).length;return{key:A.key,label:A.label,count:S,percent:Math.round(S/ee*100)}}).filter(A=>A.count>0).sort((A,S)=>S.count-A.count),ue=new Map(h.map(A=>[A.id,A.name])),P=new Map;for(const A of d){const S=A.project_id?ue.get(A.project_id)||"已删除项目":"无项目";P.set(S,(P.get(S)||0)+1)}const L=Array.from(P.entries()).map(A=>({name:A[0],count:A[1]})).sort((A,S)=>S.count-A.count),J=d.filter(A=>A.is_milestone===1).map(A=>({date:A.date,content:A.content})),ce=d.filter(A=>A.needs_followup===1).map(A=>({date:A.date,content:A.content,remark:A.remark||""})),ie=d.filter(A=>!!A.takeaway).map(A=>({date:A.date,text:A.takeaway})),Q=y.map(A=>({weekStart:A.week_start,highlights:A.highlights||"",challenges:A.challenges||"",plan_next:A.plan_next||""}));return{range:{start:e,end:t,label:n},attendDays:m,totalHours:(w/60).toFixed(1),makeupCount:C,leaveCount:c.filter(A=>A.kind==="leave").length,itemCount:d.length,categoryStats:te,projectStats:L,locationStats:N,milestones:J,followups:ce,takeaways:ie,weekNotes:Q}}function Zg(e){const t=[];t.push("# 实习工作总结("+e.range.start+" ~ "+e.range.end+")"),t.push(""),t.push("## 一、考勤概况"),t.push(""),t.push("出勤 "+e.attendDays+" 天,累计工时 "+e.totalHours+" 小时,补卡 "+e.makeupCount+" 次"+(e.leaveCount?",请假 "+e.leaveCount+" 天":""));const n=e.locationStats.filter(s=>s.name!=="未记录");n.length&&t.push("其中:"+n.map(s=>s.name+" "+s.count+" 天").join(",")),t.push(""),t.push("## 二、工作内容分布"),t.push(""),t.push(e.categoryStats.length?e.categoryStats.map(s=>s.label+" "+s.percent+"%("+s.count+" 条)").join(","):"(无记录)"),t.push(""),t.push("## 三、项目投入"),t.push(""),t.push(e.projectStats.length?e.projectStats.map(s=>s.name+" "+s.count+" 条").join(","):"(无记录)"),t.push(""),t.push("## 四、主要成果"),t.push(""),e.milestones.length?e.milestones.forEach((s,o)=>t.push(o+1+". 【成果】"+s.content+"("+s.date+")")):t.push("(无)"),t.push(""),t.push("## 五、待跟进事项"),t.push(""),e.followups.length?e.followups.forEach(s=>t.push("- 【待跟进】"+s.content+(s.remark?"("+s.date+" 备注:"+s.remark+")":"("+s.date+")"))):t.push("(无)"),t.push(""),t.push("## 六、学习与成长"),t.push(""),e.takeaways.length?e.takeaways.forEach(s=>t.push("- "+s.text+"("+s.date+")")):t.push("(无)");for(const s of e.weekNotes)t.push(""),t.push("### 周记("+s.weekStart+" 起)"),t.push(""),t.push("- 本周亮点:"+(s.highlights||"(无)")),t.push("- 踩的坑:"+(s.challenges||"(无)")),t.push("- 下周计划:"+(s.plan_next||"(无)"));return t.push(""),t.join(` +`)}const eb="modulepreload",tb=function(e,t){return new URL(e,t).href},Fu={},Af=function(t,n,s){let o=Promise.resolve();if(n&&n.length>0){const c=document.getElementsByTagName("link"),d=document.querySelector("meta[property=csp-nonce]"),h=(d==null?void 0:d.nonce)||(d==null?void 0:d.getAttribute("nonce"));o=Promise.allSettled(n.map(y=>{if(y=tb(y,s),y in Fu)return;Fu[y]=!0;const m=y.endsWith(".css"),w=m?'[rel="stylesheet"]':"";if(!!s)for(let N=c.length-1;N>=0;N--){const ee=c[N];if(ee.href===y&&(!m||ee.rel==="stylesheet"))return}else if(document.querySelector(`link[href="${y}"]${w}`))return;const O=document.createElement("link");if(O.rel=m?"stylesheet":eb,m||(O.as="script"),O.crossOrigin="",O.href=y,h&&O.setAttribute("nonce",h),document.head.appendChild(O),m)return new Promise((N,ee)=>{O.addEventListener("load",N),O.addEventListener("error",()=>ee(new Error(`Unable to preload CSS for ${y}`)))})}))}function a(c){const d=new Event("vite:preloadError",{cancelable:!0});if(d.payload=c,window.dispatchEvent(d),!d.defaultPrevented)throw c}return o.then(c=>{for(const d of c||[])d.status==="rejected"&&a(d.reason);return t().catch(a)})};/*! Capacitor: https://capacitorjs.com/ - MIT License */const nb=e=>{const t=new Map;t.set("web",{name:"web"});const n=e.CapacitorPlatforms||{currentPlatform:{name:"web"},platforms:t},s=(a,c)=>{n.platforms.set(a,c)},o=a=>{n.platforms.has(a)&&(n.currentPlatform=n.platforms.get(a))};return n.addPlatform=s,n.setPlatform=o,n},rb=e=>e.CapacitorPlatforms=nb(e),Of=rb(typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:typeof global<"u"?global:{});Of.addPlatform;Of.setPlatform;var ts;(function(e){e.Unimplemented="UNIMPLEMENTED",e.Unavailable="UNAVAILABLE"})(ts||(ts={}));class va extends Error{constructor(t,n,s){super(t),this.message=t,this.code=n,this.data=s}}const sb=e=>{var t,n;return e!=null&&e.androidBridge?"android":!((n=(t=e==null?void 0:e.webkit)===null||t===void 0?void 0:t.messageHandlers)===null||n===void 0)&&n.bridge?"ios":"web"},ob=e=>{var t,n,s,o,a;const c=e.CapacitorCustomPlatform||null,d=e.Capacitor||{},h=d.Plugins=d.Plugins||{},y=e.CapacitorPlatforms,m=()=>c!==null?c.name:sb(e),w=((t=y==null?void 0:y.currentPlatform)===null||t===void 0?void 0:t.getPlatform)||m,C=()=>w()!=="web",O=((n=y==null?void 0:y.currentPlatform)===null||n===void 0?void 0:n.isNativePlatform)||C,N=Q=>{const A=J.get(Q);return!!(A!=null&&A.platforms.has(w())||ue(Q))},ee=((s=y==null?void 0:y.currentPlatform)===null||s===void 0?void 0:s.isPluginAvailable)||N,te=Q=>{var A;return(A=d.PluginHeaders)===null||A===void 0?void 0:A.find(S=>S.name===Q)},ue=((o=y==null?void 0:y.currentPlatform)===null||o===void 0?void 0:o.getPluginHeader)||te,P=Q=>e.console.error(Q),L=(Q,A,S)=>Promise.reject(`${S} does not have an implementation of "${A}".`),J=new Map,ce=(Q,A={})=>{const S=J.get(Q);if(S)return console.warn(`Capacitor plugin "${Q}" already registered. Cannot register plugins twice.`),S.proxy;const oe=w(),ge=ue(Q);let Y;const xe=async()=>(!Y&&oe in A?Y=typeof A[oe]=="function"?Y=await A[oe]():Y=A[oe]:c!==null&&!Y&&"web"in A&&(Y=typeof A.web=="function"?Y=await A.web():Y=A.web),Y),Fe=(Ne,De)=>{var Ce,X;if(ge){const Z=ge==null?void 0:ge.methods.find(ke=>De===ke.name);if(Z)return Z.rtype==="promise"?ke=>d.nativePromise(Q,De.toString(),ke):(ke,Be)=>d.nativeCallback(Q,De.toString(),ke,Be);if(Ne)return(Ce=Ne[De])===null||Ce===void 0?void 0:Ce.bind(Ne)}else{if(Ne)return(X=Ne[De])===null||X===void 0?void 0:X.bind(Ne);throw new va(`"${Q}" plugin is not implemented on ${oe}`,ts.Unimplemented)}},rt=Ne=>{let De;const Ce=(...X)=>{const Z=xe().then(ke=>{const Be=Fe(ke,Ne);if(Be){const dt=Be(...X);return De=dt==null?void 0:dt.remove,dt}else throw new va(`"${Q}.${Ne}()" is not implemented on ${oe}`,ts.Unimplemented)});return Ne==="addListener"&&(Z.remove=async()=>De()),Z};return Ce.toString=()=>`${Ne.toString()}() { [capacitor code] }`,Object.defineProperty(Ce,"name",{value:Ne,writable:!1,configurable:!1}),Ce},We=rt("addListener"),Ye=rt("removeListener"),me=(Ne,De)=>{const Ce=We({eventName:Ne},De),X=async()=>{const ke=await Ce;Ye({eventName:Ne,callbackId:ke},De)},Z=new Promise(ke=>Ce.then(()=>ke({remove:X})));return Z.remove=async()=>{console.warn("Using addListener() without 'await' is deprecated."),await X()},Z},Me=new Proxy({},{get(Ne,De){switch(De){case"$$typeof":return;case"toJSON":return()=>({});case"addListener":return ge?me:We;case"removeListener":return Ye;default:return rt(De)}}});return h[Q]=Me,J.set(Q,{name:Q,proxy:Me,platforms:new Set([...Object.keys(A),...ge?[oe]:[]])}),Me},ie=((a=y==null?void 0:y.currentPlatform)===null||a===void 0?void 0:a.registerPlugin)||ce;return d.convertFileSrc||(d.convertFileSrc=Q=>Q),d.getPlatform=w,d.handleError=P,d.isNativePlatform=O,d.isPluginAvailable=ee,d.pluginMethodNoop=L,d.registerPlugin=ie,d.Exception=va,d.DEBUG=!!d.DEBUG,d.isLoggingEnabled=!!d.isLoggingEnabled,d.platform=d.getPlatform(),d.isNative=d.isNativePlatform(),d},ib=e=>e.Capacitor=ob(e),ns=ib(typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:typeof global<"u"?global:{}),Mf=ns.registerPlugin;ns.Plugins;class If{constructor(t){this.listeners={},this.retainedEventArguments={},this.windowListeners={},t&&(console.warn(`Capacitor WebPlugin "${t.name}" config object was deprecated in v3 and will be removed in v4.`),this.config=t)}addListener(t,n){let s=!1;this.listeners[t]||(this.listeners[t]=[],s=!0),this.listeners[t].push(n);const a=this.windowListeners[t];a&&!a.registered&&this.addWindowListener(a),s&&this.sendRetainedArgumentsForEvent(t);const c=async()=>this.removeListener(t,n);return Promise.resolve({remove:c})}async removeAllListeners(){this.listeners={};for(const t in this.windowListeners)this.removeWindowListener(this.windowListeners[t]);this.windowListeners={}}notifyListeners(t,n,s){const o=this.listeners[t];if(!o){if(s){let a=this.retainedEventArguments[t];a||(a=[]),a.push(n),this.retainedEventArguments[t]=a}return}o.forEach(a=>a(n))}hasListeners(t){return!!this.listeners[t].length}registerWindowListener(t,n){this.windowListeners[n]={registered:!1,windowEventName:t,pluginEventName:n,handler:s=>{this.notifyListeners(n,s)}}}unimplemented(t="not implemented"){return new ns.Exception(t,ts.Unimplemented)}unavailable(t="not available"){return new ns.Exception(t,ts.Unavailable)}async removeListener(t,n){const s=this.listeners[t];if(!s)return;const o=s.indexOf(n);this.listeners[t].splice(o,1),this.listeners[t].length||this.removeWindowListener(this.windowListeners[t])}addWindowListener(t){window.addEventListener(t.windowEventName,t.handler),t.registered=!0}removeWindowListener(t){t&&(window.removeEventListener(t.windowEventName,t.handler),t.registered=!1)}sendRetainedArgumentsForEvent(t){const n=this.retainedEventArguments[t];n&&(delete this.retainedEventArguments[t],n.forEach(s=>{this.notifyListeners(t,s)}))}}const Nu=e=>encodeURIComponent(e).replace(/%(2[346B]|5E|60|7C)/g,decodeURIComponent).replace(/[()]/g,escape),Vu=e=>e.replace(/(%[\dA-F]{2})+/gi,decodeURIComponent);class ab extends If{async getCookies(){const t=document.cookie,n={};return t.split(";").forEach(s=>{if(s.length<=0)return;let[o,a]=s.replace(/=/,"CAP_COOKIE").split("CAP_COOKIE");o=Vu(o).trim(),a=Vu(a).trim(),n[o]=a}),n}async setCookie(t){try{const n=Nu(t.key),s=Nu(t.value),o=`; expires=${(t.expires||"").replace("expires=","")}`,a=(t.path||"/").replace("path=",""),c=t.url!=null&&t.url.length>0?`domain=${t.url}`:"";document.cookie=`${n}=${s||""}${o}; path=${a}; ${c};`}catch(n){return Promise.reject(n)}}async deleteCookie(t){try{document.cookie=`${t.key}=; Max-Age=0`}catch(n){return Promise.reject(n)}}async clearCookies(){try{const t=document.cookie.split(";")||[];for(const n of t)document.cookie=n.replace(/^ +/,"").replace(/=.*/,`=;expires=${new Date().toUTCString()};path=/`)}catch(t){return Promise.reject(t)}}async clearAllCookies(){try{await this.clearCookies()}catch(t){return Promise.reject(t)}}}Mf("CapacitorCookies",{web:()=>new ab});const lb=async e=>new Promise((t,n)=>{const s=new FileReader;s.onload=()=>{const o=s.result;t(o.indexOf(",")>=0?o.split(",")[1]:o)},s.onerror=o=>n(o),s.readAsDataURL(e)}),ub=(e={})=>{const t=Object.keys(e);return Object.keys(e).map(o=>o.toLocaleLowerCase()).reduce((o,a,c)=>(o[a]=e[t[c]],o),{})},cb=(e,t=!0)=>e?Object.entries(e).reduce((s,o)=>{const[a,c]=o;let d,h;return Array.isArray(c)?(h="",c.forEach(y=>{d=t?encodeURIComponent(y):y,h+=`${a}=${d}&`}),h.slice(0,-1)):(d=t?encodeURIComponent(c):c,h=`${a}=${d}`),`${s}&${h}`},"").substr(1):null,fb=(e,t={})=>{const n=Object.assign({method:e.method||"GET",headers:e.headers},t),o=ub(e.headers)["content-type"]||"";if(typeof e.data=="string")n.body=e.data;else if(o.includes("application/x-www-form-urlencoded")){const a=new URLSearchParams;for(const[c,d]of Object.entries(e.data||{}))a.set(c,d);n.body=a.toString()}else if(o.includes("multipart/form-data")||e.data instanceof FormData){const a=new FormData;if(e.data instanceof FormData)e.data.forEach((d,h)=>{a.append(h,d)});else for(const d of Object.keys(e.data))a.append(d,e.data[d]);n.body=a;const c=new Headers(n.headers);c.delete("content-type"),n.headers=c}else(o.includes("application/json")||typeof e.data=="object")&&(n.body=JSON.stringify(e.data));return n};class db extends If{async request(t){const n=fb(t,t.webFetchExtra),s=cb(t.params,t.shouldEncodeUrlParams),o=s?`${t.url}?${s}`:t.url,a=await fetch(o,n),c=a.headers.get("content-type")||"";let{responseType:d="text"}=a.ok?t:{};c.includes("application/json")&&(d="json");let h,y;switch(d){case"arraybuffer":case"blob":y=await a.blob(),h=await lb(y);break;case"json":h=await a.json();break;case"document":case"text":default:h=await a.text()}const m={};return a.headers.forEach((w,C)=>{m[C]=w}),{data:h,headers:m,status:a.status,url:a.url}}async get(t){return this.request(Object.assign(Object.assign({},t),{method:"GET"}))}async post(t){return this.request(Object.assign(Object.assign({},t),{method:"POST"}))}async put(t){return this.request(Object.assign(Object.assign({},t),{method:"PUT"}))}async patch(t){return this.request(Object.assign(Object.assign({},t),{method:"PATCH"}))}async delete(t){return this.request(Object.assign(Object.assign({},t),{method:"DELETE"}))}}Mf("CapacitorHttp",{web:()=>new db});async function ml(e,t){const n=window;if(n.electronAPI&&n.electronAPI.saveFile){const c=await n.electronAPI.saveFile(e,t);return c&&c.saved?c.path:""}if(ns.isNativePlatform()){const{Filesystem:c,Directory:d,Encoding:h}=await Af(async()=>{const{Filesystem:y,Directory:m,Encoding:w}=await import("./index-2zIp9hhK.js");return{Filesystem:y,Directory:m,Encoding:w}},[],import.meta.url);try{return(await c.writeFile({path:e,data:t,directory:d.Documents,encoding:h.UTF8,recursive:!0})).uri}catch{return(await c.writeFile({path:e,data:t,directory:d.Cache,encoding:h.UTF8,recursive:!0})).uri}}const s=new Blob([t],{type:"text/plain;charset=utf-8"}),o=URL.createObjectURL(s),a=document.createElement("a");return a.href=o,a.download=e,a.click(),window.setTimeout(()=>URL.revokeObjectURL(o),1e4),""}const pb=Object.freeze(Object.defineProperty({__proto__:null,downloadText:ml},Symbol.toStringTag,{value:"Module"}));async function Ua(e){try{await navigator.clipboard.writeText(e)}catch{const t=document.createElement("textarea");t.value=e,t.style.position="fixed",t.style.opacity="0",document.body.appendChild(t),t.select(),document.execCommand("copy"),document.body.removeChild(t)}}async function hb(e){const t=await Promise.all([gt("ai_base_url",""),gt("ai_api_key",""),gt("ai_model","")]),n=t[0].trim().replace(/\/+$/,""),s=t[1].trim(),o=t[2].trim();if(!n||!o)throw new Error("请先在设置页配置 AI 接口地址与模型名称");const a=n+"/chat/completions",c={"Content-Type":"application/json"};s&&(c.Authorization="Bearer "+s);const h=JSON.stringify({model:o,messages:[{role:"system",content:"你是一名严谨的中文助理。请将用户提供的工作总结 Markdown 草稿润色为通顺、专业、简洁的工作总结。要求:保留原有章节结构与全部事实数据(数字、日期、条目),不得虚构或遗漏内容,只输出 Markdown 正文。"},{role:"user",content:e}],temperature:.3});let y;try{y=await fetch(a,{method:"POST",headers:c,body:h})}catch{throw new Error("无法访问 AI 接口:请检查地址是否正确、服务端是否允许浏览器跨域访问")}if(!y.ok){let C="接口返回 "+y.status;try{const O=await y.json();O&&O.error&&O.error.message&&(C+=":"+O.error.message)}catch{}throw new Error(C)}const m=await y.json(),w=m&&m.choices&&m.choices[0]&&m.choices[0].message&&m.choices[0].message.content;if(!w)throw new Error("接口未返回内容");return String(w)}const vb={class:"report"},mb={class:"report-toolbar"},yb={class:"seg"},gb=["onClick"],bb=["disabled"],wb=["disabled"],_b={key:0,class:"ai-error"},kb={class:"report-grid"},xb={class:"report-left"},Cb={class:"card section"},Sb={class:"section-title"},Eb={class:"muted note-saved"},$b={class:"card section"},Tb={class:"report-right"},Pb={key:0,class:"card section"},Ab={class:"sum-row"},Ob={class:"num"},Mb={class:"sum-row"},Ib={class:"num"},jb={class:"sum-row"},Db={class:"num"},Lb={class:"sum-row"},Rb={class:"num"},Kb={class:"sum-row"},Fb={class:"num"},Nb={class:"muted"},Vb={class:"num"},Bb={key:0,class:"muted sum-empty"},Ub={class:"muted"},qb={key:1,class:"muted sum-empty"},Hb={class:"muted"},Wb={key:2,class:"muted sum-empty"},zb={class:"muted"},Gb={key:3,class:"muted sum-empty"},Yb=Bt({__name:"ReportView",setup(e){const t=[{key:"week",label:"本周"},{key:"month",label:"本月"},{key:"all",label:"全部"},{key:"custom",label:"自定义"}],n=F("week"),s=F(Ts(xt())),o=F(xt()),a=F(null),c=F(""),d=F(!1),h=F(!1),y=F(null),m=F(""),w=F(Ts(xt())),C=F(""),O=F(""),N=F(""),ee=F(!1);async function te(){const A=await vl(w.value);C.value=(A==null?void 0:A.highlights)||"",O.value=(A==null?void 0:A.challenges)||"",N.value=(A==null?void 0:A.plan_next)||"",ee.value=!1}async function ue(){await Pm(w.value,{highlights:C.value.trim()||null,challenges:O.value.trim()||null,plan_next:N.value.trim()||null}),ee.value=!0,await L()}function P(A){const S=xt();if(A==="week"){const oe=Ts(S);return{start:oe,end:Kn(oe,6),label:"本周"}}if(A==="month"){const oe=S.slice(0,7);return{start:oe+"-01",end:S,label:oe+" 本月"}}return A==="all"?{start:"2000-01-01",end:S,label:"全部实习期"}:{start:s.value,end:o.value,label:s.value+" ~ "+o.value}}async function L(){d.value=!0;const A=P(n.value),S=await Qg(A.start,A.end,A.label);a.value=S,c.value=Zg(S),d.value=!1}vt(n,L),vt([s,o],()=>{n.value==="custom"&&L()}),mn(async()=>{await te(),await L()});async function J(){const A=xt().replace(/-/g,""),S=await ml("实习工作总结_"+A+".md",c.value);Ue(S?"总结已导出到:"+S:"总结已导出到系统下载目录")}async function ce(){await Ua(c.value),Ue("总结已复制到剪贴板")}async function ie(){if(h.value)return;m.value="";const A=c.value.trim();if(!A){m.value="当前草稿为空,无法润色";return}h.value=!0;try{y.value=c.value,c.value=await hb(A),Ue("AI 润色完成")}catch(S){y.value=null,m.value=S instanceof Error?S.message:"润色失败"}h.value=!1}function Q(){y.value!==null&&(c.value=y.value),y.value=null}return(A,S)=>(K(),H("div",vb,[u("div",mb,[u("div",yb,[(K(),H(Re,null,ct(t,oe=>u("button",{key:oe.key,class:tt(["seg-btn",{active:n.value===oe.key}]),onClick:ge=>n.value=oe.key},se(oe.label),11,gb)),64))]),n.value==="custom"?(K(),H(Re,{key:0},[Te(u("input",{type:"date",class:"input w-date","onUpdate:modelValue":S[0]||(S[0]=oe=>s.value=oe)},null,512),[[Le,s.value]]),S[6]||(S[6]=u("span",{class:"muted"},"至",-1)),Te(u("input",{type:"date",class:"input w-date","onUpdate:modelValue":S[1]||(S[1]=oe=>o.value=oe)},null,512),[[Le,o.value]])],64)):Ee("",!0),S[10]||(S[10]=u("span",{class:"flex1"},null,-1)),u("button",{class:"btn btn-sm",disabled:h.value,onClick:ie},[Oe(ut,{name:"edit",size:14}),S[7]||(S[7]=rn("AI 润色 ",-1))],8,bb),y.value!==null?(K(),H("button",{key:1,class:"btn btn-sm",onClick:Q},"还原润色前")):Ee("",!0),u("button",{class:"btn btn-sm",disabled:d.value,onClick:L},[Oe(ut,{name:"edit",size:14}),S[8]||(S[8]=rn("重新生成 ",-1))],8,wb),u("button",{class:"btn btn-sm",onClick:ce},"复制"),u("button",{class:"btn btn-primary btn-sm",onClick:J},[Oe(ut,{name:"export",size:14}),S[9]||(S[9]=rn("导出 Markdown ",-1))])]),m.value?(K(),H("div",_b,se(m.value),1)):Ee("",!0),u("div",kb,[u("div",xb,[u("div",Cb,[u("div",Sb,"本周周记("+se(w.value)+" 起)",1),S[11]||(S[11]=u("label",{class:"note-label muted"},"本周亮点",-1)),Te(u("textarea",{class:"textarea","onUpdate:modelValue":S[2]||(S[2]=oe=>C.value=oe),placeholder:"本周最有价值的一件事",onBlur:ue},null,544),[[Le,C.value]]),S[12]||(S[12]=u("label",{class:"note-label muted"},"踩的坑",-1)),Te(u("textarea",{class:"textarea","onUpdate:modelValue":S[3]||(S[3]=oe=>O.value=oe),placeholder:"遇到的问题与教训",onBlur:ue},null,544),[[Le,O.value]]),S[13]||(S[13]=u("label",{class:"note-label muted"},"下周计划",-1)),Te(u("textarea",{class:"textarea","onUpdate:modelValue":S[4]||(S[4]=oe=>N.value=oe),placeholder:"下周准备做什么",onBlur:ue},null,544),[[Le,N.value]]),u("div",Eb,se(ee.value?"已保存":"失焦自动保存"),1)]),u("div",$b,[S[14]||(S[14]=u("div",{class:"section-title"},"总结草稿(可编辑)",-1)),Te(u("textarea",{class:"textarea md-editor","onUpdate:modelValue":S[5]||(S[5]=oe=>c.value=oe),spellcheck:"false"},null,512),[[Le,c.value]])])]),u("div",Tb,[a.value?(K(),H("div",Pb,[S[20]||(S[20]=u("div",{class:"section-title"},"数据摘要",-1)),u("div",Ab,[S[15]||(S[15]=u("span",{class:"muted"},"出勤",-1)),u("span",Ob,se(a.value.attendDays)+" 天",1)]),u("div",Mb,[S[16]||(S[16]=u("span",{class:"muted"},"工时",-1)),u("span",Ib,se(a.value.totalHours)+" 小时",1)]),u("div",jb,[S[17]||(S[17]=u("span",{class:"muted"},"补卡",-1)),u("span",Db,se(a.value.makeupCount)+" 次",1)]),u("div",Lb,[S[18]||(S[18]=u("span",{class:"muted"},"请假",-1)),u("span",Rb,se(a.value.leaveCount)+" 天",1)]),u("div",Kb,[S[19]||(S[19]=u("span",{class:"muted"},"记录",-1)),u("span",Fb,se(a.value.itemCount)+" 条",1)]),S[21]||(S[21]=u("div",{class:"section-sub"},"分类分布",-1)),(K(!0),H(Re,null,ct(a.value.categoryStats,oe=>(K(),H("div",{key:oe.key,class:"sum-row"},[u("span",Nb,se(oe.label),1),u("span",Vb,se(oe.count)+" 条 · "+se(oe.percent)+"%",1)]))),128)),a.value.categoryStats.length?Ee("",!0):(K(),H("div",Bb,"(无)")),S[22]||(S[22]=u("div",{class:"section-sub"},"主要成果",-1)),(K(!0),H(Re,null,ct(a.value.milestones,(oe,ge)=>(K(),H("div",{key:"m"+ge,class:"sum-item"},[rn(se(oe.content),1),u("span",Ub,"("+se(oe.date)+")",1)]))),128)),a.value.milestones.length?Ee("",!0):(K(),H("div",qb,"(无)")),S[23]||(S[23]=u("div",{class:"section-sub"},"待跟进",-1)),(K(!0),H(Re,null,ct(a.value.followups,(oe,ge)=>(K(),H("div",{key:"f"+ge,class:"sum-item"},[rn(se(oe.content),1),u("span",Hb,"("+se(oe.date)+")",1)]))),128)),a.value.followups.length?Ee("",!0):(K(),H("div",Wb,"(无)")),S[24]||(S[24]=u("div",{class:"section-sub"},"学习与成长",-1)),(K(!0),H(Re,null,ct(a.value.takeaways,(oe,ge)=>(K(),H("div",{key:"t"+ge,class:"sum-item"},[rn(se(oe.text),1),u("span",zb,"("+se(oe.date)+")",1)]))),128)),a.value.takeaways.length?Ee("",!0):(K(),H("div",Gb,"(无)"))])):Ee("",!0)])])]))}}),Jb=Yt(Yb,[["__scopeId","data-v-43f9c59b"]]),Xb=["aria-label"],Qb={class:"dialog-head"},Zb={class:"dialog-title"},ew={class:"dialog-body"},tw={class:"form-grid"},nw={class:"field span2"},rw={class:"seg"},sw={class:"field"},ow={class:"field"},iw={class:"field"},aw=["value"],lw={key:0,class:"field"},uw={class:"seg"},cw={class:"field span2"},fw={key:0,class:"form-error"},dw={class:"dialog-btns"},pw=Bt({__name:"TransactionDialog",props:{open:{type:Boolean},title:{},initial:{}},emits:["cancel","save"],setup(e,{emit:t}){const n=e,s=t,o=F("expense"),a=F("餐饮"),c=F(""),d=F(""),h=F(""),y=F(!1),m=F(!1),w=F(""),C=F(null);function O(ue){n.open&&ue.key==="Escape"&&s("cancel")}vt(()=>n.open,async ue=>{var P;ue?(o.value=n.initial.type==="income"?"income":"expense",a.value=n.initial.category,c.value=n.initial.amountYuan,d.value=n.initial.date,h.value=n.initial.note,y.value=n.initial.reimbursable===1,m.value=n.initial.reimbursed===1,w.value="",window.addEventListener("keydown",O),await rs(),(P=C.value)==null||P.focus()):window.removeEventListener("keydown",O)}),fr(()=>window.removeEventListener("keydown",O)),vt(o,ue=>{a.value=ue==="expense"?zr[0]:Jo[0]});const N=at(()=>o.value==="expense"?zr:Jo);function ee(){return a.value&&N.value.includes(a.value)?a.value:N.value[0]}function te(){const ue=String(c.value??"").trim(),P=Number(ue);if(!ue||!isFinite(P)||P<=0){w.value="请填写大于 0 的金额";return}if(!d.value){w.value="请选择日期";return}const L=o.value==="expense"&&y.value?1:0;s("save",{type:o.value,category:ee(),amount:Math.round(P*100),date:d.value,note:String(h.value??"").trim(),reimbursable:L,reimbursed:L&&m.value?1:0})}return(ue,P)=>(K(),It(Us,{to:"body"},[Oe(ss,{name:"modal"},{default:cr(()=>[e.open?(K(),H("div",{key:0,class:"mask",onClick:P[11]||(P[11]=Ir(L=>s("cancel"),["self"]))},[u("div",{class:"dialog",role:"dialog","aria-label":e.title},[u("div",Qb,[u("span",Zb,se(e.title),1),u("button",{class:"icon-btn",title:"关闭",onClick:P[0]||(P[0]=L=>s("cancel"))},[Oe(ut,{name:"close",size:16})])]),u("div",ew,[u("div",tw,[u("div",nw,[P[12]||(P[12]=u("label",null,"类型",-1)),u("div",rw,[u("button",{class:tt(["seg-btn",{active:o.value==="expense"}]),onClick:P[1]||(P[1]=L=>o.value="expense")},"支出",2),u("button",{class:tt(["seg-btn",{active:o.value==="income"}]),onClick:P[2]||(P[2]=L=>o.value="income")},"收入",2)])]),u("div",sw,[P[13]||(P[13]=u("label",null,"金额(元,必填)",-1)),Te(u("input",{ref_key:"amountInput",ref:C,class:tt(["input",{invalid:w.value}]),"onUpdate:modelValue":P[3]||(P[3]=L=>c.value=L),type:"number",min:"0",step:"0.01",placeholder:"0.00"},null,2),[[Le,c.value]])]),u("div",ow,[P[14]||(P[14]=u("label",null,"日期(必填)",-1)),Te(u("input",{class:"input",type:"date","onUpdate:modelValue":P[4]||(P[4]=L=>d.value=L)},null,512),[[Le,d.value]])]),u("div",iw,[P[15]||(P[15]=u("label",null,"分类",-1)),Te(u("select",{class:"select","onUpdate:modelValue":P[5]||(P[5]=L=>a.value=L)},[(K(!0),H(Re,null,ct(N.value,L=>(K(),H("option",{key:L,value:L},se(L),9,aw))),128))],512),[[Fn,a.value]])]),o.value==="expense"?(K(),H("div",lw,[P[16]||(P[16]=u("label",null,"报销状态",-1)),u("div",uw,[u("button",{class:tt(["seg-btn",{active:!y.value}]),onClick:P[6]||(P[6]=L=>{y.value=!1,m.value=!1})},"无需报销",2),u("button",{class:tt(["seg-btn",{active:y.value&&!m.value}]),onClick:P[7]||(P[7]=L=>{y.value=!0,m.value=!1})},"待报销",2),u("button",{class:tt(["seg-btn",{active:y.value&&m.value}]),onClick:P[8]||(P[8]=L=>{y.value=!0,m.value=!0})},"已报销",2)])])):Ee("",!0),u("div",cw,[P[17]||(P[17]=u("label",null,"备注",-1)),Te(u("textarea",{class:"textarea","onUpdate:modelValue":P[9]||(P[9]=L=>h.value=L),placeholder:"选填"},null,512),[[Le,h.value]])])]),w.value?(K(),H("div",fw,se(w.value),1)):Ee("",!0)]),u("div",dw,[u("button",{class:"btn btn-sm",onClick:P[10]||(P[10]=L=>s("cancel"))},"取消"),u("button",{class:"btn btn-primary btn-sm",onClick:te},"保存")])],8,Xb)])):Ee("",!0)]),_:1})]))}}),hw=Yt(pw,[["__scopeId","data-v-edca3327"]]),vw={class:"ledger-page"},mw={class:"ledger-toolbar"},yw={class:"month-title num"},gw={class:"cards"},bw={class:"card stat-card"},ww={class:"stat-num num amt-income"},_w={class:"card stat-card"},kw={class:"stat-num num"},xw={class:"card stat-card"},Cw={class:"card stat-card"},Sw={class:"stat-num num amt-warn"},Ew={class:"card sec"},$w={class:"form-grid"},Tw={class:"field span2"},Pw={class:"seg"},Aw={class:"field"},Ow={class:"field"},Mw={class:"field"},Iw=["value"],jw={key:0,class:"field"},Dw={class:"field span2"},Lw={key:0,class:"form-error"},Rw={class:"form-footer"},Kw=["disabled"],Fw=["disabled"],Nw={key:0,class:"card sec"},Vw={class:"bar-label"},Bw={class:"bar-track"},Uw={class:"muted num bar-num"},qw={key:1,class:"card section"},Hw={class:"form-error"},Ww={class:"card table-card"},zw={class:"tx-table"},Gw={class:"num"},Yw={class:"tag"},Jw={class:"td-note"},Xw={key:0,class:"muted"},Qw={key:1,class:"tx-done"},Zw={key:2,class:"tx-pending"},e_={class:"ops"},t_=["onClick"],n_=["onClick"],r_=["onClick"],s_={key:0},o_={class:"muted vault-note num"},i_=Bt({__name:"LedgerView",setup(e){const t=F(xt()),n=F([]),s=F(!0),o=F("expense"),a=F(""),c=F(zr[0]),d=F(xt()),h=F(""),y=F(!1),m=F(""),w=F(""),C=F(!1),O=F(!1),N=F(null),ee=F({type:"expense",category:zr[0],amountYuan:"",date:xt(),note:"",reimbursable:0,reimbursed:0}),te=F(null),ue=at(()=>t.value.slice(0,7)+"-01"),P=at(()=>{const X=Number(t.value.slice(0,4)),Z=Number(t.value.slice(5,7))-1,ke=new Date(X,Z+1,0).getDate();return t.value.slice(0,7)+"-"+(ke<10?"0"+ke:String(ke))}),L=at(()=>Number(t.value.slice(0,4))+" 年 "+Number(t.value.slice(5,7))+" 月");async function J(){s.value=!0;try{n.value=await Rm(ue.value,P.value),w.value=""}catch(X){w.value="账目加载失败:"+(X instanceof Error?X.stack||X.message:String(X)),Ue("账目加载失败")}s.value=!1}mn(J),vt(t,J),vt(o,X=>{c.value=X==="expense"?zr[0]:Jo[0]});const ce=at(()=>n.value.slice().sort((X,Z)=>X.date===Z.date?Z.id-X.id:X.date{let X=0,Z=0,ke=0;for(const Be of n.value)Be.type==="income"?X+=Be.amount:(Z+=Be.amount,Be.reimbursable===1&&Be.reimbursed!==1&&(ke+=Be.amount));return{income:X,expense:Z,pending:ke,balance:X-Z}}),Q=F("all"),A=F("all"),S=at(()=>ce.value.filter(X=>!(Q.value!=="all"&&X.type!==Q.value||A.value==="pending"&&!(X.type==="expense"&&X.reimbursable===1&&X.reimbursed!==1)||A.value==="done"&&!(X.reimbursable===1&&X.reimbursed===1)))),oe=at(()=>{const X=new Map;let Z=0;for(const Be of n.value)Be.type==="expense"&&(X.set(Be.category,(X.get(Be.category)||0)+Be.amount),Z+=Be.amount);const ke=Z||1;return Array.from(X.entries()).map(Be=>({name:Be[0],amount:Be[1],percent:Math.round(Be[1]/ke*100)})).sort((Be,dt)=>dt.amount-Be.amount)});function ge(X){return(X/100).toFixed(2)}function Y(X){return(X.type==="income"?"+":"-")+ge(X.amount)}function xe(){t.value=Xo(t.value,-1)}function Fe(){t.value=Xo(t.value,1)}function rt(){t.value=xt()}vt(a,()=>{m.value&&(m.value="")});async function We(){const X=String(a.value??"").trim(),Z=Number(X);if(!X||!isFinite(Z)||Z<=0){m.value="请填写大于 0 的金额";return}if(!d.value){m.value="请选择日期";return}if(!C.value){C.value=!0;try{await Km({type:o.value,category:c.value,amount:Math.round(Z*100),date:d.value,note:String(h.value??"").trim(),reimbursable:o.value==="expense"&&y.value?1:0,reimbursed:0})}catch(ke){Ue("添加失败:"+(ke instanceof Error?ke.message:String(ke))),C.value=!1;return}a.value="",h.value="",y.value=!1,m.value="",await J(),Ue("记账已添加"),C.value=!1}}const Ye=at(()=>String(a.value??"").trim()!==""||String(h.value??"").trim()!=="");function me(){a.value="",h.value="",y.value=!1,m.value=""}async function Me(X){await Vm(X.id),await J(),Ue("已标记为已报销")}function Ne(X){N.value=X.id,ee.value={type:X.type,category:X.category,amountYuan:ge(X.amount),date:X.date,note:X.note||"",reimbursable:X.reimbursable,reimbursed:X.reimbursed},O.value=!0}async function De(X){const Z=N.value;await Fm(Z,X),O.value=!1,await J(),Ue("账目已更新")}async function Ce(){te.value&&te.value.id&&await Nm(te.value.id),te.value=null,await J(),Ue("账目已删除")}return(X,Z)=>(K(),H("div",vw,[u("div",mw,[u("button",{class:"icon-btn",onClick:xe},[Oe(ut,{name:"chevron-left",size:16})]),u("span",yw,se(L.value),1),u("button",{class:"icon-btn",onClick:Fe},[Oe(ut,{name:"chevron-right",size:16})]),u("button",{class:"btn btn-sm",onClick:rt},"回到本月"),Z[13]||(Z[13]=u("span",{class:"flex1"},null,-1)),Te(u("select",{class:"select w-filter","onUpdate:modelValue":Z[0]||(Z[0]=ke=>Q.value=ke)},[...Z[11]||(Z[11]=[u("option",{value:"all"},"全部类型",-1),u("option",{value:"expense"},"仅支出",-1),u("option",{value:"income"},"仅收入",-1)])],512),[[Fn,Q.value]]),Te(u("select",{class:"select w-filter","onUpdate:modelValue":Z[1]||(Z[1]=ke=>A.value=ke)},[...Z[12]||(Z[12]=[u("option",{value:"all"},"全部报销",-1),u("option",{value:"pending"},"待报销",-1),u("option",{value:"done"},"已报销",-1)])],512),[[Fn,A.value]])]),u("div",gw,[u("div",bw,[Z[14]||(Z[14]=u("div",{class:"muted"},"本月收入(元)",-1)),u("div",ww,se(ge(ie.value.income)),1)]),u("div",_w,[Z[15]||(Z[15]=u("div",{class:"muted"},"本月支出(元)",-1)),u("div",kw,se(ge(ie.value.expense)),1)]),u("div",xw,[Z[16]||(Z[16]=u("div",{class:"muted"},"本月结余(元)",-1)),u("div",{class:tt(["stat-num num",{"amt-income":ie.value.balance>=0,"amt-expense":ie.value.balance<0}])},se(ge(ie.value.balance)),3)]),u("div",Cw,[Z[17]||(Z[17]=u("div",{class:"muted"},"待报销(元)",-1)),u("div",Sw,se(ge(ie.value.pending)),1)])]),u("div",Ew,[Z[24]||(Z[24]=u("div",{class:"sec-head"},[u("span",{class:"sec-title"},"新增一笔"),u("span",{class:"muted form-hint"},"金额必填,回车快速添加")],-1)),u("div",$w,[u("div",Tw,[Z[18]||(Z[18]=u("label",null,"类型",-1)),u("div",Pw,[u("button",{class:tt(["seg-btn",{active:o.value==="expense"}]),onClick:Z[2]||(Z[2]=ke=>o.value="expense")},"支出",2),u("button",{class:tt(["seg-btn",{active:o.value==="income"}]),onClick:Z[3]||(Z[3]=ke=>o.value="income")},"收入",2)])]),u("div",Aw,[Z[19]||(Z[19]=u("label",null,"金额(元,必填)",-1)),Te(u("input",{class:tt(["input",{invalid:m.value}]),"onUpdate:modelValue":Z[4]||(Z[4]=ke=>a.value=ke),type:"number",min:"0",step:"0.01",placeholder:"0.00",onKeydown:Dt(We,["enter"])},null,34),[[Le,a.value]])]),u("div",Ow,[Z[20]||(Z[20]=u("label",null,"日期",-1)),Te(u("input",{class:"input",type:"date","onUpdate:modelValue":Z[5]||(Z[5]=ke=>d.value=ke)},null,512),[[Le,d.value]])]),u("div",Mw,[Z[21]||(Z[21]=u("label",null,"分类",-1)),Te(u("select",{class:"select","onUpdate:modelValue":Z[6]||(Z[6]=ke=>c.value=ke)},[(K(!0),H(Re,null,ct(o.value==="expense"?Zt(zr):Zt(Jo),ke=>(K(),H("option",{key:ke,value:ke},se(ke),9,Iw))),128))],512),[[Fn,c.value]])]),o.value==="expense"?(K(),H("div",jw,[Z[22]||(Z[22]=u("label",null,"报销",-1)),u("button",{class:tt(["toggle-btn",{on:y.value}]),onClick:Z[7]||(Z[7]=ke=>y.value=!y.value)},se(y.value?"需要报销":"无需报销"),3)])):Ee("",!0),u("div",Dw,[Z[23]||(Z[23]=u("label",null,"备注",-1)),Te(u("input",{class:"input","onUpdate:modelValue":Z[8]||(Z[8]=ke=>h.value=ke),placeholder:"选填,如:客户现场午餐",onKeydown:Dt(We,["enter"])},null,544),[[Le,h.value]])])]),m.value?(K(),H("div",Lw,se(m.value),1)):Ee("",!0),u("div",Rw,[u("button",{class:"btn btn-sm",disabled:!Ye.value,onClick:me},"重置",8,Kw),u("button",{class:"btn btn-primary btn-sm",disabled:C.value,onClick:We},"添加记录",8,Fw)])]),oe.value.length?(K(),H("div",Nw,[Z[25]||(Z[25]=u("div",{class:"sec-title"},"本月支出分类",-1)),(K(!0),H(Re,null,ct(oe.value,ke=>(K(),H("div",{key:ke.name,class:"bar-row"},[u("span",Vw,se(ke.name),1),u("span",Bw,[u("span",{class:"bar-fill",style:nr({width:ke.percent+"%"})},null,4)]),u("span",Uw,se(ge(ke.amount))+" 元 · "+se(ke.percent)+"%",1)]))),128))])):Ee("",!0),w.value?(K(),H("div",qw,[u("div",Hw,se(w.value),1),Z[26]||(Z[26]=u("div",{class:"muted loc-note"},"请将上方完整错误文字发送给开发者",-1))])):Ee("",!0),u("div",Ww,[u("table",zw,[Z[28]||(Z[28]=u("thead",null,[u("tr",null,[u("th",null,"日期"),u("th",null,"分类"),u("th",null,"金额(元)"),u("th",null,"备注"),u("th",null,"报销"),u("th",{class:"th-ops"},"操作")])],-1)),u("tbody",null,[(K(!0),H(Re,null,ct(S.value,ke=>(K(),H("tr",{key:ke.id},[u("td",Gw,se(ke.date),1),u("td",null,[u("span",Yw,se(ke.category),1)]),u("td",{class:tt(["num",ke.type==="income"?"amt-income":"amt-expense"])},se(Y(ke)),3),u("td",Jw,se(ke.note||"--"),1),u("td",null,[ke.type!=="expense"||ke.reimbursable!==1?(K(),H("span",Xw,"--")):ke.reimbursed===1?(K(),H("span",Qw,"已报销")):(K(),H("span",Zw,"待报销"))]),u("td",null,[u("div",e_,[ke.type==="expense"&&ke.reimbursable===1&&ke.reimbursed!==1?(K(),H("button",{key:0,class:"btn btn-xs",onClick:Be=>Me(ke)},"标记已报销",8,t_)):Ee("",!0),u("button",{class:"btn btn-xs",onClick:Be=>Ne(ke)},"编辑",8,n_),u("button",{class:"btn btn-xs",onClick:Be=>te.value=ke},"删除",8,r_)])])]))),128)),!S.value.length&&!s.value?(K(),H("tr",s_,[...Z[27]||(Z[27]=[u("td",{colspan:"6",class:"empty muted"},"本月暂无账目",-1)])])):Ee("",!0)])])]),u("div",o_,"筛选结果 "+se(S.value.length)+" 条 / 本月共 "+se(n.value.length)+" 条",1),Oe(hw,{open:O.value,title:(N.value,"编辑账目"),initial:ee.value,onCancel:Z[9]||(Z[9]=ke=>O.value=!1),onSave:De},null,8,["open","title","initial"]),Oe(lr,{open:!!te.value,title:"删除确认",message:te.value?"将删除 "+te.value.date+" 的账目("+te.value.category+" "+ge(te.value.amount)+" 元)。删除后不可恢复。":"","confirm-text":"删除",danger:"",onCancel:Z[10]||(Z[10]=ke=>te.value=null),onConfirm:Ce},null,8,["open","message"])]))}}),a_=Yt(i_,[["__scopeId","data-v-0f950d19"]]),l_={class:"memo-page"},u_={class:"card memo-list"},c_={class:"pane-head"},f_={class:"pane-title"},d_={class:"memo-scroll"},p_=["onClick"],h_={class:"memo-item-title"},v_={class:"muted memo-item-sub"},m_={class:"muted num memo-item-time"},y_={key:0,class:"muted empty"},g_={class:"card memo-editor"},b_={class:"editor-foot"},w_={class:"muted foot-info"},__=["disabled"],k_=["disabled"],x_={key:1,class:"empty muted editor-empty"},C_=Bt({__name:"MemoView",setup(e){const t=F([]),n=F(null),s=F(!1),o=F(""),a=F(""),c=F(null),d=F(null);async function h(){if(t.value=await Om(),n.value&&n.value.id){const ie=t.value.find(Q=>Q.id===n.value.id);ie&&(n.value=ie)}}mn(async()=>{await h(),t.value.length&&w(t.value[0]),window.addEventListener("keydown",y)}),fr(()=>window.removeEventListener("keydown",y)),vt(Ka,async ie=>{if(!ie)return;t.value.length||await h();const Q=t.value.find(A=>A.id===ie);Ka.value=null,Q&&C(Q)},{immediate:!0});function y(ie){(ie.ctrlKey||ie.metaKey)&&ie.key.toLowerCase()==="s"&&s.value&&m.value&&(ie.preventDefault(),te())}const m=at(()=>{if(!s.value)return!1;const ie=n.value?n.value.title:"",Q=n.value?n.value.content:"";return o.value!==ie||a.value!==Q});function w(ie){n.value=ie,s.value=!0,o.value=ie.title,a.value=ie.content}function C(ie){if(!(s.value&&n.value&&n.value.id===ie.id)){if(m.value){d.value={type:"select",memo:ie};return}w(ie)}}function O(){if(m.value){d.value={type:"new"};return}N()}function N(){n.value=null,s.value=!0,o.value="",a.value=""}function ee(){n.value?w(n.value):N()}async function te(){if(!o.value.trim()&&!a.value.trim()){Ue("标题与内容不能都为空");return}if(n.value&&n.value.id)await Im(n.value.id,o.value,a.value),Ue("备忘已保存");else{const ie=await Mm(o.value,a.value);n.value=ie,o.value=ie.title,a.value=ie.content,Ue("备忘已创建")}await h()}function ue(){n.value&&n.value.id&&(c.value=n.value)}async function P(){c.value&&c.value.id&&(await jm(c.value.id),Ue("备忘已删除")),c.value=null,await h(),N()}function L(){const ie=d.value;d.value=null,ie&&(ie.type==="select"?w(ie.memo):N())}function J(ie){return(ie.content||"").replace(/\s+/g," ").slice(0,30)}function ce(ie){return ie.replace("T"," ").slice(0,16)}return(ie,Q)=>(K(),H("div",l_,[u("aside",u_,[u("div",c_,[u("span",f_,"备忘录("+se(t.value.length)+")",1),u("button",{class:"btn btn-primary btn-sm",onClick:O},"新建")]),u("div",d_,[(K(!0),H(Re,null,ct(t.value,A=>(K(),H("div",{key:A.id,class:tt(["memo-item",{active:s.value&&n.value&&n.value.id===A.id}]),onClick:S=>C(A)},[u("div",h_,se(A.title||"无标题"),1),u("div",v_,se(J(A)||"空"),1),u("div",m_,se(ce(A.updated_at)),1)],10,p_))),128)),t.value.length?Ee("",!0):(K(),H("div",y_,"暂无备忘"))])]),u("section",g_,[s.value?(K(),H(Re,{key:0},[Te(u("input",{class:"input title-input","onUpdate:modelValue":Q[0]||(Q[0]=A=>o.value=A),placeholder:"标题"},null,512),[[Le,o.value]]),Te(u("textarea",{class:"textarea content-textarea","onUpdate:modelValue":Q[1]||(Q[1]=A=>a.value=A),placeholder:"内容"},null,512),[[Le,a.value]]),u("div",b_,[u("span",w_,[m.value?(K(),H(Re,{key:0},[rn("有未保存修改")],64)):n.value&&n.value.id?(K(),H(Re,{key:1},[rn("更新于 "+se(ce(n.value.updated_at)),1)],64)):(K(),H(Re,{key:2},[rn("新备忘")],64))]),Q[4]||(Q[4]=u("span",{class:"flex1"},null,-1)),n.value&&n.value.id?(K(),H("button",{key:0,class:"btn btn-sm",onClick:ue},"删除")):Ee("",!0),u("button",{class:"btn btn-sm",disabled:!m.value,onClick:ee},"放弃修改",8,__),u("button",{class:"btn btn-primary btn-sm",disabled:!m.value,onClick:te},"保存",8,k_)])],64)):(K(),H("div",x_,"选择左侧备忘,或点击右上角新建"))]),Oe(lr,{open:!!c.value,title:"删除确认",message:c.value?"将删除备忘「"+(c.value.title||"无标题")+"」。删除后不可恢复。":"","confirm-text":"删除",danger:"",onCancel:Q[2]||(Q[2]=A=>c.value=null),onConfirm:P},null,8,["open","message"]),Oe(lr,{open:!!d.value,title:"未保存提示",message:"当前备忘有未保存的修改,继续操作将丢失这些修改。","confirm-text":"放弃修改并继续",onCancel:Q[3]||(Q[3]=A=>d.value=null),onConfirm:L},null,8,["open"])]))}}),S_=Yt(C_,[["__scopeId","data-v-74d60dba"]]),E_=["aria-label"],$_={class:"dialog-head"},T_={class:"dialog-title"},P_={class:"dialog-body"},A_={class:"form-grid"},O_={class:"field span2"},M_={class:"field span2"},I_={class:"field span2"},j_={class:"pwd-row"},D_={class:"field span2"},L_={key:0,class:"form-error"},R_={class:"dialog-btns"},K_=Bt({__name:"CredentialDialog",props:{open:{type:Boolean},title:{},initial:{}},emits:["cancel","save"],setup(e,{emit:t}){const n=e,s=t,o=F(""),a=F(""),c=F(""),d=F(""),h=F(""),y=F(null);function m(O){n.open&&O.key==="Escape"&&s("cancel")}vt(()=>n.open,async O=>{var N;O?(o.value=n.initial.system,a.value=n.initial.account,c.value=n.initial.password,d.value=n.initial.remark,h.value="",window.addEventListener("keydown",m),await rs(),(N=y.value)==null||N.focus()):window.removeEventListener("keydown",m)}),fr(()=>window.removeEventListener("keydown",m));function w(){const O="ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz23456789",N="!@#$%^&*",ee=crypto.getRandomValues(new Uint8Array(14));let te="";for(let ue=0;ue(K(),It(Us,{to:"body"},[Oe(ss,{name:"modal"},{default:cr(()=>[e.open?(K(),H("div",{key:0,class:"mask",onClick:N[6]||(N[6]=Ir(ee=>s("cancel"),["self"]))},[u("div",{class:"dialog",role:"dialog","aria-label":e.title},[u("div",$_,[u("span",T_,se(e.title),1),u("button",{class:"icon-btn",title:"关闭",onClick:N[0]||(N[0]=ee=>s("cancel"))},[Oe(ut,{name:"close",size:16})])]),u("div",P_,[u("div",A_,[u("div",O_,[N[7]||(N[7]=u("label",null,"系统名称(必填)",-1)),Te(u("input",{ref_key:"systemInput",ref:y,class:"input","onUpdate:modelValue":N[1]||(N[1]=ee=>o.value=ee),placeholder:"如:企业邮箱 / OA / VPN"},null,512),[[Le,o.value]])]),u("div",M_,[N[8]||(N[8]=u("label",null,"账号(必填)",-1)),Te(u("input",{class:"input","onUpdate:modelValue":N[2]||(N[2]=ee=>a.value=ee),placeholder:"用户名、工号或邮箱"},null,512),[[Le,a.value]])]),u("div",I_,[N[9]||(N[9]=u("label",null,"密码(必填)",-1)),u("div",j_,[Te(u("input",{class:"input","onUpdate:modelValue":N[3]||(N[3]=ee=>c.value=ee),placeholder:"输入或点击生成"},null,512),[[Le,c.value]]),u("button",{class:"btn btn-sm",onClick:w},"生成")])]),u("div",D_,[N[10]||(N[10]=u("label",null,"备注",-1)),Te(u("textarea",{class:"textarea","onUpdate:modelValue":N[4]||(N[4]=ee=>d.value=ee),placeholder:"用途、到期时间、负责人等(选填)"},null,512),[[Le,d.value]])])]),h.value?(K(),H("div",L_,se(h.value),1)):Ee("",!0)]),u("div",R_,[u("button",{class:"btn btn-sm",onClick:N[5]||(N[5]=ee=>s("cancel"))},"取消"),u("button",{class:"btn btn-primary btn-sm",onClick:C},"保存")])],8,E_)])):Ee("",!0)]),_:1})]))}}),F_=Yt(K_,[["__scopeId","data-v-f383b0a6"]]),N_={class:"vault-page"},V_={key:0,class:"empty muted"},B_={key:1,class:"card lock-card"},U_={class:"lock-badge"},q_={key:0,class:"form-error"},H_=["disabled"],W_={key:0,class:"form-error"},z_=["disabled"],G_={class:"vault-toolbar"},Y_={class:"search-wrap"},J_={class:"card table-card"},X_={class:"cred-table"},Q_={class:"td-system"},Z_=["onClick"],e1={class:"pwd-cell"},t1={class:"num pwd-text"},n1=["onClick"],r1=["onClick"],s1={class:"td-remark"},o1={class:"ops"},i1=["onClick"],a1=["onClick"],l1={key:0},u1={class:"muted vault-note num"},c1={class:"dialog pwd-dialog"},f1={class:"dialog-head"},d1={class:"dialog-body"},p1={class:"vp-field"},h1={class:"vp-field"},v1={class:"vp-field"},m1={key:0,class:"form-error"},y1={class:"dialog-btns"},g1=5*60*1e3,b1=Bt({__name:"VaultView",setup(e){const t=F(null),n=F(Ev()),s=F(!1),o=F(""),a=F(""),c=F(""),d=F(""),h=F(""),y=F([]),m=F(""),w=F({}),C=F(!1),O=F(null),N=F({system:"",account:"",password:"",remark:""}),ee=F(null),te=F(!1),ue=F(""),P=F(""),L=F(""),J=F("");async function ce(){y.value=await Ov(),w.value={}}let ie=null;function Q(){ie!==null&&window.clearTimeout(ie),ie=window.setTimeout(()=>{n.value&&(ei(),n.value=!1,y.value=[],w.value={},Ue("长时间未操作,密码库已自动锁定"))},g1)}function A(){n.value&&Q()}mn(async()=>{t.value=await ff(),window.addEventListener("click",A),window.addEventListener("keydown",A),n.value&&Q()}),fr(()=>{window.removeEventListener("click",A),window.removeEventListener("keydown",A),ie!==null&&window.clearTimeout(ie)});const S=at(()=>{const Ce=m.value.trim().toLowerCase();return Ce?y.value.filter(X=>(X.system+" "+X.account+" "+(X.remark||"")).toLowerCase().includes(Ce)):y.value});async function oe(){if(!s.value){if(c.value="",!o.value){c.value="请输入主密码";return}if(o.value.length<6){c.value="主密码至少 6 位";return}if(o.value!==a.value){c.value="两次输入的主密码不一致";return}s.value=!0;try{await $v(o.value),o.value="",a.value="",n.value=!0,Q(),await ce(),Ue("主密码已设置,密码库已解锁")}catch(Ce){c.value=Ce instanceof Error?Ce.message:"设置失败"}s.value=!1}}async function ge(){if(!s.value){if(h.value="",!d.value){h.value="请输入主密码";return}s.value=!0;try{await Tv(d.value),d.value="",n.value=!0,Q(),await ce()}catch(Ce){h.value=Ce instanceof Error?Ce.message:"解锁失败"}s.value=!1}}function Y(){ei(),n.value=!1,y.value=[],w.value={},ie!==null&&window.clearTimeout(ie),Ue("密码库已锁定")}async function xe(Ce){const X=Ce.id;if(w.value[X]){w.value[X]=!1;return}try{Ce.passwordPlain=await pa(X),w.value[X]=!0}catch(Z){Ue(Z instanceof Error?Z.message:"解密失败")}}async function Fe(Ce){try{const X=await pa(Ce.id);await Ua(X),Ue("密码已复制")}catch(X){Ue(X instanceof Error?X.message:"复制失败")}}async function rt(Ce){await Ua(Ce.account),Ue("账号已复制")}function We(){O.value=null,N.value={system:"",account:"",password:"",remark:""},C.value=!0}async function Ye(Ce){try{const X=await pa(Ce.id);O.value=Ce.id,N.value={system:Ce.system,account:Ce.account,password:X,remark:Ce.remark||""},C.value=!0}catch(X){Ue(X instanceof Error?X.message:"解密失败")}}async function me(Ce){const X=O.value??void 0;await Mv(Ce,X),C.value=!1,await ce(),Ue(X?"账号已更新":"账号已添加")}async function Me(){ee.value&&ee.value.id&&(await Iv(ee.value.id),Ue("账号已删除")),ee.value=null,await ce()}function Ne(){ue.value="",P.value="",L.value="",J.value="",te.value=!0}async function De(){J.value="";try{const Ce=await jv(ue.value,P.value);te.value=!1,ue.value="",P.value="",L.value="",Ue("主密码已修改,"+Ce+" 条账号密码已重新加密")}catch(Ce){J.value=Ce instanceof Error?Ce.message:"修改失败"}}return(Ce,X)=>(K(),H("div",N_,[t.value===null?(K(),H("div",V_,"加载中")):n.value?(K(),H(Re,{key:2},[u("div",G_,[u("div",Y_,[Oe(ut,{name:"search",size:14,class:"search-icon"}),Te(u("input",{class:"input","onUpdate:modelValue":X[3]||(X[3]=Z=>m.value=Z),placeholder:"搜索系统名称、账号或备注"},null,512),[[Le,m.value]])]),X[16]||(X[16]=u("span",{class:"flex1"},null,-1)),u("button",{class:"btn btn-sm",onClick:Ne},"修改主密码"),u("button",{class:"btn btn-sm",onClick:Y},"锁定"),u("button",{class:"btn btn-primary btn-sm",onClick:We},"新增账号")]),u("div",J_,[u("table",X_,[X[18]||(X[18]=u("thead",null,[u("tr",null,[u("th",null,"系统名称"),u("th",null,"账号"),u("th",null,"密码"),u("th",null,"备注"),u("th",{class:"th-ops"},"操作")])],-1)),u("tbody",null,[(K(!0),H(Re,null,ct(S.value,Z=>(K(),H("tr",{key:Z.id},[u("td",Q_,se(Z.system),1),u("td",null,[u("span",{class:"copyable",title:"点击复制账号",onClick:ke=>rt(Z)},se(Z.account),9,Z_)]),u("td",null,[u("div",e1,[u("span",t1,se(w.value[Z.id]?Z.passwordPlain:"........"),1),u("button",{class:"btn btn-xs",onClick:ke=>xe(Z)},se(w.value[Z.id]?"隐藏":"显示"),9,n1),u("button",{class:"btn btn-xs",onClick:ke=>Fe(Z)},"复制",8,r1)])]),u("td",s1,se(Z.remark||"--"),1),u("td",null,[u("div",o1,[u("button",{class:"btn btn-xs",onClick:ke=>Ye(Z)},"编辑",8,i1),u("button",{class:"btn btn-xs",onClick:ke=>ee.value=Z},"删除",8,a1)])])]))),128)),S.value.length?Ee("",!0):(K(),H("tr",l1,[...X[17]||(X[17]=[u("td",{colspan:"5",class:"empty muted"},"暂无账号,点击右上角新增",-1)])]))])])]),u("div",u1,"共 "+se(y.value.length)+" 条账号记录 · 密码以 AES-256-GCM 加密存储于本机",1)],64)):(K(),H("div",B_,[u("div",U_,[Oe(ut,{name:"lock",size:26})]),t.value===!1?(K(),H(Re,{key:0},[X[12]||(X[12]=u("div",{class:"lock-title"},"设置主密码",-1)),X[13]||(X[13]=u("div",{class:"muted lock-tip"},"主密码用于加密保存在本机的账号密码,遗忘后无法找回,请务必牢记",-1)),Te(u("input",{type:"password",class:"input","onUpdate:modelValue":X[0]||(X[0]=Z=>o.value=Z),placeholder:"设置主密码(至少 6 位)",onKeydown:Dt(oe,["enter"])},null,544),[[Le,o.value]]),Te(u("input",{type:"password",class:"input","onUpdate:modelValue":X[1]||(X[1]=Z=>a.value=Z),placeholder:"再次输入主密码",onKeydown:Dt(oe,["enter"])},null,544),[[Le,a.value]]),c.value?(K(),H("div",q_,se(c.value),1)):Ee("",!0),u("button",{class:"btn btn-primary lock-btn",disabled:s.value,onClick:oe},"完成设置并解锁",8,H_)],64)):(K(),H(Re,{key:1},[X[14]||(X[14]=u("div",{class:"lock-title"},"密码库已锁定",-1)),X[15]||(X[15]=u("div",{class:"muted lock-tip"},"输入主密码解锁后查看与复制密码",-1)),Te(u("input",{type:"password",class:"input","onUpdate:modelValue":X[2]||(X[2]=Z=>d.value=Z),placeholder:"主密码",onKeydown:Dt(ge,["enter"])},null,544),[[Le,d.value]]),h.value?(K(),H("div",W_,se(h.value),1)):Ee("",!0),u("button",{class:"btn btn-primary lock-btn",disabled:s.value,onClick:ge},"解锁",8,z_)],64))])),Oe(F_,{open:C.value,title:O.value?"编辑账号":"新增账号",initial:N.value,onCancel:X[4]||(X[4]=Z=>C.value=!1),onSave:me},null,8,["open","title","initial"]),Oe(lr,{open:!!ee.value,title:"删除确认",message:ee.value?"将删除系统「"+ee.value.system+"」的账号记录。删除后不可恢复。":"","confirm-text":"删除",danger:"",onCancel:X[5]||(X[5]=Z=>ee.value=null),onConfirm:Me},null,8,["open","message"]),(K(),It(Us,{to:"body"},[Oe(ss,{name:"modal"},{default:cr(()=>[te.value?(K(),H("div",{key:0,class:"mask",onClick:X[11]||(X[11]=Ir(Z=>te.value=!1,["self"]))},[u("div",c1,[u("div",f1,[X[19]||(X[19]=u("span",{class:"dialog-title"},"修改主密码",-1)),u("button",{class:"icon-btn",title:"关闭",onClick:X[6]||(X[6]=Z=>te.value=!1)},[Oe(ut,{name:"close",size:16})])]),u("div",d1,[u("div",p1,[X[20]||(X[20]=u("label",null,"旧主密码",-1)),Te(u("input",{type:"password",class:"input","onUpdate:modelValue":X[7]||(X[7]=Z=>ue.value=Z)},null,512),[[Le,ue.value]])]),u("div",h1,[X[21]||(X[21]=u("label",null,"新主密码(至少 6 位)",-1)),Te(u("input",{type:"password",class:"input","onUpdate:modelValue":X[8]||(X[8]=Z=>P.value=Z)},null,512),[[Le,P.value]])]),u("div",v1,[X[22]||(X[22]=u("label",null,"确认新主密码",-1)),Te(u("input",{type:"password",class:"input","onUpdate:modelValue":X[9]||(X[9]=Z=>L.value=Z)},null,512),[[Le,L.value]])]),J.value?(K(),H("div",m1,se(J.value),1)):Ee("",!0),X[23]||(X[23]=u("div",{class:"muted vp-tip"},"确认后所有账号密码将使用新主密码重新加密",-1))]),u("div",y1,[u("button",{class:"btn btn-sm",onClick:X[10]||(X[10]=Z=>te.value=!1)},"取消"),u("button",{class:"btn btn-primary btn-sm",onClick:De},"确认修改")])])])):Ee("",!0)]),_:1})]))]))}}),w1=Yt(b1,[["__scopeId","data-v-6820bc9c"]]);function _1(e){return'"'+(e==null?"":String(e)).replace(/"/g,'""')+'"'}async function Bu(e,t){const s="\uFEFF"+t.map(d=>d.map(_1).join(",")).join(`\r +`);if(ns.isNativePlatform()){const{downloadText:d}=await Af(async()=>{const{downloadText:h}=await Promise.resolve().then(()=>pb);return{downloadText:h}},void 0,import.meta.url);return d(e,s)}const o=new Blob([s],{type:"text/csv;charset=utf-8"}),a=URL.createObjectURL(o),c=document.createElement("a");return c.href=a,c.download=e,c.click(),window.setTimeout(()=>URL.revokeObjectURL(a),1e4),""}const k1={class:"settings"},x1={class:"card section"},C1={class:"muted acc-line"},S1={class:"ai-grid"},E1={class:"rule-item"},$1={class:"rule-item"},T1={class:"rule-item"},P1={key:0,class:"form-error"},A1={class:"rule-save"},O1={class:"card section"},M1={class:"rule-grid"},I1={class:"rule-item"},j1={class:"rule-item"},D1={class:"rule-item"},L1={class:"rule-item"},R1={class:"rule-item"},K1={class:"card section"},F1={class:"proj-add"},N1={key:0,class:"muted proj-tip"},V1=["onKeydown"],B1=["onClick"],U1=["onClick"],q1=["onClick"],H1={key:1,class:"muted"},W1={class:"card section"},z1={class:"card section"},G1={class:"muted acc-line"},Y1={class:"rule-item"},J1={class:"rule-save"},X1=["disabled"],Q1={key:0,class:"muted acc-line"},Z1={key:1,class:"form-error"},e0={key:2,class:"form-error"},t0={class:"card section"},n0={class:"ai-grid"},r0={class:"rule-item"},s0={class:"rule-item"},o0={class:"rule-item"},i0={class:"card section"},a0={class:"backup-row"},l0={key:0,class:"import-error"},u0=Bt({__name:"SettingsView",setup(e){var k;const t=F({work_start:"09:00",work_end:"18:00",grace_minutes:10,lunch_minutes:60,remind_weekly:"friday"}),n=F([]),s=F(""),o=F(""),a=F(""),c=F(""),d=F(""),h=F(""),y=F(null),m=F(""),w=F(null),C=F(null),O=F(""),N=F(((k=wi())==null?void 0:k.username)||""),ee=F(""),te=F(""),ue=F(""),P=F(""),L=F(!1),J="0.2.0",ce=F(""),ie=F(""),Q=F(""),A=F(""),S=F(""),oe=F(!1),ge=F("");async function Y(){var _;ce.value=await Gv(),ie.value=((_=dr())==null?void 0:_.username)||"",ge.value=await Zv(),S.value=Jr.value}vt(Jr,_=>{S.value=_});async function xe(){await Lv(ce.value.trim()),Ue("同步地址已保存")}async function Fe(){A.value="";try{await _f(),Ue("云端绑定已重建")}catch(_){A.value=_ instanceof Error?_.message:"绑定失败"}}async function rt(){if(!oe.value){A.value="",S.value=Jr.value,oe.value=!0;try{await xe();const _=await Fa();ge.value=_.at,Q.value="推送 "+_.pushed+" 条 · 拉取 "+_.pulled+" 条 · 删除 "+_.removed+" 条",S.value="",Ue("同步完成")}catch(_){A.value=_ instanceof Error?_.message:"同步失败"}oe.value=!1}}async function We(){if(P.value="",te.value!==ue.value){P.value="两次输入的新密码不一致";return}try{await Wv(ee.value,te.value),ee.value="",te.value="",ue.value="",Ue("登录密码已修改")}catch(_){P.value=_ instanceof Error?_.message:"修改失败"}}async function Ye(){await zv(),window.location.reload()}async function me(){t.value=await Dr(),n.value=await Ns(!0),a.value=(await hl()).join(` +`),c.value=await gt("ai_base_url",""),d.value=await gt("ai_api_key",""),h.value=await gt("ai_model",""),await Y()}async function Me(){await jt("ai_base_url",c.value.trim()),await jt("ai_api_key",d.value.trim()),await jt("ai_model",h.value.trim()),Ue("AI 配置已保存")}async function Ne(){const _=xt(),x=await Promise.all([ki("2000-01-01",_),Ns(!0)]),z=x[0],ne=x[1],le=new Map(ne.map(ae=>[ae.id,ae.name])),be=[["日期","分类","项目","内容","耗时(分钟)","成果","待跟进","收获","备注"]];for(const ae of z)be.push([ae.date,ll(ae.category),ae.project_id&&le.get(ae.project_id)||"",ae.content,ae.minutes==null?"":ae.minutes,ae.is_milestone?"是":"",ae.needs_followup?"是":"",ae.takeaway||"",ae.remark||""]);const ve=await Bu("工作记录_"+_.replace(/-/g,"")+".csv",be);Ue(ve?"CSV 已导出到:"+ve:"CSV 已导出到系统下载目录")}async function De(){const _=xt(),x=await Promise.all([Dr(),_i("2000-01-01",_)]),z=x[0],ne=x[1],le=["周日","周一","周二","周三","周四","周五","周六"],be=[["日期","星期","状态","上班时间","下班时间","地点","类型","说明"]];for(const ae of ne){const U=zs(ae,ae.date,z,ae.date===_);be.push([ae.date,le[os(ae.date).getDay()],U.label,ae.clock_in_at?Vn(ae.clock_in_at):"",ae.clock_out_at?Vn(ae.clock_out_at):"",ae.location||"",ae.kind==="makeup"?"补卡":ae.kind==="leave"?"休假":"正常",ae.note||""])}const ve=await Bu("考勤记录_"+_.replace(/-/g,"")+".csv",be);Ue(ve?"CSV 已导出到:"+ve:"CSV 已导出到系统下载目录")}mn(me);async function Ce(){await jt("work_start",t.value.work_start),await jt("work_end",t.value.work_end),await jt("grace_minutes",String(t.value.grace_minutes)),await jt("lunch_minutes",String(t.value.lunch_minutes)),await jt("remind_weekly",t.value.remind_weekly),Ue("打卡规则已保存")}async function X(){await $f(a.value.split(` +`)),Ue("常用地点已保存")}async function Z(){const _=s.value.trim();if(_){try{await mm(_),o.value="",s.value=""}catch{o.value="项目名已存在"}await me()}}function ke(_){y.value=_.id,m.value=_.name}async function Be(_){const x=m.value.trim();if(x)try{await ym(_.id,x),o.value=""}catch{o.value="项目名已存在"}y.value=null,await me()}async function dt(_){await gm(_.id,_.archived!==1),await me()}async function Jt(){try{const _=await Bm(),x=await ml("实习日志备份_"+xt().replace(/-/g,"")+".json",_);Ue(x?"备份已导出到:"+x:"备份已导出到系统下载目录")}catch(_){Ue("导出失败:"+(_ instanceof Error?_.message:String(_)))}}function Xt(_){const x=_.target,z=x.files&&x.files[0];if(O.value="",!z)return;const ne=z.name;z.text().then(le=>{C.value={name:ne,text:le}}),x.value=""}async function je(){if(C.value)try{await Um(C.value.text),C.value=null,O.value="",await me(),Ue("数据导入完成")}catch(_){C.value=null,O.value=_ instanceof Error?_.message:"导入失败"}}return(_,x)=>(K(),H("div",k1,[u("div",x1,[x[23]||(x[23]=u("div",{class:"section-title"},"账号与隐私",-1)),u("div",C1,"版本 v"+se(Zt(J))+" · 当前用户:"+se(N.value)+" · 每位用户独立数据库隔离存储于本机 · 登录密码仅保存 PBKDF2 哈希",1),u("div",S1,[u("div",E1,[x[20]||(x[20]=u("label",null,"旧登录密码",-1)),Te(u("input",{type:"password",class:"input","onUpdate:modelValue":x[0]||(x[0]=z=>ee.value=z)},null,512),[[Le,ee.value]])]),u("div",$1,[x[21]||(x[21]=u("label",null,"新登录密码(至少 6 位)",-1)),Te(u("input",{type:"password",class:"input","onUpdate:modelValue":x[1]||(x[1]=z=>te.value=z)},null,512),[[Le,te.value]])]),u("div",T1,[x[22]||(x[22]=u("label",null,"确认新登录密码",-1)),Te(u("input",{type:"password",class:"input","onUpdate:modelValue":x[2]||(x[2]=z=>ue.value=z)},null,512),[[Le,ue.value]])])]),P.value?(K(),H("div",P1,se(P.value),1)):Ee("",!0),u("div",A1,[u("button",{class:"btn btn-primary btn-sm",onClick:We},"修改登录密码"),u("button",{class:"btn btn-sm btn-danger",onClick:x[3]||(x[3]=z=>L.value=!0)},"删除此用户及全部数据")])]),u("div",O1,[x[30]||(x[30]=u("div",{class:"section-title"},"打卡规则",-1)),u("div",M1,[u("div",I1,[x[24]||(x[24]=u("label",null,"上班时间",-1)),Te(u("input",{type:"time",class:"input","onUpdate:modelValue":x[4]||(x[4]=z=>t.value.work_start=z)},null,512),[[Le,t.value.work_start]])]),u("div",j1,[x[25]||(x[25]=u("label",null,"下班时间",-1)),Te(u("input",{type:"time",class:"input","onUpdate:modelValue":x[5]||(x[5]=z=>t.value.work_end=z)},null,512),[[Le,t.value.work_end]])]),u("div",D1,[x[26]||(x[26]=u("label",null,"迟到宽限(分钟)",-1)),Te(u("input",{type:"number",class:"input",min:"0","onUpdate:modelValue":x[6]||(x[6]=z=>t.value.grace_minutes=z)},null,512),[[Le,t.value.grace_minutes,void 0,{number:!0}]])]),u("div",L1,[x[27]||(x[27]=u("label",null,"午休扣除(分钟)",-1)),Te(u("input",{type:"number",class:"input",min:"0","onUpdate:modelValue":x[7]||(x[7]=z=>t.value.lunch_minutes=z)},null,512),[[Le,t.value.lunch_minutes,void 0,{number:!0}]])]),u("div",R1,[x[29]||(x[29]=u("label",null,"周记提醒",-1)),Te(u("select",{class:"select","onUpdate:modelValue":x[8]||(x[8]=z=>t.value.remind_weekly=z)},[...x[28]||(x[28]=[u("option",{value:"friday"},"每周五提醒",-1),u("option",{value:"off"},"关闭",-1)])],512),[[Fn,t.value.remind_weekly]])])]),u("div",{class:"rule-save"},[u("button",{class:"btn btn-primary btn-sm",onClick:Ce},"保存规则")])]),u("div",K1,[x[31]||(x[31]=u("div",{class:"section-title"},"项目管理",-1)),u("div",F1,[Te(u("input",{class:"input","onUpdate:modelValue":x[9]||(x[9]=z=>s.value=z),placeholder:"新项目名称",onKeydown:Dt(Z,["enter"])},null,544),[[Le,s.value]]),u("button",{class:"btn btn-sm",onClick:Z},"添加")]),o.value?(K(),H("div",N1,se(o.value),1)):Ee("",!0),(K(!0),H(Re,null,ct(n.value,z=>(K(),H("div",{key:z.id,class:"proj-row"},[y.value===z.id?(K(),H(Re,{key:0},[Te(u("input",{class:"input","onUpdate:modelValue":x[10]||(x[10]=ne=>m.value=ne),onKeydown:Dt(ne=>Be(z),["enter"])},null,40,V1),[[Le,m.value]]),u("button",{class:"btn btn-sm",onClick:ne=>Be(z)},"保存",8,B1),u("button",{class:"btn btn-sm",onClick:x[11]||(x[11]=ne=>y.value=null)},"取消")],64)):(K(),H(Re,{key:1},[u("span",{class:tt(["proj-name",{archived:z.archived===1}])},se(z.name),3),u("button",{class:"icon-btn",title:"重命名",onClick:ne=>ke(z)},[Oe(ut,{name:"edit",size:14})],8,U1),u("button",{class:"btn btn-sm",onClick:ne=>dt(z)},se(z.archived===1?"恢复":"归档"),9,q1)],64))]))),128)),n.value.length?Ee("",!0):(K(),H("div",H1,"暂无项目,先添加一个"))]),u("div",W1,[x[33]||(x[33]=u("div",{class:"section-title"},"常用地点",-1)),Te(u("textarea",{class:"textarea","onUpdate:modelValue":x[12]||(x[12]=z=>a.value=z),placeholder:"每行一个地点,如:公司、客户现场、出差、居家办公"},null,512),[[Le,a.value]]),u("div",{class:"rule-save"},[u("button",{class:"btn btn-primary btn-sm",onClick:X},"保存地点"),x[32]||(x[32]=u("span",{class:"muted loc-note"},"打卡时可直接输入新地点,保存后自动加入列表",-1))])]),u("div",z1,[x[35]||(x[35]=u("div",{class:"section-title"},"多端数据同步",-1)),u("div",G1,"云端账号:"+se(ie.value||"未绑定")+" · 数据仅保存在服务器,本机只是实时缓存(变更 ~3 秒推上云端 + 其他端秒级自动刷新);密码库同步密文,主密码永不出本机",1),u("div",Y1,[x[34]||(x[34]=u("label",null,"同步服务地址(默认即可)",-1)),Te(u("input",{class:"input","onUpdate:modelValue":x[13]||(x[13]=z=>ce.value=z),placeholder:"https://daywk.linyux.cn"},null,512),[[Le,ce.value]])]),u("div",J1,[u("button",{class:"btn btn-sm",onClick:xe},"保存地址"),u("button",{class:"btn btn-primary btn-sm",disabled:oe.value,onClick:rt},se(oe.value?"同步中":"立即同步"),9,X1),u("button",{class:"btn btn-sm",onClick:Fe},"重建云端绑定")]),Q.value?(K(),H("div",Q1,"上次同步:"+se(ge.value||"--")+" · "+se(Q.value),1)):Ee("",!0),A.value?(K(),H("div",Z1,se(A.value),1)):Ee("",!0),S.value?(K(),H("div",e0,"最近自动同步失败:"+se(S.value)+"(可点「立即同步」重试)",1)):Ee("",!0)]),u("div",t0,[x[40]||(x[40]=u("div",{class:"section-title"},"AI 润色配置(可选)",-1)),u("div",n0,[u("div",r0,[x[36]||(x[36]=u("label",null,"接口地址(OpenAI 兼容,到 /v1 为止)",-1)),Te(u("input",{class:"input","onUpdate:modelValue":x[14]||(x[14]=z=>c.value=z),placeholder:"https://api.example.com/v1"},null,512),[[Le,c.value]])]),u("div",s0,[x[37]||(x[37]=u("label",null,"API Key",-1)),Te(u("input",{class:"input","onUpdate:modelValue":x[15]||(x[15]=z=>d.value=z),placeholder:"sk-..."},null,512),[[Le,d.value]])]),u("div",o0,[x[38]||(x[38]=u("label",null,"模型名称",-1)),Te(u("input",{class:"input","onUpdate:modelValue":x[16]||(x[16]=z=>h.value=z),placeholder:"如:deepseek-chat"},null,512),[[Le,h.value]])])]),u("div",{class:"rule-save"},[u("button",{class:"btn btn-primary btn-sm",onClick:Me},"保存 AI 配置"),x[39]||(x[39]=u("span",{class:"muted loc-note"},"配置仅保存在本机浏览器;总结页可用 AI 润色草稿,需服务端允许浏览器跨域",-1))])]),u("div",i0,[x[41]||(x[41]=u("div",{class:"section-title"},"数据备份",-1)),u("div",a0,[u("button",{class:"btn btn-sm",onClick:Jt},"导出 JSON 备份"),u("button",{class:"btn btn-sm",onClick:x[17]||(x[17]=z=>{var ne;return(ne=w.value)==null?void 0:ne.click()})},"导入 JSON 备份"),u("button",{class:"btn btn-sm",onClick:Ne},"导出工作记录 CSV"),u("button",{class:"btn btn-sm",onClick:De},"导出考勤 CSV"),u("input",{ref_key:"fileInput",ref:w,type:"file",accept:"application/json,.json",style:{display:"none"},onChange:Xt},null,544)]),O.value?(K(),H("div",l0,se(O.value),1)):Ee("",!0),x[42]||(x[42]=u("div",{class:"muted backup-note"},"数据保存在浏览器 IndexedDB 中,建议定期导出 JSON 备份。",-1))]),Oe(lr,{open:!!C.value,title:"导入确认",message:C.value?"将从文件「"+C.value.name+"」导入备份。现有全部数据将被覆盖,且不可恢复,请先确认已导出当前备份。":"","confirm-text":"覆盖导入",danger:"",onCancel:x[18]||(x[18]=z=>C.value=null),onConfirm:je},null,8,["open","message"]),Oe(lr,{open:L.value,title:"删除用户确认",message:"将永久删除云端账号「"+N.value+"」及其服务器上的全部数据:工作日志、考勤、备忘录、账号密码库都将被清除,任何设备都无法再取回,且不可恢复。请确认。","confirm-text":"永久删除",danger:"",onCancel:x[19]||(x[19]=z=>L.value=!1),onConfirm:Ye},null,8,["open","message"])]))}}),c0=Yt(u0,[["__scopeId","data-v-cea34561"]]),f0={class:"login-page"},d0={class:"card login-card"},p0={class:"login-brand"},h0={class:"brand-icon"},v0={class:"seg"},m0=["placeholder"],y0={key:1,class:"form-error"},g0=["disabled"],b0=Bt({__name:"LoginView",emits:["login"],setup(e,{emit:t}){const n=t,s=F("login"),o=F(""),a=F(""),c=F(""),d=F(""),h=F(!1);function y(w){s.value=w,d.value="",c.value=""}async function m(){if(!h.value){d.value="",h.value=!0;try{let w;if(s.value==="login")w=await Vv(o.value,a.value);else{if(a.value.length<6){d.value="登录密码至少 6 位",h.value=!1;return}if(a.value!==c.value){d.value="两次输入的密码不一致",h.value=!1;return}w=await Bv(o.value,a.value)}n("login",w)}catch(w){d.value=w instanceof Error?w.message:"操作失败"}h.value=!1}}return(w,C)=>(K(),H("div",f0,[u("div",d0,[u("div",p0,[u("div",h0,[Oe(ut,{name:"calendar",size:22})]),C[5]||(C[5]=u("div",{class:"login-title"},"实习工作日志",-1)),C[6]||(C[6]=u("div",{class:"muted login-sub"},"打卡 · 记录 · 总结 · 备忘录 · 密码库",-1)),C[7]||(C[7]=u("div",{class:"muted login-sub"},"数据保存在云端服务器,所有设备登录同一账号即可实时同步",-1))]),u("div",v0,[u("button",{class:tt(["seg-btn",{active:s.value==="login"}]),onClick:C[0]||(C[0]=O=>y("login"))},"登录",2),u("button",{class:tt(["seg-btn",{active:s.value==="create"}]),onClick:C[1]||(C[1]=O=>y("create"))},"创建用户",2)]),Te(u("input",{class:"input","onUpdate:modelValue":C[2]||(C[2]=O=>o.value=O),placeholder:"用户名(2 到 20 个字符)",onKeydown:Dt(m,["enter"])},null,544),[[Le,o.value]]),Te(u("input",{type:"password",class:"input","onUpdate:modelValue":C[3]||(C[3]=O=>a.value=O),placeholder:s.value==="login"?"登录密码":"设置登录密码(至少 6 位)",onKeydown:Dt(m,["enter"])},null,40,m0),[[Le,a.value]]),s.value==="create"?Te((K(),H("input",{key:0,type:"password",class:"input","onUpdate:modelValue":C[4]||(C[4]=O=>c.value=O),placeholder:"再次输入密码",onKeydown:Dt(m,["enter"])},null,544)),[[Le,c.value]]):Ee("",!0),d.value?(K(),H("div",y0,se(d.value),1)):Ee("",!0),u("button",{class:"btn btn-primary login-btn",disabled:h.value,onClick:m},se(s.value==="login"?"登录":"创建并进入"),9,g0),C[8]||(C[8]=u("div",{class:"muted login-note"}," 登录密码仅服务器保存哈希;本机保存加密的自动登录凭据,登录后无需重复输入 ",-1))])]))}}),w0=Yt(b0,[["__scopeId","data-v-bf714afa"]]),_0={key:1,class:"app"},k0={class:"side"},x0=["data-tip","onClick"],C0={class:"main"},S0={class:"topbar"},E0={class:"title"},$0={class:"gsearch"},T0={key:0,class:"gs-panel"},P0={key:0,class:"gs-group muted"},A0=["onMousedown"],O0={class:"tag"},M0={class:"gs-text"},I0={class:"muted num gs-date"},j0={key:1,class:"gs-group muted"},D0=["onMousedown"],L0={class:"gs-text"},R0={class:"muted gs-sub"},K0={key:1,class:"gs-empty muted"},F0={class:"topbar-actions"},N0={class:"user-chip num"},V0=["disabled"],B0={class:"num"},U0={class:"content"},q0={class:"content-inner"},H0={class:"toast-wrap"},W0=Bt({__name:"App",setup(e){const t=Hm(),n=F(wi());async function s(me){n.value=me,ni(me.userId),location.hash="#/calendar",ce.value="calendar",await ge(),await Ye(),c();try{await _f(),await Qr()}catch{}Ue("欢迎,"+me.username);const Me=sessionStorage.getItem("dsh_migrate_toast");Me&&(sessionStorage.removeItem("dsh_migrate_toast"),Ue("已迁移原有数据 "+Me+" 条"))}async function o(){sm(),a!==null&&(window.clearInterval(a),a=null),await qv(),n.value=null,ce.value="calendar",location.hash="#/calendar",Ue("已退出登录")}let a=null;function c(){rm(),a!==null&&window.clearInterval(a),a=window.setInterval(()=>{Qr()},60*1e3),Qr()}const d=F(null),h=F(""),y=F(!1),m=F({logs:[],memos:[]});let w=null;const C=at(()=>!!(m.value.logs.length||m.value.memos.length));function O(){w&&window.clearTimeout(w);const me=h.value;w=window.setTimeout(async()=>{const Me=me.trim();if(!Me){m.value={logs:[],memos:[]};return}const Ne=await Promise.all([Dm(Me,8),Lm(Me,4)]);m.value={logs:Ne[0],memos:Ne[1]}},200)}function N(){h.value="",m.value={logs:[],memos:[]},y.value=!1}function ee(me){Ra.value=me.date,ie("calendar"),N()}function te(me){Ka.value=me.id,ie("memo"),N()}function ue(){window.setTimeout(()=>{y.value=!1},150)}function P(me){var Me;(me.ctrlKey||me.metaKey)&&me.key.toLowerCase()==="k"&&(me.preventDefault(),(Me=d.value)==null||Me.focus())}const L=[{key:"calendar",name:"日历",icon:"calendar"},{key:"today",name:"详情",icon:"edit"},{key:"stats",name:"统计",icon:"chart"},{key:"report",name:"总结",icon:"export"},{key:"ledger",name:"记账",icon:"wallet"},{key:"memo",name:"备忘录",icon:"memo"},{key:"vault",name:"密码库",icon:"lock"},{key:"settings",name:"设置",icon:"settings"}];function J(){const me=(location.hash||"").replace("#/","");return L.some(Me=>Me.key===me)?me:"calendar"}const ce=F(J());window.addEventListener("hashchange",()=>{ce.value=J()});function ie(me){location.hash="#/"+me}const Q=at(()=>L.find(me=>me.key===ce.value)||L[0]),A=F(xt()),S=F(void 0),oe=F(!1);async function ge(){if(S.value=await yn(A.value),oe.value=!1,new Date().getHours()<4){const Me=await yn(Kn(A.value,-1));oe.value=!!(Me&&Me.clock_in_at&&!Me.clock_out_at)}}const Y=at(()=>{const me=S.value;return me&&me.clock_in_at&&!me.clock_out_at?!0:oe.value&&!(me&&me.clock_in_at)}),xe=at(()=>{const me=S.value;return!!(me&&me.clock_in_at&&me.clock_out_at)}),Fe=at(()=>{const me=S.value;return Y.value?"下班打卡":xe.value?"已打卡 "+Vn(me==null?void 0:me.clock_in_at)+" - "+Vn(me==null?void 0:me.clock_out_at):"上班打卡"});async function rt(){if(Y.value)try{await wm()}catch{}else await Tf(A.value);await ge(),er()}vt(Ws,()=>{n.value&&ge()});const We=F(!1);async function Ye(){if((await Dr()).remind_weekly==="off"){We.value=!1;return}const Me=new Date().getDay();if(Me===5||Me===6||Me===0){const Ne=await vl(Ts(A.value));We.value=!Ne||!Ne.highlights&&!Ne.challenges&&!Ne.plan_next}else We.value=!1}return mn(async()=>{window.addEventListener("keydown",P),n.value&&(ni(n.value.userId),await ge(),await Ye(),c())}),(me,Me)=>{var Ne;return n.value?(K(),H("div",_0,[u("nav",k0,[(K(),H(Re,null,ct(L,De=>u("button",{key:De.key,class:tt(["nav-btn",{active:ce.value===De.key}]),"data-tip":De.name,onClick:Ce=>ie(De.key)},[Oe(ut,{name:De.icon,size:18},null,8,["name"])],10,x0)),64))]),u("div",C0,[u("header",S0,[u("span",E0,se(Q.value.name),1),u("div",$0,[Oe(ut,{name:"search",size:14,class:"gs-icon"}),Te(u("input",{ref_key:"gsInput",ref:d,class:"input gs-input","onUpdate:modelValue":Me[0]||(Me[0]=De=>h.value=De),placeholder:"搜索工作记录与备忘录(Ctrl+K)",onInput:O,onFocus:Me[1]||(Me[1]=De=>y.value=!0),onBlur:ue,onKeydown:Dt(N,["esc"])},null,544),[[Le,h.value]]),y.value&&h.value.trim()?(K(),H("div",T0,[C.value?(K(),H(Re,{key:0},[m.value.logs.length?(K(),H("div",P0,"工作记录")):Ee("",!0),(K(!0),H(Re,null,ct(m.value.logs,De=>(K(),H("div",{key:"l"+De.id,class:"gs-item",onMousedown:Ir(Ce=>ee(De),["prevent"])},[u("span",O0,se(Zt(ll)(De.category)),1),u("span",M0,se(De.content),1),u("span",I0,se(De.date),1)],40,A0))),128)),m.value.memos.length?(K(),H("div",j0,"备忘录")):Ee("",!0),(K(!0),H(Re,null,ct(m.value.memos,De=>(K(),H("div",{key:"m"+De.id,class:"gs-item",onMousedown:Ir(Ce=>te(De),["prevent"])},[u("span",L0,se(De.title||"无标题"),1),u("span",R0,se(De.content),1)],40,D0))),128))],64)):(K(),H("div",K0,"无匹配结果"))])):Ee("",!0)]),Me[4]||(Me[4]=u("span",{class:"flex1"},null,-1)),u("div",F0,[We.value?(K(),H("button",{key:0,class:"week-tip",onClick:Me[2]||(Me[2]=De=>ie("report"))},[...Me[3]||(Me[3]=[u("span",{class:"dot",style:{background:"var(--warn)"}},null,-1),rn(" 填写本周周记 ",-1)])])):Ee("",!0),u("span",N0,se((Ne=n.value)==null?void 0:Ne.username),1),u("button",{class:"btn btn-sm",onClick:o},"退出"),u("button",{class:"btn btn-primary btn-sm",disabled:xe.value,onClick:rt},[Oe(ut,{name:xe.value?"check-circle":"clock",size:14},null,8,["name"]),u("span",B0,se(Fe.value),1)],8,V0)])]),u("main",U0,[u("div",q0,[ce.value==="calendar"?(K(),It(hg,{key:0})):ce.value==="today"?(K(),It(wg,{key:1})):ce.value==="stats"?(K(),It(Xg,{key:2})):ce.value==="report"?(K(),It(Jb,{key:3})):ce.value==="ledger"?(K(),It(a_,{key:4})):ce.value==="memo"?(K(),It(S_,{key:5})):ce.value==="vault"?(K(),It(w1,{key:6})):(K(),It(c0,{key:7}))])])]),u("div",H0,[Oe(Eh,{name:"toast"},{default:cr(()=>[(K(!0),H(Re,null,ct(Zt(t),De=>(K(),H("div",{key:De.id,class:"toast"},se(De.text),1))),128))]),_:1})])])):(K(),It(w0,{key:0,onLogin:s}))}}}),z0=Yt(W0,[["__scopeId","data-v-d5bd1ff7"]]);function Lo(e,t){try{let n=document.getElementById("fatal-overlay");n||(n=document.createElement("div"),n.id="fatal-overlay",n.style.cssText="position:fixed;inset:0;z-index:99999;background:#FFFFFF;color:#1D2129;padding:20px;overflow:auto;font:13px/1.7 -apple-system,PingFang SC,Microsoft YaHei,sans-serif;",n.addEventListener("click",o=>{o.target===n&&n.parentElement&&n.parentElement.removeChild(n)}),document.body.appendChild(n));const s=document.createElement("div");s.style.cssText="border:1px solid #E5484D;border-radius:8px;padding:12px;margin-bottom:12px;word-break:break-all;white-space:pre-wrap;",s.textContent=e+` +`+t,n.appendChild(s)}catch{}}async function G0(){const e=await Uv();e&&ni(e.userId);const t=Vh(z0);t.config.errorHandler=(n,s,o)=>{const a=n;Lo("应用内部错误(点击空白处关闭,请将以下内容发送给开发者)",a&&(a.stack||a.message)||String(n)+` +触发位置: `+o)},window.addEventListener("unhandledrejection",n=>{const s=n.reason;Lo("未处理的异步错误(点击空白处关闭)",s&&(s.stack||s.message)||String(n.reason))}),window.addEventListener("error",n=>{n.message&&n.message!=="ResizeObserver loop limit exceeded"&&Lo("运行错误(点击空白处关闭)",n.message)}),t.mount("#app"),"serviceWorker"in navigator&&location.protocol.startsWith("http")&&window.addEventListener("load",()=>{navigator.serviceWorker.register("sw.js").catch(()=>{})})}G0().catch(e=>{Lo("无法启动:连接同步服务器失败",e&&(e.stack||e.message)||String(e))});export{If as W,Af as _,fb as b,Mf as r}; diff --git a/intern-log/dist/assets/index-CAFZD9Jo.js b/intern-log/dist/assets/index-CAFZD9Jo.js deleted file mode 100644 index 7d8cc36..0000000 --- a/intern-log/dist/assets/index-CAFZD9Jo.js +++ /dev/null @@ -1,26 +0,0 @@ -(function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const o of document.querySelectorAll('link[rel="modulepreload"]'))s(o);new MutationObserver(o=>{for(const a of o)if(a.type==="childList")for(const u of a.addedNodes)u.tagName==="LINK"&&u.rel==="modulepreload"&&s(u)}).observe(document,{childList:!0,subtree:!0});function n(o){const a={};return o.integrity&&(a.integrity=o.integrity),o.referrerPolicy&&(a.referrerPolicy=o.referrerPolicy),o.crossOrigin==="use-credentials"?a.credentials="include":o.crossOrigin==="anonymous"?a.credentials="omit":a.credentials="same-origin",a}function s(o){if(o.ep)return;o.ep=!0;const a=n(o);fetch(o.href,a)}})();/** -* @vue/shared v3.5.44 -* (c) 2018-present Yuxi (Evan) You and Vue contributors -* @license MIT -**/function Na(e){const t=Object.create(null);for(const n of e.split(","))t[n]=1;return n=>n in t}const dt={},Ar=[],En=()=>{},Wu=()=>!1,ri=e=>e.charCodeAt(0)===111&&e.charCodeAt(1)===110&&(e.charCodeAt(2)>122||e.charCodeAt(2)<97),si=e=>e.startsWith("onUpdate:"),Et=Object.assign,Va=(e,t)=>{const n=e.indexOf(t);n>-1&&e.splice(n,1)},af=Object.prototype.hasOwnProperty,it=(e,t)=>af.call(e,t),Ke=Array.isArray,sr=e=>Bs(e)==="[object Map]",Bn=e=>Bs(e)==="[object Set]",zl=e=>Bs(e)==="[object Date]",Ge=e=>typeof e=="function",wt=e=>typeof e=="string",$n=e=>typeof e=="symbol",lt=e=>e!==null&&typeof e=="object",zu=e=>(lt(e)||Ge(e))&&Ge(e.then)&&Ge(e.catch),Gu=Object.prototype.toString,Bs=e=>Gu.call(e),lf=e=>Bs(e).slice(8,-1),Yu=e=>Bs(e)==="[object Object]",Ba=e=>wt(e)&&e!=="NaN"&&e[0]!=="-"&&""+parseInt(e,10)===e,bs=Na(",key,ref,ref_for,ref_key,onVnodeBeforeMount,onVnodeMounted,onVnodeBeforeUpdate,onVnodeUpdated,onVnodeBeforeUnmount,onVnodeUnmounted"),oi=e=>{const t=Object.create(null);return n=>t[n]||(t[n]=e(n))},uf=/-\w/g,hn=oi(e=>e.replace(uf,t=>t.slice(1).toUpperCase())),cf=/\B([A-Z])/g,dr=oi(e=>e.replace(cf,"-$1").toLowerCase()),Ju=oi(e=>e.charAt(0).toUpperCase()+e.slice(1)),Zi=oi(e=>e?`on${Ju(e)}`:""),Cn=(e,t)=>!Object.is(e,t),Po=(e,...t)=>{for(let n=0;n{Object.defineProperty(e,t,{configurable:!0,enumerable:!1,writable:s,value:n})},ii=e=>{const t=parseFloat(e);return isNaN(t)?e:t},df=e=>{const t=wt(e)?Number(e):NaN;return isNaN(t)?e:t};let Gl;const ai=()=>Gl||(Gl=typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:typeof global<"u"?global:{});function or(e){if(Ke(e)){const t={};for(let n=0;nn.startsWith("/*")?"":n).split(ff).forEach(n=>{if(n){const s=n.split(pf);s.length>1&&(t[s[0].trim()]=s[1].trim())}}),t}function tt(e){let t="";if(wt(e))t=e;else if(Ke(e))for(let n=0;nUn(n,t))}const Zu=e=>!!(e&&e.__v_isRef===!0),se=e=>wt(e)?e:e==null?"":Ke(e)||lt(e)&&(e.toString===Gu||!Ge(e.toString))?Zu(e)?se(e.value):JSON.stringify(e,ec,2):String(e),ec=(e,t)=>Zu(t)?ec(e,t.value):sr(t)?{[`Map(${t.size})`]:[...t.entries()].reduce((n,[s,o],a)=>(n[ea(s,a)+" =>"]=o,n),{})}:Bn(t)?{[`Set(${t.size})`]:[...t.values()].map(n=>ea(n))}:$n(t)?ea(t):lt(t)&&!Ke(t)&&!Yu(t)?String(t):t,ea=(e,t="")=>{var n;return $n(e)?`Symbol(${(n=e.description)!=null?n:t})`:e};/** -* @vue/reactivity v3.5.44 -* (c) 2018-present Yuxi (Evan) You and Vue contributors -* @license MIT -**/let Mt;class wf{constructor(t=!1){this.detached=t,this._active=!0,this._on=0,this.effects=[],this.cleanups=[],this._isPaused=!1,this._warnOnRun=!0,this.__v_skip=!0,!t&&Mt&&(Mt.active?(this.parent=Mt,this.index=(Mt.scopes||(Mt.scopes=[])).push(this)-1):(this._active=!1,this._warnOnRun=!1))}get active(){return this._active}pause(){if(this._active){this._isPaused=!0;let t,n;if(this.scopes){const s=this.scopes.slice();for(t=0,n=s.length;t0&&--this._on===0){if(Mt===this)Mt=this.prevScope;else{let t=Mt;for(;t;){if(t.prevScope===this){t.prevScope=this.prevScope;break}t=t.prevScope}}this.prevScope=void 0}}stop(t){if(this._active){this._active=!1;let n,s;for(n=0,s=this.effects.length;n0)return;if(_s){let t=_s;for(_s=void 0;t;){const n=t.next;t.next=void 0,t.flags&=-9,t=n}}let e;for(;ws;){let t=ws;for(ws=void 0;t;){const n=t.next;if(t.next=void 0,t.flags&=-9,t.flags&1)try{t.trigger()}catch(s){e||(e=s)}t=n}}if(e)throw e}function sc(e){for(let t=e.deps;t;t=t.nextDep)t.version=-1,t.prevActiveLink=t.dep.activeLink,t.dep.activeLink=t}function oc(e){let t,n=e.depsTail,s=n;for(;s;){const o=s.prevDep;s.version===-1?(s===n&&(n=o),Wa(s),kf(s)):t=s,s.dep.activeLink=s.prevActiveLink,s.prevActiveLink=void 0,s=o}e.deps=t,e.depsTail=n}function ya(e){for(let t=e.deps;t;t=t.nextDep)if(t.dep.version!==t.version||t.dep.computed&&(ic(t.dep.computed)||t.dep.version!==t.version))return!0;return!!e._dirty}function ic(e){if(e.flags&4&&!(e.flags&16)||(e.flags&=-17,e.globalVersion===Ps)||(e.globalVersion=Ps,!e.isSSR&&e.flags&128&&(!e.deps&&!e._dirty||!ya(e))))return;e.flags|=2;const t=e.dep,n=ht,s=vn;ht=e,vn=!0;try{sc(e);const o=e.fn(e._value);(t.version===0||Cn(o,e._value))&&(e.flags|=128,e._value=o,t.version++)}catch(o){throw t.version++,o}finally{ht=n,vn=s,oc(e),e.flags&=-3}}function Wa(e,t=!1){const{dep:n,prevSub:s,nextSub:o}=e;if(s&&(s.nextSub=o,e.prevSub=void 0),o&&(o.prevSub=s,e.nextSub=void 0),n.subs===e&&(n.subs=s,!s&&n.computed)){n.computed.flags&=-5;for(let a=n.computed.deps;a;a=a.nextDep)Wa(a,!0)}!t&&!--n.sc&&n.map&&n.map.delete(n.key)}function kf(e){const{prevDep:t,nextDep:n}=e;t&&(t.nextDep=n,e.prevDep=void 0),n&&(n.prevDep=t,e.nextDep=void 0)}let vn=!0;const ac=[];function An(){ac.push(vn),vn=!1}function Pn(){const e=ac.pop();vn=e===void 0?!0:e}function Xl(e){const{cleanup:t}=e;if(e.cleanup=void 0,t){const n=ht;ht=void 0;try{t()}finally{ht=n}}}let Ps=0;class xf{constructor(t,n){this.sub=t,this.dep=n,this.version=n.version,this.nextDep=this.prevDep=this.nextSub=this.prevSub=this.prevActiveLink=void 0}}class za{constructor(t){this.computed=t,this.version=0,this.activeLink=void 0,this.subs=void 0,this.map=void 0,this.key=void 0,this.sc=0,this.__v_skip=!0}track(t){if(!ht||!vn||ht===this.computed)return;let n=this.activeLink;if(n===void 0||n.sub!==ht)n=this.activeLink=new xf(ht,this),ht.deps?(n.prevDep=ht.depsTail,ht.depsTail.nextDep=n,ht.depsTail=n):ht.deps=ht.depsTail=n,lc(n);else if(n.version===-1&&(n.version=this.version,n.nextDep)){const s=n.nextDep;s.prevDep=n.prevDep,n.prevDep&&(n.prevDep.nextDep=s),n.prevDep=ht.depsTail,n.nextDep=void 0,ht.depsTail.nextDep=n,ht.depsTail=n,ht.deps===n&&(ht.deps=s)}return n}trigger(t){this.version++,Ps++,this.notify(t)}notify(t){qa();try{for(let n=this.subs;n;n=n.prevSub)n.sub.notify()&&n.sub.dep.notify()}finally{Ha()}}}function lc(e){if(e.dep.sc++,e.sub.flags&4){const t=e.dep.computed;if(t&&!e.dep.subs){t.flags|=20;for(let s=t.deps;s;s=s.nextDep)lc(s)}const n=e.dep.subs;n!==e&&(e.prevSub=n,n&&(n.nextSub=e)),e.dep.subs=e}}const ga=new WeakMap,Pr=Symbol(""),ba=Symbol(""),Ts=Symbol("");function Kt(e,t,n){if(vn&&ht){let s=ga.get(e);s||ga.set(e,s=new Map);let o=s.get(n);o||(s.set(n,o=new za),o.map=s,o.key=n),o.track()}}function Rn(e,t,n,s,o,a){const u=ga.get(e);if(!u){Ps++;return}const f=h=>{h&&h.trigger()};if(qa(),t==="clear")u.forEach(f);else{const h=Ke(e),y=h&&Ba(n);if(h&&n==="length"){const m=Number(s);u.forEach((w,C)=>{(C==="length"||C===Ts||!$n(C)&&C>=m)&&f(w)})}else switch((n!==void 0||u.has(void 0))&&f(u.get(n)),y&&f(u.get(Ts)),t){case"add":h?y&&f(u.get("length")):(f(u.get(Pr)),sr(e)&&f(u.get(ba)));break;case"delete":h||(f(u.get(Pr)),sr(e)&&f(u.get(ba)));break;case"set":sr(e)&&f(u.get(Pr));break}}Ha()}function qr(e){const t=ot(e);return t===e||(Kt(t,"iterate",Ts),ln(e))?t:Tn(e)?ir(e)?t.map(n=>ar(un(n))):t.map(ar):t.map(un)}function li(e){return Kt(e=ot(e),"iterate",Ts),e}function _n(e,t){return Tn(e)?ar(ir(e)?un(t):t):un(t)}const Cf={__proto__:null,[Symbol.iterator](){return na(this,Symbol.iterator,e=>_n(this,e))},concat(...e){return qr(this).concat(...e.map(t=>Ke(t)?qr(t):t))},entries(){return na(this,"entries",e=>(e[1]=_n(this,e[1]),e))},every(e,t){return In(this,"every",e,t,void 0,arguments)},filter(e,t){return In(this,"filter",e,t,n=>n.map(s=>_n(this,s)),arguments)},find(e,t){return In(this,"find",e,t,n=>_n(this,n),arguments)},findIndex(e,t){return In(this,"findIndex",e,t,void 0,arguments)},findLast(e,t){return In(this,"findLast",e,t,n=>_n(this,n),arguments)},findLastIndex(e,t){return In(this,"findLastIndex",e,t,void 0,arguments)},forEach(e,t){return In(this,"forEach",e,t,void 0,arguments)},includes(...e){return ra(this,"includes",e)},indexOf(...e){return ra(this,"indexOf",e)},join(e){return qr(this).join(e)},lastIndexOf(...e){return ra(this,"lastIndexOf",e)},map(e,t){return In(this,"map",e,t,void 0,arguments)},pop(){return ps(this,"pop")},push(...e){return ps(this,"push",e)},reduce(e,...t){return Zl(this,"reduce",e,t)},reduceRight(e,...t){return Zl(this,"reduceRight",e,t)},shift(){return ps(this,"shift")},some(e,t){return In(this,"some",e,t,void 0,arguments)},splice(...e){return ps(this,"splice",e)},toReversed(){return qr(this).toReversed()},toSorted(e){return qr(this).toSorted(e)},toSpliced(...e){return qr(this).toSpliced(...e)},unshift(...e){return ps(this,"unshift",e)},values(){return na(this,"values",e=>_n(this,e))}};function na(e,t,n){const s=li(e),o=s[t],a=o.call(s);if(s!==e&&!ln(e)){if(a[Symbol.toStringTag]==="Array Iterator"){const u=Object.create(Object.getPrototypeOf(a));return u.next=()=>Ql(a.next(),n),o!==uc[t]&&Object.defineProperties(u,{return:{get(){const f=a.return;return typeof f=="function"?f.bind(a):f}},throw:{get(){const f=a.throw;return typeof f=="function"?f.bind(a):f}}}),u}a._next=a.next,a.next=()=>Ql(a._next(),n)}return a}function Ql(e,t){return e.done||(e.value=t(e.value)),e}const uc=Array.prototype;function In(e,t,n,s,o,a){const u=li(e),f=u!==e&&!ln(e),h=u[t];if(h!==uc[t]){const w=h.apply(e,a);return f?un(w):w}let y=n;u!==e&&(f?y=function(w,C){return n.call(this,_n(e,w),C,e)}:n.length>2&&(y=function(w,C){return n.call(this,w,C,e)}));const m=h.call(u,y,s);return f&&o?o(m):m}function Zl(e,t,n,s){const o=li(e),a=o!==e&&!ln(e);let u=n,f=!1;o!==e&&(a?(f=s.length===0,u=function(y,m,w){return f&&(f=!1,y=_n(e,y)),n.call(this,y,_n(e,m),w,e)}):n.length>3&&(u=function(y,m,w){return n.call(this,y,m,w,e)}));const h=o[t](u,...s);return f?_n(e,h):h}function ra(e,t,n){const s=ot(e);Kt(s,"iterate",Ts);const o=s[t](...n);return(o===-1||o===!1)&&Xa(n[0])?(n[0]=ot(n[0]),s[t](...n)):o}function ps(e,t,n=[]){An(),qa();const s=ot(e)[t].apply(e,n);return Ha(),Pn(),s}const Sf=Na("__proto__,__v_isRef,__isVue"),cc=new Set(Object.getOwnPropertyNames(Symbol).filter(e=>e!=="arguments"&&e!=="caller").map(e=>Symbol[e]).filter($n));function Ef(e){$n(e)||(e=String(e));const t=ot(this);return Kt(t,"has",e),t.hasOwnProperty(e)}class dc{constructor(t=!1,n=!1){this._isReadonly=t,this._isShallow=n}get(t,n,s){if(n==="__v_skip")return t.__v_skip;const o=this._isReadonly,a=this._isShallow;if(n==="__v_isReactive")return!o;if(n==="__v_isReadonly")return o;if(n==="__v_isShallow")return a;if(n==="__v_raw")return s===(o?a?Rf:vc:a?hc:pc).get(t)||Object.getPrototypeOf(t)===Object.getPrototypeOf(s)?t:void 0;const u=Ke(t);if(!o){let h;if(u&&(h=Cf[n]))return h;if(n==="hasOwnProperty")return Ef}const f=Reflect.get(t,n,Nt(t)?t:s);if(($n(n)?cc.has(n):Sf(n))||(o||Kt(t,"get",n),a))return f;if(Nt(f)){const h=u&&Ba(n)?f:f.value;return o&<(h)?_a(h):h}return lt(f)?o?_a(f):Ya(f):f}}class fc extends dc{constructor(t=!1){super(!1,t)}set(t,n,s,o){let a=t[n];const u=Ke(t)&&Ba(n);if(!this._isShallow){const y=Tn(a);if(!ln(s)&&!Tn(s)&&(a=ot(a),s=ot(s)),!u&&Nt(a)&&!Nt(s))return y||(a.value=s),!0}const f=u?Number(n)e,ko=e=>Reflect.getPrototypeOf(e);function Of(e,t,n){return function(...s){const o=this.__v_raw,a=ot(o),u=sr(a),f=e==="entries"||e===Symbol.iterator&&u,h=e==="keys"&&u,y=o[e](...s),m=n?wa:t?ar:un;return!t&&Kt(a,"iterate",h?ba:Pr),Et(Object.create(y),{next(){const{value:w,done:C}=y.next();return C?{value:w,done:C}:{value:f?[m(w[0]),m(w[1])]:m(w),done:C}}})}}function xo(e){return function(...t){return e==="delete"?!1:e==="clear"?void 0:this}}function Mf(e,t){const n={get(o){const a=this.__v_raw,u=ot(a),f=ot(o);e||(Cn(o,f)&&Kt(u,"get",o),Kt(u,"get",f));const{has:h}=ko(u),y=t?wa:e?ar:un;if(h.call(u,o))return y(a.get(o));if(h.call(u,f))return y(a.get(f));a!==u&&a.get(o)},get size(){const o=this.__v_raw;return!e&&Kt(ot(o),"iterate",Pr),o.size},has(o){const a=this.__v_raw,u=ot(a),f=ot(o);return e||(Cn(o,f)&&Kt(u,"has",o),Kt(u,"has",f)),o===f?a.has(o):a.has(o)||a.has(f)},forEach(o,a){const u=this,f=u.__v_raw,h=ot(f),y=t?wa:e?ar:un;return!e&&Kt(h,"iterate",Pr),f.forEach((m,w)=>o.call(a,y(m),y(w),u))}};return Et(n,e?{add:xo("add"),set:xo("set"),delete:xo("delete"),clear:xo("clear")}:{add(o){const a=ot(this),u=ko(a),f=ot(o),h=!t&&!ln(o)&&!Tn(o)?f:o;return u.has.call(a,h)||Cn(o,h)&&u.has.call(a,o)||Cn(f,h)&&u.has.call(a,f)||(a.add(h),Rn(a,"add",h,h)),this},set(o,a){!t&&!ln(a)&&!Tn(a)&&(a=ot(a));const u=ot(this),{has:f,get:h}=ko(u);let y=f.call(u,o);y||(o=ot(o),y=f.call(u,o));const m=h.call(u,o);return u.set(o,a),y?Cn(a,m)&&Rn(u,"set",o,a):Rn(u,"add",o,a),this},delete(o){const a=ot(this),{has:u,get:f}=ko(a);let h=u.call(a,o);h||(o=ot(o),h=u.call(a,o)),f&&f.call(a,o);const y=a.delete(o);return h&&Rn(a,"delete",o,void 0),y},clear(){const o=ot(this),a=o.size!==0,u=o.clear();return a&&Rn(o,"clear",void 0,void 0),u}}),["keys","values","entries",Symbol.iterator].forEach(o=>{n[o]=Of(o,e,t)}),n}function Ga(e,t){const n=Mf(e,t);return(s,o,a)=>o==="__v_isReactive"?!e:o==="__v_isReadonly"?e:o==="__v_isShallow"?t:o==="__v_raw"?s:Reflect.get(it(n,o)&&o in s?n:s,o,a)}const If={get:Ga(!1,!1)},jf={get:Ga(!1,!0)},Df={get:Ga(!0,!1)};const pc=new WeakMap,hc=new WeakMap,vc=new WeakMap,Rf=new WeakMap;function Lf(e){switch(e){case"Object":case"Array":return 1;case"Map":case"Set":case"WeakMap":case"WeakSet":return 2;default:return 0}}function Ya(e){return Tn(e)?e:Ja(e,!1,Af,If,pc)}function Kf(e){return Ja(e,!1,Tf,jf,hc)}function _a(e){return Ja(e,!0,Pf,Df,vc)}function Ja(e,t,n,s,o){if(!lt(e)||e.__v_raw&&!(t&&e.__v_isReactive)||e.__v_skip||!Object.isExtensible(e))return e;const a=o.get(e);if(a)return a;const u=Lf(lf(e));if(u===0)return e;const f=new Proxy(e,u===2?s:n);return o.set(e,f),f}function ir(e){return Tn(e)?ir(e.__v_raw):!!(e&&e.__v_isReactive)}function Tn(e){return!!(e&&e.__v_isReadonly)}function ln(e){return!!(e&&e.__v_isShallow)}function Xa(e){return e?!!e.__v_raw:!1}function ot(e){const t=e&&e.__v_raw;return t?ot(t):e}function Ff(e){return!it(e,"__v_skip")&&Object.isExtensible(e)&&Xu(e,"__v_skip",!0),e}const un=e=>lt(e)?Ya(e):e,ar=e=>lt(e)?_a(e):e;function Nt(e){return e?e.__v_isRef===!0:!1}function N(e){return Nf(e,!1)}function Nf(e,t){return Nt(e)?e:new Vf(e,t)}class Vf{constructor(t,n){this.dep=new za,this.__v_isRef=!0,this.__v_isShallow=!1,this._rawValue=n?t:ot(t),this._value=n?t:un(t),this.__v_isShallow=n}get value(){return this.dep.track(),this._value}set value(t){const n=this._rawValue,s=this.__v_isShallow||ln(t)||Tn(t);t=s?t:ot(t),Cn(t,n)&&(this._rawValue=t,this._value=s?t:un(t),this.dep.trigger())}}function Qt(e){return Nt(e)?e.value:e}const Bf={get:(e,t,n)=>t==="__v_raw"?e:Qt(Reflect.get(e,t,n)),set:(e,t,n,s)=>{const o=e[t];return Nt(o)&&!Nt(n)?(o.value=n,!0):Reflect.set(e,t,n,s)}};function mc(e){return ir(e)?e:new Proxy(e,Bf)}class Uf{constructor(t,n,s){this.fn=t,this.setter=n,this._value=void 0,this.dep=new za(this),this.__v_isRef=!0,this.deps=void 0,this.depsTail=void 0,this.flags=16,this.globalVersion=Ps-1,this.next=void 0,this.effect=this,this.__v_isReadonly=!n,this.isSSR=s}notify(){if(this.flags|=16,!(this.flags&8)&&ht!==this)return rc(this,!0),!0}get value(){const t=this.dep.track();return ic(this),t&&(t.version=this.dep.version),this._value}set value(t){this.setter&&this.setter(t)}}function qf(e,t,n=!1){let s,o;return Ge(e)?s=e:(s=e.get,o=e.set),new Uf(s,o,n)}const Co={},Lo=new WeakMap;let Sr;function Hf(e,t=!1,n=Sr){if(n){let s=Lo.get(n);s||Lo.set(n,s=[]),s.push(e)}}function Wf(e,t,n=dt){const{immediate:s,deep:o,once:a,scheduler:u,augmentJob:f,call:h}=n,y=X=>o?X:ln(X)||o===!1||o===0?Ln(X,1):Ln(X);let m,w,C,S,M=!1,B=!1;if(Nt(e)?(w=()=>e.value,M=ln(e)):ir(e)?(w=()=>y(e),M=!0):Ke(e)?(B=!0,M=e.some(X=>ir(X)||ln(X)),w=()=>e.map(X=>{if(Nt(X))return X.value;if(ir(X))return y(X);if(Ge(X))return h?h(X,2):X()})):Ge(e)?t?w=h?()=>h(e,2):e:w=()=>{if(C){An();try{C()}finally{Pn()}}const X=Sr;Sr=m;try{return h?h(e,3,[S]):e(S)}finally{Sr=X}}:w=En,t&&o){const X=w,de=o===!0?1/0:o;w=()=>Ln(X(),de)}const oe=_f(),ae=()=>{m.stop(),oe&&oe.active&&Va(oe.effects,m)};if(a&&t){const X=t;t=(...de)=>{try{return X(...de)}finally{ae()}}}let T=B?new Array(e.length).fill(Co):Co;const E=X=>{if(!(!(m.flags&1)||!m.dirty&&!X))if(t){const de=m.run();if(X||o||M||(B?de.some((ie,te)=>Cn(ie,T[te])):Cn(de,T))){const ie=Sr;An();try{C&&C(),Sr=m;const te=[de,T===Co?void 0:B&&T[0]===Co?[]:T,S];T=de,h?h(t,3,te):t(...te)}finally{Sr=ie,Pn()}}}else m.run()};return f&&f(E),m=new tc(w),m.scheduler=u?()=>u(E,!1):E,S=X=>Hf(X,!1,m),C=m.onStop=()=>{const X=Lo.get(m);if(X){if(h)h(X,4);else for(const de of X)de();Lo.delete(m)}},t?s?E(!0):T=m.run():u?u(E.bind(null,!0),!0):m.run(),ae.pause=m.pause.bind(m),ae.resume=m.resume.bind(m),ae.stop=ae,ae}function Ln(e,t=1/0,n){if(t<=0||!lt(e)||e.__v_skip||(n=n||new Map,(n.get(e)||0)>=t))return e;if(n.set(e,t),t--,Nt(e))Ln(e.value,t,n);else if(Ke(e))for(let s=0;s{Ln(s,t,n)});else if(Yu(e)){for(const s in e)Ln(e[s],t,n);for(const s of Object.getOwnPropertySymbols(e))Object.prototype.propertyIsEnumerable.call(e,s)&&Ln(e[s],t,n)}return e}/** -* @vue/runtime-core v3.5.44 -* (c) 2018-present Yuxi (Evan) You and Vue contributors -* @license MIT -**/function Us(e,t,n,s){try{return s?e(...s):e()}catch(o){ui(o,t,n)}}function cn(e,t,n,s){if(Ge(e)){const o=Us(e,t,n,s);return o&&zu(o)&&o.catch(a=>{ui(a,t,n)}),o}if(Ke(e)){const o=[];for(let a=0;a>>1,o=Wt[s],a=Os(o);a=Os(n)?Wt.push(e):Wt.splice(Gf(t),0,e),e.flags|=1,gc()}}function gc(){Ko||(Ko=yc.then(_c))}function Yf(e){if(!Ke(e))tr&&e.id===-1?tr.splice(Hr+1,0,e):e.flags&1||(kn.push(e),e.flags|=1);else for(let t=0;t=t))continue;Wt.splice(s,1),s=e?s-1:pn,o.flags&4&&(o.flags&=-2),o(),o.flags&4||(o.flags&=-2)}}}function wc(e,t,n=0){if(kn.length){let s=kn,o=0;if(t){s=[];for(let u=0;uOs(u)-Os(f));if(kn.length=o,tr){for(let u=0;ue.id==null?e.flags&2?-1:1/0:e.id;function _c(e){try{for(pn=0;pn{s._d&&Uo(-1);const a=Fo(t),u=Tr.length;let f;try{f=e(...o)}finally{for(let h=Tr.length;h>u;h--)Jc();Fo(a),s._d&&Uo(1)}return f};return s._n=!0,s._c=!0,s._d=!0,s}function $e(e,t){if(an===null)return e;const n=vi(an),s=e.dirs||(e.dirs=[]);for(let o=0;o1)return n&&Ge(t)?t.call(s&&s.proxy):t}}const Qf=Symbol.for("v-scx"),Zf=()=>To(Qf);function mt(e,t,n){return xc(e,t,n)}function xc(e,t,n=dt){const{immediate:s,deep:o,flush:a,once:u}=n,f=Et({},n),h=t&&s||!t&&a!=="post";let y;if(Ls){if(a==="sync"){const S=Zf();y=S.__watcherHandles||(S.__watcherHandles=[])}else if(!h){const S=()=>{};return S.stop=En,S.resume=En,S.pause=En,S}}const m=zt;f.call=(S,M,B)=>cn(S,m,M,B);let w=!1;a==="post"?f.scheduler=S=>{S.i=m,Ht(S,m&&m.suspense)}:a!=="sync"&&(w=!0,f.scheduler=(S,M)=>{M?S():Qa(S)}),f.augmentJob=S=>{t&&(S.flags|=4),w&&(S.flags|=2,m&&(S.id=m.uid,S.i=m))};const C=Wf(e,t,f);return Ls&&(y?y.push(C):h&&C()),C}function ep(e,t,n){const s=this.proxy,o=wt(e)?e.includes(".")?Cc(s,e):()=>s[e]:e.bind(s,s);let a;Ge(t)?a=t:(a=t.handler,n=t);const u=Hs(this),f=xc(o,a.bind(s),n);return u(),f}function Cc(e,t){const n=t.split(".");return()=>{let s=e;for(let o=0;oe.__isTeleport,Er=e=>e&&(e.disabled||e.disabled===""),tp=e=>e&&(e.defer||e.defer===""),eu=e=>typeof SVGElement<"u"&&e instanceof SVGElement,tu=e=>typeof MathMLElement=="function"&&e instanceof MathMLElement,ka=(e,t)=>{const n=e&&e.to;return wt(n)?t?t(n):null:n},np={name:"Teleport",__isTeleport:!0,process(e,t,n,s,o,a,u,f,h,y){const{mc:m,pc:w,pbc:C,o:{insert:S,querySelector:M,createText:B,createComment:oe,parentNode:ae}}=y,T=Er(t.props);let{dynamicChildren:E}=t;const X=(te,O,j)=>{te.shapeFlag&16&&m(te.children,O,j,o,a,u,f,h)},de=(te=t)=>{const O=Er(te.props),j=te.target=ka(te.props,M),ce=xa(j,te,B,S);j&&(u!=="svg"&&eu(j)?u="svg":u!=="mathml"&&tu(j)&&(u="mathml"),o&&o.isCE&&(o.ce._teleportTargets||(o.ce._teleportTargets=new Set)).add(j),O||(X(te,j,ce),ms(te,!1)))},ie=te=>{const O=()=>{if(Zn.get(te)===O){if(Zn.delete(te),Er(te.props)){const j=ae(te.el)||n;X(te,j,te.anchor),ms(te,!0)}de(te)}};Zn.set(te,O),Ht(O,a)};if(e==null){const te=t.el=B(""),O=t.anchor=B("");if(S(te,n,s),S(O,n,s),tp(t.props)||a&&a.pendingBranch){ie(t);return}T&&(X(t,n,O),ms(t,!0)),de()}else{t.el=e.el;const te=t.anchor=e.anchor,O=Zn.get(e);if(O){O.flags|=8,Zn.delete(e),ie(t);return}t.targetStart=e.targetStart;const j=t.target=e.target,ce=t.targetAnchor=e.targetAnchor,ke=Er(e.props),J=ke?n:j,xe=ke?te:ce;if(u==="svg"||eu(j)?u="svg":(u==="mathml"||tu(j))&&(u="mathml"),E?(C(e.dynamicChildren,E,J,o,a,u,f),nl(e,t,!0)):h||w(e,t,J,xe,o,a,u,f,!1),T)ke?t.props&&e.props&&t.props.to!==e.props.to&&(t.props.to=e.props.to):So(t,n,te,y,1);else if((t.props&&t.props.to)!==(e.props&&e.props.to)){const Ue=ka(t.props,M);Ue&&(t.target=Ue,So(t,Ue,null,y,0))}else ke&&So(t,j,ce,y,1);ms(t,T)}},remove(e,t,n,{um:s,o:{remove:o}},a){const{shapeFlag:u,children:f,anchor:h,targetStart:y,targetAnchor:m,target:w,props:C}=e,S=Er(C),M=a||!S,B=Zn.get(e);if(B&&(B.flags|=8,Zn.delete(e)),w&&(o(y),o(m)),a&&o(h),!B&&(S||w)&&u&16)for(let oe=0;oe{e.isMounted=!0}),Ic(()=>{e.isUnmounting=!0}),e}const sn=[Function,Array],$c={mode:String,appear:Boolean,persisted:Boolean,onBeforeEnter:sn,onEnter:sn,onAfterEnter:sn,onEnterCancelled:sn,onBeforeLeave:sn,onLeave:sn,onAfterLeave:sn,onLeaveCancelled:sn,onBeforeAppear:sn,onAppear:sn,onAfterAppear:sn,onAppearCancelled:sn},sp={name:"BaseTransition",props:$c,setup(e,{slots:t}){const n=rl(),s=Ec();return()=>{const o=t.default&&Za(t.default(),!0),a=o&&o.length?Ac(o):n.subTree?Ee():void 0;if(!a)return;const u=ot(e),{mode:f}=u;if(s.isLeaving)return oa(a);const h=No(a);if(!h)return oa(a);let y=Ms(h,u,s,n,w=>y=w);h.type!==Ft&&lr(h,y);let m=n.subTree&&No(n.subTree);if(m&&m.type!==Ft&&!$r(m,h)&&Is(n.subTree)){let w=Ms(m,u,s,n);if(lr(m,w),f==="out-in"&&h.type!==Ft)return s.isLeaving=!0,w.afterLeave=()=>{s.isLeaving=!1,n.job.flags&8||n.update(),delete w.afterLeave,m=void 0},oa(a);f==="in-out"&&h.type!==Ft?w.delayLeave=(C,S,M)=>{const B=Pc(s,m);B[String(m.key)]=m,C[on]=()=>{S(),C[on]=void 0,delete y.delayedLeave,m=void 0},y.delayedLeave=()=>{M(),delete y.delayedLeave,m=void 0}}:m=void 0}else m&&(m=void 0);return a}}};function Ac(e){let t=e[0];if(e.length>1){for(const n of e)if(n.type!==Ft){t=n;break}}return t}const op=sp;function Pc(e,t){const{leavingVNodes:n}=e;let s=n.get(t.type);return s||(s=Object.create(null),n.set(t.type,s)),s}function Ms(e,t,n,s,o){const{appear:a,mode:u,persisted:f=!1,onBeforeEnter:h,onEnter:y,onAfterEnter:m,onEnterCancelled:w,onBeforeLeave:C,onLeave:S,onAfterLeave:M,onLeaveCancelled:B,onBeforeAppear:oe,onAppear:ae,onAfterAppear:T,onAppearCancelled:E}=t,X=String(e.key),de=Pc(n,e),ie=(j,ce)=>{j&&cn(j,s,9,ce)},te=(j,ce)=>{const ke=ce[1];ie(j,ce),Ke(j)?j.every(J=>J.length<=1)&&ke():j.length<=1&&ke()},O={mode:u,persisted:f,beforeEnter(j){let ce=h;if(!n.isMounted)if(a)ce=oe||h;else return;j[on]&&j[on](!0);const ke=de[X];if(ke&&$r(e,ke)){let J=ke.el[on];if(!J){const xe=Is(ke);J=xe&&xe.el[on]}J&&J()}ie(ce,[j])},enter(j){if(de[X]===e)return;let ce=y,ke=m,J=w;if(!n.isMounted)if(a)ce=ae||y,ke=T||m,J=E||w;else return;let xe=!1;j[hs]=rt=>{xe||(xe=!0,rt?ie(J,[j]):ie(ke,[j]),O.delayedLeave&&O.delayedLeave(),j[hs]=void 0)};const Ue=j[hs].bind(null,!1);ce?te(ce,[j,Ue]):Ue()},leave(j,ce){const ke=String(e.key);if(j[hs]&&j[hs](!0),n.isUnmounting)return ce();ie(C,[j]);let J=!1;j[on]=Ue=>{J||(J=!0,ce(),Ue?ie(B,[j]):ie(M,[j]),j[on]=void 0,de[ke]===e&&delete de[ke])};const xe=j[on].bind(null,!1);de[ke]=e,S?te(S,[j,xe]):xe()},clone(j){const ce=Ms(j,t,n,s,o);return o&&o(ce),ce}};return O}function oa(e){if(di(e))return e=ur(e),e.children=null,e}function No(e){if(!di(e))return ci(e.type)&&e.children?Ac(e.children):e;if(e.component)return e.component.subTree;const{shapeFlag:t,children:n}=e;if(n){if(t&16)return n[0];if(t&32&&Ge(n.default))return n.default()}}function lr(e,t){if(e.shapeFlag&6&&e.component){e.transition=t;const n=e.component.subTree;lr(ci(n.type)&&No(n)||n,t)}else if(e.shapeFlag&128)e.ssContent.transition=t.clone(e.ssContent),e.ssFallback.transition=t.clone(e.ssFallback);else if(e.transition=t,e.type===Le&&Ke(e.children)){const n=Kc(e.children,!1);n&&lr(n,t)}}function Za(e,t=!1,n){let s=[],o=0;for(let a=0;a1)for(let a=0;aks(B,t&&(Ke(t)?t[oe]:t),n,s,o));return}if(xs(s)&&!o){s.shapeFlag&512&&s.type.__asyncResolved&&s.component.subTree.component&&ks(e,t,n,s.component.subTree);return}const a=s.shapeFlag&4?vi(s.component):s.el,u=o?null:a,{i:f,r:h}=e,y=t&&t.r,m=f.refs===dt?f.refs={}:f.refs,w=f.setupState,C=ot(w),S=w===dt?Wu:B=>nu(m,B)?!1:it(C,B),M=(B,oe)=>!(oe&&nu(m,oe));if(y!=null&&y!==h){if(ru(t),wt(y))m[y]=null,S(y)&&(w[y]=null);else if(Nt(y)){const B=t;M(y,B.k)&&(y.value=null),B.k&&(m[B.k]=null)}}if(Ge(h))Us(h,f,12,[u,m]);else{const B=wt(h),oe=Nt(h);if(B||oe){const ae=()=>{if(e.f){const T=B?S(h)?w[h]:m[h]:M()||!e.k?h.value:m[e.k];if(o)Ke(T)&&Va(T,a);else if(Ke(T))T.includes(a)||T.push(a);else if(B)m[h]=[a],S(h)&&(w[h]=m[h]);else{const E=[a];M(h,e.k)&&(h.value=E),e.k&&(m[e.k]=E)}}else B?(m[h]=u,S(h)&&(w[h]=u)):oe&&(M(h,e.k)&&(h.value=u),e.k&&(m[e.k]=u))};if(u){const T=()=>{ae(),Vo.delete(e)};T.id=-1,Vo.set(e,T),Ht(T,n)}else ru(e),ae()}}}function ru(e){const t=Vo.get(e);t&&(t.flags|=8,Vo.delete(e))}ai().requestIdleCallback;ai().cancelIdleCallback;const xs=e=>!!e.type.__asyncLoader,di=e=>e.type.__isKeepAlive;function ip(e,t){Oc(e,"a",t)}function ap(e,t){Oc(e,"da",t)}function Oc(e,t,n=zt){const s=e.__wdc||(e.__wdc=()=>{let o=n;for(;o;){if(o.isDeactivated)return;o=o.parent}return e()});if(fi(t,s,n),n){let o=n.parent;for(;o&&o.parent;)di(o.parent.vnode)&&lp(s,t,n,o),o=o.parent}}function lp(e,t,n,s){const o=fi(t,e,s,!0);pr(()=>{Va(s[t],o)},n)}function fi(e,t,n=zt,s=!1){if(n){const o=n[e]||(n[e]=[]),a=t.__weh||(t.__weh=(...u)=>{An();const f=Hs(n),h=cn(t,n,e,u);return f(),Pn(),h});return s?o.unshift(a):o.push(a),a}}const qn=e=>(t,n=zt)=>{(!Ls||e==="sp")&&fi(e,(...s)=>t(...s),n)},up=qn("bm"),dn=qn("m"),cp=qn("bu"),Mc=qn("u"),Ic=qn("bum"),pr=qn("um"),dp=qn("sp"),fp=qn("rtg"),pp=qn("rtc");function hp(e,t=zt){fi("ec",e,t)}const vp=Symbol.for("v-ndc");function ct(e,t,n,s){let o;const a=n,u=Ke(e);if(u||wt(e)){const f=u&&ir(e);let h=!1,y=!1;f&&(h=!ln(e),y=Tn(e),e=li(e)),o=new Array(e.length);for(let m=0,w=e.length;mt(f,h,void 0,a));else{const f=Object.keys(e);o=new Array(f.length);for(let h=0,y=f.length;he?ed(e)?vi(e):Ca(e.parent):null,Cs=Et(Object.create(null),{$:e=>e,$el:e=>e.vnode.el,$data:e=>e.data,$props:e=>e.props,$attrs:e=>e.attrs,$slots:e=>e.slots,$refs:e=>e.refs,$parent:e=>Ca(e.parent),$root:e=>Ca(e.root),$host:e=>e.ce,$emit:e=>e.emit,$options:e=>Dc(e),$forceUpdate:e=>e.f||(e.f=()=>{Qa(e.update)}),$nextTick:e=>e.n||(e.n=ts.bind(e.proxy)),$watch:e=>ep.bind(e)}),ia=(e,t)=>e!==dt&&!e.__isScriptSetup&&it(e,t),mp={get({_:e},t){if(t==="__v_skip")return!0;const{ctx:n,setupState:s,data:o,props:a,accessCache:u,type:f,appContext:h}=e;if(t[0]!=="$"){const C=u[t];if(C!==void 0)switch(C){case 1:return s[t];case 2:return o[t];case 4:return n[t];case 3:return a[t]}else{if(ia(s,t))return u[t]=1,s[t];if(o!==dt&&it(o,t))return u[t]=2,o[t];if(it(a,t))return u[t]=3,a[t];if(n!==dt&&it(n,t))return u[t]=4,n[t];Sa&&(u[t]=0)}}const y=Cs[t];let m,w;if(y)return t==="$attrs"&&Kt(e.attrs,"get",""),y(e);if((m=f.__cssModules)&&(m=m[t]))return m;if(n!==dt&&it(n,t))return u[t]=4,n[t];if(w=h.config.globalProperties,it(w,t))return w[t]},set({_:e},t,n){const{data:s,setupState:o,ctx:a}=e;return ia(o,t)?(o[t]=n,!0):s!==dt&&it(s,t)?(s[t]=n,!0):it(e.props,t)||t[0]==="$"&&t.slice(1)in e?!1:(a[t]=n,!0)},has({_:{data:e,setupState:t,accessCache:n,ctx:s,appContext:o,props:a,type:u}},f){let h;return!!(n[f]||e!==dt&&f[0]!=="$"&&it(e,f)||ia(t,f)||it(a,f)||it(s,f)||it(Cs,f)||it(o.config.globalProperties,f)||(h=u.__cssModules)&&h[f])},defineProperty(e,t,n){return n.get!=null?e._.accessCache[t]=0:it(n,"value")&&this.set(e,t,n.value,null),Reflect.defineProperty(e,t,n)}};function su(e){return Ke(e)?e.reduce((t,n)=>(t[n]=null,t),{}):e}let Sa=!0;function yp(e){const t=Dc(e),n=e.proxy,s=e.ctx;Sa=!1,t.beforeCreate&&ou(t.beforeCreate,e,"bc");const{data:o,computed:a,methods:u,watch:f,provide:h,inject:y,created:m,beforeMount:w,mounted:C,beforeUpdate:S,updated:M,activated:B,deactivated:oe,beforeDestroy:ae,beforeUnmount:T,destroyed:E,unmounted:X,render:de,renderTracked:ie,renderTriggered:te,errorCaptured:O,serverPrefetch:j,expose:ce,inheritAttrs:ke,components:J,directives:xe,filters:Ue}=t;if(y&&gp(y,s,null),u)for(const Ye in u){const me=u[Ye];Ge(me)&&(s[Ye]=me.bind(n))}if(o){const Ye=o.call(n,n);lt(Ye)&&(e.data=Ya(Ye))}if(Sa=!0,a)for(const Ye in a){const me=a[Ye],Me=Ge(me)?me.bind(n,n):Ge(me.get)?me.get.bind(n,n):En,Fe=!Ge(me)&&Ge(me.set)?me.set.bind(n):En,De=at({get:Me,set:Fe});Object.defineProperty(s,Ye,{enumerable:!0,configurable:!0,get:()=>De.value,set:Ce=>De.value=Ce})}if(f)for(const Ye in f)jc(f[Ye],s,n,Ye);if(h){const Ye=Ge(h)?h.call(n):h;Reflect.ownKeys(Ye).forEach(me=>{Xf(me,Ye[me])})}m&&ou(m,e,"c");function We(Ye,me){Ke(me)?me.forEach(Me=>Ye(Me.bind(n))):me&&Ye(me.bind(n))}if(We(up,w),We(dn,C),We(cp,S),We(Mc,M),We(ip,B),We(ap,oe),We(hp,O),We(pp,ie),We(fp,te),We(Ic,T),We(pr,X),We(dp,j),Ke(ce))if(ce.length){const Ye=e.exposed||(e.exposed={});ce.forEach(me=>{Object.defineProperty(Ye,me,{get:()=>n[me],set:Me=>n[me]=Me,enumerable:!0})})}else e.exposed||(e.exposed={});de&&e.render===En&&(e.render=de),ke!=null&&(e.inheritAttrs=ke),J&&(e.components=J),xe&&(e.directives=xe),j&&Tc(e)}function gp(e,t,n=En){Ke(e)&&(e=Ea(e));for(const s in e){const o=e[s];let a;lt(o)?"default"in o?a=To(o.from||s,o.default,!0):a=To(o.from||s):a=To(o),Nt(a)?Object.defineProperty(t,s,{enumerable:!0,configurable:!0,get:()=>a.value,set:u=>a.value=u}):t[s]=a}}function ou(e,t,n){cn(Ke(e)?e.map(s=>s.bind(t.proxy)):e.bind(t.proxy),t,n)}function jc(e,t,n,s){let o=s.includes(".")?Cc(n,s):()=>n[s];if(wt(e)){const a=t[e];Ge(a)&&mt(o,a)}else if(Ge(e))mt(o,e.bind(n));else if(lt(e))if(Ke(e))e.forEach(a=>jc(a,t,n,s));else{const a=Ge(e.handler)?e.handler.bind(n):t[e.handler];Ge(a)&&mt(o,a,e)}}function Dc(e){const t=e.type,{mixins:n,extends:s}=t,{mixins:o,optionsCache:a,config:{optionMergeStrategies:u}}=e.appContext,f=a.get(t);let h;return f?h=f:!o.length&&!n&&!s?h=t:(h={},o.length&&o.forEach(y=>Bo(h,y,u,!0)),Bo(h,t,u)),lt(t)&&a.set(t,h),h}function Bo(e,t,n,s=!1){const{mixins:o,extends:a}=t;a&&Bo(e,a,n,!0),o&&o.forEach(u=>Bo(e,u,n,!0));for(const u in t)if(!(s&&u==="expose")){const f=bp[u]||n&&n[u];e[u]=f?f(e[u],t[u]):t[u]}return e}const bp={data:iu,props:au,emits:au,methods:ys,computed:ys,beforeCreate:qt,created:qt,beforeMount:qt,mounted:qt,beforeUpdate:qt,updated:qt,beforeDestroy:qt,beforeUnmount:qt,destroyed:qt,unmounted:qt,activated:qt,deactivated:qt,errorCaptured:qt,serverPrefetch:qt,components:ys,directives:ys,watch:_p,provide:iu,inject:wp};function iu(e,t){return t?e?function(){return Et(Ge(e)?e.call(this,this):e,Ge(t)?t.call(this,this):t)}:t:e}function wp(e,t){return ys(Ea(e),Ea(t))}function Ea(e){if(Ke(e)){const t={};for(let n=0;nt==="modelValue"||t==="model-value"?e.modelModifiers:e[`${t}Modifiers`]||e[`${hn(t)}Modifiers`]||e[`${dr(t)}Modifiers`];function Sp(e,t,...n){if(e.isUnmounted)return;const s=e.vnode.props||dt;let o=n;const a=t.startsWith("update:"),u=a&&Cp(s,t.slice(7));u&&(u.trim&&(o=n.map(m=>wt(m)?m.trim():m)),u.number&&(o=o.map(ii)));let f,h=s[f=Zi(t)]||s[f=Zi(hn(t))];!h&&a&&(h=s[f=Zi(dr(t))]),h&&cn(h,e,6,o);const y=s[f+"Once"];if(y){if(!e.emitted)e.emitted={};else if(e.emitted[f])return;e.emitted[f]=!0,cn(y,e,6,o)}}const Ep=new WeakMap;function Lc(e,t,n=!1){const s=n?Ep:t.emitsCache,o=s.get(e);if(o!==void 0)return o;const a=e.emits;let u={},f=!1;if(!Ge(e)){const h=y=>{const m=Lc(y,t,!0);m&&(f=!0,Et(u,m))};!n&&t.mixins.length&&t.mixins.forEach(h),e.extends&&h(e.extends),e.mixins&&e.mixins.forEach(h)}return!a&&!f?(lt(e)&&s.set(e,null),null):(Ke(a)?a.forEach(h=>u[h]=null):Et(u,a),lt(e)&&s.set(e,u),u)}function pi(e,t){return!e||!ri(t)?!1:(t=t.slice(2),t=t==="Once"?t:t.replace(/Once$/,""),it(e,t[0].toLowerCase()+t.slice(1))||it(e,dr(t))||it(e,t))}function lu(e){const{type:t,vnode:n,proxy:s,withProxy:o,propsOptions:[a],slots:u,attrs:f,emit:h,render:y,renderCache:m,props:w,data:C,setupState:S,ctx:M,inheritAttrs:B}=e,oe=Fo(e);let ae,T;try{if(n.shapeFlag&4){const X=o||s,de=X;ae=xn(y.call(de,X,m,w,S,C,M)),T=f}else{const X=t;ae=xn(X.length>1?X(w,{attrs:f,slots:u,emit:h}):X(w,null)),T=t.props?f:$p(f)}}catch(X){Tr.length=0,ui(X,e,1),ae=Oe(Ft)}let E=ae;if(T&&B!==!1){const X=Object.keys(T),{shapeFlag:de}=E;X.length&&de&7&&(a&&X.some(si)&&(T=Ap(T,a)),E=ur(E,T,!1,!0))}if(n.dirs&&(E=ur(E,null,!1,!0),E.dirs=E.dirs?E.dirs.concat(n.dirs):n.dirs),n.transition){const X=ci(E.type)&&No(E)||E;lr(X,n.transition)}return ae=E,Fo(oe),ae}function Kc(e,t=!0){let n;for(let s=0;s{let t;for(const n in e)(n==="class"||n==="style"||ri(n))&&((t||(t={}))[n]=e[n]);return t},Ap=(e,t)=>{const n={};for(const s in e)(!si(s)||!(s.slice(9)in t))&&(n[s]=e[s]);return n};function Pp(e,t,n){const{props:s,children:o,component:a}=e,{props:u,children:f,patchFlag:h}=t,y=a.emitsOptions;if(t.dirs||t.transition)return!0;if(n&&h>=0){if(h&1024)return!0;if(h&16)return s?uu(s,u,y):!!u;if(h&8){const m=t.dynamicProps;for(let w=0;wObject.create(Nc),Bc=e=>Object.getPrototypeOf(e)===Nc;function Op(e,t,n,s=!1){const o={},a=Vc();e.propsDefaults=Object.create(null),Uc(e,t,o,a);for(const u in e.propsOptions[0])u in o||(o[u]=void 0);n?e.props=s?o:Kf(o):e.type.props?e.props=o:e.props=a,e.attrs=a}function Mp(e,t,n,s){const{props:o,attrs:a,vnode:{patchFlag:u}}=e,f=ot(o),[h]=e.propsOptions;let y=!1;if((s||u>0)&&!(u&16)){if(u&8){const m=e.vnode.dynamicProps;for(let w=0;w{h=!0;const[C,S]=qc(w,t,!0);Et(u,C),S&&f.push(...S)};!n&&t.mixins.length&&t.mixins.forEach(m),e.extends&&m(e.extends),e.mixins&&e.mixins.forEach(m)}if(!a&&!h)return lt(e)&&s.set(e,Ar),Ar;if(Ke(a))for(let m=0;me==="_"||e==="_ctx"||e==="$stable",tl=e=>Ke(e)?e.map(xn):[xn(e)],jp=(e,t,n)=>{if(t._n)return t;const s=fr((...o)=>tl(t(...o)),n);return s._c=!1,s},Hc=(e,t,n)=>{const s=e._ctx;for(const o in e){if(el(o))continue;const a=e[o];if(Ge(a))t[o]=jp(o,a,s);else if(a!=null){const u=tl(a);t[o]=()=>u}}},Wc=(e,t)=>{const n=tl(t);e.slots.default=()=>n},zc=(e,t,n)=>{for(const s in t)(n||!el(s))&&(e[s]=t[s])},Dp=(e,t,n)=>{const s=e.slots=Vc();if(e.vnode.shapeFlag&32){const o=t._;o?(zc(s,t,n),n&&Xu(s,"_",o,!0)):Hc(t,s)}else t&&Wc(e,t)},Rp=(e,t,n)=>{const{vnode:s,slots:o}=e;let a=!0,u=dt;if(s.shapeFlag&32){const f=t._;f?n&&f===1?a=!1:zc(o,t,n):(a=!t.$stable,Hc(t,o)),u=t}else t&&(Wc(e,t),u={default:1});if(a)for(const f in o)!el(f)&&u[f]==null&&delete o[f]},Ht=Vp;function Lp(e){return Kp(e)}function Kp(e,t){const n=ai();n.__VUE__=!0;const{insert:s,remove:o,patchProp:a,createElement:u,createText:f,createComment:h,setText:y,setElementText:m,parentNode:w,nextSibling:C,setScopeId:S=En,insertStaticContent:M}=e,B=(k,_,x,G=null,ne=null,ue=null,ge=void 0,ve=null,le=!!_.dynamicChildren)=>{if(k===_)return;k&&!$r(k,_)&&(G=ft(k),Ce(k,ne,ue,!0),k=null),_.patchFlag===-2&&(le=!1,_.dynamicChildren=null),_.dynamicChildren&&k&&k.dynamicChildren&&k.dynamicChildren.hasOnce&&(_.dynamicChildren===Ar&&(_.dynamicChildren=[]),_.dynamicChildren.hasOnce=!0);const{type:H,ref:W,shapeFlag:Y}=_;switch(H){case hi:oe(k,_,x,G);break;case Ft:ae(k,_,x,G);break;case Oo:k==null&&T(_,x,G,ge);break;case Le:J(k,_,x,G,ne,ue,ge,ve,le);break;default:Y&1?de(k,_,x,G,ne,ue,ge,ve,le):Y&6?xe(k,_,x,G,ne,ue,ge,ve,le):(Y&64||Y&128)&&H.process(k,_,x,G,ne,ue,ge,ve,le,Jt)}W!=null&&ne?ks(W,k&&k.ref,ue,_||k,!_):W==null&&k&&k.ref!=null&&ks(k.ref,null,ue,k,!0)},oe=(k,_,x,G)=>{if(k==null)s(_.el=f(_.children),x,G);else{const ne=_.el=k.el;_.children!==k.children&&y(ne,_.children)}},ae=(k,_,x,G)=>{k==null?s(_.el=h(_.children||""),x,G):_.el=k.el},T=(k,_,x,G)=>{[k.el,k.anchor]=M(k.children,_,x,G,k.el,k.anchor)},E=({el:k,anchor:_},x,G)=>{let ne;for(;k&&k!==_;)ne=C(k),s(k,x,G),k=ne;s(_,x,G)},X=({el:k,anchor:_})=>{let x;for(;k&&k!==_;)x=C(k),o(k),k=x;o(_)},de=(k,_,x,G,ne,ue,ge,ve,le)=>{if(_.type==="svg"?ge="svg":_.type==="math"&&(ge="mathml"),k==null)ie(_,x,G,ne,ue,ge,ve,le);else{const H=k.el&&k.el._isVueCE?k.el:null;try{H&&H._beginPatch(),j(k,_,ne,ue,ge,ve,le)}finally{H&&H._endPatch()}}},ie=(k,_,x,G,ne,ue,ge,ve)=>{let le,H;const{props:W,shapeFlag:Y,transition:Ae,dirs:Ne}=k;if(le=k.el=u(k.type,ue,W&&W.is,W),Y&8?m(le,k.children):Y&16&&O(k.children,le,null,G,ne,aa(k,ue),ge,ve),Ne&&kr(k,null,G,"created"),te(le,k,k.scopeId,ge,G),W){for(const Xe in W)Xe!=="value"&&!bs(Xe)&&a(le,Xe,null,W[Xe],ue,G);"value"in W&&a(le,"value",null,W.value,ue),(H=W.onVnodeBeforeMount)&&gn(H,G,k)}Ne&&kr(k,null,G,"beforeMount");const Qe=Fp(ne,Ae);Qe&&Ae.beforeEnter(le),s(le,_,x),((H=W&&W.onVnodeMounted)||Qe||Ne)&&Ht(()=>{try{H&&gn(H,G,k),Qe&&Ae.enter(le),Ne&&kr(k,null,G,"mounted")}finally{}},ne)},te=(k,_,x,G,ne)=>{if(x&&S(k,x),G)for(let ue=0;ue{for(let H=le;H{const ve=_.el=k.el;let{patchFlag:le,dynamicChildren:H,dirs:W}=_;le|=k.patchFlag&16;const Y=k.props||dt,Ae=_.props||dt;let Ne;if(x&&xr(x,!1),(Ne=Ae.onVnodeBeforeUpdate)&&gn(Ne,x,_,k),W&&kr(_,k,x,"beforeUpdate"),x&&xr(x,!0),H&&(!k.dynamicChildren||k.dynamicChildren.length!==H.length)&&(le=0,ge=!1,H=null),(Y.innerHTML&&Ae.innerHTML==null||Y.textContent&&Ae.textContent==null)&&m(ve,""),H?ce(k.dynamicChildren,H,ve,x,G,aa(_,ne),ue):ge||me(k,_,ve,null,x,G,aa(_,ne),ue,!1),le>0){if(le&16)ke(ve,Y,Ae,x,ne);else if(le&2&&Y.class!==Ae.class&&a(ve,"class",null,Ae.class,ne),le&4&&a(ve,"style",Y.style,Ae.style,ne),le&8){const Qe=_.dynamicProps;for(let Xe=0;Xe{Ne&&gn(Ne,x,_,k),W&&kr(_,k,x,"updated")},G)},ce=(k,_,x,G,ne,ue,ge)=>{for(let ve=0;ve<_.length;ve++){const le=k[ve],H=_[ve],W=le.el||Aa(le),Y=W&&(le.type===Le||!$r(le,H)||le.shapeFlag&198)?w(W):x;B(le,H,Y,null,G,ne,ue,ge,!0)}},ke=(k,_,x,G,ne)=>{if(_!==x){if(_!==dt)for(const ue in _)!bs(ue)&&!(ue in x)&&a(k,ue,_[ue],null,ne,G);for(const ue in x){if(bs(ue))continue;const ge=x[ue],ve=_[ue];ge!==ve&&ue!=="value"&&a(k,ue,ve,ge,ne,G)}"value"in x&&a(k,"value",_.value,x.value,ne)}},J=(k,_,x,G,ne,ue,ge,ve,le)=>{const H=_.el=k?k.el:f(""),W=_.anchor=k?k.anchor:f("");let{patchFlag:Y,dynamicChildren:Ae,slotScopeIds:Ne}=_;Ne&&(ve=ve?ve.concat(Ne):Ne),k==null?(s(H,x,G),s(W,x,G),O(_.children||[],x,W,ne,ue,ge,ve,le)):Y>0&&Y&64&&Ae&&k.dynamicChildren&&k.dynamicChildren.length===Ae.length?(ce(k.dynamicChildren,Ae,x,ne,ue,ge,ve),(_.key!=null||ne&&_===ne.subTree)&&nl(k,_,!0)):me(k,_,x,W,ne,ue,ge,ve,le)},xe=(k,_,x,G,ne,ue,ge,ve,le)=>{_.slotScopeIds=ve,k==null?_.shapeFlag&512?ne.ctx.activate(_,x,G,ge,le):Ue(_,x,G,ne,ue,ge,le):rt(k,_,le)},Ue=(k,_,x,G,ne,ue,ge)=>{const ve=k.component=Gp(k,G,ne);if(di(k)&&(ve.ctx.renderer=Jt),Yp(ve,!1,ge),ve.asyncDep){if(ne&&ne.registerDep(ve,We,ge,ue),!k.el){const le=ve.subTree=Oe(Ft);ae(null,le,_,x),k.placeholder=le.el}}else We(ve,k,_,x,ne,ue,ge)},rt=(k,_,x)=>{const G=_.component=k.component;if(Pp(k,_,x))if(G.asyncDep&&!G.asyncResolved){_.el=k.el,_.placeholder=k.placeholder,Ye(G,_,x);return}else G.next=_,G.update();else _.el=k.el,_.placeholder=k.placeholder,G.vnode=_},We=(k,_,x,G,ne,ue,ge)=>{const ve=()=>{if(k.isMounted){let{next:Y,bu:Ae,u:Ne,parent:Qe,vnode:Xe}=k;{const Bt=Gc(k);if(Bt){Y&&(Y.el=Xe.el,Ye(k,Y,ge)),Bt.asyncDep.then(()=>{Ht(()=>{k.isUnmounted||H()},ne)});return}}let Ze=Y,yt;xr(k,!1),Y?(Y.el=Xe.el,Ye(k,Y,ge)):Y=Xe,Ae&&Po(Ae),(yt=Y.props&&Y.props.onVnodeBeforeUpdate)&&gn(yt,Qe,Y,Xe),xr(k,!0);const _t=lu(k),Xt=k.subTree;k.subTree=_t,B(Xt,_t,w(Xt.el),ft(Xt),k,ne,ue),Y.el=_t.el,Ze===null&&Tp(k,_t.el),Ne&&Ht(Ne,ne),(yt=Y.props&&Y.props.onVnodeUpdated)&&Ht(()=>gn(yt,Qe,Y,Xe),ne)}else{let Y;const{el:Ae,props:Ne}=_,{bm:Qe,m:Xe,parent:Ze,root:yt,type:_t}=k,Xt=xs(_);xr(k,!1),Qe&&Po(Qe),!Xt&&(Y=Ne&&Ne.onVnodeBeforeMount)&&gn(Y,Ze,_),xr(k,!0);{yt.ce&&yt.ce._hasShadowRoot()&&yt.ce._injectChildStyle(_t,k.parent?k.parent.type:void 0);const Bt=k.subTree=lu(k);B(null,Bt,x,G,k,ne,ue),_.el=Bt.el}if(Xe&&Ht(Xe,ne),!Xt&&(Y=Ne&&Ne.onVnodeMounted)){const Bt=_;Ht(()=>gn(Y,Ze,Bt),ne)}(_.shapeFlag&256||Ze&&xs(Ze.vnode)&&Ze.vnode.shapeFlag&256)&&k.a&&Ht(k.a,ne),k.isMounted=!0,_=x=G=null}};k.scope.on();const le=k.effect=new tc(ve);k.scope.off();const H=k.update=le.run.bind(le),W=k.job=le.runIfDirty.bind(le);W.i=k,W.id=k.uid,le.scheduler=()=>Qa(W),xr(k,!0),H()},Ye=(k,_,x)=>{_.component=k;const G=k.vnode.props;k.vnode=_,k.next=null,Mp(k,_.props,G,x),Rp(k,_.children,x),An(),bc(k),Pn()},me=(k,_,x,G,ne,ue,ge,ve,le=!1)=>{const H=k&&k.children,W=k?k.shapeFlag:0,Y=_.children,{patchFlag:Ae,shapeFlag:Ne}=_;if(Ae>0){if(Ae&128){Fe(H,Y,x,G,ne,ue,ge,ve,le);return}else if(Ae&256){Me(H,Y,x,G,ne,ue,ge,ve,le);return}}Ne&8?(W&16&&Ve(H,ne,ue),Y!==H&&m(x,Y)):W&16?Ne&16?Fe(H,Y,x,G,ne,ue,ge,ve,le):Ve(H,ne,ue,!0):(W&8&&m(x,""),Ne&16&&O(Y,x,G,ne,ue,ge,ve,le))},Me=(k,_,x,G,ne,ue,ge,ve,le)=>{k=k||Ar,_=_||Ar;const H=k.length,W=_.length,Y=Math.min(H,W);let Ae;for(Ae=0;AeW?Ve(k,ne,ue,!0,!1,Y):O(_,x,G,ne,ue,ge,ve,le,Y)},Fe=(k,_,x,G,ne,ue,ge,ve,le)=>{let H=0;const W=_.length;let Y=k.length-1,Ae=W-1;for(;H<=Y&&H<=Ae;){const Ne=k[H],Qe=_[H]=le?Dn(_[H]):xn(_[H]);if($r(Ne,Qe))B(Ne,Qe,x,null,ne,ue,ge,ve,le);else break;H++}for(;H<=Y&&H<=Ae;){const Ne=k[Y],Qe=_[Ae]=le?Dn(_[Ae]):xn(_[Ae]);if($r(Ne,Qe))B(Ne,Qe,x,null,ne,ue,ge,ve,le);else break;Y--,Ae--}if(H>Y){if(H<=Ae){const Ne=Ae+1,Qe=NeAe)for(;H<=Y;)Ce(k[H],ne,ue,!0),H++;else{const Ne=H,Qe=H,Xe=new Map;for(H=Qe;H<=Ae;H++){const Ot=_[H]=le?Dn(_[H]):xn(_[H]);Ot.key!=null&&Xe.set(Ot.key,H)}let Ze,yt=0;const _t=Ae-Qe+1;let Xt=!1,Bt=0;const Zt=new Array(_t);for(H=0;H<_t;H++)Zt[H]=0;for(H=Ne;H<=Y;H++){const Ot=k[H];if(yt>=_t){Ce(Ot,ne,ue,!0);continue}let $t;if(Ot.key!=null)$t=Xe.get(Ot.key);else for(Ze=Qe;Ze<=Ae;Ze++)if(Zt[Ze-Qe]===0&&$r(Ot,_[Ze])){$t=Ze;break}$t===void 0?Ce(Ot,ne,ue,!0):(Zt[$t-Qe]=H+1,$t>=Bt?Bt=$t:Xt=!0,B(Ot,_[$t],x,null,ne,ue,ge,ve,le),yt++)}const hr=Xt?Np(Zt):Ar;for(Ze=hr.length-1,H=_t-1;H>=0;H--){const Ot=Qe+H,$t=_[Ot],Ie=_[Ot+1],Hn=Ot+1{const{el:ue,type:ge,transition:ve,children:le,shapeFlag:H}=k;if(H&6){De(k.component.subTree,_,x,G);return}if(H&128){k.suspense.move(_,x,G);return}if(H&64){ge.move(k,_,x,Jt);return}if(ge===Le){s(ue,_,x);for(let Y=0;Yve.enter(ue),ne));else{const{leave:Y,delayLeave:Ae,afterLeave:Ne}=ve,Qe=()=>{k.ctx.isUnmounted?o(ue):s(ue,_,x)},Xe=()=>{const Ze=ue._isLeaving||!!ue[on];ue._isLeaving&&ue[on](!0),ve.persisted&&!Ze?Qe():Y(ue,()=>{Qe(),Ne&&Ne()})};Ae?Ae(ue,Qe,Xe):Xe()}else s(ue,_,x)},Ce=(k,_,x,G=!1,ne=!1)=>{const{type:ue,props:ge,ref:ve,children:le,dynamicChildren:H,shapeFlag:W,patchFlag:Y,dirs:Ae,cacheIndex:Ne,memo:Qe}=k;if((Y===-2||H&&H.hasOnce)&&(ne=!1),ve!=null&&(An(),ks(ve,null,x,k,!0),Pn()),Ne!=null&&(!k.ctx||k.ctx===_)&&(_.renderCache[Ne]=void 0),W&256){_.ctx.deactivate(k);return}const Xe=W&1&&Ae,Ze=!xs(k);let yt;if(Ze&&(yt=ge&&ge.onVnodeBeforeUnmount)&&gn(yt,_,k),W&6)_e(k.component,x,G);else{if(W&128){k.suspense.unmount(x,G);return}Xe&&kr(k,null,_,"beforeUnmount"),W&64?k.type.remove(k,_,x,Jt,G):H&&!H.hasOnce&&(ue!==Le||Y>0&&Y&64)?Ve(H,_,x,!1,!0):(ue===Le&&Y&384||!ne&&W&16)&&Ve(le,_,x),G&&Q(k)}const _t=Qe!=null&&Ne==null;(Ze&&(yt=ge&&ge.onVnodeUnmounted)||Xe||_t)&&Ht(()=>{yt&&gn(yt,_,k),Xe&&kr(k,null,_,"unmounted"),_t&&(k.el=null)},x)},Q=k=>{const{type:_,el:x,anchor:G,transition:ne}=k,ue=_===Le;if(ue&&!ne){Z(x,G);return}if(_===Oo){X(k),ne&&!ne.persisted&&ne.afterLeave&&ne.afterLeave();return}const ge=ue?Is(k):k,ve=()=>{ue?w(x)&&Z(x,G):o(x),ne&&!ne.persisted&&ne.afterLeave&&ne.afterLeave()};if(ge&&ge.shapeFlag&1&&ne&&!ne.persisted){const{leave:le,delayLeave:H}=ne,W=ge.el,Y=()=>le(W,ve);H?H(W,ve,Y):Y()}else ve()},Z=(k,_)=>{let x;for(;k!==_;)x=C(k),o(k),k=x;o(_)},_e=(k,_,x)=>{const{bum:G,scope:ne,job:ue,subTree:ge,um:ve,m:le,a:H}=k;du(le),du(H),G&&Po(G),ne.stop(),ue?(ue.flags|=8,Ce(ge,k,_,x)):k.vnode.el&&ge&&(ge.transition=k.vnode.transition,Ce(ge,k,_,x)),ve&&Ht(ve,_),Ht(()=>{k.isUnmounted=!0},_)},Ve=(k,_,x,G=!1,ne=!1,ue=0)=>{for(let ge=ue;ge{if(k.shapeFlag&6)return ft(k.component.subTree);if(k.shapeFlag&128)return k.suspense.next();const _=C(k.anchor||k.el),x=_&&_[Sc];return x?C(x):_},Yt=(k,_,x)=>{const G=k&&_._vnode?void 0:k&&k.component?k.component.uid:zp();Jf(()=>{k==null?_._vnode&&Ce(_._vnode,null,null,!0):B(_._vnode||null,k,_,null,null,null,x),_._vnode=k},G)},Jt={p:B,um:Ce,m:De,r:Q,mt:Ue,mc:O,pc:me,pbc:ce,n:ft,o:e};return{render:Yt,hydrate:void 0,createApp:xp(Yt)}}function aa({type:e,props:t},n){return n==="svg"&&e==="foreignObject"||n==="mathml"&&e==="annotation-xml"&&t&&t.encoding&&t.encoding.includes("html")?void 0:n}function xr({effect:e,job:t},n){n?(e.flags|=32,t.flags|=4):(e.flags&=-33,t.flags&=-5)}function Fp(e,t){return(!e||e&&!e.pendingBranch)&&t&&!t.persisted}function nl(e,t,n=!1){const s=e.children,o=t.children;if(Ke(s)&&Ke(o))for(let a=0;a>1,e[n[f]]0&&(t[s]=n[a-1]),n[a]=s)}}for(a=n.length,u=n[a-1];a-- >0;)n[a]=u,u=t[u];return n}function Gc(e){const t=e.subTree.component;if(t)return t.asyncDep&&!t.asyncResolved?t:Gc(t)}function du(e){if(e)for(let t=0;te.__isSuspense;function Vp(e,t){t&&t.pendingBranch?Ke(e)?t.effects.push(...e):t.effects.push(e):Yf(e)}const Le=Symbol.for("v-fgt"),hi=Symbol.for("v-txt"),Ft=Symbol.for("v-cmt"),Oo=Symbol.for("v-stc"),Tr=[];let rn=null;function F(e=!1){Tr.push(rn=e?null:[])}function Jc(){Tr.pop(),rn=Tr[Tr.length-1]||null}let js=1;function Uo(e,t=!1){js+=e,e<0&&rn&&t&&(rn.hasOnce=!0)}function Xc(e){return e.dynamicChildren=js>0?rn||Ar:null,Jc(),js>0&&rn&&rn.push(e),e}function q(e,t,n,s,o,a){return Xc(c(e,t,n,s,o,a,!0))}function It(e,t,n,s,o){return Xc(Oe(e,t,n,s,o,!0))}function Ds(e){return e?e.__v_isVNode===!0:!1}function $r(e,t){return e.type===t.type&&e.key===t.key}const Qc=({key:e})=>e??null,Mo=({ref:e,ref_key:t,ref_for:n})=>(typeof e=="number"&&(e=""+e),e!=null?wt(e)||Nt(e)||Ge(e)?{i:an,r:e,k:t,f:!!n}:e:null);function c(e,t=null,n=null,s=0,o=null,a=e===Le?0:1,u=!1,f=!1){const h={__v_isVNode:!0,__v_skip:!0,type:e,props:t,key:t&&Qc(t),ref:t&&Mo(t),scopeId:kc,slotScopeIds:null,children:n,component:null,suspense:null,ssContent:null,ssFallback:null,dirs:null,transition:null,el:null,anchor:null,target:null,targetStart:null,targetAnchor:null,staticCount:0,shapeFlag:a,patchFlag:s,dynamicProps:o,dynamicChildren:null,appContext:null,ctx:an};return f?(qo(h,n),a&128&&e.normalize(h)):n&&(h.shapeFlag|=wt(n)?8:16),js>0&&!u&&rn&&(h.patchFlag>0||a&6)&&h.patchFlag!==32&&rn.push(h),h}const Oe=Bp;function Bp(e,t=null,n=null,s=0,o=null,a=!1){if((!e||e===vp)&&(e=Ft),Ds(e)){const f=ur(e,t,!0);return n&&qo(f,n),js>0&&!a&&rn&&(f.shapeFlag&6?rn[rn.indexOf(e)]=f:rn.push(f)),f.patchFlag=-2,f}if(Zp(e)&&(e=e.__vccOpts),t){t=Up(t);let{class:f,style:h}=t;f&&!wt(f)&&(t.class=tt(f)),lt(h)&&(Xa(h)&&!Ke(h)&&(h=Et({},h)),t.style=or(h))}const u=wt(e)?1:Yc(e)?128:ci(e)?64:lt(e)?4:Ge(e)?2:0;return c(e,t,n,s,o,u,a,!0)}function Up(e){return e?Xa(e)||Bc(e)?Et({},e):e:null}function ur(e,t,n=!1,s=!1){const{props:o,ref:a,patchFlag:u,children:f,transition:h}=e,y=t?Hp(o||{},t):o,m={__v_isVNode:!0,__v_skip:!0,type:e.type,props:y,key:y&&Qc(y),ref:t&&t.ref?n&&a?Ke(a)?a.concat(Mo(t)):[a,Mo(t)]:Mo(t):a,scopeId:e.scopeId,slotScopeIds:e.slotScopeIds,children:f,target:e.target,targetStart:e.targetStart,targetAnchor:e.targetAnchor,staticCount:e.staticCount,shapeFlag:e.shapeFlag,patchFlag:t&&e.type!==Le?u===-1?16:u|16:u,dynamicProps:e.dynamicProps,dynamicChildren:e.dynamicChildren,appContext:e.appContext,dirs:e.dirs,transition:h,component:e.component,suspense:e.suspense,ssContent:e.ssContent&&ur(e.ssContent),ssFallback:e.ssFallback&&ur(e.ssFallback),placeholder:e.placeholder,el:e.el,anchor:e.anchor,ctx:e.ctx,ce:e.ce,cacheIndex:e.cacheIndex};return h&&s&&lr(m,h.clone(m)),m}function nn(e=" ",t=0){return Oe(hi,null,e,t)}function qp(e,t){const n=Oe(Oo,null,e);return n.staticCount=t,n}function Ee(e="",t=!1){return t?(F(),It(Ft,null,e)):Oe(Ft,null,e)}function xn(e){return e==null||typeof e=="boolean"?Oe(Ft):Ke(e)?Oe(Le,null,e.slice()):Ds(e)?Dn(e):Oe(hi,null,String(e))}function Dn(e){return e.el===null&&e.patchFlag!==-1||e.memo?e:ur(e)}function qo(e,t){let n=0;const{shapeFlag:s}=e;if(t==null)t=null;else if(Ke(t))n=16;else if(typeof t=="object")if(s&65){const o=t.default;o&&(o._c&&(o._d=!1),qo(e,o()),o._c&&(o._d=!0));return}else{n=32;const o=t._;!o&&!Bc(t)?t._ctx=an:o===3&&an&&(an.slots._===1?t._=1:(t._=2,e.patchFlag|=1024))}else if(Ge(t)){if(s&65){qo(e,{default:t});return}t={default:t,_ctx:an},n=32}else t=String(t),s&64?(n=16,t=[nn(t)]):n=8;e.children=t,e.shapeFlag|=n}function Hp(...e){const t={};for(let n=0;nzt||an;let Ho,Rs;{const e=ai(),t=(n,s)=>{let o;return(o=e[n])||(o=e[n]=[]),o.push(s),a=>{o.length>1?o.forEach(u=>u(a)):o[0](a)}};Ho=t("__VUE_INSTANCE_SETTERS__",n=>zt=n),Rs=t("__VUE_SSR_SETTERS__",n=>Ls=n)}const Hs=e=>{const t=zt;return Ho(e),e.scope.on(),()=>{e.scope.off(),Ho(t)}},fu=()=>{zt&&zt.scope.off(),Ho(null)};function ed(e){return e.vnode.shapeFlag&4}let Ls=!1;function Yp(e,t=!1,n=!1){t&&Rs(t);const{props:s,children:o}=e.vnode,a=ed(e);Op(e,s,a,t),Dp(e,o,n||t);const u=a?Jp(e,t):void 0;return t&&Rs(!1),u}function Jp(e,t){const n=e.type;e.accessCache=Object.create(null),e.proxy=new Proxy(e.ctx,mp);const{setup:s}=n;if(s){An();const o=e.setupContext=s.length>1?Qp(e):null,a=Hs(e),u=Us(s,e,0,[e.props,o]),f=zu(u);if(Pn(),a(),(f||e.sp)&&!xs(e)&&Tc(e),f){if(u.then(fu,fu),t)return u.then(h=>{Rs(!0);try{pu(e,h,t)}finally{Rs(!1)}}).catch(h=>{ui(h,e,0)});e.asyncDep=u}else pu(e,u)}else td(e)}function pu(e,t,n){Ge(t)?e.type.__ssrInlineRender?e.ssrRender=t:e.render=t:lt(t)&&(e.setupState=mc(t)),td(e)}function td(e,t,n){const s=e.type;e.render||(e.render=s.render||En);{const o=Hs(e);An();try{yp(e)}finally{Pn(),o()}}}const Xp={get(e,t){return Kt(e,"get",""),e[t]}};function Qp(e){const t=n=>{e.exposed=n||{}};return{attrs:new Proxy(e.attrs,Xp),slots:e.slots,emit:e.emit,expose:t}}function vi(e){return e.exposed?e.exposeProxy||(e.exposeProxy=new Proxy(mc(Ff(e.exposed)),{get(t,n){if(n in t)return t[n];if(n in Cs)return Cs[n](e)},has(t,n){return n in t||n in Cs}})):e.proxy}function Zp(e){return Ge(e)&&"__vccOpts"in e}const at=(e,t)=>qf(e,t,Ls);function eh(e,t,n){try{Uo(-1);const s=arguments.length;return s===2?lt(t)&&!Ke(t)?Ds(t)?Oe(e,null,[t]):Oe(e,t):Oe(e,null,t):(s>3?n=Array.prototype.slice.call(arguments,2):s===3&&Ds(n)&&(n=[n]),Oe(e,t,n))}finally{Uo(1)}}const th="3.5.44";/** -* @vue/runtime-dom v3.5.44 -* (c) 2018-present Yuxi (Evan) You and Vue contributors -* @license MIT -**/let Pa;const hu=typeof window<"u"&&window.trustedTypes;if(hu)try{Pa=hu.createPolicy("vue",{createHTML:e=>e})}catch{}const nd=Pa?e=>Pa.createHTML(e):e=>e,nh="http://www.w3.org/2000/svg",rh="http://www.w3.org/1998/Math/MathML",jn=typeof document<"u"?document:null,vu=jn&&jn.createElement("template"),sh={insert:(e,t,n)=>{t.insertBefore(e,n||null)},remove:e=>{const t=e.parentNode;t&&t.removeChild(e)},createElement:(e,t,n,s)=>{const o=t==="svg"?jn.createElementNS(nh,e):t==="mathml"?jn.createElementNS(rh,e):n?jn.createElement(e,{is:n}):jn.createElement(e);return e==="select"&&s&&s.multiple!=null&&o.setAttribute("multiple",s.multiple),o},createText:e=>jn.createTextNode(e),createComment:e=>jn.createComment(e),setText:(e,t)=>{e.nodeValue=t},setElementText:(e,t)=>{e.textContent=t},parentNode:e=>e.parentNode,nextSibling:e=>e.nextSibling,querySelector:e=>jn.querySelector(e),setScopeId(e,t){e.setAttribute(t,"")},insertStaticContent(e,t,n,s,o,a){const u=n?n.previousSibling:t.lastChild;if(o&&(o===a||o.nextSibling))for(;t.insertBefore(o.cloneNode(!0),n),!(o===a||!(o=o.nextSibling)););else{vu.innerHTML=nd(s==="svg"?`${e}`:s==="mathml"?`${e}`:e);const f=vu.content;if(s==="svg"||s==="mathml"){const h=f.firstChild;for(;h.firstChild;)f.appendChild(h.firstChild);f.removeChild(h)}t.insertBefore(f,n)}return[u?u.nextSibling:t.firstChild,n?n.previousSibling:t.lastChild]}},Qn="transition",vs="animation",Jr=Symbol("_vtc"),rd={name:String,type:String,css:{type:Boolean,default:!0},duration:[String,Number,Object],enterFromClass:String,enterActiveClass:String,enterToClass:String,appearFromClass:String,appearActiveClass:String,appearToClass:String,leaveFromClass:String,leaveActiveClass:String,leaveToClass:String},sd=Et({},$c,rd),oh=e=>(e.displayName="Transition",e.props=sd,e),ns=oh((e,{slots:t})=>eh(op,od(e),t)),Cr=(e,t=[])=>{Ke(e)?e.forEach(n=>n(...t)):e&&e(...t)},mu=e=>e?Ke(e)?e.some(t=>t.length>1):e.length>1:!1;function od(e){const t={};for(const J in e)J in rd||(t[J]=e[J]);if(e.css===!1)return t;const{name:n="v",type:s,duration:o,enterFromClass:a=`${n}-enter-from`,enterActiveClass:u=`${n}-enter-active`,enterToClass:f=`${n}-enter-to`,appearFromClass:h=a,appearActiveClass:y=u,appearToClass:m=f,leaveFromClass:w=`${n}-leave-from`,leaveActiveClass:C=`${n}-leave-active`,leaveToClass:S=`${n}-leave-to`}=e,M=ih(o),B=M&&M[0],oe=M&&M[1],{onBeforeEnter:ae,onEnter:T,onEnterCancelled:E,onLeave:X,onLeaveCancelled:de,onBeforeAppear:ie=ae,onAppear:te=T,onAppearCancelled:O=E}=t,j=(J,xe,Ue,rt)=>{J._enterCancelled=rt,er(J,xe?m:f),er(J,xe?y:u),Ue&&Ue()},ce=(J,xe)=>{J._isLeaving=!1,er(J,w),er(J,S),er(J,C),xe&&xe()},ke=J=>(xe,Ue)=>{const rt=J?te:T,We=()=>j(xe,J,Ue);Cr(rt,[xe,We]),yu(()=>{er(xe,J?h:a),bn(xe,J?m:f),mu(rt)||gu(xe,s,B,We)})};return Et(t,{onBeforeEnter(J){Cr(ae,[J]),bn(J,a),bn(J,u)},onBeforeAppear(J){Cr(ie,[J]),bn(J,h),bn(J,y)},onEnter:ke(!1),onAppear:ke(!0),onLeave(J,xe){J._isLeaving=!0;const Ue=()=>ce(J,xe);bn(J,w),J._enterCancelled?(bn(J,C),Ta(J)):(Ta(J),bn(J,C)),yu(()=>{J._isLeaving&&(er(J,w),bn(J,S),mu(X)||gu(J,s,oe,Ue))}),Cr(X,[J,Ue])},onEnterCancelled(J){j(J,!1,void 0,!0),Cr(E,[J])},onAppearCancelled(J){j(J,!0,void 0,!0),Cr(O,[J])},onLeaveCancelled(J){ce(J),Cr(de,[J])}})}function ih(e){if(e==null)return null;if(lt(e))return[la(e.enter),la(e.leave)];{const t=la(e);return[t,t]}}function la(e){return df(e)}function bn(e,t){t.split(/\s+/).forEach(n=>n&&e.classList.add(n)),(e[Jr]||(e[Jr]=new Set)).add(t)}function er(e,t){t.split(/\s+/).forEach(s=>s&&e.classList.remove(s));const n=e[Jr];n&&(n.delete(t),n.size||(e[Jr]=void 0))}function yu(e){requestAnimationFrame(()=>{requestAnimationFrame(e)})}let ah=0;function gu(e,t,n,s){const o=e._endId=++ah,a=()=>{o===e._endId&&s()};if(n!=null)return setTimeout(a,n);const{type:u,timeout:f,propCount:h}=id(e,t);if(!u)return s();const y=u+"end";let m=0;const w=()=>{e.removeEventListener(y,C),a()},C=S=>{S.target===e&&++m>=h&&w()};setTimeout(()=>{m(n[M]||"").split(", "),o=s(`${Qn}Delay`),a=s(`${Qn}Duration`),u=bu(o,a),f=s(`${vs}Delay`),h=s(`${vs}Duration`),y=bu(f,h);let m=null,w=0,C=0;t===Qn?u>0&&(m=Qn,w=u,C=a.length):t===vs?y>0&&(m=vs,w=y,C=h.length):(w=Math.max(u,y),m=w>0?u>y?Qn:vs:null,C=m?m===Qn?a.length:h.length:0);const S=m===Qn&&/\b(?:transform|all)(?:,|$)/.test(s(`${Qn}Property`).toString());return{type:m,timeout:w,propCount:C,hasTransform:S}}function bu(e,t){for(;e.lengthwu(n)+wu(e[s])))}function wu(e){return e==="auto"?0:Number(e.slice(0,-1).replace(",","."))*1e3}function Ta(e){return(e?e.ownerDocument:document).body.offsetHeight}function lh(e,t,n){const s=e[Jr];s&&(t=(t?[t,...s]:[...s]).join(" ")),t==null?e.removeAttribute("class"):n?e.setAttribute("class",t):e.className=t}const _u=Symbol("_vod"),ad=Symbol("_vsh"),uh=Symbol(""),ch=/(?:^|;)\s*display\s*:/;function dh(e,t,n){const s=e.style,o=wt(n);let a=!1;if(n&&!o){if(t)if(wt(t))for(const u of t.split(";")){const f=u.slice(0,u.indexOf(":")).trim();n[f]==null&&gs(s,f,"")}else for(const u in t)n[u]==null&&gs(s,u,"");for(const u in n){u==="display"&&(a=!0);const f=n[u];f!=null?ph(e,u,!wt(t)&&t?t[u]:void 0,f)||gs(s,u,f):gs(s,u,"")}}else if(o){if(t!==n){const u=s[uh];u&&(n+=";"+u),s.cssText=n,a=ch.test(n)}}else t&&e.removeAttribute("style");_u in e&&((!o||t!==n)&&(e[_u]=a?s.display:""),e[ad]&&(s.display="none"))}const Eo=/\s*!important$/;function gs(e,t,n){if(Ke(n))n.forEach(s=>gs(e,t,s));else if(n==null&&(n=""),t.startsWith("--"))Eo.test(n)?e.setProperty(t,n.replace(Eo,""),"important"):e.setProperty(t,n);else{const s=fh(e,t);Eo.test(n)?e.setProperty(dr(s),n.replace(Eo,""),"important"):e[s]=n}}const ku=["Webkit","Moz","ms"],ua={};function fh(e,t){const n=ua[t];if(n)return n;let s=hn(t);if(s!=="filter"&&s in e)return ua[t]=s;s=Ju(s);for(let o=0;oca||(bh.then(()=>ca=0),ca=Date.now());function _h(e,t){const n=s=>{if(!s._vts)s._vts=Date.now();else if(s._vts<=n.attached)return;const o=n.value;if(Ke(o)){const a=s.stopImmediatePropagation;s.stopImmediatePropagation=()=>{a.call(s),s._stopped=!0};const u=o.slice(),f=[s];for(let h=0;he.charCodeAt(0)===111&&e.charCodeAt(1)===110&&e.charCodeAt(2)>96&&e.charCodeAt(2)<123,kh=(e,t,n,s,o,a)=>{const u=o==="svg";t==="class"?lh(e,s,u):t==="style"?dh(e,n,s):ri(t)?si(t)||vh(e,t,n,s,a):(t[0]==="."?(t=t.slice(1),!0):t[0]==="^"?(t=t.slice(1),!1):xh(e,t,s,u))?(Su(e,t,s),!e.tagName.includes("-")&&(t==="value"||t==="checked"||t==="selected")&&Cu(e,t,s,u,a,t!=="value")):e._isVueCE&&(Ch(e,t)||e._def.__asyncLoader&&(/[A-Z]/.test(t)||!wt(s)))?Su(e,hn(t),s,a,t):(t==="true-value"?e._trueValue=s:t==="false-value"&&(e._falseValue=s),Cu(e,t,s,u))};function xh(e,t,n,s){if(s)return!!(t==="innerHTML"||t==="textContent"||t in e&&$u(t)&&Ge(n));if(t==="spellcheck"||t==="draggable"||t==="translate"||t==="autocorrect"||t==="sandbox"&&e.tagName==="IFRAME"||t==="form"||t==="list"&&e.tagName==="INPUT"||t==="type"&&e.tagName==="TEXTAREA")return!1;if(t==="width"||t==="height"){const o=e.tagName;if(o==="IMG"||o==="VIDEO"||o==="CANVAS"||o==="SOURCE")return!1}return $u(t)&&wt(n)?!1:t in e}function Ch(e,t){const n=e._def.props;if(!n)return!1;const s=hn(t);return Array.isArray(n)?n.some(o=>hn(o)===s):Object.keys(n).some(o=>hn(o)===s)}const ld=new WeakMap,ud=new WeakMap,Wo=Symbol("_moveCb"),Au=Symbol("_enterCb"),Oa=new WeakMap,Sh=e=>(delete e.props.mode,e),Eh=Sh({name:"TransitionGroup",props:Et({},sd,{tag:String,moveClass:String}),setup(e,{slots:t}){const n=rl(),s=Ec();let o,a,u,f;const h=()=>(f===void 0&&(f=o.length>0&&jh(o[0].el,n.vnode.el,Pu(e))),f);return Mc(()=>{if(Oa.delete(n),!h()){o=[],u=void 0;return}const y=Pu(e);o.forEach(Ah);const m=u&&Ih(u,n.vnode.el);u=void 0,o.forEach(C=>Ph(C,m));const w=o.filter(Th);Ta(n.vnode.el),w.forEach(C=>{const S=C.el,M=S.style;bn(S,y),M.transform=M.webkitTransform=M.transitionDuration="";const B=S[Wo]=oe=>{oe&&oe.target!==S||(!oe||oe.propertyName.endsWith("transform"))&&(S.removeEventListener("transitionend",B),S[Wo]=null,er(S,y))};S.addEventListener("transitionend",B)}),o=[]}),()=>{const y=ot(e),m=od(y);let w=y.tag||Le;if(o=[],f=void 0,a)for(let C=0;Cs.willMove()&&s.item.contains(t));return n&&mi(n.item,n)}function jh(e,t,n){const s=e.cloneNode(),o=e[Jr];o&&o.forEach(f=>{f.split(/\s+/).forEach(h=>h&&s.classList.remove(h))}),n.split(/\s+/).forEach(f=>f&&s.classList.add(f)),s.style.display="none";const a=t.nodeType===1?t:t.parentNode;a.appendChild(s);const{hasTransform:u}=id(s);return a.removeChild(s),u}const Xr=e=>{const t=e.props["onUpdate:modelValue"]||!1;return Ke(t)?n=>Po(t,n):t};function Dh(e){e.target.composing=!0}function Tu(e){const t=e.target;t.composing&&(t.composing=!1,t.dispatchEvent(new Event("input")))}const Sn=Symbol("_assign"),$o=Symbol("_initialValue");function da(e,t,n){return t&&(e=e.trim()),n&&(e=ii(e)),e}const Re={created(e,{modifiers:{lazy:t,trim:n,number:s}},o){e.parentNode&&(e.type==="text"?e[$o]=e.defaultValue.replace(/[\r\n]/g,""):e.type==="textarea"&&(e[$o]=e.defaultValue.replace(/\r\n?/g,` -`))),e[Sn]=Xr(o);const a=s||o.props&&o.props.type==="number";rr(e,t?"change":"input",u=>{u.target.composing||e[Sn](da(e.value,n,a))}),(n||a)&&rr(e,"change",()=>{e.value=da(e.value,n,a)}),t||(rr(e,"compositionstart",Dh),rr(e,"compositionend",Tu),rr(e,"change",Tu))},mounted(e,{value:t,modifiers:{trim:n,number:s}}){const o=t??"",a=e[$o];delete e[$o],a!==void 0&&(e.type==="text"||e.type==="textarea")&&e.value!==a?e[Sn](da(e.value,n,s)):e.value=o},beforeUpdate(e,{value:t,oldValue:n,modifiers:{lazy:s,trim:o,number:a}},u){if(e[Sn]=Xr(u),e.composing)return;const f=(a||e.type==="number")&&!/^0\d/.test(e.value)?ii(e.value):e.value,h=t??"";if(f===h)return;const y=e.getRootNode();(y instanceof Document||y instanceof ShadowRoot)&&y.activeElement===e&&e.type!=="range"&&(s&&t===n||o&&e.value.trim()===h)||(e.value=h)}},Rh={deep:!0,created(e,t,n){e[Sn]=Xr(n),rr(e,"change",()=>{const s=e._modelValue,o=Ks(e),a=e.checked,u=e[Sn];if(Ke(s)){const f=Ua(s,o),h=f!==-1;if(a&&!h)u(s.concat(o));else if(!a&&h){const y=[...s];y.splice(f,1),u(y)}}else if(Bn(s)){const f=new Set(s);a?f.add(o):f.delete(o),u(f)}else u(cd(e,a))})},mounted:Ou,beforeUpdate(e,t,n){e[Sn]=Xr(n),Ou(e,t,n)}};function Ou(e,{value:t,oldValue:n},s){e._modelValue=t;let o;if(Ke(t))o=Ua(t,s.props.value)>-1;else if(Bn(t))o=t.has(s.props.value);else{if(t===n)return;o=Un(t,cd(e,!0))}e.checked!==o&&(e.checked=o)}const Fn={deep:!0,created(e,{value:t,modifiers:{number:n}},s){e._modelValue=t,rr(e,"change",()=>{const o=Array.prototype.filter.call(e.options,h=>h.selected).map(h=>n?ii(Ks(h)):Ks(h)),a=e.multiple,u=a?Bn(e._modelValue)?new Set(o):o:o[0],f=e._pendingValue=[a,a?Ke(u)?o.slice():o:u];try{e[Sn](u)}finally{ts(()=>{e._pendingValue===f&&(e._pendingValue=void 0)})}}),e[Sn]=Xr(s)},mounted(e,{value:t}){Mu(e,t)},beforeUpdate(e,{value:t},n){e._modelValue=t,e[Sn]=Xr(n)},updated(e,{value:t}){const n=e._pendingValue;e._pendingValue=void 0,(!n||n[0]!==e.multiple||!Lh(t,n[1],n[0]))&&Mu(e,t)}};function Lh(e,t,n){if(!n||Ke(e))return Un(e,t);if(Bn(e)){if(e.size!==t.length)return!1;for(const s of t)if(!e.has(s))return!1;return!0}return!1}function Mu(e,t){const n=e.multiple,s=Ke(t);if(!(n&&!s&&!Bn(t))){for(let o=0,a=e.options.length;oString(y)===String(f)):u.selected=Ua(t,f)>-1}else u.selected=t.has(f);else if(Un(Ks(u),t)){e.selectedIndex!==o&&(e.selectedIndex=o);return}}!n&&e.selectedIndex!==-1&&(e.selectedIndex=-1)}}function Ks(e){return"_value"in e?e._value:e.value}function cd(e,t){const n=t?"_trueValue":"_falseValue";return n in e?e[n]:t}const Kh=["ctrl","shift","alt","meta"],Fh={stop:e=>e.stopPropagation(),prevent:e=>e.preventDefault(),self:e=>e.target!==e.currentTarget,ctrl:e=>!e.ctrlKey,shift:e=>!e.shiftKey,alt:e=>!e.altKey,meta:e=>!e.metaKey,left:e=>"button"in e&&e.button!==0,middle:e=>"button"in e&&e.button!==1,right:e=>"button"in e&&e.button!==2,exact:(e,t)=>Kh.some(n=>e[`${n}Key`]&&!t.includes(n))},Mr=(e,t)=>{if(!e)return e;const n=e._withMods||(e._withMods={}),s=t.join(".");return n[s]||(n[s]=(o,...a)=>{for(let u=0;u{const n=e._withKeys||(e._withKeys={}),s=t.join(".");return n[s]||(n[s]=o=>{if(!("key"in o))return;const a=dr(o.key);if(t.some(u=>u===a||Nh[u]===a))return e(o)})},Vh=Et({patchProp:kh},sh);let Iu;function Bh(){return Iu||(Iu=Lp(Vh))}const Uh=(...e)=>{const t=Bh().createApp(...e),{mount:n}=t;return t.mount=s=>{const o=Hh(s);if(!o)return;const a=t._component;!Ge(a)&&!a.render&&!a.template&&(a.template=o.innerHTML),o.nodeType===1&&(o.textContent="");const u=n(o,!1,qh(o));return o instanceof Element&&(o.removeAttribute("v-cloak"),o.setAttribute("data-v-app","")),u},t};function qh(e){if(e instanceof SVGElement)return"svg";if(typeof MathMLElement=="function"&&e instanceof MathMLElement)return"mathml"}function Hh(e){return wt(e)?document.querySelector(e):e}function At(e){return''+e+""}const Wh={calendar:At(''),clock:At(''),"check-circle":At(''),edit:At(''),tag:At(''),star:At(''),close:At(''),flag:At(''),chart:At(''),export:At(''),"chevron-left":At(''),"chevron-right":At(''),"chevron-down":At(''),plus:At(''),search:At(''),settings:At(''),memo:At(''),lock:At(''),wallet:At('')},zh=["innerHTML"],ut=Vt({__name:"Icon",props:{name:{},size:{default:16}},setup(e){const t=e,n=at(()=>Wh[t.name]||"");return(s,o)=>(F(),q("span",{class:"icon",style:or({width:e.size+"px",height:e.size+"px"}),innerHTML:n.value},null,12,zh))}}),Gh=["aria-label"],Yh={class:"dialog-title"},Jh={class:"dialog-msg"},Xh={class:"dialog-btns"},Qh=Vt({__name:"ConfirmDialog",props:{open:{type:Boolean},title:{},message:{},confirmText:{default:"确认"},cancelText:{default:"取消"},danger:{type:Boolean,default:!1}},emits:["cancel","confirm"],setup(e,{emit:t}){const n=e,s=t;function o(a){n.open&&a.key==="Escape"&&s("cancel")}return mt(()=>n.open,a=>{a?window.addEventListener("keydown",o):window.removeEventListener("keydown",o)}),pr(()=>window.removeEventListener("keydown",o)),(a,u)=>(F(),It(qs,{to:"body"},[Oe(ns,{name:"modal"},{default:fr(()=>[e.open?(F(),q("div",{key:0,class:"mask",onClick:u[2]||(u[2]=Mr(f=>s("cancel"),["self"]))},[c("div",{class:"dialog",role:"dialog","aria-label":e.title},[c("div",Yh,se(e.title),1),c("div",Jh,se(e.message),1),c("div",Xh,[c("button",{class:"btn btn-sm",onClick:u[0]||(u[0]=f=>s("cancel"))},se(e.cancelText),1),c("button",{class:tt(["btn btn-sm",e.danger?"btn-danger-solid":"btn-primary"]),onClick:u[1]||(u[1]=f=>s("confirm"))},se(e.confirmText),3)])],8,Gh)])):Ee("",!0)]),_:1})]))}}),Gt=(e,t)=>{const n=e.__vccOpts||e;for(const[s,o]of t)n[s]=o;return n},cr=Gt(Qh,[["__scopeId","data-v-f27041d4"]]);var ju=typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{};function Zh(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var dd={exports:{}};(function(e,t){((n,s)=>{e.exports=s()})(ju,function(){var n=function(r,i){return(n=Object.setPrototypeOf||({__proto__:[]}instanceof Array?function(l,d){l.__proto__=d}:function(l,d){for(var p in d)Object.prototype.hasOwnProperty.call(d,p)&&(l[p]=d[p])}))(r,i)},s=function(){return(s=Object.assign||function(r){for(var i,l=1,d=arguments.length;l"u"||a.Promise||(a.Promise=Promise);var y=Object.getPrototypeOf,m={}.hasOwnProperty;function w(r,i){return m.call(r,i)}function C(r,i){typeof i=="function"&&(i=i(y(r))),(typeof Reflect>"u"?u:Reflect.ownKeys)(i).forEach(function(l){M(r,l,i[l])})}var S=Object.defineProperty;function M(r,i,l,d){S(r,i,h(l&&w(l,"get")&&typeof l.get=="function"?{get:l.get,set:l.set,configurable:!0}:{value:l,configurable:!0,writable:!0},d))}function B(r){return{from:function(i){return r.prototype=Object.create(i.prototype),M(r.prototype,"constructor",r),{extend:C.bind(null,r.prototype)}}}}var oe=Object.getOwnPropertyDescriptor,ae=[].slice;function T(r,i,l){return ae.call(r,i,l)}function E(r,i){return i(r)}function X(r){if(!r)throw new Error("Assertion Failed")}function de(r){a.setImmediate?setImmediate(r):setTimeout(r,0)}function ie(r,i){if(typeof i=="string"&&w(r,i))return r[i];if(!i)return r;if(typeof i!="string"){for(var l=[],d=0,p=i.length;d"u"?[]:(Xe=Promise.resolve(),typeof crypto<"u"&&crypto.subtle?[Qe=crypto.subtle.digest("SHA-512",new Uint8Array([0])),y(Qe),Xe]:[Xe,y(Xe),Xe]),Xe=Qe[0],Br=Qe[1],Br=Br&&Br.then,Ze=Xe&&Xe.constructor,yt=!!Qe[2],_t=function(r,i){Hn.push([r,i]),Bt&&(queueMicrotask(Rd),Bt=!1)},Xt=!0,Bt=!0,Zt=[],hr=[],Ot=x,$t={id:"global",global:!0,ref:0,unhandleds:[],onunhandled:_,pgp:!1,env:{},finalize:_},Ie=$t,Hn=[],vr=0,Js=[];function Se(r){if(typeof this!="object")throw new TypeError("Promises must be constructed via new");this._listeners=[],this._lib=!1;var i=this._PSD=Ie;if(typeof r!="function"){if(r!==Ae)throw new TypeError("Not a function");this._state=arguments[1],this._value=arguments[2],this._state===!1&&xi(this,this._value)}else this._state=null,this._value=null,++i.ref,function l(d,p){try{p(function(v){if(d._state===null){if(v===d)throw new TypeError("A promise cannot be resolved with itself.");var g=d._lib&&Rr();v&&typeof v.then=="function"?l(d,function(b,A){v instanceof Se?v._then(b,A):v.then(b,A)}):(d._state=!0,d._value=v,vl(d)),g&&Lr()}},xi.bind(null,d))}catch(v){xi(d,v)}}(this,r)}var ki={get:function(){var r=Ie,i=eo;function l(d,p){var v=this,g=!r.global&&(r!==Ie||i!==eo),b=g&&!zn(),A=new Se(function(V,I){Ci(v,new hl(yl(d,r,g,b),yl(p,r,g,b),V,I,r))});return this._consoleTask&&(A._consoleTask=this._consoleTask),A}return l.prototype=Ae,l},set:function(r){M(this,"then",r&&r.prototype===Ae?ki:{get:function(){return r},set:ki.set})}};function hl(r,i,l,d,p){this.onFulfilled=typeof r=="function"?r:null,this.onRejected=typeof i=="function"?i:null,this.resolve=l,this.reject=d,this.psd=p}function xi(r,i){var l,d;hr.push(i),r._state===null&&(l=r._lib&&Rr(),i=Ot(i),r._state=!1,r._value=i,d=r,Zt.some(function(p){return p._value===d._value})||Zt.push(d),vl(r),l)&&Lr()}function vl(r){var i=r._listeners;r._listeners=[];for(var l=0,d=i.length;l{for(var g=Zt.length;g;)if(Zt[--g]._value===v._value)return Zt.splice(g,1)})(i),l.resolve(d)}catch(v){l.reject(v)}finally{--vr==0&&Si(),--l.psd.ref||l.psd.finalize()}}function Rd(){mr($t,function(){Rr()&&Lr()})}function Rr(){var r=Xt;return Bt=Xt=!1,r}function Lr(){var r,i,l;do for(;0.",gl="String expected.",no="__dbnames",$i="readonly",Ai="readwrite";function gr(r,i){return r?i?function(){return r.apply(this,arguments)&&i.apply(this,arguments)}:r:i}var bl={type:3,lower:-1/0,lowerOpen:!1,upper:[[]],upperOpen:!1};function ro(r){return typeof r!="string"||/\./.test(r)?function(i){return i}:function(i){return i[r]===void 0&&r in i&&delete(i=xe(i))[r],i}}function wl(){throw je.Type("Entity instances must never be new:ed. Instances are generated by the framework bypassing the constructor.")}function nt(r,i){try{var l=_l(r),d=_l(i);if(l!==d)return l==="Array"?1:d==="Array"?-1:l==="binary"?1:d==="binary"?-1:l==="string"?1:d==="string"?-1:l==="Date"?1:d!=="Date"?NaN:-1;switch(l){case"number":case"Date":case"string":return i{var b=I,A=g;if(typeof A!="function"&&A!==null)throw new TypeError("Class extends value "+String(A)+" is not a constructor or null");function V(){this.constructor=b}function I(){return g!==null&&g.apply(this,arguments)||this}return n(b,A),b.prototype=A===null?Object.create(A):(V.prototype=A.prototype,new V),Object.defineProperty(I.prototype,"db",{get:function(){return i},enumerable:!1,configurable:!0}),I.prototype.table=function(){return l},I})(r)),new Set),p=r.prototype;p;p=y(p))Object.getOwnPropertyNames(p).forEach(function(g){return d.add(g)});function v(g){if(!g)return g;var b,A=Object.create(r.prototype);for(b in g)if(!d.has(b))try{A[b]=g[b]}catch{}return A}return this.schema.readHook&&this.hook.reading.unsubscribe(this.schema.readHook),this.schema.readHook=v,this.hook("reading",v),r},pt.prototype.defineClass=function(){return this.mapToClass(function(r){h(this,r)})},pt.prototype.add=function(r,i){var l=this,d=this.schema.primKey,p=d.auto,v=d.keyPath,g=r;return v&&p&&(g=ro(v)(r)),this._trans("readwrite",function(b){return l.core.mutate({trans:b,type:"add",keys:i!=null?[i]:null,values:[g]})}).then(function(b){return b.numFailures?Se.reject(b.failures[0]):b.lastResult}).then(function(b){if(v)try{te(r,v,b)}catch{}return b})},pt.prototype.upsert=function(r,i){var l=this,d=this.schema.primKey.keyPath;return this._trans("readwrite",function(p){return l.core.get({trans:p,key:r}).then(function(v){var g=v??{};return Cl(g,i),d&&te(g,d,r),l.core.mutate({trans:p,type:"put",values:[g],keys:[r],upsert:!0,updates:{keys:[r],changeSpecs:[i]}}).then(function(b){return b.numFailures?Se.reject(b.failures[0]):!!v})})})},pt.prototype.update=function(r,i){return typeof r!="object"||f(r)?this.where(":id").equals(r).modify(i):(r=ie(r,this.schema.primKey.keyPath))===void 0?Ct(new je.InvalidArgument("Given object does not contain its primary key")):this.where(":id").equals(r).modify(i)},pt.prototype.put=function(r,i){var l=this,d=this.schema.primKey,p=d.auto,v=d.keyPath,g=r;return v&&p&&(g=ro(v)(r)),this._trans("readwrite",function(b){return l.core.mutate({trans:b,type:"put",values:[g],keys:i!=null?[i]:null})}).then(function(b){return b.numFailures?Se.reject(b.failures[0]):b.lastResult}).then(function(b){if(v)try{te(r,v,b)}catch{}return b})},pt.prototype.delete=function(r){var i=this;return this._trans("readwrite",function(l){return i.core.mutate({trans:l,type:"delete",keys:[r]}).then(function(d){return so(i,[r],d)}).then(function(d){return d.numFailures?Se.reject(d.failures[0]):void 0})})},pt.prototype.clear=function(){var r=this;return this._trans("readwrite",function(i){return r.core.mutate({trans:i,type:"deleteRange",range:bl}).then(function(l){return so(r,null,l)})}).then(function(i){return i.numFailures?Se.reject(i.failures[0]):void 0})},pt.prototype.bulkGet=function(r){var i=this;return this._trans("readonly",function(l){return i.core.getMany({keys:r,trans:l}).then(function(d){return d.map(function(p){return i.hook.reading.fire(p)})})})},pt.prototype.bulkAdd=function(r,i,l){var d=this,p=Array.isArray(i)?i:void 0,v=(l=l||(p?void 0:i))?l.allKeys:void 0;return this._trans("readwrite",function(g){var b=d.schema.primKey,V=b.auto,b=b.keyPath;if(b&&p)throw new je.InvalidArgument("bulkAdd(): keys argument invalid on tables with inbound keys");if(p&&p.length!==r.length)throw new je.InvalidArgument("Arguments objects and keys must have the same length");var A=r.length,V=b&&V?r.map(ro(b)):r;return d.core.mutate({trans:g,type:"add",keys:p,values:V,wantResults:v}).then(function(I){var $=I.numFailures,P=I.failures;if($===0)return v?I.results:I.lastResult;throw new ft("".concat(d.name,".bulkAdd(): ").concat($," of ").concat(A," operations failed"),P)})})},pt.prototype.bulkPut=function(r,i,l){var d=this,p=Array.isArray(i)?i:void 0,v=(l=l||(p?void 0:i))?l.allKeys:void 0;return this._trans("readwrite",function(g){var b=d.schema.primKey,V=b.auto,b=b.keyPath;if(b&&p)throw new je.InvalidArgument("bulkPut(): keys argument invalid on tables with inbound keys");if(p&&p.length!==r.length)throw new je.InvalidArgument("Arguments objects and keys must have the same length");var A=r.length,V=b&&V?r.map(ro(b)):r;return d.core.mutate({trans:g,type:"put",keys:p,values:V,wantResults:v}).then(function(I){var $=I.numFailures,P=I.failures;if($===0)return v?I.results:I.lastResult;throw new ft("".concat(d.name,".bulkPut(): ").concat($," of ").concat(A," operations failed"),P)})})},pt.prototype.bulkUpdate=function(r){var i=this,l=this.core,d=r.map(function(g){return g.key}),p=r.map(function(g){return g.changes}),v=[];return this._trans("readwrite",function(g){return l.getMany({trans:g,keys:d,cache:"clone"}).then(function(b){var A=[],V=[],I=(r.forEach(function($,P){var K=$.key,R=$.changes,D=b[P];if(D){for(var L=0,z=Object.keys(R);LU+re&&L(U+V)})})}var z=Fr(l)&&l.limit===1/0&&(typeof r!="function"||R)&&{index:l.index,range:l.range};return L(0).then(function(){if(0<$.length)throw new Ve("Error modifying one or more objects",$,P,K);return D.length})})})},st.prototype.delete=function(){var r=this._ctx,i=r.range;return!Fr(r)||r.table.schema.yProps||!r.isPrimKey&&i.type!==3?this.modify(Al):this._write(function(l){var d=r.table.core.schema.primaryKey,p=i;return r.table.core.count({trans:l,query:{index:d,range:p}}).then(function(v){return r.table.core.mutate({trans:l,type:"deleteRange",range:p}).then(function(A){var b=A.failures,A=A.numFailures;if(A)throw new Ve("Could not delete some values",Object.keys(b).map(function(V){return b[V]}),v-A);return v-A})})})};var Nd=st;function st(){}var Al=function(r,i){return i.value=null};function Vd(r,i){return r{for(var He=Math.min(ye.length,Te.length),Je=-1,et=0;et=P})).length===0?Se.resolve():(L.forEach(function(U){D.push(function(){var re,fe,he,we=z,ye=U._cfg.dbschema,Pe=(ho($,we,R),ho($,ye,R),z=$._dbSchema=ye,Ri(we,ye)),be=(Pe.add.forEach(function(Te){Li(R,Te[0],Te[1].primKey,Te[1].indexes)}),Pe.change.forEach(function(Te){if(Te.recreate)throw new je.Upgrade("Not yet support for changing primary key");var pe=R.objectStore(Te.name);Te.add.forEach(function(qe){return fo(pe,qe)}),Te.change.forEach(function(qe){pe.deleteIndex(qe.name),fo(pe,qe)}),Te.del.forEach(function(qe){return pe.deleteIndex(qe)})}),U._cfg.contentUpgrade);if(be&&U._cfg.version>P)return uo($,R),K._memoizedTables={},re=O(ye),Pe.del.forEach(function(Te){re[Te]=we[Te]}),Di($,[$.Transaction.prototype]),co($,[$.Transaction.prototype],u(re),re),K.schema=re,(fe=De(be))&&Kr(),ye=Se.follow(function(){var Te;(he=be(K))&&fe&&(Te=zn.bind(null,null),he.then(Te,Te))}),he&&typeof he.then=="function"?Se.resolve(he):ye.then(function(){return he})}),D.push(function(re){var fe,he,we=U._cfg.dbschema;fe=we,he=re,[].slice.call(he.db.objectStoreNames).forEach(function(ye){return fe[ye]==null&&he.db.deleteObjectStore(ye)}),Di($,[$.Transaction.prototype]),co($,[$.Transaction.prototype],$._storeNames,$._dbSchema),K.schema=$._dbSchema}),D.push(function(re){$.idbdb.objectStoreNames.contains("$meta")&&(Math.ceil($.idbdb.version/10)===U._cfg.version?($.idbdb.deleteObjectStore("$meta"),delete $._dbSchema.$meta,$._storeNames=$._storeNames.filter(function(fe){return fe!=="$meta"})):re.objectStore("$meta").put(U._cfg.version,"version"))})}),function U(){return D.length?Se.resolve(D.shift()(K.idbtrans)).then(U):Se.resolve()}().then(function(){Il(z,R)}))}).catch(g);var A,V;u(p).forEach(function(I){Li(l,I,p[I].primKey,p[I].indexes)}),uo(r,l),Se.follow(function(){return r.on.populate.fire(v)}).catch(g)})}function Yd(r,i){Il(r._dbSchema,i),i.db.version%10!=0||i.objectStoreNames.contains("$meta")||i.db.createObjectStore("$meta").add(Math.ceil(i.db.version/10-1),"version");var l=po(0,r.idbdb,i);ho(r,r._dbSchema,i);for(var d=0,p=Ri(l,r._dbSchema).change;d{if(g.change.length||g.recreate)return console.warn("Unable to patch indexes of table ".concat(g.name," because it has changes on the type of index or primary key.")),{value:void 0};var b=i.objectStore(g.name);g.add.forEach(function(A){W&&console.debug("Dexie upgrade patch: Creating missing index ".concat(g.name,".").concat(A.src)),fo(b,A)})})(p[d]);if(typeof v=="object")return v.value}}function Ri(r,i){var l,d={del:[],add:[],change:[]};for(l in r)i[l]||d.del.push(l);for(l in i){var p=r[l],v=i[l];if(p){var g={name:l,def:v,recreate:!1,del:[],add:[],change:[]};if(""+(p.primKey.keyPath||"")!=""+(v.primKey.keyPath||"")||p.primKey.auto!==v.primKey.auto)g.recreate=!0,d.change.push(g);else{var b=p.idxByName,A=v.idxByName,V=void 0;for(V in b)A[V]||g.del.push(V);for(V in A){var I=b[V],$=A[V];I?I.src!==$.src&&g.change.push($):g.add.push($)}(0{var r,i,l;return typeof FinalizationRegistry<"u"&&typeof WeakRef<"u"?(r=new Set,i=new FinalizationRegistry(function(d){r.delete(d)}),{toArray:function(){return Array.from(r).map(function(d){return d.deref()}).filter(function(d){return d!==void 0})},add:function(d){var p=new WeakRef(d._novip);r.add(p),i.register(d._novip,p,p),r.size>d._options.maxConnections&&(p=r.values().next().value,r.delete(p),i.unregister(p))},remove:function(d){if(d)for(var p=r.values(),v=p.next();!v.done;){var g=v.value;if(g.deref()===d._novip)return r.delete(g),void i.unregister(g);v=p.next()}}}):(l=[],{toArray:function(){return l},add:function(d){l.push(d._novip)},remove:function(d){d&&(d=l.indexOf(d._novip))!==-1&&l.splice(d,1)}})})();function Ki(r,i){var l=r._dbNamesDB;return l||(l=r._dbNamesDB=new Mn(no,{addons:[],indexedDB:r,IDBKeyRange:i})).version(1).stores({dbnames:"name"}),l.table("dbnames")}function Fi(r){return r&&typeof r.databases=="function"}function Ni(r){return Wn(function(){return Ie.letThrough=!0,r()})}function Vi(r){return!("from"in r)}var Dt=function(r,i){var l;if(!this)return l=new Dt,r&&"d"in r&&h(l,r),l;h(this,arguments.length?{d:1,from:r,to:1Math.pow(2,62)?0:L.oldVersion,$=z<1,r.idbdb=D.result,v&&Yd(r,I),Gd(r,z/10,I,K))},K),D.onsuccess=gt(function(){I=null;var L,z,U,re,fe,he,we=r.idbdb=D.result,ye=T(we.objectStoreNames);if(0"u"?Se.resolve():!navigator.userAgentData&&/Safari\//.test(navigator.userAgent)&&!/Chrom(e|ium)\//.test(navigator.userAgent)&&indexedDB.databases?new Promise(function(P){function K(){return indexedDB.databases().finally(P)}A=setInterval(K,100),K()}).finally(function(){return clearInterval(A)}):Promise.resolve()).then(b)]).then(function(){return g(),i.onReadyBeingFired=[],Se.resolve(Ni(function(){return r.on.ready.fire(r.vip)})).then(function P(){var K;if(0i.limit?d.length=i.limit:r.length===i.limit&&d.length{if(l===void 0)return d!==void 0?-1:0;if(d===void 0)return 1;if((l=nt(l,d))===0){if(p&&v)return 0;if(p)return 1;if(v)return-1}return l})(r.lower,i.lower,r.lowerOpen,i.lowerOpen)<=0&&0<=((l,d,p,v)=>{if(l===void 0)return d!==void 0?1:0;if(d===void 0)return-1;if((l=nt(l,d))===0){if(p&&v)return 0;if(p)return-1;if(v)return 1}return l})(r.upper,i.upper,r.upperOpen,i.upperOpen)}function rf(r,i,l,d){r.subscribers.add(l),d.addEventListener("abort",function(){var p,v;r.subscribers.delete(l),r.subscribers.size===0&&(p=r,v=i,setTimeout(function(){p.subscribers.size===0&&me(v,p)},3e3))})}var sf={stack:"dbcore",level:0,name:"Cache",create:function(r){var i=r.schema.name;return s(s({},r),{transaction:function(l,d,p){var v,g,b=r.transaction(l,d,p);return d==="readwrite"&&(p=(v=new AbortController).signal,b.addEventListener("abort",(g=function(A){return function(){if(v.abort(),d==="readwrite"){for(var V=new Set,I=0,$=l;I<$.length;I++){var P=$[I],K=br["idb://".concat(i,"/").concat(P)];if(K){var R=r.table(P),D=K.optimisticOps.filter(function(pe){return pe.trans===b});if(b._explicit&&A&&b.mutatedParts)for(var L=0,z=Object.values(K.queries.query);L{var z=br["idb://".concat(K,"/").concat(R)];if(!z)return[];if(!(K=z.queries[D]))return[null,!1,z,null];var U=K[(L.query?L.query.index.name:null)||""];if(!U)return[null,!1,z,null];switch(D){case"query":var re=(fe=L.direction)!=null?fe:"next",fe=U.find(function(he){var we;return he.req.limit===L.limit&&he.req.values===L.values&&((we=he.req.direction)!=null?we:"next")===re&&ql(he.req.query.range,L.query.range)});return fe?[fe,!0,z,U]:[U.find(function(he){var we;return("limit"in he.req?he.req.limit:1/0)>=L.limit&&((we=he.req.direction)!=null?we:"next")===re&&(!L.values||he.req.values)&&nf(he.req.query.range,L.query.range)}),!1,z,U];case"count":return fe=U.find(function(he){return ql(he.req.query.range,L.query.range)}),[fe,!!fe,z,U]}})(i,l,"query",v),P=$[0],V=$[2],I=$[3],P&&$[1]?P.obsSet=v.obsSet:($=d.query(v).then(function(K){var R=K.result;if(P&&(P.res=R),g){for(var D=0,L=R.length;D{var fe=Rr();try{v&&Kr();var he=Wn(r,re);return he=v?he.finally(zn):he}finally{fe&&Lr()}})(z={subscr:L,signal:g.signal,requery:P,querier:r,trans:null}),$||(Jn.storagemutated.subscribe(R),$=!0),Promise.resolve(U).then(function(re){l=!0,i=re,b||z.signal.aborted||(K()||(V=L,K())?P():(A={},Ei(function(){return!b&&p.next&&p.next(re)})))},function(re){l=!1,["DatabaseClosedError","AbortError"].includes(re==null?void 0:re.name)||b||Ei(function(){b||p.error&&p.error(re)})}))};return setTimeout(P,0),I});return d.hasValue=function(){return l},d.getValue=function(){return i},d}var wr=Mn;function Xi(r){var i=Xn;try{Xn=!0,Jn.storagemutated.fire(r),Hi(r,!0)}finally{Xn=i}}C(wr,s(s({},Ce),{delete:function(r){return new wr(r,{addons:[]}).delete()},exists:function(r){return new wr(r,{addons:[]}).open().then(function(i){return i.close(),!0}).catch("NoSuchDatabaseError",function(){return!1})},getDatabaseNames:function(r){try{return i=wr.dependencies,l=i.indexedDB,i=i.IDBKeyRange,(Fi(l)?Promise.resolve(l.databases()).then(function(d){return d.map(function(p){return p.name}).filter(function(p){return p!==no})}):Ki(l,i).toCollection().primaryKeys()).then(r)}catch{return Ct(new je.MissingAPI)}var i,l},defineClass:function(){return function(r){h(this,r)}},ignoreTransaction:function(r){return Ie.trans?mr(Ie.transless||$t,r):r()},vip:Ni,async:function(r){return function(){try{var i=Wi(r.apply(this,arguments));return i&&typeof i.then=="function"?i:Se.resolve(i)}catch(l){return Ct(l)}}},spawn:function(r,i,l){try{var d=Wi(r.apply(l,i||[]));return d&&typeof d.then=="function"?d:Se.resolve(d)}catch(p){return Ct(p)}},currentTransaction:{get:function(){return Ie.trans||null}},waitFor:function(r,i){return r=Se.resolve(typeof r=="function"?wr.ignoreTransaction(r):r).timeout(i||6e4),Ie.trans?Ie.trans.waitFor(r):r},Promise:Se,debug:{get:function(){return W},set:function(r){Y(r)}},derive:B,extend:h,props:C,override:E,Events:os,on:Jn,liveQuery:Hl,extendObservabilitySet:mo,getByKeyPath:ie,setByKeyPath:te,delByKeyPath:function(r,i){typeof i=="string"?te(r,i,void 0):"length"in i&&[].map.call(i,function(l){te(r,l,void 0)})},shallowClone:O,deepClone:xe,getObjectDiff:zi,cmp:nt,asap:de,minKey:-1/0,addons:[],connections:{get:cs.toArray},errnames:Yt,dependencies:wo,cache:br,semVer:"4.4.6",version:"4.4.6".split(".").map(function(r){return parseInt(r)}).reduce(function(r,i,l){return r+i/Math.pow(10,2*l)})})),wr.maxKey=ls(wr.dependencies.IDBKeyRange),typeof dispatchEvent<"u"&&typeof addEventListener<"u"&&(Jn(lo,function(r){Xn||(r=new CustomEvent(Oi,{detail:r}),Xn=!0,dispatchEvent(r),Xn=!1)}),addEventListener(Oi,function(r){r=r.detail,Xn||Xi(r)}));var Ur,Xn=!1,Wl=function(){};return typeof BroadcastChannel<"u"&&((Wl=function(){(Ur=new BroadcastChannel(Oi)).onmessage=function(r){return r.data&&Xi(r.data)}})(),typeof Ur.unref=="function"&&Ur.unref(),Jn(lo,function(r){Xn||Ur.postMessage(r)})),typeof addEventListener<"u"&&(addEventListener("pagehide",function(r){if(!Mn.disableBfCache&&r.persisted){W&&console.debug("Dexie: handling persisted pagehide"),Ur!=null&&Ur.close();for(var i=0,l=cs.toArray();in.key===e);return t?t.label:"其他"}const sv={class:"dialog",role:"dialog","aria-label":"编辑工作记录"},ov={class:"dialog-head"},iv={key:0,class:"muted dialog-sub"},av={class:"dialog-body"},lv={class:"form-grid"},uv={class:"field span2"},cv={key:0,class:"form-error"},dv={class:"field"},fv=["value"],pv={class:"field"},hv=["value"],vv={class:"field"},mv={class:"field"},yv={class:"field span2"},gv={class:"field"},bv={class:"field"},wv={class:"dialog-btns"},_v=Vt({__name:"EditLogDialog",props:{open:{type:Boolean},item:{},projects:{},date:{}},emits:["cancel","save"],setup(e,{emit:t}){const n=e,s=t,o=N(""),a=N(null),u=N("dev"),f=N(null),h=N(""),y=N(""),m=N(0),w=N(0),C=N(""),S=N(null),M=at(()=>{var E;const ae=n.projects.filter(X=>X.archived!==1),T=(E=n.item)==null?void 0:E.project_id;if(T&&!ae.some(X=>X.id===T)){const X=n.projects.find(ie=>ie.id===T),de=ae.slice();return X&&de.unshift({...X,name:X.name+"(已归档)"}),de}return ae});function B(ae){n.open&&ae.key==="Escape"&&s("cancel")}mt(()=>n.open,async ae=>{var T;if(ae){const E=n.item;o.value=(E==null?void 0:E.content)??"",a.value=(E==null?void 0:E.project_id)??null,u.value=(E==null?void 0:E.category)??"dev",f.value=(E==null?void 0:E.minutes)??null,h.value=(E==null?void 0:E.takeaway)??"",y.value=(E==null?void 0:E.remark)??"",m.value=(E==null?void 0:E.is_milestone)??0,w.value=(E==null?void 0:E.needs_followup)??0,C.value="",window.addEventListener("keydown",B),await ts(),(T=S.value)==null||T.focus()}else window.removeEventListener("keydown",B)}),pr(()=>window.removeEventListener("keydown",B)),mt(o,()=>{C.value&&(C.value="")});function oe(){const ae=o.value.trim();if(!ae){C.value="请填写工作内容";return}if(!n.item||!n.item.id){s("cancel");return}s("save",{id:n.item.id,content:ae,project_id:a.value,category:u.value,minutes:f.value&&f.value>0?f.value:null,takeaway:h.value.trim()||null,remark:y.value.trim()||null,is_milestone:m.value?1:0,needs_followup:w.value?1:0})}return(ae,T)=>(F(),It(qs,{to:"body"},[Oe(ns,{name:"modal"},{default:fr(()=>[e.open?(F(),q("div",{key:0,class:"mask",onClick:T[10]||(T[10]=Mr(E=>s("cancel"),["self"]))},[c("div",sv,[c("div",ov,[c("div",null,[T[11]||(T[11]=c("div",{class:"dialog-title"},"编辑工作记录",-1)),e.date?(F(),q("div",iv,se(e.date),1)):Ee("",!0)]),c("button",{class:"icon-btn",title:"关闭",onClick:T[0]||(T[0]=E=>s("cancel"))},[Oe(ut,{name:"close",size:16})])]),c("div",av,[c("div",lv,[c("div",uv,[T[12]||(T[12]=c("label",null,"工作内容(必填)",-1)),$e(c("input",{ref_key:"contentInput",ref:S,class:tt(["input",{invalid:C.value}]),"onUpdate:modelValue":T[1]||(T[1]=E=>o.value=E),onKeydown:jt(oe,["enter"])},null,34),[[Re,o.value]]),C.value?(F(),q("div",cv,se(C.value),1)):Ee("",!0)]),c("div",dv,[T[14]||(T[14]=c("label",null,"所属项目",-1)),$e(c("select",{class:"select","onUpdate:modelValue":T[2]||(T[2]=E=>a.value=E)},[T[13]||(T[13]=c("option",{value:null},"无项目",-1)),(F(!0),q(Le,null,ct(M.value,E=>(F(),q("option",{key:E.id,value:E.id},se(E.name),9,fv))),128))],512),[[Fn,a.value]])]),c("div",pv,[T[15]||(T[15]=c("label",null,"工作分类",-1)),$e(c("select",{class:"select","onUpdate:modelValue":T[3]||(T[3]=E=>u.value=E)},[(F(!0),q(Le,null,ct(Qt(Ws),E=>(F(),q("option",{key:E.key,value:E.key},se(E.label),9,hv))),128))],512),[[Fn,u.value]])]),c("div",vv,[T[16]||(T[16]=c("label",null,"耗时(分钟)",-1)),$e(c("input",{class:"input",type:"number",min:"0","onUpdate:modelValue":T[4]||(T[4]=E=>f.value=E),placeholder:"选填"},null,512),[[Re,f.value,void 0,{number:!0}]])]),c("div",mv,[T[17]||(T[17]=c("label",null,"主要收获",-1)),$e(c("input",{class:"input","onUpdate:modelValue":T[5]||(T[5]=E=>h.value=E),placeholder:"一句话:学到了什么"},null,512),[[Re,h.value]])]),c("div",yv,[T[18]||(T[18]=c("label",null,"备注",-1)),$e(c("textarea",{class:"textarea","onUpdate:modelValue":T[6]||(T[6]=E=>y.value=E),placeholder:"背景、链接、未决事项(选填)"},null,512),[[Re,y.value]])]),c("div",gv,[T[19]||(T[19]=c("label",null,"成果标记",-1)),c("button",{class:tt(["toggle-btn",{on:m.value===1}]),onClick:T[7]||(T[7]=E=>m.value=m.value===1?0:1)},se(m.value===1?"已标记为成果":"未标记"),3)]),c("div",bv,[T[20]||(T[20]=c("label",null,"待跟进",-1)),c("button",{class:tt(["toggle-btn",{onwarn:w.value===1}]),onClick:T[8]||(T[8]=E=>w.value=w.value===1?0:1)},se(w.value===1?"需要跟进":"无需跟进"),3)])])]),c("div",wv,[c("button",{class:"btn btn-sm",onClick:T[9]||(T[9]=E=>s("cancel"))},"取消"),c("button",{class:"btn btn-primary btn-sm",onClick:oe},"保存修改")])])])):Ee("",!0)]),_:1})]))}}),kv=Gt(_v,[["__scopeId","data-v-63bc0b48"]]);function Ss(e){return e<10?"0"+e:String(e)}function Nn(e){return e.getFullYear()+"-"+Ss(e.getMonth()+1)+"-"+Ss(e.getDate())}function xt(){return Nn(new Date)}function vt(){const e=new Date;return Nn(e)+"T"+Ss(e.getHours())+":"+Ss(e.getMinutes())+":"+Ss(e.getSeconds())}function Vn(e){if(!e)return"--:--";const t=e.indexOf("T");return t>=0?e.slice(t+1,t+6):e.slice(0,5)}function rs(e){const t=e.split("-").map(Number);return new Date(t[0],t[1]-1,t[2])}function Kn(e,t){const n=rs(e);return n.setDate(n.getDate()+t),Nn(n)}function Go(e,t){const n=rs(e),s=n.getDate();n.setDate(1),n.setMonth(n.getMonth()+t);const o=new Date(n.getFullYear(),n.getMonth()+1,0).getDate();return n.setDate(Math.min(s,o)),Nn(n)}function Es(e){const t=rs(e),n=(t.getDay()+6)%7;return t.setDate(t.getDate()-n),Nn(t)}function xv(e){const t=rs(e).getDay();return t===0||t===6}function Cv(e,t){return Math.round((new Date(t).getTime()-new Date(e).getTime())/6e4)}function pd(e){const t=rs(e),n=["周日","周一","周二","周三","周四","周五","周六"];return t.getFullYear()+" 年 "+(t.getMonth()+1)+" 月 "+t.getDate()+" 日 "+n[t.getDay()]}async function bt(e,t){const n=await ee.setting.get(e);return n?n.value:t}async function kt(e,t){await ee.setting.put({key:e,value:t})}async function jr(){const e=await Promise.all([bt("work_start","09:00"),bt("work_end","18:00"),bt("grace_minutes","10"),bt("lunch_minutes","60"),bt("remind_weekly","friday")]);return{work_start:e[0],work_end:e[1],grace_minutes:Number(e[2])||0,lunch_minutes:Number(e[3])||0,remind_weekly:e[4]}}async function Sv(){const e=await bt("last_project",""),t=await bt("last_category","dev");return{project_id:e?Number(e):null,category:t||"dev"}}async function Ev(){return bt("last_location","")}async function $v(e,t){const n=t.trim();await kt("last_location",n),n&&await Yo(n);const s=await mn(e);s&&s.id?await ee.attendance.update(s.id,{location:n||null}):n&&await ee.attendance.add({date:e,clock_in_at:null,clock_out_at:null,kind:"normal",note:null,location:n,created_at:vt()})}async function il(){const e=await bt("location_presets","");if(!e)return Ru.slice();try{const t=JSON.parse(e);if(Array.isArray(t))return t.filter(n=>typeof n=="string"&&n.trim()).map(n=>n.trim())}catch{}return Ru.slice()}async function hd(e){const t=Array.from(new Set(e.map(n=>n.trim()).filter(Boolean)));await kt("location_presets",JSON.stringify(t))}async function Yo(e){const t=e.trim();if(!t)return;const n=await il();n.includes(t)||await hd([...n,t])}async function Fs(e=!1){const t=await ee.project.orderBy("name").toArray();return e?t:t.filter(n=>n.archived!==1)}async function Av(e){await ee.project.add({name:e.trim(),archived:0,created_at:vt()})}async function Pv(e,t){await ee.project.update(e,{name:t.trim()})}async function Tv(e,t){await ee.project.update(e,{archived:t?1:0})}async function mn(e){return ee.attendance.where("date").equals(e).first()}async function vd(e,t){const n=((t===void 0?await bt("last_location",""):t)||"").trim(),s=await mn(e);if(s&&s.id){if(!s.clock_in_at){const o={clock_in_at:vt()};n&&(o.location=n),await ee.attendance.update(s.id,o)}n&&(await kt("last_location",n),await Yo(n));return}await ee.attendance.add({date:e,clock_in_at:vt(),clock_out_at:null,kind:"normal",note:null,location:n||null,created_at:vt()}),n&&(await kt("last_location",n),await Yo(n))}async function Ov(e){const t=await mn(e);t&&t.id&&t.clock_in_at&&!t.clock_out_at&&await ee.attendance.update(t.id,{clock_out_at:vt()})}async function Mv(){const e=new Date,t=Nn(e);if(e.getHours()<4){const s=await mn(Kn(t,-1));if(s&&s.id&&s.clock_in_at&&!s.clock_out_at)return await ee.attendance.update(s.id,{clock_out_at:vt()}),s.date}const n=await mn(t);if(n&&n.id&&n.clock_in_at&&!n.clock_out_at)return await ee.attendance.update(n.id,{clock_out_at:vt()}),n.date;throw new Error("没有进行中的打卡")}async function Iv(e,t,n,s,o){(o||"").trim()&&await Yo(o);const a=await mn(e),u={date:e,clock_in_at:t,clock_out_at:n,kind:"makeup",note:s||null,location:(o||"").trim()||null,created_at:vt()};a&&a.id?await ee.attendance.update(a.id,u):await ee.attendance.add(u)}async function jv(e,t,n){const s=(n||"").trim();if(!s)return;const o=await mn(e);o&&o.id&&await ee.attendance.update(o.id,{[t]:e+"T"+s+":00"})}async function yi(e,t){return ee.attendance.where("date").between(e,t,!0,!0).toArray()}async function Dv(e,t){const n=await mn(e);if(t){const s={date:e,kind:"leave",clock_in_at:null,clock_out_at:null,created_at:vt()};n&&n.id?await ee.attendance.update(n.id,s):await ee.attendance.add({...s,note:null,location:null})}else n&&n.id&&await ee.attendance.update(n.id,{kind:"normal"})}async function Rv(e){const t=await ee.work_log.where("date").equals(e).first();return t||{id:await ee.work_log.add({date:e,created_at:vt()}),date:e,created_at:vt()}}async function Lv(e){return ee.work_log.where("date").equals(e).first()}async function Kv(e){const t=await Lv(e);return!t||!t.id?[]:(await ee.log_item.where("work_log_id").equals(t.id).toArray()).sort((s,o)=>o.id-s.id)}async function Fv(e,t){const n=await Rv(e);await ee.log_item.add({work_log_id:n.id,content:t.content,project_id:t.project_id,category:t.category,minutes:t.minutes,is_milestone:0,needs_followup:0,takeaway:t.takeaway,remark:t.remark,sort_order:0,created_at:vt()}),await kt("last_project",t.project_id?String(t.project_id):""),await kt("last_category",t.category)}async function fa(e,t){await ee.log_item.update(e,t)}async function Nv(e){await ee.log_item.delete(e)}async function gi(e,t){const n=await ee.work_log.where("date").between(e,t,!0,!0).toArray();if(!n.length)return[];const s=new Map(n.map(a=>[a.id,a.date]));return(await ee.log_item.where("work_log_id").anyOf(n.map(a=>a.id)).toArray()).map(a=>({...a,date:s.get(a.work_log_id)||""})).sort((a,u)=>a.date===u.date?a.id-u.id:a.datet.updated_at[u.id,u.date]));return(await ee.log_item.toArray()).filter(u=>((u.content||"")+" "+(u.takeaway||"")+" "+(u.remark||"")).toLowerCase().includes(n)).sort((u,f)=>f.id-u.id).slice(0,t).map(u=>({...u,date:o.get(u.work_log_id)||""}))}async function Gv(e,t=4){const n=e.trim().toLowerCase();return n?(await ee.memo.toArray()).filter(o=>((o.title||"")+" "+(o.content||"")).toLowerCase().includes(n)).sort((o,a)=>o.updated_at{await Promise.all([ee.project.clear(),ee.work_log.clear(),ee.log_item.clear(),ee.attendance.clear(),ee.weekly_note.clear(),ee.setting.clear(),ee.memo.clear(),ee.credential.clear(),ee.table("transaction").clear()]),n.project&&n.project.length&&await ee.project.bulkAdd(n.project),n.work_log&&n.work_log.length&&await ee.work_log.bulkAdd(n.work_log),n.log_item&&n.log_item.length&&await ee.log_item.bulkAdd(n.log_item),n.attendance&&n.attendance.length&&await ee.attendance.bulkAdd(n.attendance),n.weekly_note&&n.weekly_note.length&&await ee.weekly_note.bulkAdd(n.weekly_note),n.setting&&n.setting.length&&await ee.setting.bulkAdd(n.setting),n.memo&&n.memo.length&&await ee.memo.bulkAdd(n.memo),n.credential&&n.credential.length&&await ee.credential.bulkAdd(n.credential),n.transaction&&n.transaction.length&&await ee.table("transaction").bulkAdd(n.transaction)})}function Ao(e){const t=e.split(":");return Number(t[0])*60+Number(t[1])}function zs(e,t,n,s){if(e&&e.kind==="leave")return{status:"leave",label:"请假",makeup:!1,workedMinutes:null};if(xv(t))return{status:"rest",label:"休息日",makeup:!1,workedMinutes:null};if(!e||!e.clock_in_at)return s?{status:"none",label:"未打卡",makeup:!1,workedMinutes:null}:{status:"absent",label:"缺勤",makeup:!!(e&&e.kind==="makeup"),workedMinutes:null};const o=e.kind==="makeup";if(!e.clock_out_at)return{status:"incomplete",label:s?"进行中":"未完成",makeup:o,workedMinutes:null};const a=Ao(Vn(e.clock_in_at)),u=Ao(Vn(e.clock_out_at)),f=Ao(n.work_start),h=Ao(n.work_end);let y="normal";!o&&a>f+n.grace_minutes?y="late":!o&&u{Io.value=Io.value.filter(n=>n.id!==t)},2e3)}function rm(){return Io}const Ia=N(null),ja=N(null),Gs=N(0);function nr(){Gs.value++}const sm={class:"day-panel"},om={class:"dp-head"},im={class:"dp-date"},am={class:"card sec"},lm={class:"att-grid"},um={class:"att-cell"},cm={key:0,class:"edit-row"},dm={key:1,class:"att-val"},fm={class:"att-cell"},pm={key:0,class:"edit-row"},hm={key:1,class:"att-val"},vm={class:"att-cell"},mm=["list"],ym=["id"],gm=["value"],bm={class:"att-cell"},wm={class:"att-val status-val"},_m={key:0,class:"tag"},km={key:1,class:"muted"},xm={key:0,class:"att-note muted"},Cm={class:"att-actions"},Sm=["disabled"],Em=["disabled"],$m=["disabled"],Am=["disabled"],Pm={key:0,class:"card sec makeup"},Tm={class:"form-grid"},Om={class:"field"},Mm={class:"field"},Im={class:"field span2"},jm=["list"],Dm={class:"field span2"},Rm={key:0,class:"form-error"},Lm={class:"form-footer"},Km={class:"card sec"},Fm={class:"form-grid"},Nm={class:"field span2"},Vm={key:0,class:"form-error"},Bm={class:"field"},Um=["value"],qm={class:"field"},Hm=["value"],Wm={class:"field"},zm={class:"field"},Gm={class:"field span2"},Ym={class:"form-footer"},Jm=["disabled"],Xm=["disabled"],Qm={class:"list-sec"},Zm={class:"sec-title"},ey={key:0,class:"empty muted"},ty={class:"item-main"},ny={class:"tag"},ry=["onClick"],sy={key:0,class:"muted item-meta"},oy={key:1,class:"muted num item-meta"},iy=["onClick"],ay=["onClick"],ly=["onClick"],uy=["onClick"],cy={key:0,class:"item-sub"},dy={key:0,class:"muted2"},fy={key:1,class:"muted"},py={key:1,class:"dp-foot muted num"},hy=Vt({__name:"DayPanel",props:{date:{}},setup(e){const t=e,n=N(!0),s=N(null),o=N(void 0),a=N([]),u=N([]),f=N(""),h=N([]),y=at(()=>"loc-list-"+t.date),m=at(()=>t.date===xt());async function w(){n.value=!0,s.value=await jr(),o.value=await mn(t.date),a.value=await Kv(t.date),u.value=await Fs(!0),h.value=await il(),f.value=o.value&&o.value.location||await Ev(),n.value=!1}dn(w),mt(()=>t.date,w),mt(Gs,()=>{w()});const C=at(()=>u.value.filter(H=>H.archived!==1));function S(H){if(!H)return"";const W=u.value.find(Y=>Y.id===H);return W?W.name:"已删除项目"}const M=at(()=>s.value?zs(o.value,t.date,s.value,m.value):null),B=at(()=>a.value.reduce((H,W)=>H+(W.minutes||0),0)),oe=N(!1);async function ae(){oe.value||(oe.value=!0,await vd(t.date,f.value),await w(),nr(),Be("上班打卡成功"),oe.value=!1)}async function T(){oe.value||(oe.value=!0,await Ov(t.date),await w(),nr(),Be("下班打卡成功"),oe.value=!1)}async function E(){await $v(t.date,f.value),nr(),Be("地点已更新")}const X=N(!1),de=at(()=>{var H;return((H=o.value)==null?void 0:H.kind)==="leave"});function ie(){if(o.value&&o.value.clock_in_at){X.value=!0;return}te(!0)}async function te(H){X.value=!1,await Dv(t.date,H),await w(),nr(),Be(H?"已标记为休假":"已取消休假")}const O=N(null),j=N(""),ce=N(null);mt(O,async H=>{var W;H&&(await ts(),(W=ce.value)==null||W.focus())});function ke(H){var Y,Ae;const W=H==="in"?(Y=o.value)==null?void 0:Y.clock_in_at:(Ae=o.value)==null?void 0:Ae.clock_out_at;O.value=H,j.value=W?Vn(W):H==="in"?"09:00":"18:00"}function J(){O.value=null}async function xe(){const H=O.value;H&&(O.value=null,j.value&&(await jv(t.date,H==="in"?"clock_in_at":"clock_out_at",j.value),await w(),nr(),Be("打卡时间已修改")))}const Ue=N(!1),rt=N("09:00"),We=N("18:00"),Ye=N(""),me=N(""),Me=N("");function Fe(){me.value=f.value,Me.value="",Ue.value=!Ue.value}async function De(){if(!rt.value||!We.value){Me.value="请填写上班与下班时间";return}await Iv(t.date,t.date+"T"+rt.value+":00",t.date+"T"+We.value+":00",Ye.value.trim(),me.value),Ue.value=!1,Ye.value="",Me.value="",await w(),nr(),Be("补卡已保存")}const Ce=N(""),Q=N("");mt(Ce,()=>{Q.value&&(Q.value="")});const Z=N(null),_e=N("dev"),Ve=N(null),ft=N(""),Yt=N(""),Jt=N(!1),je=at(()=>!!(Ce.value.trim()||Ve.value||ft.value.trim()||Yt.value.trim()));dn(async()=>{const H=await Sv();Z.value=H.project_id,_e.value=H.category});function k(){Ce.value="",Ve.value=null,ft.value="",Yt.value="",Q.value=""}async function _(){const H=Ce.value.trim();if(!H){Q.value="请填写工作内容";return}Jt.value||(Jt.value=!0,await Fv(t.date,{content:H,project_id:Z.value,category:_e.value,minutes:Ve.value&&Ve.value>0?Ve.value:null,takeaway:ft.value.trim()||null,remark:Yt.value.trim()||null}),k(),await w(),Be("记录已添加"),Jt.value=!1)}const x=N(null);function G(H){x.value=H}async function ne(H){const W=H.id,Y={content:H.content,project_id:H.project_id,category:H.category,minutes:H.minutes,takeaway:H.takeaway,remark:H.remark,is_milestone:H.is_milestone,needs_followup:H.needs_followup};await fa(W,Y),x.value=null,await w(),Be("修改已保存")}async function ue(H){await fa(H.id,{is_milestone:H.is_milestone?0:1}),await w()}async function ge(H){await fa(H.id,{needs_followup:H.needs_followup?0:1}),await w()}const ve=N(null);async function le(){ve.value&&ve.value.id&&await Nv(ve.value.id),ve.value=null,await w(),Be("记录已删除")}return(H,W)=>(F(),q("div",sm,[c("div",om,[c("div",im,se(Qt(pd)(e.date)),1)]),c("div",am,[W[25]||(W[25]=c("div",{class:"sec-title"},"出勤信息",-1)),c("div",lm,[c("div",um,[W[21]||(W[21]=c("label",null,"上班时间",-1)),O.value==="in"?(F(),q("div",cm,[$e(c("input",{ref_key:"timeInput",ref:ce,type:"time",class:"input time-input","onUpdate:modelValue":W[0]||(W[0]=Y=>j.value=Y),onKeydown:[jt(xe,["enter"]),jt(J,["esc"])]},null,544),[[Re,j.value]]),c("button",{class:"btn btn-primary btn-sm",onClick:xe},"确认"),c("button",{class:"btn btn-sm",onClick:J},"取消")])):(F(),q("div",dm,[c("span",{class:tt(["num",{"val-empty":!(o.value&&o.value.clock_in_at)}])},se(o.value&&o.value.clock_in_at?Qt(Vn)(o.value.clock_in_at):"未打卡"),3),o.value&&o.value.id?(F(),q("button",{key:0,class:"icon-btn",title:"修改上班时间",onClick:W[1]||(W[1]=Y=>ke("in"))},[Oe(ut,{name:"edit",size:13})])):Ee("",!0)]))]),c("div",fm,[W[22]||(W[22]=c("label",null,"下班时间",-1)),O.value==="out"?(F(),q("div",pm,[$e(c("input",{ref_key:"timeInput",ref:ce,type:"time",class:"input time-input","onUpdate:modelValue":W[2]||(W[2]=Y=>j.value=Y),onKeydown:[jt(xe,["enter"]),jt(J,["esc"])]},null,544),[[Re,j.value]]),c("button",{class:"btn btn-primary btn-sm",onClick:xe},"确认"),c("button",{class:"btn btn-sm",onClick:J},"取消")])):(F(),q("div",hm,[c("span",{class:tt(["num",{"val-empty":!(o.value&&o.value.clock_out_at)}])},se(o.value&&o.value.clock_out_at?Qt(Vn)(o.value.clock_out_at):"未打卡"),3),o.value&&o.value.id?(F(),q("button",{key:0,class:"icon-btn",title:"修改下班时间",onClick:W[3]||(W[3]=Y=>ke("out"))},[Oe(ut,{name:"edit",size:13})])):Ee("",!0)]))]),c("div",vm,[W[23]||(W[23]=c("label",null,"上班地点",-1)),$e(c("input",{class:"input","onUpdate:modelValue":W[4]||(W[4]=Y=>f.value=Y),list:y.value,placeholder:"可直接输入",title:"上班地点,可自由输入",onChange:E},null,40,mm),[[Re,f.value]]),c("datalist",{id:y.value},[(F(!0),q(Le,null,ct(h.value,Y=>(F(),q("option",{key:Y,value:Y},null,8,gm))),128))],8,ym)]),c("div",bm,[W[24]||(W[24]=c("label",null,"考勤状态",-1)),c("div",wm,[M.value?(F(),q(Le,{key:0},[c("span",{class:tt(["dot",M.value.status])},null,2),c("span",null,se(M.value.label),1),o.value&&o.value.kind==="makeup"?(F(),q("span",_m,"补卡")):Ee("",!0)],64)):(F(),q("span",km,"--"))])])]),o.value&&o.value.note?(F(),q("div",xm,"补卡说明:"+se(o.value.note),1)):Ee("",!0),c("div",Cm,[m.value&&(!o.value||!o.value.clock_in_at)?(F(),q("button",{key:0,class:"btn btn-primary btn-sm",disabled:oe.value,onClick:ae},"上班打卡",8,Sm)):m.value&&o.value&&o.value.clock_in_at&&!o.value.clock_out_at?(F(),q("button",{key:1,class:"btn btn-primary btn-sm",disabled:oe.value,onClick:T},"下班打卡",8,Em)):Ee("",!0),!m.value&&(!o.value||!o.value.clock_in_at)?(F(),q("button",{key:2,class:"btn btn-sm",onClick:Fe},"补卡")):Ee("",!0),de.value?(F(),q("button",{key:4,class:"btn btn-sm",disabled:oe.value,onClick:W[5]||(W[5]=Y=>te(!1))},"取消休假",8,Am)):(F(),q("button",{key:3,class:"btn btn-sm",disabled:oe.value,onClick:ie},"标记休假",8,$m))])]),Ue.value?(F(),q("div",Pm,[W[30]||(W[30]=c("div",{class:"sec-title"},"补卡登记",-1)),c("div",Tm,[c("div",Om,[W[26]||(W[26]=c("label",null,"上班时间",-1)),$e(c("input",{type:"time",class:"input","onUpdate:modelValue":W[6]||(W[6]=Y=>rt.value=Y)},null,512),[[Re,rt.value]])]),c("div",Mm,[W[27]||(W[27]=c("label",null,"下班时间",-1)),$e(c("input",{type:"time",class:"input","onUpdate:modelValue":W[7]||(W[7]=Y=>We.value=Y)},null,512),[[Re,We.value]])]),c("div",Im,[W[28]||(W[28]=c("label",null,"上班地点",-1)),$e(c("input",{class:"input",list:y.value,"onUpdate:modelValue":W[8]||(W[8]=Y=>me.value=Y),placeholder:"可直接输入"},null,8,jm),[[Re,me.value]])]),c("div",Dm,[W[29]||(W[29]=c("label",null,"补卡原因",-1)),$e(c("input",{class:"input","onUpdate:modelValue":W[9]||(W[9]=Y=>Ye.value=Y),placeholder:"如:外出拜访客户忘记打卡"},null,512),[[Re,Ye.value]])])]),Me.value?(F(),q("div",Rm,se(Me.value),1)):Ee("",!0),c("div",Lm,[c("button",{class:"btn btn-sm",onClick:W[10]||(W[10]=Y=>Ue.value=!1)},"取消"),c("button",{class:"btn btn-primary btn-sm",onClick:De},"保存补卡")])])):Ee("",!0),c("div",Km,[W[38]||(W[38]=c("div",{class:"sec-head"},[c("span",{class:"sec-title"},"新增工作记录"),c("span",{class:"muted form-hint"},"内容必填,其余选填")],-1)),c("div",Fm,[c("div",Nm,[W[31]||(W[31]=c("label",null,"工作内容(必填)",-1)),$e(c("input",{class:tt(["input",{invalid:Q.value}]),"onUpdate:modelValue":W[11]||(W[11]=Y=>Ce.value=Y),placeholder:"做了什么,一句话一条",onKeydown:jt(_,["enter"])},null,34),[[Re,Ce.value]]),Q.value?(F(),q("div",Vm,se(Q.value),1)):Ee("",!0)]),c("div",Bm,[W[33]||(W[33]=c("label",null,"所属项目",-1)),$e(c("select",{class:"select","onUpdate:modelValue":W[12]||(W[12]=Y=>Z.value=Y)},[W[32]||(W[32]=c("option",{value:null},"无项目",-1)),(F(!0),q(Le,null,ct(C.value,Y=>(F(),q("option",{key:Y.id,value:Y.id},se(Y.name),9,Um))),128))],512),[[Fn,Z.value]])]),c("div",qm,[W[34]||(W[34]=c("label",null,"工作分类",-1)),$e(c("select",{class:"select","onUpdate:modelValue":W[13]||(W[13]=Y=>_e.value=Y)},[(F(!0),q(Le,null,ct(Qt(Ws),Y=>(F(),q("option",{key:Y.key,value:Y.key},se(Y.label),9,Hm))),128))],512),[[Fn,_e.value]])]),c("div",Wm,[W[35]||(W[35]=c("label",null,"耗时(分钟)",-1)),$e(c("input",{class:"input",type:"number",min:"0","onUpdate:modelValue":W[14]||(W[14]=Y=>Ve.value=Y),placeholder:"选填"},null,512),[[Re,Ve.value,void 0,{number:!0}]])]),c("div",zm,[W[36]||(W[36]=c("label",null,"主要收获",-1)),$e(c("input",{class:"input","onUpdate:modelValue":W[15]||(W[15]=Y=>ft.value=Y),placeholder:"一句话:学到了什么"},null,512),[[Re,ft.value]])]),c("div",Gm,[W[37]||(W[37]=c("label",null,"备注",-1)),$e(c("textarea",{class:"textarea","onUpdate:modelValue":W[16]||(W[16]=Y=>Yt.value=Y),placeholder:"背景、链接、未决事项(选填)"},null,512),[[Re,Yt.value]])])]),c("div",Ym,[c("button",{class:"btn btn-sm",disabled:!je.value,onClick:k},"重置",8,Jm),c("button",{class:"btn btn-primary btn-sm",disabled:Jt.value,onClick:_},"添加记录",8,Xm)])]),c("div",Qm,[c("div",Zm,"工作记录("+se(a.value.length)+")",1),!a.value.length&&!n.value?(F(),q("div",ey,"暂无记录")):Ee("",!0),(F(!0),q(Le,null,ct(a.value,Y=>(F(),q("div",{key:Y.id,class:"item"},[c("div",ty,[c("span",ny,se(Qt(ol)(Y.category)),1),c("span",{class:"item-content",title:"点击编辑",onClick:Ae=>G(Y)},se(Y.content),9,ry),Y.project_id?(F(),q("span",sy,se(S(Y.project_id)),1)):Ee("",!0),Y.minutes?(F(),q("span",oy,se(Y.minutes)+" 分钟",1)):Ee("",!0),W[39]||(W[39]=c("span",{class:"flex1"},null,-1)),c("button",{class:"icon-btn",title:"编辑完整信息",onClick:Ae=>G(Y)},[Oe(ut,{name:"edit",size:14})],8,iy),c("button",{class:tt(["icon-btn",{active:Y.is_milestone===1}]),title:"成果标记",onClick:Ae=>ue(Y)},[Oe(ut,{name:"star",size:14})],10,ay),c("button",{class:tt(["icon-btn",{"active-warn":Y.needs_followup===1}]),title:"待跟进",onClick:Ae=>ge(Y)},[Oe(ut,{name:"flag",size:14})],10,ly),c("button",{class:"icon-btn",title:"删除",onClick:Ae=>ve.value=Y},[Oe(ut,{name:"close",size:14})],8,uy)]),Y.takeaway||Y.remark?(F(),q("div",cy,[Y.takeaway?(F(),q("div",dy,"收获:"+se(Y.takeaway),1)):Ee("",!0),Y.remark?(F(),q("div",fy,"备注:"+se(Y.remark),1)):Ee("",!0)])):Ee("",!0)]))),128)),a.value.length?(F(),q("div",py,[nn(" 共 "+se(a.value.length)+" 条事项 ",1),B.value?(F(),q(Le,{key:0},[nn(" · "+se((B.value/60).toFixed(1))+" 小时",1)],64)):Ee("",!0)])):Ee("",!0)]),Oe(cr,{open:!!ve.value,title:"删除确认",message:ve.value?"将删除工作记录「"+ve.value.content+"」。删除后不可恢复。":"","confirm-text":"删除",danger:"",onCancel:W[17]||(W[17]=Y=>ve.value=null),onConfirm:le},null,8,["open","message"]),Oe(cr,{open:X.value,title:"标记休假确认",message:"该日已有打卡记录,标记休假将清空上下班时间。是否继续?","confirm-text":"标记休假",danger:"",onCancel:W[18]||(W[18]=Y=>X.value=!1),onConfirm:W[19]||(W[19]=Y=>te(!0))},null,8,["open"]),Oe(kv,{open:!!x.value,item:x.value,projects:u.value,date:e.date,onCancel:W[20]||(W[20]=Y=>x.value=null),onSave:ne},null,8,["open","item","projects","date"])]))}}),md=Gt(hy,[["__scopeId","data-v-2e90c9d8"]]),vy={class:"cal-page"},my={class:"cal-toolbar"},yy={class:"cal-title num"},gy={class:"cal-head"},by={class:"cal-grid"},wy=["title","onClick"],_y={class:"cal-marks"},ky={key:0,class:"drawer"},xy={class:"drawer-head"},Cy={class:"drawer-body"},Sy=Vt({__name:"CalendarView",setup(e){const t=N(xt()),n=at(()=>Number(t.value.slice(0,4))),s=at(()=>Number(t.value.slice(5,7))-1),o=at(()=>n.value+" 年 "+(s.value+1)+" 月"),a=["一","二","三","四","五","六","日"],u=at(()=>{const X=(new Date(n.value,s.value,1).getDay()+6)%7,de=new Date(n.value,s.value+1,0).getDate(),ie=[];for(let te=0;te[ke.date,ke])),O=de[2],j=new Map;for(const ke of u.value){if(!ke.inMonth)continue;const J=zs(te.get(ke.date),ke.date,ie,ke.date===h),xe=O.filter(Ue=>Ue.date===ke.date);j.set(ke.date,{status:J.status,label:J.label,location:((ce=te.get(ke.date))==null?void 0:ce.location)||"",hasLog:xe.length>0,hasMilestone:xe.some(Ue=>Ue.is_milestone===1)})}f.value=j}mt([n,s],y,{immediate:!0}),mt(Gs,()=>{y()});function m(E){var X;return((X=f.value.get(E))==null?void 0:X.status)??""}function w(E){const X=f.value.get(E);return X?E+" · "+X.label+(X.location?" · "+X.location:""):E}function C(E){var X;return!!((X=f.value.get(E))!=null&&X.hasLog)}function S(E){var X;return!!((X=f.value.get(E))!=null&&X.hasMilestone)}function M(){t.value=Go(t.value,-1)}function B(){t.value=Go(t.value,1)}function oe(){t.value=xt()}const ae=N(null);function T(E,X){X&&(ae.value=E)}return mt(Ia,E=>{E&&(t.value=E,ae.value=E,Ia.value=null)},{immediate:!0}),(E,X)=>(F(),q("div",vy,[c("div",my,[c("button",{class:"icon-btn",onClick:M},[Oe(ut,{name:"chevron-left",size:16})]),c("span",yy,se(o.value),1),c("button",{class:"icon-btn",onClick:B},[Oe(ut,{name:"chevron-right",size:16})]),c("button",{class:"btn btn-sm",onClick:oe},"回到今天")]),c("div",gy,[(F(),q(Le,null,ct(a,de=>c("span",{key:de,class:"cal-week muted"},se(de),1)),64))]),c("div",by,[(F(!0),q(Le,null,ct(u.value,(de,ie)=>(F(),q("button",{key:ie,class:tt(["cal-cell",{blank:!de.inMonth,weekend:de.weekend,selected:ae.value===de.date}]),title:de.inMonth?w(de.date):void 0,onClick:te=>T(de.date,de.inMonth)},[de.inMonth?(F(),q(Le,{key:0},[c("span",{class:tt(["daynum num",{today:de.date===Qt(h)}])},se(Number(de.date.slice(8,10))),3),c("span",_y,[m(de.date)?(F(),q("span",{key:0,class:tt(["dot",m(de.date)])},null,2)):Ee("",!0),C(de.date)?(F(),It(ut,{key:1,name:"check-circle",size:12,class:"mark-log"})):Ee("",!0),S(de.date)?(F(),It(ut,{key:2,name:"star",size:12,class:"mark-star"})):Ee("",!0)])],64)):Ee("",!0)],10,wy))),128))]),Oe(ns,{name:"drawer"},{default:fr(()=>[ae.value?(F(),q("aside",ky,[c("div",xy,[X[1]||(X[1]=c("span",{class:"drawer-title"},"当日详情",-1)),c("button",{class:"icon-btn",onClick:X[0]||(X[0]=de=>ae.value=null)},[Oe(ut,{name:"close",size:16})])]),c("div",Cy,[Oe(md,{date:ae.value},null,8,["date"])])])):Ee("",!0)]),_:1})]))}}),Ey=Gt(Sy,[["__scopeId","data-v-2404dfbe"]]),$y={class:"detail-page"},Ay={class:"detail-toolbar"},Py=["value"],Ty=["disabled"],Oy=Vt({__name:"TodayView",setup(e){const t=N(xt()),n=at(()=>t.value===xt());function s(){t.value=Kn(t.value,-1)}function o(){t.value=Kn(t.value,1)}function a(){t.value=xt()}function u(f){const h=f.target.value;h&&(t.value=h)}return(f,h)=>(F(),q("div",$y,[c("div",Ay,[c("button",{class:"icon-btn",title:"前一天",onClick:s},[Oe(ut,{name:"chevron-left",size:16})]),c("span",{class:tt(["date-title num",{"is-today":n.value}])},se(Qt(pd)(t.value)),3),c("button",{class:"icon-btn",title:"后一天",onClick:o},[Oe(ut,{name:"chevron-right",size:16})]),c("input",{type:"date",class:"input w-date",value:t.value,onChange:u},null,40,Py),c("button",{class:"btn btn-sm",disabled:n.value,onClick:a},"回到今天",8,Ty)]),Oe(md,{date:t.value},null,8,["date"])]))}}),My=Gt(Oy,[["__scopeId","data-v-76243d98"]]),Iy={class:"stats"},jy={class:"cards"},Dy={class:"card stat-card"},Ry={class:"stat-num num"},Ly={class:"card stat-card"},Ky={class:"stat-num num"},Fy={class:"card stat-card"},Ny={class:"stat-num num"},Vy={class:"card stat-card"},By={class:"stat-num num"},Uy={class:"card section"},qy={class:"heat"},Hy=["title"],Wy={class:"two-col"},zy={class:"card section"},Gy={class:"bar-label"},Yy={class:"bar-track"},Jy={class:"muted num bar-num"},Xy={key:0,class:"muted"},Qy={class:"card section"},Zy={class:"bar-label"},eg={class:"bar-track"},tg={class:"muted num bar-num"},ng={key:0,class:"muted"},rg={class:"card section"},sg={class:"bar-label loc-label"},og={class:"bar-track"},ig={class:"muted num bar-num"},ag={key:0,class:"muted"},lg=Vt({__name:"StatsView",setup(e){const t=N({attendDays:0,totalHours:"0",itemCount:0,streak:0}),n=N([]),s=N([]),o=N([]),a=N([]);async function u(){const y=xt(),m="2000-01-01",w=await Promise.all([jr(),yi(m,y),gi(m,y),Fs(!0)]),C=w[0],S=w[1],M=w[2],B=w[3],oe=S.filter(J=>J.clock_in_at||J.kind==="makeup");let ae=0;for(const J of oe){const xe=zs(J,J.date,C,J.date===y);ae+=xe.workedMinutes??0}const T=new Set(M.map(J=>J.date));let E=0,X=y;for(T.has(X)||(X=Kn(y,-1));T.has(X);)E++,X=Kn(X,-1);t.value={attendDays:oe.length,totalHours:(ae/60).toFixed(1),itemCount:M.length,streak:E};const de=new Map;for(const J of oe){const xe=J.location||"未记录";de.set(xe,(de.get(xe)||0)+1)}a.value=Array.from(de.entries()).map(J=>({name:J[0],count:J[1],percent:Math.round(J[1]/(oe.length||1)*100)})).sort((J,xe)=>xe.count-J.count);const ie=M.length||1;s.value=Ws.map(J=>{const xe=M.filter(Ue=>Ue.category===J.key).length;return{key:J.key,label:J.label,count:xe,percent:Math.round(xe/ie*100)}}).filter(J=>J.count>0).sort((J,xe)=>xe.count-J.count);const te=new Map(B.map(J=>[J.id,J.name])),O=new Map;for(const J of M){const xe=J.project_id?te.get(J.project_id)||"已删除项目":"无项目";O.set(xe,(O.get(xe)||0)+1)}o.value=Array.from(O.entries()).map(J=>({name:J[0],count:J[1],percent:Math.round(J[1]/ie*100)})).sort((J,xe)=>xe.count-J.count);const j=new Map;for(const J of M)j.set(J.date,(j.get(J.date)||0)+1);const ce=Es(y),ke=[];for(let J=11;J>=0;J--){const xe=Kn(ce,-7*J),Ue=[];for(let rt=0;rt<7;rt++){const We=Kn(xe,rt);Ue.push({date:We,count:j.get(We)||0})}ke.push(Ue)}n.value=ke}dn(async()=>{await u()}),mt(Gs,()=>{u()});function f(y){return y===0?0:y===1?1:y<=3?2:y<=5?3:4}function h(y,m){return y+" · "+(m?m+" 条":"无记录")}return(y,m)=>(F(),q("div",Iy,[c("div",jy,[c("div",Dy,[m[0]||(m[0]=c("div",{class:"muted"},"出勤天数",-1)),c("div",Ry,se(t.value.attendDays),1)]),c("div",Ly,[m[1]||(m[1]=c("div",{class:"muted"},"累计工时(小时)",-1)),c("div",Ky,se(t.value.totalHours),1)]),c("div",Fy,[m[2]||(m[2]=c("div",{class:"muted"},"记录条数",-1)),c("div",Ny,se(t.value.itemCount),1)]),c("div",Vy,[m[3]||(m[3]=c("div",{class:"muted"},"连续记录(天)",-1)),c("div",By,se(t.value.streak),1)])]),c("div",Uy,[m[4]||(m[4]=c("div",{class:"section-title"},"记录热力图(近 12 周)",-1)),c("div",qy,[(F(!0),q(Le,null,ct(n.value,(w,C)=>(F(),q("div",{key:C,class:"heat-col"},[(F(!0),q(Le,null,ct(w,S=>(F(),q("span",{key:S.date,class:tt(["heat-cell","lv"+f(S.count)]),title:h(S.date,S.count)},null,10,Hy))),128))]))),128))]),m[5]||(m[5]=qp('
少多
',1))]),c("div",Wy,[c("div",zy,[m[6]||(m[6]=c("div",{class:"section-title"},"分类分布",-1)),(F(!0),q(Le,null,ct(s.value,w=>(F(),q("div",{key:w.key,class:"bar-row"},[c("span",Gy,se(w.label),1),c("span",Yy,[c("span",{class:"bar-fill",style:or({width:w.percent+"%"})},null,4)]),c("span",Jy,se(w.count)+" 条 · "+se(w.percent)+"%",1)]))),128)),s.value.length?Ee("",!0):(F(),q("div",Xy,"暂无数据"))]),c("div",Qy,[m[7]||(m[7]=c("div",{class:"section-title"},"项目投入",-1)),(F(!0),q(Le,null,ct(o.value,w=>(F(),q("div",{key:w.name,class:"bar-row"},[c("span",Zy,se(w.name),1),c("span",eg,[c("span",{class:"bar-fill",style:or({width:w.percent+"%"})},null,4)]),c("span",tg,se(w.count)+" 条 · "+se(w.percent)+"%",1)]))),128)),o.value.length?Ee("",!0):(F(),q("div",ng,"暂无数据"))])]),c("div",rg,[m[8]||(m[8]=c("div",{class:"section-title"},"地点分布(按出勤天)",-1)),(F(!0),q(Le,null,ct(a.value,w=>(F(),q("div",{key:w.name,class:"bar-row"},[c("span",sg,se(w.name),1),c("span",og,[c("span",{class:"bar-fill",style:or({width:w.percent+"%"})},null,4)]),c("span",ig,se(w.count)+" 天 · "+se(w.percent)+"%",1)]))),128)),a.value.length?Ee("",!0):(F(),q("div",ag,"暂无数据"))])]))}}),ug=Gt(lg,[["__scopeId","data-v-73e5ba49"]]);async function cg(e,t,n){const s=xt(),o=await Promise.all([jr(),yi(e,t),gi(e,t),Fs(!0),Bv(e,t)]),a=o[0],u=o[1],f=o[2],h=o[3],y=o[4];let m=0,w=0,C=0;for(const O of u){(O.clock_in_at||O.kind==="makeup")&&m++,O.kind==="makeup"&&C++;const j=zs(O,O.date,a,O.date===s);w+=j.workedMinutes??0}const S=new Map;for(const O of u){if(!(O.clock_in_at||O.kind==="makeup"))continue;const j=O.location||"未记录";S.set(j,(S.get(j)||0)+1)}const M=Array.from(S.entries()).map(O=>({name:O[0],count:O[1]})).sort((O,j)=>j.count-O.count),B=f.length||1,oe=Ws.map(O=>{const j=f.filter(ce=>ce.category===O.key).length;return{key:O.key,label:O.label,count:j,percent:Math.round(j/B*100)}}).filter(O=>O.count>0).sort((O,j)=>j.count-O.count),ae=new Map(h.map(O=>[O.id,O.name])),T=new Map;for(const O of f){const j=O.project_id?ae.get(O.project_id)||"已删除项目":"无项目";T.set(j,(T.get(j)||0)+1)}const E=Array.from(T.entries()).map(O=>({name:O[0],count:O[1]})).sort((O,j)=>j.count-O.count),X=f.filter(O=>O.is_milestone===1).map(O=>({date:O.date,content:O.content})),de=f.filter(O=>O.needs_followup===1).map(O=>({date:O.date,content:O.content,remark:O.remark||""})),ie=f.filter(O=>!!O.takeaway).map(O=>({date:O.date,text:O.takeaway})),te=y.map(O=>({weekStart:O.week_start,highlights:O.highlights||"",challenges:O.challenges||"",plan_next:O.plan_next||""}));return{range:{start:e,end:t,label:n},attendDays:m,totalHours:(w/60).toFixed(1),makeupCount:C,leaveCount:u.filter(O=>O.kind==="leave").length,itemCount:f.length,categoryStats:oe,projectStats:E,locationStats:M,milestones:X,followups:de,takeaways:ie,weekNotes:te}}function dg(e){const t=[];t.push("# 实习工作总结("+e.range.start+" ~ "+e.range.end+")"),t.push(""),t.push("## 一、考勤概况"),t.push(""),t.push("出勤 "+e.attendDays+" 天,累计工时 "+e.totalHours+" 小时,补卡 "+e.makeupCount+" 次"+(e.leaveCount?",请假 "+e.leaveCount+" 天":""));const n=e.locationStats.filter(s=>s.name!=="未记录");n.length&&t.push("其中:"+n.map(s=>s.name+" "+s.count+" 天").join(",")),t.push(""),t.push("## 二、工作内容分布"),t.push(""),t.push(e.categoryStats.length?e.categoryStats.map(s=>s.label+" "+s.percent+"%("+s.count+" 条)").join(","):"(无记录)"),t.push(""),t.push("## 三、项目投入"),t.push(""),t.push(e.projectStats.length?e.projectStats.map(s=>s.name+" "+s.count+" 条").join(","):"(无记录)"),t.push(""),t.push("## 四、主要成果"),t.push(""),e.milestones.length?e.milestones.forEach((s,o)=>t.push(o+1+". 【成果】"+s.content+"("+s.date+")")):t.push("(无)"),t.push(""),t.push("## 五、待跟进事项"),t.push(""),e.followups.length?e.followups.forEach(s=>t.push("- 【待跟进】"+s.content+(s.remark?"("+s.date+" 备注:"+s.remark+")":"("+s.date+")"))):t.push("(无)"),t.push(""),t.push("## 六、学习与成长"),t.push(""),e.takeaways.length?e.takeaways.forEach(s=>t.push("- "+s.text+"("+s.date+")")):t.push("(无)");for(const s of e.weekNotes)t.push(""),t.push("### 周记("+s.weekStart+" 起)"),t.push(""),t.push("- 本周亮点:"+(s.highlights||"(无)")),t.push("- 踩的坑:"+(s.challenges||"(无)")),t.push("- 下周计划:"+(s.plan_next||"(无)"));return t.push(""),t.join(` -`)}const fg="modulepreload",pg=function(e,t){return new URL(e,t).href},Lu={},yd=function(t,n,s){let o=Promise.resolve();if(n&&n.length>0){const u=document.getElementsByTagName("link"),f=document.querySelector("meta[property=csp-nonce]"),h=(f==null?void 0:f.nonce)||(f==null?void 0:f.getAttribute("nonce"));o=Promise.allSettled(n.map(y=>{if(y=pg(y,s),y in Lu)return;Lu[y]=!0;const m=y.endsWith(".css"),w=m?'[rel="stylesheet"]':"";if(!!s)for(let M=u.length-1;M>=0;M--){const B=u[M];if(B.href===y&&(!m||B.rel==="stylesheet"))return}else if(document.querySelector(`link[href="${y}"]${w}`))return;const S=document.createElement("link");if(S.rel=m?"stylesheet":fg,m||(S.as="script"),S.crossOrigin="",S.href=y,h&&S.setAttribute("nonce",h),document.head.appendChild(S),m)return new Promise((M,B)=>{S.addEventListener("load",M),S.addEventListener("error",()=>B(new Error(`Unable to preload CSS for ${y}`)))})}))}function a(u){const f=new Event("vite:preloadError",{cancelable:!0});if(f.payload=u,window.dispatchEvent(f),!f.defaultPrevented)throw u}return o.then(u=>{for(const f of u||[])f.status==="rejected"&&a(f.reason);return t().catch(a)})};/*! Capacitor: https://capacitorjs.com/ - MIT License */const hg=e=>{const t=new Map;t.set("web",{name:"web"});const n=e.CapacitorPlatforms||{currentPlatform:{name:"web"},platforms:t},s=(a,u)=>{n.platforms.set(a,u)},o=a=>{n.platforms.has(a)&&(n.currentPlatform=n.platforms.get(a))};return n.addPlatform=s,n.setPlatform=o,n},vg=e=>e.CapacitorPlatforms=hg(e),gd=vg(typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:typeof global<"u"?global:{});gd.addPlatform;gd.setPlatform;var Qr;(function(e){e.Unimplemented="UNIMPLEMENTED",e.Unavailable="UNAVAILABLE"})(Qr||(Qr={}));class pa extends Error{constructor(t,n,s){super(t),this.message=t,this.code=n,this.data=s}}const mg=e=>{var t,n;return e!=null&&e.androidBridge?"android":!((n=(t=e==null?void 0:e.webkit)===null||t===void 0?void 0:t.messageHandlers)===null||n===void 0)&&n.bridge?"ios":"web"},yg=e=>{var t,n,s,o,a;const u=e.CapacitorCustomPlatform||null,f=e.Capacitor||{},h=f.Plugins=f.Plugins||{},y=e.CapacitorPlatforms,m=()=>u!==null?u.name:mg(e),w=((t=y==null?void 0:y.currentPlatform)===null||t===void 0?void 0:t.getPlatform)||m,C=()=>w()!=="web",S=((n=y==null?void 0:y.currentPlatform)===null||n===void 0?void 0:n.isNativePlatform)||C,M=te=>{const O=X.get(te);return!!(O!=null&&O.platforms.has(w())||ae(te))},B=((s=y==null?void 0:y.currentPlatform)===null||s===void 0?void 0:s.isPluginAvailable)||M,oe=te=>{var O;return(O=f.PluginHeaders)===null||O===void 0?void 0:O.find(j=>j.name===te)},ae=((o=y==null?void 0:y.currentPlatform)===null||o===void 0?void 0:o.getPluginHeader)||oe,T=te=>e.console.error(te),E=(te,O,j)=>Promise.reject(`${j} does not have an implementation of "${O}".`),X=new Map,de=(te,O={})=>{const j=X.get(te);if(j)return console.warn(`Capacitor plugin "${te}" already registered. Cannot register plugins twice.`),j.proxy;const ce=w(),ke=ae(te);let J;const xe=async()=>(!J&&ce in O?J=typeof O[ce]=="function"?J=await O[ce]():J=O[ce]:u!==null&&!J&&"web"in O&&(J=typeof O.web=="function"?J=await O.web():J=O.web),J),Ue=(Fe,De)=>{var Ce,Q;if(ke){const Z=ke==null?void 0:ke.methods.find(_e=>De===_e.name);if(Z)return Z.rtype==="promise"?_e=>f.nativePromise(te,De.toString(),_e):(_e,Ve)=>f.nativeCallback(te,De.toString(),_e,Ve);if(Fe)return(Ce=Fe[De])===null||Ce===void 0?void 0:Ce.bind(Fe)}else{if(Fe)return(Q=Fe[De])===null||Q===void 0?void 0:Q.bind(Fe);throw new pa(`"${te}" plugin is not implemented on ${ce}`,Qr.Unimplemented)}},rt=Fe=>{let De;const Ce=(...Q)=>{const Z=xe().then(_e=>{const Ve=Ue(_e,Fe);if(Ve){const ft=Ve(...Q);return De=ft==null?void 0:ft.remove,ft}else throw new pa(`"${te}.${Fe}()" is not implemented on ${ce}`,Qr.Unimplemented)});return Fe==="addListener"&&(Z.remove=async()=>De()),Z};return Ce.toString=()=>`${Fe.toString()}() { [capacitor code] }`,Object.defineProperty(Ce,"name",{value:Fe,writable:!1,configurable:!1}),Ce},We=rt("addListener"),Ye=rt("removeListener"),me=(Fe,De)=>{const Ce=We({eventName:Fe},De),Q=async()=>{const _e=await Ce;Ye({eventName:Fe,callbackId:_e},De)},Z=new Promise(_e=>Ce.then(()=>_e({remove:Q})));return Z.remove=async()=>{console.warn("Using addListener() without 'await' is deprecated."),await Q()},Z},Me=new Proxy({},{get(Fe,De){switch(De){case"$$typeof":return;case"toJSON":return()=>({});case"addListener":return ke?me:We;case"removeListener":return Ye;default:return rt(De)}}});return h[te]=Me,X.set(te,{name:te,proxy:Me,platforms:new Set([...Object.keys(O),...ke?[ce]:[]])}),Me},ie=((a=y==null?void 0:y.currentPlatform)===null||a===void 0?void 0:a.registerPlugin)||de;return f.convertFileSrc||(f.convertFileSrc=te=>te),f.getPlatform=w,f.handleError=T,f.isNativePlatform=S,f.isPluginAvailable=B,f.pluginMethodNoop=E,f.registerPlugin=ie,f.Exception=pa,f.DEBUG=!!f.DEBUG,f.isLoggingEnabled=!!f.isLoggingEnabled,f.platform=f.getPlatform(),f.isNative=f.isNativePlatform(),f},gg=e=>e.Capacitor=yg(e),Zr=gg(typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:typeof global<"u"?global:{}),bd=Zr.registerPlugin;Zr.Plugins;class wd{constructor(t){this.listeners={},this.retainedEventArguments={},this.windowListeners={},t&&(console.warn(`Capacitor WebPlugin "${t.name}" config object was deprecated in v3 and will be removed in v4.`),this.config=t)}addListener(t,n){let s=!1;this.listeners[t]||(this.listeners[t]=[],s=!0),this.listeners[t].push(n);const a=this.windowListeners[t];a&&!a.registered&&this.addWindowListener(a),s&&this.sendRetainedArgumentsForEvent(t);const u=async()=>this.removeListener(t,n);return Promise.resolve({remove:u})}async removeAllListeners(){this.listeners={};for(const t in this.windowListeners)this.removeWindowListener(this.windowListeners[t]);this.windowListeners={}}notifyListeners(t,n,s){const o=this.listeners[t];if(!o){if(s){let a=this.retainedEventArguments[t];a||(a=[]),a.push(n),this.retainedEventArguments[t]=a}return}o.forEach(a=>a(n))}hasListeners(t){return!!this.listeners[t].length}registerWindowListener(t,n){this.windowListeners[n]={registered:!1,windowEventName:t,pluginEventName:n,handler:s=>{this.notifyListeners(n,s)}}}unimplemented(t="not implemented"){return new Zr.Exception(t,Qr.Unimplemented)}unavailable(t="not available"){return new Zr.Exception(t,Qr.Unavailable)}async removeListener(t,n){const s=this.listeners[t];if(!s)return;const o=s.indexOf(n);this.listeners[t].splice(o,1),this.listeners[t].length||this.removeWindowListener(this.windowListeners[t])}addWindowListener(t){window.addEventListener(t.windowEventName,t.handler),t.registered=!0}removeWindowListener(t){t&&(window.removeEventListener(t.windowEventName,t.handler),t.registered=!1)}sendRetainedArgumentsForEvent(t){const n=this.retainedEventArguments[t];n&&(delete this.retainedEventArguments[t],n.forEach(s=>{this.notifyListeners(t,s)}))}}const Ku=e=>encodeURIComponent(e).replace(/%(2[346B]|5E|60|7C)/g,decodeURIComponent).replace(/[()]/g,escape),Fu=e=>e.replace(/(%[\dA-F]{2})+/gi,decodeURIComponent);class bg extends wd{async getCookies(){const t=document.cookie,n={};return t.split(";").forEach(s=>{if(s.length<=0)return;let[o,a]=s.replace(/=/,"CAP_COOKIE").split("CAP_COOKIE");o=Fu(o).trim(),a=Fu(a).trim(),n[o]=a}),n}async setCookie(t){try{const n=Ku(t.key),s=Ku(t.value),o=`; expires=${(t.expires||"").replace("expires=","")}`,a=(t.path||"/").replace("path=",""),u=t.url!=null&&t.url.length>0?`domain=${t.url}`:"";document.cookie=`${n}=${s||""}${o}; path=${a}; ${u};`}catch(n){return Promise.reject(n)}}async deleteCookie(t){try{document.cookie=`${t.key}=; Max-Age=0`}catch(n){return Promise.reject(n)}}async clearCookies(){try{const t=document.cookie.split(";")||[];for(const n of t)document.cookie=n.replace(/^ +/,"").replace(/=.*/,`=;expires=${new Date().toUTCString()};path=/`)}catch(t){return Promise.reject(t)}}async clearAllCookies(){try{await this.clearCookies()}catch(t){return Promise.reject(t)}}}bd("CapacitorCookies",{web:()=>new bg});const wg=async e=>new Promise((t,n)=>{const s=new FileReader;s.onload=()=>{const o=s.result;t(o.indexOf(",")>=0?o.split(",")[1]:o)},s.onerror=o=>n(o),s.readAsDataURL(e)}),_g=(e={})=>{const t=Object.keys(e);return Object.keys(e).map(o=>o.toLocaleLowerCase()).reduce((o,a,u)=>(o[a]=e[t[u]],o),{})},kg=(e,t=!0)=>e?Object.entries(e).reduce((s,o)=>{const[a,u]=o;let f,h;return Array.isArray(u)?(h="",u.forEach(y=>{f=t?encodeURIComponent(y):y,h+=`${a}=${f}&`}),h.slice(0,-1)):(f=t?encodeURIComponent(u):u,h=`${a}=${f}`),`${s}&${h}`},"").substr(1):null,xg=(e,t={})=>{const n=Object.assign({method:e.method||"GET",headers:e.headers},t),o=_g(e.headers)["content-type"]||"";if(typeof e.data=="string")n.body=e.data;else if(o.includes("application/x-www-form-urlencoded")){const a=new URLSearchParams;for(const[u,f]of Object.entries(e.data||{}))a.set(u,f);n.body=a.toString()}else if(o.includes("multipart/form-data")||e.data instanceof FormData){const a=new FormData;if(e.data instanceof FormData)e.data.forEach((f,h)=>{a.append(h,f)});else for(const f of Object.keys(e.data))a.append(f,e.data[f]);n.body=a;const u=new Headers(n.headers);u.delete("content-type"),n.headers=u}else(o.includes("application/json")||typeof e.data=="object")&&(n.body=JSON.stringify(e.data));return n};class Cg extends wd{async request(t){const n=xg(t,t.webFetchExtra),s=kg(t.params,t.shouldEncodeUrlParams),o=s?`${t.url}?${s}`:t.url,a=await fetch(o,n),u=a.headers.get("content-type")||"";let{responseType:f="text"}=a.ok?t:{};u.includes("application/json")&&(f="json");let h,y;switch(f){case"arraybuffer":case"blob":y=await a.blob(),h=await wg(y);break;case"json":h=await a.json();break;case"document":case"text":default:h=await a.text()}const m={};return a.headers.forEach((w,C)=>{m[C]=w}),{data:h,headers:m,status:a.status,url:a.url}}async get(t){return this.request(Object.assign(Object.assign({},t),{method:"GET"}))}async post(t){return this.request(Object.assign(Object.assign({},t),{method:"POST"}))}async put(t){return this.request(Object.assign(Object.assign({},t),{method:"PUT"}))}async patch(t){return this.request(Object.assign(Object.assign({},t),{method:"PATCH"}))}async delete(t){return this.request(Object.assign(Object.assign({},t),{method:"DELETE"}))}}bd("CapacitorHttp",{web:()=>new Cg});async function ll(e,t){const n=window;if(n.electronAPI&&n.electronAPI.saveFile){const u=await n.electronAPI.saveFile(e,t);return u&&u.saved?u.path:""}if(Zr.isNativePlatform()){const{Filesystem:u,Directory:f,Encoding:h}=await yd(async()=>{const{Filesystem:y,Directory:m,Encoding:w}=await import("./index-BYlgk7tc.js");return{Filesystem:y,Directory:m,Encoding:w}},[],import.meta.url);try{return(await u.writeFile({path:e,data:t,directory:f.Documents,encoding:h.UTF8,recursive:!0})).uri}catch{return(await u.writeFile({path:e,data:t,directory:f.Cache,encoding:h.UTF8,recursive:!0})).uri}}const s=new Blob([t],{type:"text/plain;charset=utf-8"}),o=URL.createObjectURL(s),a=document.createElement("a");return a.href=o,a.download=e,a.click(),window.setTimeout(()=>URL.revokeObjectURL(o),1e4),""}const Sg=Object.freeze(Object.defineProperty({__proto__:null,downloadText:ll},Symbol.toStringTag,{value:"Module"}));async function Da(e){try{await navigator.clipboard.writeText(e)}catch{const t=document.createElement("textarea");t.value=e,t.style.position="fixed",t.style.opacity="0",document.body.appendChild(t),t.select(),document.execCommand("copy"),document.body.removeChild(t)}}async function Eg(e){const t=await Promise.all([bt("ai_base_url",""),bt("ai_api_key",""),bt("ai_model","")]),n=t[0].trim().replace(/\/+$/,""),s=t[1].trim(),o=t[2].trim();if(!n||!o)throw new Error("请先在设置页配置 AI 接口地址与模型名称");const a=n+"/chat/completions",u={"Content-Type":"application/json"};s&&(u.Authorization="Bearer "+s);const h=JSON.stringify({model:o,messages:[{role:"system",content:"你是一名严谨的中文助理。请将用户提供的工作总结 Markdown 草稿润色为通顺、专业、简洁的工作总结。要求:保留原有章节结构与全部事实数据(数字、日期、条目),不得虚构或遗漏内容,只输出 Markdown 正文。"},{role:"user",content:e}],temperature:.3});let y;try{y=await fetch(a,{method:"POST",headers:u,body:h})}catch{throw new Error("无法访问 AI 接口:请检查地址是否正确、服务端是否允许浏览器跨域访问")}if(!y.ok){let C="接口返回 "+y.status;try{const S=await y.json();S&&S.error&&S.error.message&&(C+=":"+S.error.message)}catch{}throw new Error(C)}const m=await y.json(),w=m&&m.choices&&m.choices[0]&&m.choices[0].message&&m.choices[0].message.content;if(!w)throw new Error("接口未返回内容");return String(w)}const $g={class:"report"},Ag={class:"report-toolbar"},Pg={class:"seg"},Tg=["onClick"],Og=["disabled"],Mg=["disabled"],Ig={key:0,class:"ai-error"},jg={class:"report-grid"},Dg={class:"report-left"},Rg={class:"card section"},Lg={class:"section-title"},Kg={class:"muted note-saved"},Fg={class:"card section"},Ng={class:"report-right"},Vg={key:0,class:"card section"},Bg={class:"sum-row"},Ug={class:"num"},qg={class:"sum-row"},Hg={class:"num"},Wg={class:"sum-row"},zg={class:"num"},Gg={class:"sum-row"},Yg={class:"num"},Jg={class:"sum-row"},Xg={class:"num"},Qg={class:"muted"},Zg={class:"num"},eb={key:0,class:"muted sum-empty"},tb={class:"muted"},nb={key:1,class:"muted sum-empty"},rb={class:"muted"},sb={key:2,class:"muted sum-empty"},ob={class:"muted"},ib={key:3,class:"muted sum-empty"},ab=Vt({__name:"ReportView",setup(e){const t=[{key:"week",label:"本周"},{key:"month",label:"本月"},{key:"all",label:"全部"},{key:"custom",label:"自定义"}],n=N("week"),s=N(Es(xt())),o=N(xt()),a=N(null),u=N(""),f=N(!1),h=N(!1),y=N(null),m=N(""),w=N(Es(xt())),C=N(""),S=N(""),M=N(""),B=N(!1);async function oe(){const O=await al(w.value);C.value=(O==null?void 0:O.highlights)||"",S.value=(O==null?void 0:O.challenges)||"",M.value=(O==null?void 0:O.plan_next)||"",B.value=!1}async function ae(){await Vv(w.value,{highlights:C.value.trim()||null,challenges:S.value.trim()||null,plan_next:M.value.trim()||null}),B.value=!0,await E()}function T(O){const j=xt();if(O==="week"){const ce=Es(j);return{start:ce,end:Kn(ce,6),label:"本周"}}if(O==="month"){const ce=j.slice(0,7);return{start:ce+"-01",end:j,label:ce+" 本月"}}return O==="all"?{start:"2000-01-01",end:j,label:"全部实习期"}:{start:s.value,end:o.value,label:s.value+" ~ "+o.value}}async function E(){f.value=!0;const O=T(n.value),j=await cg(O.start,O.end,O.label);a.value=j,u.value=dg(j),f.value=!1}mt(n,E),mt([s,o],()=>{n.value==="custom"&&E()}),dn(async()=>{await oe(),await E()});async function X(){const O=xt().replace(/-/g,""),j=await ll("实习工作总结_"+O+".md",u.value);Be(j?"总结已导出到:"+j:"总结已导出到系统下载目录")}async function de(){await Da(u.value),Be("总结已复制到剪贴板")}async function ie(){if(h.value)return;m.value="";const O=u.value.trim();if(!O){m.value="当前草稿为空,无法润色";return}h.value=!0;try{y.value=u.value,u.value=await Eg(O),Be("AI 润色完成")}catch(j){y.value=null,m.value=j instanceof Error?j.message:"润色失败"}h.value=!1}function te(){y.value!==null&&(u.value=y.value),y.value=null}return(O,j)=>(F(),q("div",$g,[c("div",Ag,[c("div",Pg,[(F(),q(Le,null,ct(t,ce=>c("button",{key:ce.key,class:tt(["seg-btn",{active:n.value===ce.key}]),onClick:ke=>n.value=ce.key},se(ce.label),11,Tg)),64))]),n.value==="custom"?(F(),q(Le,{key:0},[$e(c("input",{type:"date",class:"input w-date","onUpdate:modelValue":j[0]||(j[0]=ce=>s.value=ce)},null,512),[[Re,s.value]]),j[6]||(j[6]=c("span",{class:"muted"},"至",-1)),$e(c("input",{type:"date",class:"input w-date","onUpdate:modelValue":j[1]||(j[1]=ce=>o.value=ce)},null,512),[[Re,o.value]])],64)):Ee("",!0),j[10]||(j[10]=c("span",{class:"flex1"},null,-1)),c("button",{class:"btn btn-sm",disabled:h.value,onClick:ie},[Oe(ut,{name:"edit",size:14}),j[7]||(j[7]=nn("AI 润色 ",-1))],8,Og),y.value!==null?(F(),q("button",{key:1,class:"btn btn-sm",onClick:te},"还原润色前")):Ee("",!0),c("button",{class:"btn btn-sm",disabled:f.value,onClick:E},[Oe(ut,{name:"edit",size:14}),j[8]||(j[8]=nn("重新生成 ",-1))],8,Mg),c("button",{class:"btn btn-sm",onClick:de},"复制"),c("button",{class:"btn btn-primary btn-sm",onClick:X},[Oe(ut,{name:"export",size:14}),j[9]||(j[9]=nn("导出 Markdown ",-1))])]),m.value?(F(),q("div",Ig,se(m.value),1)):Ee("",!0),c("div",jg,[c("div",Dg,[c("div",Rg,[c("div",Lg,"本周周记("+se(w.value)+" 起)",1),j[11]||(j[11]=c("label",{class:"note-label muted"},"本周亮点",-1)),$e(c("textarea",{class:"textarea","onUpdate:modelValue":j[2]||(j[2]=ce=>C.value=ce),placeholder:"本周最有价值的一件事",onBlur:ae},null,544),[[Re,C.value]]),j[12]||(j[12]=c("label",{class:"note-label muted"},"踩的坑",-1)),$e(c("textarea",{class:"textarea","onUpdate:modelValue":j[3]||(j[3]=ce=>S.value=ce),placeholder:"遇到的问题与教训",onBlur:ae},null,544),[[Re,S.value]]),j[13]||(j[13]=c("label",{class:"note-label muted"},"下周计划",-1)),$e(c("textarea",{class:"textarea","onUpdate:modelValue":j[4]||(j[4]=ce=>M.value=ce),placeholder:"下周准备做什么",onBlur:ae},null,544),[[Re,M.value]]),c("div",Kg,se(B.value?"已保存":"失焦自动保存"),1)]),c("div",Fg,[j[14]||(j[14]=c("div",{class:"section-title"},"总结草稿(可编辑)",-1)),$e(c("textarea",{class:"textarea md-editor","onUpdate:modelValue":j[5]||(j[5]=ce=>u.value=ce),spellcheck:"false"},null,512),[[Re,u.value]])])]),c("div",Ng,[a.value?(F(),q("div",Vg,[j[20]||(j[20]=c("div",{class:"section-title"},"数据摘要",-1)),c("div",Bg,[j[15]||(j[15]=c("span",{class:"muted"},"出勤",-1)),c("span",Ug,se(a.value.attendDays)+" 天",1)]),c("div",qg,[j[16]||(j[16]=c("span",{class:"muted"},"工时",-1)),c("span",Hg,se(a.value.totalHours)+" 小时",1)]),c("div",Wg,[j[17]||(j[17]=c("span",{class:"muted"},"补卡",-1)),c("span",zg,se(a.value.makeupCount)+" 次",1)]),c("div",Gg,[j[18]||(j[18]=c("span",{class:"muted"},"请假",-1)),c("span",Yg,se(a.value.leaveCount)+" 天",1)]),c("div",Jg,[j[19]||(j[19]=c("span",{class:"muted"},"记录",-1)),c("span",Xg,se(a.value.itemCount)+" 条",1)]),j[21]||(j[21]=c("div",{class:"section-sub"},"分类分布",-1)),(F(!0),q(Le,null,ct(a.value.categoryStats,ce=>(F(),q("div",{key:ce.key,class:"sum-row"},[c("span",Qg,se(ce.label),1),c("span",Zg,se(ce.count)+" 条 · "+se(ce.percent)+"%",1)]))),128)),a.value.categoryStats.length?Ee("",!0):(F(),q("div",eb,"(无)")),j[22]||(j[22]=c("div",{class:"section-sub"},"主要成果",-1)),(F(!0),q(Le,null,ct(a.value.milestones,(ce,ke)=>(F(),q("div",{key:"m"+ke,class:"sum-item"},[nn(se(ce.content),1),c("span",tb,"("+se(ce.date)+")",1)]))),128)),a.value.milestones.length?Ee("",!0):(F(),q("div",nb,"(无)")),j[23]||(j[23]=c("div",{class:"section-sub"},"待跟进",-1)),(F(!0),q(Le,null,ct(a.value.followups,(ce,ke)=>(F(),q("div",{key:"f"+ke,class:"sum-item"},[nn(se(ce.content),1),c("span",rb,"("+se(ce.date)+")",1)]))),128)),a.value.followups.length?Ee("",!0):(F(),q("div",sb,"(无)")),j[24]||(j[24]=c("div",{class:"section-sub"},"学习与成长",-1)),(F(!0),q(Le,null,ct(a.value.takeaways,(ce,ke)=>(F(),q("div",{key:"t"+ke,class:"sum-item"},[nn(se(ce.text),1),c("span",ob,"("+se(ce.date)+")",1)]))),128)),a.value.takeaways.length?Ee("",!0):(F(),q("div",ib,"(无)"))])):Ee("",!0)])])]))}}),lb=Gt(ab,[["__scopeId","data-v-43f9c59b"]]),ub=["aria-label"],cb={class:"dialog-head"},db={class:"dialog-title"},fb={class:"dialog-body"},pb={class:"form-grid"},hb={class:"field span2"},vb={class:"seg"},mb={class:"field"},yb={class:"field"},gb={class:"field"},bb=["value"],wb={key:0,class:"field"},_b={class:"seg"},kb={class:"field span2"},xb={key:0,class:"form-error"},Cb={class:"dialog-btns"},Sb=Vt({__name:"TransactionDialog",props:{open:{type:Boolean},title:{},initial:{}},emits:["cancel","save"],setup(e,{emit:t}){const n=e,s=t,o=N("expense"),a=N("餐饮"),u=N(""),f=N(""),h=N(""),y=N(!1),m=N(!1),w=N(""),C=N(null);function S(ae){n.open&&ae.key==="Escape"&&s("cancel")}mt(()=>n.open,async ae=>{var T;ae?(o.value=n.initial.type==="income"?"income":"expense",a.value=n.initial.category,u.value=n.initial.amountYuan,f.value=n.initial.date,h.value=n.initial.note,y.value=n.initial.reimbursable===1,m.value=n.initial.reimbursed===1,w.value="",window.addEventListener("keydown",S),await ts(),(T=C.value)==null||T.focus()):window.removeEventListener("keydown",S)}),pr(()=>window.removeEventListener("keydown",S)),mt(o,ae=>{a.value=ae==="expense"?Wr[0]:zo[0]});const M=at(()=>o.value==="expense"?Wr:zo);function B(){return a.value&&M.value.includes(a.value)?a.value:M.value[0]}function oe(){const ae=String(u.value??"").trim(),T=Number(ae);if(!ae||!isFinite(T)||T<=0){w.value="请填写大于 0 的金额";return}if(!f.value){w.value="请选择日期";return}const E=o.value==="expense"&&y.value?1:0;s("save",{type:o.value,category:B(),amount:Math.round(T*100),date:f.value,note:String(h.value??"").trim(),reimbursable:E,reimbursed:E&&m.value?1:0})}return(ae,T)=>(F(),It(qs,{to:"body"},[Oe(ns,{name:"modal"},{default:fr(()=>[e.open?(F(),q("div",{key:0,class:"mask",onClick:T[11]||(T[11]=Mr(E=>s("cancel"),["self"]))},[c("div",{class:"dialog",role:"dialog","aria-label":e.title},[c("div",cb,[c("span",db,se(e.title),1),c("button",{class:"icon-btn",title:"关闭",onClick:T[0]||(T[0]=E=>s("cancel"))},[Oe(ut,{name:"close",size:16})])]),c("div",fb,[c("div",pb,[c("div",hb,[T[12]||(T[12]=c("label",null,"类型",-1)),c("div",vb,[c("button",{class:tt(["seg-btn",{active:o.value==="expense"}]),onClick:T[1]||(T[1]=E=>o.value="expense")},"支出",2),c("button",{class:tt(["seg-btn",{active:o.value==="income"}]),onClick:T[2]||(T[2]=E=>o.value="income")},"收入",2)])]),c("div",mb,[T[13]||(T[13]=c("label",null,"金额(元,必填)",-1)),$e(c("input",{ref_key:"amountInput",ref:C,class:tt(["input",{invalid:w.value}]),"onUpdate:modelValue":T[3]||(T[3]=E=>u.value=E),type:"number",min:"0",step:"0.01",placeholder:"0.00"},null,2),[[Re,u.value]])]),c("div",yb,[T[14]||(T[14]=c("label",null,"日期(必填)",-1)),$e(c("input",{class:"input",type:"date","onUpdate:modelValue":T[4]||(T[4]=E=>f.value=E)},null,512),[[Re,f.value]])]),c("div",gb,[T[15]||(T[15]=c("label",null,"分类",-1)),$e(c("select",{class:"select","onUpdate:modelValue":T[5]||(T[5]=E=>a.value=E)},[(F(!0),q(Le,null,ct(M.value,E=>(F(),q("option",{key:E,value:E},se(E),9,bb))),128))],512),[[Fn,a.value]])]),o.value==="expense"?(F(),q("div",wb,[T[16]||(T[16]=c("label",null,"报销状态",-1)),c("div",_b,[c("button",{class:tt(["seg-btn",{active:!y.value}]),onClick:T[6]||(T[6]=E=>{y.value=!1,m.value=!1})},"无需报销",2),c("button",{class:tt(["seg-btn",{active:y.value&&!m.value}]),onClick:T[7]||(T[7]=E=>{y.value=!0,m.value=!1})},"待报销",2),c("button",{class:tt(["seg-btn",{active:y.value&&m.value}]),onClick:T[8]||(T[8]=E=>{y.value=!0,m.value=!0})},"已报销",2)])])):Ee("",!0),c("div",kb,[T[17]||(T[17]=c("label",null,"备注",-1)),$e(c("textarea",{class:"textarea","onUpdate:modelValue":T[9]||(T[9]=E=>h.value=E),placeholder:"选填"},null,512),[[Re,h.value]])])]),w.value?(F(),q("div",xb,se(w.value),1)):Ee("",!0)]),c("div",Cb,[c("button",{class:"btn btn-sm",onClick:T[10]||(T[10]=E=>s("cancel"))},"取消"),c("button",{class:"btn btn-primary btn-sm",onClick:oe},"保存")])],8,ub)])):Ee("",!0)]),_:1})]))}}),Eb=Gt(Sb,[["__scopeId","data-v-edca3327"]]),$b={class:"ledger-page"},Ab={class:"ledger-toolbar"},Pb={class:"month-title num"},Tb={class:"cards"},Ob={class:"card stat-card"},Mb={class:"stat-num num amt-income"},Ib={class:"card stat-card"},jb={class:"stat-num num"},Db={class:"card stat-card"},Rb={class:"card stat-card"},Lb={class:"stat-num num amt-warn"},Kb={class:"card sec"},Fb={class:"form-grid"},Nb={class:"field span2"},Vb={class:"seg"},Bb={class:"field"},Ub={class:"field"},qb={class:"field"},Hb=["value"],Wb={key:0,class:"field"},zb={class:"field span2"},Gb={key:0,class:"form-error"},Yb={class:"form-footer"},Jb=["disabled"],Xb=["disabled"],Qb={key:0,class:"card sec"},Zb={class:"bar-label"},ew={class:"bar-track"},tw={class:"muted num bar-num"},nw={key:1,class:"card section"},rw={class:"form-error"},sw={class:"card table-card"},ow={class:"tx-table"},iw={class:"num"},aw={class:"tag"},lw={class:"td-note"},uw={key:0,class:"muted"},cw={key:1,class:"tx-done"},dw={key:2,class:"tx-pending"},fw={class:"ops"},pw=["onClick"],hw=["onClick"],vw=["onClick"],mw={key:0},yw={class:"muted vault-note num"},gw=Vt({__name:"LedgerView",setup(e){const t=N(xt()),n=N([]),s=N(!0),o=N("expense"),a=N(""),u=N(Wr[0]),f=N(xt()),h=N(""),y=N(!1),m=N(""),w=N(""),C=N(!1),S=N(!1),M=N(null),B=N({type:"expense",category:Wr[0],amountYuan:"",date:xt(),note:"",reimbursable:0,reimbursed:0}),oe=N(null),ae=at(()=>t.value.slice(0,7)+"-01"),T=at(()=>{const Q=Number(t.value.slice(0,4)),Z=Number(t.value.slice(5,7))-1,_e=new Date(Q,Z+1,0).getDate();return t.value.slice(0,7)+"-"+(_e<10?"0"+_e:String(_e))}),E=at(()=>Number(t.value.slice(0,4))+" 年 "+Number(t.value.slice(5,7))+" 月");async function X(){s.value=!0;try{n.value=await Yv(ae.value,T.value),w.value=""}catch(Q){w.value="账目加载失败:"+(Q instanceof Error?Q.stack||Q.message:String(Q)),Be("账目加载失败")}s.value=!1}dn(X),mt(t,X),mt(o,Q=>{u.value=Q==="expense"?Wr[0]:zo[0]});const de=at(()=>n.value.slice().sort((Q,Z)=>Q.date===Z.date?Z.id-Q.id:Q.date{let Q=0,Z=0,_e=0;for(const Ve of n.value)Ve.type==="income"?Q+=Ve.amount:(Z+=Ve.amount,Ve.reimbursable===1&&Ve.reimbursed!==1&&(_e+=Ve.amount));return{income:Q,expense:Z,pending:_e,balance:Q-Z}}),te=N("all"),O=N("all"),j=at(()=>de.value.filter(Q=>!(te.value!=="all"&&Q.type!==te.value||O.value==="pending"&&!(Q.type==="expense"&&Q.reimbursable===1&&Q.reimbursed!==1)||O.value==="done"&&!(Q.reimbursable===1&&Q.reimbursed===1)))),ce=at(()=>{const Q=new Map;let Z=0;for(const Ve of n.value)Ve.type==="expense"&&(Q.set(Ve.category,(Q.get(Ve.category)||0)+Ve.amount),Z+=Ve.amount);const _e=Z||1;return Array.from(Q.entries()).map(Ve=>({name:Ve[0],amount:Ve[1],percent:Math.round(Ve[1]/_e*100)})).sort((Ve,ft)=>ft.amount-Ve.amount)});function ke(Q){return(Q/100).toFixed(2)}function J(Q){return(Q.type==="income"?"+":"-")+ke(Q.amount)}function xe(){t.value=Go(t.value,-1)}function Ue(){t.value=Go(t.value,1)}function rt(){t.value=xt()}mt(a,()=>{m.value&&(m.value="")});async function We(){const Q=String(a.value??"").trim(),Z=Number(Q);if(!Q||!isFinite(Z)||Z<=0){m.value="请填写大于 0 的金额";return}if(!f.value){m.value="请选择日期";return}if(!C.value){C.value=!0;try{await Jv({type:o.value,category:u.value,amount:Math.round(Z*100),date:f.value,note:String(h.value??"").trim(),reimbursable:o.value==="expense"&&y.value?1:0,reimbursed:0})}catch(_e){Be("添加失败:"+(_e instanceof Error?_e.message:String(_e))),C.value=!1;return}a.value="",h.value="",y.value=!1,m.value="",await X(),Be("记账已添加"),C.value=!1}}const Ye=at(()=>String(a.value??"").trim()!==""||String(h.value??"").trim()!=="");function me(){a.value="",h.value="",y.value=!1,m.value=""}async function Me(Q){await Zv(Q.id),await X(),Be("已标记为已报销")}function Fe(Q){M.value=Q.id,B.value={type:Q.type,category:Q.category,amountYuan:ke(Q.amount),date:Q.date,note:Q.note||"",reimbursable:Q.reimbursable,reimbursed:Q.reimbursed},S.value=!0}async function De(Q){const Z=M.value;await Xv(Z,Q),S.value=!1,await X(),Be("账目已更新")}async function Ce(){oe.value&&oe.value.id&&await Qv(oe.value.id),oe.value=null,await X(),Be("账目已删除")}return(Q,Z)=>(F(),q("div",$b,[c("div",Ab,[c("button",{class:"icon-btn",onClick:xe},[Oe(ut,{name:"chevron-left",size:16})]),c("span",Pb,se(E.value),1),c("button",{class:"icon-btn",onClick:Ue},[Oe(ut,{name:"chevron-right",size:16})]),c("button",{class:"btn btn-sm",onClick:rt},"回到本月"),Z[13]||(Z[13]=c("span",{class:"flex1"},null,-1)),$e(c("select",{class:"select w-filter","onUpdate:modelValue":Z[0]||(Z[0]=_e=>te.value=_e)},[...Z[11]||(Z[11]=[c("option",{value:"all"},"全部类型",-1),c("option",{value:"expense"},"仅支出",-1),c("option",{value:"income"},"仅收入",-1)])],512),[[Fn,te.value]]),$e(c("select",{class:"select w-filter","onUpdate:modelValue":Z[1]||(Z[1]=_e=>O.value=_e)},[...Z[12]||(Z[12]=[c("option",{value:"all"},"全部报销",-1),c("option",{value:"pending"},"待报销",-1),c("option",{value:"done"},"已报销",-1)])],512),[[Fn,O.value]])]),c("div",Tb,[c("div",Ob,[Z[14]||(Z[14]=c("div",{class:"muted"},"本月收入(元)",-1)),c("div",Mb,se(ke(ie.value.income)),1)]),c("div",Ib,[Z[15]||(Z[15]=c("div",{class:"muted"},"本月支出(元)",-1)),c("div",jb,se(ke(ie.value.expense)),1)]),c("div",Db,[Z[16]||(Z[16]=c("div",{class:"muted"},"本月结余(元)",-1)),c("div",{class:tt(["stat-num num",{"amt-income":ie.value.balance>=0,"amt-expense":ie.value.balance<0}])},se(ke(ie.value.balance)),3)]),c("div",Rb,[Z[17]||(Z[17]=c("div",{class:"muted"},"待报销(元)",-1)),c("div",Lb,se(ke(ie.value.pending)),1)])]),c("div",Kb,[Z[24]||(Z[24]=c("div",{class:"sec-head"},[c("span",{class:"sec-title"},"新增一笔"),c("span",{class:"muted form-hint"},"金额必填,回车快速添加")],-1)),c("div",Fb,[c("div",Nb,[Z[18]||(Z[18]=c("label",null,"类型",-1)),c("div",Vb,[c("button",{class:tt(["seg-btn",{active:o.value==="expense"}]),onClick:Z[2]||(Z[2]=_e=>o.value="expense")},"支出",2),c("button",{class:tt(["seg-btn",{active:o.value==="income"}]),onClick:Z[3]||(Z[3]=_e=>o.value="income")},"收入",2)])]),c("div",Bb,[Z[19]||(Z[19]=c("label",null,"金额(元,必填)",-1)),$e(c("input",{class:tt(["input",{invalid:m.value}]),"onUpdate:modelValue":Z[4]||(Z[4]=_e=>a.value=_e),type:"number",min:"0",step:"0.01",placeholder:"0.00",onKeydown:jt(We,["enter"])},null,34),[[Re,a.value]])]),c("div",Ub,[Z[20]||(Z[20]=c("label",null,"日期",-1)),$e(c("input",{class:"input",type:"date","onUpdate:modelValue":Z[5]||(Z[5]=_e=>f.value=_e)},null,512),[[Re,f.value]])]),c("div",qb,[Z[21]||(Z[21]=c("label",null,"分类",-1)),$e(c("select",{class:"select","onUpdate:modelValue":Z[6]||(Z[6]=_e=>u.value=_e)},[(F(!0),q(Le,null,ct(o.value==="expense"?Qt(Wr):Qt(zo),_e=>(F(),q("option",{key:_e,value:_e},se(_e),9,Hb))),128))],512),[[Fn,u.value]])]),o.value==="expense"?(F(),q("div",Wb,[Z[22]||(Z[22]=c("label",null,"报销",-1)),c("button",{class:tt(["toggle-btn",{on:y.value}]),onClick:Z[7]||(Z[7]=_e=>y.value=!y.value)},se(y.value?"需要报销":"无需报销"),3)])):Ee("",!0),c("div",zb,[Z[23]||(Z[23]=c("label",null,"备注",-1)),$e(c("input",{class:"input","onUpdate:modelValue":Z[8]||(Z[8]=_e=>h.value=_e),placeholder:"选填,如:客户现场午餐",onKeydown:jt(We,["enter"])},null,544),[[Re,h.value]])])]),m.value?(F(),q("div",Gb,se(m.value),1)):Ee("",!0),c("div",Yb,[c("button",{class:"btn btn-sm",disabled:!Ye.value,onClick:me},"重置",8,Jb),c("button",{class:"btn btn-primary btn-sm",disabled:C.value,onClick:We},"添加记录",8,Xb)])]),ce.value.length?(F(),q("div",Qb,[Z[25]||(Z[25]=c("div",{class:"sec-title"},"本月支出分类",-1)),(F(!0),q(Le,null,ct(ce.value,_e=>(F(),q("div",{key:_e.name,class:"bar-row"},[c("span",Zb,se(_e.name),1),c("span",ew,[c("span",{class:"bar-fill",style:or({width:_e.percent+"%"})},null,4)]),c("span",tw,se(ke(_e.amount))+" 元 · "+se(_e.percent)+"%",1)]))),128))])):Ee("",!0),w.value?(F(),q("div",nw,[c("div",rw,se(w.value),1),Z[26]||(Z[26]=c("div",{class:"muted loc-note"},"请将上方完整错误文字发送给开发者",-1))])):Ee("",!0),c("div",sw,[c("table",ow,[Z[28]||(Z[28]=c("thead",null,[c("tr",null,[c("th",null,"日期"),c("th",null,"分类"),c("th",null,"金额(元)"),c("th",null,"备注"),c("th",null,"报销"),c("th",{class:"th-ops"},"操作")])],-1)),c("tbody",null,[(F(!0),q(Le,null,ct(j.value,_e=>(F(),q("tr",{key:_e.id},[c("td",iw,se(_e.date),1),c("td",null,[c("span",aw,se(_e.category),1)]),c("td",{class:tt(["num",_e.type==="income"?"amt-income":"amt-expense"])},se(J(_e)),3),c("td",lw,se(_e.note||"--"),1),c("td",null,[_e.type!=="expense"||_e.reimbursable!==1?(F(),q("span",uw,"--")):_e.reimbursed===1?(F(),q("span",cw,"已报销")):(F(),q("span",dw,"待报销"))]),c("td",null,[c("div",fw,[_e.type==="expense"&&_e.reimbursable===1&&_e.reimbursed!==1?(F(),q("button",{key:0,class:"btn btn-xs",onClick:Ve=>Me(_e)},"标记已报销",8,pw)):Ee("",!0),c("button",{class:"btn btn-xs",onClick:Ve=>Fe(_e)},"编辑",8,hw),c("button",{class:"btn btn-xs",onClick:Ve=>oe.value=_e},"删除",8,vw)])])]))),128)),!j.value.length&&!s.value?(F(),q("tr",mw,[...Z[27]||(Z[27]=[c("td",{colspan:"6",class:"empty muted"},"本月暂无账目",-1)])])):Ee("",!0)])])]),c("div",yw,"筛选结果 "+se(j.value.length)+" 条 / 本月共 "+se(n.value.length)+" 条",1),Oe(Eb,{open:S.value,title:(M.value,"编辑账目"),initial:B.value,onCancel:Z[9]||(Z[9]=_e=>S.value=!1),onSave:De},null,8,["open","title","initial"]),Oe(cr,{open:!!oe.value,title:"删除确认",message:oe.value?"将删除 "+oe.value.date+" 的账目("+oe.value.category+" "+ke(oe.value.amount)+" 元)。删除后不可恢复。":"","confirm-text":"删除",danger:"",onCancel:Z[10]||(Z[10]=_e=>oe.value=null),onConfirm:Ce},null,8,["open","message"])]))}}),bw=Gt(gw,[["__scopeId","data-v-0f950d19"]]),ww={class:"memo-page"},_w={class:"card memo-list"},kw={class:"pane-head"},xw={class:"pane-title"},Cw={class:"memo-scroll"},Sw=["onClick"],Ew={class:"memo-item-title"},$w={class:"muted memo-item-sub"},Aw={class:"muted num memo-item-time"},Pw={key:0,class:"muted empty"},Tw={class:"card memo-editor"},Ow={class:"editor-foot"},Mw={class:"muted foot-info"},Iw=["disabled"],jw=["disabled"],Dw={key:1,class:"empty muted editor-empty"},Rw=Vt({__name:"MemoView",setup(e){const t=N([]),n=N(null),s=N(!1),o=N(""),a=N(""),u=N(null),f=N(null);async function h(){if(t.value=await Uv(),n.value&&n.value.id){const ie=t.value.find(te=>te.id===n.value.id);ie&&(n.value=ie)}}dn(async()=>{await h(),t.value.length&&w(t.value[0]),window.addEventListener("keydown",y)}),pr(()=>window.removeEventListener("keydown",y)),mt(ja,async ie=>{if(!ie)return;t.value.length||await h();const te=t.value.find(O=>O.id===ie);ja.value=null,te&&C(te)},{immediate:!0});function y(ie){(ie.ctrlKey||ie.metaKey)&&ie.key.toLowerCase()==="s"&&s.value&&m.value&&(ie.preventDefault(),oe())}const m=at(()=>{if(!s.value)return!1;const ie=n.value?n.value.title:"",te=n.value?n.value.content:"";return o.value!==ie||a.value!==te});function w(ie){n.value=ie,s.value=!0,o.value=ie.title,a.value=ie.content}function C(ie){if(!(s.value&&n.value&&n.value.id===ie.id)){if(m.value){f.value={type:"select",memo:ie};return}w(ie)}}function S(){if(m.value){f.value={type:"new"};return}M()}function M(){n.value=null,s.value=!0,o.value="",a.value=""}function B(){n.value?w(n.value):M()}async function oe(){if(!o.value.trim()&&!a.value.trim()){Be("标题与内容不能都为空");return}if(n.value&&n.value.id)await Hv(n.value.id,o.value,a.value),Be("备忘已保存");else{const ie=await qv(o.value,a.value);n.value=ie,o.value=ie.title,a.value=ie.content,Be("备忘已创建")}await h()}function ae(){n.value&&n.value.id&&(u.value=n.value)}async function T(){u.value&&u.value.id&&(await Wv(u.value.id),Be("备忘已删除")),u.value=null,await h(),M()}function E(){const ie=f.value;f.value=null,ie&&(ie.type==="select"?w(ie.memo):M())}function X(ie){return(ie.content||"").replace(/\s+/g," ").slice(0,30)}function de(ie){return ie.replace("T"," ").slice(0,16)}return(ie,te)=>(F(),q("div",ww,[c("aside",_w,[c("div",kw,[c("span",xw,"备忘录("+se(t.value.length)+")",1),c("button",{class:"btn btn-primary btn-sm",onClick:S},"新建")]),c("div",Cw,[(F(!0),q(Le,null,ct(t.value,O=>(F(),q("div",{key:O.id,class:tt(["memo-item",{active:s.value&&n.value&&n.value.id===O.id}]),onClick:j=>C(O)},[c("div",Ew,se(O.title||"无标题"),1),c("div",$w,se(X(O)||"空"),1),c("div",Aw,se(de(O.updated_at)),1)],10,Sw))),128)),t.value.length?Ee("",!0):(F(),q("div",Pw,"暂无备忘"))])]),c("section",Tw,[s.value?(F(),q(Le,{key:0},[$e(c("input",{class:"input title-input","onUpdate:modelValue":te[0]||(te[0]=O=>o.value=O),placeholder:"标题"},null,512),[[Re,o.value]]),$e(c("textarea",{class:"textarea content-textarea","onUpdate:modelValue":te[1]||(te[1]=O=>a.value=O),placeholder:"内容"},null,512),[[Re,a.value]]),c("div",Ow,[c("span",Mw,[m.value?(F(),q(Le,{key:0},[nn("有未保存修改")],64)):n.value&&n.value.id?(F(),q(Le,{key:1},[nn("更新于 "+se(de(n.value.updated_at)),1)],64)):(F(),q(Le,{key:2},[nn("新备忘")],64))]),te[4]||(te[4]=c("span",{class:"flex1"},null,-1)),n.value&&n.value.id?(F(),q("button",{key:0,class:"btn btn-sm",onClick:ae},"删除")):Ee("",!0),c("button",{class:"btn btn-sm",disabled:!m.value,onClick:B},"放弃修改",8,Iw),c("button",{class:"btn btn-primary btn-sm",disabled:!m.value,onClick:oe},"保存",8,jw)])],64)):(F(),q("div",Dw,"选择左侧备忘,或点击右上角新建"))]),Oe(cr,{open:!!u.value,title:"删除确认",message:u.value?"将删除备忘「"+(u.value.title||"无标题")+"」。删除后不可恢复。":"","confirm-text":"删除",danger:"",onCancel:te[2]||(te[2]=O=>u.value=null),onConfirm:T},null,8,["open","message"]),Oe(cr,{open:!!f.value,title:"未保存提示",message:"当前备忘有未保存的修改,继续操作将丢失这些修改。","confirm-text":"放弃修改并继续",onCancel:te[3]||(te[3]=O=>f.value=null),onConfirm:E},null,8,["open"])]))}}),Lw=Gt(Rw,[["__scopeId","data-v-74d60dba"]]),Kw=["aria-label"],Fw={class:"dialog-head"},Nw={class:"dialog-title"},Vw={class:"dialog-body"},Bw={class:"form-grid"},Uw={class:"field span2"},qw={class:"field span2"},Hw={class:"field span2"},Ww={class:"pwd-row"},zw={class:"field span2"},Gw={key:0,class:"form-error"},Yw={class:"dialog-btns"},Jw=Vt({__name:"CredentialDialog",props:{open:{type:Boolean},title:{},initial:{}},emits:["cancel","save"],setup(e,{emit:t}){const n=e,s=t,o=N(""),a=N(""),u=N(""),f=N(""),h=N(""),y=N(null);function m(S){n.open&&S.key==="Escape"&&s("cancel")}mt(()=>n.open,async S=>{var M;S?(o.value=n.initial.system,a.value=n.initial.account,u.value=n.initial.password,f.value=n.initial.remark,h.value="",window.addEventListener("keydown",m),await ts(),(M=y.value)==null||M.focus()):window.removeEventListener("keydown",m)}),pr(()=>window.removeEventListener("keydown",m));function w(){const S="ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz23456789",M="!@#$%^&*",B=crypto.getRandomValues(new Uint8Array(14));let oe="";for(let ae=0;ae(F(),It(qs,{to:"body"},[Oe(ns,{name:"modal"},{default:fr(()=>[e.open?(F(),q("div",{key:0,class:"mask",onClick:M[6]||(M[6]=Mr(B=>s("cancel"),["self"]))},[c("div",{class:"dialog",role:"dialog","aria-label":e.title},[c("div",Fw,[c("span",Nw,se(e.title),1),c("button",{class:"icon-btn",title:"关闭",onClick:M[0]||(M[0]=B=>s("cancel"))},[Oe(ut,{name:"close",size:16})])]),c("div",Vw,[c("div",Bw,[c("div",Uw,[M[7]||(M[7]=c("label",null,"系统名称(必填)",-1)),$e(c("input",{ref_key:"systemInput",ref:y,class:"input","onUpdate:modelValue":M[1]||(M[1]=B=>o.value=B),placeholder:"如:企业邮箱 / OA / VPN"},null,512),[[Re,o.value]])]),c("div",qw,[M[8]||(M[8]=c("label",null,"账号(必填)",-1)),$e(c("input",{class:"input","onUpdate:modelValue":M[2]||(M[2]=B=>a.value=B),placeholder:"用户名、工号或邮箱"},null,512),[[Re,a.value]])]),c("div",Hw,[M[9]||(M[9]=c("label",null,"密码(必填)",-1)),c("div",Ww,[$e(c("input",{class:"input","onUpdate:modelValue":M[3]||(M[3]=B=>u.value=B),placeholder:"输入或点击生成"},null,512),[[Re,u.value]]),c("button",{class:"btn btn-sm",onClick:w},"生成")])]),c("div",zw,[M[10]||(M[10]=c("label",null,"备注",-1)),$e(c("textarea",{class:"textarea","onUpdate:modelValue":M[4]||(M[4]=B=>f.value=B),placeholder:"用途、到期时间、负责人等(选填)"},null,512),[[Re,f.value]])])]),h.value?(F(),q("div",Gw,se(h.value),1)):Ee("",!0)]),c("div",Yw,[c("button",{class:"btn btn-sm",onClick:M[5]||(M[5]=B=>s("cancel"))},"取消"),c("button",{class:"btn btn-primary btn-sm",onClick:C},"保存")])],8,Kw)])):Ee("",!0)]),_:1})]))}}),Xw=Gt(Jw,[["__scopeId","data-v-f383b0a6"]]),_d=15e4;function Jo(e){const t=new Uint8Array(e);let n="";for(let s=0;s{n.value&&(ti(),n.value=!1,y.value=[],w.value={},Be("长时间未操作,密码库已自动锁定"))},N_)}function O(){n.value&&te()}dn(async()=>{t.value=await xd(),window.addEventListener("click",O),window.addEventListener("keydown",O),n.value&&te()}),pr(()=>{window.removeEventListener("click",O),window.removeEventListener("keydown",O),ie!==null&&window.clearTimeout(ie)});const j=at(()=>{const Ce=m.value.trim().toLowerCase();return Ce?y.value.filter(Q=>(Q.system+" "+Q.account+" "+(Q.remark||"")).toLowerCase().includes(Ce)):y.value});async function ce(){if(!s.value){if(u.value="",!o.value){u.value="请输入主密码";return}if(o.value.length<6){u.value="主密码至少 6 位";return}if(o.value!==a.value){u.value="两次输入的主密码不一致";return}s.value=!0;try{await Zw(o.value),o.value="",a.value="",n.value=!0,te(),await de(),Be("主密码已设置,密码库已解锁")}catch(Ce){u.value=Ce instanceof Error?Ce.message:"设置失败"}s.value=!1}}async function ke(){if(!s.value){if(h.value="",!f.value){h.value="请输入主密码";return}s.value=!0;try{await e_(f.value),f.value="",n.value=!0,te(),await de()}catch(Ce){h.value=Ce instanceof Error?Ce.message:"解锁失败"}s.value=!1}}function J(){ti(),n.value=!1,y.value=[],w.value={},ie!==null&&window.clearTimeout(ie),Be("密码库已锁定")}async function xe(Ce){const Q=Ce.id;if(w.value[Q]){w.value[Q]=!1;return}try{Ce.passwordPlain=await ha(Q),w.value[Q]=!0}catch(Z){Be(Z instanceof Error?Z.message:"解密失败")}}async function Ue(Ce){try{const Q=await ha(Ce.id);await Da(Q),Be("密码已复制")}catch(Q){Be(Q instanceof Error?Q.message:"复制失败")}}async function rt(Ce){await Da(Ce.account),Be("账号已复制")}function We(){S.value=null,M.value={system:"",account:"",password:"",remark:""},C.value=!0}async function Ye(Ce){try{const Q=await ha(Ce.id);S.value=Ce.id,M.value={system:Ce.system,account:Ce.account,password:Q,remark:Ce.remark||""},C.value=!0}catch(Q){Be(Q instanceof Error?Q.message:"解密失败")}}async function me(Ce){const Q=S.value??void 0;await s_(Ce,Q),C.value=!1,await de(),Be(Q?"账号已更新":"账号已添加")}async function Me(){B.value&&B.value.id&&(await o_(B.value.id),Be("账号已删除")),B.value=null,await de()}function Fe(){ae.value="",T.value="",E.value="",X.value="",oe.value=!0}async function De(){X.value="";try{const Ce=await i_(ae.value,T.value);oe.value=!1,ae.value="",T.value="",E.value="",Be("主密码已修改,"+Ce+" 条账号密码已重新加密")}catch(Ce){X.value=Ce instanceof Error?Ce.message:"修改失败"}}return(Ce,Q)=>(F(),q("div",l_,[t.value===null?(F(),q("div",u_,"加载中")):n.value?(F(),q(Le,{key:2},[c("div",m_,[c("div",y_,[Oe(ut,{name:"search",size:14,class:"search-icon"}),$e(c("input",{class:"input","onUpdate:modelValue":Q[3]||(Q[3]=Z=>m.value=Z),placeholder:"搜索系统名称、账号或备注"},null,512),[[Re,m.value]])]),Q[16]||(Q[16]=c("span",{class:"flex1"},null,-1)),c("button",{class:"btn btn-sm",onClick:Fe},"修改主密码"),c("button",{class:"btn btn-sm",onClick:J},"锁定"),c("button",{class:"btn btn-primary btn-sm",onClick:We},"新增账号")]),c("div",g_,[c("table",b_,[Q[18]||(Q[18]=c("thead",null,[c("tr",null,[c("th",null,"系统名称"),c("th",null,"账号"),c("th",null,"密码"),c("th",null,"备注"),c("th",{class:"th-ops"},"操作")])],-1)),c("tbody",null,[(F(!0),q(Le,null,ct(j.value,Z=>(F(),q("tr",{key:Z.id},[c("td",w_,se(Z.system),1),c("td",null,[c("span",{class:"copyable",title:"点击复制账号",onClick:_e=>rt(Z)},se(Z.account),9,__)]),c("td",null,[c("div",k_,[c("span",x_,se(w.value[Z.id]?Z.passwordPlain:"........"),1),c("button",{class:"btn btn-xs",onClick:_e=>xe(Z)},se(w.value[Z.id]?"隐藏":"显示"),9,C_),c("button",{class:"btn btn-xs",onClick:_e=>Ue(Z)},"复制",8,S_)])]),c("td",E_,se(Z.remark||"--"),1),c("td",null,[c("div",$_,[c("button",{class:"btn btn-xs",onClick:_e=>Ye(Z)},"编辑",8,A_),c("button",{class:"btn btn-xs",onClick:_e=>B.value=Z},"删除",8,P_)])])]))),128)),j.value.length?Ee("",!0):(F(),q("tr",T_,[...Q[17]||(Q[17]=[c("td",{colspan:"5",class:"empty muted"},"暂无账号,点击右上角新增",-1)])]))])])]),c("div",O_,"共 "+se(y.value.length)+" 条账号记录 · 密码以 AES-256-GCM 加密存储于本机",1)],64)):(F(),q("div",c_,[c("div",d_,[Oe(ut,{name:"lock",size:26})]),t.value===!1?(F(),q(Le,{key:0},[Q[12]||(Q[12]=c("div",{class:"lock-title"},"设置主密码",-1)),Q[13]||(Q[13]=c("div",{class:"muted lock-tip"},"主密码用于加密保存在本机的账号密码,遗忘后无法找回,请务必牢记",-1)),$e(c("input",{type:"password",class:"input","onUpdate:modelValue":Q[0]||(Q[0]=Z=>o.value=Z),placeholder:"设置主密码(至少 6 位)",onKeydown:jt(ce,["enter"])},null,544),[[Re,o.value]]),$e(c("input",{type:"password",class:"input","onUpdate:modelValue":Q[1]||(Q[1]=Z=>a.value=Z),placeholder:"再次输入主密码",onKeydown:jt(ce,["enter"])},null,544),[[Re,a.value]]),u.value?(F(),q("div",f_,se(u.value),1)):Ee("",!0),c("button",{class:"btn btn-primary lock-btn",disabled:s.value,onClick:ce},"完成设置并解锁",8,p_)],64)):(F(),q(Le,{key:1},[Q[14]||(Q[14]=c("div",{class:"lock-title"},"密码库已锁定",-1)),Q[15]||(Q[15]=c("div",{class:"muted lock-tip"},"输入主密码解锁后查看与复制密码",-1)),$e(c("input",{type:"password",class:"input","onUpdate:modelValue":Q[2]||(Q[2]=Z=>f.value=Z),placeholder:"主密码",onKeydown:jt(ke,["enter"])},null,544),[[Re,f.value]]),h.value?(F(),q("div",h_,se(h.value),1)):Ee("",!0),c("button",{class:"btn btn-primary lock-btn",disabled:s.value,onClick:ke},"解锁",8,v_)],64))])),Oe(Xw,{open:C.value,title:S.value?"编辑账号":"新增账号",initial:M.value,onCancel:Q[4]||(Q[4]=Z=>C.value=!1),onSave:me},null,8,["open","title","initial"]),Oe(cr,{open:!!B.value,title:"删除确认",message:B.value?"将删除系统「"+B.value.system+"」的账号记录。删除后不可恢复。":"","confirm-text":"删除",danger:"",onCancel:Q[5]||(Q[5]=Z=>B.value=null),onConfirm:Me},null,8,["open","message"]),(F(),It(qs,{to:"body"},[Oe(ns,{name:"modal"},{default:fr(()=>[oe.value?(F(),q("div",{key:0,class:"mask",onClick:Q[11]||(Q[11]=Mr(Z=>oe.value=!1,["self"]))},[c("div",M_,[c("div",I_,[Q[19]||(Q[19]=c("span",{class:"dialog-title"},"修改主密码",-1)),c("button",{class:"icon-btn",title:"关闭",onClick:Q[6]||(Q[6]=Z=>oe.value=!1)},[Oe(ut,{name:"close",size:16})])]),c("div",j_,[c("div",D_,[Q[20]||(Q[20]=c("label",null,"旧主密码",-1)),$e(c("input",{type:"password",class:"input","onUpdate:modelValue":Q[7]||(Q[7]=Z=>ae.value=Z)},null,512),[[Re,ae.value]])]),c("div",R_,[Q[21]||(Q[21]=c("label",null,"新主密码(至少 6 位)",-1)),$e(c("input",{type:"password",class:"input","onUpdate:modelValue":Q[8]||(Q[8]=Z=>T.value=Z)},null,512),[[Re,T.value]])]),c("div",L_,[Q[22]||(Q[22]=c("label",null,"确认新主密码",-1)),$e(c("input",{type:"password",class:"input","onUpdate:modelValue":Q[9]||(Q[9]=Z=>E.value=Z)},null,512),[[Re,E.value]])]),X.value?(F(),q("div",K_,se(X.value),1)):Ee("",!0),Q[23]||(Q[23]=c("div",{class:"muted vp-tip"},"确认后所有账号密码将使用新主密码重新加密",-1))]),c("div",F_,[c("button",{class:"btn btn-sm",onClick:Q[10]||(Q[10]=Z=>oe.value=!1)},"取消"),c("button",{class:"btn btn-primary btn-sm",onClick:De},"确认修改")])])])):Ee("",!0)]),_:1})]))]))}}),B_=Gt(V_,[["__scopeId","data-v-6820bc9c"]]);function U_(e){return'"'+(e==null?"":String(e)).replace(/"/g,'""')+'"'}async function Nu(e,t){const s="\uFEFF"+t.map(f=>f.map(U_).join(",")).join(`\r -`);if(Zr.isNativePlatform()){const{downloadText:f}=await yd(async()=>{const{downloadText:h}=await Promise.resolve().then(()=>Sg);return{downloadText:h}},void 0,import.meta.url);return f(e,s)}const o=new Blob([s],{type:"text/csv;charset=utf-8"}),a=URL.createObjectURL(o),u=document.createElement("a");return u.href=a,u.download=e,u.click(),window.setTimeout(()=>URL.revokeObjectURL(a),1e4),""}class q_ extends Ir{constructor(){super("intern_worklog_users"),this.version(1).stores({user:"id, &username"})}}const Or=new q_,wi="intern_worklog",cl="dsh_session_user";function Ys(){try{const e=localStorage.getItem(cl);if(!e)return null;const t=JSON.parse(e);if(t&&t.userId&&t.username)return t}catch{}return null}function Sd(e){localStorage.setItem(cl,JSON.stringify(e))}function Ed(){localStorage.removeItem(cl)}const dl="dsh_cloud_creds";function $d(e,t){localStorage.setItem(dl,JSON.stringify({username:e,password:t}))}function _i(){try{const e=localStorage.getItem(dl);if(!e)return null;const t=JSON.parse(e);if(t&&t.username&&t.password)return t}catch{}return null}function Ad(){localStorage.removeItem(dl)}let ni=null;function Ns(e){ni===e&&ee||(ee&&sl(),nv(new fd(wi+"_"+e)),ni=e)}async function H_(e,t,n){const s=e.trim();if(s.length<2||s.length>20)throw new Error("用户名需 2 到 20 个字符");if(t.length<6)throw new Error("登录密码至少 6 位");if(await Or.user.where("username").equals(s).first())throw new Error("用户名已存在");const a=ul(),u=await Qo(t,a),f="u_"+Date.now().toString(36)+"_"+Math.random().toString(36).slice(2,6);await Or.user.add({id:f,username:s,pwd_hash:u,pwd_salt:a,created_at:new Date().toISOString()}),Ns(f),n&&await Pd()&&(await J_(),await Or.user.update(f,{legacy_imported_at:new Date().toISOString()}));const h={userId:f,username:s};return Sd(h),$d(h.username,t),h}async function W_(e,t){const n=e.trim(),s=await Or.user.where("username").equals(n).first();if(!s)throw new Error("用户不存在");if(await Qo(t,s.pwd_salt)!==s.pwd_hash)throw new Error("密码不正确");Ns(s.id);const a={userId:s.id,username:s.username};return Sd(a),$d(a.username,t),a}async function z_(){ti(),sl(),ni=null,Ed(),Ad()}async function G_(e,t){const n=Ys();if(!n)throw new Error("未登录");if(t.length<6)throw new Error("新密码至少 6 位");const s=await Or.user.get(n.userId);if(!s)throw new Error("用户不存在");if(await Qo(e,s.pwd_salt)!==s.pwd_hash)throw new Error("旧密码不正确");const a=ul(),u=await Qo(t,a);await Or.user.update(s.id,{pwd_hash:u,pwd_salt:a})}async function Y_(){const e=Ys();if(!e)throw new Error("未登录");ti(),sl(),ni=null,await Ir.delete(wi+"_"+e.userId),await Or.user.delete(e.userId),Ed(),Ad()}async function Pd(){return Ir.exists(wi)}async function J_(){if(!ee)throw new Error("用户数据库未就绪");const e=new fd(wi),t=await Promise.all([e.project.toArray(),e.work_log.toArray(),e.log_item.toArray(),e.attendance.toArray(),e.weekly_note.toArray(),e.setting.toArray(),e.memo.toArray(),e.credential.toArray()]);await ee.transaction("rw",[ee.project,ee.work_log,ee.log_item,ee.attendance,ee.weekly_note,ee.setting,ee.memo,ee.credential],async()=>{await Promise.all([ee.project.clear(),ee.work_log.clear(),ee.log_item.clear(),ee.attendance.clear(),ee.weekly_note.clear(),ee.setting.clear(),ee.memo.clear(),ee.credential.clear()]),t[0].length&&await ee.project.bulkAdd(t[0]),t[1].length&&await ee.work_log.bulkAdd(t[1]),t[2].length&&await ee.log_item.bulkAdd(t[2]),t[3].length&&await ee.attendance.bulkAdd(t[3]),t[4].length&&await ee.weekly_note.bulkAdd(t[4]),t[5].length&&await ee.setting.bulkAdd(t[5]),t[6].length&&await ee.memo.bulkAdd(t[6]),t[7].length&&await ee.credential.bulkAdd(t[7])});const n=t[0].length+t[1].length+t[2].length+t[3].length+t[4].length+t[6].length+t[7].length;return e.close(),n}const $s=N(""),Vs=["project","work_log","log_item","attendance","weekly_note","setting","memo","credential","transaction"],Ra=new Set(["sync_cursor","sync_last_time","sync_token","last_project","last_category"]),X_={project:"name",work_log:"date",attendance:"date",weekly_note:"week_start",setting:"key"};function Q_(){return typeof crypto<"u"&&crypto.randomUUID?crypto.randomUUID():"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,e=>{const t=Math.random()*16|0;return(e==="x"?t:t&3|8).toString(16)})}function Vu(e){return JSON.stringify(e)}async function Z_(e){return ee.table(e).toArray()}function La(e,t){return e==="setting"?t.key:t.id}async function e1(){for(const e of Vs){const t=ee.table(e),n=await t.toArray();for(const s of n){if(e==="setting"&&Ra.has(s.key))continue;const o={};s.uuid||(o.uuid=Q_()),s.updated_at||(o.updated_at=s.created_at||vt()),Object.keys(o).length&&await t.update(La(e,s),o)}}}async function t1(){return _i()!=null}async function n1(){return bt("sync_last_time","")}async function Td(e,t){const n=await fetch(e+"/api/auth/login",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({username:t.username.trim(),password:t.password})});if(!n.ok)throw new Error("云端账号或密码不正确");const s=await n.json();if(!s||!s.token)throw new Error("云端登录异常");return String(s.token)}async function r1(e,t){let n=await bt("sync_token","");return n||(n=await Td(e,t),await kt("sync_token",n),n)}let As=!1,jo=!1,Ka=!1,Gr=null,wn=null,Fa="",Bu=!1,Do=null;async function Yr(){if(As){jo=!0;return}try{if(!await t1())return;await Id(await Od()),$s.value=""}catch(e){$s.value=e instanceof Error?e.message:String(e)}}function s1(){if(Bu)return;Bu=!0,Do=tv(async()=>{const t={};for(const n of Vs)t[n]=await ee.table(n).count();return t}).subscribe({next:()=>{Ka||As||(Gr&&globalThis.clearTimeout(Gr),Gr=globalThis.setTimeout(()=>{Yr()},3e3))},error:()=>{}})}function o1(){Do&&(Do.unsubscribe(),Do=null),wn&&(wn.close(),wn=null,Fa=""),Gr&&(globalThis.clearTimeout(Gr),Gr=null)}function i1(e,t){const n=e+"|"+t;if(!(wn&&Fa===n)){wn&&(wn.close(),wn=null);try{wn=new EventSource(e+"/api/events?token="+encodeURIComponent(t)),Fa=n,wn.onmessage=()=>{Yr()}}catch{wn=null}}}async function fl(){return await bt("sync_base_url","")||a1}const a1="https://daywk.linyux.cn";async function Od(){const e=_i();if(!e)throw new Error("未登录,无法同步");return{baseUrl:await fl(),username:e.username,password:e.password}}async function Md(){const e=_i();if(!e)throw new Error("未登录");const t=await fl(),n={"Content-Type":"application/json"},s=JSON.stringify({username:e.username,password:e.password});let o=await fetch(t+"/api/auth/register",{method:"POST",headers:n,body:s});if(o.status===409){if(o=await fetch(t+"/api/auth/login",{method:"POST",headers:n,body:s}),!o.ok)throw new Error("云端已存在同名账号且密码不一致,请检查")}else if(!o.ok)throw new Error("云端绑定失败:"+o.status)}async function l1(){return Id(await Od())}function Uu(e,t,n){const s={};for(const o of Object.keys(t))o!=="id"&&(s[o]=t[o]);if(e==="log_item"){delete s.work_log_id,delete s.project_id;const o=t.work_log_id?n.workLog.get(t.work_log_id):null;o&&o.uuid&&(s.wuuid=o.uuid);const a=t.project_id?n.project.get(t.project_id):null;a&&a.uuid&&(s.puuid=a.uuid)}return s}async function qu(){const e=await ee.work_log.toArray(),t=await ee.project.toArray();return{workLog:new Map(e.map(n=>[n.id,n])),project:new Map(t.map(n=>[n.id,n]))}}let Ro=0;async function Id(e){if(As)return jo=!0,{pushed:0,pulled:0,removed:0,errors:0,at:""};As=!0,Ka=!0,Ro=0;try{const t=await u1(e);return jo&&(jo=!1,globalThis.setTimeout(()=>{Yr()},800)),t}finally{As=!1,Ka=!1}}async function u1(e){const t=e.baseUrl.trim().replace(/\/+$/,"");if(!t)throw new Error("请先配置同步服务地址");await e1();const n=await qu(),s=await ee.sync_mirror.toArray(),o=new Map;for(const E of s)o.set(E.table+"|"+E.uuid,E);const a={},u=[];let f=0;for(const E of Vs){let X=await Z_(E);E==="setting"&&(X=X.filter(ie=>!Ra.has(ie.key)));const de=new Map;for(const ie of X)de.set(ie.uuid,ie);for(const[ie,te]of de){const O=Uu(E,te,n),j=Vu(O),ce=o.get(E+"|"+ie);(!ce||ce.hash!==j)&&(a[E]=a[E]||[],a[E].push(O),f++)}for(const[ie,te]of o)ie.startsWith(E+"|")&&!de.has(te.uuid)&&u.push({table:E,uuid:te.uuid,deleted_at:vt()});a[E]=a[E]||[]}const h=await ee.tombstone.toArray();for(const E of h)u.push({table:E.table,uuid:E.uuid,deleted_at:E.deleted_at});const y=await r1(t,e),m=E=>fetch(t+"/api/sync",{method:"POST",headers:{"Content-Type":"application/json",Authorization:"Bearer "+E},body:JSON.stringify({device:"client",tables:a,tombstones:u})});let w=await m(y);if(w.status===401){await kt("sync_token","");const E=await Td(t,e);await kt("sync_token",E),w=await m(E)}if(!w.ok)throw new Error("同步服务返回 "+w.status);const C=await w.json(),S=C.tables||{},M=C.tombstones||[],B=await d1(S,M),oe=await qu(),ae=[];for(const E of Vs){const X=await ee.table(E).toArray();for(const de of X)E==="setting"&&Ra.has(de.key)||ae.push({table:E,uuid:de.uuid,hash:Vu(Uu(E,de,oe))})}await ee.sync_mirror.clear(),ae.length&&await ee.sync_mirror.bulkAdd(ae.map(E=>({...E}))),i1(t,y);const T=vt();if(await kt("sync_last_time",T),(B.pulled>0||B.removed>0)&&nr(),h.length){const E=new Set(h.map(X=>X.id));await ee.tombstone.where("id").anyOf(Array.from(E)).delete()}return{pushed:f,pulled:B.pulled,removed:B.removed,errors:B.errors,at:T}}let va=new Map,ma=new Map,c1=0;async function d1(e,t){let n=0,s=0;for(const o of Vs){const a=ee.table(o),u=await a.toArray(),f=new Map;for(const C of u)f.set(C.uuid,C);const h=X_[o]||null,y=new Map;if(h)for(const C of u){const S=C[h];S!=null&&S!==""&&y.set(String(S),C)}const m=new Set(t.filter(C=>C.table===o).map(C=>C.uuid)),w=e[o]||[];for(const C of w)try{if(m.has(C.uuid))continue;const S=f.get(C.uuid);if(S){const M=String(S.updated_at||"");if(String(C.updated_at||"")>M){const oe={...C};if(o==="setting"&&delete oe.key,o==="log_item"){const ae=C.wuuid?va.get(C.wuuid):null;if(!ae)continue;oe.work_log_id=ae,delete oe.wuuid,oe.project_id=C.puuid?ma.get(C.puuid)??null:S.project_id??null,delete oe.puuid}await a.update(S.id,oe),n++}}else{const M=h&&C[h]!=null&&C[h]!==""?String(C[h]):null,B=M?y.get(M):void 0;if(B&&B.uuid!==C.uuid){const oe=String(B.updated_at||"");if(String(C.updated_at||"")>=oe){o==="work_log"&&await ee.log_item.where("work_log_id").equals(B.id).modify({work_log_id:-1}),await a.delete(La(o,B)),await ee.tombstone.add({table:o,uuid:B.uuid,deleted_at:vt()});const T=await a.add({...C});o==="work_log"&&await ee.log_item.where("work_log_id").equals(-1).modify({work_log_id:T}),f.set(C.uuid,{...C,id:T}),h&&M&&y.set(M,{...C,id:T}),n++}else await ee.tombstone.add({table:o,uuid:C.uuid,deleted_at:vt()}),c1++}else{if(o==="log_item"){const ae=C.wuuid?va.get(C.wuuid):null;if(!ae)continue;C.work_log_id=ae,delete C.wuuid,C.project_id=C.puuid?ma.get(C.puuid)??null:null,delete C.puuid}const oe=await a.add({...C});f.set(C.uuid,{...C,id:oe}),h&&M&&y.set(M,{...C,id:oe}),n++}}}catch(S){Ro++,S instanceof Error?S.message:String(S)}for(const C of u)if(m.has(C.uuid))try{if(o==="work_log"){const M=(await a.toArray()).find(B=>B.date===C.date&&!m.has(B.uuid)&&B.uuid!==C.uuid);M&&C.id&&await ee.log_item.where("work_log_id").equals(C.id).modify({work_log_id:M.id})}await a.delete(La(o,C)),s++}catch{Ro++}if(o==="work_log"){const C=await a.toArray();va=new Map(C.map(S=>[S.uuid,S.id]))}if(o==="project"){const C=await a.toArray();ma=new Map(C.map(S=>[S.uuid,S.id]))}}return{pulled:n,removed:s,errors:Ro}}const f1={class:"settings"},p1={class:"card section"},h1={class:"muted acc-line"},v1={class:"ai-grid"},m1={class:"rule-item"},y1={class:"rule-item"},g1={class:"rule-item"},b1={key:0,class:"form-error"},w1={class:"rule-save"},_1={class:"card section"},k1={class:"rule-grid"},x1={class:"rule-item"},C1={class:"rule-item"},S1={class:"rule-item"},E1={class:"rule-item"},$1={class:"rule-item"},A1={class:"card section"},P1={class:"proj-add"},T1={key:0,class:"muted proj-tip"},O1=["onKeydown"],M1=["onClick"],I1=["onClick"],j1=["onClick"],D1={key:1,class:"muted"},R1={class:"card section"},L1={class:"card section"},K1={class:"muted acc-line"},F1={class:"rule-item"},N1={class:"rule-save"},V1=["disabled"],B1={key:0,class:"muted acc-line"},U1={key:1,class:"form-error"},q1={key:2,class:"form-error"},H1={class:"card section"},W1={class:"ai-grid"},z1={class:"rule-item"},G1={class:"rule-item"},Y1={class:"rule-item"},J1={class:"card section"},X1={class:"backup-row"},Q1={key:0,class:"import-error"},Z1=Vt({__name:"SettingsView",setup(e){var k;const t=N({work_start:"09:00",work_end:"18:00",grace_minutes:10,lunch_minutes:60,remind_weekly:"friday"}),n=N([]),s=N(""),o=N(""),a=N(""),u=N(""),f=N(""),h=N(""),y=N(null),m=N(""),w=N(null),C=N(null),S=N(""),M=N(((k=Ys())==null?void 0:k.username)||""),B=N(""),oe=N(""),ae=N(""),T=N(""),E=N(!1),X="0.2.0",de=N(""),ie=N(""),te=N(""),O=N(""),j=N(""),ce=N(!1),ke=N("");async function J(){var _;de.value=await fl(),ie.value=((_=_i())==null?void 0:_.username)||"",ke.value=await n1(),j.value=$s.value}mt($s,_=>{j.value=_});async function xe(){await kt("sync_base_url",de.value.trim()),Be("同步地址已保存")}async function Ue(){O.value="";try{await Md(),Be("云端绑定已重建")}catch(_){O.value=_ instanceof Error?_.message:"绑定失败"}}async function rt(){if(!ce.value){O.value="",j.value=$s.value,ce.value=!0;try{await xe();const _=await l1();ke.value=_.at,te.value="推送 "+_.pushed+" 条 · 拉取 "+_.pulled+" 条 · 删除 "+_.removed+" 条",j.value="",Be("同步完成")}catch(_){O.value=_ instanceof Error?_.message:"同步失败"}ce.value=!1}}async function We(){if(T.value="",oe.value!==ae.value){T.value="两次输入的新密码不一致";return}try{await G_(B.value,oe.value),B.value="",oe.value="",ae.value="",Be("登录密码已修改")}catch(_){T.value=_ instanceof Error?_.message:"修改失败"}}async function Ye(){await Y_(),window.location.reload()}async function me(){t.value=await jr(),n.value=await Fs(!0),a.value=(await il()).join(` -`),u.value=await bt("ai_base_url",""),f.value=await bt("ai_api_key",""),h.value=await bt("ai_model",""),await J()}async function Me(){await kt("ai_base_url",u.value.trim()),await kt("ai_api_key",f.value.trim()),await kt("ai_model",h.value.trim()),Be("AI 配置已保存")}async function Fe(){const _=xt(),x=await Promise.all([gi("2000-01-01",_),Fs(!0)]),G=x[0],ne=x[1],ue=new Map(ne.map(le=>[le.id,le.name])),ge=[["日期","分类","项目","内容","耗时(分钟)","成果","待跟进","收获","备注"]];for(const le of G)ge.push([le.date,ol(le.category),le.project_id&&ue.get(le.project_id)||"",le.content,le.minutes==null?"":le.minutes,le.is_milestone?"是":"",le.needs_followup?"是":"",le.takeaway||"",le.remark||""]);const ve=await Nu("工作记录_"+_.replace(/-/g,"")+".csv",ge);Be(ve?"CSV 已导出到:"+ve:"CSV 已导出到系统下载目录")}async function De(){const _=xt(),x=await Promise.all([jr(),yi("2000-01-01",_)]),G=x[0],ne=x[1],ue=["周日","周一","周二","周三","周四","周五","周六"],ge=[["日期","星期","状态","上班时间","下班时间","地点","类型","说明"]];for(const le of ne){const H=zs(le,le.date,G,le.date===_);ge.push([le.date,ue[rs(le.date).getDay()],H.label,le.clock_in_at?Vn(le.clock_in_at):"",le.clock_out_at?Vn(le.clock_out_at):"",le.location||"",le.kind==="makeup"?"补卡":le.kind==="leave"?"休假":"正常",le.note||""])}const ve=await Nu("考勤记录_"+_.replace(/-/g,"")+".csv",ge);Be(ve?"CSV 已导出到:"+ve:"CSV 已导出到系统下载目录")}dn(me);async function Ce(){await kt("work_start",t.value.work_start),await kt("work_end",t.value.work_end),await kt("grace_minutes",String(t.value.grace_minutes)),await kt("lunch_minutes",String(t.value.lunch_minutes)),await kt("remind_weekly",t.value.remind_weekly),Be("打卡规则已保存")}async function Q(){await hd(a.value.split(` -`)),Be("常用地点已保存")}async function Z(){const _=s.value.trim();if(_){try{await Av(_),o.value="",s.value=""}catch{o.value="项目名已存在"}await me()}}function _e(_){y.value=_.id,m.value=_.name}async function Ve(_){const x=m.value.trim();if(x)try{await Pv(_.id,x),o.value=""}catch{o.value="项目名已存在"}y.value=null,await me()}async function ft(_){await Tv(_.id,_.archived!==1),await me()}async function Yt(){try{const _=await em(),x=await ll("实习日志备份_"+xt().replace(/-/g,"")+".json",_);Be(x?"备份已导出到:"+x:"备份已导出到系统下载目录")}catch(_){Be("导出失败:"+(_ instanceof Error?_.message:String(_)))}}function Jt(_){const x=_.target,G=x.files&&x.files[0];if(S.value="",!G)return;const ne=G.name;G.text().then(ue=>{C.value={name:ne,text:ue}}),x.value=""}async function je(){if(C.value)try{await tm(C.value.text),C.value=null,S.value="",await me(),Be("数据导入完成")}catch(_){C.value=null,S.value=_ instanceof Error?_.message:"导入失败"}}return(_,x)=>(F(),q("div",f1,[c("div",p1,[x[23]||(x[23]=c("div",{class:"section-title"},"账号与隐私",-1)),c("div",h1,"版本 v"+se(Qt(X))+" · 当前用户:"+se(M.value)+" · 每位用户独立数据库隔离存储于本机 · 登录密码仅保存 PBKDF2 哈希",1),c("div",v1,[c("div",m1,[x[20]||(x[20]=c("label",null,"旧登录密码",-1)),$e(c("input",{type:"password",class:"input","onUpdate:modelValue":x[0]||(x[0]=G=>B.value=G)},null,512),[[Re,B.value]])]),c("div",y1,[x[21]||(x[21]=c("label",null,"新登录密码(至少 6 位)",-1)),$e(c("input",{type:"password",class:"input","onUpdate:modelValue":x[1]||(x[1]=G=>oe.value=G)},null,512),[[Re,oe.value]])]),c("div",g1,[x[22]||(x[22]=c("label",null,"确认新登录密码",-1)),$e(c("input",{type:"password",class:"input","onUpdate:modelValue":x[2]||(x[2]=G=>ae.value=G)},null,512),[[Re,ae.value]])])]),T.value?(F(),q("div",b1,se(T.value),1)):Ee("",!0),c("div",w1,[c("button",{class:"btn btn-primary btn-sm",onClick:We},"修改登录密码"),c("button",{class:"btn btn-sm btn-danger",onClick:x[3]||(x[3]=G=>E.value=!0)},"删除此用户及全部数据")])]),c("div",_1,[x[30]||(x[30]=c("div",{class:"section-title"},"打卡规则",-1)),c("div",k1,[c("div",x1,[x[24]||(x[24]=c("label",null,"上班时间",-1)),$e(c("input",{type:"time",class:"input","onUpdate:modelValue":x[4]||(x[4]=G=>t.value.work_start=G)},null,512),[[Re,t.value.work_start]])]),c("div",C1,[x[25]||(x[25]=c("label",null,"下班时间",-1)),$e(c("input",{type:"time",class:"input","onUpdate:modelValue":x[5]||(x[5]=G=>t.value.work_end=G)},null,512),[[Re,t.value.work_end]])]),c("div",S1,[x[26]||(x[26]=c("label",null,"迟到宽限(分钟)",-1)),$e(c("input",{type:"number",class:"input",min:"0","onUpdate:modelValue":x[6]||(x[6]=G=>t.value.grace_minutes=G)},null,512),[[Re,t.value.grace_minutes,void 0,{number:!0}]])]),c("div",E1,[x[27]||(x[27]=c("label",null,"午休扣除(分钟)",-1)),$e(c("input",{type:"number",class:"input",min:"0","onUpdate:modelValue":x[7]||(x[7]=G=>t.value.lunch_minutes=G)},null,512),[[Re,t.value.lunch_minutes,void 0,{number:!0}]])]),c("div",$1,[x[29]||(x[29]=c("label",null,"周记提醒",-1)),$e(c("select",{class:"select","onUpdate:modelValue":x[8]||(x[8]=G=>t.value.remind_weekly=G)},[...x[28]||(x[28]=[c("option",{value:"friday"},"每周五提醒",-1),c("option",{value:"off"},"关闭",-1)])],512),[[Fn,t.value.remind_weekly]])])]),c("div",{class:"rule-save"},[c("button",{class:"btn btn-primary btn-sm",onClick:Ce},"保存规则")])]),c("div",A1,[x[31]||(x[31]=c("div",{class:"section-title"},"项目管理",-1)),c("div",P1,[$e(c("input",{class:"input","onUpdate:modelValue":x[9]||(x[9]=G=>s.value=G),placeholder:"新项目名称",onKeydown:jt(Z,["enter"])},null,544),[[Re,s.value]]),c("button",{class:"btn btn-sm",onClick:Z},"添加")]),o.value?(F(),q("div",T1,se(o.value),1)):Ee("",!0),(F(!0),q(Le,null,ct(n.value,G=>(F(),q("div",{key:G.id,class:"proj-row"},[y.value===G.id?(F(),q(Le,{key:0},[$e(c("input",{class:"input","onUpdate:modelValue":x[10]||(x[10]=ne=>m.value=ne),onKeydown:jt(ne=>Ve(G),["enter"])},null,40,O1),[[Re,m.value]]),c("button",{class:"btn btn-sm",onClick:ne=>Ve(G)},"保存",8,M1),c("button",{class:"btn btn-sm",onClick:x[11]||(x[11]=ne=>y.value=null)},"取消")],64)):(F(),q(Le,{key:1},[c("span",{class:tt(["proj-name",{archived:G.archived===1}])},se(G.name),3),c("button",{class:"icon-btn",title:"重命名",onClick:ne=>_e(G)},[Oe(ut,{name:"edit",size:14})],8,I1),c("button",{class:"btn btn-sm",onClick:ne=>ft(G)},se(G.archived===1?"恢复":"归档"),9,j1)],64))]))),128)),n.value.length?Ee("",!0):(F(),q("div",D1,"暂无项目,先添加一个"))]),c("div",R1,[x[33]||(x[33]=c("div",{class:"section-title"},"常用地点",-1)),$e(c("textarea",{class:"textarea","onUpdate:modelValue":x[12]||(x[12]=G=>a.value=G),placeholder:"每行一个地点,如:公司、客户现场、出差、居家办公"},null,512),[[Re,a.value]]),c("div",{class:"rule-save"},[c("button",{class:"btn btn-primary btn-sm",onClick:Q},"保存地点"),x[32]||(x[32]=c("span",{class:"muted loc-note"},"打卡时可直接输入新地点,保存后自动加入列表",-1))])]),c("div",L1,[x[35]||(x[35]=c("div",{class:"section-title"},"多端数据同步",-1)),c("div",K1,"云端账号:"+se(ie.value||"未绑定")+" · 登录即自动绑定并同步(变更实时推送 + 每 5 分钟兜底);密码库以密文同步,主密码永不出本机",1),c("div",F1,[x[34]||(x[34]=c("label",null,"同步服务地址(默认即可)",-1)),$e(c("input",{class:"input","onUpdate:modelValue":x[13]||(x[13]=G=>de.value=G),placeholder:"https://daywk.linyux.cn"},null,512),[[Re,de.value]])]),c("div",N1,[c("button",{class:"btn btn-sm",onClick:xe},"保存地址"),c("button",{class:"btn btn-primary btn-sm",disabled:ce.value,onClick:rt},se(ce.value?"同步中":"立即同步"),9,V1),c("button",{class:"btn btn-sm",onClick:Ue},"重建云端绑定")]),te.value?(F(),q("div",B1,"上次同步:"+se(ke.value||"--")+" · "+se(te.value),1)):Ee("",!0),O.value?(F(),q("div",U1,se(O.value),1)):Ee("",!0),j.value?(F(),q("div",q1,"最近自动同步失败:"+se(j.value)+"(可点「立即同步」重试)",1)):Ee("",!0)]),c("div",H1,[x[40]||(x[40]=c("div",{class:"section-title"},"AI 润色配置(可选)",-1)),c("div",W1,[c("div",z1,[x[36]||(x[36]=c("label",null,"接口地址(OpenAI 兼容,到 /v1 为止)",-1)),$e(c("input",{class:"input","onUpdate:modelValue":x[14]||(x[14]=G=>u.value=G),placeholder:"https://api.example.com/v1"},null,512),[[Re,u.value]])]),c("div",G1,[x[37]||(x[37]=c("label",null,"API Key",-1)),$e(c("input",{class:"input","onUpdate:modelValue":x[15]||(x[15]=G=>f.value=G),placeholder:"sk-..."},null,512),[[Re,f.value]])]),c("div",Y1,[x[38]||(x[38]=c("label",null,"模型名称",-1)),$e(c("input",{class:"input","onUpdate:modelValue":x[16]||(x[16]=G=>h.value=G),placeholder:"如:deepseek-chat"},null,512),[[Re,h.value]])])]),c("div",{class:"rule-save"},[c("button",{class:"btn btn-primary btn-sm",onClick:Me},"保存 AI 配置"),x[39]||(x[39]=c("span",{class:"muted loc-note"},"配置仅保存在本机浏览器;总结页可用 AI 润色草稿,需服务端允许浏览器跨域",-1))])]),c("div",J1,[x[41]||(x[41]=c("div",{class:"section-title"},"数据备份",-1)),c("div",X1,[c("button",{class:"btn btn-sm",onClick:Yt},"导出 JSON 备份"),c("button",{class:"btn btn-sm",onClick:x[17]||(x[17]=G=>{var ne;return(ne=w.value)==null?void 0:ne.click()})},"导入 JSON 备份"),c("button",{class:"btn btn-sm",onClick:Fe},"导出工作记录 CSV"),c("button",{class:"btn btn-sm",onClick:De},"导出考勤 CSV"),c("input",{ref_key:"fileInput",ref:w,type:"file",accept:"application/json,.json",style:{display:"none"},onChange:Jt},null,544)]),S.value?(F(),q("div",Q1,se(S.value),1)):Ee("",!0),x[42]||(x[42]=c("div",{class:"muted backup-note"},"数据保存在浏览器 IndexedDB 中,建议定期导出 JSON 备份。",-1))]),Oe(cr,{open:!!C.value,title:"导入确认",message:C.value?"将从文件「"+C.value.name+"」导入备份。现有全部数据将被覆盖,且不可恢复,请先确认已导出当前备份。":"","confirm-text":"覆盖导入",danger:"",onCancel:x[18]||(x[18]=G=>C.value=null),onConfirm:je},null,8,["open","message"]),Oe(cr,{open:E.value,title:"删除用户确认",message:"将永久删除用户「"+M.value+"」及其全部数据:工作日志、考勤、备忘录、账号密码库都将被清除,且不可恢复。请确认。","confirm-text":"永久删除",danger:"",onCancel:x[19]||(x[19]=G=>E.value=!1),onConfirm:Ye},null,8,["open","message"])]))}}),e0=Gt(Z1,[["__scopeId","data-v-1a8e0505"]]),t0={class:"login-page"},n0={class:"card login-card"},r0={class:"login-brand"},s0={class:"brand-icon"},o0={class:"seg"},i0=["placeholder"],a0={key:1,class:"mig-row"},l0={key:2,class:"form-error"},u0=["disabled"],c0=Vt({__name:"LoginView",emits:["login"],setup(e,{emit:t}){const n=t,s=N("login"),o=N(""),a=N(""),u=N(""),f=N(!0),h=N(!1),y=N(""),m=N(!1);dn(async()=>{h.value=await Pd()});function w(S){s.value=S,y.value="",u.value=""}async function C(){if(!m.value){y.value="",m.value=!0;try{let S;if(s.value==="login")S=await W_(o.value,a.value);else{if(a.value.length<6){y.value="登录密码至少 6 位",m.value=!1;return}if(a.value!==u.value){y.value="两次输入的密码不一致",m.value=!1;return}S=await H_(o.value,a.value,f.value)}n("login",S)}catch(S){y.value=S instanceof Error?S.message:"操作失败"}m.value=!1}}return(S,M)=>(F(),q("div",t0,[c("div",n0,[c("div",r0,[c("div",s0,[Oe(ut,{name:"calendar",size:22})]),M[6]||(M[6]=c("div",{class:"login-title"},"实习工作日志",-1)),M[7]||(M[7]=c("div",{class:"muted login-sub"},"打卡 · 记录 · 总结 · 备忘录 · 密码库",-1)),M[8]||(M[8]=c("div",{class:"muted login-sub"},"每位用户独立数据库,数据彼此隔离并保存在本机",-1))]),c("div",o0,[c("button",{class:tt(["seg-btn",{active:s.value==="login"}]),onClick:M[0]||(M[0]=B=>w("login"))},"登录",2),c("button",{class:tt(["seg-btn",{active:s.value==="create"}]),onClick:M[1]||(M[1]=B=>w("create"))},"创建用户",2)]),$e(c("input",{class:"input","onUpdate:modelValue":M[2]||(M[2]=B=>o.value=B),placeholder:"用户名(2 到 20 个字符)",onKeydown:jt(C,["enter"])},null,544),[[Re,o.value]]),$e(c("input",{type:"password",class:"input","onUpdate:modelValue":M[3]||(M[3]=B=>a.value=B),placeholder:s.value==="login"?"登录密码":"设置登录密码(至少 6 位)",onKeydown:jt(C,["enter"])},null,40,i0),[[Re,a.value]]),s.value==="create"?$e((F(),q("input",{key:0,type:"password",class:"input","onUpdate:modelValue":M[4]||(M[4]=B=>u.value=B),placeholder:"再次输入密码",onKeydown:jt(C,["enter"])},null,544)),[[Re,u.value]]):Ee("",!0),s.value==="create"&&h.value?(F(),q("label",a0,[$e(c("input",{type:"checkbox","onUpdate:modelValue":M[5]||(M[5]=B=>f.value=B)},null,512),[[Rh,f.value]]),M[9]||(M[9]=c("span",null,"导入本机原有工作日志数据到此用户(原数据保留不删除)",-1))])):Ee("",!0),y.value?(F(),q("div",l0,se(y.value),1)):Ee("",!0),c("button",{class:"btn btn-primary login-btn",disabled:m.value,onClick:C},se(s.value==="login"?"登录":"创建并进入"),9,u0),M[10]||(M[10]=c("div",{class:"muted login-note"}," 登录后自动开启云端同步(密码会保存在本机用于云同步);系统只保存密码哈希,忘记密码将无法访问该用户数据 ",-1))])]))}}),d0=Gt(c0,[["__scopeId","data-v-d3d6c8cb"]]),f0={key:1,class:"app"},p0={class:"side"},h0=["data-tip","onClick"],v0={class:"main"},m0={class:"topbar"},y0={class:"title"},g0={class:"gsearch"},b0={key:0,class:"gs-panel"},w0={key:0,class:"gs-group muted"},_0=["onMousedown"],k0={class:"tag"},x0={class:"gs-text"},C0={class:"muted num gs-date"},S0={key:1,class:"gs-group muted"},E0=["onMousedown"],$0={class:"gs-text"},A0={class:"muted gs-sub"},P0={key:1,class:"gs-empty muted"},T0={class:"topbar-actions"},O0={class:"user-chip num"},M0=["disabled"],I0={class:"num"},j0={class:"content"},D0={class:"content-inner"},R0={class:"toast-wrap"},L0=Vt({__name:"App",setup(e){const t=rm(),n=N(Ys());async function s(me){n.value=me,Ns(me.userId),location.hash="#/calendar",de.value="calendar",await ke(),await Ye(),u();try{await Md(),await Yr()}catch{}Be("欢迎,"+me.username);const Me=sessionStorage.getItem("dsh_migrate_toast");Me&&(sessionStorage.removeItem("dsh_migrate_toast"),Be("已迁移原有数据 "+Me+" 条"))}async function o(){o1(),a!==null&&(window.clearInterval(a),a=null),await z_(),n.value=null,de.value="calendar",location.hash="#/calendar",Be("已退出登录")}let a=null;function u(){s1(),a!==null&&window.clearInterval(a),a=window.setInterval(()=>{Yr()},60*1e3),Yr()}const f=N(null),h=N(""),y=N(!1),m=N({logs:[],memos:[]});let w=null;const C=at(()=>!!(m.value.logs.length||m.value.memos.length));function S(){w&&window.clearTimeout(w);const me=h.value;w=window.setTimeout(async()=>{const Me=me.trim();if(!Me){m.value={logs:[],memos:[]};return}const Fe=await Promise.all([zv(Me,8),Gv(Me,4)]);m.value={logs:Fe[0],memos:Fe[1]}},200)}function M(){h.value="",m.value={logs:[],memos:[]},y.value=!1}function B(me){Ia.value=me.date,ie("calendar"),M()}function oe(me){ja.value=me.id,ie("memo"),M()}function ae(){window.setTimeout(()=>{y.value=!1},150)}function T(me){var Me;(me.ctrlKey||me.metaKey)&&me.key.toLowerCase()==="k"&&(me.preventDefault(),(Me=f.value)==null||Me.focus())}const E=[{key:"calendar",name:"日历",icon:"calendar"},{key:"today",name:"详情",icon:"edit"},{key:"stats",name:"统计",icon:"chart"},{key:"report",name:"总结",icon:"export"},{key:"ledger",name:"记账",icon:"wallet"},{key:"memo",name:"备忘录",icon:"memo"},{key:"vault",name:"密码库",icon:"lock"},{key:"settings",name:"设置",icon:"settings"}];function X(){const me=(location.hash||"").replace("#/","");return E.some(Me=>Me.key===me)?me:"calendar"}const de=N(X());window.addEventListener("hashchange",()=>{de.value=X()});function ie(me){location.hash="#/"+me}const te=at(()=>E.find(me=>me.key===de.value)||E[0]),O=N(xt()),j=N(void 0),ce=N(!1);async function ke(){if(j.value=await mn(O.value),ce.value=!1,new Date().getHours()<4){const Me=await mn(Kn(O.value,-1));ce.value=!!(Me&&Me.clock_in_at&&!Me.clock_out_at)}}const J=at(()=>{const me=j.value;return me&&me.clock_in_at&&!me.clock_out_at?!0:ce.value&&!(me&&me.clock_in_at)}),xe=at(()=>{const me=j.value;return!!(me&&me.clock_in_at&&me.clock_out_at)}),Ue=at(()=>{const me=j.value;return J.value?"下班打卡":xe.value?"已打卡 "+Vn(me==null?void 0:me.clock_in_at)+" - "+Vn(me==null?void 0:me.clock_out_at):"上班打卡"});async function rt(){if(J.value)try{await Mv()}catch{}else await vd(O.value);await ke(),nr()}mt(Gs,()=>{n.value&&ke()});const We=N(!1);async function Ye(){if((await jr()).remind_weekly==="off"){We.value=!1;return}const Me=new Date().getDay();if(Me===5||Me===6||Me===0){const Fe=await al(Es(O.value));We.value=!Fe||!Fe.highlights&&!Fe.challenges&&!Fe.plan_next}else We.value=!1}return dn(async()=>{window.addEventListener("keydown",T),n.value&&(Ns(n.value.userId),await ke(),await Ye(),u())}),(me,Me)=>{var Fe;return n.value?(F(),q("div",f0,[c("nav",p0,[(F(),q(Le,null,ct(E,De=>c("button",{key:De.key,class:tt(["nav-btn",{active:de.value===De.key}]),"data-tip":De.name,onClick:Ce=>ie(De.key)},[Oe(ut,{name:De.icon,size:18},null,8,["name"])],10,h0)),64))]),c("div",v0,[c("header",m0,[c("span",y0,se(te.value.name),1),c("div",g0,[Oe(ut,{name:"search",size:14,class:"gs-icon"}),$e(c("input",{ref_key:"gsInput",ref:f,class:"input gs-input","onUpdate:modelValue":Me[0]||(Me[0]=De=>h.value=De),placeholder:"搜索工作记录与备忘录(Ctrl+K)",onInput:S,onFocus:Me[1]||(Me[1]=De=>y.value=!0),onBlur:ae,onKeydown:jt(M,["esc"])},null,544),[[Re,h.value]]),y.value&&h.value.trim()?(F(),q("div",b0,[C.value?(F(),q(Le,{key:0},[m.value.logs.length?(F(),q("div",w0,"工作记录")):Ee("",!0),(F(!0),q(Le,null,ct(m.value.logs,De=>(F(),q("div",{key:"l"+De.id,class:"gs-item",onMousedown:Mr(Ce=>B(De),["prevent"])},[c("span",k0,se(Qt(ol)(De.category)),1),c("span",x0,se(De.content),1),c("span",C0,se(De.date),1)],40,_0))),128)),m.value.memos.length?(F(),q("div",S0,"备忘录")):Ee("",!0),(F(!0),q(Le,null,ct(m.value.memos,De=>(F(),q("div",{key:"m"+De.id,class:"gs-item",onMousedown:Mr(Ce=>oe(De),["prevent"])},[c("span",$0,se(De.title||"无标题"),1),c("span",A0,se(De.content),1)],40,E0))),128))],64)):(F(),q("div",P0,"无匹配结果"))])):Ee("",!0)]),Me[4]||(Me[4]=c("span",{class:"flex1"},null,-1)),c("div",T0,[We.value?(F(),q("button",{key:0,class:"week-tip",onClick:Me[2]||(Me[2]=De=>ie("report"))},[...Me[3]||(Me[3]=[c("span",{class:"dot",style:{background:"var(--warn)"}},null,-1),nn(" 填写本周周记 ",-1)])])):Ee("",!0),c("span",O0,se((Fe=n.value)==null?void 0:Fe.username),1),c("button",{class:"btn btn-sm",onClick:o},"退出"),c("button",{class:"btn btn-primary btn-sm",disabled:xe.value,onClick:rt},[Oe(ut,{name:xe.value?"check-circle":"clock",size:14},null,8,["name"]),c("span",I0,se(Ue.value),1)],8,M0)])]),c("main",j0,[c("div",D0,[de.value==="calendar"?(F(),It(Ey,{key:0})):de.value==="today"?(F(),It(My,{key:1})):de.value==="stats"?(F(),It(ug,{key:2})):de.value==="report"?(F(),It(lb,{key:3})):de.value==="ledger"?(F(),It(bw,{key:4})):de.value==="memo"?(F(),It(Lw,{key:5})):de.value==="vault"?(F(),It(B_,{key:6})):(F(),It(e0,{key:7}))])])]),c("div",R0,[Oe($h,{name:"toast"},{default:fr(()=>[(F(!0),q(Le,null,ct(Qt(t),De=>(F(),q("div",{key:De.id,class:"toast"},se(De.text),1))),128))]),_:1})])])):(F(),It(d0,{key:0,onLogin:s}))}}}),K0=Gt(L0,[["__scopeId","data-v-d5bd1ff7"]]);function pl(e,t){try{let n=document.getElementById("fatal-overlay");n||(n=document.createElement("div"),n.id="fatal-overlay",n.style.cssText="position:fixed;inset:0;z-index:99999;background:#FFFFFF;color:#1D2129;padding:20px;overflow:auto;font:13px/1.7 -apple-system,PingFang SC,Microsoft YaHei,sans-serif;",n.addEventListener("click",o=>{o.target===n&&n.parentElement&&n.parentElement.removeChild(n)}),document.body.appendChild(n));const s=document.createElement("div");s.style.cssText="border:1px solid #E5484D;border-radius:8px;padding:12px;margin-bottom:12px;word-break:break-all;white-space:pre-wrap;",s.textContent=e+` -`+t,n.appendChild(s)}catch{}}const Hu=Ys();Hu&&Ns(Hu.userId);const jd=Uh(K0);jd.config.errorHandler=(e,t,n)=>{const s=e;pl("应用内部错误(点击空白处关闭,请将以下内容发送给开发者)",s&&(s.stack||s.message)||String(e)+` -触发位置: `+n)};window.addEventListener("unhandledrejection",e=>{const t=e.reason;pl("未处理的异步错误(点击空白处关闭)",t&&(t.stack||t.message)||String(e.reason))});window.addEventListener("error",e=>{e.message&&e.message!=="ResizeObserver loop limit exceeded"&&pl("运行错误(点击空白处关闭)",e.message)});jd.mount("#app");"serviceWorker"in navigator&&location.protocol.startsWith("http")&&window.addEventListener("load",()=>{navigator.serviceWorker.register("sw.js").catch(()=>{})});export{wd as W,yd as _,xg as b,bd as r}; diff --git a/intern-log/dist/assets/index-CDIr69jA.css b/intern-log/dist/assets/index-CkA9n_Ns.css similarity index 93% rename from intern-log/dist/assets/index-CDIr69jA.css rename to intern-log/dist/assets/index-CkA9n_Ns.css index 74eb8da..09683dd 100644 --- a/intern-log/dist/assets/index-CDIr69jA.css +++ b/intern-log/dist/assets/index-CkA9n_Ns.css @@ -1 +1 @@ -.mask[data-v-f27041d4]{position:fixed;top:0;right:0;bottom:0;left:0;background:#1d212966;display:flex;align-items:center;justify-content:center;z-index:100}.dialog[data-v-f27041d4]{width:380px;max-width:calc(100vw - 32px);background:var(--bg-page);border-radius:var(--radius-lg);box-shadow:var(--shadow-float);padding:20px}.dialog-title[data-v-f27041d4]{font-size:14px;font-weight:600;color:var(--text-1)}.dialog-msg[data-v-f27041d4]{margin-top:8px;color:var(--text-2);font-size:13px;line-height:1.7;word-break:break-all}.dialog-btns[data-v-f27041d4]{margin-top:20px;display:flex;justify-content:flex-end;gap:8px}.btn-danger-solid[data-v-f27041d4]{background:var(--danger);border-color:var(--danger);color:#fff}.btn-danger-solid[data-v-f27041d4]:hover{background:#d13a3f}.modal-enter-active[data-v-f27041d4],.modal-leave-active[data-v-f27041d4]{transition:opacity .15s ease}.modal-enter-from[data-v-f27041d4],.modal-leave-to[data-v-f27041d4]{opacity:0}.mask[data-v-63bc0b48]{position:fixed;top:0;right:0;bottom:0;left:0;background:#1d212966;display:flex;align-items:center;justify-content:center;z-index:90}.dialog[data-v-63bc0b48]{width:560px;max-width:calc(100vw - 32px);max-height:85vh;background:var(--bg-page);border-radius:var(--radius-lg);box-shadow:var(--shadow-float);display:flex;flex-direction:column}.dialog-head[data-v-63bc0b48]{display:flex;align-items:flex-start;justify-content:space-between;padding:16px 20px 12px;border-bottom:1px solid var(--border);flex:none}.dialog-title[data-v-63bc0b48]{font-size:14px;font-weight:600;color:var(--text-1)}.dialog-sub[data-v-63bc0b48]{font-size:12px;margin-top:2px}.dialog-body[data-v-63bc0b48]{padding:16px 20px;overflow:auto}.dialog-btns[data-v-63bc0b48]{display:flex;justify-content:flex-end;gap:8px;padding:12px 20px 16px;border-top:1px solid var(--border);flex:none}.form-grid[data-v-63bc0b48]{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px 16px}.field.span2[data-v-63bc0b48]{grid-column:span 2}.field label[data-v-63bc0b48]{display:block;font-size:12px;color:var(--text-2);margin-bottom:4px}.form-error[data-v-63bc0b48]{color:var(--danger);font-size:12px;margin-top:4px}.input.invalid[data-v-63bc0b48],.input.invalid[data-v-63bc0b48]:focus{border-color:var(--danger)}.toggle-btn[data-v-63bc0b48]{height:32px;width:100%;border:1px solid var(--border-strong);background:var(--bg-page);border-radius:var(--radius-sm);cursor:pointer;font-size:13px;color:var(--text-2)}.toggle-btn[data-v-63bc0b48]:hover{background:var(--bg-hover)}.toggle-btn.on[data-v-63bc0b48]{color:var(--accent);border-color:var(--accent);background:var(--accent-bg)}.toggle-btn.onwarn[data-v-63bc0b48]{color:var(--warn);border-color:var(--warn)}.modal-enter-active[data-v-63bc0b48],.modal-leave-active[data-v-63bc0b48]{transition:opacity .15s ease}.modal-enter-from[data-v-63bc0b48],.modal-leave-to[data-v-63bc0b48]{opacity:0}.dp-head[data-v-2e90c9d8]{margin-bottom:12px}.dp-date[data-v-2e90c9d8]{font-size:14px;font-weight:600}.sec[data-v-2e90c9d8]{padding:14px 16px;margin-bottom:12px}.sec-title[data-v-2e90c9d8]{font-size:13px;font-weight:600;margin-bottom:10px;color:var(--text-1)}.sec-head[data-v-2e90c9d8]{display:flex;align-items:baseline;justify-content:space-between;gap:8px;margin-bottom:10px}.sec-head .sec-title[data-v-2e90c9d8]{margin-bottom:0}.form-hint[data-v-2e90c9d8]{font-size:12px}.att-grid[data-v-2e90c9d8]{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px 16px}.att-cell label[data-v-2e90c9d8],.field label[data-v-2e90c9d8]{display:block;font-size:12px;color:var(--text-2);margin-bottom:4px}.att-val[data-v-2e90c9d8]{display:flex;align-items:center;gap:6px;min-height:32px;font-size:13px}.status-val[data-v-2e90c9d8]{min-height:32px}.val-empty[data-v-2e90c9d8]{color:var(--text-3)}.edit-row[data-v-2e90c9d8]{display:flex;gap:6px;align-items:center;flex-wrap:wrap}.time-input[data-v-2e90c9d8]{width:104px}.att-note[data-v-2e90c9d8]{margin-top:10px;font-size:12px}.att-actions[data-v-2e90c9d8]{display:flex;gap:8px;margin-top:12px}.form-grid[data-v-2e90c9d8]{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px 16px}.field.span2[data-v-2e90c9d8]{grid-column:span 2}.form-footer[data-v-2e90c9d8]{display:flex;justify-content:flex-end;gap:8px;margin-top:12px;padding-top:12px;border-top:1px solid var(--border)}.form-error[data-v-2e90c9d8]{color:var(--danger);font-size:12px;margin-top:4px}.input.invalid[data-v-2e90c9d8]{border-color:var(--danger)}.input.invalid[data-v-2e90c9d8]:focus{border-color:var(--danger)}.list-sec[data-v-2e90c9d8]{margin-bottom:4px}.item[data-v-2e90c9d8]{border:1px solid var(--border);border-radius:var(--radius-sm);padding:8px 10px;margin-bottom:6px;background:var(--bg-page)}.item-main[data-v-2e90c9d8]{display:flex;align-items:center;gap:8px;min-height:26px;flex-wrap:wrap}.item-content[data-v-2e90c9d8]{cursor:text;word-break:break-all}.item-meta[data-v-2e90c9d8]{font-size:12px}.item-sub[data-v-2e90c9d8]{margin-top:6px;padding-top:6px;border-top:1px dashed var(--border);font-size:12px;display:flex;flex-direction:column;gap:2px}.empty[data-v-2e90c9d8]{text-align:center;padding:24px 0}.dp-foot[data-v-2e90c9d8]{margin-top:10px;font-size:12px;text-align:right}@media (max-width: 560px){.att-grid[data-v-2e90c9d8],.form-grid[data-v-2e90c9d8]{grid-template-columns:1fr}.field.span2[data-v-2e90c9d8]{grid-column:auto}}.cal-toolbar[data-v-2404dfbe]{display:flex;align-items:center;gap:10px;margin-bottom:12px}.cal-title[data-v-2404dfbe]{font-size:14px;font-weight:600;min-width:96px;text-align:center}.cal-head[data-v-2404dfbe]{display:grid;grid-template-columns:repeat(7,1fr);border-top:1px solid var(--border);border-left:1px solid var(--border)}.cal-week[data-v-2404dfbe]{text-align:center;padding:6px 0;font-size:12px;border-right:1px solid var(--border);border-bottom:1px solid var(--border)}.cal-grid[data-v-2404dfbe]{display:grid;grid-template-columns:repeat(7,1fr);border-top:1px solid var(--border);border-left:1px solid var(--border)}.cal-cell[data-v-2404dfbe]{min-height:92px;padding:6px 8px;text-align:left;background:var(--bg-page);border:none;border-right:1px solid var(--border);border-bottom:1px solid var(--border);cursor:pointer;display:block;font-size:13px}.cal-cell[data-v-2404dfbe]:hover{background:var(--bg-subtle)}.cal-cell.blank[data-v-2404dfbe]{cursor:default}.cal-cell.blank[data-v-2404dfbe]:hover{background:var(--bg-page)}.cal-cell.selected[data-v-2404dfbe]{background:var(--accent-bg)}.daynum.today[data-v-2404dfbe]{color:var(--accent);font-weight:600}.cal-cell.weekend .daynum[data-v-2404dfbe]{color:var(--text-3)}.cal-marks[data-v-2404dfbe]{display:flex;align-items:center;gap:4px;margin-top:8px;height:14px}.mark-log[data-v-2404dfbe]{color:var(--text-3)}.mark-star[data-v-2404dfbe]{color:var(--accent)}.drawer[data-v-2404dfbe]{position:fixed;top:0;right:0;bottom:0;width:min(420px,100%);background:var(--bg-page);border-left:1px solid var(--border);box-shadow:var(--shadow-float);z-index:20;display:flex;flex-direction:column}.drawer-head[data-v-2404dfbe]{height:48px;flex:none;display:flex;align-items:center;justify-content:space-between;padding:0 16px;border-bottom:1px solid var(--border)}.drawer-title[data-v-2404dfbe]{font-weight:600}.drawer-body[data-v-2404dfbe]{flex:1;overflow:auto;padding:16px}.drawer-enter-active[data-v-2404dfbe],.drawer-leave-active[data-v-2404dfbe]{transition:opacity .15s ease}.drawer-enter-from[data-v-2404dfbe],.drawer-leave-to[data-v-2404dfbe]{opacity:0}@media (max-width: 720px){.cal-cell[data-v-2404dfbe]{min-height:60px;padding:4px 5px}.cal-title[data-v-2404dfbe]{min-width:76px;font-size:13px}.cal-marks[data-v-2404dfbe]{gap:3px;margin-top:4px;height:12px}.drawer[data-v-2404dfbe]{width:100%}}.detail-toolbar[data-v-76243d98]{display:flex;align-items:center;gap:10px;margin-bottom:12px;flex-wrap:wrap}.date-title[data-v-76243d98]{font-size:14px;font-weight:600;min-width:170px;text-align:center}.date-title.is-today[data-v-76243d98]{color:var(--accent)}.w-date[data-v-76243d98]{width:150px}@media (max-width: 720px){.detail-toolbar[data-v-76243d98]{gap:8px}.date-title[data-v-76243d98]{min-width:0;flex:1;text-align:left}.w-date[data-v-76243d98]{flex:1;min-width:120px;width:auto}}.cards[data-v-73e5ba49]{display:grid;grid-template-columns:repeat(4,1fr);gap:12px}.stat-card[data-v-73e5ba49]{padding:14px 16px}.stat-num[data-v-73e5ba49]{font-size:20px;font-weight:600;margin-top:4px}.section[data-v-73e5ba49]{padding:14px 16px;margin-top:12px}.section-title[data-v-73e5ba49]{font-weight:600;margin-bottom:10px;font-size:13px}.heat[data-v-73e5ba49]{display:flex;gap:3px;overflow-x:auto;padding-bottom:4px}.heat-col[data-v-73e5ba49]{display:flex;flex-direction:column;gap:3px}.heat-cell[data-v-73e5ba49]{width:12px;height:12px;border-radius:2px;display:inline-block}.lv0[data-v-73e5ba49]{background:var(--bg-subtle);border:1px solid var(--border)}.lv1[data-v-73e5ba49]{background:#d8ecdf}.lv2[data-v-73e5ba49]{background:#a9d8bc}.lv3[data-v-73e5ba49]{background:#6fbf92}.lv4[data-v-73e5ba49]{background:var(--ok)}.heat-legend[data-v-73e5ba49]{display:flex;align-items:center;gap:3px;margin-top:8px;font-size:12px}.two-col[data-v-73e5ba49]{display:grid;grid-template-columns:1fr 1fr;gap:12px}.bar-row[data-v-73e5ba49]{display:flex;align-items:center;gap:10px;margin:6px 0}.bar-label[data-v-73e5ba49]{width:72px;flex:none;color:var(--text-2);font-size:12px;text-align:right}.bar-track[data-v-73e5ba49]{flex:1;height:8px;border-radius:4px;background:var(--bg-subtle);overflow:hidden}.bar-fill[data-v-73e5ba49]{display:block;height:100%;background:var(--accent);border-radius:4px}.bar-num[data-v-73e5ba49]{font-size:12px;width:92px;flex:none}.loc-label[data-v-73e5ba49]{width:110px;text-align:left}@media (max-width: 720px){.cards[data-v-73e5ba49]{grid-template-columns:repeat(2,1fr)}.two-col[data-v-73e5ba49]{grid-template-columns:1fr}}.report-toolbar[data-v-43f9c59b]{display:flex;align-items:center;gap:10px;margin-bottom:12px;flex-wrap:wrap}.ai-error[data-v-43f9c59b]{color:var(--danger);font-size:12px;margin:0 0 8px}.seg[data-v-43f9c59b]{display:inline-flex;border:1px solid var(--border-strong);border-radius:6px;overflow:hidden}.seg-btn[data-v-43f9c59b]{height:28px;padding:0 12px;border:none;background:var(--bg-page);color:var(--text-2);cursor:pointer;font-size:12px;border-right:1px solid var(--border)}.seg-btn[data-v-43f9c59b]:last-child{border-right:none}.seg-btn[data-v-43f9c59b]:hover{background:var(--bg-hover)}.seg-btn.active[data-v-43f9c59b]{background:var(--accent-bg);color:var(--accent)}.w-date[data-v-43f9c59b]{width:140px}.report-grid[data-v-43f9c59b]{display:grid;grid-template-columns:minmax(0,1fr) 320px;gap:12px;align-items:start}.section[data-v-43f9c59b]{padding:14px 16px}.section-title[data-v-43f9c59b]{font-weight:600;margin-bottom:8px;font-size:13px}.section+.section[data-v-43f9c59b]{margin-top:12px}.note-label[data-v-43f9c59b]{display:block;font-size:12px;margin:8px 0 4px}.note-saved[data-v-43f9c59b]{font-size:12px;margin-top:6px}.md-editor[data-v-43f9c59b]{min-height:420px;line-height:1.7}.sum-row[data-v-43f9c59b]{display:flex;justify-content:space-between;padding:3px 0;font-size:12px}.section-sub[data-v-43f9c59b]{font-weight:600;margin:10px 0 4px;font-size:12px}.sum-item[data-v-43f9c59b]{font-size:12px;padding:2px 0;word-break:break-all}.sum-empty[data-v-43f9c59b]{font-size:12px}@media (max-width: 960px){.report-grid[data-v-43f9c59b]{grid-template-columns:1fr}}.mask[data-v-edca3327]{position:fixed;top:0;right:0;bottom:0;left:0;background:#1d212966;display:flex;align-items:center;justify-content:center;z-index:90}.dialog[data-v-edca3327]{width:480px;max-width:calc(100vw - 32px);background:var(--bg-page);border-radius:var(--radius-lg);box-shadow:var(--shadow-float)}.dialog-head[data-v-edca3327]{display:flex;align-items:center;justify-content:space-between;padding:16px 20px 12px;border-bottom:1px solid var(--border)}.dialog-title[data-v-edca3327]{font-size:14px;font-weight:600;color:var(--text-1)}.dialog-body[data-v-edca3327]{padding:16px 20px}.dialog-btns[data-v-edca3327]{display:flex;justify-content:flex-end;gap:8px;padding:12px 20px 16px;border-top:1px solid var(--border)}.form-grid[data-v-edca3327]{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px 16px}.field.span2[data-v-edca3327]{grid-column:span 2}.field label[data-v-edca3327]{display:block;font-size:12px;color:var(--text-2);margin-bottom:4px}.seg[data-v-edca3327]{display:inline-flex;border:1px solid var(--border-strong);border-radius:var(--radius-sm);overflow:hidden}.seg-btn[data-v-edca3327]{height:30px;padding:0 14px;border:none;background:var(--bg-page);color:var(--text-2);cursor:pointer;font-size:13px}.seg-btn+.seg-btn[data-v-edca3327]{border-left:1px solid var(--border)}.seg-btn.active[data-v-edca3327]{background:var(--accent-bg);color:var(--accent)}.form-error[data-v-edca3327]{color:var(--danger);font-size:12px;margin-top:8px}.input.invalid[data-v-edca3327],.input.invalid[data-v-edca3327]:focus{border-color:var(--danger)}.modal-enter-active[data-v-edca3327],.modal-leave-active[data-v-edca3327]{transition:opacity .15s ease}.modal-enter-from[data-v-edca3327],.modal-leave-to[data-v-edca3327]{opacity:0}.ledger-toolbar[data-v-0f950d19]{display:flex;align-items:center;gap:8px;margin-bottom:12px;flex-wrap:wrap}.month-title[data-v-0f950d19]{font-size:14px;font-weight:600;min-width:88px;text-align:center}.w-filter[data-v-0f950d19]{width:110px;flex:none}.cards[data-v-0f950d19]{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:12px}.stat-card[data-v-0f950d19]{padding:14px 16px}.stat-num[data-v-0f950d19]{font-size:20px;font-weight:600;margin-top:4px}.amt-income[data-v-0f950d19]{color:var(--ok)}.amt-expense[data-v-0f950d19]{color:var(--text-1)}.amt-warn[data-v-0f950d19]{color:var(--warn)}.sec[data-v-0f950d19]{padding:14px 16px;margin-top:12px}.sec-title[data-v-0f950d19]{font-size:13px;font-weight:600;margin-bottom:10px}.sec-head[data-v-0f950d19]{display:flex;align-items:baseline;justify-content:space-between;gap:8px;margin-bottom:10px}.sec-head .sec-title[data-v-0f950d19]{margin-bottom:0}.form-hint[data-v-0f950d19]{font-size:12px}.form-grid[data-v-0f950d19]{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px 16px}.field.span2[data-v-0f950d19]{grid-column:span 2}.field label[data-v-0f950d19]{display:block;font-size:12px;color:var(--text-2);margin-bottom:4px}.form-error[data-v-0f950d19]{color:var(--danger);font-size:12px;margin-top:8px}.form-footer[data-v-0f950d19]{display:flex;justify-content:flex-end;gap:8px;margin-top:12px;padding-top:12px;border-top:1px solid var(--border)}.seg[data-v-0f950d19]{display:inline-flex;border:1px solid var(--border-strong);border-radius:var(--radius-sm);overflow:hidden}.seg-btn[data-v-0f950d19]{height:30px;padding:0 14px;border:none;background:var(--bg-page);color:var(--text-2);cursor:pointer;font-size:13px}.seg-btn+.seg-btn[data-v-0f950d19]{border-left:1px solid var(--border)}.seg-btn.active[data-v-0f950d19]{background:var(--accent-bg);color:var(--accent)}.toggle-btn[data-v-0f950d19]{height:32px;width:100%;border:1px solid var(--border-strong);background:var(--bg-page);border-radius:var(--radius-sm);cursor:pointer;font-size:13px;color:var(--text-2)}.toggle-btn[data-v-0f950d19]:hover{background:var(--bg-hover)}.toggle-btn.on[data-v-0f950d19]{color:var(--accent);border-color:var(--accent);background:var(--accent-bg)}.bar-row[data-v-0f950d19]{display:flex;align-items:center;gap:10px;margin:6px 0}.bar-label[data-v-0f950d19]{width:56px;flex:none;color:var(--text-2);font-size:12px;text-align:right}.bar-track[data-v-0f950d19]{flex:1;height:8px;border-radius:4px;background:var(--bg-subtle);overflow:hidden}.bar-fill[data-v-0f950d19]{display:block;height:100%;background:var(--accent);border-radius:4px}.bar-num[data-v-0f950d19]{font-size:12px;width:110px;flex:none}.table-card[data-v-0f950d19]{overflow-x:auto}.tx-table[data-v-0f950d19]{width:100%;border-collapse:collapse;font-size:13px}.tx-table th[data-v-0f950d19]{text-align:left;font-weight:500;color:var(--text-2);background:var(--bg-subtle);padding:10px 12px;border-bottom:1px solid var(--border);white-space:nowrap}.tx-table td[data-v-0f950d19]{padding:10px 12px;border-bottom:1px solid var(--border);vertical-align:top;word-break:break-all}.tx-table tbody tr[data-v-0f950d19]:hover{background:var(--bg-subtle)}.tx-table tbody tr:last-child td[data-v-0f950d19]{border-bottom:none}.td-note[data-v-0f950d19]{color:var(--text-2)}.tx-pending[data-v-0f950d19]{color:var(--warn);font-size:12px}.tx-done[data-v-0f950d19]{color:var(--ok);font-size:12px}.th-ops[data-v-0f950d19]{width:220px}.ops[data-v-0f950d19]{display:flex;gap:4px;flex-wrap:wrap}.empty[data-v-0f950d19]{text-align:center;padding:24px 0}.vault-note[data-v-0f950d19]{margin-top:10px;font-size:12px;text-align:right}@media (max-width: 560px){.form-grid[data-v-0f950d19]{grid-template-columns:1fr}.field.span2[data-v-0f950d19]{grid-column:auto}.ledger-toolbar .w-filter[data-v-0f950d19]{flex:1;min-width:0;width:auto}}.memo-page[data-v-74d60dba]{display:grid;grid-template-columns:280px minmax(0,1fr);gap:12px;align-items:stretch}.memo-list[data-v-74d60dba]{display:flex;flex-direction:column;max-height:calc(100vh - 140px)}.pane-head[data-v-74d60dba]{display:flex;align-items:center;justify-content:space-between;padding:12px 12px 8px;border-bottom:1px solid var(--border);flex:none}.pane-title[data-v-74d60dba]{font-size:13px;font-weight:600}.memo-scroll[data-v-74d60dba]{overflow:auto;padding:6px}.memo-item[data-v-74d60dba]{padding:8px 10px;border-radius:var(--radius-sm);cursor:pointer;margin-bottom:2px}.memo-item[data-v-74d60dba]:hover{background:var(--bg-hover)}.memo-item.active[data-v-74d60dba]{background:var(--accent-bg)}.memo-item.active .memo-item-title[data-v-74d60dba]{color:var(--accent)}.memo-item-title[data-v-74d60dba]{font-size:13px;font-weight:500;word-break:break-all}.memo-item-sub[data-v-74d60dba]{font-size:12px;margin-top:2px;word-break:break-all}.memo-item-time[data-v-74d60dba]{font-size:11px;margin-top:2px}.memo-editor[data-v-74d60dba]{padding:16px;min-height:420px;display:flex;flex-direction:column}.title-input[data-v-74d60dba]{font-size:14px;font-weight:500;margin-bottom:10px}.content-textarea[data-v-74d60dba]{flex:1;min-height:340px;line-height:1.8}.editor-foot[data-v-74d60dba]{display:flex;align-items:center;gap:8px;margin-top:10px;padding-top:10px;border-top:1px solid var(--border)}.foot-info[data-v-74d60dba]{font-size:12px}.editor-empty[data-v-74d60dba]{display:flex;align-items:center;justify-content:center;flex:1;padding:60px 0}@media (max-width: 800px){.memo-page[data-v-74d60dba]{grid-template-columns:1fr}.memo-list[data-v-74d60dba]{max-height:240px}.content-textarea[data-v-74d60dba]{min-height:240px}}.mask[data-v-f383b0a6]{position:fixed;top:0;right:0;bottom:0;left:0;background:#1d212966;display:flex;align-items:center;justify-content:center;z-index:90}.dialog[data-v-f383b0a6]{width:480px;max-width:calc(100vw - 32px);background:var(--bg-page);border-radius:var(--radius-lg);box-shadow:var(--shadow-float)}.dialog-head[data-v-f383b0a6]{display:flex;align-items:center;justify-content:space-between;padding:16px 20px 12px;border-bottom:1px solid var(--border)}.dialog-title[data-v-f383b0a6]{font-size:14px;font-weight:600;color:var(--text-1)}.dialog-body[data-v-f383b0a6]{padding:16px 20px}.dialog-btns[data-v-f383b0a6]{display:flex;justify-content:flex-end;gap:8px;padding:12px 20px 16px;border-top:1px solid var(--border)}.form-grid[data-v-f383b0a6]{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px 16px}.field.span2[data-v-f383b0a6]{grid-column:span 2}.field label[data-v-f383b0a6]{display:block;font-size:12px;color:var(--text-2);margin-bottom:4px}.pwd-row[data-v-f383b0a6]{display:flex;gap:8px}.pwd-row .input[data-v-f383b0a6]{flex:1}.form-error[data-v-f383b0a6]{color:var(--danger);font-size:12px;margin-top:8px}.modal-enter-active[data-v-f383b0a6],.modal-leave-active[data-v-f383b0a6]{transition:opacity .15s ease}.modal-enter-from[data-v-f383b0a6],.modal-leave-to[data-v-f383b0a6]{opacity:0}.lock-card[data-v-6820bc9c]{max-width:380px;margin:60px auto 0;padding:28px 24px;text-align:center;display:flex;flex-direction:column;gap:10px}.lock-badge[data-v-6820bc9c]{width:52px;height:52px;margin:0 auto;border-radius:50%;background:var(--bg-subtle);border:1px solid var(--border);display:flex;align-items:center;justify-content:center;color:var(--text-2)}.lock-title[data-v-6820bc9c]{font-size:14px;font-weight:600}.lock-tip[data-v-6820bc9c]{font-size:12px;line-height:1.7}.lock-btn[data-v-6820bc9c]{margin-top:4px}.form-error[data-v-6820bc9c]{color:var(--danger);font-size:12px}.empty[data-v-6820bc9c]{text-align:center;padding:24px 0}.vault-toolbar[data-v-6820bc9c]{display:flex;align-items:center;gap:8px;margin-bottom:12px;flex-wrap:wrap}.search-wrap[data-v-6820bc9c]{position:relative;width:280px;max-width:100%}.search-wrap .input[data-v-6820bc9c]{padding-left:30px}.search-icon[data-v-6820bc9c]{position:absolute;left:10px;top:50%;transform:translateY(-50%);color:var(--text-3)}.table-card[data-v-6820bc9c]{overflow-x:auto}.cred-table[data-v-6820bc9c]{width:100%;border-collapse:collapse;font-size:13px}.cred-table th[data-v-6820bc9c]{text-align:left;font-weight:500;color:var(--text-2);background:var(--bg-subtle);padding:10px 12px;border-bottom:1px solid var(--border);white-space:nowrap}.cred-table td[data-v-6820bc9c]{padding:10px 12px;border-bottom:1px solid var(--border);vertical-align:top;word-break:break-all}.cred-table tbody tr[data-v-6820bc9c]:hover{background:var(--bg-subtle)}.cred-table tbody tr:last-child td[data-v-6820bc9c]{border-bottom:none}.td-system[data-v-6820bc9c]{font-weight:500}.th-ops[data-v-6820bc9c]{width:150px}.pwd-cell[data-v-6820bc9c]{display:flex;align-items:center;gap:4px;flex-wrap:wrap}.pwd-text[data-v-6820bc9c]{letter-spacing:1px}.copyable[data-v-6820bc9c]{cursor:pointer}.copyable[data-v-6820bc9c]:hover{color:var(--accent)}.ops[data-v-6820bc9c]{display:flex;gap:4px;flex-wrap:wrap}.vault-note[data-v-6820bc9c]{margin-top:10px;font-size:12px;text-align:right}.mask[data-v-6820bc9c]{position:fixed;top:0;right:0;bottom:0;left:0;background:#1d212966;display:flex;align-items:center;justify-content:center;z-index:90}.dialog[data-v-6820bc9c]{width:440px;max-width:calc(100vw - 32px);background:var(--bg-page);border-radius:var(--radius-lg);box-shadow:var(--shadow-float)}.dialog-head[data-v-6820bc9c]{display:flex;align-items:center;justify-content:space-between;padding:16px 20px 12px;border-bottom:1px solid var(--border)}.dialog-title[data-v-6820bc9c]{font-size:14px;font-weight:600}.dialog-body[data-v-6820bc9c]{padding:16px 20px}.dialog-btns[data-v-6820bc9c]{display:flex;justify-content:flex-end;gap:8px;padding:12px 20px 16px;border-top:1px solid var(--border)}.vp-field[data-v-6820bc9c]{margin-bottom:10px}.vp-field label[data-v-6820bc9c]{display:block;font-size:12px;color:var(--text-2);margin-bottom:4px}.vp-tip[data-v-6820bc9c]{font-size:12px;margin-top:8px}.modal-enter-active[data-v-6820bc9c],.modal-leave-active[data-v-6820bc9c]{transition:opacity .15s ease}.modal-enter-from[data-v-6820bc9c],.modal-leave-to[data-v-6820bc9c]{opacity:0}.settings[data-v-1a8e0505]{display:flex;flex-direction:column;gap:12px;max-width:640px}.acc-line[data-v-1a8e0505]{font-size:12px;margin-bottom:10px;line-height:1.7}.section[data-v-1a8e0505]{padding:14px 16px}.section-title[data-v-1a8e0505]{font-weight:600;margin-bottom:10px;font-size:13px}.rule-grid[data-v-1a8e0505]{display:grid;grid-template-columns:1fr 1fr;gap:10px 16px}.rule-item label[data-v-1a8e0505]{display:block;font-size:12px;color:var(--text-2);margin-bottom:4px}.rule-save[data-v-1a8e0505]{display:flex;align-items:center;gap:10px;margin-top:12px}.proj-add[data-v-1a8e0505]{display:flex;gap:8px}.proj-tip[data-v-1a8e0505]{font-size:12px;margin-top:6px}.proj-row[data-v-1a8e0505]{display:flex;align-items:center;gap:8px;padding:6px 0;border-bottom:1px solid var(--border)}.proj-row[data-v-1a8e0505]:last-child{border-bottom:none}.proj-name[data-v-1a8e0505]{flex:1;word-break:break-all}.proj-name.archived[data-v-1a8e0505]{color:var(--text-3);text-decoration:line-through}.loc-note[data-v-1a8e0505]{font-size:12px}.ai-grid[data-v-1a8e0505]{display:flex;flex-direction:column;gap:10px}.backup-row[data-v-1a8e0505]{display:flex;gap:8px}.import-error[data-v-1a8e0505]{color:var(--danger);font-size:12px;margin-top:8px}.backup-note[data-v-1a8e0505]{font-size:12px;margin-top:10px}.login-page[data-v-d3d6c8cb]{min-height:100vh;background:var(--bg-subtle);display:flex;align-items:center;justify-content:center;padding:20px}.login-card[data-v-d3d6c8cb]{width:400px;max-width:100%;padding:28px 26px;display:flex;flex-direction:column;gap:12px;background:var(--bg-page)}.login-brand[data-v-d3d6c8cb]{text-align:center;margin-bottom:6px}.brand-icon[data-v-d3d6c8cb]{width:46px;height:46px;margin:0 auto 10px;border-radius:var(--radius-md);background:var(--accent-bg);color:var(--accent);display:flex;align-items:center;justify-content:center}.login-title[data-v-d3d6c8cb]{font-size:18px;font-weight:600;color:var(--text-1)}.login-sub[data-v-d3d6c8cb]{font-size:12px;margin-top:4px;line-height:1.7}.seg[data-v-d3d6c8cb]{display:inline-flex;border:1px solid var(--border-strong);border-radius:var(--radius-sm);overflow:hidden}.seg-btn[data-v-d3d6c8cb]{flex:1;height:30px;border:none;background:var(--bg-page);color:var(--text-2);cursor:pointer;font-size:13px}.seg-btn+.seg-btn[data-v-d3d6c8cb]{border-left:1px solid var(--border)}.seg-btn.active[data-v-d3d6c8cb]{background:var(--accent-bg);color:var(--accent)}.mig-row[data-v-d3d6c8cb]{display:flex;align-items:flex-start;gap:8px;font-size:12px;color:var(--text-2);cursor:pointer;line-height:1.6}.mig-row input[data-v-d3d6c8cb]{margin-top:3px}.form-error[data-v-d3d6c8cb]{color:var(--danger);font-size:12px}.login-btn[data-v-d3d6c8cb]{margin-top:2px}.login-note[data-v-d3d6c8cb]{font-size:12px;text-align:center;line-height:1.7}.app[data-v-d5bd1ff7]{display:flex;height:100vh;height:100dvh;overflow:hidden}.side[data-v-d5bd1ff7]{width:56px;flex:none;border-right:1px solid var(--border);display:flex;flex-direction:column;align-items:center;padding-top:10px;gap:4px;background:var(--bg-page)}.nav-btn[data-v-d5bd1ff7]{width:40px;height:40px;display:flex;align-items:center;justify-content:center;border-radius:var(--radius-md);color:var(--text-3);cursor:pointer;border:none;background:transparent;position:relative}.nav-btn[data-v-d5bd1ff7]:hover{background:var(--bg-hover);color:var(--text-1)}.nav-btn.active[data-v-d5bd1ff7]{background:var(--accent-bg);color:var(--accent)}.nav-btn[data-v-d5bd1ff7]:after{content:attr(data-tip);position:absolute;left:46px;top:50%;transform:translateY(-50%);background:var(--text-1);color:#fff;font-size:12px;line-height:1.4;padding:2px 8px;border-radius:4px;white-space:nowrap;opacity:0;pointer-events:none;transition:opacity .15s}.nav-btn[data-v-d5bd1ff7]:hover:after{opacity:1}.main[data-v-d5bd1ff7]{flex:1;display:flex;flex-direction:column;min-width:0}.topbar[data-v-d5bd1ff7]{height:56px;flex:none;border-bottom:1px solid var(--border);display:flex;align-items:center;gap:12px;padding:0 20px}.title[data-v-d5bd1ff7]{font-size:14px;font-weight:600}.topbar-actions[data-v-d5bd1ff7]{display:flex;align-items:center;gap:8px}.gsearch[data-v-d5bd1ff7]{position:relative;width:300px;max-width:38vw}.gs-icon[data-v-d5bd1ff7]{position:absolute;left:10px;top:50%;transform:translateY(-50%);color:var(--text-3)}.gs-input[data-v-d5bd1ff7]{height:30px;padding-left:30px}.gs-panel[data-v-d5bd1ff7]{position:absolute;top:36px;left:0;right:0;background:var(--bg-page);border:1px solid var(--border);border-radius:var(--radius-md);box-shadow:var(--shadow-float);z-index:50;max-height:420px;overflow:auto;padding:6px}.gs-group[data-v-d5bd1ff7]{font-size:12px;padding:6px 8px 2px}.gs-item[data-v-d5bd1ff7]{display:flex;align-items:center;gap:8px;padding:6px 8px;border-radius:var(--radius-sm);cursor:pointer}.gs-item[data-v-d5bd1ff7]:hover{background:var(--bg-hover)}.gs-text[data-v-d5bd1ff7],.gs-sub[data-v-d5bd1ff7]{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.gs-text[data-v-d5bd1ff7]{font-size:13px}.gs-sub[data-v-d5bd1ff7]{font-size:12px}.gs-date[data-v-d5bd1ff7]{font-size:12px;flex:none}.gs-empty[data-v-d5bd1ff7]{padding:10px;font-size:12px;text-align:center}.user-chip[data-v-d5bd1ff7]{font-size:12px;color:var(--text-2);padding:0 4px}.week-tip[data-v-d5bd1ff7]{display:inline-flex;align-items:center;gap:6px;border:1px solid var(--warn);color:var(--warn);background:var(--bg-page);border-radius:999px;height:26px;padding:0 10px;font-size:12px;cursor:pointer}.week-tip[data-v-d5bd1ff7]:hover{background:var(--bg-subtle)}.content[data-v-d5bd1ff7]{flex:1;overflow:auto}.content-inner[data-v-d5bd1ff7]{max-width:1200px;margin:0 auto;padding:20px}.toast-wrap[data-v-d5bd1ff7]{position:fixed;top:68px;right:20px;z-index:60;display:flex;flex-direction:column;gap:8px;align-items:flex-end;pointer-events:none}.toast[data-v-d5bd1ff7]{background:var(--bg-page);border:1px solid var(--border);box-shadow:var(--shadow-float);border-radius:var(--radius-sm);padding:8px 14px;font-size:13px;color:var(--text-1)}.toast-enter-from[data-v-d5bd1ff7],.toast-leave-to[data-v-d5bd1ff7]{opacity:0;transform:translateY(-4px)}.toast-enter-active[data-v-d5bd1ff7],.toast-leave-active[data-v-d5bd1ff7]{transition:all .15s ease}@media (max-width: 720px){.app[data-v-d5bd1ff7]{flex-direction:column;height:100dvh}.side[data-v-d5bd1ff7]{order:2;width:100%;height:calc(54px + env(safe-area-inset-bottom));padding-bottom:env(safe-area-inset-bottom);flex-direction:row;justify-content:space-around;border-right:none;border-top:1px solid var(--border);padding-top:0}.main[data-v-d5bd1ff7]{order:1;flex:1;min-height:0}.nav-btn[data-v-d5bd1ff7]{width:44px;height:42px}.nav-btn[data-v-d5bd1ff7]:after{display:none}.topbar[data-v-d5bd1ff7]{flex-wrap:wrap;height:auto;min-height:52px;padding:8px 12px;row-gap:8px}.topbar>.flex1[data-v-d5bd1ff7]{display:none}.gsearch[data-v-d5bd1ff7]{order:10;width:100%;max-width:100%}.gs-input[data-v-d5bd1ff7]{height:34px}.gs-panel[data-v-d5bd1ff7]{top:100%}.topbar-actions[data-v-d5bd1ff7]{margin-left:auto}.user-chip[data-v-d5bd1ff7]{max-width:72px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.content-inner[data-v-d5bd1ff7]{padding:12px}.toast-wrap[data-v-d5bd1ff7]{top:8px;right:12px;left:12px;align-items:flex-end}}:root{--bg-page: #FFFFFF;--bg-subtle: #F7F8FA;--bg-hover: #F2F3F5;--border: #EBEDF0;--border-strong: #DCDEE3;--text-1: #1D2129;--text-2: #4E5969;--text-3: #86909C;--accent: #3370FF;--accent-bg: #F0F5FF;--ok: #23A757;--warn: #E8842C;--danger: #E5484D;--dot-empty: #C9CDD4;--radius-sm: 6px;--radius-md: 8px;--radius-lg: 12px;--shadow-float: 0 4px 16px rgba(29, 33, 41, .08)}*{box-sizing:border-box}html,body{margin:0;padding:0}body{background:var(--bg-page);color:var(--text-1);font-family:-apple-system,PingFang SC,Microsoft YaHei,system-ui,sans-serif;font-size:13px;line-height:1.6;-webkit-font-smoothing:antialiased}button,input,select,textarea{font:inherit;color:inherit}.num{font-variant-numeric:tabular-nums}.flex1{flex:1}.muted{color:var(--text-3)}.muted2{color:var(--text-2)}.btn{display:inline-flex;align-items:center;justify-content:center;gap:6px;padding:0 12px;height:32px;border-radius:var(--radius-sm);border:1px solid var(--border-strong);background:var(--bg-page);color:var(--text-1);cursor:pointer;white-space:nowrap}.btn:hover{background:var(--bg-hover)}.btn:disabled{opacity:.45;cursor:not-allowed}.btn-primary{background:var(--accent);border-color:var(--accent);color:#fff}.btn-primary:hover{background:#2b5fd9}.btn-danger{color:var(--danger);border-color:var(--danger)}.btn-sm{height:26px;padding:0 10px;font-size:12px}.btn-xs{height:22px;padding:0 8px;font-size:12px}.input,.select,.textarea{height:32px;padding:0 10px;border:1px solid var(--border-strong);border-radius:var(--radius-sm);background:var(--bg-page);outline:none;width:100%}.textarea{height:auto;min-height:56px;padding:8px 10px;resize:vertical}.input:focus,.select:focus,.textarea:focus{border-color:var(--accent)}.input::placeholder,.textarea::placeholder{color:var(--text-3)}.card{border:1px solid var(--border);border-radius:var(--radius-md);background:var(--bg-page)}.icon-btn{display:inline-flex;align-items:center;justify-content:center;width:26px;height:26px;flex:none;border:none;background:transparent;border-radius:var(--radius-sm);color:var(--text-3);cursor:pointer}.icon-btn:hover{background:var(--bg-hover);color:var(--text-1)}.icon-btn.active{color:var(--accent)}.icon-btn.active-warn{color:var(--warn)}.tag{display:inline-block;padding:0 8px;height:22px;line-height:20px;border-radius:4px;font-size:12px;background:var(--bg-subtle);color:var(--text-2);border:1px solid var(--border);white-space:nowrap}.dot{width:6px;height:6px;border-radius:50%;display:inline-block;flex:none}.dot.normal{background:var(--ok)}.dot.late,.dot.early,.dot.incomplete{background:var(--warn)}.dot.absent{background:var(--danger)}.dot.none,.dot.leave{background:var(--dot-empty)}@media (max-width: 720px){input,select,textarea{font-size:16px!important}input[type=checkbox]{font-size:initial}}.dot.rest{background:var(--border)}.icon{display:inline-flex;align-items:center;justify-content:center;flex:none}.icon svg{width:100%;height:100%;display:block} +.mask[data-v-f27041d4]{position:fixed;top:0;right:0;bottom:0;left:0;background:#1d212966;display:flex;align-items:center;justify-content:center;z-index:100}.dialog[data-v-f27041d4]{width:380px;max-width:calc(100vw - 32px);background:var(--bg-page);border-radius:var(--radius-lg);box-shadow:var(--shadow-float);padding:20px}.dialog-title[data-v-f27041d4]{font-size:14px;font-weight:600;color:var(--text-1)}.dialog-msg[data-v-f27041d4]{margin-top:8px;color:var(--text-2);font-size:13px;line-height:1.7;word-break:break-all}.dialog-btns[data-v-f27041d4]{margin-top:20px;display:flex;justify-content:flex-end;gap:8px}.btn-danger-solid[data-v-f27041d4]{background:var(--danger);border-color:var(--danger);color:#fff}.btn-danger-solid[data-v-f27041d4]:hover{background:#d13a3f}.modal-enter-active[data-v-f27041d4],.modal-leave-active[data-v-f27041d4]{transition:opacity .15s ease}.modal-enter-from[data-v-f27041d4],.modal-leave-to[data-v-f27041d4]{opacity:0}.mask[data-v-63bc0b48]{position:fixed;top:0;right:0;bottom:0;left:0;background:#1d212966;display:flex;align-items:center;justify-content:center;z-index:90}.dialog[data-v-63bc0b48]{width:560px;max-width:calc(100vw - 32px);max-height:85vh;background:var(--bg-page);border-radius:var(--radius-lg);box-shadow:var(--shadow-float);display:flex;flex-direction:column}.dialog-head[data-v-63bc0b48]{display:flex;align-items:flex-start;justify-content:space-between;padding:16px 20px 12px;border-bottom:1px solid var(--border);flex:none}.dialog-title[data-v-63bc0b48]{font-size:14px;font-weight:600;color:var(--text-1)}.dialog-sub[data-v-63bc0b48]{font-size:12px;margin-top:2px}.dialog-body[data-v-63bc0b48]{padding:16px 20px;overflow:auto}.dialog-btns[data-v-63bc0b48]{display:flex;justify-content:flex-end;gap:8px;padding:12px 20px 16px;border-top:1px solid var(--border);flex:none}.form-grid[data-v-63bc0b48]{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px 16px}.field.span2[data-v-63bc0b48]{grid-column:span 2}.field label[data-v-63bc0b48]{display:block;font-size:12px;color:var(--text-2);margin-bottom:4px}.form-error[data-v-63bc0b48]{color:var(--danger);font-size:12px;margin-top:4px}.input.invalid[data-v-63bc0b48],.input.invalid[data-v-63bc0b48]:focus{border-color:var(--danger)}.toggle-btn[data-v-63bc0b48]{height:32px;width:100%;border:1px solid var(--border-strong);background:var(--bg-page);border-radius:var(--radius-sm);cursor:pointer;font-size:13px;color:var(--text-2)}.toggle-btn[data-v-63bc0b48]:hover{background:var(--bg-hover)}.toggle-btn.on[data-v-63bc0b48]{color:var(--accent);border-color:var(--accent);background:var(--accent-bg)}.toggle-btn.onwarn[data-v-63bc0b48]{color:var(--warn);border-color:var(--warn)}.modal-enter-active[data-v-63bc0b48],.modal-leave-active[data-v-63bc0b48]{transition:opacity .15s ease}.modal-enter-from[data-v-63bc0b48],.modal-leave-to[data-v-63bc0b48]{opacity:0}.dp-head[data-v-2e90c9d8]{margin-bottom:12px}.dp-date[data-v-2e90c9d8]{font-size:14px;font-weight:600}.sec[data-v-2e90c9d8]{padding:14px 16px;margin-bottom:12px}.sec-title[data-v-2e90c9d8]{font-size:13px;font-weight:600;margin-bottom:10px;color:var(--text-1)}.sec-head[data-v-2e90c9d8]{display:flex;align-items:baseline;justify-content:space-between;gap:8px;margin-bottom:10px}.sec-head .sec-title[data-v-2e90c9d8]{margin-bottom:0}.form-hint[data-v-2e90c9d8]{font-size:12px}.att-grid[data-v-2e90c9d8]{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px 16px}.att-cell label[data-v-2e90c9d8],.field label[data-v-2e90c9d8]{display:block;font-size:12px;color:var(--text-2);margin-bottom:4px}.att-val[data-v-2e90c9d8]{display:flex;align-items:center;gap:6px;min-height:32px;font-size:13px}.status-val[data-v-2e90c9d8]{min-height:32px}.val-empty[data-v-2e90c9d8]{color:var(--text-3)}.edit-row[data-v-2e90c9d8]{display:flex;gap:6px;align-items:center;flex-wrap:wrap}.time-input[data-v-2e90c9d8]{width:104px}.att-note[data-v-2e90c9d8]{margin-top:10px;font-size:12px}.att-actions[data-v-2e90c9d8]{display:flex;gap:8px;margin-top:12px}.form-grid[data-v-2e90c9d8]{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px 16px}.field.span2[data-v-2e90c9d8]{grid-column:span 2}.form-footer[data-v-2e90c9d8]{display:flex;justify-content:flex-end;gap:8px;margin-top:12px;padding-top:12px;border-top:1px solid var(--border)}.form-error[data-v-2e90c9d8]{color:var(--danger);font-size:12px;margin-top:4px}.input.invalid[data-v-2e90c9d8]{border-color:var(--danger)}.input.invalid[data-v-2e90c9d8]:focus{border-color:var(--danger)}.list-sec[data-v-2e90c9d8]{margin-bottom:4px}.item[data-v-2e90c9d8]{border:1px solid var(--border);border-radius:var(--radius-sm);padding:8px 10px;margin-bottom:6px;background:var(--bg-page)}.item-main[data-v-2e90c9d8]{display:flex;align-items:center;gap:8px;min-height:26px;flex-wrap:wrap}.item-content[data-v-2e90c9d8]{cursor:text;word-break:break-all}.item-meta[data-v-2e90c9d8]{font-size:12px}.item-sub[data-v-2e90c9d8]{margin-top:6px;padding-top:6px;border-top:1px dashed var(--border);font-size:12px;display:flex;flex-direction:column;gap:2px}.empty[data-v-2e90c9d8]{text-align:center;padding:24px 0}.dp-foot[data-v-2e90c9d8]{margin-top:10px;font-size:12px;text-align:right}@media (max-width: 560px){.att-grid[data-v-2e90c9d8],.form-grid[data-v-2e90c9d8]{grid-template-columns:1fr}.field.span2[data-v-2e90c9d8]{grid-column:auto}}.cal-toolbar[data-v-2404dfbe]{display:flex;align-items:center;gap:10px;margin-bottom:12px}.cal-title[data-v-2404dfbe]{font-size:14px;font-weight:600;min-width:96px;text-align:center}.cal-head[data-v-2404dfbe]{display:grid;grid-template-columns:repeat(7,1fr);border-top:1px solid var(--border);border-left:1px solid var(--border)}.cal-week[data-v-2404dfbe]{text-align:center;padding:6px 0;font-size:12px;border-right:1px solid var(--border);border-bottom:1px solid var(--border)}.cal-grid[data-v-2404dfbe]{display:grid;grid-template-columns:repeat(7,1fr);border-top:1px solid var(--border);border-left:1px solid var(--border)}.cal-cell[data-v-2404dfbe]{min-height:92px;padding:6px 8px;text-align:left;background:var(--bg-page);border:none;border-right:1px solid var(--border);border-bottom:1px solid var(--border);cursor:pointer;display:block;font-size:13px}.cal-cell[data-v-2404dfbe]:hover{background:var(--bg-subtle)}.cal-cell.blank[data-v-2404dfbe]{cursor:default}.cal-cell.blank[data-v-2404dfbe]:hover{background:var(--bg-page)}.cal-cell.selected[data-v-2404dfbe]{background:var(--accent-bg)}.daynum.today[data-v-2404dfbe]{color:var(--accent);font-weight:600}.cal-cell.weekend .daynum[data-v-2404dfbe]{color:var(--text-3)}.cal-marks[data-v-2404dfbe]{display:flex;align-items:center;gap:4px;margin-top:8px;height:14px}.mark-log[data-v-2404dfbe]{color:var(--text-3)}.mark-star[data-v-2404dfbe]{color:var(--accent)}.drawer[data-v-2404dfbe]{position:fixed;top:0;right:0;bottom:0;width:min(420px,100%);background:var(--bg-page);border-left:1px solid var(--border);box-shadow:var(--shadow-float);z-index:20;display:flex;flex-direction:column}.drawer-head[data-v-2404dfbe]{height:48px;flex:none;display:flex;align-items:center;justify-content:space-between;padding:0 16px;border-bottom:1px solid var(--border)}.drawer-title[data-v-2404dfbe]{font-weight:600}.drawer-body[data-v-2404dfbe]{flex:1;overflow:auto;padding:16px}.drawer-enter-active[data-v-2404dfbe],.drawer-leave-active[data-v-2404dfbe]{transition:opacity .15s ease}.drawer-enter-from[data-v-2404dfbe],.drawer-leave-to[data-v-2404dfbe]{opacity:0}@media (max-width: 720px){.cal-cell[data-v-2404dfbe]{min-height:60px;padding:4px 5px}.cal-title[data-v-2404dfbe]{min-width:76px;font-size:13px}.cal-marks[data-v-2404dfbe]{gap:3px;margin-top:4px;height:12px}.drawer[data-v-2404dfbe]{width:100%}}.detail-toolbar[data-v-76243d98]{display:flex;align-items:center;gap:10px;margin-bottom:12px;flex-wrap:wrap}.date-title[data-v-76243d98]{font-size:14px;font-weight:600;min-width:170px;text-align:center}.date-title.is-today[data-v-76243d98]{color:var(--accent)}.w-date[data-v-76243d98]{width:150px}@media (max-width: 720px){.detail-toolbar[data-v-76243d98]{gap:8px}.date-title[data-v-76243d98]{min-width:0;flex:1;text-align:left}.w-date[data-v-76243d98]{flex:1;min-width:120px;width:auto}}.cards[data-v-73e5ba49]{display:grid;grid-template-columns:repeat(4,1fr);gap:12px}.stat-card[data-v-73e5ba49]{padding:14px 16px}.stat-num[data-v-73e5ba49]{font-size:20px;font-weight:600;margin-top:4px}.section[data-v-73e5ba49]{padding:14px 16px;margin-top:12px}.section-title[data-v-73e5ba49]{font-weight:600;margin-bottom:10px;font-size:13px}.heat[data-v-73e5ba49]{display:flex;gap:3px;overflow-x:auto;padding-bottom:4px}.heat-col[data-v-73e5ba49]{display:flex;flex-direction:column;gap:3px}.heat-cell[data-v-73e5ba49]{width:12px;height:12px;border-radius:2px;display:inline-block}.lv0[data-v-73e5ba49]{background:var(--bg-subtle);border:1px solid var(--border)}.lv1[data-v-73e5ba49]{background:#d8ecdf}.lv2[data-v-73e5ba49]{background:#a9d8bc}.lv3[data-v-73e5ba49]{background:#6fbf92}.lv4[data-v-73e5ba49]{background:var(--ok)}.heat-legend[data-v-73e5ba49]{display:flex;align-items:center;gap:3px;margin-top:8px;font-size:12px}.two-col[data-v-73e5ba49]{display:grid;grid-template-columns:1fr 1fr;gap:12px}.bar-row[data-v-73e5ba49]{display:flex;align-items:center;gap:10px;margin:6px 0}.bar-label[data-v-73e5ba49]{width:72px;flex:none;color:var(--text-2);font-size:12px;text-align:right}.bar-track[data-v-73e5ba49]{flex:1;height:8px;border-radius:4px;background:var(--bg-subtle);overflow:hidden}.bar-fill[data-v-73e5ba49]{display:block;height:100%;background:var(--accent);border-radius:4px}.bar-num[data-v-73e5ba49]{font-size:12px;width:92px;flex:none}.loc-label[data-v-73e5ba49]{width:110px;text-align:left}@media (max-width: 720px){.cards[data-v-73e5ba49]{grid-template-columns:repeat(2,1fr)}.two-col[data-v-73e5ba49]{grid-template-columns:1fr}}.report-toolbar[data-v-43f9c59b]{display:flex;align-items:center;gap:10px;margin-bottom:12px;flex-wrap:wrap}.ai-error[data-v-43f9c59b]{color:var(--danger);font-size:12px;margin:0 0 8px}.seg[data-v-43f9c59b]{display:inline-flex;border:1px solid var(--border-strong);border-radius:6px;overflow:hidden}.seg-btn[data-v-43f9c59b]{height:28px;padding:0 12px;border:none;background:var(--bg-page);color:var(--text-2);cursor:pointer;font-size:12px;border-right:1px solid var(--border)}.seg-btn[data-v-43f9c59b]:last-child{border-right:none}.seg-btn[data-v-43f9c59b]:hover{background:var(--bg-hover)}.seg-btn.active[data-v-43f9c59b]{background:var(--accent-bg);color:var(--accent)}.w-date[data-v-43f9c59b]{width:140px}.report-grid[data-v-43f9c59b]{display:grid;grid-template-columns:minmax(0,1fr) 320px;gap:12px;align-items:start}.section[data-v-43f9c59b]{padding:14px 16px}.section-title[data-v-43f9c59b]{font-weight:600;margin-bottom:8px;font-size:13px}.section+.section[data-v-43f9c59b]{margin-top:12px}.note-label[data-v-43f9c59b]{display:block;font-size:12px;margin:8px 0 4px}.note-saved[data-v-43f9c59b]{font-size:12px;margin-top:6px}.md-editor[data-v-43f9c59b]{min-height:420px;line-height:1.7}.sum-row[data-v-43f9c59b]{display:flex;justify-content:space-between;padding:3px 0;font-size:12px}.section-sub[data-v-43f9c59b]{font-weight:600;margin:10px 0 4px;font-size:12px}.sum-item[data-v-43f9c59b]{font-size:12px;padding:2px 0;word-break:break-all}.sum-empty[data-v-43f9c59b]{font-size:12px}@media (max-width: 960px){.report-grid[data-v-43f9c59b]{grid-template-columns:1fr}}.mask[data-v-edca3327]{position:fixed;top:0;right:0;bottom:0;left:0;background:#1d212966;display:flex;align-items:center;justify-content:center;z-index:90}.dialog[data-v-edca3327]{width:480px;max-width:calc(100vw - 32px);background:var(--bg-page);border-radius:var(--radius-lg);box-shadow:var(--shadow-float)}.dialog-head[data-v-edca3327]{display:flex;align-items:center;justify-content:space-between;padding:16px 20px 12px;border-bottom:1px solid var(--border)}.dialog-title[data-v-edca3327]{font-size:14px;font-weight:600;color:var(--text-1)}.dialog-body[data-v-edca3327]{padding:16px 20px}.dialog-btns[data-v-edca3327]{display:flex;justify-content:flex-end;gap:8px;padding:12px 20px 16px;border-top:1px solid var(--border)}.form-grid[data-v-edca3327]{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px 16px}.field.span2[data-v-edca3327]{grid-column:span 2}.field label[data-v-edca3327]{display:block;font-size:12px;color:var(--text-2);margin-bottom:4px}.seg[data-v-edca3327]{display:inline-flex;border:1px solid var(--border-strong);border-radius:var(--radius-sm);overflow:hidden}.seg-btn[data-v-edca3327]{height:30px;padding:0 14px;border:none;background:var(--bg-page);color:var(--text-2);cursor:pointer;font-size:13px}.seg-btn+.seg-btn[data-v-edca3327]{border-left:1px solid var(--border)}.seg-btn.active[data-v-edca3327]{background:var(--accent-bg);color:var(--accent)}.form-error[data-v-edca3327]{color:var(--danger);font-size:12px;margin-top:8px}.input.invalid[data-v-edca3327],.input.invalid[data-v-edca3327]:focus{border-color:var(--danger)}.modal-enter-active[data-v-edca3327],.modal-leave-active[data-v-edca3327]{transition:opacity .15s ease}.modal-enter-from[data-v-edca3327],.modal-leave-to[data-v-edca3327]{opacity:0}.ledger-toolbar[data-v-0f950d19]{display:flex;align-items:center;gap:8px;margin-bottom:12px;flex-wrap:wrap}.month-title[data-v-0f950d19]{font-size:14px;font-weight:600;min-width:88px;text-align:center}.w-filter[data-v-0f950d19]{width:110px;flex:none}.cards[data-v-0f950d19]{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:12px}.stat-card[data-v-0f950d19]{padding:14px 16px}.stat-num[data-v-0f950d19]{font-size:20px;font-weight:600;margin-top:4px}.amt-income[data-v-0f950d19]{color:var(--ok)}.amt-expense[data-v-0f950d19]{color:var(--text-1)}.amt-warn[data-v-0f950d19]{color:var(--warn)}.sec[data-v-0f950d19]{padding:14px 16px;margin-top:12px}.sec-title[data-v-0f950d19]{font-size:13px;font-weight:600;margin-bottom:10px}.sec-head[data-v-0f950d19]{display:flex;align-items:baseline;justify-content:space-between;gap:8px;margin-bottom:10px}.sec-head .sec-title[data-v-0f950d19]{margin-bottom:0}.form-hint[data-v-0f950d19]{font-size:12px}.form-grid[data-v-0f950d19]{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px 16px}.field.span2[data-v-0f950d19]{grid-column:span 2}.field label[data-v-0f950d19]{display:block;font-size:12px;color:var(--text-2);margin-bottom:4px}.form-error[data-v-0f950d19]{color:var(--danger);font-size:12px;margin-top:8px}.form-footer[data-v-0f950d19]{display:flex;justify-content:flex-end;gap:8px;margin-top:12px;padding-top:12px;border-top:1px solid var(--border)}.seg[data-v-0f950d19]{display:inline-flex;border:1px solid var(--border-strong);border-radius:var(--radius-sm);overflow:hidden}.seg-btn[data-v-0f950d19]{height:30px;padding:0 14px;border:none;background:var(--bg-page);color:var(--text-2);cursor:pointer;font-size:13px}.seg-btn+.seg-btn[data-v-0f950d19]{border-left:1px solid var(--border)}.seg-btn.active[data-v-0f950d19]{background:var(--accent-bg);color:var(--accent)}.toggle-btn[data-v-0f950d19]{height:32px;width:100%;border:1px solid var(--border-strong);background:var(--bg-page);border-radius:var(--radius-sm);cursor:pointer;font-size:13px;color:var(--text-2)}.toggle-btn[data-v-0f950d19]:hover{background:var(--bg-hover)}.toggle-btn.on[data-v-0f950d19]{color:var(--accent);border-color:var(--accent);background:var(--accent-bg)}.bar-row[data-v-0f950d19]{display:flex;align-items:center;gap:10px;margin:6px 0}.bar-label[data-v-0f950d19]{width:56px;flex:none;color:var(--text-2);font-size:12px;text-align:right}.bar-track[data-v-0f950d19]{flex:1;height:8px;border-radius:4px;background:var(--bg-subtle);overflow:hidden}.bar-fill[data-v-0f950d19]{display:block;height:100%;background:var(--accent);border-radius:4px}.bar-num[data-v-0f950d19]{font-size:12px;width:110px;flex:none}.table-card[data-v-0f950d19]{overflow-x:auto}.tx-table[data-v-0f950d19]{width:100%;border-collapse:collapse;font-size:13px}.tx-table th[data-v-0f950d19]{text-align:left;font-weight:500;color:var(--text-2);background:var(--bg-subtle);padding:10px 12px;border-bottom:1px solid var(--border);white-space:nowrap}.tx-table td[data-v-0f950d19]{padding:10px 12px;border-bottom:1px solid var(--border);vertical-align:top;word-break:break-all}.tx-table tbody tr[data-v-0f950d19]:hover{background:var(--bg-subtle)}.tx-table tbody tr:last-child td[data-v-0f950d19]{border-bottom:none}.td-note[data-v-0f950d19]{color:var(--text-2)}.tx-pending[data-v-0f950d19]{color:var(--warn);font-size:12px}.tx-done[data-v-0f950d19]{color:var(--ok);font-size:12px}.th-ops[data-v-0f950d19]{width:220px}.ops[data-v-0f950d19]{display:flex;gap:4px;flex-wrap:wrap}.empty[data-v-0f950d19]{text-align:center;padding:24px 0}.vault-note[data-v-0f950d19]{margin-top:10px;font-size:12px;text-align:right}@media (max-width: 560px){.form-grid[data-v-0f950d19]{grid-template-columns:1fr}.field.span2[data-v-0f950d19]{grid-column:auto}.ledger-toolbar .w-filter[data-v-0f950d19]{flex:1;min-width:0;width:auto}}.memo-page[data-v-74d60dba]{display:grid;grid-template-columns:280px minmax(0,1fr);gap:12px;align-items:stretch}.memo-list[data-v-74d60dba]{display:flex;flex-direction:column;max-height:calc(100vh - 140px)}.pane-head[data-v-74d60dba]{display:flex;align-items:center;justify-content:space-between;padding:12px 12px 8px;border-bottom:1px solid var(--border);flex:none}.pane-title[data-v-74d60dba]{font-size:13px;font-weight:600}.memo-scroll[data-v-74d60dba]{overflow:auto;padding:6px}.memo-item[data-v-74d60dba]{padding:8px 10px;border-radius:var(--radius-sm);cursor:pointer;margin-bottom:2px}.memo-item[data-v-74d60dba]:hover{background:var(--bg-hover)}.memo-item.active[data-v-74d60dba]{background:var(--accent-bg)}.memo-item.active .memo-item-title[data-v-74d60dba]{color:var(--accent)}.memo-item-title[data-v-74d60dba]{font-size:13px;font-weight:500;word-break:break-all}.memo-item-sub[data-v-74d60dba]{font-size:12px;margin-top:2px;word-break:break-all}.memo-item-time[data-v-74d60dba]{font-size:11px;margin-top:2px}.memo-editor[data-v-74d60dba]{padding:16px;min-height:420px;display:flex;flex-direction:column}.title-input[data-v-74d60dba]{font-size:14px;font-weight:500;margin-bottom:10px}.content-textarea[data-v-74d60dba]{flex:1;min-height:340px;line-height:1.8}.editor-foot[data-v-74d60dba]{display:flex;align-items:center;gap:8px;margin-top:10px;padding-top:10px;border-top:1px solid var(--border)}.foot-info[data-v-74d60dba]{font-size:12px}.editor-empty[data-v-74d60dba]{display:flex;align-items:center;justify-content:center;flex:1;padding:60px 0}@media (max-width: 800px){.memo-page[data-v-74d60dba]{grid-template-columns:1fr}.memo-list[data-v-74d60dba]{max-height:240px}.content-textarea[data-v-74d60dba]{min-height:240px}}.mask[data-v-f383b0a6]{position:fixed;top:0;right:0;bottom:0;left:0;background:#1d212966;display:flex;align-items:center;justify-content:center;z-index:90}.dialog[data-v-f383b0a6]{width:480px;max-width:calc(100vw - 32px);background:var(--bg-page);border-radius:var(--radius-lg);box-shadow:var(--shadow-float)}.dialog-head[data-v-f383b0a6]{display:flex;align-items:center;justify-content:space-between;padding:16px 20px 12px;border-bottom:1px solid var(--border)}.dialog-title[data-v-f383b0a6]{font-size:14px;font-weight:600;color:var(--text-1)}.dialog-body[data-v-f383b0a6]{padding:16px 20px}.dialog-btns[data-v-f383b0a6]{display:flex;justify-content:flex-end;gap:8px;padding:12px 20px 16px;border-top:1px solid var(--border)}.form-grid[data-v-f383b0a6]{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px 16px}.field.span2[data-v-f383b0a6]{grid-column:span 2}.field label[data-v-f383b0a6]{display:block;font-size:12px;color:var(--text-2);margin-bottom:4px}.pwd-row[data-v-f383b0a6]{display:flex;gap:8px}.pwd-row .input[data-v-f383b0a6]{flex:1}.form-error[data-v-f383b0a6]{color:var(--danger);font-size:12px;margin-top:8px}.modal-enter-active[data-v-f383b0a6],.modal-leave-active[data-v-f383b0a6]{transition:opacity .15s ease}.modal-enter-from[data-v-f383b0a6],.modal-leave-to[data-v-f383b0a6]{opacity:0}.lock-card[data-v-6820bc9c]{max-width:380px;margin:60px auto 0;padding:28px 24px;text-align:center;display:flex;flex-direction:column;gap:10px}.lock-badge[data-v-6820bc9c]{width:52px;height:52px;margin:0 auto;border-radius:50%;background:var(--bg-subtle);border:1px solid var(--border);display:flex;align-items:center;justify-content:center;color:var(--text-2)}.lock-title[data-v-6820bc9c]{font-size:14px;font-weight:600}.lock-tip[data-v-6820bc9c]{font-size:12px;line-height:1.7}.lock-btn[data-v-6820bc9c]{margin-top:4px}.form-error[data-v-6820bc9c]{color:var(--danger);font-size:12px}.empty[data-v-6820bc9c]{text-align:center;padding:24px 0}.vault-toolbar[data-v-6820bc9c]{display:flex;align-items:center;gap:8px;margin-bottom:12px;flex-wrap:wrap}.search-wrap[data-v-6820bc9c]{position:relative;width:280px;max-width:100%}.search-wrap .input[data-v-6820bc9c]{padding-left:30px}.search-icon[data-v-6820bc9c]{position:absolute;left:10px;top:50%;transform:translateY(-50%);color:var(--text-3)}.table-card[data-v-6820bc9c]{overflow-x:auto}.cred-table[data-v-6820bc9c]{width:100%;border-collapse:collapse;font-size:13px}.cred-table th[data-v-6820bc9c]{text-align:left;font-weight:500;color:var(--text-2);background:var(--bg-subtle);padding:10px 12px;border-bottom:1px solid var(--border);white-space:nowrap}.cred-table td[data-v-6820bc9c]{padding:10px 12px;border-bottom:1px solid var(--border);vertical-align:top;word-break:break-all}.cred-table tbody tr[data-v-6820bc9c]:hover{background:var(--bg-subtle)}.cred-table tbody tr:last-child td[data-v-6820bc9c]{border-bottom:none}.td-system[data-v-6820bc9c]{font-weight:500}.th-ops[data-v-6820bc9c]{width:150px}.pwd-cell[data-v-6820bc9c]{display:flex;align-items:center;gap:4px;flex-wrap:wrap}.pwd-text[data-v-6820bc9c]{letter-spacing:1px}.copyable[data-v-6820bc9c]{cursor:pointer}.copyable[data-v-6820bc9c]:hover{color:var(--accent)}.ops[data-v-6820bc9c]{display:flex;gap:4px;flex-wrap:wrap}.vault-note[data-v-6820bc9c]{margin-top:10px;font-size:12px;text-align:right}.mask[data-v-6820bc9c]{position:fixed;top:0;right:0;bottom:0;left:0;background:#1d212966;display:flex;align-items:center;justify-content:center;z-index:90}.dialog[data-v-6820bc9c]{width:440px;max-width:calc(100vw - 32px);background:var(--bg-page);border-radius:var(--radius-lg);box-shadow:var(--shadow-float)}.dialog-head[data-v-6820bc9c]{display:flex;align-items:center;justify-content:space-between;padding:16px 20px 12px;border-bottom:1px solid var(--border)}.dialog-title[data-v-6820bc9c]{font-size:14px;font-weight:600}.dialog-body[data-v-6820bc9c]{padding:16px 20px}.dialog-btns[data-v-6820bc9c]{display:flex;justify-content:flex-end;gap:8px;padding:12px 20px 16px;border-top:1px solid var(--border)}.vp-field[data-v-6820bc9c]{margin-bottom:10px}.vp-field label[data-v-6820bc9c]{display:block;font-size:12px;color:var(--text-2);margin-bottom:4px}.vp-tip[data-v-6820bc9c]{font-size:12px;margin-top:8px}.modal-enter-active[data-v-6820bc9c],.modal-leave-active[data-v-6820bc9c]{transition:opacity .15s ease}.modal-enter-from[data-v-6820bc9c],.modal-leave-to[data-v-6820bc9c]{opacity:0}.settings[data-v-cea34561]{display:flex;flex-direction:column;gap:12px;max-width:640px}.acc-line[data-v-cea34561]{font-size:12px;margin-bottom:10px;line-height:1.7}.section[data-v-cea34561]{padding:14px 16px}.section-title[data-v-cea34561]{font-weight:600;margin-bottom:10px;font-size:13px}.rule-grid[data-v-cea34561]{display:grid;grid-template-columns:1fr 1fr;gap:10px 16px}.rule-item label[data-v-cea34561]{display:block;font-size:12px;color:var(--text-2);margin-bottom:4px}.rule-save[data-v-cea34561]{display:flex;align-items:center;gap:10px;margin-top:12px}.proj-add[data-v-cea34561]{display:flex;gap:8px}.proj-tip[data-v-cea34561]{font-size:12px;margin-top:6px}.proj-row[data-v-cea34561]{display:flex;align-items:center;gap:8px;padding:6px 0;border-bottom:1px solid var(--border)}.proj-row[data-v-cea34561]:last-child{border-bottom:none}.proj-name[data-v-cea34561]{flex:1;word-break:break-all}.proj-name.archived[data-v-cea34561]{color:var(--text-3);text-decoration:line-through}.loc-note[data-v-cea34561]{font-size:12px}.ai-grid[data-v-cea34561]{display:flex;flex-direction:column;gap:10px}.backup-row[data-v-cea34561]{display:flex;gap:8px}.import-error[data-v-cea34561]{color:var(--danger);font-size:12px;margin-top:8px}.backup-note[data-v-cea34561]{font-size:12px;margin-top:10px}.login-page[data-v-bf714afa]{min-height:100vh;background:var(--bg-subtle);display:flex;align-items:center;justify-content:center;padding:20px}.login-card[data-v-bf714afa]{width:400px;max-width:100%;padding:28px 26px;display:flex;flex-direction:column;gap:12px;background:var(--bg-page)}.login-brand[data-v-bf714afa]{text-align:center;margin-bottom:6px}.brand-icon[data-v-bf714afa]{width:46px;height:46px;margin:0 auto 10px;border-radius:var(--radius-md);background:var(--accent-bg);color:var(--accent);display:flex;align-items:center;justify-content:center}.login-title[data-v-bf714afa]{font-size:18px;font-weight:600;color:var(--text-1)}.login-sub[data-v-bf714afa]{font-size:12px;margin-top:4px;line-height:1.7}.seg[data-v-bf714afa]{display:inline-flex;border:1px solid var(--border-strong);border-radius:var(--radius-sm);overflow:hidden}.seg-btn[data-v-bf714afa]{flex:1;height:30px;border:none;background:var(--bg-page);color:var(--text-2);cursor:pointer;font-size:13px}.seg-btn+.seg-btn[data-v-bf714afa]{border-left:1px solid var(--border)}.seg-btn.active[data-v-bf714afa]{background:var(--accent-bg);color:var(--accent)}.mig-row[data-v-bf714afa]{display:flex;align-items:flex-start;gap:8px;font-size:12px;color:var(--text-2);cursor:pointer;line-height:1.6}.mig-row input[data-v-bf714afa]{margin-top:3px}.form-error[data-v-bf714afa]{color:var(--danger);font-size:12px}.login-btn[data-v-bf714afa]{margin-top:2px}.login-note[data-v-bf714afa]{font-size:12px;text-align:center;line-height:1.7}.app[data-v-d5bd1ff7]{display:flex;height:100vh;height:100dvh;overflow:hidden}.side[data-v-d5bd1ff7]{width:56px;flex:none;border-right:1px solid var(--border);display:flex;flex-direction:column;align-items:center;padding-top:10px;gap:4px;background:var(--bg-page)}.nav-btn[data-v-d5bd1ff7]{width:40px;height:40px;display:flex;align-items:center;justify-content:center;border-radius:var(--radius-md);color:var(--text-3);cursor:pointer;border:none;background:transparent;position:relative}.nav-btn[data-v-d5bd1ff7]:hover{background:var(--bg-hover);color:var(--text-1)}.nav-btn.active[data-v-d5bd1ff7]{background:var(--accent-bg);color:var(--accent)}.nav-btn[data-v-d5bd1ff7]:after{content:attr(data-tip);position:absolute;left:46px;top:50%;transform:translateY(-50%);background:var(--text-1);color:#fff;font-size:12px;line-height:1.4;padding:2px 8px;border-radius:4px;white-space:nowrap;opacity:0;pointer-events:none;transition:opacity .15s}.nav-btn[data-v-d5bd1ff7]:hover:after{opacity:1}.main[data-v-d5bd1ff7]{flex:1;display:flex;flex-direction:column;min-width:0}.topbar[data-v-d5bd1ff7]{height:56px;flex:none;border-bottom:1px solid var(--border);display:flex;align-items:center;gap:12px;padding:0 20px}.title[data-v-d5bd1ff7]{font-size:14px;font-weight:600}.topbar-actions[data-v-d5bd1ff7]{display:flex;align-items:center;gap:8px}.gsearch[data-v-d5bd1ff7]{position:relative;width:300px;max-width:38vw}.gs-icon[data-v-d5bd1ff7]{position:absolute;left:10px;top:50%;transform:translateY(-50%);color:var(--text-3)}.gs-input[data-v-d5bd1ff7]{height:30px;padding-left:30px}.gs-panel[data-v-d5bd1ff7]{position:absolute;top:36px;left:0;right:0;background:var(--bg-page);border:1px solid var(--border);border-radius:var(--radius-md);box-shadow:var(--shadow-float);z-index:50;max-height:420px;overflow:auto;padding:6px}.gs-group[data-v-d5bd1ff7]{font-size:12px;padding:6px 8px 2px}.gs-item[data-v-d5bd1ff7]{display:flex;align-items:center;gap:8px;padding:6px 8px;border-radius:var(--radius-sm);cursor:pointer}.gs-item[data-v-d5bd1ff7]:hover{background:var(--bg-hover)}.gs-text[data-v-d5bd1ff7],.gs-sub[data-v-d5bd1ff7]{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.gs-text[data-v-d5bd1ff7]{font-size:13px}.gs-sub[data-v-d5bd1ff7]{font-size:12px}.gs-date[data-v-d5bd1ff7]{font-size:12px;flex:none}.gs-empty[data-v-d5bd1ff7]{padding:10px;font-size:12px;text-align:center}.user-chip[data-v-d5bd1ff7]{font-size:12px;color:var(--text-2);padding:0 4px}.week-tip[data-v-d5bd1ff7]{display:inline-flex;align-items:center;gap:6px;border:1px solid var(--warn);color:var(--warn);background:var(--bg-page);border-radius:999px;height:26px;padding:0 10px;font-size:12px;cursor:pointer}.week-tip[data-v-d5bd1ff7]:hover{background:var(--bg-subtle)}.content[data-v-d5bd1ff7]{flex:1;overflow:auto}.content-inner[data-v-d5bd1ff7]{max-width:1200px;margin:0 auto;padding:20px}.toast-wrap[data-v-d5bd1ff7]{position:fixed;top:68px;right:20px;z-index:60;display:flex;flex-direction:column;gap:8px;align-items:flex-end;pointer-events:none}.toast[data-v-d5bd1ff7]{background:var(--bg-page);border:1px solid var(--border);box-shadow:var(--shadow-float);border-radius:var(--radius-sm);padding:8px 14px;font-size:13px;color:var(--text-1)}.toast-enter-from[data-v-d5bd1ff7],.toast-leave-to[data-v-d5bd1ff7]{opacity:0;transform:translateY(-4px)}.toast-enter-active[data-v-d5bd1ff7],.toast-leave-active[data-v-d5bd1ff7]{transition:all .15s ease}@media (max-width: 720px){.app[data-v-d5bd1ff7]{flex-direction:column;height:100dvh}.side[data-v-d5bd1ff7]{order:2;width:100%;height:calc(54px + env(safe-area-inset-bottom));padding-bottom:env(safe-area-inset-bottom);flex-direction:row;justify-content:space-around;border-right:none;border-top:1px solid var(--border);padding-top:0}.main[data-v-d5bd1ff7]{order:1;flex:1;min-height:0}.nav-btn[data-v-d5bd1ff7]{width:44px;height:42px}.nav-btn[data-v-d5bd1ff7]:after{display:none}.topbar[data-v-d5bd1ff7]{flex-wrap:wrap;height:auto;min-height:52px;padding:8px 12px;row-gap:8px}.topbar>.flex1[data-v-d5bd1ff7]{display:none}.gsearch[data-v-d5bd1ff7]{order:10;width:100%;max-width:100%}.gs-input[data-v-d5bd1ff7]{height:34px}.gs-panel[data-v-d5bd1ff7]{top:100%}.topbar-actions[data-v-d5bd1ff7]{margin-left:auto}.user-chip[data-v-d5bd1ff7]{max-width:72px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.content-inner[data-v-d5bd1ff7]{padding:12px}.toast-wrap[data-v-d5bd1ff7]{top:8px;right:12px;left:12px;align-items:flex-end}}:root{--bg-page: #FFFFFF;--bg-subtle: #F7F8FA;--bg-hover: #F2F3F5;--border: #EBEDF0;--border-strong: #DCDEE3;--text-1: #1D2129;--text-2: #4E5969;--text-3: #86909C;--accent: #3370FF;--accent-bg: #F0F5FF;--ok: #23A757;--warn: #E8842C;--danger: #E5484D;--dot-empty: #C9CDD4;--radius-sm: 6px;--radius-md: 8px;--radius-lg: 12px;--shadow-float: 0 4px 16px rgba(29, 33, 41, .08)}*{box-sizing:border-box}html,body{margin:0;padding:0}body{background:var(--bg-page);color:var(--text-1);font-family:-apple-system,PingFang SC,Microsoft YaHei,system-ui,sans-serif;font-size:13px;line-height:1.6;-webkit-font-smoothing:antialiased}button,input,select,textarea{font:inherit;color:inherit}.num{font-variant-numeric:tabular-nums}.flex1{flex:1}.muted{color:var(--text-3)}.muted2{color:var(--text-2)}.btn{display:inline-flex;align-items:center;justify-content:center;gap:6px;padding:0 12px;height:32px;border-radius:var(--radius-sm);border:1px solid var(--border-strong);background:var(--bg-page);color:var(--text-1);cursor:pointer;white-space:nowrap}.btn:hover{background:var(--bg-hover)}.btn:disabled{opacity:.45;cursor:not-allowed}.btn-primary{background:var(--accent);border-color:var(--accent);color:#fff}.btn-primary:hover{background:#2b5fd9}.btn-danger{color:var(--danger);border-color:var(--danger)}.btn-sm{height:26px;padding:0 10px;font-size:12px}.btn-xs{height:22px;padding:0 8px;font-size:12px}.input,.select,.textarea{height:32px;padding:0 10px;border:1px solid var(--border-strong);border-radius:var(--radius-sm);background:var(--bg-page);outline:none;width:100%}.textarea{height:auto;min-height:56px;padding:8px 10px;resize:vertical}.input:focus,.select:focus,.textarea:focus{border-color:var(--accent)}.input::placeholder,.textarea::placeholder{color:var(--text-3)}.card{border:1px solid var(--border);border-radius:var(--radius-md);background:var(--bg-page)}.icon-btn{display:inline-flex;align-items:center;justify-content:center;width:26px;height:26px;flex:none;border:none;background:transparent;border-radius:var(--radius-sm);color:var(--text-3);cursor:pointer}.icon-btn:hover{background:var(--bg-hover);color:var(--text-1)}.icon-btn.active{color:var(--accent)}.icon-btn.active-warn{color:var(--warn)}.tag{display:inline-block;padding:0 8px;height:22px;line-height:20px;border-radius:4px;font-size:12px;background:var(--bg-subtle);color:var(--text-2);border:1px solid var(--border);white-space:nowrap}.dot{width:6px;height:6px;border-radius:50%;display:inline-block;flex:none}.dot.normal{background:var(--ok)}.dot.late,.dot.early,.dot.incomplete{background:var(--warn)}.dot.absent{background:var(--danger)}.dot.none,.dot.leave{background:var(--dot-empty)}@media (max-width: 720px){input,select,textarea{font-size:16px!important}input[type=checkbox]{font-size:initial}}.dot.rest{background:var(--border)}.icon{display:inline-flex;align-items:center;justify-content:center;flex:none}.icon svg{width:100%;height:100%;display:block} diff --git a/intern-log/dist/assets/web-KxR5SJwt.js b/intern-log/dist/assets/web-DCXp8Rvi.js similarity index 98% rename from intern-log/dist/assets/web-KxR5SJwt.js rename to intern-log/dist/assets/web-DCXp8Rvi.js index b41c52c..02a456c 100644 --- a/intern-log/dist/assets/web-KxR5SJwt.js +++ b/intern-log/dist/assets/web-DCXp8Rvi.js @@ -1 +1 @@ -import{W as P,b as x}from"./index-CAFZD9Jo.js";import{Encoding as E}from"./index-BYlgk7tc.js";function m(w){const e=w.split("/").filter(t=>t!=="."),r=[];return e.forEach(t=>{t===".."&&r.length>0&&r[r.length-1]!==".."?r.pop():r.push(t)}),r.join("/")}function R(w,e){w=m(w),e=m(e);const r=w.split("/"),t=e.split("/");return w!==e&&r.every((i,n)=>i===t[n])}class g extends P{constructor(){super(...arguments),this.DB_VERSION=1,this.DB_NAME="Disc",this._writeCmds=["add","put","delete"],this.downloadFile=async e=>{var r,t;const i=x(e,e.webFetchExtra),n=await fetch(e.url,i);let s;if(!e.progress)s=await n.blob();else if(!(n!=null&&n.body))s=new Blob;else{const c=n.body.getReader();let o=0;const d=[],h=n.headers.get("content-type"),y=parseInt(n.headers.get("content-length")||"0",10);for(;;){const{done:f,value:p}=await c.read();if(f)break;d.push(p),o+=(p==null?void 0:p.length)||0;const b={url:e.url,bytes:o,contentLength:y};this.notifyListeners("progress",b)}const u=new Uint8Array(o);let l=0;for(const f of d)typeof f>"u"||(u.set(f,l),l+=f.length);s=new Blob([u.buffer],{type:h||void 0})}return{path:(await this.writeFile({path:e.path,directory:(r=e.directory)!==null&&r!==void 0?r:void 0,recursive:(t=e.recursive)!==null&&t!==void 0?t:!1,data:s})).uri,blob:s}}}async initDb(){if(this._db!==void 0)return this._db;if(!("indexedDB"in window))throw this.unavailable("This browser doesn't support IndexedDB");return new Promise((e,r)=>{const t=indexedDB.open(this.DB_NAME,this.DB_VERSION);t.onupgradeneeded=g.doUpgrade,t.onsuccess=()=>{this._db=t.result,e(t.result)},t.onerror=()=>r(t.error),t.onblocked=()=>{console.warn("db blocked")}})}static doUpgrade(e){const t=e.target.result;switch(e.oldVersion){case 0:case 1:default:t.objectStoreNames.contains("FileStorage")&&t.deleteObjectStore("FileStorage"),t.createObjectStore("FileStorage",{keyPath:"path"}).createIndex("by_folder","folder")}}async dbRequest(e,r){const t=this._writeCmds.indexOf(e)!==-1?"readwrite":"readonly";return this.initDb().then(i=>new Promise((n,s)=>{const o=i.transaction(["FileStorage"],t).objectStore("FileStorage")[e](...r);o.onsuccess=()=>n(o.result),o.onerror=()=>s(o.error)}))}async dbIndexRequest(e,r,t){const i=this._writeCmds.indexOf(r)!==-1?"readwrite":"readonly";return this.initDb().then(n=>new Promise((s,a)=>{const h=n.transaction(["FileStorage"],i).objectStore("FileStorage").index(e)[r](...t);h.onsuccess=()=>s(h.result),h.onerror=()=>a(h.error)}))}getPath(e,r){const t=r!==void 0?r.replace(/^[/]+|[/]+$/g,""):"";let i="";return e!==void 0&&(i+="/"+e),r!==""&&(i+="/"+t),i}async clear(){(await this.initDb()).transaction(["FileStorage"],"readwrite").objectStore("FileStorage").clear()}async readFile(e){const r=this.getPath(e.directory,e.path),t=await this.dbRequest("get",[r]);if(t===void 0)throw Error("File does not exist.");return{data:t.content?t.content:""}}async writeFile(e){const r=this.getPath(e.directory,e.path);let t=e.data;const i=e.encoding,n=e.recursive,s=await this.dbRequest("get",[r]);if(s&&s.type==="directory")throw Error("The supplied path is a directory.");const a=r.substr(0,r.lastIndexOf("/"));if(await this.dbRequest("get",[a])===void 0){const h=a.indexOf("/",1);if(h!==-1){const y=a.substr(h);await this.mkdir({path:y,directory:e.directory,recursive:n})}}if(!i&&!(t instanceof Blob)&&(t=t.indexOf(",")>=0?t.split(",")[1]:t,!this.isBase64String(t)))throw Error("The supplied data is not valid base64 content.");const o=Date.now(),d={path:r,folder:a,type:"file",size:t instanceof Blob?t.size:t.length,ctime:o,mtime:o,content:t};return await this.dbRequest("put",[d]),{uri:d.path}}async appendFile(e){const r=this.getPath(e.directory,e.path);let t=e.data;const i=e.encoding,n=r.substr(0,r.lastIndexOf("/")),s=Date.now();let a=s;const c=await this.dbRequest("get",[r]);if(c&&c.type==="directory")throw Error("The supplied path is a directory.");if(await this.dbRequest("get",[n])===void 0){const h=n.indexOf("/",1);if(h!==-1){const y=n.substr(h);await this.mkdir({path:y,directory:e.directory,recursive:!0})}}if(!i&&!this.isBase64String(t))throw Error("The supplied data is not valid base64 content.");if(c!==void 0){if(c.content instanceof Blob)throw Error("The occupied entry contains a Blob object which cannot be appended to.");c.content!==void 0&&!i?t=btoa(atob(c.content)+atob(t)):t=c.content+t,a=c.ctime}const d={path:r,folder:n,type:"file",size:t.length,ctime:a,mtime:s,content:t};await this.dbRequest("put",[d])}async deleteFile(e){const r=this.getPath(e.directory,e.path);if(await this.dbRequest("get",[r])===void 0)throw Error("File does not exist.");if((await this.dbIndexRequest("by_folder","getAllKeys",[IDBKeyRange.only(r)])).length!==0)throw Error("Folder is not empty.");await this.dbRequest("delete",[r])}async mkdir(e){const r=this.getPath(e.directory,e.path),t=e.recursive,i=r.substr(0,r.lastIndexOf("/")),n=(r.match(/\//g)||[]).length,s=await this.dbRequest("get",[i]),a=await this.dbRequest("get",[r]);if(n===1)throw Error("Cannot create Root directory");if(a!==void 0)throw Error("Current directory does already exist.");if(!t&&n!==2&&s===void 0)throw Error("Parent directory must exist");if(t&&n!==2&&s===void 0){const d=i.substr(i.indexOf("/",1));await this.mkdir({path:d,directory:e.directory,recursive:t})}const c=Date.now(),o={path:r,folder:i,type:"directory",size:0,ctime:c,mtime:c};await this.dbRequest("put",[o])}async rmdir(e){const{path:r,directory:t,recursive:i}=e,n=this.getPath(t,r),s=await this.dbRequest("get",[n]);if(s===void 0)throw Error("Folder does not exist.");if(s.type!=="directory")throw Error("Requested path is not a directory");const a=await this.readdir({path:r,directory:t});if(a.files.length!==0&&!i)throw Error("Folder is not empty");for(const c of a.files){const o=`${r}/${c.name}`;(await this.stat({path:o,directory:t})).type==="file"?await this.deleteFile({path:o,directory:t}):await this.rmdir({path:o,directory:t,recursive:i})}await this.dbRequest("delete",[n])}async readdir(e){const r=this.getPath(e.directory,e.path),t=await this.dbRequest("get",[r]);if(e.path!==""&&t===void 0)throw Error("Folder does not exist.");const i=await this.dbIndexRequest("by_folder","getAllKeys",[IDBKeyRange.only(r)]);return{files:await Promise.all(i.map(async s=>{let a=await this.dbRequest("get",[s]);return a===void 0&&(a=await this.dbRequest("get",[s+"/"])),{name:s.substring(r.length+1),type:a.type,size:a.size,ctime:a.ctime,mtime:a.mtime,uri:a.path}}))}}async getUri(e){const r=this.getPath(e.directory,e.path);let t=await this.dbRequest("get",[r]);return t===void 0&&(t=await this.dbRequest("get",[r+"/"])),{uri:(t==null?void 0:t.path)||r}}async stat(e){const r=this.getPath(e.directory,e.path);let t=await this.dbRequest("get",[r]);if(t===void 0&&(t=await this.dbRequest("get",[r+"/"])),t===void 0)throw Error("Entry does not exist.");return{type:t.type,size:t.size,ctime:t.ctime,mtime:t.mtime,uri:t.path}}async rename(e){await this._copy(e,!0)}async copy(e){return this._copy(e,!1)}async requestPermissions(){return{publicStorage:"granted"}}async checkPermissions(){return{publicStorage:"granted"}}async _copy(e,r=!1){let{toDirectory:t}=e;const{to:i,from:n,directory:s}=e;if(!i||!n)throw Error("Both to and from must be provided");t||(t=s);const a=this.getPath(s,n),c=this.getPath(t,i);if(a===c)return{uri:c};if(R(a,c))throw Error("To path cannot contain the from path");let o;try{o=await this.stat({path:i,directory:t})}catch{const l=i.split("/");l.pop();const f=l.join("/");if(l.length>0&&(await this.stat({path:f,directory:t})).type!=="directory")throw new Error("Parent directory of the to path is a file")}if(o&&o.type==="directory")throw new Error("Cannot overwrite a directory with a file");const d=await this.stat({path:n,directory:s}),h=async(u,l,f)=>{const p=this.getPath(t,u),b=await this.dbRequest("get",[p]);b.ctime=l,b.mtime=f,await this.dbRequest("put",[b])},y=d.ctime?d.ctime:Date.now();switch(d.type){case"file":{const u=await this.readFile({path:n,directory:s});r&&await this.deleteFile({path:n,directory:s});let l;!(u.data instanceof Blob)&&!this.isBase64String(u.data)&&(l=E.UTF8);const f=await this.writeFile({path:i,directory:t,data:u.data,encoding:l});return r&&await h(i,y,d.mtime),f}case"directory":{if(o)throw Error("Cannot move a directory over an existing object");try{await this.mkdir({path:i,directory:t,recursive:!1}),r&&await h(i,y,d.mtime)}catch{}const u=(await this.readdir({path:n,directory:s})).files;for(const l of u)await this._copy({from:`${n}/${l.name}`,to:`${i}/${l.name}`,directory:s,toDirectory:t},r);r&&await this.rmdir({path:n,directory:s})}}return{uri:c}}isBase64String(e){try{return btoa(atob(e))==e}catch{return!1}}}g._debug=!0;export{g as FilesystemWeb}; +import{W as P,b as x}from"./index-BztxiTek.js";import{Encoding as E}from"./index-2zIp9hhK.js";function m(w){const e=w.split("/").filter(t=>t!=="."),r=[];return e.forEach(t=>{t===".."&&r.length>0&&r[r.length-1]!==".."?r.pop():r.push(t)}),r.join("/")}function R(w,e){w=m(w),e=m(e);const r=w.split("/"),t=e.split("/");return w!==e&&r.every((i,n)=>i===t[n])}class g extends P{constructor(){super(...arguments),this.DB_VERSION=1,this.DB_NAME="Disc",this._writeCmds=["add","put","delete"],this.downloadFile=async e=>{var r,t;const i=x(e,e.webFetchExtra),n=await fetch(e.url,i);let s;if(!e.progress)s=await n.blob();else if(!(n!=null&&n.body))s=new Blob;else{const c=n.body.getReader();let o=0;const d=[],h=n.headers.get("content-type"),y=parseInt(n.headers.get("content-length")||"0",10);for(;;){const{done:f,value:p}=await c.read();if(f)break;d.push(p),o+=(p==null?void 0:p.length)||0;const b={url:e.url,bytes:o,contentLength:y};this.notifyListeners("progress",b)}const u=new Uint8Array(o);let l=0;for(const f of d)typeof f>"u"||(u.set(f,l),l+=f.length);s=new Blob([u.buffer],{type:h||void 0})}return{path:(await this.writeFile({path:e.path,directory:(r=e.directory)!==null&&r!==void 0?r:void 0,recursive:(t=e.recursive)!==null&&t!==void 0?t:!1,data:s})).uri,blob:s}}}async initDb(){if(this._db!==void 0)return this._db;if(!("indexedDB"in window))throw this.unavailable("This browser doesn't support IndexedDB");return new Promise((e,r)=>{const t=indexedDB.open(this.DB_NAME,this.DB_VERSION);t.onupgradeneeded=g.doUpgrade,t.onsuccess=()=>{this._db=t.result,e(t.result)},t.onerror=()=>r(t.error),t.onblocked=()=>{console.warn("db blocked")}})}static doUpgrade(e){const t=e.target.result;switch(e.oldVersion){case 0:case 1:default:t.objectStoreNames.contains("FileStorage")&&t.deleteObjectStore("FileStorage"),t.createObjectStore("FileStorage",{keyPath:"path"}).createIndex("by_folder","folder")}}async dbRequest(e,r){const t=this._writeCmds.indexOf(e)!==-1?"readwrite":"readonly";return this.initDb().then(i=>new Promise((n,s)=>{const o=i.transaction(["FileStorage"],t).objectStore("FileStorage")[e](...r);o.onsuccess=()=>n(o.result),o.onerror=()=>s(o.error)}))}async dbIndexRequest(e,r,t){const i=this._writeCmds.indexOf(r)!==-1?"readwrite":"readonly";return this.initDb().then(n=>new Promise((s,a)=>{const h=n.transaction(["FileStorage"],i).objectStore("FileStorage").index(e)[r](...t);h.onsuccess=()=>s(h.result),h.onerror=()=>a(h.error)}))}getPath(e,r){const t=r!==void 0?r.replace(/^[/]+|[/]+$/g,""):"";let i="";return e!==void 0&&(i+="/"+e),r!==""&&(i+="/"+t),i}async clear(){(await this.initDb()).transaction(["FileStorage"],"readwrite").objectStore("FileStorage").clear()}async readFile(e){const r=this.getPath(e.directory,e.path),t=await this.dbRequest("get",[r]);if(t===void 0)throw Error("File does not exist.");return{data:t.content?t.content:""}}async writeFile(e){const r=this.getPath(e.directory,e.path);let t=e.data;const i=e.encoding,n=e.recursive,s=await this.dbRequest("get",[r]);if(s&&s.type==="directory")throw Error("The supplied path is a directory.");const a=r.substr(0,r.lastIndexOf("/"));if(await this.dbRequest("get",[a])===void 0){const h=a.indexOf("/",1);if(h!==-1){const y=a.substr(h);await this.mkdir({path:y,directory:e.directory,recursive:n})}}if(!i&&!(t instanceof Blob)&&(t=t.indexOf(",")>=0?t.split(",")[1]:t,!this.isBase64String(t)))throw Error("The supplied data is not valid base64 content.");const o=Date.now(),d={path:r,folder:a,type:"file",size:t instanceof Blob?t.size:t.length,ctime:o,mtime:o,content:t};return await this.dbRequest("put",[d]),{uri:d.path}}async appendFile(e){const r=this.getPath(e.directory,e.path);let t=e.data;const i=e.encoding,n=r.substr(0,r.lastIndexOf("/")),s=Date.now();let a=s;const c=await this.dbRequest("get",[r]);if(c&&c.type==="directory")throw Error("The supplied path is a directory.");if(await this.dbRequest("get",[n])===void 0){const h=n.indexOf("/",1);if(h!==-1){const y=n.substr(h);await this.mkdir({path:y,directory:e.directory,recursive:!0})}}if(!i&&!this.isBase64String(t))throw Error("The supplied data is not valid base64 content.");if(c!==void 0){if(c.content instanceof Blob)throw Error("The occupied entry contains a Blob object which cannot be appended to.");c.content!==void 0&&!i?t=btoa(atob(c.content)+atob(t)):t=c.content+t,a=c.ctime}const d={path:r,folder:n,type:"file",size:t.length,ctime:a,mtime:s,content:t};await this.dbRequest("put",[d])}async deleteFile(e){const r=this.getPath(e.directory,e.path);if(await this.dbRequest("get",[r])===void 0)throw Error("File does not exist.");if((await this.dbIndexRequest("by_folder","getAllKeys",[IDBKeyRange.only(r)])).length!==0)throw Error("Folder is not empty.");await this.dbRequest("delete",[r])}async mkdir(e){const r=this.getPath(e.directory,e.path),t=e.recursive,i=r.substr(0,r.lastIndexOf("/")),n=(r.match(/\//g)||[]).length,s=await this.dbRequest("get",[i]),a=await this.dbRequest("get",[r]);if(n===1)throw Error("Cannot create Root directory");if(a!==void 0)throw Error("Current directory does already exist.");if(!t&&n!==2&&s===void 0)throw Error("Parent directory must exist");if(t&&n!==2&&s===void 0){const d=i.substr(i.indexOf("/",1));await this.mkdir({path:d,directory:e.directory,recursive:t})}const c=Date.now(),o={path:r,folder:i,type:"directory",size:0,ctime:c,mtime:c};await this.dbRequest("put",[o])}async rmdir(e){const{path:r,directory:t,recursive:i}=e,n=this.getPath(t,r),s=await this.dbRequest("get",[n]);if(s===void 0)throw Error("Folder does not exist.");if(s.type!=="directory")throw Error("Requested path is not a directory");const a=await this.readdir({path:r,directory:t});if(a.files.length!==0&&!i)throw Error("Folder is not empty");for(const c of a.files){const o=`${r}/${c.name}`;(await this.stat({path:o,directory:t})).type==="file"?await this.deleteFile({path:o,directory:t}):await this.rmdir({path:o,directory:t,recursive:i})}await this.dbRequest("delete",[n])}async readdir(e){const r=this.getPath(e.directory,e.path),t=await this.dbRequest("get",[r]);if(e.path!==""&&t===void 0)throw Error("Folder does not exist.");const i=await this.dbIndexRequest("by_folder","getAllKeys",[IDBKeyRange.only(r)]);return{files:await Promise.all(i.map(async s=>{let a=await this.dbRequest("get",[s]);return a===void 0&&(a=await this.dbRequest("get",[s+"/"])),{name:s.substring(r.length+1),type:a.type,size:a.size,ctime:a.ctime,mtime:a.mtime,uri:a.path}}))}}async getUri(e){const r=this.getPath(e.directory,e.path);let t=await this.dbRequest("get",[r]);return t===void 0&&(t=await this.dbRequest("get",[r+"/"])),{uri:(t==null?void 0:t.path)||r}}async stat(e){const r=this.getPath(e.directory,e.path);let t=await this.dbRequest("get",[r]);if(t===void 0&&(t=await this.dbRequest("get",[r+"/"])),t===void 0)throw Error("Entry does not exist.");return{type:t.type,size:t.size,ctime:t.ctime,mtime:t.mtime,uri:t.path}}async rename(e){await this._copy(e,!0)}async copy(e){return this._copy(e,!1)}async requestPermissions(){return{publicStorage:"granted"}}async checkPermissions(){return{publicStorage:"granted"}}async _copy(e,r=!1){let{toDirectory:t}=e;const{to:i,from:n,directory:s}=e;if(!i||!n)throw Error("Both to and from must be provided");t||(t=s);const a=this.getPath(s,n),c=this.getPath(t,i);if(a===c)return{uri:c};if(R(a,c))throw Error("To path cannot contain the from path");let o;try{o=await this.stat({path:i,directory:t})}catch{const l=i.split("/");l.pop();const f=l.join("/");if(l.length>0&&(await this.stat({path:f,directory:t})).type!=="directory")throw new Error("Parent directory of the to path is a file")}if(o&&o.type==="directory")throw new Error("Cannot overwrite a directory with a file");const d=await this.stat({path:n,directory:s}),h=async(u,l,f)=>{const p=this.getPath(t,u),b=await this.dbRequest("get",[p]);b.ctime=l,b.mtime=f,await this.dbRequest("put",[b])},y=d.ctime?d.ctime:Date.now();switch(d.type){case"file":{const u=await this.readFile({path:n,directory:s});r&&await this.deleteFile({path:n,directory:s});let l;!(u.data instanceof Blob)&&!this.isBase64String(u.data)&&(l=E.UTF8);const f=await this.writeFile({path:i,directory:t,data:u.data,encoding:l});return r&&await h(i,y,d.mtime),f}case"directory":{if(o)throw Error("Cannot move a directory over an existing object");try{await this.mkdir({path:i,directory:t,recursive:!1}),r&&await h(i,y,d.mtime)}catch{}const u=(await this.readdir({path:n,directory:s})).files;for(const l of u)await this._copy({from:`${n}/${l.name}`,to:`${i}/${l.name}`,directory:s,toDirectory:t},r);r&&await this.rmdir({path:n,directory:s})}}return{uri:c}}isBase64String(e){try{return btoa(atob(e))==e}catch{return!1}}}g._debug=!0;export{g as FilesystemWeb}; diff --git a/intern-log/dist/index.html b/intern-log/dist/index.html index 71816f7..d0059da 100644 --- a/intern-log/dist/index.html +++ b/intern-log/dist/index.html @@ -8,8 +8,8 @@ 实习工作日志 - - + +
diff --git a/intern-log/repro/engine-realtime.ts b/intern-log/repro/engine-realtime.ts index 35b9ff7..92cfbab 100644 --- a/intern-log/repro/engine-realtime.ts +++ b/intern-log/repro/engine-realtime.ts @@ -15,8 +15,8 @@ const store = new Map() setItem: (k: string, v: string) => { store.set(k, String(v)) }, removeItem: (k: string) => { store.delete(k) } } -store.set('dsh_cloud_creds', JSON.stringify({ username: 'audit_a', password: 'aapass123' })) -store.set('dsh_session_user', JSON.stringify({ userId: 'local_rt', username: 'audit_a' })) +store.set('dsh_cloud_creds', JSON.stringify({ username: 'twodev', password: 'dev123456' })) +store.set('dsh_session_user', JSON.stringify({ userId: 'local_rt', username: 'twodev' })) // Node 24 自带 EventSource;老环境则垫一个基于 fetch 流的最小实现 if (typeof (globalThis as any).EventSource === 'undefined') { @@ -54,7 +54,7 @@ async function main() { check('Node 有 EventSource(原生或垫片)', typeof (globalThis as any).EventSource !== 'undefined') bindDatabase(new WorklogDB('rt_a')) - await repo.setSetting('sync_base_url', BASE) // 测试环境指向本机服务 + store.set('dsh_sync_base', BASE) // 测试环境同步基址走本地覆盖 engine.enableRealtimeSync() // ---- 场景1:本地写入 -> 防抖 3s -> 自动推送 ---- @@ -63,7 +63,7 @@ async function main() { const login = await fetch(BASE + '/api/auth/login', { method: 'POST', headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ username: 'audit_a', password: 'aapass123' }) + body: JSON.stringify({ username: 'twodev', password: 'dev123456' }) }) const tok = (await login.json()).token as string async function serverSnapshot(): Promise> { @@ -101,10 +101,10 @@ async function main() { // ---- 场景3:autoSyncNow 手动失败可见性(断開服务)---- engine.stopRealtime() - await repo.setSetting('sync_base_url', 'http://127.0.0.1:9') // 不可达端口 + store.set('dsh_sync_base', 'http://127.0.0.1:9') // 服务不可达 await engine.autoSyncNow() check('服务不可达时 syncLastError 被记录', engine.syncLastError.value !== '', engine.syncLastError.value) - await repo.setSetting('sync_base_url', BASE) + store.set('dsh_sync_base', BASE) console.log('==== 实时链路审计: PASS ' + pass + ' / FAIL ' + fail + ' ====') process.exit(fail > 0 ? 1 : 0) diff --git a/intern-log/src/db/auth.ts b/intern-log/src/db/auth.ts index a64d3b1..d55e99c 100644 --- a/intern-log/src/db/auth.ts +++ b/intern-log/src/db/auth.ts @@ -1,27 +1,9 @@ -import Dexie, { type Table } from 'dexie' +// 身份认证:账号与密码哈希只保存在服务器(PBKDF2) +// 本机仅保存"会话标识"与自动登录凭据(localStorage),用于免重复登录 +// 业务数据一律在服务器,本机数据库只是缓存(由同步引擎全量刷新) import { bindDatabase, db, unbindDatabase, WorklogDB } from './schema' import { lockVault } from './vault' -import { pbkdf2Hash, randomSaltB64 } from '../lib/crypto' - -interface UserRecord { - id: string - username: string - pwd_hash: string - pwd_salt: string - legacy_imported_at?: string - created_at: string -} - -// 用户注册表:独立小库,仅存用户名与密码哈希,不存任何业务数据 -class UserRegistry extends Dexie { - user!: Table - constructor() { - super('intern_worklog_users') - this.version(1).stores({ user: 'id, &username' }) - } -} - -const registry = new UserRegistry() +import { getSyncBase } from '../lib/server' const LEGACY_DB_NAME = 'intern_worklog' const SESSION_KEY = 'dsh_session_user' @@ -31,8 +13,8 @@ export interface Session { username: string } -// 会话持久化到 localStorage:关闭浏览器后仍保持登录,无需每次使用都登录 -// 安全边界:密码库主密码不随会话保存,每次启动仍需解锁 +// ---------- 本地会话与凭据 ---------- + export function getSession(): Session | null { try { const raw = localStorage.getItem(SESSION_KEY) @@ -42,14 +24,16 @@ export function getSession(): Session | null { } catch { /* 忽略损坏会话 */ } return null } + function setSession(s: Session): void { localStorage.setItem(SESSION_KEY, JSON.stringify(s)) } + function clearSession(): void { localStorage.removeItem(SESSION_KEY) } -// 云端凭据:与本地登录同账号同密码,用于登录后自动云同步(保存在本机浏览器) +// 云端凭据:同用户名同密码,用于应用启动时免输密码的自动登录 const CREDS_KEY = 'dsh_cloud_creds' export function setCloudCreds(username: string, password: string): void { localStorage.setItem(CREDS_KEY, JSON.stringify({ username, password })) @@ -67,6 +51,8 @@ export function clearCloudCreds(): void { localStorage.removeItem(CREDS_KEY) } +// ---------- 用户数据库(本地缓存实例) ---------- + let openedFor: string | null = null export function openUserDatabase(userId: string): void { @@ -76,42 +62,76 @@ export function openUserDatabase(userId: string): void { openedFor = userId } -export async function createUser(username: string, password: string, migrateLegacy: boolean): Promise { - const name = username.trim() - if (name.length < 2 || name.length > 20) throw new Error('用户名需 2 到 20 个字符') - if (password.length < 6) throw new Error('登录密码至少 6 位') - const exists = await registry.user.where('username').equals(name).first() - if (exists) throw new Error('用户名已存在') - const salt = randomSaltB64() - const hash = await pbkdf2Hash(password, salt) - const id = 'u_' + Date.now().toString(36) + '_' + Math.random().toString(36).slice(2, 6) - await registry.user.add({ id, username: name, pwd_hash: hash, pwd_salt: salt, created_at: new Date().toISOString() }) - openUserDatabase(id) - let copied = 0 - if (migrateLegacy && await legacyDataExists()) { - copied = await migrateLegacyInto() - await registry.user.update(id, { legacy_imported_at: new Date().toISOString() }) +// ---------- 登录 / 注册(全部经由服务器) ---------- + +async function serverAuth(path: 'login' | 'register', username: string, password: string): Promise<{ userId: string; username: string }> { + const base = await getSyncBase() + let resp: Response + try { + resp = await fetch(base + '/api/auth/' + path, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ username: username.trim(), password }) + }) + } catch { + throw new Error('无法连接同步服务器:请检查网络后重试') } - const session: Session = { userId: id, username: name } + const j = await resp.json().catch(() => ({})) + if (!resp.ok) { + const msg = (j && j.error) || ('服务返回 ' + resp.status) + if (path === 'register' && resp.status === 409) throw new Error('云端已有同名账号且密码一致,直接登录即可') + throw new Error(String(msg)) + } + if (!j.userId || !j.username) throw new Error('登录响应异常') + return { userId: String(j.userId), username: String(j.username) } +} + +async function establishSession(username: string, password: string, path: 'login' | 'register'): Promise { + const info = await serverAuth(path, username, password) + openUserDatabase(info.userId) + const session: Session = { userId: info.userId, username: info.username } setSession(session) - setCloudCreds(session.username, password) + setCloudCreds(info.username, password) return session } export async function login(username: string, password: string): Promise { - const name = username.trim() - const rec = await registry.user.where('username').equals(name).first() - if (!rec) throw new Error('用户不存在') - const hash = await pbkdf2Hash(password, rec.pwd_salt) - if (hash !== rec.pwd_hash) throw new Error('密码不正确') - openUserDatabase(rec.id) - const session: Session = { userId: rec.id, username: rec.username } - setSession(session) - setCloudCreds(session.username, password) - return session + const name = (username || '').trim() + if (!name || !password) throw new Error('请输入用户名与密码') + return establishSession(name, password, 'login') +} + +export interface RegisterOptions { migrateLegacy?: boolean } + +export async function createUser(username: string, password: string): Promise +export async function createUser(username: string, password: string, migrateLegacy: boolean): Promise +export async function createUser(username: string, password: string, _migrateLegacy?: boolean): Promise { + const name = (username || '').trim() + if (name.length < 2 || name.length > 20) throw new Error('用户名需 2 到 20 个字符') + if (password.length < 6) throw new Error('登录密码至少 6 位') + return establishSession(name, password, 'register') +} + +// 启动引导:已保存过凭据则静默登录,直接进入应用 +export async function bootstrapSession(): Promise { + const creds = getCloudCreds() + if (!creds) return null + try { + return await establishSession(creds.username, creds.password, 'login') + } catch { + return null + } } export async function logoutUser(): Promise { + lockVault() + unbindDatabase() + openedFor = null + // 保留云端凭据:退出登录后再次打开仍可一键重新进入;如需彻底退出请删除用户 + clearSession() +} + +export function forgetDevice(): void { lockVault() unbindDatabase() openedFor = null @@ -123,67 +143,54 @@ export async function changeLoginPassword(oldPwd: string, newPwd: string): Promi const s = getSession() if (!s) throw new Error('未登录') if (newPwd.length < 6) throw new Error('新密码至少 6 位') - const rec = await registry.user.get(s.userId) - if (!rec) throw new Error('用户不存在') - const oldHash = await pbkdf2Hash(oldPwd, rec.pwd_salt) - if (oldHash !== rec.pwd_hash) throw new Error('旧密码不正确') - const salt = randomSaltB64() - const hash = await pbkdf2Hash(newPwd, salt) - await registry.user.update(rec.id, { pwd_hash: hash, pwd_salt: salt }) + const creds = getCloudCreds() + if (!creds || creds.password !== oldPwd) throw new Error('旧密码不正确') + const base = await getSyncBase() + let resp: Response + try { + resp = await fetch(base + '/api/auth/password', { + method: 'POST', + headers: { 'Content-Type': 'application/json', Authorization: 'Bearer ' + getCachedToken() }, + body: JSON.stringify({ oldPassword: oldPwd, newPassword: newPwd }) + }) + } catch { + throw new Error('无法连接同步服务器') + } + if (!resp.ok) { + const j = await resp.json().catch(() => ({})) + throw new Error((j && j.error) || ('修改失败 ' + resp.status)) + } + setCloudCreds(creds.username, newPwd) } export async function deleteCurrentUser(): Promise { const s = getSession() if (!s) throw new Error('未登录') - lockVault() - unbindDatabase() - openedFor = null - await Dexie.delete(LEGACY_DB_NAME + '_' + s.userId) - await registry.user.delete(s.userId) - clearSession() - clearCloudCreds() + const base = await getSyncBase() + let resp: Response + try { + resp = await fetch(base + '/api/auth/delete', { + method: 'POST', + headers: { Authorization: 'Bearer ' + getCachedToken() } + }) + } catch { + throw new Error('无法连接同步服务器') + } + if (!resp.ok) { + const j = await resp.json().catch(() => ({})) + throw new Error((j && j.error) || ('删除失败 ' + resp.status)) + } + forgetDevice() } -// 旧单机数据检测与迁移(迁移只复制,不删除原库,作为安全兜底) +// 令牌由同步引擎负责登录换取/续期;此处读取共享的本地令牌副本 +import { getToken } from '../lib/server' +function getCachedToken(): string { + return getToken() +} + +// 兼容旧导出:纯在线模式下不再存在本机旧数据迁移(账号与数据都在服务器) export async function legacyDataExists(): Promise { - return Dexie.exists(LEGACY_DB_NAME) -} - -async function migrateLegacyInto(): Promise { - if (!db) throw new Error('用户数据库未就绪') - const legacy = new WorklogDB(LEGACY_DB_NAME) - const legacyData = await Promise.all([ - legacy.project.toArray(), - legacy.work_log.toArray(), - legacy.log_item.toArray(), - legacy.attendance.toArray(), - legacy.weekly_note.toArray(), - legacy.setting.toArray(), - legacy.memo.toArray(), - legacy.credential.toArray() - ]) - await db.transaction('rw', [db.project, db.work_log, db.log_item, db.attendance, db.weekly_note, db.setting, db.memo, db.credential], async () => { - await Promise.all([ - db.project.clear(), db.work_log.clear(), db.log_item.clear(), - db.attendance.clear(), db.weekly_note.clear(), db.setting.clear(), - db.memo.clear(), db.credential.clear() - ]) - if (legacyData[0].length) await db.project.bulkAdd(legacyData[0] as never[]) - if (legacyData[1].length) await db.work_log.bulkAdd(legacyData[1] as never[]) - if (legacyData[2].length) await db.log_item.bulkAdd(legacyData[2] as never[]) - if (legacyData[3].length) await db.attendance.bulkAdd(legacyData[3] as never[]) - if (legacyData[4].length) await db.weekly_note.bulkAdd(legacyData[4] as never[]) - if (legacyData[5].length) await db.setting.bulkAdd(legacyData[5] as never[]) - if (legacyData[6].length) await db.memo.bulkAdd(legacyData[6] as never[]) - if (legacyData[7].length) await db.credential.bulkAdd(legacyData[7] as never[]) - }) - const count = legacyData[0].length + legacyData[1].length + legacyData[2].length + - legacyData[3].length + legacyData[4].length + legacyData[6].length + legacyData[7].length - legacy.close() - return count -} - -function showToastCopied(count: number): void { - // 迁移完成的反馈由登录后的轻提示呈现(此处在会话建立前,暂存标记) - try { sessionStorage.setItem('dsh_migrate_toast', String(count)) } catch { /* 忽略 */ } + void LEGACY_DB_NAME + return false } diff --git a/intern-log/src/db/repo.ts b/intern-log/src/db/repo.ts index 2a9c100..9a4e338 100644 --- a/intern-log/src/db/repo.ts +++ b/intern-log/src/db/repo.ts @@ -1,5 +1,17 @@ +// 数据仓库:全部业务数据只有服务器一份权威副本,本地 Dexie 是实时缓存。 +// 约定:每个写函数修改本地缓存后立即调用 commit() —— 推送差异给服务器, +// 并以服务器返回的权威快照重建缓存;断网时抛出错误(纯在线模式)。 import { db, DEFAULT_LOCATIONS, SCHEMA_VERSION, type Attendance, type Credential, type LogItem, type Memo, type Project, type Transaction, type WeeklyNote, type WorkLog } from './schema' import { addDays, nowLocalISO, toDateStr } from '../lib/date' +import { flushAfterWrite } from '../sync/engine' + +// 这些本地临时键不参与同步,写入时不触发推送 +const LOCAL_ONLY_KEYS = new Set(['sync_cursor', 'sync_last_time', 'sync_token', 'last_project', 'last_category']) + +// 写后即时提交:推送 + 快照重建;失败向上抛(调用方已有 toast 展示) +async function commit(): Promise { + await flushAfterWrite() +} // ---------- 设置 ---------- @@ -10,6 +22,7 @@ export async function getSetting(key: string, fallback: string): Promise export async function setSetting(key: string, value: string): Promise { await db.setting.put({ key, value }) + if (!LOCAL_ONLY_KEYS.has(key)) await commit() } export interface WorkRule { @@ -52,15 +65,21 @@ export async function setAttendanceLocation(date: string, location: string): Pro const loc = location.trim() await setSetting('last_location', loc) if (loc) await rememberLocation(loc) + let committed = false const row = await getAttendance(date) if (row && row.id) { - await db.attendance.update(row.id, { location: loc || null }) + if ((row.location || '') !== loc) { + await db.attendance.update(row.id, { location: loc || null }) + committed = true + } } else if (loc) { await db.attendance.add({ date, clock_in_at: null, clock_out_at: null, kind: 'normal', note: null, location: loc, created_at: nowLocalISO() }) + committed = true } + if (committed) await commit() } export async function getLocationPresets(): Promise { @@ -99,14 +118,17 @@ export async function listProjects(includeArchived = false): Promise export async function addProject(name: string): Promise { await db.project.add({ name: name.trim(), archived: 0, created_at: nowLocalISO() }) + await commit() } export async function renameProject(id: number, name: string): Promise { await db.project.update(id, { name: name.trim() }) + await commit() } export async function setProjectArchived(id: number, archived: boolean): Promise { await db.project.update(id, { archived: archived ? 1 : 0 }) + await commit() } // ---------- 打卡 ---------- @@ -117,17 +139,22 @@ export async function getAttendance(date: string): Promise { const loc = ((location === undefined ? await getSetting('last_location', '') : location) || '').trim() + let committed = false const row = await getAttendance(date) if (row && row.id) { if (!row.clock_in_at) { const patch: Partial = { clock_in_at: nowLocalISO() } if (loc) patch.location = loc await db.attendance.update(row.id, patch) + committed = true } if (loc) { - await setSetting('last_location', loc) + if ((await getSetting('last_location', '')) !== loc) { + await setSetting('last_location', loc) + } await rememberLocation(loc) } + if (committed) await commit() return } await db.attendance.add({ @@ -138,31 +165,38 @@ export async function clockIn(date: string, location?: string): Promise { await setSetting('last_location', loc) await rememberLocation(loc) } + await commit() } export async function clockOut(date: string): Promise { const row = await getAttendance(date) if (row && row.id && row.clock_in_at && !row.clock_out_at) { await db.attendance.update(row.id, { clock_out_at: nowLocalISO() }) + await commit() } } export async function smartClockOut(): Promise { const now = new Date() const today = toDateStr(now) + let touched = '' if (now.getHours() < 4) { const yRec = await getAttendance(addDays(today, -1)) if (yRec && yRec.id && yRec.clock_in_at && !yRec.clock_out_at) { await db.attendance.update(yRec.id, { clock_out_at: nowLocalISO() }) - return yRec.date + touched = yRec.date } } - const tRec = await getAttendance(today) - if (tRec && tRec.id && tRec.clock_in_at && !tRec.clock_out_at) { - await db.attendance.update(tRec.id, { clock_out_at: nowLocalISO() }) - return tRec.date + if (!touched) { + const tRec = await getAttendance(today) + if (tRec && tRec.id && tRec.clock_in_at && !tRec.clock_out_at) { + await db.attendance.update(tRec.id, { clock_out_at: nowLocalISO() }) + touched = tRec.date + } } - throw new Error('没有进行中的打卡') + if (!touched) throw new Error('没有进行中的打卡') + await commit() + return touched } export async function saveMakeup(date: string, inAt: string, outAt: string, note: string, location?: string): Promise { @@ -179,6 +213,7 @@ export async function saveMakeup(date: string, inAt: string, outAt: string, note } if (row && row.id) await db.attendance.update(row.id, patch) else await db.attendance.add(patch) + await commit() } // 直接修改某天的上/下班时间(行内编辑),状态由 computeDay 运行时自动重算 @@ -188,6 +223,7 @@ export async function setAttendanceTime(date: string, field: 'clock_in_at' | 'cl const row = await getAttendance(date) if (row && row.id) { await db.attendance.update(row.id, { [field]: date + 'T' + t + ':00' }) + await commit() } } @@ -205,6 +241,7 @@ export async function setLeave(date: string, leave: boolean): Promise { } else if (row && row.id) { await db.attendance.update(row.id, { kind: 'normal' }) } + await commit() } // ---------- 工作日志 ---------- @@ -237,8 +274,17 @@ export interface NewLogItem { } export async function addLogItem(date: string, data: NewLogItem): Promise { - const wl = await ensureWorkLog(date) - await db.log_item.add({ + let wlExisted = true + let changedWorkLog = false + const existing = await db.work_log.where('date').equals(date).first() + let wl: WorkLog + if (existing && existing.id) wl = existing + else { + wlExisted = false + wl = await ensureWorkLog(date) + changedWorkLog = true + } + await db.table('log_item').add({ work_log_id: wl.id as number, content: data.content, project_id: data.project_id, @@ -251,23 +297,35 @@ export async function addLogItem(date: string, data: NewLogItem): Promise sort_order: 0, created_at: nowLocalISO() }) - await setSetting('last_project', data.project_id ? String(data.project_id) : '') - await setSetting('last_category', data.category) + const lpKey = data.project_id ? String(data.project_id) : '' + if ((await getSetting('last_project', '')) !== lpKey) { + await setSetting('last_project', lpKey) + changedWorkLog = true + } + if ((await getSetting('last_category', '')) !== data.category) { + await setSetting('last_category', data.category) + changedWorkLog = true + } + void wlExisted + await commit() + void changedWorkLog } export async function updateLogItem(id: number, patch: Partial): Promise { - await db.log_item.update(id, patch) + await db.table('log_item').update(id, patch) + await commit() } export async function deleteLogItem(id: number): Promise { - await db.log_item.delete(id) + await db.table('log_item').delete(id) + await commit() } export async function listLogItemsBetween(start: string, end: string): Promise<(LogItem & { date: string })[]> { const wls = await db.work_log.where('date').between(start, end, true, true).toArray() if (!wls.length) return [] const map = new Map(wls.map(w => [w.id as number, w.date])) - const items = await db.log_item.where('work_log_id').anyOf(wls.map(w => w.id as number)).toArray() + const items = await db.table('log_item').where('work_log_id').anyOf(wls.map(w => w.id as number)).toArray() return items .map(it => ({ ...it, date: map.get(it.work_log_id) || '' })) .sort((a, b) => (a.date === b.date ? (a.id as number) - (b.id as number) : a.date < b.date ? -1 : 1)) @@ -295,6 +353,7 @@ export async function saveWeeklyNote( created_at: nowLocalISO() }) } + await commit() } export async function listWeeklyNotesBetween(start: string, end: string): Promise { @@ -311,15 +370,18 @@ export async function listMemos(): Promise { export async function addMemo(title: string, content: string): Promise { const now = nowLocalISO() const id = await db.memo.add({ title: title.trim(), content, created_at: now, updated_at: now }) + await commit() return { id, title: title.trim(), content, created_at: now, updated_at: now } } export async function updateMemo(id: number, title: string, content: string): Promise { await db.memo.update(id, { title: title.trim(), content, updated_at: nowLocalISO() }) + await commit() } export async function deleteMemo(id: number): Promise { await db.memo.delete(id) + await commit() } // ---------- 全局搜索 ---------- @@ -329,7 +391,7 @@ export async function searchLogItems(q: string, limit = 8): Promise<(LogItem & { if (!needle) return [] const wls = await db.work_log.toArray() const map = new Map(wls.map(w => [w.id as number, w.date])) - const all = await db.log_item.toArray() + const all = await db.table('log_item').toArray() return all .filter(it => ((it.content || '') + ' ' + (it.takeaway || '') + ' ' + (it.remark || '')).toLowerCase().includes(needle)) .sort((a, b) => (b.id as number) - (a.id as number)) @@ -365,18 +427,22 @@ export async function listTransactionsBetween(start: string, end: string): Promi export async function addTransaction(input: TransactionInput): Promise { await db.table('transaction').add({ ...input, created_at: nowLocalISO() }) + await commit() } export async function updateTransaction(id: number, input: TransactionInput): Promise { await db.table('transaction').update(id, { ...input }) + await commit() } export async function deleteTransaction(id: number): Promise { await db.table('transaction').delete(id) + await commit() } export async function setTransactionReimbursed(id: number, done: boolean): Promise { await db.table('transaction').update(id, { reimbursed: done ? 1 : 0 }) + await commit() } // ---------- 备份 ---------- @@ -385,7 +451,7 @@ export async function exportAll(): Promise { const tables = await Promise.all([ db.project.toArray(), db.work_log.toArray(), - db.log_item.toArray(), + db.table('log_item').toArray(), db.attendance.toArray(), db.weekly_note.toArray(), db.setting.toArray(), @@ -421,20 +487,24 @@ export async function importAll(jsonText: string): Promise { throw new Error('文件格式或 schema 版本不匹配') } const d = parsed.data - await db.transaction('rw', [db.project, db.work_log, db.log_item, db.attendance, db.weekly_note, db.setting, db.memo, db.credential, db.table('transaction')], async () => { + const dl = db.table('log_item') + const dt = db.table('transaction') + await db.transaction('rw', [db.project, db.work_log, dl, db.attendance, db.weekly_note, db.setting, db.memo, db.credential, dt], async () => { await Promise.all([ - db.project.clear(), db.work_log.clear(), db.log_item.clear(), + db.project.clear(), db.work_log.clear(), dl.clear(), db.attendance.clear(), db.weekly_note.clear(), db.setting.clear(), - db.memo.clear(), db.credential.clear(), db.table('transaction').clear() + db.memo.clear(), db.credential.clear(), dt.clear() ]) if (d.project && d.project.length) await db.project.bulkAdd(d.project as never[]) if (d.work_log && d.work_log.length) await db.work_log.bulkAdd(d.work_log as never[]) - if (d.log_item && d.log_item.length) await db.log_item.bulkAdd(d.log_item as never[]) + if (d.log_item && d.log_item.length) await dl.bulkAdd(d.log_item as never[]) if (d.attendance && d.attendance.length) await db.attendance.bulkAdd(d.attendance as never[]) if (d.weekly_note && d.weekly_note.length) await db.weekly_note.bulkAdd(d.weekly_note as never[]) if (d.setting && d.setting.length) await db.setting.bulkAdd(d.setting as never[]) if (d.memo && d.memo.length) await db.memo.bulkAdd(d.memo as never[]) if (d.credential && d.credential.length) await db.credential.bulkAdd(d.credential as never[]) - if (d.transaction && d.transaction.length) await db.table('transaction').bulkAdd(d.transaction as never[]) + if (d.transaction && d.transaction.length) await dt.bulkAdd(d.transaction as never[]) }) + // 导入即推送:以导入内容覆盖服务器(缺失行自动生成墓碑清除),随后以快照回读 + await commit() } diff --git a/intern-log/src/db/vault.ts b/intern-log/src/db/vault.ts index 64e8299..1f104ed 100644 --- a/intern-log/src/db/vault.ts +++ b/intern-log/src/db/vault.ts @@ -1,5 +1,11 @@ import { db, type Credential } from './schema' import { getSetting, setSetting } from './repo' +import { flushAfterWrite } from '../sync/engine' + +// 密码库写操作同样立即推送服务器(密文本体;主密码永不出本机) +async function commit(): Promise { + await flushAfterWrite() +} import { aesGcmDecrypt, aesGcmEncrypt, bufToB64, deriveKeyFromPassword, randomSaltB64 } from '../lib/crypto' import { nowLocalISO } from '../lib/date' @@ -88,10 +94,12 @@ export async function saveCredential(input: CredentialInput, id?: number): Promi } else { await db.credential.add({ ...base, created_at: nowLocalISO(), updated_at: nowLocalISO() }) } + await commit() } export async function deleteCredential(id: number): Promise { await db.credential.delete(id) + await commit() } export async function revealCredentialPassword(id: number): Promise { @@ -127,6 +135,7 @@ export async function changeMasterPassword(oldPwd: string, newPwd: string): Prom } await setSetting('pwd_verifier', await aesGcmEncrypt(newKey, VERIFY_TEXT)) masterKey = newKey + await commit() return count } diff --git a/intern-log/src/lib/server.ts b/intern-log/src/lib/server.ts new file mode 100644 index 0000000..745f0d8 --- /dev/null +++ b/intern-log/src/lib/server.ts @@ -0,0 +1,40 @@ +// 服务器访问基础层:同步服务地址与登录令牌的本地持久化 +// 这些信息必须保存在本地(登录前就需要知道服务器地址),不属于业务数据,不参与同步 +export const DEFAULT_SYNC_BASE = 'https://daywk.linyux.cn' + +const BASE_KEY = 'dsh_sync_base' +const TOKEN_KEY = 'dsh_sync_token' + +function lsGet(key: string): string { + try { return localStorage.getItem(key) || '' } catch { return '' } +} +function lsSet(key: string, value: string): void { + try { localStorage.setItem(key, value) } catch { /* 隐私模式忽略 */ } +} +function lsDel(key: string): void { + try { localStorage.removeItem(key) } catch { /* 忽略 */ } +} + +export async function getSyncBase(): Promise { + return lsGet(BASE_KEY) || DEFAULT_SYNC_BASE +} + +export async function setSyncBaseOverride(value: string): Promise { + const v = (value || '').trim().replace(/\/+$/, '') + if (v && v !== DEFAULT_SYNC_BASE) lsSet(BASE_KEY, v) + else lsDel(BASE_KEY) +} + +export function getToken(): string { + const raw = lsGet(TOKEN_KEY) + if (!raw) return '' + try { + // 令牌形如 payload.sig;过期由服务端判断,401 时上层负责重登 + return raw + } catch { return '' } +} + +export function setToken(token: string): void { + if (token) lsSet(TOKEN_KEY, token) + else lsDel(TOKEN_KEY) +} diff --git a/intern-log/src/main.ts b/intern-log/src/main.ts index 5092ec1..8e29503 100644 --- a/intern-log/src/main.ts +++ b/intern-log/src/main.ts @@ -2,34 +2,41 @@ import { createApp } from 'vue' import App from './App.vue' import './styles/tokens.css' import { showFatalError } from './lib/errOverlay' -import { getSession, openUserDatabase } from './db/auth' +import { bootstrapSession, openUserDatabase } from './db/auth' -// 持久会话恢复:必须在任何视图挂载并读取数据之前绑定用户数据库 -const restoredSession = getSession() -if (restoredSession) openUserDatabase(restoredSession.userId) +// 纯在线模式:启动时先静默登录换取云端会话,再绑定本地缓存库并挂载应用 +async function boot(): Promise { + const session = await bootstrapSession() + if (session) openUserDatabase(session.userId) -const app = createApp(App) + const app = createApp(App) -// 捕获所有会导致白屏的渲染与运行错误,转为屏幕上的错误报告 -app.config.errorHandler = (err, _inst, info) => { - const e = err as Error - showFatalError('应用内部错误(点击空白处关闭,请将以下内容发送给开发者)', (e && (e.stack || e.message)) || String(err) + '\n触发位置: ' + info) -} -window.addEventListener('unhandledrejection', e => { - const reason = e.reason as Error - showFatalError('未处理的异步错误(点击空白处关闭)', (reason && (reason.stack || reason.message)) || String(e.reason)) -}) -window.addEventListener('error', e => { - if (e.message && e.message !== 'ResizeObserver loop limit exceeded') { - showFatalError('运行错误(点击空白处关闭)', e.message) + // 捕获所有会导致白屏的渲染与运行错误,转为屏幕上的错误报告 + app.config.errorHandler = (err, _inst, info) => { + const e = err as Error + showFatalError('应用内部错误(点击空白处关闭,请将以下内容发送给开发者)', (e && (e.stack || e.message)) || String(err) + '\n触发位置: ' + info) } -}) - -app.mount('#app') - -// PWA:注册 Service Worker,安装为应用后可离线使用 -if ('serviceWorker' in navigator && location.protocol.startsWith('http')) { - window.addEventListener('load', () => { - navigator.serviceWorker.register('sw.js').catch(() => { /* 注册失败不影响正常使用 */ }) + window.addEventListener('unhandledrejection', e => { + const reason = e.reason as Error + showFatalError('未处理的异步错误(点击空白处关闭)', (reason && (reason.stack || reason.message)) || String(e.reason)) }) + window.addEventListener('error', e => { + if (e.message && e.message !== 'ResizeObserver loop limit exceeded') { + showFatalError('运行错误(点击空白处关闭)', e.message) + } + }) + + app.mount('#app') + + // PWA:注册 Service Worker,安装为应用后可离线使用(数据在服务器,仅缓存) + if ('serviceWorker' in navigator && location.protocol.startsWith('http')) { + window.addEventListener('load', () => { + navigator.serviceWorker.register('sw.js').catch(() => { /* 注册失败不影响正常使用 */ }) + }) + } } + +boot().catch(e => { + // 服务器不可达等启动失败:明确提示(纯在线模式下无法绕过服务器) + showFatalError('无法启动:连接同步服务器失败', (e && (e.stack || e.message)) || String(e)) +}) diff --git a/intern-log/src/sync/engine.ts b/intern-log/src/sync/engine.ts index de2308f..cc5fb4f 100644 --- a/intern-log/src/sync/engine.ts +++ b/intern-log/src/sync/engine.ts @@ -1,22 +1,24 @@ -// 多端同步引擎:全量差异对比 + 记录级新者胜 + 自然键去重 + 外键重映射 + 软删除墓碑 -// 实时性:本地变更 3 秒内推送;服务端变更通过 SSE 秒级通知其他端;60 秒轮询兜底 +// 同步引擎:服务器是唯一数据权威,本机只是实时缓存。 +// 写路径:界面修改本地缓存 → 立即把差异推给服务器 → 服务器返回权威快照 → 本地缓存全量重建 +// 读路径:启动 / SSE 通知 / 60 秒兜底 / 任何写操作之后 → 全量刷新 +// 因此本地与服务器的数据永远强一致:没有合并、没有冲突收敛、没有双端分歧。 import { ref } from 'vue' import Dexie, { liveQuery } from 'dexie' import { db } from '../db/schema' -import { getSetting, setSetting } from '../db/repo' import { getCloudCreds } from '../db/auth' import { nowLocalISO } from '../lib/date' import { notifyAttendanceChanged } from '../lib/bus' +import { DEFAULT_SYNC_BASE, getSyncBase as baseOf, getToken, setToken, setSyncBaseOverride } from '../lib/server' // 最近一次自动同步的错误(设置页展示用) export const syncLastError = ref('') const TABLES = ['project', 'work_log', 'log_item', 'attendance', 'weekly_note', 'setting', 'memo', 'credential', 'transaction'] -// 本地敏感或临时性的设置不参与同步 +// 本地临时性键不参与同步,也不能从服务端写回本地缓存 const EXCLUDE_SETTING_KEYS = new Set(['sync_cursor', 'sync_last_time', 'sync_token', 'last_project', 'last_category']) -// 自然键:同一逻辑记录在两台设备上独立创建时的去重依据(冲突时保留 updated_at 较新者) +// 自然键:同一逻辑记录在并发写入时的服务端去重依据(保留 updated_at 较新者) const NATURAL_KEYS: Record = { project: 'name', work_log: 'date', @@ -26,23 +28,11 @@ const NATURAL_KEYS: Record = { } export const SYNC_TABLES = TABLES +export { DEFAULT_SYNC_BASE, setSyncBaseOverride } +export const getSyncBase = baseOf interface AnyRow { [key: string]: any } -function newUuid(): string { - if (typeof crypto !== 'undefined' && crypto.randomUUID) return crypto.randomUUID() - return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => { - const r = (Math.random() * 16) | 0 - return (c === 'x' ? r : (r & 0x3) | 0x8).toString(16) - }) -} - -function stripId(row: AnyRow): AnyRow { - const copy: AnyRow = { ...row } - delete copy.id - return copy -} - function rowHash(row: AnyRow): string { return JSON.stringify(row) } @@ -56,7 +46,7 @@ function pkOf(t: string, row: AnyRow): any { return t === 'setting' ? row.key : row.id } -// 一次性补齐 uuid 与 updated_at,缺失时回填 +// 一次性补齐 uuid 与 updated_at,缺失时回填(写路径入口先生效,快照兜底) async function ensureSyncFields(): Promise { for (const t of TABLES) { const table = db.table(t) @@ -64,13 +54,18 @@ async function ensureSyncFields(): Promise { for (const row of rows) { if (t === 'setting' && EXCLUDE_SETTING_KEYS.has(row.key)) continue const patch: AnyRow = {} - if (!row.uuid) patch.uuid = newUuid() - if (!row.updated_at) patch.updated_at = row.created_at || nowLocalISO() + if (!row.uuid) patch.uuid = genUuid() + if (!row.updated_at && row.created_at) patch.updated_at = row.created_at if (Object.keys(patch).length) await table.update(pkOf(t, row), patch) } } } +function genUuid(): string { + if (typeof crypto !== 'undefined' && crypto.randomUUID) return crypto.randomUUID() + return 'u' + Date.now().toString(36) + Math.random().toString(36).slice(2, 10) +} + export interface SyncResult { pushed: number pulled: number @@ -90,7 +85,11 @@ export async function isSyncConfigured(): Promise { } export async function getSyncLastTime(): Promise { - return getSetting('sync_last_time', '') + try { return localStorage.getItem('dsh_last_sync') || '' } catch { return '' } +} + +async function putSyncLastTime(at: string): Promise { + try { localStorage.setItem('dsh_last_sync', at) } catch { /* 忽略 */ } } // 云端账号注册(服务端存 PBKDF2 哈希) @@ -128,101 +127,24 @@ async function loginCloud(base: string, config: SyncConfig): Promise { } async function ensureToken(base: string, config: SyncConfig): Promise { - let token = await getSetting('sync_token', '') + let token = getToken() if (token) return token token = await loginCloud(base, config) - await setSetting('sync_token', token) + setToken(token) return token } -// ---------- 并发保护与实时触发 ---------- - -let syncRunning = false -let pendingSync = false -let changesSuppressed = false -let changeDebounce: number | null = null -let sse: EventSource | null = null -let sseKey = '' -let realtimeAttached = false -let realtimeSub: { unsubscribe: () => void } | null = null - -export async function autoSyncNow(): Promise { - if (syncRunning) { - pendingSync = true - return - } - try { - if (!(await isSyncConfigured())) return - await runSync(await loadSyncConfig()) - syncLastError.value = '' - } catch (e) { - syncLastError.value = e instanceof Error ? e.message : String(e) - } -} - -// 实时触发:本地任何数据变更 3 秒后自动推送(Dexie 4 核心 liveQuery,跨全部业务表) -export function enableRealtimeSync(): void { - if (realtimeAttached) return - realtimeAttached = true - const sub = liveQuery(async () => { - const counts: Record = {} - for (const t of TABLES) counts[t] = await db.table(t).count() - return counts - }) - realtimeSub = sub.subscribe({ - next: () => { - if (changesSuppressed || syncRunning) return - if (changeDebounce) globalThis.clearTimeout(changeDebounce) - changeDebounce = globalThis.setTimeout(() => { void autoSyncNow() }, 3000) - }, - error: () => { /* 忽略监听错误,轮询兜底 */ } - }) -} - -export function stopRealtime(): void { - if (realtimeSub) { realtimeSub.unsubscribe(); realtimeSub = null } - if (sse) { sse.close(); sse = null; sseKey = '' } - if (changeDebounce) { globalThis.clearTimeout(changeDebounce); changeDebounce = null } -} - -// 服务端 SSE 通知:其他端有变更时立即拉取 -function ensureSSE(base: string, token: string): void { - const key = base + '|' + token - if (sse && sseKey === key) return - if (sse) { sse.close(); sse = null } - try { - sse = new EventSource(base + '/api/events?token=' + encodeURIComponent(token)) - sseKey = key - sse.onmessage = () => { void autoSyncNow() } - } catch { sse = null } -} - -// 同步基址:设置页可覆盖,默认使用独立子域名 -export async function getSyncBase(): Promise { - return (await getSetting('sync_base_url', '')) || DEFAULT_SYNC_BASE -} -export const DEFAULT_SYNC_BASE = 'https://daywk.linyux.cn' - -async function loadSyncConfig(): Promise { - const creds = getCloudCreds() - if (!creds) throw new Error('未登录,无法同步') - return { baseUrl: await getSyncBase(), username: creds.username, password: creds.password } -} - -// 登录后自动绑定云端账号:云端不存在则注册,同名则校验密码一致 +// 登录后自动绑定云端账号:云端存在则校验密码一致(同用户名即同一数据集) export async function ensureCloudBinding(): Promise { const creds = getCloudCreds() if (!creds) throw new Error('未登录') - const base = await getSyncBase() - const headers = { 'Content-Type': 'application/json' } - const body = JSON.stringify({ username: creds.username, password: creds.password }) - let resp = await fetch(base + '/api/auth/register', { method: 'POST', headers, body }) - if (resp.status === 409) { - resp = await fetch(base + '/api/auth/login', { method: 'POST', headers, body }) - if (!resp.ok) throw new Error('云端已存在同名账号且密码不一致,请检查') - } else if (!resp.ok) { - throw new Error('云端绑定失败:' + resp.status) - } + const base = await baseOf() + const resp = await fetch(base + '/api/auth/login', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ username: creds.username, password: creds.password }) + }) + if (!resp.ok) throw new Error('云端账号校验失败:' + resp.status) } export function getCloudUser(): string | null { @@ -230,9 +152,22 @@ export function getCloudUser(): string | null { return c ? c.username : null } -// 使用当前登录凭据执行同步(供设置页与自动同步调用) +// 使用当前登录凭据执行同步(设置页与写后推送共用) export async function syncWithStoredConfig(): Promise { - return runSync(await loadSyncConfig()) + const creds = getCloudCreds() + if (!creds) throw new Error('未登录,无法同步') + return runSync({ baseUrl: await baseOf(), username: creds.username, password: creds.password }) +} + +// 界面写操作完成后调用:立即推送差异并以服务器快照重建缓存(失败会把缓存回退到服务器真值) +export async function flushAfterWrite(): Promise { + try { + await syncWithStoredConfig() + } catch (e) { + syncLastError.value = e instanceof Error ? e.message : String(e) + try { await syncWithStoredConfig() } catch { /* 服务器不可达:本地暂存修改,下次自动推送或全量刷新时对齐 */ } + throw e + } } // ---------- 推送规范化:剥离本地 id,外键转换为 uuid 引用 ---------- @@ -270,8 +205,72 @@ async function buildRefMaps(): Promise { // ---------- 执行同步 ---------- -let applyErrors = 0 -let lastApplyError = '' +let syncRunning = false +let pendingSync = false +let changesSuppressed = false +let changeDebounce: number | null = null +let sse: EventSource | null = null +let sseKey = '' +let realtimeAttached = false +let realtimeSub: { unsubscribe: () => void } | null = null + +export async function autoSyncNow(): Promise { + if (syncRunning) { + pendingSync = true + return + } + try { + if (!(await isSyncConfigured())) return + await runSync(await configOf()) + syncLastError.value = '' + } catch (e) { + syncLastError.value = e instanceof Error ? e.message : String(e) + } +} + +async function configOf(): Promise { + const creds = getCloudCreds() + if (!creds) throw new Error('未登录,无法同步') + return { baseUrl: await baseOf(), username: creds.username, password: creds.password } +} + +// 实时触发:本地任何数据变更 3 秒内推送(Dexie 4 liveQuery,跨全部业务表) +export function enableRealtimeSync(): void { + if (realtimeAttached) return + realtimeAttached = true + const sub = liveQuery(async () => { + const counts: Record = {} + for (const t of TABLES) counts[t] = await db.table(t).count() + return counts + }) + realtimeSub = sub.subscribe({ + next: () => { + if (changesSuppressed || syncRunning) return + if (changeDebounce) globalThis.clearTimeout(changeDebounce) + changeDebounce = globalThis.setTimeout(() => { void autoSyncNow() }, 3000) + }, + error: () => { /* 忽略监听错误,轮询兜底 */ } + }) +} + +export function stopRealtime(): void { + if (realtimeSub) { realtimeSub.unsubscribe(); realtimeSub = null } + if (sse) { sse.close(); sse = null; sseKey = '' } + if (changeDebounce) { globalThis.clearTimeout(changeDebounce); changeDebounce = null } + realtimeAttached = false +} + +// 服务端 SSE 通知:其他端有变更时立即刷新(服务端广播 change 即表示权威数据有变化) +function ensureSSE(base: string, token: string): void { + const key = base + '|' + token + if (sse && sseKey === key) return + if (sse) { sse.close(); sse = null } + try { + sse = new EventSource(base + '/api/events?token=' + encodeURIComponent(token)) + sseKey = key + sse.onmessage = () => { void autoSyncNow() } + } catch { sse = null } +} export async function runSync(config: SyncConfig): Promise { if (syncRunning) { @@ -280,8 +279,6 @@ export async function runSync(config: SyncConfig): Promise { } syncRunning = true changesSuppressed = true - applyErrors = 0 - lastApplyError = '' try { const result = await doRunSync(config) if (pendingSync) { @@ -301,7 +298,7 @@ async function doRunSync(config: SyncConfig): Promise { await ensureSyncFields() const refs = await buildRefMaps() - // 1. 载入镜像,计算本地差异(推送内容按规范化形式比对) + // 1. 载入镜像,计算本地与服务器权威数据的差异(推送内容按规范化形式比对) const mirrorRows = await db.sync_mirror.toArray() const mirror = new Map() for (const m of mirrorRows) mirror.set(m.table + '|' + m.uuid, m) @@ -334,11 +331,8 @@ async function doRunSync(config: SyncConfig): Promise { pushTables[t] = pushTables[t] || [] } - // 本地待推送的删除墓碑 - const localTombs = await db.tombstone.toArray() - for (const tb of localTombs) { - tombstones.push({ table: tb.table, uuid: tb.uuid, deleted_at: tb.deleted_at }) - } + // 服务端残留临时键的清理墓碑(如早前同步上去的 sync_token 等) + tombstones.push(...drainServerCleanup()) // 2. 认证并与服务端交换(token 失效自动重登一次) const token = await ensureToken(base, config) @@ -349,9 +343,9 @@ async function doRunSync(config: SyncConfig): Promise { }) let resp = await doPush(token) if (resp.status === 401) { - await setSetting('sync_token', '') + setToken('') const token2 = await loginCloud(base, config) - await setSetting('sync_token', token2) + setToken(token2) resp = await doPush(token2) } if (!resp.ok) throw new Error('同步服务返回 ' + resp.status) @@ -359,160 +353,147 @@ async function doRunSync(config: SyncConfig): Promise { const serverTables: Record = data.tables || {} const serverTombstones: { table: string; uuid: string; deleted_at: string }[] = data.tombstones || [] - // 3. 应用服务端权威数据 - const applyResult = await applyServerTables(serverTables, serverTombstones) + // 3. 用服务器快照全量重建本地缓存(本地不再有映射逻辑,服务器永远是对的) + const applyResult = await applySnapshot(serverTables, serverTombstones) - // 4. 重建镜像 + 建立 SSE 实时通道 + 广播考勤变更 - const refsNow = await buildRefMaps() + // 4. 建立 SSE 实时通道 + 记录同步时间 + 广播考勤变更 + ensureSSE(base, getToken() || token) + const at = nowLocalISO() + await putSyncLastTime(at) + if (applyResult.changed > 0 || applyResult.removed > 0 || pushed > 0) notifyAttendanceChanged() + return { pushed, pulled: applyResult.changed, removed: applyResult.removed, errors: 0, at } +} + +// ---------- 快照重建:清空重灌 + 稳定本地 id(uuid -> id 映射保存在本地) ---------- + +interface IdMap { [table: string]: { [uuid: string]: number } } + +function idMapKey(): string { + const user = getCloudCreds()?.username || 'anon' + return 'dsh_idmap_' + user +} + +function loadIdMap(): IdMap { + try { + const raw = localStorage.getItem(idMapKey()) + if (raw) return JSON.parse(raw) as IdMap + } catch { /* 忽略 */ } + return {} +} + +function saveIdMap(map: IdMap): void { + try { localStorage.setItem(idMapKey(), JSON.stringify(map)) } catch { /* 忽略 */ } +} + +async function applySnapshot( + serverTables: Record, + serverTombstones: { table: string; uuid: string; deleted_at: string }[] +): Promise<{ changed: number; removed: number }> { + const idMap = loadIdMap() + const dead = new Set(serverTombstones.map(x => x.table + '|' + x.uuid)) + const mirrorNow = new Map() + for (const m of await db.sync_mirror.toArray()) mirrorNow.set(m.table + '|' + m.uuid, m) + const mirrorUuids = new Set(Array.from(mirrorNow.keys()).map(k => k.split('|')[1])) + let changed = 0 + let removed = 0 + const wlIds: { [uuid: string]: number } = {} + const pjIds: { [uuid: string]: number } = {} + + for (const t of TABLES) { + const table = db.table(t) + const prevRows: AnyRow[] = await table.toArray() + const prevById = new Map(prevRows.map(r => [pkOf(t, r), r])) + const prevByUuid = new Map(prevRows.filter(r => r.uuid).map(r => [r.uuid as string, r])) + + const live: AnyRow[] = (serverTables[t] || []).filter(r => !dead.has(t + '|' + r.uuid)) + // 设置表的临时键:不写回本地缓存;顺手在服务端也清掉(下一轮推送墓碑) + const filtered = live.filter(r => !(t === 'setting' && EXCLUDE_SETTING_KEYS.has(r.key))) + const tmpKeys = live.filter(r => t === 'setting' && EXCLUDE_SETTING_KEYS.has(r.key)) + for (const r of tmpKeys) tombstoneLater(t, r.uuid) + + // 在途写入保护:本次界面写操作尚未推送完成时,快照重建不得抹掉这些行 + const inflight = t === 'setting' + ? [] + : prevRows.filter(r => r.uuid && !mirrorUuids.has(r.uuid) && !dead.has(t + '|' + r.uuid)) + void inflight + + // 本地 id:优先沿用既有映射,保证视图引用稳定 + const nextId = { v: Math.max(0, ...prevRows.map(r => Number(r.id) || 0)) } + const importance = filtered.length + const hydrated: AnyRow[] = [] + for (const srow0 of filtered) { + const srow = { ...srow0 } + if (t === 'log_item') { + const wlId = srow.wuuid ? wlIds[srow.wuuid] : undefined + if (!wlId) continue + srow.work_log_id = wlId + delete srow.wuuid + srow.project_id = srow.puuid ? (pjIds[srow.puuid] ?? null) : null + delete srow.puuid + } + let id: any = pkOf(t, srow0) + if (t === 'setting') id = srow0.key + else { + const byUuid = idMap[t] && idMap[t][srow0.uuid] + const prevRow = prevByUuid.get(srow0.uuid) + if (prevRow && prevRow.id != null) id = prevRow.id + else if (typeof byUuid === 'number') id = byUuid + else id = ++nextId.v + } + const rowOut: AnyRow = { ...srow, id } + if (t === 'setting' && EXCLUDE_SETTING_KEYS.has(rowOut.key)) continue + hydrated.push(rowOut) + if (t === 'work_log') wlIds[srow0.uuid] = id + if (t === 'project') pjIds[srow0.uuid] = id + } + void importance + const outRows = hydrated.concat(inflight) + + // 增删差异统计:内容或 id 变化都算变更 + for (const r of outRows) { + const p = prevById.get(pkOf(t, r)) + if (!p || rowHash(p) !== rowHash(r)) changed++ + } + removed += prevRows.filter(r => r.uuid && !hydrated.some(x => x.uuid === r.uuid) && !dead.has(t + '|' + r.uuid)).length + + // 全量重建:先清空后批量写入;在途行粘回缓存(它们会在随后的推送中上 JOIN 服务器) + await table.clear() + if (outRows.length) await table.bulkPut(outRows) + + // 更新 uuid -> id 映射 + const m2: { [uuid: string]: number } = {} + for (const r of outRows) { if (r.uuid) m2[r.uuid] = r.id } + idMap[t] = m2 + } + + saveIdMap(idMap) + + // 清理镜像与本地墓碑(快照重建后镜像直接按快照重建) + const refs = await buildRefMaps() const finalMirror: { table: string; uuid: string; hash: string }[] = [] for (const t of TABLES) { const rows: AnyRow[] = await db.table(t).toArray() for (const row of rows) { if (t === 'setting' && EXCLUDE_SETTING_KEYS.has(row.key)) continue - finalMirror.push({ table: t, uuid: row.uuid, hash: rowHash(normalizeRow(t, row, refsNow)) }) + if (!row.uuid) continue + finalMirror.push({ table: t, uuid: row.uuid, hash: rowHash(normalizeRow(t, row, refs)) }) } } await db.sync_mirror.clear() if (finalMirror.length) await db.sync_mirror.bulkAdd(finalMirror.map(m => ({ ...m }))) - ensureSSE(base, token) - const at = nowLocalISO() - await setSetting('sync_last_time', at) - if (applyResult.pulled > 0 || applyResult.removed > 0) notifyAttendanceChanged() - // 清除已确认推送的本地墓碑(保留本轮新产生的去重墓碑) - if (localTombs.length) { - const pushedIds = new Set(localTombs.map(t => t.id)) - await db.tombstone.where('id').anyOf(Array.from(pushedIds)).delete() - } - return { pushed, pulled: applyResult.pulled, removed: applyResult.removed, errors: applyResult.errors, at } + await db.tombstone.clear() + return { changed, removed: removed + pendingTombstones.length } } -// ---------- 应用服务端数据(含自然键去重与外键重映射) ---------- - -let localWorkLogIdByUuid = new Map() -let localProjectIdByUuid = new Map() -let applyConflicts = 0 - -async function applyServerTables( - serverTables: Record, - serverTombstones: { table: string; uuid: string; deleted_at: string }[] -): Promise<{ pulled: number; removed: number; errors: number }> { - let pulled = 0 - let removed = 0 - - for (const t of TABLES) { - const table = db.table(t) - const localRows: AnyRow[] = await table.toArray() - const byUuid = new Map() - for (const row of localRows) byUuid.set(row.uuid, row) - const nk = NATURAL_KEYS[t] || null - const byNatural = new Map() - if (nk) { - for (const row of localRows) { - const v = row[nk] - if (v != null && v !== '') byNatural.set(String(v), row) - } - } - - const dead = new Set(serverTombstones.filter(x => x.table === t).map(x => x.uuid)) - const serverRows: AnyRow[] = serverTables[t] || [] - - // 阶段一:应用未删除行的增改 - for (const srow of serverRows) { - try { - if (dead.has(srow.uuid)) continue - const local = byUuid.get(srow.uuid) - if (local) { - const localUa = String(local.updated_at || '') - const serverUa = String(srow.updated_at || '') - if (serverUa > localUa) { - const patch: AnyRow = { ...srow } - if (t === 'setting') delete patch.key - if (t === 'log_item') { - const wlId = srow.wuuid ? localWorkLogIdByUuid.get(srow.wuuid) : null - if (!wlId) continue - patch.work_log_id = wlId - delete patch.wuuid - patch.project_id = srow.puuid ? (localProjectIdByUuid.get(srow.puuid) ?? null) : (local.project_id ?? null) - delete patch.puuid - } - await table.update(local.id, patch) - pulled++ - } - } else { - const nkVal = nk && srow[nk] != null && srow[nk] !== '' ? String(srow[nk]) : null - const dup = nkVal ? byNatural.get(nkVal) : undefined - if (dup && dup.uuid !== srow.uuid) { - const dupUa = String(dup.updated_at || '') - const serverUa = String(srow.updated_at || '') - if (serverUa >= dupUa) { - // 服务端较新:先迁移关联数据,删除本地重复行,写入服务端行 - if (t === 'work_log') { - await db.log_item.where('work_log_id').equals(dup.id as number).modify({ work_log_id: -1 }) - } - await table.delete(pkOf(t, dup)) - await db.tombstone.add({ table: t, uuid: dup.uuid, deleted_at: nowLocalISO() }) - const newId = await table.add({ ...srow }) - if (t === 'work_log') { - await db.log_item.where('work_log_id').equals(-1).modify({ work_log_id: newId }) - } - byUuid.set(srow.uuid, { ...srow, id: newId }) - if (nk && nkVal) byNatural.set(nkVal, { ...srow, id: newId }) - pulled++ - } else { - // 本地较新:跳过服务端行,记墓碑待下次推送清除服务端副本 - await db.tombstone.add({ table: t, uuid: srow.uuid, deleted_at: nowLocalISO() }) - applyConflicts++ - } - } else { - if (t === 'log_item') { - const wlId = srow.wuuid ? localWorkLogIdByUuid.get(srow.wuuid) : null - if (!wlId) continue - srow.work_log_id = wlId - delete srow.wuuid - srow.project_id = srow.puuid ? (localProjectIdByUuid.get(srow.puuid) ?? null) : null - delete srow.puuid - } - const newId = await table.add({ ...srow }) - byUuid.set(srow.uuid, { ...srow, id: newId }) - if (nk && nkVal) byNatural.set(nkVal, { ...srow, id: newId }) - pulled++ - } - } - } catch (err) { - applyErrors++ - lastApplyError = err instanceof Error ? err.message : String(err) - } - } - - // 阶段二:应用墓碑删除(work_log 删除时把本地条目迁移到同日幸存者) - for (const row of localRows) { - if (!dead.has(row.uuid)) continue - try { - if (t === 'work_log') { - const freshRows: AnyRow[] = await table.toArray() - const survivor = freshRows.find(r2 => r2.date === row.date && !dead.has(r2.uuid) && r2.uuid !== row.uuid) - if (survivor && row.id) { - await db.log_item.where('work_log_id').equals(row.id as number).modify({ work_log_id: survivor.id as number }) - } - } - await table.delete(pkOf(t, row)) - removed++ - } catch (err) { - applyErrors++ - } - } - - // 外键重映射表:work_log 与 project 处理完成后构建 - if (t === 'work_log') { - const fresh: AnyRow[] = await table.toArray() - localWorkLogIdByUuid = new Map(fresh.map(r => [r.uuid as string, r.id as number])) - } - if (t === 'project') { - const fresh: AnyRow[] = await table.toArray() - localProjectIdByUuid = new Map(fresh.map(r => [r.uuid as string, r.id as number])) - } +// 服务端不应存在的临时设置键:推墓碑到服务端做一次清理 +const pendingTombstones: { table: string; uuid: string; deleted_at: string }[] = [] +function tombstoneLater(t: string, uuid: string): void { + if (!pendingTombstones.some(x => x.table === t && x.uuid === uuid)) { + pendingTombstones.push({ table: t, uuid, deleted_at: nowLocalISO() }) } - void lastApplyError - void applyConflicts - return { pulled, removed, errors: applyErrors } +} + +// 每轮推送时把待清理的临时键墓碑捎带上去 +export function drainServerCleanup(): { table: string; uuid: string; deleted_at: string }[] { + return pendingTombstones.splice(0) } diff --git a/intern-log/src/views/LoginView.vue b/intern-log/src/views/LoginView.vue index 1d2abd4..7ac94d8 100644 --- a/intern-log/src/views/LoginView.vue +++ b/intern-log/src/views/LoginView.vue @@ -1,7 +1,7 @@