@bobfrankston/rmfmail 1.1.79 → 1.1.81
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.commitmsg +20 -14
- package/client/android-bootstrap.bundle.js +5 -0
- package/client/android-bootstrap.bundle.js.map +2 -2
- package/client/app.bundle.js +32 -17
- package/client/app.bundle.js.map +3 -3
- package/client/app.js +8 -0
- package/client/app.js.map +1 -1
- package/client/app.ts +8 -0
- package/client/components/message-viewer.js +33 -20
- package/client/components/message-viewer.js.map +1 -1
- package/client/components/message-viewer.ts +32 -19
- package/client/compose/compose.bundle.js +5 -0
- package/client/compose/compose.bundle.js.map +2 -2
- package/client/lib/api-client.js +7 -0
- package/client/lib/api-client.js.map +1 -1
- package/client/lib/api-client.ts +8 -0
- package/client/lib/mailxapi.js +9 -0
- package/npmchanges.md +32 -0
- package/package.json +3 -3
- package/packages/mailx-service/index.d.ts +9 -0
- package/packages/mailx-service/index.d.ts.map +1 -1
- package/packages/mailx-service/index.js +26 -0
- package/packages/mailx-service/index.js.map +1 -1
- package/packages/mailx-service/index.ts +25 -0
- package/packages/mailx-service/jsonrpc.js +2 -0
- package/packages/mailx-service/jsonrpc.js.map +1 -1
- package/packages/mailx-service/jsonrpc.ts +2 -0
- package/packages/mailx-store-web/package.json +1 -1
- package/packages/mailx-store-web/web-service.d.ts +4 -0
- package/packages/mailx-store-web/web-service.d.ts.map +1 -1
- package/packages/mailx-store-web/web-service.js +3 -0
- package/packages/mailx-store-web/web-service.js.map +1 -1
- package/packages/mailx-store-web/web-service.ts +3 -0
- package/packages/mailx-types/mailx-api.d.ts +4 -0
- package/packages/mailx-types/mailx-api.d.ts.map +1 -1
- package/packages/mailx-types/mailx-api.ts +1 -0
- package/packages/mailx-types/package.json +1 -1
- /package/packages/mailx-imap/{node_modules.npmglobalize-stash-81260 → node_modules.npmglobalize-stash-76204}/.package-lock.json +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../node_modules/sql.js/dist/sql-wasm-browser.js", "../packages/mailx-types/contact-rules.ts", "../packages/mailx-types/contacts-config.ts", "../packages/mailx-types/groups.ts", "../packages/mailx-types/index.ts", "../packages/mailx-store-web/web-settings.ts", "../node_modules/jsonc-parser/lib/esm/impl/scanner.js", "../node_modules/jsonc-parser/lib/esm/impl/string-intern.js", "../node_modules/jsonc-parser/lib/esm/impl/format.js", "../node_modules/jsonc-parser/lib/esm/impl/parser.js", "../node_modules/jsonc-parser/lib/esm/impl/edit.js", "../node_modules/jsonc-parser/lib/esm/main.js", "../packages/mailx-store-web/db.ts", "../packages/mailx-store-web/web-message-store.ts", "../packages/mailx-store-web/web-service.ts", "../packages/mailx-store-web/android-bootstrap.ts", "../../../MailApps/mailx-sync/gmail.ts", "../../../MailApps/tcp-transport/bridge-tcp-transport.ts", "../../../MailApps/iflow-direct/imap-protocol.ts", "../../../MailApps/iflow-direct/imap-native.ts", "../../../MailApps/iflow-direct/fetched-message.ts", "../../../MailApps/iflow-direct/imap-compat.ts", "../packages/mailx-store-web/imap-web-provider.ts", "../../../MailApps/smtp-direct/smtp-client.ts"],
|
|
4
|
-
"sourcesContent": ["\n// We are modularizing this manually because the current modularize setting in Emscripten has some issues:\n// https://github.com/kripken/emscripten/issues/5820\n// In addition, When you use emcc's modularization, it still expects to export a global object called `Module`,\n// which is able to be used/called before the WASM is loaded.\n// The modularization below exports a promise that loads and resolves to the actual sql.js module.\n// That way, this module can't be used before the WASM is finished loading.\n\n// We are going to define a function that a user will call to start loading initializing our Sql.js library\n// However, that function might be called multiple times, and on subsequent calls, we don't actually want it to instantiate a new instance of the Module\n// Instead, we want to return the previously loaded module\n\n// TODO: Make this not declare a global if used in the browser\nvar initSqlJsPromise = undefined;\n\nvar initSqlJs = function (moduleConfig) {\n\n if (initSqlJsPromise){\n return initSqlJsPromise;\n }\n // If we're here, we've never called this function before\n initSqlJsPromise = new Promise(function (resolveModule, reject) {\n\n // We are modularizing this manually because the current modularize setting in Emscripten has some issues:\n // https://github.com/kripken/emscripten/issues/5820\n\n // The way to affect the loading of emcc compiled modules is to create a variable called `Module` and add\n // properties to it, like `preRun`, `postRun`, etc\n // We are using that to get notified when the WASM has finished loading.\n // Only then will we return our promise\n\n // If they passed in a moduleConfig object, use that\n // Otherwise, initialize Module to the empty object\n var Module = typeof moduleConfig !== 'undefined' ? moduleConfig : {};\n\n // EMCC only allows for a single onAbort function (not an array of functions)\n // So if the user defined their own onAbort function, we remember it and call it\n var originalOnAbortFunction = Module['onAbort'];\n Module['onAbort'] = function (errorThatCausedAbort) {\n reject(new Error(errorThatCausedAbort));\n if (originalOnAbortFunction){\n originalOnAbortFunction(errorThatCausedAbort);\n }\n };\n\n Module['postRun'] = Module['postRun'] || [];\n Module['postRun'].push(function () {\n // When Emscripted calls postRun, this promise resolves with the built Module\n resolveModule(Module);\n });\n\n // There is a section of code in the emcc-generated code below that looks like this:\n // (Note that this is lowercase `module`)\n // if (typeof module !== 'undefined') {\n // module['exports'] = Module;\n // }\n // When that runs, it's going to overwrite our own modularization export efforts in shell-post.js!\n // The only way to tell emcc not to emit it is to pass the MODULARIZE=1 or MODULARIZE_INSTANCE=1 flags,\n // but that carries with it additional unnecessary baggage/bugs we don't want either.\n // So, we have three options:\n // 1) We undefine `module`\n // 2) We remember what `module['exports']` was at the beginning of this function and we restore it later\n // 3) We write a script to remove those lines of code as part of the Make process.\n //\n // Since those are the only lines of code that care about module, we will undefine it. It's the most straightforward\n // of the options, and has the side effect of reducing emcc's efforts to modify the module if its output were to change in the future.\n // That's a nice side effect since we're handling the modularization efforts ourselves\n module = undefined;\n\n // The emcc-generated code and shell-post.js code goes below,\n // meaning that all of it runs inside of this promise. If anything throws an exception, our promise will abort\nvar k;k||=typeof Module != 'undefined' ? Module : {};var aa=!!globalThis.window,ba=!!globalThis.WorkerGlobalScope;\nk.onRuntimeInitialized=function(){function a(f,l){switch(typeof l){case \"boolean\":$b(f,l?1:0);break;case \"number\":ac(f,l);break;case \"string\":bc(f,l,-1,-1);break;case \"object\":if(null===l)eb(f);else if(null!=l.length){var n=ca(l.length);m.set(l,n);cc(f,n,l.length,-1);da(n)}else ra(f,\"Wrong API use : tried to return a value of an unknown type (\"+l+\").\",-1);break;default:eb(f)}}function b(f,l){for(var n=[],p=0;p<f;p+=1){var u=r(l+4*p,\"i32\"),v=dc(u);if(1===v||2===v)u=ec(u);else if(3===v)u=fc(u);else if(4===\nv){v=u;u=gc(v);v=hc(v);for(var K=new Uint8Array(u),I=0;I<u;I+=1)K[I]=m[v+I];u=K}else u=null;n.push(u)}return n}function c(f,l){this.Qa=f;this.db=l;this.Oa=1;this.yb=[]}function d(f,l){this.db=l;this.ob=ea(f);if(null===this.ob)throw Error(\"Unable to allocate memory for the SQL string\");this.ub=this.ob;this.gb=this.Fb=null}function e(f){this.filename=\"dbfile_\"+(4294967295*Math.random()>>>0);if(null!=f){var l=this.filename,n=\"/\",p=l;n&&(n=\"string\"==typeof n?n:fa(n),p=l?ha(n+\"/\"+l):n);l=ia(!0,!0);p=ja(p,\nl);if(f){if(\"string\"==typeof f){n=Array(f.length);for(var u=0,v=f.length;u<v;++u)n[u]=f.charCodeAt(u);f=n}ka(p,l|146);n=la(p,577);ma(n,f,0,f.length,0);na(n);ka(p,l)}}this.handleError(q(this.filename,g));this.db=r(g,\"i32\");hb(this.db);this.pb={};this.Sa={}}var g=y(4),h=k.cwrap,q=h(\"sqlite3_open\",\"number\",[\"string\",\"number\"]),w=h(\"sqlite3_close_v2\",\"number\",[\"number\"]),t=h(\"sqlite3_exec\",\"number\",[\"number\",\"string\",\"number\",\"number\",\"number\"]),x=h(\"sqlite3_changes\",\"number\",[\"number\"]),D=h(\"sqlite3_prepare_v2\",\n\"number\",[\"number\",\"string\",\"number\",\"number\",\"number\"]),ib=h(\"sqlite3_sql\",\"string\",[\"number\"]),jc=h(\"sqlite3_normalized_sql\",\"string\",[\"number\"]),jb=h(\"sqlite3_prepare_v2\",\"number\",[\"number\",\"number\",\"number\",\"number\",\"number\"]),kc=h(\"sqlite3_bind_text\",\"number\",[\"number\",\"number\",\"number\",\"number\",\"number\"]),kb=h(\"sqlite3_bind_blob\",\"number\",[\"number\",\"number\",\"number\",\"number\",\"number\"]),lc=h(\"sqlite3_bind_double\",\"number\",[\"number\",\"number\",\"number\"]),mc=h(\"sqlite3_bind_int\",\"number\",[\"number\",\n\"number\",\"number\"]),nc=h(\"sqlite3_bind_parameter_index\",\"number\",[\"number\",\"string\"]),oc=h(\"sqlite3_step\",\"number\",[\"number\"]),pc=h(\"sqlite3_errmsg\",\"string\",[\"number\"]),qc=h(\"sqlite3_column_count\",\"number\",[\"number\"]),rc=h(\"sqlite3_data_count\",\"number\",[\"number\"]),sc=h(\"sqlite3_column_double\",\"number\",[\"number\",\"number\"]),lb=h(\"sqlite3_column_text\",\"string\",[\"number\",\"number\"]),tc=h(\"sqlite3_column_blob\",\"number\",[\"number\",\"number\"]),uc=h(\"sqlite3_column_bytes\",\"number\",[\"number\",\"number\"]),vc=h(\"sqlite3_column_type\",\n\"number\",[\"number\",\"number\"]),wc=h(\"sqlite3_column_name\",\"string\",[\"number\",\"number\"]),xc=h(\"sqlite3_reset\",\"number\",[\"number\"]),yc=h(\"sqlite3_clear_bindings\",\"number\",[\"number\"]),zc=h(\"sqlite3_finalize\",\"number\",[\"number\"]),mb=h(\"sqlite3_create_function_v2\",\"number\",\"number string number number number number number number number\".split(\" \")),dc=h(\"sqlite3_value_type\",\"number\",[\"number\"]),gc=h(\"sqlite3_value_bytes\",\"number\",[\"number\"]),fc=h(\"sqlite3_value_text\",\"string\",[\"number\"]),hc=h(\"sqlite3_value_blob\",\n\"number\",[\"number\"]),ec=h(\"sqlite3_value_double\",\"number\",[\"number\"]),ac=h(\"sqlite3_result_double\",\"\",[\"number\",\"number\"]),eb=h(\"sqlite3_result_null\",\"\",[\"number\"]),bc=h(\"sqlite3_result_text\",\"\",[\"number\",\"string\",\"number\",\"number\"]),cc=h(\"sqlite3_result_blob\",\"\",[\"number\",\"number\",\"number\",\"number\"]),$b=h(\"sqlite3_result_int\",\"\",[\"number\",\"number\"]),ra=h(\"sqlite3_result_error\",\"\",[\"number\",\"string\",\"number\"]),nb=h(\"sqlite3_aggregate_context\",\"number\",[\"number\",\"number\"]),hb=h(\"RegisterExtensionFunctions\",\n\"number\",[\"number\"]),ob=h(\"sqlite3_update_hook\",\"number\",[\"number\",\"number\",\"number\"]);c.prototype.bind=function(f){if(!this.Qa)throw\"Statement closed\";this.reset();return Array.isArray(f)?this.Wb(f):null!=f&&\"object\"===typeof f?this.Xb(f):!0};c.prototype.step=function(){if(!this.Qa)throw\"Statement closed\";this.Oa=1;var f=oc(this.Qa);switch(f){case 100:return!0;case 101:return!1;default:throw this.db.handleError(f);}};c.prototype.Pb=function(f){null==f&&(f=this.Oa,this.Oa+=1);return sc(this.Qa,f)};\nc.prototype.hc=function(f){null==f&&(f=this.Oa,this.Oa+=1);f=lb(this.Qa,f);if(\"function\"!==typeof BigInt)throw Error(\"BigInt is not supported\");return BigInt(f)};c.prototype.mc=function(f){null==f&&(f=this.Oa,this.Oa+=1);return lb(this.Qa,f)};c.prototype.getBlob=function(f){null==f&&(f=this.Oa,this.Oa+=1);var l=uc(this.Qa,f);f=tc(this.Qa,f);for(var n=new Uint8Array(l),p=0;p<l;p+=1)n[p]=m[f+p];return n};c.prototype.get=function(f,l){l=l||{};null!=f&&this.bind(f)&&this.step();f=[];for(var n=rc(this.Qa),\np=0;p<n;p+=1)switch(vc(this.Qa,p)){case 1:var u=l.useBigInt?this.hc(p):this.Pb(p);f.push(u);break;case 2:f.push(this.Pb(p));break;case 3:f.push(this.mc(p));break;case 4:f.push(this.getBlob(p));break;default:f.push(null)}return f};c.prototype.Db=function(){for(var f=[],l=qc(this.Qa),n=0;n<l;n+=1)f.push(wc(this.Qa,n));return f};c.prototype.Ob=function(f,l){f=this.get(f,l);l=this.Db();for(var n={},p=0;p<l.length;p+=1)n[l[p]]=f[p];return n};c.prototype.lc=function(){return ib(this.Qa)};c.prototype.ic=\nfunction(){return jc(this.Qa)};c.prototype.Jb=function(f){null!=f&&this.bind(f);this.step();return this.reset()};c.prototype.Lb=function(f,l){null==l&&(l=this.Oa,this.Oa+=1);f=ea(f);this.yb.push(f);this.db.handleError(kc(this.Qa,l,f,-1,0))};c.prototype.Vb=function(f,l){null==l&&(l=this.Oa,this.Oa+=1);var n=ca(f.length);m.set(f,n);this.yb.push(n);this.db.handleError(kb(this.Qa,l,n,f.length,0))};c.prototype.Kb=function(f,l){null==l&&(l=this.Oa,this.Oa+=1);this.db.handleError((f===(f|0)?mc:lc)(this.Qa,\nl,f))};c.prototype.Yb=function(f){null==f&&(f=this.Oa,this.Oa+=1);kb(this.Qa,f,0,0,0)};c.prototype.Mb=function(f,l){null==l&&(l=this.Oa,this.Oa+=1);switch(typeof f){case \"string\":this.Lb(f,l);return;case \"number\":this.Kb(f,l);return;case \"bigint\":this.Lb(f.toString(),l);return;case \"boolean\":this.Kb(f+0,l);return;case \"object\":if(null===f){this.Yb(l);return}if(null!=f.length){this.Vb(f,l);return}}throw\"Wrong API use : tried to bind a value of an unknown type (\"+f+\").\";};c.prototype.Xb=function(f){var l=\nthis;Object.keys(f).forEach(function(n){var p=nc(l.Qa,n);0!==p&&l.Mb(f[n],p)});return!0};c.prototype.Wb=function(f){for(var l=0;l<f.length;l+=1)this.Mb(f[l],l+1);return!0};c.prototype.reset=function(){this.Cb();return 0===yc(this.Qa)&&0===xc(this.Qa)};c.prototype.Cb=function(){for(var f;void 0!==(f=this.yb.pop());)da(f)};c.prototype.cb=function(){this.Cb();var f=0===zc(this.Qa);delete this.db.pb[this.Qa];this.Qa=0;return f};d.prototype.next=function(){if(null===this.ob)return{done:!0};null!==this.gb&&\n(this.gb.cb(),this.gb=null);if(!this.db.db)throw this.Ab(),Error(\"Database closed\");var f=oa(),l=y(4);pa(g);pa(l);try{this.db.handleError(jb(this.db.db,this.ub,-1,g,l));this.ub=r(l,\"i32\");var n=r(g,\"i32\");if(0===n)return this.Ab(),{done:!0};this.gb=new c(n,this.db);this.db.pb[n]=this.gb;return{value:this.gb,done:!1}}catch(p){throw this.Fb=z(this.ub),this.Ab(),p;}finally{qa(f)}};d.prototype.Ab=function(){da(this.ob);this.ob=null};d.prototype.jc=function(){return null!==this.Fb?this.Fb:z(this.ub)};\n\"function\"===typeof Symbol&&\"symbol\"===typeof Symbol.iterator&&(d.prototype[Symbol.iterator]=function(){return this});e.prototype.Jb=function(f,l){if(!this.db)throw\"Database closed\";if(l){f=this.Gb(f,l);try{f.step()}finally{f.cb()}}else this.handleError(t(this.db,f,0,0,g));return this};e.prototype.exec=function(f,l,n){if(!this.db)throw\"Database closed\";var p=null,u=null,v=null;try{v=u=ea(f);var K=y(4);for(f=[];0!==r(v,\"i8\");){pa(g);pa(K);this.handleError(jb(this.db,v,-1,g,K));var I=r(g,\"i32\");v=r(K,\n\"i32\");if(0!==I){var H=null;p=new c(I,this);for(null!=l&&p.bind(l);p.step();)null===H&&(H={columns:p.Db(),values:[]},f.push(H)),H.values.push(p.get(null,n));p.cb()}}return f}catch(L){throw p&&p.cb(),L;}finally{u&&da(u)}};e.prototype.ec=function(f,l,n,p,u){\"function\"===typeof l&&(p=n,n=l,l=void 0);f=this.Gb(f,l);try{for(;f.step();)n(f.Ob(null,u))}finally{f.cb()}if(\"function\"===typeof p)return p()};e.prototype.Gb=function(f,l){pa(g);this.handleError(D(this.db,f,-1,g,0));f=r(g,\"i32\");if(0===f)throw\"Nothing to prepare\";\nvar n=new c(f,this);null!=l&&n.bind(l);return this.pb[f]=n};e.prototype.pc=function(f){return new d(f,this)};e.prototype.fc=function(){Object.values(this.pb).forEach(function(l){l.cb()});Object.values(this.Sa).forEach(A);this.Sa={};this.handleError(w(this.db));var f=sa(this.filename);this.handleError(q(this.filename,g));this.db=r(g,\"i32\");hb(this.db);return f};e.prototype.close=function(){null!==this.db&&(Object.values(this.pb).forEach(function(f){f.cb()}),Object.values(this.Sa).forEach(A),this.Sa=\n{},this.fb&&(A(this.fb),this.fb=void 0),this.handleError(w(this.db)),ta(\"/\"+this.filename),this.db=null)};e.prototype.handleError=function(f){if(0===f)return null;f=pc(this.db);throw Error(f);};e.prototype.kc=function(){return x(this.db)};e.prototype.bc=function(f,l){Object.prototype.hasOwnProperty.call(this.Sa,f)&&(A(this.Sa[f]),delete this.Sa[f]);var n=ua(function(p,u,v){u=b(u,v);try{var K=l.apply(null,u)}catch(I){ra(p,I,-1);return}a(p,K)},\"viii\");this.Sa[f]=n;this.handleError(mb(this.db,f,l.length,\n1,0,n,0,0,0));return this};e.prototype.ac=function(f,l){var n=l.init||function(){return null},p=l.finalize||function(H){return H},u=l.step;if(!u)throw\"An aggregate function must have a step function in \"+f;var v={};Object.hasOwnProperty.call(this.Sa,f)&&(A(this.Sa[f]),delete this.Sa[f]);l=f+\"__finalize\";Object.hasOwnProperty.call(this.Sa,l)&&(A(this.Sa[l]),delete this.Sa[l]);var K=ua(function(H,L,Ka){var V=nb(H,1);Object.hasOwnProperty.call(v,V)||(v[V]=n());L=b(L,Ka);L=[v[V]].concat(L);try{v[V]=u.apply(null,\nL)}catch(Bc){delete v[V],ra(H,Bc,-1)}},\"viii\"),I=ua(function(H){var L=nb(H,1);try{var Ka=p(v[L])}catch(V){delete v[L];ra(H,V,-1);return}a(H,Ka);delete v[L]},\"vi\");this.Sa[f]=K;this.Sa[l]=I;this.handleError(mb(this.db,f,u.length-1,1,0,0,K,I,0));return this};e.prototype.vc=function(f){this.fb&&(ob(this.db,0,0),A(this.fb),this.fb=void 0);if(!f)return this;this.fb=ua(function(l,n,p,u,v){switch(n){case 18:l=\"insert\";break;case 23:l=\"update\";break;case 9:l=\"delete\";break;default:throw\"unknown operationCode in updateHook callback: \"+\nn;}p=z(p);u=z(u);if(v>Number.MAX_SAFE_INTEGER)throw\"rowId too big to fit inside a Number\";f(l,p,u,Number(v))},\"viiiij\");ob(this.db,this.fb,0);return this};c.prototype.bind=c.prototype.bind;c.prototype.step=c.prototype.step;c.prototype.get=c.prototype.get;c.prototype.getColumnNames=c.prototype.Db;c.prototype.getAsObject=c.prototype.Ob;c.prototype.getSQL=c.prototype.lc;c.prototype.getNormalizedSQL=c.prototype.ic;c.prototype.run=c.prototype.Jb;c.prototype.reset=c.prototype.reset;c.prototype.freemem=\nc.prototype.Cb;c.prototype.free=c.prototype.cb;d.prototype.next=d.prototype.next;d.prototype.getRemainingSQL=d.prototype.jc;e.prototype.run=e.prototype.Jb;e.prototype.exec=e.prototype.exec;e.prototype.each=e.prototype.ec;e.prototype.prepare=e.prototype.Gb;e.prototype.iterateStatements=e.prototype.pc;e.prototype[\"export\"]=e.prototype.fc;e.prototype.close=e.prototype.close;e.prototype.handleError=e.prototype.handleError;e.prototype.getRowsModified=e.prototype.kc;e.prototype.create_function=e.prototype.bc;\ne.prototype.create_aggregate=e.prototype.ac;e.prototype.updateHook=e.prototype.vc;k.Database=e};var va=\"./this.program\",wa=globalThis.document?.currentScript?.src;ba&&(wa=self.location.href);var xa=\"\",ya,za;\nif(aa||ba){try{xa=(new URL(\".\",wa)).href}catch{}ba&&(za=a=>{var b=new XMLHttpRequest;b.open(\"GET\",a,!1);b.responseType=\"arraybuffer\";b.send(null);return new Uint8Array(b.response)});ya=async a=>{a=await fetch(a,{credentials:\"same-origin\"});if(a.ok)return a.arrayBuffer();throw Error(a.status+\" : \"+a.url);}}var Aa=console.log.bind(console),B=console.error.bind(console),Ba,Ca=!1,Da,m,C,Ea,E,F,Fa,Ga,G;\nfunction Ha(){var a=Ia.buffer;m=new Int8Array(a);Ea=new Int16Array(a);C=new Uint8Array(a);new Uint16Array(a);E=new Int32Array(a);F=new Uint32Array(a);Fa=new Float32Array(a);Ga=new Float64Array(a);G=new BigInt64Array(a);new BigUint64Array(a)}function Ja(a){k.onAbort?.(a);a=\"Aborted(\"+a+\")\";B(a);Ca=!0;throw new WebAssembly.RuntimeError(a+\". Build with -sASSERTIONS for more info.\");}var La;\nasync function Ma(a){if(!Ba)try{var b=await ya(a);return new Uint8Array(b)}catch{}if(a==La&&Ba)a=new Uint8Array(Ba);else if(za)a=za(a);else throw\"both async and sync fetching of the wasm failed\";return a}async function Na(a,b){try{var c=await Ma(a);return await WebAssembly.instantiate(c,b)}catch(d){B(`failed to asynchronously prepare wasm: ${d}`),Ja(d)}}\nasync function Oa(a){var b=La;if(!Ba)try{var c=fetch(b,{credentials:\"same-origin\"});return await WebAssembly.instantiateStreaming(c,a)}catch(d){B(`wasm streaming compile failed: ${d}`),B(\"falling back to ArrayBuffer instantiation\")}return Na(b,a)}class Pa{name=\"ExitStatus\";constructor(a){this.message=`Program terminated with exit(${a})`;this.status=a}}var Qa=a=>{for(;0<a.length;)a.shift()(k)},Ra=[],Sa=[],Ta=()=>{var a=k.preRun.shift();Sa.push(a)},J=0,Ua=null;\nfunction r(a,b=\"i8\"){b.endsWith(\"*\")&&(b=\"*\");switch(b){case \"i1\":return m[a];case \"i8\":return m[a];case \"i16\":return Ea[a>>1];case \"i32\":return E[a>>2];case \"i64\":return G[a>>3];case \"float\":return Fa[a>>2];case \"double\":return Ga[a>>3];case \"*\":return F[a>>2];default:Ja(`invalid type for getValue: ${b}`)}}var Va=!0;\nfunction pa(a){var b=\"i32\";b.endsWith(\"*\")&&(b=\"*\");switch(b){case \"i1\":m[a]=0;break;case \"i8\":m[a]=0;break;case \"i16\":Ea[a>>1]=0;break;case \"i32\":E[a>>2]=0;break;case \"i64\":G[a>>3]=BigInt(0);break;case \"float\":Fa[a>>2]=0;break;case \"double\":Ga[a>>3]=0;break;case \"*\":F[a>>2]=0;break;default:Ja(`invalid type for setValue: ${b}`)}}\nvar Wa=new TextDecoder,Xa=(a,b,c,d)=>{c=b+c;if(d)return c;for(;a[b]&&!(b>=c);)++b;return b},z=(a,b,c)=>a?Wa.decode(C.subarray(a,Xa(C,a,b,c))):\"\",Ya=(a,b)=>{for(var c=0,d=a.length-1;0<=d;d--){var e=a[d];\".\"===e?a.splice(d,1):\"..\"===e?(a.splice(d,1),c++):c&&(a.splice(d,1),c--)}if(b)for(;c;c--)a.unshift(\"..\");return a},ha=a=>{var b=\"/\"===a.charAt(0),c=\"/\"===a.slice(-1);(a=Ya(a.split(\"/\").filter(d=>!!d),!b).join(\"/\"))||b||(a=\".\");a&&c&&(a+=\"/\");return(b?\"/\":\"\")+a},Za=a=>{var b=/^(\\/?|)([\\s\\S]*?)((?:\\.{1,2}|[^\\/]+?|)(\\.[^.\\/]*|))(?:[\\/]*)$/.exec(a).slice(1);\na=b[0];b=b[1];if(!a&&!b)return\".\";b&&=b.slice(0,-1);return a+b},$a=a=>a&&a.match(/([^\\/]+|\\/)\\/*$/)[1],ab=()=>a=>crypto.getRandomValues(a),bb=a=>{(bb=ab())(a)},cb=(...a)=>{for(var b=\"\",c=!1,d=a.length-1;-1<=d&&!c;d--){c=0<=d?a[d]:\"/\";if(\"string\"!=typeof c)throw new TypeError(\"Arguments to path.resolve must be strings\");if(!c)return\"\";b=c+\"/\"+b;c=\"/\"===c.charAt(0)}b=Ya(b.split(\"/\").filter(e=>!!e),!c).join(\"/\");return(c?\"/\":\"\")+b||\".\"},db=a=>{var b=Xa(a,0);return Wa.decode(a.buffer?a.subarray(0,b):\nnew Uint8Array(a.slice(0,b)))},fb=[],gb=a=>{for(var b=0,c=0;c<a.length;++c){var d=a.charCodeAt(c);127>=d?b++:2047>=d?b+=2:55296<=d&&57343>=d?(b+=4,++c):b+=3}return b},M=(a,b,c,d)=>{if(!(0<d))return 0;var e=c;d=c+d-1;for(var g=0;g<a.length;++g){var h=a.codePointAt(g);if(127>=h){if(c>=d)break;b[c++]=h}else if(2047>=h){if(c+1>=d)break;b[c++]=192|h>>6;b[c++]=128|h&63}else if(65535>=h){if(c+2>=d)break;b[c++]=224|h>>12;b[c++]=128|h>>6&63;b[c++]=128|h&63}else{if(c+3>=d)break;b[c++]=240|h>>18;b[c++]=128|\nh>>12&63;b[c++]=128|h>>6&63;b[c++]=128|h&63;g++}}b[c]=0;return c-e},pb=[];function qb(a,b){pb[a]={input:[],output:[],kb:b};rb(a,sb)}\nvar sb={open(a){var b=pb[a.node.nb];if(!b)throw new N(43);a.Va=b;a.seekable=!1},close(a){a.Va.kb.lb(a.Va)},lb(a){a.Va.kb.lb(a.Va)},read(a,b,c,d){if(!a.Va||!a.Va.kb.Qb)throw new N(60);for(var e=0,g=0;g<d;g++){try{var h=a.Va.kb.Qb(a.Va)}catch(q){throw new N(29);}if(void 0===h&&0===e)throw new N(6);if(null===h||void 0===h)break;e++;b[c+g]=h}e&&(a.node.$a=Date.now());return e},write(a,b,c,d){if(!a.Va||!a.Va.kb.Hb)throw new N(60);try{for(var e=0;e<d;e++)a.Va.kb.Hb(a.Va,b[c+e])}catch(g){throw new N(29);\n}d&&(a.node.Ua=a.node.Ta=Date.now());return e}},tb={Qb(){a:{if(!fb.length){var a=null;globalThis.window?.prompt&&(a=window.prompt(\"Input: \"),null!==a&&(a+=\"\\n\"));if(!a){var b=null;break a}b=Array(gb(a)+1);a=M(a,b,0,b.length);b.length=a;fb=b}b=fb.shift()}return b},Hb(a,b){null===b||10===b?(Aa(db(a.output)),a.output=[]):0!=b&&a.output.push(b)},lb(a){0<a.output?.length&&(Aa(db(a.output)),a.output=[])},Dc(){return{yc:25856,Ac:5,xc:191,zc:35387,wc:[3,28,127,21,4,0,1,0,17,19,26,0,18,15,23,22,0,0,0,0,0,\n0,0,0,0,0,0,0,0,0,0,0]}},Ec(){return 0},Fc(){return[24,80]}},ub={Hb(a,b){null===b||10===b?(B(db(a.output)),a.output=[]):0!=b&&a.output.push(b)},lb(a){0<a.output?.length&&(B(db(a.output)),a.output=[])}},O={Za:null,ab(){return O.createNode(null,\"/\",16895,0)},createNode(a,b,c,d){if(24576===(c&61440)||4096===(c&61440))throw new N(63);O.Za||(O.Za={dir:{node:{Wa:O.La.Wa,Xa:O.La.Xa,mb:O.La.mb,rb:O.La.rb,Tb:O.La.Tb,xb:O.La.xb,vb:O.La.vb,Ib:O.La.Ib,wb:O.La.wb},stream:{Ya:O.Ma.Ya}},file:{node:{Wa:O.La.Wa,Xa:O.La.Xa},\nstream:{Ya:O.Ma.Ya,read:O.Ma.read,write:O.Ma.write,sb:O.Ma.sb,tb:O.Ma.tb}},link:{node:{Wa:O.La.Wa,Xa:O.La.Xa,eb:O.La.eb},stream:{}},Nb:{node:{Wa:O.La.Wa,Xa:O.La.Xa},stream:vb}});c=wb(a,b,c,d);P(c.mode)?(c.La=O.Za.dir.node,c.Ma=O.Za.dir.stream,c.Na={}):32768===(c.mode&61440)?(c.La=O.Za.file.node,c.Ma=O.Za.file.stream,c.Ra=0,c.Na=null):40960===(c.mode&61440)?(c.La=O.Za.link.node,c.Ma=O.Za.link.stream):8192===(c.mode&61440)&&(c.La=O.Za.Nb.node,c.Ma=O.Za.Nb.stream);c.$a=c.Ua=c.Ta=Date.now();a&&(a.Na[b]=\nc,a.$a=a.Ua=a.Ta=c.$a);return c},Cc(a){return a.Na?a.Na.subarray?a.Na.subarray(0,a.Ra):new Uint8Array(a.Na):new Uint8Array(0)},La:{Wa(a){var b={};b.cc=8192===(a.mode&61440)?a.id:1;b.oc=a.id;b.mode=a.mode;b.rc=1;b.uid=0;b.nc=0;b.nb=a.nb;P(a.mode)?b.size=4096:32768===(a.mode&61440)?b.size=a.Ra:40960===(a.mode&61440)?b.size=a.link.length:b.size=0;b.$a=new Date(a.$a);b.Ua=new Date(a.Ua);b.Ta=new Date(a.Ta);b.Zb=4096;b.$b=Math.ceil(b.size/b.Zb);return b},Xa(a,b){for(var c of[\"mode\",\"atime\",\"mtime\",\"ctime\"])null!=\nb[c]&&(a[c]=b[c]);void 0!==b.size&&(b=b.size,a.Ra!=b&&(0==b?(a.Na=null,a.Ra=0):(c=a.Na,a.Na=new Uint8Array(b),c&&a.Na.set(c.subarray(0,Math.min(b,a.Ra))),a.Ra=b)))},mb(){O.zb||(O.zb=new N(44),O.zb.stack=\"<generic error, no stack>\");throw O.zb;},rb(a,b,c,d){return O.createNode(a,b,c,d)},Tb(a,b,c){try{var d=Q(b,c)}catch(g){}if(d){if(P(a.mode))for(var e in d.Na)throw new N(55);xb(d)}delete a.parent.Na[a.name];b.Na[c]=a;a.name=c;b.Ta=b.Ua=a.parent.Ta=a.parent.Ua=Date.now()},xb(a,b){delete a.Na[b];a.Ta=\na.Ua=Date.now()},vb(a,b){var c=Q(a,b),d;for(d in c.Na)throw new N(55);delete a.Na[b];a.Ta=a.Ua=Date.now()},Ib(a){return[\".\",\"..\",...Object.keys(a.Na)]},wb(a,b,c){a=O.createNode(a,b,41471,0);a.link=c;return a},eb(a){if(40960!==(a.mode&61440))throw new N(28);return a.link}},Ma:{read(a,b,c,d,e){var g=a.node.Na;if(e>=a.node.Ra)return 0;a=Math.min(a.node.Ra-e,d);if(8<a&&g.subarray)b.set(g.subarray(e,e+a),c);else for(d=0;d<a;d++)b[c+d]=g[e+d];return a},write(a,b,c,d,e,g){b.buffer===m.buffer&&(g=!1);if(!d)return 0;\na=a.node;a.Ua=a.Ta=Date.now();if(b.subarray&&(!a.Na||a.Na.subarray)){if(g)return a.Na=b.subarray(c,c+d),a.Ra=d;if(0===a.Ra&&0===e)return a.Na=b.slice(c,c+d),a.Ra=d;if(e+d<=a.Ra)return a.Na.set(b.subarray(c,c+d),e),d}g=e+d;var h=a.Na?a.Na.length:0;h>=g||(g=Math.max(g,h*(1048576>h?2:1.125)>>>0),0!=h&&(g=Math.max(g,256)),h=a.Na,a.Na=new Uint8Array(g),0<a.Ra&&a.Na.set(h.subarray(0,a.Ra),0));if(a.Na.subarray&&b.subarray)a.Na.set(b.subarray(c,c+d),e);else for(g=0;g<d;g++)a.Na[e+g]=b[c+g];a.Ra=Math.max(a.Ra,\ne+d);return d},Ya(a,b,c){1===c?b+=a.position:2===c&&32768===(a.node.mode&61440)&&(b+=a.node.Ra);if(0>b)throw new N(28);return b},sb(a,b,c,d,e){if(32768!==(a.node.mode&61440))throw new N(43);a=a.node.Na;if(e&2||!a||a.buffer!==m.buffer){e=!0;d=65536*Math.ceil(b/65536);var g=yb(65536,d);g&&C.fill(0,g,g+d);d=g;if(!d)throw new N(48);if(a){if(0<c||c+b<a.length)a.subarray?a=a.subarray(c,c+b):a=Array.prototype.slice.call(a,c,c+b);m.set(a,d)}}else e=!1,d=a.byteOffset;return{tc:d,Ub:e}},tb(a,b,c,d){O.Ma.write(a,\nb,0,d,c,!1);return 0}}},ia=(a,b)=>{var c=0;a&&(c|=365);b&&(c|=146);return c},zb=null,Ab={},Bb=[],Cb=1,R=null,Db=!1,Eb=!0,N=class{name=\"ErrnoError\";constructor(a){this.Pa=a}},Fb=class{qb={};node=null;get flags(){return this.qb.flags}set flags(a){this.qb.flags=a}get position(){return this.qb.position}set position(a){this.qb.position=a}},Gb=class{La={};Ma={};ib=null;constructor(a,b,c,d){a||=this;this.parent=a;this.ab=a.ab;this.id=Cb++;this.name=b;this.mode=c;this.nb=d;this.$a=this.Ua=this.Ta=Date.now()}get read(){return 365===\n(this.mode&365)}set read(a){a?this.mode|=365:this.mode&=-366}get write(){return 146===(this.mode&146)}set write(a){a?this.mode|=146:this.mode&=-147}};\nfunction S(a,b={}){if(!a)throw new N(44);b.Bb??(b.Bb=!0);\"/\"===a.charAt(0)||(a=\"//\"+a);var c=0;a:for(;40>c;c++){a=a.split(\"/\").filter(q=>!!q);for(var d=zb,e=\"/\",g=0;g<a.length;g++){var h=g===a.length-1;if(h&&b.parent)break;if(\".\"!==a[g])if(\"..\"===a[g])if(e=Za(e),d===d.parent){a=e+\"/\"+a.slice(g+1).join(\"/\");c--;continue a}else d=d.parent;else{e=ha(e+\"/\"+a[g]);try{d=Q(d,a[g])}catch(q){if(44===q?.Pa&&h&&b.sc)return{path:e};throw q;}!d.ib||h&&!b.Bb||(d=d.ib.root);if(40960===(d.mode&61440)&&(!h||b.hb)){if(!d.La.eb)throw new N(52);\nd=d.La.eb(d);\"/\"===d.charAt(0)||(d=Za(e)+\"/\"+d);a=d+\"/\"+a.slice(g+1).join(\"/\");continue a}}}return{path:e,node:d}}throw new N(32);}function fa(a){for(var b;;){if(a===a.parent)return a=a.ab.Sb,b?\"/\"!==a[a.length-1]?`${a}/${b}`:a+b:a;b=b?`${a.name}/${b}`:a.name;a=a.parent}}function Hb(a,b){for(var c=0,d=0;d<b.length;d++)c=(c<<5)-c+b.charCodeAt(d)|0;return(a+c>>>0)%R.length}function xb(a){var b=Hb(a.parent.id,a.name);if(R[b]===a)R[b]=a.jb;else for(b=R[b];b;){if(b.jb===a){b.jb=a.jb;break}b=b.jb}}\nfunction Q(a,b){var c=P(a.mode)?(c=Ib(a,\"x\"))?c:a.La.mb?0:2:54;if(c)throw new N(c);for(c=R[Hb(a.id,b)];c;c=c.jb){var d=c.name;if(c.parent.id===a.id&&d===b)return c}return a.La.mb(a,b)}function wb(a,b,c,d){a=new Gb(a,b,c,d);b=Hb(a.parent.id,a.name);a.jb=R[b];return R[b]=a}function P(a){return 16384===(a&61440)}function Ib(a,b){return Eb?0:b.includes(\"r\")&&!(a.mode&292)||b.includes(\"w\")&&!(a.mode&146)||b.includes(\"x\")&&!(a.mode&73)?2:0}\nfunction Jb(a,b){if(!P(a.mode))return 54;try{return Q(a,b),20}catch(c){}return Ib(a,\"wx\")}function Kb(a,b,c){try{var d=Q(a,b)}catch(e){return e.Pa}if(a=Ib(a,\"wx\"))return a;if(c){if(!P(d.mode))return 54;if(d===d.parent||\"/\"===fa(d))return 10}else if(P(d.mode))return 31;return 0}function Lb(a){if(!a)throw new N(63);return a}function T(a){a=Bb[a];if(!a)throw new N(8);return a}\nfunction Mb(a,b=-1){a=Object.assign(new Fb,a);if(-1==b)a:{for(b=0;4096>=b;b++)if(!Bb[b])break a;throw new N(33);}a.bb=b;return Bb[b]=a}function Nb(a,b=-1){a=Mb(a,b);a.Ma?.Bc?.(a);return a}function Ob(a,b,c){var d=a?.Ma.Xa;a=d?a:b;d??=b.La.Xa;Lb(d);d(a,c)}var vb={open(a){a.Ma=Ab[a.node.nb].Ma;a.Ma.open?.(a)},Ya(){throw new N(70);}};function rb(a,b){Ab[a]={Ma:b}}\nfunction Pb(a,b){var c=\"/\"===b;if(c&&zb)throw new N(10);if(!c&&b){var d=S(b,{Bb:!1});b=d.path;d=d.node;if(d.ib)throw new N(10);if(!P(d.mode))throw new N(54);}b={type:a,Gc:{},Sb:b,qc:[]};a=a.ab(b);a.ab=b;b.root=a;c?zb=a:d&&(d.ib=b,d.ab&&d.ab.qc.push(b))}function Qb(a,b,c){var d=S(a,{parent:!0}).node;a=$a(a);if(!a)throw new N(28);if(\".\"===a||\"..\"===a)throw new N(20);var e=Jb(d,a);if(e)throw new N(e);if(!d.La.rb)throw new N(63);return d.La.rb(d,a,b,c)}\nfunction ja(a,b=438){return Qb(a,b&4095|32768,0)}function U(a,b=511){return Qb(a,b&1023|16384,0)}function Rb(a,b,c){\"undefined\"==typeof c&&(c=b,b=438);Qb(a,b|8192,c)}function Sb(a,b){if(!cb(a))throw new N(44);var c=S(b,{parent:!0}).node;if(!c)throw new N(44);b=$a(b);var d=Jb(c,b);if(d)throw new N(d);if(!c.La.wb)throw new N(63);c.La.wb(c,b,a)}\nfunction Tb(a){var b=S(a,{parent:!0}).node;a=$a(a);var c=Q(b,a),d=Kb(b,a,!0);if(d)throw new N(d);if(!b.La.vb)throw new N(63);if(c.ib)throw new N(10);b.La.vb(b,a);xb(c)}function ta(a){var b=S(a,{parent:!0}).node;if(!b)throw new N(44);a=$a(a);var c=Q(b,a),d=Kb(b,a,!1);if(d)throw new N(d);if(!b.La.xb)throw new N(63);if(c.ib)throw new N(10);b.La.xb(b,a);xb(c)}function Ub(a,b){a=S(a,{hb:!b}).node;return Lb(a.La.Wa)(a)}function Vb(a,b,c,d){Ob(a,b,{mode:c&4095|b.mode&-4096,Ta:Date.now(),dc:d})}\nfunction ka(a,b){a=\"string\"==typeof a?S(a,{hb:!0}).node:a;Vb(null,a,b)}function Wb(a,b,c){if(P(b.mode))throw new N(31);if(32768!==(b.mode&61440))throw new N(28);var d=Ib(b,\"w\");if(d)throw new N(d);Ob(a,b,{size:c,timestamp:Date.now()})}\nfunction la(a,b,c=438){if(\"\"===a)throw new N(44);if(\"string\"==typeof b){var d={r:0,\"r+\":2,w:577,\"w+\":578,a:1089,\"a+\":1090}[b];if(\"undefined\"==typeof d)throw Error(`Unknown file open mode: ${b}`);b=d}c=b&64?c&4095|32768:0;if(\"object\"==typeof a)d=a;else{var e=a.endsWith(\"/\");var g=S(a,{hb:!(b&131072),sc:!0});d=g.node;a=g.path}g=!1;if(b&64)if(d){if(b&128)throw new N(20);}else{if(e)throw new N(31);d=Qb(a,c|511,0);g=!0}if(!d)throw new N(44);8192===(d.mode&61440)&&(b&=-513);if(b&65536&&!P(d.mode))throw new N(54);\nif(!g&&(d?40960===(d.mode&61440)?e=32:(e=[\"r\",\"w\",\"rw\"][b&3],b&512&&(e+=\"w\"),e=P(d.mode)&&(\"r\"!==e||b&576)?31:Ib(d,e)):e=44,e))throw new N(e);b&512&&!g&&(e=d,e=\"string\"==typeof e?S(e,{hb:!0}).node:e,Wb(null,e,0));b=Mb({node:d,path:fa(d),flags:b&-131713,seekable:!0,position:0,Ma:d.Ma,uc:[],error:!1});b.Ma.open&&b.Ma.open(b);g&&ka(d,c&511);return b}function na(a){if(null===a.bb)throw new N(8);a.Eb&&(a.Eb=null);try{a.Ma.close&&a.Ma.close(a)}catch(b){throw b;}finally{Bb[a.bb]=null}a.bb=null}\nfunction Xb(a,b,c){if(null===a.bb)throw new N(8);if(!a.seekable||!a.Ma.Ya)throw new N(70);if(0!=c&&1!=c&&2!=c)throw new N(28);a.position=a.Ma.Ya(a,b,c);a.uc=[]}function Yb(a,b,c,d,e){if(0>d||0>e)throw new N(28);if(null===a.bb)throw new N(8);if(1===(a.flags&2097155))throw new N(8);if(P(a.node.mode))throw new N(31);if(!a.Ma.read)throw new N(28);var g=\"undefined\"!=typeof e;if(!g)e=a.position;else if(!a.seekable)throw new N(70);b=a.Ma.read(a,b,c,d,e);g||(a.position+=b);return b}\nfunction ma(a,b,c,d,e){if(0>d||0>e)throw new N(28);if(null===a.bb)throw new N(8);if(0===(a.flags&2097155))throw new N(8);if(P(a.node.mode))throw new N(31);if(!a.Ma.write)throw new N(28);a.seekable&&a.flags&1024&&Xb(a,0,2);var g=\"undefined\"!=typeof e;if(!g)e=a.position;else if(!a.seekable)throw new N(70);b=a.Ma.write(a,b,c,d,e,void 0);g||(a.position+=b);return b}\nfunction sa(a){var b=b||0;var c=\"binary\";\"utf8\"!==c&&\"binary\"!==c&&Ja(`Invalid encoding type \"${c}\"`);b=la(a,b);a=Ub(a).size;var d=new Uint8Array(a);Yb(b,d,0,a,0);\"utf8\"===c&&(d=db(d));na(b);return d}\nfunction W(a,b,c){a=ha(\"/dev/\"+a);var d=ia(!!b,!!c);W.Rb??(W.Rb=64);var e=W.Rb++<<8|0;rb(e,{open(g){g.seekable=!1},close(){c?.buffer?.length&&c(10)},read(g,h,q,w){for(var t=0,x=0;x<w;x++){try{var D=b()}catch(ib){throw new N(29);}if(void 0===D&&0===t)throw new N(6);if(null===D||void 0===D)break;t++;h[q+x]=D}t&&(g.node.$a=Date.now());return t},write(g,h,q,w){for(var t=0;t<w;t++)try{c(h[q+t])}catch(x){throw new N(29);}w&&(g.node.Ua=g.node.Ta=Date.now());return t}});Rb(a,d,e)}var X={};\nfunction Y(a,b,c){if(\"/\"===b.charAt(0))return b;a=-100===a?\"/\":T(a).path;if(0==b.length){if(!c)throw new N(44);return a}return a+\"/\"+b}\nfunction Zb(a,b){F[a>>2]=b.cc;F[a+4>>2]=b.mode;F[a+8>>2]=b.rc;F[a+12>>2]=b.uid;F[a+16>>2]=b.nc;F[a+20>>2]=b.nb;G[a+24>>3]=BigInt(b.size);E[a+32>>2]=4096;E[a+36>>2]=b.$b;var c=b.$a.getTime(),d=b.Ua.getTime(),e=b.Ta.getTime();G[a+40>>3]=BigInt(Math.floor(c/1E3));F[a+48>>2]=c%1E3*1E6;G[a+56>>3]=BigInt(Math.floor(d/1E3));F[a+64>>2]=d%1E3*1E6;G[a+72>>3]=BigInt(Math.floor(e/1E3));F[a+80>>2]=e%1E3*1E6;G[a+88>>3]=BigInt(b.oc);return 0}\nvar ic=void 0,Ac=()=>{var a=E[+ic>>2];ic+=4;return a},Cc=0,Dc=[0,31,60,91,121,152,182,213,244,274,305,335],Ec=[0,31,59,90,120,151,181,212,243,273,304,334],Fc={},Gc=a=>{if(!(a instanceof Pa||\"unwind\"==a))throw a;},Hc=a=>{Da=a;Va||0<Cc||(k.onExit?.(a),Ca=!0);throw new Pa(a);},Ic=a=>{if(!Ca)try{a()}catch(b){Gc(b)}finally{if(!(Va||0<Cc))try{Da=a=Da,Hc(a)}catch(b){Gc(b)}}},Jc={},Lc=()=>{if(!Kc){var a={USER:\"web_user\",LOGNAME:\"web_user\",PATH:\"/\",PWD:\"/\",HOME:\"/home/web_user\",LANG:(globalThis.navigator?.language??\n\"C\").replace(\"-\",\"_\")+\".UTF-8\",_:va||\"./this.program\"},b;for(b in Jc)void 0===Jc[b]?delete a[b]:a[b]=Jc[b];var c=[];for(b in a)c.push(`${b}=${a[b]}`);Kc=c}return Kc},Kc,Mc=(a,b,c,d)=>{var e={string:t=>{var x=0;if(null!==t&&void 0!==t&&0!==t){x=gb(t)+1;var D=y(x);M(t,C,D,x);x=D}return x},array:t=>{var x=y(t.length);m.set(t,x);return x}};a=k[\"_\"+a];var g=[],h=0;if(d)for(var q=0;q<d.length;q++){var w=e[c[q]];w?(0===h&&(h=oa()),g[q]=w(d[q])):g[q]=d[q]}c=a(...g);return c=function(t){0!==h&&qa(h);return\"string\"===\nb?z(t):\"boolean\"===b?!!t:t}(c)},ea=a=>{var b=gb(a)+1,c=ca(b);c&&M(a,C,c,b);return c},Nc,Oc=[],A=a=>{Nc.delete(Z.get(a));Z.set(a,null);Oc.push(a)},Pc=a=>{const b=a.length;return[b%128|128,b>>7,...a]},Qc={i:127,p:127,j:126,f:125,d:124,e:111},Rc=a=>Pc(Array.from(a,b=>Qc[b])),ua=(a,b)=>{if(!Nc){Nc=new WeakMap;var c=Z.length;if(Nc)for(var d=0;d<0+c;d++){var e=Z.get(d);e&&Nc.set(e,d)}}if(c=Nc.get(a)||0)return c;c=Oc.length?Oc.pop():Z.grow(1);try{Z.set(c,a)}catch(g){if(!(g instanceof TypeError))throw g;\nb=Uint8Array.of(0,97,115,109,1,0,0,0,1,...Pc([1,96,...Rc(b.slice(1)),...Rc(\"v\"===b[0]?\"\":b[0])]),2,7,1,1,101,1,102,0,0,7,5,1,1,102,0,0);b=new WebAssembly.Module(b);b=(new WebAssembly.Instance(b,{e:{f:a}})).exports.f;Z.set(c,b)}Nc.set(a,c);return c};R=Array(4096);Pb(O,\"/\");U(\"/tmp\");U(\"/home\");U(\"/home/web_user\");\n(function(){U(\"/dev\");rb(259,{read:()=>0,write:(d,e,g,h)=>h,Ya:()=>0});Rb(\"/dev/null\",259);qb(1280,tb);qb(1536,ub);Rb(\"/dev/tty\",1280);Rb(\"/dev/tty1\",1536);var a=new Uint8Array(1024),b=0,c=()=>{0===b&&(bb(a),b=a.byteLength);return a[--b]};W(\"random\",c);W(\"urandom\",c);U(\"/dev/shm\");U(\"/dev/shm/tmp\")})();\n(function(){U(\"/proc\");var a=U(\"/proc/self\");U(\"/proc/self/fd\");Pb({ab(){var b=wb(a,\"fd\",16895,73);b.Ma={Ya:O.Ma.Ya};b.La={mb(c,d){c=+d;var e=T(c);c={parent:null,ab:{Sb:\"fake\"},La:{eb:()=>e.path},id:c+1};return c.parent=c},Ib(){return Array.from(Bb.entries()).filter(([,c])=>c).map(([c])=>c.toString())}};return b}},\"/proc/self/fd\")})();k.noExitRuntime&&(Va=k.noExitRuntime);k.print&&(Aa=k.print);k.printErr&&(B=k.printErr);k.wasmBinary&&(Ba=k.wasmBinary);k.thisProgram&&(va=k.thisProgram);\nif(k.preInit)for(\"function\"==typeof k.preInit&&(k.preInit=[k.preInit]);0<k.preInit.length;)k.preInit.shift()();k.stackSave=()=>oa();k.stackRestore=a=>qa(a);k.stackAlloc=a=>y(a);k.cwrap=(a,b,c,d)=>{var e=!c||c.every(g=>\"number\"===g||\"boolean\"===g);return\"string\"!==b&&e&&!d?k[\"_\"+a]:(...g)=>Mc(a,b,c,g)};k.addFunction=ua;k.removeFunction=A;k.UTF8ToString=z;k.stringToNewUTF8=ea;k.writeArrayToMemory=(a,b)=>{m.set(a,b)};\nvar ca,da,yb,Sc,qa,y,oa,Ia,Z,Tc={a:(a,b,c,d)=>Ja(`Assertion failed: ${z(a)}, at: `+[b?z(b):\"unknown filename\",c,d?z(d):\"unknown function\"]),i:function(a,b){try{return a=z(a),ka(a,b),0}catch(c){if(\"undefined\"==typeof X||\"ErrnoError\"!==c.name)throw c;return-c.Pa}},L:function(a,b,c){try{b=z(b);b=Y(a,b);if(c&-8)return-28;var d=S(b,{hb:!0}).node;if(!d)return-44;a=\"\";c&4&&(a+=\"r\");c&2&&(a+=\"w\");c&1&&(a+=\"x\");return a&&Ib(d,a)?-2:0}catch(e){if(\"undefined\"==typeof X||\"ErrnoError\"!==e.name)throw e;return-e.Pa}},\nj:function(a,b){try{var c=T(a);Vb(c,c.node,b,!1);return 0}catch(d){if(\"undefined\"==typeof X||\"ErrnoError\"!==d.name)throw d;return-d.Pa}},h:function(a){try{var b=T(a);Ob(b,b.node,{timestamp:Date.now(),dc:!1});return 0}catch(c){if(\"undefined\"==typeof X||\"ErrnoError\"!==c.name)throw c;return-c.Pa}},b:function(a,b,c){ic=c;try{var d=T(a);switch(b){case 0:var e=Ac();if(0>e)break;for(;Bb[e];)e++;return Nb(d,e).bb;case 1:case 2:return 0;case 3:return d.flags;case 4:return e=Ac(),d.flags|=e,0;case 12:return e=\nAc(),Ea[e+0>>1]=2,0;case 13:case 14:return 0}return-28}catch(g){if(\"undefined\"==typeof X||\"ErrnoError\"!==g.name)throw g;return-g.Pa}},g:function(a,b){try{var c=T(a),d=c.node,e=c.Ma.Wa;a=e?c:d;e??=d.La.Wa;Lb(e);var g=e(a);return Zb(b,g)}catch(h){if(\"undefined\"==typeof X||\"ErrnoError\"!==h.name)throw h;return-h.Pa}},H:function(a,b){b=-9007199254740992>b||9007199254740992<b?NaN:Number(b);try{if(isNaN(b))return-61;var c=T(a);if(0>b||0===(c.flags&2097155))throw new N(28);Wb(c,c.node,b);return 0}catch(d){if(\"undefined\"==\ntypeof X||\"ErrnoError\"!==d.name)throw d;return-d.Pa}},G:function(a,b){try{if(0===b)return-28;var c=gb(\"/\")+1;if(b<c)return-68;M(\"/\",C,a,b);return c}catch(d){if(\"undefined\"==typeof X||\"ErrnoError\"!==d.name)throw d;return-d.Pa}},K:function(a,b){try{return a=z(a),Zb(b,Ub(a,!0))}catch(c){if(\"undefined\"==typeof X||\"ErrnoError\"!==c.name)throw c;return-c.Pa}},C:function(a,b,c){try{return b=z(b),b=Y(a,b),U(b,c),0}catch(d){if(\"undefined\"==typeof X||\"ErrnoError\"!==d.name)throw d;return-d.Pa}},J:function(a,\nb,c,d){try{b=z(b);var e=d&256;b=Y(a,b,d&4096);return Zb(c,e?Ub(b,!0):Ub(b))}catch(g){if(\"undefined\"==typeof X||\"ErrnoError\"!==g.name)throw g;return-g.Pa}},x:function(a,b,c,d){ic=d;try{b=z(b);b=Y(a,b);var e=d?Ac():0;return la(b,c,e).bb}catch(g){if(\"undefined\"==typeof X||\"ErrnoError\"!==g.name)throw g;return-g.Pa}},v:function(a,b,c,d){try{b=z(b);b=Y(a,b);if(0>=d)return-28;var e=S(b).node;if(!e)throw new N(44);if(!e.La.eb)throw new N(28);var g=e.La.eb(e);var h=Math.min(d,gb(g)),q=m[c+h];M(g,C,c,d+1);\nm[c+h]=q;return h}catch(w){if(\"undefined\"==typeof X||\"ErrnoError\"!==w.name)throw w;return-w.Pa}},u:function(a){try{return a=z(a),Tb(a),0}catch(b){if(\"undefined\"==typeof X||\"ErrnoError\"!==b.name)throw b;return-b.Pa}},f:function(a,b){try{return a=z(a),Zb(b,Ub(a))}catch(c){if(\"undefined\"==typeof X||\"ErrnoError\"!==c.name)throw c;return-c.Pa}},r:function(a,b,c){try{b=z(b);b=Y(a,b);if(c)if(512===c)Tb(b);else return-28;else ta(b);return 0}catch(d){if(\"undefined\"==typeof X||\"ErrnoError\"!==d.name)throw d;\nreturn-d.Pa}},q:function(a,b,c){try{b=z(b);b=Y(a,b,!0);var d=Date.now(),e,g;if(c){var h=F[c>>2]+4294967296*E[c+4>>2],q=E[c+8>>2];1073741823==q?e=d:1073741822==q?e=null:e=1E3*h+q/1E6;c+=16;h=F[c>>2]+4294967296*E[c+4>>2];q=E[c+8>>2];1073741823==q?g=d:1073741822==q?g=null:g=1E3*h+q/1E6}else g=e=d;if(null!==(g??e)){a=e;var w=S(b,{hb:!0}).node;Lb(w.La.Xa)(w,{$a:a,Ua:g})}return 0}catch(t){if(\"undefined\"==typeof X||\"ErrnoError\"!==t.name)throw t;return-t.Pa}},m:()=>Ja(\"\"),l:()=>{Va=!1;Cc=0},A:function(a,\nb){a=-9007199254740992>a||9007199254740992<a?NaN:Number(a);a=new Date(1E3*a);E[b>>2]=a.getSeconds();E[b+4>>2]=a.getMinutes();E[b+8>>2]=a.getHours();E[b+12>>2]=a.getDate();E[b+16>>2]=a.getMonth();E[b+20>>2]=a.getFullYear()-1900;E[b+24>>2]=a.getDay();var c=a.getFullYear();E[b+28>>2]=(0!==c%4||0===c%100&&0!==c%400?Ec:Dc)[a.getMonth()]+a.getDate()-1|0;E[b+36>>2]=-(60*a.getTimezoneOffset());c=(new Date(a.getFullYear(),6,1)).getTimezoneOffset();var d=(new Date(a.getFullYear(),0,1)).getTimezoneOffset();\nE[b+32>>2]=(c!=d&&a.getTimezoneOffset()==Math.min(d,c))|0},y:function(a,b,c,d,e,g,h){e=-9007199254740992>e||9007199254740992<e?NaN:Number(e);try{var q=T(d);if(0!==(b&2)&&0===(c&2)&&2!==(q.flags&2097155))throw new N(2);if(1===(q.flags&2097155))throw new N(2);if(!q.Ma.sb)throw new N(43);if(!a)throw new N(28);var w=q.Ma.sb(q,a,e,b,c);var t=w.tc;E[g>>2]=w.Ub;F[h>>2]=t;return 0}catch(x){if(\"undefined\"==typeof X||\"ErrnoError\"!==x.name)throw x;return-x.Pa}},z:function(a,b,c,d,e,g){g=-9007199254740992>g||\n9007199254740992<g?NaN:Number(g);try{var h=T(e);if(c&2){if(32768!==(h.node.mode&61440))throw new N(43);d&2||h.Ma.tb&&h.Ma.tb(h,C.slice(a,a+b),g,b,d)}}catch(q){if(\"undefined\"==typeof X||\"ErrnoError\"!==q.name)throw q;return-q.Pa}},n:(a,b)=>{Fc[a]&&(clearTimeout(Fc[a].id),delete Fc[a]);if(!b)return 0;var c=setTimeout(()=>{delete Fc[a];Ic(()=>Sc(a,performance.now()))},b);Fc[a]={id:c,Hc:b};return 0},B:(a,b,c,d)=>{var e=(new Date).getFullYear(),g=(new Date(e,0,1)).getTimezoneOffset();e=(new Date(e,6,1)).getTimezoneOffset();\nF[a>>2]=60*Math.max(g,e);E[b>>2]=Number(g!=e);b=h=>{var q=Math.abs(h);return`UTC${0<=h?\"-\":\"+\"}${String(Math.floor(q/60)).padStart(2,\"0\")}${String(q%60).padStart(2,\"0\")}`};a=b(g);b=b(e);e<g?(M(a,C,c,17),M(b,C,d,17)):(M(a,C,d,17),M(b,C,c,17))},d:()=>Date.now(),s:()=>2147483648,c:()=>performance.now(),o:a=>{var b=C.length;a>>>=0;if(2147483648<a)return!1;for(var c=1;4>=c;c*=2){var d=b*(1+.2/c);d=Math.min(d,a+100663296);a:{d=(Math.min(2147483648,65536*Math.ceil(Math.max(a,d)/65536))-Ia.buffer.byteLength+\n65535)/65536|0;try{Ia.grow(d);Ha();var e=1;break a}catch(g){}e=void 0}if(e)return!0}return!1},E:(a,b)=>{var c=0,d=0,e;for(e of Lc()){var g=b+c;F[a+d>>2]=g;c+=M(e,C,g,Infinity)+1;d+=4}return 0},F:(a,b)=>{var c=Lc();F[a>>2]=c.length;a=0;for(var d of c)a+=gb(d)+1;F[b>>2]=a;return 0},e:function(a){try{var b=T(a);na(b);return 0}catch(c){if(\"undefined\"==typeof X||\"ErrnoError\"!==c.name)throw c;return c.Pa}},p:function(a,b){try{var c=T(a);m[b]=c.Va?2:P(c.mode)?3:40960===(c.mode&61440)?7:4;Ea[b+2>>1]=0;G[b+\n8>>3]=BigInt(0);G[b+16>>3]=BigInt(0);return 0}catch(d){if(\"undefined\"==typeof X||\"ErrnoError\"!==d.name)throw d;return d.Pa}},w:function(a,b,c,d){try{a:{var e=T(a);a=b;for(var g,h=b=0;h<c;h++){var q=F[a>>2],w=F[a+4>>2];a+=8;var t=Yb(e,m,q,w,g);if(0>t){var x=-1;break a}b+=t;if(t<w)break;\"undefined\"!=typeof g&&(g+=t)}x=b}F[d>>2]=x;return 0}catch(D){if(\"undefined\"==typeof X||\"ErrnoError\"!==D.name)throw D;return D.Pa}},D:function(a,b,c,d){b=-9007199254740992>b||9007199254740992<b?NaN:Number(b);try{if(isNaN(b))return 61;\nvar e=T(a);Xb(e,b,c);G[d>>3]=BigInt(e.position);e.Eb&&0===b&&0===c&&(e.Eb=null);return 0}catch(g){if(\"undefined\"==typeof X||\"ErrnoError\"!==g.name)throw g;return g.Pa}},I:function(a){try{var b=T(a);return b.Ma?.lb?.(b)}catch(c){if(\"undefined\"==typeof X||\"ErrnoError\"!==c.name)throw c;return c.Pa}},t:function(a,b,c,d){try{a:{var e=T(a);a=b;for(var g,h=b=0;h<c;h++){var q=F[a>>2],w=F[a+4>>2];a+=8;var t=ma(e,m,q,w,g);if(0>t){var x=-1;break a}b+=t;if(t<w)break;\"undefined\"!=typeof g&&(g+=t)}x=b}F[d>>2]=x;\nreturn 0}catch(D){if(\"undefined\"==typeof X||\"ErrnoError\"!==D.name)throw D;return D.Pa}},k:Hc};\nfunction Uc(){function a(){k.calledRun=!0;if(!Ca){if(!k.noFSInit&&!Db){var b,c;Db=!0;b??=k.stdin;c??=k.stdout;d??=k.stderr;b?W(\"stdin\",b):Sb(\"/dev/tty\",\"/dev/stdin\");c?W(\"stdout\",null,c):Sb(\"/dev/tty\",\"/dev/stdout\");d?W(\"stderr\",null,d):Sb(\"/dev/tty1\",\"/dev/stderr\");la(\"/dev/stdin\",0);la(\"/dev/stdout\",1);la(\"/dev/stderr\",1)}Vc.N();Eb=!1;k.onRuntimeInitialized?.();if(k.postRun)for(\"function\"==typeof k.postRun&&(k.postRun=[k.postRun]);k.postRun.length;){var d=k.postRun.shift();Ra.push(d)}Qa(Ra)}}if(0<\nJ)Ua=Uc;else{if(k.preRun)for(\"function\"==typeof k.preRun&&(k.preRun=[k.preRun]);k.preRun.length;)Ta();Qa(Sa);0<J?Ua=Uc:k.setStatus?(k.setStatus(\"Running...\"),setTimeout(()=>{setTimeout(()=>k.setStatus(\"\"),1);a()},1)):a()}}var Vc;\n(async function(){function a(c){c=Vc=c.exports;k._sqlite3_free=c.P;k._sqlite3_value_text=c.Q;k._sqlite3_prepare_v2=c.R;k._sqlite3_step=c.S;k._sqlite3_reset=c.T;k._sqlite3_exec=c.U;k._sqlite3_finalize=c.V;k._sqlite3_column_name=c.W;k._sqlite3_column_text=c.X;k._sqlite3_column_type=c.Y;k._sqlite3_errmsg=c.Z;k._sqlite3_clear_bindings=c._;k._sqlite3_value_blob=c.$;k._sqlite3_value_bytes=c.aa;k._sqlite3_value_double=c.ba;k._sqlite3_value_int=c.ca;k._sqlite3_value_type=c.da;k._sqlite3_result_blob=c.ea;\nk._sqlite3_result_double=c.fa;k._sqlite3_result_error=c.ga;k._sqlite3_result_int=c.ha;k._sqlite3_result_int64=c.ia;k._sqlite3_result_null=c.ja;k._sqlite3_result_text=c.ka;k._sqlite3_aggregate_context=c.la;k._sqlite3_column_count=c.ma;k._sqlite3_data_count=c.na;k._sqlite3_column_blob=c.oa;k._sqlite3_column_bytes=c.pa;k._sqlite3_column_double=c.qa;k._sqlite3_bind_blob=c.ra;k._sqlite3_bind_double=c.sa;k._sqlite3_bind_int=c.ta;k._sqlite3_bind_text=c.ua;k._sqlite3_bind_parameter_index=c.va;k._sqlite3_sql=\nc.wa;k._sqlite3_normalized_sql=c.xa;k._sqlite3_changes=c.ya;k._sqlite3_close_v2=c.za;k._sqlite3_create_function_v2=c.Aa;k._sqlite3_update_hook=c.Ba;k._sqlite3_open=c.Ca;ca=k._malloc=c.Da;da=k._free=c.Ea;k._RegisterExtensionFunctions=c.Fa;yb=c.Ga;Sc=c.Ha;qa=c.Ia;y=c.Ja;oa=c.Ka;Ia=c.M;Z=c.O;Ha();J--;k.monitorRunDependencies?.(J);0==J&&Ua&&(c=Ua,Ua=null,c());return Vc}J++;k.monitorRunDependencies?.(J);var b={a:Tc};if(k.instantiateWasm)return new Promise(c=>{k.instantiateWasm(b,(d,e)=>{c(a(d,e))})});\nLa??=k.locateFile?k.locateFile(\"sql-wasm-browser.wasm\",xa):xa+\"sql-wasm-browser.wasm\";return a((await Oa(b)).instance)})();Uc();\n\n\n // The shell-pre.js and emcc-generated code goes above\n return Module;\n }); // The end of the promise being returned\n\n return initSqlJsPromise;\n} // The end of our initSqlJs function\n\n// This bit below is copied almost exactly from what you get when you use the MODULARIZE=1 flag with emcc\n// However, we don't want to use the emcc modularization. See shell-pre.js\nif (typeof exports === 'object' && typeof module === 'object'){\n module.exports = initSqlJs;\n // This will allow the module to be used in ES6 or CommonJS\n module.exports.default = initSqlJs;\n}\nelse if (typeof define === 'function' && define['amd']) {\n define([], function() { return initSqlJs; });\n}\nelse if (typeof exports === 'object'){\n exports[\"Module\"] = initSqlJs;\n}\n", "// AUTO-GENERATED from contact-rules.jsonc \u2014 do not edit.\n// Edit the .jsonc and run `node build-rules.js` (or `npm run build`).\n\nexport const CONTACT_RULES = {\n \"rulesVersion\": \"v3-domain-oneoff\",\n \"junk\": {\n \"localExact\": \"^(no-?reply|do-?not-?reply|noreply|mailer-daemon|postmaster|abuse|automated|bounce(s|d)?|list-?(server|admin|owner|manager)?|notification|notifications?|admin@.*automated|root|daemon|nobody|undisclosed)$\",\n \"localSuffix\": \"(-bounces|\\\\+bounces|-noreply|-no-reply|-notifications?|-mailer)$\",\n \"localPrefix\": \"^(no-?reply|noreply|do-?not-?reply|donotreply|notifications?|alerts?|bounces?|mailer)[-_+]\",\n \"localOneoff\": \"^[0-9a-f]{4}\\\\.[0-9a-f]{4}(\\\\.[0-9a-z]{6})?$\",\n \"domain\": \"^(txt\\\\.voice\\\\.google\\\\.com|reply\\\\.facebook\\\\.com|reply\\\\.linkedin\\\\.com)$\"\n }\n} as const;\n", "/**\n * Shared `contacts.jsonc` mutations \u2014 denylist + preferred.\n *\n * Pure logic with cloud I/O injected, so the desktop service\n * (`mailx-service`, Node) and the Android service (`mailx-store-web`, in the\n * WebView) run ONE implementation instead of each keeping its own copy.\n * `web-service.ts` used to stub `addToDenylist` / `addPreferredContact` as\n * `notImpl()`, which is why the phone's \u2298 / \u2605 buttons did nothing.\n *\n * Nothing here is platform-specific: it's a `cloudRead` \u2192 mutate \u2192 `cloudWrite`\n * round-trip. Each caller passes its own platform's cloud functions.\n */\n\nexport type CloudReadFn = (filename: string) => Promise<string | null>;\n// Return type is intentionally loose \u2014 desktop `cloudWrite` resolves void,\n// the Android one resolves a boolean; the shared code ignores the result.\nexport type CloudWriteFn = (filename: string, content: string) => Promise<unknown>;\n\nexport interface PreferredContactEntry {\n name: string;\n email: string;\n source?: string;\n organization?: string;\n}\n\n/** Loose-parse a JSONC blob. The file mailx writes is plain JSON\n * (`JSON.stringify`), but a hand-edit may add `//` comments or trailing\n * commas \u2014 strip those and retry rather than losing the whole file. */\nfunction parseContactsConfig(raw: string | null): Record<string, unknown> {\n if (!raw) return {};\n try { return JSON.parse(raw) || {}; } catch { /* fall through to loose */ }\n try {\n const stripped = raw\n .replace(/^\\s*\\/\\/.*$/gm, \"\") // line comments\n .replace(/,(\\s*[}\\]])/g, \"$1\"); // trailing commas\n return JSON.parse(stripped) || {};\n } catch { return {}; }\n}\n\n/** Append an email to `contacts.jsonc#denylist[]` \u2014 idempotent and\n * case-insensitive. Writes only when the entry is genuinely new. */\nexport async function addContactsDenylistEntry(\n email: string, cloudRead: CloudReadFn, cloudWrite: CloudWriteFn,\n): Promise<void> {\n const lower = (email || \"\").trim().toLowerCase();\n if (!lower) return;\n const cfg = parseContactsConfig(await cloudRead(\"contacts.jsonc\")) as any;\n if (!Array.isArray(cfg.denylist)) cfg.denylist = [];\n if (cfg.denylist.some((e: any) => (e || \"\").toLowerCase() === lower)) return;\n cfg.denylist.push(email);\n await cloudWrite(\"contacts.jsonc\", JSON.stringify(cfg, null, 2));\n}\n\n/** Append a preferred contact to `contacts.jsonc#preferred[]` \u2014 dedup by\n * source|email|name. Writes only when the entry is genuinely new. */\nexport async function addContactsPreferredEntry(\n entry: PreferredContactEntry, cloudRead: CloudReadFn, cloudWrite: CloudWriteFn,\n): Promise<void> {\n if (!entry?.email) return;\n const cfg = parseContactsConfig(await cloudRead(\"contacts.jsonc\")) as any;\n if (!Array.isArray(cfg.preferred)) cfg.preferred = [];\n const key = (s: string, e: string, n: string): string =>\n `${(s || \"preferred\").toLowerCase()}|${(e || \"\").toLowerCase()}|${(n || \"\").toLowerCase()}`;\n const dupKey = key(entry.source || \"\", entry.email, entry.name || \"\");\n if (cfg.preferred.some((e: any) => key(e?.source || \"\", e?.email || \"\", e?.name || \"\") === dupKey)) return;\n const row: Record<string, string> = { name: entry.name || \"\", email: entry.email };\n if (entry.source) row.source = entry.source;\n if (entry.organization) row.organization = entry.organization;\n cfg.preferred.push(row);\n await cloudWrite(\"contacts.jsonc\", JSON.stringify(cfg, null, 2));\n}\n", "/**\n * Group expansion \u2014 turns a recipient string with group names into a flat\n * deduplicated address list. Shared between desktop (mailx-service) and\n * Android (mailx-store-web) so send paths produce the same result.\n *\n * Group source: contacts.jsonc \u2192 groups: Record<string, string[]>. Each\n * value is an array of either email addresses (\"a@b\" or \"Name <a@b>\") or\n * names of other groups (recursive aliasing). Cycles are detected; depth\n * is capped at 10 nested levels.\n */\n\n/** Raw recipient string from a To/Cc/Bcc field; may contain group names. */\nexport type RecipientToken = string;\n\n/** Map of group name \u2192 member list (each entry: address or another group name). */\nexport type GroupMap = Record<string, string[]>;\n\n/** Result of expanding a recipient string. */\nexport interface ExpansionResult {\n /** Flat unique address list (preserving order of first occurrence). */\n addresses: string[];\n /** Group names that couldn't be resolved (typo / cycle) \u2014 surface in UI. */\n unresolved: string[];\n}\n\n/** Split a comma-or-semicolon recipient string into tokens. Respects\n * angle-bracket address blocks (\"Name, Suffix <a@b>\") so a comma inside\n * the display name doesn't split the entry. */\nexport function splitRecipients(raw: string): RecipientToken[] {\n const out: string[] = [];\n let buf = \"\";\n let depth = 0;\n for (let i = 0; i < raw.length; i++) {\n const c = raw[i];\n if (c === \"<\") depth++;\n else if (c === \">\") depth = Math.max(0, depth - 1);\n if ((c === \",\" || c === \";\") && depth === 0) {\n const t = buf.trim();\n if (t) out.push(t);\n buf = \"\";\n } else {\n buf += c;\n }\n }\n const t = buf.trim();\n if (t) out.push(t);\n return out;\n}\n\n/** Quick test: does the token look like an email address (with or without\n * a display name)? Anything containing \"@\" with non-whitespace on both\n * sides counts. */\nexport function isAddressToken(token: string): boolean {\n return /^[^@\\s][^@]*@[^@\\s]+(\\s|$)|<[^>]+@[^>]+>/.test(token) || /^[^\\s<>@]+@[^\\s<>@]+$/.test(token);\n}\n\n/** Extract the bare email address from a token. Returns the original token\n * lowercased if it has no angle-bracket form. */\nexport function extractAddress(token: string): string {\n const m = token.match(/<([^>]+)>/);\n if (m) return m[1].trim().toLowerCase();\n return token.trim().toLowerCase();\n}\n\n/** Expand a recipient string by resolving group names against `groups`.\n * Group names take precedence: if a token matches a group name AND looks\n * like an address, it's treated as a group. (In practice no one names a\n * group \"x@y.com\", so this is rarely a real conflict.) */\nexport function expandRecipients(raw: string, groups: GroupMap): ExpansionResult {\n const tokens = splitRecipients(raw);\n const seen = new Set<string>();\n const addresses: string[] = [];\n const unresolved: string[] = [];\n\n const visit = (token: string, depth: number, visited: Set<string>): void => {\n if (depth > 10) {\n unresolved.push(`${token} (depth limit)`);\n return;\n }\n // Group name match \u2014 case-insensitive\n const groupKey = Object.keys(groups).find(k => k.toLowerCase() === token.trim().toLowerCase());\n if (groupKey) {\n if (visited.has(groupKey.toLowerCase())) {\n unresolved.push(`${groupKey} (cycle)`);\n return;\n }\n const next = new Set(visited);\n next.add(groupKey.toLowerCase());\n for (const member of groups[groupKey] || []) {\n visit(member, depth + 1, next);\n }\n return;\n }\n // Address \u2014 keep the original (with display name if present), but\n // dedupe by lowercased bare address.\n if (isAddressToken(token)) {\n const key = extractAddress(token);\n if (!seen.has(key)) {\n seen.add(key);\n addresses.push(token.trim());\n }\n return;\n }\n // Neither group nor address \u2014 flag.\n unresolved.push(token);\n };\n\n for (const t of tokens) {\n visit(t, 0, new Set());\n }\n return { addresses, unresolved };\n}\n", "/**\n * @bobfrankston/mailx-types\n * Shared type definitions for the mailx email client.\n * This is the contract between client and server.\n */\n\n// Generated rule data \u2014 both desktop store and Android store import via\n// this barrel so a single source-of-truth (contact-rules.jsonc) drives\n// junk-contact filtering on every platform.\nexport { CONTACT_RULES } from \"./contact-rules.js\";\nexport type { MailxApi } from \"./mailx-api.js\";\n// Shared contacts.jsonc mutations \u2014 one implementation for desktop + Android.\nexport {\n addContactsDenylistEntry, addContactsPreferredEntry,\n type PreferredContactEntry, type CloudReadFn, type CloudWriteFn,\n} from \"./contacts-config.js\";\n\n// Group-name expansion for recipient fields. Lets users type a group name\n// (e.g. \"family\") in To/Cc/Bcc and have it expand to the address list at\n// send time. Both desktop and Android send paths consume this expander\n// against contacts.jsonc \u2192 groups.\nexport {\n expandRecipients, splitRecipients, isAddressToken, extractAddress,\n} from \"./groups.js\";\nexport type { GroupMap, RecipientToken, ExpansionResult } from \"./groups.js\";\n\n// \u2500\u2500 Account Configuration \u2500\u2500\n\n/** Supported authentication methods */\nexport type AuthMethod = \"password\" | \"oauth2\";\n\n/** Mail account configuration */\nexport interface AccountConfig {\n id: string; /** Unique account identifier (e.g., \"iecc\", \"gmail-bob\") */\n name: string; /** Sender name for From header (e.g., \"Bob Frankston\") */\n label?: string; /** UI label for account list (e.g., \"Gmail\"). Falls back to name if not set */\n email: string; /** Email address */\n imap: {\n host: string;\n port: number;\n tls: boolean;\n auth: AuthMethod;\n user: string;\n password?: string; /** For password auth */\n oauthClientId?: string; /** For OAuth2 */\n };\n smtp: {\n host: string;\n port: number;\n tls: boolean;\n auth: AuthMethod;\n user: string;\n password?: string;\n };\n enabled: boolean;\n primary?: boolean; /** Catch-all \"this is my main account\" \u2014 default source for Calendar / Tasks / Contacts when no per-feature override set. */\n primaryCalendar?: boolean; /** Per-feature override: use this account's Google Calendar. Falls back to `primary` if unset. */\n primaryTasks?: boolean; /** Per-feature override: use this account's Google Tasks. Falls back to `primary` if unset. */\n primaryContacts?: boolean; /** Per-feature override: use this account's Google Contacts. Falls back to `primary` if unset. */\n defaultSend?: boolean; /** Use this account's SMTP when From doesn't match any account */\n syncContacts?: boolean; /** Sync contacts even when account is disabled (contacts-only Gmail) */\n relayDomains?: string[]; /** Domains to skip in Delivered-To chain (e.g., [\"relay.aaz.lt\"]) */\n identityDomains?: string[]; /** Domains where Delivered-To address should become the reply From (e.g., [\"bob.ma\", \"bobf.frankston.com\"]) */\n spam?: string; /** IMAP folder path for \"Mark as spam\" button (e.g., \"_spam\"). Button hidden when not set. */\n signature?: string; /** Legacy: HTML signature appended to all outgoing messages (new + reply + forward). Plain text or HTML allowed. Superseded by `sig`. */\n sig?: AccountSignature; /** Per-account signature object. Initially appended only to NEW messages; later options will cover replies/forwards. */\n}\n\n/** Signature configuration in accounts.jsonc. Initial shape carries `text`\n * only; `html: true` reserved for future support of raw HTML signatures. */\nexport interface AccountSignature {\n text: string; /** Plain-text signature body. Newlines preserved. Appended to NEW messages with the standard \"-- \" RFC 3676 separator. */\n html?: boolean; /** Future flag: when true, `text` is treated as raw HTML rather than escaped plain text. Currently ignored. */\n}\n\n// \u2500\u2500 Folder Types \u2500\u2500\n\n/** Standard IMAP special-use folder types */\nexport type SpecialUse = \"inbox\" | \"sent\" | \"drafts\" | \"trash\" | \"junk\" | \"archive\" | \"all\";\n\n/** A mailbox folder */\nexport interface Folder {\n id: number;\n accountId: string;\n path: string; /** IMAP path e.g., \"INBOX\", \"INBOX/Projects\" */\n name: string; /** Display name */\n specialUse: SpecialUse; /** Standard folder type, or null for custom */\n delimiter: string; /** IMAP hierarchy delimiter */\n totalCount: number;\n unreadCount: number;\n children: Folder[]; /** Nested subfolders */\n}\n\n// \u2500\u2500 Message flag state \u2500\u2500\n//\n// External API surface for the IMAP system flags. The literal strings\n// (`\"\\\\Seen\"`, `\"\\\\Flagged\"`, etc.) live ONLY inside this module \u2014 every\n// caller speaks in terms of named predicates (`seenOf(msg)`) and verbs\n// (`setSeen(msg, true)`, `toggleSeen(msg)`). That keeps a typo like\n// `\"\\Seen\"` (single backslash) from silently bypassing flag checks\n// elsewhere, and removes the \"two-API leak\" of having both `FLAG.SEEN`\n// constants AND verb helpers exposed simultaneously.\n//\n// These work against any object with a mutable `flags: string[]`\n// property \u2014 `MessageEnvelope`, `Message`, and the row's `msg` reference\n// all qualify. The verbs return `void` and mutate `msg.flags` in place\n// (replacing the array with a fresh one so listeners observing\n// reference identity, e.g. message-state, still re-render). Pure\n// predicate calls (`seenOf`, `flaggedOf`) don't mutate.\n\nconst _SEEN = \"\\\\Seen\";\nconst _FLAGGED = \"\\\\Flagged\";\nconst _ANSWERED = \"\\\\Answered\";\nconst _DRAFT = \"\\\\Draft\";\nconst _DELETED = \"\\\\Deleted\";\n\ninterface FlagBearing { flags: string[]; }\n\nfunction _has(msg: FlagBearing | { flags?: readonly string[] }, flag: string): boolean {\n return !!msg.flags && msg.flags.includes(flag);\n}\nfunction _set(msg: FlagBearing, flag: string, state: boolean): void {\n const present = (msg.flags || []).includes(flag);\n if (state === present) return;\n const next = state\n ? [...(msg.flags || []), flag]\n : (msg.flags || []).filter(f => f !== flag);\n msg.flags = next;\n}\n\nexport const seenOf = (m: { flags?: readonly string[] }): boolean => _has(m, _SEEN);\nexport const flaggedOf = (m: { flags?: readonly string[] }): boolean => _has(m, _FLAGGED);\nexport const answeredOf = (m: { flags?: readonly string[] }): boolean => _has(m, _ANSWERED);\nexport const draftOf = (m: { flags?: readonly string[] }): boolean => _has(m, _DRAFT);\nexport const deletedOf = (m: { flags?: readonly string[] }): boolean => _has(m, _DELETED);\n\nexport const setSeen = (m: FlagBearing, state: boolean): void => _set(m, _SEEN, state);\nexport const setFlagged = (m: FlagBearing, state: boolean): void => _set(m, _FLAGGED, state);\nexport const setAnswered = (m: FlagBearing, state: boolean): void => _set(m, _ANSWERED, state);\nexport const setDraft = (m: FlagBearing, state: boolean): void => _set(m, _DRAFT, state);\n\nexport const toggleSeen = (m: FlagBearing): void => _set(m, _SEEN, !_has(m, _SEEN));\nexport const toggleFlagged = (m: FlagBearing): void => _set(m, _FLAGGED, !_has(m, _FLAGGED));\n\n// \u2500\u2500 Message Types \u2500\u2500\n\n/** Email address with optional display name */\nexport interface EmailAddress {\n name: string; /** Display name, may be empty */\n address: string; /** Email address */\n}\n\n/** Message envelope (headers only, for list display) */\nexport interface MessageEnvelope {\n id: number; /** Local store ID */\n accountId: string;\n folderId: number;\n folderName?: string; /** Leaf folder name; populated by cross-folder search so the UI can tag each hit */\n uid: number; /** IMAP UID (server-side identity; changes on move, UIDVALIDITY bump) */\n uuid?: string; /** Stable local identity, minted once at first-sight; never changes */\n messageId: string; /** RFC Message-ID header */\n inReplyTo: string; /** For threading */\n references: string[]; /** For threading */\n threadId?: string; /** Computed thread id (root Message-ID of the conversation) */\n date: number; /** Epoch ms */\n subject: string;\n from: EmailAddress;\n to: EmailAddress[];\n cc: EmailAddress[];\n flags: string[]; /** IMAP flags: [\"\\\\Seen\", \"\\\\Flagged\"] */\n size: number;\n hasAttachments: boolean;\n preview: string; /** First ~200 chars of body text */\n bodyPath?: string; /** Local body location: \"idb:...\" or \"gmail:<id>\" */\n providerId?: string; /** Native server id (Gmail hex id, Outlook Graph id) \u2014 bypasses UID\u2192id pagination on body fetch */\n pending?: boolean; /** True when a queued local action (move/flag/delete) hasn't been ACK'd by the server yet \u2014 UI renders pink */\n}\n\n/** Full message with body content */\nexport interface Message extends MessageEnvelope {\n bodyHtml: string; /** HTML body */\n bodyText: string; /** Plain text body */\n attachments: Attachment[];\n}\n\n/** File attachment metadata */\nexport interface Attachment {\n id: number;\n filename: string;\n mimeType: string;\n size: number;\n contentId: string; /** For inline attachments (cid:) */\n}\n\n// \u2500\u2500 API Types \u2500\u2500\n\n/** Paginated list response */\nexport interface PagedResult<T> {\n items: T[];\n total: number;\n page: number;\n pageSize: number;\n}\n\n/** Message list query parameters */\nexport interface MessageQuery {\n accountId: string;\n folderId: number;\n page?: number;\n pageSize?: number;\n sort?: \"date\" | \"from\" | \"subject\";\n sortDir?: \"asc\" | \"desc\";\n search?: string;\n /** Restrict to messages with the \\Flagged flag set (whole-folder, not\n * just the currently-rendered page \u2014 lets the \"show flagged\" filter\n * find stars on messages that haven't been paged in yet). */\n flaggedOnly?: boolean;\n}\n\n/** Compose/send a message */\nexport interface ComposeMessage {\n from: string; /** Account ID to send from */\n to: EmailAddress[];\n cc?: EmailAddress[];\n bcc?: EmailAddress[];\n subject: string;\n bodyHtml: string;\n bodyText?: string;\n inReplyTo?: string; /** Message-ID of message being replied to */\n references?: string[];\n attachments?: { filename: string; data: string; mimeType: string }[];\n}\n\n// \u2500\u2500 Queue Types \u2500\u2500\n\nexport type QueueStatus = \"pending\" | \"sending\" | \"sent\" | \"failed\";\n\nexport interface QueueItem {\n id: number;\n status: QueueStatus;\n createdAt: number;\n sendAfter: number; /** Epoch ms, for deferred send */\n attempts: number;\n lastAttempt: number;\n error: string;\n subject: string;\n to: EmailAddress[];\n}\n\n// \u2500\u2500 WebSocket Event Types \u2500\u2500\n\nexport type WsEvent =\n | { type: \"newMessage\"; accountId: string; folderId: number; message: MessageEnvelope }\n | { type: \"messageDeleted\"; accountId: string; folderId: number; uid: number }\n | { type: \"messageMoved\"; accountId: string; fromFolderId: number; toFolderId: number; uid: number }\n | { type: \"folderCountsChanged\"; accountId: string; counts: Record<number, { total: number; unread: number }> }\n | { type: \"folderSynced\"; accountId: string; entries: { folderId: number; syncedAt: number }[] }\n | { type: \"syncProgress\"; accountId: string; phase: string; progress: number }\n | { type: \"queueUpdate\"; pending: number; sending: number; failed: number }\n | { type: \"connected\" }\n | { type: \"reload\" }\n | { type: \"error\"; message: string }\n | { type: \"accountError\"; accountId: string; error: string; hint: string; isOAuth: boolean };\n\n// \u2500\u2500 Settings Types \u2500\u2500\n\nexport interface MailxSettings {\n accounts: AccountConfig[];\n ui: {\n theme: \"system\" | \"dark\" | \"light\";\n editor: \"quill\" | \"tiptap\";\n folderWidth: number;\n listViewerSplit: number; /** Percentage for message list height */\n fontSize: number;\n };\n sync: {\n intervalMinutes: number;\n historyDays: number; /** 0 = all history */\n prefetch: boolean; /** Download message bodies during sync (default true) */\n };\n store: {\n basePath: string; /** Where message bodies are stored */\n compressionBoundaryDays: number; /** Messages older than this get compressed */\n };\n autocomplete?: AutocompleteSettings;\n}\n\n// \u2500\u2500 Autocomplete Types \u2500\u2500\n\nexport interface AutocompleteSettings {\n enabled: boolean;\n provider: \"ollama\" | \"claude\" | \"openai\" | \"off\";\n ollamaUrl: string;\n ollamaModel: string;\n cloudApiKey: string;\n cloudModel: string;\n debounceMs: number;\n maxTokens: number;\n /** Per-feature opt-in for non-autocomplete AI helpers. All default false\n * per user preference (2026-04-21): AI features should be controlled by\n * a flag, initially OFF in settings. Provider config is shared with\n * autocomplete (provider, cloudApiKey, cloudModel, etc.). */\n translateEnabled?: boolean;\n proofreadEnabled?: boolean;\n}\n\n/** AI provider API keys. Lives at the top of `accounts.jsonc` alongside\n * `accounts:` so all secrets are co-located in one cloud-synced file. The\n * keys field replaces `preferences.jsonc.autocomplete.cloudApiKey` (which\n * was tied to the *active* provider) so a user can set both Anthropic and\n * OpenAI keys once and switch providers without re-entering anything. */\nexport interface AiKeys {\n anthropic?: string;\n openai?: string;\n}\n\nexport interface AutocompleteRequest {\n subject: string;\n to: string;\n bodyText: string;\n cursorOffset: number;\n}\n\nexport interface AutocompleteResponse {\n suggestion: string;\n}\n\n// \u2500\u2500 AI Transform (translate / proofread / summarize) \u2500\u2500\n\nexport interface AiTransformRequest {\n /** translate = render in `targetLang`; proofread = corrected version\n * with grammar/spelling fixes; summarize = short paragraph summary;\n * extractEvent = parse natural-language event description into a\n * structured calendar event (title/start/end/location/notes). */\n action: \"translate\" | \"proofread\" | \"summarize\" | \"extractEvent\";\n text: string;\n /** ISO-639-1 (or BCP-47) language code for translate. Defaults to \"en\". */\n targetLang?: string;\n /** Caller's \"now\" hint, ISO 8601 (e.g. 2026-05-05T18:30:00). Used by\n * extractEvent to resolve relative dates (\"tomorrow at 3pm\"). The\n * service can't trust its own clock \u2014 the user might be on a phone\n * in a different timezone \u2014 so the caller supplies it. */\n nowISO?: string;\n}\n\n/** Structured calendar event fields parsed from a natural-language\n * description by aiTransform({ action: \"extractEvent\" }). All times are\n * ISO 8601 in the caller's local timezone (no `Z` suffix); the client\n * shapes them into Google Calendar's `dates=` URL parameter. */\nexport interface ExtractedEvent {\n title: string;\n startISO?: string;\n endISO?: string;\n allDay?: boolean;\n location?: string;\n notes?: string;\n}\n\nexport interface AiTransformResponse {\n /** Transformed text. Empty when AI is disabled / provider error / feature\n * not enabled \u2014 caller should treat empty as \"no result\". For\n * extractEvent this holds the JSON-stringified ExtractedEvent so the\n * response shape stays single-field across all actions. */\n text: string;\n /** Parsed ExtractedEvent, populated only for extractEvent. Lets the\n * client skip the JSON.parse step (the service already validated). */\n event?: ExtractedEvent;\n /** Optional reason for empty result, surfaced to UI status bar. */\n reason?: string;\n}\n\n// \u2500\u2500 Store Interface \u2500\u2500\n\n/** Body storage backend interface -- implementations are swappable */\nexport interface MessageStore {\n putMessage(accountId: string, folderId: number, uid: number, raw: Buffer): Promise<string>;\n getMessage(accountId: string, folderId: number, uid: number): Promise<Buffer>;\n deleteMessage(accountId: string, folderId: number, uid: number): Promise<void>;\n hasMessage(accountId: string, folderId: number, uid: number): Promise<boolean>;\n}\n\n// \u2500\u2500 Shared Utilities \u2500\u2500\n// Pure functions used by both desktop (mailx-service) and Android (web-service).\n// Kept here to avoid duplication \u2014 both platforms import from mailx-types.\n\n/** Sanitize HTML for safe display \u2014 strips scripts, inline handlers, remote images, forms, iframes. */\nexport function sanitizeHtml(html: string): { html: string; hasRemoteContent: boolean } {\n let hasRemoteContent = false;\n let clean = html.replace(/<script\\b[^>]*>[\\s\\S]*?<\\/script>/gi, \"\");\n clean = clean.replace(/\\s+on\\w+\\s*=\\s*(\"[^\"]*\"|'[^']*'|[^\\s>]+)/gi, \"\");\n clean = clean.replace(/<img\\b([^>]*)\\bsrc\\s*=\\s*(\"[^\"]*\"|'[^']*')/gi, (match, before, src) => {\n const url = src.slice(1, -1);\n if (url.startsWith(\"data:\") || url.startsWith(\"cid:\")) return match;\n hasRemoteContent = true;\n return `<img${before}src=\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='20' height='20'%3E%3Crect fill='%23888' width='20' height='20' rx='3'/%3E%3Ctext x='10' y='14' text-anchor='middle' fill='white' font-size='12'%3E\u2298%3C/text%3E%3C/svg%3E\" data-blocked-src=${src} title=\"Remote image blocked\"`;\n });\n clean = clean.replace(/<link\\b[^>]*rel\\s*=\\s*[\"']stylesheet[\"'][^>]*>/gi, (match) => {\n hasRemoteContent = true;\n return `<!-- blocked: ${match.replace(/--/g, \"\")} -->`;\n });\n clean = clean.replace(/url\\s*\\(\\s*(['\"]?)(https?:\\/\\/[^)]+)\\1\\s*\\)/gi, (_match, _q, url) => {\n hasRemoteContent = true;\n return `url(\"\") /* blocked: ${url} */`;\n });\n clean = clean.replace(/<\\/?form\\b[^>]*>/gi, \"\");\n // Strip every interactive form element. Even without the surrounding\n // <form>, an <input type=\"password\"> in an email body is dangerous \u2014\n // WebView2's password manager offers to autofill it, and the user\n // might type a real password into what looks like an in-email control.\n // Same for <textarea>, <select>/<option>, and <button>. Bob 2026-05-14:\n // observed a phishing-shaped \"CHANGE YOUR PASSWORD\" email rendering\n // with working input fields + the OS autofill chip. Replace with a\n // visible \"[blocked: input]\" marker so the user sees something was\n // stripped (a silent removal would hide the phishing attempt entirely\n // \u2014 they'd think \"this email is just text\" when it actually tried to\n // capture credentials).\n clean = clean.replace(/<input\\b[^>]*\\/?>/gi, \"[blocked: form input]\");\n clean = clean.replace(/<textarea\\b[^>]*>[\\s\\S]*?<\\/textarea>/gi, \"[blocked: textarea]\");\n clean = clean.replace(/<select\\b[^>]*>[\\s\\S]*?<\\/select>/gi, \"[blocked: select]\");\n clean = clean.replace(/<button\\b[^>]*>([\\s\\S]*?)<\\/button>/gi, \"$1\");\n clean = clean.replace(/<iframe\\b[^>]*>[\\s\\S]*?<\\/iframe>/gi, \"\");\n return { html: clean, hasRemoteContent };\n}\n\n/** Encode text as RFC 2045 quoted-printable. */\nexport function encodeQuotedPrintable(text: string): string {\n const encoder = new TextEncoder();\n const bytes = encoder.encode(text);\n let line = \"\";\n let result = \"\";\n for (let i = 0; i < bytes.length; i++) {\n const b = bytes[i];\n let encoded: string;\n if (b === 0x0D && bytes[i + 1] === 0x0A) {\n result += line + \"\\r\\n\";\n line = \"\";\n i++;\n continue;\n } else if (b === 0x0A) {\n result += line + \"\\r\\n\";\n line = \"\";\n continue;\n } else if ((b >= 33 && b <= 126 && b !== 61) || b === 9 || b === 32) {\n encoded = String.fromCharCode(b);\n } else {\n encoded = \"=\" + b.toString(16).toUpperCase().padStart(2, \"0\");\n }\n if (line.length + encoded.length > 75) {\n result += line + \"=\\r\\n\";\n line = \"\";\n }\n line += encoded;\n }\n result += line;\n return result;\n}\n\n/** Render an HTML document as a plain-text approximation suitable for the\n * text/plain alternative part of a multipart/alternative outgoing MIME\n * message. Not a full HTML-to-text engine \u2014 just enough to give non-HTML\n * clients (plain-text readers, spam filters scoring on text/plain, people\n * who turned HTML off) a readable fallback. Preserves line breaks for\n * `<br>` / `</p>` / `</div>` / `<li>`, strips all other tags, decodes the\n * common HTML entities, and collapses runs of whitespace.\n *\n * Spam filters (SpamAssassin, Rspamd) penalise HTML-only mail aggressively;\n * shipping a real text part typically drops the score by 1\u20132 points. Also\n * matches the behaviour of every other mainstream mail client \u2014 sending a\n * text/html part alone marks mailx as an outlier in mail logs. */\nexport function htmlToPlainText(html: string): string {\n if (!html) return \"\";\n let s = html;\n // Drop <style> / <script> entirely (their contents aren't readable text).\n s = s.replace(/<style\\b[^>]*>[\\s\\S]*?<\\/style>/gi, \"\");\n s = s.replace(/<script\\b[^>]*>[\\s\\S]*?<\\/script>/gi, \"\");\n // Block-level breaks \u2014 treat closing tags as line terminators so\n // paragraphs don't run together.\n s = s.replace(/<br\\s*\\/?\\s*>/gi, \"\\n\");\n s = s.replace(/<\\/(p|div|li|tr|h[1-6]|blockquote|pre|section|article)\\s*>/gi, \"\\n\");\n // List-item leading bullet (rough but readable).\n s = s.replace(/<li\\b[^>]*>/gi, \" \u2022 \");\n // Anchor: keep href in parens after the text so URLs survive.\n s = s.replace(/<a\\b[^>]*href\\s*=\\s*(['\"])([^'\"]*)\\1[^>]*>([\\s\\S]*?)<\\/a>/gi,\n (_m, _q, href, text) => {\n const t = text.replace(/<[^>]+>/g, \"\").trim();\n return t && t !== href ? `${t} (${href})` : href;\n });\n // Strip remaining tags.\n s = s.replace(/<[^>]+>/g, \"\");\n // Decode a pragmatic set of HTML entities \u2014 the rare ones survive as-is.\n s = s.replace(/ /gi, \" \")\n .replace(/&/gi, \"&\")\n .replace(/</gi, \"<\")\n .replace(/>/gi, \">\")\n .replace(/"/gi, \"\\\"\")\n .replace(/'/gi, \"'\")\n .replace(/'/gi, \"'\")\n .replace(/—/gi, \"\u2014\")\n .replace(/–/gi, \"\u2013\")\n .replace(/…/gi, \"\u2026\")\n .replace(/&#(\\d+);/g, (_m, n) => String.fromCodePoint(parseInt(n, 10)))\n .replace(/&#x([0-9a-f]+);/gi, (_m, h) => String.fromCodePoint(parseInt(h, 16)));\n // Normalise whitespace: collapse runs of spaces/tabs, trim per-line,\n // cap consecutive blank lines at 2.\n s = s.replace(/[ \\t]+/g, \" \")\n .split(\"\\n\").map(l => l.replace(/^[ \\t]+|[ \\t]+$/g, \"\")).join(\"\\n\")\n .replace(/\\n{3,}/g, \"\\n\\n\")\n .trim();\n return s;\n}\n\n/** Parse search query into structured conditions.\n * Supports qualifiers: from:, to:, subject:, date:, has:attachment,\n * is:flagged, is:unread, is:read. Unqualified terms search across subject /\n * from / preview. Returns { conditions, params } for SQL WHERE clause with\n * LIKE plus structured predicates (flags_json LIKE, has_attachments=1, date\n * range comparisons).\n *\n * Date syntax (matches Gmail-ish conventions):\n * - date:2026-04-22 exact day\n * - date:2026-04 month\n * - date:>2026-04-01 after\n * - date:<2026-04-01 before\n * - date:2026-04-01..2026-04-30 range\n * - date:today / yesterday / last7 / last30\n */\nexport function parseSearchQuery(query: string): { conditions: string[]; params: (string | number)[] } {\n const parts = query.match(/(?:[^\\s\"]+|\"[^\"]*\")+/g) || [];\n const conditions: string[] = [];\n const params: (string | number)[] = [];\n\n const dayStart = (y: number, m: number, d: number) => new Date(y, m - 1, d).getTime();\n const parseDateSpec = (spec: string): { from?: number; to?: number } | null => {\n const now = new Date();\n const today0 = new Date(now.getFullYear(), now.getMonth(), now.getDate()).getTime();\n if (spec === \"today\") return { from: today0, to: today0 + 86400_000 };\n if (spec === \"yesterday\") return { from: today0 - 86400_000, to: today0 };\n const lastN = spec.match(/^last(\\d+)$/i);\n if (lastN) return { from: today0 - parseInt(lastN[1]) * 86400_000 };\n const rangeMatch = spec.match(/^(\\d{4})-(\\d{2})-(\\d{2})\\.\\.(\\d{4})-(\\d{2})-(\\d{2})$/);\n if (rangeMatch) return {\n from: dayStart(+rangeMatch[1], +rangeMatch[2], +rangeMatch[3]),\n to: dayStart(+rangeMatch[4], +rangeMatch[5], +rangeMatch[6]) + 86400_000,\n };\n const gtMatch = spec.match(/^>(\\d{4})-(\\d{2})-(\\d{2})$/);\n if (gtMatch) return { from: dayStart(+gtMatch[1], +gtMatch[2], +gtMatch[3]) + 86400_000 };\n const ltMatch = spec.match(/^<(\\d{4})-(\\d{2})-(\\d{2})$/);\n if (ltMatch) return { to: dayStart(+ltMatch[1], +ltMatch[2], +ltMatch[3]) };\n const monthMatch = spec.match(/^(\\d{4})-(\\d{2})$/);\n if (monthMatch) {\n const y = +monthMatch[1], m = +monthMatch[2];\n const from = dayStart(y, m, 1);\n const to = m === 12 ? dayStart(y + 1, 1, 1) : dayStart(y, m + 1, 1);\n return { from, to };\n }\n const dayMatch = spec.match(/^(\\d{4})-(\\d{2})-(\\d{2})$/);\n if (dayMatch) {\n const from = dayStart(+dayMatch[1], +dayMatch[2], +dayMatch[3]);\n return { from, to: from + 86400_000 };\n }\n return null;\n };\n\n for (const part of parts) {\n const fromMatch = part.match(/^from:(.+)$/i);\n const toMatch = part.match(/^to:(.+)$/i);\n const subjectMatch = part.match(/^subject:(.+)$/i);\n const hasMatch = part.match(/^has:(.+)$/i);\n const isMatch = part.match(/^is:(.+)$/i);\n const dateMatch = part.match(/^date:(.+)$/i);\n\n if (fromMatch) {\n const term = `%${fromMatch[1].replace(/\"/g, \"\")}%`;\n conditions.push(\"(from_name LIKE ? OR from_address LIKE ?)\");\n params.push(term, term);\n } else if (toMatch) {\n const term = `%${toMatch[1].replace(/\"/g, \"\")}%`;\n conditions.push(\"(to_json LIKE ? OR cc_json LIKE ?)\");\n params.push(term, term);\n } else if (subjectMatch) {\n const term = `%${subjectMatch[1].replace(/\"/g, \"\")}%`;\n conditions.push(\"subject LIKE ?\");\n params.push(term);\n } else if (hasMatch) {\n const v = hasMatch[1].toLowerCase();\n if (v === \"attachment\" || v === \"attachments\") {\n conditions.push(\"has_attachments = 1\");\n }\n // Unknown has: qualifier \u2014 silently drop; treating as a literal\n // search term would be confusing.\n } else if (isMatch) {\n const v = isMatch[1].toLowerCase();\n if (v === \"flagged\" || v === \"starred\") {\n conditions.push(\"flags_json LIKE ?\"); params.push(\"%\\\\\\\\Flagged%\");\n } else if (v === \"unread\") {\n conditions.push(\"flags_json NOT LIKE ?\"); params.push(\"%\\\\\\\\Seen%\");\n } else if (v === \"read\") {\n conditions.push(\"flags_json LIKE ?\"); params.push(\"%\\\\\\\\Seen%\");\n }\n } else if (dateMatch) {\n const spec = parseDateSpec(dateMatch[1]);\n if (spec) {\n if (spec.from !== undefined) {\n conditions.push(\"date >= ?\"); params.push(spec.from);\n }\n if (spec.to !== undefined) {\n conditions.push(\"date < ?\"); params.push(spec.to);\n }\n }\n } else {\n const term = `%${part}%`;\n conditions.push(\"(subject LIKE ? OR from_name LIKE ? OR from_address LIKE ? OR preview LIKE ?)\");\n params.push(term, term, term, term);\n }\n }\n\n return { conditions, params };\n}\n", "/**\n * Browser-compatible settings for Android/WebView.\n * Replaces @bobfrankston/mailx-settings which depends on node:fs.\n *\n * Settings are stored in IndexedDB and synced to Google Drive\n * via the GDrive API (same API as desktop cloud mode).\n *\n * On first run, settings are fetched from GDrive. Subsequent reads\n * use the local IndexedDB cache. Writes go to both.\n */\n\nimport type { AccountConfig, MailxSettings, AutocompleteSettings } from \"@bobfrankston/mailx-types\";\n\nconst IDB_NAME = \"mailx-settings\";\nconst IDB_VERSION = 1;\nconst STORE_NAME = \"files\";\n\n// \u2500\u2500 IndexedDB helpers \u2500\u2500\n\nfunction openSettingsDb(): Promise<IDBDatabase> {\n return new Promise((resolve, reject) => {\n const req = indexedDB.open(IDB_NAME, IDB_VERSION);\n req.onupgradeneeded = () => {\n const db = req.result;\n if (!db.objectStoreNames.contains(STORE_NAME)) {\n db.createObjectStore(STORE_NAME);\n }\n };\n req.onsuccess = () => resolve(req.result);\n req.onerror = () => reject(req.error);\n });\n}\n\nasync function idbRead(key: string): Promise<string | null> {\n const db = await openSettingsDb();\n return new Promise((resolve, reject) => {\n const tx = db.transaction(STORE_NAME, \"readonly\");\n const req = tx.objectStore(STORE_NAME).get(key);\n req.onsuccess = () => resolve(req.result as string | null);\n req.onerror = () => reject(req.error);\n });\n}\n\nasync function idbWrite(key: string, value: string): Promise<void> {\n const db = await openSettingsDb();\n return new Promise((resolve, reject) => {\n const tx = db.transaction(STORE_NAME, \"readwrite\");\n tx.objectStore(STORE_NAME).put(value, key);\n tx.oncomplete = () => resolve();\n tx.onerror = () => reject(tx.error);\n });\n}\n\nasync function idbDelete(key: string): Promise<void> {\n const db = await openSettingsDb();\n return new Promise((resolve, reject) => {\n const tx = db.transaction(STORE_NAME, \"readwrite\");\n tx.objectStore(STORE_NAME).delete(key);\n tx.oncomplete = () => resolve();\n tx.onerror = () => reject(tx.error);\n });\n}\n\n// \u2500\u2500 GDrive API \u2500\u2500\n\n/** GDrive folder ID for the \".rmfmail\" app folder */\nlet gDriveFolderId: string | null = null;\n/** GDrive folder name (resolved from query \u2014 \".rmfmail\" today, but kept dynamic in case the query changes) */\nlet gDriveFolderName: string | null = null;\n/** Full path \"My Drive/home/.rmfmail\" \u2014 surfaced in About so the user can verify */\nlet gDriveFolderPath: string | null = null;\n/** Owner email of the matched .rmfmail folder \u2014 surfaces wrong-account picks (e.g. spouse's shared folder) */\nlet gDriveFolderOwner: string | null = null;\n/** OAuth token provider \u2014 set by bootstrap */\nlet tokenProvider: (() => Promise<string>) | null = null;\n\nexport function setGDriveTokenProvider(provider: () => Promise<string>): void {\n tokenProvider = provider;\n}\n\nexport function setGDriveFolderId(folderId: string, folderName?: string, ownerEmail?: string, folderPath?: string): void {\n gDriveFolderId = folderId;\n if (folderName) gDriveFolderName = folderName;\n if (ownerEmail) gDriveFolderOwner = ownerEmail;\n if (folderPath) gDriveFolderPath = folderPath;\n}\n\nexport async function cloudRead(filename: string): Promise<string | null> {\n return gDriveRead(filename);\n}\nexport async function cloudWrite(filename: string, content: string): Promise<boolean> {\n return gDriveWrite(filename, content);\n}\n\nasync function gDriveRead(filename: string): Promise<string | null> {\n if (!tokenProvider || !gDriveFolderId) return null;\n try {\n const token = await tokenProvider();\n // Find file by name in folder\n const q = encodeURIComponent(`name='${filename}' and '${gDriveFolderId}' in parents and trashed=false`);\n const listRes = await globalThis.fetch(\n `https://www.googleapis.com/drive/v3/files?q=${q}&fields=files(id)`,\n { headers: { \"Authorization\": `Bearer ${token}` } }\n );\n if (!listRes.ok) return null;\n const listData = await listRes.json() as any;\n const fileId = listData.files?.[0]?.id;\n if (!fileId) return null;\n // Download content\n const res = await globalThis.fetch(\n `https://www.googleapis.com/drive/v3/files/${fileId}?alt=media`,\n { headers: { \"Authorization\": `Bearer ${token}` } }\n );\n if (!res.ok) return null;\n return res.text();\n } catch (e: any) {\n console.error(`[settings] GDrive read ${filename}: ${e.message}`);\n return null;\n }\n}\n\nasync function gDriveWrite(filename: string, content: string): Promise<boolean> {\n if (!tokenProvider || !gDriveFolderId) return false;\n try {\n const token = await tokenProvider();\n // Check if file exists\n const q = encodeURIComponent(`name='${filename}' and '${gDriveFolderId}' in parents and trashed=false`);\n const listRes = await globalThis.fetch(\n `https://www.googleapis.com/drive/v3/files?q=${q}&fields=files(id)`,\n { headers: { \"Authorization\": `Bearer ${token}` } }\n );\n if (!listRes.ok) return false;\n const listData = await listRes.json() as any;\n const fileId = listData.files?.[0]?.id;\n\n if (fileId) {\n // Update existing\n const res = await globalThis.fetch(\n `https://www.googleapis.com/upload/drive/v3/files/${fileId}?uploadType=media`,\n {\n method: \"PATCH\",\n headers: {\n \"Authorization\": `Bearer ${token}`,\n \"Content-Type\": \"application/json\",\n },\n body: content,\n }\n );\n return res.ok;\n } else {\n // Create new\n const metadata = JSON.stringify({\n name: filename,\n parents: [gDriveFolderId],\n mimeType: \"application/json\",\n });\n const boundary = \"----mailx\" + Date.now();\n const body = `--${boundary}\\r\\nContent-Type: application/json; charset=UTF-8\\r\\n\\r\\n${metadata}\\r\\n--${boundary}\\r\\nContent-Type: application/json\\r\\n\\r\\n${content}\\r\\n--${boundary}--`;\n const res = await globalThis.fetch(\n \"https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart\",\n {\n method: \"POST\",\n headers: {\n \"Authorization\": `Bearer ${token}`,\n \"Content-Type\": `multipart/related; boundary=${boundary}`,\n },\n body,\n }\n );\n return res.ok;\n }\n } catch (e: any) {\n console.error(`[settings] GDrive write ${filename}: ${e.message}`);\n return false;\n }\n}\n\n// \u2500\u2500 Provider defaults (same as desktop mailx-settings) \u2500\u2500\n\ninterface ProviderDefaults {\n label: string;\n imap: { host: string; port: number; tls: boolean; auth: \"password\" | \"oauth2\" };\n smtp: { host: string; port: number; tls: boolean; auth: \"password\" | \"oauth2\" };\n}\n\nconst PROVIDERS: Record<string, ProviderDefaults> = {\n \"gmail.com\": {\n label: \"Gmail\",\n imap: { host: \"imap.gmail.com\", port: 993, tls: true, auth: \"oauth2\" },\n smtp: { host: \"smtp.gmail.com\", port: 587, tls: true, auth: \"oauth2\" },\n },\n \"googlemail.com\": {\n label: \"Gmail\",\n imap: { host: \"imap.gmail.com\", port: 993, tls: true, auth: \"oauth2\" },\n smtp: { host: \"smtp.gmail.com\", port: 587, tls: true, auth: \"oauth2\" },\n },\n \"outlook.com\": {\n label: \"Outlook\",\n imap: { host: \"outlook.office365.com\", port: 993, tls: true, auth: \"oauth2\" },\n smtp: { host: \"smtp.office365.com\", port: 587, tls: true, auth: \"oauth2\" },\n },\n \"hotmail.com\": {\n label: \"Hotmail\",\n imap: { host: \"outlook.office365.com\", port: 993, tls: true, auth: \"oauth2\" },\n smtp: { host: \"smtp.office365.com\", port: 587, tls: true, auth: \"oauth2\" },\n },\n \"yahoo.com\": {\n label: \"Yahoo\",\n imap: { host: \"imap.mail.yahoo.com\", port: 993, tls: true, auth: \"password\" },\n smtp: { host: \"smtp.mail.yahoo.com\", port: 587, tls: true, auth: \"password\" },\n },\n \"icloud.com\": {\n label: \"iCloud\",\n imap: { host: \"imap.mail.me.com\", port: 993, tls: true, auth: \"password\" },\n smtp: { host: \"smtp.mail.me.com\", port: 587, tls: true, auth: \"password\" },\n },\n};\n\nfunction normalizeAccount(acct: any, globalName?: string): AccountConfig {\n const email = acct.email || \"\";\n const domain = email.split(\"@\")[1]?.toLowerCase() || \"\";\n const provider = PROVIDERS[domain];\n const user = acct.imap?.user || acct.user || email;\n\n return {\n id: acct.id || domain.split(\".\")[0] || \"account\",\n name: acct.name || globalName || email.split(\"@\")[0],\n label: acct.label || provider?.label,\n email,\n imap: {\n host: acct.imap?.host || provider?.imap.host || `imap.${domain}`,\n port: acct.imap?.port || provider?.imap.port || 993,\n tls: acct.imap?.tls ?? provider?.imap.tls ?? true,\n auth: acct.imap?.auth || provider?.imap.auth || \"password\",\n user: acct.imap?.user || user,\n password: acct.imap?.password || acct.password,\n },\n smtp: {\n host: acct.smtp?.host || provider?.smtp.host || `smtp.${domain}`,\n port: acct.smtp?.port || provider?.smtp.port || 587,\n tls: acct.smtp?.tls ?? provider?.smtp.tls ?? true,\n auth: acct.smtp?.auth || provider?.smtp.auth || \"password\",\n user: acct.smtp?.user || user,\n password: acct.smtp?.password || acct.password,\n },\n enabled: acct.enabled ?? true,\n defaultSend: acct.defaultSend,\n syncContacts: acct.syncContacts ?? (provider?.imap.auth === \"oauth2\"),\n relayDomains: acct.relayDomains,\n };\n}\n\n// \u2500\u2500 Default settings \u2500\u2500\n\nconst DEFAULT_PREFERENCES = {\n ui: {\n theme: \"system\" as const,\n editor: \"quill\" as const,\n folderWidth: 220,\n listViewerSplit: 40,\n fontSize: 15,\n },\n sync: {\n intervalMinutes: 5,\n historyDays: 30,\n prefetch: true,\n },\n autocomplete: {\n enabled: false,\n provider: \"off\" as const,\n ollamaUrl: \"\",\n ollamaModel: \"\",\n cloudApiKey: \"\",\n cloudModel: \"\",\n debounceMs: 600,\n maxTokens: 60,\n },\n};\n\nconst DEFAULT_ALLOWLIST = {\n senders: [] as string[],\n domains: [] as string[],\n recipients: [] as string[],\n flaggedSenders: [] as string[],\n flaggedDomains: [] as string[],\n};\n\n// \u2500\u2500 JSONC parser (strips comments and trailing commas) \u2500\u2500\n\nfunction parseJsonc(text: string): any {\n // Strip /* block comments */ and // line comments, but preserve content inside strings\n let stripped = \"\";\n let i = 0;\n let inString = false;\n let stringChar = \"\";\n while (i < text.length) {\n const c = text[i];\n const next = text[i + 1];\n if (inString) {\n stripped += c;\n if (c === \"\\\\\" && i + 1 < text.length) {\n stripped += text[i + 1];\n i += 2;\n continue;\n }\n if (c === stringChar) inString = false;\n i++;\n continue;\n }\n if (c === '\"' || c === \"'\") {\n inString = true;\n stringChar = c;\n stripped += c;\n i++;\n continue;\n }\n if (c === \"/\" && next === \"/\") {\n // Line comment \u2014 skip to end of line\n while (i < text.length && text[i] !== \"\\n\") i++;\n continue;\n }\n if (c === \"/\" && next === \"*\") {\n // Block comment \u2014 skip to */\n i += 2;\n while (i < text.length - 1 && !(text[i] === \"*\" && text[i + 1] === \"/\")) i++;\n i += 2;\n continue;\n }\n stripped += c;\n i++;\n }\n // Strip trailing commas before } or ]\n stripped = stripped.replace(/,(\\s*[}\\]])/g, \"$1\");\n return JSON.parse(stripped);\n}\n\n// \u2500\u2500 Public API \u2500\u2500\n\n/** Load accounts \u2014 first from IndexedDB cache, then GDrive */\nexport async function loadAccounts(): Promise<AccountConfig[]> {\n // Try local cache first\n const cached = await idbRead(\"accounts.jsonc\");\n if (cached) {\n try {\n const data = parseJsonc(cached);\n const raw: any[] = data.accounts || (Array.isArray(data) ? data : []);\n if (raw.length > 0) {\n return raw.map((a: any) => normalizeAccount(a, data.name));\n }\n } catch (e: any) { console.warn(`[settings] Cached accounts.jsonc parse failed: ${e.message}`); }\n }\n // Try GDrive\n const content = await gDriveRead(\"accounts.jsonc\");\n if (content) {\n await idbWrite(\"accounts.jsonc\", content);\n try {\n const data = parseJsonc(content);\n const raw: any[] = data.accounts || (Array.isArray(data) ? data : []);\n return raw.map((a: any) => normalizeAccount(a, data.name));\n } catch (e: any) { console.warn(`[settings] GDrive accounts.jsonc parse failed: ${e.message}`); }\n }\n return [];\n}\n\n/** Load accounts directly from GDrive, bypassing local cache */\nexport async function loadAccountsFromCloud(): Promise<AccountConfig[]> {\n const content = await gDriveRead(\"accounts.jsonc\");\n if (content) {\n await idbWrite(\"accounts.jsonc\", content);\n try {\n const data = parseJsonc(content);\n const raw: any[] = data.accounts || (Array.isArray(data) ? data : []);\n return raw.map((a: any) => normalizeAccount(a, data.name));\n } catch (e: any) { console.warn(`[settings] loadAccountsFromCloud parse failed: ${e.message}`); }\n }\n return [];\n}\n\n/** Save accounts to IndexedDB and GDrive */\nexport async function saveAccounts(accounts: AccountConfig[]): Promise<void> {\n const content = JSON.stringify({ accounts }, null, 2);\n await idbWrite(\"accounts.jsonc\", content);\n await gDriveWrite(\"accounts.jsonc\", content);\n}\n\n/** Load preferences */\nexport async function loadPreferences(): Promise<typeof DEFAULT_PREFERENCES> {\n const cached = await idbRead(\"preferences.jsonc\");\n if (cached) {\n try {\n const data = parseJsonc(cached);\n return {\n ui: { ...DEFAULT_PREFERENCES.ui, ...data.ui },\n sync: { ...DEFAULT_PREFERENCES.sync, ...data.sync },\n autocomplete: { ...DEFAULT_PREFERENCES.autocomplete, ...data.autocomplete },\n };\n } catch { /* parse error */ }\n }\n // Try GDrive\n const content = await gDriveRead(\"preferences.jsonc\");\n if (content) {\n await idbWrite(\"preferences.jsonc\", content);\n try {\n const data = parseJsonc(content);\n return {\n ui: { ...DEFAULT_PREFERENCES.ui, ...data.ui },\n sync: { ...DEFAULT_PREFERENCES.sync, ...data.sync },\n autocomplete: { ...DEFAULT_PREFERENCES.autocomplete, ...data.autocomplete },\n };\n } catch { /* parse error */ }\n }\n return { ...DEFAULT_PREFERENCES };\n}\n\n/** Save preferences */\nexport async function savePreferences(prefs: any): Promise<void> {\n const content = JSON.stringify(prefs, null, 2);\n await idbWrite(\"preferences.jsonc\", content);\n await gDriveWrite(\"preferences.jsonc\", content);\n}\n\n/** Load full settings (accounts + preferences combined) */\nexport async function loadSettings(): Promise<MailxSettings> {\n const accounts = await loadAccounts();\n const prefs = await loadPreferences();\n return {\n accounts,\n ui: prefs.ui,\n sync: prefs.sync,\n autocomplete: prefs.autocomplete as AutocompleteSettings,\n store: {\n basePath: \"indexeddb\",\n compressionBoundaryDays: 365,\n },\n };\n}\n\n/** Save full settings */\nexport async function saveSettings(settings: MailxSettings): Promise<void> {\n await saveAccounts(settings.accounts);\n await savePreferences({ ui: settings.ui, sync: settings.sync, autocomplete: settings.autocomplete });\n}\n\n/** Load allowlist */\nexport async function loadAllowlist(): Promise<typeof DEFAULT_ALLOWLIST> {\n const cached = await idbRead(\"allowlist.jsonc\");\n if (cached) {\n try { return parseJsonc(cached); } catch { /* */ }\n }\n const content = await gDriveRead(\"allowlist.jsonc\");\n if (content) {\n await idbWrite(\"allowlist.jsonc\", content);\n try { return parseJsonc(content); } catch { /* */ }\n }\n return { ...DEFAULT_ALLOWLIST };\n}\n\n/** Save allowlist */\nexport async function saveAllowlist(list: typeof DEFAULT_ALLOWLIST): Promise<void> {\n const content = JSON.stringify(list, null, 2);\n await idbWrite(\"allowlist.jsonc\", content);\n await gDriveWrite(\"allowlist.jsonc\", content);\n}\n\n/** Load autocomplete settings */\nexport async function loadAutocomplete(): Promise<AutocompleteSettings> {\n const prefs = await loadPreferences();\n return prefs.autocomplete as AutocompleteSettings;\n}\n\n/** Save autocomplete settings */\nexport async function saveAutocomplete(settings: AutocompleteSettings): Promise<void> {\n const prefs = await loadPreferences();\n (prefs as any).autocomplete = settings;\n await savePreferences(prefs);\n}\n\n/** Get history days \u2014 read from preferences */\nexport async function getHistoryDays(): Promise<number> {\n const prefs = await loadPreferences();\n return prefs.sync.historyDays || 30;\n}\n\n/** Get prefetch setting */\nexport async function getPrefetch(): Promise<boolean> {\n const prefs = await loadPreferences();\n return prefs.sync.prefetch !== false;\n}\n\n/** Get storage info */\nexport function getStorageInfo(): { provider: string; mode: string; folderId?: string; folderName?: string; folderPath?: string; folderOwner?: string } {\n return {\n provider: gDriveFolderId ? \"gdrive\" : \"local\",\n mode: gDriveFolderId ? \"api\" : \"local\",\n folderId: gDriveFolderId || undefined,\n folderName: gDriveFolderName || undefined,\n folderPath: gDriveFolderPath || undefined,\n folderOwner: gDriveFolderOwner || undefined,\n };\n}\n\n/** Clear all cached settings \u2014 used for \"Reset Store\" */\nexport async function clearSettings(): Promise<void> {\n await idbDelete(\"accounts.jsonc\");\n await idbDelete(\"preferences.jsonc\");\n await idbDelete(\"allowlist.jsonc\");\n}\n\n// \u2500\u2500 Per-device settings \u2500\u2500\n\nconst DEVICE_ID_KEY = \"mailx-device-id\";\n\n/** Get or create a stable device ID (UUID stored in localStorage) */\nexport function getDeviceId(): string {\n let id = localStorage.getItem(DEVICE_ID_KEY);\n if (!id) {\n id = crypto.randomUUID();\n localStorage.setItem(DEVICE_ID_KEY, id);\n }\n return id;\n}\n\n/** Save device-specific settings to GDrive (devices/<deviceId>/state.json) */\nexport async function saveDeviceState(state: any): Promise<void> {\n const deviceId = getDeviceId();\n const filename = `devices/${deviceId}/state.json`;\n const content = JSON.stringify(state, null, 2);\n await idbWrite(filename, content);\n await gDriveWrite(filename, content);\n}\n\n/** Load device-specific settings */\nexport async function loadDeviceState(): Promise<any> {\n const deviceId = getDeviceId();\n const filename = `devices/${deviceId}/state.json`;\n const cached = await idbRead(filename);\n if (cached) {\n try { return parseJsonc(cached); } catch { /* */ }\n }\n const content = await gDriveRead(filename);\n if (content) {\n await idbWrite(filename, content);\n try { return parseJsonc(content); } catch { /* */ }\n }\n return {};\n}\n", "/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n'use strict';\n/**\n * Creates a JSON scanner on the given text.\n * If ignoreTrivia is set, whitespaces or comments are ignored.\n */\nexport function createScanner(text, ignoreTrivia = false) {\n const len = text.length;\n let pos = 0, value = '', tokenOffset = 0, token = 16 /* SyntaxKind.Unknown */, lineNumber = 0, lineStartOffset = 0, tokenLineStartOffset = 0, prevTokenLineStartOffset = 0, scanError = 0 /* ScanError.None */;\n function scanHexDigits(count, exact) {\n let digits = 0;\n let value = 0;\n while (digits < count || !exact) {\n let ch = text.charCodeAt(pos);\n if (ch >= 48 /* CharacterCodes._0 */ && ch <= 57 /* CharacterCodes._9 */) {\n value = value * 16 + ch - 48 /* CharacterCodes._0 */;\n }\n else if (ch >= 65 /* CharacterCodes.A */ && ch <= 70 /* CharacterCodes.F */) {\n value = value * 16 + ch - 65 /* CharacterCodes.A */ + 10;\n }\n else if (ch >= 97 /* CharacterCodes.a */ && ch <= 102 /* CharacterCodes.f */) {\n value = value * 16 + ch - 97 /* CharacterCodes.a */ + 10;\n }\n else {\n break;\n }\n pos++;\n digits++;\n }\n if (digits < count) {\n value = -1;\n }\n return value;\n }\n function setPosition(newPosition) {\n pos = newPosition;\n value = '';\n tokenOffset = 0;\n token = 16 /* SyntaxKind.Unknown */;\n scanError = 0 /* ScanError.None */;\n }\n function scanNumber() {\n let start = pos;\n if (text.charCodeAt(pos) === 48 /* CharacterCodes._0 */) {\n pos++;\n }\n else {\n pos++;\n while (pos < text.length && isDigit(text.charCodeAt(pos))) {\n pos++;\n }\n }\n if (pos < text.length && text.charCodeAt(pos) === 46 /* CharacterCodes.dot */) {\n pos++;\n if (pos < text.length && isDigit(text.charCodeAt(pos))) {\n pos++;\n while (pos < text.length && isDigit(text.charCodeAt(pos))) {\n pos++;\n }\n }\n else {\n scanError = 3 /* ScanError.UnexpectedEndOfNumber */;\n return text.substring(start, pos);\n }\n }\n let end = pos;\n if (pos < text.length && (text.charCodeAt(pos) === 69 /* CharacterCodes.E */ || text.charCodeAt(pos) === 101 /* CharacterCodes.e */)) {\n pos++;\n if (pos < text.length && text.charCodeAt(pos) === 43 /* CharacterCodes.plus */ || text.charCodeAt(pos) === 45 /* CharacterCodes.minus */) {\n pos++;\n }\n if (pos < text.length && isDigit(text.charCodeAt(pos))) {\n pos++;\n while (pos < text.length && isDigit(text.charCodeAt(pos))) {\n pos++;\n }\n end = pos;\n }\n else {\n scanError = 3 /* ScanError.UnexpectedEndOfNumber */;\n }\n }\n return text.substring(start, end);\n }\n function scanString() {\n let result = '', start = pos;\n while (true) {\n if (pos >= len) {\n result += text.substring(start, pos);\n scanError = 2 /* ScanError.UnexpectedEndOfString */;\n break;\n }\n const ch = text.charCodeAt(pos);\n if (ch === 34 /* CharacterCodes.doubleQuote */) {\n result += text.substring(start, pos);\n pos++;\n break;\n }\n if (ch === 92 /* CharacterCodes.backslash */) {\n result += text.substring(start, pos);\n pos++;\n if (pos >= len) {\n scanError = 2 /* ScanError.UnexpectedEndOfString */;\n break;\n }\n const ch2 = text.charCodeAt(pos++);\n switch (ch2) {\n case 34 /* CharacterCodes.doubleQuote */:\n result += '\\\"';\n break;\n case 92 /* CharacterCodes.backslash */:\n result += '\\\\';\n break;\n case 47 /* CharacterCodes.slash */:\n result += '/';\n break;\n case 98 /* CharacterCodes.b */:\n result += '\\b';\n break;\n case 102 /* CharacterCodes.f */:\n result += '\\f';\n break;\n case 110 /* CharacterCodes.n */:\n result += '\\n';\n break;\n case 114 /* CharacterCodes.r */:\n result += '\\r';\n break;\n case 116 /* CharacterCodes.t */:\n result += '\\t';\n break;\n case 117 /* CharacterCodes.u */:\n const ch3 = scanHexDigits(4, true);\n if (ch3 >= 0) {\n result += String.fromCharCode(ch3);\n }\n else {\n scanError = 4 /* ScanError.InvalidUnicode */;\n }\n break;\n default:\n scanError = 5 /* ScanError.InvalidEscapeCharacter */;\n }\n start = pos;\n continue;\n }\n if (ch >= 0 && ch <= 0x1f) {\n if (isLineBreak(ch)) {\n result += text.substring(start, pos);\n scanError = 2 /* ScanError.UnexpectedEndOfString */;\n break;\n }\n else {\n scanError = 6 /* ScanError.InvalidCharacter */;\n // mark as error but continue with string\n }\n }\n pos++;\n }\n return result;\n }\n function scanNext() {\n value = '';\n scanError = 0 /* ScanError.None */;\n tokenOffset = pos;\n lineStartOffset = lineNumber;\n prevTokenLineStartOffset = tokenLineStartOffset;\n if (pos >= len) {\n // at the end\n tokenOffset = len;\n return token = 17 /* SyntaxKind.EOF */;\n }\n let code = text.charCodeAt(pos);\n // trivia: whitespace\n if (isWhiteSpace(code)) {\n do {\n pos++;\n value += String.fromCharCode(code);\n code = text.charCodeAt(pos);\n } while (isWhiteSpace(code));\n return token = 15 /* SyntaxKind.Trivia */;\n }\n // trivia: newlines\n if (isLineBreak(code)) {\n pos++;\n value += String.fromCharCode(code);\n if (code === 13 /* CharacterCodes.carriageReturn */ && text.charCodeAt(pos) === 10 /* CharacterCodes.lineFeed */) {\n pos++;\n value += '\\n';\n }\n lineNumber++;\n tokenLineStartOffset = pos;\n return token = 14 /* SyntaxKind.LineBreakTrivia */;\n }\n switch (code) {\n // tokens: []{}:,\n case 123 /* CharacterCodes.openBrace */:\n pos++;\n return token = 1 /* SyntaxKind.OpenBraceToken */;\n case 125 /* CharacterCodes.closeBrace */:\n pos++;\n return token = 2 /* SyntaxKind.CloseBraceToken */;\n case 91 /* CharacterCodes.openBracket */:\n pos++;\n return token = 3 /* SyntaxKind.OpenBracketToken */;\n case 93 /* CharacterCodes.closeBracket */:\n pos++;\n return token = 4 /* SyntaxKind.CloseBracketToken */;\n case 58 /* CharacterCodes.colon */:\n pos++;\n return token = 6 /* SyntaxKind.ColonToken */;\n case 44 /* CharacterCodes.comma */:\n pos++;\n return token = 5 /* SyntaxKind.CommaToken */;\n // strings\n case 34 /* CharacterCodes.doubleQuote */:\n pos++;\n value = scanString();\n return token = 10 /* SyntaxKind.StringLiteral */;\n // comments\n case 47 /* CharacterCodes.slash */:\n const start = pos - 1;\n // Single-line comment\n if (text.charCodeAt(pos + 1) === 47 /* CharacterCodes.slash */) {\n pos += 2;\n while (pos < len) {\n if (isLineBreak(text.charCodeAt(pos))) {\n break;\n }\n pos++;\n }\n value = text.substring(start, pos);\n return token = 12 /* SyntaxKind.LineCommentTrivia */;\n }\n // Multi-line comment\n if (text.charCodeAt(pos + 1) === 42 /* CharacterCodes.asterisk */) {\n pos += 2;\n const safeLength = len - 1; // For lookahead.\n let commentClosed = false;\n while (pos < safeLength) {\n const ch = text.charCodeAt(pos);\n if (ch === 42 /* CharacterCodes.asterisk */ && text.charCodeAt(pos + 1) === 47 /* CharacterCodes.slash */) {\n pos += 2;\n commentClosed = true;\n break;\n }\n pos++;\n if (isLineBreak(ch)) {\n if (ch === 13 /* CharacterCodes.carriageReturn */ && text.charCodeAt(pos) === 10 /* CharacterCodes.lineFeed */) {\n pos++;\n }\n lineNumber++;\n tokenLineStartOffset = pos;\n }\n }\n if (!commentClosed) {\n pos++;\n scanError = 1 /* ScanError.UnexpectedEndOfComment */;\n }\n value = text.substring(start, pos);\n return token = 13 /* SyntaxKind.BlockCommentTrivia */;\n }\n // just a single slash\n value += String.fromCharCode(code);\n pos++;\n return token = 16 /* SyntaxKind.Unknown */;\n // numbers\n case 45 /* CharacterCodes.minus */:\n value += String.fromCharCode(code);\n pos++;\n if (pos === len || !isDigit(text.charCodeAt(pos))) {\n return token = 16 /* SyntaxKind.Unknown */;\n }\n // found a minus, followed by a number so\n // we fall through to proceed with scanning\n // numbers\n case 48 /* CharacterCodes._0 */:\n case 49 /* CharacterCodes._1 */:\n case 50 /* CharacterCodes._2 */:\n case 51 /* CharacterCodes._3 */:\n case 52 /* CharacterCodes._4 */:\n case 53 /* CharacterCodes._5 */:\n case 54 /* CharacterCodes._6 */:\n case 55 /* CharacterCodes._7 */:\n case 56 /* CharacterCodes._8 */:\n case 57 /* CharacterCodes._9 */:\n value += scanNumber();\n return token = 11 /* SyntaxKind.NumericLiteral */;\n // literals and unknown symbols\n default:\n // is a literal? Read the full word.\n while (pos < len && isUnknownContentCharacter(code)) {\n pos++;\n code = text.charCodeAt(pos);\n }\n if (tokenOffset !== pos) {\n value = text.substring(tokenOffset, pos);\n // keywords: true, false, null\n switch (value) {\n case 'true': return token = 8 /* SyntaxKind.TrueKeyword */;\n case 'false': return token = 9 /* SyntaxKind.FalseKeyword */;\n case 'null': return token = 7 /* SyntaxKind.NullKeyword */;\n }\n return token = 16 /* SyntaxKind.Unknown */;\n }\n // some\n value += String.fromCharCode(code);\n pos++;\n return token = 16 /* SyntaxKind.Unknown */;\n }\n }\n function isUnknownContentCharacter(code) {\n if (isWhiteSpace(code) || isLineBreak(code)) {\n return false;\n }\n switch (code) {\n case 125 /* CharacterCodes.closeBrace */:\n case 93 /* CharacterCodes.closeBracket */:\n case 123 /* CharacterCodes.openBrace */:\n case 91 /* CharacterCodes.openBracket */:\n case 34 /* CharacterCodes.doubleQuote */:\n case 58 /* CharacterCodes.colon */:\n case 44 /* CharacterCodes.comma */:\n case 47 /* CharacterCodes.slash */:\n return false;\n }\n return true;\n }\n function scanNextNonTrivia() {\n let result;\n do {\n result = scanNext();\n } while (result >= 12 /* SyntaxKind.LineCommentTrivia */ && result <= 15 /* SyntaxKind.Trivia */);\n return result;\n }\n return {\n setPosition: setPosition,\n getPosition: () => pos,\n scan: ignoreTrivia ? scanNextNonTrivia : scanNext,\n getToken: () => token,\n getTokenValue: () => value,\n getTokenOffset: () => tokenOffset,\n getTokenLength: () => pos - tokenOffset,\n getTokenStartLine: () => lineStartOffset,\n getTokenStartCharacter: () => tokenOffset - prevTokenLineStartOffset,\n getTokenError: () => scanError,\n };\n}\nfunction isWhiteSpace(ch) {\n return ch === 32 /* CharacterCodes.space */ || ch === 9 /* CharacterCodes.tab */;\n}\nfunction isLineBreak(ch) {\n return ch === 10 /* CharacterCodes.lineFeed */ || ch === 13 /* CharacterCodes.carriageReturn */;\n}\nfunction isDigit(ch) {\n return ch >= 48 /* CharacterCodes._0 */ && ch <= 57 /* CharacterCodes._9 */;\n}\nvar CharacterCodes;\n(function (CharacterCodes) {\n CharacterCodes[CharacterCodes[\"lineFeed\"] = 10] = \"lineFeed\";\n CharacterCodes[CharacterCodes[\"carriageReturn\"] = 13] = \"carriageReturn\";\n CharacterCodes[CharacterCodes[\"space\"] = 32] = \"space\";\n CharacterCodes[CharacterCodes[\"_0\"] = 48] = \"_0\";\n CharacterCodes[CharacterCodes[\"_1\"] = 49] = \"_1\";\n CharacterCodes[CharacterCodes[\"_2\"] = 50] = \"_2\";\n CharacterCodes[CharacterCodes[\"_3\"] = 51] = \"_3\";\n CharacterCodes[CharacterCodes[\"_4\"] = 52] = \"_4\";\n CharacterCodes[CharacterCodes[\"_5\"] = 53] = \"_5\";\n CharacterCodes[CharacterCodes[\"_6\"] = 54] = \"_6\";\n CharacterCodes[CharacterCodes[\"_7\"] = 55] = \"_7\";\n CharacterCodes[CharacterCodes[\"_8\"] = 56] = \"_8\";\n CharacterCodes[CharacterCodes[\"_9\"] = 57] = \"_9\";\n CharacterCodes[CharacterCodes[\"a\"] = 97] = \"a\";\n CharacterCodes[CharacterCodes[\"b\"] = 98] = \"b\";\n CharacterCodes[CharacterCodes[\"c\"] = 99] = \"c\";\n CharacterCodes[CharacterCodes[\"d\"] = 100] = \"d\";\n CharacterCodes[CharacterCodes[\"e\"] = 101] = \"e\";\n CharacterCodes[CharacterCodes[\"f\"] = 102] = \"f\";\n CharacterCodes[CharacterCodes[\"g\"] = 103] = \"g\";\n CharacterCodes[CharacterCodes[\"h\"] = 104] = \"h\";\n CharacterCodes[CharacterCodes[\"i\"] = 105] = \"i\";\n CharacterCodes[CharacterCodes[\"j\"] = 106] = \"j\";\n CharacterCodes[CharacterCodes[\"k\"] = 107] = \"k\";\n CharacterCodes[CharacterCodes[\"l\"] = 108] = \"l\";\n CharacterCodes[CharacterCodes[\"m\"] = 109] = \"m\";\n CharacterCodes[CharacterCodes[\"n\"] = 110] = \"n\";\n CharacterCodes[CharacterCodes[\"o\"] = 111] = \"o\";\n CharacterCodes[CharacterCodes[\"p\"] = 112] = \"p\";\n CharacterCodes[CharacterCodes[\"q\"] = 113] = \"q\";\n CharacterCodes[CharacterCodes[\"r\"] = 114] = \"r\";\n CharacterCodes[CharacterCodes[\"s\"] = 115] = \"s\";\n CharacterCodes[CharacterCodes[\"t\"] = 116] = \"t\";\n CharacterCodes[CharacterCodes[\"u\"] = 117] = \"u\";\n CharacterCodes[CharacterCodes[\"v\"] = 118] = \"v\";\n CharacterCodes[CharacterCodes[\"w\"] = 119] = \"w\";\n CharacterCodes[CharacterCodes[\"x\"] = 120] = \"x\";\n CharacterCodes[CharacterCodes[\"y\"] = 121] = \"y\";\n CharacterCodes[CharacterCodes[\"z\"] = 122] = \"z\";\n CharacterCodes[CharacterCodes[\"A\"] = 65] = \"A\";\n CharacterCodes[CharacterCodes[\"B\"] = 66] = \"B\";\n CharacterCodes[CharacterCodes[\"C\"] = 67] = \"C\";\n CharacterCodes[CharacterCodes[\"D\"] = 68] = \"D\";\n CharacterCodes[CharacterCodes[\"E\"] = 69] = \"E\";\n CharacterCodes[CharacterCodes[\"F\"] = 70] = \"F\";\n CharacterCodes[CharacterCodes[\"G\"] = 71] = \"G\";\n CharacterCodes[CharacterCodes[\"H\"] = 72] = \"H\";\n CharacterCodes[CharacterCodes[\"I\"] = 73] = \"I\";\n CharacterCodes[CharacterCodes[\"J\"] = 74] = \"J\";\n CharacterCodes[CharacterCodes[\"K\"] = 75] = \"K\";\n CharacterCodes[CharacterCodes[\"L\"] = 76] = \"L\";\n CharacterCodes[CharacterCodes[\"M\"] = 77] = \"M\";\n CharacterCodes[CharacterCodes[\"N\"] = 78] = \"N\";\n CharacterCodes[CharacterCodes[\"O\"] = 79] = \"O\";\n CharacterCodes[CharacterCodes[\"P\"] = 80] = \"P\";\n CharacterCodes[CharacterCodes[\"Q\"] = 81] = \"Q\";\n CharacterCodes[CharacterCodes[\"R\"] = 82] = \"R\";\n CharacterCodes[CharacterCodes[\"S\"] = 83] = \"S\";\n CharacterCodes[CharacterCodes[\"T\"] = 84] = \"T\";\n CharacterCodes[CharacterCodes[\"U\"] = 85] = \"U\";\n CharacterCodes[CharacterCodes[\"V\"] = 86] = \"V\";\n CharacterCodes[CharacterCodes[\"W\"] = 87] = \"W\";\n CharacterCodes[CharacterCodes[\"X\"] = 88] = \"X\";\n CharacterCodes[CharacterCodes[\"Y\"] = 89] = \"Y\";\n CharacterCodes[CharacterCodes[\"Z\"] = 90] = \"Z\";\n CharacterCodes[CharacterCodes[\"asterisk\"] = 42] = \"asterisk\";\n CharacterCodes[CharacterCodes[\"backslash\"] = 92] = \"backslash\";\n CharacterCodes[CharacterCodes[\"closeBrace\"] = 125] = \"closeBrace\";\n CharacterCodes[CharacterCodes[\"closeBracket\"] = 93] = \"closeBracket\";\n CharacterCodes[CharacterCodes[\"colon\"] = 58] = \"colon\";\n CharacterCodes[CharacterCodes[\"comma\"] = 44] = \"comma\";\n CharacterCodes[CharacterCodes[\"dot\"] = 46] = \"dot\";\n CharacterCodes[CharacterCodes[\"doubleQuote\"] = 34] = \"doubleQuote\";\n CharacterCodes[CharacterCodes[\"minus\"] = 45] = \"minus\";\n CharacterCodes[CharacterCodes[\"openBrace\"] = 123] = \"openBrace\";\n CharacterCodes[CharacterCodes[\"openBracket\"] = 91] = \"openBracket\";\n CharacterCodes[CharacterCodes[\"plus\"] = 43] = \"plus\";\n CharacterCodes[CharacterCodes[\"slash\"] = 47] = \"slash\";\n CharacterCodes[CharacterCodes[\"formFeed\"] = 12] = \"formFeed\";\n CharacterCodes[CharacterCodes[\"tab\"] = 9] = \"tab\";\n})(CharacterCodes || (CharacterCodes = {}));\n", "export const cachedSpaces = new Array(20).fill(0).map((_, index) => {\n return ' '.repeat(index);\n});\nconst maxCachedValues = 200;\nexport const cachedBreakLinesWithSpaces = {\n ' ': {\n '\\n': new Array(maxCachedValues).fill(0).map((_, index) => {\n return '\\n' + ' '.repeat(index);\n }),\n '\\r': new Array(maxCachedValues).fill(0).map((_, index) => {\n return '\\r' + ' '.repeat(index);\n }),\n '\\r\\n': new Array(maxCachedValues).fill(0).map((_, index) => {\n return '\\r\\n' + ' '.repeat(index);\n }),\n },\n '\\t': {\n '\\n': new Array(maxCachedValues).fill(0).map((_, index) => {\n return '\\n' + '\\t'.repeat(index);\n }),\n '\\r': new Array(maxCachedValues).fill(0).map((_, index) => {\n return '\\r' + '\\t'.repeat(index);\n }),\n '\\r\\n': new Array(maxCachedValues).fill(0).map((_, index) => {\n return '\\r\\n' + '\\t'.repeat(index);\n }),\n }\n};\nexport const supportedEols = ['\\n', '\\r', '\\r\\n'];\n", "/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n'use strict';\nimport { createScanner } from './scanner';\nimport { cachedSpaces, cachedBreakLinesWithSpaces, supportedEols } from './string-intern';\nexport function format(documentText, range, options) {\n let initialIndentLevel;\n let formatText;\n let formatTextStart;\n let rangeStart;\n let rangeEnd;\n if (range) {\n rangeStart = range.offset;\n rangeEnd = rangeStart + range.length;\n formatTextStart = rangeStart;\n while (formatTextStart > 0 && !isEOL(documentText, formatTextStart - 1)) {\n formatTextStart--;\n }\n let endOffset = rangeEnd;\n while (endOffset < documentText.length && !isEOL(documentText, endOffset)) {\n endOffset++;\n }\n formatText = documentText.substring(formatTextStart, endOffset);\n initialIndentLevel = computeIndentLevel(formatText, options);\n }\n else {\n formatText = documentText;\n initialIndentLevel = 0;\n formatTextStart = 0;\n rangeStart = 0;\n rangeEnd = documentText.length;\n }\n const eol = getEOL(options, documentText);\n const eolFastPathSupported = supportedEols.includes(eol);\n let numberLineBreaks = 0;\n let indentLevel = 0;\n let indentValue;\n if (options.insertSpaces) {\n indentValue = cachedSpaces[options.tabSize || 4] ?? repeat(cachedSpaces[1], options.tabSize || 4);\n }\n else {\n indentValue = '\\t';\n }\n const indentType = indentValue === '\\t' ? '\\t' : ' ';\n let scanner = createScanner(formatText, false);\n let hasError = false;\n function newLinesAndIndent() {\n if (numberLineBreaks > 1) {\n return repeat(eol, numberLineBreaks) + repeat(indentValue, initialIndentLevel + indentLevel);\n }\n const amountOfSpaces = indentValue.length * (initialIndentLevel + indentLevel);\n if (!eolFastPathSupported || amountOfSpaces > cachedBreakLinesWithSpaces[indentType][eol].length) {\n return eol + repeat(indentValue, initialIndentLevel + indentLevel);\n }\n if (amountOfSpaces <= 0) {\n return eol;\n }\n return cachedBreakLinesWithSpaces[indentType][eol][amountOfSpaces];\n }\n function scanNext() {\n let token = scanner.scan();\n numberLineBreaks = 0;\n while (token === 15 /* SyntaxKind.Trivia */ || token === 14 /* SyntaxKind.LineBreakTrivia */) {\n if (token === 14 /* SyntaxKind.LineBreakTrivia */ && options.keepLines) {\n numberLineBreaks += 1;\n }\n else if (token === 14 /* SyntaxKind.LineBreakTrivia */) {\n numberLineBreaks = 1;\n }\n token = scanner.scan();\n }\n hasError = token === 16 /* SyntaxKind.Unknown */ || scanner.getTokenError() !== 0 /* ScanError.None */;\n return token;\n }\n const editOperations = [];\n function addEdit(text, startOffset, endOffset) {\n if (!hasError && (!range || (startOffset < rangeEnd && endOffset > rangeStart)) && documentText.substring(startOffset, endOffset) !== text) {\n editOperations.push({ offset: startOffset, length: endOffset - startOffset, content: text });\n }\n }\n let firstToken = scanNext();\n if (options.keepLines && numberLineBreaks > 0) {\n addEdit(repeat(eol, numberLineBreaks), 0, 0);\n }\n if (firstToken !== 17 /* SyntaxKind.EOF */) {\n let firstTokenStart = scanner.getTokenOffset() + formatTextStart;\n let initialIndent = (indentValue.length * initialIndentLevel < 20) && options.insertSpaces\n ? cachedSpaces[indentValue.length * initialIndentLevel]\n : repeat(indentValue, initialIndentLevel);\n addEdit(initialIndent, formatTextStart, firstTokenStart);\n }\n while (firstToken !== 17 /* SyntaxKind.EOF */) {\n let firstTokenEnd = scanner.getTokenOffset() + scanner.getTokenLength() + formatTextStart;\n let secondToken = scanNext();\n let replaceContent = '';\n let needsLineBreak = false;\n while (numberLineBreaks === 0 && (secondToken === 12 /* SyntaxKind.LineCommentTrivia */ || secondToken === 13 /* SyntaxKind.BlockCommentTrivia */)) {\n let commentTokenStart = scanner.getTokenOffset() + formatTextStart;\n addEdit(cachedSpaces[1], firstTokenEnd, commentTokenStart);\n firstTokenEnd = scanner.getTokenOffset() + scanner.getTokenLength() + formatTextStart;\n needsLineBreak = secondToken === 12 /* SyntaxKind.LineCommentTrivia */;\n replaceContent = needsLineBreak ? newLinesAndIndent() : '';\n secondToken = scanNext();\n }\n if (secondToken === 2 /* SyntaxKind.CloseBraceToken */) {\n if (firstToken !== 1 /* SyntaxKind.OpenBraceToken */) {\n indentLevel--;\n }\n ;\n if (options.keepLines && numberLineBreaks > 0 || !options.keepLines && firstToken !== 1 /* SyntaxKind.OpenBraceToken */) {\n replaceContent = newLinesAndIndent();\n }\n else if (options.keepLines) {\n replaceContent = cachedSpaces[1];\n }\n }\n else if (secondToken === 4 /* SyntaxKind.CloseBracketToken */) {\n if (firstToken !== 3 /* SyntaxKind.OpenBracketToken */) {\n indentLevel--;\n }\n ;\n if (options.keepLines && numberLineBreaks > 0 || !options.keepLines && firstToken !== 3 /* SyntaxKind.OpenBracketToken */) {\n replaceContent = newLinesAndIndent();\n }\n else if (options.keepLines) {\n replaceContent = cachedSpaces[1];\n }\n }\n else {\n switch (firstToken) {\n case 3 /* SyntaxKind.OpenBracketToken */:\n case 1 /* SyntaxKind.OpenBraceToken */:\n indentLevel++;\n if (options.keepLines && numberLineBreaks > 0 || !options.keepLines) {\n replaceContent = newLinesAndIndent();\n }\n else {\n replaceContent = cachedSpaces[1];\n }\n break;\n case 5 /* SyntaxKind.CommaToken */:\n if (options.keepLines && numberLineBreaks > 0 || !options.keepLines) {\n replaceContent = newLinesAndIndent();\n }\n else {\n replaceContent = cachedSpaces[1];\n }\n break;\n case 12 /* SyntaxKind.LineCommentTrivia */:\n replaceContent = newLinesAndIndent();\n break;\n case 13 /* SyntaxKind.BlockCommentTrivia */:\n if (numberLineBreaks > 0) {\n replaceContent = newLinesAndIndent();\n }\n else if (!needsLineBreak) {\n replaceContent = cachedSpaces[1];\n }\n break;\n case 6 /* SyntaxKind.ColonToken */:\n if (options.keepLines && numberLineBreaks > 0) {\n replaceContent = newLinesAndIndent();\n }\n else if (!needsLineBreak) {\n replaceContent = cachedSpaces[1];\n }\n break;\n case 10 /* SyntaxKind.StringLiteral */:\n if (options.keepLines && numberLineBreaks > 0) {\n replaceContent = newLinesAndIndent();\n }\n else if (secondToken === 6 /* SyntaxKind.ColonToken */ && !needsLineBreak) {\n replaceContent = '';\n }\n break;\n case 7 /* SyntaxKind.NullKeyword */:\n case 8 /* SyntaxKind.TrueKeyword */:\n case 9 /* SyntaxKind.FalseKeyword */:\n case 11 /* SyntaxKind.NumericLiteral */:\n case 2 /* SyntaxKind.CloseBraceToken */:\n case 4 /* SyntaxKind.CloseBracketToken */:\n if (options.keepLines && numberLineBreaks > 0) {\n replaceContent = newLinesAndIndent();\n }\n else {\n if ((secondToken === 12 /* SyntaxKind.LineCommentTrivia */ || secondToken === 13 /* SyntaxKind.BlockCommentTrivia */) && !needsLineBreak) {\n replaceContent = cachedSpaces[1];\n }\n else if (secondToken !== 5 /* SyntaxKind.CommaToken */ && secondToken !== 17 /* SyntaxKind.EOF */) {\n hasError = true;\n }\n }\n break;\n case 16 /* SyntaxKind.Unknown */:\n hasError = true;\n break;\n }\n if (numberLineBreaks > 0 && (secondToken === 12 /* SyntaxKind.LineCommentTrivia */ || secondToken === 13 /* SyntaxKind.BlockCommentTrivia */)) {\n replaceContent = newLinesAndIndent();\n }\n }\n if (secondToken === 17 /* SyntaxKind.EOF */) {\n if (options.keepLines && numberLineBreaks > 0) {\n replaceContent = newLinesAndIndent();\n }\n else {\n replaceContent = options.insertFinalNewline ? eol : '';\n }\n }\n const secondTokenStart = scanner.getTokenOffset() + formatTextStart;\n addEdit(replaceContent, firstTokenEnd, secondTokenStart);\n firstToken = secondToken;\n }\n return editOperations;\n}\nfunction repeat(s, count) {\n let result = '';\n for (let i = 0; i < count; i++) {\n result += s;\n }\n return result;\n}\nfunction computeIndentLevel(content, options) {\n let i = 0;\n let nChars = 0;\n const tabSize = options.tabSize || 4;\n while (i < content.length) {\n let ch = content.charAt(i);\n if (ch === cachedSpaces[1]) {\n nChars++;\n }\n else if (ch === '\\t') {\n nChars += tabSize;\n }\n else {\n break;\n }\n i++;\n }\n return Math.floor(nChars / tabSize);\n}\nfunction getEOL(options, text) {\n for (let i = 0; i < text.length; i++) {\n const ch = text.charAt(i);\n if (ch === '\\r') {\n if (i + 1 < text.length && text.charAt(i + 1) === '\\n') {\n return '\\r\\n';\n }\n return '\\r';\n }\n else if (ch === '\\n') {\n return '\\n';\n }\n }\n return (options && options.eol) || '\\n';\n}\nexport function isEOL(text, offset) {\n return '\\r\\n'.indexOf(text.charAt(offset)) !== -1;\n}\n", "/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n'use strict';\nimport { createScanner } from './scanner';\nvar ParseOptions;\n(function (ParseOptions) {\n ParseOptions.DEFAULT = {\n allowTrailingComma: false\n };\n})(ParseOptions || (ParseOptions = {}));\n/**\n * For a given offset, evaluate the location in the JSON document. Each segment in the location path is either a property name or an array index.\n */\nexport function getLocation(text, position) {\n const segments = []; // strings or numbers\n const earlyReturnException = new Object();\n let previousNode = undefined;\n const previousNodeInst = {\n value: {},\n offset: 0,\n length: 0,\n type: 'object',\n parent: undefined\n };\n let isAtPropertyKey = false;\n function setPreviousNode(value, offset, length, type) {\n previousNodeInst.value = value;\n previousNodeInst.offset = offset;\n previousNodeInst.length = length;\n previousNodeInst.type = type;\n previousNodeInst.colonOffset = undefined;\n previousNode = previousNodeInst;\n }\n try {\n visit(text, {\n onObjectBegin: (offset, length) => {\n if (position <= offset) {\n throw earlyReturnException;\n }\n previousNode = undefined;\n isAtPropertyKey = position > offset;\n segments.push(''); // push a placeholder (will be replaced)\n },\n onObjectProperty: (name, offset, length) => {\n if (position < offset) {\n throw earlyReturnException;\n }\n setPreviousNode(name, offset, length, 'property');\n segments[segments.length - 1] = name;\n if (position <= offset + length) {\n throw earlyReturnException;\n }\n },\n onObjectEnd: (offset, length) => {\n if (position <= offset) {\n throw earlyReturnException;\n }\n previousNode = undefined;\n segments.pop();\n },\n onArrayBegin: (offset, length) => {\n if (position <= offset) {\n throw earlyReturnException;\n }\n previousNode = undefined;\n segments.push(0);\n },\n onArrayEnd: (offset, length) => {\n if (position <= offset) {\n throw earlyReturnException;\n }\n previousNode = undefined;\n segments.pop();\n },\n onLiteralValue: (value, offset, length) => {\n if (position < offset) {\n throw earlyReturnException;\n }\n setPreviousNode(value, offset, length, getNodeType(value));\n if (position <= offset + length) {\n throw earlyReturnException;\n }\n },\n onSeparator: (sep, offset, length) => {\n if (position <= offset) {\n throw earlyReturnException;\n }\n if (sep === ':' && previousNode && previousNode.type === 'property') {\n previousNode.colonOffset = offset;\n isAtPropertyKey = false;\n previousNode = undefined;\n }\n else if (sep === ',') {\n const last = segments[segments.length - 1];\n if (typeof last === 'number') {\n segments[segments.length - 1] = last + 1;\n }\n else {\n isAtPropertyKey = true;\n segments[segments.length - 1] = '';\n }\n previousNode = undefined;\n }\n }\n });\n }\n catch (e) {\n if (e !== earlyReturnException) {\n throw e;\n }\n }\n return {\n path: segments,\n previousNode,\n isAtPropertyKey,\n matches: (pattern) => {\n let k = 0;\n for (let i = 0; k < pattern.length && i < segments.length; i++) {\n if (pattern[k] === segments[i] || pattern[k] === '*') {\n k++;\n }\n else if (pattern[k] !== '**') {\n return false;\n }\n }\n return k === pattern.length;\n }\n };\n}\n/**\n * Parses the given text and returns the object the JSON content represents. On invalid input, the parser tries to be as fault tolerant as possible, but still return a result.\n * Therefore always check the errors list to find out if the input was valid.\n */\nexport function parse(text, errors = [], options = ParseOptions.DEFAULT) {\n let currentProperty = null;\n let currentParent = [];\n const previousParents = [];\n function onValue(value) {\n if (Array.isArray(currentParent)) {\n currentParent.push(value);\n }\n else if (currentProperty !== null) {\n currentParent[currentProperty] = value;\n }\n }\n const visitor = {\n onObjectBegin: () => {\n const object = {};\n onValue(object);\n previousParents.push(currentParent);\n currentParent = object;\n currentProperty = null;\n },\n onObjectProperty: (name) => {\n currentProperty = name;\n },\n onObjectEnd: () => {\n currentParent = previousParents.pop();\n },\n onArrayBegin: () => {\n const array = [];\n onValue(array);\n previousParents.push(currentParent);\n currentParent = array;\n currentProperty = null;\n },\n onArrayEnd: () => {\n currentParent = previousParents.pop();\n },\n onLiteralValue: onValue,\n onError: (error, offset, length) => {\n errors.push({ error, offset, length });\n }\n };\n visit(text, visitor, options);\n return currentParent[0];\n}\n/**\n * Parses the given text and returns a tree representation the JSON content. On invalid input, the parser tries to be as fault tolerant as possible, but still return a result.\n */\nexport function parseTree(text, errors = [], options = ParseOptions.DEFAULT) {\n let currentParent = { type: 'array', offset: -1, length: -1, children: [], parent: undefined }; // artificial root\n function ensurePropertyComplete(endOffset) {\n if (currentParent.type === 'property') {\n currentParent.length = endOffset - currentParent.offset;\n currentParent = currentParent.parent;\n }\n }\n function onValue(valueNode) {\n currentParent.children.push(valueNode);\n return valueNode;\n }\n const visitor = {\n onObjectBegin: (offset) => {\n currentParent = onValue({ type: 'object', offset, length: -1, parent: currentParent, children: [] });\n },\n onObjectProperty: (name, offset, length) => {\n currentParent = onValue({ type: 'property', offset, length: -1, parent: currentParent, children: [] });\n currentParent.children.push({ type: 'string', value: name, offset, length, parent: currentParent });\n },\n onObjectEnd: (offset, length) => {\n ensurePropertyComplete(offset + length); // in case of a missing value for a property: make sure property is complete\n currentParent.length = offset + length - currentParent.offset;\n currentParent = currentParent.parent;\n ensurePropertyComplete(offset + length);\n },\n onArrayBegin: (offset, length) => {\n currentParent = onValue({ type: 'array', offset, length: -1, parent: currentParent, children: [] });\n },\n onArrayEnd: (offset, length) => {\n currentParent.length = offset + length - currentParent.offset;\n currentParent = currentParent.parent;\n ensurePropertyComplete(offset + length);\n },\n onLiteralValue: (value, offset, length) => {\n onValue({ type: getNodeType(value), offset, length, parent: currentParent, value });\n ensurePropertyComplete(offset + length);\n },\n onSeparator: (sep, offset, length) => {\n if (currentParent.type === 'property') {\n if (sep === ':') {\n currentParent.colonOffset = offset;\n }\n else if (sep === ',') {\n ensurePropertyComplete(offset);\n }\n }\n },\n onError: (error, offset, length) => {\n errors.push({ error, offset, length });\n }\n };\n visit(text, visitor, options);\n const result = currentParent.children[0];\n if (result) {\n delete result.parent;\n }\n return result;\n}\n/**\n * Finds the node at the given path in a JSON DOM.\n */\nexport function findNodeAtLocation(root, path) {\n if (!root) {\n return undefined;\n }\n let node = root;\n for (let segment of path) {\n if (typeof segment === 'string') {\n if (node.type !== 'object' || !Array.isArray(node.children)) {\n return undefined;\n }\n let found = false;\n for (const propertyNode of node.children) {\n if (Array.isArray(propertyNode.children) && propertyNode.children[0].value === segment && propertyNode.children.length === 2) {\n node = propertyNode.children[1];\n found = true;\n break;\n }\n }\n if (!found) {\n return undefined;\n }\n }\n else {\n const index = segment;\n if (node.type !== 'array' || index < 0 || !Array.isArray(node.children) || index >= node.children.length) {\n return undefined;\n }\n node = node.children[index];\n }\n }\n return node;\n}\n/**\n * Gets the JSON path of the given JSON DOM node\n */\nexport function getNodePath(node) {\n if (!node.parent || !node.parent.children) {\n return [];\n }\n const path = getNodePath(node.parent);\n if (node.parent.type === 'property') {\n const key = node.parent.children[0].value;\n path.push(key);\n }\n else if (node.parent.type === 'array') {\n const index = node.parent.children.indexOf(node);\n if (index !== -1) {\n path.push(index);\n }\n }\n return path;\n}\n/**\n * Evaluates the JavaScript object of the given JSON DOM node\n */\nexport function getNodeValue(node) {\n switch (node.type) {\n case 'array':\n return node.children.map(getNodeValue);\n case 'object':\n const obj = Object.create(null);\n for (let prop of node.children) {\n const valueNode = prop.children[1];\n if (valueNode) {\n obj[prop.children[0].value] = getNodeValue(valueNode);\n }\n }\n return obj;\n case 'null':\n case 'string':\n case 'number':\n case 'boolean':\n return node.value;\n default:\n return undefined;\n }\n}\nexport function contains(node, offset, includeRightBound = false) {\n return (offset >= node.offset && offset < (node.offset + node.length)) || includeRightBound && (offset === (node.offset + node.length));\n}\n/**\n * Finds the most inner node at the given offset. If includeRightBound is set, also finds nodes that end at the given offset.\n */\nexport function findNodeAtOffset(node, offset, includeRightBound = false) {\n if (contains(node, offset, includeRightBound)) {\n const children = node.children;\n if (Array.isArray(children)) {\n for (let i = 0; i < children.length && children[i].offset <= offset; i++) {\n const item = findNodeAtOffset(children[i], offset, includeRightBound);\n if (item) {\n return item;\n }\n }\n }\n return node;\n }\n return undefined;\n}\n/**\n * Parses the given text and invokes the visitor functions for each object, array and literal reached.\n */\nexport function visit(text, visitor, options = ParseOptions.DEFAULT) {\n const _scanner = createScanner(text, false);\n // Important: Only pass copies of this to visitor functions to prevent accidental modification, and\n // to not affect visitor functions which stored a reference to a previous JSONPath\n const _jsonPath = [];\n // Depth of onXXXBegin() callbacks suppressed. onXXXEnd() decrements this if it isn't 0 already.\n // Callbacks are only called when this value is 0.\n let suppressedCallbacks = 0;\n function toNoArgVisit(visitFunction) {\n return visitFunction ? () => suppressedCallbacks === 0 && visitFunction(_scanner.getTokenOffset(), _scanner.getTokenLength(), _scanner.getTokenStartLine(), _scanner.getTokenStartCharacter()) : () => true;\n }\n function toOneArgVisit(visitFunction) {\n return visitFunction ? (arg) => suppressedCallbacks === 0 && visitFunction(arg, _scanner.getTokenOffset(), _scanner.getTokenLength(), _scanner.getTokenStartLine(), _scanner.getTokenStartCharacter()) : () => true;\n }\n function toOneArgVisitWithPath(visitFunction) {\n return visitFunction ? (arg) => suppressedCallbacks === 0 && visitFunction(arg, _scanner.getTokenOffset(), _scanner.getTokenLength(), _scanner.getTokenStartLine(), _scanner.getTokenStartCharacter(), () => _jsonPath.slice()) : () => true;\n }\n function toBeginVisit(visitFunction) {\n return visitFunction ?\n () => {\n if (suppressedCallbacks > 0) {\n suppressedCallbacks++;\n }\n else {\n let cbReturn = visitFunction(_scanner.getTokenOffset(), _scanner.getTokenLength(), _scanner.getTokenStartLine(), _scanner.getTokenStartCharacter(), () => _jsonPath.slice());\n if (cbReturn === false) {\n suppressedCallbacks = 1;\n }\n }\n }\n : () => true;\n }\n function toEndVisit(visitFunction) {\n return visitFunction ?\n () => {\n if (suppressedCallbacks > 0) {\n suppressedCallbacks--;\n }\n if (suppressedCallbacks === 0) {\n visitFunction(_scanner.getTokenOffset(), _scanner.getTokenLength(), _scanner.getTokenStartLine(), _scanner.getTokenStartCharacter());\n }\n }\n : () => true;\n }\n const onObjectBegin = toBeginVisit(visitor.onObjectBegin), onObjectProperty = toOneArgVisitWithPath(visitor.onObjectProperty), onObjectEnd = toEndVisit(visitor.onObjectEnd), onArrayBegin = toBeginVisit(visitor.onArrayBegin), onArrayEnd = toEndVisit(visitor.onArrayEnd), onLiteralValue = toOneArgVisitWithPath(visitor.onLiteralValue), onSeparator = toOneArgVisit(visitor.onSeparator), onComment = toNoArgVisit(visitor.onComment), onError = toOneArgVisit(visitor.onError);\n const disallowComments = options && options.disallowComments;\n const allowTrailingComma = options && options.allowTrailingComma;\n function scanNext() {\n while (true) {\n const token = _scanner.scan();\n switch (_scanner.getTokenError()) {\n case 4 /* ScanError.InvalidUnicode */:\n handleError(14 /* ParseErrorCode.InvalidUnicode */);\n break;\n case 5 /* ScanError.InvalidEscapeCharacter */:\n handleError(15 /* ParseErrorCode.InvalidEscapeCharacter */);\n break;\n case 3 /* ScanError.UnexpectedEndOfNumber */:\n handleError(13 /* ParseErrorCode.UnexpectedEndOfNumber */);\n break;\n case 1 /* ScanError.UnexpectedEndOfComment */:\n if (!disallowComments) {\n handleError(11 /* ParseErrorCode.UnexpectedEndOfComment */);\n }\n break;\n case 2 /* ScanError.UnexpectedEndOfString */:\n handleError(12 /* ParseErrorCode.UnexpectedEndOfString */);\n break;\n case 6 /* ScanError.InvalidCharacter */:\n handleError(16 /* ParseErrorCode.InvalidCharacter */);\n break;\n }\n switch (token) {\n case 12 /* SyntaxKind.LineCommentTrivia */:\n case 13 /* SyntaxKind.BlockCommentTrivia */:\n if (disallowComments) {\n handleError(10 /* ParseErrorCode.InvalidCommentToken */);\n }\n else {\n onComment();\n }\n break;\n case 16 /* SyntaxKind.Unknown */:\n handleError(1 /* ParseErrorCode.InvalidSymbol */);\n break;\n case 15 /* SyntaxKind.Trivia */:\n case 14 /* SyntaxKind.LineBreakTrivia */:\n break;\n default:\n return token;\n }\n }\n }\n function handleError(error, skipUntilAfter = [], skipUntil = []) {\n onError(error);\n if (skipUntilAfter.length + skipUntil.length > 0) {\n let token = _scanner.getToken();\n while (token !== 17 /* SyntaxKind.EOF */) {\n if (skipUntilAfter.indexOf(token) !== -1) {\n scanNext();\n break;\n }\n else if (skipUntil.indexOf(token) !== -1) {\n break;\n }\n token = scanNext();\n }\n }\n }\n function parseString(isValue) {\n const value = _scanner.getTokenValue();\n if (isValue) {\n onLiteralValue(value);\n }\n else {\n onObjectProperty(value);\n // add property name afterwards\n _jsonPath.push(value);\n }\n scanNext();\n return true;\n }\n function parseLiteral() {\n switch (_scanner.getToken()) {\n case 11 /* SyntaxKind.NumericLiteral */:\n const tokenValue = _scanner.getTokenValue();\n let value = Number(tokenValue);\n if (isNaN(value)) {\n handleError(2 /* ParseErrorCode.InvalidNumberFormat */);\n value = 0;\n }\n onLiteralValue(value);\n break;\n case 7 /* SyntaxKind.NullKeyword */:\n onLiteralValue(null);\n break;\n case 8 /* SyntaxKind.TrueKeyword */:\n onLiteralValue(true);\n break;\n case 9 /* SyntaxKind.FalseKeyword */:\n onLiteralValue(false);\n break;\n default:\n return false;\n }\n scanNext();\n return true;\n }\n function parseProperty() {\n if (_scanner.getToken() !== 10 /* SyntaxKind.StringLiteral */) {\n handleError(3 /* ParseErrorCode.PropertyNameExpected */, [], [2 /* SyntaxKind.CloseBraceToken */, 5 /* SyntaxKind.CommaToken */]);\n return false;\n }\n parseString(false);\n if (_scanner.getToken() === 6 /* SyntaxKind.ColonToken */) {\n onSeparator(':');\n scanNext(); // consume colon\n if (!parseValue()) {\n handleError(4 /* ParseErrorCode.ValueExpected */, [], [2 /* SyntaxKind.CloseBraceToken */, 5 /* SyntaxKind.CommaToken */]);\n }\n }\n else {\n handleError(5 /* ParseErrorCode.ColonExpected */, [], [2 /* SyntaxKind.CloseBraceToken */, 5 /* SyntaxKind.CommaToken */]);\n }\n _jsonPath.pop(); // remove processed property name\n return true;\n }\n function parseObject() {\n onObjectBegin();\n scanNext(); // consume open brace\n let needsComma = false;\n while (_scanner.getToken() !== 2 /* SyntaxKind.CloseBraceToken */ && _scanner.getToken() !== 17 /* SyntaxKind.EOF */) {\n if (_scanner.getToken() === 5 /* SyntaxKind.CommaToken */) {\n if (!needsComma) {\n handleError(4 /* ParseErrorCode.ValueExpected */, [], []);\n }\n onSeparator(',');\n scanNext(); // consume comma\n if (_scanner.getToken() === 2 /* SyntaxKind.CloseBraceToken */ && allowTrailingComma) {\n break;\n }\n }\n else if (needsComma) {\n handleError(6 /* ParseErrorCode.CommaExpected */, [], []);\n }\n if (!parseProperty()) {\n handleError(4 /* ParseErrorCode.ValueExpected */, [], [2 /* SyntaxKind.CloseBraceToken */, 5 /* SyntaxKind.CommaToken */]);\n }\n needsComma = true;\n }\n onObjectEnd();\n if (_scanner.getToken() !== 2 /* SyntaxKind.CloseBraceToken */) {\n handleError(7 /* ParseErrorCode.CloseBraceExpected */, [2 /* SyntaxKind.CloseBraceToken */], []);\n }\n else {\n scanNext(); // consume close brace\n }\n return true;\n }\n function parseArray() {\n onArrayBegin();\n scanNext(); // consume open bracket\n let isFirstElement = true;\n let needsComma = false;\n while (_scanner.getToken() !== 4 /* SyntaxKind.CloseBracketToken */ && _scanner.getToken() !== 17 /* SyntaxKind.EOF */) {\n if (_scanner.getToken() === 5 /* SyntaxKind.CommaToken */) {\n if (!needsComma) {\n handleError(4 /* ParseErrorCode.ValueExpected */, [], []);\n }\n onSeparator(',');\n scanNext(); // consume comma\n if (_scanner.getToken() === 4 /* SyntaxKind.CloseBracketToken */ && allowTrailingComma) {\n break;\n }\n }\n else if (needsComma) {\n handleError(6 /* ParseErrorCode.CommaExpected */, [], []);\n }\n if (isFirstElement) {\n _jsonPath.push(0);\n isFirstElement = false;\n }\n else {\n _jsonPath[_jsonPath.length - 1]++;\n }\n if (!parseValue()) {\n handleError(4 /* ParseErrorCode.ValueExpected */, [], [4 /* SyntaxKind.CloseBracketToken */, 5 /* SyntaxKind.CommaToken */]);\n }\n needsComma = true;\n }\n onArrayEnd();\n if (!isFirstElement) {\n _jsonPath.pop(); // remove array index\n }\n if (_scanner.getToken() !== 4 /* SyntaxKind.CloseBracketToken */) {\n handleError(8 /* ParseErrorCode.CloseBracketExpected */, [4 /* SyntaxKind.CloseBracketToken */], []);\n }\n else {\n scanNext(); // consume close bracket\n }\n return true;\n }\n function parseValue() {\n switch (_scanner.getToken()) {\n case 3 /* SyntaxKind.OpenBracketToken */:\n return parseArray();\n case 1 /* SyntaxKind.OpenBraceToken */:\n return parseObject();\n case 10 /* SyntaxKind.StringLiteral */:\n return parseString(true);\n default:\n return parseLiteral();\n }\n }\n scanNext();\n if (_scanner.getToken() === 17 /* SyntaxKind.EOF */) {\n if (options.allowEmptyContent) {\n return true;\n }\n handleError(4 /* ParseErrorCode.ValueExpected */, [], []);\n return false;\n }\n if (!parseValue()) {\n handleError(4 /* ParseErrorCode.ValueExpected */, [], []);\n return false;\n }\n if (_scanner.getToken() !== 17 /* SyntaxKind.EOF */) {\n handleError(9 /* ParseErrorCode.EndOfFileExpected */, [], []);\n }\n return true;\n}\n/**\n * Takes JSON with JavaScript-style comments and remove\n * them. Optionally replaces every none-newline character\n * of comments with a replaceCharacter\n */\nexport function stripComments(text, replaceCh) {\n let _scanner = createScanner(text), parts = [], kind, offset = 0, pos;\n do {\n pos = _scanner.getPosition();\n kind = _scanner.scan();\n switch (kind) {\n case 12 /* SyntaxKind.LineCommentTrivia */:\n case 13 /* SyntaxKind.BlockCommentTrivia */:\n case 17 /* SyntaxKind.EOF */:\n if (offset !== pos) {\n parts.push(text.substring(offset, pos));\n }\n if (replaceCh !== undefined) {\n parts.push(_scanner.getTokenValue().replace(/[^\\r\\n]/g, replaceCh));\n }\n offset = _scanner.getPosition();\n break;\n }\n } while (kind !== 17 /* SyntaxKind.EOF */);\n return parts.join('');\n}\nexport function getNodeType(value) {\n switch (typeof value) {\n case 'boolean': return 'boolean';\n case 'number': return 'number';\n case 'string': return 'string';\n case 'object': {\n if (!value) {\n return 'null';\n }\n else if (Array.isArray(value)) {\n return 'array';\n }\n return 'object';\n }\n default: return 'null';\n }\n}\n", "/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n'use strict';\nimport { format, isEOL } from './format';\nimport { parseTree, findNodeAtLocation } from './parser';\nexport function removeProperty(text, path, options) {\n return setProperty(text, path, void 0, options);\n}\nexport function setProperty(text, originalPath, value, options) {\n const path = originalPath.slice();\n const errors = [];\n const root = parseTree(text, errors);\n let parent = void 0;\n let lastSegment = void 0;\n while (path.length > 0) {\n lastSegment = path.pop();\n parent = findNodeAtLocation(root, path);\n if (parent === void 0 && value !== void 0) {\n if (typeof lastSegment === 'string') {\n value = { [lastSegment]: value };\n }\n else {\n value = [value];\n }\n }\n else {\n break;\n }\n }\n if (!parent) {\n // empty document\n if (value === void 0) { // delete\n throw new Error('Can not delete in empty document');\n }\n return withFormatting(text, { offset: root ? root.offset : 0, length: root ? root.length : 0, content: JSON.stringify(value) }, options);\n }\n else if (parent.type === 'object' && typeof lastSegment === 'string' && Array.isArray(parent.children)) {\n const existing = findNodeAtLocation(parent, [lastSegment]);\n if (existing !== void 0) {\n if (value === void 0) { // delete\n if (!existing.parent) {\n throw new Error('Malformed AST');\n }\n const propertyIndex = parent.children.indexOf(existing.parent);\n let removeBegin;\n let removeEnd = existing.parent.offset + existing.parent.length;\n if (propertyIndex > 0) {\n // remove the comma of the previous node\n let previous = parent.children[propertyIndex - 1];\n removeBegin = previous.offset + previous.length;\n }\n else {\n removeBegin = parent.offset + 1;\n if (parent.children.length > 1) {\n // remove the comma of the next node\n let next = parent.children[1];\n removeEnd = next.offset;\n }\n }\n return withFormatting(text, { offset: removeBegin, length: removeEnd - removeBegin, content: '' }, options);\n }\n else {\n // set value of existing property\n return withFormatting(text, { offset: existing.offset, length: existing.length, content: JSON.stringify(value) }, options);\n }\n }\n else {\n if (value === void 0) { // delete\n return []; // property does not exist, nothing to do\n }\n const newProperty = `${JSON.stringify(lastSegment)}: ${JSON.stringify(value)}`;\n const index = options.getInsertionIndex ? options.getInsertionIndex(parent.children.map(p => p.children[0].value)) : parent.children.length;\n let edit;\n if (index > 0) {\n let previous = parent.children[index - 1];\n edit = { offset: previous.offset + previous.length, length: 0, content: ',' + newProperty };\n }\n else if (parent.children.length === 0) {\n edit = { offset: parent.offset + 1, length: 0, content: newProperty };\n }\n else {\n edit = { offset: parent.offset + 1, length: 0, content: newProperty + ',' };\n }\n return withFormatting(text, edit, options);\n }\n }\n else if (parent.type === 'array' && typeof lastSegment === 'number' && Array.isArray(parent.children)) {\n const insertIndex = lastSegment;\n if (insertIndex === -1) {\n // Insert\n const newProperty = `${JSON.stringify(value)}`;\n let edit;\n if (parent.children.length === 0) {\n edit = { offset: parent.offset + 1, length: 0, content: newProperty };\n }\n else {\n const previous = parent.children[parent.children.length - 1];\n edit = { offset: previous.offset + previous.length, length: 0, content: ',' + newProperty };\n }\n return withFormatting(text, edit, options);\n }\n else if (value === void 0 && parent.children.length >= 0) {\n // Removal\n const removalIndex = lastSegment;\n const toRemove = parent.children[removalIndex];\n let edit;\n if (parent.children.length === 1) {\n // only item\n edit = { offset: parent.offset + 1, length: parent.length - 2, content: '' };\n }\n else if (parent.children.length - 1 === removalIndex) {\n // last item\n let previous = parent.children[removalIndex - 1];\n let offset = previous.offset + previous.length;\n let parentEndOffset = parent.offset + parent.length;\n edit = { offset, length: parentEndOffset - 2 - offset, content: '' };\n }\n else {\n edit = { offset: toRemove.offset, length: parent.children[removalIndex + 1].offset - toRemove.offset, content: '' };\n }\n return withFormatting(text, edit, options);\n }\n else if (value !== void 0) {\n let edit;\n const newProperty = `${JSON.stringify(value)}`;\n if (!options.isArrayInsertion && parent.children.length > lastSegment) {\n const toModify = parent.children[lastSegment];\n edit = { offset: toModify.offset, length: toModify.length, content: newProperty };\n }\n else if (parent.children.length === 0 || lastSegment === 0) {\n edit = { offset: parent.offset + 1, length: 0, content: parent.children.length === 0 ? newProperty : newProperty + ',' };\n }\n else {\n const index = lastSegment > parent.children.length ? parent.children.length : lastSegment;\n const previous = parent.children[index - 1];\n edit = { offset: previous.offset + previous.length, length: 0, content: ',' + newProperty };\n }\n return withFormatting(text, edit, options);\n }\n else {\n throw new Error(`Can not ${value === void 0 ? 'remove' : (options.isArrayInsertion ? 'insert' : 'modify')} Array index ${insertIndex} as length is not sufficient`);\n }\n }\n else {\n throw new Error(`Can not add ${typeof lastSegment !== 'number' ? 'index' : 'property'} to parent of type ${parent.type}`);\n }\n}\nfunction withFormatting(text, edit, options) {\n if (!options.formattingOptions) {\n return [edit];\n }\n // apply the edit\n let newText = applyEdit(text, edit);\n // format the new text\n let begin = edit.offset;\n let end = edit.offset + edit.content.length;\n if (edit.length === 0 || edit.content.length === 0) { // insert or remove\n while (begin > 0 && !isEOL(newText, begin - 1)) {\n begin--;\n }\n while (end < newText.length && !isEOL(newText, end)) {\n end++;\n }\n }\n const edits = format(newText, { offset: begin, length: end - begin }, { ...options.formattingOptions, keepLines: false });\n // apply the formatting edits and track the begin and end offsets of the changes\n for (let i = edits.length - 1; i >= 0; i--) {\n const edit = edits[i];\n newText = applyEdit(newText, edit);\n begin = Math.min(begin, edit.offset);\n end = Math.max(end, edit.offset + edit.length);\n end += edit.content.length - edit.length;\n }\n // create a single edit with all changes\n const editLength = text.length - (newText.length - end) - begin;\n return [{ offset: begin, length: editLength, content: newText.substring(begin, end) }];\n}\nexport function applyEdit(text, edit) {\n return text.substring(0, edit.offset) + edit.content + text.substring(edit.offset + edit.length);\n}\nexport function isWS(text, offset) {\n return '\\r\\n \\t'.indexOf(text.charAt(offset)) !== -1;\n}\n", "/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n'use strict';\nimport * as formatter from './impl/format';\nimport * as edit from './impl/edit';\nimport * as scanner from './impl/scanner';\nimport * as parser from './impl/parser';\n/**\n * Creates a JSON scanner on the given text.\n * If ignoreTrivia is set, whitespaces or comments are ignored.\n */\nexport const createScanner = scanner.createScanner;\nexport var ScanError;\n(function (ScanError) {\n ScanError[ScanError[\"None\"] = 0] = \"None\";\n ScanError[ScanError[\"UnexpectedEndOfComment\"] = 1] = \"UnexpectedEndOfComment\";\n ScanError[ScanError[\"UnexpectedEndOfString\"] = 2] = \"UnexpectedEndOfString\";\n ScanError[ScanError[\"UnexpectedEndOfNumber\"] = 3] = \"UnexpectedEndOfNumber\";\n ScanError[ScanError[\"InvalidUnicode\"] = 4] = \"InvalidUnicode\";\n ScanError[ScanError[\"InvalidEscapeCharacter\"] = 5] = \"InvalidEscapeCharacter\";\n ScanError[ScanError[\"InvalidCharacter\"] = 6] = \"InvalidCharacter\";\n})(ScanError || (ScanError = {}));\nexport var SyntaxKind;\n(function (SyntaxKind) {\n SyntaxKind[SyntaxKind[\"OpenBraceToken\"] = 1] = \"OpenBraceToken\";\n SyntaxKind[SyntaxKind[\"CloseBraceToken\"] = 2] = \"CloseBraceToken\";\n SyntaxKind[SyntaxKind[\"OpenBracketToken\"] = 3] = \"OpenBracketToken\";\n SyntaxKind[SyntaxKind[\"CloseBracketToken\"] = 4] = \"CloseBracketToken\";\n SyntaxKind[SyntaxKind[\"CommaToken\"] = 5] = \"CommaToken\";\n SyntaxKind[SyntaxKind[\"ColonToken\"] = 6] = \"ColonToken\";\n SyntaxKind[SyntaxKind[\"NullKeyword\"] = 7] = \"NullKeyword\";\n SyntaxKind[SyntaxKind[\"TrueKeyword\"] = 8] = \"TrueKeyword\";\n SyntaxKind[SyntaxKind[\"FalseKeyword\"] = 9] = \"FalseKeyword\";\n SyntaxKind[SyntaxKind[\"StringLiteral\"] = 10] = \"StringLiteral\";\n SyntaxKind[SyntaxKind[\"NumericLiteral\"] = 11] = \"NumericLiteral\";\n SyntaxKind[SyntaxKind[\"LineCommentTrivia\"] = 12] = \"LineCommentTrivia\";\n SyntaxKind[SyntaxKind[\"BlockCommentTrivia\"] = 13] = \"BlockCommentTrivia\";\n SyntaxKind[SyntaxKind[\"LineBreakTrivia\"] = 14] = \"LineBreakTrivia\";\n SyntaxKind[SyntaxKind[\"Trivia\"] = 15] = \"Trivia\";\n SyntaxKind[SyntaxKind[\"Unknown\"] = 16] = \"Unknown\";\n SyntaxKind[SyntaxKind[\"EOF\"] = 17] = \"EOF\";\n})(SyntaxKind || (SyntaxKind = {}));\n/**\n * For a given offset, evaluate the location in the JSON document. Each segment in the location path is either a property name or an array index.\n */\nexport const getLocation = parser.getLocation;\n/**\n * Parses the given text and returns the object the JSON content represents. On invalid input, the parser tries to be as fault tolerant as possible, but still return a result.\n * Therefore, always check the errors list to find out if the input was valid.\n */\nexport const parse = parser.parse;\n/**\n * Parses the given text and returns a tree representation the JSON content. On invalid input, the parser tries to be as fault tolerant as possible, but still return a result.\n */\nexport const parseTree = parser.parseTree;\n/**\n * Finds the node at the given path in a JSON DOM.\n */\nexport const findNodeAtLocation = parser.findNodeAtLocation;\n/**\n * Finds the innermost node at the given offset. If includeRightBound is set, also finds nodes that end at the given offset.\n */\nexport const findNodeAtOffset = parser.findNodeAtOffset;\n/**\n * Gets the JSON path of the given JSON DOM node\n */\nexport const getNodePath = parser.getNodePath;\n/**\n * Evaluates the JavaScript object of the given JSON DOM node\n */\nexport const getNodeValue = parser.getNodeValue;\n/**\n * Parses the given text and invokes the visitor functions for each object, array and literal reached.\n */\nexport const visit = parser.visit;\n/**\n * Takes JSON with JavaScript-style comments and remove\n * them. Optionally replaces every none-newline character\n * of comments with a replaceCharacter\n */\nexport const stripComments = parser.stripComments;\nexport var ParseErrorCode;\n(function (ParseErrorCode) {\n ParseErrorCode[ParseErrorCode[\"InvalidSymbol\"] = 1] = \"InvalidSymbol\";\n ParseErrorCode[ParseErrorCode[\"InvalidNumberFormat\"] = 2] = \"InvalidNumberFormat\";\n ParseErrorCode[ParseErrorCode[\"PropertyNameExpected\"] = 3] = \"PropertyNameExpected\";\n ParseErrorCode[ParseErrorCode[\"ValueExpected\"] = 4] = \"ValueExpected\";\n ParseErrorCode[ParseErrorCode[\"ColonExpected\"] = 5] = \"ColonExpected\";\n ParseErrorCode[ParseErrorCode[\"CommaExpected\"] = 6] = \"CommaExpected\";\n ParseErrorCode[ParseErrorCode[\"CloseBraceExpected\"] = 7] = \"CloseBraceExpected\";\n ParseErrorCode[ParseErrorCode[\"CloseBracketExpected\"] = 8] = \"CloseBracketExpected\";\n ParseErrorCode[ParseErrorCode[\"EndOfFileExpected\"] = 9] = \"EndOfFileExpected\";\n ParseErrorCode[ParseErrorCode[\"InvalidCommentToken\"] = 10] = \"InvalidCommentToken\";\n ParseErrorCode[ParseErrorCode[\"UnexpectedEndOfComment\"] = 11] = \"UnexpectedEndOfComment\";\n ParseErrorCode[ParseErrorCode[\"UnexpectedEndOfString\"] = 12] = \"UnexpectedEndOfString\";\n ParseErrorCode[ParseErrorCode[\"UnexpectedEndOfNumber\"] = 13] = \"UnexpectedEndOfNumber\";\n ParseErrorCode[ParseErrorCode[\"InvalidUnicode\"] = 14] = \"InvalidUnicode\";\n ParseErrorCode[ParseErrorCode[\"InvalidEscapeCharacter\"] = 15] = \"InvalidEscapeCharacter\";\n ParseErrorCode[ParseErrorCode[\"InvalidCharacter\"] = 16] = \"InvalidCharacter\";\n})(ParseErrorCode || (ParseErrorCode = {}));\nexport function printParseErrorCode(code) {\n switch (code) {\n case 1 /* ParseErrorCode.InvalidSymbol */: return 'InvalidSymbol';\n case 2 /* ParseErrorCode.InvalidNumberFormat */: return 'InvalidNumberFormat';\n case 3 /* ParseErrorCode.PropertyNameExpected */: return 'PropertyNameExpected';\n case 4 /* ParseErrorCode.ValueExpected */: return 'ValueExpected';\n case 5 /* ParseErrorCode.ColonExpected */: return 'ColonExpected';\n case 6 /* ParseErrorCode.CommaExpected */: return 'CommaExpected';\n case 7 /* ParseErrorCode.CloseBraceExpected */: return 'CloseBraceExpected';\n case 8 /* ParseErrorCode.CloseBracketExpected */: return 'CloseBracketExpected';\n case 9 /* ParseErrorCode.EndOfFileExpected */: return 'EndOfFileExpected';\n case 10 /* ParseErrorCode.InvalidCommentToken */: return 'InvalidCommentToken';\n case 11 /* ParseErrorCode.UnexpectedEndOfComment */: return 'UnexpectedEndOfComment';\n case 12 /* ParseErrorCode.UnexpectedEndOfString */: return 'UnexpectedEndOfString';\n case 13 /* ParseErrorCode.UnexpectedEndOfNumber */: return 'UnexpectedEndOfNumber';\n case 14 /* ParseErrorCode.InvalidUnicode */: return 'InvalidUnicode';\n case 15 /* ParseErrorCode.InvalidEscapeCharacter */: return 'InvalidEscapeCharacter';\n case 16 /* ParseErrorCode.InvalidCharacter */: return 'InvalidCharacter';\n }\n return '<unknown ParseErrorCode>';\n}\n/**\n * Computes the edit operations needed to format a JSON document.\n *\n * @param documentText The input text\n * @param range The range to format or `undefined` to format the full content\n * @param options The formatting options\n * @returns The edit operations describing the formatting changes to the original document following the format described in {@linkcode EditResult}.\n * To apply the edit operations to the input, use {@linkcode applyEdits}.\n */\nexport function format(documentText, range, options) {\n return formatter.format(documentText, range, options);\n}\n/**\n * Computes the edit operations needed to modify a value in the JSON document.\n *\n * @param documentText The input text\n * @param path The path of the value to change. The path represents either to the document root, a property or an array item.\n * If the path points to an non-existing property or item, it will be created.\n * @param value The new value for the specified property or item. If the value is undefined,\n * the property or item will be removed.\n * @param options Options\n * @returns The edit operations describing the changes to the original document, following the format described in {@linkcode EditResult}.\n * To apply the edit operations to the input, use {@linkcode applyEdits}.\n */\nexport function modify(text, path, value, options) {\n return edit.setProperty(text, path, value, options);\n}\n/**\n * Applies edits to an input string.\n * @param text The input text\n * @param edits Edit operations following the format described in {@linkcode EditResult}.\n * @returns The text with the applied edits.\n * @throws An error if the edit operations are not well-formed as described in {@linkcode EditResult}.\n */\nexport function applyEdits(text, edits) {\n let sortedEdits = edits.slice(0).sort((a, b) => {\n const diff = a.offset - b.offset;\n if (diff === 0) {\n return a.length - b.length;\n }\n return diff;\n });\n let lastModifiedOffset = text.length;\n for (let i = sortedEdits.length - 1; i >= 0; i--) {\n let e = sortedEdits[i];\n if (e.offset + e.length <= lastModifiedOffset) {\n text = edit.applyEdit(text, e);\n }\n else {\n throw new Error('Overlapping edit');\n }\n lastModifiedOffset = e.offset;\n }\n return text;\n}\n", "/**\n * WebAssembly SQLite metadata index for mailx (Android/browser).\n * API-compatible with @bobfrankston/mailx-store's MailxDB.\n * Uses sql.js (SQLite compiled to WebAssembly) for in-browser SQLite.\n *\n * Database is persisted to IndexedDB on every write operation.\n * Bodies are stored in IndexedDB via WebMessageStore (not filesystem).\n */\n\nimport initSqlJs, { type Database } from \"sql.js\";\n// Inline the WebAssembly binary at bundle time (esbuild loader: \".wasm\" =\n// \"binary\"). The import resolves to a Uint8Array of the wasm bytes. We\n// pass these directly to initSqlJs via `wasmBinary`, skipping sql.js's\n// runtime fetch of the .wasm \u2014 Android WebView can't compile WASM\n// fetched from `file://` (no application/wasm MIME, and the ArrayBuffer\n// fallback fetch also blocks). Found via jserv logit 2026-05-14 v1.1.6.1:\n// \"wasm streaming compile failed \u2192 fallback ArrayBuffer instantiation\n// \u2192 both async and sync fetching of the wasm failed\". Embedding makes\n// the android-bootstrap bundle ~700 KB larger but eliminates the runtime\n// fetch dependency entirely. Desktop (msger) doesn't load this bundle \u2014\n// the check `if (!window.mailxapi)` in index.html routes desktop past\n// android-bootstrap.js \u2014 so the extra bytes only ship in the Android APK.\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nimport sqlWasmBinary from \"sql.js/dist/sql-wasm.wasm\";\nimport { parseSearchQuery, CONTACT_RULES } from \"@bobfrankston/mailx-types\";\nimport type { MessageEnvelope, Folder, EmailAddress, PagedResult, MessageQuery } from \"@bobfrankston/mailx-types\";\n\n/** Junk-contact filter regexes \u2014 sourced from contact-rules.jsonc so\n * desktop and Android share one rule definition. */\nconst JUNK_LOCAL_RE = new RegExp(CONTACT_RULES.junk.localExact, \"i\");\nconst JUNK_LOCAL_SUFFIX_RE = new RegExp(CONTACT_RULES.junk.localSuffix, \"i\");\nconst JUNK_LOCAL_PREFIX_RE = new RegExp(CONTACT_RULES.junk.localPrefix, \"i\");\nconst JUNK_DOMAIN_RE = new RegExp(CONTACT_RULES.junk.domain, \"i\");\nconst JUNK_LOCAL_ONEOFF_RE = new RegExp(CONTACT_RULES.junk.localOneoff, \"i\");\nfunction isJunkContact(email: string, name: string): boolean {\n const lower = (email || \"\").toLowerCase();\n const at = lower.indexOf(\"@\");\n const local = at >= 0 ? lower.slice(0, at) : lower;\n const domain = at >= 0 ? lower.slice(at + 1) : \"\";\n if (JUNK_LOCAL_RE.test(local)) return true;\n if (JUNK_LOCAL_SUFFIX_RE.test(local)) return true;\n if (JUNK_LOCAL_PREFIX_RE.test(local)) return true;\n if (JUNK_LOCAL_ONEOFF_RE.test(local)) return true;\n if (domain && JUNK_DOMAIN_RE.test(domain)) return true;\n if (local.length < 2) return true;\n const lname = (name || \"\").trim().toLowerCase();\n if (lname.includes(\"mailer-daemon\") || lname.includes(\"postmaster\")) return true;\n return false;\n}\n\nconst SCHEMA = `\n CREATE TABLE IF NOT EXISTS accounts (\n id TEXT PRIMARY KEY,\n name TEXT NOT NULL,\n email TEXT NOT NULL,\n config_json TEXT NOT NULL,\n last_sync INTEGER DEFAULT 0\n );\n\n CREATE TABLE IF NOT EXISTS folders (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n account_id TEXT NOT NULL REFERENCES accounts(id),\n path TEXT NOT NULL,\n name TEXT NOT NULL,\n special_use TEXT,\n delimiter TEXT DEFAULT '/',\n total_count INTEGER DEFAULT 0,\n unread_count INTEGER DEFAULT 0,\n uidvalidity INTEGER DEFAULT 0,\n highest_modseq TEXT DEFAULT '0',\n UNIQUE(account_id, path)\n );\n\n CREATE TABLE IF NOT EXISTS messages (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n account_id TEXT NOT NULL,\n folder_id INTEGER NOT NULL REFERENCES folders(id),\n uid INTEGER NOT NULL,\n message_id TEXT,\n in_reply_to TEXT,\n refs TEXT,\n date INTEGER NOT NULL,\n subject TEXT DEFAULT '',\n from_address TEXT DEFAULT '',\n from_name TEXT DEFAULT '',\n to_json TEXT DEFAULT '[]',\n cc_json TEXT DEFAULT '[]',\n flags_json TEXT DEFAULT '[]',\n size INTEGER DEFAULT 0,\n has_attachments INTEGER DEFAULT 0,\n preview TEXT DEFAULT '',\n body_path TEXT,\n cached_at INTEGER NOT NULL,\n UNIQUE(account_id, folder_id, uid)\n );\n\n CREATE INDEX IF NOT EXISTS idx_messages_folder_date\n ON messages(account_id, folder_id, date DESC);\n\n CREATE INDEX IF NOT EXISTS idx_messages_message_id\n ON messages(message_id);\n\n CREATE TABLE IF NOT EXISTS queue (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n status TEXT NOT NULL DEFAULT 'pending',\n created_at INTEGER NOT NULL,\n send_after INTEGER NOT NULL,\n attempts INTEGER DEFAULT 0,\n last_attempt INTEGER DEFAULT 0,\n error TEXT,\n from_account TEXT NOT NULL,\n to_json TEXT NOT NULL,\n cc_json TEXT DEFAULT '[]',\n bcc_json TEXT DEFAULT '[]',\n subject TEXT DEFAULT '',\n body_html TEXT DEFAULT '',\n body_text TEXT DEFAULT '',\n in_reply_to TEXT,\n refs TEXT\n );\n\n CREATE TABLE IF NOT EXISTS contacts (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n source TEXT NOT NULL DEFAULT 'sent',\n google_id TEXT,\n name TEXT DEFAULT '',\n email TEXT NOT NULL,\n organization TEXT DEFAULT '',\n last_used INTEGER DEFAULT 0,\n use_count INTEGER DEFAULT 0,\n updated_at INTEGER NOT NULL,\n UNIQUE(email)\n );\n\n CREATE INDEX IF NOT EXISTS idx_contacts_email ON contacts(email);\n CREATE INDEX IF NOT EXISTS idx_contacts_name ON contacts(name);\n\n CREATE TABLE IF NOT EXISTS sync_actions (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n account_id TEXT NOT NULL,\n action TEXT NOT NULL,\n uid INTEGER,\n folder_id INTEGER,\n target_folder_id INTEGER,\n flags_json TEXT,\n raw_message TEXT,\n created_at INTEGER NOT NULL,\n attempts INTEGER DEFAULT 0,\n last_error TEXT,\n UNIQUE(account_id, action, uid, folder_id)\n );\n\n -- Calendar events two-way cache (Android parity with desktop's\n -- packages/mailx-store/db.ts calendar_events table). uuid = stable\n -- local identity, provider_id = Google Calendar event id when known,\n -- dirty = local edit not yet pushed, deleted = tombstone pending delete.\n CREATE TABLE IF NOT EXISTS calendar_events (\n uuid TEXT PRIMARY KEY,\n account_id TEXT NOT NULL,\n provider_id TEXT,\n calendar_id TEXT DEFAULT 'primary',\n title TEXT NOT NULL DEFAULT '',\n start_ms INTEGER NOT NULL,\n end_ms INTEGER NOT NULL,\n all_day INTEGER DEFAULT 0,\n location TEXT DEFAULT '',\n notes TEXT DEFAULT '',\n etag TEXT,\n last_synced INTEGER DEFAULT 0,\n dirty INTEGER DEFAULT 0,\n deleted INTEGER DEFAULT 0,\n updated_at INTEGER NOT NULL\n );\n CREATE INDEX IF NOT EXISTS idx_calendar_events_start ON calendar_events(account_id, start_ms);\n\n CREATE TABLE IF NOT EXISTS tasks (\n uuid TEXT PRIMARY KEY,\n account_id TEXT NOT NULL,\n provider_id TEXT,\n list_id TEXT DEFAULT '@default',\n title TEXT NOT NULL DEFAULT '',\n notes TEXT DEFAULT '',\n due_ms INTEGER,\n completed_ms INTEGER,\n etag TEXT,\n last_synced INTEGER DEFAULT 0,\n dirty INTEGER DEFAULT 0,\n deleted INTEGER DEFAULT 0,\n updated_at INTEGER NOT NULL\n );\n CREATE INDEX IF NOT EXISTS idx_tasks_account ON tasks(account_id);\n\n -- Generic store-sync queue for non-message domains (calendar/tasks/contacts).\n CREATE TABLE IF NOT EXISTS store_sync (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n kind TEXT NOT NULL,\n op TEXT NOT NULL,\n account_id TEXT NOT NULL,\n target_uuid TEXT NOT NULL,\n payload TEXT,\n attempts INTEGER DEFAULT 0,\n last_error TEXT,\n created_at INTEGER NOT NULL,\n UNIQUE(kind, target_uuid, op)\n );\n`;\n\nconst IDB_NAME = \"mailx-sqldb\";\nconst IDB_STORE = \"database\";\nconst IDB_KEY = \"mailx.db\";\n\n// \u2500\u2500 IndexedDB persistence \u2500\u2500\n\nfunction openIdb(): Promise<IDBDatabase> {\n return new Promise((resolve, reject) => {\n const req = indexedDB.open(IDB_NAME, 1);\n req.onupgradeneeded = () => {\n const db = req.result;\n if (!db.objectStoreNames.contains(IDB_STORE)) {\n db.createObjectStore(IDB_STORE);\n }\n };\n req.onsuccess = () => resolve(req.result);\n req.onerror = () => reject(req.error);\n });\n}\n\nasync function loadDbFromIdb(): Promise<Uint8Array | null> {\n const idb = await openIdb();\n return new Promise((resolve, reject) => {\n const tx = idb.transaction(IDB_STORE, \"readonly\");\n const req = tx.objectStore(IDB_STORE).get(IDB_KEY);\n req.onsuccess = () => resolve(req.result ? new Uint8Array(req.result) : null);\n req.onerror = () => reject(req.error);\n });\n}\n\nasync function saveDbToIdb(data: Uint8Array): Promise<void> {\n const idb = await openIdb();\n return new Promise((resolve, reject) => {\n const tx = idb.transaction(IDB_STORE, \"readwrite\");\n tx.objectStore(IDB_STORE).put(data.buffer, IDB_KEY);\n tx.oncomplete = () => resolve();\n tx.onerror = () => reject(tx.error);\n });\n}\n\nasync function clearIdb(): Promise<void> {\n const idb = await openIdb();\n return new Promise((resolve, reject) => {\n const tx = idb.transaction(IDB_STORE, \"readwrite\");\n tx.objectStore(IDB_STORE).delete(IDB_KEY);\n tx.oncomplete = () => resolve();\n tx.onerror = () => reject(tx.error);\n });\n}\n\n// \u2500\u2500 Helper: convert sql.js result to array of objects \u2500\u2500\n\nfunction resultToRows(result: any[]): any[] {\n if (!result || result.length === 0) return [];\n const { columns, values } = result[0];\n return values.map((row: any[]) => {\n const obj: any = {};\n columns.forEach((col: string, i: number) => { obj[col] = row[i]; });\n return obj;\n });\n}\n\nexport class WebMailxDB {\n private db: Database | null = null;\n private ready: Promise<void>;\n private saveTimer: ReturnType<typeof setTimeout> | null = null;\n\n constructor(dbName = \"mailx\") {\n this.ready = this.init(dbName);\n }\n\n private async init(_dbName: string): Promise<void> {\n // wasmBinary is the bundle-inlined Uint8Array (see import + comment\n // at top of file). Bypasses sql.js's runtime fetch entirely \u2014 works\n // identically on Android WebView (file://), browser, desktop msger,\n // and Node tests. locateFile is omitted because nothing else in the\n // sql.js init path fetches anymore once wasmBinary is provided.\n // sql.js's TypeScript declarations don't include `wasmBinary` in\n // the InitSqlJsOptions type, but Emscripten honors it at runtime \u2014\n // the bytes go straight into WebAssembly.instantiate without a\n // fetch. Cast to `any` to bypass the type check.\n const SQL = await initSqlJs({\n wasmBinary: sqlWasmBinary,\n } as any);\n\n // Try to load existing DB from IndexedDB\n const existing = await loadDbFromIdb();\n if (existing) {\n this.db = new SQL.Database(existing);\n } else {\n this.db = new SQL.Database();\n }\n\n this.db.run(\"PRAGMA foreign_keys = ON\");\n this.db.run(SCHEMA);\n this.scheduleSave();\n }\n\n /** Wait for DB initialization */\n async waitReady(): Promise<void> {\n await this.ready;\n this.runOneShotJunkContactPurge();\n }\n\n /** One-shot junk-contact purge \u2014 see desktop equivalent in mailx-store/db.ts.\n * Bump TARGET when filter rules tighten so we sweep historical rows once\n * per device. Flag stored in localStorage (the web DB has no kv table). */\n private runOneShotJunkContactPurge(): void {\n const TARGET = CONTACT_RULES.rulesVersion;\n try {\n const last = localStorage.getItem(\"mailx-contacts-purge-v\");\n if (last === TARGET) return;\n const rows = this.all(\"SELECT id, email, name FROM contacts WHERE source IN ('discovered','sent','received')\") as { id: number; email: string; name: string }[];\n let dropped = 0;\n for (const r of rows) {\n if (isJunkContact(r.email || \"\", r.name || \"\")) {\n this.run(\"DELETE FROM contacts WHERE id = ?\", [r.id]);\n dropped++;\n }\n }\n localStorage.setItem(\"mailx-contacts-purge-v\", TARGET);\n if (dropped > 0) console.log(` [contacts] one-shot purge: dropped ${dropped} junk rows (${TARGET})`);\n } catch (e: any) {\n console.warn(`[contacts] one-shot purge failed: ${e.message}`);\n }\n }\n\n /** Persist DB to IndexedDB (debounced \u2014 batches rapid writes) */\n private scheduleSave(): void {\n if (this.saveTimer) return;\n this.saveTimer = setTimeout(async () => {\n this.saveTimer = null;\n if (this.db) {\n const data = this.db.export();\n await saveDbToIdb(data);\n }\n }, 1000);\n }\n\n /** Force immediate persist */\n async flush(): Promise<void> {\n if (this.saveTimer) {\n clearTimeout(this.saveTimer);\n this.saveTimer = null;\n }\n if (this.db) {\n const data = this.db.export();\n await saveDbToIdb(data);\n }\n }\n\n close(): void {\n if (this.db) {\n this.flush();\n this.db.close();\n this.db = null;\n }\n }\n\n private run(sql: string, params?: any[]): void {\n this.db!.run(sql, params);\n this.scheduleSave();\n }\n\n private get(sql: string, params?: any[]): any {\n const result = this.db!.exec(sql, params);\n const rows = resultToRows(result);\n return rows[0] || null;\n }\n\n private all(sql: string, params?: any[]): any[] {\n const result = this.db!.exec(sql, params);\n return resultToRows(result);\n }\n\n private lastId(): number {\n const row = this.get(\"SELECT last_insert_rowid() as id\");\n return row?.id || 0;\n }\n\n // \u2500\u2500 Accounts \u2500\u2500\n\n upsertAccount(id: string, name: string, email: string, configJson: string): void {\n this.run(\n `INSERT INTO accounts (id, name, email, config_json)\n VALUES (?, ?, ?, ?)\n ON CONFLICT(id) DO UPDATE SET name=?, email=?, config_json=?`,\n [id, name, email, configJson, name, email, configJson]);\n }\n\n getAccounts(): { id: string; name: string; email: string; lastSync: number }[] {\n return this.all(\"SELECT id, name, email, last_sync as lastSync FROM accounts\");\n }\n\n getAccountConfigs(): { id: string; name: string; email: string; configJson: string }[] {\n return this.all(\"SELECT id, name, email, config_json as configJson FROM accounts\");\n }\n\n updateLastSync(accountId: string, timestamp: number): void {\n this.run(\"UPDATE accounts SET last_sync = ? WHERE id = ?\", [timestamp, accountId]);\n }\n\n // \u2500\u2500 Folders \u2500\u2500\n\n upsertFolder(accountId: string, folderPath: string, name: string, specialUse: string, delimiter: string): number {\n const existing = this.get(\n \"SELECT id FROM folders WHERE account_id = ? AND path = ?\",\n [accountId, folderPath]);\n if (existing) {\n this.run(\"UPDATE folders SET name = ?, special_use = ?, delimiter = ? WHERE id = ?\",\n [name, specialUse, delimiter, existing.id]);\n return existing.id;\n }\n this.run(\"INSERT INTO folders (account_id, path, name, special_use, delimiter) VALUES (?, ?, ?, ?, ?)\",\n [accountId, folderPath, name, specialUse, delimiter]);\n return this.lastId();\n }\n\n getFolders(accountId: string): Folder[] {\n const rows = this.all(\"SELECT * FROM folders WHERE account_id = ? ORDER BY path\", [accountId]);\n return rows.map(r => ({\n id: r.id, accountId: r.account_id, path: r.path, name: r.name,\n specialUse: r.special_use, delimiter: r.delimiter,\n totalCount: r.total_count, unreadCount: r.unread_count,\n children: [] as Folder[]\n }));\n }\n\n deleteFolder(folderId: number): void {\n this.run(\"DELETE FROM messages WHERE folder_id = ?\", [folderId]);\n this.run(\"DELETE FROM folders WHERE id = ?\", [folderId]);\n }\n\n markFolderRead(folderId: number): void {\n this.run(\n `UPDATE messages SET flags_json = REPLACE(flags_json, '[]', '[\"\\\\\\\\Seen\"]')\n WHERE folder_id = ? AND flags_json NOT LIKE '%\\\\\\\\Seen%'`, [folderId]);\n this.recalcFolderCounts(folderId);\n }\n\n deleteAllMessages(accountId: string, folderId: number): void {\n this.run(\"DELETE FROM messages WHERE account_id = ? AND folder_id = ?\", [accountId, folderId]);\n this.recalcFolderCounts(folderId);\n }\n\n updateFolderCounts(folderId: number, total: number, unread: number): void {\n this.run(\"UPDATE folders SET total_count = ?, unread_count = ? WHERE id = ?\", [total, unread, folderId]);\n }\n\n updateFolderSync(folderId: number, uidvalidity: number, highestModseq: string): void {\n this.run(\"UPDATE folders SET uidvalidity = ?, highest_modseq = ? WHERE id = ?\",\n [uidvalidity, highestModseq, folderId]);\n }\n\n getFolderSync(folderId: number): { uidvalidity: number; highestModseq: string } {\n const row = this.get(\"SELECT uidvalidity, highest_modseq as highestModseq FROM folders WHERE id = ?\", [folderId]);\n return row || { uidvalidity: 0, highestModseq: \"0\" };\n }\n\n // \u2500\u2500 Messages \u2500\u2500\n\n upsertMessage(msg: {\n accountId: string; folderId: number; uid: number; messageId: string;\n inReplyTo: string; references: string[]; date: number; subject: string;\n from: EmailAddress; to: EmailAddress[]; cc: EmailAddress[];\n flags: string[]; size: number; hasAttachments: boolean; preview: string; bodyPath: string;\n }): number {\n const existing = this.get(\n \"SELECT id FROM messages WHERE account_id = ? AND folder_id = ? AND uid = ?\",\n [msg.accountId, msg.folderId, msg.uid]);\n if (existing) {\n this.run(`UPDATE messages SET flags_json = ?, preview = ?, body_path = ?, cached_at = ? WHERE id = ?`,\n [JSON.stringify(msg.flags), msg.preview, msg.bodyPath, Date.now(), existing.id]);\n return existing.id;\n }\n this.run(\n `INSERT INTO messages (\n account_id, folder_id, uid, message_id, in_reply_to, refs,\n date, subject, from_address, from_name, to_json, cc_json,\n flags_json, size, has_attachments, preview, body_path, cached_at\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,\n [\n msg.accountId, msg.folderId, msg.uid, msg.messageId,\n msg.inReplyTo, JSON.stringify(msg.references),\n msg.date, msg.subject, msg.from.address, msg.from.name,\n JSON.stringify(msg.to), JSON.stringify(msg.cc),\n JSON.stringify(msg.flags), msg.size, msg.hasAttachments ? 1 : 0,\n msg.preview, msg.bodyPath, Date.now()\n ]);\n return this.lastId();\n }\n\n getMessages(query: MessageQuery): PagedResult<MessageEnvelope> {\n const page = query.page || 1;\n const pageSize = query.pageSize || 50;\n const offset = (page - 1) * pageSize;\n const sortCol = query.sort === \"from\" ? \"from_name\" : query.sort === \"subject\" ? \"subject\" : \"date\";\n const sortDir = query.sortDir || \"desc\";\n\n let where = \"account_id = ? AND folder_id = ?\";\n const params: any[] = [query.accountId, query.folderId];\n if (query.search) {\n where += \" AND (subject LIKE ? OR from_name LIKE ? OR from_address LIKE ?)\";\n const term = `%${query.search}%`;\n params.push(term, term, term);\n }\n\n const countRow = this.get(`SELECT COUNT(*) as cnt FROM messages WHERE ${where}`, params);\n const total = countRow?.cnt || 0;\n const rows = this.all(\n `SELECT * FROM messages WHERE ${where} ORDER BY ${sortCol} ${sortDir} LIMIT ? OFFSET ?`,\n [...params, pageSize, offset]);\n return { items: rows.map(r => this.rowToEnvelope(r)), total, page, pageSize };\n }\n\n getUnifiedInbox(page = 1, pageSize = 50): PagedResult<MessageEnvelope> {\n const offset = (page - 1) * pageSize;\n const inboxRows = this.all(\"SELECT id FROM folders WHERE special_use = 'inbox'\");\n if (inboxRows.length === 0) return { items: [], total: 0, page, pageSize };\n const ids = inboxRows.map(r => r.id);\n const placeholders = ids.map(() => \"?\").join(\",\");\n const countRow = this.get(`SELECT COUNT(*) as cnt FROM messages WHERE folder_id IN (${placeholders})`, ids);\n const total = countRow?.cnt || 0;\n const rows = this.all(\n `SELECT * FROM messages WHERE folder_id IN (${placeholders}) ORDER BY date DESC LIMIT ? OFFSET ?`,\n [...ids, pageSize, offset]);\n return { items: rows.map(r => this.rowToEnvelope(r)), total, page, pageSize };\n }\n\n getMessageByUid(accountId: string, uid: number, folderId?: number): MessageEnvelope {\n const sql = folderId != null\n ? \"SELECT * FROM messages WHERE account_id = ? AND uid = ? AND folder_id = ?\"\n : \"SELECT * FROM messages WHERE account_id = ? AND uid = ?\";\n const params = folderId != null ? [accountId, uid, folderId] : [accountId, uid];\n const r = this.get(sql, params);\n if (!r) return null as any;\n return this.rowToEnvelope(r);\n }\n\n getMessageBodyPath(accountId: string, uid: number): string {\n const r = this.get(\"SELECT body_path FROM messages WHERE account_id = ? AND uid = ?\", [accountId, uid]);\n return r?.body_path || \"\";\n }\n\n /** The provider's own message id (Gmail message id) for a uid. Passed to\n * the Gmail provider's trash/move so it doesn't fall back to a capped\n * list-and-hash search that misses messages in a large mailbox. \"\" when\n * unknown \u2014 the provider then uses its (capped) fallback. */\n getProviderId(accountId: string, uid: number): string {\n const r = this.get(\"SELECT provider_id FROM messages WHERE account_id = ? AND uid = ?\", [accountId, uid]);\n return r?.provider_id || \"\";\n }\n\n updateMessageFlags(accountId: string, uid: number, flags: string[]): void {\n this.run(\"UPDATE messages SET flags_json = ? WHERE account_id = ? AND uid = ?\",\n [JSON.stringify(flags), accountId, uid]);\n }\n\n updateBodyPath(accountId: string, uid: number, bodyPath: string): void {\n this.run(\"UPDATE messages SET body_path = ? WHERE account_id = ? AND uid = ?\",\n [bodyPath, accountId, uid]);\n }\n\n getMessagesWithoutBody(accountId: string, limit = 50): { uid: number; folderId: number }[] {\n // \"idb:<acct>/<folder>/<uid>\" means the body is cached in IndexedDB via\n // WebMessageStore. Anything else (NULL, \"\", \"gmail:<id>\", legacy paths)\n // still needs fetching.\n // Prefetch order: smallest first, NULL/0 sizes last, recent within\n // tiebreak. Matches the desktop store \u2014 short notification mails\n // dominate the cache fill on slow Android networks instead of one\n // multi-megabyte attachment monopolizing bandwidth.\n return this.all(\n \"SELECT uid, folder_id as folderId FROM messages WHERE account_id = ? AND (body_path IS NULL OR body_path NOT LIKE 'idb:%') ORDER BY (size IS NULL OR size = 0), size ASC, date DESC LIMIT ?\",\n [accountId, limit]);\n }\n\n getHighestUid(accountId: string, folderId: number): number {\n const r = this.get(\"SELECT MAX(uid) as maxUid FROM messages WHERE account_id = ? AND folder_id = ?\",\n [accountId, folderId]);\n return r?.maxUid || 0;\n }\n\n getOldestDate(accountId: string, folderId: number): number {\n const r = this.get(\"SELECT MIN(date) as minDate FROM messages WHERE account_id = ? AND folder_id = ?\",\n [accountId, folderId]);\n return r?.minDate || 0;\n }\n\n getMessageCount(accountId: string, folderId: number): number {\n const r = this.get(\"SELECT count(*) as cnt FROM messages WHERE account_id = ? AND folder_id = ?\",\n [accountId, folderId]);\n return r?.cnt || 0;\n }\n\n getUidsForFolder(accountId: string, folderId: number): number[] {\n return this.all(\"SELECT uid FROM messages WHERE account_id = ? AND folder_id = ?\",\n [accountId, folderId]).map(r => r.uid);\n }\n\n deleteMessage(accountId: string, uid: number): void {\n const msg = this.get(\"SELECT folder_id FROM messages WHERE account_id = ? AND uid = ?\", [accountId, uid]);\n this.run(\"DELETE FROM messages WHERE account_id = ? AND uid = ?\", [accountId, uid]);\n if (msg) this.recalcFolderCounts(msg.folder_id);\n }\n\n recalcFolderCounts(folderId: number): void {\n const counts = this.get(\n `SELECT COUNT(*) as total,\n SUM(CASE WHEN flags_json NOT LIKE '%\\\\\\\\Seen%' THEN 1 ELSE 0 END) as unread\n FROM messages WHERE folder_id = ?`, [folderId]);\n this.updateFolderCounts(folderId, counts?.total || 0, counts?.unread || 0);\n }\n\n beginTransaction(): void { this.db!.run(\"BEGIN\"); }\n commitTransaction(): void { this.db!.run(\"COMMIT\"); this.scheduleSave(); }\n rollbackTransaction(): void { this.db!.run(\"ROLLBACK\"); }\n\n // \u2500\u2500 Contacts \u2500\u2500\n\n /** Delete every contact row tied to a single Google contact identity\n * (resourceName like \"people/c12345\"). Used by the People-API\n * incremental sync when Google flags a contact as deleted. A single\n * Google contact can have multiple email-rows; remove them all. */\n deleteContactByGoogleId(googleId: string): number {\n if (!googleId) return 0;\n const before = (this.get(\"SELECT COUNT(*) as c FROM contacts WHERE google_id = ?\", [googleId]) as any)?.c || 0;\n this.run(\"DELETE FROM contacts WHERE google_id = ?\", [googleId]);\n return before;\n }\n\n /** Stamp the google_id + organization on an already-recorded contact row.\n * Web side mirrors mailx-store/db.ts \u2014 the Google sync calls\n * `recordSentAddress` first to upsert, then this to attach the\n * Google identity for incremental delete tracking. */\n setContactGoogleId(email: string, googleId: string, organization: string): void {\n if (!email) return;\n this.run(\n \"UPDATE contacts SET source = 'google', google_id = ?, organization = ?, updated_at = ? WHERE email = ?\",\n [googleId, organization || \"\", Date.now(), email]);\n }\n\n recordSentAddress(name: string, email: string): void {\n if (isJunkContact(email, name)) return;\n const now = Date.now();\n const existing = this.get(\"SELECT id FROM contacts WHERE email = ?\", [email]);\n if (existing) {\n this.run(\n \"UPDATE contacts SET name = CASE WHEN ? != '' THEN ? ELSE name END, last_used = ?, use_count = use_count + 1, updated_at = ? WHERE email = ?\",\n [name, name, now, now, email]);\n } else {\n this.run(\n \"INSERT INTO contacts (source, name, email, last_used, use_count, updated_at) VALUES ('sent', ?, ?, ?, 1, ?)\",\n [name, email, now, now]);\n }\n }\n\n seedContactsFromMessages(): number {\n const now = Date.now();\n const rows = this.all(\n `SELECT from_name, from_address, COUNT(*) as cnt, MAX(date) as last\n FROM messages WHERE from_address != '' GROUP BY from_address`);\n let added = 0;\n for (const r of rows) {\n if (isJunkContact(r.from_address, r.from_name || \"\")) continue;\n const existing = this.get(\"SELECT id FROM contacts WHERE email = ?\", [r.from_address]);\n if (!existing) {\n this.run(\n \"INSERT INTO contacts (source, name, email, last_used, use_count, updated_at) VALUES ('received', ?, ?, ?, ?, ?)\",\n [r.from_name || \"\", r.from_address, r.last, r.cnt, now]);\n added++;\n }\n }\n return added;\n }\n\n /** Emails the user denylisted (contacts.jsonc#denylist). Filtered out of\n * autocomplete. Populated by web-service's loadContactsConfig. */\n private _denylist = new Set<string>();\n setContactsDenylist(emails: string[]): void {\n this._denylist = new Set((emails || [])\n .map(e => (e || \"\").trim().toLowerCase())\n .filter(Boolean));\n }\n\n searchContacts(query: string, limit = 10): { name: string; email: string; source: string; useCount: number }[] {\n query = (query || \"\").trim();\n if (!query) return [];\n const q = `%${query}%`;\n // Over-fetch, then drop denylisted rows in JS \u2014 filtering after a\n // hard SQL LIMIT could underfill the result when denylisted rows\n // rank high.\n const rows = this.all(\n `SELECT name, email, source, use_count as useCount FROM contacts\n WHERE email LIKE ? OR name LIKE ?\n ORDER BY use_count DESC, last_used DESC LIMIT ?`, [q, q, limit + 25]);\n return rows\n .filter((r: any) => !this._denylist.has((r.email || \"\").toLowerCase()))\n .slice(0, limit);\n }\n\n /** Address-book listing. Same shape as mailx-store/db.ts:listContacts so\n * the address-book modal renders identically on desktop and Android. */\n listContacts(query: string, page = 1, pageSize = 100): { items: any[]; total: number; page: number; pageSize: number } {\n query = (query || \"\").trim();\n const hasQuery = !!query;\n const q = `%${query}%`;\n const whereClause = hasQuery ? \"WHERE email LIKE ? OR name LIKE ?\" : \"\";\n const params: any[] = hasQuery ? [q, q] : [];\n const totalRow = this.get(`SELECT COUNT(*) as c FROM contacts ${whereClause}`, params);\n const offset = (page - 1) * pageSize;\n const rows = this.all(\n `SELECT name, email, source, google_id, use_count, last_used FROM contacts\n ${whereClause}\n ORDER BY use_count DESC, last_used DESC\n LIMIT ? OFFSET ?`, [...params, pageSize, offset]);\n return {\n items: rows.map((r: any) => ({\n name: r.name, email: r.email, source: r.source,\n googleId: r.google_id || null,\n useCount: r.use_count, lastUsed: r.last_used,\n })),\n total: (totalRow as any)?.c || 0,\n page, pageSize,\n };\n }\n\n upsertContact(name: string, email: string): void {\n if (!email || !/^[^\\s<>@]+@[^\\s<>@]+\\.[^\\s<>@]+$/.test(email)) {\n throw new Error(`Invalid email: ${email}`);\n }\n const now = Date.now();\n const existing = this.get(\"SELECT id FROM contacts WHERE email = ?\", [email]);\n if (existing) {\n this.run(\"UPDATE contacts SET name = ?, updated_at = ? WHERE email = ?\",\n [name || \"\", now, email]);\n } else {\n this.run(\"INSERT INTO contacts (source, name, email, last_used, use_count, updated_at) VALUES ('manual', ?, ?, 0, 0, ?)\",\n [name || \"\", email, now]);\n }\n }\n\n deleteContactLocal(email: string): void {\n this.run(\"DELETE FROM contacts WHERE email = ?\", [email]);\n }\n\n /** Q49 heuristic: has the user ever sent to `recipientEmail` with a\n * non-empty Cc? Scans Sent folder(s). Used by compose to auto-expand\n * the Cc row on reply to a frequent-Cc'd recipient. */\n hasCcHistoryTo(recipientEmail: string): boolean {\n const email = (recipientEmail || \"\").trim().toLowerCase();\n if (!email) return false;\n try {\n const row = this.get(`\n SELECT 1 FROM messages m\n JOIN folders f ON m.folder_id = f.id\n WHERE f.special_use = 'sent'\n AND lower(m.to_json) LIKE ?\n AND m.cc_json IS NOT NULL AND m.cc_json != '[]' AND m.cc_json != ''\n LIMIT 1\n `, [`%\"${email}\"%`]);\n return !!row;\n } catch {\n return false;\n }\n }\n\n // \u2500\u2500 Search \u2500\u2500\n\n searchMessages(query: string, page = 1, pageSize = 50, accountId?: string, folderId?: number): PagedResult<MessageEnvelope> {\n const offset = (page - 1) * pageSize;\n const parsed = parseSearchQuery(query);\n const allParams: any[] = [...parsed.params];\n let where = parsed.conditions.length > 0 ? parsed.conditions.join(\" AND \") : \"1=0\";\n if (accountId && folderId) {\n where += \" AND account_id = ? AND folder_id = ?\";\n allParams.push(accountId, folderId);\n } else if (accountId) {\n where += \" AND account_id = ?\";\n allParams.push(accountId);\n }\n const countRow = this.get(`SELECT COUNT(*) as cnt FROM messages WHERE ${where}`, allParams);\n const total = countRow?.cnt || 0;\n const rows = this.all(\n `SELECT * FROM messages WHERE ${where} ORDER BY date DESC LIMIT ? OFFSET ?`,\n [...allParams, pageSize, offset]);\n return { items: rows.map(r => this.rowToEnvelope(r)), total, page, pageSize };\n }\n\n // \u2500\u2500 Sync Actions \u2500\u2500\n\n queueSyncAction(accountId: string, action: string, uid: number, folderId: number, extra?: {\n targetFolderId?: number; flags?: string[]; rawMessage?: string;\n }): void {\n try {\n this.run(\n `INSERT OR REPLACE INTO sync_actions (account_id, action, uid, folder_id, target_folder_id, flags_json, raw_message, created_at)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,\n [accountId, action, uid, folderId,\n extra?.targetFolderId || null,\n extra?.flags ? JSON.stringify(extra.flags) : null,\n extra?.rawMessage || null,\n Date.now()]);\n } catch { /* UNIQUE constraint */ }\n }\n\n getPendingSyncActions(accountId: string): any[] {\n const rows = this.all(\"SELECT * FROM sync_actions WHERE account_id = ? ORDER BY created_at\", [accountId]);\n return rows.map(r => ({\n id: r.id, action: r.action, uid: r.uid, folderId: r.folder_id,\n targetFolderId: r.target_folder_id,\n flags: r.flags_json ? JSON.parse(r.flags_json) : [],\n rawMessage: r.raw_message, attempts: r.attempts,\n }));\n }\n\n completeSyncAction(id: number): void { this.run(\"DELETE FROM sync_actions WHERE id = ?\", [id]); }\n\n failSyncAction(id: number, error: string): void {\n this.run(\"UPDATE sync_actions SET attempts = attempts + 1, last_error = ? WHERE id = ?\", [error, id]);\n }\n\n /** Delete a queued sync action by (accountId, action, uid) \u2014 used by the\n * send path which tracks queued sends via a unique negative uid rather\n * than threading the row id through the async send pipeline. */\n completeSyncActionByUid(accountId: string, action: string, uid: number): void {\n this.run(\"DELETE FROM sync_actions WHERE account_id = ? AND action = ? AND uid = ?\",\n [accountId, action, uid]);\n }\n\n /** Mark a send-queue action failed by uid \u2014 same tracking-key rationale. */\n failSyncActionByUid(accountId: string, action: string, uid: number, error: string): void {\n this.run(\"UPDATE sync_actions SET attempts = attempts + 1, last_error = ? WHERE account_id = ? AND action = ? AND uid = ?\",\n [error, accountId, action, uid]);\n }\n\n getPendingSyncCount(accountId: string): number {\n const r = this.get(\"SELECT COUNT(*) as cnt FROM sync_actions WHERE account_id = ?\", [accountId]);\n return r?.cnt || 0;\n }\n\n getTotalPendingSyncCount(): number {\n const r = this.get(\"SELECT COUNT(*) as cnt FROM sync_actions\");\n return r?.cnt || 0;\n }\n\n /** Reset the entire database */\n async resetStore(): Promise<void> {\n this.run(\"DELETE FROM sync_actions\");\n this.run(\"DELETE FROM contacts\");\n this.run(\"DELETE FROM messages\");\n this.run(\"DELETE FROM folders\");\n this.run(\"DELETE FROM accounts\");\n this.run(\"DELETE FROM queue\");\n await clearIdb();\n }\n\n // \u2500\u2500 Helpers \u2500\u2500\n\n private rowToEnvelope(r: any): MessageEnvelope {\n return {\n id: r.id, accountId: r.account_id, folderId: r.folder_id,\n uid: r.uid, messageId: r.message_id || \"\", inReplyTo: r.in_reply_to || \"\",\n references: JSON.parse(r.refs || \"[]\"), date: r.date, subject: r.subject,\n from: { name: r.from_name, address: r.from_address },\n to: JSON.parse(r.to_json), cc: JSON.parse(r.cc_json),\n flags: JSON.parse(r.flags_json), size: r.size,\n hasAttachments: !!r.has_attachments, preview: r.preview,\n bodyPath: r.body_path || \"\"\n };\n }\n}\n", "/**\n * IndexedDB-based message body storage for Android/browser.\n * Mirrors FileMessageStore API from @bobfrankston/mailx-store.\n * Stores RFC 2822 message bodies as blobs keyed by accountId/folderId/uid.\n */\n\nconst DB_NAME = \"mailx-bodies\";\nconst DB_VERSION = 1;\nconst STORE_NAME = \"messages\";\n\nfunction openDb(): Promise<IDBDatabase> {\n return new Promise((resolve, reject) => {\n const req = indexedDB.open(DB_NAME, DB_VERSION);\n req.onupgradeneeded = () => {\n const db = req.result;\n if (!db.objectStoreNames.contains(STORE_NAME)) {\n db.createObjectStore(STORE_NAME);\n }\n };\n req.onsuccess = () => resolve(req.result);\n req.onerror = () => reject(req.error);\n });\n}\n\nfunction makeKey(accountId: string, folderId: number, uid: number): string {\n return `${accountId}/${folderId}/${uid}`;\n}\n\nexport class WebMessageStore {\n private dbPromise: Promise<IDBDatabase>;\n\n constructor() {\n this.dbPromise = openDb();\n }\n\n async putMessage(accountId: string, folderId: number, uid: number, raw: Uint8Array | ArrayBuffer): Promise<string> {\n const db = await this.dbPromise;\n const key = makeKey(accountId, folderId, uid);\n const data = raw instanceof Uint8Array ? raw.buffer.slice(raw.byteOffset, raw.byteOffset + raw.byteLength) : raw;\n return new Promise((resolve, reject) => {\n const tx = db.transaction(STORE_NAME, \"readwrite\");\n tx.objectStore(STORE_NAME).put(data, key);\n tx.oncomplete = () => resolve(key);\n tx.onerror = () => reject(tx.error);\n });\n }\n\n async getMessage(accountId: string, folderId: number, uid: number): Promise<Uint8Array | null> {\n const db = await this.dbPromise;\n const key = makeKey(accountId, folderId, uid);\n return new Promise((resolve, reject) => {\n const tx = db.transaction(STORE_NAME, \"readonly\");\n const req = tx.objectStore(STORE_NAME).get(key);\n req.onsuccess = () => {\n if (req.result) {\n resolve(new Uint8Array(req.result as ArrayBuffer));\n } else {\n resolve(null);\n }\n };\n req.onerror = () => reject(req.error);\n });\n }\n\n async deleteMessage(accountId: string, folderId: number, uid: number): Promise<void> {\n const db = await this.dbPromise;\n const key = makeKey(accountId, folderId, uid);\n return new Promise((resolve, reject) => {\n const tx = db.transaction(STORE_NAME, \"readwrite\");\n tx.objectStore(STORE_NAME).delete(key);\n tx.oncomplete = () => resolve();\n tx.onerror = () => reject(tx.error);\n });\n }\n\n async hasMessage(accountId: string, folderId: number, uid: number): Promise<boolean> {\n const db = await this.dbPromise;\n const key = makeKey(accountId, folderId, uid);\n return new Promise((resolve, reject) => {\n const tx = db.transaction(STORE_NAME, \"readonly\");\n const req = tx.objectStore(STORE_NAME).count(IDBKeyRange.only(key));\n req.onsuccess = () => resolve(req.result > 0);\n req.onerror = () => reject(req.error);\n });\n }\n\n /** Clear all stored bodies \u2014 used for \"Reset Store\" */\n async clear(): Promise<void> {\n const db = await this.dbPromise;\n return new Promise((resolve, reject) => {\n const tx = db.transaction(STORE_NAME, \"readwrite\");\n tx.objectStore(STORE_NAME).clear();\n tx.oncomplete = () => resolve();\n tx.onerror = () => reject(tx.error);\n });\n }\n}\n", "/**\n * Web-compatible MailxService for Android/browser.\n * Replaces @bobfrankston/mailx-service which depends on Node.js (fs, dns, mailparser).\n *\n * Key differences from desktop:\n * - Uses WebMailxDB (wa-sqlite) instead of MailxDB (node:sqlite)\n * - Uses WebMessageStore (IndexedDB) instead of FileMessageStore (filesystem)\n * - Uses postal-mime or manual header parsing instead of mailparser's simpleParser\n * - Settings via IndexedDB + GDrive API instead of filesystem\n * - No dns.resolveMx \u2014 provider detection is static (Gmail/Outlook/Yahoo/iCloud)\n */\n\nimport type { WebMailxDB } from \"./db.js\";\nimport type { WebMessageStore } from \"./web-message-store.js\";\nimport type { Folder, AutocompleteSettings, MailxApi } from \"@bobfrankston/mailx-types\";\nimport { sanitizeHtml, encodeQuotedPrintable, htmlToPlainText } from \"@bobfrankston/mailx-types\";\nimport {\n loadSettings, saveSettings, loadAccounts, loadAllowlist, saveAllowlist,\n loadAutocomplete, saveAutocomplete, getStorageInfo\n} from \"./web-settings.js\";\n\n// sanitizeHtml and encodeQuotedPrintable imported from @bobfrankston/mailx-types (shared with desktop)\n\n// \u2500\u2500 Simple email parser (replaces mailparser for browser) \u2500\u2500\n\ninterface ParsedMessage {\n html: string;\n text: string;\n headers: Map<string, string>;\n attachments: { filename: string; contentType: string; size: number; contentId: string; content: Uint8Array }[];\n}\n\n/** Parse an RFC 2822 message from raw bytes. Handles basic MIME. */\nfunction parseEmailSource(raw: string): ParsedMessage {\n const headers = new Map<string, string>();\n const headerEnd = raw.indexOf(\"\\r\\n\\r\\n\");\n const headerSection = headerEnd >= 0 ? raw.substring(0, headerEnd) : raw;\n const body = headerEnd >= 0 ? raw.substring(headerEnd + 4) : \"\";\n\n // Parse headers (handle continuations)\n const headerLines = headerSection.split(\"\\r\\n\");\n let lastKey = \"\";\n for (const line of headerLines) {\n if (line.startsWith(\" \") || line.startsWith(\"\\t\")) {\n // Continuation\n if (lastKey) {\n headers.set(lastKey, (headers.get(lastKey) || \"\") + \" \" + line.trim());\n }\n } else {\n const colon = line.indexOf(\":\");\n if (colon > 0) {\n lastKey = line.substring(0, colon).toLowerCase().trim();\n headers.set(lastKey, line.substring(colon + 1).trim());\n }\n }\n }\n\n const contentType = headers.get(\"content-type\") || \"text/plain\";\n const transferEncoding = (headers.get(\"content-transfer-encoding\") || \"\").toLowerCase();\n const attachments: ParsedMessage[\"attachments\"] = [];\n\n // Check for multipart\n const boundaryMatch = contentType.match(/boundary=\"?([^\";\\s]+)\"?/i);\n if (boundaryMatch) {\n const boundary = boundaryMatch[1];\n return parseMimeParts(body, boundary, headers);\n }\n\n // Single part\n let decoded = decodeBody(body, transferEncoding);\n const isHtml = contentType.includes(\"text/html\");\n\n return {\n html: isHtml ? decoded : \"\",\n text: isHtml ? \"\" : decoded,\n headers,\n attachments,\n };\n}\n\nfunction parseMimeParts(body: string, boundary: string, topHeaders: Map<string, string>): ParsedMessage {\n const parts = body.split(\"--\" + boundary);\n let html = \"\";\n let text = \"\";\n const attachments: ParsedMessage[\"attachments\"] = [];\n\n for (let i = 1; i < parts.length; i++) {\n const part = parts[i];\n if (part.startsWith(\"--\")) break; // End marker\n\n const partHeaderEnd = part.indexOf(\"\\r\\n\\r\\n\");\n if (partHeaderEnd < 0) continue;\n const partHeaderSection = part.substring(0, partHeaderEnd);\n const partBody = part.substring(partHeaderEnd + 4).replace(/\\r?\\n$/, \"\");\n\n // Parse part headers\n const partHeaders = new Map<string, string>();\n const partHeaderLines = partHeaderSection.split(\"\\r\\n\");\n let lastKey = \"\";\n for (const line of partHeaderLines) {\n if (line.startsWith(\" \") || line.startsWith(\"\\t\")) {\n if (lastKey) partHeaders.set(lastKey, (partHeaders.get(lastKey) || \"\") + \" \" + line.trim());\n } else {\n const colon = line.indexOf(\":\");\n if (colon > 0) {\n lastKey = line.substring(0, colon).toLowerCase().trim();\n partHeaders.set(lastKey, line.substring(colon + 1).trim());\n }\n }\n }\n\n const partType = partHeaders.get(\"content-type\") || \"text/plain\";\n const partEncoding = (partHeaders.get(\"content-transfer-encoding\") || \"\").toLowerCase();\n const disposition = partHeaders.get(\"content-disposition\") || \"\";\n\n // Nested multipart\n const nestedBoundary = partType.match(/boundary=\"?([^\";\\s]+)\"?/i);\n if (nestedBoundary) {\n const nested = parseMimeParts(partBody, nestedBoundary[1], topHeaders);\n if (!html && nested.html) html = nested.html;\n if (!text && nested.text) text = nested.text;\n attachments.push(...nested.attachments);\n continue;\n }\n\n if (disposition.includes(\"attachment\") || (partType.includes(\"application/\") && !partType.includes(\"text/\"))) {\n const filenameMatch = disposition.match(/filename=\"?([^\";\\r\\n]+)\"?/i) || partType.match(/name=\"?([^\";\\r\\n]+)\"?/i);\n const decoded = decodeBody(partBody, partEncoding);\n attachments.push({\n filename: filenameMatch?.[1]?.trim() || `attachment-${attachments.length}`,\n contentType: partType.split(\";\")[0].trim(),\n size: decoded.length,\n contentId: (partHeaders.get(\"content-id\") || \"\").replace(/[<>]/g, \"\"),\n content: new TextEncoder().encode(decoded),\n });\n } else if (partType.includes(\"text/html\")) {\n const charsetMatch = partType.match(/charset=\"?([^\";\\s]+)\"?/i);\n html = decodeBody(partBody, partEncoding, charsetMatch?.[1] || \"utf-8\");\n } else if (partType.includes(\"text/plain\")) {\n const charsetMatch = partType.match(/charset=\"?([^\";\\s]+)\"?/i);\n text = decodeBody(partBody, partEncoding, charsetMatch?.[1] || \"utf-8\");\n }\n }\n\n return { html, text, headers: topHeaders, attachments };\n}\n\nfunction decodeBody(body: string, encoding: string, charset: string = \"utf-8\"): string {\n // Step 1: decode the transfer encoding to a byte array\n let bytes: Uint8Array;\n if (encoding === \"base64\") {\n try {\n const binary = atob(body.replace(/\\s/g, \"\"));\n bytes = Uint8Array.from(binary, c => c.charCodeAt(0));\n } catch {\n return body;\n }\n } else if (encoding === \"quoted-printable\") {\n // Decode QP into bytes (NOT into a string \u2014 multi-byte UTF-8 must stay as bytes)\n const cleaned = body.replace(/=\\r?\\n/g, \"\");\n const out: number[] = [];\n for (let i = 0; i < cleaned.length; i++) {\n const c = cleaned[i];\n if (c === \"=\" && i + 2 < cleaned.length && /[0-9A-Fa-f]{2}/.test(cleaned.substr(i + 1, 2))) {\n out.push(parseInt(cleaned.substr(i + 1, 2), 16));\n i += 2;\n } else {\n // Existing character \u2014 encode as its byte (assumes ASCII for QP source)\n out.push(c.charCodeAt(0) & 0xff);\n }\n }\n bytes = new Uint8Array(out);\n } else if (encoding === \"7bit\" || encoding === \"8bit\" || encoding === \"\" || encoding === \"binary\") {\n // No transfer encoding \u2014 body is already a string of single-byte chars\n bytes = Uint8Array.from(body, c => c.charCodeAt(0) & 0xff);\n } else {\n // Unknown encoding \u2014 return as-is\n return body;\n }\n // Step 2: decode bytes using the declared charset (default UTF-8)\n try {\n const normalized = charset.toLowerCase().replace(\"windows-\", \"windows-\").replace(\"iso-\", \"iso-\");\n return new TextDecoder(normalized).decode(bytes);\n } catch {\n // Unknown charset \u2014 fall back to UTF-8 with replacement chars\n return new TextDecoder(\"utf-8\").decode(bytes);\n }\n}\n\n// \u2500\u2500 Quoted-printable encoding (for compose/send) \u2500\u2500\n\n// encodeQuotedPrintable imported from @bobfrankston/mailx-types\n\n// \u2500\u2500 Types for sync manager \u2500\u2500\n\nexport interface WebSyncManager {\n syncAll(): Promise<void>;\n syncFolders(accountId: string): Promise<Folder[]>;\n syncFolder(accountId: string, folderId: number): Promise<void>;\n fetchMessageBody(accountId: string, folderId: number, uid: number): Promise<Uint8Array | null>;\n updateFlagsLocal(accountId: string, uid: number, folderId: number, flags: string[]): Promise<void>;\n trashMessage(accountId: string, folderId: number, uid: number): Promise<void>;\n trashMessages(accountId: string, messages: { uid: number; folderId: number }[]): Promise<void>;\n moveMessage(accountId: string, uid: number, folderId: number, targetFolderId: number): Promise<void>;\n moveMessages(accountId: string, messages: { uid: number; folderId: number }[], targetFolderId: number): Promise<void>;\n moveMessageCrossAccount(accountId: string, uid: number, folderId: number, targetAccountId: string, targetFolderId: number): Promise<void>;\n undeleteMessage(accountId: string, uid: number, folderId: number): Promise<void>;\n queueOutgoingLocal(accountId: string, rawMessage: string): void | Promise<void>;\n saveDraft(accountId: string, raw: string, previousDraftUid?: number, draftId?: string): Promise<number | null>;\n deleteDraft(accountId: string, draftUid: number): Promise<void>;\n reauthenticate(accountId: string): Promise<boolean>;\n searchOnServer(accountId: string, folderPath: string, criteria: any): Promise<number[]>;\n syncAllContacts(): Promise<void>;\n addAccount(account: any): Promise<void>;\n on(event: string, handler: (...args: any[]) => void): void;\n emit(event: string, ...args: any[]): void;\n}\n\n// \u2500\u2500 Service \u2500\u2500\n\nexport class WebMailxService implements MailxApi {\n constructor(\n private db: WebMailxDB,\n private bodyStore: WebMessageStore,\n private syncManager: WebSyncManager,\n ) {}\n\n // \u2500\u2500 Accounts \u2500\u2500\n\n async getAccounts(): Promise<any[]> {\n const dbAccounts = this.db.getAccounts();\n const settings = await loadSettings();\n const ordered: any[] = [];\n for (const cfg of settings.accounts) {\n const a = dbAccounts.find(d => d.id === cfg.id);\n if (a) ordered.push({ ...a, label: cfg.label, defaultSend: cfg.defaultSend || false });\n }\n for (const a of dbAccounts) {\n if (!ordered.find((o: any) => o.id === a.id)) ordered.push(a);\n }\n return ordered;\n }\n\n // \u2500\u2500 Folders \u2500\u2500\n\n getFolders(accountId: string): Folder[] {\n return this.db.getFolders(accountId);\n }\n\n // \u2500\u2500 Messages \u2500\u2500\n\n getUnifiedInbox(page = 1, pageSize = 50): any {\n return this.db.getUnifiedInbox(page, pageSize);\n }\n\n getMessages(accountId: string, folderId: number, page = 1, pageSize = 50, sort = \"date\", sortDir = \"desc\", search?: string): any {\n return this.db.getMessages({ accountId, folderId, page, pageSize, sort: sort as any, sortDir: sortDir as any, search });\n }\n\n async getMessage(accountId: string, uid: number, allowRemote = false, folderId?: number): Promise<any> {\n const envelope = this.db.getMessageByUid(accountId, uid, folderId);\n if (!envelope) throw new Error(\"Message not found\");\n\n let bodyHtml = \"\";\n let bodyText = \"\";\n let hasRemoteContent = false;\n let attachments: { id: number; filename: string; mimeType: string; size: number; contentId: string }[] = [];\n\n let raw: Uint8Array | null = null;\n try {\n raw = await this.syncManager.fetchMessageBody(accountId, envelope.folderId, envelope.uid);\n } catch (fetchErr: any) {\n // Mirror the desktop service: surface as structured bodyError\n // so the viewer shows its dedicated error banner instead of\n // rendering the message text verbatim in the body area.\n const rawErr = fetchErr.message || \"fetch failed\";\n const isTransient = /connection|Too many|UNAVAILABLE|rate|429|5\\d\\d|timeout|ENOTFOUND|ECONNRESET|ETIMEDOUT/i.test(rawErr);\n return {\n ...envelope, bodyHtml: \"\", bodyText: \"\",\n bodyError: rawErr, bodyErrorTransient: isTransient,\n hasRemoteContent: false, remoteAllowed: false, attachments: [], deliveredTo: \"\", returnPath: \"\", listUnsubscribe: \"\"\n };\n }\n\n if (!raw) {\n return {\n ...envelope, bodyHtml: \"\", bodyText: \"\",\n bodyError: \"Message body not cached locally and the server fetch returned nothing.\",\n bodyErrorTransient: true,\n hasRemoteContent: false, remoteAllowed: false, attachments: [], deliveredTo: \"\", returnPath: \"\", listUnsubscribe: \"\"\n };\n } else {\n const source = new TextDecoder().decode(raw);\n const parsed = parseEmailSource(source);\n bodyHtml = parsed.html || \"\";\n bodyText = parsed.text || \"\";\n attachments = (parsed.attachments || []).map((a, i) => ({\n id: i,\n filename: a.filename || `attachment-${i}`,\n mimeType: a.contentType || \"application/octet-stream\",\n size: a.size || 0,\n contentId: a.contentId || \"\"\n }));\n }\n\n // Sanitize HTML + compute flagged-sender state. flaggedSenders /\n // flaggedDomains live in the same allowlist.jsonc as remote-content\n // permissions; matching this on phone parity-fixes the viewer's\n // \u26A0 FLAGGED banner (which only painted on desktop before).\n const allowList = await loadAllowlist();\n const senderAddr = (envelope.from?.address || \"\").toLowerCase();\n const senderDomain = senderAddr.split(\"@\")[1] || \"\";\n const isFlagged = !!(\n (allowList.flaggedSenders || []).some((s: string) => (s || \"\").toLowerCase() === senderAddr) ||\n (allowList.flaggedDomains || []).some((d: string) => (d || \"\").toLowerCase() === senderDomain)\n );\n if (bodyHtml && !allowRemote) {\n const toAddrs = (envelope.to || []).map((a: any) => a.address);\n const isAllowed = allowList.senders.includes(senderAddr) ||\n allowList.domains.includes(senderDomain) ||\n toAddrs.some((a: string) => allowList.recipients?.includes(a));\n\n if (isAllowed) {\n allowRemote = true;\n } else {\n const result = sanitizeHtml(bodyHtml);\n bodyHtml = result.html;\n hasRemoteContent = result.hasRemoteContent;\n }\n }\n\n return {\n ...envelope, bodyHtml, bodyText, hasRemoteContent, remoteAllowed: allowRemote,\n attachments, deliveredTo: \"\", returnPath: \"\", listUnsubscribe: \"\",\n isFlagged,\n };\n }\n\n /** Flag (or unflag) a sender / domain. Mirrors the desktop service so\n * the viewer's right-click \"Flag sender\" / \"Flag domain\" buttons work\n * on phone \u2014 was a no-op on Android before. Toggles membership in\n * flaggedSenders / flaggedDomains in allowlist.jsonc, which syncs\n * back to the cloud copy. */\n async flagSenderOrDomain(type: \"sender\" | \"domain\", value: string): Promise<{ flagged: boolean }> {\n const list = await loadAllowlist() as any;\n const key = type === \"sender\" ? \"flaggedSenders\" : \"flaggedDomains\";\n const arr: string[] = Array.isArray(list[key]) ? list[key] : [];\n const v = (value || \"\").trim().toLowerCase();\n if (!v) return { flagged: false };\n const idx = arr.findIndex((x: string) => (x || \"\").toLowerCase() === v);\n let flagged: boolean;\n if (idx >= 0) {\n arr.splice(idx, 1);\n flagged = false;\n } else {\n arr.push(v);\n flagged = true;\n }\n list[key] = arr;\n await saveAllowlist(list);\n return { flagged };\n }\n\n async updateFlags(accountId: string, uid: number, flags: string[]): Promise<void> {\n const envelope = this.db.getMessageByUid(accountId, uid);\n await this.syncManager.updateFlagsLocal(accountId, uid, envelope?.folderId || 0, flags);\n }\n\n // \u2500\u2500 Remote content allow-list \u2500\u2500\n\n async allowRemoteContent(type: \"sender\" | \"domain\" | \"recipient\", value: string): Promise<void> {\n const list = await loadAllowlist();\n if (type === \"sender\" && !list.senders.includes(value)) list.senders.push(value);\n else if (type === \"domain\" && !list.domains.includes(value)) list.domains.push(value);\n else if (type === \"recipient\") {\n if (!list.recipients) list.recipients = [];\n if (!list.recipients.includes(value)) list.recipients.push(value);\n }\n await saveAllowlist(list);\n }\n\n // \u2500\u2500 Search \u2500\u2500\n\n async search(q: string, page = 1, pageSize = 50, scope = \"all\", accountId?: string, folderId?: number): Promise<any> {\n if (!q.trim()) return { items: [], total: 0, page, pageSize };\n // On mobile, always use local search (no server-side IMAP search)\n if (scope === \"current\" && accountId && folderId) {\n return this.db.searchMessages(q, page, pageSize, accountId, folderId);\n }\n return this.db.searchMessages(q, page, pageSize);\n }\n\n // \u2500\u2500 Sync \u2500\u2500\n\n getSyncPending(): { pending: number } {\n return { pending: this.db.getTotalPendingSyncCount() };\n }\n\n async syncAll(): Promise<void> {\n await this.syncManager.syncAll();\n }\n\n async syncAccount(accountId: string): Promise<void> {\n const folders = await this.syncManager.syncFolders(accountId);\n // INBOX-first: await INBOX so the UI re-renders new mail immediately,\n // then fire the rest in the background so labels don't block the\n // list. S57 (Android parity with desktop's local-first rule).\n const inbox = folders.find(f => f.specialUse === \"inbox\");\n const others = folders.filter(f => f.specialUse !== \"inbox\");\n if (inbox) {\n try { await this.syncManager.syncFolder(accountId, inbox.id); }\n catch (e: any) { console.error(` Skipping INBOX ${inbox.path}: ${e.message}`); }\n }\n // Background fan-out: don't await; errors log. UI already has INBOX.\n (async () => {\n for (const folder of others) {\n try { await this.syncManager.syncFolder(accountId, folder.id); }\n catch (e: any) { console.error(` Skipping folder ${folder.path}: ${e.message}`); }\n }\n })().catch(() => { /* top-level already logged */ });\n }\n\n async reauthenticate(accountId: string): Promise<boolean> {\n return this.syncManager.reauthenticate(accountId);\n }\n\n // \u2500\u2500 Send \u2500\u2500\n\n async send(msg: any): Promise<void> {\n const settings = await loadSettings();\n const account = settings.accounts.find(a => a.id === msg.from);\n if (!account) throw new Error(`Unknown account: ${msg.from}`);\n\n const fromHeader = msg.fromAddress || `${account.name} <${account.email}>`;\n const to = msg.to.map((a: any) => a.name ? `${a.name} <${a.address}>` : a.address).join(\", \");\n const cc = msg.cc?.map((a: any) => a.name ? `${a.name} <${a.address}>` : a.address).join(\", \");\n const bcc = msg.bcc?.map((a: any) => a.name ? `${a.name} <${a.address}>` : a.address).join(\", \");\n // HTML-bodied send gets a multipart/alternative wrapper with a\n // text/plain derived from the HTML \u2014 matches desktop's path; spam\n // filters score HTML-only mail harshly without it.\n const hasHtml = !!msg.bodyHtml;\n const htmlBody = msg.bodyHtml || \"\";\n const textBody = msg.bodyText || (hasHtml ? htmlToPlainText(htmlBody) : \"\");\n const htmlEncoded = hasHtml ? encodeQuotedPrintable(htmlBody) : \"\";\n const textEncoded = encodeQuotedPrintable(textBody);\n\n const domain = account.email.split(\"@\")[1] || \"mailx.local\";\n const messageId = `<${Date.now()}.${Math.random().toString(36).slice(2)}@${domain}>`;\n\n const envelope = [\n `From: ${fromHeader}`, `To: ${to}`,\n cc ? `Cc: ${cc}` : null, bcc ? `Bcc: ${bcc}` : null,\n `Subject: ${msg.subject}`, `Date: ${new Date().toUTCString()}`,\n `Message-ID: ${messageId}`,\n msg.inReplyTo ? `In-Reply-To: ${msg.inReplyTo}` : null,\n msg.references?.length ? `References: ${msg.references.join(\" \")}` : null,\n `MIME-Version: 1.0`,\n ].filter(h => h !== null);\n\n let rawMessage: string;\n if (hasHtml) {\n const altBoundary = `mailx_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 10)}`;\n const body =\n `--${altBoundary}\\r\\n` +\n `Content-Type: text/plain; charset=UTF-8\\r\\n` +\n `Content-Transfer-Encoding: quoted-printable\\r\\n\\r\\n` +\n `${textEncoded}\\r\\n` +\n `--${altBoundary}\\r\\n` +\n `Content-Type: text/html; charset=UTF-8\\r\\n` +\n `Content-Transfer-Encoding: quoted-printable\\r\\n\\r\\n` +\n `${htmlEncoded}\\r\\n` +\n `--${altBoundary}--\\r\\n`;\n const headers = [\n ...envelope,\n `Content-Type: multipart/alternative; boundary=\"${altBoundary}\"`,\n ].join(\"\\r\\n\");\n rawMessage = `${headers}\\r\\n\\r\\n${body}`;\n } else {\n const headers = [\n ...envelope,\n `Content-Type: text/plain; charset=UTF-8`,\n `Content-Transfer-Encoding: quoted-printable`,\n ].join(\"\\r\\n\");\n rawMessage = `${headers}\\r\\n\\r\\n${textEncoded}`;\n }\n\n // queueOutgoingLocal on the Android bridge is async (it flushes\n // sql.js \u2192 IndexedDB before returning so a tab-close in the\n // debounce window can't lose the row). On the web-worker\n // SyncManager it's synchronous and returns void; awaiting an\n // undefined value is benign, so this works for both.\n await this.syncManager.queueOutgoingLocal(account.id, rawMessage);\n\n for (const addr of msg.to) this.db.recordSentAddress(addr.name, addr.address);\n if (msg.cc) for (const addr of msg.cc) this.db.recordSentAddress(addr.name, addr.address);\n if (msg.bcc) for (const addr of msg.bcc) this.db.recordSentAddress(addr.name, addr.address);\n }\n\n // \u2500\u2500 Delete / Move \u2500\u2500\n\n async deleteMessage(accountId: string, uid: number): Promise<void> {\n const envelope = this.db.getMessageByUid(accountId, uid);\n if (!envelope) throw new Error(\"Message not found\");\n await this.syncManager.trashMessage(accountId, envelope.folderId, envelope.uid);\n }\n\n async deleteMessages(accountId: string, uids: number[]): Promise<void> {\n const messages = uids.map(uid => {\n const env = this.db.getMessageByUid(accountId, uid);\n if (!env) return null;\n return { uid: env.uid, folderId: env.folderId };\n }).filter(m => m !== null);\n await this.syncManager.trashMessages(accountId, messages);\n }\n\n async moveMessage(accountId: string, uid: number, targetFolderId: number, targetAccountId?: string): Promise<void> {\n const envelope = this.db.getMessageByUid(accountId, uid);\n if (!envelope) throw new Error(\"Message not found\");\n if (targetAccountId && targetAccountId !== accountId) {\n await this.syncManager.moveMessageCrossAccount(accountId, envelope.uid, envelope.folderId, targetAccountId, targetFolderId);\n } else {\n await this.syncManager.moveMessage(accountId, envelope.uid, envelope.folderId, targetFolderId);\n }\n }\n\n async moveMessages(accountId: string, uids: number[], targetFolderId: number): Promise<void> {\n const messages = uids.map(uid => {\n const env = this.db.getMessageByUid(accountId, uid);\n if (!env) return null;\n return { uid: env.uid, folderId: env.folderId };\n }).filter(m => m !== null);\n await this.syncManager.moveMessages(accountId, messages, targetFolderId);\n }\n\n async undeleteMessage(accountId: string, uid: number, folderId: number): Promise<void> {\n await this.syncManager.undeleteMessage(accountId, uid, folderId);\n }\n\n // \u2500\u2500 Drafts \u2500\u2500\n\n async saveDraft(accountId: string, subject: string, bodyHtml: string, bodyText: string, to?: string, cc?: string, previousDraftUid?: number, draftId?: string): Promise<{ draftUid: number | null; draftId: string }> {\n const settings = await loadSettings();\n const account = settings.accounts.find(a => a.id === accountId);\n if (!account) throw new Error(`Unknown account: ${accountId}`);\n\n const id = draftId || `mailx-draft-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;\n const body = bodyHtml || bodyText || \"\";\n const bodyEncoded = encodeQuotedPrintable(body);\n\n const headers = [\n `From: ${account.name} <${account.email}>`,\n to ? `To: ${to}` : null, cc ? `Cc: ${cc}` : null,\n `Subject: ${subject || \"(no subject)\"}`, `Date: ${new Date().toUTCString()}`,\n `X-Mailx-Draft-ID: ${id}`,\n `MIME-Version: 1.0`, `Content-Type: text/html; charset=UTF-8`, `Content-Transfer-Encoding: quoted-printable`,\n ].filter(h => h !== null).join(\"\\r\\n\");\n const raw = `${headers}\\r\\n\\r\\n${bodyEncoded}`;\n const draftUid = await this.syncManager.saveDraft(accountId, raw, previousDraftUid, id);\n // Was `{ uid, draftId }` \u2014 silent drift from desktop's `{ draftUid, draftId }`\n // contract. Clients reading `data.draftUid` got undefined on Android,\n // breaking dedup on the next save.\n return { draftUid, draftId: id };\n }\n\n async deleteDraft(accountId: string, draftUid: number): Promise<void> {\n await this.syncManager.deleteDraft(accountId, draftUid);\n }\n\n // \u2500\u2500 Contacts \u2500\u2500\n\n searchContacts(query: string): any[] {\n query = (query || \"\").trim();\n if (query.length < 1) return [];\n return this.db.searchContacts(query);\n }\n\n /** Address-book listing \u2014 paginated, filterable. Mirrors mailx-service's\n * signature so the same client-side address-book modal works on Android\n * without an \"ipc(...).listContacts is not a function\" crash. */\n listContacts(query: string, page = 1, pageSize = 100) {\n return this.db.listContacts(query || \"\", page, pageSize);\n }\n\n /** Manual upsert from the address-book UI. The desktop path queues a\n * Google People sync; Android relies on the desktop pushing changes\n * back, so this is local-only for now. */\n upsertContact(name: string, email: string): { ok: true } {\n this.db.upsertContact(name || \"\", email);\n return { ok: true };\n }\n\n deleteContact(email: string): { ok: true } {\n this.db.deleteContactLocal(email);\n return { ok: true };\n }\n\n addContact(name: string, email: string): boolean {\n if (!email || !/^[^\\s<>@]+@[^\\s<>@]+\\.[^\\s<>@]+$/.test(email)) return false;\n this.db.recordSentAddress(name || \"\", email);\n return true;\n }\n\n /** Q49 heuristic mirror: true if the user has ever sent a message to\n * `recipientEmail` that had a non-empty Cc field. Compose uses this to\n * decide whether to auto-expand the Cc row on reply. */\n hasCcHistoryTo(recipientEmail: string): boolean {\n return (this.db as any).hasCcHistoryTo?.(recipientEmail) ?? false;\n }\n\n // \u2500\u2500 Settings \u2500\u2500\n\n async getSettings(): Promise<any> {\n return loadSettings();\n }\n\n async saveSettingsData(settings: any): Promise<void> {\n await saveSettings(settings);\n }\n\n getStorageInfo(): { provider: string; mode: string; folderId?: string; folderName?: string; folderPath?: string; folderOwner?: string } {\n return getStorageInfo();\n }\n\n // \u2500\u2500 Folder management (limited on mobile \u2014 read-only) \u2500\u2500\n\n markFolderRead(folderId: number): void {\n this.db.markFolderRead(folderId);\n }\n\n // \u2500\u2500 Autocomplete \u2500\u2500\n\n async getAutocompleteSettings(): Promise<AutocompleteSettings> {\n return loadAutocomplete();\n }\n\n async saveAutocompleteSettings(settings: AutocompleteSettings): Promise<void> {\n await saveAutocomplete(settings);\n }\n\n async autocomplete(_req: any): Promise<{ suggestion: string }> {\n // Autocomplete disabled on mobile by default\n return { suggestion: \"\" };\n }\n\n // \u2500\u2500 Reset \u2500\u2500\n\n async resetStore(): Promise<void> {\n await this.db.resetStore();\n await this.bodyStore.clear();\n console.log(\"[service] Store reset complete\");\n }\n\n // \u2500\u2500 JSONC config editor (Android: GDrive only; no local config.jsonc) \u2500\u2500\n // Mirror of the desktop service so the in-app editor works on phone.\n // Android sandbox has no per-machine config.jsonc; selecting it returns\n // null (the editor displays \"(file not available on this platform)\").\n\n async readJsoncFile(name: string): Promise<string | null> {\n const WHITELIST = [\"accounts.jsonc\", \"allowlist.jsonc\", \"clients.jsonc\", \"config.jsonc\", \"contacts.jsonc\"];\n if (!WHITELIST.includes(name)) throw new Error(`File not allowed: ${name}`);\n if (name === \"config.jsonc\") return null; // local-only on desktop; n/a on Android\n const { cloudRead } = await import(\"./web-settings.js\");\n return await cloudRead(name);\n }\n\n async writeJsoncFile(name: string, content: string): Promise<void> {\n const WHITELIST = [\"accounts.jsonc\", \"allowlist.jsonc\", \"clients.jsonc\", \"config.jsonc\", \"contacts.jsonc\"];\n if (!WHITELIST.includes(name)) throw new Error(`File not allowed: ${name}`);\n if (name === \"config.jsonc\") throw new Error(\"config.jsonc is local-only \u2014 not editable on Android\");\n const { parse: parseJsonc } = await import(\"jsonc-parser\");\n const errors: any[] = [];\n parseJsonc(content, errors, { allowTrailingComma: true });\n if (errors.length) {\n throw new Error(`JSONC parse error: ${errors.map(e => e.error).join(\", \")}`);\n }\n const { cloudWrite } = await import(\"./web-settings.js\");\n const ok = await cloudWrite(name, content);\n if (!ok) throw new Error(`Failed to save ${name} to Drive`);\n }\n\n async formatJsonc(content: string): Promise<string> {\n const { format, applyEdits } = await import(\"jsonc-parser\");\n const edits = format(content, undefined, {\n tabSize: 2, insertSpaces: true, eol: \"\\n\", insertFinalNewline: true,\n });\n return applyEdits(content, edits);\n }\n\n async readConfigHelp(_name: string): Promise<string> {\n // Help markdown isn't bundled in the Android assets \u2014 return empty\n // so the editor's help panel just shows \"No help available\".\n return \"\";\n }\n\n // \u2500\u2500 Priority senders / domains (Android parity) \u2500\u2500\n // Cached in-memory; refreshed on every read since contacts.jsonc is\n // small (~hundreds of entries) and reads hit IndexedDB cache.\n\n /** Compute and return the priority sender / domain index from the\n * current contacts.jsonc. Reads from cloud (or local cache) every\n * call \u2014 small file, simpler than maintaining a long-lived cache. */\n async getPriorityLists(): Promise<{ senders: string[]; domains: string[] }> {\n const { cloudRead } = await import(\"./web-settings.js\");\n const raw = await cloudRead(\"contacts.jsonc\");\n if (!raw) return { senders: [], domains: [] };\n const cfg = parseJsoncLoose(raw);\n const senders = Array.isArray(cfg?.preferred)\n ? cfg.preferred.filter((e: any) => e?.priority === true && e.email).map((e: any) => (e.email as string).toLowerCase())\n : [];\n const domains = Array.isArray(cfg?.priorityDomains)\n ? cfg.priorityDomains.map((d: string) => (d || \"\").toLowerCase()).filter(Boolean)\n : [];\n return { senders, domains };\n }\n\n async setPrioritySender(email: string, value: boolean, name?: string): Promise<void> {\n const lower = (email || \"\").trim().toLowerCase();\n if (!lower) return;\n const { cloudRead, cloudWrite } = await import(\"./web-settings.js\");\n const raw = await cloudRead(\"contacts.jsonc\");\n const cfg = raw ? parseJsoncLoose(raw) || {} : {};\n if (!Array.isArray(cfg.preferred)) cfg.preferred = [];\n const idx = cfg.preferred.findIndex((e: any) => (e?.email || \"\").toLowerCase() === lower);\n if (idx >= 0) {\n if (value) cfg.preferred[idx].priority = true;\n else delete cfg.preferred[idx].priority;\n } else if (value) {\n cfg.preferred.push({ name: name || \"\", email, priority: true });\n }\n await cloudWrite(\"contacts.jsonc\", JSON.stringify(cfg, null, 2));\n }\n\n async setPriorityDomain(domain: string, value: boolean): Promise<void> {\n const lower = (domain || \"\").trim().toLowerCase();\n if (!lower) return;\n const { cloudRead, cloudWrite } = await import(\"./web-settings.js\");\n const raw = await cloudRead(\"contacts.jsonc\");\n const cfg = raw ? parseJsoncLoose(raw) || {} : {};\n if (!Array.isArray(cfg.priorityDomains)) cfg.priorityDomains = [];\n const i = cfg.priorityDomains.findIndex((d: string) => (d || \"\").toLowerCase() === lower);\n if (value && i < 0) cfg.priorityDomains.push(lower);\n else if (!value && i >= 0) cfg.priorityDomains.splice(i, 1);\n await cloudWrite(\"contacts.jsonc\", JSON.stringify(cfg, null, 2));\n }\n\n // \u2500\u2500 MailxApi contract: name aliases \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n // The IPC dispatch names (`sendMessage`, `searchMessages`) differ from\n // the historical web method names (`send`, `search`). Thin aliases keep\n // the existing internal method bodies while satisfying `implements\n // MailxApi`. NEW methods should use the IPC name directly so this\n // section doesn't grow.\n sendMessage(msg: any): Promise<void> { return this.send(msg); }\n searchMessages(query: string, page?: number, pageSize?: number, scope?: string, accountId?: string, folderId?: number, _includeTrashSpam?: boolean): Promise<any> {\n // Android `search` lacks the includeTrashSpam flag \u2014 folder scoping\n // is enforced UI-side anyway. Drop the 7th argument silently.\n return this.search(query, page, pageSize, scope, accountId, folderId);\n }\n\n // \u2500\u2500 MailxApi contract: explicit stubs for unimplemented Android features \u2500\n //\n // Every method below is in the contract but has no Android implementation\n // today. Each is declared explicitly so it's *visible* in this file \u2014\n // before the contract was added, these were just absent and IPC calls\n // returned \"parent bridge has no method X\", silently swallowed by\n // `.catch()` in callers. Now the gap is in one auditable list.\n //\n // Implementation policy:\n // - Pure read with no Android backing: return [] / {} / null / false.\n // UI degrades gracefully; no crash.\n // - Write that mutates state: throw `notImpl()` so a UI button that\n // calls it surfaces an error rather than appearing to succeed.\n // - OS-specific (Word, msger popups, OS file open): also `notImpl()`.\n // These are declared optional `?:` in the contract so we technically\n // could omit them entirely \u2014 explicit stubs are clearer.\n //\n // To wire one up: replace the stub body, run tsc, the contract enforces\n // the signature.\n\n private notImpl(name: string): never {\n throw new Error(`Not implemented on Android: ${name}`);\n }\n\n // Threads / attachments / message reads\n getThreadMessages(_accountId: string, _threadId: string): any { return []; }\n async getAttachment(_accountId: string, _uid: number, _attachmentId: number, _folderId?: number): Promise<{ content: any; contentType: string; filename: string }> { return this.notImpl(\"getAttachment\"); }\n\n // Spam / abuse\n async markAsSpamMessages(_accountId: string, _uids: number[]): Promise<{ targetFolderId: number; moved: number }> { return this.notImpl(\"markAsSpamMessages\"); }\n async recordSpamReport(_accountId: string, _uid: number, _folderId: number): Promise<any> { return this.notImpl(\"recordSpamReport\"); }\n\n // Folder CRUD\n async createFolder(_accountId: string, _parentPath: string, _name: string): Promise<void> { this.notImpl(\"createFolder\"); }\n async renameFolder(_accountId: string, _folderId: number, _newName: string): Promise<void> { this.notImpl(\"renameFolder\"); }\n async deleteFolder(_accountId: string, _folderId: number): Promise<void> { this.notImpl(\"deleteFolder\"); }\n async moveFolderToTrash(_accountId: string, _folderId: number): Promise<void> { this.notImpl(\"moveFolderToTrash\"); }\n async emptyFolder(_accountId: string, _folderId: number): Promise<void> { this.notImpl(\"emptyFolder\"); }\n\n // Outbox management\n getOutboxStatus(): any { return { count: 0, items: [] }; }\n listQueuedOutgoing(): any[] { return []; }\n cancelQueuedOutgoing(_filePath: string): { ok: true } { return { ok: true }; }\n\n // Sync infrastructure \u2014 getSyncPending already defined above\n async drainStoreSync(): Promise<void> { /* no-op on Android */ }\n reauthGoogleScopes(): { cleared: number } { return { cleared: 0 }; }\n\n // Contacts extensions. The contacts.jsonc mutation logic is shared with\n // the desktop service \u2014 see mailx-types/contacts-config.ts. These used\n // to be `notImpl()` stubs, so the phone's \u2605 / \u2298 autocomplete buttons did\n // nothing; now they run the same code desktop does.\n async addPreferredContact(entry: { name: string; email: string; source?: string; organization?: string }): Promise<void> {\n const { cloudRead, cloudWrite } = await import(\"./web-settings.js\");\n const { addContactsPreferredEntry } = await import(\"@bobfrankston/mailx-types\");\n await addContactsPreferredEntry(entry, cloudRead, cloudWrite);\n await this.loadContactsConfig();\n }\n async addToDenylist(email: string): Promise<void> {\n const { cloudRead, cloudWrite } = await import(\"./web-settings.js\");\n const { addContactsDenylistEntry } = await import(\"@bobfrankston/mailx-types\");\n await addContactsDenylistEntry(email, cloudRead, cloudWrite);\n await this.loadContactsConfig();\n }\n hasBccHistoryTo(_email: string): boolean { return false; }\n /** Pull the shared GDrive `contacts.jsonc` and merge its entries into the\n * local contacts table. Desktop flushes the full union there (everything\n * it discovered from its mailbox corpus + Google contacts + preferred);\n * this is how an Android device gets contacts it never saw in its own\n * (partial) on-device corpus. Called once at startup \u2014 re-importing on a\n * loop would bump `use_count` every pass and distort autocomplete rank. */\n async loadContactsConfig(): Promise<any> {\n try {\n const { cloudRead } = await import(\"./web-settings.js\");\n const raw = await cloudRead(\"contacts.jsonc\");\n if (!raw) return null;\n const cfg = parseJsoncLoose(raw);\n if (!cfg) return null;\n // Apply the denylist so denylisted addresses are filtered out of\n // autocomplete \u2014 without this the \u2298 button writes the cloud file\n // but the phone keeps suggesting the address.\n this.db.setContactsDenylist(Array.isArray(cfg.denylist) ? cfg.denylist : []);\n let imported = 0;\n for (const list of [cfg.preferred, cfg.discovered]) {\n if (!Array.isArray(list)) continue;\n for (const e of list) {\n const email = (e?.email || \"\").trim();\n if (!email) continue;\n this.db.recordSentAddress((e?.name || \"\").trim(), email);\n imported++;\n }\n }\n if (imported > 0) console.log(`[contacts] loaded ${imported} from contacts.jsonc`);\n return { imported };\n } catch (e: any) {\n console.error(`[contacts] loadContactsConfig failed: ${e?.message || e}`);\n return null;\n }\n }\n\n // Calendar \u2014 Android UI has its own native calendar; no JS-side data.\n async getCalendarEvents(_fromMs: number, _toMs: number): Promise<any[]> { return []; }\n async createCalendarEvent(_ev: any): Promise<{ uuid: string }> { return this.notImpl(\"createCalendarEvent\"); }\n async updateCalendarEvent(_uuid: string, _patch: any): Promise<{ ok: true }> { return this.notImpl(\"updateCalendarEvent\"); }\n async deleteCalendarEvent(_uuid: string): Promise<{ ok: true }> { return this.notImpl(\"deleteCalendarEvent\"); }\n\n // Tasks \u2014 same story\n async getTasks(_includeCompleted?: boolean): Promise<any[]> { return []; }\n async createTask(_t: { title: string; notes?: string; dueMs?: number }): Promise<{ uuid: string }> { return this.notImpl(\"createTask\"); }\n async updateTask(_uuid: string, _patch: any): Promise<{ ok: true }> { return this.notImpl(\"updateTask\"); }\n async deleteTask(_uuid: string): Promise<{ ok: true }> { return this.notImpl(\"deleteTask\"); }\n\n // User dictionary (cloud-mirrored) \u2014 Android can implement these via\n // the same userdict.csv cloud round-trip the desktop uses; until that\n // wire-up lands, return safe defaults so spellcheck.ts catch() paths\n // don't fire and clutter logs.\n async getUserDict(): Promise<string[]> { return []; }\n async addUserDictWord(_word: string): Promise<string[]> { return []; }\n async addUserDictWords(_words: string[]): Promise<string[]> { return []; }\n async removeUserDictWord(_word: string): Promise<string[]> { return []; }\n\n // Diagnostics / version / primary account\n getDiagnostics(): any { return { ok: true, platform: \"android\" }; }\n getPrimaryAccount(_feature?: string): any { return null; }\n getVersion(): any { return { version: \"android\", platform: \"android\" }; }\n consumePendingMailto(): any { return null; }\n logClientEvent(..._args: any[]): void { /* no-op \u2014 server-side logging not wired on Android */ }\n\n // Setup / repair / unsubscribe\n async setupAccount(_name: string, _email: string, _password?: string): Promise<{ ok: boolean; error?: string; message?: string }> { return this.notImpl(\"setupAccount\"); }\n async repairAccounts(): Promise<{ ok: boolean; error?: string; message?: string }> { return this.notImpl(\"repairAccounts\"); }\n async unsubscribeOneClick(_url: string): Promise<{ ok: boolean; status: number; statusText: string }> { return this.notImpl(\"unsubscribeOneClick\"); }\n\n // AI transforms \u2014 pipe through to web autocomplete or no-op\n async aiTransform(_req: any): Promise<any> { return this.notImpl(\"aiTransform\"); }\n}\n\n/** Loose JSONC parse \u2014 strips // comments and trailing commas before JSON.parse.\n * Sufficient for contacts.jsonc which is machine-written; doesn't pull in\n * jsonc-parser as a dep on the Android side where bundle size matters. */\nfunction parseJsoncLoose(raw: string): any {\n try {\n const stripped = raw\n .replace(/^\\s*\\/\\/.*$/gm, \"\")\n .replace(/,(\\s*[}\\]])/g, \"$1\");\n return JSON.parse(stripped);\n } catch { return null; }\n}\n", "/**\n * Android bootstrap \u2014 wires WebMailxDB + WebMessageStore + GmailApiWebProvider + WebMailxService\n * into the mailxapi bridge. This replaces Node.js backend for Android WebView.\n *\n * On Android, everything runs in the same JavaScript context:\n * - wa-sqlite for metadata (via WebMailxDB)\n * - IndexedDB for message bodies (via WebMessageStore)\n * - Gmail/Outlook sync via REST APIs (plain fetch \u2014 no native bridge needed)\n * - IMAP accounts use BridgeTransport (via MAUI TCP bridge) \u2014 not yet implemented\n *\n * The existing client UI (app.ts, components/) is completely unchanged \u2014\n * it calls window.mailxapi.* which this module provides.\n */\n\nimport { WebMailxDB } from \"./db.js\";\nimport { WebMessageStore } from \"./web-message-store.js\";\nimport { WebMailxService, type WebSyncManager } from \"./web-service.js\";\nimport {\n loadAccounts, loadAccountsFromCloud, saveAccounts, loadSettings, clearSettings, getDeviceId,\n setGDriveTokenProvider, setGDriveFolderId\n} from \"./web-settings.js\";\nimport { GmailApiWebProvider } from \"./gmail-api-web.js\";\nimport { ImapWebProvider } from \"./imap-web-provider.js\";\nimport { SmtpClient, type SmtpAuth } from \"@bobfrankston/smtp-direct\";\nimport { BridgeTcpTransport } from \"@bobfrankston/tcp-transport\";\nimport type { MailProvider, ProviderMessage } from \"./provider-types.js\";\nimport type { Folder, EmailAddress, AccountConfig } from \"@bobfrankston/mailx-types\";\n\n// \u2500\u2500 State \u2500\u2500\n\nlet db: WebMailxDB;\nlet bodyStore: WebMessageStore;\nlet service: WebMailxService;\nlet syncManager: AndroidSyncManager;\nconst eventHandlers: ((event: any) => void)[] = [];\n\n// \u2500\u2500 Event emitter \u2500\u2500\n\nfunction emitEvent(event: any): void {\n for (const h of eventHandlers) {\n try { h(event); } catch { /* ignore */ }\n }\n if (typeof (window as any)._msgapiServiceEvent === \"function\") {\n (window as any)._msgapiServiceEvent(event);\n }\n}\n\n// \u2500\u2500 Helpers \u2500\u2500\n\nfunction toEmailAddress(addr: { name?: string; address?: string } | undefined): EmailAddress {\n return { name: addr?.name || \"\", address: addr?.address || \"\" };\n}\n\n/** Verbose log \u2014 goes to logit but doesn't clutter the screen (silent=true) */\nfunction vlog(msg: string): void {\n try {\n fetch(`https://rmf39.aaz.lt/logit/${encodeURIComponent(\"V/\" + msg.substring(0, 800))}?log=mailx-android&silent=true`).catch(() => {});\n } catch { /* ignore */ }\n}\n\n// \u2500\u2500 Sync Manager \u2500\u2500\n\nclass AndroidSyncManager implements WebSyncManager {\n private providers = new Map<string, MailProvider>();\n private tokenProviders = new Map<string, () => Promise<string>>();\n // One prefetch session per account \u2014 prevents every syncAll tick from\n // spawning parallel fetch loops that race on IndexedDB and blow through\n // Gmail's per-user quota.\n private prefetchingAccounts = new Set<string>();\n\n constructor(\n private db: WebMailxDB,\n private bodyStore: WebMessageStore,\n ) {}\n\n on(_event: string, _handler: (...args: any[]) => void): void { /* stub */ }\n emit(event: string, ...args: any[]): void { emitEvent({ type: event, ...args[0] }); }\n\n async addAccount(account: AccountConfig): Promise<void> {\n vlog(`addAccount id=${account.id} email=${account.email} host=${account.imap?.host} auth=${account.imap?.auth}`);\n this.db.upsertAccount(account.id, account.name, account.email, JSON.stringify(account));\n // Idempotent: a provider already registered for this account is kept\n // as-is. The Android bootstrap re-runs the account load periodically;\n // recreating the provider each time built a fresh ImapWebProvider +\n // BridgeTransport and replaced the live one \u2014 which orphaned any\n // body fetch in flight on the old provider, so `fetchOne` came back\n // with no source and the message showed \"Body parsed empty\". A real\n // config change is rare and handled by a restart.\n if (this.providers.has(account.id)) {\n vlog(`addAccount ${account.id}: provider already registered \u2014 keeping it`);\n return;\n }\n if (this.isGmailAccount(account)) {\n const tokenProvider = this.tokenProviders.get(account.id);\n if (tokenProvider) {\n this.providers.set(account.id, new GmailApiWebProvider(tokenProvider));\n console.log(`[sync] ${account.id}: Gmail API provider registered`);\n } else {\n console.warn(`[sync] ${account.id}: no token provider`);\n }\n } else if (account.imap?.host && account.imap?.user) {\n // Generic IMAP account \u2014 use BridgeTransport through MAUI's TCP bridge\n try {\n const provider = new ImapWebProvider({\n server: account.imap.host,\n port: account.imap.port || 993,\n username: account.imap.user,\n password: account.imap.password,\n inactivityTimeout: 300000, // 300s for slow Dovecot\n fetchChunkSize: 10,\n fetchChunkSizeMax: 100,\n }, () => new BridgeTcpTransport());\n this.providers.set(account.id, provider);\n vlog(`addAccount ${account.id}: IMAP provider registered (${account.imap.host}:${account.imap.port})`);\n console.log(`[sync] ${account.id}: IMAP provider registered (${account.imap.host})`);\n } catch (e: any) {\n vlog(`addAccount ${account.id}: IMAP provider FAILED: ${e.message}`);\n console.error(`[sync] ${account.id}: IMAP provider failed: ${e.message}`);\n }\n } else {\n vlog(`addAccount ${account.id}: no imap config, skipping`);\n }\n }\n\n setTokenProvider(accountId: string, provider: () => Promise<string>): void {\n this.tokenProviders.set(accountId, provider);\n }\n\n private isGmailAccount(account: AccountConfig): boolean {\n return account.imap?.host?.includes(\"gmail\") || account.email?.endsWith(\"@gmail.com\") || false;\n }\n\n private getProvider(accountId: string): MailProvider | null {\n return this.providers.get(accountId) || null;\n }\n\n async syncAll(): Promise<void> {\n const accounts = this.db.getAccounts();\n vlog(`syncAll: ${accounts.length} accounts in DB: ${accounts.map(a => a.id).join(\",\")}`);\n\n // Phase 1: Sync INBOX for every account first \u2014 user sees new mail fast.\n for (const account of accounts) {\n if (!this.providers.has(account.id)) continue;\n try {\n const folders = await this.syncFolders(account.id);\n const inbox = folders.find(f => f.specialUse === \"inbox\");\n if (inbox) {\n await this.syncFolder(account.id, inbox.id);\n emitEvent({ type: \"syncComplete\", accountId: account.id });\n }\n } catch (e: any) {\n console.error(`[sync] ${account.id} inbox: ${e.message}`);\n }\n }\n\n // Phase 2: Remaining folders (sent, drafts, trash, then everything else).\n for (const account of accounts) {\n if (!this.providers.has(account.id)) continue;\n try {\n const folders = this.db.getFolders(account.id);\n const remaining = folders.filter(f => f.specialUse !== \"inbox\");\n for (const folder of remaining) {\n try { await this.syncFolder(account.id, folder.id); }\n catch (e: any) { console.error(`[sync] Skip ${folder.path}: ${e.message}`); }\n }\n this.db.updateLastSync(account.id, Date.now());\n emitEvent({ type: \"syncComplete\", accountId: account.id });\n } catch (e: any) {\n console.error(`[sync] ${account.id}: ${e.message}`);\n vlog(`syncAll: ${account.id} ERROR: ${e.message}`);\n emitEvent({ type: \"syncError\", accountId: account.id, error: e.message });\n }\n }\n\n // Phase 3: background body prefetch. Fire-and-forget \u2014 sync itself is\n // already done and the UI doesn't wait on this. Per-account guard means\n // a slow account can't block a fast one.\n for (const account of accounts) {\n if (!this.providers.has(account.id)) continue;\n this.prefetchBodies(account.id).catch(e =>\n console.error(`[prefetch] ${account.id}: ${e.message}`));\n }\n }\n\n /** Background body prefetch \u2014 download bodies for messages that don't have\n * them yet, so tapping a message in the list opens instantly from cache. */\n async prefetchBodies(accountId: string): Promise<void> {\n if (this.prefetchingAccounts.has(accountId)) return;\n this.prefetchingAccounts.add(accountId);\n try {\n const BATCH_SIZE = 20;\n const THROTTLE_MS = 150;\n const RATE_LIMIT_PAUSE_MS = 30000;\n const ERROR_BUDGET = 10;\n const CONCURRENCY = 2; // S62: 2 in-flight per account\n let totalFetched = 0;\n let errors = 0;\n let announced = false;\n // Per-session blacklist: messages whose fetch errored once.\n // `getMessagesWithoutBody` returns the same set every batch\n // (no per-row failed-marker in DB yet), so without this set\n // a single failing message would burn the entire ERROR_BUDGET\n // by being retried first in every batch. Skipping locally\n // unblocks subsequent messages; next syncAll cycle starts\n // a new prefetch session and the blacklist resets.\n const failedThisSession = new Set<number>();\n // S62: INBOX always first. Within each folder the DB returns rows\n // most-recent-first (PRIMARY KEY order), so newest unfetched INBOX\n // mail wins the queue. A slow label (`[Gmail]/Jerrry`, etc.) can't\n // starve INBOX any more.\n const folderPriority = (folderId: number): number => {\n const f = this.db.getFolders(accountId).find((x: any) => x.id === folderId);\n return f?.specialUse === \"inbox\" ? 0 : 1;\n };\n let rateLimitCooldownUntil = 0;\n\n while (true) {\n const allMissing = this.db.getMessagesWithoutBody(accountId, BATCH_SIZE * 4);\n const missing = allMissing.filter((m: any) => !failedThisSession.has(m.uid));\n if (missing.length === 0) break;\n // Cap to BATCH_SIZE after filtering so a deep blacklist\n // doesn't leave us with a tiny working set per pass.\n if (missing.length > BATCH_SIZE) missing.length = BATCH_SIZE;\n if (!announced) {\n console.log(`[prefetch] ${accountId}: ${missing.length}+ bodies to fetch`);\n vlog(`prefetch ${accountId} start: ${missing.length}+ pending`);\n announced = true;\n }\n // Sort this batch INBOX-first. getMessagesWithoutBody doesn't\n // know the priority, and re-querying per folder would multiply\n // the SELECTs. One in-memory sort is cheap.\n missing.sort((a: any, b: any) => folderPriority(a.folderId) - folderPriority(b.folderId));\n let progressedThisBatch = false;\n let batchAborted = false;\n\n // Bounded-concurrency worker pool. Each worker pulls the next\n // unclaimed item from `missing`. Shared flags (errors,\n // rateLimitCooldownUntil, progressedThisBatch) are updated\n // inside the loop \u2014 sql.js is single-threaded so there's no\n // actual race on reads/writes.\n let cursor = 0;\n const worker = async (): Promise<void> => {\n while (cursor < missing.length) {\n if (batchAborted) return;\n if (errors >= ERROR_BUDGET) return;\n const idx = cursor++;\n const m = missing[idx];\n // Honor rate-limit cooldown across workers.\n const now = Date.now();\n if (rateLimitCooldownUntil > now) {\n await new Promise(r => setTimeout(r, rateLimitCooldownUntil - now));\n }\n if (await this.bodyStore.hasMessage(accountId, m.folderId, m.uid)) {\n this.db.updateBodyPath(accountId, m.uid, `idb:${accountId}/${m.folderId}/${m.uid}`);\n progressedThisBatch = true;\n continue;\n }\n try {\n const result = await this.fetchMessageBody(accountId, m.folderId, m.uid);\n if (result) {\n totalFetched++;\n progressedThisBatch = true;\n emitEvent({ type: \"bodyCached\", accountId, uid: m.uid, folderId: m.folderId });\n } else {\n errors++;\n failedThisSession.add(m.uid);\n }\n } catch (e: any) {\n errors++;\n failedThisSession.add(m.uid);\n const msg = String(e?.message || \"\");\n if (/429|rate|too many/i.test(msg)) {\n console.log(`[prefetch] ${accountId}: rate-limited \u2014 pausing ${RATE_LIMIT_PAUSE_MS / 1000}s`);\n rateLimitCooldownUntil = Date.now() + RATE_LIMIT_PAUSE_MS;\n } else {\n console.error(`[prefetch] ${accountId}/${m.uid}: ${msg}`);\n }\n }\n // Throttle kept per-request to spread load on flaky\n // phone networks; concurrency-2 means effective request\n // rate is ~1 per THROTTLE_MS/2.\n await new Promise(r => setTimeout(r, THROTTLE_MS));\n }\n };\n await Promise.all(Array.from({ length: Math.min(CONCURRENCY, missing.length) }, () => worker()));\n if (errors >= ERROR_BUDGET) {\n console.error(`[prefetch] ${accountId}: stopping after ${errors} errors (${totalFetched} cached)`);\n vlog(`prefetch ${accountId} aborted: ${errors} errors, ${totalFetched} cached`);\n return;\n }\n if (!progressedThisBatch) {\n console.warn(`[prefetch] ${accountId}: batch made no progress, stopping`);\n break;\n }\n }\n if (totalFetched > 0) {\n console.log(`[prefetch] ${accountId}: done \u2014 cached ${totalFetched} bodies`);\n vlog(`prefetch ${accountId} done: ${totalFetched} cached`);\n }\n } finally {\n this.prefetchingAccounts.delete(accountId);\n }\n }\n\n async syncFolders(accountId: string): Promise<Folder[]> {\n const provider = this.getProvider(accountId);\n if (!provider) {\n const existing = this.db.getFolders(accountId);\n vlog(`syncFolders: ${accountId} no provider, returning ${existing.length} cached folders`);\n return existing;\n }\n emitEvent({ type: \"syncProgress\", accountId, phase: \"folders\", progress: 0 });\n console.log(`[sync] ${accountId}: listing folders from provider`);\n let providerFolders: any[] = [];\n try {\n providerFolders = await provider.listFolders();\n } catch (e: any) {\n console.error(`[sync] ${accountId}: listFolders threw: ${e?.message || e}`);\n throw e;\n }\n console.log(`[sync] ${accountId}: provider returned ${providerFolders.length} folders` +\n (providerFolders.length > 0 ? ` (sample: ${providerFolders.slice(0, 3).map((f: any) => f.path || f.name).join(\", \")})` : \"\"));\n for (const folder of providerFolders) {\n const flags = folder.flags || [];\n if (flags.some((f: string) => f.toLowerCase() === \"\\\\noselect\")) continue;\n this.db.upsertFolder(accountId, folder.path, folder.name, folder.specialUse, folder.delimiter);\n }\n emitEvent({ type: \"syncProgress\", accountId, phase: \"folders\", progress: 100 });\n const dbFolders = this.db.getFolders(accountId);\n console.log(`[sync] ${accountId}: ${dbFolders.length} folders in db, inbox=${dbFolders.some((f: any) => f.specialUse === \"inbox\") ? \"yes\" : \"no\"}`);\n emitEvent({ type: \"folderCountsChanged\", accountId, counts: {} });\n return dbFolders;\n }\n\n async syncFolder(accountId: string, folderId: number): Promise<void> {\n const provider = this.getProvider(accountId);\n if (!provider) return;\n const folders = this.db.getFolders(accountId);\n const folder = folders.find(f => f.id === folderId);\n if (!folder) return;\n\n emitEvent({ type: \"syncProgress\", accountId, phase: `sync:${folder.path}`, progress: 0 });\n const highestUid = this.db.getHighestUid(accountId, folderId);\n const startDate = new Date(Date.now() - 30 * 86400000);\n\n let messages: ProviderMessage[];\n if (highestUid > 0) {\n messages = await provider.fetchSince(folder.path, highestUid, { source: false });\n messages = messages.filter(m => m.uid > highestUid);\n } else {\n const tomorrow = new Date(Date.now() + 86400000);\n messages = await provider.fetchByDate(folder.path, startDate, tomorrow, { source: false });\n }\n\n if (messages.length > 0) {\n console.log(`[sync] ${folder.path}: ${messages.length} messages`);\n this.storeProviderMessages(accountId, folderId, messages);\n this.db.recalcFolderCounts(folderId);\n emitEvent({ type: \"folderCountsChanged\", accountId, counts: {} });\n }\n\n // Reconcile deletions \u2014 messages present locally but no longer on the\n // server (moved away, deleted on another client). Without this, the\n // Android client never drops removed rows: e.g., moves to _spam from\n // another client showed up in _spam (next time it synced) but never\n // disappeared from INBOX.\n //\n // Same safety guards as the desktop reconcile path:\n // - Skip if the server list is empty but local has messages (likely\n // a transient API failure that returned []).\n // - Refuse to delete more than 50% of local in one pass \u2014 better to\n // keep phantoms than to wipe a folder on a sync bug. Rebuild local\n // cache fixes a stuck state.\n try {\n const serverUidsArr = await provider.getUids(folder.path);\n const serverUids = new Set(serverUidsArr);\n const localUids = this.db.getUidsForFolder(accountId, folderId);\n if (serverUidsArr.length === 0 && localUids.length > 0) {\n console.log(`[sync] ${folder.path}: reconcile skipped \u2014 server returned empty but local has ${localUids.length}`);\n } else {\n const toDelete = localUids.filter(uid => !serverUids.has(uid));\n const RECONCILE_DELETE_THRESHOLD = 0.5;\n if (localUids.length > 0 && toDelete.length / localUids.length > RECONCILE_DELETE_THRESHOLD) {\n console.log(`[sync] ${folder.path}: reconcile refused \u2014 would delete ${toDelete.length}/${localUids.length} (${Math.round(toDelete.length / localUids.length * 100)}%)`);\n } else {\n for (const uid of toDelete) {\n this.db.deleteMessage(accountId, uid);\n this.bodyStore.deleteMessage(accountId, folderId, uid).catch(() => {});\n }\n if (toDelete.length > 0) {\n console.log(`[sync] ${folder.path}: reconciled ${toDelete.length} deletions`);\n this.db.recalcFolderCounts(folderId);\n emitEvent({ type: \"folderCountsChanged\", accountId, counts: {} });\n }\n }\n }\n } catch (e: any) {\n console.error(`[sync] ${folder.path}: reconcile error: ${e.message}`);\n }\n\n emitEvent({ type: \"folderSynced\", accountId, entries: [{ folderId, syncedAt: Date.now() }] });\n emitEvent({ type: \"syncProgress\", accountId, phase: `sync:${folder.path}`, progress: 100 });\n }\n\n private storeProviderMessages(accountId: string, folderId: number, messages: ProviderMessage[]): void {\n this.db.beginTransaction();\n try {\n for (const msg of messages) {\n const flags: string[] = [];\n if (msg.seen) flags.push(\"\\\\Seen\");\n if (msg.flagged) flags.push(\"\\\\Flagged\");\n if (msg.answered) flags.push(\"\\\\Answered\");\n if (msg.draft) flags.push(\"\\\\Draft\");\n // Store the Gmail providerId in bodyPath as \"gmail:<id>\" so we can\n // fetch the body directly without re-listing 1000 messages from the folder\n const bodyPath = msg.providerId ? `gmail:${msg.providerId}` : \"\";\n this.db.upsertMessage({\n accountId, folderId, uid: msg.uid,\n messageId: msg.messageId || \"\", inReplyTo: \"\", references: [],\n date: msg.date ? msg.date.getTime() : Date.now(),\n subject: msg.subject || \"\",\n from: toEmailAddress(msg.from?.[0]),\n to: msg.to.map(a => toEmailAddress(a)),\n cc: msg.cc.map(a => toEmailAddress(a)),\n flags, size: msg.size || 0, hasAttachments: false, preview: \"\", bodyPath,\n });\n }\n this.db.commitTransaction();\n } catch (e: any) {\n this.db.rollbackTransaction();\n console.error(`[sync] storeMessages error: ${e.message}`);\n }\n }\n\n async fetchMessageBody(accountId: string, folderId: number, uid: number): Promise<Uint8Array | null> {\n const t0 = Date.now();\n if (await this.bodyStore.hasMessage(accountId, folderId, uid)) {\n // Cache hit is the common case on every body open \u2014 not worth a\n // log line each time. Only an actual fetch (below) is logged.\n return await this.bodyStore.getMessage(accountId, folderId, uid);\n }\n const provider = this.getProvider(accountId);\n if (!provider) {\n console.warn(`[fetchBody] No provider for ${accountId}`);\n return null;\n }\n // Look up the Gmail providerId stored in body_path during sync\n const envelope = this.db.getMessageByUid(accountId, uid, folderId);\n const bp = (envelope as any)?.bodyPath || \"\";\n // 60 s wall-clock cap \u2014 infinite hang was the user-reported symptom\n // (\"fetch message body on android is infinite\"). A dead BridgeTransport\n // socket won't recover by waiting. Legit fetches finish in seconds.\n const FETCH_TIMEOUT_MS = 60_000;\n let __folderPath = \"(n/a)\";\n const fetchPromise = (async (): Promise<any> => {\n if (bp.startsWith(\"gmail:\") && (provider as any).fetchById) {\n const providerId = bp.substring(6);\n __folderPath = `gmail:${bp.substring(6)}`;\n return (provider as any).fetchById(providerId, { source: true });\n }\n const folders = this.db.getFolders(accountId);\n const folder = folders.find(f => f.id === folderId);\n if (!folder) { __folderPath = \"(folder row missing)\"; return null; }\n __folderPath = folder.path || \"(empty path)\";\n return provider.fetchOne(folder.path, uid, { source: true });\n })();\n let msg: any = null;\n try {\n msg = await Promise.race([\n fetchPromise,\n new Promise((_, reject) => setTimeout(\n () => reject(new Error(`body-fetch timeout ${FETCH_TIMEOUT_MS / 1000}s (${accountId}/${folderId}/${uid})`)),\n FETCH_TIMEOUT_MS\n )),\n ]);\n } catch (e: any) {\n console.error(`[fetchBody] failed ${accountId}/${folderId}/${uid} after ${Date.now() - t0}ms: ${e?.message || e}`);\n throw e;\n }\n if (!msg?.source) {\n // Detail so the next log pins WHY: folder path used, and whether\n // the provider returned null vs a message with an empty body.\n const why = msg == null ? \"fetchOne returned null\" : \"message had no .source\";\n console.warn(`[fetchBody] No source returned for ${accountId}/${folderId}/${uid} (bp=${bp}, path=${__folderPath}, ${why}, ${Date.now() - t0}ms)`);\n return null;\n }\n // Encode the UTF-8 string back to bytes for storage\n const raw = new TextEncoder().encode(msg.source);\n await this.bodyStore.putMessage(accountId, folderId, uid, raw);\n this.db.updateBodyPath(accountId, uid, `idb:${accountId}/${folderId}/${uid}`);\n console.log(`[fetchBody] fetched + cached ${accountId}/${folderId}/${uid} (${raw.byteLength} bytes, ${Date.now() - t0}ms)`);\n return raw;\n }\n\n async updateFlagsLocal(accountId: string, uid: number, folderId: number, flags: string[]): Promise<void> {\n this.db.updateMessageFlags(accountId, uid, flags);\n this.db.recalcFolderCounts(folderId);\n this.db.queueSyncAction(accountId, \"flags\", uid, folderId, { flags });\n emitEvent({ type: \"folderCountsChanged\", accountId, counts: {} });\n }\n\n async trashMessage(accountId: string, folderId: number, uid: number): Promise<void> {\n this.db.deleteMessage(accountId, uid);\n this.db.queueSyncAction(accountId, \"trash\", uid, folderId);\n emitEvent({ type: \"messageDeleted\", accountId, folderId, uid });\n emitEvent({ type: \"folderCountsChanged\", accountId, counts: {} });\n }\n\n async trashMessages(accountId: string, messages: { uid: number; folderId: number }[]): Promise<void> {\n for (const m of messages) await this.trashMessage(accountId, m.folderId, m.uid);\n }\n\n async moveMessage(accountId: string, uid: number, folderId: number, targetFolderId: number): Promise<void> {\n this.db.queueSyncAction(accountId, \"move\", uid, folderId, { targetFolderId });\n emitEvent({ type: \"messageMoved\", accountId, fromFolderId: folderId, toFolderId: targetFolderId, uid });\n }\n\n async moveMessages(accountId: string, messages: { uid: number; folderId: number }[], targetFolderId: number): Promise<void> {\n for (const m of messages) await this.moveMessage(accountId, m.uid, m.folderId, targetFolderId);\n }\n\n async moveMessageCrossAccount(): Promise<void> {\n throw new Error(\"Cross-account move not supported on mobile\");\n }\n\n async undeleteMessage(accountId: string, uid: number, folderId: number): Promise<void> {\n this.db.queueSyncAction(accountId, \"undelete\", uid, folderId);\n }\n\n /** Q112: drain queued move/flag/trash actions to the provider. Android is\n * standalone \u2014 it pushes state changes directly to Gmail (or other\n * provider) the same way desktop does. Called from the periodic 2-min\n * tick above. `send` actions drain separately via `processSendQueue`. */\n async processSyncActions(accountId: string): Promise<void> {\n const provider: any = this.providers.get(accountId);\n if (!provider) return;\n const pending = this.db.getPendingSyncActions(accountId)\n .filter((a: any) => a.action !== \"send\");\n if (pending.length === 0) return;\n const folders = this.db.getFolders(accountId);\n const folderPath = (id: number): string | null => {\n const f = folders.find((x: any) => x.id === id);\n return f?.path || null;\n };\n for (const p of pending) {\n const path = folderPath(p.folderId);\n if (!path) { this.db.failSyncActionByUid(accountId, p.action, p.uid, `unknown folder ${p.folderId}`); continue; }\n try {\n if (p.action === \"flags\" && typeof provider.setFlags === \"function\") {\n await provider.setFlags(path, p.uid, Array.isArray(p.flags) ? p.flags : (p.flags ? [p.flags] : []));\n } else if (p.action === \"trash\" && typeof provider.trashMessage === \"function\") {\n // Pass the stored Gmail id so the provider trashes by id\n // instead of its capped list-and-hash search \u2014 that search\n // misses messages past the most-recent ~1000 in a large\n // mailbox, fails, and the deletion un-happens.\n await provider.trashMessage(path, p.uid, this.db.getProviderId(accountId, p.uid));\n } else if (p.action === \"move\" && typeof provider.moveMessage === \"function\") {\n const toId = p.targetFolderId as number;\n const toPath = folderPath(toId);\n if (!toPath) { this.db.failSyncActionByUid(accountId, p.action, p.uid, `unknown target folder ${toId}`); continue; }\n await provider.moveMessage(path, p.uid, toPath, this.db.getProviderId(accountId, p.uid));\n } else {\n this.db.failSyncActionByUid(accountId, p.action, p.uid, `provider does not support ${p.action}`);\n continue;\n }\n this.db.completeSyncActionByUid(accountId, p.action, p.uid);\n } catch (e: any) {\n const msg = e?.message || String(e);\n console.error(`[sync-action] ${accountId} ${p.action} uid=${p.uid}: ${msg}`);\n this.db.failSyncActionByUid(accountId, p.action, p.uid, msg);\n }\n }\n }\n\n /** In-flight send tracker keyed by queueUid. Prevents\n * processSendQueue from re-firing the same row when it overlaps\n * with an in-progress attempt (e.g., the periodic tick fires while\n * the original attemptSend's promise is still pending). Without\n * this, a slow Gmail/SMTP send race-conditions into a double-send. */\n private sendInFlight = new Set<number>();\n\n async queueOutgoingLocal(accountId: string, rawMessage: string): Promise<void> {\n // Local-first: PERSIST to sync_actions before attempting the network\n // send, so a crash / offline / process kill between now and SMTP ACK\n // doesn't drop the message. Desktop parity \u2014 PC writes `.ltr` to disk\n // synchronously; Android writes a sync_actions row and now FLUSHES\n // sql.js \u2192 IndexedDB before returning. The previous version relied on\n // the 1-second scheduleSave debounce, so a tab-close inside the debounce\n // window erased the row before it was persisted \u2014 the \"letter just\n // disappeared\" symptom user-reported 2026-04-30.\n //\n // Equivalent of PC's `~/.mailx/outbox/<acct>/*.ltr` durable write.\n const queueUid = -Date.now();\n this.db.queueSyncAction(accountId, \"send\", queueUid, -1, { rawMessage });\n await this.db.flush();\n this.attemptSend(accountId, queueUid, rawMessage);\n }\n\n /** Kick off a send for a message that's already in the queue. Called by\n * queueOutgoingLocal on a fresh submit AND by processSendQueue on\n * startup / periodic tick for anything stranded from a prior run.\n * Guards against double-send via sendInFlight. */\n private attemptSend(accountId: string, queueUid: number, rawMessage: string): void {\n if (this.sendInFlight.has(queueUid)) return;\n this.sendInFlight.add(queueUid);\n // Helper to mark complete + flush + clear in-flight \u2014 used on every\n // success/failure exit. Flush ensures the row deletion or attempt\n // counter actually reaches IndexedDB before the next process-kill,\n // matching the \"persist before network\" rule for the post-network\n // outcome too. Without flushing on completion, a successful send\n // followed by a fast app-close left the row in the queue, which\n // looked like a \"stuck\" message on next launch.\n const finishSend = (success: boolean, error?: string) => {\n if (success) {\n this.db.completeSyncActionByUid(accountId, \"send\", queueUid);\n } else {\n this.db.failSyncActionByUid(accountId, \"send\", queueUid, error || \"send failed\");\n }\n this.db.flush().catch(() => { /* save will retry on next mutation */ });\n this.sendInFlight.delete(queueUid);\n };\n\n const provider = this.getProvider(accountId);\n if (provider && typeof (provider as any).sendRaw === \"function\") {\n (provider as any).sendRaw(rawMessage)\n .then((result: { id: string; threadId: string }) => {\n console.log(`[send] ${accountId}: sent via Gmail API (id=${result.id})`);\n finishSend(true);\n emitEvent({ type: \"sendComplete\", accountId, messageId: result.id });\n })\n .catch((e: any) => {\n console.error(`[send] ${accountId}: Gmail send failed: ${e.message}`);\n finishSend(false, e.message || String(e));\n emitEvent({ type: \"sendError\", accountId, error: e.message });\n });\n return;\n }\n\n // Non-Gmail: use smtp-direct + BridgeTransport. Pull SMTP config from the\n // stored account JSON.\n const accounts = db.getAccountConfigs();\n const row = accounts.find(a => a.id === accountId);\n if (!row) {\n const e = \"Unknown account\";\n console.error(`[send] ${accountId}: ${e}`);\n finishSend(false, e);\n emitEvent({ type: \"sendError\", accountId, error: e });\n return;\n }\n let account: AccountConfig;\n try { account = JSON.parse(row.configJson); }\n catch {\n const e = \"Account config malformed\";\n finishSend(false, e);\n emitEvent({ type: \"sendError\", accountId, error: e });\n return;\n }\n if (!account.smtp) {\n const e = \"No SMTP config for this account\";\n console.error(`[send] ${accountId}: ${e}`);\n finishSend(false, e);\n emitEvent({ type: \"sendError\", accountId, error: e });\n return;\n }\n\n this.sendViaSmtpDirect(accountId, account, rawMessage)\n .then((result) => {\n console.log(`[send] ${accountId}: sent via SMTP (${result.accepted.length} accepted, ${result.rejected.length} rejected)`);\n finishSend(true);\n emitEvent({ type: \"sendComplete\", accountId });\n })\n .catch((e: any) => {\n console.error(`[send] ${accountId}: SMTP send failed: ${e.message}`);\n finishSend(false, e.message || String(e));\n emitEvent({ type: \"sendError\", accountId, error: e.message });\n });\n }\n\n /** Drain any stranded 'send' queue entries \u2014 called at startup and on\n * each periodic sync tick so messages queued while offline or stranded\n * by a crash get a retry. Each row keeps its queueUid as tracking key. */\n async processSendQueue(accountId: string): Promise<void> {\n const pending = this.db.getPendingSyncActions(accountId).filter(a => a.action === \"send\" && a.rawMessage);\n if (pending.length === 0) return;\n console.log(`[send] ${accountId}: draining ${pending.length} queued message(s)`);\n for (const p of pending) {\n this.attemptSend(accountId, p.uid, p.rawMessage);\n }\n }\n\n /** Build SMTP config from account, send via smtp-direct over BridgeTransport. */\n private async sendViaSmtpDirect(\n accountId: string, account: AccountConfig, raw: string,\n ): Promise<{ accepted: string[]; rejected: { address: string; code: number; message: string }[] }> {\n const SMTP_PORT_STARTTLS = 587;\n const SMTP_PORT_IMPLICIT_TLS = 465;\n const smtp = account.smtp!;\n const smtpPort = smtp.port || SMTP_PORT_STARTTLS;\n const smtpHost = smtp.host || account.imap?.host;\n if (!smtpHost) throw new Error(\"No SMTP host\");\n\n // Auth: password \u2192 PLAIN; oauth2 \u2192 XOAUTH2 (token from this account's provider)\n const smtpUser = smtp.user || account.imap?.user || account.email;\n const authType = smtp.auth || (account.imap?.password ? \"password\" : undefined);\n let auth: SmtpAuth | undefined;\n if (authType === \"password\") {\n const pass = smtp.password || account.imap?.password;\n if (!pass) throw new Error(\"SMTP password not configured\");\n auth = { method: \"PLAIN\", user: smtpUser, pass };\n } else if (authType === \"oauth2\") {\n const tp = this.tokenProviders.get(accountId);\n if (!tp) throw new Error(\"OAuth token provider not registered\");\n const token = await tp();\n auth = { method: \"XOAUTH2\", user: smtpUser, token };\n }\n\n // Recipients from headers\n const parseAddrs = (s: string) => s.match(/[\\w.+-]+@[\\w.-]+/g) || [];\n const toMatch = raw.match(/^To:\\s*(.+)$/mi);\n const ccMatch = raw.match(/^Cc:\\s*(.+)$/mi);\n const bccMatch = raw.match(/^Bcc:\\s*(.+)$/mi);\n const fromMatch = raw.match(/^From:\\s*(.+)$/mi);\n const recipients = [\n ...(toMatch ? parseAddrs(toMatch[1]) : []),\n ...(ccMatch ? parseAddrs(ccMatch[1]) : []),\n ...(bccMatch ? parseAddrs(bccMatch[1]) : []),\n ];\n const sender = fromMatch ? (parseAddrs(fromMatch[1])[0] || account.email) : account.email;\n if (recipients.length === 0) throw new Error(\"No recipients\");\n\n const rawToSend = raw.replace(/^Bcc:.*\\r?\\n/mi, \"\");\n\n const client = new SmtpClient({\n host: smtpHost,\n port: smtpPort,\n secure: smtpPort === SMTP_PORT_IMPLICIT_TLS,\n auth,\n localname: \"mailx-android\",\n }, () => new BridgeTcpTransport());\n try {\n await client.connect();\n return await client.sendMail({ from: sender, to: recipients }, rawToSend);\n } finally {\n try { await client.quit(); } catch { /* ignore */ }\n }\n }\n\n async saveDraft(_accountId: string, _raw: string, _prevUid?: number, _draftId?: string): Promise<number | null> {\n return null;\n }\n\n async deleteDraft(_accountId: string, _draftUid: number): Promise<void> { }\n\n async reauthenticate(_accountId: string): Promise<boolean> { return false; }\n\n async searchOnServer(): Promise<number[]> { return []; }\n\n async syncAllContacts(): Promise<void> { }\n}\n\n// \u2500\u2500 OAuth credentials (same \"installed\" client as desktop) \u2500\u2500\n\n// Same credentials as desktop mailx (iflow-credentials.json from @bobfrankston/iflow-direct)\nconst OAUTH_CLIENT = {\n clientId: \"884213380682-hcso64dcqmk4p98vsc7br2e6gvn7iv2u.apps.googleusercontent.com\",\n clientSecret: \"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\",\n authUri: \"https://accounts.google.com/o/oauth2/auth\",\n tokenUri: \"https://oauth2.googleapis.com/token\",\n // Reverse client ID scheme \u2014 auto-allowed for Google \"installed\" apps\n redirectUri: \"com.googleusercontent.apps.884213380682-hcso64dcqmk4p98vsc7br2e6gvn7iv2u:/oauth2callback\",\n};\n\n// Use full drive scope so we can read/write the desktop's accounts.jsonc + clients.jsonc.\n// drive.file is per-consent-grant: files created by desktop's grant aren't visible to Android's grant\n// even with the same client_id. drive (full) lets us see all files the user has access to.\n// `tasks` added 2026-05-05 to match desktop. Without it, the Tasks pane's\n// HTTP calls 403 even though the same OAuth grant works for Calendar.\nconst OAUTH_SCOPES = \"https://mail.google.com/ https://www.googleapis.com/auth/contacts.readonly https://www.googleapis.com/auth/drive https://www.googleapis.com/auth/calendar https://www.googleapis.com/auth/tasks\";\n\n// \u2500\u2500 Token cache (IndexedDB) \u2500\u2500\n\nasync function getCachedToken(email: string): Promise<{ access_token: string; refresh_token?: string; expires_at?: number } | null> {\n const key = `oauth-token-${email.replace(/[@.]/g, \"_\")}`;\n const raw = localStorage.getItem(key);\n if (!raw) {\n console.log(`[oauth] no cached token for ${email} (localStorage key=${key} missing \u2014 fresh consent will follow)`);\n return null;\n }\n try {\n const parsed = JSON.parse(raw);\n const hasRefresh = !!parsed?.refresh_token;\n const expiresAt = parsed?.expires_at || 0;\n const expiresIn = expiresAt ? Math.round((expiresAt - Date.now()) / 1000) : 0;\n console.log(`[oauth] cached token for ${email}: hasRefresh=${hasRefresh}, expiresIn=${expiresIn}s`);\n return parsed;\n } catch { return null; }\n}\n\nasync function setCachedToken(email: string, token: { access_token: string; refresh_token?: string; expires_at?: number }): Promise<void> {\n const key = `oauth-token-${email.replace(/[@.]/g, \"_\")}`;\n localStorage.setItem(key, JSON.stringify(token));\n}\n\nasync function clearCachedToken(email: string): Promise<void> {\n const key = `oauth-token-${email.replace(/[@.]/g, \"_\")}`;\n localStorage.removeItem(key);\n}\n\n// \u2500\u2500 Token exchange \u2500\u2500\n\nasync function exchangeCodeForTokens(code: string): Promise<{ access_token: string; refresh_token?: string; expires_in: number }> {\n const body = new URLSearchParams({\n code,\n client_id: OAUTH_CLIENT.clientId,\n client_secret: OAUTH_CLIENT.clientSecret,\n redirect_uri: OAUTH_CLIENT.redirectUri,\n grant_type: \"authorization_code\",\n });\n const res = await fetch(OAUTH_CLIENT.tokenUri, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/x-www-form-urlencoded\" },\n body: body.toString(),\n });\n if (!res.ok) {\n const text = await res.text();\n throw new Error(`Token exchange failed: ${res.status} ${text}`);\n }\n return res.json();\n}\n\nasync function refreshAccessToken(refreshToken: string): Promise<{ access_token: string; expires_in: number }> {\n const body = new URLSearchParams({\n refresh_token: refreshToken,\n client_id: OAUTH_CLIENT.clientId,\n client_secret: OAUTH_CLIENT.clientSecret,\n grant_type: \"refresh_token\",\n });\n const res = await fetch(OAUTH_CLIENT.tokenUri, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/x-www-form-urlencoded\" },\n body: body.toString(),\n });\n if (!res.ok) {\n const text = await res.text();\n throw new Error(`Token refresh failed: ${res.status} ${text}`);\n }\n return res.json();\n}\n\n// \u2500\u2500 Token provider (browser OAuth, same as desktop) \u2500\u2500\n\nfunction createNativeTokenProvider(email: string): () => Promise<string> {\n return async () => {\n // Check cached token first\n const cached = await getCachedToken(email);\n if (cached?.access_token) {\n const expiresAt = cached.expires_at || 0;\n const bufferMs = 5 * 60 * 1000; // 5 min buffer\n if (Date.now() < expiresAt - bufferMs) {\n return cached.access_token;\n }\n // Try refresh\n if (cached.refresh_token) {\n try {\n console.log(`[oauth] Refreshing token for ${email}`);\n const refreshed = await refreshAccessToken(cached.refresh_token);\n const token = {\n access_token: refreshed.access_token,\n refresh_token: cached.refresh_token,\n expires_at: Date.now() + refreshed.expires_in * 1000,\n };\n await setCachedToken(email, token);\n return token.access_token;\n } catch (e: any) {\n console.warn(`[oauth] Refresh failed: ${e.message}, starting new flow`);\n }\n }\n }\n\n // No valid token \u2014 start browser OAuth flow\n const bridge = (window as any)._nativeBridge;\n if (!bridge?.app?.startOAuth) {\n throw new Error(\"No native OAuth bridge\");\n }\n\n const authUrl = `${OAUTH_CLIENT.authUri}?` + new URLSearchParams({\n client_id: OAUTH_CLIENT.clientId,\n redirect_uri: OAUTH_CLIENT.redirectUri,\n response_type: \"code\",\n scope: OAUTH_SCOPES,\n access_type: \"offline\",\n prompt: \"consent\",\n login_hint: email,\n }).toString();\n\n console.log(`[oauth] Starting browser consent for ${email}`);\n const code = await bridge.app.startOAuth(authUrl);\n const tokens = await exchangeCodeForTokens(code);\n const token = {\n access_token: tokens.access_token,\n refresh_token: tokens.refresh_token,\n expires_at: Date.now() + tokens.expires_in * 1000,\n };\n await setCachedToken(email, token);\n console.log(`[oauth] Token obtained for ${email}`);\n return token.access_token;\n };\n}\n\n// \u2500\u2500 GDrive folder lookup \u2500\u2500\n\nasync function registerDeviceInGDrive(\n tokenProvider: () => Promise<string>,\n folderId: string,\n accountIds: string[]\n): Promise<void> {\n try {\n const token = await tokenProvider();\n // Use persistent Android device ID (survives factory reset & app data clear)\n const bridge = (window as any)._nativeBridge;\n let deviceId = \"android-unknown\";\n if (bridge?.app?.getAndroidId) {\n try {\n const androidId = await bridge.app.getAndroidId();\n deviceId = `android-${androidId.substring(0, 12)}`;\n } catch {\n deviceId = `android-${getDeviceId().substring(0, 8)}`;\n }\n }\n // Read existing clients.jsonc\n const q = encodeURIComponent(`name='clients.jsonc' and '${folderId}' in parents and trashed=false`);\n const listRes = await fetch(\n `https://www.googleapis.com/drive/v3/files?q=${q}&fields=files(id)`,\n { headers: { \"Authorization\": `Bearer ${token}` } }\n );\n if (!listRes.ok) {\n console.warn(`[gdrive] clients.jsonc list failed: ${listRes.status}`);\n return;\n }\n const listData = await listRes.json() as any;\n const fileId = listData.files?.[0]?.id;\n let clients: any = {};\n if (fileId) {\n const readRes = await fetch(\n `https://www.googleapis.com/drive/v3/files/${fileId}?alt=media`,\n { headers: { \"Authorization\": `Bearer ${token}` } }\n );\n if (readRes.ok) {\n try { clients = JSON.parse(await readRes.text()); } catch { /* */ }\n }\n }\n // Remove stale android-* entries (from old random-UUID approach) \u2014 keep only this device\n for (const key of Object.keys(clients)) {\n if (key.startsWith(\"android-\") && key !== deviceId) {\n delete clients[key];\n }\n }\n clients[deviceId] = {\n hostname: deviceId,\n platform: \"android\",\n accounts: accountIds,\n lastSeen: new Date().toISOString(),\n version: (window as any)._nativeBridge?.info?.version || \"?\",\n };\n const content = JSON.stringify(clients, null, 2);\n if (fileId) {\n const upRes = await fetch(\n `https://www.googleapis.com/upload/drive/v3/files/${fileId}?uploadType=media`,\n {\n method: \"PATCH\",\n headers: {\n \"Authorization\": `Bearer ${token}`,\n \"Content-Type\": \"application/json\",\n },\n body: content,\n }\n );\n if (upRes.ok) console.log(`[android] Registered device in clients.jsonc as ${deviceId}`);\n else console.warn(`[gdrive] clients.jsonc update failed: ${upRes.status}`);\n }\n } catch (e: any) {\n console.warn(`[android] Device registration failed: ${e.message}`);\n }\n}\n\n// \u2500\u2500 Google Contacts sync (People API, incremental) \u2500\u2500\n//\n// Mirrors mailx-imap's syncGoogleContactsImpl. Persists nextSyncToken in\n// localStorage per account so subsequent calls only fetch deltas. Web DB\n// has no kv table, so we use localStorage (one row per device \u2014 that's\n// what we want; sync tokens are per-account per-device).\n//\n// In-flight guard prevents the periodic timer from stacking calls when a\n// sync is still running.\n\nconst contactsSyncing = new Map<string, Promise<number>>();\n\nfunction getContactsSyncToken(accountId: string): string {\n try { return localStorage.getItem(`mailx-contacts-synctoken-${accountId}`) || \"\"; }\n catch { return \"\"; }\n}\n\nfunction setContactsSyncToken(accountId: string, token: string | null): void {\n try {\n const key = `mailx-contacts-synctoken-${accountId}`;\n if (token === null) localStorage.removeItem(key);\n else localStorage.setItem(key, token);\n } catch { /* private mode */ }\n}\n\n/** True when the account is Google-backed (Gmail address or Gmail IMAP host).\n * Only Google accounts have a People API + OAuth token; running the contacts\n * sync for a plain IMAP account is meaningless and triggers a bogus OAuth\n * consent prompt for an address Google doesn't own. */\nfunction isGoogleAccount(account: { email?: string; imap?: { host?: string } }): boolean {\n return !!(account.imap?.host?.toLowerCase().includes(\"gmail\")\n || account.email?.toLowerCase().endsWith(\"@gmail.com\"));\n}\n\nasync function syncGoogleContactsForAccount(\n db: WebMailxDB,\n accountId: string,\n tokenProvider: () => Promise<string>,\n): Promise<number> {\n const inFlight = contactsSyncing.get(accountId);\n if (inFlight) return inFlight;\n const promise = (async (): Promise<number> => {\n const token = await tokenProvider();\n if (!token) return 0;\n\n let changed = 0;\n let nextPageToken: string | undefined;\n let syncToken = getContactsSyncToken(accountId);\n\n try {\n do {\n const params = new URLSearchParams({\n personFields: \"names,emailAddresses,organizations,photos\",\n pageSize: \"100\",\n });\n if (nextPageToken) params.set(\"pageToken\", nextPageToken);\n if (syncToken) params.set(\"syncToken\", syncToken);\n else params.set(\"requestSyncToken\", \"true\");\n\n const url = `https://people.googleapis.com/v1/people/me/connections?${params}`;\n const res = await fetch(url, { headers: { Authorization: `Bearer ${token}` } });\n\n if (!res.ok) {\n const err = await res.text().catch(() => \"\");\n // Expired sync token: People API returns HTTP 400\n // FAILED_PRECONDITION / EXPIRED_SYNC_TOKEN (older behavior\n // was 410 \u2014 match both via the body). Drop the token and\n // restart as a full sync.\n if (syncToken && (res.status === 410 || /EXPIRED_SYNC_TOKEN|sync token is expired/i.test(err))) {\n console.log(`[contacts] ${accountId}: sync token expired \u2014 clearing for full resync`);\n setContactsSyncToken(accountId, null);\n syncToken = \"\";\n nextPageToken = undefined;\n changed = 0;\n continue;\n }\n console.error(`[contacts] API error for ${accountId}: ${res.status} ${err}`);\n return changed;\n }\n\n const data = await res.json() as any;\n if (data.connections) {\n for (const person of data.connections) {\n const googleId = person.resourceName || \"\";\n if (person.metadata?.deleted) {\n const removed = db.deleteContactByGoogleId(googleId);\n if (removed > 0) changed += removed;\n continue;\n }\n const name = person.names?.[0]?.displayName || \"\";\n const org = person.organizations?.[0]?.name || \"\";\n for (const e of person.emailAddresses || []) {\n const email = e.value?.toLowerCase();\n if (!email) continue;\n const existing = db.searchContacts(email, 1);\n const wasNew = !(existing.length > 0 && existing[0].email === email);\n db.recordSentAddress(name, email);\n db.setContactGoogleId(email, googleId, org);\n if (wasNew) changed++;\n }\n }\n }\n nextPageToken = data.nextPageToken;\n if (data.nextSyncToken) {\n setContactsSyncToken(accountId, data.nextSyncToken);\n syncToken = data.nextSyncToken;\n }\n } while (nextPageToken);\n\n console.log(`[contacts] ${accountId}: ${changed} change(s) (${syncToken ? \"incremental\" : \"full\"})`);\n } catch (e: any) {\n console.error(`[contacts] Sync error for ${accountId}: ${e.message}`);\n }\n return changed;\n })().finally(() => contactsSyncing.delete(accountId));\n contactsSyncing.set(accountId, promise);\n return promise;\n}\n\nasync function findGDriveMailxFolder(tokenProvider: () => Promise<string>): Promise<{ id: string; name: string; path: string; ownerEmail?: string } | null> {\n const token = await tokenProvider();\n const headers = { \"Authorization\": `Bearer ${token}` };\n // Two-step lookup: My Drive root \u2192 home/ \u2192 .rmfmail\n // Direct My-Drive-root scope finds shared folders too (spouse's .rmfmail\n // appears at root of \"Shared with me\"). Path scope avoids that AND\n // matches the user's actual layout: ~/home/.rmfmail.\n const homeQ = encodeURIComponent(\"name='home' and mimeType='application/vnd.google-apps.folder' and 'root' in parents and trashed=false\");\n const homeRes = await fetch(\n `https://www.googleapis.com/drive/v3/files?q=${homeQ}&fields=files(id,name)&spaces=drive`,\n { headers }\n );\n if (!homeRes.ok) {\n console.warn(`[gdrive] home folder search failed: ${homeRes.status}`);\n return null;\n }\n const homeData = await homeRes.json() as any;\n const home = homeData.files?.[0];\n if (!home?.id) {\n console.warn(\"[gdrive] 'home' folder not found at My Drive root\");\n return null;\n }\n const q = encodeURIComponent(`name='.rmfmail' and mimeType='application/vnd.google-apps.folder' and '${home.id}' in parents and trashed=false`);\n const res = await fetch(\n `https://www.googleapis.com/drive/v3/files?q=${q}&fields=files(id,name,owners(emailAddress))&spaces=drive`,\n { headers }\n );\n if (!res.ok) {\n console.warn(`[gdrive] .rmfmail search failed: ${res.status}`);\n return null;\n }\n const data = await res.json() as any;\n const folder = data.files?.[0];\n if (!folder?.id) return null;\n const homeName = home.name || \"home\";\n const folderName = folder.name || \".rmfmail\";\n return {\n id: folder.id,\n name: folderName,\n path: `My Drive/${homeName}/${folderName}`,\n ownerEmail: folder.owners?.[0]?.emailAddress,\n };\n}\n\n// \u2500\u2500 Initialization \u2500\u2500\n\nasync function waitForNativeBridge(timeoutMs: number = 5000): Promise<void> {\n if ((window as any)._nativeBridge) return;\n return new Promise((resolve) => {\n const start = Date.now();\n const check = () => {\n if ((window as any)._nativeBridge || Date.now() - start > timeoutMs) {\n resolve();\n } else {\n setTimeout(check, 50);\n }\n };\n // Also listen for the event C# dispatches after bridge injection\n window.addEventListener(\"nativebridgeready\", () => resolve(), { once: true });\n check();\n });\n}\n\nexport async function initAndroid(): Promise<void> {\n console.log(\"[android] Initializing mailx (main-thread mode)...\");\n\n // Main-thread path: async I/O (fetch, TCP bridge) doesn't block the UI,\n // and only sql.js is CPU-bound enough to maybe warrant a Worker later.\n // Worker path was reverted 2026-04-14 (stuck at \"Initializing...\" on Android).\n await waitForNativeBridge();\n if ((window as any)._nativeBridge && !(window as any).msgapi) {\n (window as any).msgapi = (window as any)._nativeBridge;\n }\n\n db = new WebMailxDB(\"mailx\");\n await db.waitReady();\n bodyStore = new WebMessageStore();\n syncManager = new AndroidSyncManager(db, bodyStore);\n service = new WebMailxService(db, bodyStore, syncManager);\n\n let accounts = await loadAccounts();\n console.log(`[android] ${accounts.length} account(s) found`);\n\n // Find a Gmail account to use as the GDrive token provider\n let gmailTokenProvider: (() => Promise<string>) | null = null;\n for (const account of accounts) {\n if (!account.enabled) continue;\n const domain = account.email?.split(\"@\")[1]?.toLowerCase() || \"\";\n if (domain === \"gmail.com\" || domain === \"googlemail.com\") {\n const tp = createNativeTokenProvider(account.email);\n syncManager.setTokenProvider(account.id, tp);\n if (!gmailTokenProvider) gmailTokenProvider = tp;\n }\n await syncManager.addAccount(account);\n }\n\n // Install the mailxapi bridge + drain pending queues IMMEDIATELY using\n // the local-cache account list. UI shouldn't wait on GDrive (which can\n // be slow on cold network) before becoming actionable. GDrive\n // reconciliation (below) runs in the background and re-registers fresh\n // accounts when it returns.\n installBridge();\n for (const account of accounts) {\n if (!account.enabled) continue;\n syncManager.processSendQueue(account.id)\n .catch(e => console.error(`[android] processSendQueue ${account.id}: ${e.message}`));\n syncManager.processSyncActions(account.id)\n .catch(e => console.error(`[android] processSyncActions ${account.id}: ${e.message}`));\n }\n // First sync from local accounts on a tiny delay so the UI gets to paint.\n setTimeout(() => {\n syncManager.syncAll().catch(e => console.error(`[android] Sync error: ${e.message}`));\n }, 1000);\n\n // GDrive reconciliation runs in the background \u2014 accounts.jsonc on the\n // shared cloud may have been edited from another device, so we re-pull\n // and re-register if it differs from the cached copy. The user can\n // already see and use mail by the time this resolves.\n if (gmailTokenProvider) {\n const tp = gmailTokenProvider;\n (async () => {\n setGDriveTokenProvider(tp);\n try {\n console.log(\"[android] Looking up GDrive .rmfmail folder\u2026\");\n const folder = await findGDriveMailxFolder(tp);\n if (!folder) {\n emitEvent({\n type: \"fatal\",\n key: \"gdrive-folder-missing\",\n message: \"GDrive folder '.rmfmail' not found \u2014 app cannot start. Create it or sign in with the correct Google account.\",\n });\n } else {\n const folderId = folder.id;\n setGDriveFolderId(folderId, folder.name, folder.ownerEmail, folder.path);\n console.log(`[android] GDrive ${folder.path} folder: ${folderId} (owner=${folder.ownerEmail || \"?\"})`);\n // DEBUG: list all files in the folder\n try {\n const tk = await tp();\n const lr = await fetch(\n `https://www.googleapis.com/drive/v3/files?q='${folderId}'+in+parents+and+trashed%3Dfalse&fields=files(id,name,mimeType,owners(emailAddress))`,\n { headers: { \"Authorization\": `Bearer ${tk}` } }\n );\n if (lr.ok) {\n const ld = await lr.json() as any;\n const names = (ld.files || []).map((f: any) => `${f.name}(${f.owners?.[0]?.emailAddress || \"?\"})`).join(\",\");\n console.log(`[android] Folder contents: ${ld.files?.length || 0} files [${names}]`);\n } else {\n console.warn(`[android] List folder failed: ${lr.status}`);\n }\n } catch (e: any) {\n console.warn(`[android] List debug: ${e.message}`);\n }\n // Read accounts directly from GDrive (bypass IndexedDB cache)\n console.log(\"[android] Reading accounts.jsonc from GDrive...\");\n const gdriveAccounts = await loadAccountsFromCloud();\n console.log(`[android] GDrive returned ${gdriveAccounts.length} accounts: ${gdriveAccounts.map(a => a.id).join(\",\")}`);\n if (gdriveAccounts.length > 0) {\n // Use canonical GDrive accounts (upsert handles overwrites)\n accounts = gdriveAccounts;\n for (const account of accounts) {\n vlog(`init: registering ${account.id} email=${account.email} enabled=${account.enabled} imap=${JSON.stringify(account.imap)}`);\n if (!account.enabled) {\n vlog(`init: ${account.id} disabled, skipping`);\n continue;\n }\n const domain = account.email?.split(\"@\")[1]?.toLowerCase() || \"\";\n if (domain === \"gmail.com\" || domain === \"googlemail.com\") {\n syncManager.setTokenProvider(account.id, createNativeTokenProvider(account.email));\n }\n await syncManager.addAccount(account);\n }\n console.log(`[android] Loaded ${accounts.length} accounts from GDrive`);\n }\n // Register this Android device in clients.jsonc\n await registerDeviceInGDrive(tp, folderId, accounts.map(a => a.id));\n }\n } catch (e: any) {\n emitEvent({\n type: \"fatal\",\n key: \"gdrive-access-failed\",\n message: `GDrive access failed \u2014 app cannot start: ${e.message}`,\n });\n }\n })();\n }\n\n // Startup contacts load. TWO sources, both wanted:\n // 1. The shared GDrive contacts.jsonc \u2014 desktop's full union (everything\n // it discovered from its mailbox + Google contacts + preferred). This\n // is how Android gets contacts it never saw in its own partial corpus.\n // 2. Google People API \u2014 keeps Google-side contacts current. Runs for\n // Google accounts ONLY; an IMAP account has no People API and would\n // pop a bogus OAuth consent.\n service.loadContactsConfig()\n .catch((e: any) => console.error(`[android] startup contacts.jsonc load: ${e?.message || e}`));\n for (const account of db.getAccounts()) {\n if (!account.email || !isGoogleAccount(account)) continue;\n const tp = createNativeTokenProvider(account.email);\n syncGoogleContactsForAccount(db, account.id, tp)\n .catch(e => console.error(`[android] startup contacts sync ${account.id}: ${e.message}`));\n }\n\n // Periodic re-sync every 2 minutes (no IDLE on Android, so poll)\n const SYNC_INTERVAL_MS = 2 * 60 * 1000;\n let contactsSyncTickCounter = 0;\n setInterval(() => {\n console.log(\"[sync] periodic poll\");\n vlog(\"periodic sync poll\");\n // Retry any failed/stranded sends every poll tick\n for (const account of db.getAccounts()) {\n syncManager.processSendQueue(account.id)\n .catch(e => console.error(`[android] retry ${account.id}: ${e.message}`));\n syncManager.processSyncActions(account.id)\n .catch(e => console.error(`[android] processSyncActions ${account.id}: ${e.message}`));\n }\n syncManager.syncAll().catch(e => console.error(`[android] Periodic sync error: ${e.message}`));\n // Contacts: once every 8 ticks (~16 min). Incremental, so cheap \u2014\n // a clean tick is one HTTP round-trip with empty connections list.\n if (++contactsSyncTickCounter % 8 === 0) {\n for (const account of db.getAccounts()) {\n if (!account.email || !isGoogleAccount(account)) continue;\n const tp = createNativeTokenProvider(account.email);\n syncGoogleContactsForAccount(db, account.id, tp)\n .catch(e => console.error(`[android] periodic contacts sync ${account.id}: ${e.message}`));\n }\n }\n }, SYNC_INTERVAL_MS);\n\n // Immediate sync + send-queue drain when app comes back to foreground\n // (e.g. user switches from another app). Without the send-queue drain,\n // a message queued while offline waits up to 2 minutes after resume\n // before retrying \u2014 long enough for the user to think it's stuck.\n document.addEventListener(\"visibilitychange\", () => {\n if (document.visibilityState === \"visible\") {\n console.log(\"[sync] resume poll\");\n for (const account of db.getAccounts()) {\n syncManager.processSendQueue(account.id)\n .catch(e => console.error(`[android] resume send-drain ${account.id}: ${e.message}`));\n }\n syncManager.syncAll().catch(e => console.error(`[android] Resume sync error: ${e.message}`));\n }\n });\n\n console.log(\"[android] Initialization complete\");\n emitEvent({ type: \"connected\" });\n}\n\nexport async function resetStore(): Promise<void> {\n await service.resetStore();\n await clearSettings();\n console.log(\"[android] Store reset\");\n}\n\n// \u2500\u2500 mailxapi Bridge \u2500\u2500\n\nfunction installBridge(): void {\n const api = {\n isApp: true,\n platform: \"android\",\n getAccounts: () => service.getAccounts(),\n getFolders: (accountId: string) => service.getFolders(accountId),\n getMessages: (accountId: string, folderId: number, page: number, pageSize: number) =>\n service.getMessages(accountId, folderId, page, pageSize),\n getUnifiedInbox: (page: number, pageSize: number) => service.getUnifiedInbox(page, pageSize),\n getMessage: (accountId: string, uid: number, allowRemote: boolean, folderId?: number) =>\n service.getMessage(accountId, uid, allowRemote, folderId),\n updateFlags: async (accountId: string, uid: number, flags: string[]) => {\n await service.updateFlags(accountId, uid, flags); return { ok: true };\n },\n deleteMessage: async (accountId: string, uid: number) => {\n await service.deleteMessage(accountId, uid); return { ok: true };\n },\n deleteMessages: async (accountId: string, uids: number[]) => {\n await service.deleteMessages(accountId, uids); return { ok: true, count: uids.length };\n },\n undeleteMessage: async (accountId: string, uid: number, folderId: number) => {\n await service.undeleteMessage(accountId, uid, folderId); return { ok: true };\n },\n moveMessage: async (accountId: string, uid: number, targetFolderId: number, targetAccountId?: string) => {\n await service.moveMessage(accountId, uid, targetFolderId, targetAccountId); return { ok: true };\n },\n moveMessages: async (accountId: string, uids: number[], targetFolderId: number) => {\n await service.moveMessages(accountId, uids, targetFolderId); return { ok: true, count: uids.length };\n },\n sendMessage: async (msg: any) => { await service.send(msg); return { ok: true }; },\n saveDraft: (p: any) => service.saveDraft(p.accountId, p.subject, p.bodyHtml, p.bodyText, p.to, p.cc, p.previousDraftUid, p.draftId),\n deleteDraft: async (accountId: string, draftUid: number) => {\n await service.deleteDraft(accountId, draftUid); return { ok: true };\n },\n searchMessages: (query: string, page: number, pageSize: number) => service.search(query, page, pageSize),\n searchContacts: (query: string) => service.searchContacts(query),\n listContacts: (query: string, page = 1, pageSize = 100) => service.listContacts(query || \"\", page, pageSize),\n upsertContact: (name: string, email: string) => service.upsertContact(name || \"\", email),\n deleteContact: (email: string) => service.deleteContact(email),\n addContact: (name: string, email: string) => service.addContact(name || \"\", email),\n hasCcHistoryTo: (email: string) => ({ hasCc: service.hasCcHistoryTo?.(email) ?? false }),\n syncAll: async () => { await service.syncAll(); return { ok: true }; },\n syncAccount: async (accountId: string) => { await service.syncAccount(accountId); return { ok: true }; },\n getSyncPending: () => service.getSyncPending(),\n getPrimaryAccount: (feature?: string) => {\n // Resolve primary account for a feature (calendar/tasks/contacts):\n // per-feature flag \u2192 catch-all `primary` \u2192 first account.\n const all = db.getAccountConfigs().map(r => {\n try { return { id: r.id, name: r.name, email: r.email, ...JSON.parse(r.configJson) }; }\n catch { return { id: r.id, name: r.name, email: r.email }; }\n });\n if (feature) {\n const key = \"primary\" + feature.charAt(0).toUpperCase() + feature.slice(1);\n const perFeature = all.find((a: any) => a[key]);\n if (perFeature) return perFeature;\n }\n return all.find((a: any) => a.primary) || all[0] || null;\n },\n reauthenticate: async (accountId: string) => ({ ok: await service.reauthenticate(accountId) }),\n markFolderRead: (_accountId: string, folderId: number) => { service.markFolderRead(folderId); return { ok: true }; },\n createFolder: async () => ({ ok: false, error: \"Not supported on mobile\" }),\n renameFolder: async () => ({ ok: false, error: \"Not supported on mobile\" }),\n deleteFolder: async () => ({ ok: false, error: \"Not supported on mobile\" }),\n emptyFolder: async () => ({ ok: false, error: \"Not supported on mobile\" }),\n allowRemoteContent: async (type: string, value: string) => {\n await service.allowRemoteContent(type as any, value); return { ok: true };\n },\n flagSenderOrDomain: async (type: string, value: string) => {\n return await service.flagSenderOrDomain(type as any, value);\n },\n getPriorityLists: () => service.getPriorityLists(),\n setPrioritySender: async (email: string, value: boolean, name?: string) => {\n await service.setPrioritySender(email, !!value, name); return { ok: true };\n },\n setPriorityDomain: async (domain: string, value: boolean) => {\n await service.setPriorityDomain(domain, !!value); return { ok: true };\n },\n getSettings: () => service.getSettings(),\n saveSettingsData: async (data: any) => { await service.saveSettingsData(data); return { ok: true }; },\n getVersion: async () => {\n const settings = await service.getSettings();\n const nativeVersion = (window as any)._nativeBridge?.info?.version || \"?\";\n return { version: nativeVersion, theme: settings.ui?.theme || \"system\", storage: service.getStorageInfo(), platform: \"android\" };\n },\n getAutocompleteSettings: () => service.getAutocompleteSettings(),\n saveAutocompleteSettings: async (settings: any) => { await service.saveAutocompleteSettings(settings); return { ok: true }; },\n getDeviceAccounts: async () => {\n const bridge = (window as any)._nativeBridge;\n if (bridge?.app?.getDeviceAccounts) {\n return bridge.app.getDeviceAccounts();\n }\n return [];\n },\n setupAccount: async (name: string, email: string, _password: string) => {\n try {\n if (!email || !email.includes(\"@\")) {\n return { ok: false, error: \"Email address required\" };\n }\n const domain = email.split(\"@\")[1].toLowerCase();\n const id = domain.split(\".\")[0] || \"account\";\n const account: AccountConfig = {\n id,\n name: name || email.split(\"@\")[0],\n email,\n enabled: true,\n imap: { host: `imap.${domain}`, port: 993, tls: true, auth: \"oauth2\" as const, user: email },\n smtp: { host: `smtp.${domain}`, port: 587, tls: true, auth: \"oauth2\" as const, user: email },\n };\n // Apply known provider defaults\n if (domain === \"gmail.com\" || domain === \"googlemail.com\") {\n account.label = \"Gmail\";\n account.imap = { host: \"imap.gmail.com\", port: 993, tls: true, auth: \"oauth2\", user: email };\n account.smtp = { host: \"smtp.gmail.com\", port: 587, tls: true, auth: \"oauth2\", user: email };\n }\n const existing = await loadAccounts();\n if (existing.some(a => a.email === email)) {\n return { ok: true, message: \"Account already exists\" };\n }\n existing.push(account);\n await saveAccounts(existing);\n // Set up token provider before adding account\n const setupDomain = email.split(\"@\")[1].toLowerCase();\n if (setupDomain === \"gmail.com\" || setupDomain === \"googlemail.com\") {\n syncManager.setTokenProvider(account.id, createNativeTokenProvider(email));\n }\n await syncManager.addAccount(account);\n db.upsertAccount(account.id, account.name, account.email, JSON.stringify(account));\n console.log(`[android] Account added: ${email}`);\n return { ok: true, message: `Added ${email}. Syncing...` };\n } catch (e: any) {\n return { ok: false, error: e.message };\n }\n },\n repairAccounts: async () => ({ ok: false, error: \"Use desktop for repair\" }),\n resetStore: () => resetStore(),\n resetAll: async () => {\n const bridge = (window as any)._nativeBridge;\n if (bridge?.app?.resetAll) {\n await bridge.app.resetAll();\n } else {\n await resetStore();\n location.reload();\n }\n },\n restart: () => { location.reload(); },\n onEvent: (handler: (event: any) => void) => { eventHandlers.push(handler); },\n };\n\n (window as any).mailxapi = api;\n window.dispatchEvent(new CustomEvent(\"mailxapiready\"));\n console.log(\"[android] mailxapi bridge installed\");\n}\n", "/**\n * Gmail API provider \u2014 replaces IMAP for Gmail accounts.\n * Uses REST API for fast, reliable sync without connection limit issues.\n *\n * SOURCE OF TRUTH: this file is the single canonical Gmail provider for\n * mailx. Both desktop (mailx-imap, Node) and Android (mailx-store-web,\n * WebView) re-export from here. Earlier they had parallel copies that\n * silently drifted (the 403-quota retry was added to desktop one day and\n * missed in the web copy until a user reported broken prefetch).\n *\n * Platform requirements: globalThis.fetch (Node 18+ and all browsers/WebViews),\n * atob, Uint8Array, TextDecoder. No Node-specific imports.\n */\n\nimport type { MailProvider, ProviderFolder, ProviderMessage, FetchOptions } from \"./types.js\";\n\nconst API = \"https://gmail.googleapis.com/gmail/v1/users/me\";\n\n/** Convert Gmail hex ID to integer UID (lower 48 bits \u2014 deterministic, stable) */\nfunction idToUid(id: string): number {\n const hex = id.length > 12 ? id.slice(-12) : id;\n return parseInt(hex, 16);\n}\n\n/** Map Gmail label to IMAP-style specialUse */\nfunction labelSpecialUse(label: { id: string; type: string; name: string }): string {\n switch (label.id) {\n case \"INBOX\": return \"inbox\";\n case \"SENT\": return \"sent\";\n case \"DRAFT\": return \"drafts\";\n case \"TRASH\": return \"trash\";\n case \"SPAM\": return \"junk\";\n case \"STARRED\": return \"\";\n case \"IMPORTANT\": return \"\";\n default: return \"\";\n }\n}\n\n/** Parse RFC 2822 headers from Gmail metadata payload */\nfunction getHeader(headers: { name: string; value: string }[], name: string): string {\n return headers.find(h => h.name.toLowerCase() === name.toLowerCase())?.value || \"\";\n}\n\n/** Parse \"Name <addr>\" or \"addr\" into { name, address } */\nfunction parseAddress(raw: string): { name?: string; address?: string } {\n const match = raw.match(/^\"?([^\"<]*?)\"?\\s*<([^>]+)>/);\n if (match) return { name: match[1].trim(), address: match[2].trim() };\n return { address: raw.trim() };\n}\n\nfunction parseAddressList(raw: string): { name?: string; address?: string }[] {\n if (!raw) return [];\n // Split on commas that aren't inside quotes\n return raw.split(/,(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)/).map(s => parseAddress(s.trim())).filter(a => a.address);\n}\n\n/** Rate-limit + cooldown state shared across all GmailApiProvider instances.\n * Gmail enforces rate limits per Google user, not per JS object, so sharing\n * state here prevents new `new GmailApiProvider(...)` from side-stepping the\n * cooldown by creating a fresh instance. Single-account setups won't notice;\n * multi-account setups are slightly over-throttled, which is safer than\n * burning through Google's tolerance. */\nconst rateState = {\n tokens: 0,\n lastRefill: 0,\n cooldownUntil: 0,\n /** Tokens refilled per second (keeps us well under per-user-per-sec caps). */\n rate: 8,\n /** Max burst above steady state. */\n burst: 8,\n};\nrateState.tokens = rateState.burst;\nrateState.lastRefill = Date.now();\n\n/** Extract Google's structured \"reason\" from a JSON error body when possible\n * (e.g. `userRateLimitExceeded`, `rateLimitExceeded`, `quotaExceeded`). */\nfunction parseGoogleReason(body: string): string {\n const m = body.match(/\"reason\"\\s*:\\s*\"([^\"]+)\"/);\n return m ? m[1] : \"\";\n}\n\nexport class GmailApiProvider implements MailProvider {\n constructor(private tokenProvider: () => Promise<string>) {}\n\n /** Block until (a) cooldown has elapsed and (b) a token is available.\n * Token-bucket refill happens lazily on each call. */\n private async acquireToken(): Promise<void> {\n // Respect an active cooldown first \u2014 refuse to even try until it ends.\n const now = Date.now();\n if (rateState.cooldownUntil > now) {\n const waitMs = rateState.cooldownUntil - now;\n console.log(` [gmail] cooldown: waiting ${(waitMs / 1000).toFixed(1)}s before next request`);\n await new Promise(r => setTimeout(r, waitMs));\n }\n // Lazy refill, then spin-wait in chunks until a token is ready.\n while (true) {\n const t = Date.now();\n const elapsedSec = (t - rateState.lastRefill) / 1000;\n rateState.tokens = Math.min(rateState.burst, rateState.tokens + elapsedSec * rateState.rate);\n rateState.lastRefill = t;\n if (rateState.tokens >= 1) {\n rateState.tokens -= 1;\n return;\n }\n const waitMs = Math.max(20, ((1 - rateState.tokens) / rateState.rate) * 1000);\n await new Promise(r => setTimeout(r, waitMs));\n }\n }\n\n private async fetch(path: string, options: RequestInit = {}): Promise<any> {\n const token = await this.tokenProvider();\n const maxAttempts = 6;\n const baseDelayMs = 1000;\n const maxDelayMs = 60_000;\n let lastStatus = 0;\n for (let attempt = 0; attempt < maxAttempts; attempt++) {\n await this.acquireToken();\n const res = await globalThis.fetch(`${API}${path}`, {\n ...options,\n headers: {\n \"Authorization\": `Bearer ${token}`,\n \"Content-Type\": \"application/json\",\n ...options.headers,\n },\n });\n // 403 with \"Quota exceeded\" body is Google's per-minute quota limit.\n // Not 429. Retry like a rate-limit, don't throw as a permanent failure.\n let isQuota403 = false;\n let reason = \"\";\n if (res.status === 403 || res.status === 429) {\n try {\n const cloned = res.clone();\n const body = await cloned.text();\n reason = parseGoogleReason(body);\n if (res.status === 403 && /quota exceeded|rate ?limit|user[-_ ]rate/i.test(body)) isQuota403 = true;\n } catch { /* ignore */ }\n }\n if (res.status === 429 || res.status >= 500 || isQuota403) {\n lastStatus = res.status;\n // Honor Retry-After if present (seconds or HTTP-date)\n const retryAfter = res.headers.get(\"Retry-After\");\n let delay = baseDelayMs * Math.pow(2, attempt);\n if (retryAfter) {\n const asInt = parseInt(retryAfter, 10);\n if (!isNaN(asInt)) delay = asInt * 1000;\n else {\n const when = Date.parse(retryAfter);\n if (!isNaN(when)) delay = Math.max(0, when - Date.now());\n }\n }\n // Per-minute-quota 403 deserves a minimum 60s wait \u2014 the quota\n // resets per minute, so shorter backoff just re-triggers.\n if (isQuota403) delay = Math.max(delay, 60_000);\n // Full jitter to avoid synchronized retries\n delay = Math.min(maxDelayMs, delay);\n delay = Math.floor(delay * (0.5 + Math.random() * 0.5));\n // Install a shared cooldown so *other* in-flight workers wait too,\n // not just this one. Prevents the common failure mode where 5\n // parallel workers each retry independently and keep the\n // per-user QPS pegged above the threshold.\n rateState.cooldownUntil = Math.max(rateState.cooldownUntil, Date.now() + delay);\n const reasonTag = reason ? ` reason=${reason}` : (isQuota403 ? \" (per-minute quota)\" : \"\");\n console.log(` [gmail] ${res.status}${reasonTag} (attempt ${attempt + 1}/${maxAttempts}), waiting ${(delay / 1000).toFixed(1)}s${retryAfter ? ` (Retry-After: ${retryAfter})` : \"\"}...`);\n await new Promise(r => setTimeout(r, delay));\n continue;\n }\n if (!res.ok) {\n const err = await res.text().catch(() => \"\");\n throw new Error(`Gmail API ${res.status}: ${err.substring(0, 200)}`);\n }\n return res.json();\n }\n // Exhausted all retries \u2014 Google is clearly unhappy. Park every\n // subsequent request behind a long cooldown so the next periodic sync\n // (30s) doesn't immediately fire another 6 retries into the same\n // limit. 5 minutes is a floor, not a ceiling \u2014 an incoming Retry-After\n // that's longer will still win via the per-attempt cooldown set above.\n const TERMINAL_COOLDOWN_MS = 5 * 60_000;\n rateState.cooldownUntil = Math.max(rateState.cooldownUntil, Date.now() + TERMINAL_COOLDOWN_MS);\n console.log(` [gmail] exhausted ${maxAttempts} retries \u2014 parking further requests for ${TERMINAL_COOLDOWN_MS / 1000}s`);\n throw new Error(`Gmail API: failed after ${maxAttempts} retries (last status ${lastStatus})`);\n }\n\n async listFolders(): Promise<ProviderFolder[]> {\n const data = await this.fetch(\"/labels\");\n const labels: any[] = data.labels || [];\n const folders: ProviderFolder[] = [];\n\n for (const label of labels) {\n // Skip system labels that aren't useful as folders\n if ([\"UNREAD\", \"STARRED\", \"IMPORTANT\", \"CATEGORY_PERSONAL\",\n \"CATEGORY_SOCIAL\", \"CATEGORY_PROMOTIONS\", \"CATEGORY_UPDATES\",\n \"CATEGORY_FORUMS\", \"CHAT\"].includes(label.id)) continue;\n\n const specialUse = labelSpecialUse(label);\n // Map Gmail path separators (/) to IMAP-style\n const path = label.name || label.id;\n const name = path.includes(\"/\") ? path.split(\"/\").pop()! : path;\n\n folders.push({\n path,\n name,\n delimiter: \"/\",\n specialUse,\n // No \\\\Noselect on Gmail labels: the unwanted system labels\n // (UNREAD/STARRED/IMPORTANT/CATEGORY_*/CHAT) are filtered\n // above, leaving INBOX/SENT/DRAFT/TRASH/SPAM and user labels \u2014\n // ALL of which are selectable. The previous \\\\Noselect tag\n // on system labels caused mailx-imap to skip them entirely,\n // so INBOX never appeared in the folder tree.\n flags: [],\n });\n }\n return folders;\n }\n\n /** List message IDs matching a query, handling pagination.\n * IMPORTANT: on any error we throw \u2014 do NOT return a partial list, because\n * callers use this for sync reconciliation and a short list would delete\n * real messages from the local DB. Returning [] silently caused the\n * \"INBOX empty in mailx\" bug when a rate-limit hit mid-pagination. */\n private async listMessageIds(query: string, maxResults = 500): Promise<string[]> {\n // maxResults === 0 \u2192 unlimited (for date-bounded queries where the\n // query itself caps the result set).\n const unlimited = maxResults === 0;\n const ids: string[] = [];\n let pageToken = \"\";\n let truncated = false;\n while (true) {\n const pageSize = unlimited ? 500 : Math.min(maxResults - ids.length, 500);\n const params = new URLSearchParams({ q: query, maxResults: String(pageSize) });\n if (pageToken) params.set(\"pageToken\", pageToken);\n const data = await this.fetch(`/messages?${params}`);\n for (const msg of data.messages || []) {\n ids.push(msg.id);\n }\n if (!data.nextPageToken) break;\n if (!unlimited && ids.length >= maxResults) {\n // Hit the caller's cap but the server has more. Flag it so\n // reconcile-style callers can refuse to treat this as complete.\n truncated = true;\n break;\n }\n pageToken = data.nextPageToken;\n }\n (ids as any)._truncated = truncated;\n return ids;\n }\n\n /** Batch-fetch message metadata or full content */\n private async batchFetch(ids: string[], options: FetchOptions = {}, onChunk?: (msgs: ProviderMessage[]) => void): Promise<ProviderMessage[]> {\n const all: ProviderMessage[] = [];\n const chunkSize = options.source ? 10 : 50; // Smaller chunks for full bodies\n const format = options.source ? \"raw\" : \"metadata\";\n\n for (let i = 0; i < ids.length; i += chunkSize) {\n const chunk = ids.slice(i, i + chunkSize);\n // Sequential fetches to avoid Gmail 429 rate limits\n const messages: any[] = [];\n for (const id of chunk) {\n const params = new URLSearchParams({ format });\n if (format === \"metadata\") {\n for (const h of [\"From\", \"To\", \"Cc\", \"Subject\", \"Message-ID\", \"Date\", \"In-Reply-To\", \"References\"]) {\n params.append(\"metadataHeaders\", h);\n }\n }\n messages.push(await this.fetch(`/messages/${id}?${params}`));\n }\n\n const parsed: ProviderMessage[] = messages.map(msg => this.parseMessage(msg, options));\n all.push(...parsed);\n if (onChunk) onChunk(parsed);\n }\n return all;\n }\n\n /** Parse a Gmail API message response into ProviderMessage */\n private parseMessage(msg: any, options: FetchOptions = {}): ProviderMessage {\n const labels: string[] = msg.labelIds || [];\n const headers = msg.payload?.headers || [];\n\n let source = \"\";\n if (options.source && msg.raw) {\n // Gmail returns URL-safe base64 \u2014 convert to standard base64 then decode\n const base64 = msg.raw.replace(/-/g, \"+\").replace(/_/g, \"/\");\n source = new TextDecoder().decode(Uint8Array.from(atob(base64), c => c.charCodeAt(0)));\n }\n\n const fromRaw = getHeader(headers, \"From\");\n const toRaw = getHeader(headers, \"To\");\n const ccRaw = getHeader(headers, \"Cc\");\n const dateRaw = getHeader(headers, \"Date\") || \"\";\n const subject = getHeader(headers, \"Subject\") || msg.snippet || \"\";\n const messageId = getHeader(headers, \"Message-ID\") || \"\";\n const inReplyTo = getHeader(headers, \"In-Reply-To\") || \"\";\n const referencesRaw = getHeader(headers, \"References\") || \"\";\n const references = referencesRaw.trim()\n ? referencesRaw.split(/\\s+/).filter(r => r.startsWith(\"<\") && r.endsWith(\">\"))\n : [];\n\n return {\n uid: idToUid(msg.id),\n messageId,\n providerId: msg.id,\n date: dateRaw ? new Date(dateRaw) : (msg.internalDate ? new Date(Number(msg.internalDate)) : null),\n subject,\n from: parseAddressList(fromRaw),\n to: parseAddressList(toRaw),\n cc: parseAddressList(ccRaw),\n inReplyTo,\n references,\n seen: !labels.includes(\"UNREAD\"),\n flagged: labels.includes(\"STARRED\"),\n answered: false, // Gmail API doesn't expose this directly\n draft: labels.includes(\"DRAFT\"),\n size: msg.sizeEstimate || 0,\n source,\n };\n }\n\n async fetchSince(folder: string, sinceUid: number, options: FetchOptions = {}): Promise<ProviderMessage[]> {\n // Gmail message IDs are hash-derived, NOT monotonic \u2014 filtering by\n // `uid > sinceUid` silently drops new messages whose hash happens to\n // fall below the high-water mark. Fetch by date (when caller supplied\n // a `since` window) or fall back to the recent-200 page.\n void sinceUid;\n let query = `in:${this.folderToLabel(folder)}`;\n if (options.since) {\n // after: is inclusive at day granularity; filter precisely on the\n // client side since Gmail's search is whole-day.\n query += ` after:${this.formatDate(options.since)}`;\n }\n // When the caller bounded by date, let pagination run \u2014 the query\n // is self-limiting. Otherwise cap at the recent 200.\n const cap = options.since ? 0 : 200;\n const ids = await this.listMessageIds(query, cap);\n return this.batchFetch(ids, options);\n }\n\n async fetchByDate(folder: string, since: Date, before: Date, options: FetchOptions = {},\n onChunk?: (msgs: ProviderMessage[]) => void): Promise<ProviderMessage[]> {\n const afterDate = this.formatDate(since);\n const beforeDate = this.formatDate(before);\n const query = `in:${this.folderToLabel(folder)} after:${afterDate} before:${beforeDate}`;\n // Date-bounded \u2014 let pagination drain the full range instead of stopping at 500.\n const ids = await this.listMessageIds(query, 0);\n return this.batchFetch(ids, options, onChunk);\n }\n\n async fetchByUids(folder: string, uids: number[], options: FetchOptions = {}): Promise<ProviderMessage[]> {\n // UIDs are derived from Gmail IDs \u2014 we'd need a reverse lookup\n // For now, fetch all messages in folder and filter\n const query = `in:${this.folderToLabel(folder)}`;\n const ids = await this.listMessageIds(query);\n const uidSet = new Set(uids);\n const matchingIds = ids.filter(id => uidSet.has(idToUid(id)));\n return this.batchFetch(matchingIds, options);\n }\n\n /** Bulk-fetch raw bodies for many UIDs in one \"folder\" (Gmail label).\n * Lists the label once, builds UID\u2192ID map, then streams bodies through\n * `onBody`. Uses Gmail's HTTP batch endpoint (up to 100 sub-requests per\n * round-trip) when available, with a single-request fallback so a batch\n * protocol blip doesn't starve prefetch entirely.\n *\n * NOTE: Gmail's model is labels, not folders \u2014 a single message can be in\n * many labels. Treating each label as a folder causes duplicate fetches\n * across labels. Proper fix tracked as separate TODO (\"Gmail label-native\n * model\"). For now we mirror the IMAP folder grouping, accepting duplicate\n * fetches of multi-labeled messages. */\n async fetchBodiesBatch(\n folder: string,\n uids: number[],\n onBody: (uid: number, source: string) => void,\n ): Promise<void> {\n if (uids.length === 0) return;\n const query = `in:${this.folderToLabel(folder)}`;\n const ids = await this.listMessageIds(query, 10000);\n const uidToId = new Map<number, string>();\n for (const id of ids) uidToId.set(idToUid(id), id);\n const wanted: { uid: number; id: string }[] = [];\n for (const uid of uids) {\n const id = uidToId.get(uid);\n if (id) wanted.push({ uid, id });\n }\n if (wanted.length === 0) return;\n\n // Item 16 / C24 Gmail half: HTTP /batch prefetch. One multipart POST\n // with up to 100 sub-requests replaces N round-trips. Typical \u00D710-20\n // speedup on large folders. Each batch still costs the same tokens\n // from the rate bucket as the individual GETs would have (no free\n // ride), but wall-clock latency collapses to roughly one round-trip\n // per 100 messages instead of per message.\n const BATCH_SIZE = 100;\n for (let i = 0; i < wanted.length; i += BATCH_SIZE) {\n const slice = wanted.slice(i, i + BATCH_SIZE);\n try {\n await this.batchFetchBodies(slice, onBody);\n } catch (e: any) {\n // Batch failed (malformed multipart, network reset, auth\n // mid-flight). Fall back to a bounded-concurrency per-message\n // loop for this slice so the user still gets bodies \u2014 we'd\n // rather ship the feature degraded than lose prefetch.\n console.error(` [gmail batch] fell back to per-message: ${e.message}`);\n await this.fetchBodiesIndividually(slice, onBody);\n }\n }\n }\n\n /** POST /batch/gmail/v1 with up to 100 sub-requests. See\n * https://developers.google.com/gmail/api/guides/batch\n * for the multipart/mixed wire format. */\n private async batchFetchBodies(\n items: { uid: number; id: string }[],\n onBody: (uid: number, source: string) => void,\n ): Promise<void> {\n if (items.length === 0) return;\n // One token covers the whole batch endpoint round-trip; Google's\n // per-user quota charges each inner request individually, but the\n // per-second request limit counts the batch as a single request \u2014\n // so rate-bucket budget matches wall-clock cost.\n await this.acquireToken();\n const token = await this.tokenProvider();\n const boundary = `batch_mailx_${Date.now()}_${Math.floor(Math.random() * 1e9)}`;\n const parts: string[] = [];\n for (const { id } of items) {\n parts.push(\n `--${boundary}\\r\\n` +\n `Content-Type: application/http\\r\\n` +\n `Content-ID: <${id}>\\r\\n` +\n `\\r\\n` +\n `GET /gmail/v1/users/me/messages/${id}?format=raw\\r\\n` +\n `Accept: application/json\\r\\n` +\n `\\r\\n`\n );\n }\n parts.push(`--${boundary}--\\r\\n`);\n const body = parts.join(\"\");\n const res = await globalThis.fetch(\"https://gmail.googleapis.com/batch/gmail/v1\", {\n method: \"POST\",\n headers: {\n \"Authorization\": `Bearer ${token}`,\n \"Content-Type\": `multipart/mixed; boundary=${boundary}`,\n },\n body,\n });\n if (!res.ok) {\n const text = await res.text().catch(() => \"\");\n throw new Error(`batch HTTP ${res.status}: ${text.slice(0, 200)}`);\n }\n const respBody = await res.text();\n // Parse multipart \u2014 extract each inner application/http response,\n // match back to the Content-ID to recover the Gmail message id,\n // then decode the raw body JSON field.\n const respCt = res.headers.get(\"content-type\") || \"\";\n const bMatch = respCt.match(/boundary=([^;]+)/i);\n if (!bMatch) throw new Error(\"batch response missing boundary\");\n const respBoundary = bMatch[1].replace(/^\"|\"$/g, \"\");\n // Google sometimes replies with its own \"batch_...\" boundary even if\n // we sent a different one; parsing by the response's boundary is the\n // reliable path. Split on boundary delimiters.\n const chunks = respBody.split(`--${respBoundary}`);\n for (const chunk of chunks) {\n const trimmed = chunk.trim();\n if (!trimmed || trimmed === \"--\") continue;\n // Each chunk is: outer headers, blank line, inner response\n // (HTTP/1.1 status line, headers, blank line, JSON body).\n // Locate the inner JSON body by finding the double blank after\n // the inner headers section.\n const idMatch = chunk.match(/Content-ID:\\s*<?response-<?([^>\\s]+)>?/i);\n const gmailId = idMatch ? idMatch[1].replace(/^<|>$/g, \"\") : \"\";\n // Skip the outer headers: first blank line ends them.\n const firstBlank = chunk.indexOf(\"\\r\\n\\r\\n\");\n if (firstBlank < 0) continue;\n const inner = chunk.slice(firstBlank + 4);\n // Skip the inner HTTP status + headers: second blank line ends them.\n const secondBlank = inner.indexOf(\"\\r\\n\\r\\n\");\n if (secondBlank < 0) continue;\n const jsonBody = inner.slice(secondBlank + 4).trim();\n if (!jsonBody || jsonBody.startsWith(\"--\")) continue;\n try {\n const parsed = JSON.parse(jsonBody);\n if (!parsed?.raw) continue;\n const actualId = parsed.id || gmailId;\n if (!actualId) continue;\n const uid = idToUid(actualId);\n const base64 = parsed.raw.replace(/-/g, \"+\").replace(/_/g, \"/\");\n const source = new TextDecoder().decode(\n Uint8Array.from(atob(base64), c => c.charCodeAt(0)),\n );\n onBody(uid, source);\n } catch { /* malformed sub-response \u2014 skip, don't poison the batch */ }\n }\n }\n\n /** Fallback path when batch fails \u2014 original bounded-concurrency loop.\n * Kept on the degraded path so a single bad batch doesn't halt prefetch. */\n private async fetchBodiesIndividually(\n items: { uid: number; id: string }[],\n onBody: (uid: number, source: string) => void,\n ): Promise<void> {\n const CONCURRENCY = 2;\n let cursor = 0;\n const worker = async (): Promise<void> => {\n while (cursor < items.length) {\n const idx = cursor++;\n const { uid, id } = items[idx];\n try {\n const msg = await this.fetch(`/messages/${id}?format=raw`);\n if (!msg?.raw) continue;\n const base64 = msg.raw.replace(/-/g, \"+\").replace(/_/g, \"/\");\n const source = new TextDecoder().decode(\n Uint8Array.from(atob(base64), c => c.charCodeAt(0)),\n );\n onBody(uid, source);\n } catch (e: any) {\n console.error(` [gmail batch] UID ${uid}: ${e.message}`);\n }\n }\n };\n await Promise.all(Array.from({ length: Math.min(CONCURRENCY, items.length) }, () => worker()));\n }\n\n async fetchOne(folder: string, uid: number, options: FetchOptions = {}): Promise<ProviderMessage | null> {\n // Caller (mailx-imap) passes providerId straight from the DB row when\n // available \u2014 saves the listMessageIds round trip (up to 2 paged calls\n // of 500 IDs each) plus the UID\u2192ID hash search per body fetch. That's\n // the dominant cost for a stuck \"Fetching message body...\" spinner\n // when Gmail rate-limits.\n let id = options.providerId;\n if (!id) {\n const query = `in:${this.folderToLabel(folder)}`;\n const ids = await this.listMessageIds(query, 1000);\n id = ids.find(id => idToUid(id) === uid);\n if (!id) return null;\n }\n const format = options.source ? \"raw\" : \"metadata\";\n const params = new URLSearchParams({ format });\n if (format === \"metadata\") {\n for (const h of [\"From\", \"To\", \"Cc\", \"Subject\", \"Message-ID\", \"Date\", \"In-Reply-To\", \"References\"]) {\n params.append(\"metadataHeaders\", h);\n }\n }\n const msg = await this.fetch(`/messages/${id}?${params}`);\n return this.parseMessage(msg, options);\n }\n\n /** Apply the absolute flag state to a message.\n * Gmail model: flags are labels. `\\Seen` is the *absence* of UNREAD;\n * `\\Flagged` is the presence of STARRED. We always send both add and\n * remove so the end state matches regardless of what was there before,\n * which makes the call idempotent and safe to retry. */\n async setFlags(folder: string, uid: number, flags: string[]): Promise<void> {\n const query = `in:${this.folderToLabel(folder)}`;\n const ids = await this.listMessageIds(query, 1000);\n const id = ids.find(id => idToUid(id) === uid);\n if (!id) throw new Error(`Gmail setFlags: UID ${uid} not found in ${folder}`);\n const flagSet = new Set(flags);\n const addLabelIds: string[] = [];\n const removeLabelIds: string[] = [];\n if (flagSet.has(\"\\\\Flagged\")) addLabelIds.push(\"STARRED\"); else removeLabelIds.push(\"STARRED\");\n if (flagSet.has(\"\\\\Seen\")) removeLabelIds.push(\"UNREAD\"); else addLabelIds.push(\"UNREAD\");\n await this.fetch(`/messages/${id}/modify`, {\n method: \"POST\",\n body: JSON.stringify({ addLabelIds, removeLabelIds }),\n });\n }\n\n /** Move a message to the trash label. Gmail treats trash as a label, not\n * as a destination folder \u2014 `POST /messages/{id}/trash` is the native\n * path (equivalent to setting TRASH and removing INBOX in one op).\n * Used by mailx's delete/trash path. */\n async trashMessage(folder: string, uid: number, gmailId?: string): Promise<void> {\n // Prefer the caller-supplied Gmail message id (mailx stores it as\n // `provider_id`). The fallback \u2014 list the folder and hash-match the\n // uid \u2014 is capped at 1000, so on a large mailbox it CANNOT find a\n // message past the most-recent ~1000: the trash then throws, the\n // sync action fails its retries, and clearTombstoneForUid resurrects\n // the message (\"deletions un-happening\", Bob 2026-05-17). Passing the\n // stored id skips that broken search entirely.\n let id = gmailId;\n if (!id) {\n const ids = await this.listMessageIds(`in:${this.folderToLabel(folder)}`, 1000);\n id = ids.find(x => idToUid(x) === uid);\n }\n if (!id) throw new Error(`Gmail trashMessage: UID ${uid} not found in ${folder}`);\n await this.fetch(`/messages/${id}/trash`, { method: \"POST\" });\n }\n\n /** Move between \"folders\" == swap one label for another via modifyLabels.\n * System labels (INBOX/SENT/TRASH/SPAM) are translated from the folder\n * path; user labels use the folder path verbatim as the label id. */\n async moveMessage(fromFolder: string, uid: number, toFolder: string, gmailId?: string): Promise<void> {\n // See trashMessage \u2014 prefer the caller's stored Gmail id; the\n // list-and-hash fallback is capped at 1000 and breaks on large\n // folders.\n let id = gmailId;\n if (!id) {\n const ids = await this.listMessageIds(`in:${this.folderToLabel(fromFolder)}`, 1000);\n id = ids.find(x => idToUid(x) === uid);\n }\n if (!id) throw new Error(`Gmail moveMessage: UID ${uid} not found in ${fromFolder}`);\n // Map the folder path to the label id. System labels are uppercased\n // aliases; user labels are passed through as-is (Gmail's label ids\n // for user-created labels match the visible label name).\n const toLabel = this.folderPathToLabelId(toFolder);\n const fromLabel = this.folderPathToLabelId(fromFolder);\n const addLabelIds: string[] = [];\n const removeLabelIds: string[] = [];\n if (toLabel) addLabelIds.push(toLabel);\n if (fromLabel && fromLabel !== toLabel) removeLabelIds.push(fromLabel);\n await this.fetch(`/messages/${id}/modify`, {\n method: \"POST\",\n body: JSON.stringify({ addLabelIds, removeLabelIds }),\n });\n }\n\n /** Folder path \u2192 Gmail label id. System folders map to uppercase label\n * constants; anything else is treated as a user label (identical name). */\n private folderPathToLabelId(path: string): string {\n const lower = path.toLowerCase();\n if (lower === \"inbox\") return \"INBOX\";\n if (lower === \"sent\" || lower === \"[gmail]/sent mail\") return \"SENT\";\n if (lower === \"drafts\" || lower === \"[gmail]/drafts\") return \"DRAFT\";\n if (lower === \"trash\" || lower === \"[gmail]/trash\") return \"TRASH\";\n if (lower === \"spam\" || lower === \"junk email\" || lower === \"[gmail]/spam\") return \"SPAM\";\n if (lower === \"archive\" || lower === \"[gmail]/all mail\") return \"\"; // no-op \u2014 archive is absence-of-INBOX\n return path; // user label \u2014 name-as-id\n }\n\n async getUids(folder: string): Promise<number[]> {\n const query = `in:${this.folderToLabel(folder)}`;\n const ids = await this.listMessageIds(query, 10000);\n const result = ids.map(idToUid);\n // Propagate the truncation flag so reconcile can refuse to delete.\n if ((ids as any)._truncated) (result as any)._truncated = true;\n return result;\n }\n\n async close(): Promise<void> {\n // No persistent connection to close\n }\n\n /** Map folder path to Gmail label query term */\n private folderToLabel(path: string): string {\n const lower = path.toLowerCase();\n if (lower === \"inbox\") return \"inbox\";\n if (lower === \"sent\" || lower === \"[gmail]/sent mail\") return \"sent\";\n if (lower === \"drafts\" || lower === \"[gmail]/drafts\") return \"drafts\";\n if (lower === \"trash\" || lower === \"[gmail]/trash\") return \"trash\";\n if (lower === \"spam\" || lower === \"[gmail]/spam\" || lower === \"junk email\") return \"spam\";\n if (lower === \"archive\" || lower === \"[gmail]/all mail\") return \"all\";\n // Custom label \u2014 use exact name\n return `\"${path}\"`;\n }\n\n /** Format date for Gmail query (YYYY/MM/DD) */\n private formatDate(d: Date): string {\n return `${d.getFullYear()}/${String(d.getMonth() + 1).padStart(2, \"0\")}/${String(d.getDate()).padStart(2, \"0\")}`;\n }\n}\n", "/**\n * BridgeTcpTransport \u2014 TcpTransport implementation backed by msgapi.tcp.\n *\n * Works in any msger-family WebView host (msger / msga / msgview / MAUI shell)\n * that exposes msgapi.tcp. TLS handshake happens natively in the host; JS only\n * sees decoded bytes.\n */\n\nimport type { TcpTransport } from \"./transport.js\";\n\ndeclare const msgapi: {\n tcp: {\n connect(host: string, port: number, tls: boolean): Promise<number>;\n write(streamId: number, data: string): Promise<void>;\n onData(streamId: number, callback: (data: string) => void): void;\n onClose(streamId: number, callback: (hadError: boolean) => void): void;\n onError(streamId: number, callback: (message: string) => void): void;\n upgradeTLS(streamId: number, servername: string): Promise<void>;\n close(streamId: number): void;\n };\n};\n\nexport class BridgeTcpTransport implements TcpTransport {\n private streamId: number | null = null;\n private dataHandler: ((data: Uint8Array) => void) | null = null;\n private closeHandler: ((hadError: boolean) => void) | null = null;\n private errorHandler: ((err: Error) => void) | null = null;\n private _connected = false;\n private encoder = new TextEncoder();\n\n get connected(): boolean { return this._connected; }\n\n async connect(host: string, port: number, tls: boolean, _servername?: string): Promise<void> {\n this.streamId = await msgapi.tcp.connect(host, port, tls);\n this._connected = true;\n\n msgapi.tcp.onData(this.streamId, (data: string) => {\n // The msger bridge currently delivers strings (the WebView IPC\n // contract is JSON-text). Encode once per chunk to honor the\n // byte-stream contract upstream consumers expect. Real fix is to\n // change msgapi.tcp.onData to deliver bytes (via base64 or\n // binary-framed IPC) \u2014 that's an msger Rust + JS bridge change,\n // tracked separately. For now the encode is bounded per-chunk,\n // not per-buffer-accumulation, so it doesn't repeat the O(n\u00B2)\n // pathology that was in iflow-direct.\n if (this.dataHandler) this.dataHandler(this.encoder.encode(data));\n });\n msgapi.tcp.onClose(this.streamId, (hadError: boolean) => {\n this._connected = false;\n if (this.closeHandler) this.closeHandler(hadError);\n });\n msgapi.tcp.onError(this.streamId, (message: string) => {\n if (this.errorHandler) this.errorHandler(new Error(message));\n });\n }\n\n async upgradeTLS(servername?: string): Promise<void> {\n if (this.streamId == null) throw new Error(\"Not connected\");\n await msgapi.tcp.upgradeTLS(this.streamId, servername || \"\");\n }\n\n async write(data: string | Uint8Array): Promise<void> {\n if (this.streamId == null) throw new Error(\"Not connected\");\n const s = typeof data === \"string\" ? data : new TextDecoder().decode(data);\n await msgapi.tcp.write(this.streamId, s);\n }\n\n onData(handler: (data: Uint8Array) => void): void { this.dataHandler = handler; }\n onClose(handler: (hadError: boolean) => void): void { this.closeHandler = handler; }\n onError(handler: (err: Error) => void): void { this.errorHandler = handler; }\n\n close(): void {\n if (this.streamId != null) {\n try { msgapi.tcp.close(this.streamId); } catch { /* ignore */ }\n this.streamId = null;\n this._connected = false;\n }\n }\n}\n", "/**\n * IMAP protocol parser and command builder.\n * Pure string logic \u2014 no I/O, no Node.js dependencies.\n * Works in browser, Node.js, or worker thread.\n */\n\n/** Parsed IMAP response line */\nexport interface ImapResponse {\n /** Tag (\"*\" for untagged, \"+\" for continuation, or the command tag) */\n tag: string;\n /** Status (OK, NO, BAD, BYE, PREAUTH) or response type (EXISTS, RECENT, FETCH, etc.) */\n type: string;\n /** The full text after the tag and type */\n text: string;\n /** Raw line */\n raw: string;\n /** Literal data keyed by BODY section name (e.g. \"BODY[]\", \"BODY[HEADER]\") */\n literals?: Map<string, string>;\n}\n\n/** Parsed FETCH response data */\nexport interface FetchData {\n seq: number;\n uid?: number;\n flags?: Set<string>;\n internalDate?: Date;\n size?: number;\n envelope?: EnvelopeData;\n bodyStructure?: any;\n headers?: string;\n source?: string;\n}\n\n/** Parsed ENVELOPE data */\nexport interface EnvelopeData {\n date: Date | null;\n subject: string;\n from: AddressData[];\n sender: AddressData[];\n replyTo: AddressData[];\n to: AddressData[];\n cc: AddressData[];\n bcc: AddressData[];\n inReplyTo: string;\n messageId: string;\n}\n\nexport interface AddressData {\n name: string;\n address: string;\n}\n\n/** Parsed folder LIST data */\nexport interface ListData {\n flags: string[];\n delimiter: string;\n path: string;\n}\n\n/** Parsed STATUS data */\nexport interface StatusData {\n messages?: number;\n recent?: number;\n uidNext?: number;\n uidValidity?: number;\n unseen?: number;\n}\n\n// \u2500\u2500 Command Builder \u2500\u2500\n\nlet tagCounter = 0;\n\n/** Generate a unique command tag */\nexport function nextTag(): string {\n return `A${++tagCounter}`;\n}\n\n/** Reset tag counter (for testing) */\nexport function resetTags(): void {\n tagCounter = 0;\n}\n\n/** Build an IMAP command string (tag + command + CRLF) */\nexport function buildCommand(tag: string, command: string): string {\n return `${tag} ${command}\\r\\n`;\n}\n\n/** Build LOGIN command */\nexport function loginCommand(tag: string, user: string, pass: string): string {\n // Quote user and password to handle special characters\n return buildCommand(tag, `LOGIN ${quoteString(user)} ${quoteString(pass)}`);\n}\n\n/** Build AUTHENTICATE XOAUTH2 command */\nexport function xoauth2Command(tag: string, user: string, token: string): string {\n const authStr = `user=${user}\\x01auth=Bearer ${token}\\x01\\x01`;\n const b64 = btoa(authStr);\n return buildCommand(tag, `AUTHENTICATE XOAUTH2 ${b64}`);\n}\n\n/** Build LIST command */\nexport function listCommand(tag: string, ref = '\"\"', pattern = '\"*\"'): string {\n return buildCommand(tag, `LIST ${ref} ${pattern}`);\n}\n\n/** Build SELECT command. Optional `qresync` triggers RFC 7162 fast resync:\n * the server emits `* VANISHED (EARLIER) <uid-set>` for every UID expunged\n * since `modSeq` and `* FETCH` for every state change since then, in lieu\n * of the caller having to diff UID sets. Capability-gated by caller;\n * requires `ENABLE QRESYNC` already issued on the session. */\nexport function selectCommand(\n tag: string,\n mailbox: string,\n qresync?: { uidValidity: number; modSeq: number; knownUids?: string },\n): string {\n if (!qresync) return buildCommand(tag, `SELECT ${quoteMailbox(mailbox)}`);\n let params = `${qresync.uidValidity} ${qresync.modSeq}`;\n if (qresync.knownUids) params += ` ${qresync.knownUids}`;\n return buildCommand(tag, `SELECT ${quoteMailbox(mailbox)} (QRESYNC (${params}))`);\n}\n\n/** Build ENABLE command per RFC 5161. Common extensions to enable: QRESYNC,\n * CONDSTORE, UTF8=ACCEPT. Must be issued before any SELECT for the\n * extension to take effect on the session. */\nexport function enableCommand(tag: string, extensions: string[]): string {\n return buildCommand(tag, `ENABLE ${extensions.join(\" \")}`);\n}\n\n/** Expand an RFC 3501 UID set (e.g. `\"1:5,8,12,20:*\"`) into a flat number\n * list. Does NOT resolve `*` \u2014 caller passes a known upper bound only\n * when it has one; here `*` is treated as a sentinel and skipped so the\n * call site can decide what to do (typically: ignore \u2014 VANISHED never\n * emits `*` because that would be open-ended). */\nexport function parseUidSet(set: string): number[] {\n const out: number[] = [];\n for (const part of set.split(\",\")) {\n const trimmed = part.trim();\n if (!trimmed) continue;\n const range = trimmed.split(\":\");\n if (range.length === 1) {\n const n = parseInt(range[0], 10);\n if (Number.isFinite(n)) out.push(n);\n } else if (range.length === 2) {\n const lo = parseInt(range[0], 10);\n const hi = range[1] === \"*\" ? lo : parseInt(range[1], 10);\n if (!Number.isFinite(lo) || !Number.isFinite(hi) || hi < lo) continue;\n for (let u = lo; u <= hi; u++) out.push(u);\n }\n }\n return out;\n}\n\n/** Build EXAMINE command (read-only SELECT) */\nexport function examineCommand(tag: string, mailbox: string): string {\n return buildCommand(tag, `EXAMINE ${quoteMailbox(mailbox)}`);\n}\n\n/** Build STATUS command */\nexport function statusCommand(tag: string, mailbox: string, items: string[] = [\"MESSAGES\", \"UIDNEXT\"]): string {\n return buildCommand(tag, `STATUS ${quoteMailbox(mailbox)} (${items.join(\" \")})`);\n}\n\n/** Build UID FETCH command */\nexport function fetchCommand(tag: string, range: string, items: string[]): string {\n return buildCommand(tag, `UID FETCH ${range} (${items.join(\" \")})`);\n}\n\n/** Build sequence-number FETCH command (no UID prefix). Used by fetchLatestN\n * to avoid SEARCH SINCE on a cold mailbox \u2014 sequence ranges are O(1) on the\n * server because they're just message numbers in the current mailbox. */\nexport function seqFetchCommand(tag: string, range: string, items: string[]): string {\n return buildCommand(tag, `FETCH ${range} (${items.join(\" \")})`);\n}\n\n/** Build UID SEARCH command */\nexport function searchCommand(tag: string, criteria: string): string {\n return buildCommand(tag, `UID SEARCH ${criteria}`);\n}\n\n/** Build UID STORE command (set/add/remove flags) */\nexport function storeCommand(tag: string, uid: number, action: string, flags: string[]): string {\n return buildCommand(tag, `UID STORE ${uid} ${action} (${flags.join(\" \")})`);\n}\n\n/** Build UID COPY command */\nexport function copyCommand(tag: string, uid: number, destination: string): string {\n return buildCommand(tag, `UID COPY ${uid} ${quoteMailbox(destination)}`);\n}\n\n/** Build UID MOVE command */\nexport function moveCommand(tag: string, uid: number, destination: string): string {\n return buildCommand(tag, `UID MOVE ${uid} ${quoteMailbox(destination)}`);\n}\n\n/** Build APPEND command header (body follows as literal) */\nexport function appendCommand(tag: string, mailbox: string, flags: string[], size: number): string {\n const flagStr = flags.length > 0 ? ` (${flags.join(\" \")})` : \"\";\n return buildCommand(tag, `APPEND ${quoteMailbox(mailbox)}${flagStr} {${size}}`);\n}\n\n/** Build IDLE command */\nexport function idleCommand(tag: string): string {\n return buildCommand(tag, \"IDLE\");\n}\n\n/** Build NOTIFY SET command (RFC 5465). `spec` is the full event group list,\n * e.g. \"(SELECTED (MessageNew MessageExpunge FlagChange)) (PERSONAL\n * (MessageNew MessageExpunge FlagChange MailboxName))\" \u2014 the server then\n * pushes unsolicited STATUS responses for non-selected mailboxes in the\n * spec while the connection is idle. Capability gated: only issue when\n * CAPABILITY response contains NOTIFY. */\nexport function notifyCommand(tag: string, spec: string): string {\n return buildCommand(tag, `NOTIFY SET ${spec}`);\n}\n\n/** Build DONE command (ends IDLE) */\nexport function doneCommand(): string {\n return \"DONE\\r\\n\";\n}\n\n/** Build STARTTLS command */\nexport function starttlsCommand(tag: string): string {\n return buildCommand(tag, \"STARTTLS\");\n}\n\n/** Build LOGOUT command */\nexport function logoutCommand(tag: string): string {\n return buildCommand(tag, \"LOGOUT\");\n}\n\n/** Build CAPABILITY command */\nexport function capabilityCommand(tag: string): string {\n return buildCommand(tag, \"CAPABILITY\");\n}\n\n/** Build NOOP command */\nexport function noopCommand(tag: string): string {\n return buildCommand(tag, \"NOOP\");\n}\n\n/** Build CREATE command */\nexport function createCommand(tag: string, mailbox: string): string {\n return buildCommand(tag, `CREATE ${quoteMailbox(mailbox)}`);\n}\n\n/** Build DELETE command */\nexport function deleteMailboxCommand(tag: string, mailbox: string): string {\n return buildCommand(tag, `DELETE ${quoteMailbox(mailbox)}`);\n}\n\n/** Build RENAME command */\nexport function renameCommand(tag: string, from: string, to: string): string {\n return buildCommand(tag, `RENAME ${quoteMailbox(from)} ${quoteMailbox(to)}`);\n}\n\n// \u2500\u2500 Response Parser \u2500\u2500\n\n/** Parse a single IMAP response line */\nexport function parseResponseLine(line: string): ImapResponse {\n const trimmed = line.replace(/\\r?\\n$/, \"\");\n\n // Continuation response\n if (trimmed.startsWith(\"+ \") || trimmed === \"+\") {\n return { tag: \"+\", type: \"CONTINUE\", text: trimmed.substring(2), raw: trimmed };\n }\n\n // Untagged response\n if (trimmed.startsWith(\"* \")) {\n const rest = trimmed.substring(2);\n // Check for numeric response (e.g., \"* 5 EXISTS\", \"* 131441 FETCH (...)\")\n const numMatch = rest.match(/^(\\d+)\\s+(\\S+)/);\n if (numMatch) {\n return { tag: \"*\", type: numMatch[2].toUpperCase(), text: rest, raw: trimmed };\n }\n // Status/capability/list response\n const spaceIdx = rest.indexOf(\" \");\n if (spaceIdx > 0) {\n return { tag: \"*\", type: rest.substring(0, spaceIdx).toUpperCase(), text: rest.substring(spaceIdx + 1), raw: trimmed };\n }\n return { tag: \"*\", type: rest.toUpperCase(), text: \"\", raw: trimmed };\n }\n\n // Tagged response (e.g., \"A1 OK Login completed\")\n const spaceIdx = trimmed.indexOf(\" \");\n if (spaceIdx > 0) {\n const tag = trimmed.substring(0, spaceIdx);\n const rest = trimmed.substring(spaceIdx + 1);\n const spaceIdx2 = rest.indexOf(\" \");\n if (spaceIdx2 > 0) {\n return { tag, type: rest.substring(0, spaceIdx2).toUpperCase(), text: rest.substring(spaceIdx2 + 1), raw: trimmed };\n }\n return { tag, type: rest.toUpperCase(), text: \"\", raw: trimmed };\n }\n\n return { tag: \"\", type: \"UNKNOWN\", text: trimmed, raw: trimmed };\n}\n\n/** Parse a LIST response line: * LIST (\\flags) \"delimiter\" \"path\" */\nexport function parseListResponse(text: string): ListData | null {\n // Match: (flags) \"delimiter\" \"path\" or (flags) \"delimiter\" path\n // The \"LIST\" prefix may or may not be present (parseResponseLine may strip it into r.type)\n const match = text.match(/^(?:LIST\\s+)?\\(([^)]*)\\)\\s+\"([^\"]*)\"\\s+(?:\"([^\"]+)\"|(\\S+))/i);\n if (!match) return null;\n const flags = match[1] ? match[1].split(/\\s+/).filter(Boolean) : [];\n const delimiter = match[2] || \".\";\n const path = (match[3] || match[4] || \"\").replace(/\\r?\\n$/, \"\");\n return { flags, delimiter, path };\n}\n\n/** Parse STATUS response: * STATUS \"mailbox\" (MESSAGES n UIDNEXT n ...) */\nexport function parseStatusResponse(text: string): StatusData | null {\n const match = text.match(/\\(([^)]+)\\)/);\n if (!match) return null;\n const pairs = match[1].split(/\\s+/);\n const data: StatusData = {};\n for (let i = 0; i < pairs.length - 1; i += 2) {\n const key = pairs[i].toUpperCase();\n const val = parseInt(pairs[i + 1]);\n if (key === \"MESSAGES\") data.messages = val;\n else if (key === \"RECENT\") data.recent = val;\n else if (key === \"UIDNEXT\") data.uidNext = val;\n else if (key === \"UIDVALIDITY\") data.uidValidity = val;\n else if (key === \"UNSEEN\") data.unseen = val;\n }\n return data;\n}\n\n/** Parse a STATUS response keeping the mailbox name. Used by NOTIFY's\n * unsolicited STATUS pushes where the mailbox identifies which folder\n * changed \u2014 `parseStatusResponse` discards that. Mailbox may be quoted\n * (\"Sent\") or atom-shaped (Sent); the regex handles both. */\nexport function parseStatusResponseFull(text: string): { mailbox: string; data: StatusData } | null {\n // Match: \"quoted name\" (data) OR atomname (data)\n const m = text.match(/^\"((?:[^\"\\\\]|\\\\.)*)\"\\s*\\((.*)\\)\\s*$/) || text.match(/^(\\S+)\\s*\\((.*)\\)\\s*$/);\n if (!m) return null;\n const mailbox = m[1].replace(/\\\\(.)/g, \"$1\");\n const data: StatusData = {};\n const pairs = m[2].split(/\\s+/);\n for (let i = 0; i < pairs.length - 1; i += 2) {\n const key = pairs[i].toUpperCase();\n const val = parseInt(pairs[i + 1]);\n if (key === \"MESSAGES\") data.messages = val;\n else if (key === \"RECENT\") data.recent = val;\n else if (key === \"UIDNEXT\") data.uidNext = val;\n else if (key === \"UIDVALIDITY\") data.uidValidity = val;\n else if (key === \"UNSEEN\") data.unseen = val;\n }\n return { mailbox, data };\n}\n\n/** Parse UID SEARCH response: * SEARCH 1 2 3 4 5 */\nexport function parseSearchResponse(text: string): number[] {\n if (!text.trim()) return [];\n return text.trim().split(/\\s+/).map(Number).filter(n => !isNaN(n));\n}\n\n/** Parse FLAGS from a FETCH or SELECT response */\nexport function parseFlags(flagStr: string): Set<string> {\n const match = flagStr.match(/\\(([^)]*)\\)/);\n if (!match) return new Set();\n return new Set(match[1].split(/\\s+/).filter(Boolean));\n}\n\n/** Parse ENVELOPE from FETCH \u2014 simplified parser for the common fields */\nexport function parseEnvelope(envStr: string): EnvelopeData {\n // ENVELOPE is a parenthesized list \u2014 this is a simplified parser\n // Full RFC 3501 envelope: (date subject from sender reply-to to cc bcc in-reply-to message-id)\n const result: EnvelopeData = {\n date: null, subject: \"\", from: [], sender: [], replyTo: [],\n to: [], cc: [], bcc: [], inReplyTo: \"\", messageId: \"\"\n };\n\n try {\n const tokens = tokenizeParenList(envStr);\n if (tokens.length >= 10) {\n result.date = tokens[0] !== \"NIL\" ? new Date(unquote(tokens[0])) : null;\n result.subject = decodeImapString(unquote(tokens[1]));\n result.from = parseAddressList(tokens[2]);\n result.sender = parseAddressList(tokens[3]);\n result.replyTo = parseAddressList(tokens[4]);\n result.to = parseAddressList(tokens[5]);\n result.cc = parseAddressList(tokens[6]);\n result.bcc = parseAddressList(tokens[7]);\n result.inReplyTo = unquote(tokens[8]);\n result.messageId = unquote(tokens[9]);\n }\n } catch {\n // Parsing envelope is best-effort \u2014 incomplete data is acceptable\n }\n return result;\n}\n\n// \u2500\u2500 IMAP String Utilities \u2500\u2500\n\n/** Quote a string for IMAP (handles special characters) */\nfunction quoteString(s: string): string {\n if (/[\\x00-\\x1f\\x7f\"\\\\]/.test(s)) {\n // Use literal for problematic characters\n return `{${new TextEncoder().encode(s).length}}\\r\\n${s}`;\n }\n return `\"${s}\"`;\n}\n\n/** Quote a mailbox name */\nfunction quoteMailbox(name: string): string {\n if (name === \"INBOX\") return name;\n if (/[\\s\"\\\\*%{]/.test(name)) return `\"${name.replace(/[\"\\\\]/g, \"\\\\$&\")}\"`;\n return name;\n}\n\n/** Remove quotes from an IMAP string */\nfunction unquote(s: string): string {\n if (!s || s === \"NIL\") return \"\";\n if (s.startsWith('\"') && s.endsWith('\"')) return s.slice(1, -1).replace(/\\\\(.)/g, \"$1\");\n return s;\n}\n\n/** Decode IMAP encoded-word (=?charset?encoding?text?=) */\nfunction decodeImapString(s: string): string {\n if (!s) return \"\";\n // RFC 2047 \u00A76.2: whitespace between adjacent encoded-words must be ignored\n const unfolded = s.replace(/\\?=\\s+=\\?/g, \"?==?\");\n return unfolded.replace(/=\\?([^?]+)\\?([BQ])\\?([^?]+)\\?=/gi, (_match, charset, encoding, text) => {\n try {\n const cs = charset.toLowerCase().replace(/^utf8$/, \"utf-8\");\n if (encoding.toUpperCase() === \"B\") {\n const raw = atob(text);\n const bytes = new Uint8Array(raw.length);\n for (let j = 0; j < raw.length; j++) bytes[j] = raw.charCodeAt(j);\n return new TextDecoder(cs).decode(bytes);\n } else {\n // Quoted-printable: collect bytes then decode with charset\n const decoded = text.replace(/_/g, \" \");\n const bytes: number[] = [];\n let i = 0;\n while (i < decoded.length) {\n if (decoded[i] === \"=\" && i + 2 < decoded.length) {\n bytes.push(parseInt(decoded.substring(i + 1, i + 3), 16));\n i += 3;\n } else {\n bytes.push(decoded.charCodeAt(i));\n i++;\n }\n }\n return new TextDecoder(cs).decode(new Uint8Array(bytes));\n }\n } catch {\n return text;\n }\n });\n}\n\n/** Tokenize a parenthesized IMAP list (top-level only) */\nfunction tokenizeParenList(s: string): string[] {\n const tokens: string[] = [];\n let i = 0;\n const str = s.trim();\n // Skip outer parens\n const start = str.startsWith(\"(\") ? 1 : 0;\n const end = str.endsWith(\")\") ? str.length - 1 : str.length;\n\n i = start;\n while (i < end) {\n // Skip whitespace\n while (i < end && str[i] === \" \") i++;\n if (i >= end) break;\n\n if (str[i] === \"(\") {\n // Nested paren group \u2014 find matching close\n let depth = 1;\n let j = i + 1;\n while (j < end && depth > 0) {\n if (str[j] === \"(\") depth++;\n else if (str[j] === \")\") depth--;\n j++;\n }\n tokens.push(str.substring(i, j));\n i = j;\n } else if (str[i] === '\"') {\n // Quoted string\n let j = i + 1;\n while (j < end) {\n if (str[j] === \"\\\\\" && j + 1 < end) { j += 2; continue; }\n if (str[j] === '\"') { j++; break; }\n j++;\n }\n tokens.push(str.substring(i, j));\n i = j;\n } else if (str.substring(i, i + 3).toUpperCase() === \"NIL\") {\n tokens.push(\"NIL\");\n i += 3;\n } else {\n // Atom\n let j = i;\n while (j < end && str[j] !== \" \" && str[j] !== \")\" && str[j] !== \"(\") j++;\n if (j === i) {\n // str[i] is a stray ')' (or '(') that none of the branches\n // above consumed \u2014 an unbalanced/malformed parenthesised\n // list (Dovecot mis-parses some Outlook `From:` headers and\n // emits exactly this). Without advancing, `i` is stuck and\n // the while-loop spins FOREVER, pinning a CPU core and\n // wedging the whole daemon event loop. Skip the stray char.\n i++;\n continue;\n }\n tokens.push(str.substring(i, j));\n i = j;\n }\n }\n return tokens;\n}\n\n/** Parse an IMAP address list: ((name NIL mailbox host) ...) */\nfunction parseAddressList(token: string): AddressData[] {\n if (!token || token === \"NIL\") return [];\n const addrs: AddressData[] = [];\n // Tokenize the outer list to get each address group as a paren-delimited token\n // e.g. ((name NIL mailbox host)(name2 NIL mailbox2 host2)) \u2192 [\"(name NIL mailbox host)\", \"(name2 ...)\"]\n const groups = tokenizeParenList(token);\n for (const group of groups) {\n if (!group.startsWith(\"(\")) continue;\n const parts = tokenizeParenList(group);\n if (parts.length >= 4) {\n const name = decodeImapString(unquote(parts[0]));\n let mailbox = unquote(parts[2]);\n let host = unquote(parts[3]);\n // Dovecot stamps \"MISSING_MAILBOX\" / \"MISSING_DOMAIN\" into the\n // ENVELOPE tuple when the source From: header didn't parse cleanly\n // (RFC 3501 forbids NIL in those slots when any address part is\n // present). Strip the sentinels so we don't render\n // \"user@iecc.com@MISSING_DOMAIN\" \u2014 observed in the wild from\n // Outlook's malformed `From: \"name\" <\"local@domain\">` over-quoting.\n if (host === \"MISSING_DOMAIN\") host = \"\";\n if (mailbox === \"MISSING_MAILBOX\") mailbox = \"\";\n // Recover from Outlook's quoted-string pathology: when the local\n // part itself contains an \"@\" the entire mailbox value is already\n // a full address, so don't append @host again. Same hand applies\n // to any server that mis-parses an over-quoted From header.\n const address = mailbox.includes(\"@\")\n ? mailbox\n : (mailbox && host ? `${mailbox}@${host}` : mailbox || \"\");\n addrs.push({ name, address });\n }\n }\n return addrs;\n}\n\n/** Build SEARCH criteria string from common search parameters */\nexport function buildSearchCriteria(criteria: {\n since?: Date;\n before?: Date;\n from?: string;\n to?: string;\n subject?: string;\n body?: string;\n uid?: string; // UID range like \"100:*\"\n all?: boolean;\n}): string {\n const parts: string[] = [];\n if (criteria.all) parts.push(\"ALL\");\n if (criteria.since) parts.push(`SINCE ${formatImapDate(criteria.since)}`);\n if (criteria.before) parts.push(`BEFORE ${formatImapDate(criteria.before)}`);\n if (criteria.from) parts.push(`FROM \"${criteria.from}\"`);\n if (criteria.to) parts.push(`TO \"${criteria.to}\"`);\n if (criteria.subject) parts.push(`SUBJECT \"${criteria.subject}\"`);\n if (criteria.body) parts.push(`BODY \"${criteria.body}\"`);\n if (criteria.uid) parts.push(`UID ${criteria.uid}`);\n return parts.length > 0 ? parts.join(\" \") : \"ALL\";\n}\n\n/** Format a date for IMAP (DD-Mon-YYYY) */\nfunction formatImapDate(d: Date): string {\n const months = [\"Jan\", \"Feb\", \"Mar\", \"Apr\", \"May\", \"Jun\", \"Jul\", \"Aug\", \"Sep\", \"Oct\", \"Nov\", \"Dec\"];\n return `${d.getDate()}-${months[d.getMonth()]}-${d.getFullYear()}`;\n}\n", "/**\n * Native IMAP client \u2014 transport-agnostic.\n * Uses ImapTransport for I/O, imap-protocol for parsing.\n * Works with NodeTransport (desktop) or BridgeTransport (Android).\n *\n * This is a NEW client alongside the existing ImapClient (which wraps imapflow).\n * Existing callers are not affected.\n */\n\nimport type { ImapTransport, TransportFactory } from \"./transport.js\";\nimport * as proto from \"./imap-protocol.js\";\nimport type { ImapClientConfig, TokenProvider } from \"./types.js\";\n\nexport interface NativeFetchedMessage {\n seq: number;\n uid: number;\n flags: Set<string>;\n date: Date | null;\n subject: string;\n messageId: string;\n from: proto.AddressData[];\n to: proto.AddressData[];\n cc: proto.AddressData[];\n bcc: proto.AddressData[];\n sender: proto.AddressData[];\n replyTo: proto.AddressData[];\n inReplyTo: string;\n size: number;\n source: string;\n headers: string;\n // Convenience flags\n seen: boolean;\n flagged: boolean;\n answered: boolean;\n draft: boolean;\n /** Per-message modification sequence (RFC 7162). Present when the\n * server is CONDSTORE/QRESYNC-capable and the client either has\n * ENABLE QRESYNC active or asked for MODSEQ explicitly. Used by the\n * caller to track its own `last_modseq` watermark per folder. */\n modSeq?: number;\n}\n\nexport interface NativeFolder {\n path: string;\n delimiter: string;\n flags: string[];\n}\n\nexport interface MailboxInfo {\n exists: number;\n recent: number;\n uidNext: number;\n uidValidity: number;\n flags: string[];\n permanentFlags: string[];\n /** Per RFC 7162. Present when the server is CONDSTORE/QRESYNC-capable\n * and includes [HIGHESTMODSEQ N] in the SELECT-OK response (or after\n * ENABLE QRESYNC). Use as the `since-modseq` argument to subsequent\n * resyncs to ask the server \"what changed since this point?\" */\n highestModSeq?: number;\n}\n\n/** Parameters for `SELECT mailbox (QRESYNC (uidvalidity modseq))` per RFC 7162.\n * Caller persists `(uidValidity, modSeq)` per folder; after ENABLE QRESYNC\n * has been issued once on the session, the next SELECT replies with\n * `* VANISHED (EARLIER) <uids>` for every message the server expunged since\n * `modSeq`, plus `* FETCH` for every message whose state changed since then.\n * No client-side UID diffing, no tombstones \u2014 the server tells you the\n * authoritative deletions. */\nexport interface QresyncParams {\n uidValidity: number;\n modSeq: number;\n knownUids?: string; // optional UID range hint, e.g. \"1:100\"\n}\n\n/** Result of a QRESYNC-enabled SELECT. The caller drains `vanishedUids`\n * (delete from local store), processes `changedMessages` (upsert state\n * changes), and saves the new `highestModSeq` for the next resync. */\nexport interface SelectResult extends MailboxInfo {\n vanishedUids: number[];\n /** Untagged `* FETCH` responses the server emitted during the QRESYNC\n * SELECT \u2014 typically flag/MODSEQ changes for messages whose state\n * shifted between the caller's previous modSeq and now. Empty for\n * non-QRESYNC SELECTs. */\n changedMessages: NativeFetchedMessage[];\n /** True if the server's UIDVALIDITY changed since the caller's last\n * visit \u2014 in that case knownUids/modSeq are invalid and the caller\n * must full-resync from scratch. */\n uidValidityChanged: boolean;\n}\n\nexport class NativeImapClient {\n private transport: ImapTransport;\n private transportFactory: TransportFactory;\n private config: ImapClientConfig;\n /** Byte-level receive buffer. IMAP literals (`{N}`) are octets \u2014 message\n * bodies, MIME parts with binary content, non-UTF-8 charsets \u2014 and the\n * parser MUST work in bytes to recover them with byte fidelity and\n * without paying O(n\u00B2) re-encoding cost on every chunk arrival. The\n * prior implementation kept `this.buffer` as a JS string, accumulated\n * UTF-8-decoded text from the transport, then `TextEncoder.encode`'d\n * the whole unread region on every TCP chunk while waiting for a\n * literal \u2014 pegged the event loop on multi-message FETCH responses.\n *\n * Invariants:\n * - `buffer[0 .. bufferLength)` holds valid received bytes\n * - `buffer[bufferOffset .. bufferLength)` is unread\n * - capacity = `buffer.length` \u2265 `bufferLength`; we grow on demand\n * - never substring \u2014 bufferOffset advances past consumed bytes;\n * compactBufferIfNeeded reclaims space when consumed >= half. */\n private buffer: Uint8Array = new Uint8Array(8192);\n private bufferLength = 0;\n private bufferOffset = 0;\n /** Cached decoder so per-line / per-literal decode doesn't re-construct\n * one. `fatal: false` (default) replaces invalid UTF-8 sequences with\n * U+FFFD \u2014 same lenient behavior as JavaScript's implicit string\n * decoding the parser used to rely on. */\n private utf8Decoder = new TextDecoder(\"utf-8\");\n private pendingCommand: {\n tag: string;\n resolve: (responses: proto.ImapResponse[]) => void;\n reject: (err: Error) => void;\n responses: proto.ImapResponse[];\n literalBytes?: number;\n literalBuffer?: string;\n /** Track literal key (e.g. \"BODY[]\") and size for the current literal being read */\n currentLiteralKey?: string;\n currentLiteralSize?: number;\n /** Accumulated literals keyed by section name */\n literals?: Map<string, string>;\n /** Called for each untagged response as it arrives (e.g. per-message FETCH streaming) */\n onUntagged?: (resp: proto.ImapResponse) => void;\n } | null = null;\n private capabilities = new Set<string>();\n private _connected = false;\n private idleTag: string | null = null;\n private idleCallback: ((count: number) => void) | null = null;\n /** Fires when the SELECTED mailbox loses messages while parked in IDLE \u2014\n * an EXISTS decrease, or an unsolicited `* EXPUNGE` / `* VANISHED`\n * (RFC 5465 NOTIFY SELECTED MessageExpunge). Lets the caller reconcile\n * a server-side deletion in real time instead of waiting for the next\n * periodic poll. Distinct from `idleCallback` (new mail only). */\n private idleExpungeCallback: (() => void) | null = null;\n private idleRefreshTimer: ReturnType<typeof setTimeout> | null = null;\n /** RFC 5465 NOTIFY: fires on unsolicited STATUS responses for non-selected\n * mailboxes (the server pushes these when the client has issued NOTIFY\n * SET with a PERSONAL group). Distinct from `idleCallback` which only\n * fires for EXISTS on the currently-selected mailbox. */\n public onMailboxStatus: ((mailbox: string, data: proto.StatusData) => void) | null = null;\n /** Set by startIdle's stop closure so auto-suspend knows not to resume after a command finishes. */\n private idleStopped = true;\n private verbose: boolean;\n private selectedMailbox: string | null = null;\n private mailboxInfo: MailboxInfo = { exists: 0, recent: 0, uidNext: 0, uidValidity: 0, flags: [], permanentFlags: [] };\n private greetingResolve: ((resp: proto.ImapResponse) => void) | null = null;\n /** Callback for waitForContinuation \u2014 set when waiting for \"+\" response */\n private continuationResolve: ((resp: proto.ImapResponse) => void) | null = null;\n /** Per-command heartbeat (30s). Hoisted to instance state so any path\n * that swaps pendingCommand can clear it cleanly \u2014 closure-scoped\n * timers leaked when handleData's inline replacement or IDLE\n * suspend/resume bypassed sendCommandCore's resolve/reject closures. */\n private heartbeatTimer: ReturnType<typeof setInterval> | null = null;\n /** Hard wall-clock cap per command. Same hoist for the same reason. */\n private wallClockTimer: ReturnType<typeof setTimeout> | null = null;\n\n constructor(config: ImapClientConfig, transportFactory: TransportFactory) {\n this.config = config;\n this.transportFactory = transportFactory;\n this.transport = transportFactory();\n this.verbose = config.verbose || false;\n this.inactivityTimeout = config.inactivityTimeout ?? 60000;\n // Hard wall-clock deadline per command. Distinct from inactivityTimeout\n // \u2014 that one resets on each data chunk and can be deferred indefinitely\n // by a slow-trickling server. Default 90s: in production we see\n // connections silently die with sinceLastRead climbing for 50s+ on\n // FETCH; 5 min was leaving them wedged for too long, blocking sync /\n // prefetch / new-mail behind a dead socket. 90s lets a slow but\n // genuine FETCH complete (Sent in isolation: 26ms; even a 50-message\n // FETCH was <1s) while killing dead sockets aggressively. Override\n // via ImapClientConfig.commandWallClockTimeout for known-slow servers.\n this.commandWallClockTimeout = config.commandWallClockTimeout ?? 90_000;\n this.fetchChunkSize = config.fetchChunkSize ?? 25;\n this.fetchChunkSizeMax = config.fetchChunkSizeMax ?? 500;\n this.greetingTimeout = config.greetingTimeout ?? 10000;\n }\n\n get connected(): boolean { return this._connected; }\n\n /** Check the underlying transport's connected state \u2014 catches silently dead sockets. */\n get transportConnected(): boolean { return this.transport?.connected ?? false; }\n\n /** Replace the transport with a fresh one from the factory. Call before reconnect\n * when the old transport is in a bad state (dead socket, stale bridge stream). */\n resetTransport(): void {\n try { this.transport?.close?.(); } catch { /* ignore */ }\n this.transport = this.transportFactory();\n this._connected = false;\n this.bufferLength = 0;\n this.bufferOffset = 0;\n this.pendingCommand = null;\n this.selectedMailbox = null;\n // Old socket is gone \u2014 kill any timers still running for the\n // command that was on it. Without this, a stale heartbeat/wall-clock\n // continues firing into a transport that no longer exists.\n this.clearAllCommandTimers();\n }\n\n // \u2500\u2500 Connection \u2500\u2500\n\n async connect(): Promise<void> {\n const useTls = this.config.port === 993;\n\n this.transport.onData((data) => this.handleData(data));\n this.transport.onClose(() => {\n this._connected = false;\n // Drop stale IDLE state \u2014 the socket is gone.\n this.idleTag = null;\n this.idleCallback = null;\n this.idleStopped = true;\n if (this.idleRefreshTimer) { clearTimeout(this.idleRefreshTimer); this.idleRefreshTimer = null; }\n // Kill any per-command timers \u2014 the connection is gone, no\n // command on it can ever complete. Otherwise heartbeat keeps\n // firing for a connection that no longer exists.\n this.clearAllCommandTimers();\n if (this.pendingCommand) {\n const { reject } = this.pendingCommand;\n this.pendingCommand = null;\n reject(new Error(\"Connection closed\"));\n }\n });\n this.transport.onError((err) => {\n if (this.verbose) console.error(` [imap] Transport error: ${err.message}`);\n // Transport errors (DNS failure, ECONNRESET, TLS failure, etc.) mean\n // the connection is dead \u2014 clear the flag so ensureConnected() will\n // reconnect on the next call, and drop the stale IDLE state so we\n // don't try to DONE a dead socket during auto-suspend.\n this._connected = false;\n this.idleTag = null;\n this.idleCallback = null;\n this.idleStopped = true;\n if (this.idleRefreshTimer) { clearTimeout(this.idleRefreshTimer); this.idleRefreshTimer = null; }\n if (this.pendingCommand) {\n const { reject } = this.pendingCommand;\n this.pendingCommand = null;\n reject(err);\n }\n });\n\n await this.transport.connect(this.config.server, this.config.port, useTls, this.config.server);\n\n // Read server greeting\n const greeting = await this.readGreeting();\n if (this.verbose) console.log(` [imap] Greeting: ${greeting.raw}`);\n\n // Parse capabilities from greeting\n if (greeting.text.includes(\"CAPABILITY\")) {\n this.parseCapabilities(greeting.text);\n } else {\n await this.capability();\n }\n\n // STARTTLS if needed\n if (!useTls && this.capabilities.has(\"STARTTLS\")) {\n await this.starttls();\n }\n\n this._connected = true;\n\n // Authenticate\n await this.authenticate();\n }\n\n private async readGreeting(): Promise<proto.ImapResponse> {\n return new Promise((resolve, reject) => {\n const timeout = setTimeout(() => {\n this.greetingResolve = null;\n reject(new Error(`Greeting timeout (${this.greetingTimeout / 1000}s)`));\n }, this.greetingTimeout);\n this.greetingResolve = (resp) => {\n clearTimeout(timeout);\n resolve(resp);\n };\n });\n }\n\n private async authenticate(): Promise<void> {\n if (this.config.tokenProvider) {\n const token = await this.config.tokenProvider();\n const tag = proto.nextTag();\n const cmd = proto.xoauth2Command(tag, this.config.username, token);\n if (this.verbose) console.log(` [imap] > AUTHENTICATE XOAUTH2 ...`);\n const responses = await this.sendCommand(tag, cmd);\n const tagged = responses.find(r => r.tag === tag);\n if (!tagged || tagged.type !== \"OK\") {\n const errText = tagged?.text || responses.map(r => r.raw).join(\"; \");\n throw new Error(`Authentication failed: ${errText}`);\n }\n } else if (this.config.password) {\n const tag = proto.nextTag();\n const cmd = proto.loginCommand(tag, this.config.username, this.config.password);\n if (this.verbose) console.log(` [imap] > LOGIN ${this.config.username} ***`);\n const responses = await this.sendCommand(tag, cmd);\n const tagged = responses.find(r => r.tag === tag);\n if (!tagged || tagged.type !== \"OK\") {\n const errText = tagged?.text || responses.map(r => r.raw).join(\"; \");\n throw new Error(`Login failed: ${errText}`);\n }\n } else {\n throw new Error(\"No password or token provider configured\");\n }\n\n // Re-read capabilities after auth (they may change)\n await this.capability();\n }\n\n private async starttls(): Promise<void> {\n const tag = proto.nextTag();\n const responses = await this.sendCommand(tag, proto.starttlsCommand(tag));\n const tagged = responses.find(r => r.tag === tag);\n if (!tagged || tagged.type !== \"OK\") throw new Error(\"STARTTLS failed\");\n await this.transport.upgradeTLS(this.config.server);\n await this.capability();\n }\n\n async capability(): Promise<Set<string>> {\n const tag = proto.nextTag();\n const responses = await this.sendCommand(tag, proto.capabilityCommand(tag));\n for (const r of responses) {\n if (r.tag === \"*\" && r.type === \"CAPABILITY\") {\n this.parseCapabilities(r.text);\n }\n }\n return this.capabilities;\n }\n\n /** Return the cached CAPABILITY set parsed at connect/login time. Callers\n * use this to gate optional code paths (NOTIFY, QRESYNC, MOVE, etc.)\n * without re-issuing CAPABILITY. Returns a defensive copy so callers\n * can't mutate internal state. */\n getCapabilities(): Set<string> {\n return new Set(this.capabilities);\n }\n\n /** Snapshot of the currently-SELECTed mailbox's info. Lets the compat\n * client read `highestModSeq` etc. after any select-implying operation\n * (fetchMessagesSinceUid, etc.) without re-issuing SELECT. */\n getMailboxInfo(): { uidValidity: number; uidNext: number; exists: number; highestModSeq?: number } {\n return {\n uidValidity: this.mailboxInfo.uidValidity,\n uidNext: this.mailboxInfo.uidNext,\n exists: this.mailboxInfo.exists,\n highestModSeq: this.mailboxInfo.highestModSeq,\n };\n }\n\n private parseCapabilities(text: string): void {\n const caps = text.replace(/^CAPABILITY\\s*/i, \"\").split(/\\s+/);\n this.capabilities.clear();\n for (const c of caps) this.capabilities.add(c.toUpperCase());\n }\n\n async logout(): Promise<void> {\n // Force-close the transport immediately. The LOGOUT command is a courtesy \u2014\n // the server cleans up the session when the socket closes.\n // Sending LOGOUT and waiting caused hangs and connection leaks.\n this.pendingCommand = null;\n this.transport.close();\n this._connected = false;\n }\n\n // \u2500\u2500 Mailbox Operations \u2500\u2500\n\n /** SELECT a mailbox. Optional QRESYNC params trigger RFC 7162 fast resync \u2014\n * on a re-visit the server replies with `* VANISHED (EARLIER) <uids>` for\n * every UID expunged since the caller's last `modSeq`, plus `* FETCH`\n * for every state change since then. The caller must have called\n * `enable([\"QRESYNC\"])` once on the session for this to take effect.\n * Returns a `SelectResult` rather than a bare `MailboxInfo` so VANISHED\n * is delivered to the caller. The result is upcast-compatible with\n * `MailboxInfo` for code paths that don't care about VANISHED. */\n async select(mailbox: string, qresync?: QresyncParams): Promise<SelectResult> {\n const tag = proto.nextTag();\n const responses = await this.sendCommand(tag, proto.selectCommand(tag, mailbox, qresync));\n const tagged = responses.find(r => r.tag === tag);\n if (!tagged || tagged.type !== \"OK\") {\n throw new Error(`SELECT ${mailbox} failed: ${tagged?.text || \"unknown\"}`);\n }\n\n // Reset transient fields each SELECT so a stale value from a previous\n // mailbox doesn't leak into the new one.\n this.mailboxInfo.highestModSeq = undefined;\n const vanishedUids: number[] = [];\n const priorUidValidity = qresync?.uidValidity;\n // Untagged FETCH responses emitted during a QRESYNC SELECT carry\n // state-change deltas the server is volunteering up-front; parse\n // them through the same path as normal FETCH so the shape matches.\n const fetchResponses = responses.filter(r => r.tag === \"*\" && r.type === \"FETCH\");\n\n for (const r of responses) {\n if (r.tag !== \"*\") continue;\n if (r.type === \"EXISTS\") {\n this.mailboxInfo.exists = parseInt(r.text);\n } else if (r.type === \"RECENT\") {\n this.mailboxInfo.recent = parseInt(r.text);\n } else if (r.type === \"FLAGS\") {\n this.mailboxInfo.flags = [...proto.parseFlags(r.text)];\n } else if (r.type === \"OK\") {\n const uidNextMatch = r.text.match(/UIDNEXT\\s+(\\d+)/i);\n if (uidNextMatch) this.mailboxInfo.uidNext = parseInt(uidNextMatch[1]);\n const uidValMatch = r.text.match(/UIDVALIDITY\\s+(\\d+)/i);\n if (uidValMatch) this.mailboxInfo.uidValidity = parseInt(uidValMatch[1]);\n const permMatch = r.text.match(/PERMANENTFLAGS\\s+\\(([^)]*)\\)/i);\n if (permMatch) this.mailboxInfo.permanentFlags = permMatch[1].split(/\\s+/).filter(Boolean);\n const modSeqMatch = r.text.match(/HIGHESTMODSEQ\\s+(\\d+)/i);\n if (modSeqMatch) this.mailboxInfo.highestModSeq = parseInt(modSeqMatch[1]);\n } else if (r.type === \"VANISHED\") {\n // `* VANISHED (EARLIER) 1:5,8,12` or `* VANISHED 1:5,8,12` \u2014\n // strip the optional `(EARLIER)` modifier and expand the UID\n // set. EARLIER means \"deleted before your last sync\", which\n // is the QRESYNC case; without it, the message just vanished\n // mid-session (post-EXPUNGE on another client).\n const text = r.text.replace(/^\\(EARLIER\\)\\s*/i, \"\").trim();\n for (const uid of proto.parseUidSet(text)) vanishedUids.push(uid);\n }\n }\n this.selectedMailbox = mailbox;\n const uidValidityChanged = priorUidValidity !== undefined\n && this.mailboxInfo.uidValidity !== priorUidValidity;\n const changedMessages = fetchResponses.length > 0\n ? this.parseFetchResponses(fetchResponses)\n : [];\n return {\n ...this.mailboxInfo,\n vanishedUids,\n changedMessages,\n uidValidityChanged,\n };\n }\n\n /** RFC 5161 ENABLE. Activates an extension for the rest of the session.\n * QRESYNC requires this once before any SELECT for VANISHED responses\n * to be emitted. Capability-gate at the caller \u2014 emitting ENABLE for\n * an unadvertised extension is a no-op on compliant servers but spams\n * the response stream. */\n async enable(extensions: string[]): Promise<Set<string>> {\n const tag = proto.nextTag();\n const responses = await this.sendCommand(tag, proto.enableCommand(tag, extensions));\n const tagged = responses.find(r => r.tag === tag);\n if (!tagged || tagged.type !== \"OK\") {\n throw new Error(`ENABLE ${extensions.join(\" \")} failed: ${tagged?.text || \"unknown\"}`);\n }\n const enabled = new Set<string>();\n for (const r of responses) {\n if (r.tag === \"*\" && r.type === \"ENABLED\") {\n for (const ext of r.text.split(/\\s+/).filter(Boolean)) enabled.add(ext.toUpperCase());\n }\n }\n return enabled;\n }\n\n async examine(mailbox: string): Promise<MailboxInfo> {\n const tag = proto.nextTag();\n const responses = await this.sendCommand(tag, proto.examineCommand(tag, mailbox));\n const tagged = responses.find(r => r.tag === tag);\n if (!tagged || tagged.type !== \"OK\") {\n throw new Error(`EXAMINE ${mailbox} failed: ${tagged?.text || \"unknown\"}`);\n }\n for (const r of responses) {\n if (r.tag !== \"*\") continue;\n if (r.type === \"EXISTS\") this.mailboxInfo.exists = parseInt(r.text);\n else if (r.type === \"RECENT\") this.mailboxInfo.recent = parseInt(r.text);\n }\n this.selectedMailbox = mailbox;\n return { ...this.mailboxInfo };\n }\n\n /** Close the currently selected mailbox */\n async closeMailbox(): Promise<void> {\n if (!this.selectedMailbox) return;\n const tag = proto.nextTag();\n await this.sendCommand(tag, proto.buildCommand(tag, \"CLOSE\"));\n this.selectedMailbox = null;\n }\n\n // \u2500\u2500 Folder Operations \u2500\u2500\n\n async listFolders(): Promise<NativeFolder[]> {\n const tag = proto.nextTag();\n const responses = await this.sendCommand(tag, proto.listCommand(tag));\n const folders: NativeFolder[] = [];\n let unparsed = 0;\n const listResponses = responses.filter(r => r.tag === \"*\" && r.type === \"LIST\");\n if (listResponses.length === 0 && responses.length > 0) {\n console.error(` [imap] LIST returned ${responses.length} responses but none were LIST type. Types: ${responses.map(r => `${r.tag}:${r.type}`).join(\", \")}`);\n if (responses.length <= 5) {\n for (const r of responses) console.error(` [imap] raw: ${JSON.stringify(r.text.substring(0, 200))}`);\n }\n }\n for (const r of responses) {\n if (r.tag === \"*\" && r.type === \"LIST\") {\n const parsed = proto.parseListResponse(r.text);\n if (parsed) {\n folders.push(parsed);\n } else {\n unparsed++;\n if (unparsed <= 3) console.error(` [imap] Unparsed LIST response: ${JSON.stringify(r.text.substring(0, 200))}`);\n }\n }\n }\n if (unparsed > 0) console.error(` [imap] ${unparsed} LIST responses could not be parsed (${responses.length} total responses)`);\n return folders;\n }\n\n async getStatus(mailbox: string): Promise<proto.StatusData> {\n const tag = proto.nextTag();\n const responses = await this.sendCommand(tag, proto.statusCommand(tag, mailbox, [\"MESSAGES\", \"UIDNEXT\", \"UNSEEN\"]));\n for (const r of responses) {\n if (r.tag === \"*\" && r.type === \"STATUS\") {\n const data = proto.parseStatusResponse(r.text);\n if (data) return data;\n }\n }\n return {};\n }\n\n async createMailbox(mailbox: string): Promise<void> {\n const tag = proto.nextTag();\n const responses = await this.sendCommand(tag, proto.createCommand(tag, mailbox));\n const tagged = responses.find(r => r.tag === tag);\n if (!tagged || tagged.type !== \"OK\") throw new Error(`CREATE failed: ${tagged?.text || \"unknown\"}`);\n }\n\n async deleteMailbox(mailbox: string): Promise<void> {\n const tag = proto.nextTag();\n const responses = await this.sendCommand(tag, proto.deleteMailboxCommand(tag, mailbox));\n const tagged = responses.find(r => r.tag === tag);\n if (!tagged || tagged.type !== \"OK\") throw new Error(`DELETE failed: ${tagged?.text || \"unknown\"}`);\n }\n\n async renameMailbox(from: string, to: string): Promise<void> {\n const tag = proto.nextTag();\n const responses = await this.sendCommand(tag, proto.renameCommand(tag, from, to));\n const tagged = responses.find(r => r.tag === tag);\n if (!tagged || tagged.type !== \"OK\") throw new Error(`RENAME failed: ${tagged?.text || \"unknown\"}`);\n }\n\n // \u2500\u2500 Message Operations \u2500\u2500\n\n /** Fetch messages by UID range. Range may be sequence set (e.g. \"1:100\"), comma list (\"1,5,10\"), or mix (\"1:10,42,50:55\"). */\n async fetchMessages(range: string, options: { source?: boolean; headers?: boolean } = {}): Promise<NativeFetchedMessage[]> {\n return this.fetchMessagesStream(range, options);\n }\n\n /**\n * Fetch messages by UID range/list, streaming each parsed message through `onMessage`\n * as soon as its server response (including any literal bodies) is received, instead\n * of buffering the entire batch until the tagged OK. Returns all parsed messages at end.\n *\n * Pass a comma list (`\"1,5,10,42\"`) or sequence set (`\"100:200\"`) \u2014 the server handles either.\n */\n async fetchMessagesStream(\n range: string,\n options: { source?: boolean; headers?: boolean } = {},\n onMessage?: (msg: NativeFetchedMessage) => void,\n ): Promise<NativeFetchedMessage[]> {\n const items = [\"UID\", \"FLAGS\", \"ENVELOPE\", \"RFC822.SIZE\", \"INTERNALDATE\"];\n if (options.headers !== false) items.push(\"BODY.PEEK[HEADER]\");\n if (options.source) items.push(\"BODY.PEEK[]\");\n\n const tag = proto.nextTag();\n const streamed: NativeFetchedMessage[] = [];\n // ALWAYS parse incrementally in the per-response callback \u2014 even\n // when the caller passed no `onMessage`. The callback runs from\n // processBuffer's 10 ms time-budgeted loop, so envelope parsing of a\n // large FETCH (a sync-backfill chunk of 100+ messages) is sliced\n // across event-loop turns. The old `onMessage ? stream : batch`\n // path parsed every envelope in ONE synchronous block after the\n // tagged OK \u2014 profiled 2026-05-15 as a ~30 s daemon wedge\n // (tokenizeParenList ~40 % of CPU), starving every getMessage /\n // move / delete IPC for the duration.\n const cb = (resp: proto.ImapResponse): void => {\n if (resp.tag !== \"*\" || resp.type !== \"FETCH\") return;\n const parsed = this.parseFetchResponses([resp]);\n for (const msg of parsed) {\n streamed.push(msg);\n if (onMessage) onMessage(msg);\n }\n };\n\n await this.sendCommand(tag, proto.fetchCommand(tag, range, items), cb);\n return streamed;\n }\n\n /**\n * Folder-scoped batch body fetch. Selects `folderPath`, issues a single\n * `UID FETCH <uids> (BODY.PEEK[] ...)`, streams each body through `onBody`\n * as it arrives, and returns when the tagged OK is received.\n *\n * Eliminates per-message SELECT+FETCH round trips for callers like mailx-imap's\n * prefetch path.\n */\n async fetchBodiesBatch(\n folderPath: string,\n uids: number[],\n onBody: (uid: number, source: string) => void,\n ): Promise<void> {\n if (uids.length === 0) return;\n if (this.selectedMailbox !== folderPath) await this.select(folderPath);\n await this.fetchMessagesStream(uids.join(\",\"), { source: true, headers: false }, (msg) => {\n if (msg.uid && msg.source) onBody(msg.uid, msg.source);\n });\n }\n\n /** Fetch messages since a UID */\n async fetchSinceUid(sinceUid: number, options: { source?: boolean } = {}, onChunk?: (msgs: NativeFetchedMessage[]) => void): Promise<NativeFetchedMessage[]> {\n const uids = await this.search(`UID ${sinceUid + 1}:*`);\n if (uids.length === 0) return [];\n uids.reverse(); // Newest first\n console.log(` [fetch] ${uids.length} UIDs since ${sinceUid} (newest first)`);\n if (uids.length <= this.fetchChunkSize) {\n const msgs = await this.fetchMessages(uids.join(\",\"), options);\n if (onChunk) onChunk(msgs);\n return msgs;\n }\n const allMessages: NativeFetchedMessage[] = [];\n let chunkSize = this.fetchChunkSize;\n for (let i = 0; i < uids.length; i += chunkSize) {\n const chunk = uids.slice(i, i + chunkSize);\n const msgs = await this.fetchMessages(chunk.join(\",\"), options);\n allMessages.push(...msgs);\n // console.log(` [fetch] ${allMessages.length}/${uids.length} (chunk of ${chunk.length})`);\n if (onChunk) onChunk(msgs);\n if (chunkSize < this.fetchChunkSizeMax) chunkSize = Math.min(chunkSize * 4, this.fetchChunkSizeMax);\n }\n return allMessages;\n }\n\n /** Fetch messages by date range. Optional onChunk callback receives each batch as it arrives. */\n async fetchByDate(since: Date, before?: Date, options: { source?: boolean } = {}, onChunk?: (msgs: NativeFetchedMessage[]) => void): Promise<NativeFetchedMessage[]> {\n const criteria = proto.buildSearchCriteria({\n since,\n before: before || undefined,\n });\n // SEARCH SINCE on Dovecot can take minutes on a cold mailbox while it\n // (re)builds its date index. Without a \"search starting\" log, mailx\n // shows nothing for the entire SEARCH window \u2014 the user thinks\n // nothing is happening. Bracket the SEARCH with logs so the silence\n // is at least labeled.\n const t0 = Date.now();\n console.log(` [search] SINCE ${since.toISOString().slice(0, 10)}${before ? ` BEFORE ${before.toISOString().slice(0, 10)}` : \"\"} \u2014 running...`);\n const uids = await this.search(criteria);\n console.log(` [search] returned ${uids.length} UIDs in ${Date.now() - t0}ms`);\n if (uids.length === 0) return [];\n // Reverse so newest messages (highest UIDs) come first\n uids.reverse();\n const allMessages: NativeFetchedMessage[] = [];\n let chunkSize = this.fetchChunkSize;\n let chunkIndex = 0;\n for (let i = 0; i < uids.length; i += chunkSize) {\n const chunk = uids.slice(i, i + chunkSize);\n const msgs = await this.fetchMessages(chunk.join(\",\"), options);\n allMessages.push(...msgs);\n chunkIndex++;\n // Log every 5th chunk + the first one \u2014 enough to see progress\n // without spamming. The first-chunk log proves the fetch is alive\n // even when subsequent chunks are slow.\n if (chunkIndex === 1 || chunkIndex % 5 === 0) {\n console.log(` [fetch] ${allMessages.length}/${uids.length} messages (chunk ${chunkIndex})`);\n }\n if (onChunk) onChunk(msgs);\n if (chunkSize < this.fetchChunkSizeMax) chunkSize = Math.min(chunkSize * 4, this.fetchChunkSizeMax);\n }\n console.log(` [fetch] done \u2014 ${allMessages.length} messages in ${Date.now() - t0}ms`);\n return allMessages;\n }\n\n /** Fetch the most recent N messages by sequence number \u2014 avoids\n * SEARCH SINCE which can take minutes on cold Dovecot mailboxes. The\n * selected mailbox's `EXISTS` count is used to compute the range\n * `(EXISTS-N+1):EXISTS`; sequence FETCH is O(1) on the server because\n * it just reads message slots, no INTERNALDATE walk. Caller must have\n * SELECTed the mailbox first (sequence numbers are session-relative). */\n async fetchLatestN(n: number, options: { source?: boolean } = {}, onChunk?: (msgs: NativeFetchedMessage[]) => void): Promise<NativeFetchedMessage[]> {\n const exists = this.mailboxInfo.exists;\n if (!exists || exists < 1) return [];\n const start = Math.max(1, exists - n + 1);\n const range = `${start}:${exists}`;\n const t0 = Date.now();\n console.log(` [fetch-latest] ${this.selectedMailbox || \"?\"}: sequence ${range} (${Math.min(n, exists)} most recent of ${exists})`);\n\n const items = [\"UID\", \"FLAGS\", \"ENVELOPE\", \"RFC822.SIZE\", \"INTERNALDATE\", \"BODY.PEEK[HEADER]\"];\n if (options.source) items.push(\"BODY.PEEK[]\");\n\n const tag = proto.nextTag();\n const streamed: NativeFetchedMessage[] = [];\n const seenChunks = new Set<number>();\n const cb = (resp: proto.ImapResponse): void => {\n if (resp.tag !== \"*\" || resp.type !== \"FETCH\") return;\n const parsed = this.parseFetchResponses([resp]);\n for (const msg of parsed) streamed.push(msg);\n // Flush onChunk every ~50 messages without buffering the whole\n // response in memory \u2014 same shape as fetchByDate's chunk emit.\n const bucket = Math.floor(streamed.length / 50);\n if (onChunk && !seenChunks.has(bucket)) {\n seenChunks.add(bucket);\n onChunk(parsed);\n }\n };\n await this.sendCommand(tag, proto.seqFetchCommand(tag, range, items), cb);\n if (onChunk && streamed.length > 0) {\n // Final flush in case last bucket didn't trip the threshold.\n const lastBucket = Math.floor(streamed.length / 50);\n if (!seenChunks.has(lastBucket)) onChunk([]);\n }\n // Reverse so newest-first matches fetchByDate ordering \u2014 caller code\n // (mailx) expects that ordering when computing highestUid windows.\n streamed.reverse();\n console.log(` [fetch-latest] done \u2014 ${streamed.length} messages in ${Date.now() - t0}ms`);\n return streamed;\n }\n\n /** Fetch a single message by UID */\n async fetchMessage(uid: number, options: { source?: boolean } = {}): Promise<NativeFetchedMessage | null> {\n const msgs = await this.fetchMessages(String(uid), options);\n return msgs.find(m => m.uid === uid) || null;\n }\n\n /** Get all UIDs in the current mailbox */\n async getUids(): Promise<number[]> {\n return this.search(\"ALL\");\n }\n\n /** UID SEARCH */\n async search(criteria: string): Promise<number[]> {\n const tag = proto.nextTag();\n const responses = await this.sendCommand(tag, proto.searchCommand(tag, criteria));\n for (const r of responses) {\n if (r.tag === \"*\" && r.type === \"SEARCH\") {\n return proto.parseSearchResponse(r.text);\n }\n }\n return [];\n }\n\n /** Set flags on a message */\n async addFlags(uid: number, flags: string[]): Promise<void> {\n const tag = proto.nextTag();\n const responses = await this.sendCommand(tag, proto.storeCommand(tag, uid, \"+FLAGS.SILENT\", flags));\n const tagged = responses.find(r => r.tag === tag);\n if (!tagged || tagged.type !== \"OK\") throw new Error(`STORE +FLAGS failed: ${tagged?.text || \"unknown\"}`);\n }\n\n /** Remove flags from a message */\n async removeFlags(uid: number, flags: string[]): Promise<void> {\n const tag = proto.nextTag();\n const responses = await this.sendCommand(tag, proto.storeCommand(tag, uid, \"-FLAGS.SILENT\", flags));\n const tagged = responses.find(r => r.tag === tag);\n if (!tagged || tagged.type !== \"OK\") throw new Error(`STORE -FLAGS failed: ${tagged?.text || \"unknown\"}`);\n }\n\n /** Copy a message to another mailbox */\n async copyMessage(uid: number, destination: string): Promise<void> {\n const tag = proto.nextTag();\n const responses = await this.sendCommand(tag, proto.copyCommand(tag, uid, destination));\n const tagged = responses.find(r => r.tag === tag);\n if (!tagged || tagged.type !== \"OK\") throw new Error(`COPY failed: ${tagged?.text || \"unknown\"}`);\n }\n\n /** Move a message to another mailbox (MOVE or COPY+DELETE) */\n async moveMessage(uid: number, destination: string): Promise<void> {\n if (this.capabilities.has(\"MOVE\")) {\n const tag = proto.nextTag();\n const responses = await this.sendCommand(tag, proto.moveCommand(tag, uid, destination));\n const tagged = responses.find(r => r.tag === tag);\n if (!tagged || tagged.type !== \"OK\") throw new Error(`MOVE failed: ${tagged?.text || \"unknown\"}`);\n } else {\n await this.copyMessage(uid, destination);\n await this.addFlags(uid, [\"\\\\Deleted\"]);\n await this.expunge();\n }\n }\n\n /** Delete a message by UID (flag + expunge) */\n async deleteMessage(uid: number): Promise<void> {\n await this.addFlags(uid, [\"\\\\Deleted\"]);\n await this.expunge();\n }\n\n /** Expunge deleted messages */\n async expunge(): Promise<void> {\n const tag = proto.nextTag();\n await this.sendCommand(tag, proto.buildCommand(tag, \"EXPUNGE\"));\n }\n\n /** Append a message to a mailbox */\n async appendMessage(mailbox: string, message: string | Uint8Array, flags: string[] = []): Promise<number | null> {\n const data = typeof message === \"string\" ? message : new TextDecoder().decode(message);\n const size = new TextEncoder().encode(data).length;\n\n const tag = proto.nextTag();\n const cmd = proto.appendCommand(tag, mailbox, flags, size);\n\n // Send command, wait for continuation\n await this.transport.write(cmd);\n\n // Wait for \"+\" continuation\n const contResp = await this.waitForContinuation(tag);\n if (!contResp) throw new Error(\"APPEND: server did not send continuation\");\n\n // Send the message data + CRLF\n await this.transport.write(data + \"\\r\\n\");\n\n // Wait for tagged response\n const responses = await this.waitForTagged(tag);\n const tagged = responses.find(r => r.tag === tag);\n if (!tagged || tagged.type !== \"OK\") throw new Error(`APPEND failed: ${tagged?.text || \"unknown\"}`);\n\n // Try to extract APPENDUID\n const uidMatch = tagged.text.match(/APPENDUID\\s+\\d+\\s+(\\d+)/i);\n return uidMatch ? parseInt(uidMatch[1]) : null;\n }\n\n // \u2500\u2500 NOTIFY (RFC 5465) \u2500\u2500\n\n /** Issue NOTIFY SET so the server starts pushing unsolicited STATUS\n * responses for the mailboxes named in `spec` (beyond the currently\n * selected one). Capability gated \u2014 callers must check\n * `getCapabilities().has(\"NOTIFY\")` before calling. Set\n * `onMailboxStatus` before issuing if you want to react. Issue AFTER\n * SELECT and BEFORE startIdle \u2014 the server holds the spec for the\n * lifetime of the connection. */\n async notify(spec: string): Promise<void> {\n const tag = proto.nextTag();\n const responses = await this.sendCommand(tag, proto.notifyCommand(tag, spec));\n const tagged = responses.find(r => r.tag === tag);\n if (!tagged || tagged.type !== \"OK\") {\n throw new Error(`NOTIFY SET failed: ${tagged?.text || \"unknown\"}`);\n }\n }\n\n // \u2500\u2500 IDLE \u2500\u2500\n\n async startIdle(\n onNewMail: (count: number) => void,\n onExpunge?: () => void,\n ): Promise<() => Promise<void>> {\n this.idleCallback = onNewMail;\n this.idleExpungeCallback = onExpunge ?? null;\n this.idleStopped = false;\n\n const beginIdleCycle = async (): Promise<void> => {\n const tag = proto.nextTag();\n this.idleTag = tag;\n // Arm continuation listener BEFORE writing \u2014 some servers reply fast enough\n // that data can arrive in the same tick.\n const waitCont = this.waitForContinuation(tag);\n await this.transport.write(proto.idleCommand(tag));\n await waitCont;\n // RFC 2177: re-IDLE every ~28 minutes to avoid servers that terminate\n // idle sessions at the 29-minute mark, and to give us a steady\n // application-level keepalive that detects silently-dropped sockets.\n this.idleRefreshTimer = setTimeout(() => {\n if (this.idleStopped) return;\n this.refreshIdle().catch(err => {\n if (this.verbose) console.error(` [imap] IDLE refresh failed: ${err.message}`);\n });\n }, 28 * 60 * 1000);\n };\n\n await beginIdleCycle();\n\n return async () => {\n this.idleStopped = true;\n if (this.idleRefreshTimer) { clearTimeout(this.idleRefreshTimer); this.idleRefreshTimer = null; }\n const tag = this.idleTag;\n this.idleTag = null;\n this.idleCallback = null;\n this.idleExpungeCallback = null;\n if (tag) {\n // Arm tagged-wait BEFORE DONE \u2014 avoid missing the OK.\n const waitTag = this.waitForTagged(tag);\n try { await this.transport.write(proto.doneCommand()); } catch { /* ignore */ }\n try { await waitTag; } catch { /* ignore */ }\n }\n };\n }\n\n /**\n * If IDLE is currently active, send DONE and wait for its tagged OK so the\n * connection is free to accept a new command. Saves the active callback so\n * the companion `resumeIdleAfterCommand` can re-enter IDLE on the same\n * mailbox afterwards. Returns the saved state, or null if IDLE was not active.\n *\n * Called automatically at the top of `sendCommand` whenever the caller issues\n * an interleaved command on an IDLE-holding connection (e.g. pullMail reacting\n * to an EXISTS notification).\n */\n private async suspendIdleForCommand(): Promise<{ callback: (count: number) => void } | null> {\n const oldTag = this.idleTag;\n const cb = this.idleCallback;\n if (!oldTag || !cb) return null;\n if (this.idleRefreshTimer) { clearTimeout(this.idleRefreshTimer); this.idleRefreshTimer = null; }\n this.idleTag = null;\n this.idleCallback = null;\n if (this.verbose) console.log(` [imap] IDLE auto-suspending for interleaved command`);\n // Arm tagged listener BEFORE DONE so we don't miss the OK if the server is fast.\n const waitTag = this.waitForTagged(oldTag);\n try { await this.transport.write(proto.doneCommand()); }\n catch (err) {\n // Write failure \u2014 pendingCommand is still set by waitForTagged; clear it to prevent hang.\n this.pendingCommand = null;\n throw err;\n }\n try { await waitTag; } catch { /* best-effort \u2014 proceed even if OK was lost */ }\n return { callback: cb };\n }\n\n /** Re-enter IDLE with the saved callback after an auto-suspended command completes. */\n private async resumeIdleAfterCommand(info: { callback: (count: number) => void }): Promise<void> {\n // The caller may have stopped IDLE during the command window \u2014 respect that.\n if (this.idleStopped) return;\n const newTag = proto.nextTag();\n this.idleTag = newTag;\n this.idleCallback = info.callback;\n // Arm continuation listener BEFORE writing IDLE.\n const waitCont = this.waitForContinuation(newTag);\n await this.transport.write(proto.idleCommand(newTag));\n await waitCont;\n if (this.verbose) console.log(` [imap] IDLE auto-resumed (${newTag})`);\n this.idleRefreshTimer = setTimeout(() => {\n if (this.idleStopped) return;\n this.refreshIdle().catch(err => {\n if (this.verbose) console.error(` [imap] IDLE refresh failed: ${err.message}`);\n });\n }, 28 * 60 * 1000);\n }\n\n /** Send DONE + re-IDLE. Called by the 28-minute refresh timer. */\n private async refreshIdle(): Promise<void> {\n const oldTag = this.idleTag;\n if (!oldTag || !this.idleCallback) return;\n const cb = this.idleCallback;\n // Arm tagged listener BEFORE writing DONE to avoid missing a fast OK.\n const waitTag = this.waitForTagged(oldTag);\n await this.transport.write(proto.doneCommand());\n try { await waitTag; } catch { /* best-effort */ }\n // Re-IDLE with a new tag\n this.idleCallback = cb; // waitForTagged resolved pendingCommand, reinstall callback\n const newTag = proto.nextTag();\n this.idleTag = newTag;\n const waitCont = this.waitForContinuation(newTag);\n await this.transport.write(proto.idleCommand(newTag));\n await waitCont;\n if (this.verbose) console.log(` [imap] IDLE refreshed (${newTag})`);\n // Schedule the next refresh\n this.idleRefreshTimer = setTimeout(() => {\n if (this.idleStopped) return;\n this.refreshIdle().catch(err => {\n if (this.verbose) console.error(` [imap] IDLE refresh failed: ${err.message}`);\n });\n }, 28 * 60 * 1000);\n }\n\n // \u2500\u2500 Message count (lightweight STATUS) \u2500\u2500\n\n async getMessageCount(mailbox: string): Promise<number> {\n const status = await this.getStatus(mailbox);\n return status.messages || 0;\n }\n\n // \u2500\u2500 Low-level command handling \u2500\u2500\n\n /** Inactivity timeout \u2014 how long to wait with NO data before declaring the connection dead.\n * This is NOT a wall-clock timeout. Timer resets every time data arrives from the server.\n * A large FETCH returning data continuously will never timeout.\n * 60s accommodates Gmail which is slow on SEARCH for large folders.\n * Overridable via ImapClientConfig.inactivityTimeout \u2014 slow Dovecot servers need 180s+. */\n private inactivityTimeout: number;\n /** Hard wall-clock cap per command (independent of inactivityTimeout).\n * A pathological server that returns one byte every (inactivityTimeout-1)\n * seconds would otherwise defer the inactivity timer forever; this is\n * the absolute deadline that always fires. Default 5 minutes. */\n private commandWallClockTimeout: number;\n /** Server-greeting timeout in ms \u2014 how long to wait for the server's\n * initial banner after TCP/TLS connects. Default 10s; bumped to 30s\n * for slow shared-hosting Dovecot in mailx-imap. */\n private greetingTimeout: number;\n\n /** Fetch chunk sizes \u2014 start small for quick first paint, ramp up for throughput.\n * Default 25 initial \u2192 500 max. Overridable via ImapClientConfig.fetchChunkSize /\n * fetchChunkSizeMax. Slow servers benefit from smaller chunks (fewer timeouts). */\n private fetchChunkSize: number;\n private fetchChunkSizeMax: number;\n\n /** Active command timer \u2014 reset by handleData on every data arrival */\n private commandTimer: ReturnType<typeof setTimeout> | null = null;\n\n /**\n * Issue an IMAP command and await its tagged response.\n *\n * If IDLE is currently active on this connection, DONE it first (and wait\n * for its tagged OK) before writing the new command; re-enter IDLE after\n * the command finishes. Without this, commands issued from within an IDLE\n * EXISTS callback (e.g. mailpuller's pullMail) would be ignored by the\n * server until the inactivity timer killed the socket.\n */\n /** Per-client command serialization. IMAP allows only one command in\n * flight at a time on a single connection (RFC 3501 \u00A72.2.1). The\n * client's `pendingCommand` field tracks that command \u2014 if a second\n * caller concurrently invokes sendCommand, it overwrites\n * pendingCommand and the first caller's await is orphaned. We saw\n * this in production: the outbox poller's `withConnection`-queued\n * task ran on the same shared ops client as syncFolder's INBOX work,\n * and INBOX silently hung forever (no heartbeat fire, no wall-clock,\n * no reject \u2014 the promise just had no command tracking it anymore).\n *\n * This chain serializes ALL sendCommand callers against this client\n * regardless of whether the caller bothered to coordinate.\n * Defensive \u2014 the right thing for the upper layer to do is also use\n * the queue (withConnection in mailx-imap), but the IMAP client\n * shouldn't allow itself to be corrupted by a careless caller. */\n private commandChain: Promise<unknown> = Promise.resolve();\n private async sendCommand(\n tag: string,\n command: string,\n onUntagged?: (resp: proto.ImapResponse) => void,\n ): Promise<proto.ImapResponse[]> {\n const prev = this.commandChain.catch(() => { /* ignore predecessor errors */ });\n let myResolve!: (v: proto.ImapResponse[]) => void;\n let myReject!: (e: any) => void;\n const myPromise = new Promise<proto.ImapResponse[]>((res, rej) => { myResolve = res; myReject = rej; });\n this.commandChain = myPromise.catch(() => { /* */ });\n // Phase timing \u2014 multi-session \"62 s INBOX stall\" hunt. The stall\n // produces NO `>` log (sendCommandCore never runs), so it lives in\n // one of the two awaits below. Logging only slow phases (>1 s, Bob's\n // \"synchronous shouldn't span\" threshold lifted to network scale)\n // pins which one without spamming the normal fast path.\n const __cmdName = command.split(/[\\s\\r]/)[0] || command.slice(0, 12);\n const __p0 = Date.now();\n await prev;\n const __prevMs = Date.now() - __p0;\n if (__prevMs > 1000) console.warn(` [imap] cmd-chain wait ${__prevMs}ms before ${__cmdName} (predecessor held the connection)`);\n try {\n const __p1 = Date.now();\n const idleState = await this.suspendIdleForCommand();\n const __idleMs = Date.now() - __p1;\n if (__idleMs > 1000) console.warn(` [imap] IDLE-suspend wait ${__idleMs}ms before ${__cmdName}`);\n try {\n const out = await this.sendCommandCore(tag, command, onUntagged);\n myResolve(out);\n return out;\n } finally {\n if (idleState) {\n try { await this.resumeIdleAfterCommand(idleState); }\n catch (err) { if (this.verbose) console.error(` [imap] IDLE auto-resume failed: ${(err as Error).message}`); }\n }\n }\n } catch (e) {\n myReject(e);\n throw e;\n }\n }\n\n private sendCommandCore(\n tag: string,\n command: string,\n onUntagged?: (resp: proto.ImapResponse) => void,\n ): Promise<proto.ImapResponse[]> {\n return new Promise((resolve, reject) => {\n if (this.verbose && !command.includes(\"LOGIN\") && !command.includes(\"AUTHENTICATE\")) {\n console.log(` [imap] > ${command.trimEnd()}`);\n }\n\n // Snapshot transport diagnostics \u2014 used by both heartbeat and timeout.\n const transportDiag = (): string => {\n try {\n const d = (this.transport as any)?.diagnostics;\n if (!d) return \"\";\n const sinceRead = d.lastReadAt ? Date.now() - d.lastReadAt : -1;\n return ` [conn#${d.connId} r=${d.bytesRead}B w=${d.bytesWritten}B writes=${d.writeCount} sinceLastRead=${sinceRead}ms]`;\n } catch { return \"\"; }\n };\n\n // Always start clean \u2014 defends against a prior pendingCommand\n // having leaked timers (e.g. swap by suspendIdle/resumeIdle that\n // bypassed resolve/reject).\n this.clearAllCommandTimers();\n\n const cmdStart = Date.now();\n const cmdSummary = command.split(\"\\r\")[0].substring(0, 80);\n\n const onTimeout = (kind: string): void => {\n this.clearAllCommandTimers();\n this.pendingCommand = null;\n this._connected = false;\n this.transport.close?.();\n reject(new Error(`${kind}: ${cmdSummary}${transportDiag()}`));\n };\n\n // Three timers, three responsibilities \u2014 all instance-scoped now:\n // commandTimer = inactivity (resets on each data chunk)\n // wallClockTimer = hard cap from command start, never resets\n // heartbeatTimer = periodic progress log every 30s\n this.commandTimer = setTimeout(\n () => onTimeout(`IMAP inactivity timeout (${this.inactivityTimeout / 1000}s)`),\n this.inactivityTimeout,\n );\n this.wallClockTimer = setTimeout(\n () => onTimeout(`IMAP command wall-clock timeout (${this.commandWallClockTimeout / 1000}s)`),\n this.commandWallClockTimeout,\n );\n this.heartbeatTimer = setInterval(() => {\n const waited = Date.now() - cmdStart;\n console.log(` [imap] still waiting for tag ${tag} after ${(waited / 1000).toFixed(1)}s \u2014 ${cmdSummary}${transportDiag()}`);\n }, 30_000);\n\n this.pendingCommand = {\n tag, responses: [],\n resolve: (responses) => { this.clearAllCommandTimers(); resolve(responses); },\n reject: (err) => { this.clearAllCommandTimers(); reject(err); },\n onUntagged,\n };\n // PRE-WRITE HEALTH CHECK \u2014 verify the socket is in a writable\n // state BEFORE we burn the inactivityTimeout window waiting for\n // a reply that can't come. socket-half-closed (peer FIN'd) and\n // destroyed states both fail fast here instead of after 300s.\n try {\n const h = (this.transport as any)?.socketHealth;\n if (h && (h.destroyed || h.writableEnded || !h.writable)) {\n this.clearAllCommandTimers();\n this.pendingCommand = null;\n this._connected = false;\n reject(new Error(`IMAP socket dead before write: destroyed=${h.destroyed} writableEnded=${h.writableEnded} writable=${h.writable}${transportDiag()}`));\n return;\n }\n } catch { /* transport may not expose socketHealth \u2014 fall through */ }\n\n this.transport.write(command).catch((err) => {\n this.clearAllCommandTimers();\n // Write failure = dead socket. Clear pendingCommand + disconnect flag\n // so the next ensureConnected() does a fresh connect instead of\n // reusing a socket that the OS layer has already declared dead\n // (the source of the \"hostname nor servname provided\" cascade).\n this.pendingCommand = null;\n this._connected = false;\n reject(err);\n });\n });\n }\n\n private waitForContinuation(tag: string): Promise<proto.ImapResponse | null> {\n return new Promise((resolve) => {\n const timeout = setTimeout(() => {\n this.continuationResolve = null;\n resolve(null);\n }, 30000);\n this.continuationResolve = (resp) => {\n clearTimeout(timeout);\n this.continuationResolve = null;\n resolve(resp);\n };\n });\n }\n\n private waitForTagged(tag: string): Promise<proto.ImapResponse[]> {\n return new Promise((resolve, reject) => {\n this.pendingCommand = { tag, resolve, reject, responses: [] };\n });\n }\n\n private handleData(data: Uint8Array): void {\n // Reset inactivity timer ONLY (heartbeat + wall-clock NEVER reset\n // on data \u2014 that was the original bug: wall-clock got reset every\n // byte, so a slow-trickling server's command never died). Inactivity\n // is \"no data for N seconds\"; data IS arriving, so push it out.\n if (this.commandTimer) {\n clearTimeout(this.commandTimer);\n this.commandTimer = setTimeout(() => {\n this.commandTimer = null;\n if (this.pendingCommand) {\n const cmd = this.pendingCommand;\n this.pendingCommand = null;\n // Use the canonical clear so heartbeat + wall-clock\n // also stop. cmd.reject runs clearAllCommandTimers via\n // the closure binding \u2014 call it directly here too in\n // case cmd.reject was already replaced (defense in depth).\n this.clearAllCommandTimers();\n this._connected = false;\n this.transport.close?.();\n cmd.reject(new Error(`IMAP inactivity timeout (${this.inactivityTimeout / 1000}s)`));\n }\n }, this.inactivityTimeout);\n }\n this.appendToBuffer(data);\n this.processBuffer();\n }\n\n /** Append received bytes to the receive buffer, growing capacity if\n * needed. O(n) over the chunk size, never over the buffer total \u2014\n * doubling growth amortizes to O(1) per byte across the response. */\n private appendToBuffer(data: Uint8Array): void {\n const need = this.bufferLength + data.length;\n if (need > this.buffer.length) {\n let cap = Math.max(this.buffer.length * 2, 8192);\n while (cap < need) cap *= 2;\n const grown = new Uint8Array(cap);\n grown.set(this.buffer.subarray(0, this.bufferLength));\n this.buffer = grown;\n }\n this.buffer.set(data, this.bufferLength);\n this.bufferLength += data.length;\n }\n\n /** Single canonical \"command finished or abandoned\" cleanup. Every\n * path that ends a command's lifecycle \u2014 resolve, reject, timeout,\n * socket close, command-replace \u2014 calls this. Was a leak source:\n * closure-scoped timers in sendCommandCore couldn't be cleared from\n * handleData's inline-replacement timer or from IDLE suspend/resume. */\n private clearAllCommandTimers(): void {\n if (this.commandTimer) { clearTimeout(this.commandTimer); this.commandTimer = null; }\n if (this.heartbeatTimer) { clearInterval(this.heartbeatTimer); this.heartbeatTimer = null; }\n if (this.wallClockTimer) { clearTimeout(this.wallClockTimer); this.wallClockTimer = null; }\n }\n\n /** Compact the buffer when bufferOffset has advanced past half the used\n * region. copyWithin moves the unread bytes to the front in-place\n * (no new allocation). Amortized O(1) per byte; never the O(n\u00B2)\n * substring-each-line pathology that blocked the event loop on a\n * large LIST response. */\n private compactBufferIfNeeded(): void {\n if (this.bufferOffset > 0 && this.bufferOffset >= this.bufferLength / 2) {\n this.buffer.copyWithin(0, this.bufferOffset, this.bufferLength);\n this.bufferLength -= this.bufferOffset;\n this.bufferOffset = 0;\n }\n }\n\n /** Find the next CRLF (0x0D 0x0A) in the unread region, returning the\n * byte index of the 0x0D, or -1 if not found. Manual byte loop \u2014\n * Uint8Array doesn't have a native indexOf for byte sequences. */\n private indexOfCRLF(from: number): number {\n const buf = this.buffer;\n const end = this.bufferLength - 1;\n for (let i = from; i < end; i++) {\n if (buf[i] === 0x0D && buf[i + 1] === 0x0A) return i;\n }\n return -1;\n }\n\n private processBuffer(): void {\n // Time-budget the synchronous processing so a large FETCH burst\n // (sync of many envelopes in a single data chunk) doesn't starve\n // the Node event loop. Without this yield, IPC dispatchers in the\n // same process can wait 10+ seconds to get cycles \u2014 visible as\n // `mailxapi timeout: getMessage` / `getUnifiedInbox` on the desktop\n // client during heavy sync (Bob 2026-05-15: log shows daemon doing\n // hundreds of literal-consumed per second; client IPCs starve and\n // hit 30s ceiling). 10 ms budget = the same time slice Node uses\n // for I/O; after that we yield via setImmediate so timers, IPC,\n // and other I/O get a turn, then resume.\n const t0 = performance.now();\n const TIME_BUDGET_MS = 10;\n while (true) {\n if (performance.now() - t0 > TIME_BUDGET_MS) {\n setImmediate(() => this.processBuffer());\n return;\n }\n // Check for literal \u2014 `{N}` announces N octets of arbitrary data\n // (message body, MIME part, attachment chunk). The buffer is\n // bytes; the check is a direct length compare and the slice is\n // O(N) over the literal's own size \u2014 never O(buffer\u00B2).\n if (this.pendingCommand?.literalBytes != null) {\n const neededBytes = this.pendingCommand.literalBytes;\n const available = this.bufferLength - this.bufferOffset;\n if (available < neededBytes) {\n if (this.verbose && this.pendingCommand.literalBytes > 0) {\n console.log(` [imap] waiting for literal: need ${neededBytes} bytes, have ${available}`);\n }\n break; // Wait for more data \u2014 cheap, no decode.\n }\n // Slice the literal bytes; advance the read cursor by N.\n // The bytes themselves stay in the underlying buffer for the\n // moment, but bufferOffset advances past them and the next\n // compactBufferIfNeeded will reclaim the space.\n const literalBytes = this.buffer.subarray(this.bufferOffset, this.bufferOffset + neededBytes);\n this.bufferOffset += neededBytes;\n // Decode literal once (UTF-8 with replacement). For BODY[]\n // literals carrying non-UTF-8 charsets this is still lossy \u2014\n // the proper fix is to keep literals as bytes through to the\n // body store, tracked separately. The win HERE is that the\n // decode happens once per literal, not once per chunk that\n // arrives during the literal's transit.\n let literal = this.utf8Decoder.decode(literalBytes);\n // For non-BODY literals (e.g. display names in ENVELOPE), wrap in quotes\n // so tokenizeParenList treats them as a single token\n if (!this.pendingCommand.currentLiteralKey) {\n literal = `\"${literal.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"').replace(/\\r?\\n/g, \"\")}\"`;\n }\n this.pendingCommand.literalBuffer = (this.pendingCommand.literalBuffer || \"\") + literal;\n this.pendingCommand.literalBytes = undefined;\n // Store the literal data by its BODY key for parseFetchResponses\n if (this.pendingCommand.currentLiteralKey) {\n if (!this.pendingCommand.literals) this.pendingCommand.literals = new Map();\n this.pendingCommand.literals.set(this.pendingCommand.currentLiteralKey, literal);\n this.pendingCommand.currentLiteralKey = undefined;\n this.pendingCommand.currentLiteralSize = undefined;\n }\n if (this.verbose) console.log(` [imap] literal consumed, ${neededBytes} bytes, buffer remaining: ${this.bufferLength - this.bufferOffset}`);\n // Allow the consumed-prefix to be reclaimed when half-full \u2014\n // long literal-heavy responses would otherwise grow the\n // backing buffer indefinitely between commands.\n this.compactBufferIfNeeded();\n continue;\n }\n\n // Find next CRLF starting from the read offset on bytes (not\n // chars). bufferOffset advances past consumed bytes; we only\n // search the unread region so per-line work is O(line length),\n // never O(response size).\n const lineEnd = this.indexOfCRLF(this.bufferOffset);\n if (lineEnd < 0) {\n // No complete line yet. Compact the buffer if we've advanced\n // far enough that the unconsumed-prefix is dragging.\n this.compactBufferIfNeeded();\n break;\n }\n\n // Slice the line bytes (including trailing CRLF) and decode\n // once. IMAP control lines are 7-bit ASCII per RFC 3501; UTF-8\n // decode is a superset and produces the same characters. The\n // existing string-based parser (parseResponseLine, tokenizers,\n // ENVELOPE/FLAGS handling) consumes the decoded line below.\n const lineBytes = this.buffer.subarray(this.bufferOffset, lineEnd + 2);\n const line = this.utf8Decoder.decode(lineBytes);\n this.bufferOffset = lineEnd + 2;\n // Periodic compaction so the consumed prefix doesn't keep\n // growing forever in long-running connections (IDLE, big sync).\n this.compactBufferIfNeeded();\n\n // Check for literal announcement {size}\\r\\n at end of line\n const literalMatch = line.match(/\\{(\\d+)\\}\\r\\n$/);\n if (literalMatch && this.pendingCommand) {\n const size = parseInt(literalMatch[1]);\n // Store the line prefix before {size} \u2014 will be prepended after literal is consumed\n const linePrefix = line.substring(0, literalMatch.index);\n if (this.pendingCommand.literalBuffer) {\n // Already have buffered data from a previous literal \u2014 append this prefix\n this.pendingCommand.literalBuffer += linePrefix;\n } else {\n this.pendingCommand.literalBuffer = linePrefix;\n }\n this.pendingCommand.literalBytes = size;\n // Extract the BODY section key from the prefix (e.g. BODY[], BODY[HEADER], BODY.PEEK[])\n const keyMatch = linePrefix.match(/BODY(?:\\.PEEK)?\\[([^\\]]*)\\]\\s*$/i);\n if (keyMatch) {\n this.pendingCommand.currentLiteralKey = `BODY[${keyMatch[1]}]`;\n this.pendingCommand.currentLiteralSize = size;\n }\n if (this.verbose) console.log(` [imap] literal announced: ${size} bytes, prefix: ${linePrefix.length} chars, key: ${this.pendingCommand.currentLiteralKey || \"none\"}`);\n continue;\n }\n\n // If we have buffered literal data, prepend it to this line (the closing part after the literal)\n let fullLine = line;\n if (this.pendingCommand?.literalBuffer) {\n fullLine = this.pendingCommand.literalBuffer + line;\n this.pendingCommand.literalBuffer = undefined;\n }\n\n const resp = proto.parseResponseLine(fullLine);\n\n // Attach accumulated literals to the response and reset for next response\n if (this.pendingCommand?.literals?.size) {\n resp.literals = this.pendingCommand.literals;\n this.pendingCommand.literals = undefined;\n }\n\n if (this.verbose) {\n const display = resp.raw.length > 200 ? resp.raw.substring(0, 200) + `... (${resp.raw.length} bytes)` : resp.raw;\n console.log(` [imap] < [tag=${resp.tag} type=${resp.type}] ${display}`);\n }\n\n // Server greeting \u2014 resolve readGreeting() promise\n if (this.greetingResolve && resp.tag === \"*\" && (resp.type === \"OK\" || resp.type === \"PREAUTH\")) {\n const resolve = this.greetingResolve;\n this.greetingResolve = null;\n resolve(resp);\n continue;\n }\n\n // During IDLE, handle EXISTS notifications\n if (this.idleTag && resp.tag === \"*\" && resp.type === \"EXISTS\") {\n const count = parseInt(resp.text);\n if (this.idleCallback && count > this.mailboxInfo.exists) {\n const newCount = count - this.mailboxInfo.exists;\n this.mailboxInfo.exists = count;\n this.idleCallback(newCount);\n } else if (count < this.mailboxInfo.exists) {\n // Count dropped \u2014 a message was expunged on the selected\n // mailbox (another client / Thunderbird deleted it).\n // Signal the caller to reconcile the deletion now.\n this.mailboxInfo.exists = count;\n if (this.idleExpungeCallback) this.idleExpungeCallback();\n }\n continue;\n }\n\n // During IDLE, an unsolicited `* n EXPUNGE` / `* VANISHED` for the\n // selected mailbox (RFC 5465 NOTIFY SELECTED MessageExpunge, or a\n // plain post-EXPUNGE notification). Push a deletion reconcile.\n if (this.idleTag && resp.tag === \"*\" && (resp.type === \"EXPUNGE\" || resp.type === \"VANISHED\")) {\n if (this.mailboxInfo.exists > 0) this.mailboxInfo.exists--;\n if (this.idleExpungeCallback) this.idleExpungeCallback();\n continue;\n }\n\n // RFC 5465 NOTIFY: unsolicited STATUS responses for non-selected\n // mailboxes arrive when the server has accepted a NOTIFY SET that\n // included a PERSONAL (or other) event group. Only route to the\n // callback when IDLE is active \u2014 a STATUS response outside IDLE\n // is the result of a direct STATUS command and belongs to the\n // pending command's response set (the fall-through below).\n if (this.idleTag && resp.tag === \"*\" && resp.type === \"STATUS\" && this.onMailboxStatus) {\n const parsed = proto.parseStatusResponseFull(resp.text);\n if (parsed) {\n try { this.onMailboxStatus(parsed.mailbox, parsed.data); }\n catch (err) { if (this.verbose) console.error(` [imap] onMailboxStatus threw: ${(err as Error).message}`); }\n continue;\n }\n // Parse failed \u2014 fall through so the response isn't silently dropped.\n }\n\n // Collect untagged responses for the pending command\n if (resp.tag === \"*\" && this.pendingCommand) {\n this.pendingCommand.responses.push(resp);\n if (this.pendingCommand.onUntagged) {\n try { this.pendingCommand.onUntagged(resp); }\n catch (err) { if (this.verbose) console.error(` [imap] onUntagged callback threw: ${(err as Error).message}`); }\n }\n continue;\n }\n\n // Continuation response\n if (resp.tag === \"+\") {\n if (this.continuationResolve) {\n // APPEND or other command waiting for continuation\n this.continuationResolve(resp);\n } else if (!this.idleTag && this.pendingCommand) {\n // Unexpected continuation (e.g. AUTHENTICATE challenge) \u2014 cancel\n this.transport.write(\"\\r\\n\").catch(() => {});\n }\n continue;\n }\n\n // Tagged response \u2014 command complete\n if (this.pendingCommand && resp.tag === this.pendingCommand.tag) {\n this.pendingCommand.responses.push(resp);\n const { resolve, responses } = this.pendingCommand;\n this.pendingCommand = null;\n resolve(responses);\n continue;\n }\n\n // Unhandled\n this.handleUntaggedResponse(resp);\n }\n }\n\n private handleUntaggedResponse(resp: proto.ImapResponse): void {\n if (resp.type === \"EXISTS\") {\n this.mailboxInfo.exists = parseInt(resp.text);\n } else if (resp.type === \"EXPUNGE\") {\n this.mailboxInfo.exists = Math.max(0, this.mailboxInfo.exists - 1);\n }\n }\n\n // \u2500\u2500 FETCH Response Parser \u2500\u2500\n\n private parseFetchResponses(responses: proto.ImapResponse[]): NativeFetchedMessage[] {\n const messages: NativeFetchedMessage[] = [];\n\n for (const r of responses) {\n if (r.tag !== \"*\" || r.type !== \"FETCH\") continue;\n\n const msg: NativeFetchedMessage = {\n seq: 0, uid: 0, flags: new Set(), date: null,\n subject: \"\", messageId: \"\", from: [], to: [], cc: [], bcc: [],\n sender: [], replyTo: [], inReplyTo: \"\", size: 0,\n source: \"\", headers: \"\", seen: false, flagged: false,\n answered: false, draft: false,\n };\n\n // Extract sequence number from \"5 FETCH (...)\"\n const seqMatch = r.text.match(/^(\\d+)\\s+FETCH/);\n if (seqMatch) msg.seq = parseInt(seqMatch[1]);\n\n // Extract UID\n const uidMatch = r.text.match(/UID\\s+(\\d+)/);\n if (uidMatch) msg.uid = parseInt(uidMatch[1]);\n\n // Extract FLAGS\n const flagsMatch = r.text.match(/FLAGS\\s+\\(([^)]*)\\)/);\n if (flagsMatch) {\n msg.flags = new Set(flagsMatch[1].split(/\\s+/).filter(Boolean));\n msg.seen = msg.flags.has(\"\\\\Seen\");\n msg.flagged = msg.flags.has(\"\\\\Flagged\");\n msg.answered = msg.flags.has(\"\\\\Answered\");\n msg.draft = msg.flags.has(\"\\\\Draft\");\n }\n\n // Extract RFC822.SIZE\n const sizeMatch = r.text.match(/RFC822\\.SIZE\\s+(\\d+)/);\n if (sizeMatch) msg.size = parseInt(sizeMatch[1]);\n\n // Extract MODSEQ (RFC 7162). Format: `MODSEQ (12345)`. Server\n // emits this when the session has ENABLE QRESYNC/CONDSTORE\n // active OR when the client explicitly asks for MODSEQ in the\n // FETCH command. Track on every FETCH so the caller can update\n // its `last_modseq` watermark.\n const modSeqMatch = r.text.match(/MODSEQ\\s+\\((\\d+)\\)/);\n if (modSeqMatch) msg.modSeq = parseInt(modSeqMatch[1]);\n\n // Extract INTERNALDATE\n const dateMatch = r.text.match(/INTERNALDATE\\s+\"([^\"]+)\"/);\n if (dateMatch) msg.date = new Date(dateMatch[1]);\n\n // Extract ENVELOPE\n const envMatch = r.text.match(/ENVELOPE\\s+(\\(.*\\))/);\n if (envMatch) {\n const env = proto.parseEnvelope(envMatch[1]);\n msg.date = msg.date || env.date;\n msg.subject = env.subject;\n msg.messageId = env.messageId;\n msg.from = env.from;\n msg.to = env.to;\n msg.cc = env.cc;\n msg.bcc = env.bcc;\n msg.sender = env.sender;\n msg.replyTo = env.replyTo;\n msg.inReplyTo = env.inReplyTo;\n }\n\n // Extract body source and headers from literals tracked by processBuffer\n if (r.literals) {\n const source = r.literals.get(\"BODY[]\");\n if (source) msg.source = source;\n const headers = r.literals.get(\"BODY[HEADER]\");\n if (headers) msg.headers = headers;\n }\n\n messages.push(msg);\n }\n return messages;\n }\n}\n", "/**\n * FetchedMessage \u2014 NativeFetchedMessage plus parsed-header state and convenience getters.\n *\n * Inherits the NativeFetchedMessage shape (via `implements`) so a FetchedMessage\n * is-a NativeFetchedMessage: it can be passed anywhere the native interface is\n * expected. Callers that want the raw shape treat it as NativeFetchedMessage;\n * callers that want extras read `.ymd`, `.listUnsubscribe`, etc. directly.\n */\n\nimport type { NativeFetchedMessage } from \"./imap-native.js\";\nimport type { AddressData } from \"./imap-protocol.js\";\n\n/** Case-insensitive multi-value header map (one key may repeat). */\nclass HeaderMap {\n private items: Record<string, string[]> = {};\n add(key: string, value: string): void {\n const k = key.toLowerCase();\n (this.items[k] ||= []).push(value);\n }\n get(key: string): string[] | undefined {\n return this.items[key.toLowerCase()];\n }\n}\n\nexport class FetchedMessage implements NativeFetchedMessage {\n // Native fields \u2014 populated by Object.assign in the constructor.\n // `implements NativeFetchedMessage` forces this list to stay in sync.\n seq!: number;\n uid!: number;\n flags!: Set<string>;\n date!: Date | null;\n subject!: string;\n messageId!: string;\n from!: AddressData[];\n to!: AddressData[];\n cc!: AddressData[];\n bcc!: AddressData[];\n sender!: AddressData[];\n replyTo!: AddressData[];\n inReplyTo!: string;\n size!: number;\n source!: string;\n headers!: string;\n seen!: boolean;\n flagged!: boolean;\n answered!: boolean;\n draft!: boolean;\n modSeq?: number;\n\n // Parsed-header state\n parsedHeader: string[][];\n headerSet: HeaderMap;\n\n constructor(init: NativeFetchedMessage) {\n Object.assign(this, init);\n\n // RFC 5322 unfold: a line starting with whitespace continues the prior one.\n const unfolded = (init.headers || \"\").replace(/\\r\\n(\\s)/g, \"$1\");\n this.parsedHeader = unfolded\n .split(/\\r?\\n/)\n .filter(line => line.trim() !== \"\")\n .map(line => {\n const i = line.indexOf(\":\");\n return i < 0 ? [line, \"\"] : [line.slice(0, i), line.slice(i + 1).trim()];\n });\n this.headerSet = new HeaderMap();\n for (const [k, v] of this.parsedHeader) this.headerSet.add(k, v);\n }\n\n // Flag convenience\n get unread() { return !this.seen; }\n get deleted() { return this.flags.has(\"\\\\Deleted\"); }\n get hasFlag() { return this.flags.size > 0; }\n\n // Display\n get ymd(): string | undefined { return this.date?.toLocaleDateString(\"se\"); }\n /** Self-typed as a keyable record for dynamic address-field access by screening rules. */\n get tcsb(): Record<string, AddressData[]> {\n return this as unknown as Record<string, AddressData[]>;\n }\n\n // Parsed-header lookups\n get listUnsubscribe() { return this.headerSet.get(\"List-Unsubscribe\")?.[0]; }\n get xpriority() { return this.headerSet.get(\"X-Priority\")?.[0]; }\n get importance() { return this.headerSet.get(\"Importance\")?.[0]; }\n get deliveredTo() { return this.headerSet.get(\"Delivered-To\")?.[0]; }\n}\n", "/**\n * Compatibility wrapper \u2014 makes NativeImapClient look like the old ImapClient API.\n * This allows mailx-imap to switch to the native client without rewriting all call sites.\n * Each method opens the mailbox, does the operation, and returns. No persistent state.\n */\n\nimport { NativeImapClient, type NativeFolder } from \"./imap-native.js\";\nimport { FetchedMessage } from \"./fetched-message.js\";\nimport type { ImapClientConfig } from \"./types.js\";\nimport type { TransportFactory } from \"./transport.js\";\nimport type * as proto from \"./imap-protocol.js\";\nimport fs from 'node:fs'; // Debugging\n\n/** Special folder detection result */\n// Later we may need special casing\nexport interface SpecialFolders {\n inbox?: string;\n sent?: string;\n trash?: string;\n drafts?: string;\n spam?: string;\n junk?: string;\n archive?: string;\n}\n\n// We may need some special cases in the future\nconst defaultFolders: SpecialFolders = {\n inbox: \"INBOX\", // Uppercase -- we'll need a reality check\n sent: \"Sent\",\n trash: \"Trash\",\n drafts: \"Drafts\",\n spam: \"_Spam\",\n junk: \"_Spam\",\n archive: \"Archive\"\n}\n\n/**\n * Compatibility IMAP client \u2014 wraps NativeImapClient with the old ImapClient API.\n * Each method creates its own select/operation/close cycle.\n */\nexport class CompatImapClient {\n private native: NativeImapClient;\n\n constructor(config: ImapClientConfig, transportFactory: TransportFactory) {\n this.native = new NativeImapClient(config, transportFactory);\n }\n\n /** Connect and authenticate */\n async connect(): Promise<void> {\n await this.native.connect();\n }\n\n /**\n * Ensure connected (lazy connect). Checks both the native client's connected\n * flag AND the transport's connected state. The transport flag catches cases\n * where the socket died without a close/error event reaching NativeImapClient\n * (common on Android where the bridge may not relay all TCP events).\n */\n private async ensureConnected(): Promise<void> {\n if (!this.native.connected || !this.native.transportConnected) {\n // Force a fresh transport \u2014 the old one may be in a bad state.\n this.native.resetTransport();\n await this.connect();\n }\n }\n\n async logout(): Promise<void> {\n await this.native.logout();\n }\n\n /** Get folder list */\n async getFolderList(): Promise<NativeFolder[]> {\n await this.ensureConnected();\n return this.native.listFolders();\n }\n\n /** Extract special folders from folder list */\n getSpecialFolders(folders: NativeFolder[]): SpecialFolders {\n // Two-pass detection so RFC 6154 \\Drafts / \\Sent / \\Trash / \\Junk /\n // \\Archive flags always win over name-based guesses. Previous single-pass\n // `else if (flag || name)` could tag a stray folder named \"DRAFT\" as the\n // drafts folder on Gmail, beating out [Imap]/Drafts which has the real\n // \\Drafts flag \u2014 Gmail then rejects APPEND to \"DRAFT\" as NONEXISTENT.\n let result: SpecialFolders = {};\n const leafName = (f: NativeFolder): string => {\n const delim = (f as any).delimiter || \".\";\n return (f.path.split(delim).at(-1) ?? f.path).toLowerCase();\n };\n const flagSet = (f: NativeFolder): Set<string> => new Set(f.flags.map(fl => fl.toLowerCase()));\n // const df = 'y:\\\\temp\\\\folders.csv';\n // fs.writeFileSync(df, \"path,flags\\n\" + folders.map(f => `${f.path},\"${f.flags.join(\";\")}\"`).join(\"\\n\"));\n // console.log(`Wrote folder list to ${df}`);\n\n // RFC 6154 flags only \u2014 authoritative if present\n // Note that Dovecot does not have them but we check INBOX for the case\n for (const f of folders) {\n const flags = flagSet(f);\n\n // Debubing \n const dbgignore = ['\\\\haschildren', '\\\\hasnochildren', '\\\\noselect', '\\\\unmarked'];\n const dbgfgall = Array.from(flags);\n const dbgfg = dbgfgall.filter(fl => !dbgignore.includes(fl));\n\n if (flags.has(\"\\\\inbox\") || leafName(f) === \"inbox\")\n result.inbox ??= f.path;\n if (flags.has(\"\\\\sent\"))\n result.sent ??= f.path;\n if (flags.has(\"\\\\trash\"))\n result.trash ??= f.path;\n if (flags.has(\"\\\\drafts\"))\n result.drafts ??= f.path;\n if (flags.has(\"\\\\archive\"))\n result.archive ??= f.path;\n if (flags.has(\"\\\\junk\"))\n result.junk = f.path;\n if (flags.has(\"\\\\spam\"))\n result.spam ??= f.path;\n }\n\n result = { ...defaultFolders, ...result }; // Fill in any missing defaults\n\n // // Pass 2: exact leaf-name fallback for servers that don't advertise flags\n // const sentNames = new Set([\"sent\", \"sent items\", \"sent mail\"]);\n // const trashNames = new Set([\"trash\", \"deleted items\", \"deleted\"]);\n // const draftsNames = new Set([\"drafts\", \"draft\"]);\n // const archiveNames = new Set([\"archive\", \"archives\"]);\n // const junkNames = new Set([\"spam\", \"junk\", \"junk email\", \"junk e-mail\"]);\n // for (const f of folders) {\n // const name = leafName(f);\n // if (sentNames.has(name)) result.sent ??= f.path;\n // if (trashNames.has(name)) result.trash ??= f.path;\n // if (draftsNames.has(name)) result.drafts ??= f.path;\n // if (archiveNames.has(name)) result.archive ??= f.path;\n // if (junkNames.has(name)) {\n // result.junk ??= f.path;\n // result.spam ??= f.path;\n // }\n // }\n return result;\n }\n\n /** Fetch messages since a UID in a mailbox */\n async fetchMessagesSinceUid(mailbox: string, sinceUid: number, options?: { source?: boolean }): Promise<FetchedMessage[]> {\n await this.ensureConnected();\n await this.native.select(mailbox);\n const msgs = await this.native.fetchSinceUid(sinceUid, options);\n await this.native.closeMailbox();\n return msgs.map(m => new FetchedMessage(m));\n }\n\n /** Batch-fetch bodies for many UIDs in one folder on one connection. Streams\n * each body through `onBody` as it arrives. No per-message round trips \u2014\n * one SELECT, one UID FETCH, streaming response. Required by mailx-imap's\n * batch prefetch path. */\n async fetchBodiesBatch(mailbox: string, uids: number[], onBody: (uid: number, source: string) => void): Promise<void> {\n if (uids.length === 0) return;\n await this.ensureConnected();\n await this.native.fetchBodiesBatch(mailbox, uids, onBody);\n }\n\n /** Fetch messages by date range. Optional onChunk callback for incremental processing. */\n async fetchMessageByDate(mailbox: string, start: Date, end?: Date, options?: { source?: boolean }, onChunk?: (msgs: FetchedMessage[]) => void): Promise<FetchedMessage[]> {\n await this.ensureConnected();\n await this.native.select(mailbox);\n const chunkCb = onChunk ? (raw: import(\"./imap-native.js\").NativeFetchedMessage[]) => onChunk(raw.map(m => new FetchedMessage(m))) : undefined;\n const msgs = await this.native.fetchByDate(start, end, options, chunkCb);\n await this.native.closeMailbox();\n return msgs.map(m => new FetchedMessage(m));\n }\n\n /** Fetch the most recent N messages by sequence number \u2014 sidesteps\n * SEARCH SINCE which can take minutes on cold Dovecot mailboxes. Used\n * by mailx-imap's first-sync path so the user sees something fast even\n * on a wide folder tree. The 30-day backfill is a follow-up step. */\n async fetchLatestN(mailbox: string, n: number, options?: { source?: boolean }, onChunk?: (msgs: FetchedMessage[]) => void): Promise<FetchedMessage[]> {\n await this.ensureConnected();\n await this.native.select(mailbox);\n const chunkCb = onChunk ? (raw: import(\"./imap-native.js\").NativeFetchedMessage[]) => onChunk(raw.map(m => new FetchedMessage(m))) : undefined;\n const msgs = await this.native.fetchLatestN(n, options, chunkCb);\n await this.native.closeMailbox();\n return msgs.map(m => new FetchedMessage(m));\n }\n\n /** Fetch a single message by UID */\n async fetchMessageByUid(mailbox: string, uid: number, options?: { source?: boolean }): Promise<FetchedMessage | null> {\n await this.ensureConnected();\n await this.native.select(mailbox);\n const msg = await this.native.fetchMessage(uid, options);\n await this.native.closeMailbox();\n return msg ? new FetchedMessage(msg) : null;\n }\n\n /** Get message count via STATUS (does not require SELECT) */\n async getMessagesCount(mailbox: string): Promise<number> {\n await this.ensureConnected();\n return this.native.getMessageCount(mailbox);\n }\n\n /** Get all UIDs in a mailbox */\n async getUids(mailbox: string): Promise<number[]> {\n await this.ensureConnected();\n await this.native.select(mailbox);\n const uids = await this.native.getUids();\n await this.native.closeMailbox();\n return uids;\n }\n\n /** Get UIDs whose INTERNALDATE is on/after `since`. Bounded version of\n * getUids \u2014 returns only the date window the caller cares about\n * instead of the entire folder. Lets set-diff reconciliation scope\n * itself to \"messages from the last N days\" rather than enumerating\n * every UID in a 134k-message folder. */\n async getUidsSince(mailbox: string, since: Date): Promise<number[]> {\n await this.ensureConnected();\n await this.native.select(mailbox);\n const months = [\"Jan\",\"Feb\",\"Mar\",\"Apr\",\"May\",\"Jun\",\"Jul\",\"Aug\",\"Sep\",\"Oct\",\"Nov\",\"Dec\"];\n const d = `${since.getUTCDate()}-${months[since.getUTCMonth()]}-${since.getUTCFullYear()}`;\n const uids = await this.native.search(`SINCE ${d}`);\n await this.native.closeMailbox();\n return uids;\n }\n\n /** Fetch messages \u2014 supports two calling conventions for compatibility:\n *\n * New: fetchMessages(mailbox, \"100:200\") \u2014 UID range string\n * Old: fetchMessages(mailbox, endSeq, count) \u2014 sequence-number range (iflow compat)\n *\n * The old form computes UID range \"start:end\" from (end - count + 1) : end,\n * matching the legacy iflow/imapflow fetchMessages(mailbox, end, count) API\n * used by the puller. */\n async fetchMessages(mailbox: string, uidRange: string, options?: { source?: boolean }): Promise<FetchedMessage[]>;\n async fetchMessages(mailbox: string, end: number, count: number, options?: { source?: boolean }): Promise<FetchedMessage[]>;\n async fetchMessages(\n mailbox: string,\n rangeOrEnd: string | number,\n countOrOptions?: number | { source?: boolean },\n maybeOptions?: { source?: boolean },\n ): Promise<FetchedMessage[]> {\n let range: string;\n let options: { source?: boolean } | undefined;\n if (typeof rangeOrEnd === \"number\") {\n // Legacy (iflow) calling convention: (mailbox, endSeq, count, options?)\n const end = rangeOrEnd;\n const count = typeof countOrOptions === \"number\" ? countOrOptions : 1;\n const start = Math.max(1, end - count + 1);\n range = `${start}:${end}`;\n options = maybeOptions;\n } else {\n // New calling convention: (mailbox, uidRange, options?)\n range = rangeOrEnd;\n options = typeof countOrOptions === \"object\" ? countOrOptions : undefined;\n }\n await this.ensureConnected();\n await this.native.select(mailbox);\n const msgs = await this.native.fetchMessages(range, options);\n await this.native.closeMailbox();\n return msgs.map(m => new FetchedMessage(m));\n }\n\n /** Search messages in a mailbox */\n async searchMessages(mailbox: string, criteria: any): Promise<number[]> {\n await this.ensureConnected();\n await this.native.select(mailbox);\n // Convert object criteria to IMAP search string\n const parts: string[] = [];\n if (criteria.from) parts.push(`FROM \"${criteria.from}\"`);\n if (criteria.to) parts.push(`TO \"${criteria.to}\"`);\n if (criteria.subject) parts.push(`SUBJECT \"${criteria.subject}\"`);\n if (criteria.body) parts.push(`BODY \"${criteria.body}\"`);\n if (criteria.since) parts.push(`SINCE ${formatDate(criteria.since)}`);\n if (criteria.before) parts.push(`BEFORE ${formatDate(criteria.before)}`);\n const searchStr = parts.length > 0 ? parts.join(\" \") : \"ALL\";\n const uids = await this.native.search(searchStr);\n await this.native.closeMailbox();\n return uids;\n }\n\n /** Search by header value \u2014 returns matching UIDs */\n async searchByHeader(mailbox: string, headerName: string, headerValue: string): Promise<number[]> {\n await this.ensureConnected();\n await this.native.select(mailbox);\n const uids = await this.native.search(`HEADER ${headerName} \"${headerValue}\"`);\n await this.native.closeMailbox();\n return uids;\n }\n\n /** Delete a message by UID */\n async deleteMessageByUid(mailbox: string, uid: number): Promise<void> {\n await this.ensureConnected();\n await this.native.select(mailbox);\n await this.native.deleteMessage(uid);\n await this.native.closeMailbox();\n }\n\n /** Move a message between mailboxes (same server) */\n async moveMessage(msg: any, fromMailbox: string, toMailbox: string): Promise<void> {\n await this.ensureConnected();\n await this.native.select(fromMailbox);\n await this.native.moveMessage(msg.uid, toMailbox);\n await this.native.closeMailbox();\n }\n\n /** Add flags to a message */\n async addFlags(mailbox: string, uid: number, flags: string[]): Promise<void> {\n await this.ensureConnected();\n await this.native.select(mailbox);\n await this.native.addFlags(uid, flags);\n await this.native.closeMailbox();\n }\n\n /** Remove flags from a message */\n async removeFlags(mailbox: string, uid: number, flags: string[]): Promise<void> {\n await this.ensureConnected();\n await this.native.select(mailbox);\n await this.native.removeFlags(uid, flags);\n await this.native.closeMailbox();\n }\n\n /** Create a mailbox */\n async createmailbox(name: string): Promise<void> {\n await this.ensureConnected();\n await this.native.createMailbox(name);\n }\n\n /** Append a message to a mailbox */\n async appendMessage(mailbox: string, message: string | Uint8Array, flags: string[] = []): Promise<number | null> {\n await this.ensureConnected();\n const data = typeof message === \"string\" ? message : new TextDecoder().decode(message);\n return this.native.appendMessage(mailbox, data, flags);\n }\n\n /** Cached CAPABILITY set parsed at connect/login. Callers gate\n * optional features (NOTIFY, QRESYNC, MOVE, ...) on this. */\n getCapabilities(): Set<string> {\n return this.native.getCapabilities();\n }\n\n /** Snapshot of the most recently SELECTed mailbox's info. Callers use this\n * to read `highestModSeq` after any operation that did a SELECT \u2014 useful\n * for seeding the QRESYNC modSeq watermark on the very first sync of a\n * folder (before the QRESYNC path is eligible). */\n getCurrentMailboxInfo(): { uidValidity: number; uidNext: number; exists: number; highestModSeq?: number } {\n const info = this.native.getMailboxInfo?.();\n return info || { uidValidity: 0, uidNext: 0, exists: 0 };\n }\n\n /** RFC 5161 ENABLE \u2014 activates an IMAP extension for the remainder of\n * the session. QRESYNC must be enabled before any SELECT for\n * `* VANISHED` responses + automatic `MODSEQ` to start flowing.\n * Returns the set of extensions the server confirmed are active. */\n async enable(extensions: string[]): Promise<Set<string>> {\n await this.ensureConnected();\n return this.native.enable(extensions);\n }\n\n /** Convenience: enable QRESYNC if the server advertises it. Returns\n * true if QRESYNC is active on the session afterwards. Idempotent \u2014\n * safe to call once per connection at connect time. */\n async enableQresync(): Promise<boolean> {\n const caps = this.getCapabilities();\n if (!caps.has(\"QRESYNC\")) return false;\n const enabled = await this.enable([\"QRESYNC\"]);\n return enabled.has(\"QRESYNC\");\n }\n\n /** Fast resync of a mailbox via RFC 7162 QRESYNC. Caller supplies the\n * `uidValidity` and last-seen `modSeq` from its prior visit; the\n * server replies with `* VANISHED` for UIDs expunged since then and\n * unsolicited `* FETCH` for state changes (flag updates etc.) since\n * then, plus the current `HIGHESTMODSEQ` for the caller to persist\n * as its new watermark.\n *\n * Returns:\n * - `uidValidityChanged`: server's UIDVALIDITY no longer matches; the\n * caller's UID set is stale and MUST be full-resynced.\n * - `vanishedUids`: authoritative deletion list. No client-side diff.\n * - `changedMessages`: state-change FETCH responses since the prior\n * modSeq \u2014 each carries `uid`, `flags`, and `modSeq` (and possibly\n * other FETCH items the caller asked for).\n * - `newHighestModSeq`: persist this for the next resync.\n *\n * Pre-requisite: `enableQresync()` returned true once on the session.\n * If the server doesn't support QRESYNC, fall back to the older\n * `fetchMessagesSinceUid` / set-diff path. */\n async resyncFolder(\n mailbox: string,\n uidValidity: number,\n modSeq: number,\n ): Promise<{\n uidValidityChanged: boolean;\n vanishedUids: number[];\n changedMessages: FetchedMessage[];\n newHighestModSeq: number | undefined;\n exists: number;\n uidNext: number;\n }> {\n await this.ensureConnected();\n const result = await this.native.select(mailbox, { uidValidity, modSeq });\n const changedMessages = result.changedMessages.map(m => new FetchedMessage(m));\n return {\n uidValidityChanged: result.uidValidityChanged,\n vanishedUids: result.vanishedUids,\n changedMessages,\n newHighestModSeq: result.highestModSeq,\n exists: result.exists,\n uidNext: result.uidNext,\n };\n }\n\n /** Watch a mailbox for new messages (IDLE). Optionally engage RFC 5465\n * NOTIFY so the server also pushes STATUS responses for non-selected\n * mailboxes named in `opts.notifySpec` \u2014 `opts.onMailboxStatus` fires\n * for each. Capability check is the caller's responsibility; pass\n * notifySpec only when `getCapabilities().has(\"NOTIFY\")`. */\n async watchMailbox(\n mailbox: string,\n onNew: (count: number) => void,\n opts?: {\n notifySpec?: string;\n onMailboxStatus?: (mailbox: string, data: proto.StatusData) => void;\n onExpunge?: () => void;\n },\n ): Promise<() => Promise<void>> {\n await this.ensureConnected();\n await this.native.select(mailbox);\n if (opts?.onMailboxStatus) this.native.onMailboxStatus = opts.onMailboxStatus;\n if (opts?.notifySpec) await this.native.notify(opts.notifySpec);\n return this.native.startIdle(onNew, opts?.onExpunge);\n }\n\n /** Copy a message to another server (cross-account) */\n async moveMessageToServer(msg: any, fromMailbox: string, targetClient: CompatImapClient, toMailbox: string): Promise<void> {\n // Fetch source, append to target, delete from source\n await this.ensureConnected();\n await this.native.select(fromMailbox);\n const fetched = await this.native.fetchMessage(msg.uid, { source: true });\n if (!fetched || !fetched.source) throw new Error(`Message UID ${msg.uid} not found`);\n\n await targetClient.ensureConnected();\n await targetClient.native.appendMessage(toMailbox, fetched.source, [...fetched.flags]);\n await this.native.deleteMessage(msg.uid);\n await this.native.closeMailbox();\n }\n\n /** Rename a mailbox (via native access) */\n async renameMailbox(from: string, to: string): Promise<void> {\n await this.ensureConnected();\n await this.native.renameMailbox(from, to);\n }\n\n /** Delete a mailbox */\n async deleteMailbox(name: string): Promise<void> {\n await this.ensureConnected();\n await this.native.deleteMailbox(name);\n }\n\n /** Get flags for a UID \u2014 returns string[] for compatibility with old client */\n async getFlags(mailbox: string, uid: number): Promise<string[]> {\n await this.ensureConnected();\n await this.native.select(mailbox);\n const msg = await this.native.fetchMessage(uid, { source: false });\n await this.native.closeMailbox();\n return msg?.flags ? [...msg.flags] : [];\n }\n}\n\nfunction formatDate(d: Date): string {\n const months = [\"Jan\", \"Feb\", \"Mar\", \"Apr\", \"May\", \"Jun\", \"Jul\", \"Aug\", \"Sep\", \"Oct\", \"Nov\", \"Dec\"];\n return `${d.getDate()}-${months[d.getMonth()]}-${d.getFullYear()}`;\n}\n", "/**\n * IMAP web provider \u2014 implements MailProvider using CompatImapClient + BridgeTransport.\n * Used for non-Gmail accounts on Android/WebView where Node.js isn't available.\n *\n * The native shell (MAUI) exposes TCP via window._nativeBridge.tcp.*; we alias it\n * to window.msgapi in initAndroid() because iflow-direct's BridgeTransport expects\n * that global name.\n *\n * Includes automatic retry on broken pipe / connection errors: if an operation fails\n * with a connection-related error, we create a fresh client and retry once.\n */\n\nimport { CompatImapClient, BridgeTransport, type ImapClientConfig, type TransportFactory } from \"@bobfrankston/iflow-direct\";\nimport type { MailProvider, ProviderFolder, ProviderMessage, FetchOptions } from \"./provider-types.js\";\n\n/**\n * Convert a NativeFolder (from iflow-direct) into a ProviderFolder,\n * detecting special-use from the IMAP flags.\n */\nfunction toProviderFolder(f: { path: string; delimiter: string; flags: string[] }, special: Record<string, string | undefined>): ProviderFolder {\n const flagsLower = (f.flags || []).map(x => x.toLowerCase());\n let specialUse = \"\";\n if (f.path === special.inbox || flagsLower.includes(\"\\\\inbox\") || f.path.toUpperCase() === \"INBOX\") specialUse = \"inbox\";\n else if (f.path === special.sent || flagsLower.includes(\"\\\\sent\")) specialUse = \"sent\";\n else if (f.path === special.trash || flagsLower.includes(\"\\\\trash\")) specialUse = \"trash\";\n else if (f.path === special.drafts || flagsLower.includes(\"\\\\drafts\")) specialUse = \"drafts\";\n else if (f.path === special.spam || f.path === special.junk || flagsLower.includes(\"\\\\junk\")) specialUse = \"junk\";\n else if (f.path === special.archive || flagsLower.includes(\"\\\\archive\")) specialUse = \"archive\";\n\n // Leaf name = last path segment after delimiter\n const leaf = f.delimiter ? f.path.split(f.delimiter).pop() || f.path : f.path;\n\n return {\n path: f.path,\n name: leaf,\n delimiter: f.delimiter || \"/\",\n specialUse,\n flags: f.flags || [],\n };\n}\n\nfunction toProviderMessage(m: any): ProviderMessage {\n return {\n uid: m.uid,\n messageId: m.messageId || \"\",\n providerId: \"\",\n date: m.date || null,\n subject: m.subject || \"\",\n from: m.from || [],\n to: m.to || [],\n cc: m.cc || [],\n seen: !!m.seen,\n flagged: !!m.flagged,\n answered: !!m.answered,\n draft: !!m.draft,\n size: m.size || 0,\n source: m.source || \"\",\n };\n}\n\n/** Check if an error is a connection/broken-pipe error worth retrying */\nfunction isConnectionError(e: any): boolean {\n const msg = (e?.message || \"\").toLowerCase();\n return msg.includes(\"broken pipe\") || msg.includes(\"not connected\") ||\n msg.includes(\"connection\") || msg.includes(\"socket\") ||\n msg.includes(\"timeout\") || msg.includes(\"econnreset\") ||\n msg.includes(\"epipe\") || msg.includes(\"closed\");\n}\n\nexport class ImapWebProvider implements MailProvider {\n private client: CompatImapClient;\n private config: ImapClientConfig;\n private transportFactory: TransportFactory;\n private specialFolders: Record<string, string | undefined> = {};\n private folderListCache: ProviderFolder[] | null = null;\n\n constructor(config: ImapClientConfig, transportFactory?: () => any) {\n this.config = config;\n this.transportFactory = transportFactory || (() => new BridgeTransport());\n this.client = new CompatImapClient(config, this.transportFactory);\n }\n\n /** Create a fresh client (after broken pipe / connection error) */\n private reconnect(): void {\n console.log(\"[imap-web] reconnecting after connection error\");\n try { this.client.logout(); } catch { /* ignore */ }\n this.client = new CompatImapClient(this.config, this.transportFactory);\n }\n\n /** Run an operation with one retry on connection error */\n private async withRetry<T>(op: () => Promise<T>, label: string): Promise<T> {\n try {\n return await op();\n } catch (e: any) {\n if (isConnectionError(e)) {\n console.warn(`[imap-web] ${label}: ${e.message} \u2014 reconnecting and retrying`);\n this.reconnect();\n return await op();\n }\n throw e;\n }\n }\n\n async listFolders(): Promise<ProviderFolder[]> {\n const native = await this.withRetry(() => this.client.getFolderList(), \"listFolders\");\n const special = this.client.getSpecialFolders(native);\n this.specialFolders = special as any;\n const result = native.map(f => toProviderFolder(f, this.specialFolders));\n this.folderListCache = result;\n return result;\n }\n\n async fetchSince(folder: string, sinceUid: number, options?: FetchOptions): Promise<ProviderMessage[]> {\n const msgs = await this.withRetry(\n () => this.client.fetchMessagesSinceUid(folder, sinceUid, { source: !!options?.source }),\n `fetchSince(${folder})`\n );\n return msgs.map(toProviderMessage);\n }\n\n async fetchByDate(folder: string, since: Date, before: Date, options?: FetchOptions,\n onChunk?: (msgs: ProviderMessage[]) => void): Promise<ProviderMessage[]> {\n const wrappedChunk = onChunk ? (raw: any[]) => onChunk(raw.map(toProviderMessage)) : undefined;\n const msgs = await this.withRetry(\n () => this.client.fetchMessageByDate(folder, since, before, { source: !!options?.source }, wrappedChunk),\n `fetchByDate(${folder})`\n );\n return msgs.map(toProviderMessage);\n }\n\n async fetchByUids(folder: string, uids: number[], options?: FetchOptions): Promise<ProviderMessage[]> {\n if (!uids.length) return [];\n const range = uids.join(\",\");\n const msgs = await this.withRetry(\n () => this.client.fetchMessages(folder, range, { source: !!options?.source }),\n `fetchByUids(${folder})`\n );\n return msgs.map(toProviderMessage);\n }\n\n async fetchOne(folder: string, uid: number, options?: FetchOptions): Promise<ProviderMessage | null> {\n const msg = await this.withRetry(\n () => this.client.fetchMessageByUid(folder, uid, { source: !!options?.source }),\n `fetchOne(${folder}/${uid})`\n );\n return msg ? toProviderMessage(msg) : null;\n }\n\n async getUids(folder: string): Promise<number[]> {\n return this.withRetry(() => this.client.getUids(folder), `getUids(${folder})`);\n }\n\n async close(): Promise<void> {\n try { await this.client.logout(); } catch { /* ignore */ }\n }\n}\n", "/**\n * Direct SMTP client \u2014 transport-agnostic, mirrors iflow-direct's structure.\n *\n * Implements RFC 5321 (SMTP), RFC 3207 (STARTTLS), RFC 4954 (AUTH),\n * RFC 4616 (PLAIN), RFC 4752 (XOAUTH2 \u2014 Google's variant).\n *\n * No Node.js dependencies. Caller injects an ImapTransport (the iflow-direct\n * transport interface \u2014 same TCP byte-stream abstraction works for SMTP):\n * - Desktop: NodeTransport from @bobfrankston/iflow-node\n * - Browser/WebView: BridgeTransport from @bobfrankston/iflow-direct\n *\n * Only one command at a time per connection (SMTP is synchronous).\n */\n\nimport type { TcpTransport, TransportFactory } from \"@bobfrankston/tcp-transport\";\nimport type {\n SmtpAuth, SmtpClientConfig, SmtpEnvelope,\n SmtpResponse, SmtpSendResult, SmtpRejectedRecipient,\n} from \"./types.js\";\n\nexport class SmtpClient {\n private transport: TcpTransport;\n private config: Required<Omit<SmtpClientConfig, \"auth\" | \"secure\">> & Pick<SmtpClientConfig, \"auth\" | \"secure\">;\n private buffer = \"\";\n private capabilities = new Set<string>();\n private _connected = false;\n private pending: {\n resolve: (resp: SmtpResponse) => void;\n reject: (err: Error) => void;\n timer: ReturnType<typeof setTimeout> | null;\n } | null = null;\n\n constructor(config: SmtpClientConfig, transportFactory: TransportFactory) {\n this.config = {\n host: config.host,\n port: config.port,\n secure: config.secure,\n auth: config.auth,\n localname: config.localname || \"localhost\",\n timeoutMs: config.timeoutMs ?? 30000,\n verbose: config.verbose || false,\n };\n this.transport = transportFactory();\n }\n\n get connected(): boolean { return this._connected; }\n get extensions(): Set<string> { return new Set(this.capabilities); }\n\n /** Connect, EHLO, STARTTLS if needed, AUTH if configured. */\n async connect(): Promise<void> {\n const useTls = this.config.secure ?? (this.config.port === 465);\n\n this.transport.onData((data) => this.handleData(data));\n this.transport.onClose(() => {\n this._connected = false;\n this.failPending(new Error(\"SMTP connection closed\"));\n });\n this.transport.onError((err) => {\n if (this.config.verbose) console.error(` [smtp] transport error: ${err.message}`);\n this.failPending(err);\n });\n\n await this.transport.connect(this.config.host, this.config.port, useTls, this.config.host);\n this._connected = true;\n\n // Server greeting (220 ...)\n const greeting = await this.readResponse();\n if (greeting.code !== 220) throw new Error(`SMTP greeting failed: ${greeting.code} ${greeting.text}`);\n\n await this.ehlo();\n\n // STARTTLS upgrade if not already TLS and server supports it.\n if (!useTls && this.capabilities.has(\"STARTTLS\")) {\n const r = await this.command(\"STARTTLS\");\n if (r.code !== 220) throw new Error(`STARTTLS failed: ${r.code} ${r.text}`);\n await this.transport.upgradeTLS(this.config.host);\n // Re-issue EHLO after TLS \u2014 capabilities can change post-handshake (notably AUTH appears).\n await this.ehlo();\n }\n\n if (this.config.auth) {\n await this.authenticate(this.config.auth);\n }\n }\n\n /** Send one message. Envelope determines MAIL FROM / RCPT TO; raw is the full RFC 2822 message. */\n async sendMail(envelope: SmtpEnvelope, raw: string | Uint8Array): Promise<SmtpSendResult> {\n if (!this._connected) throw new Error(\"SMTP: not connected\");\n if (!envelope.from) throw new Error(\"SMTP: missing sender\");\n if (!envelope.to?.length) throw new Error(\"SMTP: no recipients\");\n\n // MAIL FROM\n const sizeHint = typeof raw === \"string\"\n ? new TextEncoder().encode(raw).byteLength\n : raw.byteLength;\n const sizeExt = this.capabilities.has(\"SIZE\") ? ` SIZE=${sizeHint}` : \"\";\n const mf = await this.command(`MAIL FROM:<${envelope.from}>${sizeExt}`);\n if (mf.code !== 250) throw new Error(`MAIL FROM rejected: ${mf.code} ${mf.text}`);\n\n // RCPT TO \u2014 collect per-recipient errors instead of failing whole send.\n const accepted: string[] = [];\n const rejected: SmtpRejectedRecipient[] = [];\n for (const addr of envelope.to) {\n const r = await this.command(`RCPT TO:<${addr}>`);\n if (r.code === 250 || r.code === 251) {\n accepted.push(addr);\n } else {\n rejected.push({ address: addr, code: r.code, message: r.text });\n if (this.config.verbose) console.error(` [smtp] RCPT rejected ${addr}: ${r.code} ${r.text}`);\n }\n }\n if (accepted.length === 0) {\n // No recipients accepted \u2014 RSET so the connection can be reused for next send.\n try { await this.command(\"RSET\"); } catch { /* ignore */ }\n throw new Error(`SMTP: all recipients rejected: ${rejected.map(r => `${r.address} (${r.code})`).join(\", \")}`);\n }\n\n // DATA \u2014 server says 354, then we stream the body and finish with \\r\\n.\\r\\n\n const data = await this.command(\"DATA\");\n if (data.code !== 354) throw new Error(`DATA rejected: ${data.code} ${data.text}`);\n\n const body = typeof raw === \"string\" ? raw : new TextDecoder().decode(raw);\n const stuffed = dotStuff(body);\n // Ensure body ends with CRLF before terminator\n const term = stuffed.endsWith(\"\\r\\n\") ? \".\\r\\n\" : \"\\r\\n.\\r\\n\";\n // Send body + terminator, then wait for the final 250\n await this.transport.write(stuffed + term);\n const resp = await this.readResponse();\n if (resp.code !== 250) throw new Error(`Message rejected after DATA: ${resp.code} ${resp.text}`);\n\n return { accepted, rejected, response: resp.text };\n }\n\n /** Polite shutdown. */\n async quit(): Promise<void> {\n if (!this._connected) return;\n try {\n // Best-effort; some servers close before sending 221.\n await Promise.race([\n this.command(\"QUIT\"),\n new Promise<void>((resolve) => setTimeout(resolve, 2000)) as Promise<any>,\n ]);\n } catch { /* ignore */ }\n try { this.transport.close(); } catch { /* ignore */ }\n this._connected = false;\n }\n\n /** Hard close \u2014 for tests / aborts. */\n close(): void {\n try { this.transport.close(); } catch { /* ignore */ }\n this._connected = false;\n this.failPending(new Error(\"SMTP closed\"));\n }\n\n // \u2500\u2500 Internals \u2500\u2500\n\n private async ehlo(): Promise<void> {\n const r = await this.command(`EHLO ${this.config.localname}`);\n if (r.code !== 250) {\n // Fallback to HELO for ancient servers without ESMTP.\n const helo = await this.command(`HELO ${this.config.localname}`);\n if (helo.code !== 250) throw new Error(`EHLO/HELO failed: ${r.code} ${r.text}`);\n this.capabilities.clear();\n return;\n }\n this.capabilities.clear();\n // EHLO body is keyword [SP params] per line, first line is greeting text.\n const lines = r.text.split(\"\\n\").slice(1); // skip greeting line\n for (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed) continue;\n const sp = trimmed.indexOf(\" \");\n const keyword = (sp < 0 ? trimmed : trimmed.substring(0, sp)).toUpperCase();\n this.capabilities.add(keyword);\n // AUTH advertises space-separated mechanisms \u2014 record each as `AUTH=<MECH>`.\n if (keyword === \"AUTH\" && sp > 0) {\n for (const mech of trimmed.substring(sp + 1).split(/\\s+/)) {\n if (mech) this.capabilities.add(`AUTH=${mech.toUpperCase()}`);\n }\n }\n }\n }\n\n private async authenticate(auth: SmtpAuth): Promise<void> {\n switch (auth.method) {\n case \"PLAIN\": {\n // RFC 4616: \\0username\\0password, base64-encoded.\n const token = b64utf8(`\\x00${auth.user}\\x00${auth.pass}`);\n const r = await this.command(`AUTH PLAIN ${token}`, /*sensitive*/ true);\n if (r.code !== 235) throw new Error(`AUTH PLAIN failed: ${r.code} ${r.text}`);\n return;\n }\n case \"LOGIN\": {\n // Two-step: server prompts 334 base64(\"Username:\") then 334 base64(\"Password:\").\n const r1 = await this.command(\"AUTH LOGIN\", true);\n if (r1.code !== 334) throw new Error(`AUTH LOGIN start failed: ${r1.code} ${r1.text}`);\n const r2 = await this.command(b64utf8(auth.user), true);\n if (r2.code !== 334) throw new Error(`AUTH LOGIN user rejected: ${r2.code} ${r2.text}`);\n const r3 = await this.command(b64utf8(auth.pass), true);\n if (r3.code !== 235) throw new Error(`AUTH LOGIN failed: ${r3.code} ${r3.text}`);\n return;\n }\n case \"XOAUTH2\": {\n // Google variant: user=<USER>\\x01auth=Bearer <TOKEN>\\x01\\x01\n const blob = b64utf8(`user=${auth.user}\\x01auth=Bearer ${auth.token}\\x01\\x01`);\n const r = await this.command(`AUTH XOAUTH2 ${blob}`, true);\n if (r.code === 235) return;\n // On failure server may emit 334 with a base64 JSON error and wait for an empty\n // continuation line before sending the final tagged 535. Send \"\" to flush, then\n // surface the original error text.\n if (r.code === 334) {\n try { await this.command(\"\"); } catch { /* ignore */ }\n throw new Error(`AUTH XOAUTH2 failed`);\n }\n throw new Error(`AUTH XOAUTH2 failed: ${r.code} ${r.text}`);\n }\n }\n }\n\n /** Send one command and await the next response. Sensitive=true redacts the log line. */\n private command(line: string, sensitive = false): Promise<SmtpResponse> {\n if (this.config.verbose) {\n console.log(` [smtp] > ${sensitive ? \"<redacted>\" : line}`);\n }\n const writeP = this.transport.write(`${line}\\r\\n`);\n const respP = this.readResponse();\n return writeP.then(() => respP);\n }\n\n private readResponse(): Promise<SmtpResponse> {\n return new Promise((resolve, reject) => {\n if (this.pending) {\n reject(new Error(\"SMTP: previous command still pending\"));\n return;\n }\n const timer = setTimeout(() => {\n this.pending = null;\n try { this.transport.close(); } catch { /* ignore */ }\n reject(new Error(`SMTP inactivity timeout (${this.config.timeoutMs}ms)`));\n }, this.config.timeoutMs);\n this.pending = {\n resolve: (resp) => { if (timer) clearTimeout(timer); resolve(resp); },\n reject: (err) => { if (timer) clearTimeout(timer); reject(err); },\n timer,\n };\n // Drain anything that might already be in the buffer (e.g. greeting on connect).\n this.tryParseResponse();\n });\n }\n\n private handleData(data: Uint8Array): void {\n // SMTP responses are 7-bit ASCII per RFC 5321 \u2014 UTF-8 decode is a\n // superset and produces the same characters. Decode each chunk\n // once on receipt; the parser stays string-based since SMTP has no\n // literal-style framing where byte fidelity matters.\n this.buffer += this.utf8Decoder.decode(data);\n this.tryParseResponse();\n }\n private utf8Decoder = new TextDecoder(\"utf-8\");\n\n /** SMTP multi-line replies: each intermediate line \"NNN-TEXT\", final \"NNN TEXT\".\n * Pulls one complete response off the buffer if available and resolves the\n * pending command. */\n private tryParseResponse(): void {\n if (!this.pending) return;\n // Find the boundary \u2014 a line whose 4th char is \" \" (space, not \"-\").\n const lines: string[] = [];\n let consumed = 0;\n let code = 0;\n const buf = this.buffer;\n let pos = 0;\n while (true) {\n const eol = buf.indexOf(\"\\r\\n\", pos);\n if (eol < 0) return; // wait for more data\n const line = buf.substring(pos, eol);\n lines.push(line);\n pos = eol + 2;\n if (line.length >= 4) {\n const codeStr = line.substring(0, 3);\n const sep = line.charAt(3);\n if (/^\\d{3}$/.test(codeStr)) {\n if (sep === \" \" || sep === \"\") {\n code = parseInt(codeStr);\n consumed = pos;\n break;\n } else if (sep !== \"-\") {\n // Malformed \u2014 consume what we have and surface as code 0.\n consumed = pos;\n break;\n }\n } else {\n // Not an SMTP-shaped line \u2014 bail and surface as 0.\n consumed = pos;\n break;\n }\n }\n }\n\n const raw = buf.substring(0, consumed);\n this.buffer = buf.substring(consumed);\n\n const text = lines.map(l => l.length >= 4 ? l.substring(4) : l).join(\"\\n\");\n if (this.config.verbose) {\n console.log(` [smtp] < ${code} ${text.split(\"\\n\").join(\" / \")}`);\n }\n\n const p = this.pending;\n this.pending = null;\n p.resolve({ code, text, raw });\n\n // If more data is buffered, schedule another parse pass \u2014 caller may already\n // have queued the next readResponse.\n if (this.buffer.length > 0) {\n queueMicrotask(() => this.tryParseResponse());\n }\n }\n\n private failPending(err: Error): void {\n if (!this.pending) return;\n const p = this.pending;\n this.pending = null;\n p.reject(err);\n }\n}\n\n/** RFC 5321 \u00A74.5.2 dot-stuffing: any line beginning with \".\" gets a leading \".\"\n * prepended so it doesn't terminate DATA prematurely. Operates on CRLF or LF\n * line endings; output is normalized to CRLF. */\nexport function dotStuff(body: string): string {\n // Normalize CRLF \u2014 leave existing CRLF alone; convert lone LF to CRLF.\n const normalized = body.replace(/\\r?\\n/g, \"\\r\\n\");\n // Insert \".\" before any line starting with \".\"\n return normalized.replace(/(^|\\r\\n)\\./g, \"$1..\");\n}\n\n/** UTF-8-safe base64 (avoids the latin-1 limitation of bare btoa). */\nfunction b64utf8(s: string): string {\n if (typeof Buffer !== \"undefined\" && Buffer.from) {\n return Buffer.from(s, \"utf-8\").toString(\"base64\");\n }\n // Browser path\n const bytes = new TextEncoder().encode(s);\n let bin = \"\";\n for (let i = 0; i < bytes.length; i++) bin += String.fromCharCode(bytes[i]);\n return btoa(bin);\n}\n"],
|
|
5
|
-
"mappings": "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gBAAeA,gBAAe,IAAI,IAAI,EAAE,IAAI;AAC5C,MAAAA,gBAAeA,gBAAe,IAAI,IAAI,EAAE,IAAI;AAC5C,MAAAA,gBAAeA,gBAAe,IAAI,IAAI,EAAE,IAAI;AAC5C,MAAAA,gBAAeA,gBAAe,IAAI,IAAI,EAAE,IAAI;AAC5C,MAAAA,gBAAeA,gBAAe,IAAI,IAAI,EAAE,IAAI;AAC5C,MAAAA,gBAAeA,gBAAe,IAAI,IAAI,EAAE,IAAI;AAC5C,MAAAA,gBAAeA,gBAAe,IAAI,IAAI,EAAE,IAAI;AAC5C,MAAAA,gBAAeA,gBAAe,IAAI,IAAI,EAAE,IAAI;AAC5C,MAAAA,gBAAeA,gBAAe,IAAI,IAAI,EAAE,IAAI;AAC5C,MAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,MAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,MAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,MAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,MAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,MAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,MAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,MAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,MAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,MAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,MAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,MAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,MAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,MAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,MAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,MAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,MAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,MAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,MAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,MAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,MAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,MAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,MAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,MAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,MAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,MAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,MAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,MAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,MAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,MAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,MAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,MAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,MAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,MAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,MAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,MAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,MAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,MAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,MAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,MAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,MAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,MAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,MAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,MAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,MAAAA,gBAAeA,gBAAe,GA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",
|
|
4
|
+
"sourcesContent": ["\n// We are modularizing this manually because the current modularize setting in Emscripten has some issues:\n// https://github.com/kripken/emscripten/issues/5820\n// In addition, When you use emcc's modularization, it still expects to export a global object called `Module`,\n// which is able to be used/called before the WASM is loaded.\n// The modularization below exports a promise that loads and resolves to the actual sql.js module.\n// That way, this module can't be used before the WASM is finished loading.\n\n// We are going to define a function that a user will call to start loading initializing our Sql.js library\n// However, that function might be called multiple times, and on subsequent calls, we don't actually want it to instantiate a new instance of the Module\n// Instead, we want to return the previously loaded module\n\n// TODO: Make this not declare a global if used in the browser\nvar initSqlJsPromise = undefined;\n\nvar initSqlJs = function (moduleConfig) {\n\n if (initSqlJsPromise){\n return initSqlJsPromise;\n }\n // If we're here, we've never called this function before\n initSqlJsPromise = new Promise(function (resolveModule, reject) {\n\n // We are modularizing this manually because the current modularize setting in Emscripten has some issues:\n // https://github.com/kripken/emscripten/issues/5820\n\n // The way to affect the loading of emcc compiled modules is to create a variable called `Module` and add\n // properties to it, like `preRun`, `postRun`, etc\n // We are using that to get notified when the WASM has finished loading.\n // Only then will we return our promise\n\n // If they passed in a moduleConfig object, use that\n // Otherwise, initialize Module to the empty object\n var Module = typeof moduleConfig !== 'undefined' ? moduleConfig : {};\n\n // EMCC only allows for a single onAbort function (not an array of functions)\n // So if the user defined their own onAbort function, we remember it and call it\n var originalOnAbortFunction = Module['onAbort'];\n Module['onAbort'] = function (errorThatCausedAbort) {\n reject(new Error(errorThatCausedAbort));\n if (originalOnAbortFunction){\n originalOnAbortFunction(errorThatCausedAbort);\n }\n };\n\n Module['postRun'] = Module['postRun'] || [];\n Module['postRun'].push(function () {\n // When Emscripted calls postRun, this promise resolves with the built Module\n resolveModule(Module);\n });\n\n // There is a section of code in the emcc-generated code below that looks like this:\n // (Note that this is lowercase `module`)\n // if (typeof module !== 'undefined') {\n // module['exports'] = Module;\n // }\n // When that runs, it's going to overwrite our own modularization export efforts in shell-post.js!\n // The only way to tell emcc not to emit it is to pass the MODULARIZE=1 or MODULARIZE_INSTANCE=1 flags,\n // but that carries with it additional unnecessary baggage/bugs we don't want either.\n // So, we have three options:\n // 1) We undefine `module`\n // 2) We remember what `module['exports']` was at the beginning of this function and we restore it later\n // 3) We write a script to remove those lines of code as part of the Make process.\n //\n // Since those are the only lines of code that care about module, we will undefine it. It's the most straightforward\n // of the options, and has the side effect of reducing emcc's efforts to modify the module if its output were to change in the future.\n // That's a nice side effect since we're handling the modularization efforts ourselves\n module = undefined;\n\n // The emcc-generated code and shell-post.js code goes below,\n // meaning that all of it runs inside of this promise. If anything throws an exception, our promise will abort\nvar k;k||=typeof Module != 'undefined' ? Module : {};var aa=!!globalThis.window,ba=!!globalThis.WorkerGlobalScope;\nk.onRuntimeInitialized=function(){function a(f,l){switch(typeof l){case \"boolean\":$b(f,l?1:0);break;case \"number\":ac(f,l);break;case \"string\":bc(f,l,-1,-1);break;case \"object\":if(null===l)eb(f);else if(null!=l.length){var n=ca(l.length);m.set(l,n);cc(f,n,l.length,-1);da(n)}else ra(f,\"Wrong API use : tried to return a value of an unknown type (\"+l+\").\",-1);break;default:eb(f)}}function b(f,l){for(var n=[],p=0;p<f;p+=1){var u=r(l+4*p,\"i32\"),v=dc(u);if(1===v||2===v)u=ec(u);else if(3===v)u=fc(u);else if(4===\nv){v=u;u=gc(v);v=hc(v);for(var K=new Uint8Array(u),I=0;I<u;I+=1)K[I]=m[v+I];u=K}else u=null;n.push(u)}return n}function c(f,l){this.Qa=f;this.db=l;this.Oa=1;this.yb=[]}function d(f,l){this.db=l;this.ob=ea(f);if(null===this.ob)throw Error(\"Unable to allocate memory for the SQL string\");this.ub=this.ob;this.gb=this.Fb=null}function e(f){this.filename=\"dbfile_\"+(4294967295*Math.random()>>>0);if(null!=f){var l=this.filename,n=\"/\",p=l;n&&(n=\"string\"==typeof n?n:fa(n),p=l?ha(n+\"/\"+l):n);l=ia(!0,!0);p=ja(p,\nl);if(f){if(\"string\"==typeof f){n=Array(f.length);for(var u=0,v=f.length;u<v;++u)n[u]=f.charCodeAt(u);f=n}ka(p,l|146);n=la(p,577);ma(n,f,0,f.length,0);na(n);ka(p,l)}}this.handleError(q(this.filename,g));this.db=r(g,\"i32\");hb(this.db);this.pb={};this.Sa={}}var g=y(4),h=k.cwrap,q=h(\"sqlite3_open\",\"number\",[\"string\",\"number\"]),w=h(\"sqlite3_close_v2\",\"number\",[\"number\"]),t=h(\"sqlite3_exec\",\"number\",[\"number\",\"string\",\"number\",\"number\",\"number\"]),x=h(\"sqlite3_changes\",\"number\",[\"number\"]),D=h(\"sqlite3_prepare_v2\",\n\"number\",[\"number\",\"string\",\"number\",\"number\",\"number\"]),ib=h(\"sqlite3_sql\",\"string\",[\"number\"]),jc=h(\"sqlite3_normalized_sql\",\"string\",[\"number\"]),jb=h(\"sqlite3_prepare_v2\",\"number\",[\"number\",\"number\",\"number\",\"number\",\"number\"]),kc=h(\"sqlite3_bind_text\",\"number\",[\"number\",\"number\",\"number\",\"number\",\"number\"]),kb=h(\"sqlite3_bind_blob\",\"number\",[\"number\",\"number\",\"number\",\"number\",\"number\"]),lc=h(\"sqlite3_bind_double\",\"number\",[\"number\",\"number\",\"number\"]),mc=h(\"sqlite3_bind_int\",\"number\",[\"number\",\n\"number\",\"number\"]),nc=h(\"sqlite3_bind_parameter_index\",\"number\",[\"number\",\"string\"]),oc=h(\"sqlite3_step\",\"number\",[\"number\"]),pc=h(\"sqlite3_errmsg\",\"string\",[\"number\"]),qc=h(\"sqlite3_column_count\",\"number\",[\"number\"]),rc=h(\"sqlite3_data_count\",\"number\",[\"number\"]),sc=h(\"sqlite3_column_double\",\"number\",[\"number\",\"number\"]),lb=h(\"sqlite3_column_text\",\"string\",[\"number\",\"number\"]),tc=h(\"sqlite3_column_blob\",\"number\",[\"number\",\"number\"]),uc=h(\"sqlite3_column_bytes\",\"number\",[\"number\",\"number\"]),vc=h(\"sqlite3_column_type\",\n\"number\",[\"number\",\"number\"]),wc=h(\"sqlite3_column_name\",\"string\",[\"number\",\"number\"]),xc=h(\"sqlite3_reset\",\"number\",[\"number\"]),yc=h(\"sqlite3_clear_bindings\",\"number\",[\"number\"]),zc=h(\"sqlite3_finalize\",\"number\",[\"number\"]),mb=h(\"sqlite3_create_function_v2\",\"number\",\"number string number number number number number number number\".split(\" \")),dc=h(\"sqlite3_value_type\",\"number\",[\"number\"]),gc=h(\"sqlite3_value_bytes\",\"number\",[\"number\"]),fc=h(\"sqlite3_value_text\",\"string\",[\"number\"]),hc=h(\"sqlite3_value_blob\",\n\"number\",[\"number\"]),ec=h(\"sqlite3_value_double\",\"number\",[\"number\"]),ac=h(\"sqlite3_result_double\",\"\",[\"number\",\"number\"]),eb=h(\"sqlite3_result_null\",\"\",[\"number\"]),bc=h(\"sqlite3_result_text\",\"\",[\"number\",\"string\",\"number\",\"number\"]),cc=h(\"sqlite3_result_blob\",\"\",[\"number\",\"number\",\"number\",\"number\"]),$b=h(\"sqlite3_result_int\",\"\",[\"number\",\"number\"]),ra=h(\"sqlite3_result_error\",\"\",[\"number\",\"string\",\"number\"]),nb=h(\"sqlite3_aggregate_context\",\"number\",[\"number\",\"number\"]),hb=h(\"RegisterExtensionFunctions\",\n\"number\",[\"number\"]),ob=h(\"sqlite3_update_hook\",\"number\",[\"number\",\"number\",\"number\"]);c.prototype.bind=function(f){if(!this.Qa)throw\"Statement closed\";this.reset();return Array.isArray(f)?this.Wb(f):null!=f&&\"object\"===typeof f?this.Xb(f):!0};c.prototype.step=function(){if(!this.Qa)throw\"Statement closed\";this.Oa=1;var f=oc(this.Qa);switch(f){case 100:return!0;case 101:return!1;default:throw this.db.handleError(f);}};c.prototype.Pb=function(f){null==f&&(f=this.Oa,this.Oa+=1);return sc(this.Qa,f)};\nc.prototype.hc=function(f){null==f&&(f=this.Oa,this.Oa+=1);f=lb(this.Qa,f);if(\"function\"!==typeof BigInt)throw Error(\"BigInt is not supported\");return BigInt(f)};c.prototype.mc=function(f){null==f&&(f=this.Oa,this.Oa+=1);return lb(this.Qa,f)};c.prototype.getBlob=function(f){null==f&&(f=this.Oa,this.Oa+=1);var l=uc(this.Qa,f);f=tc(this.Qa,f);for(var n=new Uint8Array(l),p=0;p<l;p+=1)n[p]=m[f+p];return n};c.prototype.get=function(f,l){l=l||{};null!=f&&this.bind(f)&&this.step();f=[];for(var n=rc(this.Qa),\np=0;p<n;p+=1)switch(vc(this.Qa,p)){case 1:var u=l.useBigInt?this.hc(p):this.Pb(p);f.push(u);break;case 2:f.push(this.Pb(p));break;case 3:f.push(this.mc(p));break;case 4:f.push(this.getBlob(p));break;default:f.push(null)}return f};c.prototype.Db=function(){for(var f=[],l=qc(this.Qa),n=0;n<l;n+=1)f.push(wc(this.Qa,n));return f};c.prototype.Ob=function(f,l){f=this.get(f,l);l=this.Db();for(var n={},p=0;p<l.length;p+=1)n[l[p]]=f[p];return n};c.prototype.lc=function(){return ib(this.Qa)};c.prototype.ic=\nfunction(){return jc(this.Qa)};c.prototype.Jb=function(f){null!=f&&this.bind(f);this.step();return this.reset()};c.prototype.Lb=function(f,l){null==l&&(l=this.Oa,this.Oa+=1);f=ea(f);this.yb.push(f);this.db.handleError(kc(this.Qa,l,f,-1,0))};c.prototype.Vb=function(f,l){null==l&&(l=this.Oa,this.Oa+=1);var n=ca(f.length);m.set(f,n);this.yb.push(n);this.db.handleError(kb(this.Qa,l,n,f.length,0))};c.prototype.Kb=function(f,l){null==l&&(l=this.Oa,this.Oa+=1);this.db.handleError((f===(f|0)?mc:lc)(this.Qa,\nl,f))};c.prototype.Yb=function(f){null==f&&(f=this.Oa,this.Oa+=1);kb(this.Qa,f,0,0,0)};c.prototype.Mb=function(f,l){null==l&&(l=this.Oa,this.Oa+=1);switch(typeof f){case \"string\":this.Lb(f,l);return;case \"number\":this.Kb(f,l);return;case \"bigint\":this.Lb(f.toString(),l);return;case \"boolean\":this.Kb(f+0,l);return;case \"object\":if(null===f){this.Yb(l);return}if(null!=f.length){this.Vb(f,l);return}}throw\"Wrong API use : tried to bind a value of an unknown type (\"+f+\").\";};c.prototype.Xb=function(f){var l=\nthis;Object.keys(f).forEach(function(n){var p=nc(l.Qa,n);0!==p&&l.Mb(f[n],p)});return!0};c.prototype.Wb=function(f){for(var l=0;l<f.length;l+=1)this.Mb(f[l],l+1);return!0};c.prototype.reset=function(){this.Cb();return 0===yc(this.Qa)&&0===xc(this.Qa)};c.prototype.Cb=function(){for(var f;void 0!==(f=this.yb.pop());)da(f)};c.prototype.cb=function(){this.Cb();var f=0===zc(this.Qa);delete this.db.pb[this.Qa];this.Qa=0;return f};d.prototype.next=function(){if(null===this.ob)return{done:!0};null!==this.gb&&\n(this.gb.cb(),this.gb=null);if(!this.db.db)throw this.Ab(),Error(\"Database closed\");var f=oa(),l=y(4);pa(g);pa(l);try{this.db.handleError(jb(this.db.db,this.ub,-1,g,l));this.ub=r(l,\"i32\");var n=r(g,\"i32\");if(0===n)return this.Ab(),{done:!0};this.gb=new c(n,this.db);this.db.pb[n]=this.gb;return{value:this.gb,done:!1}}catch(p){throw this.Fb=z(this.ub),this.Ab(),p;}finally{qa(f)}};d.prototype.Ab=function(){da(this.ob);this.ob=null};d.prototype.jc=function(){return null!==this.Fb?this.Fb:z(this.ub)};\n\"function\"===typeof Symbol&&\"symbol\"===typeof Symbol.iterator&&(d.prototype[Symbol.iterator]=function(){return this});e.prototype.Jb=function(f,l){if(!this.db)throw\"Database closed\";if(l){f=this.Gb(f,l);try{f.step()}finally{f.cb()}}else this.handleError(t(this.db,f,0,0,g));return this};e.prototype.exec=function(f,l,n){if(!this.db)throw\"Database closed\";var p=null,u=null,v=null;try{v=u=ea(f);var K=y(4);for(f=[];0!==r(v,\"i8\");){pa(g);pa(K);this.handleError(jb(this.db,v,-1,g,K));var I=r(g,\"i32\");v=r(K,\n\"i32\");if(0!==I){var H=null;p=new c(I,this);for(null!=l&&p.bind(l);p.step();)null===H&&(H={columns:p.Db(),values:[]},f.push(H)),H.values.push(p.get(null,n));p.cb()}}return f}catch(L){throw p&&p.cb(),L;}finally{u&&da(u)}};e.prototype.ec=function(f,l,n,p,u){\"function\"===typeof l&&(p=n,n=l,l=void 0);f=this.Gb(f,l);try{for(;f.step();)n(f.Ob(null,u))}finally{f.cb()}if(\"function\"===typeof p)return p()};e.prototype.Gb=function(f,l){pa(g);this.handleError(D(this.db,f,-1,g,0));f=r(g,\"i32\");if(0===f)throw\"Nothing to prepare\";\nvar n=new c(f,this);null!=l&&n.bind(l);return this.pb[f]=n};e.prototype.pc=function(f){return new d(f,this)};e.prototype.fc=function(){Object.values(this.pb).forEach(function(l){l.cb()});Object.values(this.Sa).forEach(A);this.Sa={};this.handleError(w(this.db));var f=sa(this.filename);this.handleError(q(this.filename,g));this.db=r(g,\"i32\");hb(this.db);return f};e.prototype.close=function(){null!==this.db&&(Object.values(this.pb).forEach(function(f){f.cb()}),Object.values(this.Sa).forEach(A),this.Sa=\n{},this.fb&&(A(this.fb),this.fb=void 0),this.handleError(w(this.db)),ta(\"/\"+this.filename),this.db=null)};e.prototype.handleError=function(f){if(0===f)return null;f=pc(this.db);throw Error(f);};e.prototype.kc=function(){return x(this.db)};e.prototype.bc=function(f,l){Object.prototype.hasOwnProperty.call(this.Sa,f)&&(A(this.Sa[f]),delete this.Sa[f]);var n=ua(function(p,u,v){u=b(u,v);try{var K=l.apply(null,u)}catch(I){ra(p,I,-1);return}a(p,K)},\"viii\");this.Sa[f]=n;this.handleError(mb(this.db,f,l.length,\n1,0,n,0,0,0));return this};e.prototype.ac=function(f,l){var n=l.init||function(){return null},p=l.finalize||function(H){return H},u=l.step;if(!u)throw\"An aggregate function must have a step function in \"+f;var v={};Object.hasOwnProperty.call(this.Sa,f)&&(A(this.Sa[f]),delete this.Sa[f]);l=f+\"__finalize\";Object.hasOwnProperty.call(this.Sa,l)&&(A(this.Sa[l]),delete this.Sa[l]);var K=ua(function(H,L,Ka){var V=nb(H,1);Object.hasOwnProperty.call(v,V)||(v[V]=n());L=b(L,Ka);L=[v[V]].concat(L);try{v[V]=u.apply(null,\nL)}catch(Bc){delete v[V],ra(H,Bc,-1)}},\"viii\"),I=ua(function(H){var L=nb(H,1);try{var Ka=p(v[L])}catch(V){delete v[L];ra(H,V,-1);return}a(H,Ka);delete v[L]},\"vi\");this.Sa[f]=K;this.Sa[l]=I;this.handleError(mb(this.db,f,u.length-1,1,0,0,K,I,0));return this};e.prototype.vc=function(f){this.fb&&(ob(this.db,0,0),A(this.fb),this.fb=void 0);if(!f)return this;this.fb=ua(function(l,n,p,u,v){switch(n){case 18:l=\"insert\";break;case 23:l=\"update\";break;case 9:l=\"delete\";break;default:throw\"unknown operationCode in updateHook callback: \"+\nn;}p=z(p);u=z(u);if(v>Number.MAX_SAFE_INTEGER)throw\"rowId too big to fit inside a Number\";f(l,p,u,Number(v))},\"viiiij\");ob(this.db,this.fb,0);return this};c.prototype.bind=c.prototype.bind;c.prototype.step=c.prototype.step;c.prototype.get=c.prototype.get;c.prototype.getColumnNames=c.prototype.Db;c.prototype.getAsObject=c.prototype.Ob;c.prototype.getSQL=c.prototype.lc;c.prototype.getNormalizedSQL=c.prototype.ic;c.prototype.run=c.prototype.Jb;c.prototype.reset=c.prototype.reset;c.prototype.freemem=\nc.prototype.Cb;c.prototype.free=c.prototype.cb;d.prototype.next=d.prototype.next;d.prototype.getRemainingSQL=d.prototype.jc;e.prototype.run=e.prototype.Jb;e.prototype.exec=e.prototype.exec;e.prototype.each=e.prototype.ec;e.prototype.prepare=e.prototype.Gb;e.prototype.iterateStatements=e.prototype.pc;e.prototype[\"export\"]=e.prototype.fc;e.prototype.close=e.prototype.close;e.prototype.handleError=e.prototype.handleError;e.prototype.getRowsModified=e.prototype.kc;e.prototype.create_function=e.prototype.bc;\ne.prototype.create_aggregate=e.prototype.ac;e.prototype.updateHook=e.prototype.vc;k.Database=e};var va=\"./this.program\",wa=globalThis.document?.currentScript?.src;ba&&(wa=self.location.href);var xa=\"\",ya,za;\nif(aa||ba){try{xa=(new URL(\".\",wa)).href}catch{}ba&&(za=a=>{var b=new XMLHttpRequest;b.open(\"GET\",a,!1);b.responseType=\"arraybuffer\";b.send(null);return new Uint8Array(b.response)});ya=async a=>{a=await fetch(a,{credentials:\"same-origin\"});if(a.ok)return a.arrayBuffer();throw Error(a.status+\" : \"+a.url);}}var Aa=console.log.bind(console),B=console.error.bind(console),Ba,Ca=!1,Da,m,C,Ea,E,F,Fa,Ga,G;\nfunction Ha(){var a=Ia.buffer;m=new Int8Array(a);Ea=new Int16Array(a);C=new Uint8Array(a);new Uint16Array(a);E=new Int32Array(a);F=new Uint32Array(a);Fa=new Float32Array(a);Ga=new Float64Array(a);G=new BigInt64Array(a);new BigUint64Array(a)}function Ja(a){k.onAbort?.(a);a=\"Aborted(\"+a+\")\";B(a);Ca=!0;throw new WebAssembly.RuntimeError(a+\". Build with -sASSERTIONS for more info.\");}var La;\nasync function Ma(a){if(!Ba)try{var b=await ya(a);return new Uint8Array(b)}catch{}if(a==La&&Ba)a=new Uint8Array(Ba);else if(za)a=za(a);else throw\"both async and sync fetching of the wasm failed\";return a}async function Na(a,b){try{var c=await Ma(a);return await WebAssembly.instantiate(c,b)}catch(d){B(`failed to asynchronously prepare wasm: ${d}`),Ja(d)}}\nasync function Oa(a){var b=La;if(!Ba)try{var c=fetch(b,{credentials:\"same-origin\"});return await WebAssembly.instantiateStreaming(c,a)}catch(d){B(`wasm streaming compile failed: ${d}`),B(\"falling back to ArrayBuffer instantiation\")}return Na(b,a)}class Pa{name=\"ExitStatus\";constructor(a){this.message=`Program terminated with exit(${a})`;this.status=a}}var Qa=a=>{for(;0<a.length;)a.shift()(k)},Ra=[],Sa=[],Ta=()=>{var a=k.preRun.shift();Sa.push(a)},J=0,Ua=null;\nfunction r(a,b=\"i8\"){b.endsWith(\"*\")&&(b=\"*\");switch(b){case \"i1\":return m[a];case \"i8\":return m[a];case \"i16\":return Ea[a>>1];case \"i32\":return E[a>>2];case \"i64\":return G[a>>3];case \"float\":return Fa[a>>2];case \"double\":return Ga[a>>3];case \"*\":return F[a>>2];default:Ja(`invalid type for getValue: ${b}`)}}var Va=!0;\nfunction pa(a){var b=\"i32\";b.endsWith(\"*\")&&(b=\"*\");switch(b){case \"i1\":m[a]=0;break;case \"i8\":m[a]=0;break;case \"i16\":Ea[a>>1]=0;break;case \"i32\":E[a>>2]=0;break;case \"i64\":G[a>>3]=BigInt(0);break;case \"float\":Fa[a>>2]=0;break;case \"double\":Ga[a>>3]=0;break;case \"*\":F[a>>2]=0;break;default:Ja(`invalid type for setValue: ${b}`)}}\nvar Wa=new TextDecoder,Xa=(a,b,c,d)=>{c=b+c;if(d)return c;for(;a[b]&&!(b>=c);)++b;return b},z=(a,b,c)=>a?Wa.decode(C.subarray(a,Xa(C,a,b,c))):\"\",Ya=(a,b)=>{for(var c=0,d=a.length-1;0<=d;d--){var e=a[d];\".\"===e?a.splice(d,1):\"..\"===e?(a.splice(d,1),c++):c&&(a.splice(d,1),c--)}if(b)for(;c;c--)a.unshift(\"..\");return a},ha=a=>{var b=\"/\"===a.charAt(0),c=\"/\"===a.slice(-1);(a=Ya(a.split(\"/\").filter(d=>!!d),!b).join(\"/\"))||b||(a=\".\");a&&c&&(a+=\"/\");return(b?\"/\":\"\")+a},Za=a=>{var b=/^(\\/?|)([\\s\\S]*?)((?:\\.{1,2}|[^\\/]+?|)(\\.[^.\\/]*|))(?:[\\/]*)$/.exec(a).slice(1);\na=b[0];b=b[1];if(!a&&!b)return\".\";b&&=b.slice(0,-1);return a+b},$a=a=>a&&a.match(/([^\\/]+|\\/)\\/*$/)[1],ab=()=>a=>crypto.getRandomValues(a),bb=a=>{(bb=ab())(a)},cb=(...a)=>{for(var b=\"\",c=!1,d=a.length-1;-1<=d&&!c;d--){c=0<=d?a[d]:\"/\";if(\"string\"!=typeof c)throw new TypeError(\"Arguments to path.resolve must be strings\");if(!c)return\"\";b=c+\"/\"+b;c=\"/\"===c.charAt(0)}b=Ya(b.split(\"/\").filter(e=>!!e),!c).join(\"/\");return(c?\"/\":\"\")+b||\".\"},db=a=>{var b=Xa(a,0);return Wa.decode(a.buffer?a.subarray(0,b):\nnew Uint8Array(a.slice(0,b)))},fb=[],gb=a=>{for(var b=0,c=0;c<a.length;++c){var d=a.charCodeAt(c);127>=d?b++:2047>=d?b+=2:55296<=d&&57343>=d?(b+=4,++c):b+=3}return b},M=(a,b,c,d)=>{if(!(0<d))return 0;var e=c;d=c+d-1;for(var g=0;g<a.length;++g){var h=a.codePointAt(g);if(127>=h){if(c>=d)break;b[c++]=h}else if(2047>=h){if(c+1>=d)break;b[c++]=192|h>>6;b[c++]=128|h&63}else if(65535>=h){if(c+2>=d)break;b[c++]=224|h>>12;b[c++]=128|h>>6&63;b[c++]=128|h&63}else{if(c+3>=d)break;b[c++]=240|h>>18;b[c++]=128|\nh>>12&63;b[c++]=128|h>>6&63;b[c++]=128|h&63;g++}}b[c]=0;return c-e},pb=[];function qb(a,b){pb[a]={input:[],output:[],kb:b};rb(a,sb)}\nvar sb={open(a){var b=pb[a.node.nb];if(!b)throw new N(43);a.Va=b;a.seekable=!1},close(a){a.Va.kb.lb(a.Va)},lb(a){a.Va.kb.lb(a.Va)},read(a,b,c,d){if(!a.Va||!a.Va.kb.Qb)throw new N(60);for(var e=0,g=0;g<d;g++){try{var h=a.Va.kb.Qb(a.Va)}catch(q){throw new N(29);}if(void 0===h&&0===e)throw new N(6);if(null===h||void 0===h)break;e++;b[c+g]=h}e&&(a.node.$a=Date.now());return e},write(a,b,c,d){if(!a.Va||!a.Va.kb.Hb)throw new N(60);try{for(var e=0;e<d;e++)a.Va.kb.Hb(a.Va,b[c+e])}catch(g){throw new N(29);\n}d&&(a.node.Ua=a.node.Ta=Date.now());return e}},tb={Qb(){a:{if(!fb.length){var a=null;globalThis.window?.prompt&&(a=window.prompt(\"Input: \"),null!==a&&(a+=\"\\n\"));if(!a){var b=null;break a}b=Array(gb(a)+1);a=M(a,b,0,b.length);b.length=a;fb=b}b=fb.shift()}return b},Hb(a,b){null===b||10===b?(Aa(db(a.output)),a.output=[]):0!=b&&a.output.push(b)},lb(a){0<a.output?.length&&(Aa(db(a.output)),a.output=[])},Dc(){return{yc:25856,Ac:5,xc:191,zc:35387,wc:[3,28,127,21,4,0,1,0,17,19,26,0,18,15,23,22,0,0,0,0,0,\n0,0,0,0,0,0,0,0,0,0,0]}},Ec(){return 0},Fc(){return[24,80]}},ub={Hb(a,b){null===b||10===b?(B(db(a.output)),a.output=[]):0!=b&&a.output.push(b)},lb(a){0<a.output?.length&&(B(db(a.output)),a.output=[])}},O={Za:null,ab(){return O.createNode(null,\"/\",16895,0)},createNode(a,b,c,d){if(24576===(c&61440)||4096===(c&61440))throw new N(63);O.Za||(O.Za={dir:{node:{Wa:O.La.Wa,Xa:O.La.Xa,mb:O.La.mb,rb:O.La.rb,Tb:O.La.Tb,xb:O.La.xb,vb:O.La.vb,Ib:O.La.Ib,wb:O.La.wb},stream:{Ya:O.Ma.Ya}},file:{node:{Wa:O.La.Wa,Xa:O.La.Xa},\nstream:{Ya:O.Ma.Ya,read:O.Ma.read,write:O.Ma.write,sb:O.Ma.sb,tb:O.Ma.tb}},link:{node:{Wa:O.La.Wa,Xa:O.La.Xa,eb:O.La.eb},stream:{}},Nb:{node:{Wa:O.La.Wa,Xa:O.La.Xa},stream:vb}});c=wb(a,b,c,d);P(c.mode)?(c.La=O.Za.dir.node,c.Ma=O.Za.dir.stream,c.Na={}):32768===(c.mode&61440)?(c.La=O.Za.file.node,c.Ma=O.Za.file.stream,c.Ra=0,c.Na=null):40960===(c.mode&61440)?(c.La=O.Za.link.node,c.Ma=O.Za.link.stream):8192===(c.mode&61440)&&(c.La=O.Za.Nb.node,c.Ma=O.Za.Nb.stream);c.$a=c.Ua=c.Ta=Date.now();a&&(a.Na[b]=\nc,a.$a=a.Ua=a.Ta=c.$a);return c},Cc(a){return a.Na?a.Na.subarray?a.Na.subarray(0,a.Ra):new Uint8Array(a.Na):new Uint8Array(0)},La:{Wa(a){var b={};b.cc=8192===(a.mode&61440)?a.id:1;b.oc=a.id;b.mode=a.mode;b.rc=1;b.uid=0;b.nc=0;b.nb=a.nb;P(a.mode)?b.size=4096:32768===(a.mode&61440)?b.size=a.Ra:40960===(a.mode&61440)?b.size=a.link.length:b.size=0;b.$a=new Date(a.$a);b.Ua=new Date(a.Ua);b.Ta=new Date(a.Ta);b.Zb=4096;b.$b=Math.ceil(b.size/b.Zb);return b},Xa(a,b){for(var c of[\"mode\",\"atime\",\"mtime\",\"ctime\"])null!=\nb[c]&&(a[c]=b[c]);void 0!==b.size&&(b=b.size,a.Ra!=b&&(0==b?(a.Na=null,a.Ra=0):(c=a.Na,a.Na=new Uint8Array(b),c&&a.Na.set(c.subarray(0,Math.min(b,a.Ra))),a.Ra=b)))},mb(){O.zb||(O.zb=new N(44),O.zb.stack=\"<generic error, no stack>\");throw O.zb;},rb(a,b,c,d){return O.createNode(a,b,c,d)},Tb(a,b,c){try{var d=Q(b,c)}catch(g){}if(d){if(P(a.mode))for(var e in d.Na)throw new N(55);xb(d)}delete a.parent.Na[a.name];b.Na[c]=a;a.name=c;b.Ta=b.Ua=a.parent.Ta=a.parent.Ua=Date.now()},xb(a,b){delete a.Na[b];a.Ta=\na.Ua=Date.now()},vb(a,b){var c=Q(a,b),d;for(d in c.Na)throw new N(55);delete a.Na[b];a.Ta=a.Ua=Date.now()},Ib(a){return[\".\",\"..\",...Object.keys(a.Na)]},wb(a,b,c){a=O.createNode(a,b,41471,0);a.link=c;return a},eb(a){if(40960!==(a.mode&61440))throw new N(28);return a.link}},Ma:{read(a,b,c,d,e){var g=a.node.Na;if(e>=a.node.Ra)return 0;a=Math.min(a.node.Ra-e,d);if(8<a&&g.subarray)b.set(g.subarray(e,e+a),c);else for(d=0;d<a;d++)b[c+d]=g[e+d];return a},write(a,b,c,d,e,g){b.buffer===m.buffer&&(g=!1);if(!d)return 0;\na=a.node;a.Ua=a.Ta=Date.now();if(b.subarray&&(!a.Na||a.Na.subarray)){if(g)return a.Na=b.subarray(c,c+d),a.Ra=d;if(0===a.Ra&&0===e)return a.Na=b.slice(c,c+d),a.Ra=d;if(e+d<=a.Ra)return a.Na.set(b.subarray(c,c+d),e),d}g=e+d;var h=a.Na?a.Na.length:0;h>=g||(g=Math.max(g,h*(1048576>h?2:1.125)>>>0),0!=h&&(g=Math.max(g,256)),h=a.Na,a.Na=new Uint8Array(g),0<a.Ra&&a.Na.set(h.subarray(0,a.Ra),0));if(a.Na.subarray&&b.subarray)a.Na.set(b.subarray(c,c+d),e);else for(g=0;g<d;g++)a.Na[e+g]=b[c+g];a.Ra=Math.max(a.Ra,\ne+d);return d},Ya(a,b,c){1===c?b+=a.position:2===c&&32768===(a.node.mode&61440)&&(b+=a.node.Ra);if(0>b)throw new N(28);return b},sb(a,b,c,d,e){if(32768!==(a.node.mode&61440))throw new N(43);a=a.node.Na;if(e&2||!a||a.buffer!==m.buffer){e=!0;d=65536*Math.ceil(b/65536);var g=yb(65536,d);g&&C.fill(0,g,g+d);d=g;if(!d)throw new N(48);if(a){if(0<c||c+b<a.length)a.subarray?a=a.subarray(c,c+b):a=Array.prototype.slice.call(a,c,c+b);m.set(a,d)}}else e=!1,d=a.byteOffset;return{tc:d,Ub:e}},tb(a,b,c,d){O.Ma.write(a,\nb,0,d,c,!1);return 0}}},ia=(a,b)=>{var c=0;a&&(c|=365);b&&(c|=146);return c},zb=null,Ab={},Bb=[],Cb=1,R=null,Db=!1,Eb=!0,N=class{name=\"ErrnoError\";constructor(a){this.Pa=a}},Fb=class{qb={};node=null;get flags(){return this.qb.flags}set flags(a){this.qb.flags=a}get position(){return this.qb.position}set position(a){this.qb.position=a}},Gb=class{La={};Ma={};ib=null;constructor(a,b,c,d){a||=this;this.parent=a;this.ab=a.ab;this.id=Cb++;this.name=b;this.mode=c;this.nb=d;this.$a=this.Ua=this.Ta=Date.now()}get read(){return 365===\n(this.mode&365)}set read(a){a?this.mode|=365:this.mode&=-366}get write(){return 146===(this.mode&146)}set write(a){a?this.mode|=146:this.mode&=-147}};\nfunction S(a,b={}){if(!a)throw new N(44);b.Bb??(b.Bb=!0);\"/\"===a.charAt(0)||(a=\"//\"+a);var c=0;a:for(;40>c;c++){a=a.split(\"/\").filter(q=>!!q);for(var d=zb,e=\"/\",g=0;g<a.length;g++){var h=g===a.length-1;if(h&&b.parent)break;if(\".\"!==a[g])if(\"..\"===a[g])if(e=Za(e),d===d.parent){a=e+\"/\"+a.slice(g+1).join(\"/\");c--;continue a}else d=d.parent;else{e=ha(e+\"/\"+a[g]);try{d=Q(d,a[g])}catch(q){if(44===q?.Pa&&h&&b.sc)return{path:e};throw q;}!d.ib||h&&!b.Bb||(d=d.ib.root);if(40960===(d.mode&61440)&&(!h||b.hb)){if(!d.La.eb)throw new N(52);\nd=d.La.eb(d);\"/\"===d.charAt(0)||(d=Za(e)+\"/\"+d);a=d+\"/\"+a.slice(g+1).join(\"/\");continue a}}}return{path:e,node:d}}throw new N(32);}function fa(a){for(var b;;){if(a===a.parent)return a=a.ab.Sb,b?\"/\"!==a[a.length-1]?`${a}/${b}`:a+b:a;b=b?`${a.name}/${b}`:a.name;a=a.parent}}function Hb(a,b){for(var c=0,d=0;d<b.length;d++)c=(c<<5)-c+b.charCodeAt(d)|0;return(a+c>>>0)%R.length}function xb(a){var b=Hb(a.parent.id,a.name);if(R[b]===a)R[b]=a.jb;else for(b=R[b];b;){if(b.jb===a){b.jb=a.jb;break}b=b.jb}}\nfunction Q(a,b){var c=P(a.mode)?(c=Ib(a,\"x\"))?c:a.La.mb?0:2:54;if(c)throw new N(c);for(c=R[Hb(a.id,b)];c;c=c.jb){var d=c.name;if(c.parent.id===a.id&&d===b)return c}return a.La.mb(a,b)}function wb(a,b,c,d){a=new Gb(a,b,c,d);b=Hb(a.parent.id,a.name);a.jb=R[b];return R[b]=a}function P(a){return 16384===(a&61440)}function Ib(a,b){return Eb?0:b.includes(\"r\")&&!(a.mode&292)||b.includes(\"w\")&&!(a.mode&146)||b.includes(\"x\")&&!(a.mode&73)?2:0}\nfunction Jb(a,b){if(!P(a.mode))return 54;try{return Q(a,b),20}catch(c){}return Ib(a,\"wx\")}function Kb(a,b,c){try{var d=Q(a,b)}catch(e){return e.Pa}if(a=Ib(a,\"wx\"))return a;if(c){if(!P(d.mode))return 54;if(d===d.parent||\"/\"===fa(d))return 10}else if(P(d.mode))return 31;return 0}function Lb(a){if(!a)throw new N(63);return a}function T(a){a=Bb[a];if(!a)throw new N(8);return a}\nfunction Mb(a,b=-1){a=Object.assign(new Fb,a);if(-1==b)a:{for(b=0;4096>=b;b++)if(!Bb[b])break a;throw new N(33);}a.bb=b;return Bb[b]=a}function Nb(a,b=-1){a=Mb(a,b);a.Ma?.Bc?.(a);return a}function Ob(a,b,c){var d=a?.Ma.Xa;a=d?a:b;d??=b.La.Xa;Lb(d);d(a,c)}var vb={open(a){a.Ma=Ab[a.node.nb].Ma;a.Ma.open?.(a)},Ya(){throw new N(70);}};function rb(a,b){Ab[a]={Ma:b}}\nfunction Pb(a,b){var c=\"/\"===b;if(c&&zb)throw new N(10);if(!c&&b){var d=S(b,{Bb:!1});b=d.path;d=d.node;if(d.ib)throw new N(10);if(!P(d.mode))throw new N(54);}b={type:a,Gc:{},Sb:b,qc:[]};a=a.ab(b);a.ab=b;b.root=a;c?zb=a:d&&(d.ib=b,d.ab&&d.ab.qc.push(b))}function Qb(a,b,c){var d=S(a,{parent:!0}).node;a=$a(a);if(!a)throw new N(28);if(\".\"===a||\"..\"===a)throw new N(20);var e=Jb(d,a);if(e)throw new N(e);if(!d.La.rb)throw new N(63);return d.La.rb(d,a,b,c)}\nfunction ja(a,b=438){return Qb(a,b&4095|32768,0)}function U(a,b=511){return Qb(a,b&1023|16384,0)}function Rb(a,b,c){\"undefined\"==typeof c&&(c=b,b=438);Qb(a,b|8192,c)}function Sb(a,b){if(!cb(a))throw new N(44);var c=S(b,{parent:!0}).node;if(!c)throw new N(44);b=$a(b);var d=Jb(c,b);if(d)throw new N(d);if(!c.La.wb)throw new N(63);c.La.wb(c,b,a)}\nfunction Tb(a){var b=S(a,{parent:!0}).node;a=$a(a);var c=Q(b,a),d=Kb(b,a,!0);if(d)throw new N(d);if(!b.La.vb)throw new N(63);if(c.ib)throw new N(10);b.La.vb(b,a);xb(c)}function ta(a){var b=S(a,{parent:!0}).node;if(!b)throw new N(44);a=$a(a);var c=Q(b,a),d=Kb(b,a,!1);if(d)throw new N(d);if(!b.La.xb)throw new N(63);if(c.ib)throw new N(10);b.La.xb(b,a);xb(c)}function Ub(a,b){a=S(a,{hb:!b}).node;return Lb(a.La.Wa)(a)}function Vb(a,b,c,d){Ob(a,b,{mode:c&4095|b.mode&-4096,Ta:Date.now(),dc:d})}\nfunction ka(a,b){a=\"string\"==typeof a?S(a,{hb:!0}).node:a;Vb(null,a,b)}function Wb(a,b,c){if(P(b.mode))throw new N(31);if(32768!==(b.mode&61440))throw new N(28);var d=Ib(b,\"w\");if(d)throw new N(d);Ob(a,b,{size:c,timestamp:Date.now()})}\nfunction la(a,b,c=438){if(\"\"===a)throw new N(44);if(\"string\"==typeof b){var d={r:0,\"r+\":2,w:577,\"w+\":578,a:1089,\"a+\":1090}[b];if(\"undefined\"==typeof d)throw Error(`Unknown file open mode: ${b}`);b=d}c=b&64?c&4095|32768:0;if(\"object\"==typeof a)d=a;else{var e=a.endsWith(\"/\");var g=S(a,{hb:!(b&131072),sc:!0});d=g.node;a=g.path}g=!1;if(b&64)if(d){if(b&128)throw new N(20);}else{if(e)throw new N(31);d=Qb(a,c|511,0);g=!0}if(!d)throw new N(44);8192===(d.mode&61440)&&(b&=-513);if(b&65536&&!P(d.mode))throw new N(54);\nif(!g&&(d?40960===(d.mode&61440)?e=32:(e=[\"r\",\"w\",\"rw\"][b&3],b&512&&(e+=\"w\"),e=P(d.mode)&&(\"r\"!==e||b&576)?31:Ib(d,e)):e=44,e))throw new N(e);b&512&&!g&&(e=d,e=\"string\"==typeof e?S(e,{hb:!0}).node:e,Wb(null,e,0));b=Mb({node:d,path:fa(d),flags:b&-131713,seekable:!0,position:0,Ma:d.Ma,uc:[],error:!1});b.Ma.open&&b.Ma.open(b);g&&ka(d,c&511);return b}function na(a){if(null===a.bb)throw new N(8);a.Eb&&(a.Eb=null);try{a.Ma.close&&a.Ma.close(a)}catch(b){throw b;}finally{Bb[a.bb]=null}a.bb=null}\nfunction Xb(a,b,c){if(null===a.bb)throw new N(8);if(!a.seekable||!a.Ma.Ya)throw new N(70);if(0!=c&&1!=c&&2!=c)throw new N(28);a.position=a.Ma.Ya(a,b,c);a.uc=[]}function Yb(a,b,c,d,e){if(0>d||0>e)throw new N(28);if(null===a.bb)throw new N(8);if(1===(a.flags&2097155))throw new N(8);if(P(a.node.mode))throw new N(31);if(!a.Ma.read)throw new N(28);var g=\"undefined\"!=typeof e;if(!g)e=a.position;else if(!a.seekable)throw new N(70);b=a.Ma.read(a,b,c,d,e);g||(a.position+=b);return b}\nfunction ma(a,b,c,d,e){if(0>d||0>e)throw new N(28);if(null===a.bb)throw new N(8);if(0===(a.flags&2097155))throw new N(8);if(P(a.node.mode))throw new N(31);if(!a.Ma.write)throw new N(28);a.seekable&&a.flags&1024&&Xb(a,0,2);var g=\"undefined\"!=typeof e;if(!g)e=a.position;else if(!a.seekable)throw new N(70);b=a.Ma.write(a,b,c,d,e,void 0);g||(a.position+=b);return b}\nfunction sa(a){var b=b||0;var c=\"binary\";\"utf8\"!==c&&\"binary\"!==c&&Ja(`Invalid encoding type \"${c}\"`);b=la(a,b);a=Ub(a).size;var d=new Uint8Array(a);Yb(b,d,0,a,0);\"utf8\"===c&&(d=db(d));na(b);return d}\nfunction W(a,b,c){a=ha(\"/dev/\"+a);var d=ia(!!b,!!c);W.Rb??(W.Rb=64);var e=W.Rb++<<8|0;rb(e,{open(g){g.seekable=!1},close(){c?.buffer?.length&&c(10)},read(g,h,q,w){for(var t=0,x=0;x<w;x++){try{var D=b()}catch(ib){throw new N(29);}if(void 0===D&&0===t)throw new N(6);if(null===D||void 0===D)break;t++;h[q+x]=D}t&&(g.node.$a=Date.now());return t},write(g,h,q,w){for(var t=0;t<w;t++)try{c(h[q+t])}catch(x){throw new N(29);}w&&(g.node.Ua=g.node.Ta=Date.now());return t}});Rb(a,d,e)}var X={};\nfunction Y(a,b,c){if(\"/\"===b.charAt(0))return b;a=-100===a?\"/\":T(a).path;if(0==b.length){if(!c)throw new N(44);return a}return a+\"/\"+b}\nfunction Zb(a,b){F[a>>2]=b.cc;F[a+4>>2]=b.mode;F[a+8>>2]=b.rc;F[a+12>>2]=b.uid;F[a+16>>2]=b.nc;F[a+20>>2]=b.nb;G[a+24>>3]=BigInt(b.size);E[a+32>>2]=4096;E[a+36>>2]=b.$b;var c=b.$a.getTime(),d=b.Ua.getTime(),e=b.Ta.getTime();G[a+40>>3]=BigInt(Math.floor(c/1E3));F[a+48>>2]=c%1E3*1E6;G[a+56>>3]=BigInt(Math.floor(d/1E3));F[a+64>>2]=d%1E3*1E6;G[a+72>>3]=BigInt(Math.floor(e/1E3));F[a+80>>2]=e%1E3*1E6;G[a+88>>3]=BigInt(b.oc);return 0}\nvar ic=void 0,Ac=()=>{var a=E[+ic>>2];ic+=4;return a},Cc=0,Dc=[0,31,60,91,121,152,182,213,244,274,305,335],Ec=[0,31,59,90,120,151,181,212,243,273,304,334],Fc={},Gc=a=>{if(!(a instanceof Pa||\"unwind\"==a))throw a;},Hc=a=>{Da=a;Va||0<Cc||(k.onExit?.(a),Ca=!0);throw new Pa(a);},Ic=a=>{if(!Ca)try{a()}catch(b){Gc(b)}finally{if(!(Va||0<Cc))try{Da=a=Da,Hc(a)}catch(b){Gc(b)}}},Jc={},Lc=()=>{if(!Kc){var a={USER:\"web_user\",LOGNAME:\"web_user\",PATH:\"/\",PWD:\"/\",HOME:\"/home/web_user\",LANG:(globalThis.navigator?.language??\n\"C\").replace(\"-\",\"_\")+\".UTF-8\",_:va||\"./this.program\"},b;for(b in Jc)void 0===Jc[b]?delete a[b]:a[b]=Jc[b];var c=[];for(b in a)c.push(`${b}=${a[b]}`);Kc=c}return Kc},Kc,Mc=(a,b,c,d)=>{var e={string:t=>{var x=0;if(null!==t&&void 0!==t&&0!==t){x=gb(t)+1;var D=y(x);M(t,C,D,x);x=D}return x},array:t=>{var x=y(t.length);m.set(t,x);return x}};a=k[\"_\"+a];var g=[],h=0;if(d)for(var q=0;q<d.length;q++){var w=e[c[q]];w?(0===h&&(h=oa()),g[q]=w(d[q])):g[q]=d[q]}c=a(...g);return c=function(t){0!==h&&qa(h);return\"string\"===\nb?z(t):\"boolean\"===b?!!t:t}(c)},ea=a=>{var b=gb(a)+1,c=ca(b);c&&M(a,C,c,b);return c},Nc,Oc=[],A=a=>{Nc.delete(Z.get(a));Z.set(a,null);Oc.push(a)},Pc=a=>{const b=a.length;return[b%128|128,b>>7,...a]},Qc={i:127,p:127,j:126,f:125,d:124,e:111},Rc=a=>Pc(Array.from(a,b=>Qc[b])),ua=(a,b)=>{if(!Nc){Nc=new WeakMap;var c=Z.length;if(Nc)for(var d=0;d<0+c;d++){var e=Z.get(d);e&&Nc.set(e,d)}}if(c=Nc.get(a)||0)return c;c=Oc.length?Oc.pop():Z.grow(1);try{Z.set(c,a)}catch(g){if(!(g instanceof TypeError))throw g;\nb=Uint8Array.of(0,97,115,109,1,0,0,0,1,...Pc([1,96,...Rc(b.slice(1)),...Rc(\"v\"===b[0]?\"\":b[0])]),2,7,1,1,101,1,102,0,0,7,5,1,1,102,0,0);b=new WebAssembly.Module(b);b=(new WebAssembly.Instance(b,{e:{f:a}})).exports.f;Z.set(c,b)}Nc.set(a,c);return c};R=Array(4096);Pb(O,\"/\");U(\"/tmp\");U(\"/home\");U(\"/home/web_user\");\n(function(){U(\"/dev\");rb(259,{read:()=>0,write:(d,e,g,h)=>h,Ya:()=>0});Rb(\"/dev/null\",259);qb(1280,tb);qb(1536,ub);Rb(\"/dev/tty\",1280);Rb(\"/dev/tty1\",1536);var a=new Uint8Array(1024),b=0,c=()=>{0===b&&(bb(a),b=a.byteLength);return a[--b]};W(\"random\",c);W(\"urandom\",c);U(\"/dev/shm\");U(\"/dev/shm/tmp\")})();\n(function(){U(\"/proc\");var a=U(\"/proc/self\");U(\"/proc/self/fd\");Pb({ab(){var b=wb(a,\"fd\",16895,73);b.Ma={Ya:O.Ma.Ya};b.La={mb(c,d){c=+d;var e=T(c);c={parent:null,ab:{Sb:\"fake\"},La:{eb:()=>e.path},id:c+1};return c.parent=c},Ib(){return Array.from(Bb.entries()).filter(([,c])=>c).map(([c])=>c.toString())}};return b}},\"/proc/self/fd\")})();k.noExitRuntime&&(Va=k.noExitRuntime);k.print&&(Aa=k.print);k.printErr&&(B=k.printErr);k.wasmBinary&&(Ba=k.wasmBinary);k.thisProgram&&(va=k.thisProgram);\nif(k.preInit)for(\"function\"==typeof k.preInit&&(k.preInit=[k.preInit]);0<k.preInit.length;)k.preInit.shift()();k.stackSave=()=>oa();k.stackRestore=a=>qa(a);k.stackAlloc=a=>y(a);k.cwrap=(a,b,c,d)=>{var e=!c||c.every(g=>\"number\"===g||\"boolean\"===g);return\"string\"!==b&&e&&!d?k[\"_\"+a]:(...g)=>Mc(a,b,c,g)};k.addFunction=ua;k.removeFunction=A;k.UTF8ToString=z;k.stringToNewUTF8=ea;k.writeArrayToMemory=(a,b)=>{m.set(a,b)};\nvar ca,da,yb,Sc,qa,y,oa,Ia,Z,Tc={a:(a,b,c,d)=>Ja(`Assertion failed: ${z(a)}, at: `+[b?z(b):\"unknown filename\",c,d?z(d):\"unknown function\"]),i:function(a,b){try{return a=z(a),ka(a,b),0}catch(c){if(\"undefined\"==typeof X||\"ErrnoError\"!==c.name)throw c;return-c.Pa}},L:function(a,b,c){try{b=z(b);b=Y(a,b);if(c&-8)return-28;var d=S(b,{hb:!0}).node;if(!d)return-44;a=\"\";c&4&&(a+=\"r\");c&2&&(a+=\"w\");c&1&&(a+=\"x\");return a&&Ib(d,a)?-2:0}catch(e){if(\"undefined\"==typeof X||\"ErrnoError\"!==e.name)throw e;return-e.Pa}},\nj:function(a,b){try{var c=T(a);Vb(c,c.node,b,!1);return 0}catch(d){if(\"undefined\"==typeof X||\"ErrnoError\"!==d.name)throw d;return-d.Pa}},h:function(a){try{var b=T(a);Ob(b,b.node,{timestamp:Date.now(),dc:!1});return 0}catch(c){if(\"undefined\"==typeof X||\"ErrnoError\"!==c.name)throw c;return-c.Pa}},b:function(a,b,c){ic=c;try{var d=T(a);switch(b){case 0:var e=Ac();if(0>e)break;for(;Bb[e];)e++;return Nb(d,e).bb;case 1:case 2:return 0;case 3:return d.flags;case 4:return e=Ac(),d.flags|=e,0;case 12:return e=\nAc(),Ea[e+0>>1]=2,0;case 13:case 14:return 0}return-28}catch(g){if(\"undefined\"==typeof X||\"ErrnoError\"!==g.name)throw g;return-g.Pa}},g:function(a,b){try{var c=T(a),d=c.node,e=c.Ma.Wa;a=e?c:d;e??=d.La.Wa;Lb(e);var g=e(a);return Zb(b,g)}catch(h){if(\"undefined\"==typeof X||\"ErrnoError\"!==h.name)throw h;return-h.Pa}},H:function(a,b){b=-9007199254740992>b||9007199254740992<b?NaN:Number(b);try{if(isNaN(b))return-61;var c=T(a);if(0>b||0===(c.flags&2097155))throw new N(28);Wb(c,c.node,b);return 0}catch(d){if(\"undefined\"==\ntypeof X||\"ErrnoError\"!==d.name)throw d;return-d.Pa}},G:function(a,b){try{if(0===b)return-28;var c=gb(\"/\")+1;if(b<c)return-68;M(\"/\",C,a,b);return c}catch(d){if(\"undefined\"==typeof X||\"ErrnoError\"!==d.name)throw d;return-d.Pa}},K:function(a,b){try{return a=z(a),Zb(b,Ub(a,!0))}catch(c){if(\"undefined\"==typeof X||\"ErrnoError\"!==c.name)throw c;return-c.Pa}},C:function(a,b,c){try{return b=z(b),b=Y(a,b),U(b,c),0}catch(d){if(\"undefined\"==typeof X||\"ErrnoError\"!==d.name)throw d;return-d.Pa}},J:function(a,\nb,c,d){try{b=z(b);var e=d&256;b=Y(a,b,d&4096);return Zb(c,e?Ub(b,!0):Ub(b))}catch(g){if(\"undefined\"==typeof X||\"ErrnoError\"!==g.name)throw g;return-g.Pa}},x:function(a,b,c,d){ic=d;try{b=z(b);b=Y(a,b);var e=d?Ac():0;return la(b,c,e).bb}catch(g){if(\"undefined\"==typeof X||\"ErrnoError\"!==g.name)throw g;return-g.Pa}},v:function(a,b,c,d){try{b=z(b);b=Y(a,b);if(0>=d)return-28;var e=S(b).node;if(!e)throw new N(44);if(!e.La.eb)throw new N(28);var g=e.La.eb(e);var h=Math.min(d,gb(g)),q=m[c+h];M(g,C,c,d+1);\nm[c+h]=q;return h}catch(w){if(\"undefined\"==typeof X||\"ErrnoError\"!==w.name)throw w;return-w.Pa}},u:function(a){try{return a=z(a),Tb(a),0}catch(b){if(\"undefined\"==typeof X||\"ErrnoError\"!==b.name)throw b;return-b.Pa}},f:function(a,b){try{return a=z(a),Zb(b,Ub(a))}catch(c){if(\"undefined\"==typeof X||\"ErrnoError\"!==c.name)throw c;return-c.Pa}},r:function(a,b,c){try{b=z(b);b=Y(a,b);if(c)if(512===c)Tb(b);else return-28;else ta(b);return 0}catch(d){if(\"undefined\"==typeof X||\"ErrnoError\"!==d.name)throw d;\nreturn-d.Pa}},q:function(a,b,c){try{b=z(b);b=Y(a,b,!0);var d=Date.now(),e,g;if(c){var h=F[c>>2]+4294967296*E[c+4>>2],q=E[c+8>>2];1073741823==q?e=d:1073741822==q?e=null:e=1E3*h+q/1E6;c+=16;h=F[c>>2]+4294967296*E[c+4>>2];q=E[c+8>>2];1073741823==q?g=d:1073741822==q?g=null:g=1E3*h+q/1E6}else g=e=d;if(null!==(g??e)){a=e;var w=S(b,{hb:!0}).node;Lb(w.La.Xa)(w,{$a:a,Ua:g})}return 0}catch(t){if(\"undefined\"==typeof X||\"ErrnoError\"!==t.name)throw t;return-t.Pa}},m:()=>Ja(\"\"),l:()=>{Va=!1;Cc=0},A:function(a,\nb){a=-9007199254740992>a||9007199254740992<a?NaN:Number(a);a=new Date(1E3*a);E[b>>2]=a.getSeconds();E[b+4>>2]=a.getMinutes();E[b+8>>2]=a.getHours();E[b+12>>2]=a.getDate();E[b+16>>2]=a.getMonth();E[b+20>>2]=a.getFullYear()-1900;E[b+24>>2]=a.getDay();var c=a.getFullYear();E[b+28>>2]=(0!==c%4||0===c%100&&0!==c%400?Ec:Dc)[a.getMonth()]+a.getDate()-1|0;E[b+36>>2]=-(60*a.getTimezoneOffset());c=(new Date(a.getFullYear(),6,1)).getTimezoneOffset();var d=(new Date(a.getFullYear(),0,1)).getTimezoneOffset();\nE[b+32>>2]=(c!=d&&a.getTimezoneOffset()==Math.min(d,c))|0},y:function(a,b,c,d,e,g,h){e=-9007199254740992>e||9007199254740992<e?NaN:Number(e);try{var q=T(d);if(0!==(b&2)&&0===(c&2)&&2!==(q.flags&2097155))throw new N(2);if(1===(q.flags&2097155))throw new N(2);if(!q.Ma.sb)throw new N(43);if(!a)throw new N(28);var w=q.Ma.sb(q,a,e,b,c);var t=w.tc;E[g>>2]=w.Ub;F[h>>2]=t;return 0}catch(x){if(\"undefined\"==typeof X||\"ErrnoError\"!==x.name)throw x;return-x.Pa}},z:function(a,b,c,d,e,g){g=-9007199254740992>g||\n9007199254740992<g?NaN:Number(g);try{var h=T(e);if(c&2){if(32768!==(h.node.mode&61440))throw new N(43);d&2||h.Ma.tb&&h.Ma.tb(h,C.slice(a,a+b),g,b,d)}}catch(q){if(\"undefined\"==typeof X||\"ErrnoError\"!==q.name)throw q;return-q.Pa}},n:(a,b)=>{Fc[a]&&(clearTimeout(Fc[a].id),delete Fc[a]);if(!b)return 0;var c=setTimeout(()=>{delete Fc[a];Ic(()=>Sc(a,performance.now()))},b);Fc[a]={id:c,Hc:b};return 0},B:(a,b,c,d)=>{var e=(new Date).getFullYear(),g=(new Date(e,0,1)).getTimezoneOffset();e=(new Date(e,6,1)).getTimezoneOffset();\nF[a>>2]=60*Math.max(g,e);E[b>>2]=Number(g!=e);b=h=>{var q=Math.abs(h);return`UTC${0<=h?\"-\":\"+\"}${String(Math.floor(q/60)).padStart(2,\"0\")}${String(q%60).padStart(2,\"0\")}`};a=b(g);b=b(e);e<g?(M(a,C,c,17),M(b,C,d,17)):(M(a,C,d,17),M(b,C,c,17))},d:()=>Date.now(),s:()=>2147483648,c:()=>performance.now(),o:a=>{var b=C.length;a>>>=0;if(2147483648<a)return!1;for(var c=1;4>=c;c*=2){var d=b*(1+.2/c);d=Math.min(d,a+100663296);a:{d=(Math.min(2147483648,65536*Math.ceil(Math.max(a,d)/65536))-Ia.buffer.byteLength+\n65535)/65536|0;try{Ia.grow(d);Ha();var e=1;break a}catch(g){}e=void 0}if(e)return!0}return!1},E:(a,b)=>{var c=0,d=0,e;for(e of Lc()){var g=b+c;F[a+d>>2]=g;c+=M(e,C,g,Infinity)+1;d+=4}return 0},F:(a,b)=>{var c=Lc();F[a>>2]=c.length;a=0;for(var d of c)a+=gb(d)+1;F[b>>2]=a;return 0},e:function(a){try{var b=T(a);na(b);return 0}catch(c){if(\"undefined\"==typeof X||\"ErrnoError\"!==c.name)throw c;return c.Pa}},p:function(a,b){try{var c=T(a);m[b]=c.Va?2:P(c.mode)?3:40960===(c.mode&61440)?7:4;Ea[b+2>>1]=0;G[b+\n8>>3]=BigInt(0);G[b+16>>3]=BigInt(0);return 0}catch(d){if(\"undefined\"==typeof X||\"ErrnoError\"!==d.name)throw d;return d.Pa}},w:function(a,b,c,d){try{a:{var e=T(a);a=b;for(var g,h=b=0;h<c;h++){var q=F[a>>2],w=F[a+4>>2];a+=8;var t=Yb(e,m,q,w,g);if(0>t){var x=-1;break a}b+=t;if(t<w)break;\"undefined\"!=typeof g&&(g+=t)}x=b}F[d>>2]=x;return 0}catch(D){if(\"undefined\"==typeof X||\"ErrnoError\"!==D.name)throw D;return D.Pa}},D:function(a,b,c,d){b=-9007199254740992>b||9007199254740992<b?NaN:Number(b);try{if(isNaN(b))return 61;\nvar e=T(a);Xb(e,b,c);G[d>>3]=BigInt(e.position);e.Eb&&0===b&&0===c&&(e.Eb=null);return 0}catch(g){if(\"undefined\"==typeof X||\"ErrnoError\"!==g.name)throw g;return g.Pa}},I:function(a){try{var b=T(a);return b.Ma?.lb?.(b)}catch(c){if(\"undefined\"==typeof X||\"ErrnoError\"!==c.name)throw c;return c.Pa}},t:function(a,b,c,d){try{a:{var e=T(a);a=b;for(var g,h=b=0;h<c;h++){var q=F[a>>2],w=F[a+4>>2];a+=8;var t=ma(e,m,q,w,g);if(0>t){var x=-1;break a}b+=t;if(t<w)break;\"undefined\"!=typeof g&&(g+=t)}x=b}F[d>>2]=x;\nreturn 0}catch(D){if(\"undefined\"==typeof X||\"ErrnoError\"!==D.name)throw D;return D.Pa}},k:Hc};\nfunction Uc(){function a(){k.calledRun=!0;if(!Ca){if(!k.noFSInit&&!Db){var b,c;Db=!0;b??=k.stdin;c??=k.stdout;d??=k.stderr;b?W(\"stdin\",b):Sb(\"/dev/tty\",\"/dev/stdin\");c?W(\"stdout\",null,c):Sb(\"/dev/tty\",\"/dev/stdout\");d?W(\"stderr\",null,d):Sb(\"/dev/tty1\",\"/dev/stderr\");la(\"/dev/stdin\",0);la(\"/dev/stdout\",1);la(\"/dev/stderr\",1)}Vc.N();Eb=!1;k.onRuntimeInitialized?.();if(k.postRun)for(\"function\"==typeof k.postRun&&(k.postRun=[k.postRun]);k.postRun.length;){var d=k.postRun.shift();Ra.push(d)}Qa(Ra)}}if(0<\nJ)Ua=Uc;else{if(k.preRun)for(\"function\"==typeof k.preRun&&(k.preRun=[k.preRun]);k.preRun.length;)Ta();Qa(Sa);0<J?Ua=Uc:k.setStatus?(k.setStatus(\"Running...\"),setTimeout(()=>{setTimeout(()=>k.setStatus(\"\"),1);a()},1)):a()}}var Vc;\n(async function(){function a(c){c=Vc=c.exports;k._sqlite3_free=c.P;k._sqlite3_value_text=c.Q;k._sqlite3_prepare_v2=c.R;k._sqlite3_step=c.S;k._sqlite3_reset=c.T;k._sqlite3_exec=c.U;k._sqlite3_finalize=c.V;k._sqlite3_column_name=c.W;k._sqlite3_column_text=c.X;k._sqlite3_column_type=c.Y;k._sqlite3_errmsg=c.Z;k._sqlite3_clear_bindings=c._;k._sqlite3_value_blob=c.$;k._sqlite3_value_bytes=c.aa;k._sqlite3_value_double=c.ba;k._sqlite3_value_int=c.ca;k._sqlite3_value_type=c.da;k._sqlite3_result_blob=c.ea;\nk._sqlite3_result_double=c.fa;k._sqlite3_result_error=c.ga;k._sqlite3_result_int=c.ha;k._sqlite3_result_int64=c.ia;k._sqlite3_result_null=c.ja;k._sqlite3_result_text=c.ka;k._sqlite3_aggregate_context=c.la;k._sqlite3_column_count=c.ma;k._sqlite3_data_count=c.na;k._sqlite3_column_blob=c.oa;k._sqlite3_column_bytes=c.pa;k._sqlite3_column_double=c.qa;k._sqlite3_bind_blob=c.ra;k._sqlite3_bind_double=c.sa;k._sqlite3_bind_int=c.ta;k._sqlite3_bind_text=c.ua;k._sqlite3_bind_parameter_index=c.va;k._sqlite3_sql=\nc.wa;k._sqlite3_normalized_sql=c.xa;k._sqlite3_changes=c.ya;k._sqlite3_close_v2=c.za;k._sqlite3_create_function_v2=c.Aa;k._sqlite3_update_hook=c.Ba;k._sqlite3_open=c.Ca;ca=k._malloc=c.Da;da=k._free=c.Ea;k._RegisterExtensionFunctions=c.Fa;yb=c.Ga;Sc=c.Ha;qa=c.Ia;y=c.Ja;oa=c.Ka;Ia=c.M;Z=c.O;Ha();J--;k.monitorRunDependencies?.(J);0==J&&Ua&&(c=Ua,Ua=null,c());return Vc}J++;k.monitorRunDependencies?.(J);var b={a:Tc};if(k.instantiateWasm)return new Promise(c=>{k.instantiateWasm(b,(d,e)=>{c(a(d,e))})});\nLa??=k.locateFile?k.locateFile(\"sql-wasm-browser.wasm\",xa):xa+\"sql-wasm-browser.wasm\";return a((await Oa(b)).instance)})();Uc();\n\n\n // The shell-pre.js and emcc-generated code goes above\n return Module;\n }); // The end of the promise being returned\n\n return initSqlJsPromise;\n} // The end of our initSqlJs function\n\n// This bit below is copied almost exactly from what you get when you use the MODULARIZE=1 flag with emcc\n// However, we don't want to use the emcc modularization. See shell-pre.js\nif (typeof exports === 'object' && typeof module === 'object'){\n module.exports = initSqlJs;\n // This will allow the module to be used in ES6 or CommonJS\n module.exports.default = initSqlJs;\n}\nelse if (typeof define === 'function' && define['amd']) {\n define([], function() { return initSqlJs; });\n}\nelse if (typeof exports === 'object'){\n exports[\"Module\"] = initSqlJs;\n}\n", "// AUTO-GENERATED from contact-rules.jsonc \u2014 do not edit.\n// Edit the .jsonc and run `node build-rules.js` (or `npm run build`).\n\nexport const CONTACT_RULES = {\n \"rulesVersion\": \"v3-domain-oneoff\",\n \"junk\": {\n \"localExact\": \"^(no-?reply|do-?not-?reply|noreply|mailer-daemon|postmaster|abuse|automated|bounce(s|d)?|list-?(server|admin|owner|manager)?|notification|notifications?|admin@.*automated|root|daemon|nobody|undisclosed)$\",\n \"localSuffix\": \"(-bounces|\\\\+bounces|-noreply|-no-reply|-notifications?|-mailer)$\",\n \"localPrefix\": \"^(no-?reply|noreply|do-?not-?reply|donotreply|notifications?|alerts?|bounces?|mailer)[-_+]\",\n \"localOneoff\": \"^[0-9a-f]{4}\\\\.[0-9a-f]{4}(\\\\.[0-9a-z]{6})?$\",\n \"domain\": \"^(txt\\\\.voice\\\\.google\\\\.com|reply\\\\.facebook\\\\.com|reply\\\\.linkedin\\\\.com)$\"\n }\n} as const;\n", "/**\n * Shared `contacts.jsonc` mutations \u2014 denylist + preferred.\n *\n * Pure logic with cloud I/O injected, so the desktop service\n * (`mailx-service`, Node) and the Android service (`mailx-store-web`, in the\n * WebView) run ONE implementation instead of each keeping its own copy.\n * `web-service.ts` used to stub `addToDenylist` / `addPreferredContact` as\n * `notImpl()`, which is why the phone's \u2298 / \u2605 buttons did nothing.\n *\n * Nothing here is platform-specific: it's a `cloudRead` \u2192 mutate \u2192 `cloudWrite`\n * round-trip. Each caller passes its own platform's cloud functions.\n */\n\nexport type CloudReadFn = (filename: string) => Promise<string | null>;\n// Return type is intentionally loose \u2014 desktop `cloudWrite` resolves void,\n// the Android one resolves a boolean; the shared code ignores the result.\nexport type CloudWriteFn = (filename: string, content: string) => Promise<unknown>;\n\nexport interface PreferredContactEntry {\n name: string;\n email: string;\n source?: string;\n organization?: string;\n}\n\n/** Loose-parse a JSONC blob. The file mailx writes is plain JSON\n * (`JSON.stringify`), but a hand-edit may add `//` comments or trailing\n * commas \u2014 strip those and retry rather than losing the whole file. */\nfunction parseContactsConfig(raw: string | null): Record<string, unknown> {\n if (!raw) return {};\n try { return JSON.parse(raw) || {}; } catch { /* fall through to loose */ }\n try {\n const stripped = raw\n .replace(/^\\s*\\/\\/.*$/gm, \"\") // line comments\n .replace(/,(\\s*[}\\]])/g, \"$1\"); // trailing commas\n return JSON.parse(stripped) || {};\n } catch { return {}; }\n}\n\n/** Append an email to `contacts.jsonc#denylist[]` \u2014 idempotent and\n * case-insensitive. Writes only when the entry is genuinely new. */\nexport async function addContactsDenylistEntry(\n email: string, cloudRead: CloudReadFn, cloudWrite: CloudWriteFn,\n): Promise<void> {\n const lower = (email || \"\").trim().toLowerCase();\n if (!lower) return;\n const cfg = parseContactsConfig(await cloudRead(\"contacts.jsonc\")) as any;\n if (!Array.isArray(cfg.denylist)) cfg.denylist = [];\n if (cfg.denylist.some((e: any) => (e || \"\").toLowerCase() === lower)) return;\n cfg.denylist.push(email);\n await cloudWrite(\"contacts.jsonc\", JSON.stringify(cfg, null, 2));\n}\n\n/** Append a preferred contact to `contacts.jsonc#preferred[]` \u2014 dedup by\n * source|email|name. Writes only when the entry is genuinely new. */\nexport async function addContactsPreferredEntry(\n entry: PreferredContactEntry, cloudRead: CloudReadFn, cloudWrite: CloudWriteFn,\n): Promise<void> {\n if (!entry?.email) return;\n const cfg = parseContactsConfig(await cloudRead(\"contacts.jsonc\")) as any;\n if (!Array.isArray(cfg.preferred)) cfg.preferred = [];\n const key = (s: string, e: string, n: string): string =>\n `${(s || \"preferred\").toLowerCase()}|${(e || \"\").toLowerCase()}|${(n || \"\").toLowerCase()}`;\n const dupKey = key(entry.source || \"\", entry.email, entry.name || \"\");\n if (cfg.preferred.some((e: any) => key(e?.source || \"\", e?.email || \"\", e?.name || \"\") === dupKey)) return;\n const row: Record<string, string> = { name: entry.name || \"\", email: entry.email };\n if (entry.source) row.source = entry.source;\n if (entry.organization) row.organization = entry.organization;\n cfg.preferred.push(row);\n await cloudWrite(\"contacts.jsonc\", JSON.stringify(cfg, null, 2));\n}\n", "/**\n * Group expansion \u2014 turns a recipient string with group names into a flat\n * deduplicated address list. Shared between desktop (mailx-service) and\n * Android (mailx-store-web) so send paths produce the same result.\n *\n * Group source: contacts.jsonc \u2192 groups: Record<string, string[]>. Each\n * value is an array of either email addresses (\"a@b\" or \"Name <a@b>\") or\n * names of other groups (recursive aliasing). Cycles are detected; depth\n * is capped at 10 nested levels.\n */\n\n/** Raw recipient string from a To/Cc/Bcc field; may contain group names. */\nexport type RecipientToken = string;\n\n/** Map of group name \u2192 member list (each entry: address or another group name). */\nexport type GroupMap = Record<string, string[]>;\n\n/** Result of expanding a recipient string. */\nexport interface ExpansionResult {\n /** Flat unique address list (preserving order of first occurrence). */\n addresses: string[];\n /** Group names that couldn't be resolved (typo / cycle) \u2014 surface in UI. */\n unresolved: string[];\n}\n\n/** Split a comma-or-semicolon recipient string into tokens. Respects\n * angle-bracket address blocks (\"Name, Suffix <a@b>\") so a comma inside\n * the display name doesn't split the entry. */\nexport function splitRecipients(raw: string): RecipientToken[] {\n const out: string[] = [];\n let buf = \"\";\n let depth = 0;\n for (let i = 0; i < raw.length; i++) {\n const c = raw[i];\n if (c === \"<\") depth++;\n else if (c === \">\") depth = Math.max(0, depth - 1);\n if ((c === \",\" || c === \";\") && depth === 0) {\n const t = buf.trim();\n if (t) out.push(t);\n buf = \"\";\n } else {\n buf += c;\n }\n }\n const t = buf.trim();\n if (t) out.push(t);\n return out;\n}\n\n/** Quick test: does the token look like an email address (with or without\n * a display name)? Anything containing \"@\" with non-whitespace on both\n * sides counts. */\nexport function isAddressToken(token: string): boolean {\n return /^[^@\\s][^@]*@[^@\\s]+(\\s|$)|<[^>]+@[^>]+>/.test(token) || /^[^\\s<>@]+@[^\\s<>@]+$/.test(token);\n}\n\n/** Extract the bare email address from a token. Returns the original token\n * lowercased if it has no angle-bracket form. */\nexport function extractAddress(token: string): string {\n const m = token.match(/<([^>]+)>/);\n if (m) return m[1].trim().toLowerCase();\n return token.trim().toLowerCase();\n}\n\n/** Expand a recipient string by resolving group names against `groups`.\n * Group names take precedence: if a token matches a group name AND looks\n * like an address, it's treated as a group. (In practice no one names a\n * group \"x@y.com\", so this is rarely a real conflict.) */\nexport function expandRecipients(raw: string, groups: GroupMap): ExpansionResult {\n const tokens = splitRecipients(raw);\n const seen = new Set<string>();\n const addresses: string[] = [];\n const unresolved: string[] = [];\n\n const visit = (token: string, depth: number, visited: Set<string>): void => {\n if (depth > 10) {\n unresolved.push(`${token} (depth limit)`);\n return;\n }\n // Group name match \u2014 case-insensitive\n const groupKey = Object.keys(groups).find(k => k.toLowerCase() === token.trim().toLowerCase());\n if (groupKey) {\n if (visited.has(groupKey.toLowerCase())) {\n unresolved.push(`${groupKey} (cycle)`);\n return;\n }\n const next = new Set(visited);\n next.add(groupKey.toLowerCase());\n for (const member of groups[groupKey] || []) {\n visit(member, depth + 1, next);\n }\n return;\n }\n // Address \u2014 keep the original (with display name if present), but\n // dedupe by lowercased bare address.\n if (isAddressToken(token)) {\n const key = extractAddress(token);\n if (!seen.has(key)) {\n seen.add(key);\n addresses.push(token.trim());\n }\n return;\n }\n // Neither group nor address \u2014 flag.\n unresolved.push(token);\n };\n\n for (const t of tokens) {\n visit(t, 0, new Set());\n }\n return { addresses, unresolved };\n}\n", "/**\n * @bobfrankston/mailx-types\n * Shared type definitions for the mailx email client.\n * This is the contract between client and server.\n */\n\n// Generated rule data \u2014 both desktop store and Android store import via\n// this barrel so a single source-of-truth (contact-rules.jsonc) drives\n// junk-contact filtering on every platform.\nexport { CONTACT_RULES } from \"./contact-rules.js\";\nexport type { MailxApi } from \"./mailx-api.js\";\n// Shared contacts.jsonc mutations \u2014 one implementation for desktop + Android.\nexport {\n addContactsDenylistEntry, addContactsPreferredEntry,\n type PreferredContactEntry, type CloudReadFn, type CloudWriteFn,\n} from \"./contacts-config.js\";\n\n// Group-name expansion for recipient fields. Lets users type a group name\n// (e.g. \"family\") in To/Cc/Bcc and have it expand to the address list at\n// send time. Both desktop and Android send paths consume this expander\n// against contacts.jsonc \u2192 groups.\nexport {\n expandRecipients, splitRecipients, isAddressToken, extractAddress,\n} from \"./groups.js\";\nexport type { GroupMap, RecipientToken, ExpansionResult } from \"./groups.js\";\n\n// \u2500\u2500 Account Configuration \u2500\u2500\n\n/** Supported authentication methods */\nexport type AuthMethod = \"password\" | \"oauth2\";\n\n/** Mail account configuration */\nexport interface AccountConfig {\n id: string; /** Unique account identifier (e.g., \"iecc\", \"gmail-bob\") */\n name: string; /** Sender name for From header (e.g., \"Bob Frankston\") */\n label?: string; /** UI label for account list (e.g., \"Gmail\"). Falls back to name if not set */\n email: string; /** Email address */\n imap: {\n host: string;\n port: number;\n tls: boolean;\n auth: AuthMethod;\n user: string;\n password?: string; /** For password auth */\n oauthClientId?: string; /** For OAuth2 */\n };\n smtp: {\n host: string;\n port: number;\n tls: boolean;\n auth: AuthMethod;\n user: string;\n password?: string;\n };\n enabled: boolean;\n primary?: boolean; /** Catch-all \"this is my main account\" \u2014 default source for Calendar / Tasks / Contacts when no per-feature override set. */\n primaryCalendar?: boolean; /** Per-feature override: use this account's Google Calendar. Falls back to `primary` if unset. */\n primaryTasks?: boolean; /** Per-feature override: use this account's Google Tasks. Falls back to `primary` if unset. */\n primaryContacts?: boolean; /** Per-feature override: use this account's Google Contacts. Falls back to `primary` if unset. */\n defaultSend?: boolean; /** Use this account's SMTP when From doesn't match any account */\n syncContacts?: boolean; /** Sync contacts even when account is disabled (contacts-only Gmail) */\n relayDomains?: string[]; /** Domains to skip in Delivered-To chain (e.g., [\"relay.aaz.lt\"]) */\n identityDomains?: string[]; /** Domains where Delivered-To address should become the reply From (e.g., [\"bob.ma\", \"bobf.frankston.com\"]) */\n spam?: string; /** IMAP folder path for \"Mark as spam\" button (e.g., \"_spam\"). Button hidden when not set. */\n signature?: string; /** Legacy: HTML signature appended to all outgoing messages (new + reply + forward). Plain text or HTML allowed. Superseded by `sig`. */\n sig?: AccountSignature; /** Per-account signature object. Initially appended only to NEW messages; later options will cover replies/forwards. */\n}\n\n/** Signature configuration in accounts.jsonc. Initial shape carries `text`\n * only; `html: true` reserved for future support of raw HTML signatures. */\nexport interface AccountSignature {\n text: string; /** Plain-text signature body. Newlines preserved. Appended to NEW messages with the standard \"-- \" RFC 3676 separator. */\n html?: boolean; /** Future flag: when true, `text` is treated as raw HTML rather than escaped plain text. Currently ignored. */\n}\n\n// \u2500\u2500 Folder Types \u2500\u2500\n\n/** Standard IMAP special-use folder types */\nexport type SpecialUse = \"inbox\" | \"sent\" | \"drafts\" | \"trash\" | \"junk\" | \"archive\" | \"all\";\n\n/** A mailbox folder */\nexport interface Folder {\n id: number;\n accountId: string;\n path: string; /** IMAP path e.g., \"INBOX\", \"INBOX/Projects\" */\n name: string; /** Display name */\n specialUse: SpecialUse; /** Standard folder type, or null for custom */\n delimiter: string; /** IMAP hierarchy delimiter */\n totalCount: number;\n unreadCount: number;\n children: Folder[]; /** Nested subfolders */\n}\n\n// \u2500\u2500 Message flag state \u2500\u2500\n//\n// External API surface for the IMAP system flags. The literal strings\n// (`\"\\\\Seen\"`, `\"\\\\Flagged\"`, etc.) live ONLY inside this module \u2014 every\n// caller speaks in terms of named predicates (`seenOf(msg)`) and verbs\n// (`setSeen(msg, true)`, `toggleSeen(msg)`). That keeps a typo like\n// `\"\\Seen\"` (single backslash) from silently bypassing flag checks\n// elsewhere, and removes the \"two-API leak\" of having both `FLAG.SEEN`\n// constants AND verb helpers exposed simultaneously.\n//\n// These work against any object with a mutable `flags: string[]`\n// property \u2014 `MessageEnvelope`, `Message`, and the row's `msg` reference\n// all qualify. The verbs return `void` and mutate `msg.flags` in place\n// (replacing the array with a fresh one so listeners observing\n// reference identity, e.g. message-state, still re-render). Pure\n// predicate calls (`seenOf`, `flaggedOf`) don't mutate.\n\nconst _SEEN = \"\\\\Seen\";\nconst _FLAGGED = \"\\\\Flagged\";\nconst _ANSWERED = \"\\\\Answered\";\nconst _DRAFT = \"\\\\Draft\";\nconst _DELETED = \"\\\\Deleted\";\n\ninterface FlagBearing { flags: string[]; }\n\nfunction _has(msg: FlagBearing | { flags?: readonly string[] }, flag: string): boolean {\n return !!msg.flags && msg.flags.includes(flag);\n}\nfunction _set(msg: FlagBearing, flag: string, state: boolean): void {\n const present = (msg.flags || []).includes(flag);\n if (state === present) return;\n const next = state\n ? [...(msg.flags || []), flag]\n : (msg.flags || []).filter(f => f !== flag);\n msg.flags = next;\n}\n\nexport const seenOf = (m: { flags?: readonly string[] }): boolean => _has(m, _SEEN);\nexport const flaggedOf = (m: { flags?: readonly string[] }): boolean => _has(m, _FLAGGED);\nexport const answeredOf = (m: { flags?: readonly string[] }): boolean => _has(m, _ANSWERED);\nexport const draftOf = (m: { flags?: readonly string[] }): boolean => _has(m, _DRAFT);\nexport const deletedOf = (m: { flags?: readonly string[] }): boolean => _has(m, _DELETED);\n\nexport const setSeen = (m: FlagBearing, state: boolean): void => _set(m, _SEEN, state);\nexport const setFlagged = (m: FlagBearing, state: boolean): void => _set(m, _FLAGGED, state);\nexport const setAnswered = (m: FlagBearing, state: boolean): void => _set(m, _ANSWERED, state);\nexport const setDraft = (m: FlagBearing, state: boolean): void => _set(m, _DRAFT, state);\n\nexport const toggleSeen = (m: FlagBearing): void => _set(m, _SEEN, !_has(m, _SEEN));\nexport const toggleFlagged = (m: FlagBearing): void => _set(m, _FLAGGED, !_has(m, _FLAGGED));\n\n// \u2500\u2500 Message Types \u2500\u2500\n\n/** Email address with optional display name */\nexport interface EmailAddress {\n name: string; /** Display name, may be empty */\n address: string; /** Email address */\n}\n\n/** Message envelope (headers only, for list display) */\nexport interface MessageEnvelope {\n id: number; /** Local store ID */\n accountId: string;\n folderId: number;\n folderName?: string; /** Leaf folder name; populated by cross-folder search so the UI can tag each hit */\n uid: number; /** IMAP UID (server-side identity; changes on move, UIDVALIDITY bump) */\n uuid?: string; /** Stable local identity, minted once at first-sight; never changes */\n messageId: string; /** RFC Message-ID header */\n inReplyTo: string; /** For threading */\n references: string[]; /** For threading */\n threadId?: string; /** Computed thread id (root Message-ID of the conversation) */\n date: number; /** Epoch ms */\n subject: string;\n from: EmailAddress;\n to: EmailAddress[];\n cc: EmailAddress[];\n flags: string[]; /** IMAP flags: [\"\\\\Seen\", \"\\\\Flagged\"] */\n size: number;\n hasAttachments: boolean;\n preview: string; /** First ~200 chars of body text */\n bodyPath?: string; /** Local body location: \"idb:...\" or \"gmail:<id>\" */\n providerId?: string; /** Native server id (Gmail hex id, Outlook Graph id) \u2014 bypasses UID\u2192id pagination on body fetch */\n pending?: boolean; /** True when a queued local action (move/flag/delete) hasn't been ACK'd by the server yet \u2014 UI renders pink */\n}\n\n/** Full message with body content */\nexport interface Message extends MessageEnvelope {\n bodyHtml: string; /** HTML body */\n bodyText: string; /** Plain text body */\n attachments: Attachment[];\n}\n\n/** File attachment metadata */\nexport interface Attachment {\n id: number;\n filename: string;\n mimeType: string;\n size: number;\n contentId: string; /** For inline attachments (cid:) */\n}\n\n// \u2500\u2500 API Types \u2500\u2500\n\n/** Paginated list response */\nexport interface PagedResult<T> {\n items: T[];\n total: number;\n page: number;\n pageSize: number;\n}\n\n/** Message list query parameters */\nexport interface MessageQuery {\n accountId: string;\n folderId: number;\n page?: number;\n pageSize?: number;\n sort?: \"date\" | \"from\" | \"subject\";\n sortDir?: \"asc\" | \"desc\";\n search?: string;\n /** Restrict to messages with the \\Flagged flag set (whole-folder, not\n * just the currently-rendered page \u2014 lets the \"show flagged\" filter\n * find stars on messages that haven't been paged in yet). */\n flaggedOnly?: boolean;\n}\n\n/** Compose/send a message */\nexport interface ComposeMessage {\n from: string; /** Account ID to send from */\n to: EmailAddress[];\n cc?: EmailAddress[];\n bcc?: EmailAddress[];\n subject: string;\n bodyHtml: string;\n bodyText?: string;\n inReplyTo?: string; /** Message-ID of message being replied to */\n references?: string[];\n attachments?: { filename: string; data: string; mimeType: string }[];\n}\n\n// \u2500\u2500 Queue Types \u2500\u2500\n\nexport type QueueStatus = \"pending\" | \"sending\" | \"sent\" | \"failed\";\n\nexport interface QueueItem {\n id: number;\n status: QueueStatus;\n createdAt: number;\n sendAfter: number; /** Epoch ms, for deferred send */\n attempts: number;\n lastAttempt: number;\n error: string;\n subject: string;\n to: EmailAddress[];\n}\n\n// \u2500\u2500 WebSocket Event Types \u2500\u2500\n\nexport type WsEvent =\n | { type: \"newMessage\"; accountId: string; folderId: number; message: MessageEnvelope }\n | { type: \"messageDeleted\"; accountId: string; folderId: number; uid: number }\n | { type: \"messageMoved\"; accountId: string; fromFolderId: number; toFolderId: number; uid: number }\n | { type: \"folderCountsChanged\"; accountId: string; counts: Record<number, { total: number; unread: number }> }\n | { type: \"folderSynced\"; accountId: string; entries: { folderId: number; syncedAt: number }[] }\n | { type: \"syncProgress\"; accountId: string; phase: string; progress: number }\n | { type: \"queueUpdate\"; pending: number; sending: number; failed: number }\n | { type: \"connected\" }\n | { type: \"reload\" }\n | { type: \"error\"; message: string }\n | { type: \"accountError\"; accountId: string; error: string; hint: string; isOAuth: boolean };\n\n// \u2500\u2500 Settings Types \u2500\u2500\n\nexport interface MailxSettings {\n accounts: AccountConfig[];\n ui: {\n theme: \"system\" | \"dark\" | \"light\";\n editor: \"quill\" | \"tiptap\";\n folderWidth: number;\n listViewerSplit: number; /** Percentage for message list height */\n fontSize: number;\n };\n sync: {\n intervalMinutes: number;\n historyDays: number; /** 0 = all history */\n prefetch: boolean; /** Download message bodies during sync (default true) */\n };\n store: {\n basePath: string; /** Where message bodies are stored */\n compressionBoundaryDays: number; /** Messages older than this get compressed */\n };\n autocomplete?: AutocompleteSettings;\n}\n\n// \u2500\u2500 Autocomplete Types \u2500\u2500\n\nexport interface AutocompleteSettings {\n enabled: boolean;\n provider: \"ollama\" | \"claude\" | \"openai\" | \"off\";\n ollamaUrl: string;\n ollamaModel: string;\n cloudApiKey: string;\n cloudModel: string;\n debounceMs: number;\n maxTokens: number;\n /** Per-feature opt-in for non-autocomplete AI helpers. All default false\n * per user preference (2026-04-21): AI features should be controlled by\n * a flag, initially OFF in settings. Provider config is shared with\n * autocomplete (provider, cloudApiKey, cloudModel, etc.). */\n translateEnabled?: boolean;\n proofreadEnabled?: boolean;\n}\n\n/** AI provider API keys. Lives at the top of `accounts.jsonc` alongside\n * `accounts:` so all secrets are co-located in one cloud-synced file. The\n * keys field replaces `preferences.jsonc.autocomplete.cloudApiKey` (which\n * was tied to the *active* provider) so a user can set both Anthropic and\n * OpenAI keys once and switch providers without re-entering anything. */\nexport interface AiKeys {\n anthropic?: string;\n openai?: string;\n}\n\nexport interface AutocompleteRequest {\n subject: string;\n to: string;\n bodyText: string;\n cursorOffset: number;\n}\n\nexport interface AutocompleteResponse {\n suggestion: string;\n}\n\n// \u2500\u2500 AI Transform (translate / proofread / summarize) \u2500\u2500\n\nexport interface AiTransformRequest {\n /** translate = render in `targetLang`; proofread = corrected version\n * with grammar/spelling fixes; summarize = short paragraph summary;\n * extractEvent = parse natural-language event description into a\n * structured calendar event (title/start/end/location/notes). */\n action: \"translate\" | \"proofread\" | \"summarize\" | \"extractEvent\";\n text: string;\n /** ISO-639-1 (or BCP-47) language code for translate. Defaults to \"en\". */\n targetLang?: string;\n /** Caller's \"now\" hint, ISO 8601 (e.g. 2026-05-05T18:30:00). Used by\n * extractEvent to resolve relative dates (\"tomorrow at 3pm\"). The\n * service can't trust its own clock \u2014 the user might be on a phone\n * in a different timezone \u2014 so the caller supplies it. */\n nowISO?: string;\n}\n\n/** Structured calendar event fields parsed from a natural-language\n * description by aiTransform({ action: \"extractEvent\" }). All times are\n * ISO 8601 in the caller's local timezone (no `Z` suffix); the client\n * shapes them into Google Calendar's `dates=` URL parameter. */\nexport interface ExtractedEvent {\n title: string;\n startISO?: string;\n endISO?: string;\n allDay?: boolean;\n location?: string;\n notes?: string;\n}\n\nexport interface AiTransformResponse {\n /** Transformed text. Empty when AI is disabled / provider error / feature\n * not enabled \u2014 caller should treat empty as \"no result\". For\n * extractEvent this holds the JSON-stringified ExtractedEvent so the\n * response shape stays single-field across all actions. */\n text: string;\n /** Parsed ExtractedEvent, populated only for extractEvent. Lets the\n * client skip the JSON.parse step (the service already validated). */\n event?: ExtractedEvent;\n /** Optional reason for empty result, surfaced to UI status bar. */\n reason?: string;\n}\n\n// \u2500\u2500 Store Interface \u2500\u2500\n\n/** Body storage backend interface -- implementations are swappable */\nexport interface MessageStore {\n putMessage(accountId: string, folderId: number, uid: number, raw: Buffer): Promise<string>;\n getMessage(accountId: string, folderId: number, uid: number): Promise<Buffer>;\n deleteMessage(accountId: string, folderId: number, uid: number): Promise<void>;\n hasMessage(accountId: string, folderId: number, uid: number): Promise<boolean>;\n}\n\n// \u2500\u2500 Shared Utilities \u2500\u2500\n// Pure functions used by both desktop (mailx-service) and Android (web-service).\n// Kept here to avoid duplication \u2014 both platforms import from mailx-types.\n\n/** Sanitize HTML for safe display \u2014 strips scripts, inline handlers, remote images, forms, iframes. */\nexport function sanitizeHtml(html: string): { html: string; hasRemoteContent: boolean } {\n let hasRemoteContent = false;\n let clean = html.replace(/<script\\b[^>]*>[\\s\\S]*?<\\/script>/gi, \"\");\n clean = clean.replace(/\\s+on\\w+\\s*=\\s*(\"[^\"]*\"|'[^']*'|[^\\s>]+)/gi, \"\");\n clean = clean.replace(/<img\\b([^>]*)\\bsrc\\s*=\\s*(\"[^\"]*\"|'[^']*')/gi, (match, before, src) => {\n const url = src.slice(1, -1);\n if (url.startsWith(\"data:\") || url.startsWith(\"cid:\")) return match;\n hasRemoteContent = true;\n return `<img${before}src=\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='20' height='20'%3E%3Crect fill='%23888' width='20' height='20' rx='3'/%3E%3Ctext x='10' y='14' text-anchor='middle' fill='white' font-size='12'%3E\u2298%3C/text%3E%3C/svg%3E\" data-blocked-src=${src} title=\"Remote image blocked\"`;\n });\n clean = clean.replace(/<link\\b[^>]*rel\\s*=\\s*[\"']stylesheet[\"'][^>]*>/gi, (match) => {\n hasRemoteContent = true;\n return `<!-- blocked: ${match.replace(/--/g, \"\")} -->`;\n });\n clean = clean.replace(/url\\s*\\(\\s*(['\"]?)(https?:\\/\\/[^)]+)\\1\\s*\\)/gi, (_match, _q, url) => {\n hasRemoteContent = true;\n return `url(\"\") /* blocked: ${url} */`;\n });\n clean = clean.replace(/<\\/?form\\b[^>]*>/gi, \"\");\n // Strip every interactive form element. Even without the surrounding\n // <form>, an <input type=\"password\"> in an email body is dangerous \u2014\n // WebView2's password manager offers to autofill it, and the user\n // might type a real password into what looks like an in-email control.\n // Same for <textarea>, <select>/<option>, and <button>. Bob 2026-05-14:\n // observed a phishing-shaped \"CHANGE YOUR PASSWORD\" email rendering\n // with working input fields + the OS autofill chip. Replace with a\n // visible \"[blocked: input]\" marker so the user sees something was\n // stripped (a silent removal would hide the phishing attempt entirely\n // \u2014 they'd think \"this email is just text\" when it actually tried to\n // capture credentials).\n clean = clean.replace(/<input\\b[^>]*\\/?>/gi, \"[blocked: form input]\");\n clean = clean.replace(/<textarea\\b[^>]*>[\\s\\S]*?<\\/textarea>/gi, \"[blocked: textarea]\");\n clean = clean.replace(/<select\\b[^>]*>[\\s\\S]*?<\\/select>/gi, \"[blocked: select]\");\n clean = clean.replace(/<button\\b[^>]*>([\\s\\S]*?)<\\/button>/gi, \"$1\");\n clean = clean.replace(/<iframe\\b[^>]*>[\\s\\S]*?<\\/iframe>/gi, \"\");\n return { html: clean, hasRemoteContent };\n}\n\n/** Encode text as RFC 2045 quoted-printable. */\nexport function encodeQuotedPrintable(text: string): string {\n const encoder = new TextEncoder();\n const bytes = encoder.encode(text);\n let line = \"\";\n let result = \"\";\n for (let i = 0; i < bytes.length; i++) {\n const b = bytes[i];\n let encoded: string;\n if (b === 0x0D && bytes[i + 1] === 0x0A) {\n result += line + \"\\r\\n\";\n line = \"\";\n i++;\n continue;\n } else if (b === 0x0A) {\n result += line + \"\\r\\n\";\n line = \"\";\n continue;\n } else if ((b >= 33 && b <= 126 && b !== 61) || b === 9 || b === 32) {\n encoded = String.fromCharCode(b);\n } else {\n encoded = \"=\" + b.toString(16).toUpperCase().padStart(2, \"0\");\n }\n if (line.length + encoded.length > 75) {\n result += line + \"=\\r\\n\";\n line = \"\";\n }\n line += encoded;\n }\n result += line;\n return result;\n}\n\n/** Render an HTML document as a plain-text approximation suitable for the\n * text/plain alternative part of a multipart/alternative outgoing MIME\n * message. Not a full HTML-to-text engine \u2014 just enough to give non-HTML\n * clients (plain-text readers, spam filters scoring on text/plain, people\n * who turned HTML off) a readable fallback. Preserves line breaks for\n * `<br>` / `</p>` / `</div>` / `<li>`, strips all other tags, decodes the\n * common HTML entities, and collapses runs of whitespace.\n *\n * Spam filters (SpamAssassin, Rspamd) penalise HTML-only mail aggressively;\n * shipping a real text part typically drops the score by 1\u20132 points. Also\n * matches the behaviour of every other mainstream mail client \u2014 sending a\n * text/html part alone marks mailx as an outlier in mail logs. */\nexport function htmlToPlainText(html: string): string {\n if (!html) return \"\";\n let s = html;\n // Drop <style> / <script> entirely (their contents aren't readable text).\n s = s.replace(/<style\\b[^>]*>[\\s\\S]*?<\\/style>/gi, \"\");\n s = s.replace(/<script\\b[^>]*>[\\s\\S]*?<\\/script>/gi, \"\");\n // Block-level breaks \u2014 treat closing tags as line terminators so\n // paragraphs don't run together.\n s = s.replace(/<br\\s*\\/?\\s*>/gi, \"\\n\");\n s = s.replace(/<\\/(p|div|li|tr|h[1-6]|blockquote|pre|section|article)\\s*>/gi, \"\\n\");\n // List-item leading bullet (rough but readable).\n s = s.replace(/<li\\b[^>]*>/gi, \" \u2022 \");\n // Anchor: keep href in parens after the text so URLs survive.\n s = s.replace(/<a\\b[^>]*href\\s*=\\s*(['\"])([^'\"]*)\\1[^>]*>([\\s\\S]*?)<\\/a>/gi,\n (_m, _q, href, text) => {\n const t = text.replace(/<[^>]+>/g, \"\").trim();\n return t && t !== href ? `${t} (${href})` : href;\n });\n // Strip remaining tags.\n s = s.replace(/<[^>]+>/g, \"\");\n // Decode a pragmatic set of HTML entities \u2014 the rare ones survive as-is.\n s = s.replace(/ /gi, \" \")\n .replace(/&/gi, \"&\")\n .replace(/</gi, \"<\")\n .replace(/>/gi, \">\")\n .replace(/"/gi, \"\\\"\")\n .replace(/'/gi, \"'\")\n .replace(/'/gi, \"'\")\n .replace(/—/gi, \"\u2014\")\n .replace(/–/gi, \"\u2013\")\n .replace(/…/gi, \"\u2026\")\n .replace(/&#(\\d+);/g, (_m, n) => String.fromCodePoint(parseInt(n, 10)))\n .replace(/&#x([0-9a-f]+);/gi, (_m, h) => String.fromCodePoint(parseInt(h, 16)));\n // Normalise whitespace: collapse runs of spaces/tabs, trim per-line,\n // cap consecutive blank lines at 2.\n s = s.replace(/[ \\t]+/g, \" \")\n .split(\"\\n\").map(l => l.replace(/^[ \\t]+|[ \\t]+$/g, \"\")).join(\"\\n\")\n .replace(/\\n{3,}/g, \"\\n\\n\")\n .trim();\n return s;\n}\n\n/** Parse search query into structured conditions.\n * Supports qualifiers: from:, to:, subject:, date:, has:attachment,\n * is:flagged, is:unread, is:read. Unqualified terms search across subject /\n * from / preview. Returns { conditions, params } for SQL WHERE clause with\n * LIKE plus structured predicates (flags_json LIKE, has_attachments=1, date\n * range comparisons).\n *\n * Date syntax (matches Gmail-ish conventions):\n * - date:2026-04-22 exact day\n * - date:2026-04 month\n * - date:>2026-04-01 after\n * - date:<2026-04-01 before\n * - date:2026-04-01..2026-04-30 range\n * - date:today / yesterday / last7 / last30\n */\nexport function parseSearchQuery(query: string): { conditions: string[]; params: (string | number)[] } {\n const parts = query.match(/(?:[^\\s\"]+|\"[^\"]*\")+/g) || [];\n const conditions: string[] = [];\n const params: (string | number)[] = [];\n\n const dayStart = (y: number, m: number, d: number) => new Date(y, m - 1, d).getTime();\n const parseDateSpec = (spec: string): { from?: number; to?: number } | null => {\n const now = new Date();\n const today0 = new Date(now.getFullYear(), now.getMonth(), now.getDate()).getTime();\n if (spec === \"today\") return { from: today0, to: today0 + 86400_000 };\n if (spec === \"yesterday\") return { from: today0 - 86400_000, to: today0 };\n const lastN = spec.match(/^last(\\d+)$/i);\n if (lastN) return { from: today0 - parseInt(lastN[1]) * 86400_000 };\n const rangeMatch = spec.match(/^(\\d{4})-(\\d{2})-(\\d{2})\\.\\.(\\d{4})-(\\d{2})-(\\d{2})$/);\n if (rangeMatch) return {\n from: dayStart(+rangeMatch[1], +rangeMatch[2], +rangeMatch[3]),\n to: dayStart(+rangeMatch[4], +rangeMatch[5], +rangeMatch[6]) + 86400_000,\n };\n const gtMatch = spec.match(/^>(\\d{4})-(\\d{2})-(\\d{2})$/);\n if (gtMatch) return { from: dayStart(+gtMatch[1], +gtMatch[2], +gtMatch[3]) + 86400_000 };\n const ltMatch = spec.match(/^<(\\d{4})-(\\d{2})-(\\d{2})$/);\n if (ltMatch) return { to: dayStart(+ltMatch[1], +ltMatch[2], +ltMatch[3]) };\n const monthMatch = spec.match(/^(\\d{4})-(\\d{2})$/);\n if (monthMatch) {\n const y = +monthMatch[1], m = +monthMatch[2];\n const from = dayStart(y, m, 1);\n const to = m === 12 ? dayStart(y + 1, 1, 1) : dayStart(y, m + 1, 1);\n return { from, to };\n }\n const dayMatch = spec.match(/^(\\d{4})-(\\d{2})-(\\d{2})$/);\n if (dayMatch) {\n const from = dayStart(+dayMatch[1], +dayMatch[2], +dayMatch[3]);\n return { from, to: from + 86400_000 };\n }\n return null;\n };\n\n for (const part of parts) {\n const fromMatch = part.match(/^from:(.+)$/i);\n const toMatch = part.match(/^to:(.+)$/i);\n const subjectMatch = part.match(/^subject:(.+)$/i);\n const hasMatch = part.match(/^has:(.+)$/i);\n const isMatch = part.match(/^is:(.+)$/i);\n const dateMatch = part.match(/^date:(.+)$/i);\n\n if (fromMatch) {\n const term = `%${fromMatch[1].replace(/\"/g, \"\")}%`;\n conditions.push(\"(from_name LIKE ? OR from_address LIKE ?)\");\n params.push(term, term);\n } else if (toMatch) {\n const term = `%${toMatch[1].replace(/\"/g, \"\")}%`;\n conditions.push(\"(to_json LIKE ? OR cc_json LIKE ?)\");\n params.push(term, term);\n } else if (subjectMatch) {\n const term = `%${subjectMatch[1].replace(/\"/g, \"\")}%`;\n conditions.push(\"subject LIKE ?\");\n params.push(term);\n } else if (hasMatch) {\n const v = hasMatch[1].toLowerCase();\n if (v === \"attachment\" || v === \"attachments\") {\n conditions.push(\"has_attachments = 1\");\n }\n // Unknown has: qualifier \u2014 silently drop; treating as a literal\n // search term would be confusing.\n } else if (isMatch) {\n const v = isMatch[1].toLowerCase();\n if (v === \"flagged\" || v === \"starred\") {\n conditions.push(\"flags_json LIKE ?\"); params.push(\"%\\\\\\\\Flagged%\");\n } else if (v === \"unread\") {\n conditions.push(\"flags_json NOT LIKE ?\"); params.push(\"%\\\\\\\\Seen%\");\n } else if (v === \"read\") {\n conditions.push(\"flags_json LIKE ?\"); params.push(\"%\\\\\\\\Seen%\");\n }\n } else if (dateMatch) {\n const spec = parseDateSpec(dateMatch[1]);\n if (spec) {\n if (spec.from !== undefined) {\n conditions.push(\"date >= ?\"); params.push(spec.from);\n }\n if (spec.to !== undefined) {\n conditions.push(\"date < ?\"); params.push(spec.to);\n }\n }\n } else {\n const term = `%${part}%`;\n conditions.push(\"(subject LIKE ? OR from_name LIKE ? OR from_address LIKE ? OR preview LIKE ?)\");\n params.push(term, term, term, term);\n }\n }\n\n return { conditions, params };\n}\n", "/**\n * Browser-compatible settings for Android/WebView.\n * Replaces @bobfrankston/mailx-settings which depends on node:fs.\n *\n * Settings are stored in IndexedDB and synced to Google Drive\n * via the GDrive API (same API as desktop cloud mode).\n *\n * On first run, settings are fetched from GDrive. Subsequent reads\n * use the local IndexedDB cache. Writes go to both.\n */\n\nimport type { AccountConfig, MailxSettings, AutocompleteSettings } from \"@bobfrankston/mailx-types\";\n\nconst IDB_NAME = \"mailx-settings\";\nconst IDB_VERSION = 1;\nconst STORE_NAME = \"files\";\n\n// \u2500\u2500 IndexedDB helpers \u2500\u2500\n\nfunction openSettingsDb(): Promise<IDBDatabase> {\n return new Promise((resolve, reject) => {\n const req = indexedDB.open(IDB_NAME, IDB_VERSION);\n req.onupgradeneeded = () => {\n const db = req.result;\n if (!db.objectStoreNames.contains(STORE_NAME)) {\n db.createObjectStore(STORE_NAME);\n }\n };\n req.onsuccess = () => resolve(req.result);\n req.onerror = () => reject(req.error);\n });\n}\n\nasync function idbRead(key: string): Promise<string | null> {\n const db = await openSettingsDb();\n return new Promise((resolve, reject) => {\n const tx = db.transaction(STORE_NAME, \"readonly\");\n const req = tx.objectStore(STORE_NAME).get(key);\n req.onsuccess = () => resolve(req.result as string | null);\n req.onerror = () => reject(req.error);\n });\n}\n\nasync function idbWrite(key: string, value: string): Promise<void> {\n const db = await openSettingsDb();\n return new Promise((resolve, reject) => {\n const tx = db.transaction(STORE_NAME, \"readwrite\");\n tx.objectStore(STORE_NAME).put(value, key);\n tx.oncomplete = () => resolve();\n tx.onerror = () => reject(tx.error);\n });\n}\n\nasync function idbDelete(key: string): Promise<void> {\n const db = await openSettingsDb();\n return new Promise((resolve, reject) => {\n const tx = db.transaction(STORE_NAME, \"readwrite\");\n tx.objectStore(STORE_NAME).delete(key);\n tx.oncomplete = () => resolve();\n tx.onerror = () => reject(tx.error);\n });\n}\n\n// \u2500\u2500 GDrive API \u2500\u2500\n\n/** GDrive folder ID for the \".rmfmail\" app folder */\nlet gDriveFolderId: string | null = null;\n/** GDrive folder name (resolved from query \u2014 \".rmfmail\" today, but kept dynamic in case the query changes) */\nlet gDriveFolderName: string | null = null;\n/** Full path \"My Drive/home/.rmfmail\" \u2014 surfaced in About so the user can verify */\nlet gDriveFolderPath: string | null = null;\n/** Owner email of the matched .rmfmail folder \u2014 surfaces wrong-account picks (e.g. spouse's shared folder) */\nlet gDriveFolderOwner: string | null = null;\n/** OAuth token provider \u2014 set by bootstrap */\nlet tokenProvider: (() => Promise<string>) | null = null;\n\nexport function setGDriveTokenProvider(provider: () => Promise<string>): void {\n tokenProvider = provider;\n}\n\nexport function setGDriveFolderId(folderId: string, folderName?: string, ownerEmail?: string, folderPath?: string): void {\n gDriveFolderId = folderId;\n if (folderName) gDriveFolderName = folderName;\n if (ownerEmail) gDriveFolderOwner = ownerEmail;\n if (folderPath) gDriveFolderPath = folderPath;\n}\n\nexport async function cloudRead(filename: string): Promise<string | null> {\n return gDriveRead(filename);\n}\nexport async function cloudWrite(filename: string, content: string): Promise<boolean> {\n return gDriveWrite(filename, content);\n}\n\nasync function gDriveRead(filename: string): Promise<string | null> {\n if (!tokenProvider || !gDriveFolderId) return null;\n try {\n const token = await tokenProvider();\n // Find file by name in folder\n const q = encodeURIComponent(`name='${filename}' and '${gDriveFolderId}' in parents and trashed=false`);\n const listRes = await globalThis.fetch(\n `https://www.googleapis.com/drive/v3/files?q=${q}&fields=files(id)`,\n { headers: { \"Authorization\": `Bearer ${token}` } }\n );\n if (!listRes.ok) return null;\n const listData = await listRes.json() as any;\n const fileId = listData.files?.[0]?.id;\n if (!fileId) return null;\n // Download content\n const res = await globalThis.fetch(\n `https://www.googleapis.com/drive/v3/files/${fileId}?alt=media`,\n { headers: { \"Authorization\": `Bearer ${token}` } }\n );\n if (!res.ok) return null;\n return res.text();\n } catch (e: any) {\n console.error(`[settings] GDrive read ${filename}: ${e.message}`);\n return null;\n }\n}\n\nasync function gDriveWrite(filename: string, content: string): Promise<boolean> {\n if (!tokenProvider || !gDriveFolderId) return false;\n try {\n const token = await tokenProvider();\n // Check if file exists\n const q = encodeURIComponent(`name='${filename}' and '${gDriveFolderId}' in parents and trashed=false`);\n const listRes = await globalThis.fetch(\n `https://www.googleapis.com/drive/v3/files?q=${q}&fields=files(id)`,\n { headers: { \"Authorization\": `Bearer ${token}` } }\n );\n if (!listRes.ok) return false;\n const listData = await listRes.json() as any;\n const fileId = listData.files?.[0]?.id;\n\n if (fileId) {\n // Update existing\n const res = await globalThis.fetch(\n `https://www.googleapis.com/upload/drive/v3/files/${fileId}?uploadType=media`,\n {\n method: \"PATCH\",\n headers: {\n \"Authorization\": `Bearer ${token}`,\n \"Content-Type\": \"application/json\",\n },\n body: content,\n }\n );\n return res.ok;\n } else {\n // Create new\n const metadata = JSON.stringify({\n name: filename,\n parents: [gDriveFolderId],\n mimeType: \"application/json\",\n });\n const boundary = \"----mailx\" + Date.now();\n const body = `--${boundary}\\r\\nContent-Type: application/json; charset=UTF-8\\r\\n\\r\\n${metadata}\\r\\n--${boundary}\\r\\nContent-Type: application/json\\r\\n\\r\\n${content}\\r\\n--${boundary}--`;\n const res = await globalThis.fetch(\n \"https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart\",\n {\n method: \"POST\",\n headers: {\n \"Authorization\": `Bearer ${token}`,\n \"Content-Type\": `multipart/related; boundary=${boundary}`,\n },\n body,\n }\n );\n return res.ok;\n }\n } catch (e: any) {\n console.error(`[settings] GDrive write ${filename}: ${e.message}`);\n return false;\n }\n}\n\n// \u2500\u2500 Provider defaults (same as desktop mailx-settings) \u2500\u2500\n\ninterface ProviderDefaults {\n label: string;\n imap: { host: string; port: number; tls: boolean; auth: \"password\" | \"oauth2\" };\n smtp: { host: string; port: number; tls: boolean; auth: \"password\" | \"oauth2\" };\n}\n\nconst PROVIDERS: Record<string, ProviderDefaults> = {\n \"gmail.com\": {\n label: \"Gmail\",\n imap: { host: \"imap.gmail.com\", port: 993, tls: true, auth: \"oauth2\" },\n smtp: { host: \"smtp.gmail.com\", port: 587, tls: true, auth: \"oauth2\" },\n },\n \"googlemail.com\": {\n label: \"Gmail\",\n imap: { host: \"imap.gmail.com\", port: 993, tls: true, auth: \"oauth2\" },\n smtp: { host: \"smtp.gmail.com\", port: 587, tls: true, auth: \"oauth2\" },\n },\n \"outlook.com\": {\n label: \"Outlook\",\n imap: { host: \"outlook.office365.com\", port: 993, tls: true, auth: \"oauth2\" },\n smtp: { host: \"smtp.office365.com\", port: 587, tls: true, auth: \"oauth2\" },\n },\n \"hotmail.com\": {\n label: \"Hotmail\",\n imap: { host: \"outlook.office365.com\", port: 993, tls: true, auth: \"oauth2\" },\n smtp: { host: \"smtp.office365.com\", port: 587, tls: true, auth: \"oauth2\" },\n },\n \"yahoo.com\": {\n label: \"Yahoo\",\n imap: { host: \"imap.mail.yahoo.com\", port: 993, tls: true, auth: \"password\" },\n smtp: { host: \"smtp.mail.yahoo.com\", port: 587, tls: true, auth: \"password\" },\n },\n \"icloud.com\": {\n label: \"iCloud\",\n imap: { host: \"imap.mail.me.com\", port: 993, tls: true, auth: \"password\" },\n smtp: { host: \"smtp.mail.me.com\", port: 587, tls: true, auth: \"password\" },\n },\n};\n\nfunction normalizeAccount(acct: any, globalName?: string): AccountConfig {\n const email = acct.email || \"\";\n const domain = email.split(\"@\")[1]?.toLowerCase() || \"\";\n const provider = PROVIDERS[domain];\n const user = acct.imap?.user || acct.user || email;\n\n return {\n id: acct.id || domain.split(\".\")[0] || \"account\",\n name: acct.name || globalName || email.split(\"@\")[0],\n label: acct.label || provider?.label,\n email,\n imap: {\n host: acct.imap?.host || provider?.imap.host || `imap.${domain}`,\n port: acct.imap?.port || provider?.imap.port || 993,\n tls: acct.imap?.tls ?? provider?.imap.tls ?? true,\n auth: acct.imap?.auth || provider?.imap.auth || \"password\",\n user: acct.imap?.user || user,\n password: acct.imap?.password || acct.password,\n },\n smtp: {\n host: acct.smtp?.host || provider?.smtp.host || `smtp.${domain}`,\n port: acct.smtp?.port || provider?.smtp.port || 587,\n tls: acct.smtp?.tls ?? provider?.smtp.tls ?? true,\n auth: acct.smtp?.auth || provider?.smtp.auth || \"password\",\n user: acct.smtp?.user || user,\n password: acct.smtp?.password || acct.password,\n },\n enabled: acct.enabled ?? true,\n defaultSend: acct.defaultSend,\n syncContacts: acct.syncContacts ?? (provider?.imap.auth === \"oauth2\"),\n relayDomains: acct.relayDomains,\n };\n}\n\n// \u2500\u2500 Default settings \u2500\u2500\n\nconst DEFAULT_PREFERENCES = {\n ui: {\n theme: \"system\" as const,\n editor: \"quill\" as const,\n folderWidth: 220,\n listViewerSplit: 40,\n fontSize: 15,\n },\n sync: {\n intervalMinutes: 5,\n historyDays: 30,\n prefetch: true,\n },\n autocomplete: {\n enabled: false,\n provider: \"off\" as const,\n ollamaUrl: \"\",\n ollamaModel: \"\",\n cloudApiKey: \"\",\n cloudModel: \"\",\n debounceMs: 600,\n maxTokens: 60,\n },\n};\n\nconst DEFAULT_ALLOWLIST = {\n senders: [] as string[],\n domains: [] as string[],\n recipients: [] as string[],\n flaggedSenders: [] as string[],\n flaggedDomains: [] as string[],\n};\n\n// \u2500\u2500 JSONC parser (strips comments and trailing commas) \u2500\u2500\n\nfunction parseJsonc(text: string): any {\n // Strip /* block comments */ and // line comments, but preserve content inside strings\n let stripped = \"\";\n let i = 0;\n let inString = false;\n let stringChar = \"\";\n while (i < text.length) {\n const c = text[i];\n const next = text[i + 1];\n if (inString) {\n stripped += c;\n if (c === \"\\\\\" && i + 1 < text.length) {\n stripped += text[i + 1];\n i += 2;\n continue;\n }\n if (c === stringChar) inString = false;\n i++;\n continue;\n }\n if (c === '\"' || c === \"'\") {\n inString = true;\n stringChar = c;\n stripped += c;\n i++;\n continue;\n }\n if (c === \"/\" && next === \"/\") {\n // Line comment \u2014 skip to end of line\n while (i < text.length && text[i] !== \"\\n\") i++;\n continue;\n }\n if (c === \"/\" && next === \"*\") {\n // Block comment \u2014 skip to */\n i += 2;\n while (i < text.length - 1 && !(text[i] === \"*\" && text[i + 1] === \"/\")) i++;\n i += 2;\n continue;\n }\n stripped += c;\n i++;\n }\n // Strip trailing commas before } or ]\n stripped = stripped.replace(/,(\\s*[}\\]])/g, \"$1\");\n return JSON.parse(stripped);\n}\n\n// \u2500\u2500 Public API \u2500\u2500\n\n/** Load accounts \u2014 first from IndexedDB cache, then GDrive */\nexport async function loadAccounts(): Promise<AccountConfig[]> {\n // Try local cache first\n const cached = await idbRead(\"accounts.jsonc\");\n if (cached) {\n try {\n const data = parseJsonc(cached);\n const raw: any[] = data.accounts || (Array.isArray(data) ? data : []);\n if (raw.length > 0) {\n return raw.map((a: any) => normalizeAccount(a, data.name));\n }\n } catch (e: any) { console.warn(`[settings] Cached accounts.jsonc parse failed: ${e.message}`); }\n }\n // Try GDrive\n const content = await gDriveRead(\"accounts.jsonc\");\n if (content) {\n await idbWrite(\"accounts.jsonc\", content);\n try {\n const data = parseJsonc(content);\n const raw: any[] = data.accounts || (Array.isArray(data) ? data : []);\n return raw.map((a: any) => normalizeAccount(a, data.name));\n } catch (e: any) { console.warn(`[settings] GDrive accounts.jsonc parse failed: ${e.message}`); }\n }\n return [];\n}\n\n/** Load accounts directly from GDrive, bypassing local cache */\nexport async function loadAccountsFromCloud(): Promise<AccountConfig[]> {\n const content = await gDriveRead(\"accounts.jsonc\");\n if (content) {\n await idbWrite(\"accounts.jsonc\", content);\n try {\n const data = parseJsonc(content);\n const raw: any[] = data.accounts || (Array.isArray(data) ? data : []);\n return raw.map((a: any) => normalizeAccount(a, data.name));\n } catch (e: any) { console.warn(`[settings] loadAccountsFromCloud parse failed: ${e.message}`); }\n }\n return [];\n}\n\n/** Save accounts to IndexedDB and GDrive */\nexport async function saveAccounts(accounts: AccountConfig[]): Promise<void> {\n const content = JSON.stringify({ accounts }, null, 2);\n await idbWrite(\"accounts.jsonc\", content);\n await gDriveWrite(\"accounts.jsonc\", content);\n}\n\n/** Load preferences */\nexport async function loadPreferences(): Promise<typeof DEFAULT_PREFERENCES> {\n const cached = await idbRead(\"preferences.jsonc\");\n if (cached) {\n try {\n const data = parseJsonc(cached);\n return {\n ui: { ...DEFAULT_PREFERENCES.ui, ...data.ui },\n sync: { ...DEFAULT_PREFERENCES.sync, ...data.sync },\n autocomplete: { ...DEFAULT_PREFERENCES.autocomplete, ...data.autocomplete },\n };\n } catch { /* parse error */ }\n }\n // Try GDrive\n const content = await gDriveRead(\"preferences.jsonc\");\n if (content) {\n await idbWrite(\"preferences.jsonc\", content);\n try {\n const data = parseJsonc(content);\n return {\n ui: { ...DEFAULT_PREFERENCES.ui, ...data.ui },\n sync: { ...DEFAULT_PREFERENCES.sync, ...data.sync },\n autocomplete: { ...DEFAULT_PREFERENCES.autocomplete, ...data.autocomplete },\n };\n } catch { /* parse error */ }\n }\n return { ...DEFAULT_PREFERENCES };\n}\n\n/** Save preferences */\nexport async function savePreferences(prefs: any): Promise<void> {\n const content = JSON.stringify(prefs, null, 2);\n await idbWrite(\"preferences.jsonc\", content);\n await gDriveWrite(\"preferences.jsonc\", content);\n}\n\n/** Load full settings (accounts + preferences combined) */\nexport async function loadSettings(): Promise<MailxSettings> {\n const accounts = await loadAccounts();\n const prefs = await loadPreferences();\n return {\n accounts,\n ui: prefs.ui,\n sync: prefs.sync,\n autocomplete: prefs.autocomplete as AutocompleteSettings,\n store: {\n basePath: \"indexeddb\",\n compressionBoundaryDays: 365,\n },\n };\n}\n\n/** Save full settings */\nexport async function saveSettings(settings: MailxSettings): Promise<void> {\n await saveAccounts(settings.accounts);\n await savePreferences({ ui: settings.ui, sync: settings.sync, autocomplete: settings.autocomplete });\n}\n\n/** Load allowlist */\nexport async function loadAllowlist(): Promise<typeof DEFAULT_ALLOWLIST> {\n const cached = await idbRead(\"allowlist.jsonc\");\n if (cached) {\n try { return parseJsonc(cached); } catch { /* */ }\n }\n const content = await gDriveRead(\"allowlist.jsonc\");\n if (content) {\n await idbWrite(\"allowlist.jsonc\", content);\n try { return parseJsonc(content); } catch { /* */ }\n }\n return { ...DEFAULT_ALLOWLIST };\n}\n\n/** Save allowlist */\nexport async function saveAllowlist(list: typeof DEFAULT_ALLOWLIST): Promise<void> {\n const content = JSON.stringify(list, null, 2);\n await idbWrite(\"allowlist.jsonc\", content);\n await gDriveWrite(\"allowlist.jsonc\", content);\n}\n\n/** Load autocomplete settings */\nexport async function loadAutocomplete(): Promise<AutocompleteSettings> {\n const prefs = await loadPreferences();\n return prefs.autocomplete as AutocompleteSettings;\n}\n\n/** Save autocomplete settings */\nexport async function saveAutocomplete(settings: AutocompleteSettings): Promise<void> {\n const prefs = await loadPreferences();\n (prefs as any).autocomplete = settings;\n await savePreferences(prefs);\n}\n\n/** Get history days \u2014 read from preferences */\nexport async function getHistoryDays(): Promise<number> {\n const prefs = await loadPreferences();\n return prefs.sync.historyDays || 30;\n}\n\n/** Get prefetch setting */\nexport async function getPrefetch(): Promise<boolean> {\n const prefs = await loadPreferences();\n return prefs.sync.prefetch !== false;\n}\n\n/** Get storage info */\nexport function getStorageInfo(): { provider: string; mode: string; folderId?: string; folderName?: string; folderPath?: string; folderOwner?: string } {\n return {\n provider: gDriveFolderId ? \"gdrive\" : \"local\",\n mode: gDriveFolderId ? \"api\" : \"local\",\n folderId: gDriveFolderId || undefined,\n folderName: gDriveFolderName || undefined,\n folderPath: gDriveFolderPath || undefined,\n folderOwner: gDriveFolderOwner || undefined,\n };\n}\n\n/** Clear all cached settings \u2014 used for \"Reset Store\" */\nexport async function clearSettings(): Promise<void> {\n await idbDelete(\"accounts.jsonc\");\n await idbDelete(\"preferences.jsonc\");\n await idbDelete(\"allowlist.jsonc\");\n}\n\n// \u2500\u2500 Per-device settings \u2500\u2500\n\nconst DEVICE_ID_KEY = \"mailx-device-id\";\n\n/** Get or create a stable device ID (UUID stored in localStorage) */\nexport function getDeviceId(): string {\n let id = localStorage.getItem(DEVICE_ID_KEY);\n if (!id) {\n id = crypto.randomUUID();\n localStorage.setItem(DEVICE_ID_KEY, id);\n }\n return id;\n}\n\n/** Save device-specific settings to GDrive (devices/<deviceId>/state.json) */\nexport async function saveDeviceState(state: any): Promise<void> {\n const deviceId = getDeviceId();\n const filename = `devices/${deviceId}/state.json`;\n const content = JSON.stringify(state, null, 2);\n await idbWrite(filename, content);\n await gDriveWrite(filename, content);\n}\n\n/** Load device-specific settings */\nexport async function loadDeviceState(): Promise<any> {\n const deviceId = getDeviceId();\n const filename = `devices/${deviceId}/state.json`;\n const cached = await idbRead(filename);\n if (cached) {\n try { return parseJsonc(cached); } catch { /* */ }\n }\n const content = await gDriveRead(filename);\n if (content) {\n await idbWrite(filename, content);\n try { return parseJsonc(content); } catch { /* */ }\n }\n return {};\n}\n", "/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n'use strict';\n/**\n * Creates a JSON scanner on the given text.\n * If ignoreTrivia is set, whitespaces or comments are ignored.\n */\nexport function createScanner(text, ignoreTrivia = false) {\n const len = text.length;\n let pos = 0, value = '', tokenOffset = 0, token = 16 /* SyntaxKind.Unknown */, lineNumber = 0, lineStartOffset = 0, tokenLineStartOffset = 0, prevTokenLineStartOffset = 0, scanError = 0 /* ScanError.None */;\n function scanHexDigits(count, exact) {\n let digits = 0;\n let value = 0;\n while (digits < count || !exact) {\n let ch = text.charCodeAt(pos);\n if (ch >= 48 /* CharacterCodes._0 */ && ch <= 57 /* CharacterCodes._9 */) {\n value = value * 16 + ch - 48 /* CharacterCodes._0 */;\n }\n else if (ch >= 65 /* CharacterCodes.A */ && ch <= 70 /* CharacterCodes.F */) {\n value = value * 16 + ch - 65 /* CharacterCodes.A */ + 10;\n }\n else if (ch >= 97 /* CharacterCodes.a */ && ch <= 102 /* CharacterCodes.f */) {\n value = value * 16 + ch - 97 /* CharacterCodes.a */ + 10;\n }\n else {\n break;\n }\n pos++;\n digits++;\n }\n if (digits < count) {\n value = -1;\n }\n return value;\n }\n function setPosition(newPosition) {\n pos = newPosition;\n value = '';\n tokenOffset = 0;\n token = 16 /* SyntaxKind.Unknown */;\n scanError = 0 /* ScanError.None */;\n }\n function scanNumber() {\n let start = pos;\n if (text.charCodeAt(pos) === 48 /* CharacterCodes._0 */) {\n pos++;\n }\n else {\n pos++;\n while (pos < text.length && isDigit(text.charCodeAt(pos))) {\n pos++;\n }\n }\n if (pos < text.length && text.charCodeAt(pos) === 46 /* CharacterCodes.dot */) {\n pos++;\n if (pos < text.length && isDigit(text.charCodeAt(pos))) {\n pos++;\n while (pos < text.length && isDigit(text.charCodeAt(pos))) {\n pos++;\n }\n }\n else {\n scanError = 3 /* ScanError.UnexpectedEndOfNumber */;\n return text.substring(start, pos);\n }\n }\n let end = pos;\n if (pos < text.length && (text.charCodeAt(pos) === 69 /* CharacterCodes.E */ || text.charCodeAt(pos) === 101 /* CharacterCodes.e */)) {\n pos++;\n if (pos < text.length && text.charCodeAt(pos) === 43 /* CharacterCodes.plus */ || text.charCodeAt(pos) === 45 /* CharacterCodes.minus */) {\n pos++;\n }\n if (pos < text.length && isDigit(text.charCodeAt(pos))) {\n pos++;\n while (pos < text.length && isDigit(text.charCodeAt(pos))) {\n pos++;\n }\n end = pos;\n }\n else {\n scanError = 3 /* ScanError.UnexpectedEndOfNumber */;\n }\n }\n return text.substring(start, end);\n }\n function scanString() {\n let result = '', start = pos;\n while (true) {\n if (pos >= len) {\n result += text.substring(start, pos);\n scanError = 2 /* ScanError.UnexpectedEndOfString */;\n break;\n }\n const ch = text.charCodeAt(pos);\n if (ch === 34 /* CharacterCodes.doubleQuote */) {\n result += text.substring(start, pos);\n pos++;\n break;\n }\n if (ch === 92 /* CharacterCodes.backslash */) {\n result += text.substring(start, pos);\n pos++;\n if (pos >= len) {\n scanError = 2 /* ScanError.UnexpectedEndOfString */;\n break;\n }\n const ch2 = text.charCodeAt(pos++);\n switch (ch2) {\n case 34 /* CharacterCodes.doubleQuote */:\n result += '\\\"';\n break;\n case 92 /* CharacterCodes.backslash */:\n result += '\\\\';\n break;\n case 47 /* CharacterCodes.slash */:\n result += '/';\n break;\n case 98 /* CharacterCodes.b */:\n result += '\\b';\n break;\n case 102 /* CharacterCodes.f */:\n result += '\\f';\n break;\n case 110 /* CharacterCodes.n */:\n result += '\\n';\n break;\n case 114 /* CharacterCodes.r */:\n result += '\\r';\n break;\n case 116 /* CharacterCodes.t */:\n result += '\\t';\n break;\n case 117 /* CharacterCodes.u */:\n const ch3 = scanHexDigits(4, true);\n if (ch3 >= 0) {\n result += String.fromCharCode(ch3);\n }\n else {\n scanError = 4 /* ScanError.InvalidUnicode */;\n }\n break;\n default:\n scanError = 5 /* ScanError.InvalidEscapeCharacter */;\n }\n start = pos;\n continue;\n }\n if (ch >= 0 && ch <= 0x1f) {\n if (isLineBreak(ch)) {\n result += text.substring(start, pos);\n scanError = 2 /* ScanError.UnexpectedEndOfString */;\n break;\n }\n else {\n scanError = 6 /* ScanError.InvalidCharacter */;\n // mark as error but continue with string\n }\n }\n pos++;\n }\n return result;\n }\n function scanNext() {\n value = '';\n scanError = 0 /* ScanError.None */;\n tokenOffset = pos;\n lineStartOffset = lineNumber;\n prevTokenLineStartOffset = tokenLineStartOffset;\n if (pos >= len) {\n // at the end\n tokenOffset = len;\n return token = 17 /* SyntaxKind.EOF */;\n }\n let code = text.charCodeAt(pos);\n // trivia: whitespace\n if (isWhiteSpace(code)) {\n do {\n pos++;\n value += String.fromCharCode(code);\n code = text.charCodeAt(pos);\n } while (isWhiteSpace(code));\n return token = 15 /* SyntaxKind.Trivia */;\n }\n // trivia: newlines\n if (isLineBreak(code)) {\n pos++;\n value += String.fromCharCode(code);\n if (code === 13 /* CharacterCodes.carriageReturn */ && text.charCodeAt(pos) === 10 /* CharacterCodes.lineFeed */) {\n pos++;\n value += '\\n';\n }\n lineNumber++;\n tokenLineStartOffset = pos;\n return token = 14 /* SyntaxKind.LineBreakTrivia */;\n }\n switch (code) {\n // tokens: []{}:,\n case 123 /* CharacterCodes.openBrace */:\n pos++;\n return token = 1 /* SyntaxKind.OpenBraceToken */;\n case 125 /* CharacterCodes.closeBrace */:\n pos++;\n return token = 2 /* SyntaxKind.CloseBraceToken */;\n case 91 /* CharacterCodes.openBracket */:\n pos++;\n return token = 3 /* SyntaxKind.OpenBracketToken */;\n case 93 /* CharacterCodes.closeBracket */:\n pos++;\n return token = 4 /* SyntaxKind.CloseBracketToken */;\n case 58 /* CharacterCodes.colon */:\n pos++;\n return token = 6 /* SyntaxKind.ColonToken */;\n case 44 /* CharacterCodes.comma */:\n pos++;\n return token = 5 /* SyntaxKind.CommaToken */;\n // strings\n case 34 /* CharacterCodes.doubleQuote */:\n pos++;\n value = scanString();\n return token = 10 /* SyntaxKind.StringLiteral */;\n // comments\n case 47 /* CharacterCodes.slash */:\n const start = pos - 1;\n // Single-line comment\n if (text.charCodeAt(pos + 1) === 47 /* CharacterCodes.slash */) {\n pos += 2;\n while (pos < len) {\n if (isLineBreak(text.charCodeAt(pos))) {\n break;\n }\n pos++;\n }\n value = text.substring(start, pos);\n return token = 12 /* SyntaxKind.LineCommentTrivia */;\n }\n // Multi-line comment\n if (text.charCodeAt(pos + 1) === 42 /* CharacterCodes.asterisk */) {\n pos += 2;\n const safeLength = len - 1; // For lookahead.\n let commentClosed = false;\n while (pos < safeLength) {\n const ch = text.charCodeAt(pos);\n if (ch === 42 /* CharacterCodes.asterisk */ && text.charCodeAt(pos + 1) === 47 /* CharacterCodes.slash */) {\n pos += 2;\n commentClosed = true;\n break;\n }\n pos++;\n if (isLineBreak(ch)) {\n if (ch === 13 /* CharacterCodes.carriageReturn */ && text.charCodeAt(pos) === 10 /* CharacterCodes.lineFeed */) {\n pos++;\n }\n lineNumber++;\n tokenLineStartOffset = pos;\n }\n }\n if (!commentClosed) {\n pos++;\n scanError = 1 /* ScanError.UnexpectedEndOfComment */;\n }\n value = text.substring(start, pos);\n return token = 13 /* SyntaxKind.BlockCommentTrivia */;\n }\n // just a single slash\n value += String.fromCharCode(code);\n pos++;\n return token = 16 /* SyntaxKind.Unknown */;\n // numbers\n case 45 /* CharacterCodes.minus */:\n value += String.fromCharCode(code);\n pos++;\n if (pos === len || !isDigit(text.charCodeAt(pos))) {\n return token = 16 /* SyntaxKind.Unknown */;\n }\n // found a minus, followed by a number so\n // we fall through to proceed with scanning\n // numbers\n case 48 /* CharacterCodes._0 */:\n case 49 /* CharacterCodes._1 */:\n case 50 /* CharacterCodes._2 */:\n case 51 /* CharacterCodes._3 */:\n case 52 /* CharacterCodes._4 */:\n case 53 /* CharacterCodes._5 */:\n case 54 /* CharacterCodes._6 */:\n case 55 /* CharacterCodes._7 */:\n case 56 /* CharacterCodes._8 */:\n case 57 /* CharacterCodes._9 */:\n value += scanNumber();\n return token = 11 /* SyntaxKind.NumericLiteral */;\n // literals and unknown symbols\n default:\n // is a literal? Read the full word.\n while (pos < len && isUnknownContentCharacter(code)) {\n pos++;\n code = text.charCodeAt(pos);\n }\n if (tokenOffset !== pos) {\n value = text.substring(tokenOffset, pos);\n // keywords: true, false, null\n switch (value) {\n case 'true': return token = 8 /* SyntaxKind.TrueKeyword */;\n case 'false': return token = 9 /* SyntaxKind.FalseKeyword */;\n case 'null': return token = 7 /* SyntaxKind.NullKeyword */;\n }\n return token = 16 /* SyntaxKind.Unknown */;\n }\n // some\n value += String.fromCharCode(code);\n pos++;\n return token = 16 /* SyntaxKind.Unknown */;\n }\n }\n function isUnknownContentCharacter(code) {\n if (isWhiteSpace(code) || isLineBreak(code)) {\n return false;\n }\n switch (code) {\n case 125 /* CharacterCodes.closeBrace */:\n case 93 /* CharacterCodes.closeBracket */:\n case 123 /* CharacterCodes.openBrace */:\n case 91 /* CharacterCodes.openBracket */:\n case 34 /* CharacterCodes.doubleQuote */:\n case 58 /* CharacterCodes.colon */:\n case 44 /* CharacterCodes.comma */:\n case 47 /* CharacterCodes.slash */:\n return false;\n }\n return true;\n }\n function scanNextNonTrivia() {\n let result;\n do {\n result = scanNext();\n } while (result >= 12 /* SyntaxKind.LineCommentTrivia */ && result <= 15 /* SyntaxKind.Trivia */);\n return result;\n }\n return {\n setPosition: setPosition,\n getPosition: () => pos,\n scan: ignoreTrivia ? scanNextNonTrivia : scanNext,\n getToken: () => token,\n getTokenValue: () => value,\n getTokenOffset: () => tokenOffset,\n getTokenLength: () => pos - tokenOffset,\n getTokenStartLine: () => lineStartOffset,\n getTokenStartCharacter: () => tokenOffset - prevTokenLineStartOffset,\n getTokenError: () => scanError,\n };\n}\nfunction isWhiteSpace(ch) {\n return ch === 32 /* CharacterCodes.space */ || ch === 9 /* CharacterCodes.tab */;\n}\nfunction isLineBreak(ch) {\n return ch === 10 /* CharacterCodes.lineFeed */ || ch === 13 /* CharacterCodes.carriageReturn */;\n}\nfunction isDigit(ch) {\n return ch >= 48 /* CharacterCodes._0 */ && ch <= 57 /* CharacterCodes._9 */;\n}\nvar CharacterCodes;\n(function (CharacterCodes) {\n CharacterCodes[CharacterCodes[\"lineFeed\"] = 10] = \"lineFeed\";\n CharacterCodes[CharacterCodes[\"carriageReturn\"] = 13] = \"carriageReturn\";\n CharacterCodes[CharacterCodes[\"space\"] = 32] = \"space\";\n CharacterCodes[CharacterCodes[\"_0\"] = 48] = \"_0\";\n CharacterCodes[CharacterCodes[\"_1\"] = 49] = \"_1\";\n CharacterCodes[CharacterCodes[\"_2\"] = 50] = \"_2\";\n CharacterCodes[CharacterCodes[\"_3\"] = 51] = \"_3\";\n CharacterCodes[CharacterCodes[\"_4\"] = 52] = \"_4\";\n CharacterCodes[CharacterCodes[\"_5\"] = 53] = \"_5\";\n CharacterCodes[CharacterCodes[\"_6\"] = 54] = \"_6\";\n CharacterCodes[CharacterCodes[\"_7\"] = 55] = \"_7\";\n CharacterCodes[CharacterCodes[\"_8\"] = 56] = \"_8\";\n CharacterCodes[CharacterCodes[\"_9\"] = 57] = \"_9\";\n CharacterCodes[CharacterCodes[\"a\"] = 97] = \"a\";\n CharacterCodes[CharacterCodes[\"b\"] = 98] = \"b\";\n CharacterCodes[CharacterCodes[\"c\"] = 99] = \"c\";\n CharacterCodes[CharacterCodes[\"d\"] = 100] = \"d\";\n CharacterCodes[CharacterCodes[\"e\"] = 101] = \"e\";\n CharacterCodes[CharacterCodes[\"f\"] = 102] = \"f\";\n CharacterCodes[CharacterCodes[\"g\"] = 103] = \"g\";\n CharacterCodes[CharacterCodes[\"h\"] = 104] = \"h\";\n CharacterCodes[CharacterCodes[\"i\"] = 105] = \"i\";\n CharacterCodes[CharacterCodes[\"j\"] = 106] = \"j\";\n CharacterCodes[CharacterCodes[\"k\"] = 107] = \"k\";\n CharacterCodes[CharacterCodes[\"l\"] = 108] = \"l\";\n CharacterCodes[CharacterCodes[\"m\"] = 109] = \"m\";\n CharacterCodes[CharacterCodes[\"n\"] = 110] = \"n\";\n CharacterCodes[CharacterCodes[\"o\"] = 111] = \"o\";\n CharacterCodes[CharacterCodes[\"p\"] = 112] = \"p\";\n CharacterCodes[CharacterCodes[\"q\"] = 113] = \"q\";\n CharacterCodes[CharacterCodes[\"r\"] = 114] = \"r\";\n CharacterCodes[CharacterCodes[\"s\"] = 115] = \"s\";\n CharacterCodes[CharacterCodes[\"t\"] = 116] = \"t\";\n CharacterCodes[CharacterCodes[\"u\"] = 117] = \"u\";\n CharacterCodes[CharacterCodes[\"v\"] = 118] = \"v\";\n CharacterCodes[CharacterCodes[\"w\"] = 119] = \"w\";\n CharacterCodes[CharacterCodes[\"x\"] = 120] = \"x\";\n CharacterCodes[CharacterCodes[\"y\"] = 121] = \"y\";\n CharacterCodes[CharacterCodes[\"z\"] = 122] = \"z\";\n CharacterCodes[CharacterCodes[\"A\"] = 65] = \"A\";\n CharacterCodes[CharacterCodes[\"B\"] = 66] = \"B\";\n CharacterCodes[CharacterCodes[\"C\"] = 67] = \"C\";\n CharacterCodes[CharacterCodes[\"D\"] = 68] = \"D\";\n CharacterCodes[CharacterCodes[\"E\"] = 69] = \"E\";\n CharacterCodes[CharacterCodes[\"F\"] = 70] = \"F\";\n CharacterCodes[CharacterCodes[\"G\"] = 71] = \"G\";\n CharacterCodes[CharacterCodes[\"H\"] = 72] = \"H\";\n CharacterCodes[CharacterCodes[\"I\"] = 73] = \"I\";\n CharacterCodes[CharacterCodes[\"J\"] = 74] = \"J\";\n CharacterCodes[CharacterCodes[\"K\"] = 75] = \"K\";\n CharacterCodes[CharacterCodes[\"L\"] = 76] = \"L\";\n CharacterCodes[CharacterCodes[\"M\"] = 77] = \"M\";\n CharacterCodes[CharacterCodes[\"N\"] = 78] = \"N\";\n CharacterCodes[CharacterCodes[\"O\"] = 79] = \"O\";\n CharacterCodes[CharacterCodes[\"P\"] = 80] = \"P\";\n CharacterCodes[CharacterCodes[\"Q\"] = 81] = \"Q\";\n CharacterCodes[CharacterCodes[\"R\"] = 82] = \"R\";\n CharacterCodes[CharacterCodes[\"S\"] = 83] = \"S\";\n CharacterCodes[CharacterCodes[\"T\"] = 84] = \"T\";\n CharacterCodes[CharacterCodes[\"U\"] = 85] = \"U\";\n CharacterCodes[CharacterCodes[\"V\"] = 86] = \"V\";\n CharacterCodes[CharacterCodes[\"W\"] = 87] = \"W\";\n CharacterCodes[CharacterCodes[\"X\"] = 88] = \"X\";\n CharacterCodes[CharacterCodes[\"Y\"] = 89] = \"Y\";\n CharacterCodes[CharacterCodes[\"Z\"] = 90] = \"Z\";\n CharacterCodes[CharacterCodes[\"asterisk\"] = 42] = \"asterisk\";\n CharacterCodes[CharacterCodes[\"backslash\"] = 92] = \"backslash\";\n CharacterCodes[CharacterCodes[\"closeBrace\"] = 125] = \"closeBrace\";\n CharacterCodes[CharacterCodes[\"closeBracket\"] = 93] = \"closeBracket\";\n CharacterCodes[CharacterCodes[\"colon\"] = 58] = \"colon\";\n CharacterCodes[CharacterCodes[\"comma\"] = 44] = \"comma\";\n CharacterCodes[CharacterCodes[\"dot\"] = 46] = \"dot\";\n CharacterCodes[CharacterCodes[\"doubleQuote\"] = 34] = \"doubleQuote\";\n CharacterCodes[CharacterCodes[\"minus\"] = 45] = \"minus\";\n CharacterCodes[CharacterCodes[\"openBrace\"] = 123] = \"openBrace\";\n CharacterCodes[CharacterCodes[\"openBracket\"] = 91] = \"openBracket\";\n CharacterCodes[CharacterCodes[\"plus\"] = 43] = \"plus\";\n CharacterCodes[CharacterCodes[\"slash\"] = 47] = \"slash\";\n CharacterCodes[CharacterCodes[\"formFeed\"] = 12] = \"formFeed\";\n CharacterCodes[CharacterCodes[\"tab\"] = 9] = \"tab\";\n})(CharacterCodes || (CharacterCodes = {}));\n", "export const cachedSpaces = new Array(20).fill(0).map((_, index) => {\n return ' '.repeat(index);\n});\nconst maxCachedValues = 200;\nexport const cachedBreakLinesWithSpaces = {\n ' ': {\n '\\n': new Array(maxCachedValues).fill(0).map((_, index) => {\n return '\\n' + ' '.repeat(index);\n }),\n '\\r': new Array(maxCachedValues).fill(0).map((_, index) => {\n return '\\r' + ' '.repeat(index);\n }),\n '\\r\\n': new Array(maxCachedValues).fill(0).map((_, index) => {\n return '\\r\\n' + ' '.repeat(index);\n }),\n },\n '\\t': {\n '\\n': new Array(maxCachedValues).fill(0).map((_, index) => {\n return '\\n' + '\\t'.repeat(index);\n }),\n '\\r': new Array(maxCachedValues).fill(0).map((_, index) => {\n return '\\r' + '\\t'.repeat(index);\n }),\n '\\r\\n': new Array(maxCachedValues).fill(0).map((_, index) => {\n return '\\r\\n' + '\\t'.repeat(index);\n }),\n }\n};\nexport const supportedEols = ['\\n', '\\r', '\\r\\n'];\n", "/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n'use strict';\nimport { createScanner } from './scanner';\nimport { cachedSpaces, cachedBreakLinesWithSpaces, supportedEols } from './string-intern';\nexport function format(documentText, range, options) {\n let initialIndentLevel;\n let formatText;\n let formatTextStart;\n let rangeStart;\n let rangeEnd;\n if (range) {\n rangeStart = range.offset;\n rangeEnd = rangeStart + range.length;\n formatTextStart = rangeStart;\n while (formatTextStart > 0 && !isEOL(documentText, formatTextStart - 1)) {\n formatTextStart--;\n }\n let endOffset = rangeEnd;\n while (endOffset < documentText.length && !isEOL(documentText, endOffset)) {\n endOffset++;\n }\n formatText = documentText.substring(formatTextStart, endOffset);\n initialIndentLevel = computeIndentLevel(formatText, options);\n }\n else {\n formatText = documentText;\n initialIndentLevel = 0;\n formatTextStart = 0;\n rangeStart = 0;\n rangeEnd = documentText.length;\n }\n const eol = getEOL(options, documentText);\n const eolFastPathSupported = supportedEols.includes(eol);\n let numberLineBreaks = 0;\n let indentLevel = 0;\n let indentValue;\n if (options.insertSpaces) {\n indentValue = cachedSpaces[options.tabSize || 4] ?? repeat(cachedSpaces[1], options.tabSize || 4);\n }\n else {\n indentValue = '\\t';\n }\n const indentType = indentValue === '\\t' ? '\\t' : ' ';\n let scanner = createScanner(formatText, false);\n let hasError = false;\n function newLinesAndIndent() {\n if (numberLineBreaks > 1) {\n return repeat(eol, numberLineBreaks) + repeat(indentValue, initialIndentLevel + indentLevel);\n }\n const amountOfSpaces = indentValue.length * (initialIndentLevel + indentLevel);\n if (!eolFastPathSupported || amountOfSpaces > cachedBreakLinesWithSpaces[indentType][eol].length) {\n return eol + repeat(indentValue, initialIndentLevel + indentLevel);\n }\n if (amountOfSpaces <= 0) {\n return eol;\n }\n return cachedBreakLinesWithSpaces[indentType][eol][amountOfSpaces];\n }\n function scanNext() {\n let token = scanner.scan();\n numberLineBreaks = 0;\n while (token === 15 /* SyntaxKind.Trivia */ || token === 14 /* SyntaxKind.LineBreakTrivia */) {\n if (token === 14 /* SyntaxKind.LineBreakTrivia */ && options.keepLines) {\n numberLineBreaks += 1;\n }\n else if (token === 14 /* SyntaxKind.LineBreakTrivia */) {\n numberLineBreaks = 1;\n }\n token = scanner.scan();\n }\n hasError = token === 16 /* SyntaxKind.Unknown */ || scanner.getTokenError() !== 0 /* ScanError.None */;\n return token;\n }\n const editOperations = [];\n function addEdit(text, startOffset, endOffset) {\n if (!hasError && (!range || (startOffset < rangeEnd && endOffset > rangeStart)) && documentText.substring(startOffset, endOffset) !== text) {\n editOperations.push({ offset: startOffset, length: endOffset - startOffset, content: text });\n }\n }\n let firstToken = scanNext();\n if (options.keepLines && numberLineBreaks > 0) {\n addEdit(repeat(eol, numberLineBreaks), 0, 0);\n }\n if (firstToken !== 17 /* SyntaxKind.EOF */) {\n let firstTokenStart = scanner.getTokenOffset() + formatTextStart;\n let initialIndent = (indentValue.length * initialIndentLevel < 20) && options.insertSpaces\n ? cachedSpaces[indentValue.length * initialIndentLevel]\n : repeat(indentValue, initialIndentLevel);\n addEdit(initialIndent, formatTextStart, firstTokenStart);\n }\n while (firstToken !== 17 /* SyntaxKind.EOF */) {\n let firstTokenEnd = scanner.getTokenOffset() + scanner.getTokenLength() + formatTextStart;\n let secondToken = scanNext();\n let replaceContent = '';\n let needsLineBreak = false;\n while (numberLineBreaks === 0 && (secondToken === 12 /* SyntaxKind.LineCommentTrivia */ || secondToken === 13 /* SyntaxKind.BlockCommentTrivia */)) {\n let commentTokenStart = scanner.getTokenOffset() + formatTextStart;\n addEdit(cachedSpaces[1], firstTokenEnd, commentTokenStart);\n firstTokenEnd = scanner.getTokenOffset() + scanner.getTokenLength() + formatTextStart;\n needsLineBreak = secondToken === 12 /* SyntaxKind.LineCommentTrivia */;\n replaceContent = needsLineBreak ? newLinesAndIndent() : '';\n secondToken = scanNext();\n }\n if (secondToken === 2 /* SyntaxKind.CloseBraceToken */) {\n if (firstToken !== 1 /* SyntaxKind.OpenBraceToken */) {\n indentLevel--;\n }\n ;\n if (options.keepLines && numberLineBreaks > 0 || !options.keepLines && firstToken !== 1 /* SyntaxKind.OpenBraceToken */) {\n replaceContent = newLinesAndIndent();\n }\n else if (options.keepLines) {\n replaceContent = cachedSpaces[1];\n }\n }\n else if (secondToken === 4 /* SyntaxKind.CloseBracketToken */) {\n if (firstToken !== 3 /* SyntaxKind.OpenBracketToken */) {\n indentLevel--;\n }\n ;\n if (options.keepLines && numberLineBreaks > 0 || !options.keepLines && firstToken !== 3 /* SyntaxKind.OpenBracketToken */) {\n replaceContent = newLinesAndIndent();\n }\n else if (options.keepLines) {\n replaceContent = cachedSpaces[1];\n }\n }\n else {\n switch (firstToken) {\n case 3 /* SyntaxKind.OpenBracketToken */:\n case 1 /* SyntaxKind.OpenBraceToken */:\n indentLevel++;\n if (options.keepLines && numberLineBreaks > 0 || !options.keepLines) {\n replaceContent = newLinesAndIndent();\n }\n else {\n replaceContent = cachedSpaces[1];\n }\n break;\n case 5 /* SyntaxKind.CommaToken */:\n if (options.keepLines && numberLineBreaks > 0 || !options.keepLines) {\n replaceContent = newLinesAndIndent();\n }\n else {\n replaceContent = cachedSpaces[1];\n }\n break;\n case 12 /* SyntaxKind.LineCommentTrivia */:\n replaceContent = newLinesAndIndent();\n break;\n case 13 /* SyntaxKind.BlockCommentTrivia */:\n if (numberLineBreaks > 0) {\n replaceContent = newLinesAndIndent();\n }\n else if (!needsLineBreak) {\n replaceContent = cachedSpaces[1];\n }\n break;\n case 6 /* SyntaxKind.ColonToken */:\n if (options.keepLines && numberLineBreaks > 0) {\n replaceContent = newLinesAndIndent();\n }\n else if (!needsLineBreak) {\n replaceContent = cachedSpaces[1];\n }\n break;\n case 10 /* SyntaxKind.StringLiteral */:\n if (options.keepLines && numberLineBreaks > 0) {\n replaceContent = newLinesAndIndent();\n }\n else if (secondToken === 6 /* SyntaxKind.ColonToken */ && !needsLineBreak) {\n replaceContent = '';\n }\n break;\n case 7 /* SyntaxKind.NullKeyword */:\n case 8 /* SyntaxKind.TrueKeyword */:\n case 9 /* SyntaxKind.FalseKeyword */:\n case 11 /* SyntaxKind.NumericLiteral */:\n case 2 /* SyntaxKind.CloseBraceToken */:\n case 4 /* SyntaxKind.CloseBracketToken */:\n if (options.keepLines && numberLineBreaks > 0) {\n replaceContent = newLinesAndIndent();\n }\n else {\n if ((secondToken === 12 /* SyntaxKind.LineCommentTrivia */ || secondToken === 13 /* SyntaxKind.BlockCommentTrivia */) && !needsLineBreak) {\n replaceContent = cachedSpaces[1];\n }\n else if (secondToken !== 5 /* SyntaxKind.CommaToken */ && secondToken !== 17 /* SyntaxKind.EOF */) {\n hasError = true;\n }\n }\n break;\n case 16 /* SyntaxKind.Unknown */:\n hasError = true;\n break;\n }\n if (numberLineBreaks > 0 && (secondToken === 12 /* SyntaxKind.LineCommentTrivia */ || secondToken === 13 /* SyntaxKind.BlockCommentTrivia */)) {\n replaceContent = newLinesAndIndent();\n }\n }\n if (secondToken === 17 /* SyntaxKind.EOF */) {\n if (options.keepLines && numberLineBreaks > 0) {\n replaceContent = newLinesAndIndent();\n }\n else {\n replaceContent = options.insertFinalNewline ? eol : '';\n }\n }\n const secondTokenStart = scanner.getTokenOffset() + formatTextStart;\n addEdit(replaceContent, firstTokenEnd, secondTokenStart);\n firstToken = secondToken;\n }\n return editOperations;\n}\nfunction repeat(s, count) {\n let result = '';\n for (let i = 0; i < count; i++) {\n result += s;\n }\n return result;\n}\nfunction computeIndentLevel(content, options) {\n let i = 0;\n let nChars = 0;\n const tabSize = options.tabSize || 4;\n while (i < content.length) {\n let ch = content.charAt(i);\n if (ch === cachedSpaces[1]) {\n nChars++;\n }\n else if (ch === '\\t') {\n nChars += tabSize;\n }\n else {\n break;\n }\n i++;\n }\n return Math.floor(nChars / tabSize);\n}\nfunction getEOL(options, text) {\n for (let i = 0; i < text.length; i++) {\n const ch = text.charAt(i);\n if (ch === '\\r') {\n if (i + 1 < text.length && text.charAt(i + 1) === '\\n') {\n return '\\r\\n';\n }\n return '\\r';\n }\n else if (ch === '\\n') {\n return '\\n';\n }\n }\n return (options && options.eol) || '\\n';\n}\nexport function isEOL(text, offset) {\n return '\\r\\n'.indexOf(text.charAt(offset)) !== -1;\n}\n", "/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n'use strict';\nimport { createScanner } from './scanner';\nvar ParseOptions;\n(function (ParseOptions) {\n ParseOptions.DEFAULT = {\n allowTrailingComma: false\n };\n})(ParseOptions || (ParseOptions = {}));\n/**\n * For a given offset, evaluate the location in the JSON document. Each segment in the location path is either a property name or an array index.\n */\nexport function getLocation(text, position) {\n const segments = []; // strings or numbers\n const earlyReturnException = new Object();\n let previousNode = undefined;\n const previousNodeInst = {\n value: {},\n offset: 0,\n length: 0,\n type: 'object',\n parent: undefined\n };\n let isAtPropertyKey = false;\n function setPreviousNode(value, offset, length, type) {\n previousNodeInst.value = value;\n previousNodeInst.offset = offset;\n previousNodeInst.length = length;\n previousNodeInst.type = type;\n previousNodeInst.colonOffset = undefined;\n previousNode = previousNodeInst;\n }\n try {\n visit(text, {\n onObjectBegin: (offset, length) => {\n if (position <= offset) {\n throw earlyReturnException;\n }\n previousNode = undefined;\n isAtPropertyKey = position > offset;\n segments.push(''); // push a placeholder (will be replaced)\n },\n onObjectProperty: (name, offset, length) => {\n if (position < offset) {\n throw earlyReturnException;\n }\n setPreviousNode(name, offset, length, 'property');\n segments[segments.length - 1] = name;\n if (position <= offset + length) {\n throw earlyReturnException;\n }\n },\n onObjectEnd: (offset, length) => {\n if (position <= offset) {\n throw earlyReturnException;\n }\n previousNode = undefined;\n segments.pop();\n },\n onArrayBegin: (offset, length) => {\n if (position <= offset) {\n throw earlyReturnException;\n }\n previousNode = undefined;\n segments.push(0);\n },\n onArrayEnd: (offset, length) => {\n if (position <= offset) {\n throw earlyReturnException;\n }\n previousNode = undefined;\n segments.pop();\n },\n onLiteralValue: (value, offset, length) => {\n if (position < offset) {\n throw earlyReturnException;\n }\n setPreviousNode(value, offset, length, getNodeType(value));\n if (position <= offset + length) {\n throw earlyReturnException;\n }\n },\n onSeparator: (sep, offset, length) => {\n if (position <= offset) {\n throw earlyReturnException;\n }\n if (sep === ':' && previousNode && previousNode.type === 'property') {\n previousNode.colonOffset = offset;\n isAtPropertyKey = false;\n previousNode = undefined;\n }\n else if (sep === ',') {\n const last = segments[segments.length - 1];\n if (typeof last === 'number') {\n segments[segments.length - 1] = last + 1;\n }\n else {\n isAtPropertyKey = true;\n segments[segments.length - 1] = '';\n }\n previousNode = undefined;\n }\n }\n });\n }\n catch (e) {\n if (e !== earlyReturnException) {\n throw e;\n }\n }\n return {\n path: segments,\n previousNode,\n isAtPropertyKey,\n matches: (pattern) => {\n let k = 0;\n for (let i = 0; k < pattern.length && i < segments.length; i++) {\n if (pattern[k] === segments[i] || pattern[k] === '*') {\n k++;\n }\n else if (pattern[k] !== '**') {\n return false;\n }\n }\n return k === pattern.length;\n }\n };\n}\n/**\n * Parses the given text and returns the object the JSON content represents. On invalid input, the parser tries to be as fault tolerant as possible, but still return a result.\n * Therefore always check the errors list to find out if the input was valid.\n */\nexport function parse(text, errors = [], options = ParseOptions.DEFAULT) {\n let currentProperty = null;\n let currentParent = [];\n const previousParents = [];\n function onValue(value) {\n if (Array.isArray(currentParent)) {\n currentParent.push(value);\n }\n else if (currentProperty !== null) {\n currentParent[currentProperty] = value;\n }\n }\n const visitor = {\n onObjectBegin: () => {\n const object = {};\n onValue(object);\n previousParents.push(currentParent);\n currentParent = object;\n currentProperty = null;\n },\n onObjectProperty: (name) => {\n currentProperty = name;\n },\n onObjectEnd: () => {\n currentParent = previousParents.pop();\n },\n onArrayBegin: () => {\n const array = [];\n onValue(array);\n previousParents.push(currentParent);\n currentParent = array;\n currentProperty = null;\n },\n onArrayEnd: () => {\n currentParent = previousParents.pop();\n },\n onLiteralValue: onValue,\n onError: (error, offset, length) => {\n errors.push({ error, offset, length });\n }\n };\n visit(text, visitor, options);\n return currentParent[0];\n}\n/**\n * Parses the given text and returns a tree representation the JSON content. On invalid input, the parser tries to be as fault tolerant as possible, but still return a result.\n */\nexport function parseTree(text, errors = [], options = ParseOptions.DEFAULT) {\n let currentParent = { type: 'array', offset: -1, length: -1, children: [], parent: undefined }; // artificial root\n function ensurePropertyComplete(endOffset) {\n if (currentParent.type === 'property') {\n currentParent.length = endOffset - currentParent.offset;\n currentParent = currentParent.parent;\n }\n }\n function onValue(valueNode) {\n currentParent.children.push(valueNode);\n return valueNode;\n }\n const visitor = {\n onObjectBegin: (offset) => {\n currentParent = onValue({ type: 'object', offset, length: -1, parent: currentParent, children: [] });\n },\n onObjectProperty: (name, offset, length) => {\n currentParent = onValue({ type: 'property', offset, length: -1, parent: currentParent, children: [] });\n currentParent.children.push({ type: 'string', value: name, offset, length, parent: currentParent });\n },\n onObjectEnd: (offset, length) => {\n ensurePropertyComplete(offset + length); // in case of a missing value for a property: make sure property is complete\n currentParent.length = offset + length - currentParent.offset;\n currentParent = currentParent.parent;\n ensurePropertyComplete(offset + length);\n },\n onArrayBegin: (offset, length) => {\n currentParent = onValue({ type: 'array', offset, length: -1, parent: currentParent, children: [] });\n },\n onArrayEnd: (offset, length) => {\n currentParent.length = offset + length - currentParent.offset;\n currentParent = currentParent.parent;\n ensurePropertyComplete(offset + length);\n },\n onLiteralValue: (value, offset, length) => {\n onValue({ type: getNodeType(value), offset, length, parent: currentParent, value });\n ensurePropertyComplete(offset + length);\n },\n onSeparator: (sep, offset, length) => {\n if (currentParent.type === 'property') {\n if (sep === ':') {\n currentParent.colonOffset = offset;\n }\n else if (sep === ',') {\n ensurePropertyComplete(offset);\n }\n }\n },\n onError: (error, offset, length) => {\n errors.push({ error, offset, length });\n }\n };\n visit(text, visitor, options);\n const result = currentParent.children[0];\n if (result) {\n delete result.parent;\n }\n return result;\n}\n/**\n * Finds the node at the given path in a JSON DOM.\n */\nexport function findNodeAtLocation(root, path) {\n if (!root) {\n return undefined;\n }\n let node = root;\n for (let segment of path) {\n if (typeof segment === 'string') {\n if (node.type !== 'object' || !Array.isArray(node.children)) {\n return undefined;\n }\n let found = false;\n for (const propertyNode of node.children) {\n if (Array.isArray(propertyNode.children) && propertyNode.children[0].value === segment && propertyNode.children.length === 2) {\n node = propertyNode.children[1];\n found = true;\n break;\n }\n }\n if (!found) {\n return undefined;\n }\n }\n else {\n const index = segment;\n if (node.type !== 'array' || index < 0 || !Array.isArray(node.children) || index >= node.children.length) {\n return undefined;\n }\n node = node.children[index];\n }\n }\n return node;\n}\n/**\n * Gets the JSON path of the given JSON DOM node\n */\nexport function getNodePath(node) {\n if (!node.parent || !node.parent.children) {\n return [];\n }\n const path = getNodePath(node.parent);\n if (node.parent.type === 'property') {\n const key = node.parent.children[0].value;\n path.push(key);\n }\n else if (node.parent.type === 'array') {\n const index = node.parent.children.indexOf(node);\n if (index !== -1) {\n path.push(index);\n }\n }\n return path;\n}\n/**\n * Evaluates the JavaScript object of the given JSON DOM node\n */\nexport function getNodeValue(node) {\n switch (node.type) {\n case 'array':\n return node.children.map(getNodeValue);\n case 'object':\n const obj = Object.create(null);\n for (let prop of node.children) {\n const valueNode = prop.children[1];\n if (valueNode) {\n obj[prop.children[0].value] = getNodeValue(valueNode);\n }\n }\n return obj;\n case 'null':\n case 'string':\n case 'number':\n case 'boolean':\n return node.value;\n default:\n return undefined;\n }\n}\nexport function contains(node, offset, includeRightBound = false) {\n return (offset >= node.offset && offset < (node.offset + node.length)) || includeRightBound && (offset === (node.offset + node.length));\n}\n/**\n * Finds the most inner node at the given offset. If includeRightBound is set, also finds nodes that end at the given offset.\n */\nexport function findNodeAtOffset(node, offset, includeRightBound = false) {\n if (contains(node, offset, includeRightBound)) {\n const children = node.children;\n if (Array.isArray(children)) {\n for (let i = 0; i < children.length && children[i].offset <= offset; i++) {\n const item = findNodeAtOffset(children[i], offset, includeRightBound);\n if (item) {\n return item;\n }\n }\n }\n return node;\n }\n return undefined;\n}\n/**\n * Parses the given text and invokes the visitor functions for each object, array and literal reached.\n */\nexport function visit(text, visitor, options = ParseOptions.DEFAULT) {\n const _scanner = createScanner(text, false);\n // Important: Only pass copies of this to visitor functions to prevent accidental modification, and\n // to not affect visitor functions which stored a reference to a previous JSONPath\n const _jsonPath = [];\n // Depth of onXXXBegin() callbacks suppressed. onXXXEnd() decrements this if it isn't 0 already.\n // Callbacks are only called when this value is 0.\n let suppressedCallbacks = 0;\n function toNoArgVisit(visitFunction) {\n return visitFunction ? () => suppressedCallbacks === 0 && visitFunction(_scanner.getTokenOffset(), _scanner.getTokenLength(), _scanner.getTokenStartLine(), _scanner.getTokenStartCharacter()) : () => true;\n }\n function toOneArgVisit(visitFunction) {\n return visitFunction ? (arg) => suppressedCallbacks === 0 && visitFunction(arg, _scanner.getTokenOffset(), _scanner.getTokenLength(), _scanner.getTokenStartLine(), _scanner.getTokenStartCharacter()) : () => true;\n }\n function toOneArgVisitWithPath(visitFunction) {\n return visitFunction ? (arg) => suppressedCallbacks === 0 && visitFunction(arg, _scanner.getTokenOffset(), _scanner.getTokenLength(), _scanner.getTokenStartLine(), _scanner.getTokenStartCharacter(), () => _jsonPath.slice()) : () => true;\n }\n function toBeginVisit(visitFunction) {\n return visitFunction ?\n () => {\n if (suppressedCallbacks > 0) {\n suppressedCallbacks++;\n }\n else {\n let cbReturn = visitFunction(_scanner.getTokenOffset(), _scanner.getTokenLength(), _scanner.getTokenStartLine(), _scanner.getTokenStartCharacter(), () => _jsonPath.slice());\n if (cbReturn === false) {\n suppressedCallbacks = 1;\n }\n }\n }\n : () => true;\n }\n function toEndVisit(visitFunction) {\n return visitFunction ?\n () => {\n if (suppressedCallbacks > 0) {\n suppressedCallbacks--;\n }\n if (suppressedCallbacks === 0) {\n visitFunction(_scanner.getTokenOffset(), _scanner.getTokenLength(), _scanner.getTokenStartLine(), _scanner.getTokenStartCharacter());\n }\n }\n : () => true;\n }\n const onObjectBegin = toBeginVisit(visitor.onObjectBegin), onObjectProperty = toOneArgVisitWithPath(visitor.onObjectProperty), onObjectEnd = toEndVisit(visitor.onObjectEnd), onArrayBegin = toBeginVisit(visitor.onArrayBegin), onArrayEnd = toEndVisit(visitor.onArrayEnd), onLiteralValue = toOneArgVisitWithPath(visitor.onLiteralValue), onSeparator = toOneArgVisit(visitor.onSeparator), onComment = toNoArgVisit(visitor.onComment), onError = toOneArgVisit(visitor.onError);\n const disallowComments = options && options.disallowComments;\n const allowTrailingComma = options && options.allowTrailingComma;\n function scanNext() {\n while (true) {\n const token = _scanner.scan();\n switch (_scanner.getTokenError()) {\n case 4 /* ScanError.InvalidUnicode */:\n handleError(14 /* ParseErrorCode.InvalidUnicode */);\n break;\n case 5 /* ScanError.InvalidEscapeCharacter */:\n handleError(15 /* ParseErrorCode.InvalidEscapeCharacter */);\n break;\n case 3 /* ScanError.UnexpectedEndOfNumber */:\n handleError(13 /* ParseErrorCode.UnexpectedEndOfNumber */);\n break;\n case 1 /* ScanError.UnexpectedEndOfComment */:\n if (!disallowComments) {\n handleError(11 /* ParseErrorCode.UnexpectedEndOfComment */);\n }\n break;\n case 2 /* ScanError.UnexpectedEndOfString */:\n handleError(12 /* ParseErrorCode.UnexpectedEndOfString */);\n break;\n case 6 /* ScanError.InvalidCharacter */:\n handleError(16 /* ParseErrorCode.InvalidCharacter */);\n break;\n }\n switch (token) {\n case 12 /* SyntaxKind.LineCommentTrivia */:\n case 13 /* SyntaxKind.BlockCommentTrivia */:\n if (disallowComments) {\n handleError(10 /* ParseErrorCode.InvalidCommentToken */);\n }\n else {\n onComment();\n }\n break;\n case 16 /* SyntaxKind.Unknown */:\n handleError(1 /* ParseErrorCode.InvalidSymbol */);\n break;\n case 15 /* SyntaxKind.Trivia */:\n case 14 /* SyntaxKind.LineBreakTrivia */:\n break;\n default:\n return token;\n }\n }\n }\n function handleError(error, skipUntilAfter = [], skipUntil = []) {\n onError(error);\n if (skipUntilAfter.length + skipUntil.length > 0) {\n let token = _scanner.getToken();\n while (token !== 17 /* SyntaxKind.EOF */) {\n if (skipUntilAfter.indexOf(token) !== -1) {\n scanNext();\n break;\n }\n else if (skipUntil.indexOf(token) !== -1) {\n break;\n }\n token = scanNext();\n }\n }\n }\n function parseString(isValue) {\n const value = _scanner.getTokenValue();\n if (isValue) {\n onLiteralValue(value);\n }\n else {\n onObjectProperty(value);\n // add property name afterwards\n _jsonPath.push(value);\n }\n scanNext();\n return true;\n }\n function parseLiteral() {\n switch (_scanner.getToken()) {\n case 11 /* SyntaxKind.NumericLiteral */:\n const tokenValue = _scanner.getTokenValue();\n let value = Number(tokenValue);\n if (isNaN(value)) {\n handleError(2 /* ParseErrorCode.InvalidNumberFormat */);\n value = 0;\n }\n onLiteralValue(value);\n break;\n case 7 /* SyntaxKind.NullKeyword */:\n onLiteralValue(null);\n break;\n case 8 /* SyntaxKind.TrueKeyword */:\n onLiteralValue(true);\n break;\n case 9 /* SyntaxKind.FalseKeyword */:\n onLiteralValue(false);\n break;\n default:\n return false;\n }\n scanNext();\n return true;\n }\n function parseProperty() {\n if (_scanner.getToken() !== 10 /* SyntaxKind.StringLiteral */) {\n handleError(3 /* ParseErrorCode.PropertyNameExpected */, [], [2 /* SyntaxKind.CloseBraceToken */, 5 /* SyntaxKind.CommaToken */]);\n return false;\n }\n parseString(false);\n if (_scanner.getToken() === 6 /* SyntaxKind.ColonToken */) {\n onSeparator(':');\n scanNext(); // consume colon\n if (!parseValue()) {\n handleError(4 /* ParseErrorCode.ValueExpected */, [], [2 /* SyntaxKind.CloseBraceToken */, 5 /* SyntaxKind.CommaToken */]);\n }\n }\n else {\n handleError(5 /* ParseErrorCode.ColonExpected */, [], [2 /* SyntaxKind.CloseBraceToken */, 5 /* SyntaxKind.CommaToken */]);\n }\n _jsonPath.pop(); // remove processed property name\n return true;\n }\n function parseObject() {\n onObjectBegin();\n scanNext(); // consume open brace\n let needsComma = false;\n while (_scanner.getToken() !== 2 /* SyntaxKind.CloseBraceToken */ && _scanner.getToken() !== 17 /* SyntaxKind.EOF */) {\n if (_scanner.getToken() === 5 /* SyntaxKind.CommaToken */) {\n if (!needsComma) {\n handleError(4 /* ParseErrorCode.ValueExpected */, [], []);\n }\n onSeparator(',');\n scanNext(); // consume comma\n if (_scanner.getToken() === 2 /* SyntaxKind.CloseBraceToken */ && allowTrailingComma) {\n break;\n }\n }\n else if (needsComma) {\n handleError(6 /* ParseErrorCode.CommaExpected */, [], []);\n }\n if (!parseProperty()) {\n handleError(4 /* ParseErrorCode.ValueExpected */, [], [2 /* SyntaxKind.CloseBraceToken */, 5 /* SyntaxKind.CommaToken */]);\n }\n needsComma = true;\n }\n onObjectEnd();\n if (_scanner.getToken() !== 2 /* SyntaxKind.CloseBraceToken */) {\n handleError(7 /* ParseErrorCode.CloseBraceExpected */, [2 /* SyntaxKind.CloseBraceToken */], []);\n }\n else {\n scanNext(); // consume close brace\n }\n return true;\n }\n function parseArray() {\n onArrayBegin();\n scanNext(); // consume open bracket\n let isFirstElement = true;\n let needsComma = false;\n while (_scanner.getToken() !== 4 /* SyntaxKind.CloseBracketToken */ && _scanner.getToken() !== 17 /* SyntaxKind.EOF */) {\n if (_scanner.getToken() === 5 /* SyntaxKind.CommaToken */) {\n if (!needsComma) {\n handleError(4 /* ParseErrorCode.ValueExpected */, [], []);\n }\n onSeparator(',');\n scanNext(); // consume comma\n if (_scanner.getToken() === 4 /* SyntaxKind.CloseBracketToken */ && allowTrailingComma) {\n break;\n }\n }\n else if (needsComma) {\n handleError(6 /* ParseErrorCode.CommaExpected */, [], []);\n }\n if (isFirstElement) {\n _jsonPath.push(0);\n isFirstElement = false;\n }\n else {\n _jsonPath[_jsonPath.length - 1]++;\n }\n if (!parseValue()) {\n handleError(4 /* ParseErrorCode.ValueExpected */, [], [4 /* SyntaxKind.CloseBracketToken */, 5 /* SyntaxKind.CommaToken */]);\n }\n needsComma = true;\n }\n onArrayEnd();\n if (!isFirstElement) {\n _jsonPath.pop(); // remove array index\n }\n if (_scanner.getToken() !== 4 /* SyntaxKind.CloseBracketToken */) {\n handleError(8 /* ParseErrorCode.CloseBracketExpected */, [4 /* SyntaxKind.CloseBracketToken */], []);\n }\n else {\n scanNext(); // consume close bracket\n }\n return true;\n }\n function parseValue() {\n switch (_scanner.getToken()) {\n case 3 /* SyntaxKind.OpenBracketToken */:\n return parseArray();\n case 1 /* SyntaxKind.OpenBraceToken */:\n return parseObject();\n case 10 /* SyntaxKind.StringLiteral */:\n return parseString(true);\n default:\n return parseLiteral();\n }\n }\n scanNext();\n if (_scanner.getToken() === 17 /* SyntaxKind.EOF */) {\n if (options.allowEmptyContent) {\n return true;\n }\n handleError(4 /* ParseErrorCode.ValueExpected */, [], []);\n return false;\n }\n if (!parseValue()) {\n handleError(4 /* ParseErrorCode.ValueExpected */, [], []);\n return false;\n }\n if (_scanner.getToken() !== 17 /* SyntaxKind.EOF */) {\n handleError(9 /* ParseErrorCode.EndOfFileExpected */, [], []);\n }\n return true;\n}\n/**\n * Takes JSON with JavaScript-style comments and remove\n * them. Optionally replaces every none-newline character\n * of comments with a replaceCharacter\n */\nexport function stripComments(text, replaceCh) {\n let _scanner = createScanner(text), parts = [], kind, offset = 0, pos;\n do {\n pos = _scanner.getPosition();\n kind = _scanner.scan();\n switch (kind) {\n case 12 /* SyntaxKind.LineCommentTrivia */:\n case 13 /* SyntaxKind.BlockCommentTrivia */:\n case 17 /* SyntaxKind.EOF */:\n if (offset !== pos) {\n parts.push(text.substring(offset, pos));\n }\n if (replaceCh !== undefined) {\n parts.push(_scanner.getTokenValue().replace(/[^\\r\\n]/g, replaceCh));\n }\n offset = _scanner.getPosition();\n break;\n }\n } while (kind !== 17 /* SyntaxKind.EOF */);\n return parts.join('');\n}\nexport function getNodeType(value) {\n switch (typeof value) {\n case 'boolean': return 'boolean';\n case 'number': return 'number';\n case 'string': return 'string';\n case 'object': {\n if (!value) {\n return 'null';\n }\n else if (Array.isArray(value)) {\n return 'array';\n }\n return 'object';\n }\n default: return 'null';\n }\n}\n", "/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n'use strict';\nimport { format, isEOL } from './format';\nimport { parseTree, findNodeAtLocation } from './parser';\nexport function removeProperty(text, path, options) {\n return setProperty(text, path, void 0, options);\n}\nexport function setProperty(text, originalPath, value, options) {\n const path = originalPath.slice();\n const errors = [];\n const root = parseTree(text, errors);\n let parent = void 0;\n let lastSegment = void 0;\n while (path.length > 0) {\n lastSegment = path.pop();\n parent = findNodeAtLocation(root, path);\n if (parent === void 0 && value !== void 0) {\n if (typeof lastSegment === 'string') {\n value = { [lastSegment]: value };\n }\n else {\n value = [value];\n }\n }\n else {\n break;\n }\n }\n if (!parent) {\n // empty document\n if (value === void 0) { // delete\n throw new Error('Can not delete in empty document');\n }\n return withFormatting(text, { offset: root ? root.offset : 0, length: root ? root.length : 0, content: JSON.stringify(value) }, options);\n }\n else if (parent.type === 'object' && typeof lastSegment === 'string' && Array.isArray(parent.children)) {\n const existing = findNodeAtLocation(parent, [lastSegment]);\n if (existing !== void 0) {\n if (value === void 0) { // delete\n if (!existing.parent) {\n throw new Error('Malformed AST');\n }\n const propertyIndex = parent.children.indexOf(existing.parent);\n let removeBegin;\n let removeEnd = existing.parent.offset + existing.parent.length;\n if (propertyIndex > 0) {\n // remove the comma of the previous node\n let previous = parent.children[propertyIndex - 1];\n removeBegin = previous.offset + previous.length;\n }\n else {\n removeBegin = parent.offset + 1;\n if (parent.children.length > 1) {\n // remove the comma of the next node\n let next = parent.children[1];\n removeEnd = next.offset;\n }\n }\n return withFormatting(text, { offset: removeBegin, length: removeEnd - removeBegin, content: '' }, options);\n }\n else {\n // set value of existing property\n return withFormatting(text, { offset: existing.offset, length: existing.length, content: JSON.stringify(value) }, options);\n }\n }\n else {\n if (value === void 0) { // delete\n return []; // property does not exist, nothing to do\n }\n const newProperty = `${JSON.stringify(lastSegment)}: ${JSON.stringify(value)}`;\n const index = options.getInsertionIndex ? options.getInsertionIndex(parent.children.map(p => p.children[0].value)) : parent.children.length;\n let edit;\n if (index > 0) {\n let previous = parent.children[index - 1];\n edit = { offset: previous.offset + previous.length, length: 0, content: ',' + newProperty };\n }\n else if (parent.children.length === 0) {\n edit = { offset: parent.offset + 1, length: 0, content: newProperty };\n }\n else {\n edit = { offset: parent.offset + 1, length: 0, content: newProperty + ',' };\n }\n return withFormatting(text, edit, options);\n }\n }\n else if (parent.type === 'array' && typeof lastSegment === 'number' && Array.isArray(parent.children)) {\n const insertIndex = lastSegment;\n if (insertIndex === -1) {\n // Insert\n const newProperty = `${JSON.stringify(value)}`;\n let edit;\n if (parent.children.length === 0) {\n edit = { offset: parent.offset + 1, length: 0, content: newProperty };\n }\n else {\n const previous = parent.children[parent.children.length - 1];\n edit = { offset: previous.offset + previous.length, length: 0, content: ',' + newProperty };\n }\n return withFormatting(text, edit, options);\n }\n else if (value === void 0 && parent.children.length >= 0) {\n // Removal\n const removalIndex = lastSegment;\n const toRemove = parent.children[removalIndex];\n let edit;\n if (parent.children.length === 1) {\n // only item\n edit = { offset: parent.offset + 1, length: parent.length - 2, content: '' };\n }\n else if (parent.children.length - 1 === removalIndex) {\n // last item\n let previous = parent.children[removalIndex - 1];\n let offset = previous.offset + previous.length;\n let parentEndOffset = parent.offset + parent.length;\n edit = { offset, length: parentEndOffset - 2 - offset, content: '' };\n }\n else {\n edit = { offset: toRemove.offset, length: parent.children[removalIndex + 1].offset - toRemove.offset, content: '' };\n }\n return withFormatting(text, edit, options);\n }\n else if (value !== void 0) {\n let edit;\n const newProperty = `${JSON.stringify(value)}`;\n if (!options.isArrayInsertion && parent.children.length > lastSegment) {\n const toModify = parent.children[lastSegment];\n edit = { offset: toModify.offset, length: toModify.length, content: newProperty };\n }\n else if (parent.children.length === 0 || lastSegment === 0) {\n edit = { offset: parent.offset + 1, length: 0, content: parent.children.length === 0 ? newProperty : newProperty + ',' };\n }\n else {\n const index = lastSegment > parent.children.length ? parent.children.length : lastSegment;\n const previous = parent.children[index - 1];\n edit = { offset: previous.offset + previous.length, length: 0, content: ',' + newProperty };\n }\n return withFormatting(text, edit, options);\n }\n else {\n throw new Error(`Can not ${value === void 0 ? 'remove' : (options.isArrayInsertion ? 'insert' : 'modify')} Array index ${insertIndex} as length is not sufficient`);\n }\n }\n else {\n throw new Error(`Can not add ${typeof lastSegment !== 'number' ? 'index' : 'property'} to parent of type ${parent.type}`);\n }\n}\nfunction withFormatting(text, edit, options) {\n if (!options.formattingOptions) {\n return [edit];\n }\n // apply the edit\n let newText = applyEdit(text, edit);\n // format the new text\n let begin = edit.offset;\n let end = edit.offset + edit.content.length;\n if (edit.length === 0 || edit.content.length === 0) { // insert or remove\n while (begin > 0 && !isEOL(newText, begin - 1)) {\n begin--;\n }\n while (end < newText.length && !isEOL(newText, end)) {\n end++;\n }\n }\n const edits = format(newText, { offset: begin, length: end - begin }, { ...options.formattingOptions, keepLines: false });\n // apply the formatting edits and track the begin and end offsets of the changes\n for (let i = edits.length - 1; i >= 0; i--) {\n const edit = edits[i];\n newText = applyEdit(newText, edit);\n begin = Math.min(begin, edit.offset);\n end = Math.max(end, edit.offset + edit.length);\n end += edit.content.length - edit.length;\n }\n // create a single edit with all changes\n const editLength = text.length - (newText.length - end) - begin;\n return [{ offset: begin, length: editLength, content: newText.substring(begin, end) }];\n}\nexport function applyEdit(text, edit) {\n return text.substring(0, edit.offset) + edit.content + text.substring(edit.offset + edit.length);\n}\nexport function isWS(text, offset) {\n return '\\r\\n \\t'.indexOf(text.charAt(offset)) !== -1;\n}\n", "/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n'use strict';\nimport * as formatter from './impl/format';\nimport * as edit from './impl/edit';\nimport * as scanner from './impl/scanner';\nimport * as parser from './impl/parser';\n/**\n * Creates a JSON scanner on the given text.\n * If ignoreTrivia is set, whitespaces or comments are ignored.\n */\nexport const createScanner = scanner.createScanner;\nexport var ScanError;\n(function (ScanError) {\n ScanError[ScanError[\"None\"] = 0] = \"None\";\n ScanError[ScanError[\"UnexpectedEndOfComment\"] = 1] = \"UnexpectedEndOfComment\";\n ScanError[ScanError[\"UnexpectedEndOfString\"] = 2] = \"UnexpectedEndOfString\";\n ScanError[ScanError[\"UnexpectedEndOfNumber\"] = 3] = \"UnexpectedEndOfNumber\";\n ScanError[ScanError[\"InvalidUnicode\"] = 4] = \"InvalidUnicode\";\n ScanError[ScanError[\"InvalidEscapeCharacter\"] = 5] = \"InvalidEscapeCharacter\";\n ScanError[ScanError[\"InvalidCharacter\"] = 6] = \"InvalidCharacter\";\n})(ScanError || (ScanError = {}));\nexport var SyntaxKind;\n(function (SyntaxKind) {\n SyntaxKind[SyntaxKind[\"OpenBraceToken\"] = 1] = \"OpenBraceToken\";\n SyntaxKind[SyntaxKind[\"CloseBraceToken\"] = 2] = \"CloseBraceToken\";\n SyntaxKind[SyntaxKind[\"OpenBracketToken\"] = 3] = \"OpenBracketToken\";\n SyntaxKind[SyntaxKind[\"CloseBracketToken\"] = 4] = \"CloseBracketToken\";\n SyntaxKind[SyntaxKind[\"CommaToken\"] = 5] = \"CommaToken\";\n SyntaxKind[SyntaxKind[\"ColonToken\"] = 6] = \"ColonToken\";\n SyntaxKind[SyntaxKind[\"NullKeyword\"] = 7] = \"NullKeyword\";\n SyntaxKind[SyntaxKind[\"TrueKeyword\"] = 8] = \"TrueKeyword\";\n SyntaxKind[SyntaxKind[\"FalseKeyword\"] = 9] = \"FalseKeyword\";\n SyntaxKind[SyntaxKind[\"StringLiteral\"] = 10] = \"StringLiteral\";\n SyntaxKind[SyntaxKind[\"NumericLiteral\"] = 11] = \"NumericLiteral\";\n SyntaxKind[SyntaxKind[\"LineCommentTrivia\"] = 12] = \"LineCommentTrivia\";\n SyntaxKind[SyntaxKind[\"BlockCommentTrivia\"] = 13] = \"BlockCommentTrivia\";\n SyntaxKind[SyntaxKind[\"LineBreakTrivia\"] = 14] = \"LineBreakTrivia\";\n SyntaxKind[SyntaxKind[\"Trivia\"] = 15] = \"Trivia\";\n SyntaxKind[SyntaxKind[\"Unknown\"] = 16] = \"Unknown\";\n SyntaxKind[SyntaxKind[\"EOF\"] = 17] = \"EOF\";\n})(SyntaxKind || (SyntaxKind = {}));\n/**\n * For a given offset, evaluate the location in the JSON document. Each segment in the location path is either a property name or an array index.\n */\nexport const getLocation = parser.getLocation;\n/**\n * Parses the given text and returns the object the JSON content represents. On invalid input, the parser tries to be as fault tolerant as possible, but still return a result.\n * Therefore, always check the errors list to find out if the input was valid.\n */\nexport const parse = parser.parse;\n/**\n * Parses the given text and returns a tree representation the JSON content. On invalid input, the parser tries to be as fault tolerant as possible, but still return a result.\n */\nexport const parseTree = parser.parseTree;\n/**\n * Finds the node at the given path in a JSON DOM.\n */\nexport const findNodeAtLocation = parser.findNodeAtLocation;\n/**\n * Finds the innermost node at the given offset. If includeRightBound is set, also finds nodes that end at the given offset.\n */\nexport const findNodeAtOffset = parser.findNodeAtOffset;\n/**\n * Gets the JSON path of the given JSON DOM node\n */\nexport const getNodePath = parser.getNodePath;\n/**\n * Evaluates the JavaScript object of the given JSON DOM node\n */\nexport const getNodeValue = parser.getNodeValue;\n/**\n * Parses the given text and invokes the visitor functions for each object, array and literal reached.\n */\nexport const visit = parser.visit;\n/**\n * Takes JSON with JavaScript-style comments and remove\n * them. Optionally replaces every none-newline character\n * of comments with a replaceCharacter\n */\nexport const stripComments = parser.stripComments;\nexport var ParseErrorCode;\n(function (ParseErrorCode) {\n ParseErrorCode[ParseErrorCode[\"InvalidSymbol\"] = 1] = \"InvalidSymbol\";\n ParseErrorCode[ParseErrorCode[\"InvalidNumberFormat\"] = 2] = \"InvalidNumberFormat\";\n ParseErrorCode[ParseErrorCode[\"PropertyNameExpected\"] = 3] = \"PropertyNameExpected\";\n ParseErrorCode[ParseErrorCode[\"ValueExpected\"] = 4] = \"ValueExpected\";\n ParseErrorCode[ParseErrorCode[\"ColonExpected\"] = 5] = \"ColonExpected\";\n ParseErrorCode[ParseErrorCode[\"CommaExpected\"] = 6] = \"CommaExpected\";\n ParseErrorCode[ParseErrorCode[\"CloseBraceExpected\"] = 7] = \"CloseBraceExpected\";\n ParseErrorCode[ParseErrorCode[\"CloseBracketExpected\"] = 8] = \"CloseBracketExpected\";\n ParseErrorCode[ParseErrorCode[\"EndOfFileExpected\"] = 9] = \"EndOfFileExpected\";\n ParseErrorCode[ParseErrorCode[\"InvalidCommentToken\"] = 10] = \"InvalidCommentToken\";\n ParseErrorCode[ParseErrorCode[\"UnexpectedEndOfComment\"] = 11] = \"UnexpectedEndOfComment\";\n ParseErrorCode[ParseErrorCode[\"UnexpectedEndOfString\"] = 12] = \"UnexpectedEndOfString\";\n ParseErrorCode[ParseErrorCode[\"UnexpectedEndOfNumber\"] = 13] = \"UnexpectedEndOfNumber\";\n ParseErrorCode[ParseErrorCode[\"InvalidUnicode\"] = 14] = \"InvalidUnicode\";\n ParseErrorCode[ParseErrorCode[\"InvalidEscapeCharacter\"] = 15] = \"InvalidEscapeCharacter\";\n ParseErrorCode[ParseErrorCode[\"InvalidCharacter\"] = 16] = \"InvalidCharacter\";\n})(ParseErrorCode || (ParseErrorCode = {}));\nexport function printParseErrorCode(code) {\n switch (code) {\n case 1 /* ParseErrorCode.InvalidSymbol */: return 'InvalidSymbol';\n case 2 /* ParseErrorCode.InvalidNumberFormat */: return 'InvalidNumberFormat';\n case 3 /* ParseErrorCode.PropertyNameExpected */: return 'PropertyNameExpected';\n case 4 /* ParseErrorCode.ValueExpected */: return 'ValueExpected';\n case 5 /* ParseErrorCode.ColonExpected */: return 'ColonExpected';\n case 6 /* ParseErrorCode.CommaExpected */: return 'CommaExpected';\n case 7 /* ParseErrorCode.CloseBraceExpected */: return 'CloseBraceExpected';\n case 8 /* ParseErrorCode.CloseBracketExpected */: return 'CloseBracketExpected';\n case 9 /* ParseErrorCode.EndOfFileExpected */: return 'EndOfFileExpected';\n case 10 /* ParseErrorCode.InvalidCommentToken */: return 'InvalidCommentToken';\n case 11 /* ParseErrorCode.UnexpectedEndOfComment */: return 'UnexpectedEndOfComment';\n case 12 /* ParseErrorCode.UnexpectedEndOfString */: return 'UnexpectedEndOfString';\n case 13 /* ParseErrorCode.UnexpectedEndOfNumber */: return 'UnexpectedEndOfNumber';\n case 14 /* ParseErrorCode.InvalidUnicode */: return 'InvalidUnicode';\n case 15 /* ParseErrorCode.InvalidEscapeCharacter */: return 'InvalidEscapeCharacter';\n case 16 /* ParseErrorCode.InvalidCharacter */: return 'InvalidCharacter';\n }\n return '<unknown ParseErrorCode>';\n}\n/**\n * Computes the edit operations needed to format a JSON document.\n *\n * @param documentText The input text\n * @param range The range to format or `undefined` to format the full content\n * @param options The formatting options\n * @returns The edit operations describing the formatting changes to the original document following the format described in {@linkcode EditResult}.\n * To apply the edit operations to the input, use {@linkcode applyEdits}.\n */\nexport function format(documentText, range, options) {\n return formatter.format(documentText, range, options);\n}\n/**\n * Computes the edit operations needed to modify a value in the JSON document.\n *\n * @param documentText The input text\n * @param path The path of the value to change. The path represents either to the document root, a property or an array item.\n * If the path points to an non-existing property or item, it will be created.\n * @param value The new value for the specified property or item. If the value is undefined,\n * the property or item will be removed.\n * @param options Options\n * @returns The edit operations describing the changes to the original document, following the format described in {@linkcode EditResult}.\n * To apply the edit operations to the input, use {@linkcode applyEdits}.\n */\nexport function modify(text, path, value, options) {\n return edit.setProperty(text, path, value, options);\n}\n/**\n * Applies edits to an input string.\n * @param text The input text\n * @param edits Edit operations following the format described in {@linkcode EditResult}.\n * @returns The text with the applied edits.\n * @throws An error if the edit operations are not well-formed as described in {@linkcode EditResult}.\n */\nexport function applyEdits(text, edits) {\n let sortedEdits = edits.slice(0).sort((a, b) => {\n const diff = a.offset - b.offset;\n if (diff === 0) {\n return a.length - b.length;\n }\n return diff;\n });\n let lastModifiedOffset = text.length;\n for (let i = sortedEdits.length - 1; i >= 0; i--) {\n let e = sortedEdits[i];\n if (e.offset + e.length <= lastModifiedOffset) {\n text = edit.applyEdit(text, e);\n }\n else {\n throw new Error('Overlapping edit');\n }\n lastModifiedOffset = e.offset;\n }\n return text;\n}\n", "/**\n * WebAssembly SQLite metadata index for mailx (Android/browser).\n * API-compatible with @bobfrankston/mailx-store's MailxDB.\n * Uses sql.js (SQLite compiled to WebAssembly) for in-browser SQLite.\n *\n * Database is persisted to IndexedDB on every write operation.\n * Bodies are stored in IndexedDB via WebMessageStore (not filesystem).\n */\n\nimport initSqlJs, { type Database } from \"sql.js\";\n// Inline the WebAssembly binary at bundle time (esbuild loader: \".wasm\" =\n// \"binary\"). The import resolves to a Uint8Array of the wasm bytes. We\n// pass these directly to initSqlJs via `wasmBinary`, skipping sql.js's\n// runtime fetch of the .wasm \u2014 Android WebView can't compile WASM\n// fetched from `file://` (no application/wasm MIME, and the ArrayBuffer\n// fallback fetch also blocks). Found via jserv logit 2026-05-14 v1.1.6.1:\n// \"wasm streaming compile failed \u2192 fallback ArrayBuffer instantiation\n// \u2192 both async and sync fetching of the wasm failed\". Embedding makes\n// the android-bootstrap bundle ~700 KB larger but eliminates the runtime\n// fetch dependency entirely. Desktop (msger) doesn't load this bundle \u2014\n// the check `if (!window.mailxapi)` in index.html routes desktop past\n// android-bootstrap.js \u2014 so the extra bytes only ship in the Android APK.\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nimport sqlWasmBinary from \"sql.js/dist/sql-wasm.wasm\";\nimport { parseSearchQuery, CONTACT_RULES } from \"@bobfrankston/mailx-types\";\nimport type { MessageEnvelope, Folder, EmailAddress, PagedResult, MessageQuery } from \"@bobfrankston/mailx-types\";\n\n/** Junk-contact filter regexes \u2014 sourced from contact-rules.jsonc so\n * desktop and Android share one rule definition. */\nconst JUNK_LOCAL_RE = new RegExp(CONTACT_RULES.junk.localExact, \"i\");\nconst JUNK_LOCAL_SUFFIX_RE = new RegExp(CONTACT_RULES.junk.localSuffix, \"i\");\nconst JUNK_LOCAL_PREFIX_RE = new RegExp(CONTACT_RULES.junk.localPrefix, \"i\");\nconst JUNK_DOMAIN_RE = new RegExp(CONTACT_RULES.junk.domain, \"i\");\nconst JUNK_LOCAL_ONEOFF_RE = new RegExp(CONTACT_RULES.junk.localOneoff, \"i\");\nfunction isJunkContact(email: string, name: string): boolean {\n const lower = (email || \"\").toLowerCase();\n const at = lower.indexOf(\"@\");\n const local = at >= 0 ? lower.slice(0, at) : lower;\n const domain = at >= 0 ? lower.slice(at + 1) : \"\";\n if (JUNK_LOCAL_RE.test(local)) return true;\n if (JUNK_LOCAL_SUFFIX_RE.test(local)) return true;\n if (JUNK_LOCAL_PREFIX_RE.test(local)) return true;\n if (JUNK_LOCAL_ONEOFF_RE.test(local)) return true;\n if (domain && JUNK_DOMAIN_RE.test(domain)) return true;\n if (local.length < 2) return true;\n const lname = (name || \"\").trim().toLowerCase();\n if (lname.includes(\"mailer-daemon\") || lname.includes(\"postmaster\")) return true;\n return false;\n}\n\nconst SCHEMA = `\n CREATE TABLE IF NOT EXISTS accounts (\n id TEXT PRIMARY KEY,\n name TEXT NOT NULL,\n email TEXT NOT NULL,\n config_json TEXT NOT NULL,\n last_sync INTEGER DEFAULT 0\n );\n\n CREATE TABLE IF NOT EXISTS folders (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n account_id TEXT NOT NULL REFERENCES accounts(id),\n path TEXT NOT NULL,\n name TEXT NOT NULL,\n special_use TEXT,\n delimiter TEXT DEFAULT '/',\n total_count INTEGER DEFAULT 0,\n unread_count INTEGER DEFAULT 0,\n uidvalidity INTEGER DEFAULT 0,\n highest_modseq TEXT DEFAULT '0',\n UNIQUE(account_id, path)\n );\n\n CREATE TABLE IF NOT EXISTS messages (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n account_id TEXT NOT NULL,\n folder_id INTEGER NOT NULL REFERENCES folders(id),\n uid INTEGER NOT NULL,\n message_id TEXT,\n in_reply_to TEXT,\n refs TEXT,\n date INTEGER NOT NULL,\n subject TEXT DEFAULT '',\n from_address TEXT DEFAULT '',\n from_name TEXT DEFAULT '',\n to_json TEXT DEFAULT '[]',\n cc_json TEXT DEFAULT '[]',\n flags_json TEXT DEFAULT '[]',\n size INTEGER DEFAULT 0,\n has_attachments INTEGER DEFAULT 0,\n preview TEXT DEFAULT '',\n body_path TEXT,\n cached_at INTEGER NOT NULL,\n UNIQUE(account_id, folder_id, uid)\n );\n\n CREATE INDEX IF NOT EXISTS idx_messages_folder_date\n ON messages(account_id, folder_id, date DESC);\n\n CREATE INDEX IF NOT EXISTS idx_messages_message_id\n ON messages(message_id);\n\n CREATE TABLE IF NOT EXISTS queue (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n status TEXT NOT NULL DEFAULT 'pending',\n created_at INTEGER NOT NULL,\n send_after INTEGER NOT NULL,\n attempts INTEGER DEFAULT 0,\n last_attempt INTEGER DEFAULT 0,\n error TEXT,\n from_account TEXT NOT NULL,\n to_json TEXT NOT NULL,\n cc_json TEXT DEFAULT '[]',\n bcc_json TEXT DEFAULT '[]',\n subject TEXT DEFAULT '',\n body_html TEXT DEFAULT '',\n body_text TEXT DEFAULT '',\n in_reply_to TEXT,\n refs TEXT\n );\n\n CREATE TABLE IF NOT EXISTS contacts (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n source TEXT NOT NULL DEFAULT 'sent',\n google_id TEXT,\n name TEXT DEFAULT '',\n email TEXT NOT NULL,\n organization TEXT DEFAULT '',\n last_used INTEGER DEFAULT 0,\n use_count INTEGER DEFAULT 0,\n updated_at INTEGER NOT NULL,\n UNIQUE(email)\n );\n\n CREATE INDEX IF NOT EXISTS idx_contacts_email ON contacts(email);\n CREATE INDEX IF NOT EXISTS idx_contacts_name ON contacts(name);\n\n CREATE TABLE IF NOT EXISTS sync_actions (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n account_id TEXT NOT NULL,\n action TEXT NOT NULL,\n uid INTEGER,\n folder_id INTEGER,\n target_folder_id INTEGER,\n flags_json TEXT,\n raw_message TEXT,\n created_at INTEGER NOT NULL,\n attempts INTEGER DEFAULT 0,\n last_error TEXT,\n UNIQUE(account_id, action, uid, folder_id)\n );\n\n -- Calendar events two-way cache (Android parity with desktop's\n -- packages/mailx-store/db.ts calendar_events table). uuid = stable\n -- local identity, provider_id = Google Calendar event id when known,\n -- dirty = local edit not yet pushed, deleted = tombstone pending delete.\n CREATE TABLE IF NOT EXISTS calendar_events (\n uuid TEXT PRIMARY KEY,\n account_id TEXT NOT NULL,\n provider_id TEXT,\n calendar_id TEXT DEFAULT 'primary',\n title TEXT NOT NULL DEFAULT '',\n start_ms INTEGER NOT NULL,\n end_ms INTEGER NOT NULL,\n all_day INTEGER DEFAULT 0,\n location TEXT DEFAULT '',\n notes TEXT DEFAULT '',\n etag TEXT,\n last_synced INTEGER DEFAULT 0,\n dirty INTEGER DEFAULT 0,\n deleted INTEGER DEFAULT 0,\n updated_at INTEGER NOT NULL\n );\n CREATE INDEX IF NOT EXISTS idx_calendar_events_start ON calendar_events(account_id, start_ms);\n\n CREATE TABLE IF NOT EXISTS tasks (\n uuid TEXT PRIMARY KEY,\n account_id TEXT NOT NULL,\n provider_id TEXT,\n list_id TEXT DEFAULT '@default',\n title TEXT NOT NULL DEFAULT '',\n notes TEXT DEFAULT '',\n due_ms INTEGER,\n completed_ms INTEGER,\n etag TEXT,\n last_synced INTEGER DEFAULT 0,\n dirty INTEGER DEFAULT 0,\n deleted INTEGER DEFAULT 0,\n updated_at INTEGER NOT NULL\n );\n CREATE INDEX IF NOT EXISTS idx_tasks_account ON tasks(account_id);\n\n -- Generic store-sync queue for non-message domains (calendar/tasks/contacts).\n CREATE TABLE IF NOT EXISTS store_sync (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n kind TEXT NOT NULL,\n op TEXT NOT NULL,\n account_id TEXT NOT NULL,\n target_uuid TEXT NOT NULL,\n payload TEXT,\n attempts INTEGER DEFAULT 0,\n last_error TEXT,\n created_at INTEGER NOT NULL,\n UNIQUE(kind, target_uuid, op)\n );\n`;\n\nconst IDB_NAME = \"mailx-sqldb\";\nconst IDB_STORE = \"database\";\nconst IDB_KEY = \"mailx.db\";\n\n// \u2500\u2500 IndexedDB persistence \u2500\u2500\n\nfunction openIdb(): Promise<IDBDatabase> {\n return new Promise((resolve, reject) => {\n const req = indexedDB.open(IDB_NAME, 1);\n req.onupgradeneeded = () => {\n const db = req.result;\n if (!db.objectStoreNames.contains(IDB_STORE)) {\n db.createObjectStore(IDB_STORE);\n }\n };\n req.onsuccess = () => resolve(req.result);\n req.onerror = () => reject(req.error);\n });\n}\n\nasync function loadDbFromIdb(): Promise<Uint8Array | null> {\n const idb = await openIdb();\n return new Promise((resolve, reject) => {\n const tx = idb.transaction(IDB_STORE, \"readonly\");\n const req = tx.objectStore(IDB_STORE).get(IDB_KEY);\n req.onsuccess = () => resolve(req.result ? new Uint8Array(req.result) : null);\n req.onerror = () => reject(req.error);\n });\n}\n\nasync function saveDbToIdb(data: Uint8Array): Promise<void> {\n const idb = await openIdb();\n return new Promise((resolve, reject) => {\n const tx = idb.transaction(IDB_STORE, \"readwrite\");\n tx.objectStore(IDB_STORE).put(data.buffer, IDB_KEY);\n tx.oncomplete = () => resolve();\n tx.onerror = () => reject(tx.error);\n });\n}\n\nasync function clearIdb(): Promise<void> {\n const idb = await openIdb();\n return new Promise((resolve, reject) => {\n const tx = idb.transaction(IDB_STORE, \"readwrite\");\n tx.objectStore(IDB_STORE).delete(IDB_KEY);\n tx.oncomplete = () => resolve();\n tx.onerror = () => reject(tx.error);\n });\n}\n\n// \u2500\u2500 Helper: convert sql.js result to array of objects \u2500\u2500\n\nfunction resultToRows(result: any[]): any[] {\n if (!result || result.length === 0) return [];\n const { columns, values } = result[0];\n return values.map((row: any[]) => {\n const obj: any = {};\n columns.forEach((col: string, i: number) => { obj[col] = row[i]; });\n return obj;\n });\n}\n\nexport class WebMailxDB {\n private db: Database | null = null;\n private ready: Promise<void>;\n private saveTimer: ReturnType<typeof setTimeout> | null = null;\n\n constructor(dbName = \"mailx\") {\n this.ready = this.init(dbName);\n }\n\n private async init(_dbName: string): Promise<void> {\n // wasmBinary is the bundle-inlined Uint8Array (see import + comment\n // at top of file). Bypasses sql.js's runtime fetch entirely \u2014 works\n // identically on Android WebView (file://), browser, desktop msger,\n // and Node tests. locateFile is omitted because nothing else in the\n // sql.js init path fetches anymore once wasmBinary is provided.\n // sql.js's TypeScript declarations don't include `wasmBinary` in\n // the InitSqlJsOptions type, but Emscripten honors it at runtime \u2014\n // the bytes go straight into WebAssembly.instantiate without a\n // fetch. Cast to `any` to bypass the type check.\n const SQL = await initSqlJs({\n wasmBinary: sqlWasmBinary,\n } as any);\n\n // Try to load existing DB from IndexedDB\n const existing = await loadDbFromIdb();\n if (existing) {\n this.db = new SQL.Database(existing);\n } else {\n this.db = new SQL.Database();\n }\n\n this.db.run(\"PRAGMA foreign_keys = ON\");\n this.db.run(SCHEMA);\n this.scheduleSave();\n }\n\n /** Wait for DB initialization */\n async waitReady(): Promise<void> {\n await this.ready;\n this.runOneShotJunkContactPurge();\n }\n\n /** One-shot junk-contact purge \u2014 see desktop equivalent in mailx-store/db.ts.\n * Bump TARGET when filter rules tighten so we sweep historical rows once\n * per device. Flag stored in localStorage (the web DB has no kv table). */\n private runOneShotJunkContactPurge(): void {\n const TARGET = CONTACT_RULES.rulesVersion;\n try {\n const last = localStorage.getItem(\"mailx-contacts-purge-v\");\n if (last === TARGET) return;\n const rows = this.all(\"SELECT id, email, name FROM contacts WHERE source IN ('discovered','sent','received')\") as { id: number; email: string; name: string }[];\n let dropped = 0;\n for (const r of rows) {\n if (isJunkContact(r.email || \"\", r.name || \"\")) {\n this.run(\"DELETE FROM contacts WHERE id = ?\", [r.id]);\n dropped++;\n }\n }\n localStorage.setItem(\"mailx-contacts-purge-v\", TARGET);\n if (dropped > 0) console.log(` [contacts] one-shot purge: dropped ${dropped} junk rows (${TARGET})`);\n } catch (e: any) {\n console.warn(`[contacts] one-shot purge failed: ${e.message}`);\n }\n }\n\n /** Persist DB to IndexedDB (debounced \u2014 batches rapid writes) */\n private scheduleSave(): void {\n if (this.saveTimer) return;\n this.saveTimer = setTimeout(async () => {\n this.saveTimer = null;\n if (this.db) {\n const data = this.db.export();\n await saveDbToIdb(data);\n }\n }, 1000);\n }\n\n /** Force immediate persist */\n async flush(): Promise<void> {\n if (this.saveTimer) {\n clearTimeout(this.saveTimer);\n this.saveTimer = null;\n }\n if (this.db) {\n const data = this.db.export();\n await saveDbToIdb(data);\n }\n }\n\n close(): void {\n if (this.db) {\n this.flush();\n this.db.close();\n this.db = null;\n }\n }\n\n private run(sql: string, params?: any[]): void {\n this.db!.run(sql, params);\n this.scheduleSave();\n }\n\n private get(sql: string, params?: any[]): any {\n const result = this.db!.exec(sql, params);\n const rows = resultToRows(result);\n return rows[0] || null;\n }\n\n private all(sql: string, params?: any[]): any[] {\n const result = this.db!.exec(sql, params);\n return resultToRows(result);\n }\n\n private lastId(): number {\n const row = this.get(\"SELECT last_insert_rowid() as id\");\n return row?.id || 0;\n }\n\n // \u2500\u2500 Accounts \u2500\u2500\n\n upsertAccount(id: string, name: string, email: string, configJson: string): void {\n this.run(\n `INSERT INTO accounts (id, name, email, config_json)\n VALUES (?, ?, ?, ?)\n ON CONFLICT(id) DO UPDATE SET name=?, email=?, config_json=?`,\n [id, name, email, configJson, name, email, configJson]);\n }\n\n getAccounts(): { id: string; name: string; email: string; lastSync: number }[] {\n return this.all(\"SELECT id, name, email, last_sync as lastSync FROM accounts\");\n }\n\n getAccountConfigs(): { id: string; name: string; email: string; configJson: string }[] {\n return this.all(\"SELECT id, name, email, config_json as configJson FROM accounts\");\n }\n\n updateLastSync(accountId: string, timestamp: number): void {\n this.run(\"UPDATE accounts SET last_sync = ? WHERE id = ?\", [timestamp, accountId]);\n }\n\n // \u2500\u2500 Folders \u2500\u2500\n\n upsertFolder(accountId: string, folderPath: string, name: string, specialUse: string, delimiter: string): number {\n const existing = this.get(\n \"SELECT id FROM folders WHERE account_id = ? AND path = ?\",\n [accountId, folderPath]);\n if (existing) {\n this.run(\"UPDATE folders SET name = ?, special_use = ?, delimiter = ? WHERE id = ?\",\n [name, specialUse, delimiter, existing.id]);\n return existing.id;\n }\n this.run(\"INSERT INTO folders (account_id, path, name, special_use, delimiter) VALUES (?, ?, ?, ?, ?)\",\n [accountId, folderPath, name, specialUse, delimiter]);\n return this.lastId();\n }\n\n getFolders(accountId: string): Folder[] {\n const rows = this.all(\"SELECT * FROM folders WHERE account_id = ? ORDER BY path\", [accountId]);\n return rows.map(r => ({\n id: r.id, accountId: r.account_id, path: r.path, name: r.name,\n specialUse: r.special_use, delimiter: r.delimiter,\n totalCount: r.total_count, unreadCount: r.unread_count,\n children: [] as Folder[]\n }));\n }\n\n deleteFolder(folderId: number): void {\n this.run(\"DELETE FROM messages WHERE folder_id = ?\", [folderId]);\n this.run(\"DELETE FROM folders WHERE id = ?\", [folderId]);\n }\n\n markFolderRead(folderId: number): void {\n this.run(\n `UPDATE messages SET flags_json = REPLACE(flags_json, '[]', '[\"\\\\\\\\Seen\"]')\n WHERE folder_id = ? AND flags_json NOT LIKE '%\\\\\\\\Seen%'`, [folderId]);\n this.recalcFolderCounts(folderId);\n }\n\n deleteAllMessages(accountId: string, folderId: number): void {\n this.run(\"DELETE FROM messages WHERE account_id = ? AND folder_id = ?\", [accountId, folderId]);\n this.recalcFolderCounts(folderId);\n }\n\n updateFolderCounts(folderId: number, total: number, unread: number): void {\n this.run(\"UPDATE folders SET total_count = ?, unread_count = ? WHERE id = ?\", [total, unread, folderId]);\n }\n\n updateFolderSync(folderId: number, uidvalidity: number, highestModseq: string): void {\n this.run(\"UPDATE folders SET uidvalidity = ?, highest_modseq = ? WHERE id = ?\",\n [uidvalidity, highestModseq, folderId]);\n }\n\n getFolderSync(folderId: number): { uidvalidity: number; highestModseq: string } {\n const row = this.get(\"SELECT uidvalidity, highest_modseq as highestModseq FROM folders WHERE id = ?\", [folderId]);\n return row || { uidvalidity: 0, highestModseq: \"0\" };\n }\n\n // \u2500\u2500 Messages \u2500\u2500\n\n upsertMessage(msg: {\n accountId: string; folderId: number; uid: number; messageId: string;\n inReplyTo: string; references: string[]; date: number; subject: string;\n from: EmailAddress; to: EmailAddress[]; cc: EmailAddress[];\n flags: string[]; size: number; hasAttachments: boolean; preview: string; bodyPath: string;\n }): number {\n const existing = this.get(\n \"SELECT id FROM messages WHERE account_id = ? AND folder_id = ? AND uid = ?\",\n [msg.accountId, msg.folderId, msg.uid]);\n if (existing) {\n this.run(`UPDATE messages SET flags_json = ?, preview = ?, body_path = ?, cached_at = ? WHERE id = ?`,\n [JSON.stringify(msg.flags), msg.preview, msg.bodyPath, Date.now(), existing.id]);\n return existing.id;\n }\n this.run(\n `INSERT INTO messages (\n account_id, folder_id, uid, message_id, in_reply_to, refs,\n date, subject, from_address, from_name, to_json, cc_json,\n flags_json, size, has_attachments, preview, body_path, cached_at\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,\n [\n msg.accountId, msg.folderId, msg.uid, msg.messageId,\n msg.inReplyTo, JSON.stringify(msg.references),\n msg.date, msg.subject, msg.from.address, msg.from.name,\n JSON.stringify(msg.to), JSON.stringify(msg.cc),\n JSON.stringify(msg.flags), msg.size, msg.hasAttachments ? 1 : 0,\n msg.preview, msg.bodyPath, Date.now()\n ]);\n return this.lastId();\n }\n\n getMessages(query: MessageQuery): PagedResult<MessageEnvelope> {\n const page = query.page || 1;\n const pageSize = query.pageSize || 50;\n const offset = (page - 1) * pageSize;\n const sortCol = query.sort === \"from\" ? \"from_name\" : query.sort === \"subject\" ? \"subject\" : \"date\";\n const sortDir = query.sortDir || \"desc\";\n\n let where = \"account_id = ? AND folder_id = ?\";\n const params: any[] = [query.accountId, query.folderId];\n if (query.search) {\n where += \" AND (subject LIKE ? OR from_name LIKE ? OR from_address LIKE ?)\";\n const term = `%${query.search}%`;\n params.push(term, term, term);\n }\n\n const countRow = this.get(`SELECT COUNT(*) as cnt FROM messages WHERE ${where}`, params);\n const total = countRow?.cnt || 0;\n const rows = this.all(\n `SELECT * FROM messages WHERE ${where} ORDER BY ${sortCol} ${sortDir} LIMIT ? OFFSET ?`,\n [...params, pageSize, offset]);\n return { items: rows.map(r => this.rowToEnvelope(r)), total, page, pageSize };\n }\n\n getUnifiedInbox(page = 1, pageSize = 50): PagedResult<MessageEnvelope> {\n const offset = (page - 1) * pageSize;\n const inboxRows = this.all(\"SELECT id FROM folders WHERE special_use = 'inbox'\");\n if (inboxRows.length === 0) return { items: [], total: 0, page, pageSize };\n const ids = inboxRows.map(r => r.id);\n const placeholders = ids.map(() => \"?\").join(\",\");\n const countRow = this.get(`SELECT COUNT(*) as cnt FROM messages WHERE folder_id IN (${placeholders})`, ids);\n const total = countRow?.cnt || 0;\n const rows = this.all(\n `SELECT * FROM messages WHERE folder_id IN (${placeholders}) ORDER BY date DESC LIMIT ? OFFSET ?`,\n [...ids, pageSize, offset]);\n return { items: rows.map(r => this.rowToEnvelope(r)), total, page, pageSize };\n }\n\n getMessageByUid(accountId: string, uid: number, folderId?: number): MessageEnvelope {\n const sql = folderId != null\n ? \"SELECT * FROM messages WHERE account_id = ? AND uid = ? AND folder_id = ?\"\n : \"SELECT * FROM messages WHERE account_id = ? AND uid = ?\";\n const params = folderId != null ? [accountId, uid, folderId] : [accountId, uid];\n const r = this.get(sql, params);\n if (!r) return null as any;\n return this.rowToEnvelope(r);\n }\n\n getMessageBodyPath(accountId: string, uid: number): string {\n const r = this.get(\"SELECT body_path FROM messages WHERE account_id = ? AND uid = ?\", [accountId, uid]);\n return r?.body_path || \"\";\n }\n\n /** The provider's own message id (Gmail message id) for a uid. Passed to\n * the Gmail provider's trash/move so it doesn't fall back to a capped\n * list-and-hash search that misses messages in a large mailbox. \"\" when\n * unknown \u2014 the provider then uses its (capped) fallback. */\n getProviderId(accountId: string, uid: number): string {\n const r = this.get(\"SELECT provider_id FROM messages WHERE account_id = ? AND uid = ?\", [accountId, uid]);\n return r?.provider_id || \"\";\n }\n\n updateMessageFlags(accountId: string, uid: number, flags: string[]): void {\n this.run(\"UPDATE messages SET flags_json = ? WHERE account_id = ? AND uid = ?\",\n [JSON.stringify(flags), accountId, uid]);\n }\n\n updateBodyPath(accountId: string, uid: number, bodyPath: string): void {\n this.run(\"UPDATE messages SET body_path = ? WHERE account_id = ? AND uid = ?\",\n [bodyPath, accountId, uid]);\n }\n\n getMessagesWithoutBody(accountId: string, limit = 50): { uid: number; folderId: number }[] {\n // \"idb:<acct>/<folder>/<uid>\" means the body is cached in IndexedDB via\n // WebMessageStore. Anything else (NULL, \"\", \"gmail:<id>\", legacy paths)\n // still needs fetching.\n // Prefetch order: smallest first, NULL/0 sizes last, recent within\n // tiebreak. Matches the desktop store \u2014 short notification mails\n // dominate the cache fill on slow Android networks instead of one\n // multi-megabyte attachment monopolizing bandwidth.\n return this.all(\n \"SELECT uid, folder_id as folderId FROM messages WHERE account_id = ? AND (body_path IS NULL OR body_path NOT LIKE 'idb:%') ORDER BY (size IS NULL OR size = 0), size ASC, date DESC LIMIT ?\",\n [accountId, limit]);\n }\n\n getHighestUid(accountId: string, folderId: number): number {\n const r = this.get(\"SELECT MAX(uid) as maxUid FROM messages WHERE account_id = ? AND folder_id = ?\",\n [accountId, folderId]);\n return r?.maxUid || 0;\n }\n\n getOldestDate(accountId: string, folderId: number): number {\n const r = this.get(\"SELECT MIN(date) as minDate FROM messages WHERE account_id = ? AND folder_id = ?\",\n [accountId, folderId]);\n return r?.minDate || 0;\n }\n\n getMessageCount(accountId: string, folderId: number): number {\n const r = this.get(\"SELECT count(*) as cnt FROM messages WHERE account_id = ? AND folder_id = ?\",\n [accountId, folderId]);\n return r?.cnt || 0;\n }\n\n getUidsForFolder(accountId: string, folderId: number): number[] {\n return this.all(\"SELECT uid FROM messages WHERE account_id = ? AND folder_id = ?\",\n [accountId, folderId]).map(r => r.uid);\n }\n\n deleteMessage(accountId: string, uid: number): void {\n const msg = this.get(\"SELECT folder_id FROM messages WHERE account_id = ? AND uid = ?\", [accountId, uid]);\n this.run(\"DELETE FROM messages WHERE account_id = ? AND uid = ?\", [accountId, uid]);\n if (msg) this.recalcFolderCounts(msg.folder_id);\n }\n\n recalcFolderCounts(folderId: number): void {\n const counts = this.get(\n `SELECT COUNT(*) as total,\n SUM(CASE WHEN flags_json NOT LIKE '%\\\\\\\\Seen%' THEN 1 ELSE 0 END) as unread\n FROM messages WHERE folder_id = ?`, [folderId]);\n this.updateFolderCounts(folderId, counts?.total || 0, counts?.unread || 0);\n }\n\n beginTransaction(): void { this.db!.run(\"BEGIN\"); }\n commitTransaction(): void { this.db!.run(\"COMMIT\"); this.scheduleSave(); }\n rollbackTransaction(): void { this.db!.run(\"ROLLBACK\"); }\n\n // \u2500\u2500 Contacts \u2500\u2500\n\n /** Delete every contact row tied to a single Google contact identity\n * (resourceName like \"people/c12345\"). Used by the People-API\n * incremental sync when Google flags a contact as deleted. A single\n * Google contact can have multiple email-rows; remove them all. */\n deleteContactByGoogleId(googleId: string): number {\n if (!googleId) return 0;\n const before = (this.get(\"SELECT COUNT(*) as c FROM contacts WHERE google_id = ?\", [googleId]) as any)?.c || 0;\n this.run(\"DELETE FROM contacts WHERE google_id = ?\", [googleId]);\n return before;\n }\n\n /** Stamp the google_id + organization on an already-recorded contact row.\n * Web side mirrors mailx-store/db.ts \u2014 the Google sync calls\n * `recordSentAddress` first to upsert, then this to attach the\n * Google identity for incremental delete tracking. */\n setContactGoogleId(email: string, googleId: string, organization: string): void {\n if (!email) return;\n this.run(\n \"UPDATE contacts SET source = 'google', google_id = ?, organization = ?, updated_at = ? WHERE email = ?\",\n [googleId, organization || \"\", Date.now(), email]);\n }\n\n recordSentAddress(name: string, email: string): void {\n if (isJunkContact(email, name)) return;\n const now = Date.now();\n const existing = this.get(\"SELECT id FROM contacts WHERE email = ?\", [email]);\n if (existing) {\n this.run(\n \"UPDATE contacts SET name = CASE WHEN ? != '' THEN ? ELSE name END, last_used = ?, use_count = use_count + 1, updated_at = ? WHERE email = ?\",\n [name, name, now, now, email]);\n } else {\n this.run(\n \"INSERT INTO contacts (source, name, email, last_used, use_count, updated_at) VALUES ('sent', ?, ?, ?, 1, ?)\",\n [name, email, now, now]);\n }\n }\n\n seedContactsFromMessages(): number {\n const now = Date.now();\n const rows = this.all(\n `SELECT from_name, from_address, COUNT(*) as cnt, MAX(date) as last\n FROM messages WHERE from_address != '' GROUP BY from_address`);\n let added = 0;\n for (const r of rows) {\n if (isJunkContact(r.from_address, r.from_name || \"\")) continue;\n const existing = this.get(\"SELECT id FROM contacts WHERE email = ?\", [r.from_address]);\n if (!existing) {\n this.run(\n \"INSERT INTO contacts (source, name, email, last_used, use_count, updated_at) VALUES ('received', ?, ?, ?, ?, ?)\",\n [r.from_name || \"\", r.from_address, r.last, r.cnt, now]);\n added++;\n }\n }\n return added;\n }\n\n /** Emails the user denylisted (contacts.jsonc#denylist). Filtered out of\n * autocomplete. Populated by web-service's loadContactsConfig. */\n private _denylist = new Set<string>();\n setContactsDenylist(emails: string[]): void {\n this._denylist = new Set((emails || [])\n .map(e => (e || \"\").trim().toLowerCase())\n .filter(Boolean));\n }\n\n searchContacts(query: string, limit = 10): { name: string; email: string; source: string; useCount: number }[] {\n query = (query || \"\").trim();\n if (!query) return [];\n const q = `%${query}%`;\n // Over-fetch, then drop denylisted rows in JS \u2014 filtering after a\n // hard SQL LIMIT could underfill the result when denylisted rows\n // rank high.\n const rows = this.all(\n `SELECT name, email, source, use_count as useCount FROM contacts\n WHERE email LIKE ? OR name LIKE ?\n ORDER BY use_count DESC, last_used DESC LIMIT ?`, [q, q, limit + 25]);\n return rows\n .filter((r: any) => !this._denylist.has((r.email || \"\").toLowerCase()))\n .slice(0, limit);\n }\n\n /** Address-book listing. Same shape as mailx-store/db.ts:listContacts so\n * the address-book modal renders identically on desktop and Android. */\n listContacts(query: string, page = 1, pageSize = 100): { items: any[]; total: number; page: number; pageSize: number } {\n query = (query || \"\").trim();\n const hasQuery = !!query;\n const q = `%${query}%`;\n const whereClause = hasQuery ? \"WHERE email LIKE ? OR name LIKE ?\" : \"\";\n const params: any[] = hasQuery ? [q, q] : [];\n const totalRow = this.get(`SELECT COUNT(*) as c FROM contacts ${whereClause}`, params);\n const offset = (page - 1) * pageSize;\n const rows = this.all(\n `SELECT name, email, source, google_id, use_count, last_used FROM contacts\n ${whereClause}\n ORDER BY use_count DESC, last_used DESC\n LIMIT ? OFFSET ?`, [...params, pageSize, offset]);\n return {\n items: rows.map((r: any) => ({\n name: r.name, email: r.email, source: r.source,\n googleId: r.google_id || null,\n useCount: r.use_count, lastUsed: r.last_used,\n })),\n total: (totalRow as any)?.c || 0,\n page, pageSize,\n };\n }\n\n upsertContact(name: string, email: string): void {\n if (!email || !/^[^\\s<>@]+@[^\\s<>@]+\\.[^\\s<>@]+$/.test(email)) {\n throw new Error(`Invalid email: ${email}`);\n }\n const now = Date.now();\n const existing = this.get(\"SELECT id FROM contacts WHERE email = ?\", [email]);\n if (existing) {\n this.run(\"UPDATE contacts SET name = ?, updated_at = ? WHERE email = ?\",\n [name || \"\", now, email]);\n } else {\n this.run(\"INSERT INTO contacts (source, name, email, last_used, use_count, updated_at) VALUES ('manual', ?, ?, 0, 0, ?)\",\n [name || \"\", email, now]);\n }\n }\n\n deleteContactLocal(email: string): void {\n this.run(\"DELETE FROM contacts WHERE email = ?\", [email]);\n }\n\n /** Q49 heuristic: has the user ever sent to `recipientEmail` with a\n * non-empty Cc? Scans Sent folder(s). Used by compose to auto-expand\n * the Cc row on reply to a frequent-Cc'd recipient. */\n hasCcHistoryTo(recipientEmail: string): boolean {\n const email = (recipientEmail || \"\").trim().toLowerCase();\n if (!email) return false;\n try {\n const row = this.get(`\n SELECT 1 FROM messages m\n JOIN folders f ON m.folder_id = f.id\n WHERE f.special_use = 'sent'\n AND lower(m.to_json) LIKE ?\n AND m.cc_json IS NOT NULL AND m.cc_json != '[]' AND m.cc_json != ''\n LIMIT 1\n `, [`%\"${email}\"%`]);\n return !!row;\n } catch {\n return false;\n }\n }\n\n // \u2500\u2500 Search \u2500\u2500\n\n searchMessages(query: string, page = 1, pageSize = 50, accountId?: string, folderId?: number): PagedResult<MessageEnvelope> {\n const offset = (page - 1) * pageSize;\n const parsed = parseSearchQuery(query);\n const allParams: any[] = [...parsed.params];\n let where = parsed.conditions.length > 0 ? parsed.conditions.join(\" AND \") : \"1=0\";\n if (accountId && folderId) {\n where += \" AND account_id = ? AND folder_id = ?\";\n allParams.push(accountId, folderId);\n } else if (accountId) {\n where += \" AND account_id = ?\";\n allParams.push(accountId);\n }\n const countRow = this.get(`SELECT COUNT(*) as cnt FROM messages WHERE ${where}`, allParams);\n const total = countRow?.cnt || 0;\n const rows = this.all(\n `SELECT * FROM messages WHERE ${where} ORDER BY date DESC LIMIT ? OFFSET ?`,\n [...allParams, pageSize, offset]);\n return { items: rows.map(r => this.rowToEnvelope(r)), total, page, pageSize };\n }\n\n // \u2500\u2500 Sync Actions \u2500\u2500\n\n queueSyncAction(accountId: string, action: string, uid: number, folderId: number, extra?: {\n targetFolderId?: number; flags?: string[]; rawMessage?: string;\n }): void {\n try {\n this.run(\n `INSERT OR REPLACE INTO sync_actions (account_id, action, uid, folder_id, target_folder_id, flags_json, raw_message, created_at)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,\n [accountId, action, uid, folderId,\n extra?.targetFolderId || null,\n extra?.flags ? JSON.stringify(extra.flags) : null,\n extra?.rawMessage || null,\n Date.now()]);\n } catch { /* UNIQUE constraint */ }\n }\n\n getPendingSyncActions(accountId: string): any[] {\n const rows = this.all(\"SELECT * FROM sync_actions WHERE account_id = ? ORDER BY created_at\", [accountId]);\n return rows.map(r => ({\n id: r.id, action: r.action, uid: r.uid, folderId: r.folder_id,\n targetFolderId: r.target_folder_id,\n flags: r.flags_json ? JSON.parse(r.flags_json) : [],\n rawMessage: r.raw_message, attempts: r.attempts,\n }));\n }\n\n completeSyncAction(id: number): void { this.run(\"DELETE FROM sync_actions WHERE id = ?\", [id]); }\n\n failSyncAction(id: number, error: string): void {\n this.run(\"UPDATE sync_actions SET attempts = attempts + 1, last_error = ? WHERE id = ?\", [error, id]);\n }\n\n /** Delete a queued sync action by (accountId, action, uid) \u2014 used by the\n * send path which tracks queued sends via a unique negative uid rather\n * than threading the row id through the async send pipeline. */\n completeSyncActionByUid(accountId: string, action: string, uid: number): void {\n this.run(\"DELETE FROM sync_actions WHERE account_id = ? AND action = ? AND uid = ?\",\n [accountId, action, uid]);\n }\n\n /** Mark a send-queue action failed by uid \u2014 same tracking-key rationale. */\n failSyncActionByUid(accountId: string, action: string, uid: number, error: string): void {\n this.run(\"UPDATE sync_actions SET attempts = attempts + 1, last_error = ? WHERE account_id = ? AND action = ? AND uid = ?\",\n [error, accountId, action, uid]);\n }\n\n getPendingSyncCount(accountId: string): number {\n const r = this.get(\"SELECT COUNT(*) as cnt FROM sync_actions WHERE account_id = ?\", [accountId]);\n return r?.cnt || 0;\n }\n\n getTotalPendingSyncCount(): number {\n const r = this.get(\"SELECT COUNT(*) as cnt FROM sync_actions\");\n return r?.cnt || 0;\n }\n\n /** Reset the entire database */\n async resetStore(): Promise<void> {\n this.run(\"DELETE FROM sync_actions\");\n this.run(\"DELETE FROM contacts\");\n this.run(\"DELETE FROM messages\");\n this.run(\"DELETE FROM folders\");\n this.run(\"DELETE FROM accounts\");\n this.run(\"DELETE FROM queue\");\n await clearIdb();\n }\n\n // \u2500\u2500 Helpers \u2500\u2500\n\n private rowToEnvelope(r: any): MessageEnvelope {\n return {\n id: r.id, accountId: r.account_id, folderId: r.folder_id,\n uid: r.uid, messageId: r.message_id || \"\", inReplyTo: r.in_reply_to || \"\",\n references: JSON.parse(r.refs || \"[]\"), date: r.date, subject: r.subject,\n from: { name: r.from_name, address: r.from_address },\n to: JSON.parse(r.to_json), cc: JSON.parse(r.cc_json),\n flags: JSON.parse(r.flags_json), size: r.size,\n hasAttachments: !!r.has_attachments, preview: r.preview,\n bodyPath: r.body_path || \"\"\n };\n }\n}\n", "/**\n * IndexedDB-based message body storage for Android/browser.\n * Mirrors FileMessageStore API from @bobfrankston/mailx-store.\n * Stores RFC 2822 message bodies as blobs keyed by accountId/folderId/uid.\n */\n\nconst DB_NAME = \"mailx-bodies\";\nconst DB_VERSION = 1;\nconst STORE_NAME = \"messages\";\n\nfunction openDb(): Promise<IDBDatabase> {\n return new Promise((resolve, reject) => {\n const req = indexedDB.open(DB_NAME, DB_VERSION);\n req.onupgradeneeded = () => {\n const db = req.result;\n if (!db.objectStoreNames.contains(STORE_NAME)) {\n db.createObjectStore(STORE_NAME);\n }\n };\n req.onsuccess = () => resolve(req.result);\n req.onerror = () => reject(req.error);\n });\n}\n\nfunction makeKey(accountId: string, folderId: number, uid: number): string {\n return `${accountId}/${folderId}/${uid}`;\n}\n\nexport class WebMessageStore {\n private dbPromise: Promise<IDBDatabase>;\n\n constructor() {\n this.dbPromise = openDb();\n }\n\n async putMessage(accountId: string, folderId: number, uid: number, raw: Uint8Array | ArrayBuffer): Promise<string> {\n const db = await this.dbPromise;\n const key = makeKey(accountId, folderId, uid);\n const data = raw instanceof Uint8Array ? raw.buffer.slice(raw.byteOffset, raw.byteOffset + raw.byteLength) : raw;\n return new Promise((resolve, reject) => {\n const tx = db.transaction(STORE_NAME, \"readwrite\");\n tx.objectStore(STORE_NAME).put(data, key);\n tx.oncomplete = () => resolve(key);\n tx.onerror = () => reject(tx.error);\n });\n }\n\n async getMessage(accountId: string, folderId: number, uid: number): Promise<Uint8Array | null> {\n const db = await this.dbPromise;\n const key = makeKey(accountId, folderId, uid);\n return new Promise((resolve, reject) => {\n const tx = db.transaction(STORE_NAME, \"readonly\");\n const req = tx.objectStore(STORE_NAME).get(key);\n req.onsuccess = () => {\n if (req.result) {\n resolve(new Uint8Array(req.result as ArrayBuffer));\n } else {\n resolve(null);\n }\n };\n req.onerror = () => reject(req.error);\n });\n }\n\n async deleteMessage(accountId: string, folderId: number, uid: number): Promise<void> {\n const db = await this.dbPromise;\n const key = makeKey(accountId, folderId, uid);\n return new Promise((resolve, reject) => {\n const tx = db.transaction(STORE_NAME, \"readwrite\");\n tx.objectStore(STORE_NAME).delete(key);\n tx.oncomplete = () => resolve();\n tx.onerror = () => reject(tx.error);\n });\n }\n\n async hasMessage(accountId: string, folderId: number, uid: number): Promise<boolean> {\n const db = await this.dbPromise;\n const key = makeKey(accountId, folderId, uid);\n return new Promise((resolve, reject) => {\n const tx = db.transaction(STORE_NAME, \"readonly\");\n const req = tx.objectStore(STORE_NAME).count(IDBKeyRange.only(key));\n req.onsuccess = () => resolve(req.result > 0);\n req.onerror = () => reject(req.error);\n });\n }\n\n /** Clear all stored bodies \u2014 used for \"Reset Store\" */\n async clear(): Promise<void> {\n const db = await this.dbPromise;\n return new Promise((resolve, reject) => {\n const tx = db.transaction(STORE_NAME, \"readwrite\");\n tx.objectStore(STORE_NAME).clear();\n tx.oncomplete = () => resolve();\n tx.onerror = () => reject(tx.error);\n });\n }\n}\n", "/**\n * Web-compatible MailxService for Android/browser.\n * Replaces @bobfrankston/mailx-service which depends on Node.js (fs, dns, mailparser).\n *\n * Key differences from desktop:\n * - Uses WebMailxDB (wa-sqlite) instead of MailxDB (node:sqlite)\n * - Uses WebMessageStore (IndexedDB) instead of FileMessageStore (filesystem)\n * - Uses postal-mime or manual header parsing instead of mailparser's simpleParser\n * - Settings via IndexedDB + GDrive API instead of filesystem\n * - No dns.resolveMx \u2014 provider detection is static (Gmail/Outlook/Yahoo/iCloud)\n */\n\nimport type { WebMailxDB } from \"./db.js\";\nimport type { WebMessageStore } from \"./web-message-store.js\";\nimport type { Folder, AutocompleteSettings, MailxApi } from \"@bobfrankston/mailx-types\";\nimport { sanitizeHtml, encodeQuotedPrintable, htmlToPlainText } from \"@bobfrankston/mailx-types\";\nimport {\n loadSettings, saveSettings, loadAccounts, loadAllowlist, saveAllowlist,\n loadAutocomplete, saveAutocomplete, getStorageInfo\n} from \"./web-settings.js\";\n\n// sanitizeHtml and encodeQuotedPrintable imported from @bobfrankston/mailx-types (shared with desktop)\n\n// \u2500\u2500 Simple email parser (replaces mailparser for browser) \u2500\u2500\n\ninterface ParsedMessage {\n html: string;\n text: string;\n headers: Map<string, string>;\n attachments: { filename: string; contentType: string; size: number; contentId: string; content: Uint8Array }[];\n}\n\n/** Parse an RFC 2822 message from raw bytes. Handles basic MIME. */\nfunction parseEmailSource(raw: string): ParsedMessage {\n const headers = new Map<string, string>();\n const headerEnd = raw.indexOf(\"\\r\\n\\r\\n\");\n const headerSection = headerEnd >= 0 ? raw.substring(0, headerEnd) : raw;\n const body = headerEnd >= 0 ? raw.substring(headerEnd + 4) : \"\";\n\n // Parse headers (handle continuations)\n const headerLines = headerSection.split(\"\\r\\n\");\n let lastKey = \"\";\n for (const line of headerLines) {\n if (line.startsWith(\" \") || line.startsWith(\"\\t\")) {\n // Continuation\n if (lastKey) {\n headers.set(lastKey, (headers.get(lastKey) || \"\") + \" \" + line.trim());\n }\n } else {\n const colon = line.indexOf(\":\");\n if (colon > 0) {\n lastKey = line.substring(0, colon).toLowerCase().trim();\n headers.set(lastKey, line.substring(colon + 1).trim());\n }\n }\n }\n\n const contentType = headers.get(\"content-type\") || \"text/plain\";\n const transferEncoding = (headers.get(\"content-transfer-encoding\") || \"\").toLowerCase();\n const attachments: ParsedMessage[\"attachments\"] = [];\n\n // Check for multipart\n const boundaryMatch = contentType.match(/boundary=\"?([^\";\\s]+)\"?/i);\n if (boundaryMatch) {\n const boundary = boundaryMatch[1];\n return parseMimeParts(body, boundary, headers);\n }\n\n // Single part\n let decoded = decodeBody(body, transferEncoding);\n const isHtml = contentType.includes(\"text/html\");\n\n return {\n html: isHtml ? decoded : \"\",\n text: isHtml ? \"\" : decoded,\n headers,\n attachments,\n };\n}\n\nfunction parseMimeParts(body: string, boundary: string, topHeaders: Map<string, string>): ParsedMessage {\n const parts = body.split(\"--\" + boundary);\n let html = \"\";\n let text = \"\";\n const attachments: ParsedMessage[\"attachments\"] = [];\n\n for (let i = 1; i < parts.length; i++) {\n const part = parts[i];\n if (part.startsWith(\"--\")) break; // End marker\n\n const partHeaderEnd = part.indexOf(\"\\r\\n\\r\\n\");\n if (partHeaderEnd < 0) continue;\n const partHeaderSection = part.substring(0, partHeaderEnd);\n const partBody = part.substring(partHeaderEnd + 4).replace(/\\r?\\n$/, \"\");\n\n // Parse part headers\n const partHeaders = new Map<string, string>();\n const partHeaderLines = partHeaderSection.split(\"\\r\\n\");\n let lastKey = \"\";\n for (const line of partHeaderLines) {\n if (line.startsWith(\" \") || line.startsWith(\"\\t\")) {\n if (lastKey) partHeaders.set(lastKey, (partHeaders.get(lastKey) || \"\") + \" \" + line.trim());\n } else {\n const colon = line.indexOf(\":\");\n if (colon > 0) {\n lastKey = line.substring(0, colon).toLowerCase().trim();\n partHeaders.set(lastKey, line.substring(colon + 1).trim());\n }\n }\n }\n\n const partType = partHeaders.get(\"content-type\") || \"text/plain\";\n const partEncoding = (partHeaders.get(\"content-transfer-encoding\") || \"\").toLowerCase();\n const disposition = partHeaders.get(\"content-disposition\") || \"\";\n\n // Nested multipart\n const nestedBoundary = partType.match(/boundary=\"?([^\";\\s]+)\"?/i);\n if (nestedBoundary) {\n const nested = parseMimeParts(partBody, nestedBoundary[1], topHeaders);\n if (!html && nested.html) html = nested.html;\n if (!text && nested.text) text = nested.text;\n attachments.push(...nested.attachments);\n continue;\n }\n\n if (disposition.includes(\"attachment\") || (partType.includes(\"application/\") && !partType.includes(\"text/\"))) {\n const filenameMatch = disposition.match(/filename=\"?([^\";\\r\\n]+)\"?/i) || partType.match(/name=\"?([^\";\\r\\n]+)\"?/i);\n const decoded = decodeBody(partBody, partEncoding);\n attachments.push({\n filename: filenameMatch?.[1]?.trim() || `attachment-${attachments.length}`,\n contentType: partType.split(\";\")[0].trim(),\n size: decoded.length,\n contentId: (partHeaders.get(\"content-id\") || \"\").replace(/[<>]/g, \"\"),\n content: new TextEncoder().encode(decoded),\n });\n } else if (partType.includes(\"text/html\")) {\n const charsetMatch = partType.match(/charset=\"?([^\";\\s]+)\"?/i);\n html = decodeBody(partBody, partEncoding, charsetMatch?.[1] || \"utf-8\");\n } else if (partType.includes(\"text/plain\")) {\n const charsetMatch = partType.match(/charset=\"?([^\";\\s]+)\"?/i);\n text = decodeBody(partBody, partEncoding, charsetMatch?.[1] || \"utf-8\");\n }\n }\n\n return { html, text, headers: topHeaders, attachments };\n}\n\nfunction decodeBody(body: string, encoding: string, charset: string = \"utf-8\"): string {\n // Step 1: decode the transfer encoding to a byte array\n let bytes: Uint8Array;\n if (encoding === \"base64\") {\n try {\n const binary = atob(body.replace(/\\s/g, \"\"));\n bytes = Uint8Array.from(binary, c => c.charCodeAt(0));\n } catch {\n return body;\n }\n } else if (encoding === \"quoted-printable\") {\n // Decode QP into bytes (NOT into a string \u2014 multi-byte UTF-8 must stay as bytes)\n const cleaned = body.replace(/=\\r?\\n/g, \"\");\n const out: number[] = [];\n for (let i = 0; i < cleaned.length; i++) {\n const c = cleaned[i];\n if (c === \"=\" && i + 2 < cleaned.length && /[0-9A-Fa-f]{2}/.test(cleaned.substr(i + 1, 2))) {\n out.push(parseInt(cleaned.substr(i + 1, 2), 16));\n i += 2;\n } else {\n // Existing character \u2014 encode as its byte (assumes ASCII for QP source)\n out.push(c.charCodeAt(0) & 0xff);\n }\n }\n bytes = new Uint8Array(out);\n } else if (encoding === \"7bit\" || encoding === \"8bit\" || encoding === \"\" || encoding === \"binary\") {\n // No transfer encoding \u2014 body is already a string of single-byte chars\n bytes = Uint8Array.from(body, c => c.charCodeAt(0) & 0xff);\n } else {\n // Unknown encoding \u2014 return as-is\n return body;\n }\n // Step 2: decode bytes using the declared charset (default UTF-8)\n try {\n const normalized = charset.toLowerCase().replace(\"windows-\", \"windows-\").replace(\"iso-\", \"iso-\");\n return new TextDecoder(normalized).decode(bytes);\n } catch {\n // Unknown charset \u2014 fall back to UTF-8 with replacement chars\n return new TextDecoder(\"utf-8\").decode(bytes);\n }\n}\n\n// \u2500\u2500 Quoted-printable encoding (for compose/send) \u2500\u2500\n\n// encodeQuotedPrintable imported from @bobfrankston/mailx-types\n\n// \u2500\u2500 Types for sync manager \u2500\u2500\n\nexport interface WebSyncManager {\n syncAll(): Promise<void>;\n syncFolders(accountId: string): Promise<Folder[]>;\n syncFolder(accountId: string, folderId: number): Promise<void>;\n fetchMessageBody(accountId: string, folderId: number, uid: number): Promise<Uint8Array | null>;\n updateFlagsLocal(accountId: string, uid: number, folderId: number, flags: string[]): Promise<void>;\n trashMessage(accountId: string, folderId: number, uid: number): Promise<void>;\n trashMessages(accountId: string, messages: { uid: number; folderId: number }[]): Promise<void>;\n moveMessage(accountId: string, uid: number, folderId: number, targetFolderId: number): Promise<void>;\n moveMessages(accountId: string, messages: { uid: number; folderId: number }[], targetFolderId: number): Promise<void>;\n moveMessageCrossAccount(accountId: string, uid: number, folderId: number, targetAccountId: string, targetFolderId: number): Promise<void>;\n undeleteMessage(accountId: string, uid: number, folderId: number): Promise<void>;\n queueOutgoingLocal(accountId: string, rawMessage: string): void | Promise<void>;\n saveDraft(accountId: string, raw: string, previousDraftUid?: number, draftId?: string): Promise<number | null>;\n deleteDraft(accountId: string, draftUid: number): Promise<void>;\n reauthenticate(accountId: string): Promise<boolean>;\n searchOnServer(accountId: string, folderPath: string, criteria: any): Promise<number[]>;\n syncAllContacts(): Promise<void>;\n addAccount(account: any): Promise<void>;\n on(event: string, handler: (...args: any[]) => void): void;\n emit(event: string, ...args: any[]): void;\n}\n\n// \u2500\u2500 Service \u2500\u2500\n\nexport class WebMailxService implements MailxApi {\n constructor(\n private db: WebMailxDB,\n private bodyStore: WebMessageStore,\n private syncManager: WebSyncManager,\n ) {}\n\n // \u2500\u2500 Accounts \u2500\u2500\n\n async getAccounts(): Promise<any[]> {\n const dbAccounts = this.db.getAccounts();\n const settings = await loadSettings();\n const ordered: any[] = [];\n for (const cfg of settings.accounts) {\n const a = dbAccounts.find(d => d.id === cfg.id);\n if (a) ordered.push({ ...a, label: cfg.label, defaultSend: cfg.defaultSend || false });\n }\n for (const a of dbAccounts) {\n if (!ordered.find((o: any) => o.id === a.id)) ordered.push(a);\n }\n return ordered;\n }\n\n // \u2500\u2500 Folders \u2500\u2500\n\n getFolders(accountId: string): Folder[] {\n return this.db.getFolders(accountId);\n }\n\n // \u2500\u2500 Messages \u2500\u2500\n\n getUnifiedInbox(page = 1, pageSize = 50): any {\n return this.db.getUnifiedInbox(page, pageSize);\n }\n\n getMessages(accountId: string, folderId: number, page = 1, pageSize = 50, sort = \"date\", sortDir = \"desc\", search?: string): any {\n return this.db.getMessages({ accountId, folderId, page, pageSize, sort: sort as any, sortDir: sortDir as any, search });\n }\n\n async getMessage(accountId: string, uid: number, allowRemote = false, folderId?: number): Promise<any> {\n const envelope = this.db.getMessageByUid(accountId, uid, folderId);\n if (!envelope) throw new Error(\"Message not found\");\n\n let bodyHtml = \"\";\n let bodyText = \"\";\n let hasRemoteContent = false;\n let attachments: { id: number; filename: string; mimeType: string; size: number; contentId: string }[] = [];\n\n let raw: Uint8Array | null = null;\n try {\n raw = await this.syncManager.fetchMessageBody(accountId, envelope.folderId, envelope.uid);\n } catch (fetchErr: any) {\n // Mirror the desktop service: surface as structured bodyError\n // so the viewer shows its dedicated error banner instead of\n // rendering the message text verbatim in the body area.\n const rawErr = fetchErr.message || \"fetch failed\";\n const isTransient = /connection|Too many|UNAVAILABLE|rate|429|5\\d\\d|timeout|ENOTFOUND|ECONNRESET|ETIMEDOUT/i.test(rawErr);\n return {\n ...envelope, bodyHtml: \"\", bodyText: \"\",\n bodyError: rawErr, bodyErrorTransient: isTransient,\n hasRemoteContent: false, remoteAllowed: false, attachments: [], deliveredTo: \"\", returnPath: \"\", listUnsubscribe: \"\"\n };\n }\n\n if (!raw) {\n return {\n ...envelope, bodyHtml: \"\", bodyText: \"\",\n bodyError: \"Message body not cached locally and the server fetch returned nothing.\",\n bodyErrorTransient: true,\n hasRemoteContent: false, remoteAllowed: false, attachments: [], deliveredTo: \"\", returnPath: \"\", listUnsubscribe: \"\"\n };\n } else {\n const source = new TextDecoder().decode(raw);\n const parsed = parseEmailSource(source);\n bodyHtml = parsed.html || \"\";\n bodyText = parsed.text || \"\";\n attachments = (parsed.attachments || []).map((a, i) => ({\n id: i,\n filename: a.filename || `attachment-${i}`,\n mimeType: a.contentType || \"application/octet-stream\",\n size: a.size || 0,\n contentId: a.contentId || \"\"\n }));\n }\n\n // Sanitize HTML + compute flagged-sender state. flaggedSenders /\n // flaggedDomains live in the same allowlist.jsonc as remote-content\n // permissions; matching this on phone parity-fixes the viewer's\n // \u26A0 FLAGGED banner (which only painted on desktop before).\n const allowList = await loadAllowlist();\n const senderAddr = (envelope.from?.address || \"\").toLowerCase();\n const senderDomain = senderAddr.split(\"@\")[1] || \"\";\n const isFlagged = !!(\n (allowList.flaggedSenders || []).some((s: string) => (s || \"\").toLowerCase() === senderAddr) ||\n (allowList.flaggedDomains || []).some((d: string) => (d || \"\").toLowerCase() === senderDomain)\n );\n if (bodyHtml && !allowRemote) {\n const toAddrs = (envelope.to || []).map((a: any) => a.address);\n const isAllowed = allowList.senders.includes(senderAddr) ||\n allowList.domains.includes(senderDomain) ||\n toAddrs.some((a: string) => allowList.recipients?.includes(a));\n\n if (isAllowed) {\n allowRemote = true;\n } else {\n const result = sanitizeHtml(bodyHtml);\n bodyHtml = result.html;\n hasRemoteContent = result.hasRemoteContent;\n }\n }\n\n return {\n ...envelope, bodyHtml, bodyText, hasRemoteContent, remoteAllowed: allowRemote,\n attachments, deliveredTo: \"\", returnPath: \"\", listUnsubscribe: \"\",\n isFlagged,\n };\n }\n\n /** Flag (or unflag) a sender / domain. Mirrors the desktop service so\n * the viewer's right-click \"Flag sender\" / \"Flag domain\" buttons work\n * on phone \u2014 was a no-op on Android before. Toggles membership in\n * flaggedSenders / flaggedDomains in allowlist.jsonc, which syncs\n * back to the cloud copy. */\n async flagSenderOrDomain(type: \"sender\" | \"domain\", value: string): Promise<{ flagged: boolean }> {\n const list = await loadAllowlist() as any;\n const key = type === \"sender\" ? \"flaggedSenders\" : \"flaggedDomains\";\n const arr: string[] = Array.isArray(list[key]) ? list[key] : [];\n const v = (value || \"\").trim().toLowerCase();\n if (!v) return { flagged: false };\n const idx = arr.findIndex((x: string) => (x || \"\").toLowerCase() === v);\n let flagged: boolean;\n if (idx >= 0) {\n arr.splice(idx, 1);\n flagged = false;\n } else {\n arr.push(v);\n flagged = true;\n }\n list[key] = arr;\n await saveAllowlist(list);\n return { flagged };\n }\n\n async updateFlags(accountId: string, uid: number, flags: string[]): Promise<void> {\n const envelope = this.db.getMessageByUid(accountId, uid);\n await this.syncManager.updateFlagsLocal(accountId, uid, envelope?.folderId || 0, flags);\n }\n\n // \u2500\u2500 Remote content allow-list \u2500\u2500\n\n async allowRemoteContent(type: \"sender\" | \"domain\" | \"recipient\", value: string): Promise<void> {\n const list = await loadAllowlist();\n if (type === \"sender\" && !list.senders.includes(value)) list.senders.push(value);\n else if (type === \"domain\" && !list.domains.includes(value)) list.domains.push(value);\n else if (type === \"recipient\") {\n if (!list.recipients) list.recipients = [];\n if (!list.recipients.includes(value)) list.recipients.push(value);\n }\n await saveAllowlist(list);\n }\n\n // \u2500\u2500 Search \u2500\u2500\n\n async search(q: string, page = 1, pageSize = 50, scope = \"all\", accountId?: string, folderId?: number): Promise<any> {\n if (!q.trim()) return { items: [], total: 0, page, pageSize };\n // On mobile, always use local search (no server-side IMAP search)\n if (scope === \"current\" && accountId && folderId) {\n return this.db.searchMessages(q, page, pageSize, accountId, folderId);\n }\n return this.db.searchMessages(q, page, pageSize);\n }\n\n // \u2500\u2500 Sync \u2500\u2500\n\n getSyncPending(): { pending: number } {\n return { pending: this.db.getTotalPendingSyncCount() };\n }\n\n async syncAll(): Promise<void> {\n await this.syncManager.syncAll();\n }\n\n async syncAccount(accountId: string): Promise<void> {\n const folders = await this.syncManager.syncFolders(accountId);\n // INBOX-first: await INBOX so the UI re-renders new mail immediately,\n // then fire the rest in the background so labels don't block the\n // list. S57 (Android parity with desktop's local-first rule).\n const inbox = folders.find(f => f.specialUse === \"inbox\");\n const others = folders.filter(f => f.specialUse !== \"inbox\");\n if (inbox) {\n try { await this.syncManager.syncFolder(accountId, inbox.id); }\n catch (e: any) { console.error(` Skipping INBOX ${inbox.path}: ${e.message}`); }\n }\n // Background fan-out: don't await; errors log. UI already has INBOX.\n (async () => {\n for (const folder of others) {\n try { await this.syncManager.syncFolder(accountId, folder.id); }\n catch (e: any) { console.error(` Skipping folder ${folder.path}: ${e.message}`); }\n }\n })().catch(() => { /* top-level already logged */ });\n }\n\n async reauthenticate(accountId: string): Promise<boolean> {\n return this.syncManager.reauthenticate(accountId);\n }\n\n // \u2500\u2500 Send \u2500\u2500\n\n async send(msg: any): Promise<void> {\n const settings = await loadSettings();\n const account = settings.accounts.find(a => a.id === msg.from);\n if (!account) throw new Error(`Unknown account: ${msg.from}`);\n\n const fromHeader = msg.fromAddress || `${account.name} <${account.email}>`;\n const to = msg.to.map((a: any) => a.name ? `${a.name} <${a.address}>` : a.address).join(\", \");\n const cc = msg.cc?.map((a: any) => a.name ? `${a.name} <${a.address}>` : a.address).join(\", \");\n const bcc = msg.bcc?.map((a: any) => a.name ? `${a.name} <${a.address}>` : a.address).join(\", \");\n // HTML-bodied send gets a multipart/alternative wrapper with a\n // text/plain derived from the HTML \u2014 matches desktop's path; spam\n // filters score HTML-only mail harshly without it.\n const hasHtml = !!msg.bodyHtml;\n const htmlBody = msg.bodyHtml || \"\";\n const textBody = msg.bodyText || (hasHtml ? htmlToPlainText(htmlBody) : \"\");\n const htmlEncoded = hasHtml ? encodeQuotedPrintable(htmlBody) : \"\";\n const textEncoded = encodeQuotedPrintable(textBody);\n\n const domain = account.email.split(\"@\")[1] || \"mailx.local\";\n const messageId = `<${Date.now()}.${Math.random().toString(36).slice(2)}@${domain}>`;\n\n const envelope = [\n `From: ${fromHeader}`, `To: ${to}`,\n cc ? `Cc: ${cc}` : null, bcc ? `Bcc: ${bcc}` : null,\n `Subject: ${msg.subject}`, `Date: ${new Date().toUTCString()}`,\n `Message-ID: ${messageId}`,\n msg.inReplyTo ? `In-Reply-To: ${msg.inReplyTo}` : null,\n msg.references?.length ? `References: ${msg.references.join(\" \")}` : null,\n `MIME-Version: 1.0`,\n ].filter(h => h !== null);\n\n let rawMessage: string;\n if (hasHtml) {\n const altBoundary = `mailx_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 10)}`;\n const body =\n `--${altBoundary}\\r\\n` +\n `Content-Type: text/plain; charset=UTF-8\\r\\n` +\n `Content-Transfer-Encoding: quoted-printable\\r\\n\\r\\n` +\n `${textEncoded}\\r\\n` +\n `--${altBoundary}\\r\\n` +\n `Content-Type: text/html; charset=UTF-8\\r\\n` +\n `Content-Transfer-Encoding: quoted-printable\\r\\n\\r\\n` +\n `${htmlEncoded}\\r\\n` +\n `--${altBoundary}--\\r\\n`;\n const headers = [\n ...envelope,\n `Content-Type: multipart/alternative; boundary=\"${altBoundary}\"`,\n ].join(\"\\r\\n\");\n rawMessage = `${headers}\\r\\n\\r\\n${body}`;\n } else {\n const headers = [\n ...envelope,\n `Content-Type: text/plain; charset=UTF-8`,\n `Content-Transfer-Encoding: quoted-printable`,\n ].join(\"\\r\\n\");\n rawMessage = `${headers}\\r\\n\\r\\n${textEncoded}`;\n }\n\n // queueOutgoingLocal on the Android bridge is async (it flushes\n // sql.js \u2192 IndexedDB before returning so a tab-close in the\n // debounce window can't lose the row). On the web-worker\n // SyncManager it's synchronous and returns void; awaiting an\n // undefined value is benign, so this works for both.\n await this.syncManager.queueOutgoingLocal(account.id, rawMessage);\n\n for (const addr of msg.to) this.db.recordSentAddress(addr.name, addr.address);\n if (msg.cc) for (const addr of msg.cc) this.db.recordSentAddress(addr.name, addr.address);\n if (msg.bcc) for (const addr of msg.bcc) this.db.recordSentAddress(addr.name, addr.address);\n }\n\n // \u2500\u2500 Delete / Move \u2500\u2500\n\n async deleteMessage(accountId: string, uid: number): Promise<void> {\n const envelope = this.db.getMessageByUid(accountId, uid);\n if (!envelope) throw new Error(\"Message not found\");\n await this.syncManager.trashMessage(accountId, envelope.folderId, envelope.uid);\n }\n\n async deleteMessages(accountId: string, uids: number[]): Promise<void> {\n const messages = uids.map(uid => {\n const env = this.db.getMessageByUid(accountId, uid);\n if (!env) return null;\n return { uid: env.uid, folderId: env.folderId };\n }).filter(m => m !== null);\n await this.syncManager.trashMessages(accountId, messages);\n }\n\n async moveMessage(accountId: string, uid: number, targetFolderId: number, targetAccountId?: string): Promise<void> {\n const envelope = this.db.getMessageByUid(accountId, uid);\n if (!envelope) throw new Error(\"Message not found\");\n if (targetAccountId && targetAccountId !== accountId) {\n await this.syncManager.moveMessageCrossAccount(accountId, envelope.uid, envelope.folderId, targetAccountId, targetFolderId);\n } else {\n await this.syncManager.moveMessage(accountId, envelope.uid, envelope.folderId, targetFolderId);\n }\n }\n\n async moveMessages(accountId: string, uids: number[], targetFolderId: number): Promise<void> {\n const messages = uids.map(uid => {\n const env = this.db.getMessageByUid(accountId, uid);\n if (!env) return null;\n return { uid: env.uid, folderId: env.folderId };\n }).filter(m => m !== null);\n await this.syncManager.moveMessages(accountId, messages, targetFolderId);\n }\n\n async undeleteMessage(accountId: string, uid: number, folderId: number): Promise<void> {\n await this.syncManager.undeleteMessage(accountId, uid, folderId);\n }\n\n // \u2500\u2500 Drafts \u2500\u2500\n\n async saveDraft(accountId: string, subject: string, bodyHtml: string, bodyText: string, to?: string, cc?: string, previousDraftUid?: number, draftId?: string): Promise<{ draftUid: number | null; draftId: string }> {\n const settings = await loadSettings();\n const account = settings.accounts.find(a => a.id === accountId);\n if (!account) throw new Error(`Unknown account: ${accountId}`);\n\n const id = draftId || `mailx-draft-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;\n const body = bodyHtml || bodyText || \"\";\n const bodyEncoded = encodeQuotedPrintable(body);\n\n const headers = [\n `From: ${account.name} <${account.email}>`,\n to ? `To: ${to}` : null, cc ? `Cc: ${cc}` : null,\n `Subject: ${subject || \"(no subject)\"}`, `Date: ${new Date().toUTCString()}`,\n `X-Mailx-Draft-ID: ${id}`,\n `MIME-Version: 1.0`, `Content-Type: text/html; charset=UTF-8`, `Content-Transfer-Encoding: quoted-printable`,\n ].filter(h => h !== null).join(\"\\r\\n\");\n const raw = `${headers}\\r\\n\\r\\n${bodyEncoded}`;\n const draftUid = await this.syncManager.saveDraft(accountId, raw, previousDraftUid, id);\n // Was `{ uid, draftId }` \u2014 silent drift from desktop's `{ draftUid, draftId }`\n // contract. Clients reading `data.draftUid` got undefined on Android,\n // breaking dedup on the next save.\n return { draftUid, draftId: id };\n }\n\n async deleteDraft(accountId: string, draftUid: number): Promise<void> {\n await this.syncManager.deleteDraft(accountId, draftUid);\n }\n\n // \u2500\u2500 Contacts \u2500\u2500\n\n searchContacts(query: string): any[] {\n query = (query || \"\").trim();\n if (query.length < 1) return [];\n return this.db.searchContacts(query);\n }\n\n /** Address-book listing \u2014 paginated, filterable. Mirrors mailx-service's\n * signature so the same client-side address-book modal works on Android\n * without an \"ipc(...).listContacts is not a function\" crash. */\n listContacts(query: string, page = 1, pageSize = 100) {\n return this.db.listContacts(query || \"\", page, pageSize);\n }\n\n /** Manual upsert from the address-book UI. The desktop path queues a\n * Google People sync; Android relies on the desktop pushing changes\n * back, so this is local-only for now. */\n upsertContact(name: string, email: string): { ok: true } {\n this.db.upsertContact(name || \"\", email);\n return { ok: true };\n }\n\n deleteContact(email: string): { ok: true } {\n this.db.deleteContactLocal(email);\n return { ok: true };\n }\n\n addContact(name: string, email: string): boolean {\n if (!email || !/^[^\\s<>@]+@[^\\s<>@]+\\.[^\\s<>@]+$/.test(email)) return false;\n this.db.recordSentAddress(name || \"\", email);\n return true;\n }\n\n /** Q49 heuristic mirror: true if the user has ever sent a message to\n * `recipientEmail` that had a non-empty Cc field. Compose uses this to\n * decide whether to auto-expand the Cc row on reply. */\n hasCcHistoryTo(recipientEmail: string): boolean {\n return (this.db as any).hasCcHistoryTo?.(recipientEmail) ?? false;\n }\n\n // \u2500\u2500 Settings \u2500\u2500\n\n async getSettings(): Promise<any> {\n return loadSettings();\n }\n\n async saveSettingsData(settings: any): Promise<void> {\n await saveSettings(settings);\n }\n\n getStorageInfo(): { provider: string; mode: string; folderId?: string; folderName?: string; folderPath?: string; folderOwner?: string } {\n return getStorageInfo();\n }\n\n // \u2500\u2500 Folder management (limited on mobile \u2014 read-only) \u2500\u2500\n\n markFolderRead(folderId: number): void {\n this.db.markFolderRead(folderId);\n }\n\n // \u2500\u2500 Autocomplete \u2500\u2500\n\n async getAutocompleteSettings(): Promise<AutocompleteSettings> {\n return loadAutocomplete();\n }\n\n async saveAutocompleteSettings(settings: AutocompleteSettings): Promise<void> {\n await saveAutocomplete(settings);\n }\n\n async autocomplete(_req: any): Promise<{ suggestion: string }> {\n // Autocomplete disabled on mobile by default\n return { suggestion: \"\" };\n }\n\n // \u2500\u2500 Reset \u2500\u2500\n\n async resetStore(): Promise<void> {\n await this.db.resetStore();\n await this.bodyStore.clear();\n console.log(\"[service] Store reset complete\");\n }\n\n // \u2500\u2500 JSONC config editor (Android: GDrive only; no local config.jsonc) \u2500\u2500\n // Mirror of the desktop service so the in-app editor works on phone.\n // Android sandbox has no per-machine config.jsonc; selecting it returns\n // null (the editor displays \"(file not available on this platform)\").\n\n async readJsoncFile(name: string): Promise<string | null> {\n const WHITELIST = [\"accounts.jsonc\", \"allowlist.jsonc\", \"clients.jsonc\", \"config.jsonc\", \"contacts.jsonc\"];\n if (!WHITELIST.includes(name)) throw new Error(`File not allowed: ${name}`);\n if (name === \"config.jsonc\") return null; // local-only on desktop; n/a on Android\n const { cloudRead } = await import(\"./web-settings.js\");\n return await cloudRead(name);\n }\n\n async writeJsoncFile(name: string, content: string): Promise<void> {\n const WHITELIST = [\"accounts.jsonc\", \"allowlist.jsonc\", \"clients.jsonc\", \"config.jsonc\", \"contacts.jsonc\"];\n if (!WHITELIST.includes(name)) throw new Error(`File not allowed: ${name}`);\n if (name === \"config.jsonc\") throw new Error(\"config.jsonc is local-only \u2014 not editable on Android\");\n const { parse: parseJsonc } = await import(\"jsonc-parser\");\n const errors: any[] = [];\n parseJsonc(content, errors, { allowTrailingComma: true });\n if (errors.length) {\n throw new Error(`JSONC parse error: ${errors.map(e => e.error).join(\", \")}`);\n }\n const { cloudWrite } = await import(\"./web-settings.js\");\n const ok = await cloudWrite(name, content);\n if (!ok) throw new Error(`Failed to save ${name} to Drive`);\n }\n\n async formatJsonc(content: string): Promise<string> {\n const { format, applyEdits } = await import(\"jsonc-parser\");\n const edits = format(content, undefined, {\n tabSize: 2, insertSpaces: true, eol: \"\\n\", insertFinalNewline: true,\n });\n return applyEdits(content, edits);\n }\n\n async readConfigHelp(_name: string): Promise<string> {\n // Help markdown isn't bundled in the Android assets \u2014 return empty\n // so the editor's help panel just shows \"No help available\".\n return \"\";\n }\n\n // \u2500\u2500 Priority senders / domains (Android parity) \u2500\u2500\n // Cached in-memory; refreshed on every read since contacts.jsonc is\n // small (~hundreds of entries) and reads hit IndexedDB cache.\n\n /** Compute and return the priority sender / domain index from the\n * current contacts.jsonc. Reads from cloud (or local cache) every\n * call \u2014 small file, simpler than maintaining a long-lived cache. */\n async getPriorityLists(): Promise<{ senders: string[]; domains: string[] }> {\n const { cloudRead } = await import(\"./web-settings.js\");\n const raw = await cloudRead(\"contacts.jsonc\");\n if (!raw) return { senders: [], domains: [] };\n const cfg = parseJsoncLoose(raw);\n const senders = Array.isArray(cfg?.preferred)\n ? cfg.preferred.filter((e: any) => e?.priority === true && e.email).map((e: any) => (e.email as string).toLowerCase())\n : [];\n const domains = Array.isArray(cfg?.priorityDomains)\n ? cfg.priorityDomains.map((d: string) => (d || \"\").toLowerCase()).filter(Boolean)\n : [];\n return { senders, domains };\n }\n\n async setPrioritySender(email: string, value: boolean, name?: string): Promise<void> {\n const lower = (email || \"\").trim().toLowerCase();\n if (!lower) return;\n const { cloudRead, cloudWrite } = await import(\"./web-settings.js\");\n const raw = await cloudRead(\"contacts.jsonc\");\n const cfg = raw ? parseJsoncLoose(raw) || {} : {};\n if (!Array.isArray(cfg.preferred)) cfg.preferred = [];\n const idx = cfg.preferred.findIndex((e: any) => (e?.email || \"\").toLowerCase() === lower);\n if (idx >= 0) {\n if (value) cfg.preferred[idx].priority = true;\n else delete cfg.preferred[idx].priority;\n } else if (value) {\n cfg.preferred.push({ name: name || \"\", email, priority: true });\n }\n await cloudWrite(\"contacts.jsonc\", JSON.stringify(cfg, null, 2));\n }\n\n async setPriorityDomain(domain: string, value: boolean): Promise<void> {\n const lower = (domain || \"\").trim().toLowerCase();\n if (!lower) return;\n const { cloudRead, cloudWrite } = await import(\"./web-settings.js\");\n const raw = await cloudRead(\"contacts.jsonc\");\n const cfg = raw ? parseJsoncLoose(raw) || {} : {};\n if (!Array.isArray(cfg.priorityDomains)) cfg.priorityDomains = [];\n const i = cfg.priorityDomains.findIndex((d: string) => (d || \"\").toLowerCase() === lower);\n if (value && i < 0) cfg.priorityDomains.push(lower);\n else if (!value && i >= 0) cfg.priorityDomains.splice(i, 1);\n await cloudWrite(\"contacts.jsonc\", JSON.stringify(cfg, null, 2));\n }\n\n // \u2500\u2500 MailxApi contract: name aliases \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n // The IPC dispatch names (`sendMessage`, `searchMessages`) differ from\n // the historical web method names (`send`, `search`). Thin aliases keep\n // the existing internal method bodies while satisfying `implements\n // MailxApi`. NEW methods should use the IPC name directly so this\n // section doesn't grow.\n sendMessage(msg: any): Promise<void> { return this.send(msg); }\n searchMessages(query: string, page?: number, pageSize?: number, scope?: string, accountId?: string, folderId?: number, _includeTrashSpam?: boolean): Promise<any> {\n // Android `search` lacks the includeTrashSpam flag \u2014 folder scoping\n // is enforced UI-side anyway. Drop the 7th argument silently.\n return this.search(query, page, pageSize, scope, accountId, folderId);\n }\n\n // \u2500\u2500 MailxApi contract: explicit stubs for unimplemented Android features \u2500\n //\n // Every method below is in the contract but has no Android implementation\n // today. Each is declared explicitly so it's *visible* in this file \u2014\n // before the contract was added, these were just absent and IPC calls\n // returned \"parent bridge has no method X\", silently swallowed by\n // `.catch()` in callers. Now the gap is in one auditable list.\n //\n // Implementation policy:\n // - Pure read with no Android backing: return [] / {} / null / false.\n // UI degrades gracefully; no crash.\n // - Write that mutates state: throw `notImpl()` so a UI button that\n // calls it surfaces an error rather than appearing to succeed.\n // - OS-specific (Word, msger popups, OS file open): also `notImpl()`.\n // These are declared optional `?:` in the contract so we technically\n // could omit them entirely \u2014 explicit stubs are clearer.\n //\n // To wire one up: replace the stub body, run tsc, the contract enforces\n // the signature.\n\n private notImpl(name: string): never {\n throw new Error(`Not implemented on Android: ${name}`);\n }\n\n // Threads / attachments / message reads\n getThreadMessages(_accountId: string, _threadId: string): any { return []; }\n async getAttachment(_accountId: string, _uid: number, _attachmentId: number, _folderId?: number): Promise<{ content: any; contentType: string; filename: string }> { return this.notImpl(\"getAttachment\"); }\n // Android opens attachments via the native bridge (_nativeBridge.openAttachment),\n // not this service path \u2014 getAttachment + base64 hand-off covers it.\n async openAttachment(_accountId: string, _uid: number, _attachmentId: number, _folderId?: number): Promise<{ ok: boolean; path: string }> { return this.notImpl(\"openAttachment\"); }\n\n // Spam / abuse\n async markAsSpamMessages(_accountId: string, _uids: number[]): Promise<{ targetFolderId: number; moved: number }> { return this.notImpl(\"markAsSpamMessages\"); }\n async recordSpamReport(_accountId: string, _uid: number, _folderId: number): Promise<any> { return this.notImpl(\"recordSpamReport\"); }\n\n // Folder CRUD\n async createFolder(_accountId: string, _parentPath: string, _name: string): Promise<void> { this.notImpl(\"createFolder\"); }\n async renameFolder(_accountId: string, _folderId: number, _newName: string): Promise<void> { this.notImpl(\"renameFolder\"); }\n async deleteFolder(_accountId: string, _folderId: number): Promise<void> { this.notImpl(\"deleteFolder\"); }\n async moveFolderToTrash(_accountId: string, _folderId: number): Promise<void> { this.notImpl(\"moveFolderToTrash\"); }\n async emptyFolder(_accountId: string, _folderId: number): Promise<void> { this.notImpl(\"emptyFolder\"); }\n\n // Outbox management\n getOutboxStatus(): any { return { count: 0, items: [] }; }\n listQueuedOutgoing(): any[] { return []; }\n cancelQueuedOutgoing(_filePath: string): { ok: true } { return { ok: true }; }\n\n // Sync infrastructure \u2014 getSyncPending already defined above\n async drainStoreSync(): Promise<void> { /* no-op on Android */ }\n reauthGoogleScopes(): { cleared: number } { return { cleared: 0 }; }\n\n // Contacts extensions. The contacts.jsonc mutation logic is shared with\n // the desktop service \u2014 see mailx-types/contacts-config.ts. These used\n // to be `notImpl()` stubs, so the phone's \u2605 / \u2298 autocomplete buttons did\n // nothing; now they run the same code desktop does.\n async addPreferredContact(entry: { name: string; email: string; source?: string; organization?: string }): Promise<void> {\n const { cloudRead, cloudWrite } = await import(\"./web-settings.js\");\n const { addContactsPreferredEntry } = await import(\"@bobfrankston/mailx-types\");\n await addContactsPreferredEntry(entry, cloudRead, cloudWrite);\n await this.loadContactsConfig();\n }\n async addToDenylist(email: string): Promise<void> {\n const { cloudRead, cloudWrite } = await import(\"./web-settings.js\");\n const { addContactsDenylistEntry } = await import(\"@bobfrankston/mailx-types\");\n await addContactsDenylistEntry(email, cloudRead, cloudWrite);\n await this.loadContactsConfig();\n }\n hasBccHistoryTo(_email: string): boolean { return false; }\n /** Pull the shared GDrive `contacts.jsonc` and merge its entries into the\n * local contacts table. Desktop flushes the full union there (everything\n * it discovered from its mailbox corpus + Google contacts + preferred);\n * this is how an Android device gets contacts it never saw in its own\n * (partial) on-device corpus. Called once at startup \u2014 re-importing on a\n * loop would bump `use_count` every pass and distort autocomplete rank. */\n async loadContactsConfig(): Promise<any> {\n try {\n const { cloudRead } = await import(\"./web-settings.js\");\n const raw = await cloudRead(\"contacts.jsonc\");\n if (!raw) return null;\n const cfg = parseJsoncLoose(raw);\n if (!cfg) return null;\n // Apply the denylist so denylisted addresses are filtered out of\n // autocomplete \u2014 without this the \u2298 button writes the cloud file\n // but the phone keeps suggesting the address.\n this.db.setContactsDenylist(Array.isArray(cfg.denylist) ? cfg.denylist : []);\n let imported = 0;\n for (const list of [cfg.preferred, cfg.discovered]) {\n if (!Array.isArray(list)) continue;\n for (const e of list) {\n const email = (e?.email || \"\").trim();\n if (!email) continue;\n this.db.recordSentAddress((e?.name || \"\").trim(), email);\n imported++;\n }\n }\n if (imported > 0) console.log(`[contacts] loaded ${imported} from contacts.jsonc`);\n return { imported };\n } catch (e: any) {\n console.error(`[contacts] loadContactsConfig failed: ${e?.message || e}`);\n return null;\n }\n }\n\n // Calendar \u2014 Android UI has its own native calendar; no JS-side data.\n async getCalendarEvents(_fromMs: number, _toMs: number): Promise<any[]> { return []; }\n async createCalendarEvent(_ev: any): Promise<{ uuid: string }> { return this.notImpl(\"createCalendarEvent\"); }\n async updateCalendarEvent(_uuid: string, _patch: any): Promise<{ ok: true }> { return this.notImpl(\"updateCalendarEvent\"); }\n async deleteCalendarEvent(_uuid: string): Promise<{ ok: true }> { return this.notImpl(\"deleteCalendarEvent\"); }\n\n // Tasks \u2014 same story\n async getTasks(_includeCompleted?: boolean): Promise<any[]> { return []; }\n async createTask(_t: { title: string; notes?: string; dueMs?: number }): Promise<{ uuid: string }> { return this.notImpl(\"createTask\"); }\n async updateTask(_uuid: string, _patch: any): Promise<{ ok: true }> { return this.notImpl(\"updateTask\"); }\n async deleteTask(_uuid: string): Promise<{ ok: true }> { return this.notImpl(\"deleteTask\"); }\n\n // User dictionary (cloud-mirrored) \u2014 Android can implement these via\n // the same userdict.csv cloud round-trip the desktop uses; until that\n // wire-up lands, return safe defaults so spellcheck.ts catch() paths\n // don't fire and clutter logs.\n async getUserDict(): Promise<string[]> { return []; }\n async addUserDictWord(_word: string): Promise<string[]> { return []; }\n async addUserDictWords(_words: string[]): Promise<string[]> { return []; }\n async removeUserDictWord(_word: string): Promise<string[]> { return []; }\n\n // Diagnostics / version / primary account\n getDiagnostics(): any { return { ok: true, platform: \"android\" }; }\n getPrimaryAccount(_feature?: string): any { return null; }\n getVersion(): any { return { version: \"android\", platform: \"android\" }; }\n consumePendingMailto(): any { return null; }\n logClientEvent(..._args: any[]): void { /* no-op \u2014 server-side logging not wired on Android */ }\n\n // Setup / repair / unsubscribe\n async setupAccount(_name: string, _email: string, _password?: string): Promise<{ ok: boolean; error?: string; message?: string }> { return this.notImpl(\"setupAccount\"); }\n async repairAccounts(): Promise<{ ok: boolean; error?: string; message?: string }> { return this.notImpl(\"repairAccounts\"); }\n async unsubscribeOneClick(_url: string): Promise<{ ok: boolean; status: number; statusText: string }> { return this.notImpl(\"unsubscribeOneClick\"); }\n\n // AI transforms \u2014 pipe through to web autocomplete or no-op\n async aiTransform(_req: any): Promise<any> { return this.notImpl(\"aiTransform\"); }\n}\n\n/** Loose JSONC parse \u2014 strips // comments and trailing commas before JSON.parse.\n * Sufficient for contacts.jsonc which is machine-written; doesn't pull in\n * jsonc-parser as a dep on the Android side where bundle size matters. */\nfunction parseJsoncLoose(raw: string): any {\n try {\n const stripped = raw\n .replace(/^\\s*\\/\\/.*$/gm, \"\")\n .replace(/,(\\s*[}\\]])/g, \"$1\");\n return JSON.parse(stripped);\n } catch { return null; }\n}\n", "/**\n * Android bootstrap \u2014 wires WebMailxDB + WebMessageStore + GmailApiWebProvider + WebMailxService\n * into the mailxapi bridge. This replaces Node.js backend for Android WebView.\n *\n * On Android, everything runs in the same JavaScript context:\n * - wa-sqlite for metadata (via WebMailxDB)\n * - IndexedDB for message bodies (via WebMessageStore)\n * - Gmail/Outlook sync via REST APIs (plain fetch \u2014 no native bridge needed)\n * - IMAP accounts use BridgeTransport (via MAUI TCP bridge) \u2014 not yet implemented\n *\n * The existing client UI (app.ts, components/) is completely unchanged \u2014\n * it calls window.mailxapi.* which this module provides.\n */\n\nimport { WebMailxDB } from \"./db.js\";\nimport { WebMessageStore } from \"./web-message-store.js\";\nimport { WebMailxService, type WebSyncManager } from \"./web-service.js\";\nimport {\n loadAccounts, loadAccountsFromCloud, saveAccounts, loadSettings, clearSettings, getDeviceId,\n setGDriveTokenProvider, setGDriveFolderId\n} from \"./web-settings.js\";\nimport { GmailApiWebProvider } from \"./gmail-api-web.js\";\nimport { ImapWebProvider } from \"./imap-web-provider.js\";\nimport { SmtpClient, type SmtpAuth } from \"@bobfrankston/smtp-direct\";\nimport { BridgeTcpTransport } from \"@bobfrankston/tcp-transport\";\nimport type { MailProvider, ProviderMessage } from \"./provider-types.js\";\nimport type { Folder, EmailAddress, AccountConfig } from \"@bobfrankston/mailx-types\";\n\n// \u2500\u2500 State \u2500\u2500\n\nlet db: WebMailxDB;\nlet bodyStore: WebMessageStore;\nlet service: WebMailxService;\nlet syncManager: AndroidSyncManager;\nconst eventHandlers: ((event: any) => void)[] = [];\n\n// \u2500\u2500 Event emitter \u2500\u2500\n\nfunction emitEvent(event: any): void {\n for (const h of eventHandlers) {\n try { h(event); } catch { /* ignore */ }\n }\n if (typeof (window as any)._msgapiServiceEvent === \"function\") {\n (window as any)._msgapiServiceEvent(event);\n }\n}\n\n// \u2500\u2500 Helpers \u2500\u2500\n\nfunction toEmailAddress(addr: { name?: string; address?: string } | undefined): EmailAddress {\n return { name: addr?.name || \"\", address: addr?.address || \"\" };\n}\n\n/** Verbose log \u2014 goes to logit but doesn't clutter the screen (silent=true) */\nfunction vlog(msg: string): void {\n try {\n fetch(`https://rmf39.aaz.lt/logit/${encodeURIComponent(\"V/\" + msg.substring(0, 800))}?log=mailx-android&silent=true`).catch(() => {});\n } catch { /* ignore */ }\n}\n\n// \u2500\u2500 Sync Manager \u2500\u2500\n\nclass AndroidSyncManager implements WebSyncManager {\n private providers = new Map<string, MailProvider>();\n private tokenProviders = new Map<string, () => Promise<string>>();\n // One prefetch session per account \u2014 prevents every syncAll tick from\n // spawning parallel fetch loops that race on IndexedDB and blow through\n // Gmail's per-user quota.\n private prefetchingAccounts = new Set<string>();\n\n constructor(\n private db: WebMailxDB,\n private bodyStore: WebMessageStore,\n ) {}\n\n on(_event: string, _handler: (...args: any[]) => void): void { /* stub */ }\n emit(event: string, ...args: any[]): void { emitEvent({ type: event, ...args[0] }); }\n\n async addAccount(account: AccountConfig): Promise<void> {\n vlog(`addAccount id=${account.id} email=${account.email} host=${account.imap?.host} auth=${account.imap?.auth}`);\n this.db.upsertAccount(account.id, account.name, account.email, JSON.stringify(account));\n // Idempotent: a provider already registered for this account is kept\n // as-is. The Android bootstrap re-runs the account load periodically;\n // recreating the provider each time built a fresh ImapWebProvider +\n // BridgeTransport and replaced the live one \u2014 which orphaned any\n // body fetch in flight on the old provider, so `fetchOne` came back\n // with no source and the message showed \"Body parsed empty\". A real\n // config change is rare and handled by a restart.\n if (this.providers.has(account.id)) {\n vlog(`addAccount ${account.id}: provider already registered \u2014 keeping it`);\n return;\n }\n if (this.isGmailAccount(account)) {\n const tokenProvider = this.tokenProviders.get(account.id);\n if (tokenProvider) {\n this.providers.set(account.id, new GmailApiWebProvider(tokenProvider));\n console.log(`[sync] ${account.id}: Gmail API provider registered`);\n } else {\n console.warn(`[sync] ${account.id}: no token provider`);\n }\n } else if (account.imap?.host && account.imap?.user) {\n // Generic IMAP account \u2014 use BridgeTransport through MAUI's TCP bridge\n try {\n const provider = new ImapWebProvider({\n server: account.imap.host,\n port: account.imap.port || 993,\n username: account.imap.user,\n password: account.imap.password,\n inactivityTimeout: 300000, // 300s for slow Dovecot\n fetchChunkSize: 10,\n fetchChunkSizeMax: 100,\n }, () => new BridgeTcpTransport());\n this.providers.set(account.id, provider);\n vlog(`addAccount ${account.id}: IMAP provider registered (${account.imap.host}:${account.imap.port})`);\n console.log(`[sync] ${account.id}: IMAP provider registered (${account.imap.host})`);\n } catch (e: any) {\n vlog(`addAccount ${account.id}: IMAP provider FAILED: ${e.message}`);\n console.error(`[sync] ${account.id}: IMAP provider failed: ${e.message}`);\n }\n } else {\n vlog(`addAccount ${account.id}: no imap config, skipping`);\n }\n }\n\n setTokenProvider(accountId: string, provider: () => Promise<string>): void {\n this.tokenProviders.set(accountId, provider);\n }\n\n private isGmailAccount(account: AccountConfig): boolean {\n return account.imap?.host?.includes(\"gmail\") || account.email?.endsWith(\"@gmail.com\") || false;\n }\n\n private getProvider(accountId: string): MailProvider | null {\n return this.providers.get(accountId) || null;\n }\n\n async syncAll(): Promise<void> {\n const accounts = this.db.getAccounts();\n vlog(`syncAll: ${accounts.length} accounts in DB: ${accounts.map(a => a.id).join(\",\")}`);\n\n // Phase 1: Sync INBOX for every account first \u2014 user sees new mail fast.\n for (const account of accounts) {\n if (!this.providers.has(account.id)) continue;\n try {\n const folders = await this.syncFolders(account.id);\n const inbox = folders.find(f => f.specialUse === \"inbox\");\n if (inbox) {\n await this.syncFolder(account.id, inbox.id);\n emitEvent({ type: \"syncComplete\", accountId: account.id });\n }\n } catch (e: any) {\n console.error(`[sync] ${account.id} inbox: ${e.message}`);\n }\n }\n\n // Phase 2: Remaining folders (sent, drafts, trash, then everything else).\n for (const account of accounts) {\n if (!this.providers.has(account.id)) continue;\n try {\n const folders = this.db.getFolders(account.id);\n const remaining = folders.filter(f => f.specialUse !== \"inbox\");\n for (const folder of remaining) {\n try { await this.syncFolder(account.id, folder.id); }\n catch (e: any) { console.error(`[sync] Skip ${folder.path}: ${e.message}`); }\n }\n this.db.updateLastSync(account.id, Date.now());\n emitEvent({ type: \"syncComplete\", accountId: account.id });\n } catch (e: any) {\n console.error(`[sync] ${account.id}: ${e.message}`);\n vlog(`syncAll: ${account.id} ERROR: ${e.message}`);\n emitEvent({ type: \"syncError\", accountId: account.id, error: e.message });\n }\n }\n\n // Phase 3: background body prefetch. Fire-and-forget \u2014 sync itself is\n // already done and the UI doesn't wait on this. Per-account guard means\n // a slow account can't block a fast one.\n for (const account of accounts) {\n if (!this.providers.has(account.id)) continue;\n this.prefetchBodies(account.id).catch(e =>\n console.error(`[prefetch] ${account.id}: ${e.message}`));\n }\n }\n\n /** Background body prefetch \u2014 download bodies for messages that don't have\n * them yet, so tapping a message in the list opens instantly from cache. */\n async prefetchBodies(accountId: string): Promise<void> {\n if (this.prefetchingAccounts.has(accountId)) return;\n this.prefetchingAccounts.add(accountId);\n try {\n const BATCH_SIZE = 20;\n const THROTTLE_MS = 150;\n const RATE_LIMIT_PAUSE_MS = 30000;\n const ERROR_BUDGET = 10;\n const CONCURRENCY = 2; // S62: 2 in-flight per account\n let totalFetched = 0;\n let errors = 0;\n let announced = false;\n // Per-session blacklist: messages whose fetch errored once.\n // `getMessagesWithoutBody` returns the same set every batch\n // (no per-row failed-marker in DB yet), so without this set\n // a single failing message would burn the entire ERROR_BUDGET\n // by being retried first in every batch. Skipping locally\n // unblocks subsequent messages; next syncAll cycle starts\n // a new prefetch session and the blacklist resets.\n const failedThisSession = new Set<number>();\n // S62: INBOX always first. Within each folder the DB returns rows\n // most-recent-first (PRIMARY KEY order), so newest unfetched INBOX\n // mail wins the queue. A slow label (`[Gmail]/Jerrry`, etc.) can't\n // starve INBOX any more.\n const folderPriority = (folderId: number): number => {\n const f = this.db.getFolders(accountId).find((x: any) => x.id === folderId);\n return f?.specialUse === \"inbox\" ? 0 : 1;\n };\n let rateLimitCooldownUntil = 0;\n\n while (true) {\n const allMissing = this.db.getMessagesWithoutBody(accountId, BATCH_SIZE * 4);\n const missing = allMissing.filter((m: any) => !failedThisSession.has(m.uid));\n if (missing.length === 0) break;\n // Cap to BATCH_SIZE after filtering so a deep blacklist\n // doesn't leave us with a tiny working set per pass.\n if (missing.length > BATCH_SIZE) missing.length = BATCH_SIZE;\n if (!announced) {\n console.log(`[prefetch] ${accountId}: ${missing.length}+ bodies to fetch`);\n vlog(`prefetch ${accountId} start: ${missing.length}+ pending`);\n announced = true;\n }\n // Sort this batch INBOX-first. getMessagesWithoutBody doesn't\n // know the priority, and re-querying per folder would multiply\n // the SELECTs. One in-memory sort is cheap.\n missing.sort((a: any, b: any) => folderPriority(a.folderId) - folderPriority(b.folderId));\n let progressedThisBatch = false;\n let batchAborted = false;\n\n // Bounded-concurrency worker pool. Each worker pulls the next\n // unclaimed item from `missing`. Shared flags (errors,\n // rateLimitCooldownUntil, progressedThisBatch) are updated\n // inside the loop \u2014 sql.js is single-threaded so there's no\n // actual race on reads/writes.\n let cursor = 0;\n const worker = async (): Promise<void> => {\n while (cursor < missing.length) {\n if (batchAborted) return;\n if (errors >= ERROR_BUDGET) return;\n const idx = cursor++;\n const m = missing[idx];\n // Honor rate-limit cooldown across workers.\n const now = Date.now();\n if (rateLimitCooldownUntil > now) {\n await new Promise(r => setTimeout(r, rateLimitCooldownUntil - now));\n }\n if (await this.bodyStore.hasMessage(accountId, m.folderId, m.uid)) {\n this.db.updateBodyPath(accountId, m.uid, `idb:${accountId}/${m.folderId}/${m.uid}`);\n progressedThisBatch = true;\n continue;\n }\n try {\n const result = await this.fetchMessageBody(accountId, m.folderId, m.uid);\n if (result) {\n totalFetched++;\n progressedThisBatch = true;\n emitEvent({ type: \"bodyCached\", accountId, uid: m.uid, folderId: m.folderId });\n } else {\n errors++;\n failedThisSession.add(m.uid);\n }\n } catch (e: any) {\n errors++;\n failedThisSession.add(m.uid);\n const msg = String(e?.message || \"\");\n if (/429|rate|too many/i.test(msg)) {\n console.log(`[prefetch] ${accountId}: rate-limited \u2014 pausing ${RATE_LIMIT_PAUSE_MS / 1000}s`);\n rateLimitCooldownUntil = Date.now() + RATE_LIMIT_PAUSE_MS;\n } else {\n console.error(`[prefetch] ${accountId}/${m.uid}: ${msg}`);\n }\n }\n // Throttle kept per-request to spread load on flaky\n // phone networks; concurrency-2 means effective request\n // rate is ~1 per THROTTLE_MS/2.\n await new Promise(r => setTimeout(r, THROTTLE_MS));\n }\n };\n await Promise.all(Array.from({ length: Math.min(CONCURRENCY, missing.length) }, () => worker()));\n if (errors >= ERROR_BUDGET) {\n console.error(`[prefetch] ${accountId}: stopping after ${errors} errors (${totalFetched} cached)`);\n vlog(`prefetch ${accountId} aborted: ${errors} errors, ${totalFetched} cached`);\n return;\n }\n if (!progressedThisBatch) {\n console.warn(`[prefetch] ${accountId}: batch made no progress, stopping`);\n break;\n }\n }\n if (totalFetched > 0) {\n console.log(`[prefetch] ${accountId}: done \u2014 cached ${totalFetched} bodies`);\n vlog(`prefetch ${accountId} done: ${totalFetched} cached`);\n }\n } finally {\n this.prefetchingAccounts.delete(accountId);\n }\n }\n\n async syncFolders(accountId: string): Promise<Folder[]> {\n const provider = this.getProvider(accountId);\n if (!provider) {\n const existing = this.db.getFolders(accountId);\n vlog(`syncFolders: ${accountId} no provider, returning ${existing.length} cached folders`);\n return existing;\n }\n emitEvent({ type: \"syncProgress\", accountId, phase: \"folders\", progress: 0 });\n console.log(`[sync] ${accountId}: listing folders from provider`);\n let providerFolders: any[] = [];\n try {\n providerFolders = await provider.listFolders();\n } catch (e: any) {\n console.error(`[sync] ${accountId}: listFolders threw: ${e?.message || e}`);\n throw e;\n }\n console.log(`[sync] ${accountId}: provider returned ${providerFolders.length} folders` +\n (providerFolders.length > 0 ? ` (sample: ${providerFolders.slice(0, 3).map((f: any) => f.path || f.name).join(\", \")})` : \"\"));\n for (const folder of providerFolders) {\n const flags = folder.flags || [];\n if (flags.some((f: string) => f.toLowerCase() === \"\\\\noselect\")) continue;\n this.db.upsertFolder(accountId, folder.path, folder.name, folder.specialUse, folder.delimiter);\n }\n emitEvent({ type: \"syncProgress\", accountId, phase: \"folders\", progress: 100 });\n const dbFolders = this.db.getFolders(accountId);\n console.log(`[sync] ${accountId}: ${dbFolders.length} folders in db, inbox=${dbFolders.some((f: any) => f.specialUse === \"inbox\") ? \"yes\" : \"no\"}`);\n emitEvent({ type: \"folderCountsChanged\", accountId, counts: {} });\n return dbFolders;\n }\n\n async syncFolder(accountId: string, folderId: number): Promise<void> {\n const provider = this.getProvider(accountId);\n if (!provider) return;\n const folders = this.db.getFolders(accountId);\n const folder = folders.find(f => f.id === folderId);\n if (!folder) return;\n\n emitEvent({ type: \"syncProgress\", accountId, phase: `sync:${folder.path}`, progress: 0 });\n const highestUid = this.db.getHighestUid(accountId, folderId);\n const startDate = new Date(Date.now() - 30 * 86400000);\n\n let messages: ProviderMessage[];\n if (highestUid > 0) {\n messages = await provider.fetchSince(folder.path, highestUid, { source: false });\n messages = messages.filter(m => m.uid > highestUid);\n } else {\n const tomorrow = new Date(Date.now() + 86400000);\n messages = await provider.fetchByDate(folder.path, startDate, tomorrow, { source: false });\n }\n\n if (messages.length > 0) {\n console.log(`[sync] ${folder.path}: ${messages.length} messages`);\n this.storeProviderMessages(accountId, folderId, messages);\n this.db.recalcFolderCounts(folderId);\n emitEvent({ type: \"folderCountsChanged\", accountId, counts: {} });\n }\n\n // Reconcile deletions \u2014 messages present locally but no longer on the\n // server (moved away, deleted on another client). Without this, the\n // Android client never drops removed rows: e.g., moves to _spam from\n // another client showed up in _spam (next time it synced) but never\n // disappeared from INBOX.\n //\n // Same safety guards as the desktop reconcile path:\n // - Skip if the server list is empty but local has messages (likely\n // a transient API failure that returned []).\n // - Refuse to delete more than 50% of local in one pass \u2014 better to\n // keep phantoms than to wipe a folder on a sync bug. Rebuild local\n // cache fixes a stuck state.\n try {\n const serverUidsArr = await provider.getUids(folder.path);\n const serverUids = new Set(serverUidsArr);\n const localUids = this.db.getUidsForFolder(accountId, folderId);\n if (serverUidsArr.length === 0 && localUids.length > 0) {\n console.log(`[sync] ${folder.path}: reconcile skipped \u2014 server returned empty but local has ${localUids.length}`);\n } else {\n const toDelete = localUids.filter(uid => !serverUids.has(uid));\n const RECONCILE_DELETE_THRESHOLD = 0.5;\n if (localUids.length > 0 && toDelete.length / localUids.length > RECONCILE_DELETE_THRESHOLD) {\n console.log(`[sync] ${folder.path}: reconcile refused \u2014 would delete ${toDelete.length}/${localUids.length} (${Math.round(toDelete.length / localUids.length * 100)}%)`);\n } else {\n for (const uid of toDelete) {\n this.db.deleteMessage(accountId, uid);\n this.bodyStore.deleteMessage(accountId, folderId, uid).catch(() => {});\n }\n if (toDelete.length > 0) {\n console.log(`[sync] ${folder.path}: reconciled ${toDelete.length} deletions`);\n this.db.recalcFolderCounts(folderId);\n emitEvent({ type: \"folderCountsChanged\", accountId, counts: {} });\n }\n }\n }\n } catch (e: any) {\n console.error(`[sync] ${folder.path}: reconcile error: ${e.message}`);\n }\n\n emitEvent({ type: \"folderSynced\", accountId, entries: [{ folderId, syncedAt: Date.now() }] });\n emitEvent({ type: \"syncProgress\", accountId, phase: `sync:${folder.path}`, progress: 100 });\n }\n\n private storeProviderMessages(accountId: string, folderId: number, messages: ProviderMessage[]): void {\n this.db.beginTransaction();\n try {\n for (const msg of messages) {\n const flags: string[] = [];\n if (msg.seen) flags.push(\"\\\\Seen\");\n if (msg.flagged) flags.push(\"\\\\Flagged\");\n if (msg.answered) flags.push(\"\\\\Answered\");\n if (msg.draft) flags.push(\"\\\\Draft\");\n // Store the Gmail providerId in bodyPath as \"gmail:<id>\" so we can\n // fetch the body directly without re-listing 1000 messages from the folder\n const bodyPath = msg.providerId ? `gmail:${msg.providerId}` : \"\";\n this.db.upsertMessage({\n accountId, folderId, uid: msg.uid,\n messageId: msg.messageId || \"\", inReplyTo: \"\", references: [],\n date: msg.date ? msg.date.getTime() : Date.now(),\n subject: msg.subject || \"\",\n from: toEmailAddress(msg.from?.[0]),\n to: msg.to.map(a => toEmailAddress(a)),\n cc: msg.cc.map(a => toEmailAddress(a)),\n flags, size: msg.size || 0, hasAttachments: false, preview: \"\", bodyPath,\n });\n }\n this.db.commitTransaction();\n } catch (e: any) {\n this.db.rollbackTransaction();\n console.error(`[sync] storeMessages error: ${e.message}`);\n }\n }\n\n async fetchMessageBody(accountId: string, folderId: number, uid: number): Promise<Uint8Array | null> {\n const t0 = Date.now();\n if (await this.bodyStore.hasMessage(accountId, folderId, uid)) {\n // Cache hit is the common case on every body open \u2014 not worth a\n // log line each time. Only an actual fetch (below) is logged.\n return await this.bodyStore.getMessage(accountId, folderId, uid);\n }\n const provider = this.getProvider(accountId);\n if (!provider) {\n console.warn(`[fetchBody] No provider for ${accountId}`);\n return null;\n }\n // Look up the Gmail providerId stored in body_path during sync\n const envelope = this.db.getMessageByUid(accountId, uid, folderId);\n const bp = (envelope as any)?.bodyPath || \"\";\n // 60 s wall-clock cap \u2014 infinite hang was the user-reported symptom\n // (\"fetch message body on android is infinite\"). A dead BridgeTransport\n // socket won't recover by waiting. Legit fetches finish in seconds.\n const FETCH_TIMEOUT_MS = 60_000;\n let __folderPath = \"(n/a)\";\n const fetchPromise = (async (): Promise<any> => {\n if (bp.startsWith(\"gmail:\") && (provider as any).fetchById) {\n const providerId = bp.substring(6);\n __folderPath = `gmail:${bp.substring(6)}`;\n return (provider as any).fetchById(providerId, { source: true });\n }\n const folders = this.db.getFolders(accountId);\n const folder = folders.find(f => f.id === folderId);\n if (!folder) { __folderPath = \"(folder row missing)\"; return null; }\n __folderPath = folder.path || \"(empty path)\";\n return provider.fetchOne(folder.path, uid, { source: true });\n })();\n let msg: any = null;\n try {\n msg = await Promise.race([\n fetchPromise,\n new Promise((_, reject) => setTimeout(\n () => reject(new Error(`body-fetch timeout ${FETCH_TIMEOUT_MS / 1000}s (${accountId}/${folderId}/${uid})`)),\n FETCH_TIMEOUT_MS\n )),\n ]);\n } catch (e: any) {\n console.error(`[fetchBody] failed ${accountId}/${folderId}/${uid} after ${Date.now() - t0}ms: ${e?.message || e}`);\n throw e;\n }\n if (!msg?.source) {\n // Detail so the next log pins WHY: folder path used, and whether\n // the provider returned null vs a message with an empty body.\n const why = msg == null ? \"fetchOne returned null\" : \"message had no .source\";\n console.warn(`[fetchBody] No source returned for ${accountId}/${folderId}/${uid} (bp=${bp}, path=${__folderPath}, ${why}, ${Date.now() - t0}ms)`);\n return null;\n }\n // Encode the UTF-8 string back to bytes for storage\n const raw = new TextEncoder().encode(msg.source);\n await this.bodyStore.putMessage(accountId, folderId, uid, raw);\n this.db.updateBodyPath(accountId, uid, `idb:${accountId}/${folderId}/${uid}`);\n console.log(`[fetchBody] fetched + cached ${accountId}/${folderId}/${uid} (${raw.byteLength} bytes, ${Date.now() - t0}ms)`);\n return raw;\n }\n\n async updateFlagsLocal(accountId: string, uid: number, folderId: number, flags: string[]): Promise<void> {\n this.db.updateMessageFlags(accountId, uid, flags);\n this.db.recalcFolderCounts(folderId);\n this.db.queueSyncAction(accountId, \"flags\", uid, folderId, { flags });\n emitEvent({ type: \"folderCountsChanged\", accountId, counts: {} });\n }\n\n async trashMessage(accountId: string, folderId: number, uid: number): Promise<void> {\n this.db.deleteMessage(accountId, uid);\n this.db.queueSyncAction(accountId, \"trash\", uid, folderId);\n emitEvent({ type: \"messageDeleted\", accountId, folderId, uid });\n emitEvent({ type: \"folderCountsChanged\", accountId, counts: {} });\n }\n\n async trashMessages(accountId: string, messages: { uid: number; folderId: number }[]): Promise<void> {\n for (const m of messages) await this.trashMessage(accountId, m.folderId, m.uid);\n }\n\n async moveMessage(accountId: string, uid: number, folderId: number, targetFolderId: number): Promise<void> {\n this.db.queueSyncAction(accountId, \"move\", uid, folderId, { targetFolderId });\n emitEvent({ type: \"messageMoved\", accountId, fromFolderId: folderId, toFolderId: targetFolderId, uid });\n }\n\n async moveMessages(accountId: string, messages: { uid: number; folderId: number }[], targetFolderId: number): Promise<void> {\n for (const m of messages) await this.moveMessage(accountId, m.uid, m.folderId, targetFolderId);\n }\n\n async moveMessageCrossAccount(): Promise<void> {\n throw new Error(\"Cross-account move not supported on mobile\");\n }\n\n async undeleteMessage(accountId: string, uid: number, folderId: number): Promise<void> {\n this.db.queueSyncAction(accountId, \"undelete\", uid, folderId);\n }\n\n /** Q112: drain queued move/flag/trash actions to the provider. Android is\n * standalone \u2014 it pushes state changes directly to Gmail (or other\n * provider) the same way desktop does. Called from the periodic 2-min\n * tick above. `send` actions drain separately via `processSendQueue`. */\n async processSyncActions(accountId: string): Promise<void> {\n const provider: any = this.providers.get(accountId);\n if (!provider) return;\n const pending = this.db.getPendingSyncActions(accountId)\n .filter((a: any) => a.action !== \"send\");\n if (pending.length === 0) return;\n const folders = this.db.getFolders(accountId);\n const folderPath = (id: number): string | null => {\n const f = folders.find((x: any) => x.id === id);\n return f?.path || null;\n };\n for (const p of pending) {\n const path = folderPath(p.folderId);\n if (!path) { this.db.failSyncActionByUid(accountId, p.action, p.uid, `unknown folder ${p.folderId}`); continue; }\n try {\n if (p.action === \"flags\" && typeof provider.setFlags === \"function\") {\n await provider.setFlags(path, p.uid, Array.isArray(p.flags) ? p.flags : (p.flags ? [p.flags] : []));\n } else if (p.action === \"trash\" && typeof provider.trashMessage === \"function\") {\n // Pass the stored Gmail id so the provider trashes by id\n // instead of its capped list-and-hash search \u2014 that search\n // misses messages past the most-recent ~1000 in a large\n // mailbox, fails, and the deletion un-happens.\n await provider.trashMessage(path, p.uid, this.db.getProviderId(accountId, p.uid));\n } else if (p.action === \"move\" && typeof provider.moveMessage === \"function\") {\n const toId = p.targetFolderId as number;\n const toPath = folderPath(toId);\n if (!toPath) { this.db.failSyncActionByUid(accountId, p.action, p.uid, `unknown target folder ${toId}`); continue; }\n await provider.moveMessage(path, p.uid, toPath, this.db.getProviderId(accountId, p.uid));\n } else {\n this.db.failSyncActionByUid(accountId, p.action, p.uid, `provider does not support ${p.action}`);\n continue;\n }\n this.db.completeSyncActionByUid(accountId, p.action, p.uid);\n } catch (e: any) {\n const msg = e?.message || String(e);\n console.error(`[sync-action] ${accountId} ${p.action} uid=${p.uid}: ${msg}`);\n this.db.failSyncActionByUid(accountId, p.action, p.uid, msg);\n }\n }\n }\n\n /** In-flight send tracker keyed by queueUid. Prevents\n * processSendQueue from re-firing the same row when it overlaps\n * with an in-progress attempt (e.g., the periodic tick fires while\n * the original attemptSend's promise is still pending). Without\n * this, a slow Gmail/SMTP send race-conditions into a double-send. */\n private sendInFlight = new Set<number>();\n\n async queueOutgoingLocal(accountId: string, rawMessage: string): Promise<void> {\n // Local-first: PERSIST to sync_actions before attempting the network\n // send, so a crash / offline / process kill between now and SMTP ACK\n // doesn't drop the message. Desktop parity \u2014 PC writes `.ltr` to disk\n // synchronously; Android writes a sync_actions row and now FLUSHES\n // sql.js \u2192 IndexedDB before returning. The previous version relied on\n // the 1-second scheduleSave debounce, so a tab-close inside the debounce\n // window erased the row before it was persisted \u2014 the \"letter just\n // disappeared\" symptom user-reported 2026-04-30.\n //\n // Equivalent of PC's `~/.mailx/outbox/<acct>/*.ltr` durable write.\n const queueUid = -Date.now();\n this.db.queueSyncAction(accountId, \"send\", queueUid, -1, { rawMessage });\n await this.db.flush();\n this.attemptSend(accountId, queueUid, rawMessage);\n }\n\n /** Kick off a send for a message that's already in the queue. Called by\n * queueOutgoingLocal on a fresh submit AND by processSendQueue on\n * startup / periodic tick for anything stranded from a prior run.\n * Guards against double-send via sendInFlight. */\n private attemptSend(accountId: string, queueUid: number, rawMessage: string): void {\n if (this.sendInFlight.has(queueUid)) return;\n this.sendInFlight.add(queueUid);\n // Helper to mark complete + flush + clear in-flight \u2014 used on every\n // success/failure exit. Flush ensures the row deletion or attempt\n // counter actually reaches IndexedDB before the next process-kill,\n // matching the \"persist before network\" rule for the post-network\n // outcome too. Without flushing on completion, a successful send\n // followed by a fast app-close left the row in the queue, which\n // looked like a \"stuck\" message on next launch.\n const finishSend = (success: boolean, error?: string) => {\n if (success) {\n this.db.completeSyncActionByUid(accountId, \"send\", queueUid);\n } else {\n this.db.failSyncActionByUid(accountId, \"send\", queueUid, error || \"send failed\");\n }\n this.db.flush().catch(() => { /* save will retry on next mutation */ });\n this.sendInFlight.delete(queueUid);\n };\n\n const provider = this.getProvider(accountId);\n if (provider && typeof (provider as any).sendRaw === \"function\") {\n (provider as any).sendRaw(rawMessage)\n .then((result: { id: string; threadId: string }) => {\n console.log(`[send] ${accountId}: sent via Gmail API (id=${result.id})`);\n finishSend(true);\n emitEvent({ type: \"sendComplete\", accountId, messageId: result.id });\n })\n .catch((e: any) => {\n console.error(`[send] ${accountId}: Gmail send failed: ${e.message}`);\n finishSend(false, e.message || String(e));\n emitEvent({ type: \"sendError\", accountId, error: e.message });\n });\n return;\n }\n\n // Non-Gmail: use smtp-direct + BridgeTransport. Pull SMTP config from the\n // stored account JSON.\n const accounts = db.getAccountConfigs();\n const row = accounts.find(a => a.id === accountId);\n if (!row) {\n const e = \"Unknown account\";\n console.error(`[send] ${accountId}: ${e}`);\n finishSend(false, e);\n emitEvent({ type: \"sendError\", accountId, error: e });\n return;\n }\n let account: AccountConfig;\n try { account = JSON.parse(row.configJson); }\n catch {\n const e = \"Account config malformed\";\n finishSend(false, e);\n emitEvent({ type: \"sendError\", accountId, error: e });\n return;\n }\n if (!account.smtp) {\n const e = \"No SMTP config for this account\";\n console.error(`[send] ${accountId}: ${e}`);\n finishSend(false, e);\n emitEvent({ type: \"sendError\", accountId, error: e });\n return;\n }\n\n this.sendViaSmtpDirect(accountId, account, rawMessage)\n .then((result) => {\n console.log(`[send] ${accountId}: sent via SMTP (${result.accepted.length} accepted, ${result.rejected.length} rejected)`);\n finishSend(true);\n emitEvent({ type: \"sendComplete\", accountId });\n })\n .catch((e: any) => {\n console.error(`[send] ${accountId}: SMTP send failed: ${e.message}`);\n finishSend(false, e.message || String(e));\n emitEvent({ type: \"sendError\", accountId, error: e.message });\n });\n }\n\n /** Drain any stranded 'send' queue entries \u2014 called at startup and on\n * each periodic sync tick so messages queued while offline or stranded\n * by a crash get a retry. Each row keeps its queueUid as tracking key. */\n async processSendQueue(accountId: string): Promise<void> {\n const pending = this.db.getPendingSyncActions(accountId).filter(a => a.action === \"send\" && a.rawMessage);\n if (pending.length === 0) return;\n console.log(`[send] ${accountId}: draining ${pending.length} queued message(s)`);\n for (const p of pending) {\n this.attemptSend(accountId, p.uid, p.rawMessage);\n }\n }\n\n /** Build SMTP config from account, send via smtp-direct over BridgeTransport. */\n private async sendViaSmtpDirect(\n accountId: string, account: AccountConfig, raw: string,\n ): Promise<{ accepted: string[]; rejected: { address: string; code: number; message: string }[] }> {\n const SMTP_PORT_STARTTLS = 587;\n const SMTP_PORT_IMPLICIT_TLS = 465;\n const smtp = account.smtp!;\n const smtpPort = smtp.port || SMTP_PORT_STARTTLS;\n const smtpHost = smtp.host || account.imap?.host;\n if (!smtpHost) throw new Error(\"No SMTP host\");\n\n // Auth: password \u2192 PLAIN; oauth2 \u2192 XOAUTH2 (token from this account's provider)\n const smtpUser = smtp.user || account.imap?.user || account.email;\n const authType = smtp.auth || (account.imap?.password ? \"password\" : undefined);\n let auth: SmtpAuth | undefined;\n if (authType === \"password\") {\n const pass = smtp.password || account.imap?.password;\n if (!pass) throw new Error(\"SMTP password not configured\");\n auth = { method: \"PLAIN\", user: smtpUser, pass };\n } else if (authType === \"oauth2\") {\n const tp = this.tokenProviders.get(accountId);\n if (!tp) throw new Error(\"OAuth token provider not registered\");\n const token = await tp();\n auth = { method: \"XOAUTH2\", user: smtpUser, token };\n }\n\n // Recipients from headers\n const parseAddrs = (s: string) => s.match(/[\\w.+-]+@[\\w.-]+/g) || [];\n const toMatch = raw.match(/^To:\\s*(.+)$/mi);\n const ccMatch = raw.match(/^Cc:\\s*(.+)$/mi);\n const bccMatch = raw.match(/^Bcc:\\s*(.+)$/mi);\n const fromMatch = raw.match(/^From:\\s*(.+)$/mi);\n const recipients = [\n ...(toMatch ? parseAddrs(toMatch[1]) : []),\n ...(ccMatch ? parseAddrs(ccMatch[1]) : []),\n ...(bccMatch ? parseAddrs(bccMatch[1]) : []),\n ];\n const sender = fromMatch ? (parseAddrs(fromMatch[1])[0] || account.email) : account.email;\n if (recipients.length === 0) throw new Error(\"No recipients\");\n\n const rawToSend = raw.replace(/^Bcc:.*\\r?\\n/mi, \"\");\n\n const client = new SmtpClient({\n host: smtpHost,\n port: smtpPort,\n secure: smtpPort === SMTP_PORT_IMPLICIT_TLS,\n auth,\n localname: \"mailx-android\",\n }, () => new BridgeTcpTransport());\n try {\n await client.connect();\n return await client.sendMail({ from: sender, to: recipients }, rawToSend);\n } finally {\n try { await client.quit(); } catch { /* ignore */ }\n }\n }\n\n async saveDraft(_accountId: string, _raw: string, _prevUid?: number, _draftId?: string): Promise<number | null> {\n return null;\n }\n\n async deleteDraft(_accountId: string, _draftUid: number): Promise<void> { }\n\n async reauthenticate(_accountId: string): Promise<boolean> { return false; }\n\n async searchOnServer(): Promise<number[]> { return []; }\n\n async syncAllContacts(): Promise<void> { }\n}\n\n// \u2500\u2500 OAuth credentials (same \"installed\" client as desktop) \u2500\u2500\n\n// Same credentials as desktop mailx (iflow-credentials.json from @bobfrankston/iflow-direct)\nconst OAUTH_CLIENT = {\n clientId: \"884213380682-hcso64dcqmk4p98vsc7br2e6gvn7iv2u.apps.googleusercontent.com\",\n clientSecret: \"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\",\n authUri: \"https://accounts.google.com/o/oauth2/auth\",\n tokenUri: \"https://oauth2.googleapis.com/token\",\n // Reverse client ID scheme \u2014 auto-allowed for Google \"installed\" apps\n redirectUri: \"com.googleusercontent.apps.884213380682-hcso64dcqmk4p98vsc7br2e6gvn7iv2u:/oauth2callback\",\n};\n\n// Use full drive scope so we can read/write the desktop's accounts.jsonc + clients.jsonc.\n// drive.file is per-consent-grant: files created by desktop's grant aren't visible to Android's grant\n// even with the same client_id. drive (full) lets us see all files the user has access to.\n// `tasks` added 2026-05-05 to match desktop. Without it, the Tasks pane's\n// HTTP calls 403 even though the same OAuth grant works for Calendar.\nconst OAUTH_SCOPES = \"https://mail.google.com/ https://www.googleapis.com/auth/contacts.readonly https://www.googleapis.com/auth/drive https://www.googleapis.com/auth/calendar https://www.googleapis.com/auth/tasks\";\n\n// \u2500\u2500 Token cache (IndexedDB) \u2500\u2500\n\nasync function getCachedToken(email: string): Promise<{ access_token: string; refresh_token?: string; expires_at?: number } | null> {\n const key = `oauth-token-${email.replace(/[@.]/g, \"_\")}`;\n const raw = localStorage.getItem(key);\n if (!raw) {\n console.log(`[oauth] no cached token for ${email} (localStorage key=${key} missing \u2014 fresh consent will follow)`);\n return null;\n }\n try {\n const parsed = JSON.parse(raw);\n const hasRefresh = !!parsed?.refresh_token;\n const expiresAt = parsed?.expires_at || 0;\n const expiresIn = expiresAt ? Math.round((expiresAt - Date.now()) / 1000) : 0;\n console.log(`[oauth] cached token for ${email}: hasRefresh=${hasRefresh}, expiresIn=${expiresIn}s`);\n return parsed;\n } catch { return null; }\n}\n\nasync function setCachedToken(email: string, token: { access_token: string; refresh_token?: string; expires_at?: number }): Promise<void> {\n const key = `oauth-token-${email.replace(/[@.]/g, \"_\")}`;\n localStorage.setItem(key, JSON.stringify(token));\n}\n\nasync function clearCachedToken(email: string): Promise<void> {\n const key = `oauth-token-${email.replace(/[@.]/g, \"_\")}`;\n localStorage.removeItem(key);\n}\n\n// \u2500\u2500 Token exchange \u2500\u2500\n\nasync function exchangeCodeForTokens(code: string): Promise<{ access_token: string; refresh_token?: string; expires_in: number }> {\n const body = new URLSearchParams({\n code,\n client_id: OAUTH_CLIENT.clientId,\n client_secret: OAUTH_CLIENT.clientSecret,\n redirect_uri: OAUTH_CLIENT.redirectUri,\n grant_type: \"authorization_code\",\n });\n const res = await fetch(OAUTH_CLIENT.tokenUri, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/x-www-form-urlencoded\" },\n body: body.toString(),\n });\n if (!res.ok) {\n const text = await res.text();\n throw new Error(`Token exchange failed: ${res.status} ${text}`);\n }\n return res.json();\n}\n\nasync function refreshAccessToken(refreshToken: string): Promise<{ access_token: string; expires_in: number }> {\n const body = new URLSearchParams({\n refresh_token: refreshToken,\n client_id: OAUTH_CLIENT.clientId,\n client_secret: OAUTH_CLIENT.clientSecret,\n grant_type: \"refresh_token\",\n });\n const res = await fetch(OAUTH_CLIENT.tokenUri, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/x-www-form-urlencoded\" },\n body: body.toString(),\n });\n if (!res.ok) {\n const text = await res.text();\n throw new Error(`Token refresh failed: ${res.status} ${text}`);\n }\n return res.json();\n}\n\n// \u2500\u2500 Token provider (browser OAuth, same as desktop) \u2500\u2500\n\nfunction createNativeTokenProvider(email: string): () => Promise<string> {\n return async () => {\n // Check cached token first\n const cached = await getCachedToken(email);\n if (cached?.access_token) {\n const expiresAt = cached.expires_at || 0;\n const bufferMs = 5 * 60 * 1000; // 5 min buffer\n if (Date.now() < expiresAt - bufferMs) {\n return cached.access_token;\n }\n // Try refresh\n if (cached.refresh_token) {\n try {\n console.log(`[oauth] Refreshing token for ${email}`);\n const refreshed = await refreshAccessToken(cached.refresh_token);\n const token = {\n access_token: refreshed.access_token,\n refresh_token: cached.refresh_token,\n expires_at: Date.now() + refreshed.expires_in * 1000,\n };\n await setCachedToken(email, token);\n return token.access_token;\n } catch (e: any) {\n console.warn(`[oauth] Refresh failed: ${e.message}, starting new flow`);\n }\n }\n }\n\n // No valid token \u2014 start browser OAuth flow\n const bridge = (window as any)._nativeBridge;\n if (!bridge?.app?.startOAuth) {\n throw new Error(\"No native OAuth bridge\");\n }\n\n const authUrl = `${OAUTH_CLIENT.authUri}?` + new URLSearchParams({\n client_id: OAUTH_CLIENT.clientId,\n redirect_uri: OAUTH_CLIENT.redirectUri,\n response_type: \"code\",\n scope: OAUTH_SCOPES,\n access_type: \"offline\",\n prompt: \"consent\",\n login_hint: email,\n }).toString();\n\n console.log(`[oauth] Starting browser consent for ${email}`);\n const code = await bridge.app.startOAuth(authUrl);\n const tokens = await exchangeCodeForTokens(code);\n const token = {\n access_token: tokens.access_token,\n refresh_token: tokens.refresh_token,\n expires_at: Date.now() + tokens.expires_in * 1000,\n };\n await setCachedToken(email, token);\n console.log(`[oauth] Token obtained for ${email}`);\n return token.access_token;\n };\n}\n\n// \u2500\u2500 GDrive folder lookup \u2500\u2500\n\nasync function registerDeviceInGDrive(\n tokenProvider: () => Promise<string>,\n folderId: string,\n accountIds: string[]\n): Promise<void> {\n try {\n const token = await tokenProvider();\n // Use persistent Android device ID (survives factory reset & app data clear)\n const bridge = (window as any)._nativeBridge;\n let deviceId = \"android-unknown\";\n if (bridge?.app?.getAndroidId) {\n try {\n const androidId = await bridge.app.getAndroidId();\n deviceId = `android-${androidId.substring(0, 12)}`;\n } catch {\n deviceId = `android-${getDeviceId().substring(0, 8)}`;\n }\n }\n // Read existing clients.jsonc\n const q = encodeURIComponent(`name='clients.jsonc' and '${folderId}' in parents and trashed=false`);\n const listRes = await fetch(\n `https://www.googleapis.com/drive/v3/files?q=${q}&fields=files(id)`,\n { headers: { \"Authorization\": `Bearer ${token}` } }\n );\n if (!listRes.ok) {\n console.warn(`[gdrive] clients.jsonc list failed: ${listRes.status}`);\n return;\n }\n const listData = await listRes.json() as any;\n const fileId = listData.files?.[0]?.id;\n let clients: any = {};\n if (fileId) {\n const readRes = await fetch(\n `https://www.googleapis.com/drive/v3/files/${fileId}?alt=media`,\n { headers: { \"Authorization\": `Bearer ${token}` } }\n );\n if (readRes.ok) {\n try { clients = JSON.parse(await readRes.text()); } catch { /* */ }\n }\n }\n // Remove stale android-* entries (from old random-UUID approach) \u2014 keep only this device\n for (const key of Object.keys(clients)) {\n if (key.startsWith(\"android-\") && key !== deviceId) {\n delete clients[key];\n }\n }\n clients[deviceId] = {\n hostname: deviceId,\n platform: \"android\",\n accounts: accountIds,\n lastSeen: new Date().toISOString(),\n version: (window as any)._nativeBridge?.info?.version || \"?\",\n };\n const content = JSON.stringify(clients, null, 2);\n if (fileId) {\n const upRes = await fetch(\n `https://www.googleapis.com/upload/drive/v3/files/${fileId}?uploadType=media`,\n {\n method: \"PATCH\",\n headers: {\n \"Authorization\": `Bearer ${token}`,\n \"Content-Type\": \"application/json\",\n },\n body: content,\n }\n );\n if (upRes.ok) console.log(`[android] Registered device in clients.jsonc as ${deviceId}`);\n else console.warn(`[gdrive] clients.jsonc update failed: ${upRes.status}`);\n }\n } catch (e: any) {\n console.warn(`[android] Device registration failed: ${e.message}`);\n }\n}\n\n// \u2500\u2500 Google Contacts sync (People API, incremental) \u2500\u2500\n//\n// Mirrors mailx-imap's syncGoogleContactsImpl. Persists nextSyncToken in\n// localStorage per account so subsequent calls only fetch deltas. Web DB\n// has no kv table, so we use localStorage (one row per device \u2014 that's\n// what we want; sync tokens are per-account per-device).\n//\n// In-flight guard prevents the periodic timer from stacking calls when a\n// sync is still running.\n\nconst contactsSyncing = new Map<string, Promise<number>>();\n\nfunction getContactsSyncToken(accountId: string): string {\n try { return localStorage.getItem(`mailx-contacts-synctoken-${accountId}`) || \"\"; }\n catch { return \"\"; }\n}\n\nfunction setContactsSyncToken(accountId: string, token: string | null): void {\n try {\n const key = `mailx-contacts-synctoken-${accountId}`;\n if (token === null) localStorage.removeItem(key);\n else localStorage.setItem(key, token);\n } catch { /* private mode */ }\n}\n\n/** True when the account is Google-backed (Gmail address or Gmail IMAP host).\n * Only Google accounts have a People API + OAuth token; running the contacts\n * sync for a plain IMAP account is meaningless and triggers a bogus OAuth\n * consent prompt for an address Google doesn't own. */\nfunction isGoogleAccount(account: { email?: string; imap?: { host?: string } }): boolean {\n return !!(account.imap?.host?.toLowerCase().includes(\"gmail\")\n || account.email?.toLowerCase().endsWith(\"@gmail.com\"));\n}\n\nasync function syncGoogleContactsForAccount(\n db: WebMailxDB,\n accountId: string,\n tokenProvider: () => Promise<string>,\n): Promise<number> {\n const inFlight = contactsSyncing.get(accountId);\n if (inFlight) return inFlight;\n const promise = (async (): Promise<number> => {\n const token = await tokenProvider();\n if (!token) return 0;\n\n let changed = 0;\n let nextPageToken: string | undefined;\n let syncToken = getContactsSyncToken(accountId);\n\n try {\n do {\n const params = new URLSearchParams({\n personFields: \"names,emailAddresses,organizations,photos\",\n pageSize: \"100\",\n });\n if (nextPageToken) params.set(\"pageToken\", nextPageToken);\n if (syncToken) params.set(\"syncToken\", syncToken);\n else params.set(\"requestSyncToken\", \"true\");\n\n const url = `https://people.googleapis.com/v1/people/me/connections?${params}`;\n const res = await fetch(url, { headers: { Authorization: `Bearer ${token}` } });\n\n if (!res.ok) {\n const err = await res.text().catch(() => \"\");\n // Expired sync token: People API returns HTTP 400\n // FAILED_PRECONDITION / EXPIRED_SYNC_TOKEN (older behavior\n // was 410 \u2014 match both via the body). Drop the token and\n // restart as a full sync.\n if (syncToken && (res.status === 410 || /EXPIRED_SYNC_TOKEN|sync token is expired/i.test(err))) {\n console.log(`[contacts] ${accountId}: sync token expired \u2014 clearing for full resync`);\n setContactsSyncToken(accountId, null);\n syncToken = \"\";\n nextPageToken = undefined;\n changed = 0;\n continue;\n }\n console.error(`[contacts] API error for ${accountId}: ${res.status} ${err}`);\n return changed;\n }\n\n const data = await res.json() as any;\n if (data.connections) {\n for (const person of data.connections) {\n const googleId = person.resourceName || \"\";\n if (person.metadata?.deleted) {\n const removed = db.deleteContactByGoogleId(googleId);\n if (removed > 0) changed += removed;\n continue;\n }\n const name = person.names?.[0]?.displayName || \"\";\n const org = person.organizations?.[0]?.name || \"\";\n for (const e of person.emailAddresses || []) {\n const email = e.value?.toLowerCase();\n if (!email) continue;\n const existing = db.searchContacts(email, 1);\n const wasNew = !(existing.length > 0 && existing[0].email === email);\n db.recordSentAddress(name, email);\n db.setContactGoogleId(email, googleId, org);\n if (wasNew) changed++;\n }\n }\n }\n nextPageToken = data.nextPageToken;\n if (data.nextSyncToken) {\n setContactsSyncToken(accountId, data.nextSyncToken);\n syncToken = data.nextSyncToken;\n }\n } while (nextPageToken);\n\n console.log(`[contacts] ${accountId}: ${changed} change(s) (${syncToken ? \"incremental\" : \"full\"})`);\n } catch (e: any) {\n console.error(`[contacts] Sync error for ${accountId}: ${e.message}`);\n }\n return changed;\n })().finally(() => contactsSyncing.delete(accountId));\n contactsSyncing.set(accountId, promise);\n return promise;\n}\n\nasync function findGDriveMailxFolder(tokenProvider: () => Promise<string>): Promise<{ id: string; name: string; path: string; ownerEmail?: string } | null> {\n const token = await tokenProvider();\n const headers = { \"Authorization\": `Bearer ${token}` };\n // Two-step lookup: My Drive root \u2192 home/ \u2192 .rmfmail\n // Direct My-Drive-root scope finds shared folders too (spouse's .rmfmail\n // appears at root of \"Shared with me\"). Path scope avoids that AND\n // matches the user's actual layout: ~/home/.rmfmail.\n const homeQ = encodeURIComponent(\"name='home' and mimeType='application/vnd.google-apps.folder' and 'root' in parents and trashed=false\");\n const homeRes = await fetch(\n `https://www.googleapis.com/drive/v3/files?q=${homeQ}&fields=files(id,name)&spaces=drive`,\n { headers }\n );\n if (!homeRes.ok) {\n console.warn(`[gdrive] home folder search failed: ${homeRes.status}`);\n return null;\n }\n const homeData = await homeRes.json() as any;\n const home = homeData.files?.[0];\n if (!home?.id) {\n console.warn(\"[gdrive] 'home' folder not found at My Drive root\");\n return null;\n }\n const q = encodeURIComponent(`name='.rmfmail' and mimeType='application/vnd.google-apps.folder' and '${home.id}' in parents and trashed=false`);\n const res = await fetch(\n `https://www.googleapis.com/drive/v3/files?q=${q}&fields=files(id,name,owners(emailAddress))&spaces=drive`,\n { headers }\n );\n if (!res.ok) {\n console.warn(`[gdrive] .rmfmail search failed: ${res.status}`);\n return null;\n }\n const data = await res.json() as any;\n const folder = data.files?.[0];\n if (!folder?.id) return null;\n const homeName = home.name || \"home\";\n const folderName = folder.name || \".rmfmail\";\n return {\n id: folder.id,\n name: folderName,\n path: `My Drive/${homeName}/${folderName}`,\n ownerEmail: folder.owners?.[0]?.emailAddress,\n };\n}\n\n// \u2500\u2500 Initialization \u2500\u2500\n\nasync function waitForNativeBridge(timeoutMs: number = 5000): Promise<void> {\n if ((window as any)._nativeBridge) return;\n return new Promise((resolve) => {\n const start = Date.now();\n const check = () => {\n if ((window as any)._nativeBridge || Date.now() - start > timeoutMs) {\n resolve();\n } else {\n setTimeout(check, 50);\n }\n };\n // Also listen for the event C# dispatches after bridge injection\n window.addEventListener(\"nativebridgeready\", () => resolve(), { once: true });\n check();\n });\n}\n\nexport async function initAndroid(): Promise<void> {\n console.log(\"[android] Initializing mailx (main-thread mode)...\");\n\n // Main-thread path: async I/O (fetch, TCP bridge) doesn't block the UI,\n // and only sql.js is CPU-bound enough to maybe warrant a Worker later.\n // Worker path was reverted 2026-04-14 (stuck at \"Initializing...\" on Android).\n await waitForNativeBridge();\n if ((window as any)._nativeBridge && !(window as any).msgapi) {\n (window as any).msgapi = (window as any)._nativeBridge;\n }\n\n db = new WebMailxDB(\"mailx\");\n await db.waitReady();\n bodyStore = new WebMessageStore();\n syncManager = new AndroidSyncManager(db, bodyStore);\n service = new WebMailxService(db, bodyStore, syncManager);\n\n let accounts = await loadAccounts();\n console.log(`[android] ${accounts.length} account(s) found`);\n\n // Find a Gmail account to use as the GDrive token provider\n let gmailTokenProvider: (() => Promise<string>) | null = null;\n for (const account of accounts) {\n if (!account.enabled) continue;\n const domain = account.email?.split(\"@\")[1]?.toLowerCase() || \"\";\n if (domain === \"gmail.com\" || domain === \"googlemail.com\") {\n const tp = createNativeTokenProvider(account.email);\n syncManager.setTokenProvider(account.id, tp);\n if (!gmailTokenProvider) gmailTokenProvider = tp;\n }\n await syncManager.addAccount(account);\n }\n\n // Install the mailxapi bridge + drain pending queues IMMEDIATELY using\n // the local-cache account list. UI shouldn't wait on GDrive (which can\n // be slow on cold network) before becoming actionable. GDrive\n // reconciliation (below) runs in the background and re-registers fresh\n // accounts when it returns.\n installBridge();\n for (const account of accounts) {\n if (!account.enabled) continue;\n syncManager.processSendQueue(account.id)\n .catch(e => console.error(`[android] processSendQueue ${account.id}: ${e.message}`));\n syncManager.processSyncActions(account.id)\n .catch(e => console.error(`[android] processSyncActions ${account.id}: ${e.message}`));\n }\n // First sync from local accounts on a tiny delay so the UI gets to paint.\n setTimeout(() => {\n syncManager.syncAll().catch(e => console.error(`[android] Sync error: ${e.message}`));\n }, 1000);\n\n // GDrive reconciliation runs in the background \u2014 accounts.jsonc on the\n // shared cloud may have been edited from another device, so we re-pull\n // and re-register if it differs from the cached copy. The user can\n // already see and use mail by the time this resolves.\n if (gmailTokenProvider) {\n const tp = gmailTokenProvider;\n (async () => {\n setGDriveTokenProvider(tp);\n try {\n console.log(\"[android] Looking up GDrive .rmfmail folder\u2026\");\n const folder = await findGDriveMailxFolder(tp);\n if (!folder) {\n emitEvent({\n type: \"fatal\",\n key: \"gdrive-folder-missing\",\n message: \"GDrive folder '.rmfmail' not found \u2014 app cannot start. Create it or sign in with the correct Google account.\",\n });\n } else {\n const folderId = folder.id;\n setGDriveFolderId(folderId, folder.name, folder.ownerEmail, folder.path);\n console.log(`[android] GDrive ${folder.path} folder: ${folderId} (owner=${folder.ownerEmail || \"?\"})`);\n // DEBUG: list all files in the folder\n try {\n const tk = await tp();\n const lr = await fetch(\n `https://www.googleapis.com/drive/v3/files?q='${folderId}'+in+parents+and+trashed%3Dfalse&fields=files(id,name,mimeType,owners(emailAddress))`,\n { headers: { \"Authorization\": `Bearer ${tk}` } }\n );\n if (lr.ok) {\n const ld = await lr.json() as any;\n const names = (ld.files || []).map((f: any) => `${f.name}(${f.owners?.[0]?.emailAddress || \"?\"})`).join(\",\");\n console.log(`[android] Folder contents: ${ld.files?.length || 0} files [${names}]`);\n } else {\n console.warn(`[android] List folder failed: ${lr.status}`);\n }\n } catch (e: any) {\n console.warn(`[android] List debug: ${e.message}`);\n }\n // Read accounts directly from GDrive (bypass IndexedDB cache)\n console.log(\"[android] Reading accounts.jsonc from GDrive...\");\n const gdriveAccounts = await loadAccountsFromCloud();\n console.log(`[android] GDrive returned ${gdriveAccounts.length} accounts: ${gdriveAccounts.map(a => a.id).join(\",\")}`);\n if (gdriveAccounts.length > 0) {\n // Use canonical GDrive accounts (upsert handles overwrites)\n accounts = gdriveAccounts;\n for (const account of accounts) {\n vlog(`init: registering ${account.id} email=${account.email} enabled=${account.enabled} imap=${JSON.stringify(account.imap)}`);\n if (!account.enabled) {\n vlog(`init: ${account.id} disabled, skipping`);\n continue;\n }\n const domain = account.email?.split(\"@\")[1]?.toLowerCase() || \"\";\n if (domain === \"gmail.com\" || domain === \"googlemail.com\") {\n syncManager.setTokenProvider(account.id, createNativeTokenProvider(account.email));\n }\n await syncManager.addAccount(account);\n }\n console.log(`[android] Loaded ${accounts.length} accounts from GDrive`);\n }\n // Register this Android device in clients.jsonc\n await registerDeviceInGDrive(tp, folderId, accounts.map(a => a.id));\n }\n } catch (e: any) {\n emitEvent({\n type: \"fatal\",\n key: \"gdrive-access-failed\",\n message: `GDrive access failed \u2014 app cannot start: ${e.message}`,\n });\n }\n })();\n }\n\n // Startup contacts load. TWO sources, both wanted:\n // 1. The shared GDrive contacts.jsonc \u2014 desktop's full union (everything\n // it discovered from its mailbox + Google contacts + preferred). This\n // is how Android gets contacts it never saw in its own partial corpus.\n // 2. Google People API \u2014 keeps Google-side contacts current. Runs for\n // Google accounts ONLY; an IMAP account has no People API and would\n // pop a bogus OAuth consent.\n service.loadContactsConfig()\n .catch((e: any) => console.error(`[android] startup contacts.jsonc load: ${e?.message || e}`));\n for (const account of db.getAccounts()) {\n if (!account.email || !isGoogleAccount(account)) continue;\n const tp = createNativeTokenProvider(account.email);\n syncGoogleContactsForAccount(db, account.id, tp)\n .catch(e => console.error(`[android] startup contacts sync ${account.id}: ${e.message}`));\n }\n\n // Periodic re-sync every 2 minutes (no IDLE on Android, so poll)\n const SYNC_INTERVAL_MS = 2 * 60 * 1000;\n let contactsSyncTickCounter = 0;\n setInterval(() => {\n console.log(\"[sync] periodic poll\");\n vlog(\"periodic sync poll\");\n // Retry any failed/stranded sends every poll tick\n for (const account of db.getAccounts()) {\n syncManager.processSendQueue(account.id)\n .catch(e => console.error(`[android] retry ${account.id}: ${e.message}`));\n syncManager.processSyncActions(account.id)\n .catch(e => console.error(`[android] processSyncActions ${account.id}: ${e.message}`));\n }\n syncManager.syncAll().catch(e => console.error(`[android] Periodic sync error: ${e.message}`));\n // Contacts: once every 8 ticks (~16 min). Incremental, so cheap \u2014\n // a clean tick is one HTTP round-trip with empty connections list.\n if (++contactsSyncTickCounter % 8 === 0) {\n for (const account of db.getAccounts()) {\n if (!account.email || !isGoogleAccount(account)) continue;\n const tp = createNativeTokenProvider(account.email);\n syncGoogleContactsForAccount(db, account.id, tp)\n .catch(e => console.error(`[android] periodic contacts sync ${account.id}: ${e.message}`));\n }\n }\n }, SYNC_INTERVAL_MS);\n\n // Immediate sync + send-queue drain when app comes back to foreground\n // (e.g. user switches from another app). Without the send-queue drain,\n // a message queued while offline waits up to 2 minutes after resume\n // before retrying \u2014 long enough for the user to think it's stuck.\n document.addEventListener(\"visibilitychange\", () => {\n if (document.visibilityState === \"visible\") {\n console.log(\"[sync] resume poll\");\n for (const account of db.getAccounts()) {\n syncManager.processSendQueue(account.id)\n .catch(e => console.error(`[android] resume send-drain ${account.id}: ${e.message}`));\n }\n syncManager.syncAll().catch(e => console.error(`[android] Resume sync error: ${e.message}`));\n }\n });\n\n console.log(\"[android] Initialization complete\");\n emitEvent({ type: \"connected\" });\n}\n\nexport async function resetStore(): Promise<void> {\n await service.resetStore();\n await clearSettings();\n console.log(\"[android] Store reset\");\n}\n\n// \u2500\u2500 mailxapi Bridge \u2500\u2500\n\nfunction installBridge(): void {\n const api = {\n isApp: true,\n platform: \"android\",\n getAccounts: () => service.getAccounts(),\n getFolders: (accountId: string) => service.getFolders(accountId),\n getMessages: (accountId: string, folderId: number, page: number, pageSize: number) =>\n service.getMessages(accountId, folderId, page, pageSize),\n getUnifiedInbox: (page: number, pageSize: number) => service.getUnifiedInbox(page, pageSize),\n getMessage: (accountId: string, uid: number, allowRemote: boolean, folderId?: number) =>\n service.getMessage(accountId, uid, allowRemote, folderId),\n updateFlags: async (accountId: string, uid: number, flags: string[]) => {\n await service.updateFlags(accountId, uid, flags); return { ok: true };\n },\n deleteMessage: async (accountId: string, uid: number) => {\n await service.deleteMessage(accountId, uid); return { ok: true };\n },\n deleteMessages: async (accountId: string, uids: number[]) => {\n await service.deleteMessages(accountId, uids); return { ok: true, count: uids.length };\n },\n undeleteMessage: async (accountId: string, uid: number, folderId: number) => {\n await service.undeleteMessage(accountId, uid, folderId); return { ok: true };\n },\n moveMessage: async (accountId: string, uid: number, targetFolderId: number, targetAccountId?: string) => {\n await service.moveMessage(accountId, uid, targetFolderId, targetAccountId); return { ok: true };\n },\n moveMessages: async (accountId: string, uids: number[], targetFolderId: number) => {\n await service.moveMessages(accountId, uids, targetFolderId); return { ok: true, count: uids.length };\n },\n sendMessage: async (msg: any) => { await service.send(msg); return { ok: true }; },\n saveDraft: (p: any) => service.saveDraft(p.accountId, p.subject, p.bodyHtml, p.bodyText, p.to, p.cc, p.previousDraftUid, p.draftId),\n deleteDraft: async (accountId: string, draftUid: number) => {\n await service.deleteDraft(accountId, draftUid); return { ok: true };\n },\n searchMessages: (query: string, page: number, pageSize: number) => service.search(query, page, pageSize),\n searchContacts: (query: string) => service.searchContacts(query),\n listContacts: (query: string, page = 1, pageSize = 100) => service.listContacts(query || \"\", page, pageSize),\n upsertContact: (name: string, email: string) => service.upsertContact(name || \"\", email),\n deleteContact: (email: string) => service.deleteContact(email),\n addContact: (name: string, email: string) => service.addContact(name || \"\", email),\n hasCcHistoryTo: (email: string) => ({ hasCc: service.hasCcHistoryTo?.(email) ?? false }),\n syncAll: async () => { await service.syncAll(); return { ok: true }; },\n syncAccount: async (accountId: string) => { await service.syncAccount(accountId); return { ok: true }; },\n getSyncPending: () => service.getSyncPending(),\n getPrimaryAccount: (feature?: string) => {\n // Resolve primary account for a feature (calendar/tasks/contacts):\n // per-feature flag \u2192 catch-all `primary` \u2192 first account.\n const all = db.getAccountConfigs().map(r => {\n try { return { id: r.id, name: r.name, email: r.email, ...JSON.parse(r.configJson) }; }\n catch { return { id: r.id, name: r.name, email: r.email }; }\n });\n if (feature) {\n const key = \"primary\" + feature.charAt(0).toUpperCase() + feature.slice(1);\n const perFeature = all.find((a: any) => a[key]);\n if (perFeature) return perFeature;\n }\n return all.find((a: any) => a.primary) || all[0] || null;\n },\n reauthenticate: async (accountId: string) => ({ ok: await service.reauthenticate(accountId) }),\n markFolderRead: (_accountId: string, folderId: number) => { service.markFolderRead(folderId); return { ok: true }; },\n createFolder: async () => ({ ok: false, error: \"Not supported on mobile\" }),\n renameFolder: async () => ({ ok: false, error: \"Not supported on mobile\" }),\n deleteFolder: async () => ({ ok: false, error: \"Not supported on mobile\" }),\n emptyFolder: async () => ({ ok: false, error: \"Not supported on mobile\" }),\n allowRemoteContent: async (type: string, value: string) => {\n await service.allowRemoteContent(type as any, value); return { ok: true };\n },\n flagSenderOrDomain: async (type: string, value: string) => {\n return await service.flagSenderOrDomain(type as any, value);\n },\n getPriorityLists: () => service.getPriorityLists(),\n setPrioritySender: async (email: string, value: boolean, name?: string) => {\n await service.setPrioritySender(email, !!value, name); return { ok: true };\n },\n setPriorityDomain: async (domain: string, value: boolean) => {\n await service.setPriorityDomain(domain, !!value); return { ok: true };\n },\n getSettings: () => service.getSettings(),\n saveSettingsData: async (data: any) => { await service.saveSettingsData(data); return { ok: true }; },\n getVersion: async () => {\n const settings = await service.getSettings();\n const nativeVersion = (window as any)._nativeBridge?.info?.version || \"?\";\n return { version: nativeVersion, theme: settings.ui?.theme || \"system\", storage: service.getStorageInfo(), platform: \"android\" };\n },\n getAutocompleteSettings: () => service.getAutocompleteSettings(),\n saveAutocompleteSettings: async (settings: any) => { await service.saveAutocompleteSettings(settings); return { ok: true }; },\n getDeviceAccounts: async () => {\n const bridge = (window as any)._nativeBridge;\n if (bridge?.app?.getDeviceAccounts) {\n return bridge.app.getDeviceAccounts();\n }\n return [];\n },\n setupAccount: async (name: string, email: string, _password: string) => {\n try {\n if (!email || !email.includes(\"@\")) {\n return { ok: false, error: \"Email address required\" };\n }\n const domain = email.split(\"@\")[1].toLowerCase();\n const id = domain.split(\".\")[0] || \"account\";\n const account: AccountConfig = {\n id,\n name: name || email.split(\"@\")[0],\n email,\n enabled: true,\n imap: { host: `imap.${domain}`, port: 993, tls: true, auth: \"oauth2\" as const, user: email },\n smtp: { host: `smtp.${domain}`, port: 587, tls: true, auth: \"oauth2\" as const, user: email },\n };\n // Apply known provider defaults\n if (domain === \"gmail.com\" || domain === \"googlemail.com\") {\n account.label = \"Gmail\";\n account.imap = { host: \"imap.gmail.com\", port: 993, tls: true, auth: \"oauth2\", user: email };\n account.smtp = { host: \"smtp.gmail.com\", port: 587, tls: true, auth: \"oauth2\", user: email };\n }\n const existing = await loadAccounts();\n if (existing.some(a => a.email === email)) {\n return { ok: true, message: \"Account already exists\" };\n }\n existing.push(account);\n await saveAccounts(existing);\n // Set up token provider before adding account\n const setupDomain = email.split(\"@\")[1].toLowerCase();\n if (setupDomain === \"gmail.com\" || setupDomain === \"googlemail.com\") {\n syncManager.setTokenProvider(account.id, createNativeTokenProvider(email));\n }\n await syncManager.addAccount(account);\n db.upsertAccount(account.id, account.name, account.email, JSON.stringify(account));\n console.log(`[android] Account added: ${email}`);\n return { ok: true, message: `Added ${email}. Syncing...` };\n } catch (e: any) {\n return { ok: false, error: e.message };\n }\n },\n repairAccounts: async () => ({ ok: false, error: \"Use desktop for repair\" }),\n resetStore: () => resetStore(),\n resetAll: async () => {\n const bridge = (window as any)._nativeBridge;\n if (bridge?.app?.resetAll) {\n await bridge.app.resetAll();\n } else {\n await resetStore();\n location.reload();\n }\n },\n restart: () => { location.reload(); },\n onEvent: (handler: (event: any) => void) => { eventHandlers.push(handler); },\n };\n\n (window as any).mailxapi = api;\n window.dispatchEvent(new CustomEvent(\"mailxapiready\"));\n console.log(\"[android] mailxapi bridge installed\");\n}\n", "/**\n * Gmail API provider \u2014 replaces IMAP for Gmail accounts.\n * Uses REST API for fast, reliable sync without connection limit issues.\n *\n * SOURCE OF TRUTH: this file is the single canonical Gmail provider for\n * mailx. Both desktop (mailx-imap, Node) and Android (mailx-store-web,\n * WebView) re-export from here. Earlier they had parallel copies that\n * silently drifted (the 403-quota retry was added to desktop one day and\n * missed in the web copy until a user reported broken prefetch).\n *\n * Platform requirements: globalThis.fetch (Node 18+ and all browsers/WebViews),\n * atob, Uint8Array, TextDecoder. No Node-specific imports.\n */\n\nimport type { MailProvider, ProviderFolder, ProviderMessage, FetchOptions } from \"./types.js\";\n\nconst API = \"https://gmail.googleapis.com/gmail/v1/users/me\";\n\n/** Convert Gmail hex ID to integer UID (lower 48 bits \u2014 deterministic, stable) */\nfunction idToUid(id: string): number {\n const hex = id.length > 12 ? id.slice(-12) : id;\n return parseInt(hex, 16);\n}\n\n/** Map Gmail label to IMAP-style specialUse */\nfunction labelSpecialUse(label: { id: string; type: string; name: string }): string {\n switch (label.id) {\n case \"INBOX\": return \"inbox\";\n case \"SENT\": return \"sent\";\n case \"DRAFT\": return \"drafts\";\n case \"TRASH\": return \"trash\";\n case \"SPAM\": return \"junk\";\n case \"STARRED\": return \"\";\n case \"IMPORTANT\": return \"\";\n default: return \"\";\n }\n}\n\n/** Parse RFC 2822 headers from Gmail metadata payload */\nfunction getHeader(headers: { name: string; value: string }[], name: string): string {\n return headers.find(h => h.name.toLowerCase() === name.toLowerCase())?.value || \"\";\n}\n\n/** Parse \"Name <addr>\" or \"addr\" into { name, address } */\nfunction parseAddress(raw: string): { name?: string; address?: string } {\n const match = raw.match(/^\"?([^\"<]*?)\"?\\s*<([^>]+)>/);\n if (match) return { name: match[1].trim(), address: match[2].trim() };\n return { address: raw.trim() };\n}\n\nfunction parseAddressList(raw: string): { name?: string; address?: string }[] {\n if (!raw) return [];\n // Split on commas that aren't inside quotes\n return raw.split(/,(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)/).map(s => parseAddress(s.trim())).filter(a => a.address);\n}\n\n/** Rate-limit + cooldown state shared across all GmailApiProvider instances.\n * Gmail enforces rate limits per Google user, not per JS object, so sharing\n * state here prevents new `new GmailApiProvider(...)` from side-stepping the\n * cooldown by creating a fresh instance. Single-account setups won't notice;\n * multi-account setups are slightly over-throttled, which is safer than\n * burning through Google's tolerance. */\nconst rateState = {\n tokens: 0,\n lastRefill: 0,\n cooldownUntil: 0,\n /** Tokens refilled per second (keeps us well under per-user-per-sec caps). */\n rate: 8,\n /** Max burst above steady state. */\n burst: 8,\n};\nrateState.tokens = rateState.burst;\nrateState.lastRefill = Date.now();\n\n/** Extract Google's structured \"reason\" from a JSON error body when possible\n * (e.g. `userRateLimitExceeded`, `rateLimitExceeded`, `quotaExceeded`). */\nfunction parseGoogleReason(body: string): string {\n const m = body.match(/\"reason\"\\s*:\\s*\"([^\"]+)\"/);\n return m ? m[1] : \"\";\n}\n\nexport class GmailApiProvider implements MailProvider {\n constructor(private tokenProvider: () => Promise<string>) {}\n\n /** Block until (a) cooldown has elapsed and (b) a token is available.\n * Token-bucket refill happens lazily on each call. */\n private async acquireToken(): Promise<void> {\n // Respect an active cooldown first \u2014 refuse to even try until it ends.\n const now = Date.now();\n if (rateState.cooldownUntil > now) {\n const waitMs = rateState.cooldownUntil - now;\n console.log(` [gmail] cooldown: waiting ${(waitMs / 1000).toFixed(1)}s before next request`);\n await new Promise(r => setTimeout(r, waitMs));\n }\n // Lazy refill, then spin-wait in chunks until a token is ready.\n while (true) {\n const t = Date.now();\n const elapsedSec = (t - rateState.lastRefill) / 1000;\n rateState.tokens = Math.min(rateState.burst, rateState.tokens + elapsedSec * rateState.rate);\n rateState.lastRefill = t;\n if (rateState.tokens >= 1) {\n rateState.tokens -= 1;\n return;\n }\n const waitMs = Math.max(20, ((1 - rateState.tokens) / rateState.rate) * 1000);\n await new Promise(r => setTimeout(r, waitMs));\n }\n }\n\n private async fetch(path: string, options: RequestInit = {}): Promise<any> {\n const token = await this.tokenProvider();\n const maxAttempts = 6;\n const baseDelayMs = 1000;\n const maxDelayMs = 60_000;\n let lastStatus = 0;\n for (let attempt = 0; attempt < maxAttempts; attempt++) {\n await this.acquireToken();\n const res = await globalThis.fetch(`${API}${path}`, {\n ...options,\n headers: {\n \"Authorization\": `Bearer ${token}`,\n \"Content-Type\": \"application/json\",\n ...options.headers,\n },\n });\n // 403 with \"Quota exceeded\" body is Google's per-minute quota limit.\n // Not 429. Retry like a rate-limit, don't throw as a permanent failure.\n let isQuota403 = false;\n let reason = \"\";\n if (res.status === 403 || res.status === 429) {\n try {\n const cloned = res.clone();\n const body = await cloned.text();\n reason = parseGoogleReason(body);\n if (res.status === 403 && /quota exceeded|rate ?limit|user[-_ ]rate/i.test(body)) isQuota403 = true;\n } catch { /* ignore */ }\n }\n if (res.status === 429 || res.status >= 500 || isQuota403) {\n lastStatus = res.status;\n // Honor Retry-After if present (seconds or HTTP-date)\n const retryAfter = res.headers.get(\"Retry-After\");\n let delay = baseDelayMs * Math.pow(2, attempt);\n if (retryAfter) {\n const asInt = parseInt(retryAfter, 10);\n if (!isNaN(asInt)) delay = asInt * 1000;\n else {\n const when = Date.parse(retryAfter);\n if (!isNaN(when)) delay = Math.max(0, when - Date.now());\n }\n }\n // Per-minute-quota 403 deserves a minimum 60s wait \u2014 the quota\n // resets per minute, so shorter backoff just re-triggers.\n if (isQuota403) delay = Math.max(delay, 60_000);\n // Full jitter to avoid synchronized retries\n delay = Math.min(maxDelayMs, delay);\n delay = Math.floor(delay * (0.5 + Math.random() * 0.5));\n // Install a shared cooldown so *other* in-flight workers wait too,\n // not just this one. Prevents the common failure mode where 5\n // parallel workers each retry independently and keep the\n // per-user QPS pegged above the threshold.\n rateState.cooldownUntil = Math.max(rateState.cooldownUntil, Date.now() + delay);\n const reasonTag = reason ? ` reason=${reason}` : (isQuota403 ? \" (per-minute quota)\" : \"\");\n console.log(` [gmail] ${res.status}${reasonTag} (attempt ${attempt + 1}/${maxAttempts}), waiting ${(delay / 1000).toFixed(1)}s${retryAfter ? ` (Retry-After: ${retryAfter})` : \"\"}...`);\n await new Promise(r => setTimeout(r, delay));\n continue;\n }\n if (!res.ok) {\n const err = await res.text().catch(() => \"\");\n throw new Error(`Gmail API ${res.status}: ${err.substring(0, 200)}`);\n }\n return res.json();\n }\n // Exhausted all retries \u2014 Google is clearly unhappy. Park every\n // subsequent request behind a long cooldown so the next periodic sync\n // (30s) doesn't immediately fire another 6 retries into the same\n // limit. 5 minutes is a floor, not a ceiling \u2014 an incoming Retry-After\n // that's longer will still win via the per-attempt cooldown set above.\n const TERMINAL_COOLDOWN_MS = 5 * 60_000;\n rateState.cooldownUntil = Math.max(rateState.cooldownUntil, Date.now() + TERMINAL_COOLDOWN_MS);\n console.log(` [gmail] exhausted ${maxAttempts} retries \u2014 parking further requests for ${TERMINAL_COOLDOWN_MS / 1000}s`);\n throw new Error(`Gmail API: failed after ${maxAttempts} retries (last status ${lastStatus})`);\n }\n\n async listFolders(): Promise<ProviderFolder[]> {\n const data = await this.fetch(\"/labels\");\n const labels: any[] = data.labels || [];\n const folders: ProviderFolder[] = [];\n\n for (const label of labels) {\n // Skip system labels that aren't useful as folders\n if ([\"UNREAD\", \"STARRED\", \"IMPORTANT\", \"CATEGORY_PERSONAL\",\n \"CATEGORY_SOCIAL\", \"CATEGORY_PROMOTIONS\", \"CATEGORY_UPDATES\",\n \"CATEGORY_FORUMS\", \"CHAT\"].includes(label.id)) continue;\n\n const specialUse = labelSpecialUse(label);\n // Map Gmail path separators (/) to IMAP-style\n const path = label.name || label.id;\n const name = path.includes(\"/\") ? path.split(\"/\").pop()! : path;\n\n folders.push({\n path,\n name,\n delimiter: \"/\",\n specialUse,\n // No \\\\Noselect on Gmail labels: the unwanted system labels\n // (UNREAD/STARRED/IMPORTANT/CATEGORY_*/CHAT) are filtered\n // above, leaving INBOX/SENT/DRAFT/TRASH/SPAM and user labels \u2014\n // ALL of which are selectable. The previous \\\\Noselect tag\n // on system labels caused mailx-imap to skip them entirely,\n // so INBOX never appeared in the folder tree.\n flags: [],\n });\n }\n return folders;\n }\n\n /** List message IDs matching a query, handling pagination.\n * IMPORTANT: on any error we throw \u2014 do NOT return a partial list, because\n * callers use this for sync reconciliation and a short list would delete\n * real messages from the local DB. Returning [] silently caused the\n * \"INBOX empty in mailx\" bug when a rate-limit hit mid-pagination. */\n private async listMessageIds(query: string, maxResults = 500): Promise<string[]> {\n // maxResults === 0 \u2192 unlimited (for date-bounded queries where the\n // query itself caps the result set).\n const unlimited = maxResults === 0;\n const ids: string[] = [];\n let pageToken = \"\";\n let truncated = false;\n while (true) {\n const pageSize = unlimited ? 500 : Math.min(maxResults - ids.length, 500);\n const params = new URLSearchParams({ q: query, maxResults: String(pageSize) });\n if (pageToken) params.set(\"pageToken\", pageToken);\n const data = await this.fetch(`/messages?${params}`);\n for (const msg of data.messages || []) {\n ids.push(msg.id);\n }\n if (!data.nextPageToken) break;\n if (!unlimited && ids.length >= maxResults) {\n // Hit the caller's cap but the server has more. Flag it so\n // reconcile-style callers can refuse to treat this as complete.\n truncated = true;\n break;\n }\n pageToken = data.nextPageToken;\n }\n (ids as any)._truncated = truncated;\n return ids;\n }\n\n /** Batch-fetch message metadata or full content */\n private async batchFetch(ids: string[], options: FetchOptions = {}, onChunk?: (msgs: ProviderMessage[]) => void): Promise<ProviderMessage[]> {\n const all: ProviderMessage[] = [];\n const chunkSize = options.source ? 10 : 50; // Smaller chunks for full bodies\n const format = options.source ? \"raw\" : \"metadata\";\n\n for (let i = 0; i < ids.length; i += chunkSize) {\n const chunk = ids.slice(i, i + chunkSize);\n // Sequential fetches to avoid Gmail 429 rate limits\n const messages: any[] = [];\n for (const id of chunk) {\n const params = new URLSearchParams({ format });\n if (format === \"metadata\") {\n for (const h of [\"From\", \"To\", \"Cc\", \"Subject\", \"Message-ID\", \"Date\", \"In-Reply-To\", \"References\"]) {\n params.append(\"metadataHeaders\", h);\n }\n }\n messages.push(await this.fetch(`/messages/${id}?${params}`));\n }\n\n const parsed: ProviderMessage[] = messages.map(msg => this.parseMessage(msg, options));\n all.push(...parsed);\n if (onChunk) onChunk(parsed);\n }\n return all;\n }\n\n /** Parse a Gmail API message response into ProviderMessage */\n private parseMessage(msg: any, options: FetchOptions = {}): ProviderMessage {\n const labels: string[] = msg.labelIds || [];\n const headers = msg.payload?.headers || [];\n\n let source = \"\";\n if (options.source && msg.raw) {\n // Gmail returns URL-safe base64 \u2014 convert to standard base64 then decode\n const base64 = msg.raw.replace(/-/g, \"+\").replace(/_/g, \"/\");\n source = new TextDecoder().decode(Uint8Array.from(atob(base64), c => c.charCodeAt(0)));\n }\n\n const fromRaw = getHeader(headers, \"From\");\n const toRaw = getHeader(headers, \"To\");\n const ccRaw = getHeader(headers, \"Cc\");\n const dateRaw = getHeader(headers, \"Date\") || \"\";\n const subject = getHeader(headers, \"Subject\") || msg.snippet || \"\";\n const messageId = getHeader(headers, \"Message-ID\") || \"\";\n const inReplyTo = getHeader(headers, \"In-Reply-To\") || \"\";\n const referencesRaw = getHeader(headers, \"References\") || \"\";\n const references = referencesRaw.trim()\n ? referencesRaw.split(/\\s+/).filter(r => r.startsWith(\"<\") && r.endsWith(\">\"))\n : [];\n\n return {\n uid: idToUid(msg.id),\n messageId,\n providerId: msg.id,\n date: dateRaw ? new Date(dateRaw) : (msg.internalDate ? new Date(Number(msg.internalDate)) : null),\n subject,\n from: parseAddressList(fromRaw),\n to: parseAddressList(toRaw),\n cc: parseAddressList(ccRaw),\n inReplyTo,\n references,\n seen: !labels.includes(\"UNREAD\"),\n flagged: labels.includes(\"STARRED\"),\n answered: false, // Gmail API doesn't expose this directly\n draft: labels.includes(\"DRAFT\"),\n size: msg.sizeEstimate || 0,\n source,\n };\n }\n\n async fetchSince(folder: string, sinceUid: number, options: FetchOptions = {}): Promise<ProviderMessage[]> {\n // Gmail message IDs are hash-derived, NOT monotonic \u2014 filtering by\n // `uid > sinceUid` silently drops new messages whose hash happens to\n // fall below the high-water mark. Fetch by date (when caller supplied\n // a `since` window) or fall back to the recent-200 page.\n void sinceUid;\n let query = `in:${this.folderToLabel(folder)}`;\n if (options.since) {\n // after: is inclusive at day granularity; filter precisely on the\n // client side since Gmail's search is whole-day.\n query += ` after:${this.formatDate(options.since)}`;\n }\n // When the caller bounded by date, let pagination run \u2014 the query\n // is self-limiting. Otherwise cap at the recent 200.\n const cap = options.since ? 0 : 200;\n const ids = await this.listMessageIds(query, cap);\n return this.batchFetch(ids, options);\n }\n\n async fetchByDate(folder: string, since: Date, before: Date, options: FetchOptions = {},\n onChunk?: (msgs: ProviderMessage[]) => void): Promise<ProviderMessage[]> {\n const afterDate = this.formatDate(since);\n const beforeDate = this.formatDate(before);\n const query = `in:${this.folderToLabel(folder)} after:${afterDate} before:${beforeDate}`;\n // Date-bounded \u2014 let pagination drain the full range instead of stopping at 500.\n const ids = await this.listMessageIds(query, 0);\n return this.batchFetch(ids, options, onChunk);\n }\n\n async fetchByUids(folder: string, uids: number[], options: FetchOptions = {}): Promise<ProviderMessage[]> {\n // UIDs are derived from Gmail IDs \u2014 we'd need a reverse lookup\n // For now, fetch all messages in folder and filter\n const query = `in:${this.folderToLabel(folder)}`;\n const ids = await this.listMessageIds(query);\n const uidSet = new Set(uids);\n const matchingIds = ids.filter(id => uidSet.has(idToUid(id)));\n return this.batchFetch(matchingIds, options);\n }\n\n /** Bulk-fetch raw bodies for many UIDs in one \"folder\" (Gmail label).\n * Lists the label once, builds UID\u2192ID map, then streams bodies through\n * `onBody`. Uses Gmail's HTTP batch endpoint (up to 100 sub-requests per\n * round-trip) when available, with a single-request fallback so a batch\n * protocol blip doesn't starve prefetch entirely.\n *\n * NOTE: Gmail's model is labels, not folders \u2014 a single message can be in\n * many labels. Treating each label as a folder causes duplicate fetches\n * across labels. Proper fix tracked as separate TODO (\"Gmail label-native\n * model\"). For now we mirror the IMAP folder grouping, accepting duplicate\n * fetches of multi-labeled messages. */\n async fetchBodiesBatch(\n folder: string,\n uids: number[],\n onBody: (uid: number, source: string) => void,\n ): Promise<void> {\n if (uids.length === 0) return;\n const query = `in:${this.folderToLabel(folder)}`;\n const ids = await this.listMessageIds(query, 10000);\n const uidToId = new Map<number, string>();\n for (const id of ids) uidToId.set(idToUid(id), id);\n const wanted: { uid: number; id: string }[] = [];\n for (const uid of uids) {\n const id = uidToId.get(uid);\n if (id) wanted.push({ uid, id });\n }\n if (wanted.length === 0) return;\n\n // Item 16 / C24 Gmail half: HTTP /batch prefetch. One multipart POST\n // with up to 100 sub-requests replaces N round-trips. Typical \u00D710-20\n // speedup on large folders. Each batch still costs the same tokens\n // from the rate bucket as the individual GETs would have (no free\n // ride), but wall-clock latency collapses to roughly one round-trip\n // per 100 messages instead of per message.\n const BATCH_SIZE = 100;\n for (let i = 0; i < wanted.length; i += BATCH_SIZE) {\n const slice = wanted.slice(i, i + BATCH_SIZE);\n try {\n await this.batchFetchBodies(slice, onBody);\n } catch (e: any) {\n // Batch failed (malformed multipart, network reset, auth\n // mid-flight). Fall back to a bounded-concurrency per-message\n // loop for this slice so the user still gets bodies \u2014 we'd\n // rather ship the feature degraded than lose prefetch.\n console.error(` [gmail batch] fell back to per-message: ${e.message}`);\n await this.fetchBodiesIndividually(slice, onBody);\n }\n }\n }\n\n /** POST /batch/gmail/v1 with up to 100 sub-requests. See\n * https://developers.google.com/gmail/api/guides/batch\n * for the multipart/mixed wire format. */\n private async batchFetchBodies(\n items: { uid: number; id: string }[],\n onBody: (uid: number, source: string) => void,\n ): Promise<void> {\n if (items.length === 0) return;\n // One token covers the whole batch endpoint round-trip; Google's\n // per-user quota charges each inner request individually, but the\n // per-second request limit counts the batch as a single request \u2014\n // so rate-bucket budget matches wall-clock cost.\n await this.acquireToken();\n const token = await this.tokenProvider();\n const boundary = `batch_mailx_${Date.now()}_${Math.floor(Math.random() * 1e9)}`;\n const parts: string[] = [];\n for (const { id } of items) {\n parts.push(\n `--${boundary}\\r\\n` +\n `Content-Type: application/http\\r\\n` +\n `Content-ID: <${id}>\\r\\n` +\n `\\r\\n` +\n `GET /gmail/v1/users/me/messages/${id}?format=raw\\r\\n` +\n `Accept: application/json\\r\\n` +\n `\\r\\n`\n );\n }\n parts.push(`--${boundary}--\\r\\n`);\n const body = parts.join(\"\");\n const res = await globalThis.fetch(\"https://gmail.googleapis.com/batch/gmail/v1\", {\n method: \"POST\",\n headers: {\n \"Authorization\": `Bearer ${token}`,\n \"Content-Type\": `multipart/mixed; boundary=${boundary}`,\n },\n body,\n });\n if (!res.ok) {\n const text = await res.text().catch(() => \"\");\n throw new Error(`batch HTTP ${res.status}: ${text.slice(0, 200)}`);\n }\n const respBody = await res.text();\n // Parse multipart \u2014 extract each inner application/http response,\n // match back to the Content-ID to recover the Gmail message id,\n // then decode the raw body JSON field.\n const respCt = res.headers.get(\"content-type\") || \"\";\n const bMatch = respCt.match(/boundary=([^;]+)/i);\n if (!bMatch) throw new Error(\"batch response missing boundary\");\n const respBoundary = bMatch[1].replace(/^\"|\"$/g, \"\");\n // Google sometimes replies with its own \"batch_...\" boundary even if\n // we sent a different one; parsing by the response's boundary is the\n // reliable path. Split on boundary delimiters.\n const chunks = respBody.split(`--${respBoundary}`);\n for (const chunk of chunks) {\n const trimmed = chunk.trim();\n if (!trimmed || trimmed === \"--\") continue;\n // Each chunk is: outer headers, blank line, inner response\n // (HTTP/1.1 status line, headers, blank line, JSON body).\n // Locate the inner JSON body by finding the double blank after\n // the inner headers section.\n const idMatch = chunk.match(/Content-ID:\\s*<?response-<?([^>\\s]+)>?/i);\n const gmailId = idMatch ? idMatch[1].replace(/^<|>$/g, \"\") : \"\";\n // Skip the outer headers: first blank line ends them.\n const firstBlank = chunk.indexOf(\"\\r\\n\\r\\n\");\n if (firstBlank < 0) continue;\n const inner = chunk.slice(firstBlank + 4);\n // Skip the inner HTTP status + headers: second blank line ends them.\n const secondBlank = inner.indexOf(\"\\r\\n\\r\\n\");\n if (secondBlank < 0) continue;\n const jsonBody = inner.slice(secondBlank + 4).trim();\n if (!jsonBody || jsonBody.startsWith(\"--\")) continue;\n try {\n const parsed = JSON.parse(jsonBody);\n if (!parsed?.raw) continue;\n const actualId = parsed.id || gmailId;\n if (!actualId) continue;\n const uid = idToUid(actualId);\n const base64 = parsed.raw.replace(/-/g, \"+\").replace(/_/g, \"/\");\n const source = new TextDecoder().decode(\n Uint8Array.from(atob(base64), c => c.charCodeAt(0)),\n );\n onBody(uid, source);\n } catch { /* malformed sub-response \u2014 skip, don't poison the batch */ }\n }\n }\n\n /** Fallback path when batch fails \u2014 original bounded-concurrency loop.\n * Kept on the degraded path so a single bad batch doesn't halt prefetch. */\n private async fetchBodiesIndividually(\n items: { uid: number; id: string }[],\n onBody: (uid: number, source: string) => void,\n ): Promise<void> {\n const CONCURRENCY = 2;\n let cursor = 0;\n const worker = async (): Promise<void> => {\n while (cursor < items.length) {\n const idx = cursor++;\n const { uid, id } = items[idx];\n try {\n const msg = await this.fetch(`/messages/${id}?format=raw`);\n if (!msg?.raw) continue;\n const base64 = msg.raw.replace(/-/g, \"+\").replace(/_/g, \"/\");\n const source = new TextDecoder().decode(\n Uint8Array.from(atob(base64), c => c.charCodeAt(0)),\n );\n onBody(uid, source);\n } catch (e: any) {\n console.error(` [gmail batch] UID ${uid}: ${e.message}`);\n }\n }\n };\n await Promise.all(Array.from({ length: Math.min(CONCURRENCY, items.length) }, () => worker()));\n }\n\n async fetchOne(folder: string, uid: number, options: FetchOptions = {}): Promise<ProviderMessage | null> {\n // Caller (mailx-imap) passes providerId straight from the DB row when\n // available \u2014 saves the listMessageIds round trip (up to 2 paged calls\n // of 500 IDs each) plus the UID\u2192ID hash search per body fetch. That's\n // the dominant cost for a stuck \"Fetching message body...\" spinner\n // when Gmail rate-limits.\n let id = options.providerId;\n if (!id) {\n const query = `in:${this.folderToLabel(folder)}`;\n const ids = await this.listMessageIds(query, 1000);\n id = ids.find(id => idToUid(id) === uid);\n if (!id) return null;\n }\n const format = options.source ? \"raw\" : \"metadata\";\n const params = new URLSearchParams({ format });\n if (format === \"metadata\") {\n for (const h of [\"From\", \"To\", \"Cc\", \"Subject\", \"Message-ID\", \"Date\", \"In-Reply-To\", \"References\"]) {\n params.append(\"metadataHeaders\", h);\n }\n }\n const msg = await this.fetch(`/messages/${id}?${params}`);\n return this.parseMessage(msg, options);\n }\n\n /** Apply the absolute flag state to a message.\n * Gmail model: flags are labels. `\\Seen` is the *absence* of UNREAD;\n * `\\Flagged` is the presence of STARRED. We always send both add and\n * remove so the end state matches regardless of what was there before,\n * which makes the call idempotent and safe to retry. */\n async setFlags(folder: string, uid: number, flags: string[]): Promise<void> {\n const query = `in:${this.folderToLabel(folder)}`;\n const ids = await this.listMessageIds(query, 1000);\n const id = ids.find(id => idToUid(id) === uid);\n if (!id) throw new Error(`Gmail setFlags: UID ${uid} not found in ${folder}`);\n const flagSet = new Set(flags);\n const addLabelIds: string[] = [];\n const removeLabelIds: string[] = [];\n if (flagSet.has(\"\\\\Flagged\")) addLabelIds.push(\"STARRED\"); else removeLabelIds.push(\"STARRED\");\n if (flagSet.has(\"\\\\Seen\")) removeLabelIds.push(\"UNREAD\"); else addLabelIds.push(\"UNREAD\");\n await this.fetch(`/messages/${id}/modify`, {\n method: \"POST\",\n body: JSON.stringify({ addLabelIds, removeLabelIds }),\n });\n }\n\n /** Move a message to the trash label. Gmail treats trash as a label, not\n * as a destination folder \u2014 `POST /messages/{id}/trash` is the native\n * path (equivalent to setting TRASH and removing INBOX in one op).\n * Used by mailx's delete/trash path. */\n async trashMessage(folder: string, uid: number, gmailId?: string): Promise<void> {\n // Prefer the caller-supplied Gmail message id (mailx stores it as\n // `provider_id`). The fallback \u2014 list the folder and hash-match the\n // uid \u2014 is capped at 1000, so on a large mailbox it CANNOT find a\n // message past the most-recent ~1000: the trash then throws, the\n // sync action fails its retries, and clearTombstoneForUid resurrects\n // the message (\"deletions un-happening\", Bob 2026-05-17). Passing the\n // stored id skips that broken search entirely.\n let id = gmailId;\n if (!id) {\n const ids = await this.listMessageIds(`in:${this.folderToLabel(folder)}`, 1000);\n id = ids.find(x => idToUid(x) === uid);\n }\n if (!id) throw new Error(`Gmail trashMessage: UID ${uid} not found in ${folder}`);\n await this.fetch(`/messages/${id}/trash`, { method: \"POST\" });\n }\n\n /** Move between \"folders\" == swap one label for another via modifyLabels.\n * System labels (INBOX/SENT/TRASH/SPAM) are translated from the folder\n * path; user labels use the folder path verbatim as the label id. */\n async moveMessage(fromFolder: string, uid: number, toFolder: string, gmailId?: string): Promise<void> {\n // See trashMessage \u2014 prefer the caller's stored Gmail id; the\n // list-and-hash fallback is capped at 1000 and breaks on large\n // folders.\n let id = gmailId;\n if (!id) {\n const ids = await this.listMessageIds(`in:${this.folderToLabel(fromFolder)}`, 1000);\n id = ids.find(x => idToUid(x) === uid);\n }\n if (!id) throw new Error(`Gmail moveMessage: UID ${uid} not found in ${fromFolder}`);\n // Map the folder path to the label id. System labels are uppercased\n // aliases; user labels are passed through as-is (Gmail's label ids\n // for user-created labels match the visible label name).\n const toLabel = this.folderPathToLabelId(toFolder);\n const fromLabel = this.folderPathToLabelId(fromFolder);\n const addLabelIds: string[] = [];\n const removeLabelIds: string[] = [];\n if (toLabel) addLabelIds.push(toLabel);\n if (fromLabel && fromLabel !== toLabel) removeLabelIds.push(fromLabel);\n await this.fetch(`/messages/${id}/modify`, {\n method: \"POST\",\n body: JSON.stringify({ addLabelIds, removeLabelIds }),\n });\n }\n\n /** Folder path \u2192 Gmail label id. System folders map to uppercase label\n * constants; anything else is treated as a user label (identical name). */\n private folderPathToLabelId(path: string): string {\n const lower = path.toLowerCase();\n if (lower === \"inbox\") return \"INBOX\";\n if (lower === \"sent\" || lower === \"[gmail]/sent mail\") return \"SENT\";\n if (lower === \"drafts\" || lower === \"[gmail]/drafts\") return \"DRAFT\";\n if (lower === \"trash\" || lower === \"[gmail]/trash\") return \"TRASH\";\n if (lower === \"spam\" || lower === \"junk email\" || lower === \"[gmail]/spam\") return \"SPAM\";\n if (lower === \"archive\" || lower === \"[gmail]/all mail\") return \"\"; // no-op \u2014 archive is absence-of-INBOX\n return path; // user label \u2014 name-as-id\n }\n\n async getUids(folder: string): Promise<number[]> {\n const query = `in:${this.folderToLabel(folder)}`;\n const ids = await this.listMessageIds(query, 10000);\n const result = ids.map(idToUid);\n // Propagate the truncation flag so reconcile can refuse to delete.\n if ((ids as any)._truncated) (result as any)._truncated = true;\n return result;\n }\n\n async close(): Promise<void> {\n // No persistent connection to close\n }\n\n /** Map folder path to Gmail label query term */\n private folderToLabel(path: string): string {\n const lower = path.toLowerCase();\n if (lower === \"inbox\") return \"inbox\";\n if (lower === \"sent\" || lower === \"[gmail]/sent mail\") return \"sent\";\n if (lower === \"drafts\" || lower === \"[gmail]/drafts\") return \"drafts\";\n if (lower === \"trash\" || lower === \"[gmail]/trash\") return \"trash\";\n if (lower === \"spam\" || lower === \"[gmail]/spam\" || lower === \"junk email\") return \"spam\";\n if (lower === \"archive\" || lower === \"[gmail]/all mail\") return \"all\";\n // Custom label \u2014 use exact name\n return `\"${path}\"`;\n }\n\n /** Format date for Gmail query (YYYY/MM/DD) */\n private formatDate(d: Date): string {\n return `${d.getFullYear()}/${String(d.getMonth() + 1).padStart(2, \"0\")}/${String(d.getDate()).padStart(2, \"0\")}`;\n }\n}\n", "/**\n * BridgeTcpTransport \u2014 TcpTransport implementation backed by msgapi.tcp.\n *\n * Works in any msger-family WebView host (msger / msga / msgview / MAUI shell)\n * that exposes msgapi.tcp. TLS handshake happens natively in the host; JS only\n * sees decoded bytes.\n */\n\nimport type { TcpTransport } from \"./transport.js\";\n\ndeclare const msgapi: {\n tcp: {\n connect(host: string, port: number, tls: boolean): Promise<number>;\n write(streamId: number, data: string): Promise<void>;\n onData(streamId: number, callback: (data: string) => void): void;\n onClose(streamId: number, callback: (hadError: boolean) => void): void;\n onError(streamId: number, callback: (message: string) => void): void;\n upgradeTLS(streamId: number, servername: string): Promise<void>;\n close(streamId: number): void;\n };\n};\n\nexport class BridgeTcpTransport implements TcpTransport {\n private streamId: number | null = null;\n private dataHandler: ((data: Uint8Array) => void) | null = null;\n private closeHandler: ((hadError: boolean) => void) | null = null;\n private errorHandler: ((err: Error) => void) | null = null;\n private _connected = false;\n private encoder = new TextEncoder();\n\n get connected(): boolean { return this._connected; }\n\n async connect(host: string, port: number, tls: boolean, _servername?: string): Promise<void> {\n this.streamId = await msgapi.tcp.connect(host, port, tls);\n this._connected = true;\n\n msgapi.tcp.onData(this.streamId, (data: string) => {\n // The msger bridge currently delivers strings (the WebView IPC\n // contract is JSON-text). Encode once per chunk to honor the\n // byte-stream contract upstream consumers expect. Real fix is to\n // change msgapi.tcp.onData to deliver bytes (via base64 or\n // binary-framed IPC) \u2014 that's an msger Rust + JS bridge change,\n // tracked separately. For now the encode is bounded per-chunk,\n // not per-buffer-accumulation, so it doesn't repeat the O(n\u00B2)\n // pathology that was in iflow-direct.\n if (this.dataHandler) this.dataHandler(this.encoder.encode(data));\n });\n msgapi.tcp.onClose(this.streamId, (hadError: boolean) => {\n this._connected = false;\n if (this.closeHandler) this.closeHandler(hadError);\n });\n msgapi.tcp.onError(this.streamId, (message: string) => {\n if (this.errorHandler) this.errorHandler(new Error(message));\n });\n }\n\n async upgradeTLS(servername?: string): Promise<void> {\n if (this.streamId == null) throw new Error(\"Not connected\");\n await msgapi.tcp.upgradeTLS(this.streamId, servername || \"\");\n }\n\n async write(data: string | Uint8Array): Promise<void> {\n if (this.streamId == null) throw new Error(\"Not connected\");\n const s = typeof data === \"string\" ? data : new TextDecoder().decode(data);\n await msgapi.tcp.write(this.streamId, s);\n }\n\n onData(handler: (data: Uint8Array) => void): void { this.dataHandler = handler; }\n onClose(handler: (hadError: boolean) => void): void { this.closeHandler = handler; }\n onError(handler: (err: Error) => void): void { this.errorHandler = handler; }\n\n close(): void {\n if (this.streamId != null) {\n try { msgapi.tcp.close(this.streamId); } catch { /* ignore */ }\n this.streamId = null;\n this._connected = false;\n }\n }\n}\n", "/**\n * IMAP protocol parser and command builder.\n * Pure string logic \u2014 no I/O, no Node.js dependencies.\n * Works in browser, Node.js, or worker thread.\n */\n\n/** Parsed IMAP response line */\nexport interface ImapResponse {\n /** Tag (\"*\" for untagged, \"+\" for continuation, or the command tag) */\n tag: string;\n /** Status (OK, NO, BAD, BYE, PREAUTH) or response type (EXISTS, RECENT, FETCH, etc.) */\n type: string;\n /** The full text after the tag and type */\n text: string;\n /** Raw line */\n raw: string;\n /** Literal data keyed by BODY section name (e.g. \"BODY[]\", \"BODY[HEADER]\") */\n literals?: Map<string, string>;\n}\n\n/** Parsed FETCH response data */\nexport interface FetchData {\n seq: number;\n uid?: number;\n flags?: Set<string>;\n internalDate?: Date;\n size?: number;\n envelope?: EnvelopeData;\n bodyStructure?: any;\n headers?: string;\n source?: string;\n}\n\n/** Parsed ENVELOPE data */\nexport interface EnvelopeData {\n date: Date | null;\n subject: string;\n from: AddressData[];\n sender: AddressData[];\n replyTo: AddressData[];\n to: AddressData[];\n cc: AddressData[];\n bcc: AddressData[];\n inReplyTo: string;\n messageId: string;\n}\n\nexport interface AddressData {\n name: string;\n address: string;\n}\n\n/** Parsed folder LIST data */\nexport interface ListData {\n flags: string[];\n delimiter: string;\n path: string;\n}\n\n/** Parsed STATUS data */\nexport interface StatusData {\n messages?: number;\n recent?: number;\n uidNext?: number;\n uidValidity?: number;\n unseen?: number;\n}\n\n// \u2500\u2500 Command Builder \u2500\u2500\n\nlet tagCounter = 0;\n\n/** Generate a unique command tag */\nexport function nextTag(): string {\n return `A${++tagCounter}`;\n}\n\n/** Reset tag counter (for testing) */\nexport function resetTags(): void {\n tagCounter = 0;\n}\n\n/** Build an IMAP command string (tag + command + CRLF) */\nexport function buildCommand(tag: string, command: string): string {\n return `${tag} ${command}\\r\\n`;\n}\n\n/** Build LOGIN command */\nexport function loginCommand(tag: string, user: string, pass: string): string {\n // Quote user and password to handle special characters\n return buildCommand(tag, `LOGIN ${quoteString(user)} ${quoteString(pass)}`);\n}\n\n/** Build AUTHENTICATE XOAUTH2 command */\nexport function xoauth2Command(tag: string, user: string, token: string): string {\n const authStr = `user=${user}\\x01auth=Bearer ${token}\\x01\\x01`;\n const b64 = btoa(authStr);\n return buildCommand(tag, `AUTHENTICATE XOAUTH2 ${b64}`);\n}\n\n/** Build LIST command */\nexport function listCommand(tag: string, ref = '\"\"', pattern = '\"*\"'): string {\n return buildCommand(tag, `LIST ${ref} ${pattern}`);\n}\n\n/** Build SELECT command. Optional `qresync` triggers RFC 7162 fast resync:\n * the server emits `* VANISHED (EARLIER) <uid-set>` for every UID expunged\n * since `modSeq` and `* FETCH` for every state change since then, in lieu\n * of the caller having to diff UID sets. Capability-gated by caller;\n * requires `ENABLE QRESYNC` already issued on the session. */\nexport function selectCommand(\n tag: string,\n mailbox: string,\n qresync?: { uidValidity: number; modSeq: number; knownUids?: string },\n): string {\n if (!qresync) return buildCommand(tag, `SELECT ${quoteMailbox(mailbox)}`);\n let params = `${qresync.uidValidity} ${qresync.modSeq}`;\n if (qresync.knownUids) params += ` ${qresync.knownUids}`;\n return buildCommand(tag, `SELECT ${quoteMailbox(mailbox)} (QRESYNC (${params}))`);\n}\n\n/** Build ENABLE command per RFC 5161. Common extensions to enable: QRESYNC,\n * CONDSTORE, UTF8=ACCEPT. Must be issued before any SELECT for the\n * extension to take effect on the session. */\nexport function enableCommand(tag: string, extensions: string[]): string {\n return buildCommand(tag, `ENABLE ${extensions.join(\" \")}`);\n}\n\n/** Expand an RFC 3501 UID set (e.g. `\"1:5,8,12,20:*\"`) into a flat number\n * list. Does NOT resolve `*` \u2014 caller passes a known upper bound only\n * when it has one; here `*` is treated as a sentinel and skipped so the\n * call site can decide what to do (typically: ignore \u2014 VANISHED never\n * emits `*` because that would be open-ended). */\nexport function parseUidSet(set: string): number[] {\n const out: number[] = [];\n for (const part of set.split(\",\")) {\n const trimmed = part.trim();\n if (!trimmed) continue;\n const range = trimmed.split(\":\");\n if (range.length === 1) {\n const n = parseInt(range[0], 10);\n if (Number.isFinite(n)) out.push(n);\n } else if (range.length === 2) {\n const lo = parseInt(range[0], 10);\n const hi = range[1] === \"*\" ? lo : parseInt(range[1], 10);\n if (!Number.isFinite(lo) || !Number.isFinite(hi) || hi < lo) continue;\n for (let u = lo; u <= hi; u++) out.push(u);\n }\n }\n return out;\n}\n\n/** Build EXAMINE command (read-only SELECT) */\nexport function examineCommand(tag: string, mailbox: string): string {\n return buildCommand(tag, `EXAMINE ${quoteMailbox(mailbox)}`);\n}\n\n/** Build STATUS command */\nexport function statusCommand(tag: string, mailbox: string, items: string[] = [\"MESSAGES\", \"UIDNEXT\"]): string {\n return buildCommand(tag, `STATUS ${quoteMailbox(mailbox)} (${items.join(\" \")})`);\n}\n\n/** Build UID FETCH command */\nexport function fetchCommand(tag: string, range: string, items: string[]): string {\n return buildCommand(tag, `UID FETCH ${range} (${items.join(\" \")})`);\n}\n\n/** Build sequence-number FETCH command (no UID prefix). Used by fetchLatestN\n * to avoid SEARCH SINCE on a cold mailbox \u2014 sequence ranges are O(1) on the\n * server because they're just message numbers in the current mailbox. */\nexport function seqFetchCommand(tag: string, range: string, items: string[]): string {\n return buildCommand(tag, `FETCH ${range} (${items.join(\" \")})`);\n}\n\n/** Build UID SEARCH command */\nexport function searchCommand(tag: string, criteria: string): string {\n return buildCommand(tag, `UID SEARCH ${criteria}`);\n}\n\n/** Build UID STORE command (set/add/remove flags) */\nexport function storeCommand(tag: string, uid: number, action: string, flags: string[]): string {\n return buildCommand(tag, `UID STORE ${uid} ${action} (${flags.join(\" \")})`);\n}\n\n/** Build UID COPY command */\nexport function copyCommand(tag: string, uid: number, destination: string): string {\n return buildCommand(tag, `UID COPY ${uid} ${quoteMailbox(destination)}`);\n}\n\n/** Build UID MOVE command */\nexport function moveCommand(tag: string, uid: number, destination: string): string {\n return buildCommand(tag, `UID MOVE ${uid} ${quoteMailbox(destination)}`);\n}\n\n/** Build APPEND command header (body follows as literal) */\nexport function appendCommand(tag: string, mailbox: string, flags: string[], size: number): string {\n const flagStr = flags.length > 0 ? ` (${flags.join(\" \")})` : \"\";\n return buildCommand(tag, `APPEND ${quoteMailbox(mailbox)}${flagStr} {${size}}`);\n}\n\n/** Build IDLE command */\nexport function idleCommand(tag: string): string {\n return buildCommand(tag, \"IDLE\");\n}\n\n/** Build NOTIFY SET command (RFC 5465). `spec` is the full event group list,\n * e.g. \"(SELECTED (MessageNew MessageExpunge FlagChange)) (PERSONAL\n * (MessageNew MessageExpunge FlagChange MailboxName))\" \u2014 the server then\n * pushes unsolicited STATUS responses for non-selected mailboxes in the\n * spec while the connection is idle. Capability gated: only issue when\n * CAPABILITY response contains NOTIFY. */\nexport function notifyCommand(tag: string, spec: string): string {\n return buildCommand(tag, `NOTIFY SET ${spec}`);\n}\n\n/** Build DONE command (ends IDLE) */\nexport function doneCommand(): string {\n return \"DONE\\r\\n\";\n}\n\n/** Build STARTTLS command */\nexport function starttlsCommand(tag: string): string {\n return buildCommand(tag, \"STARTTLS\");\n}\n\n/** Build LOGOUT command */\nexport function logoutCommand(tag: string): string {\n return buildCommand(tag, \"LOGOUT\");\n}\n\n/** Build CAPABILITY command */\nexport function capabilityCommand(tag: string): string {\n return buildCommand(tag, \"CAPABILITY\");\n}\n\n/** Build NOOP command */\nexport function noopCommand(tag: string): string {\n return buildCommand(tag, \"NOOP\");\n}\n\n/** Build CREATE command */\nexport function createCommand(tag: string, mailbox: string): string {\n return buildCommand(tag, `CREATE ${quoteMailbox(mailbox)}`);\n}\n\n/** Build DELETE command */\nexport function deleteMailboxCommand(tag: string, mailbox: string): string {\n return buildCommand(tag, `DELETE ${quoteMailbox(mailbox)}`);\n}\n\n/** Build RENAME command */\nexport function renameCommand(tag: string, from: string, to: string): string {\n return buildCommand(tag, `RENAME ${quoteMailbox(from)} ${quoteMailbox(to)}`);\n}\n\n// \u2500\u2500 Response Parser \u2500\u2500\n\n/** Parse a single IMAP response line */\nexport function parseResponseLine(line: string): ImapResponse {\n const trimmed = line.replace(/\\r?\\n$/, \"\");\n\n // Continuation response\n if (trimmed.startsWith(\"+ \") || trimmed === \"+\") {\n return { tag: \"+\", type: \"CONTINUE\", text: trimmed.substring(2), raw: trimmed };\n }\n\n // Untagged response\n if (trimmed.startsWith(\"* \")) {\n const rest = trimmed.substring(2);\n // Check for numeric response (e.g., \"* 5 EXISTS\", \"* 131441 FETCH (...)\")\n const numMatch = rest.match(/^(\\d+)\\s+(\\S+)/);\n if (numMatch) {\n return { tag: \"*\", type: numMatch[2].toUpperCase(), text: rest, raw: trimmed };\n }\n // Status/capability/list response\n const spaceIdx = rest.indexOf(\" \");\n if (spaceIdx > 0) {\n return { tag: \"*\", type: rest.substring(0, spaceIdx).toUpperCase(), text: rest.substring(spaceIdx + 1), raw: trimmed };\n }\n return { tag: \"*\", type: rest.toUpperCase(), text: \"\", raw: trimmed };\n }\n\n // Tagged response (e.g., \"A1 OK Login completed\")\n const spaceIdx = trimmed.indexOf(\" \");\n if (spaceIdx > 0) {\n const tag = trimmed.substring(0, spaceIdx);\n const rest = trimmed.substring(spaceIdx + 1);\n const spaceIdx2 = rest.indexOf(\" \");\n if (spaceIdx2 > 0) {\n return { tag, type: rest.substring(0, spaceIdx2).toUpperCase(), text: rest.substring(spaceIdx2 + 1), raw: trimmed };\n }\n return { tag, type: rest.toUpperCase(), text: \"\", raw: trimmed };\n }\n\n return { tag: \"\", type: \"UNKNOWN\", text: trimmed, raw: trimmed };\n}\n\n/** Parse a LIST response line: * LIST (\\flags) \"delimiter\" \"path\" */\nexport function parseListResponse(text: string): ListData | null {\n // Match: (flags) \"delimiter\" \"path\" or (flags) \"delimiter\" path\n // The \"LIST\" prefix may or may not be present (parseResponseLine may strip it into r.type)\n const match = text.match(/^(?:LIST\\s+)?\\(([^)]*)\\)\\s+\"([^\"]*)\"\\s+(?:\"([^\"]+)\"|(\\S+))/i);\n if (!match) return null;\n const flags = match[1] ? match[1].split(/\\s+/).filter(Boolean) : [];\n const delimiter = match[2] || \".\";\n const path = (match[3] || match[4] || \"\").replace(/\\r?\\n$/, \"\");\n return { flags, delimiter, path };\n}\n\n/** Parse STATUS response: * STATUS \"mailbox\" (MESSAGES n UIDNEXT n ...) */\nexport function parseStatusResponse(text: string): StatusData | null {\n const match = text.match(/\\(([^)]+)\\)/);\n if (!match) return null;\n const pairs = match[1].split(/\\s+/);\n const data: StatusData = {};\n for (let i = 0; i < pairs.length - 1; i += 2) {\n const key = pairs[i].toUpperCase();\n const val = parseInt(pairs[i + 1]);\n if (key === \"MESSAGES\") data.messages = val;\n else if (key === \"RECENT\") data.recent = val;\n else if (key === \"UIDNEXT\") data.uidNext = val;\n else if (key === \"UIDVALIDITY\") data.uidValidity = val;\n else if (key === \"UNSEEN\") data.unseen = val;\n }\n return data;\n}\n\n/** Parse a STATUS response keeping the mailbox name. Used by NOTIFY's\n * unsolicited STATUS pushes where the mailbox identifies which folder\n * changed \u2014 `parseStatusResponse` discards that. Mailbox may be quoted\n * (\"Sent\") or atom-shaped (Sent); the regex handles both. */\nexport function parseStatusResponseFull(text: string): { mailbox: string; data: StatusData } | null {\n // Match: \"quoted name\" (data) OR atomname (data)\n const m = text.match(/^\"((?:[^\"\\\\]|\\\\.)*)\"\\s*\\((.*)\\)\\s*$/) || text.match(/^(\\S+)\\s*\\((.*)\\)\\s*$/);\n if (!m) return null;\n const mailbox = m[1].replace(/\\\\(.)/g, \"$1\");\n const data: StatusData = {};\n const pairs = m[2].split(/\\s+/);\n for (let i = 0; i < pairs.length - 1; i += 2) {\n const key = pairs[i].toUpperCase();\n const val = parseInt(pairs[i + 1]);\n if (key === \"MESSAGES\") data.messages = val;\n else if (key === \"RECENT\") data.recent = val;\n else if (key === \"UIDNEXT\") data.uidNext = val;\n else if (key === \"UIDVALIDITY\") data.uidValidity = val;\n else if (key === \"UNSEEN\") data.unseen = val;\n }\n return { mailbox, data };\n}\n\n/** Parse UID SEARCH response: * SEARCH 1 2 3 4 5 */\nexport function parseSearchResponse(text: string): number[] {\n if (!text.trim()) return [];\n return text.trim().split(/\\s+/).map(Number).filter(n => !isNaN(n));\n}\n\n/** Parse FLAGS from a FETCH or SELECT response */\nexport function parseFlags(flagStr: string): Set<string> {\n const match = flagStr.match(/\\(([^)]*)\\)/);\n if (!match) return new Set();\n return new Set(match[1].split(/\\s+/).filter(Boolean));\n}\n\n/** Parse ENVELOPE from FETCH \u2014 simplified parser for the common fields */\nexport function parseEnvelope(envStr: string): EnvelopeData {\n // ENVELOPE is a parenthesized list \u2014 this is a simplified parser\n // Full RFC 3501 envelope: (date subject from sender reply-to to cc bcc in-reply-to message-id)\n const result: EnvelopeData = {\n date: null, subject: \"\", from: [], sender: [], replyTo: [],\n to: [], cc: [], bcc: [], inReplyTo: \"\", messageId: \"\"\n };\n\n try {\n const tokens = tokenizeParenList(envStr);\n if (tokens.length >= 10) {\n result.date = tokens[0] !== \"NIL\" ? new Date(unquote(tokens[0])) : null;\n result.subject = decodeImapString(unquote(tokens[1]));\n result.from = parseAddressList(tokens[2]);\n result.sender = parseAddressList(tokens[3]);\n result.replyTo = parseAddressList(tokens[4]);\n result.to = parseAddressList(tokens[5]);\n result.cc = parseAddressList(tokens[6]);\n result.bcc = parseAddressList(tokens[7]);\n result.inReplyTo = unquote(tokens[8]);\n result.messageId = unquote(tokens[9]);\n }\n } catch {\n // Parsing envelope is best-effort \u2014 incomplete data is acceptable\n }\n return result;\n}\n\n// \u2500\u2500 IMAP String Utilities \u2500\u2500\n\n/** Quote a string for IMAP (handles special characters) */\nfunction quoteString(s: string): string {\n if (/[\\x00-\\x1f\\x7f\"\\\\]/.test(s)) {\n // Use literal for problematic characters\n return `{${new TextEncoder().encode(s).length}}\\r\\n${s}`;\n }\n return `\"${s}\"`;\n}\n\n/** Quote a mailbox name */\nfunction quoteMailbox(name: string): string {\n if (name === \"INBOX\") return name;\n if (/[\\s\"\\\\*%{]/.test(name)) return `\"${name.replace(/[\"\\\\]/g, \"\\\\$&\")}\"`;\n return name;\n}\n\n/** Remove quotes from an IMAP string */\nfunction unquote(s: string): string {\n if (!s || s === \"NIL\") return \"\";\n if (s.startsWith('\"') && s.endsWith('\"')) return s.slice(1, -1).replace(/\\\\(.)/g, \"$1\");\n return s;\n}\n\n/** Decode IMAP encoded-word (=?charset?encoding?text?=) */\nfunction decodeImapString(s: string): string {\n if (!s) return \"\";\n // RFC 2047 \u00A76.2: whitespace between adjacent encoded-words must be ignored\n const unfolded = s.replace(/\\?=\\s+=\\?/g, \"?==?\");\n return unfolded.replace(/=\\?([^?]+)\\?([BQ])\\?([^?]+)\\?=/gi, (_match, charset, encoding, text) => {\n try {\n const cs = charset.toLowerCase().replace(/^utf8$/, \"utf-8\");\n if (encoding.toUpperCase() === \"B\") {\n const raw = atob(text);\n const bytes = new Uint8Array(raw.length);\n for (let j = 0; j < raw.length; j++) bytes[j] = raw.charCodeAt(j);\n return new TextDecoder(cs).decode(bytes);\n } else {\n // Quoted-printable: collect bytes then decode with charset\n const decoded = text.replace(/_/g, \" \");\n const bytes: number[] = [];\n let i = 0;\n while (i < decoded.length) {\n if (decoded[i] === \"=\" && i + 2 < decoded.length) {\n bytes.push(parseInt(decoded.substring(i + 1, i + 3), 16));\n i += 3;\n } else {\n bytes.push(decoded.charCodeAt(i));\n i++;\n }\n }\n return new TextDecoder(cs).decode(new Uint8Array(bytes));\n }\n } catch {\n return text;\n }\n });\n}\n\n/** Tokenize a parenthesized IMAP list (top-level only) */\nfunction tokenizeParenList(s: string): string[] {\n const tokens: string[] = [];\n let i = 0;\n const str = s.trim();\n // Skip outer parens\n const start = str.startsWith(\"(\") ? 1 : 0;\n const end = str.endsWith(\")\") ? str.length - 1 : str.length;\n\n i = start;\n while (i < end) {\n // Skip whitespace\n while (i < end && str[i] === \" \") i++;\n if (i >= end) break;\n\n if (str[i] === \"(\") {\n // Nested paren group \u2014 find matching close\n let depth = 1;\n let j = i + 1;\n while (j < end && depth > 0) {\n if (str[j] === \"(\") depth++;\n else if (str[j] === \")\") depth--;\n j++;\n }\n tokens.push(str.substring(i, j));\n i = j;\n } else if (str[i] === '\"') {\n // Quoted string\n let j = i + 1;\n while (j < end) {\n if (str[j] === \"\\\\\" && j + 1 < end) { j += 2; continue; }\n if (str[j] === '\"') { j++; break; }\n j++;\n }\n tokens.push(str.substring(i, j));\n i = j;\n } else if (str.substring(i, i + 3).toUpperCase() === \"NIL\") {\n tokens.push(\"NIL\");\n i += 3;\n } else {\n // Atom\n let j = i;\n while (j < end && str[j] !== \" \" && str[j] !== \")\" && str[j] !== \"(\") j++;\n if (j === i) {\n // str[i] is a stray ')' (or '(') that none of the branches\n // above consumed \u2014 an unbalanced/malformed parenthesised\n // list (Dovecot mis-parses some Outlook `From:` headers and\n // emits exactly this). Without advancing, `i` is stuck and\n // the while-loop spins FOREVER, pinning a CPU core and\n // wedging the whole daemon event loop. Skip the stray char.\n i++;\n continue;\n }\n tokens.push(str.substring(i, j));\n i = j;\n }\n }\n return tokens;\n}\n\n/** Parse an IMAP address list: ((name NIL mailbox host) ...) */\nfunction parseAddressList(token: string): AddressData[] {\n if (!token || token === \"NIL\") return [];\n const addrs: AddressData[] = [];\n // Tokenize the outer list to get each address group as a paren-delimited token\n // e.g. ((name NIL mailbox host)(name2 NIL mailbox2 host2)) \u2192 [\"(name NIL mailbox host)\", \"(name2 ...)\"]\n const groups = tokenizeParenList(token);\n for (const group of groups) {\n if (!group.startsWith(\"(\")) continue;\n const parts = tokenizeParenList(group);\n if (parts.length >= 4) {\n const name = decodeImapString(unquote(parts[0]));\n let mailbox = unquote(parts[2]);\n let host = unquote(parts[3]);\n // Dovecot stamps \"MISSING_MAILBOX\" / \"MISSING_DOMAIN\" into the\n // ENVELOPE tuple when the source From: header didn't parse cleanly\n // (RFC 3501 forbids NIL in those slots when any address part is\n // present). Strip the sentinels so we don't render\n // \"user@iecc.com@MISSING_DOMAIN\" \u2014 observed in the wild from\n // Outlook's malformed `From: \"name\" <\"local@domain\">` over-quoting.\n if (host === \"MISSING_DOMAIN\") host = \"\";\n if (mailbox === \"MISSING_MAILBOX\") mailbox = \"\";\n // Recover from Outlook's quoted-string pathology: when the local\n // part itself contains an \"@\" the entire mailbox value is already\n // a full address, so don't append @host again. Same hand applies\n // to any server that mis-parses an over-quoted From header.\n const address = mailbox.includes(\"@\")\n ? mailbox\n : (mailbox && host ? `${mailbox}@${host}` : mailbox || \"\");\n addrs.push({ name, address });\n }\n }\n return addrs;\n}\n\n/** Build SEARCH criteria string from common search parameters */\nexport function buildSearchCriteria(criteria: {\n since?: Date;\n before?: Date;\n from?: string;\n to?: string;\n subject?: string;\n body?: string;\n uid?: string; // UID range like \"100:*\"\n all?: boolean;\n}): string {\n const parts: string[] = [];\n if (criteria.all) parts.push(\"ALL\");\n if (criteria.since) parts.push(`SINCE ${formatImapDate(criteria.since)}`);\n if (criteria.before) parts.push(`BEFORE ${formatImapDate(criteria.before)}`);\n if (criteria.from) parts.push(`FROM \"${criteria.from}\"`);\n if (criteria.to) parts.push(`TO \"${criteria.to}\"`);\n if (criteria.subject) parts.push(`SUBJECT \"${criteria.subject}\"`);\n if (criteria.body) parts.push(`BODY \"${criteria.body}\"`);\n if (criteria.uid) parts.push(`UID ${criteria.uid}`);\n return parts.length > 0 ? parts.join(\" \") : \"ALL\";\n}\n\n/** Format a date for IMAP (DD-Mon-YYYY) */\nfunction formatImapDate(d: Date): string {\n const months = [\"Jan\", \"Feb\", \"Mar\", \"Apr\", \"May\", \"Jun\", \"Jul\", \"Aug\", \"Sep\", \"Oct\", \"Nov\", \"Dec\"];\n return `${d.getDate()}-${months[d.getMonth()]}-${d.getFullYear()}`;\n}\n", "/**\n * Native IMAP client \u2014 transport-agnostic.\n * Uses ImapTransport for I/O, imap-protocol for parsing.\n * Works with NodeTransport (desktop) or BridgeTransport (Android).\n *\n * This is a NEW client alongside the existing ImapClient (which wraps imapflow).\n * Existing callers are not affected.\n */\n\nimport type { ImapTransport, TransportFactory } from \"./transport.js\";\nimport * as proto from \"./imap-protocol.js\";\nimport type { ImapClientConfig, TokenProvider } from \"./types.js\";\n\nexport interface NativeFetchedMessage {\n seq: number;\n uid: number;\n flags: Set<string>;\n date: Date | null;\n subject: string;\n messageId: string;\n from: proto.AddressData[];\n to: proto.AddressData[];\n cc: proto.AddressData[];\n bcc: proto.AddressData[];\n sender: proto.AddressData[];\n replyTo: proto.AddressData[];\n inReplyTo: string;\n size: number;\n source: string;\n headers: string;\n // Convenience flags\n seen: boolean;\n flagged: boolean;\n answered: boolean;\n draft: boolean;\n /** Per-message modification sequence (RFC 7162). Present when the\n * server is CONDSTORE/QRESYNC-capable and the client either has\n * ENABLE QRESYNC active or asked for MODSEQ explicitly. Used by the\n * caller to track its own `last_modseq` watermark per folder. */\n modSeq?: number;\n}\n\nexport interface NativeFolder {\n path: string;\n delimiter: string;\n flags: string[];\n}\n\nexport interface MailboxInfo {\n exists: number;\n recent: number;\n uidNext: number;\n uidValidity: number;\n flags: string[];\n permanentFlags: string[];\n /** Per RFC 7162. Present when the server is CONDSTORE/QRESYNC-capable\n * and includes [HIGHESTMODSEQ N] in the SELECT-OK response (or after\n * ENABLE QRESYNC). Use as the `since-modseq` argument to subsequent\n * resyncs to ask the server \"what changed since this point?\" */\n highestModSeq?: number;\n}\n\n/** Parameters for `SELECT mailbox (QRESYNC (uidvalidity modseq))` per RFC 7162.\n * Caller persists `(uidValidity, modSeq)` per folder; after ENABLE QRESYNC\n * has been issued once on the session, the next SELECT replies with\n * `* VANISHED (EARLIER) <uids>` for every message the server expunged since\n * `modSeq`, plus `* FETCH` for every message whose state changed since then.\n * No client-side UID diffing, no tombstones \u2014 the server tells you the\n * authoritative deletions. */\nexport interface QresyncParams {\n uidValidity: number;\n modSeq: number;\n knownUids?: string; // optional UID range hint, e.g. \"1:100\"\n}\n\n/** Result of a QRESYNC-enabled SELECT. The caller drains `vanishedUids`\n * (delete from local store), processes `changedMessages` (upsert state\n * changes), and saves the new `highestModSeq` for the next resync. */\nexport interface SelectResult extends MailboxInfo {\n vanishedUids: number[];\n /** Untagged `* FETCH` responses the server emitted during the QRESYNC\n * SELECT \u2014 typically flag/MODSEQ changes for messages whose state\n * shifted between the caller's previous modSeq and now. Empty for\n * non-QRESYNC SELECTs. */\n changedMessages: NativeFetchedMessage[];\n /** True if the server's UIDVALIDITY changed since the caller's last\n * visit \u2014 in that case knownUids/modSeq are invalid and the caller\n * must full-resync from scratch. */\n uidValidityChanged: boolean;\n}\n\nexport class NativeImapClient {\n private transport: ImapTransport;\n private transportFactory: TransportFactory;\n private config: ImapClientConfig;\n /** Byte-level receive buffer. IMAP literals (`{N}`) are octets \u2014 message\n * bodies, MIME parts with binary content, non-UTF-8 charsets \u2014 and the\n * parser MUST work in bytes to recover them with byte fidelity and\n * without paying O(n\u00B2) re-encoding cost on every chunk arrival. The\n * prior implementation kept `this.buffer` as a JS string, accumulated\n * UTF-8-decoded text from the transport, then `TextEncoder.encode`'d\n * the whole unread region on every TCP chunk while waiting for a\n * literal \u2014 pegged the event loop on multi-message FETCH responses.\n *\n * Invariants:\n * - `buffer[0 .. bufferLength)` holds valid received bytes\n * - `buffer[bufferOffset .. bufferLength)` is unread\n * - capacity = `buffer.length` \u2265 `bufferLength`; we grow on demand\n * - never substring \u2014 bufferOffset advances past consumed bytes;\n * compactBufferIfNeeded reclaims space when consumed >= half. */\n private buffer: Uint8Array = new Uint8Array(8192);\n private bufferLength = 0;\n private bufferOffset = 0;\n /** Cached decoder so per-line / per-literal decode doesn't re-construct\n * one. `fatal: false` (default) replaces invalid UTF-8 sequences with\n * U+FFFD \u2014 same lenient behavior as JavaScript's implicit string\n * decoding the parser used to rely on. */\n private utf8Decoder = new TextDecoder(\"utf-8\");\n private pendingCommand: {\n tag: string;\n resolve: (responses: proto.ImapResponse[]) => void;\n reject: (err: Error) => void;\n responses: proto.ImapResponse[];\n literalBytes?: number;\n literalBuffer?: string;\n /** Track literal key (e.g. \"BODY[]\") and size for the current literal being read */\n currentLiteralKey?: string;\n currentLiteralSize?: number;\n /** Accumulated literals keyed by section name */\n literals?: Map<string, string>;\n /** Called for each untagged response as it arrives (e.g. per-message FETCH streaming) */\n onUntagged?: (resp: proto.ImapResponse) => void;\n } | null = null;\n private capabilities = new Set<string>();\n private _connected = false;\n private idleTag: string | null = null;\n private idleCallback: ((count: number) => void) | null = null;\n /** Fires when the SELECTED mailbox loses messages while parked in IDLE \u2014\n * an EXISTS decrease, or an unsolicited `* EXPUNGE` / `* VANISHED`\n * (RFC 5465 NOTIFY SELECTED MessageExpunge). Lets the caller reconcile\n * a server-side deletion in real time instead of waiting for the next\n * periodic poll. Distinct from `idleCallback` (new mail only). */\n private idleExpungeCallback: (() => void) | null = null;\n private idleRefreshTimer: ReturnType<typeof setTimeout> | null = null;\n /** RFC 5465 NOTIFY: fires on unsolicited STATUS responses for non-selected\n * mailboxes (the server pushes these when the client has issued NOTIFY\n * SET with a PERSONAL group). Distinct from `idleCallback` which only\n * fires for EXISTS on the currently-selected mailbox. */\n public onMailboxStatus: ((mailbox: string, data: proto.StatusData) => void) | null = null;\n /** Set by startIdle's stop closure so auto-suspend knows not to resume after a command finishes. */\n private idleStopped = true;\n private verbose: boolean;\n private selectedMailbox: string | null = null;\n private mailboxInfo: MailboxInfo = { exists: 0, recent: 0, uidNext: 0, uidValidity: 0, flags: [], permanentFlags: [] };\n private greetingResolve: ((resp: proto.ImapResponse) => void) | null = null;\n /** Callback for waitForContinuation \u2014 set when waiting for \"+\" response */\n private continuationResolve: ((resp: proto.ImapResponse) => void) | null = null;\n /** Per-command heartbeat (30s). Hoisted to instance state so any path\n * that swaps pendingCommand can clear it cleanly \u2014 closure-scoped\n * timers leaked when handleData's inline replacement or IDLE\n * suspend/resume bypassed sendCommandCore's resolve/reject closures. */\n private heartbeatTimer: ReturnType<typeof setInterval> | null = null;\n /** Hard wall-clock cap per command. Same hoist for the same reason. */\n private wallClockTimer: ReturnType<typeof setTimeout> | null = null;\n\n constructor(config: ImapClientConfig, transportFactory: TransportFactory) {\n this.config = config;\n this.transportFactory = transportFactory;\n this.transport = transportFactory();\n this.verbose = config.verbose || false;\n this.inactivityTimeout = config.inactivityTimeout ?? 60000;\n // Hard wall-clock deadline per command. Distinct from inactivityTimeout\n // \u2014 that one resets on each data chunk and can be deferred indefinitely\n // by a slow-trickling server. Default 90s: in production we see\n // connections silently die with sinceLastRead climbing for 50s+ on\n // FETCH; 5 min was leaving them wedged for too long, blocking sync /\n // prefetch / new-mail behind a dead socket. 90s lets a slow but\n // genuine FETCH complete (Sent in isolation: 26ms; even a 50-message\n // FETCH was <1s) while killing dead sockets aggressively. Override\n // via ImapClientConfig.commandWallClockTimeout for known-slow servers.\n this.commandWallClockTimeout = config.commandWallClockTimeout ?? 90_000;\n this.fetchChunkSize = config.fetchChunkSize ?? 25;\n this.fetchChunkSizeMax = config.fetchChunkSizeMax ?? 500;\n this.greetingTimeout = config.greetingTimeout ?? 10000;\n }\n\n get connected(): boolean { return this._connected; }\n\n /** Check the underlying transport's connected state \u2014 catches silently dead sockets. */\n get transportConnected(): boolean { return this.transport?.connected ?? false; }\n\n /** Replace the transport with a fresh one from the factory. Call before reconnect\n * when the old transport is in a bad state (dead socket, stale bridge stream). */\n resetTransport(): void {\n try { this.transport?.close?.(); } catch { /* ignore */ }\n this.transport = this.transportFactory();\n this._connected = false;\n this.bufferLength = 0;\n this.bufferOffset = 0;\n this.pendingCommand = null;\n this.selectedMailbox = null;\n // Old socket is gone \u2014 kill any timers still running for the\n // command that was on it. Without this, a stale heartbeat/wall-clock\n // continues firing into a transport that no longer exists.\n this.clearAllCommandTimers();\n }\n\n // \u2500\u2500 Connection \u2500\u2500\n\n async connect(): Promise<void> {\n const useTls = this.config.port === 993;\n\n this.transport.onData((data) => this.handleData(data));\n this.transport.onClose(() => {\n this._connected = false;\n // Drop stale IDLE state \u2014 the socket is gone.\n this.idleTag = null;\n this.idleCallback = null;\n this.idleStopped = true;\n if (this.idleRefreshTimer) { clearTimeout(this.idleRefreshTimer); this.idleRefreshTimer = null; }\n // Kill any per-command timers \u2014 the connection is gone, no\n // command on it can ever complete. Otherwise heartbeat keeps\n // firing for a connection that no longer exists.\n this.clearAllCommandTimers();\n if (this.pendingCommand) {\n const { reject } = this.pendingCommand;\n this.pendingCommand = null;\n reject(new Error(\"Connection closed\"));\n }\n });\n this.transport.onError((err) => {\n if (this.verbose) console.error(` [imap] Transport error: ${err.message}`);\n // Transport errors (DNS failure, ECONNRESET, TLS failure, etc.) mean\n // the connection is dead \u2014 clear the flag so ensureConnected() will\n // reconnect on the next call, and drop the stale IDLE state so we\n // don't try to DONE a dead socket during auto-suspend.\n this._connected = false;\n this.idleTag = null;\n this.idleCallback = null;\n this.idleStopped = true;\n if (this.idleRefreshTimer) { clearTimeout(this.idleRefreshTimer); this.idleRefreshTimer = null; }\n if (this.pendingCommand) {\n const { reject } = this.pendingCommand;\n this.pendingCommand = null;\n reject(err);\n }\n });\n\n await this.transport.connect(this.config.server, this.config.port, useTls, this.config.server);\n\n // Read server greeting\n const greeting = await this.readGreeting();\n if (this.verbose) console.log(` [imap] Greeting: ${greeting.raw}`);\n\n // Parse capabilities from greeting\n if (greeting.text.includes(\"CAPABILITY\")) {\n this.parseCapabilities(greeting.text);\n } else {\n await this.capability();\n }\n\n // STARTTLS if needed\n if (!useTls && this.capabilities.has(\"STARTTLS\")) {\n await this.starttls();\n }\n\n this._connected = true;\n\n // Authenticate\n await this.authenticate();\n }\n\n private async readGreeting(): Promise<proto.ImapResponse> {\n return new Promise((resolve, reject) => {\n const timeout = setTimeout(() => {\n this.greetingResolve = null;\n reject(new Error(`Greeting timeout (${this.greetingTimeout / 1000}s)`));\n }, this.greetingTimeout);\n this.greetingResolve = (resp) => {\n clearTimeout(timeout);\n resolve(resp);\n };\n });\n }\n\n private async authenticate(): Promise<void> {\n if (this.config.tokenProvider) {\n const token = await this.config.tokenProvider();\n const tag = proto.nextTag();\n const cmd = proto.xoauth2Command(tag, this.config.username, token);\n if (this.verbose) console.log(` [imap] > AUTHENTICATE XOAUTH2 ...`);\n const responses = await this.sendCommand(tag, cmd);\n const tagged = responses.find(r => r.tag === tag);\n if (!tagged || tagged.type !== \"OK\") {\n const errText = tagged?.text || responses.map(r => r.raw).join(\"; \");\n throw new Error(`Authentication failed: ${errText}`);\n }\n } else if (this.config.password) {\n const tag = proto.nextTag();\n const cmd = proto.loginCommand(tag, this.config.username, this.config.password);\n if (this.verbose) console.log(` [imap] > LOGIN ${this.config.username} ***`);\n const responses = await this.sendCommand(tag, cmd);\n const tagged = responses.find(r => r.tag === tag);\n if (!tagged || tagged.type !== \"OK\") {\n const errText = tagged?.text || responses.map(r => r.raw).join(\"; \");\n throw new Error(`Login failed: ${errText}`);\n }\n } else {\n throw new Error(\"No password or token provider configured\");\n }\n\n // Re-read capabilities after auth (they may change)\n await this.capability();\n }\n\n private async starttls(): Promise<void> {\n const tag = proto.nextTag();\n const responses = await this.sendCommand(tag, proto.starttlsCommand(tag));\n const tagged = responses.find(r => r.tag === tag);\n if (!tagged || tagged.type !== \"OK\") throw new Error(\"STARTTLS failed\");\n await this.transport.upgradeTLS(this.config.server);\n await this.capability();\n }\n\n async capability(): Promise<Set<string>> {\n const tag = proto.nextTag();\n const responses = await this.sendCommand(tag, proto.capabilityCommand(tag));\n for (const r of responses) {\n if (r.tag === \"*\" && r.type === \"CAPABILITY\") {\n this.parseCapabilities(r.text);\n }\n }\n return this.capabilities;\n }\n\n /** Return the cached CAPABILITY set parsed at connect/login time. Callers\n * use this to gate optional code paths (NOTIFY, QRESYNC, MOVE, etc.)\n * without re-issuing CAPABILITY. Returns a defensive copy so callers\n * can't mutate internal state. */\n getCapabilities(): Set<string> {\n return new Set(this.capabilities);\n }\n\n /** Snapshot of the currently-SELECTed mailbox's info. Lets the compat\n * client read `highestModSeq` etc. after any select-implying operation\n * (fetchMessagesSinceUid, etc.) without re-issuing SELECT. */\n getMailboxInfo(): { uidValidity: number; uidNext: number; exists: number; highestModSeq?: number } {\n return {\n uidValidity: this.mailboxInfo.uidValidity,\n uidNext: this.mailboxInfo.uidNext,\n exists: this.mailboxInfo.exists,\n highestModSeq: this.mailboxInfo.highestModSeq,\n };\n }\n\n private parseCapabilities(text: string): void {\n const caps = text.replace(/^CAPABILITY\\s*/i, \"\").split(/\\s+/);\n this.capabilities.clear();\n for (const c of caps) this.capabilities.add(c.toUpperCase());\n }\n\n async logout(): Promise<void> {\n // Force-close the transport immediately. The LOGOUT command is a courtesy \u2014\n // the server cleans up the session when the socket closes.\n // Sending LOGOUT and waiting caused hangs and connection leaks.\n this.pendingCommand = null;\n this.transport.close();\n this._connected = false;\n }\n\n // \u2500\u2500 Mailbox Operations \u2500\u2500\n\n /** SELECT a mailbox. Optional QRESYNC params trigger RFC 7162 fast resync \u2014\n * on a re-visit the server replies with `* VANISHED (EARLIER) <uids>` for\n * every UID expunged since the caller's last `modSeq`, plus `* FETCH`\n * for every state change since then. The caller must have called\n * `enable([\"QRESYNC\"])` once on the session for this to take effect.\n * Returns a `SelectResult` rather than a bare `MailboxInfo` so VANISHED\n * is delivered to the caller. The result is upcast-compatible with\n * `MailboxInfo` for code paths that don't care about VANISHED. */\n async select(mailbox: string, qresync?: QresyncParams): Promise<SelectResult> {\n const tag = proto.nextTag();\n const responses = await this.sendCommand(tag, proto.selectCommand(tag, mailbox, qresync));\n const tagged = responses.find(r => r.tag === tag);\n if (!tagged || tagged.type !== \"OK\") {\n throw new Error(`SELECT ${mailbox} failed: ${tagged?.text || \"unknown\"}`);\n }\n\n // Reset transient fields each SELECT so a stale value from a previous\n // mailbox doesn't leak into the new one.\n this.mailboxInfo.highestModSeq = undefined;\n const vanishedUids: number[] = [];\n const priorUidValidity = qresync?.uidValidity;\n // Untagged FETCH responses emitted during a QRESYNC SELECT carry\n // state-change deltas the server is volunteering up-front; parse\n // them through the same path as normal FETCH so the shape matches.\n const fetchResponses = responses.filter(r => r.tag === \"*\" && r.type === \"FETCH\");\n\n for (const r of responses) {\n if (r.tag !== \"*\") continue;\n if (r.type === \"EXISTS\") {\n this.mailboxInfo.exists = parseInt(r.text);\n } else if (r.type === \"RECENT\") {\n this.mailboxInfo.recent = parseInt(r.text);\n } else if (r.type === \"FLAGS\") {\n this.mailboxInfo.flags = [...proto.parseFlags(r.text)];\n } else if (r.type === \"OK\") {\n const uidNextMatch = r.text.match(/UIDNEXT\\s+(\\d+)/i);\n if (uidNextMatch) this.mailboxInfo.uidNext = parseInt(uidNextMatch[1]);\n const uidValMatch = r.text.match(/UIDVALIDITY\\s+(\\d+)/i);\n if (uidValMatch) this.mailboxInfo.uidValidity = parseInt(uidValMatch[1]);\n const permMatch = r.text.match(/PERMANENTFLAGS\\s+\\(([^)]*)\\)/i);\n if (permMatch) this.mailboxInfo.permanentFlags = permMatch[1].split(/\\s+/).filter(Boolean);\n const modSeqMatch = r.text.match(/HIGHESTMODSEQ\\s+(\\d+)/i);\n if (modSeqMatch) this.mailboxInfo.highestModSeq = parseInt(modSeqMatch[1]);\n } else if (r.type === \"VANISHED\") {\n // `* VANISHED (EARLIER) 1:5,8,12` or `* VANISHED 1:5,8,12` \u2014\n // strip the optional `(EARLIER)` modifier and expand the UID\n // set. EARLIER means \"deleted before your last sync\", which\n // is the QRESYNC case; without it, the message just vanished\n // mid-session (post-EXPUNGE on another client).\n const text = r.text.replace(/^\\(EARLIER\\)\\s*/i, \"\").trim();\n for (const uid of proto.parseUidSet(text)) vanishedUids.push(uid);\n }\n }\n this.selectedMailbox = mailbox;\n const uidValidityChanged = priorUidValidity !== undefined\n && this.mailboxInfo.uidValidity !== priorUidValidity;\n const changedMessages = fetchResponses.length > 0\n ? this.parseFetchResponses(fetchResponses)\n : [];\n return {\n ...this.mailboxInfo,\n vanishedUids,\n changedMessages,\n uidValidityChanged,\n };\n }\n\n /** RFC 5161 ENABLE. Activates an extension for the rest of the session.\n * QRESYNC requires this once before any SELECT for VANISHED responses\n * to be emitted. Capability-gate at the caller \u2014 emitting ENABLE for\n * an unadvertised extension is a no-op on compliant servers but spams\n * the response stream. */\n async enable(extensions: string[]): Promise<Set<string>> {\n const tag = proto.nextTag();\n const responses = await this.sendCommand(tag, proto.enableCommand(tag, extensions));\n const tagged = responses.find(r => r.tag === tag);\n if (!tagged || tagged.type !== \"OK\") {\n throw new Error(`ENABLE ${extensions.join(\" \")} failed: ${tagged?.text || \"unknown\"}`);\n }\n const enabled = new Set<string>();\n for (const r of responses) {\n if (r.tag === \"*\" && r.type === \"ENABLED\") {\n for (const ext of r.text.split(/\\s+/).filter(Boolean)) enabled.add(ext.toUpperCase());\n }\n }\n return enabled;\n }\n\n async examine(mailbox: string): Promise<MailboxInfo> {\n const tag = proto.nextTag();\n const responses = await this.sendCommand(tag, proto.examineCommand(tag, mailbox));\n const tagged = responses.find(r => r.tag === tag);\n if (!tagged || tagged.type !== \"OK\") {\n throw new Error(`EXAMINE ${mailbox} failed: ${tagged?.text || \"unknown\"}`);\n }\n for (const r of responses) {\n if (r.tag !== \"*\") continue;\n if (r.type === \"EXISTS\") this.mailboxInfo.exists = parseInt(r.text);\n else if (r.type === \"RECENT\") this.mailboxInfo.recent = parseInt(r.text);\n }\n this.selectedMailbox = mailbox;\n return { ...this.mailboxInfo };\n }\n\n /** Close the currently selected mailbox */\n async closeMailbox(): Promise<void> {\n if (!this.selectedMailbox) return;\n const tag = proto.nextTag();\n await this.sendCommand(tag, proto.buildCommand(tag, \"CLOSE\"));\n this.selectedMailbox = null;\n }\n\n // \u2500\u2500 Folder Operations \u2500\u2500\n\n async listFolders(): Promise<NativeFolder[]> {\n const tag = proto.nextTag();\n const responses = await this.sendCommand(tag, proto.listCommand(tag));\n const folders: NativeFolder[] = [];\n let unparsed = 0;\n const listResponses = responses.filter(r => r.tag === \"*\" && r.type === \"LIST\");\n if (listResponses.length === 0 && responses.length > 0) {\n console.error(` [imap] LIST returned ${responses.length} responses but none were LIST type. Types: ${responses.map(r => `${r.tag}:${r.type}`).join(\", \")}`);\n if (responses.length <= 5) {\n for (const r of responses) console.error(` [imap] raw: ${JSON.stringify(r.text.substring(0, 200))}`);\n }\n }\n for (const r of responses) {\n if (r.tag === \"*\" && r.type === \"LIST\") {\n const parsed = proto.parseListResponse(r.text);\n if (parsed) {\n folders.push(parsed);\n } else {\n unparsed++;\n if (unparsed <= 3) console.error(` [imap] Unparsed LIST response: ${JSON.stringify(r.text.substring(0, 200))}`);\n }\n }\n }\n if (unparsed > 0) console.error(` [imap] ${unparsed} LIST responses could not be parsed (${responses.length} total responses)`);\n return folders;\n }\n\n async getStatus(mailbox: string): Promise<proto.StatusData> {\n const tag = proto.nextTag();\n const responses = await this.sendCommand(tag, proto.statusCommand(tag, mailbox, [\"MESSAGES\", \"UIDNEXT\", \"UNSEEN\"]));\n for (const r of responses) {\n if (r.tag === \"*\" && r.type === \"STATUS\") {\n const data = proto.parseStatusResponse(r.text);\n if (data) return data;\n }\n }\n return {};\n }\n\n async createMailbox(mailbox: string): Promise<void> {\n const tag = proto.nextTag();\n const responses = await this.sendCommand(tag, proto.createCommand(tag, mailbox));\n const tagged = responses.find(r => r.tag === tag);\n if (!tagged || tagged.type !== \"OK\") throw new Error(`CREATE failed: ${tagged?.text || \"unknown\"}`);\n }\n\n async deleteMailbox(mailbox: string): Promise<void> {\n const tag = proto.nextTag();\n const responses = await this.sendCommand(tag, proto.deleteMailboxCommand(tag, mailbox));\n const tagged = responses.find(r => r.tag === tag);\n if (!tagged || tagged.type !== \"OK\") throw new Error(`DELETE failed: ${tagged?.text || \"unknown\"}`);\n }\n\n async renameMailbox(from: string, to: string): Promise<void> {\n const tag = proto.nextTag();\n const responses = await this.sendCommand(tag, proto.renameCommand(tag, from, to));\n const tagged = responses.find(r => r.tag === tag);\n if (!tagged || tagged.type !== \"OK\") throw new Error(`RENAME failed: ${tagged?.text || \"unknown\"}`);\n }\n\n // \u2500\u2500 Message Operations \u2500\u2500\n\n /** Fetch messages by UID range. Range may be sequence set (e.g. \"1:100\"), comma list (\"1,5,10\"), or mix (\"1:10,42,50:55\"). */\n async fetchMessages(range: string, options: { source?: boolean; headers?: boolean } = {}): Promise<NativeFetchedMessage[]> {\n return this.fetchMessagesStream(range, options);\n }\n\n /**\n * Fetch messages by UID range/list, streaming each parsed message through `onMessage`\n * as soon as its server response (including any literal bodies) is received, instead\n * of buffering the entire batch until the tagged OK. Returns all parsed messages at end.\n *\n * Pass a comma list (`\"1,5,10,42\"`) or sequence set (`\"100:200\"`) \u2014 the server handles either.\n */\n async fetchMessagesStream(\n range: string,\n options: { source?: boolean; headers?: boolean } = {},\n onMessage?: (msg: NativeFetchedMessage) => void,\n ): Promise<NativeFetchedMessage[]> {\n const items = [\"UID\", \"FLAGS\", \"ENVELOPE\", \"RFC822.SIZE\", \"INTERNALDATE\"];\n if (options.headers !== false) items.push(\"BODY.PEEK[HEADER]\");\n if (options.source) items.push(\"BODY.PEEK[]\");\n\n const tag = proto.nextTag();\n const streamed: NativeFetchedMessage[] = [];\n // ALWAYS parse incrementally in the per-response callback \u2014 even\n // when the caller passed no `onMessage`. The callback runs from\n // processBuffer's 10 ms time-budgeted loop, so envelope parsing of a\n // large FETCH (a sync-backfill chunk of 100+ messages) is sliced\n // across event-loop turns. The old `onMessage ? stream : batch`\n // path parsed every envelope in ONE synchronous block after the\n // tagged OK \u2014 profiled 2026-05-15 as a ~30 s daemon wedge\n // (tokenizeParenList ~40 % of CPU), starving every getMessage /\n // move / delete IPC for the duration.\n const cb = (resp: proto.ImapResponse): void => {\n if (resp.tag !== \"*\" || resp.type !== \"FETCH\") return;\n const parsed = this.parseFetchResponses([resp]);\n for (const msg of parsed) {\n streamed.push(msg);\n if (onMessage) onMessage(msg);\n }\n };\n\n await this.sendCommand(tag, proto.fetchCommand(tag, range, items), cb);\n return streamed;\n }\n\n /**\n * Folder-scoped batch body fetch. Selects `folderPath`, issues a single\n * `UID FETCH <uids> (BODY.PEEK[] ...)`, streams each body through `onBody`\n * as it arrives, and returns when the tagged OK is received.\n *\n * Eliminates per-message SELECT+FETCH round trips for callers like mailx-imap's\n * prefetch path.\n */\n async fetchBodiesBatch(\n folderPath: string,\n uids: number[],\n onBody: (uid: number, source: string) => void,\n ): Promise<void> {\n if (uids.length === 0) return;\n if (this.selectedMailbox !== folderPath) await this.select(folderPath);\n await this.fetchMessagesStream(uids.join(\",\"), { source: true, headers: false }, (msg) => {\n if (msg.uid && msg.source) onBody(msg.uid, msg.source);\n });\n }\n\n /** Fetch messages since a UID */\n async fetchSinceUid(sinceUid: number, options: { source?: boolean } = {}, onChunk?: (msgs: NativeFetchedMessage[]) => void): Promise<NativeFetchedMessage[]> {\n const uids = await this.search(`UID ${sinceUid + 1}:*`);\n if (uids.length === 0) return [];\n uids.reverse(); // Newest first\n console.log(` [fetch] ${uids.length} UIDs since ${sinceUid} (newest first)`);\n if (uids.length <= this.fetchChunkSize) {\n const msgs = await this.fetchMessages(uids.join(\",\"), options);\n if (onChunk) onChunk(msgs);\n return msgs;\n }\n const allMessages: NativeFetchedMessage[] = [];\n let chunkSize = this.fetchChunkSize;\n for (let i = 0; i < uids.length; i += chunkSize) {\n const chunk = uids.slice(i, i + chunkSize);\n const msgs = await this.fetchMessages(chunk.join(\",\"), options);\n allMessages.push(...msgs);\n // console.log(` [fetch] ${allMessages.length}/${uids.length} (chunk of ${chunk.length})`);\n if (onChunk) onChunk(msgs);\n if (chunkSize < this.fetchChunkSizeMax) chunkSize = Math.min(chunkSize * 4, this.fetchChunkSizeMax);\n }\n return allMessages;\n }\n\n /** Fetch messages by date range. Optional onChunk callback receives each batch as it arrives. */\n async fetchByDate(since: Date, before?: Date, options: { source?: boolean } = {}, onChunk?: (msgs: NativeFetchedMessage[]) => void): Promise<NativeFetchedMessage[]> {\n const criteria = proto.buildSearchCriteria({\n since,\n before: before || undefined,\n });\n // SEARCH SINCE on Dovecot can take minutes on a cold mailbox while it\n // (re)builds its date index. Without a \"search starting\" log, mailx\n // shows nothing for the entire SEARCH window \u2014 the user thinks\n // nothing is happening. Bracket the SEARCH with logs so the silence\n // is at least labeled.\n const t0 = Date.now();\n console.log(` [search] SINCE ${since.toISOString().slice(0, 10)}${before ? ` BEFORE ${before.toISOString().slice(0, 10)}` : \"\"} \u2014 running...`);\n const uids = await this.search(criteria);\n console.log(` [search] returned ${uids.length} UIDs in ${Date.now() - t0}ms`);\n if (uids.length === 0) return [];\n // Reverse so newest messages (highest UIDs) come first\n uids.reverse();\n const allMessages: NativeFetchedMessage[] = [];\n let chunkSize = this.fetchChunkSize;\n let chunkIndex = 0;\n for (let i = 0; i < uids.length; i += chunkSize) {\n const chunk = uids.slice(i, i + chunkSize);\n const msgs = await this.fetchMessages(chunk.join(\",\"), options);\n allMessages.push(...msgs);\n chunkIndex++;\n // Log every 5th chunk + the first one \u2014 enough to see progress\n // without spamming. The first-chunk log proves the fetch is alive\n // even when subsequent chunks are slow.\n if (chunkIndex === 1 || chunkIndex % 5 === 0) {\n console.log(` [fetch] ${allMessages.length}/${uids.length} messages (chunk ${chunkIndex})`);\n }\n if (onChunk) onChunk(msgs);\n if (chunkSize < this.fetchChunkSizeMax) chunkSize = Math.min(chunkSize * 4, this.fetchChunkSizeMax);\n }\n console.log(` [fetch] done \u2014 ${allMessages.length} messages in ${Date.now() - t0}ms`);\n return allMessages;\n }\n\n /** Fetch the most recent N messages by sequence number \u2014 avoids\n * SEARCH SINCE which can take minutes on cold Dovecot mailboxes. The\n * selected mailbox's `EXISTS` count is used to compute the range\n * `(EXISTS-N+1):EXISTS`; sequence FETCH is O(1) on the server because\n * it just reads message slots, no INTERNALDATE walk. Caller must have\n * SELECTed the mailbox first (sequence numbers are session-relative). */\n async fetchLatestN(n: number, options: { source?: boolean } = {}, onChunk?: (msgs: NativeFetchedMessage[]) => void): Promise<NativeFetchedMessage[]> {\n const exists = this.mailboxInfo.exists;\n if (!exists || exists < 1) return [];\n const start = Math.max(1, exists - n + 1);\n const range = `${start}:${exists}`;\n const t0 = Date.now();\n console.log(` [fetch-latest] ${this.selectedMailbox || \"?\"}: sequence ${range} (${Math.min(n, exists)} most recent of ${exists})`);\n\n const items = [\"UID\", \"FLAGS\", \"ENVELOPE\", \"RFC822.SIZE\", \"INTERNALDATE\", \"BODY.PEEK[HEADER]\"];\n if (options.source) items.push(\"BODY.PEEK[]\");\n\n const tag = proto.nextTag();\n const streamed: NativeFetchedMessage[] = [];\n const seenChunks = new Set<number>();\n const cb = (resp: proto.ImapResponse): void => {\n if (resp.tag !== \"*\" || resp.type !== \"FETCH\") return;\n const parsed = this.parseFetchResponses([resp]);\n for (const msg of parsed) streamed.push(msg);\n // Flush onChunk every ~50 messages without buffering the whole\n // response in memory \u2014 same shape as fetchByDate's chunk emit.\n const bucket = Math.floor(streamed.length / 50);\n if (onChunk && !seenChunks.has(bucket)) {\n seenChunks.add(bucket);\n onChunk(parsed);\n }\n };\n await this.sendCommand(tag, proto.seqFetchCommand(tag, range, items), cb);\n if (onChunk && streamed.length > 0) {\n // Final flush in case last bucket didn't trip the threshold.\n const lastBucket = Math.floor(streamed.length / 50);\n if (!seenChunks.has(lastBucket)) onChunk([]);\n }\n // Reverse so newest-first matches fetchByDate ordering \u2014 caller code\n // (mailx) expects that ordering when computing highestUid windows.\n streamed.reverse();\n console.log(` [fetch-latest] done \u2014 ${streamed.length} messages in ${Date.now() - t0}ms`);\n return streamed;\n }\n\n /** Fetch a single message by UID */\n async fetchMessage(uid: number, options: { source?: boolean } = {}): Promise<NativeFetchedMessage | null> {\n const msgs = await this.fetchMessages(String(uid), options);\n return msgs.find(m => m.uid === uid) || null;\n }\n\n /** Get all UIDs in the current mailbox */\n async getUids(): Promise<number[]> {\n return this.search(\"ALL\");\n }\n\n /** UID SEARCH */\n async search(criteria: string): Promise<number[]> {\n const tag = proto.nextTag();\n const responses = await this.sendCommand(tag, proto.searchCommand(tag, criteria));\n for (const r of responses) {\n if (r.tag === \"*\" && r.type === \"SEARCH\") {\n return proto.parseSearchResponse(r.text);\n }\n }\n return [];\n }\n\n /** Set flags on a message */\n async addFlags(uid: number, flags: string[]): Promise<void> {\n const tag = proto.nextTag();\n const responses = await this.sendCommand(tag, proto.storeCommand(tag, uid, \"+FLAGS.SILENT\", flags));\n const tagged = responses.find(r => r.tag === tag);\n if (!tagged || tagged.type !== \"OK\") throw new Error(`STORE +FLAGS failed: ${tagged?.text || \"unknown\"}`);\n }\n\n /** Remove flags from a message */\n async removeFlags(uid: number, flags: string[]): Promise<void> {\n const tag = proto.nextTag();\n const responses = await this.sendCommand(tag, proto.storeCommand(tag, uid, \"-FLAGS.SILENT\", flags));\n const tagged = responses.find(r => r.tag === tag);\n if (!tagged || tagged.type !== \"OK\") throw new Error(`STORE -FLAGS failed: ${tagged?.text || \"unknown\"}`);\n }\n\n /** Copy a message to another mailbox */\n async copyMessage(uid: number, destination: string): Promise<void> {\n const tag = proto.nextTag();\n const responses = await this.sendCommand(tag, proto.copyCommand(tag, uid, destination));\n const tagged = responses.find(r => r.tag === tag);\n if (!tagged || tagged.type !== \"OK\") throw new Error(`COPY failed: ${tagged?.text || \"unknown\"}`);\n }\n\n /** Move a message to another mailbox (MOVE or COPY+DELETE) */\n async moveMessage(uid: number, destination: string): Promise<void> {\n if (this.capabilities.has(\"MOVE\")) {\n const tag = proto.nextTag();\n const responses = await this.sendCommand(tag, proto.moveCommand(tag, uid, destination));\n const tagged = responses.find(r => r.tag === tag);\n if (!tagged || tagged.type !== \"OK\") throw new Error(`MOVE failed: ${tagged?.text || \"unknown\"}`);\n } else {\n await this.copyMessage(uid, destination);\n await this.addFlags(uid, [\"\\\\Deleted\"]);\n await this.expunge();\n }\n }\n\n /** Delete a message by UID (flag + expunge) */\n async deleteMessage(uid: number): Promise<void> {\n await this.addFlags(uid, [\"\\\\Deleted\"]);\n await this.expunge();\n }\n\n /** Expunge deleted messages */\n async expunge(): Promise<void> {\n const tag = proto.nextTag();\n await this.sendCommand(tag, proto.buildCommand(tag, \"EXPUNGE\"));\n }\n\n /** Append a message to a mailbox */\n async appendMessage(mailbox: string, message: string | Uint8Array, flags: string[] = []): Promise<number | null> {\n const data = typeof message === \"string\" ? message : new TextDecoder().decode(message);\n const size = new TextEncoder().encode(data).length;\n\n const tag = proto.nextTag();\n const cmd = proto.appendCommand(tag, mailbox, flags, size);\n\n // Send command, wait for continuation\n await this.transport.write(cmd);\n\n // Wait for \"+\" continuation\n const contResp = await this.waitForContinuation(tag);\n if (!contResp) throw new Error(\"APPEND: server did not send continuation\");\n\n // Send the message data + CRLF\n await this.transport.write(data + \"\\r\\n\");\n\n // Wait for tagged response\n const responses = await this.waitForTagged(tag);\n const tagged = responses.find(r => r.tag === tag);\n if (!tagged || tagged.type !== \"OK\") throw new Error(`APPEND failed: ${tagged?.text || \"unknown\"}`);\n\n // Try to extract APPENDUID\n const uidMatch = tagged.text.match(/APPENDUID\\s+\\d+\\s+(\\d+)/i);\n return uidMatch ? parseInt(uidMatch[1]) : null;\n }\n\n // \u2500\u2500 NOTIFY (RFC 5465) \u2500\u2500\n\n /** Issue NOTIFY SET so the server starts pushing unsolicited STATUS\n * responses for the mailboxes named in `spec` (beyond the currently\n * selected one). Capability gated \u2014 callers must check\n * `getCapabilities().has(\"NOTIFY\")` before calling. Set\n * `onMailboxStatus` before issuing if you want to react. Issue AFTER\n * SELECT and BEFORE startIdle \u2014 the server holds the spec for the\n * lifetime of the connection. */\n async notify(spec: string): Promise<void> {\n const tag = proto.nextTag();\n const responses = await this.sendCommand(tag, proto.notifyCommand(tag, spec));\n const tagged = responses.find(r => r.tag === tag);\n if (!tagged || tagged.type !== \"OK\") {\n throw new Error(`NOTIFY SET failed: ${tagged?.text || \"unknown\"}`);\n }\n }\n\n // \u2500\u2500 IDLE \u2500\u2500\n\n async startIdle(\n onNewMail: (count: number) => void,\n onExpunge?: () => void,\n ): Promise<() => Promise<void>> {\n this.idleCallback = onNewMail;\n this.idleExpungeCallback = onExpunge ?? null;\n this.idleStopped = false;\n\n const beginIdleCycle = async (): Promise<void> => {\n const tag = proto.nextTag();\n this.idleTag = tag;\n // Arm continuation listener BEFORE writing \u2014 some servers reply fast enough\n // that data can arrive in the same tick.\n const waitCont = this.waitForContinuation(tag);\n await this.transport.write(proto.idleCommand(tag));\n await waitCont;\n // RFC 2177: re-IDLE every ~28 minutes to avoid servers that terminate\n // idle sessions at the 29-minute mark, and to give us a steady\n // application-level keepalive that detects silently-dropped sockets.\n this.idleRefreshTimer = setTimeout(() => {\n if (this.idleStopped) return;\n this.refreshIdle().catch(err => {\n if (this.verbose) console.error(` [imap] IDLE refresh failed: ${err.message}`);\n });\n }, 28 * 60 * 1000);\n };\n\n await beginIdleCycle();\n\n return async () => {\n this.idleStopped = true;\n if (this.idleRefreshTimer) { clearTimeout(this.idleRefreshTimer); this.idleRefreshTimer = null; }\n const tag = this.idleTag;\n this.idleTag = null;\n this.idleCallback = null;\n this.idleExpungeCallback = null;\n if (tag) {\n // Arm tagged-wait BEFORE DONE \u2014 avoid missing the OK.\n const waitTag = this.waitForTagged(tag);\n try { await this.transport.write(proto.doneCommand()); } catch { /* ignore */ }\n try { await waitTag; } catch { /* ignore */ }\n }\n };\n }\n\n /**\n * If IDLE is currently active, send DONE and wait for its tagged OK so the\n * connection is free to accept a new command. Saves the active callback so\n * the companion `resumeIdleAfterCommand` can re-enter IDLE on the same\n * mailbox afterwards. Returns the saved state, or null if IDLE was not active.\n *\n * Called automatically at the top of `sendCommand` whenever the caller issues\n * an interleaved command on an IDLE-holding connection (e.g. pullMail reacting\n * to an EXISTS notification).\n */\n private async suspendIdleForCommand(): Promise<{ callback: (count: number) => void } | null> {\n const oldTag = this.idleTag;\n const cb = this.idleCallback;\n if (!oldTag || !cb) return null;\n if (this.idleRefreshTimer) { clearTimeout(this.idleRefreshTimer); this.idleRefreshTimer = null; }\n this.idleTag = null;\n this.idleCallback = null;\n if (this.verbose) console.log(` [imap] IDLE auto-suspending for interleaved command`);\n // Arm tagged listener BEFORE DONE so we don't miss the OK if the server is fast.\n const waitTag = this.waitForTagged(oldTag);\n try { await this.transport.write(proto.doneCommand()); }\n catch (err) {\n // Write failure \u2014 pendingCommand is still set by waitForTagged; clear it to prevent hang.\n this.pendingCommand = null;\n throw err;\n }\n try { await waitTag; } catch { /* best-effort \u2014 proceed even if OK was lost */ }\n return { callback: cb };\n }\n\n /** Re-enter IDLE with the saved callback after an auto-suspended command completes. */\n private async resumeIdleAfterCommand(info: { callback: (count: number) => void }): Promise<void> {\n // The caller may have stopped IDLE during the command window \u2014 respect that.\n if (this.idleStopped) return;\n const newTag = proto.nextTag();\n this.idleTag = newTag;\n this.idleCallback = info.callback;\n // Arm continuation listener BEFORE writing IDLE.\n const waitCont = this.waitForContinuation(newTag);\n await this.transport.write(proto.idleCommand(newTag));\n await waitCont;\n if (this.verbose) console.log(` [imap] IDLE auto-resumed (${newTag})`);\n this.idleRefreshTimer = setTimeout(() => {\n if (this.idleStopped) return;\n this.refreshIdle().catch(err => {\n if (this.verbose) console.error(` [imap] IDLE refresh failed: ${err.message}`);\n });\n }, 28 * 60 * 1000);\n }\n\n /** Send DONE + re-IDLE. Called by the 28-minute refresh timer. */\n private async refreshIdle(): Promise<void> {\n const oldTag = this.idleTag;\n if (!oldTag || !this.idleCallback) return;\n const cb = this.idleCallback;\n // Arm tagged listener BEFORE writing DONE to avoid missing a fast OK.\n const waitTag = this.waitForTagged(oldTag);\n await this.transport.write(proto.doneCommand());\n try { await waitTag; } catch { /* best-effort */ }\n // Re-IDLE with a new tag\n this.idleCallback = cb; // waitForTagged resolved pendingCommand, reinstall callback\n const newTag = proto.nextTag();\n this.idleTag = newTag;\n const waitCont = this.waitForContinuation(newTag);\n await this.transport.write(proto.idleCommand(newTag));\n await waitCont;\n if (this.verbose) console.log(` [imap] IDLE refreshed (${newTag})`);\n // Schedule the next refresh\n this.idleRefreshTimer = setTimeout(() => {\n if (this.idleStopped) return;\n this.refreshIdle().catch(err => {\n if (this.verbose) console.error(` [imap] IDLE refresh failed: ${err.message}`);\n });\n }, 28 * 60 * 1000);\n }\n\n // \u2500\u2500 Message count (lightweight STATUS) \u2500\u2500\n\n async getMessageCount(mailbox: string): Promise<number> {\n const status = await this.getStatus(mailbox);\n return status.messages || 0;\n }\n\n // \u2500\u2500 Low-level command handling \u2500\u2500\n\n /** Inactivity timeout \u2014 how long to wait with NO data before declaring the connection dead.\n * This is NOT a wall-clock timeout. Timer resets every time data arrives from the server.\n * A large FETCH returning data continuously will never timeout.\n * 60s accommodates Gmail which is slow on SEARCH for large folders.\n * Overridable via ImapClientConfig.inactivityTimeout \u2014 slow Dovecot servers need 180s+. */\n private inactivityTimeout: number;\n /** Hard wall-clock cap per command (independent of inactivityTimeout).\n * A pathological server that returns one byte every (inactivityTimeout-1)\n * seconds would otherwise defer the inactivity timer forever; this is\n * the absolute deadline that always fires. Default 5 minutes. */\n private commandWallClockTimeout: number;\n /** Server-greeting timeout in ms \u2014 how long to wait for the server's\n * initial banner after TCP/TLS connects. Default 10s; bumped to 30s\n * for slow shared-hosting Dovecot in mailx-imap. */\n private greetingTimeout: number;\n\n /** Fetch chunk sizes \u2014 start small for quick first paint, ramp up for throughput.\n * Default 25 initial \u2192 500 max. Overridable via ImapClientConfig.fetchChunkSize /\n * fetchChunkSizeMax. Slow servers benefit from smaller chunks (fewer timeouts). */\n private fetchChunkSize: number;\n private fetchChunkSizeMax: number;\n\n /** Active command timer \u2014 reset by handleData on every data arrival */\n private commandTimer: ReturnType<typeof setTimeout> | null = null;\n\n /**\n * Issue an IMAP command and await its tagged response.\n *\n * If IDLE is currently active on this connection, DONE it first (and wait\n * for its tagged OK) before writing the new command; re-enter IDLE after\n * the command finishes. Without this, commands issued from within an IDLE\n * EXISTS callback (e.g. mailpuller's pullMail) would be ignored by the\n * server until the inactivity timer killed the socket.\n */\n /** Per-client command serialization. IMAP allows only one command in\n * flight at a time on a single connection (RFC 3501 \u00A72.2.1). The\n * client's `pendingCommand` field tracks that command \u2014 if a second\n * caller concurrently invokes sendCommand, it overwrites\n * pendingCommand and the first caller's await is orphaned. We saw\n * this in production: the outbox poller's `withConnection`-queued\n * task ran on the same shared ops client as syncFolder's INBOX work,\n * and INBOX silently hung forever (no heartbeat fire, no wall-clock,\n * no reject \u2014 the promise just had no command tracking it anymore).\n *\n * This chain serializes ALL sendCommand callers against this client\n * regardless of whether the caller bothered to coordinate.\n * Defensive \u2014 the right thing for the upper layer to do is also use\n * the queue (withConnection in mailx-imap), but the IMAP client\n * shouldn't allow itself to be corrupted by a careless caller. */\n private commandChain: Promise<unknown> = Promise.resolve();\n private async sendCommand(\n tag: string,\n command: string,\n onUntagged?: (resp: proto.ImapResponse) => void,\n ): Promise<proto.ImapResponse[]> {\n const prev = this.commandChain.catch(() => { /* ignore predecessor errors */ });\n let myResolve!: (v: proto.ImapResponse[]) => void;\n let myReject!: (e: any) => void;\n const myPromise = new Promise<proto.ImapResponse[]>((res, rej) => { myResolve = res; myReject = rej; });\n this.commandChain = myPromise.catch(() => { /* */ });\n // Phase timing \u2014 multi-session \"62 s INBOX stall\" hunt. The stall\n // produces NO `>` log (sendCommandCore never runs), so it lives in\n // one of the two awaits below. Logging only slow phases (>1 s, Bob's\n // \"synchronous shouldn't span\" threshold lifted to network scale)\n // pins which one without spamming the normal fast path.\n const __cmdName = command.split(/[\\s\\r]/)[0] || command.slice(0, 12);\n const __p0 = Date.now();\n await prev;\n const __prevMs = Date.now() - __p0;\n if (__prevMs > 1000) console.warn(` [imap] cmd-chain wait ${__prevMs}ms before ${__cmdName} (predecessor held the connection)`);\n try {\n const __p1 = Date.now();\n const idleState = await this.suspendIdleForCommand();\n const __idleMs = Date.now() - __p1;\n if (__idleMs > 1000) console.warn(` [imap] IDLE-suspend wait ${__idleMs}ms before ${__cmdName}`);\n try {\n const out = await this.sendCommandCore(tag, command, onUntagged);\n myResolve(out);\n return out;\n } finally {\n if (idleState) {\n try { await this.resumeIdleAfterCommand(idleState); }\n catch (err) { if (this.verbose) console.error(` [imap] IDLE auto-resume failed: ${(err as Error).message}`); }\n }\n }\n } catch (e) {\n myReject(e);\n throw e;\n }\n }\n\n private sendCommandCore(\n tag: string,\n command: string,\n onUntagged?: (resp: proto.ImapResponse) => void,\n ): Promise<proto.ImapResponse[]> {\n return new Promise((resolve, reject) => {\n if (this.verbose && !command.includes(\"LOGIN\") && !command.includes(\"AUTHENTICATE\")) {\n console.log(` [imap] > ${command.trimEnd()}`);\n }\n\n // Snapshot transport diagnostics \u2014 used by both heartbeat and timeout.\n const transportDiag = (): string => {\n try {\n const d = (this.transport as any)?.diagnostics;\n if (!d) return \"\";\n const sinceRead = d.lastReadAt ? Date.now() - d.lastReadAt : -1;\n return ` [conn#${d.connId} r=${d.bytesRead}B w=${d.bytesWritten}B writes=${d.writeCount} sinceLastRead=${sinceRead}ms]`;\n } catch { return \"\"; }\n };\n\n // Always start clean \u2014 defends against a prior pendingCommand\n // having leaked timers (e.g. swap by suspendIdle/resumeIdle that\n // bypassed resolve/reject).\n this.clearAllCommandTimers();\n\n const cmdStart = Date.now();\n const cmdSummary = command.split(\"\\r\")[0].substring(0, 80);\n\n const onTimeout = (kind: string): void => {\n this.clearAllCommandTimers();\n this.pendingCommand = null;\n this._connected = false;\n this.transport.close?.();\n reject(new Error(`${kind}: ${cmdSummary}${transportDiag()}`));\n };\n\n // Three timers, three responsibilities \u2014 all instance-scoped now:\n // commandTimer = inactivity (resets on each data chunk)\n // wallClockTimer = hard cap from command start, never resets\n // heartbeatTimer = periodic progress log every 30s\n this.commandTimer = setTimeout(\n () => onTimeout(`IMAP inactivity timeout (${this.inactivityTimeout / 1000}s)`),\n this.inactivityTimeout,\n );\n this.wallClockTimer = setTimeout(\n () => onTimeout(`IMAP command wall-clock timeout (${this.commandWallClockTimeout / 1000}s)`),\n this.commandWallClockTimeout,\n );\n this.heartbeatTimer = setInterval(() => {\n const waited = Date.now() - cmdStart;\n console.log(` [imap] still waiting for tag ${tag} after ${(waited / 1000).toFixed(1)}s \u2014 ${cmdSummary}${transportDiag()}`);\n }, 30_000);\n\n this.pendingCommand = {\n tag, responses: [],\n resolve: (responses) => { this.clearAllCommandTimers(); resolve(responses); },\n reject: (err) => { this.clearAllCommandTimers(); reject(err); },\n onUntagged,\n };\n // PRE-WRITE HEALTH CHECK \u2014 verify the socket is in a writable\n // state BEFORE we burn the inactivityTimeout window waiting for\n // a reply that can't come. socket-half-closed (peer FIN'd) and\n // destroyed states both fail fast here instead of after 300s.\n try {\n const h = (this.transport as any)?.socketHealth;\n if (h && (h.destroyed || h.writableEnded || !h.writable)) {\n this.clearAllCommandTimers();\n this.pendingCommand = null;\n this._connected = false;\n reject(new Error(`IMAP socket dead before write: destroyed=${h.destroyed} writableEnded=${h.writableEnded} writable=${h.writable}${transportDiag()}`));\n return;\n }\n } catch { /* transport may not expose socketHealth \u2014 fall through */ }\n\n this.transport.write(command).catch((err) => {\n this.clearAllCommandTimers();\n // Write failure = dead socket. Clear pendingCommand + disconnect flag\n // so the next ensureConnected() does a fresh connect instead of\n // reusing a socket that the OS layer has already declared dead\n // (the source of the \"hostname nor servname provided\" cascade).\n this.pendingCommand = null;\n this._connected = false;\n reject(err);\n });\n });\n }\n\n private waitForContinuation(tag: string): Promise<proto.ImapResponse | null> {\n return new Promise((resolve) => {\n const timeout = setTimeout(() => {\n this.continuationResolve = null;\n resolve(null);\n }, 30000);\n this.continuationResolve = (resp) => {\n clearTimeout(timeout);\n this.continuationResolve = null;\n resolve(resp);\n };\n });\n }\n\n private waitForTagged(tag: string): Promise<proto.ImapResponse[]> {\n return new Promise((resolve, reject) => {\n this.pendingCommand = { tag, resolve, reject, responses: [] };\n });\n }\n\n private handleData(data: Uint8Array): void {\n // Reset inactivity timer ONLY (heartbeat + wall-clock NEVER reset\n // on data \u2014 that was the original bug: wall-clock got reset every\n // byte, so a slow-trickling server's command never died). Inactivity\n // is \"no data for N seconds\"; data IS arriving, so push it out.\n if (this.commandTimer) {\n clearTimeout(this.commandTimer);\n this.commandTimer = setTimeout(() => {\n this.commandTimer = null;\n if (this.pendingCommand) {\n const cmd = this.pendingCommand;\n this.pendingCommand = null;\n // Use the canonical clear so heartbeat + wall-clock\n // also stop. cmd.reject runs clearAllCommandTimers via\n // the closure binding \u2014 call it directly here too in\n // case cmd.reject was already replaced (defense in depth).\n this.clearAllCommandTimers();\n this._connected = false;\n this.transport.close?.();\n cmd.reject(new Error(`IMAP inactivity timeout (${this.inactivityTimeout / 1000}s)`));\n }\n }, this.inactivityTimeout);\n }\n this.appendToBuffer(data);\n this.processBuffer();\n }\n\n /** Append received bytes to the receive buffer, growing capacity if\n * needed. O(n) over the chunk size, never over the buffer total \u2014\n * doubling growth amortizes to O(1) per byte across the response. */\n private appendToBuffer(data: Uint8Array): void {\n const need = this.bufferLength + data.length;\n if (need > this.buffer.length) {\n let cap = Math.max(this.buffer.length * 2, 8192);\n while (cap < need) cap *= 2;\n const grown = new Uint8Array(cap);\n grown.set(this.buffer.subarray(0, this.bufferLength));\n this.buffer = grown;\n }\n this.buffer.set(data, this.bufferLength);\n this.bufferLength += data.length;\n }\n\n /** Single canonical \"command finished or abandoned\" cleanup. Every\n * path that ends a command's lifecycle \u2014 resolve, reject, timeout,\n * socket close, command-replace \u2014 calls this. Was a leak source:\n * closure-scoped timers in sendCommandCore couldn't be cleared from\n * handleData's inline-replacement timer or from IDLE suspend/resume. */\n private clearAllCommandTimers(): void {\n if (this.commandTimer) { clearTimeout(this.commandTimer); this.commandTimer = null; }\n if (this.heartbeatTimer) { clearInterval(this.heartbeatTimer); this.heartbeatTimer = null; }\n if (this.wallClockTimer) { clearTimeout(this.wallClockTimer); this.wallClockTimer = null; }\n }\n\n /** Compact the buffer when bufferOffset has advanced past half the used\n * region. copyWithin moves the unread bytes to the front in-place\n * (no new allocation). Amortized O(1) per byte; never the O(n\u00B2)\n * substring-each-line pathology that blocked the event loop on a\n * large LIST response. */\n private compactBufferIfNeeded(): void {\n if (this.bufferOffset > 0 && this.bufferOffset >= this.bufferLength / 2) {\n this.buffer.copyWithin(0, this.bufferOffset, this.bufferLength);\n this.bufferLength -= this.bufferOffset;\n this.bufferOffset = 0;\n }\n }\n\n /** Find the next CRLF (0x0D 0x0A) in the unread region, returning the\n * byte index of the 0x0D, or -1 if not found. Manual byte loop \u2014\n * Uint8Array doesn't have a native indexOf for byte sequences. */\n private indexOfCRLF(from: number): number {\n const buf = this.buffer;\n const end = this.bufferLength - 1;\n for (let i = from; i < end; i++) {\n if (buf[i] === 0x0D && buf[i + 1] === 0x0A) return i;\n }\n return -1;\n }\n\n private processBuffer(): void {\n // Time-budget the synchronous processing so a large FETCH burst\n // (sync of many envelopes in a single data chunk) doesn't starve\n // the Node event loop. Without this yield, IPC dispatchers in the\n // same process can wait 10+ seconds to get cycles \u2014 visible as\n // `mailxapi timeout: getMessage` / `getUnifiedInbox` on the desktop\n // client during heavy sync (Bob 2026-05-15: log shows daemon doing\n // hundreds of literal-consumed per second; client IPCs starve and\n // hit 30s ceiling). 10 ms budget = the same time slice Node uses\n // for I/O; after that we yield via setImmediate so timers, IPC,\n // and other I/O get a turn, then resume.\n const t0 = performance.now();\n const TIME_BUDGET_MS = 10;\n while (true) {\n if (performance.now() - t0 > TIME_BUDGET_MS) {\n setImmediate(() => this.processBuffer());\n return;\n }\n // Check for literal \u2014 `{N}` announces N octets of arbitrary data\n // (message body, MIME part, attachment chunk). The buffer is\n // bytes; the check is a direct length compare and the slice is\n // O(N) over the literal's own size \u2014 never O(buffer\u00B2).\n if (this.pendingCommand?.literalBytes != null) {\n const neededBytes = this.pendingCommand.literalBytes;\n const available = this.bufferLength - this.bufferOffset;\n if (available < neededBytes) {\n if (this.verbose && this.pendingCommand.literalBytes > 0) {\n console.log(` [imap] waiting for literal: need ${neededBytes} bytes, have ${available}`);\n }\n break; // Wait for more data \u2014 cheap, no decode.\n }\n // Slice the literal bytes; advance the read cursor by N.\n // The bytes themselves stay in the underlying buffer for the\n // moment, but bufferOffset advances past them and the next\n // compactBufferIfNeeded will reclaim the space.\n const literalBytes = this.buffer.subarray(this.bufferOffset, this.bufferOffset + neededBytes);\n this.bufferOffset += neededBytes;\n // Decode literal once (UTF-8 with replacement). For BODY[]\n // literals carrying non-UTF-8 charsets this is still lossy \u2014\n // the proper fix is to keep literals as bytes through to the\n // body store, tracked separately. The win HERE is that the\n // decode happens once per literal, not once per chunk that\n // arrives during the literal's transit.\n let literal = this.utf8Decoder.decode(literalBytes);\n // For non-BODY literals (e.g. display names in ENVELOPE), wrap in quotes\n // so tokenizeParenList treats them as a single token\n if (!this.pendingCommand.currentLiteralKey) {\n literal = `\"${literal.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"').replace(/\\r?\\n/g, \"\")}\"`;\n }\n this.pendingCommand.literalBuffer = (this.pendingCommand.literalBuffer || \"\") + literal;\n this.pendingCommand.literalBytes = undefined;\n // Store the literal data by its BODY key for parseFetchResponses\n if (this.pendingCommand.currentLiteralKey) {\n if (!this.pendingCommand.literals) this.pendingCommand.literals = new Map();\n this.pendingCommand.literals.set(this.pendingCommand.currentLiteralKey, literal);\n this.pendingCommand.currentLiteralKey = undefined;\n this.pendingCommand.currentLiteralSize = undefined;\n }\n if (this.verbose) console.log(` [imap] literal consumed, ${neededBytes} bytes, buffer remaining: ${this.bufferLength - this.bufferOffset}`);\n // Allow the consumed-prefix to be reclaimed when half-full \u2014\n // long literal-heavy responses would otherwise grow the\n // backing buffer indefinitely between commands.\n this.compactBufferIfNeeded();\n continue;\n }\n\n // Find next CRLF starting from the read offset on bytes (not\n // chars). bufferOffset advances past consumed bytes; we only\n // search the unread region so per-line work is O(line length),\n // never O(response size).\n const lineEnd = this.indexOfCRLF(this.bufferOffset);\n if (lineEnd < 0) {\n // No complete line yet. Compact the buffer if we've advanced\n // far enough that the unconsumed-prefix is dragging.\n this.compactBufferIfNeeded();\n break;\n }\n\n // Slice the line bytes (including trailing CRLF) and decode\n // once. IMAP control lines are 7-bit ASCII per RFC 3501; UTF-8\n // decode is a superset and produces the same characters. The\n // existing string-based parser (parseResponseLine, tokenizers,\n // ENVELOPE/FLAGS handling) consumes the decoded line below.\n const lineBytes = this.buffer.subarray(this.bufferOffset, lineEnd + 2);\n const line = this.utf8Decoder.decode(lineBytes);\n this.bufferOffset = lineEnd + 2;\n // Periodic compaction so the consumed prefix doesn't keep\n // growing forever in long-running connections (IDLE, big sync).\n this.compactBufferIfNeeded();\n\n // Check for literal announcement {size}\\r\\n at end of line\n const literalMatch = line.match(/\\{(\\d+)\\}\\r\\n$/);\n if (literalMatch && this.pendingCommand) {\n const size = parseInt(literalMatch[1]);\n // Store the line prefix before {size} \u2014 will be prepended after literal is consumed\n const linePrefix = line.substring(0, literalMatch.index);\n if (this.pendingCommand.literalBuffer) {\n // Already have buffered data from a previous literal \u2014 append this prefix\n this.pendingCommand.literalBuffer += linePrefix;\n } else {\n this.pendingCommand.literalBuffer = linePrefix;\n }\n this.pendingCommand.literalBytes = size;\n // Extract the BODY section key from the prefix (e.g. BODY[], BODY[HEADER], BODY.PEEK[])\n const keyMatch = linePrefix.match(/BODY(?:\\.PEEK)?\\[([^\\]]*)\\]\\s*$/i);\n if (keyMatch) {\n this.pendingCommand.currentLiteralKey = `BODY[${keyMatch[1]}]`;\n this.pendingCommand.currentLiteralSize = size;\n }\n if (this.verbose) console.log(` [imap] literal announced: ${size} bytes, prefix: ${linePrefix.length} chars, key: ${this.pendingCommand.currentLiteralKey || \"none\"}`);\n continue;\n }\n\n // If we have buffered literal data, prepend it to this line (the closing part after the literal)\n let fullLine = line;\n if (this.pendingCommand?.literalBuffer) {\n fullLine = this.pendingCommand.literalBuffer + line;\n this.pendingCommand.literalBuffer = undefined;\n }\n\n const resp = proto.parseResponseLine(fullLine);\n\n // Attach accumulated literals to the response and reset for next response\n if (this.pendingCommand?.literals?.size) {\n resp.literals = this.pendingCommand.literals;\n this.pendingCommand.literals = undefined;\n }\n\n if (this.verbose) {\n const display = resp.raw.length > 200 ? resp.raw.substring(0, 200) + `... (${resp.raw.length} bytes)` : resp.raw;\n console.log(` [imap] < [tag=${resp.tag} type=${resp.type}] ${display}`);\n }\n\n // Server greeting \u2014 resolve readGreeting() promise\n if (this.greetingResolve && resp.tag === \"*\" && (resp.type === \"OK\" || resp.type === \"PREAUTH\")) {\n const resolve = this.greetingResolve;\n this.greetingResolve = null;\n resolve(resp);\n continue;\n }\n\n // During IDLE, handle EXISTS notifications\n if (this.idleTag && resp.tag === \"*\" && resp.type === \"EXISTS\") {\n const count = parseInt(resp.text);\n if (this.idleCallback && count > this.mailboxInfo.exists) {\n const newCount = count - this.mailboxInfo.exists;\n this.mailboxInfo.exists = count;\n this.idleCallback(newCount);\n } else if (count < this.mailboxInfo.exists) {\n // Count dropped \u2014 a message was expunged on the selected\n // mailbox (another client / Thunderbird deleted it).\n // Signal the caller to reconcile the deletion now.\n this.mailboxInfo.exists = count;\n if (this.idleExpungeCallback) this.idleExpungeCallback();\n }\n continue;\n }\n\n // During IDLE, an unsolicited `* n EXPUNGE` / `* VANISHED` for the\n // selected mailbox (RFC 5465 NOTIFY SELECTED MessageExpunge, or a\n // plain post-EXPUNGE notification). Push a deletion reconcile.\n if (this.idleTag && resp.tag === \"*\" && (resp.type === \"EXPUNGE\" || resp.type === \"VANISHED\")) {\n if (this.mailboxInfo.exists > 0) this.mailboxInfo.exists--;\n if (this.idleExpungeCallback) this.idleExpungeCallback();\n continue;\n }\n\n // RFC 5465 NOTIFY: unsolicited STATUS responses for non-selected\n // mailboxes arrive when the server has accepted a NOTIFY SET that\n // included a PERSONAL (or other) event group. Only route to the\n // callback when IDLE is active \u2014 a STATUS response outside IDLE\n // is the result of a direct STATUS command and belongs to the\n // pending command's response set (the fall-through below).\n if (this.idleTag && resp.tag === \"*\" && resp.type === \"STATUS\" && this.onMailboxStatus) {\n const parsed = proto.parseStatusResponseFull(resp.text);\n if (parsed) {\n try { this.onMailboxStatus(parsed.mailbox, parsed.data); }\n catch (err) { if (this.verbose) console.error(` [imap] onMailboxStatus threw: ${(err as Error).message}`); }\n continue;\n }\n // Parse failed \u2014 fall through so the response isn't silently dropped.\n }\n\n // Collect untagged responses for the pending command\n if (resp.tag === \"*\" && this.pendingCommand) {\n this.pendingCommand.responses.push(resp);\n if (this.pendingCommand.onUntagged) {\n try { this.pendingCommand.onUntagged(resp); }\n catch (err) { if (this.verbose) console.error(` [imap] onUntagged callback threw: ${(err as Error).message}`); }\n }\n continue;\n }\n\n // Continuation response\n if (resp.tag === \"+\") {\n if (this.continuationResolve) {\n // APPEND or other command waiting for continuation\n this.continuationResolve(resp);\n } else if (!this.idleTag && this.pendingCommand) {\n // Unexpected continuation (e.g. AUTHENTICATE challenge) \u2014 cancel\n this.transport.write(\"\\r\\n\").catch(() => {});\n }\n continue;\n }\n\n // Tagged response \u2014 command complete\n if (this.pendingCommand && resp.tag === this.pendingCommand.tag) {\n this.pendingCommand.responses.push(resp);\n const { resolve, responses } = this.pendingCommand;\n this.pendingCommand = null;\n resolve(responses);\n continue;\n }\n\n // Unhandled\n this.handleUntaggedResponse(resp);\n }\n }\n\n private handleUntaggedResponse(resp: proto.ImapResponse): void {\n if (resp.type === \"EXISTS\") {\n this.mailboxInfo.exists = parseInt(resp.text);\n } else if (resp.type === \"EXPUNGE\") {\n this.mailboxInfo.exists = Math.max(0, this.mailboxInfo.exists - 1);\n }\n }\n\n // \u2500\u2500 FETCH Response Parser \u2500\u2500\n\n private parseFetchResponses(responses: proto.ImapResponse[]): NativeFetchedMessage[] {\n const messages: NativeFetchedMessage[] = [];\n\n for (const r of responses) {\n if (r.tag !== \"*\" || r.type !== \"FETCH\") continue;\n\n const msg: NativeFetchedMessage = {\n seq: 0, uid: 0, flags: new Set(), date: null,\n subject: \"\", messageId: \"\", from: [], to: [], cc: [], bcc: [],\n sender: [], replyTo: [], inReplyTo: \"\", size: 0,\n source: \"\", headers: \"\", seen: false, flagged: false,\n answered: false, draft: false,\n };\n\n // Extract sequence number from \"5 FETCH (...)\"\n const seqMatch = r.text.match(/^(\\d+)\\s+FETCH/);\n if (seqMatch) msg.seq = parseInt(seqMatch[1]);\n\n // Extract UID\n const uidMatch = r.text.match(/UID\\s+(\\d+)/);\n if (uidMatch) msg.uid = parseInt(uidMatch[1]);\n\n // Extract FLAGS\n const flagsMatch = r.text.match(/FLAGS\\s+\\(([^)]*)\\)/);\n if (flagsMatch) {\n msg.flags = new Set(flagsMatch[1].split(/\\s+/).filter(Boolean));\n msg.seen = msg.flags.has(\"\\\\Seen\");\n msg.flagged = msg.flags.has(\"\\\\Flagged\");\n msg.answered = msg.flags.has(\"\\\\Answered\");\n msg.draft = msg.flags.has(\"\\\\Draft\");\n }\n\n // Extract RFC822.SIZE\n const sizeMatch = r.text.match(/RFC822\\.SIZE\\s+(\\d+)/);\n if (sizeMatch) msg.size = parseInt(sizeMatch[1]);\n\n // Extract MODSEQ (RFC 7162). Format: `MODSEQ (12345)`. Server\n // emits this when the session has ENABLE QRESYNC/CONDSTORE\n // active OR when the client explicitly asks for MODSEQ in the\n // FETCH command. Track on every FETCH so the caller can update\n // its `last_modseq` watermark.\n const modSeqMatch = r.text.match(/MODSEQ\\s+\\((\\d+)\\)/);\n if (modSeqMatch) msg.modSeq = parseInt(modSeqMatch[1]);\n\n // Extract INTERNALDATE\n const dateMatch = r.text.match(/INTERNALDATE\\s+\"([^\"]+)\"/);\n if (dateMatch) msg.date = new Date(dateMatch[1]);\n\n // Extract ENVELOPE\n const envMatch = r.text.match(/ENVELOPE\\s+(\\(.*\\))/);\n if (envMatch) {\n const env = proto.parseEnvelope(envMatch[1]);\n msg.date = msg.date || env.date;\n msg.subject = env.subject;\n msg.messageId = env.messageId;\n msg.from = env.from;\n msg.to = env.to;\n msg.cc = env.cc;\n msg.bcc = env.bcc;\n msg.sender = env.sender;\n msg.replyTo = env.replyTo;\n msg.inReplyTo = env.inReplyTo;\n }\n\n // Extract body source and headers from literals tracked by processBuffer\n if (r.literals) {\n const source = r.literals.get(\"BODY[]\");\n if (source) msg.source = source;\n const headers = r.literals.get(\"BODY[HEADER]\");\n if (headers) msg.headers = headers;\n }\n\n messages.push(msg);\n }\n return messages;\n }\n}\n", "/**\n * FetchedMessage \u2014 NativeFetchedMessage plus parsed-header state and convenience getters.\n *\n * Inherits the NativeFetchedMessage shape (via `implements`) so a FetchedMessage\n * is-a NativeFetchedMessage: it can be passed anywhere the native interface is\n * expected. Callers that want the raw shape treat it as NativeFetchedMessage;\n * callers that want extras read `.ymd`, `.listUnsubscribe`, etc. directly.\n */\n\nimport type { NativeFetchedMessage } from \"./imap-native.js\";\nimport type { AddressData } from \"./imap-protocol.js\";\n\n/** Case-insensitive multi-value header map (one key may repeat). */\nclass HeaderMap {\n private items: Record<string, string[]> = {};\n add(key: string, value: string): void {\n const k = key.toLowerCase();\n (this.items[k] ||= []).push(value);\n }\n get(key: string): string[] | undefined {\n return this.items[key.toLowerCase()];\n }\n}\n\nexport class FetchedMessage implements NativeFetchedMessage {\n // Native fields \u2014 populated by Object.assign in the constructor.\n // `implements NativeFetchedMessage` forces this list to stay in sync.\n seq!: number;\n uid!: number;\n flags!: Set<string>;\n date!: Date | null;\n subject!: string;\n messageId!: string;\n from!: AddressData[];\n to!: AddressData[];\n cc!: AddressData[];\n bcc!: AddressData[];\n sender!: AddressData[];\n replyTo!: AddressData[];\n inReplyTo!: string;\n size!: number;\n source!: string;\n headers!: string;\n seen!: boolean;\n flagged!: boolean;\n answered!: boolean;\n draft!: boolean;\n modSeq?: number;\n\n // Parsed-header state\n parsedHeader: string[][];\n headerSet: HeaderMap;\n\n constructor(init: NativeFetchedMessage) {\n Object.assign(this, init);\n\n // RFC 5322 unfold: a line starting with whitespace continues the prior one.\n const unfolded = (init.headers || \"\").replace(/\\r\\n(\\s)/g, \"$1\");\n this.parsedHeader = unfolded\n .split(/\\r?\\n/)\n .filter(line => line.trim() !== \"\")\n .map(line => {\n const i = line.indexOf(\":\");\n return i < 0 ? [line, \"\"] : [line.slice(0, i), line.slice(i + 1).trim()];\n });\n this.headerSet = new HeaderMap();\n for (const [k, v] of this.parsedHeader) this.headerSet.add(k, v);\n }\n\n // Flag convenience\n get unread() { return !this.seen; }\n get deleted() { return this.flags.has(\"\\\\Deleted\"); }\n get hasFlag() { return this.flags.size > 0; }\n\n // Display\n get ymd(): string | undefined { return this.date?.toLocaleDateString(\"se\"); }\n /** Self-typed as a keyable record for dynamic address-field access by screening rules. */\n get tcsb(): Record<string, AddressData[]> {\n return this as unknown as Record<string, AddressData[]>;\n }\n\n // Parsed-header lookups\n get listUnsubscribe() { return this.headerSet.get(\"List-Unsubscribe\")?.[0]; }\n get xpriority() { return this.headerSet.get(\"X-Priority\")?.[0]; }\n get importance() { return this.headerSet.get(\"Importance\")?.[0]; }\n get deliveredTo() { return this.headerSet.get(\"Delivered-To\")?.[0]; }\n}\n", "/**\n * Compatibility wrapper \u2014 makes NativeImapClient look like the old ImapClient API.\n * This allows mailx-imap to switch to the native client without rewriting all call sites.\n * Each method opens the mailbox, does the operation, and returns. No persistent state.\n */\n\nimport { NativeImapClient, type NativeFolder } from \"./imap-native.js\";\nimport { FetchedMessage } from \"./fetched-message.js\";\nimport type { ImapClientConfig } from \"./types.js\";\nimport type { TransportFactory } from \"./transport.js\";\nimport type * as proto from \"./imap-protocol.js\";\nimport fs from 'node:fs'; // Debugging\n\n/** Special folder detection result */\n// Later we may need special casing\nexport interface SpecialFolders {\n inbox?: string;\n sent?: string;\n trash?: string;\n drafts?: string;\n spam?: string;\n junk?: string;\n archive?: string;\n}\n\n// We may need some special cases in the future\nconst defaultFolders: SpecialFolders = {\n inbox: \"INBOX\", // Uppercase -- we'll need a reality check\n sent: \"Sent\",\n trash: \"Trash\",\n drafts: \"Drafts\",\n spam: \"_Spam\",\n junk: \"_Spam\",\n archive: \"Archive\"\n}\n\n/**\n * Compatibility IMAP client \u2014 wraps NativeImapClient with the old ImapClient API.\n * Each method creates its own select/operation/close cycle.\n */\nexport class CompatImapClient {\n private native: NativeImapClient;\n\n constructor(config: ImapClientConfig, transportFactory: TransportFactory) {\n this.native = new NativeImapClient(config, transportFactory);\n }\n\n /** Connect and authenticate */\n async connect(): Promise<void> {\n await this.native.connect();\n }\n\n /**\n * Ensure connected (lazy connect). Checks both the native client's connected\n * flag AND the transport's connected state. The transport flag catches cases\n * where the socket died without a close/error event reaching NativeImapClient\n * (common on Android where the bridge may not relay all TCP events).\n */\n private async ensureConnected(): Promise<void> {\n if (!this.native.connected || !this.native.transportConnected) {\n // Force a fresh transport \u2014 the old one may be in a bad state.\n this.native.resetTransport();\n await this.connect();\n }\n }\n\n async logout(): Promise<void> {\n await this.native.logout();\n }\n\n /** Get folder list */\n async getFolderList(): Promise<NativeFolder[]> {\n await this.ensureConnected();\n return this.native.listFolders();\n }\n\n /** Extract special folders from folder list */\n getSpecialFolders(folders: NativeFolder[]): SpecialFolders {\n // Two-pass detection so RFC 6154 \\Drafts / \\Sent / \\Trash / \\Junk /\n // \\Archive flags always win over name-based guesses. Previous single-pass\n // `else if (flag || name)` could tag a stray folder named \"DRAFT\" as the\n // drafts folder on Gmail, beating out [Imap]/Drafts which has the real\n // \\Drafts flag \u2014 Gmail then rejects APPEND to \"DRAFT\" as NONEXISTENT.\n let result: SpecialFolders = {};\n const leafName = (f: NativeFolder): string => {\n const delim = (f as any).delimiter || \".\";\n return (f.path.split(delim).at(-1) ?? f.path).toLowerCase();\n };\n const flagSet = (f: NativeFolder): Set<string> => new Set(f.flags.map(fl => fl.toLowerCase()));\n // const df = 'y:\\\\temp\\\\folders.csv';\n // fs.writeFileSync(df, \"path,flags\\n\" + folders.map(f => `${f.path},\"${f.flags.join(\";\")}\"`).join(\"\\n\"));\n // console.log(`Wrote folder list to ${df}`);\n\n // RFC 6154 flags only \u2014 authoritative if present\n // Note that Dovecot does not have them but we check INBOX for the case\n for (const f of folders) {\n const flags = flagSet(f);\n\n // Debubing \n const dbgignore = ['\\\\haschildren', '\\\\hasnochildren', '\\\\noselect', '\\\\unmarked'];\n const dbgfgall = Array.from(flags);\n const dbgfg = dbgfgall.filter(fl => !dbgignore.includes(fl));\n\n if (flags.has(\"\\\\inbox\") || leafName(f) === \"inbox\")\n result.inbox ??= f.path;\n if (flags.has(\"\\\\sent\"))\n result.sent ??= f.path;\n if (flags.has(\"\\\\trash\"))\n result.trash ??= f.path;\n if (flags.has(\"\\\\drafts\"))\n result.drafts ??= f.path;\n if (flags.has(\"\\\\archive\"))\n result.archive ??= f.path;\n if (flags.has(\"\\\\junk\"))\n result.junk = f.path;\n if (flags.has(\"\\\\spam\"))\n result.spam ??= f.path;\n }\n\n result = { ...defaultFolders, ...result }; // Fill in any missing defaults\n\n // // Pass 2: exact leaf-name fallback for servers that don't advertise flags\n // const sentNames = new Set([\"sent\", \"sent items\", \"sent mail\"]);\n // const trashNames = new Set([\"trash\", \"deleted items\", \"deleted\"]);\n // const draftsNames = new Set([\"drafts\", \"draft\"]);\n // const archiveNames = new Set([\"archive\", \"archives\"]);\n // const junkNames = new Set([\"spam\", \"junk\", \"junk email\", \"junk e-mail\"]);\n // for (const f of folders) {\n // const name = leafName(f);\n // if (sentNames.has(name)) result.sent ??= f.path;\n // if (trashNames.has(name)) result.trash ??= f.path;\n // if (draftsNames.has(name)) result.drafts ??= f.path;\n // if (archiveNames.has(name)) result.archive ??= f.path;\n // if (junkNames.has(name)) {\n // result.junk ??= f.path;\n // result.spam ??= f.path;\n // }\n // }\n return result;\n }\n\n /** Fetch messages since a UID in a mailbox */\n async fetchMessagesSinceUid(mailbox: string, sinceUid: number, options?: { source?: boolean }): Promise<FetchedMessage[]> {\n await this.ensureConnected();\n await this.native.select(mailbox);\n const msgs = await this.native.fetchSinceUid(sinceUid, options);\n await this.native.closeMailbox();\n return msgs.map(m => new FetchedMessage(m));\n }\n\n /** Batch-fetch bodies for many UIDs in one folder on one connection. Streams\n * each body through `onBody` as it arrives. No per-message round trips \u2014\n * one SELECT, one UID FETCH, streaming response. Required by mailx-imap's\n * batch prefetch path. */\n async fetchBodiesBatch(mailbox: string, uids: number[], onBody: (uid: number, source: string) => void): Promise<void> {\n if (uids.length === 0) return;\n await this.ensureConnected();\n await this.native.fetchBodiesBatch(mailbox, uids, onBody);\n }\n\n /** Fetch messages by date range. Optional onChunk callback for incremental processing. */\n async fetchMessageByDate(mailbox: string, start: Date, end?: Date, options?: { source?: boolean }, onChunk?: (msgs: FetchedMessage[]) => void): Promise<FetchedMessage[]> {\n await this.ensureConnected();\n await this.native.select(mailbox);\n const chunkCb = onChunk ? (raw: import(\"./imap-native.js\").NativeFetchedMessage[]) => onChunk(raw.map(m => new FetchedMessage(m))) : undefined;\n const msgs = await this.native.fetchByDate(start, end, options, chunkCb);\n await this.native.closeMailbox();\n return msgs.map(m => new FetchedMessage(m));\n }\n\n /** Fetch the most recent N messages by sequence number \u2014 sidesteps\n * SEARCH SINCE which can take minutes on cold Dovecot mailboxes. Used\n * by mailx-imap's first-sync path so the user sees something fast even\n * on a wide folder tree. The 30-day backfill is a follow-up step. */\n async fetchLatestN(mailbox: string, n: number, options?: { source?: boolean }, onChunk?: (msgs: FetchedMessage[]) => void): Promise<FetchedMessage[]> {\n await this.ensureConnected();\n await this.native.select(mailbox);\n const chunkCb = onChunk ? (raw: import(\"./imap-native.js\").NativeFetchedMessage[]) => onChunk(raw.map(m => new FetchedMessage(m))) : undefined;\n const msgs = await this.native.fetchLatestN(n, options, chunkCb);\n await this.native.closeMailbox();\n return msgs.map(m => new FetchedMessage(m));\n }\n\n /** Fetch a single message by UID */\n async fetchMessageByUid(mailbox: string, uid: number, options?: { source?: boolean }): Promise<FetchedMessage | null> {\n await this.ensureConnected();\n await this.native.select(mailbox);\n const msg = await this.native.fetchMessage(uid, options);\n await this.native.closeMailbox();\n return msg ? new FetchedMessage(msg) : null;\n }\n\n /** Get message count via STATUS (does not require SELECT) */\n async getMessagesCount(mailbox: string): Promise<number> {\n await this.ensureConnected();\n return this.native.getMessageCount(mailbox);\n }\n\n /** Get all UIDs in a mailbox */\n async getUids(mailbox: string): Promise<number[]> {\n await this.ensureConnected();\n await this.native.select(mailbox);\n const uids = await this.native.getUids();\n await this.native.closeMailbox();\n return uids;\n }\n\n /** Get UIDs whose INTERNALDATE is on/after `since`. Bounded version of\n * getUids \u2014 returns only the date window the caller cares about\n * instead of the entire folder. Lets set-diff reconciliation scope\n * itself to \"messages from the last N days\" rather than enumerating\n * every UID in a 134k-message folder. */\n async getUidsSince(mailbox: string, since: Date): Promise<number[]> {\n await this.ensureConnected();\n await this.native.select(mailbox);\n const months = [\"Jan\",\"Feb\",\"Mar\",\"Apr\",\"May\",\"Jun\",\"Jul\",\"Aug\",\"Sep\",\"Oct\",\"Nov\",\"Dec\"];\n const d = `${since.getUTCDate()}-${months[since.getUTCMonth()]}-${since.getUTCFullYear()}`;\n const uids = await this.native.search(`SINCE ${d}`);\n await this.native.closeMailbox();\n return uids;\n }\n\n /** Fetch messages \u2014 supports two calling conventions for compatibility:\n *\n * New: fetchMessages(mailbox, \"100:200\") \u2014 UID range string\n * Old: fetchMessages(mailbox, endSeq, count) \u2014 sequence-number range (iflow compat)\n *\n * The old form computes UID range \"start:end\" from (end - count + 1) : end,\n * matching the legacy iflow/imapflow fetchMessages(mailbox, end, count) API\n * used by the puller. */\n async fetchMessages(mailbox: string, uidRange: string, options?: { source?: boolean }): Promise<FetchedMessage[]>;\n async fetchMessages(mailbox: string, end: number, count: number, options?: { source?: boolean }): Promise<FetchedMessage[]>;\n async fetchMessages(\n mailbox: string,\n rangeOrEnd: string | number,\n countOrOptions?: number | { source?: boolean },\n maybeOptions?: { source?: boolean },\n ): Promise<FetchedMessage[]> {\n let range: string;\n let options: { source?: boolean } | undefined;\n if (typeof rangeOrEnd === \"number\") {\n // Legacy (iflow) calling convention: (mailbox, endSeq, count, options?)\n const end = rangeOrEnd;\n const count = typeof countOrOptions === \"number\" ? countOrOptions : 1;\n const start = Math.max(1, end - count + 1);\n range = `${start}:${end}`;\n options = maybeOptions;\n } else {\n // New calling convention: (mailbox, uidRange, options?)\n range = rangeOrEnd;\n options = typeof countOrOptions === \"object\" ? countOrOptions : undefined;\n }\n await this.ensureConnected();\n await this.native.select(mailbox);\n const msgs = await this.native.fetchMessages(range, options);\n await this.native.closeMailbox();\n return msgs.map(m => new FetchedMessage(m));\n }\n\n /** Search messages in a mailbox */\n async searchMessages(mailbox: string, criteria: any): Promise<number[]> {\n await this.ensureConnected();\n await this.native.select(mailbox);\n // Convert object criteria to IMAP search string\n const parts: string[] = [];\n if (criteria.from) parts.push(`FROM \"${criteria.from}\"`);\n if (criteria.to) parts.push(`TO \"${criteria.to}\"`);\n if (criteria.subject) parts.push(`SUBJECT \"${criteria.subject}\"`);\n if (criteria.body) parts.push(`BODY \"${criteria.body}\"`);\n if (criteria.since) parts.push(`SINCE ${formatDate(criteria.since)}`);\n if (criteria.before) parts.push(`BEFORE ${formatDate(criteria.before)}`);\n const searchStr = parts.length > 0 ? parts.join(\" \") : \"ALL\";\n const uids = await this.native.search(searchStr);\n await this.native.closeMailbox();\n return uids;\n }\n\n /** Search by header value \u2014 returns matching UIDs */\n async searchByHeader(mailbox: string, headerName: string, headerValue: string): Promise<number[]> {\n await this.ensureConnected();\n await this.native.select(mailbox);\n const uids = await this.native.search(`HEADER ${headerName} \"${headerValue}\"`);\n await this.native.closeMailbox();\n return uids;\n }\n\n /** Delete a message by UID */\n async deleteMessageByUid(mailbox: string, uid: number): Promise<void> {\n await this.ensureConnected();\n await this.native.select(mailbox);\n await this.native.deleteMessage(uid);\n await this.native.closeMailbox();\n }\n\n /** Move a message between mailboxes (same server) */\n async moveMessage(msg: any, fromMailbox: string, toMailbox: string): Promise<void> {\n await this.ensureConnected();\n await this.native.select(fromMailbox);\n await this.native.moveMessage(msg.uid, toMailbox);\n await this.native.closeMailbox();\n }\n\n /** Add flags to a message */\n async addFlags(mailbox: string, uid: number, flags: string[]): Promise<void> {\n await this.ensureConnected();\n await this.native.select(mailbox);\n await this.native.addFlags(uid, flags);\n await this.native.closeMailbox();\n }\n\n /** Remove flags from a message */\n async removeFlags(mailbox: string, uid: number, flags: string[]): Promise<void> {\n await this.ensureConnected();\n await this.native.select(mailbox);\n await this.native.removeFlags(uid, flags);\n await this.native.closeMailbox();\n }\n\n /** Create a mailbox */\n async createmailbox(name: string): Promise<void> {\n await this.ensureConnected();\n await this.native.createMailbox(name);\n }\n\n /** Append a message to a mailbox */\n async appendMessage(mailbox: string, message: string | Uint8Array, flags: string[] = []): Promise<number | null> {\n await this.ensureConnected();\n const data = typeof message === \"string\" ? message : new TextDecoder().decode(message);\n return this.native.appendMessage(mailbox, data, flags);\n }\n\n /** Cached CAPABILITY set parsed at connect/login. Callers gate\n * optional features (NOTIFY, QRESYNC, MOVE, ...) on this. */\n getCapabilities(): Set<string> {\n return this.native.getCapabilities();\n }\n\n /** Snapshot of the most recently SELECTed mailbox's info. Callers use this\n * to read `highestModSeq` after any operation that did a SELECT \u2014 useful\n * for seeding the QRESYNC modSeq watermark on the very first sync of a\n * folder (before the QRESYNC path is eligible). */\n getCurrentMailboxInfo(): { uidValidity: number; uidNext: number; exists: number; highestModSeq?: number } {\n const info = this.native.getMailboxInfo?.();\n return info || { uidValidity: 0, uidNext: 0, exists: 0 };\n }\n\n /** RFC 5161 ENABLE \u2014 activates an IMAP extension for the remainder of\n * the session. QRESYNC must be enabled before any SELECT for\n * `* VANISHED` responses + automatic `MODSEQ` to start flowing.\n * Returns the set of extensions the server confirmed are active. */\n async enable(extensions: string[]): Promise<Set<string>> {\n await this.ensureConnected();\n return this.native.enable(extensions);\n }\n\n /** Convenience: enable QRESYNC if the server advertises it. Returns\n * true if QRESYNC is active on the session afterwards. Idempotent \u2014\n * safe to call once per connection at connect time. */\n async enableQresync(): Promise<boolean> {\n const caps = this.getCapabilities();\n if (!caps.has(\"QRESYNC\")) return false;\n const enabled = await this.enable([\"QRESYNC\"]);\n return enabled.has(\"QRESYNC\");\n }\n\n /** Fast resync of a mailbox via RFC 7162 QRESYNC. Caller supplies the\n * `uidValidity` and last-seen `modSeq` from its prior visit; the\n * server replies with `* VANISHED` for UIDs expunged since then and\n * unsolicited `* FETCH` for state changes (flag updates etc.) since\n * then, plus the current `HIGHESTMODSEQ` for the caller to persist\n * as its new watermark.\n *\n * Returns:\n * - `uidValidityChanged`: server's UIDVALIDITY no longer matches; the\n * caller's UID set is stale and MUST be full-resynced.\n * - `vanishedUids`: authoritative deletion list. No client-side diff.\n * - `changedMessages`: state-change FETCH responses since the prior\n * modSeq \u2014 each carries `uid`, `flags`, and `modSeq` (and possibly\n * other FETCH items the caller asked for).\n * - `newHighestModSeq`: persist this for the next resync.\n *\n * Pre-requisite: `enableQresync()` returned true once on the session.\n * If the server doesn't support QRESYNC, fall back to the older\n * `fetchMessagesSinceUid` / set-diff path. */\n async resyncFolder(\n mailbox: string,\n uidValidity: number,\n modSeq: number,\n ): Promise<{\n uidValidityChanged: boolean;\n vanishedUids: number[];\n changedMessages: FetchedMessage[];\n newHighestModSeq: number | undefined;\n exists: number;\n uidNext: number;\n }> {\n await this.ensureConnected();\n const result = await this.native.select(mailbox, { uidValidity, modSeq });\n const changedMessages = result.changedMessages.map(m => new FetchedMessage(m));\n return {\n uidValidityChanged: result.uidValidityChanged,\n vanishedUids: result.vanishedUids,\n changedMessages,\n newHighestModSeq: result.highestModSeq,\n exists: result.exists,\n uidNext: result.uidNext,\n };\n }\n\n /** Watch a mailbox for new messages (IDLE). Optionally engage RFC 5465\n * NOTIFY so the server also pushes STATUS responses for non-selected\n * mailboxes named in `opts.notifySpec` \u2014 `opts.onMailboxStatus` fires\n * for each. Capability check is the caller's responsibility; pass\n * notifySpec only when `getCapabilities().has(\"NOTIFY\")`. */\n async watchMailbox(\n mailbox: string,\n onNew: (count: number) => void,\n opts?: {\n notifySpec?: string;\n onMailboxStatus?: (mailbox: string, data: proto.StatusData) => void;\n onExpunge?: () => void;\n },\n ): Promise<() => Promise<void>> {\n await this.ensureConnected();\n await this.native.select(mailbox);\n if (opts?.onMailboxStatus) this.native.onMailboxStatus = opts.onMailboxStatus;\n if (opts?.notifySpec) await this.native.notify(opts.notifySpec);\n return this.native.startIdle(onNew, opts?.onExpunge);\n }\n\n /** Copy a message to another server (cross-account) */\n async moveMessageToServer(msg: any, fromMailbox: string, targetClient: CompatImapClient, toMailbox: string): Promise<void> {\n // Fetch source, append to target, delete from source\n await this.ensureConnected();\n await this.native.select(fromMailbox);\n const fetched = await this.native.fetchMessage(msg.uid, { source: true });\n if (!fetched || !fetched.source) throw new Error(`Message UID ${msg.uid} not found`);\n\n await targetClient.ensureConnected();\n await targetClient.native.appendMessage(toMailbox, fetched.source, [...fetched.flags]);\n await this.native.deleteMessage(msg.uid);\n await this.native.closeMailbox();\n }\n\n /** Rename a mailbox (via native access) */\n async renameMailbox(from: string, to: string): Promise<void> {\n await this.ensureConnected();\n await this.native.renameMailbox(from, to);\n }\n\n /** Delete a mailbox */\n async deleteMailbox(name: string): Promise<void> {\n await this.ensureConnected();\n await this.native.deleteMailbox(name);\n }\n\n /** Get flags for a UID \u2014 returns string[] for compatibility with old client */\n async getFlags(mailbox: string, uid: number): Promise<string[]> {\n await this.ensureConnected();\n await this.native.select(mailbox);\n const msg = await this.native.fetchMessage(uid, { source: false });\n await this.native.closeMailbox();\n return msg?.flags ? [...msg.flags] : [];\n }\n}\n\nfunction formatDate(d: Date): string {\n const months = [\"Jan\", \"Feb\", \"Mar\", \"Apr\", \"May\", \"Jun\", \"Jul\", \"Aug\", \"Sep\", \"Oct\", \"Nov\", \"Dec\"];\n return `${d.getDate()}-${months[d.getMonth()]}-${d.getFullYear()}`;\n}\n", "/**\n * IMAP web provider \u2014 implements MailProvider using CompatImapClient + BridgeTransport.\n * Used for non-Gmail accounts on Android/WebView where Node.js isn't available.\n *\n * The native shell (MAUI) exposes TCP via window._nativeBridge.tcp.*; we alias it\n * to window.msgapi in initAndroid() because iflow-direct's BridgeTransport expects\n * that global name.\n *\n * Includes automatic retry on broken pipe / connection errors: if an operation fails\n * with a connection-related error, we create a fresh client and retry once.\n */\n\nimport { CompatImapClient, BridgeTransport, type ImapClientConfig, type TransportFactory } from \"@bobfrankston/iflow-direct\";\nimport type { MailProvider, ProviderFolder, ProviderMessage, FetchOptions } from \"./provider-types.js\";\n\n/**\n * Convert a NativeFolder (from iflow-direct) into a ProviderFolder,\n * detecting special-use from the IMAP flags.\n */\nfunction toProviderFolder(f: { path: string; delimiter: string; flags: string[] }, special: Record<string, string | undefined>): ProviderFolder {\n const flagsLower = (f.flags || []).map(x => x.toLowerCase());\n let specialUse = \"\";\n if (f.path === special.inbox || flagsLower.includes(\"\\\\inbox\") || f.path.toUpperCase() === \"INBOX\") specialUse = \"inbox\";\n else if (f.path === special.sent || flagsLower.includes(\"\\\\sent\")) specialUse = \"sent\";\n else if (f.path === special.trash || flagsLower.includes(\"\\\\trash\")) specialUse = \"trash\";\n else if (f.path === special.drafts || flagsLower.includes(\"\\\\drafts\")) specialUse = \"drafts\";\n else if (f.path === special.spam || f.path === special.junk || flagsLower.includes(\"\\\\junk\")) specialUse = \"junk\";\n else if (f.path === special.archive || flagsLower.includes(\"\\\\archive\")) specialUse = \"archive\";\n\n // Leaf name = last path segment after delimiter\n const leaf = f.delimiter ? f.path.split(f.delimiter).pop() || f.path : f.path;\n\n return {\n path: f.path,\n name: leaf,\n delimiter: f.delimiter || \"/\",\n specialUse,\n flags: f.flags || [],\n };\n}\n\nfunction toProviderMessage(m: any): ProviderMessage {\n return {\n uid: m.uid,\n messageId: m.messageId || \"\",\n providerId: \"\",\n date: m.date || null,\n subject: m.subject || \"\",\n from: m.from || [],\n to: m.to || [],\n cc: m.cc || [],\n seen: !!m.seen,\n flagged: !!m.flagged,\n answered: !!m.answered,\n draft: !!m.draft,\n size: m.size || 0,\n source: m.source || \"\",\n };\n}\n\n/** Check if an error is a connection/broken-pipe error worth retrying */\nfunction isConnectionError(e: any): boolean {\n const msg = (e?.message || \"\").toLowerCase();\n return msg.includes(\"broken pipe\") || msg.includes(\"not connected\") ||\n msg.includes(\"connection\") || msg.includes(\"socket\") ||\n msg.includes(\"timeout\") || msg.includes(\"econnreset\") ||\n msg.includes(\"epipe\") || msg.includes(\"closed\");\n}\n\nexport class ImapWebProvider implements MailProvider {\n private client: CompatImapClient;\n private config: ImapClientConfig;\n private transportFactory: TransportFactory;\n private specialFolders: Record<string, string | undefined> = {};\n private folderListCache: ProviderFolder[] | null = null;\n\n constructor(config: ImapClientConfig, transportFactory?: () => any) {\n this.config = config;\n this.transportFactory = transportFactory || (() => new BridgeTransport());\n this.client = new CompatImapClient(config, this.transportFactory);\n }\n\n /** Create a fresh client (after broken pipe / connection error) */\n private reconnect(): void {\n console.log(\"[imap-web] reconnecting after connection error\");\n try { this.client.logout(); } catch { /* ignore */ }\n this.client = new CompatImapClient(this.config, this.transportFactory);\n }\n\n /** Run an operation with one retry on connection error */\n private async withRetry<T>(op: () => Promise<T>, label: string): Promise<T> {\n try {\n return await op();\n } catch (e: any) {\n if (isConnectionError(e)) {\n console.warn(`[imap-web] ${label}: ${e.message} \u2014 reconnecting and retrying`);\n this.reconnect();\n return await op();\n }\n throw e;\n }\n }\n\n async listFolders(): Promise<ProviderFolder[]> {\n const native = await this.withRetry(() => this.client.getFolderList(), \"listFolders\");\n const special = this.client.getSpecialFolders(native);\n this.specialFolders = special as any;\n const result = native.map(f => toProviderFolder(f, this.specialFolders));\n this.folderListCache = result;\n return result;\n }\n\n async fetchSince(folder: string, sinceUid: number, options?: FetchOptions): Promise<ProviderMessage[]> {\n const msgs = await this.withRetry(\n () => this.client.fetchMessagesSinceUid(folder, sinceUid, { source: !!options?.source }),\n `fetchSince(${folder})`\n );\n return msgs.map(toProviderMessage);\n }\n\n async fetchByDate(folder: string, since: Date, before: Date, options?: FetchOptions,\n onChunk?: (msgs: ProviderMessage[]) => void): Promise<ProviderMessage[]> {\n const wrappedChunk = onChunk ? (raw: any[]) => onChunk(raw.map(toProviderMessage)) : undefined;\n const msgs = await this.withRetry(\n () => this.client.fetchMessageByDate(folder, since, before, { source: !!options?.source }, wrappedChunk),\n `fetchByDate(${folder})`\n );\n return msgs.map(toProviderMessage);\n }\n\n async fetchByUids(folder: string, uids: number[], options?: FetchOptions): Promise<ProviderMessage[]> {\n if (!uids.length) return [];\n const range = uids.join(\",\");\n const msgs = await this.withRetry(\n () => this.client.fetchMessages(folder, range, { source: !!options?.source }),\n `fetchByUids(${folder})`\n );\n return msgs.map(toProviderMessage);\n }\n\n async fetchOne(folder: string, uid: number, options?: FetchOptions): Promise<ProviderMessage | null> {\n const msg = await this.withRetry(\n () => this.client.fetchMessageByUid(folder, uid, { source: !!options?.source }),\n `fetchOne(${folder}/${uid})`\n );\n return msg ? toProviderMessage(msg) : null;\n }\n\n async getUids(folder: string): Promise<number[]> {\n return this.withRetry(() => this.client.getUids(folder), `getUids(${folder})`);\n }\n\n async close(): Promise<void> {\n try { await this.client.logout(); } catch { /* ignore */ }\n }\n}\n", "/**\n * Direct SMTP client \u2014 transport-agnostic, mirrors iflow-direct's structure.\n *\n * Implements RFC 5321 (SMTP), RFC 3207 (STARTTLS), RFC 4954 (AUTH),\n * RFC 4616 (PLAIN), RFC 4752 (XOAUTH2 \u2014 Google's variant).\n *\n * No Node.js dependencies. Caller injects an ImapTransport (the iflow-direct\n * transport interface \u2014 same TCP byte-stream abstraction works for SMTP):\n * - Desktop: NodeTransport from @bobfrankston/iflow-node\n * - Browser/WebView: BridgeTransport from @bobfrankston/iflow-direct\n *\n * Only one command at a time per connection (SMTP is synchronous).\n */\n\nimport type { TcpTransport, TransportFactory } from \"@bobfrankston/tcp-transport\";\nimport type {\n SmtpAuth, SmtpClientConfig, SmtpEnvelope,\n SmtpResponse, SmtpSendResult, SmtpRejectedRecipient,\n} from \"./types.js\";\n\nexport class SmtpClient {\n private transport: TcpTransport;\n private config: Required<Omit<SmtpClientConfig, \"auth\" | \"secure\">> & Pick<SmtpClientConfig, \"auth\" | \"secure\">;\n private buffer = \"\";\n private capabilities = new Set<string>();\n private _connected = false;\n private pending: {\n resolve: (resp: SmtpResponse) => void;\n reject: (err: Error) => void;\n timer: ReturnType<typeof setTimeout> | null;\n } | null = null;\n\n constructor(config: SmtpClientConfig, transportFactory: TransportFactory) {\n this.config = {\n host: config.host,\n port: config.port,\n secure: config.secure,\n auth: config.auth,\n localname: config.localname || \"localhost\",\n timeoutMs: config.timeoutMs ?? 30000,\n verbose: config.verbose || false,\n };\n this.transport = transportFactory();\n }\n\n get connected(): boolean { return this._connected; }\n get extensions(): Set<string> { return new Set(this.capabilities); }\n\n /** Connect, EHLO, STARTTLS if needed, AUTH if configured. */\n async connect(): Promise<void> {\n const useTls = this.config.secure ?? (this.config.port === 465);\n\n this.transport.onData((data) => this.handleData(data));\n this.transport.onClose(() => {\n this._connected = false;\n this.failPending(new Error(\"SMTP connection closed\"));\n });\n this.transport.onError((err) => {\n if (this.config.verbose) console.error(` [smtp] transport error: ${err.message}`);\n this.failPending(err);\n });\n\n await this.transport.connect(this.config.host, this.config.port, useTls, this.config.host);\n this._connected = true;\n\n // Server greeting (220 ...)\n const greeting = await this.readResponse();\n if (greeting.code !== 220) throw new Error(`SMTP greeting failed: ${greeting.code} ${greeting.text}`);\n\n await this.ehlo();\n\n // STARTTLS upgrade if not already TLS and server supports it.\n if (!useTls && this.capabilities.has(\"STARTTLS\")) {\n const r = await this.command(\"STARTTLS\");\n if (r.code !== 220) throw new Error(`STARTTLS failed: ${r.code} ${r.text}`);\n await this.transport.upgradeTLS(this.config.host);\n // Re-issue EHLO after TLS \u2014 capabilities can change post-handshake (notably AUTH appears).\n await this.ehlo();\n }\n\n if (this.config.auth) {\n await this.authenticate(this.config.auth);\n }\n }\n\n /** Send one message. Envelope determines MAIL FROM / RCPT TO; raw is the full RFC 2822 message. */\n async sendMail(envelope: SmtpEnvelope, raw: string | Uint8Array): Promise<SmtpSendResult> {\n if (!this._connected) throw new Error(\"SMTP: not connected\");\n if (!envelope.from) throw new Error(\"SMTP: missing sender\");\n if (!envelope.to?.length) throw new Error(\"SMTP: no recipients\");\n\n // MAIL FROM\n const sizeHint = typeof raw === \"string\"\n ? new TextEncoder().encode(raw).byteLength\n : raw.byteLength;\n const sizeExt = this.capabilities.has(\"SIZE\") ? ` SIZE=${sizeHint}` : \"\";\n const mf = await this.command(`MAIL FROM:<${envelope.from}>${sizeExt}`);\n if (mf.code !== 250) throw new Error(`MAIL FROM rejected: ${mf.code} ${mf.text}`);\n\n // RCPT TO \u2014 collect per-recipient errors instead of failing whole send.\n const accepted: string[] = [];\n const rejected: SmtpRejectedRecipient[] = [];\n for (const addr of envelope.to) {\n const r = await this.command(`RCPT TO:<${addr}>`);\n if (r.code === 250 || r.code === 251) {\n accepted.push(addr);\n } else {\n rejected.push({ address: addr, code: r.code, message: r.text });\n if (this.config.verbose) console.error(` [smtp] RCPT rejected ${addr}: ${r.code} ${r.text}`);\n }\n }\n if (accepted.length === 0) {\n // No recipients accepted \u2014 RSET so the connection can be reused for next send.\n try { await this.command(\"RSET\"); } catch { /* ignore */ }\n throw new Error(`SMTP: all recipients rejected: ${rejected.map(r => `${r.address} (${r.code})`).join(\", \")}`);\n }\n\n // DATA \u2014 server says 354, then we stream the body and finish with \\r\\n.\\r\\n\n const data = await this.command(\"DATA\");\n if (data.code !== 354) throw new Error(`DATA rejected: ${data.code} ${data.text}`);\n\n const body = typeof raw === \"string\" ? raw : new TextDecoder().decode(raw);\n const stuffed = dotStuff(body);\n // Ensure body ends with CRLF before terminator\n const term = stuffed.endsWith(\"\\r\\n\") ? \".\\r\\n\" : \"\\r\\n.\\r\\n\";\n // Send body + terminator, then wait for the final 250\n await this.transport.write(stuffed + term);\n const resp = await this.readResponse();\n if (resp.code !== 250) throw new Error(`Message rejected after DATA: ${resp.code} ${resp.text}`);\n\n return { accepted, rejected, response: resp.text };\n }\n\n /** Polite shutdown. */\n async quit(): Promise<void> {\n if (!this._connected) return;\n try {\n // Best-effort; some servers close before sending 221.\n await Promise.race([\n this.command(\"QUIT\"),\n new Promise<void>((resolve) => setTimeout(resolve, 2000)) as Promise<any>,\n ]);\n } catch { /* ignore */ }\n try { this.transport.close(); } catch { /* ignore */ }\n this._connected = false;\n }\n\n /** Hard close \u2014 for tests / aborts. */\n close(): void {\n try { this.transport.close(); } catch { /* ignore */ }\n this._connected = false;\n this.failPending(new Error(\"SMTP closed\"));\n }\n\n // \u2500\u2500 Internals \u2500\u2500\n\n private async ehlo(): Promise<void> {\n const r = await this.command(`EHLO ${this.config.localname}`);\n if (r.code !== 250) {\n // Fallback to HELO for ancient servers without ESMTP.\n const helo = await this.command(`HELO ${this.config.localname}`);\n if (helo.code !== 250) throw new Error(`EHLO/HELO failed: ${r.code} ${r.text}`);\n this.capabilities.clear();\n return;\n }\n this.capabilities.clear();\n // EHLO body is keyword [SP params] per line, first line is greeting text.\n const lines = r.text.split(\"\\n\").slice(1); // skip greeting line\n for (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed) continue;\n const sp = trimmed.indexOf(\" \");\n const keyword = (sp < 0 ? trimmed : trimmed.substring(0, sp)).toUpperCase();\n this.capabilities.add(keyword);\n // AUTH advertises space-separated mechanisms \u2014 record each as `AUTH=<MECH>`.\n if (keyword === \"AUTH\" && sp > 0) {\n for (const mech of trimmed.substring(sp + 1).split(/\\s+/)) {\n if (mech) this.capabilities.add(`AUTH=${mech.toUpperCase()}`);\n }\n }\n }\n }\n\n private async authenticate(auth: SmtpAuth): Promise<void> {\n switch (auth.method) {\n case \"PLAIN\": {\n // RFC 4616: \\0username\\0password, base64-encoded.\n const token = b64utf8(`\\x00${auth.user}\\x00${auth.pass}`);\n const r = await this.command(`AUTH PLAIN ${token}`, /*sensitive*/ true);\n if (r.code !== 235) throw new Error(`AUTH PLAIN failed: ${r.code} ${r.text}`);\n return;\n }\n case \"LOGIN\": {\n // Two-step: server prompts 334 base64(\"Username:\") then 334 base64(\"Password:\").\n const r1 = await this.command(\"AUTH LOGIN\", true);\n if (r1.code !== 334) throw new Error(`AUTH LOGIN start failed: ${r1.code} ${r1.text}`);\n const r2 = await this.command(b64utf8(auth.user), true);\n if (r2.code !== 334) throw new Error(`AUTH LOGIN user rejected: ${r2.code} ${r2.text}`);\n const r3 = await this.command(b64utf8(auth.pass), true);\n if (r3.code !== 235) throw new Error(`AUTH LOGIN failed: ${r3.code} ${r3.text}`);\n return;\n }\n case \"XOAUTH2\": {\n // Google variant: user=<USER>\\x01auth=Bearer <TOKEN>\\x01\\x01\n const blob = b64utf8(`user=${auth.user}\\x01auth=Bearer ${auth.token}\\x01\\x01`);\n const r = await this.command(`AUTH XOAUTH2 ${blob}`, true);\n if (r.code === 235) return;\n // On failure server may emit 334 with a base64 JSON error and wait for an empty\n // continuation line before sending the final tagged 535. Send \"\" to flush, then\n // surface the original error text.\n if (r.code === 334) {\n try { await this.command(\"\"); } catch { /* ignore */ }\n throw new Error(`AUTH XOAUTH2 failed`);\n }\n throw new Error(`AUTH XOAUTH2 failed: ${r.code} ${r.text}`);\n }\n }\n }\n\n /** Send one command and await the next response. Sensitive=true redacts the log line. */\n private command(line: string, sensitive = false): Promise<SmtpResponse> {\n if (this.config.verbose) {\n console.log(` [smtp] > ${sensitive ? \"<redacted>\" : line}`);\n }\n const writeP = this.transport.write(`${line}\\r\\n`);\n const respP = this.readResponse();\n return writeP.then(() => respP);\n }\n\n private readResponse(): Promise<SmtpResponse> {\n return new Promise((resolve, reject) => {\n if (this.pending) {\n reject(new Error(\"SMTP: previous command still pending\"));\n return;\n }\n const timer = setTimeout(() => {\n this.pending = null;\n try { this.transport.close(); } catch { /* ignore */ }\n reject(new Error(`SMTP inactivity timeout (${this.config.timeoutMs}ms)`));\n }, this.config.timeoutMs);\n this.pending = {\n resolve: (resp) => { if (timer) clearTimeout(timer); resolve(resp); },\n reject: (err) => { if (timer) clearTimeout(timer); reject(err); },\n timer,\n };\n // Drain anything that might already be in the buffer (e.g. greeting on connect).\n this.tryParseResponse();\n });\n }\n\n private handleData(data: Uint8Array): void {\n // SMTP responses are 7-bit ASCII per RFC 5321 \u2014 UTF-8 decode is a\n // superset and produces the same characters. Decode each chunk\n // once on receipt; the parser stays string-based since SMTP has no\n // literal-style framing where byte fidelity matters.\n this.buffer += this.utf8Decoder.decode(data);\n this.tryParseResponse();\n }\n private utf8Decoder = new TextDecoder(\"utf-8\");\n\n /** SMTP multi-line replies: each intermediate line \"NNN-TEXT\", final \"NNN TEXT\".\n * Pulls one complete response off the buffer if available and resolves the\n * pending command. */\n private tryParseResponse(): void {\n if (!this.pending) return;\n // Find the boundary \u2014 a line whose 4th char is \" \" (space, not \"-\").\n const lines: string[] = [];\n let consumed = 0;\n let code = 0;\n const buf = this.buffer;\n let pos = 0;\n while (true) {\n const eol = buf.indexOf(\"\\r\\n\", pos);\n if (eol < 0) return; // wait for more data\n const line = buf.substring(pos, eol);\n lines.push(line);\n pos = eol + 2;\n if (line.length >= 4) {\n const codeStr = line.substring(0, 3);\n const sep = line.charAt(3);\n if (/^\\d{3}$/.test(codeStr)) {\n if (sep === \" \" || sep === \"\") {\n code = parseInt(codeStr);\n consumed = pos;\n break;\n } else if (sep !== \"-\") {\n // Malformed \u2014 consume what we have and surface as code 0.\n consumed = pos;\n break;\n }\n } else {\n // Not an SMTP-shaped line \u2014 bail and surface as 0.\n consumed = pos;\n break;\n }\n }\n }\n\n const raw = buf.substring(0, consumed);\n this.buffer = buf.substring(consumed);\n\n const text = lines.map(l => l.length >= 4 ? l.substring(4) : l).join(\"\\n\");\n if (this.config.verbose) {\n console.log(` [smtp] < ${code} ${text.split(\"\\n\").join(\" / \")}`);\n }\n\n const p = this.pending;\n this.pending = null;\n p.resolve({ code, text, raw });\n\n // If more data is buffered, schedule another parse pass \u2014 caller may already\n // have queued the next readResponse.\n if (this.buffer.length > 0) {\n queueMicrotask(() => this.tryParseResponse());\n }\n }\n\n private failPending(err: Error): void {\n if (!this.pending) return;\n const p = this.pending;\n this.pending = null;\n p.reject(err);\n }\n}\n\n/** RFC 5321 \u00A74.5.2 dot-stuffing: any line beginning with \".\" gets a leading \".\"\n * prepended so it doesn't terminate DATA prematurely. Operates on CRLF or LF\n * line endings; output is normalized to CRLF. */\nexport function dotStuff(body: string): string {\n // Normalize CRLF \u2014 leave existing CRLF alone; convert lone LF to CRLF.\n const normalized = body.replace(/\\r?\\n/g, \"\\r\\n\");\n // Insert \".\" before any line starting with \".\"\n return normalized.replace(/(^|\\r\\n)\\./g, \"$1..\");\n}\n\n/** UTF-8-safe base64 (avoids the latin-1 limitation of bare btoa). */\nfunction b64utf8(s: string): string {\n if (typeof Buffer !== \"undefined\" && Buffer.from) {\n return Buffer.from(s, \"utf-8\").toString(\"base64\");\n }\n // Browser path\n const bytes = new TextEncoder().encode(s);\n let bin = \"\";\n for (let i = 0; i < bytes.length; i++) bin += String.fromCharCode(bytes[i]);\n return btoa(bin);\n}\n"],
|
|
5
|
+
"mappings": "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gBAAeA,gBAAe,IAAI,IAAI,EAAE,IAAI;AAC5C,MAAAA,gBAAeA,gBAAe,IAAI,IAAI,EAAE,IAAI;AAC5C,MAAAA,gBAAeA,gBAAe,IAAI,IAAI,EAAE,IAAI;AAC5C,MAAAA,gBAAeA,gBAAe,IAAI,IAAI,EAAE,IAAI;AAC5C,MAAAA,gBAAeA,gBAAe,IAAI,IAAI,EAAE,IAAI;AAC5C,MAAAA,gBAAeA,gBAAe,IAAI,IAAI,EAAE,IAAI;AAC5C,MAAAA,gBAAeA,gBAAe,IAAI,IAAI,EAAE,IAAI;AAC5C,MAAAA,gBAAeA,gBAAe,IAAI,IAAI,EAAE,IAAI;AAC5C,MAAAA,gBAAeA,gBAAe,IAAI,IAAI,EAAE,IAAI;AAC5C,MAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,MAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,MAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,MAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,MAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,MAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,MAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,MAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,MAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,MAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,MAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,MAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,MAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,MAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,MAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,MAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,MAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,MAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,MAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,MAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,MAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,MAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,MAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,MAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,MAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,MAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,MAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,MAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,MAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,MAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,MAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,MAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,MAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,MAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,MAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,MAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,MAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,MAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,MAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,MAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,MAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,MAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,MAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,MAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,MAAAA,gBAAeA,gBAAe,GA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",
|
|
6
6
|
"names": ["initSqlJs", "db", "cloudRead", "cloudWrite", "t", "visit", "IDB_NAME", "db", "STORE_NAME", "value", "CharacterCodes", "ParseOptions", "edit", "createScanner", "findNodeAtLocation", "findNodeAtOffset", "format", "getLocation", "getNodePath", "getNodeValue", "parse", "parseTree", "stripComments", "visit", "ScanError", "SyntaxKind", "ParseErrorCode", "db", "initSqlJs", "db", "db", "bodyStore", "syncManager", "cloudRead", "parseJsonc", "cloudWrite", "format", "applyEdits", "addContactsPreferredEntry", "addContactsDenylistEntry", "tokenProvider", "format", "id", "spaceIdx", "parseAddressList", "db", "bodyStore", "tokenProvider", "token", "tokenProvider", "db"]
|
|
7
7
|
}
|