UNPKG

le-player

Version:

The best HTML5 video player made for Lectoriy.

644 lines (553 loc) 56.3 kB
/******/ (function(modules) { // webpackBootstrap /******/ // The module cache /******/ var installedModules = {}; /******/ /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ /******/ // Check if module is in cache /******/ if(installedModules[moduleId]) /******/ return installedModules[moduleId].exports; /******/ /******/ // Create a new module (and put it into the cache) /******/ var module = installedModules[moduleId] = { /******/ exports: {}, /******/ id: moduleId, /******/ loaded: false /******/ }; /******/ /******/ // Execute the module function /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); /******/ /******/ // Flag the module as loaded /******/ module.loaded = true; /******/ /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ /******/ /******/ // expose the modules object (__webpack_modules__) /******/ __webpack_require__.m = modules; /******/ /******/ // expose the module cache /******/ __webpack_require__.c = installedModules; /******/ /******/ // __webpack_public_path__ /******/ __webpack_require__.p = "/dist/js/"; /******/ /******/ // Load entry module and return exports /******/ return __webpack_require__(0); /******/ }) /************************************************************************/ /******/ ({ /***/ 0: /***/ (function(module, exports, __webpack_require__) { module.exports = __webpack_require__(72); /***/ }), /***/ 2: /***/ (function(module, exports) { module.exports = $; /***/ }), /***/ 72: /***/ (function(module, exports, __webpack_require__) { 'use strict'; var _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; }; }(); var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; var _set = function set(object, property, value, receiver) { var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent !== null) { set(parent, property, value, receiver); } } else if ("value" in desc && desc.writable) { desc.value = value; } else { var setter = desc.set; if (setter !== undefined) { setter.call(receiver, value); } } return value; }; var _jquery = __webpack_require__(2); var _jquery2 = _interopRequireDefault(_jquery); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _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; } function _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; } var Player = window.lePlayer || window.$.lePlayer; var Entity = Player.getComponent('Entity'); var trackProvide = function trackProvide(track) { if (track == null || track.languageCode == null) { return track; } return { language: track.languageCode, title: track.languageCode, tooltip: track.languageName, name: track.languageCode }; }; var Youtube = function (_Entity) { _inherits(Youtube, _Entity); function Youtube(player, options) { _classCallCheck(this, Youtube); var _this = _possibleConstructorReturn(this, (Youtube.__proto__ || Object.getPrototypeOf(Youtube)).call(this, player, options)); _this._paused = true; _this.src = _this.player.options.src; _this.player.addClass('leplayer--youtube'); _this.element.on('click', _this.onClick.bind(_this)); _this.element.on('dblclick', _this.onDblclick.bind(_this)); return _this; } /** * @override */ _createClass(Youtube, [{ key: 'onClick', value: function onClick(event) { this.trigger('click'); } }, { key: 'onDblclick', value: function onDblclick() { this.trigger('dblclick'); } }, { key: 'increaseRate', /** * @override */ value: function increaseRate() { var index = this.availableRates.indexOf(this.rate); if (index + 1 >= this.availableRates.length) return; return this.rate = this.availableRates[index + 1]; } /** * @override */ }, { key: 'decreaseRate', value: function decreaseRate() { var index = this.availableRates.indexOf(this.rate); if (index - 1 < 0) return; return this.rate = this.availableRates[index - 1]; } }, { key: 'getAvailableQualityLevels', value: function getAvailableQualityLevels() { var arr = this.ytPlayer.getAvailableQualityLevels(); var index = arr.indexOf('auto'); if (index > -1) { arr.splice(index, 1); } return arr.map(function (item) { return { title: Youtube.QUALITY_NAMES[item] || item, name: item }; }); } }, { key: 'supportsFullScreen', value: function supportsFullScreen() { return true; } }, { key: 'play', value: function play() { this.ytPlayer.playVideo(); this.trigger('play'); } }, { key: 'pause', value: function pause() { this.ytPlayer.pauseVideo(); this.trigger('pause'); } }, { key: 'init', value: function init() { var _this2 = this; _get(Youtube.prototype.__proto__ || Object.getPrototypeOf(Youtube.prototype), 'init', this).call(this); return Youtube.apiLoaded().then(function () { return _this2.initYTPlayer(); }); } }, { key: 'createElement', value: function createElement() { this.element = (0, _jquery2.default)('<div />').addClass('leplayer__youtube-wrapper').attr('tabindex', '0'); this.youtubeElement = (0, _jquery2.default)('<div />').addClass('leplayer__youtube'); this.blocker = (0, _jquery2.default)('<div />').addClass('leplayer__youtube-blocker'); return this.element.append(this.blocker).append(this.youtubeElement); } }, { key: 'initYTPlayer', value: function initYTPlayer() { var _this3 = this; this._initPromise = _jquery2.default.Deferred(); var globalOptions = this.player.options; var ytOptions = { autoplay: globalOptions.autoplay ? 1 : 0, loop: globalOptions.loop ? 1 : 0, iv_load_policy: 3, controls: 0, modestbranding: 1, rel: 0, showinfo: 0, cc_load_policy: 0, disablekb: 0, fs: 0, start: globalOptions.time }; YT.ready(function () { _this3.options.ctx.replaceWith(_this3.element); _this3.ytPlayer = new YT.Player(_this3.youtubeElement[0], { videoId: _this3.videoId, width: globalOptions.width || '100%', playerVars: ytOptions, events: { onReady: _this3.onYTPReady.bind(_this3), onStateChange: _this3.onYTPStateChange.bind(_this3), onPlaybackRateChange: _this3.onYTPRateChange.bind(_this3), onPlaybackQualityChange: _this3.onYTPPlaybackQualityChange.bind(_this3) } }); }); return this._initPromise.promise(); } }, { key: 'setAvailablePlaybackRates', value: function setAvailablePlaybackRates() { this.availableRates = this.ytPlayer.getAvailablePlaybackRates(); this.rateMin = this.availableRates[0]; this.rateMax = this.availableRates[this.availableRates.length - 1]; } }, { key: 'onYTPReady', value: function onYTPReady(e) { this._initPromise.resolve(); this._initRate(); this._initVolume(); this.setAvailablePlaybackRates(); } }, { key: 'onYTPRateChange', value: function onYTPRateChange(e) { this.trigger('ratechange'); } }, { key: 'onYTPPlaybackQualityChange', value: function onYTPPlaybackQualityChange(e) { var data = e.data; this._playbackQuality = this.getAvailableQualityLevels().find(function (item) { return item.name === data; }); this.trigger('qualitychange', this._playbackQuality); } }, { key: 'onYTPStateChange', value: function onYTPStateChange(e) { var state = e.data; if (state === this.lastState) { return; } this.lastState = state; switch (state) { case YT.PlayerState.UNSTARTED: this.trigger('loadstart'); this.trigger('loadedmetadata'); this.trigger('durationchange'); this.trigger('ratechange'); this.trigger('volumechange'); this.trigger('trackschange'); if (this.player.options.autoplay) { this.trigger('play'); } break; case YT.PlayerState.ENDED: this.trigger('pause'); this.trigger('ended'); break; case YT.PlayerState.PLAYING: this.trigger('timeupdate'); this.trigger('durationchange'); this.trigger('playing'); this.ytPlayer.setPlaybackQuality(this._nextPlaybackQuality); if (this.isSeeking) { this.onSeeked(); } this.loadCaptions(); this.emitTimeupdate(); break; case YT.PlayerState.PAUSED: this.trigger('canplay'); if (this.isSeeking) { this.onSeeked(); } break; case YT.PlayerState.BUFFERING: this.player.trigger('timeupdate'); this.player.trigger('waiting'); this.ytPlayer.setPlaybackQuality(this._nextPlaybackQuality); break; } } }, { key: 'onSeeked', value: function onSeeked() { clearInterval(this.seekingInterval); this.isSeeking = false; if (this.wasPausedBeforeSeek) { this.pause(); } this.trigger('seeked'); } }, { key: 'emitTimeupdate', value: function emitTimeupdate() { var _this4 = this; clearInterval(this.seekingInterval); this.seekingInterval = setInterval(function () { if (_this4.lastState === YT.PlayerState.PAUSED) { clearInterval(_this4.seekingInterval); } else if (_this4.currentTime !== _this4.timeBeforeSeek) { _this4.trigger('timeupdate'); } }, 250); } }, { key: 'loadCaptions', value: function loadCaptions() { var _this5 = this; var emptyTracklist = function emptyTracklist() { return _this5.subtitles == null || _this5.subtitles.length === 0; }; clearInterval(this._loadCaptionsWatcher); if (!this._tracksDisable && this.checkCaptionsExist() && emptyTracklist()) { this.ytPlayer.loadModule('captions'); this._loadCaptionsWatcher = setInterval(function () { if (!emptyTracklist() && _this5.checkCaptionsExist()) { _this5.trigger('trackschange'); clearInterval(_this5._loadCaptionsWatcher); } }, 250); } } }, { key: 'checkCaptionsExist', value: function checkCaptionsExist() { try { return this.ytPlayer.getOptions('captions') != null; } catch (error) { return false; } } }, { key: 'src', set: function set(src) { if (src == null) return; if (this.src && this.src.url === src.url) return; var url = src.url || src.id; this.videoId = Youtube.parseUrl(url); if (this.player.options.poster) { this.poster = this.player.options.poster; } else { this.poster = 'https://img.youtube.com/vi/' + this.videoId + '/0.jpg'; } } }, { key: 'currentTime', get: function get() { return this.ytPlayer ? this.ytPlayer.getCurrentTime() : 0; }, set: function set(value) { if (this.lastState === YT.PlayerState.PAUSED) { this.timeBeforeSeek = this.currentTime; } if (!this.isSeeking) { this.wasPausedBeforeSeek = this.paused; } var time = void 0; if (value >= this.duration) { time = this.duration; } else if (value < 0) { time = 0; } else { time = value; } this.isSeeking = true; this.ytPlayer.seekTo(time, true); this.player.trigger('timeupdateload', { currentTime: time }); this.trigger('seeking'); this.emitTimeupdate(); } }, { key: 'duration', get: function get() { return this.ytPlayer && this.ytPlayer.getDuration ? this.ytPlayer.getDuration() : NaN; } }, { key: 'paused', get: function get() { return this.ytPlayer ? this.lastState !== YT.PlayerState.PLAYING && this.lastState !== YT.PlayerState.BUFFERING : true; } }, { key: 'rate', get: function get() { return this.ytPlayer.getPlaybackRate(); }, set: function set(value) { _set(Youtube.prototype.__proto__ || Object.getPrototypeOf(Youtube.prototype), 'rate', value, this); this.ytPlayer.setPlaybackRate(value); this.trigger('ratechange'); } }, { key: 'muted', set: function set(value) { var _this6 = this; if (value) { this.ytPlayer.mute(); } else { this.ytPlayer.unMute(); } setTimeout(function () { _this6.trigger('volumechange'); }, 50); }, get: function get() { return this.ytPlayer.isMuted(); } }, { key: 'subtitles', get: function get() { return this.checkCaptionsExist() ? (this.ytPlayer.getOption('captions', 'tracklist') || []).map(trackProvide) : []; } }, { key: 'track', get: function get() { if (this._track === undefined && this.checkCaptionsExist()) { return trackProvide(this.ytPlayer.getOption('captions', 'track')); } else { return this._track; } }, set: function set(value) { this._track = value; if (value === null) { this._tracksDisable = true; /* Disable captions */ this.ytPlayer.unloadModule('captions'); this.trigger('trackschange'); return; } this.ytPlayer.setOption('captions', 'track', { languageCode: value.name }).setOption('captions', 'reload', true); if (this._tracksDisable) { /* Enable captions */ this.ytPlayer.loadModule('captions'); } this.trigger('trackschange'); } }, { key: 'playbackQuality', set: function set(name) { _set(Youtube.prototype.__proto__ || Object.getPrototypeOf(Youtube.prototype), 'playbackQuality', name, this); var time = this.currentTime; var status = this.ytPlayer.getPlayerState(); if (status !== YT.PlayerState.UNSTARTED && status !== YT.PlayerState.CUED) { this.ytPlayer.pauseVideo(); } this._nextPlaybackQuality = name; this.ytPlayer.setPlaybackQuality(name); this.ytPlayer.seekTo(time); if (status !== YT.PlayerState.PAUSED) { this.ytPlayer.playVideo(); } }, get: function get() { var _this7 = this; if (this._playbackQuality == null) { this._playbackQuality = this.getAvailableQualityLevels().find(function (item) { return item.name === _this7.ytPlayer.getPlaybackQuality(); }); } return this._playbackQuality; } }, { key: 'volume', get: function get() { return this.ytPlayer ? this.ytPlayer.getVolume() / 100.0 : 1; }, set: function set(value) { var _this8 = this; _set(Youtube.prototype.__proto__ || Object.getPrototypeOf(Youtube.prototype), 'volume', value, this); this.ytPlayer.setVolume(value * 100); setTimeout(function () { _this8.trigger('volumechange'); }, 50); } }], [{ key: 'parseUrl', value: function parseUrl(url) { var result = null; var regex = Youtube.URL_REGEX; var match = url.match(regex); if (url.length === 11) { result = url; } else if (match && match[2].length === 11) { result = match[2]; } return result; } }]); return Youtube; }(Entity); Youtube.TEST_VIDEO = document.createElement('video'); /** * @return {boolean} * - True if volume can be controlled * - False otherwise */ Youtube.canControlVolume = function () { // IE will error if Windows Media Player not installed #3315 try { var volume = Youtube.TEST_VIDEO.volume; Youtube.TEST_VIDEO.volume = volume / 2 + 0.1; return volume !== Youtube.TEST_VIDEO.volume; } catch (e) { return false; } }; Youtube.prototype.featureControlVolume = Youtube.canControlVolume(); Youtube.URL_REGEX = /^.*(youtu.be\/|v\/|u\/\w\/|embed\/|watch\?v=|\&v=)([^#\&\?]*).*/; Youtube.QUALITY_NAMES = { tiny: '140p', small: '240p', medium: '360p', large: '480p', hd720: '720p', hd1080: '1080p', highres: 'HD', auto: 'Авто' }; Youtube.apiLoaded = function () { var _this9 = this; if (this._loaded) return _jquery2.default.Deferred().resolve(); return _jquery2.default.getScript('https://www.youtube.com/iframe_api').then(function () { return _this9._loaded = true; }); }; Player.registerComponent('Youtube', Youtube); Player.preset('youtube', { options: { entity: 'Youtube', controls: { common: [['play', 'volume', 'timeline', 'rate', 'backward', 'source', 'subtitle', 'divider', 'section', 'fullscreen'], []], fullscreen: [['play', 'volume', 'timeline', 'rate', 'backward', 'source', 'subtitle', 'divider', 'section', 'fullscreen']] } } }); Player.preset('youtube-2035', { options: { entity: 'Youtube', controls: { common: [['play', 'volume', 'timeline', 'rate', 'backward', 'section', 'fullscreen']], fullscreen: [['play', 'volume', 'timeline', 'rate', 'backward', 'section', 'fullscreen']], mini: [['play', 'timeline', 'volume', 'fullscreen']] } } }); Player.plugin('youtube', function (pluginOptions) { /* global YT */ Youtube.apiLoaded(); }); /***/ }) /******/ }); //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vd2VicGFjay9ib290c3RyYXAgMGY5MzEzNjliZTUwMjljZDRlOGQ/ZDZkMSoqKiIsIndlYnBhY2s6Ly8vZXh0ZXJuYWwgXCIkXCI/NTdhYSoqKiIsIndlYnBhY2s6Ly8vLi9zb3VyY2UvanMvcGx1Z2lucy9sZS1wbGF5ZXIteW91dHViZS5qcz8xMmNjIl0sIm5hbWVzIjpbIlBsYXllciIsIndpbmRvdyIsImxlUGxheWVyIiwiJCIsIkVudGl0eSIsImdldENvbXBvbmVudCIsInRyYWNrUHJvdmlkZSIsInRyYWNrIiwibGFuZ3VhZ2VDb2RlIiwibGFuZ3VhZ2UiLCJ0aXRsZSIsInRvb2x0aXAiLCJsYW5ndWFnZU5hbWUiLCJuYW1lIiwiWW91dHViZSIsInBsYXllciIsIm9wdGlvbnMiLCJfcGF1c2VkIiwic3JjIiwiYWRkQ2xhc3MiLCJlbGVtZW50Iiwib24iLCJvbkNsaWNrIiwiYmluZCIsIm9uRGJsY2xpY2siLCJldmVudCIsInRyaWdnZXIiLCJpbmRleCIsImF2YWlsYWJsZVJhdGVzIiwiaW5kZXhPZiIsInJhdGUiLCJsZW5ndGgiLCJhcnIiLCJ5dFBsYXllciIsImdldEF2YWlsYWJsZVF1YWxpdHlMZXZlbHMiLCJzcGxpY2UiLCJtYXAiLCJRVUFMSVRZX05BTUVTIiwiaXRlbSIsInBsYXlWaWRlbyIsInBhdXNlVmlkZW8iLCJhcGlMb2FkZWQiLCJ0aGVuIiwiaW5pdFlUUGxheWVyIiwiYXR0ciIsInlvdXR1YmVFbGVtZW50IiwiYmxvY2tlciIsImFwcGVuZCIsIl9pbml0UHJvbWlzZSIsIkRlZmVycmVkIiwiZ2xvYmFsT3B0aW9ucyIsInl0T3B0aW9ucyIsImF1dG9wbGF5IiwibG9vcCIsIml2X2xvYWRfcG9saWN5IiwiY29udHJvbHMiLCJtb2Rlc3RicmFuZGluZyIsInJlbCIsInNob3dpbmZvIiwiY2NfbG9hZF9wb2xpY3kiLCJkaXNhYmxla2IiLCJmcyIsInN0YXJ0IiwidGltZSIsIllUIiwicmVhZHkiLCJjdHgiLCJyZXBsYWNlV2l0aCIsInZpZGVvSWQiLCJ3aWR0aCIsInBsYXllclZhcnMiLCJldmVudHMiLCJvblJlYWR5Iiwib25ZVFBSZWFkeSIsIm9uU3RhdGVDaGFuZ2UiLCJvbllUUFN0YXRlQ2hhbmdlIiwib25QbGF5YmFja1JhdGVDaGFuZ2UiLCJvbllUUFJhdGVDaGFuZ2UiLCJvblBsYXliYWNrUXVhbGl0eUNoYW5nZSIsIm9uWVRQUGxheWJhY2tRdWFsaXR5Q2hhbmdlIiwicHJvbWlzZSIsImdldEF2YWlsYWJsZVBsYXliYWNrUmF0ZXMiLCJyYXRlTWluIiwicmF0ZU1heCIsImUiLCJyZXNvbHZlIiwiX2luaXRSYXRlIiwiX2luaXRWb2x1bWUiLCJzZXRBdmFpbGFibGVQbGF5YmFja1JhdGVzIiwiZGF0YSIsIl9wbGF5YmFja1F1YWxpdHkiLCJmaW5kIiwic3RhdGUiLCJsYXN0U3RhdGUiLCJQbGF5ZXJTdGF0ZSIsIlVOU1RBUlRFRCIsIkVOREVEIiwiUExBWUlORyIsInNldFBsYXliYWNrUXVhbGl0eSIsIl9uZXh0UGxheWJhY2tRdWFsaXR5IiwiaXNTZWVraW5nIiwib25TZWVrZWQiLCJsb2FkQ2FwdGlvbnMiLCJlbWl0VGltZXVwZGF0ZSIsIlBBVVNFRCIsIkJVRkZFUklORyIsImNsZWFySW50ZXJ2YWwiLCJzZWVraW5nSW50ZXJ2YWwiLCJ3YXNQYXVzZWRCZWZvcmVTZWVrIiwicGF1c2UiLCJzZXRJbnRlcnZhbCIsImN1cnJlbnRUaW1lIiwidGltZUJlZm9yZVNlZWsiLCJlbXB0eVRyYWNrbGlzdCIsInN1YnRpdGxlcyIsIl9sb2FkQ2FwdGlvbnNXYXRjaGVyIiwiX3RyYWNrc0Rpc2FibGUiLCJjaGVja0NhcHRpb25zRXhpc3QiLCJsb2FkTW9kdWxlIiwiZ2V0T3B0aW9ucyIsImVycm9yIiwidXJsIiwiaWQiLCJwYXJzZVVybCIsInBvc3RlciIsImdldEN1cnJlbnRUaW1lIiwidmFsdWUiLCJwYXVzZWQiLCJkdXJhdGlvbiIsInNlZWtUbyIsImdldER1cmF0aW9uIiwiTmFOIiwiZ2V0UGxheWJhY2tSYXRlIiwic2V0UGxheWJhY2tSYXRlIiwibXV0ZSIsInVuTXV0ZSIsInNldFRpbWVvdXQiLCJpc011dGVkIiwiZ2V0T3B0aW9uIiwiX3RyYWNrIiwidW5kZWZpbmVkIiwidW5sb2FkTW9kdWxlIiwic2V0T3B0aW9uIiwic3RhdHVzIiwiZ2V0UGxheWVyU3RhdGUiLCJDVUVEIiwiZ2V0UGxheWJhY2tRdWFsaXR5IiwiZ2V0Vm9sdW1lIiwic2V0Vm9sdW1lIiwicmVzdWx0IiwicmVnZXgiLCJVUkxfUkVHRVgiLCJtYXRjaCIsIlRFU1RfVklERU8iLCJkb2N1bWVudCIsImNyZWF0ZUVsZW1lbnQiLCJjYW5Db250cm9sVm9sdW1lIiwidm9sdW1lIiwicHJvdG90eXBlIiwiZmVhdHVyZUNvbnRyb2xWb2x1bWUiLCJ0aW55Iiwic21hbGwiLCJtZWRpdW0iLCJsYXJnZSIsImhkNzIwIiwiaGQxMDgwIiwiaGlnaHJlcyIsImF1dG8iLCJfbG9hZGVkIiwiZ2V0U2NyaXB0IiwicmVnaXN0ZXJDb21wb25lbnQiLCJwcmVzZXQiLCJlbnRpdHkiLCJjb21tb24iLCJmdWxsc2NyZWVuIiwibWluaSIsInBsdWdpbiIsInBsdWdpbk9wdGlvbnMiXSwibWFwcGluZ3MiOiI7QUFBQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSx1QkFBZTtBQUNmO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOzs7QUFHQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOzs7Ozs7Ozs7Ozs7Ozs7O0FDdENBLG9COzs7Ozs7O0FDQUE7Ozs7Ozs7O0FBRUE7Ozs7Ozs7Ozs7OztBQUVBLEtBQU1BLFNBQVNDLE9BQU9DLFFBQVAsSUFBbUJELE9BQU9FLENBQVAsQ0FBU0QsUUFBM0M7QUFDQSxLQUFNRSxTQUFTSixPQUFPSyxZQUFQLENBQW9CLFFBQXBCLENBQWY7O0FBRUEsS0FBTUMsZUFBZSxTQUFmQSxZQUFlLFFBQVM7QUFDN0IsTUFBSUMsU0FBUyxJQUFU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RUFBUyxVQUFULEVBQXFCLFFBQXJCLEVBQStCLFlBQS9CLENBRFk7QUFQSDtBQUZGO0FBRG1CLEVBQTlCOztBQWlCQS9LLFFBQU9nTCxNQUFQLENBQWMsU0FBZCxFQUF5QixVQUFVQyxhQUFWLEVBQXlCOztBQUVqRDtBQUNBbkssVUFBUTJCLFNBQVI7QUFDQSxFQUpELEUiLCJmaWxlIjoibGUtcGxheWVyLXlvdXR1YmUuanMiLCJzb3VyY2VzQ29udGVudCI6WyIgXHQvLyBUaGUgbW9kdWxlIGNhY2hlXG4gXHR2YXIgaW5zdGFsbGVkTW9kdWxlcyA9IHt9O1xuXG4gXHQvLyBUaGUgcmVxdWlyZSBmdW5jdGlvblxuIFx0ZnVuY3Rpb24gX193ZWJwYWNrX3JlcXVpcmVfXyhtb2R1bGVJZCkge1xuXG4gXHRcdC8vIENoZWNrIGlmIG1vZHVsZSBpcyBpbiBjYWNoZVxuIFx0XHRpZihpbnN0YWxsZWRNb2R1bGVzW21vZHVsZUlkXSlcbiBcdFx0XHRyZXR1cm4gaW5zdGFsbGVkTW9kdWxlc1ttb2R1bGVJZF0uZXhwb3J0cztcblxuIFx0XHQvLyBDcmVhdGUgYSBuZXcgbW9kdWxlIChhbmQgcHV0IGl0IGludG8gdGhlIGNhY2hlKVxuIFx0XHR2YXIgbW9kdWxlID0gaW5zdGFsbGVkTW9kdWxlc1ttb2R1bGVJZF0gPSB7XG4gXHRcdFx0ZXhwb3J0czoge30sXG4gXHRcdFx0aWQ6IG1vZHVsZUlkLFxuIFx0XHRcdGxvYWRlZDogZmFsc2VcbiBcdFx0fTtcblxuIFx0XHQvLyBFeGVjdXRlIHRoZSBtb2R1bGUgZnVuY3Rpb25cbiBcdFx0bW9kdWxlc1ttb2R1bGVJZF0uY2FsbChtb2R1bGUuZXhwb3J0cywgbW9kdWxlLCBtb2R1bGUuZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXyk7XG5cbiBcdFx0Ly8gRmxhZyB0aGUgbW9kdWxlIGFzIGxvYWRlZFxuIFx0XHRtb2R1bGUubG9hZGVkID0gdHJ1ZTtcblxuIFx0XHQvLyBSZXR1cm4gdGhlIGV4cG9ydHMgb2YgdGhlIG1vZHVsZVxuIFx0XHRyZXR1cm4gbW9kdWxlLmV4cG9ydHM7XG4gXHR9XG5cblxuIFx0Ly8gZXhwb3NlIHRoZSBtb2R1bGVzIG9iamVjdCAoX193ZWJwYWNrX21vZHVsZXNfXylcbiBcdF9fd2VicGFja19yZXF1aXJlX18ubSA9IG1vZHVsZXM7XG5cbiBcdC8vIGV4cG9zZSB0aGUgbW9kdWxlIGNhY2hlXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLmMgPSBpbnN0YWxsZWRNb2R1bGVzO1xuXG4gXHQvLyBfX3dlYnBhY2tfcHVibGljX3BhdGhfX1xuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5wID0gXCIvZGlzdC9qcy9cIjtcblxuIFx0Ly8gTG9hZCBlbnRyeSBtb2R1bGUgYW5kIHJldHVybiBleHBvcnRzXG4gXHRyZXR1cm4gX193ZWJwYWNrX3JlcXVpcmVfXygwKTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyB3ZWJwYWNrL2Jvb3RzdHJhcCAwZjkzMTM2OWJlNTAyOWNkNGU4ZCIsIm1vZHVsZS5leHBvcnRzID0gJDtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyBleHRlcm5hbCBcIiRcIlxuLy8gbW9kdWxlIGlkID0gMlxuLy8gbW9kdWxlIGNodW5rcyA9IDAgMSAyIDMgNCIsIid1c2Ugc3RyaWN0JztcblxuaW1wb3J0ICQgZnJvbSAnanF1ZXJ5JztcblxuY29uc3QgUGxheWVyID0gd2luZG93LmxlUGxheWVyIHx8IHdpbmRvdy4kLmxlUGxheWVyO1xuY29uc3QgRW50aXR5ID0gUGxheWVyLmdldENvbXBvbmVudCgnRW50aXR5Jyk7XG5cbmNvbnN0IHRyYWNrUHJvdmlkZSA9IHRyYWNrID0+IHtcblx0aWYgKHRyYWNrID09IG51bGwgfHwgdHJhY2subGFuZ3VhZ2VDb2RlID09IG51bGwpIHtcblx0XHRyZXR1cm4gdHJhY2tcblx0fVxuXHRyZXR1cm4ge1xuXHRcdGxhbmd1YWdlIDogdHJhY2subGFuZ3VhZ2VDb2RlLFxuXHRcdHRpdGxlICAgIDogdHJhY2subGFuZ3VhZ2VDb2RlLFxuXHRcdHRvb2x0aXAgIDogdHJhY2subGFuZ3VhZ2VOYW1lLFxuXHRcdG5hbWUgICAgIDogdHJhY2subGFuZ3VhZ2VDb2RlLFxuXHR9XG59XG5cbmNsYXNzIFlvdXR1YmUgZXh0ZW5kcyBFbnRpdHkge1xuXHRjb25zdHJ1Y3RvciAocGxheWVyLCBvcHRpb25zKSB7XG5cdFx0c3VwZXIocGxheWVyLCBvcHRpb25zKTtcblx0XHR0aGlzLl9wYXVzZWQgPSB0cnVlO1xuXG5cdFx0dGhpcy5zcmMgPSB0aGlzLnBsYXllci5vcHRpb25zLnNyYztcblxuXHRcdHRoaXMucGxheWVyLmFkZENsYXNzKCdsZXBsYXllci0teW91dHViZScpO1xuXHRcdHRoaXMuZWxlbWVudC5vbignY2xpY2snLCB0aGlzLm9uQ2xpY2suYmluZCh0aGlzKSk7XG5cdFx0dGhpcy5lbGVtZW50Lm9uKCdkYmxjbGljaycsIHRoaXMub25EYmxjbGljay5iaW5kKHRoaXMpKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBAb3ZlcnJpZGVcblx0ICovXG5cdHNldCBzcmMgKHNyYykge1xuXHRcdGlmIChzcmMgPT0gbnVsbCkgcmV0dXJuO1xuXHRcdGlmICh0aGlzLnNyYyAmJiB0aGlzLnNyYy51cmwgPT09IHNyYy51cmwpIHJldHVybjtcblxuXHRcdGNvbnN0IHVybCA9IHNyYy51cmwgfHwgc3JjLmlkO1xuXG5cdFx0dGhpcy52aWRlb0lkID0gWW91dHViZS5wYXJzZVVybCh1cmwpO1xuXG5cdFx0aWYgKHRoaXMucGxheWVyLm9wdGlvbnMucG9zdGVyKSB7XG5cdFx0XHR0aGlzLnBvc3RlciA9IHRoaXMucGxheWVyLm9wdGlvbnMucG9zdGVyXG5cdFx0fSBlbHNlIHtcblx0XHRcdHRoaXMucG9zdGVyID0gJ2h0dHBzOi8vaW1nLnlvdXR1YmUuY29tL3ZpLycgKyB0aGlzLnZpZGVvSWQgKyAnLzAuanBnJztcblx0XHR9XG5cdH1cblxuXHRvbkNsaWNrIChldmVudCkge1xuXHRcdHRoaXMudHJpZ2dlcignY2xpY2snKTtcblx0fVxuXG5cdG9uRGJsY2xpY2sgKCkge1xuXHRcdHRoaXMudHJpZ2dlcignZGJsY2xpY2snKTtcblx0fVxuXG5cdGdldCBjdXJyZW50VGltZSAoKSB7XG5cdFx0cmV0dXJuIHRoaXMueXRQbGF5ZXIgPyB0aGlzLnl0UGxheWVyLmdldEN1cnJlbnRUaW1lKCkgOiAwO1xuXHR9XG5cblx0c2V0IGN1cnJlbnRUaW1lICh2YWx1ZSkge1xuXHRcdGlmICh0aGlzLmxhc3RTdGF0ZSA9PT0gWVQuUGxheWVyU3RhdGUuUEFVU0VEKSB7XG5cdFx0XHR0aGlzLnRpbWVCZWZvcmVTZWVrID0gdGhpcy5jdXJyZW50VGltZTtcblx0XHR9XG5cblx0XHRpZiAoIXRoaXMuaXNTZWVraW5nKSB7XG5cdFx0XHR0aGlzLndhc1BhdXNlZEJlZm9yZVNlZWsgPSB0aGlzLnBhdXNlZDtcblx0XHR9XG5cblx0XHRsZXQgdGltZTtcblx0XHRpZiAodmFsdWUgPj0gdGhpcy5kdXJhdGlvbikge1xuXHRcdFx0dGltZSA9IHRoaXMuZHVyYXRpb25cblx0XHR9IGVsc2UgaWYgKHZhbHVlIDwgMCkge1xuXHRcdFx0dGltZSA9IDBcblx0XHR9IGVsc2Uge1xuXHRcdFx0dGltZSA9IHZhbHVlO1xuXHRcdH1cblxuXHRcdHRoaXMuaXNTZWVraW5nID0gdHJ1ZTtcblx0XHR0aGlzLnl0UGxheWVyLnNlZWtUbyh0aW1lLCB0cnVlKTtcblx0XHR0aGlzLnBsYXllci50cmlnZ2VyKCd0aW1ldXBkYXRlbG9hZCcsIHsgY3VycmVudFRpbWUgOiB0aW1lIH0pO1xuXG5cdFx0dGhpcy50cmlnZ2VyKCdzZWVraW5nJyk7XG5cblx0XHR0aGlzLmVtaXRUaW1ldXBkYXRlKCk7XG5cdH1cblxuXHRnZXQgZHVyYXRpb24gKCkge1xuXHRcdHJldHVybiB0aGlzLnl0UGxheWVyICYmIHRoaXMueXRQbGF5ZXIuZ2V0RHVyYXRpb24gPyB0aGlzLnl0UGxheWVyLmdldER1cmF0aW9uKCkgOiBOYU47XG5cdH1cblxuXHRnZXQgcGF1c2VkICgpIHtcblx0XHRyZXR1cm4gKHRoaXMueXRQbGF5ZXIpID9cblx0XHRcdCh0aGlzLmxhc3RTdGF0ZSAhPT0gWVQuUGxheWVyU3RhdGUuUExBWUlORyAmJiB0aGlzLmxhc3RTdGF0ZSAhPT0gWVQuUGxheWVyU3RhdGUuQlVGRkVSSU5HKVxuXHRcdFx0OiB0cnVlO1xuXG5cdH1cblxuXHRnZXQgcmF0ZSAoKSB7XG5cdFx0cmV0dXJuIHRoaXMueXRQbGF5ZXIuZ2V0UGxheWJhY2tSYXRlKCk7XG5cdH1cblxuXHRzZXQgcmF0ZSAodmFsdWUpIHtcblx0XHRzdXBlci5yYXRlID0gdmFsdWU7XG5cdFx0dGhpcy55dFBsYXllci5zZXRQbGF5YmFja1JhdGUodmFsdWUpO1xuXHRcdHRoaXMudHJpZ2dlcigncmF0ZWNoYW5nZScpO1xuXHR9XG5cblx0c2V0IG11dGVkICh2YWx1ZSkge1xuXHRcdGlmICh2YWx1ZSkge1xuXHRcdFx0dGhpcy55dFBsYXllci5tdXRlKCk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdHRoaXMueXRQbGF5ZXIudW5NdXRlKCk7XG5cdFx0fVxuXG5cdFx0c2V0VGltZW91dCgoKSA9PiB7XG5cdFx0XHR0aGlzLnRyaWdnZXIoJ3ZvbHVtZWNoYW5nZScpO1xuXHRcdH0sIDUwKTtcblx0fVxuXG5cdGdldCBtdXRlZCAoKSB7XG5cdFx0cmV0dXJuIHRoaXMueXRQbGF5ZXIuaXNNdXRlZCgpO1xuXHR9XG5cblx0Z2V0IHN1YnRpdGxlcyAoKSB7XG5cdFx0cmV0dXJuIHRoaXMuY2hlY2tDYXB0aW9uc0V4aXN0KClcblx0XHRcdD8gKHRoaXMueXRQbGF5ZXIuZ2V0T3B0aW9uKCdjYXB0aW9ucycsICd0cmFja2xpc3QnKSB8fCBbXSkubWFwKHRyYWNrUHJvdmlkZSlcblx0XHRcdDogW11cblx0fVxuXG5cdGdldCB0cmFjayAoKSB7XG5cdFx0aWYgKHRoaXMuX3RyYWNrID09PSB1bmRlZmluZWQgJiYgdGhpcy5jaGVja0NhcHRpb25zRXhpc3QoKSkge1xuXHRcdFx0cmV0dXJuIHRyYWNrUHJvdmlkZSh0aGlzLnl0UGxheWVyLmdldE9wdGlvbignY2FwdGlvbnMnLCAndHJhY2snKSlcblx0XHR9IGVsc2Uge1xuXHRcdFx0cmV0dXJuIHRoaXMuX3RyYWNrO1xuXHRcdH1cblx0fVxuXG5cdHNldCB0cmFjayAodmFsdWUpIHtcblx0XHR0aGlzLl90cmFjayA9IHZhbHVlO1xuXHRcdGlmICh2YWx1ZSA9PT0gbnVsbCkge1xuXHRcdFx0dGhpcy5fdHJhY2tzRGlzYWJsZSA9IHRydWU7XG5cdFx0XHQvKiBEaXNhYmxlIGNhcHRpb25zICovXG5cdFx0XHR0aGlzLnl0UGxheWVyLnVubG9hZE1vZHVsZSgnY2FwdGlvbnMnKTtcblxuXHRcdFx0dGhpcy50cmlnZ2VyKCd0cmFja3NjaGFuZ2UnKTtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cdFx0dGhpcy55dFBsYXllclxuXHRcdFx0LnNldE9wdGlvbignY2FwdGlvbnMnLCAndHJhY2snLCB7IGxhbmd1YWdlQ29kZSA6IHZhbHVlLm5hbWUgfSlcblx0XHRcdC5zZXRPcHRpb24oJ2NhcHRpb25zJywgJ3JlbG9hZCcsIHRydWUpO1xuXG5cdFx0aWYgKHRoaXMuX3RyYWNrc0Rpc2FibGUpIHtcblx0XHRcdC8qIEVuYWJsZSBjYXB0aW9ucyAqL1xuXHRcdFx0dGhpcy55dFBsYXllci5sb2FkTW9kdWxlKCdjYXB0aW9ucycpO1xuXHRcdH1cblx0XHR0aGlzLnRyaWdnZXIoJ3RyYWNrc2NoYW5nZScpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEBvdmVycmlkZVxuXHQgKi9cblx0aW5jcmVhc2VSYXRlICgpIHtcblx0XHRjb25zdCBpbmRleCA9IHRoaXMuYXZhaWxhYmxlUmF0ZXMuaW5kZXhPZih0aGlzLnJhdGUpO1xuXHRcdGlmIChpbmRleCArIDEgPj0gdGhpcy5hdmFpbGFibGVSYXRlcy5sZW5ndGgpIHJldHVybjtcblx0XHRyZXR1cm4gdGhpcy5yYXRlID0gdGhpcy5hdmFpbGFibGVSYXRlc1tpbmRleCArIDFdO1xuXHR9XG5cblx0LyoqXG5cdCAqIEBvdmVycmlkZVxuXHQgKi9cblx0ZGVjcmVhc2VSYXRlICgpIHtcblx0XHRjb25zdCBpbmRleCA9IHRoaXMuYXZhaWxhYmxlUmF0ZXMuaW5kZXhPZih0aGlzLnJhdGUpO1xuXHRcdGlmIChpbmRleCAtIDEgPCAwKSByZXR1cm47XG5cdFx0cmV0dXJuIHRoaXMucmF0ZSA9IHRoaXMuYXZhaWxhYmxlUmF0ZXNbaW5kZXggLSAxXTtcblx0fVxuXG5cdGdldEF2YWlsYWJsZVF1YWxpdHlMZXZlbHMgKCkge1xuXHRcdGNvbnN0IGFyciAgID0gdGhpcy55dFBsYXllci5nZXRBdmFpbGFibGVRdWFsaXR5TGV2ZWxzKCk7XG5cdFx0Y29uc3QgaW5kZXggPSBhcnIuaW5kZXhPZignYXV0bycpO1xuXG5cdFx0aWYgKGluZGV4ID4gLTEpIHtcblx0XHRcdGFyci5zcGxpY2UoaW5kZXgsIDEpO1xuXHRcdH1cblxuXHRcdHJldHVybiBhcnIubWFwKGl0ZW0gPT4gKHtcblx0XHRcdHRpdGxlIDogWW91dHViZS5RVUFMSVRZX05BTUVTW2l0ZW1dIHx8IGl0ZW0sXG5cdFx0XHRuYW1lICA6IGl0ZW1cblx0XHR9KSk7XG5cdH1cblxuXHRzZXQgcGxheWJhY2tRdWFsaXR5IChuYW1lKSB7XG5cdFx0c3VwZXIucGxheWJhY2tRdWFsaXR5ID0gbmFtZTtcblx0XHRjb25zdCB0aW1lICAgICAgICAgICAgPSB0aGlzLmN1cnJlbnRUaW1lO1xuXHRcdGNvbnN0IHN0YXR1cyAgICAgICAgICA9IHRoaXMueXRQbGF5ZXIuZ2V0UGxheWVyU3RhdGUoKTtcblxuXHRcdGlmIChzdGF0dXMgIT09IFlULlBsYXllclN0YXRlLlVOU1RBUlRFRCAmJiBzdGF0dXMgIT09IFlULlBsYXllclN0YXRlLkNVRUQpIHtcblx0XHRcdHRoaXMueXRQbGF5ZXIucGF1c2VWaWRlbygpO1xuXHRcdH1cblxuXHRcdHRoaXMuX25leHRQbGF5YmFja1F1YWxpdHkgPSBuYW1lO1xuXHRcdHRoaXMueXRQbGF5ZXIuc2V0UGxheWJhY2tRdWFsaXR5KG5hbWUpO1xuXHRcdHRoaXMueXRQbGF5ZXIuc2Vla1RvKHRpbWUpO1xuXG5cdFx0aWYgKHN0YXR1cyAhPT0gWVQuUGxheWVyU3RhdGUuUEFVU0VEKSB7XG5cdFx0XHR0aGlzLnl0UGxheWVyLnBsYXlWaWRlbygpO1xuXHRcdH1cblxuXHR9XG5cblx0Z2V0IHBsYXliYWNrUXVhbGl0eSAoKSB7XG5cdFx0aWYgKHRoaXMuX3BsYXliYWNrUXVhbGl0eSA9PSBudWxsKSB7XG5cdFx0XHR0aGlzLl9wbGF5YmFja1F1YWxpdHkgPSB0aGlzLmdldEF2YWlsYWJsZVF1YWxpdHlMZXZlbHMoKVxuXHRcdFx0XHQuZmluZChpdGVtID0+IGl0ZW0ubmFtZSA9PT0gdGhpcy55dFBsYXllci5nZXRQbGF5YmFja1F1YWxpdHkoKSlcblx0XHR9XG5cdFx0cmV0dXJuIHRoaXMuX3BsYXliYWNrUXVhbGl0eTtcblx0fVxuXG5cdGdldCB2b2x1bWUgKCkge1xuXHRcdHJldHVybiB0aGlzLnl0UGxheWVyID8gdGhpcy55dFBsYXllci5nZXRWb2x1bWUoKSAvIDEwMC4wIDogMTtcblx0fVxuXG5cdHNldCB2b2x1bWUgKHZhbHVlKSB7XG5cdFx0c3VwZXIudm9sdW1lID0gdmFsdWU7XG5cdFx0dGhpcy55dFBsYXllci5zZXRWb2x1bWUodmFsdWUgKiAxMDApO1xuXG5cdFx0c2V0VGltZW91dCgoKSA9PiB7XG5cdFx0XHR0aGlzLnRyaWdnZXIoJ3ZvbHVtZWNoYW5nZScpO1xuXHRcdH0sIDUwKVxuXG5cdH1cblxuXHRzdXBwb3J0c0Z1bGxTY3JlZW4gKCkge1xuXHRcdHJldHVybiB0cnVlO1xuXHR9XG5cblx0cGxheSAoKSB7XG5cdFx0dGhpcy55dFBsYXllci5wbGF5VmlkZW8oKTtcblx0XHR0aGlzLnRyaWdnZXIoJ3BsYXknKTtcblx0fVxuXG5cdHBhdXNlICgpIHtcblx0XHR0aGlzLnl0UGxheWVyLnBhdXNlVmlkZW8oKTtcblx0XHR0aGlzLnRyaWdnZXIoJ3BhdXNlJyk7XG5cdH1cblxuXHRpbml0ICgpIHtcblx0XHRzdXBlci5pbml0KCk7XG5cdFx0cmV0dXJuIFlvdXR1YmUuYXBpTG9hZGVkKClcblx0XHRcdC50aGVuKCgpID0+IHRoaXMuaW5pdFlUUGxheWVyKCkpXG5cdH1cblxuXHRjcmVhdGVFbGVtZW50ICgpIHtcblx0XHR0aGlzLmVsZW1lbnQgICAgICAgID0gJCgnPGRpdiAvPicpXG5cdFx0XHQuYWRkQ2xhc3MoJ2xlcGxheWVyX195b3V0dWJlLXdyYXBwZXInKVxuXHRcdFx0LmF0dHIoJ3RhYmluZGV4JywgJzAnKTtcblx0XHR0aGlzLnlvdXR1YmVFbGVtZW50ID0gJCgnPGRpdiAvPicpXG5cdFx0XHQuYWRkQ2xhc3MoJ2xlcGxheWVyX195b3V0dWJlJyk7XG5cdFx0dGhpcy5ibG9ja2VyICAgICAgICA9ICQoJzxkaXYgLz4nKVxuXHRcdFx0LmFkZENsYXNzKCdsZXBsYXllcl9feW91dHViZS1ibG9ja2VyJyk7XG5cblx0XHRyZXR1cm4gdGhpcy5lbGVtZW50XG5cdFx0XHQuYXBwZW5kKHRoaXMuYmxvY2tlcilcblx0XHRcdC5hcHBlbmQodGhpcy55b3V0dWJlRWxlbWVudCk7XG5cdH1cblxuXHRpbml0WVRQbGF5ZXIgKCkge1xuXHRcdHRoaXMuX2luaXRQcm9taXNlICAgPSAkLkRlZmVycmVkKCk7XG5cdFx0Y29uc3QgZ2xvYmFsT3B0aW9ucyA9IHRoaXMucGxheWVyLm9wdGlvbnM7XG5cdFx0bGV0IHl0T3B0aW9ucyAgICAgICA9IHtcblx0XHRcdGF1dG9wbGF5ICAgICAgIDogZ2xvYmFsT3B0aW9ucy5hdXRvcGxheSA/IDEgOiAwLFxuXHRcdFx0bG9vcCAgICAgICAgICAgOiBnbG9iYWxPcHRpb25zLmxvb3AgPyAxIDogMCxcblx0XHRcdGl2X2xvYWRfcG9saWN5IDogMyxcblx0XHRcdGNvbnRyb2xzICAgICAgIDogMCxcblx0XHRcdG1vZGVzdGJyYW5kaW5nIDogMSxcblx0XHRcdHJlbCAgICAgICAgICAgIDogMCxcblx0XHRcdHNob3dpbmZvICAgICAgIDogMCxcblx0XHRcdGNjX2xvYWRfcG9saWN5IDogMCxcblx0XHRcdGRpc2FibGVrYiAgICAgIDogMCxcblx0XHRcdGZzICAgICAgICAgICAgIDogMCxcblx0XHRcdHN0YXJ0ICAgICAgICAgIDogZ2xvYmFsT3B0aW9ucy50aW1lXG5cdFx0fTtcblxuXHRcdFlULnJlYWR5KCgpID0+IHtcblx0XHRcdHRoaXMub3B0aW9ucy5jdHgucmVwbGFjZVdpdGgodGhpcy5lbGVtZW50KTtcblxuXHRcdFx0dGhpcy55dFBsYXllciA9IG5ldyBZVC5QbGF5ZXIodGhpcy55b3V0dWJlRWxlbWVudFswXSwge1xuXHRcdFx0XHR2aWRlb0lkICAgIDogdGhpcy52aWRlb0lkLFxuXHRcdFx0XHR3aWR0aCAgICAgIDogZ2xvYmFsT3B0aW9ucy53aWR0aCB8fCAnMTAwJScsXG5cdFx0XHRcdHBsYXllclZhcnMgOiB5dE9wdGlvbnMsXG5cdFx0XHRcdGV2ZW50cyAgICAgOiB7XG5cdFx0XHRcdFx0b25SZWFkeSAgICAgICAgICAgICAgICAgOiB0aGlzLm9uWVRQUmVhZHkuYmluZCh0aGlzKSxcblx0XHRcdFx0XHRvblN0YXRlQ2hhbmdlICAgICAgICAgICA6IHRoaXMub25ZVFBTdGF0ZUNoYW5nZS5iaW5kKHRoaXMpLFxuXHRcdFx0XHRcdG9uUGxheWJhY2tSYXRlQ2hhbmdlICAgIDogdGhpcy5vbllUUFJhdGVDaGFuZ2UuYmluZCh0aGlzKSxcblx0XHRcdFx0XHRvblBsYXliYWNrUXVhbGl0eUNoYW5nZSA6IHRoaXMub25ZVFBQbGF5YmFja1F1YWxpdHlDaGFuZ2UuYmluZCh0aGlzKVxuXHRcdFx0XHR9XG5cdFx0XHR9KVxuXG5cdFx0fSlcblx0XHRyZXR1cm4gdGhpcy5faW5pdFByb21pc2UucHJvbWlzZSgpO1xuXHR9XG5cblx0c2V0QXZhaWxhYmxlUGxheWJhY2tSYXRlcyAoKSB7XG5cdFx0dGhpcy5hdmFpbGFibGVSYXRlcyA9IHRoaXMueXRQbGF5ZXIuZ2V0QXZhaWxhYmxlUGxheWJhY2tSYXRlcygpO1xuXHRcdHRoaXMucmF0ZU1pbiAgICAgICAgPSB0aGlzLmF2YWlsYWJsZVJhdGVzWzBdO1xuXHRcdHRoaXMucmF0ZU1heCAgICAgICAgPSB0aGlzLmF2YWlsYWJsZVJhdGVzW3RoaXMuYXZhaWxhYmxlUmF0ZXMubGVuZ3RoIC0gMV07XG5cdH1cblxuXHRvbllUUFJlYWR5IChlKSB7XG5cdFx0dGhpcy5faW5pdFByb21pc2UucmVzb2x2ZSgpO1xuXHRcdHRoaXMuX2luaXRSYXRlKCk7XG5cdFx0dGhpcy5faW5pdFZvbHVtZSgpO1xuXHRcdHRoaXMuc2V0QXZhaWxhYmxlUGxheWJhY2tSYXRlcygpO1xuXHR9XG5cblx0b25ZVFBSYXRlQ2hhbmdlIChlKSB7XG5cdFx0dGhpcy50cmlnZ2VyKCdyYXRlY2hhbmdlJyk7XG5cdH1cblxuXHRvbllUUFBsYXliYWNrUXVhbGl0eUNoYW5nZSAoZSkge1xuXHRcdGNvbnN0IGRhdGEgICAgICAgICAgICA9IGUuZGF0YTtcblx0XHR0aGlzLl9wbGF5YmFja1F1YWxpdHkgPSB0aGlzLmdldEF2YWlsYWJsZVF1YWxpdHlMZXZlbHMoKS5maW5kKGl0ZW0gPT4gaXRlbS5uYW1lID09PSBkYXRhKTtcblx0XHR0aGlzLnRyaWdnZXIoJ3F1YWxpdHljaGFuZ2UnLCB0aGlzLl9wbGF5YmFja1F1YWxpdHkpO1xuXHR9XG5cblx0b25ZVFBTdGF0ZUNoYW5nZSAoZSkge1xuXHRcdGNvbnN0IHN0YXRlID0gZS5kYXRhO1xuXHRcdGlmIChzdGF0ZSA9PT0gdGhpcy5sYXN0U3RhdGUpIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHR0aGlzLmxhc3RTdGF0ZSA9IHN0YXRlO1xuXHRcdHN3aXRjaCAoc3RhdGUpIHtcblx0XHRcdGNhc2UgWVQuUGxheWVyU3RhdGUuVU5TVEFSVEVEOlxuXHRcdFx0XHR0aGlzLnRyaWdnZXIoJ2xvYWRzdGFydCcpO1xuXHRcdFx0XHR0aGlzLnRyaWdnZXIoJ2xvYWRlZG1ldGFkYXRhJyk7XG5cdFx0XHRcdHRoaXMudHJpZ2dlcignZHVyYXRpb25jaGFuZ2UnKTtcblx0XHRcdFx0dGhpcy50cmlnZ2VyKCdyYXRlY2hhbmdlJyk7XG5cdFx0XHRcdHRoaXMudHJpZ2dlcigndm9sdW1lY2hhbmdlJyk7XG5cdFx