From 013318d258076cbc913a5f518dc395856c35d72b Mon Sep 17 00:00:00 2001 From: Leo <5376265+leoherzog@users.noreply.github.com> Date: Sat, 18 Jun 2022 02:27:57 +0000 Subject: [PATCH] Update Ubuntu Magnet Example --- bin/bundle.js | 4 ++-- bin/bundle.min.js | 2 +- src/parse.js | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/bin/bundle.js b/bin/bundle.js index 73e55b0..7c5a44c 100644 --- a/bin/bundle.js +++ b/bin/bundle.js @@ -62985,11 +62985,11 @@ function start() { // example buttons example1.addEventListener('click', function(event) { event.preventDefault(); - notyf.success('Parsing Ubuntu 20.04 Magnet URL'); + notyf.success('Parsing Ubuntu 22.04 Magnet URL'); source = 'magnet'; originalSourceIcon.innerHTML = ''; sourceTooltip.setContent('Currently loaded information sourced from Magnet URL'); - parse('magnet:?xt=urn:btih:9fc20b9e98ea98b4a35e6223041a5ef94ea27809&dn=ubuntu-20.04-desktop-amd64.iso&tr=https%3A%2F%2Ftorrent.ubuntu.com%2Fannounce&tr=https%3A%2F%2Fipv6.torrent.ubuntu.com%2Fannounce'); + parse('magnet:?xt=urn:btih:2c6b6858d61da9543d4231a71db4b1c9264b0685&dn=ubuntu-22.04-desktop-amd64.iso&tr=https%3A%2F%2Ftorrent.ubuntu.com%2Fannounce&tr=https%3A%2F%2Fipv6.torrent.ubuntu.com%2Fannounce'); }); example2.addEventListener('click', async function(event) { diff --git a/bin/bundle.min.js b/bin/bundle.min.js index 96db892..ff50409 100644 --- a/bin/bundle.min.js +++ b/bin/bundle.min.js @@ -107,4 +107,4 @@ const i=16384;class n{constructor(e){this.length=e,this.missing=e,this.sources=n /*! ut_metadata. MIT License. WebTorrent LLC */ const{EventEmitter:n}=e("events"),r=e("bencode"),s=e("bitfield").default,a=e("debug")("ut_metadata"),o=e("simple-sha1"),c=16384;t.exports=e=>{class t extends n{constructor(t){super(),this._wire=t,this._fetching=!1,this._metadataComplete=!1,this._metadataSize=null,this._remainingRejects=null,this._bitfield=new s(0,{grow:1e3}),i.isBuffer(e)&&this.setMetadata(e)}onHandshake(e,t,i){this._infoHash=e}onExtendedHandshake(e){return e.m&&e.m.ut_metadata?e.metadata_size?"number"!=typeof e.metadata_size||1e7this._metadataSize&&(i=this._metadataSize);const n=this.metadata.slice(t,i);this._data(e,n,this._metadataSize)}_onData(e,t,i){t.length>c||!this._fetching||(t.copy(this.metadata,e*c),this._bitfield.set(e),this._checkDone())}_onReject(e){this._remainingRejects>0&&this._fetching?(this._request(e),this._remainingRejects-=1):this.emit("warning",new Error('Peer sent "reject" too much'))}_requestPieces(){if(this._fetching){this.metadata=i.alloc(this._metadataSize);for(let e=0;e0?this._requestPieces():this.emit("warning",new Error("Peer sent invalid metadata"))}}return t.prototype.name="ut_metadata",t}}).call(this)}).call(this,e("buffer").Buffer)},{bencode:22,bitfield:26,buffer:109,debug:160,events:192,"simple-sha1":410}],485:[function(e,t,i){(function(e){(function(){function i(t){try{if(!e.localStorage)return!1}catch(e){return!1}var i=e.localStorage[t];return null!=i&&"true"===String(i).toLowerCase()}t.exports=function(e,t){if(i("noDeprecation"))return e;var n=!1;return function(){if(!n){if(i("throwDeprecation"))throw new Error(t);i("traceDeprecation")?console.trace(t):console.warn(t),n=!0}return e.apply(this,arguments)}}}).call(this)}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}],486:[function(e,t,i){(function(i){(function(){const n=e("binary-search"),r=e("events"),s=e("mp4-stream"),a=e("mp4-box-encoding"),o=e("range-slice-stream");class c{constructor(e,t){this._entries=e,this._countName=t||"count",this._index=0,this._offset=0,this.value=this._entries[0]}inc(){this._offset++,this._offset>=this._entries[this._index][this._countName]&&(this._index++,this._offset=0),this.value=this._entries[this._index]}}const l=1;t.exports=class extends r{constructor(e){super(),this._tracks=[],this._file=e,this._decoder=null,this._findMoov(0)}_findMoov(e){this._decoder&&this._decoder.destroy();let t=0;this._decoder=s.decode();const i=this._file.createReadStream({start:e});i.pipe(this._decoder);const n=r=>{"moov"===r.type?(this._decoder.removeListener("box",n),this._decoder.decode((e=>{i.destroy();try{this._processMoov(e)}catch(e){e.message=`Cannot parse mp4 file: ${e.message}`,this.emit("error",e)}}))):r.length<4096?(t+=r.length,this._decoder.ignore()):(this._decoder.removeListener("box",n),t+=r.length,i.destroy(),this._decoder.destroy(),this._findMoov(e+t))};this._decoder.on("box",n)}_processMoov(e){const t=e.traks;this._tracks=[],this._hasVideo=!1,this._hasAudio=!1;for(let i=0;i=s.stsz.entries.length)break;if(f++,m+=e,f>=n.samplesPerChunk){f=0,m=0,h++;const e=s.stsc.entries[b+1];e&&h+1>=e.firstChunk&&b++}v+=t,g.inc(),y&&y.inc(),r&&_++}r.mdia.mdhd.duration=0,r.tkhd.duration=0;const x=n.sampleDescriptionId,w={type:"moov",mvhd:e.mvhd,traks:[{tkhd:r.tkhd,mdia:{mdhd:r.mdia.mdhd,hdlr:r.mdia.hdlr,elng:r.mdia.elng,minf:{vmhd:r.mdia.minf.vmhd,smhd:r.mdia.minf.smhd,dinf:r.mdia.minf.dinf,stbl:{stsd:s.stsd,stts:{version:0,flags:0,entries:[]},ctts:{version:0,flags:0,entries:[]},stsc:{version:0,flags:0,entries:[]},stsz:{version:0,flags:0,entries:[]},stco:{version:0,flags:0,entries:[]},stss:{version:0,flags:0,entries:[]}}}}}],mvex:{mehd:{fragmentDuration:e.mvhd.duration},trexs:[{trackId:r.tkhd.trackId,defaultSampleDescriptionIndex:x,defaultSampleDuration:0,defaultSampleSize:0,defaultSampleFlags:0}]}};this._tracks.push({fragmentSequence:1,trackId:r.tkhd.trackId,timeScale:r.mdia.mdhd.timeScale,samples:p,currSample:null,currTime:null,moov:w,mime:u})}if(0===this._tracks.length)return void this.emit("error",new Error("no playable tracks"));e.mvhd.duration=0,this._ftyp={type:"ftyp",brand:"iso5",brandVersion:0,compatibleBrands:["iso5"]};const r=a.encode(this._ftyp),s=this._tracks.map((e=>{const t=a.encode(e.moov);return{mime:e.mime,init:i.concat([r,t])}}));this.emit("ready",s)}seek(e){if(!this._tracks)throw new Error("Not ready yet; wait for 'ready' event");this._fileStream&&(this._fileStream.destroy(),this._fileStream=null);let t=-1;if(this._tracks.map(((i,n)=>{i.outStream&&i.outStream.destroy(),i.inStream&&(i.inStream.destroy(),i.inStream=null);const r=i.outStream=s.encode(),a=this._generateFragment(n,e);if(!a)return r.finalize();(-1===t||a.ranges[0].start{r.destroyed||r.box(e.moof,(t=>{if(t)return this.emit("error",t);if(r.destroyed)return;i.inStream.slice(e.ranges).pipe(r.mediaData(e.length,(e=>{if(e)return this.emit("error",e);if(r.destroyed)return;const t=this._generateFragment(n);if(!t)return r.finalize();o(t)})))}))};o(a)})),t>=0){const e=this._fileStream=this._file.createReadStream({start:t});this._tracks.forEach((i=>{i.inStream=new o(t,{highWaterMark:1e7}),e.pipe(i.inStream)}))}return this._tracks.map((e=>e.outStream))}_findSampleBefore(e,t){const i=this._tracks[e],r=Math.floor(i.timeScale*t);let s=n(i.samples,r,((e,t)=>e.dts+e.presentationOffset-t));for(-1===s?s=0:s<0&&(s=-s-2);!i.samples[s].sync;)s--;return s}_generateFragment(e,t){const i=this._tracks[e];let n;if(n=void 0!==t?this._findSampleBefore(e,t):i.currSample,n>=i.samples.length)return null;const r=i.samples[n].dts;let s=0;const a=[];for(var o=n;o=i.timeScale*l)break;s+=e.size;const t=a.length-1;t<0||a[t].end!==e.offset?a.push({start:e.offset,end:e.offset+e.size}):a[t].end+=e.size}return i.currSample=o,{moof:this._generateMoof(e,n,o),ranges:a,length:s}}_generateMoof(e,t,i){const n=this._tracks[e],r=[];let s=0;for(let e=t;e{this.detailedError=this._elemWrapper.detailedError,this.destroy()},this._onWaiting=()=>{this._waitingFired=!0,this._muxer?this._tracks&&this._pump():this._createMuxer()},t.autoplay&&(t.preload="auto"),t.addEventListener("waiting",this._onWaiting),t.addEventListener("error",this._onError)}a.prototype={_createMuxer(){this._muxer=new s(this._file),this._muxer.on("ready",(e=>{this._tracks=e.map((e=>{const t=this._elemWrapper.createWriteStream(e.mime);t.on("error",(e=>{this._elemWrapper.error(e)}));const i={muxed:null,mediaSource:t,initFlushed:!1,onInitFlushed:null};return t.write(e.init,(e=>{i.initFlushed=!0,i.onInitFlushed&&i.onInitFlushed(e)})),i})),(this._waitingFired||"auto"===this._elem.preload)&&this._pump()})),this._muxer.on("error",(e=>{this._elemWrapper.error(e)}))},_pump(){const e=this._muxer.seek(this._elem.currentTime,!this._tracks);this._tracks.forEach(((t,i)=>{const n=()=>{t.muxed&&(t.muxed.destroy(),t.mediaSource=this._elemWrapper.createWriteStream(t.mediaSource),t.mediaSource.on("error",(e=>{this._elemWrapper.error(e)}))),t.muxed=e[i],r(t.muxed,t.mediaSource)};t.initFlushed?n():t.onInitFlushed=e=>{e?this._elemWrapper.error(e):n()}}))},destroy(){this.destroyed||(this.destroyed=!0,this._elem.removeEventListener("waiting",this._onWaiting),this._elem.removeEventListener("error",this._onError),this._tracks&&this._tracks.forEach((e=>{e.muxed&&e.muxed.destroy()})),this._elem.src="")}},t.exports=a},{"./mp4-remuxer":486,mediasource:258,pump:348}],488:[function(e,t,i){(function(i){(function(){ /*! webtorrent. MIT License. WebTorrent LLC */ -const n=e("events"),r=e("path"),s=e("simple-concat"),a=e("create-torrent"),o=e("debug"),c=e("bittorrent-dht/client"),l=e("load-ip-set"),u=e("run-parallel"),p=e("parse-torrent"),d=e("simple-peer"),f=e("queue-microtask"),h=e("randombytes"),m=e("simple-sha1"),b=e("throughput"),{ThrottleGroup:v}=e("speed-limiter"),g=e("./lib/conn-pool.js"),y=e("./lib/torrent.js"),{version:_}=e("./package.json"),x=o("webtorrent"),w=_.replace(/\d*./g,(e=>("0"+e%100).slice(-2))).slice(0,4),k=`-WW${w}-`;class E extends n{constructor(t={}){super(),"string"==typeof t.peerId?this.peerId=t.peerId:i.isBuffer(t.peerId)?this.peerId=t.peerId.toString("hex"):this.peerId=i.from(k+h(9).toString("base64")).toString("hex"),this.peerIdBuffer=i.from(this.peerId,"hex"),"string"==typeof t.nodeId?this.nodeId=t.nodeId:i.isBuffer(t.nodeId)?this.nodeId=t.nodeId.toString("hex"):this.nodeId=h(20).toString("hex"),this.nodeIdBuffer=i.from(this.nodeId,"hex"),this._debugId=this.peerId.toString("hex").substring(0,7),this.destroyed=!1,this.listening=!1,this.torrentPort=t.torrentPort||0,this.dhtPort=t.dhtPort||0,this.tracker=void 0!==t.tracker?t.tracker:{},this.lsd=!1!==t.lsd,this.torrents=[],this.maxConns=Number(t.maxConns)||55,this.utp=E.UTP_SUPPORT&&!1!==t.utp,this._downloadLimit=Math.max("number"==typeof t.downloadLimit?t.downloadLimit:-1,-1),this._uploadLimit=Math.max("number"==typeof t.uploadLimit?t.uploadLimit:-1,-1),this.serviceWorker=null,this.workerKeepAliveInterval=null,this.workerPortCount=0,!0===t.secure&&e("./lib/peer").enableSecure(),this._debug("new webtorrent (peerId %s, nodeId %s, port %s)",this.peerId,this.nodeId,this.torrentPort),this.throttleGroups={down:new v({rate:Math.max(this._downloadLimit,0),enabled:this._downloadLimit>=0}),up:new v({rate:Math.max(this._uploadLimit,0),enabled:this._uploadLimit>=0})},this.tracker&&("object"!=typeof this.tracker&&(this.tracker={}),globalThis.WRTC&&!this.tracker.wrtc&&(this.tracker.wrtc=globalThis.WRTC)),"function"==typeof g?this._connPool=new g(this):f((()=>{this._onListening()})),this._downloadSpeed=b(),this._uploadSpeed=b(),!1!==t.dht&&"function"==typeof c?(this.dht=new c(Object.assign({},{nodeId:this.nodeId},t.dht)),this.dht.once("error",(e=>{this._destroy(e)})),this.dht.once("listening",(()=>{const e=this.dht.address();e&&(this.dhtPort=e.port)})),this.dht.setMaxListeners(0),this.dht.listen(this.dhtPort)):this.dht=!1,this.enableWebSeeds=!1!==t.webSeeds;const n=()=>{this.destroyed||(this.ready=!0,this.emit("ready"))};"function"==typeof l&&null!=t.blocklist?l(t.blocklist,{headers:{"user-agent":`WebTorrent/${_} (https://webtorrent.io)`}},((e,t)=>{if(e)return console.error(`Failed to load blocklist: ${e.message}`);this.blocked=t,n()})):f(n)}loadWorker(e,t=(()=>{})){if(!(e instanceof ServiceWorker))throw new Error("Invalid worker registration");if("activated"!==e.state)throw new Error("Worker isn't activated");this.serviceWorker=e,navigator.serviceWorker.addEventListener("message",(e=>{const{data:t}=e;if(!t.type||"webtorrent"===!t.type||!t.url)return null;let[i,...n]=t.url.slice(t.url.indexOf(t.scope+"webtorrent/")+11+t.scope.length).split("/");if(n=decodeURI(n.join("/")),!i||!n)return null;const[r]=e.ports,s=this.get(i)&&this.get(i).files.find((e=>e.path===n));if(!s)return null;const[a,o,c]=s._serve(t),l=o&&o[Symbol.asyncIterator](),u=()=>{r.onmessage=null,o&&o.destroy(),c&&c.destroy(),this.workerPortCount--,this.workerPortCount||(clearInterval(this.workerKeepAliveInterval),this.workerKeepAliveInterval=null)};r.onmessage=async e=>{if(e.data){let e;try{e=(await l.next()).value}catch(e){}r.postMessage(e),e||u(),this.workerKeepAliveInterval||(this.workerKeepAliveInterval=setInterval((()=>fetch(`${this.serviceWorker.scriptURL.slice(0,this.serviceWorker.scriptURL.lastIndexOf("/")+1).slice(window.location.origin.length)}webtorrent/keepalive/`)),2e4))}else u()},this.workerPortCount++,r.postMessage(a)})),t(this.serviceWorker)}get downloadSpeed(){return this._downloadSpeed()}get uploadSpeed(){return this._uploadSpeed()}get progress(){const e=this.torrents.filter((e=>1!==e.progress));return e.reduce(((e,t)=>e+t.downloaded),0)/(e.reduce(((e,t)=>e+(t.length||0)),0)||1)}get ratio(){return this.torrents.reduce(((e,t)=>e+t.uploaded),0)/(this.torrents.reduce(((e,t)=>e+t.received),0)||1)}get(e){if(e instanceof y){if(this.torrents.includes(e))return e}else{let t;try{t=p(e)}catch(e){}if(!t)return null;if(!t.infoHash)throw new Error("Invalid torrent identifier");for(const e of this.torrents)if(e.infoHash===t.infoHash)return e}return null}add(e,t={},i=(()=>{})){if(this.destroyed)throw new Error("client is destroyed");"function"==typeof t&&([t,i]=[{},t]);const n=()=>{if(!this.destroyed)for(const e of this.torrents)if(e.infoHash===s.infoHash&&e!==s)return void s._destroy(new Error(`Cannot add duplicate torrent ${s.infoHash}`))},r=()=>{this.destroyed||(i(s),this.emit("torrent",s))};this._debug("add"),t=t?Object.assign({},t):{};const s=new y(e,this,t);return this.torrents.push(s),s.once("_infoHash",n),s.once("ready",r),s.once("close",(function e(){s.removeListener("_infoHash",n),s.removeListener("ready",r),s.removeListener("close",e)})),s}seed(e,t,i){if(this.destroyed)throw new Error("client is destroyed");"function"==typeof t&&([t,i]=[{},t]),this._debug("seed"),(t=t?Object.assign({},t):{}).skipVerify=!0;const n="string"==typeof e;n&&(t.path=r.dirname(e)),t.createdBy||(t.createdBy=`WebTorrent/${w}`);const o=e=>{this._debug("on seed"),"function"==typeof i&&i(e),e.emit("seed"),this.emit("seed",e)},c=this.add(null,t,(e=>{const i=[i=>{if(n||t.preloadedStore)return i();e.load(l,i)}];this.dht&&i.push((t=>{e.once("dhtAnnounce",t)})),u(i,(t=>{if(!this.destroyed)return t?e._destroy(t):void o(e)}))}));let l;var p;return p=e,"undefined"!=typeof FileList&&p instanceof FileList?e=Array.from(e):Array.isArray(e)||(e=[e]),u(e.map((e=>i=>{!t.preloadedStore&&function(e){return"object"==typeof e&&null!=e&&"function"==typeof e.pipe}(e)?s(e,((t,n)=>{if(t)return i(t);n.name=e.name,i(null,n)})):i(null,e)})),((e,n)=>{if(!this.destroyed)return e?c._destroy(e):void a.parseInput(n,t,((e,r)=>{if(!this.destroyed){if(e)return c._destroy(e);l=r.map((e=>e.getStream)),a(n,t,((e,t)=>{if(this.destroyed)return;if(e)return c._destroy(e);const n=this.get(t);n?(console.warn("A torrent with the same id is already being seeded"),c._destroy(),"function"==typeof i&&i(n)):c._onTorrentId(t)}))}}))})),c}remove(e,t,i){if("function"==typeof t)return this.remove(e,null,t);this._debug("remove");if(!this.get(e))throw new Error(`No torrent with id ${e}`);this._remove(e,t,i)}_remove(e,t,i){if("function"==typeof t)return this._remove(e,null,t);const n=this.get(e);n&&(this.torrents.splice(this.torrents.indexOf(n),1),n.destroy(t,i),this.dht&&this.dht._tables.remove(n.infoHash))}address(){return this.listening?this._connPool?this._connPool.tcpServer.address():{address:"0.0.0.0",family:"IPv4",port:0}:null}throttleDownload(e){return e=Number(e),!(isNaN(e)||!isFinite(e)||e<-1)&&(this._downloadLimit=e,this._downloadLimit<0?this.throttleGroups.down.setEnabled(!1):(this.throttleGroups.down.setEnabled(!0),void this.throttleGroups.down.setRate(this._downloadLimit)))}throttleUpload(e){return e=Number(e),!(isNaN(e)||!isFinite(e)||e<-1)&&(this._uploadLimit=e,this._uploadLimit<0?this.throttleGroups.up.setEnabled(!1):(this.throttleGroups.up.setEnabled(!0),void this.throttleGroups.up.setRate(this._uploadLimit)))}destroy(e){if(this.destroyed)throw new Error("client already destroyed");this._destroy(null,e)}_destroy(e,t){this._debug("client destroy"),this.destroyed=!0;const i=this.torrents.map((e=>t=>{e.destroy(t)}));this._connPool&&i.push((e=>{this._connPool.destroy(e)})),this.dht&&i.push((e=>{this.dht.destroy(e)})),u(i,t),e&&this.emit("error",e),this.torrents=[],this._connPool=null,this.dht=null,this.throttleGroups.down.destroy(),this.throttleGroups.up.destroy()}_onListening(){if(this._debug("listening"),this.listening=!0,this._connPool){const e=this._connPool.tcpServer.address();e&&(this.torrentPort=e.port)}this.emit("listening")}_debug(){const e=[].slice.call(arguments);e[0]=`[${this._debugId}] ${e[0]}`,x(...e)}_getByHash(e){for(const t of this.torrents)if(t.infoHashHash||(t.infoHashHash=m.sync(i.from("72657132"+t.infoHash,"hex"))),e===t.infoHashHash)return t;return null}}E.WEBRTC_SUPPORT=d.WEBRTC_SUPPORT,E.UTP_SUPPORT=g.UTP_SUPPORT,E.VERSION=_,t.exports=E}).call(this)}).call(this,e("buffer").Buffer)},{"./lib/conn-pool.js":66,"./lib/peer":491,"./lib/torrent.js":493,"./package.json":495,"bittorrent-dht/client":66,buffer:109,"create-torrent":143,debug:160,events:192,"load-ip-set":66,"parse-torrent":331,path:332,"queue-microtask":353,randombytes:356,"run-parallel":380,"simple-concat":392,"simple-peer":394,"simple-sha1":410,"speed-limiter":428,throughput:474}],489:[function(e,t,i){const n=e("stream"),r=e("debug"),s=e("end-of-stream"),a=r("webtorrent:file-stream");class o extends n.Readable{constructor(e,t){super(t),this._torrent=e._torrent;const i=t&&t.start||0,n=t&&t.end&&t.end{this._notify()})),s(this,(e=>{this.destroy(e)}))}_read(){this._reading||(this._reading=!0,this._notify())}_notify(){if(!this._reading||0===this._missing)return;if(!this._torrent.bitfield.get(this._piece))return this._torrent.critical(this._piece,this._piece+this._criticalLength);if(this._notifying)return;if(this._notifying=!0,this._torrent.destroyed)return this.destroy(new Error("Torrent removed"));const e=this._piece,t={};e===this._torrent.pieces.length-1&&(t.length=this._torrent.lastPieceLength),this._torrent.store.get(e,t,((t,i)=>{if(this._notifying=!1,!this.destroyed){if(a("read %s (length %s) (err %s)",e,i&&i.length,t&&t.message),t)return this.destroy(t);this._offset&&(i=i.slice(this._offset),this._offset=0),this._missing{const s=r===e.length-1?n:i;return t.get(r)?s:s-e[r].missing};let o=0;for(let t=r;t<=s;t+=1){const c=a(t);if(o+=c,t===r){const e=this.offset%i;o-=Math.min(e,c)}if(t===s){const t=(s===e.length-1?n:i)-(this.offset+this.length)%i;o-=Math.min(t,c)}}return o}get progress(){return this.length?this.downloaded/this.length:0}select(e){0!==this.length&&this._torrent.select(this._startPiece,this._endPiece,e)}deselect(){0!==this.length&&this._torrent.deselect(this._startPiece,this._endPiece,!1)}createReadStream(e){if(0===this.length){const e=new r;return u((()=>{e.end()})),e}const t=new h(this,e);return this._fileStreams.add(t),t.once("close",(()=>{this._fileStreams.delete(t)})),t}getBuffer(e){l(this.createReadStream(),this.length,e)}getBlob(e){if("undefined"==typeof window)throw new Error("browser-only method");o(this.createReadStream(),this._getMimeType()).then((t=>e(null,t)),(t=>e(t)))}getBlobURL(e){if("undefined"==typeof window)throw new Error("browser-only method");c(this.createReadStream(),this._getMimeType()).then((t=>e(null,t)),(t=>e(t)))}appendTo(e,t,i){if("undefined"==typeof window)throw new Error("browser-only method");a.append(this,e,t,i)}renderTo(e,t,i){if("undefined"==typeof window)throw new Error("browser-only method");a.render(this,e,t,i)}_serve(e){const t={status:200,headers:{"Accept-Ranges":"bytes","Content-Type":d.getType(this.name),"Cache-Control":"no-cache, no-store, must-revalidate, max-age=0",Expires:"0"},body:"HEAD"===e.method?"":"STREAM"};"document"===e.destination&&(t.headers["Content-Type"]="application/octet-stream",t.headers["Content-Disposition"]="attachment",t.body="DOWNLOAD");let i=p(this.length,e.headers.range||"");i.constructor===Array?(t.status=206,i=i[0],t.headers["Content-Range"]=`bytes ${i.start}-${i.end}/${this.length}`,t.headers["Content-Length"]=""+(i.end-i.start+1)):t.headers["Content-Length"]=this.length;const n="GET"===e.method&&this.createReadStream(i);let r=null;return n&&this.emit("stream",{stream:n,req:e,file:this},(e=>{r=e,f(e,(()=>{e&&e.destroy(),n.destroy()}))})),[t,r||n,r&&n]}getStreamURL(e=(()=>{})){if("undefined"==typeof window)throw new Error("browser-only method");if(!this._serviceWorker)throw new Error("No worker registered");if("activated"!==this._serviceWorker.state)throw new Error("Worker isn't activated");e(null,`${this._serviceWorker.scriptURL.slice(0,this._serviceWorker.scriptURL.lastIndexOf("/")+1).slice(window.location.origin.length)}webtorrent/${this._torrent.infoHash}/${encodeURI(this.path)}`)}streamTo(e,t=(()=>{})){if("undefined"==typeof window)throw new Error("browser-only method");if(!this._serviceWorker)throw new Error("No worker registered");if("activated"!==this._serviceWorker.state)throw new Error("Worker isn't activated");const i=this._serviceWorker.scriptURL.slice(0,this._serviceWorker.scriptURL.lastIndexOf("/")+1).slice(window.location.origin.length);e.src=`${i}webtorrent/${this._torrent.infoHash}/${encodeURI(this.path)}`,t(null,e)}_getMimeType(){return a.mime[s.extname(this.name).toLowerCase()]}_destroy(){this._destroyed=!0,this._torrent=null;for(const e of this._fileStreams)e.destroy();this._fileStreams.clear()}}},{"./file-stream.js":489,"end-of-stream":190,events:192,mime:281,path:332,"queue-microtask":353,"range-parser":358,"render-media":376,stream:433,"stream-to-blob":468,"stream-to-blob-url":467,"stream-with-known-length-to-buffer":469}],491:[function(e,t,i){const n=e("events"),{Transform:r}=e("stream"),s=e("unordered-array-remove"),a=e("debug"),o=e("bittorrent-protocol"),c=a("webtorrent:peer");let l=!1;i.enableSecure=()=>{l=!0},i.createWebRTCPeer=(e,t,i)=>{const n=new d(e.id,"webrtc");if(n.conn=e,n.swarm=t,n.throttleGroups=i,n.conn.connected)n.onConnect();else{const e=()=>{n.conn.removeListener("connect",t),n.conn.removeListener("error",i)},t=()=>{e(),n.onConnect()},i=t=>{e(),n.destroy(t)};n.conn.once("connect",t),n.conn.once("error",i),n.startConnectTimeout()}return n},i.createTCPIncomingPeer=(e,t)=>u(e,"tcpIncoming",t),i.createUTPIncomingPeer=(e,t)=>u(e,"utpIncoming",t),i.createTCPOutgoingPeer=(e,t,i)=>p(e,t,"tcpOutgoing",i),i.createUTPOutgoingPeer=(e,t,i)=>p(e,t,"utpOutgoing",i);const u=(e,t,i)=>{const n=`${e.remoteAddress}:${e.remotePort}`,r=new d(n,t);return r.conn=e,r.addr=n,r.throttleGroups=i,r.onConnect(),r},p=(e,t,i,n)=>{const r=new d(e,i);return r.addr=e,r.swarm=t,r.throttleGroups=n,r};i.createWebSeedPeer=(e,t,i,n)=>{const r=new d(t,"webSeed");return r.swarm=i,r.conn=e,r.throttleGroups=n,r.onConnect(),r};class d extends n{constructor(e,t){super(),this.id=e,this.type=t,c("new %s Peer %s",t,e),this.addr=null,this.conn=null,this.swarm=null,this.wire=null,this.connected=!1,this.destroyed=!1,this.timeout=null,this.retries=0,this.sentPe1=!1,this.sentPe2=!1,this.sentPe3=!1,this.sentPe4=!1,this.sentHandshake=!1}onConnect(){if(this.destroyed)return;this.connected=!0,c("Peer %s connected",this.id),clearTimeout(this.connectTimeout);const e=this.conn;e.once("end",(()=>{this.destroy()})),e.once("close",(()=>{this.destroy()})),e.once("finish",(()=>{this.destroy()})),e.once("error",(e=>{this.destroy(e)}));const t=this.wire=new o(this.type,this.retries,l);t.once("end",(()=>{this.destroy()})),t.once("close",(()=>{this.destroy()})),t.once("finish",(()=>{this.destroy()})),t.once("error",(e=>{this.destroy(e)})),t.once("pe1",(()=>{this.onPe1()})),t.once("pe2",(()=>{this.onPe2()})),t.once("pe3",(()=>{this.onPe3()})),t.once("pe4",(()=>{this.onPe4()})),t.once("handshake",((e,t)=>{this.onHandshake(e,t)})),this.startHandshakeTimeout(),this.setThrottlePipes(),this.swarm&&("tcpOutgoing"===this.type?l&&0===this.retries&&!this.sentPe1?this.sendPe1():this.sentHandshake||this.handshake():"tcpIncoming"===this.type||this.sentHandshake||this.handshake())}sendPe1(){this.wire.sendPe1(),this.sentPe1=!0}onPe1(){this.sendPe2()}sendPe2(){this.wire.sendPe2(),this.sentPe2=!0}onPe2(){this.sendPe3()}sendPe3(){this.wire.sendPe3(this.swarm.infoHash),this.sentPe3=!0}onPe3(e){this.swarm&&(this.swarm.infoHashHash!==e&&this.destroy(new Error("unexpected crypto handshake info hash for this swarm")),this.sendPe4())}sendPe4(){this.wire.sendPe4(this.swarm.infoHash),this.sentPe4=!0}onPe4(){this.sentHandshake||this.handshake()}clearPipes(){this.conn.unpipe(),this.wire.unpipe()}setThrottlePipes(){const e=this;this.conn.pipe(this.throttleGroups.down.throttle()).pipe(new r({transform(t,i,n){e.emit("download",t.length),e.destroyed||n(null,t)}})).pipe(this.wire).pipe(this.throttleGroups.up.throttle()).pipe(new r({transform(t,i,n){e.emit("upload",t.length),e.destroyed||n(null,t)}})).pipe(this.conn)}onHandshake(e,t){if(!this.swarm)return;if(this.destroyed)return;if(this.swarm.destroyed)return this.destroy(new Error("swarm already destroyed"));if(e!==this.swarm.infoHash)return this.destroy(new Error("unexpected handshake info hash for this swarm"));if(t===this.swarm.peerId)return this.destroy(new Error("refusing to connect to ourselves"));c("Peer %s got handshake %s",this.id,e),clearTimeout(this.handshakeTimeout),this.retries=0;let i=this.addr;!i&&this.conn.remoteAddress&&this.conn.remotePort&&(i=`${this.conn.remoteAddress}:${this.conn.remotePort}`),this.swarm._onWire(this.wire,i),this.swarm&&!this.swarm.destroyed&&(this.sentHandshake||this.handshake())}handshake(){const e={dht:!this.swarm.private&&!!this.swarm.client.dht,fast:!0};this.wire.handshake(this.swarm.infoHash,this.swarm.client.peerId,e),this.sentHandshake=!0}startConnectTimeout(){clearTimeout(this.connectTimeout);const e={webrtc:25e3,tcpOutgoing:5e3,utpOutgoing:5e3};this.connectTimeout=setTimeout((()=>{this.destroy(new Error("connect timeout"))}),e[this.type]),this.connectTimeout.unref&&this.connectTimeout.unref()}startHandshakeTimeout(){clearTimeout(this.handshakeTimeout),this.handshakeTimeout=setTimeout((()=>{this.destroy(new Error("handshake timeout"))}),25e3),this.handshakeTimeout.unref&&this.handshakeTimeout.unref()}destroy(e){if(this.destroyed)return;this.destroyed=!0,this.connected=!1,c("destroy %s %s (error: %s)",this.type,this.id,e&&(e.message||e)),clearTimeout(this.connectTimeout),clearTimeout(this.handshakeTimeout);const t=this.swarm,i=this.conn,n=this.wire;this.swarm=null,this.conn=null,this.wire=null,t&&n&&s(t.wires,t.wires.indexOf(n)),i&&(i.on("error",(()=>{})),i.destroy()),n&&n.destroy(),t&&t.removePeer(this.id)}}},{"bittorrent-protocol":27,debug:160,events:192,stream:433,"unordered-array-remove":481}],492:[function(e,t,i){t.exports=class{constructor(e){this._torrent=e,this._numPieces=e.pieces.length,this._pieces=new Array(this._numPieces),this._onWire=e=>{this.recalculate(),this._initWire(e)},this._onWireHave=e=>{this._pieces[e]+=1},this._onWireBitfield=()=>{this.recalculate()},this._torrent.wires.forEach((e=>{this._initWire(e)})),this._torrent.on("wire",this._onWire),this.recalculate()}getRarestPiece(e){let t=[],i=1/0;for(let n=0;n{this._cleanupWireEvents(e)})),this._torrent=null,this._pieces=null,this._onWire=null,this._onWireHave=null,this._onWireBitfield=null}_initWire(e){e._onClose=()=>{this._cleanupWireEvents(e);for(let t=0;t0&&(i=Math.min(i,t))}return i}function $(){}t.exports=class extends r{constructor(e,t,i){super(),this._debugId="unknown infohash",this.client=t,this.announce=i.announce,this.urlList=i.urlList,this.path=i.path||V,this.addUID=i.addUID||!1,this.skipVerify=!!i.skipVerify,this._store=i.store||b,this._preloadedStore=i.preloadedStore||null,this._storeCacheSlots=void 0!==i.storeCacheSlots?i.storeCacheSlots:20,this._destroyStoreOnDestroy=i.destroyStoreOnDestroy||!1,this._getAnnounceOpts=i.getAnnounceOpts,"boolean"==typeof i.private&&(this.private=i.private),this.strategy=i.strategy||"sequential",this.maxWebConns=i.maxWebConns||4,this._rechokeNumSlots=!1===i.uploads||0===i.uploads?0:+i.uploads||10,this._rechokeOptimisticWire=null,this._rechokeOptimisticTime=0,this._rechokeIntervalId=null,this.ready=!1,this.destroyed=!1,this.paused=i.paused||!1,this.done=!1,this.metadata=null,this.store=null,this.storeOpts=i.storeOpts,this.files=[],this.pieces=[],this._amInterested=!1,this._selections=[],this._critical=[],this.wires=[],this._queue=[],this._peers={},this._peersLength=0,this.received=0,this.uploaded=0,this._downloadSpeed=T(),this._uploadSpeed=T(),this._servers=[],this._xsRequests=[],this._fileModtimes=i.fileModtimes,null!==e&&this._onTorrentId(e),this._debug("new torrent")}get timeRemaining(){return this.done?0:0===this.downloadSpeed?1/0:(this.length-this.downloaded)/this.downloadSpeed*1e3}get downloaded(){if(!this.bitfield)return 0;let e=0;for(let t=0,i=this.pieces.length;t{this.destroyed||this._onParsedTorrent(t)}))):E.remote(e,((e,t)=>{if(!this.destroyed)return e?this._destroy(e):void this._onParsedTorrent(t)}))}_onParsedTorrent(e){if(!this.destroyed){if(this._processParsedTorrent(e),!this.infoHash)return this._destroy(new Error("Malformed torrent data: No info hash"));this._rechokeIntervalId=setInterval((()=>{this._rechoke()}),1e4),this._rechokeIntervalId.unref&&this._rechokeIntervalId.unref(),this.emit("_infoHash",this.infoHash),this.destroyed||(this.emit("infoHash",this.infoHash),this.destroyed||(this.client.listening?this._onListening():this.client.once("listening",(()=>{this._onListening()}))))}}_processParsedTorrent(e){this._debugId=e.infoHash.toString("hex").substring(0,7),void 0!==this.private&&(e.private=this.private),this.announce&&(e.announce=e.announce.concat(this.announce)),this.client.tracker&&n.WEBTORRENT_ANNOUNCE&&!e.private&&(e.announce=e.announce.concat(n.WEBTORRENT_ANNOUNCE)),this.urlList&&(e.urlList=e.urlList.concat(this.urlList)),e.announce=Array.from(new Set(e.announce)),e.urlList=Array.from(new Set(e.urlList)),Object.assign(this,e),this.magnetURI=E.toMagnetURI(e),this.torrentFile=E.toTorrentFile(e)}_onListening(){this.destroyed||(this.info?this._onMetadata(this):(this.xs&&this._getMetadataFromServer(),this._startDiscovery()))}_startDiscovery(){if(this.discovery||this.destroyed)return;let e=this.client.tracker;e&&(e=Object.assign({},this.client.tracker,{getAnnounceOpts:()=>{if(this.destroyed)return;const e={uploaded:this.uploaded,downloaded:this.downloaded,left:Math.max(this.length-this.downloaded,0)};return this.client.tracker.getAnnounceOpts&&Object.assign(e,this.client.tracker.getAnnounceOpts()),this._getAnnounceOpts&&Object.assign(e,this._getAnnounceOpts()),e}})),this.peerAddresses&&this.peerAddresses.forEach((e=>this.addPeer(e))),this.discovery=new m({infoHash:this.infoHash,announce:this.announce,peerId:this.client.peerId,dht:!this.private&&this.client.dht,tracker:e,port:this.client.torrentPort,userAgent:W,lsd:this.client.lsd}),this.discovery.on("error",(e=>{this._destroy(e)})),this.discovery.on("peer",((e,t)=>{this._debug("peer %s discovered via %s",e,t),"string"==typeof e&&this.done||this.addPeer(e)})),this.discovery.on("trackerAnnounce",(()=>{this.emit("trackerAnnounce"),0===this.numPeers&&this.emit("noPeers","tracker")})),this.discovery.on("dhtAnnounce",(()=>{this.emit("dhtAnnounce"),0===this.numPeers&&this.emit("noPeers","dht")})),this.discovery.on("warning",(e=>{this.emit("warning",e)}))}_getMetadataFromServer(){const e=this,t=(Array.isArray(this.xs)?this.xs:[this.xs]).map((t=>i=>{!function(t,i){if(0!==t.indexOf("http://")&&0!==t.indexOf("https://"))return e.emit("warning",new Error(`skipping non-http xs param: ${t}`)),i(null);const n={url:t,method:"GET",headers:{"user-agent":W}};let r;try{r=v.concat(n,s)}catch(n){return e.emit("warning",new Error(`skipping invalid url xs param: ${t}`)),i(null)}function s(n,r,s){if(e.destroyed)return i(null);if(e.metadata)return i(null);if(n)return e.emit("warning",new Error(`http error from xs param: ${t}`)),i(null);if(200!==r.statusCode)return e.emit("warning",new Error(`non-200 status code ${r.statusCode} from xs param: ${t}`)),i(null);let a;try{a=E(s)}catch(n){}return a?a.infoHash!==e.infoHash?(e.emit("warning",new Error(`got torrent file with incorrect info hash from xs param: ${t}`)),i(null)):(e._onMetadata(a),void i(null)):(e.emit("warning",new Error(`got invalid torrent file from xs param: ${t}`)),i(null))}e._xsRequests.push(r)}(t,i)}));w(t)}_onMetadata(e){if(this.metadata||this.destroyed)return;let t;if(this._debug("got metadata"),this._xsRequests.forEach((e=>{e.abort()})),this._xsRequests=[],e&&e.infoHash)t=e;else try{t=E(e)}catch(e){return this._destroy(e)}this._processParsedTorrent(t),this.metadata=this.torrentFile,this.client.enableWebSeeds&&this.urlList.forEach((e=>{this.addWebSeed(e)})),this._rarityMap=new O(this),this.files=this.files.map((e=>new R(this,e)));let i=this._preloadedStore;if(i||(i=new this._store(this.pieceLength,{...this.storeOpts,torrent:this,path:this.path,files:this.files,length:this.length,name:this.name+" - "+this.infoHash.slice(0,8),addUID:this.addUID})),this._storeCacheSlots>0&&!(i instanceof _)&&(i=new p(i,{max:this._storeCacheSlots})),this.store=new g(i),this.so?this.files.forEach(((e,t)=>{this.so.includes(t)?this.files[t].select():this.files[t].deselect()})):0!==this.pieces.length&&this.select(0,this.pieces.length-1,!1),this._hashes=this.pieces,this.pieces=this.pieces.map(((e,t)=>{const i=t===this.pieces.length-1?this.lastPieceLength:this.pieceLength;return new S(i)})),this._reservations=this.pieces.map((()=>[])),this.bitfield=new u(this.pieces.length),this.emit("metadata"),!this.destroyed)if(this.skipVerify)this._markAllVerified(),this._onStore();else{const e=e=>{if(e)return this._destroy(e);this._debug("done verifying"),this._onStore()};this._debug("verifying existing torrent data"),this._fileModtimes&&this._store===b?this.getFileModtimes(((t,i)=>{if(t)return this._destroy(t);this.files.map(((e,t)=>i[t]===this._fileModtimes[t])).every((e=>e))?(this._markAllVerified(),this._onStore()):this._verifyPieces(e)})):this._verifyPieces(e)}}getFileModtimes(e){const t=[];k(this.files.map(((e,i)=>n=>{const r=this.addUID?c.join(this.name+" - "+this.infoHash.slice(0,8)):c.join(this.path,e.path);s.stat(r,((e,r)=>{if(e&&"ENOENT"!==e.code)return n(e);t[i]=r&&r.mtime.getTime(),n(null)}))})),H,(i=>{this._debug("done getting file modtimes"),e(i,t)}))}_verifyPieces(e){k(this.pieces.map(((e,t)=>e=>{if(this.destroyed)return e(new Error("torrent is destroyed"));const i={};t===this.pieces.length-1&&(i.length=this.lastPieceLength),this.store.get(t,i,((i,n)=>this.destroyed?e(new Error("torrent is destroyed")):i?A((()=>e(null))):void I(n,(i=>{if(this.destroyed)return e(new Error("torrent is destroyed"));i===this._hashes[t]?(this._debug("piece verified %s",t),this._markVerified(t)):this._debug("piece invalid %s",t),e(null)}))))})),H,e)}rescanFiles(e){if(this.destroyed)throw new Error("torrent is destroyed");e||(e=$),this._verifyPieces((t=>{if(t)return this._destroy(t),e(t);this._checkDone(),e(null)}))}_markAllVerified(){for(let e=0;ee))return!0;return!1}_onStore(){this.destroyed||(this._debug("on store"),this._startDiscovery(),this.ready=!0,this.emit("ready"),this._checkDone(),this._updateSelections(),this.wires.forEach((e=>{e.ut_metadata&&e.ut_metadata.setMetadata(this.metadata),this._onWireWithMetadata(e)})))}destroy(e,t){if("function"==typeof e)return this.destroy(null,e);this._destroy(null,e,t)}_destroy(e,t,i){if("function"==typeof t)return this._destroy(e,null,t);if(this.destroyed)return;this.destroyed=!0,this._debug("destroy"),this.client._remove(this),clearInterval(this._rechokeIntervalId),this._xsRequests.forEach((e=>{e.abort()})),this._rarityMap&&this._rarityMap.destroy();for(const e in this._peers)this.removePeer(e);this.files.forEach((e=>{e instanceof R&&e._destroy()}));const n=this._servers.map((e=>t=>{e.destroy(t)}));if(this.discovery&&n.push((e=>{this.discovery.destroy(e)})),this.store){let e=this._destroyStoreOnDestroy;t&&void 0!==t.destroyStore&&(e=t.destroyStore),n.push((t=>{e?this.store.destroy(t):this.store.close(t)}))}w(n,i),e&&(0===this.listenerCount("error")?this.client.emit("error",e):this.emit("error",e)),this.emit("close"),this.client=null,this.files=[],this.discovery=null,this.store=null,this._rarityMap=null,this._peers=null,this._servers=null,this._xsRequests=null}addPeer(e){if(this.destroyed)throw new Error("torrent is destroyed");if(!this.infoHash)throw new Error("addPeer() must not be called before the `infoHash` event");let t;if(this.client.blocked){if("string"==typeof e){let i;try{i=l(e)}catch(t){return this._debug("ignoring peer: invalid %s",e),this.emit("invalidPeer",e),!1}t=i[0]}else"string"==typeof e.remoteAddress&&(t=e.remoteAddress);if(t&&this.client.blocked.contains(t))return this._debug("ignoring peer: blocked %s",e),"string"!=typeof e&&e.destroy(),this.emit("blockedPeer",e),!1}const i=this.client.utp&&this._isIPv4(t)?"utp":"tcp",n=!!this._addPeer(e,i);return n?this.emit("peer",e):this.emit("invalidPeer",e),n}_addPeer(e,t){if(this.destroyed)return"string"!=typeof e&&e.destroy(),null;if("string"==typeof e&&!this._validAddr(e))return this._debug("ignoring peer: invalid %s",e),null;const i=e&&e.id||e;if(this._peers[i])return this._debug("ignoring peer: duplicate (%s)",i),"string"!=typeof e&&e.destroy(),null;if(this.paused)return this._debug("ignoring peer: torrent is paused"),"string"!=typeof e&&e.destroy(),null;let n;return this._debug("add peer %s",i),n="string"==typeof e?"utp"===t?L.createUTPOutgoingPeer(e,this,this.client.throttleGroups):L.createTCPOutgoingPeer(e,this,this.client.throttleGroups):L.createWebRTCPeer(e,this,this.client.throttleGroups),this._registerPeer(n),"string"==typeof e&&(this._queue.push(n),this._drain()),n}addWebSeed(e){if(this.destroyed)throw new Error("torrent is destroyed");let t,i;if("string"==typeof e){if(t=e,!/^https?:\/\/.+/.test(t))return this.emit("warning",new Error(`ignoring invalid web seed: ${t}`)),void this.emit("invalidPeer",t);if(this._peers[t])return this.emit("warning",new Error(`ignoring duplicate web seed: ${t}`)),void this.emit("invalidPeer",t);i=new q(t,this)}else{if(!e||"string"!=typeof e.connId)return void this.emit("warning",new Error("addWebSeed must be passed a string or connection object with id property"));if(i=e,t=i.connId,this._peers[t])return this.emit("warning",new Error(`ignoring duplicate web seed: ${t}`)),void this.emit("invalidPeer",t)}this._debug("add web seed %s",t);const n=L.createWebSeedPeer(i,t,this,this.client.throttleGroups);this._registerPeer(n),this.emit("peer",t)}_addIncomingPeer(e){return this.destroyed?e.destroy(new Error("torrent is destroyed")):this.paused?e.destroy(new Error("torrent is paused")):(this._debug("add incoming peer %s",e.id),void this._registerPeer(e))}_registerPeer(e){e.on("download",(e=>{this.destroyed||(this.received+=e,this._downloadSpeed(e),this.client._downloadSpeed(e),this.emit("download",e),this.destroyed||this.client.emit("download",e))})),e.on("upload",(e=>{this.destroyed||(this.uploaded+=e,this._uploadSpeed(e),this.client._uploadSpeed(e),this.emit("upload",e),this.destroyed||this.client.emit("upload",e))})),this._peers[e.id]=e,this._peersLength+=1}removePeer(e){const t=e&&e.id||e;(e=this._peers[t])&&(this._debug("removePeer %s",t),delete this._peers[t],this._peersLength-=1,e.destroy(),this._drain())}select(e,t,i,n){if(this.destroyed)throw new Error("torrent is destroyed");if(e<0||tt.priority-e.priority)),this._updateSelections()}deselect(e,t,i){if(this.destroyed)throw new Error("torrent is destroyed");i=Number(i)||0,this._debug("deselect %s-%s (priority %s)",e,t,i);for(let n=0;n{if(!this.destroyed&&!this.client.dht.destroyed){if(!e.remoteAddress)return this._debug("ignoring PORT from peer with no address");if(0===i||i>65536)return this._debug("ignoring invalid PORT from peer");this._debug("port: %s (from %s)",i,t),this.client.dht.addNode({host:e.remoteAddress,port:i})}})),e.on("timeout",(()=>{this._debug("wire timeout (%s)",t),e.destroy()})),"webSeed"!==e.type&&e.setTimeout(3e4,!0),e.setKeepAlive(!0),e.use(C(this.metadata)),e.ut_metadata.on("warning",(e=>{this._debug("ut_metadata warning: %s",e.message)})),this.metadata||(e.ut_metadata.on("metadata",(e=>{this._debug("got metadata via ut_metadata"),this._onMetadata(e)})),e.ut_metadata.fetch()),"function"!=typeof B||this.private||(e.use(B()),e.ut_pex.on("peer",(e=>{this.done||(this._debug("ut_pex: got peer: %s (from %s)",e,t),this.addPeer(e))})),e.ut_pex.on("dropped",(e=>{const i=this._peers[e];i&&!i.connected&&(this._debug("ut_pex: dropped peer: %s (from %s)",e,t),this.removePeer(e))})),e.once("close",(()=>{e.ut_pex.reset()}))),e.use(y()),this.emit("wire",e,t),this.ready&&A((()=>{this._onWireWithMetadata(e)}))}_onWireWithMetadata(e){let t=null;const i=()=>{this.destroyed||e.destroyed||(this._numQueued>2*(this._numConns-this.numPeers)&&e.amInterested?e.destroy():(t=setTimeout(i,D),t.unref&&t.unref()))};let n;const r=()=>{if(e.peerPieces.buffer.length===this.bitfield.buffer.length){for(n=0;n{r(),this._update(),this._updateWireInterest(e)})),e.on("have",(()=>{r(),this._update(),this._updateWireInterest(e)})),e.lt_donthave.on("donthave",(()=>{r(),this._update(),this._updateWireInterest(e)})),e.on("have-all",(()=>{e.isSeeder=!0,e.choke(),this._update(),this._updateWireInterest(e)})),e.on("have-none",(()=>{e.isSeeder=!1,this._update(),this._updateWireInterest(e)})),e.on("allowed-fast",(e=>{this._update()})),e.once("interested",(()=>{e.unchoke()})),e.once("close",(()=>{clearTimeout(t)})),e.on("choke",(()=>{clearTimeout(t),t=setTimeout(i,D),t.unref&&t.unref()})),e.on("unchoke",(()=>{clearTimeout(t),this._update()})),e.on("request",((t,i,n,r)=>{if(n>131072)return e.destroy();this.pieces[t]||this.store.get(t,{offset:i,length:n},r)})),e.hasFast&&this._hasAllPieces()?e.haveAll():e.hasFast&&this._hasNoPieces()?e.haveNone():e.bitfield(this.bitfield),this._updateWireInterest(e),e.peerExtensions.dht&&this.client.dht&&this.client.dht.listening&&e.port(this.client.dht.address().port),"webSeed"!==e.type&&(t=setTimeout(i,D),t.unref&&t.unref()),e.isSeeder=!1,r()}_updateSelections(){this.ready&&!this.destroyed&&(A((()=>{this._gcSelections()})),this._updateInterest(),this._update())}_gcSelections(){for(let e=0;ethis._updateWireInterest(e))),e!==this._amInterested&&(this._amInterested?this.emit("interested"):this.emit("uninterested"))}_updateWireInterest(e){let t=!1;for(let i=0;i{t._updateWire(e)}),{timeout:250}):t._updateWire(e)}_updateWire(e){const t=this,i=K(e,.5);if(e.requests.length>=i)return;const n=K(e,1);if(e.peerChoking)e.hasFast&&e.peerAllowedFastSet.length>0&&!this._hasMorePieces(e.peerAllowedFastSet.length-1)&&function(){if(e.requests.length>=n)return!1;for(const i of e.peerAllowedFastSet){if(e.peerPieces.get(i)&&!t.bitfield.get(i))for(;t._request(e,i,!1)&&e.requests.length=n.from+n.offset;--s)if(e.peerPieces.get(s)&&t._request(e,s,!1))return}}();a(!1)||a(!0)}function r(t,i,n,r){return s=>s>=t&&s<=i&&!(s in n)&&e.peerPieces.get(s)&&(!r||r(s))}function s(e){let i=e;for(let n=e;n=n)return!0;const a=function(){const i=e.downloadSpeed()||1;if(i>z)return()=>!0;const n=Math.max(1,e.requests.length)*S.BLOCK_LENGTH/i;let r=10,s=0;return e=>{if(!r||t.bitfield.get(e))return!0;let a=t.pieces[e].missing;for(;s0))return r--,!1}return!0}}();for(let o=0;o({wire:e,random:Math.random()}))).sort(((e,t)=>{const i=e.wire,n=t.wire;return i.downloadSpeed()!==n.downloadSpeed()?i.downloadSpeed()-n.downloadSpeed():i.uploadSpeed()!==n.uploadSpeed()?i.uploadSpeed()-n.uploadSpeed():i.amChoking!==n.amChoking?i.amChoking?-1:1:e.random-t.random})).map((e=>e.wire));this._rechokeOptimisticTime<=0?this._rechokeOptimisticWire=null:this._rechokeOptimisticTime-=1;let t=0;for(;e.length>0&&t0){const t=e.filter((e=>e.peerInterested));if(t.length>0){const e=t[(i=t.length,Math.random()*i|0)];e.unchoke(),this._rechokeOptimisticWire=e,this._rechokeOptimisticTime=2}}var i;e.filter((e=>e!==this._rechokeOptimisticWire)).forEach((e=>e.choke()))}_hotswap(e,t){const i=e.downloadSpeed();if(i=z||(2*o>i||o>a||(r=t,a=o))}if(!r)return!1;for(s=0;s=a)return!1;const o=n.pieces[t];let c=s?o.reserveRemaining():o.reserve();if(-1===c&&i&&n._hotswap(e,t)&&(c=s?o.reserveRemaining():o.reserve()),-1===c)return!1;let l=n._reservations[t];l||(l=n._reservations[t]=[]);let u=l.indexOf(null);-1===u&&(u=l.length),l[u]=e;const p=o.chunkOffset(c),d=s?o.chunkLengthRemaining(c):o.chunkLength(c);function f(){A((()=>{n._update()}))}return e.request(t,p,d,(function i(r,a){if(n.destroyed)return;if(!n.ready)return n.once("ready",(()=>{i(r,a)}));if(l[u]===e&&(l[u]=null),o!==n.pieces[t])return f();if(r)return n._debug("error getting piece %s (offset: %s length: %s) from %s: %s",t,p,d,`${e.remoteAddress}:${e.remotePort}`,r.message),s?o.cancelRemaining(c):o.cancel(c),void f();if(n._debug("got piece %s (offset: %s length: %s) from %s",t,p,d,`${e.remoteAddress}:${e.remotePort}`),!o.set(c,a,e))return f();const h=o.flush();I(h,(e=>{n.destroyed||(e===n._hashes[t]?(n._debug("piece verified %s",t),n.store.put(t,h,(e=>{e?n._destroy(e):(n.pieces[t]=null,n._markVerified(t),n.wires.forEach((e=>{e.have(t)})),n._checkDone()&&!n.destroyed&&n.discovery.complete(),f())}))):(n.pieces[t]=new S(o.length),n.emit("warning",new Error(`Piece ${t} failed verification`)),f()))}))})),!0}_checkDone(){if(this.destroyed)return;this.files.forEach((e=>{if(!e.done){for(let t=e._startPiece;t<=e._endPiece;++t)if(!this.bitfield.get(t))return;e.done=!0,e.emit("done"),this._debug(`file done: ${e.name}`)}}));let e=!0;for(const t of this._selections){for(let i=t.from;i<=t.to;i++)if(!this.bitfield.get(i)){e=!1;break}if(!e)break}return!this.done&&e?(this.done=!0,this._debug(`torrent done: ${this.infoHash}`),this.emit("done")):this.done=!1,this._gcSelections(),e}load(e,t){if(this.destroyed)throw new Error("torrent is destroyed");if(!this.ready)return this.once("ready",(()=>{this.load(e,t)}));Array.isArray(e)||(e=[e]),t||(t=$);const i=new x(e),n=new d(this.store,this.pieceLength);M(i,n,(e=>{if(e)return t(e);this._markAllVerified(),this._checkDone(),t(null)}))}createServer(e){if("function"!=typeof P)throw new Error("node.js-only method");if(this.destroyed)throw new Error("torrent is destroyed");const t=new P(this,e);return this._servers.push(t),t}pause(){this.destroyed||(this._debug("pause"),this.paused=!0)}resume(){this.destroyed||(this._debug("resume"),this.paused=!1,this._drain())}_debug(){const e=[].slice.call(arguments);e[0]=`[${this.client?this.client._debugId:"No Client"}] [${this._debugId}] ${e[0]}`,N(...e)}_drain(){if(this._debug("_drain numConns %s maxConns %s",this._numConns,this.client.maxConns),"function"!=typeof a.connect||this.destroyed||this.paused||this._numConns>=this.client.maxConns)return;this._debug("drain (%s queued, %s/%s peers)",this._numQueued,this.numPeers,this.client.maxConns);const e=this._queue.shift();if(!e)return;this._debug("%s connect attempt to %s",e.type,e.addr);const t=l(e.addr),i={host:t[0],port:t[1]};this.client.utp&&"utpOutgoing"===e.type?e.conn=U.connect(i.port,i.host):e.conn=a.connect(i);const n=e.conn;n.once("connect",(()=>{e.onConnect()})),n.once("error",(t=>{e.destroy(t)})),e.startConnectTimeout(),n.on("close",(()=>{if(this.destroyed)return;if(e.retries>=F.length){if(this.client.utp){const t=this._addPeer(e.addr,"tcp");t&&(t.retries=0)}else this._debug("conn %s closed: will not re-add (max %s attempts)",e.addr,F.length);return}const t=F[e.retries];this._debug("conn %s closed: will re-add to queue in %sms (attempt %s)",e.addr,t,e.retries+1);const i=setTimeout((()=>{if(this.destroyed)return;const t=l(e.addr)[0],i=this.client.utp&&this._isIPv4(t)?"utp":"tcp",n=this._addPeer(e.addr,i);n&&(n.retries=e.retries+1)}),t);i.unref&&i.unref()}))}_validAddr(e){let t;try{t=l(e)}catch(e){return!1}const i=t[0],n=t[1];return n>0&&n<65535&&!("127.0.0.1"===i&&n===this.client.torrentPort)}_isIPv4(e){return/^((?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])[.]){3}(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])$/.test(e)}}}).call(this)}).call(this,e("_process"),"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"../package.json":495,"./file.js":490,"./peer.js":491,"./rarity-map.js":492,"./server.js":66,"./utp.js":66,"./webconn.js":494,_process:340,"addr-to-ip-port":2,bitfield:26,"cache-chunk-store":116,"chunk-store-stream/write":132,cpus:136,debug:160,events:192,fs:66,"fs-chunk-store":274,"immediate-chunk-store":244,lt_donthave:255,"memory-chunk-store":274,multistream:308,net:66,os:66,"parse-torrent":331,path:332,pump:348,"queue-microtask":353,"random-iterate":355,"run-parallel":380,"run-parallel-limit":379,"simple-get":393,"simple-sha1":410,throughput:474,"torrent-discovery":477,"torrent-piece":478,ut_metadata:484,ut_pex:66}],494:[function(e,t,i){(function(i){(function(){const{default:n}=e("bitfield"),r=e("debug"),s=e("simple-get"),a=e("lt_donthave"),o=e("simple-sha1"),c=e("bittorrent-protocol"),l=r("webtorrent:webconn"),u=e("../package.json").version;t.exports=class extends c{constructor(e,t){super(),this.url=e,this.connId=e,this.webPeerId=o.sync(e),this._torrent=t,this._init()}_init(){this.setKeepAlive(!0),this.use(a()),this.once("handshake",((e,t)=>{if(this.destroyed)return;this.handshake(e,this.webPeerId);const i=this._torrent.pieces.length,r=new n(i);for(let e=0;e<=i;e++)r.set(e,!0);this.bitfield(r)})),this.once("interested",(()=>{l("interested"),this.unchoke()})),this.on("uninterested",(()=>{l("uninterested")})),this.on("choke",(()=>{l("choke")})),this.on("unchoke",(()=>{l("unchoke")})),this.on("bitfield",(()=>{l("bitfield")})),this.lt_donthave.on("donthave",(()=>{l("donthave")})),this.on("request",((e,t,i,n)=>{l("request pieceIndex=%d offset=%d length=%d",e,t,i),this.httpRequest(e,t,i,((t,i)=>{if(t){this.lt_donthave.donthave(e);const t=setTimeout((()=>{this.destroyed||this.have(e)}),1e4);t.unref&&t.unref()}n(t,i)}))}))}httpRequest(e,t,n,r){const a=e*this._torrent.pieceLength+t,o=a+n-1,c=this._torrent.files;let p;if(c.length<=1)p=[{url:this.url,start:a,end:o}];else{const e=c.filter((e=>e.offset<=o&&e.offset+e.length>a));if(e.length<1)return r(new Error("Could not find file corresponding to web seed range request"));p=e.map((e=>{const t=e.offset+e.length-1;return{url:this.url+("/"===this.url[this.url.length-1]?"":"/")+e.path.replace(this._torrent.path,""),fileOffsetInRange:Math.max(e.offset-a,0),start:Math.max(a-e.offset,0),end:Math.min(t,o-e.offset)}}))}let d,f=0,h=!1;p.length>1&&(d=i.alloc(n)),p.forEach((i=>{const a=i.url,o=i.start,c=i.end;l("Requesting url=%s pieceIndex=%d offset=%d length=%d start=%d end=%d",a,e,t,n,o,c);const m={url:a,method:"GET",headers:{"user-agent":`WebTorrent/${u} (https://webtorrent.io)`,range:`bytes=${o}-${c}`},timeout:6e4};function b(e,t){if(e.statusCode<200||e.statusCode>=300){if(h)return;return h=!0,r(new Error(`Unexpected HTTP status code ${e.statusCode}`))}l("Got data of length %d",t.length),1===p.length?r(null,t):(t.copy(d,i.fileOffsetInRange),++f===p.length&&r(null,d))}s.concat(m,((e,t,i)=>{if(!h)return e?"undefined"==typeof window||a.startsWith(`${window.location.origin}/`)?(h=!0,r(e)):s.head(a,((t,i)=>{if(!h){if(t)return h=!0,r(t);if(i.statusCode<200||i.statusCode>=300)return h=!0,r(new Error(`Unexpected HTTP status code ${i.statusCode}`));if(i.url===a)return h=!0,r(e);m.url=i.url,s.concat(m,((e,t,i)=>{if(!h)return e?(h=!0,r(e)):void b(t,i)}))}})):void b(t,i)}))}))}destroy(){super.destroy(),this._torrent=null}}}).call(this)}).call(this,e("buffer").Buffer)},{"../package.json":495,bitfield:26,"bittorrent-protocol":27,buffer:109,debug:160,lt_donthave:255,"simple-get":393,"simple-sha1":410}],495:[function(e,t,i){t.exports={version:"1.8.22"}},{}],496:[function(e,t,i){t.exports=function e(t,i){if(t&&i)return e(t)(i);if("function"!=typeof t)throw new TypeError("need wrapper function");return Object.keys(t).forEach((function(e){n[e]=t[e]})),n;function n(){for(var e=new Array(arguments.length),i=0;i1080?(P.setProps({placement:"right"}),U.setProps({placement:"right"}),q.setProps({placement:"right"})):(P.setProps({placement:"top"}),U.setProps({placement:"top"}),q.setProps({placement:"top"}))}function H(e){G();try{console.info("Attempting parse"),l=n(e),W(),l.xs&&(console.info("Magnet includes xs, attempting remote parse"),F(l.xs))}catch(t){console.warn(t),"magnet"==c?(console.info("Attempting remote parse"),F(e)):(D.error("Problem parsing input. Is this a .torrent file?"),console.error("Problem parsing input"))}}function F(e){n.remote(e,(function(e,t){if(e)return D.error("Problem remotely fetching that file or parsing result"),console.warn(e),void G();c="remote-torrent-file",m.innerHTML='',b.setContent("Currently loaded information sourced from remotely fetched Torrent file"),l=t,W()}))}function W(){if(console.log(l),w.value=l.infoHash,v.value=l.name?l.name:"",l.created?(y.value=l.created.toISOString().slice(0,19),y.type="datetime-local"):y.type="text",_.value=l.createdBy?" by "+l.createdBy:"",x.value=l.comment?l.comment:"",M.innerHTML="",l.announce&&l.announce.length)for(let e=0;e',n.addEventListener("click",Z),t.appendChild(n),M.appendChild(t)}if(A.innerHTML="",l.urlList&&l.urlList.length)for(let e=0;e',n.addEventListener("click",Z),t.appendChild(n),A.appendChild(t)}if(T.innerHTML="",l.files&&l.files.length){if(C.style.display="none",l.files.length<100)for(let e of l.files){let t=K(s.lookup(e.name));T.appendChild(V(t,e.name,e.length))}else{for(let e=0;e<100;e++){let t=K(s.lookup(l.files[e].name));T.appendChild(V(t,l.files[e].name,l.files[e].length))}T.appendChild(V("","...and another "+(l.files.length-100)+" more files",""))}T.appendChild(V("folder-tree","",l.length)),q.setContent("Download Torrent file"),O.addEventListener("click",te),O.disabled=!1}else N.torrents.length>0?(C.style.display="none",T.innerHTML=''):(C.style.display="block",T.innerHTML=''),q.setContent("Files metadata is required to generate a Torrent file. Try fetching files list from WebTorrent."),O.removeEventListener("click",te),O.disabled=!0;B.setAttribute("data-clipboard-text",window.location.origin+"#"+n.toMagnetURI(l)),R.setAttribute("data-clipboard-text",n.toMagnetURI(l)),u.style.display="none",h.style.display="flex",window.location.hash=n.toMagnetURI(l),l.name?document.title="Torrent Parts | "+l.name:document.title="Torrent Parts | Inspect and edit what's in your Torrent file or Magnet link",b.enable()}function V(e,t,i){let n=document.createElement("tr"),s=document.createElement("td");e&&(s.innerHTML=''),n.appendChild(s);let a=document.createElement("td");a.innerHTML=t,n.appendChild(a);let o=document.createElement("td");return o.innerHTML=r.format(i,{decimalPlaces:1,unitSeparator:" "}),n.appendChild(o),n}function K(e){if(!e)return"file";switch(!0){case e.includes("msword"):case e.includes("wordprocessingml"):case e.includes("opendocument.text"):case e.includes("abiword"):return"file-word";case e.includes("ms-excel"):case e.includes("spreadsheet"):case e.includes("powerpoint"):case e.includes("presentation"):return"file-powerpoint";case e.includes("7z-"):case e.includes("iso9660"):case e.includes("zip"):case e.includes("octet-stream"):return"file-archive";case e.includes("csv"):return"file-csv";case e.includes("pdf"):return"file-pdf";case e.includes("font"):return"file-contract";case e.includes("text"):case e.includes("subrip"):case e.includes("vtt"):return"file-alt";case e.includes("audio"):return"file-audio";case e.includes("image"):return"file-image";case e.includes("video"):return"file-video";default:return"file"}}function $(e){this.dataset.group?l[this.dataset.group][this.dataset.index]=this.value?this.value:"":l[this.id]=this.value?this.value:"",window.location.hash=n.toMagnetURI(l),Q()}function G(){document.getElementById("magnet").value="",document.getElementById("torrent").value="",u.style.display="flex",h.style.display="none",v.value="",y.value="",_.value="",x.value="",w.value="",M.innerHTML="",A.innerHTML="",N.torrents.forEach((e=>e.destroy())),C.style.display="block",T.innerHTML="",window.location.hash="",B.setAttribute("data-clipboard-text",""),R.setAttribute("data-clipboard-text",""),document.title="Torrent Parts | Inspect and edit what's in your Torrent file or Magnet link",b.disable()}async function X(){k.className="disabled",k.innerHTML="Adding...";try{let e=await fetch("https://newtrackon.com/api/stable"),t=await e.text();l.announce=l.announce.concat(t.split("\n\n")),l.announce.push("http://bt1.archive.org:6969/announce"),l.announce.push("http://bt2.archive.org:6969/announce"),l.announce=l.announce.filter(((e,t)=>e&&l.announce.indexOf(e)===t)),D.success("Added known working trackers from newTrackon"),Q()}catch(e){D.error("Problem fetching trackers from newTrackon"),console.warn(e)}k.className="",k.innerHTML="Add Known Working Trackers",W()}function Y(){l[this.dataset.type].unshift(""),W()}function Z(){l[this.parentElement.className].splice(this.parentElement.dataset.index,1),W()}function J(e){l[e]=[],Q(),W()}function Q(){l.created=new Date,l.createdBy="Torrent Parts ",l.created?(y.value=l.created.toISOString().slice(0,19),y.type="datetime-local"):y.type="text",_.value=l.createdBy?" by "+l.createdBy:""}function ee(){console.info("Attempting fetching files from Webtorrent..."),C.style.display="none",l.announce.push("wss://tracker.webtorrent.io"),l.announce.push("wss://tracker.openwebtorrent.com"),l.announce.push("wss://tracker.btorrent.xyz"),l.announce.push("wss://tracker.fastcast.nz"),l.announce=l.announce.filter(((e,t)=>e&&l.announce.indexOf(e)===t)),N.add(n.toMagnetURI(l),(e=>{l.info=Object.assign({},e.info),l.files=e.files,l.infoBuffer=e.infoBuffer,l.length=e.length,l.lastPieceLength=e.lastPieceLength,Q(),W(),D.success("Fetched file details from Webtorrent peers"),e.destroy()})),W()}function te(){let e=n.toTorrentFile(l);if(null!==e&&navigator.msSaveBlob)return navigator.msSaveBlob(new Blob([e],{type:"application/x-bittorrent"}),l.name+".torrent");let t=document.createElement("a");t.style.display="none";let i=window.URL.createObjectURL(new Blob([e],{type:"application/x-bittorrent"}));t.setAttribute("href",i),t.setAttribute("download",l.name+".torrent"),document.body.appendChild(t),t.click(),window.URL.revokeObjectURL(i),t.remove()}window.addEventListener("resize",z),z(),document.addEventListener("DOMContentLoaded",(function(){document.getElementById("magnet").addEventListener("keyup",(function(e){e.preventDefault(),"Enter"===e.key&&(c="magnet",m.innerHTML='',b.setContent("Currently loaded information sourced from Magnet URL"),H(magnet.value))})),document.getElementById("torrent").addEventListener("change",(function(e){e.preventDefault(),e.target.files[0].arrayBuffer().then((function(e){c="torrent-file",m.innerHTML='',b.setContent("Currently loaded information sourced from Torrent file"),H(t.from(e))}))})),document.addEventListener("dragover",(function(e){e.preventDefault()})),document.addEventListener("drop",(function(e){e.preventDefault(),e.dataTransfer.items[0].getAsFile().arrayBuffer().then((function(e){c="torrent-file",m.innerHTML='',b.setContent("Currently loaded information sourced from Torrent file"),H(t.from(e))}))})),p.addEventListener("click",(function(e){e.preventDefault(),D.success("Parsing Ubuntu 20.04 Magnet URL"),c="magnet",m.innerHTML='',b.setContent("Currently loaded information sourced from Magnet URL"),H("magnet:?xt=urn:btih:9fc20b9e98ea98b4a35e6223041a5ef94ea27809&dn=ubuntu-20.04-desktop-amd64.iso&tr=https%3A%2F%2Ftorrent.ubuntu.com%2Fannounce&tr=https%3A%2F%2Fipv6.torrent.ubuntu.com%2Fannounce")})),d.addEventListener("click",(async function(e){e.preventDefault(),D.success("Fetching and Parsing “The WIRED CD” Torrent File..."),c="remote-torrent-file",m.innerHTML='',b.setContent("Currently loaded information sourced from remotely fetched Torrent file"),F("https://webtorrent.io/torrents/wired-cd.torrent")})),f.addEventListener("click",(async function(e){e.preventDefault(),D.success("Parsing Jack Johnson Archive.org Torrent File");let i=await fetch("/ext/jj2008-06-14.mk4_archive.torrent"),n=await i.arrayBuffer();c="torrent-file",m.innerHTML='',b.setContent("Currently loaded information sourced from Torrent file"),H(t.from(n))}));let e=new i("#copyURL");e.on("success",(function(e){D.success("Copied site URL to clipboard!"),console.info(e)})),e.on("failure",(function(e){D.error("Problem copying to clipboard"),console.warn(e)}));let n=new i("#copyMagnet");n.on("success",(function(e){D.success("Copied Magnet URL to clipboard!")})),n.on("failure",(function(e){D.error("Problem copying to clipboard"),console.warn(e)})),v.addEventListener("input",$),v.addEventListener("change",$),v.addEventListener("reset",$),v.addEventListener("paste",$),g.addEventListener("click",G),x.addEventListener("input",$),x.addEventListener("change",$),x.addEventListener("reset",$),x.addEventListener("paste",$),k.addEventListener("click",X),E.addEventListener("click",Y),S.addEventListener("click",(()=>J("announce"))),j.addEventListener("click",Y),I.addEventListener("click",(()=>J("urlList"))),C.addEventListener("click",ee),o("[data-tippy-content]",{theme:"torrent-parts",animation:"shift-away-subtle"}),b.disable(),window.location.hash&&(c="shared-url",m.innerHTML='',b.setContent("Currently loaded information sourced from shared torrent.parts link"),H(window.location.hash.split("#")[1]))}))}).call(this)}).call(this,e("buffer").Buffer)},{buffer:109,bytes:115,clipboard:134,"mime-types":279,"parse-torrent":331,"tippy.js":475,webtorrent:488}]},{},[498]); \ No newline at end of file +const n=e("events"),r=e("path"),s=e("simple-concat"),a=e("create-torrent"),o=e("debug"),c=e("bittorrent-dht/client"),l=e("load-ip-set"),u=e("run-parallel"),p=e("parse-torrent"),d=e("simple-peer"),f=e("queue-microtask"),h=e("randombytes"),m=e("simple-sha1"),b=e("throughput"),{ThrottleGroup:v}=e("speed-limiter"),g=e("./lib/conn-pool.js"),y=e("./lib/torrent.js"),{version:_}=e("./package.json"),x=o("webtorrent"),w=_.replace(/\d*./g,(e=>("0"+e%100).slice(-2))).slice(0,4),k=`-WW${w}-`;class E extends n{constructor(t={}){super(),"string"==typeof t.peerId?this.peerId=t.peerId:i.isBuffer(t.peerId)?this.peerId=t.peerId.toString("hex"):this.peerId=i.from(k+h(9).toString("base64")).toString("hex"),this.peerIdBuffer=i.from(this.peerId,"hex"),"string"==typeof t.nodeId?this.nodeId=t.nodeId:i.isBuffer(t.nodeId)?this.nodeId=t.nodeId.toString("hex"):this.nodeId=h(20).toString("hex"),this.nodeIdBuffer=i.from(this.nodeId,"hex"),this._debugId=this.peerId.toString("hex").substring(0,7),this.destroyed=!1,this.listening=!1,this.torrentPort=t.torrentPort||0,this.dhtPort=t.dhtPort||0,this.tracker=void 0!==t.tracker?t.tracker:{},this.lsd=!1!==t.lsd,this.torrents=[],this.maxConns=Number(t.maxConns)||55,this.utp=E.UTP_SUPPORT&&!1!==t.utp,this._downloadLimit=Math.max("number"==typeof t.downloadLimit?t.downloadLimit:-1,-1),this._uploadLimit=Math.max("number"==typeof t.uploadLimit?t.uploadLimit:-1,-1),this.serviceWorker=null,this.workerKeepAliveInterval=null,this.workerPortCount=0,!0===t.secure&&e("./lib/peer").enableSecure(),this._debug("new webtorrent (peerId %s, nodeId %s, port %s)",this.peerId,this.nodeId,this.torrentPort),this.throttleGroups={down:new v({rate:Math.max(this._downloadLimit,0),enabled:this._downloadLimit>=0}),up:new v({rate:Math.max(this._uploadLimit,0),enabled:this._uploadLimit>=0})},this.tracker&&("object"!=typeof this.tracker&&(this.tracker={}),globalThis.WRTC&&!this.tracker.wrtc&&(this.tracker.wrtc=globalThis.WRTC)),"function"==typeof g?this._connPool=new g(this):f((()=>{this._onListening()})),this._downloadSpeed=b(),this._uploadSpeed=b(),!1!==t.dht&&"function"==typeof c?(this.dht=new c(Object.assign({},{nodeId:this.nodeId},t.dht)),this.dht.once("error",(e=>{this._destroy(e)})),this.dht.once("listening",(()=>{const e=this.dht.address();e&&(this.dhtPort=e.port)})),this.dht.setMaxListeners(0),this.dht.listen(this.dhtPort)):this.dht=!1,this.enableWebSeeds=!1!==t.webSeeds;const n=()=>{this.destroyed||(this.ready=!0,this.emit("ready"))};"function"==typeof l&&null!=t.blocklist?l(t.blocklist,{headers:{"user-agent":`WebTorrent/${_} (https://webtorrent.io)`}},((e,t)=>{if(e)return console.error(`Failed to load blocklist: ${e.message}`);this.blocked=t,n()})):f(n)}loadWorker(e,t=(()=>{})){if(!(e instanceof ServiceWorker))throw new Error("Invalid worker registration");if("activated"!==e.state)throw new Error("Worker isn't activated");this.serviceWorker=e,navigator.serviceWorker.addEventListener("message",(e=>{const{data:t}=e;if(!t.type||"webtorrent"===!t.type||!t.url)return null;let[i,...n]=t.url.slice(t.url.indexOf(t.scope+"webtorrent/")+11+t.scope.length).split("/");if(n=decodeURI(n.join("/")),!i||!n)return null;const[r]=e.ports,s=this.get(i)&&this.get(i).files.find((e=>e.path===n));if(!s)return null;const[a,o,c]=s._serve(t),l=o&&o[Symbol.asyncIterator](),u=()=>{r.onmessage=null,o&&o.destroy(),c&&c.destroy(),this.workerPortCount--,this.workerPortCount||(clearInterval(this.workerKeepAliveInterval),this.workerKeepAliveInterval=null)};r.onmessage=async e=>{if(e.data){let e;try{e=(await l.next()).value}catch(e){}r.postMessage(e),e||u(),this.workerKeepAliveInterval||(this.workerKeepAliveInterval=setInterval((()=>fetch(`${this.serviceWorker.scriptURL.slice(0,this.serviceWorker.scriptURL.lastIndexOf("/")+1).slice(window.location.origin.length)}webtorrent/keepalive/`)),2e4))}else u()},this.workerPortCount++,r.postMessage(a)})),t(this.serviceWorker)}get downloadSpeed(){return this._downloadSpeed()}get uploadSpeed(){return this._uploadSpeed()}get progress(){const e=this.torrents.filter((e=>1!==e.progress));return e.reduce(((e,t)=>e+t.downloaded),0)/(e.reduce(((e,t)=>e+(t.length||0)),0)||1)}get ratio(){return this.torrents.reduce(((e,t)=>e+t.uploaded),0)/(this.torrents.reduce(((e,t)=>e+t.received),0)||1)}get(e){if(e instanceof y){if(this.torrents.includes(e))return e}else{let t;try{t=p(e)}catch(e){}if(!t)return null;if(!t.infoHash)throw new Error("Invalid torrent identifier");for(const e of this.torrents)if(e.infoHash===t.infoHash)return e}return null}add(e,t={},i=(()=>{})){if(this.destroyed)throw new Error("client is destroyed");"function"==typeof t&&([t,i]=[{},t]);const n=()=>{if(!this.destroyed)for(const e of this.torrents)if(e.infoHash===s.infoHash&&e!==s)return void s._destroy(new Error(`Cannot add duplicate torrent ${s.infoHash}`))},r=()=>{this.destroyed||(i(s),this.emit("torrent",s))};this._debug("add"),t=t?Object.assign({},t):{};const s=new y(e,this,t);return this.torrents.push(s),s.once("_infoHash",n),s.once("ready",r),s.once("close",(function e(){s.removeListener("_infoHash",n),s.removeListener("ready",r),s.removeListener("close",e)})),s}seed(e,t,i){if(this.destroyed)throw new Error("client is destroyed");"function"==typeof t&&([t,i]=[{},t]),this._debug("seed"),(t=t?Object.assign({},t):{}).skipVerify=!0;const n="string"==typeof e;n&&(t.path=r.dirname(e)),t.createdBy||(t.createdBy=`WebTorrent/${w}`);const o=e=>{this._debug("on seed"),"function"==typeof i&&i(e),e.emit("seed"),this.emit("seed",e)},c=this.add(null,t,(e=>{const i=[i=>{if(n||t.preloadedStore)return i();e.load(l,i)}];this.dht&&i.push((t=>{e.once("dhtAnnounce",t)})),u(i,(t=>{if(!this.destroyed)return t?e._destroy(t):void o(e)}))}));let l;var p;return p=e,"undefined"!=typeof FileList&&p instanceof FileList?e=Array.from(e):Array.isArray(e)||(e=[e]),u(e.map((e=>i=>{!t.preloadedStore&&function(e){return"object"==typeof e&&null!=e&&"function"==typeof e.pipe}(e)?s(e,((t,n)=>{if(t)return i(t);n.name=e.name,i(null,n)})):i(null,e)})),((e,n)=>{if(!this.destroyed)return e?c._destroy(e):void a.parseInput(n,t,((e,r)=>{if(!this.destroyed){if(e)return c._destroy(e);l=r.map((e=>e.getStream)),a(n,t,((e,t)=>{if(this.destroyed)return;if(e)return c._destroy(e);const n=this.get(t);n?(console.warn("A torrent with the same id is already being seeded"),c._destroy(),"function"==typeof i&&i(n)):c._onTorrentId(t)}))}}))})),c}remove(e,t,i){if("function"==typeof t)return this.remove(e,null,t);this._debug("remove");if(!this.get(e))throw new Error(`No torrent with id ${e}`);this._remove(e,t,i)}_remove(e,t,i){if("function"==typeof t)return this._remove(e,null,t);const n=this.get(e);n&&(this.torrents.splice(this.torrents.indexOf(n),1),n.destroy(t,i),this.dht&&this.dht._tables.remove(n.infoHash))}address(){return this.listening?this._connPool?this._connPool.tcpServer.address():{address:"0.0.0.0",family:"IPv4",port:0}:null}throttleDownload(e){return e=Number(e),!(isNaN(e)||!isFinite(e)||e<-1)&&(this._downloadLimit=e,this._downloadLimit<0?this.throttleGroups.down.setEnabled(!1):(this.throttleGroups.down.setEnabled(!0),void this.throttleGroups.down.setRate(this._downloadLimit)))}throttleUpload(e){return e=Number(e),!(isNaN(e)||!isFinite(e)||e<-1)&&(this._uploadLimit=e,this._uploadLimit<0?this.throttleGroups.up.setEnabled(!1):(this.throttleGroups.up.setEnabled(!0),void this.throttleGroups.up.setRate(this._uploadLimit)))}destroy(e){if(this.destroyed)throw new Error("client already destroyed");this._destroy(null,e)}_destroy(e,t){this._debug("client destroy"),this.destroyed=!0;const i=this.torrents.map((e=>t=>{e.destroy(t)}));this._connPool&&i.push((e=>{this._connPool.destroy(e)})),this.dht&&i.push((e=>{this.dht.destroy(e)})),u(i,t),e&&this.emit("error",e),this.torrents=[],this._connPool=null,this.dht=null,this.throttleGroups.down.destroy(),this.throttleGroups.up.destroy()}_onListening(){if(this._debug("listening"),this.listening=!0,this._connPool){const e=this._connPool.tcpServer.address();e&&(this.torrentPort=e.port)}this.emit("listening")}_debug(){const e=[].slice.call(arguments);e[0]=`[${this._debugId}] ${e[0]}`,x(...e)}_getByHash(e){for(const t of this.torrents)if(t.infoHashHash||(t.infoHashHash=m.sync(i.from("72657132"+t.infoHash,"hex"))),e===t.infoHashHash)return t;return null}}E.WEBRTC_SUPPORT=d.WEBRTC_SUPPORT,E.UTP_SUPPORT=g.UTP_SUPPORT,E.VERSION=_,t.exports=E}).call(this)}).call(this,e("buffer").Buffer)},{"./lib/conn-pool.js":66,"./lib/peer":491,"./lib/torrent.js":493,"./package.json":495,"bittorrent-dht/client":66,buffer:109,"create-torrent":143,debug:160,events:192,"load-ip-set":66,"parse-torrent":331,path:332,"queue-microtask":353,randombytes:356,"run-parallel":380,"simple-concat":392,"simple-peer":394,"simple-sha1":410,"speed-limiter":428,throughput:474}],489:[function(e,t,i){const n=e("stream"),r=e("debug"),s=e("end-of-stream"),a=r("webtorrent:file-stream");class o extends n.Readable{constructor(e,t){super(t),this._torrent=e._torrent;const i=t&&t.start||0,n=t&&t.end&&t.end{this._notify()})),s(this,(e=>{this.destroy(e)}))}_read(){this._reading||(this._reading=!0,this._notify())}_notify(){if(!this._reading||0===this._missing)return;if(!this._torrent.bitfield.get(this._piece))return this._torrent.critical(this._piece,this._piece+this._criticalLength);if(this._notifying)return;if(this._notifying=!0,this._torrent.destroyed)return this.destroy(new Error("Torrent removed"));const e=this._piece,t={};e===this._torrent.pieces.length-1&&(t.length=this._torrent.lastPieceLength),this._torrent.store.get(e,t,((t,i)=>{if(this._notifying=!1,!this.destroyed){if(a("read %s (length %s) (err %s)",e,i&&i.length,t&&t.message),t)return this.destroy(t);this._offset&&(i=i.slice(this._offset),this._offset=0),this._missing{const s=r===e.length-1?n:i;return t.get(r)?s:s-e[r].missing};let o=0;for(let t=r;t<=s;t+=1){const c=a(t);if(o+=c,t===r){const e=this.offset%i;o-=Math.min(e,c)}if(t===s){const t=(s===e.length-1?n:i)-(this.offset+this.length)%i;o-=Math.min(t,c)}}return o}get progress(){return this.length?this.downloaded/this.length:0}select(e){0!==this.length&&this._torrent.select(this._startPiece,this._endPiece,e)}deselect(){0!==this.length&&this._torrent.deselect(this._startPiece,this._endPiece,!1)}createReadStream(e){if(0===this.length){const e=new r;return u((()=>{e.end()})),e}const t=new h(this,e);return this._fileStreams.add(t),t.once("close",(()=>{this._fileStreams.delete(t)})),t}getBuffer(e){l(this.createReadStream(),this.length,e)}getBlob(e){if("undefined"==typeof window)throw new Error("browser-only method");o(this.createReadStream(),this._getMimeType()).then((t=>e(null,t)),(t=>e(t)))}getBlobURL(e){if("undefined"==typeof window)throw new Error("browser-only method");c(this.createReadStream(),this._getMimeType()).then((t=>e(null,t)),(t=>e(t)))}appendTo(e,t,i){if("undefined"==typeof window)throw new Error("browser-only method");a.append(this,e,t,i)}renderTo(e,t,i){if("undefined"==typeof window)throw new Error("browser-only method");a.render(this,e,t,i)}_serve(e){const t={status:200,headers:{"Accept-Ranges":"bytes","Content-Type":d.getType(this.name),"Cache-Control":"no-cache, no-store, must-revalidate, max-age=0",Expires:"0"},body:"HEAD"===e.method?"":"STREAM"};"document"===e.destination&&(t.headers["Content-Type"]="application/octet-stream",t.headers["Content-Disposition"]="attachment",t.body="DOWNLOAD");let i=p(this.length,e.headers.range||"");i.constructor===Array?(t.status=206,i=i[0],t.headers["Content-Range"]=`bytes ${i.start}-${i.end}/${this.length}`,t.headers["Content-Length"]=""+(i.end-i.start+1)):t.headers["Content-Length"]=this.length;const n="GET"===e.method&&this.createReadStream(i);let r=null;return n&&this.emit("stream",{stream:n,req:e,file:this},(e=>{r=e,f(e,(()=>{e&&e.destroy(),n.destroy()}))})),[t,r||n,r&&n]}getStreamURL(e=(()=>{})){if("undefined"==typeof window)throw new Error("browser-only method");if(!this._serviceWorker)throw new Error("No worker registered");if("activated"!==this._serviceWorker.state)throw new Error("Worker isn't activated");e(null,`${this._serviceWorker.scriptURL.slice(0,this._serviceWorker.scriptURL.lastIndexOf("/")+1).slice(window.location.origin.length)}webtorrent/${this._torrent.infoHash}/${encodeURI(this.path)}`)}streamTo(e,t=(()=>{})){if("undefined"==typeof window)throw new Error("browser-only method");if(!this._serviceWorker)throw new Error("No worker registered");if("activated"!==this._serviceWorker.state)throw new Error("Worker isn't activated");const i=this._serviceWorker.scriptURL.slice(0,this._serviceWorker.scriptURL.lastIndexOf("/")+1).slice(window.location.origin.length);e.src=`${i}webtorrent/${this._torrent.infoHash}/${encodeURI(this.path)}`,t(null,e)}_getMimeType(){return a.mime[s.extname(this.name).toLowerCase()]}_destroy(){this._destroyed=!0,this._torrent=null;for(const e of this._fileStreams)e.destroy();this._fileStreams.clear()}}},{"./file-stream.js":489,"end-of-stream":190,events:192,mime:281,path:332,"queue-microtask":353,"range-parser":358,"render-media":376,stream:433,"stream-to-blob":468,"stream-to-blob-url":467,"stream-with-known-length-to-buffer":469}],491:[function(e,t,i){const n=e("events"),{Transform:r}=e("stream"),s=e("unordered-array-remove"),a=e("debug"),o=e("bittorrent-protocol"),c=a("webtorrent:peer");let l=!1;i.enableSecure=()=>{l=!0},i.createWebRTCPeer=(e,t,i)=>{const n=new d(e.id,"webrtc");if(n.conn=e,n.swarm=t,n.throttleGroups=i,n.conn.connected)n.onConnect();else{const e=()=>{n.conn.removeListener("connect",t),n.conn.removeListener("error",i)},t=()=>{e(),n.onConnect()},i=t=>{e(),n.destroy(t)};n.conn.once("connect",t),n.conn.once("error",i),n.startConnectTimeout()}return n},i.createTCPIncomingPeer=(e,t)=>u(e,"tcpIncoming",t),i.createUTPIncomingPeer=(e,t)=>u(e,"utpIncoming",t),i.createTCPOutgoingPeer=(e,t,i)=>p(e,t,"tcpOutgoing",i),i.createUTPOutgoingPeer=(e,t,i)=>p(e,t,"utpOutgoing",i);const u=(e,t,i)=>{const n=`${e.remoteAddress}:${e.remotePort}`,r=new d(n,t);return r.conn=e,r.addr=n,r.throttleGroups=i,r.onConnect(),r},p=(e,t,i,n)=>{const r=new d(e,i);return r.addr=e,r.swarm=t,r.throttleGroups=n,r};i.createWebSeedPeer=(e,t,i,n)=>{const r=new d(t,"webSeed");return r.swarm=i,r.conn=e,r.throttleGroups=n,r.onConnect(),r};class d extends n{constructor(e,t){super(),this.id=e,this.type=t,c("new %s Peer %s",t,e),this.addr=null,this.conn=null,this.swarm=null,this.wire=null,this.connected=!1,this.destroyed=!1,this.timeout=null,this.retries=0,this.sentPe1=!1,this.sentPe2=!1,this.sentPe3=!1,this.sentPe4=!1,this.sentHandshake=!1}onConnect(){if(this.destroyed)return;this.connected=!0,c("Peer %s connected",this.id),clearTimeout(this.connectTimeout);const e=this.conn;e.once("end",(()=>{this.destroy()})),e.once("close",(()=>{this.destroy()})),e.once("finish",(()=>{this.destroy()})),e.once("error",(e=>{this.destroy(e)}));const t=this.wire=new o(this.type,this.retries,l);t.once("end",(()=>{this.destroy()})),t.once("close",(()=>{this.destroy()})),t.once("finish",(()=>{this.destroy()})),t.once("error",(e=>{this.destroy(e)})),t.once("pe1",(()=>{this.onPe1()})),t.once("pe2",(()=>{this.onPe2()})),t.once("pe3",(()=>{this.onPe3()})),t.once("pe4",(()=>{this.onPe4()})),t.once("handshake",((e,t)=>{this.onHandshake(e,t)})),this.startHandshakeTimeout(),this.setThrottlePipes(),this.swarm&&("tcpOutgoing"===this.type?l&&0===this.retries&&!this.sentPe1?this.sendPe1():this.sentHandshake||this.handshake():"tcpIncoming"===this.type||this.sentHandshake||this.handshake())}sendPe1(){this.wire.sendPe1(),this.sentPe1=!0}onPe1(){this.sendPe2()}sendPe2(){this.wire.sendPe2(),this.sentPe2=!0}onPe2(){this.sendPe3()}sendPe3(){this.wire.sendPe3(this.swarm.infoHash),this.sentPe3=!0}onPe3(e){this.swarm&&(this.swarm.infoHashHash!==e&&this.destroy(new Error("unexpected crypto handshake info hash for this swarm")),this.sendPe4())}sendPe4(){this.wire.sendPe4(this.swarm.infoHash),this.sentPe4=!0}onPe4(){this.sentHandshake||this.handshake()}clearPipes(){this.conn.unpipe(),this.wire.unpipe()}setThrottlePipes(){const e=this;this.conn.pipe(this.throttleGroups.down.throttle()).pipe(new r({transform(t,i,n){e.emit("download",t.length),e.destroyed||n(null,t)}})).pipe(this.wire).pipe(this.throttleGroups.up.throttle()).pipe(new r({transform(t,i,n){e.emit("upload",t.length),e.destroyed||n(null,t)}})).pipe(this.conn)}onHandshake(e,t){if(!this.swarm)return;if(this.destroyed)return;if(this.swarm.destroyed)return this.destroy(new Error("swarm already destroyed"));if(e!==this.swarm.infoHash)return this.destroy(new Error("unexpected handshake info hash for this swarm"));if(t===this.swarm.peerId)return this.destroy(new Error("refusing to connect to ourselves"));c("Peer %s got handshake %s",this.id,e),clearTimeout(this.handshakeTimeout),this.retries=0;let i=this.addr;!i&&this.conn.remoteAddress&&this.conn.remotePort&&(i=`${this.conn.remoteAddress}:${this.conn.remotePort}`),this.swarm._onWire(this.wire,i),this.swarm&&!this.swarm.destroyed&&(this.sentHandshake||this.handshake())}handshake(){const e={dht:!this.swarm.private&&!!this.swarm.client.dht,fast:!0};this.wire.handshake(this.swarm.infoHash,this.swarm.client.peerId,e),this.sentHandshake=!0}startConnectTimeout(){clearTimeout(this.connectTimeout);const e={webrtc:25e3,tcpOutgoing:5e3,utpOutgoing:5e3};this.connectTimeout=setTimeout((()=>{this.destroy(new Error("connect timeout"))}),e[this.type]),this.connectTimeout.unref&&this.connectTimeout.unref()}startHandshakeTimeout(){clearTimeout(this.handshakeTimeout),this.handshakeTimeout=setTimeout((()=>{this.destroy(new Error("handshake timeout"))}),25e3),this.handshakeTimeout.unref&&this.handshakeTimeout.unref()}destroy(e){if(this.destroyed)return;this.destroyed=!0,this.connected=!1,c("destroy %s %s (error: %s)",this.type,this.id,e&&(e.message||e)),clearTimeout(this.connectTimeout),clearTimeout(this.handshakeTimeout);const t=this.swarm,i=this.conn,n=this.wire;this.swarm=null,this.conn=null,this.wire=null,t&&n&&s(t.wires,t.wires.indexOf(n)),i&&(i.on("error",(()=>{})),i.destroy()),n&&n.destroy(),t&&t.removePeer(this.id)}}},{"bittorrent-protocol":27,debug:160,events:192,stream:433,"unordered-array-remove":481}],492:[function(e,t,i){t.exports=class{constructor(e){this._torrent=e,this._numPieces=e.pieces.length,this._pieces=new Array(this._numPieces),this._onWire=e=>{this.recalculate(),this._initWire(e)},this._onWireHave=e=>{this._pieces[e]+=1},this._onWireBitfield=()=>{this.recalculate()},this._torrent.wires.forEach((e=>{this._initWire(e)})),this._torrent.on("wire",this._onWire),this.recalculate()}getRarestPiece(e){let t=[],i=1/0;for(let n=0;n{this._cleanupWireEvents(e)})),this._torrent=null,this._pieces=null,this._onWire=null,this._onWireHave=null,this._onWireBitfield=null}_initWire(e){e._onClose=()=>{this._cleanupWireEvents(e);for(let t=0;t0&&(i=Math.min(i,t))}return i}function $(){}t.exports=class extends r{constructor(e,t,i){super(),this._debugId="unknown infohash",this.client=t,this.announce=i.announce,this.urlList=i.urlList,this.path=i.path||V,this.addUID=i.addUID||!1,this.skipVerify=!!i.skipVerify,this._store=i.store||b,this._preloadedStore=i.preloadedStore||null,this._storeCacheSlots=void 0!==i.storeCacheSlots?i.storeCacheSlots:20,this._destroyStoreOnDestroy=i.destroyStoreOnDestroy||!1,this._getAnnounceOpts=i.getAnnounceOpts,"boolean"==typeof i.private&&(this.private=i.private),this.strategy=i.strategy||"sequential",this.maxWebConns=i.maxWebConns||4,this._rechokeNumSlots=!1===i.uploads||0===i.uploads?0:+i.uploads||10,this._rechokeOptimisticWire=null,this._rechokeOptimisticTime=0,this._rechokeIntervalId=null,this.ready=!1,this.destroyed=!1,this.paused=i.paused||!1,this.done=!1,this.metadata=null,this.store=null,this.storeOpts=i.storeOpts,this.files=[],this.pieces=[],this._amInterested=!1,this._selections=[],this._critical=[],this.wires=[],this._queue=[],this._peers={},this._peersLength=0,this.received=0,this.uploaded=0,this._downloadSpeed=T(),this._uploadSpeed=T(),this._servers=[],this._xsRequests=[],this._fileModtimes=i.fileModtimes,null!==e&&this._onTorrentId(e),this._debug("new torrent")}get timeRemaining(){return this.done?0:0===this.downloadSpeed?1/0:(this.length-this.downloaded)/this.downloadSpeed*1e3}get downloaded(){if(!this.bitfield)return 0;let e=0;for(let t=0,i=this.pieces.length;t{this.destroyed||this._onParsedTorrent(t)}))):E.remote(e,((e,t)=>{if(!this.destroyed)return e?this._destroy(e):void this._onParsedTorrent(t)}))}_onParsedTorrent(e){if(!this.destroyed){if(this._processParsedTorrent(e),!this.infoHash)return this._destroy(new Error("Malformed torrent data: No info hash"));this._rechokeIntervalId=setInterval((()=>{this._rechoke()}),1e4),this._rechokeIntervalId.unref&&this._rechokeIntervalId.unref(),this.emit("_infoHash",this.infoHash),this.destroyed||(this.emit("infoHash",this.infoHash),this.destroyed||(this.client.listening?this._onListening():this.client.once("listening",(()=>{this._onListening()}))))}}_processParsedTorrent(e){this._debugId=e.infoHash.toString("hex").substring(0,7),void 0!==this.private&&(e.private=this.private),this.announce&&(e.announce=e.announce.concat(this.announce)),this.client.tracker&&n.WEBTORRENT_ANNOUNCE&&!e.private&&(e.announce=e.announce.concat(n.WEBTORRENT_ANNOUNCE)),this.urlList&&(e.urlList=e.urlList.concat(this.urlList)),e.announce=Array.from(new Set(e.announce)),e.urlList=Array.from(new Set(e.urlList)),Object.assign(this,e),this.magnetURI=E.toMagnetURI(e),this.torrentFile=E.toTorrentFile(e)}_onListening(){this.destroyed||(this.info?this._onMetadata(this):(this.xs&&this._getMetadataFromServer(),this._startDiscovery()))}_startDiscovery(){if(this.discovery||this.destroyed)return;let e=this.client.tracker;e&&(e=Object.assign({},this.client.tracker,{getAnnounceOpts:()=>{if(this.destroyed)return;const e={uploaded:this.uploaded,downloaded:this.downloaded,left:Math.max(this.length-this.downloaded,0)};return this.client.tracker.getAnnounceOpts&&Object.assign(e,this.client.tracker.getAnnounceOpts()),this._getAnnounceOpts&&Object.assign(e,this._getAnnounceOpts()),e}})),this.peerAddresses&&this.peerAddresses.forEach((e=>this.addPeer(e))),this.discovery=new m({infoHash:this.infoHash,announce:this.announce,peerId:this.client.peerId,dht:!this.private&&this.client.dht,tracker:e,port:this.client.torrentPort,userAgent:W,lsd:this.client.lsd}),this.discovery.on("error",(e=>{this._destroy(e)})),this.discovery.on("peer",((e,t)=>{this._debug("peer %s discovered via %s",e,t),"string"==typeof e&&this.done||this.addPeer(e)})),this.discovery.on("trackerAnnounce",(()=>{this.emit("trackerAnnounce"),0===this.numPeers&&this.emit("noPeers","tracker")})),this.discovery.on("dhtAnnounce",(()=>{this.emit("dhtAnnounce"),0===this.numPeers&&this.emit("noPeers","dht")})),this.discovery.on("warning",(e=>{this.emit("warning",e)}))}_getMetadataFromServer(){const e=this,t=(Array.isArray(this.xs)?this.xs:[this.xs]).map((t=>i=>{!function(t,i){if(0!==t.indexOf("http://")&&0!==t.indexOf("https://"))return e.emit("warning",new Error(`skipping non-http xs param: ${t}`)),i(null);const n={url:t,method:"GET",headers:{"user-agent":W}};let r;try{r=v.concat(n,s)}catch(n){return e.emit("warning",new Error(`skipping invalid url xs param: ${t}`)),i(null)}function s(n,r,s){if(e.destroyed)return i(null);if(e.metadata)return i(null);if(n)return e.emit("warning",new Error(`http error from xs param: ${t}`)),i(null);if(200!==r.statusCode)return e.emit("warning",new Error(`non-200 status code ${r.statusCode} from xs param: ${t}`)),i(null);let a;try{a=E(s)}catch(n){}return a?a.infoHash!==e.infoHash?(e.emit("warning",new Error(`got torrent file with incorrect info hash from xs param: ${t}`)),i(null)):(e._onMetadata(a),void i(null)):(e.emit("warning",new Error(`got invalid torrent file from xs param: ${t}`)),i(null))}e._xsRequests.push(r)}(t,i)}));w(t)}_onMetadata(e){if(this.metadata||this.destroyed)return;let t;if(this._debug("got metadata"),this._xsRequests.forEach((e=>{e.abort()})),this._xsRequests=[],e&&e.infoHash)t=e;else try{t=E(e)}catch(e){return this._destroy(e)}this._processParsedTorrent(t),this.metadata=this.torrentFile,this.client.enableWebSeeds&&this.urlList.forEach((e=>{this.addWebSeed(e)})),this._rarityMap=new O(this),this.files=this.files.map((e=>new R(this,e)));let i=this._preloadedStore;if(i||(i=new this._store(this.pieceLength,{...this.storeOpts,torrent:this,path:this.path,files:this.files,length:this.length,name:this.name+" - "+this.infoHash.slice(0,8),addUID:this.addUID})),this._storeCacheSlots>0&&!(i instanceof _)&&(i=new p(i,{max:this._storeCacheSlots})),this.store=new g(i),this.so?this.files.forEach(((e,t)=>{this.so.includes(t)?this.files[t].select():this.files[t].deselect()})):0!==this.pieces.length&&this.select(0,this.pieces.length-1,!1),this._hashes=this.pieces,this.pieces=this.pieces.map(((e,t)=>{const i=t===this.pieces.length-1?this.lastPieceLength:this.pieceLength;return new S(i)})),this._reservations=this.pieces.map((()=>[])),this.bitfield=new u(this.pieces.length),this.emit("metadata"),!this.destroyed)if(this.skipVerify)this._markAllVerified(),this._onStore();else{const e=e=>{if(e)return this._destroy(e);this._debug("done verifying"),this._onStore()};this._debug("verifying existing torrent data"),this._fileModtimes&&this._store===b?this.getFileModtimes(((t,i)=>{if(t)return this._destroy(t);this.files.map(((e,t)=>i[t]===this._fileModtimes[t])).every((e=>e))?(this._markAllVerified(),this._onStore()):this._verifyPieces(e)})):this._verifyPieces(e)}}getFileModtimes(e){const t=[];k(this.files.map(((e,i)=>n=>{const r=this.addUID?c.join(this.name+" - "+this.infoHash.slice(0,8)):c.join(this.path,e.path);s.stat(r,((e,r)=>{if(e&&"ENOENT"!==e.code)return n(e);t[i]=r&&r.mtime.getTime(),n(null)}))})),H,(i=>{this._debug("done getting file modtimes"),e(i,t)}))}_verifyPieces(e){k(this.pieces.map(((e,t)=>e=>{if(this.destroyed)return e(new Error("torrent is destroyed"));const i={};t===this.pieces.length-1&&(i.length=this.lastPieceLength),this.store.get(t,i,((i,n)=>this.destroyed?e(new Error("torrent is destroyed")):i?A((()=>e(null))):void I(n,(i=>{if(this.destroyed)return e(new Error("torrent is destroyed"));i===this._hashes[t]?(this._debug("piece verified %s",t),this._markVerified(t)):this._debug("piece invalid %s",t),e(null)}))))})),H,e)}rescanFiles(e){if(this.destroyed)throw new Error("torrent is destroyed");e||(e=$),this._verifyPieces((t=>{if(t)return this._destroy(t),e(t);this._checkDone(),e(null)}))}_markAllVerified(){for(let e=0;ee))return!0;return!1}_onStore(){this.destroyed||(this._debug("on store"),this._startDiscovery(),this.ready=!0,this.emit("ready"),this._checkDone(),this._updateSelections(),this.wires.forEach((e=>{e.ut_metadata&&e.ut_metadata.setMetadata(this.metadata),this._onWireWithMetadata(e)})))}destroy(e,t){if("function"==typeof e)return this.destroy(null,e);this._destroy(null,e,t)}_destroy(e,t,i){if("function"==typeof t)return this._destroy(e,null,t);if(this.destroyed)return;this.destroyed=!0,this._debug("destroy"),this.client._remove(this),clearInterval(this._rechokeIntervalId),this._xsRequests.forEach((e=>{e.abort()})),this._rarityMap&&this._rarityMap.destroy();for(const e in this._peers)this.removePeer(e);this.files.forEach((e=>{e instanceof R&&e._destroy()}));const n=this._servers.map((e=>t=>{e.destroy(t)}));if(this.discovery&&n.push((e=>{this.discovery.destroy(e)})),this.store){let e=this._destroyStoreOnDestroy;t&&void 0!==t.destroyStore&&(e=t.destroyStore),n.push((t=>{e?this.store.destroy(t):this.store.close(t)}))}w(n,i),e&&(0===this.listenerCount("error")?this.client.emit("error",e):this.emit("error",e)),this.emit("close"),this.client=null,this.files=[],this.discovery=null,this.store=null,this._rarityMap=null,this._peers=null,this._servers=null,this._xsRequests=null}addPeer(e){if(this.destroyed)throw new Error("torrent is destroyed");if(!this.infoHash)throw new Error("addPeer() must not be called before the `infoHash` event");let t;if(this.client.blocked){if("string"==typeof e){let i;try{i=l(e)}catch(t){return this._debug("ignoring peer: invalid %s",e),this.emit("invalidPeer",e),!1}t=i[0]}else"string"==typeof e.remoteAddress&&(t=e.remoteAddress);if(t&&this.client.blocked.contains(t))return this._debug("ignoring peer: blocked %s",e),"string"!=typeof e&&e.destroy(),this.emit("blockedPeer",e),!1}const i=this.client.utp&&this._isIPv4(t)?"utp":"tcp",n=!!this._addPeer(e,i);return n?this.emit("peer",e):this.emit("invalidPeer",e),n}_addPeer(e,t){if(this.destroyed)return"string"!=typeof e&&e.destroy(),null;if("string"==typeof e&&!this._validAddr(e))return this._debug("ignoring peer: invalid %s",e),null;const i=e&&e.id||e;if(this._peers[i])return this._debug("ignoring peer: duplicate (%s)",i),"string"!=typeof e&&e.destroy(),null;if(this.paused)return this._debug("ignoring peer: torrent is paused"),"string"!=typeof e&&e.destroy(),null;let n;return this._debug("add peer %s",i),n="string"==typeof e?"utp"===t?L.createUTPOutgoingPeer(e,this,this.client.throttleGroups):L.createTCPOutgoingPeer(e,this,this.client.throttleGroups):L.createWebRTCPeer(e,this,this.client.throttleGroups),this._registerPeer(n),"string"==typeof e&&(this._queue.push(n),this._drain()),n}addWebSeed(e){if(this.destroyed)throw new Error("torrent is destroyed");let t,i;if("string"==typeof e){if(t=e,!/^https?:\/\/.+/.test(t))return this.emit("warning",new Error(`ignoring invalid web seed: ${t}`)),void this.emit("invalidPeer",t);if(this._peers[t])return this.emit("warning",new Error(`ignoring duplicate web seed: ${t}`)),void this.emit("invalidPeer",t);i=new q(t,this)}else{if(!e||"string"!=typeof e.connId)return void this.emit("warning",new Error("addWebSeed must be passed a string or connection object with id property"));if(i=e,t=i.connId,this._peers[t])return this.emit("warning",new Error(`ignoring duplicate web seed: ${t}`)),void this.emit("invalidPeer",t)}this._debug("add web seed %s",t);const n=L.createWebSeedPeer(i,t,this,this.client.throttleGroups);this._registerPeer(n),this.emit("peer",t)}_addIncomingPeer(e){return this.destroyed?e.destroy(new Error("torrent is destroyed")):this.paused?e.destroy(new Error("torrent is paused")):(this._debug("add incoming peer %s",e.id),void this._registerPeer(e))}_registerPeer(e){e.on("download",(e=>{this.destroyed||(this.received+=e,this._downloadSpeed(e),this.client._downloadSpeed(e),this.emit("download",e),this.destroyed||this.client.emit("download",e))})),e.on("upload",(e=>{this.destroyed||(this.uploaded+=e,this._uploadSpeed(e),this.client._uploadSpeed(e),this.emit("upload",e),this.destroyed||this.client.emit("upload",e))})),this._peers[e.id]=e,this._peersLength+=1}removePeer(e){const t=e&&e.id||e;(e=this._peers[t])&&(this._debug("removePeer %s",t),delete this._peers[t],this._peersLength-=1,e.destroy(),this._drain())}select(e,t,i,n){if(this.destroyed)throw new Error("torrent is destroyed");if(e<0||tt.priority-e.priority)),this._updateSelections()}deselect(e,t,i){if(this.destroyed)throw new Error("torrent is destroyed");i=Number(i)||0,this._debug("deselect %s-%s (priority %s)",e,t,i);for(let n=0;n{if(!this.destroyed&&!this.client.dht.destroyed){if(!e.remoteAddress)return this._debug("ignoring PORT from peer with no address");if(0===i||i>65536)return this._debug("ignoring invalid PORT from peer");this._debug("port: %s (from %s)",i,t),this.client.dht.addNode({host:e.remoteAddress,port:i})}})),e.on("timeout",(()=>{this._debug("wire timeout (%s)",t),e.destroy()})),"webSeed"!==e.type&&e.setTimeout(3e4,!0),e.setKeepAlive(!0),e.use(C(this.metadata)),e.ut_metadata.on("warning",(e=>{this._debug("ut_metadata warning: %s",e.message)})),this.metadata||(e.ut_metadata.on("metadata",(e=>{this._debug("got metadata via ut_metadata"),this._onMetadata(e)})),e.ut_metadata.fetch()),"function"!=typeof B||this.private||(e.use(B()),e.ut_pex.on("peer",(e=>{this.done||(this._debug("ut_pex: got peer: %s (from %s)",e,t),this.addPeer(e))})),e.ut_pex.on("dropped",(e=>{const i=this._peers[e];i&&!i.connected&&(this._debug("ut_pex: dropped peer: %s (from %s)",e,t),this.removePeer(e))})),e.once("close",(()=>{e.ut_pex.reset()}))),e.use(y()),this.emit("wire",e,t),this.ready&&A((()=>{this._onWireWithMetadata(e)}))}_onWireWithMetadata(e){let t=null;const i=()=>{this.destroyed||e.destroyed||(this._numQueued>2*(this._numConns-this.numPeers)&&e.amInterested?e.destroy():(t=setTimeout(i,D),t.unref&&t.unref()))};let n;const r=()=>{if(e.peerPieces.buffer.length===this.bitfield.buffer.length){for(n=0;n{r(),this._update(),this._updateWireInterest(e)})),e.on("have",(()=>{r(),this._update(),this._updateWireInterest(e)})),e.lt_donthave.on("donthave",(()=>{r(),this._update(),this._updateWireInterest(e)})),e.on("have-all",(()=>{e.isSeeder=!0,e.choke(),this._update(),this._updateWireInterest(e)})),e.on("have-none",(()=>{e.isSeeder=!1,this._update(),this._updateWireInterest(e)})),e.on("allowed-fast",(e=>{this._update()})),e.once("interested",(()=>{e.unchoke()})),e.once("close",(()=>{clearTimeout(t)})),e.on("choke",(()=>{clearTimeout(t),t=setTimeout(i,D),t.unref&&t.unref()})),e.on("unchoke",(()=>{clearTimeout(t),this._update()})),e.on("request",((t,i,n,r)=>{if(n>131072)return e.destroy();this.pieces[t]||this.store.get(t,{offset:i,length:n},r)})),e.hasFast&&this._hasAllPieces()?e.haveAll():e.hasFast&&this._hasNoPieces()?e.haveNone():e.bitfield(this.bitfield),this._updateWireInterest(e),e.peerExtensions.dht&&this.client.dht&&this.client.dht.listening&&e.port(this.client.dht.address().port),"webSeed"!==e.type&&(t=setTimeout(i,D),t.unref&&t.unref()),e.isSeeder=!1,r()}_updateSelections(){this.ready&&!this.destroyed&&(A((()=>{this._gcSelections()})),this._updateInterest(),this._update())}_gcSelections(){for(let e=0;ethis._updateWireInterest(e))),e!==this._amInterested&&(this._amInterested?this.emit("interested"):this.emit("uninterested"))}_updateWireInterest(e){let t=!1;for(let i=0;i{t._updateWire(e)}),{timeout:250}):t._updateWire(e)}_updateWire(e){const t=this,i=K(e,.5);if(e.requests.length>=i)return;const n=K(e,1);if(e.peerChoking)e.hasFast&&e.peerAllowedFastSet.length>0&&!this._hasMorePieces(e.peerAllowedFastSet.length-1)&&function(){if(e.requests.length>=n)return!1;for(const i of e.peerAllowedFastSet){if(e.peerPieces.get(i)&&!t.bitfield.get(i))for(;t._request(e,i,!1)&&e.requests.length=n.from+n.offset;--s)if(e.peerPieces.get(s)&&t._request(e,s,!1))return}}();a(!1)||a(!0)}function r(t,i,n,r){return s=>s>=t&&s<=i&&!(s in n)&&e.peerPieces.get(s)&&(!r||r(s))}function s(e){let i=e;for(let n=e;n=n)return!0;const a=function(){const i=e.downloadSpeed()||1;if(i>z)return()=>!0;const n=Math.max(1,e.requests.length)*S.BLOCK_LENGTH/i;let r=10,s=0;return e=>{if(!r||t.bitfield.get(e))return!0;let a=t.pieces[e].missing;for(;s0))return r--,!1}return!0}}();for(let o=0;o({wire:e,random:Math.random()}))).sort(((e,t)=>{const i=e.wire,n=t.wire;return i.downloadSpeed()!==n.downloadSpeed()?i.downloadSpeed()-n.downloadSpeed():i.uploadSpeed()!==n.uploadSpeed()?i.uploadSpeed()-n.uploadSpeed():i.amChoking!==n.amChoking?i.amChoking?-1:1:e.random-t.random})).map((e=>e.wire));this._rechokeOptimisticTime<=0?this._rechokeOptimisticWire=null:this._rechokeOptimisticTime-=1;let t=0;for(;e.length>0&&t0){const t=e.filter((e=>e.peerInterested));if(t.length>0){const e=t[(i=t.length,Math.random()*i|0)];e.unchoke(),this._rechokeOptimisticWire=e,this._rechokeOptimisticTime=2}}var i;e.filter((e=>e!==this._rechokeOptimisticWire)).forEach((e=>e.choke()))}_hotswap(e,t){const i=e.downloadSpeed();if(i=z||(2*o>i||o>a||(r=t,a=o))}if(!r)return!1;for(s=0;s=a)return!1;const o=n.pieces[t];let c=s?o.reserveRemaining():o.reserve();if(-1===c&&i&&n._hotswap(e,t)&&(c=s?o.reserveRemaining():o.reserve()),-1===c)return!1;let l=n._reservations[t];l||(l=n._reservations[t]=[]);let u=l.indexOf(null);-1===u&&(u=l.length),l[u]=e;const p=o.chunkOffset(c),d=s?o.chunkLengthRemaining(c):o.chunkLength(c);function f(){A((()=>{n._update()}))}return e.request(t,p,d,(function i(r,a){if(n.destroyed)return;if(!n.ready)return n.once("ready",(()=>{i(r,a)}));if(l[u]===e&&(l[u]=null),o!==n.pieces[t])return f();if(r)return n._debug("error getting piece %s (offset: %s length: %s) from %s: %s",t,p,d,`${e.remoteAddress}:${e.remotePort}`,r.message),s?o.cancelRemaining(c):o.cancel(c),void f();if(n._debug("got piece %s (offset: %s length: %s) from %s",t,p,d,`${e.remoteAddress}:${e.remotePort}`),!o.set(c,a,e))return f();const h=o.flush();I(h,(e=>{n.destroyed||(e===n._hashes[t]?(n._debug("piece verified %s",t),n.store.put(t,h,(e=>{e?n._destroy(e):(n.pieces[t]=null,n._markVerified(t),n.wires.forEach((e=>{e.have(t)})),n._checkDone()&&!n.destroyed&&n.discovery.complete(),f())}))):(n.pieces[t]=new S(o.length),n.emit("warning",new Error(`Piece ${t} failed verification`)),f()))}))})),!0}_checkDone(){if(this.destroyed)return;this.files.forEach((e=>{if(!e.done){for(let t=e._startPiece;t<=e._endPiece;++t)if(!this.bitfield.get(t))return;e.done=!0,e.emit("done"),this._debug(`file done: ${e.name}`)}}));let e=!0;for(const t of this._selections){for(let i=t.from;i<=t.to;i++)if(!this.bitfield.get(i)){e=!1;break}if(!e)break}return!this.done&&e?(this.done=!0,this._debug(`torrent done: ${this.infoHash}`),this.emit("done")):this.done=!1,this._gcSelections(),e}load(e,t){if(this.destroyed)throw new Error("torrent is destroyed");if(!this.ready)return this.once("ready",(()=>{this.load(e,t)}));Array.isArray(e)||(e=[e]),t||(t=$);const i=new x(e),n=new d(this.store,this.pieceLength);M(i,n,(e=>{if(e)return t(e);this._markAllVerified(),this._checkDone(),t(null)}))}createServer(e){if("function"!=typeof P)throw new Error("node.js-only method");if(this.destroyed)throw new Error("torrent is destroyed");const t=new P(this,e);return this._servers.push(t),t}pause(){this.destroyed||(this._debug("pause"),this.paused=!0)}resume(){this.destroyed||(this._debug("resume"),this.paused=!1,this._drain())}_debug(){const e=[].slice.call(arguments);e[0]=`[${this.client?this.client._debugId:"No Client"}] [${this._debugId}] ${e[0]}`,N(...e)}_drain(){if(this._debug("_drain numConns %s maxConns %s",this._numConns,this.client.maxConns),"function"!=typeof a.connect||this.destroyed||this.paused||this._numConns>=this.client.maxConns)return;this._debug("drain (%s queued, %s/%s peers)",this._numQueued,this.numPeers,this.client.maxConns);const e=this._queue.shift();if(!e)return;this._debug("%s connect attempt to %s",e.type,e.addr);const t=l(e.addr),i={host:t[0],port:t[1]};this.client.utp&&"utpOutgoing"===e.type?e.conn=U.connect(i.port,i.host):e.conn=a.connect(i);const n=e.conn;n.once("connect",(()=>{e.onConnect()})),n.once("error",(t=>{e.destroy(t)})),e.startConnectTimeout(),n.on("close",(()=>{if(this.destroyed)return;if(e.retries>=F.length){if(this.client.utp){const t=this._addPeer(e.addr,"tcp");t&&(t.retries=0)}else this._debug("conn %s closed: will not re-add (max %s attempts)",e.addr,F.length);return}const t=F[e.retries];this._debug("conn %s closed: will re-add to queue in %sms (attempt %s)",e.addr,t,e.retries+1);const i=setTimeout((()=>{if(this.destroyed)return;const t=l(e.addr)[0],i=this.client.utp&&this._isIPv4(t)?"utp":"tcp",n=this._addPeer(e.addr,i);n&&(n.retries=e.retries+1)}),t);i.unref&&i.unref()}))}_validAddr(e){let t;try{t=l(e)}catch(e){return!1}const i=t[0],n=t[1];return n>0&&n<65535&&!("127.0.0.1"===i&&n===this.client.torrentPort)}_isIPv4(e){return/^((?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])[.]){3}(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])$/.test(e)}}}).call(this)}).call(this,e("_process"),"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"../package.json":495,"./file.js":490,"./peer.js":491,"./rarity-map.js":492,"./server.js":66,"./utp.js":66,"./webconn.js":494,_process:340,"addr-to-ip-port":2,bitfield:26,"cache-chunk-store":116,"chunk-store-stream/write":132,cpus:136,debug:160,events:192,fs:66,"fs-chunk-store":274,"immediate-chunk-store":244,lt_donthave:255,"memory-chunk-store":274,multistream:308,net:66,os:66,"parse-torrent":331,path:332,pump:348,"queue-microtask":353,"random-iterate":355,"run-parallel":380,"run-parallel-limit":379,"simple-get":393,"simple-sha1":410,throughput:474,"torrent-discovery":477,"torrent-piece":478,ut_metadata:484,ut_pex:66}],494:[function(e,t,i){(function(i){(function(){const{default:n}=e("bitfield"),r=e("debug"),s=e("simple-get"),a=e("lt_donthave"),o=e("simple-sha1"),c=e("bittorrent-protocol"),l=r("webtorrent:webconn"),u=e("../package.json").version;t.exports=class extends c{constructor(e,t){super(),this.url=e,this.connId=e,this.webPeerId=o.sync(e),this._torrent=t,this._init()}_init(){this.setKeepAlive(!0),this.use(a()),this.once("handshake",((e,t)=>{if(this.destroyed)return;this.handshake(e,this.webPeerId);const i=this._torrent.pieces.length,r=new n(i);for(let e=0;e<=i;e++)r.set(e,!0);this.bitfield(r)})),this.once("interested",(()=>{l("interested"),this.unchoke()})),this.on("uninterested",(()=>{l("uninterested")})),this.on("choke",(()=>{l("choke")})),this.on("unchoke",(()=>{l("unchoke")})),this.on("bitfield",(()=>{l("bitfield")})),this.lt_donthave.on("donthave",(()=>{l("donthave")})),this.on("request",((e,t,i,n)=>{l("request pieceIndex=%d offset=%d length=%d",e,t,i),this.httpRequest(e,t,i,((t,i)=>{if(t){this.lt_donthave.donthave(e);const t=setTimeout((()=>{this.destroyed||this.have(e)}),1e4);t.unref&&t.unref()}n(t,i)}))}))}httpRequest(e,t,n,r){const a=e*this._torrent.pieceLength+t,o=a+n-1,c=this._torrent.files;let p;if(c.length<=1)p=[{url:this.url,start:a,end:o}];else{const e=c.filter((e=>e.offset<=o&&e.offset+e.length>a));if(e.length<1)return r(new Error("Could not find file corresponding to web seed range request"));p=e.map((e=>{const t=e.offset+e.length-1;return{url:this.url+("/"===this.url[this.url.length-1]?"":"/")+e.path.replace(this._torrent.path,""),fileOffsetInRange:Math.max(e.offset-a,0),start:Math.max(a-e.offset,0),end:Math.min(t,o-e.offset)}}))}let d,f=0,h=!1;p.length>1&&(d=i.alloc(n)),p.forEach((i=>{const a=i.url,o=i.start,c=i.end;l("Requesting url=%s pieceIndex=%d offset=%d length=%d start=%d end=%d",a,e,t,n,o,c);const m={url:a,method:"GET",headers:{"user-agent":`WebTorrent/${u} (https://webtorrent.io)`,range:`bytes=${o}-${c}`},timeout:6e4};function b(e,t){if(e.statusCode<200||e.statusCode>=300){if(h)return;return h=!0,r(new Error(`Unexpected HTTP status code ${e.statusCode}`))}l("Got data of length %d",t.length),1===p.length?r(null,t):(t.copy(d,i.fileOffsetInRange),++f===p.length&&r(null,d))}s.concat(m,((e,t,i)=>{if(!h)return e?"undefined"==typeof window||a.startsWith(`${window.location.origin}/`)?(h=!0,r(e)):s.head(a,((t,i)=>{if(!h){if(t)return h=!0,r(t);if(i.statusCode<200||i.statusCode>=300)return h=!0,r(new Error(`Unexpected HTTP status code ${i.statusCode}`));if(i.url===a)return h=!0,r(e);m.url=i.url,s.concat(m,((e,t,i)=>{if(!h)return e?(h=!0,r(e)):void b(t,i)}))}})):void b(t,i)}))}))}destroy(){super.destroy(),this._torrent=null}}}).call(this)}).call(this,e("buffer").Buffer)},{"../package.json":495,bitfield:26,"bittorrent-protocol":27,buffer:109,debug:160,lt_donthave:255,"simple-get":393,"simple-sha1":410}],495:[function(e,t,i){t.exports={version:"1.8.22"}},{}],496:[function(e,t,i){t.exports=function e(t,i){if(t&&i)return e(t)(i);if("function"!=typeof t)throw new TypeError("need wrapper function");return Object.keys(t).forEach((function(e){n[e]=t[e]})),n;function n(){for(var e=new Array(arguments.length),i=0;i1080?(P.setProps({placement:"right"}),U.setProps({placement:"right"}),q.setProps({placement:"right"})):(P.setProps({placement:"top"}),U.setProps({placement:"top"}),q.setProps({placement:"top"}))}function H(e){G();try{console.info("Attempting parse"),l=n(e),W(),l.xs&&(console.info("Magnet includes xs, attempting remote parse"),F(l.xs))}catch(t){console.warn(t),"magnet"==c?(console.info("Attempting remote parse"),F(e)):(D.error("Problem parsing input. Is this a .torrent file?"),console.error("Problem parsing input"))}}function F(e){n.remote(e,(function(e,t){if(e)return D.error("Problem remotely fetching that file or parsing result"),console.warn(e),void G();c="remote-torrent-file",m.innerHTML='',b.setContent("Currently loaded information sourced from remotely fetched Torrent file"),l=t,W()}))}function W(){if(console.log(l),w.value=l.infoHash,v.value=l.name?l.name:"",l.created?(y.value=l.created.toISOString().slice(0,19),y.type="datetime-local"):y.type="text",_.value=l.createdBy?" by "+l.createdBy:"",x.value=l.comment?l.comment:"",M.innerHTML="",l.announce&&l.announce.length)for(let e=0;e',n.addEventListener("click",Z),t.appendChild(n),M.appendChild(t)}if(A.innerHTML="",l.urlList&&l.urlList.length)for(let e=0;e',n.addEventListener("click",Z),t.appendChild(n),A.appendChild(t)}if(T.innerHTML="",l.files&&l.files.length){if(C.style.display="none",l.files.length<100)for(let e of l.files){let t=K(s.lookup(e.name));T.appendChild(V(t,e.name,e.length))}else{for(let e=0;e<100;e++){let t=K(s.lookup(l.files[e].name));T.appendChild(V(t,l.files[e].name,l.files[e].length))}T.appendChild(V("","...and another "+(l.files.length-100)+" more files",""))}T.appendChild(V("folder-tree","",l.length)),q.setContent("Download Torrent file"),O.addEventListener("click",te),O.disabled=!1}else N.torrents.length>0?(C.style.display="none",T.innerHTML=''):(C.style.display="block",T.innerHTML=''),q.setContent("Files metadata is required to generate a Torrent file. Try fetching files list from WebTorrent."),O.removeEventListener("click",te),O.disabled=!0;B.setAttribute("data-clipboard-text",window.location.origin+"#"+n.toMagnetURI(l)),R.setAttribute("data-clipboard-text",n.toMagnetURI(l)),u.style.display="none",h.style.display="flex",window.location.hash=n.toMagnetURI(l),l.name?document.title="Torrent Parts | "+l.name:document.title="Torrent Parts | Inspect and edit what's in your Torrent file or Magnet link",b.enable()}function V(e,t,i){let n=document.createElement("tr"),s=document.createElement("td");e&&(s.innerHTML=''),n.appendChild(s);let a=document.createElement("td");a.innerHTML=t,n.appendChild(a);let o=document.createElement("td");return o.innerHTML=r.format(i,{decimalPlaces:1,unitSeparator:" "}),n.appendChild(o),n}function K(e){if(!e)return"file";switch(!0){case e.includes("msword"):case e.includes("wordprocessingml"):case e.includes("opendocument.text"):case e.includes("abiword"):return"file-word";case e.includes("ms-excel"):case e.includes("spreadsheet"):case e.includes("powerpoint"):case e.includes("presentation"):return"file-powerpoint";case e.includes("7z-"):case e.includes("iso9660"):case e.includes("zip"):case e.includes("octet-stream"):return"file-archive";case e.includes("csv"):return"file-csv";case e.includes("pdf"):return"file-pdf";case e.includes("font"):return"file-contract";case e.includes("text"):case e.includes("subrip"):case e.includes("vtt"):return"file-alt";case e.includes("audio"):return"file-audio";case e.includes("image"):return"file-image";case e.includes("video"):return"file-video";default:return"file"}}function $(e){this.dataset.group?l[this.dataset.group][this.dataset.index]=this.value?this.value:"":l[this.id]=this.value?this.value:"",window.location.hash=n.toMagnetURI(l),Q()}function G(){document.getElementById("magnet").value="",document.getElementById("torrent").value="",u.style.display="flex",h.style.display="none",v.value="",y.value="",_.value="",x.value="",w.value="",M.innerHTML="",A.innerHTML="",N.torrents.forEach((e=>e.destroy())),C.style.display="block",T.innerHTML="",window.location.hash="",B.setAttribute("data-clipboard-text",""),R.setAttribute("data-clipboard-text",""),document.title="Torrent Parts | Inspect and edit what's in your Torrent file or Magnet link",b.disable()}async function X(){k.className="disabled",k.innerHTML="Adding...";try{let e=await fetch("https://newtrackon.com/api/stable"),t=await e.text();l.announce=l.announce.concat(t.split("\n\n")),l.announce.push("http://bt1.archive.org:6969/announce"),l.announce.push("http://bt2.archive.org:6969/announce"),l.announce=l.announce.filter(((e,t)=>e&&l.announce.indexOf(e)===t)),D.success("Added known working trackers from newTrackon"),Q()}catch(e){D.error("Problem fetching trackers from newTrackon"),console.warn(e)}k.className="",k.innerHTML="Add Known Working Trackers",W()}function Y(){l[this.dataset.type].unshift(""),W()}function Z(){l[this.parentElement.className].splice(this.parentElement.dataset.index,1),W()}function J(e){l[e]=[],Q(),W()}function Q(){l.created=new Date,l.createdBy="Torrent Parts ",l.created?(y.value=l.created.toISOString().slice(0,19),y.type="datetime-local"):y.type="text",_.value=l.createdBy?" by "+l.createdBy:""}function ee(){console.info("Attempting fetching files from Webtorrent..."),C.style.display="none",l.announce.push("wss://tracker.webtorrent.io"),l.announce.push("wss://tracker.openwebtorrent.com"),l.announce.push("wss://tracker.btorrent.xyz"),l.announce.push("wss://tracker.fastcast.nz"),l.announce=l.announce.filter(((e,t)=>e&&l.announce.indexOf(e)===t)),N.add(n.toMagnetURI(l),(e=>{l.info=Object.assign({},e.info),l.files=e.files,l.infoBuffer=e.infoBuffer,l.length=e.length,l.lastPieceLength=e.lastPieceLength,Q(),W(),D.success("Fetched file details from Webtorrent peers"),e.destroy()})),W()}function te(){let e=n.toTorrentFile(l);if(null!==e&&navigator.msSaveBlob)return navigator.msSaveBlob(new Blob([e],{type:"application/x-bittorrent"}),l.name+".torrent");let t=document.createElement("a");t.style.display="none";let i=window.URL.createObjectURL(new Blob([e],{type:"application/x-bittorrent"}));t.setAttribute("href",i),t.setAttribute("download",l.name+".torrent"),document.body.appendChild(t),t.click(),window.URL.revokeObjectURL(i),t.remove()}window.addEventListener("resize",z),z(),document.addEventListener("DOMContentLoaded",(function(){document.getElementById("magnet").addEventListener("keyup",(function(e){e.preventDefault(),"Enter"===e.key&&(c="magnet",m.innerHTML='',b.setContent("Currently loaded information sourced from Magnet URL"),H(magnet.value))})),document.getElementById("torrent").addEventListener("change",(function(e){e.preventDefault(),e.target.files[0].arrayBuffer().then((function(e){c="torrent-file",m.innerHTML='',b.setContent("Currently loaded information sourced from Torrent file"),H(t.from(e))}))})),document.addEventListener("dragover",(function(e){e.preventDefault()})),document.addEventListener("drop",(function(e){e.preventDefault(),e.dataTransfer.items[0].getAsFile().arrayBuffer().then((function(e){c="torrent-file",m.innerHTML='',b.setContent("Currently loaded information sourced from Torrent file"),H(t.from(e))}))})),p.addEventListener("click",(function(e){e.preventDefault(),D.success("Parsing Ubuntu 22.04 Magnet URL"),c="magnet",m.innerHTML='',b.setContent("Currently loaded information sourced from Magnet URL"),H("magnet:?xt=urn:btih:2c6b6858d61da9543d4231a71db4b1c9264b0685&dn=ubuntu-22.04-desktop-amd64.iso&tr=https%3A%2F%2Ftorrent.ubuntu.com%2Fannounce&tr=https%3A%2F%2Fipv6.torrent.ubuntu.com%2Fannounce")})),d.addEventListener("click",(async function(e){e.preventDefault(),D.success("Fetching and Parsing “The WIRED CD” Torrent File..."),c="remote-torrent-file",m.innerHTML='',b.setContent("Currently loaded information sourced from remotely fetched Torrent file"),F("https://webtorrent.io/torrents/wired-cd.torrent")})),f.addEventListener("click",(async function(e){e.preventDefault(),D.success("Parsing Jack Johnson Archive.org Torrent File");let i=await fetch("/ext/jj2008-06-14.mk4_archive.torrent"),n=await i.arrayBuffer();c="torrent-file",m.innerHTML='',b.setContent("Currently loaded information sourced from Torrent file"),H(t.from(n))}));let e=new i("#copyURL");e.on("success",(function(e){D.success("Copied site URL to clipboard!"),console.info(e)})),e.on("failure",(function(e){D.error("Problem copying to clipboard"),console.warn(e)}));let n=new i("#copyMagnet");n.on("success",(function(e){D.success("Copied Magnet URL to clipboard!")})),n.on("failure",(function(e){D.error("Problem copying to clipboard"),console.warn(e)})),v.addEventListener("input",$),v.addEventListener("change",$),v.addEventListener("reset",$),v.addEventListener("paste",$),g.addEventListener("click",G),x.addEventListener("input",$),x.addEventListener("change",$),x.addEventListener("reset",$),x.addEventListener("paste",$),k.addEventListener("click",X),E.addEventListener("click",Y),S.addEventListener("click",(()=>J("announce"))),j.addEventListener("click",Y),I.addEventListener("click",(()=>J("urlList"))),C.addEventListener("click",ee),o("[data-tippy-content]",{theme:"torrent-parts",animation:"shift-away-subtle"}),b.disable(),window.location.hash&&(c="shared-url",m.innerHTML='',b.setContent("Currently loaded information sourced from shared torrent.parts link"),H(window.location.hash.split("#")[1]))}))}).call(this)}).call(this,e("buffer").Buffer)},{buffer:109,bytes:115,clipboard:134,"mime-types":279,"parse-torrent":331,"tippy.js":475,webtorrent:488}]},{},[498]); \ No newline at end of file diff --git a/src/parse.js b/src/parse.js index 5402aed..bd0a9c3 100644 --- a/src/parse.js +++ b/src/parse.js @@ -119,11 +119,11 @@ function start() { // example buttons example1.addEventListener('click', function(event) { event.preventDefault(); - notyf.success('Parsing Ubuntu 20.04 Magnet URL'); + notyf.success('Parsing Ubuntu 22.04 Magnet URL'); source = 'magnet'; originalSourceIcon.innerHTML = ''; sourceTooltip.setContent('Currently loaded information sourced from Magnet URL'); - parse('magnet:?xt=urn:btih:9fc20b9e98ea98b4a35e6223041a5ef94ea27809&dn=ubuntu-20.04-desktop-amd64.iso&tr=https%3A%2F%2Ftorrent.ubuntu.com%2Fannounce&tr=https%3A%2F%2Fipv6.torrent.ubuntu.com%2Fannounce'); + parse('magnet:?xt=urn:btih:2c6b6858d61da9543d4231a71db4b1c9264b0685&dn=ubuntu-22.04-desktop-amd64.iso&tr=https%3A%2F%2Ftorrent.ubuntu.com%2Fannounce&tr=https%3A%2F%2Fipv6.torrent.ubuntu.com%2Fannounce'); }); example2.addEventListener('click', async function(event) {