UNPKG

hls.js

Version:

JavaScript HLS client using MediaSourceExtension

1,714 lines (1,495 loc) 799 kB
(function (factory) { typeof define === 'function' && define.amd ? define(factory) : factory(); })((function () { 'use strict'; function getDefaultExportFromCjs (x) { return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x; } /** * Create test stream * @param {string} url * @param {string} description * @param {boolean} [live] * @param {boolean} [abr] * @param {string[]} [skip_ua] * @returns {{url: string, description: string, live: boolean, abr: boolean, skip_ua: string[]}} */ var testStreams$1; var hasRequiredTestStreams; function requireTestStreams() { if (hasRequiredTestStreams) return testStreams$1; hasRequiredTestStreams = 1; function createTestStream(url, description, live, abr, skip_ua) { if (live === void 0) { live = false; } if (abr === void 0) { abr = true; } if (skip_ua === void 0) { skip_ua = []; } return { url: url, description: description, live: live, abr: abr, skip_ua: skip_ua }; } /** * @param {Object} target * @param {Object} [config] * @returns {{url: string, description: string, live: boolean, abr: boolean, skip_ua: string[]}} */ function createTestStreamWithConfig(target, config) { if (typeof target !== 'object') { throw new Error('target should be object'); } var testStream = createTestStream(target.url, target.description, target.live, target.abr, target.skip_ua); testStream.config = config; return testStream; } testStreams$1 = { bbb: { url: 'https://test-streams.mux.dev/x36xhzz/x36xhzz.m3u8', description: 'Big Buck Bunny - adaptive qualities', abr: true }, fdr: { url: 'https://cdn.jwplayer.com/manifests/pZxWPRg4.m3u8', description: 'FDR - CDN packaged, 4s segments, 180p - 1080p', abr: true }, bigBuckBunny480p: { url: 'https://test-streams.mux.dev/x36xhzz/url_6/193039199_mp4_h264_aac_hq_7.m3u8', description: 'Big Buck Bunny - 480p only', abr: false }, arte: { url: 'https://test-streams.mux.dev/test_001/stream.m3u8', description: 'ARTE China,ABR', abr: true }, deltatreDAI: { url: 'https://test-streams.mux.dev/dai-discontinuity-deltatre/manifest.m3u8', description: 'Ad-insertion in event stream', abr: false }, issue666: { url: 'https://playertest.longtailvideo.com/adaptive/issue666/playlists/cisq0gim60007xzvi505emlxx.m3u8', description: 'Surveillance footage - https://github.com/video-dev/hls.js/issues/666', abr: false }, closedCaptions: { url: 'https://playertest.longtailvideo.com/adaptive/captions/playlist.m3u8', description: 'CNN special report, with CC', abr: false }, customIvBadDts: { url: 'https://playertest.longtailvideo.com/adaptive/customIV/prog_index.m3u8', description: 'Custom IV with bad PTS DTS', abr: false }, oceansAES: { url: 'https://playertest.longtailvideo.com/adaptive/oceans_aes/oceans_aes.m3u8', description: 'AES-128 encrypted, ABR', abr: true }, tracksWithAES: { url: 'https://playertest.longtailvideo.com/adaptive/aes-with-tracks/master.m3u8', description: 'AES-128 encrypted, TS main with AAC audio track', abr: false }, mp3Audio: { url: 'https://playertest.longtailvideo.com/adaptive/vod-with-mp3/manifest.m3u8', description: 'MP3 VOD demo', abr: false }, mpegAudioOnly: { url: 'https://pl.streamingvideoprovider.com/mp3-playlist/playlist.m3u8', description: 'MPEG Audio Only demo', abr: false, skip_ua: ['MicrosoftEdge', 'firefox'] }, fmp4: { url: 'https://storage.googleapis.com/shaka-demo-assets/angel-one-hls/hls.m3u8', description: 'HLS fMP4 Angel-One multiple audio-tracks', abr: true }, fmp4Bitmovin: { url: 'https://bitdash-a.akamaihd.net/content/MI201109210084_1/m3u8s-fmp4/f08e80da-bf1d-4e3d-8899-f0f6155f6efa.m3u8', description: 'HLS fMP4 by Bitmovin', abr: true }, fmp4BitmovinHevc: { url: 'https://bitmovin-a.akamaihd.net/content/dataset/multi-codec/hevc/stream_fmp4.m3u8', description: 'HLS HEVC fMP4 by Bitmovin (Safari and Edge? only as of 2020-08)', abr: true, skipFunctionalTests: true }, offset_pts: { url: 'https://test-streams.mux.dev/pts_shift/master.m3u8', description: 'DK Turntable, PTS shifted by 2.3s', abr: true }, angelOneShakaWidevine: createTestStreamWithConfig({ url: 'https://storage.googleapis.com/shaka-demo-assets/angel-one-widevine-hls/hls.m3u8', description: 'Shaka-packager Widevine DRM (EME) HLS-fMP4 - Angel One Demo', abr: true, skip_ua: ['firefox', 'safari', { name: 'chrome', version: '75.0' }, { name: 'chrome', version: '79.0' }] }, { widevineLicenseUrl: 'https://cwip-shaka-proxy.appspot.com/no_auth', emeEnabled: true }), audioOnlyMultipleLevels: { url: 'https://s3.amazonaws.com/qa.jwplayer.com/~alex/121628/new_master.m3u8', description: 'Multiple non-alternate audio levels', abr: true }, pdtDuplicate: { url: 'https://playertest.longtailvideo.com/adaptive/artbeats/manifest.m3u8', description: 'Duplicate sequential PDT values', abr: false }, pdtLargeGap: createTestStreamWithConfig({ url: 'https://playertest.longtailvideo.com/adaptive/boxee/playlist.m3u8', description: 'PDTs with large gaps following discontinuities', abr: false }, { // gaps are introduced by missing audio samples in the TS segments // silent audio insertion can only prepend missing back to the last appended time provided there is room // The discontinuities and starting offset of the timestamps do not allow prepending earlier than the start of the disco allowedBufferedRangesInSeekTest: 7, // Ignore "should buffer up to maxBufferLength" result avBufferOffset: 39 }), pdtBadValues: { url: 'https://playertest.longtailvideo.com/adaptive/progdatime/playlist2.m3u8', description: 'PDTs with bad values', abr: false }, pdtOneValue: { url: 'https://playertest.longtailvideo.com/adaptive/aviion/manifest.m3u8', description: 'One PDT, no discontinuities', abr: false }, noTrackIntersection: createTestStreamWithConfig({ url: 'https://s3.amazonaws.com/qa.jwplayer.com/~alex/123633/new_master.m3u8', description: 'Audio/video track PTS values do not intersect; 10 second start gap', abr: false }, { avBufferOffset: 10.5 }), altAudioAndTracks: { // url: 'https://wowzaec2demo.streamlock.net/vod-multitrack/_definst_/smil:ElephantsDream/elephantsdream2.smil/playlist.m3u', url: 'https://playertest.longtailvideo.com/adaptive/elephants_dream_v4/index.m3u8', description: 'Alternate audio tracks, and multiple VTT tracks', vendor: 'wowza', abr: true }, altAudioAudioOnly: createTestStreamWithConfig({ url: 'https://playertest.longtailvideo.com/adaptive/alt-audio-no-video/sintel/playlist.m3u8', description: 'Audio only with alternate audio track (Sintel)', abr: false }, { // the playlist segment durations are longer than the media. So much so, that when seeking near the end, // the timeline shifts roughly 10 seconds seconds back, and as a result buffering skips several segments // to adjust for the currentTime now being places at the very end of the stream. allowedBufferedRangesInSeekTest: 3 }), altAudioMultiAudioOnly: { url: 'https://playertest.longtailvideo.com/adaptive/alt-audio-no-video/angel-one.m3u8', description: 'Audio only with multiple alternate audio tracks (Angel One)', abr: false }, muxedFmp4: { url: 'https://s3.amazonaws.com/qa.jwplayer.com/hlsjs/muxed-fmp4/hls.m3u8', description: 'Muxed av fmp4 - appended to "audiovideo" SourceBuffer', abr: false }, altAudioWithPdtAndStartGap: { url: 'https://playertest.longtailvideo.com/adaptive/hls-test-streams/test-audio-pdt/playlist.m3u8', description: 'PDT before each segment, 1.59s start gap', // Disable smooth switch on this stream. Test is flakey because of what looks like (auto)play issue. To be expected with this large a gap (for now). // abr: true, startSeek: true }, AppleAdvancedHevcAvcHls: { url: 'https://devstreaming-cdn.apple.com/videos/streaming/examples/bipbop_adv_example_hevc/master.m3u8', description: 'Advanced stream (HEVC/H.264, AC-3/AAC, WebVTT, fMP4 segments)' }, MuxLowLatencyHls: { url: 'https://stream.mux.com/v69RSHhFelSm4701snP22dYz2jICy4E4FUyk02rW4gxRM.m3u8', description: 'Low-Latency HLS sample of Big Buck Bunny loop and a timer. Restarts every 12 hours. (fMP4 segments)', live: true }, // AppleLowLatencyHls: { // url: 'https://ll-hls-test.apple.com/master.m3u8', // description: 'Apple Low-Latency HLS sample (TS segments)', // live: true, // }, // AppleLowLatencyCmafHls: { // url: 'https://ll-hls-test.apple.com/cmaf/master.m3u8', // description: 'Apple Low-Latency HLS sample (fMP4 segments)', // live: true, // }, groupIds: { url: 'https://mtoczko.github.io/hls-test-streams/test-group/playlist.m3u8', description: 'Group-id: subtitle and audio', abr: true, skipFunctionalTests: true }, redundantLevelsWithTrackGroups: { url: 'https://playertest.longtailvideo.com/adaptive/elephants_dream_v4/redundant.m3u8', description: 'Redundant levels with subtitle and audio track groups', abr: true, skipFunctionalTests: true }, startDelimiterOverlappingBetweenPESPackets: { url: 'https://wistia.github.io/hlsjs-test-streams/assets/start-delimiter.m3u8', description: "A stream with the start delimiter overlapping between PES packets.\n Related to https://github.com/video-dev/hls.js/issues/3834, where Apple Silicon chips throw decoding errors if\n NAL units are not starting right at the beginning of the PES packet when using hardware accelerated decoding.", abr: false, skipFunctionalTests: true }, aes256: { url: 'https://jvaryhlstests.blob.core.windows.net/hlstestdata/playlist_encrypted.m3u8', description: 'aes-256 and aes-256-ctr full segment encryption', abr: false }, mpegTsHevcHls: { url: 'https://devoldemar.github.io/streams/hls/bipbop/hevc.m3u8', description: 'Advanced stream (HEVC Main 10, MPEG-TS segments)', skipFunctionalTests: true }, mpegTsBitmovinHevc: { url: 'https://bitmovin-a.akamaihd.net/content/dataset/multi-codec/hevc/v720p_ts.m3u8', description: 'HLS M2TS by Bitmovin (HEVC Main, many NALUs overflowing PESes, video only)', abr: false, skipFunctionalTests: true } }; return testStreams$1; } var main = {}; /* Copyright (c) 2013, Rodrigo González, Sapienlab All Rights Reserved. Available via MIT LICENSE. See https://github.com/roro89/jsonpack/blob/master/LICENSE.md for details. */ var hasRequiredMain; function requireMain () { if (hasRequiredMain) return main; hasRequiredMain = 1; (function (exports) { (function(define) { define([], function() { var TOKEN_TRUE = -1; var TOKEN_FALSE = -2; var TOKEN_NULL = -3; var TOKEN_EMPTY_STRING = -4; var TOKEN_UNDEFINED = -5; var pack = function(json, options) { // Canonizes the options options = options || {}; // A shorthand for debugging var verbose = options.verbose || false; verbose && console.log('Normalize the JSON Object'); // JSON as Javascript Object (Not string representation) json = typeof json === 'string' ? this.JSON.parse(json) : json; verbose && console.log('Creating a empty dictionary'); // The dictionary var dictionary = { strings : [], integers : [], floats : [] }; verbose && console.log('Creating the AST'); // The AST var ast = (function recursiveAstBuilder(item) { verbose && console.log('Calling recursiveAstBuilder with ' + this.JSON.stringify(item)); // The type of the item var type = typeof item; // Case 7: The item is null if (item === null) { return { type : 'null', index : TOKEN_NULL }; } //add undefined if (typeof item === 'undefined') { return { type : 'undefined', index : TOKEN_UNDEFINED }; } // Case 1: The item is Array Object if ( item instanceof Array) { // Create a new sub-AST of type Array (@) var ast = ['@']; // Add each items for (var i in item) { if (!item.hasOwnProperty(i)) continue; ast.push(recursiveAstBuilder(item[i])); } // And return return ast; } // Case 2: The item is Object if (type === 'object') { // Create a new sub-AST of type Object ($) var ast = ['$']; // Add each items for (var key in item) { if (!item.hasOwnProperty(key)) continue; ast.push(recursiveAstBuilder(key)); ast.push(recursiveAstBuilder(item[key])); } // And return return ast; } // Case 3: The item empty string if (item === '') { return { type : 'empty', index : TOKEN_EMPTY_STRING }; } // Case 4: The item is String if (type === 'string') { // The index of that word in the dictionary var index = _indexOf.call(dictionary.strings, item); // If not, add to the dictionary and actualize the index if (index == -1) { dictionary.strings.push(_encode(item)); index = dictionary.strings.length - 1; } // Return the token return { type : 'strings', index : index }; } // Case 5: The item is integer if (type === 'number' && item % 1 === 0) { // The index of that number in the dictionary var index = _indexOf.call(dictionary.integers, item); // If not, add to the dictionary and actualize the index if (index == -1) { dictionary.integers.push(_base10To36(item)); index = dictionary.integers.length - 1; } // Return the token return { type : 'integers', index : index }; } // Case 6: The item is float if (type === 'number') { // The index of that number in the dictionary var index = _indexOf.call(dictionary.floats, item); // If not, add to the dictionary and actualize the index if (index == -1) { // Float not use base 36 dictionary.floats.push(item); index = dictionary.floats.length - 1; } // Return the token return { type : 'floats', index : index }; } // Case 7: The item is boolean if (type === 'boolean') { return { type : 'boolean', index : item ? TOKEN_TRUE : TOKEN_FALSE }; } // Default throw new Error('Unexpected argument of type ' + typeof (item)); })(json); // A set of shorthands proxies for the length of the dictionaries var stringLength = dictionary.strings.length; var integerLength = dictionary.integers.length; dictionary.floats.length; verbose && console.log('Parsing the dictionary'); // Create a raw dictionary var packed = dictionary.strings.join('|'); packed += '^' + dictionary.integers.join('|'); packed += '^' + dictionary.floats.join('|'); verbose && console.log('Parsing the structure'); // And add the structure packed += '^' + (function recursiveParser(item) { verbose && console.log('Calling a recursiveParser with ' + this.JSON.stringify(item)); // If the item is Array, then is a object of // type [object Object] or [object Array] if ( item instanceof Array) { // The packed resulting var packed = item.shift(); for (var i in item) { if (!item.hasOwnProperty(i)) continue; packed += recursiveParser(item[i]) + '|'; } return (packed[packed.length - 1] === '|' ? packed.slice(0, -1) : packed) + ']'; } // A shorthand proxies var type = item.type, index = item.index; if (type === 'strings') { // Just return the base 36 of index return _base10To36(index); } if (type === 'integers') { // Return a base 36 of index plus stringLength offset return _base10To36(stringLength + index); } if (type === 'floats') { // Return a base 36 of index plus stringLength and integerLength offset return _base10To36(stringLength + integerLength + index); } if (type === 'boolean') { return item.index; } if (type === 'null') { return TOKEN_NULL; } if (type === 'undefined') { return TOKEN_UNDEFINED; } if (type === 'empty') { return TOKEN_EMPTY_STRING; } throw new TypeError('The item is alien!'); })(ast); verbose && console.log('Ending parser'); // If debug, return a internal representation of dictionary and stuff if (options.debug) return { dictionary : dictionary, ast : ast, packed : packed }; return packed; }; var unpack = function(packed, options) { // Canonizes the options options = options || {}; // A raw buffer var rawBuffers = packed.split('^'); // Create a dictionary options.verbose && console.log('Building dictionary'); var dictionary = []; // Add the strings values var buffer = rawBuffers[0]; if (buffer !== '') { buffer = buffer.split('|'); options.verbose && console.log('Parse the strings dictionary'); for (var i=0, n=buffer.length; i<n; i++){ dictionary.push(_decode(buffer[i])); } } // Add the integers values buffer = rawBuffers[1]; if (buffer !== '') { buffer = buffer.split('|'); options.verbose && console.log('Parse the integers dictionary'); for (var i=0, n=buffer.length; i<n; i++){ dictionary.push(_base36To10(buffer[i])); } } // Add the floats values buffer = rawBuffers[2]; if (buffer !== '') { buffer = buffer.split('|'); options.verbose && console.log('Parse the floats dictionary'); for (var i=0, n=buffer.length; i<n; i++){ dictionary.push(parseFloat(buffer[i])); } } // Free memory buffer = null; options.verbose && console.log('Tokenizing the structure'); // Tokenizer the structure var number36 = ''; var tokens = []; var len=rawBuffers[3].length; for (var i = 0; i < len; i++) { var symbol = rawBuffers[3].charAt(i); if (symbol === '|' || symbol === '$' || symbol === '@' || symbol === ']') { if (number36) { tokens.push(_base36To10(number36)); number36 = ''; } symbol !== '|' && tokens.push(symbol); } else { number36 += symbol; } } // A shorthand proxy for tokens.length var tokensLength = tokens.length; // The index of the next token to read var tokensIndex = 0; options.verbose && console.log('Starting recursive parser'); return (function recursiveUnpackerParser() { // Maybe '$' (object) or '@' (array) var type = tokens[tokensIndex++]; options.verbose && console.log('Reading collection type ' + (type === '$' ? 'object' : 'Array')); // Parse an array if (type === '@') { var node = []; for (; tokensIndex < tokensLength; tokensIndex++) { var value = tokens[tokensIndex]; options.verbose && console.log('Read ' + value + ' symbol'); if (value === ']') return node; if (value === '@' || value === '$') { node.push(recursiveUnpackerParser()); } else { switch(value) { case TOKEN_TRUE: node.push(true); break; case TOKEN_FALSE: node.push(false); break; case TOKEN_NULL: node.push(null); break; case TOKEN_UNDEFINED: node.push(undefined); break; case TOKEN_EMPTY_STRING: node.push(''); break; default: node.push(dictionary[value]); } } } options.verbose && console.log('Parsed ' + this.JSON.stringify(node)); return node; } // Parse a object if (type === '$') { var node = {}; for (; tokensIndex < tokensLength; tokensIndex++) { var key = tokens[tokensIndex]; if (key === ']') return node; if (key === TOKEN_EMPTY_STRING) key = ''; else key = dictionary[key]; var value = tokens[++tokensIndex]; if (value === '@' || value === '$') { node[key] = recursiveUnpackerParser(); } else { switch(value) { case TOKEN_TRUE: node[key] = true; break; case TOKEN_FALSE: node[key] = false; break; case TOKEN_NULL: node[key] = null; break; case TOKEN_UNDEFINED: node[key] = undefined; break; case TOKEN_EMPTY_STRING: node[key] = ''; break; default: node[key] = dictionary[value]; } } } options.verbose && console.log('Parsed ' + this.JSON.stringify(node)); return node; } throw new TypeError('Bad token ' + type + ' isn\'t a type'); })(); }; var _encode = function(str) { if ( typeof str !== 'string') return str; return str.replace(/[\+ \|\^\%]/g, function(a) { return ({ ' ' : '+', '+' : '%2B', '|' : '%7C', '^' : '%5E', '%' : '%25' })[a] }); }; var _decode = function(str) { if ( typeof str !== 'string') return str; return str.replace(/\+|%2B|%7C|%5E|%25/g, function(a) { return ({ '+' : ' ', '%2B' : '+', '%7C' : '|', '%5E' : '^', '%25' : '%' })[a] }) }; var _base10To36 = function(number) { return Number.prototype.toString.call(number, 36).toUpperCase(); }; var _base36To10 = function(number) { return parseInt(number, 36); }; var _indexOf = Array.prototype.indexOf || function(obj, start) { for (var i = (start || 0), j = this.length; i < j; i++) { if (this[i] === obj) { return i; } } return -1; }; return { JSON : JSON, pack : pack, unpack : unpack }; }); })( function(deps, factory) { var jsonpack = factory(); for (var key in jsonpack) exports[key] = jsonpack[key]; } ); } (main)); return main; } var mainExports = requireMain(); /** * @this {Promise} */ function finallyConstructor(callback) { var constructor = this.constructor; return this.then( function(value) { // @ts-ignore return constructor.resolve(callback()).then(function() { return value; }); }, function(reason) { // @ts-ignore return constructor.resolve(callback()).then(function() { // @ts-ignore return constructor.reject(reason); }); } ); } function allSettled(arr) { var P = this; return new P(function(resolve, reject) { if (!(arr && typeof arr.length !== 'undefined')) { return reject( new TypeError( typeof arr + ' ' + arr + ' is not iterable(cannot read property Symbol(Symbol.iterator))' ) ); } var args = Array.prototype.slice.call(arr); if (args.length === 0) return resolve([]); var remaining = args.length; function res(i, val) { if (val && (typeof val === 'object' || typeof val === 'function')) { var then = val.then; if (typeof then === 'function') { then.call( val, function(val) { res(i, val); }, function(e) { args[i] = { status: 'rejected', reason: e }; if (--remaining === 0) { resolve(args); } } ); return; } } args[i] = { status: 'fulfilled', value: val }; if (--remaining === 0) { resolve(args); } } for (var i = 0; i < args.length; i++) { res(i, args[i]); } }); } /** * @constructor */ function AggregateError(errors, message) { (this.name = 'AggregateError'), (this.errors = errors); this.message = message || ''; } AggregateError.prototype = Error.prototype; function any(arr) { var P = this; return new P(function(resolve, reject) { if (!(arr && typeof arr.length !== 'undefined')) { return reject(new TypeError('Promise.any accepts an array')); } var args = Array.prototype.slice.call(arr); if (args.length === 0) return reject(); var rejectionReasons = []; for (var i = 0; i < args.length; i++) { try { P.resolve(args[i]) .then(resolve) .catch(function(error) { rejectionReasons.push(error); if (rejectionReasons.length === args.length) { reject( new AggregateError( rejectionReasons, 'All promises were rejected' ) ); } }); } catch (ex) { reject(ex); } } }); } // Store setTimeout reference so promise-polyfill will be unaffected by // other code modifying setTimeout (like sinon.useFakeTimers()) var setTimeoutFunc = setTimeout; function isArray(x) { return Boolean(x && typeof x.length !== 'undefined'); } function noop() {} // Polyfill for Function.prototype.bind function bind(fn, thisArg) { return function() { fn.apply(thisArg, arguments); }; } /** * @constructor * @param {Function} fn */ function Promise$1(fn) { if (!(this instanceof Promise$1)) throw new TypeError('Promises must be constructed via new'); if (typeof fn !== 'function') throw new TypeError('not a function'); /** @type {!number} */ this._state = 0; /** @type {!boolean} */ this._handled = false; /** @type {Promise|undefined} */ this._value = undefined; /** @type {!Array<!Function>} */ this._deferreds = []; doResolve(fn, this); } function handle(self, deferred) { while (self._state === 3) { self = self._value; } if (self._state === 0) { self._deferreds.push(deferred); return; } self._handled = true; Promise$1._immediateFn(function() { var cb = self._state === 1 ? deferred.onFulfilled : deferred.onRejected; if (cb === null) { (self._state === 1 ? resolve : reject)(deferred.promise, self._value); return; } var ret; try { ret = cb(self._value); } catch (e) { reject(deferred.promise, e); return; } resolve(deferred.promise, ret); }); } function resolve(self, newValue) { try { // Promise Resolution Procedure: https://github.com/promises-aplus/promises-spec#the-promise-resolution-procedure if (newValue === self) throw new TypeError('A promise cannot be resolved with itself.'); if ( newValue && (typeof newValue === 'object' || typeof newValue === 'function') ) { var then = newValue.then; if (newValue instanceof Promise$1) { self._state = 3; self._value = newValue; finale(self); return; } else if (typeof then === 'function') { doResolve(bind(then, newValue), self); return; } } self._state = 1; self._value = newValue; finale(self); } catch (e) { reject(self, e); } } function reject(self, newValue) { self._state = 2; self._value = newValue; finale(self); } function finale(self) { if (self._state === 2 && self._deferreds.length === 0) { Promise$1._immediateFn(function() { if (!self._handled) { Promise$1._unhandledRejectionFn(self._value); } }); } for (var i = 0, len = self._deferreds.length; i < len; i++) { handle(self, self._deferreds[i]); } self._deferreds = null; } /** * @constructor */ function Handler(onFulfilled, onRejected, promise) { this.onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : null; this.onRejected = typeof onRejected === 'function' ? onRejected : null; this.promise = promise; } /** * Take a potentially misbehaving resolver function and make sure * onFulfilled and onRejected are only called once. * * Makes no guarantees about asynchrony. */ function doResolve(fn, self) { var done = false; try { fn( function(value) { if (done) return; done = true; resolve(self, value); }, function(reason) { if (done) return; done = true; reject(self, reason); } ); } catch (ex) { if (done) return; done = true; reject(self, ex); } } Promise$1.prototype['catch'] = function(onRejected) { return this.then(null, onRejected); }; Promise$1.prototype.then = function(onFulfilled, onRejected) { // @ts-ignore var prom = new this.constructor(noop); handle(this, new Handler(onFulfilled, onRejected, prom)); return prom; }; Promise$1.prototype['finally'] = finallyConstructor; Promise$1.all = function(arr) { return new Promise$1(function(resolve, reject) { if (!isArray(arr)) { return reject(new TypeError('Promise.all accepts an array')); } var args = Array.prototype.slice.call(arr); if (args.length === 0) return resolve([]); var remaining = args.length; function res(i, val) { try { if (val && (typeof val === 'object' || typeof val === 'function')) { var then = val.then; if (typeof then === 'function') { then.call( val, function(val) { res(i, val); }, reject ); return; } } args[i] = val; if (--remaining === 0) { resolve(args); } } catch (ex) { reject(ex); } } for (var i = 0; i < args.length; i++) { res(i, args[i]); } }); }; Promise$1.any = any; Promise$1.allSettled = allSettled; Promise$1.resolve = function(value) { if (value && typeof value === 'object' && value.constructor === Promise$1) { return value; } return new Promise$1(function(resolve) { resolve(value); }); }; Promise$1.reject = function(value) { return new Promise$1(function(resolve, reject) { reject(value); }); }; Promise$1.race = function(arr) { return new Promise$1(function(resolve, reject) { if (!isArray(arr)) { return reject(new TypeError('Promise.race accepts an array')); } for (var i = 0, len = arr.length; i < len; i++) { Promise$1.resolve(arr[i]).then(resolve, reject); } }); }; // Use polyfill for setImmediate for performance gains Promise$1._immediateFn = // @ts-ignore (typeof setImmediate === 'function' && function(fn) { // @ts-ignore setImmediate(fn); }) || function(fn) { setTimeoutFunc(fn, 0); }; Promise$1._unhandledRejectionFn = function _unhandledRejectionFn(err) { if (typeof console !== 'undefined' && console) { console.warn('Possible Unhandled Promise Rejection:', err); // eslint-disable-line no-console } }; /** @suppress {undefinedVars} */ var globalNS = (function() { // the only reliable means to get the global object is // `Function('return this')()` // However, this causes CSP violations in Chrome apps. if (typeof self !== 'undefined') { return self; } if (typeof window !== 'undefined') { return window; } if (typeof global !== 'undefined') { return global; } throw new Error('unable to locate global object'); })(); // Expose the polyfill if Promise is undefined or set to a // non-function value. The latter can be due to a named HTMLElement // being exposed by browsers for legacy reasons. // https://github.com/taylorhakes/promise-polyfill/issues/114 if (typeof globalNS['Promise'] !== 'function') { globalNS['Promise'] = Promise$1; } else { if (!globalNS.Promise.prototype['finally']) { globalNS.Promise.prototype['finally'] = finallyConstructor; } if (!globalNS.Promise.allSettled) { globalNS.Promise.allSettled = allSettled; } if (!globalNS.Promise.any) { globalNS.Promise.any = any; } } function sortObject(obj) { if (typeof obj !== 'object') { return obj; } var temp = {}; var keys = []; for (var key in obj) { keys.push(key); } keys.sort(); for (var index in keys) { temp[keys[index]] = sortObject(obj[keys[index]]); } return temp; } function copyTextToClipboard(text) { var textArea = document.createElement('textarea'); textArea.value = text; document.body.appendChild(textArea); textArea.select(); try { var successful = document.execCommand('copy'); var msg = successful ? 'successful' : 'unsuccessful'; console.log('Copying text command was ' + msg); } catch (err) { console.log('Oops, unable to copy'); } document.body.removeChild(textArea); } function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || false, o.configurable = true, "value" in o && (o.writable = true), Object.defineProperty(e, _toPropertyKey(o.key), o); } } function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), Object.defineProperty(e, "prototype", { writable: false }), e; } function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); } function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return (String )(t); } function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; } var Chart$2 = {exports: {}}; function commonjsRequire(path) { throw new Error('Could not dynamically require "' + path + '". Please configure the dynamicRequireTargets or/and ignoreDynamicRequires option of @rollup/plugin-commonjs appropriately for this require call to work.'); } var moment$1 = {exports: {}}; var moment = moment$1.exports; var hasRequiredMoment; function requireMoment () { if (hasRequiredMoment) return moment$1.exports; hasRequiredMoment = 1; (function (module, exports) { (function (global, factory) { module.exports = factory() ; }(moment, (function () { var hookCallback; function hooks() { return hookCallback.apply(null, arguments); } // This is done to register the method called with moment() // without creating circular dependencies. function setHookCallback(callback) { hookCallback = callback; } function isArray(input) { return ( input instanceof Array || Object.prototype.toString.call(input) === '[object Array]' ); } function isObject(input) { // IE8 will treat undefined and null as object if it wasn't for // input != null return ( input != null && Object.prototype.toString.call(input) === '[object Object]' ); } function hasOwnProp(a, b) { return Object.prototype.hasOwnProperty.call(a, b); } function isObjectEmpty(obj) { if (Object.getOwnPropertyNames) { return Object.getOwnPropertyNames(obj).length === 0; } else { var k; for (k in obj) { if (hasOwnProp(obj, k)) { return false; } } return true; } } function isUndefined(input) { return input === void 0; } function isNumber(input) { return ( typeof input === 'number' || Object.prototype.toString.call(input) === '[object Number]' ); } function isDate(input) { return ( input instanceof Date || Object.prototype.toString.call(input) === '[object Date]' ); } function map(arr, fn) { var res = [], i, arrLen = arr.length; for (i = 0; i < arrLen; ++i) { res.push(fn(arr[i], i)); } return res; } function extend(a, b) { for (var i in b) { if (hasOwnProp(b, i)) { a[i] = b[i]; } } if (hasOwnProp(b, 'toString')) { a.toString = b.toString; } if (hasOwnProp(b, 'valueOf')) { a.valueOf = b.valueOf; } return a; } function createUTC(input, format, locale, strict) { return createLocalOrUTC(input, format, locale, strict, true).utc(); } function defaultParsingFlags() { // We need to deep clone this object. return { empty: false, unusedTokens: [], unusedInput: [], overflow: -2, charsLeftOver: 0, nullInput: false, invalidEra: null, invalidMonth: null, invalidFormat: false, userInvalidated: false, iso: false, parsedDateParts: [], era: null, meridiem: null, rfc2822: false, weekdayMismatch: false, }; } function getParsingFlags(m) { if (m._pf == null) { m._pf = defaultParsingFlags(); } return m._pf; } var some; if (Array.prototype.some) { some = Array.prototype.some; } else { some = function (fun) { var t = Object(this), len = t.length >>> 0, i; for (i = 0; i < len; i++) { if (i in t && fun.call(this, t[i], i, t)) { return true; } } return false; }; } function isValid(m) { if (m._isValid == null) { var flags = getParsingFlags(m), parsedParts = some.call(flags.parsedDateParts, function (i) { return i != null; }), isNowValid = !isNaN(m._d.getTime()) && flags.overflow < 0 && !flags.empty && !flags.invalidEra && !flags.invalidMonth && !flags.invalidWeekday && !flags.weekdayMismatch && !flags.nullInput && !flags.invalidFormat && !flags.userInvalidated && (!flags.meridiem || (flags.meridiem && parsedParts)); if (m._strict) { isNowValid = isNowValid && flags.charsLeftOver === 0 && flags.unusedTokens.length === 0 && flags.bigHour === undefined; } if (Object.isFrozen == null || !Object.isFrozen(m)) { m._isValid = isNowValid; } else { return isNowValid; } } return m._isValid; } function createInvalid(flags) { var m = createUTC(NaN); if (flags != null) { extend(getParsingFlags(m), flags); } else { getParsingFlags(m).userInvalidated = true; } return m; } // Plugins that add properties should also add the key here (null value), // so we can properly clone ourselves. var momentProperties = (hooks.momentProperties = []), updateInProgress = false; function copyConfig(to, from) { var i, prop, val, momentPropertiesLen = momentProperties.length; if (!isUndefined(from._isAMomentObject)) { to._isAMomentObject = from._isAMomentObject; } if (!isUndefined(from._i)) { to._i = from._i; } if (!isUndefined(from._f)) { to._f = from._f; } if (!isUndefined(from._l)) { to._l = from._l; } if (!isUndefined(from._strict)) { to._strict = from._strict; } if (!isUndefined(from._tzm)) { to._tzm = from._tzm; } if (!isUndefined(from._isUTC)) { to._isUTC = from._isUTC; } if (!isUndefined(from._offset)) { to._offset = from._offset; } if (!isUndefined(from._pf)) { to._pf = getParsingFlags(from); } if (!isUndefined(from._locale)) { to._locale = from._locale; } if (momentPropertiesLen > 0) { for (i = 0; i < momentPropertiesLen; i++) { prop = momentProperties[i]; val = from[prop]; if (!isUndefined(val)) { to[prop] = val; } } } return to; } // Moment prototype object function Moment(config) { copyConfig(this, config); this._d = new Date(config._d != null ? config._d.getTime() : NaN); if (!this.isValid()) { this._d = new Date(NaN); } // Prevent infinite loop in case updateOffset creates new moment // objects. if (updateInProgress === false) { updateInProgress = true; hooks.updateOffset(this); updateInProgress = false; } } function isMoment(obj) { return ( obj instanceof Moment || (obj != null && obj._isAMomentObject != null) ); } function warn(msg) { if ( hooks.suppressDeprecationWarnings === false && typeof console !== 'undefined' && console.warn ) { console.warn('Deprecation warning: ' + msg); } } function deprecate(msg, fn) { var firstTime = true; return extend(function () { if (hooks.deprecationHandler != null) { hooks.deprecationHandler(null, msg); } if (firstTime) { var args = [], arg, i, key, argLen = arguments.length; for (i = 0; i < argLen; i++) { arg = ''; if (typeof arguments[i] === 'object') { arg += '\n[' + i + '] '; for (key in arguments[0]) { if (hasOwnProp(arguments[0], key)) { arg += key + ': ' + arguments[0][key] + ', '; } } arg = arg.slice(0, -2); // Remove trailing comma and space } else { arg = arguments[i]; } args.push(arg); } warn( msg + '\nArguments: ' + Array.prototype.slice.call(args).join('') + '\n' + new Error().stack ); firstTime = false; } return fn.apply(this, arguments); }, fn); } var deprecations = {}; function deprecateSimple(name, msg) { if (hooks.deprecationHandler != null) { hooks.deprecationHandler(name, msg); } if (!deprecations[name]) { warn(msg); deprecations[name] = true; } } hooks.suppressDeprecationWarnings = false; hooks.deprecationHandler = null; function isFunction(input) { return ( (typeof Function !== 'undefined' && input instanceof Function) || Object.prototype.toString.call(input) === '[object Function]' ); } function set(config) { var prop, i; for (i in config) { if (hasOwnProp(config, i)) { prop = config[i]; if (isFunction(prop)) { this[i] = prop; } else { this['_' + i] = prop; } } } this._config = config; // Lenient ordinal parsing accepts just a number in addition to // number + (possibly) stuff coming from _dayOfMonthOrdinalParse. // TODO: Remove "ordinalParse" fallback in next major release. this._dayOfMonthOrdinalParseLenient = new RegExp( (this._dayOfMonthOrdinalParse.source || this._ordinalParse.source) + '|' + /\d{1,2}/.source ); } function mergeConfigs(parentConfig, childConfig) { var res = extend({}, parentConfig), prop; for (prop in childConfig) { if (hasOwnProp(childConfig, prop)) { if (isObject(parentConfig[prop]) && isObject(childConfig[prop])) { res[prop] = {}; extend(res[prop], parentConfig[prop]); extend(res[prop], childConfig[prop]); } else if (childConfig[prop] != null) { res[prop] = childConfig[prop]; } else { delete res[prop]; } } } for (prop in parentConfig) { if ( hasOwnProp(parentConfig, prop) && !hasOwnProp(childConfig, prop) && isObject(parentConfig[prop]) ) { // make sure changes to properties don't modify parent config res[prop] = extend({}, res[prop]); } } return res; } function Locale(config) { if (config != null) { this.set(config); } } var keys; if (Object.keys) { keys = Object.keys; } else { keys = function (obj) { var i, res = []; for (i in obj) { if (hasOwnProp(obj, i)) { res.push(i); } } return res; }; } var defaultCalendar = { sameDay: '[Today at] LT', nextDay: '[Tomorrow at] LT', nextWeek: 'dddd [at] LT', lastDay: '[Yesterday at] LT', lastWeek: '[Last] dddd [at] LT', sameElse: 'L', };