mailfile 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +203 -0
  3. package/dist/mailfile.cjs +2035 -0
  4. package/dist/mailfile.js +2037 -0
  5. package/dist/mailfile.min.js +30 -0
  6. package/package.json +84 -0
  7. package/src/cfb/index.js +4 -0
  8. package/src/cfb/read.js +221 -0
  9. package/src/cfb/write.js +262 -0
  10. package/src/errors.js +49 -0
  11. package/src/index.js +86 -0
  12. package/src/mapi/bag.js +195 -0
  13. package/src/mapi/index.js +6 -0
  14. package/src/mapi/tags.js +147 -0
  15. package/src/message.js +199 -0
  16. package/src/mime/build.js +100 -0
  17. package/src/mime/encodings.js +188 -0
  18. package/src/mime/headers.js +344 -0
  19. package/src/mime/index.js +12 -0
  20. package/src/mime/parse.js +153 -0
  21. package/src/msg/read.js +178 -0
  22. package/src/msg/write.js +124 -0
  23. package/src/rtf/deencapsulate.js +155 -0
  24. package/src/rtf/index.js +3 -0
  25. package/src/rtf/lzfu.js +67 -0
  26. package/src/util.js +59 -0
  27. package/types/cfb/index.d.ts +2 -0
  28. package/types/cfb/read.d.ts +70 -0
  29. package/types/cfb/write.d.ts +67 -0
  30. package/types/errors.d.ts +36 -0
  31. package/types/index.d.ts +73 -0
  32. package/types/mapi/bag.d.ts +77 -0
  33. package/types/mapi/index.d.ts +2 -0
  34. package/types/mapi/tags.d.ts +137 -0
  35. package/types/message.d.ts +94 -0
  36. package/types/mime/build.d.ts +27 -0
  37. package/types/mime/encodings.d.ts +52 -0
  38. package/types/mime/headers.d.ts +111 -0
  39. package/types/mime/index.d.ts +4 -0
  40. package/types/mime/parse.d.ts +43 -0
  41. package/types/msg/read.d.ts +26 -0
  42. package/types/msg/write.d.ts +6 -0
  43. package/types/rtf/deencapsulate.d.ts +23 -0
  44. package/types/rtf/index.d.ts +2 -0
  45. package/types/rtf/lzfu.d.ts +8 -0
  46. package/types/util.d.ts +25 -0
@@ -0,0 +1,30 @@
1
+ var mailfile=(()=>{var Tt=Object.defineProperty;var ie=Object.getOwnPropertyDescriptor;var oe=Object.getOwnPropertyNames;var se=Object.prototype.hasOwnProperty;var ce=(t,e)=>{for(var n in e)Tt(t,n,{get:e[n],enumerable:!0})},ae=(t,e,n,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of oe(e))!se.call(t,o)&&o!==n&&Tt(t,o,{get:()=>e[o],enumerable:!(r=ie(e,o))||r.enumerable});return t};var le=t=>ae(Tt({},"__esModule",{value:!0}),t);var je={};ce(je,{ErrorCode:()=>U,Headers:()=>b,MailfileError:()=>R,Message:()=>W,convert:()=>Ye,detect:()=>re,version:()=>ye});var B="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";function ct(t){let e="",n,r=t.length;for(n=0;n+2<r;n+=3){let i=t[n]<<16|t[n+1]<<8|t[n+2];e+=B[i>>18&63]+B[i>>12&63]+B[i>>6&63]+B[i&63]}let o=r-n;if(o===1){let i=t[n]<<16;e+=B[i>>18&63]+B[i>>12&63]+"=="}else if(o===2){let i=t[n]<<16|t[n+1]<<8;e+=B[i>>18&63]+B[i>>12&63]+B[i>>6&63]+"="}return e}function at(t){let e=String(t).replace(/[^A-Za-z0-9+/=]/g,""),n=e.indexOf("=");n>=0&&(e=e.slice(0,n));let r=e.length,o=new Uint8Array(Math.floor(r*3/4)),i=0,c=0,u=0;for(let l=0;l<r;l++){let h=B.indexOf(e[l]);h<0||(c=c<<6|h,u+=6,u>=8&&(u-=8,o[i++]=c>>u&255))}return o.subarray(0,i)}function Nt(t,e){let n=[];for(let r=0;r<t.length;r+=e)n.push(t.slice(r,r+e));return n.join(`\r
2
+ `)}var fe=new TextEncoder;function L(t){return fe.encode(t)}function O(t,e){let n=(e||"utf-8").toLowerCase().replace(/^["']|["']$/g,"");(n==="us-ascii"||n==="ascii"||n==="ansi_x3.4-1968")&&(n="utf-8"),(n==="cp1252"||n==="win-1252")&&(n="windows-1252"),n==="utf8"&&(n="utf-8");try{return new TextDecoder(n,{fatal:!1}).decode(t)}catch{try{return new TextDecoder("windows-1252").decode(t)}catch{let r="";for(let o=0;o<t.length;o++)r+=String.fromCharCode(t[o]);return r}}}function lt(t){try{return new TextDecoder("utf-16le").decode(t)}catch{let e="";for(let n=0;n+1<t.length;n+=2)e+=String.fromCharCode(t[n]|t[n+1]<<8);return e}}function wt(t){let e=new Uint8Array(t.length*2);for(let n=0;n<t.length;n++){let r=t.charCodeAt(n);e[n*2]=r&255,e[n*2+1]=r>>8}return e}function ft(t,e){let n=[],r=0;for(;r<t.length;){let o=t[r];if(o==="="){if(t[r+1]==="\r"&&t[r+2]===`
3
+ `){r+=3;continue}if(t[r+1]===`
4
+ `){r+=2;continue}let i=t.substr(r+1,2);if(/^[0-9A-Fa-f]{2}$/.test(i)){n.push(parseInt(i,16)),r+=3;continue}n.push(61),r++}else e&&o==="_"?(n.push(32),r++):(n.push(t.charCodeAt(r)&255),r++)}return new Uint8Array(n)}function Rt(t){let e="",n=0;function r(i){n+i.length>75&&(e+=`=\r
5
+ `,n=0),e+=i,n+=i.length}let o=i=>"="+("0"+i.toString(16).toUpperCase()).slice(-2);for(let i=0;i<t.length;i++){let c=t[i];if(c===13&&t[i+1]===10){e+=`\r
6
+ `,n=0,i++;continue}if(c===10){e+=`\r
7
+ `,n=0;continue}if(c===32||c===9){let u=t[i+1];r(u===13||u===10||u===void 0?o(c):String.fromCharCode(c));continue}c===61||c<32||c>126?r(o(c)):r(String.fromCharCode(c))}return e}function K(t){return!t||t.indexOf("=?")<0?t||"":t.replace(/(\?=)(?:\r?\n)?[ \t]+(=\?)/g,"$1$2").replace(/=\?([^?]+)\?([BbQq])\?([^?]*)\?=/g,(n,r,o,i)=>{try{let c=o.toUpperCase()==="B"?at(i):ft(i,!0);return O(c,r)}catch{return n}})}function ut(t){return/[^\x20-\x7E]/.test(t)}function ht(t){if(!ut(t))return t;let e=[],n="",r=0,o=Array.from(t);for(let i of o){let c=L(i).length;r+c>36&&(e.push(n),n="",r=0),n+=i,r+=c}return n&&e.push(n),e.map(i=>"=?UTF-8?B?"+ct(L(i))+"?=").join(`\r
8
+ `)}function gt(t,e){let n=t+": "+e;if(n.length<=78||/\r\n/.test(n))return n;let r="",o=t+":",i=e.split(" ");for(let c of i)o.length+1+c.length>78&&o!==t+":"?(r+=o+`\r
9
+ `,o=" "+c):o+=(o===" "?"":" ")+c;return r+o}function xt(t,e){return e=(e||"").trim(),t=(t||"").trim(),e?!t||t.toLowerCase()===e.toLowerCase()?e:ut(t)?ht(t)+" <"+e+">":/[()<>@,;:\\".\[\]]/.test(t)?'"'+t.replace(/(["\\])/g,"\\$1")+'" <'+e+">":t+" <"+e+">":t?ht(t):""}function ue(t){let e=[],n="",r=!1,o=0;for(let i=0;i<t.length;i++){let c=t[i];if(c==='"'&&t[i-1]!=="\\"&&(r=!r),!r&&(c==="<"||c==="(")&&o++,!r&&(c===">"||c===")")&&o--,c===","&&!r&&o<=0){e.push(n),n="";continue}n+=c}return n.trim()&&e.push(n),e.map(i=>i.trim()).filter(Boolean)}function he(t){let e=K(String(t).trim()),n=e.match(/^(.*)<([^>]*)>\s*$/);return n?{name:n[1].trim().replace(/^"(.*)"$/,"$1").replace(/\\(["\\])/g,"$1"),email:n[2].trim()}:{name:"",email:e.replace(/^<|>$/g,"").trim()}}function V(t){return t?ue(String(t)).map(he).filter(e=>e.email||e.name):[]}function St(t){let e="",n={},r=0,o=String(t||"");for(;r<o.length&&o[r]!==";";)e+=o[r],r++;let i=o.slice(r+1),c=/\s*([^=\s;]+)\s*=\s*("(?:[^"\\]|\\.)*"|[^;]*)\s*(?:;|$)/g,u={},l;for(;(l=c.exec(i))&&l[1];){let d=l[2].trim();d[0]==='"'&&(d=d.slice(1,-1).replace(/\\(.)/g,"$1")),u[l[1].toLowerCase()]=d}let h={};for(let d of Object.keys(u)){let p=d.match(/^([^*]+)(?:\*(\d+))?(\*)?$/);if(!p){n[d]=u[d];continue}let g=p[1],S=p[2]===void 0?-1:parseInt(p[2],10),E=!!p[3];if(S<0&&!E){g in h||(n[g]=u[d]);continue}h[g]=h[g]||[],h[g].push({idx:S<0?0:S,ext:E,v:u[d]})}for(let d of Object.keys(h)){let p=h[d].sort((E,I)=>E.idx-I.idx),g=null,S="";if(p.forEach((E,I)=>{let _=E.v;if(E.ext){if(I===0&&_.indexOf("'")>=0){let C=_.split("'");g=C[0],_=C.slice(2).join("'")}S+=_}else S+=_}),g||/%[0-9A-Fa-f]{2}/.test(S)){let E=[];for(let I=0;I<S.length;I++)S[I]==="%"&&/^[0-9A-Fa-f]{2}$/.test(S.substr(I+1,2))?(E.push(parseInt(S.substr(I+1,2),16)),I+=2):E.push(S.charCodeAt(I)&255);n[d]=O(new Uint8Array(E),g||"utf-8")}else n[d]=K(S)}return{value:e.trim(),params:n}}function At(t,e){if(!ut(e)&&!/[";\\]/.test(e))return t+'="'+e+'"';if(!ut(e))return t+'="'+e.replace(/(["\\])/g,"\\$1")+'"';let n=L(e),r="";for(let i of n)i>=48&&i<=57||i>=65&&i<=90||i>=97&&i<=122||i===45||i===46||i===95?r+=String.fromCharCode(i):r+="%"+("0"+i.toString(16).toUpperCase()).slice(-2);let o=e.replace(/[^\x20-\x7E]/g,"_").replace(/(["\\])/g,"");return t+'="'+o+'"; '+t+"*=UTF-8''"+r}var b=class t{constructor(e){this.entries=e?e.slice():[]}static parse(e){let n=String(e||"").replace(/\r?\n[ \t]+/g," "),r=[];for(let o of n.split(/\r?\n/)){if(!o.trim())continue;let i=o.indexOf(":");i<0||r.push([o.slice(0,i).trim(),o.slice(i+1).trim()])}return new t(r)}get(e){let n=e.toLowerCase();for(let[r,o]of this.entries)if(r.toLowerCase()===n)return o;return null}getAll(e){let n=e.toLowerCase();return this.entries.filter(([r])=>r.toLowerCase()===n).map(([,r])=>r)}has(e){return this.get(e)!==null}set(e,n){return this.delete(e),this.entries.push([e,n]),this}add(e,n){return this.entries.push([e,n]),this}delete(e){let n=e.toLowerCase();return this.entries=this.entries.filter(([r])=>r.toLowerCase()!==n),this}get raw(){return this.entries.map(([e,n])=>gt(e,n)).join(`\r
10
+ `)}[Symbol.iterator](){return this.entries[Symbol.iterator]()}};function Ft(t){let e=["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],n=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],r=c=>(c<10?"0":"")+c,o=-t.getTimezoneOffset(),i=o>=0?"+":"-";return o=Math.abs(o),e[t.getDay()]+", "+t.getDate()+" "+n[t.getMonth()]+" "+t.getFullYear()+" "+r(t.getHours())+":"+r(t.getMinutes())+":"+r(t.getSeconds())+" "+i+r(Math.floor(o/60))+r(o%60)}function Ut(t){if(!t)return null;let e=new Date(String(t).replace(/\s*\([^)]*\)\s*$/,""));return isNaN(e.getTime())?null:e}function me(t){let e="";for(let n=0;n<24;n++)e+="0123456789abcdef"[Math.floor(Math.random()*16)];return"----=_"+t+"_"+e}function _t(t,e){return["Content-Type: "+t+'; charset="utf-8"',"Content-Transfer-Encoding: quoted-printable","",Rt(L(e))].join(`\r
11
+ `)}function Ot(t){let n=["Content-Type: "+(t.mime||"application/octet-stream")+"; "+At("name",t.filename),"Content-Transfer-Encoding: base64"];return t.cid&&n.push("Content-ID: <"+t.cid+">"),n.push("Content-Disposition: "+(t.inline?"inline":"attachment")+"; "+At("filename",t.filename)),n.push(""),n.push(Nt(ct(t.data),76)),n.join(`\r
12
+ `)}function Ct(t,e,n){let r=me(t.toUpperCase()),o="Content-Type: multipart/"+t+'; boundary="'+r+'"'+(n||""),i="";for(let c of e)i+="--"+r+`\r
13
+ `+c+`\r
14
+ `;return i+="--"+r+`--\r
15
+ `,{head:o,body:i}}function Pt(t){let e=[],n=[];for(let h of t.attachments||[])h.inline&&h.cid?e.push(h):n.push(h);let r=[];t.text&&r.push(_t("text/plain",t.text)),t.html&&r.push(_t("text/html",t.html)),r.length||r.push(_t("text/plain",""));let o;if(r.length>1){let h=Ct("alternative",r);o=h.head+`\r
16
+ \r
17
+ `+h.body}else o=r[0];if(e.length){let h=Ct("related",[o].concat(e.map(Ot)),'; type="text/html"');o=h.head+`\r
18
+ \r
19
+ `+h.body}if(n.length){let h=Ct("mixed",[o].concat(n.map(Ot)));o=h.head+`\r
20
+ \r
21
+ `+h.body}let i=o.indexOf(`\r
22
+ \r
23
+ `),c=o.slice(0,i),u=o.slice(i+4),l=[];for(let[h,d]of t.headers||[])l.push(gt(h,d));l.push("MIME-Version: 1.0");for(let h of c.split(`\r
24
+ `))h&&l.push(h);return L(l.join(`\r
25
+ `)+`\r
26
+ \r
27
+ `+u)}function pe(t){for(let e=0;e+1<t.length;e++){if(t[e]===10&&t[e+1]===10)return{end:e,bodyStart:e+2};if(t[e]===13&&t[e+1]===10&&t[e+2]===13&&t[e+3]===10)return{end:e,bodyStart:e+4}}return{end:t.length,bodyStart:t.length}}function de(t,e){let n=L("--"+e),r=[],o=[];for(let i=0;i<=t.length-n.length;i++){if(t[i]!==45||t[i+1]!==45||i>0&&t[i-1]!==10)continue;let c=!0;for(let p=0;p<n.length;p++)if(t[i+p]!==n[p]){c=!1;break}if(!c)continue;let u=i+n.length,l=t[u]===45&&t[u+1]===45,h=u+(l?2:0);for(;t[h]===32||t[h]===9;)h++;if(!(t[h]===13||t[h]===10||h>=t.length))continue;let d=h;if(t[d]===13&&d++,t[d]===10&&d++,o.push({at:i,contentStart:d,isEnd:l}),l)break}for(let i=0;i<o.length-1;i++){let c=o[i].contentStart,u=o[i+1].at;u>c&&t[u-1]===10&&u--,u>c&&t[u-1]===13&&u--,r.push(t.subarray(c,Math.max(c,u)))}return r}function Ee(t,e){let n=(e||"7bit").trim().toLowerCase();if(n==="base64")return at(O(t,"utf-8"));if(n==="quoted-printable"){let r="";for(let o=0;o<t.length;o++)r+=String.fromCharCode(t[o]);return ft(r,!1)}return t}function Lt(t,e=0){let n=pe(t),r=b.parse(O(t.subarray(0,n.end),"utf-8")),o=t.subarray(n.bodyStart),i=St(r.get("content-type")||"text/plain"),c={headers:r,contentType:(i.value||"text/plain").toLowerCase(),params:i.params,children:[]};if(c.contentType.startsWith("multipart/")&&i.params.boundary&&e<20)for(let u of de(o,i.params.boundary))c.children.push(Lt(u,e+1));else c.content=Ee(o,r.get("content-transfer-encoding"));return c}var Te={"text/plain":"txt","text/html":"html","image/png":"png","image/jpeg":"jpg","image/gif":"gif","application/pdf":"pdf","message/rfc822":"eml"};function ge(t,e){return"attachment-"+(e+1)+"."+(Te[t]||"bin")}function bt(t,e,n){if(t.children.length){for(let h of t.children)bt(h,e,t.contentType);return}let r=St(t.headers.get("content-disposition")||""),o=(r.value||"").toLowerCase(),i=r.params.filename||t.params.name||"",c=(t.headers.get("content-id")||"").replace(/^<|>$/g,"").trim();if((t.contentType==="text/plain"||t.contentType==="text/html")&&o!=="attachment"&&!i){let h=O(t.content,t.params.charset||"utf-8");t.contentType==="text/html"?e.html=e.html||h:e.text=e.text||h;return}e.attachments.push({filename:K(i)||ge(t.contentType,e.attachments.length),mime:t.contentType,data:t.content||new Uint8Array(0),cid:c,inline:o==="inline"||!!c&&n==="multipart/related"})}function Bt(t){let e=Lt(t,0),n={text:"",html:"",attachments:[],headers:e.headers,root:e};return bt(e,n,e.contentType),n}var U={NOT_COMPOUND_FILE:"NOT_COMPOUND_FILE",CORRUPT_CFB:"CORRUPT_CFB",TRUNCATED_STREAM:"TRUNCATED_STREAM",NOT_A_MESSAGE:"NOT_A_MESSAGE",EMPTY_INPUT:"EMPTY_INPUT",UNSUPPORTED:"UNSUPPORTED",MALFORMED:"MALFORMED"},R=class extends Error{constructor(e,n,r){super(n),this.name="MailfileError",this.code=e,r&&r.cause!==void 0&&(this.cause=r.cause)}};var xe=[208,207,17,224,161,177,26,225],rt=4294967295,it=4294967294,Se=4294967295,Ae=4096;function yt(t){if(!t||!t.length)throw new R(U.EMPTY_INPUT,"No data to read");if(t.length<512)throw new R(U.NOT_COMPOUND_FILE,"File is too small to be a compound file");let e=new DataView(t.buffer,t.byteOffset,t.byteLength);for(let f=0;f<8;f++)if(t[f]!==xe[f])throw new R(U.NOT_COMPOUND_FILE,"Not a compound file (bad OLE signature)");let n=1<<e.getUint16(30,!0),r=1<<e.getUint16(32,!0),o=e.getUint32(44,!0),i=e.getUint32(48,!0),c=e.getUint32(56,!0)||Ae,u=e.getUint32(60,!0),l=e.getUint32(68,!0);if(n<128||n>65536)throw new R(U.CORRUPT_CFB,"Invalid sector size");let h=Math.floor((t.length-n)/n),d=f=>(f+1)*n;function p(f){if(f>h||f<0)throw new R(U.CORRUPT_CFB,"Sector reference outside the file (offset "+f+")")}let g=[];for(let f=0;f<109&&g.length<o;f++){let x=e.getUint32(76+f*4,!0);if(x===rt||x===it)break;g.push(x)}let S=l,E=0;for(;S!==it&&S!==rt&&E++<1e5&&g.length<o;){p(S);let f=d(S);for(let x=0;x<n/4-1;x++){let s=e.getUint32(f+x*4,!0);if(s===rt||s===it)break;g.push(s)}S=e.getUint32(f+n-4,!0)}let I=n/4,_=new Uint32Array(g.length*I);for(let f=0;f<g.length;f++){p(g[f]);let x=d(g[f]);for(let s=0;s<I;s++)_[f*I+s]=e.getUint32(x+s*4,!0)}function C(f){let x=[],s=f,m=0;for(;s!==it&&s!==rt&&s!==void 0;){if(m++>_.length+8)throw new R(U.CORRUPT_CFB,"Sector chain loops back on itself");p(s),x.push(s),s=_[s]}return x}function M(f,x){let s=new Uint8Array(f.length*n);for(let m=0;m<f.length;m++)s.set(t.subarray(d(f[m]),d(f[m])+n),m*n);return x==null?s:s.subarray(0,x)}let A=M(C(u)),D=new Uint32Array(A.length>>2),N=new DataView(A.buffer,A.byteOffset,A.byteLength);for(let f=0;f<D.length;f++)D[f]=N.getUint32(f*4,!0);let G=M(C(i)),nt=Math.floor(G.length/128),F=new DataView(G.buffer,G.byteOffset,G.byteLength),P=[];for(let f=0;f<nt;f++){let x=f*128,s=F.getUint16(x+64,!0),m="";for(let T=0;T+1<s-1;T+=2){let w=F.getUint16(x+T,!0);if(w===0)break;m+=String.fromCharCode(w)}P.push({id:f,name:m,type:F.getUint8(x+66),left:F.getUint32(x+68,!0),right:F.getUint32(x+72,!0),child:F.getUint32(x+76,!0),start:F.getUint32(x+116,!0),size:F.getUint32(x+120,!0)+F.getUint32(x+124,!0)*4294967296,children:null})}if(!P.length)throw new R(U.CORRUPT_CFB,"Compound file has no directory");let v=P[0],z=M(C(v.start),v.size);function Q(f){if(!f||f.type!==2||!f.size)return new Uint8Array(0);if(f.size<c){let x=new Uint8Array(f.size),s=f.start,m=0,T=0;for(;s!==it&&s!==rt&&m<f.size;){if(T++>D.length+8)throw new R(U.CORRUPT_CFB,"Mini sector chain loops back on itself");let w=Math.min(r,f.size-m);x.set(z.subarray(s*r,s*r+w),m),m+=w,s=D[s]}return x}return M(C(f.start),f.size)}function k(f,x,s){if(f===Se||f>=P.length||s[f])return;s[f]=1;let m=P[f];k(m.left,x,s),x.push(m),k(m.right,x,s)}function $(f){if(f.children)return f.children;let x=[];k(f.child,x,{});let s=Object.create(null);for(let m=0;m<x.length;m++)s[x[m].name]=x[m];return f.children={list:x,map:s},f.children}return{root:v,entries:P,readStream:Q,childrenOf:$}}var _e=[208,207,17,224,161,177,26,225],mt=4294967295,y=4294967294,Ce=4294967293,Ie=4294967292,J=4294967295,Ht=4096;function Yt(t){return{name:"Root Entry",type:5,clsid:t||null,children:[]}}function pt(t,e,n){let r={name:e,type:1,clsid:n||null,children:[]};return t.children.push(r),r}function q(t,e,n){let r={name:e,type:2,data:n||new Uint8Array(0)};return t.children.push(r),r}function Me(t,e){if(t.length!==e.length)return t.length-e.length;let n=t.toUpperCase(),r=e.toUpperCase();for(let o=0;o<n.length;o++){let i=n.charCodeAt(o)-r.charCodeAt(o);if(i)return i}return 0}function jt(t){let e=[],n=s=>{s.id=e.length,e.push(s)};n(t);function r(s,m,T){if(m>=T)return J;let w=m+T>>1,X=s[w];return X.leftId=r(s,m,w),X.rightId=r(s,w+1,T),X.id}function o(s){if(!s.children||!s.children.length){s.childId=J;return}let m=s.children.slice().sort((T,w)=>Me(T.name,w.name));for(let T=0;T<m.length;T++)n(m[T]);s.childId=r(m,0,m.length);for(let T=0;T<m.length;T++)o(m[T])}o(t);let i=512,c=64,u=i/4,l=[],h=[];for(let s=1;s<e.length;s++){let m=e[s];if(m.type!==2){m.startSector=y,m.streamSize=0;continue}m.streamSize=m.data.length,m.data.length===0?m.startSector=y:m.data.length>=Ht?l.push(m):h.push(m)}let d=0;for(let s of h)s.startSector=d,d+=Math.ceil(s.data.length/c);let p=d*c,g=Math.ceil(p/i),S=new Uint8Array(g*i);for(let s of h)S.set(s.data,s.startSector*c);let E=l.map(s=>Math.ceil(s.data.length/i)),I=E.reduce((s,m)=>s+m,0),_=Math.ceil(d*4/i)||0,C=Math.ceil(e.length/4),M=1,A=0,D=0;for(let s=0;s<64;s++){D=I+g+_+C+M+A;let m=Math.max(1,Math.ceil(D/u)),T=m<=109?0:Math.ceil((m-109)/(u-1));if(m===M&&T===A)break;M=m,A=T}D=I+g+_+C+M+A;let N=0;for(let s=0;s<l.length;s++)l[s].startSector=N,N+=E[s];let G=g?N:y;N+=g;let nt=_?N:y;N+=_;let F=N;N+=C;let P=N;N+=M;let v=A?N:y;N+=A;let z=new Uint32Array(M*u);z.fill(mt);function Q(s,m){for(let T=0;T<m;T++)z[s+T]=T===m-1?y:s+T+1}for(let s=0;s<l.length;s++)Q(l[s].startSector,E[s]);g&&Q(G,g),_&&Q(nt,_),Q(F,C);for(let s=0;s<M;s++)z[P+s]=Ce;for(let s=0;s<A;s++)z[v+s]=Ie;let k=new Uint32Array(_*i/4);k.fill(mt);for(let s of h){let m=Math.ceil(s.data.length/c);for(let T=0;T<m;T++)k[s.startSector+T]=T===m-1?y:s.startSector+T+1}t.startSector=G,t.streamSize=p;let $=new Uint8Array(i*(1+D)),f=new DataView($.buffer);for(let s=0;s<8;s++)$[s]=_e[s];f.setUint16(24,62,!0),f.setUint16(26,3,!0),f.setUint16(28,65534,!0),f.setUint16(30,9,!0),f.setUint16(32,6,!0),f.setUint32(44,M,!0),f.setUint32(48,F,!0),f.setUint32(56,Ht,!0),f.setUint32(60,nt,!0),f.setUint32(64,_,!0),f.setUint32(68,v,!0),f.setUint32(72,A,!0);for(let s=0;s<109;s++)f.setUint32(76+s*4,s<M?P+s:mt,!0);let x=s=>i*(1+s);for(let s of l)$.set(s.data,x(s.startSector));if(g&&$.set(S,x(G)),_)for(let s=0;s<k.length;s++)f.setUint32(x(nt)+s*4,k[s],!0);for(let s=0;s<z.length;s++)f.setUint32(x(P)+s*4,z[s],!0);for(let s=0;s<A;s++){let m=x(v+s);for(let T=0;T<u-1;T++){let w=109+s*(u-1)+T;f.setUint32(m+T*4,w<M?P+w:mt,!0)}f.setUint32(m+i-4,s===A-1?y:v+s+1,!0)}for(let s=0;s<e.length;s++){let m=e[s],T=x(F)+s*128,w=Math.min(m.name.length,31);for(let st=0;st<w;st++)f.setUint16(T+st*2,m.name.charCodeAt(st),!0);f.setUint16(T+64,w*2+2,!0),f.setUint8(T+66,m.type),f.setUint8(T+67,1),f.setUint32(T+68,m.leftId==null?J:m.leftId,!0),f.setUint32(T+72,m.rightId==null?J:m.rightId,!0),f.setUint32(T+76,m.childId==null?J:m.childId,!0),m.clsid&&$.set(m.clsid,T+80),f.setUint32(T+116,m.startSector==null?y:m.startSector,!0);let X=m.streamSize||0;f.setUint32(T+120,X>>>0,!0),f.setUint32(T+124,Math.floor(X/4294967296),!0)}for(let s=e.length;s<C*4;s++){let m=x(F)+s*128;f.setUint32(m+68,J,!0),f.setUint32(m+72,J,!0),f.setUint32(m+76,J,!0),f.setUint32(m+116,y,!0)}return $}var a={SUBJECT:55,NORMALIZED_SUBJECT:3613,BODY:4096,RTF_COMPRESSED:4105,HTML:4115,MESSAGE_CLASS:26,TRANSPORT_HEADERS:125,CLIENT_SUBMIT_TIME:57,DELIVERY_TIME:3590,LAST_MODIFICATION_TIME:12296,CREATION_TIME:12295,INTERNET_MESSAGE_ID:4149,IN_REPLY_TO_ID:4162,INTERNET_REFERENCES:4153,DISPLAY_TO:3588,DISPLAY_CC:3587,DISPLAY_BCC:3586,SENDER_NAME:3098,SENDER_EMAIL:3103,SENDER_ADDRTYPE:3102,SENDER_SMTP:23809,SENT_REP_NAME:66,SENT_REP_EMAIL:101,SENT_REP_ADDRTYPE:100,SENT_REP_SMTP:23810,MESSAGE_FLAGS:3591,HASATTACH:3611,STORE_SUPPORT_MASK:13325,INTERNET_CPID:16350,MESSAGE_CODEPAGE:16381,PRIORITY:38,IMPORTANCE:23,OBJECT_TYPE:4094,DISPLAY_TYPE:14592,ROWID:12288,RECIPIENT_TYPE:3093,DISPLAY_NAME:12289,EMAIL_ADDRESS:12291,ADDRTYPE:12290,SMTP_ADDRESS:14846,ATTACH_METHOD:14085,ATTACH_DATA_BIN:14081,ATTACH_LONG_FILENAME:14087,ATTACH_FILENAME:14084,ATTACH_EXTENSION:14083,ATTACH_MIME_TAG:14094,ATTACH_CONTENT_ID:14098,ATTACH_SIZE:3616,ATTACH_NUM:3617,ATTACH_FLAGS:14100,ATTACHMENT_HIDDEN:32766,RENDERING_POSITION:14091},Y={SHORT:2,LONG:3,FLOAT:4,DOUBLE:5,BOOLEAN:11,I8:20,STRING8:30,UNICODE:31,SYSTIME:64,BINARY:258,OBJECT:13},Z={TO:1,CC:2,BCC:3},Gt={NONE:0,BY_VALUE:1,BY_REFERENCE:2,EMBEDDED_MSG:5},j={TOP_LEVEL:32,EMBEDDED:24,RECIPIENT:8,ATTACHMENT:8},vt=new Uint8Array([11,13,2,0,0,0,0,0,192,0,0,0,0,0,0,70]),zt={20127:"us-ascii",28591:"iso-8859-1",28592:"iso-8859-2",28595:"iso-8859-5",28597:"iso-8859-7",28598:"iso-8859-8",28599:"iso-8859-9",28605:"iso-8859-15",65e3:"utf-7",65001:"utf-8",1250:"windows-1250",1251:"windows-1251",1252:"windows-1252",1253:"windows-1253",1254:"windows-1254",1255:"windows-1255",1256:"windows-1256",1257:"windows-1257",1258:"windows-1258",932:"shift_jis",936:"gbk",949:"euc-kr",950:"big5",874:"windows-874"};function H(t){return("000"+t.toString(16).toUpperCase()).slice(-4)}function It(t){return("0000000"+t.toString(16).toUpperCase()).slice(-8)}function ot(t,e){return"__substg1.0_"+H(t)+H(e)}function kt(t,e){if(!t&&!e)return null;let r=(e*4294967296+t)/1e4-116444736e5;return!isFinite(r)||r<-22089888e5||r>41024448e5?null:new Date(r)}function $t(t){let e=Math.round((t.getTime()+116444736e5)*1e4);return{lo:e%4294967296,hi:Math.floor(e/4294967296)}}var tt=class{constructor(e,n,r){let o=e.childrenOf(n);this.vars=Object.create(null),this.fixed=Object.create(null),this.subStorages=[],this.cfb=e,this.childMap=o.map;for(let u of o.list){let l=/^__substg1\.0_([0-9A-Fa-f]{8})$/.exec(u.name);if(l){u.type===2?this.vars[l[1].toUpperCase()]=e.readStream(u):this.subStorages.push(u);continue}u.type===1&&this.subStorages.push(u)}let i=o.map["__properties_version1.0"];if(i){let u=e.readStream(i),l=new DataView(u.buffer,u.byteOffset,u.byteLength);for(let h=r;h+16<=u.length;h+=16)this.fixed[l.getUint16(h+2,!0)]={type:l.getUint16(h,!0),lo:l.getUint32(h+8,!0),hi:l.getUint32(h+12,!0),i32:l.getInt32(h+8,!0)}}let c=this.fixed[a.INTERNET_CPID]?.i32??this.fixed[a.MESSAGE_CODEPAGE]?.i32??0;this.charset=zt[c]||"windows-1252"}str(e){let n=this.vars[H(e)+"001F"];if(n)return lt(n);let r=this.vars[H(e)+"001E"];return r?O(r,this.charset):""}bin(e){return this.vars[H(e)+"0102"]||null}int(e){return this.fixed[e]?this.fixed[e].i32:null}bool(e){return this.fixed[e]?!!(this.fixed[e].lo&1):null}date(e){return this.fixed[e]?kt(this.fixed[e].lo,this.fixed[e].hi):null}has(e){let n=H(e);return!!(this.fixed[e]||this.vars[n+"001F"]||this.vars[n+"001E"]||this.vars[n+"0102"])}ids(){let e=new Set(Object.keys(this.fixed).map(Number));for(let n of Object.keys(this.vars))e.add(parseInt(n.slice(0,4),16));return[...e].sort((n,r)=>n-r)}storagesMatching(e){return this.subStorages.filter(n=>e.test(n.name)).sort((n,r)=>n.name.localeCompare(r.name))}},et=class{constructor(e,n){this.node=e,this.headerSize=n,this.entries=[]}_entry(e,n,r,o,i){this.entries.push({id:e,type:n,size:r,lo:o||0,hi:i||0})}str(e,n){if(n==null||n==="")return this;let r=wt(String(n));return q(this.node,ot(e,Y.UNICODE),r),this._entry(e,Y.UNICODE,r.length+2),this}bin(e,n){return n?(q(this.node,ot(e,Y.BINARY),n),this._entry(e,Y.BINARY,n.length),this):this}int32(e,n){return n==null?this:(this._entry(e,Y.LONG,null,n>>>0,0),this)}bool(e,n){return this._entry(e,Y.BOOLEAN,null,n?1:0,0),this}time(e,n){if(!n)return this;let r=$t(n);return this._entry(e,Y.SYSTIME,null,r.lo,r.hi),this}finish(e){let n=new Uint8Array(this.headerSize+this.entries.length*16),r=new DataView(n.buffer);e&&e(r);for(let o=0;o<this.entries.length;o++){let i=this.entries[o],c=this.headerSize+o*16;r.setUint16(c,i.type,!0),r.setUint16(c+2,i.id,!0),r.setUint32(c+4,6,!0),i.size!=null?(r.setUint32(c+8,i.size,!0),r.setUint32(c+12,0,!0)):(r.setUint32(c+8,i.lo,!0),r.setUint32(c+12,i.hi,!0))}q(this.node,"__properties_version1.0",n)}};var Mt=`{\\rtf1\\ansi\\mac\\deff0\\deftab720{\\fonttbl;}{\\f0\\fnil \\froman \\fswiss \\fmodern \\fscript \\fdecor MS Sans SerifSymbolArialTimes New RomanCourier{\\colortbl\\red0\\green0\\blue0\r
28
+ \\par \\pard\\plain\\f0\\fs20\\b\\i\\u\\tab\\tx`;function Vt(t){if(!t||t.length<16)return null;let e=new DataView(t.buffer,t.byteOffset,t.byteLength),n=e.getUint32(0,!0),r=e.getUint32(4,!0),o=e.getUint32(8,!0);if(o===1095517517)return t.subarray(16,Math.min(t.length,16+r));if(o!==1967544908)return null;let i=new Uint8Array(4096);for(let p=0;p<Mt.length;p++)i[p]=Mt.charCodeAt(p)&255;let c=Mt.length,u=new Uint8Array(r),l=0,h=16,d=Math.min(t.length,n+4);for(;h<d&&l<r;){let p=t[h++];for(let g=0;g<8&&h<d&&l<r;g++)if(p&1<<g){if(h+1>=d)return u.subarray(0,l);let S=t[h++],E=t[h++],I=S<<4|E>>4,_=(E&15)+2;if(I===c%4096)return u.subarray(0,l);for(let C=0;C<_&&l<r;C++){let M=i[(I+C)%4096];u[l++]=M,i[c%4096]=M,c++}}else{let S=t[h++];u[l++]=S,i[c%4096]=S,c++}}return u.subarray(0,l)}var De={"&":"&amp;","<":"&lt;",">":"&gt;"},Jt=t=>t.replace(/[&<>]/g,e=>De[e]),qt={lquote:"&lsquo;",rquote:"&rsquo;",ldblquote:"&ldquo;",rdblquote:"&rdquo;",emdash:"&mdash;",endash:"&ndash;",bullet:"&bull;",nbsp:"&nbsp;"},Ne=new Set(["fonttbl","colortbl","stylesheet","info","pntext","generator"]);function we(t){return/\\from(html|text)1?/.test(t.slice(0,4096))}function Re(t,e){let n=[],r=[],o=0,i=t.length,c=!1,u=0,l=0,h=0,d=!1,p=[],g=/\\fromtext/.test(t.slice(0,4096));function S(_){h||c&&!u||n.push(_)}function E(){if(!p.length)return;let _=e(new Uint8Array(p));p=[],S(u?_:Jt(_))}for(;o<i;){let _=t[o];if(_==="\\"){let C=t[o+1];if(C==="\\"||C==="{"||C==="}"){p.push(C.charCodeAt(0)),o+=2;continue}if(C==="'"){p.push(parseInt(t.substr(o+2,2),16)||0),o+=4;continue}if(C==="*"){o+=2,d=!0;continue}let M=/^\\([a-zA-Z]+)(-?\d+)? ?/.exec(t.slice(o));if(!M){o+=2;continue}let A=M[1],D=M[2]===void 0?null:parseInt(M[2],10);if(o+=M[0].length,E(),A==="htmltag"){d=!1,u=l;continue}if(A==="htmlrtf"){c=D!==0;continue}if(A==="mhtmltag"){h=l,d=!1;continue}if(d){h=l,d=!1;continue}if(A==="u"&&D!==null){if(!c||u){let N=D<0?D+65536:D;S(u?String.fromCharCode(N):Jt(String.fromCharCode(N)))}t[o]==="?"&&o++;continue}if(A==="par"||A==="line"){g&&S(`
29
+ `);continue}if(A==="tab"){S(" ");continue}if(qt[A]){S(qt[A]);continue}if(Ne.has(A)){h=l;continue}continue}if(_==="{"){E(),l++,r.push({suppress:c,inHtmlTag:u}),o++;continue}if(_==="}"){E(),h&&l===h&&(h=0),u&&l===u&&(u=0),l--;let C=r.pop();C&&(c=C.suppress),d=!1,o++;continue}if(_==="\r"||_===`
30
+ `){o++;continue}p.push(t.charCodeAt(o)&255),o++}E();let I=n.join("");return g?'<html><body><pre style="font-family:inherit;white-space:pre-wrap">'+I+"</pre></body></html>":I}function Zt(t,e){if(!t||!t.length)return null;let n="";for(let r=0;r<t.length;r++)n+=String.fromCharCode(t[r]);if(!we(n))return null;try{let r=Re(n,e);return r&&r.trim()?r:null}catch{return null}}var Fe={pdf:"application/pdf",png:"image/png",jpg:"image/jpeg",jpeg:"image/jpeg",gif:"image/gif",bmp:"image/bmp",webp:"image/webp",svg:"image/svg+xml",txt:"text/plain",csv:"text/csv",html:"text/html",htm:"text/html",xml:"application/xml",json:"application/json",zip:"application/zip",doc:"application/msword",dot:"application/msword",docx:"application/vnd.openxmlformats-officedocument.wordprocessingml.document",xls:"application/vnd.ms-excel",xlsx:"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",ppt:"application/vnd.ms-powerpoint",pptx:"application/vnd.openxmlformats-officedocument.presentationml.presentation",eml:"message/rfc822",msg:"application/vnd.ms-outlook",ics:"text/calendar",rtf:"application/rtf",mp3:"audio/mpeg",mp4:"video/mp4"};function dt(t){let e=/\.([A-Za-z0-9]+)$/.exec(t||"");return e&&Fe[e[1].toLowerCase()]||"application/octet-stream"}function Wt(t){return String(t||"file").replace(/[\\/:*?"<>|\r\n\t]+/g,"_").replace(/^\.+/,"").slice(0,120)||"file"}function Qt(t){let e=/^(.*?)(\.[A-Za-z0-9]{1,3})?$/.exec(t||"file");return((e[1]||"file").replace(/[^A-Za-z0-9_-]/g,"").slice(0,8)||"file")+(e[2]||"")}function Xt(t,e){return(String(t).replace(/\.[^.\\/]+$/,"")||"message")+e}function Ue(t,e){let n="";for(let o=0;o<Math.min(t.length,2048);o++)n+=String.fromCharCode(t[o]);let r=/charset\s*=\s*["']?\s*([\w-]+)/i.exec(n);return r?r[1]:e}function Et(t,e,n,r,o){let i=t.str(e),c=t.str(o);if(!c){let u=(t.str(r)||"").toUpperCase(),l=t.str(n);(u==="SMTP"||l&&l.indexOf("@")>0&&l.indexOf("/")<0)&&(c=l)}return{name:i,email:c}}function Kt(t,e,n,r,o){let i=new tt(t,e,n),c={messageClass:i.str(a.MESSAGE_CLASS),subject:i.str(a.SUBJECT)||i.str(a.NORMALIZED_SUBJECT),messageId:i.str(a.INTERNET_MESSAGE_ID),inReplyTo:i.str(a.IN_REPLY_TO_ID),references:i.str(a.INTERNET_REFERENCES),date:i.date(a.CLIENT_SUBMIT_TIME)||i.date(a.DELIVERY_TIME)||i.date(a.LAST_MODIFICATION_TIME)||null,importance:i.int(a.IMPORTANCE),text:i.str(a.BODY),html:"",to:[],cc:[],bcc:[],attachments:[],headers:b.parse(i.str(a.TRANSPORT_HEADERS)),props:i},u=Et(i,a.SENT_REP_NAME,a.SENT_REP_EMAIL,a.SENT_REP_ADDRTYPE,a.SENT_REP_SMTP);if(!u.email&&!u.name)u=Et(i,a.SENDER_NAME,a.SENDER_EMAIL,a.SENDER_ADDRTYPE,a.SENDER_SMTP);else if(!u.email){let h=Et(i,a.SENDER_NAME,a.SENDER_EMAIL,a.SENDER_ADDRTYPE,a.SENDER_SMTP);h.email&&(u.email=h.email)}c.from=u;let l=i.bin(a.HTML);if(l&&l.length?c.html=O(l,Ue(l,i.charset)):i.vars[H(a.HTML)+"001F"]&&(c.html=lt(i.vars[H(a.HTML)+"001F"])),!c.html){let h=i.bin(a.RTF_COMPRESSED);if(h){let d=Vt(h);if(d){let p=i.charset,g=Zt(d,S=>O(S,p));g&&(c.html=g)}}}for(let h of i.storagesMatching(/^__recip_version1\.0_/)){let d=new tt(t,h,j.RECIPIENT),p=Et(d,a.DISPLAY_NAME,a.EMAIL_ADDRESS,a.ADDRTYPE,a.SMTP_ADDRESS);if(!p.email&&!p.name)continue;let g=d.int(a.RECIPIENT_TYPE);g===Z.CC?c.cc.push(p):g===Z.BCC?c.bcc.push(p):c.to.push(p)}!c.to.length&&!c.cc.length&&(c.to=V(i.str(a.DISPLAY_TO)),c.cc=V(i.str(a.DISPLAY_CC)));for(let h of i.storagesMatching(/^__attach_version1\.0_/)){let d=new tt(t,h,j.ATTACHMENT),p=d.int(a.ATTACH_METHOD),g=d.str(a.ATTACH_LONG_FILENAME)||d.str(a.ATTACH_FILENAME),S=d.str(a.ATTACH_CONTENT_ID),E=d.str(a.ATTACH_MIME_TAG),I=d.int(a.ATTACH_FLAGS)||0,_=d.bool(a.ATTACHMENT_HIDDEN);if(p===Gt.EMBEDDED_MSG){let A=d.childMap[ot(a.ATTACH_DATA_BIN,Y.OBJECT)];if(A&&o<10)try{let D=Kt(t,A,j.EMBEDDED,r,o+1);c.attachments.push({filename:Wt(g||D.subject||"message")+".eml",mime:"message/rfc822",embedded:D,cid:S,inline:!1})}catch{}continue}let C=g||"attachment"+(c.attachments.length+1)+(d.str(a.ATTACH_EXTENSION)||".bin"),M={filename:C,mime:E||dt(C),cid:S,inline:!!S&&((I&4)!==0||_===!0||!!c.html&&c.html.indexOf("cid:"+S)>=0)};if(r.lazy){let A=null;if(Object.defineProperty(M,"data",{enumerable:!0,configurable:!0,get(){return A||(A=d.bin(a.ATTACH_DATA_BIN)||new Uint8Array(0)),A}}),!d.has(a.ATTACH_DATA_BIN))continue}else{let A=d.bin(a.ATTACH_DATA_BIN);if(!A)continue;M.data=A}c.attachments.push(M)}return c}function te(t,e={}){let n=yt(t);return Kt(n,n.root,j.TOP_LEVEL,e,0)}var Oe=1,Pe=262144,ee=65001,Le=4,Dt=t=>t.name||t.email;function ne(t){let e=Yt(vt),n=pt(e,"__nameid_version1.0");q(n,"__substg1.0_00020102",new Uint8Array(0)),q(n,"__substg1.0_00030102",new Uint8Array(0)),q(n,"__substg1.0_00040102",new Uint8Array(0));let r=t.to||[],o=t.cc||[],i=t.bcc||[],c=t.attachments||[],u=t.from||{name:"",email:""},l=new et(e,j.TOP_LEVEL);l.str(a.MESSAGE_CLASS,t.messageClass||"IPM.Note"),l.str(a.SUBJECT,t.subject||""),l.str(a.NORMALIZED_SUBJECT,(t.subject||"").replace(/^\s*(re|fw|fwd)\s*:\s*/i,"")),l.str(a.BODY,t.text||""),t.html&&l.bin(a.HTML,L(t.html)),t.headersRaw&&l.str(a.TRANSPORT_HEADERS,t.headersRaw),l.str(a.INTERNET_MESSAGE_ID,t.messageId||""),l.str(a.IN_REPLY_TO_ID,t.inReplyTo||""),l.str(a.INTERNET_REFERENCES,t.references||"");let h=u.email?"SMTP":"";l.str(a.SENDER_NAME,u.name||u.email||""),l.str(a.SENDER_EMAIL,u.email||""),l.str(a.SENDER_ADDRTYPE,h),l.str(a.SENDER_SMTP,u.email||""),l.str(a.SENT_REP_NAME,u.name||u.email||""),l.str(a.SENT_REP_EMAIL,u.email||""),l.str(a.SENT_REP_ADDRTYPE,h),l.str(a.SENT_REP_SMTP,u.email||""),l.str(a.DISPLAY_TO,r.map(Dt).join("; ")),l.str(a.DISPLAY_CC,o.map(Dt).join("; ")),l.str(a.DISPLAY_BCC,i.map(Dt).join("; ")),l.time(a.CLIENT_SUBMIT_TIME,t.date),l.time(a.DELIVERY_TIME,t.date),l.time(a.CREATION_TIME,t.date||new Date),l.time(a.LAST_MODIFICATION_TIME,new Date),l.int32(a.MESSAGE_FLAGS,Oe),l.int32(a.STORE_SUPPORT_MASK,Pe),l.int32(a.INTERNET_CPID,ee),l.int32(a.MESSAGE_CODEPAGE,ee),t.importance!=null&&l.int32(a.IMPORTANCE,t.importance),l.bool(a.HASATTACH,c.length>0);let d=[...r.map(p=>({a:p,t:Z.TO})),...o.map(p=>({a:p,t:Z.CC})),...i.map(p=>({a:p,t:Z.BCC}))];return d.forEach((p,g)=>{let S=pt(e,"__recip_version1.0_#"+It(g)),E=new et(S,j.RECIPIENT);E.int32(a.ROWID,g),E.int32(a.RECIPIENT_TYPE,p.t),E.int32(a.OBJECT_TYPE,6),E.int32(a.DISPLAY_TYPE,0),E.str(a.DISPLAY_NAME,p.a.name||p.a.email),E.str(a.EMAIL_ADDRESS,p.a.email),E.str(a.SMTP_ADDRESS,p.a.email),E.str(a.ADDRTYPE,"SMTP"),E.finish()}),c.forEach((p,g)=>{let S=pt(e,"__attach_version1.0_#"+It(g)),E=new et(S,j.ATTACHMENT);E.int32(a.ATTACH_NUM,g),E.int32(a.ATTACH_METHOD,1),E.int32(a.OBJECT_TYPE,7),E.int32(a.ATTACH_SIZE,p.data.length),E.int32(a.RENDERING_POSITION,-1),E.bin(a.ATTACH_DATA_BIN,p.data),E.str(a.ATTACH_LONG_FILENAME,p.filename),E.str(a.ATTACH_FILENAME,Qt(p.filename));let I=/\.[A-Za-z0-9]+$/.exec(p.filename);I&&E.str(a.ATTACH_EXTENSION,I[0]),E.str(a.ATTACH_MIME_TAG,p.mime||dt(p.filename)),p.cid&&(E.str(a.ATTACH_CONTENT_ID,p.cid),p.inline&&(E.int32(a.ATTACH_FLAGS,Le),E.bool(a.ATTACHMENT_HIDDEN,!0))),E.finish()}),l.finish(p=>{p.setUint32(8,d.length,!0),p.setUint32(12,c.length,!0),p.setUint32(16,d.length,!0),p.setUint32(20,c.length,!0)}),jt(e)}var be=new Set(["mime-version","content-type","content-transfer-encoding","content-disposition","content-id","content-description","content-language","content-location"]),Be={low:0,normal:1,high:2},W=class t{constructor(e={}){this.subject=e.subject||"",this.from=e.from||{name:"",email:""},this.to=e.to||[],this.cc=e.cc||[],this.bcc=e.bcc||[],this.date=e.date||null,this.messageId=e.messageId||"",this.inReplyTo=e.inReplyTo||"",this.references=e.references||"",this.importance=e.importance==null?null:e.importance,this.messageClass=e.messageClass||"IPM.Note",this.text=e.text||"",this.html=e.html||"",this.attachments=e.attachments||[],this.headers=e.headers instanceof b?e.headers:new b(e.headers||[]),this.props=e.props||null}static fromMsg(e,n={}){let r=te(e,n);return r.attachments=r.attachments.map(o=>{if(!o.embedded)return o;let{embedded:i,...c}=o;return{...c,data:new t(i).toEml()}}),new t(r)}static fromEml(e){let n=Bt(e),r=n.headers;return new t({subject:K(r.get("subject")||""),from:V(r.get("from")||"")[0]||{name:"",email:""},to:V(r.get("to")||""),cc:V(r.get("cc")||""),bcc:V(r.get("bcc")||""),date:Ut(r.get("date")),messageId:r.get("message-id")||"",inReplyTo:r.get("in-reply-to")||"",references:r.get("references")||"",importance:Be[(r.get("importance")||"").toLowerCase()]??null,text:n.text,html:n.html,attachments:n.attachments,headers:r})}toEml(){let e=[],n=new Set;for(let[i,c]of this.headers)be.has(i.toLowerCase())||(e.push([i,c]),n.add(i.toLowerCase()));let r=(i,c)=>{!c||n.has(i.toLowerCase())||(e.push([i,c]),n.add(i.toLowerCase()))},o=i=>i.map(c=>xt(c.name,c.email)).filter(Boolean).join(", ");return this.date&&r("Date",Ft(this.date)),(this.from.email||this.from.name)&&r("From",xt(this.from.name,this.from.email)),this.to.length&&r("To",o(this.to)),this.cc.length&&r("Cc",o(this.cc)),this.bcc.length&&r("Bcc",o(this.bcc)),n.has("subject")||r("Subject",ht(this.subject||"")||" "),r("Message-ID",this.messageId),r("In-Reply-To",this.inReplyTo),r("References",this.references),Pt({headers:e,text:this.text,html:this.html,attachments:this.attachments})}toMsg(){return ne({messageClass:this.messageClass,subject:this.subject,from:this.from,to:this.to,cc:this.cc,bcc:this.bcc,date:this.date,messageId:this.messageId,inReplyTo:this.inReplyTo,references:this.references,importance:this.importance,text:this.text,html:this.html,attachments:this.attachments,headersRaw:this.headers.entries.length?this.headers.raw:""})}};var ye="0.1.0",He=[208,207,17,224,161,177,26,225];function re(t,e){if(t&&t.length>=8){let r=!0;for(let o=0;o<8;o++)if(t[o]!==He[o]){r=!1;break}if(r)return"msg"}let n=(/\.([^.]+)$/.exec(e||"")||[])[1];return n&&n.toLowerCase()==="msg"?"msg":"eml"}function Ye(t,e={}){if(!t||!t.length)throw new R(U.EMPTY_INPUT,"File is empty");let n=e.from||re(t,e.filename),r=e.to||(n==="msg"?"eml":"msg"),o=n==="msg"?W.fromMsg(t,{lazy:e.lazy}):W.fromEml(t);return{data:r==="msg"?o.toMsg():o.toEml(),format:r,sourceFormat:n,mime:r==="msg"?"application/vnd.ms-outlook":"message/rfc822",filename:e.filename?Xt(e.filename,"."+r):void 0,message:o}}return le(je);})();
package/package.json ADDED
@@ -0,0 +1,84 @@
1
+ {
2
+ "name": "mailfile",
3
+ "version": "0.1.0",
4
+ "description": "Read and write Outlook .msg and RFC 5322 .eml files. Zero dependencies, runs in browsers, Node, Deno, Bun and workers.",
5
+ "type": "module",
6
+ "license": "MIT",
7
+ "author": "Scott McKellar",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/smck83/mailfile.git"
11
+ },
12
+ "homepage": "https://github.com/smck83/mailfile#readme",
13
+ "bugs": {
14
+ "url": "https://github.com/smck83/mailfile/issues"
15
+ },
16
+ "sideEffects": false,
17
+ "engines": {
18
+ "node": ">=18"
19
+ },
20
+ "main": "./dist/mailfile.cjs",
21
+ "module": "./src/index.js",
22
+ "types": "./types/index.d.ts",
23
+ "unpkg": "./dist/mailfile.min.js",
24
+ "jsdelivr": "./dist/mailfile.min.js",
25
+ "exports": {
26
+ ".": {
27
+ "types": "./types/index.d.ts",
28
+ "require": "./dist/mailfile.cjs",
29
+ "default": "./src/index.js"
30
+ },
31
+ "./cfb": {
32
+ "types": "./types/cfb/index.d.ts",
33
+ "default": "./src/cfb/index.js"
34
+ },
35
+ "./mime": {
36
+ "types": "./types/mime/index.d.ts",
37
+ "default": "./src/mime/index.js"
38
+ },
39
+ "./mapi": {
40
+ "types": "./types/mapi/index.d.ts",
41
+ "default": "./src/mapi/index.js"
42
+ },
43
+ "./rtf": {
44
+ "types": "./types/rtf/index.d.ts",
45
+ "default": "./src/rtf/index.js"
46
+ },
47
+ "./package.json": "./package.json"
48
+ },
49
+ "files": [
50
+ "src",
51
+ "dist",
52
+ "types",
53
+ "README.md",
54
+ "LICENSE"
55
+ ],
56
+ "scripts": {
57
+ "build": "node scripts/build.js",
58
+ "types": "tsc -p tsconfig.json",
59
+ "test": "node --test",
60
+ "corpus": "node scripts/corpus.js",
61
+ "prepublishOnly": "npm run build && npm run types && npm test"
62
+ },
63
+ "keywords": [
64
+ "msg",
65
+ "eml",
66
+ "outlook",
67
+ "email",
68
+ "mime",
69
+ "rfc5322",
70
+ "mapi",
71
+ "cfb",
72
+ "ole2",
73
+ "compound-file",
74
+ "rtf",
75
+ "lzfu",
76
+ "converter",
77
+ "browser"
78
+ ],
79
+ "devDependencies": {
80
+ "@kenjiuno/msgreader": "^1.22.0",
81
+ "esbuild": "^0.24.0",
82
+ "typescript": "^5.6.3"
83
+ }
84
+ }
@@ -0,0 +1,4 @@
1
+ /** Compound File Binary (OLE2) reader and writer — MS-CFB.
2
+ * Usable on its own for any OLE2 container, not just .msg. */
3
+ export { read } from './read.js';
4
+ export { write, newRoot, addStorage, addStream } from './write.js';
@@ -0,0 +1,221 @@
1
+ /**
2
+ * Compound File Binary (OLE2 / CFBF) reader — MS-CFB.
3
+ * Used by .msg, but also by legacy .doc/.xls/.ppt, .msi and Thumbs.db.
4
+ */
5
+ import { MailfileError, ErrorCode } from '../errors.js';
6
+
7
+ const SIG = [0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1];
8
+ const FREESECT = 0xFFFFFFFF;
9
+ const ENDOFCHAIN = 0xFFFFFFFE;
10
+ const NOSTREAM = 0xFFFFFFFF;
11
+ const MINI_CUTOFF = 4096;
12
+
13
+ /**
14
+ * @typedef {object} DirEntry
15
+ * @property {number} id
16
+ * @property {string} name
17
+ * @property {number} type 1 = storage, 2 = stream, 5 = root
18
+ * @property {number} start First sector of the stream.
19
+ * @property {number} size Stream length in bytes.
20
+ * @property {number} left Left sibling id in the storage's red-black tree.
21
+ * @property {number} right Right sibling id.
22
+ * @property {number} child First child id, for storages.
23
+ * @property {{list: DirEntry[], map: Record<string, DirEntry>}|null} children
24
+ * Memoised child index, filled in by `childrenOf`.
25
+ */
26
+
27
+ /**
28
+ * @typedef {object} CfbFile
29
+ * @property {DirEntry} root
30
+ * @property {DirEntry[]} entries
31
+ * @property {(entry: DirEntry) => Uint8Array} readStream
32
+ * @property {(entry: DirEntry) => {list: DirEntry[], map: Record<string, DirEntry>}} childrenOf
33
+ */
34
+
35
+ /**
36
+ * Parse a compound file.
37
+ * @param {Uint8Array} bytes
38
+ * @returns {CfbFile}
39
+ */
40
+ export function read(bytes) {
41
+ if (!bytes || !bytes.length) {
42
+ throw new MailfileError(ErrorCode.EMPTY_INPUT, 'No data to read');
43
+ }
44
+ if (bytes.length < 512) {
45
+ throw new MailfileError(ErrorCode.NOT_COMPOUND_FILE,
46
+ 'File is too small to be a compound file');
47
+ }
48
+ const dv = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
49
+ for (let i = 0; i < 8; i++) {
50
+ if (bytes[i] !== SIG[i]) {
51
+ throw new MailfileError(ErrorCode.NOT_COMPOUND_FILE,
52
+ 'Not a compound file (bad OLE signature)');
53
+ }
54
+ }
55
+
56
+ const sectorSize = 1 << dv.getUint16(30, true);
57
+ const miniSectorSize = 1 << dv.getUint16(32, true);
58
+ const numFatSectors = dv.getUint32(44, true);
59
+ const firstDirSector = dv.getUint32(48, true);
60
+ const miniCutoff = dv.getUint32(56, true) || MINI_CUTOFF;
61
+ const firstMiniFat = dv.getUint32(60, true);
62
+ const firstDifat = dv.getUint32(68, true);
63
+
64
+ if (sectorSize < 128 || sectorSize > 65536) {
65
+ throw new MailfileError(ErrorCode.CORRUPT_CFB, 'Invalid sector size');
66
+ }
67
+
68
+ const maxSector = Math.floor((bytes.length - sectorSize) / sectorSize);
69
+ const sectorOffset = (s) => (s + 1) * sectorSize;
70
+ function checkSector(s) {
71
+ if (s > maxSector || s < 0) {
72
+ throw new MailfileError(ErrorCode.CORRUPT_CFB,
73
+ 'Sector reference outside the file (offset ' + s + ')');
74
+ }
75
+ }
76
+
77
+ // DIFAT -> list of FAT sector numbers
78
+ const fatSectors = [];
79
+ for (let d = 0; d < 109 && fatSectors.length < numFatSectors; d++) {
80
+ const v = dv.getUint32(76 + d * 4, true);
81
+ if (v === FREESECT || v === ENDOFCHAIN) break;
82
+ fatSectors.push(v);
83
+ }
84
+ let difSec = firstDifat;
85
+ let guard = 0;
86
+ while (difSec !== ENDOFCHAIN && difSec !== FREESECT &&
87
+ guard++ < 100000 && fatSectors.length < numFatSectors) {
88
+ checkSector(difSec);
89
+ const base = sectorOffset(difSec);
90
+ for (let k = 0; k < (sectorSize / 4) - 1; k++) {
91
+ const fv = dv.getUint32(base + k * 4, true);
92
+ if (fv === FREESECT || fv === ENDOFCHAIN) break;
93
+ fatSectors.push(fv);
94
+ }
95
+ difSec = dv.getUint32(base + sectorSize - 4, true);
96
+ }
97
+
98
+ // FAT
99
+ const perSector = sectorSize / 4;
100
+ const fat = new Uint32Array(fatSectors.length * perSector);
101
+ for (let f = 0; f < fatSectors.length; f++) {
102
+ checkSector(fatSectors[f]);
103
+ const off = sectorOffset(fatSectors[f]);
104
+ for (let j = 0; j < perSector; j++) {
105
+ fat[f * perSector + j] = dv.getUint32(off + j * 4, true);
106
+ }
107
+ }
108
+
109
+ function chain(start) {
110
+ const out = [];
111
+ let s = start;
112
+ let n = 0;
113
+ while (s !== ENDOFCHAIN && s !== FREESECT && s !== undefined) {
114
+ if (n++ > fat.length + 8) {
115
+ throw new MailfileError(ErrorCode.CORRUPT_CFB, 'Sector chain loops back on itself');
116
+ }
117
+ checkSector(s);
118
+ out.push(s);
119
+ s = fat[s];
120
+ }
121
+ return out;
122
+ }
123
+
124
+ function readSectors(list, size) {
125
+ const out = new Uint8Array(list.length * sectorSize);
126
+ for (let i = 0; i < list.length; i++) {
127
+ out.set(bytes.subarray(sectorOffset(list[i]), sectorOffset(list[i]) + sectorSize),
128
+ i * sectorSize);
129
+ }
130
+ return size == null ? out : out.subarray(0, size);
131
+ }
132
+
133
+ // MiniFAT
134
+ const miniFatBytes = readSectors(chain(firstMiniFat));
135
+ const miniFat = new Uint32Array(miniFatBytes.length >> 2);
136
+ const mdv = new DataView(miniFatBytes.buffer, miniFatBytes.byteOffset, miniFatBytes.byteLength);
137
+ for (let m = 0; m < miniFat.length; m++) miniFat[m] = mdv.getUint32(m * 4, true);
138
+
139
+ // Directory
140
+ const dirBytes = readSectors(chain(firstDirSector));
141
+ const count = Math.floor(dirBytes.length / 128);
142
+ const ddv = new DataView(dirBytes.buffer, dirBytes.byteOffset, dirBytes.byteLength);
143
+ const entries = [];
144
+ for (let e = 0; e < count; e++) {
145
+ const o = e * 128;
146
+ const nameLen = ddv.getUint16(o + 64, true);
147
+ let name = '';
148
+ for (let c = 0; c + 1 < nameLen - 1; c += 2) {
149
+ const code = ddv.getUint16(o + c, true);
150
+ if (code === 0) break;
151
+ name += String.fromCharCode(code);
152
+ }
153
+ entries.push({
154
+ id: e,
155
+ name,
156
+ type: ddv.getUint8(o + 66),
157
+ left: ddv.getUint32(o + 68, true),
158
+ right: ddv.getUint32(o + 72, true),
159
+ child: ddv.getUint32(o + 76, true),
160
+ start: ddv.getUint32(o + 116, true),
161
+ size: ddv.getUint32(o + 120, true) + ddv.getUint32(o + 124, true) * 4294967296,
162
+ children: null
163
+ });
164
+ }
165
+ if (!entries.length) {
166
+ throw new MailfileError(ErrorCode.CORRUPT_CFB, 'Compound file has no directory');
167
+ }
168
+
169
+ const root = entries[0];
170
+ const miniStream = readSectors(chain(root.start), root.size);
171
+
172
+ /**
173
+ * @param {DirEntry} entry
174
+ * @returns {Uint8Array}
175
+ */
176
+ function readStream(entry) {
177
+ if (!entry || entry.type !== 2 || !entry.size) return new Uint8Array(0);
178
+ if (entry.size < miniCutoff) {
179
+ const out = new Uint8Array(entry.size);
180
+ let s = entry.start;
181
+ let pos = 0;
182
+ let n = 0;
183
+ while (s !== ENDOFCHAIN && s !== FREESECT && pos < entry.size) {
184
+ if (n++ > miniFat.length + 8) {
185
+ throw new MailfileError(ErrorCode.CORRUPT_CFB, 'Mini sector chain loops back on itself');
186
+ }
187
+ const take = Math.min(miniSectorSize, entry.size - pos);
188
+ out.set(miniStream.subarray(s * miniSectorSize, s * miniSectorSize + take), pos);
189
+ pos += take;
190
+ s = miniFat[s];
191
+ }
192
+ return out;
193
+ }
194
+ return readSectors(chain(entry.start), entry.size);
195
+ }
196
+
197
+ // Each storage's children live in a red-black tree; walk it in order.
198
+ function collect(nodeId, into, seen) {
199
+ if (nodeId === NOSTREAM || nodeId >= entries.length || seen[nodeId]) return;
200
+ seen[nodeId] = 1;
201
+ const n = entries[nodeId];
202
+ collect(n.left, into, seen);
203
+ into.push(n);
204
+ collect(n.right, into, seen);
205
+ }
206
+
207
+ /**
208
+ * @param {DirEntry} entry
209
+ */
210
+ function childrenOf(entry) {
211
+ if (entry.children) return entry.children;
212
+ const list = [];
213
+ collect(entry.child, list, {});
214
+ const map = Object.create(null);
215
+ for (let i = 0; i < list.length; i++) map[list[i].name] = list[i];
216
+ entry.children = { list, map };
217
+ return entry.children;
218
+ }
219
+
220
+ return { root, entries, readStream, childrenOf };
221
+ }