From 37b3b61f791eaa767cdb352878af6093416e7601 Mon Sep 17 00:00:00 2001 From: Mikhail Mitrofanov Date: Tue, 15 Sep 2026 10:54:09 +0300 Subject: [PATCH] deck display --- dist/assets/index-CiCJJhCu.js | 52 ------- dist/assets/index-Dqxd5Tgf.js | 59 ++++++++ ...{index-CXPiR0gG.css => index-u8F3m7-8.css} | 2 +- dist/index.html | 5 +- index.html | 1 + src/db-types.ts | 11 ++ src/decks-page.ts | 139 ++++++++++++++++++ src/main.ts | 10 +- src/style.css | 5 + 9 files changed, 226 insertions(+), 58 deletions(-) delete mode 100644 dist/assets/index-CiCJJhCu.js create mode 100644 dist/assets/index-Dqxd5Tgf.js rename dist/assets/{index-CXPiR0gG.css => index-u8F3m7-8.css} (99%) create mode 100644 src/decks-page.ts diff --git a/dist/assets/index-CiCJJhCu.js b/dist/assets/index-CiCJJhCu.js deleted file mode 100644 index 4991ee0..0000000 --- a/dist/assets/index-CiCJJhCu.js +++ /dev/null @@ -1,52 +0,0 @@ -(function(){const n=document.createElement("link").relList;if(n&&n.supports&&n.supports("modulepreload"))return;for(const i of document.querySelectorAll('link[rel="modulepreload"]'))s(i);new MutationObserver(i=>{for(const u of i)if(u.type==="childList")for(const h of u.addedNodes)h.tagName==="LINK"&&h.rel==="modulepreload"&&s(h)}).observe(document,{childList:!0,subtree:!0});function o(i){const u={};return i.integrity&&(u.integrity=i.integrity),i.referrerPolicy&&(u.referrerPolicy=i.referrerPolicy),i.crossOrigin==="use-credentials"?u.credentials="include":i.crossOrigin==="anonymous"?u.credentials="omit":u.credentials="same-origin",u}function s(i){if(i.ep)return;i.ep=!0;const u=o(i);fetch(i.href,u)}})();const _e=new Worker(new URL("/assets/db-worker-AHwpujSZ.js",import.meta.url),{type:"module"});let ar=0,Ye=null;const De=new Map;function kn(){return Ye||(Ye=new Promise((r,n)=>{_e.onmessage=s=>{const i=s.data;if(i.type==="ready")return;const u=De.get(i.id);u&&(De.delete(i.id),i.type=="success"?u.resolve(i.data):u.reject(new Error(i.error??i.message??"Неизвестная ошибка Worker")))},_e.onerror=s=>{console.error("[SQLite Worker] Ошибка:",s),n(new Error("Ошибка Worker"))};const o=++ar;De.set(o,{resolve:r,reject:n}),_e.postMessage({type:"start",id:o})}),Ye)}function $n(r,n){return new Promise((o,s)=>{if(!_e){s(new Error("Worker не создан"));return}const i=++ar;De.set(i,{resolve:o,reject:s}),_e.postMessage({type:r,id:i,...n})})}async function Ae(r,n){return await $n("query",{sql:r,params:n??[]})}function Qn(r){if(r==null)return[];const n=String(r).trim();return n?n.split(/[,\s;]+/).map(o=>o.trim()).filter(o=>o.length>0):[]}function Tn(r){const n=new Map;if(r==null)return n;const o=String(r);if(!o)return n;const s=o.split("");for(let i=0;i+10?`WHERE ${n.join(" AND ")}`:"",params:o}}async function Nn(r={}){const{clause:n,params:o}=or(r),i=(await Ae(`SELECT COUNT(*) as cnt FROM words ${n}`,o))[0]?.cnt;return typeof i=="number"?i:Number(i??0)}async function jt(r={}){const{clause:n,params:o}=or(r),s=Math.max(1,Math.min(r.limit??50,500)),i=Math.max(0,r.offset??0);return(await Ae(`SELECT id, key, value, tags, more, group_id FROM words ${n} ORDER BY id LIMIT ? OFFSET ?`,[...o,s,i])).map(Fn)}async function Hn(){return(await Ae("SELECT id, name FROM word_groups ORDER BY id")).map(n=>({id:Number(n.id),name:String(n.name??"")}))}async function Pn(){return(await Ae("SELECT id, name, identifier FROM custom_fields ORDER BY id")).map(n=>({id:Number(n.id),name:String(n.name??""),identifier:String(n.identifier??"")}))}const Ut="japanese_app.db";async function Ct(){return navigator.storage.getDirectory()}async function _n(r){r[18]=1,r[19]=1;const o=await(await Ct()).getFileHandle(Ut,{create:!0}),s=o.createSyncAccessHandle;if(typeof s=="function")try{const u=await s.call(o);try{u.truncate(0),u.write(r,{at:0}),u.flush()}finally{u.close()}return}catch{}const i=await o.createWritable();try{await i.truncate(0);const u=new Uint8Array(r.length);u.set(r),await i.write(u)}finally{await i.close()}}async function qn(){const r=await Ct();let n;try{n=await r.getFileHandle(Ut)}catch{throw new Error("Локальная база не найдена — сначала скачай сохранение")}const o=await n.getFile();if(o.size===0)throw new Error("Локальная база пуста");return new Uint8Array(await o.arrayBuffer())}async function Ge(){try{return(await(await(await Ct()).getFileHandle(Ut)).getFile()).size>0}catch{return!1}}var Ln=ArrayBuffer,z=Uint8Array,je=Uint16Array,Rn=Int16Array,et=Int32Array,ft=function(r,n,o){if(z.prototype.slice)return z.prototype.slice.call(r,n,o);(n==null||n<0)&&(n=0),(o==null||o>r.length)&&(o=r.length);var s=new z(o-n);return s.set(r.subarray(n,o)),s},qe=function(r,n,o,s){if(z.prototype.fill)return z.prototype.fill.call(r,n,o,s);for((o==null||o<0)&&(o=0),(s==null||s>r.length)&&(s=r.length);or.length)&&(s=r.length);o2046MB)","invalid block type","FSE accuracy too high","match distance too far back","unexpected EOF"],B=function(r,n,o){var s=new Error(n||Jn[r]);if(s.code=r,Error.captureStackTrace&&Error.captureStackTrace(s,B),!o)throw s;return s},Wt=function(r,n,o){for(var s=0,i=0;s>>0},Kn=function(r,n){var o=r[0]|r[1]<<8|r[2]<<16;if(o==3126568&&r[3]==253){var s=r[4],i=s>>5&1,u=s>>2&1,h=s&3,w=s>>6;s&8&&B(0);var U=6-i,M=h==3?4:h,b=Wt(r,U,M);U+=M;var F=w?1<>3);y=Q+(Q>>3)*(r[5]&7)}y>2145386496&&B(1);var m=new z((n==1?N||y:n?0:y)+12);return m[0]=1,m[4]=4,m[8]=8,{b:U+F,y:0,l:0,d:b,w:n&&n!=1?n:m.subarray(12),e:y,o:new et(m.buffer,0,3),u:N,c:u,m:Math.min(131072,y)}}else if((o>>4|r[3]<<20)==25481893)return Sn(r,4)+8;B(0)},Ce=function(r){for(var n=0;1<o&&B(3);for(var u=1<0;){var X=Ce(h+1),R=s>>3,Y=(1<>(s&7)&Y,E=(1<E&&(K-=O)),N[++w]=--K,K==-1?(h+=K,x[--b]=w):h-=K,!K)do{var ee=s>>3;U=(r[ee]|r[ee+1]<<8)>>(s&7)&3,s+=2,w+=U}while(U==3)}(w>255||h)&&B(0);for(var G=0,re=(u>>1)+(u>>3)+3,V=u-1,j=0;j<=w;++j){var H=N[j];if(H<1){y[j]=-H;continue}for(M=0;M=b)}}for(G&&B(0),M=0;M>3,{b:i,s:x,n:I,t:Q}]},Xn=function(r,n){var o=0,s=-1,i=new z(292),u=r[n],h=i.subarray(0,256),w=i.subarray(256,268),U=new je(i.buffer,268);if(u<128){var M=Le(r,n+1,6),b=M[0],F=M[1];n+=u;var N=b<<3,y=r[n];y||B(0);for(var Q=0,m=0,x=F.b,I=x,X=(++n<<3)-8+Ce(y);X-=x,!(X>3;if(Q+=(r[R]|r[R+1]<<8)>>(X&7)&(1<>3,m+=(r[R]|r[R+1]<<8)>>(X&7)&(1<255&&B(0)}else{for(s=u-127;o>4,h[o+1]=Y&15}++n}var K=0;for(o=0;o11&&B(0),K+=E&&1<0;--o){var j=U[o];qe(V,o,j,U[o-1]=j+w[o]*(1<w&&F>3,y=(r[N]|r[N+1]<<8|r[N+2]<<16)>>(b&7);U=(U<>2,h=u<<1,w=u+h;Pe(r.subarray(s,s+=r[0]|r[1]<<8),n.subarray(0,u),o),Pe(r.subarray(s,s+=r[2]|r[3]<<8),n.subarray(u,h),o),Pe(r.subarray(s,s+=r[4]|r[5]<<8),n.subarray(h,w),o),Pe(r.subarray(s),n.subarray(w),o)},Dn=function(r,n,o){var s,i=n.b,u=r[i],h=u>>1&3;n.l=u&1;var w=u>>3|r[i+1]<<5|r[i+2]<<13,U=(i+=3)+w;if(h==1)return i>=r.length?void 0:(n.b=i+1,o?(qe(o,r[i],n.y,n.y+=w),o):qe(new z(w),r[i]));if(!(U>r.length)){if(h==0)return n.b=U,o?(o.set(r.subarray(i,U),n.y),n.y+=w,o):ft(r,i,U);if(h==2){var M=r[i],b=M&3,F=M>>2&3,N=M>>4,y=0,Q=0;b<2?F&1?N|=r[++i]<<4|(F&2&&r[++i]<<12):N=M>>3:(Q=F,F<2?(N|=(r[++i]&63)<<4,y=r[i]>>6|r[++i]<<2):F==2?(N|=r[++i]<<4|(r[++i]&3)<<12,y=r[i]>>2|r[++i]<<6):(N|=r[++i]<<4|(r[++i]&63)<<12,y=r[i]>>6|r[++i]<<2|r[++i]<<10)),++i;var m=o?o.subarray(n.y,n.y+n.m):new z(n.m),x=m.length-N;if(b==0)m.set(r.subarray(i,i+=N),x);else if(b==1)qe(m,r[i++],x);else{var I=n.h;if(b==2){var X=Xn(r,i);y+=i-(i=X[0]),n.h=I=X[1]}else I||B(0);(Q?Yn:Pe)(r.subarray(i,i+=y),m.subarray(x),I)}var R=r[i++];if(R){R==255?R=(r[i++]|r[i++]<<8)+32512:R>127&&(R=R-128<<8|r[i++]);var Y=r[i++];Y&3&&B(0);for(var K=[zn,Vn,On],E=2;E>-1;--E){var O=Y>>(E<<1)+2&3;if(O==1){var D=new z([0,0,r[i++]]);K[E]={s:D.subarray(2,3),n:D.subarray(0,1),t:new je(D.buffer,0,1),b:0}}else O==2?(s=Le(r,i,9-(E&1)),i=s[0],K[E]=s[1]):O==3&&(n.t||B(0),K[E]=n.t[E])}var ee=n.t=K,G=ee[0],re=ee[1],V=ee[2],j=r[U-1];j||B(0);var H=(U<<3)-8+Ce(j)-V.b,g=H>>3,C=0,k=(r[g]|r[g+1]<<8)>>(H&7)&(1<>3;var P=(r[g]|r[g+1]<<8)>>(H&7)&(1<>3;var _=(r[g]|r[g+1]<<8)>>(H&7)&(1<>3;var we=1<>>(H&7)&we-1);g=(H-=vt[Me])>>3;var ie=Bn[Me]+((r[g]|r[g+1]<<8|r[g+2]<<16)>>(H&7)&(1<>3;var he=Zn[fe]+((r[g]|r[g+1]<<8|r[g+2]<<16)>>(H&7)&(1<>3,k=V.t[k]+((r[g]|r[g+1]<<8)>>(H&7)&(1<>3,_=G.t[_]+((r[g]|r[g+1]<<8)>>(H&7)&(1<>3,P=re.t[P]+((r[g]|r[g+1]<<8)>>(H&7)&(1<3)n.o[2]=n.o[1],n.o[1]=n.o[0],n.o[0]=ne-=3;else{var Ee=ne-(he!=0);Ee?(ne=Ee==3?n.o[0]-1:n.o[Ee],Ee>1&&(n.o[2]=n.o[1]),n.o[1]=n.o[0],n.o[0]=ne):ne=n.o[0]}for(var E=0;Eie&&(ae=ie);for(var E=0;E{throw e},s,i=console.log.bind(console),u=console.error.bind(console),h,w=!1,U,M=t=>t.startsWith("file://"),b=!1;function F(){return Ze.buffer}function N(){if(!D?.buffer?.resizable){var t=F();D=new Int8Array(t),Se=new Int16Array(t),n.HEAPU8=k=new Uint8Array(t),$e=new Uint16Array(t),Ke=new Int32Array(t),_=new Uint32Array(t),qt=new Float32Array(t),Lt=new Float64Array(t),Mt=new BigInt64Array(t),xt=new BigUint64Array(t)}}function y(){b=!0,Fe.A()}function Q(t){t=`Aborted(${t})`,u(t),w=!0,t+=". Build with -sASSERTIONS for more info.",b&&Xt();var e=new WebAssembly.RuntimeError(t);throw e}var m;let x=()=>"";function I(t){if(t==m&&h)return new Uint8Array(h);throw"both async and sync fetching of the wasm failed"}async function X(t){if(!h)try{var e=await s(t);return new Uint8Array(e)}catch{}return I(t)}async function R(t,e){try{var a=await X(t),l=await WebAssembly.instantiate(a,e);return l}catch(c){u(`failed to asynchronously prepare wasm: ${c}`),Q(c)}}async function Y(t,e,a){if(!t&&!M(e))try{var l=fetch(e,{credentials:"same-origin"}),c=await WebAssembly.instantiateStreaming(l,a);return c}catch(d){u(`wasm streaming compile failed: ${d}`),u("falling back to ArrayBuffer instantiation")}return R(e,a)}function K(){var t={a:Mn};return t}async function E(){function t(d){return Fe=d.exports,En(Fe),N(),Fe}function e(d){return t(d.instance)}var a=K();m??=x();var l=await Y(h,m,a),c=e(l);return c}class O{name="ExitStatus";constructor(e){this.message=`Program terminated with exit(${e})`,this.status=e}}var D,ee=()=>Yt,G=t=>{var e=t.getArg(ee(),0);return Zt(e)},re=()=>Vt(),V=t=>Ot(t),j=t=>zt(t),H=globalThis.TextDecoder&&new TextDecoder,g=(t,e,a,l)=>{var c=e+a;if(l)return c;for(;t[e]&&!(e>=c);)++e;return e},C=(t,e=0,a,l)=>{var c=g(t,e,a,l);if(c-e>16&&t.buffer&&H)return H.decode(t.subarray(e,c));for(var d="";e>10,56320|$&1023)}}return d},k,P=(t,e,a)=>t?C(k,t,e,a):"",_,fe=t=>{var e=re(),a=j(4),l=j(4);Bt(t,a,l);var c=_[a>>2],d=_[l>>2],p=P(c);pe(c);var f;return d&&(f=P(d),pe(d)),V(e),[p,f]},ue=t=>{var e=G(t);return fe(e)},Me=t=>{var e=new WebAssembly.Exception(ee(),[t],{traceStack:!0});throw e.message=ue(e),e},Je=()=>Q(""),ve={},xe=t=>{for(;t.length;){var e=t.pop(),a=t.pop();a(e)}};function we(t){return this.fromWireType(_[t>>2])}var ne={},ie={},he={};class Ee extends Error{constructor(e){super(e),this.name="InternalError"}}var ce=t=>{throw new Ee(t)},ae=(t,e,a)=>{t.forEach(f=>he[f]=e);function l(f){var v=a(f);v.length!==t.length&&ce("Mismatched type converter count");for(var $=0;${c[f]=ie[v],++p,p===d.length&&l(c)}));d.length===0&&l(c)},tt=t=>{var e=ve[t];delete ve[t];var a=e.rawConstructor,l=e.rawDestructor,c=e.fields,d=c.map(p=>p.getterReturnType).concat(c.map(p=>p.setterArgumentType));ae([t],d,p=>{var f={};for(var[v,$]of c.entries()){let T=p[v],J=$.getter,L=$.getterContext,S=p[v+c.length],W=$.setter,oe=$.setterContext;f[$.fieldName]={read:A=>T.fromWireType(J(L,A)),write:(A,Z)=>{var me=[];W(oe,A,S.toWireType(me,Z)),xe(me)},optional:T.optional}}return[{name:e.name,fromWireType:T=>{var J={};for(var L in f)J[L]=f[L].read(T);return l(T),J},toWireType:(T,J)=>{for(var L in f)if(!(L in J)&&!f[L].optional)throw new TypeError(`Missing field: "${L}"`);var S=a();for(L in f)f[L].write(S,J[L]);return T!==null&&T.push(l,S),S},readValueFromPointer:we,destructorFunction:l}]})},te=t=>{for(var e="";;){var a=k[t++];if(!a)return e;e+=String.fromCharCode(a)}};class ke extends Error{constructor(e){super(e),this.name="BindingError"}}var q=t=>{throw new ke(t)};function hr(t,e,a={}){var l=e.name;if(t||q(`type "${l}" must have a positive integer typeid pointer`),ie.hasOwnProperty(t)){if(a.ignoreDuplicateRegistrations)return;q(`Cannot register type '${l}' twice`)}if(ie[t]=e,delete he[t],ne.hasOwnProperty(t)){var c=ne[t];delete ne[t],c.forEach(d=>d())}}function de(t,e,a={}){return hr(t,e,a)}var Se,$e,Ke,Mt,xt,kt=(t,e,a)=>{switch(e){case 1:return a?l=>D[l]:l=>k[l];case 2:return a?l=>Se[l>>1]:l=>$e[l>>1];case 4:return a?l=>Ke[l>>2]:l=>_[l>>2];case 8:return a?l=>Mt[l>>3]:l=>xt[l>>3];default:throw new TypeError(`invalid integer width (${e}): ${t}`)}},gr=(t,e,a,l,c)=>{e=te(e);let d=l===0n,p=f=>f;if(d){let f=a*8;p=v=>BigInt.asUintN(f,v),c=p(c)}de(t,{name:e,fromWireType:p,toWireType:(f,v)=>(typeof v=="number"&&(v=BigInt(v)),v),readValueFromPointer:kt(e,a,!d),destructorFunction:null})},wr=(t,e,a,l)=>{e=te(e),de(t,{name:e,fromWireType:function(c){return!!c},toWireType:function(c,d){return d?a:l},readValueFromPointer:function(c){return this.fromWireType(k[c])},destructorFunction:null})},mr=t=>({count:t.count,deleteScheduled:t.deleteScheduled,preservePointerOnDelete:t.preservePointerOnDelete,ptr:t.ptr,ptrType:t.ptrType,smartPtr:t.smartPtr,smartPtrType:t.smartPtrType}),rt=t=>{function e(a){return a.$$.ptrType.registeredClass.name}q(e(t)+" instance already deleted")},nt=!1,$t=t=>{},vr=t=>{t.smartPtr?t.smartPtrType.rawDestructor(t.smartPtr):t.ptrType.registeredClass.rawDestructor(t.ptr)},Qt=t=>{t.count.value-=1;var e=t.count.value===0;e&&vr(t)},Qe=t=>globalThis.FinalizationRegistry?(nt=new FinalizationRegistry(e=>{Qt(e.$$)}),Qe=e=>{var a=e.$$,l=!!a.smartPtr;if(l){var c={$$:a};nt.register(e,c,e)}return e},$t=e=>nt.unregister(e),Qe(t)):(Qe=e=>e,t),yr=()=>{let t=Xe.prototype;Object.assign(t,{isAliasOf(a){if(!(this instanceof Xe)||!(a instanceof Xe))return!1;var l=this.$$.ptrType.registeredClass,c=this.$$.ptr;a.$$=a.$$;for(var d=a.$$.ptrType.registeredClass,p=a.$$.ptr;l.baseClass;)c=l.upcast(c),l=l.baseClass;for(;d.baseClass;)p=d.upcast(p),d=d.baseClass;return l===d&&c===p},clone(){if(this.$$.ptr||rt(this),this.$$.preservePointerOnDelete)return this.$$.count.value+=1,this;var a=Qe(Object.create(Object.getPrototypeOf(this),{$$:{value:mr(this.$$)}}));return a.$$.count.value+=1,a.$$.deleteScheduled=!1,a},delete(){this.$$.ptr||rt(this),this.$$.deleteScheduled&&!this.$$.preservePointerOnDelete&&q("Object already scheduled for deletion"),$t(this),Qt(this.$$),this.$$.preservePointerOnDelete||(this.$$.smartPtr=void 0,this.$$.ptr=void 0)},isDeleted(){return!this.$$.ptr},deleteLater(){return this.$$.ptr||rt(this),this.$$.deleteScheduled&&!this.$$.preservePointerOnDelete&&q("Object already scheduled for deletion"),this.$$.deleteScheduled=!0,this}});let e=Symbol.dispose;e&&(t[e]=t.delete)};function Xe(){}var Tt=(t,e)=>Object.defineProperty(e,"name",{value:t}),Ft={},at=(t,e,a)=>{if(t[e].overloadTable===void 0){var l=t[e];t[e]=function(...c){return t[e].overloadTable.hasOwnProperty(c.length)||q(`Function '${a}' called with an invalid number of arguments (${c.length}) - expects one of (${t[e].overloadTable})!`),t[e].overloadTable[c.length].apply(this,c)},t[e].overloadTable=[],t[e].overloadTable[l.argCount]=l}},br=(t,e,a)=>{n.hasOwnProperty(t)?(q(`Cannot register public name '${t}' twice`),at(n,t,t),n[t].overloadTable.hasOwnProperty(a)&&q(`Cannot register multiple overloads of a function with the same number of arguments (${a})!`),n[t].overloadTable[a]=e):(n[t]=e,n[t].argCount=a)},Ur=48,Cr=57,Er=t=>{t=t.replace(/[^a-zA-Z0-9_]/g,"$");var e=t.charCodeAt(0);return e>=Ur&&e<=Cr?`_${t}`:t};function Mr(t,e,a,l,c,d,p,f){this.name=t,this.constructor=e,this.instancePrototype=a,this.rawDestructor=l,this.baseClass=c,this.getActualType=d,this.upcast=p,this.downcast=f,this.pureVirtualFunctions=[]}var ot=(t,e,a)=>{for(;e!==a;)e.upcast||q(`Expected null or instance of ${a.name}, got an instance of ${e.name}`),t=e.upcast(t),e=e.baseClass;return t},it=t=>{if(t===null)return"null";var e=typeof t;return e==="object"||e==="array"||e==="function"?t.toString():""+t};function xr(t,e){if(e===null)return this.isReference&&q(`null is not a valid ${this.name}`),0;e.$$||q(`Cannot pass "${it(e)}" as a ${this.name}`),e.$$.ptr||q(`Cannot pass deleted object as a pointer of type ${this.name}`);var a=e.$$.ptrType.registeredClass,l=ot(e.$$.ptr,a,this.registeredClass);return l}function kr(t,e){var a;if(e===null)return this.isReference&&q(`null is not a valid ${this.name}`),this.isSmartPointer?(a=this.rawConstructor(),t!==null&&t.push(this.rawDestructor,a),a):0;(!e||!e.$$)&&q(`Cannot pass "${it(e)}" as a ${this.name}`),e.$$.ptr||q(`Cannot pass deleted object as a pointer of type ${this.name}`),!this.isConst&&e.$$.ptrType.isConst&&q(`Cannot convert argument of type ${e.$$.smartPtrType?e.$$.smartPtrType.name:e.$$.ptrType.name} to parameter type ${this.name}`);var l=e.$$.ptrType.registeredClass;if(a=ot(e.$$.ptr,l,this.registeredClass),this.isSmartPointer)switch(e.$$.smartPtr===void 0&&q("Passing raw pointer to smart pointer is illegal"),this.sharingPolicy){case 0:e.$$.smartPtrType===this?a=e.$$.smartPtr:q(`Cannot convert argument of type ${e.$$.smartPtrType?e.$$.smartPtrType.name:e.$$.ptrType.name} to parameter type ${this.name}`);break;case 1:a=e.$$.smartPtr;break;case 2:if(e.$$.smartPtrType===this)a=e.$$.smartPtr;else{var c=e.clone();a=this.rawShare(a,ut.toHandle(()=>c.delete())),t!==null&&t.push(this.rawDestructor,a)}break;default:q("Unsupported sharing policy")}return a}function $r(t,e){if(e===null)return this.isReference&&q(`null is not a valid ${this.name}`),0;e.$$||q(`Cannot pass "${it(e)}" as a ${this.name}`),e.$$.ptr||q(`Cannot pass deleted object as a pointer of type ${this.name}`),e.$$.ptrType.isConst&&q(`Cannot convert argument of type ${e.$$.ptrType.name} to parameter type ${this.name}`);var a=e.$$.ptrType.registeredClass,l=ot(e.$$.ptr,a,this.registeredClass);return l}var Nt=(t,e,a)=>{if(e===a)return t;if(a.baseClass===void 0)return null;var l=Nt(t,e,a.baseClass);return l===null?null:a.downcast(l)},Qr={},Tr=(t,e)=>{for(e===void 0&&q("ptr should not be undefined");t.baseClass;)e=t.upcast(e),t=t.baseClass;return e},Fr=(t,e)=>(e=Tr(t,e),Qr[e]),Oe=(t,e)=>{(!e.ptrType||!e.ptr)&&ce("makeClassHandle requires ptr and ptrType");var a=!!e.smartPtrType,l=!!e.smartPtr;return a!==l&&ce("Both smartPtrType and smartPtr must be specified"),e.count={value:1},Qe(Object.create(t,{$$:{value:e,writable:!0}}))};function Nr(t){var e=this.getPointee(t);if(!e)return this.destructor(t),null;var a=Fr(this.registeredClass,e);if(a!==void 0){if(a.$$.count.value===0)return a.$$.ptr=e,a.$$.smartPtr=t,a.clone();var l=a.clone();return this.destructor(t),l}function c(){return this.isSmartPointer?Oe(this.registeredClass.instancePrototype,{ptrType:this.pointeeType,ptr:e,smartPtrType:this,smartPtr:t}):Oe(this.registeredClass.instancePrototype,{ptrType:this,ptr:t})}var d=this.registeredClass.getActualType(e),p=Ft[d];if(!p)return c.call(this);var f;this.isConst?f=p.constPointerType:f=p.pointerType;var v=Nt(e,this.registeredClass,f.registeredClass);return v===null?c.call(this):this.isSmartPointer?Oe(f.registeredClass.instancePrototype,{ptrType:f,ptr:v,smartPtrType:this,smartPtr:t}):Oe(f.registeredClass.instancePrototype,{ptrType:f,ptr:v})}var Hr=()=>{Object.assign(ze.prototype,{getPointee(t){return this.rawGetPointee&&(t=this.rawGetPointee(t)),t},destructor(t){this.rawDestructor?.(t)},readValueFromPointer:we,fromWireType:Nr})};function ze(t,e,a,l,c,d,p,f,v,$,T){this.name=t,this.registeredClass=e,this.isReference=a,this.isConst=l,this.isSmartPointer=c,this.pointeeType=d,this.sharingPolicy=p,this.rawGetPointee=f,this.rawConstructor=v,this.rawShare=$,this.rawDestructor=T,!c&&e.baseClass===void 0?l?(this.toWireType=xr,this.destructorFunction=null):(this.toWireType=$r,this.destructorFunction=null):this.toWireType=kr}var Pr=(t,e,a)=>{n.hasOwnProperty(t)||ce("Replacing nonexistent public symbol"),n[t].overloadTable!==void 0&&a!==void 0?n[t].overloadTable[a]=e:(n[t]=e,n[t].argCount=a)},_r=t=>Dt.get(t),le=(t,e,a=!1)=>{t=te(t);function l(){var d=_r(e);return d}var c=l();return typeof c!="function"&&q(`unknown function pointer with signature ${t}: ${e}`),c};class qr extends Error{}var Lr=t=>{var e=St(t),a=te(e);return pe(e),a},Ve=(t,e)=>{var a=[],l={};function c(d){if(!l[d]&&!ie[d]){if(he[d]){he[d].forEach(c);return}a.push(d),l[d]=!0}}throw e.forEach(c),new qr(`${t}: `+a.map(Lr).join([", "]))},Rr=(t,e,a,l,c,d,p,f,v,$,T,J,L)=>{T=te(T),d=le(c,d),f&&=le(p,f),$&&=le(v,$),L=le(J,L);var S=Er(T);br(S,function(){Ve(`Cannot construct ${T} due to unbound types`,[l])}),ae([t,e,a],l?[l]:[],W=>{W=W[0];var oe,A;l?(oe=W.registeredClass,A=oe.instancePrototype):A=Xe.prototype;var Z=Tt(T,function(...pt){if(Object.getPrototypeOf(this)!==me)throw new ke(`Use 'new' to construct ${T}`);if(se.constructor_body===void 0)throw new ke(`${T} has no accessible constructor`);var Gt=se.constructor_body[pt.length];if(Gt===void 0)throw new ke(`Tried to invoke ctor of ${T} with invalid number of parameters (${pt.length}) - expected (${Object.keys(se.constructor_body).toString()}) parameters instead!`);return Gt.apply(this,pt)}),me=Object.create(A,{constructor:{value:Z}});Z.prototype=me;var se=new Mr(T,Z,me,L,oe,d,f,$);se.baseClass&&(se.baseClass.__derivedClasses??=[],se.baseClass.__derivedClasses.push(se));var dt=new ze(T,se,!0,!1,!1),ge=new ze(T+"*",se,!1,!1,!1),Be=new ze(T+" const*",se,!1,!0,!1);return Ft[t]={pointerType:ge,constPointerType:Be},Pr(S,Z),[dt,ge,Be]})};function Ir(t){for(var e=1;e{for(var a=[],l=0;l>2]);return a},Ht=t=>{t=t.trim();let e=t.indexOf("(");return e===-1?t:t.slice(0,e)},Jr=(t,e,a,l,c,d,p,f,v)=>{var $=lt(a,l);e=te(e),e=Ht(e),d=le(c,d,f),ae([],[t],T=>{T=T[0];var J=`${T.name}.${e}`;function L(){Ve(`Cannot call ${J} due to unbound types`,$)}e.startsWith("@@")&&(e=Symbol[e.substring(2)]);var S=T.registeredClass.constructor;return S[e]===void 0?(L.argCount=a-1,S[e]=L):(at(S,e,J),S[e].overloadTable[a-1]=L),ae([],$,W=>{var oe=[W[0],null].concat(W.slice(1)),A=st(J,oe,null,d,p);if(S[e].overloadTable===void 0?(A.argCount=a-1,S[e]=A):S[e].overloadTable[a-1]=A,T.registeredClass.__derivedClasses)for(let Z of T.registeredClass.__derivedClasses)Z.constructor.hasOwnProperty(e)||(Z.constructor[e]=A);return[]}),[]})},Sr=(t,e,a,l,c,d)=>{var p=lt(e,a);c=le(l,c),ae([],[t],f=>{f=f[0];var v=`constructor ${f.name}`;if(f.registeredClass.constructor_body===void 0&&(f.registeredClass.constructor_body=[]),f.registeredClass.constructor_body[e-1]!==void 0)throw new ke(`Cannot register multiple constructors with identical number of parameters (${e-1}) for class '${f.name}'! Overload resolution is currently only performed using the parameter count, not actual type info!`);return f.registeredClass.constructor_body[e-1]=()=>{Ve(`Cannot construct ${f.name} due to unbound types`,p)},ae([],p,$=>($.splice(1,0,null),f.registeredClass.constructor_body[e-1]=st(v,$,null,c,d),[])),[]})},Kr=(t,e,a,l,c,d,p,f,v,$)=>{var T=lt(a,l);e=te(e),e=Ht(e),d=le(c,d,v),ae([],[t],J=>{J=J[0];var L=`${J.name}.${e}`;e.startsWith("@@")&&(e=Symbol[e.substring(2)]),f&&J.registeredClass.pureVirtualFunctions.push(e);function S(){Ve(`Cannot call ${L} due to unbound types`,T)}var W=J.registeredClass.instancePrototype,oe=W[e];return oe===void 0||oe.overloadTable===void 0&&oe.className!==J.name&&oe.argCount===a-2?(S.argCount=a-2,S.className=J.name,W[e]=S):(at(W,e,L),W[e].overloadTable[a-2]=S),ae([],T,A=>{var Z=st(L,A,J,d,p);return W[e].overloadTable===void 0?(Z.argCount=a-2,W[e]=Z):W[e].overloadTable[a-2]=Z,[]}),[]})},Pt=[],ye=[0,1,,1,null,1,!0,1,!1,1],_t=[],Xr=t=>{if(t>9&&--ye[t+1]===0){var e=ye[t];ye[t]=void 0;var a=_t[t];a&&(_t[t]=void 0,a(e)),Pt.push(t)}},ut={toValue:t=>(t||q(`Cannot use deleted val. handle = ${t}`),ye[t]),toHandle:t=>{switch(t){case void 0:return 2;case null:return 4;case!0:return 6;case!1:return 8;default:{let e=Pt.pop()||ye.length;return ye[e]=t,ye[e+1]=1,e}}}},Or={name:"emscripten::val",fromWireType:t=>{var e=ut.toValue(t);return Xr(t),e},toWireType:(t,e)=>ut.toHandle(e),readValueFromPointer:we,destructorFunction:null},zr=t=>de(t,Or),qt,Lt,Vr=(t,e)=>{switch(e){case 4:return function(a){return this.fromWireType(qt[a>>2])};case 8:return function(a){return this.fromWireType(Lt[a>>3])};default:throw new TypeError(`invalid float width (${e}): ${t}`)}},Zr=(t,e,a)=>{e=te(e),de(t,{name:e,fromWireType:l=>l,toWireType:(l,c)=>c,readValueFromPointer:Vr(e,a),destructorFunction:null})},Br=(t,e,a,l,c)=>{e=te(e);let d=l===0,p=v=>v;if(d){var f=32-8*a;p=v=>v<>>f,c=p(c)}de(t,{name:e,fromWireType:p,toWireType:(v,$)=>$,readValueFromPointer:kt(e,a,l!==0),destructorFunction:null})},Yr=(t,e,a)=>{var l=[Int8Array,Uint8Array,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array,BigInt64Array,BigUint64Array],c=l[e];function d(p){var f=_[p>>2],v=_[p+4>>2];return new c(D.buffer,v,f)}a=te(a),de(t,{name:a,fromWireType:d,readValueFromPointer:d},{ignoreDuplicateRegistrations:!0})},Dr=(t,e,a,l)=>{if(!(l>0))return 0;for(var c=a,d=a+l-1,p=0;p=d)break;e[a++]=f}else if(f<=2047){if(a+1>=d)break;e[a++]=192|f>>6,e[a++]=128|f&63}else if(f<=65535){if(a+2>=d)break;e[a++]=224|f>>12,e[a++]=128|f>>6&63,e[a++]=128|f&63}else{if(a+3>=d)break;e[a++]=240|f>>18,e[a++]=128|f>>12&63,e[a++]=128|f>>6&63,e[a++]=128|f&63,p++}}return e[a]=0,a-c},Rt=(t,e,a)=>Dr(t,k,e,a),It=t=>{for(var e=0,a=0;a=55296&&l<=57343?(e+=4,++a):e+=3}return e},Gr=(t,e)=>{e=te(e),de(t,{name:e,fromWireType(a){var l=_[a>>2],c=a+4,d;return d=P(c,l,!0),pe(a),d},toWireType(a,l){l instanceof ArrayBuffer&&(l=new Uint8Array(l));var c,d=typeof l=="string";d||ArrayBuffer.isView(l)&&l.BYTES_PER_ELEMENT==1||q("Cannot pass non-string to std::string"),d?c=It(l):c=l.length;var p=ct(4+c+1),f=p+4;return _[p>>2]=c,d?Rt(l,f,c+1):k.set(l,f),a!==null&&a.push(pe,p),p},readValueFromPointer:we,destructorFunction(a){pe(a)}})},Jt=globalThis.TextDecoder?new TextDecoder("utf-16le"):void 0,jr=(t,e,a)=>{var l=t>>1,c=g($e,l,e/2,a);if(c-l>16&&Jt)return Jt.decode($e.subarray(l,c));for(var d="",p=l;p{if(a<2)return 0;a-=2;for(var l=e,c=a>1]=p,e+=2}return Se[e>>1]=0,e-l},Ar=t=>t.length*2,en=(t,e,a)=>{for(var l="",c=t>>2,d=0;!(d>=e/4);d++){var p=_[c+d];if(!p&&!a)break;l+=String.fromCodePoint(p)}return l},tn=(t,e,a=2147483647)=>{if(a<4)return 0;for(var l=e,c=l+a-4,d=0;d65535&&d++,Ke[e>>2]=p,e+=4,e+4>c)break}return Ke[e>>2]=0,e-l},rn=t=>{for(var e=0,a=0;a65535&&a++,e+=4}return e},nn=(t,e,a)=>{a=te(a);var l,c,d;e===2?(l=jr,c=Wr,d=Ar):(l=en,c=tn,d=rn),de(t,{name:a,fromWireType:p=>{var f=_[p>>2],v=l(p+4,f*e,!0);return pe(p),v},toWireType:(p,f)=>{typeof f!="string"&&q(`Cannot pass non-string to C++ string type ${a}`);var v=d(f),$=ct(4+v+e);return _[$>>2]=v/e,c(f,$+4,v+e),p!==null&&p.push(pe,$),$},readValueFromPointer:we,destructorFunction(p){pe(p)}})},an=(t,e,a,l,c,d)=>{ve[t]={name:te(e),rawConstructor:le(a,l),rawDestructor:le(c,d),fields:[]}},on=(t,e,a,l,c,d,p,f,v,$)=>{ve[t].fields.push({fieldName:te(e),getterReturnType:a,getter:le(l,c),getterContext:d,setterArgumentType:p,setter:le(f,v),setterContext:$})},sn=(t,e)=>{e=te(e),de(t,{isVoid:!0,name:e,fromWireType:()=>{},toWireType:(a,l)=>{}})},ln=()=>{},Te={},un=t=>{if(t instanceof O||t=="unwind")return U;o(1,t)},cn=t=>{U=t,o(t,new O(t))},dn=t=>{if(!w)try{return t()}catch(e){un(e)}},pn=()=>performance.now(),fn=(t,e)=>{if(Te[t]&&(clearTimeout(Te[t].id),delete Te[t]),!e)return 0;var a=setTimeout(()=>{delete Te[t],dn(()=>Kt(t,pn()))},e);return Te[t]={id:a,timeout_ms:e},0},hn=()=>2147483648,gn=(t,e)=>Math.ceil(t/e)*e,wn=t=>{var e=Ze.buffer.byteLength,a=(t-e+65535)/65536|0;try{return Ze.grow(a),N(),1}catch{}},mn=t=>{var e=k.length;t>>>=0;var a=hn();if(t>a)return!1;for(var l=1;l<=4;l*=2){var c=e*(1+.2/l);c=Math.min(c,t+100663296);var d=Math.min(a,gn(Math.max(t,c),65536)),p=wn(d);if(p)return!0}return!1},vn=t=>52;function yn(t,e,a,l){return 70}var bn=[null,[],[]],Un=(t,e)=>{var a=bn[t];!e||e===10?((t===1?i:u)(C(a)),a.length=0):a.push(e)},Cn=(t,e,a,l)=>{for(var c=0,d=0;d>2],f=_[e+4>>2];e+=8;for(var v=0;v>2]=c,0};yr(),Hr(),n.wasmBinary&&(h=n.wasmBinary),n.UTF8ToString=P,n.stringToUTF8=Rt,n.lengthBytesUTF8=It;var St,ct,pe,Kt,Xt,Ot,zt,Vt,Zt,Bt,Yt,Ze,Dt;function En(t){St=t.B,ct=n._malloc=t.C,pe=n._free=t.D,Kt=t.F,Xt=t.G,Ot=t.H,zt=t.I,Vt=t.J,Zt=t.K,Bt=t.L,Ze=t.z,Dt=t.E,Yt=t.M}var Mn={t:Me,x:Je,f:tt,i:gr,l:wr,o:Rr,b:Jr,n:Sr,d:Kr,y:zr,h:Zr,c:Br,a:Yr,k:Gr,g:nn,j:an,e:on,m:sn,w:ln,p:fn,u:mn,s:vn,q:yn,r:Cn,v:cn};async function xn(){!w&&y()}var Fe;return Fe=await E(),await xn(),n}var An=Wn,ea=new Int8Array([-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,62,90,63,64,65,66,-1,67,68,69,70,71,-1,72,73,52,53,54,55,56,57,58,59,60,61,74,75,76,77,78,79,80,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,81,-1,82,83,84,85,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,86,87,88,89,-1]);function ta(r){let n=new Uint8Array(170930),o=0,s=0,i=0,u=-1;for(let h=0,w=r.length;h127)continue;let M=ea[U];if(!(M<0))if(u<0)u=M;else{u+=M*91,s|=u<88?13:14;do n[o++]=s,s>>>=8,i-=8;while(i>7);u=-1}}return u>=0&&(n[o++]=(s|u<""})}function aa(){yt=void 0}var oa=class{_module;constructor(r){this._module=r}malloc(r){let n=this._module._malloc(r);return{ptr:n,size:r,dispose:()=>this.free({ptr:n,size:r,dispose:()=>{}})}}free(r){this._module._free(r.ptr)}dataToHeap(r){let n=this.malloc(r.byteLength);return this._module.HEAPU8.set(r,n.ptr),n}heapView(r){return this._module.HEAPU8.subarray(r.ptr,r.ptr+r.size)}heapToUint8Array(r){return new Uint8Array([...this.heapView(r)])}lengthBytes(r){return this._module.lengthBytesUTF8(r)}stringToHeap(r){let n=this.lengthBytes(r)+1,o=this._module._malloc(n);return this._module.stringToUTF8(r,o,n),{ptr:o,size:n,dispose:()=>this.free({ptr:o,size:n,dispose:()=>{}})}}heapToString(r){return this._module.UTF8ToString(r.ptr,r.size)}hasFilesystem(){let r=this._module;return r.FS_createPath!==void 0&&r.FS_createDataFile!==void 0&&r.FS_preloadFile!==void 0&&r.FS_unlink!==void 0}createPath(r,n=!0,o=!0){return this._module.FS_createPath("/",r,n,o)}createDataFile(r,n,o=!0,s=!0,i=!0){return this._module.FS_createDataFile("/",r,n,o,s,i)}preloadFile(r,n,o=!0,s=!0,i=!1,u=!0,h=!1){return this._module.FS_preloadFile("/",r,n,o,s,i,u,h)}unlink(r){return this._module.FS_unlink(r)}},Ne,ia=4294967295;function He(r,n){if(!Number.isInteger(r)||r<0||r>ia)throw new Error(`${n} length ${r} is outside the WASM32-safe range`)}function ht(r){if(r.length===0)return new Uint8Array(0);if(r.length===1)return r[0];let n=0;for(let i of r)n+=i.length;let o=new Uint8Array(n),s=0;for(let i of r)o.set(i,s),s+=i.length;return o}var sa=class sr{_mainModule;_zstdClass;_zstd;_compressionLevel;_decompressFrameCompleted=!1;_decompressRemaining=0;_decompressSawInput=!1;constructor(n){this._mainModule=new oa(n),this._zstdClass=n.zstd,this._zstd=new this._zstdClass,this._compressionLevel=this._zstdClass.defaultCLevel()}static load(){return Ne||(Ne=na().then(n=>new sr(n))),Ne}static unload(){aa(),Ne?.then(n=>{n?._zstd?.delete()}),Ne=void 0}copyHeap(n){return this._mainModule.heapView(n).slice()}mallocChecked(n,o){He(n,o);let s=this._mainModule.malloc(n);if(!s.ptr)throw this._mainModule.free(s),new Error(`Failed to allocate ${n} bytes for ${o}`);return s}throwStreamError(n,o){throw new Error(`${n} failed: ${o.errorName||"unknown error"}`)}ensureStreamOk(n,o){o.error&&this.throwStreamError(n,o)}version(){return this._zstdClass.version()}reset(){let n=this._zstd.reset();this.ensureStreamOk("reset",n),this._decompressFrameCompleted=!1,this._decompressRemaining=0,this._decompressSawInput=!1}resetCompression(n){n!==void 0&&(this._compressionLevel=n);let o=this._zstd.resetCompression(this._compressionLevel);this.ensureStreamOk("resetCompression",o)}resetDecompression(){let n=this._zstd.resetDecompression();this.ensureStreamOk("resetDecompression",n),this._decompressFrameCompleted=!1,this._decompressRemaining=0,this._decompressSawInput=!1}setCompressionLevel(n){let o=this._zstd.setCompressionLevel(n);this.ensureStreamOk("setCompressionLevel",o),this._compressionLevel=n}compress(n,o=this.defaultCLevel()){He(n.length,"compress input");let s=this._mainModule.dataToHeap(n);try{if(!s.ptr&&n.length>0)throw new Error("Failed to allocate compress input buffer");let i=this._zstdClass.compressBound(n.length),u=this.mallocChecked(i,"compress output");try{if(u.size=this._zstdClass.compress(u.ptr,i,s.ptr,s.size,o),this._zstdClass.isError(u.size))throw new Error(`compress failed: ${this._zstdClass.getErrorName(u.size)}`);return this.copyHeap(u)}finally{this._mainModule.free(u)}}finally{this._mainModule.free(s)}}compressChunk(n){if(He(n.length,"compressChunk input"),n.length===0)return new Uint8Array(0);let o=this._mainModule.dataToHeap(n);try{if(!o.ptr)throw new Error("Failed to allocate compressChunk input buffer");let s=this._zstdClass.CStreamOutSize(),i=[],u=0;for(;u0&&(h.size=w.produced,i.push(this.copyHeap(h)))}finally{this._mainModule.free(h)}}return ht(i)}finally{this._mainModule.free(o)}}compressEnd(){let n=this._zstdClass.CStreamOutSize(),o=[],s=1;for(;s!==0;){let i=this.mallocChecked(n,"compressEnd output");try{let u=this._zstd.compressEnd(i.ptr,n);if(this.ensureStreamOk("compressEnd",u),u.produced===0&&u.remaining!==0)throw new Error("compressEnd failed: no progress while finishing stream");s=u.remaining,u.produced>0&&(i.size=u.produced,o.push(this.copyHeap(i)))}finally{this._mainModule.free(i)}}return ht(o)}frameContentSize(n){return this._zstdClass.getFrameContentSize(n.ptr,n.size)}decompress(n){He(n.length,"decompress input");let o=this._mainModule.dataToHeap(n);try{if(!o.ptr&&n.length>0)throw new Error("Failed to allocate decompress input buffer");let s=this.frameContentSize(o);if(s.error)throw new Error(`Failed to get frame content size: ${s.errorName}`);let i=s.known;if(i){let u=this._zstdClass.findFrameCompressedSize(o.ptr,o.size);if(this._zstdClass.isError(u))throw new Error(`Failed to find frame compressed size: ${this._zstdClass.getErrorName(u)}`);u0?o.ptr+u:0,b=this._zstd.decompressChunk(w.ptr,s,M,U);if(this.ensureStreamOk("decompressChunk",b),b.consumed===0&&b.produced===0){if(U===0){b.remaining>0&&(this._decompressRemaining=b.remaining);break}throw new Error("decompressChunk failed: no progress while consuming input")}u+=b.consumed,h=b.produced===s&&b.remaining!==0,b.produced>0&&(w.size=b.produced,i.push(this.copyHeap(w))),b.remaining===0?(this._decompressFrameCompleted=!0,this._decompressRemaining=0):this._decompressRemaining=b.remaining}finally{this._mainModule.free(w)}}return ht(i)}finally{this._mainModule.free(o)}}decompressEnd(){if(!this._decompressSawInput)throw new Error("decompressEnd failed: empty compressed input is not a completed frame");if(!this._decompressFrameCompleted||this._decompressRemaining!==0)throw new Error("decompressEnd failed: truncated Zstandard input")}defaultCLevel(){return this._zstdClass.defaultCLevel()}minCLevel(){return this._zstdClass.minCLevel()}maxCLevel(){return this._zstdClass.maxCLevel()}};let gt=null;function la(){return gt||(gt=sa.load()),gt}function ua(r){return r.length>=4&&r[0]===40&&r[1]===181&&r[2]===47&&r[3]===253}function bt(r){const n="SQLite format 3\0";if(r.length/g,">").replace(/"/g,""").replace(/'/g,"'")}function er(r,n,o){const s=r.tagsList[0]??"",i=r.tagsList.length>1?` +${r.tagsList.length-1}`:"",u=Ue(r.tagsList.join(", ")),h=s?`${Ue(s)}${i}`:"",w=r.more.size>0?'':"";return`
`+(o?lr(r,n):"")+"
"}function lr(r,n){const o=[...r.more.entries()].map(([s,i])=>{const u=n.get(s);return`
${u?Ue(u.name):`Поле #${s}`}
${Ue(i)}
`}).join("");return o?`
${o}
`:""}function da(r,n){r.innerHTML=` - -
-

📚 Слова

-
- - -
-

-
База ещё не проверена.
-
-
-
- `;const o=r.querySelector("#home-db-banner"),s=r.querySelector("#home-db-text"),i=r.querySelector("#home-db-go"),u=r.querySelector("#words-search"),h=r.querySelector("#words-group"),w=r.querySelector("#words-count"),U=r.querySelector("#words-status"),M=r.querySelector("#words-list"),b=r.querySelector("#words-more");function F(g,C){o.hidden=!1,s.textContent=g,i.hidden=!1}function N(){o.hidden=!0}i.addEventListener("click",()=>{document.querySelector('.drawer-btn[data-page="sync"]')?.click()});let y=!1,Q=new Map,m=0,x=[],I=null,X=0,R=!1,Y=0,K=0;function E(){const g=h.value;if(g==="")return{search:u.value.trim(),groupId:null};const C=Number(g);return{search:u.value.trim(),groupId:Number.isFinite(C)?C:null}}function O(){b.hidden=!(y&&x.lengther(g,Q,g.id===I)).join(""),w.textContent=m>0?`Показано ${x.length} из ${m}`:"",O()}function ee(g){if(I===g){g!=null&&G(g),I=null;return}I!=null&&G(I),I=g,g!=null&&re(g)}function G(g){const C=M.querySelector(`.word-row-wrap[data-word-id="${g}"]`);if(!C)return;const k=C.querySelector(".word-row"),P=C.querySelector(".word-extra");k&&(k.classList.remove("open"),k.setAttribute("aria-expanded","false")),P&&(P.hidden=!0,P.innerHTML="")}function re(g){const C=x.find(fe=>fe.id===g),k=M.querySelector(`.word-row-wrap[data-word-id="${g}"]`);if(!C||!k)return;const P=k.querySelector(".word-row"),_=k.querySelector(".word-extra");P&&(P.classList.add("open"),P.setAttribute("aria-expanded","true")),_&&(_.hidden=!1,_.innerHTML=lr(C,Q))}function V(g){U.textContent=g,U.hidden=g===""}async function j(){if(!y||R)return;R=!0;const g=++Y,C=E();b.disabled=!0,x.length===0&&V("Загрузка слов…");try{const[k,P]=await Promise.all([Nn({search:C.search,groupId:C.groupId??void 0}),jt({search:C.search,groupId:C.groupId??void 0,limit:At,offset:0})]);if(g!==Y)return;m=k,x=P,X=P.length,I!=null&&!x.some(_=>_.id===I)&&(I=null),D(),V(P.length===0?"По этому запросу слов нет.":""),P.length===0&&m===0&&(w.textContent="Слов в базе пока нет.")}catch(k){if(g!==Y)return;V(`Не удалось загрузить слова: ${k instanceof Error?k.message:String(k)}`)}finally{g===Y&&(R=!1,b.disabled=!1,O())}}async function H(){if(!y||R||x.length>=m)return;R=!0;const g=++Y,C=E();b.disabled=!0,b.textContent="Загрузка…";try{const k=await jt({search:C.search,groupId:C.groupId??void 0,limit:At,offset:X});if(g!==Y)return;x=x.concat(k),X+=k.length,M.insertAdjacentHTML("beforeend",k.map(P=>er(P,Q,P.id===I)).join("")),w.textContent=`Показано ${x.length} из ${m}`,O()}catch(k){if(g!==Y)return;V(`Не удалось догрузить: ${k instanceof Error?k.message:String(k)}`)}finally{g===Y&&(R=!1,b.disabled=!1,O())}}u.addEventListener("input",()=>{window.clearTimeout(K),K=window.setTimeout(()=>{j()},300)}),u.addEventListener("keydown",g=>{g.key==="Enter"&&(window.clearTimeout(K),j())}),h.addEventListener("change",()=>{j()}),b.addEventListener("click",()=>{H()}),M.addEventListener("click",g=>{const C=g.target.closest(".word-row");if(!C||C.disabled)return;const k=Number(C.dataset.wordId);Number.isFinite(k)&&ee(I===k?null:k)}),(async()=>{if(!await Ge()){F("Локальной базы нет — скачай сохранение."),V("Нет локальной базы — скачай сохранение на странице «Синхронизация»."),w.textContent="";return}try{const C=await qn();if(!bt(C)){F("Файл в OPFS не похож на SQLite — перекачай сохранение.",!0),V("Файл в OPFS не похож на SQLite — перекачай сохранение.");return}N();try{const[P,_]=await Promise.all([Hn(),Pn()]),fe=P;Q=new Map(_.map(ue=>[ue.id,ue])),h.innerHTML=''+fe.map(ue=>``).join(""),y=!0,await j(),h.options[0].textContent=`Все группы (${m})`}catch(P){V(`БД есть, но слова не прочитались: ${P instanceof Error?P.message:String(P)}`)}}catch(C){F(`Не удалось прочитать базу: ${C instanceof Error?C.message:String(C)}`)}})()}const tr=24,pa=/^[A-Za-z0-9]{24}$/,ur="japlearn_sync_token";function rr(r){return r.trim().replace(/\s+/g,"")}function be(r){return pa.test(r)}function fa(){try{return localStorage.getItem(ur)??""}catch{return""}}function wt(r){try{localStorage.setItem(ur,r)}catch{}}const cr="https://learning.micialware.ru";function ha(r,n=cr){return`${n.replace(/\/+$/,"")}/download/${encodeURIComponent(r)}`}async function ga(r,n,o=cr){const s=ha(r,o);let i;try{i=await fetch(s,{method:"GET",...n})}catch(h){throw new Error(`Нет связи с сервером: ${h instanceof Error?h.message:String(h)}`)}if(!i.ok)throw i.status===404?new Error("Сохранение не найдено (404). Проверь токен."):new Error(`Сервер ответил ${i.status} ${i.statusText}`);const u=await i.arrayBuffer();if(u.byteLength===0)throw new Error("Сервер вернул пустой файл");return new Uint8Array(u)}function wa(r){r.innerHTML=` -
-

📡 Синхронизация

-

Токен сохранения — 24 символа: латинские буквы и цифры.

- - - -
- - 0 / 24 -
- -
- - -
- -

Введите токен из 24 символов

-
- `;const n=r.querySelector("#token-input"),o=r.querySelector("#token-error"),s=r.querySelector("#token-counter"),i=r.querySelector("#btn-download"),u=r.querySelector("#btn-upload"),h=r.querySelector("#status");function w(y){h.textContent=y,console.log(`[JapLearn] ${y}`)}function U(){return rr(n.value)}function M(y){i.disabled=y||!be(U()),u.disabled=!0,n.disabled=y,y||Ge().then(Q=>{!n.disabled&&be(U())&&(u.disabled=!Q)})}function b(){const y=U(),Q=y.length;s.textContent=`${Q} / ${tr}`;const m=be(y),x=Q===0;n.classList.toggle("invalid",!x&&!m),n.setAttribute("aria-invalid",String(!x&&!m)),x?o.textContent="":Q!==tr?o.textContent=`Нужно 24 символа, сейчас ${Q}`:o.textContent=m?"":"Только латинские буквы и цифры",i.disabled=!m,m?Ge().then(I=>{n.disabled||(u.disabled=!I)}):u.disabled=!0}async function F(){const y=U();if(be(y)){wt(y),M(!0),w("Скачивание сохранения...");try{const Q=await ga(y);w(`Скачано ${(Q.length/1024).toFixed(1)} КБ, распаковка...`);const m=await ca(Q);w(`Распаковано ${(m.length/1024).toFixed(1)} КБ, сохранение в OPFS...`),await _n(m),w(`Готово: база ${(m.length/1024).toFixed(1)} КБ сохранена локально (OPFS).`)}catch(Q){w(`Ошибка скачивания: ${Q instanceof Error?Q.message:String(Q)}`)}finally{M(!1),b()}}}n.addEventListener("input",()=>{b()}),n.addEventListener("change",()=>{const y=U();n.value=y,be(y)&&(wt(y),w("Токен сохранён локально. Можно скачивать или выгружать.")),b()}),i.addEventListener("click",()=>{F()}),u.addEventListener("click",()=>{const y=U();be(y)&&(wt(y),w("Выгрузка — следующий шаг (POST /upload/stream/{id})."))});const N=fa();N&&(n.value=N),b(),be(rr(N))&&Ge().then(y=>{w(y?"Токен восстановлен, локальная база на месте.":"Токен восстановлен. Нажми «Скачать», чтобы получить базу."),b()})}const ma={home:"Главная",sync:"Синхронизация"};function Re(r){const n=document.getElementById(r);if(!n)throw new Error(`[JapLearn] Не найден элемент #${r}`);return n}const dr=Re("burger-btn"),We=Re("drawer"),pr=Re("drawer-overlay"),va=Re("page-title"),nr=Re("page");let Et=!1;function Ie(r){Et=r,We.classList.toggle("open",r),pr.hidden=!r,dr.setAttribute("aria-expanded",String(r)),We.setAttribute("aria-hidden",String(!r)),document.body.classList.toggle("drawer-open",r)}function ya(r){We.querySelectorAll(".drawer-btn").forEach(n=>{n.classList.toggle("active",n.dataset.page===r)})}function fr(r){va.textContent=ma[r],ya(r),r==="home"?da(nr):wa(nr)}dr.addEventListener("click",()=>{Ie(!Et)});pr.addEventListener("click",()=>{Ie(!1)});document.addEventListener("keydown",r=>{r.key==="Escape"&&Et&&Ie(!1)});We.querySelectorAll(".drawer-btn").forEach(r=>{r.addEventListener("click",()=>{const n=r.dataset.page;(n==="home"||n==="sync")&&fr(n),Ie(!1)})});await kn();Ie(!1);fr("home");console.log("[JapLearn] crossOriginIsolated =",window.crossOriginIsolated); diff --git a/dist/assets/index-Dqxd5Tgf.js b/dist/assets/index-Dqxd5Tgf.js new file mode 100644 index 0000000..62abbe2 --- /dev/null +++ b/dist/assets/index-Dqxd5Tgf.js @@ -0,0 +1,59 @@ +(function(){const n=document.createElement("link").relList;if(n&&n.supports&&n.supports("modulepreload"))return;for(const o of document.querySelectorAll('link[rel="modulepreload"]'))s(o);new MutationObserver(o=>{for(const c of o)if(c.type==="childList")for(const h of c.addedNodes)h.tagName==="LINK"&&h.rel==="modulepreload"&&s(h)}).observe(document,{childList:!0,subtree:!0});function i(o){const c={};return o.integrity&&(c.integrity=o.integrity),o.referrerPolicy&&(c.referrerPolicy=o.referrerPolicy),o.crossOrigin==="use-credentials"?c.credentials="include":o.crossOrigin==="anonymous"?c.credentials="omit":c.credentials="same-origin",c}function s(o){if(o.ep)return;o.ep=!0;const c=i(o);fetch(o.href,c)}})();const Pe=new Worker(new URL("/assets/db-worker-AHwpujSZ.js",import.meta.url),{type:"module"});let ir=0,Ge=null;const je=new Map;function Tn(){return Ge||(Ge=new Promise((t,n)=>{Pe.onmessage=s=>{const o=s.data;if(o.type==="ready")return;const c=je.get(o.id);c&&(je.delete(o.id),o.type=="success"?c.resolve(o.data):c.reject(new Error(o.error??o.message??"Неизвестная ошибка Worker")))},Pe.onerror=s=>{console.error("[SQLite Worker] Ошибка:",s),n(new Error("Ошибка Worker"))};const i=++ir;je.set(i,{resolve:t,reject:n}),Pe.postMessage({type:"start",id:i})}),Ge)}function Qn(t,n){return new Promise((i,s)=>{if(!Pe){s(new Error("Worker не создан"));return}const o=++ir;je.set(o,{resolve:i,reject:s}),Pe.postMessage({type:t,id:o,...n})})}async function Re(t,n){return await Qn("query",{sql:t,params:n??[]})}function Nn(t){if(t==null)return[];const n=String(t).trim();return n?n.split(/[,\s;]+/).map(i=>i.trim()).filter(i=>i.length>0):[]}function Fn(t){const n=new Map;if(t==null)return n;const i=String(t);if(!i)return n;const s=i.split("");for(let o=0;o+10?`WHERE ${n.join(" AND ")}`:"",params:i}}async function qn(t={}){const{clause:n,params:i}=or(t),o=(await Re(`SELECT COUNT(*) as cnt FROM words ${n}`,i))[0]?.cnt;return typeof o=="number"?o:Number(o??0)}async function At(t={}){const{clause:n,params:i}=or(t),s=Math.max(1,Math.min(t.limit??50,500)),o=Math.max(0,t.offset??0);return(await Re(`SELECT id, key, value, tags, more, group_id FROM words ${n} ORDER BY id LIMIT ? OFFSET ?`,[...i,s,o])).map(Hn)}async function Pn(){return(await Re("SELECT id, name FROM word_groups ORDER BY id")).map(n=>({id:Number(n.id),name:String(n.name??"")}))}async function Ln(){return(await Re("SELECT id, name, forward, backward, filter FROM decks ORDER BY id")).map(n=>({id:Number(n.id),name:String(n.name??""),forward:String(n.forward??""),backward:String(n.backward??""),filter:String(n.filter??"")}))}async function _n(){return(await Re("SELECT id, name, identifier FROM custom_fields ORDER BY id")).map(n=>({id:Number(n.id),name:String(n.name??""),identifier:String(n.identifier??"")}))}const kt="japanese_app.db";async function Et(){return navigator.storage.getDirectory()}async function Rn(t){t[18]=1,t[19]=1;const i=await(await Et()).getFileHandle(kt,{create:!0}),s=i.createSyncAccessHandle;if(typeof s=="function")try{const c=await s.call(i);try{c.truncate(0),c.write(t,{at:0}),c.flush()}finally{c.close()}return}catch{}const o=await i.createWritable();try{await o.truncate(0);const c=new Uint8Array(t.length);c.set(t),await o.write(c)}finally{await o.close()}}async function Sn(){const t=await Et();let n;try{n=await t.getFileHandle(kt)}catch{throw new Error("Локальная база не найдена — сначала скачай сохранение")}const i=await n.getFile();if(i.size===0)throw new Error("Локальная база пуста");return new Uint8Array(await i.arrayBuffer())}async function Le(){try{return(await(await(await Et()).getFileHandle(kt)).getFile()).size>0}catch{return!1}}var In=ArrayBuffer,z=Uint8Array,We=Uint16Array,Jn=Int16Array,tt=Int32Array,ht=function(t,n,i){if(z.prototype.slice)return z.prototype.slice.call(t,n,i);(n==null||n<0)&&(n=0),(i==null||i>t.length)&&(i=t.length);var s=new z(i-n);return s.set(t.subarray(n,i)),s},_e=function(t,n,i,s){if(z.prototype.fill)return z.prototype.fill.call(t,n,i,s);for((i==null||i<0)&&(i=0),(s==null||s>t.length)&&(s=t.length);it.length)&&(s=t.length);i2046MB)","invalid block type","FSE accuracy too high","match distance too far back","unexpected EOF"],B=function(t,n,i){var s=new Error(n||On[t]);if(s.code=t,Error.captureStackTrace&&Error.captureStackTrace(s,B),!i)throw s;return s},er=function(t,n,i){for(var s=0,o=0;s>>0},zn=function(t,n){var i=t[0]|t[1]<<8|t[2]<<16;if(i==3126568&&t[3]==253){var s=t[4],o=s>>5&1,c=s>>2&1,h=s&3,w=s>>6;s&8&&B(0);var C=6-o,x=h==3?4:h,m=er(t,C,x);C+=x;var U=w?1<>3);y=Q+(Q>>3)*(t[5]&7)}y>2145386496&&B(1);var v=new z((n==1?E||y:n?0:y)+12);return v[0]=1,v[4]=4,v[8]=8,{b:C+U,y:0,l:0,d:m,w:n&&n!=1?n:v.subarray(12),e:y,o:new tt(v.buffer,0,3),u:E,c,m:Math.min(131072,y)}}else if((i>>4|t[3]<<20)==25481893)return Xn(t,4)+8;B(0)},Ce=function(t){for(var n=0;1<i&&B(3);for(var c=1<0;){var O=Ce(h+1),R=s>>3,Y=(1<>(s&7)&Y,M=(1<M&&(K-=X)),E[++w]=--K,K==-1?(h+=K,$[--m]=w):h-=K,!K)do{var ee=s>>3;C=(t[ee]|t[ee+1]<<8)>>(s&7)&3,s+=2,w+=C}while(C==3)}(w>255||h)&&B(0);for(var G=0,re=(c>>1)+(c>>3)+3,V=c-1,j=0;j<=w;++j){var H=E[j];if(H<1){y[j]=-H;continue}for(x=0;x=m)}}for(G&&B(0),x=0;x>3,{b:o,s:$,n:S,t:Q}]},Vn=function(t,n){var i=0,s=-1,o=new z(292),c=t[n],h=o.subarray(0,256),w=o.subarray(256,268),C=new We(o.buffer,268);if(c<128){var x=Se(t,n+1,6),m=x[0],U=x[1];n+=c;var E=m<<3,y=t[n];y||B(0);for(var Q=0,v=0,$=U.b,S=$,O=(++n<<3)-8+Ce(y);O-=$,!(O>3;if(Q+=(t[R]|t[R+1]<<8)>>(O&7)&(1<<$)-1,h[++s]=U.s[Q],O-=S,O>3,v+=(t[R]|t[R+1]<<8)>>(O&7)&(1<255&&B(0)}else{for(s=c-127;i>4,h[i+1]=Y&15}++n}var K=0;for(i=0;i11&&B(0),K+=M&&1<0;--i){var j=C[i];_e(V,i,j,C[i-1]=j+w[i]*(1<w&&U>3,y=(t[E]|t[E+1]<<8|t[E+2]<<16)>>(m&7);C=(C<>2,h=c<<1,w=c+h;qe(t.subarray(s,s+=t[0]|t[1]<<8),n.subarray(0,c),i),qe(t.subarray(s,s+=t[2]|t[3]<<8),n.subarray(c,h),i),qe(t.subarray(s,s+=t[4]|t[5]<<8),n.subarray(h,w),i),qe(t.subarray(s),n.subarray(w),i)},Wn=function(t,n,i){var s,o=n.b,c=t[o],h=c>>1&3;n.l=c&1;var w=c>>3|t[o+1]<<5|t[o+2]<<13,C=(o+=3)+w;if(h==1)return o>=t.length?void 0:(n.b=o+1,i?(_e(i,t[o],n.y,n.y+=w),i):_e(new z(w),t[o]));if(!(C>t.length)){if(h==0)return n.b=C,i?(i.set(t.subarray(o,C),n.y),n.y+=w,i):ht(t,o,C);if(h==2){var x=t[o],m=x&3,U=x>>2&3,E=x>>4,y=0,Q=0;m<2?U&1?E|=t[++o]<<4|(U&2&&t[++o]<<12):E=x>>3:(Q=U,U<2?(E|=(t[++o]&63)<<4,y=t[o]>>6|t[++o]<<2):U==2?(E|=t[++o]<<4|(t[++o]&3)<<12,y=t[o]>>2|t[++o]<<6):(E|=t[++o]<<4|(t[++o]&63)<<12,y=t[o]>>6|t[++o]<<2|t[++o]<<10)),++o;var v=i?i.subarray(n.y,n.y+n.m):new z(n.m),$=v.length-E;if(m==0)v.set(t.subarray(o,o+=E),$);else if(m==1)_e(v,t[o++],$);else{var S=n.h;if(m==2){var O=Vn(t,o);y+=o-(o=O[0]),n.h=S=O[1]}else S||B(0);(Q?jn:qe)(t.subarray(o,o+=y),v.subarray($),S)}var R=t[o++];if(R){R==255?R=(t[o++]|t[o++]<<8)+32512:R>127&&(R=R-128<<8|t[o++]);var Y=t[o++];Y&3&&B(0);for(var K=[Bn,Yn,Zn],M=2;M>-1;--M){var X=Y>>(M<<1)+2&3;if(X==1){var D=new z([0,0,t[o++]]);K[M]={s:D.subarray(2,3),n:D.subarray(0,1),t:new We(D.buffer,0,1),b:0}}else X==2?(s=Se(t,o,9-(M&1)),o=s[0],K[M]=s[1]):X==3&&(n.t||B(0),K[M]=n.t[M])}var ee=n.t=K,G=ee[0],re=ee[1],V=ee[2],j=t[C-1];j||B(0);var H=(C<<3)-8+Ce(j)-V.b,g=H>>3,k=0,T=(t[g]|t[g+1]<<8)>>(H&7)&(1<>3;var q=(t[g]|t[g+1]<<8)>>(H&7)&(1<>3;var P=(t[g]|t[g+1]<<8)>>(H&7)&(1<>3;var we=1<>>(H&7)&we-1);g=(H-=bt[Ee])>>3;var oe=Gn[Ee]+((t[g]|t[g+1]<<8|t[g+2]<<16)>>(H&7)&(1<>3;var he=Dn[fe]+((t[g]|t[g+1]<<8|t[g+2]<<16)>>(H&7)&(1<>3,T=V.t[T]+((t[g]|t[g+1]<<8)>>(H&7)&(1<>3,P=G.t[P]+((t[g]|t[g+1]<<8)>>(H&7)&(1<>3,q=re.t[q]+((t[g]|t[g+1]<<8)>>(H&7)&(1<3)n.o[2]=n.o[1],n.o[1]=n.o[0],n.o[0]=ne-=3;else{var ke=ne-(he!=0);ke?(ne=ke==3?n.o[0]-1:n.o[ke],ke>1&&(n.o[2]=n.o[1]),n.o[1]=n.o[0],n.o[0]=ne):ne=n.o[0]}for(var M=0;Moe&&(ae=oe);for(var M=0;M{throw e},s,o=console.log.bind(console),c=console.error.bind(console),h,w=!1,C,x=r=>r.startsWith("file://"),m=!1;function U(){return Ye.buffer}function E(){if(!D?.buffer?.resizable){var r=U();D=new Int8Array(r),Oe=new Int16Array(r),n.HEAPU8=T=new Uint8Array(r),$e=new Uint16Array(r),Xe=new Int32Array(r),P=new Uint32Array(r),Rt=new Float32Array(r),St=new Float64Array(r),Mt=new BigInt64Array(r),$t=new BigUint64Array(r)}}function y(){m=!0,Ne.A()}function Q(r){r=`Aborted(${r})`,c(r),w=!0,r+=". Build with -sASSERTIONS for more info.",m&&zt();var e=new WebAssembly.RuntimeError(r);throw e}var v;let $=()=>"";function S(r){if(r==v&&h)return new Uint8Array(h);throw"both async and sync fetching of the wasm failed"}async function O(r){if(!h)try{var e=await s(r);return new Uint8Array(e)}catch{}return S(r)}async function R(r,e){try{var a=await O(r),l=await WebAssembly.instantiate(a,e);return l}catch(u){c(`failed to asynchronously prepare wasm: ${u}`),Q(u)}}async function Y(r,e,a){if(!r&&!x(e))try{var l=fetch(e,{credentials:"same-origin"}),u=await WebAssembly.instantiateStreaming(l,a);return u}catch(d){c(`wasm streaming compile failed: ${d}`),c("falling back to ArrayBuffer instantiation")}return R(e,a)}function K(){var r={a:Mn};return r}async function M(){function r(d){return Ne=d.exports,xn(Ne),E(),Ne}function e(d){return r(d.instance)}var a=K();v??=$();var l=await Y(h,v,a),u=e(l);return u}class X{name="ExitStatus";constructor(e){this.message=`Program terminated with exit(${e})`,this.status=e}}var D,ee=()=>Gt,G=r=>{var e=r.getArg(ee(),0);return Yt(e)},re=()=>Bt(),V=r=>Vt(r),j=r=>Zt(r),H=globalThis.TextDecoder&&new TextDecoder,g=(r,e,a,l)=>{var u=e+a;if(l)return u;for(;r[e]&&!(e>=u);)++e;return e},k=(r,e=0,a,l)=>{var u=g(r,e,a,l);if(u-e>16&&r.buffer&&H)return H.decode(r.subarray(e,u));for(var d="";e>10,56320|N&1023)}}return d},T,q=(r,e,a)=>r?k(T,r,e,a):"",P,fe=r=>{var e=re(),a=j(4),l=j(4);Dt(r,a,l);var u=P[a>>2],d=P[l>>2],p=q(u);pe(u);var f;return d&&(f=q(d),pe(d)),V(e),[p,f]},ce=r=>{var e=G(r);return fe(e)},Ee=r=>{var e=new WebAssembly.Exception(ee(),[r],{traceStack:!0});throw e.message=ce(e),e},Ke=()=>Q(""),ve={},xe=r=>{for(;r.length;){var e=r.pop(),a=r.pop();a(e)}};function we(r){return this.fromWireType(P[r>>2])}var ne={},oe={},he={};class ke extends Error{constructor(e){super(e),this.name="InternalError"}}var ue=r=>{throw new ke(r)},ae=(r,e,a)=>{r.forEach(f=>he[f]=e);function l(f){var b=a(f);b.length!==r.length&&ue("Mismatched type converter count");for(var N=0;N{u[f]=oe[b],++p,p===d.length&&l(u)}));d.length===0&&l(u)},rt=r=>{var e=ve[r];delete ve[r];var a=e.rawConstructor,l=e.rawDestructor,u=e.fields,d=u.map(p=>p.getterReturnType).concat(u.map(p=>p.setterArgumentType));ae([r],d,p=>{var f={};for(var[b,N]of u.entries()){let F=p[b],I=N.getter,_=N.getterContext,J=p[b+u.length],W=N.setter,ie=N.setterContext;f[N.fieldName]={read:A=>F.fromWireType(I(_,A)),write:(A,Z)=>{var me=[];W(ie,A,J.toWireType(me,Z)),xe(me)},optional:F.optional}}return[{name:e.name,fromWireType:F=>{var I={};for(var _ in f)I[_]=f[_].read(F);return l(F),I},toWireType:(F,I)=>{for(var _ in f)if(!(_ in I)&&!f[_].optional)throw new TypeError(`Missing field: "${_}"`);var J=a();for(_ in f)f[_].write(J,I[_]);return F!==null&&F.push(l,J),J},readValueFromPointer:we,destructorFunction:l}]})},te=r=>{for(var e="";;){var a=T[r++];if(!a)return e;e+=String.fromCharCode(a)}};class Me extends Error{constructor(e){super(e),this.name="BindingError"}}var L=r=>{throw new Me(r)};function wr(r,e,a={}){var l=e.name;if(r||L(`type "${l}" must have a positive integer typeid pointer`),oe.hasOwnProperty(r)){if(a.ignoreDuplicateRegistrations)return;L(`Cannot register type '${l}' twice`)}if(oe[r]=e,delete he[r],ne.hasOwnProperty(r)){var u=ne[r];delete ne[r],u.forEach(d=>d())}}function de(r,e,a={}){return wr(r,e,a)}var Oe,$e,Xe,Mt,$t,Tt=(r,e,a)=>{switch(e){case 1:return a?l=>D[l]:l=>T[l];case 2:return a?l=>Oe[l>>1]:l=>$e[l>>1];case 4:return a?l=>Xe[l>>2]:l=>P[l>>2];case 8:return a?l=>Mt[l>>3]:l=>$t[l>>3];default:throw new TypeError(`invalid integer width (${e}): ${r}`)}},mr=(r,e,a,l,u)=>{e=te(e);let d=l===0n,p=f=>f;if(d){let f=a*8;p=b=>BigInt.asUintN(f,b),u=p(u)}de(r,{name:e,fromWireType:p,toWireType:(f,b)=>(typeof b=="number"&&(b=BigInt(b)),b),readValueFromPointer:Tt(e,a,!d),destructorFunction:null})},vr=(r,e,a,l)=>{e=te(e),de(r,{name:e,fromWireType:function(u){return!!u},toWireType:function(u,d){return d?a:l},readValueFromPointer:function(u){return this.fromWireType(T[u])},destructorFunction:null})},yr=r=>({count:r.count,deleteScheduled:r.deleteScheduled,preservePointerOnDelete:r.preservePointerOnDelete,ptr:r.ptr,ptrType:r.ptrType,smartPtr:r.smartPtr,smartPtrType:r.smartPtrType}),nt=r=>{function e(a){return a.$$.ptrType.registeredClass.name}L(e(r)+" instance already deleted")},at=!1,Qt=r=>{},br=r=>{r.smartPtr?r.smartPtrType.rawDestructor(r.smartPtr):r.ptrType.registeredClass.rawDestructor(r.ptr)},Nt=r=>{r.count.value-=1;var e=r.count.value===0;e&&br(r)},Te=r=>globalThis.FinalizationRegistry?(at=new FinalizationRegistry(e=>{Nt(e.$$)}),Te=e=>{var a=e.$$,l=!!a.smartPtr;if(l){var u={$$:a};at.register(e,u,e)}return e},Qt=e=>at.unregister(e),Te(r)):(Te=e=>e,r),Ur=()=>{let r=ze.prototype;Object.assign(r,{isAliasOf(a){if(!(this instanceof ze)||!(a instanceof ze))return!1;var l=this.$$.ptrType.registeredClass,u=this.$$.ptr;a.$$=a.$$;for(var d=a.$$.ptrType.registeredClass,p=a.$$.ptr;l.baseClass;)u=l.upcast(u),l=l.baseClass;for(;d.baseClass;)p=d.upcast(p),d=d.baseClass;return l===d&&u===p},clone(){if(this.$$.ptr||nt(this),this.$$.preservePointerOnDelete)return this.$$.count.value+=1,this;var a=Te(Object.create(Object.getPrototypeOf(this),{$$:{value:yr(this.$$)}}));return a.$$.count.value+=1,a.$$.deleteScheduled=!1,a},delete(){this.$$.ptr||nt(this),this.$$.deleteScheduled&&!this.$$.preservePointerOnDelete&&L("Object already scheduled for deletion"),Qt(this),Nt(this.$$),this.$$.preservePointerOnDelete||(this.$$.smartPtr=void 0,this.$$.ptr=void 0)},isDeleted(){return!this.$$.ptr},deleteLater(){return this.$$.ptr||nt(this),this.$$.deleteScheduled&&!this.$$.preservePointerOnDelete&&L("Object already scheduled for deletion"),this.$$.deleteScheduled=!0,this}});let e=Symbol.dispose;e&&(r[e]=r.delete)};function ze(){}var Ft=(r,e)=>Object.defineProperty(e,"name",{value:r}),Ht={},it=(r,e,a)=>{if(r[e].overloadTable===void 0){var l=r[e];r[e]=function(...u){return r[e].overloadTable.hasOwnProperty(u.length)||L(`Function '${a}' called with an invalid number of arguments (${u.length}) - expects one of (${r[e].overloadTable})!`),r[e].overloadTable[u.length].apply(this,u)},r[e].overloadTable=[],r[e].overloadTable[l.argCount]=l}},Cr=(r,e,a)=>{n.hasOwnProperty(r)?(L(`Cannot register public name '${r}' twice`),it(n,r,r),n[r].overloadTable.hasOwnProperty(a)&&L(`Cannot register multiple overloads of a function with the same number of arguments (${a})!`),n[r].overloadTable[a]=e):(n[r]=e,n[r].argCount=a)},kr=48,Er=57,xr=r=>{r=r.replace(/[^a-zA-Z0-9_]/g,"$");var e=r.charCodeAt(0);return e>=kr&&e<=Er?`_${r}`:r};function Mr(r,e,a,l,u,d,p,f){this.name=r,this.constructor=e,this.instancePrototype=a,this.rawDestructor=l,this.baseClass=u,this.getActualType=d,this.upcast=p,this.downcast=f,this.pureVirtualFunctions=[]}var ot=(r,e,a)=>{for(;e!==a;)e.upcast||L(`Expected null or instance of ${a.name}, got an instance of ${e.name}`),r=e.upcast(r),e=e.baseClass;return r},st=r=>{if(r===null)return"null";var e=typeof r;return e==="object"||e==="array"||e==="function"?r.toString():""+r};function $r(r,e){if(e===null)return this.isReference&&L(`null is not a valid ${this.name}`),0;e.$$||L(`Cannot pass "${st(e)}" as a ${this.name}`),e.$$.ptr||L(`Cannot pass deleted object as a pointer of type ${this.name}`);var a=e.$$.ptrType.registeredClass,l=ot(e.$$.ptr,a,this.registeredClass);return l}function Tr(r,e){var a;if(e===null)return this.isReference&&L(`null is not a valid ${this.name}`),this.isSmartPointer?(a=this.rawConstructor(),r!==null&&r.push(this.rawDestructor,a),a):0;(!e||!e.$$)&&L(`Cannot pass "${st(e)}" as a ${this.name}`),e.$$.ptr||L(`Cannot pass deleted object as a pointer of type ${this.name}`),!this.isConst&&e.$$.ptrType.isConst&&L(`Cannot convert argument of type ${e.$$.smartPtrType?e.$$.smartPtrType.name:e.$$.ptrType.name} to parameter type ${this.name}`);var l=e.$$.ptrType.registeredClass;if(a=ot(e.$$.ptr,l,this.registeredClass),this.isSmartPointer)switch(e.$$.smartPtr===void 0&&L("Passing raw pointer to smart pointer is illegal"),this.sharingPolicy){case 0:e.$$.smartPtrType===this?a=e.$$.smartPtr:L(`Cannot convert argument of type ${e.$$.smartPtrType?e.$$.smartPtrType.name:e.$$.ptrType.name} to parameter type ${this.name}`);break;case 1:a=e.$$.smartPtr;break;case 2:if(e.$$.smartPtrType===this)a=e.$$.smartPtr;else{var u=e.clone();a=this.rawShare(a,ut.toHandle(()=>u.delete())),r!==null&&r.push(this.rawDestructor,a)}break;default:L("Unsupported sharing policy")}return a}function Qr(r,e){if(e===null)return this.isReference&&L(`null is not a valid ${this.name}`),0;e.$$||L(`Cannot pass "${st(e)}" as a ${this.name}`),e.$$.ptr||L(`Cannot pass deleted object as a pointer of type ${this.name}`),e.$$.ptrType.isConst&&L(`Cannot convert argument of type ${e.$$.ptrType.name} to parameter type ${this.name}`);var a=e.$$.ptrType.registeredClass,l=ot(e.$$.ptr,a,this.registeredClass);return l}var qt=(r,e,a)=>{if(e===a)return r;if(a.baseClass===void 0)return null;var l=qt(r,e,a.baseClass);return l===null?null:a.downcast(l)},Nr={},Fr=(r,e)=>{for(e===void 0&&L("ptr should not be undefined");r.baseClass;)e=r.upcast(e),r=r.baseClass;return e},Hr=(r,e)=>(e=Fr(r,e),Nr[e]),Ve=(r,e)=>{(!e.ptrType||!e.ptr)&&ue("makeClassHandle requires ptr and ptrType");var a=!!e.smartPtrType,l=!!e.smartPtr;return a!==l&&ue("Both smartPtrType and smartPtr must be specified"),e.count={value:1},Te(Object.create(r,{$$:{value:e,writable:!0}}))};function qr(r){var e=this.getPointee(r);if(!e)return this.destructor(r),null;var a=Hr(this.registeredClass,e);if(a!==void 0){if(a.$$.count.value===0)return a.$$.ptr=e,a.$$.smartPtr=r,a.clone();var l=a.clone();return this.destructor(r),l}function u(){return this.isSmartPointer?Ve(this.registeredClass.instancePrototype,{ptrType:this.pointeeType,ptr:e,smartPtrType:this,smartPtr:r}):Ve(this.registeredClass.instancePrototype,{ptrType:this,ptr:r})}var d=this.registeredClass.getActualType(e),p=Ht[d];if(!p)return u.call(this);var f;this.isConst?f=p.constPointerType:f=p.pointerType;var b=qt(e,this.registeredClass,f.registeredClass);return b===null?u.call(this):this.isSmartPointer?Ve(f.registeredClass.instancePrototype,{ptrType:f,ptr:b,smartPtrType:this,smartPtr:r}):Ve(f.registeredClass.instancePrototype,{ptrType:f,ptr:b})}var Pr=()=>{Object.assign(Ze.prototype,{getPointee(r){return this.rawGetPointee&&(r=this.rawGetPointee(r)),r},destructor(r){this.rawDestructor?.(r)},readValueFromPointer:we,fromWireType:qr})};function Ze(r,e,a,l,u,d,p,f,b,N,F){this.name=r,this.registeredClass=e,this.isReference=a,this.isConst=l,this.isSmartPointer=u,this.pointeeType=d,this.sharingPolicy=p,this.rawGetPointee=f,this.rawConstructor=b,this.rawShare=N,this.rawDestructor=F,!u&&e.baseClass===void 0?l?(this.toWireType=$r,this.destructorFunction=null):(this.toWireType=Qr,this.destructorFunction=null):this.toWireType=Tr}var Lr=(r,e,a)=>{n.hasOwnProperty(r)||ue("Replacing nonexistent public symbol"),n[r].overloadTable!==void 0&&a!==void 0?n[r].overloadTable[a]=e:(n[r]=e,n[r].argCount=a)},_r=r=>jt.get(r),le=(r,e,a=!1)=>{r=te(r);function l(){var d=_r(e);return d}var u=l();return typeof u!="function"&&L(`unknown function pointer with signature ${r}: ${e}`),u};class Rr extends Error{}var Sr=r=>{var e=Ot(r),a=te(e);return pe(e),a},Be=(r,e)=>{var a=[],l={};function u(d){if(!l[d]&&!oe[d]){if(he[d]){he[d].forEach(u);return}a.push(d),l[d]=!0}}throw e.forEach(u),new Rr(`${r}: `+a.map(Sr).join([", "]))},Ir=(r,e,a,l,u,d,p,f,b,N,F,I,_)=>{F=te(F),d=le(u,d),f&&=le(p,f),N&&=le(b,N),_=le(I,_);var J=xr(F);Cr(J,function(){Be(`Cannot construct ${F} due to unbound types`,[l])}),ae([r,e,a],l?[l]:[],W=>{W=W[0];var ie,A;l?(ie=W.registeredClass,A=ie.instancePrototype):A=ze.prototype;var Z=Ft(F,function(...ft){if(Object.getPrototypeOf(this)!==me)throw new Me(`Use 'new' to construct ${F}`);if(se.constructor_body===void 0)throw new Me(`${F} has no accessible constructor`);var Wt=se.constructor_body[ft.length];if(Wt===void 0)throw new Me(`Tried to invoke ctor of ${F} with invalid number of parameters (${ft.length}) - expected (${Object.keys(se.constructor_body).toString()}) parameters instead!`);return Wt.apply(this,ft)}),me=Object.create(A,{constructor:{value:Z}});Z.prototype=me;var se=new Mr(F,Z,me,_,ie,d,f,N);se.baseClass&&(se.baseClass.__derivedClasses??=[],se.baseClass.__derivedClasses.push(se));var pt=new Ze(F,se,!0,!1,!1),ge=new Ze(F+"*",se,!1,!1,!1),De=new Ze(F+" const*",se,!1,!0,!1);return Ht[r]={pointerType:ge,constPointerType:De},Lr(J,Z),[pt,ge,De]})};function Jr(r){for(var e=1;e{for(var a=[],l=0;l>2]);return a},Pt=r=>{r=r.trim();let e=r.indexOf("(");return e===-1?r:r.slice(0,e)},Kr=(r,e,a,l,u,d,p,f,b)=>{var N=ct(a,l);e=te(e),e=Pt(e),d=le(u,d,f),ae([],[r],F=>{F=F[0];var I=`${F.name}.${e}`;function _(){Be(`Cannot call ${I} due to unbound types`,N)}e.startsWith("@@")&&(e=Symbol[e.substring(2)]);var J=F.registeredClass.constructor;return J[e]===void 0?(_.argCount=a-1,J[e]=_):(it(J,e,I),J[e].overloadTable[a-1]=_),ae([],N,W=>{var ie=[W[0],null].concat(W.slice(1)),A=lt(I,ie,null,d,p);if(J[e].overloadTable===void 0?(A.argCount=a-1,J[e]=A):J[e].overloadTable[a-1]=A,F.registeredClass.__derivedClasses)for(let Z of F.registeredClass.__derivedClasses)Z.constructor.hasOwnProperty(e)||(Z.constructor[e]=A);return[]}),[]})},Or=(r,e,a,l,u,d)=>{var p=ct(e,a);u=le(l,u),ae([],[r],f=>{f=f[0];var b=`constructor ${f.name}`;if(f.registeredClass.constructor_body===void 0&&(f.registeredClass.constructor_body=[]),f.registeredClass.constructor_body[e-1]!==void 0)throw new Me(`Cannot register multiple constructors with identical number of parameters (${e-1}) for class '${f.name}'! Overload resolution is currently only performed using the parameter count, not actual type info!`);return f.registeredClass.constructor_body[e-1]=()=>{Be(`Cannot construct ${f.name} due to unbound types`,p)},ae([],p,N=>(N.splice(1,0,null),f.registeredClass.constructor_body[e-1]=lt(b,N,null,u,d),[])),[]})},Xr=(r,e,a,l,u,d,p,f,b,N)=>{var F=ct(a,l);e=te(e),e=Pt(e),d=le(u,d,b),ae([],[r],I=>{I=I[0];var _=`${I.name}.${e}`;e.startsWith("@@")&&(e=Symbol[e.substring(2)]),f&&I.registeredClass.pureVirtualFunctions.push(e);function J(){Be(`Cannot call ${_} due to unbound types`,F)}var W=I.registeredClass.instancePrototype,ie=W[e];return ie===void 0||ie.overloadTable===void 0&&ie.className!==I.name&&ie.argCount===a-2?(J.argCount=a-2,J.className=I.name,W[e]=J):(it(W,e,_),W[e].overloadTable[a-2]=J),ae([],F,A=>{var Z=lt(_,A,I,d,p);return W[e].overloadTable===void 0?(Z.argCount=a-2,W[e]=Z):W[e].overloadTable[a-2]=Z,[]}),[]})},Lt=[],ye=[0,1,,1,null,1,!0,1,!1,1],_t=[],zr=r=>{if(r>9&&--ye[r+1]===0){var e=ye[r];ye[r]=void 0;var a=_t[r];a&&(_t[r]=void 0,a(e)),Lt.push(r)}},ut={toValue:r=>(r||L(`Cannot use deleted val. handle = ${r}`),ye[r]),toHandle:r=>{switch(r){case void 0:return 2;case null:return 4;case!0:return 6;case!1:return 8;default:{let e=Lt.pop()||ye.length;return ye[e]=r,ye[e+1]=1,e}}}},Vr={name:"emscripten::val",fromWireType:r=>{var e=ut.toValue(r);return zr(r),e},toWireType:(r,e)=>ut.toHandle(e),readValueFromPointer:we,destructorFunction:null},Zr=r=>de(r,Vr),Rt,St,Br=(r,e)=>{switch(e){case 4:return function(a){return this.fromWireType(Rt[a>>2])};case 8:return function(a){return this.fromWireType(St[a>>3])};default:throw new TypeError(`invalid float width (${e}): ${r}`)}},Yr=(r,e,a)=>{e=te(e),de(r,{name:e,fromWireType:l=>l,toWireType:(l,u)=>u,readValueFromPointer:Br(e,a),destructorFunction:null})},Dr=(r,e,a,l,u)=>{e=te(e);let d=l===0,p=b=>b;if(d){var f=32-8*a;p=b=>b<>>f,u=p(u)}de(r,{name:e,fromWireType:p,toWireType:(b,N)=>N,readValueFromPointer:Tt(e,a,l!==0),destructorFunction:null})},Gr=(r,e,a)=>{var l=[Int8Array,Uint8Array,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array,BigInt64Array,BigUint64Array],u=l[e];function d(p){var f=P[p>>2],b=P[p+4>>2];return new u(D.buffer,b,f)}a=te(a),de(r,{name:a,fromWireType:d,readValueFromPointer:d},{ignoreDuplicateRegistrations:!0})},jr=(r,e,a,l)=>{if(!(l>0))return 0;for(var u=a,d=a+l-1,p=0;p=d)break;e[a++]=f}else if(f<=2047){if(a+1>=d)break;e[a++]=192|f>>6,e[a++]=128|f&63}else if(f<=65535){if(a+2>=d)break;e[a++]=224|f>>12,e[a++]=128|f>>6&63,e[a++]=128|f&63}else{if(a+3>=d)break;e[a++]=240|f>>18,e[a++]=128|f>>12&63,e[a++]=128|f>>6&63,e[a++]=128|f&63,p++}}return e[a]=0,a-u},It=(r,e,a)=>jr(r,T,e,a),Jt=r=>{for(var e=0,a=0;a=55296&&l<=57343?(e+=4,++a):e+=3}return e},Wr=(r,e)=>{e=te(e),de(r,{name:e,fromWireType(a){var l=P[a>>2],u=a+4,d;return d=q(u,l,!0),pe(a),d},toWireType(a,l){l instanceof ArrayBuffer&&(l=new Uint8Array(l));var u,d=typeof l=="string";d||ArrayBuffer.isView(l)&&l.BYTES_PER_ELEMENT==1||L("Cannot pass non-string to std::string"),d?u=Jt(l):u=l.length;var p=dt(4+u+1),f=p+4;return P[p>>2]=u,d?It(l,f,u+1):T.set(l,f),a!==null&&a.push(pe,p),p},readValueFromPointer:we,destructorFunction(a){pe(a)}})},Kt=globalThis.TextDecoder?new TextDecoder("utf-16le"):void 0,Ar=(r,e,a)=>{var l=r>>1,u=g($e,l,e/2,a);if(u-l>16&&Kt)return Kt.decode($e.subarray(l,u));for(var d="",p=l;p{if(a<2)return 0;a-=2;for(var l=e,u=a>1]=p,e+=2}return Oe[e>>1]=0,e-l},tn=r=>r.length*2,rn=(r,e,a)=>{for(var l="",u=r>>2,d=0;!(d>=e/4);d++){var p=P[u+d];if(!p&&!a)break;l+=String.fromCodePoint(p)}return l},nn=(r,e,a=2147483647)=>{if(a<4)return 0;for(var l=e,u=l+a-4,d=0;d65535&&d++,Xe[e>>2]=p,e+=4,e+4>u)break}return Xe[e>>2]=0,e-l},an=r=>{for(var e=0,a=0;a65535&&a++,e+=4}return e},on=(r,e,a)=>{a=te(a);var l,u,d;e===2?(l=Ar,u=en,d=tn):(l=rn,u=nn,d=an),de(r,{name:a,fromWireType:p=>{var f=P[p>>2],b=l(p+4,f*e,!0);return pe(p),b},toWireType:(p,f)=>{typeof f!="string"&&L(`Cannot pass non-string to C++ string type ${a}`);var b=d(f),N=dt(4+b+e);return P[N>>2]=b/e,u(f,N+4,b+e),p!==null&&p.push(pe,N),N},readValueFromPointer:we,destructorFunction(p){pe(p)}})},sn=(r,e,a,l,u,d)=>{ve[r]={name:te(e),rawConstructor:le(a,l),rawDestructor:le(u,d),fields:[]}},ln=(r,e,a,l,u,d,p,f,b,N)=>{ve[r].fields.push({fieldName:te(e),getterReturnType:a,getter:le(l,u),getterContext:d,setterArgumentType:p,setter:le(f,b),setterContext:N})},cn=(r,e)=>{e=te(e),de(r,{isVoid:!0,name:e,fromWireType:()=>{},toWireType:(a,l)=>{}})},un=()=>{},Qe={},dn=r=>{if(r instanceof X||r=="unwind")return C;i(1,r)},pn=r=>{C=r,i(r,new X(r))},fn=r=>{if(!w)try{return r()}catch(e){dn(e)}},hn=()=>performance.now(),gn=(r,e)=>{if(Qe[r]&&(clearTimeout(Qe[r].id),delete Qe[r]),!e)return 0;var a=setTimeout(()=>{delete Qe[r],fn(()=>Xt(r,hn()))},e);return Qe[r]={id:a,timeout_ms:e},0},wn=()=>2147483648,mn=(r,e)=>Math.ceil(r/e)*e,vn=r=>{var e=Ye.buffer.byteLength,a=(r-e+65535)/65536|0;try{return Ye.grow(a),E(),1}catch{}},yn=r=>{var e=T.length;r>>>=0;var a=wn();if(r>a)return!1;for(var l=1;l<=4;l*=2){var u=e*(1+.2/l);u=Math.min(u,r+100663296);var d=Math.min(a,mn(Math.max(r,u),65536)),p=vn(d);if(p)return!0}return!1},bn=r=>52;function Un(r,e,a,l){return 70}var Cn=[null,[],[]],kn=(r,e)=>{var a=Cn[r];!e||e===10?((r===1?o:c)(k(a)),a.length=0):a.push(e)},En=(r,e,a,l)=>{for(var u=0,d=0;d>2],f=P[e+4>>2];e+=8;for(var b=0;b>2]=u,0};Ur(),Pr(),n.wasmBinary&&(h=n.wasmBinary),n.UTF8ToString=q,n.stringToUTF8=It,n.lengthBytesUTF8=Jt;var Ot,dt,pe,Xt,zt,Vt,Zt,Bt,Yt,Dt,Gt,Ye,jt;function xn(r){Ot=r.B,dt=n._malloc=r.C,pe=n._free=r.D,Xt=r.F,zt=r.G,Vt=r.H,Zt=r.I,Bt=r.J,Yt=r.K,Dt=r.L,Ye=r.z,jt=r.E,Gt=r.M}var Mn={t:Ee,x:Ke,f:rt,i:mr,l:vr,o:Ir,b:Kr,n:Or,d:Xr,y:Zr,h:Yr,c:Dr,a:Gr,k:Wr,g:on,j:sn,e:ln,m:cn,w:un,p:gn,u:yn,s:bn,q:Un,r:En,v:pn};async function $n(){!w&&y()}var Ne;return Ne=await M(),await $n(),n}var ra=ta,na=new Int8Array([-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,62,90,63,64,65,66,-1,67,68,69,70,71,-1,72,73,52,53,54,55,56,57,58,59,60,61,74,75,76,77,78,79,80,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,81,-1,82,83,84,85,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,86,87,88,89,-1]);function aa(t){let n=new Uint8Array(170930),i=0,s=0,o=0,c=-1;for(let h=0,w=t.length;h127)continue;let x=na[C];if(!(x<0))if(c<0)c=x;else{c+=x*91,s|=c<88?13:14;do n[i++]=s,s>>>=8,o-=8;while(o>7);c=-1}}return c>=0&&(n[i++]=(s|c<""})}function sa(){Ut=void 0}var la=class{_module;constructor(t){this._module=t}malloc(t){let n=this._module._malloc(t);return{ptr:n,size:t,dispose:()=>this.free({ptr:n,size:t,dispose:()=>{}})}}free(t){this._module._free(t.ptr)}dataToHeap(t){let n=this.malloc(t.byteLength);return this._module.HEAPU8.set(t,n.ptr),n}heapView(t){return this._module.HEAPU8.subarray(t.ptr,t.ptr+t.size)}heapToUint8Array(t){return new Uint8Array([...this.heapView(t)])}lengthBytes(t){return this._module.lengthBytesUTF8(t)}stringToHeap(t){let n=this.lengthBytes(t)+1,i=this._module._malloc(n);return this._module.stringToUTF8(t,i,n),{ptr:i,size:n,dispose:()=>this.free({ptr:i,size:n,dispose:()=>{}})}}heapToString(t){return this._module.UTF8ToString(t.ptr,t.size)}hasFilesystem(){let t=this._module;return t.FS_createPath!==void 0&&t.FS_createDataFile!==void 0&&t.FS_preloadFile!==void 0&&t.FS_unlink!==void 0}createPath(t,n=!0,i=!0){return this._module.FS_createPath("/",t,n,i)}createDataFile(t,n,i=!0,s=!0,o=!0){return this._module.FS_createDataFile("/",t,n,i,s,o)}preloadFile(t,n,i=!0,s=!0,o=!1,c=!0,h=!1){return this._module.FS_preloadFile("/",t,n,i,s,o,c,h)}unlink(t){return this._module.FS_unlink(t)}},Fe,ca=4294967295;function He(t,n){if(!Number.isInteger(t)||t<0||t>ca)throw new Error(`${n} length ${t} is outside the WASM32-safe range`)}function gt(t){if(t.length===0)return new Uint8Array(0);if(t.length===1)return t[0];let n=0;for(let o of t)n+=o.length;let i=new Uint8Array(n),s=0;for(let o of t)i.set(o,s),s+=o.length;return i}var ua=class lr{_mainModule;_zstdClass;_zstd;_compressionLevel;_decompressFrameCompleted=!1;_decompressRemaining=0;_decompressSawInput=!1;constructor(n){this._mainModule=new la(n),this._zstdClass=n.zstd,this._zstd=new this._zstdClass,this._compressionLevel=this._zstdClass.defaultCLevel()}static load(){return Fe||(Fe=oa().then(n=>new lr(n))),Fe}static unload(){sa(),Fe?.then(n=>{n?._zstd?.delete()}),Fe=void 0}copyHeap(n){return this._mainModule.heapView(n).slice()}mallocChecked(n,i){He(n,i);let s=this._mainModule.malloc(n);if(!s.ptr)throw this._mainModule.free(s),new Error(`Failed to allocate ${n} bytes for ${i}`);return s}throwStreamError(n,i){throw new Error(`${n} failed: ${i.errorName||"unknown error"}`)}ensureStreamOk(n,i){i.error&&this.throwStreamError(n,i)}version(){return this._zstdClass.version()}reset(){let n=this._zstd.reset();this.ensureStreamOk("reset",n),this._decompressFrameCompleted=!1,this._decompressRemaining=0,this._decompressSawInput=!1}resetCompression(n){n!==void 0&&(this._compressionLevel=n);let i=this._zstd.resetCompression(this._compressionLevel);this.ensureStreamOk("resetCompression",i)}resetDecompression(){let n=this._zstd.resetDecompression();this.ensureStreamOk("resetDecompression",n),this._decompressFrameCompleted=!1,this._decompressRemaining=0,this._decompressSawInput=!1}setCompressionLevel(n){let i=this._zstd.setCompressionLevel(n);this.ensureStreamOk("setCompressionLevel",i),this._compressionLevel=n}compress(n,i=this.defaultCLevel()){He(n.length,"compress input");let s=this._mainModule.dataToHeap(n);try{if(!s.ptr&&n.length>0)throw new Error("Failed to allocate compress input buffer");let o=this._zstdClass.compressBound(n.length),c=this.mallocChecked(o,"compress output");try{if(c.size=this._zstdClass.compress(c.ptr,o,s.ptr,s.size,i),this._zstdClass.isError(c.size))throw new Error(`compress failed: ${this._zstdClass.getErrorName(c.size)}`);return this.copyHeap(c)}finally{this._mainModule.free(c)}}finally{this._mainModule.free(s)}}compressChunk(n){if(He(n.length,"compressChunk input"),n.length===0)return new Uint8Array(0);let i=this._mainModule.dataToHeap(n);try{if(!i.ptr)throw new Error("Failed to allocate compressChunk input buffer");let s=this._zstdClass.CStreamOutSize(),o=[],c=0;for(;c0&&(h.size=w.produced,o.push(this.copyHeap(h)))}finally{this._mainModule.free(h)}}return gt(o)}finally{this._mainModule.free(i)}}compressEnd(){let n=this._zstdClass.CStreamOutSize(),i=[],s=1;for(;s!==0;){let o=this.mallocChecked(n,"compressEnd output");try{let c=this._zstd.compressEnd(o.ptr,n);if(this.ensureStreamOk("compressEnd",c),c.produced===0&&c.remaining!==0)throw new Error("compressEnd failed: no progress while finishing stream");s=c.remaining,c.produced>0&&(o.size=c.produced,i.push(this.copyHeap(o)))}finally{this._mainModule.free(o)}}return gt(i)}frameContentSize(n){return this._zstdClass.getFrameContentSize(n.ptr,n.size)}decompress(n){He(n.length,"decompress input");let i=this._mainModule.dataToHeap(n);try{if(!i.ptr&&n.length>0)throw new Error("Failed to allocate decompress input buffer");let s=this.frameContentSize(i);if(s.error)throw new Error(`Failed to get frame content size: ${s.errorName}`);let o=s.known;if(o){let c=this._zstdClass.findFrameCompressedSize(i.ptr,i.size);if(this._zstdClass.isError(c))throw new Error(`Failed to find frame compressed size: ${this._zstdClass.getErrorName(c)}`);c0?i.ptr+c:0,m=this._zstd.decompressChunk(w.ptr,s,x,C);if(this.ensureStreamOk("decompressChunk",m),m.consumed===0&&m.produced===0){if(C===0){m.remaining>0&&(this._decompressRemaining=m.remaining);break}throw new Error("decompressChunk failed: no progress while consuming input")}c+=m.consumed,h=m.produced===s&&m.remaining!==0,m.produced>0&&(w.size=m.produced,o.push(this.copyHeap(w))),m.remaining===0?(this._decompressFrameCompleted=!0,this._decompressRemaining=0):this._decompressRemaining=m.remaining}finally{this._mainModule.free(w)}}return gt(o)}finally{this._mainModule.free(i)}}decompressEnd(){if(!this._decompressSawInput)throw new Error("decompressEnd failed: empty compressed input is not a completed frame");if(!this._decompressFrameCompleted||this._decompressRemaining!==0)throw new Error("decompressEnd failed: truncated Zstandard input")}defaultCLevel(){return this._zstdClass.defaultCLevel()}minCLevel(){return this._zstdClass.minCLevel()}maxCLevel(){return this._zstdClass.maxCLevel()}};let wt=null;function da(){return wt||(wt=ua.load()),wt}function pa(t){return t.length>=4&&t[0]===40&&t[1]===181&&t[2]===47&&t[3]===253}function Ct(t){const n="SQLite format 3\0";if(t.length/g,">").replace(/"/g,""").replace(/'/g,"'")}function rr(t,n,i){const s=t.tagsList[0]??"",o=t.tagsList.length>1?` +${t.tagsList.length-1}`:"",c=Ue(t.tagsList.join(", ")),h=s?`${Ue(s)}${o}`:"",w=t.more.size>0?'':"";return`
`+(i?cr(t,n):"")+"
"}function cr(t,n){const i=[...t.more.entries()].map(([s,o])=>{const c=n.get(s);return`
${c?Ue(c.name):`Поле #${s}`}
${Ue(o)}
`}).join("");return i?`
${i}
`:""}function ha(t,n){t.innerHTML=` + +
+

📚 Слова

+
+ + +
+

+
База ещё не проверена.
+
+
+
+ `;const i=t.querySelector("#home-db-banner"),s=t.querySelector("#home-db-text"),o=t.querySelector("#home-db-go"),c=t.querySelector("#words-search"),h=t.querySelector("#words-group"),w=t.querySelector("#words-count"),C=t.querySelector("#words-status"),x=t.querySelector("#words-list"),m=t.querySelector("#words-more");function U(g,k){i.hidden=!1,s.textContent=g,o.hidden=!1}function E(){i.hidden=!0}o.addEventListener("click",()=>{document.querySelector('.drawer-btn[data-page="sync"]')?.click()});let y=!1,Q=new Map,v=0,$=[],S=null,O=0,R=!1,Y=0,K=0;function M(){const g=h.value;if(g==="")return{search:c.value.trim(),groupId:null};const k=Number(g);return{search:c.value.trim(),groupId:Number.isFinite(k)?k:null}}function X(){m.hidden=!(y&&$.lengthrr(g,Q,g.id===S)).join(""),w.textContent=v>0?`Показано ${$.length} из ${v}`:"",X()}function ee(g){if(S===g){g!=null&&G(g),S=null;return}S!=null&&G(S),S=g,g!=null&&re(g)}function G(g){const k=x.querySelector(`.word-row-wrap[data-word-id="${g}"]`);if(!k)return;const T=k.querySelector(".word-row"),q=k.querySelector(".word-extra");T&&(T.classList.remove("open"),T.setAttribute("aria-expanded","false")),q&&(q.hidden=!0,q.innerHTML="")}function re(g){const k=$.find(fe=>fe.id===g),T=x.querySelector(`.word-row-wrap[data-word-id="${g}"]`);if(!k||!T)return;const q=T.querySelector(".word-row"),P=T.querySelector(".word-extra");q&&(q.classList.add("open"),q.setAttribute("aria-expanded","true")),P&&(P.hidden=!1,P.innerHTML=cr(k,Q))}function V(g){C.textContent=g,C.hidden=g===""}async function j(){if(!y||R)return;R=!0;const g=++Y,k=M();m.disabled=!0,$.length===0&&V("Загрузка слов…");try{const[T,q]=await Promise.all([qn({search:k.search,groupId:k.groupId??void 0}),At({search:k.search,groupId:k.groupId??void 0,limit:tr,offset:0})]);if(g!==Y)return;v=T,$=q,O=q.length,S!=null&&!$.some(P=>P.id===S)&&(S=null),D(),V(q.length===0?"По этому запросу слов нет.":""),q.length===0&&v===0&&(w.textContent="Слов в базе пока нет.")}catch(T){if(g!==Y)return;V(`Не удалось загрузить слова: ${T instanceof Error?T.message:String(T)}`)}finally{g===Y&&(R=!1,m.disabled=!1,X())}}async function H(){if(!y||R||$.length>=v)return;R=!0;const g=++Y,k=M();m.disabled=!0,m.textContent="Загрузка…";try{const T=await At({search:k.search,groupId:k.groupId??void 0,limit:tr,offset:O});if(g!==Y)return;$=$.concat(T),O+=T.length,x.insertAdjacentHTML("beforeend",T.map(q=>rr(q,Q,q.id===S)).join("")),w.textContent=`Показано ${$.length} из ${v}`,X()}catch(T){if(g!==Y)return;V(`Не удалось догрузить: ${T instanceof Error?T.message:String(T)}`)}finally{g===Y&&(R=!1,m.disabled=!1,X())}}c.addEventListener("input",()=>{window.clearTimeout(K),K=window.setTimeout(()=>{j()},300)}),c.addEventListener("keydown",g=>{g.key==="Enter"&&(window.clearTimeout(K),j())}),h.addEventListener("change",()=>{j()}),m.addEventListener("click",()=>{H()}),x.addEventListener("click",g=>{const k=g.target.closest(".word-row");if(!k||k.disabled)return;const T=Number(k.dataset.wordId);Number.isFinite(T)&&ee(S===T?null:T)}),(async()=>{if(!await Le()){U("Локальной базы нет — скачай сохранение."),V("Нет локальной базы — скачай сохранение на странице «Синхронизация»."),w.textContent="";return}try{const k=await Sn();if(!Ct(k)){U("Файл в OPFS не похож на SQLite — перекачай сохранение.",!0),V("Файл в OPFS не похож на SQLite — перекачай сохранение.");return}E();try{const[q,P]=await Promise.all([Pn(),_n()]),fe=q;Q=new Map(P.map(ce=>[ce.id,ce])),h.innerHTML=''+fe.map(ce=>``).join(""),y=!0,await j(),h.options[0].textContent=`Все группы (${v})`}catch(q){V(`БД есть, но слова не прочитались: ${q instanceof Error?q.message:String(q)}`)}}catch(k){U(`Не удалось прочитать базу: ${k instanceof Error?k.message:String(k)}`)}})()}function Ae(t){return t.replace(/&/g,"&").replace(//g,">").replace(/"/g,""").replace(/'/g,"'")}function ga(t,n){const i=[t.forward,t.backward].filter(s=>s.trim().length>0).join(" → ");return`
`+(n?ur(t):"")+"
"}function ur(t){return`
${[["forward",t.forward],["backward",t.backward],["filter",t.filter]].map(([s,o])=>`
${Ae(s)}
${o?Ae(o):'—'}
`).join("")}
`}function wa(t){t.innerHTML=` +
+

🗂️ Колоды

+

+
Проверка локальной базы…
+
+
+ `;const n=t.querySelector("#decks-count"),i=t.querySelector("#decks-status"),s=t.querySelector("#decks-list");let o=[],c=null;function h(m){i.textContent=m,i.hidden=m===""}function w(m){const U=s.querySelector(`.word-row-wrap[data-deck-id="${m}"]`);if(!U)return;const E=U.querySelector(".word-row"),y=U.querySelector(".word-extra");E&&(E.classList.remove("open"),E.setAttribute("aria-expanded","false")),y&&(y.hidden=!0,y.innerHTML="")}function C(m){const U=o.find(v=>v.id===m),E=s.querySelector(`.word-row-wrap[data-deck-id="${m}"]`);if(!U||!E)return;const y=E.querySelector(".word-row"),Q=E.querySelector(".word-extra");y&&(y.classList.add("open"),y.setAttribute("aria-expanded","true")),Q&&(Q.hidden=!1,Q.innerHTML=ur(U))}function x(m){if(c===m){m!=null&&w(m),c=null;return}c!=null&&w(c),c=m,m!=null&&C(m)}s.addEventListener("click",m=>{const U=m.target.closest(".word-row");if(!U)return;const E=Number(U.dataset.deckId);Number.isFinite(E)&&x(c===E?null:E)}),(async()=>{if(!await Le()){h("Нет локальной базы — скачай сохранение на странице «Синхронизация»."),n.textContent="";return}h("Загрузка колод…");try{if(o=await Ln(),o.length===0){n.textContent="Колоды пока отсутствуют.",h(""),s.innerHTML="";return}n.textContent=`Всего: ${o.length}`,h(""),s.innerHTML=o.map(U=>ga(U,U.id===c)).join("")}catch(U){h(`Не удалось загрузить колоды: ${U instanceof Error?U.message:String(U)}`)}})()}const nr=24,ma=/^[A-Za-z0-9]{24}$/,dr="japlearn_sync_token";function ar(t){return t.trim().replace(/\s+/g,"")}function be(t){return ma.test(t)}function va(){try{return localStorage.getItem(dr)??""}catch{return""}}function mt(t){try{localStorage.setItem(dr,t)}catch{}}const pr="https://learning.micialware.ru";function ya(t,n=pr){return`${n.replace(/\/+$/,"")}/download/${encodeURIComponent(t)}`}async function ba(t,n,i=pr){const s=ya(t,i);let o;try{o=await fetch(s,{method:"GET",...n})}catch(h){throw new Error(`Нет связи с сервером: ${h instanceof Error?h.message:String(h)}`)}if(!o.ok)throw o.status===404?new Error("Сохранение не найдено (404). Проверь токен."):new Error(`Сервер ответил ${o.status} ${o.statusText}`);const c=await o.arrayBuffer();if(c.byteLength===0)throw new Error("Сервер вернул пустой файл");return new Uint8Array(c)}function Ua(t){t.innerHTML=` +
+

📡 Синхронизация

+

Токен сохранения — 24 символа: латинские буквы и цифры.

+ + + +
+ + 0 / 24 +
+ +
+ + +
+ +

Введите токен из 24 символов

+
+ `;const n=t.querySelector("#token-input"),i=t.querySelector("#token-error"),s=t.querySelector("#token-counter"),o=t.querySelector("#btn-download"),c=t.querySelector("#btn-upload"),h=t.querySelector("#status");function w(y){h.textContent=y,console.log(`[JapLearn] ${y}`)}function C(){return ar(n.value)}function x(y){o.disabled=y||!be(C()),c.disabled=!0,n.disabled=y,y||Le().then(Q=>{!n.disabled&&be(C())&&(c.disabled=!Q)})}function m(){const y=C(),Q=y.length;s.textContent=`${Q} / ${nr}`;const v=be(y),$=Q===0;n.classList.toggle("invalid",!$&&!v),n.setAttribute("aria-invalid",String(!$&&!v)),$?i.textContent="":Q!==nr?i.textContent=`Нужно 24 символа, сейчас ${Q}`:i.textContent=v?"":"Только латинские буквы и цифры",o.disabled=!v,v?Le().then(S=>{n.disabled||(c.disabled=!S)}):c.disabled=!0}async function U(){const y=C();if(be(y)){mt(y),x(!0),w("Скачивание сохранения...");try{const Q=await ba(y);w(`Скачано ${(Q.length/1024).toFixed(1)} КБ, распаковка...`);const v=await fa(Q);w(`Распаковано ${(v.length/1024).toFixed(1)} КБ, сохранение в OPFS...`),await Rn(v),w(`Готово: база ${(v.length/1024).toFixed(1)} КБ сохранена локально (OPFS).`)}catch(Q){w(`Ошибка скачивания: ${Q instanceof Error?Q.message:String(Q)}`)}finally{x(!1),m()}}}n.addEventListener("input",()=>{m()}),n.addEventListener("change",()=>{const y=C();n.value=y,be(y)&&(mt(y),w("Токен сохранён локально. Можно скачивать или выгружать.")),m()}),o.addEventListener("click",()=>{U()}),c.addEventListener("click",()=>{const y=C();be(y)&&(mt(y),w("Выгрузка — следующий шаг (POST /upload/stream/{id})."))});const E=va();E&&(n.value=E),m(),be(ar(E))&&Le().then(y=>{w(y?"Токен восстановлен, локальная база на месте.":"Токен восстановлен. Нажми «Скачать», чтобы получить базу."),m()})}const Ca={home:"Главная",decks:"Колоды",sync:"Синхронизация"};function Ie(t){const n=document.getElementById(t);if(!n)throw new Error(`[JapLearn] Не найден элемент #${t}`);return n}const fr=Ie("burger-btn"),et=Ie("drawer"),hr=Ie("drawer-overlay"),ka=Ie("page-title"),vt=Ie("page");let xt=!1;function Je(t){xt=t,et.classList.toggle("open",t),hr.hidden=!t,fr.setAttribute("aria-expanded",String(t)),et.setAttribute("aria-hidden",String(!t)),document.body.classList.toggle("drawer-open",t)}function Ea(t){et.querySelectorAll(".drawer-btn").forEach(n=>{n.classList.toggle("active",n.dataset.page===t)})}function gr(t){ka.textContent=Ca[t],Ea(t),t==="home"?ha(vt):t==="decks"?wa(vt):Ua(vt)}fr.addEventListener("click",()=>{Je(!xt)});hr.addEventListener("click",()=>{Je(!1)});document.addEventListener("keydown",t=>{t.key==="Escape"&&xt&&Je(!1)});et.querySelectorAll(".drawer-btn").forEach(t=>{t.addEventListener("click",()=>{const n=t.dataset.page;(n==="home"||n==="decks"||n==="sync")&&gr(n),Je(!1)})});await Tn();Je(!1);gr("home");console.log("[JapLearn] crossOriginIsolated =",window.crossOriginIsolated); diff --git a/dist/assets/index-CXPiR0gG.css b/dist/assets/index-u8F3m7-8.css similarity index 99% rename from dist/assets/index-CXPiR0gG.css rename to dist/assets/index-u8F3m7-8.css index 1002fe7..9daad16 100644 --- a/dist/assets/index-CXPiR0gG.css +++ b/dist/assets/index-u8F3m7-8.css @@ -1 +1 @@ -:root{font-family:system-ui,-apple-system,Segoe UI,Roboto,sans-serif;line-height:1.5;color:#1e1b2e;background:#f4f1fa}*{box-sizing:border-box}body{margin:0;min-height:100dvh;display:flex;justify-content:center;padding:env(safe-area-inset-top) env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left)}#app{width:100%;max-width:480px;padding:24px 16px 32px;display:flex;flex-direction:column;gap:16px}.app-header h1{margin:0;font-size:1.75rem;letter-spacing:.02em}.app-subtitle{margin:4px 0 0;color:#6d6390}.top-bar{display:flex;align-items:center;gap:12px}.burger-btn{width:44px;height:44px;border:2px solid #d9d2f0;border-radius:12px;background:#fff;cursor:pointer;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:5px;touch-action:manipulation;flex:none}.burger-btn span{display:block;width:20px;height:2px;border-radius:2px;background:#4c446b}.burger-btn[aria-expanded=true]{border-color:#7c3aed}.top-bar-title h1{margin:0;font-size:1.4rem;line-height:1.2}.top-bar-title p{margin:0;font-size:.9rem;color:#6d6390}.top-bar-spacer{flex:1}.app-content{display:flex;flex-direction:column;gap:16px}.drawer-overlay{position:fixed;inset:0;background:#1e1b2e73;z-index:40}.drawer-overlay[hidden]{display:none}.drawer{position:fixed;top:0;left:0;bottom:0;width:min(300px,85vw);background:#fff;z-index:50;transform:translate(-105%);transition:transform .22s ease;display:flex;flex-direction:column;gap:8px;padding:20px 14px;box-shadow:8px 0 32px #1e1b2e2e}.drawer.open{transform:translate(0)}.drawer-header{padding:4px 8px 14px;border-bottom:1px solid #eee9fb;margin-bottom:8px}.drawer-logo{font-size:1.3rem;font-weight:800;color:#7c3aed}.drawer-subtitle{font-size:.9rem;color:#6d6390}.drawer-btn{border:none;background:transparent;text-align:left;font-size:1.05rem;font-weight:600;color:#1e1b2e;padding:13px 12px;border-radius:12px;cursor:pointer;touch-action:manipulation}.drawer-btn.active{background:#f1eafe;color:#6d28d9}.drawer-btn:active{background:#e9defc}body.drawer-open{overflow:hidden}.card{background:#fff;border-radius:16px;padding:20px 16px;box-shadow:0 8px 24px #7c3aed1f;display:flex;flex-direction:column;gap:12px}.card-title{margin:0;font-size:1.25rem}.card-hint{margin:0;color:#6d6390;font-size:.95rem}.field-label{font-weight:600;font-size:.95rem}.token-input{width:100%;padding:14px 12px;font-size:1.05rem;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;letter-spacing:.04em;border:2px solid #d9d2f0;border-radius:12px;outline:none}.token-input:focus{border-color:#7c3aed}.token-input.invalid{border-color:#dc2626;background:#fef2f2}.token-meta{display:flex;justify-content:space-between;align-items:baseline;gap:8px;min-height:1.4em}.token-error{color:#dc2626;font-size:.9rem}.token-counter{color:#6d6390;font-variant-numeric:tabular-nums;white-space:nowrap}.btn-row{display:flex;gap:12px}.btn{flex:1;padding:14px 12px;font-size:1rem;font-weight:600;border-radius:12px;border:2px solid #7c3aed;background:#fff;color:#7c3aed;cursor:pointer;touch-action:manipulation}.btn-primary{background:#7c3aed;color:#fff}.btn:disabled{opacity:.4;cursor:not-allowed}.btn:not(:disabled):active{transform:scale(.98)}.status-bar{margin:0;padding:10px 12px;border-radius:10px;background:#f4f1fa;color:#4c446b;font-size:.95rem;word-break:break-word}.status-bar[hidden]{display:none}.db-banner{display:flex;align-items:center;gap:8px;padding:8px 12px;border-radius:10px;background:#fff7e6;color:#7a5b00;font-size:.85rem}.db-banner[hidden]{display:none}.db-banner-text{flex:1;min-width:0}.db-banner-link{flex:none;border:none;background:transparent;padding:4px;font:inherit;font-weight:700;color:#7c3aed;cursor:pointer;touch-action:manipulation}.db-banner-link[hidden]{display:none}.words-toolbar{display:flex;gap:8px}.words-search{flex:1;min-width:0;padding:12px;font-size:1rem;border:2px solid #d9d2f0;border-radius:12px;outline:none;background:#fff;color:inherit}.words-search:focus{border-color:#7c3aed}.words-group{flex:none;max-width:42%;padding:12px 8px;font-size:.95rem;font-weight:600;color:#4c446b;border:2px solid #d9d2f0;border-radius:12px;background:#fff;outline:none}.words-group:focus{border-color:#7c3aed}.words-list{display:flex;flex-direction:column}.word-row-wrap{border-bottom:1px solid #eee9fb}.word-row-wrap:last-child{border-bottom:none}.word-row{display:flex;align-items:baseline;gap:8px;width:100%;padding:11px 4px;border:none;background:transparent;font:inherit;color:inherit;text-align:left;cursor:pointer;touch-action:manipulation;border-radius:8px}.word-row:disabled{cursor:default}.word-row:not(:disabled):active{background:#f4f1fa}.word-row.open{background:#f4f1fa}.word-main{flex:1;min-width:0;overflow-wrap:break-word}.word-key{font-weight:700}.word-sep{color:#6d6390}.word-value{color:#4c446b}.word-tag{flex:none;max-width:38%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:.8rem;color:#6d6390;text-align:right}.word-dot{flex:none;width:6px;height:6px;border-radius:50%;background:#7c3aed;opacity:.55;align-self:center}.word-extra[hidden]{display:none}.word-extra-list{margin:0 0 10px;padding:10px 12px;background:#f4f1fa;border-radius:10px;display:flex;flex-direction:column;gap:8px}.word-extra-row dt{font-size:.8rem;font-weight:700;color:#6d6390}.word-extra-row dd{margin:2px 0 0;word-break:break-word} +:root{font-family:system-ui,-apple-system,Segoe UI,Roboto,sans-serif;line-height:1.5;color:#1e1b2e;background:#f4f1fa}*{box-sizing:border-box}body{margin:0;min-height:100dvh;display:flex;justify-content:center;padding:env(safe-area-inset-top) env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left)}#app{width:100%;max-width:480px;padding:24px 16px 32px;display:flex;flex-direction:column;gap:16px}.app-header h1{margin:0;font-size:1.75rem;letter-spacing:.02em}.app-subtitle{margin:4px 0 0;color:#6d6390}.top-bar{display:flex;align-items:center;gap:12px}.burger-btn{width:44px;height:44px;border:2px solid #d9d2f0;border-radius:12px;background:#fff;cursor:pointer;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:5px;touch-action:manipulation;flex:none}.burger-btn span{display:block;width:20px;height:2px;border-radius:2px;background:#4c446b}.burger-btn[aria-expanded=true]{border-color:#7c3aed}.top-bar-title h1{margin:0;font-size:1.4rem;line-height:1.2}.top-bar-title p{margin:0;font-size:.9rem;color:#6d6390}.top-bar-spacer{flex:1}.app-content{display:flex;flex-direction:column;gap:16px}.drawer-overlay{position:fixed;inset:0;background:#1e1b2e73;z-index:40}.drawer-overlay[hidden]{display:none}.drawer{position:fixed;top:0;left:0;bottom:0;width:min(300px,85vw);background:#fff;z-index:50;transform:translate(-105%);transition:transform .22s ease;display:flex;flex-direction:column;gap:8px;padding:20px 14px;box-shadow:8px 0 32px #1e1b2e2e}.drawer.open{transform:translate(0)}.drawer-header{padding:4px 8px 14px;border-bottom:1px solid #eee9fb;margin-bottom:8px}.drawer-logo{font-size:1.3rem;font-weight:800;color:#7c3aed}.drawer-subtitle{font-size:.9rem;color:#6d6390}.drawer-btn{border:none;background:transparent;text-align:left;font-size:1.05rem;font-weight:600;color:#1e1b2e;padding:13px 12px;border-radius:12px;cursor:pointer;touch-action:manipulation}.drawer-btn.active{background:#f1eafe;color:#6d28d9}.drawer-btn:active{background:#e9defc}body.drawer-open{overflow:hidden}.card{background:#fff;border-radius:16px;padding:20px 16px;box-shadow:0 8px 24px #7c3aed1f;display:flex;flex-direction:column;gap:12px}.card-title{margin:0;font-size:1.25rem}.card-hint{margin:0;color:#6d6390;font-size:.95rem}.field-label{font-weight:600;font-size:.95rem}.token-input{width:100%;padding:14px 12px;font-size:1.05rem;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;letter-spacing:.04em;border:2px solid #d9d2f0;border-radius:12px;outline:none}.token-input:focus{border-color:#7c3aed}.token-input.invalid{border-color:#dc2626;background:#fef2f2}.token-meta{display:flex;justify-content:space-between;align-items:baseline;gap:8px;min-height:1.4em}.token-error{color:#dc2626;font-size:.9rem}.token-counter{color:#6d6390;font-variant-numeric:tabular-nums;white-space:nowrap}.btn-row{display:flex;gap:12px}.btn{flex:1;padding:14px 12px;font-size:1rem;font-weight:600;border-radius:12px;border:2px solid #7c3aed;background:#fff;color:#7c3aed;cursor:pointer;touch-action:manipulation}.btn-primary{background:#7c3aed;color:#fff}.btn:disabled{opacity:.4;cursor:not-allowed}.btn:not(:disabled):active{transform:scale(.98)}.status-bar{margin:0;padding:10px 12px;border-radius:10px;background:#f4f1fa;color:#4c446b;font-size:.95rem;word-break:break-word}.status-bar[hidden]{display:none}.db-banner{display:flex;align-items:center;gap:8px;padding:8px 12px;border-radius:10px;background:#fff7e6;color:#7a5b00;font-size:.85rem}.db-banner[hidden]{display:none}.db-banner-text{flex:1;min-width:0}.db-banner-link{flex:none;border:none;background:transparent;padding:4px;font:inherit;font-weight:700;color:#7c3aed;cursor:pointer;touch-action:manipulation}.db-banner-link[hidden]{display:none}.words-toolbar{display:flex;gap:8px}.words-search{flex:1;min-width:0;padding:12px;font-size:1rem;border:2px solid #d9d2f0;border-radius:12px;outline:none;background:#fff;color:inherit}.words-search:focus{border-color:#7c3aed}.words-group{flex:none;max-width:42%;padding:12px 8px;font-size:.95rem;font-weight:600;color:#4c446b;border:2px solid #d9d2f0;border-radius:12px;background:#fff;outline:none}.words-group:focus{border-color:#7c3aed}.words-list{display:flex;flex-direction:column}.word-row-wrap{border-bottom:1px solid #eee9fb}.word-row-wrap:last-child{border-bottom:none}.word-row{display:flex;align-items:baseline;gap:8px;width:100%;padding:11px 4px;border:none;background:transparent;font:inherit;color:inherit;text-align:left;cursor:pointer;touch-action:manipulation;border-radius:8px}.word-row:disabled{cursor:default}.word-row:not(:disabled):active{background:#f4f1fa}.word-row.open{background:#f4f1fa}.word-main{flex:1;min-width:0;overflow-wrap:break-word}.word-key{font-weight:700}.word-sep{color:#6d6390}.word-value{color:#4c446b}.word-tag{flex:none;max-width:38%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:.8rem;color:#6d6390;text-align:right}.word-dot{flex:none;width:6px;height:6px;border-radius:50%;background:#7c3aed;opacity:.55;align-self:center}.word-extra[hidden]{display:none}.word-extra-list{margin:0 0 10px;padding:10px 12px;background:#f4f1fa;border-radius:10px;display:flex;flex-direction:column;gap:8px}.word-extra-row dt{font-size:.8rem;font-weight:700;color:#6d6390}.word-extra-row dd{margin:2px 0 0;word-break:break-word}.empty-val{opacity:.5} diff --git a/dist/index.html b/dist/index.html index 18e917b..d79227d 100644 --- a/dist/index.html +++ b/dist/index.html @@ -5,8 +5,8 @@ JapLearn — интервальные повторения - - + +
@@ -30,6 +30,7 @@
Интервальные повторения
+ diff --git a/index.html b/index.html index 4c18f70..d537e3e 100644 --- a/index.html +++ b/index.html @@ -28,6 +28,7 @@
Интервальные повторения
+ diff --git a/src/db-types.ts b/src/db-types.ts index 5e02247..1ca2e6b 100644 --- a/src/db-types.ts +++ b/src/db-types.ts @@ -166,6 +166,17 @@ export async function getWordGroups(): Promise { })); } +export async function getDecks(): Promise { + const rows = await query("SELECT id, name, forward, backward, filter FROM decks ORDER BY id"); + return (rows as Record[]).map((r) => ({ + id: Number(r["id"]), + name: String(r["name"] ?? ""), + forward: String(r["forward"] ?? ""), + backward: String(r["backward"] ?? ""), + filter: String(r["filter"] ?? ""), + })); +} + export async function getCustomFields(): Promise { const rows = await query("SELECT id, name, identifier FROM custom_fields ORDER BY id"); return (rows as Record[]).map((r) => ({ diff --git a/src/decks-page.ts b/src/decks-page.ts new file mode 100644 index 0000000..8b4c488 --- /dev/null +++ b/src/decks-page.ts @@ -0,0 +1,139 @@ +// Страница «Колоды»: плоский список строк из таблицы decks 1:1. +// Никаких связей (states/history/words) здесь не додумываем — только колонки таблицы. + +import { getDecks } from './db-types.ts'; +import type { Deck } from './db-types.ts'; +import { hasDatabaseFile } from './opfs.ts'; + +function escapeHtml(s: string): string { + return s + .replace(/&/g, '&') + .replace(//g, '>') + .replace(/"/g, '"') + .replace(/'/g, '''); +} + +// Одна колода — плоская строка: имя слева, направление справа. +function deckRowHtml(d: Deck, expanded: boolean): string { + const dir = [d.forward, d.backward].filter((s) => s.trim().length > 0).join(' → '); + return `
` + + `` + + `
` + + (expanded ? deckExtraHtml(d) : '') + + `
`; +} + +// Раскрытие — сырые поля строки decks (имена колонок как в dbschema.sql). +function deckExtraHtml(d: Deck): string { + const rows: Array<[string, string]> = [ + ['forward', d.forward], + ['backward', d.backward], + ['filter', d.filter], + ]; + const html = rows + .map(([k, v]) => `
${escapeHtml(k)}
${v ? escapeHtml(v) : '—'}
`) + .join(''); + return `
${html}
`; +} + +export function renderDecksPage(root: HTMLElement): void { + root.innerHTML = ` +
+

🗂️ Колоды

+

+
Проверка локальной базы…
+
+
+ `; + + const countEl = root.querySelector('#decks-count')!; + const statusEl = root.querySelector('#decks-status')!; + const listEl = root.querySelector('#decks-list')!; + + let decks: Deck[] = []; + let expandedId: number | null = null; + + function setStatus(msg: string): void { + statusEl.textContent = msg; + statusEl.hidden = msg === ''; + } + + function collapseRow(id: number): void { + const wrap = listEl.querySelector(`.word-row-wrap[data-deck-id="${id}"]`); + if (!wrap) return; + const btn = wrap.querySelector('.word-row'); + const extra = wrap.querySelector('.word-extra'); + if (btn) { + btn.classList.remove('open'); + btn.setAttribute('aria-expanded', 'false'); + } + if (extra) { + extra.hidden = true; + extra.innerHTML = ''; + } + } + + function expandRow(id: number): void { + const d = decks.find((x) => x.id === id); + const wrap = listEl.querySelector(`.word-row-wrap[data-deck-id="${id}"]`); + if (!d || !wrap) return; + const btn = wrap.querySelector('.word-row'); + const extra = wrap.querySelector('.word-extra'); + if (btn) { + btn.classList.add('open'); + btn.setAttribute('aria-expanded', 'true'); + } + if (extra) { + extra.hidden = false; + extra.innerHTML = deckExtraHtml(d); + } + } + + function setExpanded(id: number | null): void { + if (expandedId === id) { + if (id != null) collapseRow(id); + expandedId = null; + return; + } + if (expandedId != null) collapseRow(expandedId); + expandedId = id; + if (id != null) expandRow(id); + } + + listEl.addEventListener('click', (e) => { + const btn = (e.target as HTMLElement).closest('.word-row'); + if (!btn) return; + const id = Number(btn.dataset.deckId); + if (!Number.isFinite(id)) return; + setExpanded(expandedId === id ? null : id); + }); + + void (async () => { + const has = await hasDatabaseFile(); + if (!has) { + setStatus('Нет локальной базы — скачай сохранение на странице «Синхронизация».'); + countEl.textContent = ''; + return; + } + setStatus('Загрузка колод…'); + try { + decks = await getDecks(); + if (decks.length === 0) { + countEl.textContent = 'Колоды пока отсутствуют.'; + setStatus(''); + listEl.innerHTML = ''; + return; + } + countEl.textContent = `Всего: ${decks.length}`; + setStatus(''); + listEl.innerHTML = decks.map((d) => deckRowHtml(d, d.id === expandedId)).join(''); + } catch (err) { + setStatus(`Не удалось загрузить колоды: ${err instanceof Error ? err.message : String(err)}`); + } + })(); +} diff --git a/src/main.ts b/src/main.ts index 39634ce..f451105 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,14 +1,16 @@ import './style.css'; import { renderHomePage } from './home-page.ts'; +import { renderDecksPage } from './decks-page.ts'; import { renderSyncPage } from './sync-page.ts'; import { initWorker } from './sqlite-api.ts'; -// Каркас приложения: топ-бар + бургер-меню + две страницы (Главная / Синхронизация). +// Каркас приложения: топ-бар + бургер-меню + страницы (Главная / Колоды / Синхронизация). -type Page = 'home' | 'sync'; +type Page = 'home' | 'decks' | 'sync'; const PAGE_TITLES: Record = { home: 'Главная', + decks: 'Колоды', sync: 'Синхронизация', }; @@ -46,6 +48,8 @@ function renderPage(page: Page): void { setActiveButton(page); if (page === 'home') { renderHomePage(pageRoot, {}); + } else if (page === 'decks') { + renderDecksPage(pageRoot); } else { renderSyncPage(pageRoot); } @@ -66,7 +70,7 @@ document.addEventListener('keydown', (e) => { drawer.querySelectorAll('.drawer-btn').forEach((btn) => { btn.addEventListener('click', () => { const page = btn.dataset.page as Page | undefined; - if (page === 'home' || page === 'sync') renderPage(page); + if (page === 'home' || page === 'decks' || page === 'sync') renderPage(page); setDrawer(false); }); }); diff --git a/src/style.css b/src/style.css index 4a0b6c9..45ec1cc 100644 --- a/src/style.css +++ b/src/style.css @@ -472,3 +472,8 @@ body.drawer-open { margin: 2px 0 0; word-break: break-word; } + +/* Пустые значения в раскрытии колоды — приглушённое тире */ +.empty-val { + opacity: 0.5; +}