UNPKG

nile.js

Version:

A tool for scalable peer-to-peer video streaming using WebTorrent

1,506 lines (1,321 loc) 746 kB
(function webpackUniversalModuleDefinition(root, factory) { if(typeof exports === 'object' && typeof module === 'object') module.exports = factory(); else if(typeof define === 'function' && define.amd) define("Viewer", [], factory); else if(typeof exports === 'object') exports["Viewer"] = factory(); else root["Viewer"] = factory(); })(this, function() { return /******/ (function(modules) { // webpackBootstrap /******/ // The module cache /******/ var installedModules = {}; /******/ /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ /******/ // Check if module is in cache /******/ if(installedModules[moduleId]) { /******/ return installedModules[moduleId].exports; /******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = installedModules[moduleId] = { /******/ i: moduleId, /******/ l: false, /******/ exports: {} /******/ }; /******/ /******/ // Execute the module function /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); /******/ /******/ // Flag the module as loaded /******/ module.l = true; /******/ /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ /******/ /******/ // expose the modules object (__webpack_modules__) /******/ __webpack_require__.m = modules; /******/ /******/ // expose the module cache /******/ __webpack_require__.c = installedModules; /******/ /******/ // identity function for calling harmony imports with the correct context /******/ __webpack_require__.i = function(value) { return value; }; /******/ /******/ // define getter function for harmony exports /******/ __webpack_require__.d = function(exports, name, getter) { /******/ if(!__webpack_require__.o(exports, name)) { /******/ Object.defineProperty(exports, name, { /******/ configurable: false, /******/ enumerable: true, /******/ get: getter /******/ }); /******/ } /******/ }; /******/ /******/ // getDefaultExport function for compatibility with non-harmony modules /******/ __webpack_require__.n = function(module) { /******/ var getter = module && module.__esModule ? /******/ function getDefault() { return module['default']; } : /******/ function getModuleExports() { return module; }; /******/ __webpack_require__.d(getter, 'a', getter); /******/ return getter; /******/ }; /******/ /******/ // Object.prototype.hasOwnProperty.call /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; /******/ /******/ // __webpack_public_path__ /******/ __webpack_require__.p = "dist"; /******/ /******/ // Load entry module and return exports /******/ return __webpack_require__(__webpack_require__.s = 35); /******/ }) /************************************************************************/ /******/ ([ /* 0 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; var g; // This works in non-strict mode g = function () { return this; }(); try { // This works if eval is allowed (see CSP) g = g || Function("return this")() || (1, eval)("this"); } catch (e) { // This works if the window reference is available if ((typeof window === "undefined" ? "undefined" : _typeof(window)) === "object") g = window; } // g can still be undefined, but nothing to do about it... // We return undefined, instead of nothing here, so it's // easier to handle this case. if(!global) { ...} module.exports = g; /***/ }), /* 1 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /* * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. * * Use of this source code is governed by a BSD-style license * that can be found in the LICENSE file in the root of the source * tree. */ /* eslint-env node */ var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; var logDisabled_ = true; // Utility methods. var utils = { disableLog: function disableLog(bool) { if (typeof bool !== 'boolean') { return new Error('Argument type: ' + (typeof bool === 'undefined' ? 'undefined' : _typeof(bool)) + '. Please use a boolean.'); } logDisabled_ = bool; return bool ? 'adapter.js logging disabled' : 'adapter.js logging enabled'; }, log: function log() { if ((typeof window === 'undefined' ? 'undefined' : _typeof(window)) === 'object') { if (logDisabled_) { return; } if (typeof console !== 'undefined' && typeof console.log === 'function') { console.log.apply(console, arguments); } } }, /** * Extract browser version out of the provided user agent string. * * @param {!string} uastring userAgent string. * @param {!string} expr Regular expression used as match criteria. * @param {!number} pos position in the version string to be returned. * @return {!number} browser version. */ extractVersion: function extractVersion(uastring, expr, pos) { var match = uastring.match(expr); return match && match.length >= pos && parseInt(match[pos], 10); }, /** * Browser detector. * * @return {object} result containing browser and version * properties. */ detectBrowser: function detectBrowser() { // Returned result object. var result = {}; result.browser = null; result.version = null; // Fail early if it's not a browser if (typeof window === 'undefined' || !window.navigator) { result.browser = 'Not a browser.'; return result; } // Firefox. if (navigator.mozGetUserMedia) { result.browser = 'firefox'; result.version = this.extractVersion(navigator.userAgent, /Firefox\/(\d+)\./, 1); } else if (navigator.webkitGetUserMedia) { // Chrome, Chromium, Webview, Opera, all use the chrome shim for now if (window.webkitRTCPeerConnection) { result.browser = 'chrome'; result.version = this.extractVersion(navigator.userAgent, /Chrom(e|ium)\/(\d+)\./, 2); } else { // Safari (in an unpublished version) or unknown webkit-based. if (navigator.userAgent.match(/Version\/(\d+).(\d+)/)) { result.browser = 'safari'; result.version = this.extractVersion(navigator.userAgent, /AppleWebKit\/(\d+)\./, 1); } else { // unknown webkit-based browser. result.browser = 'Unsupported webkit-based browser ' + 'with GUM support but no WebRTC support.'; return result; } } } else if (navigator.mediaDevices && navigator.userAgent.match(/Edge\/(\d+).(\d+)$/)) { // Edge. result.browser = 'edge'; result.version = this.extractVersion(navigator.userAgent, /Edge\/(\d+).(\d+)$/, 2); } else if (navigator.mediaDevices && navigator.userAgent.match(/AppleWebKit\/(\d+)\./)) { // Safari, with webkitGetUserMedia removed. result.browser = 'safari'; result.version = this.extractVersion(navigator.userAgent, /AppleWebKit\/(\d+)\./, 1); } else { // Default fallthrough: not supported. result.browser = 'Not a supported browser.'; return result; } return result; }, // shimCreateObjectURL must be called before shimSourceObject to avoid loop. shimCreateObjectURL: function shimCreateObjectURL() { if (!((typeof window === 'undefined' ? 'undefined' : _typeof(window)) === 'object' && window.HTMLMediaElement && 'srcObject' in window.HTMLMediaElement.prototype)) { // Only shim CreateObjectURL using srcObject if srcObject exists. return undefined; } var nativeCreateObjectURL = URL.createObjectURL.bind(URL); var nativeRevokeObjectURL = URL.revokeObjectURL.bind(URL); var streams = new Map(), newId = 0; URL.createObjectURL = function (stream) { if ('getTracks' in stream) { var url = 'polyblob:' + ++newId; streams.set(url, stream); console.log('URL.createObjectURL(stream) is deprecated! ' + 'Use elem.srcObject = stream instead!'); return url; } return nativeCreateObjectURL(stream); }; URL.revokeObjectURL = function (url) { nativeRevokeObjectURL(url); streams.delete(url); }; var dsc = Object.getOwnPropertyDescriptor(window.HTMLMediaElement.prototype, 'src'); Object.defineProperty(window.HTMLMediaElement.prototype, 'src', { get: function get() { return dsc.get.apply(this); }, set: function set(url) { this.srcObject = streams.get(url) || null; return dsc.set.apply(this, [url]); } }); var nativeSetAttribute = HTMLMediaElement.prototype.setAttribute; HTMLMediaElement.prototype.setAttribute = function () { if (arguments.length === 2 && ('' + arguments[0]).toLowerCase() === 'src') { this.srcObject = streams.get(arguments[1]) || null; } return nativeSetAttribute.apply(this, arguments); }; } }; // Export. module.exports = { log: utils.log, disableLog: utils.disableLog, browserDetails: utils.detectBrowser(), extractVersion: utils.extractVersion, shimCreateObjectURL: utils.shimCreateObjectURL, detectBrowser: utils.detectBrowser.bind(utils) }; /***/ }), /* 2 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /* WEBPACK VAR INJECTION */(function(global) { /** * Module dependencies. */ var keys = __webpack_require__(48); var hasBinary = __webpack_require__(19); var sliceBuffer = __webpack_require__(37); var after = __webpack_require__(36); var utf8 = __webpack_require__(71); var base64encoder; if (global && global.ArrayBuffer) { base64encoder = __webpack_require__(39); } /** * Check if we are running an android browser. That requires us to use * ArrayBuffer with polling transports... * * http://ghinda.net/jpeg-blob-ajax-android/ */ var isAndroid = typeof navigator !== 'undefined' && /Android/i.test(navigator.userAgent); /** * Check if we are running in PhantomJS. * Uploading a Blob with PhantomJS does not work correctly, as reported here: * https://github.com/ariya/phantomjs/issues/11395 * @type boolean */ var isPhantomJS = typeof navigator !== 'undefined' && /PhantomJS/i.test(navigator.userAgent); /** * When true, avoids using Blobs to encode payloads. * @type boolean */ var dontSendBlobs = isAndroid || isPhantomJS; /** * Current protocol version. */ exports.protocol = 3; /** * Packet types. */ var packets = exports.packets = { open: 0 // non-ws , close: 1 // non-ws , ping: 2, pong: 3, message: 4, upgrade: 5, noop: 6 }; var packetslist = keys(packets); /** * Premade error packet. */ var err = { type: 'error', data: 'parser error' }; /** * Create a blob api even for blob builder when vendor prefixes exist */ var Blob = __webpack_require__(40); /** * Encodes a packet. * * <packet type id> [ <data> ] * * Example: * * 5hello world * 3 * 4 * * Binary is encoded in an identical principle * * @api private */ exports.encodePacket = function (packet, supportsBinary, utf8encode, callback) { if ('function' == typeof supportsBinary) { callback = supportsBinary; supportsBinary = false; } if ('function' == typeof utf8encode) { callback = utf8encode; utf8encode = null; } var data = packet.data === undefined ? undefined : packet.data.buffer || packet.data; if (global.ArrayBuffer && data instanceof ArrayBuffer) { return encodeArrayBuffer(packet, supportsBinary, callback); } else if (Blob && data instanceof global.Blob) { return encodeBlob(packet, supportsBinary, callback); } // might be an object with { base64: true, data: dataAsBase64String } if (data && data.base64) { return encodeBase64Object(packet, callback); } // Sending data as a utf-8 string var encoded = packets[packet.type]; // data fragment is optional if (undefined !== packet.data) { encoded += utf8encode ? utf8.encode(String(packet.data)) : String(packet.data); } return callback('' + encoded); }; function encodeBase64Object(packet, callback) { // packet data is an object { base64: true, data: dataAsBase64String } var message = 'b' + exports.packets[packet.type] + packet.data.data; return callback(message); } /** * Encode packet helpers for binary types */ function encodeArrayBuffer(packet, supportsBinary, callback) { if (!supportsBinary) { return exports.encodeBase64Packet(packet, callback); } var data = packet.data; var contentArray = new Uint8Array(data); var resultBuffer = new Uint8Array(1 + data.byteLength); resultBuffer[0] = packets[packet.type]; for (var i = 0; i < contentArray.length; i++) { resultBuffer[i + 1] = contentArray[i]; } return callback(resultBuffer.buffer); } function encodeBlobAsArrayBuffer(packet, supportsBinary, callback) { if (!supportsBinary) { return exports.encodeBase64Packet(packet, callback); } var fr = new FileReader(); fr.onload = function () { packet.data = fr.result; exports.encodePacket(packet, supportsBinary, true, callback); }; return fr.readAsArrayBuffer(packet.data); } function encodeBlob(packet, supportsBinary, callback) { if (!supportsBinary) { return exports.encodeBase64Packet(packet, callback); } if (dontSendBlobs) { return encodeBlobAsArrayBuffer(packet, supportsBinary, callback); } var length = new Uint8Array(1); length[0] = packets[packet.type]; var blob = new Blob([length.buffer, packet.data]); return callback(blob); } /** * Encodes a packet with binary data in a base64 string * * @param {Object} packet, has `type` and `data` * @return {String} base64 encoded message */ exports.encodeBase64Packet = function (packet, callback) { var message = 'b' + exports.packets[packet.type]; if (Blob && packet.data instanceof global.Blob) { var fr = new FileReader(); fr.onload = function () { var b64 = fr.result.split(',')[1]; callback(message + b64); }; return fr.readAsDataURL(packet.data); } var b64data; try { b64data = String.fromCharCode.apply(null, new Uint8Array(packet.data)); } catch (e) { // iPhone Safari doesn't let you apply with typed arrays var typed = new Uint8Array(packet.data); var basic = new Array(typed.length); for (var i = 0; i < typed.length; i++) { basic[i] = typed[i]; } b64data = String.fromCharCode.apply(null, basic); } message += global.btoa(b64data); return callback(message); }; /** * Decodes a packet. Changes format to Blob if requested. * * @return {Object} with `type` and `data` (if any) * @api private */ exports.decodePacket = function (data, binaryType, utf8decode) { if (data === undefined) { return err; } // String data if (typeof data == 'string') { if (data.charAt(0) == 'b') { return exports.decodeBase64Packet(data.substr(1), binaryType); } if (utf8decode) { data = tryDecode(data); if (data === false) { return err; } } var type = data.charAt(0); if (Number(type) != type || !packetslist[type]) { return err; } if (data.length > 1) { return { type: packetslist[type], data: data.substring(1) }; } else { return { type: packetslist[type] }; } } var asArray = new Uint8Array(data); var type = asArray[0]; var rest = sliceBuffer(data, 1); if (Blob && binaryType === 'blob') { rest = new Blob([rest]); } return { type: packetslist[type], data: rest }; }; function tryDecode(data) { try { data = utf8.decode(data); } catch (e) { return false; } return data; } /** * Decodes a packet encoded in a base64 string * * @param {String} base64 encoded message * @return {Object} with `type` and `data` (if any) */ exports.decodeBase64Packet = function (msg, binaryType) { var type = packetslist[msg.charAt(0)]; if (!base64encoder) { return { type: type, data: { base64: true, data: msg.substr(1) } }; } var data = base64encoder.decode(msg.substr(1)); if (binaryType === 'blob' && Blob) { data = new Blob([data]); } return { type: type, data: data }; }; /** * Encodes multiple messages (payload). * * <length>:data * * Example: * * 11:hello world2:hi * * If any contents are binary, they will be encoded as base64 strings. Base64 * encoded strings are marked with a b before the length specifier * * @param {Array} packets * @api private */ exports.encodePayload = function (packets, supportsBinary, callback) { if (typeof supportsBinary == 'function') { callback = supportsBinary; supportsBinary = null; } var isBinary = hasBinary(packets); if (supportsBinary && isBinary) { if (Blob && !dontSendBlobs) { return exports.encodePayloadAsBlob(packets, callback); } return exports.encodePayloadAsArrayBuffer(packets, callback); } if (!packets.length) { return callback('0:'); } function setLengthHeader(message) { return message.length + ':' + message; } function encodeOne(packet, doneCallback) { exports.encodePacket(packet, !isBinary ? false : supportsBinary, true, function (message) { doneCallback(null, setLengthHeader(message)); }); } map(packets, encodeOne, function (err, results) { return callback(results.join('')); }); }; /** * Async array map using after */ function map(ary, each, done) { var result = new Array(ary.length); var next = after(ary.length, done); var eachWithIndex = function eachWithIndex(i, el, cb) { each(el, function (error, msg) { result[i] = msg; cb(error, result); }); }; for (var i = 0; i < ary.length; i++) { eachWithIndex(i, ary[i], next); } } /* * Decodes data when a payload is maybe expected. Possible binary contents are * decoded from their base64 representation * * @param {String} data, callback method * @api public */ exports.decodePayload = function (data, binaryType, callback) { if (typeof data != 'string') { return exports.decodePayloadAsBinary(data, binaryType, callback); } if (typeof binaryType === 'function') { callback = binaryType; binaryType = null; } var packet; if (data == '') { // parser error - ignoring payload return callback(err, 0, 1); } var length = '', n, msg; for (var i = 0, l = data.length; i < l; i++) { var chr = data.charAt(i); if (':' != chr) { length += chr; } else { if ('' == length || length != (n = Number(length))) { // parser error - ignoring payload return callback(err, 0, 1); } msg = data.substr(i + 1, n); if (length != msg.length) { // parser error - ignoring payload return callback(err, 0, 1); } if (msg.length) { packet = exports.decodePacket(msg, binaryType, true); if (err.type == packet.type && err.data == packet.data) { // parser error in individual packet - ignoring payload return callback(err, 0, 1); } var ret = callback(packet, i + n, l); if (false === ret) return; } // advance cursor i += n; length = ''; } } if (length != '') { // parser error - ignoring payload return callback(err, 0, 1); } }; /** * Encodes multiple messages (payload) as binary. * * <1 = binary, 0 = string><number from 0-9><number from 0-9>[...]<number * 255><data> * * Example: * 1 3 255 1 2 3, if the binary contents are interpreted as 8 bit integers * * @param {Array} packets * @return {ArrayBuffer} encoded payload * @api private */ exports.encodePayloadAsArrayBuffer = function (packets, callback) { if (!packets.length) { return callback(new ArrayBuffer(0)); } function encodeOne(packet, doneCallback) { exports.encodePacket(packet, true, true, function (data) { return doneCallback(null, data); }); } map(packets, encodeOne, function (err, encodedPackets) { var totalLength = encodedPackets.reduce(function (acc, p) { var len; if (typeof p === 'string') { len = p.length; } else { len = p.byteLength; } return acc + len.toString().length + len + 2; // string/binary identifier + separator = 2 }, 0); var resultArray = new Uint8Array(totalLength); var bufferIndex = 0; encodedPackets.forEach(function (p) { var isString = typeof p === 'string'; var ab = p; if (isString) { var view = new Uint8Array(p.length); for (var i = 0; i < p.length; i++) { view[i] = p.charCodeAt(i); } ab = view.buffer; } if (isString) { // not true binary resultArray[bufferIndex++] = 0; } else { // true binary resultArray[bufferIndex++] = 1; } var lenStr = ab.byteLength.toString(); for (var i = 0; i < lenStr.length; i++) { resultArray[bufferIndex++] = parseInt(lenStr[i]); } resultArray[bufferIndex++] = 255; var view = new Uint8Array(ab); for (var i = 0; i < view.length; i++) { resultArray[bufferIndex++] = view[i]; } }); return callback(resultArray.buffer); }); }; /** * Encode as Blob */ exports.encodePayloadAsBlob = function (packets, callback) { function encodeOne(packet, doneCallback) { exports.encodePacket(packet, true, true, function (encoded) { var binaryIdentifier = new Uint8Array(1); binaryIdentifier[0] = 1; if (typeof encoded === 'string') { var view = new Uint8Array(encoded.length); for (var i = 0; i < encoded.length; i++) { view[i] = encoded.charCodeAt(i); } encoded = view.buffer; binaryIdentifier[0] = 0; } var len = encoded instanceof ArrayBuffer ? encoded.byteLength : encoded.size; var lenStr = len.toString(); var lengthAry = new Uint8Array(lenStr.length + 1); for (var i = 0; i < lenStr.length; i++) { lengthAry[i] = parseInt(lenStr[i]); } lengthAry[lenStr.length] = 255; if (Blob) { var blob = new Blob([binaryIdentifier.buffer, lengthAry.buffer, encoded]); doneCallback(null, blob); } }); } map(packets, encodeOne, function (err, results) { return callback(new Blob(results)); }); }; /* * Decodes data when a payload is maybe expected. Strings are decoded by * interpreting each byte as a key code for entries marked to start with 0. See * description of encodePayloadAsBinary * * @param {ArrayBuffer} data, callback method * @api public */ exports.decodePayloadAsBinary = function (data, binaryType, callback) { if (typeof binaryType === 'function') { callback = binaryType; binaryType = null; } var bufferTail = data; var buffers = []; var numberTooLong = false; while (bufferTail.byteLength > 0) { var tailArray = new Uint8Array(bufferTail); var isString = tailArray[0] === 0; var msgLength = ''; for (var i = 1;; i++) { if (tailArray[i] == 255) break; if (msgLength.length > 310) { numberTooLong = true; break; } msgLength += tailArray[i]; } if (numberTooLong) return callback(err, 0, 1); bufferTail = sliceBuffer(bufferTail, 2 + msgLength.length); msgLength = parseInt(msgLength); var msg = sliceBuffer(bufferTail, 0, msgLength); if (isString) { try { msg = String.fromCharCode.apply(null, new Uint8Array(msg)); } catch (e) { // iPhone Safari doesn't let you apply to typed arrays var typed = new Uint8Array(msg); msg = ''; for (var i = 0; i < typed.length; i++) { msg += String.fromCharCode(typed[i]); } } } buffers.push(msg); bufferTail = sliceBuffer(bufferTail, msgLength); } var total = buffers.length; buffers.forEach(function (buffer, i) { callback(exports.decodePacket(buffer, binaryType, true), i, total); }); }; /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) /***/ }), /* 3 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /** * Expose `Emitter`. */ if (true) { module.exports = Emitter; } /** * Initialize a new `Emitter`. * * @api public */ function Emitter(obj) { if (obj) return mixin(obj); }; /** * Mixin the emitter properties. * * @param {Object} obj * @return {Object} * @api private */ function mixin(obj) { for (var key in Emitter.prototype) { obj[key] = Emitter.prototype[key]; } return obj; } /** * Listen on the given `event` with `fn`. * * @param {String} event * @param {Function} fn * @return {Emitter} * @api public */ Emitter.prototype.on = Emitter.prototype.addEventListener = function (event, fn) { this._callbacks = this._callbacks || {}; (this._callbacks['$' + event] = this._callbacks['$' + event] || []).push(fn); return this; }; /** * Adds an `event` listener that will be invoked a single * time then automatically removed. * * @param {String} event * @param {Function} fn * @return {Emitter} * @api public */ Emitter.prototype.once = function (event, fn) { function on() { this.off(event, on); fn.apply(this, arguments); } on.fn = fn; this.on(event, on); return this; }; /** * Remove the given callback for `event` or all * registered callbacks. * * @param {String} event * @param {Function} fn * @return {Emitter} * @api public */ Emitter.prototype.off = Emitter.prototype.removeListener = Emitter.prototype.removeAllListeners = Emitter.prototype.removeEventListener = function (event, fn) { this._callbacks = this._callbacks || {}; // all if (0 == arguments.length) { this._callbacks = {}; return this; } // specific event var callbacks = this._callbacks['$' + event]; if (!callbacks) return this; // remove all handlers if (1 == arguments.length) { delete this._callbacks['$' + event]; return this; } // remove specific handler var cb; for (var i = 0; i < callbacks.length; i++) { cb = callbacks[i]; if (cb === fn || cb.fn === fn) { callbacks.splice(i, 1); break; } } return this; }; /** * Emit `event` with the given args. * * @param {String} event * @param {Mixed} ... * @return {Emitter} */ Emitter.prototype.emit = function (event) { this._callbacks = this._callbacks || {}; var args = [].slice.call(arguments, 1), callbacks = this._callbacks['$' + event]; if (callbacks) { callbacks = callbacks.slice(0); for (var i = 0, len = callbacks.length; i < len; ++i) { callbacks[i].apply(this, args); } } return this; }; /** * Return array of callbacks for `event`. * * @param {String} event * @return {Array} * @api public */ Emitter.prototype.listeners = function (event) { this._callbacks = this._callbacks || {}; return this._callbacks['$' + event] || []; }; /** * Check if this emitter has `event` handlers. * * @param {String} event * @return {Boolean} * @api public */ Emitter.prototype.hasListeners = function (event) { return !!this.listeners(event).length; }; /***/ }), /* 4 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; // shim for using process in browser var process = module.exports = {}; // cached from whatever global is present so that test runners that stub it // don't break things. But we need to wrap it in a try catch in case it is // wrapped in strict mode code which doesn't define any globals. It's inside a // function because try/catches deoptimize in certain engines. var cachedSetTimeout; var cachedClearTimeout; function defaultSetTimout() { throw new Error('setTimeout has not been defined'); } function defaultClearTimeout() { throw new Error('clearTimeout has not been defined'); } (function () { try { if (typeof setTimeout === 'function') { cachedSetTimeout = setTimeout; } else { cachedSetTimeout = defaultSetTimout; } } catch (e) { cachedSetTimeout = defaultSetTimout; } try { if (typeof clearTimeout === 'function') { cachedClearTimeout = clearTimeout; } else { cachedClearTimeout = defaultClearTimeout; } } catch (e) { cachedClearTimeout = defaultClearTimeout; } })(); function runTimeout(fun) { if (cachedSetTimeout === setTimeout) { //normal enviroments in sane situations return setTimeout(fun, 0); } // if setTimeout wasn't available but was latter defined if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) { cachedSetTimeout = setTimeout; return setTimeout(fun, 0); } try { // when when somebody has screwed with setTimeout but no I.E. maddness return cachedSetTimeout(fun, 0); } catch (e) { try { // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally return cachedSetTimeout.call(null, fun, 0); } catch (e) { // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error return cachedSetTimeout.call(this, fun, 0); } } } function runClearTimeout(marker) { if (cachedClearTimeout === clearTimeout) { //normal enviroments in sane situations return clearTimeout(marker); } // if clearTimeout wasn't available but was latter defined if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) { cachedClearTimeout = clearTimeout; return clearTimeout(marker); } try { // when when somebody has screwed with setTimeout but no I.E. maddness return cachedClearTimeout(marker); } catch (e) { try { // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally return cachedClearTimeout.call(null, marker); } catch (e) { // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error. // Some versions of I.E. have different rules for clearTimeout vs setTimeout return cachedClearTimeout.call(this, marker); } } } var queue = []; var draining = false; var currentQueue; var queueIndex = -1; function cleanUpNextTick() { if (!draining || !currentQueue) { return; } draining = false; if (currentQueue.length) { queue = currentQueue.concat(queue); } else { queueIndex = -1; } if (queue.length) { drainQueue(); } } function drainQueue() { if (draining) { return; } var timeout = runTimeout(cleanUpNextTick); draining = true; var len = queue.length; while (len) { currentQueue = queue; queue = []; while (++queueIndex < len) { if (currentQueue) { currentQueue[queueIndex].run(); } } queueIndex = -1; len = queue.length; } currentQueue = null; draining = false; runClearTimeout(timeout); } process.nextTick = function (fun) { var args = new Array(arguments.length - 1); if (arguments.length > 1) { for (var i = 1; i < arguments.length; i++) { args[i - 1] = arguments[i]; } } queue.push(new Item(fun, args)); if (queue.length === 1 && !draining) { runTimeout(drainQueue); } }; // v8 likes predictible objects function Item(fun, array) { this.fun = fun; this.array = array; } Item.prototype.run = function () { this.fun.apply(null, this.array); }; process.title = 'browser'; process.browser = true; process.env = {}; process.argv = []; process.version = ''; // empty string to avoid regexp issues process.versions = {}; function noop() {} process.on = noop; process.addListener = noop; process.once = noop; process.off = noop; process.removeListener = noop; process.removeAllListeners = noop; process.emit = noop; process.prependListener = noop; process.prependOnceListener = noop; process.listeners = function (name) { return []; }; process.binding = function (name) { throw new Error('process.binding is not supported'); }; process.cwd = function () { return '/'; }; process.chdir = function (dir) { throw new Error('process.chdir is not supported'); }; process.umask = function () { return 0; }; /***/ }), /* 5 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /* WEBPACK VAR INJECTION */(function(global, setImmediate) {var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;var require;var require; var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; !function (e) { if ("object" == ( false ? "undefined" : _typeof(exports)) && "undefined" != typeof module) module.exports = e();else if (true) !(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_FACTORY__ = (e), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));else { var t;t = "undefined" != typeof window ? window : "undefined" != typeof global ? global : "undefined" != typeof self ? self : this, t.WebTorrent = e(); } }(function () { var e;return function e(t, n, r) { function o(s, a) { if (!n[s]) { if (!t[s]) { var u = "function" == typeof require && require;if (!a && u) return require(s, !0);if (i) return require(s, !0);var c = new Error("Cannot find module '" + s + "'");throw c.code = "MODULE_NOT_FOUND", c; }var f = n[s] = { exports: {} };t[s][0].call(f.exports, function (e) { var n = t[s][1][e];return o(n || e); }, f, f.exports, e, t, n, r); }return n[s].exports; }for (var i = "function" == typeof require && require, s = 0; s < r.length; s++) { o(r[s]); }return o; }({ 1: [function (e, t, n) { function r(e, t) { s.Readable.call(this, t), this.destroyed = !1, this._torrent = e._torrent;var n = t && t.start || 0, r = t && t.end && t.end < e.length ? t.end : e.length - 1, o = e._torrent.pieceLength;this._startPiece = (n + e.offset) / o | 0, this._endPiece = (r + e.offset) / o | 0, this._piece = this._startPiece, this._offset = n + e.offset - this._startPiece * o, this._missing = r - n + 1, this._reading = !1, this._notifying = !1, this._criticalLength = Math.min(1048576 / o | 0, 2); }t.exports = r;var o = e("debug")("webtorrent:file-stream"), i = e("inherits"), s = e("readable-stream");i(r, s.Readable), r.prototype._read = function () { this._reading || (this._reading = !0, this._notify()); }, r.prototype._notify = function () { var e = this;if (e._reading && 0 !== e._missing) { if (!e._torrent.bitfield.get(e._piece)) return e._torrent.critical(e._piece, e._piece + e._criticalLength);if (!e._notifying) { e._notifying = !0;var t = e._piece;e._torrent.store.get(t, function (n, r) { if (e._notifying = !1, !e.destroyed) { if (n) return e._destroy(n);o("read %s (length %s) (err %s)", t, r.length, n && n.message), e._offset && (r = r.slice(e._offset), e._offset = 0), e._missing < r.length && (r = r.slice(0, e._missing)), e._missing -= r.length, o("pushing buffer of length %s", r.length), e._reading = !1, e.push(r), 0 === e._missing && e.push(null); } }), e._piece += 1; } } }, r.prototype.destroy = function (e) { this._destroy(null, e); }, r.prototype._destroy = function (e, t) { this.destroyed || (this.destroyed = !0, this._torrent.destroyed || this._torrent.deselect(this._startPiece, this._endPiece, !0), e && this.emit("error", e), this.emit("close"), t && t()); }; }, { debug: 30, inherits: 41, "readable-stream": 82 }], 2: [function (e, t, n) { (function (n) { function r(e, t) { i.call(this), this._torrent = e, this._destroyed = !1, this.name = t.name, this.path = t.path, this.length = t.length, this.offset = t.offset, this.done = !1;var n = t.offset, r = n + t.length - 1;this._startPiece = n / this._torrent.pieceLength | 0, this._endPiece = r / this._torrent.pieceLength | 0, 0 === this.length && (this.done = !0, this.emit("done")); }t.exports = r;var o = e("end-of-stream"), i = e("events").EventEmitter, s = e("./file-stream"), a = e("inherits"), u = e("path"), c = e("render-media"), f = e("readable-stream"), d = e("stream-to-blob"), h = e("stream-to-blob-url"), l = e("stream-with-known-length-to-buffer");a(r, i), Object.defineProperty(r.prototype, "downloaded", { get: function get() { if (!this._torrent.bitfield) return 0;for (var e = 0, t = this._startPiece; t <= this._endPiece; ++t) { if (this._torrent.bitfield.get(t)) e += this._torrent.pieceLength;else { var n = this._torrent.pieces[t];e += n.length - n.missing; } }return e; } }), r.prototype.select = function (e) { 0 !== this.length && this._torrent.select(this._startPiece, this._endPiece, e); }, r.prototype.deselect = function () { 0 !== this.length && this._torrent.deselect(this._startPiece, this._endPiece, !1); }, r.prototype.createReadStream = function (e) { var t = this;if (0 === this.length) { var r = new f.PassThrough();return n.nextTick(function () { r.end(); }), r; }var i = new s(t, e);return t._torrent.select(i._startPiece, i._endPiece, !0, function () { i._notify(); }), o(i, function () { t._destroyed || t._torrent.destroyed || t._torrent.deselect(i._startPiece, i._endPiece, !0); }), i; }, r.prototype.getBuffer = function (e) { l(this.createReadStream(), this.length, e); }, r.prototype.getBlob = function (e) { if ("undefined" == typeof window) throw new Error("browser-only method");d(this.createReadStream(), this._getMimeType(), e); }, r.prototype.getBlobURL = function (e) { if ("undefined" == typeof window) throw new Error("browser-only method");h(this.createReadStream(), this._getMimeType(), e); }, r.prototype.appendTo = function (e, t, n) { if ("undefined" == typeof window) throw new Error("browser-only method");c.append(this, e, t, n); }, r.prototype.renderTo = function (e, t, n) { if ("undefined" == typeof window) throw new Error("browser-only method");c.render(this, e, t, n); }, r.prototype._getMimeType = function () { return c.mime[u.extname(this.name).toLowerCase()]; }, r.prototype._destroy = function () { this._destroyed = !0, this._torrent = null; }; }).call(this, e("_process")); }, { "./file-stream": 1, _process: 66, "end-of-stream": 33, events: 34, inherits: 41, path: 63, "readable-stream": 82, "render-media": 83, "stream-to-blob": 100, "stream-to-blob-url": 99, "stream-with-known-length-to-buffer": 101 }], 3: [function (e, t, n) { function r(e, t) { var n = this;n.id = e, n.type = t, s("new Peer %s", e), n.addr = null, n.conn = null, n.swarm = null, n.wire = null, n.connected = !1, n.destroyed = !1, n.timeout = null, n.retries = 0, n.sentHandshake = !1; }function o() {}var i = e("unordered-array-remove"), s = e("debug")("webtorrent:peer"), a = e("bittorrent-protocol"), u = e("./webconn");n.createWebRTCPeer = function (e, t) { var n = new r(e.id, "webrtc");return n.conn = e, n.swarm = t, n.conn.connected ? n.onConnect() : (n.conn.once("connect", function () { n.onConnect(); }), n.conn.once("error", function (e) { n.destroy(e); }), n.startConnectTimeout()), n; }, n.createTCPIncomingPeer = function (e) { var t = e.remoteAddress + ":" + e.remotePort, n = new r(t, "tcpIncoming");return n.conn = e, n.addr = t, n.onConnect(), n; }, n.createTCPOutgoingPeer = function (e, t) { var n = new r(e, "tcpOutgoing");return n.addr = e, n.swarm = t, n; }, n.createWebSeedPeer = function (e, t) { var n = new r(e, "webSeed");return n.swarm = t, n.conn = new u(e, t), n.onConnect(), n; }, r.prototype.onConnect = function () { var e = this;if (!e.destroyed) { e.connected = !0, s("Peer %s connected", e.id), clearTimeout(e.connectTimeout);var t = e.conn;t.once("end", function () { e.destroy(); }), t.once("close", function () { e.destroy(); }), t.once("finish", function () { e.destroy(); }), t.once("error", function (t) { e.destroy(t); });var n = e.wire = new a();n.type = e.type, n.once("end", function () { e.destroy(); }), n.once("close", function () { e.destroy(); }), n.once("finish", function () { e.destroy(); }), n.once("error", function (t) { e.destroy(t); }), n.once("handshake", function (t, n) { e.onHandshake(t, n); }), e.startHandshakeTimeout(), t.pipe(n).pipe(t), e.swarm && !e.sentHandshake && e.handshake(); } }, r.prototype.onHandshake = function (e, t) { var n = this;if (n.swarm && !n.destroyed) { if (n.swarm.destroyed) return n.destroy(new Error("swarm already destroyed"));if (e !== n.swarm.infoHash) return n.destroy(new Error("unexpected handshake info hash for this swarm"));if (t === n.swarm.peerId) return n.destroy(new Error("refusing to connect to ourselves"));s("Peer %s got handshake %s", n.id, e), clearTimeout(n.handshakeTimeout), n.retries = 0;var r = n.addr;!r && n.conn.remoteAddress && (r = n.conn.remoteAddress + ":" + n.conn.remotePort), n.swarm._onWire(n.wire, r), n.swarm && !n.swarm.destroyed && (n.sentHandshake || n.handshake()); } }, r.prototype.handshake = function () { var e = this, t = { dht: !e.swarm.private && !!e.swarm.client.dht };e.wire.handshake(e.swarm.infoHash, e.swarm.client.peerId, t), e.sentHandshake = !0; }, r.prototype.startConnectTimeout = function () { var e = this;clearTimeout(e.connectTimeout), e.connectTimeout = setTimeout(function () { e.destroy(new Error("connect timeout")); }, "webrtc" === e.type ? 25e3 : 5e3), e.connectTimeout.unref && e.connectTimeout.unref(); }, r.prototype.startHandshakeTimeout = function () { var e = this;clearTimeout(e.handshakeTimeout), e.handshakeTimeout = setTimeout(function () { e.destroy(new Error("handshake timeout")); }, 25e3), e.handshakeTimeout.unref && e.handshakeTimeout.unref(); }, r.prototype.destroy = function (e) { var t = this;if (!t.destroyed) { t.destroyed = !0, t.connected = !1, s("destroy %s (error: %s)", t.id, e && (e.message || e)), clearTimeout(t.connectTimeout), clearTimeout(t.handshakeTimeout);var n = t.swarm, r = t.conn, a = t.wire;t.swarm = null, t.conn = null, t.wire = null, n && a && i(n.wires, n.wires.indexOf(a)), r && (r.on("error", o), r.destroy()), a && a.destroy(), n && n.removePeer(t.id); } }; }, { "./webconn": 6, "bittorrent-protocol": 14, debug: 30, "unordered-array-remove": 111 }], 4: [function (e, t, n) { function r(e) { var t = this;t._torrent = e, t._numPieces = e.pieces.length, t._pieces = [], t._onWire = function (e) { t.recalculate(), t._initWire(e); }, t._onWireHave = function (e) { t._pieces[e] += 1; }, t._onWireBitfield = function () { t.recalculate(); }, t._torrent.wires.forEach(function (e) { t._initWire(e); }), t._torrent.on("wire", t._onWire), t.recalculate(); }function o() { return !0; }t.exports = r, r.prototype.getRarestPiece = function (e) { e || (e = o);for (var t = [], n = 1 / 0, r = 0; r < this._numPieces; ++r) { if (e(r)) { var i = this._pieces[r];i === n ? t.push(r) : i < n && (t = [r], n = i); } }return t.length > 0 ? t[Math.random() * t.length | 0] : -1; }, r.prototype.destroy = function () { var e = this;e._torrent.removeListener("wire", e._onWire), e._torrent.wires.forEach(function (t) { e._cleanupWireEvents(t); }), e._torrent = null, e._pieces = null, e._onWire = null, e._onWireHave = null, e._onWireBitfield = null; }, r.prototype._initWire = function (e) { var t = this;e._onClose = function () { t._cleanupWireEvents(e);for (var n = 0; n < this._numPieces; ++n) { t._pieces[n] -= e.peerPieces.get(n); } }, e.on("have", t._onWireHave), e.on("bitfield", t._onWireBitfield), e.once("close", e._onClose); }, r.prototype.recalculate = function () { var e;for (e = 0; e < this._numPieces; ++e) { this._pieces[e] = 0; }var t = this._torrent.wires.length;for (e = 0; e < t; ++e) { for (var n = this._torrent.wires[e], r = 0; r < this._numPieces; ++r) { this._pieces[r] += n.peerPieces.get(r); } } }, r.prototype._cleanupWireEvents = function (e) { e.removeListener("have", this._onWireHave), e.removeListener("bitfield", this._onWireBitfield), e._onClose && e.removeListener("close", e._onClose), e._onClose = null; }; }, {}], 5: [function (e, t, n) { (function (n, r) { function o(e, t, n) { m.call(this), this._debugId = "unknown infohash", this.client = t, this.announce = n.announce, this.urlList = n.urlList, this.path = n.path, this._store = n.store || v, this._getAnnounceOpts = n.getAnnounceOpts, this.strategy = n.strategy || "sequential", this.maxWebConns = n.maxWebConns || 4, this._rechokeNumSlots = !1 === n.uploads || 0 === n.uploads ? 0 : +n.uploads || 10, this._rechokeOptimisticWire = null, this._rechokeOptimisticTime = 0, this._rechokeIntervalId = null, this.ready = !1, this.destroyed = !1, this.paused = !1, this.done = !1, this.metadata = null, this.store = null, this.files = [], this.pieces = [], this._amInterested = !1, this._selections = [], this._critical = [], this.wires = [], this._queue = [], this._peers = {}, this._peersLength = 0, this.received = 0, this.uploaded = 0, this._downloadSpeed = O(), this._uploadSpeed = O(), this._servers = [], this._xsRequests = [], this._fileModtimes = n.fileModtimes, null !== e && this._onTorrentId(e), this._debug("new torrent"); }function i(e, t) { return 2 + Math.ceil(t * e.downloadSpeed() / T.BLOCK_LENGTH); }function s(e, t, n) { return 1 + Math.ceil(t * e.downloadSpeed() / n); }function a(e) { return Math.random() * e | 0; }function u() {}t.exports = o;var c, f = e("addr-to-ip-port"), d = e("bitfield"), h = e("chunk-store-stream/write"), l = e("debug")("webtorrent:torrent"), p = e("torrent-discovery"), m = e("events").EventEmitter, g = e("xtend"), y = e("xtend/mutable"), _ = e("fs"), v = e("fs-chunk-store"), b = e("simple-get"), w = e("immediate-chunk-store"), E = e("inherits"), k = e("multistream"), x = e("net"), S = e("os"), I = e("run-parallel"), B = e("run-parallel-limit"), A = e("parse-torrent"), C = e("path"), T = e("torrent-piece"), L = e("pump"), U = e("random-iterate"), R = e("simple-sha1"), O = e("speedometer"), M = e("uniq"), P = e("ut_metadata"), j = e("ut_pex"), H = e("./file"), N = e("./peer"), q = e("./rarity-map"), D = e("./server"), W = 5e3, z = 3 * T.BLOCK_LENGTH, F = [1e3, 5e3, 15e3], V = e("../package.json").version, G = "WebTorrent/" + V + " (https://webtorrent.io)";try { c = C.join(_.statSync("/tmp") && "/tmp", "webtorrent"); } catch (e) { c = C.join("function" == typeof S.tmpdir ? S.tmpdir() : "/", "webtorrent"); }E(o, m), Object.defineProperty(o.prototype, "timeRemaining", { get: function get() { return this.done ? 0 : 0 === this.downloadSpeed ? 1 / 0 : (this.length - this.downloaded) / this.