Improve Accessibility

This commit is contained in:
Leo Herzog committed 2020-11-11 21:44:28 -05:00
1 parent f09514e8d5
commit 8e12c1b6b4
5 files changed
+144 -117

No files matched your search

+102 -87
View File
@@ -2123,9 +2123,7 @@ function fromByteArray (uint8) {
// go through the array every three bytes, we'll deal with trailing stuff later // go through the array every three bytes, we'll deal with trailing stuff later
for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) { for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) {
parts.push(encodeChunk( parts.push(encodeChunk(uint8, i, (i + maxChunkLength) > len2 ? len2 : (i + maxChunkLength)))
uint8, i, (i + maxChunkLength) > len2 ? len2 : (i + maxChunkLength)
))
} }
// pad the end with zeros, but make sure to not forget the extra bytes // pad the end with zeros, but make sure to not forget the extra bytes
@@ -27514,18 +27512,18 @@ simpleGet.concat = (opts, cb) => {
}).call(this)}).call(this,require("buffer").Buffer) }).call(this)}).call(this,require("buffer").Buffer)
},{"buffer":60,"decompress-response":55,"http":264,"https":116,"once":183,"querystring":192,"simple-concat":221,"url":299}],223:[function(require,module,exports){ },{"buffer":60,"decompress-response":55,"http":264,"https":116,"once":183,"querystring":192,"simple-concat":221,"url":299}],223:[function(require,module,exports){
(function (Buffer){(function (){
/*! simple-peer. MIT License. Feross Aboukhadijeh <https://feross.org/opensource> */ /*! simple-peer. MIT License. Feross Aboukhadijeh <https://feross.org/opensource> */
var debug = require('debug')('simple-peer') const debug = require('debug')('simple-peer')
var getBrowserRTC = require('get-browser-rtc') const getBrowserRTC = require('get-browser-rtc')
var randombytes = require('randombytes') const randombytes = require('randombytes')
var stream = require('readable-stream') const stream = require('readable-stream')
var queueMicrotask = require('queue-microtask') // TODO: remove when Node 10 is not supported const queueMicrotask = require('queue-microtask') // TODO: remove when Node 10 is not supported
var errCode = require('err-code') const errCode = require('err-code')
const { Buffer } = require('buffer')
var MAX_BUFFERED_AMOUNT = 64 * 1024 const MAX_BUFFERED_AMOUNT = 64 * 1024
var ICECOMPLETE_TIMEOUT = 5 * 1000 const ICECOMPLETE_TIMEOUT = 5 * 1000
var CHANNEL_CLOSING_TIMEOUT = 5 * 1000 const CHANNEL_CLOSING_TIMEOUT = 5 * 1000
// HACK: Filter trickle lines when trickle is disabled #354 // HACK: Filter trickle lines when trickle is disabled #354
function filterTrickle (sdp) { function filterTrickle (sdp) {
@@ -27569,6 +27567,7 @@ class Peer extends stream.Duplex {
this.iceCompleteTimeout = opts.iceCompleteTimeout || ICECOMPLETE_TIMEOUT this.iceCompleteTimeout = opts.iceCompleteTimeout || ICECOMPLETE_TIMEOUT
this.destroyed = false this.destroyed = false
this.destroying = false
this._connected = false this._connected = false
this.remoteAddress = undefined this.remoteAddress = undefined
@@ -27735,7 +27734,7 @@ class Peer extends stream.Duplex {
} }
_addIceCandidate (candidate) { _addIceCandidate (candidate) {
var iceCandidateObj = new this._wrtc.RTCIceCandidate(candidate) const iceCandidateObj = new this._wrtc.RTCIceCandidate(candidate)
this._pc.addIceCandidate(iceCandidateObj) this._pc.addIceCandidate(iceCandidateObj)
.catch(err => { .catch(err => {
if (!iceCandidateObj.address || iceCandidateObj.address.endsWith('.local')) { if (!iceCandidateObj.address || iceCandidateObj.address.endsWith('.local')) {
@@ -27771,6 +27770,7 @@ class Peer extends stream.Duplex {
} }
} else { } else {
this.emit('signal', { // request initiator to renegotiate this.emit('signal', { // request initiator to renegotiate
type: 'transceiverRequest',
transceiverRequest: { kind, init } transceiverRequest: { kind, init }
}) })
} }
@@ -27796,8 +27796,8 @@ class Peer extends stream.Duplex {
addTrack (track, stream) { addTrack (track, stream) {
this._debug('addTrack()') this._debug('addTrack()')
var submap = this._senderMap.get(track) || new Map() // nested Maps map [track, stream] to sender const submap = this._senderMap.get(track) || new Map() // nested Maps map [track, stream] to sender
var sender = submap.get(stream) let sender = submap.get(stream)
if (!sender) { if (!sender) {
sender = this._pc.addTrack(track, stream) sender = this._pc.addTrack(track, stream)
submap.set(stream, sender) submap.set(stream, sender)
@@ -27819,8 +27819,8 @@ class Peer extends stream.Duplex {
replaceTrack (oldTrack, newTrack, stream) { replaceTrack (oldTrack, newTrack, stream) {
this._debug('replaceTrack()') this._debug('replaceTrack()')
var submap = this._senderMap.get(oldTrack) const submap = this._senderMap.get(oldTrack)
var sender = submap ? submap.get(stream) : null const sender = submap ? submap.get(stream) : null
if (!sender) { if (!sender) {
throw errCode(new Error('Cannot replace track that was never added.'), 'ERR_TRACK_NOT_ADDED') throw errCode(new Error('Cannot replace track that was never added.'), 'ERR_TRACK_NOT_ADDED')
} }
@@ -27841,8 +27841,8 @@ class Peer extends stream.Duplex {
removeTrack (track, stream) { removeTrack (track, stream) {
this._debug('removeSender()') this._debug('removeSender()')
var submap = this._senderMap.get(track) const submap = this._senderMap.get(track)
var sender = submap ? submap.get(stream) : null const sender = submap ? submap.get(stream) : null
if (!sender) { if (!sender) {
throw errCode(new Error('Cannot remove track that was never added.'), 'ERR_TRACK_NOT_ADDED') throw errCode(new Error('Cannot remove track that was never added.'), 'ERR_TRACK_NOT_ADDED')
} }
@@ -27905,6 +27905,7 @@ class Peer extends stream.Duplex {
} else { } else {
this._debug('requesting negotiation from initiator') this._debug('requesting negotiation from initiator')
this.emit('signal', { // request initiator to renegotiate this.emit('signal', { // request initiator to renegotiate
type: 'renegotiate',
renegotiate: true renegotiate: true
}) })
} }
@@ -27920,62 +27921,71 @@ class Peer extends stream.Duplex {
} }
_destroy (err, cb) { _destroy (err, cb) {
if (this.destroyed) return if (this.destroyed || this.destroying) return
this.destroying = true
this._debug('destroy (error: %s)', err && (err.message || err)) this._debug('destroying (error: %s)', err && (err.message || err))
this.readable = this.writable = false queueMicrotask(() => { // allow events concurrent with the call to _destroy() to fire (see #692)
this.destroyed = true
this.destroying = false
if (!this._readableState.ended) this.push(null) this._debug('destroy (error: %s)', err && (err.message || err))
if (!this._writableState.finished) this.end()
this.destroyed = true this.readable = this.writable = false
this._connected = false
this._pcReady = false
this._channelReady = false
this._remoteTracks = null
this._remoteStreams = null
this._senderMap = null
clearInterval(this._closingInterval) if (!this._readableState.ended) this.push(null)
this._closingInterval = null if (!this._writableState.finished) this.end()
clearInterval(this._interval) this._connected = false
this._interval = null this._pcReady = false
this._chunk = null this._channelReady = false
this._cb = null this._remoteTracks = null
this._remoteStreams = null
this._senderMap = null
if (this._onFinishBound) this.removeListener('finish', this._onFinishBound) clearInterval(this._closingInterval)
this._onFinishBound = null this._closingInterval = null
if (this._channel) { clearInterval(this._interval)
try { this._interval = null
this._channel.close() this._chunk = null
} catch (err) {} this._cb = null
this._channel.onmessage = null if (this._onFinishBound) this.removeListener('finish', this._onFinishBound)
this._channel.onopen = null this._onFinishBound = null
this._channel.onclose = null
this._channel.onerror = null
}
if (this._pc) {
try {
this._pc.close()
} catch (err) {}
this._pc.oniceconnectionstatechange = null if (this._channel) {
this._pc.onicegatheringstatechange = null try {
this._pc.onsignalingstatechange = null this._channel.close()
this._pc.onicecandidate = null } catch (err) {}
this._pc.ontrack = null
this._pc.ondatachannel = null
}
this._pc = null
this._channel = null
if (err) this.emit('error', err) // allow events concurrent with destruction to be handled
this.emit('close') this._channel.onmessage = null
cb() this._channel.onopen = null
this._channel.onclose = null
this._channel.onerror = null
}
if (this._pc) {
try {
this._pc.close()
} catch (err) {}
// allow events concurrent with destruction to be handled
this._pc.oniceconnectionstatechange = null
this._pc.onicegatheringstatechange = null
this._pc.onsignalingstatechange = null
this._pc.onicecandidate = null
this._pc.ontrack = null
this._pc.ondatachannel = null
}
this._pc = null
this._channel = null
if (err) this.emit('error', err)
this.emit('close')
cb()
})
} }
_setupData (event) { _setupData (event) {
@@ -28013,7 +28023,7 @@ class Peer extends stream.Duplex {
// HACK: Chrome will sometimes get stuck in readyState "closing", let's check for this condition // HACK: Chrome will sometimes get stuck in readyState "closing", let's check for this condition
// https://bugs.chromium.org/p/chromium/issues/detail?id=882743 // https://bugs.chromium.org/p/chromium/issues/detail?id=882743
var isClosing = false let isClosing = false
this._closingInterval = setInterval(() => { // No "onclosing" event this._closingInterval = setInterval(() => { // No "onclosing" event
if (this._channel && this._channel.readyState === 'closing') { if (this._channel && this._channel.readyState === 'closing') {
if (isClosing) this._onChannelClose() // closing timed out: equivalent to onclose firing if (isClosing) this._onChannelClose() // closing timed out: equivalent to onclose firing
@@ -28091,7 +28101,7 @@ class Peer extends stream.Duplex {
const sendOffer = () => { const sendOffer = () => {
if (this.destroyed) return if (this.destroyed) return
var signal = this._pc.localDescription || offer const signal = this._pc.localDescription || offer
this._debug('signal') this._debug('signal')
this.emit('signal', { this.emit('signal', {
type: signal.type, type: signal.type,
@@ -28141,7 +28151,7 @@ class Peer extends stream.Duplex {
const sendAnswer = () => { const sendAnswer = () => {
if (this.destroyed) return if (this.destroyed) return
var signal = this._pc.localDescription || answer const signal = this._pc.localDescription || answer
this._debug('signal') this._debug('signal')
this.emit('signal', { this.emit('signal', {
type: signal.type, type: signal.type,
@@ -28178,8 +28188,8 @@ class Peer extends stream.Duplex {
_onIceStateChange () { _onIceStateChange () {
if (this.destroyed) return if (this.destroyed) return
var iceConnectionState = this._pc.iceConnectionState const iceConnectionState = this._pc.iceConnectionState
var iceGatheringState = this._pc.iceGatheringState const iceGatheringState = this._pc.iceGatheringState
this._debug( this._debug(
'iceStateChange (connection: %s) (gathering: %s)', 'iceStateChange (connection: %s) (gathering: %s)',
@@ -28215,7 +28225,7 @@ class Peer extends stream.Duplex {
if (this._pc.getStats.length === 0 || this._isReactNativeWebrtc) { if (this._pc.getStats.length === 0 || this._isReactNativeWebrtc) {
this._pc.getStats() this._pc.getStats()
.then(res => { .then(res => {
var reports = [] const reports = []
res.forEach(report => { res.forEach(report => {
reports.push(flattenValues(report)) reports.push(flattenValues(report))
}) })
@@ -28228,9 +28238,9 @@ class Peer extends stream.Duplex {
// If we destroy connection in `connect` callback this code might happen to run when actual connection is already closed // If we destroy connection in `connect` callback this code might happen to run when actual connection is already closed
if (this.destroyed) return if (this.destroyed) return
var reports = [] const reports = []
res.result().forEach(result => { res.result().forEach(result => {
var report = {} const report = {}
result.names().forEach(name => { result.names().forEach(name => {
report[name] = result.stat(name) report[name] = result.stat(name)
}) })
@@ -28265,10 +28275,10 @@ class Peer extends stream.Duplex {
// Treat getStats error as non-fatal. It's not essential. // Treat getStats error as non-fatal. It's not essential.
if (err) items = [] if (err) items = []
var remoteCandidates = {} const remoteCandidates = {}
var localCandidates = {} const localCandidates = {}
var candidatePairs = {} const candidatePairs = {}
var foundSelectedCandidatePair = false let foundSelectedCandidatePair = false
items.forEach(item => { items.forEach(item => {
// TODO: Once all browsers support the hyphenated stats report types, remove // TODO: Once all browsers support the hyphenated stats report types, remove
@@ -28287,7 +28297,7 @@ class Peer extends stream.Duplex {
const setSelectedCandidatePair = selectedCandidatePair => { const setSelectedCandidatePair = selectedCandidatePair => {
foundSelectedCandidatePair = true foundSelectedCandidatePair = true
var local = localCandidates[selectedCandidatePair.localCandidateId] let local = localCandidates[selectedCandidatePair.localCandidateId]
if (local && (local.ip || local.address)) { if (local && (local.ip || local.address)) {
// Spec // Spec
@@ -28307,7 +28317,7 @@ class Peer extends stream.Duplex {
this.localFamily = this.localAddress.includes(':') ? 'IPv6' : 'IPv4' this.localFamily = this.localAddress.includes(':') ? 'IPv6' : 'IPv4'
} }
var remote = remoteCandidates[selectedCandidatePair.remoteCandidateId] let remote = remoteCandidates[selectedCandidatePair.remoteCandidateId]
if (remote && (remote.ip || remote.address)) { if (remote && (remote.ip || remote.address)) {
// Spec // Spec
@@ -28329,7 +28339,10 @@ class Peer extends stream.Duplex {
this._debug( this._debug(
'connect local: %s:%s remote: %s:%s', 'connect local: %s:%s remote: %s:%s',
this.localAddress, this.localPort, this.remoteAddress, this.remotePort this.localAddress,
this.localPort,
this.remoteAddress,
this.remotePort
) )
} }
@@ -28367,7 +28380,7 @@ class Peer extends stream.Duplex {
this._chunk = null this._chunk = null
this._debug('sent chunk from "write before connect"') this._debug('sent chunk from "write before connect"')
var cb = this._cb const cb = this._cb
this._cb = null this._cb = null
cb(null) cb(null)
} }
@@ -28412,8 +28425,8 @@ class Peer extends stream.Duplex {
this._queuedNegotiation = false this._queuedNegotiation = false
this._needsNegotiation() // negotiate again this._needsNegotiation() // negotiate again
} else { } else {
this._debug('negotiate') this._debug('negotiated')
this.emit('negotiate') this.emit('negotiated')
} }
} }
@@ -28425,6 +28438,7 @@ class Peer extends stream.Duplex {
if (this.destroyed) return if (this.destroyed) return
if (event.candidate && this.trickle) { if (event.candidate && this.trickle) {
this.emit('signal', { this.emit('signal', {
type: 'candidate',
candidate: { candidate: {
candidate: event.candidate.candidate, candidate: event.candidate.candidate,
sdpMLineIndex: event.candidate.sdpMLineIndex, sdpMLineIndex: event.candidate.sdpMLineIndex,
@@ -28443,7 +28457,7 @@ class Peer extends stream.Duplex {
_onChannelMessage (event) { _onChannelMessage (event) {
if (this.destroyed) return if (this.destroyed) return
var data = event.data let data = event.data
if (data instanceof ArrayBuffer) data = Buffer.from(data) if (data instanceof ArrayBuffer) data = Buffer.from(data)
this.push(data) this.push(data)
} }
@@ -28451,7 +28465,7 @@ class Peer extends stream.Duplex {
_onChannelBufferedAmountLow () { _onChannelBufferedAmountLow () {
if (this.destroyed || !this._cb) return if (this.destroyed || !this._cb) return
this._debug('ending backpressure: bufferedAmount %d', this._channel.bufferedAmount) this._debug('ending backpressure: bufferedAmount %d', this._channel.bufferedAmount)
var cb = this._cb const cb = this._cb
this._cb = null this._cb = null
cb(null) cb(null)
} }
@@ -28487,13 +28501,14 @@ class Peer extends stream.Duplex {
this._remoteStreams.push(eventStream) this._remoteStreams.push(eventStream)
queueMicrotask(() => { queueMicrotask(() => {
this._debug('on stream')
this.emit('stream', eventStream) // ensure all tracks have been added this.emit('stream', eventStream) // ensure all tracks have been added
}) })
}) })
} }
_debug () { _debug () {
var args = [].slice.call(arguments) const args = [].slice.call(arguments)
args[0] = '[' + this._id + '] ' + args[0] args[0] = '[' + this._id + '] ' + args[0]
debug.apply(null, args) debug.apply(null, args)
} }
@@ -28522,7 +28537,6 @@ Peer.channelConfig = {}
module.exports = Peer module.exports = Peer
}).call(this)}).call(this,require("buffer").Buffer)
},{"buffer":60,"debug":224,"err-code":97,"get-browser-rtc":115,"queue-microtask":193,"randombytes":195,"readable-stream":241}],224:[function(require,module,exports){ },{"buffer":60,"debug":224,"err-code":97,"get-browser-rtc":115,"queue-microtask":193,"randombytes":195,"readable-stream":241}],224:[function(require,module,exports){
arguments[4][13][0].apply(exports,arguments) arguments[4][13][0].apply(exports,arguments)
},{"./common":225,"_process":187,"dup":13}],225:[function(require,module,exports){ },{"./common":225,"_process":187,"dup":13}],225:[function(require,module,exports){
@@ -37970,6 +37984,7 @@ function start() {
getFiles.addEventListener('click', getFilesFromPeers); getFiles.addEventListener('click', getFilesFromPeers);
tippy('[data-tippy-content]', {"theme": "torrent-parts", "animation": "shift-away-subtle"}); // all element-defined tooltips tippy('[data-tippy-content]', {"theme": "torrent-parts", "animation": "shift-away-subtle"}); // all element-defined tooltips
source.disable();
if (window.location.hash) { if (window.location.hash) {
originalSourceIcon.innerHTML = '<span class="fad fa-link fa-fw"></span>'; originalSourceIcon.innerHTML = '<span class="fad fa-link fa-fw"></span>';
+3 -3
View File
@@ -64,9 +64,9 @@ var i=e("buffer"),r=i.Buffer;function o(e,t){for(var n in e)t[n]=e[n]}function s
/*! simple-concat. MIT License. Feross Aboukhadijeh <https://feross.org/opensource> */ /*! simple-concat. MIT License. Feross Aboukhadijeh <https://feross.org/opensource> */
t.exports=function(t,n){var i=[];t.on("data",(function(e){i.push(e)})),t.once("end",(function(){n&&n(null,e.concat(i)),n=null})),t.once("error",(function(e){n&&n(e),n=null}))}}).call(this)}).call(this,e("buffer").Buffer)},{buffer:60}],222:[function(e,t,n){(function(n){(function(){ t.exports=function(t,n){var i=[];t.on("data",(function(e){i.push(e)})),t.once("end",(function(){n&&n(null,e.concat(i)),n=null})),t.once("error",(function(e){n&&n(e),n=null}))}}).call(this)}).call(this,e("buffer").Buffer)},{buffer:60}],222:[function(e,t,n){(function(n){(function(){
/*! simple-get. MIT License. Feross Aboukhadijeh <https://feross.org/opensource> */ /*! simple-get. MIT License. Feross Aboukhadijeh <https://feross.org/opensource> */
t.exports=u;const i=e("simple-concat"),r=e("decompress-response"),o=e("http"),s=e("https"),a=e("once"),c=e("querystring"),l=e("url"),p=e=>null!==e&&"object"==typeof e&&"function"==typeof e.pipe;function u(e,t){if(e=Object.assign({maxRedirects:10},"string"==typeof e?{url:e}:e),t=a(t),e.url){const{hostname:t,port:n,protocol:i,auth:r,path:o}=l.parse(e.url);delete e.url,t||n||i||r?Object.assign(e,{hostname:t,port:n,protocol:i,auth:r,path:o}):e.path=o}const i={"accept-encoding":"gzip, deflate"};let d;e.headers&&Object.keys(e.headers).forEach((t=>i[t.toLowerCase()]=e.headers[t])),e.headers=i,e.body?d=e.json&&!p(e.body)?JSON.stringify(e.body):e.body:e.form&&(d="string"==typeof e.form?e.form:c.stringify(e.form),e.headers["content-type"]="application/x-www-form-urlencoded"),d&&(e.method||(e.method="POST"),p(d)||(e.headers["content-length"]=n.byteLength(d)),e.json&&!e.form&&(e.headers["content-type"]="application/json")),delete e.body,delete e.form,e.json&&(e.headers.accept="application/json"),e.method&&(e.method=e.method.toUpperCase());const f=("https:"===e.protocol?s:o).request(e,(n=>{if(!1!==e.followRedirects&&n.statusCode>=300&&n.statusCode<400&&n.headers.location)return e.url=n.headers.location,delete e.headers.host,n.resume(),"POST"===e.method&&[301,302].includes(n.statusCode)&&(e.method="GET",delete e.headers["content-length"],delete e.headers["content-type"]),0==e.maxRedirects--?t(new Error("too many redirects")):u(e,t);const i="function"==typeof r&&"HEAD"!==e.method;t(null,i?r(n):n)}));return f.on("timeout",(()=>{f.abort(),t(new Error("Request timed out"))})),f.on("error",t),p(d)?d.on("error",t).pipe(f):f.end(d),f}u.concat=(e,t)=>u(e,((n,r)=>{if(n)return t(n);i(r,((n,i)=>{if(n)return t(n);if(e.json)try{i=JSON.parse(i.toString())}catch(n){return t(n,r,i)}t(null,r,i)}))})),["get","post","put","patch","head","delete"].forEach((e=>{u[e]=(t,n)=>("string"==typeof t&&(t={url:t}),u(Object.assign({method:e.toUpperCase()},t),n))}))}).call(this)}).call(this,e("buffer").Buffer)},{buffer:60,"decompress-response":55,http:264,https:116,once:183,querystring:192,"simple-concat":221,url:299}],223:[function(e,t,n){(function(n){(function(){ t.exports=u;const i=e("simple-concat"),r=e("decompress-response"),o=e("http"),s=e("https"),a=e("once"),c=e("querystring"),l=e("url"),p=e=>null!==e&&"object"==typeof e&&"function"==typeof e.pipe;function u(e,t){if(e=Object.assign({maxRedirects:10},"string"==typeof e?{url:e}:e),t=a(t),e.url){const{hostname:t,port:n,protocol:i,auth:r,path:o}=l.parse(e.url);delete e.url,t||n||i||r?Object.assign(e,{hostname:t,port:n,protocol:i,auth:r,path:o}):e.path=o}const i={"accept-encoding":"gzip, deflate"};let d;e.headers&&Object.keys(e.headers).forEach((t=>i[t.toLowerCase()]=e.headers[t])),e.headers=i,e.body?d=e.json&&!p(e.body)?JSON.stringify(e.body):e.body:e.form&&(d="string"==typeof e.form?e.form:c.stringify(e.form),e.headers["content-type"]="application/x-www-form-urlencoded"),d&&(e.method||(e.method="POST"),p(d)||(e.headers["content-length"]=n.byteLength(d)),e.json&&!e.form&&(e.headers["content-type"]="application/json")),delete e.body,delete e.form,e.json&&(e.headers.accept="application/json"),e.method&&(e.method=e.method.toUpperCase());const f=("https:"===e.protocol?s:o).request(e,(n=>{if(!1!==e.followRedirects&&n.statusCode>=300&&n.statusCode<400&&n.headers.location)return e.url=n.headers.location,delete e.headers.host,n.resume(),"POST"===e.method&&[301,302].includes(n.statusCode)&&(e.method="GET",delete e.headers["content-length"],delete e.headers["content-type"]),0==e.maxRedirects--?t(new Error("too many redirects")):u(e,t);const i="function"==typeof r&&"HEAD"!==e.method;t(null,i?r(n):n)}));return f.on("timeout",(()=>{f.abort(),t(new Error("Request timed out"))})),f.on("error",t),p(d)?d.on("error",t).pipe(f):f.end(d),f}u.concat=(e,t)=>u(e,((n,r)=>{if(n)return t(n);i(r,((n,i)=>{if(n)return t(n);if(e.json)try{i=JSON.parse(i.toString())}catch(n){return t(n,r,i)}t(null,r,i)}))})),["get","post","put","patch","head","delete"].forEach((e=>{u[e]=(t,n)=>("string"==typeof t&&(t={url:t}),u(Object.assign({method:e.toUpperCase()},t),n))}))}).call(this)}).call(this,e("buffer").Buffer)},{buffer:60,"decompress-response":55,http:264,https:116,once:183,querystring:192,"simple-concat":221,url:299}],223:[function(e,t,n){
/*! simple-peer. MIT License. Feross Aboukhadijeh <https://feross.org/opensource> */ /*! simple-peer. MIT License. Feross Aboukhadijeh <https://feross.org/opensource> */
var i=e("debug")("simple-peer"),r=e("get-browser-rtc"),o=e("randombytes"),s=e("readable-stream"),a=e("queue-microtask"),c=e("err-code"),l=65536;function p(e){return e.replace(/a=ice-options:trickle\s\n/g,"")}class u extends s.Duplex{constructor(e){if(super(e=Object.assign({allowHalfOpen:!1},e)),this._id=o(4).toString("hex").slice(0,7),this._debug("new peer %o",e),this.channelName=e.initiator?e.channelName||o(20).toString("hex"):null,this.initiator=e.initiator||!1,this.channelConfig=e.channelConfig||u.channelConfig,this.channelNegotiated=this.channelConfig.negotiated,this.config=Object.assign({},u.config,e.config),this.offerOptions=e.offerOptions||{},this.answerOptions=e.answerOptions||{},this.sdpTransform=e.sdpTransform||(e=>e),this.streams=e.streams||(e.stream?[e.stream]:[]),this.trickle=void 0===e.trickle||e.trickle,this.allowHalfTrickle=void 0!==e.allowHalfTrickle&&e.allowHalfTrickle,this.iceCompleteTimeout=e.iceCompleteTimeout||5e3,this.destroyed=!1,this._connected=!1,this.remoteAddress=void 0,this.remoteFamily=void 0,this.remotePort=void 0,this.localAddress=void 0,this.localFamily=void 0,this.localPort=void 0,this._wrtc=e.wrtc&&"object"==typeof e.wrtc?e.wrtc:r(),!this._wrtc)throw"undefined"==typeof window?c(new Error("No WebRTC support: Specify `opts.wrtc` option in this environment"),"ERR_WEBRTC_SUPPORT"):c(new Error("No WebRTC support: Not a supported browser"),"ERR_WEBRTC_SUPPORT");this._pcReady=!1,this._channelReady=!1,this._iceComplete=!1,this._iceCompleteTimer=null,this._channel=null,this._pendingCandidates=[],this._isNegotiating=!1,this._firstNegotiation=!0,this._batchedNegotiation=!1,this._queuedNegotiation=!1,this._sendersAwaitingStable=[],this._senderMap=new Map,this._closingInterval=null,this._remoteTracks=[],this._remoteStreams=[],this._chunk=null,this._cb=null,this._interval=null;try{this._pc=new this._wrtc.RTCPeerConnection(this.config)}catch(e){return void a((()=>this.destroy(c(e,"ERR_PC_CONSTRUCTOR"))))}this._isReactNativeWebrtc="number"==typeof this._pc._peerConnectionId,this._pc.oniceconnectionstatechange=()=>{this._onIceStateChange()},this._pc.onicegatheringstatechange=()=>{this._onIceStateChange()},this._pc.onconnectionstatechange=()=>{this._onConnectionStateChange()},this._pc.onsignalingstatechange=()=>{this._onSignalingStateChange()},this._pc.onicecandidate=e=>{this._onIceCandidate(e)},this.initiator||this.channelNegotiated?this._setupData({channel:this._pc.createDataChannel(this.channelName,this.channelConfig)}):this._pc.ondatachannel=e=>{this._setupData(e)},this.streams&&this.streams.forEach((e=>{this.addStream(e)})),this._pc.ontrack=e=>{this._onTrack(e)},this._debug("initial negotiation"),this._needsNegotiation(),this._onFinishBound=()=>{this._onFinish()},this.once("finish",this._onFinishBound)}get bufferSize(){return this._channel&&this._channel.bufferedAmount||0}get connected(){return this._connected&&"open"===this._channel.readyState}address(){return{port:this.localPort,family:this.localFamily,address:this.localAddress}}signal(e){if(this.destroyed)throw c(new Error("cannot signal after peer is destroyed"),"ERR_SIGNALING");if("string"==typeof e)try{e=JSON.parse(e)}catch(t){e={}}this._debug("signal()"),e.renegotiate&&this.initiator&&(this._debug("got request to renegotiate"),this._needsNegotiation()),e.transceiverRequest&&this.initiator&&(this._debug("got request for transceiver"),this.addTransceiver(e.transceiverRequest.kind,e.transceiverRequest.init)),e.candidate&&(this._pc.remoteDescription&&this._pc.remoteDescription.type?this._addIceCandidate(e.candidate):this._pendingCandidates.push(e.candidate)),e.sdp&&this._pc.setRemoteDescription(new this._wrtc.RTCSessionDescription(e)).then((()=>{this.destroyed||(this._pendingCandidates.forEach((e=>{this._addIceCandidate(e)})),this._pendingCandidates=[],"offer"===this._pc.remoteDescription.type&&this._createAnswer())})).catch((e=>{this.destroy(c(e,"ERR_SET_REMOTE_DESCRIPTION"))})),e.sdp||e.candidate||e.renegotiate||e.transceiverRequest||this.destroy(c(new Error("signal() called with invalid signal data"),"ERR_SIGNALING"))}_addIceCandidate(e){var t=new this._wrtc.RTCIceCandidate(e);this._pc.addIceCandidate(t).catch((e=>{var n;!t.address||t.address.endsWith(".local")?(n="Ignoring unsupported ICE candidate.",console.warn(n)):this.destroy(c(e,"ERR_ADD_ICE_CANDIDATE"))}))}send(e){this._channel.send(e)}addTransceiver(e,t){if(this._debug("addTransceiver()"),this.initiator)try{this._pc.addTransceiver(e,t),this._needsNegotiation()}catch(e){this.destroy(c(e,"ERR_ADD_TRANSCEIVER"))}else this.emit("signal",{transceiverRequest:{kind:e,init:t}})}addStream(e){this._debug("addStream()"),e.getTracks().forEach((t=>{this.addTrack(t,e)}))}addTrack(e,t){this._debug("addTrack()");var n=this._senderMap.get(e)||new Map,i=n.get(t);if(i)throw i.removed?c(new Error("Track has been removed. You should enable/disable tracks that you want to re-add."),"ERR_SENDER_REMOVED"):c(new Error("Track has already been added to that stream."),"ERR_SENDER_ALREADY_ADDED");i=Line truncated const i=e("debug")("simple-peer"),r=e("get-browser-rtc"),o=e("randombytes"),s=e("readable-stream"),a=e("queue-microtask"),c=e("err-code"),{Buffer:l}=e("buffer"),p=65536;function u(e){return e.replace(/a=ice-options:trickle\s\n/g,"")}class d extends s.Duplex{constructor(e){if(super(e=Object.assign({allowHalfOpen:!1},e)),this._id=o(4).toString("hex").slice(0,7),this._debug("new peer %o",e),this.channelName=e.initiator?e.channelName||o(20).toString("hex"):null,this.initiator=e.initiator||!1,this.channelConfig=e.channelConfig||d.channelConfig,this.channelNegotiated=this.channelConfig.negotiated,this.config=Object.assign({},d.config,e.config),this.offerOptions=e.offerOptions||{},this.answerOptions=e.answerOptions||{},this.sdpTransform=e.sdpTransform||(e=>e),this.streams=e.streams||(e.stream?[e.stream]:[]),this.trickle=void 0===e.trickle||e.trickle,this.allowHalfTrickle=void 0!==e.allowHalfTrickle&&e.allowHalfTrickle,this.iceCompleteTimeout=e.iceCompleteTimeout||5e3,this.destroyed=!1,this.destroying=!1,this._connected=!1,this.remoteAddress=void 0,this.remoteFamily=void 0,this.remotePort=void 0,this.localAddress=void 0,this.localFamily=void 0,this.localPort=void 0,this._wrtc=e.wrtc&&"object"==typeof e.wrtc?e.wrtc:r(),!this._wrtc)throw"undefined"==typeof window?c(new Error("No WebRTC support: Specify `opts.wrtc` option in this environment"),"ERR_WEBRTC_SUPPORT"):c(new Error("No WebRTC support: Not a supported browser"),"ERR_WEBRTC_SUPPORT");this._pcReady=!1,this._channelReady=!1,this._iceComplete=!1,this._iceCompleteTimer=null,this._channel=null,this._pendingCandidates=[],this._isNegotiating=!1,this._firstNegotiation=!0,this._batchedNegotiation=!1,this._queuedNegotiation=!1,this._sendersAwaitingStable=[],this._senderMap=new Map,this._closingInterval=null,this._remoteTracks=[],this._remoteStreams=[],this._chunk=null,this._cb=null,this._interval=null;try{this._pc=new this._wrtc.RTCPeerConnection(this.config)}catch(e){return void a((()=>this.destroy(c(e,"ERR_PC_CONSTRUCTOR"))))}this._isReactNativeWebrtc="number"==typeof this._pc._peerConnectionId,this._pc.oniceconnectionstatechange=()=>{this._onIceStateChange()},this._pc.onicegatheringstatechange=()=>{this._onIceStateChange()},this._pc.onconnectionstatechange=()=>{this._onConnectionStateChange()},this._pc.onsignalingstatechange=()=>{this._onSignalingStateChange()},this._pc.onicecandidate=e=>{this._onIceCandidate(e)},this.initiator||this.channelNegotiated?this._setupData({channel:this._pc.createDataChannel(this.channelName,this.channelConfig)}):this._pc.ondatachannel=e=>{this._setupData(e)},this.streams&&this.streams.forEach((e=>{this.addStream(e)})),this._pc.ontrack=e=>{this._onTrack(e)},this._debug("initial negotiation"),this._needsNegotiation(),this._onFinishBound=()=>{this._onFinish()},this.once("finish",this._onFinishBound)}get bufferSize(){return this._channel&&this._channel.bufferedAmount||0}get connected(){return this._connected&&"open"===this._channel.readyState}address(){return{port:this.localPort,family:this.localFamily,address:this.localAddress}}signal(e){if(this.destroyed)throw c(new Error("cannot signal after peer is destroyed"),"ERR_SIGNALING");if("string"==typeof e)try{e=JSON.parse(e)}catch(t){e={}}this._debug("signal()"),e.renegotiate&&this.initiator&&(this._debug("got request to renegotiate"),this._needsNegotiation()),e.transceiverRequest&&this.initiator&&(this._debug("got request for transceiver"),this.addTransceiver(e.transceiverRequest.kind,e.transceiverRequest.init)),e.candidate&&(this._pc.remoteDescription&&this._pc.remoteDescription.type?this._addIceCandidate(e.candidate):this._pendingCandidates.push(e.candidate)),e.sdp&&this._pc.setRemoteDescription(new this._wrtc.RTCSessionDescription(e)).then((()=>{this.destroyed||(this._pendingCandidates.forEach((e=>{this._addIceCandidate(e)})),this._pendingCandidates=[],"offer"===this._pc.remoteDescription.type&&this._createAnswer())})).catch((e=>{this.destroy(c(e,"ERR_SET_REMOTE_DESCRIPTION"))})),e.sdp||e.candidate||e.renegotiate||e.transceiverRequest||this.destroy(c(new Error("signal() called with invalid signal data"),"ERR_SIGNALING"))}_addIceCandidate(e){const t=new this._wrtc.RTCIceCandidate(e);this._pc.addIceCandidate(t).catch((e=>{var n;!t.address||t.address.endsWith(".local")?(n="Ignoring unsupported ICE candidate.",console.warn(n)):this.destroy(c(e,"ERR_ADD_ICE_CANDIDATE"))}))}send(e){this._channel.send(e)}addTransceiver(e,t){if(this._debug("addTransceiver()"),this.initiator)try{this._pc.addTransceiver(e,t),this._needsNegotiation()}catch(e){this.destroy(c(e,"ERR_ADD_TRANSCEIVER"))}else this.emit("signal",{type:"transceiverRequest",transceiverRequest:{kind:e,init:t}})}addStream(e){this._debug("addStream()"),e.getTracks().forEach((t=>{this.addTrack(t,e)}))}addTrack(e,t){this._debug("addTrack()");const n=this._senderMap.get(e)||new Map;let i=n.get(t);if(i)throw i.removed?c(new Error("Track has been removed. You should enable/disable tracks that you want to re-add."),"ERR_SENDER_REMOVED"):c(new Error(Line truncated
/*! stream-to-blob-url. MIT License. Feross Aboukhadijeh <https://feross.org/opensource> */ /*! stream-to-blob-url. MIT License. Feross Aboukhadijeh <https://feross.org/opensource> */
t.exports=async function(e,t){const n=await i(e,t);return URL.createObjectURL(n)};const i=e("stream-to-blob")},{"stream-to-blob":284}],284:[function(e,t,n){ t.exports=async function(e,t){const n=await i(e,t);return URL.createObjectURL(n)};const i=e("stream-to-blob")},{"stream-to-blob":284}],284:[function(e,t,n){
/*! stream-to-blob. MIT License. Feross Aboukhadijeh <https://feross.org/opensource> */ /*! stream-to-blob. MIT License. Feross Aboukhadijeh <https://feross.org/opensource> */
@@ -84,4 +84,4 @@ const i=e("debug")("torrent-discovery"),r=e("bittorrent-dht/client"),o=e("events
/*! ut_metadata. MIT License. WebTorrent LLC <https://webtorrent.io/opensource> */ /*! ut_metadata. MIT License. WebTorrent LLC <https://webtorrent.io/opensource> */
const{EventEmitter:i}=e("events"),r=e("bencode"),o=e("bitfield").default,s=e("debug")("ut_metadata"),a=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 o(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||1e7<e.metadata_size||e.metadata_size<=0?this.emit("warning",new Error("Peer gave invalid metadata size")):(this._metadataSize=e.metadata_size,this._numPieces=Math.ceil(this._metadataSize/c),this._remainingRejects=2*this._numPieces,void this._requestPieces()):this.emit("warning",new Error("Peer does not have metadata")):this.emit("warning",new Error("Peer does not support ut_metadata"))}onMessage(e){let t,n;try{const i=e.toString(),o=i.indexOf("ee")+2;t=r.decode(i.substring(0,o)),n=e.slice(o)}catch(e){return}switch(t.msg_type){case 0:this._onRequest(t.piece);break;case 1:this._onData(t.piece,n,t.total_size);break;case 2:this._onReject(t.piece)}}fetch(){this._metadataComplete||(this._fetching=!0,this._metadataSize&&this._requestPieces())}cancel(){this._fetching=!1}setMetadata(e){if(this._metadataComplete)return!0;s("set metadata");try{const t=r.decode(e).info;t&&(e=r.encode(t))}catch(e){}return(!this._infoHash||this._infoHash===a.sync(e))&&(this.cancel(),this.metadata=e,this._metadataComplete=!0,this._metadataSize=this.metadata.length,this._wire.extendedHandshake.metadata_size=this._metadataSize,this.emit("metadata",r.encode({info:r.decode(this.metadata)})),!0)}_send(e,t){let i=r.encode(e);n.isBuffer(t)&&(i=n.concat([i,t])),this._wire.extended("ut_metadata",i)}_request(e){this._send({msg_type:0,piece:e})}_data(e,t,n){const i={msg_type:1,piece:e};"number"==typeof n&&(i.total_size=n),this._send(i,t)}_reject(e){this._send({msg_type:2,piece:e})}_onRequest(e){if(!this._metadataComplete)return void this._reject(e);const t=e*c;let n=t+c;n>this._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;e<this._numPieces;e++)this._request(e)}}_checkDone(){let e=!0;for(let t=0;t<this._numPieces;t++)if(!this._bitfield.get(t)){e=!1;break}if(!e)return;this.setMetadata(this.metadata)||this._failedMetadata()}_failedMetadata(){this._bitfield=new o(0,{grow:1e3}),this._remainingRejects-=this._numPieces,this._remainingRejects>0?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:7,bitfield:302,buffer:60,debug:303,events:98,"simple-sha1":242}],302:[function(e,t,n){arguments[4][12][0].apply(n,arguments)},{dup:12}],303:[function(e,t,n){arguments[4][13][0].apply(n,arguments)},{"./common":304,_process:187,dup:13}],304:[function(e,t,n){arguments[4][14][0].apply(n,arguments)},{dup:14,ms:305}],305:[function(e,t,n){arguments[4][15][0].apply(n,arguments)},{dup:15}],306:[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:{})},{}],307:[function(e,t,n){(function(n){(function(){const i=e("binary-search"),r=e("events"),o=e("mp4-stream"),s=e("mp4-box-encoding"),a=e("range-slice-stream");class c{constructor(e,t){this._entries=e,this._countName=t||"count",this._index=0,this._offset=0,this.value=this._entries[0]}inc(){this._offset++,this._offset>=this._entries[this._index][this._countName]&&(this._index++,this._offset=0),this.value=this._entries[this._index]}}const l=1;t.exports=class extends r{constructor(e){super(),this._tracks=[],this._file=e,this._decoder=null,this._findMoov(0)}_findMoov(e){this._decoder&&this._decoder.destroy();let t=0;this._decoder=o.decode();const n=this._file.createReadStream({start:e});n.pipe(this._decoder);const i=r=>{"moov"===r.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)}}))):r.length<4096?(t+=r.length,this._decoder.ignore()):(this._decoder.removeListener("box",i),t+=r.length,n.destroy(),this._decoLine truncated const{EventEmitter:i}=e("events"),r=e("bencode"),o=e("bitfield").default,s=e("debug")("ut_metadata"),a=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 o(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||1e7<e.metadata_size||e.metadata_size<=0?this.emit("warning",new Error("Peer gave invalid metadata size")):(this._metadataSize=e.metadata_size,this._numPieces=Math.ceil(this._metadataSize/c),this._remainingRejects=2*this._numPieces,void this._requestPieces()):this.emit("warning",new Error("Peer does not have metadata")):this.emit("warning",new Error("Peer does not support ut_metadata"))}onMessage(e){let t,n;try{const i=e.toString(),o=i.indexOf("ee")+2;t=r.decode(i.substring(0,o)),n=e.slice(o)}catch(e){return}switch(t.msg_type){case 0:this._onRequest(t.piece);break;case 1:this._onData(t.piece,n,t.total_size);break;case 2:this._onReject(t.piece)}}fetch(){this._metadataComplete||(this._fetching=!0,this._metadataSize&&this._requestPieces())}cancel(){this._fetching=!1}setMetadata(e){if(this._metadataComplete)return!0;s("set metadata");try{const t=r.decode(e).info;t&&(e=r.encode(t))}catch(e){}return(!this._infoHash||this._infoHash===a.sync(e))&&(this.cancel(),this.metadata=e,this._metadataComplete=!0,this._metadataSize=this.metadata.length,this._wire.extendedHandshake.metadata_size=this._metadataSize,this.emit("metadata",r.encode({info:r.decode(this.metadata)})),!0)}_send(e,t){let i=r.encode(e);n.isBuffer(t)&&(i=n.concat([i,t])),this._wire.extended("ut_metadata",i)}_request(e){this._send({msg_type:0,piece:e})}_data(e,t,n){const i={msg_type:1,piece:e};"number"==typeof n&&(i.total_size=n),this._send(i,t)}_reject(e){this._send({msg_type:2,piece:e})}_onRequest(e){if(!this._metadataComplete)return void this._reject(e);const t=e*c;let n=t+c;n>this._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;e<this._numPieces;e++)this._request(e)}}_checkDone(){let e=!0;for(let t=0;t<this._numPieces;t++)if(!this._bitfield.get(t)){e=!1;break}if(!e)return;this.setMetadata(this.metadata)||this._failedMetadata()}_failedMetadata(){this._bitfield=new o(0,{grow:1e3}),this._remainingRejects-=this._numPieces,this._remainingRejects>0?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:7,bitfield:302,buffer:60,debug:303,events:98,"simple-sha1":242}],302:[function(e,t,n){arguments[4][12][0].apply(n,arguments)},{dup:12}],303:[function(e,t,n){arguments[4][13][0].apply(n,arguments)},{"./common":304,_process:187,dup:13}],304:[function(e,t,n){arguments[4][14][0].apply(n,arguments)},{dup:14,ms:305}],305:[function(e,t,n){arguments[4][15][0].apply(n,arguments)},{dup:15}],306:[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:{})},{}],307:[function(e,t,n){(function(n){(function(){const i=e("binary-search"),r=e("events"),o=e("mp4-stream"),s=e("mp4-box-encoding"),a=e("range-slice-stream");class c{constructor(e,t){this._entries=e,this._countName=t||"count",this._index=0,this._offset=0,this.value=this._entries[0]}inc(){this._offset++,this._offset>=this._entries[this._index][this._countName]&&(this._index++,this._offset=0),this.value=this._entries[this._index]}}const l=1;t.exports=class extends r{constructor(e){super(),this._tracks=[],this._file=e,this._decoder=null,this._findMoov(0)}_findMoov(e){this._decoder&&this._decoder.destroy();let t=0;this._decoder=o.decode();const n=this._file.createReadStream({start:e});n.pipe(this._decoder);const i=r=>{"moov"===r.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)}}))):r.length<4096?(t+=r.length,this._decoder.ignore()):(this._decoder.removeListener("box",i),t+=r.length,n.destroy(),this._decoLine truncated
/*! webtorrent. MIT License. WebTorrent LLC <https://webtorrent.io/opensource> */ /*! webtorrent. MIT License. WebTorrent LLC <https://webtorrent.io/opensource> */
const{EventEmitter:o}=e("events"),s=e("simple-concat"),a=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"),f=e("path"),h=e("simple-peer"),m=e("randombytes"),g=e("speedometer"),v=e("./lib/conn-pool"),b=e("./lib/torrent"),x=e("./package.json").version,y=x.replace(/\d*./g,(e=>("0"+e%100).slice(-2))).slice(0,4),_=`-WW${y}-`;class w extends o{constructor(e={}){super(),"string"==typeof e.peerId?this.peerId=e.peerId:r.isBuffer(e.peerId)?this.peerId=e.peerId.toString("hex"):this.peerId=r.from(_+m(9).toString("base64")).toString("hex"),this.peerIdBuffer=r.from(this.peerId,"hex"),"string"==typeof e.nodeId?this.nodeId=e.nodeId:r.isBuffer(e.nodeId)?this.nodeId=e.nodeId.toString("hex"):this.nodeId=m(20).toString("hex"),this.nodeIdBuffer=r.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===o.infoHash&&e!==o)return void o._destroy(new Error("Cannot add duplicate torrent "+o.infoHash))},r=()=>{this.destroyed||(n(o),this.emit("torrent",o))};this._debug("add"),t=t?Object.assign({},t):{};const o=new b(e,this,t);return this.torrents.push(o),o.once("_infoHash",i),o.once("ready",r),o.once("close",(function e(){o.removeListener("_infoHash",i),o.removeListener("ready",r),o.removeListener("close",e)})),o}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=f.dirname(e)),t.createdBy||(t.createdBy="WebTorrent/"+y);const r=e=>{this._debug("on seed"),"function"==typeof n&&n(e),e.emit("seed"),this.emit("seed",e)},o=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 r(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):s(e,t)})),((e,n)=>{if(!this.destroyed)return e?o._destroy(e):void a.parseInput(n,t,((e,i)=>{if(!this.destroyed){if(e)return o._destroy(e);c=i.map((e=>e.getStream)),a(n,t,((e,t)=>{if(this.destroyed)return;if(e)return o._destroy(e);const n=this.get(t);n?o._destroy(new Error("Cannot add duplicate torrent "+n.infoHash)):o._onTorrentId(t)}))}}))})),o}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,tLine truncated const{EventEmitter:o}=e("events"),s=e("simple-concat"),a=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"),f=e("path"),h=e("simple-peer"),m=e("randombytes"),g=e("speedometer"),v=e("./lib/conn-pool"),b=e("./lib/torrent"),x=e("./package.json").version,y=x.replace(/\d*./g,(e=>("0"+e%100).slice(-2))).slice(0,4),_=`-WW${y}-`;class w extends o{constructor(e={}){super(),"string"==typeof e.peerId?this.peerId=e.peerId:r.isBuffer(e.peerId)?this.peerId=e.peerId.toString("hex"):this.peerId=r.from(_+m(9).toString("base64")).toString("hex"),this.peerIdBuffer=r.from(this.peerId,"hex"),"string"==typeof e.nodeId?this.nodeId=e.nodeId:r.isBuffer(e.nodeId)?this.nodeId=e.nodeId.toString("hex"):this.nodeId=m(20).toString("hex"),this.nodeIdBuffer=r.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===o.infoHash&&e!==o)return void o._destroy(new Error("Cannot add duplicate torrent "+o.infoHash))},r=()=>{this.destroyed||(n(o),this.emit("torrent",o))};this._debug("add"),t=t?Object.assign({},t):{};const o=new b(e,this,t);return this.torrents.push(o),o.once("_infoHash",i),o.once("ready",r),o.once("close",(function e(){o.removeListener("_infoHash",i),o.removeListener("ready",r),o.removeListener("close",e)})),o}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=f.dirname(e)),t.createdBy||(t.createdBy="WebTorrent/"+y);const r=e=>{this._debug("on seed"),"function"==typeof n&&n(e),e.emit("seed"),this.emit("seed",e)},o=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 r(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):s(e,t)})),((e,n)=>{if(!this.destroyed)return e?o._destroy(e):void a.parseInput(n,t,((e,i)=>{if(!this.destroyed){if(e)return o._destroy(e);c=i.map((e=>e.getStream)),a(n,t,((e,t)=>{if(this.destroyed)return;if(e)return o._destroy(e);const n=this.get(t);n?o._destroy(new Error("Cannot add duplicate torrent "+n.infoHash)):o._onTorrentId(t)}))}}))})),o}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,tLine truncated
+27 -27
View File
@@ -4,7 +4,7 @@
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="description" content="Inspect and edit what's in your Torrent file or Magnet link" /> <meta name="description" content="Inspect and edit what's in your Torrent file or Magnet link" />
<meta name="keywords" content="torrent, webtorrent, magnet, p2p, peer to peer, filesharing, announce, tracker, webseed" /> <meta name="keywords" content="torrent, webtorrent, magnet, p2p, peer to peer, filesharing, announce, tracker, webseed" />
@@ -35,7 +35,7 @@
<title>Torrent Parts | Inspect and edit what's in your Torrent file or Magnet link</title> <title>Torrent Parts | Inspect and edit what's in your Torrent file or Magnet link</title>
<link rel="stylesheet" href="style.css" /> <link rel="stylesheet" href="style.css" />
<link href="https://fonts.googleapis.com/css2?family=Alata&display=swap" rel="stylesheet"> <link href="https://fonts.googleapis.com/css2?family=Alata&display=swap" rel="stylesheet" />
<script async src="https://kit.fontawesome.com/9ca49f101f.js"></script> <script async src="https://kit.fontawesome.com/9ca49f101f.js"></script>
<script async defer src="https://buttons.github.io/buttons.js"></script> <script async defer src="https://buttons.github.io/buttons.js"></script>
@@ -52,18 +52,18 @@
<body> <body>
<header> <header>
<h1 id="logo">Torrent<span id="originalSourceIcon"><span class="fad fa-magnet fa-fw"></span></span>Parts</h1> <h1 id="logo">Torrent<span id="originalSourceIcon"><span class="fad fa-magnet fa-fw" aria-hidden="true"></span></span>Parts</h1>
<a class="github-button" href="https://github.com/leoherzog/TorrentParts" data-color-scheme="no-preference:light;light:light;dark:dark;" data-icon="octicon-star" data-show-count="true" aria-label="Star leoherzog/TorrentParts on GitHub">Star</a> <a class="github-button" href="https://github.com/leoherzog/TorrentParts" data-icon="octicon-star" data-show-count="true" aria-label="Star leoherzog/TorrentParts on GitHub">Star</a>
</header> </header>
<div id="startButtons"> <div id="startButtons">
<input id="magnet" type="text" placeholder="Enter Magnet URL" aria-label="Enter Magnet URL and press enter" /> <input id="magnet" type="text" placeholder="Enter Magnet URL" aria-label="Enter Magnet URL and press enter" />
<label for="magnet" style="display:none"> <label for="magnet" class="sr-only">
Enter Magnet link and press enter Enter Magnet link and press enter
</label> </label>
<input id="torrent" type="file" aria-label="Select Torrent file" /> <input id="torrent" type="file" aria-label="Select Torrent file" />
<label for="torrent"> <label for="torrent">
<span class="fas fa-cloud-upload"></span> Select Torrent File <span class="fas fa-cloud-upload" aria-hidden="true"></span> Select Torrent File
</label> </label>
</div> </div>
@@ -88,10 +88,10 @@
<div class="property"> <div class="property">
<div class="labels"> <div class="labels">
<label for="hash"> <div>
<span class="info" data-tippy-content="This is the unique identifier that makes Torrents work. All of the files contained in this Torrent are run through an algorithm that generates a unique string, or &ldquo;hash&rdquo;."><span class="far fa-info-circle"></span></span> <span class="info" data-tippy-content="This is the unique identifier that makes Torrents work. All of the files contained in this Torrent are run through an algorithm that generates a unique string, or &ldquo;hash&rdquo;."><span class="far fa-info-circle"></span></span>
Unique Hash <label for="hash">Unique Hash</label>
</label> </div>
</div> </div>
<div class="content"> <div class="content">
<input id="hash" type="text" placeholder="" disabled/> <input id="hash" type="text" placeholder="" disabled/>
@@ -100,10 +100,10 @@
<div class="property"> <div class="property">
<div class="labels"> <div class="labels">
<label for="name"> <div>
<span class="info" data-tippy-content="An optional title specified by the creator"><span class="far fa-info-circle"></span></span> <span class="info" data-tippy-content="An optional title specified by the creator"><span class="far fa-info-circle"></span></span>
Torrent Name <label for="name">Torrent Name</label>
</label> </div>
</div> </div>
<div class="content"> <div class="content">
<input id="name" type="text" placeholder="Unnamed" /> <input id="name" type="text" placeholder="Unnamed" />
@@ -112,10 +112,10 @@
<div class="property"> <div class="property">
<div class="labels"> <div class="labels">
<label for="created"> <div>
<span class="info" data-tippy-content="Data embedded into a Torrent file that says what program created it and when. Not included in Magnet links."><span class="far fa-info-circle"></span></span> <span class="info" data-tippy-content="Data embedded into a Torrent file that says what program created it and when. Not included in Magnet links."><span class="far fa-info-circle"></span></span>
Created <label for="created">Created</label>
</label> </div>
<label for="createdBy" style="display:none">Created By</label> <label for="createdBy" style="display:none">Created By</label>
</div> </div>
<div class="content"> <div class="content">
@@ -127,10 +127,10 @@
<div class="property"> <div class="property">
<div class="labels"> <div class="labels">
<label for="comment"> <div>
<span class="info" data-tippy-content="An optional description specified by the creator"><span class="far fa-info-circle"></span></span> <span class="info" data-tippy-content="An optional description specified by the creator"><span class="far fa-info-circle"></span></span>
Comment <label for="comment">Comment</label>
</label> </div>
</div> </div>
<div class="content"> <div class="content">
<input id="comment" type="text" placeholder="Not included in the URL/File provided" /> <input id="comment" type="text" placeholder="Not included in the URL/File provided" />
@@ -139,10 +139,10 @@
<div class="property"> <div class="property">
<div class="labels"> <div class="labels">
<label for="announce"> <div>
<span class="info" data-tippy-content="Servers that keep track of other users who are actively downloading this Torrent, called &ldquo;peers&rdquo;. Your client will contact these servers first to find out who else is available to download the files from."><span class="far fa-info-circle"></span></span> <span class="info" data-tippy-content="Servers that keep track of other users who are actively downloading this Torrent, called &ldquo;peers&rdquo;. Your client will contact these servers first to find out who else is available to download the files from."><span class="far fa-info-circle"></span></span>
Tracker URLs <label for="announce">Tracker URLs</label>
</label> </div>
<a id="addTrackers">Add Known Working Trackers</a> <a id="addTrackers">Add Known Working Trackers</a>
<a id="removeTrackers">Remove All</a> <a id="removeTrackers">Remove All</a>
</div> </div>
@@ -156,10 +156,10 @@
<div class="property"> <div class="property">
<div class="labels"> <div class="labels">
<label for="urlList"> <div>
<span class="info" data-tippy-content="A list of webservers on the internet that also have a copy of the file(s) in this Torrent, to use in case no peers are available"><span class="far fa-info-circle"></span></span> <span class="info" data-tippy-content="A list of webservers on the internet that also have a copy of the file(s) in this Torrent, to use in case no peers are available"><span class="far fa-info-circle"></span></span>
Webseed URLs <label for="urlList">Webseed URLs</label>
</label> </div>
<a id="removeWebseeds">Remove All</a> <a id="removeWebseeds">Remove All</a>
</div> </div>
<div class="content"> <div class="content">
@@ -172,10 +172,10 @@
<div class="property"> <div class="property">
<div class="labels"> <div class="labels">
<label for="files"> <div>
<span class="info" data-tippy-content="The files listed in this Torrent file. Not included in Magnet links."><span class="far fa-info-circle"></span></span> <span class="info" data-tippy-content="The files listed in this Torrent file. Not included in Magnet links."><span class="far fa-info-circle"></span></span>
Files <label for="files">Files</label>
</label> </div>
<a id="getFiles">Fetch Files List from WebTorrent</a> <a id="getFiles">Fetch Files List from WebTorrent</a>
</div> </div>
<table id="files"> <table id="files">
+1
View File
@@ -108,6 +108,7 @@ function start() {
getFiles.addEventListener('click', getFilesFromPeers); getFiles.addEventListener('click', getFilesFromPeers);
tippy('[data-tippy-content]', {"theme": "torrent-parts", "animation": "shift-away-subtle"}); // all element-defined tooltips tippy('[data-tippy-content]', {"theme": "torrent-parts", "animation": "shift-away-subtle"}); // all element-defined tooltips
source.disable();
if (window.location.hash) { if (window.location.hash) {
originalSourceIcon.innerHTML = '<span class="fad fa-link fa-fw"></span>'; originalSourceIcon.innerHTML = '<span class="fad fa-link fa-fw"></span>';
+11
View File
@@ -1,6 +1,17 @@
/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */ /*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */
html{line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0}main{display:block}h1{font-size:2em;margin:.67em 0}hr{box-sizing:content-box;height:0;overflow:visible}pre{font-family:monospace,monospace;font-size:1em}a{background-color:transparent}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:bolder}code,kbd,samp{font-family:monospace,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}img{border-style:none}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring,button:-moz-focusring{outline:1px dotted ButtonText}fieldset{padding:.35em .75em .625em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{vertical-align:baseline}textarea{overflow:auto}[type=checkbox],[type=radio]{box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details{display:block}summary{display:list-item}template{display:none}[hidden]{display:none} html{line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0}main{display:block}h1{font-size:2em;margin:.67em 0}hr{box-sizing:content-box;height:0;overflow:visible}pre{font-family:monospace,monospace;font-size:1em}a{background-color:transparent}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:bolder}code,kbd,samp{font-family:monospace,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}img{border-style:none}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring,button:-moz-focusring{outline:1px dotted ButtonText}fieldset{padding:.35em .75em .625em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{vertical-align:baseline}textarea{overflow:auto}[type=checkbox],[type=radio]{box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details{display:block}summary{display:list-item}template{display:none}[hidden]{display:none}
.sr-only {
border: 0;
clip: rect(0 0 0 0);
height: 1px;
margin: -1px;
overflow: hidden;
padding: 0;
position: absolute;
width: 1px;
}
:root { :root {
--gradient: linear-gradient(180deg, #152332, #24384D); --gradient: linear-gradient(180deg, #152332, #24384D);
--dark-blue: #102030; --dark-blue: #102030;