basalt-sync 0.1.7 → 0.1.8

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/README.md CHANGED
@@ -56,6 +56,19 @@ command gives machine-readable output. State lives in `.basalt/` inside the
56
56
  vault, which is never synced: `config.json` (0600, holds the root secret) and
57
57
  `index.json`.
58
58
 
59
+ `--config-dir` names Obsidian's config folder when it is not `.obsidian`. The
60
+ plugin asks Obsidian for this and always gets it right; a headless client has
61
+ nothing to ask, so it assumes `.obsidian` and has to be told otherwise. Until
62
+ this flag existed there was no way to tell it, and a vault whose config folder
63
+ had been renamed in the app had it synced here and refused by the plugin, which
64
+ is one vault disagreeing with itself about the one thing this project will not
65
+ sync. Naming a different folder also makes `.obsidian` ordinary content again,
66
+ since by then it is just a folder.
67
+
68
+ `--ignore NAME` leaves one more top-level name alone, and can be repeated. One
69
+ name per flag rather than a separated list, because a filename may contain a
70
+ comma and a vault is the wrong place to discover which separator was assumed.
71
+
59
72
  `cli.ts` takes an argv and two output functions and returns an exit code, so
60
73
  `cli.test.ts` drives the whole client against a real server with no subprocess.
61
74
  `bin.ts` is the six lines connecting that to a terminal, and the only part no
package/dist/basalt.mjs CHANGED
@@ -1,12 +1,12 @@
1
1
  #!/usr/bin/env node
2
- var jn=Object.create;var Mt=Object.defineProperty;var Gn=Object.getOwnPropertyDescriptor;var qn=Object.getOwnPropertyNames;var Zn=Object.getPrototypeOf,Xn=Object.prototype.hasOwnProperty;var Yn=(n,e)=>()=>{try{return e||n((e={exports:{}}).exports,e),e.exports}catch(t){throw e=0,t}};var Qn=(n,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of qn(e))!Xn.call(n,i)&&i!==t&&Mt(n,i,{get:()=>e[i],enumerable:!(r=Gn(e,i))||r.enumerable});return n};var er=(n,e,t)=>(t=n!=null?jn(Zn(n)):{},Qn(e||!n||!n.__esModule?Mt(t,"default",{value:n,enumerable:!0}):t,n));var on=Yn((Bi,me)=>{var d=function(){this.Diff_Timeout=1,this.Diff_EditCost=4,this.Match_Threshold=.5,this.Match_Distance=1e3,this.Patch_DeleteThreshold=.5,this.Patch_Margin=4,this.Match_MaxBits=32},C=-1,T=1,k=0;d.Diff=function(n,e){return[n,e]};d.prototype.diff_main=function(n,e,t,r){typeof r>"u"&&(this.Diff_Timeout<=0?r=Number.MAX_VALUE:r=new Date().getTime()+this.Diff_Timeout*1e3);var i=r;if(n==null||e==null)throw new Error("Null input. (diff_main)");if(n==e)return n?[new d.Diff(k,n)]:[];typeof t>"u"&&(t=!0);var s=t,o=this.diff_commonPrefix(n,e),a=n.substring(0,o);n=n.substring(o),e=e.substring(o),o=this.diff_commonSuffix(n,e);var l=n.substring(n.length-o);n=n.substring(0,n.length-o),e=e.substring(0,e.length-o);var c=this.diff_compute_(n,e,s,i);return a&&c.unshift(new d.Diff(k,a)),l&&c.push(new d.Diff(k,l)),this.diff_cleanupMerge(c),c};d.prototype.diff_compute_=function(n,e,t,r){var i;if(!n)return[new d.Diff(T,e)];if(!e)return[new d.Diff(C,n)];var s=n.length>e.length?n:e,o=n.length>e.length?e:n,a=s.indexOf(o);if(a!=-1)return i=[new d.Diff(T,s.substring(0,a)),new d.Diff(k,o),new d.Diff(T,s.substring(a+o.length))],n.length>e.length&&(i[0][0]=i[2][0]=C),i;if(o.length==1)return[new d.Diff(C,n),new d.Diff(T,e)];var l=this.diff_halfMatch_(n,e);if(l){var c=l[0],h=l[1],u=l[2],f=l[3],g=l[4],m=this.diff_main(c,u,t,r),v=this.diff_main(h,f,t,r);return m.concat([new d.Diff(k,g)],v)}return t&&n.length>100&&e.length>100?this.diff_lineMode_(n,e,r):this.diff_bisect_(n,e,r)};d.prototype.diff_lineMode_=function(n,e,t){var r=this.diff_linesToChars_(n,e);n=r.chars1,e=r.chars2;var i=r.lineArray,s=this.diff_main(n,e,!1,t);this.diff_charsToLines_(s,i),this.diff_cleanupSemantic(s),s.push(new d.Diff(k,""));for(var o=0,a=0,l=0,c="",h="";o<s.length;){switch(s[o][0]){case T:l++,h+=s[o][1];break;case C:a++,c+=s[o][1];break;case k:if(a>=1&&l>=1){s.splice(o-a-l,a+l),o=o-a-l;for(var u=this.diff_main(c,h,!1,t),f=u.length-1;f>=0;f--)s.splice(o,0,u[f]);o=o+u.length}l=0,a=0,c="",h="";break}o++}return s.pop(),s};d.prototype.diff_bisect_=function(n,e,t){for(var r=n.length,i=e.length,s=Math.ceil((r+i)/2),o=s,a=2*s,l=new Array(a),c=new Array(a),h=0;h<a;h++)l[h]=-1,c[h]=-1;l[o+1]=0,c[o+1]=0;for(var u=r-i,f=u%2!=0,g=0,m=0,v=0,x=0,w=0;w<s&&!(new Date().getTime()>t);w++){for(var A=-w+g;A<=w-m;A+=2){var b=o+A,S;A==-w||A!=w&&l[b-1]<l[b+1]?S=l[b+1]:S=l[b-1]+1;for(var M=S-A;S<r&&M<i&&n.charAt(S)==e.charAt(M);)S++,M++;if(l[b]=S,S>r)m+=2;else if(M>i)g+=2;else if(f){var $=o+u-A;if($>=0&&$<a&&c[$]!=-1){var E=r-c[$];if(S>=E)return this.diff_bisectSplit_(n,e,S,M,t)}}}for(var y=-w+v;y<=w-x;y+=2){var $=o+y,E;y==-w||y!=w&&c[$-1]<c[$+1]?E=c[$+1]:E=c[$-1]+1;for(var p=E-y;E<r&&p<i&&n.charAt(r-E-1)==e.charAt(i-p-1);)E++,p++;if(c[$]=E,E>r)x+=2;else if(p>i)v+=2;else if(!f){var b=o+u-y;if(b>=0&&b<a&&l[b]!=-1){var S=l[b],M=o+S-b;if(E=r-E,S>=E)return this.diff_bisectSplit_(n,e,S,M,t)}}}}return[new d.Diff(C,n),new d.Diff(T,e)]};d.prototype.diff_bisectSplit_=function(n,e,t,r,i){var s=n.substring(0,t),o=e.substring(0,r),a=n.substring(t),l=e.substring(r),c=this.diff_main(s,o,!1,i),h=this.diff_main(a,l,!1,i);return c.concat(h)};d.prototype.diff_linesToChars_=function(n,e){var t=[],r={};t[0]="";function i(l){for(var c="",h=0,u=-1,f=t.length;u<l.length-1;){u=l.indexOf(`
3
- `,h),u==-1&&(u=l.length-1);var g=l.substring(h,u+1);(r.hasOwnProperty?r.hasOwnProperty(g):r[g]!==void 0)?c+=String.fromCharCode(r[g]):(f==s&&(g=l.substring(h),u=l.length),c+=String.fromCharCode(f),r[g]=f,t[f++]=g),h=u+1}return c}var s=4e4,o=i(n);s=65535;var a=i(e);return{chars1:o,chars2:a,lineArray:t}};d.prototype.diff_charsToLines_=function(n,e){for(var t=0;t<n.length;t++){for(var r=n[t][1],i=[],s=0;s<r.length;s++)i[s]=e[r.charCodeAt(s)];n[t][1]=i.join("")}};d.prototype.diff_commonPrefix=function(n,e){if(!n||!e||n.charAt(0)!=e.charAt(0))return 0;for(var t=0,r=Math.min(n.length,e.length),i=r,s=0;t<i;)n.substring(s,i)==e.substring(s,i)?(t=i,s=t):r=i,i=Math.floor((r-t)/2+t);return i};d.prototype.diff_commonSuffix=function(n,e){if(!n||!e||n.charAt(n.length-1)!=e.charAt(e.length-1))return 0;for(var t=0,r=Math.min(n.length,e.length),i=r,s=0;t<i;)n.substring(n.length-i,n.length-s)==e.substring(e.length-i,e.length-s)?(t=i,s=t):r=i,i=Math.floor((r-t)/2+t);return i};d.prototype.diff_commonOverlap_=function(n,e){var t=n.length,r=e.length;if(t==0||r==0)return 0;t>r?n=n.substring(t-r):t<r&&(e=e.substring(0,t));var i=Math.min(t,r);if(n==e)return i;for(var s=0,o=1;;){var a=n.substring(i-o),l=e.indexOf(a);if(l==-1)return s;o+=l,(l==0||n.substring(i-o)==e.substring(0,o))&&(s=o,o++)}};d.prototype.diff_halfMatch_=function(n,e){if(this.Diff_Timeout<=0)return null;var t=n.length>e.length?n:e,r=n.length>e.length?e:n;if(t.length<4||r.length*2<t.length)return null;var i=this;function s(m,v,x){for(var w=m.substring(x,x+Math.floor(m.length/4)),A=-1,b="",S,M,$,E;(A=v.indexOf(w,A+1))!=-1;){var y=i.diff_commonPrefix(m.substring(x),v.substring(A)),p=i.diff_commonSuffix(m.substring(0,x),v.substring(0,A));b.length<p+y&&(b=v.substring(A-p,A)+v.substring(A,A+y),S=m.substring(0,x-p),M=m.substring(x+y),$=v.substring(0,A-p),E=v.substring(A+y))}return b.length*2>=m.length?[S,M,$,E,b]:null}var o=s(t,r,Math.ceil(t.length/4)),a=s(t,r,Math.ceil(t.length/2)),l;if(!o&&!a)return null;a?o?l=o[4].length>a[4].length?o:a:l=a:l=o;var c,h,u,f;n.length>e.length?(c=l[0],h=l[1],u=l[2],f=l[3]):(u=l[0],f=l[1],c=l[2],h=l[3]);var g=l[4];return[c,h,u,f,g]};d.prototype.diff_cleanupSemantic=function(n){for(var e=!1,t=[],r=0,i=null,s=0,o=0,a=0,l=0,c=0;s<n.length;)n[s][0]==k?(t[r++]=s,o=l,a=c,l=0,c=0,i=n[s][1]):(n[s][0]==T?l+=n[s][1].length:c+=n[s][1].length,i&&i.length<=Math.max(o,a)&&i.length<=Math.max(l,c)&&(n.splice(t[r-1],0,new d.Diff(C,i)),n[t[r-1]+1][0]=T,r--,r--,s=r>0?t[r-1]:-1,o=0,a=0,l=0,c=0,i=null,e=!0)),s++;for(e&&this.diff_cleanupMerge(n),this.diff_cleanupSemanticLossless(n),s=1;s<n.length;){if(n[s-1][0]==C&&n[s][0]==T){var h=n[s-1][1],u=n[s][1],f=this.diff_commonOverlap_(h,u),g=this.diff_commonOverlap_(u,h);f>=g?(f>=h.length/2||f>=u.length/2)&&(n.splice(s,0,new d.Diff(k,u.substring(0,f))),n[s-1][1]=h.substring(0,h.length-f),n[s+1][1]=u.substring(f),s++):(g>=h.length/2||g>=u.length/2)&&(n.splice(s,0,new d.Diff(k,h.substring(0,g))),n[s-1][0]=T,n[s-1][1]=u.substring(0,u.length-g),n[s+1][0]=C,n[s+1][1]=h.substring(g),s++),s++}s++}};d.prototype.diff_cleanupSemanticLossless=function(n){function e(g,m){if(!g||!m)return 6;var v=g.charAt(g.length-1),x=m.charAt(0),w=v.match(d.nonAlphaNumericRegex_),A=x.match(d.nonAlphaNumericRegex_),b=w&&v.match(d.whitespaceRegex_),S=A&&x.match(d.whitespaceRegex_),M=b&&v.match(d.linebreakRegex_),$=S&&x.match(d.linebreakRegex_),E=M&&g.match(d.blanklineEndRegex_),y=$&&m.match(d.blanklineStartRegex_);return E||y?5:M||$?4:w&&!b&&S?3:b||S?2:w||A?1:0}for(var t=1;t<n.length-1;){if(n[t-1][0]==k&&n[t+1][0]==k){var r=n[t-1][1],i=n[t][1],s=n[t+1][1],o=this.diff_commonSuffix(r,i);if(o){var a=i.substring(i.length-o);r=r.substring(0,r.length-o),i=a+i.substring(0,i.length-o),s=a+s}for(var l=r,c=i,h=s,u=e(r,i)+e(i,s);i.charAt(0)===s.charAt(0);){r+=i.charAt(0),i=i.substring(1)+s.charAt(0),s=s.substring(1);var f=e(r,i)+e(i,s);f>=u&&(u=f,l=r,c=i,h=s)}n[t-1][1]!=l&&(l?n[t-1][1]=l:(n.splice(t-1,1),t--),n[t][1]=c,h?n[t+1][1]=h:(n.splice(t+1,1),t--))}t++}};d.nonAlphaNumericRegex_=/[^a-zA-Z0-9]/;d.whitespaceRegex_=/\s/;d.linebreakRegex_=/[\r\n]/;d.blanklineEndRegex_=/\n\r?\n$/;d.blanklineStartRegex_=/^\r?\n\r?\n/;d.prototype.diff_cleanupEfficiency=function(n){for(var e=!1,t=[],r=0,i=null,s=0,o=!1,a=!1,l=!1,c=!1;s<n.length;)n[s][0]==k?(n[s][1].length<this.Diff_EditCost&&(l||c)?(t[r++]=s,o=l,a=c,i=n[s][1]):(r=0,i=null),l=c=!1):(n[s][0]==C?c=!0:l=!0,i&&(o&&a&&l&&c||i.length<this.Diff_EditCost/2&&o+a+l+c==3)&&(n.splice(t[r-1],0,new d.Diff(C,i)),n[t[r-1]+1][0]=T,r--,i=null,o&&a?(l=c=!0,r=0):(r--,s=r>0?t[r-1]:-1,l=c=!1),e=!0)),s++;e&&this.diff_cleanupMerge(n)};d.prototype.diff_cleanupMerge=function(n){n.push(new d.Diff(k,""));for(var e=0,t=0,r=0,i="",s="",o;e<n.length;)switch(n[e][0]){case T:r++,s+=n[e][1],e++;break;case C:t++,i+=n[e][1],e++;break;case k:t+r>1?(t!==0&&r!==0&&(o=this.diff_commonPrefix(s,i),o!==0&&(e-t-r>0&&n[e-t-r-1][0]==k?n[e-t-r-1][1]+=s.substring(0,o):(n.splice(0,0,new d.Diff(k,s.substring(0,o))),e++),s=s.substring(o),i=i.substring(o)),o=this.diff_commonSuffix(s,i),o!==0&&(n[e][1]=s.substring(s.length-o)+n[e][1],s=s.substring(0,s.length-o),i=i.substring(0,i.length-o))),e-=t+r,n.splice(e,t+r),i.length&&(n.splice(e,0,new d.Diff(C,i)),e++),s.length&&(n.splice(e,0,new d.Diff(T,s)),e++),e++):e!==0&&n[e-1][0]==k?(n[e-1][1]+=n[e][1],n.splice(e,1)):e++,r=0,t=0,i="",s="";break}n[n.length-1][1]===""&&n.pop();var a=!1;for(e=1;e<n.length-1;)n[e-1][0]==k&&n[e+1][0]==k&&(n[e][1].substring(n[e][1].length-n[e-1][1].length)==n[e-1][1]?(n[e][1]=n[e-1][1]+n[e][1].substring(0,n[e][1].length-n[e-1][1].length),n[e+1][1]=n[e-1][1]+n[e+1][1],n.splice(e-1,1),a=!0):n[e][1].substring(0,n[e+1][1].length)==n[e+1][1]&&(n[e-1][1]+=n[e+1][1],n[e][1]=n[e][1].substring(n[e+1][1].length)+n[e+1][1],n.splice(e+1,1),a=!0)),e++;a&&this.diff_cleanupMerge(n)};d.prototype.diff_xIndex=function(n,e){var t=0,r=0,i=0,s=0,o;for(o=0;o<n.length&&(n[o][0]!==T&&(t+=n[o][1].length),n[o][0]!==C&&(r+=n[o][1].length),!(t>e));o++)i=t,s=r;return n.length!=o&&n[o][0]===C?s:s+(e-i)};d.prototype.diff_prettyHtml=function(n){for(var e=[],t=/&/g,r=/</g,i=/>/g,s=/\n/g,o=0;o<n.length;o++){var a=n[o][0],l=n[o][1],c=l.replace(t,"&amp;").replace(r,"&lt;").replace(i,"&gt;").replace(s,"&para;<br>");switch(a){case T:e[o]='<ins style="background:#e6ffe6;">'+c+"</ins>";break;case C:e[o]='<del style="background:#ffe6e6;">'+c+"</del>";break;case k:e[o]="<span>"+c+"</span>";break}}return e.join("")};d.prototype.diff_text1=function(n){for(var e=[],t=0;t<n.length;t++)n[t][0]!==T&&(e[t]=n[t][1]);return e.join("")};d.prototype.diff_text2=function(n){for(var e=[],t=0;t<n.length;t++)n[t][0]!==C&&(e[t]=n[t][1]);return e.join("")};d.prototype.diff_levenshtein=function(n){for(var e=0,t=0,r=0,i=0;i<n.length;i++){var s=n[i][0],o=n[i][1];switch(s){case T:t+=o.length;break;case C:r+=o.length;break;case k:e+=Math.max(t,r),t=0,r=0;break}}return e+=Math.max(t,r),e};d.prototype.diff_toDelta=function(n){for(var e=[],t=0;t<n.length;t++)switch(n[t][0]){case T:e[t]="+"+encodeURI(n[t][1]);break;case C:e[t]="-"+n[t][1].length;break;case k:e[t]="="+n[t][1].length;break}return e.join(" ").replace(/%20/g," ")};d.prototype.diff_fromDelta=function(n,e){for(var t=[],r=0,i=0,s=e.split(/\t/g),o=0;o<s.length;o++){var a=s[o].substring(1);switch(s[o].charAt(0)){case"+":try{t[r++]=new d.Diff(T,decodeURI(a))}catch{throw new Error("Illegal escape in diff_fromDelta: "+a)}break;case"-":case"=":var l=parseInt(a,10);if(isNaN(l)||l<0)throw new Error("Invalid number in diff_fromDelta: "+a);var c=n.substring(i,i+=l);s[o].charAt(0)=="="?t[r++]=new d.Diff(k,c):t[r++]=new d.Diff(C,c);break;default:if(s[o])throw new Error("Invalid diff operation in diff_fromDelta: "+s[o])}}if(i!=n.length)throw new Error("Delta length ("+i+") does not equal source text length ("+n.length+").");return t};d.prototype.match_main=function(n,e,t){if(n==null||e==null||t==null)throw new Error("Null input. (match_main)");return t=Math.max(0,Math.min(t,n.length)),n==e?0:n.length?n.substring(t,t+e.length)==e?t:this.match_bitap_(n,e,t):-1};d.prototype.match_bitap_=function(n,e,t){if(e.length>this.Match_MaxBits)throw new Error("Pattern too long for this browser.");var r=this.match_alphabet_(e),i=this;function s(S,M){var $=S/e.length,E=Math.abs(t-M);return i.Match_Distance?$+E/i.Match_Distance:E?1:$}var o=this.Match_Threshold,a=n.indexOf(e,t);a!=-1&&(o=Math.min(s(0,a),o),a=n.lastIndexOf(e,t+e.length),a!=-1&&(o=Math.min(s(0,a),o)));var l=1<<e.length-1;a=-1;for(var c,h,u=e.length+n.length,f,g=0;g<e.length;g++){for(c=0,h=u;c<h;)s(g,t+h)<=o?c=h:u=h,h=Math.floor((u-c)/2+c);u=h;var m=Math.max(1,t-h+1),v=Math.min(t+h,n.length)+e.length,x=Array(v+2);x[v+1]=(1<<g)-1;for(var w=v;w>=m;w--){var A=r[n.charAt(w-1)];if(g===0?x[w]=(x[w+1]<<1|1)&A:x[w]=(x[w+1]<<1|1)&A|((f[w+1]|f[w])<<1|1)|f[w+1],x[w]&l){var b=s(g,w-1);if(b<=o)if(o=b,a=w-1,a>t)m=Math.max(1,2*t-a);else break}}if(s(g+1,t)>o)break;f=x}return a};d.prototype.match_alphabet_=function(n){for(var e={},t=0;t<n.length;t++)e[n.charAt(t)]=0;for(var t=0;t<n.length;t++)e[n.charAt(t)]|=1<<n.length-t-1;return e};d.prototype.patch_addContext_=function(n,e){if(e.length!=0){if(n.start2===null)throw Error("patch not initialized");for(var t=e.substring(n.start2,n.start2+n.length1),r=0;e.indexOf(t)!=e.lastIndexOf(t)&&t.length<this.Match_MaxBits-this.Patch_Margin-this.Patch_Margin;)r+=this.Patch_Margin,t=e.substring(n.start2-r,n.start2+n.length1+r);r+=this.Patch_Margin;var i=e.substring(n.start2-r,n.start2);i&&n.diffs.unshift(new d.Diff(k,i));var s=e.substring(n.start2+n.length1,n.start2+n.length1+r);s&&n.diffs.push(new d.Diff(k,s)),n.start1-=i.length,n.start2-=i.length,n.length1+=i.length+s.length,n.length2+=i.length+s.length}};d.prototype.patch_make=function(n,e,t){var r,i;if(typeof n=="string"&&typeof e=="string"&&typeof t>"u")r=n,i=this.diff_main(r,e,!0),i.length>2&&(this.diff_cleanupSemantic(i),this.diff_cleanupEfficiency(i));else if(n&&typeof n=="object"&&typeof e>"u"&&typeof t>"u")i=n,r=this.diff_text1(i);else if(typeof n=="string"&&e&&typeof e=="object"&&typeof t>"u")r=n,i=e;else if(typeof n=="string"&&typeof e=="string"&&t&&typeof t=="object")r=n,i=t;else throw new Error("Unknown call format to patch_make.");if(i.length===0)return[];for(var s=[],o=new d.patch_obj,a=0,l=0,c=0,h=r,u=r,f=0;f<i.length;f++){var g=i[f][0],m=i[f][1];switch(!a&&g!==k&&(o.start1=l,o.start2=c),g){case T:o.diffs[a++]=i[f],o.length2+=m.length,u=u.substring(0,c)+m+u.substring(c);break;case C:o.length1+=m.length,o.diffs[a++]=i[f],u=u.substring(0,c)+u.substring(c+m.length);break;case k:m.length<=2*this.Patch_Margin&&a&&i.length!=f+1?(o.diffs[a++]=i[f],o.length1+=m.length,o.length2+=m.length):m.length>=2*this.Patch_Margin&&a&&(this.patch_addContext_(o,h),s.push(o),o=new d.patch_obj,a=0,h=u,l=c);break}g!==T&&(l+=m.length),g!==C&&(c+=m.length)}return a&&(this.patch_addContext_(o,h),s.push(o)),s};d.prototype.patch_deepCopy=function(n){for(var e=[],t=0;t<n.length;t++){var r=n[t],i=new d.patch_obj;i.diffs=[];for(var s=0;s<r.diffs.length;s++)i.diffs[s]=new d.Diff(r.diffs[s][0],r.diffs[s][1]);i.start1=r.start1,i.start2=r.start2,i.length1=r.length1,i.length2=r.length2,e[t]=i}return e};d.prototype.patch_apply=function(n,e){if(n.length==0)return[e,[]];n=this.patch_deepCopy(n);var t=this.patch_addPadding(n);e=t+e+t,this.patch_splitMax(n);for(var r=0,i=[],s=0;s<n.length;s++){var o=n[s].start2+r,a=this.diff_text1(n[s].diffs),l,c=-1;if(a.length>this.Match_MaxBits?(l=this.match_main(e,a.substring(0,this.Match_MaxBits),o),l!=-1&&(c=this.match_main(e,a.substring(a.length-this.Match_MaxBits),o+a.length-this.Match_MaxBits),(c==-1||l>=c)&&(l=-1))):l=this.match_main(e,a,o),l==-1)i[s]=!1,r-=n[s].length2-n[s].length1;else{i[s]=!0,r=l-o;var h;if(c==-1?h=e.substring(l,l+a.length):h=e.substring(l,c+this.Match_MaxBits),a==h)e=e.substring(0,l)+this.diff_text2(n[s].diffs)+e.substring(l+a.length);else{var u=this.diff_main(a,h,!1);if(a.length>this.Match_MaxBits&&this.diff_levenshtein(u)/a.length>this.Patch_DeleteThreshold)i[s]=!1;else{this.diff_cleanupSemanticLossless(u);for(var f=0,g,m=0;m<n[s].diffs.length;m++){var v=n[s].diffs[m];v[0]!==k&&(g=this.diff_xIndex(u,f)),v[0]===T?e=e.substring(0,l+g)+v[1]+e.substring(l+g):v[0]===C&&(e=e.substring(0,l+g)+e.substring(l+this.diff_xIndex(u,f+v[1].length))),v[0]!==C&&(f+=v[1].length)}}}}}return e=e.substring(t.length,e.length-t.length),[e,i]};d.prototype.patch_addPadding=function(n){for(var e=this.Patch_Margin,t="",r=1;r<=e;r++)t+=String.fromCharCode(r);for(var r=0;r<n.length;r++)n[r].start1+=e,n[r].start2+=e;var i=n[0],s=i.diffs;if(s.length==0||s[0][0]!=k)s.unshift(new d.Diff(k,t)),i.start1-=e,i.start2-=e,i.length1+=e,i.length2+=e;else if(e>s[0][1].length){var o=e-s[0][1].length;s[0][1]=t.substring(s[0][1].length)+s[0][1],i.start1-=o,i.start2-=o,i.length1+=o,i.length2+=o}if(i=n[n.length-1],s=i.diffs,s.length==0||s[s.length-1][0]!=k)s.push(new d.Diff(k,t)),i.length1+=e,i.length2+=e;else if(e>s[s.length-1][1].length){var o=e-s[s.length-1][1].length;s[s.length-1][1]+=t.substring(0,o),i.length1+=o,i.length2+=o}return t};d.prototype.patch_splitMax=function(n){for(var e=this.Match_MaxBits,t=0;t<n.length;t++)if(!(n[t].length1<=e)){var r=n[t];n.splice(t--,1);for(var i=r.start1,s=r.start2,o="";r.diffs.length!==0;){var a=new d.patch_obj,l=!0;for(a.start1=i-o.length,a.start2=s-o.length,o!==""&&(a.length1=a.length2=o.length,a.diffs.push(new d.Diff(k,o)));r.diffs.length!==0&&a.length1<e-this.Patch_Margin;){var c=r.diffs[0][0],h=r.diffs[0][1];c===T?(a.length2+=h.length,s+=h.length,a.diffs.push(r.diffs.shift()),l=!1):c===C&&a.diffs.length==1&&a.diffs[0][0]==k&&h.length>2*e?(a.length1+=h.length,i+=h.length,l=!1,a.diffs.push(new d.Diff(c,h)),r.diffs.shift()):(h=h.substring(0,e-a.length1-this.Patch_Margin),a.length1+=h.length,i+=h.length,c===k?(a.length2+=h.length,s+=h.length):l=!1,a.diffs.push(new d.Diff(c,h)),h==r.diffs[0][1]?r.diffs.shift():r.diffs[0][1]=r.diffs[0][1].substring(h.length))}o=this.diff_text2(a.diffs),o=o.substring(o.length-this.Patch_Margin);var u=this.diff_text1(r.diffs).substring(0,this.Patch_Margin);u!==""&&(a.length1+=u.length,a.length2+=u.length,a.diffs.length!==0&&a.diffs[a.diffs.length-1][0]===k?a.diffs[a.diffs.length-1][1]+=u:a.diffs.push(new d.Diff(k,u))),l||n.splice(++t,0,a)}}};d.prototype.patch_toText=function(n){for(var e=[],t=0;t<n.length;t++)e[t]=n[t];return e.join("")};d.prototype.patch_fromText=function(n){var e=[];if(!n)return e;for(var t=n.split(`
4
- `),r=0,i=/^@@ -(\d+),?(\d*) \+(\d+),?(\d*) @@$/;r<t.length;){var s=t[r].match(i);if(!s)throw new Error("Invalid patch string: "+t[r]);var o=new d.patch_obj;for(e.push(o),o.start1=parseInt(s[1],10),s[2]===""?(o.start1--,o.length1=1):s[2]=="0"?o.length1=0:(o.start1--,o.length1=parseInt(s[2],10)),o.start2=parseInt(s[3],10),s[4]===""?(o.start2--,o.length2=1):s[4]=="0"?o.length2=0:(o.start2--,o.length2=parseInt(s[4],10)),r++;r<t.length;){var a=t[r].charAt(0);try{var l=decodeURI(t[r].substring(1))}catch{throw new Error("Illegal escape in patch_fromText: "+l)}if(a=="-")o.diffs.push(new d.Diff(C,l));else if(a=="+")o.diffs.push(new d.Diff(T,l));else if(a==" ")o.diffs.push(new d.Diff(k,l));else{if(a=="@")break;if(a!=="")throw new Error('Invalid patch mode "'+a+'" in: '+l)}r++}}return e};d.patch_obj=function(){this.diffs=[],this.start1=null,this.start2=null,this.length1=0,this.length2=0};d.patch_obj.prototype.toString=function(){var n,e;this.length1===0?n=this.start1+",0":this.length1==1?n=this.start1+1:n=this.start1+1+","+this.length1,this.length2===0?e=this.start2+",0":this.length2==1?e=this.start2+1:e=this.start2+1+","+this.length2;for(var t=["@@ -"+n+" +"+e+` @@
5
- `],r,i=0;i<this.diffs.length;i++){switch(this.diffs[i][0]){case T:r="+";break;case C:r="-";break;case k:r=" ";break}t[i+1]=r+encodeURI(this.diffs[i][1])+`
6
- `}return t.join("").replace(/%20/g," ")};me.exports=d;me.exports.diff_match_patch=d;me.exports.DIFF_DELETE=C;me.exports.DIFF_INSERT=T;me.exports.DIFF_EQUAL=k});import{hostname as yi}from"node:os";import{resolve as wi}from"node:path";import{createRequire as tr}from"module";var nr=tr("/"),fe,rr,ir;try{fe=nr("worker_threads"),rr=fe.Worker,ir=fe.isMarkedAsUntransferable}catch{}var N=Uint8Array,K=Uint16Array,at=Int32Array,De=new N([0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0,0]),Oe=new N([0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,0,0]),rt=new N([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]),Rt=function(n,e){for(var t=new K(31),r=0;r<31;++r)t[r]=e+=1<<n[r-1];for(var i=new at(t[30]),r=1;r<30;++r)for(var s=t[r];s<t[r+1];++s)i[s]=s-t[r]<<5|r;return{b:t,r:i}},fe=Rt(De,2),It=fe.b,it=fe.r;It[28]=258,it[258]=28;var zt=Rt(Oe,0),sr=zt.b,_t=zt.r,st=new K(32768);for(_=0;_<32768;++_)ee=(_&43690)>>1|(_&21845)<<1,ee=(ee&52428)>>2|(ee&13107)<<2,ee=(ee&61680)>>4|(ee&3855)<<4,st[_]=((ee&65280)>>8|(ee&255)<<8)>>1;var ee,_,Y=(function(n,e,t){for(var r=n.length,i=0,s=new K(e);i<r;++i)n[i]&&++s[n[i]-1];var o=new K(e);for(i=1;i<e;++i)o[i]=o[i-1]+s[i-1]<<1;var a;if(t){a=new K(1<<e);var l=15-e;for(i=0;i<r;++i)if(n[i])for(var c=i<<4|n[i],h=e-n[i],u=o[n[i]-1]++<<h,f=u|(1<<h)-1;u<=f;++u)a[st[u]>>l]=c}else for(a=new K(r),i=0;i<r;++i)n[i]&&(a[i]=st[o[n[i]-1]++]>>15-n[i]);return a}),ie=new N(288);for(_=0;_<144;++_)ie[_]=8;var _;for(_=144;_<256;++_)ie[_]=9;var _;for(_=256;_<280;++_)ie[_]=7;var _;for(_=280;_<288;++_)ie[_]=8;var _,Ee=new N(32);for(_=0;_<32;++_)Ee[_]=5;var _,or=Y(ie,9,0),ar=Y(ie,9,1),lr=Y(Ee,5,0),hr=Y(Ee,5,1),et=function(n){for(var e=n[0],t=1;t<n.length;++t)n[t]>e&&(e=n[t]);return e},q=function(n,e,t){var r=e/8|0;return(n[r]|n[r+1]<<8)>>(e&7)&t},tt=function(n,e){var t=e/8|0;return(n[t]|n[t+1]<<8|n[t+2]<<16)>>(e&7)},lt=function(n){return(n+7)/8|0},Ut=function(n,e,t){return(e==null||e<0)&&(e=0),(t==null||t>n.length)&&(t=n.length),new N(n.subarray(e,t))};var cr=["unexpected EOF","invalid block type","invalid length/literal","invalid distance","stream finished","no stream handler",,"no callback","invalid UTF-8 data","extra field too long","date not in range 1980-2099","filename too long","stream finishing","invalid zip data"],ne=function(n,e,t){var r=new Error(e||cr[n]);if(r.code=n,Error.captureStackTrace&&Error.captureStackTrace(r,ne),!t)throw r;return r},ur=function(n,e,t,r){var i=n.length,s=r?r.length:0;if(!i||e.f&&!e.l)return t||new N(0);var o=!t,a=o||e.i!=2,l=e.i;o&&(t=new N(i*3));var c=function(we){var be=t.length;if(we>be){var ue=new N(Math.max(be*2,we));ue.set(t),t=ue}},h=e.f||0,u=e.p||0,f=e.b||0,g=e.l,m=e.d,v=e.m,x=e.n,w=i*8;do{if(!g){h=q(n,u,1);var A=q(n,u+1,3);if(u+=3,A)if(A==1)g=ar,m=hr,v=9,x=5;else if(A==2){var $=q(n,u,31)+257,E=q(n,u+10,15)+4,y=$+q(n,u+5,31)+1;u+=14;for(var p=new N(y),U=new N(19),z=0;z<E;++z)U[rt[z]]=q(n,u+z*3,7);u+=E*3;for(var F=et(U),re=(1<<F)-1,W=Y(U,F,1),z=0;z<y;){var B=W[q(n,u,re)];u+=B&15;var b=B>>4;if(b<16)p[z++]=b;else{var D=0,R=0;for(b==16?(R=3+q(n,u,3),u+=2,D=p[z-1]):b==17?(R=3+q(n,u,7),u+=3):b==18&&(R=11+q(n,u,127),u+=7);R--;)p[z++]=D}}var L=p.subarray(0,$),O=p.subarray($);v=et(L),x=et(O),g=Y(L,v,1),m=Y(O,x,1)}else ne(1);else{var b=lt(u)+4,S=n[b-4]|n[b-3]<<8,M=b+S;if(M>i){l&&ne(0);break}a&&c(f+S),t.set(n.subarray(b,M),f),e.b=f+=S,e.p=u=M*8,e.f=h;continue}if(u>w){l&&ne(0);break}}a&&c(f+131072);for(var ye=(1<<v)-1,G=(1<<x)-1,Q=u;;Q=u){var D=g[tt(n,u)&ye],V=D>>4;if(u+=D&15,u>w){l&&ne(0);break}if(D||ne(2),V<256)t[f++]=V;else if(V==256){Q=u,g=null;break}else{var J=V-254;if(V>264){var z=V-257,I=De[z];J=q(n,u,(1<<I)-1)+It[z],u+=I}var X=m[tt(n,u)&G],he=X>>4;X||ne(3),u+=X&15;var O=sr[he];if(he>3){var I=Oe[he];O+=tt(n,u)&(1<<I)-1,u+=I}if(u>w){l&&ne(0);break}a&&c(f+131072);var ce=f+J;if(f<O){var ze=s-O,Ue=Math.min(O,ce);for(ze+f<0&&ne(3);f<Ue;++f)t[f]=r[ze+f]}for(;f<ce;++f)t[f]=t[f-O]}}e.l=g,e.p=Q,e.b=f,e.f=h,g&&(h=1,e.m=v,e.d=m,e.n=x)}while(!h);return f!=t.length&&o?Ut(t,0,f):t.subarray(0,f)},te=function(n,e,t){t<<=e&7;var r=e/8|0;n[r]|=t,n[r+1]|=t>>8},ke=function(n,e,t){t<<=e&7;var r=e/8|0;n[r]|=t,n[r+1]|=t>>8,n[r+2]|=t>>16},nt=function(n,e){for(var t=[],r=0;r<n.length;++r)n[r]&&t.push({s:r,f:n[r]});var i=t.length,s=t.slice();if(!i)return{t:Ot,l:0};if(i==1){var o=new N(t[0].s+1);return o[t[0].s]=1,{t:o,l:1}}t.sort(function(M,$){return M.f-$.f}),t.push({s:-1,f:25001});var a=t[0],l=t[1],c=0,h=1,u=2;for(t[0]={s:-1,f:a.f+l.f,l:a,r:l};h!=i-1;)a=t[t[c].f<t[u].f?c++:u++],l=t[c!=h&&t[c].f<t[u].f?c++:u++],t[h++]={s:-1,f:a.f+l.f,l:a,r:l};for(var f=s[0].s,r=1;r<i;++r)s[r].s>f&&(f=s[r].s);var g=new K(f+1),m=ot(t[h-1],g,0);if(m>e){var r=0,v=0,x=m-e,w=1<<x;for(s.sort(function($,E){return g[E.s]-g[$.s]||$.f-E.f});r<i;++r){var A=s[r].s;if(g[A]>e)v+=w-(1<<m-g[A]),g[A]=e;else break}for(v>>=x;v>0;){var b=s[r].s;g[b]<e?v-=1<<e-g[b]++-1:++r}for(;r>=0&&v;--r){var S=s[r].s;g[S]==e&&(--g[S],++v)}m=e}return{t:new N(g),l:m}},ot=function(n,e,t){return n.s==-1?Math.max(ot(n.l,e,t+1),ot(n.r,e,t+1)):e[n.s]=t},Ct=function(n){for(var e=n.length;e&&!n[--e];);for(var t=new K(++e),r=0,i=n[0],s=1,o=function(l){t[r++]=l},a=1;a<=e;++a)if(n[a]==i&&a!=e)++s;else{if(!i&&s>2){for(;s>138;s-=138)o(32754);s>2&&(o(s>10?s-11<<5|28690:s-3<<5|12305),s=0)}else if(s>3){for(o(i),--s;s>6;s-=6)o(8304);s>2&&(o(s-3<<5|8208),s=0)}for(;s--;)o(i);s=1,i=n[a]}return{c:t.subarray(0,r),n:e}},Se=function(n,e){for(var t=0,r=0;r<e.length;++r)t+=n[r]*e[r];return t},Dt=function(n,e,t){var r=t.length,i=lt(e+2);n[i]=r&255,n[i+1]=r>>8,n[i+2]=n[i]^255,n[i+3]=n[i+1]^255;for(var s=0;s<r;++s)n[i+s+4]=t[s];return(i+4+r)*8},Tt=function(n,e,t,r,i,s,o,a,l,c,h){te(e,h++,t),++i[256];for(var u=nt(i,15),f=u.t,g=u.l,m=nt(s,15),v=m.t,x=m.l,w=Ct(f),A=w.c,b=w.n,S=Ct(v),M=S.c,$=S.n,E=new K(19),y=0;y<A.length;++y)++E[A[y]&31];for(var y=0;y<M.length;++y)++E[M[y]&31];for(var p=nt(E,7),U=p.t,z=p.l,F=19;F>4&&!U[rt[F-1]];--F);var re=c+5<<3,W=Se(i,ie)+Se(s,Ee)+o,B=Se(i,f)+Se(s,v)+o+14+3*F+Se(E,U)+2*E[16]+3*E[17]+7*E[18];if(l>=0&&re<=W&&re<=B)return Dt(e,h,n.subarray(l,l+c));var D,R,L,O;if(te(e,h,1+(B<W)),h+=2,B<W){D=Y(f,g,0),R=f,L=Y(v,x,0),O=v;var ye=Y(U,z,0);te(e,h,b-257),te(e,h+5,$-1),te(e,h+10,F-4),h+=14;for(var y=0;y<F;++y)te(e,h+3*y,U[rt[y]]);h+=3*F;for(var G=[A,M],Q=0;Q<2;++Q)for(var V=G[Q],y=0;y<V.length;++y){var J=V[y]&31;te(e,h,ye[J]),h+=U[J],J>15&&(te(e,h,V[y]>>5&127),h+=V[y]>>12)}}else D=or,R=ie,L=lr,O=Ee;for(var y=0;y<a;++y){var I=r[y];if(I>255){var J=I>>18&31;ke(e,h,D[J+257]),h+=R[J+257],J>7&&(te(e,h,I>>23&31),h+=De[J]);var X=I&31;ke(e,h,L[X]),h+=O[X],X>3&&(ke(e,h,I>>5&8191),h+=Oe[X])}else ke(e,h,D[I]),h+=R[I]}return ke(e,h,D[256]),h+R[256]},fr=new at([65540,131080,131088,131104,262176,1048704,1048832,2114560,2117632]),Ot=new N(0),dr=function(n,e,t,r,i,s){var o=s.z||n.length,a=new N(r+o+5*(1+Math.ceil(o/7e3))+i),l=a.subarray(r,a.length-i),c=s.l,h=(s.r||0)&7;if(e){h&&(l[0]=s.r>>3);for(var u=fr[e-1],f=u>>13,g=u&8191,m=(1<<t)-1,v=s.p||new K(32768),x=s.h||new K(m+1),w=Math.ceil(t/3),A=2*w,b=function(Qe){return(n[Qe]^n[Qe+1]<<w^n[Qe+2]<<A)&m},S=new at(25e3),M=new K(288),$=new K(32),E=0,y=0,p=s.i||0,U=0,z=s.w||0,F=0;p+2<o;++p){var re=b(p),W=p&32767,B=x[re];if(v[W]=B,x[re]=W,z<=p){var D=o-p;if((E>7e3||U>24576)&&(D>423||!c)){h=Tt(n,l,0,S,M,$,y,U,F,p-F,h),U=E=y=0,F=p;for(var R=0;R<286;++R)M[R]=0;for(var R=0;R<30;++R)$[R]=0}var L=2,O=0,ye=g,G=W-B&32767;if(D>2&&re==b(p-G))for(var Q=Math.min(f,D)-1,V=Math.min(32767,p),J=Math.min(258,D);G<=V&&--ye&&W!=B;){if(n[p+L]==n[p+L-G]){for(var I=0;I<J&&n[p+I]==n[p+I-G];++I);if(I>L){if(L=I,O=G,I>Q)break;for(var X=Math.min(G,I-2),he=0,R=0;R<X;++R){var ce=p-G+R&32767,ze=v[ce],Ue=ce-ze&32767;Ue>he&&(he=Ue,B=ce)}}}W=B,B=v[W],G+=W-B&32767}if(O){S[U++]=268435456|it[L]<<18|_t[O];var we=it[L]&31,be=_t[O]&31;y+=De[we]+Oe[be],++M[257+we],++$[be],z=p+L,++E}else S[U++]=n[p],++M[n[p]]}}for(p=Math.max(p,z);p<o;++p)S[U++]=n[p],++M[n[p]];h=Tt(n,l,c,S,M,$,y,U,F,p-F,h),c||(s.r=h&7|l[h/8|0]<<3,h-=7,s.h=x,s.p=v,s.i=p,s.w=z)}else{for(var p=s.w||0;p<o+c;p+=65535){var ue=p+65535;ue>=o&&(l[h/8|0]=c,ue=o),h=Dt(l,h+1,n.subarray(p,ue))}s.i=o}return Ut(a,0,r+lt(h)+i)};var gr=function(n,e,t,r,i){if(!i&&(i={l:1},e.dictionary)){var s=e.dictionary.subarray(-32768),o=new N(s.length+n.length);o.set(s),o.set(n,s.length),n=o,i.w=s.length}return dr(n,e.level==null?6:e.level,e.mem==null?i.l?Math.ceil(Math.max(8,Math.min(13,Math.log(n.length)))*1.5):20:12+e.mem,t,r,i)};function ht(n,e){return gr(n,e||{},0,0)}function Ft(n,e){return ur(n,{i:2},e&&e.out,e&&e.dictionary)}var mr=typeof TextDecoder<"u"&&new TextDecoder,vr=0;try{mr.decode(Ot,{stream:!0}),vr=1}catch{}var Bt="basalt/hkdf-aes-gcm/1",oe=12,Ne=128,Lt=oe+Ne/8+1,Z=20,Wt=new TextEncoder,pr=new TextDecoder,Fe={auth:"basalt/auth/1",path:"basalt/path/1",content:"basalt/content/1",nonce:"basalt/nonce/1"};function Ae(){let n=globalThis.crypto;if(!n?.subtle)throw new Error("WebCrypto is unavailable, so this vault cannot be opened");return n.subtle}function Vt(){let n=globalThis.crypto;if(!n?.getRandomValues)throw new Error("no secure random source is available, so a vault cannot be created here");return n.getRandomValues(new Uint8Array(Z))}async function Jt(n){if(n.length<16)throw new Error(`root secret is ${n.length} bytes, need at least 16`);let e=Ae(),t=await e.importKey("raw",ae(n),"HKDF",!1,["deriveKey","deriveBits"]),r=l=>({name:"HKDF",hash:"SHA-256",salt:new Uint8Array(0),info:Wt.encode(l)}),[i,s,o,a]=await Promise.all([e.deriveBits(r(Fe.auth),t,256),e.deriveKey(r(Fe.path),t,{name:"AES-GCM",length:256},!1,["encrypt","decrypt"]),e.deriveKey(r(Fe.content),t,{name:"AES-GCM",length:256},!1,["encrypt","decrypt"]),e.deriveKey(r(Fe.nonce),t,{name:"HMAC",hash:"SHA-256"},!1,["sign"])]);return{auth:new Uint8Array(i),path:s,content:o,nonce:a}}async function Kt(n,e,t){let r=Ae(),i=await yr(e,t),s=await r.encrypt({name:"AES-GCM",iv:ae(i),tagLength:Ne},n,ae(t)),o=new Uint8Array(oe+s.byteLength);return o.set(i,0),o.set(new Uint8Array(s),oe),o}async function Ht(n,e){if(e.length<oe+Ne/8)throw new Error(`sealed value is ${e.length} bytes, too short to contain a nonce and a tag`);let t=Ae(),r=e.subarray(0,oe),i=e.subarray(oe);try{let s=await t.decrypt({name:"AES-GCM",iv:ae(r),tagLength:Ne},n,ae(i));return new Uint8Array(s)}catch(s){throw new Error("sealed value failed authentication, so it is not what was stored",{cause:s})}}async function yr(n,e){let t=await Ae().sign("HMAC",n,ae(e));return new Uint8Array(t,0,oe)}async function Be(n,e){return xe(await Kt(n.path,n.nonce,Wt.encode(e)))}async function Le(n,e){let t=await Ht(n.path,We(e));return pr.decode(t)}var jt=0,Gt=1;async function wr(n,e){let t=br(e)?ht(e,{level:6}):void 0,r=t!==void 0&&t.length<e.length,i=r?t:e,s=new Uint8Array(1+i.length);return s[0]=r?Gt:jt,s.set(i,1),Kt(n.content,n.nonce,s)}function br(n){if(n.length===0)return!1;if(n.length<=Nt*2)return!0;let e=n.subarray(0,Nt);return ht(e,{level:6}).length<e.length}var Nt=4096;async function ge(n,e){return Promise.all([...e].map(async t=>{let r=await wr(n,t);return{name:await ct(r),bytes:r}}))}async function qt(n,e){let t=await Ht(n.content,e);if(t.length===0)throw new Error("sealed chunk carries no marker byte");let r=t[0],i=t.subarray(1);if(r===jt)return i;if(r===Gt)try{return Ft(i)}catch(s){throw new Error("sealed chunk claims to be deflated and is not",{cause:s})}throw new Error(`sealed chunk has an unknown marker byte ${r}`)}async function ct(n){let e=await Ae().digest("SHA-256",ae(n));return kr(new Uint8Array(e))}function Zt(n){return xe(n.auth)}function ae(n){return n.slice().buffer}function kr(n){let e="";for(let t of n)e+=t.toString(16).padStart(2,"0");return e}var de="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";function xe(n){let e="";for(let t=0;t<n.length;t+=3){let r=n[t],i=t+1<n.length?n[t+1]:void 0,s=t+2<n.length?n[t+2]:void 0;if(e+=de[r>>2],e+=de[(r&3)<<4|(i??0)>>4],i===void 0||(e+=de[(i&15)<<2|(s??0)>>6],s===void 0))break;e+=de[s&63]}return e}var Sr=(()=>{let n=new Int16Array(128).fill(-1);for(let e=0;e<de.length;e++)n[de.charCodeAt(e)]=e;return n})();function We(n){let e=n.length,t=new Uint8Array(Math.floor(e*3/4)),r=0,i=0,s=0;for(let o=0;o<e;o++){let a=n.charCodeAt(o),l=a<128?Sr[a]:-1;if(l<0)throw new Error(`invalid base64url character ${JSON.stringify(n[o])} at position ${o}`);i=i<<6|l,s+=6,s>=8&&(s-=8,t[r++]=i>>s&255)}return t.subarray(0,r)}var se=48,le=31,Xt=1,Yt={min:512,avg:1024,max:4096},Er=64,Ar=Yt.avg,xr=64*1024;function Pr(n){let e=Math.sqrt(Er*Math.max(n,1)),t=Math.min(xr,Math.max(Ar,Math.round(e/512)*512));return{min:Math.max(Yt.min,t/2),avg:t,max:t*4}}var ut={min:128*1024,avg:256*1024,max:1024*1024},$r=4*1024*1024;function Qt(n,e,t=ut.max){(!Number.isFinite(t)||t<=0)&&(t=ut.max);let r=e&&n<$r?Pr(n):ut,i=Math.min(r.max,t-Lt),s=Math.max(i,se*4);return{min:Math.min(r.min,s),avg:Math.min(r.avg,s),max:s}}function en(n,e,t){let r=t-1;for(;r>e&&(n[r]&192)===128;)r--;if(r<e)return t;let i=n[r],s=i<128?1:(i&224)===192?2:(i&240)===224?3:(i&248)===240?4:1;return t-r>=s?t:r>e?r:t}function*tn(n,e,t){let{min:r,avg:i,max:s}=e,o=n.length,a=1;for(let h=0;h<se-1;h++)a=Math.imul(a,le);let l=0,c=0;for(let h=0;h<o;h++){let u=n[h];h>=l+se?(c=c-Math.imul(n[h-se],a)|0,c=Math.imul(c,le),c=c+u|0):(c=Math.imul(c,le),c=c+u|0);let f=h-l+1,g=f>=r&&(c>>>0)%i===Xt;if(f>=s&&(g=!0),g){let m=t?en(n,l,h+1):h+1;yield{offset:l,bytes:n.subarray(l,m)},l=m,c=0,h=m-1}}l<o&&(yield{offset:l,bytes:n.subarray(l,o)})}async function*nn(n,e,t){let{min:r,avg:i,max:s}=e,o=1;for(let f=0;f<se-1;f++)o=Math.imul(o,le);let a=new Uint8Array(Math.max(s,se*2)),l=0,c=0,h=0,u=()=>{let f=t?en(a,0,l):l,g={offset:h,bytes:a.slice(0,f)};h+=f;let m=l-f;a.copyWithin(0,f,l),l=m,c=0;for(let v=0;v<m;v++)c=Math.imul(c,le),c=c+a[v]|0;return g};for await(let f of n)for(let g=0;g<f.length;g++){let m=f[g];a[l++]=m,l>=se+1?(c=c-Math.imul(a[l-1-se],o)|0,c=Math.imul(c,le),c=c+m|0):(c=Math.imul(c,le),c=c+m|0),(l>=s||l>=r&&(c>>>0)%i===Xt)&&(yield u())}if(l>0){let f={offset:h,bytes:a.slice(0,l)};h+=l,l=0,yield f}}var Mr=new Set(["md","txt","canvas","json","csv","yml","yaml","xml","html","css","js","ts","svg","bib","tex"]);function rn(n){let e=n.lastIndexOf(".");return e<0?!1:Mr.has(n.slice(e+1).toLowerCase())}var _r=new Set(["canvas","json"]);function sn(n){let e=n.lastIndexOf(".");return e<0?!1:_r.has(n.slice(e+1).toLowerCase())}var hn=er(on(),1),Cr=-1,Tr=0,Rr=1;function an(n){let e=[],t=0;for(let[r,i]of n)r===Tr?t+=i.length:r===Cr?(e.push({start:t,end:t+i.length}),t+=i.length):e.push({start:t,end:t});return e}function Ir(n,e){for(let t of n)for(let r of e){let i=t.start===t.end,s=r.start===r.end;if(!(i&&s)){if(i){if(r.start<t.start&&t.start<r.end)return t;continue}if(s){if(t.start<r.start&&r.start<t.end)return r;continue}if(t.start<r.end&&r.start<t.end)return t}}}function cn(n,e,t,r=()=>!0){if(e===t)return{kind:"take",text:e,why:"both sides already agree"};if(n===e)return{kind:"take",text:t,why:"no local change since the last sync"};if(n===t)return{kind:"take",text:e,why:"no remote change since the last sync"};let i=new hn.diff_match_patch,s=i.diff_main(n,e,!0,0);s.length>2&&(i.diff_cleanupSemantic(s),i.diff_cleanupEfficiency(s));let o=i.diff_main(n,t,!0,0);o.length>2&&(i.diff_cleanupSemantic(o),i.diff_cleanupEfficiency(o));let a=Ir(an(s),an(o));if(a!==void 0)return{kind:"conflict",why:`both devices changed the same text, at characters ${a.start} to ${a.end} of the last synced version`};let l=ln(i,n,s,t),c=ln(i,n,o,e);if(l.failed>0||c.failed>0){let u=Math.max(l.failed,c.failed),f=Math.max(l.total,c.total);return{kind:"conflict",why:`${u} of ${f} changes could not be placed in the other version`}}if(!zr(l.text,c.text))return{kind:"conflict",why:"merging the two versions in either order gives different content, so at least one change was placed wrongly"};let h=Ur(s,l.text);return h!==void 0?{kind:"conflict",why:`the merge reported success but ${Dr(h)} is not in the result`}:r(l.text)?{kind:"merged",text:l.text}:{kind:"conflict",why:"both sides merged cleanly and the result is no longer a valid file of its kind"}}function zr(n,e){if(n===e)return!0;let t=n.split(`
2
+ var qn=Object.create;var Ct=Object.defineProperty;var Zn=Object.getOwnPropertyDescriptor;var Xn=Object.getOwnPropertyNames;var Yn=Object.getPrototypeOf,Qn=Object.prototype.hasOwnProperty;var er=(t,e)=>()=>{try{return e||t((e={exports:{}}).exports,e),e.exports}catch(n){throw e=0,n}};var tr=(t,e,n,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of Xn(e))!Qn.call(t,i)&&i!==n&&Ct(t,i,{get:()=>e[i],enumerable:!(r=Zn(e,i))||r.enumerable});return t};var nr=(t,e,n)=>(n=t!=null?qn(Yn(t)):{},tr(e||!t||!t.__esModule?Ct(n,"default",{value:t,enumerable:!0}):n,t));var ln=er((Wi,me)=>{var d=function(){this.Diff_Timeout=1,this.Diff_EditCost=4,this.Match_Threshold=.5,this.Match_Distance=1e3,this.Patch_DeleteThreshold=.5,this.Patch_Margin=4,this.Match_MaxBits=32},C=-1,T=1,k=0;d.Diff=function(t,e){return[t,e]};d.prototype.diff_main=function(t,e,n,r){typeof r>"u"&&(this.Diff_Timeout<=0?r=Number.MAX_VALUE:r=new Date().getTime()+this.Diff_Timeout*1e3);var i=r;if(t==null||e==null)throw new Error("Null input. (diff_main)");if(t==e)return t?[new d.Diff(k,t)]:[];typeof n>"u"&&(n=!0);var s=n,o=this.diff_commonPrefix(t,e),a=t.substring(0,o);t=t.substring(o),e=e.substring(o),o=this.diff_commonSuffix(t,e);var l=t.substring(t.length-o);t=t.substring(0,t.length-o),e=e.substring(0,e.length-o);var c=this.diff_compute_(t,e,s,i);return a&&c.unshift(new d.Diff(k,a)),l&&c.push(new d.Diff(k,l)),this.diff_cleanupMerge(c),c};d.prototype.diff_compute_=function(t,e,n,r){var i;if(!t)return[new d.Diff(T,e)];if(!e)return[new d.Diff(C,t)];var s=t.length>e.length?t:e,o=t.length>e.length?e:t,a=s.indexOf(o);if(a!=-1)return i=[new d.Diff(T,s.substring(0,a)),new d.Diff(k,o),new d.Diff(T,s.substring(a+o.length))],t.length>e.length&&(i[0][0]=i[2][0]=C),i;if(o.length==1)return[new d.Diff(C,t),new d.Diff(T,e)];var l=this.diff_halfMatch_(t,e);if(l){var c=l[0],h=l[1],u=l[2],f=l[3],g=l[4],m=this.diff_main(c,u,n,r),v=this.diff_main(h,f,n,r);return m.concat([new d.Diff(k,g)],v)}return n&&t.length>100&&e.length>100?this.diff_lineMode_(t,e,r):this.diff_bisect_(t,e,r)};d.prototype.diff_lineMode_=function(t,e,n){var r=this.diff_linesToChars_(t,e);t=r.chars1,e=r.chars2;var i=r.lineArray,s=this.diff_main(t,e,!1,n);this.diff_charsToLines_(s,i),this.diff_cleanupSemantic(s),s.push(new d.Diff(k,""));for(var o=0,a=0,l=0,c="",h="";o<s.length;){switch(s[o][0]){case T:l++,h+=s[o][1];break;case C:a++,c+=s[o][1];break;case k:if(a>=1&&l>=1){s.splice(o-a-l,a+l),o=o-a-l;for(var u=this.diff_main(c,h,!1,n),f=u.length-1;f>=0;f--)s.splice(o,0,u[f]);o=o+u.length}l=0,a=0,c="",h="";break}o++}return s.pop(),s};d.prototype.diff_bisect_=function(t,e,n){for(var r=t.length,i=e.length,s=Math.ceil((r+i)/2),o=s,a=2*s,l=new Array(a),c=new Array(a),h=0;h<a;h++)l[h]=-1,c[h]=-1;l[o+1]=0,c[o+1]=0;for(var u=r-i,f=u%2!=0,g=0,m=0,v=0,x=0,w=0;w<s&&!(new Date().getTime()>n);w++){for(var A=-w+g;A<=w-m;A+=2){var b=o+A,S;A==-w||A!=w&&l[b-1]<l[b+1]?S=l[b+1]:S=l[b-1]+1;for(var M=S-A;S<r&&M<i&&t.charAt(S)==e.charAt(M);)S++,M++;if(l[b]=S,S>r)m+=2;else if(M>i)g+=2;else if(f){var $=o+u-A;if($>=0&&$<a&&c[$]!=-1){var E=r-c[$];if(S>=E)return this.diff_bisectSplit_(t,e,S,M,n)}}}for(var y=-w+v;y<=w-x;y+=2){var $=o+y,E;y==-w||y!=w&&c[$-1]<c[$+1]?E=c[$+1]:E=c[$-1]+1;for(var p=E-y;E<r&&p<i&&t.charAt(r-E-1)==e.charAt(i-p-1);)E++,p++;if(c[$]=E,E>r)x+=2;else if(p>i)v+=2;else if(!f){var b=o+u-y;if(b>=0&&b<a&&l[b]!=-1){var S=l[b],M=o+S-b;if(E=r-E,S>=E)return this.diff_bisectSplit_(t,e,S,M,n)}}}}return[new d.Diff(C,t),new d.Diff(T,e)]};d.prototype.diff_bisectSplit_=function(t,e,n,r,i){var s=t.substring(0,n),o=e.substring(0,r),a=t.substring(n),l=e.substring(r),c=this.diff_main(s,o,!1,i),h=this.diff_main(a,l,!1,i);return c.concat(h)};d.prototype.diff_linesToChars_=function(t,e){var n=[],r={};n[0]="";function i(l){for(var c="",h=0,u=-1,f=n.length;u<l.length-1;){u=l.indexOf(`
3
+ `,h),u==-1&&(u=l.length-1);var g=l.substring(h,u+1);(r.hasOwnProperty?r.hasOwnProperty(g):r[g]!==void 0)?c+=String.fromCharCode(r[g]):(f==s&&(g=l.substring(h),u=l.length),c+=String.fromCharCode(f),r[g]=f,n[f++]=g),h=u+1}return c}var s=4e4,o=i(t);s=65535;var a=i(e);return{chars1:o,chars2:a,lineArray:n}};d.prototype.diff_charsToLines_=function(t,e){for(var n=0;n<t.length;n++){for(var r=t[n][1],i=[],s=0;s<r.length;s++)i[s]=e[r.charCodeAt(s)];t[n][1]=i.join("")}};d.prototype.diff_commonPrefix=function(t,e){if(!t||!e||t.charAt(0)!=e.charAt(0))return 0;for(var n=0,r=Math.min(t.length,e.length),i=r,s=0;n<i;)t.substring(s,i)==e.substring(s,i)?(n=i,s=n):r=i,i=Math.floor((r-n)/2+n);return i};d.prototype.diff_commonSuffix=function(t,e){if(!t||!e||t.charAt(t.length-1)!=e.charAt(e.length-1))return 0;for(var n=0,r=Math.min(t.length,e.length),i=r,s=0;n<i;)t.substring(t.length-i,t.length-s)==e.substring(e.length-i,e.length-s)?(n=i,s=n):r=i,i=Math.floor((r-n)/2+n);return i};d.prototype.diff_commonOverlap_=function(t,e){var n=t.length,r=e.length;if(n==0||r==0)return 0;n>r?t=t.substring(n-r):n<r&&(e=e.substring(0,n));var i=Math.min(n,r);if(t==e)return i;for(var s=0,o=1;;){var a=t.substring(i-o),l=e.indexOf(a);if(l==-1)return s;o+=l,(l==0||t.substring(i-o)==e.substring(0,o))&&(s=o,o++)}};d.prototype.diff_halfMatch_=function(t,e){if(this.Diff_Timeout<=0)return null;var n=t.length>e.length?t:e,r=t.length>e.length?e:t;if(n.length<4||r.length*2<n.length)return null;var i=this;function s(m,v,x){for(var w=m.substring(x,x+Math.floor(m.length/4)),A=-1,b="",S,M,$,E;(A=v.indexOf(w,A+1))!=-1;){var y=i.diff_commonPrefix(m.substring(x),v.substring(A)),p=i.diff_commonSuffix(m.substring(0,x),v.substring(0,A));b.length<p+y&&(b=v.substring(A-p,A)+v.substring(A,A+y),S=m.substring(0,x-p),M=m.substring(x+y),$=v.substring(0,A-p),E=v.substring(A+y))}return b.length*2>=m.length?[S,M,$,E,b]:null}var o=s(n,r,Math.ceil(n.length/4)),a=s(n,r,Math.ceil(n.length/2)),l;if(!o&&!a)return null;a?o?l=o[4].length>a[4].length?o:a:l=a:l=o;var c,h,u,f;t.length>e.length?(c=l[0],h=l[1],u=l[2],f=l[3]):(u=l[0],f=l[1],c=l[2],h=l[3]);var g=l[4];return[c,h,u,f,g]};d.prototype.diff_cleanupSemantic=function(t){for(var e=!1,n=[],r=0,i=null,s=0,o=0,a=0,l=0,c=0;s<t.length;)t[s][0]==k?(n[r++]=s,o=l,a=c,l=0,c=0,i=t[s][1]):(t[s][0]==T?l+=t[s][1].length:c+=t[s][1].length,i&&i.length<=Math.max(o,a)&&i.length<=Math.max(l,c)&&(t.splice(n[r-1],0,new d.Diff(C,i)),t[n[r-1]+1][0]=T,r--,r--,s=r>0?n[r-1]:-1,o=0,a=0,l=0,c=0,i=null,e=!0)),s++;for(e&&this.diff_cleanupMerge(t),this.diff_cleanupSemanticLossless(t),s=1;s<t.length;){if(t[s-1][0]==C&&t[s][0]==T){var h=t[s-1][1],u=t[s][1],f=this.diff_commonOverlap_(h,u),g=this.diff_commonOverlap_(u,h);f>=g?(f>=h.length/2||f>=u.length/2)&&(t.splice(s,0,new d.Diff(k,u.substring(0,f))),t[s-1][1]=h.substring(0,h.length-f),t[s+1][1]=u.substring(f),s++):(g>=h.length/2||g>=u.length/2)&&(t.splice(s,0,new d.Diff(k,h.substring(0,g))),t[s-1][0]=T,t[s-1][1]=u.substring(0,u.length-g),t[s+1][0]=C,t[s+1][1]=h.substring(g),s++),s++}s++}};d.prototype.diff_cleanupSemanticLossless=function(t){function e(g,m){if(!g||!m)return 6;var v=g.charAt(g.length-1),x=m.charAt(0),w=v.match(d.nonAlphaNumericRegex_),A=x.match(d.nonAlphaNumericRegex_),b=w&&v.match(d.whitespaceRegex_),S=A&&x.match(d.whitespaceRegex_),M=b&&v.match(d.linebreakRegex_),$=S&&x.match(d.linebreakRegex_),E=M&&g.match(d.blanklineEndRegex_),y=$&&m.match(d.blanklineStartRegex_);return E||y?5:M||$?4:w&&!b&&S?3:b||S?2:w||A?1:0}for(var n=1;n<t.length-1;){if(t[n-1][0]==k&&t[n+1][0]==k){var r=t[n-1][1],i=t[n][1],s=t[n+1][1],o=this.diff_commonSuffix(r,i);if(o){var a=i.substring(i.length-o);r=r.substring(0,r.length-o),i=a+i.substring(0,i.length-o),s=a+s}for(var l=r,c=i,h=s,u=e(r,i)+e(i,s);i.charAt(0)===s.charAt(0);){r+=i.charAt(0),i=i.substring(1)+s.charAt(0),s=s.substring(1);var f=e(r,i)+e(i,s);f>=u&&(u=f,l=r,c=i,h=s)}t[n-1][1]!=l&&(l?t[n-1][1]=l:(t.splice(n-1,1),n--),t[n][1]=c,h?t[n+1][1]=h:(t.splice(n+1,1),n--))}n++}};d.nonAlphaNumericRegex_=/[^a-zA-Z0-9]/;d.whitespaceRegex_=/\s/;d.linebreakRegex_=/[\r\n]/;d.blanklineEndRegex_=/\n\r?\n$/;d.blanklineStartRegex_=/^\r?\n\r?\n/;d.prototype.diff_cleanupEfficiency=function(t){for(var e=!1,n=[],r=0,i=null,s=0,o=!1,a=!1,l=!1,c=!1;s<t.length;)t[s][0]==k?(t[s][1].length<this.Diff_EditCost&&(l||c)?(n[r++]=s,o=l,a=c,i=t[s][1]):(r=0,i=null),l=c=!1):(t[s][0]==C?c=!0:l=!0,i&&(o&&a&&l&&c||i.length<this.Diff_EditCost/2&&o+a+l+c==3)&&(t.splice(n[r-1],0,new d.Diff(C,i)),t[n[r-1]+1][0]=T,r--,i=null,o&&a?(l=c=!0,r=0):(r--,s=r>0?n[r-1]:-1,l=c=!1),e=!0)),s++;e&&this.diff_cleanupMerge(t)};d.prototype.diff_cleanupMerge=function(t){t.push(new d.Diff(k,""));for(var e=0,n=0,r=0,i="",s="",o;e<t.length;)switch(t[e][0]){case T:r++,s+=t[e][1],e++;break;case C:n++,i+=t[e][1],e++;break;case k:n+r>1?(n!==0&&r!==0&&(o=this.diff_commonPrefix(s,i),o!==0&&(e-n-r>0&&t[e-n-r-1][0]==k?t[e-n-r-1][1]+=s.substring(0,o):(t.splice(0,0,new d.Diff(k,s.substring(0,o))),e++),s=s.substring(o),i=i.substring(o)),o=this.diff_commonSuffix(s,i),o!==0&&(t[e][1]=s.substring(s.length-o)+t[e][1],s=s.substring(0,s.length-o),i=i.substring(0,i.length-o))),e-=n+r,t.splice(e,n+r),i.length&&(t.splice(e,0,new d.Diff(C,i)),e++),s.length&&(t.splice(e,0,new d.Diff(T,s)),e++),e++):e!==0&&t[e-1][0]==k?(t[e-1][1]+=t[e][1],t.splice(e,1)):e++,r=0,n=0,i="",s="";break}t[t.length-1][1]===""&&t.pop();var a=!1;for(e=1;e<t.length-1;)t[e-1][0]==k&&t[e+1][0]==k&&(t[e][1].substring(t[e][1].length-t[e-1][1].length)==t[e-1][1]?(t[e][1]=t[e-1][1]+t[e][1].substring(0,t[e][1].length-t[e-1][1].length),t[e+1][1]=t[e-1][1]+t[e+1][1],t.splice(e-1,1),a=!0):t[e][1].substring(0,t[e+1][1].length)==t[e+1][1]&&(t[e-1][1]+=t[e+1][1],t[e][1]=t[e][1].substring(t[e+1][1].length)+t[e+1][1],t.splice(e+1,1),a=!0)),e++;a&&this.diff_cleanupMerge(t)};d.prototype.diff_xIndex=function(t,e){var n=0,r=0,i=0,s=0,o;for(o=0;o<t.length&&(t[o][0]!==T&&(n+=t[o][1].length),t[o][0]!==C&&(r+=t[o][1].length),!(n>e));o++)i=n,s=r;return t.length!=o&&t[o][0]===C?s:s+(e-i)};d.prototype.diff_prettyHtml=function(t){for(var e=[],n=/&/g,r=/</g,i=/>/g,s=/\n/g,o=0;o<t.length;o++){var a=t[o][0],l=t[o][1],c=l.replace(n,"&amp;").replace(r,"&lt;").replace(i,"&gt;").replace(s,"&para;<br>");switch(a){case T:e[o]='<ins style="background:#e6ffe6;">'+c+"</ins>";break;case C:e[o]='<del style="background:#ffe6e6;">'+c+"</del>";break;case k:e[o]="<span>"+c+"</span>";break}}return e.join("")};d.prototype.diff_text1=function(t){for(var e=[],n=0;n<t.length;n++)t[n][0]!==T&&(e[n]=t[n][1]);return e.join("")};d.prototype.diff_text2=function(t){for(var e=[],n=0;n<t.length;n++)t[n][0]!==C&&(e[n]=t[n][1]);return e.join("")};d.prototype.diff_levenshtein=function(t){for(var e=0,n=0,r=0,i=0;i<t.length;i++){var s=t[i][0],o=t[i][1];switch(s){case T:n+=o.length;break;case C:r+=o.length;break;case k:e+=Math.max(n,r),n=0,r=0;break}}return e+=Math.max(n,r),e};d.prototype.diff_toDelta=function(t){for(var e=[],n=0;n<t.length;n++)switch(t[n][0]){case T:e[n]="+"+encodeURI(t[n][1]);break;case C:e[n]="-"+t[n][1].length;break;case k:e[n]="="+t[n][1].length;break}return e.join(" ").replace(/%20/g," ")};d.prototype.diff_fromDelta=function(t,e){for(var n=[],r=0,i=0,s=e.split(/\t/g),o=0;o<s.length;o++){var a=s[o].substring(1);switch(s[o].charAt(0)){case"+":try{n[r++]=new d.Diff(T,decodeURI(a))}catch{throw new Error("Illegal escape in diff_fromDelta: "+a)}break;case"-":case"=":var l=parseInt(a,10);if(isNaN(l)||l<0)throw new Error("Invalid number in diff_fromDelta: "+a);var c=t.substring(i,i+=l);s[o].charAt(0)=="="?n[r++]=new d.Diff(k,c):n[r++]=new d.Diff(C,c);break;default:if(s[o])throw new Error("Invalid diff operation in diff_fromDelta: "+s[o])}}if(i!=t.length)throw new Error("Delta length ("+i+") does not equal source text length ("+t.length+").");return n};d.prototype.match_main=function(t,e,n){if(t==null||e==null||n==null)throw new Error("Null input. (match_main)");return n=Math.max(0,Math.min(n,t.length)),t==e?0:t.length?t.substring(n,n+e.length)==e?n:this.match_bitap_(t,e,n):-1};d.prototype.match_bitap_=function(t,e,n){if(e.length>this.Match_MaxBits)throw new Error("Pattern too long for this browser.");var r=this.match_alphabet_(e),i=this;function s(S,M){var $=S/e.length,E=Math.abs(n-M);return i.Match_Distance?$+E/i.Match_Distance:E?1:$}var o=this.Match_Threshold,a=t.indexOf(e,n);a!=-1&&(o=Math.min(s(0,a),o),a=t.lastIndexOf(e,n+e.length),a!=-1&&(o=Math.min(s(0,a),o)));var l=1<<e.length-1;a=-1;for(var c,h,u=e.length+t.length,f,g=0;g<e.length;g++){for(c=0,h=u;c<h;)s(g,n+h)<=o?c=h:u=h,h=Math.floor((u-c)/2+c);u=h;var m=Math.max(1,n-h+1),v=Math.min(n+h,t.length)+e.length,x=Array(v+2);x[v+1]=(1<<g)-1;for(var w=v;w>=m;w--){var A=r[t.charAt(w-1)];if(g===0?x[w]=(x[w+1]<<1|1)&A:x[w]=(x[w+1]<<1|1)&A|((f[w+1]|f[w])<<1|1)|f[w+1],x[w]&l){var b=s(g,w-1);if(b<=o)if(o=b,a=w-1,a>n)m=Math.max(1,2*n-a);else break}}if(s(g+1,n)>o)break;f=x}return a};d.prototype.match_alphabet_=function(t){for(var e={},n=0;n<t.length;n++)e[t.charAt(n)]=0;for(var n=0;n<t.length;n++)e[t.charAt(n)]|=1<<t.length-n-1;return e};d.prototype.patch_addContext_=function(t,e){if(e.length!=0){if(t.start2===null)throw Error("patch not initialized");for(var n=e.substring(t.start2,t.start2+t.length1),r=0;e.indexOf(n)!=e.lastIndexOf(n)&&n.length<this.Match_MaxBits-this.Patch_Margin-this.Patch_Margin;)r+=this.Patch_Margin,n=e.substring(t.start2-r,t.start2+t.length1+r);r+=this.Patch_Margin;var i=e.substring(t.start2-r,t.start2);i&&t.diffs.unshift(new d.Diff(k,i));var s=e.substring(t.start2+t.length1,t.start2+t.length1+r);s&&t.diffs.push(new d.Diff(k,s)),t.start1-=i.length,t.start2-=i.length,t.length1+=i.length+s.length,t.length2+=i.length+s.length}};d.prototype.patch_make=function(t,e,n){var r,i;if(typeof t=="string"&&typeof e=="string"&&typeof n>"u")r=t,i=this.diff_main(r,e,!0),i.length>2&&(this.diff_cleanupSemantic(i),this.diff_cleanupEfficiency(i));else if(t&&typeof t=="object"&&typeof e>"u"&&typeof n>"u")i=t,r=this.diff_text1(i);else if(typeof t=="string"&&e&&typeof e=="object"&&typeof n>"u")r=t,i=e;else if(typeof t=="string"&&typeof e=="string"&&n&&typeof n=="object")r=t,i=n;else throw new Error("Unknown call format to patch_make.");if(i.length===0)return[];for(var s=[],o=new d.patch_obj,a=0,l=0,c=0,h=r,u=r,f=0;f<i.length;f++){var g=i[f][0],m=i[f][1];switch(!a&&g!==k&&(o.start1=l,o.start2=c),g){case T:o.diffs[a++]=i[f],o.length2+=m.length,u=u.substring(0,c)+m+u.substring(c);break;case C:o.length1+=m.length,o.diffs[a++]=i[f],u=u.substring(0,c)+u.substring(c+m.length);break;case k:m.length<=2*this.Patch_Margin&&a&&i.length!=f+1?(o.diffs[a++]=i[f],o.length1+=m.length,o.length2+=m.length):m.length>=2*this.Patch_Margin&&a&&(this.patch_addContext_(o,h),s.push(o),o=new d.patch_obj,a=0,h=u,l=c);break}g!==T&&(l+=m.length),g!==C&&(c+=m.length)}return a&&(this.patch_addContext_(o,h),s.push(o)),s};d.prototype.patch_deepCopy=function(t){for(var e=[],n=0;n<t.length;n++){var r=t[n],i=new d.patch_obj;i.diffs=[];for(var s=0;s<r.diffs.length;s++)i.diffs[s]=new d.Diff(r.diffs[s][0],r.diffs[s][1]);i.start1=r.start1,i.start2=r.start2,i.length1=r.length1,i.length2=r.length2,e[n]=i}return e};d.prototype.patch_apply=function(t,e){if(t.length==0)return[e,[]];t=this.patch_deepCopy(t);var n=this.patch_addPadding(t);e=n+e+n,this.patch_splitMax(t);for(var r=0,i=[],s=0;s<t.length;s++){var o=t[s].start2+r,a=this.diff_text1(t[s].diffs),l,c=-1;if(a.length>this.Match_MaxBits?(l=this.match_main(e,a.substring(0,this.Match_MaxBits),o),l!=-1&&(c=this.match_main(e,a.substring(a.length-this.Match_MaxBits),o+a.length-this.Match_MaxBits),(c==-1||l>=c)&&(l=-1))):l=this.match_main(e,a,o),l==-1)i[s]=!1,r-=t[s].length2-t[s].length1;else{i[s]=!0,r=l-o;var h;if(c==-1?h=e.substring(l,l+a.length):h=e.substring(l,c+this.Match_MaxBits),a==h)e=e.substring(0,l)+this.diff_text2(t[s].diffs)+e.substring(l+a.length);else{var u=this.diff_main(a,h,!1);if(a.length>this.Match_MaxBits&&this.diff_levenshtein(u)/a.length>this.Patch_DeleteThreshold)i[s]=!1;else{this.diff_cleanupSemanticLossless(u);for(var f=0,g,m=0;m<t[s].diffs.length;m++){var v=t[s].diffs[m];v[0]!==k&&(g=this.diff_xIndex(u,f)),v[0]===T?e=e.substring(0,l+g)+v[1]+e.substring(l+g):v[0]===C&&(e=e.substring(0,l+g)+e.substring(l+this.diff_xIndex(u,f+v[1].length))),v[0]!==C&&(f+=v[1].length)}}}}}return e=e.substring(n.length,e.length-n.length),[e,i]};d.prototype.patch_addPadding=function(t){for(var e=this.Patch_Margin,n="",r=1;r<=e;r++)n+=String.fromCharCode(r);for(var r=0;r<t.length;r++)t[r].start1+=e,t[r].start2+=e;var i=t[0],s=i.diffs;if(s.length==0||s[0][0]!=k)s.unshift(new d.Diff(k,n)),i.start1-=e,i.start2-=e,i.length1+=e,i.length2+=e;else if(e>s[0][1].length){var o=e-s[0][1].length;s[0][1]=n.substring(s[0][1].length)+s[0][1],i.start1-=o,i.start2-=o,i.length1+=o,i.length2+=o}if(i=t[t.length-1],s=i.diffs,s.length==0||s[s.length-1][0]!=k)s.push(new d.Diff(k,n)),i.length1+=e,i.length2+=e;else if(e>s[s.length-1][1].length){var o=e-s[s.length-1][1].length;s[s.length-1][1]+=n.substring(0,o),i.length1+=o,i.length2+=o}return n};d.prototype.patch_splitMax=function(t){for(var e=this.Match_MaxBits,n=0;n<t.length;n++)if(!(t[n].length1<=e)){var r=t[n];t.splice(n--,1);for(var i=r.start1,s=r.start2,o="";r.diffs.length!==0;){var a=new d.patch_obj,l=!0;for(a.start1=i-o.length,a.start2=s-o.length,o!==""&&(a.length1=a.length2=o.length,a.diffs.push(new d.Diff(k,o)));r.diffs.length!==0&&a.length1<e-this.Patch_Margin;){var c=r.diffs[0][0],h=r.diffs[0][1];c===T?(a.length2+=h.length,s+=h.length,a.diffs.push(r.diffs.shift()),l=!1):c===C&&a.diffs.length==1&&a.diffs[0][0]==k&&h.length>2*e?(a.length1+=h.length,i+=h.length,l=!1,a.diffs.push(new d.Diff(c,h)),r.diffs.shift()):(h=h.substring(0,e-a.length1-this.Patch_Margin),a.length1+=h.length,i+=h.length,c===k?(a.length2+=h.length,s+=h.length):l=!1,a.diffs.push(new d.Diff(c,h)),h==r.diffs[0][1]?r.diffs.shift():r.diffs[0][1]=r.diffs[0][1].substring(h.length))}o=this.diff_text2(a.diffs),o=o.substring(o.length-this.Patch_Margin);var u=this.diff_text1(r.diffs).substring(0,this.Patch_Margin);u!==""&&(a.length1+=u.length,a.length2+=u.length,a.diffs.length!==0&&a.diffs[a.diffs.length-1][0]===k?a.diffs[a.diffs.length-1][1]+=u:a.diffs.push(new d.Diff(k,u))),l||t.splice(++n,0,a)}}};d.prototype.patch_toText=function(t){for(var e=[],n=0;n<t.length;n++)e[n]=t[n];return e.join("")};d.prototype.patch_fromText=function(t){var e=[];if(!t)return e;for(var n=t.split(`
4
+ `),r=0,i=/^@@ -(\d+),?(\d*) \+(\d+),?(\d*) @@$/;r<n.length;){var s=n[r].match(i);if(!s)throw new Error("Invalid patch string: "+n[r]);var o=new d.patch_obj;for(e.push(o),o.start1=parseInt(s[1],10),s[2]===""?(o.start1--,o.length1=1):s[2]=="0"?o.length1=0:(o.start1--,o.length1=parseInt(s[2],10)),o.start2=parseInt(s[3],10),s[4]===""?(o.start2--,o.length2=1):s[4]=="0"?o.length2=0:(o.start2--,o.length2=parseInt(s[4],10)),r++;r<n.length;){var a=n[r].charAt(0);try{var l=decodeURI(n[r].substring(1))}catch{throw new Error("Illegal escape in patch_fromText: "+l)}if(a=="-")o.diffs.push(new d.Diff(C,l));else if(a=="+")o.diffs.push(new d.Diff(T,l));else if(a==" ")o.diffs.push(new d.Diff(k,l));else{if(a=="@")break;if(a!=="")throw new Error('Invalid patch mode "'+a+'" in: '+l)}r++}}return e};d.patch_obj=function(){this.diffs=[],this.start1=null,this.start2=null,this.length1=0,this.length2=0};d.patch_obj.prototype.toString=function(){var t,e;this.length1===0?t=this.start1+",0":this.length1==1?t=this.start1+1:t=this.start1+1+","+this.length1,this.length2===0?e=this.start2+",0":this.length2==1?e=this.start2+1:e=this.start2+1+","+this.length2;for(var n=["@@ -"+t+" +"+e+` @@
5
+ `],r,i=0;i<this.diffs.length;i++){switch(this.diffs[i][0]){case T:r="+";break;case C:r="-";break;case k:r=" ";break}n[i+1]=r+encodeURI(this.diffs[i][1])+`
6
+ `}return n.join("").replace(/%20/g," ")};me.exports=d;me.exports.diff_match_patch=d;me.exports.DIFF_DELETE=C;me.exports.DIFF_INSERT=T;me.exports.DIFF_EQUAL=k});import{hostname as bi}from"node:os";import{resolve as ki}from"node:path";import{createRequire as rr}from"module";var ir=rr("/"),fe,sr,or;try{fe=ir("worker_threads"),sr=fe.Worker,or=fe.isMarkedAsUntransferable}catch{}var N=Uint8Array,K=Uint16Array,at=Int32Array,ze=new N([0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0,0]),Oe=new N([0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,0,0]),rt=new N([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]),Dt=function(t,e){for(var n=new K(31),r=0;r<31;++r)n[r]=e+=1<<t[r-1];for(var i=new at(n[30]),r=1;r<30;++r)for(var s=n[r];s<n[r+1];++s)i[s]=s-n[r]<<5|r;return{b:n,r:i}},fe=Dt(ze,2),Ut=fe.b,it=fe.r;Ut[28]=258,it[258]=28;var zt=Dt(Oe,0),ar=zt.b,Tt=zt.r,st=new K(32768);for(_=0;_<32768;++_)ee=(_&43690)>>1|(_&21845)<<1,ee=(ee&52428)>>2|(ee&13107)<<2,ee=(ee&61680)>>4|(ee&3855)<<4,st[_]=((ee&65280)>>8|(ee&255)<<8)>>1;var ee,_,Y=(function(t,e,n){for(var r=t.length,i=0,s=new K(e);i<r;++i)t[i]&&++s[t[i]-1];var o=new K(e);for(i=1;i<e;++i)o[i]=o[i-1]+s[i-1]<<1;var a;if(n){a=new K(1<<e);var l=15-e;for(i=0;i<r;++i)if(t[i])for(var c=i<<4|t[i],h=e-t[i],u=o[t[i]-1]++<<h,f=u|(1<<h)-1;u<=f;++u)a[st[u]>>l]=c}else for(a=new K(r),i=0;i<r;++i)t[i]&&(a[i]=st[o[t[i]-1]++]>>15-t[i]);return a}),ie=new N(288);for(_=0;_<144;++_)ie[_]=8;var _;for(_=144;_<256;++_)ie[_]=9;var _;for(_=256;_<280;++_)ie[_]=7;var _;for(_=280;_<288;++_)ie[_]=8;var _,Ee=new N(32);for(_=0;_<32;++_)Ee[_]=5;var _,lr=Y(ie,9,0),hr=Y(ie,9,1),cr=Y(Ee,5,0),ur=Y(Ee,5,1),et=function(t){for(var e=t[0],n=1;n<t.length;++n)t[n]>e&&(e=t[n]);return e},q=function(t,e,n){var r=e/8|0;return(t[r]|t[r+1]<<8)>>(e&7)&n},tt=function(t,e){var n=e/8|0;return(t[n]|t[n+1]<<8|t[n+2]<<16)>>(e&7)},lt=function(t){return(t+7)/8|0},Ot=function(t,e,n){return(e==null||e<0)&&(e=0),(n==null||n>t.length)&&(n=t.length),new N(t.subarray(e,n))};var fr=["unexpected EOF","invalid block type","invalid length/literal","invalid distance","stream finished","no stream handler",,"no callback","invalid UTF-8 data","extra field too long","date not in range 1980-2099","filename too long","stream finishing","invalid zip data"],ne=function(t,e,n){var r=new Error(e||fr[t]);if(r.code=t,Error.captureStackTrace&&Error.captureStackTrace(r,ne),!n)throw r;return r},dr=function(t,e,n,r){var i=t.length,s=r?r.length:0;if(!i||e.f&&!e.l)return n||new N(0);var o=!n,a=o||e.i!=2,l=e.i;o&&(n=new N(i*3));var c=function(we){var be=n.length;if(we>be){var ue=new N(Math.max(be*2,we));ue.set(n),n=ue}},h=e.f||0,u=e.p||0,f=e.b||0,g=e.l,m=e.d,v=e.m,x=e.n,w=i*8;do{if(!g){h=q(t,u,1);var A=q(t,u+1,3);if(u+=3,A)if(A==1)g=hr,m=ur,v=9,x=5;else if(A==2){var $=q(t,u,31)+257,E=q(t,u+10,15)+4,y=$+q(t,u+5,31)+1;u+=14;for(var p=new N(y),U=new N(19),D=0;D<E;++D)U[rt[D]]=q(t,u+D*3,7);u+=E*3;for(var F=et(U),re=(1<<F)-1,W=Y(U,F,1),D=0;D<y;){var B=W[q(t,u,re)];u+=B&15;var b=B>>4;if(b<16)p[D++]=b;else{var z=0,R=0;for(b==16?(R=3+q(t,u,3),u+=2,z=p[D-1]):b==17?(R=3+q(t,u,7),u+=3):b==18&&(R=11+q(t,u,127),u+=7);R--;)p[D++]=z}}var L=p.subarray(0,$),O=p.subarray($);v=et(L),x=et(O),g=Y(L,v,1),m=Y(O,x,1)}else ne(1);else{var b=lt(u)+4,S=t[b-4]|t[b-3]<<8,M=b+S;if(M>i){l&&ne(0);break}a&&c(f+S),n.set(t.subarray(b,M),f),e.b=f+=S,e.p=u=M*8,e.f=h;continue}if(u>w){l&&ne(0);break}}a&&c(f+131072);for(var ye=(1<<v)-1,G=(1<<x)-1,Q=u;;Q=u){var z=g[tt(t,u)&ye],V=z>>4;if(u+=z&15,u>w){l&&ne(0);break}if(z||ne(2),V<256)n[f++]=V;else if(V==256){Q=u,g=null;break}else{var J=V-254;if(V>264){var D=V-257,I=ze[D];J=q(t,u,(1<<I)-1)+Ut[D],u+=I}var X=m[tt(t,u)&G],he=X>>4;X||ne(3),u+=X&15;var O=ar[he];if(he>3){var I=Oe[he];O+=tt(t,u)&(1<<I)-1,u+=I}if(u>w){l&&ne(0);break}a&&c(f+131072);var ce=f+J;if(f<O){var De=s-O,Ue=Math.min(O,ce);for(De+f<0&&ne(3);f<Ue;++f)n[f]=r[De+f]}for(;f<ce;++f)n[f]=n[f-O]}}e.l=g,e.p=Q,e.b=f,e.f=h,g&&(h=1,e.m=v,e.d=m,e.n=x)}while(!h);return f!=n.length&&o?Ot(n,0,f):n.subarray(0,f)},te=function(t,e,n){n<<=e&7;var r=e/8|0;t[r]|=n,t[r+1]|=n>>8},ke=function(t,e,n){n<<=e&7;var r=e/8|0;t[r]|=n,t[r+1]|=n>>8,t[r+2]|=n>>16},nt=function(t,e){for(var n=[],r=0;r<t.length;++r)t[r]&&n.push({s:r,f:t[r]});var i=n.length,s=n.slice();if(!i)return{t:Nt,l:0};if(i==1){var o=new N(n[0].s+1);return o[n[0].s]=1,{t:o,l:1}}n.sort(function(M,$){return M.f-$.f}),n.push({s:-1,f:25001});var a=n[0],l=n[1],c=0,h=1,u=2;for(n[0]={s:-1,f:a.f+l.f,l:a,r:l};h!=i-1;)a=n[n[c].f<n[u].f?c++:u++],l=n[c!=h&&n[c].f<n[u].f?c++:u++],n[h++]={s:-1,f:a.f+l.f,l:a,r:l};for(var f=s[0].s,r=1;r<i;++r)s[r].s>f&&(f=s[r].s);var g=new K(f+1),m=ot(n[h-1],g,0);if(m>e){var r=0,v=0,x=m-e,w=1<<x;for(s.sort(function($,E){return g[E.s]-g[$.s]||$.f-E.f});r<i;++r){var A=s[r].s;if(g[A]>e)v+=w-(1<<m-g[A]),g[A]=e;else break}for(v>>=x;v>0;){var b=s[r].s;g[b]<e?v-=1<<e-g[b]++-1:++r}for(;r>=0&&v;--r){var S=s[r].s;g[S]==e&&(--g[S],++v)}m=e}return{t:new N(g),l:m}},ot=function(t,e,n){return t.s==-1?Math.max(ot(t.l,e,n+1),ot(t.r,e,n+1)):e[t.s]=n},Rt=function(t){for(var e=t.length;e&&!t[--e];);for(var n=new K(++e),r=0,i=t[0],s=1,o=function(l){n[r++]=l},a=1;a<=e;++a)if(t[a]==i&&a!=e)++s;else{if(!i&&s>2){for(;s>138;s-=138)o(32754);s>2&&(o(s>10?s-11<<5|28690:s-3<<5|12305),s=0)}else if(s>3){for(o(i),--s;s>6;s-=6)o(8304);s>2&&(o(s-3<<5|8208),s=0)}for(;s--;)o(i);s=1,i=t[a]}return{c:n.subarray(0,r),n:e}},Se=function(t,e){for(var n=0,r=0;r<e.length;++r)n+=t[r]*e[r];return n},Ft=function(t,e,n){var r=n.length,i=lt(e+2);t[i]=r&255,t[i+1]=r>>8,t[i+2]=t[i]^255,t[i+3]=t[i+1]^255;for(var s=0;s<r;++s)t[i+s+4]=n[s];return(i+4+r)*8},It=function(t,e,n,r,i,s,o,a,l,c,h){te(e,h++,n),++i[256];for(var u=nt(i,15),f=u.t,g=u.l,m=nt(s,15),v=m.t,x=m.l,w=Rt(f),A=w.c,b=w.n,S=Rt(v),M=S.c,$=S.n,E=new K(19),y=0;y<A.length;++y)++E[A[y]&31];for(var y=0;y<M.length;++y)++E[M[y]&31];for(var p=nt(E,7),U=p.t,D=p.l,F=19;F>4&&!U[rt[F-1]];--F);var re=c+5<<3,W=Se(i,ie)+Se(s,Ee)+o,B=Se(i,f)+Se(s,v)+o+14+3*F+Se(E,U)+2*E[16]+3*E[17]+7*E[18];if(l>=0&&re<=W&&re<=B)return Ft(e,h,t.subarray(l,l+c));var z,R,L,O;if(te(e,h,1+(B<W)),h+=2,B<W){z=Y(f,g,0),R=f,L=Y(v,x,0),O=v;var ye=Y(U,D,0);te(e,h,b-257),te(e,h+5,$-1),te(e,h+10,F-4),h+=14;for(var y=0;y<F;++y)te(e,h+3*y,U[rt[y]]);h+=3*F;for(var G=[A,M],Q=0;Q<2;++Q)for(var V=G[Q],y=0;y<V.length;++y){var J=V[y]&31;te(e,h,ye[J]),h+=U[J],J>15&&(te(e,h,V[y]>>5&127),h+=V[y]>>12)}}else z=lr,R=ie,L=cr,O=Ee;for(var y=0;y<a;++y){var I=r[y];if(I>255){var J=I>>18&31;ke(e,h,z[J+257]),h+=R[J+257],J>7&&(te(e,h,I>>23&31),h+=ze[J]);var X=I&31;ke(e,h,L[X]),h+=O[X],X>3&&(ke(e,h,I>>5&8191),h+=Oe[X])}else ke(e,h,z[I]),h+=R[I]}return ke(e,h,z[256]),h+R[256]},gr=new at([65540,131080,131088,131104,262176,1048704,1048832,2114560,2117632]),Nt=new N(0),mr=function(t,e,n,r,i,s){var o=s.z||t.length,a=new N(r+o+5*(1+Math.ceil(o/7e3))+i),l=a.subarray(r,a.length-i),c=s.l,h=(s.r||0)&7;if(e){h&&(l[0]=s.r>>3);for(var u=gr[e-1],f=u>>13,g=u&8191,m=(1<<n)-1,v=s.p||new K(32768),x=s.h||new K(m+1),w=Math.ceil(n/3),A=2*w,b=function(Qe){return(t[Qe]^t[Qe+1]<<w^t[Qe+2]<<A)&m},S=new at(25e3),M=new K(288),$=new K(32),E=0,y=0,p=s.i||0,U=0,D=s.w||0,F=0;p+2<o;++p){var re=b(p),W=p&32767,B=x[re];if(v[W]=B,x[re]=W,D<=p){var z=o-p;if((E>7e3||U>24576)&&(z>423||!c)){h=It(t,l,0,S,M,$,y,U,F,p-F,h),U=E=y=0,F=p;for(var R=0;R<286;++R)M[R]=0;for(var R=0;R<30;++R)$[R]=0}var L=2,O=0,ye=g,G=W-B&32767;if(z>2&&re==b(p-G))for(var Q=Math.min(f,z)-1,V=Math.min(32767,p),J=Math.min(258,z);G<=V&&--ye&&W!=B;){if(t[p+L]==t[p+L-G]){for(var I=0;I<J&&t[p+I]==t[p+I-G];++I);if(I>L){if(L=I,O=G,I>Q)break;for(var X=Math.min(G,I-2),he=0,R=0;R<X;++R){var ce=p-G+R&32767,De=v[ce],Ue=ce-De&32767;Ue>he&&(he=Ue,B=ce)}}}W=B,B=v[W],G+=W-B&32767}if(O){S[U++]=268435456|it[L]<<18|Tt[O];var we=it[L]&31,be=Tt[O]&31;y+=ze[we]+Oe[be],++M[257+we],++$[be],D=p+L,++E}else S[U++]=t[p],++M[t[p]]}}for(p=Math.max(p,D);p<o;++p)S[U++]=t[p],++M[t[p]];h=It(t,l,c,S,M,$,y,U,F,p-F,h),c||(s.r=h&7|l[h/8|0]<<3,h-=7,s.h=x,s.p=v,s.i=p,s.w=D)}else{for(var p=s.w||0;p<o+c;p+=65535){var ue=p+65535;ue>=o&&(l[h/8|0]=c,ue=o),h=Ft(l,h+1,t.subarray(p,ue))}s.i=o}return Ot(a,0,r+lt(h)+i)};var vr=function(t,e,n,r,i){if(!i&&(i={l:1},e.dictionary)){var s=e.dictionary.subarray(-32768),o=new N(s.length+t.length);o.set(s),o.set(t,s.length),t=o,i.w=s.length}return mr(t,e.level==null?6:e.level,e.mem==null?i.l?Math.ceil(Math.max(8,Math.min(13,Math.log(t.length)))*1.5):20:12+e.mem,n,r,i)};function ht(t,e){return vr(t,e||{},0,0)}function Bt(t,e){return dr(t,{i:2},e&&e.out,e&&e.dictionary)}var pr=typeof TextDecoder<"u"&&new TextDecoder,yr=0;try{pr.decode(Nt,{stream:!0}),yr=1}catch{}var Wt="basalt/hkdf-aes-gcm/1",oe=12,Ne=128,Vt=oe+Ne/8+1,Z=20,Jt=new TextEncoder,wr=new TextDecoder,Fe={auth:"basalt/auth/1",path:"basalt/path/1",content:"basalt/content/1",nonce:"basalt/nonce/1"};function Ae(){let t=globalThis.crypto;if(!t?.subtle)throw new Error("WebCrypto is unavailable, so this vault cannot be opened");return t.subtle}function Kt(){let t=globalThis.crypto;if(!t?.getRandomValues)throw new Error("no secure random source is available, so a vault cannot be created here");return t.getRandomValues(new Uint8Array(Z))}async function Ht(t){if(t.length<16)throw new Error(`root secret is ${t.length} bytes, need at least 16`);let e=Ae(),n=await e.importKey("raw",ae(t),"HKDF",!1,["deriveKey","deriveBits"]),r=l=>({name:"HKDF",hash:"SHA-256",salt:new Uint8Array(0),info:Jt.encode(l)}),[i,s,o,a]=await Promise.all([e.deriveBits(r(Fe.auth),n,256),e.deriveKey(r(Fe.path),n,{name:"AES-GCM",length:256},!1,["encrypt","decrypt"]),e.deriveKey(r(Fe.content),n,{name:"AES-GCM",length:256},!1,["encrypt","decrypt"]),e.deriveKey(r(Fe.nonce),n,{name:"HMAC",hash:"SHA-256"},!1,["sign"])]);return{auth:new Uint8Array(i),path:s,content:o,nonce:a}}async function jt(t,e,n){let r=Ae(),i=await br(e,n),s=await r.encrypt({name:"AES-GCM",iv:ae(i),tagLength:Ne},t,ae(n)),o=new Uint8Array(oe+s.byteLength);return o.set(i,0),o.set(new Uint8Array(s),oe),o}async function Gt(t,e){if(e.length<oe+Ne/8)throw new Error(`sealed value is ${e.length} bytes, too short to contain a nonce and a tag`);let n=Ae(),r=e.subarray(0,oe),i=e.subarray(oe);try{let s=await n.decrypt({name:"AES-GCM",iv:ae(r),tagLength:Ne},t,ae(i));return new Uint8Array(s)}catch(s){throw new Error("sealed value failed authentication, so it is not what was stored",{cause:s})}}async function br(t,e){let n=await Ae().sign("HMAC",t,ae(e));return new Uint8Array(n,0,oe)}async function Be(t,e){return xe(await jt(t.path,t.nonce,Jt.encode(e)))}async function Le(t,e){let n=await Gt(t.path,We(e));return wr.decode(n)}var qt=0,Zt=1;async function kr(t,e){let n=Sr(e)?ht(e,{level:6}):void 0,r=n!==void 0&&n.length<e.length,i=r?n:e,s=new Uint8Array(1+i.length);return s[0]=r?Zt:qt,s.set(i,1),jt(t.content,t.nonce,s)}function Sr(t){if(t.length===0)return!1;if(t.length<=Lt*2)return!0;let e=t.subarray(0,Lt);return ht(e,{level:6}).length<e.length}var Lt=4096;async function ge(t,e){return Promise.all([...e].map(async n=>{let r=await kr(t,n);return{name:await ct(r),bytes:r}}))}async function Xt(t,e){let n=await Gt(t.content,e);if(n.length===0)throw new Error("sealed chunk carries no marker byte");let r=n[0],i=n.subarray(1);if(r===qt)return i;if(r===Zt)try{return Bt(i)}catch(s){throw new Error("sealed chunk claims to be deflated and is not",{cause:s})}throw new Error(`sealed chunk has an unknown marker byte ${r}`)}async function ct(t){let e=await Ae().digest("SHA-256",ae(t));return Er(new Uint8Array(e))}function Yt(t){return xe(t.auth)}function ae(t){return t.slice().buffer}function Er(t){let e="";for(let n of t)e+=n.toString(16).padStart(2,"0");return e}var de="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";function xe(t){let e="";for(let n=0;n<t.length;n+=3){let r=t[n],i=n+1<t.length?t[n+1]:void 0,s=n+2<t.length?t[n+2]:void 0;if(e+=de[r>>2],e+=de[(r&3)<<4|(i??0)>>4],i===void 0||(e+=de[(i&15)<<2|(s??0)>>6],s===void 0))break;e+=de[s&63]}return e}var Ar=(()=>{let t=new Int16Array(128).fill(-1);for(let e=0;e<de.length;e++)t[de.charCodeAt(e)]=e;return t})();function We(t){let e=t.length,n=new Uint8Array(Math.floor(e*3/4)),r=0,i=0,s=0;for(let o=0;o<e;o++){let a=t.charCodeAt(o),l=a<128?Ar[a]:-1;if(l<0)throw new Error(`invalid base64url character ${JSON.stringify(t[o])} at position ${o}`);i=i<<6|l,s+=6,s>=8&&(s-=8,n[r++]=i>>s&255)}return n.subarray(0,r)}var se=48,le=31,Qt=1,en={min:512,avg:1024,max:4096},xr=64,Pr=en.avg,$r=64*1024;function Mr(t){let e=Math.sqrt(xr*Math.max(t,1)),n=Math.min($r,Math.max(Pr,Math.round(e/512)*512));return{min:Math.max(en.min,n/2),avg:n,max:n*4}}var ut={min:128*1024,avg:256*1024,max:1024*1024},_r=4*1024*1024;function tn(t,e,n=ut.max){(!Number.isFinite(n)||n<=0)&&(n=ut.max);let r=e&&t<_r?Mr(t):ut,i=Math.min(r.max,n-Vt),s=Math.max(i,se*4);return{min:Math.min(r.min,s),avg:Math.min(r.avg,s),max:s}}function nn(t,e,n){let r=n-1;for(;r>e&&(t[r]&192)===128;)r--;if(r<e)return n;let i=t[r],s=i<128?1:(i&224)===192?2:(i&240)===224?3:(i&248)===240?4:1;return n-r>=s?n:r>e?r:n}function*rn(t,e,n){let{min:r,avg:i,max:s}=e,o=t.length,a=1;for(let h=0;h<se-1;h++)a=Math.imul(a,le);let l=0,c=0;for(let h=0;h<o;h++){let u=t[h];h>=l+se?(c=c-Math.imul(t[h-se],a)|0,c=Math.imul(c,le),c=c+u|0):(c=Math.imul(c,le),c=c+u|0);let f=h-l+1,g=f>=r&&(c>>>0)%i===Qt;if(f>=s&&(g=!0),g){let m=n?nn(t,l,h+1):h+1;yield{offset:l,bytes:t.subarray(l,m)},l=m,c=0,h=m-1}}l<o&&(yield{offset:l,bytes:t.subarray(l,o)})}async function*sn(t,e,n){let{min:r,avg:i,max:s}=e,o=1;for(let f=0;f<se-1;f++)o=Math.imul(o,le);let a=new Uint8Array(Math.max(s,se*2)),l=0,c=0,h=0,u=()=>{let f=n?nn(a,0,l):l,g={offset:h,bytes:a.slice(0,f)};h+=f;let m=l-f;a.copyWithin(0,f,l),l=m,c=0;for(let v=0;v<m;v++)c=Math.imul(c,le),c=c+a[v]|0;return g};for await(let f of t)for(let g=0;g<f.length;g++){let m=f[g];a[l++]=m,l>=se+1?(c=c-Math.imul(a[l-1-se],o)|0,c=Math.imul(c,le),c=c+m|0):(c=Math.imul(c,le),c=c+m|0),(l>=s||l>=r&&(c>>>0)%i===Qt)&&(yield u())}if(l>0){let f={offset:h,bytes:a.slice(0,l)};h+=l,l=0,yield f}}var Cr=new Set(["md","txt","canvas","json","csv","yml","yaml","xml","html","css","js","ts","svg","bib","tex"]);function on(t){let e=t.lastIndexOf(".");return e<0?!1:Cr.has(t.slice(e+1).toLowerCase())}var Tr=new Set(["canvas","json"]);function an(t){let e=t.lastIndexOf(".");return e<0?!1:Tr.has(t.slice(e+1).toLowerCase())}var un=nr(ln(),1),Rr=-1,Ir=0,Dr=1;function hn(t){let e=[],n=0;for(let[r,i]of t)r===Ir?n+=i.length:r===Rr?(e.push({start:n,end:n+i.length}),n+=i.length):e.push({start:n,end:n});return e}function Ur(t,e){for(let n of t)for(let r of e){let i=n.start===n.end,s=r.start===r.end;if(!(i&&s)){if(i){if(r.start<n.start&&n.start<r.end)return n;continue}if(s){if(n.start<r.start&&r.start<n.end)return r;continue}if(n.start<r.end&&r.start<n.end)return n}}}function fn(t,e,n,r=()=>!0){if(e===n)return{kind:"take",text:e,why:"both sides already agree"};if(t===e)return{kind:"take",text:n,why:"no local change since the last sync"};if(t===n)return{kind:"take",text:e,why:"no remote change since the last sync"};let i=new un.diff_match_patch,s=i.diff_main(t,e,!0,0);s.length>2&&(i.diff_cleanupSemantic(s),i.diff_cleanupEfficiency(s));let o=i.diff_main(t,n,!0,0);o.length>2&&(i.diff_cleanupSemantic(o),i.diff_cleanupEfficiency(o));let a=Ur(hn(s),hn(o));if(a!==void 0)return{kind:"conflict",why:`both devices changed the same text, at characters ${a.start} to ${a.end} of the last synced version`};let l=cn(i,t,s,n),c=cn(i,t,o,e);if(l.failed>0||c.failed>0){let u=Math.max(l.failed,c.failed),f=Math.max(l.total,c.total);return{kind:"conflict",why:`${u} of ${f} changes could not be placed in the other version`}}if(!zr(l.text,c.text))return{kind:"conflict",why:"merging the two versions in either order gives different content, so at least one change was placed wrongly"};let h=Or(s,l.text);return h!==void 0?{kind:"conflict",why:`the merge reported success but ${Fr(h)} is not in the result`}:r(l.text)?{kind:"merged",text:l.text}:{kind:"conflict",why:"both sides merged cleanly and the result is no longer a valid file of its kind"}}function zr(t,e){if(t===e)return!0;let n=t.split(`
7
7
  `).sort(),r=e.split(`
8
- `).sort();if(t.length!==r.length)return!1;for(let i=0;i<t.length;i++)if(t[i]!==r[i])return!1;return!0}function ln(n,e,t,r){let[i,s]=n.patch_apply(n.patch_make(e,t),r);return{text:i,failed:s.filter(o=>!o).length,total:s.length}}function Ur(n,e){for(let[t,r]of n)if(t===Rr&&!e.includes(r))return r}function Dr(n){let e=n.replace(/\s+/g," ").trim(),t=e.length>60?`${e.slice(0,57)}...`:e;return`a local edit (${JSON.stringify(t)})`}function un(n,e,t){let r=n.lastIndexOf("."),i=n.lastIndexOf("/"),s=r>i,o=s?n.slice(0,r):n,a=s?n.slice(r):"",l=(h,u=2)=>String(h).padStart(u,"0"),c=`${t.getFullYear()}${l(t.getMonth()+1)}${l(t.getDate())}${l(t.getHours())}${l(t.getMinutes())}`;return`${o} (Conflicted copy ${Or(e)} ${c})${a}`}function Or(n){return n.replace(/[-\\/:*?"<>|\s]/g,"-").replace(/-{2,}/g,"-").replace(/^[.\-\s]+|[.\-\s]+$/g,"").slice(0,32)||"device"}function ft(n){return{path:n,prev:"",folder:!1,ctime:0,mtime:0,size:0,hash:"",chunks:[],synchash:"",syncuid:0,synctime:0}}function fn(n){let{local:e,remote:t,index:r,mergeable:i}=n,s=r.synchash;return e?.folder||t?.folder?Fr(e,t):e===void 0&&(t===void 0||t.deleted)?{kind:"nothing",why:"absent on both sides"}:t===void 0?{kind:"upload",why:"new file, the server has never held this path"}:e===void 0?Nr(t,r):t.deleted?e.hash===s&&s!==""?{kind:"deleteLocal",why:"deleted on another device and unchanged here"}:s===""?{kind:"upload",why:"deleted on the server but never synced from here"}:{kind:"upload",why:"deleted on another device but edited here, so the edit is kept and re-sent"}:e.hash===t.hash?{kind:"nothing",why:"the two sides hold the same content"}:s===""?{kind:"conflict",why:"both sides have content and there is no last-synced version to merge from"}:e.hash===s?{kind:"download",why:"changed on another device and unchanged here"}:t.hash===s?{kind:"upload",why:"changed here and unchanged on the server"}:i?{kind:"merge",why:"changed on both sides since the last sync"}:{kind:"conflict",why:"changed on both sides and this file cannot be merged"}}function Fr(n,e){return n!==void 0&&n.folder?e===void 0?{kind:"upload",why:"new folder, the server has never held this path"}:e.deleted?{kind:"nothing",why:"folder deleted elsewhere; its files decide"}:e.folder?{kind:"nothing",why:"folder exists on both sides"}:{kind:"clash",why:"a folder here and a file of the same name on another device"}:e?.folder&&!e.deleted?n!==void 0?{kind:"clash",why:"a file here and a folder of the same name on another device"}:{kind:"createLocalFolder",why:"folder exists on the server and not here"}:{kind:"nothing",why:"folder absent on both sides"}}function Nr(n,e){let t=e.synchash;return n.deleted?{kind:"nothing",why:"deleted on both sides"}:t===""?{kind:"download",why:"new on the server"}:n.hash===t?{kind:"deleteRemote",why:"deleted here and unchanged on the server"}:{kind:"restoreLocal",why:"deleted here but changed on another device, so the newer content is restored"}}function dt(n,e,t){return n.hash===""||n.chunks.length===0?!0:n.mtime!==e||n.size!==t}function Pe(n,e){let t=Math.ceil(e.mtime),r=Math.ceil(e.ctime);if(e.folder){n.folder=!0,n.mtime=0,n.ctime=0,n.size=0,n.hash="",n.chunks=[];return}dt(n,t,Br(e))&&(n.hash="",n.chunks=[]),n.folder=!1,n.mtime=t,n.ctime=r,n.size=e.size}function Br(n){return n.size}function dn(n,e,t){n.path=t,n.prev===""&&(n.prev=e),n.prev===t&&(n.prev=""),n.synctime=0}function ve(n,e,t,r,i){n.hash=e,n.chunks=[...t],n.synchash=e,n.syncuid=r,n.synctime=i,n.prev=""}function gn(n,e){if(!n.synctime)return!0;let t=n.size>102400?30:n.size>10240?20:10;return e-n.synctime>t*1e3}var gt=1,mn=6e4,$e=256;function vn(n){return{size:n.size,ctime:n.ctime,mtime:n.mtime,folder:n.folder??!1,deleted:n.deleted??!1,...n.prev?{prev:n.prev}:{}}}var P=class extends Error{constructor(t,r){super(r);this.code=t;this.name="ProtocolError"}code;get fatal(){return["proto","auth","cursor","busy","protostate","badchunk","internal"].includes(this.code)}};function Lr(n){return n.startsWith("wss://")?`. If that server has no TLS in front of it, pair with ws://${n.slice(6)} instead`:""}var j=class extends Error{constructor(e){super(e),this.name="ConnectionError"}},Ve=class{constructor(e,t){this.url=e;this.opts=t}url;opts;socket;replyWaiter;replyTimer;bodyWaiter;bodyQueue=[];expecting=0;requestsSent=0;closed=!1;closeReason;cursor=0;notifying=Promise.resolve();log(e,...t){this.opts.log?.(e,...t)}get appliedCursor(){return this.cursor}async connect(){if(this.socket)throw new Error("already connected");let t=(this.opts.socketFactory??Wr)(this.url);t.binaryType="arraybuffer",this.socket=t,await new Promise((r,i)=>{t.onopen=()=>r(),t.onerror=()=>i(new j(`could not connect to ${this.url}${Lr(this.url)}`)),t.onclose=s=>i(new j(`connection closed before opening: ${pn(s)}`))}),t.onerror=()=>this.die(new j("the connection failed")),t.onclose=r=>this.die(new j(`the connection closed: ${pn(r)}`)),t.onmessage=r=>this.onFrame(r.data)}die(e){if(this.closed)return;this.closed=!0,this.closeReason=e,this.log("transport closed",e.message),this.disarmReply();let t=this.replyWaiter,r=this.bodyWaiter;this.replyWaiter=void 0,this.bodyWaiter=void 0,t?.reject(e),r?.reject(e);try{this.socket?.close()}catch{}try{this.opts.onClosed?.(e)}catch{}}disarmReply(){this.replyTimer!==void 0&&(clearTimeout(this.replyTimer),this.replyTimer=void 0)}close(){this.die(new j("closed by this device"))}get isClosed(){return this.closed}onFrame(e){if(typeof e=="string"){let i;try{i=JSON.parse(e)}catch{this.die(new P("protostate",`server sent a frame that is not JSON: ${e.slice(0,120)}`));return}this.onTextFrame(i);return}let t=Vr(e);if(t===void 0){this.die(new P("protostate","server sent a frame of an unexpected type"));return}let r=this.bodyWaiter;if(r){this.bodyWaiter=void 0,r.resolve(t);return}if(this.bodyQueue.length>=this.expecting){this.die(new P("protostate",`server sent a ${t.length} byte body with nothing outstanding to receive it`));return}this.bodyQueue.push(t)}onTextFrame(e){if(e.op==="batch"){this.queueNotification(()=>this.onBatchFrame(e));return}if(e.op==="caught-up"){let r=H(e.cursor);this.queueNotification(async()=>{if(r!==this.cursor){this.die(new P("protostate",`server says caught up at ${r}, this device reached ${this.cursor}`));return}this.opts.onCaughtUp?.(r)});return}let t=this.replyWaiter;if(!t){this.die(new P("protostate",`server sent an unexpected reply: ${JSON.stringify(e)}`));return}this.replyWaiter=void 0,t.resolve(e)}queueNotification(e){this.notifying=this.notifying.then(e).catch(t=>{this.die(t instanceof Error?t:new Error(String(t)))})}async onBatchFrame(e){let t=H(e.from),r=H(e.to),i=e.entries;if(!Array.isArray(i))throw new P("protostate",`batch ${t} to ${r} carries no entries array, so an empty batch cannot be told from a lost one`);let s=i;if(t!==this.cursor+1)throw new P("protostate",`batch covers ${t} to ${r} but this device has applied up to ${this.cursor}, so something was skipped`);if(r<t)throw new P("protostate",`batch covers an empty range, ${t} to ${r}`);for(let o of s){if(typeof o?.uid!="number"||!Number.isFinite(o.uid))throw new P("protostate",`batch ${t}..${r} contains an entry with no uid`);if(typeof o.path!="string"||o.path==="")throw new P("protostate",`batch ${t}..${r} contains uid ${o.uid} with no path`);if(!Array.isArray(o.chunks))throw new P("protostate",`batch ${t}..${r} contains uid ${o.uid} with no chunks array`);if(o.uid<t||o.uid>r)throw new P("protostate",`batch ${t}..${r} contains uid ${o.uid}`)}await this.opts.onBatch({from:t,to:r,entries:s}),this.cursor=r}send(e){if(this.closed||!this.socket)throw this.closeReason??new j("not connected");this.socket.send(JSON.stringify(e))}sendBody(e){if(this.closed||!this.socket)throw this.closeReason??new j("not connected");this.socket.send(e)}async request(e){if(this.replyWaiter)throw new Error("a request is already in flight");this.requestsSent++;let t=this.opts.timeoutMs??mn,r=await new Promise((i,s)=>{let o=setTimeout(()=>{this.die(new j(`no reply within ${t}ms`))},t);this.replyTimer=o,this.replyWaiter={resolve:a=>{this.disarmReply(),i(a)},reject:a=>{this.disarmReply(),s(a)}};try{this.send(e)}catch(a){this.disarmReply(),this.replyWaiter=void 0,s(a instanceof Error?a:new Error(String(a)))}});if(r.res==="err"){let i=new P(String(r.code??"unknown"),String(r.msg??"no message"));throw i.fatal&&this.die(i),i}return r}async body(){let e=this.bodyQueue.shift();if(e)return e;if(this.closed)throw this.closeReason??new j("not connected");return new Promise((t,r)=>{this.bodyWaiter={resolve:t,reject:r}})}async hello(e){this.cursor=e.cursor;let t=await this.request({op:"hello",proto:gt,crypto:Bt,vault:e.vault,token:e.token,device:e.device,cursor:e.cursor,...e.claim!==void 0?{claim:e.claim}:{}});if(t.res!=="ready")throw new P("protostate",`expected ready, got ${JSON.stringify(t)}`);let r={proto:H(t.proto),cursor:H(t.cursor),perFileMax:H(t.perFileMax),chunkMax:H(t.chunkMax),maxChunks:H(t.maxChunks)};if(r.proto!==gt)throw new P("proto",`server speaks protocol ${r.proto}, this client speaks ${gt}`);return this.log("ready",r),r}async put(e,t,r,i){let s=await this.request({op:"put",path:e,meta:vn(t),chunks:[...r]});if(s.res==="have")return{uid:H(s.uid),uploaded:0,bytes:0};if(s.res!=="want")throw new P("protostate",`expected want or have, got ${JSON.stringify(s)}`);let o=mt(s.chunks),a=new Set(r),l=0;for(let h of o){if(!a.has(h))throw new P("badchunk",`server asked for ${h}, which this put does not contain`);let u=await i(h);this.sendBody(u),l+=u.length}return{uid:await this.awaitAck(),uploaded:o.length,bytes:l}}async putMany(e,t){if(e.length===0)return{results:[],uploaded:0,bytes:0};if(e.length>$e)throw new P("toolarge",`${e.length} entries in one batch, the limit is ${$e}`);let r=await this.request({op:"putmany",entries:e.map(c=>({path:c.path,meta:vn(c.meta),chunks:[...c.names]}))}),i=r,s=0,o=0;if(r.res==="want"){let c=mt(r.chunks),h=new Set;for(let u of e)for(let f of u.names)h.add(f);for(let u of c){if(!h.has(u))throw new P("badchunk",`server asked for ${u}, which this batch does not contain`);let f=await t(u);this.sendBody(f),o+=f.length}s=c.length,i=await this.awaitReply()}if(i.res!=="acks")throw new P("protostate",`expected acks, got ${JSON.stringify(i)}`);let a=i.results;if(!Array.isArray(a)||a.length!==e.length)throw new P("protostate",`${e.length} entries went up and ${Array.isArray(a)?a.length:"no"} results came back`);let l=a.map(c=>{let h=c??{};return h.code!==void 0?{uid:0,error:new P(String(h.code),String(h.msg??"no message"))}:{uid:H(h.uid)}});for(let c of l)c.error?.fatal&&this.die(c.error);return{results:l,uploaded:s,bytes:o}}async awaitAck(){let e=await this.awaitReply();if(e.res!=="ack")throw new P("protostate",`expected ack, got ${JSON.stringify(e)}`);return H(e.uid)}async awaitReply(){let e=await new Promise((t,r)=>{if(this.closed){r(this.closeReason??new j("not connected"));return}let i=this.opts.timeoutMs??mn,s=setTimeout(()=>{this.die(new j(`no acknowledgement within ${i}ms`))},i);this.replyWaiter={resolve:o=>{clearTimeout(s),t(o)},reject:o=>{clearTimeout(s),r(o)}}});if(e.res==="err"){let t=new P(String(e.code??"unknown"),String(e.msg??"no message"));throw t.fatal&&this.die(t),t}return e}async get(e){let t=await this.request({op:"get",uid:e});if(t.res!=="chunks")throw new P("protostate",`expected chunks, got ${JSON.stringify(t)}`);return{uid:H(t.uid),size:H(t.size),chunks:mt(t.chunks)}}async history(e,t={}){let r=await this.request({op:"history",path:e,...t.before!==void 0?{before:t.before}:{},...t.limit!==void 0?{limit:t.limit}:{}});if(r.res!=="history")throw new P("protostate",`expected history, got ${JSON.stringify(r)}`);return yn(r.entries,"history")}async deleted(e){let t=await this.request({op:"deleted",...e!==void 0?{limit:e}:{}});if(t.res!=="deleted")throw new P("protostate",`expected deleted, got ${JSON.stringify(t)}`);return{entries:yn(t.entries,"deleted"),more:t.more===!0}}async fetch(e){if(e.length===0)return[];this.expecting+=e.length;let t=this.request({op:"fetch",chunks:[...e]}),r=[];try{for(let i=0;i<e.length;i++){let s=await Promise.race([this.body(),t.then(a=>{throw new P("protostate",`expected a chunk body, got ${JSON.stringify(a)}`)})]),o=await ct(s);if(o!==e[i])throw new P("badchunk",`asked for ${e[i]} and received ${s.length} bytes that hash to ${o}`);r.push(s)}}catch(i){throw this.expecting=0,this.disarmReply(),this.replyWaiter=void 0,i instanceof P&&i.code==="badchunk"&&this.die(i),i}return this.expecting=Math.max(0,this.expecting-e.length),this.disarmReply(),this.replyWaiter=void 0,r}async ping(){let e=await this.request({op:"ping"});if(e.res!=="pong")throw new P("protostate",`expected pong, got ${JSON.stringify(e)}`)}},Je=class{constructor(e=0,t=3e5,r=5e3,i=!0,s=Math.random){this.min=e;this.max=t;this.base=r;this.jitter=i;this.random=s}min;max;base;jitter;random;count=0;nextAt=0;success(e){this.count=0,this.nextAt=e+this.delay()}fail(e){this.count++,this.nextAt=e+this.delay()}delay(){if(this.count===0)return this.min;let e=this.base*Math.pow(2,this.count-1);return this.jitter&&(e*=.5+.5*this.random()),Math.floor(Math.min(this.max,this.min+e))}readyAt(){return this.nextAt}isReady(e){return e>=this.nextAt}get failures(){return this.count}};function Wr(n){let e=globalThis.WebSocket;if(!e)throw new Error("no WebSocket available in this environment");return new e(n)}function Vr(n){if(n instanceof Uint8Array)return n;if(n instanceof ArrayBuffer)return new Uint8Array(n);if(ArrayBuffer.isView(n))return new Uint8Array(n.buffer,n.byteOffset,n.byteLength)}function H(n){return typeof n=="number"&&Number.isFinite(n)?n:0}function mt(n){return Array.isArray(n)?n.filter(e=>typeof e=="string"):[]}function pn(n){let e=n.code??0,t=n.reason?`, ${n.reason}`:"";return`code ${e}${t}`}function yn(n,e){if(!Array.isArray(n))throw new P("protostate",`${e} came back without a list of entries`);return n}function wn(n){let e=n.split("/");e.pop();let t=[],r="";for(let i of e)r=r?`${r}/${i}`:i,t.push(r);return t}function Me(n){return n.length===0?"-empty-":n.join(",")}function Jr(n){return n===""||n==="-empty-"?[]:n.split(",")}function bn(){return{uploaded:0,downloaded:0,merged:0,conflicted:0,deletedLocally:0,deletedRemotely:0,restored:0,foldersCreated:0,unchanged:0,waiting:0,retrying:0,skipped:0,blocked:0,chunksSent:0,bytesSent:0}}var Ke=class{constructor(e){this.opts=e}opts;entries=new Map;remote=new Map;pending=new Set;retries=new Map;skipped=new Map;blocked=new Set;cannotStream=!1;outbox=[];outboxBytes=0;inbox=[];inboxBytes=0;limits;unsealed=new Map;cursor=0;syncing=!1;again=!1;started=!1;now(){return this.opts.now?.()??Date.now()}log(e,...t){this.opts.log?.(e,...t)}mergeable(e){return(this.opts.mergeable??rn)(e)}sizesFor(e,t){return Qt(e,t,this.limits?.chunkMax)}get coalesce(){return this.opts.coalesceWrites??!0}status(){let e=0;for(let t of this.entries.values())t.folder||e++;return{cursor:this.cursor,files:e,pending:this.pending.size,retrying:this.retries.size,skipped:this.skipped.size,syncing:this.syncing}}async start(){if(this.started)throw new Error("already started");this.started=!0;let e=await this.opts.store.load();if(e){this.cursor=e.cursor;for(let[r,i]of Object.entries(e.entries))this.entries.set(r,{...ft(r),...i});for(let[r,i]of Object.entries(e.remote))this.remote.set(r,i);for(let r of e.pending)this.pending.add(r);this.log("index loaded",{cursor:this.cursor,entries:this.entries.size,pending:this.pending.size})}let t=await this.opts.transport.hello({vault:this.opts.vaultId,token:this.opts.token,device:this.opts.device,cursor:this.cursor,...this.opts.claim!==void 0?{claim:this.opts.claim}:{}});return this.limits=t,this.log("connected",t),t}async acceptBatch(e){for(let t of e.entries){let r=await this.plaintextPath(t.path);if(this.remote.set(r,{uid:t.uid,folder:t.folder,deleted:t.deleted,mtime:t.mtime,size:t.size,hash:Me(t.chunks)}),this.pending.add(r),t.prev){let i=await this.plaintextPath(t.prev);this.remote.set(i,{uid:t.uid,folder:!1,deleted:!0,mtime:t.mtime,size:0,hash:""}),this.pending.add(i)}}this.cursor=e.to}async plaintextPath(e){let t=this.unsealed.get(e);if(t!==void 0)return t;let r=await Le(this.opts.keys,e);return this.unsealed.set(e,r),r}async sync(e={}){if(this.syncing)return this.again=!0,bn();this.syncing=!0;try{let t=await this.pass(e);for(;this.again;){this.again=!1;let r=await this.pass(e);t=Kr(t,r)}return t}finally{this.syncing=!1}}async pass(e={}){let t=bn(),r=this.now(),i=e.coalesceWrites??this.coalesce;(this.outbox.length>0||this.inbox.length>0)&&(this.log("a pass ended early, discarding what it had queued",{writes:this.outbox.length,reads:this.inbox.length}),this.outbox=[],this.outboxBytes=0,this.inbox=[],this.inboxBytes=0);let s=await this.opts.vault.list(),o=new Map(s.map(h=>[h.path,h]));for(let h of s){let u=this.entryFor(h.path);Pe(u,h)}let a=new Set;for(let[h,u]of o)u.folder||a.add(h);let l=new Set,c=new Set([...o.keys(),...this.entries.keys(),...this.remote.keys()]);for(let h of[...c].sort()){let u=this.skipped.get(h);if(u){if(vt(this.entries.get(h))===u.fingerprint){t.skipped++;continue}this.skipped.delete(h),this.log("skipped file changed, trying again",h)}let f=wn(h).find(m=>a.has(m));if(f!==void 0&&!o.has(h)){l.add(h),this.blocked.has(h)||this.log("cannot be both",h,`${f} is a file here and a folder elsewhere`),t.blocked++;continue}let g=this.retries.get(h);if(g&&g.at>r){t.retrying++;continue}try{this.opts.onProgress?.(h),await this.reconcile(h,o.get(h),t,r,i),this.retries.delete(h)}catch(m){this.recordFailure(h,m,t)}}return await this.fill(t),await this.flush(t),this.opts.onProgress?.(void 0),this.blocked=l,this.prune(o),await this.save(),t}entryFor(e){let t=this.entries.get(e);return t||(t=ft(e),this.entries.set(e,t)),t}async reconcile(e,t,r,i,s){let o=this.entryFor(e),a=this.remote.get(e),l=this.limits?.perFileMax??0;if(t&&!t.folder&&l>0&&t.size>l){this.recordFailure(e,qr(t.size,l),r);return}let c,h;t&&(!t.folder&&dt(o,Math.ceil(t.mtime),t.size)&&(h=await this.rehash(o,e,t.size)),c={folder:t.folder,mtime:o.mtime,size:o.size,hash:o.hash});let u=fn({local:c,remote:a,index:o,mergeable:this.mergeable(e)});if(s&&u.kind!=="nothing"&&c&&!t?.folder&&!gn(o,i)){r.waiting++;return}await this.act(e,u,o,c,a,r,h),this.pending.delete(e)}async rehash(e,t,r){let i=await this.streamScan(e,t,r);if(i)return i;let s=await this.opts.vault.read(t),o=this.mergeable(t),a=[...tn(s,this.sizesFor(s.length,o),o)],l=a.map(c=>c.bytes);if(s.length<=kn){let c=await ge(this.opts.keys,l);return e.chunks=c.map(h=>h.name),e.hash=Me(e.chunks),e.size=s.length,{bytes:s,pieces:a,names:e.chunks,sealed:c}}return e.chunks=await this.namesOf(l),e.hash=Me(e.chunks),e.size=s.length,{bytes:s,pieces:a,names:e.chunks}}async streamScan(e,t,r){let i=this.opts.vault;if(!(!i.readBlocks||!i.readRange||this.cannotStream)&&!(r===void 0||r<=kn))try{return await this.streamed(e,t,r)}catch(s){this.cannotStream=!0,this.log("streaming is not available here, reading whole files instead",t,{why:s.message});return}}async streamed(e,t,r){let i=this.opts.vault,s=this.mergeable(t),o=[],a=[],l=0;for await(let c of nn(i.readBlocks(t),this.sizesFor(r,s),s)){let h=await ge(this.opts.keys,[c.bytes]);o.push(h[0].name),a.push({start:c.offset,end:c.offset+c.bytes.length}),l+=c.bytes.length}return e.chunks=o,e.hash=Me(o),e.size=l,{names:o,spans:a,path:t,size:l}}namesOf(e){return jr(this.opts.keys,e)}async act(e,t,r,i,s,o,a){switch(t.kind){case"nothing":o.unchanged++,i&&s&&!s.deleted&&i.hash===s.hash&&ve(r,i.hash,r.chunks,s.uid,this.now());return;case"upload":await this.upload(e,r,o,!0,a);return;case"download":case"restoreLocal":{if(!s)return;await this.receive(e,r,s,t.kind,t.why,o);return}case"createLocalFolder":await this.opts.vault.mkdir(e),r.folder=!0,s&&ve(r,"",[],s.uid,this.now()),o.foldersCreated++;return;case"clash":this.skipped.set(e,{why:`${t.why}. Rename one of them, and it will sync.`,fingerprint:vt(r)}),o.skipped++,this.log("cannot be both",e,t.why);return;case"deleteLocal":await this.opts.vault.remove(e),this.entries.delete(e),o.deletedLocally++,this.log("deleted locally",e,t.why);return;case"deleteRemote":await this.queue({path:e,size:0,entry:{path:await this.sealedPath(e),meta:{size:0,ctime:0,mtime:this.now(),deleted:!0},names:[]},bodyOf:En,commit:l=>{this.remote.set(e,{uid:l,folder:!1,deleted:!0,mtime:this.now(),size:0,hash:""}),this.entries.delete(e),o.deletedRemotely++,this.log("deleted on the server",e,t.why)}},o);return;case"merge":await this.merge(e,r,s,o);return;case"conflict":await this.conflict(e,r,s,o,t.why);return}}async upload(e,t,r,i=!1,s){if(t.folder){await this.queue({path:e,size:0,entry:{path:await this.sealedPath(e),meta:{size:0,ctime:0,mtime:0,folder:!0},names:[]},bodyOf:En,commit:u=>{ve(t,"",[],u,this.now()),this.remote.set(e,{uid:u,folder:!0,deleted:!1,mtime:0,size:0,hash:""}),i&&r.uploaded++}},r);return}let o=await this.planUpload(t,e,s),a=t.hash,l=[...t.chunks],c=t.size,h=t.mtime;await this.queue({path:e,size:c,entry:{path:await this.sealedPath(e),meta:{size:c,ctime:t.ctime,mtime:h,...t.prev?{prev:await this.sealedPath(t.prev)}:{}},names:o.names},bodyOf:o.bodyOf,commit:u=>{ve(t,a,l,u,this.now()),this.remote.set(e,{uid:u,folder:!1,deleted:!1,mtime:h,size:c,hash:a}),i&&r.uploaded++,this.log("uploaded",e)}},r)}async queue(e,t){this.outbox.push(e),this.outboxBytes+=e.size,(this.outbox.length>=$e||this.outboxBytes>=Sn)&&await this.flush(t)}async flush(e){if(this.outbox.length===0)return;let t=this.outbox;this.outbox=[],this.outboxBytes=0;let r=new Map;for(let s of t)for(let o of s.entry.names)r.has(o)||r.set(o,s.bodyOf);let i;try{i=await this.opts.transport.putMany(t.map(s=>s.entry),async s=>{let o=r.get(s);if(!o)throw new Error(`server asked for ${s}, which no queued file contains`);return o(s)})}catch(s){for(let o of t)this.recordFailure(o.path,s,e);return}e.chunksSent+=i.uploaded,e.bytesSent+=i.bytes;for(let s=0;s<t.length;s++){let o=t[s],a=i.results[s];if(a.error){this.recordFailure(o.path,a.error,e);continue}o.commit(a.uid)}}async planUpload(e,t,r){let i=r??await this.scan(e,t);if(i.sealed){let c=new Map(i.sealed.map(h=>[h.name,h.bytes]));return{names:i.names,bodyOf:async h=>{let u=c.get(h);if(!u)throw new Error(`no sealed body for ${h} of ${t}`);return u}}}let s=this.opts.keys,o=this.opts.vault;if(i.spans){let c=new Map(i.names.map((h,u)=>[h,i.spans[u]]));return{names:i.names,bodyOf:async h=>{let u=c.get(h);if(!u)throw new Error(`no chunk named ${h} in ${t}`);let f=await o.readRange(i.path,u.start,u.end),g=await ge(s,[f]);if(g[0].name!==h)throw new Error(`${t} changed while it was being sent, so it was not sent`);return g[0].bytes}}}let a=new Map;for(let c=0;c<i.names.length;c++){let h=i.pieces[c];a.set(i.names[c],{start:h.offset,end:h.offset+h.bytes.length})}let l=i.bytes;return{names:i.names,bodyOf:async c=>{let h=a.get(c);if(!h)throw new Error(`no chunk named ${c} in ${t}`);return(await ge(s,[l.subarray(h.start,h.end)]))[0].bytes}}}scan(e,t){return this.rehash(e,t)}async receive(e,t,r,i,s,o){let a=Jr(r.hash);this.checkChunkCount(r.uid,a.length),this.inbox.push({path:e,entry:t,remote:r,chunks:a,kind:i,why:s}),this.inboxBytes+=r.size,(this.inbox.length>=$e||this.inboxBytes>=Sn)&&await this.fill(o)}async fill(e){if(this.inbox.length===0)return;let t=this.inbox;this.inbox=[],this.inboxBytes=0;let r=[],i=new Set;for(let o of t)for(let a of o.chunks)i.has(a)||(i.add(a),r.push(a));let s=new Map;if(r.length>0)try{let o=await this.opts.transport.fetch(r);for(let a=0;a<r.length;a++)s.set(r[a],o[a])}catch(o){for(let a of t)this.recordFailure(a.path,o,e);return}for(let o of t)try{await this.land(o,s),o.kind==="download"?e.downloaded++:e.restored++,this.log(o.kind,o.path,o.why)}catch(a){this.recordFailure(o.path,a,e)}}async land(e,t){let r=e.chunks.map(s=>{let o=t.get(s);if(!o)throw new Error(`the server did not send ${s}, which ${e.path} is made of`);return o}),i=await this.assemble(e.remote.uid,r);await this.opts.vault.write(e.path,i,{mtime:e.remote.mtime,ctime:e.remote.mtime}),Pe(e.entry,{folder:!1,mtime:e.remote.mtime,ctime:e.remote.mtime,size:i.length}),e.entry.chunks=[...e.chunks],e.entry.hash=Me(e.chunks),e.entry.size=i.length,ve(e.entry,e.entry.hash,e.entry.chunks,e.remote.uid,this.now())}async contentOf(e,t){let r=t!==void 0?{chunks:t}:await this.opts.transport.get(e);return r.chunks.length===0?new Uint8Array(0):(this.checkChunkCount(e,r.chunks.length),this.assemble(e,await this.opts.transport.fetch(r.chunks)))}checkChunkCount(e,t){let r=this.limits?.maxChunks??0;if(r>0&&t>r)throw new Error(`version ${e} names ${t} chunks, and this server said it stores at most ${r}`)}async assemble(e,t){if(t.length===0)return new Uint8Array(0);let r=[],i=0,s=this.limits?.perFileMax??0;for(let l of t){let c=await qt(this.opts.keys,l);if(i+=c.length,s>0&&i>s)throw new Error(`version ${e} is over ${i} bytes, and this server said it stores at most ${s}`);r.push(c)}let o=new Uint8Array(i),a=0;for(let l of r)o.set(l,a),a+=l.length;return o}async merge(e,t,r,i){if(!r)return;let s=new TextDecoder("utf-8",{fatal:!0}),o,a,l;try{o=s.decode(await this.contentOf(t.syncuid)),a=s.decode(await this.opts.vault.read(e)),l=s.decode(await this.contentOf(r.uid))}catch{let u="one side is not valid UTF-8, so merging it would rewrite bytes nobody edited";this.log("merge refused",e,u),await this.conflict(e,t,r,i,u);return}let c=cn(o,a,l,sn(e)?Zr:void 0);if(c.kind==="conflict"){this.log("merge refused",e,c.why),await this.conflict(e,t,r,i,c.why);return}let h=c.text;h!==a&&await this.opts.vault.write(e,new TextEncoder().encode(h),{mtime:this.now(),ctime:t.ctime}),Pe(t,{folder:!1,mtime:this.now(),ctime:t.ctime,size:h.length}),await this.upload(e,t,i),i.merged++,this.log("merged",e,c.kind==="merged"?"three-way":c.why)}freeConflictPath(e){return Gr(un(e,this.opts.device,new Date(this.now())),t=>this.opts.vault.exists(t))}async conflict(e,t,r,i,s){if(!r)return;let o=await this.freeConflictPath(e),a=await this.contentOf(r.uid);await this.opts.vault.write(o,a,{mtime:r.mtime,ctime:r.mtime});let l=this.entryFor(o);Pe(l,{folder:!1,mtime:r.mtime,ctime:r.mtime,size:a.length}),await this.upload(o,l,i),await this.upload(e,t,i),i.conflicted++,this.log("kept both",e,{copy:o,why:s})}async sealedPath(e){let t=await Be(this.opts.keys,e);return this.unsealed.set(t,e),t}recordFailure(e,t,r){let i=t instanceof Error?t.message:String(t),s=t?.code;if(s!==void 0&&["badentry","badname","toolarge"].includes(s)){this.skipped.set(e,{why:i,fingerprint:vt(this.entries.get(e))}),r.skipped++,this.log("skipped for good",e,i);return}let a=this.retries.get(e)??{count:0,error:"",at:0};a.count++,a.error=i,a.at=this.now()+Math.min(3e5,5e3*Math.pow(2,a.count)),this.retries.set(e,a),r.retrying++,this.log("will retry",e,{attempt:a.count,error:i})}prune(e){for(let[t,r]of this.entries){if(e.has(t))continue;let i=this.remote.get(t);i&&!i.deleted||r.synchash===""&&r.hash===""&&this.entries.delete(t)}for(let[t,r]of this.remote)r.deleted&&(e.has(t)||this.entries.has(t)||this.pending.has(t)||this.remote.delete(t))}async save(){let e={};for(let[r,i]of this.entries)e[r]=i;let t={};for(let[r,i]of this.remote)t[r]=i;await this.opts.store.save({cursor:this.cursor,entries:e,remote:t,pending:[...this.pending]})}noteRename(e,t){let r=this.entries.get(e);r&&(this.entries.delete(e),dn(r,e,t),this.entries.set(t,r))}};function Kr(n,e){let t={...n};for(let r of Object.keys(t))t[r]=n[r]+e[r];return t}function vt(n){return n?`${n.mtime}:${n.size}`:"gone"}var kn=8*1024*1024,Hr=16;async function jr(n,e,t=Hr){let r=[];for(let i=0;i<e.length;i+=t){let s=await ge(n,e.slice(i,i+t));for(let o of s)r.push(o.name)}return r}var Sn=8*1024*1024;async function Gr(n,e){if(!await e(n))return n;let t=n.lastIndexOf("."),r=n.lastIndexOf("/"),i=t>r,s=i?n.slice(0,t):n,o=i?n.slice(t):"";for(let a=2;a<1e3;a++){let l=`${s} ${a}${o}`;if(!await e(l))return l}throw new Error(`cannot find an unused name beside ${n}`)}function qr(n,e){let t=new Error(`${n} bytes, and this server said it stores at most ${e}, so it was not read`);return t.code="toolarge",t}async function En(n){throw new Error(`this put has no bodies, and the server asked for ${n}`)}function Zr(n){try{return JSON.parse(n),!0}catch{return!1}}var Xr=150,_e=class{constructor(e){this.opts=e;let t;this.transport=new Ve(e.url,{onBatch:async r=>{await t.acceptBatch(r),r.entries.length>0&&this.soon()},onCaughtUp:()=>{this.caughtUp=!0},onClosed:r=>{this.endedWith=r,this.notifyEnded?.(r)},...e.timeoutMs!==void 0?{timeoutMs:e.timeoutMs}:{},...e.log!==void 0?{log:e.log}:{},...e.socketFactory!==void 0?{socketFactory:e.socketFactory}:{}}),t=new Ke({vault:e.vault,store:e.store,keys:e.keys,transport:this.transport,device:e.device,vaultId:e.vaultId,token:e.token,...e.claim!==void 0?{claim:e.claim}:{},...e.coalesceWrites!==void 0?{coalesceWrites:e.coalesceWrites}:{},...e.log!==void 0?{log:e.log}:{},...e.onProgress!==void 0?{onProgress:e.onProgress}:{}}),this.engine=t}opts;engine;transport;limits;soonTimer;caughtUp=!1;endedWith;notifyEnded;queue=Promise.resolve();serial(e){let t=this.queue.then(e,e);return this.queue=t.catch(()=>{}),t}get requestsSent(){return this.transport.requestsSent}get serverCursor(){return this.limits?.cursor??0}async connect(){await this.transport.connect(),this.limits=await this.engine.start();let e=this.opts.timeoutMs??3e4,t=Date.now()+e;for(;!this.caughtUp&&Date.now()<t;){if(this.endedWith)throw this.endedWith;await pt(25)}if(!this.caughtUp)throw new Error("the server never finished sending what it already had");return this.limits}async settle(e={},t=8){let r=await this.pass(e),i=r;for(let s=0;s<t&&ti(r);s++)await pt(60),r=await this.pass(e),i=ei(i,r);return i}pass(e){return this.serial(()=>this.engine.sync(e))}async runUntilClosed(e=3e4){if(this.endedWith)return this.endedWith;let t=this.opts.vault.watch?.(()=>{this.sync()}),r=setInterval(()=>{this.sync().then(()=>this.keepalive())},e);try{return await new Promise(i=>{this.notifyEnded=i})}finally{clearInterval(r),t?.()}}async keepalive(){try{await this.transport.ping()}catch{}}soon(){this.soonTimer===void 0&&(this.soonTimer=setTimeout(()=>{this.soonTimer=void 0,this.sync()},Xr))}async sync(e={}){try{return await this.pass(e)}catch(t){this.opts.log?.("sync failed",t.message);return}}async history(e,t={}){let r=await Be(this.opts.keys,e);return(await this.serial(()=>this.transport.history(r,t))).map(s=>this.asVersion(s,e))}async deleted(e){let t=await this.serial(()=>this.transport.deleted(e)),r=[];for(let i of t.entries)r.push({...this.asVersion(i,await Le(this.opts.keys,i.path)),restorable:i.restorable??0});return{notes:r,more:t.more}}async contentAt(e){return e.deleted||e.folder?new Uint8Array(0):this.serial(()=>this.engine.contentOf(e.uid))}async restore(e,t){if(e.deleted)throw new Error(`version ${e.uid} of ${e.path} is the deletion itself, not a version to restore`);if(e.folder){let o=t??e.path;return await this.opts.vault.mkdir(o),{path:o,bytes:0}}let r=await this.serial(()=>this.engine.contentOf(e.uid)),i=t??e.path,s=await this.opts.vault.exists(i)?Yr(i,e):i;return await this.opts.vault.write(s,r,{mtime:e.mtime,ctime:e.ctime}),{path:s,bytes:r.length}}async newestContentVersion(e){return(await this.history(e,{limit:50})).find(r=>!r.deleted)}asVersion(e,t){return{uid:e.uid,path:t,size:e.size,ctime:e.ctime,mtime:e.mtime,folder:e.folder,deleted:e.deleted,device:e.device,chunks:e.chunks?.length??0}}close(){this.soonTimer!==void 0&&(clearTimeout(this.soonTimer),this.soonTimer=void 0),this.transport.close()}};function Yr(n,e){let t=n.lastIndexOf("/"),r=t===-1?"":n.slice(0,t+1),i=t===-1?n:n.slice(t+1),s=i.lastIndexOf("."),o=s<=0?i:i.slice(0,s),a=s<=0?"":i.slice(s);return`${r}${o} (restored ${e.uid})${a}`}async function An(n,e={}){let t=new Je(0,3e5,5e3,!0);for(;e.keepGoing?.()??!0;){let r,i,s=!1;try{r=new _e(n),await r.connect(),s=!0,t.success(Date.now()),e.onClient?.(r),e.onSynced?.(await r.settle(),r.serverCursor),i=await r.runUntilClosed()}catch(l){i=l}finally{e.onClient?.(void 0),r?.close()}if(i&&Qr(i)){e.onFatal?.(i);return}if(!(e.keepGoing?.()??!0))return;t.fail(Date.now());let o=t.delay(),a=i??new Error("the connection ended");s?e.onDisconnected?.(a,o):e.onUnreachable?.(a,o),await pt(o)}}function Qr(n){return n instanceof P&&n.fatal}function ei(n,e){return{uploaded:n.uploaded+e.uploaded,downloaded:n.downloaded+e.downloaded,merged:n.merged+e.merged,conflicted:n.conflicted+e.conflicted,deletedLocally:n.deletedLocally+e.deletedLocally,deletedRemotely:n.deletedRemotely+e.deletedRemotely,restored:n.restored+e.restored,foldersCreated:n.foldersCreated+e.foldersCreated,chunksSent:n.chunksSent+e.chunksSent,bytesSent:n.bytesSent+e.bytesSent,unchanged:e.unchanged,waiting:e.waiting,retrying:e.retrying,skipped:e.skipped,blocked:e.blocked}}function ti(n){return n.uploaded+n.downloaded+n.merged+n.conflicted+n.deletedLocally+n.deletedRemotely+n.restored+n.foldersCreated+n.waiting>0}var pt=n=>new Promise(e=>setTimeout(e,n));var He="basalt2_",yt=2,Ce=4,xn=new TextEncoder,ni=new TextDecoder;function wt(n){if(n.secret.length!==Z)throw new Error(`a root secret is ${Z} bytes, not ${n.secret.length}`);let e=[xn.encode(n.url),xn.encode(n.vaultId)];for(let o of e)if(o.length>255)throw new Error("a pairing field is too long to encode");let t=1+Z+e.reduce((o,a)=>o+1+a.length,0),r=new Uint8Array(t);r[0]=yt,r.set(n.secret,1);let i=1+Z;for(let o of e)r[i++]=o.length,r.set(o,i),i+=o.length;let s=new Uint8Array(t+Ce);return s.set(r,0),s.set($n(r),t),He+xe(s)}function Pn(n){let e=n.trim();if(e.startsWith("basalt1_"))throw new Error("this is a version 1 pairing string, from before the server token was folded into the root secret. Run basalt invite on a device that is already paired to get a current one.");if(!e.startsWith(He))throw new Error(`not a pairing string: it should start with ${He}`);let t;try{t=We(e.slice(He.length))}catch{throw new Error("this pairing string is damaged: it is not valid base64url")}if(t.length<1+Z+2+Ce)throw new Error("this pairing string is too short to be complete");let r=t.subarray(0,t.length-Ce),i=t.subarray(t.length-Ce),s=$n(r);for(let u=0;u<Ce;u++)if(i[u]!==s[u])throw new Error("this pairing string is damaged: it did not survive being copied");if(r[0]!==yt)throw new Error(`this pairing string is version ${r[0]}, and this device understands ${yt}`);let o=r.slice(1,1+Z),a=1+Z,l=u=>{if(a>=r.length)throw new Error(`this pairing string ends before its ${u}`);let f=r[a++];if(a+f>r.length)throw new Error(`this pairing string ends inside its ${u}`);let g=ni.decode(r.subarray(a,a+f));return a+=f,g},c=l("server address"),h=l("vault name");if(a!==r.length)throw new Error("this pairing string has more in it than it should");if(c===""||h==="")throw new Error("this pairing string has an empty field");return{url:c,secret:o,vaultId:h}}function $n(n){let e=4294967295;for(let t of n){e^=t;for(let r=0;r<8;r++)e=e&1?e>>>1^3988292384:e>>>1}return e=(e^4294967295)>>>0,new Uint8Array([e>>>24&255,e>>>16&255,e>>>8&255,e&255])}function Mn(n){return{url:n.url,vaultId:n.vaultId,device:n.device,secret:xe(n.secret),...n.bootstrap?{bootstrap:n.bootstrap}:{}}}function _n(n,e){if(typeof n!="object"||n===null)throw new Error(`${e} does not hold a configuration`);let t=n,r=o=>{let a=t[o];if(typeof a!="string"||a==="")throw new Error(`${e} has no ${o}`);return a},i=We(r("secret"));if(i.length!==Z)throw new Error(`${e} holds a ${i.length} byte secret, and a root secret is ${Z}`);let s=t.bootstrap;return{url:r("url"),vaultId:r("vaultId"),device:r("device"),secret:i,...typeof s=="string"&&s!==""?{bootstrap:s}:{}}}function Cn(n){let e=n.trim().replace(/\/+$/,"");if(e==="")throw new Error("that is not a server address");if(e.startsWith("ws://")||e.startsWith("wss://"))return e;if(e.startsWith("http://"))return"ws://"+e.slice(7);if(e.startsWith("https://"))return"wss://"+e.slice(8);if(e.includes("://"))throw new Error(`a server address is ws:// or wss://, not ${e.split("://")[0]}://`);return"wss://"+e}import{constants as bt,watch as ri}from"node:fs";import{access as kt,cp as ii,mkdir as je,open as Ge,readFile as Un,readdir as si,rename as Dn,rm as oi,stat as ai,utimes as li}from"node:fs/promises";import{basename as St,dirname as qe,join as Tn,relative as hi,resolve as Rn,sep as In}from"node:path";var On=".trash",ci=new Set([".obsidian",".basalt",On,".git",".DS_Store","node_modules"]),Ze=class{root;ignore;constructor(e,t={}){this.root=Rn(e),this.ignore=new Set([...ci,...t.alsoIgnore??[]])}absolute(e){let t=Rn(this.root,e),r=hi(this.root,t);if(r===""||r.startsWith("..")||r.startsWith(`..${In}`))throw new Error(`refusing a path outside the vault: ${e}`);return t}async list(){let e=[],t=async(r,i)=>{let s;try{s=await si(r,{withFileTypes:!0})}catch(o){throw new Error(`cannot read ${r}: ${o.message}`)}for(let o of s){if(this.ignore.has(o.name)||zn(o.name))continue;let a=i?`${i}/${o.name}`:o.name,l=Tn(r,o.name);if(o.isDirectory())e.push({path:a,folder:!0,mtime:0,ctime:0,size:0}),await t(l,a);else if(o.isFile()){let c=await ai(l);e.push({path:a,folder:!1,mtime:c.mtimeMs,ctime:c.birthtimeMs||c.ctimeMs,size:c.size})}}};return await t(this.root,""),e}async read(e){return new Uint8Array(await Un(this.absolute(e)))}async*readBlocks(e,t=1024*1024){let r=await Ge(this.absolute(e),"r");try{let i=new Uint8Array(t);for(;;){let{bytesRead:s}=await r.read(i,0,t,null);if(s===0)return;yield i.slice(0,s)}}finally{await r.close()}}async readRange(e,t,r){let i=await Ge(this.absolute(e),"r");try{let s=new Uint8Array(r-t),o=0;for(;o<s.length;){let{bytesRead:a}=await i.read(s,o,s.length-o,t+o);if(a===0)break;o+=a}return o===s.length?s:s.subarray(0,o)}finally{await i.close()}}async write(e,t,r){let i=this.absolute(e);if(await je(qe(i),{recursive:!0}),await Nn(i,t),r.mtime>0){let s=r.mtime/1e3;await li(i,s,s)}}async remove(e){let t=this.absolute(e);try{await kt(t,bt.F_OK)}catch{return}let r=await this.freeTrashPath(e);await je(qe(r),{recursive:!0});try{await Dn(t,r);return}catch(i){if(i.code!=="EXDEV")throw i}await ii(t,r,{recursive:!0}),await oi(t,{recursive:!0,force:!0})}async freeTrashPath(e){let t=Tn(this.root,On,e),r=St(e).lastIndexOf("."),[i,s]=r<=0?[t,""]:[t.slice(0,t.length-(St(e).length-r)),t.slice(t.length-(St(e).length-r))];for(let o=0;o<1e3;o++){let a=o===0?t:`${i} (${o})${s}`;try{await kt(a,bt.F_OK)}catch{return a}}throw new Error(`the trash already holds a thousand copies of ${e}`)}async mkdir(e){await je(this.absolute(e),{recursive:!0})}async exists(e){try{return await kt(this.absolute(e),bt.F_OK),!0}catch{return!1}}watch(e){let t,r="",i;try{i=ri(this.root,{recursive:!0,persistent:!0},(s,o)=>{if(!o)return;let a=o.toString().split(In).join("/");a.split("/").some(l=>this.ignore.has(l))||zn(a)||(r=a,t&&clearTimeout(t),t=setTimeout(()=>{t=void 0,e(r)},150))}),i.on("error",()=>{})}catch{return()=>{}}return()=>{t&&clearTimeout(t),i?.close()}}},Te=class{constructor(e){this.file=e}file;async load(){let e;try{e=await Un(this.file,"utf8")}catch(t){if(t.code==="ENOENT")return;throw new Error(`cannot read the index at ${this.file}: ${t.message}`)}try{return JSON.parse(e)}catch(t){throw new Error(`the index at ${this.file} is not valid JSON, so it cannot be trusted: ${t.message}`)}}async save(e){await je(qe(this.file),{recursive:!0}),await Nn(this.file,new TextEncoder().encode(JSON.stringify(e)))}},Fn=".basalt-tmp-";function zn(n){return n.includes(Fn)}var ui=0;async function fi(n){for(let e=0;e<64;e++){let t=`${n}${Fn}${(ui++).toString(36)}${e?`-${e}`:""}`;try{return{tmp:t,handle:await Ge(t,"wx")}}catch(r){if(r.code!=="EEXIST")throw r}}throw new Error(`could not find an unused temporary name beside ${n}`)}async function Nn(n,e){let{tmp:t,handle:r}=await fi(n);try{await r.write(e),await r.sync()}finally{await r.close()}await Dn(t,n);let i=await Ge(qe(n),"r");try{await i.sync()}finally{await i.close()}}import{chmod as di,mkdir as gi,readFile as mi,rename as vi,rm as Bn,writeFile as pi}from"node:fs/promises";import{join as Et}from"node:path";var At=".basalt",xt=n=>Et(n,At,"config.json"),Xe=n=>Et(n,At,"index.json");async function Re(n){let e=xt(n),t;try{t=await mi(e,"utf8")}catch(i){if(i.code==="ENOENT")return;throw new Error(`cannot read ${e}: ${i.message}`)}let r;try{r=JSON.parse(t)}catch(i){throw new Error(`${e} is not valid JSON, so it cannot be trusted: ${i.message}`)}return _n(r,e)}async function Ye(n,e){let t=Et(n,At);await gi(t,{recursive:!0});let r=xt(n),i=`${r}.tmp`;await pi(i,JSON.stringify(Mn(e),null,2)+`
9
- `,{mode:384}),await di(i,384),await vi(i,r)}async function Ln(n){await Bn(xt(n),{force:!0}),await Bn(Xe(n),{force:!0})}var Wn=`basalt: self-hosted sync for Obsidian
8
+ `).sort();if(n.length!==r.length)return!1;for(let i=0;i<n.length;i++)if(n[i]!==r[i])return!1;return!0}function cn(t,e,n,r){let[i,s]=t.patch_apply(t.patch_make(e,n),r);return{text:i,failed:s.filter(o=>!o).length,total:s.length}}function Or(t,e){for(let[n,r]of t)if(n===Dr&&!e.includes(r))return r}function Fr(t){let e=t.replace(/\s+/g," ").trim(),n=e.length>60?`${e.slice(0,57)}...`:e;return`a local edit (${JSON.stringify(n)})`}function dn(t,e,n){let r=t.lastIndexOf("."),i=t.lastIndexOf("/"),s=r>i,o=s?t.slice(0,r):t,a=s?t.slice(r):"",l=(h,u=2)=>String(h).padStart(u,"0"),c=`${n.getFullYear()}${l(n.getMonth()+1)}${l(n.getDate())}${l(n.getHours())}${l(n.getMinutes())}`;return`${o} (Conflicted copy ${Nr(e)} ${c})${a}`}function Nr(t){return t.replace(/[-\\/:*?"<>|\s]/g,"-").replace(/-{2,}/g,"-").replace(/^[.\-\s]+|[.\-\s]+$/g,"").slice(0,32)||"device"}function ft(t){return{path:t,prev:"",folder:!1,ctime:0,mtime:0,size:0,hash:"",chunks:[],synchash:"",syncuid:0,synctime:0}}function gn(t){let{local:e,remote:n,index:r,mergeable:i}=t,s=r.synchash;return e?.folder||n?.folder?Br(e,n):e===void 0&&(n===void 0||n.deleted)?{kind:"nothing",why:"absent on both sides"}:n===void 0?{kind:"upload",why:"new file, the server has never held this path"}:e===void 0?Lr(n,r):n.deleted?e.hash===s&&s!==""?{kind:"deleteLocal",why:"deleted on another device and unchanged here"}:s===""?{kind:"upload",why:"deleted on the server but never synced from here"}:{kind:"upload",why:"deleted on another device but edited here, so the edit is kept and re-sent"}:e.hash===n.hash?{kind:"nothing",why:"the two sides hold the same content"}:s===""?{kind:"conflict",why:"both sides have content and there is no last-synced version to merge from"}:e.hash===s?{kind:"download",why:"changed on another device and unchanged here"}:n.hash===s?{kind:"upload",why:"changed here and unchanged on the server"}:i?{kind:"merge",why:"changed on both sides since the last sync"}:{kind:"conflict",why:"changed on both sides and this file cannot be merged"}}function Br(t,e){return t!==void 0&&t.folder?e===void 0?{kind:"upload",why:"new folder, the server has never held this path"}:e.deleted?{kind:"nothing",why:"folder deleted elsewhere; its files decide"}:e.folder?{kind:"nothing",why:"folder exists on both sides"}:{kind:"clash",why:"a folder here and a file of the same name on another device"}:e?.folder&&!e.deleted?t!==void 0?{kind:"clash",why:"a file here and a folder of the same name on another device"}:{kind:"createLocalFolder",why:"folder exists on the server and not here"}:{kind:"nothing",why:"folder absent on both sides"}}function Lr(t,e){let n=e.synchash;return t.deleted?{kind:"nothing",why:"deleted on both sides"}:n===""?{kind:"download",why:"new on the server"}:t.hash===n?{kind:"deleteRemote",why:"deleted here and unchanged on the server"}:{kind:"restoreLocal",why:"deleted here but changed on another device, so the newer content is restored"}}function dt(t,e,n){return t.hash===""||t.chunks.length===0?!0:t.mtime!==e||t.size!==n}function Pe(t,e){let n=Math.ceil(e.mtime),r=Math.ceil(e.ctime);if(e.folder){t.folder=!0,t.mtime=0,t.ctime=0,t.size=0,t.hash="",t.chunks=[];return}dt(t,n,Wr(e))&&(t.hash="",t.chunks=[]),t.folder=!1,t.mtime=n,t.ctime=r,t.size=e.size}function Wr(t){return t.size}function mn(t,e,n){t.path=n,t.prev===""&&(t.prev=e),t.prev===n&&(t.prev=""),t.synctime=0}function ve(t,e,n,r,i){t.hash=e,t.chunks=[...n],t.synchash=e,t.syncuid=r,t.synctime=i,t.prev=""}function vn(t,e){if(!t.synctime)return!0;let n=t.size>102400?30:t.size>10240?20:10;return e-t.synctime>n*1e3}var gt=1,pn=6e4,$e=256;function yn(t){return{size:t.size,ctime:t.ctime,mtime:t.mtime,folder:t.folder??!1,deleted:t.deleted??!1,...t.prev?{prev:t.prev}:{}}}var P=class extends Error{constructor(n,r){super(r);this.code=n;this.name="ProtocolError"}code;get fatal(){return["proto","auth","cursor","busy","protostate","badchunk","internal"].includes(this.code)}};function Vr(t){return t.startsWith("wss://")?`. If that server has no TLS in front of it, pair with ws://${t.slice(6)} instead`:""}var j=class extends Error{constructor(e){super(e),this.name="ConnectionError"}},Ve=class{constructor(e,n){this.url=e;this.opts=n}url;opts;socket;replyWaiter;replyTimer;bodyWaiter;bodyQueue=[];expecting=0;requestsSent=0;closed=!1;closeReason;cursor=0;notifying=Promise.resolve();log(e,...n){this.opts.log?.(e,...n)}get appliedCursor(){return this.cursor}async connect(){if(this.socket)throw new Error("already connected");let n=(this.opts.socketFactory??Jr)(this.url);n.binaryType="arraybuffer",this.socket=n,await new Promise((r,i)=>{n.onopen=()=>r(),n.onerror=()=>i(new j(`could not connect to ${this.url}${Vr(this.url)}`)),n.onclose=s=>i(new j(`connection closed before opening: ${wn(s)}`))}),n.onerror=()=>this.die(new j("the connection failed")),n.onclose=r=>this.die(new j(`the connection closed: ${wn(r)}`)),n.onmessage=r=>this.onFrame(r.data)}die(e){if(this.closed)return;this.closed=!0,this.closeReason=e,this.log("transport closed",e.message),this.disarmReply();let n=this.replyWaiter,r=this.bodyWaiter;this.replyWaiter=void 0,this.bodyWaiter=void 0,n?.reject(e),r?.reject(e);try{this.socket?.close()}catch{}try{this.opts.onClosed?.(e)}catch{}}disarmReply(){this.replyTimer!==void 0&&(clearTimeout(this.replyTimer),this.replyTimer=void 0)}close(){this.die(new j("closed by this device"))}get isClosed(){return this.closed}onFrame(e){if(typeof e=="string"){let i;try{i=JSON.parse(e)}catch{this.die(new P("protostate",`server sent a frame that is not JSON: ${e.slice(0,120)}`));return}this.onTextFrame(i);return}let n=Kr(e);if(n===void 0){this.die(new P("protostate","server sent a frame of an unexpected type"));return}let r=this.bodyWaiter;if(r){this.bodyWaiter=void 0,r.resolve(n);return}if(this.bodyQueue.length>=this.expecting){this.die(new P("protostate",`server sent a ${n.length} byte body with nothing outstanding to receive it`));return}this.bodyQueue.push(n)}onTextFrame(e){if(e.op==="batch"){this.queueNotification(()=>this.onBatchFrame(e));return}if(e.op==="caught-up"){let r=H(e.cursor);this.queueNotification(async()=>{if(r!==this.cursor){this.die(new P("protostate",`server says caught up at ${r}, this device reached ${this.cursor}`));return}this.opts.onCaughtUp?.(r)});return}let n=this.replyWaiter;if(!n){this.die(new P("protostate",`server sent an unexpected reply: ${JSON.stringify(e)}`));return}this.replyWaiter=void 0,n.resolve(e)}queueNotification(e){this.notifying=this.notifying.then(e).catch(n=>{this.die(n instanceof Error?n:new Error(String(n)))})}async onBatchFrame(e){let n=H(e.from),r=H(e.to),i=e.entries;if(!Array.isArray(i))throw new P("protostate",`batch ${n} to ${r} carries no entries array, so an empty batch cannot be told from a lost one`);let s=i;if(n!==this.cursor+1)throw new P("protostate",`batch covers ${n} to ${r} but this device has applied up to ${this.cursor}, so something was skipped`);if(r<n)throw new P("protostate",`batch covers an empty range, ${n} to ${r}`);for(let o of s){if(typeof o?.uid!="number"||!Number.isFinite(o.uid))throw new P("protostate",`batch ${n}..${r} contains an entry with no uid`);if(typeof o.path!="string"||o.path==="")throw new P("protostate",`batch ${n}..${r} contains uid ${o.uid} with no path`);if(!Array.isArray(o.chunks))throw new P("protostate",`batch ${n}..${r} contains uid ${o.uid} with no chunks array`);if(o.uid<n||o.uid>r)throw new P("protostate",`batch ${n}..${r} contains uid ${o.uid}`)}await this.opts.onBatch({from:n,to:r,entries:s}),this.cursor=r}send(e){if(this.closed||!this.socket)throw this.closeReason??new j("not connected");this.socket.send(JSON.stringify(e))}sendBody(e){if(this.closed||!this.socket)throw this.closeReason??new j("not connected");this.socket.send(e)}async request(e){if(this.replyWaiter)throw new Error("a request is already in flight");this.requestsSent++;let n=this.opts.timeoutMs??pn,r=await new Promise((i,s)=>{let o=setTimeout(()=>{this.die(new j(`no reply within ${n}ms`))},n);this.replyTimer=o,this.replyWaiter={resolve:a=>{this.disarmReply(),i(a)},reject:a=>{this.disarmReply(),s(a)}};try{this.send(e)}catch(a){this.disarmReply(),this.replyWaiter=void 0,s(a instanceof Error?a:new Error(String(a)))}});if(r.res==="err"){let i=new P(String(r.code??"unknown"),String(r.msg??"no message"));throw i.fatal&&this.die(i),i}return r}async body(){let e=this.bodyQueue.shift();if(e)return e;if(this.closed)throw this.closeReason??new j("not connected");return new Promise((n,r)=>{this.bodyWaiter={resolve:n,reject:r}})}async hello(e){this.cursor=e.cursor;let n=await this.request({op:"hello",proto:gt,crypto:Wt,vault:e.vault,token:e.token,device:e.device,cursor:e.cursor,...e.claim!==void 0?{claim:e.claim}:{}});if(n.res!=="ready")throw new P("protostate",`expected ready, got ${JSON.stringify(n)}`);let r={proto:H(n.proto),cursor:H(n.cursor),perFileMax:H(n.perFileMax),chunkMax:H(n.chunkMax),maxChunks:H(n.maxChunks)};if(r.proto!==gt)throw new P("proto",`server speaks protocol ${r.proto}, this client speaks ${gt}`);return this.log("ready",r),r}async put(e,n,r,i){let s=await this.request({op:"put",path:e,meta:yn(n),chunks:[...r]});if(s.res==="have")return{uid:H(s.uid),uploaded:0,bytes:0};if(s.res!=="want")throw new P("protostate",`expected want or have, got ${JSON.stringify(s)}`);let o=mt(s.chunks),a=new Set(r),l=0;for(let h of o){if(!a.has(h))throw new P("badchunk",`server asked for ${h}, which this put does not contain`);let u=await i(h);this.sendBody(u),l+=u.length}return{uid:await this.awaitAck(),uploaded:o.length,bytes:l}}async putMany(e,n){if(e.length===0)return{results:[],uploaded:0,bytes:0};if(e.length>$e)throw new P("toolarge",`${e.length} entries in one batch, the limit is ${$e}`);let r=await this.request({op:"putmany",entries:e.map(c=>({path:c.path,meta:yn(c.meta),chunks:[...c.names]}))}),i=r,s=0,o=0;if(r.res==="want"){let c=mt(r.chunks),h=new Set;for(let u of e)for(let f of u.names)h.add(f);for(let u of c){if(!h.has(u))throw new P("badchunk",`server asked for ${u}, which this batch does not contain`);let f=await n(u);this.sendBody(f),o+=f.length}s=c.length,i=await this.awaitReply()}if(i.res!=="acks")throw new P("protostate",`expected acks, got ${JSON.stringify(i)}`);let a=i.results;if(!Array.isArray(a)||a.length!==e.length)throw new P("protostate",`${e.length} entries went up and ${Array.isArray(a)?a.length:"no"} results came back`);let l=a.map(c=>{let h=c??{};return h.code!==void 0?{uid:0,error:new P(String(h.code),String(h.msg??"no message"))}:{uid:H(h.uid)}});for(let c of l)c.error?.fatal&&this.die(c.error);return{results:l,uploaded:s,bytes:o}}async awaitAck(){let e=await this.awaitReply();if(e.res!=="ack")throw new P("protostate",`expected ack, got ${JSON.stringify(e)}`);return H(e.uid)}async awaitReply(){let e=await new Promise((n,r)=>{if(this.closed){r(this.closeReason??new j("not connected"));return}let i=this.opts.timeoutMs??pn,s=setTimeout(()=>{this.die(new j(`no acknowledgement within ${i}ms`))},i);this.replyWaiter={resolve:o=>{clearTimeout(s),n(o)},reject:o=>{clearTimeout(s),r(o)}}});if(e.res==="err"){let n=new P(String(e.code??"unknown"),String(e.msg??"no message"));throw n.fatal&&this.die(n),n}return e}async get(e){let n=await this.request({op:"get",uid:e});if(n.res!=="chunks")throw new P("protostate",`expected chunks, got ${JSON.stringify(n)}`);return{uid:H(n.uid),size:H(n.size),chunks:mt(n.chunks)}}async history(e,n={}){let r=await this.request({op:"history",path:e,...n.before!==void 0?{before:n.before}:{},...n.limit!==void 0?{limit:n.limit}:{}});if(r.res!=="history")throw new P("protostate",`expected history, got ${JSON.stringify(r)}`);return bn(r.entries,"history")}async deleted(e){let n=await this.request({op:"deleted",...e!==void 0?{limit:e}:{}});if(n.res!=="deleted")throw new P("protostate",`expected deleted, got ${JSON.stringify(n)}`);return{entries:bn(n.entries,"deleted"),more:n.more===!0}}async fetch(e){if(e.length===0)return[];this.expecting+=e.length;let n=this.request({op:"fetch",chunks:[...e]}),r=[];try{for(let i=0;i<e.length;i++){let s=await Promise.race([this.body(),n.then(a=>{throw new P("protostate",`expected a chunk body, got ${JSON.stringify(a)}`)})]),o=await ct(s);if(o!==e[i])throw new P("badchunk",`asked for ${e[i]} and received ${s.length} bytes that hash to ${o}`);r.push(s)}}catch(i){throw this.expecting=0,this.disarmReply(),this.replyWaiter=void 0,i instanceof P&&i.code==="badchunk"&&this.die(i),i}return this.expecting=Math.max(0,this.expecting-e.length),this.disarmReply(),this.replyWaiter=void 0,r}async ping(){let e=await this.request({op:"ping"});if(e.res!=="pong")throw new P("protostate",`expected pong, got ${JSON.stringify(e)}`)}},Je=class{constructor(e=0,n=3e5,r=5e3,i=!0,s=Math.random){this.min=e;this.max=n;this.base=r;this.jitter=i;this.random=s}min;max;base;jitter;random;count=0;nextAt=0;success(e){this.count=0,this.nextAt=e+this.delay()}fail(e){this.count++,this.nextAt=e+this.delay()}delay(){if(this.count===0)return this.min;let e=this.base*Math.pow(2,this.count-1);return this.jitter&&(e*=.5+.5*this.random()),Math.floor(Math.min(this.max,this.min+e))}readyAt(){return this.nextAt}isReady(e){return e>=this.nextAt}get failures(){return this.count}};function Jr(t){let e=globalThis.WebSocket;if(!e)throw new Error("no WebSocket available in this environment");return new e(t)}function Kr(t){if(t instanceof Uint8Array)return t;if(t instanceof ArrayBuffer)return new Uint8Array(t);if(ArrayBuffer.isView(t))return new Uint8Array(t.buffer,t.byteOffset,t.byteLength)}function H(t){return typeof t=="number"&&Number.isFinite(t)?t:0}function mt(t){return Array.isArray(t)?t.filter(e=>typeof e=="string"):[]}function wn(t){let e=t.code??0,n=t.reason?`, ${t.reason}`:"";return`code ${e}${n}`}function bn(t,e){if(!Array.isArray(t))throw new P("protostate",`${e} came back without a list of entries`);return t}function kn(t){let e=t.split("/");e.pop();let n=[],r="";for(let i of e)r=r?`${r}/${i}`:i,n.push(r);return n}function Me(t){return t.length===0?"-empty-":t.join(",")}function Hr(t){return t===""||t==="-empty-"?[]:t.split(",")}function Sn(){return{uploaded:0,downloaded:0,merged:0,conflicted:0,deletedLocally:0,deletedRemotely:0,restored:0,foldersCreated:0,unchanged:0,waiting:0,retrying:0,skipped:0,blocked:0,chunksSent:0,bytesSent:0}}var Ke=class{constructor(e){this.opts=e}opts;entries=new Map;remote=new Map;pending=new Set;retries=new Map;skipped=new Map;blocked=new Set;cannotStream=!1;outbox=[];outboxBytes=0;inbox=[];inboxBytes=0;limits;unsealed=new Map;cursor=0;syncing=!1;again=!1;started=!1;now(){return this.opts.now?.()??Date.now()}log(e,...n){this.opts.log?.(e,...n)}mergeable(e){return(this.opts.mergeable??on)(e)}sizesFor(e,n){return tn(e,n,this.limits?.chunkMax)}get coalesce(){return this.opts.coalesceWrites??!0}status(){let e=0;for(let n of this.entries.values())n.folder||e++;return{cursor:this.cursor,files:e,pending:this.pending.size,retrying:this.retries.size,skipped:this.skipped.size,syncing:this.syncing}}async start(){if(this.started)throw new Error("already started");this.started=!0;let e=await this.opts.store.load();if(e){this.cursor=e.cursor;for(let[r,i]of Object.entries(e.entries))this.entries.set(r,{...ft(r),...i});for(let[r,i]of Object.entries(e.remote))this.remote.set(r,i);for(let r of e.pending)this.pending.add(r);this.log("index loaded",{cursor:this.cursor,entries:this.entries.size,pending:this.pending.size})}let n=await this.opts.transport.hello({vault:this.opts.vaultId,token:this.opts.token,device:this.opts.device,cursor:this.cursor,...this.opts.claim!==void 0?{claim:this.opts.claim}:{}});return this.limits=n,this.log("connected",n),n}async acceptBatch(e){for(let n of e.entries){let r=await this.plaintextPath(n.path);if(this.remote.set(r,{uid:n.uid,folder:n.folder,deleted:n.deleted,mtime:n.mtime,size:n.size,hash:Me(n.chunks)}),this.pending.add(r),n.prev){let i=await this.plaintextPath(n.prev);this.remote.set(i,{uid:n.uid,folder:!1,deleted:!0,mtime:n.mtime,size:0,hash:""}),this.pending.add(i)}}this.cursor=e.to}async plaintextPath(e){let n=this.unsealed.get(e);if(n!==void 0)return n;let r=await Le(this.opts.keys,e);return this.unsealed.set(e,r),r}async sync(e={}){if(this.syncing)return this.again=!0,Sn();this.syncing=!0;try{let n=await this.pass(e);for(;this.again;){this.again=!1;let r=await this.pass(e);n=jr(n,r)}return n}finally{this.syncing=!1}}async pass(e={}){let n=Sn(),r=this.now(),i=e.coalesceWrites??this.coalesce;(this.outbox.length>0||this.inbox.length>0)&&(this.log("a pass ended early, discarding what it had queued",{writes:this.outbox.length,reads:this.inbox.length}),this.outbox=[],this.outboxBytes=0,this.inbox=[],this.inboxBytes=0);let s=await this.opts.vault.list(),o=new Map(s.map(h=>[h.path,h]));for(let h of s){let u=this.entryFor(h.path);Pe(u,h)}let a=new Set;for(let[h,u]of o)u.folder||a.add(h);let l=new Set,c=new Set([...o.keys(),...this.entries.keys(),...this.remote.keys()]);for(let h of[...c].sort()){let u=this.skipped.get(h);if(u){if(vt(this.entries.get(h))===u.fingerprint){n.skipped++;continue}this.skipped.delete(h),this.log("skipped file changed, trying again",h)}let f=kn(h).find(m=>a.has(m));if(f!==void 0&&!o.has(h)){l.add(h),this.blocked.has(h)||this.log("cannot be both",h,`${f} is a file here and a folder elsewhere`),n.blocked++;continue}let g=this.retries.get(h);if(g&&g.at>r){n.retrying++;continue}try{this.opts.onProgress?.(h),await this.reconcile(h,o.get(h),n,r,i),this.retries.delete(h)}catch(m){this.recordFailure(h,m,n)}}return await this.fill(n),await this.flush(n),this.opts.onProgress?.(void 0),this.blocked=l,this.prune(o),await this.save(),n}entryFor(e){let n=this.entries.get(e);return n||(n=ft(e),this.entries.set(e,n)),n}async reconcile(e,n,r,i,s){let o=this.entryFor(e),a=this.remote.get(e),l=this.limits?.perFileMax??0;if(n&&!n.folder&&l>0&&n.size>l){this.recordFailure(e,Xr(n.size,l),r);return}let c,h;n&&(!n.folder&&dt(o,Math.ceil(n.mtime),n.size)&&(h=await this.rehash(o,e,n.size)),c={folder:n.folder,mtime:o.mtime,size:o.size,hash:o.hash});let u=gn({local:c,remote:a,index:o,mergeable:this.mergeable(e)});if(s&&u.kind!=="nothing"&&c&&!n?.folder&&!vn(o,i)){r.waiting++;return}await this.act(e,u,o,c,a,r,h),this.pending.delete(e)}async rehash(e,n,r){let i=await this.streamScan(e,n,r);if(i)return i;let s=await this.opts.vault.read(n),o=this.mergeable(n),a=[...rn(s,this.sizesFor(s.length,o),o)],l=a.map(c=>c.bytes);if(s.length<=En){let c=await ge(this.opts.keys,l);return e.chunks=c.map(h=>h.name),e.hash=Me(e.chunks),e.size=s.length,{bytes:s,pieces:a,names:e.chunks,sealed:c}}return e.chunks=await this.namesOf(l),e.hash=Me(e.chunks),e.size=s.length,{bytes:s,pieces:a,names:e.chunks}}async streamScan(e,n,r){let i=this.opts.vault;if(!(!i.readBlocks||!i.readRange||this.cannotStream)&&!(r===void 0||r<=En))try{return await this.streamed(e,n,r)}catch(s){this.cannotStream=!0,this.log("streaming is not available here, reading whole files instead",n,{why:s.message});return}}async streamed(e,n,r){let i=this.opts.vault,s=this.mergeable(n),o=[],a=[],l=0;for await(let c of sn(i.readBlocks(n),this.sizesFor(r,s),s)){let h=await ge(this.opts.keys,[c.bytes]);o.push(h[0].name),a.push({start:c.offset,end:c.offset+c.bytes.length}),l+=c.bytes.length}return e.chunks=o,e.hash=Me(o),e.size=l,{names:o,spans:a,path:n,size:l}}namesOf(e){return qr(this.opts.keys,e)}async act(e,n,r,i,s,o,a){switch(n.kind){case"nothing":o.unchanged++,i&&s&&!s.deleted&&i.hash===s.hash&&ve(r,i.hash,r.chunks,s.uid,this.now());return;case"upload":await this.upload(e,r,o,!0,a);return;case"download":case"restoreLocal":{if(!s)return;await this.receive(e,r,s,n.kind,n.why,o);return}case"createLocalFolder":await this.opts.vault.mkdir(e),r.folder=!0,s&&ve(r,"",[],s.uid,this.now()),o.foldersCreated++;return;case"clash":this.skipped.set(e,{why:`${n.why}. Rename one of them, and it will sync.`,fingerprint:vt(r)}),o.skipped++,this.log("cannot be both",e,n.why);return;case"deleteLocal":await this.opts.vault.remove(e),this.entries.delete(e),o.deletedLocally++,this.log("deleted locally",e,n.why);return;case"deleteRemote":await this.queue({path:e,size:0,entry:{path:await this.sealedPath(e),meta:{size:0,ctime:0,mtime:this.now(),deleted:!0},names:[]},bodyOf:xn,commit:l=>{this.remote.set(e,{uid:l,folder:!1,deleted:!0,mtime:this.now(),size:0,hash:""}),this.entries.delete(e),o.deletedRemotely++,this.log("deleted on the server",e,n.why)}},o);return;case"merge":await this.merge(e,r,s,o);return;case"conflict":await this.conflict(e,r,s,o,n.why);return}}async upload(e,n,r,i=!1,s){if(n.folder){await this.queue({path:e,size:0,entry:{path:await this.sealedPath(e),meta:{size:0,ctime:0,mtime:0,folder:!0},names:[]},bodyOf:xn,commit:u=>{ve(n,"",[],u,this.now()),this.remote.set(e,{uid:u,folder:!0,deleted:!1,mtime:0,size:0,hash:""}),i&&r.uploaded++}},r);return}let o=await this.planUpload(n,e,s),a=n.hash,l=[...n.chunks],c=n.size,h=n.mtime;await this.queue({path:e,size:c,entry:{path:await this.sealedPath(e),meta:{size:c,ctime:n.ctime,mtime:h,...n.prev?{prev:await this.sealedPath(n.prev)}:{}},names:o.names},bodyOf:o.bodyOf,commit:u=>{ve(n,a,l,u,this.now()),this.remote.set(e,{uid:u,folder:!1,deleted:!1,mtime:h,size:c,hash:a}),i&&r.uploaded++,this.log("uploaded",e)}},r)}async queue(e,n){this.outbox.push(e),this.outboxBytes+=e.size,(this.outbox.length>=$e||this.outboxBytes>=An)&&await this.flush(n)}async flush(e){if(this.outbox.length===0)return;let n=this.outbox;this.outbox=[],this.outboxBytes=0;let r=new Map;for(let s of n)for(let o of s.entry.names)r.has(o)||r.set(o,s.bodyOf);let i;try{i=await this.opts.transport.putMany(n.map(s=>s.entry),async s=>{let o=r.get(s);if(!o)throw new Error(`server asked for ${s}, which no queued file contains`);return o(s)})}catch(s){for(let o of n)this.recordFailure(o.path,s,e);return}e.chunksSent+=i.uploaded,e.bytesSent+=i.bytes;for(let s=0;s<n.length;s++){let o=n[s],a=i.results[s];if(a.error){this.recordFailure(o.path,a.error,e);continue}o.commit(a.uid)}}async planUpload(e,n,r){let i=r??await this.scan(e,n);if(i.sealed){let c=new Map(i.sealed.map(h=>[h.name,h.bytes]));return{names:i.names,bodyOf:async h=>{let u=c.get(h);if(!u)throw new Error(`no sealed body for ${h} of ${n}`);return u}}}let s=this.opts.keys,o=this.opts.vault;if(i.spans){let c=new Map(i.names.map((h,u)=>[h,i.spans[u]]));return{names:i.names,bodyOf:async h=>{let u=c.get(h);if(!u)throw new Error(`no chunk named ${h} in ${n}`);let f=await o.readRange(i.path,u.start,u.end),g=await ge(s,[f]);if(g[0].name!==h)throw new Error(`${n} changed while it was being sent, so it was not sent`);return g[0].bytes}}}let a=new Map;for(let c=0;c<i.names.length;c++){let h=i.pieces[c];a.set(i.names[c],{start:h.offset,end:h.offset+h.bytes.length})}let l=i.bytes;return{names:i.names,bodyOf:async c=>{let h=a.get(c);if(!h)throw new Error(`no chunk named ${c} in ${n}`);return(await ge(s,[l.subarray(h.start,h.end)]))[0].bytes}}}scan(e,n){return this.rehash(e,n)}async receive(e,n,r,i,s,o){let a=Hr(r.hash);this.checkChunkCount(r.uid,a.length),this.inbox.push({path:e,entry:n,remote:r,chunks:a,kind:i,why:s}),this.inboxBytes+=r.size,(this.inbox.length>=$e||this.inboxBytes>=An)&&await this.fill(o)}async fill(e){if(this.inbox.length===0)return;let n=this.inbox;this.inbox=[],this.inboxBytes=0;let r=[],i=new Set;for(let o of n)for(let a of o.chunks)i.has(a)||(i.add(a),r.push(a));let s=new Map;if(r.length>0)try{let o=await this.opts.transport.fetch(r);for(let a=0;a<r.length;a++)s.set(r[a],o[a])}catch(o){for(let a of n)this.recordFailure(a.path,o,e);return}for(let o of n)try{await this.land(o,s),o.kind==="download"?e.downloaded++:e.restored++,this.log(o.kind,o.path,o.why)}catch(a){this.recordFailure(o.path,a,e)}}async land(e,n){let r=e.chunks.map(s=>{let o=n.get(s);if(!o)throw new Error(`the server did not send ${s}, which ${e.path} is made of`);return o}),i=await this.assemble(e.remote.uid,r);await this.opts.vault.write(e.path,i,{mtime:e.remote.mtime,ctime:e.remote.mtime}),Pe(e.entry,{folder:!1,mtime:e.remote.mtime,ctime:e.remote.mtime,size:i.length}),e.entry.chunks=[...e.chunks],e.entry.hash=Me(e.chunks),e.entry.size=i.length,ve(e.entry,e.entry.hash,e.entry.chunks,e.remote.uid,this.now())}async contentOf(e,n){let r=n!==void 0?{chunks:n}:await this.opts.transport.get(e);return r.chunks.length===0?new Uint8Array(0):(this.checkChunkCount(e,r.chunks.length),this.assemble(e,await this.opts.transport.fetch(r.chunks)))}checkChunkCount(e,n){let r=this.limits?.maxChunks??0;if(r>0&&n>r)throw new Error(`version ${e} names ${n} chunks, and this server said it stores at most ${r}`)}async assemble(e,n){if(n.length===0)return new Uint8Array(0);let r=[],i=0,s=this.limits?.perFileMax??0;for(let l of n){let c=await Xt(this.opts.keys,l);if(i+=c.length,s>0&&i>s)throw new Error(`version ${e} is over ${i} bytes, and this server said it stores at most ${s}`);r.push(c)}let o=new Uint8Array(i),a=0;for(let l of r)o.set(l,a),a+=l.length;return o}async merge(e,n,r,i){if(!r)return;let s=new TextDecoder("utf-8",{fatal:!0}),o,a,l;try{o=s.decode(await this.contentOf(n.syncuid)),a=s.decode(await this.opts.vault.read(e)),l=s.decode(await this.contentOf(r.uid))}catch{let u="one side is not valid UTF-8, so merging it would rewrite bytes nobody edited";this.log("merge refused",e,u),await this.conflict(e,n,r,i,u);return}let c=fn(o,a,l,an(e)?Yr:void 0);if(c.kind==="conflict"){this.log("merge refused",e,c.why),await this.conflict(e,n,r,i,c.why);return}let h=c.text;h!==a&&await this.opts.vault.write(e,new TextEncoder().encode(h),{mtime:this.now(),ctime:n.ctime}),Pe(n,{folder:!1,mtime:this.now(),ctime:n.ctime,size:h.length}),await this.upload(e,n,i),i.merged++,this.log("merged",e,c.kind==="merged"?"three-way":c.why)}freeConflictPath(e){return Zr(dn(e,this.opts.device,new Date(this.now())),n=>this.opts.vault.exists(n))}async conflict(e,n,r,i,s){if(!r)return;let o=await this.freeConflictPath(e),a=await this.contentOf(r.uid);await this.opts.vault.write(o,a,{mtime:r.mtime,ctime:r.mtime});let l=this.entryFor(o);Pe(l,{folder:!1,mtime:r.mtime,ctime:r.mtime,size:a.length}),await this.upload(o,l,i),await this.upload(e,n,i),i.conflicted++,this.log("kept both",e,{copy:o,why:s})}async sealedPath(e){let n=await Be(this.opts.keys,e);return this.unsealed.set(n,e),n}recordFailure(e,n,r){let i=n instanceof Error?n.message:String(n),s=n?.code;if(s!==void 0&&["badentry","badname","toolarge"].includes(s)){this.skipped.set(e,{why:i,fingerprint:vt(this.entries.get(e))}),r.skipped++,this.log("skipped for good",e,i);return}let a=this.retries.get(e)??{count:0,error:"",at:0};a.count++,a.error=i,a.at=this.now()+Math.min(3e5,5e3*Math.pow(2,a.count)),this.retries.set(e,a),r.retrying++,this.log("will retry",e,{attempt:a.count,error:i})}prune(e){for(let[n,r]of this.entries){if(e.has(n))continue;let i=this.remote.get(n);i&&!i.deleted||r.synchash===""&&r.hash===""&&this.entries.delete(n)}for(let[n,r]of this.remote)r.deleted&&(e.has(n)||this.entries.has(n)||this.pending.has(n)||this.remote.delete(n))}async save(){let e={};for(let[r,i]of this.entries)e[r]=i;let n={};for(let[r,i]of this.remote)n[r]=i;await this.opts.store.save({cursor:this.cursor,entries:e,remote:n,pending:[...this.pending]})}noteRename(e,n){let r=this.entries.get(e);r&&(this.entries.delete(e),mn(r,e,n),this.entries.set(n,r))}};function jr(t,e){let n={...t};for(let r of Object.keys(n))n[r]=t[r]+e[r];return n}function vt(t){return t?`${t.mtime}:${t.size}`:"gone"}var En=8*1024*1024,Gr=16;async function qr(t,e,n=Gr){let r=[];for(let i=0;i<e.length;i+=n){let s=await ge(t,e.slice(i,i+n));for(let o of s)r.push(o.name)}return r}var An=8*1024*1024;async function Zr(t,e){if(!await e(t))return t;let n=t.lastIndexOf("."),r=t.lastIndexOf("/"),i=n>r,s=i?t.slice(0,n):t,o=i?t.slice(n):"";for(let a=2;a<1e3;a++){let l=`${s} ${a}${o}`;if(!await e(l))return l}throw new Error(`cannot find an unused name beside ${t}`)}function Xr(t,e){let n=new Error(`${t} bytes, and this server said it stores at most ${e}, so it was not read`);return n.code="toolarge",n}async function xn(t){throw new Error(`this put has no bodies, and the server asked for ${t}`)}function Yr(t){try{return JSON.parse(t),!0}catch{return!1}}var Qr=150,_e=class{constructor(e){this.opts=e;let n;this.transport=new Ve(e.url,{onBatch:async r=>{await n.acceptBatch(r),r.entries.length>0&&this.soon()},onCaughtUp:()=>{this.caughtUp=!0},onClosed:r=>{this.endedWith=r,this.notifyEnded?.(r)},...e.timeoutMs!==void 0?{timeoutMs:e.timeoutMs}:{},...e.log!==void 0?{log:e.log}:{},...e.socketFactory!==void 0?{socketFactory:e.socketFactory}:{}}),n=new Ke({vault:e.vault,store:e.store,keys:e.keys,transport:this.transport,device:e.device,vaultId:e.vaultId,token:e.token,...e.claim!==void 0?{claim:e.claim}:{},...e.coalesceWrites!==void 0?{coalesceWrites:e.coalesceWrites}:{},...e.log!==void 0?{log:e.log}:{},...e.onProgress!==void 0?{onProgress:e.onProgress}:{}}),this.engine=n}opts;engine;transport;limits;soonTimer;caughtUp=!1;endedWith;notifyEnded;queue=Promise.resolve();serial(e){let n=this.queue.then(e,e);return this.queue=n.catch(()=>{}),n}get requestsSent(){return this.transport.requestsSent}get serverCursor(){return this.limits?.cursor??0}async connect(){await this.transport.connect(),this.limits=await this.engine.start();let e=this.opts.timeoutMs??3e4,n=Date.now()+e;for(;!this.caughtUp&&Date.now()<n;){if(this.endedWith)throw this.endedWith;await pt(25)}if(!this.caughtUp)throw new Error("the server never finished sending what it already had");return this.limits}async settle(e={},n=8){let r=await this.pass(e),i=r;for(let s=0;s<n&&ri(r);s++)await pt(60),r=await this.pass(e),i=ni(i,r);return i}pass(e){return this.serial(()=>this.engine.sync(e))}async runUntilClosed(e=3e4){if(this.endedWith)return this.endedWith;let n=this.opts.vault.watch?.(()=>{this.sync()}),r=setInterval(()=>{this.sync().then(()=>this.keepalive())},e);try{return await new Promise(i=>{this.notifyEnded=i})}finally{clearInterval(r),n?.()}}async keepalive(){try{await this.transport.ping()}catch{}}soon(){this.soonTimer===void 0&&(this.soonTimer=setTimeout(()=>{this.soonTimer=void 0,this.sync()},Qr))}async sync(e={}){try{return await this.pass(e)}catch(n){this.opts.log?.("sync failed",n.message);return}}async history(e,n={}){let r=await Be(this.opts.keys,e);return(await this.serial(()=>this.transport.history(r,n))).map(s=>this.asVersion(s,e))}async deleted(e){let n=await this.serial(()=>this.transport.deleted(e)),r=[];for(let i of n.entries)r.push({...this.asVersion(i,await Le(this.opts.keys,i.path)),restorable:i.restorable??0});return{notes:r,more:n.more}}async contentAt(e){return e.deleted||e.folder?new Uint8Array(0):this.serial(()=>this.engine.contentOf(e.uid))}async restore(e,n){if(e.deleted)throw new Error(`version ${e.uid} of ${e.path} is the deletion itself, not a version to restore`);if(e.folder){let o=n??e.path;return await this.opts.vault.mkdir(o),{path:o,bytes:0}}let r=await this.serial(()=>this.engine.contentOf(e.uid)),i=n??e.path,s=await this.opts.vault.exists(i)?ei(i,e):i;return await this.opts.vault.write(s,r,{mtime:e.mtime,ctime:e.ctime}),{path:s,bytes:r.length}}async newestContentVersion(e){return(await this.history(e,{limit:50})).find(r=>!r.deleted)}asVersion(e,n){return{uid:e.uid,path:n,size:e.size,ctime:e.ctime,mtime:e.mtime,folder:e.folder,deleted:e.deleted,device:e.device,chunks:e.chunks?.length??0}}close(){this.soonTimer!==void 0&&(clearTimeout(this.soonTimer),this.soonTimer=void 0),this.transport.close()}};function ei(t,e){let n=t.lastIndexOf("/"),r=n===-1?"":t.slice(0,n+1),i=n===-1?t:t.slice(n+1),s=i.lastIndexOf("."),o=s<=0?i:i.slice(0,s),a=s<=0?"":i.slice(s);return`${r}${o} (restored ${e.uid})${a}`}async function Pn(t,e={}){let n=new Je(0,3e5,5e3,!0);for(;e.keepGoing?.()??!0;){let r,i,s=!1;try{r=new _e(t),await r.connect(),s=!0,n.success(Date.now()),e.onClient?.(r),e.onSynced?.(await r.settle(),r.serverCursor),i=await r.runUntilClosed()}catch(l){i=l}finally{e.onClient?.(void 0),r?.close()}if(i&&ti(i)){e.onFatal?.(i);return}if(!(e.keepGoing?.()??!0))return;n.fail(Date.now());let o=n.delay(),a=i??new Error("the connection ended");s?e.onDisconnected?.(a,o):e.onUnreachable?.(a,o),await pt(o)}}function ti(t){return t instanceof P&&t.fatal}function ni(t,e){return{uploaded:t.uploaded+e.uploaded,downloaded:t.downloaded+e.downloaded,merged:t.merged+e.merged,conflicted:t.conflicted+e.conflicted,deletedLocally:t.deletedLocally+e.deletedLocally,deletedRemotely:t.deletedRemotely+e.deletedRemotely,restored:t.restored+e.restored,foldersCreated:t.foldersCreated+e.foldersCreated,chunksSent:t.chunksSent+e.chunksSent,bytesSent:t.bytesSent+e.bytesSent,unchanged:e.unchanged,waiting:e.waiting,retrying:e.retrying,skipped:e.skipped,blocked:e.blocked}}function ri(t){return t.uploaded+t.downloaded+t.merged+t.conflicted+t.deletedLocally+t.deletedRemotely+t.restored+t.foldersCreated+t.waiting>0}var pt=t=>new Promise(e=>setTimeout(e,t));var He="basalt2_",yt=2,Ce=4,$n=new TextEncoder,ii=new TextDecoder;function wt(t){if(t.secret.length!==Z)throw new Error(`a root secret is ${Z} bytes, not ${t.secret.length}`);let e=[$n.encode(t.url),$n.encode(t.vaultId)];for(let o of e)if(o.length>255)throw new Error("a pairing field is too long to encode");let n=1+Z+e.reduce((o,a)=>o+1+a.length,0),r=new Uint8Array(n);r[0]=yt,r.set(t.secret,1);let i=1+Z;for(let o of e)r[i++]=o.length,r.set(o,i),i+=o.length;let s=new Uint8Array(n+Ce);return s.set(r,0),s.set(_n(r),n),He+xe(s)}function Mn(t){let e=t.trim();if(e.startsWith("basalt1_"))throw new Error("this is a version 1 pairing string, from before the server token was folded into the root secret. Run basalt invite on a device that is already paired to get a current one.");if(!e.startsWith(He))throw new Error(`not a pairing string: it should start with ${He}`);let n;try{n=We(e.slice(He.length))}catch{throw new Error("this pairing string is damaged: it is not valid base64url")}if(n.length<1+Z+2+Ce)throw new Error("this pairing string is too short to be complete");let r=n.subarray(0,n.length-Ce),i=n.subarray(n.length-Ce),s=_n(r);for(let u=0;u<Ce;u++)if(i[u]!==s[u])throw new Error("this pairing string is damaged: it did not survive being copied");if(r[0]!==yt)throw new Error(`this pairing string is version ${r[0]}, and this device understands ${yt}`);let o=r.slice(1,1+Z),a=1+Z,l=u=>{if(a>=r.length)throw new Error(`this pairing string ends before its ${u}`);let f=r[a++];if(a+f>r.length)throw new Error(`this pairing string ends inside its ${u}`);let g=ii.decode(r.subarray(a,a+f));return a+=f,g},c=l("server address"),h=l("vault name");if(a!==r.length)throw new Error("this pairing string has more in it than it should");if(c===""||h==="")throw new Error("this pairing string has an empty field");return{url:c,secret:o,vaultId:h}}function _n(t){let e=4294967295;for(let n of t){e^=n;for(let r=0;r<8;r++)e=e&1?e>>>1^3988292384:e>>>1}return e=(e^4294967295)>>>0,new Uint8Array([e>>>24&255,e>>>16&255,e>>>8&255,e&255])}function Cn(t){return{url:t.url,vaultId:t.vaultId,device:t.device,secret:xe(t.secret),...t.bootstrap?{bootstrap:t.bootstrap}:{}}}function Tn(t,e){if(typeof t!="object"||t===null)throw new Error(`${e} does not hold a configuration`);let n=t,r=o=>{let a=n[o];if(typeof a!="string"||a==="")throw new Error(`${e} has no ${o}`);return a},i=We(r("secret"));if(i.length!==Z)throw new Error(`${e} holds a ${i.length} byte secret, and a root secret is ${Z}`);let s=n.bootstrap;return{url:r("url"),vaultId:r("vaultId"),device:r("device"),secret:i,...typeof s=="string"&&s!==""?{bootstrap:s}:{}}}function Rn(t){let e=t.trim().replace(/\/+$/,"");if(e==="")throw new Error("that is not a server address");if(e.startsWith("ws://")||e.startsWith("wss://"))return e;if(e.startsWith("http://"))return"ws://"+e.slice(7);if(e.startsWith("https://"))return"wss://"+e.slice(8);if(e.includes("://"))throw new Error(`a server address is ws:// or wss://, not ${e.split("://")[0]}://`);return"wss://"+e}import{constants as bt,watch as si}from"node:fs";import{access as kt,cp as oi,mkdir as je,open as Ge,readFile as On,readdir as ai,rename as Fn,rm as li,stat as hi,utimes as ci}from"node:fs/promises";import{basename as St,dirname as qe,join as In,relative as ui,resolve as Dn,sep as Un}from"node:path";var Nn=".trash",fi=new Set([".basalt",Nn,".git",".DS_Store","node_modules"]),Et=".obsidian";function At(t){let e=t.replace(/^\/+|\/+$/g,"");if(e===""||e.includes("/"))throw new Error(`refusing to sync: the config folder ${JSON.stringify(t)} is not a plain name`);return e}var Ze=class{root;ignore;constructor(e,n={}){this.root=Dn(e);let r=At(n.configDir??Et);this.ignore=new Set([...fi,r,...n.alsoIgnore??[]])}absolute(e){let n=Dn(this.root,e),r=ui(this.root,n);if(r===""||r.startsWith("..")||r.startsWith(`..${Un}`))throw new Error(`refusing a path outside the vault: ${e}`);return n}async list(){let e=[],n=async(r,i)=>{let s;try{s=await ai(r,{withFileTypes:!0})}catch(o){throw new Error(`cannot read ${r}: ${o.message}`)}for(let o of s){if(this.ignore.has(o.name)||zn(o.name))continue;let a=i?`${i}/${o.name}`:o.name,l=In(r,o.name);if(o.isDirectory())e.push({path:a,folder:!0,mtime:0,ctime:0,size:0}),await n(l,a);else if(o.isFile()){let c=await hi(l);e.push({path:a,folder:!1,mtime:c.mtimeMs,ctime:c.birthtimeMs||c.ctimeMs,size:c.size})}}};return await n(this.root,""),e}async read(e){return new Uint8Array(await On(this.absolute(e)))}async*readBlocks(e,n=1024*1024){let r=await Ge(this.absolute(e),"r");try{let i=new Uint8Array(n);for(;;){let{bytesRead:s}=await r.read(i,0,n,null);if(s===0)return;yield i.slice(0,s)}}finally{await r.close()}}async readRange(e,n,r){let i=await Ge(this.absolute(e),"r");try{let s=new Uint8Array(r-n),o=0;for(;o<s.length;){let{bytesRead:a}=await i.read(s,o,s.length-o,n+o);if(a===0)break;o+=a}return o===s.length?s:s.subarray(0,o)}finally{await i.close()}}async write(e,n,r){let i=this.absolute(e);if(await je(qe(i),{recursive:!0}),await Ln(i,n),r.mtime>0){let s=r.mtime/1e3;await ci(i,s,s)}}async remove(e){let n=this.absolute(e);try{await kt(n,bt.F_OK)}catch{return}let r=await this.freeTrashPath(e);await je(qe(r),{recursive:!0});try{await Fn(n,r);return}catch(i){if(i.code!=="EXDEV")throw i}await oi(n,r,{recursive:!0}),await li(n,{recursive:!0,force:!0})}async freeTrashPath(e){let n=In(this.root,Nn,e),r=St(e).lastIndexOf("."),[i,s]=r<=0?[n,""]:[n.slice(0,n.length-(St(e).length-r)),n.slice(n.length-(St(e).length-r))];for(let o=0;o<1e3;o++){let a=o===0?n:`${i} (${o})${s}`;try{await kt(a,bt.F_OK)}catch{return a}}throw new Error(`the trash already holds a thousand copies of ${e}`)}async mkdir(e){await je(this.absolute(e),{recursive:!0})}async exists(e){try{return await kt(this.absolute(e),bt.F_OK),!0}catch{return!1}}watch(e){let n,r="",i;try{i=si(this.root,{recursive:!0,persistent:!0},(s,o)=>{if(!o)return;let a=o.toString().split(Un).join("/");a.split("/").some(l=>this.ignore.has(l))||zn(a)||(r=a,n&&clearTimeout(n),n=setTimeout(()=>{n=void 0,e(r)},150))}),i.on("error",()=>{})}catch{return()=>{}}return()=>{n&&clearTimeout(n),i?.close()}}},Te=class{constructor(e){this.file=e}file;async load(){let e;try{e=await On(this.file,"utf8")}catch(n){if(n.code==="ENOENT")return;throw new Error(`cannot read the index at ${this.file}: ${n.message}`)}try{return JSON.parse(e)}catch(n){throw new Error(`the index at ${this.file} is not valid JSON, so it cannot be trusted: ${n.message}`)}}async save(e){await je(qe(this.file),{recursive:!0}),await Ln(this.file,new TextEncoder().encode(JSON.stringify(e)))}},Bn=".basalt-tmp-";function zn(t){return t.includes(Bn)}var di=0;async function gi(t){for(let e=0;e<64;e++){let n=`${t}${Bn}${(di++).toString(36)}${e?`-${e}`:""}`;try{return{tmp:n,handle:await Ge(n,"wx")}}catch(r){if(r.code!=="EEXIST")throw r}}throw new Error(`could not find an unused temporary name beside ${t}`)}async function Ln(t,e){let{tmp:n,handle:r}=await gi(t);try{await r.write(e),await r.sync()}finally{await r.close()}await Fn(n,t);let i=await Ge(qe(t),"r");try{await i.sync()}finally{await i.close()}}import{chmod as mi,mkdir as vi,readFile as pi,rename as yi,rm as Wn,writeFile as wi}from"node:fs/promises";import{join as xt}from"node:path";var Pt=".basalt",$t=t=>xt(t,Pt,"config.json"),Xe=t=>xt(t,Pt,"index.json");async function Re(t){let e=$t(t),n;try{n=await pi(e,"utf8")}catch(i){if(i.code==="ENOENT")return;throw new Error(`cannot read ${e}: ${i.message}`)}let r;try{r=JSON.parse(n)}catch(i){throw new Error(`${e} is not valid JSON, so it cannot be trusted: ${i.message}`)}return Tn(r,e)}async function Ye(t,e){let n=xt(t,Pt);await vi(n,{recursive:!0});let r=$t(t),i=`${r}.tmp`;await wi(i,JSON.stringify(Cn(e),null,2)+`
9
+ `,{mode:384}),await mi(i,384),await yi(i,r)}async function Vn(t){await Wn($t(t),{force:!0}),await Wn(Xe(t),{force:!0})}var Jn=`basalt: self-hosted sync for Obsidian
10
10
 
11
11
  basalt init --server URL --token TOKEN claim a new vault, with the server's first-run token
12
12
  basalt pair PAIRING-STRING pair this vault with an existing one
@@ -28,6 +28,8 @@ Options
28
28
  --uid N restore one exact version, from basalt history
29
29
  --to PATH restore somewhere other than where it came from
30
30
  --limit N how many versions history shows (default: 20)
31
- `;async function Jn(n,e){let t;try{t=Ci(n)}catch(r){return e.err(String(r.message)),2}if(t.help||t.command===void 0)return e.out(Wn),t.command===void 0&&!t.help?2:0;try{switch(t.command){case"init":return await bi(t,e);case"pair":return await ki(t,e);case"invite":return await Si(t,e);case"sync":return await Ei(t,e);case"status":return await xi(t,e);case"deleted":return await Pi(t,e);case"history":return await $i(t,e);case"restore":return await Mi(t,e);case"unlink":return await _i(t,e);default:return e.err(`no such command: ${t.command}`),e.err(Wn),2}}catch(r){let i=r instanceof Error?r.message:String(r);return t.json?e.out(JSON.stringify({ok:!1,error:i})):e.err(`basalt: ${i}`),1}}async function bi(n,e){if(!n.server||!n.token)throw new Error("init needs --server and --token, from the server's first run");if(await Re(n.dir))throw new Error(`${n.dir} is already paired. Use unlink first if that is really what you want.`);let t={url:Cn(n.server),vaultId:n.vaultId,device:n.device,secret:Vt(),bootstrap:n.token};await Ye(n.dir,t);let r=wt(t);return n.json?e.out(JSON.stringify({ok:!0,paired:n.dir,device:t.device,pairing:r})):(e.out(`Paired ${n.dir} as "${t.device}".`),e.out(""),e.out("Give this to every other device. Anyone who has it has the vault:"),e.out(""),e.out(` ${r}`),e.out(""),e.out("It is the only copy. The server cannot reissue it, because the server"),e.out("has never seen the secret in it.")),0}async function ki(n,e){if(!n.rest[0])throw new Error("pair needs the string another device printed");if(await Re(n.dir))throw new Error(`${n.dir} is already paired. Use unlink first if that is really what you want.`);let r={...Pn(n.rest[0]),device:n.device};return await Ye(n.dir,r),n.json?e.out(JSON.stringify({ok:!0,paired:n.dir,device:r.device,url:r.url})):e.out(`Paired ${n.dir} with ${r.url} as "${r.device}". Run basalt sync.`),0}async function Si(n,e){let t=await pe(n.dir),r=wt(t);return n.json?e.out(JSON.stringify({ok:!0,pairing:r})):(e.out(r),e.err("Anyone who has that string has this vault.")),0}async function Ei(n,e){let t=await pe(n.dir);if(n.watch)return await Ai(t,n,e);let r=await Ie(t,n,e);try{let i=await r.settle();return Hn(i,n,e,r.serverCursor),i.skipped>0||i.retrying>0?1:0}finally{r.close()}}async function Ai(n,e,t){let r;return await An(await Kn(n,e,t),{onSynced:(i,s)=>{Hn(i,e,t,s),e.json||t.err("Watching for changes. Ctrl-C to stop.")},onDisconnected:(i,s)=>{t.err(`Disconnected: ${i.message}. Trying again in ${Vn(s)}.`)},onUnreachable:(i,s)=>{t.err(`Cannot reach the server: ${i.message}. Trying again in ${Vn(s)}.`)},onFatal:i=>{r=i}}),r?(t.err(`basalt: ${r.message}`),t.err("That will not fix itself by trying again."),1):0}async function xi(n,e){let t=await pe(n.dir),r=await new Te(Xe(n.dir)).load(),i={vault:n.dir,device:t.device,server:t.url,vaultId:t.vaultId,cursor:r?.cursor??0,tracked:r?Object.keys(r.entries).length:0,pending:r?.pending.length??0},s;try{let o=await Ie(t,n,e);s={reachable:!0,cursor:o.serverCursor,behind:Math.max(0,o.serverCursor-i.cursor)},o.close()}catch(o){s={reachable:!1,error:o.message}}return n.json?(e.out(JSON.stringify({ok:!0,...i,server:s})),s.reachable?0:1):(e.out(`vault ${i.vault}`),e.out(`device ${i.device}`),e.out(`server ${i.server} (vault "${i.vaultId}")`),e.out(`tracked ${i.tracked} files`),e.out(`cursor ${i.cursor}`),i.pending>0&&e.out(`pending ${i.pending} files with work outstanding`),s.reachable?(e.out(s.behind===0?"state up to date with the server":`state ${s.behind} changes behind`),0):(e.out(`state cannot reach the server: ${s.error}`),1))}async function Pi(n,e){let t=await pe(n.dir),r=await Ie(t,n,e);try{let i=await r.deleted(n.limit>20?n.limit:void 0);if(n.json)return e.out(JSON.stringify({ok:!0,deleted:i.notes,more:i.more})),0;if(i.notes.length===0)return e.out("Nothing has been deleted from this vault."),0;let s=0;for(let a of i.notes){let l=a.restorable===0?" (content purged)":"";a.restorable===0&&s++,e.out(`${Pt(a.mtime)} ${a.device.padEnd(12)} ${a.path}${l}`)}e.out("");let o=i.notes.length-s;return s===0?e.out(`${o} deleted, all still recoverable. basalt restore PATH brings one back.`):e.out(`${i.notes.length} deleted. ${o} can be restored; ${s} had their history purged and cannot be.`),i.more&&e.out("There are older deletions than these. --limit N shows more."),0}finally{r.close()}}async function $i(n,e){let t=n.rest[0];if(!t)throw new Error("history needs the path of a note");let r=await pe(n.dir),i=await Ie(r,n,e);try{let s=await i.history(t,{limit:n.limit});if(n.json)return e.out(JSON.stringify({ok:!0,path:t,versions:s})),0;if(s.length===0)return e.out(`The server holds no versions of ${t}.`),0;for(let o of s){let a=o.deleted?"deleted":o.folder?"folder":`${$t(o.size)}`;e.out(`${String(o.uid).padStart(7)} ${Pt(o.mtime)} ${o.device.padEnd(12)} ${a}`)}return e.out(""),e.out("basalt restore PATH --uid N brings one of these back."),0}finally{i.close()}}async function Mi(n,e){let t=n.rest[0];if(!t)throw new Error("restore needs the path of a note");let r=await pe(n.dir),i=await Ie(r,n,e);try{let s;if(n.uid!==void 0){if(s=(await i.history(t,{limit:500})).find(c=>c.uid===n.uid),!s)throw new Error(`the server has no version ${n.uid} of ${t}`)}else if(s=await i.newestContentVersion(t),!s)throw new Error(`the server holds no version of ${t} with any content in it`);let o=await i.restore(s,n.to),a=await i.settle({coalesceWrites:!1});return n.json?(e.out(JSON.stringify({ok:!0,path:o.path,uid:s.uid,bytes:o.bytes,sync:a})),0):(e.out(`Restored version ${s.uid} of ${t} (${$t(o.bytes)}, from ${Pt(s.mtime)}).`),o.path!==(n.to??t)&&e.out(`Written to ${o.path}, because something is already at ${n.to??t}.`),a.uploaded>0&&e.out("Sent to the server, so your other devices will pick it up."),0)}finally{i.close()}}async function _i(n,e){let t=await Re(n.dir).catch(()=>{});return await Ln(n.dir),n.json?e.out(JSON.stringify({ok:!0,unlinked:n.dir,wasPaired:t!==void 0})):(e.out(`Forgot the pairing for ${n.dir}. Every note is where it was.`),e.out("Nothing was removed from the server.")),0}async function Ie(n,e,t){let r=new _e(await Kn(n,e,t));if(await r.connect(),n.bootstrap){let{bootstrap:i,...s}=n;await Ye(e.dir,s)}return r}async function Kn(n,e,t){let r=await Jt(n.secret),i=Zt(r);return{vault:new Ze(e.dir),store:new Te(Xe(e.dir)),keys:r,url:n.url,token:n.bootstrap??i,claim:i,vaultId:n.vaultId,device:n.device,timeoutMs:e.timeout,coalesceWrites:e.watch,...e.watch&&t?{onProgress:s=>{s!==void 0&&t.err(` ... ${s}`)}}:{},...e.verbose&&t?{log:(s,...o)=>t.err(` ${s} ${o.map(Ti).join(" ")}`.trimEnd())}:{}}}function Hn(n,e,t,r){if(e.json){t.out(JSON.stringify({ok:!0,...n,serverCursor:r}));return}let i=[],s=(o,a)=>{o>0&&i.push(`${String(o).padStart(5)} ${a}`)};if(s(n.uploaded,"uploaded"),s(n.downloaded,"downloaded"),s(n.merged,"merged"),s(n.conflicted,"kept both versions"),s(n.deletedLocally,"deleted here"),s(n.deletedRemotely,"deleted on the server"),s(n.restored,"brought back, having been edited elsewhere"),s(n.foldersCreated,"folders created"),s(n.waiting,"waiting for a write to settle"),s(n.retrying,"failed, will try again"),s(n.skipped,"cannot sync and will not be retried"),s(n.blocked,"waiting on a name that is a file here and a folder elsewhere"),i.length===0)t.out("Nothing to do. Everything here matches the server.");else for(let o of i)t.out(o);n.chunksSent>0&&t.out(`${String(n.chunksSent).padStart(5)} chunks sent, ${$t(n.bytesSent)}`),n.conflicted>0&&t.err('Look for files with "Conflicted copy" in the name. Both versions are kept.')}function Ci(n){let e={rest:[],dir:process.cwd(),device:yi().split(".")[0]||"device",vaultId:"default",json:!1,watch:!1,limit:20,verbose:!1,help:!1,timeout:3e4},t=new Set(["--dir","--device","--vault-id","--server","--token","--timeout","--uid","--to","--limit"]);for(let r=0;r<n.length;r++){let i=n[r],s;if(t.has(i)&&(s=n[++r],s===void 0||s.startsWith("--")))throw new Error(`${i} needs a value`);switch(i){case"--dir":e.dir=wi(s);break;case"--device":e.device=s;break;case"--vault-id":e.vaultId=s;break;case"--server":e.server=s;break;case"--token":e.token=s;break;case"--timeout":{let o=Number(s);if(!Number.isFinite(o)||o<=0)throw new Error(`--timeout wants a number of milliseconds, not ${s}`);e.timeout=o;break}case"--uid":{let o=Number(s);if(!Number.isInteger(o)||o<=0)throw new Error(`--uid wants a version number, not ${s}`);e.uid=o;break}case"--to":e.to=s;break;case"--limit":{let o=Number(s);if(!Number.isInteger(o)||o<=0)throw new Error(`--limit wants a count, not ${s}`);e.limit=o;break}case"--json":e.json=!0;break;case"--watch":e.watch=!0;break;case"--verbose":case"-v":e.verbose=!0;break;case"--help":case"-h":e.help=!0;break;default:if(i.startsWith("-"))throw new Error(`no such option: ${i}`);e.command===void 0?e.command=i:e.rest.push(i)}}return e}async function pe(n){let e=await Re(n);if(!e)throw new Error(`${n} is not paired. Run basalt init or basalt pair first.`);return e}function Pt(n){if(!Number.isFinite(n)||n<=0)return"unknown ";let e=new Date(n),t=r=>String(r).padStart(2,"0");return`${e.getFullYear()}-${t(e.getMonth()+1)}-${t(e.getDate())} ${t(e.getHours())}:${t(e.getMinutes())}`}function Vn(n){return`${Math.max(1,Math.round(n/1e3))}s`}function $t(n){return n<1024?`${n} B`:n<1024*1024?`${(n/1024).toFixed(1)} KiB`:`${(n/(1024*1024)).toFixed(1)} MiB`}function Ti(n){return typeof n=="string"?n:JSON.stringify(n)}var Ri=await Jn(process.argv.slice(2),{out:n=>process.stdout.write(n+`
32
- `),err:n=>process.stderr.write(n+`
33
- `)});process.exit(Ri);
31
+ --config-dir DIR Obsidian's config folder, if it is not .obsidian
32
+ --ignore NAME a top-level name never to sync, repeatable
33
+ `;async function Hn(t,e){let n;try{n=Ri(t)}catch(r){return e.err(String(r.message)),2}if(n.help||n.command===void 0)return e.out(Jn),n.command===void 0&&!n.help?2:0;try{switch(n.command){case"init":return await Si(n,e);case"pair":return await Ei(n,e);case"invite":return await Ai(n,e);case"sync":return await xi(n,e);case"status":return await $i(n,e);case"deleted":return await Mi(n,e);case"history":return await _i(n,e);case"restore":return await Ci(n,e);case"unlink":return await Ti(n,e);default:return e.err(`no such command: ${n.command}`),e.err(Jn),2}}catch(r){let i=r instanceof Error?r.message:String(r);return n.json?e.out(JSON.stringify({ok:!1,error:i})):e.err(`basalt: ${i}`),1}}async function Si(t,e){if(!t.server||!t.token)throw new Error("init needs --server and --token, from the server's first run");if(await Re(t.dir))throw new Error(`${t.dir} is already paired. Use unlink first if that is really what you want.`);let n={url:Rn(t.server),vaultId:t.vaultId,device:t.device,secret:Kt(),bootstrap:t.token};await Ye(t.dir,n);let r=wt(n);return t.json?e.out(JSON.stringify({ok:!0,paired:t.dir,device:n.device,pairing:r})):(e.out(`Paired ${t.dir} as "${n.device}".`),e.out(""),e.out("Give this to every other device. Anyone who has it has the vault:"),e.out(""),e.out(` ${r}`),e.out(""),e.out("It is the only copy. The server cannot reissue it, because the server"),e.out("has never seen the secret in it.")),0}async function Ei(t,e){if(!t.rest[0])throw new Error("pair needs the string another device printed");if(await Re(t.dir))throw new Error(`${t.dir} is already paired. Use unlink first if that is really what you want.`);let r={...Mn(t.rest[0]),device:t.device};return await Ye(t.dir,r),t.json?e.out(JSON.stringify({ok:!0,paired:t.dir,device:r.device,url:r.url})):e.out(`Paired ${t.dir} with ${r.url} as "${r.device}". Run basalt sync.`),0}async function Ai(t,e){let n=await pe(t.dir),r=wt(n);return t.json?e.out(JSON.stringify({ok:!0,pairing:r})):(e.out(r),e.err("Anyone who has that string has this vault.")),0}async function xi(t,e){let n=await pe(t.dir);if(t.watch)return await Pi(n,t,e);let r=await Ie(n,t,e);try{let i=await r.settle();return Gn(i,t,e,r.serverCursor),i.skipped>0||i.retrying>0?1:0}finally{r.close()}}async function Pi(t,e,n){let r;return await Pn(await jn(t,e,n),{onSynced:(i,s)=>{Gn(i,e,n,s),e.json||n.err("Watching for changes. Ctrl-C to stop.")},onDisconnected:(i,s)=>{n.err(`Disconnected: ${i.message}. Trying again in ${Kn(s)}.`)},onUnreachable:(i,s)=>{n.err(`Cannot reach the server: ${i.message}. Trying again in ${Kn(s)}.`)},onFatal:i=>{r=i}}),r?(n.err(`basalt: ${r.message}`),n.err("That will not fix itself by trying again."),1):0}async function $i(t,e){let n=await pe(t.dir),r=await new Te(Xe(t.dir)).load(),i={vault:t.dir,device:n.device,server:n.url,vaultId:n.vaultId,cursor:r?.cursor??0,tracked:r?Object.keys(r.entries).length:0,pending:r?.pending.length??0},s;try{let o=await Ie(n,t,e);s={reachable:!0,cursor:o.serverCursor,behind:Math.max(0,o.serverCursor-i.cursor)},o.close()}catch(o){s={reachable:!1,error:o.message}}return t.json?(e.out(JSON.stringify({ok:!0,...i,server:s})),s.reachable?0:1):(e.out(`vault ${i.vault}`),e.out(`device ${i.device}`),e.out(`server ${i.server} (vault "${i.vaultId}")`),e.out(`tracked ${i.tracked} files`),e.out(`cursor ${i.cursor}`),i.pending>0&&e.out(`pending ${i.pending} files with work outstanding`),s.reachable?(e.out(s.behind===0?"state up to date with the server":`state ${s.behind} changes behind`),0):(e.out(`state cannot reach the server: ${s.error}`),1))}async function Mi(t,e){let n=await pe(t.dir),r=await Ie(n,t,e);try{let i=await r.deleted(t.limit>20?t.limit:void 0);if(t.json)return e.out(JSON.stringify({ok:!0,deleted:i.notes,more:i.more})),0;if(i.notes.length===0)return e.out("Nothing has been deleted from this vault."),0;let s=0;for(let a of i.notes){let l=a.restorable===0?" (content purged)":"";a.restorable===0&&s++,e.out(`${Mt(a.mtime)} ${a.device.padEnd(12)} ${a.path}${l}`)}e.out("");let o=i.notes.length-s;return s===0?e.out(`${o} deleted, all still recoverable. basalt restore PATH brings one back.`):e.out(`${i.notes.length} deleted. ${o} can be restored; ${s} had their history purged and cannot be.`),i.more&&e.out("There are older deletions than these. --limit N shows more."),0}finally{r.close()}}async function _i(t,e){let n=t.rest[0];if(!n)throw new Error("history needs the path of a note");let r=await pe(t.dir),i=await Ie(r,t,e);try{let s=await i.history(n,{limit:t.limit});if(t.json)return e.out(JSON.stringify({ok:!0,path:n,versions:s})),0;if(s.length===0)return e.out(`The server holds no versions of ${n}.`),0;for(let o of s){let a=o.deleted?"deleted":o.folder?"folder":`${_t(o.size)}`;e.out(`${String(o.uid).padStart(7)} ${Mt(o.mtime)} ${o.device.padEnd(12)} ${a}`)}return e.out(""),e.out("basalt restore PATH --uid N brings one of these back."),0}finally{i.close()}}async function Ci(t,e){let n=t.rest[0];if(!n)throw new Error("restore needs the path of a note");let r=await pe(t.dir),i=await Ie(r,t,e);try{let s;if(t.uid!==void 0){if(s=(await i.history(n,{limit:500})).find(c=>c.uid===t.uid),!s)throw new Error(`the server has no version ${t.uid} of ${n}`)}else if(s=await i.newestContentVersion(n),!s)throw new Error(`the server holds no version of ${n} with any content in it`);let o=await i.restore(s,t.to),a=await i.settle({coalesceWrites:!1});return t.json?(e.out(JSON.stringify({ok:!0,path:o.path,uid:s.uid,bytes:o.bytes,sync:a})),0):(e.out(`Restored version ${s.uid} of ${n} (${_t(o.bytes)}, from ${Mt(s.mtime)}).`),o.path!==(t.to??n)&&e.out(`Written to ${o.path}, because something is already at ${t.to??n}.`),a.uploaded>0&&e.out("Sent to the server, so your other devices will pick it up."),0)}finally{i.close()}}async function Ti(t,e){let n=await Re(t.dir).catch(()=>{});return await Vn(t.dir),t.json?e.out(JSON.stringify({ok:!0,unlinked:t.dir,wasPaired:n!==void 0})):(e.out(`Forgot the pairing for ${t.dir}. Every note is where it was.`),e.out("Nothing was removed from the server.")),0}async function Ie(t,e,n){let r=new _e(await jn(t,e,n));if(await r.connect(),t.bootstrap){let{bootstrap:i,...s}=t;await Ye(e.dir,s)}return r}async function jn(t,e,n){let r=await Ht(t.secret),i=Yt(r);return{vault:new Ze(e.dir,{configDir:e.configDir,alsoIgnore:e.ignore}),store:new Te(Xe(e.dir)),keys:r,url:t.url,token:t.bootstrap??i,claim:i,vaultId:t.vaultId,device:t.device,timeoutMs:e.timeout,coalesceWrites:e.watch,...e.watch&&n?{onProgress:s=>{s!==void 0&&n.err(` ... ${s}`)}}:{},...e.verbose&&n?{log:(s,...o)=>n.err(` ${s} ${o.map(Ii).join(" ")}`.trimEnd())}:{}}}function Gn(t,e,n,r){if(e.json){n.out(JSON.stringify({ok:!0,...t,serverCursor:r}));return}let i=[],s=(o,a)=>{o>0&&i.push(`${String(o).padStart(5)} ${a}`)};if(s(t.uploaded,"uploaded"),s(t.downloaded,"downloaded"),s(t.merged,"merged"),s(t.conflicted,"kept both versions"),s(t.deletedLocally,"deleted here"),s(t.deletedRemotely,"deleted on the server"),s(t.restored,"brought back, having been edited elsewhere"),s(t.foldersCreated,"folders created"),s(t.waiting,"waiting for a write to settle"),s(t.retrying,"failed, will try again"),s(t.skipped,"cannot sync and will not be retried"),s(t.blocked,"waiting on a name that is a file here and a folder elsewhere"),i.length===0)n.out("Nothing to do. Everything here matches the server.");else for(let o of i)n.out(o);t.chunksSent>0&&n.out(`${String(t.chunksSent).padStart(5)} chunks sent, ${_t(t.bytesSent)}`),t.conflicted>0&&n.err('Look for files with "Conflicted copy" in the name. Both versions are kept.')}function Ri(t){let e={rest:[],dir:process.cwd(),device:bi().split(".")[0]||"device",vaultId:"default",json:!1,watch:!1,limit:20,verbose:!1,help:!1,timeout:3e4,configDir:Et,ignore:[]},n=new Set(["--dir","--device","--vault-id","--server","--token","--timeout","--uid","--to","--limit","--config-dir","--ignore"]);for(let r=0;r<t.length;r++){let i=t[r],s;if(n.has(i)&&(s=t[++r],s===void 0||s.startsWith("--")))throw new Error(`${i} needs a value`);switch(i){case"--dir":e.dir=ki(s);break;case"--device":e.device=s;break;case"--vault-id":e.vaultId=s;break;case"--server":e.server=s;break;case"--token":e.token=s;break;case"--timeout":{let o=Number(s);if(!Number.isFinite(o)||o<=0)throw new Error(`--timeout wants a number of milliseconds, not ${s}`);e.timeout=o;break}case"--uid":{let o=Number(s);if(!Number.isInteger(o)||o<=0)throw new Error(`--uid wants a version number, not ${s}`);e.uid=o;break}case"--to":e.to=s;break;case"--config-dir":e.configDir=At(s);break;case"--ignore":e.ignore.push(s);break;case"--limit":{let o=Number(s);if(!Number.isInteger(o)||o<=0)throw new Error(`--limit wants a count, not ${s}`);e.limit=o;break}case"--json":e.json=!0;break;case"--watch":e.watch=!0;break;case"--verbose":case"-v":e.verbose=!0;break;case"--help":case"-h":e.help=!0;break;default:if(i.startsWith("-"))throw new Error(`no such option: ${i}`);e.command===void 0?e.command=i:e.rest.push(i)}}return e}async function pe(t){let e=await Re(t);if(!e)throw new Error(`${t} is not paired. Run basalt init or basalt pair first.`);return e}function Mt(t){if(!Number.isFinite(t)||t<=0)return"unknown ";let e=new Date(t),n=r=>String(r).padStart(2,"0");return`${e.getFullYear()}-${n(e.getMonth()+1)}-${n(e.getDate())} ${n(e.getHours())}:${n(e.getMinutes())}`}function Kn(t){return`${Math.max(1,Math.round(t/1e3))}s`}function _t(t){return t<1024?`${t} B`:t<1024*1024?`${(t/1024).toFixed(1)} KiB`:`${(t/(1024*1024)).toFixed(1)} MiB`}function Ii(t){return typeof t=="string"?t:JSON.stringify(t)}var Di=await Hn(process.argv.slice(2),{out:t=>process.stdout.write(t+`
34
+ `),err:t=>process.stderr.write(t+`
35
+ `)});process.exit(Di);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "basalt-sync",
3
- "version": "0.1.7",
3
+ "version": "0.1.8",
4
4
  "description": "Headless Obsidian vault sync for a Basalt server.",
5
5
  "keywords": [
6
6
  "obsidian",