@dropgate/core 3.0.0 → 3.0.2

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/LICENSE ADDED
@@ -0,0 +1,201 @@
1
+ Apache License
2
+ Version 2.0, January 2004
3
+ http://www.apache.org/licenses/
4
+
5
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6
+
7
+ 1. Definitions.
8
+
9
+ "License" shall mean the terms and conditions for use, reproduction,
10
+ and distribution as defined by Sections 1 through 9 of this document.
11
+
12
+ "Licensor" shall mean the copyright owner or entity authorized by
13
+ the copyright owner that is granting the License.
14
+
15
+ "Legal Entity" shall mean the union of the acting entity and all
16
+ other entities that control, are controlled by, or are under common
17
+ control with that entity. For the purposes of this definition,
18
+ "control" means (i) the power, direct or indirect, to cause the
19
+ direction or management of such entity, whether by contract or
20
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
21
+ outstanding shares, or (iii) beneficial ownership of such entity.
22
+
23
+ "You" (or "Your") shall mean an individual or Legal Entity
24
+ exercising permissions granted by this License.
25
+
26
+ "Source" form shall mean the preferred form for making modifications,
27
+ including but not limited to software source code, documentation
28
+ source, and configuration files.
29
+
30
+ "Object" form shall mean any form resulting from mechanical
31
+ transformation or translation of a Source form, including but
32
+ not limited to compiled object code, generated documentation,
33
+ and conversions to other media types.
34
+
35
+ "Work" shall mean the work of authorship, whether in Source or
36
+ Object form, made available under the License, as indicated by a
37
+ copyright notice that is included in or attached to the work
38
+ (an example is provided in the Appendix below).
39
+
40
+ "Derivative Works" shall mean any work, whether in Source or Object
41
+ form, that is based on (or derived from) the Work and for which the
42
+ editorial revisions, annotations, elaborations, or other modifications
43
+ represent, as a whole, an original work of authorship. For the purposes
44
+ of this License, Derivative Works shall not include works that remain
45
+ separable from, or merely link (or bind by name) to the interfaces of,
46
+ the Work and Derivative Works thereof.
47
+
48
+ "Contribution" shall mean any work of authorship, including
49
+ the original version of the Work and any modifications or additions
50
+ to that Work or Derivative Works thereof, that is intentionally
51
+ submitted to Licensor for inclusion in the Work by the copyright owner
52
+ or by an individual or Legal Entity authorized to submit on behalf of
53
+ the copyright owner. For the purposes of this definition, "submitted"
54
+ means any form of electronic, verbal, or written communication sent
55
+ to the Licensor or its representatives, including but not limited to
56
+ communication on electronic mailing lists, source code control systems,
57
+ and issue tracking systems that are managed by, or on behalf of, the
58
+ Licensor for the purpose of discussing and improving the Work, but
59
+ excluding communication that is conspicuously marked or otherwise
60
+ designated in writing by the copyright owner as "Not a Contribution."
61
+
62
+ "Contributor" shall mean Licensor and any individual or Legal Entity
63
+ on behalf of whom a Contribution has been received by Licensor and
64
+ subsequently incorporated within the Work.
65
+
66
+ 2. Grant of Copyright License. Subject to the terms and conditions of
67
+ this License, each Contributor hereby grants to You a perpetual,
68
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69
+ copyright license to reproduce, prepare Derivative Works of,
70
+ publicly display, publicly perform, sublicense, and distribute the
71
+ Work and such Derivative Works in Source or Object form.
72
+
73
+ 3. Grant of Patent License. Subject to the terms and conditions of
74
+ this License, each Contributor hereby grants to You a perpetual,
75
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76
+ (except as stated in this section) patent license to make, have made,
77
+ use, offer to sell, sell, import, and otherwise transfer the Work,
78
+ where such license applies only to those patent claims licensable
79
+ by such Contributor that are necessarily infringed by their
80
+ Contribution(s) alone or by combination of their Contribution(s)
81
+ with the Work to which such Contribution(s) was submitted. If You
82
+ institute patent litigation against any entity (including a
83
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
84
+ or a Contribution incorporated within the Work constitutes direct
85
+ or contributory patent infringement, then any patent licenses
86
+ granted to You under this License for that Work shall terminate
87
+ as of the date such litigation is filed.
88
+
89
+ 4. Redistribution. You may reproduce and distribute copies of the
90
+ Work or Derivative Works thereof in any medium, with or without
91
+ modifications, and in Source or Object form, provided that You
92
+ meet the following conditions:
93
+
94
+ (a) You must give any other recipients of the Work or
95
+ Derivative Works a copy of this License; and
96
+
97
+ (b) You must cause any modified files to carry prominent notices
98
+ stating that You changed the files; and
99
+
100
+ (c) You must retain, in the Source form of any Derivative Works
101
+ that You distribute, all copyright, patent, trademark, and
102
+ attribution notices from the Source form of the Work,
103
+ excluding those notices that do not pertain to any part of
104
+ the Derivative Works; and
105
+
106
+ (d) If the Work includes a "NOTICE" text file as part of its
107
+ distribution, then any Derivative Works that You distribute must
108
+ include a readable copy of the attribution notices contained
109
+ within such NOTICE file, excluding those notices that do not
110
+ pertain to any part of the Derivative Works, in at least one
111
+ of the following places: within a NOTICE text file distributed
112
+ as part of the Derivative Works; within the Source form or
113
+ documentation, if provided along with the Derivative Works; or,
114
+ within a display generated by the Derivative Works, if and
115
+ wherever such third-party notices normally appear. The contents
116
+ of the NOTICE file are for informational purposes only and
117
+ do not modify the License. You may add Your own attribution
118
+ notices within Derivative Works that You distribute, alongside
119
+ or as an addendum to the NOTICE text from the Work, provided
120
+ that such additional attribution notices cannot be construed
121
+ as modifying the License.
122
+
123
+ You may add Your own copyright statement to Your modifications and
124
+ may provide additional or different license terms and conditions
125
+ for use, reproduction, or distribution of Your modifications, or
126
+ for any such Derivative Works as a whole, provided Your use,
127
+ reproduction, and distribution of the Work otherwise complies with
128
+ the conditions stated in this License.
129
+
130
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
131
+ any Contribution intentionally submitted for inclusion in the Work
132
+ by You to the Licensor shall be under the terms and conditions of
133
+ this License, without any additional terms or conditions.
134
+ Notwithstanding the above, nothing herein shall supersede or modify
135
+ the terms of any separate license agreement you may have executed
136
+ with Licensor regarding such Contributions.
137
+
138
+ 6. Trademarks. This License does not grant permission to use the trade
139
+ names, trademarks, service marks, or product names of the Licensor,
140
+ except as required for reasonable and customary use in describing the
141
+ origin of the Work and reproducing the content of the NOTICE file.
142
+
143
+ 7. Disclaimer of Warranty. Unless required by applicable law or
144
+ agreed to in writing, Licensor provides the Work (and each
145
+ Contributor provides its Contributions) on an "AS IS" BASIS,
146
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147
+ implied, including, without limitation, any warranties or conditions
148
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149
+ PARTICULAR PURPOSE. You are solely responsible for determining the
150
+ appropriateness of using or redistributing the Work and assume any
151
+ risks associated with Your exercise of permissions under this License.
152
+
153
+ 8. Limitation of Liability. In no event and under no legal theory,
154
+ whether in tort (including negligence), contract, or otherwise,
155
+ unless required by applicable law (such as deliberate and grossly
156
+ negligent acts) or agreed to in writing, shall any Contributor be
157
+ liable to You for damages, including any direct, indirect, special,
158
+ incidental, or consequential damages of any character arising as a
159
+ result of this License or out of the use or inability to use the
160
+ Work (including but not limited to damages for loss of goodwill,
161
+ work stoppage, computer failure or malfunction, or any and all
162
+ other commercial damages or losses), even if such Contributor
163
+ has been advised of the possibility of such damages.
164
+
165
+ 9. Accepting Warranty or Additional Liability. While redistributing
166
+ the Work or Derivative Works thereof, You may choose to offer,
167
+ and charge a fee for, acceptance of support, warranty, indemnity,
168
+ or other liability obligations and/or rights consistent with this
169
+ License. However, in accepting such obligations, You may act only
170
+ on Your own behalf and on Your sole responsibility, not on behalf
171
+ of any other Contributor, and only if You agree to indemnify,
172
+ defend, and hold each Contributor harmless for any liability
173
+ incurred by, or claims asserted against, such Contributor by reason
174
+ of your accepting any such warranty or additional liability.
175
+
176
+ END OF TERMS AND CONDITIONS
177
+
178
+ APPENDIX: How to apply the Apache License to your work.
179
+
180
+ To apply the Apache License to your work, attach the following
181
+ boilerplate notice, with the fields enclosed by brackets "[]"
182
+ replaced with your own identifying information. (Don't include
183
+ the brackets!) The text should be enclosed in the appropriate
184
+ comment syntax for the file format. We also recommend that a
185
+ file or class name and description of purpose be included on the
186
+ same "printed page" as the copyright notice for easier
187
+ identification within third-party archives.
188
+
189
+ Copyright [yyyy] [name of copyright owner]
190
+
191
+ Licensed under the Apache License, Version 2.0 (the "License");
192
+ you may not use this file except in compliance with the License.
193
+ You may obtain a copy of the License at
194
+
195
+ http://www.apache.org/licenses/LICENSE-2.0
196
+
197
+ Unless required by applicable law or agreed to in writing, software
198
+ distributed under the License is distributed on an "AS IS" BASIS,
199
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200
+ See the License for the specific language governing permissions and
201
+ limitations under the License.
package/README.md CHANGED
@@ -9,7 +9,7 @@
9
9
  <div align="center">
10
10
 
11
11
  ![license](https://img.shields.io/badge/license-Apache--2.0-blue?style=flat-square)
12
- ![version](https://img.shields.io/badge/version-3.0.0-brightgreen?style=flat-square)
12
+ ![version](https://img.shields.io/badge/version-3.0.2-brightgreen?style=flat-square)
13
13
  ![typescript](https://img.shields.io/badge/TypeScript-5.0+-blue?style=flat-square)
14
14
 
15
15
  [![discord](https://img.shields.io/discord/667479986214666272?logo=discord&logoColor=white&style=flat-square)](https://diamonddigital.dev/discord)
@@ -55,7 +55,7 @@ All operations go through a single `DropgateClient` instance. Server connection
55
55
  import { DropgateClient } from '@dropgate/core';
56
56
 
57
57
  const client = new DropgateClient({
58
- clientVersion: '3.0.0',
58
+ clientVersion: '3.0.2',
59
59
  server: 'https://dropgate.link', // URL string or { host, port?, secure? }
60
60
  fallbackToHttp: true, // auto-retry HTTP if HTTPS fails (optional)
61
61
  });
@@ -422,7 +422,7 @@ For browser environments, you can use the IIFE bundle:
422
422
  <script src="/path/to/dropgate-core.browser.js"></script>
423
423
  <script>
424
424
  const { DropgateClient } = DropgateCore;
425
- const client = new DropgateClient({ clientVersion: '3.0.0', server: location.origin });
425
+ const client = new DropgateClient({ clientVersion: '3.0.2', server: location.origin });
426
426
  // ...
427
427
  </script>
428
428
  ```
@@ -432,7 +432,7 @@ Or as an ES module:
432
432
  ```html
433
433
  <script type="module">
434
434
  import { DropgateClient } from '/path/to/dropgate-core.js';
435
- const client = new DropgateClient({ clientVersion: '3.0.0', server: location.origin });
435
+ const client = new DropgateClient({ clientVersion: '3.0.2', server: location.origin });
436
436
  // ...
437
437
  </script>
438
438
  ```
@@ -1,3 +1,3 @@
1
- "use strict";var DropgateCore=(()=>{var Xe=Object.defineProperty;var Zt=Object.getOwnPropertyDescriptor;var Yt=Object.getOwnPropertyNames;var Xt=Object.prototype.hasOwnProperty;var Qt=(r,e,t)=>e in r?Xe(r,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):r[e]=t;var er=(r=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(r,{get:(e,t)=>(typeof require<"u"?require:e)[t]}):r)(function(r){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+r+'" is not supported')});var tr=(r,e)=>{for(var t in e)Xe(r,t,{get:e[t],enumerable:!0})},rr=(r,e,t,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of Yt(e))!Xt.call(r,i)&&i!==t&&Xe(r,i,{get:()=>e[i],enumerable:!(n=Zt(e,i))||n.enumerable});return r};var nr=r=>rr(Xe({},"__esModule",{value:!0}),r);var Q=(r,e,t)=>Qt(r,typeof e!="symbol"?e+"":e,t);var kr={};tr(kr,{AES_GCM_IV_BYTES:()=>je,AES_GCM_TAG_BYTES:()=>xt,DEFAULT_CHUNK_SIZE:()=>dt,DropgateAbortError:()=>te,DropgateClient:()=>pt,DropgateError:()=>X,DropgateNetworkError:()=>N,DropgateProtocolError:()=>H,DropgateTimeoutError:()=>Te,DropgateValidationError:()=>S,ENCRYPTION_OVERHEAD_PER_CHUNK:()=>Qe,StreamingZipWriter:()=>Ne,arrayBufferToBase64:()=>Ue,base64ToBytes:()=>Ct,buildBaseUrl:()=>Ke,bytesToBase64:()=>gt,decryptChunk:()=>xe,decryptFilenameFromBase64:()=>De,encryptFilenameToBase64:()=>st,encryptToBlob:()=>_e,estimateTotalUploadSizeBytes:()=>qe,exportKeyBase64:()=>it,fetchJson:()=>oe,generateAesGcmKey:()=>nt,generateP2PCode:()=>He,getDefaultBase64:()=>be,getDefaultCrypto:()=>Re,getDefaultFetch:()=>$e,getServerInfo:()=>ut,importKeyFromBase64:()=>Ee,isLocalhostHostname:()=>lt,isP2PCodeLike:()=>Ge,isSecureContextForP2P:()=>vt,lifetimeToMs:()=>At,makeAbortSignal:()=>Oe,parseSemverMajorMinor:()=>Le,parseServerUrl:()=>tt,sha256Hex:()=>rt,sleep:()=>me,validatePlainFilename:()=>et});var dt=5242880,je=12,xt=16,Qe=28;var X=class extends Error{constructor(t,n={}){super(t,n.cause!==void 0?{cause:n.cause}:void 0);Q(this,"code");Q(this,"details");this.name=this.constructor.name,this.code=n.code||"DROPGATE_ERROR",this.details=n.details}},S=class extends X{constructor(e,t={}){super(e,{...t,code:t.code||"VALIDATION_ERROR"})}},N=class extends X{constructor(e,t={}){super(e,{...t,code:t.code||"NETWORK_ERROR"})}},H=class extends X{constructor(e,t={}){super(e,{...t,code:t.code||"PROTOCOL_ERROR"})}},te=class extends X{constructor(e="Operation aborted"){super(e,{code:"ABORT_ERROR"}),this.name="AbortError"}},Te=class extends X{constructor(e="Request timed out"){super(e,{code:"TIMEOUT_ERROR"}),this.name="TimeoutError"}};function be(){if(typeof Buffer<"u"&&typeof Buffer.from=="function")return{encode(r){return Buffer.from(r).toString("base64")},decode(r){return new Uint8Array(Buffer.from(r,"base64"))}};if(typeof btoa=="function"&&typeof atob=="function")return{encode(r){let e="";for(let t=0;t<r.length;t++)e+=String.fromCharCode(r[t]);return btoa(e)},decode(r){let e=atob(r),t=new Uint8Array(e.length);for(let n=0;n<e.length;n++)t[n]=e.charCodeAt(n);return t}};throw new Error("No Base64 implementation available. Provide a Base64Adapter via options.")}function Re(){return globalThis.crypto}function $e(){return globalThis.fetch?.bind(globalThis)}var mt=null;function St(r){return r||(mt||(mt=be()),mt)}function gt(r,e){return St(e).encode(r)}function Ue(r,e){return gt(new Uint8Array(r),e)}function Ct(r,e){return St(e).decode(r)}var ir={minutes:6e4,hours:36e5,days:864e5};function At(r,e){let t=String(e||"").toLowerCase(),n=Number(r);if(t==="unlimited"||!Number.isFinite(n)||n<=0)return 0;let i=ir[t];return i?Math.round(n*i):0}function Le(r){let e=String(r||"").split(".").map(i=>Number(i)),t=Number.isFinite(e[0])?e[0]:0,n=Number.isFinite(e[1])?e[1]:0;return{major:t,minor:n}}function et(r){if(typeof r!="string"||r.trim().length===0)throw new S("Invalid filename. Must be a non-empty string.");if(r.length>255||/[\/\\]/.test(r))throw new S("Invalid filename. Contains illegal characters or is too long.")}function tt(r){let e=r.trim();!e.startsWith("http://")&&!e.startsWith("https://")&&(e="https://"+e);let t=new URL(e);return{host:t.hostname,port:t.port?Number(t.port):void 0,secure:t.protocol==="https:"}}function Ke(r){let{host:e,port:t,secure:n}=r;if(!e||typeof e!="string")throw new S("Server host is required.");let i=n===!1?"http":"https",s=t?`:${t}`:"";return`${i}://${e}${s}`}function me(r,e){return new Promise((t,n)=>{if(e?.aborted)return n(e.reason||new te);let i=setTimeout(t,r);e&&e.addEventListener("abort",()=>{clearTimeout(i),n(e.reason||new te)},{once:!0})})}function Oe(r,e){let t=new AbortController,n=null,i=s=>{t.signal.aborted||t.abort(s)};return r&&(r.aborted?i(r.reason):r.addEventListener("abort",()=>i(r.reason),{once:!0})),Number.isFinite(e)&&e>0&&(n=setTimeout(()=>{i(new Te)},e)),{signal:t.signal,cleanup:()=>{n&&clearTimeout(n)}}}async function oe(r,e,t={}){let{timeoutMs:n,signal:i,...s}=t,{signal:a,cleanup:l}=Oe(i,n);try{let o=await r(e,{...s,signal:a}),c=await o.text(),h=null;try{h=c?JSON.parse(c):null}catch{}return{res:o,json:h,text:c}}finally{l()}}var sr=new Uint32Array([1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298]);function ye(r,e){return r>>>e|r<<32-e}function Mt(r){let e=new Uint8Array(r),t=e.length*8,n=new Uint8Array(Math.ceil((e.length+9)/64)*64);n.set(e),n[e.length]=128;let i=new DataView(n.buffer);i.setUint32(n.length-8,t/4294967296>>>0,!1),i.setUint32(n.length-4,t>>>0,!1);let s=1779033703,a=3144134277,l=1013904242,o=2773480762,c=1359893119,h=2600822924,k=528734635,p=1541459225,d=new Uint32Array(64);for(let P=0;P<n.length;P+=64){for(let F=0;F<16;F++)d[F]=i.getUint32(P+F*4,!1);for(let F=16;F<64;F++){let B=ye(d[F-15],7)^ye(d[F-15],18)^d[F-15]>>>3,g=ye(d[F-2],17)^ye(d[F-2],19)^d[F-2]>>>10;d[F]=d[F-16]+B+d[F-7]+g|0}let u=s,E=a,m=l,f=o,C=c,w=h,M=k,z=p;for(let F=0;F<64;F++){let B=ye(C,6)^ye(C,11)^ye(C,25),g=C&w^~C&M,R=z+B+g+sr[F]+d[F]|0,D=ye(u,2)^ye(u,13)^ye(u,22),Z=u&E^u&m^E&m,ie=D+Z|0;z=M,M=w,w=C,C=f+R|0,f=m,m=E,E=u,u=R+ie|0}s=s+u|0,a=a+E|0,l=l+m|0,o=o+f|0,c=c+C|0,h=h+w|0,k=k+M|0,p=p+z|0}let y=new ArrayBuffer(32),v=new DataView(y);return v.setUint32(0,s,!1),v.setUint32(4,a,!1),v.setUint32(8,l,!1),v.setUint32(12,o,!1),v.setUint32(16,c,!1),v.setUint32(20,h,!1),v.setUint32(24,k,!1),v.setUint32(28,p,!1),y}async function Ee(r,e,t){let i=(t||be()).decode(e),s=new Uint8Array(i).buffer;return r.subtle.importKey("raw",s,{name:"AES-GCM"},!0,["decrypt"])}async function xe(r,e,t){let n=e.slice(0,12),i=e.slice(12);return r.subtle.decrypt({name:"AES-GCM",iv:n},t,i)}async function De(r,e,t,n){let s=(n||be()).decode(e),a=await xe(r,s,t);return new TextDecoder().decode(a)}function Bt(r){let e=new Uint8Array(r),t="";for(let n=0;n<e.length;n++)t+=e[n].toString(16).padStart(2,"0");return t}async function rt(r,e){if(r?.subtle){let t=await r.subtle.digest("SHA-256",e);return Bt(t)}return Bt(Mt(e))}async function nt(r){return r.subtle.generateKey({name:"AES-GCM",length:256},!0,["encrypt","decrypt"])}async function it(r,e){let t=await r.subtle.exportKey("raw",e);return Ue(t)}async function _e(r,e,t){let n=r.getRandomValues(new Uint8Array(12)),i=await r.subtle.encrypt({name:"AES-GCM",iv:n},t,e);return new Blob([n,new Uint8Array(i)])}async function st(r,e,t){let n=new TextEncoder().encode(String(e)),s=await(await _e(r,n.buffer,t)).arrayBuffer();return Ue(s)}var It=er("module"),or=(0,It.createRequire)("/"),ar;try{ar=or("worker_threads").Worker}catch{}var le=Uint8Array,zt=Uint16Array,lr=Int32Array,cr=new le([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]),fr=new le([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]),Yr=new le([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]),Tt=function(r,e){for(var t=new zt(31),n=0;n<31;++n)t[n]=e+=1<<r[n-1];for(var i=new lr(t[30]),n=1;n<30;++n)for(var s=t[n];s<t[n+1];++s)i[s]=s-t[n]<<5|n;return{b:t,r:i}},Rt=Tt(cr,2),ur=Rt.b,pr=Rt.r;ur[28]=258,pr[258]=28;var Ut=Tt(fr,0),Xr=Ut.b,Qr=Ut.r,hr=new zt(32768);for(O=0;O<32768;++O)Se=(O&43690)>>1|(O&21845)<<1,Se=(Se&52428)>>2|(Se&13107)<<2,Se=(Se&61680)>>4|(Se&3855)<<4,hr[O]=((Se&65280)>>8|(Se&255)<<8)>>1;var Se,O;var at=new le(288);for(O=0;O<144;++O)at[O]=8;var O;for(O=144;O<256;++O)at[O]=9;var O;for(O=256;O<280;++O)at[O]=7;var O;for(O=280;O<288;++O)at[O]=8;var O,dr=new le(32);for(O=0;O<32;++O)dr[O]=5;var O;var mr=function(r,e,t){return(e==null||e<0)&&(e=0),(t==null||t>r.length)&&(t=r.length),new le(r.subarray(e,t))};var gr=["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"],Me=function(r,e,t){var n=new Error(e||gr[r]);if(n.code=r,Error.captureStackTrace&&Error.captureStackTrace(n,Me),!t)throw n;return n};var vr=new le(0);var yr=(function(){for(var r=new Int32Array(256),e=0;e<256;++e){for(var t=e,n=9;--n;)t=(t&1&&-306674912)^t>>>1;r[e]=t}return r})(),Pr=function(){var r=-1;return{p:function(e){for(var t=r,n=0;n<e.length;++n)t=yr[t&255^e[n]]^t>>>8;r=t},d:function(){return~r}}};var wr=function(r,e){var t={};for(var n in r)t[n]=r[n];for(var n in e)t[n]=e[n];return t};var J=function(r,e,t){for(;t;++e)r[e]=t,t>>>=8};var kt=typeof TextEncoder<"u"&&new TextEncoder,br=typeof TextDecoder<"u"&&new TextDecoder,xr=0;try{br.decode(vr,{stream:!0}),xr=1}catch{}function Et(r,e){if(e){for(var t=new le(r.length),n=0;n<r.length;++n)t[n]=r.charCodeAt(n);return t}if(kt)return kt.encode(r);for(var i=r.length,s=new le(r.length+(r.length>>1)),a=0,l=function(h){s[a++]=h},n=0;n<i;++n){if(a+5>s.length){var o=new le(a+8+(i-n<<1));o.set(s),s=o}var c=r.charCodeAt(n);c<128||e?l(c):c<2048?(l(192|c>>6),l(128|c&63)):c>55295&&c<57344?(c=65536+(c&1047552)|r.charCodeAt(++n)&1023,l(240|c>>18),l(128|c>>12&63),l(128|c>>6&63),l(128|c&63)):(l(224|c>>12),l(128|c>>6&63),l(128|c&63))}return mr(s,0,a)}var ot=function(r){var e=0;if(r)for(var t in r){var n=r[t].length;n>65535&&Me(9),e+=n+4}return e},Ft=function(r,e,t,n,i,s,a,l){var o=n.length,c=t.extra,h=l&&l.length,k=ot(c);J(r,e,a!=null?33639248:67324752),e+=4,a!=null&&(r[e++]=20,r[e++]=t.os),r[e]=20,e+=2,r[e++]=t.flag<<1|(s<0&&8),r[e++]=i&&8,r[e++]=t.compression&255,r[e++]=t.compression>>8;var p=new Date(t.mtime==null?Date.now():t.mtime),d=p.getFullYear()-1980;if((d<0||d>119)&&Me(10),J(r,e,d<<25|p.getMonth()+1<<21|p.getDate()<<16|p.getHours()<<11|p.getMinutes()<<5|p.getSeconds()>>1),e+=4,s!=-1&&(J(r,e,t.crc),J(r,e+4,s<0?-s-2:s),J(r,e+8,t.size)),J(r,e+12,o),J(r,e+14,k),e+=16,a!=null&&(J(r,e,h),J(r,e+6,t.attrs),J(r,e+10,a),e+=14),r.set(n,e),e+=o,k)for(var y in c){var v=c[y],P=v.length;J(r,e,+y),J(r,e+2,P),r.set(v,e+4),e+=4+P}return h&&(r.set(l,e),e+=h),e},Sr=function(r,e,t,n,i){J(r,e,101010256),J(r,e+8,t),J(r,e+10,t),J(r,e+12,n),J(r,e+16,i)},Ot=(function(){function r(e){this.filename=e,this.c=Pr(),this.size=0,this.compression=0}return r.prototype.process=function(e,t){this.ondata(null,e,t)},r.prototype.push=function(e,t){this.ondata||Me(5),this.c.p(e),this.size+=e.length,t&&(this.crc=this.c.d()),this.process(e,t||!1)},r})();var Dt=(function(){function r(e){this.ondata=e,this.u=[],this.d=1}return r.prototype.add=function(e){var t=this;if(this.ondata||Me(5),this.d&2)this.ondata(Me(4+(this.d&1)*8,0,1),null,!1);else{var n=Et(e.filename),i=n.length,s=e.comment,a=s&&Et(s),l=i!=e.filename.length||a&&s.length!=a.length,o=i+ot(e.extra)+30;i>65535&&this.ondata(Me(11,0,1),null,!1);var c=new le(o);Ft(c,0,e,n,l,-1);var h=[c],k=function(){for(var P=0,u=h;P<u.length;P++){var E=u[P];t.ondata(null,E,!1)}h=[]},p=this.d;this.d=0;var d=this.u.length,y=wr(e,{f:n,u:l,o:a,t:function(){e.terminate&&e.terminate()},r:function(){if(k(),p){var P=t.u[d+1];P?P.r():t.d=1}p=1}}),v=0;e.ondata=function(P,u,E){if(P)t.ondata(P,u,E),t.terminate();else if(v+=u.length,h.push(u),E){var m=new le(16);J(m,0,134695760),J(m,4,e.crc),J(m,8,v),J(m,12,e.size),h.push(m),y.c=v,y.b=o+v+16,y.crc=e.crc,y.size=e.size,p&&y.r(),p=1}else p&&k()},this.u.push(y)}},r.prototype.end=function(){var e=this;if(this.d&2){this.ondata(Me(4+(this.d&1)*8,0,1),null,!0);return}this.d?this.e():this.u.push({r:function(){e.d&1&&(e.u.splice(-1,1),e.e())},t:function(){}}),this.d=3},r.prototype.e=function(){for(var e=0,t=0,n=0,i=0,s=this.u;i<s.length;i++){var a=s[i];n+=46+a.f.length+ot(a.extra)+(a.o?a.o.length:0)}for(var l=new le(n+22),o=0,c=this.u;o<c.length;o++){var a=c[o];Ft(l,e,a,a.f,a.u,-a.c-2,t,a.o),e+=46+a.f.length+ot(a.extra)+(a.o?a.o.length:0),t+=a.b}Sr(l,e,this.u.length,n,t),this.ondata(null,l,!0),this.d=2},r.prototype.terminate=function(){for(var e=0,t=this.u;e<t.length;e++){var n=t[e];n.t()}this.d=2},r})();var Ne=class{constructor(e){Q(this,"zip");Q(this,"currentFile",null);Q(this,"onData");Q(this,"finalized",!1);Q(this,"pendingWrites",Promise.resolve());this.onData=e,this.zip=new Dt((t,n,i)=>{if(t)throw t;this.pendingWrites=this.pendingWrites.then(()=>this.onData(n))})}startFile(e){if(this.currentFile)throw new Error("Must call endFile() before starting a new file.");if(this.finalized)throw new Error("ZIP has already been finalized.");let t=new Ot(e);this.zip.add(t),this.currentFile=t}writeChunk(e){if(!this.currentFile)throw new Error("No file started. Call startFile() first.");this.currentFile.push(e,!1)}endFile(){if(!this.currentFile)throw new Error("No file to end.");this.currentFile.push(new Uint8Array(0),!0),this.currentFile=null}async finalize(){if(this.currentFile)throw new Error("Cannot finalize with an open file. Call endFile() first.");this.finalized||(this.finalized=!0,this.zip.end(),await this.pendingWrites)}};function lt(r){let e=String(r||"").toLowerCase();return e==="localhost"||e==="127.0.0.1"||e==="::1"}function vt(r,e){return!!e||lt(r||"")}function He(r){let e=r||Re(),t="ABCDEFGHJKLMNPQRSTUVWXYZ";if(e){let s=new Uint8Array(8);e.getRandomValues(s);let a="";for(let o=0;o<4;o++)a+=t[s[o]%t.length];let l="";for(let o=4;o<8;o++)l+=(s[o]%10).toString();return`${a}-${l}`}let n="";for(let s=0;s<4;s++)n+=t[Math.floor(Math.random()*t.length)];let i="";for(let s=0;s<4;s++)i+=Math.floor(Math.random()*10);return`${n}-${i}`}function Ge(r){return/^[A-Z]{4}-\d{4}$/.test(String(r||"").trim())}function Fe(r,e){return{path:r.peerjsPath??e?.peerjsPath??"/peerjs",iceServers:r.iceServers??e?.iceServers??[]}}function ct(r={}){let{host:e,port:t,peerjsPath:n="/peerjs",secure:i=!1,iceServers:s=[]}=r,a={host:e,path:n,secure:i,config:{iceServers:s},debug:0};return t&&(a.port=t),a}async function _t(r){let{code:e,codeGenerator:t,maxAttempts:n,buildPeer:i,onCode:s}=r,a=e||t(),l=null,o=null;for(let c=0;c<n;c++){s?.(a,c);try{return l=await new Promise((h,k)=>{let p=i(a);p.on("open",()=>h(p)),p.on("error",d=>{try{p.destroy()}catch{}k(d)})}),{peer:l,code:a}}catch(h){o=h,a=t()}}throw o||new N("Could not establish PeerJS connection.")}function ft(r){if(!r||typeof r!="object")return!1;let e=r;return typeof e.t=="string"&&["hello","file_list","meta","ready","chunk","chunk_ack","file_end","file_end_ack","end","end_ack","ping","pong","error","cancelled","resume","resume_ack"].includes(e.t)}var Nt=64*1024,jt=32,$t=15e3,Lt=3,Kt=100,Ht=2e3;function Cr(){return crypto.randomUUID()}var Ar={initializing:["listening","closed"],listening:["handshaking","closed","cancelled"],handshaking:["negotiating","closed","cancelled"],negotiating:["transferring","closed","cancelled"],transferring:["finishing","closed","cancelled"],finishing:["awaiting_ack","closed","cancelled"],awaiting_ack:["completed","closed","cancelled"],completed:["closed"],cancelled:["closed"],closed:[]};async function Gt(r){let{file:e,Peer:t,serverInfo:n,host:i,port:s,peerjsPath:a,secure:l=!1,iceServers:o,codeGenerator:c,cryptoObj:h,maxAttempts:k=4,chunkSize:p=Nt,endAckTimeoutMs:d=$t,bufferHighWaterMark:y=8*1024*1024,bufferLowWaterMark:v=2*1024*1024,heartbeatIntervalMs:P=5e3,chunkAcknowledgments:u=!0,maxUnackedChunks:E=jt,onCode:m,onStatus:f,onProgress:C,onComplete:w,onError:M,onDisconnect:z,onCancel:F,onConnectionHealth:B}=r,g=Array.isArray(e)?e:[e],R=g.length>1,D=g.reduce((x,K)=>x+K.size,0);if(!g.length)throw new S("At least one file is required.");if(!t)throw new S("PeerJS Peer constructor is required. Install peerjs and pass it as the Peer option.");let Z=n?.capabilities?.p2p;if(n&&!Z?.enabled)throw new S("Direct transfer is disabled on this server.");let{path:ie,iceServers:pe}=Fe({peerjsPath:a,iceServers:o},Z),ge=ct({host:i,port:s,peerjsPath:ie,secure:l,iceServers:pe}),Ce=c||(()=>He(h)),G=x=>new t(x,ge),{peer:V,code:Pe}=await _t({code:null,codeGenerator:Ce,maxAttempts:k,buildPeer:G,onCode:m}),ee=Cr(),I="listening",q=null,ne=0,se=null,ce=null,re=Date.now(),fe=new Map,b=0,Y=[],A=x=>Ar[I].includes(x)?(I=x,!0):(console.warn(`[P2P Send] Invalid state transition: ${I} -> ${x}`),!1),U=x=>{if(j())return;let K=Number.isFinite(x.total)&&x.total>0?x.total:D,ue=Math.min(Number(x.received)||0,K||0),he=K?ue/K*100:0;C?.({processedBytes:ue,totalBytes:K,percent:he})},T=x=>{I==="closed"||I==="completed"||I==="cancelled"||(A("closed"),M?.(x),L())},$=()=>{I!=="awaiting_ack"&&I!=="finishing"||(A("completed"),w?.(),L())},L=()=>{se&&(clearInterval(se),se=null),ce&&(clearInterval(ce),ce=null),Y.forEach(x=>x()),Y=[],fe.clear(),typeof window<"u"&&window.removeEventListener("beforeunload",_);try{q?.close()}catch{}try{V.destroy()}catch{}},_=()=>{try{q?.send({t:"error",message:"Sender closed the connection."})}catch{}ae()};typeof window<"u"&&window.addEventListener("beforeunload",_);let ae=()=>{if(I==="closed"||I==="cancelled")return;if(I==="completed"){L();return}let x=I==="transferring"||I==="finishing"||I==="awaiting_ack";A("cancelled");try{q&&q.open&&q.send({t:"cancelled",message:"Sender cancelled the transfer."})}catch{}x&&F&&F({cancelledBy:"sender"}),L()},j=()=>I==="closed"||I==="cancelled",Ie=x=>{B&&(ce=setInterval(()=>{if(j())return;let K=x._dc;if(!K)return;let ue={iceConnectionState:K.readyState==="open"?"connected":"disconnected",bufferedAmount:K.bufferedAmount,lastActivityMs:Date.now()-re};B(ue)},2e3))},Ae=x=>{re=Date.now(),fe.delete(x.seq),U({received:x.received,total:D});let K=Y.shift();K&&K()},We=()=>new Promise(x=>{Y.push(x)}),Wt=async(x,K,ue,he)=>{if(u){for(;fe.size>=E;)if(await Promise.race([We(),me(1e3)]),j())return}let Be=b++;u&&fe.set(Be,{offset:ue,size:K.byteLength,sentAt:Date.now()}),x.send({t:"chunk",seq:Be,offset:ue,size:K.byteLength,total:he??D}),x.send(K),ne+=K.byteLength;let we=x._dc;if(we&&y>0){for(;we.bufferedAmount>y;)if(await new Promise(Je=>{let ht=setTimeout(Je,60);try{we.addEventListener("bufferedamountlow",()=>{clearTimeout(ht),Je()},{once:!0})}catch{}}),j())return}},Jt=async(x,K)=>{let ue=d;for(let he=0;he<Lt;he++){x.send({t:"end",attempt:he});let Be=ue*Math.pow(1.5,he),we=await Promise.race([K,me(Be).then(()=>null)]);if(we&&we.t==="end_ack")return we;if(j())throw new N("Connection closed during completion.")}throw new N("Receiver did not confirm completion after retries.")};return V.on("connection",x=>{if(j())return;if(q){let W=q.open!==!1;if(W&&I==="transferring"){try{x.send({t:"error",message:"Transfer already in progress."})}catch{}try{x.close()}catch{}return}else if(W){try{x.send({t:"error",message:"Another receiver is already connected."})}catch{}try{x.close()}catch{}return}else{try{q.close()}catch{}q=null,I="listening",ne=0,b=0,fe.clear()}}q=x,A("handshaking"),j()||f?.({phase:"connected",message:"Receiver connected."}),re=Date.now();let K=null,ue=null,he=null,Be=null,we=new Promise(W=>{K=W}),Je=new Promise(W=>{ue=W}),ht=new Promise(W=>{he=W});x.on("data",W=>{if(re=Date.now(),W instanceof ArrayBuffer||ArrayBuffer.isView(W)||!ft(W))return;let ve=W;switch(ve.t){case"hello":K?.(ve.protocolVersion);break;case"ready":j()||f?.({phase:"transferring",message:"Receiver accepted. Starting transfer..."}),ue?.();break;case"chunk_ack":Ae(ve);break;case"file_end_ack":Be?.(ve);break;case"end_ack":he?.(ve);break;case"pong":break;case"error":T(new N(ve.message||"Receiver reported an error."));break;case"cancelled":if(I==="cancelled"||I==="closed"||I==="completed")return;A("cancelled"),F?.({cancelledBy:"receiver",message:ve.reason}),L();break}}),x.on("open",async()=>{try{if(j())return;Ie(x),x.send({t:"hello",protocolVersion:3,sessionId:ee});let W=await Promise.race([we,me(1e4).then(()=>null)]);if(j())return;if(W===null)throw new N("Receiver did not respond to handshake.");if(W!==3)throw new N(`Protocol version mismatch: sender v${3}, receiver v${W}`);A("negotiating"),j()||f?.({phase:"waiting",message:"Connected. Waiting for receiver to accept..."}),R&&x.send({t:"file_list",fileCount:g.length,files:g.map(de=>({name:de.name,size:de.size,mime:de.type||"application/octet-stream"})),totalSize:D}),x.send({t:"meta",sessionId:ee,name:g[0].name,size:g[0].size,mime:g[0].type||"application/octet-stream",...R?{fileIndex:0}:{}});let ve=x._dc;if(ve&&Number.isFinite(v))try{ve.bufferedAmountLowThreshold=v}catch{}if(await Je,j())return;P>0&&(se=setInterval(()=>{if(I==="transferring"||I==="finishing"||I==="awaiting_ack")try{x.send({t:"ping",timestamp:Date.now()})}catch{}},P)),A("transferring");let yt=0;for(let de=0;de<g.length;de++){let ze=g[de];R&&de>0&&x.send({t:"meta",sessionId:ee,name:ze.name,size:ze.size,mime:ze.type||"application/octet-stream",fileIndex:de});for(let ke=0;ke<ze.size;ke+=p){if(j())return;let Ye=await ze.slice(ke,ke+p).arrayBuffer();if(j())return;await Wt(x,Ye,ke,ze.size),yt+=Ye.byteLength,U({received:yt,total:D})}if(j())return;if(R){let ke=new Promise(Ye=>{Be=Ye});x.send({t:"file_end",fileIndex:de});let bt=await Promise.race([ke,me(d).then(()=>null)]);if(j())return;if(!bt)throw new N(`Receiver did not confirm receipt of file ${de+1}/${g.length}.`)}}if(j())return;A("finishing"),A("awaiting_ack");let Pt=await Jt(x,ht);if(j())return;let Ze=Number(Pt.total)||D,wt=Number(Pt.received)||0;if(Ze&&wt<Ze)throw new N("Receiver reported an incomplete transfer.");U({received:wt||Ze,total:Ze}),$()}catch(W){T(W)}}),x.on("error",W=>{T(W)}),x.on("close",()=>{if(I==="closed"||I==="completed"||I==="cancelled"){L();return}if(I==="awaiting_ack"){setTimeout(()=>{I==="awaiting_ack"&&T(new N("Connection closed while awaiting confirmation."))},Ht);return}I==="transferring"||I==="finishing"?(A("cancelled"),F?.({cancelledBy:"receiver"}),L()):(q=null,I="listening",ne=0,b=0,fe.clear(),z?.())})}),{peer:V,code:Pe,sessionId:ee,stop:ae,getStatus:()=>I,getBytesSent:()=>ne,getConnectedPeerId:()=>q&&q.peer||null}}var Mr={initializing:["connecting","closed"],connecting:["handshaking","closed","cancelled"],handshaking:["negotiating","closed","cancelled"],negotiating:["transferring","closed","cancelled"],transferring:["completed","closed","cancelled"],completed:["closed"],cancelled:["closed"],closed:[]};async function Vt(r){let{code:e,Peer:t,serverInfo:n,host:i,port:s,peerjsPath:a,secure:l=!1,iceServers:o,autoReady:c=!0,watchdogTimeoutMs:h=15e3,onStatus:k,onMeta:p,onData:d,onProgress:y,onFileStart:v,onFileEnd:P,onComplete:u,onError:E,onDisconnect:m,onCancel:f}=r;if(!e)throw new S("No sharing code was provided.");if(!t)throw new S("PeerJS Peer constructor is required. Install peerjs and pass it as the Peer option.");let C=n?.capabilities?.p2p;if(n&&!C?.enabled)throw new S("Direct transfer is disabled on this server.");let w=String(e).trim().replace(/\s+/g,"").toUpperCase();if(!Ge(w))throw new S("Invalid direct transfer code.");let{path:M,iceServers:z}=Fe({peerjsPath:a,iceServers:o},C),F=ct({host:i,port:s,peerjsPath:M,secure:l,iceServers:z}),B=new t(void 0,F),g="initializing",R=0,D=0,Z=null,ie=Promise.resolve(),pe=null,ge=null,Ce=null,G=null,V=0,Pe=0,ee=A=>Mr[g].includes(A)?(g=A,!0):(console.warn(`[P2P Receive] Invalid state transition: ${g} -> ${A}`),!1),I=()=>g==="closed"||g==="cancelled",q=()=>{h<=0||(pe&&clearTimeout(pe),pe=setTimeout(()=>{g==="transferring"&&se(new N("Connection timed out (no data received)."))},h))},ne=()=>{pe&&(clearTimeout(pe),pe=null)},se=A=>{g==="closed"||g==="completed"||g==="cancelled"||(ee("closed"),E?.(A),re())},ce=A=>{g==="transferring"&&(ee("completed"),u?.(A))},re=()=>{ne(),typeof window<"u"&&window.removeEventListener("beforeunload",fe);try{B.destroy()}catch{}},fe=()=>{try{ge?.send({t:"error",message:"Receiver closed the connection."})}catch{}b()};typeof window<"u"&&window.addEventListener("beforeunload",fe);let b=()=>{if(g==="closed"||g==="cancelled")return;if(g==="completed"){re();return}let A=g==="transferring";ee("cancelled");try{ge&&ge.open&&ge.send({t:"cancelled",reason:"Receiver cancelled the transfer."})}catch{}A&&f&&f({cancelledBy:"receiver"}),re()},Y=(A,U)=>{try{A.send({t:"chunk_ack",seq:U,received:D})}catch{}};return B.on("error",A=>{se(A)}),B.on("open",()=>{ee("connecting");let A=B.connect(w,{reliable:!0});ge=A,A.on("open",()=>{ee("handshaking"),k?.({phase:"connected",message:"Connected."}),A.send({t:"hello",protocolVersion:3,sessionId:""})}),A.on("data",async U=>{try{if(q(),U instanceof ArrayBuffer||ArrayBuffer.isView(U)||typeof Blob<"u"&&U instanceof Blob){let $;if(U instanceof ArrayBuffer)$=Promise.resolve(new Uint8Array(U));else if(ArrayBuffer.isView(U))$=Promise.resolve(new Uint8Array(U.buffer,U.byteOffset,U.byteLength));else if(typeof Blob<"u"&&U instanceof Blob)$=U.arrayBuffer().then(_=>new Uint8Array(_));else return;let L=Ce?.seq??-1;Ce=null,ie=ie.then(async()=>{let _=await $;d&&await d(_),D+=_.byteLength,V+=_.byteLength;let ae=G?Pe+V:D,j=G?G.totalSize:R,Ie=j?Math.min(100,ae/j*100):0;I()||y?.({processedBytes:ae,totalBytes:j,percent:Ie}),L>=0&&Y(A,L)}).catch(_=>{try{A.send({t:"error",message:_?.message||"Receiver write failed."})}catch{}se(_)});return}if(!ft(U))return;let T=U;switch(T.t){case"hello":Z=T.sessionId||null,ee("negotiating"),k?.({phase:"waiting",message:"Waiting for file details..."});break;case"file_list":G=T,R=G.totalSize;break;case"meta":{if(g!=="negotiating"&&!(g==="transferring"&&G))return;if(Z&&T.sessionId&&T.sessionId!==Z){try{A.send({t:"error",message:"Busy with another session."})}catch{}return}T.sessionId&&(Z=T.sessionId);let _=String(T.name||"file"),ae=Number(T.size)||0,j=T.fileIndex;if(G&&typeof j=="number"&&j>0){V=0,v?.({fileIndex:j,name:_,size:ae});break}D=0,V=0,Pe=0,G||(R=ae),ie=Promise.resolve();let Ie=()=>{ee("transferring"),q(),G&&v?.({fileIndex:0,name:_,size:ae});try{A.send({t:"ready"})}catch{}},Ae={name:_,total:R};G&&(Ae.fileCount=G.fileCount,Ae.files=G.files.map(We=>({name:We.name,size:We.size})),Ae.totalSize=G.totalSize),c?(I()||(p?.(Ae),y?.({processedBytes:D,totalBytes:R,percent:0})),Ie()):(Ae.sendReady=Ie,I()||(p?.(Ae),y?.({processedBytes:D,totalBytes:R,percent:0})));break}case"chunk":Ce=T;break;case"ping":try{A.send({t:"pong",timestamp:Date.now()})}catch{}break;case"file_end":{ne(),await ie;let _=T.fileIndex;P?.({fileIndex:_,receivedBytes:V});try{A.send({t:"file_end_ack",fileIndex:_,received:V,size:V})}catch{}Pe+=V,V=0,q();break}case"end":ne(),await ie;let $=G?Pe+V:D,L=G?G.totalSize:R;if(L&&$<L){let _=new N("Transfer ended before all data was received.");try{A.send({t:"error",message:_.message})}catch{}throw _}try{A.send({t:"end_ack",received:$,total:L})}catch{}ce({received:$,total:L}),(async()=>{for(let _=0;_<2;_++){await me(Kt);try{A.send({t:"end_ack",received:$,total:L})}catch{break}}})().catch(()=>{});break;case"error":throw new N(T.message||"Sender reported an error.");case"cancelled":if(g==="cancelled"||g==="closed"||g==="completed")return;ee("cancelled"),f?.({cancelledBy:"sender",message:T.reason}),re();break}}catch(T){se(T)}}),A.on("close",()=>{if(g==="closed"||g==="completed"||g==="cancelled"){re();return}g==="transferring"?(ee("cancelled"),f?.({cancelledBy:"sender"}),re()):g==="negotiating"?(ee("closed"),re(),m?.()):se(new N("Sender disconnected before file details were received."))})}),{peer:B,stop:b,getStatus:()=>g,getBytesReceived:()=>D,getTotalBytes:()=>R,getSessionId:()=>Z}}function qt(r){return typeof r=="string"?Ke(tt(r)):Ke(r)}function qe(r,e,t){let n=Number(r)||0;return t?n+(Number(e)||0)*28:n}async function ut(r){let{server:e,timeoutMs:t=5e3,signal:n,fetchFn:i}=r,s=i||$e();if(!s)throw new S("No fetch() implementation found.");let a=qt(e);try{let{res:l,json:o}=await oe(s,`${a}/api/info`,{method:"GET",timeoutMs:t,signal:n,headers:{Accept:"application/json"}});if(l.ok&&o&&typeof o=="object"&&"version"in o)return{baseUrl:a,serverInfo:o};throw new H(`Server info request failed (status ${l.status}).`)}catch(l){throw l instanceof X?l:new N("Could not reach server /api/info.",{cause:l})}}var pt=class{constructor(e){Q(this,"clientVersion");Q(this,"chunkSize");Q(this,"fetchFn");Q(this,"cryptoObj");Q(this,"base64");Q(this,"baseUrl");Q(this,"_fallbackToHttp");Q(this,"_compat",null);Q(this,"_connectPromise",null);if(!e||typeof e.clientVersion!="string")throw new S("DropgateClient requires clientVersion (string).");if(!e.server)throw new S("DropgateClient requires server (URL string or ServerTarget object).");this.clientVersion=e.clientVersion,this.chunkSize=Number.isFinite(e.chunkSize)?e.chunkSize:5242880;let t=e.fetchFn||$e();if(!t)throw new S("No fetch() implementation found.");this.fetchFn=t;let n=e.cryptoObj||Re();if(!n)throw new S("No crypto implementation found.");this.cryptoObj=n,this.base64=e.base64||be(),this._fallbackToHttp=!!e.fallbackToHttp,this.baseUrl=qt(e.server)}get serverTarget(){let e=new URL(this.baseUrl);return{host:e.hostname,port:e.port?Number(e.port):void 0,secure:e.protocol==="https:"}}async connect(e){return this._compat?this._compat:(this._connectPromise||(this._connectPromise=this._fetchAndCheckCompat(e).finally(()=>{this._connectPromise=null})),this._connectPromise)}async _fetchAndCheckCompat(e){let{timeoutMs:t=5e3,signal:n}=e??{},i=this.baseUrl,s;try{let l=await ut({server:i,timeoutMs:t,signal:n,fetchFn:this.fetchFn});i=l.baseUrl,s=l.serverInfo}catch(l){if(this._fallbackToHttp&&this.baseUrl.startsWith("https://")){let o=this.baseUrl.replace("https://","http://");try{let c=await ut({server:o,timeoutMs:t,signal:n,fetchFn:this.fetchFn});this.baseUrl=o,i=c.baseUrl,s=c.serverInfo}catch{throw l instanceof X?l:new N("Could not connect to the server.",{cause:l})}}else throw l instanceof X?l:new N("Could not connect to the server.",{cause:l})}let a=this._checkVersionCompat(s);return this._compat={...a,serverInfo:s,baseUrl:i},this._compat}_checkVersionCompat(e){let t=String(e?.version||"0.0.0"),n=String(this.clientVersion||"0.0.0"),i=Le(n),s=Le(t);return i.major!==s.major?{compatible:!1,clientVersion:n,serverVersion:t,message:`Incompatible versions. Client v${n}, Server v${t}${e?.name?` (${e.name})`:""}.`}:i.minor>s.minor?{compatible:!0,clientVersion:n,serverVersion:t,message:`Client (v${n}) is newer than Server (v${t})${e?.name?` (${e.name})`:""}. Some features may not work.`}:{compatible:!0,clientVersion:n,serverVersion:t,message:`Server: v${t}, Client: v${n}${e?.name?` (${e.name})`:""}.`}}async resolveShareTarget(e,t){let{timeoutMs:n=5e3,signal:i}=t??{},s=await this.connect(t);if(!s.compatible)throw new S(s.message);let{baseUrl:a}=s,{res:l,json:o}=await oe(this.fetchFn,`${a}/api/resolve`,{method:"POST",timeoutMs:n,signal:i,headers:{"Content-Type":"application/json",Accept:"application/json"},body:JSON.stringify({value:e})});if(!l.ok){let c=(o&&typeof o=="object"&&"error"in o?o.error:null)||`Share lookup failed (status ${l.status}).`;throw new H(c,{details:o})}return o||{valid:!1,reason:"Unknown response."}}async getFileMetadata(e,t){if(!e||typeof e!="string")throw new S("File ID is required.");let{timeoutMs:n=5e3,signal:i}=t??{},s=`${this.baseUrl}/api/file/${encodeURIComponent(e)}/meta`,{res:a,json:l}=await oe(this.fetchFn,s,{method:"GET",timeoutMs:n,signal:i});if(!a.ok){let o=(l&&typeof l=="object"&&"error"in l?l.error:null)||`Failed to fetch file metadata (status ${a.status}).`;throw new H(o,{details:l})}return l}async getBundleMetadata(e,t,n){if(!e||typeof e!="string")throw new S("Bundle ID is required.");let{timeoutMs:i=5e3,signal:s}=n??{},a=`${this.baseUrl}/api/bundle/${encodeURIComponent(e)}/meta`,{res:l,json:o}=await oe(this.fetchFn,a,{method:"GET",timeoutMs:i,signal:s});if(!l.ok){let d=(o&&typeof o=="object"&&"error"in o?o.error:null)||`Failed to fetch bundle metadata (status ${l.status}).`;throw new H(d,{details:o})}let c=o,h=[];if(c.sealed&&c.encryptedManifest){if(!t)throw new S("Decryption key (keyB64) is required for encrypted sealed bundles.");let d=await Ee(this.cryptoObj,t),y=this.base64.decode(c.encryptedManifest),v=await xe(this.cryptoObj,y,d),P=new TextDecoder().decode(v);h=JSON.parse(P).files.map(E=>({fileId:E.fileId,sizeBytes:E.sizeBytes,filename:E.name}))}else if(c.files)h=c.files;else throw new H("Invalid bundle metadata: missing files or manifest.");let k=h.reduce((d,y)=>d+(y.sizeBytes||0),0),p=h.length;return{isEncrypted:c.isEncrypted,sealed:c.sealed,encryptedManifest:c.encryptedManifest,files:h,totalSizeBytes:k,fileCount:p}}validateUploadInputs(e){let{files:t,lifetimeMs:n,encrypt:i,serverInfo:s}=e,a=s?.capabilities?.upload;if(!a||!a.enabled)throw new S("Server does not support file uploads.");let l=Array.isArray(t)?t:[t];if(l.length===0)throw new S("At least one file is required.");for(let h=0;h<l.length;h++){let k=l[h],p=Number(k?.size||0);if(!k||!Number.isFinite(p)||p<=0)throw new S(`File at index ${h} is missing or invalid.`);let d=Number(a.maxSizeMB);if(Number.isFinite(d)&&d>0){let y=d*1e3*1e3,v=Number.isFinite(a.chunkSize)&&a.chunkSize>0?a.chunkSize:this.chunkSize,P=Math.ceil(p/v);if(qe(p,P,!!i)>y){let E=i?`File at index ${h} too large once encryption overhead is included. Server limit: ${d} MB.`:`File at index ${h} too large. Server limit: ${d} MB.`;throw new S(E)}}}let o=Number(a.maxLifetimeHours),c=Number(n);if(!Number.isFinite(c)||c<0||!Number.isInteger(c))throw new S("Invalid lifetime. Must be a non-negative integer (milliseconds).");if(Number.isFinite(o)&&o>0){let h=Math.round(o*60*60*1e3);if(c===0)throw new S(`Server does not allow unlimited file lifetime. Max: ${o} hours.`);if(c>h)throw new S(`File lifetime too long. Server limit: ${o} hours.`)}if(i&&!a.e2ee)throw new S("End-to-end encryption is not supported on this server.");return!0}async uploadFiles(e){let{files:t,lifetimeMs:n,encrypt:i,maxDownloads:s,filenameOverrides:a,onProgress:l,onCancel:o,signal:c,timeouts:h={},retry:k={}}=e,p=Array.isArray(t)?t:[t];if(p.length===0)throw new S("At least one file is required.");let d=c?null:new AbortController,y=c||d?.signal,v="initializing",P=[],u=p.reduce((f,C)=>f+C.size,0),E=(async()=>{try{let f=b=>{try{l&&l(b)}catch{}};f({phase:"server-info",text:"Checking server...",percent:0,processedBytes:0,totalBytes:u});let C=await this.connect({timeoutMs:h.serverInfoMs??5e3,signal:y}),{baseUrl:w,serverInfo:M}=C;if(f({phase:"server-compat",text:C.message,percent:0,processedBytes:0,totalBytes:u}),!C.compatible)throw new S(C.message);let z=p.map((b,Y)=>a?.[Y]??b.name??"file"),F=!!M?.capabilities?.upload?.e2ee,B=i??F;if(!B)for(let b of z)et(b);this.validateUploadInputs({files:p,lifetimeMs:n,encrypt:B,serverInfo:M});let g=null,R=null,D=[];if(B){if(!this.cryptoObj?.subtle)throw new S("Web Crypto API not available (crypto.subtle). Encryption requires a secure context (HTTPS or localhost).");f({phase:"crypto",text:"Generating encryption key...",percent:0,processedBytes:0,totalBytes:u});try{g=await nt(this.cryptoObj),R=await it(this.cryptoObj,g);for(let b of z)D.push(await st(this.cryptoObj,b,g))}catch(b){throw new X("Failed to prepare encryption.",{code:"CRYPTO_PREP_FAILED",cause:b})}}else D.push(...z);let Z=M?.capabilities?.upload?.chunkSize,ie=Number.isFinite(Z)&&Z>0?Z:this.chunkSize,pe=Number.isFinite(k.retries)?k.retries:5,ge=Number.isFinite(k.backoffMs)?k.backoffMs:1e3,Ce=Number.isFinite(k.maxBackoffMs)?k.maxBackoffMs:3e4;if(p.length===1){let b=p[0],Y=Math.ceil(b.size/ie),A=qe(b.size,Y,B);f({phase:"init",text:"Reserving server storage...",percent:0,processedBytes:0,totalBytes:b.size});let U=await oe(this.fetchFn,`${w}/upload/init`,{method:"POST",timeoutMs:h.initMs??15e3,signal:y,headers:{"Content-Type":"application/json",Accept:"application/json"},body:JSON.stringify({filename:D[0],lifetime:n,isEncrypted:B,totalSize:A,totalChunks:Y,...s!==void 0?{maxDownloads:s}:{}})});if(!U.res.ok){let ae=U.json;throw new H(ae?.error||`Server initialisation failed: ${U.res.status}`,{details:U.json||U.text})}let T=U.json?.uploadId;if(!T)throw new H("Server did not return a valid uploadId.");P.push(T),v="uploading",await this._uploadFileChunks({file:b,uploadId:T,cryptoKey:g,effectiveChunkSize:ie,totalChunks:Y,totalUploadSize:A,baseOffset:0,totalBytesAllFiles:b.size,progress:f,signal:y,baseUrl:w,retries:pe,backoffMs:ge,maxBackoffMs:Ce,chunkTimeoutMs:h.chunkMs??6e4}),f({phase:"complete",text:"Finalising upload...",percent:100,processedBytes:b.size,totalBytes:b.size}),v="completing";let $=await oe(this.fetchFn,`${w}/upload/complete`,{method:"POST",timeoutMs:h.completeMs??3e4,signal:y,headers:{"Content-Type":"application/json",Accept:"application/json"},body:JSON.stringify({uploadId:T})});if(!$.res.ok){let ae=$.json;throw new H(ae?.error||"Finalisation failed.",{details:$.json||$.text})}let L=$.json?.id;if(!L)throw new H("Server did not return a valid file id.");let _=`${w}/${L}`;return B&&R&&(_+=`#${R}`),f({phase:"done",text:"Upload successful!",percent:100,processedBytes:b.size,totalBytes:b.size}),v="completed",{downloadUrl:_,fileId:L,uploadId:T,baseUrl:w,...B&&R?{keyB64:R}:{}}}let G=p.map((b,Y)=>{let A=Math.ceil(b.size/ie),U=qe(b.size,A,B);return{filename:D[Y],totalSize:U,totalChunks:A}});f({phase:"init",text:`Reserving server storage for ${p.length} files...`,percent:0,processedBytes:0,totalBytes:u,totalFiles:p.length});let V=await oe(this.fetchFn,`${w}/upload/init-bundle`,{method:"POST",timeoutMs:h.initMs??15e3,signal:y,headers:{"Content-Type":"application/json",Accept:"application/json"},body:JSON.stringify({fileCount:p.length,files:G,lifetime:n,isEncrypted:B,...s!==void 0?{maxDownloads:s}:{}})});if(!V.res.ok){let b=V.json;throw new H(b?.error||`Bundle initialisation failed: ${V.res.status}`,{details:V.json||V.text})}let Pe=V.json,ee=Pe?.bundleUploadId,I=Pe?.fileUploadIds;if(!ee||!I||I.length!==p.length)throw new H("Server did not return valid bundle upload IDs.");P.push(...I),v="uploading";let q=[],ne=0;for(let b=0;b<p.length;b++){let Y=p[b],A=I[b],U=G[b].totalChunks,T=G[b].totalSize;f({phase:"file-start",text:`Uploading file ${b+1} of ${p.length}: ${z[b]}`,percent:u>0?ne/u*100:0,processedBytes:ne,totalBytes:u,fileIndex:b,totalFiles:p.length,currentFileName:z[b]}),await this._uploadFileChunks({file:Y,uploadId:A,cryptoKey:g,effectiveChunkSize:ie,totalChunks:U,totalUploadSize:T,baseOffset:ne,totalBytesAllFiles:u,progress:f,signal:y,baseUrl:w,retries:pe,backoffMs:ge,maxBackoffMs:Ce,chunkTimeoutMs:h.chunkMs??6e4,fileIndex:b,totalFiles:p.length,currentFileName:z[b]});let $=await oe(this.fetchFn,`${w}/upload/complete`,{method:"POST",timeoutMs:h.completeMs??3e4,signal:y,headers:{"Content-Type":"application/json",Accept:"application/json"},body:JSON.stringify({uploadId:A})});if(!$.res.ok){let _=$.json;throw new H(_?.error||`File ${b+1} finalisation failed.`,{details:$.json||$.text})}let L=$.json?.id;if(!L)throw new H(`Server did not return a valid file id for file ${b+1}.`);q.push({fileId:L,name:z[b],size:Y.size}),ne+=Y.size,f({phase:"file-complete",text:`File ${b+1} of ${p.length} uploaded.`,percent:u>0?ne/u*100:0,processedBytes:ne,totalBytes:u,fileIndex:b,totalFiles:p.length,currentFileName:z[b]})}f({phase:"complete",text:"Finalising bundle...",percent:100,processedBytes:u,totalBytes:u}),v="completing";let se;if(B&&g){let b=JSON.stringify({files:q.map(T=>({fileId:T.fileId,name:T.name,sizeBytes:T.size}))}),Y=new TextEncoder().encode(b),A=await _e(this.cryptoObj,Y.buffer,g),U=new Uint8Array(await A.arrayBuffer());se=this.base64.encode(U)}let ce=await oe(this.fetchFn,`${w}/upload/complete-bundle`,{method:"POST",timeoutMs:h.completeMs??3e4,signal:y,headers:{"Content-Type":"application/json",Accept:"application/json"},body:JSON.stringify({bundleUploadId:ee,...se?{encryptedManifest:se}:{}})});if(!ce.res.ok){let b=ce.json;throw new H(b?.error||"Bundle finalisation failed.",{details:ce.json||ce.text})}let re=ce.json?.bundleId;if(!re)throw new H("Server did not return a valid bundle id.");let fe=`${w}/b/${re}`;return B&&R&&(fe+=`#${R}`),f({phase:"done",text:"Upload successful!",percent:100,processedBytes:u,totalBytes:u}),v="completed",{downloadUrl:fe,bundleId:re,baseUrl:w,files:q,...B&&R?{keyB64:R}:{}}}catch(f){throw f instanceof Error&&(f.name==="AbortError"||f.message?.includes("abort"))?(v="cancelled",o?.()):v="error",f}})(),m=async f=>{try{await oe(this.fetchFn,`${this.baseUrl}/upload/cancel`,{method:"POST",timeoutMs:5e3,headers:{"Content-Type":"application/json",Accept:"application/json"},body:JSON.stringify({uploadId:f})})}catch{}};return{result:E,cancel:f=>{if(!(v==="completed"||v==="cancelled")){v="cancelled";for(let C of P)m(C).catch(()=>{});d?.abort(new te(f||"Upload cancelled by user."))}},getStatus:()=>v}}async _uploadFileChunks(e){let{file:t,uploadId:n,cryptoKey:i,effectiveChunkSize:s,totalChunks:a,baseOffset:l,totalBytesAllFiles:o,progress:c,signal:h,baseUrl:k,retries:p,backoffMs:d,maxBackoffMs:y,chunkTimeoutMs:v,fileIndex:P,totalFiles:u,currentFileName:E}=e;for(let m=0;m<a;m++){if(h?.aborted)throw h.reason||new te;let f=m*s,C=Math.min(f+s,t.size),w=t.slice(f,C),M=l+f,z=o>0?M/o*100:0;c({phase:"chunk",text:`Uploading chunk ${m+1} of ${a}...`,percent:z,processedBytes:M,totalBytes:o,chunkIndex:m,totalChunks:a,...P!==void 0?{fileIndex:P,totalFiles:u,currentFileName:E}:{}});let F=await w.arrayBuffer(),B;if(i?B=await _e(this.cryptoObj,F,i):B=new Blob([F]),B.size>s+1024)throw new S("Chunk too large (client-side). Check chunk size settings.");let g=await B.arrayBuffer(),R=await rt(this.cryptoObj,g);await this._attemptChunkUpload(`${k}/upload/chunk`,{method:"POST",headers:{"Content-Type":"application/octet-stream","X-Upload-ID":n,"X-Chunk-Index":String(m),"X-Chunk-Hash":R},body:B},{retries:p,backoffMs:d,maxBackoffMs:y,timeoutMs:v,signal:h,progress:c,chunkIndex:m,totalChunks:a,chunkSize:s,fileSizeBytes:o})}}async downloadFiles(e){let{fileId:t,bundleId:n,keyB64:i,asZip:s,zipFilename:a,onProgress:l,onData:o,onFileStart:c,onFileData:h,onFileEnd:k,signal:p,timeoutMs:d=6e4}=e,y=M=>{try{l&&l(M)}catch{}};if(!t&&!n)throw new S("Either fileId or bundleId is required.");y({phase:"server-info",text:"Checking server...",processedBytes:0,totalBytes:0,percent:0});let v=await this.connect({timeoutMs:d,signal:p}),{baseUrl:P}=v;if(y({phase:"server-compat",text:v.message,processedBytes:0,totalBytes:0,percent:0}),!v.compatible)throw new S(v.message);if(t)return this._downloadSingleFile({fileId:t,keyB64:i,onProgress:l,onData:o,signal:p,timeoutMs:d,baseUrl:P,compat:v});y({phase:"metadata",text:"Fetching bundle info...",processedBytes:0,totalBytes:0,percent:0});let u;try{u=await this.getBundleMetadata(n,i,{timeoutMs:d,signal:p})}catch(M){throw M instanceof X?M:M instanceof Error&&M.name==="AbortError"?new te("Download cancelled."):new N("Could not fetch bundle metadata.",{cause:M})}let E=!!u.isEncrypted,m=u.totalSizeBytes||0,f,C=[];if(E){if(!i)throw new S("Decryption key is required for encrypted bundles.");if(!this.cryptoObj?.subtle)throw new S("Web Crypto API not available for decryption.");try{if(f=await Ee(this.cryptoObj,i,this.base64),u.sealed&&u.encryptedManifest){let M=this.base64.decode(u.encryptedManifest),z=await xe(this.cryptoObj,M,f),F=new TextDecoder().decode(z),B=JSON.parse(F);u.files=B.files.map(g=>({fileId:g.fileId,sizeBytes:g.sizeBytes,filename:g.name})),u.fileCount=u.files.length;for(let g of u.files)C.push(g.filename||"file")}else for(let M of u.files)C.push(await De(this.cryptoObj,M.encryptedFilename,f,this.base64))}catch(M){throw new X("Failed to decrypt bundle manifest.",{code:"DECRYPT_MANIFEST_FAILED",cause:M})}}else for(let M of u.files)C.push(M.filename||"file");let w=0;if(s&&o){let M=new Ne(o);for(let z=0;z<u.files.length;z++){let F=u.files[z],B=C[z];y({phase:"zipping",text:`Downloading ${B}...`,percent:m>0?w/m*100:0,processedBytes:w,totalBytes:m,fileIndex:z,totalFiles:u.files.length,currentFileName:B}),M.startFile(B);let g=w,R=await this._streamFileIntoCallback(P,F.fileId,E,f,v,p,d,D=>{M.writeChunk(D)},D=>{let Z=g+D;y({phase:"zipping",text:`Downloading ${B}...`,percent:m>0?Z/m*100:0,processedBytes:Z,totalBytes:m,fileIndex:z,totalFiles:u.files.length,currentFileName:B})});M.endFile(),w+=R}await M.finalize();try{await oe(this.fetchFn,`${P}/api/bundle/${n}/downloaded`,{method:"POST",timeoutMs:5e3,headers:{"Content-Type":"application/json",Accept:"application/json"},body:"{}"})}catch{}return y({phase:"complete",text:"Download complete!",percent:100,processedBytes:w,totalBytes:m}),{filenames:C,receivedBytes:w,wasEncrypted:E}}else{let M=h||o;for(let z=0;z<u.files.length;z++){let F=u.files[z],B=C[z];y({phase:"downloading",text:`Downloading ${B}...`,percent:m>0?w/m*100:0,processedBytes:w,totalBytes:m,fileIndex:z,totalFiles:u.files.length,currentFileName:B}),c?.({name:B,size:F.sizeBytes,index:z});let g=w,R=await this._streamFileIntoCallback(P,F.fileId,E,f,v,p,d,M?D=>M(D):void 0,D=>{let Z=g+D;y({phase:"downloading",text:`Downloading ${B}...`,percent:m>0?Z/m*100:0,processedBytes:Z,totalBytes:m,fileIndex:z,totalFiles:u.files.length,currentFileName:B})});k?.({name:B,index:z}),w+=R}return y({phase:"complete",text:"Download complete!",percent:100,processedBytes:w,totalBytes:m}),{filenames:C,receivedBytes:w,wasEncrypted:E}}}async _downloadSingleFile(e){let{fileId:t,keyB64:n,onProgress:i,onData:s,signal:a,timeoutMs:l,baseUrl:o,compat:c}=e,h=f=>{try{i&&i(f)}catch{}};h({phase:"metadata",text:"Fetching file info...",processedBytes:0,totalBytes:0,percent:0});let k;try{k=await this.getFileMetadata(t,{timeoutMs:l,signal:a})}catch(f){throw f instanceof X?f:f instanceof Error&&f.name==="AbortError"?new te("Download cancelled."):new N("Could not fetch file metadata.",{cause:f})}let p=!!k.isEncrypted,d=k.sizeBytes||0;if(!s&&d>104857600){let f=Math.round(d/1048576),C=Math.round(104857600/(1024*1024));throw new S(`File is too large (${f}MB) to download without streaming. Provide an onData callback to stream files larger than ${C}MB.`)}let y,v;if(p){if(!n)throw new S("Decryption key is required for encrypted files.");if(!this.cryptoObj?.subtle)throw new S("Web Crypto API not available for decryption.");h({phase:"decrypting",text:"Preparing decryption...",processedBytes:0,totalBytes:0,percent:0});try{v=await Ee(this.cryptoObj,n,this.base64),y=await De(this.cryptoObj,k.encryptedFilename,v,this.base64)}catch(f){throw new X("Failed to decrypt filename.",{code:"DECRYPT_FILENAME_FAILED",cause:f})}}else y=k.filename||"file";h({phase:"downloading",text:"Starting download...",percent:0,processedBytes:0,totalBytes:d});let P=[],u=!s,E=await this._streamFileIntoCallback(o,t,p,v,c,a,l,async f=>{u?P.push(f):await s(f)},f=>{h({phase:"downloading",text:"Downloading...",percent:d>0?f/d*100:0,processedBytes:f,totalBytes:d})});h({phase:"complete",text:"Download complete!",percent:100,processedBytes:E,totalBytes:d});let m;if(u&&P.length>0){let f=P.reduce((w,M)=>w+M.length,0);m=new Uint8Array(f);let C=0;for(let w of P)m.set(w,C),C+=w.length}return{filename:y,receivedBytes:E,wasEncrypted:p,...m?{data:m}:{}}}async _streamFileIntoCallback(e,t,n,i,s,a,l,o,c){let{signal:h,cleanup:k}=Oe(a,l),p=0;try{let d=await this.fetchFn(`${e}/api/file/${t}`,{method:"GET",signal:h});if(!d.ok)throw new H(`Download failed (status ${d.status}).`);if(!d.body)throw new H("Streaming response not available.");let y=d.body.getReader();if(n&&i){let P=(Number.isFinite(s.serverInfo?.capabilities?.upload?.chunkSize)&&s.serverInfo.capabilities.upload.chunkSize>0?s.serverInfo.capabilities.upload.chunkSize:this.chunkSize)+28,u=[],E=0,m=()=>{if(u.length===0)return new Uint8Array(0);if(u.length===1){let w=u[0];return u.length=0,E=0,w}let f=new Uint8Array(E),C=0;for(let w of u)f.set(w,C),C+=w.length;return u.length=0,E=0,f};for(;;){if(a?.aborted)throw new te("Download cancelled.");let{done:f,value:C}=await y.read();if(f)break;for(u.push(C),E+=C.length,p+=C.length,c&&c(p);E>=P;){let w=m(),M=w.subarray(0,P);w.length>P&&(u.push(w.subarray(P)),E=w.length-P);let z=await xe(this.cryptoObj,M,i);o&&await o(new Uint8Array(z))}}if(E>0){let f=m(),C=await xe(this.cryptoObj,f,i);o&&await o(new Uint8Array(C))}}else for(;;){if(a?.aborted)throw new te("Download cancelled.");let{done:v,value:P}=await y.read();if(v)break;p+=P.length,c&&c(p),o&&await o(P)}}catch(d){throw d instanceof X?d:d instanceof Error&&d.name==="AbortError"?new te("Download cancelled."):new N("Download failed.",{cause:d})}finally{k()}return p}async p2pSend(e){let t=await this.connect();if(!t.compatible)throw new S(t.message);let{serverInfo:n}=t,i=n?.capabilities?.p2p;if(!i?.enabled)throw new S("Direct transfer is disabled on this server.");let{host:s,port:a,secure:l}=this.serverTarget,{path:o,iceServers:c}=Fe({},i);return Gt({...e,host:s,port:a,secure:l,peerjsPath:o,iceServers:c,serverInfo:n,cryptoObj:this.cryptoObj})}async p2pReceive(e){let t=await this.connect();if(!t.compatible)throw new S(t.message);let{serverInfo:n}=t,i=n?.capabilities?.p2p;if(!i?.enabled)throw new S("Direct transfer is disabled on this server.");let{host:s,port:a,secure:l}=this.serverTarget,{path:o,iceServers:c}=Fe({},i);return Vt({...e,host:s,port:a,secure:l,peerjsPath:o,iceServers:c,serverInfo:n})}async _attemptChunkUpload(e,t,n){let{retries:i,backoffMs:s,maxBackoffMs:a,timeoutMs:l,signal:o,progress:c,chunkIndex:h,totalChunks:k,chunkSize:p,fileSizeBytes:d}=n,y=i,v=s,P=i;for(;;){if(o?.aborted)throw o.reason||new te;let{signal:u,cleanup:E}=Oe(o,l);try{let m=await this.fetchFn(e,{...t,signal:u});if(m.ok)return;let f=await m.text().catch(()=>"");throw new H(`Chunk ${h+1} failed (HTTP ${m.status}).`,{details:{status:m.status,bodySnippet:f.slice(0,120)}})}catch(m){if(E(),m instanceof Error&&(m.name==="AbortError"||m.code==="ABORT_ERR"))throw m;if(o?.aborted)throw o.reason||new te;if(y<=0)throw m instanceof X?m:new N("Chunk upload failed.",{cause:m});let f=P-y+1,C=h*p,w=h/k*100,M=v,z=100;for(;M>0;){let F=(M/1e3).toFixed(1);c({phase:"retry-wait",text:`Chunk upload failed. Retrying in ${F}s... (${f}/${P})`,percent:w,processedBytes:C,totalBytes:d,chunkIndex:h,totalChunks:k}),await me(Math.min(z,M),o),M-=z}c({phase:"retry",text:`Chunk upload failed. Retrying now... (${f}/${P})`,percent:w,processedBytes:C,totalBytes:d,chunkIndex:h,totalChunks:k}),y-=1,v=Math.min(v*2,a);continue}finally{E()}}}};return nr(kr);})();
1
+ "use strict";var DropgateCore=(()=>{var rt=Object.defineProperty;var tn=Object.getOwnPropertyDescriptor;var nn=Object.getOwnPropertyNames;var rn=Object.prototype.hasOwnProperty;var sn=(n,e,t)=>e in n?rt(n,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):n[e]=t;var on=(n=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(n,{get:(e,t)=>(typeof require<"u"?require:e)[t]}):n)(function(n){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+n+'" is not supported')});var an=(n,e)=>{for(var t in e)rt(n,t,{get:e[t],enumerable:!0})},ln=(n,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of nn(e))!rn.call(n,i)&&i!==t&&rt(n,i,{get:()=>e[i],enumerable:!(r=tn(e,i))||r.enumerable});return n};var cn=n=>ln(rt({},"__esModule",{value:!0}),n);var te=(n,e,t)=>sn(n,typeof e!="symbol"?e+"":e,t);var Un={};an(Un,{AES_GCM_IV_BYTES:()=>qe,AES_GCM_TAG_BYTES:()=>kt,DEFAULT_CHUNK_SIZE:()=>wt,DropgateAbortError:()=>ne,DropgateClient:()=>vt,DropgateError:()=>X,DropgateNetworkError:()=>D,DropgateProtocolError:()=>L,DropgateTimeoutError:()=>Ne,DropgateValidationError:()=>y,ENCRYPTION_OVERHEAD_PER_CHUNK:()=>it,StreamingZipWriter:()=>Ge,arrayBufferToBase64:()=>$e,base64ToBytes:()=>Et,buildBaseUrl:()=>Je,bytesToBase64:()=>bt,decryptChunk:()=>Ee,decryptFilenameFromBase64:()=>Ke,encryptFilenameToBase64:()=>ft,encryptToBlob:()=>He,estimateTotalUploadSizeBytes:()=>Qe,exportKeyBase64:()=>ct,fetchJson:()=>ce,generateAesGcmKey:()=>lt,generateP2PCode:()=>Ze,getDefaultBase64:()=>Be,getDefaultCrypto:()=>je,getDefaultFetch:()=>Ve,getServerInfo:()=>gt,importKeyFromBase64:()=>Re,isLocalhostHostname:()=>ht,isP2PCodeLike:()=>Ye,isSecureContextForP2P:()=>xt,lifetimeToMs:()=>Ft,makeAbortSignal:()=>Le,parseSemverMajorMinor:()=>We,parseServerUrl:()=>ot,sha256Hex:()=>at,sleep:()=>Pe,validatePlainFilename:()=>st});var wt=5242880,qe=12,kt=16,it=28;var X=class extends Error{constructor(t,r={}){super(t,r.cause!==void 0?{cause:r.cause}:void 0);te(this,"code");te(this,"details");this.name=this.constructor.name,this.code=r.code||"DROPGATE_ERROR",this.details=r.details}},y=class extends X{constructor(e,t={}){super(e,{...t,code:t.code||"VALIDATION_ERROR"})}},D=class extends X{constructor(e,t={}){super(e,{...t,code:t.code||"NETWORK_ERROR"})}},L=class extends X{constructor(e,t={}){super(e,{...t,code:t.code||"PROTOCOL_ERROR"})}},ne=class extends X{constructor(e="Operation aborted"){super(e,{code:"ABORT_ERROR"}),this.name="AbortError"}},Ne=class extends X{constructor(e="Request timed out"){super(e,{code:"TIMEOUT_ERROR"}),this.name="TimeoutError"}};function Be(){if(typeof Buffer<"u"&&typeof Buffer.from=="function")return{encode(n){return Buffer.from(n).toString("base64")},decode(n){return new Uint8Array(Buffer.from(n,"base64"))}};if(typeof btoa=="function"&&typeof atob=="function")return{encode(n){let e="";for(let t=0;t<n.length;t++)e+=String.fromCharCode(n[t]);return btoa(e)},decode(n){let e=atob(n),t=new Uint8Array(e.length);for(let r=0;r<e.length;r++)t[r]=e.charCodeAt(r);return t}};throw new Error("No Base64 implementation available. Provide a Base64Adapter via options.")}function je(){return globalThis.crypto}function Ve(){return globalThis.fetch?.bind(globalThis)}var Pt=null;function Bt(n){return n||(Pt||(Pt=Be()),Pt)}function bt(n,e){return Bt(e).encode(n)}function $e(n,e){return bt(new Uint8Array(n),e)}function Et(n,e){return Bt(e).decode(n)}var fn={minutes:6e4,hours:36e5,days:864e5};function Ft(n,e){let t=String(e||"").toLowerCase(),r=Number(n);if(t==="unlimited"||!Number.isFinite(r)||r<=0)return 0;let i=fn[t];return i?Math.round(r*i):0}function We(n){let e=String(n||"").split(".").map(i=>Number(i)),t=Number.isFinite(e[0])?e[0]:0,r=Number.isFinite(e[1])?e[1]:0;return{major:t,minor:r}}function st(n){if(typeof n!="string"||n.trim().length===0)throw new y("Invalid filename. Must be a non-empty string.");if(n.length>255||/[\/\\]/.test(n))throw new y("Invalid filename. Contains illegal characters or is too long.")}function ot(n){let e=n.trim();!e.startsWith("http://")&&!e.startsWith("https://")&&(e="https://"+e);let t=new URL(e);return{host:t.hostname,port:t.port?Number(t.port):void 0,secure:t.protocol==="https:"}}function Je(n){let{host:e,port:t,secure:r}=n;if(!e||typeof e!="string")throw new y("Server host is required.");let i=r===!1?"http":"https",s=t?`:${t}`:"";return`${i}://${e}${s}`}function Pe(n,e){return new Promise((t,r)=>{if(e?.aborted)return r(e.reason||new ne);let i=setTimeout(t,n);e&&e.addEventListener("abort",()=>{clearTimeout(i),r(e.reason||new ne)},{once:!0})})}function Le(n,e){let t=new AbortController,r=null,i=s=>{t.signal.aborted||t.abort(s)};return n&&(n.aborted?i(n.reason):n.addEventListener("abort",()=>i(n.reason),{once:!0})),Number.isFinite(e)&&e>0&&(r=setTimeout(()=>{i(new Ne)},e)),{signal:t.signal,cleanup:()=>{r&&clearTimeout(r)}}}async function ce(n,e,t={}){let{timeoutMs:r,signal:i,...s}=t,{signal:a,cleanup:l}=Le(i,r);try{let o=await n(e,{...s,signal:a}),c=await o.text(),h=null;try{h=c?JSON.parse(c):null}catch{}return{res:o,json:h,text:c}}finally{l()}}var un=new Uint32Array([1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298]);function Ce(n,e){return n>>>e|n<<32-e}function It(n){let e=new Uint8Array(n),t=e.length*8,r=new Uint8Array(Math.ceil((e.length+9)/64)*64);r.set(e),r[e.length]=128;let i=new DataView(r.buffer);i.setUint32(r.length-8,t/4294967296>>>0,!1),i.setUint32(r.length-4,t>>>0,!1);let s=1779033703,a=3144134277,l=1013904242,o=2773480762,c=1359893119,h=2600822924,B=528734635,p=1541459225,d=new Uint32Array(64);for(let b=0;b<r.length;b+=64){for(let F=0;F<16;F++)d[F]=i.getUint32(b+F*4,!1);for(let F=16;F<64;F++){let M=Ce(d[F-15],7)^Ce(d[F-15],18)^d[F-15]>>>3,m=Ce(d[F-2],17)^Ce(d[F-2],19)^d[F-2]>>>10;d[F]=d[F-16]+M+d[F-7]+m|0}let u=s,E=a,g=l,f=o,C=c,S=h,A=B,z=p;for(let F=0;F<64;F++){let M=Ce(C,6)^Ce(C,11)^Ce(C,25),m=C&S^~C&A,T=z+M+m+un[F]+d[F]|0,R=Ce(u,2)^Ce(u,13)^Ce(u,22),Z=u&E^u&g^E&g,oe=R+Z|0;z=A,A=S,S=C,C=f+T|0,f=g,g=E,E=u,u=T+oe|0}s=s+u|0,a=a+E|0,l=l+g|0,o=o+f|0,c=c+C|0,h=h+S|0,B=B+A|0,p=p+z|0}let w=new ArrayBuffer(32),v=new DataView(w);return v.setUint32(0,s,!1),v.setUint32(4,a,!1),v.setUint32(8,l,!1),v.setUint32(12,o,!1),v.setUint32(16,c,!1),v.setUint32(20,h,!1),v.setUint32(24,B,!1),v.setUint32(28,p,!1),w}async function Re(n,e,t){let i=(t||Be()).decode(e),s=new Uint8Array(i).buffer;return n.subtle.importKey("raw",s,{name:"AES-GCM"},!0,["decrypt"])}async function Ee(n,e,t){let r=e.slice(0,12),i=e.slice(12);return n.subtle.decrypt({name:"AES-GCM",iv:r},t,i)}async function Ke(n,e,t,r){let s=(r||Be()).decode(e),a=await Ee(n,s,t);return new TextDecoder().decode(a)}function zt(n){let e=new Uint8Array(n),t="";for(let r=0;r<e.length;r++)t+=e[r].toString(16).padStart(2,"0");return t}async function at(n,e){if(n?.subtle){let t=await n.subtle.digest("SHA-256",e);return zt(t)}return zt(It(e))}async function lt(n){return n.subtle.generateKey({name:"AES-GCM",length:256},!0,["encrypt","decrypt"])}async function ct(n,e){let t=await n.subtle.exportKey("raw",e);return $e(t)}async function He(n,e,t){let r=n.getRandomValues(new Uint8Array(12)),i=await n.subtle.encrypt({name:"AES-GCM",iv:r},t,e);return new Blob([r,new Uint8Array(i)])}async function ft(n,e,t){let r=new TextEncoder().encode(String(e)),s=await(await He(n,r.buffer,t)).arrayBuffer();return $e(s)}var Ot=on("module"),pn=(0,Ot.createRequire)("/"),hn;try{hn=pn("worker_threads").Worker}catch{}var ue=Uint8Array,Dt=Uint16Array,dn=Int32Array,mn=new ue([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]),gn=new ue([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]),ir=new ue([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]),_t=function(n,e){for(var t=new Dt(31),r=0;r<31;++r)t[r]=e+=1<<n[r-1];for(var i=new dn(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}},Nt=_t(mn,2),vn=Nt.b,yn=Nt.r;vn[28]=258,yn[258]=28;var jt=_t(gn,0),sr=jt.b,or=jt.r,wn=new Dt(32768);for(O=0;O<32768;++O)Fe=(O&43690)>>1|(O&21845)<<1,Fe=(Fe&52428)>>2|(Fe&13107)<<2,Fe=(Fe&61680)>>4|(Fe&3855)<<4,wn[O]=((Fe&65280)>>8|(Fe&255)<<8)>>1;var Fe,O;var pt=new ue(288);for(O=0;O<144;++O)pt[O]=8;var O;for(O=144;O<256;++O)pt[O]=9;var O;for(O=256;O<280;++O)pt[O]=7;var O;for(O=280;O<288;++O)pt[O]=8;var O,Pn=new ue(32);for(O=0;O<32;++O)Pn[O]=5;var O;var bn=function(n,e,t){return(e==null||e<0)&&(e=0),(t==null||t>n.length)&&(t=n.length),new ue(n.subarray(e,t))};var xn=["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"],Ie=function(n,e,t){var r=new Error(e||xn[n]);if(r.code=n,Error.captureStackTrace&&Error.captureStackTrace(r,Ie),!t)throw r;return r};var Sn=new ue(0);var Cn=(function(){for(var n=new Int32Array(256),e=0;e<256;++e){for(var t=e,r=9;--r;)t=(t&1&&-306674912)^t>>>1;n[e]=t}return n})(),An=function(){var n=-1;return{p:function(e){for(var t=n,r=0;r<e.length;++r)t=Cn[t&255^e[r]]^t>>>8;n=t},d:function(){return~n}}};var Mn=function(n,e){var t={};for(var r in n)t[r]=n[r];for(var r in e)t[r]=e[r];return t};var J=function(n,e,t){for(;t;++e)n[e]=t,t>>>=8};var Tt=typeof TextEncoder<"u"&&new TextEncoder,kn=typeof TextDecoder<"u"&&new TextDecoder,Bn=0;try{kn.decode(Sn,{stream:!0}),Bn=1}catch{}function Rt(n,e){if(e){for(var t=new ue(n.length),r=0;r<n.length;++r)t[r]=n.charCodeAt(r);return t}if(Tt)return Tt.encode(n);for(var i=n.length,s=new ue(n.length+(n.length>>1)),a=0,l=function(h){s[a++]=h},r=0;r<i;++r){if(a+5>s.length){var o=new ue(a+8+(i-r<<1));o.set(s),s=o}var c=n.charCodeAt(r);c<128||e?l(c):c<2048?(l(192|c>>6),l(128|c&63)):c>55295&&c<57344?(c=65536+(c&1047552)|n.charCodeAt(++r)&1023,l(240|c>>18),l(128|c>>12&63),l(128|c>>6&63),l(128|c&63)):(l(224|c>>12),l(128|c>>6&63),l(128|c&63))}return bn(s,0,a)}var ut=function(n){var e=0;if(n)for(var t in n){var r=n[t].length;r>65535&&Ie(9),e+=r+4}return e},Ut=function(n,e,t,r,i,s,a,l){var o=r.length,c=t.extra,h=l&&l.length,B=ut(c);J(n,e,a!=null?33639248:67324752),e+=4,a!=null&&(n[e++]=20,n[e++]=t.os),n[e]=20,e+=2,n[e++]=t.flag<<1|(s<0&&8),n[e++]=i&&8,n[e++]=t.compression&255,n[e++]=t.compression>>8;var p=new Date(t.mtime==null?Date.now():t.mtime),d=p.getFullYear()-1980;if((d<0||d>119)&&Ie(10),J(n,e,d<<25|p.getMonth()+1<<21|p.getDate()<<16|p.getHours()<<11|p.getMinutes()<<5|p.getSeconds()>>1),e+=4,s!=-1&&(J(n,e,t.crc),J(n,e+4,s<0?-s-2:s),J(n,e+8,t.size)),J(n,e+12,o),J(n,e+14,B),e+=16,a!=null&&(J(n,e,h),J(n,e+6,t.attrs),J(n,e+10,a),e+=14),n.set(r,e),e+=o,B)for(var w in c){var v=c[w],b=v.length;J(n,e,+w),J(n,e+2,b),n.set(v,e+4),e+=4+b}return h&&(n.set(l,e),e+=h),e},En=function(n,e,t,r,i){J(n,e,101010256),J(n,e+8,t),J(n,e+10,t),J(n,e+12,r),J(n,e+16,i)},$t=(function(){function n(e){this.filename=e,this.c=An(),this.size=0,this.compression=0}return n.prototype.process=function(e,t){this.ondata(null,e,t)},n.prototype.push=function(e,t){this.ondata||Ie(5),this.c.p(e),this.size+=e.length,t&&(this.crc=this.c.d()),this.process(e,t||!1)},n})();var Lt=(function(){function n(e){this.ondata=e,this.u=[],this.d=1}return n.prototype.add=function(e){var t=this;if(this.ondata||Ie(5),this.d&2)this.ondata(Ie(4+(this.d&1)*8,0,1),null,!1);else{var r=Rt(e.filename),i=r.length,s=e.comment,a=s&&Rt(s),l=i!=e.filename.length||a&&s.length!=a.length,o=i+ut(e.extra)+30;i>65535&&this.ondata(Ie(11,0,1),null,!1);var c=new ue(o);Ut(c,0,e,r,l,-1);var h=[c],B=function(){for(var b=0,u=h;b<u.length;b++){var E=u[b];t.ondata(null,E,!1)}h=[]},p=this.d;this.d=0;var d=this.u.length,w=Mn(e,{f:r,u:l,o:a,t:function(){e.terminate&&e.terminate()},r:function(){if(B(),p){var b=t.u[d+1];b?b.r():t.d=1}p=1}}),v=0;e.ondata=function(b,u,E){if(b)t.ondata(b,u,E),t.terminate();else if(v+=u.length,h.push(u),E){var g=new ue(16);J(g,0,134695760),J(g,4,e.crc),J(g,8,v),J(g,12,e.size),h.push(g),w.c=v,w.b=o+v+16,w.crc=e.crc,w.size=e.size,p&&w.r(),p=1}else p&&B()},this.u.push(w)}},n.prototype.end=function(){var e=this;if(this.d&2){this.ondata(Ie(4+(this.d&1)*8,0,1),null,!0);return}this.d?this.e():this.u.push({r:function(){e.d&1&&(e.u.splice(-1,1),e.e())},t:function(){}}),this.d=3},n.prototype.e=function(){for(var e=0,t=0,r=0,i=0,s=this.u;i<s.length;i++){var a=s[i];r+=46+a.f.length+ut(a.extra)+(a.o?a.o.length:0)}for(var l=new ue(r+22),o=0,c=this.u;o<c.length;o++){var a=c[o];Ut(l,e,a,a.f,a.u,-a.c-2,t,a.o),e+=46+a.f.length+ut(a.extra)+(a.o?a.o.length:0),t+=a.b}En(l,e,this.u.length,r,t),this.ondata(null,l,!0),this.d=2},n.prototype.terminate=function(){for(var e=0,t=this.u;e<t.length;e++){var r=t[e];r.t()}this.d=2},n})();var Ge=class{constructor(e){te(this,"zip");te(this,"currentFile",null);te(this,"onData");te(this,"finalized",!1);te(this,"pendingWrites",Promise.resolve());this.onData=e,this.zip=new Lt((t,r,i)=>{if(t)throw t;this.pendingWrites=this.pendingWrites.then(()=>this.onData(r))})}startFile(e){if(this.currentFile)throw new Error("Must call endFile() before starting a new file.");if(this.finalized)throw new Error("ZIP has already been finalized.");let t=new $t(e);this.zip.add(t),this.currentFile=t}writeChunk(e){if(!this.currentFile)throw new Error("No file started. Call startFile() first.");this.currentFile.push(e,!1)}endFile(){if(!this.currentFile)throw new Error("No file to end.");this.currentFile.push(new Uint8Array(0),!0),this.currentFile=null}async finalize(){if(this.currentFile)throw new Error("Cannot finalize with an open file. Call endFile() first.");this.finalized||(this.finalized=!0,this.zip.end(),await this.pendingWrites)}};function ht(n){let e=String(n||"").toLowerCase();return e==="localhost"||e==="127.0.0.1"||e==="::1"}function xt(n,e){return!!e||ht(n||"")}function Ze(n){let e=n||je(),t="ABCDEFGHJKLMNPQRSTUVWXYZ";if(e){let s=new Uint8Array(8);e.getRandomValues(s);let a="";for(let o=0;o<4;o++)a+=t[s[o]%t.length];let l="";for(let o=4;o<8;o++)l+=(s[o]%10).toString();return`${a}-${l}`}let r="";for(let s=0;s<4;s++)r+=t[Math.floor(Math.random()*t.length)];let i="";for(let s=0;s<4;s++)i+=Math.floor(Math.random()*10);return`${r}-${i}`}function Ye(n){return/^[A-Z]{4}-\d{4}$/.test(String(n||"").trim())}function Ue(n,e){return{path:n.peerjsPath??e?.peerjsPath??"/peerjs",iceServers:n.iceServers??e?.iceServers??[]}}function dt(n={}){let{host:e,port:t,peerjsPath:r="/peerjs",secure:i=!1,iceServers:s=[]}=n,a={host:e,path:r,secure:i,config:{iceServers:s},debug:0};return t&&(a.port=t),a}async function Kt(n){let{code:e,codeGenerator:t,maxAttempts:r,buildPeer:i,onCode:s}=n,a=e||t(),l=null,o=null;for(let c=0;c<r;c++){s?.(a,c);try{return l=await new Promise((h,B)=>{let p=i(a);p.on("open",()=>h(p)),p.on("error",d=>{try{p.destroy()}catch{}B(d)})}),{peer:l,code:a}}catch(h){o=h,a=t()}}throw o||new D("Could not establish PeerJS connection.")}function mt(n){if(!n||typeof n!="object")return!1;let e=n;return typeof e.t=="string"&&["hello","file_list","meta","ready","chunk","chunk_ack","file_end","file_end_ack","end","end_ack","ping","pong","error","cancelled","resume","resume_ack"].includes(e.t)}var Ht=64*1024,Gt=32,qt=15e3,Vt=3,Wt=100,Jt=2e3;var Fn=3e4;function In(){return crypto.randomUUID()}var zn={initializing:["listening","closed"],listening:["handshaking","closed","cancelled"],handshaking:["negotiating","closed","cancelled"],negotiating:["transferring","closed","cancelled"],transferring:["finishing","closed","cancelled"],finishing:["awaiting_ack","closed","cancelled"],awaiting_ack:["completed","closed","cancelled"],completed:["closed"],cancelled:["closed"],closed:[]};async function Zt(n){let{file:e,Peer:t,serverInfo:r,host:i,port:s,peerjsPath:a,secure:l=!1,iceServers:o,codeGenerator:c,cryptoObj:h,maxAttempts:B=4,chunkSize:p=Ht,endAckTimeoutMs:d=qt,bufferHighWaterMark:w=8*1024*1024,bufferLowWaterMark:v=2*1024*1024,heartbeatIntervalMs:b=5e3,chunkAcknowledgments:u=!0,maxUnackedChunks:E=Gt,onCode:g,onStatus:f,onProgress:C,onComplete:S,onError:A,onDisconnect:z,onCancel:F,onConnectionHealth:M}=n,m=Array.isArray(e)?e:[e],T=m.length>1,R=m.reduce((x,$)=>x+$.size,0);if(!m.length)throw new y("At least one file is required.");if(!t)throw new y("PeerJS Peer constructor is required. Install peerjs and pass it as the Peer option.");let Z=r?.capabilities?.p2p;if(r&&!Z?.enabled)throw new y("Direct transfer is disabled on this server.");let{path:oe,iceServers:me}=Ue({peerjsPath:a,iceServers:o},Z),be=dt({host:i,port:s,peerjsPath:oe,secure:l,iceServers:me}),Ae=c||(()=>Ze(h)),K=x=>new t(x,be),{peer:H,code:Me}=await Kt({code:null,codeGenerator:Ae,maxAttempts:B,buildPeer:K,onCode:g}),ge=In(),I="listening",Q=null,fe=0,ee=null,ae=null,pe=Date.now(),le=new Map,P=0,Y=[],G=!1,q=[],re=10,se=1e4,k=x=>zn[I].includes(x)?(I=x,!0):(console.warn(`[P2P Send] Invalid state transition: ${I} -> ${x}`),!1),j=x=>{if(_())return;let $=Number.isFinite(x.total)&&x.total>0?x.total:R,de=Math.min(Number(x.received)||0,$||0),ye=$?de/$*100:0;C?.({processedBytes:de,totalBytes:$,percent:ye})},N=x=>{I==="closed"||I==="completed"||I==="cancelled"||(k("closed"),A?.(x),ie())},ve=()=>{I!=="awaiting_ack"&&I!=="finishing"||(k("completed"),S?.(),ie())},ie=()=>{ee&&(clearInterval(ee),ee=null),ae&&(clearInterval(ae),ae=null),Y.forEach(x=>x()),Y=[],le.clear(),typeof window<"u"&&window.removeEventListener("beforeunload",U);try{Q?.close()}catch{}try{H.destroy()}catch{}},U=()=>{try{Q?.send({t:"error",message:"Sender closed the connection."})}catch{}V()};typeof window<"u"&&window.addEventListener("beforeunload",U);let V=()=>{if(I==="closed"||I==="cancelled")return;if(I==="completed"){ie();return}let x=I==="transferring"||I==="finishing"||I==="awaiting_ack";k("cancelled");try{Q&&Q.open&&Q.send({t:"cancelled",message:"Sender cancelled the transfer."})}catch{}x&&F&&F({cancelledBy:"sender"}),ie()},_=()=>I==="closed"||I==="cancelled",ke=x=>{M&&(ae=setInterval(()=>{if(_())return;let $=x._dc;if(!$)return;let de={iceConnectionState:$.readyState==="open"?"connected":"disconnected",bufferedAmount:$.bufferedAmount,lastActivityMs:Date.now()-pe};M(de)},2e3))},he=x=>{pe=Date.now(),le.delete(x.seq),j({received:x.received,total:R});let $=Y.shift();$&&$()},Oe=()=>new Promise(x=>{Y.push(x)}),Qt=async(x,$,de,ye)=>{if(u)for(;le.size>=E;){let De=Date.now();for(let[et,yt]of le)if(De-yt.sentAt>Fn)throw new D("Receiver stopped acknowledging chunks");if(await Promise.race([Oe(),Pe(1e3)]),_())return}let ze=P++;u&&le.set(ze,{offset:de,size:$.byteLength,sentAt:Date.now()}),x.send({t:"chunk",seq:ze,offset:de,size:$.byteLength,total:ye??R}),x.send($),fe+=$.byteLength;let xe=x._dc;if(xe&&w>0){for(;xe.bufferedAmount>w;)if(await new Promise(De=>{let et=setTimeout(De,60);try{xe.addEventListener("bufferedamountlow",()=>{clearTimeout(et),De()},{once:!0})}catch{}}),_())return}},en=async(x,$)=>{let de=d;for(let ye=0;ye<Vt;ye++){x.send({t:"end",attempt:ye});let ze=de*Math.pow(1.5,ye),xe=await Promise.race([$,Pe(ze).then(()=>null)]);if(xe&&xe.t==="end_ack")return xe;if(_())throw new D("Connection closed during completion.")}throw new D("Receiver did not confirm completion after retries.")};return H.on("connection",x=>{if(_())return;let $=Date.now();for(;q.length>0&&q[0]<$-se;)q.shift();if(q.length>=re){console.warn("[P2P Send] Connection rate limit exceeded, rejecting connection");try{x.send({t:"error",message:"Too many connection attempts. Please wait."})}catch{}try{x.close()}catch{}return}if(q.push($),Q){let W=Q.open!==!1;if(W&&I==="transferring"){try{x.send({t:"error",message:"Transfer already in progress."})}catch{}try{x.close()}catch{}return}else if(W){try{x.send({t:"error",message:"Another receiver is already connected."})}catch{}try{x.close()}catch{}return}else{try{Q.close()}catch{}if(Q=null,G){try{x.send({t:"error",message:"Transfer already started with another receiver. Cannot reconnect."})}catch{}try{x.close()}catch{}return}I="listening",fe=0,P=0,le.clear()}}Q=x,k("handshaking"),_()||f?.({phase:"connected",message:"Receiver connected."}),pe=Date.now();let de=null,ye=null,ze=null,xe=null,De=new Promise(W=>{de=W}),et=new Promise(W=>{ye=W}),yt=new Promise(W=>{ze=W});x.on("data",W=>{if(pe=Date.now(),W instanceof ArrayBuffer||ArrayBuffer.isView(W)||!mt(W))return;let Se=W;switch(Se.t){case"hello":de?.(Se.protocolVersion);break;case"ready":_()||f?.({phase:"transferring",message:"Receiver accepted. Starting transfer..."}),ye?.();break;case"chunk_ack":he(Se);break;case"file_end_ack":xe?.(Se);break;case"end_ack":ze?.(Se);break;case"pong":break;case"error":N(new D(Se.message||"Receiver reported an error."));break;case"cancelled":if(I==="cancelled"||I==="closed"||I==="completed")return;k("cancelled"),F?.({cancelledBy:"receiver",message:Se.reason}),ie();break}}),x.on("open",async()=>{try{if(_())return;ke(x),x.send({t:"hello",protocolVersion:3,sessionId:ge});let W=await Promise.race([De,Pe(1e4).then(()=>null)]);if(_())return;if(W===null)throw new D("Receiver did not respond to handshake.");if(W!==3)throw new D(`Protocol version mismatch: sender v${3}, receiver v${W}`);k("negotiating"),_()||f?.({phase:"waiting",message:"Connected. Waiting for receiver to accept..."}),T&&x.send({t:"file_list",fileCount:m.length,files:m.map(we=>({name:we.name,size:we.size,mime:we.type||"application/octet-stream"})),totalSize:R}),x.send({t:"meta",sessionId:ge,name:m[0].name,size:m[0].size,mime:m[0].type||"application/octet-stream",...T?{fileIndex:0}:{}});let Se=x._dc;if(Se&&Number.isFinite(v))try{Se.bufferedAmountLowThreshold=v}catch{}if(await et,_())return;b>0&&(ee=setInterval(()=>{if(I==="transferring"||I==="finishing"||I==="awaiting_ack")try{x.send({t:"ping",timestamp:Date.now()})}catch{}},b)),k("transferring"),G=!0;let St=0;for(let we=0;we<m.length;we++){let _e=m[we];T&&we>0&&x.send({t:"meta",sessionId:ge,name:_e.name,size:_e.size,mime:_e.type||"application/octet-stream",fileIndex:we});for(let Te=0;Te<_e.size;Te+=p){if(_())return;let nt=await _e.slice(Te,Te+p).arrayBuffer();if(_())return;await Qt(x,nt,Te,_e.size),St+=nt.byteLength,j({received:St,total:R})}if(_())return;if(T){let Te=new Promise(nt=>{xe=nt});x.send({t:"file_end",fileIndex:we});let Mt=await Promise.race([Te,Pe(d).then(()=>null)]);if(_())return;if(!Mt)throw new D(`Receiver did not confirm receipt of file ${we+1}/${m.length}.`)}}if(_())return;k("finishing"),k("awaiting_ack");let Ct=await en(x,yt);if(_())return;let tt=Number(Ct.total)||R,At=Number(Ct.received)||0;if(tt&&At<tt)throw new D("Receiver reported an incomplete transfer.");j({received:At||tt,total:tt}),ve()}catch(W){N(W)}}),x.on("error",W=>{N(W)}),x.on("close",()=>{if(I==="closed"||I==="completed"||I==="cancelled"){ie();return}if(I==="awaiting_ack"){setTimeout(()=>{I==="awaiting_ack"&&N(new D("Connection closed while awaiting confirmation."))},Jt);return}I==="transferring"||I==="finishing"?(k("cancelled"),F?.({cancelledBy:"receiver"}),ie()):(Q=null,I="listening",fe=0,P=0,le.clear(),z?.())})}),{peer:H,code:Me,sessionId:ge,stop:V,getStatus:()=>I,getBytesSent:()=>fe,getConnectedPeerId:()=>Q&&Q.peer||null}}var Tn={initializing:["connecting","closed"],connecting:["handshaking","closed","cancelled"],handshaking:["negotiating","closed","cancelled"],negotiating:["transferring","closed","cancelled"],transferring:["completed","closed","cancelled"],completed:["closed"],cancelled:["closed"],closed:[]};async function Yt(n){let{code:e,Peer:t,serverInfo:r,host:i,port:s,peerjsPath:a,secure:l=!1,iceServers:o,autoReady:c=!0,watchdogTimeoutMs:h=15e3,onStatus:B,onMeta:p,onData:d,onProgress:w,onFileStart:v,onFileEnd:b,onComplete:u,onError:E,onDisconnect:g,onCancel:f}=n;if(!e)throw new y("No sharing code was provided.");if(!t)throw new y("PeerJS Peer constructor is required. Install peerjs and pass it as the Peer option.");let C=r?.capabilities?.p2p;if(r&&!C?.enabled)throw new y("Direct transfer is disabled on this server.");let S=String(e).trim().replace(/\s+/g,"").toUpperCase();if(!Ye(S))throw new y("Invalid direct transfer code.");let{path:A,iceServers:z}=Ue({peerjsPath:a,iceServers:o},C),F=dt({host:i,port:s,peerjsPath:A,secure:l,iceServers:z}),M=new t(void 0,F),m="initializing",T=0,R=0,Z=null,oe=Promise.resolve(),me=null,be=null,Ae=null,K=null,H=0,Me=0,ge=0,I=0,Q=100,fe=1e4,ee=k=>Tn[m].includes(k)?(m=k,!0):(console.warn(`[P2P Receive] Invalid state transition: ${m} -> ${k}`),!1),ae=()=>m==="closed"||m==="cancelled",pe=()=>{h<=0||(me&&clearTimeout(me),me=setTimeout(()=>{m==="transferring"&&P(new D("Connection timed out (no data received)."))},h))},le=()=>{me&&(clearTimeout(me),me=null)},P=k=>{m==="closed"||m==="completed"||m==="cancelled"||(ee("closed"),E?.(k),G())},Y=k=>{m==="transferring"&&(ee("completed"),u?.(k))},G=()=>{le(),typeof window<"u"&&window.removeEventListener("beforeunload",q);try{M.destroy()}catch{}},q=()=>{try{be?.send({t:"error",message:"Receiver closed the connection."})}catch{}re()};typeof window<"u"&&window.addEventListener("beforeunload",q);let re=()=>{if(m==="closed"||m==="cancelled")return;if(m==="completed"){G();return}let k=m==="transferring";ee("cancelled");try{be&&be.open&&be.send({t:"cancelled",reason:"Receiver cancelled the transfer."})}catch{}k&&f&&f({cancelledBy:"receiver"}),G()},se=(k,j)=>{try{k.send({t:"chunk_ack",seq:j,received:R})}catch{}};return M.on("error",k=>{P(k)}),M.on("open",()=>{ee("connecting");let k=M.connect(S,{reliable:!0});be=k,k.on("open",()=>{ee("handshaking"),B?.({phase:"connected",message:"Connected."}),k.send({t:"hello",protocolVersion:3,sessionId:""})}),k.on("data",async j=>{try{if(j instanceof ArrayBuffer||ArrayBuffer.isView(j)||typeof Blob<"u"&&j instanceof Blob){if(m!=="transferring")throw new y("Received binary data before transfer was accepted. Possible malicious sender.");if(pe(),I>=Q)throw new D("Write queue overflow - receiver cannot keep up");let ve;if(j instanceof ArrayBuffer)ve=Promise.resolve(new Uint8Array(j));else if(ArrayBuffer.isView(j))ve=Promise.resolve(new Uint8Array(j.buffer,j.byteOffset,j.byteLength));else if(typeof Blob<"u"&&j instanceof Blob)ve=j.arrayBuffer().then(V=>new Uint8Array(V));else return;let ie=Ae?.seq??-1,U=Ae?.size;Ae=null,I++,oe=oe.then(async()=>{let V=await ve;if(U!==void 0&&V.byteLength!==U)throw new y(`Chunk size mismatch: expected ${U}, got ${V.byteLength}`);let _=R+V.byteLength;if(T>0&&_>T)throw new y(`Received more data than expected: ${_} > ${T}`);d&&await d(V),R+=V.byteLength,H+=V.byteLength;let ke=K?Me+H:R,he=K?K.totalSize:T,Oe=he?Math.min(100,ke/he*100):0;ae()||w?.({processedBytes:ke,totalBytes:he,percent:Oe}),ie>=0&&se(k,ie)}).catch(V=>{try{k.send({t:"error",message:V?.message||"Receiver write failed."})}catch{}P(V)}).finally(()=>{I--});return}if(!mt(j))return;let N=j;switch(N.t){case"hello":Z=N.sessionId||null,ee("negotiating"),B?.({phase:"waiting",message:"Waiting for file details..."});break;case"file_list":{let U=N;if(U.fileCount>fe)throw new y(`Too many files: ${U.fileCount}`);let V=U.files.reduce((_,ke)=>_+ke.size,0);if(V!==U.totalSize)throw new y(`File list size mismatch: declared ${U.totalSize}, actual sum ${V}`);K=U,T=U.totalSize;break}case"meta":{if(m!=="negotiating"&&!(m==="transferring"&&K))return;if(Z&&N.sessionId&&N.sessionId!==Z){try{k.send({t:"error",message:"Busy with another session."})}catch{}return}N.sessionId&&(Z=N.sessionId);let U=String(N.name||"file"),V=Number(N.size)||0,_=N.fileIndex;if(K&&typeof _=="number"&&_>0){H=0,v?.({fileIndex:_,name:U,size:V});break}R=0,H=0,Me=0,K||(T=V),oe=Promise.resolve();let ke=()=>{ee("transferring"),pe(),K&&v?.({fileIndex:0,name:U,size:V});try{k.send({t:"ready"})}catch{}},he={name:U,total:T};K&&(he.fileCount=K.fileCount,he.files=K.files.map(Oe=>({name:Oe.name,size:Oe.size})),he.totalSize=K.totalSize),c?(ae()||(p?.(he),w?.({processedBytes:R,totalBytes:T,percent:0})),ke()):(he.sendReady=ke,ae()||(p?.(he),w?.({processedBytes:R,totalBytes:T,percent:0})));break}case"chunk":{let U=N;if(m!=="transferring")throw new y("Received chunk message before transfer was accepted.");if(U.seq!==ge)throw new y(`Chunk sequence error: expected ${ge}, got ${U.seq}`);ge++,Ae=U;break}case"ping":try{k.send({t:"pong",timestamp:Date.now()})}catch{}break;case"file_end":{le(),await oe;let U=N.fileIndex;b?.({fileIndex:U,receivedBytes:H});try{k.send({t:"file_end_ack",fileIndex:U,received:H,size:H})}catch{}Me+=H,H=0,pe();break}case"end":le(),await oe;let ve=K?Me+H:R,ie=K?K.totalSize:T;if(ie&&ve<ie){let U=new D("Transfer ended before all data was received.");try{k.send({t:"error",message:U.message})}catch{}throw U}try{k.send({t:"end_ack",received:ve,total:ie})}catch{}Y({received:ve,total:ie}),(async()=>{for(let U=0;U<2;U++){await Pe(Wt);try{k.send({t:"end_ack",received:ve,total:ie})}catch{break}}})().catch(()=>{});break;case"error":throw new D(N.message||"Sender reported an error.");case"cancelled":if(m==="cancelled"||m==="closed"||m==="completed")return;ee("cancelled"),f?.({cancelledBy:"sender",message:N.reason}),G();break}}catch(N){P(N)}}),k.on("close",()=>{if(m==="closed"||m==="completed"||m==="cancelled"){G();return}m==="transferring"?(ee("cancelled"),f?.({cancelledBy:"sender"}),G()):m==="negotiating"?(ee("closed"),G(),g?.()):P(new D("Sender disconnected before file details were received."))})}),{peer:M,stop:re,getStatus:()=>m,getBytesReceived:()=>R,getTotalBytes:()=>T,getSessionId:()=>Z}}function Xt(n){return typeof n=="string"?Je(ot(n)):Je(n)}function Qe(n,e,t){let r=Number(n)||0;return t?r+(Number(e)||0)*28:r}async function gt(n){let{server:e,timeoutMs:t=5e3,signal:r,fetchFn:i}=n,s=i||Ve();if(!s)throw new y("No fetch() implementation found.");let a=Xt(e);try{let{res:l,json:o}=await ce(s,`${a}/api/info`,{method:"GET",timeoutMs:t,signal:r,headers:{Accept:"application/json"}});if(l.ok&&o&&typeof o=="object"&&"version"in o)return{baseUrl:a,serverInfo:o};throw new L(`Server info request failed (status ${l.status}).`)}catch(l){throw l instanceof X?l:new D("Could not reach server /api/info.",{cause:l})}}var vt=class{constructor(e){te(this,"clientVersion");te(this,"chunkSize");te(this,"fetchFn");te(this,"cryptoObj");te(this,"base64");te(this,"baseUrl");te(this,"_fallbackToHttp");te(this,"_compat",null);te(this,"_connectPromise",null);if(!e||typeof e.clientVersion!="string")throw new y("DropgateClient requires clientVersion (string).");if(!e.server)throw new y("DropgateClient requires server (URL string or ServerTarget object).");this.clientVersion=e.clientVersion,this.chunkSize=Number.isFinite(e.chunkSize)?e.chunkSize:5242880;let t=e.fetchFn||Ve();if(!t)throw new y("No fetch() implementation found.");this.fetchFn=t;let r=e.cryptoObj||je();if(!r)throw new y("No crypto implementation found.");this.cryptoObj=r,this.base64=e.base64||Be(),this._fallbackToHttp=!!e.fallbackToHttp,this.baseUrl=Xt(e.server)}get serverTarget(){let e=new URL(this.baseUrl);return{host:e.hostname,port:e.port?Number(e.port):void 0,secure:e.protocol==="https:"}}async connect(e){return this._compat?this._compat:(this._connectPromise||(this._connectPromise=this._fetchAndCheckCompat(e).finally(()=>{this._connectPromise=null})),this._connectPromise)}async _fetchAndCheckCompat(e){let{timeoutMs:t=5e3,signal:r}=e??{},i=this.baseUrl,s;try{let l=await gt({server:i,timeoutMs:t,signal:r,fetchFn:this.fetchFn});i=l.baseUrl,s=l.serverInfo}catch(l){if(this._fallbackToHttp&&this.baseUrl.startsWith("https://")){let o=this.baseUrl.replace("https://","http://");try{let c=await gt({server:o,timeoutMs:t,signal:r,fetchFn:this.fetchFn});this.baseUrl=o,i=c.baseUrl,s=c.serverInfo}catch{throw l instanceof X?l:new D("Could not connect to the server.",{cause:l})}}else throw l instanceof X?l:new D("Could not connect to the server.",{cause:l})}let a=this._checkVersionCompat(s);return this._compat={...a,serverInfo:s,baseUrl:i},this._compat}_checkVersionCompat(e){let t=String(e?.version||"0.0.0"),r=String(this.clientVersion||"0.0.0"),i=We(r),s=We(t);return i.major!==s.major?{compatible:!1,clientVersion:r,serverVersion:t,message:`Incompatible versions. Client v${r}, Server v${t}${e?.name?` (${e.name})`:""}.`}:i.minor>s.minor?{compatible:!0,clientVersion:r,serverVersion:t,message:`Client (v${r}) is newer than Server (v${t})${e?.name?` (${e.name})`:""}. Some features may not work.`}:{compatible:!0,clientVersion:r,serverVersion:t,message:`Server: v${t}, Client: v${r}${e?.name?` (${e.name})`:""}.`}}async resolveShareTarget(e,t){let{timeoutMs:r=5e3,signal:i}=t??{},s=await this.connect(t);if(!s.compatible)throw new y(s.message);let{baseUrl:a}=s,{res:l,json:o}=await ce(this.fetchFn,`${a}/api/resolve`,{method:"POST",timeoutMs:r,signal:i,headers:{"Content-Type":"application/json",Accept:"application/json"},body:JSON.stringify({value:e})});if(!l.ok){let c=(o&&typeof o=="object"&&"error"in o?o.error:null)||`Share lookup failed (status ${l.status}).`;throw new L(c,{details:o})}return o||{valid:!1,reason:"Unknown response."}}async getFileMetadata(e,t){if(!e||typeof e!="string")throw new y("File ID is required.");let{timeoutMs:r=5e3,signal:i}=t??{},s=`${this.baseUrl}/api/file/${encodeURIComponent(e)}/meta`,{res:a,json:l}=await ce(this.fetchFn,s,{method:"GET",timeoutMs:r,signal:i});if(!a.ok){let o=(l&&typeof l=="object"&&"error"in l?l.error:null)||`Failed to fetch file metadata (status ${a.status}).`;throw new L(o,{details:l})}return l}async getBundleMetadata(e,t,r){if(!e||typeof e!="string")throw new y("Bundle ID is required.");let{timeoutMs:i=5e3,signal:s}=r??{},a=`${this.baseUrl}/api/bundle/${encodeURIComponent(e)}/meta`,{res:l,json:o}=await ce(this.fetchFn,a,{method:"GET",timeoutMs:i,signal:s});if(!l.ok){let d=(o&&typeof o=="object"&&"error"in o?o.error:null)||`Failed to fetch bundle metadata (status ${l.status}).`;throw new L(d,{details:o})}let c=o,h=[];if(c.sealed&&c.encryptedManifest){if(!t)throw new y("Decryption key (keyB64) is required for encrypted sealed bundles.");let d=await Re(this.cryptoObj,t),w=this.base64.decode(c.encryptedManifest),v=await Ee(this.cryptoObj,w,d),b=new TextDecoder().decode(v);h=JSON.parse(b).files.map(E=>({fileId:E.fileId,sizeBytes:E.sizeBytes,filename:E.name}))}else if(c.files)h=c.files;else throw new L("Invalid bundle metadata: missing files or manifest.");let B=h.reduce((d,w)=>d+(w.sizeBytes||0),0),p=h.length;return{isEncrypted:c.isEncrypted,sealed:c.sealed,encryptedManifest:c.encryptedManifest,files:h,totalSizeBytes:B,fileCount:p}}validateUploadInputs(e){let{files:t,lifetimeMs:r,encrypt:i,serverInfo:s}=e,a=s?.capabilities?.upload;if(!a||!a.enabled)throw new y("Server does not support file uploads.");let l=Array.isArray(t)?t:[t];if(l.length===0)throw new y("At least one file is required.");for(let h=0;h<l.length;h++){let B=l[h],p=Number(B?.size||0);if(!B||!Number.isFinite(p)||p<=0)throw new y(`File at index ${h} is missing or invalid.`);let d=Number(a.maxSizeMB);if(Number.isFinite(d)&&d>0){let w=d*1e3*1e3,v=Number.isFinite(a.chunkSize)&&a.chunkSize>0?a.chunkSize:this.chunkSize,b=Math.ceil(p/v);if(Qe(p,b,!!i)>w){let E=i?`File at index ${h} too large once encryption overhead is included. Server limit: ${d} MB.`:`File at index ${h} too large. Server limit: ${d} MB.`;throw new y(E)}}}let o=Number(a.maxLifetimeHours),c=Number(r);if(!Number.isFinite(c)||c<0||!Number.isInteger(c))throw new y("Invalid lifetime. Must be a non-negative integer (milliseconds).");if(Number.isFinite(o)&&o>0){let h=Math.round(o*60*60*1e3);if(c===0)throw new y(`Server does not allow unlimited file lifetime. Max: ${o} hours.`);if(c>h)throw new y(`File lifetime too long. Server limit: ${o} hours.`)}if(i&&!a.e2ee)throw new y("End-to-end encryption is not supported on this server.");return!0}async uploadFiles(e){let{files:t,lifetimeMs:r,encrypt:i,maxDownloads:s,filenameOverrides:a,onProgress:l,onCancel:o,signal:c,timeouts:h={},retry:B={}}=e,p=Array.isArray(t)?t:[t];if(p.length===0)throw new y("At least one file is required.");let d=c?null:new AbortController,w=c||d?.signal,v="initializing",b=[],u=p.reduce((f,C)=>f+C.size,0),E=(async()=>{try{let f=P=>{try{l&&l(P)}catch{}};f({phase:"server-info",text:"Checking server...",percent:0,processedBytes:0,totalBytes:u});let C=await this.connect({timeoutMs:h.serverInfoMs??5e3,signal:w}),{baseUrl:S,serverInfo:A}=C;if(f({phase:"server-compat",text:C.message,percent:0,processedBytes:0,totalBytes:u}),!C.compatible)throw new y(C.message);let z=p.map((P,Y)=>a?.[Y]??P.name??"file"),F=!!A?.capabilities?.upload?.e2ee,M=i??F;if(!M)for(let P of z)st(P);this.validateUploadInputs({files:p,lifetimeMs:r,encrypt:M,serverInfo:A});let m=null,T=null,R=[];if(M){if(!this.cryptoObj?.subtle)throw new y("Web Crypto API not available (crypto.subtle). Encryption requires a secure context (HTTPS or localhost).");f({phase:"crypto",text:"Generating encryption key...",percent:0,processedBytes:0,totalBytes:u});try{m=await lt(this.cryptoObj),T=await ct(this.cryptoObj,m);for(let P of z)R.push(await ft(this.cryptoObj,P,m))}catch(P){throw new X("Failed to prepare encryption.",{code:"CRYPTO_PREP_FAILED",cause:P})}}else R.push(...z);let Z=A?.capabilities?.upload?.chunkSize,oe=Number.isFinite(Z)&&Z>0?Z:this.chunkSize,me=Number.isFinite(B.retries)?B.retries:5,be=Number.isFinite(B.backoffMs)?B.backoffMs:1e3,Ae=Number.isFinite(B.maxBackoffMs)?B.maxBackoffMs:3e4;if(p.length===1){let P=p[0],Y=Math.ceil(P.size/oe),G=Qe(P.size,Y,M);f({phase:"init",text:"Reserving server storage...",percent:0,processedBytes:0,totalBytes:P.size});let q=await ce(this.fetchFn,`${S}/upload/init`,{method:"POST",timeoutMs:h.initMs??15e3,signal:w,headers:{"Content-Type":"application/json",Accept:"application/json"},body:JSON.stringify({filename:R[0],lifetime:r,isEncrypted:M,totalSize:G,totalChunks:Y,...s!==void 0?{maxDownloads:s}:{}})});if(!q.res.ok){let N=q.json;throw new L(N?.error||`Server initialisation failed: ${q.res.status}`,{details:q.json||q.text})}let re=q.json?.uploadId;if(!re)throw new L("Server did not return a valid uploadId.");b.push(re),v="uploading",await this._uploadFileChunks({file:P,uploadId:re,cryptoKey:m,effectiveChunkSize:oe,totalChunks:Y,totalUploadSize:G,baseOffset:0,totalBytesAllFiles:P.size,progress:f,signal:w,baseUrl:S,retries:me,backoffMs:be,maxBackoffMs:Ae,chunkTimeoutMs:h.chunkMs??6e4}),f({phase:"complete",text:"Finalising upload...",percent:100,processedBytes:P.size,totalBytes:P.size}),v="completing";let se=await ce(this.fetchFn,`${S}/upload/complete`,{method:"POST",timeoutMs:h.completeMs??3e4,signal:w,headers:{"Content-Type":"application/json",Accept:"application/json"},body:JSON.stringify({uploadId:re})});if(!se.res.ok){let N=se.json;throw new L(N?.error||"Finalisation failed.",{details:se.json||se.text})}let k=se.json?.id;if(!k)throw new L("Server did not return a valid file id.");let j=`${S}/${k}`;return M&&T&&(j+=`#${T}`),f({phase:"done",text:"Upload successful!",percent:100,processedBytes:P.size,totalBytes:P.size}),v="completed",{downloadUrl:j,fileId:k,uploadId:re,baseUrl:S,...M&&T?{keyB64:T}:{}}}let K=p.map((P,Y)=>{let G=Math.ceil(P.size/oe),q=Qe(P.size,G,M);return{filename:R[Y],totalSize:q,totalChunks:G}});f({phase:"init",text:`Reserving server storage for ${p.length} files...`,percent:0,processedBytes:0,totalBytes:u,totalFiles:p.length});let H=await ce(this.fetchFn,`${S}/upload/init-bundle`,{method:"POST",timeoutMs:h.initMs??15e3,signal:w,headers:{"Content-Type":"application/json",Accept:"application/json"},body:JSON.stringify({fileCount:p.length,files:K,lifetime:r,isEncrypted:M,...s!==void 0?{maxDownloads:s}:{}})});if(!H.res.ok){let P=H.json;throw new L(P?.error||`Bundle initialisation failed: ${H.res.status}`,{details:H.json||H.text})}let Me=H.json,ge=Me?.bundleUploadId,I=Me?.fileUploadIds;if(!ge||!I||I.length!==p.length)throw new L("Server did not return valid bundle upload IDs.");b.push(...I),v="uploading";let Q=[],fe=0;for(let P=0;P<p.length;P++){let Y=p[P],G=I[P],q=K[P].totalChunks,re=K[P].totalSize;f({phase:"file-start",text:`Uploading file ${P+1} of ${p.length}: ${z[P]}`,percent:u>0?fe/u*100:0,processedBytes:fe,totalBytes:u,fileIndex:P,totalFiles:p.length,currentFileName:z[P]}),await this._uploadFileChunks({file:Y,uploadId:G,cryptoKey:m,effectiveChunkSize:oe,totalChunks:q,totalUploadSize:re,baseOffset:fe,totalBytesAllFiles:u,progress:f,signal:w,baseUrl:S,retries:me,backoffMs:be,maxBackoffMs:Ae,chunkTimeoutMs:h.chunkMs??6e4,fileIndex:P,totalFiles:p.length,currentFileName:z[P]});let se=await ce(this.fetchFn,`${S}/upload/complete`,{method:"POST",timeoutMs:h.completeMs??3e4,signal:w,headers:{"Content-Type":"application/json",Accept:"application/json"},body:JSON.stringify({uploadId:G})});if(!se.res.ok){let j=se.json;throw new L(j?.error||`File ${P+1} finalisation failed.`,{details:se.json||se.text})}let k=se.json?.id;if(!k)throw new L(`Server did not return a valid file id for file ${P+1}.`);Q.push({fileId:k,name:z[P],size:Y.size}),fe+=Y.size,f({phase:"file-complete",text:`File ${P+1} of ${p.length} uploaded.`,percent:u>0?fe/u*100:0,processedBytes:fe,totalBytes:u,fileIndex:P,totalFiles:p.length,currentFileName:z[P]})}f({phase:"complete",text:"Finalising bundle...",percent:100,processedBytes:u,totalBytes:u}),v="completing";let ee;if(M&&m){let P=JSON.stringify({files:Q.map(re=>({fileId:re.fileId,name:re.name,sizeBytes:re.size}))}),Y=new TextEncoder().encode(P),G=await He(this.cryptoObj,Y.buffer,m),q=new Uint8Array(await G.arrayBuffer());ee=this.base64.encode(q)}let ae=await ce(this.fetchFn,`${S}/upload/complete-bundle`,{method:"POST",timeoutMs:h.completeMs??3e4,signal:w,headers:{"Content-Type":"application/json",Accept:"application/json"},body:JSON.stringify({bundleUploadId:ge,...ee?{encryptedManifest:ee}:{}})});if(!ae.res.ok){let P=ae.json;throw new L(P?.error||"Bundle finalisation failed.",{details:ae.json||ae.text})}let pe=ae.json?.bundleId;if(!pe)throw new L("Server did not return a valid bundle id.");let le=`${S}/b/${pe}`;return M&&T&&(le+=`#${T}`),f({phase:"done",text:"Upload successful!",percent:100,processedBytes:u,totalBytes:u}),v="completed",{downloadUrl:le,bundleId:pe,baseUrl:S,files:Q,...M&&T?{keyB64:T}:{}}}catch(f){throw f instanceof Error&&(f.name==="AbortError"||f.message?.includes("abort"))?(v="cancelled",o?.()):v="error",f}})(),g=async f=>{try{await ce(this.fetchFn,`${this.baseUrl}/upload/cancel`,{method:"POST",timeoutMs:5e3,headers:{"Content-Type":"application/json",Accept:"application/json"},body:JSON.stringify({uploadId:f})})}catch{}};return{result:E,cancel:f=>{if(!(v==="completed"||v==="cancelled")){v="cancelled";for(let C of b)g(C).catch(()=>{});d?.abort(new ne(f||"Upload cancelled by user."))}},getStatus:()=>v}}async _uploadFileChunks(e){let{file:t,uploadId:r,cryptoKey:i,effectiveChunkSize:s,totalChunks:a,baseOffset:l,totalBytesAllFiles:o,progress:c,signal:h,baseUrl:B,retries:p,backoffMs:d,maxBackoffMs:w,chunkTimeoutMs:v,fileIndex:b,totalFiles:u,currentFileName:E}=e;for(let g=0;g<a;g++){if(h?.aborted)throw h.reason||new ne;let f=g*s,C=Math.min(f+s,t.size),S=t.slice(f,C),A=l+f,z=o>0?A/o*100:0;c({phase:"chunk",text:`Uploading chunk ${g+1} of ${a}...`,percent:z,processedBytes:A,totalBytes:o,chunkIndex:g,totalChunks:a,...b!==void 0?{fileIndex:b,totalFiles:u,currentFileName:E}:{}});let F=await S.arrayBuffer(),M;if(i?M=await He(this.cryptoObj,F,i):M=new Blob([F]),M.size>s+1024)throw new y("Chunk too large (client-side). Check chunk size settings.");let m=await M.arrayBuffer(),T=await at(this.cryptoObj,m);await this._attemptChunkUpload(`${B}/upload/chunk`,{method:"POST",headers:{"Content-Type":"application/octet-stream","X-Upload-ID":r,"X-Chunk-Index":String(g),"X-Chunk-Hash":T},body:M},{retries:p,backoffMs:d,maxBackoffMs:w,timeoutMs:v,signal:h,progress:c,chunkIndex:g,totalChunks:a,chunkSize:s,fileSizeBytes:o})}}async downloadFiles(e){let{fileId:t,bundleId:r,keyB64:i,asZip:s,zipFilename:a,onProgress:l,onData:o,onFileStart:c,onFileData:h,onFileEnd:B,signal:p,timeoutMs:d=6e4}=e,w=A=>{try{l&&l(A)}catch{}};if(!t&&!r)throw new y("Either fileId or bundleId is required.");w({phase:"server-info",text:"Checking server...",processedBytes:0,totalBytes:0,percent:0});let v=await this.connect({timeoutMs:d,signal:p}),{baseUrl:b}=v;if(w({phase:"server-compat",text:v.message,processedBytes:0,totalBytes:0,percent:0}),!v.compatible)throw new y(v.message);if(t)return this._downloadSingleFile({fileId:t,keyB64:i,onProgress:l,onData:o,signal:p,timeoutMs:d,baseUrl:b,compat:v});w({phase:"metadata",text:"Fetching bundle info...",processedBytes:0,totalBytes:0,percent:0});let u;try{u=await this.getBundleMetadata(r,i,{timeoutMs:d,signal:p})}catch(A){throw A instanceof X?A:A instanceof Error&&A.name==="AbortError"?new ne("Download cancelled."):new D("Could not fetch bundle metadata.",{cause:A})}let E=!!u.isEncrypted,g=u.totalSizeBytes||0,f,C=[];if(E){if(!i)throw new y("Decryption key is required for encrypted bundles.");if(!this.cryptoObj?.subtle)throw new y("Web Crypto API not available for decryption.");try{if(f=await Re(this.cryptoObj,i,this.base64),u.sealed&&u.encryptedManifest){let A=this.base64.decode(u.encryptedManifest),z=await Ee(this.cryptoObj,A,f),F=new TextDecoder().decode(z),M=JSON.parse(F);u.files=M.files.map(m=>({fileId:m.fileId,sizeBytes:m.sizeBytes,filename:m.name})),u.fileCount=u.files.length;for(let m of u.files)C.push(m.filename||"file")}else for(let A of u.files)C.push(await Ke(this.cryptoObj,A.encryptedFilename,f,this.base64))}catch(A){throw new X("Failed to decrypt bundle manifest.",{code:"DECRYPT_MANIFEST_FAILED",cause:A})}}else for(let A of u.files)C.push(A.filename||"file");let S=0;if(s&&o){let A=new Ge(o);for(let z=0;z<u.files.length;z++){let F=u.files[z],M=C[z];w({phase:"zipping",text:`Downloading ${M}...`,percent:g>0?S/g*100:0,processedBytes:S,totalBytes:g,fileIndex:z,totalFiles:u.files.length,currentFileName:M}),A.startFile(M);let m=S,T=await this._streamFileIntoCallback(b,F.fileId,E,f,v,p,d,R=>{A.writeChunk(R)},R=>{let Z=m+R;w({phase:"zipping",text:`Downloading ${M}...`,percent:g>0?Z/g*100:0,processedBytes:Z,totalBytes:g,fileIndex:z,totalFiles:u.files.length,currentFileName:M})});A.endFile(),S+=T}await A.finalize();try{await ce(this.fetchFn,`${b}/api/bundle/${r}/downloaded`,{method:"POST",timeoutMs:5e3,headers:{"Content-Type":"application/json",Accept:"application/json"},body:"{}"})}catch{}return w({phase:"complete",text:"Download complete!",percent:100,processedBytes:S,totalBytes:g}),{filenames:C,receivedBytes:S,wasEncrypted:E}}else{let A=h||o;for(let z=0;z<u.files.length;z++){let F=u.files[z],M=C[z];w({phase:"downloading",text:`Downloading ${M}...`,percent:g>0?S/g*100:0,processedBytes:S,totalBytes:g,fileIndex:z,totalFiles:u.files.length,currentFileName:M}),c?.({name:M,size:F.sizeBytes,index:z});let m=S,T=await this._streamFileIntoCallback(b,F.fileId,E,f,v,p,d,A?R=>A(R):void 0,R=>{let Z=m+R;w({phase:"downloading",text:`Downloading ${M}...`,percent:g>0?Z/g*100:0,processedBytes:Z,totalBytes:g,fileIndex:z,totalFiles:u.files.length,currentFileName:M})});B?.({name:M,index:z}),S+=T}return w({phase:"complete",text:"Download complete!",percent:100,processedBytes:S,totalBytes:g}),{filenames:C,receivedBytes:S,wasEncrypted:E}}}async _downloadSingleFile(e){let{fileId:t,keyB64:r,onProgress:i,onData:s,signal:a,timeoutMs:l,baseUrl:o,compat:c}=e,h=f=>{try{i&&i(f)}catch{}};h({phase:"metadata",text:"Fetching file info...",processedBytes:0,totalBytes:0,percent:0});let B;try{B=await this.getFileMetadata(t,{timeoutMs:l,signal:a})}catch(f){throw f instanceof X?f:f instanceof Error&&f.name==="AbortError"?new ne("Download cancelled."):new D("Could not fetch file metadata.",{cause:f})}let p=!!B.isEncrypted,d=B.sizeBytes||0;if(!s&&d>104857600){let f=Math.round(d/1048576),C=Math.round(104857600/(1024*1024));throw new y(`File is too large (${f}MB) to download without streaming. Provide an onData callback to stream files larger than ${C}MB.`)}let w,v;if(p){if(!r)throw new y("Decryption key is required for encrypted files.");if(!this.cryptoObj?.subtle)throw new y("Web Crypto API not available for decryption.");h({phase:"decrypting",text:"Preparing decryption...",processedBytes:0,totalBytes:0,percent:0});try{v=await Re(this.cryptoObj,r,this.base64),w=await Ke(this.cryptoObj,B.encryptedFilename,v,this.base64)}catch(f){throw new X("Failed to decrypt filename.",{code:"DECRYPT_FILENAME_FAILED",cause:f})}}else w=B.filename||"file";h({phase:"downloading",text:"Starting download...",percent:0,processedBytes:0,totalBytes:d});let b=[],u=!s,E=await this._streamFileIntoCallback(o,t,p,v,c,a,l,async f=>{u?b.push(f):await s(f)},f=>{h({phase:"downloading",text:"Downloading...",percent:d>0?f/d*100:0,processedBytes:f,totalBytes:d})});h({phase:"complete",text:"Download complete!",percent:100,processedBytes:E,totalBytes:d});let g;if(u&&b.length>0){let f=b.reduce((S,A)=>S+A.length,0);g=new Uint8Array(f);let C=0;for(let S of b)g.set(S,C),C+=S.length}return{filename:w,receivedBytes:E,wasEncrypted:p,...g?{data:g}:{}}}async _streamFileIntoCallback(e,t,r,i,s,a,l,o,c){let{signal:h,cleanup:B}=Le(a,l),p=0;try{let d=await this.fetchFn(`${e}/api/file/${t}`,{method:"GET",signal:h});if(!d.ok)throw new L(`Download failed (status ${d.status}).`);if(!d.body)throw new L("Streaming response not available.");let w=d.body.getReader();if(r&&i){let b=(Number.isFinite(s.serverInfo?.capabilities?.upload?.chunkSize)&&s.serverInfo.capabilities.upload.chunkSize>0?s.serverInfo.capabilities.upload.chunkSize:this.chunkSize)+28,u=[],E=0,g=()=>{if(u.length===0)return new Uint8Array(0);if(u.length===1){let S=u[0];return u.length=0,E=0,S}let f=new Uint8Array(E),C=0;for(let S of u)f.set(S,C),C+=S.length;return u.length=0,E=0,f};for(;;){if(a?.aborted)throw new ne("Download cancelled.");let{done:f,value:C}=await w.read();if(f)break;for(u.push(C),E+=C.length,p+=C.length,c&&c(p);E>=b;){let S=g(),A=S.subarray(0,b);S.length>b&&(u.push(S.subarray(b)),E=S.length-b);let z=await Ee(this.cryptoObj,A,i);o&&await o(new Uint8Array(z))}}if(E>0){let f=g(),C=await Ee(this.cryptoObj,f,i);o&&await o(new Uint8Array(C))}}else for(;;){if(a?.aborted)throw new ne("Download cancelled.");let{done:v,value:b}=await w.read();if(v)break;p+=b.length,c&&c(p),o&&await o(b)}}catch(d){throw d instanceof X?d:d instanceof Error&&d.name==="AbortError"?new ne("Download cancelled."):new D("Download failed.",{cause:d})}finally{B()}return p}async p2pSend(e){let t=await this.connect();if(!t.compatible)throw new y(t.message);let{serverInfo:r}=t,i=r?.capabilities?.p2p;if(!i?.enabled)throw new y("Direct transfer is disabled on this server.");let{host:s,port:a,secure:l}=this.serverTarget,{path:o,iceServers:c}=Ue({},i);return Zt({...e,host:s,port:a,secure:l,peerjsPath:o,iceServers:c,serverInfo:r,cryptoObj:this.cryptoObj})}async p2pReceive(e){let t=await this.connect();if(!t.compatible)throw new y(t.message);let{serverInfo:r}=t,i=r?.capabilities?.p2p;if(!i?.enabled)throw new y("Direct transfer is disabled on this server.");let{host:s,port:a,secure:l}=this.serverTarget,{path:o,iceServers:c}=Ue({},i);return Yt({...e,host:s,port:a,secure:l,peerjsPath:o,iceServers:c,serverInfo:r})}async _attemptChunkUpload(e,t,r){let{retries:i,backoffMs:s,maxBackoffMs:a,timeoutMs:l,signal:o,progress:c,chunkIndex:h,totalChunks:B,chunkSize:p,fileSizeBytes:d}=r,w=i,v=s,b=i;for(;;){if(o?.aborted)throw o.reason||new ne;let{signal:u,cleanup:E}=Le(o,l);try{let g=await this.fetchFn(e,{...t,signal:u});if(g.ok)return;let f=await g.text().catch(()=>"");throw new L(`Chunk ${h+1} failed (HTTP ${g.status}).`,{details:{status:g.status,bodySnippet:f.slice(0,120)}})}catch(g){if(E(),g instanceof Error&&(g.name==="AbortError"||g.code==="ABORT_ERR"))throw g;if(o?.aborted)throw o.reason||new ne;if(w<=0)throw g instanceof X?g:new D("Chunk upload failed.",{cause:g});let f=b-w+1,C=h*p,S=h/B*100,A=v,z=100;for(;A>0;){let F=(A/1e3).toFixed(1);c({phase:"retry-wait",text:`Chunk upload failed. Retrying in ${F}s... (${f}/${b})`,percent:S,processedBytes:C,totalBytes:d,chunkIndex:h,totalChunks:B}),await Pe(Math.min(z,A),o),A-=z}c({phase:"retry",text:`Chunk upload failed. Retrying now... (${f}/${b})`,percent:S,processedBytes:C,totalBytes:d,chunkIndex:h,totalChunks:B}),w-=1,v=Math.min(v*2,a);continue}finally{E()}}}};return cn(Un);})();
2
2
  if(typeof window!=="undefined"){window.DropgateCore=DropgateCore;}
3
3
  //# sourceMappingURL=index.browser.js.map