OR CONTRIBUTORS BE\n\t * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n\t * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n\t * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\n\t * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\n\t * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE\n\t * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN\n\t * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\t *\n\t * The views and conclusions contained in the software and documentation\n\t * are those of the authors and should not be interpreted as representing\n\t * official policies, either expressed or implied, of the authors.\n\t */\n\t\n\tvar _aes = _dereq_(13);\n\t\n\tvar _aes2 = _interopRequireDefault(_aes);\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\t\n\tfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\t\n\tvar AES128Decrypter = function () {\n\t function AES128Decrypter(key, initVector) {\n\t _classCallCheck(this, AES128Decrypter);\n\t\n\t this.key = key;\n\t this.iv = initVector;\n\t }\n\t\n\t /**\n\t * Convert network-order (big-endian) bytes into their little-endian\n\t * representation.\n\t */\n\t\n\t\n\t _createClass(AES128Decrypter, [{\n\t key: 'ntoh',\n\t value: function ntoh(word) {\n\t return word << 24 | (word & 0xff00) << 8 | (word & 0xff0000) >> 8 | word >>> 24;\n\t }\n\t\n\t /**\n\t * Decrypt bytes using AES-128 with CBC and PKCS#7 padding.\n\t * @param encrypted {Uint8Array} the encrypted bytes\n\t * @param key {Uint32Array} the bytes of the decryption key\n\t * @param initVector {Uint32Array} the initialization vector (IV) to\n\t * use for the first round of CBC.\n\t * @return {Uint8Array} the decrypted bytes\n\t *\n\t * @see http://en.wikipedia.org/wiki/Advanced_Encryption_Standard\n\t * @see http://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Cipher_Block_Chaining_.28CBC.29\n\t * @see https://tools.ietf.org/html/rfc2315\n\t */\n\t\n\t }, {\n\t key: 'doDecrypt',\n\t value: function doDecrypt(encrypted, key, initVector) {\n\t var\n\t // word-level access to the encrypted bytes\n\t encrypted32 = new Int32Array(encrypted.buffer, encrypted.byteOffset, encrypted.byteLength >> 2),\n\t decipher = new _aes2.default(Array.prototype.slice.call(key)),\n\t\n\t\n\t // byte and word-level access for the decrypted output\n\t decrypted = new Uint8Array(encrypted.byteLength),\n\t decrypted32 = new Int32Array(decrypted.buffer),\n\t\n\t\n\t // temporary variables for working with the IV, encrypted, and\n\t // decrypted data\n\t init0,\n\t init1,\n\t init2,\n\t init3,\n\t encrypted0,\n\t encrypted1,\n\t encrypted2,\n\t encrypted3,\n\t\n\t\n\t // iteration variable\n\t wordIx;\n\t\n\t // pull out the words of the IV to ensure we don't modify the\n\t // passed-in reference and easier access\n\t init0 = ~ ~initVector[0];\n\t init1 = ~ ~initVector[1];\n\t init2 = ~ ~initVector[2];\n\t init3 = ~ ~initVector[3];\n\t\n\t // decrypt four word sequences, applying cipher-block chaining (CBC)\n\t // to each decrypted block\n\t for (wordIx = 0; wordIx < encrypted32.length; wordIx += 4) {\n\t // convert big-endian (network order) words into little-endian\n\t // (javascript order)\n\t encrypted0 = ~ ~this.ntoh(encrypted32[wordIx]);\n\t encrypted1 = ~ ~this.ntoh(encrypted32[wordIx + 1]);\n\t encrypted2 = ~ ~this.ntoh(encrypted32[wordIx + 2]);\n\t encrypted3 = ~ ~this.ntoh(encrypted32[wordIx + 3]);\n\t\n\t // decrypt the block\n\t decipher.decrypt(encrypted0, encrypted1, encrypted2, encrypted3, decrypted32, wordIx);\n\t\n\t // XOR with the IV, and restore network byte-order to obtain the\n\t // plaintext\n\t decrypted32[wordIx] = this.ntoh(decrypted32[wordIx] ^ init0);\n\t decrypted32[wordIx + 1] = this.ntoh(decrypted32[wordIx + 1] ^ init1);\n\t decrypted32[wordIx + 2] = this.ntoh(decrypted32[wordIx + 2] ^ init2);\n\t decrypted32[wordIx + 3] = this.ntoh(decrypted32[wordIx + 3] ^ init3);\n\t\n\t // setup the IV for the next round\n\t init0 = encrypted0;\n\t init1 = encrypted1;\n\t init2 = encrypted2;\n\t init3 = encrypted3;\n\t }\n\t\n\t return decrypted;\n\t }\n\t }, {\n\t key: 'localDecrypt',\n\t value: function localDecrypt(encrypted, key, initVector, decrypted) {\n\t var bytes = this.doDecrypt(encrypted, key, initVector);\n\t decrypted.set(bytes, encrypted.byteOffset);\n\t }\n\t }, {\n\t key: 'decrypt',\n\t value: function decrypt(encrypted) {\n\t var step = 4 * 8000,\n\t\n\t //encrypted32 = new Int32Array(encrypted.buffer),\n\t encrypted32 = new Int32Array(encrypted),\n\t decrypted = new Uint8Array(encrypted.byteLength),\n\t i = 0;\n\t\n\t // split up the encryption job and do the individual chunks asynchronously\n\t var key = this.key;\n\t var initVector = this.iv;\n\t this.localDecrypt(encrypted32.subarray(i, i + step), key, initVector, decrypted);\n\t\n\t for (i = step; i < encrypted32.length; i += step) {\n\t initVector = new Uint32Array([this.ntoh(encrypted32[i - 4]), this.ntoh(encrypted32[i - 3]), this.ntoh(encrypted32[i - 2]), this.ntoh(encrypted32[i - 1])]);\n\t this.localDecrypt(encrypted32.subarray(i, i + step), key, initVector, decrypted);\n\t }\n\t\n\t return decrypted;\n\t }\n\t }]);\n\t\n\t return AES128Decrypter;\n\t}();\n\t\n\texports.default = AES128Decrypter;\n\t\n\t},{\"13\":13}],15:[function(_dereq_,module,exports){\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t\n\tvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /*\n\t * AES128 decryption.\n\t */\n\t\n\tvar _aes128Decrypter = _dereq_(14);\n\t\n\tvar _aes128Decrypter2 = _interopRequireDefault(_aes128Decrypter);\n\t\n\tvar _errors = _dereq_(24);\n\t\n\tvar _logger = _dereq_(43);\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\t\n\tfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\t\n\tvar Decrypter = function () {\n\t function Decrypter(hls) {\n\t _classCallCheck(this, Decrypter);\n\t\n\t this.hls = hls;\n\t try {\n\t var browserCrypto = window ? window.crypto : crypto;\n\t this.subtle = browserCrypto.subtle || browserCrypto.webkitSubtle;\n\t this.disableWebCrypto = !this.subtle;\n\t } catch (e) {\n\t this.disableWebCrypto = true;\n\t }\n\t }\n\t\n\t _createClass(Decrypter, [{\n\t key: 'destroy',\n\t value: function destroy() {}\n\t }, {\n\t key: 'decrypt',\n\t value: function decrypt(data, key, iv, callback) {\n\t if (this.disableWebCrypto && this.hls.config.enableSoftwareAES) {\n\t this.decryptBySoftware(data, key, iv, callback);\n\t } else {\n\t this.decryptByWebCrypto(data, key, iv, callback);\n\t }\n\t }\n\t }, {\n\t key: 'decryptByWebCrypto',\n\t value: function decryptByWebCrypto(data, key, iv, callback) {\n\t var _this = this;\n\t\n\t _logger.logger.log('decrypting by WebCrypto API');\n\t\n\t this.subtle.importKey('raw', key, { name: 'AES-CBC', length: 128 }, false, ['decrypt']).then(function (importedKey) {\n\t _this.subtle.decrypt({ name: 'AES-CBC', iv: iv.buffer }, importedKey, data).then(callback).catch(function (err) {\n\t _this.onWebCryptoError(err, data, key, iv, callback);\n\t });\n\t }).catch(function (err) {\n\t _this.onWebCryptoError(err, data, key, iv, callback);\n\t });\n\t }\n\t }, {\n\t key: 'decryptBySoftware',\n\t value: function decryptBySoftware(data, key8, iv8, callback) {\n\t _logger.logger.log('decrypting by JavaScript Implementation');\n\t\n\t var view = new DataView(key8.buffer);\n\t var key = new Uint32Array([view.getUint32(0), view.getUint32(4), view.getUint32(8), view.getUint32(12)]);\n\t\n\t view = new DataView(iv8.buffer);\n\t var iv = new Uint32Array([view.getUint32(0), view.getUint32(4), view.getUint32(8), view.getUint32(12)]);\n\t\n\t var decrypter = new _aes128Decrypter2.default(key, iv);\n\t callback(decrypter.decrypt(data).buffer);\n\t }\n\t }, {\n\t key: 'onWebCryptoError',\n\t value: function onWebCryptoError(err, data, key, iv, callback) {\n\t if (this.hls.config.enableSoftwareAES) {\n\t _logger.logger.log('disabling to use WebCrypto API');\n\t this.disableWebCrypto = true;\n\t this.decryptBySoftware(data, key, iv, callback);\n\t } else {\n\t _logger.logger.error('decrypting error : ' + err.message);\n\t this.hls.trigger(Event.ERROR, { type: _errors.ErrorTypes.MEDIA_ERROR, details: _errors.ErrorDetails.FRAG_DECRYPT_ERROR, fatal: true, reason: err.message });\n\t }\n\t }\n\t }]);\n\t\n\t return Decrypter;\n\t}();\n\t\n\texports.default = Decrypter;\n\t\n\t},{\"14\":14,\"24\":24,\"43\":43}],16:[function(_dereq_,module,exports){\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t\n\tvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /**\n\t * AAC demuxer\n\t */\n\t\n\t\n\tvar _adts = _dereq_(17);\n\t\n\tvar _adts2 = _interopRequireDefault(_adts);\n\t\n\tvar _logger = _dereq_(43);\n\t\n\tvar _id = _dereq_(22);\n\t\n\tvar _id2 = _interopRequireDefault(_id);\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\t\n\tfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\t\n\tvar AACDemuxer = function () {\n\t function AACDemuxer(observer, id, remuxerClass, config) {\n\t _classCallCheck(this, AACDemuxer);\n\t\n\t this.observer = observer;\n\t this.id = id;\n\t this.remuxerClass = remuxerClass;\n\t this.config = config;\n\t this.remuxer = new this.remuxerClass(observer, id, config);\n\t this.insertDiscontinuity();\n\t }\n\t\n\t _createClass(AACDemuxer, [{\n\t key: 'insertDiscontinuity',\n\t value: function insertDiscontinuity() {\n\t this._aacTrack = { container: 'audio/adts', type: 'audio', id: -1, sequenceNumber: 0, samples: [], len: 0 };\n\t }\n\t }, {\n\t key: 'push',\n\t\n\t\n\t // feed incoming data to the front of the parsing pipeline\n\t value: function push(data, audioCodec, videoCodec, timeOffset, cc, level, sn, duration, accurateTimeOffset) {\n\t var track,\n\t id3 = new _id2.default(data),\n\t pts = 90 * id3.timeStamp,\n\t config,\n\t frameLength,\n\t frameDuration,\n\t frameIndex,\n\t offset,\n\t headerLength,\n\t stamp,\n\t len,\n\t aacSample;\n\t\n\t var contiguous = false;\n\t if (cc !== this.lastCC) {\n\t _logger.logger.log(this.id + ' discontinuity detected');\n\t this.lastCC = cc;\n\t this.insertDiscontinuity();\n\t this.remuxer.switchLevel();\n\t this.remuxer.insertDiscontinuity();\n\t } else if (level !== this.lastLevel) {\n\t _logger.logger.log('audio track switch detected');\n\t this.lastLevel = level;\n\t this.remuxer.switchLevel();\n\t this.insertDiscontinuity();\n\t } else if (sn === this.lastSN + 1) {\n\t contiguous = true;\n\t }\n\t track = this._aacTrack;\n\t this.lastSN = sn;\n\t this.lastLevel = level;\n\t\n\t // look for ADTS header (0xFFFx)\n\t for (offset = id3.length, len = data.length; offset < len - 1; offset++) {\n\t if (data[offset] === 0xff && (data[offset + 1] & 0xf0) === 0xf0) {\n\t break;\n\t }\n\t }\n\t\n\t if (!track.audiosamplerate) {\n\t config = _adts2.default.getAudioConfig(this.observer, data, offset, audioCodec);\n\t track.config = config.config;\n\t track.audiosamplerate = config.samplerate;\n\t track.channelCount = config.channelCount;\n\t track.codec = config.codec;\n\t track.duration = duration;\n\t _logger.logger.log('parsed codec:' + track.codec + ',rate:' + config.samplerate + ',nb channel:' + config.channelCount);\n\t }\n\t frameIndex = 0;\n\t frameDuration = 1024 * 90000 / track.audiosamplerate;\n\t while (offset + 5 < len) {\n\t // The protection skip bit tells us if we have 2 bytes of CRC data at the end of the ADTS header\n\t headerLength = !!(data[offset + 1] & 0x01) ? 7 : 9;\n\t // retrieve frame size\n\t frameLength = (data[offset + 3] & 0x03) << 11 | data[offset + 4] << 3 | (data[offset + 5] & 0xE0) >>> 5;\n\t frameLength -= headerLength;\n\t //stamp = pes.pts;\n\t\n\t if (frameLength > 0 && offset + headerLength + frameLength <= len) {\n\t stamp = pts + frameIndex * frameDuration;\n\t //logger.log(`AAC frame, offset/length/total/pts:${offset+headerLength}/${frameLength}/${data.byteLength}/${(stamp/90).toFixed(0)}`);\n\t aacSample = { unit: data.subarray(offset + headerLength, offset + headerLength + frameLength), pts: stamp, dts: stamp };\n\t track.samples.push(aacSample);\n\t track.len += frameLength;\n\t offset += frameLength + headerLength;\n\t frameIndex++;\n\t // look for ADTS header (0xFFFx)\n\t for (; offset < len - 1; offset++) {\n\t if (data[offset] === 0xff && (data[offset + 1] & 0xf0) === 0xf0) {\n\t break;\n\t }\n\t }\n\t } else {\n\t break;\n\t }\n\t }\n\t this.remuxer.remux(level, sn, this._aacTrack, { samples: [] }, { samples: [{ pts: pts, dts: pts, unit: id3.payload }] }, { samples: [] }, timeOffset, contiguous, accurateTimeOffset);\n\t }\n\t }, {\n\t key: 'destroy',\n\t value: function destroy() {}\n\t }], [{\n\t key: 'probe',\n\t value: function probe(data) {\n\t // check if data contains ID3 timestamp and ADTS sync worc\n\t var id3 = new _id2.default(data),\n\t offset,\n\t len;\n\t if (id3.hasTimeStamp) {\n\t // look for ADTS header (0xFFFx)\n\t for (offset = id3.length, len = data.length; offset < len - 1; offset++) {\n\t if (data[offset] === 0xff && (data[offset + 1] & 0xf0) === 0xf0) {\n\t //logger.log('ADTS sync word found !');\n\t return true;\n\t }\n\t }\n\t }\n\t return false;\n\t }\n\t }]);\n\t\n\t return AACDemuxer;\n\t}();\n\t\n\texports.default = AACDemuxer;\n\t\n\t},{\"17\":17,\"22\":22,\"43\":43}],17:[function(_dereq_,module,exports){\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t\n\tvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /**\n\t * ADTS parser helper\n\t */\n\t\n\t\n\tvar _logger = _dereq_(43);\n\t\n\tvar _errors = _dereq_(24);\n\t\n\tfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\t\n\tvar ADTS = function () {\n\t function ADTS() {\n\t _classCallCheck(this, ADTS);\n\t }\n\t\n\t _createClass(ADTS, null, [{\n\t key: 'getAudioConfig',\n\t value: function getAudioConfig(observer, data, offset, audioCodec) {\n\t var adtsObjectType,\n\t // :int\n\t adtsSampleingIndex,\n\t // :int\n\t adtsExtensionSampleingIndex,\n\t // :int\n\t adtsChanelConfig,\n\t // :int\n\t config,\n\t userAgent = navigator.userAgent.toLowerCase(),\n\t adtsSampleingRates = [96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000, 7350];\n\t // byte 2\n\t adtsObjectType = ((data[offset + 2] & 0xC0) >>> 6) + 1;\n\t adtsSampleingIndex = (data[offset + 2] & 0x3C) >>> 2;\n\t if (adtsSampleingIndex > adtsSampleingRates.length - 1) {\n\t observer.trigger(Event.ERROR, { type: _errors.ErrorTypes.MEDIA_ERROR, details: _errors.ErrorDetails.FRAG_PARSING_ERROR, fatal: true, reason: 'invalid ADTS sampling index:' + adtsSampleingIndex });\n\t return;\n\t }\n\t adtsChanelConfig = (data[offset + 2] & 0x01) << 2;\n\t // byte 3\n\t adtsChanelConfig |= (data[offset + 3] & 0xC0) >>> 6;\n\t _logger.logger.log('manifest codec:' + audioCodec + ',ADTS data:type:' + adtsObjectType + ',sampleingIndex:' + adtsSampleingIndex + '[' + adtsSampleingRates[adtsSampleingIndex] + 'Hz],channelConfig:' + adtsChanelConfig);\n\t // firefox/Opera: freq less than 24kHz = AAC SBR (HE-AAC)\n\t if (/firefox|OPR/i.test(userAgent)) {\n\t if (adtsSampleingIndex >= 6) {\n\t adtsObjectType = 5;\n\t config = new Array(4);\n\t // HE-AAC uses SBR (Spectral Band Replication) , high frequencies are constructed from low frequencies\n\t // there is a factor 2 between frame sample rate and output sample rate\n\t // multiply frequency by 2 (see table below, equivalent to substract 3)\n\t adtsExtensionSampleingIndex = adtsSampleingIndex - 3;\n\t } else {\n\t adtsObjectType = 2;\n\t config = new Array(2);\n\t adtsExtensionSampleingIndex = adtsSampleingIndex;\n\t }\n\t // Android : always use AAC\n\t } else if (userAgent.indexOf('android') !== -1) {\n\t adtsObjectType = 2;\n\t config = new Array(2);\n\t adtsExtensionSampleingIndex = adtsSampleingIndex;\n\t } else {\n\t /* for other browsers (Chrome/Vivaldi ...)\n\t always force audio type to be HE-AAC SBR, as some browsers do not support audio codec switch properly (like Chrome ...)\n\t */\n\t adtsObjectType = 5;\n\t config = new Array(4);\n\t // if (manifest codec is HE-AAC or HE-AACv2) OR (manifest codec not specified AND frequency less than 24kHz)\n\t if (audioCodec && (audioCodec.indexOf('mp4a.40.29') !== -1 || audioCodec.indexOf('mp4a.40.5') !== -1) || !audioCodec && adtsSampleingIndex >= 6) {\n\t // HE-AAC uses SBR (Spectral Band Replication) , high frequencies are constructed from low frequencies\n\t // there is a factor 2 between frame sample rate and output sample rate\n\t // multiply frequency by 2 (see table below, equivalent to substract 3)\n\t adtsExtensionSampleingIndex = adtsSampleingIndex - 3;\n\t } else {\n\t // if (manifest codec is AAC) AND (frequency less than 24kHz AND nb channel is 1) OR (manifest codec not specified and mono audio)\n\t // Chrome fails to play back with low frequency AAC LC mono when initialized with HE-AAC. This is not a problem with stereo.\n\t if (audioCodec && audioCodec.indexOf('mp4a.40.2') !== -1 && adtsSampleingIndex >= 6 && adtsChanelConfig === 1 || !audioCodec && adtsChanelConfig === 1) {\n\t adtsObjectType = 2;\n\t config = new Array(2);\n\t }\n\t adtsExtensionSampleingIndex = adtsSampleingIndex;\n\t }\n\t }\n\t /* refer to http://wiki.multimedia.cx/index.php?title=MPEG-4_Audio#Audio_Specific_Config\n\t ISO 14496-3 (AAC).pdf - Table 1.13 — Syntax of AudioSpecificConfig()\n\t Audio Profile / Audio Object Type\n\t 0: Null\n\t 1: AAC Main\n\t 2: AAC LC (Low Complexity)\n\t 3: AAC SSR (Scalable Sample Rate)\n\t 4: AAC LTP (Long Term Prediction)\n\t 5: SBR (Spectral Band Replication)\n\t 6: AAC Scalable\n\t sampling freq\n\t 0: 96000 Hz\n\t 1: 88200 Hz\n\t 2: 64000 Hz\n\t 3: 48000 Hz\n\t 4: 44100 Hz\n\t 5: 32000 Hz\n\t 6: 24000 Hz\n\t 7: 22050 Hz\n\t 8: 16000 Hz\n\t 9: 12000 Hz\n\t 10: 11025 Hz\n\t 11: 8000 Hz\n\t 12: 7350 Hz\n\t 13: Reserved\n\t 14: Reserved\n\t 15: frequency is written explictly\n\t Channel Configurations\n\t These are the channel configurations:\n\t 0: Defined in AOT Specifc Config\n\t 1: 1 channel: front-center\n\t 2: 2 channels: front-left, front-right\n\t */\n\t // audioObjectType = profile => profile, the MPEG-4 Audio Object Type minus 1\n\t config[0] = adtsObjectType << 3;\n\t // samplingFrequencyIndex\n\t config[0] |= (adtsSampleingIndex & 0x0E) >> 1;\n\t config[1] |= (adtsSampleingIndex & 0x01) << 7;\n\t // channelConfiguration\n\t config[1] |= adtsChanelConfig << 3;\n\t if (adtsObjectType === 5) {\n\t // adtsExtensionSampleingIndex\n\t config[1] |= (adtsExtensionSampleingIndex & 0x0E) >> 1;\n\t config[2] = (adtsExtensionSampleingIndex & 0x01) << 7;\n\t // adtsObjectType (force to 2, chrome is checking that object type is less than 5 ???\n\t // https://chromium.googlesource.com/chromium/src.git/+/master/media/formats/mp4/aac.cc\n\t config[2] |= 2 << 2;\n\t config[3] = 0;\n\t }\n\t return { config: config, samplerate: adtsSampleingRates[adtsSampleingIndex], channelCount: adtsChanelConfig, codec: 'mp4a.40.' + adtsObjectType };\n\t }\n\t }]);\n\t\n\t return ADTS;\n\t}();\n\t\n\texports.default = ADTS;\n\t\n\t},{\"24\":24,\"43\":43}],18:[function(_dereq_,module,exports){\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t\n\tvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /* inline demuxer.\n\t * probe fragments and instantiate appropriate demuxer depending on content type (TSDemuxer, AACDemuxer, ...)\n\t */\n\t\n\tvar _events = _dereq_(26);\n\t\n\tvar _events2 = _interopRequireDefault(_events);\n\t\n\tvar _errors = _dereq_(24);\n\t\n\tvar _aacdemuxer = _dereq_(16);\n\t\n\tvar _aacdemuxer2 = _interopRequireDefault(_aacdemuxer);\n\t\n\tvar _tsdemuxer = _dereq_(23);\n\t\n\tvar _tsdemuxer2 = _interopRequireDefault(_tsdemuxer);\n\t\n\tvar _mp4Remuxer = _dereq_(36);\n\t\n\tvar _mp4Remuxer2 = _interopRequireDefault(_mp4Remuxer);\n\t\n\tvar _passthroughRemuxer = _dereq_(37);\n\t\n\tvar _passthroughRemuxer2 = _interopRequireDefault(_passthroughRemuxer);\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\t\n\tfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\t\n\tvar DemuxerInline = function () {\n\t function DemuxerInline(hls, id, typeSupported) {\n\t var config = arguments.length <= 3 || arguments[3] === undefined ? null : arguments[3];\n\t\n\t _classCallCheck(this, DemuxerInline);\n\t\n\t this.hls = hls;\n\t this.id = id;\n\t this.config = this.hls.config || config;\n\t this.typeSupported = typeSupported;\n\t }\n\t\n\t _createClass(DemuxerInline, [{\n\t key: 'destroy',\n\t value: function destroy() {\n\t var demuxer = this.demuxer;\n\t if (demuxer) {\n\t demuxer.destroy();\n\t }\n\t }\n\t }, {\n\t key: 'push',\n\t value: function push(data, audioCodec, videoCodec, timeOffset, cc, level, sn, duration, accurateTimeOffset) {\n\t var demuxer = this.demuxer;\n\t if (!demuxer) {\n\t var hls = this.hls,\n\t id = this.id;\n\t // probe for content type\n\t if (_tsdemuxer2.default.probe(data)) {\n\t if (this.typeSupported.mp2t === true) {\n\t demuxer = new _tsdemuxer2.default(hls, id, _passthroughRemuxer2.default, this.config);\n\t } else {\n\t demuxer = new _tsdemuxer2.default(hls, id, _mp4Remuxer2.default, this.config);\n\t }\n\t } else if (_aacdemuxer2.default.probe(data)) {\n\t demuxer = new _aacdemuxer2.default(hls, id, _mp4Remuxer2.default, this.config);\n\t } else {\n\t hls.trigger(_events2.default.ERROR, { type: _errors.ErrorTypes.MEDIA_ERROR, id: id, details: _errors.ErrorDetails.FRAG_PARSING_ERROR, fatal: true, reason: 'no demux matching with content found' });\n\t return;\n\t }\n\t this.demuxer = demuxer;\n\t }\n\t demuxer.push(data, audioCodec, videoCodec, timeOffset, cc, level, sn, duration, accurateTimeOffset);\n\t }\n\t }]);\n\t\n\t return DemuxerInline;\n\t}();\n\t\n\texports.default = DemuxerInline;\n\t\n\t},{\"16\":16,\"23\":23,\"24\":24,\"26\":26,\"36\":36,\"37\":37}],19:[function(_dereq_,module,exports){\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t\n\tvar _demuxerInline = _dereq_(18);\n\t\n\tvar _demuxerInline2 = _interopRequireDefault(_demuxerInline);\n\t\n\tvar _events = _dereq_(26);\n\t\n\tvar _events2 = _interopRequireDefault(_events);\n\t\n\tvar _logger = _dereq_(43);\n\t\n\tvar _events3 = _dereq_(1);\n\t\n\tvar _events4 = _interopRequireDefault(_events3);\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\t\n\t/* demuxer web worker.\n\t * - listen to worker message, and trigger DemuxerInline upon reception of Fragments.\n\t * - provides MP4 Boxes back to main thread using [transferable objects](https://developers.google.com/web/updates/2011/12/Transferable-Objects-Lightning-Fast) in order to minimize message passing overhead.\n\t */\n\t\n\tvar DemuxerWorker = function DemuxerWorker(self) {\n\t // observer setup\n\t var observer = new _events4.default();\n\t observer.trigger = function trigger(event) {\n\t for (var _len = arguments.length, data = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {\n\t data[_key - 1] = arguments[_key];\n\t }\n\t\n\t observer.emit.apply(observer, [event, event].concat(data));\n\t };\n\t\n\t observer.off = function off(event) {\n\t for (var _len2 = arguments.length, data = Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {\n\t data[_key2 - 1] = arguments[_key2];\n\t }\n\t\n\t observer.removeListener.apply(observer, [event].concat(data));\n\t };\n\t\n\t var forwardMessage = function forwardMessage(ev, data) {\n\t self.postMessage({ event: ev, data: data });\n\t };\n\t\n\t self.addEventListener('message', function (ev) {\n\t var data = ev.data;\n\t //console.log('demuxer cmd:' + data.cmd);\n\t switch (data.cmd) {\n\t case 'init':\n\t var config = JSON.parse(data.config);\n\t self.demuxer = new _demuxerInline2.default(observer, data.id, data.typeSupported, config);\n\t try {\n\t (0, _logger.enableLogs)(config.debug);\n\t } catch (err) {\n\t console.warn('demuxerWorker: unable to enable logs');\n\t }\n\t // signal end of worker init\n\t forwardMessage('init', null);\n\t break;\n\t case 'demux':\n\t self.demuxer.push(new Uint8Array(data.data), data.audioCodec, data.videoCodec, data.timeOffset, data.cc, data.level, data.sn, data.duration, data.accurateTimeOffset);\n\t break;\n\t default:\n\t break;\n\t }\n\t });\n\t\n\t // forward events to main thread\n\t observer.on(_events2.default.FRAG_PARSING_INIT_SEGMENT, forwardMessage);\n\t observer.on(_events2.default.FRAG_PARSED, forwardMessage);\n\t observer.on(_events2.default.ERROR, forwardMessage);\n\t observer.on(_events2.default.FRAG_PARSING_METADATA, forwardMessage);\n\t observer.on(_events2.default.FRAG_PARSING_USERDATA, forwardMessage);\n\t\n\t // special case for FRAG_PARSING_DATA: pass data1/data2 as transferable object (no copy)\n\t observer.on(_events2.default.FRAG_PARSING_DATA, function (ev, data) {\n\t var data1 = data.data1.buffer,\n\t data2 = data.data2.buffer;\n\t // remove data1 and data2 reference from data to avoid copying them ...\n\t delete data.data1;\n\t delete data.data2;\n\t self.postMessage({ event: ev, data: data, data1: data1, data2: data2 }, [data1, data2]);\n\t });\n\t};\n\t\n\texports.default = DemuxerWorker;\n\t\n\t},{\"1\":1,\"18\":18,\"26\":26,\"43\":43}],20:[function(_dereq_,module,exports){\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t\n\tvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\t\n\tvar _events = _dereq_(26);\n\t\n\tvar _events2 = _interopRequireDefault(_events);\n\t\n\tvar _demuxerInline = _dereq_(18);\n\t\n\tvar _demuxerInline2 = _interopRequireDefault(_demuxerInline);\n\t\n\tvar _demuxerWorker = _dereq_(19);\n\t\n\tvar _demuxerWorker2 = _interopRequireDefault(_demuxerWorker);\n\t\n\tvar _logger = _dereq_(43);\n\t\n\tvar _decrypter = _dereq_(15);\n\t\n\tvar _decrypter2 = _interopRequireDefault(_decrypter);\n\t\n\tvar _errors = _dereq_(24);\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\t\n\tfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\t\n\tvar Demuxer = function () {\n\t function Demuxer(hls, id) {\n\t _classCallCheck(this, Demuxer);\n\t\n\t this.hls = hls;\n\t this.id = id;\n\t var typeSupported = {\n\t mp4: MediaSource.isTypeSupported('video/mp4'),\n\t mp2t: hls.config.enableMP2TPassThrough && MediaSource.isTypeSupported('video/mp2t')\n\t };\n\t if (hls.config.enableWorker && typeof Worker !== 'undefined') {\n\t _logger.logger.log('demuxing in webworker');\n\t var w = void 0;\n\t try {\n\t var work = _dereq_(2);\n\t w = this.w = work(_demuxerWorker2.default);\n\t this.onwmsg = this.onWorkerMessage.bind(this);\n\t w.addEventListener('message', this.onwmsg);\n\t w.onerror = function (event) {\n\t hls.trigger(_events2.default.ERROR, { type: _errors.ErrorTypes.OTHER_ERROR, details: _errors.ErrorDetails.INTERNAL_EXCEPTION, fatal: true, event: 'demuxerWorker', err: { message: event.message + ' (' + event.filename + ':' + event.lineno + ')' } });\n\t };\n\t w.postMessage({ cmd: 'init', typeSupported: typeSupported, id: id, config: JSON.stringify(hls.config) });\n\t } catch (err) {\n\t _logger.logger.error('error while initializing DemuxerWorker, fallback on DemuxerInline');\n\t if (w) {\n\t // revoke the Object URL that was used to create demuxer worker, so as not to leak it\n\t URL.revokeObjectURL(w.objectURL);\n\t }\n\t this.demuxer = new _demuxerInline2.default(hls, id, typeSupported);\n\t }\n\t } else {\n\t this.demuxer = new _demuxerInline2.default(hls, id, typeSupported);\n\t }\n\t this.demuxInitialized = true;\n\t }\n\t\n\t _createClass(Demuxer, [{\n\t key: 'destroy',\n\t value: function destroy() {\n\t var w = this.w;\n\t if (w) {\n\t w.removeEventListener('message', this.onwmsg);\n\t w.terminate();\n\t this.w = null;\n\t } else {\n\t var demuxer = this.demuxer;\n\t if (demuxer) {\n\t demuxer.destroy();\n\t this.demuxer = null;\n\t }\n\t }\n\t var decrypter = this.decrypter;\n\t if (decrypter) {\n\t decrypter.destroy();\n\t this.decrypter = null;\n\t }\n\t }\n\t }, {\n\t key: 'pushDecrypted',\n\t value: function pushDecrypted(data, audioCodec, videoCodec, timeOffset, cc, level, sn, duration, accurateTimeOffset) {\n\t var w = this.w;\n\t if (w) {\n\t // post fragment payload as transferable objects (no copy)\n\t w.postMessage({ cmd: 'demux', data: data, audioCodec: audioCodec, videoCodec: videoCodec, timeOffset: timeOffset, cc: cc, level: level, sn: sn, duration: duration, accurateTimeOffset: accurateTimeOffset }, [data]);\n\t } else {\n\t var demuxer = this.demuxer;\n\t if (demuxer) {\n\t demuxer.push(new Uint8Array(data), audioCodec, videoCodec, timeOffset, cc, level, sn, duration, accurateTimeOffset);\n\t }\n\t }\n\t }\n\t }, {\n\t key: 'push',\n\t value: function push(data, audioCodec, videoCodec, timeOffset, cc, level, sn, duration, decryptdata, accurateTimeOffset) {\n\t if (data.byteLength > 0 && decryptdata != null && decryptdata.key != null && decryptdata.method === 'AES-128') {\n\t if (this.decrypter == null) {\n\t this.decrypter = new _decrypter2.default(this.hls);\n\t }\n\t\n\t var localthis = this;\n\t this.decrypter.decrypt(data, decryptdata.key, decryptdata.iv, function (decryptedData) {\n\t localthis.pushDecrypted(decryptedData, audioCodec, videoCodec, timeOffset, cc, level, sn, duration, accurateTimeOffset);\n\t });\n\t } else {\n\t this.pushDecrypted(data, audioCodec, videoCodec, timeOffset, cc, level, sn, duration, accurateTimeOffset);\n\t }\n\t }\n\t }, {\n\t key: 'onWorkerMessage',\n\t value: function onWorkerMessage(ev) {\n\t var data = ev.data,\n\t hls = this.hls;\n\t //console.log('onWorkerMessage:' + data.event);\n\t switch (data.event) {\n\t case 'init':\n\t // revoke the Object URL that was used to create demuxer worker, so as not to leak it\n\t URL.revokeObjectURL(this.w.objectURL);\n\t break;\n\t // special case for FRAG_PARSING_DATA: data1 and data2 are transferable objects\n\t case _events2.default.FRAG_PARSING_DATA:\n\t data.data.data1 = new Uint8Array(data.data1);\n\t data.data.data2 = new Uint8Array(data.data2);\n\t /* falls through */\n\t default:\n\t hls.trigger(data.event, data.data);\n\t break;\n\t }\n\t }\n\t }]);\n\t\n\t return Demuxer;\n\t}();\n\t\n\texports.default = Demuxer;\n\t\n\t},{\"15\":15,\"18\":18,\"19\":19,\"2\":2,\"24\":24,\"26\":26,\"43\":43}],21:[function(_dereq_,module,exports){\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t\n\tvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /**\n\t * Parser for exponential Golomb codes, a variable-bitwidth number encoding scheme used by h264.\n\t */\n\t\n\tvar _logger = _dereq_(43);\n\t\n\tfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\t\n\tvar ExpGolomb = function () {\n\t function ExpGolomb(data) {\n\t _classCallCheck(this, ExpGolomb);\n\t\n\t this.data = data;\n\t // the number of bytes left to examine in this.data\n\t this.bytesAvailable = this.data.byteLength;\n\t // the current word being examined\n\t this.word = 0; // :uint\n\t // the number of bits left to examine in the current word\n\t this.bitsAvailable = 0; // :uint\n\t }\n\t\n\t // ():void\n\t\n\t\n\t _createClass(ExpGolomb, [{\n\t key: 'loadWord',\n\t value: function loadWord() {\n\t var position = this.data.byteLength - this.bytesAvailable,\n\t workingBytes = new Uint8Array(4),\n\t availableBytes = Math.min(4, this.bytesAvailable);\n\t if (availableBytes === 0) {\n\t throw new Error('no bytes available');\n\t }\n\t workingBytes.set(this.data.subarray(position, position + availableBytes));\n\t this.word = new DataView(workingBytes.buffer).getUint32(0);\n\t // track the amount of this.data that has been processed\n\t this.bitsAvailable = availableBytes * 8;\n\t this.bytesAvailable -= availableBytes;\n\t }\n\t\n\t // (count:int):void\n\t\n\t }, {\n\t key: 'skipBits',\n\t value: function skipBits(count) {\n\t var skipBytes; // :int\n\t if (this.bitsAvailable > count) {\n\t this.word <<= count;\n\t this.bitsAvailable -= count;\n\t } else {\n\t count -= this.bitsAvailable;\n\t skipBytes = count >> 3;\n\t count -= skipBytes >> 3;\n\t this.bytesAvailable -= skipBytes;\n\t this.loadWord();\n\t this.word <<= count;\n\t this.bitsAvailable -= count;\n\t }\n\t }\n\t\n\t // (size:int):uint\n\t\n\t }, {\n\t key: 'readBits',\n\t value: function readBits(size) {\n\t var bits = Math.min(this.bitsAvailable, size),\n\t // :uint\n\t valu = this.word >>> 32 - bits; // :uint\n\t if (size > 32) {\n\t _logger.logger.error('Cannot read more than 32 bits at a time');\n\t }\n\t this.bitsAvailable -= bits;\n\t if (this.bitsAvailable > 0) {\n\t this.word <<= bits;\n\t } else if (this.bytesAvailable > 0) {\n\t this.loadWord();\n\t }\n\t bits = size - bits;\n\t if (bits > 0 && this.bitsAvailable) {\n\t return valu << bits | this.readBits(bits);\n\t } else {\n\t return valu;\n\t }\n\t }\n\t\n\t // ():uint\n\t\n\t }, {\n\t key: 'skipLZ',\n\t value: function skipLZ() {\n\t var leadingZeroCount; // :uint\n\t for (leadingZeroCount = 0; leadingZeroCount < this.bitsAvailable; ++leadingZeroCount) {\n\t if (0 !== (this.word & 0x80000000 >>> leadingZeroCount)) {\n\t // the first bit of working word is 1\n\t this.word <<= leadingZeroCount;\n\t this.bitsAvailable -= leadingZeroCount;\n\t return leadingZeroCount;\n\t }\n\t }\n\t // we exhausted word and still have not found a 1\n\t this.loadWord();\n\t return leadingZeroCount + this.skipLZ();\n\t }\n\t\n\t // ():void\n\t\n\t }, {\n\t key: 'skipUEG',\n\t value: function skipUEG() {\n\t this.skipBits(1 + this.skipLZ());\n\t }\n\t\n\t // ():void\n\t\n\t }, {\n\t key: 'skipEG',\n\t value: function skipEG() {\n\t this.skipBits(1 + this.skipLZ());\n\t }\n\t\n\t // ():uint\n\t\n\t }, {\n\t key: 'readUEG',\n\t value: function readUEG() {\n\t var clz = this.skipLZ(); // :uint\n\t return this.readBits(clz + 1) - 1;\n\t }\n\t\n\t // ():int\n\t\n\t }, {\n\t key: 'readEG',\n\t value: function readEG() {\n\t var valu = this.readUEG(); // :int\n\t if (0x01 & valu) {\n\t // the number is odd if the low order bit is set\n\t return 1 + valu >>> 1; // add 1 to make it even, and divide by 2\n\t } else {\n\t return -1 * (valu >>> 1); // divide by two then make it negative\n\t }\n\t }\n\t\n\t // Some convenience functions\n\t // :Boolean\n\t\n\t }, {\n\t key: 'readBoolean',\n\t value: function readBoolean() {\n\t return 1 === this.readBits(1);\n\t }\n\t\n\t // ():int\n\t\n\t }, {\n\t key: 'readUByte',\n\t value: function readUByte() {\n\t return this.readBits(8);\n\t }\n\t\n\t // ():int\n\t\n\t }, {\n\t key: 'readUShort',\n\t value: function readUShort() {\n\t return this.readBits(16);\n\t }\n\t // ():int\n\t\n\t }, {\n\t key: 'readUInt',\n\t value: function readUInt() {\n\t return this.readBits(32);\n\t }\n\t\n\t /**\n\t * Advance the ExpGolomb decoder past a scaling list. The scaling\n\t * list is optionally transmitted as part of a sequence parameter\n\t * set and is not relevant to transmuxing.\n\t * @param count {number} the number of entries in this scaling list\n\t * @see Recommendation ITU-T H.264, Section 7.3.2.1.1.1\n\t */\n\t\n\t }, {\n\t key: 'skipScalingList',\n\t value: function skipScalingList(count) {\n\t var lastScale = 8,\n\t nextScale = 8,\n\t j,\n\t deltaScale;\n\t for (j = 0; j < count; j++) {\n\t if (nextScale !== 0) {\n\t deltaScale = this.readEG();\n\t nextScale = (lastScale + deltaScale + 256) % 256;\n\t }\n\t lastScale = nextScale === 0 ? lastScale : nextScale;\n\t }\n\t }\n\t\n\t /**\n\t * Read a sequence parameter set and return some interesting video\n\t * properties. A sequence parameter set is the H264 metadata that\n\t * describes the properties of upcoming video frames.\n\t * @param data {Uint8Array} the bytes of a sequence parameter set\n\t * @return {object} an object with configuration parsed from the\n\t * sequence parameter set, including the dimensions of the\n\t * associated video frames.\n\t */\n\t\n\t }, {\n\t key: 'readSPS',\n\t value: function readSPS() {\n\t var frameCropLeftOffset = 0,\n\t frameCropRightOffset = 0,\n\t frameCropTopOffset = 0,\n\t frameCropBottomOffset = 0,\n\t sarScale = 1,\n\t profileIdc,\n\t profileCompat,\n\t levelIdc,\n\t numRefFramesInPicOrderCntCycle,\n\t picWidthInMbsMinus1,\n\t picHeightInMapUnitsMinus1,\n\t frameMbsOnlyFlag,\n\t scalingListCount,\n\t i;\n\t this.readUByte();\n\t profileIdc = this.readUByte(); // profile_idc\n\t profileCompat = this.readBits(5); // constraint_set[0-4]_flag, u(5)\n\t this.skipBits(3); // reserved_zero_3bits u(3),\n\t levelIdc = this.readUByte(); //level_idc u(8)\n\t this.skipUEG(); // seq_parameter_set_id\n\t // some profiles have more optional data we don't need\n\t if (profileIdc === 100 || profileIdc === 110 || profileIdc === 122 || profileIdc === 244 || profileIdc === 44 || profileIdc === 83 || profileIdc === 86 || profileIdc === 118 || profileIdc === 128) {\n\t var chromaFormatIdc = this.readUEG();\n\t if (chromaFormatIdc === 3) {\n\t this.skipBits(1); // separate_colour_plane_flag\n\t }\n\t this.skipUEG(); // bit_depth_luma_minus8\n\t this.skipUEG(); // bit_depth_chroma_minus8\n\t this.skipBits(1); // qpprime_y_zero_transform_bypass_flag\n\t if (this.readBoolean()) {\n\t // seq_scaling_matrix_present_flag\n\t scalingListCount = chromaFormatIdc !== 3 ? 8 : 12;\n\t for (i = 0; i < scalingListCount; i++) {\n\t if (this.readBoolean()) {\n\t // seq_scaling_list_present_flag[ i ]\n\t if (i < 6) {\n\t this.skipScalingList(16);\n\t } else {\n\t this.skipScalingList(64);\n\t }\n\t }\n\t }\n\t }\n\t }\n\t this.skipUEG(); // log2_max_frame_num_minus4\n\t var picOrderCntType = this.readUEG();\n\t if (picOrderCntType === 0) {\n\t this.readUEG(); //log2_max_pic_order_cnt_lsb_minus4\n\t } else if (picOrderCntType === 1) {\n\t this.skipBits(1); // delta_pic_order_always_zero_flag\n\t this.skipEG(); // offset_for_non_ref_pic\n\t this.skipEG(); // offset_for_top_to_bottom_field\n\t numRefFramesInPicOrderCntCycle = this.readUEG();\n\t for (i = 0; i < numRefFramesInPicOrderCntCycle; i++) {\n\t this.skipEG(); // offset_for_ref_frame[ i ]\n\t }\n\t }\n\t this.skipUEG(); // max_num_ref_frames\n\t this.skipBits(1); // gaps_in_frame_num_value_allowed_flag\n\t picWidthInMbsMinus1 = this.readUEG();\n\t picHeightInMapUnitsMinus1 = this.readUEG();\n\t frameMbsOnlyFlag = this.readBits(1);\n\t if (frameMbsOnlyFlag === 0) {\n\t this.skipBits(1); // mb_adaptive_frame_field_flag\n\t }\n\t this.skipBits(1); // direct_8x8_inference_flag\n\t if (this.readBoolean()) {\n\t // frame_cropping_flag\n\t frameCropLeftOffset = this.readUEG();\n\t frameCropRightOffset = this.readUEG();\n\t frameCropTopOffset = this.readUEG();\n\t frameCropBottomOffset = this.readUEG();\n\t }\n\t if (this.readBoolean()) {\n\t // vui_parameters_present_flag\n\t if (this.readBoolean()) {\n\t // aspect_ratio_info_present_flag\n\t var sarRatio = void 0;\n\t var aspectRatioIdc = this.readUByte();\n\t switch (aspectRatioIdc) {\n\t case 1:\n\t sarRatio = [1, 1];break;\n\t case 2:\n\t sarRatio = [12, 11];break;\n\t case 3:\n\t sarRatio = [10, 11];break;\n\t case 4:\n\t sarRatio = [16, 11];break;\n\t case 5:\n\t sarRatio = [40, 33];break;\n\t case 6:\n\t sarRatio = [24, 11];break;\n\t case 7:\n\t sarRatio = [20, 11];break;\n\t case 8:\n\t sarRatio = [32, 11];break;\n\t case 9:\n\t sarRatio = [80, 33];break;\n\t case 10:\n\t sarRatio = [18, 11];break;\n\t case 11:\n\t sarRatio = [15, 11];break;\n\t case 12:\n\t sarRatio = [64, 33];break;\n\t case 13:\n\t sarRatio = [160, 99];break;\n\t case 14:\n\t sarRatio = [4, 3];break;\n\t case 15:\n\t sarRatio = [3, 2];break;\n\t case 16:\n\t sarRatio = [2, 1];break;\n\t case 255:\n\t {\n\t sarRatio = [this.readUByte() << 8 | this.readUByte(), this.readUByte() << 8 | this.readUByte()];\n\t break;\n\t }\n\t }\n\t if (sarRatio) {\n\t sarScale = sarRatio[0] / sarRatio[1];\n\t }\n\t }\n\t }\n\t return {\n\t width: Math.ceil(((picWidthInMbsMinus1 + 1) * 16 - frameCropLeftOffset * 2 - frameCropRightOffset * 2) * sarScale),\n\t height: (2 - frameMbsOnlyFlag) * (picHeightInMapUnitsMinus1 + 1) * 16 - (frameMbsOnlyFlag ? 2 : 4) * (frameCropTopOffset + frameCropBottomOffset)\n\t };\n\t }\n\t }, {\n\t key: 'readSliceType',\n\t value: function readSliceType() {\n\t // skip NALu type\n\t this.readUByte();\n\t // discard first_mb_in_slice\n\t this.readUEG();\n\t // return slice_type\n\t return this.readUEG();\n\t }\n\t }]);\n\t\n\t return ExpGolomb;\n\t}();\n\t\n\texports.default = ExpGolomb;\n\t\n\t},{\"43\":43}],22:[function(_dereq_,module,exports){\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t\n\tvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /**\n\t * ID3 parser\n\t */\n\t\n\t\n\tvar _logger = _dereq_(43);\n\t\n\tfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\t\n\t//import Hex from '../utils/hex';\n\t\n\tvar ID3 = function () {\n\t function ID3(data) {\n\t _classCallCheck(this, ID3);\n\t\n\t this._hasTimeStamp = false;\n\t var offset = 0,\n\t byte1,\n\t byte2,\n\t byte3,\n\t byte4,\n\t tagSize,\n\t endPos,\n\t header,\n\t len;\n\t do {\n\t header = this.readUTF(data, offset, 3);\n\t offset += 3;\n\t // first check for ID3 header\n\t if (header === 'ID3') {\n\t // skip 24 bits\n\t offset += 3;\n\t // retrieve tag(s) length\n\t byte1 = data[offset++] & 0x7f;\n\t byte2 = data[offset++] & 0x7f;\n\t byte3 = data[offset++] & 0x7f;\n\t byte4 = data[offset++] & 0x7f;\n\t tagSize = (byte1 << 21) + (byte2 << 14) + (byte3 << 7) + byte4;\n\t endPos = offset + tagSize;\n\t //logger.log(`ID3 tag found, size/end: ${tagSize}/${endPos}`);\n\t\n\t // read ID3 tags\n\t this._parseID3Frames(data, offset, endPos);\n\t offset = endPos;\n\t } else if (header === '3DI') {\n\t // http://id3.org/id3v2.4.0-structure chapter 3.4. ID3v2 footer\n\t offset += 7;\n\t _logger.logger.log('3DI footer found, end: ' + offset);\n\t } else {\n\t offset -= 3;\n\t len = offset;\n\t if (len) {\n\t //logger.log(`ID3 len: ${len}`);\n\t if (!this.hasTimeStamp) {\n\t _logger.logger.warn('ID3 tag found, but no timestamp');\n\t }\n\t this._length = len;\n\t this._payload = data.subarray(0, len);\n\t }\n\t return;\n\t }\n\t } while (true);\n\t }\n\t\n\t _createClass(ID3, [{\n\t key: 'readUTF',\n\t value: function readUTF(data, start, len) {\n\t\n\t var result = '',\n\t offset = start,\n\t end = start + len;\n\t do {\n\t result += String.fromCharCode(data[offset++]);\n\t } while (offset < end);\n\t return result;\n\t }\n\t }, {\n\t key: '_parseID3Frames',\n\t value: function _parseID3Frames(data, offset, endPos) {\n\t var tagId, tagLen, tagStart, tagFlags, timestamp;\n\t while (offset + 8 <= endPos) {\n\t tagId = this.readUTF(data, offset, 4);\n\t offset += 4;\n\t\n\t tagLen = data[offset++] << 24 + data[offset++] << 16 + data[offset++] << 8 + data[offset++];\n\t\n\t tagFlags = data[offset++] << 8 + data[offset++];\n\t\n\t tagStart = offset;\n\t //logger.log(\"ID3 tag id:\" + tagId);\n\t switch (tagId) {\n\t case 'PRIV':\n\t //logger.log('parse frame:' + Hex.hexDump(data.subarray(offset,endPos)));\n\t // owner should be \"com.apple.streaming.transportStreamTimestamp\"\n\t if (this.readUTF(data, offset, 44) === 'com.apple.streaming.transportStreamTimestamp') {\n\t offset += 44;\n\t // smelling even better ! we found the right descriptor\n\t // skip null character (string end) + 3 first bytes\n\t offset += 4;\n\t\n\t // timestamp is 33 bit expressed as a big-endian eight-octet number, with the upper 31 bits set to zero.\n\t var pts33Bit = data[offset++] & 0x1;\n\t this._hasTimeStamp = true;\n\t\n\t timestamp = ((data[offset++] << 23) + (data[offset++] << 15) + (data[offset++] << 7) + data[offset++]) / 45;\n\t\n\t if (pts33Bit) {\n\t timestamp += 47721858.84; // 2^32 / 90\n\t }\n\t timestamp = Math.round(timestamp);\n\t _logger.logger.trace('ID3 timestamp found: ' + timestamp);\n\t this._timeStamp = timestamp;\n\t }\n\t break;\n\t default:\n\t break;\n\t }\n\t }\n\t }\n\t }, {\n\t key: 'hasTimeStamp',\n\t get: function get() {\n\t return this._hasTimeStamp;\n\t }\n\t }, {\n\t key: 'timeStamp',\n\t get: function get() {\n\t return this._timeStamp;\n\t }\n\t }, {\n\t key: 'length',\n\t get: function get() {\n\t return this._length;\n\t }\n\t }, {\n\t key: 'payload',\n\t get: function get() {\n\t return this._payload;\n\t }\n\t }]);\n\t\n\t return ID3;\n\t}();\n\t\n\texports.default = ID3;\n\t\n\t},{\"43\":43}],23:[function(_dereq_,module,exports){\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t\n\tvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /**\n\t * highly optimized TS demuxer:\n\t * parse PAT, PMT\n\t * extract PES packet from audio and video PIDs\n\t * extract AVC/H264 NAL units and AAC/ADTS samples from PES packet\n\t * trigger the remuxer upon parsing completion\n\t * it also tries to workaround as best as it can audio codec switch (HE-AAC to AAC and vice versa), without having to restart the MediaSource.\n\t * it also controls the remuxing process :\n\t * upon discontinuity or level switch detection, it will also notifies the remuxer so that it can reset its state.\n\t */\n\t\n\t// import Hex from '../utils/hex';\n\t\n\t\n\tvar _adts = _dereq_(17);\n\t\n\tvar _adts2 = _interopRequireDefault(_adts);\n\t\n\tvar _events = _dereq_(26);\n\t\n\tvar _events2 = _interopRequireDefault(_events);\n\t\n\tvar _expGolomb = _dereq_(21);\n\t\n\tvar _expGolomb2 = _interopRequireDefault(_expGolomb);\n\t\n\tvar _logger = _dereq_(43);\n\t\n\tvar _errors = _dereq_(24);\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\t\n\tfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\t\n\tvar TSDemuxer = function () {\n\t function TSDemuxer(observer, id, remuxerClass, config) {\n\t _classCallCheck(this, TSDemuxer);\n\t\n\t this.observer = observer;\n\t this.id = id;\n\t this.remuxerClass = remuxerClass;\n\t this.config = config;\n\t this.lastCC = 0;\n\t this.remuxer = new this.remuxerClass(observer, id, config);\n\t }\n\t\n\t _createClass(TSDemuxer, [{\n\t key: 'switchLevel',\n\t value: function switchLevel() {\n\t this.pmtParsed = false;\n\t this._pmtId = -1;\n\t this._avcTrack = { container: 'video/mp2t', type: 'video', id: -1, sequenceNumber: 0, samples: [], len: 0, dropped: 0 };\n\t this._aacTrack = { container: 'video/mp2t', type: 'audio', id: -1, sequenceNumber: 0, samples: [], len: 0 };\n\t this._id3Track = { type: 'id3', id: -1, sequenceNumber: 0, samples: [], len: 0 };\n\t this._txtTrack = { type: 'text', id: -1, sequenceNumber: 0, samples: [], len: 0 };\n\t // flush any partial content\n\t this.aacOverFlow = null;\n\t this.aacLastPTS = null;\n\t this.avcSample = null;\n\t this.remuxer.switchLevel();\n\t }\n\t }, {\n\t key: 'insertDiscontinuity',\n\t value: function insertDiscontinuity() {\n\t this.switchLevel();\n\t this.remuxer.insertDiscontinuity();\n\t }\n\t\n\t // feed incoming data to the front of the parsing pipeline\n\t\n\t }, {\n\t key: 'push',\n\t value: function push(data, audioCodec, videoCodec, timeOffset, cc, level, sn, duration, accurateTimeOffset) {\n\t var start,\n\t len = data.length,\n\t stt,\n\t pid,\n\t atf,\n\t offset,\n\t pes,\n\t codecsOnly = this.remuxer.passthrough,\n\t unknownPIDs = false;\n\t\n\t this.audioCodec = audioCodec;\n\t this.videoCodec = videoCodec;\n\t this._duration = duration;\n\t this.contiguous = false;\n\t this.accurateTimeOffset = accurateTimeOffset;\n\t if (cc !== this.lastCC) {\n\t _logger.logger.log('discontinuity detected');\n\t this.insertDiscontinuity();\n\t this.lastCC = cc;\n\t }\n\t if (level !== this.lastLevel) {\n\t _logger.logger.log('level switch detected');\n\t this.switchLevel();\n\t this.lastLevel = level;\n\t } else if (sn === this.lastSN + 1) {\n\t this.contiguous = true;\n\t }\n\t this.lastSN = sn;\n\t\n\t var pmtParsed = this.pmtParsed,\n\t avcTrack = this._avcTrack,\n\t aacTrack = this._aacTrack,\n\t id3Track = this._id3Track,\n\t avcId = avcTrack.id,\n\t aacId = aacTrack.id,\n\t id3Id = id3Track.id,\n\t pmtId = this._pmtId,\n\t avcData = avcTrack.pesData,\n\t aacData = aacTrack.pesData,\n\t id3Data = id3Track.pesData,\n\t parsePAT = this._parsePAT,\n\t parsePMT = this._parsePMT,\n\t parsePES = this._parsePES,\n\t parseAVCPES = this._parseAVCPES.bind(this),\n\t parseAACPES = this._parseAACPES.bind(this),\n\t parseID3PES = this._parseID3PES.bind(this);\n\t\n\t // don't parse last TS packet if incomplete\n\t len -= len % 188;\n\t // loop through TS packets\n\t for (start = 0; start < len; start += 188) {\n\t if (data[start] === 0x47) {\n\t stt = !!(data[start + 1] & 0x40);\n\t // pid is a 13-bit field starting at the last bit of TS[1]\n\t pid = ((data[start + 1] & 0x1f) << 8) + data[start + 2];\n\t atf = (data[start + 3] & 0x30) >> 4;\n\t // if an adaption field is present, its length is specified by the fifth byte of the TS packet header.\n\t if (atf > 1) {\n\t offset = start + 5 + data[start + 4];\n\t // continue if there is only adaptation field\n\t if (offset === start + 188) {\n\t continue;\n\t }\n\t } else {\n\t offset = start + 4;\n\t }\n\t switch (pid) {\n\t case avcId:\n\t if (stt) {\n\t if (avcData && (pes = parsePES(avcData))) {\n\t parseAVCPES(pes, false);\n\t if (codecsOnly) {\n\t // if we have video codec info AND\n\t // if audio PID is undefined OR if we have audio codec info,\n\t // we have all codec info !\n\t if (avcTrack.codec && (aacId === -1 || aacTrack.codec)) {\n\t this.remux(level, sn, data, timeOffset);\n\t return;\n\t }\n\t }\n\t }\n\t avcData = { data: [], size: 0 };\n\t }\n\t if (avcData) {\n\t avcData.data.push(data.subarray(offset, start + 188));\n\t avcData.size += start + 188 - offset;\n\t }\n\t break;\n\t case aacId:\n\t if (stt) {\n\t if (aacData && (pes = parsePES(aacData))) {\n\t parseAACPES(pes);\n\t if (codecsOnly) {\n\t // here we now that we have audio codec info\n\t // if video PID is undefined OR if we have video codec info,\n\t // we have all codec infos !\n\t if (aacTrack.codec && (avcId === -1 || avcTrack.codec)) {\n\t this.remux(level, sn, data, timeOffset);\n\t return;\n\t }\n\t }\n\t }\n\t aacData = { data: [], size: 0 };\n\t }\n\t if (aacData) {\n\t aacData.data.push(data.subarray(offset, start + 188));\n\t aacData.size += start + 188 - offset;\n\t }\n\t break;\n\t case id3Id:\n\t if (stt) {\n\t if (id3Data && (pes = parsePES(id3Data))) {\n\t parseID3PES(pes);\n\t }\n\t id3Data = { data: [], size: 0 };\n\t }\n\t if (id3Data) {\n\t id3Data.data.push(data.subarray(offset, start + 188));\n\t id3Data.size += start + 188 - offset;\n\t }\n\t break;\n\t case 0:\n\t if (stt) {\n\t offset += data[offset] + 1;\n\t }\n\t pmtId = this._pmtId = parsePAT(data, offset);\n\t break;\n\t case pmtId:\n\t if (stt) {\n\t offset += data[offset] + 1;\n\t }\n\t var parsedPIDs = parsePMT(data, offset);\n\t avcId = avcTrack.id = parsedPIDs.avc;\n\t aacId = aacTrack.id = parsedPIDs.aac;\n\t id3Id = id3Track.id = parsedPIDs.id3;\n\t if (unknownPIDs && !pmtParsed) {\n\t _logger.logger.log('reparse from beginning');\n\t unknownPIDs = false;\n\t // we set it to -188, the += 188 in the for loop will reset start to 0\n\t start = -188;\n\t }\n\t pmtParsed = this.pmtParsed = true;\n\t break;\n\t case 17:\n\t case 0x1fff:\n\t break;\n\t default:\n\t unknownPIDs = true;\n\t break;\n\t }\n\t } else {\n\t this.observer.trigger(_events2.default.ERROR, { type: _errors.ErrorTypes.MEDIA_ERROR, id: this.id, details: _errors.ErrorDetails.FRAG_PARSING_ERROR, fatal: false, reason: 'TS packet did not start with 0x47' });\n\t }\n\t }\n\t // try to parse last PES packets\n\t if (avcData && (pes = parsePES(avcData))) {\n\t parseAVCPES(pes, true);\n\t avcTrack.pesData = null;\n\t } else {\n\t // either avcData null or PES truncated, keep it for next frag parsing\n\t avcTrack.pesData = avcData;\n\t }\n\t\n\t if (aacData && (pes = parsePES(aacData))) {\n\t parseAACPES(pes);\n\t aacTrack.pesData = null;\n\t } else {\n\t if (aacData && aacData.size) {\n\t _logger.logger.log('last AAC PES packet truncated,might overlap between fragments');\n\t }\n\t // either aacData null or PES truncated, keep it for next frag parsing\n\t aacTrack.pesData = aacData;\n\t }\n\t\n\t if (id3Data && (pes = parsePES(id3Data))) {\n\t parseID3PES(pes);\n\t id3Track.pesData = null;\n\t } else {\n\t // either id3Data null or PES truncated, keep it for next frag parsing\n\t id3Track.pesData = id3Data;\n\t }\n\t this.remux(level, sn, null, timeOffset);\n\t }\n\t }, {\n\t key: 'remux',\n\t value: function remux(level, sn, data, timeOffset) {\n\t var avcTrack = this._avcTrack,\n\t samples = avcTrack.samples;\n\t\n\t // compute total/avc sample length and nb of NAL units\n\t var trackData = samples.reduce(function (prevSampleData, curSample) {\n\t var sampleData = curSample.units.units.reduce(function (prevUnitData, curUnit) {\n\t return {\n\t len: prevUnitData.len + curUnit.data.length,\n\t nbNalu: prevUnitData.nbNalu + 1\n\t };\n\t }, { len: 0, nbNalu: 0 });\n\t curSample.length = sampleData.len;\n\t return {\n\t len: prevSampleData.len + sampleData.len,\n\t nbNalu: prevSampleData.nbNalu + sampleData.nbNalu\n\t };\n\t }, { len: 0, nbNalu: 0 });\n\t avcTrack.len = trackData.len;\n\t avcTrack.nbNalu = trackData.nbNalu;\n\t this.remuxer.remux(level, sn, this._aacTrack, this._avcTrack, this._id3Track, this._txtTrack, timeOffset, this.contiguous, this.accurateTimeOffset, data);\n\t }\n\t }, {\n\t key: 'destroy',\n\t value: function destroy() {\n\t this.switchLevel();\n\t this._initPTS = this._initDTS = undefined;\n\t this._duration = 0;\n\t }\n\t }, {\n\t key: '_parsePAT',\n\t value: function _parsePAT(data, offset) {\n\t // skip the PSI header and parse the first PMT entry\n\t return (data[offset + 10] & 0x1F) << 8 | data[offset + 11];\n\t //logger.log('PMT PID:' + this._pmtId);\n\t }\n\t }, {\n\t key: '_parsePMT',\n\t value: function _parsePMT(data, offset) {\n\t var sectionLength,\n\t tableEnd,\n\t programInfoLength,\n\t pid,\n\t result = { aac: -1, avc: -1, id3: -1 };\n\t sectionLength = (data[offset + 1] & 0x0f) << 8 | data[offset + 2];\n\t tableEnd = offset + 3 + sectionLength - 4;\n\t // to determine where the table is, we have to figure out how\n\t // long the program info descriptors are\n\t programInfoLength = (data[offset + 10] & 0x0f) << 8 | data[offset + 11];\n\t // advance the offset to the first entry in the mapping table\n\t offset += 12 + programInfoLength;\n\t while (offset < tableEnd) {\n\t pid = (data[offset + 1] & 0x1F) << 8 | data[offset + 2];\n\t switch (data[offset]) {\n\t // ISO/IEC 13818-7 ADTS AAC (MPEG-2 lower bit-rate audio)\n\t case 0x0f:\n\t //logger.log('AAC PID:' + pid);\n\t if (result.aac === -1) {\n\t result.aac = pid;\n\t }\n\t break;\n\t // Packetized metadata (ID3)\n\t case 0x15:\n\t //logger.log('ID3 PID:' + pid);\n\t if (result.id3 === -1) {\n\t result.id3 = pid;\n\t }\n\t break;\n\t // ITU-T Rec. H.264 and ISO/IEC 14496-10 (lower bit-rate video)\n\t case 0x1b:\n\t //logger.log('AVC PID:' + pid);\n\t if (result.avc === -1) {\n\t result.avc = pid;\n\t }\n\t break;\n\t case 0x24:\n\t _logger.logger.warn('HEVC stream type found, not supported for now');\n\t break;\n\t default:\n\t _logger.logger.log('unkown stream type:' + data[offset]);\n\t break;\n\t }\n\t // move to the next table entry\n\t // skip past the elementary stream descriptors, if present\n\t offset += ((data[offset + 3] & 0x0F) << 8 | data[offset + 4]) + 5;\n\t }\n\t return result;\n\t }\n\t }, {\n\t key: '_parsePES',\n\t value: function _parsePES(stream) {\n\t var i = 0,\n\t frag,\n\t pesFlags,\n\t pesPrefix,\n\t pesLen,\n\t pesHdrLen,\n\t pesData,\n\t pesPts,\n\t pesDts,\n\t payloadStartOffset,\n\t data = stream.data;\n\t // safety check\n\t if (!stream || stream.size === 0) {\n\t return null;\n\t }\n\t\n\t // we might need up to 19 bytes to read PES header\n\t // if first chunk of data is less than 19 bytes, let's merge it with following ones until we get 19 bytes\n\t // usually only one merge is needed (and this is rare ...)\n\t while (data[0].length < 19 && data.length > 1) {\n\t var newData = new Uint8Array(data[0].length + data[1].length);\n\t newData.set(data[0]);\n\t newData.set(data[1], data[0].length);\n\t data[0] = newData;\n\t data.splice(1, 1);\n\t }\n\t //retrieve PTS/DTS from first fragment\n\t frag = data[0];\n\t pesPrefix = (frag[0] << 16) + (frag[1] << 8) + frag[2];\n\t if (pesPrefix === 1) {\n\t pesLen = (frag[4] << 8) + frag[5];\n\t // if PES len is not zero and not matching with total len, stop parsing. PES might be truncated\n\t // minus 6 : PES header size\n\t if (pesLen && pesLen !== stream.size - 6) {\n\t return null;\n\t }\n\t pesFlags = frag[7];\n\t if (pesFlags & 0xC0) {\n\t /* PES header described here : http://dvd.sourceforge.net/dvdinfo/pes-hdr.html\n\t as PTS / DTS is 33 bit we cannot use bitwise operator in JS,\n\t as Bitwise operators treat their operands as a sequence of 32 bits */\n\t pesPts = (frag[9] & 0x0E) * 536870912 + // 1 << 29\n\t (frag[10] & 0xFF) * 4194304 + // 1 << 22\n\t (frag[11] & 0xFE) * 16384 + // 1 << 14\n\t (frag[12] & 0xFF) * 128 + // 1 << 7\n\t (frag[13] & 0xFE) / 2;\n\t // check if greater than 2^32 -1\n\t if (pesPts > 4294967295) {\n\t // decrement 2^33\n\t pesPts -= 8589934592;\n\t }\n\t if (pesFlags & 0x40) {\n\t pesDts = (frag[14] & 0x0E) * 536870912 + // 1 << 29\n\t (frag[15] & 0xFF) * 4194304 + // 1 << 22\n\t (frag[16] & 0xFE) * 16384 + // 1 << 14\n\t (frag[17] & 0xFF) * 128 + // 1 << 7\n\t (frag[18] & 0xFE) / 2;\n\t // check if greater than 2^32 -1\n\t if (pesDts > 4294967295) {\n\t // decrement 2^33\n\t pesDts -= 8589934592;\n\t }\n\t } else {\n\t pesDts = pesPts;\n\t }\n\t }\n\t pesHdrLen = frag[8];\n\t // 9 bytes : 6 bytes for PES header + 3 bytes for PES extension\n\t payloadStartOffset = pesHdrLen + 9;\n\t\n\t stream.size -= payloadStartOffset;\n\t //reassemble PES packet\n\t pesData = new Uint8Array(stream.size);\n\t while (data.length) {\n\t frag = data.shift();\n\t var len = frag.byteLength;\n\t if (payloadStartOffset) {\n\t if (payloadStartOffset > len) {\n\t // trim full frag if PES header bigger than frag\n\t payloadStartOffset -= len;\n\t continue;\n\t } else {\n\t // trim partial frag if PES header smaller than frag\n\t frag = frag.subarray(payloadStartOffset);\n\t len -= payloadStartOffset;\n\t payloadStartOffset = 0;\n\t }\n\t }\n\t pesData.set(frag, i);\n\t i += len;\n\t }\n\t if (pesLen) {\n\t // payload size : remove PES header + PES extension\n\t pesLen -= pesHdrLen + 3;\n\t }\n\t return { data: pesData, pts: pesPts, dts: pesDts, len: pesLen };\n\t } else {\n\t return null;\n\t }\n\t }\n\t }, {\n\t key: 'pushAccesUnit',\n\t value: function pushAccesUnit(avcSample, avcTrack) {\n\t if (avcSample.units.units.length) {\n\t // only push AVC sample if starting with a keyframe is not mandatory OR\n\t // if keyframe already found in this fragment OR\n\t // keyframe found in last fragment (track.sps) AND\n\t // samples already appended (we already found a keyframe in this fragment) OR fragment is contiguous\n\t if (!this.config.forceKeyFrameOnDiscontinuity || avcSample.key === true || avcTrack.sps && (avcTrack.samples.length || this.contiguous)) {\n\t avcTrack.samples.push(avcSample);\n\t } else {\n\t // dropped samples, track it\n\t avcTrack.dropped++;\n\t }\n\t }\n\t if (avcSample.debug.length) {\n\t _logger.logger.log(avcSample.pts + '/' + avcSample.dts + ':' + avcSample.debug + ',' + avcSample.units.length);\n\t }\n\t }\n\t }, {\n\t key: '_parseAVCPES',\n\t value: function _parseAVCPES(pes, last) {\n\t var _this = this;\n\t\n\t //logger.log('parse new PES');\n\t var track = this._avcTrack,\n\t units = this._parseAVCNALu(pes.data),\n\t debug = false,\n\t expGolombDecoder,\n\t avcSample = this.avcSample,\n\t push,\n\t i;\n\t //free pes.data to save up some memory\n\t pes.data = null;\n\t\n\t units.forEach(function (unit) {\n\t switch (unit.type) {\n\t //NDR\n\t case 1:\n\t push = true;\n\t if (debug && avcSample) {\n\t avcSample.debug += 'NDR ';\n\t }\n\t break;\n\t //IDR\n\t case 5:\n\t push = true;\n\t // handle PES not starting with AUD\n\t if (!avcSample) {\n\t avcSample = _this.avcSample = _this._createAVCSample(true, pes.pts, pes.dts, '');\n\t }\n\t if (debug) {\n\t avcSample.debug += 'IDR ';\n\t }\n\t avcSample.key = true;\n\t break;\n\t //SEI\n\t case 6:\n\t push = true;\n\t if (debug && avcSample) {\n\t avcSample.debug += 'SEI ';\n\t }\n\t expGolombDecoder = new _expGolomb2.default(_this.discardEPB(unit.data));\n\t\n\t // skip frameType\n\t expGolombDecoder.readUByte();\n\t\n\t var payloadType = 0;\n\t var payloadSize = 0;\n\t var endOfCaptions = false;\n\t var b = 0;\n\t\n\t while (!endOfCaptions && expGolombDecoder.bytesAvailable > 1) {\n\t payloadType = 0;\n\t do {\n\t b = expGolombDecoder.readUByte();\n\t payloadType += b;\n\t } while (b === 0xFF);\n\t\n\t // Parse payload size.\n\t payloadSize = 0;\n\t do {\n\t b = expGolombDecoder.readUByte();\n\t payloadSize += b;\n\t } while (b === 0xFF);\n\t\n\t // TODO: there can be more than one payload in an SEI packet...\n\t // TODO: need to read type and size in a while loop to get them all\n\t if (payloadType === 4 && expGolombDecoder.bytesAvailable !== 0) {\n\t\n\t endOfCaptions = true;\n\t\n\t var countryCode = expGolombDecoder.readUByte();\n\t\n\t if (countryCode === 181) {\n\t var providerCode = expGolombDecoder.readUShort();\n\t\n\t if (providerCode === 49) {\n\t var userStructure = expGolombDecoder.readUInt();\n\t\n\t if (userStructure === 0x47413934) {\n\t var userDataType = expGolombDecoder.readUByte();\n\t\n\t // Raw CEA-608 bytes wrapped in CEA-708 packet\n\t if (userDataType === 3) {\n\t var firstByte = expGolombDecoder.readUByte();\n\t var secondByte = expGolombDecoder.readUByte();\n\t\n\t var totalCCs = 31 & firstByte;\n\t var byteArray = [firstByte, secondByte];\n\t\n\t for (i = 0; i < totalCCs; i++) {\n\t // 3 bytes per CC\n\t byteArray.push(expGolombDecoder.readUByte());\n\t byteArray.push(expGolombDecoder.readUByte());\n\t byteArray.push(expGolombDecoder.readUByte());\n\t }\n\t\n\t _this._insertSampleInOrder(_this._txtTrack.samples, { type: 3, pts: pes.pts, bytes: byteArray });\n\t }\n\t }\n\t }\n\t }\n\t } else if (payloadSize < expGolombDecoder.bytesAvailable) {\n\t for (i = 0; i < payloadSize; i++) {\n\t expGolombDecoder.readUByte();\n\t }\n\t }\n\t }\n\t break;\n\t //SPS\n\t case 7:\n\t push = true;\n\t if (debug && avcSample) {\n\t avcSample.debug += 'SPS ';\n\t }\n\t if (!track.sps) {\n\t expGolombDecoder = new _expGolomb2.default(unit.data);\n\t var config = expGolombDecoder.readSPS();\n\t track.width = config.width;\n\t track.height = config.height;\n\t track.sps = [unit.data];\n\t track.duration = _this._duration;\n\t var codecarray = unit.data.subarray(1, 4);\n\t var codecstring = 'avc1.';\n\t for (i = 0; i < 3; i++) {\n\t var h = codecarray[i].toString(16);\n\t if (h.length < 2) {\n\t h = '0' + h;\n\t }\n\t codecstring += h;\n\t }\n\t track.codec = codecstring;\n\t }\n\t break;\n\t //PPS\n\t case 8:\n\t push = true;\n\t if (debug && avcSample) {\n\t avcSample.debug += 'PPS ';\n\t }\n\t if (!track.pps) {\n\t track.pps = [unit.data];\n\t }\n\t break;\n\t // AUD\n\t case 9:\n\t push = false;\n\t if (avcSample) {\n\t _this.pushAccesUnit(avcSample, track);\n\t }\n\t avcSample = _this.avcSample = _this._createAVCSample(false, pes.pts, pes.dts, debug ? 'AUD ' : '');\n\t break;\n\t // Filler Data\n\t case 12:\n\t push = false;\n\t break;\n\t default:\n\t push = false;\n\t if (avcSample) {\n\t avcSample.debug += 'unknown NAL ' + unit.type + ' ';\n\t }\n\t break;\n\t }\n\t if (avcSample && push) {\n\t var _units = avcSample.units;\n\t _units.units.push(unit);\n\t }\n\t });\n\t // if last PES packet, push samples\n\t if (last && avcSample) {\n\t this.pushAccesUnit(avcSample, track);\n\t this.avcSample = null;\n\t }\n\t }\n\t }, {\n\t key: '_createAVCSample',\n\t value: function _createAVCSample(key, pts, dts, debug) {\n\t return { key: key, pts: pts, dts: dts, units: { units: [], length: 0 }, debug: debug };\n\t }\n\t }, {\n\t key: '_insertSampleInOrder',\n\t value: function _insertSampleInOrder(arr, data) {\n\t var len = arr.length;\n\t if (len > 0) {\n\t if (data.pts >= arr[len - 1].pts) {\n\t arr.push(data);\n\t } else {\n\t for (var pos = len - 1; pos >= 0; pos--) {\n\t if (data.pts < arr[pos].pts) {\n\t arr.splice(pos, 0, data);\n\t break;\n\t }\n\t }\n\t }\n\t } else {\n\t arr.push(data);\n\t }\n\t }\n\t }, {\n\t key: '_getLastNalUnit',\n\t value: function _getLastNalUnit() {\n\t var avcSample = this.avcSample,\n\t lastUnit = void 0;\n\t // try to fallback to previous sample if current one is empty\n\t if (!avcSample || avcSample.units.units.length === 0) {\n\t var track = this._avcTrack,\n\t samples = track.samples;\n\t avcSample = samples[samples.length - 1];\n\t }\n\t if (avcSample) {\n\t var units = avcSample.units.units;\n\t lastUnit = units[units.length - 1];\n\t }\n\t return lastUnit;\n\t }\n\t }, {\n\t key: '_parseAVCNALu',\n\t value: function _parseAVCNALu(array) {\n\t var i = 0,\n\t len = array.byteLength,\n\t value,\n\t overflow,\n\t track = this._avcTrack,\n\t state = track.naluState || 0,\n\t lastState = state;\n\t var units = [],\n\t unit,\n\t unitType,\n\t lastUnitStart = -1,\n\t lastUnitType;\n\t //logger.log('PES:' + Hex.hexDump(array));\n\t while (i < len) {\n\t value = array[i++];\n\t // finding 3 or 4-byte start codes (00 00 01 OR 00 00 00 01)\n\t switch (state) {\n\t case 0:\n\t if (value === 0) {\n\t state = 1;\n\t }\n\t break;\n\t case 1:\n\t if (value === 0) {\n\t state = 2;\n\t } else {\n\t state = 0;\n\t }\n\t break;\n\t case 2:\n\t case 3:\n\t if (value === 0) {\n\t state = 3;\n\t } else if (value === 1) {\n\t if (lastUnitStart >= 0) {\n\t unit = { data: array.subarray(lastUnitStart, i - state - 1), type: lastUnitType };\n\t //logger.log('pushing NALU, type/size:' + unit.type + '/' + unit.data.byteLength);\n\t units.push(unit);\n\t } else {\n\t // lastUnitStart is undefined => this is the first start code found in this PES packet\n\t // first check if start code delimiter is overlapping between 2 PES packets,\n\t // ie it started in last packet (lastState not zero)\n\t // and ended at the beginning of this PES packet (i <= 4 - lastState)\n\t var lastUnit = this._getLastNalUnit();\n\t if (lastUnit) {\n\t if (lastState && i <= 4 - lastState) {\n\t // start delimiter overlapping between PES packets\n\t // strip start delimiter bytes from the end of last NAL unit\n\t // check if lastUnit had a state different from zero\n\t if (lastUnit.state) {\n\t // strip last bytes\n\t lastUnit.data = lastUnit.data.subarray(0, lastUnit.data.byteLength - lastState);\n\t }\n\t }\n\t // If NAL units are not starting right at the beginning of the PES packet, push preceding data into previous NAL unit.\n\t overflow = i - state - 1;\n\t if (overflow > 0) {\n\t //logger.log('first NALU found with overflow:' + overflow);\n\t var tmp = new Uint8Array(lastUnit.data.byteLength + overflow);\n\t tmp.set(lastUnit.data, 0);\n\t tmp.set(array.subarray(0, overflow), lastUnit.data.byteLength);\n\t lastUnit.data = tmp;\n\t }\n\t }\n\t }\n\t // check if we can read unit type\n\t if (i < len) {\n\t unitType = array[i] & 0x1f;\n\t //logger.log('find NALU @ offset:' + i + ',type:' + unitType);\n\t lastUnitStart = i;\n\t lastUnitType = unitType;\n\t state = 0;\n\t } else {\n\t // not enough byte to read unit type. let's read it on next PES parsing\n\t state = -1;\n\t }\n\t } else {\n\t state = 0;\n\t }\n\t break;\n\t case -1:\n\t // special use case where we found 3 or 4-byte start codes exactly at the end of previous PES packet\n\t lastUnitStart = 0;\n\t // NALu type is value read from offset 0\n\t lastUnitType = value & 0x1f;\n\t state = 0;\n\t break;\n\t default:\n\t break;\n\t }\n\t }\n\t if (lastUnitStart >= 0 && state >= 0) {\n\t unit = { data: array.subarray(lastUnitStart, len), type: lastUnitType, state: state };\n\t units.push(unit);\n\t //logger.log('pushing NALU, type/size/state:' + unit.type + '/' + unit.data.byteLength + '/' + state);\n\t }\n\t // no NALu found\n\t if (units.length === 0) {\n\t // append pes.data to previous NAL unit\n\t var _lastUnit = this._getLastNalUnit();\n\t if (_lastUnit) {\n\t var _tmp = new Uint8Array(_lastUnit.data.byteLength + array.byteLength);\n\t _tmp.set(_lastUnit.data, 0);\n\t _tmp.set(array, _lastUnit.data.byteLength);\n\t _lastUnit.data = _tmp;\n\t }\n\t }\n\t track.naluState = state;\n\t return units;\n\t }\n\t\n\t /**\n\t * remove Emulation Prevention bytes from a RBSP\n\t */\n\t\n\t }, {\n\t key: 'discardEPB',\n\t value: function discardEPB(data) {\n\t var length = data.byteLength,\n\t EPBPositions = [],\n\t i = 1,\n\t newLength,\n\t newData;\n\t\n\t // Find all `Emulation Prevention Bytes`\n\t while (i < length - 2) {\n\t if (data[i] === 0 && data[i + 1] === 0 && data[i + 2] === 0x03) {\n\t EPBPositions.push(i + 2);\n\t i += 2;\n\t } else {\n\t i++;\n\t }\n\t }\n\t\n\t // If no Emulation Prevention Bytes were found just return the original\n\t // array\n\t if (EPBPositions.length === 0) {\n\t return data;\n\t }\n\t\n\t // Create a new array to hold the NAL unit data\n\t newLength = length - EPBPositions.length;\n\t newData = new Uint8Array(newLength);\n\t var sourceIndex = 0;\n\t\n\t for (i = 0; i < newLength; sourceIndex++, i++) {\n\t if (sourceIndex === EPBPositions[0]) {\n\t // Skip this byte\n\t sourceIndex++;\n\t // Remove this position index\n\t EPBPositions.shift();\n\t }\n\t newData[i] = data[sourceIndex];\n\t }\n\t return newData;\n\t }\n\t }, {\n\t key: '_parseAACPES',\n\t value: function _parseAACPES(pes) {\n\t var track = this._aacTrack,\n\t data = pes.data,\n\t pts = pes.pts,\n\t startOffset = 0,\n\t aacOverFlow = this.aacOverFlow,\n\t aacLastPTS = this.aacLastPTS,\n\t config,\n\t frameLength,\n\t frameDuration,\n\t frameIndex,\n\t offset,\n\t headerLength,\n\t stamp,\n\t len,\n\t aacSample;\n\t if (aacOverFlow) {\n\t var tmp = new Uint8Array(aacOverFlow.byteLength + data.byteLength);\n\t tmp.set(aacOverFlow, 0);\n\t tmp.set(data, aacOverFlow.byteLength);\n\t //logger.log(`AAC: append overflowing ${aacOverFlow.byteLength} bytes to beginning of new PES`);\n\t data = tmp;\n\t }\n\t // look for ADTS header (0xFFFx)\n\t for (offset = startOffset, len = data.length; offset < len - 1; offset++) {\n\t if (data[offset] === 0xff && (data[offset + 1] & 0xf0) === 0xf0) {\n\t break;\n\t }\n\t }\n\t // if ADTS header does not start straight from the beginning of the PES payload, raise an error\n\t if (offset) {\n\t var reason, fatal;\n\t if (offset < len - 1) {\n\t reason = 'AAC PES did not start with ADTS header,offset:' + offset;\n\t fatal = false;\n\t } else {\n\t reason = 'no ADTS header found in AAC PES';\n\t fatal = true;\n\t }\n\t _logger.logger.warn('parsing error:' + reason);\n\t this.observer.trigger(_events2.default.ERROR, { type: _errors.ErrorTypes.MEDIA_ERROR, id: this.id, details: _errors.ErrorDetails.FRAG_PARSING_ERROR, fatal: fatal, reason: reason });\n\t if (fatal) {\n\t return;\n\t }\n\t }\n\t if (!track.audiosamplerate) {\n\t config = _adts2.default.getAudioConfig(this.observer, data, offset, this.audioCodec);\n\t track.config = config.config;\n\t track.audiosamplerate = config.samplerate;\n\t track.channelCount = config.channelCount;\n\t track.codec = config.codec;\n\t track.duration = this._duration;\n\t _logger.logger.log('parsed codec:' + track.codec + ',rate:' + config.samplerate + ',nb channel:' + config.channelCount);\n\t }\n\t frameIndex = 0;\n\t frameDuration = 1024 * 90000 / track.audiosamplerate;\n\t\n\t // if last AAC frame is overflowing, we should ensure timestamps are contiguous:\n\t // first sample PTS should be equal to last sample PTS + frameDuration\n\t if (aacOverFlow && aacLastPTS) {\n\t var newPTS = aacLastPTS + frameDuration;\n\t if (Math.abs(newPTS - pts) > 1) {\n\t _logger.logger.log('AAC: align PTS for overlapping frames by ' + Math.round((newPTS - pts) / 90));\n\t pts = newPTS;\n\t }\n\t }\n\t\n\t while (offset + 5 < len) {\n\t // The protection skip bit tells us if we have 2 bytes of CRC data at the end of the ADTS header\n\t headerLength = !!(data[offset + 1] & 0x01) ? 7 : 9;\n\t // retrieve frame size\n\t frameLength = (data[offset + 3] & 0x03) << 11 | data[offset + 4] << 3 | (data[offset + 5] & 0xE0) >>> 5;\n\t frameLength -= headerLength;\n\t //stamp = pes.pts;\n\t\n\t if (frameLength > 0 && offset + headerLength + frameLength <= len) {\n\t stamp = pts + frameIndex * frameDuration;\n\t //logger.log(`AAC frame, offset/length/total/pts:${offset+headerLength}/${frameLength}/${data.byteLength}/${(stamp/90).toFixed(0)}`);\n\t aacSample = { unit: data.subarray(offset + headerLength, offset + headerLength + frameLength), pts: stamp, dts: stamp };\n\t track.samples.push(aacSample);\n\t track.len += frameLength;\n\t offset += frameLength + headerLength;\n\t frameIndex++;\n\t // look for ADTS header (0xFFFx)\n\t for (; offset < len - 1; offset++) {\n\t if (data[offset] === 0xff && (data[offset + 1] & 0xf0) === 0xf0) {\n\t break;\n\t }\n\t }\n\t } else {\n\t break;\n\t }\n\t }\n\t if (offset < len) {\n\t aacOverFlow = data.subarray(offset, len);\n\t //logger.log(`AAC: overflow detected:${len-offset}`);\n\t } else {\n\t aacOverFlow = null;\n\t }\n\t this.aacOverFlow = aacOverFlow;\n\t this.aacLastPTS = stamp;\n\t }\n\t }, {\n\t key: '_parseID3PES',\n\t value: function _parseID3PES(pes) {\n\t this._id3Track.samples.push(pes);\n\t }\n\t }], [{\n\t key: 'probe',\n\t value: function probe(data) {\n\t // a TS fragment should contain at least 3 TS packets, a PAT, a PMT, and one PID, each starting with 0x47\n\t if (data.length >= 3 * 188 && data[0] === 0x47 && data[188] === 0x47 && data[2 * 188] === 0x47) {\n\t return true;\n\t } else {\n\t return false;\n\t }\n\t }\n\t }]);\n\t\n\t return TSDemuxer;\n\t}();\n\t\n\texports.default = TSDemuxer;\n\t\n\t},{\"17\":17,\"21\":21,\"24\":24,\"26\":26,\"43\":43}],24:[function(_dereq_,module,exports){\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\tvar ErrorTypes = exports.ErrorTypes = {\n\t // Identifier for a network error (loading error / timeout ...)\n\t NETWORK_ERROR: 'networkError',\n\t // Identifier for a media Error (video/parsing/mediasource error)\n\t MEDIA_ERROR: 'mediaError',\n\t // Identifier for all other errors\n\t OTHER_ERROR: 'otherError'\n\t};\n\t\n\tvar ErrorDetails = exports.ErrorDetails = {\n\t // Identifier for a manifest load error - data: { url : faulty URL, response : { code: error code, text: error text }}\n\t MANIFEST_LOAD_ERROR: 'manifestLoadError',\n\t // Identifier for a manifest load timeout - data: { url : faulty URL, response : { code: error code, text: error text }}\n\t MANIFEST_LOAD_TIMEOUT: 'manifestLoadTimeOut',\n\t // Identifier for a manifest parsing error - data: { url : faulty URL, reason : error reason}\n\t MANIFEST_PARSING_ERROR: 'manifestParsingError',\n\t // Identifier for a manifest with only incompatible codecs error - data: { url : faulty URL, reason : error reason}\n\t MANIFEST_INCOMPATIBLE_CODECS_ERROR: 'manifestIncompatibleCodecsError',\n\t // Identifier for a level load error - data: { url : faulty URL, response : { code: error code, text: error text }}\n\t LEVEL_LOAD_ERROR: 'levelLoadError',\n\t // Identifier for a level load timeout - data: { url : faulty URL, response : { code: error code, text: error text }}\n\t LEVEL_LOAD_TIMEOUT: 'levelLoadTimeOut',\n\t // Identifier for a level switch error - data: { level : faulty level Id, event : error description}\n\t LEVEL_SWITCH_ERROR: 'levelSwitchError',\n\t // Identifier for an audio track load error - data: { url : faulty URL, response : { code: error code, text: error text }}\n\t AUDIO_TRACK_LOAD_ERROR: 'audioTrackLoadError',\n\t // Identifier for an audio track load timeout - data: { url : faulty URL, response : { code: error code, text: error text }}\n\t AUDIO_TRACK_LOAD_TIMEOUT: 'audioTrackLoadTimeOut',\n\t // Identifier for fragment load error - data: { frag : fragment object, response : { code: error code, text: error text }}\n\t FRAG_LOAD_ERROR: 'fragLoadError',\n\t // Identifier for fragment loop loading error - data: { frag : fragment object}\n\t FRAG_LOOP_LOADING_ERROR: 'fragLoopLoadingError',\n\t // Identifier for fragment load timeout error - data: { frag : fragment object}\n\t FRAG_LOAD_TIMEOUT: 'fragLoadTimeOut',\n\t // Identifier for a fragment decryption error event - data: parsing error description\n\t FRAG_DECRYPT_ERROR: 'fragDecryptError',\n\t // Identifier for a fragment parsing error event - data: parsing error description\n\t FRAG_PARSING_ERROR: 'fragParsingError',\n\t // Identifier for decrypt key load error - data: { frag : fragment object, response : { code: error code, text: error text }}\n\t KEY_LOAD_ERROR: 'keyLoadError',\n\t // Identifier for decrypt key load timeout error - data: { frag : fragment object}\n\t KEY_LOAD_TIMEOUT: 'keyLoadTimeOut',\n\t // Triggered when an exception occurs while adding a sourceBuffer to MediaSource - data : { err : exception , mimeType : mimeType }\n\t BUFFER_ADD_CODEC_ERROR: 'bufferAddCodecError',\n\t // Identifier for a buffer append error - data: append error description\n\t BUFFER_APPEND_ERROR: 'bufferAppendError',\n\t // Identifier for a buffer appending error event - data: appending error description\n\t BUFFER_APPENDING_ERROR: 'bufferAppendingError',\n\t // Identifier for a buffer stalled error event\n\t BUFFER_STALLED_ERROR: 'bufferStalledError',\n\t // Identifier for a buffer full event\n\t BUFFER_FULL_ERROR: 'bufferFullError',\n\t // Identifier for a buffer seek over hole event\n\t BUFFER_SEEK_OVER_HOLE: 'bufferSeekOverHole',\n\t // Identifier for an internal exception happening inside hls.js while handling an event\n\t INTERNAL_EXCEPTION: 'internalException'\n\t};\n\t\n\t},{}],25:[function(_dereq_,module,exports){\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t\n\tvar _typeof = typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol ? \"symbol\" : typeof obj; };\n\t\n\tvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /*\n\t *\n\t * All objects in the event handling chain should inherit from this class\n\t *\n\t */\n\t\n\tvar _logger = _dereq_(43);\n\t\n\tvar _errors = _dereq_(24);\n\t\n\tvar _events = _dereq_(26);\n\t\n\tvar _events2 = _interopRequireDefault(_events);\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\t\n\tfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\t\n\tvar EventHandler = function () {\n\t function EventHandler(hls) {\n\t _classCallCheck(this, EventHandler);\n\t\n\t this.hls = hls;\n\t this.onEvent = this.onEvent.bind(this);\n\t\n\t for (var _len = arguments.length, events = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {\n\t events[_key - 1] = arguments[_key];\n\t }\n\t\n\t this.handledEvents = events;\n\t this.useGenericHandler = true;\n\t\n\t this.registerListeners();\n\t }\n\t\n\t _createClass(EventHandler, [{\n\t key: 'destroy',\n\t value: function destroy() {\n\t this.unregisterListeners();\n\t }\n\t }, {\n\t key: 'isEventHandler',\n\t value: function isEventHandler() {\n\t return _typeof(this.handledEvents) === 'object' && this.handledEvents.length && typeof this.onEvent === 'function';\n\t }\n\t }, {\n\t key: 'registerListeners',\n\t value: function registerListeners() {\n\t if (this.isEventHandler()) {\n\t this.handledEvents.forEach(function (event) {\n\t if (event === 'hlsEventGeneric') {\n\t throw new Error('Forbidden event name: ' + event);\n\t }\n\t this.hls.on(event, this.onEvent);\n\t }.bind(this));\n\t }\n\t }\n\t }, {\n\t key: 'unregisterListeners',\n\t value: function unregisterListeners() {\n\t if (this.isEventHandler()) {\n\t this.handledEvents.forEach(function (event) {\n\t this.hls.off(event, this.onEvent);\n\t }.bind(this));\n\t }\n\t }\n\t\n\t /**\n\t * arguments: event (string), data (any)\n\t */\n\t\n\t }, {\n\t key: 'onEvent',\n\t value: function onEvent(event, data) {\n\t this.onEventGeneric(event, data);\n\t }\n\t }, {\n\t key: 'onEventGeneric',\n\t value: function onEventGeneric(event, data) {\n\t var eventToFunction = function eventToFunction(event, data) {\n\t var funcName = 'on' + event.replace('hls', '');\n\t if (typeof this[funcName] !== 'function') {\n\t throw new Error('Event ' + event + ' has no generic handler in this ' + this.constructor.name + ' class (tried ' + funcName + ')');\n\t }\n\t return this[funcName].bind(this, data);\n\t };\n\t try {\n\t eventToFunction.call(this, event, data).call();\n\t } catch (err) {\n\t _logger.logger.error('internal error happened while processing ' + event + ':' + err.message);\n\t this.hls.trigger(_events2.default.ERROR, { type: _errors.ErrorTypes.OTHER_ERROR, details: _errors.ErrorDetails.INTERNAL_EXCEPTION, fatal: false, event: event, err: err });\n\t }\n\t }\n\t }]);\n\t\n\t return EventHandler;\n\t}();\n\t\n\texports.default = EventHandler;\n\t\n\t},{\"24\":24,\"26\":26,\"43\":43}],26:[function(_dereq_,module,exports){\n\t'use strict';\n\t\n\tmodule.exports = {\n\t // fired before MediaSource is attaching to media element - data: { media }\n\t MEDIA_ATTACHING: 'hlsMediaAttaching',\n\t // fired when MediaSource has been succesfully attached to media element - data: { }\n\t MEDIA_ATTACHED: 'hlsMediaAttached',\n\t // fired before detaching MediaSource from media element - data: { }\n\t MEDIA_DETACHING: 'hlsMediaDetaching',\n\t // fired when MediaSource has been detached from media element - data: { }\n\t MEDIA_DETACHED: 'hlsMediaDetached',\n\t // fired when we buffer is going to be resetted\n\t BUFFER_RESET: 'hlsBufferReset',\n\t // fired when we know about the codecs that we need buffers for to push into - data: {tracks : { container, codec, levelCodec, initSegment, metadata }}\n\t BUFFER_CODECS: 'hlsBufferCodecs',\n\t // fired when sourcebuffers have been created data: { tracks : tracks}\n\t BUFFER_CREATED: 'hlsBufferCreated',\n\t // fired when we append a segment to the buffer - data: { segment: segment object }\n\t BUFFER_APPENDING: 'hlsBufferAppending',\n\t // fired when we are done with appending a media segment to the buffer data : { parent : segment parent that triggered BUFFER_APPENDING }\n\t BUFFER_APPENDED: 'hlsBufferAppended',\n\t // fired when the stream is finished and we want to notify the media buffer that there will be no more data\n\t BUFFER_EOS: 'hlsBufferEos',\n\t // fired when the media buffer should be flushed - data {startOffset, endOffset}\n\t BUFFER_FLUSHING: 'hlsBufferFlushing',\n\t // fired when the media has been flushed\n\t BUFFER_FLUSHED: 'hlsBufferFlushed',\n\t // fired to signal that a manifest loading starts - data: { url : manifestURL}\n\t MANIFEST_LOADING: 'hlsManifestLoading',\n\t // fired after manifest has been loaded - data: { levels : [available quality levels] , audioTracks : [ available audio tracks], url : manifestURL, stats : { trequest, tfirst, tload, mtime}}\n\t MANIFEST_LOADED: 'hlsManifestLoaded',\n\t // fired after manifest has been parsed - data: { levels : [available quality levels] , firstLevel : index of first quality level appearing in Manifest}\n\t MANIFEST_PARSED: 'hlsManifestParsed',\n\t // fired when a level playlist loading starts - data: { url : level URL level : id of level being loaded}\n\t LEVEL_LOADING: 'hlsLevelLoading',\n\t // fired when a level playlist loading finishes - data: { details : levelDetails object, level : id of loaded level, stats : { trequest, tfirst, tload, mtime} }\n\t LEVEL_LOADED: 'hlsLevelLoaded',\n\t // fired when a level's details have been updated based on previous details, after it has been loaded. - data: { details : levelDetails object, level : id of updated level }\n\t LEVEL_UPDATED: 'hlsLevelUpdated',\n\t // fired when a level's PTS information has been updated after parsing a fragment - data: { details : levelDetails object, level : id of updated level, drift: PTS drift observed when parsing last fragment }\n\t LEVEL_PTS_UPDATED: 'hlsLevelPtsUpdated',\n\t // fired when a level switch is requested - data: { level : id of new level }\n\t LEVEL_SWITCH: 'hlsLevelSwitch',\n\t // fired to notify that audio track lists has been updated data: { audioTracks : audioTracks}\n\t AUDIO_TRACKS_UPDATED: 'hlsAudioTracksUpdated',\n\t // fired when an audio track switch occurs - data: { id : audio track id}\n\t AUDIO_TRACK_SWITCH: 'hlsAudioTrackSwitch',\n\t // fired when an audio track loading starts - data: { url : audio track URL id : audio track id}\n\t AUDIO_TRACK_LOADING: 'hlsAudioTrackLoading',\n\t // fired when an audio track loading finishes - data: { details : levelDetails object, id : audio track id, stats : { trequest, tfirst, tload, mtime} }\n\t AUDIO_TRACK_LOADED: 'hlsAudioTrackLoaded',\n\t // fired when a fragment loading starts - data: { frag : fragment object}\n\t FRAG_LOADING: 'hlsFragLoading',\n\t // fired when a fragment loading is progressing - data: { frag : fragment object, { trequest, tfirst, loaded}}\n\t FRAG_LOAD_PROGRESS: 'hlsFragLoadProgress',\n\t // Identifier for fragment load aborting for emergency switch down - data: {frag : fragment object}\n\t FRAG_LOAD_EMERGENCY_ABORTED: 'hlsFragLoadEmergencyAborted',\n\t // fired when a fragment loading is completed - data: { frag : fragment object, payload : fragment payload, stats : { trequest, tfirst, tload, length}}\n\t FRAG_LOADED: 'hlsFragLoaded',\n\t // fired when Init Segment has been extracted from fragment - data: { id : demuxer id, level : levelId, sn : sequence number, moov : moov MP4 box, codecs : codecs found while parsing fragment}\n\t FRAG_PARSING_INIT_SEGMENT: 'hlsFragParsingInitSegment',\n\t // fired when parsing sei text is completed - data: { id : demuxer id, , level : levelId, sn : sequence number, samples : [ sei samples pes ] }\n\t FRAG_PARSING_USERDATA: 'hlsFragParsingUserdata',\n\t // fired when parsing id3 is completed - data: { id : demuxer id, , level : levelId, sn : sequence number, samples : [ id3 samples pes ] }\n\t FRAG_PARSING_METADATA: 'hlsFragParsingMetadata',\n\t // fired when data have been extracted from fragment - data: { id : demuxer id, level : levelId, sn : sequence number, data1 : moof MP4 box or TS fragments, data2 : mdat MP4 box or null}\n\t FRAG_PARSING_DATA: 'hlsFragParsingData',\n\t // fired when fragment parsing is completed - data: { id : demuxer id; level : levelId, sn : sequence number, }\n\t FRAG_PARSED: 'hlsFragParsed',\n\t // fired when fragment remuxed MP4 boxes have all been appended into SourceBuffer - data: { id : demuxer id,frag : fragment object, stats : { trequest, tfirst, tload, tparsed, tbuffered, length} }\n\t FRAG_BUFFERED: 'hlsFragBuffered',\n\t // fired when fragment matching with current media position is changing - data : { id : demuxer id, frag : fragment object }\n\t FRAG_CHANGED: 'hlsFragChanged',\n\t // Identifier for a FPS drop event - data: {curentDropped, currentDecoded, totalDroppedFrames}\n\t FPS_DROP: 'hlsFpsDrop',\n\t //triggered when FPS drop triggers auto level capping - data: {level, droppedlevel}\n\t FPS_DROP_LEVEL_CAPPING: 'hlsFpsDropLevelCapping',\n\t // Identifier for an error event - data: { type : error type, details : error details, fatal : if true, hls.js cannot/will not try to recover, if false, hls.js will try to recover,other error specific data}\n\t ERROR: 'hlsError',\n\t // fired when hls.js instance starts destroying. Different from MEDIA_DETACHED as one could want to detach and reattach a media to the instance of hls.js to handle mid-rolls for example\n\t DESTROYING: 'hlsDestroying',\n\t // fired when a decrypt key loading starts - data: { frag : fragment object}\n\t KEY_LOADING: 'hlsKeyLoading',\n\t // fired when a decrypt key loading is completed - data: { frag : fragment object, payload : key payload, stats : { trequest, tfirst, tload, length}}\n\t KEY_LOADED: 'hlsKeyLoaded',\n\t // fired upon stream controller state transitions - data: {previousState, nextState}\n\t STREAM_STATE_TRANSITION: 'hlsStreamStateTransition'\n\t};\n\t\n\t},{}],27:[function(_dereq_,module,exports){\n\t\"use strict\";\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t\n\tvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\t\n\tfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\t\n\t/**\n\t * AAC helper\n\t */\n\t\n\tvar AAC = function () {\n\t function AAC() {\n\t _classCallCheck(this, AAC);\n\t }\n\t\n\t _createClass(AAC, null, [{\n\t key: \"getSilentFrame\",\n\t value: function getSilentFrame(channelCount) {\n\t if (channelCount === 1) {\n\t return new Uint8Array([0x00, 0xc8, 0x00, 0x80, 0x23, 0x80]);\n\t } else if (channelCount === 2) {\n\t return new Uint8Array([0x21, 0x00, 0x49, 0x90, 0x02, 0x19, 0x00, 0x23, 0x80]);\n\t } else if (channelCount === 3) {\n\t return new Uint8Array([0x00, 0xc8, 0x00, 0x80, 0x20, 0x84, 0x01, 0x26, 0x40, 0x08, 0x64, 0x00, 0x8e]);\n\t } else if (channelCount === 4) {\n\t return new Uint8Array([0x00, 0xc8, 0x00, 0x80, 0x20, 0x84, 0x01, 0x26, 0x40, 0x08, 0x64, 0x00, 0x80, 0x2c, 0x80, 0x08, 0x02, 0x38]);\n\t } else if (channelCount === 5) {\n\t return new Uint8Array([0x00, 0xc8, 0x00, 0x80, 0x20, 0x84, 0x01, 0x26, 0x40, 0x08, 0x64, 0x00, 0x82, 0x30, 0x04, 0x99, 0x00, 0x21, 0x90, 0x02, 0x38]);\n\t } else if (channelCount === 6) {\n\t return new Uint8Array([0x00, 0xc8, 0x00, 0x80, 0x20, 0x84, 0x01, 0x26, 0x40, 0x08, 0x64, 0x00, 0x82, 0x30, 0x04, 0x99, 0x00, 0x21, 0x90, 0x02, 0x00, 0xb2, 0x00, 0x20, 0x08, 0xe0]);\n\t }\n\t return null;\n\t }\n\t }]);\n\t\n\t return AAC;\n\t}();\n\t\n\texports.default = AAC;\n\t\n\t},{}],28:[function(_dereq_,module,exports){\n\t\"use strict\";\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t\n\tvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\t\n\tfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\t\n\t/**\n\t * Buffer Helper class, providing methods dealing buffer length retrieval\n\t*/\n\t\n\tvar BufferHelper = function () {\n\t function BufferHelper() {\n\t _classCallCheck(this, BufferHelper);\n\t }\n\t\n\t _createClass(BufferHelper, null, [{\n\t key: \"isBuffered\",\n\t value: function isBuffered(media, position) {\n\t if (media) {\n\t var buffered = media.buffered;\n\t for (var i = 0; i < buffered.length; i++) {\n\t if (position >= buffered.start(i) && position <= buffered.end(i)) {\n\t return true;\n\t }\n\t }\n\t }\n\t return false;\n\t }\n\t }, {\n\t key: \"bufferInfo\",\n\t value: function bufferInfo(media, pos, maxHoleDuration) {\n\t if (media) {\n\t var vbuffered = media.buffered,\n\t buffered = [],\n\t i;\n\t for (i = 0; i < vbuffered.length; i++) {\n\t buffered.push({ start: vbuffered.start(i), end: vbuffered.end(i) });\n\t }\n\t return this.bufferedInfo(buffered, pos, maxHoleDuration);\n\t } else {\n\t return { len: 0, start: 0, end: 0, nextStart: undefined };\n\t }\n\t }\n\t }, {\n\t key: \"bufferedInfo\",\n\t value: function bufferedInfo(buffered, pos, maxHoleDuration) {\n\t var buffered2 = [],\n\t\n\t // bufferStart and bufferEnd are buffer boundaries around current video position\n\t bufferLen,\n\t bufferStart,\n\t bufferEnd,\n\t bufferStartNext,\n\t i;\n\t // sort on buffer.start/smaller end (IE does not always return sorted buffered range)\n\t buffered.sort(function (a, b) {\n\t var diff = a.start - b.start;\n\t if (diff) {\n\t return diff;\n\t } else {\n\t return b.end - a.end;\n\t }\n\t });\n\t // there might be some small holes between buffer time range\n\t // consider that holes smaller than maxHoleDuration are irrelevant and build another\n\t // buffer time range representations that discards those holes\n\t for (i = 0; i < buffered.length; i++) {\n\t var buf2len = buffered2.length;\n\t if (buf2len) {\n\t var buf2end = buffered2[buf2len - 1].end;\n\t // if small hole (value between 0 or maxHoleDuration ) or overlapping (negative)\n\t if (buffered[i].start - buf2end < maxHoleDuration) {\n\t // merge overlapping time ranges\n\t // update lastRange.end only if smaller than item.end\n\t // e.g. [ 1, 15] with [ 2,8] => [ 1,15] (no need to modify lastRange.end)\n\t // whereas [ 1, 8] with [ 2,15] => [ 1,15] ( lastRange should switch from [1,8] to [1,15])\n\t if (buffered[i].end > buf2end) {\n\t buffered2[buf2len - 1].end = buffered[i].end;\n\t }\n\t } else {\n\t // big hole\n\t buffered2.push(buffered[i]);\n\t }\n\t } else {\n\t // first value\n\t buffered2.push(buffered[i]);\n\t }\n\t }\n\t for (i = 0, bufferLen = 0, bufferStart = bufferEnd = pos; i < buffered2.length; i++) {\n\t var start = buffered2[i].start,\n\t end = buffered2[i].end;\n\t //logger.log('buf start/end:' + buffered.start(i) + '/' + buffered.end(i));\n\t if (pos + maxHoleDuration >= start && pos < end) {\n\t // play position is inside this buffer TimeRange, retrieve end of buffer position and buffer length\n\t bufferStart = start;\n\t bufferEnd = end;\n\t bufferLen = bufferEnd - pos;\n\t } else if (pos + maxHoleDuration < start) {\n\t bufferStartNext = start;\n\t break;\n\t }\n\t }\n\t return { len: bufferLen, start: bufferStart, end: bufferEnd, nextStart: bufferStartNext };\n\t }\n\t }]);\n\t\n\t return BufferHelper;\n\t}();\n\t\n\texports.default = BufferHelper;\n\t\n\t},{}],29:[function(_dereq_,module,exports){\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t\n\tvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /**\n\t * Level Helper class, providing methods dealing with playlist sliding and drift\n\t */\n\t\n\tvar _logger = _dereq_(43);\n\t\n\tfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\t\n\tvar LevelHelper = function () {\n\t function LevelHelper() {\n\t _classCallCheck(this, LevelHelper);\n\t }\n\t\n\t _createClass(LevelHelper, null, [{\n\t key: 'mergeDetails',\n\t value: function mergeDetails(oldDetails, newDetails) {\n\t var start = Math.max(oldDetails.startSN, newDetails.startSN) - newDetails.startSN,\n\t end = Math.min(oldDetails.endSN, newDetails.endSN) - newDetails.startSN,\n\t delta = newDetails.startSN - oldDetails.startSN,\n\t oldfragments = oldDetails.fragments,\n\t newfragments = newDetails.fragments,\n\t ccOffset = 0,\n\t PTSFrag;\n\t\n\t // check if old/new playlists have fragments in common\n\t if (end < start) {\n\t newDetails.PTSKnown = false;\n\t return;\n\t }\n\t // loop through overlapping SN and update startPTS , cc, and duration if any found\n\t for (var i = start; i <= end; i++) {\n\t var oldFrag = oldfragments[delta + i],\n\t newFrag = newfragments[i];\n\t if (newFrag && oldFrag) {\n\t ccOffset = oldFrag.cc - newFrag.cc;\n\t if (!isNaN(oldFrag.startPTS)) {\n\t newFrag.start = newFrag.startPTS = oldFrag.startPTS;\n\t newFrag.endPTS = oldFrag.endPTS;\n\t newFrag.duration = oldFrag.duration;\n\t PTSFrag = newFrag;\n\t }\n\t }\n\t }\n\t\n\t if (ccOffset) {\n\t _logger.logger.log('discontinuity sliding from playlist, take drift into account');\n\t for (i = 0; i < newfragments.length; i++) {\n\t newfragments[i].cc += ccOffset;\n\t }\n\t }\n\t\n\t // if at least one fragment contains PTS info, recompute PTS information for all fragments\n\t if (PTSFrag) {\n\t LevelHelper.updateFragPTSDTS(newDetails, PTSFrag.sn, PTSFrag.startPTS, PTSFrag.endPTS, PTSFrag.startDTS, PTSFrag.endDTS);\n\t } else {\n\t // ensure that delta is within oldfragments range\n\t // also adjust sliding in case delta is 0 (we could have old=[50-60] and new=old=[50-61])\n\t // in that case we also need to adjust start offset of all fragments\n\t if (delta >= 0 && delta < oldfragments.length) {\n\t // adjust start by sliding offset\n\t var sliding = oldfragments[delta].start;\n\t for (i = 0; i < newfragments.length; i++) {\n\t newfragments[i].start += sliding;\n\t }\n\t }\n\t }\n\t // if we are here, it means we have fragments overlapping between\n\t // old and new level. reliable PTS info is thus relying on old level\n\t newDetails.PTSKnown = oldDetails.PTSKnown;\n\t return;\n\t }\n\t }, {\n\t key: 'updateFragPTSDTS',\n\t value: function updateFragPTSDTS(details, sn, startPTS, endPTS, startDTS, endDTS) {\n\t var fragIdx, fragments, frag, i;\n\t // exit if sn out of range\n\t if (sn < details.startSN || sn > details.endSN) {\n\t return 0;\n\t }\n\t fragIdx = sn - details.startSN;\n\t fragments = details.fragments;\n\t frag = fragments[fragIdx];\n\t if (!isNaN(frag.startPTS)) {\n\t // delta PTS between audio and video\n\t var deltaPTS = Math.abs(frag.startPTS - startPTS);\n\t if (isNaN(frag.deltaPTS)) {\n\t frag.deltaPTS = deltaPTS;\n\t } else {\n\t frag.deltaPTS = Math.max(deltaPTS, frag.deltaPTS);\n\t }\n\t startPTS = Math.min(startPTS, frag.startPTS);\n\t endPTS = Math.max(endPTS, frag.endPTS);\n\t startDTS = Math.min(startDTS, frag.startDTS);\n\t endDTS = Math.max(endDTS, frag.endDTS);\n\t }\n\t\n\t var drift = startPTS - frag.start;\n\t\n\t frag.start = frag.startPTS = startPTS;\n\t frag.endPTS = endPTS;\n\t frag.startDTS = startDTS;\n\t frag.endDTS = endDTS;\n\t frag.duration = endPTS - startPTS;\n\t // adjust fragment PTS/duration from seqnum-1 to frag 0\n\t for (i = fragIdx; i > 0; i--) {\n\t LevelHelper.updatePTS(fragments, i, i - 1);\n\t }\n\t\n\t // adjust fragment PTS/duration from seqnum to last frag\n\t for (i = fragIdx; i < fragments.length - 1; i++) {\n\t LevelHelper.updatePTS(fragments, i, i + 1);\n\t }\n\t details.PTSKnown = true;\n\t //logger.log(` frag start/end:${startPTS.toFixed(3)}/${endPTS.toFixed(3)}`);\n\t\n\t return drift;\n\t }\n\t }, {\n\t key: 'updatePTS',\n\t value: function updatePTS(fragments, fromIdx, toIdx) {\n\t var fragFrom = fragments[fromIdx],\n\t fragTo = fragments[toIdx],\n\t fragToPTS = fragTo.startPTS;\n\t // if we know startPTS[toIdx]\n\t if (!isNaN(fragToPTS)) {\n\t // update fragment duration.\n\t // it helps to fix drifts between playlist reported duration and fragment real duration\n\t if (toIdx > fromIdx) {\n\t fragFrom.duration = fragToPTS - fragFrom.start;\n\t if (fragFrom.duration < 0) {\n\t _logger.logger.warn('negative duration computed for frag ' + fragFrom.sn + ',level ' + fragFrom.level + ', there should be some duration drift between playlist and fragment!');\n\t }\n\t } else {\n\t fragTo.duration = fragFrom.start - fragToPTS;\n\t if (fragTo.duration < 0) {\n\t _logger.logger.warn('negative duration computed for frag ' + fragTo.sn + ',level ' + fragTo.level + ', there should be some duration drift between playlist and fragment!');\n\t }\n\t }\n\t } else {\n\t // we dont know startPTS[toIdx]\n\t if (toIdx > fromIdx) {\n\t fragTo.start = fragFrom.start + fragFrom.duration;\n\t } else {\n\t fragTo.start = fragFrom.start - fragTo.duration;\n\t }\n\t }\n\t }\n\t }]);\n\t\n\t return LevelHelper;\n\t}();\n\t\n\texports.default = LevelHelper;\n\t\n\t},{\"43\":43}],30:[function(_dereq_,module,exports){\n\t/**\n\t * HLS interface\n\t */\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t\n\tvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\t//import FetchLoader from './utils/fetch-loader';\n\t\n\t\n\tvar _events = _dereq_(26);\n\t\n\tvar _events2 = _interopRequireDefault(_events);\n\t\n\tvar _errors = _dereq_(24);\n\t\n\tvar _playlistLoader = _dereq_(34);\n\t\n\tvar _playlistLoader2 = _interopRequireDefault(_playlistLoader);\n\t\n\tvar _fragmentLoader = _dereq_(32);\n\t\n\tvar _fragmentLoader2 = _interopRequireDefault(_fragmentLoader);\n\t\n\tvar _abrController = _dereq_(3);\n\t\n\tvar _abrController2 = _interopRequireDefault(_abrController);\n\t\n\tvar _bufferController = _dereq_(6);\n\t\n\tvar _bufferController2 = _interopRequireDefault(_bufferController);\n\t\n\tvar _capLevelController = _dereq_(7);\n\t\n\tvar _capLevelController2 = _interopRequireDefault(_capLevelController);\n\t\n\tvar _audioStreamController = _dereq_(4);\n\t\n\tvar _audioStreamController2 = _interopRequireDefault(_audioStreamController);\n\t\n\tvar _streamController = _dereq_(11);\n\t\n\tvar _streamController2 = _interopRequireDefault(_streamController);\n\t\n\tvar _levelController = _dereq_(10);\n\t\n\tvar _levelController2 = _interopRequireDefault(_levelController);\n\t\n\tvar _timelineController = _dereq_(12);\n\t\n\tvar _timelineController2 = _interopRequireDefault(_timelineController);\n\t\n\tvar _fpsController = _dereq_(9);\n\t\n\tvar _fpsController2 = _interopRequireDefault(_fpsController);\n\t\n\tvar _audioTrackController = _dereq_(5);\n\t\n\tvar _audioTrackController2 = _interopRequireDefault(_audioTrackController);\n\t\n\tvar _logger = _dereq_(43);\n\t\n\tvar _xhrLoader = _dereq_(47);\n\t\n\tvar _xhrLoader2 = _interopRequireDefault(_xhrLoader);\n\t\n\tvar _events3 = _dereq_(1);\n\t\n\tvar _events4 = _interopRequireDefault(_events3);\n\t\n\tvar _keyLoader = _dereq_(33);\n\t\n\tvar _keyLoader2 = _interopRequireDefault(_keyLoader);\n\t\n\tvar _cues = _dereq_(41);\n\t\n\tvar _cues2 = _interopRequireDefault(_cues);\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\t\n\tfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\t\n\tvar Hls = function () {\n\t _createClass(Hls, null, [{\n\t key: 'isSupported',\n\t value: function isSupported() {\n\t return window.MediaSource && typeof window.MediaSource.isTypeSupported === 'function' && window.MediaSource.isTypeSupported('video/mp4; codecs=\"avc1.42E01E,mp4a.40.2\"');\n\t }\n\t }, {\n\t key: 'version',\n\t get: function get() {\n\t // replaced with browserify-versionify transform\n\t return '0.6.7';\n\t }\n\t }, {\n\t key: 'Events',\n\t get: function get() {\n\t return _events2.default;\n\t }\n\t }, {\n\t key: 'ErrorTypes',\n\t get: function get() {\n\t return _errors.ErrorTypes;\n\t }\n\t }, {\n\t key: 'ErrorDetails',\n\t get: function get() {\n\t return _errors.ErrorDetails;\n\t }\n\t }, {\n\t key: 'DefaultConfig',\n\t get: function get() {\n\t if (!Hls.defaultConfig) {\n\t Hls.defaultConfig = {\n\t autoStartLoad: true,\n\t startPosition: -1,\n\t defaultAudioCodec: undefined,\n\t debug: false,\n\t capLevelOnFPSDrop: false,\n\t capLevelToPlayerSize: false,\n\t maxBufferLength: 30,\n\t maxBufferSize: 60 * 1000 * 1000,\n\t maxBufferHole: 0.5,\n\t maxSeekHole: 2,\n\t seekHoleNudgeDuration: 0.01,\n\t stalledInBufferedNudgeThreshold: 10,\n\t maxFragLookUpTolerance: 0.2,\n\t liveSyncDurationCount: 3,\n\t liveMaxLatencyDurationCount: Infinity,\n\t liveSyncDuration: undefined,\n\t liveMaxLatencyDuration: undefined,\n\t maxMaxBufferLength: 600,\n\t enableWorker: true,\n\t enableSoftwareAES: true,\n\t manifestLoadingTimeOut: 10000,\n\t manifestLoadingMaxRetry: 1,\n\t manifestLoadingRetryDelay: 1000,\n\t manifestLoadingMaxRetryTimeout: 64000,\n\t startLevel: undefined,\n\t levelLoadingTimeOut: 10000,\n\t levelLoadingMaxRetry: 4,\n\t levelLoadingRetryDelay: 1000,\n\t levelLoadingMaxRetryTimeout: 64000,\n\t fragLoadingTimeOut: 20000,\n\t fragLoadingMaxRetry: 6,\n\t fragLoadingRetryDelay: 1000,\n\t fragLoadingMaxRetryTimeout: 64000,\n\t fragLoadingLoopThreshold: 3,\n\t startFragPrefetch: false,\n\t fpsDroppedMonitoringPeriod: 5000,\n\t fpsDroppedMonitoringThreshold: 0.2,\n\t appendErrorMaxRetry: 3,\n\t loader: _xhrLoader2.default,\n\t //loader: FetchLoader,\n\t fLoader: undefined,\n\t pLoader: undefined,\n\t xhrSetup: undefined,\n\t fetchSetup: undefined,\n\t abrController: _abrController2.default,\n\t bufferController: _bufferController2.default,\n\t capLevelController: _capLevelController2.default,\n\t fpsController: _fpsController2.default,\n\t streamController: _streamController2.default,\n\t audioStreamController: _audioStreamController2.default,\n\t timelineController: _timelineController2.default,\n\t cueHandler: _cues2.default,\n\t enableCEA708Captions: true,\n\t enableMP2TPassThrough: false,\n\t stretchShortVideoTrack: false,\n\t forceKeyFrameOnDiscontinuity: true,\n\t abrEwmaFastLive: 5,\n\t abrEwmaSlowLive: 9,\n\t abrEwmaFastVoD: 3,\n\t abrEwmaSlowVoD: 9,\n\t abrEwmaDefaultEstimate: 5e5, // 500 kbps\n\t abrBandWidthFactor: 0.8,\n\t abrBandWidthUpFactor: 0.7,\n\t maxStarvationDelay: 4,\n\t maxLoadingDelay: 4,\n\t minAutoBitrate: 0\n\t };\n\t }\n\t return Hls.defaultConfig;\n\t },\n\t set: function set(defaultConfig) {\n\t Hls.defaultConfig = defaultConfig;\n\t }\n\t }]);\n\t\n\t function Hls() {\n\t var config = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];\n\t\n\t _classCallCheck(this, Hls);\n\t\n\t var defaultConfig = Hls.DefaultConfig;\n\t\n\t if ((config.liveSyncDurationCount || config.liveMaxLatencyDurationCount) && (config.liveSyncDuration || config.liveMaxLatencyDuration)) {\n\t throw new Error('Illegal hls.js config: don\\'t mix up liveSyncDurationCount/liveMaxLatencyDurationCount and liveSyncDuration/liveMaxLatencyDuration');\n\t }\n\t\n\t for (var prop in defaultConfig) {\n\t if (prop in config) {\n\t continue;\n\t }\n\t config[prop] = defaultConfig[prop];\n\t }\n\t\n\t if (config.liveMaxLatencyDurationCount !== undefined && config.liveMaxLatencyDurationCount <= config.liveSyncDurationCount) {\n\t throw new Error('Illegal hls.js config: \"liveMaxLatencyDurationCount\" must be gt \"liveSyncDurationCount\"');\n\t }\n\t\n\t if (config.liveMaxLatencyDuration !== undefined && (config.liveMaxLatencyDuration <= config.liveSyncDuration || config.liveSyncDuration === undefined)) {\n\t throw new Error('Illegal hls.js config: \"liveMaxLatencyDuration\" must be gt \"liveSyncDuration\"');\n\t }\n\t\n\t (0, _logger.enableLogs)(config.debug);\n\t this.config = config;\n\t // observer setup\n\t var observer = this.observer = new _events4.default();\n\t observer.trigger = function trigger(event) {\n\t for (var _len = arguments.length, data = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {\n\t data[_key - 1] = arguments[_key];\n\t }\n\t\n\t observer.emit.apply(observer, [event, event].concat(data));\n\t };\n\t\n\t observer.off = function off(event) {\n\t for (var _len2 = arguments.length, data = Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {\n\t data[_key2 - 1] = arguments[_key2];\n\t }\n\t\n\t observer.removeListener.apply(observer, [event].concat(data));\n\t };\n\t this.on = observer.on.bind(observer);\n\t this.off = observer.off.bind(observer);\n\t this.trigger = observer.trigger.bind(observer);\n\t this.playlistLoader = new _playlistLoader2.default(this);\n\t this.fragmentLoader = new _fragmentLoader2.default(this);\n\t this.levelController = new _levelController2.default(this);\n\t this.abrController = new config.abrController(this);\n\t this.bufferController = new config.bufferController(this);\n\t this.capLevelController = new config.capLevelController(this);\n\t this.fpsController = new config.fpsController(this);\n\t this.streamController = new config.streamController(this);\n\t this.audioStreamController = new config.audioStreamController(this);\n\t this.timelineController = new config.timelineController(this);\n\t this.audioTrackController = new _audioTrackController2.default(this);\n\t this.keyLoader = new _keyLoader2.default(this);\n\t }\n\t\n\t _createClass(Hls, [{\n\t key: 'destroy',\n\t value: function destroy() {\n\t _logger.logger.log('destroy');\n\t this.trigger(_events2.default.DESTROYING);\n\t this.detachMedia();\n\t this.playlistLoader.destroy();\n\t this.fragmentLoader.destroy();\n\t this.levelController.destroy();\n\t this.abrController.destroy();\n\t this.bufferController.destroy();\n\t this.capLevelController.destroy();\n\t this.fpsController.destroy();\n\t this.streamController.destroy();\n\t this.audioStreamController.destroy();\n\t this.timelineController.destroy();\n\t this.audioTrackController.destroy();\n\t this.keyLoader.destroy();\n\t this.url = null;\n\t this.observer.removeAllListeners();\n\t }\n\t }, {\n\t key: 'attachMedia',\n\t value: function attachMedia(media) {\n\t _logger.logger.log('attachMedia');\n\t this.media = media;\n\t this.trigger(_events2.default.MEDIA_ATTACHING, { media: media });\n\t }\n\t }, {\n\t key: 'detachMedia',\n\t value: function detachMedia() {\n\t _logger.logger.log('detachMedia');\n\t this.trigger(_events2.default.MEDIA_DETACHING);\n\t this.media = null;\n\t }\n\t }, {\n\t key: 'loadSource',\n\t value: function loadSource(url) {\n\t _logger.logger.log('loadSource:' + url);\n\t this.url = url;\n\t // when attaching to a source URL, trigger a playlist load\n\t this.trigger(_events2.default.MANIFEST_LOADING, { url: url });\n\t }\n\t }, {\n\t key: 'startLoad',\n\t value: function startLoad() {\n\t var startPosition = arguments.length <= 0 || arguments[0] === undefined ? -1 : arguments[0];\n\t\n\t _logger.logger.log('startLoad');\n\t this.levelController.startLoad();\n\t this.streamController.startLoad(startPosition);\n\t this.audioStreamController.startLoad(startPosition);\n\t }\n\t }, {\n\t key: 'stopLoad',\n\t value: function stopLoad() {\n\t _logger.logger.log('stopLoad');\n\t this.levelController.stopLoad();\n\t this.streamController.stopLoad();\n\t this.audioStreamController.stopLoad();\n\t }\n\t }, {\n\t key: 'swapAudioCodec',\n\t value: function swapAudioCodec() {\n\t _logger.logger.log('swapAudioCodec');\n\t this.streamController.swapAudioCodec();\n\t }\n\t }, {\n\t key: 'recoverMediaError',\n\t value: function recoverMediaError() {\n\t _logger.logger.log('recoverMediaError');\n\t var media = this.media;\n\t this.detachMedia();\n\t this.attachMedia(media);\n\t }\n\t\n\t /** Return all quality levels **/\n\t\n\t }, {\n\t key: 'levels',\n\t get: function get() {\n\t return this.levelController.levels;\n\t }\n\t\n\t /** Return current playback quality level **/\n\t\n\t }, {\n\t key: 'currentLevel',\n\t get: function get() {\n\t return this.streamController.currentLevel;\n\t }\n\t\n\t /* set quality level immediately (-1 for automatic level selection) */\n\t ,\n\t set: function set(newLevel) {\n\t _logger.logger.log('set currentLevel:' + newLevel);\n\t this.loadLevel = newLevel;\n\t this.streamController.immediateLevelSwitch();\n\t }\n\t\n\t /** Return next playback quality level (quality level of next fragment) **/\n\t\n\t }, {\n\t key: 'nextLevel',\n\t get: function get() {\n\t return this.streamController.nextLevel;\n\t }\n\t\n\t /* set quality level for next fragment (-1 for automatic level selection) */\n\t ,\n\t set: function set(newLevel) {\n\t _logger.logger.log('set nextLevel:' + newLevel);\n\t this.levelController.manualLevel = newLevel;\n\t this.streamController.nextLevelSwitch();\n\t }\n\t\n\t /** Return the quality level of current/last loaded fragment **/\n\t\n\t }, {\n\t key: 'loadLevel',\n\t get: function get() {\n\t return this.levelController.level;\n\t }\n\t\n\t /* set quality level for current/next loaded fragment (-1 for automatic level selection) */\n\t ,\n\t set: function set(newLevel) {\n\t _logger.logger.log('set loadLevel:' + newLevel);\n\t this.levelController.manualLevel = newLevel;\n\t }\n\t\n\t /** Return the quality level of next loaded fragment **/\n\t\n\t }, {\n\t key: 'nextLoadLevel',\n\t get: function get() {\n\t return this.levelController.nextLoadLevel;\n\t }\n\t\n\t /** set quality level of next loaded fragment **/\n\t ,\n\t set: function set(level) {\n\t this.levelController.nextLoadLevel = level;\n\t }\n\t\n\t /** Return first level (index of first level referenced in manifest)\n\t **/\n\t\n\t }, {\n\t key: 'firstLevel',\n\t get: function get() {\n\t return this.levelController.firstLevel;\n\t }\n\t\n\t /** set first level (index of first level referenced in manifest)\n\t **/\n\t ,\n\t set: function set(newLevel) {\n\t _logger.logger.log('set firstLevel:' + newLevel);\n\t this.levelController.firstLevel = newLevel;\n\t }\n\t\n\t /** Return start level (level of first fragment that will be played back)\n\t if not overrided by user, first level appearing in manifest will be used as start level\n\t if -1 : automatic start level selection, playback will start from level matching download bandwidth (determined from download of first segment)\n\t **/\n\t\n\t }, {\n\t key: 'startLevel',\n\t get: function get() {\n\t return this.levelController.startLevel;\n\t }\n\t\n\t /** set start level (level of first fragment that will be played back)\n\t if not overrided by user, first level appearing in manifest will be used as start level\n\t if -1 : automatic start level selection, playback will start from level matching download bandwidth (determined from download of first segment)\n\t **/\n\t ,\n\t set: function set(newLevel) {\n\t _logger.logger.log('set startLevel:' + newLevel);\n\t this.levelController.startLevel = newLevel;\n\t }\n\t\n\t /** Return the capping/max level value that could be used by automatic level selection algorithm **/\n\t\n\t }, {\n\t key: 'autoLevelCapping',\n\t get: function get() {\n\t return this.abrController.autoLevelCapping;\n\t }\n\t\n\t /** set the capping/max level value that could be used by automatic level selection algorithm **/\n\t ,\n\t set: function set(newLevel) {\n\t _logger.logger.log('set autoLevelCapping:' + newLevel);\n\t this.abrController.autoLevelCapping = newLevel;\n\t }\n\t\n\t /* check if we are in automatic level selection mode */\n\t\n\t }, {\n\t key: 'autoLevelEnabled',\n\t get: function get() {\n\t return this.levelController.manualLevel === -1;\n\t }\n\t\n\t /* return manual level */\n\t\n\t }, {\n\t key: 'manualLevel',\n\t get: function get() {\n\t return this.levelController.manualLevel;\n\t }\n\t\n\t /** get alternate audio tracks list from playlist **/\n\t\n\t }, {\n\t key: 'audioTracks',\n\t get: function get() {\n\t return this.audioTrackController.audioTracks;\n\t }\n\t\n\t /** get index of the selected audio track (index in audio track lists) **/\n\t\n\t }, {\n\t key: 'audioTrack',\n\t get: function get() {\n\t return this.audioTrackController.audioTrack;\n\t }\n\t\n\t /** select an audio track, based on its index in audio track lists**/\n\t ,\n\t set: function set(audioTrackId) {\n\t this.audioTrackController.audioTrack = audioTrackId;\n\t }\n\t }, {\n\t key: 'liveSyncPosition',\n\t get: function get() {\n\t return this.streamController.liveSyncPosition;\n\t }\n\t }]);\n\t\n\t return Hls;\n\t}();\n\t\n\texports.default = Hls;\n\t\n\t},{\"1\":1,\"10\":10,\"11\":11,\"12\":12,\"24\":24,\"26\":26,\"3\":3,\"32\":32,\"33\":33,\"34\":34,\"4\":4,\"41\":41,\"43\":43,\"47\":47,\"5\":5,\"6\":6,\"7\":7,\"9\":9}],31:[function(_dereq_,module,exports){\n\t'use strict';\n\t\n\t// This is mostly for support of the es6 module export\n\t// syntax with the babel compiler, it looks like it doesnt support\n\t// function exports like we are used to in node/commonjs\n\tmodule.exports = _dereq_(30).default;\n\t\n\t},{\"30\":30}],32:[function(_dereq_,module,exports){\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t\n\tvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\t\n\tvar _events = _dereq_(26);\n\t\n\tvar _events2 = _interopRequireDefault(_events);\n\t\n\tvar _eventHandler = _dereq_(25);\n\t\n\tvar _eventHandler2 = _interopRequireDefault(_eventHandler);\n\t\n\tvar _errors = _dereq_(24);\n\t\n\tvar _logger = _dereq_(43);\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\t\n\tfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\t\n\tfunction _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return call && (typeof call === \"object\" || typeof call === \"function\") ? call : self; }\n\t\n\tfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /*\n\t * Fragment Loader\n\t */\n\t\n\tvar FragmentLoader = function (_EventHandler) {\n\t _inherits(FragmentLoader, _EventHandler);\n\t\n\t function FragmentLoader(hls) {\n\t _classCallCheck(this, FragmentLoader);\n\t\n\t var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(FragmentLoader).call(this, hls, _events2.default.FRAG_LOADING));\n\t\n\t _this.loaders = {};\n\t return _this;\n\t }\n\t\n\t _createClass(FragmentLoader, [{\n\t key: 'destroy',\n\t value: function destroy() {\n\t var loaders = this.loaders;\n\t for (var loaderName in loaders) {\n\t var loader = loaders[loaderName];\n\t if (loader) {\n\t loader.destroy();\n\t }\n\t }\n\t this.loaders = {};\n\t _eventHandler2.default.prototype.destroy.call(this);\n\t }\n\t }, {\n\t key: 'onFragLoading',\n\t value: function onFragLoading(data) {\n\t var frag = data.frag,\n\t type = frag.type,\n\t loader = this.loaders[type],\n\t config = this.hls.config;\n\t\n\t frag.loaded = 0;\n\t if (loader) {\n\t _logger.logger.warn('abort previous fragment loader for type:' + type);\n\t loader.abort();\n\t }\n\t loader = this.loaders[type] = frag.loader = typeof config.fLoader !== 'undefined' ? new config.fLoader(config) : new config.loader(config);\n\t\n\t var loaderContext = void 0,\n\t loaderConfig = void 0,\n\t loaderCallbacks = void 0;\n\t loaderContext = { url: frag.url, frag: frag, responseType: 'arraybuffer', progressData: false };\n\t var start = frag.byteRangeStartOffset,\n\t end = frag.byteRangeEndOffset;\n\t if (!isNaN(start) && !isNaN(end)) {\n\t loaderContext.rangeStart = start;\n\t loaderContext.rangeEnd = end;\n\t }\n\t loaderConfig = { timeout: config.fragLoadingTimeOut, maxRetry: 0, retryDelay: 0, maxRetryDelay: config.fragLoadingMaxRetryTimeout };\n\t loaderCallbacks = { onSuccess: this.loadsuccess.bind(this), onError: this.loaderror.bind(this), onTimeout: this.loadtimeout.bind(this), onProgress: this.loadprogress.bind(this) };\n\t loader.load(loaderContext, loaderConfig, loaderCallbacks);\n\t }\n\t }, {\n\t key: 'loadsuccess',\n\t value: function loadsuccess(response, stats, context) {\n\t var payload = response.data,\n\t frag = context.frag;\n\t // detach fragment loader on load success\n\t frag.loader = undefined;\n\t this.loaders[frag.type] = undefined;\n\t this.hls.trigger(_events2.default.FRAG_LOADED, { payload: payload, frag: frag, stats: stats });\n\t }\n\t }, {\n\t key: 'loaderror',\n\t value: function loaderror(response, context) {\n\t var loader = context.loader;\n\t if (loader) {\n\t loader.abort();\n\t }\n\t this.loaders[context.type] = undefined;\n\t this.hls.trigger(_events2.default.ERROR, { type: _errors.ErrorTypes.NETWORK_ERROR, details: _errors.ErrorDetails.FRAG_LOAD_ERROR, fatal: false, frag: context.frag, response: response });\n\t }\n\t }, {\n\t key: 'loadtimeout',\n\t value: function loadtimeout(stats, context) {\n\t var loader = context.loader;\n\t if (loader) {\n\t loader.abort();\n\t }\n\t this.loaders[context.type] = undefined;\n\t this.hls.trigger(_events2.default.ERROR, { type: _errors.ErrorTypes.NETWORK_ERROR, details: _errors.ErrorDetails.FRAG_LOAD_TIMEOUT, fatal: false, frag: context.frag });\n\t }\n\t\n\t // data will be used for progressive parsing\n\t\n\t }, {\n\t key: 'loadprogress',\n\t value: function loadprogress(stats, context, data) {\n\t // jshint ignore:line\n\t var frag = context.frag;\n\t frag.loaded = stats.loaded;\n\t this.hls.trigger(_events2.default.FRAG_LOAD_PROGRESS, { frag: frag, stats: stats });\n\t }\n\t }]);\n\t\n\t return FragmentLoader;\n\t}(_eventHandler2.default);\n\t\n\texports.default = FragmentLoader;\n\t\n\t},{\"24\":24,\"25\":25,\"26\":26,\"43\":43}],33:[function(_dereq_,module,exports){\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t\n\tvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\t\n\tvar _events = _dereq_(26);\n\t\n\tvar _events2 = _interopRequireDefault(_events);\n\t\n\tvar _eventHandler = _dereq_(25);\n\t\n\tvar _eventHandler2 = _interopRequireDefault(_eventHandler);\n\t\n\tvar _errors = _dereq_(24);\n\t\n\tvar _logger = _dereq_(43);\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\t\n\tfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\t\n\tfunction _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return call && (typeof call === \"object\" || typeof call === \"function\") ? call : self; }\n\t\n\tfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /*\n\t * Decrypt key Loader\n\t */\n\t\n\tvar KeyLoader = function (_EventHandler) {\n\t _inherits(KeyLoader, _EventHandler);\n\t\n\t function KeyLoader(hls) {\n\t _classCallCheck(this, KeyLoader);\n\t\n\t var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(KeyLoader).call(this, hls, _events2.default.KEY_LOADING));\n\t\n\t _this.loaders = {};\n\t _this.decryptkey = null;\n\t _this.decrypturl = null;\n\t return _this;\n\t }\n\t\n\t _createClass(KeyLoader, [{\n\t key: 'destroy',\n\t value: function destroy() {\n\t for (var loaderName in this.loaders) {\n\t var loader = this.loaders[loaderName];\n\t if (loader) {\n\t loader.destroy();\n\t }\n\t }\n\t this.loaders = {};\n\t _eventHandler2.default.prototype.destroy.call(this);\n\t }\n\t }, {\n\t key: 'onKeyLoading',\n\t value: function onKeyLoading(data) {\n\t var frag = data.frag,\n\t type = frag.type,\n\t loader = this.loaders[type],\n\t decryptdata = frag.decryptdata,\n\t uri = decryptdata.uri;\n\t // if uri is different from previous one or if decrypt key not retrieved yet\n\t if (uri !== this.decrypturl || this.decryptkey === null) {\n\t var config = this.hls.config;\n\t\n\t if (loader) {\n\t _logger.logger.warn('abort previous fragment loader for type:' + type);\n\t loader.abort();\n\t }\n\t frag.loader = this.loaders[type] = new config.loader(config);\n\t this.decrypturl = uri;\n\t this.decryptkey = null;\n\t\n\t var loaderContext = void 0,\n\t loaderConfig = void 0,\n\t loaderCallbacks = void 0;\n\t loaderContext = { url: uri, frag: frag, responseType: 'arraybuffer' };\n\t loaderConfig = { timeout: config.fragLoadingTimeOut, maxRetry: config.fragLoadingMaxRetry, retryDelay: config.fragLoadingRetryDelay, maxRetryDelay: config.fragLoadingMaxRetryTimeout };\n\t loaderCallbacks = { onSuccess: this.loadsuccess.bind(this), onError: this.loaderror.bind(this), onTimeout: this.loadtimeout.bind(this) };\n\t frag.loader.load(loaderContext, loaderConfig, loaderCallbacks);\n\t } else if (this.decryptkey) {\n\t // we already loaded this key, return it\n\t decryptdata.key = this.decryptkey;\n\t this.hls.trigger(_events2.default.KEY_LOADED, { frag: frag });\n\t }\n\t }\n\t }, {\n\t key: 'loadsuccess',\n\t value: function loadsuccess(response, stats, context) {\n\t var frag = context.frag;\n\t this.decryptkey = frag.decryptdata.key = new Uint8Array(response.data);\n\t // detach fragment loader on load success\n\t frag.loader = undefined;\n\t this.loaders[context.type] = undefined;\n\t this.hls.trigger(_events2.default.KEY_LOADED, { frag: frag });\n\t }\n\t }, {\n\t key: 'loaderror',\n\t value: function loaderror(response, context) {\n\t var frag = context.frag,\n\t loader = frag.loader;\n\t if (loader) {\n\t loader.abort();\n\t }\n\t this.loaders[context.type] = undefined;\n\t this.hls.trigger(_events2.default.ERROR, { type: _errors.ErrorTypes.NETWORK_ERROR, details: _errors.ErrorDetails.KEY_LOAD_ERROR, fatal: false, frag: frag, response: response });\n\t }\n\t }, {\n\t key: 'loadtimeout',\n\t value: function loadtimeout(stats, context) {\n\t var frag = context.frag,\n\t loader = frag.loader;\n\t if (loader) {\n\t loader.abort();\n\t }\n\t this.loaders[context.type] = undefined;\n\t this.hls.trigger(_events2.default.ERROR, { type: _errors.ErrorTypes.NETWORK_ERROR, details: _errors.ErrorDetails.KEY_LOAD_TIMEOUT, fatal: false, frag: frag });\n\t }\n\t }]);\n\t\n\t return KeyLoader;\n\t}(_eventHandler2.default);\n\t\n\texports.default = KeyLoader;\n\t\n\t},{\"24\":24,\"25\":25,\"26\":26,\"43\":43}],34:[function(_dereq_,module,exports){\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t\n\tvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\t\n\tvar _events = _dereq_(26);\n\t\n\tvar _events2 = _interopRequireDefault(_events);\n\t\n\tvar _eventHandler = _dereq_(25);\n\t\n\tvar _eventHandler2 = _interopRequireDefault(_eventHandler);\n\t\n\tvar _errors = _dereq_(24);\n\t\n\tvar _url = _dereq_(46);\n\t\n\tvar _url2 = _interopRequireDefault(_url);\n\t\n\tvar _attrList = _dereq_(38);\n\t\n\tvar _attrList2 = _interopRequireDefault(_attrList);\n\t\n\tvar _logger = _dereq_(43);\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\t\n\tfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\t\n\tfunction _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return call && (typeof call === \"object\" || typeof call === \"function\") ? call : self; }\n\t\n\tfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**\n\t * Playlist Loader\n\t */\n\t\n\tvar PlaylistLoader = function (_EventHandler) {\n\t _inherits(PlaylistLoader, _EventHandler);\n\t\n\t function PlaylistLoader(hls) {\n\t _classCallCheck(this, PlaylistLoader);\n\t\n\t var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(PlaylistLoader).call(this, hls, _events2.default.MANIFEST_LOADING, _events2.default.LEVEL_LOADING, _events2.default.AUDIO_TRACK_LOADING));\n\t\n\t _this.loaders = {};\n\t return _this;\n\t }\n\t\n\t _createClass(PlaylistLoader, [{\n\t key: 'destroy',\n\t value: function destroy() {\n\t for (var loaderName in this.loaders) {\n\t var loader = this.loaders[loaderName];\n\t if (loader) {\n\t loader.destroy();\n\t }\n\t }\n\t this.loaders = {};\n\t _eventHandler2.default.prototype.destroy.call(this);\n\t }\n\t }, {\n\t key: 'onManifestLoading',\n\t value: function onManifestLoading(data) {\n\t this.load(data.url, { type: 'manifest' });\n\t }\n\t }, {\n\t key: 'onLevelLoading',\n\t value: function onLevelLoading(data) {\n\t this.load(data.url, { type: 'level', level: data.level, id: data.id });\n\t }\n\t }, {\n\t key: 'onAudioTrackLoading',\n\t value: function onAudioTrackLoading(data) {\n\t this.load(data.url, { type: 'audioTrack', id: data.id });\n\t }\n\t }, {\n\t key: 'load',\n\t value: function load(url, context) {\n\t var loader = this.loaders[context.type];\n\t if (loader) {\n\t var loaderContext = loader.context;\n\t if (loaderContext && loaderContext.url === url) {\n\t _logger.logger.trace('playlist request ongoing');\n\t return;\n\t } else {\n\t _logger.logger.warn('abort previous loader for type:' + context.type);\n\t loader.abort();\n\t }\n\t }\n\t var config = this.hls.config,\n\t retry = void 0,\n\t timeout = void 0,\n\t retryDelay = void 0,\n\t maxRetryDelay = void 0;\n\t if (context.type === 'manifest') {\n\t retry = config.manifestLoadingMaxRetry;\n\t timeout = config.manifestLoadingTimeOut;\n\t retryDelay = config.manifestLoadingRetryDelay;\n\t maxRetryDelay = config.manifestLoadingMaxRetryTimeOut;\n\t } else {\n\t retry = config.levelLoadingMaxRetry;\n\t timeout = config.levelLoadingTimeOut;\n\t retryDelay = config.levelLoadingRetryDelay;\n\t maxRetryDelay = config.levelLoadingMaxRetryTimeOut;\n\t _logger.logger.log('loading playlist for level ' + context.level);\n\t }\n\t loader = this.loaders[context.type] = context.loader = typeof config.pLoader !== 'undefined' ? new config.pLoader(config) : new config.loader(config);\n\t context.url = url;\n\t context.responseType = '';\n\t\n\t var loaderConfig = void 0,\n\t loaderCallbacks = void 0;\n\t loaderConfig = { timeout: timeout, maxRetry: retry, retryDelay: retryDelay, maxRetryDelay: maxRetryDelay };\n\t loaderCallbacks = { onSuccess: this.loadsuccess.bind(this), onError: this.loaderror.bind(this), onTimeout: this.loadtimeout.bind(this) };\n\t loader.load(context, loaderConfig, loaderCallbacks);\n\t }\n\t }, {\n\t key: 'resolve',\n\t value: function resolve(url, baseUrl) {\n\t return _url2.default.buildAbsoluteURL(baseUrl, url);\n\t }\n\t }, {\n\t key: 'parseMasterPlaylist',\n\t value: function parseMasterPlaylist(string, baseurl) {\n\t var levels = [],\n\t result = void 0;\n\t\n\t // https://regex101.com is your friend\n\t var re = /#EXT-X-STREAM-INF:([^\\n\\r]*)[\\r\\n]+([^\\r\\n]+)/g;\n\t while ((result = re.exec(string)) != null) {\n\t var level = {};\n\t\n\t var attrs = level.attrs = new _attrList2.default(result[1]);\n\t level.url = this.resolve(result[2], baseurl);\n\t\n\t var resolution = attrs.decimalResolution('RESOLUTION');\n\t if (resolution) {\n\t level.width = resolution.width;\n\t level.height = resolution.height;\n\t }\n\t level.bitrate = attrs.decimalInteger('AVERAGE-BANDWIDTH') || attrs.decimalInteger('BANDWIDTH');\n\t level.name = attrs.NAME;\n\t\n\t var codecs = attrs.CODECS;\n\t if (codecs) {\n\t codecs = codecs.split(',');\n\t for (var i = 0; i < codecs.length; i++) {\n\t var codec = codecs[i];\n\t if (codec.indexOf('avc1') !== -1) {\n\t level.videoCodec = this.avc1toavcoti(codec);\n\t } else {\n\t level.audioCodec = codec;\n\t }\n\t }\n\t }\n\t\n\t levels.push(level);\n\t }\n\t return levels;\n\t }\n\t }, {\n\t key: 'parseMasterPlaylistMedia',\n\t value: function parseMasterPlaylistMedia(string, baseurl, type) {\n\t var result = void 0,\n\t medias = [];\n\t\n\t // https://regex101.com is your friend\n\t var re = /#EXT-X-MEDIA:(.*)/g;\n\t while ((result = re.exec(string)) != null) {\n\t var media = {};\n\t var attrs = new _attrList2.default(result[1]);\n\t if (attrs.TYPE === type) {\n\t media.groupId = attrs['GROUP-ID'];\n\t media.name = attrs.NAME;\n\t media.type = type;\n\t media.default = attrs.DEFAULT === 'YES';\n\t media.autoselect = attrs.AUTOSELECT === 'YES';\n\t media.forced = attrs.FORCED === 'YES';\n\t if (attrs.URI) {\n\t media.url = this.resolve(attrs.URI, baseurl);\n\t }\n\t media.lang = attrs.LANGUAGE;\n\t if (!media.name) {\n\t media.name = media.lang;\n\t }\n\t medias.push(media);\n\t }\n\t }\n\t return medias;\n\t }\n\t /**\n\t * Utility method for parseLevelPlaylist to create an initialization vector for a given segment\n\t * @returns {Uint8Array}\n\t */\n\t\n\t }, {\n\t key: 'createInitializationVector',\n\t value: function createInitializationVector(segmentNumber) {\n\t var uint8View = new Uint8Array(16);\n\t\n\t for (var i = 12; i < 16; i++) {\n\t uint8View[i] = segmentNumber >> 8 * (15 - i) & 0xff;\n\t }\n\t\n\t return uint8View;\n\t }\n\t\n\t /**\n\t * Utility method for parseLevelPlaylist to get a fragment's decryption data from the currently parsed encryption key data\n\t * @param levelkey - a playlist's encryption info\n\t * @param segmentNumber - the fragment's segment number\n\t * @returns {*} - an object to be applied as a fragment's decryptdata\n\t */\n\t\n\t }, {\n\t key: 'fragmentDecryptdataFromLevelkey',\n\t value: function fragmentDecryptdataFromLevelkey(levelkey, segmentNumber) {\n\t var decryptdata = levelkey;\n\t\n\t if (levelkey && levelkey.method && levelkey.uri && !levelkey.iv) {\n\t decryptdata = this.cloneObj(levelkey);\n\t decryptdata.iv = this.createInitializationVector(segmentNumber);\n\t }\n\t\n\t return decryptdata;\n\t }\n\t }, {\n\t key: 'avc1toavcoti',\n\t value: function avc1toavcoti(codec) {\n\t var result,\n\t avcdata = codec.split('.');\n\t if (avcdata.length > 2) {\n\t result = avcdata.shift() + '.';\n\t result += parseInt(avcdata.shift()).toString(16);\n\t result += ('000' + parseInt(avcdata.shift()).toString(16)).substr(-4);\n\t } else {\n\t result = codec;\n\t }\n\t return result;\n\t }\n\t }, {\n\t key: 'cloneObj',\n\t value: function cloneObj(obj) {\n\t return JSON.parse(JSON.stringify(obj));\n\t }\n\t }, {\n\t key: 'parseLevelPlaylist',\n\t value: function parseLevelPlaylist(string, baseurl, id, type) {\n\t var currentSN = 0,\n\t fragdecryptdata,\n\t totalduration = 0,\n\t level = { type: null, version: null, url: baseurl, fragments: [], live: true, startSN: 0 },\n\t levelkey = { method: null, key: null, iv: null, uri: null },\n\t cc = 0,\n\t programDateTime = null,\n\t frag = null,\n\t result,\n\t regexp,\n\t duration = null,\n\t title = null,\n\t byteRangeEndOffset = null,\n\t byteRangeStartOffset = null,\n\t tagList = [];\n\t\n\t regexp = /(?:(?:#(EXTM3U))|(?:#EXT-X-(PLAYLIST-TYPE):(.+))|(?:#EXT-X-(MEDIA-SEQUENCE):(\\d+))|(?:#EXT-X-(TARGETDURATION):(\\d+))|(?:#EXT-X-(KEY):(.+))|(?:#EXT-X-(START):(.+))|(?:#EXT(INF):(\\d+(?:\\.\\d+)?)(?:,(.*))?)|(?:(?!#)()(\\S.+))|(?:#EXT-X-(BYTERANGE):(\\d+(?:@\\d+(?:\\.\\d+)?)?)|(?:#EXT-X-(ENDLIST))|(?:#EXT-X-(DIS)CONTINUITY))|(?:#EXT-X-(PROGRAM-DATE-TIME):(.+))|(?:#EXT-X-(VERSION):(\\d+))|(?:(#)(.*):(.*))|(?:(#)(.*)))(?:.*)\\r?\\n?/g;\n\t while ((result = regexp.exec(string)) !== null) {\n\t result.shift();\n\t result = result.filter(function (n) {\n\t return n !== undefined;\n\t });\n\t switch (result[0]) {\n\t case 'PLAYLIST-TYPE':\n\t level.type = result[1].toUpperCase();\n\t break;\n\t case 'MEDIA-SEQUENCE':\n\t currentSN = level.startSN = parseInt(result[1]);\n\t break;\n\t case 'TARGETDURATION':\n\t level.targetduration = parseFloat(result[1]);\n\t break;\n\t case 'VERSION':\n\t level.version = parseInt(result[1]);\n\t break;\n\t case 'EXTM3U':\n\t break;\n\t case 'ENDLIST':\n\t level.live = false;\n\t break;\n\t case 'DIS':\n\t cc++;\n\t tagList.push(result);\n\t break;\n\t case 'BYTERANGE':\n\t var params = result[1].split('@');\n\t if (params.length === 1) {\n\t byteRangeStartOffset = byteRangeEndOffset;\n\t } else {\n\t byteRangeStartOffset = parseInt(params[1]);\n\t }\n\t byteRangeEndOffset = parseInt(params[0]) + byteRangeStartOffset;\n\t break;\n\t case 'INF':\n\t duration = parseFloat(result[1]);\n\t title = result[2] ? result[2] : null;\n\t tagList.push(result);\n\t break;\n\t case '':\n\t // url\n\t if (!isNaN(duration)) {\n\t var sn = currentSN++;\n\t fragdecryptdata = this.fragmentDecryptdataFromLevelkey(levelkey, sn);\n\t var url = result[1] ? this.resolve(result[1], baseurl) : null;\n\t frag = { url: url,\n\t type: type,\n\t duration: duration,\n\t title: title,\n\t start: totalduration,\n\t sn: sn,\n\t level: id,\n\t cc: cc,\n\t decryptdata: fragdecryptdata,\n\t programDateTime: programDateTime,\n\t tagList: tagList };\n\t // only include byte range options if used/needed\n\t if (byteRangeStartOffset !== null) {\n\t frag.byteRangeStartOffset = byteRangeStartOffset;\n\t frag.byteRangeEndOffset = byteRangeEndOffset;\n\t }\n\t level.fragments.push(frag);\n\t totalduration += duration;\n\t duration = null;\n\t title = null;\n\t byteRangeStartOffset = null;\n\t programDateTime = null;\n\t tagList = [];\n\t }\n\t break;\n\t case 'KEY':\n\t // https://tools.ietf.org/html/draft-pantos-http-live-streaming-08#section-3.4.4\n\t var decryptparams = result[1];\n\t var keyAttrs = new _attrList2.default(decryptparams);\n\t var decryptmethod = keyAttrs.enumeratedString('METHOD'),\n\t decrypturi = keyAttrs.URI,\n\t decryptiv = keyAttrs.hexadecimalInteger('IV');\n\t if (decryptmethod) {\n\t levelkey = { method: null, key: null, iv: null, uri: null };\n\t if (decrypturi && decryptmethod === 'AES-128') {\n\t levelkey.method = decryptmethod;\n\t // URI to get the key\n\t levelkey.uri = this.resolve(decrypturi, baseurl);\n\t levelkey.key = null;\n\t // Initialization Vector (IV)\n\t levelkey.iv = decryptiv;\n\t }\n\t }\n\t break;\n\t case 'START':\n\t var startParams = result[1];\n\t var startAttrs = new _attrList2.default(startParams);\n\t var startTimeOffset = startAttrs.decimalFloatingPoint('TIME-OFFSET');\n\t //TIME-OFFSET can be 0\n\t if (!isNaN(startTimeOffset)) {\n\t level.startTimeOffset = startTimeOffset;\n\t }\n\t break;\n\t case 'PROGRAM-DATE-TIME':\n\t programDateTime = new Date(Date.parse(result[1]));\n\t tagList.push(result);\n\t break;\n\t case '#':\n\t result.shift();\n\t tagList.push(result);\n\t break;\n\t default:\n\t _logger.logger.warn('line parsed but not handled: ' + result);\n\t break;\n\t }\n\t }\n\t //logger.log('found ' + level.fragments.length + ' fragments');\n\t if (frag && !frag.url) {\n\t level.fragments.pop();\n\t totalduration -= frag.duration;\n\t }\n\t level.totalduration = totalduration;\n\t level.averagetargetduration = totalduration / level.fragments.length;\n\t level.endSN = currentSN - 1;\n\t return level;\n\t }\n\t }, {\n\t key: 'loadsuccess',\n\t value: function loadsuccess(response, stats, context) {\n\t var string = response.data,\n\t url = response.url,\n\t type = context.type,\n\t id = context.id,\n\t level = context.level,\n\t hls = this.hls;\n\t\n\t this.loaders[type] = undefined;\n\t // responseURL not supported on some browsers (it is used to detect URL redirection)\n\t // data-uri mode also not supported (but no need to detect redirection)\n\t if (url === undefined || url.indexOf('data:') === 0) {\n\t // fallback to initial URL\n\t url = context.url;\n\t }\n\t stats.tload = performance.now();\n\t //stats.mtime = new Date(target.getResponseHeader('Last-Modified'));\n\t if (string.indexOf('#EXTM3U') === 0) {\n\t if (string.indexOf('#EXTINF:') > 0) {\n\t var isLevel = type !== 'audioTrack',\n\t levelDetails = this.parseLevelPlaylist(string, url, (isLevel ? level : id) || 0, isLevel ? 'main' : 'audio');\n\t if (type === 'manifest') {\n\t // first request, stream manifest (no master playlist), fire manifest loaded event with level details\n\t hls.trigger(_events2.default.MANIFEST_LOADED, { levels: [{ url: url, details: levelDetails }], audioTracks: [], url: url, stats: stats });\n\t }\n\t stats.tparsed = performance.now();\n\t if (isLevel) {\n\t hls.trigger(_events2.default.LEVEL_LOADED, { details: levelDetails, level: level || 0, id: id || 0, stats: stats });\n\t } else {\n\t hls.trigger(_events2.default.AUDIO_TRACK_LOADED, { details: levelDetails, id: id, stats: stats });\n\t }\n\t } else {\n\t var levels = this.parseMasterPlaylist(string, url);\n\t // multi level playlist, parse level info\n\t if (levels.length) {\n\t var audiotracks = this.parseMasterPlaylistMedia(string, url, 'AUDIO');\n\t if (audiotracks.length) {\n\t // check if we have found an audio track embedded in main playlist (audio track without URI attribute)\n\t var embeddedAudioFound = false;\n\t audiotracks.forEach(function (audioTrack) {\n\t if (!audioTrack.url) {\n\t embeddedAudioFound = true;\n\t }\n\t });\n\t // if no embedded audio track defined, but audio codec signaled in quality level, we need to signal this main audio track\n\t // this could happen with playlists with alt audio rendition in which quality levels (main) contains both audio+video. but with mixed audio track not signaled\n\t if (embeddedAudioFound === false && levels[0].audioCodec && !levels[0].attrs.AUDIO) {\n\t _logger.logger.log('audio codec signaled in quality level, but no embedded audio track signaled, create one');\n\t audiotracks.unshift({ type: 'main', name: 'main' });\n\t }\n\t }\n\t hls.trigger(_events2.default.MANIFEST_LOADED, { levels: levels, audioTracks: audiotracks, url: url, stats: stats });\n\t } else {\n\t hls.trigger(_events2.default.ERROR, { type: _errors.ErrorTypes.NETWORK_ERROR, details: _errors.ErrorDetails.MANIFEST_PARSING_ERROR, fatal: true, url: url, reason: 'no level found in manifest' });\n\t }\n\t }\n\t } else {\n\t hls.trigger(_events2.default.ERROR, { type: _errors.ErrorTypes.NETWORK_ERROR, details: _errors.ErrorDetails.MANIFEST_PARSING_ERROR, fatal: true, url: url, reason: 'no EXTM3U delimiter' });\n\t }\n\t }\n\t }, {\n\t key: 'loaderror',\n\t value: function loaderror(response, context) {\n\t var details,\n\t fatal,\n\t loader = context.loader;\n\t switch (context.type) {\n\t case 'manifest':\n\t details = _errors.ErrorDetails.MANIFEST_LOAD_ERROR;\n\t fatal = true;\n\t break;\n\t case 'level':\n\t details = _errors.ErrorDetails.LEVEL_LOAD_ERROR;\n\t fatal = false;\n\t break;\n\t case 'audioTrack':\n\t details = _errors.ErrorDetails.AUDIO_TRACK_LOAD_ERROR;\n\t fatal = false;\n\t break;\n\t }\n\t if (loader) {\n\t loader.abort();\n\t this.loaders[context.type] = undefined;\n\t }\n\t this.hls.trigger(_events2.default.ERROR, { type: _errors.ErrorTypes.NETWORK_ERROR, details: details, fatal: fatal, url: loader.url, loader: loader, response: response, context: context });\n\t }\n\t }, {\n\t key: 'loadtimeout',\n\t value: function loadtimeout(stats, context) {\n\t var details,\n\t fatal,\n\t loader = context.loader;\n\t switch (context.type) {\n\t case 'manifest':\n\t details = _errors.ErrorDetails.MANIFEST_LOAD_TIMEOUT;\n\t fatal = true;\n\t break;\n\t case 'level':\n\t details = _errors.ErrorDetails.LEVEL_LOAD_TIMEOUT;\n\t fatal = false;\n\t break;\n\t case 'audioTrack':\n\t details = _errors.ErrorDetails.AUDIO_TRACK_LOAD_TIMEOUT;\n\t fatal = false;\n\t break;\n\t }\n\t if (loader) {\n\t loader.abort();\n\t this.loaders[context.type] = undefined;\n\t }\n\t this.hls.trigger(_events2.default.ERROR, { type: _errors.ErrorTypes.NETWORK_ERROR, details: details, fatal: fatal, url: loader.url, loader: loader, context: context });\n\t }\n\t }]);\n\t\n\t return PlaylistLoader;\n\t}(_eventHandler2.default);\n\t\n\texports.default = PlaylistLoader;\n\t\n\t},{\"24\":24,\"25\":25,\"26\":26,\"38\":38,\"43\":43,\"46\":46}],35:[function(_dereq_,module,exports){\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t\n\tvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\t\n\tfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\t\n\t/**\n\t * Generate MP4 Box\n\t*/\n\t\n\t//import Hex from '../utils/hex';\n\t\n\tvar MP4 = function () {\n\t function MP4() {\n\t _classCallCheck(this, MP4);\n\t }\n\t\n\t _createClass(MP4, null, [{\n\t key: 'init',\n\t value: function init() {\n\t MP4.types = {\n\t avc1: [], // codingname\n\t avcC: [],\n\t btrt: [],\n\t dinf: [],\n\t dref: [],\n\t esds: [],\n\t ftyp: [],\n\t hdlr: [],\n\t mdat: [],\n\t mdhd: [],\n\t mdia: [],\n\t mfhd: [],\n\t minf: [],\n\t moof: [],\n\t moov: [],\n\t mp4a: [],\n\t mvex: [],\n\t mvhd: [],\n\t sdtp: [],\n\t stbl: [],\n\t stco: [],\n\t stsc: [],\n\t stsd: [],\n\t stsz: [],\n\t stts: [],\n\t tfdt: [],\n\t tfhd: [],\n\t traf: [],\n\t trak: [],\n\t trun: [],\n\t trex: [],\n\t tkhd: [],\n\t vmhd: [],\n\t smhd: []\n\t };\n\t\n\t var i;\n\t for (i in MP4.types) {\n\t if (MP4.types.hasOwnProperty(i)) {\n\t MP4.types[i] = [i.charCodeAt(0), i.charCodeAt(1), i.charCodeAt(2), i.charCodeAt(3)];\n\t }\n\t }\n\t\n\t var videoHdlr = new Uint8Array([0x00, // version 0\n\t 0x00, 0x00, 0x00, // flags\n\t 0x00, 0x00, 0x00, 0x00, // pre_defined\n\t 0x76, 0x69, 0x64, 0x65, // handler_type: 'vide'\n\t 0x00, 0x00, 0x00, 0x00, // reserved\n\t 0x00, 0x00, 0x00, 0x00, // reserved\n\t 0x00, 0x00, 0x00, 0x00, // reserved\n\t 0x56, 0x69, 0x64, 0x65, 0x6f, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x00 // name: 'VideoHandler'\n\t ]);\n\t\n\t var audioHdlr = new Uint8Array([0x00, // version 0\n\t 0x00, 0x00, 0x00, // flags\n\t 0x00, 0x00, 0x00, 0x00, // pre_defined\n\t 0x73, 0x6f, 0x75, 0x6e, // handler_type: 'soun'\n\t 0x00, 0x00, 0x00, 0x00, // reserved\n\t 0x00, 0x00, 0x00, 0x00, // reserved\n\t 0x00, 0x00, 0x00, 0x00, // reserved\n\t 0x53, 0x6f, 0x75, 0x6e, 0x64, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x00 // name: 'SoundHandler'\n\t ]);\n\t\n\t MP4.HDLR_TYPES = {\n\t 'video': videoHdlr,\n\t 'audio': audioHdlr\n\t };\n\t\n\t var dref = new Uint8Array([0x00, // version 0\n\t 0x00, 0x00, 0x00, // flags\n\t 0x00, 0x00, 0x00, 0x01, // entry_count\n\t 0x00, 0x00, 0x00, 0x0c, // entry_size\n\t 0x75, 0x72, 0x6c, 0x20, // 'url' type\n\t 0x00, // version 0\n\t 0x00, 0x00, 0x01 // entry_flags\n\t ]);\n\t\n\t var stco = new Uint8Array([0x00, // version\n\t 0x00, 0x00, 0x00, // flags\n\t 0x00, 0x00, 0x00, 0x00 // entry_count\n\t ]);\n\t\n\t MP4.STTS = MP4.STSC = MP4.STCO = stco;\n\t\n\t MP4.STSZ = new Uint8Array([0x00, // version\n\t 0x00, 0x00, 0x00, // flags\n\t 0x00, 0x00, 0x00, 0x00, // sample_size\n\t 0x00, 0x00, 0x00, 0x00]);\n\t // sample_count\n\t MP4.VMHD = new Uint8Array([0x00, // version\n\t 0x00, 0x00, 0x01, // flags\n\t 0x00, 0x00, // graphicsmode\n\t 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // opcolor\n\t ]);\n\t MP4.SMHD = new Uint8Array([0x00, // version\n\t 0x00, 0x00, 0x00, // flags\n\t 0x00, 0x00, // balance\n\t 0x00, 0x00 // reserved\n\t ]);\n\t\n\t MP4.STSD = new Uint8Array([0x00, // version 0\n\t 0x00, 0x00, 0x00, // flags\n\t 0x00, 0x00, 0x00, 0x01]); // entry_count\n\t\n\t var majorBrand = new Uint8Array([105, 115, 111, 109]); // isom\n\t var avc1Brand = new Uint8Array([97, 118, 99, 49]); // avc1\n\t var minorVersion = new Uint8Array([0, 0, 0, 1]);\n\t\n\t MP4.FTYP = MP4.box(MP4.types.ftyp, majorBrand, minorVersion, majorBrand, avc1Brand);\n\t MP4.DINF = MP4.box(MP4.types.dinf, MP4.box(MP4.types.dref, dref));\n\t }\n\t }, {\n\t key: 'box',\n\t value: function box(type) {\n\t var payload = Array.prototype.slice.call(arguments, 1),\n\t size = 8,\n\t i = payload.length,\n\t len = i,\n\t result;\n\t // calculate the total size we need to allocate\n\t while (i--) {\n\t size += payload[i].byteLength;\n\t }\n\t result = new Uint8Array(size);\n\t result[0] = size >> 24 & 0xff;\n\t result[1] = size >> 16 & 0xff;\n\t result[2] = size >> 8 & 0xff;\n\t result[3] = size & 0xff;\n\t result.set(type, 4);\n\t // copy the payload into the result\n\t for (i = 0, size = 8; i < len; i++) {\n\t // copy payload[i] array @ offset size\n\t result.set(payload[i], size);\n\t size += payload[i].byteLength;\n\t }\n\t return result;\n\t }\n\t }, {\n\t key: 'hdlr',\n\t value: function hdlr(type) {\n\t return MP4.box(MP4.types.hdlr, MP4.HDLR_TYPES[type]);\n\t }\n\t }, {\n\t key: 'mdat',\n\t value: function mdat(data) {\n\t return MP4.box(MP4.types.mdat, data);\n\t }\n\t }, {\n\t key: 'mdhd',\n\t value: function mdhd(timescale, duration) {\n\t duration *= timescale;\n\t return MP4.box(MP4.types.mdhd, new Uint8Array([0x00, // version 0\n\t 0x00, 0x00, 0x00, // flags\n\t 0x00, 0x00, 0x00, 0x02, // creation_time\n\t 0x00, 0x00, 0x00, 0x03, // modification_time\n\t timescale >> 24 & 0xFF, timescale >> 16 & 0xFF, timescale >> 8 & 0xFF, timescale & 0xFF, // timescale\n\t duration >> 24, duration >> 16 & 0xFF, duration >> 8 & 0xFF, duration & 0xFF, // duration\n\t 0x55, 0xc4, // 'und' language (undetermined)\n\t 0x00, 0x00]));\n\t }\n\t }, {\n\t key: 'mdia',\n\t value: function mdia(track) {\n\t return MP4.box(MP4.types.mdia, MP4.mdhd(track.timescale, track.duration), MP4.hdlr(track.type), MP4.minf(track));\n\t }\n\t }, {\n\t key: 'mfhd',\n\t value: function mfhd(sequenceNumber) {\n\t return MP4.box(MP4.types.mfhd, new Uint8Array([0x00, 0x00, 0x00, 0x00, // flags\n\t sequenceNumber >> 24, sequenceNumber >> 16 & 0xFF, sequenceNumber >> 8 & 0xFF, sequenceNumber & 0xFF]));\n\t }\n\t }, {\n\t key: 'minf',\n\t // sequence_number\n\t value: function minf(track) {\n\t if (track.type === 'audio') {\n\t return MP4.box(MP4.types.minf, MP4.box(MP4.types.smhd, MP4.SMHD), MP4.DINF, MP4.stbl(track));\n\t } else {\n\t return MP4.box(MP4.types.minf, MP4.box(MP4.types.vmhd, MP4.VMHD), MP4.DINF, MP4.stbl(track));\n\t }\n\t }\n\t }, {\n\t key: 'moof',\n\t value: function moof(sn, baseMediaDecodeTime, track) {\n\t return MP4.box(MP4.types.moof, MP4.mfhd(sn), MP4.traf(track, baseMediaDecodeTime));\n\t }\n\t /**\n\t * @param tracks... (optional) {array} the tracks associated with this movie\n\t */\n\t\n\t }, {\n\t key: 'moov',\n\t value: function moov(tracks) {\n\t var i = tracks.length,\n\t boxes = [];\n\t\n\t while (i--) {\n\t boxes[i] = MP4.trak(tracks[i]);\n\t }\n\t\n\t return MP4.box.apply(null, [MP4.types.moov, MP4.mvhd(tracks[0].timescale, tracks[0].duration)].concat(boxes).concat(MP4.mvex(tracks)));\n\t }\n\t }, {\n\t key: 'mvex',\n\t value: function mvex(tracks) {\n\t var i = tracks.length,\n\t boxes = [];\n\t\n\t while (i--) {\n\t boxes[i] = MP4.trex(tracks[i]);\n\t }\n\t return MP4.box.apply(null, [MP4.types.mvex].concat(boxes));\n\t }\n\t }, {\n\t key: 'mvhd',\n\t value: function mvhd(timescale, duration) {\n\t duration *= timescale;\n\t var bytes = new Uint8Array([0x00, // version 0\n\t 0x00, 0x00, 0x00, // flags\n\t 0x00, 0x00, 0x00, 0x01, // creation_time\n\t 0x00, 0x00, 0x00, 0x02, // modification_time\n\t timescale >> 24 & 0xFF, timescale >> 16 & 0xFF, timescale >> 8 & 0xFF, timescale & 0xFF, // timescale\n\t duration >> 24 & 0xFF, duration >> 16 & 0xFF, duration >> 8 & 0xFF, duration & 0xFF, // duration\n\t 0x00, 0x01, 0x00, 0x00, // 1.0 rate\n\t 0x01, 0x00, // 1.0 volume\n\t 0x00, 0x00, // reserved\n\t 0x00, 0x00, 0x00, 0x00, // reserved\n\t 0x00, 0x00, 0x00, 0x00, // reserved\n\t 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, // transformation: unity matrix\n\t 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // pre_defined\n\t 0xff, 0xff, 0xff, 0xff // next_track_ID\n\t ]);\n\t return MP4.box(MP4.types.mvhd, bytes);\n\t }\n\t }, {\n\t key: 'sdtp',\n\t value: function sdtp(track) {\n\t var samples = track.samples || [],\n\t bytes = new Uint8Array(4 + samples.length),\n\t flags,\n\t i;\n\t // leave the full box header (4 bytes) all zero\n\t // write the sample table\n\t for (i = 0; i < samples.length; i++) {\n\t flags = samples[i].flags;\n\t bytes[i + 4] = flags.dependsOn << 4 | flags.isDependedOn << 2 | flags.hasRedundancy;\n\t }\n\t\n\t return MP4.box(MP4.types.sdtp, bytes);\n\t }\n\t }, {\n\t key: 'stbl',\n\t value: function stbl(track) {\n\t return MP4.box(MP4.types.stbl, MP4.stsd(track), MP4.box(MP4.types.stts, MP4.STTS), MP4.box(MP4.types.stsc, MP4.STSC), MP4.box(MP4.types.stsz, MP4.STSZ), MP4.box(MP4.types.stco, MP4.STCO));\n\t }\n\t }, {\n\t key: 'avc1',\n\t value: function avc1(track) {\n\t var sps = [],\n\t pps = [],\n\t i,\n\t data,\n\t len;\n\t // assemble the SPSs\n\t\n\t for (i = 0; i < track.sps.length; i++) {\n\t data = track.sps[i];\n\t len = data.byteLength;\n\t sps.push(len >>> 8 & 0xFF);\n\t sps.push(len & 0xFF);\n\t sps = sps.concat(Array.prototype.slice.call(data)); // SPS\n\t }\n\t\n\t // assemble the PPSs\n\t for (i = 0; i < track.pps.length; i++) {\n\t data = track.pps[i];\n\t len = data.byteLength;\n\t pps.push(len >>> 8 & 0xFF);\n\t pps.push(len & 0xFF);\n\t pps = pps.concat(Array.prototype.slice.call(data));\n\t }\n\t\n\t var avcc = MP4.box(MP4.types.avcC, new Uint8Array([0x01, // version\n\t sps[3], // profile\n\t sps[4], // profile compat\n\t sps[5], // level\n\t 0xfc | 3, // lengthSizeMinusOne, hard-coded to 4 bytes\n\t 0xE0 | track.sps.length // 3bit reserved (111) + numOfSequenceParameterSets\n\t ].concat(sps).concat([track.pps.length // numOfPictureParameterSets\n\t ]).concat(pps))),\n\t // \"PPS\"\n\t width = track.width,\n\t height = track.height;\n\t //console.log('avcc:' + Hex.hexDump(avcc));\n\t return MP4.box(MP4.types.avc1, new Uint8Array([0x00, 0x00, 0x00, // reserved\n\t 0x00, 0x00, 0x00, // reserved\n\t 0x00, 0x01, // data_reference_index\n\t 0x00, 0x00, // pre_defined\n\t 0x00, 0x00, // reserved\n\t 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // pre_defined\n\t width >> 8 & 0xFF, width & 0xff, // width\n\t height >> 8 & 0xFF, height & 0xff, // height\n\t 0x00, 0x48, 0x00, 0x00, // horizresolution\n\t 0x00, 0x48, 0x00, 0x00, // vertresolution\n\t 0x00, 0x00, 0x00, 0x00, // reserved\n\t 0x00, 0x01, // frame_count\n\t 0x12, 0x64, 0x61, 0x69, 0x6C, //dailymotion/hls.js\n\t 0x79, 0x6D, 0x6F, 0x74, 0x69, 0x6F, 0x6E, 0x2F, 0x68, 0x6C, 0x73, 0x2E, 0x6A, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // compressorname\n\t 0x00, 0x18, // depth = 24\n\t 0x11, 0x11]), // pre_defined = -1\n\t avcc, MP4.box(MP4.types.btrt, new Uint8Array([0x00, 0x1c, 0x9c, 0x80, // bufferSizeDB\n\t 0x00, 0x2d, 0xc6, 0xc0, // maxBitrate\n\t 0x00, 0x2d, 0xc6, 0xc0])) // avgBitrate\n\t );\n\t }\n\t }, {\n\t key: 'esds',\n\t value: function esds(track) {\n\t var configlen = track.config.length;\n\t return new Uint8Array([0x00, // version 0\n\t 0x00, 0x00, 0x00, // flags\n\t\n\t 0x03, // descriptor_type\n\t 0x17 + configlen, // length\n\t 0x00, 0x01, //es_id\n\t 0x00, // stream_priority\n\t\n\t 0x04, // descriptor_type\n\t 0x0f + configlen, // length\n\t 0x40, //codec : mpeg4_audio\n\t 0x15, // stream_type\n\t 0x00, 0x00, 0x00, // buffer_size\n\t 0x00, 0x00, 0x00, 0x00, // maxBitrate\n\t 0x00, 0x00, 0x00, 0x00, // avgBitrate\n\t\n\t 0x05 // descriptor_type\n\t ].concat([configlen]).concat(track.config).concat([0x06, 0x01, 0x02])); // GASpecificConfig)); // length + audio config descriptor\n\t }\n\t }, {\n\t key: 'mp4a',\n\t value: function mp4a(track) {\n\t var audiosamplerate = track.audiosamplerate;\n\t return MP4.box(MP4.types.mp4a, new Uint8Array([0x00, 0x00, 0x00, // reserved\n\t 0x00, 0x00, 0x00, // reserved\n\t 0x00, 0x01, // data_reference_index\n\t 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // reserved\n\t 0x00, track.channelCount, // channelcount\n\t 0x00, 0x10, // sampleSize:16bits\n\t 0x00, 0x00, 0x00, 0x00, // reserved2\n\t audiosamplerate >> 8 & 0xFF, audiosamplerate & 0xff, //\n\t 0x00, 0x00]), MP4.box(MP4.types.esds, MP4.esds(track)));\n\t }\n\t }, {\n\t key: 'stsd',\n\t value: function stsd(track) {\n\t if (track.type === 'audio') {\n\t return MP4.box(MP4.types.stsd, MP4.STSD, MP4.mp4a(track));\n\t } else {\n\t return MP4.box(MP4.types.stsd, MP4.STSD, MP4.avc1(track));\n\t }\n\t }\n\t }, {\n\t key: 'tkhd',\n\t value: function tkhd(track) {\n\t var id = track.id,\n\t duration = track.duration * track.timescale,\n\t width = track.width,\n\t height = track.height;\n\t return MP4.box(MP4.types.tkhd, new Uint8Array([0x00, // version 0\n\t 0x00, 0x00, 0x07, // flags\n\t 0x00, 0x00, 0x00, 0x00, // creation_time\n\t 0x00, 0x00, 0x00, 0x00, // modification_time\n\t id >> 24 & 0xFF, id >> 16 & 0xFF, id >> 8 & 0xFF, id & 0xFF, // track_ID\n\t 0x00, 0x00, 0x00, 0x00, // reserved\n\t duration >> 24, duration >> 16 & 0xFF, duration >> 8 & 0xFF, duration & 0xFF, // duration\n\t 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // reserved\n\t 0x00, 0x00, // layer\n\t 0x00, 0x00, // alternate_group\n\t 0x00, 0x00, // non-audio track volume\n\t 0x00, 0x00, // reserved\n\t 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, // transformation: unity matrix\n\t width >> 8 & 0xFF, width & 0xFF, 0x00, 0x00, // width\n\t height >> 8 & 0xFF, height & 0xFF, 0x00, 0x00 // height\n\t ]));\n\t }\n\t }, {\n\t key: 'traf',\n\t value: function traf(track, baseMediaDecodeTime) {\n\t var sampleDependencyTable = MP4.sdtp(track),\n\t id = track.id;\n\t return MP4.box(MP4.types.traf, MP4.box(MP4.types.tfhd, new Uint8Array([0x00, // version 0\n\t 0x00, 0x00, 0x00, // flags\n\t id >> 24, id >> 16 & 0XFF, id >> 8 & 0XFF, id & 0xFF])), // track_ID\n\t MP4.box(MP4.types.tfdt, new Uint8Array([0x00, // version 0\n\t 0x00, 0x00, 0x00, // flags\n\t baseMediaDecodeTime >> 24, baseMediaDecodeTime >> 16 & 0XFF, baseMediaDecodeTime >> 8 & 0XFF, baseMediaDecodeTime & 0xFF])), // baseMediaDecodeTime\n\t MP4.trun(track, sampleDependencyTable.length + 16 + // tfhd\n\t 16 + // tfdt\n\t 8 + // traf header\n\t 16 + // mfhd\n\t 8 + // moof header\n\t 8), // mdat header\n\t sampleDependencyTable);\n\t }\n\t\n\t /**\n\t * Generate a track box.\n\t * @param track {object} a track definition\n\t * @return {Uint8Array} the track box\n\t */\n\t\n\t }, {\n\t key: 'trak',\n\t value: function trak(track) {\n\t track.duration = track.duration || 0xffffffff;\n\t return MP4.box(MP4.types.trak, MP4.tkhd(track), MP4.mdia(track));\n\t }\n\t }, {\n\t key: 'trex',\n\t value: function trex(track) {\n\t var id = track.id;\n\t return MP4.box(MP4.types.trex, new Uint8Array([0x00, // version 0\n\t 0x00, 0x00, 0x00, // flags\n\t id >> 24, id >> 16 & 0XFF, id >> 8 & 0XFF, id & 0xFF, // track_ID\n\t 0x00, 0x00, 0x00, 0x01, // default_sample_description_index\n\t 0x00, 0x00, 0x00, 0x00, // default_sample_duration\n\t 0x00, 0x00, 0x00, 0x00, // default_sample_size\n\t 0x00, 0x01, 0x00, 0x01 // default_sample_flags\n\t ]));\n\t }\n\t }, {\n\t key: 'trun',\n\t value: function trun(track, offset) {\n\t var samples = track.samples || [],\n\t len = samples.length,\n\t arraylen = 12 + 16 * len,\n\t array = new Uint8Array(arraylen),\n\t i,\n\t sample,\n\t duration,\n\t size,\n\t flags,\n\t cts;\n\t offset += 8 + arraylen;\n\t array.set([0x00, // version 0\n\t 0x00, 0x0f, 0x01, // flags\n\t len >>> 24 & 0xFF, len >>> 16 & 0xFF, len >>> 8 & 0xFF, len & 0xFF, // sample_count\n\t offset >>> 24 & 0xFF, offset >>> 16 & 0xFF, offset >>> 8 & 0xFF, offset & 0xFF // data_offset\n\t ], 0);\n\t for (i = 0; i < len; i++) {\n\t sample = samples[i];\n\t duration = sample.duration;\n\t size = sample.size;\n\t flags = sample.flags;\n\t cts = sample.cts;\n\t array.set([duration >>> 24 & 0xFF, duration >>> 16 & 0xFF, duration >>> 8 & 0xFF, duration & 0xFF, // sample_duration\n\t size >>> 24 & 0xFF, size >>> 16 & 0xFF, size >>> 8 & 0xFF, size & 0xFF, // sample_size\n\t flags.isLeading << 2 | flags.dependsOn, flags.isDependedOn << 6 | flags.hasRedundancy << 4 | flags.paddingValue << 1 | flags.isNonSync, flags.degradPrio & 0xF0 << 8, flags.degradPrio & 0x0F, // sample_flags\n\t cts >>> 24 & 0xFF, cts >>> 16 & 0xFF, cts >>> 8 & 0xFF, cts & 0xFF // sample_composition_time_offset\n\t ], 12 + 16 * i);\n\t }\n\t return MP4.box(MP4.types.trun, array);\n\t }\n\t }, {\n\t key: 'initSegment',\n\t value: function initSegment(tracks) {\n\t if (!MP4.types) {\n\t MP4.init();\n\t }\n\t var movie = MP4.moov(tracks),\n\t result;\n\t result = new Uint8Array(MP4.FTYP.byteLength + movie.byteLength);\n\t result.set(MP4.FTYP);\n\t result.set(movie, MP4.FTYP.byteLength);\n\t return result;\n\t }\n\t }]);\n\t\n\t return MP4;\n\t}();\n\t\n\texports.default = MP4;\n\t\n\t},{}],36:[function(_dereq_,module,exports){\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t\n\tvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /**\n\t * fMP4 remuxer\n\t */\n\t\n\tvar _aac = _dereq_(27);\n\t\n\tvar _aac2 = _interopRequireDefault(_aac);\n\t\n\tvar _events = _dereq_(26);\n\t\n\tvar _events2 = _interopRequireDefault(_events);\n\t\n\tvar _logger = _dereq_(43);\n\t\n\tvar _mp4Generator = _dereq_(35);\n\t\n\tvar _mp4Generator2 = _interopRequireDefault(_mp4Generator);\n\t\n\tvar _errors = _dereq_(24);\n\t\n\t_dereq_(44);\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\t\n\tfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\t\n\tvar MP4Remuxer = function () {\n\t function MP4Remuxer(observer, id, config) {\n\t _classCallCheck(this, MP4Remuxer);\n\t\n\t this.observer = observer;\n\t this.id = id;\n\t this.config = config;\n\t this.ISGenerated = false;\n\t this.PES2MP4SCALEFACTOR = 4;\n\t this.PES_TIMESCALE = 90000;\n\t this.MP4_TIMESCALE = this.PES_TIMESCALE / this.PES2MP4SCALEFACTOR;\n\t }\n\t\n\t _createClass(MP4Remuxer, [{\n\t key: 'destroy',\n\t value: function destroy() {}\n\t }, {\n\t key: 'insertDiscontinuity',\n\t value: function insertDiscontinuity() {\n\t this._initPTS = this._initDTS = undefined;\n\t }\n\t }, {\n\t key: 'switchLevel',\n\t value: function switchLevel() {\n\t this.ISGenerated = false;\n\t }\n\t }, {\n\t key: 'remux',\n\t value: function remux(level, sn, audioTrack, videoTrack, id3Track, textTrack, timeOffset, contiguous, accurateTimeOffset) {\n\t this.level = level;\n\t this.sn = sn;\n\t // generate Init Segment if needed\n\t if (!this.ISGenerated) {\n\t this.generateIS(audioTrack, videoTrack, timeOffset);\n\t }\n\t\n\t if (this.ISGenerated) {\n\t // Purposefully remuxing audio before video, so that remuxVideo can use nextAacPts, which is\n\t // calculated in remuxAudio.\n\t //logger.log('nb AAC samples:' + audioTrack.samples.length);\n\t if (audioTrack.samples.length) {\n\t var audioData = this.remuxAudio(audioTrack, timeOffset, contiguous, accurateTimeOffset);\n\t //logger.log('nb AVC samples:' + videoTrack.samples.length);\n\t if (videoTrack.samples.length) {\n\t var audioTrackLength = void 0;\n\t if (audioData) {\n\t audioTrackLength = audioData.endPTS - audioData.startPTS;\n\t }\n\t this.remuxVideo(videoTrack, timeOffset, contiguous, audioTrackLength);\n\t }\n\t } else {\n\t var videoData = void 0;\n\t //logger.log('nb AVC samples:' + videoTrack.samples.length);\n\t if (videoTrack.samples.length) {\n\t videoData = this.remuxVideo(videoTrack, timeOffset, contiguous);\n\t }\n\t if (videoData && audioTrack.codec) {\n\t this.remuxEmptyAudio(audioTrack, timeOffset, contiguous, videoData);\n\t }\n\t }\n\t }\n\t //logger.log('nb ID3 samples:' + audioTrack.samples.length);\n\t if (id3Track.samples.length) {\n\t this.remuxID3(id3Track, timeOffset);\n\t }\n\t //logger.log('nb ID3 samples:' + audioTrack.samples.length);\n\t if (textTrack.samples.length) {\n\t this.remuxText(textTrack, timeOffset);\n\t }\n\t //notify end of parsing\n\t this.observer.trigger(_events2.default.FRAG_PARSED, { id: this.id, level: this.level, sn: this.sn });\n\t }\n\t }, {\n\t key: 'generateIS',\n\t value: function generateIS(audioTrack, videoTrack, timeOffset) {\n\t var observer = this.observer,\n\t audioSamples = audioTrack.samples,\n\t videoSamples = videoTrack.samples,\n\t pesTimeScale = this.PES_TIMESCALE,\n\t tracks = {},\n\t data = { id: this.id, level: this.level, sn: this.sn, tracks: tracks, unique: false },\n\t computePTSDTS = this._initPTS === undefined,\n\t initPTS,\n\t initDTS;\n\t\n\t if (computePTSDTS) {\n\t initPTS = initDTS = Infinity;\n\t }\n\t if (audioTrack.config && audioSamples.length) {\n\t audioTrack.timescale = audioTrack.audiosamplerate;\n\t // MP4 duration (track duration in seconds multiplied by timescale) is coded on 32 bits\n\t // we know that each AAC sample contains 1024 frames....\n\t // in order to avoid overflowing the 32 bit counter for large duration, we use smaller timescale (timescale/gcd)\n\t // we just need to ensure that AAC sample duration will still be an integer (will be 1024/gcd)\n\t if (audioTrack.timescale * audioTrack.duration > Math.pow(2, 32)) {\n\t (function () {\n\t var greatestCommonDivisor = function greatestCommonDivisor(a, b) {\n\t if (!b) {\n\t return a;\n\t }\n\t return greatestCommonDivisor(b, a % b);\n\t };\n\t audioTrack.timescale = audioTrack.audiosamplerate / greatestCommonDivisor(audioTrack.audiosamplerate, 1024);\n\t })();\n\t }\n\t _logger.logger.log('audio mp4 timescale :' + audioTrack.timescale);\n\t tracks.audio = {\n\t container: 'audio/mp4',\n\t codec: audioTrack.codec,\n\t initSegment: _mp4Generator2.default.initSegment([audioTrack]),\n\t metadata: {\n\t channelCount: audioTrack.channelCount\n\t }\n\t };\n\t if (computePTSDTS) {\n\t // remember first PTS of this demuxing context. for audio, PTS = DTS\n\t initPTS = initDTS = audioSamples[0].pts - pesTimeScale * timeOffset;\n\t }\n\t }\n\t\n\t if (videoTrack.sps && videoTrack.pps && videoSamples.length) {\n\t videoTrack.timescale = this.MP4_TIMESCALE;\n\t tracks.video = {\n\t container: 'video/mp4',\n\t codec: videoTrack.codec,\n\t initSegment: _mp4Generator2.default.initSegment([videoTrack]),\n\t metadata: {\n\t width: videoTrack.width,\n\t height: videoTrack.height\n\t }\n\t };\n\t if (computePTSDTS) {\n\t initPTS = Math.min(initPTS, videoSamples[0].pts - pesTimeScale * timeOffset);\n\t initDTS = Math.min(initDTS, videoSamples[0].dts - pesTimeScale * timeOffset);\n\t }\n\t }\n\t\n\t if (Object.keys(tracks).length) {\n\t observer.trigger(_events2.default.FRAG_PARSING_INIT_SEGMENT, data);\n\t this.ISGenerated = true;\n\t if (computePTSDTS) {\n\t this._initPTS = initPTS;\n\t this._initDTS = initDTS;\n\t }\n\t } else {\n\t observer.trigger(_events2.default.ERROR, { type: _errors.ErrorTypes.MEDIA_ERROR, id: this.id, details: _errors.ErrorDetails.FRAG_PARSING_ERROR, fatal: false, reason: 'no audio/video samples found' });\n\t }\n\t }\n\t }, {\n\t key: 'remuxVideo',\n\t value: function remuxVideo(track, timeOffset, contiguous, audioTrackLength) {\n\t var offset = 8,\n\t pesTimeScale = this.PES_TIMESCALE,\n\t pes2mp4ScaleFactor = this.PES2MP4SCALEFACTOR,\n\t mp4SampleDuration,\n\t mdat,\n\t moof,\n\t firstPTS,\n\t firstDTS,\n\t nextDTS,\n\t lastPTS,\n\t lastDTS,\n\t inputSamples = track.samples,\n\t outputSamples = [];\n\t\n\t // for (let i = 0; i < track.samples.length; i++) {\n\t // let avcSample = track.samples[i];\n\t // let units = avcSample.units.units;\n\t // let unitsString = '';\n\t // for (let j = 0; j < units.length ; j++) {\n\t // unitsString += units[j].type + ',';\n\t // if (units[j].data.length < 500) {\n\t // unitsString += Hex.hexDump(units[j].data);\n\t // }\n\t // }\n\t // logger.log(avcSample.pts + '/' + avcSample.dts + ',' + unitsString + avcSample.units.length);\n\t // }\n\t\n\t // handle broken streams with PTS < DTS, tolerance up 200ms (18000 in 90kHz timescale)\n\t var PTSDTSshift = inputSamples.reduce(function (prev, curr) {\n\t return Math.max(Math.min(prev, curr.pts - curr.dts), -18000);\n\t }, 0);\n\t if (PTSDTSshift < 0) {\n\t _logger.logger.warn('PTS < DTS detected in video samples, shifting DTS by ' + Math.round(PTSDTSshift / 90) + ' ms to overcome this issue');\n\t for (var i = 0; i < inputSamples.length; i++) {\n\t inputSamples[i].dts += PTSDTSshift;\n\t }\n\t }\n\t\n\t // PTS is coded on 33bits, and can loop from -2^32 to 2^32\n\t // PTSNormalize will make PTS/DTS value monotonic, we use last known DTS value as reference value\n\t var nextAvcDts = void 0;\n\t // contiguous fragments are consecutive fragments from same quality level (same level, new SN = old SN + 1)\n\t if (contiguous) {\n\t // if parsed fragment is contiguous with last one, let's use last DTS value as reference\n\t nextAvcDts = this.nextAvcDts;\n\t } else {\n\t // if not contiguous, let's use target timeOffset\n\t nextAvcDts = timeOffset * pesTimeScale;\n\t }\n\t\n\t // compute first DTS and last DTS, normalize them against reference value\n\t var sample = inputSamples[0];\n\t firstDTS = Math.max(this._PTSNormalize(sample.dts - this._initDTS, nextAvcDts), 0);\n\t firstPTS = Math.max(this._PTSNormalize(sample.pts - this._initDTS, nextAvcDts), 0);\n\t\n\t // check timestamp continuity accross consecutive fragments (this is to remove inter-fragment gap/hole)\n\t var delta = Math.round((firstDTS - nextAvcDts) / 90);\n\t // if fragment are contiguous, detect hole/overlapping between fragments\n\t if (contiguous) {\n\t if (delta) {\n\t if (delta > 1) {\n\t _logger.logger.log('AVC:' + delta + ' ms hole between fragments detected,filling it');\n\t } else if (delta < -1) {\n\t _logger.logger.log('AVC:' + -delta + ' ms overlapping between fragments detected');\n\t }\n\t // remove hole/gap : set DTS to next expected DTS\n\t firstDTS = nextAvcDts;\n\t inputSamples[0].dts = firstDTS + this._initDTS;\n\t // offset PTS as well, ensure that PTS is smaller or equal than new DTS\n\t firstPTS = Math.max(firstPTS - delta, nextAvcDts);\n\t inputSamples[0].pts = firstPTS + this._initDTS;\n\t _logger.logger.log('Video/PTS/DTS adjusted: ' + Math.round(firstPTS / 90) + '/' + Math.round(firstDTS / 90) + ',delta:' + delta + ' ms');\n\t }\n\t }\n\t nextDTS = firstDTS;\n\t\n\t // compute lastPTS/lastDTS\n\t sample = inputSamples[inputSamples.length - 1];\n\t lastDTS = Math.max(this._PTSNormalize(sample.dts - this._initDTS, nextAvcDts), 0);\n\t lastPTS = Math.max(this._PTSNormalize(sample.pts - this._initDTS, nextAvcDts), 0);\n\t lastPTS = Math.max(lastPTS, lastDTS);\n\t\n\t var vendor = navigator.vendor,\n\t userAgent = navigator.userAgent,\n\t isSafari = vendor && vendor.indexOf('Apple') > -1 && userAgent && !userAgent.match('CriOS');\n\t\n\t // on Safari let's signal the same sample duration for all samples\n\t // sample duration (as expected by trun MP4 boxes), should be the delta between sample DTS\n\t // set this constant duration as being the avg delta between consecutive DTS.\n\t if (isSafari) {\n\t mp4SampleDuration = Math.round((lastDTS - firstDTS) / (pes2mp4ScaleFactor * (inputSamples.length - 1)));\n\t }\n\t\n\t // normalize all PTS/DTS now ...\n\t for (var _i = 0; _i < inputSamples.length; _i++) {\n\t var _sample = inputSamples[_i];\n\t if (isSafari) {\n\t // sample DTS is computed using a constant decoding offset (mp4SampleDuration) between samples\n\t _sample.dts = firstDTS + _i * pes2mp4ScaleFactor * mp4SampleDuration;\n\t } else {\n\t // ensure sample monotonic DTS\n\t _sample.dts = Math.max(this._PTSNormalize(_sample.dts - this._initDTS, nextAvcDts), firstDTS);\n\t // ensure dts is a multiple of scale factor to avoid rounding issues\n\t _sample.dts = Math.round(_sample.dts / pes2mp4ScaleFactor) * pes2mp4ScaleFactor;\n\t }\n\t // we normalize PTS against nextAvcDts, we also substract initDTS (some streams don't start @ PTS O)\n\t // and we ensure that computed value is greater or equal than sample DTS\n\t _sample.pts = Math.max(this._PTSNormalize(_sample.pts - this._initDTS, nextAvcDts), _sample.dts);\n\t // ensure pts is a multiple of scale factor to avoid rounding issues\n\t _sample.pts = Math.round(_sample.pts / pes2mp4ScaleFactor) * pes2mp4ScaleFactor;\n\t }\n\t\n\t /* concatenate the video data and construct the mdat in place\n\t (need 8 more bytes to fill length and mpdat type) */\n\t mdat = new Uint8Array(track.len + 4 * track.nbNalu + 8);\n\t var view = new DataView(mdat.buffer);\n\t view.setUint32(0, mdat.byteLength);\n\t mdat.set(_mp4Generator2.default.types.mdat, 4);\n\t\n\t for (var _i2 = 0; _i2 < inputSamples.length; _i2++) {\n\t var avcSample = inputSamples[_i2],\n\t mp4SampleLength = 0,\n\t compositionTimeOffset = void 0;\n\t // convert NALU bitstream to MP4 format (prepend NALU with size field)\n\t while (avcSample.units.units.length) {\n\t var unit = avcSample.units.units.shift();\n\t view.setUint32(offset, unit.data.byteLength);\n\t offset += 4;\n\t mdat.set(unit.data, offset);\n\t offset += unit.data.byteLength;\n\t mp4SampleLength += 4 + unit.data.byteLength;\n\t }\n\t\n\t if (!isSafari) {\n\t // expected sample duration is the Decoding Timestamp diff of consecutive samples\n\t if (_i2 < inputSamples.length - 1) {\n\t mp4SampleDuration = inputSamples[_i2 + 1].dts - avcSample.dts;\n\t } else {\n\t var config = this.config,\n\t lastFrameDuration = avcSample.dts - inputSamples[_i2 > 0 ? _i2 - 1 : _i2].dts;\n\t if (config.stretchShortVideoTrack) {\n\t // In some cases, a segment's audio track duration may exceed the video track duration.\n\t // Since we've already remuxed audio, and we know how long the audio track is, we look to\n\t // see if the delta to the next segment is longer than the minimum of maxBufferHole and\n\t // maxSeekHole. If so, playback would potentially get stuck, so we artificially inflate\n\t // the duration of the last frame to minimize any potential gap between segments.\n\t var maxBufferHole = config.maxBufferHole,\n\t maxSeekHole = config.maxSeekHole,\n\t gapTolerance = Math.floor(Math.min(maxBufferHole, maxSeekHole) * pesTimeScale),\n\t deltaToFrameEnd = (audioTrackLength ? firstPTS + audioTrackLength * pesTimeScale : this.nextAacPts) - avcSample.pts;\n\t if (deltaToFrameEnd > gapTolerance) {\n\t // We subtract lastFrameDuration from deltaToFrameEnd to try to prevent any video\n\t // frame overlap. maxBufferHole/maxSeekHole should be >> lastFrameDuration anyway.\n\t mp4SampleDuration = deltaToFrameEnd - lastFrameDuration;\n\t if (mp4SampleDuration < 0) {\n\t mp4SampleDuration = lastFrameDuration;\n\t }\n\t _logger.logger.log('It is approximately ' + deltaToFrameEnd / 90 + ' ms to the next segment; using duration ' + mp4SampleDuration / 90 + ' ms for the last video frame.');\n\t } else {\n\t mp4SampleDuration = lastFrameDuration;\n\t }\n\t } else {\n\t mp4SampleDuration = lastFrameDuration;\n\t }\n\t }\n\t mp4SampleDuration /= pes2mp4ScaleFactor;\n\t compositionTimeOffset = Math.round((avcSample.pts - avcSample.dts) / pes2mp4ScaleFactor);\n\t } else {\n\t compositionTimeOffset = Math.max(0, mp4SampleDuration * Math.round((avcSample.pts - avcSample.dts) / (pes2mp4ScaleFactor * mp4SampleDuration)));\n\t }\n\t\n\t //console.log('PTS/DTS/initDTS/normPTS/normDTS/relative PTS : ${avcSample.pts}/${avcSample.dts}/${this._initDTS}/${ptsnorm}/${dtsnorm}/${(avcSample.pts/4294967296).toFixed(3)}');\n\t outputSamples.push({\n\t size: mp4SampleLength,\n\t // constant duration\n\t duration: mp4SampleDuration,\n\t cts: compositionTimeOffset,\n\t flags: {\n\t isLeading: 0,\n\t isDependedOn: 0,\n\t hasRedundancy: 0,\n\t degradPrio: 0,\n\t dependsOn: avcSample.key ? 2 : 1,\n\t isNonSync: avcSample.key ? 0 : 1\n\t }\n\t });\n\t }\n\t // next AVC sample DTS should be equal to last sample DTS + last sample duration (in PES timescale)\n\t this.nextAvcDts = lastDTS + mp4SampleDuration * pes2mp4ScaleFactor;\n\t var dropped = track.dropped;\n\t track.len = 0;\n\t track.nbNalu = 0;\n\t track.dropped = 0;\n\t if (outputSamples.length && navigator.userAgent.toLowerCase().indexOf('chrome') > -1) {\n\t var flags = outputSamples[0].flags;\n\t // chrome workaround, mark first sample as being a Random Access Point to avoid sourcebuffer append issue\n\t // https://code.google.com/p/chromium/issues/detail?id=229412\n\t flags.dependsOn = 2;\n\t flags.isNonSync = 0;\n\t }\n\t track.samples = outputSamples;\n\t moof = _mp4Generator2.default.moof(track.sequenceNumber++, firstDTS / pes2mp4ScaleFactor, track);\n\t track.samples = [];\n\t\n\t var data = {\n\t id: this.id,\n\t level: this.level,\n\t sn: this.sn,\n\t data1: moof,\n\t data2: mdat,\n\t startPTS: firstPTS / pesTimeScale,\n\t endPTS: (lastPTS + pes2mp4ScaleFactor * mp4SampleDuration) / pesTimeScale,\n\t startDTS: firstDTS / pesTimeScale,\n\t endDTS: this.nextAvcDts / pesTimeScale,\n\t type: 'video',\n\t nb: outputSamples.length,\n\t dropped: dropped\n\t };\n\t this.observer.trigger(_events2.default.FRAG_PARSING_DATA, data);\n\t return data;\n\t }\n\t }, {\n\t key: 'remuxAudio',\n\t value: function remuxAudio(track, timeOffset, contiguous, accurateTimeOffset) {\n\t var pesTimeScale = this.PES_TIMESCALE,\n\t mp4timeScale = track.timescale,\n\t pes2mp4ScaleFactor = pesTimeScale / mp4timeScale,\n\t expectedSampleDuration = track.timescale * 1024 / track.audiosamplerate;\n\t var view,\n\t offset = 8,\n\t aacSample,\n\t mp4Sample,\n\t unit,\n\t mdat,\n\t moof,\n\t firstPTS,\n\t firstDTS,\n\t lastDTS,\n\t pts,\n\t dts,\n\t ptsnorm,\n\t dtsnorm,\n\t samples = [],\n\t samples0 = [],\n\t fillFrame,\n\t newStamp;\n\t\n\t track.samples.sort(function (a, b) {\n\t return a.pts - b.pts;\n\t });\n\t samples0 = track.samples;\n\t\n\t // for audio samples, also consider consecutive fragments as being contiguous (even if a level switch occurs),\n\t // for sake of clarity:\n\t // consecutive fragments are frags with less than 100ms gaps between new time offset and next expected PTS\n\t // contiguous fragments are consecutive fragments from same quality level (same level, new SN = old SN + 1)\n\t // this helps ensuring audio continuity\n\t // and this also avoids audio glitches/cut when switching quality, or reporting wrong duration on first audio frame\n\t\n\t contiguous |= samples0.length && this.nextAacPts && Math.abs(timeOffset - this.nextAacPts / pesTimeScale) < 0.1;\n\t\n\t var nextAacPts = contiguous ? this.nextAacPts : timeOffset * pesTimeScale;\n\t\n\t // If the audio track is missing samples, the frames seem to get \"left-shifted\" within the\n\t // resulting mp4 segment, causing sync issues and leaving gaps at the end of the audio segment.\n\t // In an effort to prevent this from happening, we inject frames here where there are gaps.\n\t // When possible, we inject a silent frame; when that's not possible, we duplicate the last\n\t // frame.\n\t var pesFrameDuration = expectedSampleDuration * pes2mp4ScaleFactor;\n\t var nextPtsNorm = nextAacPts;\n\t\n\t // only inject/drop audio frames in case time offset is accurate\n\t if (accurateTimeOffset) {\n\t for (var i = 0; i < samples0.length;) {\n\t // First, let's see how far off this frame is from where we expect it to be\n\t var sample = samples0[i],\n\t ptsNorm = this._PTSNormalize(sample.pts - this._initDTS, nextAacPts),\n\t delta = ptsNorm - nextPtsNorm;\n\t\n\t // If we're overlapping by more than a duration, drop this sample\n\t if (delta <= -pesFrameDuration) {\n\t _logger.logger.warn('Dropping 1 audio frame @ ' + Math.round(nextPtsNorm / 90) / 1000 + 's due to ' + Math.round(Math.abs(delta / 90)) + ' ms overlap.');\n\t samples0.splice(i, 1);\n\t track.len -= sample.unit.length;\n\t // Don't touch nextPtsNorm or i\n\t }\n\t // Otherwise, if we're more than a frame away from where we should be, insert missing frames\n\t else if (delta >= pesFrameDuration) {\n\t var missing = Math.round(delta / pesFrameDuration);\n\t _logger.logger.warn('Injecting ' + missing + ' audio frame @ ' + Math.round(nextPtsNorm / 90) / 1000 + 's due to ' + Math.round(delta / 90) + ' ms gap.');\n\t for (var j = 0; j < missing; j++) {\n\t newStamp = nextPtsNorm + this._initDTS;\n\t newStamp = Math.max(newStamp, this._initDTS);\n\t fillFrame = _aac2.default.getSilentFrame(track.channelCount);\n\t if (!fillFrame) {\n\t _logger.logger.log('Unable to get silent frame for given audio codec; duplicating last frame instead.');\n\t fillFrame = sample.unit.slice(0);\n\t }\n\t samples0.splice(i, 0, { unit: fillFrame, pts: newStamp, dts: newStamp });\n\t track.len += fillFrame.length;\n\t nextPtsNorm += pesFrameDuration;\n\t i += 1;\n\t }\n\t\n\t // Adjust sample to next expected pts\n\t sample.pts = sample.dts = nextPtsNorm + this._initDTS;\n\t nextPtsNorm += pesFrameDuration;\n\t i += 1;\n\t }\n\t // Otherwise, we're within half a frame duration, so just adjust pts\n\t else {\n\t if (Math.abs(delta) > 0.1 * pesFrameDuration) {\n\t //logger.log(`Invalid frame delta ${Math.round(ptsNorm - nextPtsNorm + pesFrameDuration)} at PTS ${Math.round(ptsNorm / 90)} (should be ${Math.round(pesFrameDuration)}).`);\n\t }\n\t nextPtsNorm += pesFrameDuration;\n\t if (i === 0) {\n\t sample.pts = sample.dts = this._initDTS + nextAacPts;\n\t } else {\n\t sample.pts = sample.dts = samples0[i - 1].pts + pesFrameDuration;\n\t }\n\t i += 1;\n\t }\n\t }\n\t }\n\t\n\t while (samples0.length) {\n\t aacSample = samples0.shift();\n\t unit = aacSample.unit;\n\t pts = aacSample.pts - this._initDTS;\n\t dts = aacSample.dts - this._initDTS;\n\t //logger.log(`Audio/PTS:${Math.round(pts/90)}`);\n\t // if not first sample\n\t if (lastDTS !== undefined) {\n\t ptsnorm = this._PTSNormalize(pts, lastDTS);\n\t dtsnorm = this._PTSNormalize(dts, lastDTS);\n\t mp4Sample.duration = Math.round((dtsnorm - lastDTS) / pes2mp4ScaleFactor);\n\t } else {\n\t ptsnorm = this._PTSNormalize(pts, nextAacPts);\n\t dtsnorm = this._PTSNormalize(dts, nextAacPts);\n\t var _delta = Math.round(1000 * (ptsnorm - nextAacPts) / pesTimeScale),\n\t numMissingFrames = 0;\n\t // if fragment are contiguous, detect hole/overlapping between fragments\n\t // contiguous fragments are consecutive fragments from same quality level (same level, new SN = old SN + 1)\n\t if (contiguous) {\n\t // log delta\n\t if (_delta) {\n\t if (_delta > 0) {\n\t numMissingFrames = Math.round((ptsnorm - nextAacPts) / pesFrameDuration);\n\t _logger.logger.log(_delta + ' ms hole between AAC samples detected,filling it');\n\t if (numMissingFrames > 0) {\n\t fillFrame = _aac2.default.getSilentFrame(track.channelCount);\n\t if (!fillFrame) {\n\t fillFrame = unit.slice(0);\n\t }\n\t track.len += numMissingFrames * fillFrame.length;\n\t }\n\t // if we have frame overlap, overlapping for more than half a frame duraion\n\t } else if (_delta < -12) {\n\t // drop overlapping audio frames... browser will deal with it\n\t _logger.logger.log(-_delta + ' ms overlapping between AAC samples detected, drop frame');\n\t track.len -= unit.byteLength;\n\t continue;\n\t }\n\t // set PTS/DTS to expected PTS/DTS\n\t ptsnorm = dtsnorm = nextAacPts;\n\t }\n\t }\n\t // remember first PTS of our aacSamples, ensure value is positive\n\t firstPTS = Math.max(0, ptsnorm);\n\t firstDTS = Math.max(0, dtsnorm);\n\t if (track.len > 0) {\n\t /* concatenate the audio data and construct the mdat in place\n\t (need 8 more bytes to fill length and mdat type) */\n\t mdat = new Uint8Array(track.len + 8);\n\t view = new DataView(mdat.buffer);\n\t view.setUint32(0, mdat.byteLength);\n\t mdat.set(_mp4Generator2.default.types.mdat, 4);\n\t } else {\n\t // no audio samples\n\t return;\n\t }\n\t for (var _i3 = 0; _i3 < numMissingFrames; _i3++) {\n\t newStamp = ptsnorm - (numMissingFrames - _i3) * pesFrameDuration;\n\t fillFrame = _aac2.default.getSilentFrame(track.channelCount);\n\t if (!fillFrame) {\n\t _logger.logger.log('Unable to get silent frame for given audio codec; duplicating this frame instead.');\n\t fillFrame = unit.slice(0);\n\t }\n\t mdat.set(fillFrame, offset);\n\t offset += fillFrame.byteLength;\n\t mp4Sample = {\n\t size: fillFrame.byteLength,\n\t cts: 0,\n\t duration: 1024,\n\t flags: {\n\t isLeading: 0,\n\t isDependedOn: 0,\n\t hasRedundancy: 0,\n\t degradPrio: 0,\n\t dependsOn: 1\n\t }\n\t };\n\t samples.push(mp4Sample);\n\t }\n\t }\n\t mdat.set(unit, offset);\n\t offset += unit.byteLength;\n\t //console.log('PTS/DTS/initDTS/normPTS/normDTS/relative PTS : ${aacSample.pts}/${aacSample.dts}/${this._initDTS}/${ptsnorm}/${dtsnorm}/${(aacSample.pts/4294967296).toFixed(3)}');\n\t mp4Sample = {\n\t size: unit.byteLength,\n\t cts: 0,\n\t duration: 0,\n\t flags: {\n\t isLeading: 0,\n\t isDependedOn: 0,\n\t hasRedundancy: 0,\n\t degradPrio: 0,\n\t dependsOn: 1\n\t }\n\t };\n\t samples.push(mp4Sample);\n\t lastDTS = dtsnorm;\n\t }\n\t var lastSampleDuration = 0;\n\t var nbSamples = samples.length;\n\t //set last sample duration as being identical to previous sample\n\t if (nbSamples >= 2) {\n\t lastSampleDuration = samples[nbSamples - 2].duration;\n\t mp4Sample.duration = lastSampleDuration;\n\t }\n\t if (nbSamples) {\n\t // next aac sample PTS should be equal to last sample PTS + duration\n\t this.nextAacPts = ptsnorm + pes2mp4ScaleFactor * lastSampleDuration;\n\t //logger.log('Audio/PTS/PTSend:' + aacSample.pts.toFixed(0) + '/' + this.nextAacDts.toFixed(0));\n\t track.len = 0;\n\t track.samples = samples;\n\t moof = _mp4Generator2.default.moof(track.sequenceNumber++, firstDTS / pes2mp4ScaleFactor, track);\n\t track.samples = [];\n\t var audioData = {\n\t id: this.id,\n\t level: this.level,\n\t sn: this.sn,\n\t data1: moof,\n\t data2: mdat,\n\t startPTS: firstPTS / pesTimeScale,\n\t endPTS: this.nextAacPts / pesTimeScale,\n\t startDTS: firstDTS / pesTimeScale,\n\t endDTS: (dtsnorm + pes2mp4ScaleFactor * lastSampleDuration) / pesTimeScale,\n\t type: 'audio',\n\t nb: nbSamples\n\t };\n\t this.observer.trigger(_events2.default.FRAG_PARSING_DATA, audioData);\n\t return audioData;\n\t }\n\t return null;\n\t }\n\t }, {\n\t key: 'remuxEmptyAudio',\n\t value: function remuxEmptyAudio(track, timeOffset, contiguous, videoData) {\n\t var pesTimeScale = this.PES_TIMESCALE,\n\t mp4timeScale = track.timescale ? track.timescale : track.audiosamplerate,\n\t pes2mp4ScaleFactor = pesTimeScale / mp4timeScale,\n\t\n\t\n\t // sync with video's timestamp\n\t startDTS = videoData.startDTS * pesTimeScale + this._initDTS,\n\t endDTS = videoData.endDTS * pesTimeScale + this._initDTS,\n\t\n\t\n\t // one sample's duration value\n\t sampleDuration = 1024,\n\t frameDuration = pes2mp4ScaleFactor * sampleDuration,\n\t\n\t\n\t // samples count of this segment's duration\n\t nbSamples = Math.ceil((endDTS - startDTS) / frameDuration),\n\t\n\t\n\t // silent frame\n\t silentFrame = _aac2.default.getSilentFrame(track.channelCount);\n\t\n\t // Can't remux if we can't generate a silent frame...\n\t if (!silentFrame) {\n\t _logger.logger.trace('Unable to remuxEmptyAudio since we were unable to get a silent frame for given audio codec!');\n\t return;\n\t }\n\t\n\t var samples = [];\n\t for (var i = 0; i < nbSamples; i++) {\n\t var stamp = startDTS + i * frameDuration;\n\t samples.push({ unit: silentFrame.slice(0), pts: stamp, dts: stamp });\n\t track.len += silentFrame.length;\n\t }\n\t track.samples = samples;\n\t\n\t this.remuxAudio(track, timeOffset, contiguous);\n\t }\n\t }, {\n\t key: 'remuxID3',\n\t value: function remuxID3(track, timeOffset) {\n\t var length = track.samples.length,\n\t sample;\n\t // consume samples\n\t if (length) {\n\t for (var index = 0; index < length; index++) {\n\t sample = track.samples[index];\n\t // setting id3 pts, dts to relative time\n\t // using this._initPTS and this._initDTS to calculate relative time\n\t sample.pts = (sample.pts - this._initPTS) / this.PES_TIMESCALE;\n\t sample.dts = (sample.dts - this._initDTS) / this.PES_TIMESCALE;\n\t }\n\t this.observer.trigger(_events2.default.FRAG_PARSING_METADATA, {\n\t id: this.id,\n\t level: this.level,\n\t sn: this.sn,\n\t samples: track.samples\n\t });\n\t }\n\t\n\t track.samples = [];\n\t timeOffset = timeOffset;\n\t }\n\t }, {\n\t key: 'remuxText',\n\t value: function remuxText(track, timeOffset) {\n\t track.samples.sort(function (a, b) {\n\t return a.pts - b.pts;\n\t });\n\t\n\t var length = track.samples.length,\n\t sample;\n\t // consume samples\n\t if (length) {\n\t for (var index = 0; index < length; index++) {\n\t sample = track.samples[index];\n\t // setting text pts, dts to relative time\n\t // using this._initPTS and this._initDTS to calculate relative time\n\t sample.pts = (sample.pts - this._initPTS) / this.PES_TIMESCALE;\n\t }\n\t this.observer.trigger(_events2.default.FRAG_PARSING_USERDATA, {\n\t id: this.id,\n\t level: this.level,\n\t sn: this.sn,\n\t samples: track.samples\n\t });\n\t }\n\t\n\t track.samples = [];\n\t timeOffset = timeOffset;\n\t }\n\t }, {\n\t key: '_PTSNormalize',\n\t value: function _PTSNormalize(value, reference) {\n\t var offset;\n\t if (reference === undefined) {\n\t return value;\n\t }\n\t if (reference < value) {\n\t // - 2^33\n\t offset = -8589934592;\n\t } else {\n\t // + 2^33\n\t offset = 8589934592;\n\t }\n\t /* PTS is 33bit (from 0 to 2^33 -1)\n\t if diff between value and reference is bigger than half of the amplitude (2^32) then it means that\n\t PTS looping occured. fill the gap */\n\t while (Math.abs(value - reference) > 4294967296) {\n\t value += offset;\n\t }\n\t return value;\n\t }\n\t }, {\n\t key: 'passthrough',\n\t get: function get() {\n\t return false;\n\t }\n\t }]);\n\t\n\t return MP4Remuxer;\n\t}();\n\t\n\texports.default = MP4Remuxer;\n\t\n\t},{\"24\":24,\"26\":26,\"27\":27,\"35\":35,\"43\":43,\"44\":44}],37:[function(_dereq_,module,exports){\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t\n\tvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /**\n\t * passthrough remuxer\n\t */\n\t\n\t\n\tvar _events = _dereq_(26);\n\t\n\tvar _events2 = _interopRequireDefault(_events);\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\t\n\tfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\t\n\tvar PassThroughRemuxer = function () {\n\t function PassThroughRemuxer(observer, id) {\n\t _classCallCheck(this, PassThroughRemuxer);\n\t\n\t this.observer = observer;\n\t this.id = id;\n\t this.ISGenerated = false;\n\t }\n\t\n\t _createClass(PassThroughRemuxer, [{\n\t key: 'destroy',\n\t value: function destroy() {}\n\t }, {\n\t key: 'insertDiscontinuity',\n\t value: function insertDiscontinuity() {}\n\t }, {\n\t key: 'switchLevel',\n\t value: function switchLevel() {\n\t this.ISGenerated = false;\n\t }\n\t }, {\n\t key: 'remux',\n\t value: function remux(audioTrack, videoTrack, id3Track, textTrack, timeOffset, rawData) {\n\t var observer = this.observer;\n\t // generate Init Segment if needed\n\t if (!this.ISGenerated) {\n\t var tracks = {},\n\t data = { id: this.id, tracks: tracks, unique: true },\n\t track = videoTrack,\n\t codec = track.codec;\n\t\n\t if (codec) {\n\t data.tracks.video = {\n\t container: track.container,\n\t codec: codec,\n\t metadata: {\n\t width: track.width,\n\t height: track.height\n\t }\n\t };\n\t }\n\t\n\t track = audioTrack;\n\t codec = track.codec;\n\t if (codec) {\n\t data.tracks.audio = {\n\t container: track.container,\n\t codec: codec,\n\t metadata: {\n\t channelCount: track.channelCount\n\t }\n\t };\n\t }\n\t this.ISGenerated = true;\n\t observer.trigger(_events2.default.FRAG_PARSING_INIT_SEGMENT, data);\n\t }\n\t observer.trigger(_events2.default.FRAG_PARSING_DATA, {\n\t id: this.id,\n\t data1: rawData,\n\t startPTS: timeOffset,\n\t startDTS: timeOffset,\n\t type: 'audiovideo',\n\t nb: 1,\n\t dropped: 0\n\t });\n\t }\n\t }, {\n\t key: 'passthrough',\n\t get: function get() {\n\t return true;\n\t }\n\t }]);\n\t\n\t return PassThroughRemuxer;\n\t}();\n\t\n\texports.default = PassThroughRemuxer;\n\t\n\t},{\"26\":26}],38:[function(_dereq_,module,exports){\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t\n\tvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\t\n\tfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\t\n\t// adapted from https://github.com/kanongil/node-m3u8parse/blob/master/attrlist.js\n\t\n\tvar AttrList = function () {\n\t function AttrList(attrs) {\n\t _classCallCheck(this, AttrList);\n\t\n\t if (typeof attrs === 'string') {\n\t attrs = AttrList.parseAttrList(attrs);\n\t }\n\t for (var attr in attrs) {\n\t if (attrs.hasOwnProperty(attr)) {\n\t this[attr] = attrs[attr];\n\t }\n\t }\n\t }\n\t\n\t _createClass(AttrList, [{\n\t key: 'decimalInteger',\n\t value: function decimalInteger(attrName) {\n\t var intValue = parseInt(this[attrName], 10);\n\t if (intValue > Number.MAX_SAFE_INTEGER) {\n\t return Infinity;\n\t }\n\t return intValue;\n\t }\n\t }, {\n\t key: 'hexadecimalInteger',\n\t value: function hexadecimalInteger(attrName) {\n\t if (this[attrName]) {\n\t var stringValue = (this[attrName] || '0x').slice(2);\n\t stringValue = (stringValue.length & 1 ? '0' : '') + stringValue;\n\t\n\t var value = new Uint8Array(stringValue.length / 2);\n\t for (var i = 0; i < stringValue.length / 2; i++) {\n\t value[i] = parseInt(stringValue.slice(i * 2, i * 2 + 2), 16);\n\t }\n\t return value;\n\t } else {\n\t return null;\n\t }\n\t }\n\t }, {\n\t key: 'hexadecimalIntegerAsNumber',\n\t value: function hexadecimalIntegerAsNumber(attrName) {\n\t var intValue = parseInt(this[attrName], 16);\n\t if (intValue > Number.MAX_SAFE_INTEGER) {\n\t return Infinity;\n\t }\n\t return intValue;\n\t }\n\t }, {\n\t key: 'decimalFloatingPoint',\n\t value: function decimalFloatingPoint(attrName) {\n\t return parseFloat(this[attrName]);\n\t }\n\t }, {\n\t key: 'enumeratedString',\n\t value: function enumeratedString(attrName) {\n\t return this[attrName];\n\t }\n\t }, {\n\t key: 'decimalResolution',\n\t value: function decimalResolution(attrName) {\n\t var res = /^(\\d+)x(\\d+)$/.exec(this[attrName]);\n\t if (res === null) {\n\t return undefined;\n\t }\n\t return {\n\t width: parseInt(res[1], 10),\n\t height: parseInt(res[2], 10)\n\t };\n\t }\n\t }], [{\n\t key: 'parseAttrList',\n\t value: function parseAttrList(input) {\n\t var re = /\\s*(.+?)\\s*=((?:\\\".*?\\\")|.*?)(?:,|$)/g;\n\t var match,\n\t attrs = {};\n\t while ((match = re.exec(input)) !== null) {\n\t var value = match[2],\n\t quote = '\"';\n\t\n\t if (value.indexOf(quote) === 0 && value.lastIndexOf(quote) === value.length - 1) {\n\t value = value.slice(1, -1);\n\t }\n\t attrs[match[1]] = value;\n\t }\n\t return attrs;\n\t }\n\t }]);\n\t\n\t return AttrList;\n\t}();\n\t\n\texports.default = AttrList;\n\t\n\t},{}],39:[function(_dereq_,module,exports){\n\t\"use strict\";\n\t\n\tvar BinarySearch = {\n\t /**\n\t * Searches for an item in an array which matches a certain condition.\n\t * This requires the condition to only match one item in the array,\n\t * and for the array to be ordered.\n\t *\n\t * @param {Array} list The array to search.\n\t * @param {Function} comparisonFunction\n\t * Called and provided a candidate item as the first argument.\n\t * Should return:\n\t * > -1 if the item should be located at a lower index than the provided item.\n\t * > 1 if the item should be located at a higher index than the provided item.\n\t * > 0 if the item is the item you're looking for.\n\t *\n\t * @return {*} The object if it is found or null otherwise.\n\t */\n\t search: function search(list, comparisonFunction) {\n\t var minIndex = 0;\n\t var maxIndex = list.length - 1;\n\t var currentIndex = null;\n\t var currentElement = null;\n\t\n\t while (minIndex <= maxIndex) {\n\t currentIndex = (minIndex + maxIndex) / 2 | 0;\n\t currentElement = list[currentIndex];\n\t\n\t var comparisonResult = comparisonFunction(currentElement);\n\t if (comparisonResult > 0) {\n\t minIndex = currentIndex + 1;\n\t } else if (comparisonResult < 0) {\n\t maxIndex = currentIndex - 1;\n\t } else {\n\t return currentElement;\n\t }\n\t }\n\t\n\t return null;\n\t }\n\t};\n\t\n\tmodule.exports = BinarySearch;\n\t\n\t},{}],40:[function(_dereq_,module,exports){\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t\n\tvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\t\n\tfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\t\n\t/**\n\t *\n\t * This code was ported from the dash.js project at:\n\t * https://github.com/Dash-Industry-Forum/dash.js/blob/development/externals/cea608-parser.js\n\t * https://github.com/Dash-Industry-Forum/dash.js/commit/8269b26a761e0853bb21d78780ed945144ecdd4d#diff-71bc295a2d6b6b7093a1d3290d53a4b2\n\t *\n\t * The original copyright appears below:\n\t *\n\t * The copyright in this software is being made available under the BSD License,\n\t * included below. This software may be subject to other third party and contributor\n\t * rights, including patent rights, and no such rights are granted under this license.\n\t *\n\t * Copyright (c) 2015-2016, DASH Industry Forum.\n\t * All rights reserved.\n\t *\n\t * Redistribution and use in source and binary forms, with or without modification,\n\t * are permitted provided that the following conditions are met:\n\t * 1. Redistributions of source code must retain the above copyright notice, this\n\t * list of conditions and the following disclaimer.\n\t * * Redistributions in binary form must reproduce the above copyright notice,\n\t * this list of conditions and the following disclaimer in the documentation and/or\n\t * other materials provided with the distribution.\n\t * 2. Neither the name of Dash Industry Forum nor the names of its\n\t * contributors may be used to endorse or promote products derived from this software\n\t * without specific prior written permission.\n\t *\n\t * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY\n\t * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n\t * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n\t * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n\t * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n\t * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n\t * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\n\t * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n\t * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n\t * POSSIBILITY OF SUCH DAMAGE.\n\t */\n\t/**\n\t * Exceptions from regular ASCII. CodePoints are mapped to UTF-16 codes\n\t */\n\t\n\tvar specialCea608CharsCodes = {\n\t 0x2a: 0xe1, // lowercase a, acute accent\n\t 0x5c: 0xe9, // lowercase e, acute accent\n\t 0x5e: 0xed, // lowercase i, acute accent\n\t 0x5f: 0xf3, // lowercase o, acute accent\n\t 0x60: 0xfa, // lowercase u, acute accent\n\t 0x7b: 0xe7, // lowercase c with cedilla\n\t 0x7c: 0xf7, // division symbol\n\t 0x7d: 0xd1, // uppercase N tilde\n\t 0x7e: 0xf1, // lowercase n tilde\n\t 0x7f: 0x2588, // Full block\n\t // THIS BLOCK INCLUDES THE 16 EXTENDED (TWO-BYTE) LINE 21 CHARACTERS\n\t // THAT COME FROM HI BYTE=0x11 AND LOW BETWEEN 0x30 AND 0x3F\n\t // THIS MEANS THAT \\x50 MUST BE ADDED TO THE VALUES\n\t 0x80: 0xae, // Registered symbol (R)\n\t 0x81: 0xb0, // degree sign\n\t 0x82: 0xbd, // 1/2 symbol\n\t 0x83: 0xbf, // Inverted (open) question mark\n\t 0x84: 0x2122, // Trademark symbol (TM)\n\t 0x85: 0xa2, // Cents symbol\n\t 0x86: 0xa3, // Pounds sterling\n\t 0x87: 0x266a, // Music 8'th note\n\t 0x88: 0xe0, // lowercase a, grave accent\n\t 0x89: 0x20, // transparent space (regular)\n\t 0x8a: 0xe8, // lowercase e, grave accent\n\t 0x8b: 0xe2, // lowercase a, circumflex accent\n\t 0x8c: 0xea, // lowercase e, circumflex accent\n\t 0x8d: 0xee, // lowercase i, circumflex accent\n\t 0x8e: 0xf4, // lowercase o, circumflex accent\n\t 0x8f: 0xfb, // lowercase u, circumflex accent\n\t // THIS BLOCK INCLUDES THE 32 EXTENDED (TWO-BYTE) LINE 21 CHARACTERS\n\t // THAT COME FROM HI BYTE=0x12 AND LOW BETWEEN 0x20 AND 0x3F\n\t 0x90: 0xc1, // capital letter A with acute\n\t 0x91: 0xc9, // capital letter E with acute\n\t 0x92: 0xd3, // capital letter O with acute\n\t 0x93: 0xda, // capital letter U with acute\n\t 0x94: 0xdc, // capital letter U with diaresis\n\t 0x95: 0xfc, // lowercase letter U with diaeresis\n\t 0x96: 0x2018, // opening single quote\n\t 0x97: 0xa1, // inverted exclamation mark\n\t 0x98: 0x2a, // asterisk\n\t 0x99: 0x2019, // closing single quote\n\t 0x9a: 0x2501, // box drawings heavy horizontal\n\t 0x9b: 0xa9, // copyright sign\n\t 0x9c: 0x2120, // Service mark\n\t 0x9d: 0x2022, // (round) bullet\n\t 0x9e: 0x201c, // Left double quotation mark\n\t 0x9f: 0x201d, // Right double quotation mark\n\t 0xa0: 0xc0, // uppercase A, grave accent\n\t 0xa1: 0xc2, // uppercase A, circumflex\n\t 0xa2: 0xc7, // uppercase C with cedilla\n\t 0xa3: 0xc8, // uppercase E, grave accent\n\t 0xa4: 0xca, // uppercase E, circumflex\n\t 0xa5: 0xcb, // capital letter E with diaresis\n\t 0xa6: 0xeb, // lowercase letter e with diaresis\n\t 0xa7: 0xce, // uppercase I, circumflex\n\t 0xa8: 0xcf, // uppercase I, with diaresis\n\t 0xa9: 0xef, // lowercase i, with diaresis\n\t 0xaa: 0xd4, // uppercase O, circumflex\n\t 0xab: 0xd9, // uppercase U, grave accent\n\t 0xac: 0xf9, // lowercase u, grave accent\n\t 0xad: 0xdb, // uppercase U, circumflex\n\t 0xae: 0xab, // left-pointing double angle quotation mark\n\t 0xaf: 0xbb, // right-pointing double angle quotation mark\n\t // THIS BLOCK INCLUDES THE 32 EXTENDED (TWO-BYTE) LINE 21 CHARACTERS\n\t // THAT COME FROM HI BYTE=0x13 AND LOW BETWEEN 0x20 AND 0x3F\n\t 0xb0: 0xc3, // Uppercase A, tilde\n\t 0xb1: 0xe3, // Lowercase a, tilde\n\t 0xb2: 0xcd, // Uppercase I, acute accent\n\t 0xb3: 0xcc, // Uppercase I, grave accent\n\t 0xb4: 0xec, // Lowercase i, grave accent\n\t 0xb5: 0xd2, // Uppercase O, grave accent\n\t 0xb6: 0xf2, // Lowercase o, grave accent\n\t 0xb7: 0xd5, // Uppercase O, tilde\n\t 0xb8: 0xf5, // Lowercase o, tilde\n\t 0xb9: 0x7b, // Open curly brace\n\t 0xba: 0x7d, // Closing curly brace\n\t 0xbb: 0x5c, // Backslash\n\t 0xbc: 0x5e, // Caret\n\t 0xbd: 0x5f, // Underscore\n\t 0xbe: 0x7c, // Pipe (vertical line)\n\t 0xbf: 0x223c, // Tilde operator\n\t 0xc0: 0xc4, // Uppercase A, umlaut\n\t 0xc1: 0xe4, // Lowercase A, umlaut\n\t 0xc2: 0xd6, // Uppercase O, umlaut\n\t 0xc3: 0xf6, // Lowercase o, umlaut\n\t 0xc4: 0xdf, // Esszett (sharp S)\n\t 0xc5: 0xa5, // Yen symbol\n\t 0xc6: 0xa4, // Generic currency sign\n\t 0xc7: 0x2503, // Box drawings heavy vertical\n\t 0xc8: 0xc5, // Uppercase A, ring\n\t 0xc9: 0xe5, // Lowercase A, ring\n\t 0xca: 0xd8, // Uppercase O, stroke\n\t 0xcb: 0xf8, // Lowercase o, strok\n\t 0xcc: 0x250f, // Box drawings heavy down and right\n\t 0xcd: 0x2513, // Box drawings heavy down and left\n\t 0xce: 0x2517, // Box drawings heavy up and right\n\t 0xcf: 0x251b // Box drawings heavy up and left\n\t};\n\t\n\t/**\n\t * Utils\n\t */\n\tvar getCharForByte = function getCharForByte(byte) {\n\t var charCode = byte;\n\t if (specialCea608CharsCodes.hasOwnProperty(byte)) {\n\t charCode = specialCea608CharsCodes[byte];\n\t }\n\t return String.fromCharCode(charCode);\n\t};\n\t\n\tvar NR_ROWS = 15,\n\t NR_COLS = 32;\n\t// Tables to look up row from PAC data\n\tvar rowsLowCh1 = { 0x11: 1, 0x12: 3, 0x15: 5, 0x16: 7, 0x17: 9, 0x10: 11, 0x13: 12, 0x14: 14 };\n\tvar rowsHighCh1 = { 0x11: 2, 0x12: 4, 0x15: 6, 0x16: 8, 0x17: 10, 0x13: 13, 0x14: 15 };\n\tvar rowsLowCh2 = { 0x19: 1, 0x1A: 3, 0x1D: 5, 0x1E: 7, 0x1F: 9, 0x18: 11, 0x1B: 12, 0x1C: 14 };\n\tvar rowsHighCh2 = { 0x19: 2, 0x1A: 4, 0x1D: 6, 0x1E: 8, 0x1F: 10, 0x1B: 13, 0x1C: 15 };\n\t\n\tvar backgroundColors = ['white', 'green', 'blue', 'cyan', 'red', 'yellow', 'magenta', 'black', 'transparent'];\n\t\n\t/**\n\t * Simple logger class to be able to write with time-stamps and filter on level.\n\t */\n\tvar logger = {\n\t verboseFilter: { 'DATA': 3, 'DEBUG': 3, 'INFO': 2, 'WARNING': 2, 'TEXT': 1, 'ERROR': 0 },\n\t time: null,\n\t verboseLevel: 0, // Only write errors\n\t setTime: function setTime(newTime) {\n\t this.time = newTime;\n\t },\n\t log: function log(severity, msg) {\n\t var minLevel = this.verboseFilter[severity];\n\t if (this.verboseLevel >= minLevel) {\n\t console.log(this.time + ' [' + severity + '] ' + msg);\n\t }\n\t }\n\t};\n\t\n\tvar numArrayToHexArray = function numArrayToHexArray(numArray) {\n\t var hexArray = [];\n\t for (var j = 0; j < numArray.length; j++) {\n\t hexArray.push(numArray[j].toString(16));\n\t }\n\t return hexArray;\n\t};\n\t\n\tvar PenState = function () {\n\t function PenState(foreground, underline, italics, background, flash) {\n\t _classCallCheck(this, PenState);\n\t\n\t this.foreground = foreground || 'white';\n\t this.underline = underline || false;\n\t this.italics = italics || false;\n\t this.background = background || 'black';\n\t this.flash = flash || false;\n\t }\n\t\n\t _createClass(PenState, [{\n\t key: 'reset',\n\t value: function reset() {\n\t this.foreground = 'white';\n\t this.underline = false;\n\t this.italics = false;\n\t this.background = 'black';\n\t this.flash = false;\n\t }\n\t }, {\n\t key: 'setStyles',\n\t value: function setStyles(styles) {\n\t var attribs = ['foreground', 'underline', 'italics', 'background', 'flash'];\n\t for (var i = 0; i < attribs.length; i++) {\n\t var style = attribs[i];\n\t if (styles.hasOwnProperty(style)) {\n\t this[style] = styles[style];\n\t }\n\t }\n\t }\n\t }, {\n\t key: 'isDefault',\n\t value: function isDefault() {\n\t return this.foreground === 'white' && !this.underline && !this.italics && this.background === 'black' && !this.flash;\n\t }\n\t }, {\n\t key: 'equals',\n\t value: function equals(other) {\n\t return this.foreground === other.foreground && this.underline === other.underline && this.italics === other.italics && this.background === other.background && this.flash === other.flash;\n\t }\n\t }, {\n\t key: 'copy',\n\t value: function copy(newPenState) {\n\t this.foreground = newPenState.foreground;\n\t this.underline = newPenState.underline;\n\t this.italics = newPenState.italics;\n\t this.background = newPenState.background;\n\t this.flash = newPenState.flash;\n\t }\n\t }, {\n\t key: 'toString',\n\t value: function toString() {\n\t return 'color=' + this.foreground + ', underline=' + this.underline + ', italics=' + this.italics + ', background=' + this.background + ', flash=' + this.flash;\n\t }\n\t }]);\n\t\n\t return PenState;\n\t}();\n\t\n\t/**\n\t * Unicode character with styling and background.\n\t * @constructor\n\t */\n\t\n\t\n\tvar StyledUnicodeChar = function () {\n\t function StyledUnicodeChar(uchar, foreground, underline, italics, background, flash) {\n\t _classCallCheck(this, StyledUnicodeChar);\n\t\n\t this.uchar = uchar || ' '; // unicode character\n\t this.penState = new PenState(foreground, underline, italics, background, flash);\n\t }\n\t\n\t _createClass(StyledUnicodeChar, [{\n\t key: 'reset',\n\t value: function reset() {\n\t this.uchar = ' ';\n\t this.penState.reset();\n\t }\n\t }, {\n\t key: 'setChar',\n\t value: function setChar(uchar, newPenState) {\n\t this.uchar = uchar;\n\t this.penState.copy(newPenState);\n\t }\n\t }, {\n\t key: 'setPenState',\n\t value: function setPenState(newPenState) {\n\t this.penState.copy(newPenState);\n\t }\n\t }, {\n\t key: 'equals',\n\t value: function equals(other) {\n\t return this.uchar === other.uchar && this.penState.equals(other.penState);\n\t }\n\t }, {\n\t key: 'copy',\n\t value: function copy(newChar) {\n\t this.uchar = newChar.uchar;\n\t this.penState.copy(newChar.penState);\n\t }\n\t }, {\n\t key: 'isEmpty',\n\t value: function isEmpty() {\n\t return this.uchar === ' ' && this.penState.isDefault();\n\t }\n\t }]);\n\t\n\t return StyledUnicodeChar;\n\t}();\n\t\n\t/**\n\t * CEA-608 row consisting of NR_COLS instances of StyledUnicodeChar.\n\t * @constructor\n\t */\n\t\n\t\n\tvar Row = function () {\n\t function Row() {\n\t _classCallCheck(this, Row);\n\t\n\t this.chars = [];\n\t for (var i = 0; i < NR_COLS; i++) {\n\t this.chars.push(new StyledUnicodeChar());\n\t }\n\t this.pos = 0;\n\t this.currPenState = new PenState();\n\t }\n\t\n\t _createClass(Row, [{\n\t key: 'equals',\n\t value: function equals(other) {\n\t var equal = true;\n\t for (var i = 0; i < NR_COLS; i++) {\n\t if (!this.chars[i].equals(other.chars[i])) {\n\t equal = false;\n\t break;\n\t }\n\t }\n\t return equal;\n\t }\n\t }, {\n\t key: 'copy',\n\t value: function copy(other) {\n\t for (var i = 0; i < NR_COLS; i++) {\n\t this.chars[i].copy(other.chars[i]);\n\t }\n\t }\n\t }, {\n\t key: 'isEmpty',\n\t value: function isEmpty() {\n\t var empty = true;\n\t for (var i = 0; i < NR_COLS; i++) {\n\t if (!this.chars[i].isEmpty()) {\n\t empty = false;\n\t break;\n\t }\n\t }\n\t return empty;\n\t }\n\t\n\t /**\n\t * Set the cursor to a valid column.\n\t */\n\t\n\t }, {\n\t key: 'setCursor',\n\t value: function setCursor(absPos) {\n\t if (this.pos !== absPos) {\n\t this.pos = absPos;\n\t }\n\t if (this.pos < 0) {\n\t logger.log('ERROR', 'Negative cursor position ' + this.pos);\n\t this.pos = 0;\n\t } else if (this.pos > NR_COLS) {\n\t logger.log('ERROR', 'Too large cursor position ' + this.pos);\n\t this.pos = NR_COLS;\n\t }\n\t }\n\t\n\t /**\n\t * Move the cursor relative to current position.\n\t */\n\t\n\t }, {\n\t key: 'moveCursor',\n\t value: function moveCursor(relPos) {\n\t var newPos = this.pos + relPos;\n\t if (relPos > 1) {\n\t for (var i = this.pos + 1; i < newPos + 1; i++) {\n\t this.chars[i].setPenState(this.currPenState);\n\t }\n\t }\n\t this.setCursor(newPos);\n\t }\n\t\n\t /**\n\t * Backspace, move one step back and clear character.\n\t */\n\t\n\t }, {\n\t key: 'backSpace',\n\t value: function backSpace() {\n\t this.moveCursor(-1);\n\t this.chars[this.pos].setChar(' ', this.currPenState);\n\t }\n\t }, {\n\t key: 'insertChar',\n\t value: function insertChar(byte) {\n\t if (byte >= 0x90) {\n\t //Extended char\n\t this.backSpace();\n\t }\n\t var char = getCharForByte(byte);\n\t if (this.pos >= NR_COLS) {\n\t logger.log('ERROR', 'Cannot insert ' + byte.toString(16) + ' (' + char + ') at position ' + this.pos + '. Skipping it!');\n\t return;\n\t }\n\t this.chars[this.pos].setChar(char, this.currPenState);\n\t this.moveCursor(1);\n\t }\n\t }, {\n\t key: 'clearFromPos',\n\t value: function clearFromPos(startPos) {\n\t var i;\n\t for (i = startPos; i < NR_COLS; i++) {\n\t this.chars[i].reset();\n\t }\n\t }\n\t }, {\n\t key: 'clear',\n\t value: function clear() {\n\t this.clearFromPos(0);\n\t this.pos = 0;\n\t this.currPenState.reset();\n\t }\n\t }, {\n\t key: 'clearToEndOfRow',\n\t value: function clearToEndOfRow() {\n\t this.clearFromPos(this.pos);\n\t }\n\t }, {\n\t key: 'getTextString',\n\t value: function getTextString() {\n\t var chars = [];\n\t var empty = true;\n\t for (var i = 0; i < NR_COLS; i++) {\n\t var char = this.chars[i].uchar;\n\t if (char !== ' ') {\n\t empty = false;\n\t }\n\t chars.push(char);\n\t }\n\t if (empty) {\n\t return '';\n\t } else {\n\t return chars.join('');\n\t }\n\t }\n\t }, {\n\t key: 'setPenStyles',\n\t value: function setPenStyles(styles) {\n\t this.currPenState.setStyles(styles);\n\t var currChar = this.chars[this.pos];\n\t currChar.setPenState(this.currPenState);\n\t }\n\t }]);\n\t\n\t return Row;\n\t}();\n\t\n\t/**\n\t * Keep a CEA-608 screen of 32x15 styled characters\n\t * @constructor\n\t*/\n\t\n\t\n\tvar CaptionScreen = function () {\n\t function CaptionScreen() {\n\t _classCallCheck(this, CaptionScreen);\n\t\n\t this.rows = [];\n\t for (var i = 0; i < NR_ROWS; i++) {\n\t this.rows.push(new Row()); // Note that we use zero-based numbering (0-14)\n\t }\n\t this.currRow = NR_ROWS - 1;\n\t this.nrRollUpRows = null;\n\t this.reset();\n\t }\n\t\n\t _createClass(CaptionScreen, [{\n\t key: 'reset',\n\t value: function reset() {\n\t for (var i = 0; i < NR_ROWS; i++) {\n\t this.rows[i].clear();\n\t }\n\t this.currRow = NR_ROWS - 1;\n\t }\n\t }, {\n\t key: 'equals',\n\t value: function equals(other) {\n\t var equal = true;\n\t for (var i = 0; i < NR_ROWS; i++) {\n\t if (!this.rows[i].equals(other.rows[i])) {\n\t equal = false;\n\t break;\n\t }\n\t }\n\t return equal;\n\t }\n\t }, {\n\t key: 'copy',\n\t value: function copy(other) {\n\t for (var i = 0; i < NR_ROWS; i++) {\n\t this.rows[i].copy(other.rows[i]);\n\t }\n\t }\n\t }, {\n\t key: 'isEmpty',\n\t value: function isEmpty() {\n\t var empty = true;\n\t for (var i = 0; i < NR_ROWS; i++) {\n\t if (!this.rows[i].isEmpty()) {\n\t empty = false;\n\t break;\n\t }\n\t }\n\t return empty;\n\t }\n\t }, {\n\t key: 'backSpace',\n\t value: function backSpace() {\n\t var row = this.rows[this.currRow];\n\t row.backSpace();\n\t }\n\t }, {\n\t key: 'clearToEndOfRow',\n\t value: function clearToEndOfRow() {\n\t var row = this.rows[this.currRow];\n\t row.clearToEndOfRow();\n\t }\n\t\n\t /**\n\t * Insert a character (without styling) in the current row.\n\t */\n\t\n\t }, {\n\t key: 'insertChar',\n\t value: function insertChar(char) {\n\t var row = this.rows[this.currRow];\n\t row.insertChar(char);\n\t }\n\t }, {\n\t key: 'setPen',\n\t value: function setPen(styles) {\n\t var row = this.rows[this.currRow];\n\t row.setPenStyles(styles);\n\t }\n\t }, {\n\t key: 'moveCursor',\n\t value: function moveCursor(relPos) {\n\t var row = this.rows[this.currRow];\n\t row.moveCursor(relPos);\n\t }\n\t }, {\n\t key: 'setCursor',\n\t value: function setCursor(absPos) {\n\t logger.log('INFO', 'setCursor: ' + absPos);\n\t var row = this.rows[this.currRow];\n\t row.setCursor(absPos);\n\t }\n\t }, {\n\t key: 'setPAC',\n\t value: function setPAC(pacData) {\n\t logger.log('INFO', 'pacData = ' + JSON.stringify(pacData));\n\t var newRow = pacData.row - 1;\n\t if (this.nrRollUpRows && newRow < this.nrRollUpRows - 1) {\n\t newRow = this.nrRollUpRows - 1;\n\t }\n\t this.currRow = newRow;\n\t var row = this.rows[this.currRow];\n\t if (pacData.indent !== null) {\n\t var indent = pacData.indent;\n\t var prevPos = Math.max(indent - 1, 0);\n\t row.setCursor(pacData.indent);\n\t pacData.color = row.chars[prevPos].penState.foreground;\n\t }\n\t var styles = { foreground: pacData.color, underline: pacData.underline, italics: pacData.italics, background: 'black', flash: false };\n\t this.setPen(styles);\n\t }\n\t\n\t /**\n\t * Set background/extra foreground, but first do back_space, and then insert space (backwards compatibility).\n\t */\n\t\n\t }, {\n\t key: 'setBkgData',\n\t value: function setBkgData(bkgData) {\n\t\n\t logger.log('INFO', 'bkgData = ' + JSON.stringify(bkgData));\n\t this.backSpace();\n\t this.setPen(bkgData);\n\t this.insertChar(0x20); //Space\n\t }\n\t }, {\n\t key: 'setRollUpRows',\n\t value: function setRollUpRows(nrRows) {\n\t this.nrRollUpRows = nrRows;\n\t }\n\t }, {\n\t key: 'rollUp',\n\t value: function rollUp() {\n\t if (this.nrRollUpRows === null) {\n\t logger.log('DEBUG', 'roll_up but nrRollUpRows not set yet');\n\t return; //Not properly setup\n\t }\n\t logger.log('TEXT', this.getDisplayText());\n\t var topRowIndex = this.currRow + 1 - this.nrRollUpRows;\n\t var topRow = this.rows.splice(topRowIndex, 1)[0];\n\t topRow.clear();\n\t this.rows.splice(this.currRow, 0, topRow);\n\t logger.log('INFO', 'Rolling up');\n\t //logger.log('TEXT', this.get_display_text())\n\t }\n\t\n\t /**\n\t * Get all non-empty rows with as unicode text.\n\t */\n\t\n\t }, {\n\t key: 'getDisplayText',\n\t value: function getDisplayText(asOneRow) {\n\t asOneRow = asOneRow || false;\n\t var displayText = [];\n\t var text = '';\n\t var rowNr = -1;\n\t for (var i = 0; i < NR_ROWS; i++) {\n\t var rowText = this.rows[i].getTextString();\n\t if (rowText) {\n\t rowNr = i + 1;\n\t if (asOneRow) {\n\t displayText.push('Row ' + rowNr + ': \\'' + rowText + '\\'');\n\t } else {\n\t displayText.push(rowText.trim());\n\t }\n\t }\n\t }\n\t if (displayText.length > 0) {\n\t if (asOneRow) {\n\t text = '[' + displayText.join(' | ') + ']';\n\t } else {\n\t text = displayText.join('\\n');\n\t }\n\t }\n\t return text;\n\t }\n\t }, {\n\t key: 'getTextAndFormat',\n\t value: function getTextAndFormat() {\n\t return this.rows;\n\t }\n\t }]);\n\t\n\t return CaptionScreen;\n\t}();\n\t\n\t//var modes = ['MODE_ROLL-UP', 'MODE_POP-ON', 'MODE_PAINT-ON', 'MODE_TEXT'];\n\t\n\tvar Cea608Channel = function () {\n\t function Cea608Channel(channelNumber, outputFilter) {\n\t _classCallCheck(this, Cea608Channel);\n\t\n\t this.chNr = channelNumber;\n\t this.outputFilter = outputFilter;\n\t this.mode = null;\n\t this.verbose = 0;\n\t this.displayedMemory = new CaptionScreen();\n\t this.nonDisplayedMemory = new CaptionScreen();\n\t this.lastOutputScreen = new CaptionScreen();\n\t this.currRollUpRow = this.displayedMemory.rows[NR_ROWS - 1];\n\t this.writeScreen = this.displayedMemory;\n\t this.mode = null;\n\t this.cueStartTime = null; // Keeps track of where a cue started.\n\t }\n\t\n\t _createClass(Cea608Channel, [{\n\t key: 'reset',\n\t value: function reset() {\n\t this.mode = null;\n\t this.displayedMemory.reset();\n\t this.nonDisplayedMemory.reset();\n\t this.lastOutputScreen.reset();\n\t this.currRollUpRow = this.displayedMemory.rows[NR_ROWS - 1];\n\t this.writeScreen = this.displayedMemory;\n\t this.mode = null;\n\t this.cueStartTime = null;\n\t this.lastCueEndTime = null;\n\t }\n\t }, {\n\t key: 'getHandler',\n\t value: function getHandler() {\n\t return this.outputFilter;\n\t }\n\t }, {\n\t key: 'setHandler',\n\t value: function setHandler(newHandler) {\n\t this.outputFilter = newHandler;\n\t }\n\t }, {\n\t key: 'setPAC',\n\t value: function setPAC(pacData) {\n\t this.writeScreen.setPAC(pacData);\n\t }\n\t }, {\n\t key: 'setBkgData',\n\t value: function setBkgData(bkgData) {\n\t this.writeScreen.setBkgData(bkgData);\n\t }\n\t }, {\n\t key: 'setMode',\n\t value: function setMode(newMode) {\n\t if (newMode === this.mode) {\n\t return;\n\t }\n\t this.mode = newMode;\n\t logger.log('INFO', 'MODE=' + newMode);\n\t if (this.mode === 'MODE_POP-ON') {\n\t this.writeScreen = this.nonDisplayedMemory;\n\t } else {\n\t this.writeScreen = this.displayedMemory;\n\t this.writeScreen.reset();\n\t }\n\t if (this.mode !== 'MODE_ROLL-UP') {\n\t this.displayedMemory.nrRollUpRows = null;\n\t this.nonDisplayedMemory.nrRollUpRows = null;\n\t }\n\t this.mode = newMode;\n\t }\n\t }, {\n\t key: 'insertChars',\n\t value: function insertChars(chars) {\n\t for (var i = 0; i < chars.length; i++) {\n\t this.writeScreen.insertChar(chars[i]);\n\t }\n\t var screen = this.writeScreen === this.displayedMemory ? 'DISP' : 'NON_DISP';\n\t logger.log('INFO', screen + ': ' + this.writeScreen.getDisplayText(true));\n\t if (this.mode === 'MODE_PAINT-ON' || this.mode === 'MODE_ROLL-UP') {\n\t logger.log('TEXT', 'DISPLAYED: ' + this.displayedMemory.getDisplayText(true));\n\t this.outputDataUpdate();\n\t }\n\t }\n\t }, {\n\t key: 'ccRCL',\n\t value: function ccRCL() {\n\t // Resume Caption Loading (switch mode to Pop On)\n\t logger.log('INFO', 'RCL - Resume Caption Loading');\n\t this.setMode('MODE_POP-ON');\n\t }\n\t }, {\n\t key: 'ccBS',\n\t value: function ccBS() {\n\t // BackSpace\n\t logger.log('INFO', 'BS - BackSpace');\n\t if (this.mode === 'MODE_TEXT') {\n\t return;\n\t }\n\t this.writeScreen.backSpace();\n\t if (this.writeScreen === this.displayedMemory) {\n\t this.outputDataUpdate();\n\t }\n\t }\n\t }, {\n\t key: 'ccAOF',\n\t value: function ccAOF() {\n\t // Reserved (formerly Alarm Off)\n\t return;\n\t }\n\t }, {\n\t key: 'ccAON',\n\t value: function ccAON() {\n\t // Reserved (formerly Alarm On)\n\t return;\n\t }\n\t }, {\n\t key: 'ccDER',\n\t value: function ccDER() {\n\t // Delete to End of Row\n\t logger.log('INFO', 'DER- Delete to End of Row');\n\t this.writeScreen.clearToEndOfRow();\n\t this.outputDataUpdate();\n\t }\n\t }, {\n\t key: 'ccRU',\n\t value: function ccRU(nrRows) {\n\t //Roll-Up Captions-2,3,or 4 Rows\n\t logger.log('INFO', 'RU(' + nrRows + ') - Roll Up');\n\t this.writeScreen = this.displayedMemory;\n\t this.setMode('MODE_ROLL-UP');\n\t this.writeScreen.setRollUpRows(nrRows);\n\t }\n\t }, {\n\t key: 'ccFON',\n\t value: function ccFON() {\n\t //Flash On\n\t logger.log('INFO', 'FON - Flash On');\n\t this.writeScreen.setPen({ flash: true });\n\t }\n\t }, {\n\t key: 'ccRDC',\n\t value: function ccRDC() {\n\t // Resume Direct Captioning (switch mode to PaintOn)\n\t logger.log('INFO', 'RDC - Resume Direct Captioning');\n\t this.setMode('MODE_PAINT-ON');\n\t }\n\t }, {\n\t key: 'ccTR',\n\t value: function ccTR() {\n\t // Text Restart in text mode (not supported, however)\n\t logger.log('INFO', 'TR');\n\t this.setMode('MODE_TEXT');\n\t }\n\t }, {\n\t key: 'ccRTD',\n\t value: function ccRTD() {\n\t // Resume Text Display in Text mode (not supported, however)\n\t logger.log('INFO', 'RTD');\n\t this.setMode('MODE_TEXT');\n\t }\n\t }, {\n\t key: 'ccEDM',\n\t value: function ccEDM() {\n\t // Erase Displayed Memory\n\t logger.log('INFO', 'EDM - Erase Displayed Memory');\n\t this.displayedMemory.reset();\n\t this.outputDataUpdate();\n\t }\n\t }, {\n\t key: 'ccCR',\n\t value: function ccCR() {\n\t // Carriage Return\n\t logger.log('CR - Carriage Return');\n\t this.writeScreen.rollUp();\n\t this.outputDataUpdate();\n\t }\n\t }, {\n\t key: 'ccENM',\n\t value: function ccENM() {\n\t //Erase Non-Displayed Memory\n\t logger.log('INFO', 'ENM - Erase Non-displayed Memory');\n\t this.nonDisplayedMemory.reset();\n\t }\n\t }, {\n\t key: 'ccEOC',\n\t value: function ccEOC() {\n\t //End of Caption (Flip Memories)\n\t logger.log('INFO', 'EOC - End Of Caption');\n\t if (this.mode === 'MODE_POP-ON') {\n\t var tmp = this.displayedMemory;\n\t this.displayedMemory = this.nonDisplayedMemory;\n\t this.nonDisplayedMemory = tmp;\n\t this.writeScreen = this.nonDisplayedMemory;\n\t logger.log('TEXT', 'DISP: ' + this.displayedMemory.getDisplayText());\n\t }\n\t this.outputDataUpdate();\n\t }\n\t }, {\n\t key: 'ccTO',\n\t value: function ccTO(nrCols) {\n\t // Tab Offset 1,2, or 3 columns\n\t logger.log('INFO', 'TO(' + nrCols + ') - Tab Offset');\n\t this.writeScreen.moveCursor(nrCols);\n\t }\n\t }, {\n\t key: 'ccMIDROW',\n\t value: function ccMIDROW(secondByte) {\n\t // Parse MIDROW command\n\t var styles = { flash: false };\n\t styles.underline = secondByte % 2 === 1;\n\t styles.italics = secondByte >= 0x2e;\n\t if (!styles.italics) {\n\t var colorIndex = Math.floor(secondByte / 2) - 0x10;\n\t var colors = ['white', 'green', 'blue', 'cyan', 'red', 'yellow', 'magenta'];\n\t styles.foreground = colors[colorIndex];\n\t } else {\n\t styles.foreground = 'white';\n\t }\n\t logger.log('INFO', 'MIDROW: ' + JSON.stringify(styles));\n\t this.writeScreen.setPen(styles);\n\t }\n\t }, {\n\t key: 'outputDataUpdate',\n\t value: function outputDataUpdate() {\n\t var t = logger.time;\n\t if (t === null) {\n\t return;\n\t }\n\t if (this.outputFilter) {\n\t if (this.outputFilter.updateData) {\n\t this.outputFilter.updateData(t, this.displayedMemory);\n\t }\n\t if (this.cueStartTime === null && !this.displayedMemory.isEmpty()) {\n\t // Start of a new cue\n\t this.cueStartTime = t;\n\t } else {\n\t if (!this.displayedMemory.equals(this.lastOutputScreen)) {\n\t if (this.outputFilter.newCue) {\n\t this.outputFilter.newCue(this.cueStartTime, t, this.lastOutputScreen);\n\t }\n\t this.cueStartTime = this.displayedMemory.isEmpty() ? null : t;\n\t }\n\t }\n\t this.lastOutputScreen.copy(this.displayedMemory);\n\t }\n\t }\n\t }, {\n\t key: 'cueSplitAtTime',\n\t value: function cueSplitAtTime(t) {\n\t if (this.outputFilter) {\n\t if (!this.displayedMemory.isEmpty()) {\n\t if (this.outputFilter.newCue) {\n\t this.outputFilter.newCue(this.cueStartTime, t, this.displayedMemory);\n\t }\n\t this.cueStartTime = t;\n\t }\n\t }\n\t }\n\t }]);\n\t\n\t return Cea608Channel;\n\t}();\n\t\n\tvar Cea608Parser = function () {\n\t function Cea608Parser(field, out1, out2) {\n\t _classCallCheck(this, Cea608Parser);\n\t\n\t this.field = field || 1;\n\t this.outputs = [out1, out2];\n\t this.channels = [new Cea608Channel(1, out1), new Cea608Channel(2, out2)];\n\t this.currChNr = -1; // Will be 1 or 2\n\t this.lastCmdA = null; // First byte of last command\n\t this.lastCmdB = null; // Second byte of last command\n\t this.bufferedData = [];\n\t this.startTime = null;\n\t this.lastTime = null;\n\t this.dataCounters = { 'padding': 0, 'char': 0, 'cmd': 0, 'other': 0 };\n\t }\n\t\n\t _createClass(Cea608Parser, [{\n\t key: 'getHandler',\n\t value: function getHandler(index) {\n\t return this.channels[index].getHandler();\n\t }\n\t }, {\n\t key: 'setHandler',\n\t value: function setHandler(index, newHandler) {\n\t this.channels[index].setHandler(newHandler);\n\t }\n\t\n\t /**\n\t * Add data for time t in forms of list of bytes (unsigned ints). The bytes are treated as pairs.\n\t */\n\t\n\t }, {\n\t key: 'addData',\n\t value: function addData(t, byteList) {\n\t var cmdFound,\n\t a,\n\t b,\n\t charsFound = false;\n\t\n\t this.lastTime = t;\n\t logger.setTime(t);\n\t\n\t for (var i = 0; i < byteList.length; i += 2) {\n\t a = byteList[i] & 0x7f;\n\t b = byteList[i + 1] & 0x7f;\n\t if (a === 0 && b === 0) {\n\t this.dataCounters.padding += 2;\n\t continue;\n\t } else {\n\t logger.log('DATA', '[' + numArrayToHexArray([byteList[i], byteList[i + 1]]) + '] -> (' + numArrayToHexArray([a, b]) + ')');\n\t }\n\t cmdFound = this.parseCmd(a, b);\n\t if (!cmdFound) {\n\t cmdFound = this.parseMidrow(a, b);\n\t }\n\t if (!cmdFound) {\n\t cmdFound = this.parsePAC(a, b);\n\t }\n\t if (!cmdFound) {\n\t cmdFound = this.parseBackgroundAttributes(a, b);\n\t }\n\t if (!cmdFound) {\n\t charsFound = this.parseChars(a, b);\n\t if (charsFound) {\n\t if (this.currChNr && this.currChNr >= 0) {\n\t var channel = this.channels[this.currChNr - 1];\n\t channel.insertChars(charsFound);\n\t } else {\n\t logger.log('WARNING', 'No channel found yet. TEXT-MODE?');\n\t }\n\t }\n\t }\n\t if (cmdFound) {\n\t this.dataCounters.cmd += 2;\n\t } else if (charsFound) {\n\t this.dataCounters.char += 2;\n\t } else {\n\t this.dataCounters.other += 2;\n\t logger.log('WARNING', 'Couldn\\'t parse cleaned data ' + numArrayToHexArray([a, b]) + ' orig: ' + numArrayToHexArray([byteList[i], byteList[i + 1]]));\n\t }\n\t }\n\t }\n\t\n\t /**\n\t * Parse Command.\n\t * @returns {Boolean} Tells if a command was found\n\t */\n\t\n\t }, {\n\t key: 'parseCmd',\n\t value: function parseCmd(a, b) {\n\t var chNr = null;\n\t\n\t var cond1 = (a === 0x14 || a === 0x1C) && 0x20 <= b && b <= 0x2F;\n\t var cond2 = (a === 0x17 || a === 0x1F) && 0x21 <= b && b <= 0x23;\n\t if (!(cond1 || cond2)) {\n\t return false;\n\t }\n\t\n\t if (a === this.lastCmdA && b === this.lastCmdB) {\n\t this.lastCmdA = null;\n\t this.lastCmdB = null; // Repeated commands are dropped (once)\n\t logger.log('DEBUG', 'Repeated command (' + numArrayToHexArray([a, b]) + ') is dropped');\n\t return true;\n\t }\n\t\n\t if (a === 0x14 || a === 0x17) {\n\t chNr = 1;\n\t } else {\n\t chNr = 2; // (a === 0x1C || a=== 0x1f)\n\t }\n\t\n\t var channel = this.channels[chNr - 1];\n\t\n\t if (a === 0x14 || a === 0x1C) {\n\t if (b === 0x20) {\n\t channel.ccRCL();\n\t } else if (b === 0x21) {\n\t channel.ccBS();\n\t } else if (b === 0x22) {\n\t channel.ccAOF();\n\t } else if (b === 0x23) {\n\t channel.ccAON();\n\t } else if (b === 0x24) {\n\t channel.ccDER();\n\t } else if (b === 0x25) {\n\t channel.ccRU(2);\n\t } else if (b === 0x26) {\n\t channel.ccRU(3);\n\t } else if (b === 0x27) {\n\t channel.ccRU(4);\n\t } else if (b === 0x28) {\n\t channel.ccFON();\n\t } else if (b === 0x29) {\n\t channel.ccRDC();\n\t } else if (b === 0x2A) {\n\t channel.ccTR();\n\t } else if (b === 0x2B) {\n\t channel.ccRTD();\n\t } else if (b === 0x2C) {\n\t channel.ccEDM();\n\t } else if (b === 0x2D) {\n\t channel.ccCR();\n\t } else if (b === 0x2E) {\n\t channel.ccENM();\n\t } else if (b === 0x2F) {\n\t channel.ccEOC();\n\t }\n\t } else {\n\t //a == 0x17 || a == 0x1F\n\t channel.ccTO(b - 0x20);\n\t }\n\t this.lastCmdA = a;\n\t this.lastCmdB = b;\n\t this.currChNr = chNr;\n\t return true;\n\t }\n\t\n\t /**\n\t * Parse midrow styling command\n\t * @returns {Boolean}\n\t */\n\t\n\t }, {\n\t key: 'parseMidrow',\n\t value: function parseMidrow(a, b) {\n\t var chNr = null;\n\t\n\t if ((a === 0x11 || a === 0x19) && 0x20 <= b && b <= 0x2f) {\n\t if (a === 0x11) {\n\t chNr = 1;\n\t } else {\n\t chNr = 2;\n\t }\n\t if (chNr !== this.currChNr) {\n\t logger.log('ERROR', 'Mismatch channel in midrow parsing');\n\t return false;\n\t }\n\t var channel = this.channels[chNr - 1];\n\t channel.ccMIDROW(b);\n\t logger.log('DEBUG', 'MIDROW (' + numArrayToHexArray([a, b]) + ')');\n\t return true;\n\t }\n\t return false;\n\t }\n\t /**\n\t * Parse Preable Access Codes (Table 53).\n\t * @returns {Boolean} Tells if PAC found\n\t */\n\t\n\t }, {\n\t key: 'parsePAC',\n\t value: function parsePAC(a, b) {\n\t\n\t var chNr = null;\n\t var row = null;\n\t\n\t var case1 = (0x11 <= a && a <= 0x17 || 0x19 <= a && a <= 0x1F) && 0x40 <= b && b <= 0x7F;\n\t var case2 = (a === 0x10 || a === 0x18) && 0x40 <= b && b <= 0x5F;\n\t if (!(case1 || case2)) {\n\t return false;\n\t }\n\t\n\t if (a === this.lastCmdA && b === this.lastCmdB) {\n\t this.lastCmdA = null;\n\t this.lastCmdB = null;\n\t return true; // Repeated commands are dropped (once)\n\t }\n\t\n\t chNr = a <= 0x17 ? 1 : 2;\n\t\n\t if (0x40 <= b && b <= 0x5F) {\n\t row = chNr === 1 ? rowsLowCh1[a] : rowsLowCh2[a];\n\t } else {\n\t // 0x60 <= b <= 0x7F\n\t row = chNr === 1 ? rowsHighCh1[a] : rowsHighCh2[a];\n\t }\n\t var pacData = this.interpretPAC(row, b);\n\t var channel = this.channels[chNr - 1];\n\t channel.setPAC(pacData);\n\t this.lastCmdA = a;\n\t this.lastCmdB = b;\n\t this.currChNr = chNr;\n\t return true;\n\t }\n\t\n\t /**\n\t * Interpret the second byte of the pac, and return the information.\n\t * @returns {Object} pacData with style parameters.\n\t */\n\t\n\t }, {\n\t key: 'interpretPAC',\n\t value: function interpretPAC(row, byte) {\n\t var pacIndex = byte;\n\t var pacData = { color: null, italics: false, indent: null, underline: false, row: row };\n\t\n\t if (byte > 0x5F) {\n\t pacIndex = byte - 0x60;\n\t } else {\n\t pacIndex = byte - 0x40;\n\t }\n\t pacData.underline = (pacIndex & 1) === 1;\n\t if (pacIndex <= 0xd) {\n\t pacData.color = ['white', 'green', 'blue', 'cyan', 'red', 'yellow', 'magenta', 'white'][Math.floor(pacIndex / 2)];\n\t } else if (pacIndex <= 0xf) {\n\t pacData.italics = true;\n\t pacData.color = 'white';\n\t } else {\n\t pacData.indent = Math.floor((pacIndex - 0x10) / 2) * 4;\n\t }\n\t return pacData; // Note that row has zero offset. The spec uses 1.\n\t }\n\t\n\t /**\n\t * Parse characters.\n\t * @returns An array with 1 to 2 codes corresponding to chars, if found. null otherwise.\n\t */\n\t\n\t }, {\n\t key: 'parseChars',\n\t value: function parseChars(a, b) {\n\t\n\t var channelNr = null,\n\t charCodes = null,\n\t charCode1 = null;\n\t\n\t if (a >= 0x19) {\n\t channelNr = 2;\n\t charCode1 = a - 8;\n\t } else {\n\t channelNr = 1;\n\t charCode1 = a;\n\t }\n\t if (0x11 <= charCode1 && charCode1 <= 0x13) {\n\t // Special character\n\t var oneCode = b;\n\t if (charCode1 === 0x11) {\n\t oneCode = b + 0x50;\n\t } else if (charCode1 === 0x12) {\n\t oneCode = b + 0x70;\n\t } else {\n\t oneCode = b + 0x90;\n\t }\n\t logger.log('INFO', 'Special char \\'' + getCharForByte(oneCode) + '\\' in channel ' + channelNr);\n\t charCodes = [oneCode];\n\t } else if (0x20 <= a && a <= 0x7f) {\n\t charCodes = b === 0 ? [a] : [a, b];\n\t }\n\t if (charCodes) {\n\t var hexCodes = numArrayToHexArray(charCodes);\n\t logger.log('DEBUG', 'Char codes = ' + hexCodes.join(','));\n\t this.lastCmdA = null;\n\t this.lastCmdB = null;\n\t }\n\t return charCodes;\n\t }\n\t\n\t /**\n\t * Parse extended background attributes as well as new foreground color black.\n\t * @returns{Boolean} Tells if background attributes are found\n\t */\n\t\n\t }, {\n\t key: 'parseBackgroundAttributes',\n\t value: function parseBackgroundAttributes(a, b) {\n\t var bkgData, index, chNr, channel;\n\t\n\t var case1 = (a === 0x10 || a === 0x18) && 0x20 <= b && b <= 0x2f;\n\t var case2 = (a === 0x17 || a === 0x1f) && 0x2d <= b && b <= 0x2f;\n\t if (!(case1 || case2)) {\n\t return false;\n\t }\n\t bkgData = {};\n\t if (a === 0x10 || a === 0x18) {\n\t index = Math.floor((b - 0x20) / 2);\n\t bkgData.background = backgroundColors[index];\n\t if (b % 2 === 1) {\n\t bkgData.background = bkgData.background + '_semi';\n\t }\n\t } else if (b === 0x2d) {\n\t bkgData.background = 'transparent';\n\t } else {\n\t bkgData.foreground = 'black';\n\t if (b === 0x2f) {\n\t bkgData.underline = true;\n\t }\n\t }\n\t chNr = a < 0x18 ? 1 : 2;\n\t channel = this.channels[chNr - 1];\n\t channel.setBkgData(bkgData);\n\t this.lastCmdA = null;\n\t this.lastCmdB = null;\n\t return true;\n\t }\n\t\n\t /**\n\t * Reset state of parser and its channels.\n\t */\n\t\n\t }, {\n\t key: 'reset',\n\t value: function reset() {\n\t for (var i = 0; i < this.channels.length; i++) {\n\t if (this.channels[i]) {\n\t this.channels[i].reset();\n\t }\n\t }\n\t this.lastCmdA = null;\n\t this.lastCmdB = null;\n\t }\n\t\n\t /**\n\t * Trigger the generation of a cue, and the start of a new one if displayScreens are not empty.\n\t */\n\t\n\t }, {\n\t key: 'cueSplitAtTime',\n\t value: function cueSplitAtTime(t) {\n\t for (var i = 0; i < this.channels.length; i++) {\n\t if (this.channels[i]) {\n\t this.channels[i].cueSplitAtTime(t);\n\t }\n\t }\n\t }\n\t }]);\n\t\n\t return Cea608Parser;\n\t}();\n\t\n\texports.default = Cea608Parser;\n\t\n\t},{}],41:[function(_dereq_,module,exports){\n\t'use strict';\n\t\n\tvar Cues = {\n\t\n\t newCue: function newCue(track, startTime, endTime, captionScreen) {\n\t var row;\n\t var cue;\n\t var indenting;\n\t var indent;\n\t var text;\n\t var VTTCue = window.VTTCue || window.TextTrackCue;\n\t\n\t for (var r = 0; r < captionScreen.rows.length; r++) {\n\t row = captionScreen.rows[r];\n\t indenting = true;\n\t indent = 0;\n\t text = '';\n\t\n\t if (!row.isEmpty()) {\n\t for (var c = 0; c < row.chars.length; c++) {\n\t if (row.chars[c].uchar.match(/\\s/) && indenting) {\n\t indent++;\n\t } else {\n\t text += row.chars[c].uchar;\n\t indenting = false;\n\t }\n\t }\n\t cue = new VTTCue(startTime, endTime, text.trim());\n\t\n\t if (indent >= 16) {\n\t indent--;\n\t } else {\n\t indent++;\n\t }\n\t\n\t // VTTCue.line get's flakey when using controls, so let's now include line 13&14\n\t // also, drop line 1 since it's to close to the top\n\t if (navigator.userAgent.match(/Firefox\\//)) {\n\t cue.line = r + 1;\n\t } else {\n\t cue.line = r > 7 ? r - 2 : r + 1;\n\t }\n\t cue.align = 'left';\n\t cue.position = 100 * (indent / 32) + (navigator.userAgent.match(/Firefox\\//) ? 50 : 0);\n\t track.addCue(cue);\n\t }\n\t }\n\t }\n\t\n\t};\n\t\n\tmodule.exports = Cues;\n\t\n\t},{}],42:[function(_dereq_,module,exports){\n\t\"use strict\";\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t\n\tvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\t\n\tfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\t\n\t/*\n\t * compute an Exponential Weighted moving average\n\t * - https://en.wikipedia.org/wiki/Moving_average#Exponential_moving_average\n\t * - heavily inspired from shaka-player\n\t */\n\t\n\tvar EWMA = function () {\n\t\n\t // About half of the estimated value will be from the last |halfLife| samples by weight.\n\t\n\t function EWMA(halfLife) {\n\t _classCallCheck(this, EWMA);\n\t\n\t // Larger values of alpha expire historical data more slowly.\n\t this.alpha_ = halfLife ? Math.exp(Math.log(0.5) / halfLife) : 0;\n\t this.estimate_ = 0;\n\t this.totalWeight_ = 0;\n\t }\n\t\n\t _createClass(EWMA, [{\n\t key: \"sample\",\n\t value: function sample(weight, value) {\n\t var adjAlpha = Math.pow(this.alpha_, weight);\n\t this.estimate_ = value * (1 - adjAlpha) + adjAlpha * this.estimate_;\n\t this.totalWeight_ += weight;\n\t }\n\t }, {\n\t key: \"getTotalWeight\",\n\t value: function getTotalWeight() {\n\t return this.totalWeight_;\n\t }\n\t }, {\n\t key: \"getEstimate\",\n\t value: function getEstimate() {\n\t if (this.alpha_) {\n\t var zeroFactor = 1 - Math.pow(this.alpha_, this.totalWeight_);\n\t return this.estimate_ / zeroFactor;\n\t } else {\n\t return this.estimate_;\n\t }\n\t }\n\t }]);\n\t\n\t return EWMA;\n\t}();\n\t\n\texports.default = EWMA;\n\t\n\t},{}],43:[function(_dereq_,module,exports){\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t\n\tvar _typeof = typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol ? \"symbol\" : typeof obj; };\n\t\n\tfunction noop() {}\n\t\n\tvar fakeLogger = {\n\t trace: noop,\n\t debug: noop,\n\t log: noop,\n\t warn: noop,\n\t info: noop,\n\t error: noop\n\t};\n\t\n\tvar exportedLogger = fakeLogger;\n\t\n\t/*globals self: false */\n\t\n\t//let lastCallTime;\n\t// function formatMsgWithTimeInfo(type, msg) {\n\t// const now = Date.now();\n\t// const diff = lastCallTime ? '+' + (now - lastCallTime) : '0';\n\t// lastCallTime = now;\n\t// msg = (new Date(now)).toISOString() + ' | [' + type + '] > ' + msg + ' ( ' + diff + ' ms )';\n\t// return msg;\n\t// }\n\t\n\tfunction formatMsg(type, msg) {\n\t msg = '[' + type + '] > ' + msg;\n\t return msg;\n\t}\n\t\n\tfunction consolePrintFn(type) {\n\t var func = self.console[type];\n\t if (func) {\n\t return function () {\n\t for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {\n\t args[_key] = arguments[_key];\n\t }\n\t\n\t if (args[0]) {\n\t args[0] = formatMsg(type, args[0]);\n\t }\n\t func.apply(self.console, args);\n\t };\n\t }\n\t return noop;\n\t}\n\t\n\tfunction exportLoggerFunctions(debugConfig) {\n\t for (var _len2 = arguments.length, functions = Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {\n\t functions[_key2 - 1] = arguments[_key2];\n\t }\n\t\n\t functions.forEach(function (type) {\n\t exportedLogger[type] = debugConfig[type] ? debugConfig[type].bind(debugConfig) : consolePrintFn(type);\n\t });\n\t}\n\t\n\tvar enableLogs = exports.enableLogs = function enableLogs(debugConfig) {\n\t if (debugConfig === true || (typeof debugConfig === 'undefined' ? 'undefined' : _typeof(debugConfig)) === 'object') {\n\t exportLoggerFunctions(debugConfig,\n\t // Remove out from list here to hard-disable a log-level\n\t //'trace',\n\t 'debug', 'log', 'info', 'warn', 'error');\n\t // Some browsers don't allow to use bind on console object anyway\n\t // fallback to default if needed\n\t try {\n\t exportedLogger.log();\n\t } catch (e) {\n\t exportedLogger = fakeLogger;\n\t }\n\t } else {\n\t exportedLogger = fakeLogger;\n\t }\n\t};\n\t\n\tvar logger = exports.logger = exportedLogger;\n\t\n\t},{}],44:[function(_dereq_,module,exports){\n\t'use strict';\n\t\n\tif (typeof ArrayBuffer !== 'undefined' && !ArrayBuffer.prototype.slice) {\n\t ArrayBuffer.prototype.slice = function (start, end) {\n\t var that = new Uint8Array(this);\n\t if (end === undefined) {\n\t end = that.length;\n\t }\n\t var result = new ArrayBuffer(end - start);\n\t var resultArray = new Uint8Array(result);\n\t for (var i = 0; i < resultArray.length; i++) {\n\t resultArray[i] = that[i + start];\n\t }\n\t return result;\n\t };\n\t}\n\t\n\t},{}],45:[function(_dereq_,module,exports){\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t\n\tvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\t\n\tfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\t\n\t/**\n\t * TimeRanges to string helper\n\t */\n\t\n\tvar TimeRanges = function () {\n\t function TimeRanges() {\n\t _classCallCheck(this, TimeRanges);\n\t }\n\t\n\t _createClass(TimeRanges, null, [{\n\t key: 'toString',\n\t value: function toString(r) {\n\t var log = '',\n\t len = r.length;\n\t for (var i = 0; i < len; i++) {\n\t log += '[' + r.start(i).toFixed(3) + ',' + r.end(i).toFixed(3) + ']';\n\t }\n\t return log;\n\t }\n\t }]);\n\t\n\t return TimeRanges;\n\t}();\n\t\n\texports.default = TimeRanges;\n\t\n\t},{}],46:[function(_dereq_,module,exports){\n\t'use strict';\n\t\n\tvar URLHelper = {\n\t // build an absolute URL from a relative one using the provided baseURL\n\t // if relativeURL is an absolute URL it will be returned as is.\n\t buildAbsoluteURL: function buildAbsoluteURL(baseURL, relativeURL) {\n\t // remove any remaining space and CRLF\n\t relativeURL = relativeURL.trim();\n\t if (/^[a-z]+:/i.test(relativeURL)) {\n\t // complete url, not relative\n\t return relativeURL;\n\t }\n\t\n\t var relativeURLQuery = null;\n\t var relativeURLHash = null;\n\t\n\t var relativeURLHashSplit = /^([^#]*)(.*)$/.exec(relativeURL);\n\t if (relativeURLHashSplit) {\n\t relativeURLHash = relativeURLHashSplit[2];\n\t relativeURL = relativeURLHashSplit[1];\n\t }\n\t var relativeURLQuerySplit = /^([^\\?]*)(.*)$/.exec(relativeURL);\n\t if (relativeURLQuerySplit) {\n\t relativeURLQuery = relativeURLQuerySplit[2];\n\t relativeURL = relativeURLQuerySplit[1];\n\t }\n\t\n\t var baseURLHashSplit = /^([^#]*)(.*)$/.exec(baseURL);\n\t if (baseURLHashSplit) {\n\t baseURL = baseURLHashSplit[1];\n\t }\n\t var baseURLQuerySplit = /^([^\\?]*)(.*)$/.exec(baseURL);\n\t if (baseURLQuerySplit) {\n\t baseURL = baseURLQuerySplit[1];\n\t }\n\t\n\t var baseURLDomainSplit = /^(([a-z]+:)?\\/\\/[a-z0-9\\.\\-_~]+(:[0-9]+)?)?(\\/.*)$/i.exec(baseURL);\n\t if (!baseURLDomainSplit) {\n\t throw new Error('Error trying to parse base URL.');\n\t }\n\t\n\t // e.g. 'http:', 'https:', ''\n\t var baseURLProtocol = baseURLDomainSplit[2] || '';\n\t // e.g. 'http://example.com', '//example.com', ''\n\t var baseURLProtocolDomain = baseURLDomainSplit[1] || '';\n\t // e.g. '/a/b/c/playlist.m3u8'\n\t var baseURLPath = baseURLDomainSplit[4];\n\t\n\t var builtURL = null;\n\t if (/^\\/\\//.test(relativeURL)) {\n\t // relative url starts wth '//' so copy protocol (which may be '' if baseUrl didn't provide one)\n\t builtURL = baseURLProtocol + '//' + URLHelper.buildAbsolutePath('', relativeURL.substring(2));\n\t } else if (/^\\//.test(relativeURL)) {\n\t // relative url starts with '/' so start from root of domain\n\t builtURL = baseURLProtocolDomain + '/' + URLHelper.buildAbsolutePath('', relativeURL.substring(1));\n\t } else {\n\t builtURL = URLHelper.buildAbsolutePath(baseURLProtocolDomain + baseURLPath, relativeURL);\n\t }\n\t\n\t // put the query and hash parts back\n\t if (relativeURLQuery) {\n\t builtURL += relativeURLQuery;\n\t }\n\t if (relativeURLHash) {\n\t builtURL += relativeURLHash;\n\t }\n\t return builtURL;\n\t },\n\t\n\t // build an absolute path using the provided basePath\n\t // adapted from https://developer.mozilla.org/en-US/docs/Web/API/document/cookie#Using_relative_URLs_in_the_path_parameter\n\t // this does not handle the case where relativePath is \"/\" or \"//\". These cases should be handled outside this.\n\t buildAbsolutePath: function buildAbsolutePath(basePath, relativePath) {\n\t var sRelPath = relativePath;\n\t var nUpLn,\n\t sDir = '',\n\t sPath = basePath.replace(/[^\\/]*$/, sRelPath.replace(/(\\/|^)(?:\\.?\\/+)+/g, '$1'));\n\t for (var nEnd, nStart = 0; nEnd = sPath.indexOf('/../', nStart), nEnd > -1; nStart = nEnd + nUpLn) {\n\t nUpLn = /^\\/(?:\\.\\.\\/)*/.exec(sPath.slice(nEnd))[0].length;\n\t sDir = (sDir + sPath.substring(nStart, nEnd)).replace(new RegExp('(?:\\\\\\/+[^\\\\\\/]*){0,' + (nUpLn - 1) / 3 + '}$'), '/');\n\t }\n\t return sDir + sPath.substr(nStart);\n\t }\n\t};\n\t\n\tmodule.exports = URLHelper;\n\t\n\t},{}],47:[function(_dereq_,module,exports){\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t\n\tvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /**\n\t * XHR based logger\n\t */\n\t\n\tvar _logger = _dereq_(43);\n\t\n\tfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\t\n\tvar XhrLoader = function () {\n\t function XhrLoader(config) {\n\t _classCallCheck(this, XhrLoader);\n\t\n\t if (config && config.xhrSetup) {\n\t this.xhrSetup = config.xhrSetup;\n\t }\n\t }\n\t\n\t _createClass(XhrLoader, [{\n\t key: 'destroy',\n\t value: function destroy() {\n\t this.abort();\n\t this.loader = null;\n\t }\n\t }, {\n\t key: 'abort',\n\t value: function abort() {\n\t var loader = this.loader;\n\t if (loader && loader.readyState !== 4) {\n\t this.stats.aborted = true;\n\t loader.abort();\n\t }\n\t\n\t window.clearTimeout(this.requestTimeout);\n\t this.requestTimeout = null;\n\t window.clearTimeout(this.retryTimeout);\n\t this.retryTimeout = null;\n\t }\n\t }, {\n\t key: 'load',\n\t value: function load(context, config, callbacks) {\n\t this.context = context;\n\t this.config = config;\n\t this.callbacks = callbacks;\n\t this.stats = { trequest: performance.now(), retry: 0 };\n\t this.retryDelay = config.retryDelay;\n\t this.loadInternal();\n\t }\n\t }, {\n\t key: 'loadInternal',\n\t value: function loadInternal() {\n\t var xhr,\n\t context = this.context;\n\t\n\t if (typeof XDomainRequest !== 'undefined') {\n\t xhr = this.loader = new XDomainRequest();\n\t } else {\n\t xhr = this.loader = new XMLHttpRequest();\n\t }\n\t\n\t xhr.onreadystatechange = this.readystatechange.bind(this);\n\t xhr.onprogress = this.loadprogress.bind(this);\n\t\n\t xhr.open('GET', context.url, true);\n\t\n\t if (context.rangeEnd) {\n\t xhr.setRequestHeader('Range', 'bytes=' + context.rangeStart + '-' + (context.rangeEnd - 1));\n\t }\n\t xhr.responseType = context.responseType;\n\t var stats = this.stats;\n\t stats.tfirst = 0;\n\t stats.loaded = 0;\n\t if (this.xhrSetup) {\n\t this.xhrSetup(xhr, context.url);\n\t }\n\t // setup timeout before we perform request\n\t this.requestTimeout = window.setTimeout(this.loadtimeout.bind(this), this.config.timeout);\n\t xhr.send();\n\t }\n\t }, {\n\t key: 'readystatechange',\n\t value: function readystatechange(event) {\n\t var xhr = event.currentTarget,\n\t readyState = xhr.readyState,\n\t stats = this.stats,\n\t context = this.context,\n\t config = this.config;\n\t\n\t // don't proceed if xhr has been aborted\n\t if (stats.aborted) {\n\t return;\n\t }\n\t\n\t // in any case clear the current xhrs timeout\n\t window.clearTimeout(this.requestTimeout);\n\t\n\t // HEADERS_RECEIVED\n\t if (readyState >= 2) {\n\t if (stats.tfirst === 0) {\n\t stats.tfirst = Math.max(performance.now(), stats.trequest);\n\t // reset timeout to total timeout duration minus the time it took to receive headers\n\t this.requestTimeout = window.setTimeout(this.loadtimeout.bind(this), config.timeout - (stats.tfirst - stats.trequest));\n\t }\n\t if (readyState === 4) {\n\t var status = xhr.status;\n\t // http status between 200 to 299 are all successful\n\t if (status >= 200 && status < 300) {\n\t stats.tload = Math.max(stats.tfirst, performance.now());\n\t var data = void 0,\n\t len = void 0;\n\t if (context.responseType === 'arraybuffer') {\n\t data = xhr.response;\n\t len = data.byteLength;\n\t } else {\n\t data = xhr.responseText;\n\t len = data.length;\n\t }\n\t stats.loaded = stats.total = len;\n\t var response = { url: xhr.responseURL, data: data };\n\t this.callbacks.onSuccess(response, stats, context);\n\t } else {\n\t // if max nb of retries reached or if http status between 400 and 499 (such error cannot be recovered, retrying is useless), return error\n\t if (stats.retry >= config.maxRetry || status >= 400 && status < 499) {\n\t _logger.logger.error(status + ' while loading ' + context.url);\n\t this.callbacks.onError({ code: status, text: xhr.statusText }, context);\n\t } else {\n\t // retry\n\t _logger.logger.warn(status + ' while loading ' + context.url + ', retrying in ' + this.retryDelay + '...');\n\t // aborts and resets internal state\n\t this.destroy();\n\t // schedule retry\n\t this.retryTimeout = window.setTimeout(this.loadInternal.bind(this), this.retryDelay);\n\t // set exponential backoff\n\t this.retryDelay = Math.min(2 * this.retryDelay, config.maxRetryDelay);\n\t stats.retry++;\n\t }\n\t }\n\t }\n\t }\n\t }\n\t }, {\n\t key: 'loadtimeout',\n\t value: function loadtimeout() {\n\t _logger.logger.warn('timeout while loading ' + this.context.url);\n\t this.callbacks.onTimeout(this.stats, this.context);\n\t }\n\t }, {\n\t key: 'loadprogress',\n\t value: function loadprogress(event) {\n\t var stats = this.stats;\n\t stats.loaded = event.loaded;\n\t if (event.lengthComputable) {\n\t stats.total = event.total;\n\t }\n\t var onProgress = this.callbacks.onProgress;\n\t if (onProgress) {\n\t // last args is to provide on progress data\n\t onProgress(stats, this.context, null);\n\t }\n\t }\n\t }]);\n\t\n\t return XhrLoader;\n\t}();\n\t\n\texports.default = XhrLoader;\n\t\n\t},{\"43\":43}]},{},[31])(31)\n\t});\n\t//# sourceMappingURL=hls.js.map\n\n\n/***/ },\n/* 91 */\n/*!****************************************************************!*\\\n !*** ./src/components/media_control/public/media-control.html ***!\n \\****************************************************************/\n/***/ function(module, exports) {\n\n\tmodule.exports = \"\\n\\n\";\n\n/***/ },\n/* 92 */\n/*!*************************************************************!*\\\n !*** ./src/playbacks/base_flash_playback/public/flash.html ***!\n \\*************************************************************/\n/***/ function(module, exports) {\n\n\tmodule.exports = \"?inline=1\\\">\\n\\n\\n\\n\\n\\n\\\">\\n\\n&callback=<%= callbackName %>\\\">\\n\\n\";\n\n/***/ },\n/* 93 */\n/*!***********************************************!*\\\n !*** ./src/playbacks/no_op/public/error.html ***!\n \\***********************************************/\n/***/ function(module, exports) {\n\n\tmodule.exports = \"\\n<%=message%>
\\n\";\n\n/***/ },\n/* 94 */\n/*!****************************************************!*\\\n !*** ./src/plugins/dvr_controls/public/index.html ***!\n \\****************************************************/\n/***/ function(module, exports) {\n\n\tmodule.exports = \"
<%= live %>
\\n\\n\";\n\n/***/ },\n/* 95 */\n/*!***********************************************!*\\\n !*** ./src/plugins/poster/public/poster.html ***!\n \\***********************************************/\n/***/ function(module, exports) {\n\n\tmodule.exports = \"\\n\";\n\n/***/ },\n/* 96 */\n/*!*****************************************************!*\\\n !*** ./src/plugins/seek_time/public/seek_time.html ***!\n \\*****************************************************/\n/***/ function(module, exports) {\n\n\tmodule.exports = \"\\n\\n\";\n\n/***/ },\n/* 97 */\n/*!**************************************************************!*\\\n !*** ./src/plugins/spinner_three_bounce/public/spinner.html ***!\n \\**************************************************************/\n/***/ function(module, exports) {\n\n\tmodule.exports = \"\\n\";\n\n/***/ },\n/* 98 */\n/*!*****************************************************!*\\\n !*** ./src/plugins/watermark/public/watermark.html ***!\n \\*****************************************************/\n/***/ function(module, exports) {\n\n\tmodule.exports = \"\\n\";\n\n/***/ },\n/* 99 */\n/*!***********************************!*\\\n !*** ./~/lodash.isequal/index.js ***!\n \\***********************************/\n/***/ function(module, exports, __webpack_require__) {\n\n\t/* WEBPACK VAR INJECTION */(function(global, module) {/**\n\t * lodash (Custom Build) \n\t * Build: `lodash modularize exports=\"npm\" -o ./`\n\t * Copyright jQuery Foundation and other contributors \n\t * Released under MIT license \n\t * Based on Underscore.js 1.8.3 \n\t * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n\t */\n\t\n\t/** Used as the size to enable large array optimizations. */\n\tvar LARGE_ARRAY_SIZE = 200;\n\t\n\t/** Used to stand-in for `undefined` hash values. */\n\tvar HASH_UNDEFINED = '__lodash_hash_undefined__';\n\t\n\t/** Used to compose bitmasks for comparison styles. */\n\tvar UNORDERED_COMPARE_FLAG = 1,\n\t PARTIAL_COMPARE_FLAG = 2;\n\t\n\t/** Used as references for various `Number` constants. */\n\tvar MAX_SAFE_INTEGER = 9007199254740991;\n\t\n\t/** `Object#toString` result references. */\n\tvar argsTag = '[object Arguments]',\n\t arrayTag = '[object Array]',\n\t boolTag = '[object Boolean]',\n\t dateTag = '[object Date]',\n\t errorTag = '[object Error]',\n\t funcTag = '[object Function]',\n\t genTag = '[object GeneratorFunction]',\n\t mapTag = '[object Map]',\n\t numberTag = '[object Number]',\n\t objectTag = '[object Object]',\n\t promiseTag = '[object Promise]',\n\t regexpTag = '[object RegExp]',\n\t setTag = '[object Set]',\n\t stringTag = '[object String]',\n\t symbolTag = '[object Symbol]',\n\t weakMapTag = '[object WeakMap]';\n\t\n\tvar arrayBufferTag = '[object ArrayBuffer]',\n\t dataViewTag = '[object DataView]',\n\t float32Tag = '[object Float32Array]',\n\t float64Tag = '[object Float64Array]',\n\t int8Tag = '[object Int8Array]',\n\t int16Tag = '[object Int16Array]',\n\t int32Tag = '[object Int32Array]',\n\t uint8Tag = '[object Uint8Array]',\n\t uint8ClampedTag = '[object Uint8ClampedArray]',\n\t uint16Tag = '[object Uint16Array]',\n\t uint32Tag = '[object Uint32Array]';\n\t\n\t/**\n\t * Used to match `RegExp`\n\t * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).\n\t */\n\tvar reRegExpChar = /[\\\\^$.*+?()[\\]{}|]/g;\n\t\n\t/** Used to detect host constructors (Safari). */\n\tvar reIsHostCtor = /^\\[object .+?Constructor\\]$/;\n\t\n\t/** Used to detect unsigned integer values. */\n\tvar reIsUint = /^(?:0|[1-9]\\d*)$/;\n\t\n\t/** Used to identify `toStringTag` values of typed arrays. */\n\tvar typedArrayTags = {};\n\ttypedArrayTags[float32Tag] = typedArrayTags[float64Tag] =\n\ttypedArrayTags[int8Tag] = typedArrayTags[int16Tag] =\n\ttypedArrayTags[int32Tag] = typedArrayTags[uint8Tag] =\n\ttypedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] =\n\ttypedArrayTags[uint32Tag] = true;\n\ttypedArrayTags[argsTag] = typedArrayTags[arrayTag] =\n\ttypedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =\n\ttypedArrayTags[dataViewTag] = typedArrayTags[dateTag] =\n\ttypedArrayTags[errorTag] = typedArrayTags[funcTag] =\n\ttypedArrayTags[mapTag] = typedArrayTags[numberTag] =\n\ttypedArrayTags[objectTag] = typedArrayTags[regexpTag] =\n\ttypedArrayTags[setTag] = typedArrayTags[stringTag] =\n\ttypedArrayTags[weakMapTag] = false;\n\t\n\t/** Detect free variable `global` from Node.js. */\n\tvar freeGlobal = typeof global == 'object' && global && global.Object === Object && global;\n\t\n\t/** Detect free variable `self`. */\n\tvar freeSelf = typeof self == 'object' && self && self.Object === Object && self;\n\t\n\t/** Used as a reference to the global object. */\n\tvar root = freeGlobal || freeSelf || Function('return this')();\n\t\n\t/** Detect free variable `exports`. */\n\tvar freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports;\n\t\n\t/** Detect free variable `module`. */\n\tvar freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module;\n\t\n\t/** Detect the popular CommonJS extension `module.exports`. */\n\tvar moduleExports = freeModule && freeModule.exports === freeExports;\n\t\n\t/** Detect free variable `process` from Node.js. */\n\tvar freeProcess = moduleExports && freeGlobal.process;\n\t\n\t/** Used to access faster Node.js helpers. */\n\tvar nodeUtil = (function() {\n\t try {\n\t return freeProcess && freeProcess.binding('util');\n\t } catch (e) {}\n\t}());\n\t\n\t/* Node.js helper references. */\n\tvar nodeIsTypedArray = nodeUtil && nodeUtil.isTypedArray;\n\t\n\t/**\n\t * A specialized version of `_.some` for arrays without support for iteratee\n\t * shorthands.\n\t *\n\t * @private\n\t * @param {Array} [array] The array to iterate over.\n\t * @param {Function} predicate The function invoked per iteration.\n\t * @returns {boolean} Returns `true` if any element passes the predicate check,\n\t * else `false`.\n\t */\n\tfunction arraySome(array, predicate) {\n\t var index = -1,\n\t length = array ? array.length : 0;\n\t\n\t while (++index < length) {\n\t if (predicate(array[index], index, array)) {\n\t return true;\n\t }\n\t }\n\t return false;\n\t}\n\t\n\t/**\n\t * The base implementation of `_.times` without support for iteratee shorthands\n\t * or max array length checks.\n\t *\n\t * @private\n\t * @param {number} n The number of times to invoke `iteratee`.\n\t * @param {Function} iteratee The function invoked per iteration.\n\t * @returns {Array} Returns the array of results.\n\t */\n\tfunction baseTimes(n, iteratee) {\n\t var index = -1,\n\t result = Array(n);\n\t\n\t while (++index < n) {\n\t result[index] = iteratee(index);\n\t }\n\t return result;\n\t}\n\t\n\t/**\n\t * The base implementation of `_.unary` without support for storing metadata.\n\t *\n\t * @private\n\t * @param {Function} func The function to cap arguments for.\n\t * @returns {Function} Returns the new capped function.\n\t */\n\tfunction baseUnary(func) {\n\t return function(value) {\n\t return func(value);\n\t };\n\t}\n\t\n\t/**\n\t * Gets the value at `key` of `object`.\n\t *\n\t * @private\n\t * @param {Object} [object] The object to query.\n\t * @param {string} key The key of the property to get.\n\t * @returns {*} Returns the property value.\n\t */\n\tfunction getValue(object, key) {\n\t return object == null ? undefined : object[key];\n\t}\n\t\n\t/**\n\t * Checks if `value` is a host object in IE < 9.\n\t *\n\t * @private\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is a host object, else `false`.\n\t */\n\tfunction isHostObject(value) {\n\t // Many host objects are `Object` objects that can coerce to strings\n\t // despite having improperly defined `toString` methods.\n\t var result = false;\n\t if (value != null && typeof value.toString != 'function') {\n\t try {\n\t result = !!(value + '');\n\t } catch (e) {}\n\t }\n\t return result;\n\t}\n\t\n\t/**\n\t * Converts `map` to its key-value pairs.\n\t *\n\t * @private\n\t * @param {Object} map The map to convert.\n\t * @returns {Array} Returns the key-value pairs.\n\t */\n\tfunction mapToArray(map) {\n\t var index = -1,\n\t result = Array(map.size);\n\t\n\t map.forEach(function(value, key) {\n\t result[++index] = [key, value];\n\t });\n\t return result;\n\t}\n\t\n\t/**\n\t * Creates a unary function that invokes `func` with its argument transformed.\n\t *\n\t * @private\n\t * @param {Function} func The function to wrap.\n\t * @param {Function} transform The argument transform.\n\t * @returns {Function} Returns the new function.\n\t */\n\tfunction overArg(func, transform) {\n\t return function(arg) {\n\t return func(transform(arg));\n\t };\n\t}\n\t\n\t/**\n\t * Converts `set` to an array of its values.\n\t *\n\t * @private\n\t * @param {Object} set The set to convert.\n\t * @returns {Array} Returns the values.\n\t */\n\tfunction setToArray(set) {\n\t var index = -1,\n\t result = Array(set.size);\n\t\n\t set.forEach(function(value) {\n\t result[++index] = value;\n\t });\n\t return result;\n\t}\n\t\n\t/** Used for built-in method references. */\n\tvar arrayProto = Array.prototype,\n\t funcProto = Function.prototype,\n\t objectProto = Object.prototype;\n\t\n\t/** Used to detect overreaching core-js shims. */\n\tvar coreJsData = root['__core-js_shared__'];\n\t\n\t/** Used to detect methods masquerading as native. */\n\tvar maskSrcKey = (function() {\n\t var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || '');\n\t return uid ? ('Symbol(src)_1.' + uid) : '';\n\t}());\n\t\n\t/** Used to resolve the decompiled source of functions. */\n\tvar funcToString = funcProto.toString;\n\t\n\t/** Used to check objects for own properties. */\n\tvar hasOwnProperty = objectProto.hasOwnProperty;\n\t\n\t/**\n\t * Used to resolve the\n\t * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)\n\t * of values.\n\t */\n\tvar objectToString = objectProto.toString;\n\t\n\t/** Used to detect if a method is native. */\n\tvar reIsNative = RegExp('^' +\n\t funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\\\$&')\n\t .replace(/hasOwnProperty|(function).*?(?=\\\\\\()| for .+?(?=\\\\\\])/g, '$1.*?') + '$'\n\t);\n\t\n\t/** Built-in value references. */\n\tvar Symbol = root.Symbol,\n\t Uint8Array = root.Uint8Array,\n\t propertyIsEnumerable = objectProto.propertyIsEnumerable,\n\t splice = arrayProto.splice;\n\t\n\t/* Built-in method references for those with the same name as other `lodash` methods. */\n\tvar nativeKeys = overArg(Object.keys, Object);\n\t\n\t/* Built-in method references that are verified to be native. */\n\tvar DataView = getNative(root, 'DataView'),\n\t Map = getNative(root, 'Map'),\n\t Promise = getNative(root, 'Promise'),\n\t Set = getNative(root, 'Set'),\n\t WeakMap = getNative(root, 'WeakMap'),\n\t nativeCreate = getNative(Object, 'create');\n\t\n\t/** Used to detect maps, sets, and weakmaps. */\n\tvar dataViewCtorString = toSource(DataView),\n\t mapCtorString = toSource(Map),\n\t promiseCtorString = toSource(Promise),\n\t setCtorString = toSource(Set),\n\t weakMapCtorString = toSource(WeakMap);\n\t\n\t/** Used to convert symbols to primitives and strings. */\n\tvar symbolProto = Symbol ? Symbol.prototype : undefined,\n\t symbolValueOf = symbolProto ? symbolProto.valueOf : undefined;\n\t\n\t/**\n\t * Creates a hash object.\n\t *\n\t * @private\n\t * @constructor\n\t * @param {Array} [entries] The key-value pairs to cache.\n\t */\n\tfunction Hash(entries) {\n\t var index = -1,\n\t length = entries ? entries.length : 0;\n\t\n\t this.clear();\n\t while (++index < length) {\n\t var entry = entries[index];\n\t this.set(entry[0], entry[1]);\n\t }\n\t}\n\t\n\t/**\n\t * Removes all key-value entries from the hash.\n\t *\n\t * @private\n\t * @name clear\n\t * @memberOf Hash\n\t */\n\tfunction hashClear() {\n\t this.__data__ = nativeCreate ? nativeCreate(null) : {};\n\t}\n\t\n\t/**\n\t * Removes `key` and its value from the hash.\n\t *\n\t * @private\n\t * @name delete\n\t * @memberOf Hash\n\t * @param {Object} hash The hash to modify.\n\t * @param {string} key The key of the value to remove.\n\t * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n\t */\n\tfunction hashDelete(key) {\n\t return this.has(key) && delete this.__data__[key];\n\t}\n\t\n\t/**\n\t * Gets the hash value for `key`.\n\t *\n\t * @private\n\t * @name get\n\t * @memberOf Hash\n\t * @param {string} key The key of the value to get.\n\t * @returns {*} Returns the entry value.\n\t */\n\tfunction hashGet(key) {\n\t var data = this.__data__;\n\t if (nativeCreate) {\n\t var result = data[key];\n\t return result === HASH_UNDEFINED ? undefined : result;\n\t }\n\t return hasOwnProperty.call(data, key) ? data[key] : undefined;\n\t}\n\t\n\t/**\n\t * Checks if a hash value for `key` exists.\n\t *\n\t * @private\n\t * @name has\n\t * @memberOf Hash\n\t * @param {string} key The key of the entry to check.\n\t * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n\t */\n\tfunction hashHas(key) {\n\t var data = this.__data__;\n\t return nativeCreate ? data[key] !== undefined : hasOwnProperty.call(data, key);\n\t}\n\t\n\t/**\n\t * Sets the hash `key` to `value`.\n\t *\n\t * @private\n\t * @name set\n\t * @memberOf Hash\n\t * @param {string} key The key of the value to set.\n\t * @param {*} value The value to set.\n\t * @returns {Object} Returns the hash instance.\n\t */\n\tfunction hashSet(key, value) {\n\t var data = this.__data__;\n\t data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value;\n\t return this;\n\t}\n\t\n\t// Add methods to `Hash`.\n\tHash.prototype.clear = hashClear;\n\tHash.prototype['delete'] = hashDelete;\n\tHash.prototype.get = hashGet;\n\tHash.prototype.has = hashHas;\n\tHash.prototype.set = hashSet;\n\t\n\t/**\n\t * Creates an list cache object.\n\t *\n\t * @private\n\t * @constructor\n\t * @param {Array} [entries] The key-value pairs to cache.\n\t */\n\tfunction ListCache(entries) {\n\t var index = -1,\n\t length = entries ? entries.length : 0;\n\t\n\t this.clear();\n\t while (++index < length) {\n\t var entry = entries[index];\n\t this.set(entry[0], entry[1]);\n\t }\n\t}\n\t\n\t/**\n\t * Removes all key-value entries from the list cache.\n\t *\n\t * @private\n\t * @name clear\n\t * @memberOf ListCache\n\t */\n\tfunction listCacheClear() {\n\t this.__data__ = [];\n\t}\n\t\n\t/**\n\t * Removes `key` and its value from the list cache.\n\t *\n\t * @private\n\t * @name delete\n\t * @memberOf ListCache\n\t * @param {string} key The key of the value to remove.\n\t * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n\t */\n\tfunction listCacheDelete(key) {\n\t var data = this.__data__,\n\t index = assocIndexOf(data, key);\n\t\n\t if (index < 0) {\n\t return false;\n\t }\n\t var lastIndex = data.length - 1;\n\t if (index == lastIndex) {\n\t data.pop();\n\t } else {\n\t splice.call(data, index, 1);\n\t }\n\t return true;\n\t}\n\t\n\t/**\n\t * Gets the list cache value for `key`.\n\t *\n\t * @private\n\t * @name get\n\t * @memberOf ListCache\n\t * @param {string} key The key of the value to get.\n\t * @returns {*} Returns the entry value.\n\t */\n\tfunction listCacheGet(key) {\n\t var data = this.__data__,\n\t index = assocIndexOf(data, key);\n\t\n\t return index < 0 ? undefined : data[index][1];\n\t}\n\t\n\t/**\n\t * Checks if a list cache value for `key` exists.\n\t *\n\t * @private\n\t * @name has\n\t * @memberOf ListCache\n\t * @param {string} key The key of the entry to check.\n\t * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n\t */\n\tfunction listCacheHas(key) {\n\t return assocIndexOf(this.__data__, key) > -1;\n\t}\n\t\n\t/**\n\t * Sets the list cache `key` to `value`.\n\t *\n\t * @private\n\t * @name set\n\t * @memberOf ListCache\n\t * @param {string} key The key of the value to set.\n\t * @param {*} value The value to set.\n\t * @returns {Object} Returns the list cache instance.\n\t */\n\tfunction listCacheSet(key, value) {\n\t var data = this.__data__,\n\t index = assocIndexOf(data, key);\n\t\n\t if (index < 0) {\n\t data.push([key, value]);\n\t } else {\n\t data[index][1] = value;\n\t }\n\t return this;\n\t}\n\t\n\t// Add methods to `ListCache`.\n\tListCache.prototype.clear = listCacheClear;\n\tListCache.prototype['delete'] = listCacheDelete;\n\tListCache.prototype.get = listCacheGet;\n\tListCache.prototype.has = listCacheHas;\n\tListCache.prototype.set = listCacheSet;\n\t\n\t/**\n\t * Creates a map cache object to store key-value pairs.\n\t *\n\t * @private\n\t * @constructor\n\t * @param {Array} [entries] The key-value pairs to cache.\n\t */\n\tfunction MapCache(entries) {\n\t var index = -1,\n\t length = entries ? entries.length : 0;\n\t\n\t this.clear();\n\t while (++index < length) {\n\t var entry = entries[index];\n\t this.set(entry[0], entry[1]);\n\t }\n\t}\n\t\n\t/**\n\t * Removes all key-value entries from the map.\n\t *\n\t * @private\n\t * @name clear\n\t * @memberOf MapCache\n\t */\n\tfunction mapCacheClear() {\n\t this.__data__ = {\n\t 'hash': new Hash,\n\t 'map': new (Map || ListCache),\n\t 'string': new Hash\n\t };\n\t}\n\t\n\t/**\n\t * Removes `key` and its value from the map.\n\t *\n\t * @private\n\t * @name delete\n\t * @memberOf MapCache\n\t * @param {string} key The key of the value to remove.\n\t * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n\t */\n\tfunction mapCacheDelete(key) {\n\t return getMapData(this, key)['delete'](key);\n\t}\n\t\n\t/**\n\t * Gets the map value for `key`.\n\t *\n\t * @private\n\t * @name get\n\t * @memberOf MapCache\n\t * @param {string} key The key of the value to get.\n\t * @returns {*} Returns the entry value.\n\t */\n\tfunction mapCacheGet(key) {\n\t return getMapData(this, key).get(key);\n\t}\n\t\n\t/**\n\t * Checks if a map value for `key` exists.\n\t *\n\t * @private\n\t * @name has\n\t * @memberOf MapCache\n\t * @param {string} key The key of the entry to check.\n\t * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n\t */\n\tfunction mapCacheHas(key) {\n\t return getMapData(this, key).has(key);\n\t}\n\t\n\t/**\n\t * Sets the map `key` to `value`.\n\t *\n\t * @private\n\t * @name set\n\t * @memberOf MapCache\n\t * @param {string} key The key of the value to set.\n\t * @param {*} value The value to set.\n\t * @returns {Object} Returns the map cache instance.\n\t */\n\tfunction mapCacheSet(key, value) {\n\t getMapData(this, key).set(key, value);\n\t return this;\n\t}\n\t\n\t// Add methods to `MapCache`.\n\tMapCache.prototype.clear = mapCacheClear;\n\tMapCache.prototype['delete'] = mapCacheDelete;\n\tMapCache.prototype.get = mapCacheGet;\n\tMapCache.prototype.has = mapCacheHas;\n\tMapCache.prototype.set = mapCacheSet;\n\t\n\t/**\n\t *\n\t * Creates an array cache object to store unique values.\n\t *\n\t * @private\n\t * @constructor\n\t * @param {Array} [values] The values to cache.\n\t */\n\tfunction SetCache(values) {\n\t var index = -1,\n\t length = values ? values.length : 0;\n\t\n\t this.__data__ = new MapCache;\n\t while (++index < length) {\n\t this.add(values[index]);\n\t }\n\t}\n\t\n\t/**\n\t * Adds `value` to the array cache.\n\t *\n\t * @private\n\t * @name add\n\t * @memberOf SetCache\n\t * @alias push\n\t * @param {*} value The value to cache.\n\t * @returns {Object} Returns the cache instance.\n\t */\n\tfunction setCacheAdd(value) {\n\t this.__data__.set(value, HASH_UNDEFINED);\n\t return this;\n\t}\n\t\n\t/**\n\t * Checks if `value` is in the array cache.\n\t *\n\t * @private\n\t * @name has\n\t * @memberOf SetCache\n\t * @param {*} value The value to search for.\n\t * @returns {number} Returns `true` if `value` is found, else `false`.\n\t */\n\tfunction setCacheHas(value) {\n\t return this.__data__.has(value);\n\t}\n\t\n\t// Add methods to `SetCache`.\n\tSetCache.prototype.add = SetCache.prototype.push = setCacheAdd;\n\tSetCache.prototype.has = setCacheHas;\n\t\n\t/**\n\t * Creates a stack cache object to store key-value pairs.\n\t *\n\t * @private\n\t * @constructor\n\t * @param {Array} [entries] The key-value pairs to cache.\n\t */\n\tfunction Stack(entries) {\n\t this.__data__ = new ListCache(entries);\n\t}\n\t\n\t/**\n\t * Removes all key-value entries from the stack.\n\t *\n\t * @private\n\t * @name clear\n\t * @memberOf Stack\n\t */\n\tfunction stackClear() {\n\t this.__data__ = new ListCache;\n\t}\n\t\n\t/**\n\t * Removes `key` and its value from the stack.\n\t *\n\t * @private\n\t * @name delete\n\t * @memberOf Stack\n\t * @param {string} key The key of the value to remove.\n\t * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n\t */\n\tfunction stackDelete(key) {\n\t return this.__data__['delete'](key);\n\t}\n\t\n\t/**\n\t * Gets the stack value for `key`.\n\t *\n\t * @private\n\t * @name get\n\t * @memberOf Stack\n\t * @param {string} key The key of the value to get.\n\t * @returns {*} Returns the entry value.\n\t */\n\tfunction stackGet(key) {\n\t return this.__data__.get(key);\n\t}\n\t\n\t/**\n\t * Checks if a stack value for `key` exists.\n\t *\n\t * @private\n\t * @name has\n\t * @memberOf Stack\n\t * @param {string} key The key of the entry to check.\n\t * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n\t */\n\tfunction stackHas(key) {\n\t return this.__data__.has(key);\n\t}\n\t\n\t/**\n\t * Sets the stack `key` to `value`.\n\t *\n\t * @private\n\t * @name set\n\t * @memberOf Stack\n\t * @param {string} key The key of the value to set.\n\t * @param {*} value The value to set.\n\t * @returns {Object} Returns the stack cache instance.\n\t */\n\tfunction stackSet(key, value) {\n\t var cache = this.__data__;\n\t if (cache instanceof ListCache) {\n\t var pairs = cache.__data__;\n\t if (!Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) {\n\t pairs.push([key, value]);\n\t return this;\n\t }\n\t cache = this.__data__ = new MapCache(pairs);\n\t }\n\t cache.set(key, value);\n\t return this;\n\t}\n\t\n\t// Add methods to `Stack`.\n\tStack.prototype.clear = stackClear;\n\tStack.prototype['delete'] = stackDelete;\n\tStack.prototype.get = stackGet;\n\tStack.prototype.has = stackHas;\n\tStack.prototype.set = stackSet;\n\t\n\t/**\n\t * Creates an array of the enumerable property names of the array-like `value`.\n\t *\n\t * @private\n\t * @param {*} value The value to query.\n\t * @param {boolean} inherited Specify returning inherited property names.\n\t * @returns {Array} Returns the array of property names.\n\t */\n\tfunction arrayLikeKeys(value, inherited) {\n\t // Safari 8.1 makes `arguments.callee` enumerable in strict mode.\n\t // Safari 9 makes `arguments.length` enumerable in strict mode.\n\t var result = (isArray(value) || isArguments(value))\n\t ? baseTimes(value.length, String)\n\t : [];\n\t\n\t var length = result.length,\n\t skipIndexes = !!length;\n\t\n\t for (var key in value) {\n\t if ((inherited || hasOwnProperty.call(value, key)) &&\n\t !(skipIndexes && (key == 'length' || isIndex(key, length)))) {\n\t result.push(key);\n\t }\n\t }\n\t return result;\n\t}\n\t\n\t/**\n\t * Gets the index at which the `key` is found in `array` of key-value pairs.\n\t *\n\t * @private\n\t * @param {Array} array The array to inspect.\n\t * @param {*} key The key to search for.\n\t * @returns {number} Returns the index of the matched value, else `-1`.\n\t */\n\tfunction assocIndexOf(array, key) {\n\t var length = array.length;\n\t while (length--) {\n\t if (eq(array[length][0], key)) {\n\t return length;\n\t }\n\t }\n\t return -1;\n\t}\n\t\n\t/**\n\t * The base implementation of `getTag`.\n\t *\n\t * @private\n\t * @param {*} value The value to query.\n\t * @returns {string} Returns the `toStringTag`.\n\t */\n\tfunction baseGetTag(value) {\n\t return objectToString.call(value);\n\t}\n\t\n\t/**\n\t * The base implementation of `_.isEqual` which supports partial comparisons\n\t * and tracks traversed objects.\n\t *\n\t * @private\n\t * @param {*} value The value to compare.\n\t * @param {*} other The other value to compare.\n\t * @param {Function} [customizer] The function to customize comparisons.\n\t * @param {boolean} [bitmask] The bitmask of comparison flags.\n\t * The bitmask may be composed of the following flags:\n\t * 1 - Unordered comparison\n\t * 2 - Partial comparison\n\t * @param {Object} [stack] Tracks traversed `value` and `other` objects.\n\t * @returns {boolean} Returns `true` if the values are equivalent, else `false`.\n\t */\n\tfunction baseIsEqual(value, other, customizer, bitmask, stack) {\n\t if (value === other) {\n\t return true;\n\t }\n\t if (value == null || other == null || (!isObject(value) && !isObjectLike(other))) {\n\t return value !== value && other !== other;\n\t }\n\t return baseIsEqualDeep(value, other, baseIsEqual, customizer, bitmask, stack);\n\t}\n\t\n\t/**\n\t * A specialized version of `baseIsEqual` for arrays and objects which performs\n\t * deep comparisons and tracks traversed objects enabling objects with circular\n\t * references to be compared.\n\t *\n\t * @private\n\t * @param {Object} object The object to compare.\n\t * @param {Object} other The other object to compare.\n\t * @param {Function} equalFunc The function to determine equivalents of values.\n\t * @param {Function} [customizer] The function to customize comparisons.\n\t * @param {number} [bitmask] The bitmask of comparison flags. See `baseIsEqual`\n\t * for more details.\n\t * @param {Object} [stack] Tracks traversed `object` and `other` objects.\n\t * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.\n\t */\n\tfunction baseIsEqualDeep(object, other, equalFunc, customizer, bitmask, stack) {\n\t var objIsArr = isArray(object),\n\t othIsArr = isArray(other),\n\t objTag = arrayTag,\n\t othTag = arrayTag;\n\t\n\t if (!objIsArr) {\n\t objTag = getTag(object);\n\t objTag = objTag == argsTag ? objectTag : objTag;\n\t }\n\t if (!othIsArr) {\n\t othTag = getTag(other);\n\t othTag = othTag == argsTag ? objectTag : othTag;\n\t }\n\t var objIsObj = objTag == objectTag && !isHostObject(object),\n\t othIsObj = othTag == objectTag && !isHostObject(other),\n\t isSameTag = objTag == othTag;\n\t\n\t if (isSameTag && !objIsObj) {\n\t stack || (stack = new Stack);\n\t return (objIsArr || isTypedArray(object))\n\t ? equalArrays(object, other, equalFunc, customizer, bitmask, stack)\n\t : equalByTag(object, other, objTag, equalFunc, customizer, bitmask, stack);\n\t }\n\t if (!(bitmask & PARTIAL_COMPARE_FLAG)) {\n\t var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'),\n\t othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__');\n\t\n\t if (objIsWrapped || othIsWrapped) {\n\t var objUnwrapped = objIsWrapped ? object.value() : object,\n\t othUnwrapped = othIsWrapped ? other.value() : other;\n\t\n\t stack || (stack = new Stack);\n\t return equalFunc(objUnwrapped, othUnwrapped, customizer, bitmask, stack);\n\t }\n\t }\n\t if (!isSameTag) {\n\t return false;\n\t }\n\t stack || (stack = new Stack);\n\t return equalObjects(object, other, equalFunc, customizer, bitmask, stack);\n\t}\n\t\n\t/**\n\t * The base implementation of `_.isNative` without bad shim checks.\n\t *\n\t * @private\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is a native function,\n\t * else `false`.\n\t */\n\tfunction baseIsNative(value) {\n\t if (!isObject(value) || isMasked(value)) {\n\t return false;\n\t }\n\t var pattern = (isFunction(value) || isHostObject(value)) ? reIsNative : reIsHostCtor;\n\t return pattern.test(toSource(value));\n\t}\n\t\n\t/**\n\t * The base implementation of `_.isTypedArray` without Node.js optimizations.\n\t *\n\t * @private\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.\n\t */\n\tfunction baseIsTypedArray(value) {\n\t return isObjectLike(value) &&\n\t isLength(value.length) && !!typedArrayTags[objectToString.call(value)];\n\t}\n\t\n\t/**\n\t * The base implementation of `_.keys` which doesn't treat sparse arrays as dense.\n\t *\n\t * @private\n\t * @param {Object} object The object to query.\n\t * @returns {Array} Returns the array of property names.\n\t */\n\tfunction baseKeys(object) {\n\t if (!isPrototype(object)) {\n\t return nativeKeys(object);\n\t }\n\t var result = [];\n\t for (var key in Object(object)) {\n\t if (hasOwnProperty.call(object, key) && key != 'constructor') {\n\t result.push(key);\n\t }\n\t }\n\t return result;\n\t}\n\t\n\t/**\n\t * A specialized version of `baseIsEqualDeep` for arrays with support for\n\t * partial deep comparisons.\n\t *\n\t * @private\n\t * @param {Array} array The array to compare.\n\t * @param {Array} other The other array to compare.\n\t * @param {Function} equalFunc The function to determine equivalents of values.\n\t * @param {Function} customizer The function to customize comparisons.\n\t * @param {number} bitmask The bitmask of comparison flags. See `baseIsEqual`\n\t * for more details.\n\t * @param {Object} stack Tracks traversed `array` and `other` objects.\n\t * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`.\n\t */\n\tfunction equalArrays(array, other, equalFunc, customizer, bitmask, stack) {\n\t var isPartial = bitmask & PARTIAL_COMPARE_FLAG,\n\t arrLength = array.length,\n\t othLength = other.length;\n\t\n\t if (arrLength != othLength && !(isPartial && othLength > arrLength)) {\n\t return false;\n\t }\n\t // Assume cyclic values are equal.\n\t var stacked = stack.get(array);\n\t if (stacked && stack.get(other)) {\n\t return stacked == other;\n\t }\n\t var index = -1,\n\t result = true,\n\t seen = (bitmask & UNORDERED_COMPARE_FLAG) ? new SetCache : undefined;\n\t\n\t stack.set(array, other);\n\t stack.set(other, array);\n\t\n\t // Ignore non-index properties.\n\t while (++index < arrLength) {\n\t var arrValue = array[index],\n\t othValue = other[index];\n\t\n\t if (customizer) {\n\t var compared = isPartial\n\t ? customizer(othValue, arrValue, index, other, array, stack)\n\t : customizer(arrValue, othValue, index, array, other, stack);\n\t }\n\t if (compared !== undefined) {\n\t if (compared) {\n\t continue;\n\t }\n\t result = false;\n\t break;\n\t }\n\t // Recursively compare arrays (susceptible to call stack limits).\n\t if (seen) {\n\t if (!arraySome(other, function(othValue, othIndex) {\n\t if (!seen.has(othIndex) &&\n\t (arrValue === othValue || equalFunc(arrValue, othValue, customizer, bitmask, stack))) {\n\t return seen.add(othIndex);\n\t }\n\t })) {\n\t result = false;\n\t break;\n\t }\n\t } else if (!(\n\t arrValue === othValue ||\n\t equalFunc(arrValue, othValue, customizer, bitmask, stack)\n\t )) {\n\t result = false;\n\t break;\n\t }\n\t }\n\t stack['delete'](array);\n\t stack['delete'](other);\n\t return result;\n\t}\n\t\n\t/**\n\t * A specialized version of `baseIsEqualDeep` for comparing objects of\n\t * the same `toStringTag`.\n\t *\n\t * **Note:** This function only supports comparing values with tags of\n\t * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.\n\t *\n\t * @private\n\t * @param {Object} object The object to compare.\n\t * @param {Object} other The other object to compare.\n\t * @param {string} tag The `toStringTag` of the objects to compare.\n\t * @param {Function} equalFunc The function to determine equivalents of values.\n\t * @param {Function} customizer The function to customize comparisons.\n\t * @param {number} bitmask The bitmask of comparison flags. See `baseIsEqual`\n\t * for more details.\n\t * @param {Object} stack Tracks traversed `object` and `other` objects.\n\t * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.\n\t */\n\tfunction equalByTag(object, other, tag, equalFunc, customizer, bitmask, stack) {\n\t switch (tag) {\n\t case dataViewTag:\n\t if ((object.byteLength != other.byteLength) ||\n\t (object.byteOffset != other.byteOffset)) {\n\t return false;\n\t }\n\t object = object.buffer;\n\t other = other.buffer;\n\t\n\t case arrayBufferTag:\n\t if ((object.byteLength != other.byteLength) ||\n\t !equalFunc(new Uint8Array(object), new Uint8Array(other))) {\n\t return false;\n\t }\n\t return true;\n\t\n\t case boolTag:\n\t case dateTag:\n\t case numberTag:\n\t // Coerce booleans to `1` or `0` and dates to milliseconds.\n\t // Invalid dates are coerced to `NaN`.\n\t return eq(+object, +other);\n\t\n\t case errorTag:\n\t return object.name == other.name && object.message == other.message;\n\t\n\t case regexpTag:\n\t case stringTag:\n\t // Coerce regexes to strings and treat strings, primitives and objects,\n\t // as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring\n\t // for more details.\n\t return object == (other + '');\n\t\n\t case mapTag:\n\t var convert = mapToArray;\n\t\n\t case setTag:\n\t var isPartial = bitmask & PARTIAL_COMPARE_FLAG;\n\t convert || (convert = setToArray);\n\t\n\t if (object.size != other.size && !isPartial) {\n\t return false;\n\t }\n\t // Assume cyclic values are equal.\n\t var stacked = stack.get(object);\n\t if (stacked) {\n\t return stacked == other;\n\t }\n\t bitmask |= UNORDERED_COMPARE_FLAG;\n\t\n\t // Recursively compare objects (susceptible to call stack limits).\n\t stack.set(object, other);\n\t var result = equalArrays(convert(object), convert(other), equalFunc, customizer, bitmask, stack);\n\t stack['delete'](object);\n\t return result;\n\t\n\t case symbolTag:\n\t if (symbolValueOf) {\n\t return symbolValueOf.call(object) == symbolValueOf.call(other);\n\t }\n\t }\n\t return false;\n\t}\n\t\n\t/**\n\t * A specialized version of `baseIsEqualDeep` for objects with support for\n\t * partial deep comparisons.\n\t *\n\t * @private\n\t * @param {Object} object The object to compare.\n\t * @param {Object} other The other object to compare.\n\t * @param {Function} equalFunc The function to determine equivalents of values.\n\t * @param {Function} customizer The function to customize comparisons.\n\t * @param {number} bitmask The bitmask of comparison flags. See `baseIsEqual`\n\t * for more details.\n\t * @param {Object} stack Tracks traversed `object` and `other` objects.\n\t * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.\n\t */\n\tfunction equalObjects(object, other, equalFunc, customizer, bitmask, stack) {\n\t var isPartial = bitmask & PARTIAL_COMPARE_FLAG,\n\t objProps = keys(object),\n\t objLength = objProps.length,\n\t othProps = keys(other),\n\t othLength = othProps.length;\n\t\n\t if (objLength != othLength && !isPartial) {\n\t return false;\n\t }\n\t var index = objLength;\n\t while (index--) {\n\t var key = objProps[index];\n\t if (!(isPartial ? key in other : hasOwnProperty.call(other, key))) {\n\t return false;\n\t }\n\t }\n\t // Assume cyclic values are equal.\n\t var stacked = stack.get(object);\n\t if (stacked && stack.get(other)) {\n\t return stacked == other;\n\t }\n\t var result = true;\n\t stack.set(object, other);\n\t stack.set(other, object);\n\t\n\t var skipCtor = isPartial;\n\t while (++index < objLength) {\n\t key = objProps[index];\n\t var objValue = object[key],\n\t othValue = other[key];\n\t\n\t if (customizer) {\n\t var compared = isPartial\n\t ? customizer(othValue, objValue, key, other, object, stack)\n\t : customizer(objValue, othValue, key, object, other, stack);\n\t }\n\t // Recursively compare objects (susceptible to call stack limits).\n\t if (!(compared === undefined\n\t ? (objValue === othValue || equalFunc(objValue, othValue, customizer, bitmask, stack))\n\t : compared\n\t )) {\n\t result = false;\n\t break;\n\t }\n\t skipCtor || (skipCtor = key == 'constructor');\n\t }\n\t if (result && !skipCtor) {\n\t var objCtor = object.constructor,\n\t othCtor = other.constructor;\n\t\n\t // Non `Object` object instances with different constructors are not equal.\n\t if (objCtor != othCtor &&\n\t ('constructor' in object && 'constructor' in other) &&\n\t !(typeof objCtor == 'function' && objCtor instanceof objCtor &&\n\t typeof othCtor == 'function' && othCtor instanceof othCtor)) {\n\t result = false;\n\t }\n\t }\n\t stack['delete'](object);\n\t stack['delete'](other);\n\t return result;\n\t}\n\t\n\t/**\n\t * Gets the data for `map`.\n\t *\n\t * @private\n\t * @param {Object} map The map to query.\n\t * @param {string} key The reference key.\n\t * @returns {*} Returns the map data.\n\t */\n\tfunction getMapData(map, key) {\n\t var data = map.__data__;\n\t return isKeyable(key)\n\t ? data[typeof key == 'string' ? 'string' : 'hash']\n\t : data.map;\n\t}\n\t\n\t/**\n\t * Gets the native function at `key` of `object`.\n\t *\n\t * @private\n\t * @param {Object} object The object to query.\n\t * @param {string} key The key of the method to get.\n\t * @returns {*} Returns the function if it's native, else `undefined`.\n\t */\n\tfunction getNative(object, key) {\n\t var value = getValue(object, key);\n\t return baseIsNative(value) ? value : undefined;\n\t}\n\t\n\t/**\n\t * Gets the `toStringTag` of `value`.\n\t *\n\t * @private\n\t * @param {*} value The value to query.\n\t * @returns {string} Returns the `toStringTag`.\n\t */\n\tvar getTag = baseGetTag;\n\t\n\t// Fallback for data views, maps, sets, and weak maps in IE 11,\n\t// for data views in Edge < 14, and promises in Node.js.\n\tif ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag) ||\n\t (Map && getTag(new Map) != mapTag) ||\n\t (Promise && getTag(Promise.resolve()) != promiseTag) ||\n\t (Set && getTag(new Set) != setTag) ||\n\t (WeakMap && getTag(new WeakMap) != weakMapTag)) {\n\t getTag = function(value) {\n\t var result = objectToString.call(value),\n\t Ctor = result == objectTag ? value.constructor : undefined,\n\t ctorString = Ctor ? toSource(Ctor) : undefined;\n\t\n\t if (ctorString) {\n\t switch (ctorString) {\n\t case dataViewCtorString: return dataViewTag;\n\t case mapCtorString: return mapTag;\n\t case promiseCtorString: return promiseTag;\n\t case setCtorString: return setTag;\n\t case weakMapCtorString: return weakMapTag;\n\t }\n\t }\n\t return result;\n\t };\n\t}\n\t\n\t/**\n\t * Checks if `value` is a valid array-like index.\n\t *\n\t * @private\n\t * @param {*} value The value to check.\n\t * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.\n\t * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.\n\t */\n\tfunction isIndex(value, length) {\n\t length = length == null ? MAX_SAFE_INTEGER : length;\n\t return !!length &&\n\t (typeof value == 'number' || reIsUint.test(value)) &&\n\t (value > -1 && value % 1 == 0 && value < length);\n\t}\n\t\n\t/**\n\t * Checks if `value` is suitable for use as unique object key.\n\t *\n\t * @private\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is suitable, else `false`.\n\t */\n\tfunction isKeyable(value) {\n\t var type = typeof value;\n\t return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean')\n\t ? (value !== '__proto__')\n\t : (value === null);\n\t}\n\t\n\t/**\n\t * Checks if `func` has its source masked.\n\t *\n\t * @private\n\t * @param {Function} func The function to check.\n\t * @returns {boolean} Returns `true` if `func` is masked, else `false`.\n\t */\n\tfunction isMasked(func) {\n\t return !!maskSrcKey && (maskSrcKey in func);\n\t}\n\t\n\t/**\n\t * Checks if `value` is likely a prototype object.\n\t *\n\t * @private\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.\n\t */\n\tfunction isPrototype(value) {\n\t var Ctor = value && value.constructor,\n\t proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto;\n\t\n\t return value === proto;\n\t}\n\t\n\t/**\n\t * Converts `func` to its source code.\n\t *\n\t * @private\n\t * @param {Function} func The function to process.\n\t * @returns {string} Returns the source code.\n\t */\n\tfunction toSource(func) {\n\t if (func != null) {\n\t try {\n\t return funcToString.call(func);\n\t } catch (e) {}\n\t try {\n\t return (func + '');\n\t } catch (e) {}\n\t }\n\t return '';\n\t}\n\t\n\t/**\n\t * Performs a\n\t * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n\t * comparison between two values to determine if they are equivalent.\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 4.0.0\n\t * @category Lang\n\t * @param {*} value The value to compare.\n\t * @param {*} other The other value to compare.\n\t * @returns {boolean} Returns `true` if the values are equivalent, else `false`.\n\t * @example\n\t *\n\t * var object = { 'a': 1 };\n\t * var other = { 'a': 1 };\n\t *\n\t * _.eq(object, object);\n\t * // => true\n\t *\n\t * _.eq(object, other);\n\t * // => false\n\t *\n\t * _.eq('a', 'a');\n\t * // => true\n\t *\n\t * _.eq('a', Object('a'));\n\t * // => false\n\t *\n\t * _.eq(NaN, NaN);\n\t * // => true\n\t */\n\tfunction eq(value, other) {\n\t return value === other || (value !== value && other !== other);\n\t}\n\t\n\t/**\n\t * Checks if `value` is likely an `arguments` object.\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 0.1.0\n\t * @category Lang\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is an `arguments` object,\n\t * else `false`.\n\t * @example\n\t *\n\t * _.isArguments(function() { return arguments; }());\n\t * // => true\n\t *\n\t * _.isArguments([1, 2, 3]);\n\t * // => false\n\t */\n\tfunction isArguments(value) {\n\t // Safari 8.1 makes `arguments.callee` enumerable in strict mode.\n\t return isArrayLikeObject(value) && hasOwnProperty.call(value, 'callee') &&\n\t (!propertyIsEnumerable.call(value, 'callee') || objectToString.call(value) == argsTag);\n\t}\n\t\n\t/**\n\t * Checks if `value` is classified as an `Array` object.\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 0.1.0\n\t * @category Lang\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is an array, else `false`.\n\t * @example\n\t *\n\t * _.isArray([1, 2, 3]);\n\t * // => true\n\t *\n\t * _.isArray(document.body.children);\n\t * // => false\n\t *\n\t * _.isArray('abc');\n\t * // => false\n\t *\n\t * _.isArray(_.noop);\n\t * // => false\n\t */\n\tvar isArray = Array.isArray;\n\t\n\t/**\n\t * Checks if `value` is array-like. A value is considered array-like if it's\n\t * not a function and has a `value.length` that's an integer greater than or\n\t * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 4.0.0\n\t * @category Lang\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is array-like, else `false`.\n\t * @example\n\t *\n\t * _.isArrayLike([1, 2, 3]);\n\t * // => true\n\t *\n\t * _.isArrayLike(document.body.children);\n\t * // => true\n\t *\n\t * _.isArrayLike('abc');\n\t * // => true\n\t *\n\t * _.isArrayLike(_.noop);\n\t * // => false\n\t */\n\tfunction isArrayLike(value) {\n\t return value != null && isLength(value.length) && !isFunction(value);\n\t}\n\t\n\t/**\n\t * This method is like `_.isArrayLike` except that it also checks if `value`\n\t * is an object.\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 4.0.0\n\t * @category Lang\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is an array-like object,\n\t * else `false`.\n\t * @example\n\t *\n\t * _.isArrayLikeObject([1, 2, 3]);\n\t * // => true\n\t *\n\t * _.isArrayLikeObject(document.body.children);\n\t * // => true\n\t *\n\t * _.isArrayLikeObject('abc');\n\t * // => false\n\t *\n\t * _.isArrayLikeObject(_.noop);\n\t * // => false\n\t */\n\tfunction isArrayLikeObject(value) {\n\t return isObjectLike(value) && isArrayLike(value);\n\t}\n\t\n\t/**\n\t * Performs a deep comparison between two values to determine if they are\n\t * equivalent.\n\t *\n\t * **Note:** This method supports comparing arrays, array buffers, booleans,\n\t * date objects, error objects, maps, numbers, `Object` objects, regexes,\n\t * sets, strings, symbols, and typed arrays. `Object` objects are compared\n\t * by their own, not inherited, enumerable properties. Functions and DOM\n\t * nodes are **not** supported.\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 0.1.0\n\t * @category Lang\n\t * @param {*} value The value to compare.\n\t * @param {*} other The other value to compare.\n\t * @returns {boolean} Returns `true` if the values are equivalent, else `false`.\n\t * @example\n\t *\n\t * var object = { 'a': 1 };\n\t * var other = { 'a': 1 };\n\t *\n\t * _.isEqual(object, other);\n\t * // => true\n\t *\n\t * object === other;\n\t * // => false\n\t */\n\tfunction isEqual(value, other) {\n\t return baseIsEqual(value, other);\n\t}\n\t\n\t/**\n\t * Checks if `value` is classified as a `Function` object.\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 0.1.0\n\t * @category Lang\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is a function, else `false`.\n\t * @example\n\t *\n\t * _.isFunction(_);\n\t * // => true\n\t *\n\t * _.isFunction(/abc/);\n\t * // => false\n\t */\n\tfunction isFunction(value) {\n\t // The use of `Object#toString` avoids issues with the `typeof` operator\n\t // in Safari 8-9 which returns 'object' for typed array and other constructors.\n\t var tag = isObject(value) ? objectToString.call(value) : '';\n\t return tag == funcTag || tag == genTag;\n\t}\n\t\n\t/**\n\t * Checks if `value` is a valid array-like length.\n\t *\n\t * **Note:** This method is loosely based on\n\t * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 4.0.0\n\t * @category Lang\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.\n\t * @example\n\t *\n\t * _.isLength(3);\n\t * // => true\n\t *\n\t * _.isLength(Number.MIN_VALUE);\n\t * // => false\n\t *\n\t * _.isLength(Infinity);\n\t * // => false\n\t *\n\t * _.isLength('3');\n\t * // => false\n\t */\n\tfunction isLength(value) {\n\t return typeof value == 'number' &&\n\t value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;\n\t}\n\t\n\t/**\n\t * Checks if `value` is the\n\t * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)\n\t * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 0.1.0\n\t * @category Lang\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n\t * @example\n\t *\n\t * _.isObject({});\n\t * // => true\n\t *\n\t * _.isObject([1, 2, 3]);\n\t * // => true\n\t *\n\t * _.isObject(_.noop);\n\t * // => true\n\t *\n\t * _.isObject(null);\n\t * // => false\n\t */\n\tfunction isObject(value) {\n\t var type = typeof value;\n\t return !!value && (type == 'object' || type == 'function');\n\t}\n\t\n\t/**\n\t * Checks if `value` is object-like. A value is object-like if it's not `null`\n\t * and has a `typeof` result of \"object\".\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 4.0.0\n\t * @category Lang\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is object-like, else `false`.\n\t * @example\n\t *\n\t * _.isObjectLike({});\n\t * // => true\n\t *\n\t * _.isObjectLike([1, 2, 3]);\n\t * // => true\n\t *\n\t * _.isObjectLike(_.noop);\n\t * // => false\n\t *\n\t * _.isObjectLike(null);\n\t * // => false\n\t */\n\tfunction isObjectLike(value) {\n\t return !!value && typeof value == 'object';\n\t}\n\t\n\t/**\n\t * Checks if `value` is classified as a typed array.\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 3.0.0\n\t * @category Lang\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.\n\t * @example\n\t *\n\t * _.isTypedArray(new Uint8Array);\n\t * // => true\n\t *\n\t * _.isTypedArray([]);\n\t * // => false\n\t */\n\tvar isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray;\n\t\n\t/**\n\t * Creates an array of the own enumerable property names of `object`.\n\t *\n\t * **Note:** Non-object values are coerced to objects. See the\n\t * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)\n\t * for more details.\n\t *\n\t * @static\n\t * @since 0.1.0\n\t * @memberOf _\n\t * @category Object\n\t * @param {Object} object The object to query.\n\t * @returns {Array} Returns the array of property names.\n\t * @example\n\t *\n\t * function Foo() {\n\t * this.a = 1;\n\t * this.b = 2;\n\t * }\n\t *\n\t * Foo.prototype.c = 3;\n\t *\n\t * _.keys(new Foo);\n\t * // => ['a', 'b'] (iteration order is not guaranteed)\n\t *\n\t * _.keys('hi');\n\t * // => ['0', '1']\n\t */\n\tfunction keys(object) {\n\t return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object);\n\t}\n\t\n\tmodule.exports = isEqual;\n\t\n\t/* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }()), __webpack_require__(/*! ./../webpack/buildin/module.js */ 23)(module)))\n\n/***/ },\n/* 100 */\n/*!*****************************************!*\\\n !*** ./~/lodash.isplainobject/index.js ***!\n \\*****************************************/\n/***/ function(module, exports) {\n\n\t/**\n\t * lodash (Custom Build) \n\t * Build: `lodash modularize exports=\"npm\" -o ./`\n\t * Copyright jQuery Foundation and other contributors \n\t * Released under MIT license \n\t * Based on Underscore.js 1.8.3 \n\t * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n\t */\n\t\n\t/** `Object#toString` result references. */\n\tvar objectTag = '[object Object]';\n\t\n\t/**\n\t * Checks if `value` is a host object in IE < 9.\n\t *\n\t * @private\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is a host object, else `false`.\n\t */\n\tfunction isHostObject(value) {\n\t // Many host objects are `Object` objects that can coerce to strings\n\t // despite having improperly defined `toString` methods.\n\t var result = false;\n\t if (value != null && typeof value.toString != 'function') {\n\t try {\n\t result = !!(value + '');\n\t } catch (e) {}\n\t }\n\t return result;\n\t}\n\t\n\t/**\n\t * Creates a unary function that invokes `func` with its argument transformed.\n\t *\n\t * @private\n\t * @param {Function} func The function to wrap.\n\t * @param {Function} transform The argument transform.\n\t * @returns {Function} Returns the new function.\n\t */\n\tfunction overArg(func, transform) {\n\t return function(arg) {\n\t return func(transform(arg));\n\t };\n\t}\n\t\n\t/** Used for built-in method references. */\n\tvar funcProto = Function.prototype,\n\t objectProto = Object.prototype;\n\t\n\t/** Used to resolve the decompiled source of functions. */\n\tvar funcToString = funcProto.toString;\n\t\n\t/** Used to check objects for own properties. */\n\tvar hasOwnProperty = objectProto.hasOwnProperty;\n\t\n\t/** Used to infer the `Object` constructor. */\n\tvar objectCtorString = funcToString.call(Object);\n\t\n\t/**\n\t * Used to resolve the\n\t * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)\n\t * of values.\n\t */\n\tvar objectToString = objectProto.toString;\n\t\n\t/** Built-in value references. */\n\tvar getPrototype = overArg(Object.getPrototypeOf, Object);\n\t\n\t/**\n\t * Checks if `value` is object-like. A value is object-like if it's not `null`\n\t * and has a `typeof` result of \"object\".\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 4.0.0\n\t * @category Lang\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is object-like, else `false`.\n\t * @example\n\t *\n\t * _.isObjectLike({});\n\t * // => true\n\t *\n\t * _.isObjectLike([1, 2, 3]);\n\t * // => true\n\t *\n\t * _.isObjectLike(_.noop);\n\t * // => false\n\t *\n\t * _.isObjectLike(null);\n\t * // => false\n\t */\n\tfunction isObjectLike(value) {\n\t return !!value && typeof value == 'object';\n\t}\n\t\n\t/**\n\t * Checks if `value` is a plain object, that is, an object created by the\n\t * `Object` constructor or one with a `[[Prototype]]` of `null`.\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 0.8.0\n\t * @category Lang\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.\n\t * @example\n\t *\n\t * function Foo() {\n\t * this.a = 1;\n\t * }\n\t *\n\t * _.isPlainObject(new Foo);\n\t * // => false\n\t *\n\t * _.isPlainObject([1, 2, 3]);\n\t * // => false\n\t *\n\t * _.isPlainObject({ 'x': 0, 'y': 0 });\n\t * // => true\n\t *\n\t * _.isPlainObject(Object.create(null));\n\t * // => true\n\t */\n\tfunction isPlainObject(value) {\n\t if (!isObjectLike(value) ||\n\t objectToString.call(value) != objectTag || isHostObject(value)) {\n\t return false;\n\t }\n\t var proto = getPrototype(value);\n\t if (proto === null) {\n\t return true;\n\t }\n\t var Ctor = hasOwnProperty.call(proto, 'constructor') && proto.constructor;\n\t return (typeof Ctor == 'function' &&\n\t Ctor instanceof Ctor && funcToString.call(Ctor) == objectCtorString);\n\t}\n\t\n\tmodule.exports = isPlainObject;\n\n\n/***/ },\n/* 101 */\n/*!********************************!*\\\n !*** ./~/lodash.once/index.js ***!\n \\********************************/\n/***/ function(module, exports) {\n\n\t/**\n\t * lodash (Custom Build) \n\t * Build: `lodash modularize exports=\"npm\" -o ./`\n\t * Copyright jQuery Foundation and other contributors \n\t * Released under MIT license \n\t * Based on Underscore.js 1.8.3 \n\t * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n\t */\n\t\n\t/** Used as the `TypeError` message for \"Functions\" methods. */\n\tvar FUNC_ERROR_TEXT = 'Expected a function';\n\t\n\t/** Used as references for various `Number` constants. */\n\tvar INFINITY = 1 / 0,\n\t MAX_INTEGER = 1.7976931348623157e+308,\n\t NAN = 0 / 0;\n\t\n\t/** `Object#toString` result references. */\n\tvar symbolTag = '[object Symbol]';\n\t\n\t/** Used to match leading and trailing whitespace. */\n\tvar reTrim = /^\\s+|\\s+$/g;\n\t\n\t/** Used to detect bad signed hexadecimal string values. */\n\tvar reIsBadHex = /^[-+]0x[0-9a-f]+$/i;\n\t\n\t/** Used to detect binary string values. */\n\tvar reIsBinary = /^0b[01]+$/i;\n\t\n\t/** Used to detect octal string values. */\n\tvar reIsOctal = /^0o[0-7]+$/i;\n\t\n\t/** Built-in method references without a dependency on `root`. */\n\tvar freeParseInt = parseInt;\n\t\n\t/** Used for built-in method references. */\n\tvar objectProto = Object.prototype;\n\t\n\t/**\n\t * Used to resolve the\n\t * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)\n\t * of values.\n\t */\n\tvar objectToString = objectProto.toString;\n\t\n\t/**\n\t * Creates a function that invokes `func`, with the `this` binding and arguments\n\t * of the created function, while it's called less than `n` times. Subsequent\n\t * calls to the created function return the result of the last `func` invocation.\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 3.0.0\n\t * @category Function\n\t * @param {number} n The number of calls at which `func` is no longer invoked.\n\t * @param {Function} func The function to restrict.\n\t * @returns {Function} Returns the new restricted function.\n\t * @example\n\t *\n\t * jQuery(element).on('click', _.before(5, addContactToList));\n\t * // => Allows adding up to 4 contacts to the list.\n\t */\n\tfunction before(n, func) {\n\t var result;\n\t if (typeof func != 'function') {\n\t throw new TypeError(FUNC_ERROR_TEXT);\n\t }\n\t n = toInteger(n);\n\t return function() {\n\t if (--n > 0) {\n\t result = func.apply(this, arguments);\n\t }\n\t if (n <= 1) {\n\t func = undefined;\n\t }\n\t return result;\n\t };\n\t}\n\t\n\t/**\n\t * Creates a function that is restricted to invoking `func` once. Repeat calls\n\t * to the function return the value of the first invocation. The `func` is\n\t * invoked with the `this` binding and arguments of the created function.\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 0.1.0\n\t * @category Function\n\t * @param {Function} func The function to restrict.\n\t * @returns {Function} Returns the new restricted function.\n\t * @example\n\t *\n\t * var initialize = _.once(createApplication);\n\t * initialize();\n\t * initialize();\n\t * // => `createApplication` is invoked once\n\t */\n\tfunction once(func) {\n\t return before(2, func);\n\t}\n\t\n\t/**\n\t * Checks if `value` is the\n\t * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)\n\t * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 0.1.0\n\t * @category Lang\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n\t * @example\n\t *\n\t * _.isObject({});\n\t * // => true\n\t *\n\t * _.isObject([1, 2, 3]);\n\t * // => true\n\t *\n\t * _.isObject(_.noop);\n\t * // => true\n\t *\n\t * _.isObject(null);\n\t * // => false\n\t */\n\tfunction isObject(value) {\n\t var type = typeof value;\n\t return !!value && (type == 'object' || type == 'function');\n\t}\n\t\n\t/**\n\t * Checks if `value` is object-like. A value is object-like if it's not `null`\n\t * and has a `typeof` result of \"object\".\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 4.0.0\n\t * @category Lang\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is object-like, else `false`.\n\t * @example\n\t *\n\t * _.isObjectLike({});\n\t * // => true\n\t *\n\t * _.isObjectLike([1, 2, 3]);\n\t * // => true\n\t *\n\t * _.isObjectLike(_.noop);\n\t * // => false\n\t *\n\t * _.isObjectLike(null);\n\t * // => false\n\t */\n\tfunction isObjectLike(value) {\n\t return !!value && typeof value == 'object';\n\t}\n\t\n\t/**\n\t * Checks if `value` is classified as a `Symbol` primitive or object.\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 4.0.0\n\t * @category Lang\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is a symbol, else `false`.\n\t * @example\n\t *\n\t * _.isSymbol(Symbol.iterator);\n\t * // => true\n\t *\n\t * _.isSymbol('abc');\n\t * // => false\n\t */\n\tfunction isSymbol(value) {\n\t return typeof value == 'symbol' ||\n\t (isObjectLike(value) && objectToString.call(value) == symbolTag);\n\t}\n\t\n\t/**\n\t * Converts `value` to a finite number.\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 4.12.0\n\t * @category Lang\n\t * @param {*} value The value to convert.\n\t * @returns {number} Returns the converted number.\n\t * @example\n\t *\n\t * _.toFinite(3.2);\n\t * // => 3.2\n\t *\n\t * _.toFinite(Number.MIN_VALUE);\n\t * // => 5e-324\n\t *\n\t * _.toFinite(Infinity);\n\t * // => 1.7976931348623157e+308\n\t *\n\t * _.toFinite('3.2');\n\t * // => 3.2\n\t */\n\tfunction toFinite(value) {\n\t if (!value) {\n\t return value === 0 ? value : 0;\n\t }\n\t value = toNumber(value);\n\t if (value === INFINITY || value === -INFINITY) {\n\t var sign = (value < 0 ? -1 : 1);\n\t return sign * MAX_INTEGER;\n\t }\n\t return value === value ? value : 0;\n\t}\n\t\n\t/**\n\t * Converts `value` to an integer.\n\t *\n\t * **Note:** This method is loosely based on\n\t * [`ToInteger`](http://www.ecma-international.org/ecma-262/7.0/#sec-tointeger).\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 4.0.0\n\t * @category Lang\n\t * @param {*} value The value to convert.\n\t * @returns {number} Returns the converted integer.\n\t * @example\n\t *\n\t * _.toInteger(3.2);\n\t * // => 3\n\t *\n\t * _.toInteger(Number.MIN_VALUE);\n\t * // => 0\n\t *\n\t * _.toInteger(Infinity);\n\t * // => 1.7976931348623157e+308\n\t *\n\t * _.toInteger('3.2');\n\t * // => 3\n\t */\n\tfunction toInteger(value) {\n\t var result = toFinite(value),\n\t remainder = result % 1;\n\t\n\t return result === result ? (remainder ? result - remainder : result) : 0;\n\t}\n\t\n\t/**\n\t * Converts `value` to a number.\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 4.0.0\n\t * @category Lang\n\t * @param {*} value The value to process.\n\t * @returns {number} Returns the number.\n\t * @example\n\t *\n\t * _.toNumber(3.2);\n\t * // => 3.2\n\t *\n\t * _.toNumber(Number.MIN_VALUE);\n\t * // => 5e-324\n\t *\n\t * _.toNumber(Infinity);\n\t * // => Infinity\n\t *\n\t * _.toNumber('3.2');\n\t * // => 3.2\n\t */\n\tfunction toNumber(value) {\n\t if (typeof value == 'number') {\n\t return value;\n\t }\n\t if (isSymbol(value)) {\n\t return NAN;\n\t }\n\t if (isObject(value)) {\n\t var other = typeof value.valueOf == 'function' ? value.valueOf() : value;\n\t value = isObject(other) ? (other + '') : other;\n\t }\n\t if (typeof value != 'string') {\n\t return value === 0 ? value : +value;\n\t }\n\t value = value.replace(reTrim, '');\n\t var isBinary = reIsBinary.test(value);\n\t return (isBinary || reIsOctal.test(value))\n\t ? freeParseInt(value.slice(2), isBinary ? 2 : 8)\n\t : (reIsBadHex.test(value) ? NAN : +value);\n\t}\n\t\n\tmodule.exports = once;\n\n\n/***/ },\n/* 102 */\n/*!**********************************!*\\\n !*** ./~/lodash.result/index.js ***!\n \\**********************************/\n/***/ function(module, exports) {\n\n\t/* WEBPACK VAR INJECTION */(function(global) {/**\n\t * lodash (Custom Build) \n\t * Build: `lodash modularize exports=\"npm\" -o ./`\n\t * Copyright jQuery Foundation and other contributors \n\t * Released under MIT license \n\t * Based on Underscore.js 1.8.3 \n\t * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n\t */\n\t\n\t/** Used as the `TypeError` message for \"Functions\" methods. */\n\tvar FUNC_ERROR_TEXT = 'Expected a function';\n\t\n\t/** Used to stand-in for `undefined` hash values. */\n\tvar HASH_UNDEFINED = '__lodash_hash_undefined__';\n\t\n\t/** Used as references for various `Number` constants. */\n\tvar INFINITY = 1 / 0;\n\t\n\t/** `Object#toString` result references. */\n\tvar funcTag = '[object Function]',\n\t genTag = '[object GeneratorFunction]',\n\t symbolTag = '[object Symbol]';\n\t\n\t/** Used to match property names within property paths. */\n\tvar reIsDeepProp = /\\.|\\[(?:[^[\\]]*|([\"'])(?:(?!\\1)[^\\\\]|\\\\.)*?\\1)\\]/,\n\t reIsPlainProp = /^\\w*$/,\n\t reLeadingDot = /^\\./,\n\t rePropName = /[^.[\\]]+|\\[(?:(-?\\d+(?:\\.\\d+)?)|([\"'])((?:(?!\\2)[^\\\\]|\\\\.)*?)\\2)\\]|(?=(?:\\.|\\[\\])(?:\\.|\\[\\]|$))/g;\n\t\n\t/**\n\t * Used to match `RegExp`\n\t * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).\n\t */\n\tvar reRegExpChar = /[\\\\^$.*+?()[\\]{}|]/g;\n\t\n\t/** Used to match backslashes in property paths. */\n\tvar reEscapeChar = /\\\\(\\\\)?/g;\n\t\n\t/** Used to detect host constructors (Safari). */\n\tvar reIsHostCtor = /^\\[object .+?Constructor\\]$/;\n\t\n\t/** Detect free variable `global` from Node.js. */\n\tvar freeGlobal = typeof global == 'object' && global && global.Object === Object && global;\n\t\n\t/** Detect free variable `self`. */\n\tvar freeSelf = typeof self == 'object' && self && self.Object === Object && self;\n\t\n\t/** Used as a reference to the global object. */\n\tvar root = freeGlobal || freeSelf || Function('return this')();\n\t\n\t/**\n\t * Gets the value at `key` of `object`.\n\t *\n\t * @private\n\t * @param {Object} [object] The object to query.\n\t * @param {string} key The key of the property to get.\n\t * @returns {*} Returns the property value.\n\t */\n\tfunction getValue(object, key) {\n\t return object == null ? undefined : object[key];\n\t}\n\t\n\t/**\n\t * Checks if `value` is a host object in IE < 9.\n\t *\n\t * @private\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is a host object, else `false`.\n\t */\n\tfunction isHostObject(value) {\n\t // Many host objects are `Object` objects that can coerce to strings\n\t // despite having improperly defined `toString` methods.\n\t var result = false;\n\t if (value != null && typeof value.toString != 'function') {\n\t try {\n\t result = !!(value + '');\n\t } catch (e) {}\n\t }\n\t return result;\n\t}\n\t\n\t/** Used for built-in method references. */\n\tvar arrayProto = Array.prototype,\n\t funcProto = Function.prototype,\n\t objectProto = Object.prototype;\n\t\n\t/** Used to detect overreaching core-js shims. */\n\tvar coreJsData = root['__core-js_shared__'];\n\t\n\t/** Used to detect methods masquerading as native. */\n\tvar maskSrcKey = (function() {\n\t var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || '');\n\t return uid ? ('Symbol(src)_1.' + uid) : '';\n\t}());\n\t\n\t/** Used to resolve the decompiled source of functions. */\n\tvar funcToString = funcProto.toString;\n\t\n\t/** Used to check objects for own properties. */\n\tvar hasOwnProperty = objectProto.hasOwnProperty;\n\t\n\t/**\n\t * Used to resolve the\n\t * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)\n\t * of values.\n\t */\n\tvar objectToString = objectProto.toString;\n\t\n\t/** Used to detect if a method is native. */\n\tvar reIsNative = RegExp('^' +\n\t funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\\\$&')\n\t .replace(/hasOwnProperty|(function).*?(?=\\\\\\()| for .+?(?=\\\\\\])/g, '$1.*?') + '$'\n\t);\n\t\n\t/** Built-in value references. */\n\tvar Symbol = root.Symbol,\n\t splice = arrayProto.splice;\n\t\n\t/* Built-in method references that are verified to be native. */\n\tvar Map = getNative(root, 'Map'),\n\t nativeCreate = getNative(Object, 'create');\n\t\n\t/** Used to convert symbols to primitives and strings. */\n\tvar symbolProto = Symbol ? Symbol.prototype : undefined,\n\t symbolToString = symbolProto ? symbolProto.toString : undefined;\n\t\n\t/**\n\t * Creates a hash object.\n\t *\n\t * @private\n\t * @constructor\n\t * @param {Array} [entries] The key-value pairs to cache.\n\t */\n\tfunction Hash(entries) {\n\t var index = -1,\n\t length = entries ? entries.length : 0;\n\t\n\t this.clear();\n\t while (++index < length) {\n\t var entry = entries[index];\n\t this.set(entry[0], entry[1]);\n\t }\n\t}\n\t\n\t/**\n\t * Removes all key-value entries from the hash.\n\t *\n\t * @private\n\t * @name clear\n\t * @memberOf Hash\n\t */\n\tfunction hashClear() {\n\t this.__data__ = nativeCreate ? nativeCreate(null) : {};\n\t}\n\t\n\t/**\n\t * Removes `key` and its value from the hash.\n\t *\n\t * @private\n\t * @name delete\n\t * @memberOf Hash\n\t * @param {Object} hash The hash to modify.\n\t * @param {string} key The key of the value to remove.\n\t * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n\t */\n\tfunction hashDelete(key) {\n\t return this.has(key) && delete this.__data__[key];\n\t}\n\t\n\t/**\n\t * Gets the hash value for `key`.\n\t *\n\t * @private\n\t * @name get\n\t * @memberOf Hash\n\t * @param {string} key The key of the value to get.\n\t * @returns {*} Returns the entry value.\n\t */\n\tfunction hashGet(key) {\n\t var data = this.__data__;\n\t if (nativeCreate) {\n\t var result = data[key];\n\t return result === HASH_UNDEFINED ? undefined : result;\n\t }\n\t return hasOwnProperty.call(data, key) ? data[key] : undefined;\n\t}\n\t\n\t/**\n\t * Checks if a hash value for `key` exists.\n\t *\n\t * @private\n\t * @name has\n\t * @memberOf Hash\n\t * @param {string} key The key of the entry to check.\n\t * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n\t */\n\tfunction hashHas(key) {\n\t var data = this.__data__;\n\t return nativeCreate ? data[key] !== undefined : hasOwnProperty.call(data, key);\n\t}\n\t\n\t/**\n\t * Sets the hash `key` to `value`.\n\t *\n\t * @private\n\t * @name set\n\t * @memberOf Hash\n\t * @param {string} key The key of the value to set.\n\t * @param {*} value The value to set.\n\t * @returns {Object} Returns the hash instance.\n\t */\n\tfunction hashSet(key, value) {\n\t var data = this.__data__;\n\t data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value;\n\t return this;\n\t}\n\t\n\t// Add methods to `Hash`.\n\tHash.prototype.clear = hashClear;\n\tHash.prototype['delete'] = hashDelete;\n\tHash.prototype.get = hashGet;\n\tHash.prototype.has = hashHas;\n\tHash.prototype.set = hashSet;\n\t\n\t/**\n\t * Creates an list cache object.\n\t *\n\t * @private\n\t * @constructor\n\t * @param {Array} [entries] The key-value pairs to cache.\n\t */\n\tfunction ListCache(entries) {\n\t var index = -1,\n\t length = entries ? entries.length : 0;\n\t\n\t this.clear();\n\t while (++index < length) {\n\t var entry = entries[index];\n\t this.set(entry[0], entry[1]);\n\t }\n\t}\n\t\n\t/**\n\t * Removes all key-value entries from the list cache.\n\t *\n\t * @private\n\t * @name clear\n\t * @memberOf ListCache\n\t */\n\tfunction listCacheClear() {\n\t this.__data__ = [];\n\t}\n\t\n\t/**\n\t * Removes `key` and its value from the list cache.\n\t *\n\t * @private\n\t * @name delete\n\t * @memberOf ListCache\n\t * @param {string} key The key of the value to remove.\n\t * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n\t */\n\tfunction listCacheDelete(key) {\n\t var data = this.__data__,\n\t index = assocIndexOf(data, key);\n\t\n\t if (index < 0) {\n\t return false;\n\t }\n\t var lastIndex = data.length - 1;\n\t if (index == lastIndex) {\n\t data.pop();\n\t } else {\n\t splice.call(data, index, 1);\n\t }\n\t return true;\n\t}\n\t\n\t/**\n\t * Gets the list cache value for `key`.\n\t *\n\t * @private\n\t * @name get\n\t * @memberOf ListCache\n\t * @param {string} key The key of the value to get.\n\t * @returns {*} Returns the entry value.\n\t */\n\tfunction listCacheGet(key) {\n\t var data = this.__data__,\n\t index = assocIndexOf(data, key);\n\t\n\t return index < 0 ? undefined : data[index][1];\n\t}\n\t\n\t/**\n\t * Checks if a list cache value for `key` exists.\n\t *\n\t * @private\n\t * @name has\n\t * @memberOf ListCache\n\t * @param {string} key The key of the entry to check.\n\t * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n\t */\n\tfunction listCacheHas(key) {\n\t return assocIndexOf(this.__data__, key) > -1;\n\t}\n\t\n\t/**\n\t * Sets the list cache `key` to `value`.\n\t *\n\t * @private\n\t * @name set\n\t * @memberOf ListCache\n\t * @param {string} key The key of the value to set.\n\t * @param {*} value The value to set.\n\t * @returns {Object} Returns the list cache instance.\n\t */\n\tfunction listCacheSet(key, value) {\n\t var data = this.__data__,\n\t index = assocIndexOf(data, key);\n\t\n\t if (index < 0) {\n\t data.push([key, value]);\n\t } else {\n\t data[index][1] = value;\n\t }\n\t return this;\n\t}\n\t\n\t// Add methods to `ListCache`.\n\tListCache.prototype.clear = listCacheClear;\n\tListCache.prototype['delete'] = listCacheDelete;\n\tListCache.prototype.get = listCacheGet;\n\tListCache.prototype.has = listCacheHas;\n\tListCache.prototype.set = listCacheSet;\n\t\n\t/**\n\t * Creates a map cache object to store key-value pairs.\n\t *\n\t * @private\n\t * @constructor\n\t * @param {Array} [entries] The key-value pairs to cache.\n\t */\n\tfunction MapCache(entries) {\n\t var index = -1,\n\t length = entries ? entries.length : 0;\n\t\n\t this.clear();\n\t while (++index < length) {\n\t var entry = entries[index];\n\t this.set(entry[0], entry[1]);\n\t }\n\t}\n\t\n\t/**\n\t * Removes all key-value entries from the map.\n\t *\n\t * @private\n\t * @name clear\n\t * @memberOf MapCache\n\t */\n\tfunction mapCacheClear() {\n\t this.__data__ = {\n\t 'hash': new Hash,\n\t 'map': new (Map || ListCache),\n\t 'string': new Hash\n\t };\n\t}\n\t\n\t/**\n\t * Removes `key` and its value from the map.\n\t *\n\t * @private\n\t * @name delete\n\t * @memberOf MapCache\n\t * @param {string} key The key of the value to remove.\n\t * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n\t */\n\tfunction mapCacheDelete(key) {\n\t return getMapData(this, key)['delete'](key);\n\t}\n\t\n\t/**\n\t * Gets the map value for `key`.\n\t *\n\t * @private\n\t * @name get\n\t * @memberOf MapCache\n\t * @param {string} key The key of the value to get.\n\t * @returns {*} Returns the entry value.\n\t */\n\tfunction mapCacheGet(key) {\n\t return getMapData(this, key).get(key);\n\t}\n\t\n\t/**\n\t * Checks if a map value for `key` exists.\n\t *\n\t * @private\n\t * @name has\n\t * @memberOf MapCache\n\t * @param {string} key The key of the entry to check.\n\t * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n\t */\n\tfunction mapCacheHas(key) {\n\t return getMapData(this, key).has(key);\n\t}\n\t\n\t/**\n\t * Sets the map `key` to `value`.\n\t *\n\t * @private\n\t * @name set\n\t * @memberOf MapCache\n\t * @param {string} key The key of the value to set.\n\t * @param {*} value The value to set.\n\t * @returns {Object} Returns the map cache instance.\n\t */\n\tfunction mapCacheSet(key, value) {\n\t getMapData(this, key).set(key, value);\n\t return this;\n\t}\n\t\n\t// Add methods to `MapCache`.\n\tMapCache.prototype.clear = mapCacheClear;\n\tMapCache.prototype['delete'] = mapCacheDelete;\n\tMapCache.prototype.get = mapCacheGet;\n\tMapCache.prototype.has = mapCacheHas;\n\tMapCache.prototype.set = mapCacheSet;\n\t\n\t/**\n\t * Gets the index at which the `key` is found in `array` of key-value pairs.\n\t *\n\t * @private\n\t * @param {Array} array The array to inspect.\n\t * @param {*} key The key to search for.\n\t * @returns {number} Returns the index of the matched value, else `-1`.\n\t */\n\tfunction assocIndexOf(array, key) {\n\t var length = array.length;\n\t while (length--) {\n\t if (eq(array[length][0], key)) {\n\t return length;\n\t }\n\t }\n\t return -1;\n\t}\n\t\n\t/**\n\t * The base implementation of `_.isNative` without bad shim checks.\n\t *\n\t * @private\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is a native function,\n\t * else `false`.\n\t */\n\tfunction baseIsNative(value) {\n\t if (!isObject(value) || isMasked(value)) {\n\t return false;\n\t }\n\t var pattern = (isFunction(value) || isHostObject(value)) ? reIsNative : reIsHostCtor;\n\t return pattern.test(toSource(value));\n\t}\n\t\n\t/**\n\t * The base implementation of `_.toString` which doesn't convert nullish\n\t * values to empty strings.\n\t *\n\t * @private\n\t * @param {*} value The value to process.\n\t * @returns {string} Returns the string.\n\t */\n\tfunction baseToString(value) {\n\t // Exit early for strings to avoid a performance hit in some environments.\n\t if (typeof value == 'string') {\n\t return value;\n\t }\n\t if (isSymbol(value)) {\n\t return symbolToString ? symbolToString.call(value) : '';\n\t }\n\t var result = (value + '');\n\t return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;\n\t}\n\t\n\t/**\n\t * Casts `value` to a path array if it's not one.\n\t *\n\t * @private\n\t * @param {*} value The value to inspect.\n\t * @returns {Array} Returns the cast property path array.\n\t */\n\tfunction castPath(value) {\n\t return isArray(value) ? value : stringToPath(value);\n\t}\n\t\n\t/**\n\t * Gets the data for `map`.\n\t *\n\t * @private\n\t * @param {Object} map The map to query.\n\t * @param {string} key The reference key.\n\t * @returns {*} Returns the map data.\n\t */\n\tfunction getMapData(map, key) {\n\t var data = map.__data__;\n\t return isKeyable(key)\n\t ? data[typeof key == 'string' ? 'string' : 'hash']\n\t : data.map;\n\t}\n\t\n\t/**\n\t * Gets the native function at `key` of `object`.\n\t *\n\t * @private\n\t * @param {Object} object The object to query.\n\t * @param {string} key The key of the method to get.\n\t * @returns {*} Returns the function if it's native, else `undefined`.\n\t */\n\tfunction getNative(object, key) {\n\t var value = getValue(object, key);\n\t return baseIsNative(value) ? value : undefined;\n\t}\n\t\n\t/**\n\t * Checks if `value` is a property name and not a property path.\n\t *\n\t * @private\n\t * @param {*} value The value to check.\n\t * @param {Object} [object] The object to query keys on.\n\t * @returns {boolean} Returns `true` if `value` is a property name, else `false`.\n\t */\n\tfunction isKey(value, object) {\n\t if (isArray(value)) {\n\t return false;\n\t }\n\t var type = typeof value;\n\t if (type == 'number' || type == 'symbol' || type == 'boolean' ||\n\t value == null || isSymbol(value)) {\n\t return true;\n\t }\n\t return reIsPlainProp.test(value) || !reIsDeepProp.test(value) ||\n\t (object != null && value in Object(object));\n\t}\n\t\n\t/**\n\t * Checks if `value` is suitable for use as unique object key.\n\t *\n\t * @private\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is suitable, else `false`.\n\t */\n\tfunction isKeyable(value) {\n\t var type = typeof value;\n\t return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean')\n\t ? (value !== '__proto__')\n\t : (value === null);\n\t}\n\t\n\t/**\n\t * Checks if `func` has its source masked.\n\t *\n\t * @private\n\t * @param {Function} func The function to check.\n\t * @returns {boolean} Returns `true` if `func` is masked, else `false`.\n\t */\n\tfunction isMasked(func) {\n\t return !!maskSrcKey && (maskSrcKey in func);\n\t}\n\t\n\t/**\n\t * Converts `string` to a property path array.\n\t *\n\t * @private\n\t * @param {string} string The string to convert.\n\t * @returns {Array} Returns the property path array.\n\t */\n\tvar stringToPath = memoize(function(string) {\n\t string = toString(string);\n\t\n\t var result = [];\n\t if (reLeadingDot.test(string)) {\n\t result.push('');\n\t }\n\t string.replace(rePropName, function(match, number, quote, string) {\n\t result.push(quote ? string.replace(reEscapeChar, '$1') : (number || match));\n\t });\n\t return result;\n\t});\n\t\n\t/**\n\t * Converts `value` to a string key if it's not a string or symbol.\n\t *\n\t * @private\n\t * @param {*} value The value to inspect.\n\t * @returns {string|symbol} Returns the key.\n\t */\n\tfunction toKey(value) {\n\t if (typeof value == 'string' || isSymbol(value)) {\n\t return value;\n\t }\n\t var result = (value + '');\n\t return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;\n\t}\n\t\n\t/**\n\t * Converts `func` to its source code.\n\t *\n\t * @private\n\t * @param {Function} func The function to process.\n\t * @returns {string} Returns the source code.\n\t */\n\tfunction toSource(func) {\n\t if (func != null) {\n\t try {\n\t return funcToString.call(func);\n\t } catch (e) {}\n\t try {\n\t return (func + '');\n\t } catch (e) {}\n\t }\n\t return '';\n\t}\n\t\n\t/**\n\t * Creates a function that memoizes the result of `func`. If `resolver` is\n\t * provided, it determines the cache key for storing the result based on the\n\t * arguments provided to the memoized function. By default, the first argument\n\t * provided to the memoized function is used as the map cache key. The `func`\n\t * is invoked with the `this` binding of the memoized function.\n\t *\n\t * **Note:** The cache is exposed as the `cache` property on the memoized\n\t * function. Its creation may be customized by replacing the `_.memoize.Cache`\n\t * constructor with one whose instances implement the\n\t * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object)\n\t * method interface of `delete`, `get`, `has`, and `set`.\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 0.1.0\n\t * @category Function\n\t * @param {Function} func The function to have its output memoized.\n\t * @param {Function} [resolver] The function to resolve the cache key.\n\t * @returns {Function} Returns the new memoized function.\n\t * @example\n\t *\n\t * var object = { 'a': 1, 'b': 2 };\n\t * var other = { 'c': 3, 'd': 4 };\n\t *\n\t * var values = _.memoize(_.values);\n\t * values(object);\n\t * // => [1, 2]\n\t *\n\t * values(other);\n\t * // => [3, 4]\n\t *\n\t * object.a = 2;\n\t * values(object);\n\t * // => [1, 2]\n\t *\n\t * // Modify the result cache.\n\t * values.cache.set(object, ['a', 'b']);\n\t * values(object);\n\t * // => ['a', 'b']\n\t *\n\t * // Replace `_.memoize.Cache`.\n\t * _.memoize.Cache = WeakMap;\n\t */\n\tfunction memoize(func, resolver) {\n\t if (typeof func != 'function' || (resolver && typeof resolver != 'function')) {\n\t throw new TypeError(FUNC_ERROR_TEXT);\n\t }\n\t var memoized = function() {\n\t var args = arguments,\n\t key = resolver ? resolver.apply(this, args) : args[0],\n\t cache = memoized.cache;\n\t\n\t if (cache.has(key)) {\n\t return cache.get(key);\n\t }\n\t var result = func.apply(this, args);\n\t memoized.cache = cache.set(key, result);\n\t return result;\n\t };\n\t memoized.cache = new (memoize.Cache || MapCache);\n\t return memoized;\n\t}\n\t\n\t// Assign cache to `_.memoize`.\n\tmemoize.Cache = MapCache;\n\t\n\t/**\n\t * Performs a\n\t * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n\t * comparison between two values to determine if they are equivalent.\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 4.0.0\n\t * @category Lang\n\t * @param {*} value The value to compare.\n\t * @param {*} other The other value to compare.\n\t * @returns {boolean} Returns `true` if the values are equivalent, else `false`.\n\t * @example\n\t *\n\t * var object = { 'a': 1 };\n\t * var other = { 'a': 1 };\n\t *\n\t * _.eq(object, object);\n\t * // => true\n\t *\n\t * _.eq(object, other);\n\t * // => false\n\t *\n\t * _.eq('a', 'a');\n\t * // => true\n\t *\n\t * _.eq('a', Object('a'));\n\t * // => false\n\t *\n\t * _.eq(NaN, NaN);\n\t * // => true\n\t */\n\tfunction eq(value, other) {\n\t return value === other || (value !== value && other !== other);\n\t}\n\t\n\t/**\n\t * Checks if `value` is classified as an `Array` object.\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 0.1.0\n\t * @category Lang\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is an array, else `false`.\n\t * @example\n\t *\n\t * _.isArray([1, 2, 3]);\n\t * // => true\n\t *\n\t * _.isArray(document.body.children);\n\t * // => false\n\t *\n\t * _.isArray('abc');\n\t * // => false\n\t *\n\t * _.isArray(_.noop);\n\t * // => false\n\t */\n\tvar isArray = Array.isArray;\n\t\n\t/**\n\t * Checks if `value` is classified as a `Function` object.\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 0.1.0\n\t * @category Lang\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is a function, else `false`.\n\t * @example\n\t *\n\t * _.isFunction(_);\n\t * // => true\n\t *\n\t * _.isFunction(/abc/);\n\t * // => false\n\t */\n\tfunction isFunction(value) {\n\t // The use of `Object#toString` avoids issues with the `typeof` operator\n\t // in Safari 8-9 which returns 'object' for typed array and other constructors.\n\t var tag = isObject(value) ? objectToString.call(value) : '';\n\t return tag == funcTag || tag == genTag;\n\t}\n\t\n\t/**\n\t * Checks if `value` is the\n\t * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)\n\t * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 0.1.0\n\t * @category Lang\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n\t * @example\n\t *\n\t * _.isObject({});\n\t * // => true\n\t *\n\t * _.isObject([1, 2, 3]);\n\t * // => true\n\t *\n\t * _.isObject(_.noop);\n\t * // => true\n\t *\n\t * _.isObject(null);\n\t * // => false\n\t */\n\tfunction isObject(value) {\n\t var type = typeof value;\n\t return !!value && (type == 'object' || type == 'function');\n\t}\n\t\n\t/**\n\t * Checks if `value` is object-like. A value is object-like if it's not `null`\n\t * and has a `typeof` result of \"object\".\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 4.0.0\n\t * @category Lang\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is object-like, else `false`.\n\t * @example\n\t *\n\t * _.isObjectLike({});\n\t * // => true\n\t *\n\t * _.isObjectLike([1, 2, 3]);\n\t * // => true\n\t *\n\t * _.isObjectLike(_.noop);\n\t * // => false\n\t *\n\t * _.isObjectLike(null);\n\t * // => false\n\t */\n\tfunction isObjectLike(value) {\n\t return !!value && typeof value == 'object';\n\t}\n\t\n\t/**\n\t * Checks if `value` is classified as a `Symbol` primitive or object.\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 4.0.0\n\t * @category Lang\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is a symbol, else `false`.\n\t * @example\n\t *\n\t * _.isSymbol(Symbol.iterator);\n\t * // => true\n\t *\n\t * _.isSymbol('abc');\n\t * // => false\n\t */\n\tfunction isSymbol(value) {\n\t return typeof value == 'symbol' ||\n\t (isObjectLike(value) && objectToString.call(value) == symbolTag);\n\t}\n\t\n\t/**\n\t * Converts `value` to a string. An empty string is returned for `null`\n\t * and `undefined` values. The sign of `-0` is preserved.\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 4.0.0\n\t * @category Lang\n\t * @param {*} value The value to process.\n\t * @returns {string} Returns the string.\n\t * @example\n\t *\n\t * _.toString(null);\n\t * // => ''\n\t *\n\t * _.toString(-0);\n\t * // => '-0'\n\t *\n\t * _.toString([1, 2, 3]);\n\t * // => '1,2,3'\n\t */\n\tfunction toString(value) {\n\t return value == null ? '' : baseToString(value);\n\t}\n\t\n\t/**\n\t * This method is like `_.get` except that if the resolved value is a\n\t * function it's invoked with the `this` binding of its parent object and\n\t * its result is returned.\n\t *\n\t * @static\n\t * @since 0.1.0\n\t * @memberOf _\n\t * @category Object\n\t * @param {Object} object The object to query.\n\t * @param {Array|string} path The path of the property to resolve.\n\t * @param {*} [defaultValue] The value returned for `undefined` resolved values.\n\t * @returns {*} Returns the resolved value.\n\t * @example\n\t *\n\t * var object = { 'a': [{ 'b': { 'c1': 3, 'c2': _.constant(4) } }] };\n\t *\n\t * _.result(object, 'a[0].b.c1');\n\t * // => 3\n\t *\n\t * _.result(object, 'a[0].b.c2');\n\t * // => 4\n\t *\n\t * _.result(object, 'a[0].b.c3', 'default');\n\t * // => 'default'\n\t *\n\t * _.result(object, 'a[0].b.c3', _.constant('default'));\n\t * // => 'default'\n\t */\n\tfunction result(object, path, defaultValue) {\n\t path = isKey(path, object) ? [path] : castPath(path);\n\t\n\t var index = -1,\n\t length = path.length;\n\t\n\t // Ensure the loop is entered when path is empty.\n\t if (!length) {\n\t object = undefined;\n\t length = 1;\n\t }\n\t while (++index < length) {\n\t var value = object == null ? undefined : object[toKey(path[index])];\n\t if (value === undefined) {\n\t index = length;\n\t value = defaultValue;\n\t }\n\t object = isFunction(value) ? value.call(object) : value;\n\t }\n\t return object;\n\t}\n\t\n\tmodule.exports = result;\n\t\n\t/* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }())))\n\n/***/ },\n/* 103 */\n/*!**********************************!*\\\n !*** ./~/lodash.uniqby/index.js ***!\n \\**********************************/\n/***/ function(module, exports, __webpack_require__) {\n\n\t/* WEBPACK VAR INJECTION */(function(global, module) {/**\n\t * lodash (Custom Build) \n\t * Build: `lodash modularize exports=\"npm\" -o ./`\n\t * Copyright jQuery Foundation and other contributors \n\t * Released under MIT license \n\t * Based on Underscore.js 1.8.3 \n\t * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n\t */\n\t\n\t/** Used as the size to enable large array optimizations. */\n\tvar LARGE_ARRAY_SIZE = 200;\n\t\n\t/** Used as the `TypeError` message for \"Functions\" methods. */\n\tvar FUNC_ERROR_TEXT = 'Expected a function';\n\t\n\t/** Used to stand-in for `undefined` hash values. */\n\tvar HASH_UNDEFINED = '__lodash_hash_undefined__';\n\t\n\t/** Used to compose bitmasks for comparison styles. */\n\tvar UNORDERED_COMPARE_FLAG = 1,\n\t PARTIAL_COMPARE_FLAG = 2;\n\t\n\t/** Used as references for various `Number` constants. */\n\tvar INFINITY = 1 / 0,\n\t MAX_SAFE_INTEGER = 9007199254740991;\n\t\n\t/** `Object#toString` result references. */\n\tvar argsTag = '[object Arguments]',\n\t arrayTag = '[object Array]',\n\t boolTag = '[object Boolean]',\n\t dateTag = '[object Date]',\n\t errorTag = '[object Error]',\n\t funcTag = '[object Function]',\n\t genTag = '[object GeneratorFunction]',\n\t mapTag = '[object Map]',\n\t numberTag = '[object Number]',\n\t objectTag = '[object Object]',\n\t promiseTag = '[object Promise]',\n\t regexpTag = '[object RegExp]',\n\t setTag = '[object Set]',\n\t stringTag = '[object String]',\n\t symbolTag = '[object Symbol]',\n\t weakMapTag = '[object WeakMap]';\n\t\n\tvar arrayBufferTag = '[object ArrayBuffer]',\n\t dataViewTag = '[object DataView]',\n\t float32Tag = '[object Float32Array]',\n\t float64Tag = '[object Float64Array]',\n\t int8Tag = '[object Int8Array]',\n\t int16Tag = '[object Int16Array]',\n\t int32Tag = '[object Int32Array]',\n\t uint8Tag = '[object Uint8Array]',\n\t uint8ClampedTag = '[object Uint8ClampedArray]',\n\t uint16Tag = '[object Uint16Array]',\n\t uint32Tag = '[object Uint32Array]';\n\t\n\t/** Used to match property names within property paths. */\n\tvar reIsDeepProp = /\\.|\\[(?:[^[\\]]*|([\"'])(?:(?!\\1)[^\\\\]|\\\\.)*?\\1)\\]/,\n\t reIsPlainProp = /^\\w*$/,\n\t reLeadingDot = /^\\./,\n\t rePropName = /[^.[\\]]+|\\[(?:(-?\\d+(?:\\.\\d+)?)|([\"'])((?:(?!\\2)[^\\\\]|\\\\.)*?)\\2)\\]|(?=(?:\\.|\\[\\])(?:\\.|\\[\\]|$))/g;\n\t\n\t/**\n\t * Used to match `RegExp`\n\t * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).\n\t */\n\tvar reRegExpChar = /[\\\\^$.*+?()[\\]{}|]/g;\n\t\n\t/** Used to match backslashes in property paths. */\n\tvar reEscapeChar = /\\\\(\\\\)?/g;\n\t\n\t/** Used to detect host constructors (Safari). */\n\tvar reIsHostCtor = /^\\[object .+?Constructor\\]$/;\n\t\n\t/** Used to detect unsigned integer values. */\n\tvar reIsUint = /^(?:0|[1-9]\\d*)$/;\n\t\n\t/** Used to identify `toStringTag` values of typed arrays. */\n\tvar typedArrayTags = {};\n\ttypedArrayTags[float32Tag] = typedArrayTags[float64Tag] =\n\ttypedArrayTags[int8Tag] = typedArrayTags[int16Tag] =\n\ttypedArrayTags[int32Tag] = typedArrayTags[uint8Tag] =\n\ttypedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] =\n\ttypedArrayTags[uint32Tag] = true;\n\ttypedArrayTags[argsTag] = typedArrayTags[arrayTag] =\n\ttypedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =\n\ttypedArrayTags[dataViewTag] = typedArrayTags[dateTag] =\n\ttypedArrayTags[errorTag] = typedArrayTags[funcTag] =\n\ttypedArrayTags[mapTag] = typedArrayTags[numberTag] =\n\ttypedArrayTags[objectTag] = typedArrayTags[regexpTag] =\n\ttypedArrayTags[setTag] = typedArrayTags[stringTag] =\n\ttypedArrayTags[weakMapTag] = false;\n\t\n\t/** Detect free variable `global` from Node.js. */\n\tvar freeGlobal = typeof global == 'object' && global && global.Object === Object && global;\n\t\n\t/** Detect free variable `self`. */\n\tvar freeSelf = typeof self == 'object' && self && self.Object === Object && self;\n\t\n\t/** Used as a reference to the global object. */\n\tvar root = freeGlobal || freeSelf || Function('return this')();\n\t\n\t/** Detect free variable `exports`. */\n\tvar freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports;\n\t\n\t/** Detect free variable `module`. */\n\tvar freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module;\n\t\n\t/** Detect the popular CommonJS extension `module.exports`. */\n\tvar moduleExports = freeModule && freeModule.exports === freeExports;\n\t\n\t/** Detect free variable `process` from Node.js. */\n\tvar freeProcess = moduleExports && freeGlobal.process;\n\t\n\t/** Used to access faster Node.js helpers. */\n\tvar nodeUtil = (function() {\n\t try {\n\t return freeProcess && freeProcess.binding('util');\n\t } catch (e) {}\n\t}());\n\t\n\t/* Node.js helper references. */\n\tvar nodeIsTypedArray = nodeUtil && nodeUtil.isTypedArray;\n\t\n\t/**\n\t * A specialized version of `_.includes` for arrays without support for\n\t * specifying an index to search from.\n\t *\n\t * @private\n\t * @param {Array} [array] The array to inspect.\n\t * @param {*} target The value to search for.\n\t * @returns {boolean} Returns `true` if `target` is found, else `false`.\n\t */\n\tfunction arrayIncludes(array, value) {\n\t var length = array ? array.length : 0;\n\t return !!length && baseIndexOf(array, value, 0) > -1;\n\t}\n\t\n\t/**\n\t * This function is like `arrayIncludes` except that it accepts a comparator.\n\t *\n\t * @private\n\t * @param {Array} [array] The array to inspect.\n\t * @param {*} target The value to search for.\n\t * @param {Function} comparator The comparator invoked per element.\n\t * @returns {boolean} Returns `true` if `target` is found, else `false`.\n\t */\n\tfunction arrayIncludesWith(array, value, comparator) {\n\t var index = -1,\n\t length = array ? array.length : 0;\n\t\n\t while (++index < length) {\n\t if (comparator(value, array[index])) {\n\t return true;\n\t }\n\t }\n\t return false;\n\t}\n\t\n\t/**\n\t * A specialized version of `_.some` for arrays without support for iteratee\n\t * shorthands.\n\t *\n\t * @private\n\t * @param {Array} [array] The array to iterate over.\n\t * @param {Function} predicate The function invoked per iteration.\n\t * @returns {boolean} Returns `true` if any element passes the predicate check,\n\t * else `false`.\n\t */\n\tfunction arraySome(array, predicate) {\n\t var index = -1,\n\t length = array ? array.length : 0;\n\t\n\t while (++index < length) {\n\t if (predicate(array[index], index, array)) {\n\t return true;\n\t }\n\t }\n\t return false;\n\t}\n\t\n\t/**\n\t * The base implementation of `_.findIndex` and `_.findLastIndex` without\n\t * support for iteratee shorthands.\n\t *\n\t * @private\n\t * @param {Array} array The array to inspect.\n\t * @param {Function} predicate The function invoked per iteration.\n\t * @param {number} fromIndex The index to search from.\n\t * @param {boolean} [fromRight] Specify iterating from right to left.\n\t * @returns {number} Returns the index of the matched value, else `-1`.\n\t */\n\tfunction baseFindIndex(array, predicate, fromIndex, fromRight) {\n\t var length = array.length,\n\t index = fromIndex + (fromRight ? 1 : -1);\n\t\n\t while ((fromRight ? index-- : ++index < length)) {\n\t if (predicate(array[index], index, array)) {\n\t return index;\n\t }\n\t }\n\t return -1;\n\t}\n\t\n\t/**\n\t * The base implementation of `_.indexOf` without `fromIndex` bounds checks.\n\t *\n\t * @private\n\t * @param {Array} array The array to inspect.\n\t * @param {*} value The value to search for.\n\t * @param {number} fromIndex The index to search from.\n\t * @returns {number} Returns the index of the matched value, else `-1`.\n\t */\n\tfunction baseIndexOf(array, value, fromIndex) {\n\t if (value !== value) {\n\t return baseFindIndex(array, baseIsNaN, fromIndex);\n\t }\n\t var index = fromIndex - 1,\n\t length = array.length;\n\t\n\t while (++index < length) {\n\t if (array[index] === value) {\n\t return index;\n\t }\n\t }\n\t return -1;\n\t}\n\t\n\t/**\n\t * The base implementation of `_.isNaN` without support for number objects.\n\t *\n\t * @private\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`.\n\t */\n\tfunction baseIsNaN(value) {\n\t return value !== value;\n\t}\n\t\n\t/**\n\t * The base implementation of `_.property` without support for deep paths.\n\t *\n\t * @private\n\t * @param {string} key The key of the property to get.\n\t * @returns {Function} Returns the new accessor function.\n\t */\n\tfunction baseProperty(key) {\n\t return function(object) {\n\t return object == null ? undefined : object[key];\n\t };\n\t}\n\t\n\t/**\n\t * The base implementation of `_.times` without support for iteratee shorthands\n\t * or max array length checks.\n\t *\n\t * @private\n\t * @param {number} n The number of times to invoke `iteratee`.\n\t * @param {Function} iteratee The function invoked per iteration.\n\t * @returns {Array} Returns the array of results.\n\t */\n\tfunction baseTimes(n, iteratee) {\n\t var index = -1,\n\t result = Array(n);\n\t\n\t while (++index < n) {\n\t result[index] = iteratee(index);\n\t }\n\t return result;\n\t}\n\t\n\t/**\n\t * The base implementation of `_.unary` without support for storing metadata.\n\t *\n\t * @private\n\t * @param {Function} func The function to cap arguments for.\n\t * @returns {Function} Returns the new capped function.\n\t */\n\tfunction baseUnary(func) {\n\t return function(value) {\n\t return func(value);\n\t };\n\t}\n\t\n\t/**\n\t * Checks if a cache value for `key` exists.\n\t *\n\t * @private\n\t * @param {Object} cache The cache to query.\n\t * @param {string} key The key of the entry to check.\n\t * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n\t */\n\tfunction cacheHas(cache, key) {\n\t return cache.has(key);\n\t}\n\t\n\t/**\n\t * Gets the value at `key` of `object`.\n\t *\n\t * @private\n\t * @param {Object} [object] The object to query.\n\t * @param {string} key The key of the property to get.\n\t * @returns {*} Returns the property value.\n\t */\n\tfunction getValue(object, key) {\n\t return object == null ? undefined : object[key];\n\t}\n\t\n\t/**\n\t * Checks if `value` is a host object in IE < 9.\n\t *\n\t * @private\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is a host object, else `false`.\n\t */\n\tfunction isHostObject(value) {\n\t // Many host objects are `Object` objects that can coerce to strings\n\t // despite having improperly defined `toString` methods.\n\t var result = false;\n\t if (value != null && typeof value.toString != 'function') {\n\t try {\n\t result = !!(value + '');\n\t } catch (e) {}\n\t }\n\t return result;\n\t}\n\t\n\t/**\n\t * Converts `map` to its key-value pairs.\n\t *\n\t * @private\n\t * @param {Object} map The map to convert.\n\t * @returns {Array} Returns the key-value pairs.\n\t */\n\tfunction mapToArray(map) {\n\t var index = -1,\n\t result = Array(map.size);\n\t\n\t map.forEach(function(value, key) {\n\t result[++index] = [key, value];\n\t });\n\t return result;\n\t}\n\t\n\t/**\n\t * Creates a unary function that invokes `func` with its argument transformed.\n\t *\n\t * @private\n\t * @param {Function} func The function to wrap.\n\t * @param {Function} transform The argument transform.\n\t * @returns {Function} Returns the new function.\n\t */\n\tfunction overArg(func, transform) {\n\t return function(arg) {\n\t return func(transform(arg));\n\t };\n\t}\n\t\n\t/**\n\t * Converts `set` to an array of its values.\n\t *\n\t * @private\n\t * @param {Object} set The set to convert.\n\t * @returns {Array} Returns the values.\n\t */\n\tfunction setToArray(set) {\n\t var index = -1,\n\t result = Array(set.size);\n\t\n\t set.forEach(function(value) {\n\t result[++index] = value;\n\t });\n\t return result;\n\t}\n\t\n\t/** Used for built-in method references. */\n\tvar arrayProto = Array.prototype,\n\t funcProto = Function.prototype,\n\t objectProto = Object.prototype;\n\t\n\t/** Used to detect overreaching core-js shims. */\n\tvar coreJsData = root['__core-js_shared__'];\n\t\n\t/** Used to detect methods masquerading as native. */\n\tvar maskSrcKey = (function() {\n\t var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || '');\n\t return uid ? ('Symbol(src)_1.' + uid) : '';\n\t}());\n\t\n\t/** Used to resolve the decompiled source of functions. */\n\tvar funcToString = funcProto.toString;\n\t\n\t/** Used to check objects for own properties. */\n\tvar hasOwnProperty = objectProto.hasOwnProperty;\n\t\n\t/**\n\t * Used to resolve the\n\t * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)\n\t * of values.\n\t */\n\tvar objectToString = objectProto.toString;\n\t\n\t/** Used to detect if a method is native. */\n\tvar reIsNative = RegExp('^' +\n\t funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\\\$&')\n\t .replace(/hasOwnProperty|(function).*?(?=\\\\\\()| for .+?(?=\\\\\\])/g, '$1.*?') + '$'\n\t);\n\t\n\t/** Built-in value references. */\n\tvar Symbol = root.Symbol,\n\t Uint8Array = root.Uint8Array,\n\t propertyIsEnumerable = objectProto.propertyIsEnumerable,\n\t splice = arrayProto.splice;\n\t\n\t/* Built-in method references for those with the same name as other `lodash` methods. */\n\tvar nativeKeys = overArg(Object.keys, Object);\n\t\n\t/* Built-in method references that are verified to be native. */\n\tvar DataView = getNative(root, 'DataView'),\n\t Map = getNative(root, 'Map'),\n\t Promise = getNative(root, 'Promise'),\n\t Set = getNative(root, 'Set'),\n\t WeakMap = getNative(root, 'WeakMap'),\n\t nativeCreate = getNative(Object, 'create');\n\t\n\t/** Used to detect maps, sets, and weakmaps. */\n\tvar dataViewCtorString = toSource(DataView),\n\t mapCtorString = toSource(Map),\n\t promiseCtorString = toSource(Promise),\n\t setCtorString = toSource(Set),\n\t weakMapCtorString = toSource(WeakMap);\n\t\n\t/** Used to convert symbols to primitives and strings. */\n\tvar symbolProto = Symbol ? Symbol.prototype : undefined,\n\t symbolValueOf = symbolProto ? symbolProto.valueOf : undefined,\n\t symbolToString = symbolProto ? symbolProto.toString : undefined;\n\t\n\t/**\n\t * Creates a hash object.\n\t *\n\t * @private\n\t * @constructor\n\t * @param {Array} [entries] The key-value pairs to cache.\n\t */\n\tfunction Hash(entries) {\n\t var index = -1,\n\t length = entries ? entries.length : 0;\n\t\n\t this.clear();\n\t while (++index < length) {\n\t var entry = entries[index];\n\t this.set(entry[0], entry[1]);\n\t }\n\t}\n\t\n\t/**\n\t * Removes all key-value entries from the hash.\n\t *\n\t * @private\n\t * @name clear\n\t * @memberOf Hash\n\t */\n\tfunction hashClear() {\n\t this.__data__ = nativeCreate ? nativeCreate(null) : {};\n\t}\n\t\n\t/**\n\t * Removes `key` and its value from the hash.\n\t *\n\t * @private\n\t * @name delete\n\t * @memberOf Hash\n\t * @param {Object} hash The hash to modify.\n\t * @param {string} key The key of the value to remove.\n\t * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n\t */\n\tfunction hashDelete(key) {\n\t return this.has(key) && delete this.__data__[key];\n\t}\n\t\n\t/**\n\t * Gets the hash value for `key`.\n\t *\n\t * @private\n\t * @name get\n\t * @memberOf Hash\n\t * @param {string} key The key of the value to get.\n\t * @returns {*} Returns the entry value.\n\t */\n\tfunction hashGet(key) {\n\t var data = this.__data__;\n\t if (nativeCreate) {\n\t var result = data[key];\n\t return result === HASH_UNDEFINED ? undefined : result;\n\t }\n\t return hasOwnProperty.call(data, key) ? data[key] : undefined;\n\t}\n\t\n\t/**\n\t * Checks if a hash value for `key` exists.\n\t *\n\t * @private\n\t * @name has\n\t * @memberOf Hash\n\t * @param {string} key The key of the entry to check.\n\t * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n\t */\n\tfunction hashHas(key) {\n\t var data = this.__data__;\n\t return nativeCreate ? data[key] !== undefined : hasOwnProperty.call(data, key);\n\t}\n\t\n\t/**\n\t * Sets the hash `key` to `value`.\n\t *\n\t * @private\n\t * @name set\n\t * @memberOf Hash\n\t * @param {string} key The key of the value to set.\n\t * @param {*} value The value to set.\n\t * @returns {Object} Returns the hash instance.\n\t */\n\tfunction hashSet(key, value) {\n\t var data = this.__data__;\n\t data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value;\n\t return this;\n\t}\n\t\n\t// Add methods to `Hash`.\n\tHash.prototype.clear = hashClear;\n\tHash.prototype['delete'] = hashDelete;\n\tHash.prototype.get = hashGet;\n\tHash.prototype.has = hashHas;\n\tHash.prototype.set = hashSet;\n\t\n\t/**\n\t * Creates an list cache object.\n\t *\n\t * @private\n\t * @constructor\n\t * @param {Array} [entries] The key-value pairs to cache.\n\t */\n\tfunction ListCache(entries) {\n\t var index = -1,\n\t length = entries ? entries.length : 0;\n\t\n\t this.clear();\n\t while (++index < length) {\n\t var entry = entries[index];\n\t this.set(entry[0], entry[1]);\n\t }\n\t}\n\t\n\t/**\n\t * Removes all key-value entries from the list cache.\n\t *\n\t * @private\n\t * @name clear\n\t * @memberOf ListCache\n\t */\n\tfunction listCacheClear() {\n\t this.__data__ = [];\n\t}\n\t\n\t/**\n\t * Removes `key` and its value from the list cache.\n\t *\n\t * @private\n\t * @name delete\n\t * @memberOf ListCache\n\t * @param {string} key The key of the value to remove.\n\t * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n\t */\n\tfunction listCacheDelete(key) {\n\t var data = this.__data__,\n\t index = assocIndexOf(data, key);\n\t\n\t if (index < 0) {\n\t return false;\n\t }\n\t var lastIndex = data.length - 1;\n\t if (index == lastIndex) {\n\t data.pop();\n\t } else {\n\t splice.call(data, index, 1);\n\t }\n\t return true;\n\t}\n\t\n\t/**\n\t * Gets the list cache value for `key`.\n\t *\n\t * @private\n\t * @name get\n\t * @memberOf ListCache\n\t * @param {string} key The key of the value to get.\n\t * @returns {*} Returns the entry value.\n\t */\n\tfunction listCacheGet(key) {\n\t var data = this.__data__,\n\t index = assocIndexOf(data, key);\n\t\n\t return index < 0 ? undefined : data[index][1];\n\t}\n\t\n\t/**\n\t * Checks if a list cache value for `key` exists.\n\t *\n\t * @private\n\t * @name has\n\t * @memberOf ListCache\n\t * @param {string} key The key of the entry to check.\n\t * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n\t */\n\tfunction listCacheHas(key) {\n\t return assocIndexOf(this.__data__, key) > -1;\n\t}\n\t\n\t/**\n\t * Sets the list cache `key` to `value`.\n\t *\n\t * @private\n\t * @name set\n\t * @memberOf ListCache\n\t * @param {string} key The key of the value to set.\n\t * @param {*} value The value to set.\n\t * @returns {Object} Returns the list cache instance.\n\t */\n\tfunction listCacheSet(key, value) {\n\t var data = this.__data__,\n\t index = assocIndexOf(data, key);\n\t\n\t if (index < 0) {\n\t data.push([key, value]);\n\t } else {\n\t data[index][1] = value;\n\t }\n\t return this;\n\t}\n\t\n\t// Add methods to `ListCache`.\n\tListCache.prototype.clear = listCacheClear;\n\tListCache.prototype['delete'] = listCacheDelete;\n\tListCache.prototype.get = listCacheGet;\n\tListCache.prototype.has = listCacheHas;\n\tListCache.prototype.set = listCacheSet;\n\t\n\t/**\n\t * Creates a map cache object to store key-value pairs.\n\t *\n\t * @private\n\t * @constructor\n\t * @param {Array} [entries] The key-value pairs to cache.\n\t */\n\tfunction MapCache(entries) {\n\t var index = -1,\n\t length = entries ? entries.length : 0;\n\t\n\t this.clear();\n\t while (++index < length) {\n\t var entry = entries[index];\n\t this.set(entry[0], entry[1]);\n\t }\n\t}\n\t\n\t/**\n\t * Removes all key-value entries from the map.\n\t *\n\t * @private\n\t * @name clear\n\t * @memberOf MapCache\n\t */\n\tfunction mapCacheClear() {\n\t this.__data__ = {\n\t 'hash': new Hash,\n\t 'map': new (Map || ListCache),\n\t 'string': new Hash\n\t };\n\t}\n\t\n\t/**\n\t * Removes `key` and its value from the map.\n\t *\n\t * @private\n\t * @name delete\n\t * @memberOf MapCache\n\t * @param {string} key The key of the value to remove.\n\t * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n\t */\n\tfunction mapCacheDelete(key) {\n\t return getMapData(this, key)['delete'](key);\n\t}\n\t\n\t/**\n\t * Gets the map value for `key`.\n\t *\n\t * @private\n\t * @name get\n\t * @memberOf MapCache\n\t * @param {string} key The key of the value to get.\n\t * @returns {*} Returns the entry value.\n\t */\n\tfunction mapCacheGet(key) {\n\t return getMapData(this, key).get(key);\n\t}\n\t\n\t/**\n\t * Checks if a map value for `key` exists.\n\t *\n\t * @private\n\t * @name has\n\t * @memberOf MapCache\n\t * @param {string} key The key of the entry to check.\n\t * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n\t */\n\tfunction mapCacheHas(key) {\n\t return getMapData(this, key).has(key);\n\t}\n\t\n\t/**\n\t * Sets the map `key` to `value`.\n\t *\n\t * @private\n\t * @name set\n\t * @memberOf MapCache\n\t * @param {string} key The key of the value to set.\n\t * @param {*} value The value to set.\n\t * @returns {Object} Returns the map cache instance.\n\t */\n\tfunction mapCacheSet(key, value) {\n\t getMapData(this, key).set(key, value);\n\t return this;\n\t}\n\t\n\t// Add methods to `MapCache`.\n\tMapCache.prototype.clear = mapCacheClear;\n\tMapCache.prototype['delete'] = mapCacheDelete;\n\tMapCache.prototype.get = mapCacheGet;\n\tMapCache.prototype.has = mapCacheHas;\n\tMapCache.prototype.set = mapCacheSet;\n\t\n\t/**\n\t *\n\t * Creates an array cache object to store unique values.\n\t *\n\t * @private\n\t * @constructor\n\t * @param {Array} [values] The values to cache.\n\t */\n\tfunction SetCache(values) {\n\t var index = -1,\n\t length = values ? values.length : 0;\n\t\n\t this.__data__ = new MapCache;\n\t while (++index < length) {\n\t this.add(values[index]);\n\t }\n\t}\n\t\n\t/**\n\t * Adds `value` to the array cache.\n\t *\n\t * @private\n\t * @name add\n\t * @memberOf SetCache\n\t * @alias push\n\t * @param {*} value The value to cache.\n\t * @returns {Object} Returns the cache instance.\n\t */\n\tfunction setCacheAdd(value) {\n\t this.__data__.set(value, HASH_UNDEFINED);\n\t return this;\n\t}\n\t\n\t/**\n\t * Checks if `value` is in the array cache.\n\t *\n\t * @private\n\t * @name has\n\t * @memberOf SetCache\n\t * @param {*} value The value to search for.\n\t * @returns {number} Returns `true` if `value` is found, else `false`.\n\t */\n\tfunction setCacheHas(value) {\n\t return this.__data__.has(value);\n\t}\n\t\n\t// Add methods to `SetCache`.\n\tSetCache.prototype.add = SetCache.prototype.push = setCacheAdd;\n\tSetCache.prototype.has = setCacheHas;\n\t\n\t/**\n\t * Creates a stack cache object to store key-value pairs.\n\t *\n\t * @private\n\t * @constructor\n\t * @param {Array} [entries] The key-value pairs to cache.\n\t */\n\tfunction Stack(entries) {\n\t this.__data__ = new ListCache(entries);\n\t}\n\t\n\t/**\n\t * Removes all key-value entries from the stack.\n\t *\n\t * @private\n\t * @name clear\n\t * @memberOf Stack\n\t */\n\tfunction stackClear() {\n\t this.__data__ = new ListCache;\n\t}\n\t\n\t/**\n\t * Removes `key` and its value from the stack.\n\t *\n\t * @private\n\t * @name delete\n\t * @memberOf Stack\n\t * @param {string} key The key of the value to remove.\n\t * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n\t */\n\tfunction stackDelete(key) {\n\t return this.__data__['delete'](key);\n\t}\n\t\n\t/**\n\t * Gets the stack value for `key`.\n\t *\n\t * @private\n\t * @name get\n\t * @memberOf Stack\n\t * @param {string} key The key of the value to get.\n\t * @returns {*} Returns the entry value.\n\t */\n\tfunction stackGet(key) {\n\t return this.__data__.get(key);\n\t}\n\t\n\t/**\n\t * Checks if a stack value for `key` exists.\n\t *\n\t * @private\n\t * @name has\n\t * @memberOf Stack\n\t * @param {string} key The key of the entry to check.\n\t * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n\t */\n\tfunction stackHas(key) {\n\t return this.__data__.has(key);\n\t}\n\t\n\t/**\n\t * Sets the stack `key` to `value`.\n\t *\n\t * @private\n\t * @name set\n\t * @memberOf Stack\n\t * @param {string} key The key of the value to set.\n\t * @param {*} value The value to set.\n\t * @returns {Object} Returns the stack cache instance.\n\t */\n\tfunction stackSet(key, value) {\n\t var cache = this.__data__;\n\t if (cache instanceof ListCache) {\n\t var pairs = cache.__data__;\n\t if (!Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) {\n\t pairs.push([key, value]);\n\t return this;\n\t }\n\t cache = this.__data__ = new MapCache(pairs);\n\t }\n\t cache.set(key, value);\n\t return this;\n\t}\n\t\n\t// Add methods to `Stack`.\n\tStack.prototype.clear = stackClear;\n\tStack.prototype['delete'] = stackDelete;\n\tStack.prototype.get = stackGet;\n\tStack.prototype.has = stackHas;\n\tStack.prototype.set = stackSet;\n\t\n\t/**\n\t * Creates an array of the enumerable property names of the array-like `value`.\n\t *\n\t * @private\n\t * @param {*} value The value to query.\n\t * @param {boolean} inherited Specify returning inherited property names.\n\t * @returns {Array} Returns the array of property names.\n\t */\n\tfunction arrayLikeKeys(value, inherited) {\n\t // Safari 8.1 makes `arguments.callee` enumerable in strict mode.\n\t // Safari 9 makes `arguments.length` enumerable in strict mode.\n\t var result = (isArray(value) || isArguments(value))\n\t ? baseTimes(value.length, String)\n\t : [];\n\t\n\t var length = result.length,\n\t skipIndexes = !!length;\n\t\n\t for (var key in value) {\n\t if ((inherited || hasOwnProperty.call(value, key)) &&\n\t !(skipIndexes && (key == 'length' || isIndex(key, length)))) {\n\t result.push(key);\n\t }\n\t }\n\t return result;\n\t}\n\t\n\t/**\n\t * Gets the index at which the `key` is found in `array` of key-value pairs.\n\t *\n\t * @private\n\t * @param {Array} array The array to inspect.\n\t * @param {*} key The key to search for.\n\t * @returns {number} Returns the index of the matched value, else `-1`.\n\t */\n\tfunction assocIndexOf(array, key) {\n\t var length = array.length;\n\t while (length--) {\n\t if (eq(array[length][0], key)) {\n\t return length;\n\t }\n\t }\n\t return -1;\n\t}\n\t\n\t/**\n\t * The base implementation of `_.get` without support for default values.\n\t *\n\t * @private\n\t * @param {Object} object The object to query.\n\t * @param {Array|string} path The path of the property to get.\n\t * @returns {*} Returns the resolved value.\n\t */\n\tfunction baseGet(object, path) {\n\t path = isKey(path, object) ? [path] : castPath(path);\n\t\n\t var index = 0,\n\t length = path.length;\n\t\n\t while (object != null && index < length) {\n\t object = object[toKey(path[index++])];\n\t }\n\t return (index && index == length) ? object : undefined;\n\t}\n\t\n\t/**\n\t * The base implementation of `getTag`.\n\t *\n\t * @private\n\t * @param {*} value The value to query.\n\t * @returns {string} Returns the `toStringTag`.\n\t */\n\tfunction baseGetTag(value) {\n\t return objectToString.call(value);\n\t}\n\t\n\t/**\n\t * The base implementation of `_.hasIn` without support for deep paths.\n\t *\n\t * @private\n\t * @param {Object} [object] The object to query.\n\t * @param {Array|string} key The key to check.\n\t * @returns {boolean} Returns `true` if `key` exists, else `false`.\n\t */\n\tfunction baseHasIn(object, key) {\n\t return object != null && key in Object(object);\n\t}\n\t\n\t/**\n\t * The base implementation of `_.isEqual` which supports partial comparisons\n\t * and tracks traversed objects.\n\t *\n\t * @private\n\t * @param {*} value The value to compare.\n\t * @param {*} other The other value to compare.\n\t * @param {Function} [customizer] The function to customize comparisons.\n\t * @param {boolean} [bitmask] The bitmask of comparison flags.\n\t * The bitmask may be composed of the following flags:\n\t * 1 - Unordered comparison\n\t * 2 - Partial comparison\n\t * @param {Object} [stack] Tracks traversed `value` and `other` objects.\n\t * @returns {boolean} Returns `true` if the values are equivalent, else `false`.\n\t */\n\tfunction baseIsEqual(value, other, customizer, bitmask, stack) {\n\t if (value === other) {\n\t return true;\n\t }\n\t if (value == null || other == null || (!isObject(value) && !isObjectLike(other))) {\n\t return value !== value && other !== other;\n\t }\n\t return baseIsEqualDeep(value, other, baseIsEqual, customizer, bitmask, stack);\n\t}\n\t\n\t/**\n\t * A specialized version of `baseIsEqual` for arrays and objects which performs\n\t * deep comparisons and tracks traversed objects enabling objects with circular\n\t * references to be compared.\n\t *\n\t * @private\n\t * @param {Object} object The object to compare.\n\t * @param {Object} other The other object to compare.\n\t * @param {Function} equalFunc The function to determine equivalents of values.\n\t * @param {Function} [customizer] The function to customize comparisons.\n\t * @param {number} [bitmask] The bitmask of comparison flags. See `baseIsEqual`\n\t * for more details.\n\t * @param {Object} [stack] Tracks traversed `object` and `other` objects.\n\t * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.\n\t */\n\tfunction baseIsEqualDeep(object, other, equalFunc, customizer, bitmask, stack) {\n\t var objIsArr = isArray(object),\n\t othIsArr = isArray(other),\n\t objTag = arrayTag,\n\t othTag = arrayTag;\n\t\n\t if (!objIsArr) {\n\t objTag = getTag(object);\n\t objTag = objTag == argsTag ? objectTag : objTag;\n\t }\n\t if (!othIsArr) {\n\t othTag = getTag(other);\n\t othTag = othTag == argsTag ? objectTag : othTag;\n\t }\n\t var objIsObj = objTag == objectTag && !isHostObject(object),\n\t othIsObj = othTag == objectTag && !isHostObject(other),\n\t isSameTag = objTag == othTag;\n\t\n\t if (isSameTag && !objIsObj) {\n\t stack || (stack = new Stack);\n\t return (objIsArr || isTypedArray(object))\n\t ? equalArrays(object, other, equalFunc, customizer, bitmask, stack)\n\t : equalByTag(object, other, objTag, equalFunc, customizer, bitmask, stack);\n\t }\n\t if (!(bitmask & PARTIAL_COMPARE_FLAG)) {\n\t var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'),\n\t othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__');\n\t\n\t if (objIsWrapped || othIsWrapped) {\n\t var objUnwrapped = objIsWrapped ? object.value() : object,\n\t othUnwrapped = othIsWrapped ? other.value() : other;\n\t\n\t stack || (stack = new Stack);\n\t return equalFunc(objUnwrapped, othUnwrapped, customizer, bitmask, stack);\n\t }\n\t }\n\t if (!isSameTag) {\n\t return false;\n\t }\n\t stack || (stack = new Stack);\n\t return equalObjects(object, other, equalFunc, customizer, bitmask, stack);\n\t}\n\t\n\t/**\n\t * The base implementation of `_.isMatch` without support for iteratee shorthands.\n\t *\n\t * @private\n\t * @param {Object} object The object to inspect.\n\t * @param {Object} source The object of property values to match.\n\t * @param {Array} matchData The property names, values, and compare flags to match.\n\t * @param {Function} [customizer] The function to customize comparisons.\n\t * @returns {boolean} Returns `true` if `object` is a match, else `false`.\n\t */\n\tfunction baseIsMatch(object, source, matchData, customizer) {\n\t var index = matchData.length,\n\t length = index,\n\t noCustomizer = !customizer;\n\t\n\t if (object == null) {\n\t return !length;\n\t }\n\t object = Object(object);\n\t while (index--) {\n\t var data = matchData[index];\n\t if ((noCustomizer && data[2])\n\t ? data[1] !== object[data[0]]\n\t : !(data[0] in object)\n\t ) {\n\t return false;\n\t }\n\t }\n\t while (++index < length) {\n\t data = matchData[index];\n\t var key = data[0],\n\t objValue = object[key],\n\t srcValue = data[1];\n\t\n\t if (noCustomizer && data[2]) {\n\t if (objValue === undefined && !(key in object)) {\n\t return false;\n\t }\n\t } else {\n\t var stack = new Stack;\n\t if (customizer) {\n\t var result = customizer(objValue, srcValue, key, object, source, stack);\n\t }\n\t if (!(result === undefined\n\t ? baseIsEqual(srcValue, objValue, customizer, UNORDERED_COMPARE_FLAG | PARTIAL_COMPARE_FLAG, stack)\n\t : result\n\t )) {\n\t return false;\n\t }\n\t }\n\t }\n\t return true;\n\t}\n\t\n\t/**\n\t * The base implementation of `_.isNative` without bad shim checks.\n\t *\n\t * @private\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is a native function,\n\t * else `false`.\n\t */\n\tfunction baseIsNative(value) {\n\t if (!isObject(value) || isMasked(value)) {\n\t return false;\n\t }\n\t var pattern = (isFunction(value) || isHostObject(value)) ? reIsNative : reIsHostCtor;\n\t return pattern.test(toSource(value));\n\t}\n\t\n\t/**\n\t * The base implementation of `_.isTypedArray` without Node.js optimizations.\n\t *\n\t * @private\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.\n\t */\n\tfunction baseIsTypedArray(value) {\n\t return isObjectLike(value) &&\n\t isLength(value.length) && !!typedArrayTags[objectToString.call(value)];\n\t}\n\t\n\t/**\n\t * The base implementation of `_.iteratee`.\n\t *\n\t * @private\n\t * @param {*} [value=_.identity] The value to convert to an iteratee.\n\t * @returns {Function} Returns the iteratee.\n\t */\n\tfunction baseIteratee(value) {\n\t // Don't store the `typeof` result in a variable to avoid a JIT bug in Safari 9.\n\t // See https://bugs.webkit.org/show_bug.cgi?id=156034 for more details.\n\t if (typeof value == 'function') {\n\t return value;\n\t }\n\t if (value == null) {\n\t return identity;\n\t }\n\t if (typeof value == 'object') {\n\t return isArray(value)\n\t ? baseMatchesProperty(value[0], value[1])\n\t : baseMatches(value);\n\t }\n\t return property(value);\n\t}\n\t\n\t/**\n\t * The base implementation of `_.keys` which doesn't treat sparse arrays as dense.\n\t *\n\t * @private\n\t * @param {Object} object The object to query.\n\t * @returns {Array} Returns the array of property names.\n\t */\n\tfunction baseKeys(object) {\n\t if (!isPrototype(object)) {\n\t return nativeKeys(object);\n\t }\n\t var result = [];\n\t for (var key in Object(object)) {\n\t if (hasOwnProperty.call(object, key) && key != 'constructor') {\n\t result.push(key);\n\t }\n\t }\n\t return result;\n\t}\n\t\n\t/**\n\t * The base implementation of `_.matches` which doesn't clone `source`.\n\t *\n\t * @private\n\t * @param {Object} source The object of property values to match.\n\t * @returns {Function} Returns the new spec function.\n\t */\n\tfunction baseMatches(source) {\n\t var matchData = getMatchData(source);\n\t if (matchData.length == 1 && matchData[0][2]) {\n\t return matchesStrictComparable(matchData[0][0], matchData[0][1]);\n\t }\n\t return function(object) {\n\t return object === source || baseIsMatch(object, source, matchData);\n\t };\n\t}\n\t\n\t/**\n\t * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`.\n\t *\n\t * @private\n\t * @param {string} path The path of the property to get.\n\t * @param {*} srcValue The value to match.\n\t * @returns {Function} Returns the new spec function.\n\t */\n\tfunction baseMatchesProperty(path, srcValue) {\n\t if (isKey(path) && isStrictComparable(srcValue)) {\n\t return matchesStrictComparable(toKey(path), srcValue);\n\t }\n\t return function(object) {\n\t var objValue = get(object, path);\n\t return (objValue === undefined && objValue === srcValue)\n\t ? hasIn(object, path)\n\t : baseIsEqual(srcValue, objValue, undefined, UNORDERED_COMPARE_FLAG | PARTIAL_COMPARE_FLAG);\n\t };\n\t}\n\t\n\t/**\n\t * A specialized version of `baseProperty` which supports deep paths.\n\t *\n\t * @private\n\t * @param {Array|string} path The path of the property to get.\n\t * @returns {Function} Returns the new accessor function.\n\t */\n\tfunction basePropertyDeep(path) {\n\t return function(object) {\n\t return baseGet(object, path);\n\t };\n\t}\n\t\n\t/**\n\t * The base implementation of `_.toString` which doesn't convert nullish\n\t * values to empty strings.\n\t *\n\t * @private\n\t * @param {*} value The value to process.\n\t * @returns {string} Returns the string.\n\t */\n\tfunction baseToString(value) {\n\t // Exit early for strings to avoid a performance hit in some environments.\n\t if (typeof value == 'string') {\n\t return value;\n\t }\n\t if (isSymbol(value)) {\n\t return symbolToString ? symbolToString.call(value) : '';\n\t }\n\t var result = (value + '');\n\t return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;\n\t}\n\t\n\t/**\n\t * The base implementation of `_.uniqBy` without support for iteratee shorthands.\n\t *\n\t * @private\n\t * @param {Array} array The array to inspect.\n\t * @param {Function} [iteratee] The iteratee invoked per element.\n\t * @param {Function} [comparator] The comparator invoked per element.\n\t * @returns {Array} Returns the new duplicate free array.\n\t */\n\tfunction baseUniq(array, iteratee, comparator) {\n\t var index = -1,\n\t includes = arrayIncludes,\n\t length = array.length,\n\t isCommon = true,\n\t result = [],\n\t seen = result;\n\t\n\t if (comparator) {\n\t isCommon = false;\n\t includes = arrayIncludesWith;\n\t }\n\t else if (length >= LARGE_ARRAY_SIZE) {\n\t var set = iteratee ? null : createSet(array);\n\t if (set) {\n\t return setToArray(set);\n\t }\n\t isCommon = false;\n\t includes = cacheHas;\n\t seen = new SetCache;\n\t }\n\t else {\n\t seen = iteratee ? [] : result;\n\t }\n\t outer:\n\t while (++index < length) {\n\t var value = array[index],\n\t computed = iteratee ? iteratee(value) : value;\n\t\n\t value = (comparator || value !== 0) ? value : 0;\n\t if (isCommon && computed === computed) {\n\t var seenIndex = seen.length;\n\t while (seenIndex--) {\n\t if (seen[seenIndex] === computed) {\n\t continue outer;\n\t }\n\t }\n\t if (iteratee) {\n\t seen.push(computed);\n\t }\n\t result.push(value);\n\t }\n\t else if (!includes(seen, computed, comparator)) {\n\t if (seen !== result) {\n\t seen.push(computed);\n\t }\n\t result.push(value);\n\t }\n\t }\n\t return result;\n\t}\n\t\n\t/**\n\t * Casts `value` to a path array if it's not one.\n\t *\n\t * @private\n\t * @param {*} value The value to inspect.\n\t * @returns {Array} Returns the cast property path array.\n\t */\n\tfunction castPath(value) {\n\t return isArray(value) ? value : stringToPath(value);\n\t}\n\t\n\t/**\n\t * Creates a set object of `values`.\n\t *\n\t * @private\n\t * @param {Array} values The values to add to the set.\n\t * @returns {Object} Returns the new set.\n\t */\n\tvar createSet = !(Set && (1 / setToArray(new Set([,-0]))[1]) == INFINITY) ? noop : function(values) {\n\t return new Set(values);\n\t};\n\t\n\t/**\n\t * A specialized version of `baseIsEqualDeep` for arrays with support for\n\t * partial deep comparisons.\n\t *\n\t * @private\n\t * @param {Array} array The array to compare.\n\t * @param {Array} other The other array to compare.\n\t * @param {Function} equalFunc The function to determine equivalents of values.\n\t * @param {Function} customizer The function to customize comparisons.\n\t * @param {number} bitmask The bitmask of comparison flags. See `baseIsEqual`\n\t * for more details.\n\t * @param {Object} stack Tracks traversed `array` and `other` objects.\n\t * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`.\n\t */\n\tfunction equalArrays(array, other, equalFunc, customizer, bitmask, stack) {\n\t var isPartial = bitmask & PARTIAL_COMPARE_FLAG,\n\t arrLength = array.length,\n\t othLength = other.length;\n\t\n\t if (arrLength != othLength && !(isPartial && othLength > arrLength)) {\n\t return false;\n\t }\n\t // Assume cyclic values are equal.\n\t var stacked = stack.get(array);\n\t if (stacked && stack.get(other)) {\n\t return stacked == other;\n\t }\n\t var index = -1,\n\t result = true,\n\t seen = (bitmask & UNORDERED_COMPARE_FLAG) ? new SetCache : undefined;\n\t\n\t stack.set(array, other);\n\t stack.set(other, array);\n\t\n\t // Ignore non-index properties.\n\t while (++index < arrLength) {\n\t var arrValue = array[index],\n\t othValue = other[index];\n\t\n\t if (customizer) {\n\t var compared = isPartial\n\t ? customizer(othValue, arrValue, index, other, array, stack)\n\t : customizer(arrValue, othValue, index, array, other, stack);\n\t }\n\t if (compared !== undefined) {\n\t if (compared) {\n\t continue;\n\t }\n\t result = false;\n\t break;\n\t }\n\t // Recursively compare arrays (susceptible to call stack limits).\n\t if (seen) {\n\t if (!arraySome(other, function(othValue, othIndex) {\n\t if (!seen.has(othIndex) &&\n\t (arrValue === othValue || equalFunc(arrValue, othValue, customizer, bitmask, stack))) {\n\t return seen.add(othIndex);\n\t }\n\t })) {\n\t result = false;\n\t break;\n\t }\n\t } else if (!(\n\t arrValue === othValue ||\n\t equalFunc(arrValue, othValue, customizer, bitmask, stack)\n\t )) {\n\t result = false;\n\t break;\n\t }\n\t }\n\t stack['delete'](array);\n\t stack['delete'](other);\n\t return result;\n\t}\n\t\n\t/**\n\t * A specialized version of `baseIsEqualDeep` for comparing objects of\n\t * the same `toStringTag`.\n\t *\n\t * **Note:** This function only supports comparing values with tags of\n\t * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.\n\t *\n\t * @private\n\t * @param {Object} object The object to compare.\n\t * @param {Object} other The other object to compare.\n\t * @param {string} tag The `toStringTag` of the objects to compare.\n\t * @param {Function} equalFunc The function to determine equivalents of values.\n\t * @param {Function} customizer The function to customize comparisons.\n\t * @param {number} bitmask The bitmask of comparison flags. See `baseIsEqual`\n\t * for more details.\n\t * @param {Object} stack Tracks traversed `object` and `other` objects.\n\t * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.\n\t */\n\tfunction equalByTag(object, other, tag, equalFunc, customizer, bitmask, stack) {\n\t switch (tag) {\n\t case dataViewTag:\n\t if ((object.byteLength != other.byteLength) ||\n\t (object.byteOffset != other.byteOffset)) {\n\t return false;\n\t }\n\t object = object.buffer;\n\t other = other.buffer;\n\t\n\t case arrayBufferTag:\n\t if ((object.byteLength != other.byteLength) ||\n\t !equalFunc(new Uint8Array(object), new Uint8Array(other))) {\n\t return false;\n\t }\n\t return true;\n\t\n\t case boolTag:\n\t case dateTag:\n\t case numberTag:\n\t // Coerce booleans to `1` or `0` and dates to milliseconds.\n\t // Invalid dates are coerced to `NaN`.\n\t return eq(+object, +other);\n\t\n\t case errorTag:\n\t return object.name == other.name && object.message == other.message;\n\t\n\t case regexpTag:\n\t case stringTag:\n\t // Coerce regexes to strings and treat strings, primitives and objects,\n\t // as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring\n\t // for more details.\n\t return object == (other + '');\n\t\n\t case mapTag:\n\t var convert = mapToArray;\n\t\n\t case setTag:\n\t var isPartial = bitmask & PARTIAL_COMPARE_FLAG;\n\t convert || (convert = setToArray);\n\t\n\t if (object.size != other.size && !isPartial) {\n\t return false;\n\t }\n\t // Assume cyclic values are equal.\n\t var stacked = stack.get(object);\n\t if (stacked) {\n\t return stacked == other;\n\t }\n\t bitmask |= UNORDERED_COMPARE_FLAG;\n\t\n\t // Recursively compare objects (susceptible to call stack limits).\n\t stack.set(object, other);\n\t var result = equalArrays(convert(object), convert(other), equalFunc, customizer, bitmask, stack);\n\t stack['delete'](object);\n\t return result;\n\t\n\t case symbolTag:\n\t if (symbolValueOf) {\n\t return symbolValueOf.call(object) == symbolValueOf.call(other);\n\t }\n\t }\n\t return false;\n\t}\n\t\n\t/**\n\t * A specialized version of `baseIsEqualDeep` for objects with support for\n\t * partial deep comparisons.\n\t *\n\t * @private\n\t * @param {Object} object The object to compare.\n\t * @param {Object} other The other object to compare.\n\t * @param {Function} equalFunc The function to determine equivalents of values.\n\t * @param {Function} customizer The function to customize comparisons.\n\t * @param {number} bitmask The bitmask of comparison flags. See `baseIsEqual`\n\t * for more details.\n\t * @param {Object} stack Tracks traversed `object` and `other` objects.\n\t * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.\n\t */\n\tfunction equalObjects(object, other, equalFunc, customizer, bitmask, stack) {\n\t var isPartial = bitmask & PARTIAL_COMPARE_FLAG,\n\t objProps = keys(object),\n\t objLength = objProps.length,\n\t othProps = keys(other),\n\t othLength = othProps.length;\n\t\n\t if (objLength != othLength && !isPartial) {\n\t return false;\n\t }\n\t var index = objLength;\n\t while (index--) {\n\t var key = objProps[index];\n\t if (!(isPartial ? key in other : hasOwnProperty.call(other, key))) {\n\t return false;\n\t }\n\t }\n\t // Assume cyclic values are equal.\n\t var stacked = stack.get(object);\n\t if (stacked && stack.get(other)) {\n\t return stacked == other;\n\t }\n\t var result = true;\n\t stack.set(object, other);\n\t stack.set(other, object);\n\t\n\t var skipCtor = isPartial;\n\t while (++index < objLength) {\n\t key = objProps[index];\n\t var objValue = object[key],\n\t othValue = other[key];\n\t\n\t if (customizer) {\n\t var compared = isPartial\n\t ? customizer(othValue, objValue, key, other, object, stack)\n\t : customizer(objValue, othValue, key, object, other, stack);\n\t }\n\t // Recursively compare objects (susceptible to call stack limits).\n\t if (!(compared === undefined\n\t ? (objValue === othValue || equalFunc(objValue, othValue, customizer, bitmask, stack))\n\t : compared\n\t )) {\n\t result = false;\n\t break;\n\t }\n\t skipCtor || (skipCtor = key == 'constructor');\n\t }\n\t if (result && !skipCtor) {\n\t var objCtor = object.constructor,\n\t othCtor = other.constructor;\n\t\n\t // Non `Object` object instances with different constructors are not equal.\n\t if (objCtor != othCtor &&\n\t ('constructor' in object && 'constructor' in other) &&\n\t !(typeof objCtor == 'function' && objCtor instanceof objCtor &&\n\t typeof othCtor == 'function' && othCtor instanceof othCtor)) {\n\t result = false;\n\t }\n\t }\n\t stack['delete'](object);\n\t stack['delete'](other);\n\t return result;\n\t}\n\t\n\t/**\n\t * Gets the data for `map`.\n\t *\n\t * @private\n\t * @param {Object} map The map to query.\n\t * @param {string} key The reference key.\n\t * @returns {*} Returns the map data.\n\t */\n\tfunction getMapData(map, key) {\n\t var data = map.__data__;\n\t return isKeyable(key)\n\t ? data[typeof key == 'string' ? 'string' : 'hash']\n\t : data.map;\n\t}\n\t\n\t/**\n\t * Gets the property names, values, and compare flags of `object`.\n\t *\n\t * @private\n\t * @param {Object} object The object to query.\n\t * @returns {Array} Returns the match data of `object`.\n\t */\n\tfunction getMatchData(object) {\n\t var result = keys(object),\n\t length = result.length;\n\t\n\t while (length--) {\n\t var key = result[length],\n\t value = object[key];\n\t\n\t result[length] = [key, value, isStrictComparable(value)];\n\t }\n\t return result;\n\t}\n\t\n\t/**\n\t * Gets the native function at `key` of `object`.\n\t *\n\t * @private\n\t * @param {Object} object The object to query.\n\t * @param {string} key The key of the method to get.\n\t * @returns {*} Returns the function if it's native, else `undefined`.\n\t */\n\tfunction getNative(object, key) {\n\t var value = getValue(object, key);\n\t return baseIsNative(value) ? value : undefined;\n\t}\n\t\n\t/**\n\t * Gets the `toStringTag` of `value`.\n\t *\n\t * @private\n\t * @param {*} value The value to query.\n\t * @returns {string} Returns the `toStringTag`.\n\t */\n\tvar getTag = baseGetTag;\n\t\n\t// Fallback for data views, maps, sets, and weak maps in IE 11,\n\t// for data views in Edge < 14, and promises in Node.js.\n\tif ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag) ||\n\t (Map && getTag(new Map) != mapTag) ||\n\t (Promise && getTag(Promise.resolve()) != promiseTag) ||\n\t (Set && getTag(new Set) != setTag) ||\n\t (WeakMap && getTag(new WeakMap) != weakMapTag)) {\n\t getTag = function(value) {\n\t var result = objectToString.call(value),\n\t Ctor = result == objectTag ? value.constructor : undefined,\n\t ctorString = Ctor ? toSource(Ctor) : undefined;\n\t\n\t if (ctorString) {\n\t switch (ctorString) {\n\t case dataViewCtorString: return dataViewTag;\n\t case mapCtorString: return mapTag;\n\t case promiseCtorString: return promiseTag;\n\t case setCtorString: return setTag;\n\t case weakMapCtorString: return weakMapTag;\n\t }\n\t }\n\t return result;\n\t };\n\t}\n\t\n\t/**\n\t * Checks if `path` exists on `object`.\n\t *\n\t * @private\n\t * @param {Object} object The object to query.\n\t * @param {Array|string} path The path to check.\n\t * @param {Function} hasFunc The function to check properties.\n\t * @returns {boolean} Returns `true` if `path` exists, else `false`.\n\t */\n\tfunction hasPath(object, path, hasFunc) {\n\t path = isKey(path, object) ? [path] : castPath(path);\n\t\n\t var result,\n\t index = -1,\n\t length = path.length;\n\t\n\t while (++index < length) {\n\t var key = toKey(path[index]);\n\t if (!(result = object != null && hasFunc(object, key))) {\n\t break;\n\t }\n\t object = object[key];\n\t }\n\t if (result) {\n\t return result;\n\t }\n\t var length = object ? object.length : 0;\n\t return !!length && isLength(length) && isIndex(key, length) &&\n\t (isArray(object) || isArguments(object));\n\t}\n\t\n\t/**\n\t * Checks if `value` is a valid array-like index.\n\t *\n\t * @private\n\t * @param {*} value The value to check.\n\t * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.\n\t * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.\n\t */\n\tfunction isIndex(value, length) {\n\t length = length == null ? MAX_SAFE_INTEGER : length;\n\t return !!length &&\n\t (typeof value == 'number' || reIsUint.test(value)) &&\n\t (value > -1 && value % 1 == 0 && value < length);\n\t}\n\t\n\t/**\n\t * Checks if `value` is a property name and not a property path.\n\t *\n\t * @private\n\t * @param {*} value The value to check.\n\t * @param {Object} [object] The object to query keys on.\n\t * @returns {boolean} Returns `true` if `value` is a property name, else `false`.\n\t */\n\tfunction isKey(value, object) {\n\t if (isArray(value)) {\n\t return false;\n\t }\n\t var type = typeof value;\n\t if (type == 'number' || type == 'symbol' || type == 'boolean' ||\n\t value == null || isSymbol(value)) {\n\t return true;\n\t }\n\t return reIsPlainProp.test(value) || !reIsDeepProp.test(value) ||\n\t (object != null && value in Object(object));\n\t}\n\t\n\t/**\n\t * Checks if `value` is suitable for use as unique object key.\n\t *\n\t * @private\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is suitable, else `false`.\n\t */\n\tfunction isKeyable(value) {\n\t var type = typeof value;\n\t return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean')\n\t ? (value !== '__proto__')\n\t : (value === null);\n\t}\n\t\n\t/**\n\t * Checks if `func` has its source masked.\n\t *\n\t * @private\n\t * @param {Function} func The function to check.\n\t * @returns {boolean} Returns `true` if `func` is masked, else `false`.\n\t */\n\tfunction isMasked(func) {\n\t return !!maskSrcKey && (maskSrcKey in func);\n\t}\n\t\n\t/**\n\t * Checks if `value` is likely a prototype object.\n\t *\n\t * @private\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.\n\t */\n\tfunction isPrototype(value) {\n\t var Ctor = value && value.constructor,\n\t proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto;\n\t\n\t return value === proto;\n\t}\n\t\n\t/**\n\t * Checks if `value` is suitable for strict equality comparisons, i.e. `===`.\n\t *\n\t * @private\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` if suitable for strict\n\t * equality comparisons, else `false`.\n\t */\n\tfunction isStrictComparable(value) {\n\t return value === value && !isObject(value);\n\t}\n\t\n\t/**\n\t * A specialized version of `matchesProperty` for source values suitable\n\t * for strict equality comparisons, i.e. `===`.\n\t *\n\t * @private\n\t * @param {string} key The key of the property to get.\n\t * @param {*} srcValue The value to match.\n\t * @returns {Function} Returns the new spec function.\n\t */\n\tfunction matchesStrictComparable(key, srcValue) {\n\t return function(object) {\n\t if (object == null) {\n\t return false;\n\t }\n\t return object[key] === srcValue &&\n\t (srcValue !== undefined || (key in Object(object)));\n\t };\n\t}\n\t\n\t/**\n\t * Converts `string` to a property path array.\n\t *\n\t * @private\n\t * @param {string} string The string to convert.\n\t * @returns {Array} Returns the property path array.\n\t */\n\tvar stringToPath = memoize(function(string) {\n\t string = toString(string);\n\t\n\t var result = [];\n\t if (reLeadingDot.test(string)) {\n\t result.push('');\n\t }\n\t string.replace(rePropName, function(match, number, quote, string) {\n\t result.push(quote ? string.replace(reEscapeChar, '$1') : (number || match));\n\t });\n\t return result;\n\t});\n\t\n\t/**\n\t * Converts `value` to a string key if it's not a string or symbol.\n\t *\n\t * @private\n\t * @param {*} value The value to inspect.\n\t * @returns {string|symbol} Returns the key.\n\t */\n\tfunction toKey(value) {\n\t if (typeof value == 'string' || isSymbol(value)) {\n\t return value;\n\t }\n\t var result = (value + '');\n\t return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;\n\t}\n\t\n\t/**\n\t * Converts `func` to its source code.\n\t *\n\t * @private\n\t * @param {Function} func The function to process.\n\t * @returns {string} Returns the source code.\n\t */\n\tfunction toSource(func) {\n\t if (func != null) {\n\t try {\n\t return funcToString.call(func);\n\t } catch (e) {}\n\t try {\n\t return (func + '');\n\t } catch (e) {}\n\t }\n\t return '';\n\t}\n\t\n\t/**\n\t * This method is like `_.uniq` except that it accepts `iteratee` which is\n\t * invoked for each element in `array` to generate the criterion by which\n\t * uniqueness is computed. The iteratee is invoked with one argument: (value).\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 4.0.0\n\t * @category Array\n\t * @param {Array} array The array to inspect.\n\t * @param {Function} [iteratee=_.identity]\n\t * The iteratee invoked per element.\n\t * @returns {Array} Returns the new duplicate free array.\n\t * @example\n\t *\n\t * _.uniqBy([2.1, 1.2, 2.3], Math.floor);\n\t * // => [2.1, 1.2]\n\t *\n\t * // The `_.property` iteratee shorthand.\n\t * _.uniqBy([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x');\n\t * // => [{ 'x': 1 }, { 'x': 2 }]\n\t */\n\tfunction uniqBy(array, iteratee) {\n\t return (array && array.length)\n\t ? baseUniq(array, baseIteratee(iteratee, 2))\n\t : [];\n\t}\n\t\n\t/**\n\t * Creates a function that memoizes the result of `func`. If `resolver` is\n\t * provided, it determines the cache key for storing the result based on the\n\t * arguments provided to the memoized function. By default, the first argument\n\t * provided to the memoized function is used as the map cache key. The `func`\n\t * is invoked with the `this` binding of the memoized function.\n\t *\n\t * **Note:** The cache is exposed as the `cache` property on the memoized\n\t * function. Its creation may be customized by replacing the `_.memoize.Cache`\n\t * constructor with one whose instances implement the\n\t * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object)\n\t * method interface of `delete`, `get`, `has`, and `set`.\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 0.1.0\n\t * @category Function\n\t * @param {Function} func The function to have its output memoized.\n\t * @param {Function} [resolver] The function to resolve the cache key.\n\t * @returns {Function} Returns the new memoized function.\n\t * @example\n\t *\n\t * var object = { 'a': 1, 'b': 2 };\n\t * var other = { 'c': 3, 'd': 4 };\n\t *\n\t * var values = _.memoize(_.values);\n\t * values(object);\n\t * // => [1, 2]\n\t *\n\t * values(other);\n\t * // => [3, 4]\n\t *\n\t * object.a = 2;\n\t * values(object);\n\t * // => [1, 2]\n\t *\n\t * // Modify the result cache.\n\t * values.cache.set(object, ['a', 'b']);\n\t * values(object);\n\t * // => ['a', 'b']\n\t *\n\t * // Replace `_.memoize.Cache`.\n\t * _.memoize.Cache = WeakMap;\n\t */\n\tfunction memoize(func, resolver) {\n\t if (typeof func != 'function' || (resolver && typeof resolver != 'function')) {\n\t throw new TypeError(FUNC_ERROR_TEXT);\n\t }\n\t var memoized = function() {\n\t var args = arguments,\n\t key = resolver ? resolver.apply(this, args) : args[0],\n\t cache = memoized.cache;\n\t\n\t if (cache.has(key)) {\n\t return cache.get(key);\n\t }\n\t var result = func.apply(this, args);\n\t memoized.cache = cache.set(key, result);\n\t return result;\n\t };\n\t memoized.cache = new (memoize.Cache || MapCache);\n\t return memoized;\n\t}\n\t\n\t// Assign cache to `_.memoize`.\n\tmemoize.Cache = MapCache;\n\t\n\t/**\n\t * Performs a\n\t * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n\t * comparison between two values to determine if they are equivalent.\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 4.0.0\n\t * @category Lang\n\t * @param {*} value The value to compare.\n\t * @param {*} other The other value to compare.\n\t * @returns {boolean} Returns `true` if the values are equivalent, else `false`.\n\t * @example\n\t *\n\t * var object = { 'a': 1 };\n\t * var other = { 'a': 1 };\n\t *\n\t * _.eq(object, object);\n\t * // => true\n\t *\n\t * _.eq(object, other);\n\t * // => false\n\t *\n\t * _.eq('a', 'a');\n\t * // => true\n\t *\n\t * _.eq('a', Object('a'));\n\t * // => false\n\t *\n\t * _.eq(NaN, NaN);\n\t * // => true\n\t */\n\tfunction eq(value, other) {\n\t return value === other || (value !== value && other !== other);\n\t}\n\t\n\t/**\n\t * Checks if `value` is likely an `arguments` object.\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 0.1.0\n\t * @category Lang\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is an `arguments` object,\n\t * else `false`.\n\t * @example\n\t *\n\t * _.isArguments(function() { return arguments; }());\n\t * // => true\n\t *\n\t * _.isArguments([1, 2, 3]);\n\t * // => false\n\t */\n\tfunction isArguments(value) {\n\t // Safari 8.1 makes `arguments.callee` enumerable in strict mode.\n\t return isArrayLikeObject(value) && hasOwnProperty.call(value, 'callee') &&\n\t (!propertyIsEnumerable.call(value, 'callee') || objectToString.call(value) == argsTag);\n\t}\n\t\n\t/**\n\t * Checks if `value` is classified as an `Array` object.\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 0.1.0\n\t * @category Lang\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is an array, else `false`.\n\t * @example\n\t *\n\t * _.isArray([1, 2, 3]);\n\t * // => true\n\t *\n\t * _.isArray(document.body.children);\n\t * // => false\n\t *\n\t * _.isArray('abc');\n\t * // => false\n\t *\n\t * _.isArray(_.noop);\n\t * // => false\n\t */\n\tvar isArray = Array.isArray;\n\t\n\t/**\n\t * Checks if `value` is array-like. A value is considered array-like if it's\n\t * not a function and has a `value.length` that's an integer greater than or\n\t * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 4.0.0\n\t * @category Lang\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is array-like, else `false`.\n\t * @example\n\t *\n\t * _.isArrayLike([1, 2, 3]);\n\t * // => true\n\t *\n\t * _.isArrayLike(document.body.children);\n\t * // => true\n\t *\n\t * _.isArrayLike('abc');\n\t * // => true\n\t *\n\t * _.isArrayLike(_.noop);\n\t * // => false\n\t */\n\tfunction isArrayLike(value) {\n\t return value != null && isLength(value.length) && !isFunction(value);\n\t}\n\t\n\t/**\n\t * This method is like `_.isArrayLike` except that it also checks if `value`\n\t * is an object.\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 4.0.0\n\t * @category Lang\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is an array-like object,\n\t * else `false`.\n\t * @example\n\t *\n\t * _.isArrayLikeObject([1, 2, 3]);\n\t * // => true\n\t *\n\t * _.isArrayLikeObject(document.body.children);\n\t * // => true\n\t *\n\t * _.isArrayLikeObject('abc');\n\t * // => false\n\t *\n\t * _.isArrayLikeObject(_.noop);\n\t * // => false\n\t */\n\tfunction isArrayLikeObject(value) {\n\t return isObjectLike(value) && isArrayLike(value);\n\t}\n\t\n\t/**\n\t * Checks if `value` is classified as a `Function` object.\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 0.1.0\n\t * @category Lang\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is a function, else `false`.\n\t * @example\n\t *\n\t * _.isFunction(_);\n\t * // => true\n\t *\n\t * _.isFunction(/abc/);\n\t * // => false\n\t */\n\tfunction isFunction(value) {\n\t // The use of `Object#toString` avoids issues with the `typeof` operator\n\t // in Safari 8-9 which returns 'object' for typed array and other constructors.\n\t var tag = isObject(value) ? objectToString.call(value) : '';\n\t return tag == funcTag || tag == genTag;\n\t}\n\t\n\t/**\n\t * Checks if `value` is a valid array-like length.\n\t *\n\t * **Note:** This method is loosely based on\n\t * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 4.0.0\n\t * @category Lang\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.\n\t * @example\n\t *\n\t * _.isLength(3);\n\t * // => true\n\t *\n\t * _.isLength(Number.MIN_VALUE);\n\t * // => false\n\t *\n\t * _.isLength(Infinity);\n\t * // => false\n\t *\n\t * _.isLength('3');\n\t * // => false\n\t */\n\tfunction isLength(value) {\n\t return typeof value == 'number' &&\n\t value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;\n\t}\n\t\n\t/**\n\t * Checks if `value` is the\n\t * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)\n\t * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 0.1.0\n\t * @category Lang\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n\t * @example\n\t *\n\t * _.isObject({});\n\t * // => true\n\t *\n\t * _.isObject([1, 2, 3]);\n\t * // => true\n\t *\n\t * _.isObject(_.noop);\n\t * // => true\n\t *\n\t * _.isObject(null);\n\t * // => false\n\t */\n\tfunction isObject(value) {\n\t var type = typeof value;\n\t return !!value && (type == 'object' || type == 'function');\n\t}\n\t\n\t/**\n\t * Checks if `value` is object-like. A value is object-like if it's not `null`\n\t * and has a `typeof` result of \"object\".\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 4.0.0\n\t * @category Lang\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is object-like, else `false`.\n\t * @example\n\t *\n\t * _.isObjectLike({});\n\t * // => true\n\t *\n\t * _.isObjectLike([1, 2, 3]);\n\t * // => true\n\t *\n\t * _.isObjectLike(_.noop);\n\t * // => false\n\t *\n\t * _.isObjectLike(null);\n\t * // => false\n\t */\n\tfunction isObjectLike(value) {\n\t return !!value && typeof value == 'object';\n\t}\n\t\n\t/**\n\t * Checks if `value` is classified as a `Symbol` primitive or object.\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 4.0.0\n\t * @category Lang\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is a symbol, else `false`.\n\t * @example\n\t *\n\t * _.isSymbol(Symbol.iterator);\n\t * // => true\n\t *\n\t * _.isSymbol('abc');\n\t * // => false\n\t */\n\tfunction isSymbol(value) {\n\t return typeof value == 'symbol' ||\n\t (isObjectLike(value) && objectToString.call(value) == symbolTag);\n\t}\n\t\n\t/**\n\t * Checks if `value` is classified as a typed array.\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 3.0.0\n\t * @category Lang\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.\n\t * @example\n\t *\n\t * _.isTypedArray(new Uint8Array);\n\t * // => true\n\t *\n\t * _.isTypedArray([]);\n\t * // => false\n\t */\n\tvar isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray;\n\t\n\t/**\n\t * Converts `value` to a string. An empty string is returned for `null`\n\t * and `undefined` values. The sign of `-0` is preserved.\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 4.0.0\n\t * @category Lang\n\t * @param {*} value The value to process.\n\t * @returns {string} Returns the string.\n\t * @example\n\t *\n\t * _.toString(null);\n\t * // => ''\n\t *\n\t * _.toString(-0);\n\t * // => '-0'\n\t *\n\t * _.toString([1, 2, 3]);\n\t * // => '1,2,3'\n\t */\n\tfunction toString(value) {\n\t return value == null ? '' : baseToString(value);\n\t}\n\t\n\t/**\n\t * Gets the value at `path` of `object`. If the resolved value is\n\t * `undefined`, the `defaultValue` is returned in its place.\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 3.7.0\n\t * @category Object\n\t * @param {Object} object The object to query.\n\t * @param {Array|string} path The path of the property to get.\n\t * @param {*} [defaultValue] The value returned for `undefined` resolved values.\n\t * @returns {*} Returns the resolved value.\n\t * @example\n\t *\n\t * var object = { 'a': [{ 'b': { 'c': 3 } }] };\n\t *\n\t * _.get(object, 'a[0].b.c');\n\t * // => 3\n\t *\n\t * _.get(object, ['a', '0', 'b', 'c']);\n\t * // => 3\n\t *\n\t * _.get(object, 'a.b.c', 'default');\n\t * // => 'default'\n\t */\n\tfunction get(object, path, defaultValue) {\n\t var result = object == null ? undefined : baseGet(object, path);\n\t return result === undefined ? defaultValue : result;\n\t}\n\t\n\t/**\n\t * Checks if `path` is a direct or inherited property of `object`.\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 4.0.0\n\t * @category Object\n\t * @param {Object} object The object to query.\n\t * @param {Array|string} path The path to check.\n\t * @returns {boolean} Returns `true` if `path` exists, else `false`.\n\t * @example\n\t *\n\t * var object = _.create({ 'a': _.create({ 'b': 2 }) });\n\t *\n\t * _.hasIn(object, 'a');\n\t * // => true\n\t *\n\t * _.hasIn(object, 'a.b');\n\t * // => true\n\t *\n\t * _.hasIn(object, ['a', 'b']);\n\t * // => true\n\t *\n\t * _.hasIn(object, 'b');\n\t * // => false\n\t */\n\tfunction hasIn(object, path) {\n\t return object != null && hasPath(object, path, baseHasIn);\n\t}\n\t\n\t/**\n\t * Creates an array of the own enumerable property names of `object`.\n\t *\n\t * **Note:** Non-object values are coerced to objects. See the\n\t * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)\n\t * for more details.\n\t *\n\t * @static\n\t * @since 0.1.0\n\t * @memberOf _\n\t * @category Object\n\t * @param {Object} object The object to query.\n\t * @returns {Array} Returns the array of property names.\n\t * @example\n\t *\n\t * function Foo() {\n\t * this.a = 1;\n\t * this.b = 2;\n\t * }\n\t *\n\t * Foo.prototype.c = 3;\n\t *\n\t * _.keys(new Foo);\n\t * // => ['a', 'b'] (iteration order is not guaranteed)\n\t *\n\t * _.keys('hi');\n\t * // => ['0', '1']\n\t */\n\tfunction keys(object) {\n\t return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object);\n\t}\n\t\n\t/**\n\t * This method returns the first argument it receives.\n\t *\n\t * @static\n\t * @since 0.1.0\n\t * @memberOf _\n\t * @category Util\n\t * @param {*} value Any value.\n\t * @returns {*} Returns `value`.\n\t * @example\n\t *\n\t * var object = { 'a': 1 };\n\t *\n\t * console.log(_.identity(object) === object);\n\t * // => true\n\t */\n\tfunction identity(value) {\n\t return value;\n\t}\n\t\n\t/**\n\t * This method returns `undefined`.\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 2.3.0\n\t * @category Util\n\t * @example\n\t *\n\t * _.times(2, _.noop);\n\t * // => [undefined, undefined]\n\t */\n\tfunction noop() {\n\t // No operation performed.\n\t}\n\t\n\t/**\n\t * Creates a function that returns the value at `path` of a given object.\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 2.4.0\n\t * @category Util\n\t * @param {Array|string} path The path of the property to get.\n\t * @returns {Function} Returns the new accessor function.\n\t * @example\n\t *\n\t * var objects = [\n\t * { 'a': { 'b': 2 } },\n\t * { 'a': { 'b': 1 } }\n\t * ];\n\t *\n\t * _.map(objects, _.property('a.b'));\n\t * // => [2, 1]\n\t *\n\t * _.map(_.sortBy(objects, _.property(['a', 'b'])), 'a.b');\n\t * // => [1, 2]\n\t */\n\tfunction property(path) {\n\t return isKey(path) ? baseProperty(toKey(path)) : basePropertyDeep(path);\n\t}\n\t\n\tmodule.exports = uniqBy;\n\t\n\t/* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }()), __webpack_require__(/*! ./../webpack/buildin/module.js */ 23)(module)))\n\n/***/ },\n/* 104 */\n/*!*******************************!*\\\n !*** ./src/icons/03-stop.svg ***!\n \\*******************************/\n/***/ function(module, exports) {\n\n\tmodule.exports = \"\"\n\n/***/ },\n/* 105 */\n/*!*********************************!*\\\n !*** ./src/icons/04-volume.svg ***!\n \\*********************************/\n/***/ function(module, exports) {\n\n\tmodule.exports = \"\"\n\n/***/ },\n/* 106 */\n/*!*******************************!*\\\n !*** ./src/icons/05-mute.svg ***!\n \\*******************************/\n/***/ function(module, exports) {\n\n\tmodule.exports = \"\"\n\n/***/ },\n/* 107 */\n/*!*********************************!*\\\n !*** ./src/icons/06-expand.svg ***!\n \\*********************************/\n/***/ function(module, exports) {\n\n\tmodule.exports = \"\"\n\n/***/ },\n/* 108 */\n/*!*********************************!*\\\n !*** ./src/icons/07-shrink.svg ***!\n \\*********************************/\n/***/ function(module, exports) {\n\n\tmodule.exports = \"\"\n\n/***/ },\n/* 109 */\n/*!*****************************!*\\\n !*** ./src/icons/08-hd.svg ***!\n \\*****************************/\n/***/ function(module, exports) {\n\n\tmodule.exports = \"\"\n\n/***/ },\n/* 110 */\n/*!***********************************************!*\\\n !*** ./src/components/core/public/Roboto.ttf ***!\n \\***********************************************/\n/***/ function(module, exports, __webpack_require__) {\n\n\tmodule.exports = __webpack_require__.p + \"38861cba61c66739c1452c3a71e39852.ttf\";\n\n/***/ },\n/* 111 */\n/*!***********************************************!*\\\n !*** ./src/playbacks/flash/public/Player.swf ***!\n \\***********************************************/\n/***/ function(module, exports, __webpack_require__) {\n\n\tmodule.exports = __webpack_require__.p + \"4b76590b32dab62bc95c1b7951efae78.swf\";\n\n/***/ },\n/* 112 */\n/*!****************************************************!*\\\n !*** ./src/playbacks/flashls/public/HLSPlayer.swf ***!\n \\****************************************************/\n/***/ function(module, exports, __webpack_require__) {\n\n\tmodule.exports = __webpack_require__.p + \"809981e5b09d5336c45d72d0869ada2a.swf\";\n\n/***/ }\n/******/ ])\n});\n;\n\n\n// WEBPACK FOOTER //\n// clappr.min.js"," \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId])\n \t\t\treturn installedModules[moduleId].exports;\n\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\texports: {},\n \t\t\tid: moduleId,\n \t\t\tloaded: false\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.loaded = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"<%=baseUrl%>/\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(0);\n\n\n\n// WEBPACK FOOTER //\n// webpack/bootstrap d556a0cfcd71319135ca","// Copyright 2014 Globo.com Player authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\nimport Player from 'components/player'\nimport Utils from 'base/utils'\nimport Events from 'base/events'\nimport Playback from 'base/playback'\nimport ContainerPlugin from 'base/container_plugin'\nimport CorePlugin from 'base/core_plugin'\nimport UICorePlugin from 'base/ui_core_plugin'\nimport UIContainerPlugin from 'base/ui_container_plugin'\nimport BaseObject from 'base/base_object'\nimport UIObject from 'base/ui_object'\nimport Browser from 'components/browser'\nimport Container from 'components/container'\nimport Core from 'components/core'\nimport Loader from 'components/loader'\nimport Mediator from 'components/mediator'\nimport MediaControl from 'components/media_control'\nimport PlayerInfo from 'components/player_info'\nimport BaseFlashPlayback from 'playbacks/base_flash_playback'\nimport Flash from 'playbacks/flash'\nimport FlasHLS from 'playbacks/flashls'\nimport HLS from 'playbacks/hls'\nimport HTML5Audio from 'playbacks/html5_audio'\nimport HTML5Video from 'playbacks/html5_video'\nimport HTMLImg from 'playbacks/html_img'\nimport NoOp from 'playbacks/no_op'\nimport Poster from 'plugins/poster'\nimport Log from 'plugins/log'\nimport Styler from 'base/styler'\nimport Vendor from 'vendor'\nimport template from 'base/template'\n\nimport $ from 'clappr-zepto'\n\nconst version = VERSION\n\nexport default {\n Player,\n Mediator,\n Events,\n Browser,\n PlayerInfo,\n MediaControl,\n ContainerPlugin,\n UIContainerPlugin,\n CorePlugin,\n UICorePlugin,\n Playback,\n Container,\n Core,\n Loader,\n BaseObject,\n UIObject,\n Utils,\n BaseFlashPlayback,\n Flash,\n FlasHLS,\n HLS,\n HTML5Audio,\n HTML5Video,\n HTMLImg,\n NoOp,\n Poster,\n Log,\n Styler,\n Vendor,\n version,\n template,\n $\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/main.js","// Copyright 2014 Globo.com Player authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\nimport Log from 'plugins/log'\nimport {uniqueId} from './utils'\nimport execOnce from 'lodash.once'\n\nconst slice = Array.prototype.slice\n\nconst eventSplitter = /\\s+/\n\nconst eventsApi = function(obj, action, name, rest) {\n if (!name) {return true}\n\n // Handle event maps.\n if (typeof name === 'object') {\n for (const key in name) {\n obj[action].apply(obj, [key, name[key]].concat(rest))\n }\n return false\n }\n\n // Handle space separated event names.\n if (eventSplitter.test(name)) {\n const names = name.split(eventSplitter)\n for (let i = 0, l = names.length; i < l; i++) {\n obj[action].apply(obj, [names[i]].concat(rest))\n }\n return false\n }\n\n return true\n}\n\nconst triggerEvents = function(events, args, klass, name) {\n let ev, i = -1\n const l = events.length, a1 = args[0], a2 = args[1], a3 = args[2]\n run()\n\n function run() {\n try {\n switch (args.length) {\n case 0: while (++i < l) { (ev = events[i]).callback.call(ev.ctx) } return\n case 1: while (++i < l) { (ev = events[i]).callback.call(ev.ctx, a1) } return\n case 2: while (++i < l) { (ev = events[i]).callback.call(ev.ctx, a1, a2) } return\n case 3: while (++i < l) { (ev = events[i]).callback.call(ev.ctx, a1, a2, a3) } return\n default: while (++i < l) { (ev = events[i]).callback.apply(ev.ctx, args) } return\n }\n } catch (exception) {\n Log.error.apply(Log, [klass, 'error on event', name, 'trigger','-', exception])\n run()\n }\n }\n}\n\n/**\n * @class Events\n * @constructor\n * @module base\n */\nexport default class Events {\n /**\n * listen to an event indefinitely, if you want to stop you need to call `off`\n * @method on\n * @param {String} name\n * @param {Function} callback\n * @param {Object} context\n */\n on(name, callback, context) {\n if (!eventsApi(this, 'on', name, [callback, context]) || !callback) {return this}\n this._events || (this._events = {})\n const events = this._events[name] || (this._events[name] = [])\n events.push({callback: callback, context: context, ctx: context || this})\n return this\n }\n\n /**\n * listen to an event only once\n * @method once\n * @param {String} name\n * @param {Function} callback\n * @param {Object} context\n */\n once(name, callback, context) {\n if (!eventsApi(this, 'once', name, [callback, context]) || !callback) {return this}\n const self = this\n const once = execOnce(function() {\n self.off(name, once)\n callback.apply(this, arguments)\n })\n once._callback = callback\n return this.on(name, once, context)\n }\n\n /**\n * stop listening to an event\n * @method off\n * @param {String} name\n * @param {Function} callback\n * @param {Object} context\n */\n off(name, callback, context) {\n let retain, ev, events, names, i, l, j, k\n if (!this._events || !eventsApi(this, 'off', name, [callback, context])) {return this}\n if (!name && !callback && !context) {\n this._events = void 0\n return this\n }\n names = name ? [name] : Object.keys(this._events)\n // jshint maxdepth:5\n for (i = 0, l = names.length; i < l; i++) {\n name = names[i]\n events = this._events[name]\n if (events) {\n this._events[name] = retain = []\n if (callback || context) {\n for (j = 0, k = events.length; j < k; j++) {\n ev = events[j]\n if ((callback && callback !== ev.callback && callback !== ev.callback._callback) ||\n (context && context !== ev.context)) {\n retain.push(ev)\n }\n }\n }\n if (!retain.length) {delete this._events[name]}\n }\n }\n return this\n }\n\n /**\n * triggers an event given its `name`\n * @method trigger\n * @param {String} name\n */\n trigger(name) {\n const klass = this.name || this.constructor.name\n Log.debug.apply(Log, [klass].concat(Array.prototype.slice.call(arguments)))\n if (!this._events) {return this}\n const args = slice.call(arguments, 1)\n if (!eventsApi(this, 'trigger', name, args)) {return this}\n const events = this._events[name]\n const allEvents = this._events.all\n if (events) {triggerEvents(events, args, klass, name)}\n if (allEvents) {triggerEvents(allEvents, arguments, klass, name)}\n return this\n }\n\n /**\n * stop listening an event for a given object\n * @method stopListening\n * @param {Object} obj\n * @param {String} name\n * @param {Function} callback\n */\n stopListening(obj, name, callback) {\n let listeningTo = this._listeningTo\n if (!listeningTo) {return this}\n const remove = !name && !callback\n if (!callback && typeof name === 'object') {callback = this}\n if (obj) {(listeningTo = {})[obj._listenId] = obj}\n for (const id in listeningTo) {\n obj = listeningTo[id]\n obj.off(name, callback, this)\n if (remove || Object.keys(obj._events).length === 0) {delete this._listeningTo[id]}\n }\n return this\n }\n}\n\n\n/**\n * listen to an event indefinitely for a given `obj`\n * @method listenTo\n * @param {Object} obj\n * @param {String} name\n * @param {Function} callback\n * @param {Object} context\n * @example\n * ```javascript\n * this.listenTo(this.core.playback, Events.PLAYBACK_PAUSE, this.callback)\n * ```\n */\n/**\n * listen to an event once for a given `obj`\n * @method listenToOnce\n * @param {Object} obj\n * @param {String} name\n * @param {Function} callback\n * @param {Object} context\n * @example\n * ```javascript\n * this.listenToOnce(this.core.playback, Events.PLAYBACK_PAUSE, this.callback)\n * ```\n */\nconst listenMethods = {listenTo: 'on', listenToOnce: 'once'}\n\nObject.keys(listenMethods).forEach(function(method) {\n Events.prototype[method] = function(obj, name, callback) {\n const listeningTo = this._listeningTo || (this._listeningTo = {})\n const id = obj._listenId || (obj._listenId = uniqueId('l'))\n listeningTo[id] = obj\n if (!callback && typeof name === 'object') {callback = this}\n obj[listenMethods[method]](name, callback, this)\n return this\n }\n})\n\n// PLAYER EVENTS\n/**\n * Fired when the player is ready on startup\n *\n * @event PLAYER_READY\n */\nEvents.PLAYER_READY = 'ready'\n/**\n * Fired when player resizes\n *\n * @event PLAYER_RESIZE\n * @param {Object} currentSize an object with the current size\n */\nEvents.PLAYER_RESIZE = 'resize'\n/**\n * Fired when player changes its fullscreen state\n *\n * @event PLAYER_FULLSCREEN\n * @param {Boolean} whether or not the player is on fullscreen mode\n */\nEvents.PLAYER_FULLSCREEN = 'fullscreen'\n/**\n * Fired when player starts to play\n *\n * @event PLAYER_PLAY\n */\nEvents.PLAYER_PLAY = 'play'\n/**\n * Fired when player pauses\n *\n * @event PLAYER_PAUSE\n */\nEvents.PLAYER_PAUSE = 'pause'\n/**\n * Fired when player stops\n *\n * @event PLAYER_STOP\n */\nEvents.PLAYER_STOP = 'stop'\n/**\n * Fired when player ends the video\n *\n * @event PLAYER_ENDED\n */\nEvents.PLAYER_ENDED = 'ended'\n/**\n * Fired when player seeks the video\n *\n * @event PLAYER_SEEK\n * @param {Number} time the current time in seconds\n */\nEvents.PLAYER_SEEK = 'seek'\n/**\n * Fired when player receives an error\n *\n * @event PLAYER_ERROR\n * @param {Object} error the error\n */\nEvents.PLAYER_ERROR = 'error'\n/**\n * Fired when the time is updated on player\n *\n * @event PLAYER_TIMEUPDATE\n * @param {Object} progress Data\n * progress object\n * @param {Number} [progress.current]\n * current time\n * @param {Number} [progress.total]\n * total time\n */\nEvents.PLAYER_TIMEUPDATE = 'timeupdate'\n/**\n * Fired when player updates its volume\n *\n * @event PLAYER_VOLUMEUPDATE\n * @param {Number} volume the current volume\n */\nEvents.PLAYER_VOLUMEUPDATE = 'volumeupdate'\n\n// Playback Events\n/**\n * Fired when the playback is downloading the media\n *\n * @event PLAYBACK_PROGRESS\n * @param progress {Object}\n * Data progress object\n * @param [progress.start] {Number}\n * start position of buffered content at current position\n * @param [progress.current] {Number}\n * end position of buffered content at current position\n * @param [progress.total] {Number}\n * total content to be downloaded\n * @param buffered {Array}\n * array of buffered segments ({start, end}). [Only for supported playbacks]\n */\nEvents.PLAYBACK_PROGRESS = 'playback:progress'\n/**\n * Fired when the time is updated on playback\n *\n * @event PLAYBACK_TIMEUPDATE\n * @param {Object} progress Data\n * progress object\n * @param {Number} [progress.current]\n * current time\n * @param {Number} [progress.total]\n * total time\n */\nEvents.PLAYBACK_TIMEUPDATE = 'playback:timeupdate'\n/**\n * Fired when playback is ready\n *\n * @event PLAYBACK_READY\n */\nEvents.PLAYBACK_READY = 'playback:ready'\n/**\n * Fired when the playback starts having to buffer because\n * playback can currently not be smooth.\n *\n * This corresponds to the playback `buffering` property being\n * `true`.\n *\n * @event PLAYBACK_BUFFERING\n */\nEvents.PLAYBACK_BUFFERING = 'playback:buffering'\n/**\n * Fired when the playback has enough in the buffer to be\n * able to play smoothly, after previously being unable to\n * do this.\n *\n * This corresponds to the playback `buffering` property being\n * `false`.\n *\n * @event PLAYBACK_BUFFERFULL\n */\nEvents.PLAYBACK_BUFFERFULL = 'playback:bufferfull'\n/**\n * Fired when playback changes any settings (volume, seek and etc)\n *\n * @event PLAYBACK_SETTINGSUPDATE\n */\nEvents.PLAYBACK_SETTINGSUPDATE = 'playback:settingsupdate'\n/**\n * Fired when playback loaded its metadata\n *\n * @event PLAYBACK_LOADEDMETADATA\n * @param {Object} metadata Data\n * settings object\n * @param {Number} [metadata.duration]\n * the playback duration\n * @param {Object} [metadata.data]\n * extra meta data\n */\nEvents.PLAYBACK_LOADEDMETADATA = 'playback:loadedmetadata'\n/**\n * Fired when playback updates its video quality\n *\n * @event PLAYBACK_HIGHDEFINITIONUPDATE\n * @param {Boolean} isHD\n * true when is on HD, false otherwise\n */\nEvents.PLAYBACK_HIGHDEFINITIONUPDATE = 'playback:highdefinitionupdate'\n/**\n * Fired when playback updates its bitrate\n *\n * @event PLAYBACK_BITRATE\n * @param {Object} bitrate Data\n * bitrate object\n * @param {Number} [bitrate.bandwidth]\n * bitrate bandwidth when it's available\n * @param {Number} [bitrate.width]\n * playback width (ex: 720, 640, 1080)\n * @param {Number} [bitrate.height]\n * playback height (ex: 240, 480, 720)\n * @param {Number} [bitrate.level]\n * playback level when it's available, it could be just a map for width (0 => 240, 1 => 480, 2 => 720)\n */\nEvents.PLAYBACK_BITRATE = 'playback:bitrate'\n/**\n * Fired when the playback has its levels\n *\n * @event PLAYBACK_LEVELS_AVAILABLE\n * @param {Array} levels\n * the ordered levels, each one with the following format `{id: 1, label: '500kbps'}` ps: id should be a number >= 0\n * @param {Number} initial\n * the initial level otherwise -1 (AUTO)\n */\nEvents.PLAYBACK_LEVELS_AVAILABLE = 'playback:levels:available'\n/**\n * Fired when the playback starts to switch level\n *\n * @event PLAYBACK_LEVEL_SWITCH_START\n *\n */\nEvents.PLAYBACK_LEVEL_SWITCH_START = 'playback:levels:switch:start'\n/**\n * Fired when the playback ends the level switch\n *\n * @event PLAYBACK_LEVEL_SWITCH_END\n *\n */\nEvents.PLAYBACK_LEVEL_SWITCH_END = 'playback:levels:switch:end'\n\n/**\n * Fired when playback internal state changes\n *\n * @event PLAYBACK_PLAYBACKSTATE\n * @param {Object} state Data\n * state object\n * @param {String} [state.type]\n * the playback type\n */\nEvents.PLAYBACK_PLAYBACKSTATE = 'playback:playbackstate'\n/**\n * Fired when DVR becomes enabled/disabled.\n *\n * @event PLAYBACK_DVR\n * @param {boolean} state true if dvr enabled\n */\nEvents.PLAYBACK_DVR = 'playback:dvr'\n// TODO doc\nEvents.PLAYBACK_MEDIACONTROL_DISABLE = 'playback:mediacontrol:disable'\n// TODO doc\nEvents.PLAYBACK_MEDIACONTROL_ENABLE = 'playback:mediacontrol:enable'\n/**\n * Fired when the media for a playback ends.\n *\n * @event PLAYBACK_ENDED\n * @param {String} name the name of the playback\n */\nEvents.PLAYBACK_ENDED = 'playback:ended'\n/**\n * Fired when user requests `play()`\n *\n * @event PLAYBACK_PLAY_INTENT\n */\nEvents.PLAYBACK_PLAY_INTENT = 'playback:play:intent'\n/**\n * Fired when the media for a playback starts playing.\n * This is not necessarily when the user requests `play()`\n * The media may have to buffer first.\n * I.e. `isPlaying()` might return `true` before this event is fired,\n * because `isPlaying()` represents the intended state.\n *\n * @event PLAYBACK_PLAY\n */\nEvents.PLAYBACK_PLAY = 'playback:play'\n/**\n * Fired when the media for a playback pauses.\n *\n * @event PLAYBACK_PAUSE\n */\nEvents.PLAYBACK_PAUSE = 'playback:pause'\n/**\n * Fired when the media for a playback is stopped.\n *\n * @event PLAYBACK_STOP\n */\nEvents.PLAYBACK_STOP = 'playback:stop'\n/**\n * Fired if an error occurs in the playback.\n *\n * @event PLAYBACK_ERROR\n * @param {Object} error An object containing the error details\n * @param {String} name Playback name\n */\nEvents.PLAYBACK_ERROR = 'playback:error'\n// TODO doc\nEvents.PLAYBACK_STATS_ADD = 'playback:stats:add'\n// TODO doc\nEvents.PLAYBACK_FRAGMENT_LOADED = 'playback:fragment:loaded'\n// TODO doc\nEvents.PLAYBACK_LEVEL_SWITCH = 'playback:level:switch'\n\n/**\n * Fired when the options were changed for the core\n *\n * @event CORE_OPTIONS_CHANGE\n */\nEvents.CORE_OPTIONS_CHANGE = 'core:options:change'\n/**\n * Fired after creating containers, when the core is ready\n *\n * @event CORE_READY\n */\nEvents.CORE_READY = 'core:ready'\n/**\n * Fired when the fullscreen state change\n *\n * @param {Boolean} whether or not the player is on fullscreen mode\n * @event CORE_READY\n */\nEvents.CORE_FULLSCREEN = 'core:fullscreen'\n\n// Container Events\n/**\n * Fired when the container internal state changes\n *\n * @event CONTAINER_PLAYBACKSTATE\n * @param {Object} state Data\n * state object\n * @param {String} [state.type]\n * the playback type\n */\nEvents.CONTAINER_PLAYBACKSTATE = 'container:playbackstate'\nEvents.CONTAINER_PLAYBACKDVRSTATECHANGED = 'container:dvr'\n/**\n * Fired when the container updates its bitrate\n *\n * @event CONTAINER_BITRATE\n * @param {Object} bitrate Data\n * bitrate object\n * @param {Number} [bitrate.bandwidth]\n * bitrate bandwidth when it's available\n * @param {Number} [bitrate.width]\n * playback width (ex: 720, 640, 1080)\n * @param {Number} [bitrate.height]\n * playback height (ex: 240, 480, 720)\n * @param {Number} [bitrate.level]\n * playback level when it's available, it could be just a map for width (0 => 240, 1 => 480, 2 => 720)\n */\nEvents.CONTAINER_BITRATE = 'container:bitrate'\nEvents.CONTAINER_STATS_REPORT = 'container:stats:report'\nEvents.CONTAINER_DESTROYED = 'container:destroyed'\n/**\n * Fired when the container is ready\n *\n * @event CONTAINER_READY\n */\nEvents.CONTAINER_READY = 'container:ready'\nEvents.CONTAINER_ERROR = 'container:error'\n/**\n * Fired when the container loaded its metadata\n *\n * @event CONTAINER_LOADEDMETADATA\n * @param {Object} metadata Data\n * settings object\n * @param {Number} [metadata.duration]\n * the playback duration\n * @param {Object} [metadata.data]\n * extra meta data\n */\nEvents.CONTAINER_LOADEDMETADATA = 'container:loadedmetadata'\n/**\n * Fired when the time is updated on container\n *\n * @event CONTAINER_TIMEUPDATE\n * @param {Object} progress Data\n * progress object\n * @param {Number} [progress.current]\n * current time\n * @param {Number} [progress.total]\n * total time\n */\nEvents.CONTAINER_TIMEUPDATE = 'container:timeupdate'\n/**\n * Fired when the container is downloading the media\n *\n * @event CONTAINER_PROGRESS\n * @param {Object} progress Data\n * progress object\n * @param {Number} [progress.start]\n * initial downloaded content\n * @param {Number} [progress.current]\n * current dowloaded content\n * @param {Number} [progress.total]\n * total content to be downloaded\n */\nEvents.CONTAINER_PROGRESS = 'container:progress'\nEvents.CONTAINER_PLAY = 'container:play'\nEvents.CONTAINER_STOP = 'container:stop'\nEvents.CONTAINER_PAUSE = 'container:pause'\nEvents.CONTAINER_ENDED = 'container:ended'\nEvents.CONTAINER_CLICK = 'container:click'\nEvents.CONTAINER_DBLCLICK = 'container:dblclick'\nEvents.CONTAINER_CONTEXTMENU = 'container:contextmenu'\nEvents.CONTAINER_MOUSE_ENTER = 'container:mouseenter'\nEvents.CONTAINER_MOUSE_LEAVE = 'container:mouseleave'\n/**\n * Fired when the container seeks the video\n *\n * @event CONTAINER_SEEK\n * @param {Number} time the current time in seconds\n */\nEvents.CONTAINER_SEEK = 'container:seek'\nEvents.CONTAINER_VOLUME = 'container:volume'\nEvents.CONTAINER_FULLSCREEN = 'container:fullscreen'\n/**\n * Fired when container is buffering\n *\n * @event CONTAINER_STATE_BUFFERING\n */\nEvents.CONTAINER_STATE_BUFFERING = 'container:state:buffering'\n/**\n * Fired when the container filled the buffer\n *\n * @event CONTAINER_STATE_BUFFERFULL\n */\nEvents.CONTAINER_STATE_BUFFERFULL = 'container:state:bufferfull'\n/**\n * Fired when the container changes any settings (volume, seek and etc)\n *\n * @event CONTAINER_SETTINGSUPDATE\n */\nEvents.CONTAINER_SETTINGSUPDATE = 'container:settingsupdate'\n/**\n * Fired when container updates its video quality\n *\n * @event CONTAINER_HIGHDEFINITIONUPDATE\n * @param {Boolean} isHD\n * true when is on HD, false otherwise\n */\nEvents.CONTAINER_HIGHDEFINITIONUPDATE = 'container:highdefinitionupdate'\n\n/**\n * Fired when the media control shows\n *\n * @event CONTAINER_MEDIACONTROL_SHOW\n */\nEvents.CONTAINER_MEDIACONTROL_SHOW = 'container:mediacontrol:show'\n/**\n * Fired when the media control hides\n *\n * @event CONTAINER_MEDIACONTROL_HIDE\n */\nEvents.CONTAINER_MEDIACONTROL_HIDE = 'container:mediacontrol:hide'\n\nEvents.CONTAINER_MEDIACONTROL_DISABLE = 'container:mediacontrol:disable'\nEvents.CONTAINER_MEDIACONTROL_ENABLE = 'container:mediacontrol:enable'\nEvents.CONTAINER_STATS_ADD = 'container:stats:add'\n/**\n * Fired when the options were changed for the container\n *\n * @event CONTAINER_OPTIONS_CHANGE\n */\nEvents.CONTAINER_OPTIONS_CHANGE = 'container:options:change'\n\n// MediaControl Events\nEvents.MEDIACONTROL_RENDERED = 'mediacontrol:rendered'\n/**\n * Fired when the player enters/exit on fullscreen\n *\n * @event MEDIACONTROL_FULLSCREEN\n */\nEvents.MEDIACONTROL_FULLSCREEN = 'mediacontrol:fullscreen'\n/**\n * Fired when the media control shows\n *\n * @event MEDIACONTROL_SHOW\n */\nEvents.MEDIACONTROL_SHOW = 'mediacontrol:show'\n/**\n * Fired when the media control hides\n *\n * @event MEDIACONTROL_HIDE\n */\nEvents.MEDIACONTROL_HIDE = 'mediacontrol:hide'\n/**\n * Fired when mouse enters on the seekbar\n *\n * @event MEDIACONTROL_MOUSEMOVE_SEEKBAR\n * @param {Object} event\n * the javascript event\n */\nEvents.MEDIACONTROL_MOUSEMOVE_SEEKBAR = 'mediacontrol:mousemove:seekbar'\n/**\n * Fired when mouse leaves the seekbar\n *\n * @event MEDIACONTROL_MOUSELEAVE_SEEKBAR\n * @param {Object} event\n * the javascript event\n */\nEvents.MEDIACONTROL_MOUSELEAVE_SEEKBAR = 'mediacontrol:mouseleave:seekbar'\n/**\n * Fired when the media is being played\n *\n * @event MEDIACONTROL_PLAYING\n */\nEvents.MEDIACONTROL_PLAYING = 'mediacontrol:playing'\n/**\n * Fired when the media is not being played\n *\n * @event MEDIACONTROL_NOTPLAYING\n */\nEvents.MEDIACONTROL_NOTPLAYING = 'mediacontrol:notplaying'\n/**\n * Fired when the container was changed\n *\n * @event MEDIACONTROL_CONTAINERCHANGED\n */\nEvents.MEDIACONTROL_CONTAINERCHANGED = 'mediacontrol:containerchanged'\n\n// Core Events\nEvents.CORE_CONTAINERS_CREATED = 'core:containers:created'\n\n\n\n// WEBPACK FOOTER //\n// ./src/base/events.js","// Copyright 2014 Globo.com Player authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n/*jshint -W079 */\n\nimport Browser from 'components/browser'\n\nfunction assign(obj, source) {\n if (source) {\n for (const prop in source) {\n const propDescriptor = Object.getOwnPropertyDescriptor(source, prop)\n propDescriptor ? Object.defineProperty(obj, prop, propDescriptor) : obj[prop] = source[prop]\n }\n }\n return obj\n}\n\nexport function extend(parent, properties) {\n class Surrogate extends parent {\n constructor(...args) {\n super(...args)\n if (properties.initialize) {\n properties.initialize.apply(this, args)\n }\n }\n }\n assign(Surrogate.prototype, properties)\n return Surrogate\n}\n\nexport function formatTime(time, paddedHours) {\n if (!isFinite(time)) {\n return '--:--'\n }\n time = time * 1000\n time = parseInt(time/1000)\n const seconds = time % 60\n time = parseInt(time/60)\n const minutes = time % 60\n time = parseInt(time/60)\n const hours = time % 24\n const days = parseInt(time/24)\n let out = ''\n if (days && days > 0) {\n out += days + ':'\n if (hours < 1) {out += '00:'}\n }\n if (hours && hours > 0 || paddedHours) {out += ('0' + hours).slice(-2) + ':'}\n out += ('0' + minutes).slice(-2) + ':'\n out += ('0' + seconds).slice(-2)\n return out.trim()\n}\n\nexport const Fullscreen = {\n isFullscreen: function() {\n return !!(\n document.webkitFullscreenElement ||\n document.webkitIsFullScreen ||\n document.mozFullScreen ||\n document.msFullscreenElement\n )\n },\n requestFullscreen: function(el) {\n if(el.requestFullscreen) {\n el.requestFullscreen()\n } else if(el.webkitRequestFullscreen) {\n el.webkitRequestFullscreen()\n } else if(el.mozRequestFullScreen) {\n el.mozRequestFullScreen()\n } else if(el.msRequestFullscreen) {\n el.msRequestFullscreen()\n } else if (el.querySelector && el.querySelector('video') && el.querySelector('video').webkitEnterFullScreen) {\n el.querySelector('video').webkitEnterFullScreen()\n }\n },\n cancelFullscreen: function() {\n if(document.exitFullscreen) {\n document.exitFullscreen()\n } else if(document.webkitCancelFullScreen) {\n document.webkitCancelFullScreen()\n } else if(document.webkitExitFullscreen) {\n document.webkitExitFullscreen()\n } else if(document.mozCancelFullScreen) {\n document.mozCancelFullScreen()\n } else if(document.msExitFullscreen) {\n document.msExitFullscreen()\n }\n },\n fullscreenEnabled: function() {\n return !!(\n document.fullscreenEnabled ||\n document.webkitFullscreenEnabled ||\n document.mozFullScreenEnabled ||\n document.msFullscreenEnabled\n )\n }\n}\n\nexport class Config {\n\n static _defaultConfig() {\n return {\n volume: {\n value: 100,\n parse: parseInt\n }\n }\n }\n\n static _defaultValueFor(key) {\n try {\n return this._defaultConfig()[key].parse(this._defaultConfig()[key].value)\n } catch(e) {\n return undefined\n }\n }\n\n static _createKeyspace(key){\n return `clappr.${document.domain}.${key}`\n }\n\n static restore(key) {\n if (Browser.hasLocalstorage && localStorage[this._createKeyspace(key)]){\n return this._defaultConfig()[key].parse(localStorage[this._createKeyspace(key)])\n }\n return this._defaultValueFor(key)\n }\n\n static persist(key, value) {\n if (Browser.hasLocalstorage) {\n try {\n localStorage[this._createKeyspace(key)] = value\n return true\n } catch(e) {\n return false\n }\n }\n }\n}\n\nexport class QueryString {\n static get params() {\n const query = window.location.search.substring(1)\n if (query !== this.query) {\n this._urlParams = this.parse(query)\n this.query = query\n }\n return this._urlParams\n }\n\n static get hashParams() {\n const hash = window.location.hash.substring(1)\n if (hash !== this.hash) {\n this._hashParams = this.parse(hash)\n this.hash = hash\n }\n return this._hashParams\n }\n\n static parse(paramsString) {\n let match\n const pl = /\\+/g, // Regex for replacing addition symbol with a space\n search = /([^&=]+)=?([^&]*)/g,\n decode = (s) => decodeURIComponent(s.replace(pl, ' ')),\n params = {}\n while (match = search.exec(paramsString)) { // eslint-disable-line no-cond-assign\n params[decode(match[1]).toLowerCase()] = decode(match[2])\n }\n return params\n }\n}\n\nexport function seekStringToSeconds(paramName = 't') {\n let seconds = 0\n const seekString = QueryString.params[paramName] || QueryString.hashParams[paramName] || ''\n const parts = seekString.match(/[0-9]+[hms]+/g) || []\n if (parts.length > 0) {\n const factor = {'h': 3600, 'm': 60, 's': 1}\n parts.forEach(function(el) {\n if (el) {\n const suffix = el[el.length - 1]\n const time = parseInt(el.slice(0, el.length - 1), 10)\n seconds += time * (factor[suffix])\n }\n })\n } else if (seekString) {\n seconds = parseInt(seekString, 10)\n }\n return seconds\n}\n\nconst idsCounter = {}\n\nexport function uniqueId(prefix) {\n idsCounter[prefix] || (idsCounter[prefix] = 0)\n const id = ++idsCounter[prefix]\n return prefix + id\n}\n\nexport function isNumber(value) {\n return value - parseFloat(value) + 1 >= 0\n}\n\nexport function currentScriptUrl() {\n const scripts = document.getElementsByTagName('script')\n return scripts.length ? scripts[scripts.length - 1].src : ''\n}\n\nexport const requestAnimationFrame = (window.requestAnimationFrame ||\n window.mozRequestAnimationFrame ||\n window.webkitRequestAnimationFrame ||\n function(fn) { window.setTimeout(fn, 1000/60) }).bind(window)\n\nexport const cancelAnimationFrame = (window.cancelAnimationFrame ||\n window.mozCancelAnimationFrame ||\n window.webkitCancelAnimationFrame ||\n window.clearTimeout).bind(window)\n\nexport function getBrowserLanguage() {\n return window.navigator && window.navigator.language\n}\n\nexport function now() {\n if (window.performance && window.performance.now) {\n return performance.now()\n }\n return Date.now()\n}\n\n// remove the item from the array if it exists in the array\nexport function removeArrayItem(arr, item) {\n const i = arr.indexOf(item)\n if (i >= 0) {\n arr.splice(i, 1)\n }\n}\n\nexport default {\n Config,\n Fullscreen,\n QueryString,\n extend,\n formatTime,\n seekStringToSeconds,\n uniqueId,\n currentScriptUrl,\n isNumber,\n requestAnimationFrame,\n cancelAnimationFrame,\n getBrowserLanguage,\n now,\n removeArrayItem\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/base/utils.js","import {extend} from './utils'\nimport UIObject from './ui_object'\n\n/**\n * An abstraction to represent a generic playback, it's like an interface to be implemented by subclasses.\n * @class Playback\n * @constructor\n * @extends UIObject\n * @module base\n */\nexport default class Playback extends UIObject {\n /**\n * Determine if the playback does not contain video/has video but video should be ignored.\n * @property isAudioOnly\n * @type Boolean\n */\n get isAudioOnly() {\n return false\n }\n\n /**\n * Determine if the playback has ended.\n * @property ended\n * @type Boolean\n */\n get ended() {\n return false\n }\n\n /**\n * The internationalization plugin.\n * @property i18n\n * @type {Strings}\n */\n get i18n() {\n return this._i18n\n }\n\n /**\n * Determine if the playback is having to buffer in order for\n * playback to be smooth.\n * (i.e if a live stream is playing smoothly, this will be false)\n * @property buffering\n * @type Boolean\n */\n get buffering() {\n return false\n }\n\n /**\n * @method constructor\n * @param {Object} options the options object\n * @param {Strings} i18n the internationalization component\n */\n constructor(options, i18n) {\n super(options)\n this.settings = {}\n this._i18n = i18n\n }\n\n /**\n * plays the playback.\n * @method play\n */\n play() {}\n\n /**\n * pauses the playback.\n * @method pause\n */\n pause() {}\n\n /**\n * stops the playback.\n * @method stop\n */\n stop() {}\n\n /**\n * seeks the playback to a given `time` in seconds\n * @method seek\n * @param {Number} time should be a number between 0 and the video duration\n */\n seek(time) {} // eslint-disable-line no-unused-vars\n\n /**\n * seeks the playback to a given `percentage` in percentage\n * @method seekPercentage\n * @param {Number} time should be a number between 0 and 100\n */\n seekPercentage(percentage) {} // eslint-disable-line no-unused-vars\n\n\n /**\n * The time that \"0\" now represents relative to when playback started.\n * For a stream with a sliding window this will increase as content is\n * removed from the beginning.\n * @method getStartTimeOffset\n * @return {Number} time (in seconds) that time \"0\" represents.\n */\n getStartTimeOffset() { return 0 }\n\n /**\n * gets the duration in seconds\n * @method getDuration\n * @return {Number} duration (in seconds) of the current source\n */\n getDuration() { return 0 }\n\n /**\n * checks if the playback is playing.\n * @method isPlaying\n * @return {Boolean} `true` if the current playback is playing, otherwise `false`\n */\n isPlaying() {\n return false\n }\n\n /**\n * checks if the playback is ready.\n * @property isReady\n * @type {Boolean} `true` if the current playback is ready, otherwise `false`\n */\n get isReady() {\n return false\n }\n\n /**\n * gets the playback type (`'vod', 'live', 'aod'`)\n * @method getPlaybackType\n * @return {String} you should write the playback type otherwise it'll assume `'no_op'`\n * @example\n * ```javascript\n * html5VideoPlayback.getPlaybackType() //vod\n * html5AudioPlayback.getPlaybackType() //aod\n * html5VideoPlayback.getPlaybackType() //live\n * flashHlsPlayback.getPlaybackType() //live\n * ```\n */\n getPlaybackType() {\n return Playback.NO_OP\n }\n\n /**\n * checks if the playback is in HD.\n * @method isHighDefinitionInUse\n * @return {Boolean} `true` if the playback is playing in HD, otherwise `false`\n */\n isHighDefinitionInUse() {\n return false\n }\n\n /**\n * sets the volume for the playback\n * @method volume\n * @param {Number} value a number between 0 (`muted`) to 100 (`max`)\n */\n volume(value) {} // eslint-disable-line no-unused-vars\n\n /**\n * destroys the playback, removing it from DOM\n * @method destroy\n */\n destroy() {\n this.$el.remove()\n }\n}\n\nPlayback.extend = function(properties) {\n return extend(Playback, properties)\n}\n\n/**\n * checks if the playback can play a given `source`\n * If a mimeType is provided then this will be used instead of inferring the mimetype\n * from the source extension.\n * @method canPlay\n * @static\n * @param {String} source the given source ex: `http://example.com/play.mp4`\n * @param {String} [mimeType] the given mime type, ex: `'application/vnd.apple.mpegurl'`\n * @return {Boolean} `true` if the playback is playable, otherwise `false`\n */\nPlayback.canPlay = (source, mimeType) => { // eslint-disable-line no-unused-vars\n return false\n}\n\n/**\n * a playback type for video on demand\n *\n * @property VOD\n * @static\n * @type String\n */\nPlayback.VOD = 'vod'\n/**\n * a playback type for audio on demand\n *\n * @property AOD\n * @static\n * @type String\n */\nPlayback.AOD = 'aod'\n/**\n * a playback type for live video\n *\n * @property LIVE\n * @static\n * @type String\n */\nPlayback.LIVE = 'live'\n/**\n * a default playback type\n *\n * @property NO_OP\n * @static\n * @type String\n */\nPlayback.NO_OP = 'no_op'\n/**\n * the plugin type\n *\n * @property type\n * @static\n * @type String\n */\nPlayback.type = 'playback'\n\n\n\n// WEBPACK FOOTER //\n// ./src/base/playback.js","// Copyright 2014 Globo.com Player authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\nimport $ from 'clappr-zepto'\nimport template from './template'\n\nconst Styler = {\n getStyleFor: function(style, options={baseUrl: ''}) {\n return $('').html(template(style.toString())(options))\n }\n}\n\nexport default Styler\n\n\n\n// WEBPACK FOOTER //\n// ./src/base/styler.js","/* Zepto v1.1.4-80-ga9184b2 - zepto event ajax callbacks deferred touch selector ie - zeptojs.com/license */\nvar Zepto=function(){function D(t){return null==t?String(t):j[S.call(t)]||\"object\"}function L(t){return\"function\"==D(t)}function k(t){return null!=t&&t==t.window}function Z(t){return null!=t&&t.nodeType==t.DOCUMENT_NODE}function $(t){return\"object\"==D(t)}function F(t){return $(t)&&!k(t)&&Object.getPrototypeOf(t)==Object.prototype}function R(t){return\"number\"==typeof t.length}function q(t){return s.call(t,function(t){return null!=t})}function W(t){return t.length>0?n.fn.concat.apply([],t):t}function z(t){return t.replace(/::/g,\"/\").replace(/([A-Z]+)([A-Z][a-z])/g,\"$1_$2\").replace(/([a-z\\d])([A-Z])/g,\"$1_$2\").replace(/_/g,\"-\").toLowerCase()}function H(t){return t in c?c[t]:c[t]=new RegExp(\"(^|\\\\s)\"+t+\"(\\\\s|$)\")}function _(t,e){return\"number\"!=typeof e||l[z(t)]?e:e+\"px\"}function I(t){var e,n;return f[t]||(e=u.createElement(t),u.body.appendChild(e),n=getComputedStyle(e,\"\").getPropertyValue(\"display\"),e.parentNode.removeChild(e),\"none\"==n&&(n=\"block\"),f[t]=n),f[t]}function U(t){return\"children\"in t?a.call(t.children):n.map(t.childNodes,function(t){return 1==t.nodeType?t:void 0})}function X(t,e){var n,i=t?t.length:0;for(n=0;i>n;n++)this[n]=t[n];this.length=i,this.selector=e||\"\"}function B(n,i,r){for(e in i)r&&(F(i[e])||A(i[e]))?(F(i[e])&&!F(n[e])&&(n[e]={}),A(i[e])&&!A(n[e])&&(n[e]=[]),B(n[e],i[e],r)):i[e]!==t&&(n[e]=i[e])}function V(t,e){return null==e?n(t):n(t).filter(e)}function Y(t,e,n,i){return L(e)?e.call(t,n,i):e}function J(t,e,n){null==n?t.removeAttribute(e):t.setAttribute(e,n)}function G(e,n){var i=e.className||\"\",r=i&&i.baseVal!==t;return n===t?r?i.baseVal:i:void(r?i.baseVal=n:e.className=n)}function K(t){try{return t?\"true\"==t||(\"false\"==t?!1:\"null\"==t?null:+t+\"\"==t?+t:/^[\\[\\{]/.test(t)?n.parseJSON(t):t):t}catch(e){return t}}function Q(t,e){e(t);for(var n=0,i=t.childNodes.length;i>n;n++)Q(t.childNodes[n],e)}var t,e,n,i,N,P,r=[],o=r.concat,s=r.filter,a=r.slice,u=window.document,f={},c={},l={\"column-count\":1,columns:1,\"font-weight\":1,\"line-height\":1,opacity:1,\"z-index\":1,zoom:1},h=/^\\s*<(\\w+|!)[^>]*>/,p=/^<(\\w+)\\s*\\/?>(?:<\\/\\1>|)$/,d=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\\w:]+)[^>]*)\\/>/gi,m=/^(?:body|html)$/i,g=/([A-Z])/g,v=[\"val\",\"css\",\"html\",\"text\",\"data\",\"width\",\"height\",\"offset\"],y=[\"after\",\"prepend\",\"before\",\"append\"],w=u.createElement(\"table\"),x=u.createElement(\"tr\"),b={tr:u.createElement(\"tbody\"),tbody:w,thead:w,tfoot:w,td:x,th:x,\"*\":u.createElement(\"div\")},E=/complete|loaded|interactive/,T=/^[\\w-]*$/,j={},S=j.toString,C={},O=u.createElement(\"div\"),M={tabindex:\"tabIndex\",readonly:\"readOnly\",\"for\":\"htmlFor\",\"class\":\"className\",maxlength:\"maxLength\",cellspacing:\"cellSpacing\",cellpadding:\"cellPadding\",rowspan:\"rowSpan\",colspan:\"colSpan\",usemap:\"useMap\",frameborder:\"frameBorder\",contenteditable:\"contentEditable\"},A=Array.isArray||function(t){return t instanceof Array};return C.matches=function(t,e){if(!e||!t||1!==t.nodeType)return!1;var n=t.webkitMatchesSelector||t.mozMatchesSelector||t.oMatchesSelector||t.matchesSelector;if(n)return n.call(t,e);var i,r=t.parentNode,o=!r;return o&&(r=O).appendChild(t),i=~C.qsa(r,e).indexOf(t),o&&O.removeChild(t),i},N=function(t){return t.replace(/-+(.)?/g,function(t,e){return e?e.toUpperCase():\"\"})},P=function(t){return s.call(t,function(e,n){return t.indexOf(e)==n})},C.fragment=function(e,i,r){var o,s,f;return p.test(e)&&(o=n(u.createElement(RegExp.$1))),o||(e.replace&&(e=e.replace(d,\"<$1>$2>\")),i===t&&(i=h.test(e)&&RegExp.$1),i in b||(i=\"*\"),f=b[i],f.innerHTML=\"\"+e,o=n.each(a.call(f.childNodes),function(){f.removeChild(this)})),F(r)&&(s=n(o),n.each(r,function(t,e){v.indexOf(t)>-1?s[t](e):s.attr(t,e)})),o},C.Z=function(t,e){return new X(t,e)},C.isZ=function(t){return t instanceof C.Z},C.init=function(e,i){var r;if(!e)return C.Z();if(\"string\"==typeof e)if(e=e.trim(),\"<\"==e[0]&&h.test(e))r=C.fragment(e,RegExp.$1,i),e=null;else{if(i!==t)return n(i).find(e);r=C.qsa(u,e)}else{if(L(e))return n(u).ready(e);if(C.isZ(e))return e;if(A(e))r=q(e);else if($(e))r=[e],e=null;else if(h.test(e))r=C.fragment(e.trim(),RegExp.$1,i),e=null;else{if(i!==t)return n(i).find(e);r=C.qsa(u,e)}}return C.Z(r,e)},n=function(t,e){return C.init(t,e)},n.extend=function(t){var e,n=a.call(arguments,1);return\"boolean\"==typeof t&&(e=t,t=n.shift()),n.forEach(function(n){B(t,n,e)}),t},C.qsa=function(t,e){var n,i=\"#\"==e[0],r=!i&&\".\"==e[0],o=i||r?e.slice(1):e,s=T.test(o);return t.getElementById&&s&&i?(n=t.getElementById(o))?[n]:[]:1!==t.nodeType&&9!==t.nodeType&&11!==t.nodeType?[]:a.call(s&&!i&&t.getElementsByClassName?r?t.getElementsByClassName(o):t.getElementsByTagName(e):t.querySelectorAll(e))},n.contains=u.documentElement.contains?function(t,e){return t!==e&&t.contains(e)}:function(t,e){for(;e&&(e=e.parentNode);)if(e===t)return!0;return!1},n.type=D,n.isFunction=L,n.isWindow=k,n.isArray=A,n.isPlainObject=F,n.isEmptyObject=function(t){var e;for(e in t)return!1;return!0},n.inArray=function(t,e,n){return r.indexOf.call(e,t,n)},n.camelCase=N,n.trim=function(t){return null==t?\"\":String.prototype.trim.call(t)},n.uuid=0,n.support={},n.expr={},n.noop=function(){},n.map=function(t,e){var n,r,o,i=[];if(R(t))for(r=0;r=0?e:e+this.length]},toArray:function(){return this.get()},size:function(){return this.length},remove:function(){return this.each(function(){null!=this.parentNode&&this.parentNode.removeChild(this)})},each:function(t){return r.every.call(this,function(e,n){return t.call(e,n,e)!==!1}),this},filter:function(t){return L(t)?this.not(this.not(t)):n(s.call(this,function(e){return C.matches(e,t)}))},add:function(t,e){return n(P(this.concat(n(t,e))))},is:function(t){return this.length>0&&C.matches(this[0],t)},not:function(e){var i=[];if(L(e)&&e.call!==t)this.each(function(t){e.call(this,t)||i.push(this)});else{var r=\"string\"==typeof e?this.filter(e):R(e)&&L(e.item)?a.call(e):n(e);this.forEach(function(t){r.indexOf(t)<0&&i.push(t)})}return n(i)},has:function(t){return this.filter(function(){return $(t)?n.contains(this,t):n(this).find(t).size()})},eq:function(t){return-1===t?this.slice(t):this.slice(t,+t+1)},first:function(){var t=this[0];return t&&!$(t)?t:n(t)},last:function(){var t=this[this.length-1];return t&&!$(t)?t:n(t)},find:function(t){var e,i=this;return e=t?\"object\"==typeof t?n(t).filter(function(){var t=this;return r.some.call(i,function(e){return n.contains(e,t)})}):1==this.length?n(C.qsa(this[0],t)):this.map(function(){return C.qsa(this,t)}):n()},closest:function(t,e){var i=this[0],r=!1;for(\"object\"==typeof t&&(r=n(t));i&&!(r?r.indexOf(i)>=0:C.matches(i,t));)i=i!==e&&!Z(i)&&i.parentNode;return n(i)},parents:function(t){for(var e=[],i=this;i.length>0;)i=n.map(i,function(t){return(t=t.parentNode)&&!Z(t)&&e.indexOf(t)<0?(e.push(t),t):void 0});return V(e,t)},parent:function(t){return V(P(this.pluck(\"parentNode\")),t)},children:function(t){return V(this.map(function(){return U(this)}),t)},contents:function(){return this.map(function(){return this.contentDocument||a.call(this.childNodes)})},siblings:function(t){return V(this.map(function(t,e){return s.call(U(e.parentNode),function(t){return t!==e})}),t)},empty:function(){return this.each(function(){this.innerHTML=\"\"})},pluck:function(t){return n.map(this,function(e){return e[t]})},show:function(){return this.each(function(){\"none\"==this.style.display&&(this.style.display=\"\"),\"none\"==getComputedStyle(this,\"\").getPropertyValue(\"display\")&&(this.style.display=I(this.nodeName))})},replaceWith:function(t){return this.before(t).remove()},wrap:function(t){var e=L(t);if(this[0]&&!e)var i=n(t).get(0),r=i.parentNode||this.length>1;return this.each(function(o){n(this).wrapAll(e?t.call(this,o):r?i.cloneNode(!0):i)})},wrapAll:function(t){if(this[0]){n(this[0]).before(t=n(t));for(var e;(e=t.children()).length;)t=e.first();n(t).append(this)}return this},wrapInner:function(t){var e=L(t);return this.each(function(i){var r=n(this),o=r.contents(),s=e?t.call(this,i):t;o.length?o.wrapAll(s):r.append(s)})},unwrap:function(){return this.parent().each(function(){n(this).replaceWith(n(this).children())}),this},clone:function(){return this.map(function(){return this.cloneNode(!0)})},hide:function(){return this.css(\"display\",\"none\")},toggle:function(e){return this.each(function(){var i=n(this);(e===t?\"none\"==i.css(\"display\"):e)?i.show():i.hide()})},prev:function(t){return n(this.pluck(\"previousElementSibling\")).filter(t||\"*\")},next:function(t){return n(this.pluck(\"nextElementSibling\")).filter(t||\"*\")},html:function(t){return 0 in arguments?this.each(function(e){var i=this.innerHTML;n(this).empty().append(Y(this,t,e,i))}):0 in this?this[0].innerHTML:null},text:function(t){return 0 in arguments?this.each(function(e){var n=Y(this,t,e,this.textContent);this.textContent=null==n?\"\":\"\"+n}):0 in this?this[0].textContent:null},attr:function(n,i){var r;return\"string\"!=typeof n||1 in arguments?this.each(function(t){if(1===this.nodeType)if($(n))for(e in n)J(this,e,n[e]);else J(this,n,Y(this,i,t,this.getAttribute(n)))}):this.length&&1===this[0].nodeType?!(r=this[0].getAttribute(n))&&n in this[0]?this[0][n]:r:t},removeAttr:function(t){return this.each(function(){1===this.nodeType&&t.split(\" \").forEach(function(t){J(this,t)},this)})},prop:function(t,e){return t=M[t]||t,1 in arguments?this.each(function(n){this[t]=Y(this,e,n,this[t])}):this[0]&&this[0][t]},data:function(e,n){var i=\"data-\"+e.replace(g,\"-$1\").toLowerCase(),r=1 in arguments?this.attr(i,n):this.attr(i);return null!==r?K(r):t},val:function(t){return 0 in arguments?this.each(function(e){this.value=Y(this,t,e,this.value)}):this[0]&&(this[0].multiple?n(this[0]).find(\"option\").filter(function(){return this.selected}).pluck(\"value\"):this[0].value)},offset:function(t){if(t)return this.each(function(e){var i=n(this),r=Y(this,t,e,i.offset()),o=i.offsetParent().offset(),s={top:r.top-o.top,left:r.left-o.left};\"static\"==i.css(\"position\")&&(s.position=\"relative\"),i.css(s)});if(!this.length)return null;if(!n.contains(u.documentElement,this[0]))return{top:0,left:0};var e=this[0].getBoundingClientRect();return{left:e.left+window.pageXOffset,top:e.top+window.pageYOffset,width:Math.round(e.width),height:Math.round(e.height)}},css:function(t,i){if(arguments.length<2){var r,o=this[0];if(!o)return;if(r=getComputedStyle(o,\"\"),\"string\"==typeof t)return o.style[N(t)]||r.getPropertyValue(t);if(A(t)){var s={};return n.each(t,function(t,e){s[e]=o.style[N(e)]||r.getPropertyValue(e)}),s}}var a=\"\";if(\"string\"==D(t))i||0===i?a=z(t)+\":\"+_(t,i):this.each(function(){this.style.removeProperty(z(t))});else for(e in t)t[e]||0===t[e]?a+=z(e)+\":\"+_(e,t[e])+\";\":this.each(function(){this.style.removeProperty(z(e))});return this.each(function(){this.style.cssText+=\";\"+a})},index:function(t){return t?this.indexOf(n(t)[0]):this.parent().children().indexOf(this[0])},hasClass:function(t){return t?r.some.call(this,function(t){return this.test(G(t))},H(t)):!1},addClass:function(t){return t?this.each(function(e){if(\"className\"in this){i=[];var r=G(this),o=Y(this,t,e,r);o.split(/\\s+/g).forEach(function(t){n(this).hasClass(t)||i.push(t)},this),i.length&&G(this,r+(r?\" \":\"\")+i.join(\" \"))}}):this},removeClass:function(e){return this.each(function(n){if(\"className\"in this){if(e===t)return G(this,\"\");i=G(this),Y(this,e,n,i).split(/\\s+/g).forEach(function(t){i=i.replace(H(t),\" \")}),G(this,i.trim())}})},toggleClass:function(e,i){return e?this.each(function(r){var o=n(this),s=Y(this,e,r,G(this));s.split(/\\s+/g).forEach(function(e){(i===t?!o.hasClass(e):i)?o.addClass(e):o.removeClass(e)})}):this},scrollTop:function(e){if(this.length){var n=\"scrollTop\"in this[0];return e===t?n?this[0].scrollTop:this[0].pageYOffset:this.each(n?function(){this.scrollTop=e}:function(){this.scrollTo(this.scrollX,e)})}},scrollLeft:function(e){if(this.length){var n=\"scrollLeft\"in this[0];return e===t?n?this[0].scrollLeft:this[0].pageXOffset:this.each(n?function(){this.scrollLeft=e}:function(){this.scrollTo(e,this.scrollY)})}},position:function(){if(this.length){var t=this[0],e=this.offsetParent(),i=this.offset(),r=m.test(e[0].nodeName)?{top:0,left:0}:e.offset();return i.top-=parseFloat(n(t).css(\"margin-top\"))||0,i.left-=parseFloat(n(t).css(\"margin-left\"))||0,r.top+=parseFloat(n(e[0]).css(\"border-top-width\"))||0,r.left+=parseFloat(n(e[0]).css(\"border-left-width\"))||0,{top:i.top-r.top,left:i.left-r.left}}},offsetParent:function(){return this.map(function(){for(var t=this.offsetParent||u.body;t&&!m.test(t.nodeName)&&\"static\"==n(t).css(\"position\");)t=t.offsetParent;return t})}},n.fn.detach=n.fn.remove,[\"width\",\"height\"].forEach(function(e){var i=e.replace(/./,function(t){return t[0].toUpperCase()});n.fn[e]=function(r){var o,s=this[0];return r===t?k(s)?s[\"inner\"+i]:Z(s)?s.documentElement[\"scroll\"+i]:(o=this.offset())&&o[e]:this.each(function(t){s=n(this),s.css(e,Y(this,r,t,s[e]()))})}}),y.forEach(function(t,e){var i=e%2;n.fn[t]=function(){var t,o,r=n.map(arguments,function(e){return t=D(e),\"object\"==t||\"array\"==t||null==e?e:C.fragment(e)}),s=this.length>1;return r.length<1?this:this.each(function(t,a){o=i?a:a.parentNode,a=0==e?a.nextSibling:1==e?a.firstChild:2==e?a:null;var f=n.contains(u.documentElement,o);r.forEach(function(t){if(s)t=t.cloneNode(!0);else if(!o)return n(t).remove();o.insertBefore(t,a),f&&Q(t,function(t){null==t.nodeName||\"SCRIPT\"!==t.nodeName.toUpperCase()||t.type&&\"text/javascript\"!==t.type||t.src||window.eval.call(window,t.innerHTML)})})})},n.fn[i?t+\"To\":\"insert\"+(e?\"Before\":\"After\")]=function(e){return n(e)[t](this),this}}),C.Z.prototype=X.prototype=n.fn,C.uniq=P,C.deserializeValue=K,n.zepto=C,n}();window.Zepto=Zepto,void 0===window.$&&(window.$=Zepto),function(t){function l(t){return t._zid||(t._zid=e++)}function h(t,e,n,i){if(e=p(e),e.ns)var r=d(e.ns);return(s[l(t)]||[]).filter(function(t){return!(!t||e.e&&t.e!=e.e||e.ns&&!r.test(t.ns)||n&&l(t.fn)!==l(n)||i&&t.sel!=i)})}function p(t){var e=(\"\"+t).split(\".\");return{e:e[0],ns:e.slice(1).sort().join(\" \")}}function d(t){return new RegExp(\"(?:^| )\"+t.replace(\" \",\" .* ?\")+\"(?: |$)\")}function m(t,e){return t.del&&!u&&t.e in f||!!e}function g(t){return c[t]||u&&f[t]||t}function v(e,i,r,o,a,u,f){var h=l(e),d=s[h]||(s[h]=[]);i.split(/\\s/).forEach(function(i){if(\"ready\"==i)return t(document).ready(r);var s=p(i);s.fn=r,s.sel=a,s.e in c&&(r=function(e){var n=e.relatedTarget;return!n||n!==this&&!t.contains(this,n)?s.fn.apply(this,arguments):void 0}),s.del=u;var l=u||r;s.proxy=function(t){if(t=T(t),!t.isImmediatePropagationStopped()){t.data=o;var i=l.apply(e,t._args==n?[t]:[t].concat(t._args));return i===!1&&(t.preventDefault(),t.stopPropagation()),i}},s.i=d.length,d.push(s),\"addEventListener\"in e&&e.addEventListener(g(s.e),s.proxy,m(s,f))})}function y(t,e,n,i,r){var o=l(t);(e||\"\").split(/\\s/).forEach(function(e){h(t,e,n,i).forEach(function(e){delete s[o][e.i],\"removeEventListener\"in t&&t.removeEventListener(g(e.e),e.proxy,m(e,r))})})}function T(e,i){return(i||!e.isDefaultPrevented)&&(i||(i=e),t.each(E,function(t,n){var r=i[t];e[t]=function(){return this[n]=w,r&&r.apply(i,arguments)},e[n]=x}),(i.defaultPrevented!==n?i.defaultPrevented:\"returnValue\"in i?i.returnValue===!1:i.getPreventDefault&&i.getPreventDefault())&&(e.isDefaultPrevented=w)),e}function j(t){var e,i={originalEvent:t};for(e in t)b.test(e)||t[e]===n||(i[e]=t[e]);return T(i,t)}var n,e=1,i=Array.prototype.slice,r=t.isFunction,o=function(t){return\"string\"==typeof t},s={},a={},u=\"onfocusin\"in window,f={focus:\"focusin\",blur:\"focusout\"},c={mouseenter:\"mouseover\",mouseleave:\"mouseout\"};a.click=a.mousedown=a.mouseup=a.mousemove=\"MouseEvents\",t.event={add:v,remove:y},t.proxy=function(e,n){var s=2 in arguments&&i.call(arguments,2);if(r(e)){var a=function(){return e.apply(n,s?s.concat(i.call(arguments)):arguments)};return a._zid=l(e),a}if(o(n))return s?(s.unshift(e[n],e),t.proxy.apply(null,s)):t.proxy(e[n],e);throw new TypeError(\"expected function\")},t.fn.bind=function(t,e,n){return this.on(t,e,n)},t.fn.unbind=function(t,e){return this.off(t,e)},t.fn.one=function(t,e,n,i){return this.on(t,e,n,i,1)};var w=function(){return!0},x=function(){return!1},b=/^([A-Z]|returnValue$|layer[XY]$)/,E={preventDefault:\"isDefaultPrevented\",stopImmediatePropagation:\"isImmediatePropagationStopped\",stopPropagation:\"isPropagationStopped\"};t.fn.delegate=function(t,e,n){return this.on(e,t,n)},t.fn.undelegate=function(t,e,n){return this.off(e,t,n)},t.fn.live=function(e,n){return t(document.body).delegate(this.selector,e,n),this},t.fn.die=function(e,n){return t(document.body).undelegate(this.selector,e,n),this},t.fn.on=function(e,s,a,u,f){var c,l,h=this;return e&&!o(e)?(t.each(e,function(t,e){h.on(t,s,a,e,f)}),h):(o(s)||r(u)||u===!1||(u=a,a=s,s=n),(u===n||a===!1)&&(u=a,a=n),u===!1&&(u=x),h.each(function(n,r){f&&(c=function(t){return y(r,t.type,u),u.apply(this,arguments)}),s&&(l=function(e){var n,o=t(e.target).closest(s,r).get(0);return o&&o!==r?(n=t.extend(j(e),{currentTarget:o,liveFired:r}),(c||u).apply(o,[n].concat(i.call(arguments,1)))):void 0}),v(r,e,u,a,s,l||c)}))},t.fn.off=function(e,i,s){var a=this;return e&&!o(e)?(t.each(e,function(t,e){a.off(t,i,e)}),a):(o(i)||r(s)||s===!1||(s=i,i=n),s===!1&&(s=x),a.each(function(){y(this,e,s,i)}))},t.fn.trigger=function(e,n){return e=o(e)||t.isPlainObject(e)?t.Event(e):T(e),e._args=n,this.each(function(){e.type in f&&\"function\"==typeof this[e.type]?this[e.type]():\"dispatchEvent\"in this?this.dispatchEvent(e):t(this).triggerHandler(e,n)})},t.fn.triggerHandler=function(e,n){var i,r;return this.each(function(s,a){i=j(o(e)?t.Event(e):e),i._args=n,i.target=a,t.each(h(a,e.type||e),function(t,e){return r=e.proxy(i),i.isImmediatePropagationStopped()?!1:void 0})}),r},\"focusin focusout focus blur load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select keydown keypress keyup error\".split(\" \").forEach(function(e){t.fn[e]=function(t){return 0 in arguments?this.bind(e,t):this.trigger(e)}}),t.Event=function(t,e){o(t)||(e=t,t=e.type);var n=document.createEvent(a[t]||\"Events\"),i=!0;if(e)for(var r in e)\"bubbles\"==r?i=!!e[r]:n[r]=e[r];return n.initEvent(t,i,!0),T(n)}}(Zepto),function(t){function h(e,n,i){var r=t.Event(n);return t(e).trigger(r,i),!r.isDefaultPrevented()}function p(t,e,i,r){return t.global?h(e||n,i,r):void 0}function d(e){e.global&&0===t.active++&&p(e,null,\"ajaxStart\")}function m(e){e.global&&!--t.active&&p(e,null,\"ajaxStop\")}function g(t,e){var n=e.context;return e.beforeSend.call(n,t,e)===!1||p(e,n,\"ajaxBeforeSend\",[t,e])===!1?!1:void p(e,n,\"ajaxSend\",[t,e])}function v(t,e,n,i){var r=n.context,o=\"success\";n.success.call(r,t,o,e),i&&i.resolveWith(r,[t,o,e]),p(n,r,\"ajaxSuccess\",[e,n,t]),w(o,e,n)}function y(t,e,n,i,r){var o=i.context;i.error.call(o,n,e,t),r&&r.rejectWith(o,[n,e,t]),p(i,o,\"ajaxError\",[n,i,t||e]),w(e,n,i)}function w(t,e,n){var i=n.context;n.complete.call(i,e,t),p(n,i,\"ajaxComplete\",[e,n]),m(n)}function x(){}function b(t){return t&&(t=t.split(\";\",2)[0]),t&&(t==f?\"html\":t==u?\"json\":s.test(t)?\"script\":a.test(t)&&\"xml\")||\"text\"}function E(t,e){return\"\"==e?t:(t+\"&\"+e).replace(/[&?]{1,2}/,\"?\")}function T(e){e.processData&&e.data&&\"string\"!=t.type(e.data)&&(e.data=t.param(e.data,e.traditional)),!e.data||e.type&&\"GET\"!=e.type.toUpperCase()||(e.url=E(e.url,e.data),e.data=void 0)}function j(e,n,i,r){return t.isFunction(n)&&(r=i,i=n,n=void 0),t.isFunction(i)||(r=i,i=void 0),{url:e,data:n,success:i,dataType:r}}function C(e,n,i,r){var o,s=t.isArray(n),a=t.isPlainObject(n);t.each(n,function(n,u){o=t.type(u),r&&(n=i?r:r+\"[\"+(a||\"object\"==o||\"array\"==o?n:\"\")+\"]\"),!r&&s?e.add(u.name,u.value):\"array\"==o||!i&&\"object\"==o?C(e,u,i,n):e.add(n,u)})}var i,r,e=0,n=window.document,o=/\n * \n * ```\n * Now, create the player:\n * ```html\n * \n * \n * \n * \n * ```\n */\nexport default class Player extends BaseObject {\n\n set loader(loader) { this._loader = loader }\n get loader() {\n if (!this._loader) {\n this._loader = new Loader(this.options.plugins || {}, this.options.playerId)\n }\n return this._loader\n }\n\n /**\n * Determine if the playback has ended.\n * @property ended\n * @type Boolean\n */\n get ended() {\n return this.core.mediaControl.container.ended\n }\n\n /**\n * Determine if the playback is having to buffer in order for\n * playback to be smooth.\n * (i.e if a live stream is playing smoothly, this will be false)\n * @property buffering\n * @type Boolean\n */\n get buffering() {\n return this.core.mediaControl.container.buffering\n }\n\n /*\n * determine if the player is ready.\n * @property isReady\n * @type {Boolean} `true` if the player is ready. ie PLAYER_READY event has fired\n */\n get isReady() {\n return !!this._ready\n }\n\n /**\n * An events map that allows the user to add custom callbacks in player's options.\n * @property eventsMapping\n * @type {Object}\n */\n get eventsMapping() {\n return {\n onReady: Events.PLAYER_READY,\n onResize: Events.PLAYER_RESIZE,\n onPlay: Events.PLAYER_PLAY,\n onPause: Events.PLAYER_PAUSE,\n onStop: Events.PLAYER_STOP,\n onEnded: Events.PLAYER_ENDED,\n onSeek: Events.PLAYER_SEEK,\n onError: Events.PLAYER_ERROR,\n onTimeUpdate: Events.PLAYER_TIMEUPDATE,\n onVolumeUpdate: Events.PLAYER_VOLUMEUPDATE\n }\n }\n\n /**\n * ## Player's constructor\n *\n * You might pass the options object to build the player.\n * ```javascript\n * var options = {source: \"http://example.com/video.mp4\", param1: \"val1\"};\n * var player = new Clappr.Player(options);\n * ```\n *\n * @method constructor\n * @param {Object} options Data\n * options to build a player instance\n * @param {Number} [options.width]\n * player's width **default**: `640`\n * @param {Number} [options.height]\n * player's height **default**: `360`\n * @param {String} [options.parentId]\n * the id of the element on the page that the player should be inserted into\n * @param {Object} [options.parent]\n * a reference to a dom element that the player should be inserted into\n * @param {String} [options.source]\n * The media source URL, or {source: <