import{a as ge,g as he}from"./vendor-utils-B_Y_1aLs.js";import{n as d,ai as Se,s as B}from"./index-BxeI5EAR.js";import{i as j,t as x,g as q}from"./serverRotation-J4OEk8av.js";const J=(e,t)=>t.some(r=>e instanceof r);let Y,ee;function pe(){return Y||(Y=[IDBDatabase,IDBObjectStore,IDBIndex,IDBCursor,IDBTransaction])}function De(){return ee||(ee=[IDBCursor.prototype.advance,IDBCursor.prototype.continue,IDBCursor.prototype.continuePrimaryKey])}const M=new WeakMap,P=new WeakMap,K=new WeakMap;function be(e){const t=new Promise((r,n)=>{const s=()=>{e.removeEventListener("success",a),e.removeEventListener("error",o)},a=()=>{r(O(e.result)),s()},o=()=>{n(e.error),s()};e.addEventListener("success",a),e.addEventListener("error",o)});return K.set(t,e),t}function ke(e){if(M.has(e))return;const t=new Promise((r,n)=>{const s=()=>{e.removeEventListener("complete",a),e.removeEventListener("error",o),e.removeEventListener("abort",o)},a=()=>{r(),s()},o=()=>{n(e.error||new DOMException("AbortError","AbortError")),s()};e.addEventListener("complete",a),e.addEventListener("error",o),e.addEventListener("abort",o)});M.set(e,t)}let W={get(e,t,r){if(e instanceof IDBTransaction){if(t==="done")return M.get(e);if(t==="store")return r.objectStoreNames[1]?void 0:r.objectStore(r.objectStoreNames[0])}return O(e[t])},set(e,t,r){return e[t]=r,!0},has(e,t){return e instanceof IDBTransaction&&(t==="done"||t==="store")?!0:t in e}};function ie(e){W=e(W)}function Ee(e){return De().includes(e)?function(...t){return e.apply(H(this),t),O(this.request)}:function(...t){return O(e.apply(H(this),t))}}function Ie(e){return typeof e=="function"?Ee(e):(e instanceof IDBTransaction&&ke(e),J(e,pe())?new Proxy(e,W):e)}function O(e){if(e instanceof IDBRequest)return be(e);if(P.has(e))return P.get(e);const t=Ie(e);return t!==e&&(P.set(e,t),K.set(t,e)),t}const H=e=>K.get(e);function ue(e,t,{blocked:r,upgrade:n,blocking:s,terminated:a}={}){const o=indexedDB.open(e,t),i=O(o);return n&&o.addEventListener("upgradeneeded",c=>{n(O(o.result),c.oldVersion,c.newVersion,O(o.transaction),c)}),r&&o.addEventListener("blocked",c=>r(c.oldVersion,c.newVersion,c)),i.then(c=>{a&&c.addEventListener("close",()=>a()),s&&c.addEventListener("versionchange",u=>s(u.oldVersion,u.newVersion,u))}).catch(()=>{}),i}const Ne=["get","getKey","getAll","getAllKeys","count"],Oe=["put","add","delete","clear"],F=new Map;function te(e,t){if(!(e instanceof IDBDatabase&&!(t in e)&&typeof t=="string"))return;if(F.get(t))return F.get(t);const r=t.replace(/FromIndex$/,""),n=t!==r,s=Oe.includes(r);if(!(r in(n?IDBIndex:IDBObjectStore).prototype)||!(s||Ne.includes(r)))return;const a=async function(o,...i){const c=this.transaction(o,s?"readwrite":"readonly");let u=c.store;return n&&(u=u.index(i.shift())),(await Promise.all([u[r](...i),s&&c.done]))[0]};return F.set(t,a),a}ie(e=>({...e,get:(t,r,n)=>te(t,r)||e.get(t,r,n),has:(t,r)=>!!te(t,r)||e.has(t,r)}));const Te=["continue","continuePrimaryKey","advance"],re={},z=new WeakMap,de=new WeakMap,Re={get(e,t){if(!Te.includes(t))return e[t];let r=re[t];return r||(r=re[t]=function(...n){z.set(this,de.get(this)[t](...n))}),r}};async function*_e(...e){let t=this;if(t instanceof IDBCursor||(t=await t.openCursor(...e)),!t)return;t=t;const r=new Proxy(t,Re);for(de.set(r,t),K.set(r,H(t));t;)yield r,t=await(z.get(r)||t.continue()),z.delete(r)}function ne(e,t){return t===Symbol.asyncIterator&&J(e,[IDBIndex,IDBObjectStore,IDBCursor])||t==="iterate"&&J(e,[IDBIndex,IDBObjectStore])}ie(e=>({...e,get(t,r,n){return ne(t,r)?_e:e.get(t,r,n)},has(t,r){return ne(t,r)||e.has(t,r)}}));const je="ClassworksDB",xe=3,E=async()=>ue(je,xe,{upgrade(e){e.objectStoreNames.contains("kv")||e.createObjectStore("kv"),e.objectStoreNames.contains("system")||e.createObjectStore("system"),e.objectStoreNames.contains("syncQueue")||e.createObjectStore("syncQueue")}}),S={async loadData(e){try{const r=await(await E()).get("kv",e);return r?v(JSON.parse(r)):f("数据不存在","NOT_FOUND")}catch(t){return f("读取本地数据失败:"+t)}},async saveData(e,t){try{return await(await E()).put("kv",JSON.stringify(t),e),v(!0)}catch(r){return f("保存本地数据失败:"+r)}},async loadKeys(e={}){try{const s=await(await E()).transaction(["kv"],"readonly").objectStore("kv").getAllKeys(),{sortDir:a="asc",limit:o=100,skip:i=0}=e,c=s.sort((h,y)=>a==="desc"?y.localeCompare(h):h.localeCompare(y)),u=c.length,l=c.slice(i,i+o),g={keys:l,total_rows:u,current_page:{limit:o,skip:i,count:l.length},load_more:null};return v(g)}catch(t){return f("获取本地键名列表失败:"+t.message)}},async addToSyncQueue(e){try{return await(await E()).put("syncQueue",JSON.stringify(e),e.key),v(!0)}catch(t){return f("添加同步队列失败:"+t)}},async getSyncQueue(){try{const e=await E(),t=await e.getAllKeys("syncQueue"),r=[];for(const n of t){const s=await e.get("syncQueue",n);s&&r.push(JSON.parse(s))}return r.sort((n,s)=>n.timestamp-s.timestamp),v(r)}catch(e){return f("获取同步队列失败:"+e)}},async removeFromSyncQueue(e){try{return await(await E()).delete("syncQueue",e),v(!0)}catch(t){return f("删除同步队列项失败:"+t)}},async deleteByPrefix(e){try{const r=(await E()).transaction("kv","readwrite"),n=r.objectStore("kv"),s=await n.getAllKeys();let a=0;for(const o of s)o.startsWith(e)&&(await n.delete(o),a++);return await r.done,a}catch(t){return console.warn("kvLocalProvider.deleteByPrefix 失败:",t),0}}};function Le(e,t){return"headers"in e&&typeof e.headers=="object"&&!Array.isArray(e.headers)?U(e.headers):"getHeaders"in e&&typeof e.getHeaders=="function"?U(e.getHeaders()):U(e)}function U(e,t){const r=D(e,"ratelimit");if(r)return $e(r);let n;if(D(e,"ratelimit-remaining"))n="ratelimit-";else if(D(e,"x-ratelimit-remaining"))n="x-ratelimit-";else if(D(e,"x-rate-limit-remaining"))n="x-rate-limit-";else return;const s=p(D(e,`${n}limit`)),a=p(D(e,`${n}used`))||p(D(e,`${n}observed`)),o=p(D(e,`${n}remaining`));let i;const c=D(e,`${n}reset`);switch(void 0){case"date":{i=fe(c??"");break}case"unix":{i=G(c??"");break}case"seconds":{i=le(c??"");break}case"milliseconds":{i=Be(c??"");break}default:if(c)i=Fe(c);else{const l=D(e,"retry-after");l&&(i=G(l))}}return{limit:Number.isNaN(s)?a+o:s,used:Number.isNaN(a)?s-o:a,remaining:o,reset:i}}var Ae=/limit\s*=\s*(\d+)/i,Ce=/remaining\s*=\s*(\d+)/i,Ke=/reset\s*=\s*(\d+)/i;function $e(e){var t,r,n;const s=p((t=Ae.exec(e))==null?void 0:t[1]),a=p((r=Ce.exec(e))==null?void 0:r[1]),o=p((n=Ke.exec(e))==null?void 0:n[1]),i=X(o);return{limit:s,used:s-a,remaining:a,reset:i}}function X(e){const t=new Date;return t.setSeconds(t.getSeconds()+e),t}function p(e){return typeof e=="number"?e:Number.parseInt(e??"",10)}function D(e,t){var r;if("get"in e&&typeof e.get=="function")return(r=e.get(t))!=null?r:void 0;if(t in e&&typeof e[t]=="string")return e[t]}function fe(e){return new Date(e)}function G(e){const t=p(e);return new Date(t*1e3)}function le(e){const t=p(e);return X(t)}function Be(e){const t=p(e);return X(t/1e3)}var Pe=/[a-z]/i;function Fe(e){if(Pe.test(e))return fe(e);const t=p(e);return t&&t>1e9?G(t):le(t)}const w=ge.create({timeout:1e4});w.interceptors.request.use(e=>{const t=d("server.provider");if(t==="kv-server"||t==="classworkscloud"){const r=d("server.kvToken");if(r)e.headers["x-app-token"]=r;else{const n=d("server.siteKey");n&&(e.headers["x-site-key"]=he.encode(n))}}return e},e=>(console.log(e),Promise.reject(e)));w.interceptors.response.use(e=>e,e=>{if(e.response&&e.response.status===429)try{const t=Le(e.response);t&&Se.show(t.reset,e.config.url,e.config.method.toUpperCase())}catch(t){console.error("解析限速头信息失败:",t)}return Promise.reject(e)});const nt=Object.freeze(Object.defineProperty({__proto__:null,default:w},Symbol.toStringTag,{value:"Module"})),b=()=>{const e={Accept:"application/json"},t=d("server.kvToken"),r=d("server.siteKey");return t?e["x-app-token"]=t:r&&(e["x-site-key"]=r),e},I={async loadNamespaceInfo(){var e,t;try{if(j())return await x(async s=>{const a=await w.get(`${s}/kv/_info`,{headers:b()});return v(a.data)});const r=d("server.domain"),n=await w.get(`${r}/kv/_info`,{headers:b()});return v(n.data)}catch(r){return console.error("获取命名空间信息失败:",r),f(((t=(e=r.response)==null?void 0:e.data)==null?void 0:t.message)||"获取命名空间信息失败","NAMESPACE_ERROR")}},async updateNamespaceInfo(e){var t,r;try{if(j())return await x(async a=>await w.put(`${a}/kv/_info`,e,{headers:b()}));const n=d("server.domain");return await w.put(`${n}/kv/_info`,e,{headers:b()})}catch(n){return f(((r=(t=n.response)==null?void 0:t.data)==null?void 0:r.message)||"更新命名空间信息失败","NAMESPACE_ERROR")}},async loadData(e){var t,r,n;try{if(j())return await x(async o=>{const i=await w.get(`${o}/kv/${e}`,{headers:b()});return v(i.data)});const s=d("server.domain"),a=await w.get(`${s}/kv/${e}`,{headers:b()});return v(a.data)}catch(s){return((t=s.response)==null?void 0:t.status)===404?f("数据不存在","NOT_FOUND"):(console.log(s),f(((n=(r=s.response)==null?void 0:r.data)==null?void 0:n.message)||"服务器连接失败","NETWORK_ERROR"))}},async saveData(e,t){var r,n;try{if(j())return await x(async a=>(await w.post(`${a}/kv/${e}`,t,{headers:b()}),v(!0)));const s=d("server.domain");return await w.post(`${s}/kv/${e}`,t,{headers:b()}),v(!0)}catch(s){return console.log(s),f(((n=(r=s.response)==null?void 0:r.data)==null?void 0:n.message)||"保存失败","SAVE_ERROR")}},async loadKeys(e={}){var t,r,n,s,a;try{const{sortBy:o="key",sortDir:i="asc",limit:c=100,skip:u=0}=e,l=new URLSearchParams({sortBy:o,sortDir:i,limit:c.toString(),skip:u.toString()});if(j())return await x(async y=>{const m=await w.get(`${y}/kv/_keys?${l}`,{headers:b()});return v(m.data)});const g=d("server.domain"),h=await w.get(`${g}/kv/_keys?${l}`,{headers:b()});return v(h.data)}catch(o){return((t=o.response)==null?void 0:t.status)===404?f("命名空间不存在","NOT_FOUND"):((r=o.response)==null?void 0:r.status)===403?f("无权限访问此命名空间","PERMISSION_DENIED"):((n=o.response)==null?void 0:n.status)===401?f("认证失败","UNAUTHORIZED"):(console.log(o),f(((a=(s=o.response)==null?void 0:s.data)==null?void 0:a.message)||"获取键名列表失败","NETWORK_ERROR"))}}};function T(e){return{vc:{[e]:0},ts:0,deviceId:e,_fieldTs:{},lastSyncedData:null,lastSyncedTs:0,lastSyncedVc:{[e]:0}}}function se(e,t){const r={...e.vc};return r[t]=(r[t]||0)+1,{...e,vc:r,ts:Date.now(),deviceId:t}}function Ue(e,t){const r={...e};for(const[n,s]of Object.entries(t))r[n]=Math.max(r[n]||0,s);return r}function R(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}function Ve(e,t){if(!e&&!t)return{};if(!e)return{...t};if(!t)return{...e};const r={...e};for(const[n,s]of Object.entries(t)){const a=r[n];(!a||s.ts>a.ts||s.ts===a.ts&&s.deviceIdR(r)?r.id:JSON.stringify(r);if("name"in t)return r=>R(r)?r.name:JSON.stringify(r);if("key"in t)return r=>R(r)?r.key:JSON.stringify(r)}return null}function Qe(e,t,r){const n=ae(e)||ae(r)||(c=>JSON.stringify(c)),s=new Map,a=new Map;e.forEach(c=>{const u=n(c);s.has(u)||s.set(u,c)}),r.forEach(c=>{const u=n(c);a.has(u)||a.set(u,c)});const o=[],i=new Set;for(const[c,u]of s)i.has(c)||(i.add(c),o.push(u));for(const[c,u]of a)i.has(c)||(i.add(c),o.push(u));return o}function Je(e,t,r,n){var o,i;const s={},a=new Set([...Object.keys(e),...Object.keys(r)]);for(const c of a){const u=c in e,l=c in r;if(u&&!l)s[c]=e[c];else if(!u&&l)s[c]=r[c];else{const g=((o=t._fieldTs)==null?void 0:o[c])||{ts:t.ts,deviceId:t.deviceId},h=((i=n._fieldTs)==null?void 0:i[c])||{ts:n.ts,deviceId:n.deviceId};g.ts>h.ts?s[c]=e[c]:h.ts>g.ts?s[c]=r[c]:s[c]=g.deviceId<=h.deviceId?e[c]:r[c]}}return s}function Me(e,t,r,n){const s=Ue(t.vc||{},n.vc||{}),a=Math.max(t.ts||0,n.ts||0),o=Ve(t._fieldTs,n._fieldTs);let i;return R(e)&&R(r)?i=Je(e,t,r,n):Array.isArray(e)&&Array.isArray(r)?i=Qe(e,t,r):typeof e==typeof r&&typeof e!="object"?(t.ts||0)>(n.ts||0)?i=e:(n.ts||0)>(t.ts||0)?i=r:i=(t.deviceId||"")<=(n.deviceId||"")?e:r:i=(t.ts||0)>=(n.ts||0)?e:r,{data:i,meta:{vc:s,ts:a,deviceId:a===(t.ts||0)?t.deviceId:n.deviceId,_fieldTs:o,lastSyncedData:n.lastSyncedData??t.lastSyncedData??null,lastSyncedTs:Math.max(t.lastSyncedTs||0,n.lastSyncedTs||0),lastSyncedVc:s}}}const $="_cache:",We="ClassworksDB",ye=7*24*60*60*1e3,He=[{pattern:"*",ttl:ye}];async function Z(){return ue(We,void 0,{upgrade(e){e.objectStoreNames.contains("kv")||e.createObjectStore("kv"),e.objectStoreNames.contains("system")||e.createObjectStore("system"),e.objectStoreNames.contains("syncQueue")||e.createObjectStore("syncQueue")}})}function ze(e,t){const r="^"+e.replace(/[.+^${}()|[\]\\]/g,"\\$&").replace(/\*/g,".*")+"$";return new RegExp(r).test(t)}function Ge(e){return e&&typeof e=="object"&&!("meta"in e)&&!("cacheTimestamp"in e)}function me(e){return e&&typeof e=="object"&&"meta"in e&&"cacheTimestamp"in e}function ve(e){for(const{pattern:t,ttl:r}of He)if(ze(t,e))return r;return ye}async function A(e){try{const t=await Z(),r=$+e,n=await t.get("kv",r);if(!n)return null;let s;try{s=typeof n=="string"?JSON.parse(n):n}catch{return null}if(Ge(s)){const a=d("device.uuid")||"unknown",o=T(a);o.ts=Date.now(),o.lastSyncedData=s;const i={data:s,meta:o,cacheTimestamp:Date.now(),cacheTTL:ve(e)};return await t.put("kv",JSON.stringify(i),r),{data:i.data,meta:i.meta}}return me(s)?Date.now()-s.cacheTimestamp>s.cacheTTL?(await t.delete("kv",r),null):{data:s.data,meta:s.meta}:null}catch(t){return console.warn("cacheManager.getCacheEntry 失败:",t),null}}async function N(e,t,r){try{const n=await Z(),s=$+e,a={data:t,meta:r,cacheTimestamp:Date.now(),cacheTTL:ve(e)};return await n.put("kv",JSON.stringify(a),s),!0}catch(n){return console.warn("cacheManager.setCacheEntry 失败:",n),!1}}async function we(){let e=0;try{const r=(await Z()).transaction("kv","readwrite"),n=r.objectStore("kv"),s=await n.getAllKeys();for(const a of s){if(!a.startsWith($))continue;const o=await n.get(a);if(!o)continue;let i;try{i=typeof o=="string"?JSON.parse(o):o}catch{continue}me(i)&&Date.now()-i.cacheTimestamp>i.cacheTTL&&(await n.delete(a),e++)}await r.done}catch(t){console.warn("cacheManager.cleanupExpiredEntries 失败:",t)}return e}let _=null,V=!1;async function C(e={}){var n;if(V)return{synced:0,failed:0};V=!0;let t=0,r=0;try{const s=await S.getSyncQueue();if(s.success===!1||!Array.isArray(s)||s.length===0)return{synced:0,failed:0};for(const a of s)try{const o=await I.saveData(a.key,a.data);if(o.success!==!1){if(await S.removeFromSyncQueue(a.key),a.meta){const i=d("device.uuid")||"unknown",c=await A(a.key);if(c){const u={...c.meta};u.lastSyncedData=a.data,u.lastSyncedTs=Date.now(),u.lastSyncedVc={...u.vc},await N(a.key,c.data,u)}else{const u=a.meta||T(i);u.lastSyncedData=a.data,u.lastSyncedTs=Date.now(),u.lastSyncedVc={...u.vc},await N(a.key,a.data,u)}}t++}else r++,e.silent||console.warn(`smartSync: 跳过 key=${a.key}, 服务器错误:`,(n=o.error)==null?void 0:n.message)}catch{r++;break}t>0&&we()}finally{V=!1}return!e.silent&&t>0&&console.log(`smartSync: 同步完成,成功 ${t} 条,失败 ${r} 条`),{synced:t,failed:r}}async function Xe(){try{const e=await S.getSyncQueue();if(e.success===!1||!Array.isArray(e)||e.length===0)return;C({silent:!0})}catch{}}function Ze(){_||(_=()=>C(),window.addEventListener("online",_),we(),navigator.onLine&&C())}function qe(){_&&(window.removeEventListener("online",_),_=null)}const v=e=>e,f=(e,t="UNKNOWN_ERROR")=>({success:!1,error:{code:t,message:e}});function Ye(e){return e&&e.success===!1}function oe(e){var t;return Ye(e)&&((t=e.error)==null?void 0:t.code)==="NETWORK_ERROR"}function ce(){return d("device.uuid")||"unknown"}function L(e){return e&&typeof e=="object"&&!Array.isArray(e)&&"value"in e?e.value:e}const st={init:Ze,destroy:qe,flushNow:C};function Q(){const e=d("server.provider");return e==="kv-server"||e==="classworkscloud"}const at={loadData:async e=>{if(!Q())return S.loadData(e);const t=await I.loadData(e),r=L(t);if(!oe(r)){if(r.success!==!1){const a=await A(e),o=ce();if(a){const i=L(a.data),c=JSON.stringify(i),u=JSON.stringify(r),l=JSON.stringify(L(a.meta.lastSyncedData)??null);if(u===c)return i;if(u!==l){const g=a.meta.vc||{},h=a.meta.lastSyncedVc||{};if((g[o]||0)>(h[o]||0)){const m=T("server");m.ts=Date.now();const k=Me(i,a.meta,r,m);return await N(e,k.data,k.meta),I.saveData(e,k.data),k.data}else{const m=T(o);return m.ts=Date.now(),m.lastSyncedData=r,m.lastSyncedTs=Date.now(),m.lastSyncedVc={...m.vc},await N(e,r,m),r}}else return i}else{const i=T(o);return i.ts=Date.now(),i.lastSyncedData=r,i.lastSyncedTs=Date.now(),i.lastSyncedVc={...i.vc},await N(e,r,i),r}}return r}const n=await A(e);if(n){const a=L(n.data);return typeof a=="object"&&a!==null&&(a.fromCache=!0),a}const s=await S.loadData($+e);return s.success!==!1?{...s,fromCache:!0}:r},saveData:async(e,t)=>{if(!Q())return S.saveData(e,t);const r=ce(),n=await A(e);let s;n?s=se(n.meta,r):s=se(T(r),r),await N(e,t,s);const a=await I.saveData(e,t);return a.success!==!1?(s.lastSyncedData=t,s.lastSyncedTs=Date.now(),s.lastSyncedVc={...s.vc},await N(e,t,s),await S.removeFromSyncQueue(e),Xe(),a):(await S.addToSyncQueue({key:e,data:t,timestamp:Date.now(),meta:s}),{success:!0,queuedForSync:!0})},loadKeys:async(e={})=>{if(!Q())return S.loadKeys(e);const t=await I.loadKeys(e);return oe(t)?S.loadKeys(e):t},async getKeyCloudUrl(e,t={}){var s;const{migrateFromLocal:r=!0,autoConfigureCloud:n=!0}=t;try{const a=d("server.provider");let o;a==="classworkscloud"?o=q():o=d("server.domain");let i=d("server.siteKey");const c=d("device.uuid");let u=!1;if(!o||!c)if(n){const y={"server.domain":"https://kv-service.houlang.cloud","server.siteKey":""};o||(B("server.domain",y["server.domain"]),o=y["server.domain"],u=!0),i||(B("server.siteKey",y["server.siteKey"]),i=y["server.siteKey"]),B("server.provider","classworkscloud"),o=q()}else return f("云端配置无效,请检查服务器域名和设备UUID","CONFIG_ERROR");let l=!1;if(r)try{const y=await S.loadData(e);if(y&&y.success!==!1){const m=await I.loadData(e);if(m&&m.success===!1&&((s=m.error)==null?void 0:s.code)==="NOT_FOUND"){const k=await I.saveData(e,y);k&&k.success!==!1&&(l=!0,console.log(`已成功将键 ${e} 的数据从本地迁移到云端`))}}}catch(y){console.warn(`迁移键 ${e} 的数据时出错:`,y)}const g=d("server.kvToken");return{success:!0,url:`${o}/kv/${e}?token=${g}`,migrated:l,configured:u}}catch(a){return console.error("获取键云端地址时出错:",a),f(a.message||"获取键云端地址失败","CLOUD_URL_ERROR")}}};export{w as a,S as b,nt as c,at as d,I as k,ue as o,st as s};