diff --git a/bundle.js b/bundle.js index c8ed381..57f2541 100644 --- a/bundle.js +++ b/bundle.js @@ -33961,6 +33961,8 @@ function propertyChange(e) { function resetProperties() { document.getElementById('magnet').value = ""; document.getElementById('torrent').value = ""; + originalSourceIcon.innerHTML = ''; + originalSourceIcon.title = ''; properties.style.display = 'none'; name.value = ""; created.value = ""; diff --git a/bundle.min.js b/bundle.min.js index 0ae35f5..3fa3482 100644 --- a/bundle.min.js +++ b/bundle.min.js @@ -78,4 +78,4 @@ const i=e("debug")("torrent-discovery"),s=e("bittorrent-dht/client"),r=e("events /*! ut_metadata. MIT License. WebTorrent LLC */ const{EventEmitter:i}=e("events"),s=e("bencode"),r=e("bitfield").default,a=e("debug")("ut_metadata"),o=e("simple-sha1"),c=16384;t.exports=e=>{class t extends i{constructor(t){super(),this._wire=t,this._fetching=!1,this._metadataComplete=!1,this._metadataSize=null,this._remainingRejects=null,this._bitfield=new r(0,{grow:1e3}),n.isBuffer(e)&&this.setMetadata(e)}onHandshake(e,t,n){this._infoHash=e}onExtendedHandshake(e){return e.m&&e.m.ut_metadata?e.metadata_size?"number"!=typeof e.metadata_size||1e7this._metadataSize&&(n=this._metadataSize);const i=this.metadata.slice(t,n);this._data(e,i,this._metadataSize)}_onData(e,t,n){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=n.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:6,bitfield:300,buffer:59,debug:301,events:97,"simple-sha1":241}],300:[function(e,t,n){arguments[4][11][0].apply(n,arguments)},{dup:11}],301:[function(e,t,n){arguments[4][12][0].apply(n,arguments)},{"./common":302,_process:186,dup:12}],302:[function(e,t,n){arguments[4][13][0].apply(n,arguments)},{dup:13,ms:303}],303:[function(e,t,n){arguments[4][14][0].apply(n,arguments)},{dup:14}],304:[function(e,t,n){(function(e){(function(){function n(t){try{if(!e.localStorage)return!1}catch(e){return!1}var n=e.localStorage[t];return null!=n&&"true"===String(n).toLowerCase()}t.exports=function(e,t){if(n("noDeprecation"))return e;var i=!1;return function(){if(!i){if(n("throwDeprecation"))throw new Error(t);n("traceDeprecation")?console.trace(t):console.warn(t),i=!0}return e.apply(this,arguments)}}}).call(this)}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}],305:[function(e,t,n){(function(n){(function(){const i=e("binary-search"),s=e("events"),r=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 s{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=r.decode();const n=this._file.createReadStream({start:e});n.pipe(this._decoder);const i=s=>{"moov"===s.type?(this._decoder.removeListener("box",i),this._decoder.decode((e=>{n.destroy();try{this._processMoov(e)}catch(e){e.message="Cannot parse mp4 file: "+e.message,this.emit("error",e)}}))):s.length<4096?(t+=s.length,this._decoder.ignore()):(this._decoder.removeListener("box",i),t+=s.length,n.destroy(),this._decoder.destroy(),this._findMoov(e+t))};this._decoder.on("box",i)}_processMoov(e){const t=e.traks;this._tracks=[],this._hasVideo=!1,this._hasAudio=!1;for(let n=0;n=r.stsz.entries.length)break;if(h++,m+=e,h>=i.samplesPerChunk){h=0,m=0,f++;const e=r.stsc.entries[g+1];e&&f+1>=e.firstChunk&&g++}v+=t,b.inc(),x&&x.inc(),s&&_++}s.mdia.mdhd.duration=0,s.tkhd.duration=0;const y=i.sampleDescriptionId,w={type:"moov",mvhd:e.mvhd,traks:[{tkhd:s.tkhd,mdia:{mdhd:s.mdia.mdhd,hdlr:s.mdia.hdlr,elng:s.mdia.elng,minf:{vmhd:s.mdia.minf.vmhd,smhd:s.mdia.minf.smhd,dinf:s.mdia.minf.dinf,stbl:{stsd:r.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:s.tkhd.trackId,defaultSampleDescriptionIndex:y,defaultSampleDuration:0,defaultSampleSize:0,defaultSampleFlags:0}]}};this._tracks.push({fragmentSequence:1,trackId:s.tkhd.trackId,timeScale:s.mdia.mdhd.timeScale,samples:u,currSample:null,currTime:null,moov:w,mime:p})}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 s=a.encode(this._ftyp),r=this._tracks.map((e=>{const t=a.encode(e.moov);return{mime:e.mime,init:n.concat([s,t])}}));this.emit("ready",r)}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(((n,i)=>{n.outStream&&n.outStream.destroy(),n.inStream&&(n.inStream.destroy(),n.inStream=null);const s=n.outStream=r.encode(),a=this._generateFragment(i,e);if(!a)return s.finalize();(-1===t||a.ranges[0].start{s.destroyed||s.box(e.moof,(t=>{if(t)return this.emit("error",t);if(s.destroyed)return;n.inStream.slice(e.ranges).pipe(s.mediaData(e.length,(e=>{if(e)return this.emit("error",e);if(s.destroyed)return;const t=this._generateFragment(i);if(!t)return s.finalize();o(t)})))}))};o(a)})),t>=0){const e=this._fileStream=this._file.createReadStream({start:t});this._tracks.forEach((n=>{n.inStream=new o(t,{highWaterMark:1e7}),e.pipe(n.inStream)}))}return this._tracks.map((e=>e.outStream))}_findSampleBefore(e,t){const n=this._tracks[e],s=Math.floor(n.timeScale*t);let r=i(n.samples,s,((e,t)=>e.dts+e.presentationOffset-t));for(-1===r?r=0:r<0&&(r=-r-2);!n.samples[r].sync;)r--;return r}_generateFragment(e,t){const n=this._tracks[e];let i;if(i=void 0!==t?this._findSampleBefore(e,t):n.currSample,i>=n.samples.length)return null;const s=n.samples[i].dts;let r=0;const a=[];for(var o=i;o=n.timeScale*l)break;r+=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 n.currSample=o,{moof:this._generateMoof(e,i,o),ranges:a,length:r}}_generateMoof(e,t,n){const i=this._tracks[e],s=[];let r=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 r(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 n={muxed:null,mediaSource:t,initFlushed:!1,onInitFlushed:null};return t.write(e.init,(e=>{n.initFlushed=!0,n.onInitFlushed&&n.onInitFlushed(e)})),n})),(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,n)=>{const i=()=>{t.muxed&&(t.muxed.destroy(),t.mediaSource=this._elemWrapper.createWriteStream(t.mediaSource),t.mediaSource.on("error",(e=>{this._elemWrapper.error(e)}))),t.muxed=e[n],s(t.muxed,t.mediaSource)};t.initFlushed?i():t.onInitFlushed=e=>{e?this._elemWrapper.error(e):i()}}))},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":305,mediasource:124,pump:187}],307:[function(e,t,n){(function(n,i,s){(function(){ /*! webtorrent. MIT License. WebTorrent LLC */ -const{EventEmitter:r}=e("events"),a=e("simple-concat"),o=e("create-torrent"),c=e("debug")("webtorrent"),l=e("bittorrent-dht/client"),p=e("load-ip-set"),u=e("run-parallel"),d=e("parse-torrent"),h=e("path"),f=e("simple-peer"),m=e("randombytes"),g=e("speedometer"),v=e("./lib/conn-pool"),b=e("./lib/torrent"),x=e("./package.json").version,_=x.replace(/\d*./g,(e=>("0"+e%100).slice(-2))).slice(0,4),y=`-WW${_}-`;class w extends r{constructor(e={}){super(),"string"==typeof e.peerId?this.peerId=e.peerId:s.isBuffer(e.peerId)?this.peerId=e.peerId.toString("hex"):this.peerId=s.from(y+m(9).toString("base64")).toString("hex"),this.peerIdBuffer=s.from(this.peerId,"hex"),"string"==typeof e.nodeId?this.nodeId=e.nodeId:s.isBuffer(e.nodeId)?this.nodeId=e.nodeId.toString("hex"):this.nodeId=m(20).toString("hex"),this.nodeIdBuffer=s.from(this.nodeId,"hex"),this._debugId=this.peerId.toString("hex").substring(0,7),this.destroyed=!1,this.listening=!1,this.torrentPort=e.torrentPort||0,this.dhtPort=e.dhtPort||0,this.tracker=void 0!==e.tracker?e.tracker:{},this.torrents=[],this.maxConns=Number(e.maxConns)||55,this.utp=!0===e.utp,this._debug("new webtorrent (peerId %s, nodeId %s, port %s)",this.peerId,this.nodeId,this.torrentPort),this.tracker&&("object"!=typeof this.tracker&&(this.tracker={}),e.rtcConfig&&(console.warn("WebTorrent: opts.rtcConfig is deprecated. Use opts.tracker.rtcConfig instead"),this.tracker.rtcConfig=e.rtcConfig),e.wrtc&&(console.warn("WebTorrent: opts.wrtc is deprecated. Use opts.tracker.wrtc instead"),this.tracker.wrtc=e.wrtc),i.WRTC&&!this.tracker.wrtc&&(this.tracker.wrtc=i.WRTC)),"function"==typeof v?this._connPool=new v(this):n.nextTick((()=>{this._onListening()})),this._downloadSpeed=g(),this._uploadSpeed=g(),!1!==e.dht&&"function"==typeof l?(this.dht=new l(Object.assign({},{nodeId:this.nodeId},e.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!==e.webSeeds;const t=()=>{this.destroyed||(this.ready=!0,this.emit("ready"))};"function"==typeof p&&null!=e.blocklist?p(e.blocklist,{headers:{"user-agent":`WebTorrent/${x} (https://webtorrent.io)`}},((e,n)=>{if(e)return this.error("Failed to load blocklist: "+e.message);this.blocked=n,t()})):n.nextTick(t)}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 b){if(this.torrents.includes(e))return e}else{let t;try{t=d(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}download(e,t,n){return console.warn("WebTorrent: client.download() is deprecated. Use client.add() instead"),this.add(e,t,n)}add(e,t={},n=(()=>{})){if(this.destroyed)throw new Error("client is destroyed");"function"==typeof t&&([t,n]=[{},t]);const i=()=>{if(!this.destroyed)for(const e of this.torrents)if(e.infoHash===r.infoHash&&e!==r)return void r._destroy(new Error("Cannot add duplicate torrent "+r.infoHash))},s=()=>{this.destroyed||(n(r),this.emit("torrent",r))};this._debug("add"),t=t?Object.assign({},t):{};const r=new b(e,this,t);return this.torrents.push(r),r.once("_infoHash",i),r.once("ready",s),r.once("close",(function e(){r.removeListener("_infoHash",i),r.removeListener("ready",s),r.removeListener("close",e)})),r}seed(e,t,n){if(this.destroyed)throw new Error("client is destroyed");"function"==typeof t&&([t,n]=[{},t]),this._debug("seed"),(t=t?Object.assign({},t):{}).skipVerify=!0;const i="string"==typeof e;i&&(t.path=h.dirname(e)),t.createdBy||(t.createdBy="WebTorrent/"+_);const s=e=>{this._debug("on seed"),"function"==typeof n&&n(e),e.emit("seed"),this.emit("seed",e)},r=this.add(null,t,(e=>{const t=[t=>{if(i)return t();e.load(c,t)}];this.dht&&t.push((t=>{e.once("dhtAnnounce",t)})),u(t,(t=>{if(!this.destroyed)return t?e._destroy(t):void s(e)}))}));let c;var l;return l=e,"undefined"!=typeof FileList&&l instanceof FileList?e=Array.from(e):Array.isArray(e)||(e=[e]),u(e.map((e=>t=>{!function(e){return"object"==typeof e&&null!=e&&"function"==typeof e.pipe}(e)?t(null,e):a(e,t)})),((e,n)=>{if(!this.destroyed)return e?r._destroy(e):void o.parseInput(n,t,((e,i)=>{if(!this.destroyed){if(e)return r._destroy(e);c=i.map((e=>e.getStream)),o(n,t,((e,t)=>{if(this.destroyed)return;if(e)return r._destroy(e);const n=this.get(t);n?r._destroy(new Error("Cannot add duplicate torrent "+n.infoHash)):r._onTorrentId(t)}))}}))})),r}remove(e,t,n){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,n)}_remove(e,t,n){if("function"==typeof t)return this._remove(e,null,t);const i=this.get(e);i&&(this.torrents.splice(this.torrents.indexOf(i),1),i.destroy(t,n))}address(){return this.listening?this._connPool?this._connPool.tcpServer.address():{address:"0.0.0.0",family:"IPv4",port:0}:null}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 n=this.torrents.map((e=>t=>{e.destroy(t)}));this._connPool&&n.push((e=>{this._connPool.destroy(e)})),this.dht&&n.push((e=>{this.dht.destroy(e)})),u(n,t),e&&this.emit("error",e),this.torrents=[],this._connPool=null,this.dht=null}_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]}`,c(...e)}}w.WEBRTC_SUPPORT=f.WEBRTC_SUPPORT,w.VERSION=x,t.exports=w}).call(this)}).call(this,e("_process"),"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{},e("buffer").Buffer)},{"./lib/conn-pool":54,"./lib/torrent":312,"./package.json":332,_process:186,"bittorrent-dht/client":54,buffer:59,"create-torrent":79,debug:314,events:97,"load-ip-set":54,"parse-torrent":183,path:184,randombytes:194,"run-parallel":217,"simple-concat":220,"simple-peer":222,speedometer:262}],308:[function(e,t,n){const i=e("debug")("webtorrent:file-stream"),s=e("readable-stream");class r extends s.Readable{constructor(e,t){super(t),this.destroyed=!1,this._torrent=e._torrent;const n=t&&t.start||0,i=t&&t.end&&t.end{if(this._notifying=!1,!this.destroyed){if(i("read %s (length %s) (err %s)",e,n.length,t&&t.message),t)return this._destroy(t);this._offset&&(n=n.slice(this._offset),this._offset=0),this._missing{e.end()})),e}const t=new u(this,e);return this._torrent.select(t._startPiece,t._endPiece,!0,(()=>{t._notify()})),r(t,(()=>{this._destroyed||this._torrent.destroyed||this._torrent.deselect(t._startPiece,t._endPiece,!0)})),t}getBuffer(e){p(this.createReadStream(),this.length,e)}getBlob(e){if("undefined"==typeof window)throw new Error("browser-only method");c(this.createReadStream(),this._getMimeType()).then((t=>e(null,t)),(t=>e(t)))}getBlobURL(e){if("undefined"==typeof window)throw new Error("browser-only method");l(this.createReadStream(),this._getMimeType()).then((t=>e(null,t)),(t=>e(t)))}appendTo(e,t,n){if("undefined"==typeof window)throw new Error("browser-only method");o.append(this,e,t,n)}renderTo(e,t,n){if("undefined"==typeof window)throw new Error("browser-only method");o.render(this,e,t,n)}_getMimeType(){return o.mime[a.extname(this.name).toLowerCase()]}_destroy(){this._destroyed=!0,this._torrent=null}}}).call(this)}).call(this,e("_process"))},{"./file-stream":308,_process:186,"end-of-stream":95,events:97,path:184,"readable-stream":331,"render-media":211,"stream-to-blob":283,"stream-to-blob-url":282,"stream-with-known-length-to-buffer":284}],310:[function(e,t,n){const i=e("unordered-array-remove"),s=e("debug")("webtorrent:peer"),r=e("bittorrent-protocol"),a=e("./webconn");n.createWebRTCPeer=(e,t)=>{const n=new l(e.id,"webrtc");return n.conn=e,n.swarm=t,n.conn.connected?n.onConnect():(n.conn.once("connect",(()=>{n.onConnect()})),n.conn.once("error",(e=>{n.destroy(e)})),n.startConnectTimeout()),n},n.createTCPIncomingPeer=e=>o(e,"tcpIncoming"),n.createUTPIncomingPeer=e=>o(e,"utpIncoming"),n.createTCPOutgoingPeer=(e,t)=>c(e,t,"tcpOutgoing"),n.createUTPOutgoingPeer=(e,t)=>c(e,t,"utpOutgoing");const o=(e,t)=>{const n=`${e.remoteAddress}:${e.remotePort}`,i=new l(n,t);return i.conn=e,i.addr=n,i.onConnect(),i},c=(e,t,n)=>{const i=new l(e,n);return i.addr=e,i.swarm=t,i};n.createWebSeedPeer=(e,t)=>{const n=new l(e,"webSeed");return n.swarm=t,n.conn=new a(e,t),n.onConnect(),n};class l{constructor(e,t){this.id=e,this.type=t,s("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.sentHandshake=!1}onConnect(){if(this.destroyed)return;this.connected=!0,s("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 r;t.type=this.type,t.once("end",(()=>{this.destroy()})),t.once("close",(()=>{this.destroy()})),t.once("finish",(()=>{this.destroy()})),t.once("error",(e=>{this.destroy(e)})),t.once("handshake",((e,t)=>{this.onHandshake(e,t)})),this.startHandshakeTimeout(),e.pipe(t).pipe(e),this.swarm&&!this.sentHandshake&&this.handshake()}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"));s("Peer %s got handshake %s",this.id,e),clearTimeout(this.handshakeTimeout),this.retries=0;let n=this.addr;!n&&this.conn.remoteAddress&&this.conn.remotePort&&(n=`${this.conn.remoteAddress}:${this.conn.remotePort}`),this.swarm._onWire(this.wire,n),this.swarm&&!this.swarm.destroyed&&(this.sentHandshake||this.handshake())}handshake(){const e={dht:!this.swarm.private&&!!this.swarm.client.dht};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,s("destroy %s %s (error: %s)",this.type,this.id,e&&(e.message||e)),clearTimeout(this.connectTimeout),clearTimeout(this.handshakeTimeout);const t=this.swarm,n=this.conn,r=this.wire;this.swarm=null,this.conn=null,this.wire=null,t&&r&&i(t.wires,t.wires.indexOf(r)),n&&(n.on("error",(()=>{})),n.destroy()),r&&r.destroy(),t&&t.removePeer(this.id)}}},{"./webconn":313,"bittorrent-protocol":10,debug:314,"unordered-array-remove":296}],311:[function(e,t,n){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=[],n=1/0;for(let i=0;i{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;t{this.destroyed||this._onParsedTorrent(t)}))):x.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.path||(this.path=_.join(N,this.infoHash)),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&&i.WEBTORRENT_ANNOUNCE&&!e.private&&(e.announce=e.announce.concat(i.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=x.toMagnetURI(e),this.torrentFile=x.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:()=>{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 c({infoHash:this.infoHash,announce:this.announce,peerId:this.client.peerId,dht:!this.private&&this.client.dht,tracker:e,port:this.client.torrentPort,userAgent:P}),this.discovery.on("error",(e=>{this._destroy(e)})),this.discovery.on("peer",(e=>{"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=>n=>{!function(t,n){if(0!==t.indexOf("http://")&&0!==t.indexOf("https://"))return e.emit("warning",new Error("skipping non-http xs param: "+t)),n(null);const i={url:t,method:"GET",headers:{"user-agent":P}};let s;try{s=d.concat(i,r)}catch(i){return e.emit("warning",new Error("skipping invalid url xs param: "+t)),n(null)}function r(i,s,r){if(e.destroyed)return n(null);if(e.metadata)return n(null);if(i)return e.emit("warning",new Error("http error from xs param: "+t)),n(null);if(200!==s.statusCode)return e.emit("warning",new Error(`non-200 status code ${s.statusCode} from xs param: ${t}`)),n(null);let a;try{a=x(r)}catch(i){}return a?a.infoHash!==e.infoHash?(e.emit("warning",new Error("got torrent file with incorrect info hash from xs param: "+t)),n(null)):(e._onMetadata(a),void n(null)):(e.emit("warning",new Error("got invalid torrent file from xs param: "+t)),n(null))}e._xsRequests.push(s)}(t,n)}));v(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=x(e)}catch(e){return this._destroy(e)}if(this._processParsedTorrent(t),this.metadata=this.torrentFile,this.client.enableWebSeeds&&this.urlList.forEach((e=>{this.addWebSeed(e)})),this._rarityMap=new L(this),this.store=new h(new this._store(this.pieceLength,{torrent:{infoHash:this.infoHash},files:this.files.map((e=>({path:_.join(this.path,e.path),length:e.length,offset:e.offset}))),length:this.length,name:this.infoHash})),this.files=this.files.map((e=>new A(this,e))),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 n=t===this.pieces.length-1?this.lastPieceLength:this.pieceLength;return new y(n)})),this._reservations=this.pieces.map((()=>[])),this.bitfield=new r(this.pieces.length),this.wires.forEach((e=>{e.ut_metadata&&e.ut_metadata.setMetadata(this.metadata),this._onWireWithMetadata(e)})),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===u?this.getFileModtimes(((t,n)=>{if(t)return this._destroy(t);this.files.map(((e,t)=>n[t]===this._fileModtimes[t])).every((e=>e))?(this._markAllVerified(),this._onStore()):this._verifyPieces(e)})):this._verifyPieces(e)}}getFileModtimes(e){const t=[];b(this.files.map(((e,n)=>i=>{p.stat(_.join(this.path,e.path),((e,s)=>{if(e&&"ENOENT"!==e.code)return i(e);t[n]=s&&s.mtime.getTime(),i(null)}))})),U,(n=>{this._debug("done getting file modtimes"),e(n,t)}))}_verifyPieces(e){b(this.pieces.map(((e,t)=>e=>{if(this.destroyed)return e(new Error("torrent is destroyed"));this.store.get(t,((i,s)=>this.destroyed?e(new Error("torrent is destroyed")):i?n.nextTick(e,null):void E(s,(n=>{if(this.destroyed)return e(new Error("torrent is destroyed"));if(n===this._hashes[t]){if(!this.pieces[t])return e(null);this._debug("piece verified %s",t),this._markVerified(t)}else this._debug("piece invalid %s",t);e(null)}))))})),U,e)}rescanFiles(e){if(this.destroyed)throw new Error("torrent is destroyed");e||(e=H),this._verifyPieces((t=>{if(t)return this._destroy(t),e(t);this._checkDone(),e(null)}))}_markAllVerified(){for(let e=0;e{e.abort()})),this._rarityMap&&this._rarityMap.destroy();for(const e in this._peers)this.removePeer(e);this.files.forEach((e=>{e instanceof A&&e._destroy()}));const i=this._servers.map((e=>t=>{e.destroy(t)}));this.discovery&&i.push((e=>{this.discovery.destroy(e)})),this.store&&i.push((e=>{t&&t.destroyStore?this.store.destroy(e):this.store.close(e)})),v(i,n),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");if(this.client.blocked){let t;if("string"==typeof e){let n;try{n=s(e)}catch(t){return this._debug("ignoring peer: invalid %s",e),this.emit("invalidPeer",e),!1}t=n[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 t=!!this._addPeer(e,this.client.utp?"utp":"tcp");return t?this.emit("peer",e):this.emit("invalidPeer",e),t}_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 n=e&&e.id||e;if(this._peers[n])return this._debug("ignoring peer: duplicate (%s)",n),"string"!=typeof e&&e.destroy(),null;if(this.paused)return this._debug("ignoring peer: torrent is paused"),"string"!=typeof e&&e.destroy(),null;let i;return this._debug("add peer %s",n),i="string"==typeof e?"utp"===t?I.createUTPOutgoingPeer(e,this):I.createTCPOutgoingPeer(e,this):I.createWebRTCPeer(e,this),this._peers[i.id]=i,this._peersLength+=1,"string"==typeof e&&(this._queue.push(i),this._drain()),i}addWebSeed(e){if(this.destroyed)throw new Error("torrent is destroyed");if(!/^https?:\/\/.+/.test(e))return this.emit("warning",new Error("ignoring invalid web seed: "+e)),void this.emit("invalidPeer",e);if(this._peers[e])return this.emit("warning",new Error("ignoring duplicate web seed: "+e)),void this.emit("invalidPeer",e);this._debug("add web seed %s",e);const t=I.createWebSeedPeer(e,this);this._peers[t.id]=t,this._peersLength+=1,this.emit("peer",e)}_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),this._peers[e.id]=e,void(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,n,i){if(this.destroyed)throw new Error("torrent is destroyed");if(e<0||tt.priority-e.priority)),this._updateSelections()}deselect(e,t,n){if(this.destroyed)throw new Error("torrent is destroyed");n=Number(n)||0,this._debug("deselect %s-%s (priority %s)",e,t,n);for(let i=0;i{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.wires.push(e),t){const n=s(t);e.remoteAddress=n[0],e.remotePort=n[1]}this.client.dht&&this.client.dht.listening&&e.on("port",(n=>{if(!this.destroyed&&!this.client.dht.destroyed){if(!e.remoteAddress)return this._debug("ignoring PORT from peer with no address");if(0===n||n>65536)return this._debug("ignoring invalid PORT from peer");this._debug("port: %s (from %s)",n,t),this.client.dht.addNode({host:e.remoteAddress,port:n})}})),e.on("timeout",(()=>{this._debug("wire timeout (%s)",t),e.destroy()})),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 T||this.private||(e.use(T()),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 n=this._peers[e];n&&!n.connected&&(this._debug("ut_pex: dropped peer: %s (from %s)",e,t),this.removePeer(e))})),e.once("close",(()=>{e.ut_pex.reset()}))),this.emit("wire",e,t),this.metadata&&n.nextTick((()=>{this._onWireWithMetadata(e)}))}_onWireWithMetadata(e){let t=null;const n=()=>{this.destroyed||e.destroyed||(this._numQueued>2*(this._numConns-this.numPeers)&&e.amInterested?e.destroy():(t=setTimeout(n,B),t.unref&&t.unref()))};let i;const s=()=>{if(e.peerPieces.buffer.length===this.bitfield.buffer.length){for(i=0;i{s(),this._update(),this._updateWireInterest(e)})),e.on("have",(()=>{s(),this._update(),this._updateWireInterest(e)})),e.once("interested",(()=>{e.unchoke()})),e.once("close",(()=>{clearTimeout(t)})),e.on("choke",(()=>{clearTimeout(t),t=setTimeout(n,B),t.unref&&t.unref()})),e.on("unchoke",(()=>{clearTimeout(t),this._update()})),e.on("request",((t,n,i,s)=>{if(i>131072)return e.destroy();this.pieces[t]||this.store.get(t,{offset:n,length:i},s)})),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(n,B),t.unref&&t.unref()),e.isSeeder=!1,s()}_updateSelections(){this.ready&&!this.destroyed&&(n.nextTick((()=>{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 n=0;n=i.from+i.offset;--r)if(e.peerPieces.get(r)&&t._request(e,r,!1))return}}();const n=q(e,.5);if(e.requests.length>=n)return;const i=q(e,1);function s(t,n,i,s){return r=>r>=t&&r<=n&&!(r in i)&&e.peerPieces.get(r)&&(!s||s(r))}function r(e){let n=e;for(let i=e;i=i)return!0;const a=function(){const n=e.downloadSpeed()||1;if(n>O)return()=>!0;const i=Math.max(1,e.requests.length)*y.BLOCK_LENGTH/n;let s=10,r=0;return e=>{if(!s||t.bitfield.get(e))return!0;let a=t.pieces[e].missing;for(;r0))return s--,!1}return!0}}();for(let o=0;o({wire:e,random:Math.random()}))).sort(((e,t)=>{const n=e.wire,i=t.wire;return n.downloadSpeed()!==i.downloadSpeed()?n.downloadSpeed()-i.downloadSpeed():n.uploadSpeed()!==i.uploadSpeed()?n.uploadSpeed()-i.uploadSpeed():n.amChoking!==i.amChoking?n.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[(n=t.length,Math.random()*n|0)];e.unchoke(),this._rechokeOptimisticWire=e,this._rechokeOptimisticTime=2}}var n;e.filter((e=>e!==this._rechokeOptimisticWire)).forEach((e=>e.choke()))}_hotswap(e,t){const n=e.downloadSpeed();if(n=O||(2*o>n||o>a||(s=t,a=o))}if(!s)return!1;for(r=0;r=(a?Math.min(function(e,t,n){return 1+Math.ceil(t*e.downloadSpeed()/n)}(e,1,s.pieceLength),s.maxWebConns):q(e,1)))return!1;const o=s.pieces[t];let c=a?o.reserveRemaining():o.reserve();if(-1===c&&i&&s._hotswap(e,t)&&(c=a?o.reserveRemaining():o.reserve()),-1===c)return!1;let l=s._reservations[t];l||(l=s._reservations[t]=[]);let p=l.indexOf(null);-1===p&&(p=l.length),l[p]=e;const u=o.chunkOffset(c),d=a?o.chunkLengthRemaining(c):o.chunkLength(c);function h(){n.nextTick((()=>{s._update()}))}return e.request(t,u,d,(function n(i,r){if(s.destroyed)return;if(!s.ready)return s.once("ready",(()=>{n(i,r)}));if(l[p]===e&&(l[p]=null),o!==s.pieces[t])return h();if(i)return s._debug("error getting piece %s (offset: %s length: %s) from %s: %s",t,u,d,`${e.remoteAddress}:${e.remotePort}`,i.message),a?o.cancelRemaining(c):o.cancel(c),void h();if(s._debug("got piece %s (offset: %s length: %s) from %s",t,u,d,`${e.remoteAddress}:${e.remotePort}`),!o.set(c,r,e))return h();const f=o.flush();E(f,(e=>{if(!s.destroyed){if(e===s._hashes[t]){if(!s.pieces[t])return;s._debug("piece verified %s",t),s.pieces[t]=null,s._reservations[t]=null,s.bitfield.set(t,!0),s.store.put(t,f),s.wires.forEach((e=>{e.have(t)})),s._checkDone()&&!s.destroyed&&s.discovery.complete()}else s.pieces[t]=new y(o.length),s.emit("warning",new Error(`Piece ${t} failed verification`));h()}}))})),!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(let t=0;t{this.load(e,t)}));Array.isArray(e)||(e=[e]),t||(t=H);const n=new f(e),i=new a(this.store,this.pieceLength);w(n,i,(e=>{if(e)return t(e);this._markAllVerified(),this._checkDone(),t(null)}))}createServer(e){if("function"!=typeof R)throw new Error("node.js-only method");if(this.destroyed)throw new Error("torrent is destroyed");const t=new R(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]}`,o(...e)}_drain(){if(this._debug("_drain numConns %s maxConns %s",this._numConns,this.client.maxConns),"function"!=typeof m.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=s(e.addr),n={host:t[0],port:t[1]};"utpOutgoing"===e.type?e.conn=j.connect(n.port,n.host):e.conn=m.connect(n);const i=e.conn;i.once("connect",(()=>{e.onConnect()})),i.once("error",(t=>{e.destroy(t)})),e.startConnectTimeout(),i.on("close",(()=>{if(this.destroyed)return;if(e.retries>=M.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,M.length);return}const t=M[e.retries];this._debug("conn %s closed: will re-add to queue in %sms (attempt %s)",e.addr,t,e.retries+1);const n=setTimeout((()=>{if(this.destroyed)return;const t=this._addPeer(e.addr,this.client.utp?"utp":"tcp");t&&(t.retries=e.retries+1)}),t);n.unref&&n.unref()}))}_validAddr(e){let t;try{t=s(e)}catch(e){return!1}const n=t[0],i=t[1];return i>0&&i<65535&&!("127.0.0.1"===n&&i===this.client.torrentPort)}}}).call(this)}).call(this,e("_process"),"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"../package.json":332,"./file":309,"./peer":310,"./rarity-map":311,"./server":54,_process:186,"addr-to-ip-port":2,bitfield:9,"chunk-store-stream/write":77,debug:314,events:97,fs:55,"fs-chunk-store":140,"immediate-chunk-store":117,multistream:165,net:54,os:54,"parse-torrent":183,path:184,pump:187,"random-iterate":193,"run-parallel":217,"run-parallel-limit":216,"simple-get":221,"simple-sha1":241,speedometer:262,"torrent-discovery":289,"torrent-piece":293,ut_metadata:299,ut_pex:54,"utp-native":54}],313:[function(e,t,n){(function(n){(function(){const i=e("bitfield"),s=e("debug")("webtorrent:webconn"),r=e("simple-get"),a=e("simple-sha1"),o=e("bittorrent-protocol"),c=e("../package.json").version;t.exports=class extends o{constructor(e,t){super(),this.url=e,this.webPeerId=a.sync(e),this._torrent=t,this._init()}_init(){this.setKeepAlive(!0),this.once("handshake",((e,t)=>{if(this.destroyed)return;this.handshake(e,this.webPeerId);const n=this._torrent.pieces.length,s=new i(n);for(let e=0;e<=n;e++)s.set(e,!0);this.bitfield(s)})),this.once("interested",(()=>{s("interested"),this.unchoke()})),this.on("uninterested",(()=>{s("uninterested")})),this.on("choke",(()=>{s("choke")})),this.on("unchoke",(()=>{s("unchoke")})),this.on("bitfield",(()=>{s("bitfield")})),this.on("request",((e,t,n,i)=>{s("request pieceIndex=%d offset=%d length=%d",e,t,n),this.httpRequest(e,t,n,i)}))}httpRequest(e,t,i,a){const o=e*this._torrent.pieceLength+t,l=o+i-1,p=this._torrent.files;let u;if(p.length<=1)u=[{url:this.url,start:o,end:l}];else{const e=p.filter((e=>e.offset<=l&&e.offset+e.length>o));if(e.length<1)return a(new Error("Could not find file corresponnding to web seed range request"));u=e.map((e=>{const t=e.offset+e.length-1;return{url:this.url+("/"===this.url[this.url.length-1]?"":"/")+e.path,fileOffsetInRange:Math.max(e.offset-o,0),start:Math.max(o-e.offset,0),end:Math.min(t,l-e.offset)}}))}let d,h=0,f=!1;u.length>1&&(d=n.alloc(i)),u.forEach((n=>{const o=n.url,l=n.start,p=n.end;s("Requesting url=%s pieceIndex=%d offset=%d length=%d start=%d end=%d",o,e,t,i,l,p);const m={url:o,method:"GET",headers:{"user-agent":`WebTorrent/${c} (https://webtorrent.io)`,range:`bytes=${l}-${p}`}};function g(e,t){if(e.statusCode<200||e.statusCode>=300)return f=!0,a(new Error("Unexpected HTTP status code "+e.statusCode));s("Got data of length %d",t.length),1===u.length?a(null,t):(t.copy(d,n.fileOffsetInRange),++h===u.length&&a(null,d))}r.concat(m,((e,t,n)=>{if(!f)return e?"undefined"==typeof window||o.startsWith(window.location.origin+"/")?(f=!0,a(e)):r.head(o,((t,n)=>{if(!f){if(t)return f=!0,a(t);if(n.statusCode<200||n.statusCode>=300)return f=!0,a(new Error("Unexpected HTTP status code "+n.statusCode));if(n.url===o)return f=!0,a(e);m.url=n.url,r.concat(m,((e,t,n)=>{if(!f)return e?(f=!0,a(e)):void g(t,n)}))}})):void g(t,n)}))}))}destroy(){super.destroy(),this._torrent=null}}}).call(this)}).call(this,e("buffer").Buffer)},{"../package.json":332,bitfield:9,"bittorrent-protocol":10,buffer:59,debug:314,"simple-get":221,"simple-sha1":241}],314:[function(e,t,n){arguments[4][12][0].apply(n,arguments)},{"./common":315,_process:186,dup:12}],315:[function(e,t,n){arguments[4][13][0].apply(n,arguments)},{dup:13,ms:316}],316:[function(e,t,n){arguments[4][14][0].apply(n,arguments)},{dup:14}],317:[function(e,t,n){arguments[4][15][0].apply(n,arguments)},{dup:15}],318:[function(e,t,n){arguments[4][16][0].apply(n,arguments)},{"./_stream_readable":320,"./_stream_writable":322,_process:186,dup:16,inherits:118}],319:[function(e,t,n){arguments[4][17][0].apply(n,arguments)},{"./_stream_transform":321,dup:17,inherits:118}],320:[function(e,t,n){arguments[4][18][0].apply(n,arguments)},{"../errors":317,"./_stream_duplex":318,"./internal/streams/async_iterator":323,"./internal/streams/buffer_list":324,"./internal/streams/destroy":325,"./internal/streams/from":327,"./internal/streams/state":329,"./internal/streams/stream":330,_process:186,buffer:59,dup:18,events:97,inherits:118,"string_decoder/":285,util:54}],321:[function(e,t,n){arguments[4][19][0].apply(n,arguments)},{"../errors":317,"./_stream_duplex":318,dup:19,inherits:118}],322:[function(e,t,n){arguments[4][20][0].apply(n,arguments)},{"../errors":317,"./_stream_duplex":318,"./internal/streams/destroy":325,"./internal/streams/state":329,"./internal/streams/stream":330,_process:186,buffer:59,dup:20,inherits:118,"util-deprecate":304}],323:[function(e,t,n){arguments[4][21][0].apply(n,arguments)},{"./end-of-stream":326,_process:186,dup:21}],324:[function(e,t,n){arguments[4][22][0].apply(n,arguments)},{buffer:59,dup:22,util:54}],325:[function(e,t,n){arguments[4][23][0].apply(n,arguments)},{_process:186,dup:23}],326:[function(e,t,n){arguments[4][24][0].apply(n,arguments)},{"../../../errors":317,dup:24}],327:[function(e,t,n){arguments[4][25][0].apply(n,arguments)},{dup:25}],328:[function(e,t,n){arguments[4][26][0].apply(n,arguments)},{"../../../errors":317,"./end-of-stream":326,dup:26}],329:[function(e,t,n){arguments[4][27][0].apply(n,arguments)},{"../../../errors":317,dup:27}],330:[function(e,t,n){arguments[4][28][0].apply(n,arguments)},{dup:28,events:97}],331:[function(e,t,n){arguments[4][29][0].apply(n,arguments)},{"./lib/_stream_duplex.js":318,"./lib/_stream_passthrough.js":319,"./lib/_stream_readable.js":320,"./lib/_stream_transform.js":321,"./lib/_stream_writable.js":322,"./lib/internal/streams/end-of-stream.js":326,"./lib/internal/streams/pipeline.js":328,dup:29}],332:[function(e,t,n){t.exports={version:"0.110.1"}},{}],333:[function(e,t,n){t.exports=function e(t,n){if(t&&n)return e(t)(n);if("function"!=typeof t)throw new TypeError("need wrapper function");return Object.keys(t).forEach((function(e){i[e]=t[e]})),i;function i(){for(var e=new Array(arguments.length),n=0;n',i.addEventListener("click",H),t.appendChild(i),y.appendChild(t)}if(w.innerHTML="",l.urlList&&l.urlList.length)for(let e=0;e',i.addEventListener("click",H),t.appendChild(i),w.appendChild(t)}if(S.innerHTML="",l.files&&l.files.length){C.style.display="none";for(let e of l.files){let t=U(o.lookup(e.name));S.appendChild(O(t,e.name,e.length))}S.appendChild(O("folder-tree","",l.length)),A.addEventListener("click",W),A.disabled=!1}else I.torrents.length>0?(C.style.display="none",S.innerHTML=''):(C.style.display="block",S.innerHTML=''),A.removeEventListener("click",W),A.disabled=!0;T.setAttribute("data-clipboard-text",window.location.origin+"#"+s.toMagnetURI(l)),j.setAttribute("data-clipboard-text",s.toMagnetURI(l)),p.style.display="flex",window.location.hash=s.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"}function O(e,t,n){let i=document.createElement("tr"),s=document.createElement("td");s.innerHTML='',i.appendChild(s);let r=document.createElement("td");r.innerHTML=t,i.appendChild(r);let o=document.createElement("td");return o.innerHTML=a.format(n,{decimalPlaces:1,unitSeparator:" "}),i.appendChild(o),i}function U(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"):return"file-powerpoint";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 M(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=s.toMagnetURI(l),F()}function P(){document.getElementById("magnet").value="",document.getElementById("torrent").value="",p.style.display="none",d.value="",f.value="",m.value="",g.value="",v.value="",y.innerHTML="",w.innerHTML="",I.torrents.forEach((e=>e.destroy())),C.style.display="block",S.innerHTML="",window.location.hash="",T.setAttribute("data-clipboard-text",""),j.setAttribute("data-clipboard-text",""),document.title="Torrent Parts | Inspect and edit what's in your Torrent file or Magnet link"}async function N(){b.className="disabled",b.innerHTML="Adding...";try{let e=await fetch("https://newtrackon.com/api/100"),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)),F()}catch(e){console.error(e)}b.innerHTML="Add Known Working Trackers",b.className="",B()}function q(){l[this.dataset.type].unshift(""),B()}function H(){l[this.parentElement.className].splice(this.parentElement.dataset.index,1),B()}function D(e){l[e]=[],F(),B()}function F(){l.created=new Date,l.createdBy="Torrent Parts ",l.created?(f.value=l.created.toISOString().slice(0,19),f.type="datetime-local"):f.type="text",m.value=l.createdBy?"by "+l.createdBy:""}function z(){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)),I.add(s.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,F(),B(),e.destroy()})),B()}function W(){let e=s.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 n=window.URL.createObjectURL(new Blob([e],{type:"application/x-bittorrent"}));t.setAttribute("href",n),t.setAttribute("download",l.name+".torrent"),document.body.appendChild(t),t.click(),window.URL.revokeObjectURL(n),t.remove()}document.addEventListener("DOMContentLoaded",(function(){document.getElementById("magnet").addEventListener("keyup",(function(e){e.preventDefault(),"Enter"===e.key&&(u.innerHTML='',u.title="Currently loaded information sourced from Magnet URL",L(magnet.value))})),document.getElementById("torrent").addEventListener("change",(function(e){e.preventDefault();try{e.target.files[0].arrayBuffer().then((function(e){u.innerHTML='',u.title="Currently loaded information sourced from Torrent file",L(r.from(e))}))}catch(e){console.error(e)}}));let e=new i("#copyURL");e.on("success",(function(e){console.info(e)})),e.on("failure",(function(e){console.error(e)}));let t=new i("#copyMagnet");t.on("success",(function(e){console.info(e)})),t.on("failure",(function(e){console.error(e)})),d.addEventListener("input",M),d.addEventListener("change",M),d.addEventListener("reset",M),d.addEventListener("paste",M),h.addEventListener("click",P),g.addEventListener("input",M),g.addEventListener("change",M),g.addEventListener("reset",M),g.addEventListener("paste",M),b.addEventListener("click",N),x.addEventListener("click",q),_.addEventListener("click",(()=>D("announce"))),k.addEventListener("click",q),E.addEventListener("click",(()=>D("urlList"))),C.addEventListener("click",z),window.location.hash&&(u.innerHTML='',u.title="Currently loaded information sourced from shared torrent.parts link",L(window.location.hash.split("#")[1]))}))},{Buffer:1,bytes:61,clipboard:78,"mime-types":143,"parse-torrent":183,webtorrent:307}]},{},[335]); \ No newline at end of file +const{EventEmitter:r}=e("events"),a=e("simple-concat"),o=e("create-torrent"),c=e("debug")("webtorrent"),l=e("bittorrent-dht/client"),p=e("load-ip-set"),u=e("run-parallel"),d=e("parse-torrent"),h=e("path"),f=e("simple-peer"),m=e("randombytes"),g=e("speedometer"),v=e("./lib/conn-pool"),b=e("./lib/torrent"),x=e("./package.json").version,_=x.replace(/\d*./g,(e=>("0"+e%100).slice(-2))).slice(0,4),y=`-WW${_}-`;class w extends r{constructor(e={}){super(),"string"==typeof e.peerId?this.peerId=e.peerId:s.isBuffer(e.peerId)?this.peerId=e.peerId.toString("hex"):this.peerId=s.from(y+m(9).toString("base64")).toString("hex"),this.peerIdBuffer=s.from(this.peerId,"hex"),"string"==typeof e.nodeId?this.nodeId=e.nodeId:s.isBuffer(e.nodeId)?this.nodeId=e.nodeId.toString("hex"):this.nodeId=m(20).toString("hex"),this.nodeIdBuffer=s.from(this.nodeId,"hex"),this._debugId=this.peerId.toString("hex").substring(0,7),this.destroyed=!1,this.listening=!1,this.torrentPort=e.torrentPort||0,this.dhtPort=e.dhtPort||0,this.tracker=void 0!==e.tracker?e.tracker:{},this.torrents=[],this.maxConns=Number(e.maxConns)||55,this.utp=!0===e.utp,this._debug("new webtorrent (peerId %s, nodeId %s, port %s)",this.peerId,this.nodeId,this.torrentPort),this.tracker&&("object"!=typeof this.tracker&&(this.tracker={}),e.rtcConfig&&(console.warn("WebTorrent: opts.rtcConfig is deprecated. Use opts.tracker.rtcConfig instead"),this.tracker.rtcConfig=e.rtcConfig),e.wrtc&&(console.warn("WebTorrent: opts.wrtc is deprecated. Use opts.tracker.wrtc instead"),this.tracker.wrtc=e.wrtc),i.WRTC&&!this.tracker.wrtc&&(this.tracker.wrtc=i.WRTC)),"function"==typeof v?this._connPool=new v(this):n.nextTick((()=>{this._onListening()})),this._downloadSpeed=g(),this._uploadSpeed=g(),!1!==e.dht&&"function"==typeof l?(this.dht=new l(Object.assign({},{nodeId:this.nodeId},e.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!==e.webSeeds;const t=()=>{this.destroyed||(this.ready=!0,this.emit("ready"))};"function"==typeof p&&null!=e.blocklist?p(e.blocklist,{headers:{"user-agent":`WebTorrent/${x} (https://webtorrent.io)`}},((e,n)=>{if(e)return this.error("Failed to load blocklist: "+e.message);this.blocked=n,t()})):n.nextTick(t)}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 b){if(this.torrents.includes(e))return e}else{let t;try{t=d(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}download(e,t,n){return console.warn("WebTorrent: client.download() is deprecated. Use client.add() instead"),this.add(e,t,n)}add(e,t={},n=(()=>{})){if(this.destroyed)throw new Error("client is destroyed");"function"==typeof t&&([t,n]=[{},t]);const i=()=>{if(!this.destroyed)for(const e of this.torrents)if(e.infoHash===r.infoHash&&e!==r)return void r._destroy(new Error("Cannot add duplicate torrent "+r.infoHash))},s=()=>{this.destroyed||(n(r),this.emit("torrent",r))};this._debug("add"),t=t?Object.assign({},t):{};const r=new b(e,this,t);return this.torrents.push(r),r.once("_infoHash",i),r.once("ready",s),r.once("close",(function e(){r.removeListener("_infoHash",i),r.removeListener("ready",s),r.removeListener("close",e)})),r}seed(e,t,n){if(this.destroyed)throw new Error("client is destroyed");"function"==typeof t&&([t,n]=[{},t]),this._debug("seed"),(t=t?Object.assign({},t):{}).skipVerify=!0;const i="string"==typeof e;i&&(t.path=h.dirname(e)),t.createdBy||(t.createdBy="WebTorrent/"+_);const s=e=>{this._debug("on seed"),"function"==typeof n&&n(e),e.emit("seed"),this.emit("seed",e)},r=this.add(null,t,(e=>{const t=[t=>{if(i)return t();e.load(c,t)}];this.dht&&t.push((t=>{e.once("dhtAnnounce",t)})),u(t,(t=>{if(!this.destroyed)return t?e._destroy(t):void s(e)}))}));let c;var l;return l=e,"undefined"!=typeof FileList&&l instanceof FileList?e=Array.from(e):Array.isArray(e)||(e=[e]),u(e.map((e=>t=>{!function(e){return"object"==typeof e&&null!=e&&"function"==typeof e.pipe}(e)?t(null,e):a(e,t)})),((e,n)=>{if(!this.destroyed)return e?r._destroy(e):void o.parseInput(n,t,((e,i)=>{if(!this.destroyed){if(e)return r._destroy(e);c=i.map((e=>e.getStream)),o(n,t,((e,t)=>{if(this.destroyed)return;if(e)return r._destroy(e);const n=this.get(t);n?r._destroy(new Error("Cannot add duplicate torrent "+n.infoHash)):r._onTorrentId(t)}))}}))})),r}remove(e,t,n){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,n)}_remove(e,t,n){if("function"==typeof t)return this._remove(e,null,t);const i=this.get(e);i&&(this.torrents.splice(this.torrents.indexOf(i),1),i.destroy(t,n))}address(){return this.listening?this._connPool?this._connPool.tcpServer.address():{address:"0.0.0.0",family:"IPv4",port:0}:null}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 n=this.torrents.map((e=>t=>{e.destroy(t)}));this._connPool&&n.push((e=>{this._connPool.destroy(e)})),this.dht&&n.push((e=>{this.dht.destroy(e)})),u(n,t),e&&this.emit("error",e),this.torrents=[],this._connPool=null,this.dht=null}_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]}`,c(...e)}}w.WEBRTC_SUPPORT=f.WEBRTC_SUPPORT,w.VERSION=x,t.exports=w}).call(this)}).call(this,e("_process"),"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{},e("buffer").Buffer)},{"./lib/conn-pool":54,"./lib/torrent":312,"./package.json":332,_process:186,"bittorrent-dht/client":54,buffer:59,"create-torrent":79,debug:314,events:97,"load-ip-set":54,"parse-torrent":183,path:184,randombytes:194,"run-parallel":217,"simple-concat":220,"simple-peer":222,speedometer:262}],308:[function(e,t,n){const i=e("debug")("webtorrent:file-stream"),s=e("readable-stream");class r extends s.Readable{constructor(e,t){super(t),this.destroyed=!1,this._torrent=e._torrent;const n=t&&t.start||0,i=t&&t.end&&t.end{if(this._notifying=!1,!this.destroyed){if(i("read %s (length %s) (err %s)",e,n.length,t&&t.message),t)return this._destroy(t);this._offset&&(n=n.slice(this._offset),this._offset=0),this._missing{e.end()})),e}const t=new u(this,e);return this._torrent.select(t._startPiece,t._endPiece,!0,(()=>{t._notify()})),r(t,(()=>{this._destroyed||this._torrent.destroyed||this._torrent.deselect(t._startPiece,t._endPiece,!0)})),t}getBuffer(e){p(this.createReadStream(),this.length,e)}getBlob(e){if("undefined"==typeof window)throw new Error("browser-only method");c(this.createReadStream(),this._getMimeType()).then((t=>e(null,t)),(t=>e(t)))}getBlobURL(e){if("undefined"==typeof window)throw new Error("browser-only method");l(this.createReadStream(),this._getMimeType()).then((t=>e(null,t)),(t=>e(t)))}appendTo(e,t,n){if("undefined"==typeof window)throw new Error("browser-only method");o.append(this,e,t,n)}renderTo(e,t,n){if("undefined"==typeof window)throw new Error("browser-only method");o.render(this,e,t,n)}_getMimeType(){return o.mime[a.extname(this.name).toLowerCase()]}_destroy(){this._destroyed=!0,this._torrent=null}}}).call(this)}).call(this,e("_process"))},{"./file-stream":308,_process:186,"end-of-stream":95,events:97,path:184,"readable-stream":331,"render-media":211,"stream-to-blob":283,"stream-to-blob-url":282,"stream-with-known-length-to-buffer":284}],310:[function(e,t,n){const i=e("unordered-array-remove"),s=e("debug")("webtorrent:peer"),r=e("bittorrent-protocol"),a=e("./webconn");n.createWebRTCPeer=(e,t)=>{const n=new l(e.id,"webrtc");return n.conn=e,n.swarm=t,n.conn.connected?n.onConnect():(n.conn.once("connect",(()=>{n.onConnect()})),n.conn.once("error",(e=>{n.destroy(e)})),n.startConnectTimeout()),n},n.createTCPIncomingPeer=e=>o(e,"tcpIncoming"),n.createUTPIncomingPeer=e=>o(e,"utpIncoming"),n.createTCPOutgoingPeer=(e,t)=>c(e,t,"tcpOutgoing"),n.createUTPOutgoingPeer=(e,t)=>c(e,t,"utpOutgoing");const o=(e,t)=>{const n=`${e.remoteAddress}:${e.remotePort}`,i=new l(n,t);return i.conn=e,i.addr=n,i.onConnect(),i},c=(e,t,n)=>{const i=new l(e,n);return i.addr=e,i.swarm=t,i};n.createWebSeedPeer=(e,t)=>{const n=new l(e,"webSeed");return n.swarm=t,n.conn=new a(e,t),n.onConnect(),n};class l{constructor(e,t){this.id=e,this.type=t,s("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.sentHandshake=!1}onConnect(){if(this.destroyed)return;this.connected=!0,s("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 r;t.type=this.type,t.once("end",(()=>{this.destroy()})),t.once("close",(()=>{this.destroy()})),t.once("finish",(()=>{this.destroy()})),t.once("error",(e=>{this.destroy(e)})),t.once("handshake",((e,t)=>{this.onHandshake(e,t)})),this.startHandshakeTimeout(),e.pipe(t).pipe(e),this.swarm&&!this.sentHandshake&&this.handshake()}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"));s("Peer %s got handshake %s",this.id,e),clearTimeout(this.handshakeTimeout),this.retries=0;let n=this.addr;!n&&this.conn.remoteAddress&&this.conn.remotePort&&(n=`${this.conn.remoteAddress}:${this.conn.remotePort}`),this.swarm._onWire(this.wire,n),this.swarm&&!this.swarm.destroyed&&(this.sentHandshake||this.handshake())}handshake(){const e={dht:!this.swarm.private&&!!this.swarm.client.dht};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,s("destroy %s %s (error: %s)",this.type,this.id,e&&(e.message||e)),clearTimeout(this.connectTimeout),clearTimeout(this.handshakeTimeout);const t=this.swarm,n=this.conn,r=this.wire;this.swarm=null,this.conn=null,this.wire=null,t&&r&&i(t.wires,t.wires.indexOf(r)),n&&(n.on("error",(()=>{})),n.destroy()),r&&r.destroy(),t&&t.removePeer(this.id)}}},{"./webconn":313,"bittorrent-protocol":10,debug:314,"unordered-array-remove":296}],311:[function(e,t,n){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=[],n=1/0;for(let i=0;i{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;t{this.destroyed||this._onParsedTorrent(t)}))):x.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.path||(this.path=_.join(N,this.infoHash)),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&&i.WEBTORRENT_ANNOUNCE&&!e.private&&(e.announce=e.announce.concat(i.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=x.toMagnetURI(e),this.torrentFile=x.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:()=>{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 c({infoHash:this.infoHash,announce:this.announce,peerId:this.client.peerId,dht:!this.private&&this.client.dht,tracker:e,port:this.client.torrentPort,userAgent:P}),this.discovery.on("error",(e=>{this._destroy(e)})),this.discovery.on("peer",(e=>{"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=>n=>{!function(t,n){if(0!==t.indexOf("http://")&&0!==t.indexOf("https://"))return e.emit("warning",new Error("skipping non-http xs param: "+t)),n(null);const i={url:t,method:"GET",headers:{"user-agent":P}};let s;try{s=d.concat(i,r)}catch(i){return e.emit("warning",new Error("skipping invalid url xs param: "+t)),n(null)}function r(i,s,r){if(e.destroyed)return n(null);if(e.metadata)return n(null);if(i)return e.emit("warning",new Error("http error from xs param: "+t)),n(null);if(200!==s.statusCode)return e.emit("warning",new Error(`non-200 status code ${s.statusCode} from xs param: ${t}`)),n(null);let a;try{a=x(r)}catch(i){}return a?a.infoHash!==e.infoHash?(e.emit("warning",new Error("got torrent file with incorrect info hash from xs param: "+t)),n(null)):(e._onMetadata(a),void n(null)):(e.emit("warning",new Error("got invalid torrent file from xs param: "+t)),n(null))}e._xsRequests.push(s)}(t,n)}));v(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=x(e)}catch(e){return this._destroy(e)}if(this._processParsedTorrent(t),this.metadata=this.torrentFile,this.client.enableWebSeeds&&this.urlList.forEach((e=>{this.addWebSeed(e)})),this._rarityMap=new L(this),this.store=new h(new this._store(this.pieceLength,{torrent:{infoHash:this.infoHash},files:this.files.map((e=>({path:_.join(this.path,e.path),length:e.length,offset:e.offset}))),length:this.length,name:this.infoHash})),this.files=this.files.map((e=>new A(this,e))),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 n=t===this.pieces.length-1?this.lastPieceLength:this.pieceLength;return new y(n)})),this._reservations=this.pieces.map((()=>[])),this.bitfield=new r(this.pieces.length),this.wires.forEach((e=>{e.ut_metadata&&e.ut_metadata.setMetadata(this.metadata),this._onWireWithMetadata(e)})),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===u?this.getFileModtimes(((t,n)=>{if(t)return this._destroy(t);this.files.map(((e,t)=>n[t]===this._fileModtimes[t])).every((e=>e))?(this._markAllVerified(),this._onStore()):this._verifyPieces(e)})):this._verifyPieces(e)}}getFileModtimes(e){const t=[];b(this.files.map(((e,n)=>i=>{p.stat(_.join(this.path,e.path),((e,s)=>{if(e&&"ENOENT"!==e.code)return i(e);t[n]=s&&s.mtime.getTime(),i(null)}))})),U,(n=>{this._debug("done getting file modtimes"),e(n,t)}))}_verifyPieces(e){b(this.pieces.map(((e,t)=>e=>{if(this.destroyed)return e(new Error("torrent is destroyed"));this.store.get(t,((i,s)=>this.destroyed?e(new Error("torrent is destroyed")):i?n.nextTick(e,null):void E(s,(n=>{if(this.destroyed)return e(new Error("torrent is destroyed"));if(n===this._hashes[t]){if(!this.pieces[t])return e(null);this._debug("piece verified %s",t),this._markVerified(t)}else this._debug("piece invalid %s",t);e(null)}))))})),U,e)}rescanFiles(e){if(this.destroyed)throw new Error("torrent is destroyed");e||(e=H),this._verifyPieces((t=>{if(t)return this._destroy(t),e(t);this._checkDone(),e(null)}))}_markAllVerified(){for(let e=0;e{e.abort()})),this._rarityMap&&this._rarityMap.destroy();for(const e in this._peers)this.removePeer(e);this.files.forEach((e=>{e instanceof A&&e._destroy()}));const i=this._servers.map((e=>t=>{e.destroy(t)}));this.discovery&&i.push((e=>{this.discovery.destroy(e)})),this.store&&i.push((e=>{t&&t.destroyStore?this.store.destroy(e):this.store.close(e)})),v(i,n),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");if(this.client.blocked){let t;if("string"==typeof e){let n;try{n=s(e)}catch(t){return this._debug("ignoring peer: invalid %s",e),this.emit("invalidPeer",e),!1}t=n[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 t=!!this._addPeer(e,this.client.utp?"utp":"tcp");return t?this.emit("peer",e):this.emit("invalidPeer",e),t}_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 n=e&&e.id||e;if(this._peers[n])return this._debug("ignoring peer: duplicate (%s)",n),"string"!=typeof e&&e.destroy(),null;if(this.paused)return this._debug("ignoring peer: torrent is paused"),"string"!=typeof e&&e.destroy(),null;let i;return this._debug("add peer %s",n),i="string"==typeof e?"utp"===t?I.createUTPOutgoingPeer(e,this):I.createTCPOutgoingPeer(e,this):I.createWebRTCPeer(e,this),this._peers[i.id]=i,this._peersLength+=1,"string"==typeof e&&(this._queue.push(i),this._drain()),i}addWebSeed(e){if(this.destroyed)throw new Error("torrent is destroyed");if(!/^https?:\/\/.+/.test(e))return this.emit("warning",new Error("ignoring invalid web seed: "+e)),void this.emit("invalidPeer",e);if(this._peers[e])return this.emit("warning",new Error("ignoring duplicate web seed: "+e)),void this.emit("invalidPeer",e);this._debug("add web seed %s",e);const t=I.createWebSeedPeer(e,this);this._peers[t.id]=t,this._peersLength+=1,this.emit("peer",e)}_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),this._peers[e.id]=e,void(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,n,i){if(this.destroyed)throw new Error("torrent is destroyed");if(e<0||tt.priority-e.priority)),this._updateSelections()}deselect(e,t,n){if(this.destroyed)throw new Error("torrent is destroyed");n=Number(n)||0,this._debug("deselect %s-%s (priority %s)",e,t,n);for(let i=0;i{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.wires.push(e),t){const n=s(t);e.remoteAddress=n[0],e.remotePort=n[1]}this.client.dht&&this.client.dht.listening&&e.on("port",(n=>{if(!this.destroyed&&!this.client.dht.destroyed){if(!e.remoteAddress)return this._debug("ignoring PORT from peer with no address");if(0===n||n>65536)return this._debug("ignoring invalid PORT from peer");this._debug("port: %s (from %s)",n,t),this.client.dht.addNode({host:e.remoteAddress,port:n})}})),e.on("timeout",(()=>{this._debug("wire timeout (%s)",t),e.destroy()})),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 T||this.private||(e.use(T()),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 n=this._peers[e];n&&!n.connected&&(this._debug("ut_pex: dropped peer: %s (from %s)",e,t),this.removePeer(e))})),e.once("close",(()=>{e.ut_pex.reset()}))),this.emit("wire",e,t),this.metadata&&n.nextTick((()=>{this._onWireWithMetadata(e)}))}_onWireWithMetadata(e){let t=null;const n=()=>{this.destroyed||e.destroyed||(this._numQueued>2*(this._numConns-this.numPeers)&&e.amInterested?e.destroy():(t=setTimeout(n,B),t.unref&&t.unref()))};let i;const s=()=>{if(e.peerPieces.buffer.length===this.bitfield.buffer.length){for(i=0;i{s(),this._update(),this._updateWireInterest(e)})),e.on("have",(()=>{s(),this._update(),this._updateWireInterest(e)})),e.once("interested",(()=>{e.unchoke()})),e.once("close",(()=>{clearTimeout(t)})),e.on("choke",(()=>{clearTimeout(t),t=setTimeout(n,B),t.unref&&t.unref()})),e.on("unchoke",(()=>{clearTimeout(t),this._update()})),e.on("request",((t,n,i,s)=>{if(i>131072)return e.destroy();this.pieces[t]||this.store.get(t,{offset:n,length:i},s)})),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(n,B),t.unref&&t.unref()),e.isSeeder=!1,s()}_updateSelections(){this.ready&&!this.destroyed&&(n.nextTick((()=>{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 n=0;n=i.from+i.offset;--r)if(e.peerPieces.get(r)&&t._request(e,r,!1))return}}();const n=q(e,.5);if(e.requests.length>=n)return;const i=q(e,1);function s(t,n,i,s){return r=>r>=t&&r<=n&&!(r in i)&&e.peerPieces.get(r)&&(!s||s(r))}function r(e){let n=e;for(let i=e;i=i)return!0;const a=function(){const n=e.downloadSpeed()||1;if(n>O)return()=>!0;const i=Math.max(1,e.requests.length)*y.BLOCK_LENGTH/n;let s=10,r=0;return e=>{if(!s||t.bitfield.get(e))return!0;let a=t.pieces[e].missing;for(;r0))return s--,!1}return!0}}();for(let o=0;o({wire:e,random:Math.random()}))).sort(((e,t)=>{const n=e.wire,i=t.wire;return n.downloadSpeed()!==i.downloadSpeed()?n.downloadSpeed()-i.downloadSpeed():n.uploadSpeed()!==i.uploadSpeed()?n.uploadSpeed()-i.uploadSpeed():n.amChoking!==i.amChoking?n.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[(n=t.length,Math.random()*n|0)];e.unchoke(),this._rechokeOptimisticWire=e,this._rechokeOptimisticTime=2}}var n;e.filter((e=>e!==this._rechokeOptimisticWire)).forEach((e=>e.choke()))}_hotswap(e,t){const n=e.downloadSpeed();if(n=O||(2*o>n||o>a||(s=t,a=o))}if(!s)return!1;for(r=0;r=(a?Math.min(function(e,t,n){return 1+Math.ceil(t*e.downloadSpeed()/n)}(e,1,s.pieceLength),s.maxWebConns):q(e,1)))return!1;const o=s.pieces[t];let c=a?o.reserveRemaining():o.reserve();if(-1===c&&i&&s._hotswap(e,t)&&(c=a?o.reserveRemaining():o.reserve()),-1===c)return!1;let l=s._reservations[t];l||(l=s._reservations[t]=[]);let p=l.indexOf(null);-1===p&&(p=l.length),l[p]=e;const u=o.chunkOffset(c),d=a?o.chunkLengthRemaining(c):o.chunkLength(c);function h(){n.nextTick((()=>{s._update()}))}return e.request(t,u,d,(function n(i,r){if(s.destroyed)return;if(!s.ready)return s.once("ready",(()=>{n(i,r)}));if(l[p]===e&&(l[p]=null),o!==s.pieces[t])return h();if(i)return s._debug("error getting piece %s (offset: %s length: %s) from %s: %s",t,u,d,`${e.remoteAddress}:${e.remotePort}`,i.message),a?o.cancelRemaining(c):o.cancel(c),void h();if(s._debug("got piece %s (offset: %s length: %s) from %s",t,u,d,`${e.remoteAddress}:${e.remotePort}`),!o.set(c,r,e))return h();const f=o.flush();E(f,(e=>{if(!s.destroyed){if(e===s._hashes[t]){if(!s.pieces[t])return;s._debug("piece verified %s",t),s.pieces[t]=null,s._reservations[t]=null,s.bitfield.set(t,!0),s.store.put(t,f),s.wires.forEach((e=>{e.have(t)})),s._checkDone()&&!s.destroyed&&s.discovery.complete()}else s.pieces[t]=new y(o.length),s.emit("warning",new Error(`Piece ${t} failed verification`));h()}}))})),!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(let t=0;t{this.load(e,t)}));Array.isArray(e)||(e=[e]),t||(t=H);const n=new f(e),i=new a(this.store,this.pieceLength);w(n,i,(e=>{if(e)return t(e);this._markAllVerified(),this._checkDone(),t(null)}))}createServer(e){if("function"!=typeof R)throw new Error("node.js-only method");if(this.destroyed)throw new Error("torrent is destroyed");const t=new R(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]}`,o(...e)}_drain(){if(this._debug("_drain numConns %s maxConns %s",this._numConns,this.client.maxConns),"function"!=typeof m.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=s(e.addr),n={host:t[0],port:t[1]};"utpOutgoing"===e.type?e.conn=j.connect(n.port,n.host):e.conn=m.connect(n);const i=e.conn;i.once("connect",(()=>{e.onConnect()})),i.once("error",(t=>{e.destroy(t)})),e.startConnectTimeout(),i.on("close",(()=>{if(this.destroyed)return;if(e.retries>=M.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,M.length);return}const t=M[e.retries];this._debug("conn %s closed: will re-add to queue in %sms (attempt %s)",e.addr,t,e.retries+1);const n=setTimeout((()=>{if(this.destroyed)return;const t=this._addPeer(e.addr,this.client.utp?"utp":"tcp");t&&(t.retries=e.retries+1)}),t);n.unref&&n.unref()}))}_validAddr(e){let t;try{t=s(e)}catch(e){return!1}const n=t[0],i=t[1];return i>0&&i<65535&&!("127.0.0.1"===n&&i===this.client.torrentPort)}}}).call(this)}).call(this,e("_process"),"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"../package.json":332,"./file":309,"./peer":310,"./rarity-map":311,"./server":54,_process:186,"addr-to-ip-port":2,bitfield:9,"chunk-store-stream/write":77,debug:314,events:97,fs:55,"fs-chunk-store":140,"immediate-chunk-store":117,multistream:165,net:54,os:54,"parse-torrent":183,path:184,pump:187,"random-iterate":193,"run-parallel":217,"run-parallel-limit":216,"simple-get":221,"simple-sha1":241,speedometer:262,"torrent-discovery":289,"torrent-piece":293,ut_metadata:299,ut_pex:54,"utp-native":54}],313:[function(e,t,n){(function(n){(function(){const i=e("bitfield"),s=e("debug")("webtorrent:webconn"),r=e("simple-get"),a=e("simple-sha1"),o=e("bittorrent-protocol"),c=e("../package.json").version;t.exports=class extends o{constructor(e,t){super(),this.url=e,this.webPeerId=a.sync(e),this._torrent=t,this._init()}_init(){this.setKeepAlive(!0),this.once("handshake",((e,t)=>{if(this.destroyed)return;this.handshake(e,this.webPeerId);const n=this._torrent.pieces.length,s=new i(n);for(let e=0;e<=n;e++)s.set(e,!0);this.bitfield(s)})),this.once("interested",(()=>{s("interested"),this.unchoke()})),this.on("uninterested",(()=>{s("uninterested")})),this.on("choke",(()=>{s("choke")})),this.on("unchoke",(()=>{s("unchoke")})),this.on("bitfield",(()=>{s("bitfield")})),this.on("request",((e,t,n,i)=>{s("request pieceIndex=%d offset=%d length=%d",e,t,n),this.httpRequest(e,t,n,i)}))}httpRequest(e,t,i,a){const o=e*this._torrent.pieceLength+t,l=o+i-1,p=this._torrent.files;let u;if(p.length<=1)u=[{url:this.url,start:o,end:l}];else{const e=p.filter((e=>e.offset<=l&&e.offset+e.length>o));if(e.length<1)return a(new Error("Could not find file corresponnding to web seed range request"));u=e.map((e=>{const t=e.offset+e.length-1;return{url:this.url+("/"===this.url[this.url.length-1]?"":"/")+e.path,fileOffsetInRange:Math.max(e.offset-o,0),start:Math.max(o-e.offset,0),end:Math.min(t,l-e.offset)}}))}let d,h=0,f=!1;u.length>1&&(d=n.alloc(i)),u.forEach((n=>{const o=n.url,l=n.start,p=n.end;s("Requesting url=%s pieceIndex=%d offset=%d length=%d start=%d end=%d",o,e,t,i,l,p);const m={url:o,method:"GET",headers:{"user-agent":`WebTorrent/${c} (https://webtorrent.io)`,range:`bytes=${l}-${p}`}};function g(e,t){if(e.statusCode<200||e.statusCode>=300)return f=!0,a(new Error("Unexpected HTTP status code "+e.statusCode));s("Got data of length %d",t.length),1===u.length?a(null,t):(t.copy(d,n.fileOffsetInRange),++h===u.length&&a(null,d))}r.concat(m,((e,t,n)=>{if(!f)return e?"undefined"==typeof window||o.startsWith(window.location.origin+"/")?(f=!0,a(e)):r.head(o,((t,n)=>{if(!f){if(t)return f=!0,a(t);if(n.statusCode<200||n.statusCode>=300)return f=!0,a(new Error("Unexpected HTTP status code "+n.statusCode));if(n.url===o)return f=!0,a(e);m.url=n.url,r.concat(m,((e,t,n)=>{if(!f)return e?(f=!0,a(e)):void g(t,n)}))}})):void g(t,n)}))}))}destroy(){super.destroy(),this._torrent=null}}}).call(this)}).call(this,e("buffer").Buffer)},{"../package.json":332,bitfield:9,"bittorrent-protocol":10,buffer:59,debug:314,"simple-get":221,"simple-sha1":241}],314:[function(e,t,n){arguments[4][12][0].apply(n,arguments)},{"./common":315,_process:186,dup:12}],315:[function(e,t,n){arguments[4][13][0].apply(n,arguments)},{dup:13,ms:316}],316:[function(e,t,n){arguments[4][14][0].apply(n,arguments)},{dup:14}],317:[function(e,t,n){arguments[4][15][0].apply(n,arguments)},{dup:15}],318:[function(e,t,n){arguments[4][16][0].apply(n,arguments)},{"./_stream_readable":320,"./_stream_writable":322,_process:186,dup:16,inherits:118}],319:[function(e,t,n){arguments[4][17][0].apply(n,arguments)},{"./_stream_transform":321,dup:17,inherits:118}],320:[function(e,t,n){arguments[4][18][0].apply(n,arguments)},{"../errors":317,"./_stream_duplex":318,"./internal/streams/async_iterator":323,"./internal/streams/buffer_list":324,"./internal/streams/destroy":325,"./internal/streams/from":327,"./internal/streams/state":329,"./internal/streams/stream":330,_process:186,buffer:59,dup:18,events:97,inherits:118,"string_decoder/":285,util:54}],321:[function(e,t,n){arguments[4][19][0].apply(n,arguments)},{"../errors":317,"./_stream_duplex":318,dup:19,inherits:118}],322:[function(e,t,n){arguments[4][20][0].apply(n,arguments)},{"../errors":317,"./_stream_duplex":318,"./internal/streams/destroy":325,"./internal/streams/state":329,"./internal/streams/stream":330,_process:186,buffer:59,dup:20,inherits:118,"util-deprecate":304}],323:[function(e,t,n){arguments[4][21][0].apply(n,arguments)},{"./end-of-stream":326,_process:186,dup:21}],324:[function(e,t,n){arguments[4][22][0].apply(n,arguments)},{buffer:59,dup:22,util:54}],325:[function(e,t,n){arguments[4][23][0].apply(n,arguments)},{_process:186,dup:23}],326:[function(e,t,n){arguments[4][24][0].apply(n,arguments)},{"../../../errors":317,dup:24}],327:[function(e,t,n){arguments[4][25][0].apply(n,arguments)},{dup:25}],328:[function(e,t,n){arguments[4][26][0].apply(n,arguments)},{"../../../errors":317,"./end-of-stream":326,dup:26}],329:[function(e,t,n){arguments[4][27][0].apply(n,arguments)},{"../../../errors":317,dup:27}],330:[function(e,t,n){arguments[4][28][0].apply(n,arguments)},{dup:28,events:97}],331:[function(e,t,n){arguments[4][29][0].apply(n,arguments)},{"./lib/_stream_duplex.js":318,"./lib/_stream_passthrough.js":319,"./lib/_stream_readable.js":320,"./lib/_stream_transform.js":321,"./lib/_stream_writable.js":322,"./lib/internal/streams/end-of-stream.js":326,"./lib/internal/streams/pipeline.js":328,dup:29}],332:[function(e,t,n){t.exports={version:"0.110.1"}},{}],333:[function(e,t,n){t.exports=function e(t,n){if(t&&n)return e(t)(n);if("function"!=typeof t)throw new TypeError("need wrapper function");return Object.keys(t).forEach((function(e){i[e]=t[e]})),i;function i(){for(var e=new Array(arguments.length),n=0;n',i.addEventListener("click",H),t.appendChild(i),y.appendChild(t)}if(w.innerHTML="",l.urlList&&l.urlList.length)for(let e=0;e',i.addEventListener("click",H),t.appendChild(i),w.appendChild(t)}if(S.innerHTML="",l.files&&l.files.length){C.style.display="none";for(let e of l.files){let t=U(o.lookup(e.name));S.appendChild(O(t,e.name,e.length))}S.appendChild(O("folder-tree","",l.length)),A.addEventListener("click",W),A.disabled=!1}else I.torrents.length>0?(C.style.display="none",S.innerHTML=''):(C.style.display="block",S.innerHTML=''),A.removeEventListener("click",W),A.disabled=!0;T.setAttribute("data-clipboard-text",window.location.origin+"#"+s.toMagnetURI(l)),j.setAttribute("data-clipboard-text",s.toMagnetURI(l)),p.style.display="flex",window.location.hash=s.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"}function O(e,t,n){let i=document.createElement("tr"),s=document.createElement("td");s.innerHTML='',i.appendChild(s);let r=document.createElement("td");r.innerHTML=t,i.appendChild(r);let o=document.createElement("td");return o.innerHTML=a.format(n,{decimalPlaces:1,unitSeparator:" "}),i.appendChild(o),i}function U(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"):return"file-powerpoint";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 M(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=s.toMagnetURI(l),F()}function P(){document.getElementById("magnet").value="",document.getElementById("torrent").value="",u.innerHTML='',u.title="",p.style.display="none",d.value="",f.value="",m.value="",g.value="",v.value="",y.innerHTML="",w.innerHTML="",I.torrents.forEach((e=>e.destroy())),C.style.display="block",S.innerHTML="",window.location.hash="",T.setAttribute("data-clipboard-text",""),j.setAttribute("data-clipboard-text",""),document.title="Torrent Parts | Inspect and edit what's in your Torrent file or Magnet link"}async function N(){b.className="disabled",b.innerHTML="Adding...";try{let e=await fetch("https://newtrackon.com/api/100"),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)),F()}catch(e){console.error(e)}b.innerHTML="Add Known Working Trackers",b.className="",B()}function q(){l[this.dataset.type].unshift(""),B()}function H(){l[this.parentElement.className].splice(this.parentElement.dataset.index,1),B()}function D(e){l[e]=[],F(),B()}function F(){l.created=new Date,l.createdBy="Torrent Parts ",l.created?(f.value=l.created.toISOString().slice(0,19),f.type="datetime-local"):f.type="text",m.value=l.createdBy?"by "+l.createdBy:""}function z(){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)),I.add(s.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,F(),B(),e.destroy()})),B()}function W(){let e=s.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 n=window.URL.createObjectURL(new Blob([e],{type:"application/x-bittorrent"}));t.setAttribute("href",n),t.setAttribute("download",l.name+".torrent"),document.body.appendChild(t),t.click(),window.URL.revokeObjectURL(n),t.remove()}document.addEventListener("DOMContentLoaded",(function(){document.getElementById("magnet").addEventListener("keyup",(function(e){e.preventDefault(),"Enter"===e.key&&(u.innerHTML='',u.title="Currently loaded information sourced from Magnet URL",L(magnet.value))})),document.getElementById("torrent").addEventListener("change",(function(e){e.preventDefault();try{e.target.files[0].arrayBuffer().then((function(e){u.innerHTML='',u.title="Currently loaded information sourced from Torrent file",L(r.from(e))}))}catch(e){console.error(e)}}));let e=new i("#copyURL");e.on("success",(function(e){console.info(e)})),e.on("failure",(function(e){console.error(e)}));let t=new i("#copyMagnet");t.on("success",(function(e){console.info(e)})),t.on("failure",(function(e){console.error(e)})),d.addEventListener("input",M),d.addEventListener("change",M),d.addEventListener("reset",M),d.addEventListener("paste",M),h.addEventListener("click",P),g.addEventListener("input",M),g.addEventListener("change",M),g.addEventListener("reset",M),g.addEventListener("paste",M),b.addEventListener("click",N),x.addEventListener("click",q),_.addEventListener("click",(()=>D("announce"))),k.addEventListener("click",q),E.addEventListener("click",(()=>D("urlList"))),C.addEventListener("click",z),window.location.hash&&(u.innerHTML='',u.title="Currently loaded information sourced from shared torrent.parts link",L(window.location.hash.split("#")[1]))}))},{Buffer:1,bytes:61,clipboard:78,"mime-types":143,"parse-torrent":183,webtorrent:307}]},{},[335]); \ No newline at end of file diff --git a/favicon.ico b/favicon.ico new file mode 100644 index 0000000..2870e11 Binary files /dev/null and b/favicon.ico differ diff --git a/img/TorrentParts-Favicon-16.png b/img/TorrentParts-Favicon-16.png new file mode 100644 index 0000000..c53f2ed Binary files /dev/null and b/img/TorrentParts-Favicon-16.png differ diff --git a/img/TorrentParts-Favicon-32.png b/img/TorrentParts-Favicon-32.png new file mode 100644 index 0000000..3772cdd Binary files /dev/null and b/img/TorrentParts-Favicon-32.png differ diff --git a/img/TorrentParts-Favicon.psd b/img/TorrentParts-Favicon.psd new file mode 100644 index 0000000..f251d83 Binary files /dev/null and b/img/TorrentParts-Favicon.psd differ diff --git a/img/TorrentParts-Icon-.5x.png b/img/TorrentParts-Icon-.5x.png new file mode 100644 index 0000000..be92f87 Binary files /dev/null and b/img/TorrentParts-Icon-.5x.png differ diff --git a/img/TorrentParts-Icon-1x.png b/img/TorrentParts-Icon-1x.png new file mode 100644 index 0000000..24ffe8e Binary files /dev/null and b/img/TorrentParts-Icon-1x.png differ diff --git a/img/TorrentParts-Icon-2x.png b/img/TorrentParts-Icon-2x.png new file mode 100644 index 0000000..3cb2414 Binary files /dev/null and b/img/TorrentParts-Icon-2x.png differ diff --git a/img/TorrentParts-Icon.psd b/img/TorrentParts-Icon.psd new file mode 100644 index 0000000..c08f506 Binary files /dev/null and b/img/TorrentParts-Icon.psd differ diff --git a/img/TorrentParts-Social.png b/img/TorrentParts-Social.png new file mode 100644 index 0000000..dd8826b Binary files /dev/null and b/img/TorrentParts-Social.png differ diff --git a/img/TorrentParts-Social.psd b/img/TorrentParts-Social.psd new file mode 100644 index 0000000..87b52db Binary files /dev/null and b/img/TorrentParts-Social.psd differ diff --git a/index.html b/index.html index 0227037..5e0ff0a 100644 --- a/index.html +++ b/index.html @@ -10,6 +10,27 @@ + + + + + + + + + + + + + + + + + + + + + Torrent Parts | Inspect and edit what's in your Torrent file or Magnet link diff --git a/parse.js b/parse.js index 707f732..8d62ee7 100644 --- a/parse.js +++ b/parse.js @@ -298,6 +298,8 @@ function propertyChange(e) { function resetProperties() { document.getElementById('magnet').value = ""; document.getElementById('torrent').value = ""; + originalSourceIcon.innerHTML = ''; + originalSourceIcon.title = ''; properties.style.display = 'none'; name.value = ""; created.value = ""; diff --git a/site.webmanifest b/site.webmanifest new file mode 100644 index 0000000..3b543b9 --- /dev/null +++ b/site.webmanifest @@ -0,0 +1,26 @@ +{ + "name": "Torrent Parts", + "description": "Inspect and edit what's in your Torrent file or Magnet link", + "theme_color": "#102030", + "background_color": "#102030", + "scope": "/", + "start_url": "/", + "display": "minimal-ui", + "icons": [ + { + "src": "/img/TorrentParts-Icon-.5x.png", + "sizes": "64x64", + "type": "image/png" + }, + { + "src": "/img/TorrentParts-Icon-1x.png", + "sizes": "128x128", + "type": "image/png" + }, + { + "src": "/img/TorrentParts-Icon-2x.png", + "sizes": "256x256", + "type": "image/png" + } + ] +} \ No newline at end of file