mirror of
https://github.com/DanielnetoDotCom/YouPHPTube
synced 2025-10-05 02:39:46 +02:00
1752 lines
195 KiB
JavaScript
1752 lines
195 KiB
JavaScript
(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
|
||
/*! npm.im/intervalometer */
|
||
'use strict';
|
||
|
||
Object.defineProperty(exports, '__esModule', { value: true });
|
||
|
||
function intervalometer(cb, request, cancel, requestParameter) {
|
||
var requestId;
|
||
var previousLoopTime;
|
||
function loop(now) {
|
||
// must be requested before cb() because that might call .stop()
|
||
requestId = request(loop, requestParameter);
|
||
|
||
// called with "ms since last call". 0 on start()
|
||
cb(now - (previousLoopTime || now));
|
||
|
||
previousLoopTime = now;
|
||
}
|
||
return {
|
||
start: function start() {
|
||
if (!requestId) { // prevent double starts
|
||
loop(0);
|
||
}
|
||
},
|
||
stop: function stop() {
|
||
cancel(requestId);
|
||
requestId = null;
|
||
previousLoopTime = 0;
|
||
}
|
||
};
|
||
}
|
||
|
||
function frameIntervalometer(cb) {
|
||
return intervalometer(cb, requestAnimationFrame, cancelAnimationFrame);
|
||
}
|
||
|
||
function timerIntervalometer(cb, delay) {
|
||
return intervalometer(cb, setTimeout, clearTimeout, delay);
|
||
}
|
||
|
||
exports.intervalometer = intervalometer;
|
||
exports.frameIntervalometer = frameIntervalometer;
|
||
exports.timerIntervalometer = timerIntervalometer;
|
||
},{}],2:[function(require,module,exports){
|
||
/*! npm.im/iphone-inline-video */
|
||
'use strict';
|
||
|
||
function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
|
||
|
||
var Symbol = _interopDefault(require('poor-mans-symbol'));
|
||
var intervalometer = require('intervalometer');
|
||
|
||
function preventEvent(element, eventName, toggleProperty, preventWithProperty) {
|
||
function handler(e) {
|
||
if (Boolean(element[toggleProperty]) === Boolean(preventWithProperty)) {
|
||
e.stopImmediatePropagation();
|
||
// console.log(eventName, 'prevented on', element);
|
||
}
|
||
delete element[toggleProperty];
|
||
}
|
||
element.addEventListener(eventName, handler, false);
|
||
|
||
// Return handler to allow to disable the prevention. Usage:
|
||
// const preventionHandler = preventEvent(el, 'click');
|
||
// el.removeEventHandler('click', preventionHandler);
|
||
return handler;
|
||
}
|
||
|
||
function proxyProperty(object, propertyName, sourceObject, copyFirst) {
|
||
function get() {
|
||
return sourceObject[propertyName];
|
||
}
|
||
function set(value) {
|
||
sourceObject[propertyName] = value;
|
||
}
|
||
|
||
if (copyFirst) {
|
||
set(object[propertyName]);
|
||
}
|
||
|
||
Object.defineProperty(object, propertyName, {get: get, set: set});
|
||
}
|
||
|
||
function proxyEvent(object, eventName, sourceObject) {
|
||
sourceObject.addEventListener(eventName, function () { return object.dispatchEvent(new Event(eventName)); });
|
||
}
|
||
|
||
function dispatchEventAsync(element, type) {
|
||
Promise.resolve().then(function () {
|
||
element.dispatchEvent(new Event(type));
|
||
});
|
||
}
|
||
|
||
// iOS 10 adds support for native inline playback + silent autoplay
|
||
var isWhitelisted = 'object-fit' in document.head.style && /iPhone|iPod/i.test(navigator.userAgent) && !matchMedia('(-webkit-video-playable-inline)').matches;
|
||
|
||
var ಠ = Symbol();
|
||
var ಠevent = Symbol();
|
||
var ಠplay = Symbol('nativeplay');
|
||
var ಠpause = Symbol('nativepause');
|
||
|
||
/**
|
||
* UTILS
|
||
*/
|
||
|
||
function getAudioFromVideo(video) {
|
||
var audio = new Audio();
|
||
proxyEvent(video, 'play', audio);
|
||
proxyEvent(video, 'playing', audio);
|
||
proxyEvent(video, 'pause', audio);
|
||
audio.crossOrigin = video.crossOrigin;
|
||
|
||
// 'data:' causes audio.networkState > 0
|
||
// which then allows to keep <audio> in a resumable playing state
|
||
// i.e. once you set a real src it will keep playing if it was if .play() was called
|
||
audio.src = video.src || video.currentSrc || 'data:';
|
||
|
||
// if (audio.src === 'data:') {
|
||
// TODO: wait for video to be selected
|
||
// }
|
||
return audio;
|
||
}
|
||
|
||
var lastRequests = [];
|
||
var requestIndex = 0;
|
||
var lastTimeupdateEvent;
|
||
|
||
function setTime(video, time, rememberOnly) {
|
||
// allow one timeupdate event every 200+ ms
|
||
if ((lastTimeupdateEvent || 0) + 200 < Date.now()) {
|
||
video[ಠevent] = true;
|
||
lastTimeupdateEvent = Date.now();
|
||
}
|
||
if (!rememberOnly) {
|
||
video.currentTime = time;
|
||
}
|
||
lastRequests[++requestIndex % 3] = time * 100 | 0 / 100;
|
||
}
|
||
|
||
function isPlayerEnded(player) {
|
||
return player.driver.currentTime >= player.video.duration;
|
||
}
|
||
|
||
function update(timeDiff) {
|
||
var player = this;
|
||
// console.log('update', player.video.readyState, player.video.networkState, player.driver.readyState, player.driver.networkState, player.driver.paused);
|
||
if (player.video.readyState >= player.video.HAVE_FUTURE_DATA) {
|
||
if (!player.hasAudio) {
|
||
player.driver.currentTime = player.video.currentTime + ((timeDiff * player.video.playbackRate) / 1000);
|
||
if (player.video.loop && isPlayerEnded(player)) {
|
||
player.driver.currentTime = 0;
|
||
}
|
||
}
|
||
setTime(player.video, player.driver.currentTime);
|
||
} else if (player.video.networkState === player.video.NETWORK_IDLE && !player.video.buffered.length) {
|
||
// this should happen when the source is available but:
|
||
// - it's potentially playing (.paused === false)
|
||
// - it's not ready to play
|
||
// - it's not loading
|
||
// If it hasAudio, that will be loaded in the 'emptied' handler below
|
||
player.video.load();
|
||
// console.log('Will load');
|
||
}
|
||
|
||
// console.assert(player.video.currentTime === player.driver.currentTime, 'Video not updating!');
|
||
|
||
if (player.video.ended) {
|
||
delete player.video[ಠevent]; // allow timeupdate event
|
||
player.video.pause(true);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* METHODS
|
||
*/
|
||
|
||
function play() {
|
||
// console.log('play');
|
||
var video = this;
|
||
var player = video[ಠ];
|
||
|
||
// if it's fullscreen, use the native player
|
||
if (video.webkitDisplayingFullscreen) {
|
||
video[ಠplay]();
|
||
return;
|
||
}
|
||
|
||
if (player.driver.src !== 'data:' && player.driver.src !== video.src) {
|
||
// console.log('src changed on play', video.src);
|
||
setTime(video, 0, true);
|
||
player.driver.src = video.src;
|
||
}
|
||
|
||
if (!video.paused) {
|
||
return;
|
||
}
|
||
player.paused = false;
|
||
|
||
if (!video.buffered.length) {
|
||
// .load() causes the emptied event
|
||
// the alternative is .play()+.pause() but that triggers play/pause events, even worse
|
||
// possibly the alternative is preventing this event only once
|
||
video.load();
|
||
}
|
||
|
||
player.driver.play();
|
||
player.updater.start();
|
||
|
||
if (!player.hasAudio) {
|
||
dispatchEventAsync(video, 'play');
|
||
if (player.video.readyState >= player.video.HAVE_ENOUGH_DATA) {
|
||
// console.log('onplay');
|
||
dispatchEventAsync(video, 'playing');
|
||
}
|
||
}
|
||
}
|
||
function pause(forceEvents) {
|
||
// console.log('pause');
|
||
var video = this;
|
||
var player = video[ಠ];
|
||
|
||
player.driver.pause();
|
||
player.updater.stop();
|
||
|
||
// if it's fullscreen, the developer the native player.pause()
|
||
// This is at the end of pause() because it also
|
||
// needs to make sure that the simulation is paused
|
||
if (video.webkitDisplayingFullscreen) {
|
||
video[ಠpause]();
|
||
}
|
||
|
||
if (player.paused && !forceEvents) {
|
||
return;
|
||
}
|
||
|
||
player.paused = true;
|
||
if (!player.hasAudio) {
|
||
dispatchEventAsync(video, 'pause');
|
||
}
|
||
if (video.ended) {
|
||
video[ಠevent] = true;
|
||
dispatchEventAsync(video, 'ended');
|
||
}
|
||
}
|
||
|
||
/**
|
||
* SETUP
|
||
*/
|
||
|
||
function addPlayer(video, hasAudio) {
|
||
var player = video[ಠ] = {};
|
||
player.paused = true; // track whether 'pause' events have been fired
|
||
player.hasAudio = hasAudio;
|
||
player.video = video;
|
||
player.updater = intervalometer.frameIntervalometer(update.bind(player));
|
||
|
||
if (hasAudio) {
|
||
player.driver = getAudioFromVideo(video);
|
||
} else {
|
||
video.addEventListener('canplay', function () {
|
||
if (!video.paused) {
|
||
// console.log('oncanplay');
|
||
dispatchEventAsync(video, 'playing');
|
||
}
|
||
});
|
||
player.driver = {
|
||
src: video.src || video.currentSrc || 'data:',
|
||
muted: true,
|
||
paused: true,
|
||
pause: function () {
|
||
player.driver.paused = true;
|
||
},
|
||
play: function () {
|
||
player.driver.paused = false;
|
||
// media automatically goes to 0 if .play() is called when it's done
|
||
if (isPlayerEnded(player)) {
|
||
setTime(video, 0);
|
||
}
|
||
},
|
||
get ended() {
|
||
return isPlayerEnded(player);
|
||
}
|
||
};
|
||
}
|
||
|
||
// .load() causes the emptied event
|
||
video.addEventListener('emptied', function () {
|
||
// console.log('driver src is', player.driver.src);
|
||
var wasEmpty = !player.driver.src || player.driver.src === 'data:';
|
||
if (player.driver.src && player.driver.src !== video.src) {
|
||
// console.log('src changed to', video.src);
|
||
setTime(video, 0, true);
|
||
player.driver.src = video.src;
|
||
// playing videos will only keep playing if no src was present when .play()’ed
|
||
if (wasEmpty) {
|
||
player.driver.play();
|
||
} else {
|
||
player.updater.stop();
|
||
}
|
||
}
|
||
}, false);
|
||
|
||
// stop programmatic player when OS takes over
|
||
video.addEventListener('webkitbeginfullscreen', function () {
|
||
if (!video.paused) {
|
||
// make sure that the <audio> and the syncer/updater are stopped
|
||
video.pause();
|
||
|
||
// play video natively
|
||
video[ಠplay]();
|
||
} else if (hasAudio && !player.driver.buffered.length) {
|
||
// if the first play is native,
|
||
// the <audio> needs to be buffered manually
|
||
// so when the fullscreen ends, it can be set to the same current time
|
||
player.driver.load();
|
||
}
|
||
});
|
||
if (hasAudio) {
|
||
video.addEventListener('webkitendfullscreen', function () {
|
||
// sync audio to new video position
|
||
player.driver.currentTime = video.currentTime;
|
||
// console.assert(player.driver.currentTime === video.currentTime, 'Audio not synced');
|
||
});
|
||
|
||
// allow seeking
|
||
video.addEventListener('seeking', function () {
|
||
if (lastRequests.indexOf(video.currentTime * 100 | 0 / 100) < 0) {
|
||
// console.log('User-requested seeking');
|
||
player.driver.currentTime = video.currentTime;
|
||
}
|
||
});
|
||
}
|
||
}
|
||
|
||
function overloadAPI(video) {
|
||
var player = video[ಠ];
|
||
video[ಠplay] = video.play;
|
||
video[ಠpause] = video.pause;
|
||
video.play = play;
|
||
video.pause = pause;
|
||
proxyProperty(video, 'paused', player.driver);
|
||
proxyProperty(video, 'muted', player.driver, true);
|
||
proxyProperty(video, 'playbackRate', player.driver, true);
|
||
proxyProperty(video, 'ended', player.driver);
|
||
proxyProperty(video, 'loop', player.driver, true);
|
||
preventEvent(video, 'seeking');
|
||
preventEvent(video, 'seeked');
|
||
preventEvent(video, 'timeupdate', ಠevent, false);
|
||
preventEvent(video, 'ended', ಠevent, false); // prevent occasional native ended events
|
||
}
|
||
|
||
function enableInlineVideo(video, hasAudio, onlyWhitelisted) {
|
||
if ( hasAudio === void 0 ) hasAudio = true;
|
||
if ( onlyWhitelisted === void 0 ) onlyWhitelisted = true;
|
||
|
||
if ((onlyWhitelisted && !isWhitelisted) || video[ಠ]) {
|
||
return;
|
||
}
|
||
addPlayer(video, hasAudio);
|
||
overloadAPI(video);
|
||
video.classList.add('IIV');
|
||
if (!hasAudio && video.autoplay) {
|
||
video.play();
|
||
}
|
||
if (!/iPhone|iPod|iPad/.test(navigator.platform)) {
|
||
console.warn('iphone-inline-video is not guaranteed to work in emulated environments');
|
||
}
|
||
}
|
||
|
||
enableInlineVideo.isWhitelisted = isWhitelisted;
|
||
|
||
module.exports = enableInlineVideo;
|
||
},{"intervalometer":1,"poor-mans-symbol":3}],3:[function(require,module,exports){
|
||
'use strict';
|
||
|
||
var index = typeof Symbol === 'undefined' ? function (description) {
|
||
return '@' + (description || '@') + Math.random();
|
||
} : Symbol;
|
||
|
||
module.exports = index;
|
||
},{}],4:[function(require,module,exports){
|
||
/**
|
||
*
|
||
* (c) Wensheng Yan <yanwsh@gmail.com>
|
||
* Date: 10/30/16
|
||
*
|
||
* For the full copyright and license information, please view the LICENSE
|
||
* file that was distributed with this source code.
|
||
*/
|
||
'use strict';
|
||
|
||
Object.defineProperty(exports, "__esModule", {
|
||
value: true
|
||
});
|
||
|
||
var _Detector = require('../lib/Detector');
|
||
|
||
var _Detector2 = _interopRequireDefault(_Detector);
|
||
|
||
var _MobileBuffering = require('../lib/MobileBuffering');
|
||
|
||
var _MobileBuffering2 = _interopRequireDefault(_MobileBuffering);
|
||
|
||
var _Util = require('../lib/Util');
|
||
|
||
var _Util2 = _interopRequireDefault(_Util);
|
||
|
||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||
|
||
var HAVE_CURRENT_DATA = 2;
|
||
|
||
var BaseCanvas = function BaseCanvas(baseComponent, THREE) {
|
||
var settings = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
||
|
||
return {
|
||
constructor: function init(player, options) {
|
||
this.settings = options;
|
||
//basic settings
|
||
this.width = player.el().offsetWidth, this.height = player.el().offsetHeight;
|
||
this.lon = options.initLon, this.lat = options.initLat, this.phi = 0, this.theta = 0;
|
||
this.videoType = options.videoType;
|
||
this.clickToToggle = options.clickToToggle;
|
||
this.mouseDown = false;
|
||
this.isUserInteracting = false;
|
||
|
||
//define render
|
||
this.renderer = new THREE.WebGLRenderer();
|
||
this.renderer.setPixelRatio(window.devicePixelRatio);
|
||
this.renderer.setSize(this.width, this.height);
|
||
this.renderer.autoClear = false;
|
||
this.renderer.setClearColor(0x000000, 1);
|
||
|
||
//define texture, on ie 11, we need additional helper canvas to solve rendering issue.
|
||
var video = settings.getTech(player);
|
||
this.supportVideoTexture = _Detector2.default.supportVideoTexture();
|
||
this.liveStreamOnSafari = _Detector2.default.isLiveStreamOnSafari(video);
|
||
if (this.liveStreamOnSafari) this.supportVideoTexture = false;
|
||
if (!this.supportVideoTexture) {
|
||
this.helperCanvas = player.addChild("HelperCanvas", {
|
||
video: video,
|
||
width: options.helperCanvas.width ? options.helperCanvas.width : this.width,
|
||
height: options.helperCanvas.height ? options.helperCanvas.height : this.height
|
||
});
|
||
var context = this.helperCanvas.el();
|
||
this.texture = new THREE.Texture(context);
|
||
} else {
|
||
this.texture = new THREE.Texture(video);
|
||
}
|
||
|
||
video.style.visibility = "hidden";
|
||
|
||
this.texture.generateMipmaps = false;
|
||
this.texture.minFilter = THREE.LinearFilter;
|
||
this.texture.maxFilter = THREE.LinearFilter;
|
||
this.texture.format = THREE.RGBFormat;
|
||
|
||
this.el_ = this.renderer.domElement;
|
||
this.el_.classList.add('vjs-video-canvas');
|
||
|
||
options.el = this.el_;
|
||
baseComponent.call(this, player, options);
|
||
|
||
this.attachControlEvents();
|
||
this.player().on("play", function () {
|
||
this.time = new Date().getTime();
|
||
this.startAnimation();
|
||
}.bind(this));
|
||
},
|
||
|
||
attachControlEvents: function attachControlEvents() {
|
||
this.on('mousemove', this.handleMouseMove.bind(this));
|
||
this.on('touchmove', this.handleTouchMove.bind(this));
|
||
this.on('mousedown', this.handleMouseDown.bind(this));
|
||
this.on('touchstart', this.handleTouchStart.bind(this));
|
||
this.on('mouseup', this.handleMouseUp.bind(this));
|
||
this.on('touchend', this.handleTouchEnd.bind(this));
|
||
if (this.settings.scrollable) {
|
||
this.on('mousewheel', this.handleMouseWheel.bind(this));
|
||
this.on('MozMousePixelScroll', this.handleMouseWheel.bind(this));
|
||
}
|
||
this.on('mouseenter', this.handleMouseEnter.bind(this));
|
||
this.on('mouseleave', this.handleMouseLease.bind(this));
|
||
this.on('dispose', this.handleDispose.bind(this));
|
||
},
|
||
|
||
handleDispose: function handleDispose(event) {
|
||
this.off('mousemove', this.handleMouseMove.bind(this));
|
||
this.off('touchmove', this.handleTouchMove.bind(this));
|
||
this.off('mousedown', this.handleMouseDown.bind(this));
|
||
this.off('touchstart', this.handleTouchStart.bind(this));
|
||
this.off('mouseup', this.handleMouseUp.bind(this));
|
||
this.off('touchend', this.handleTouchEnd.bind(this));
|
||
if (this.settings.scrollable) {
|
||
this.off('mousewheel', this.handleMouseWheel.bind(this));
|
||
this.off('MozMousePixelScroll', this.handleMouseWheel.bind(this));
|
||
}
|
||
this.off('mouseenter', this.handleMouseEnter.bind(this));
|
||
this.off('mouseleave', this.handleMouseLease.bind(this));
|
||
this.off('dispose', this.handleDispose.bind(this));
|
||
this.stopAnimation();
|
||
},
|
||
|
||
startAnimation: function startAnimation() {
|
||
this.render_animation = true;
|
||
this.animate();
|
||
},
|
||
|
||
stopAnimation: function stopAnimation() {
|
||
this.render_animation = false;
|
||
if (this.requestAnimationId) {
|
||
cancelAnimationFrame(this.requestAnimationId);
|
||
}
|
||
},
|
||
|
||
handleResize: function handleResize() {
|
||
this.width = this.player().el().offsetWidth, this.height = this.player().el().offsetHeight;
|
||
this.renderer.setSize(this.width, this.height);
|
||
},
|
||
|
||
handleMouseUp: function handleMouseUp(event) {
|
||
this.mouseDown = false;
|
||
if (this.clickToToggle) {
|
||
var clientX = event.clientX || event.changedTouches && event.changedTouches[0].clientX;
|
||
var clientY = event.clientY || event.changedTouches && event.changedTouches[0].clientY;
|
||
if (typeof clientX === "undefined" || clientY === "undefined") return;
|
||
var diffX = Math.abs(clientX - this.onPointerDownPointerX);
|
||
var diffY = Math.abs(clientY - this.onPointerDownPointerY);
|
||
if (diffX < 0.1 && diffY < 0.1) this.player().paused() ? this.player().play() : this.player().pause();
|
||
}
|
||
},
|
||
|
||
handleMouseDown: function handleMouseDown(event) {
|
||
event.preventDefault();
|
||
var clientX = event.clientX || event.touches && event.touches[0].clientX;
|
||
var clientY = event.clientY || event.touches && event.touches[0].clientY;
|
||
if (typeof clientX === "undefined" || clientY === "undefined") return;
|
||
this.mouseDown = true;
|
||
this.onPointerDownPointerX = clientX;
|
||
this.onPointerDownPointerY = clientY;
|
||
this.onPointerDownLon = this.lon;
|
||
this.onPointerDownLat = this.lat;
|
||
},
|
||
|
||
handleTouchStart: function handleTouchStart(event) {
|
||
if (event.touches.length > 1) {
|
||
this.isUserPinch = true;
|
||
this.multiTouchDistance = _Util2.default.getTouchesDistance(event.touches);
|
||
}
|
||
this.handleMouseDown(event);
|
||
},
|
||
|
||
handleTouchEnd: function handleTouchEnd(event) {
|
||
this.isUserPinch = false;
|
||
this.handleMouseUp(event);
|
||
},
|
||
|
||
handleMouseMove: function handleMouseMove(event) {
|
||
var clientX = event.clientX || event.touches && event.touches[0].clientX;
|
||
var clientY = event.clientY || event.touches && event.touches[0].clientY;
|
||
if (typeof clientX === "undefined" || clientY === "undefined") return;
|
||
if (this.settings.clickAndDrag) {
|
||
if (this.mouseDown) {
|
||
this.lon = (this.onPointerDownPointerX - clientX) * 0.2 + this.onPointerDownLon;
|
||
this.lat = (clientY - this.onPointerDownPointerY) * 0.2 + this.onPointerDownLat;
|
||
}
|
||
} else {
|
||
var x = clientX - this.el_.offsetLeft;
|
||
var y = clientY - this.el_.offsetTop;
|
||
this.lon = x / this.width * 430 - 225;
|
||
this.lat = y / this.height * -180 + 90;
|
||
}
|
||
},
|
||
|
||
handleTouchMove: function handleTouchMove(event) {
|
||
//handle single touch event,
|
||
if (!this.isUserPinch || event.touches.length <= 1) {
|
||
this.handleMouseMove(event);
|
||
}
|
||
},
|
||
|
||
handleMobileOrientation: function handleMobileOrientation(event) {
|
||
if (typeof event.rotationRate === "undefined") return;
|
||
var x = event.rotationRate.alpha;
|
||
var y = event.rotationRate.beta;
|
||
var portrait = typeof event.portrait !== "undefined" ? event.portrait : window.matchMedia("(orientation: portrait)").matches;
|
||
var landscape = typeof event.landscape !== "undefined" ? event.landscape : window.matchMedia("(orientation: landscape)").matches;
|
||
var orientation = event.orientation || window.orientation;
|
||
|
||
if (portrait) {
|
||
this.lon = this.lon - y * this.settings.mobileVibrationValue;
|
||
this.lat = this.lat + x * this.settings.mobileVibrationValue;
|
||
} else if (landscape) {
|
||
var orientationDegree = -90;
|
||
if (typeof orientation != "undefined") {
|
||
orientationDegree = orientation;
|
||
}
|
||
|
||
this.lon = orientationDegree == -90 ? this.lon + x * this.settings.mobileVibrationValue : this.lon - x * this.settings.mobileVibrationValue;
|
||
this.lat = orientationDegree == -90 ? this.lat + y * this.settings.mobileVibrationValue : this.lat - y * this.settings.mobileVibrationValue;
|
||
}
|
||
},
|
||
|
||
handleMouseWheel: function handleMouseWheel(event) {
|
||
event.stopPropagation();
|
||
event.preventDefault();
|
||
},
|
||
|
||
handleMouseEnter: function handleMouseEnter(event) {
|
||
this.isUserInteracting = true;
|
||
},
|
||
|
||
handleMouseLease: function handleMouseLease(event) {
|
||
this.isUserInteracting = false;
|
||
if (this.mouseDown) {
|
||
this.mouseDown = false;
|
||
}
|
||
},
|
||
|
||
animate: function animate() {
|
||
if (!this.render_animation) return;
|
||
this.requestAnimationId = requestAnimationFrame(this.animate.bind(this));
|
||
if (!this.player().paused()) {
|
||
if (typeof this.texture !== "undefined" && (!this.isPlayOnMobile && this.player().readyState() >= HAVE_CURRENT_DATA || this.isPlayOnMobile && this.player().hasClass("vjs-playing"))) {
|
||
var ct = new Date().getTime();
|
||
if (ct - this.time >= 30) {
|
||
this.texture.needsUpdate = true;
|
||
this.time = ct;
|
||
}
|
||
if (this.isPlayOnMobile) {
|
||
var currentTime = this.player().currentTime();
|
||
if (_MobileBuffering2.default.isBuffering(currentTime)) {
|
||
if (!this.player().hasClass("vjs-panorama-mobile-inline-video-buffering")) {
|
||
this.player().addClass("vjs-panorama-mobile-inline-video-buffering");
|
||
}
|
||
} else {
|
||
if (this.player().hasClass("vjs-panorama-mobile-inline-video-buffering")) {
|
||
this.player().removeClass("vjs-panorama-mobile-inline-video-buffering");
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
this.render();
|
||
},
|
||
|
||
render: function render() {
|
||
if (!this.isUserInteracting) {
|
||
var symbolLat = this.lat > this.settings.initLat ? -1 : 1;
|
||
var symbolLon = this.lon > this.settings.initLon ? -1 : 1;
|
||
if (this.settings.backToVerticalCenter) {
|
||
this.lat = this.lat > this.settings.initLat - Math.abs(this.settings.returnStepLat) && this.lat < this.settings.initLat + Math.abs(this.settings.returnStepLat) ? this.settings.initLat : this.lat + this.settings.returnStepLat * symbolLat;
|
||
}
|
||
if (this.settings.backToHorizonCenter) {
|
||
this.lon = this.lon > this.settings.initLon - Math.abs(this.settings.returnStepLon) && this.lon < this.settings.initLon + Math.abs(this.settings.returnStepLon) ? this.settings.initLon : this.lon + this.settings.returnStepLon * symbolLon;
|
||
}
|
||
}
|
||
this.lat = Math.max(this.settings.minLat, Math.min(this.settings.maxLat, this.lat));
|
||
this.lon = Math.max(this.settings.minLon, Math.min(this.settings.maxLon, this.lon));
|
||
this.phi = THREE.Math.degToRad(90 - this.lat);
|
||
this.theta = THREE.Math.degToRad(this.lon);
|
||
|
||
if (!this.supportVideoTexture) {
|
||
this.helperCanvas.update();
|
||
}
|
||
this.renderer.clear();
|
||
},
|
||
|
||
playOnMobile: function playOnMobile() {
|
||
this.isPlayOnMobile = true;
|
||
if (this.settings.autoMobileOrientation) window.addEventListener('devicemotion', this.handleMobileOrientation.bind(this));
|
||
},
|
||
|
||
el: function el() {
|
||
return this.el_;
|
||
}
|
||
};
|
||
};
|
||
|
||
exports.default = BaseCanvas;
|
||
|
||
},{"../lib/Detector":6,"../lib/MobileBuffering":8,"../lib/Util":11}],5:[function(require,module,exports){
|
||
'use strict';
|
||
|
||
Object.defineProperty(exports, "__esModule", {
|
||
value: true
|
||
});
|
||
|
||
var _BaseCanvas = require('./BaseCanvas');
|
||
|
||
var _BaseCanvas2 = _interopRequireDefault(_BaseCanvas);
|
||
|
||
var _Util = require('./Util');
|
||
|
||
var _Util2 = _interopRequireDefault(_Util);
|
||
|
||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||
|
||
/**
|
||
* Created by yanwsh on 4/3/16.
|
||
*/
|
||
|
||
var Canvas = function Canvas(baseComponent, THREE) {
|
||
var settings = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
||
|
||
var parent = (0, _BaseCanvas2.default)(baseComponent, THREE, settings);
|
||
|
||
return _Util2.default.extend(parent, {
|
||
constructor: function init(player, options) {
|
||
parent.constructor.call(this, player, options);
|
||
|
||
this.VRMode = false;
|
||
//define scene
|
||
this.scene = new THREE.Scene();
|
||
//define camera
|
||
this.camera = new THREE.PerspectiveCamera(options.initFov, this.width / this.height, 1, 2000);
|
||
this.camera.target = new THREE.Vector3(0, 0, 0);
|
||
|
||
//define geometry
|
||
var geometry = this.videoType === "equirectangular" ? new THREE.SphereGeometry(500, 60, 40) : new THREE.SphereBufferGeometry(500, 60, 40).toNonIndexed();
|
||
if (this.videoType === "fisheye") {
|
||
var normals = geometry.attributes.normal.array;
|
||
var uvs = geometry.attributes.uv.array;
|
||
for (var i = 0, l = normals.length / 3; i < l; i++) {
|
||
var x = normals[i * 3 + 0];
|
||
var y = normals[i * 3 + 1];
|
||
var z = normals[i * 3 + 2];
|
||
|
||
var r = Math.asin(Math.sqrt(x * x + z * z) / Math.sqrt(x * x + y * y + z * z)) / Math.PI;
|
||
if (y < 0) r = 1 - r;
|
||
var theta = x == 0 && z == 0 ? 0 : Math.acos(x / Math.sqrt(x * x + z * z));
|
||
if (z < 0) theta = theta * -1;
|
||
uvs[i * 2 + 0] = -0.8 * r * Math.cos(theta) + 0.5;
|
||
uvs[i * 2 + 1] = 0.8 * r * Math.sin(theta) + 0.5;
|
||
}
|
||
geometry.rotateX(options.rotateX);
|
||
geometry.rotateY(options.rotateY);
|
||
geometry.rotateZ(options.rotateZ);
|
||
} else if (this.videoType === "dual_fisheye") {
|
||
var _normals = geometry.attributes.normal.array;
|
||
var _uvs = geometry.attributes.uv.array;
|
||
var _l = _normals.length / 3;
|
||
for (var _i = 0; _i < _l / 2; _i++) {
|
||
var _x2 = _normals[_i * 3 + 0];
|
||
var _y = _normals[_i * 3 + 1];
|
||
var _z = _normals[_i * 3 + 2];
|
||
|
||
var _r = _x2 == 0 && _z == 0 ? 1 : Math.acos(_y) / Math.sqrt(_x2 * _x2 + _z * _z) * (2 / Math.PI);
|
||
_uvs[_i * 2 + 0] = _x2 * options.dualFish.circle1.rx * _r * options.dualFish.circle1.coverX + options.dualFish.circle1.x;
|
||
_uvs[_i * 2 + 1] = _z * options.dualFish.circle1.ry * _r * options.dualFish.circle1.coverY + options.dualFish.circle1.y;
|
||
}
|
||
for (var _i2 = _l / 2; _i2 < _l; _i2++) {
|
||
var _x3 = _normals[_i2 * 3 + 0];
|
||
var _y2 = _normals[_i2 * 3 + 1];
|
||
var _z2 = _normals[_i2 * 3 + 2];
|
||
|
||
var _r2 = _x3 == 0 && _z2 == 0 ? 1 : Math.acos(-_y2) / Math.sqrt(_x3 * _x3 + _z2 * _z2) * (2 / Math.PI);
|
||
_uvs[_i2 * 2 + 0] = -_x3 * options.dualFish.circle2.rx * _r2 * options.dualFish.circle2.coverX + options.dualFish.circle2.x;
|
||
_uvs[_i2 * 2 + 1] = _z2 * options.dualFish.circle2.ry * _r2 * options.dualFish.circle2.coverY + options.dualFish.circle2.y;
|
||
}
|
||
geometry.rotateX(options.rotateX);
|
||
geometry.rotateY(options.rotateY);
|
||
geometry.rotateZ(options.rotateZ);
|
||
}
|
||
geometry.scale(-1, 1, 1);
|
||
//define mesh
|
||
this.mesh = new THREE.Mesh(geometry, new THREE.MeshBasicMaterial({ map: this.texture }));
|
||
//this.mesh.scale.x = -1;
|
||
this.scene.add(this.mesh);
|
||
},
|
||
|
||
enableVR: function enableVR() {
|
||
this.VRMode = true;
|
||
if (typeof vrHMD !== 'undefined') {
|
||
var eyeParamsL = vrHMD.getEyeParameters('left');
|
||
var eyeParamsR = vrHMD.getEyeParameters('right');
|
||
|
||
this.eyeFOVL = eyeParamsL.recommendedFieldOfView;
|
||
this.eyeFOVR = eyeParamsR.recommendedFieldOfView;
|
||
}
|
||
|
||
this.cameraL = new THREE.PerspectiveCamera(this.camera.fov, this.width / 2 / this.height, 1, 2000);
|
||
this.cameraR = new THREE.PerspectiveCamera(this.camera.fov, this.width / 2 / this.height, 1, 2000);
|
||
},
|
||
|
||
disableVR: function disableVR() {
|
||
this.VRMode = false;
|
||
this.renderer.setViewport(0, 0, this.width, this.height);
|
||
this.renderer.setScissor(0, 0, this.width, this.height);
|
||
},
|
||
|
||
handleResize: function handleResize() {
|
||
parent.handleResize.call(this);
|
||
this.camera.aspect = this.width / this.height;
|
||
this.camera.updateProjectionMatrix();
|
||
if (this.VRMode) {
|
||
this.cameraL.aspect = this.camera.aspect / 2;
|
||
this.cameraR.aspect = this.camera.aspect / 2;
|
||
this.cameraL.updateProjectionMatrix();
|
||
this.cameraR.updateProjectionMatrix();
|
||
}
|
||
},
|
||
|
||
handleMouseWheel: function handleMouseWheel(event) {
|
||
parent.handleMouseWheel(event);
|
||
// WebKit
|
||
if (event.wheelDeltaY) {
|
||
this.camera.fov -= event.wheelDeltaY * 0.05;
|
||
// Opera / Explorer 9
|
||
} else if (event.wheelDelta) {
|
||
this.camera.fov -= event.wheelDelta * 0.05;
|
||
// Firefox
|
||
} else if (event.detail) {
|
||
this.camera.fov += event.detail * 1.0;
|
||
}
|
||
this.camera.fov = Math.min(this.settings.maxFov, this.camera.fov);
|
||
this.camera.fov = Math.max(this.settings.minFov, this.camera.fov);
|
||
this.camera.updateProjectionMatrix();
|
||
if (this.VRMode) {
|
||
this.cameraL.fov = this.camera.fov;
|
||
this.cameraR.fov = this.camera.fov;
|
||
this.cameraL.updateProjectionMatrix();
|
||
this.cameraR.updateProjectionMatrix();
|
||
}
|
||
},
|
||
|
||
handleTouchMove: function handleTouchMove(event) {
|
||
parent.handleTouchMove.call(this, event);
|
||
if (this.isUserPinch) {
|
||
var currentDistance = _Util2.default.getTouchesDistance(event.touches);
|
||
event.wheelDeltaY = (currentDistance - this.multiTouchDistance) * 2;
|
||
this.handleMouseWheel.call(this, event);
|
||
this.multiTouchDistance = currentDistance;
|
||
}
|
||
},
|
||
|
||
render: function render() {
|
||
parent.render.call(this);
|
||
this.camera.target.x = 500 * Math.sin(this.phi) * Math.cos(this.theta);
|
||
this.camera.target.y = 500 * Math.cos(this.phi);
|
||
this.camera.target.z = 500 * Math.sin(this.phi) * Math.sin(this.theta);
|
||
this.camera.lookAt(this.camera.target);
|
||
|
||
if (!this.VRMode) {
|
||
this.renderer.render(this.scene, this.camera);
|
||
} else {
|
||
var viewPortWidth = this.width / 2,
|
||
viewPortHeight = this.height;
|
||
if (typeof vrHMD !== 'undefined') {
|
||
this.cameraL.projectionMatrix = _Util2.default.fovToProjection(this.eyeFOVL, true, this.camera.near, this.camera.far);
|
||
this.cameraR.projectionMatrix = _Util2.default.fovToProjection(this.eyeFOVR, true, this.camera.near, this.camera.far);
|
||
} else {
|
||
var lonL = this.lon + this.settings.VRGapDegree;
|
||
var lonR = this.lon - this.settings.VRGapDegree;
|
||
|
||
var thetaL = THREE.Math.degToRad(lonL);
|
||
var thetaR = THREE.Math.degToRad(lonR);
|
||
|
||
var targetL = _Util2.default.deepCopy(this.camera.target);
|
||
targetL.x = 500 * Math.sin(this.phi) * Math.cos(thetaL);
|
||
targetL.z = 500 * Math.sin(this.phi) * Math.sin(thetaL);
|
||
this.cameraL.lookAt(targetL);
|
||
|
||
var targetR = _Util2.default.deepCopy(this.camera.target);
|
||
targetR.x = 500 * Math.sin(this.phi) * Math.cos(thetaR);
|
||
targetR.z = 500 * Math.sin(this.phi) * Math.sin(thetaR);
|
||
this.cameraR.lookAt(targetR);
|
||
}
|
||
// render left eye
|
||
this.renderer.setViewport(0, 0, viewPortWidth, viewPortHeight);
|
||
this.renderer.setScissor(0, 0, viewPortWidth, viewPortHeight);
|
||
this.renderer.render(this.scene, this.cameraL);
|
||
|
||
// render right eye
|
||
this.renderer.setViewport(viewPortWidth, 0, viewPortWidth, viewPortHeight);
|
||
this.renderer.setScissor(viewPortWidth, 0, viewPortWidth, viewPortHeight);
|
||
this.renderer.render(this.scene, this.cameraR);
|
||
}
|
||
}
|
||
});
|
||
};
|
||
|
||
exports.default = Canvas;
|
||
|
||
},{"./BaseCanvas":4,"./Util":11}],6:[function(require,module,exports){
|
||
'use strict';
|
||
|
||
Object.defineProperty(exports, "__esModule", {
|
||
value: true
|
||
});
|
||
/**
|
||
* @author alteredq / http://alteredqualia.com/
|
||
* @author mr.doob / http://mrdoob.com/
|
||
*/
|
||
|
||
//in case it's running on node.js
|
||
var win = {};
|
||
|
||
if (typeof window !== "undefined") {
|
||
win = window;
|
||
}
|
||
|
||
var Detector = {
|
||
|
||
canvas: !!win.CanvasRenderingContext2D,
|
||
webgl: function () {
|
||
|
||
try {
|
||
|
||
var canvas = document.createElement('canvas');return !!(win.WebGLRenderingContext && (canvas.getContext('webgl') || canvas.getContext('experimental-webgl')));
|
||
} catch (e) {
|
||
|
||
return false;
|
||
}
|
||
}(),
|
||
workers: !!win.Worker,
|
||
fileapi: win.File && win.FileReader && win.FileList && win.Blob,
|
||
|
||
Check_Version: function Check_Version() {
|
||
var rv = -1; // Return value assumes failure.
|
||
|
||
if (navigator.appName == 'Microsoft Internet Explorer') {
|
||
|
||
var ua = navigator.userAgent,
|
||
re = new RegExp("MSIE ([0-9]{1,}[\\.0-9]{0,})");
|
||
|
||
if (re.exec(ua) !== null) {
|
||
rv = parseFloat(RegExp.$1);
|
||
}
|
||
} else if (navigator.appName == "Netscape") {
|
||
/// in IE 11 the navigator.appVersion says 'trident'
|
||
/// in Edge the navigator.appVersion does not say trident
|
||
if (navigator.appVersion.indexOf('Trident') !== -1) rv = 11;else {
|
||
var ua = navigator.userAgent;
|
||
var re = new RegExp("Edge\/([0-9]{1,}[\\.0-9]{0,})");
|
||
if (re.exec(ua) !== null) {
|
||
rv = parseFloat(RegExp.$1);
|
||
}
|
||
}
|
||
}
|
||
|
||
return rv;
|
||
},
|
||
|
||
supportVideoTexture: function supportVideoTexture() {
|
||
//ie 11 and edge 12 doesn't support video texture.
|
||
var version = this.Check_Version();
|
||
return version === -1 || version >= 13;
|
||
},
|
||
|
||
isLiveStreamOnSafari: function isLiveStreamOnSafari(videoElement) {
|
||
//live stream on safari doesn't support video texture
|
||
var videoSources = [].slice.call(videoElement.querySelectorAll("source"));
|
||
var result = false;
|
||
if (videoElement.src && videoElement.src.indexOf('.m3u8') > -1) {
|
||
videoSources.push({
|
||
src: videoElement.src,
|
||
type: "application/x-mpegURL"
|
||
});
|
||
}
|
||
for (var i = 0; i < videoSources.length; i++) {
|
||
var currentVideoSource = videoSources[i];
|
||
if ((currentVideoSource.type === "application/x-mpegURL" || currentVideoSource.type === "application/vnd.apple.mpegurl") && /(Safari|AppleWebKit)/.test(navigator.userAgent) && /Apple Computer/.test(navigator.vendor)) {
|
||
result = true;
|
||
break;
|
||
}
|
||
}
|
||
return result;
|
||
},
|
||
|
||
getWebGLErrorMessage: function getWebGLErrorMessage() {
|
||
|
||
var element = document.createElement('div');
|
||
element.id = 'webgl-error-message';
|
||
|
||
if (!this.webgl) {
|
||
|
||
element.innerHTML = win.WebGLRenderingContext ? ['Your graphics card does not seem to support <a href="http://khronos.org/webgl/wiki/Getting_a_WebGL_Implementation" style="color:#000">WebGL</a>.<br />', 'Find out how to get it <a href="http://get.webgl.org/" style="color:#000">here</a>.'].join('\n') : ['Your browser does not seem to support <a href="http://khronos.org/webgl/wiki/Getting_a_WebGL_Implementation" style="color:#000">WebGL</a>.<br/>', 'Find out how to get it <a href="http://get.webgl.org/" style="color:#000">here</a>.'].join('\n');
|
||
}
|
||
|
||
return element;
|
||
},
|
||
|
||
addGetWebGLMessage: function addGetWebGLMessage(parameters) {
|
||
|
||
var parent, id, element;
|
||
|
||
parameters = parameters || {};
|
||
|
||
parent = parameters.parent !== undefined ? parameters.parent : document.body;
|
||
id = parameters.id !== undefined ? parameters.id : 'oldie';
|
||
|
||
element = Detector.getWebGLErrorMessage();
|
||
element.id = id;
|
||
|
||
parent.appendChild(element);
|
||
}
|
||
|
||
};
|
||
|
||
exports.default = Detector;
|
||
|
||
},{}],7:[function(require,module,exports){
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", {
|
||
value: true
|
||
});
|
||
/**
|
||
* Created by wensheng.yan on 5/23/16.
|
||
*/
|
||
var HelperCanvas = function HelperCanvas(baseComponent) {
|
||
var element = document.createElement('canvas');
|
||
element.className = "vjs-video-helper-canvas";
|
||
return {
|
||
constructor: function init(player, options) {
|
||
this.videoElement = options.video;
|
||
this.width = options.width;
|
||
this.height = options.height;
|
||
|
||
element.width = this.width;
|
||
element.height = this.height;
|
||
element.style.display = "none";
|
||
options.el = element;
|
||
|
||
this.context = element.getContext('2d');
|
||
this.context.drawImage(this.videoElement, 0, 0, this.width, this.height);
|
||
baseComponent.call(this, player, options);
|
||
},
|
||
|
||
getContext: function getContext() {
|
||
return this.context;
|
||
},
|
||
|
||
update: function update() {
|
||
this.context.drawImage(this.videoElement, 0, 0, this.width, this.height);
|
||
},
|
||
|
||
el: function el() {
|
||
return element;
|
||
}
|
||
};
|
||
};
|
||
|
||
exports.default = HelperCanvas;
|
||
|
||
},{}],8:[function(require,module,exports){
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", {
|
||
value: true
|
||
});
|
||
/**
|
||
* Created by yanwsh on 6/6/16.
|
||
*/
|
||
var MobileBuffering = {
|
||
prev_currentTime: 0,
|
||
counter: 0,
|
||
|
||
isBuffering: function isBuffering(currentTime) {
|
||
if (currentTime == this.prev_currentTime) this.counter++;else this.counter = 0;
|
||
this.prev_currentTime = currentTime;
|
||
if (this.counter > 10) {
|
||
//not let counter overflow
|
||
this.counter = 10;
|
||
return true;
|
||
}
|
||
return false;
|
||
}
|
||
};
|
||
|
||
exports.default = MobileBuffering;
|
||
|
||
},{}],9:[function(require,module,exports){
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", {
|
||
value: true
|
||
});
|
||
|
||
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
|
||
|
||
/**
|
||
* Created by yanwsh on 4/4/16.
|
||
*/
|
||
|
||
var Notice = function Notice(baseComponent) {
|
||
var element = document.createElement('div');
|
||
element.className = "vjs-video-notice-label";
|
||
|
||
return {
|
||
constructor: function init(player, options) {
|
||
if (_typeof(options.NoticeMessage) == "object") {
|
||
element = options.NoticeMessage;
|
||
options.el = options.NoticeMessage;
|
||
} else if (typeof options.NoticeMessage == "string") {
|
||
element.innerHTML = options.NoticeMessage;
|
||
options.el = element;
|
||
}
|
||
|
||
baseComponent.call(this, player, options);
|
||
},
|
||
|
||
el: function el() {
|
||
return element;
|
||
}
|
||
};
|
||
};
|
||
|
||
exports.default = Notice;
|
||
|
||
},{}],10:[function(require,module,exports){
|
||
/**
|
||
*
|
||
* (c) Wensheng Yan <yanwsh@gmail.com>
|
||
* Date: 10/21/16
|
||
*
|
||
* For the full copyright and license information, please view the LICENSE
|
||
* file that was distributed with this source code.
|
||
*/
|
||
'use strict';
|
||
|
||
Object.defineProperty(exports, "__esModule", {
|
||
value: true
|
||
});
|
||
|
||
var _BaseCanvas = require('./BaseCanvas');
|
||
|
||
var _BaseCanvas2 = _interopRequireDefault(_BaseCanvas);
|
||
|
||
var _Util = require('./Util');
|
||
|
||
var _Util2 = _interopRequireDefault(_Util);
|
||
|
||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||
|
||
var ThreeDCanvas = function ThreeDCanvas(baseComponent, THREE) {
|
||
var settings = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
||
|
||
var parent = (0, _BaseCanvas2.default)(baseComponent, THREE, settings);
|
||
return _Util2.default.extend(parent, {
|
||
constructor: function init(player, options) {
|
||
parent.constructor.call(this, player, options);
|
||
//only show left part by default
|
||
this.VRMode = false;
|
||
//define scene
|
||
this.scene = new THREE.Scene();
|
||
|
||
var aspectRatio = this.width / this.height;
|
||
//define camera
|
||
this.cameraL = new THREE.PerspectiveCamera(options.initFov, aspectRatio, 1, 2000);
|
||
this.cameraL.target = new THREE.Vector3(0, 0, 0);
|
||
|
||
this.cameraR = new THREE.PerspectiveCamera(options.initFov, aspectRatio / 2, 1, 2000);
|
||
this.cameraR.position.set(1000, 0, 0);
|
||
this.cameraR.target = new THREE.Vector3(1000, 0, 0);
|
||
|
||
var geometryL = new THREE.SphereBufferGeometry(500, 60, 40).toNonIndexed();
|
||
var geometryR = new THREE.SphereBufferGeometry(500, 60, 40).toNonIndexed();
|
||
|
||
var uvsL = geometryL.attributes.uv.array;
|
||
var normalsL = geometryL.attributes.normal.array;
|
||
for (var i = 0; i < normalsL.length / 3; i++) {
|
||
uvsL[i * 2 + 1] = uvsL[i * 2 + 1] / 2;
|
||
}
|
||
|
||
var uvsR = geometryR.attributes.uv.array;
|
||
var normalsR = geometryR.attributes.normal.array;
|
||
for (var i = 0; i < normalsR.length / 3; i++) {
|
||
uvsR[i * 2 + 1] = uvsR[i * 2 + 1] / 2 + 0.5;
|
||
}
|
||
|
||
geometryL.scale(-1, 1, 1);
|
||
geometryR.scale(-1, 1, 1);
|
||
|
||
this.meshL = new THREE.Mesh(geometryL, new THREE.MeshBasicMaterial({ map: this.texture }));
|
||
|
||
this.meshR = new THREE.Mesh(geometryR, new THREE.MeshBasicMaterial({ map: this.texture }));
|
||
this.meshR.position.set(1000, 0, 0);
|
||
|
||
this.scene.add(this.meshL);
|
||
|
||
if (options.callback) options.callback();
|
||
},
|
||
|
||
handleResize: function handleResize() {
|
||
parent.handleResize.call(this);
|
||
var aspectRatio = this.width / this.height;
|
||
if (!this.VRMode) {
|
||
this.cameraL.aspect = aspectRatio;
|
||
this.cameraL.updateProjectionMatrix();
|
||
} else {
|
||
aspectRatio /= 2;
|
||
this.cameraL.aspect = aspectRatio;
|
||
this.cameraR.aspect = aspectRatio;
|
||
this.cameraL.updateProjectionMatrix();
|
||
this.cameraR.updateProjectionMatrix();
|
||
}
|
||
},
|
||
|
||
handleMouseWheel: function handleMouseWheel(event) {
|
||
parent.handleMouseWheel(event);
|
||
// WebKit
|
||
if (event.wheelDeltaY) {
|
||
this.cameraL.fov -= event.wheelDeltaY * 0.05;
|
||
// Opera / Explorer 9
|
||
} else if (event.wheelDelta) {
|
||
this.cameraL.fov -= event.wheelDelta * 0.05;
|
||
// Firefox
|
||
} else if (event.detail) {
|
||
this.cameraL.fov += event.detail * 1.0;
|
||
}
|
||
this.cameraL.fov = Math.min(this.settings.maxFov, this.cameraL.fov);
|
||
this.cameraL.fov = Math.max(this.settings.minFov, this.cameraL.fov);
|
||
this.cameraL.updateProjectionMatrix();
|
||
if (this.VRMode) {
|
||
this.cameraR.fov = this.cameraL.fov;
|
||
this.cameraR.updateProjectionMatrix();
|
||
}
|
||
},
|
||
|
||
enableVR: function enableVR() {
|
||
this.VRMode = true;
|
||
this.scene.add(this.meshR);
|
||
this.handleResize();
|
||
},
|
||
|
||
disableVR: function disableVR() {
|
||
this.VRMode = false;
|
||
this.scene.remove(this.meshR);
|
||
this.handleResize();
|
||
},
|
||
|
||
render: function render() {
|
||
parent.render.call(this);
|
||
this.cameraL.target.x = 500 * Math.sin(this.phi) * Math.cos(this.theta);
|
||
this.cameraL.target.y = 500 * Math.cos(this.phi);
|
||
this.cameraL.target.z = 500 * Math.sin(this.phi) * Math.sin(this.theta);
|
||
this.cameraL.lookAt(this.cameraL.target);
|
||
|
||
if (this.VRMode) {
|
||
var viewPortWidth = this.width / 2,
|
||
viewPortHeight = this.height;
|
||
this.cameraR.target.x = 1000 + 500 * Math.sin(this.phi) * Math.cos(this.theta);
|
||
this.cameraR.target.y = 500 * Math.cos(this.phi);
|
||
this.cameraR.target.z = 500 * Math.sin(this.phi) * Math.sin(this.theta);
|
||
this.cameraR.lookAt(this.cameraR.target);
|
||
|
||
// render left eye
|
||
this.renderer.setViewport(0, 0, viewPortWidth, viewPortHeight);
|
||
this.renderer.setScissor(0, 0, viewPortWidth, viewPortHeight);
|
||
this.renderer.render(this.scene, this.cameraL);
|
||
|
||
// render right eye
|
||
this.renderer.setViewport(viewPortWidth, 0, viewPortWidth, viewPortHeight);
|
||
this.renderer.setScissor(viewPortWidth, 0, viewPortWidth, viewPortHeight);
|
||
this.renderer.render(this.scene, this.cameraR);
|
||
} else {
|
||
this.renderer.render(this.scene, this.cameraL);
|
||
}
|
||
}
|
||
});
|
||
};
|
||
|
||
exports.default = ThreeDCanvas;
|
||
|
||
},{"./BaseCanvas":4,"./Util":11}],11:[function(require,module,exports){
|
||
'use strict';
|
||
|
||
Object.defineProperty(exports, "__esModule", {
|
||
value: true
|
||
});
|
||
/**
|
||
* Created by wensheng.yan on 4/4/16.
|
||
*/
|
||
function whichTransitionEvent() {
|
||
var t;
|
||
var el = document.createElement('fakeelement');
|
||
var transitions = {
|
||
'transition': 'transitionend',
|
||
'OTransition': 'oTransitionEnd',
|
||
'MozTransition': 'transitionend',
|
||
'WebkitTransition': 'webkitTransitionEnd'
|
||
};
|
||
|
||
for (t in transitions) {
|
||
if (el.style[t] !== undefined) {
|
||
return transitions[t];
|
||
}
|
||
}
|
||
}
|
||
|
||
function mobileAndTabletcheck() {
|
||
var check = false;
|
||
(function (a) {
|
||
if (/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino|android|ipad|playbook|silk/i.test(a) || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0, 4))) check = true;
|
||
})(navigator.userAgent || navigator.vendor || window.opera);
|
||
return check;
|
||
}
|
||
|
||
function isIos() {
|
||
return (/iPhone|iPad|iPod/i.test(navigator.userAgent)
|
||
);
|
||
}
|
||
|
||
function isRealIphone() {
|
||
return (/iPhone|iPod/i.test(navigator.platform)
|
||
);
|
||
}
|
||
|
||
//adopt code from: https://github.com/MozVR/vr-web-examples/blob/master/threejs-vr-boilerplate/js/VREffect.js
|
||
function fovToNDCScaleOffset(fov) {
|
||
var pxscale = 2.0 / (fov.leftTan + fov.rightTan);
|
||
var pxoffset = (fov.leftTan - fov.rightTan) * pxscale * 0.5;
|
||
var pyscale = 2.0 / (fov.upTan + fov.downTan);
|
||
var pyoffset = (fov.upTan - fov.downTan) * pyscale * 0.5;
|
||
return { scale: [pxscale, pyscale], offset: [pxoffset, pyoffset] };
|
||
}
|
||
|
||
function fovPortToProjection(fov, rightHanded, zNear, zFar) {
|
||
|
||
rightHanded = rightHanded === undefined ? true : rightHanded;
|
||
zNear = zNear === undefined ? 0.01 : zNear;
|
||
zFar = zFar === undefined ? 10000.0 : zFar;
|
||
|
||
var handednessScale = rightHanded ? -1.0 : 1.0;
|
||
|
||
// start with an identity matrix
|
||
var mobj = new THREE.Matrix4();
|
||
var m = mobj.elements;
|
||
|
||
// and with scale/offset info for normalized device coords
|
||
var scaleAndOffset = fovToNDCScaleOffset(fov);
|
||
|
||
// X result, map clip edges to [-w,+w]
|
||
m[0 * 4 + 0] = scaleAndOffset.scale[0];
|
||
m[0 * 4 + 1] = 0.0;
|
||
m[0 * 4 + 2] = scaleAndOffset.offset[0] * handednessScale;
|
||
m[0 * 4 + 3] = 0.0;
|
||
|
||
// Y result, map clip edges to [-w,+w]
|
||
// Y offset is negated because this proj matrix transforms from world coords with Y=up,
|
||
// but the NDC scaling has Y=down (thanks D3D?)
|
||
m[1 * 4 + 0] = 0.0;
|
||
m[1 * 4 + 1] = scaleAndOffset.scale[1];
|
||
m[1 * 4 + 2] = -scaleAndOffset.offset[1] * handednessScale;
|
||
m[1 * 4 + 3] = 0.0;
|
||
|
||
// Z result (up to the app)
|
||
m[2 * 4 + 0] = 0.0;
|
||
m[2 * 4 + 1] = 0.0;
|
||
m[2 * 4 + 2] = zFar / (zNear - zFar) * -handednessScale;
|
||
m[2 * 4 + 3] = zFar * zNear / (zNear - zFar);
|
||
|
||
// W result (= Z in)
|
||
m[3 * 4 + 0] = 0.0;
|
||
m[3 * 4 + 1] = 0.0;
|
||
m[3 * 4 + 2] = handednessScale;
|
||
m[3 * 4 + 3] = 0.0;
|
||
|
||
mobj.transpose();
|
||
|
||
return mobj;
|
||
}
|
||
|
||
function fovToProjection(fov, rightHanded, zNear, zFar) {
|
||
var DEG2RAD = Math.PI / 180.0;
|
||
|
||
var fovPort = {
|
||
upTan: Math.tan(fov.upDegrees * DEG2RAD),
|
||
downTan: Math.tan(fov.downDegrees * DEG2RAD),
|
||
leftTan: Math.tan(fov.leftDegrees * DEG2RAD),
|
||
rightTan: Math.tan(fov.rightDegrees * DEG2RAD)
|
||
};
|
||
|
||
return fovPortToProjection(fovPort, rightHanded, zNear, zFar);
|
||
}
|
||
|
||
function extend(superClass) {
|
||
var subClassMethods = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
||
|
||
for (var method in superClass) {
|
||
if (superClass.hasOwnProperty(method) && !subClassMethods.hasOwnProperty(method)) {
|
||
subClassMethods[method] = superClass[method];
|
||
}
|
||
}
|
||
return subClassMethods;
|
||
}
|
||
|
||
function deepCopy(obj) {
|
||
var to = {};
|
||
|
||
for (var name in obj) {
|
||
to[name] = obj[name];
|
||
}
|
||
|
||
return to;
|
||
}
|
||
|
||
function getTouchesDistance(touches) {
|
||
return Math.sqrt((touches[0].clientX - touches[1].clientX) * (touches[0].clientX - touches[1].clientX) + (touches[0].clientY - touches[1].clientY) * (touches[0].clientY - touches[1].clientY));
|
||
}
|
||
|
||
exports.default = {
|
||
whichTransitionEvent: whichTransitionEvent,
|
||
mobileAndTabletcheck: mobileAndTabletcheck,
|
||
isIos: isIos,
|
||
isRealIphone: isRealIphone,
|
||
fovToProjection: fovToProjection,
|
||
extend: extend,
|
||
deepCopy: deepCopy,
|
||
getTouchesDistance: getTouchesDistance
|
||
};
|
||
|
||
},{}],12:[function(require,module,exports){
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", {
|
||
value: true
|
||
});
|
||
/**
|
||
* Created by yanwsh on 8/13/16.
|
||
*/
|
||
|
||
var VRButton = function VRButton(ButtonComponent) {
|
||
return {
|
||
constructor: function init(player, options) {
|
||
ButtonComponent.call(this, player, options);
|
||
},
|
||
|
||
buildCSSClass: function buildCSSClass() {
|
||
return "vjs-VR-control " + ButtonComponent.prototype.buildCSSClass.call(this);
|
||
},
|
||
|
||
handleClick: function handleClick() {
|
||
var canvas = this.player().getChild("Canvas");
|
||
!canvas.VRMode ? canvas.enableVR() : canvas.disableVR();
|
||
canvas.VRMode ? this.addClass("enable") : this.removeClass("enable");
|
||
canvas.VRMode ? this.player().trigger('VRModeOn') : this.player().trigger('VRModeOff');
|
||
},
|
||
|
||
controlText_: "VR"
|
||
};
|
||
};
|
||
|
||
exports.default = VRButton;
|
||
|
||
},{}],13:[function(require,module,exports){
|
||
/**
|
||
* Created by yanwsh on 4/3/16.
|
||
*/
|
||
'use strict';
|
||
|
||
Object.defineProperty(exports, "__esModule", {
|
||
value: true
|
||
});
|
||
|
||
var _Util = require('./lib/Util');
|
||
|
||
var _Util2 = _interopRequireDefault(_Util);
|
||
|
||
var _Detector = require('./lib/Detector');
|
||
|
||
var _Detector2 = _interopRequireDefault(_Detector);
|
||
|
||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||
|
||
var runOnMobile = typeof window !== "undefined" ? _Util2.default.mobileAndTabletcheck() : false;
|
||
|
||
// Default options for the plugin.
|
||
var defaults = {
|
||
clickAndDrag: runOnMobile,
|
||
showNotice: true,
|
||
NoticeMessage: "Please use your mouse drag and drop the video.",
|
||
autoHideNotice: 3000,
|
||
//limit the video size when user scroll.
|
||
scrollable: true,
|
||
initFov: 75,
|
||
maxFov: 105,
|
||
minFov: 51,
|
||
//initial position for the video
|
||
initLat: 0,
|
||
initLon: -180,
|
||
//A float value back to center when mouse out the canvas. The higher, the faster.
|
||
returnStepLat: 0.5,
|
||
returnStepLon: 2,
|
||
backToVerticalCenter: !runOnMobile,
|
||
backToHorizonCenter: !runOnMobile,
|
||
clickToToggle: false,
|
||
|
||
//limit viewable zoom
|
||
minLat: -85,
|
||
maxLat: 85,
|
||
|
||
minLon: -Infinity,
|
||
maxLon: Infinity,
|
||
|
||
videoType: "equirectangular",
|
||
|
||
rotateX: 0,
|
||
rotateY: 0,
|
||
rotateZ: 0,
|
||
|
||
autoMobileOrientation: false,
|
||
mobileVibrationValue: runOnMobile && _Util2.default.isIos() ? 0.022 : 1,
|
||
|
||
VREnable: true,
|
||
VRGapDegree: 2.5,
|
||
|
||
closePanorama: false,
|
||
|
||
helperCanvas: {},
|
||
|
||
dualFish: {
|
||
width: 1920,
|
||
height: 1080,
|
||
circle1: {
|
||
x: 0.240625,
|
||
y: 0.553704,
|
||
rx: 0.23333,
|
||
ry: 0.43148,
|
||
coverX: 0.913,
|
||
coverY: 0.9
|
||
},
|
||
circle2: {
|
||
x: 0.757292,
|
||
y: 0.553704,
|
||
rx: 0.232292,
|
||
ry: 0.4296296,
|
||
coverX: 0.913,
|
||
coverY: 0.9308
|
||
}
|
||
}
|
||
};
|
||
|
||
function playerResize(player) {
|
||
var canvas = player.getChild('Canvas');
|
||
return function () {
|
||
player.el().style.width = window.innerWidth + "px";
|
||
player.el().style.height = window.innerHeight + "px";
|
||
canvas.handleResize();
|
||
};
|
||
}
|
||
|
||
function fullscreenOnIOS(player, clickFn) {
|
||
var resizeFn = playerResize(player);
|
||
player.controlBar.fullscreenToggle.off("tap", clickFn);
|
||
player.controlBar.fullscreenToggle.on("tap", function fullscreen() {
|
||
var canvas = player.getChild('Canvas');
|
||
if (!player.isFullscreen()) {
|
||
//set to fullscreen
|
||
player.isFullscreen(true);
|
||
player.enterFullWindow();
|
||
resizeFn();
|
||
window.addEventListener("devicemotion", resizeFn);
|
||
} else {
|
||
player.isFullscreen(false);
|
||
player.exitFullWindow();
|
||
player.el().style.width = "";
|
||
player.el().style.height = "";
|
||
canvas.handleResize();
|
||
window.removeEventListener("devicemotion", resizeFn);
|
||
}
|
||
});
|
||
}
|
||
|
||
/**
|
||
* Function to invoke when the player is ready.
|
||
*
|
||
* This is a great place for your plugin to initialize itself. When this
|
||
* function is called, the player will have its DOM and child components
|
||
* in place.
|
||
*
|
||
* @function onPlayerReady
|
||
* @param {Player} player
|
||
* @param {Object} [options={}]
|
||
*/
|
||
var onPlayerReady = function onPlayerReady(player, options, settings) {
|
||
player.addClass('vjs-panorama');
|
||
if (!_Detector2.default.webgl) {
|
||
PopupNotification(player, {
|
||
NoticeMessage: _Detector2.default.getWebGLErrorMessage(),
|
||
autoHideNotice: options.autoHideNotice
|
||
});
|
||
if (options.callback) {
|
||
options.callback();
|
||
}
|
||
return;
|
||
}
|
||
player.addChild('Canvas', _Util2.default.deepCopy(options));
|
||
var canvas = player.getChild('Canvas');
|
||
if (runOnMobile) {
|
||
var videoElement = settings.getTech(player);
|
||
if (_Util2.default.isRealIphone()) {
|
||
var makeVideoPlayableInline = require('iphone-inline-video');
|
||
//ios 10 support play video inline
|
||
videoElement.setAttribute("playsinline", "");
|
||
makeVideoPlayableInline(videoElement, true);
|
||
}
|
||
if (_Util2.default.isIos()) {
|
||
fullscreenOnIOS(player, settings.getFullscreenToggleClickFn(player));
|
||
}
|
||
player.addClass("vjs-panorama-mobile-inline-video");
|
||
player.removeClass("vjs-using-native-controls");
|
||
canvas.playOnMobile();
|
||
}
|
||
if (options.showNotice) {
|
||
player.on("playing", function () {
|
||
PopupNotification(player, _Util2.default.deepCopy(options));
|
||
});
|
||
}
|
||
if (options.VREnable) {
|
||
player.controlBar.addChild('VRButton', {}, player.controlBar.children().length - 1);
|
||
}
|
||
canvas.hide();
|
||
player.on("play", function () {
|
||
canvas.show();
|
||
});
|
||
player.on("fullscreenchange", function () {
|
||
canvas.handleResize();
|
||
});
|
||
if (options.callback) options.callback();
|
||
};
|
||
|
||
var PopupNotification = function PopupNotification(player) {
|
||
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {
|
||
NoticeMessage: ""
|
||
};
|
||
|
||
var notice = player.addChild('Notice', options);
|
||
|
||
if (options.autoHideNotice > 0) {
|
||
setTimeout(function () {
|
||
notice.addClass("vjs-video-notice-fadeOut");
|
||
var transitionEvent = _Util2.default.whichTransitionEvent();
|
||
var hide = function hide() {
|
||
notice.hide();
|
||
notice.removeClass("vjs-video-notice-fadeOut");
|
||
notice.off(transitionEvent, hide);
|
||
};
|
||
notice.on(transitionEvent, hide);
|
||
}, options.autoHideNotice);
|
||
}
|
||
};
|
||
|
||
var plugin = function plugin() {
|
||
var settings = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
||
|
||
/**
|
||
* A video.js plugin.
|
||
*
|
||
* In the plugin function, the value of `this` is a video.js `Player`
|
||
* instance. You cannot rely on the player being in a "ready" state here,
|
||
* depending on how the plugin is invoked. This may or may not be important
|
||
* to you; if not, remove the wait for "ready"!
|
||
*
|
||
* @function panorama
|
||
* @param {Object} [options={}]
|
||
* An object of options left to the plugin author to define.
|
||
*/
|
||
var videoTypes = ["equirectangular", "fisheye", "3dVideo", "dual_fisheye"];
|
||
var panorama = function panorama(options) {
|
||
var _this = this;
|
||
|
||
if (settings.mergeOption) options = settings.mergeOption(defaults, options);
|
||
if (typeof settings._init === "undefined" || typeof settings._init !== "function") {
|
||
console.error("plugin must implement init function().");
|
||
return;
|
||
}
|
||
if (videoTypes.indexOf(options.videoType) == -1) options.videoType = defaults.videoType;
|
||
settings._init(options);
|
||
/* implement callback function when videojs is ready */
|
||
this.ready(function () {
|
||
onPlayerReady(_this, options, settings);
|
||
});
|
||
};
|
||
|
||
// Include the version number.
|
||
panorama.VERSION = '0.1.7';
|
||
|
||
return panorama;
|
||
};
|
||
|
||
exports.default = plugin;
|
||
|
||
},{"./lib/Detector":6,"./lib/Util":11,"iphone-inline-video":2}],14:[function(require,module,exports){
|
||
'use strict';
|
||
|
||
var _Canvas = require('./lib/Canvas');
|
||
|
||
var _Canvas2 = _interopRequireDefault(_Canvas);
|
||
|
||
var _ThreeCanvas = require('./lib/ThreeCanvas');
|
||
|
||
var _ThreeCanvas2 = _interopRequireDefault(_ThreeCanvas);
|
||
|
||
var _Notice = require('./lib/Notice');
|
||
|
||
var _Notice2 = _interopRequireDefault(_Notice);
|
||
|
||
var _HelperCanvas = require('./lib/HelperCanvas');
|
||
|
||
var _HelperCanvas2 = _interopRequireDefault(_HelperCanvas);
|
||
|
||
var _VRButton = require('./lib/VRButton');
|
||
|
||
var _VRButton2 = _interopRequireDefault(_VRButton);
|
||
|
||
var _plugin = require('./plugin');
|
||
|
||
var _plugin2 = _interopRequireDefault(_plugin);
|
||
|
||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||
|
||
function getTech(player) {
|
||
return player.tech({ IWillNotUseThisInPlugins: true }).el();
|
||
}
|
||
|
||
function getFullscreenToggleClickFn(player) {
|
||
return player.controlBar.fullscreenToggle.handleClick;
|
||
}
|
||
|
||
var component = videojs.getComponent('Component');
|
||
|
||
var notice = (0, _Notice2.default)(component);
|
||
videojs.registerComponent('Notice', videojs.extend(component, notice));
|
||
|
||
var helperCanvas = (0, _HelperCanvas2.default)(component);
|
||
videojs.registerComponent('HelperCanvas', videojs.extend(component, helperCanvas));
|
||
|
||
var button = videojs.getComponent("Button");
|
||
var vrBtn = (0, _VRButton2.default)(button);
|
||
videojs.registerComponent('VRButton', videojs.extend(button, vrBtn));
|
||
|
||
// Register the plugin with video.js.
|
||
videojs.plugin('panorama', (0, _plugin2.default)({
|
||
_init: function _init(options) {
|
||
var canvas = options.videoType !== "3dVideo" ? (0, _Canvas2.default)(component, window.THREE, {
|
||
getTech: getTech
|
||
}) : (0, _ThreeCanvas2.default)(component, window.THREE, {
|
||
getTech: getTech
|
||
});
|
||
videojs.registerComponent('Canvas', videojs.extend(component, canvas));
|
||
},
|
||
mergeOption: function mergeOption(defaults, options) {
|
||
return videojs.mergeOptions(defaults, options);
|
||
},
|
||
getTech: getTech,
|
||
getFullscreenToggleClickFn: getFullscreenToggleClickFn
|
||
}));
|
||
|
||
},{"./lib/Canvas":5,"./lib/HelperCanvas":7,"./lib/Notice":9,"./lib/ThreeCanvas":10,"./lib/VRButton":12,"./plugin":13}]},{},[14])
|
||
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJub2RlX21vZHVsZXMvaW50ZXJ2YWxvbWV0ZXIvZGlzdC9pbnRlcnZhbG9tZXRlci5jb21tb24tanMuanMiLCJub2RlX21vZHVsZXMvaXBob25lLWlubGluZS12aWRlby9kaXN0L2lwaG9uZS1pbmxpbmUtdmlkZW8uY29tbW9uLWpzLmpzIiwibm9kZV9tb2R1bGVzL3Bvb3ItbWFucy1zeW1ib2wvZGlzdC9wb29yLW1hbnMtc3ltYm9sLmNvbW1vbi1qcy5qcyIsInNyYy9zY3JpcHRzL2xpYi9CYXNlQ2FudmFzLmpzIiwic3JjL3NjcmlwdHMvbGliL0NhbnZhcy5qcyIsInNyYy9zY3JpcHRzL2xpYi9EZXRlY3Rvci5qcyIsInNyYy9zY3JpcHRzL2xpYi9IZWxwZXJDYW52YXMuanMiLCJzcmMvc2NyaXB0cy9saWIvTW9iaWxlQnVmZmVyaW5nLmpzIiwic3JjL3NjcmlwdHMvbGliL05vdGljZS5qcyIsInNyYy9zY3JpcHRzL2xpYi9UaHJlZUNhbnZhcy5qcyIsInNyYy9zY3JpcHRzL2xpYi9VdGlsLmpzIiwic3JjL3NjcmlwdHMvbGliL1ZSQnV0dG9uLmpzIiwic3JjL3NjcmlwdHMvcGx1Z2luLmpzIiwic3JjL3NjcmlwdHMvcGx1Z2luX3Y1LmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBO0FDQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2VUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDTkE7Ozs7Ozs7O0FBUUE7Ozs7OztBQUVBOzs7O0FBQ0E7Ozs7QUFDQTs7Ozs7O0FBRUEsSUFBTSxvQkFBb0IsQ0FBMUI7O0FBRUEsSUFBSSxhQUFhLFNBQWIsVUFBYSxDQUFVLGFBQVYsRUFBeUIsS0FBekIsRUFBK0M7QUFBQSxRQUFmLFFBQWUsdUVBQUosRUFBSTs7QUFDNUQsV0FBTztBQUNILHFCQUFhLFNBQVMsSUFBVCxD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QixFQUEwQyxRQUFRLE1BQVIsQ0FBZSxTQUFmLEVBQTBCLFlBQTFCLENBQTFDOztBQUVBLElBQUksU0FBUyxRQUFRLFlBQVIsQ0FBcUIsUUFBckIsQ0FBYjtBQUNBLElBQUksUUFBUSx3QkFBUyxNQUFULENBQVo7QUFDQSxRQUFRLGlCQUFSLENBQTBCLFVBQTFCLEVBQXNDLFFBQVEsTUFBUixDQUFlLE1BQWYsRUFBdUIsS0FBdkIsQ0FBdEM7O0FBRUE7QUFDQSxRQUFRLE1BQVIsQ0FBZSxVQUFmLEVBQTJCLHNCQUFTO0FBQ2hDLFdBQU8sZUFBUyxPQUFULEVBQWlCO0FBQ3BCLFlBQUksU0FBVSxRQUFRLFNBQVIsS0FBc0IsU0FBdkIsR0FDVCxzQkFBTyxTQUFQLEVBQWtCLE9BQU8sS0FBekIsRUFBZ0M7QUFDNUIscUJBQVM7QUFEbUIsU0FBaEMsQ0FEUyxHQUlULDJCQUFhLFNBQWIsRUFBd0IsT0FBTyxLQUEvQixFQUFzQztBQUNsQyxxQkFBUztBQUR5QixTQUF0QyxDQUpKO0FBT0EsZ0JBQVEsaUJBQVIsQ0FBMEIsUUFBMUIsRUFBb0MsUUFBUSxNQUFSLENBQWUsU0FBZixFQUEwQixNQUExQixDQUFwQztBQUNILEtBVitCO0FBV2hDLGlCQUFhLHFCQUFVLFFBQVYsRUFBb0IsT0FBcEIsRUFBNkI7QUFDdEMsZUFBTyxRQUFRLFlBQVIsQ0FBcUIsUUFBckIsRUFBK0IsT0FBL0IsQ0FBUDtBQUNILEtBYitCO0FBY2hDLGFBQVMsT0FkdUI7QUFlaEMsZ0NBQTRCO0FBZkksQ0FBVCxDQUEzQiIsImZpbGUiOiJnZW5lcmF0ZWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlc0NvbnRlbnQiOlsiKGZ1bmN0aW9uIGUodCxuLHIpe2Z1bmN0aW9uIHMobyx1KXtpZighbltvXSl7aWYoIXRbb10pe3ZhciBhPXR5cGVvZiByZXF1aXJlPT1cImZ1bmN0aW9uXCImJnJlcXVpcmU7aWYoIXUmJmEpcmV0dXJuIGEobywhMCk7aWYoaSlyZXR1cm4gaShvLCEwKTt2YXIgZj1uZXcgRXJyb3IoXCJDYW5ub3QgZmluZCBtb2R1bGUgJ1wiK28rXCInXCIpO3Rocm93IGYuY29kZT1cIk1PRFVMRV9OT1RfRk9VTkRcIixmfXZhciBsPW5bb109e2V4cG9ydHM6e319O3Rbb11bMF0uY2FsbChsLmV4cG9ydHMsZnVuY3Rpb24oZSl7dmFyIG49dFtvXVsxXVtlXTtyZXR1cm4gcyhuP246ZSl9LGwsbC5leHBvcnRzLGUsdCxuLHIpfXJldHVybiBuW29dLmV4cG9ydHN9dmFyIGk9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtmb3IodmFyIG89MDtvPHIubGVuZ3RoO28rKylzKHJbb10pO3JldHVybiBzfSkiLCIvKiEgbnBtLmltL2ludGVydmFsb21ldGVyICovXG4ndXNlIHN0cmljdCc7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAnX19lc01vZHVsZScsIHsgdmFsdWU6IHRydWUgfSk7XG5cbmZ1bmN0aW9uIGludGVydmFsb21ldGVyKGNiLCByZXF1ZXN0LCBjYW5jZWwsIHJlcXVlc3RQYXJhbWV0ZXIpIHtcblx0dmFyIHJlcXVlc3RJZDtcblx0dmFyIHByZXZpb3VzTG9vcFRpbWU7XG5cdGZ1bmN0aW9uIGxvb3Aobm93KSB7XG5cdFx0Ly8gbXVzdCBiZSByZXF1ZXN0ZWQgYmVmb3JlIGNiKCkgYmVjYXVzZSB0aGF0IG1pZ2h0IGNhbGwgLnN0b3AoKVxuXHRcdHJlcXVlc3RJZCA9IHJlcXVlc3QobG9vcCwgcmVxdWVzdFBhcmFtZXRlcik7XG5cblx0XHQvLyBjYWxsZWQgd2l0aCBcIm1zIHNpbmNlIGxhc3QgY2FsbFwiLiAwIG9uIHN0YXJ0KClcblx0XHRjYihub3cgLSAocHJldmlvdXNMb29wVGltZSB8fCBub3cpKTtcblxuXHRcdHByZXZpb3VzTG9vcFRpbWUgPSBub3c7XG5cdH1cblx0cmV0dXJuIHtcblx0XHRzdGFydDogZnVuY3Rpb24gc3RhcnQoKSB7XG5cdFx0XHRpZiAoIXJlcXVlc3RJZCkgeyAvLyBwcmV2ZW50IGRvdWJsZSBzdGFydHNcblx0XHRcdFx0bG9vcCgwKTtcblx0XHRcdH1cblx0XHR9LFxuXHRcdHN0b3A6IGZ1bmN0aW9uIHN0b3AoKSB7XG5cdFx0XHRjYW5jZWwocmVxdWVzdElkKTtcblx0XHRcdHJlcXVlc3RJZCA9IG51bGw7XG5cdFx0XHRwcmV2aW91c0xvb3BUaW1lID0gMDtcblx0XHR9XG5cdH07XG59XG5cbmZ1bmN0aW9uIGZyYW1lSW50ZXJ2YWxvbWV0ZXIoY2IpIHtcblx0cmV0dXJuIGludGVydmFsb21ldGVyKGNiLCByZXF1ZXN0QW5pbWF0aW9uRnJhbWUsIGNhbmNlbEFuaW1hdGlvbkZyYW1lKTtcbn1cblxuZnVuY3Rpb24gdGltZXJJbnRlcnZhbG9tZXRlcihjYiwgZGVsYXkpIHtcblx0cmV0dXJuIGludGVydmFsb21ldGVyKGNiLCBzZXRUaW1lb3V0LCBjbGVhclRpbWVvdXQsIGRlbGF5KTtcbn1cblxuZXhwb3J0cy5pbnRlcnZhbG9tZXRlciA9IGludGVydmFsb21ldGVyO1xuZXhwb3J0cy5mcmFtZUludGVydmFsb21ldGVyID0gZnJhbWVJbnRlcnZhbG9tZXRlcjtcbmV4cG9ydHMudGltZXJJbnRlcnZhbG9tZXRlciA9IHRpbWVySW50ZXJ2YWxvbWV0ZXI7IiwiLyohIG5wbS5pbS9pcGhvbmUtaW5saW5lLXZpZGVvICovXG4ndXNlIHN0cmljdCc7XG5cbmZ1bmN0aW9uIF9pbnRlcm9wRGVmYXVsdCAoZXgpIHsgcmV0dXJuIChleCAmJiAodHlwZW9mIGV4ID09PSAnb2JqZWN0JykgJiYgJ2RlZmF1bHQnIGluIGV4KSA/IGV4WydkZWZhdWx0J10gOiBleDsgfVxuXG52YXIgU3ltYm9sID0gX2ludGVyb3BEZWZhdWx0KHJlcXVpcmUoJ3Bvb3ItbWFucy1zeW1ib2wnKSk7XG52YXIgaW50ZXJ2YWxvbWV0ZXIgPSByZXF1aXJlKCdpbnRlcnZhbG9tZXRlcicpO1xuXG5mdW5jdGlvbiBwcmV2ZW50RXZlbnQoZWxlbWVudCwgZXZlbnROYW1lLCB0b2dnbGVQcm9wZXJ0eSwgcHJldmVudFdpdGhQcm9wZXJ0eSkge1xuXHRmdW5jdGlvbiBoYW5kbGVyKGUpIHtcblx0XHRpZiAoQm9vbGVhbihlbGVtZW50W3RvZ2dsZVByb3BlcnR5XSkgPT09IEJvb2xlYW4ocHJldmVudFdpdGhQcm9wZXJ0eSkpIHtcblx0XHRcdGUuc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uKCk7XG5cdFx0XHQvLyBjb25zb2xlLmxvZyhldmVudE5hbWUsICdwcmV2ZW50ZWQgb24nLCBlbGVtZW50KTtcblx0XHR9XG5cdFx0ZGVsZXRlIGVsZW1lbnRbdG9nZ2xlUHJvcGVydHldO1xuXHR9XG5cdGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihldmVudE5hbWUsIGhhbmRsZXIsIGZhbHNlKTtcblxuXHQvLyBSZXR1cm4gaGFuZGxlciB0byBhbGxvdyB0byBkaXNhYmxlIHRoZSBwcmV2ZW50aW9uLiBVc2FnZTpcblx0Ly8gY29uc3QgcHJldmVudGlvbkhhbmRsZXIgPSBwcmV2ZW50RXZlbnQoZWwsICdjbGljaycpO1xuXHQvLyBlbC5yZW1vdmVFdmVudEhhbmRsZXIoJ2NsaWNrJywgcHJldmVudGlvbkhhbmRsZXIpO1xuXHRyZXR1cm4gaGFuZGxlcjtcbn1cblxuZnVuY3Rpb24gcHJveHlQcm9wZXJ0eShvYmplY3QsIHByb3BlcnR5TmFtZSwgc291cmNlT2JqZWN0LCBjb3B5Rmlyc3QpIHtcblx0ZnVuY3Rpb24gZ2V0KCkge1xuXHRcdHJldHVybiBzb3VyY2VPYmplY3RbcHJvcGVydHlOYW1lXTtcblx0fVxuXHRmdW5jdGlvbiBzZXQodmFsdWUpIHtcblx0XHRzb3VyY2VPYmplY3RbcHJvcGVydHlOYW1lXSA9IHZhbHVlO1xuXHR9XG5cblx0aWYgKGNvcHlGaXJzdCkge1xuXHRcdHNldChvYmplY3RbcHJvcGVydHlOYW1lXSk7XG5cdH1cblxuXHRPYmplY3QuZGVmaW5lUHJvcGVydHkob2JqZWN0LCBwcm9wZXJ0eU5hbWUsIHtnZXQ6IGdldCwgc2V0OiBzZXR9KTtcbn1cblxuZnVuY3Rpb24gcHJveHlFdmVudChvYmplY3QsIGV2ZW50TmFtZSwgc291cmNlT2JqZWN0KSB7XG5cdHNvdXJjZU9iamVjdC5hZGRFdmVudExpc3RlbmVyKGV2ZW50TmFtZSwgZnVuY3Rpb24gKCkgeyByZXR1cm4gb2JqZWN0LmRpc3BhdGNoRXZlbnQobmV3IEV2ZW50KGV2ZW50TmFtZSkpOyB9KTtcbn1cblxuZnVuY3Rpb24gZGlzcGF0Y2hFdmVudEFzeW5jKGVsZW1lbnQsIHR5cGUpIHtcblx0UHJvbWlzZS5yZXNvbHZlKCkudGhlbihmdW5jdGlvbiAoKSB7XG5cdFx0ZWxlbWVudC5kaXNwYXRjaEV2ZW50KG5ldyBFdmVudCh0eXBlKSk7XG5cdH0pO1xufVxuXG4vLyBpT1MgMTAgYWRkcyBzdXBwb3J0IGZvciBuYXRpdmUgaW5saW5lIHBsYXliYWNrICsgc2lsZW50IGF1dG9wbGF5XG52YXIgaXNXaGl0ZWxpc3RlZCA9ICdvYmplY3QtZml0JyBpbiBkb2N1bWVudC5oZWFkLnN0eWxlICYmIC9pUGhvbmV8aVBvZC9pLnRlc3QobmF2aWdhdG9yLnVzZXJBZ2VudCkgJiYgIW1hdGNoTWVkaWEoJygtd2Via2l0LXZpZGVvLXBsYXlhYmxlLWlubGluZSknKS5tYXRjaGVzO1xuXG52YXIg4LKgID0gU3ltYm9sKCk7XG52YXIg4LKgZXZlbnQgPSBTeW1ib2woKTtcbnZhciDgsqBwbGF5ID0gU3ltYm9sKCduYXRpdmVwbGF5Jyk7XG52YXIg4LKgcGF1c2UgPSBTeW1ib2woJ25hdGl2ZXBhdXNlJyk7XG5cbi8qKlxuICogVVRJTFNcbiAqL1xuXG5mdW5jdGlvbiBnZXRBdWRpb0Zyb21WaWRlbyh2aWRlbykge1xuXHR2YXIgYXVkaW8gPSBuZXcgQXVkaW8oKTtcblx0cHJveHlFdmVudCh2aWRlbywgJ3BsYXknLCBhdWRpbyk7XG5cdHByb3h5RXZlbnQodmlkZW8sICdwbGF5aW5nJywgYXVkaW8pO1xuXHRwcm94eUV2ZW50KHZpZGVvLCAncGF1c2UnLCBhdWRpbyk7XG5cdGF1ZGlvLmNyb3NzT3JpZ2luID0gdmlkZW8uY3Jvc3NPcmlnaW47XG5cblx0Ly8gJ2RhdGE6JyBjYXVzZXMgYXVkaW8ubmV0d29ya1N0YXRlID4gMFxuXHQvLyB3aGljaCB0aGVuIGFsbG93cyB0byBrZWVwIDxhdWRpbz4gaW4gYSByZXN1bWFibGUgcGxheWluZyBzdGF0ZVxuXHQvLyBpLmUuIG9uY2UgeW91IHNldCBhIHJlYWwgc3JjIGl0IHdpbGwga2VlcCBwbGF5aW5nIGlmIGl0IHdhcyBpZiAucGxheSgpIHdhcyBjYWxsZWRcblx0YXVkaW8uc3JjID0gdmlkZW8uc3JjIHx8IHZpZGVvLmN1cnJlbnRTcmMgfHwgJ2RhdGE6JztcblxuXHQvLyBpZiAoYXVkaW8uc3JjID09PSAnZGF0YTonKSB7XG5cdC8vICAgVE9ETzogd2FpdCBmb3IgdmlkZW8gdG8gYmUgc2VsZWN0ZWRcblx0Ly8gfVxuXHRyZXR1cm4gYXVkaW87XG59XG5cbnZhciBsYXN0UmVxdWVzdHMgPSBbXTtcbnZhciByZXF1ZXN0SW5kZXggPSAwO1xudmFyIGxhc3RUaW1ldXBkYXRlRXZlbnQ7XG5cbmZ1bmN0aW9uIHNldFRpbWUodmlkZW8sIHRpbWUsIHJlbWVtYmVyT25seSkge1xuXHQvLyBhbGxvdyBvbmUgdGltZXVwZGF0ZSBldmVudCBldmVyeSAyMDArIG1zXG5cdGlmICgobGFzdFRpbWV1cGRhdGVFdmVudCB8fCAwKSArIDIwMCA8IERhdGUubm93KCkpIHtcblx0XHR2aWRlb1vgsqBldmVudF0gPSB0cnVlO1xuXHRcdGxhc3RUaW1ldXBkYXRlRXZlbnQgPSBEYXRlLm5vdygpO1xuXHR9XG5cdGlmICghcmVtZW1iZXJPbmx5KSB7XG5cdFx0dmlkZW8uY3VycmVudFRpbWUgPSB0aW1lO1xuXHR9XG5cdGxhc3RSZXF1ZXN0c1srK3JlcXVlc3RJbmRleCAlIDNdID0gdGltZSAqIDEwMCB8IDAgLyAxMDA7XG59XG5cbmZ1bmN0aW9uIGlzUGxheWVyRW5kZWQocGxheWVyKSB7XG5cdHJldHVybiBwbGF5ZXIuZHJpdmVyLmN1cnJlbnRUaW1lID49IHBsYXllci52aWRlby5kdXJhdGlvbjtcbn1cblxuZnVuY3Rpb24gdXBkYXRlKHRpbWVEaWZmKSB7XG5cdHZhciBwbGF5ZXIgPSB0aGlzO1xuXHQvLyBjb25zb2xlLmxvZygndXBkYXRlJywgcGxheWVyLnZpZGVvLnJlYWR5U3RhdGUsIHBsYXllci52aWRlby5uZXR3b3JrU3RhdGUsIHBsYXllci5kcml2ZXIucmVhZHlTdGF0ZSwgcGxheWVyLmRyaXZlci5uZXR3b3JrU3RhdGUsIHBsYXllci5kcml2ZXIucGF1c2VkKTtcblx0aWYgKHBsYXllci52aWRlby5yZWFkeVN0YXRlID49IHBsYXllci52aWRlby5IQVZFX0ZVVFVSRV9EQVRBKSB7XG5cdFx0aWYgKCFwbGF5ZXIuaGFzQXVkaW8pIHtcblx0XHRcdHBsYXllci5kcml2ZXIuY3VycmVudFRpbWUgPSBwbGF5ZXIudmlkZW8uY3VycmVudFRpbWUgKyAoKHRpbWVEaWZmICogcGxheWVyLnZpZGVvLnBsYXliYWNrUmF0ZSkgLyAxMDAwKTtcblx0XHRcdGlmIChwbGF5ZXIudmlkZW8ubG9vcCAmJiBpc1BsYXllckVuZGVkKHBsYXllcikpIHtcblx0XHRcdFx0cGxheWVyLmRyaXZlci5jdXJyZW50VGltZSA9IDA7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHNldFRpbWUocGxheWVyLnZpZGVvLCBwbGF5ZXIuZHJpdmVyLmN1cnJlbnRUaW1lKTtcblx0fSBlbHNlIGlmIChwbGF5ZXIudmlkZW8ubmV0d29ya1N0YXRlID09PSBwbGF5ZXIudmlkZW8uTkVUV09SS19JRExFICYmICFwbGF5ZXIudmlkZW8uYnVmZmVyZWQubGVuZ3RoKSB7XG5cdFx0Ly8gdGhpcyBzaG91bGQgaGFwcGVuIHdoZW4gdGhlIHNvdXJjZSBpcyBhdmFpbGFibGUgYnV0OlxuXHRcdC8vIC0gaXQncyBwb3RlbnRpYWxseSBwbGF5aW5nICgucGF1c2VkID09PSBmYWxzZSlcblx0XHQvLyAtIGl0J3Mgbm90IHJlYWR5IHRvIHBsYXlcblx0XHQvLyAtIGl0J3Mgbm90IGxvYWRpbmdcblx0XHQvLyBJZiBpdCBoYXNBdWRpbywgdGhhdCB3aWxsIGJlIGxvYWRlZCBpbiB0aGUgJ2VtcHRpZWQnIGhhbmRsZXIgYmVsb3dcblx0XHRwbGF5ZXIudmlkZW8ubG9hZCgpO1xuXHRcdC8vIGNvbnNvbGUubG9nKCdXaWxsIGxvYWQnKTtcblx0fVxuXG5cdC8vIGNvbnNvbGUuYXNzZXJ0KHBsYXllci52aWRlby5jdXJyZW50VGltZSA9PT0gcGxheWVyLmRyaXZlci5jdXJyZW50VGltZSwgJ1ZpZGVvIG5vdCB1cGRhdGluZyEnKTtcblxuXHRpZiAocGxheWVyLnZpZGVvLmVuZGVkKSB7XG5cdFx0ZGVsZXRlIHBsYXllci52aWRlb1vgsqBldmVudF07IC8vIGFsbG93IHRpbWV1cGRhdGUgZXZlbnRcblx0XHRwbGF5ZXIudmlkZW8ucGF1c2UodHJ1ZSk7XG5cdH1cbn1cblxuLyoqXG4gKiBNRVRIT0RTXG4gKi9cblxuZnVuY3Rpb24gcGxheSgpIHtcblx0Ly8gY29uc29sZS5sb2coJ3BsYXknKTtcblx0dmFyIHZpZGVvID0gdGhpcztcblx0dmFyIHBsYXllciA9IHZpZGVvW+CyoF07XG5cblx0Ly8gaWYgaXQncyBmdWxsc2NyZWVuLCB1c2UgdGhlIG5hdGl2ZSBwbGF5ZXJcblx0aWYgKHZpZGVvLndlYmtpdERpc3BsYXlpbmdGdWxsc2NyZWVuKSB7XG5cdFx0dmlkZW9b4LKgcGxheV0oKTtcblx0XHRyZXR1cm47XG5cdH1cblxuXHRpZiAocGxheWVyLmRyaXZlci5zcmMgIT09ICdkYXRhOicgJiYgcGxheWVyLmRyaXZlci5zcmMgIT09IHZpZGVvLnNyYykge1xuXHRcdC8vIGNvbnNvbGUubG9nKCdzcmMgY2hhbmdlZCBvbiBwbGF5JywgdmlkZW8uc3JjKTtcblx0XHRzZXRUaW1lKHZpZGVvLCAwLCB0cnVlKTtcblx0XHRwbGF5ZXIuZHJpdmVyLnNyYyA9IHZpZGVvLnNyYztcblx0fVxuXG5cdGlmICghdmlkZW8ucGF1c2VkKSB7XG5cdFx0cmV0dXJuO1xuXHR9XG5cdHBsYXllci5wYXVzZWQgPSBmYWxzZTtcblxuXHRpZiAoIXZpZGVvLmJ1ZmZlcmVkLmxlbmd0aCkge1xuXHRcdC8vIC5sb2FkKCkgY2F1c2VzIHRoZSBlbXB0aWVkIGV2ZW50XG5cdFx0Ly8gdGhlIGFsdGVybmF0aXZlIGlzIC5wbGF5KCkrLnBhdXNlKCkgYnV0IHRoYXQgdHJpZ2dlcnMgcGxheS9wYXVzZSBldmVudHMsIGV2ZW4gd29yc2Vcblx0XHQvLyBwb3NzaWJseSB0aGUgYWx0ZXJuYXRpdmUgaXMgcHJldmVudGluZyB0aGlzIGV2ZW50IG9ubHkgb25jZVxuXHRcdHZpZGVvLmxvYWQoKTtcblx0fVxuXG5cdHBsYXllci5kcml2ZXIucGxheSgpO1xuXHRwbGF5ZXIudXBkYXRlci5zdGFydCgpO1xuXG5cdGlmICghcGxheWVyLmhhc0F1ZGlvKSB7XG5cdFx0ZGlzcGF0Y2hFdmVudEFzeW5jKHZpZGVvLCAncGxheScpO1xuXHRcdGlmIChwbGF5ZXIudmlkZW8ucmVhZHlTdGF0ZSA+PSBwbGF5ZXIudmlkZW8uSEFWRV9FTk9VR0hfREFUQSkge1xuXHRcdFx0Ly8gY29uc29sZS5sb2coJ29ucGxheScpO1xuXHRcdFx0ZGlzcGF0Y2hFdmVudEFzeW5jKHZpZGVvLCAncGxheWluZycpO1xuXHRcdH1cblx0fVxufVxuZnVuY3Rpb24gcGF1c2UoZm9yY2VFdmVudHMpIHtcblx0Ly8gY29uc29sZS5sb2coJ3BhdXNlJyk7XG5cdHZhciB2aWRlbyA9IHRoaXM7XG5cdHZhciBwbGF5ZXIgPSB2aWRlb1vgsqBdO1xuXG5cdHBsYXllci5kcml2ZXIucGF1c2UoKTtcblx0cGxheWVyLnVwZGF0ZXIuc3RvcCgpO1xuXG5cdC8vIGlmIGl0J3MgZnVsbHNjcmVlbiwgdGhlIGRldmVsb3BlciB0aGUgbmF0aXZlIHBsYXllci5wYXVzZSgpXG5cdC8vIFRoaXMgaXMgYXQgdGhlIGVuZCBvZiBwYXVzZSgpIGJlY2F1c2UgaXQgYWxzb1xuXHQvLyBuZWVkcyB0byBtYWtlIHN1cmUgdGhhdCB0aGUgc2ltdWxhdGlvbiBpcyBwYXVzZWRcblx0aWYgKHZpZGVvLndlYmtpdERpc3BsYXlpbmdGdWxsc2NyZWVuKSB7XG5cdFx0dmlkZW9b4LKgcGF1c2VdKCk7XG5cdH1cblxuXHRpZiAocGxheWVyLnBhdXNlZCAmJiAhZm9yY2VFdmVudHMpIHtcblx0XHRyZXR1cm47XG5cdH1cblxuXHRwbGF5ZXIucGF1c2VkID0gdHJ1ZTtcblx0aWYgKCFwbGF5ZXIuaGFzQXVkaW8pIHtcblx0XHRkaXNwYXRjaEV2ZW50QXN5bmModmlkZW8sICdwYXVzZScpO1xuXHR9XG5cdGlmICh2aWRlby5lbmRlZCkge1xuXHRcdHZpZGVvW+CyoGV2ZW50XSA9IHRydWU7XG5cdFx0ZGlzcGF0Y2hFdmVudEFzeW5jKHZpZGVvLCAnZW5kZWQnKTtcblx0fVxufVxuXG4vKipcbiAqIFNFVFVQXG4gKi9cblxuZnVuY3Rpb24gYWRkUGxheWVyKHZpZGVvLCBoYXNBdWRpbykge1xuXHR2YXIgcGxheWVyID0gdmlkZW9b4LKgXSA9IHt9O1xuXHRwbGF5ZXIucGF1c2VkID0gdHJ1ZTsgLy8gdHJhY2sgd2hldGhlciAncGF1c2UnIGV2ZW50cyBoYXZlIGJlZW4gZmlyZWRcblx0cGxheWVyLmhhc0F1ZGlvID0gaGFzQXVkaW87XG5cdHBsYXllci52aWRlbyA9IHZpZGVvO1xuXHRwbGF5ZXIudXBkYXRlciA9IGludGVydmFsb21ldGVyLmZyYW1lSW50ZXJ2YWxvbWV0ZXIodXBkYXRlLmJpbmQocGxheWVyKSk7XG5cblx0aWYgKGhhc0F1ZGlvKSB7XG5cdFx0cGxheWVyLmRyaXZlciA9IGdldEF1ZGlvRnJvbVZpZGVvKHZpZGVvKTtcblx0fSBlbHNlIHtcblx0XHR2aWRlby5hZGRFdmVudExpc3RlbmVyKCdjYW5wbGF5JywgZnVuY3Rpb24gKCkge1xuXHRcdFx0aWYgKCF2aWRlby5wYXVzZWQpIHtcblx0XHRcdFx0Ly8gY29uc29sZS5sb2coJ29uY2FucGxheScpO1xuXHRcdFx0XHRkaXNwYXRjaEV2ZW50QXN5bmModmlkZW8sICdwbGF5aW5nJyk7XG5cdFx0XHR9XG5cdFx0fSk7XG5cdFx0cGxheWVyLmRyaXZlciA9IHtcblx0XHRcdHNyYzogdmlkZW8uc3JjIHx8IHZpZGVvLmN1cnJlbnRTcmMgfHwgJ2RhdGE6Jyxcblx0XHRcdG11dGVkOiB0cnVlLFxuXHRcdFx0cGF1c2VkOiB0cnVlLFxuXHRcdFx0cGF1c2U6IGZ1bmN0aW9uICgpIHtcblx0XHRcdFx0cGxheWVyLmRyaXZlci5wYXVzZWQgPSB0cnVlO1xuXHRcdFx0fSxcblx0XHRcdHBsYXk6IGZ1bmN0aW9uICgpIHtcblx0XHRcdFx0cGxheWVyLmRyaXZlci5wYXVzZWQgPSBmYWxzZTtcblx0XHRcdFx0Ly8gbWVkaWEgYXV0b21hdGljYWxseSBnb2VzIHRvIDAgaWYgLnBsYXkoKSBpcyBjYWxsZWQgd2hlbiBpdCdzIGRvbmVcblx0XHRcdFx0aWYgKGlzUGxheWVyRW5kZWQocGxheWVyKSkge1xuXHRcdFx0XHRcdHNldFRpbWUodmlkZW8sIDApO1xuXHRcdFx0XHR9XG5cdFx0XHR9LFxuXHRcdFx0Z2V0IGVuZGVkKCkge1xuXHRcdFx0XHRyZXR1cm4gaXNQbGF5ZXJFbmRlZChwbGF5ZXIpO1xuXHRcdFx0fVxuXHRcdH07XG5cdH1cblxuXHQvLyAubG9hZCgpIGNhdXNlcyB0aGUgZW1wdGllZCBldmVudFxuXHR2aWRlby5hZGRFdmVudExpc3RlbmVyKCdlbXB0aWVkJywgZnVuY3Rpb24gKCkge1xuXHRcdC8vIGNvbnNvbGUubG9nKCdkcml2ZXIgc3JjIGlzJywgcGxheWVyLmRyaXZlci5zcmMpO1xuXHRcdHZhciB3YXNFbXB0eSA9ICFwbGF5ZXIuZHJpdmVyLnNyYyB8fCBwbGF5ZXIuZHJpdmVyLnNyYyA9PT0gJ2RhdGE6Jztcblx0XHRpZiAocGxheWVyLmRyaXZlci5zcmMgJiYgcGxheWVyLmRyaXZlci5zcmMgIT09IHZpZGVvLnNyYykge1xuXHRcdFx0Ly8gY29uc29sZS5sb2coJ3NyYyBjaGFuZ2VkIHRvJywgdmlkZW8uc3JjKTtcblx0XHRcdHNldFRpbWUodmlkZW8sIDAsIHRydWUpO1xuXHRcdFx0cGxheWVyLmRyaXZlci5zcmMgPSB2aWRlby5zcmM7XG5cdFx0XHQvLyBwbGF5aW5nIHZpZGVvcyB3aWxsIG9ubHkga2VlcCBwbGF5aW5nIGlmIG5vIHNyYyB3YXMgcHJlc2VudCB3aGVuIC5wbGF5KCnigJllZFxuXHRcdFx0aWYgKHdhc0VtcHR5KSB7XG5cdFx0XHRcdHBsYXllci5kcml2ZXIucGxheSgpO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0cGxheWVyLnVwZGF0ZXIuc3RvcCgpO1xuXHRcdFx0fVxuXHRcdH1cblx0fSwgZmFsc2UpO1xuXG5cdC8vIHN0b3AgcHJvZ3JhbW1hdGljIHBsYXllciB3aGVuIE9TIHRha2VzIG92ZXJcblx0dmlkZW8uYWRkRXZlbnRMaXN0ZW5lcignd2Via2l0YmVnaW5mdWxsc2NyZWVuJywgZnVuY3Rpb24gKCkge1xuXHRcdGlmICghdmlkZW8ucGF1c2VkKSB7XG5cdFx0XHQvLyBtYWtlIHN1cmUgdGhhdCB0aGUgPGF1ZGlvPiBhbmQgdGhlIHN5bmNlci91cGRhdGVyIGFyZSBzdG9wcGVkXG5cdFx0XHR2aWRlby5wYXVzZSgpO1xuXG5cdFx0XHQvLyBwbGF5IHZpZGVvIG5hdGl2ZWx5XG5cdFx0XHR2aWRlb1vgsqBwbGF5XSgpO1xuXHRcdH0gZWxzZSBpZiAoaGFzQXVkaW8gJiYgIXBsYXllci5kcml2ZXIuYnVmZmVyZWQubGVuZ3RoKSB7XG5cdFx0XHQvLyBpZiB0aGUgZmlyc3QgcGxheSBpcyBuYXRpdmUsXG5cdFx0XHQvLyB0aGUgPGF1ZGlvPiBuZWVkcyB0byBiZSBidWZmZXJlZCBtYW51YWxseVxuXHRcdFx0Ly8gc28gd2hlbiB0aGUgZnVsbHNjcmVlbiBlbmRzLCBpdCBjYW4gYmUgc2V0IHRvIHRoZSBzYW1lIGN1cnJlbnQgdGltZVxuXHRcdFx0cGxheWVyLmRyaXZlci5sb2FkKCk7XG5cdFx0fVxuXHR9KTtcblx0aWYgKGhhc0F1ZGlvKSB7XG5cdFx0dmlkZW8uYWRkRXZlbnRMaXN0ZW5lcignd2Via2l0ZW5kZnVsbHNjcmVlbicsIGZ1bmN0aW9uICgpIHtcblx0XHRcdC8vIHN5bmMgYXVkaW8gdG8gbmV3IHZpZGVvIHBvc2l0aW9uXG5cdFx0XHRwbGF5ZXIuZHJpdmVyLmN1cnJlbnRUaW1lID0gdmlkZW8uY3VycmVudFRpbWU7XG5cdFx0XHQvLyBjb25zb2xlLmFzc2VydChwbGF5ZXIuZHJpdmVyLmN1cnJlbnRUaW1lID09PSB2aWRlby5jdXJyZW50VGltZSwgJ0F1ZGlvIG5vdCBzeW5jZWQnKTtcblx0XHR9KTtcblxuXHRcdC8vIGFsbG93IHNlZWtpbmdcblx0XHR2aWRlby5hZGRFdmVudExpc3RlbmVyKCdzZWVraW5nJywgZnVuY3Rpb24gKCkge1xuXHRcdFx0aWYgKGxhc3RSZXF1ZXN0cy5pbmRleE9mKHZpZGVvLmN1cnJlbnRUaW1lICogMTAwIHwgMCAvIDEwMCkgPCAwKSB7XG5cdFx0XHRcdC8vIGNvbnNvbGUubG9nKCdVc2VyLXJlcXVlc3RlZCBzZWVraW5nJyk7XG5cdFx0XHRcdHBsYXllci5kcml2ZXIuY3VycmVudFRpbWUgPSB2aWRlby5jdXJyZW50VGltZTtcblx0XHRcdH1cblx0XHR9KTtcblx0fVxufVxuXG5mdW5jdGlvbiBvdmVybG9hZEFQSSh2aWRlbykge1xuXHR2YXIgcGxheWVyID0gdmlkZW9b4LKgXTtcblx0dmlkZW9b4LKgcGxheV0gPSB2aWRlby5wbGF5O1xuXHR2aWRlb1vgsqBwYXVzZV0gPSB2aWRlby5wYXVzZTtcblx0dmlkZW8ucGxheSA9IHBsYXk7XG5cdHZpZGVvLnBhdXNlID0gcGF1c2U7XG5cdHByb3h5UHJvcGVydHkodmlkZW8sICdwYXVzZWQnLCBwbGF5ZXIuZHJpdmVyKTtcblx0cHJveHlQcm9wZXJ0eSh2aWRlbywgJ211dGVkJywgcGxheWVyLmRyaXZlciwgdHJ1ZSk7XG5cdHByb3h5UHJvcGVydHkodmlkZW8sICdwbGF5YmFja1JhdGUnLCBwbGF5ZXIuZHJpdmVyLCB0cnVlKTtcblx0cHJveHlQcm9wZXJ0eSh2aWRlbywgJ2VuZGVkJywgcGxheWVyLmRyaXZlcik7XG5cdHByb3h5UHJvcGVydHkodmlkZW8sICdsb29wJywgcGxheWVyLmRyaXZlciwgdHJ1ZSk7XG5cdHByZXZlbnRFdmVudCh2aWRlbywgJ3NlZWtpbmcnKTtcblx0cHJldmVudEV2ZW50KHZpZGVvLCAnc2Vla2VkJyk7XG5cdHByZXZlbnRFdmVudCh2aWRlbywgJ3RpbWV1cGRhdGUnLCDgsqBldmVudCwgZmFsc2UpO1xuXHRwcmV2ZW50RXZlbnQodmlkZW8sICdlbmRlZCcsIOCyoGV2ZW50LCBmYWxzZSk7IC8vIHByZXZlbnQgb2NjYXNpb25hbCBuYXRpdmUgZW5kZWQgZXZlbnRzXG59XG5cbmZ1bmN0aW9uIGVuYWJsZUlubGluZVZpZGVvKHZpZGVvLCBoYXNBdWRpbywgb25seVdoaXRlbGlzdGVkKSB7XG5cdGlmICggaGFzQXVkaW8gPT09IHZvaWQgMCApIGhhc0F1ZGlvID0gdHJ1ZTtcblx0aWYgKCBvbmx5V2hpdGVsaXN0ZWQgPT09IHZvaWQgMCApIG9ubHlXaGl0ZWxpc3RlZCA9IHRydWU7XG5cblx0aWYgKChvbmx5V2hpdGVsaXN0ZWQgJiYgIWlzV2hpdGVsaXN0ZWQpIHx8IHZpZGVvW+CyoF0pIHtcblx0XHRyZXR1cm47XG5cdH1cblx0YWRkUGxheWVyKHZpZGVvLCBoYXNBdWRpbyk7XG5cdG92ZXJsb2FkQVBJKHZpZGVvKTtcblx0dmlkZW8uY2xhc3NMaXN0LmFkZCgnSUlWJyk7XG5cdGlmICghaGFzQXVkaW8gJiYgdmlkZW8uYXV0b3BsYXkpIHtcblx0XHR2aWRlby5wbGF5KCk7XG5cdH1cblx0aWYgKCEvaVBob25lfGlQb2R8aVBhZC8udGVzdChuYXZpZ2F0b3IucGxhdGZvcm0pKSB7XG5cdFx0Y29uc29sZS53YXJuKCdpcGhvbmUtaW5saW5lLXZpZGVvIGlzIG5vdCBndWFyYW50ZWVkIHRvIHdvcmsgaW4gZW11bGF0ZWQgZW52aXJvbm1lbnRzJyk7XG5cdH1cbn1cblxuZW5hYmxlSW5saW5lVmlkZW8uaXNXaGl0ZWxpc3RlZCA9IGlzV2hpdGVsaXN0ZWQ7XG5cbm1vZHVsZS5leHBvcnRzID0gZW5hYmxlSW5saW5lVmlkZW87IiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgaW5kZXggPSB0eXBlb2YgU3ltYm9sID09PSAndW5kZWZpbmVkJyA/IGZ1bmN0aW9uIChkZXNjcmlwdGlvbikge1xuXHRyZXR1cm4gJ0AnICsgKGRlc2NyaXB0aW9uIHx8ICdAJykgKyBNYXRoLnJhbmRvbSgpO1xufSA6IFN5bWJvbDtcblxubW9kdWxlLmV4cG9ydHMgPSBpbmRleDsiLCIvKipcbiAqXG4gKiAoYykgV2Vuc2hlbmcgWWFuIDx5YW53c2hAZ21haWwuY29tPlxuICogRGF0ZTogMTAvMzAvMTZcbiAqXG4gKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRVxuICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuXG4gKi9cbid1c2Ugc3RyaWN0JztcblxuaW1wb3J0IERldGVjdG9yIGZyb20gJy4uL2xpYi9EZXRlY3Rvcic7XG5pbXBvcnQgTW9iaWxlQnVmZmVyaW5nIGZyb20gJy4uL2xpYi9Nb2JpbGVCdWZmZXJpbmcnO1xuaW1wb3J0IFV0aWwgZnJvbSAnLi4vbGliL1V0aWwnO1xuXG5jb25zdCBIQVZFX0NVUlJFTlRfREFUQSA9IDI7XG5cbnZhciBCYXNlQ2FudmFzID0gZnVuY3Rpb24gKGJhc2VDb21wb25lbnQsIFRIUkVFLCBzZXR0aW5ncyA9IHt9KSB7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgY29uc3RydWN0b3I6IGZ1bmN0aW9uIGluaXQocGxheWVyLCBvcHRpb25zKXtcbiAgICAgICAgICAgIHRoaXMuc2V0dGluZ3MgPSBvcHRpb25zO1xuICAgICAgICAgICAgLy9iYXNpYyBzZXR0aW5nc1xuICAgICAgICAgICAgdGhpcy53aWR0aCA9IHBsYXllci5lbCgpLm9mZnNldFdpZHRoLCB0aGlzLmhlaWdodCA9IHBsYXllci5lbCgpLm9mZnNldEhlaWdodDtcbiAgICAgICAgICAgIHRoaXMubG9uID0gb3B0aW9ucy5pbml0TG9uLCB0aGlzLmxhdCA9IG9wdGlvbnMuaW5pdExhdCwgdGhpcy5waGkgPSAwLCB0aGlzLnRoZXRhID0gMDtcbiAgICAgICAgICAgIHRoaXMudmlkZW9UeXBlID0gb3B0aW9ucy52aWRlb1R5cGU7XG4gICAgICAgICAgICB0aGlzLmNsaWNrVG9Ub2dnbGUgPSBvcHRpb25zLmNsaWNrVG9Ub2dnbGU7XG4gICAgICAgICAgICB0aGlzLm1vdXNlRG93biA9IGZhbHNlO1xuICAgICAgICAgICAgdGhpcy5pc1VzZXJJbnRlcmFjdGluZyA9IGZhbHNlO1xuXG4gICAgICAgICAgICAvL2RlZmluZSByZW5kZXJcbiAgICAgICAgICAgIHRoaXMucmVuZGVyZXIgPSBuZXcgVEhSRUUuV2ViR0xSZW5kZXJlcigpO1xuICAgICAgICAgICAgdGhpcy5yZW5kZXJlci5zZXRQaXhlbFJhdGlvKHdpbmRvdy5kZXZpY2VQaXhlbFJhdGlvKTtcbiAgICAgICAgICAgIHRoaXMucmVuZGVyZXIuc2V0U2l6ZSh0aGlzLndpZHRoLCB0aGlzLmhlaWdodCk7XG4gICAgICAgICAgICB0aGlzLnJlbmRlcmVyLmF1dG9DbGVhciA9IGZhbHNlO1xuICAgICAgICAgICAgdGhpcy5yZW5kZXJlci5zZXRDbGVhckNvbG9yKDB4MDAwMDAwLCAxKTtcblxuICAgICAgICAgICAgLy9kZWZpbmUgdGV4dHVyZSwgb24gaWUgMTEsIHdlIG5lZWQgYWRkaXRpb25hbCBoZWxwZXIgY2FudmFzIHRvIHNvbHZlIHJlbmRlcmluZyBpc3N1ZS5cbiAgICAgICAgICAgIHZhciB2aWRlbyA9IHNldHRpbmdzLmdldFRlY2gocGxheWVyKTtcbiAgICAgICAgICAgIHRoaXMuc3VwcG9ydFZpZGVvVGV4dHVyZSA9IERldGVjdG9yLnN1cHBvcnRWaWRlb1RleHR1cmUoKTtcbiAgICAgICAgICAgIHRoaXMubGl2ZVN0cmVhbU9uU2FmYXJpID0gRGV0ZWN0b3IuaXNMaXZlU3RyZWFtT25TYWZhcmkodmlkZW8pO1xuICAgICAgICAgICAgaWYodGhpcy5saXZlU3RyZWFtT25TYWZhcmkpIHRoaXMuc3VwcG9ydFZpZGVvVGV4dHVyZSA9IGZhbHNlO1xuICAgICAgICAgICAgaWYoIXRoaXMuc3VwcG9ydFZpZGVvVGV4dHVyZSl7XG4gICAgICAgICAgICAgICAgdGhpcy5oZWxwZXJDYW52YXMgPSBwbGF5ZXIuYWRkQ2hpbGQoXCJIZWxwZXJDYW52YXNcIiwge1xuICAgICAgICAgICAgICAgICAgICB2aWRlbzogdmlkZW8sXG4gICAgICAgICAgICAgICAgICAgIHdpZHRoOiAob3B0aW9ucy5oZWxwZXJDYW52YXMud2lkdGgpPyBvcHRpb25zLmhlbHBlckNhbnZhcy53aWR0aDogdGhpcy53aWR0aCxcbiAgICAgICAgICAgICAgICAgICAgaGVpZ2h0OiAob3B0aW9ucy5oZWxwZXJDYW52YXMuaGVpZ2h0KT8gb3B0aW9ucy5oZWxwZXJDYW52YXMuaGVpZ2h0OiB0aGlzLmhlaWdodFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIHZhciBjb250ZXh0ID0gdGhpcy5oZWxwZXJDYW52YXMuZWwoKTtcbiAgICAgICAgICAgICAgICB0aGlzLnRleHR1cmUgPSBuZXcgVEhSRUUuVGV4dHVyZShjb250ZXh0KTtcbiAgICAgICAgICAgIH1lbHNle1xuICAgICAgICAgICAgICAgIHRoaXMudGV4dHVyZSA9IG5ldyBUSFJFRS5UZXh0dXJlKHZpZGVvKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdmlkZW8uc3R5bGUudmlzaWJpbGl0eSA9IFwiaGlkZGVuXCI7XG5cbiAgICAgICAgICAgIHRoaXMudGV4dHVyZS5nZW5lcmF0ZU1pcG1hcHMgPSBmYWxzZTtcbiAgICAgICAgICAgIHRoaXMudGV4dHVyZS5taW5GaWx0ZXIgPSBUSFJFRS5MaW5lYXJGaWx0ZXI7XG4gICAgICAgICAgICB0aGlzLnRleHR1cmUubWF4RmlsdGVyID0gVEhSRUUuTGluZWFyRmlsdGVyO1xuICAgICAgICAgICAgdGhpcy50ZXh0dXJlLmZvcm1hdCA9IFRIUkVFLlJHQkZvcm1hdDtcblxuICAgICAgICAgICAgdGhpcy5lbF8gPSB0aGlzLnJlbmRlcmVyLmRvbUVsZW1lbnQ7XG4gICAgICAgICAgICB0aGlzLmVsXy5jbGFzc0xpc3QuYWRkKCd2anMtdmlkZW8tY2FudmFzJyk7XG5cbiAgICAgICAgICAgIG9wdGlvbnMuZWwgPSB0aGlzLmVsXztcbiAgICAgICAgICAgIGJhc2VDb21wb25lbnQuY2FsbCh0aGlzLCBwbGF5ZXIsIG9wdGlvbnMpO1xuXG4gICAgICAgICAgICB0aGlzLmF0dGFjaENvbnRyb2xFdmVudHMoKTtcbiAgICAgICAgICAgIHRoaXMucGxheWVyKCkub24oXCJwbGF5XCIsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnRpbWUgPSBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcbiAgICAgICAgICAgICAgICB0aGlzLnN0YXJ0QW5pbWF0aW9uKCk7XG4gICAgICAgICAgICB9LmJpbmQodGhpcykpO1xuICAgICAgICB9LFxuXG4gICAgICAgIGF0dGFjaENvbnRyb2xFdmVudHM6IGZ1bmN0aW9uKCl7XG4gICAgICAgICAgICB0aGlzLm9uKCdtb3VzZW1vdmUnLCB0aGlzLmhhbmRsZU1vdXNlTW92ZS5iaW5kKHRoaXMpKTtcbiAgICAgICAgICAgIHRoaXMub24oJ3RvdWNobW92ZScsIHRoaXMuaGFuZGxlVG91Y2hNb3ZlLmJpbmQodGhpcykpO1xuICAgICAgICAgICAgdGhpcy5vbignbW91c2Vkb3duJywgdGhpcy5oYW5kbGVNb3VzZURvd24uYmluZCh0aGlzKSk7XG4gICAgICAgICAgICB0aGlzLm9uKCd0b3VjaHN0YXJ0Jyx0aGlzLmhhbmRsZVRvdWNoU3RhcnQuYmluZCh0aGlzKSk7XG4gICAgICAgICAgICB0aGlzLm9uKCdtb3VzZXVwJywgdGhpcy5oYW5kbGVNb3VzZVVwLmJpbmQodGhpcykpO1xuICAgICAgICAgICAgdGhpcy5vbigndG91Y2hlbmQnLCB0aGlzLmhhbmRsZVRvdWNoRW5kLmJpbmQodGhpcykpO1xuICAgICAgICAgICAgaWYodGhpcy5zZXR0aW5ncy5zY3JvbGxhYmxlKXtcbiAgICAgICAgICAgICAgICB0aGlzLm9uKCdtb3VzZXdoZWVsJywgdGhpcy5oYW5kbGVNb3VzZVdoZWVsLmJpbmQodGhpcykpO1xuICAgICAgICAgICAgICAgIHRoaXMub24oJ01vek1vdXNlUGl4ZWxTY3JvbGwnLCB0aGlzLmhhbmRsZU1vdXNlV2hlZWwuYmluZCh0aGlzKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLm9uKCdtb3VzZWVudGVyJywgdGhpcy5oYW5kbGVNb3VzZUVudGVyLmJpbmQodGhpcykpO1xuICAgICAgICAgICAgdGhpcy5vbignbW91c2VsZWF2ZScsIHRoaXMuaGFuZGxlTW91c2VMZWFzZS5iaW5kKHRoaXMpKTtcbiAgICAgICAgICAgIHRoaXMub24oJ2Rpc3Bvc2UnLCB0aGlzLmhhbmRsZURpc3Bvc2UuYmluZCh0aGlzKSk7XG4gICAgICAgIH0sXG5cbiAgICAgICAgaGFuZGxlRGlzcG9zZTogZnVuY3Rpb24gKGV2ZW50KXtcbiAgICAgICAgICAgIHRoaXMub2ZmKCdtb3VzZW1vdmUnLCB0aGlzLmhhbmRsZU1vdXNlTW92ZS5iaW5kKHRoaXMpKTtcbiAgICAgICAgICAgIHRoaXMub2ZmKCd0b3VjaG1vdmUnLCB0aGlzLmhhbmRsZVRvdWNoTW92ZS5iaW5kKHRoaXMpKTtcbiAgICAgICAgICAgIHRoaXMub2ZmKCdtb3VzZWRvd24nLCB0aGlzLmhhbmRsZU1vdXNlRG93bi5iaW5kKHRoaXMpKTtcbiAgICAgICAgICAgIHRoaXMub2ZmKCd0b3VjaHN0YXJ0Jyx0aGlzLmhhbmRsZVRvdWNoU3RhcnQuYmluZCh0aGlzKSk7XG4gICAgICAgICAgICB0aGlzLm9mZignbW91c2V1cCcsIHRoaXMuaGFuZGxlTW91c2VVcC5iaW5kKHRoaXMpKTtcbiAgICAgICAgICAgIHRoaXMub2ZmKCd0b3VjaGVuZCcsIHRoaXMuaGFuZGxlVG91Y2hFbmQuYmluZCh0aGlzKSk7XG4gICAgICAgICAgICBpZih0aGlzLnNldHRpbmdzLnNjcm9sbGFibGUpe1xuICAgICAgICAgICAgICAgIHRoaXMub2ZmKCdtb3VzZXdoZWVsJywgdGhpcy5oYW5kbGVNb3VzZVdoZWVsLmJpbmQodGhpcykpO1xuICAgICAgICAgICAgICAgIHRoaXMub2ZmKCdNb3pNb3VzZVBpeGVsU2Nyb2xsJywgdGhpcy5oYW5kbGVNb3VzZVdoZWVsLmJpbmQodGhpcykpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5vZmYoJ21vdXNlZW50ZXInLCB0aGlzLmhhbmRsZU1vdXNlRW50ZXIuYmluZCh0aGlzKSk7XG4gICAgICAgICAgICB0aGlzLm9mZignbW91c2VsZWF2ZScsIHRoaXMuaGFuZGxlTW91c2VMZWFzZS5iaW5kKHRoaXMpKTtcbiAgICAgICAgICAgIHRoaXMub2ZmKCdkaXNwb3NlJywgdGhpcy5oYW5kbGVEaXNwb3NlLmJpbmQodGhpcykpO1xuICAgICAgICAgICAgdGhpcy5zdG9wQW5pbWF0aW9uKCk7XG4gICAgICAgIH0sXG5cbiAgICAgICAgc3RhcnRBbmltYXRpb246IGZ1bmN0aW9uKCl7XG4gICAgICAgICAgICB0aGlzLnJlbmRlcl9hbmltYXRpb24gPSB0cnVlO1xuICAgICAgICAgICAgdGhpcy5hbmltYXRlKCk7XG4gICAgICAgIH0sXG5cbiAgICAgICAgc3RvcEFuaW1hdGlvbjogZnVuY3Rpb24oKXtcbiAgICAgICAgICAgIHRoaXMucmVuZGVyX2FuaW1hdGlvbiA9IGZhbHNlO1xuICAgICAgICAgICAgaWYodGhpcy5yZXF1ZXN0QW5pbWF0aW9uSWQpe1xuICAgICAgICAgICAgICAgIGNhbmNlbEFuaW1hdGlvbkZyYW1lKHRoaXMucmVxdWVzdEFuaW1hdGlvbklkKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSxcblxuICAgICAgICBoYW5kbGVSZXNpemU6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHRoaXMud2lkdGggPSB0aGlzLnBsYXllcigpLmVsKCkub2Zmc2V0V2lkdGgsIHRoaXMuaGVpZ2h0ID0gdGhpcy5wbGF5ZXIoKS5lbCgpLm9mZnNldEhlaWdodDtcbiAgICAgICAgICAgIHRoaXMucmVuZGVyZXIuc2V0U2l6ZSggdGhpcy53aWR0aCwgdGhpcy5oZWlnaHQgKTtcbiAgICAgICAgfSxcblxuICAgICAgICBoYW5kbGVNb3VzZVVwOiBmdW5jdGlvbihldmVudCl7XG4gICAgICAgICAgICB0aGlzLm1vdXNlRG93biA9IGZhbHNlO1xuICAgICAgICAgICAgaWYodGhpcy5jbGlja1RvVG9nZ2xlKXtcbiAgICAgICAgICAgICAgICB2YXIgY2xpZW50WCA9IGV2ZW50LmNsaWVudFggfHwgZXZlbnQuY2hhbmdlZFRvdWNoZXMgJiYgZXZlbnQuY2hhbmdlZFRvdWNoZXNbMF0uY2xpZW50WDtcbiAgICAgICAgICAgICAgICB2YXIgY2xpZW50WSA9IGV2ZW50LmNsaWVudFkgfHwgZXZlbnQuY2hhbmdlZFRvdWNoZXMgJiYgZXZlbnQuY2hhbmdlZFRvdWNoZXNbMF0uY2xpZW50WTtcbiAgICAgICAgICAgICAgICBpZih0eXBlb2YgY2xpZW50WCA9PT0gXCJ1bmRlZmluZWRcIiB8fCBjbGllbnRZID09PSBcInVuZGVmaW5lZFwiKSByZXR1cm47XG4gICAgICAgICAgICAgICAgdmFyIGRpZmZYID0gTWF0aC5hYnMoY2xpZW50WCAtIHRoaXMub25Qb2ludGVyRG93blBvaW50ZXJYKTtcbiAgICAgICAgICAgICAgICB2YXIgZGlmZlkgPSBNYXRoLmFicyhjbGllbnRZIC0gdGhpcy5vblBvaW50ZXJEb3duUG9pbnRlclkpO1xuICAgICAgICAgICAgICAgIGlmKGRpZmZYIDwgMC4xICYmIGRpZmZZIDwgMC4xKVxuICAgICAgICAgICAgICAgICAgICB0aGlzLnBsYXllcigpLnBhdXNlZCgpID8gdGhpcy5wbGF5ZXIoKS5wbGF5KCkgOiB0aGlzLnBsYXllcigpLnBhdXNlKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG5cbiAgICAgICAgaGFuZGxlTW91c2VEb3duOiBmdW5jdGlvbihldmVudCl7XG4gICAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgdmFyIGNsaWVudFggPSBldmVudC5jbGllbnRYIHx8IGV2ZW50LnRvdWNoZXMgJiYgZXZlbnQudG91Y2hlc1swXS5jbGllbnRYO1xuICAgICAgICAgICAgdmFyIGNsaWVudFkgPSBldmVudC5jbGllbnRZIHx8IGV2ZW50LnRvdWNoZXMgJiYgZXZlbnQudG91Y2hlc1swXS5jbGllbnRZO1xuICAgICAgICAgICAgaWYodHlwZW9mIGNsaWVudFggPT09IFwidW5kZWZpbmVkXCIgfHwgY2xpZW50WSA9PT0gXCJ1bmRlZmluZWRcIikgcmV0dXJuO1xuICAgICAgICAgICAgdGhpcy5tb3VzZURvd24gPSB0cnVlO1xuICAgICAgICAgICAgdGhpcy5vblBvaW50ZXJEb3duUG9pbnRlclggPSBjbGllbnRYO1xuICAgICAgICAgICAgdGhpcy5vblBvaW50ZXJEb3duUG9pbnRlclkgPSBjbGllbnRZO1xuICAgICAgICAgICAgdGhpcy5vblBvaW50ZXJEb3duTG9uID0gdGhpcy5sb247XG4gICAgICAgICAgICB0aGlzLm9uUG9pbnRlckRvd25MYXQgPSB0aGlzLmxhdDtcbiAgICAgICAgfSxcblxuICAgICAgICBoYW5kbGVUb3VjaFN0YXJ0OiBmdW5jdGlvbihldmVudCl7XG4gICAgICAgICAgICBpZihldmVudC50b3VjaGVzLmxlbmd0aCA+IDEpe1xuICAgICAgICAgICAgICAgIHRoaXMuaXNVc2VyUGluY2ggPSB0cnVlO1xuICAgICAgICAgICAgICAgIHRoaXMubXVsdGlUb3VjaERpc3RhbmNlID0gVXRpbC5nZXRUb3VjaGVzRGlzdGFuY2UoZXZlbnQudG91Y2hlcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLmhhbmRsZU1vdXNlRG93bihldmVudCk7XG4gICAgICAgIH0sXG5cbiAgICAgICAgaGFuZGxlVG91Y2hFbmQ6IGZ1bmN0aW9uKGV2ZW50KXtcbiAgICAgICAgICAgIHRoaXMuaXNVc2VyUGluY2ggPSBmYWxzZTtcbiAgICAgICAgICAgIHRoaXMuaGFuZGxlTW91c2VVcChldmVudCk7XG4gICAgICAgIH0sXG5cbiAgICAgICAgaGFuZGxlTW91c2VNb3ZlOiBmdW5jdGlvbihldmVudCl7XG4gICAgICAgICAgICB2YXIgY2xpZW50WCA9IGV2ZW50LmNsaWVudFggfHwgZXZlbnQudG91Y2hlcyAmJiBldmVudC50b3VjaGVzWzBdLmNsaWVudFg7XG4gICAgICAgICAgICB2YXIgY2xpZW50WSA9IGV2ZW50LmNsaWVudFkgfHwgZXZlbnQudG91Y2hlcyAmJiBldmVudC50b3VjaGVzWzBdLmNsaWVudFk7XG4gICAgICAgICAgICBpZih0eXBlb2YgY2xpZW50WCA9PT0gXCJ1bmRlZmluZWRcIiB8fCBjbGllbnRZID09PSBcInVuZGVmaW5lZFwiKSByZXR1cm47XG4gICAgICAgICAgICBpZih0aGlzLnNldHRpbmdzLmNsaWNrQW5kRHJhZyl7XG4gICAgICAgICAgICAgICAgaWYodGhpcy5tb3VzZURvd24pe1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmxvbiA9ICggdGhpcy5vblBvaW50ZXJEb3duUG9pbnRlclggLSBjbGllbnRYICkgKiAwLjIgKyB0aGlzLm9uUG9pbnRlckRvd25Mb247XG4gICAgICAgICAgICAgICAgICAgIHRoaXMubGF0ID0gKCBjbGllbnRZIC0gdGhpcy5vblBvaW50ZXJEb3duUG9pbnRlclkgKSAqIDAuMiArIHRoaXMub25Qb2ludGVyRG93bkxhdDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9ZWxzZXtcbiAgICAgICAgICAgICAgICB2YXIgeCA9IGNsaWVudFggLSB0aGlzLmVsXy5vZmZzZXRMZWZ0O1xuICAgICAgICAgICAgICAgIHZhciB5ID0gY2xpZW50WSAtIHRoaXMuZWxfLm9mZnNldFRvcDtcbiAgICAgICAgICAgICAgICB0aGlzLmxvbiA9ICh4IC8gdGhpcy53aWR0aCkgKiA0MzAgLSAyMjU7XG4gICAgICAgICAgICAgICAgdGhpcy5sYXQgPSAoeSAvIHRoaXMuaGVpZ2h0KSAqIC0xODAgKyA5MDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSxcblxuICAgICAgICBoYW5kbGVUb3VjaE1vdmU6IGZ1bmN0aW9uKGV2ZW50KXtcbiAgICAgICAgICAgIC8vaGFuZGxlIHNpbmdsZSB0b3VjaCBldmVudCxcbiAgICAgICAgICAgIGlmKCF0aGlzLmlzVXNlclBpbmNoIHx8IGV2ZW50LnRvdWNoZXMubGVuZ3RoIDw9IDEpe1xuICAgICAgICAgICAgICAgIHRoaXMuaGFuZGxlTW91c2VNb3ZlKGV2ZW50KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSxcblxuICAgICAgICBoYW5kbGVNb2JpbGVPcmllbnRhdGlvbjogZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgICAgICAgICBpZih0eXBlb2YgZXZlbnQucm90YXRpb25SYXRlID09PSBcInVuZGVmaW5lZFwiKSByZXR1cm47XG4gICAgICAgICAgICB2YXIgeCA9IGV2ZW50LnJvdGF0aW9uUmF0ZS5hbHBoYTtcbiAgICAgICAgICAgIHZhciB5ID0gZXZlbnQucm90YXRpb25SYXRlLmJldGE7XG4gICAgICAgICAgICB2YXIgcG9ydHJhaXQgPSAodHlwZW9mIGV2ZW50LnBvcnRyYWl0ICE9PSBcInVuZGVmaW5lZFwiKT8gZXZlbnQucG9ydHJhaXQgOiB3aW5kb3cubWF0Y2hNZWRpYShcIihvcmllbnRhdGlvbjogcG9ydHJhaXQpXCIpLm1hdGNoZXM7XG4gICAgICAgICAgICB2YXIgbGFuZHNjYXBlID0gKHR5cGVvZiBldmVudC5sYW5kc2NhcGUgIT09IFwidW5kZWZpbmVkXCIpPyBldmVudC5sYW5kc2NhcGUgOiB3aW5kb3cubWF0Y2hNZWRpYShcIihvcmllbnRhdGlvbjogbGFuZHNjYXBlKVwiKS5tYXRjaGVzO1xuICAgICAgICAgICAgdmFyIG9yaWVudGF0aW9uID0gZXZlbnQub3JpZW50YXRpb24gfHwgd2luZG93Lm9yaWVudGF0aW9uO1xuXG4gICAgICAgICAgICBpZiAocG9ydHJhaXQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmxvbiA9IHRoaXMubG9uIC0geSAqIHRoaXMuc2V0dGluZ3MubW9iaWxlVmlicmF0aW9uVmFsdWU7XG4gICAgICAgICAgICAgICAgdGhpcy5sYXQgPSB0aGlzLmxhdCArIHggKiB0aGlzLnNldHRpbmdzLm1vYmlsZVZpYnJhdGlvblZhbHVlO1xuICAgICAgICAgICAgfWVsc2UgaWYobGFuZHNjYXBlKXtcbiAgICAgICAgICAgICAgICB2YXIgb3JpZW50YXRpb25EZWdyZWUgPSAtOTA7XG4gICAgICAgICAgICAgICAgaWYodHlwZW9mIG9yaWVudGF0aW9uICE9IFwidW5kZWZpbmVkXCIpe1xuICAgICAgICAgICAgICAgICAgICBvcmllbnRhdGlvbkRlZ3JlZSA9IG9yaWVudGF0aW9uO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHRoaXMubG9uID0gKG9yaWVudGF0aW9uRGVncmVlID09IC05MCk/IHRoaXMubG9uICsgeCAqIHRoaXMuc2V0dGluZ3MubW9iaWxlVmlicmF0aW9uVmFsdWUgOiB0aGlzLmxvbiAtIHggKiB0aGlzLnNldHRpbmdzLm1vYmlsZVZpYnJhdGlvblZhbHVlO1xuICAgICAgICAgICAgICAgIHRoaXMubGF0ID0gKG9yaWVudGF0aW9uRGVncmVlID09IC05MCk/IHRoaXMubGF0ICsgeSAqIHRoaXMuc2V0dGluZ3MubW9iaWxlVmlicmF0aW9uVmFsdWUgOiB0aGlzLmxhdCAtIHkgKiB0aGlzLnNldHRpbmdzLm1vYmlsZVZpYnJhdGlvblZhbHVlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9LFxuXG4gICAgICAgIGhhbmRsZU1vdXNlV2hlZWw6IGZ1bmN0aW9uKGV2ZW50KXtcbiAgICAgICAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgfSxcblxuICAgICAgICBoYW5kbGVNb3VzZUVudGVyOiBmdW5jdGlvbiAoZXZlbnQpIHtcbiAgICAgICAgICAgIHRoaXMuaXNVc2VySW50ZXJhY3RpbmcgPSB0cnVlO1xuICAgICAgICB9LFxuXG4gICAgICAgIGhhbmRsZU1vdXNlTGVhc2U6IGZ1bmN0aW9uIChldmVudCkge1xuICAgICAgICAgICAgdGhpcy5pc1VzZXJJbnRlcmFjdGluZyA9IGZhbHNlO1xuICAgICAgICAgICAgaWYodGhpcy5tb3VzZURvd24pIHtcbiAgICAgICAgICAgICAgICB0aGlzLm1vdXNlRG93biA9IGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9LFxuXG4gICAgICAgIGFuaW1hdGU6IGZ1bmN0aW9uKCl7XG4gICAgICAgICAgICBpZighdGhpcy5yZW5kZXJfYW5pbWF0aW9uKSByZXR1cm47XG4gICAgICAgICAgICB0aGlzLnJlcXVlc3RBbmltYXRpb25JZCA9IHJlcXVlc3RBbmltYXRpb25GcmFtZSggdGhpcy5hbmltYXRlLmJpbmQodGhpcykgKTtcbiAgICAgICAgICAgIGlmKCF0aGlzLnBsYXllcigpLnBhdXNlZCgpKXtcbiAgICAgICAgICAgICAgICBpZih0eXBlb2YodGhpcy50ZXh0dXJlKSAhPT0gXCJ1bmRlZmluZWRcIiAmJiAoIXRoaXMuaXNQbGF5T25Nb2JpbGUgJiYgdGhpcy5wbGF5ZXIoKS5yZWFkeVN0YXRlKCkgPj0gSEFWRV9DVVJSRU5UX0RBVEEgfHwgdGhpcy5pc1BsYXlPbk1vYmlsZSAmJiB0aGlzLnBsYXllcigpLmhhc0NsYXNzKFwidmpzLXBsYXlpbmdcIikpKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBjdCA9IG5ldyBEYXRlKCkuZ2V0VGltZSgpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoY3QgLSB0aGlzLnRpbWUgPj0gMzApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMudGV4dHVyZS5uZWVkc1VwZGF0ZSA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnRpbWUgPSBjdDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZih0aGlzLmlzUGxheU9uTW9iaWxlKXtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjdXJyZW50VGltZSA9IHRoaXMucGxheWVyKCkuY3VycmVudFRpbWUoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmKE1vYmlsZUJ1ZmZlcmluZy5pc0J1ZmZlcmluZyhjdXJyZW50VGltZSkpe1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmKCF0aGlzLnBsYXllcigpLmhhc0NsYXNzKFwidmpzLXBhbm9yYW1hLW1vYmlsZS1pbmxpbmUtdmlkZW8tYnVmZmVyaW5nXCIpKXtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5wbGF5ZXIoKS5hZGRDbGFzcyhcInZqcy1wYW5vcmFtYS1tb2JpbGUtaW5saW5lLXZpZGVvLWJ1ZmZlcmluZ1wiKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9ZWxzZXtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZih0aGlzLnBsYXllcigpLmhhc0NsYXNzKFwidmpzLXBhbm9yYW1hLW1vYmlsZS1pbmxpbmUtdmlkZW8tYnVmZmVyaW5nXCIpKXtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5wbGF5ZXIoKS5yZW1vdmVDbGFzcyhcInZqcy1wYW5vcmFtYS1tb2JpbGUtaW5saW5lLXZpZGVvLWJ1ZmZlcmluZ1wiKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLnJlbmRlcigpO1xuICAgICAgICB9LFxuXG4gICAgICAgIHJlbmRlcjogZnVuY3Rpb24oKXtcbiAgICAgICAgICAgIGlmKCF0aGlzLmlzVXNlckludGVyYWN0aW5nKXtcbiAgICAgICAgICAgICAgICB2YXIgc3ltYm9sTGF0ID0gKHRoaXMubGF0ID4gdGhpcy5zZXR0aW5ncy5pbml0TGF0KT8gIC0xIDogMTtcbiAgICAgICAgICAgICAgICB2YXIgc3ltYm9sTG9uID0gKHRoaXMubG9uID4gdGhpcy5zZXR0aW5ncy5pbml0TG9uKT8gIC0xIDogMTtcbiAgICAgICAgICAgICAgICBpZih0aGlzLnNldHRpbmdzLmJhY2tUb1ZlcnRpY2FsQ2VudGVyKXtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5sYXQgPSAoXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmxhdCA+ICh0aGlzLnNldHRpbmdzLmluaXRMYXQgLSBNYXRoLmFicyh0aGlzLnNldHRpbmdzLnJldHVyblN0ZXBMYXQpKSAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5sYXQgPCAodGhpcy5zZXR0aW5ncy5pbml0TGF0ICsgTWF0aC5hYnModGhpcy5zZXR0aW5ncy5yZXR1cm5TdGVwTGF0KSlcbiAgICAgICAgICAgICAgICAgICAgKT8gdGhpcy5zZXR0aW5ncy5pbml0TGF0IDogdGhpcy5sYXQgKyB0aGlzLnNldHRpbmdzLnJldHVyblN0ZXBMYXQgKiBzeW1ib2xMYXQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmKHRoaXMuc2V0dGluZ3MuYmFja1RvSG9yaXpvbkNlbnRlcil7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMubG9uID0gKFxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5sb24gPiAodGhpcy5zZXR0aW5ncy5pbml0TG9uIC0gTWF0aC5hYnModGhpcy5zZXR0aW5ncy5yZXR1cm5TdGVwTG9uKSkgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubG9uIDwgKHRoaXMuc2V0dGluZ3MuaW5pdExvbiArIE1hdGguYWJzKHRoaXMuc2V0dGluZ3MucmV0dXJuU3RlcExvbikpXG4gICAgICAgICAgICAgICAgICAgICk/IHRoaXMuc2V0dGluZ3MuaW5pdExvbiA6IHRoaXMubG9uICsgdGhpcy5zZXR0aW5ncy5yZXR1cm5TdGVwTG9uICogc3ltYm9sTG9uO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMubGF0ID0gTWF0aC5tYXgoIHRoaXMuc2V0dGluZ3MubWluTGF0LCBNYXRoLm1pbiggdGhpcy5zZXR0aW5ncy5tYXhMYXQsIHRoaXMubGF0ICkgKTtcbiAgICAgICAgICAgIHRoaXMubG9uID0gTWF0aC5tYXgoIHRoaXMuc2V0dGluZ3MubWluTG9uLCBNYXRoLm1pbiggdGhpcy5zZXR0aW5ncy5tYXhMb24sIHRoaXMubG9uICkgKTtcbiAgICAgICAgICAgIHRoaXMucGhpID0gVEhSRUUuTWF0aC5kZWdUb1JhZCggOTAgLSB0aGlzLmxhdCApO1xuICAgICAgICAgICAgdGhpcy50aGV0YSA9IFRIUkVFLk1hdGguZGVnVG9SYWQoIHRoaXMubG9uICk7XG5cbiAgICAgICAgICAgIGlmKCF0aGlzLnN1cHBvcnRWaWRlb1RleHR1cmUpe1xuICAgICAgICAgICAgICAgIHRoaXMuaGVscGVyQ2FudmFzLnVwZGF0ZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5yZW5kZXJlci5jbGVhcigpO1xuICAgICAgICB9LFxuXG4gICAgICAgIHBsYXlPbk1vYmlsZTogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgdGhpcy5pc1BsYXlPbk1vYmlsZSA9IHRydWU7XG4gICAgICAgICAgICBpZih0aGlzLnNldHRpbmdzLmF1dG9Nb2JpbGVPcmllbnRhdGlvbilcbiAgICAgICAgICAgICAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignZGV2aWNlbW90aW9uJywgdGhpcy5oYW5kbGVNb2JpbGVPcmllbnRhdGlvbi5iaW5kKHRoaXMpKTtcbiAgICAgICAgfSxcblxuICAgICAgICBlbDogZnVuY3Rpb24oKXtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmVsXztcbiAgICAgICAgfVxuICAgIH1cbn07XG5cbmV4cG9ydCBkZWZhdWx0IEJhc2VDYW52YXM7XG4iLCIvKipcbiAqIENyZWF0ZWQgYnkgeWFud3NoIG9uIDQvMy8xNi5cbiAqL1xuXG5pbXBvcnQgQmFzZUNhbnZhcyBmcm9tICcuL0Jhc2VDYW52YXMnO1xuaW1wb3J0IFV0aWwgZnJvbSAnLi9VdGlsJztcblxudmFyIENhbnZhcyA9IGZ1bmN0aW9uIChiYXNlQ29tcG9uZW50LCBUSFJFRSwgc2V0dGluZ3MgPSB7fSkge1xuICAgIHZhciBwYXJlbnQgPSBCYXNlQ2FudmFzKGJhc2VDb21wb25lbnQsIFRIUkVFLCBzZXR0aW5ncyk7XG5cbiAgICByZXR1cm4gVXRpbC5leHRlbmQocGFyZW50LCB7XG4gICAgICAgIGNvbnN0cnVjdG9yOiBmdW5jdGlvbiBpbml0KHBsYXllciwgb3B0aW9ucyl7XG4gICAgICAgICAgICBwYXJlbnQuY29uc3RydWN0b3IuY2FsbCh0aGlzLCBwbGF5ZXIsIG9wdGlvbnMpO1xuXG4gICAgICAgICAgICB0aGlzLlZSTW9kZSA9IGZhbHNlO1xuICAgICAgICAgICAgLy9kZWZpbmUgc2NlbmVcbiAgICAgICAgICAgIHRoaXMuc2NlbmUgPSBuZXcgVEhSRUUuU2NlbmUoKTtcbiAgICAgICAgICAgIC8vZGVmaW5lIGNhbWVyYVxuICAgICAgICAgICAgdGhpcy5jYW1lcmEgPSBuZXcgVEhSRUUuUGVyc3BlY3RpdmVDYW1lcmEob3B0aW9ucy5pbml0Rm92LCB0aGlzLndpZHRoIC8gdGhpcy5oZWlnaHQsIDEsIDIwMDApO1xuICAgICAgICAgICAgdGhpcy5jYW1lcmEudGFyZ2V0ID0gbmV3IFRIUkVFLlZlY3RvcjMoIDAsIDAsIDAgKTtcblxuICAgICAgICAgICAgLy9kZWZpbmUgZ2VvbWV0cnlcbiAgICAgICAgICAgIHZhciBnZW9tZXRyeSA9ICh0aGlzLnZpZGVvVHlwZSA9PT0gXCJlcXVpcmVjdGFuZ3VsYXJcIik/IG5ldyBUSFJFRS5TcGhlcmVHZW9tZXRyeSg1MDAsIDYwLCA0MCk6IG5ldyBUSFJFRS5TcGhlcmVCdWZmZXJHZW9tZXRyeSggNTAwLCA2MCwgNDAgKS50b05vbkluZGV4ZWQoKTtcbiAgICAgICAgICAgIGlmKHRoaXMudmlkZW9UeXBlID09PSBcImZpc2hleWVcIil7XG4gICAgICAgICAgICAgICAgbGV0IG5vcm1hbHMgPSBnZW9tZXRyeS5hdHRyaWJ1dGVzLm5vcm1hbC5hcnJheTtcbiAgICAgICAgICAgICAgICBsZXQgdXZzID0gZ2VvbWV0cnkuYXR0cmlidXRlcy51di5hcnJheTtcbiAgICAgICAgICAgICAgICBmb3IgKCBsZXQgaSA9IDAsIGwgPSBub3JtYWxzLmxlbmd0aCAvIDM7IGkgPCBsOyBpICsrICkge1xuICAgICAgICAgICAgICAgICAgICBsZXQgeCA9IG5vcm1hbHNbIGkgKiAzICsgMCBdO1xuICAgICAgICAgICAgICAgICAgICBsZXQgeSA9IG5vcm1hbHNbIGkgKiAzICsgMSBdO1xuICAgICAgICAgICAgICAgICAgICBsZXQgeiA9IG5vcm1hbHNbIGkgKiAzICsgMiBdO1xuXG4gICAgICAgICAgICAgICAgICAgIGxldCByID0gTWF0aC5hc2luKE1hdGguc3FydCh4ICogeCArIHogKiB6KSAvIE1hdGguc3FydCh4ICogeCAgKyB5ICogeSArIHogKiB6KSkgLyBNYXRoLlBJO1xuICAgICAgICAgICAgICAgICAgICBpZih5IDwgMCkgciA9IDEgLSByO1xuICAgICAgICAgICAgICAgICAgICBsZXQgdGhldGEgPSAoeCA9PSAwICYmIHogPT0gMCk/IDAgOiBNYXRoLmFjb3MoeCAvIE1hdGguc3FydCh4ICogeCArIHogKiB6KSk7XG4gICAgICAgICAgICAgICAgICAgIGlmKHogPCAwKSB0aGV0YSA9IHRoZXRhICogLTE7XG4gICAgICAgICAgICAgICAgICAgIHV2c1sgaSAqIDIgKyAwIF0gPSAtMC44ICogciAqIE1hdGguY29zKHRoZXRhKSArIDAuNTtcbiAgICAgICAgICAgICAgICAgICAgdXZzWyBpICogMiArIDEgXSA9IDAuOCAqIHIgKiBNYXRoLnNpbih0aGV0YSkgKyAwLjU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGdlb21ldHJ5LnJvdGF0ZVgoIG9wdGlvbnMucm90YXRlWCk7XG4gICAgICAgICAgICAgICAgZ2VvbWV0cnkucm90YXRlWSggb3B0aW9ucy5yb3RhdGVZKTtcbiAgICAgICAgICAgICAgICBnZW9tZXRyeS5yb3RhdGVaKCBvcHRpb25zLnJvdGF0ZVopO1xuICAgICAgICAgICAgfWVsc2UgaWYodGhpcy52aWRlb1R5cGUgPT09IFwiZHVhbF9maXNoZXllXCIpe1xuICAgICAgICAgICAgICAgIGxldCBub3JtYWxzID0gZ2VvbWV0cnkuYXR0cmlidXRlcy5ub3JtYWwuYXJyYXk7XG4gICAgICAgICAgICAgICAgbGV0IHV2cyA9IGdlb21ldHJ5LmF0dHJpYnV0ZXMudXYuYXJyYXk7XG4gICAgICAgICAgICAgICAgbGV0IGwgPSBub3JtYWxzLmxlbmd0aCAvIDM7XG4gICAgICAgICAgICAgICAgZm9yICggbGV0IGkgPSAwOyBpIDwgbCAvIDI7IGkgKysgKSB7XG4gICAgICAgICAgICAgICAgICAgIGxldCB4ID0gbm9ybWFsc1sgaSAqIDMgKyAwIF07XG4gICAgICAgICAgICAgICAgICAgIGxldCB5ID0gbm9ybWFsc1sgaSAqIDMgKyAxIF07XG4gICAgICAgICAgICAgICAgICAgIGxldCB6ID0gbm9ybWFsc1sgaSAqIDMgKyAyIF07XG5cbiAgICAgICAgICAgICAgICAgICAgbGV0IHIgPSAoIHggPT0gMCAmJiB6ID09IDAgKSA/IDEgOiAoIE1hdGguYWNvcyggeSApIC8gTWF0aC5zcXJ0KCB4ICogeCArIHogKiB6ICkgKSAqICggMiAvIE1hdGguUEkgKTtcbiAgICAgICAgICAgICAgICAgICAgdXZzWyBpICogMiArIDAgXSA9IHggKiBvcHRpb25zLmR1YWxGaXNoLmNpcmNsZTEucnggKiByICogb3B0aW9ucy5kdWFsRmlzaC5jaXJjbGUxLmNvdmVyWCAgKyBvcHRpb25zLmR1YWxGaXNoLmNpcmNsZTEueDtcbiAgICAgICAgICAgICAgICAgICAgdXZzWyBpICogMiArIDEgXSA9IHogKiBvcHRpb25zLmR1YWxGaXNoLmNpcmNsZTEucnkgKiByICogb3B0aW9ucy5kdWFsRmlzaC5jaXJjbGUxLmNvdmVyWSAgKyBvcHRpb25zLmR1YWxGaXNoLmNpcmNsZTEueTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZm9yICggbGV0IGkgPSBsIC8gMjsgaSA8IGw7IGkgKysgKSB7XG4gICAgICAgICAgICAgICAgICAgIGxldCB4ID0gbm9ybWFsc1sgaSAqIDMgKyAwIF07XG4gICAgICAgICAgICAgICAgICAgIGxldCB5ID0gbm9ybWFsc1sgaSAqIDMgKyAxIF07XG4gICAgICAgICAgICAgICAgICAgIGxldCB6ID0gbm9ybWFsc1sgaSAqIDMgKyAyIF07XG5cbiAgICAgICAgICAgICAgICAgICAgbGV0IHIgPSAoIHggPT0gMCAmJiB6ID09IDAgKSA/IDEgOiAoIE1hdGguYWNvcyggLSB5ICkgLyBNYXRoLnNxcnQoIHggKiB4ICsgeiAqIHogKSApICogKCAyIC8gTWF0aC5QSSApO1xuICAgICAgICAgICAgICAgICAgICB1dnNbIGkgKiAyICsgMCBdID0gLSB4ICogb3B0aW9ucy5kdWFsRmlzaC5jaXJjbGUyLnJ4ICogciAqIG9wdGlvbnMuZHVhbEZpc2guY2lyY2xlMi5jb3ZlclggICsgb3B0aW9ucy5kdWFsRmlzaC5jaXJjbGUyLng7XG4gICAgICAgICAgICAgICAgICAgIHV2c1sgaSAqIDIgKyAxIF0gPSB6ICogb3B0aW9ucy5kdWFsRmlzaC5jaXJjbGUyLnJ5ICogciAqIG9wdGlvbnMuZHVhbEZpc2guY2lyY2xlMi5jb3ZlclkgICsgb3B0aW9ucy5kdWFsRmlzaC5jaXJjbGUyLnk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGdlb21ldHJ5LnJvdGF0ZVgoIG9wdGlvbnMucm90YXRlWCk7XG4gICAgICAgICAgICAgICAgZ2VvbWV0cnkucm90YXRlWSggb3B0aW9ucy5yb3RhdGVZKTtcbiAgICAgICAgICAgICAgICBnZW9tZXRyeS5yb3RhdGVaKCBvcHRpb25zLnJvdGF0ZVopO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZ2VvbWV0cnkuc2NhbGUoIC0gMSwgMSwgMSApO1xuICAgICAgICAgICAgLy9kZWZpbmUgbWVzaFxuICAgICAgICAgICAgdGhpcy5tZXNoID0gbmV3IFRIUkVFLk1lc2goZ2VvbWV0cnksXG4gICAgICAgICAgICAgICAgbmV3IFRIUkVFLk1lc2hCYXNpY01hdGVyaWFsKHsgbWFwOiB0aGlzLnRleHR1cmV9KVxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIC8vdGhpcy5tZXNoLnNjYWxlLnggPSAtMTtcbiAgICAgICAgICAgIHRoaXMuc2NlbmUuYWRkKHRoaXMubWVzaCk7XG4gICAgICAgIH0sXG5cbiAgICAgICAgZW5hYmxlVlI6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHRoaXMuVlJNb2RlID0gdHJ1ZTtcbiAgICAgICAgICAgIGlmKHR5cGVvZiB2ckhNRCAhPT0gJ3VuZGVmaW5lZCcpe1xuICAgICAgICAgICAgICAgIHZhciBleWVQYXJhbXNMID0gdnJITUQuZ2V0RXllUGFyYW1ldGVycyggJ2xlZnQnICk7XG4gICAgICAgICAgICAgICAgdmFyIGV5ZVBhcmFtc1IgPSB2ckhNRC5nZXRFeWVQYXJhbWV0ZXJzKCAncmlnaHQnICk7XG5cbiAgICAgICAgICAgICAgICB0aGlzLmV5ZUZPVkwgPSBleWVQYXJhbXNMLnJlY29tbWVuZGVkRmllbGRPZlZpZXc7XG4gICAgICAgICAgICAgICAgdGhpcy5leWVGT1ZSID0gZXllUGFyYW1zUi5yZWNvbW1lbmRlZEZpZWxkT2ZWaWV3O1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLmNhbWVyYUwgPSBuZXcgVEhSRUUuUGVyc3BlY3RpdmVDYW1lcmEodGhpcy5jYW1lcmEuZm92LCB0aGlzLndpZHRoIC8yIC8gdGhpcy5oZWlnaHQsIDEsIDIwMDApO1xuICAgICAgICAgICAgdGhpcy5jYW1lcmFSID0gbmV3IFRIUkVFLlBlcnNwZWN0aXZlQ2FtZXJhKHRoaXMuY2FtZXJhLmZvdiwgdGhpcy53aWR0aCAvMiAvIHRoaXMuaGVpZ2h0LCAxLCAyMDAwKTtcbiAgICAgICAgfSxcblxuICAgICAgICBkaXNhYmxlVlI6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHRoaXMuVlJNb2RlID0gZmFsc2U7XG4gICAgICAgICAgICB0aGlzLnJlbmRlcmVyLnNldFZpZXdwb3J0KCAwLCAwLCB0aGlzLndpZHRoLCB0aGlzLmhlaWdodCApO1xuICAgICAgICAgICAgdGhpcy5yZW5kZXJlci5zZXRTY2lzc29yKCAwLCAwLCB0aGlzLndpZHRoLCB0aGlzLmhlaWdodCApO1xuICAgICAgICB9LFxuXG4gICAgICAgIGhhbmRsZVJlc2l6ZTogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcGFyZW50LmhhbmRsZVJlc2l6ZS5jYWxsKHRoaXMpO1xuICAgICAgICAgICAgdGhpcy5jYW1lcmEuYXNwZWN0ID0gdGhpcy53aWR0aCAvIHRoaXMuaGVpZ2h0O1xuICAgICAgICAgICAgdGhpcy5jYW1lcmEudXBkYXRlUHJvamVjdGlvbk1hdHJpeCgpO1xuICAgICAgICAgICAgaWYodGhpcy5WUk1vZGUpe1xuICAgICAgICAgICAgICAgIHRoaXMuY2FtZXJhTC5hc3BlY3QgPSB0aGlzLmNhbWVyYS5hc3BlY3QgLyAyO1xuICAgICAgICAgICAgICAgIHRoaXMuY2FtZXJhUi5hc3BlY3QgPSB0aGlzLmNhbWVyYS5hc3BlY3QgLyAyO1xuICAgICAgICAgICAgICAgIHRoaXMuY2FtZXJhTC51cGRhdGVQcm9qZWN0aW9uTWF0cml4KCk7XG4gICAgICAgICAgICAgICAgdGhpcy5jYW1lcmFSLnVwZGF0ZVByb2plY3Rpb25NYXRyaXgoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSxcblxuICAgICAgICBoYW5kbGVNb3VzZVdoZWVsOiBmdW5jdGlvbihldmVudCl7XG4gICAgICAgICAgICBwYXJlbnQuaGFuZGxlTW91c2VXaGVlbChldmVudCk7XG4gICAgICAgICAgICAvLyBXZWJLaXRcbiAgICAgICAgICAgIGlmICggZXZlbnQud2hlZWxEZWx0YVkgKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5jYW1lcmEuZm92IC09IGV2ZW50LndoZWVsRGVsdGFZICogMC4wNTtcbiAgICAgICAgICAgICAgICAvLyBPcGVyYSAvIEV4cGxvcmVyIDlcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoIGV2ZW50LndoZWVsRGVsdGEgKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5jYW1lcmEuZm92IC09IGV2ZW50LndoZWVsRGVsdGEgKiAwLjA1O1xuICAgICAgICAgICAgICAgIC8vIEZpcmVmb3hcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoIGV2ZW50LmRldGFpbCApIHtcbiAgICAgICAgICAgICAgICB0aGlzLmNhbWVyYS5mb3YgKz0gZXZlbnQuZGV0YWlsICogMS4wO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5jYW1lcmEuZm92ID0gTWF0aC5taW4odGhpcy5zZXR0aW5ncy5tYXhGb3YsIHRoaXMuY2FtZXJhLmZvdik7XG4gICAgICAgICAgICB0aGlzLmNhbWVyYS5mb3YgPSBNYXRoLm1heCh0aGlzLnNldHRpbmdzLm1pbkZvdiwgdGhpcy5jYW1lcmEuZm92KTtcbiAgICAgICAgICAgIHRoaXMuY2FtZXJhLnVwZGF0ZVByb2plY3Rpb25NYXRyaXgoKTtcbiAgICAgICAgICAgIGlmKHRoaXMuVlJNb2RlKXtcbiAgICAgICAgICAgICAgICB0aGlzLmNhbWVyYUwuZm92ID0gdGhpcy5jYW1lcmEuZm92O1xuICAgICAgICAgICAgICAgIHRoaXMuY2FtZXJhUi5mb3YgPSB0aGlzLmNhbWVyYS5mb3Y7XG4gICAgICAgICAgICAgICAgdGhpcy5jYW1lcmFMLnVwZGF0ZVByb2plY3Rpb25NYXRyaXgoKTtcbiAgICAgICAgICAgICAgICB0aGlzLmNhbWVyYVIudXBkYXRlUHJvamVjdGlvbk1hdHJpeCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9LFxuXG4gICAgICAgIGhhbmRsZVRvdWNoTW92ZTogZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgICAgICAgICBwYXJlbnQuaGFuZGxlVG91Y2hNb3ZlLmNhbGwodGhpcywgZXZlbnQpO1xuICAgICAgICAgICAgaWYodGhpcy5pc1VzZXJQaW5jaCl7XG4gICAgICAgICAgICAgICAgbGV0IGN1cnJlbnREaXN0YW5jZSA9IFV0aWwuZ2V0VG91Y2hlc0Rpc3RhbmNlKGV2ZW50LnRvdWNoZXMpO1xuICAgICAgICAgICAgICAgIGV2ZW50LndoZWVsRGVsdGFZID0gIChjdXJyZW50RGlzdGFuY2UgLSB0aGlzLm11bHRpVG91Y2hEaXN0YW5jZSkgKiAyO1xuICAgICAgICAgICAgICAgIHRoaXMuaGFuZGxlTW91c2VXaGVlbC5jYWxsKHRoaXMsIGV2ZW50KTtcbiAgICAgICAgICAgICAgICB0aGlzLm11bHRpVG91Y2hEaXN0YW5jZSA9IGN1cnJlbnREaXN0YW5jZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSxcblxuICAgICAgICByZW5kZXI6IGZ1bmN0aW9uKCl7XG4gICAgICAgICAgICBwYXJlbnQucmVuZGVyLmNhbGwodGhpcyk7XG4gICAgICAgICAgICB0aGlzLmNhbWVyYS50YXJnZXQueCA9IDUwMCAqIE1hdGguc2luKCB0aGlzLnBoaSApICogTWF0aC5jb3MoIHRoaXMudGhldGEgKTtcbiAgICAgICAgICAgIHRoaXMuY2FtZXJhLnRhcmdldC55ID0gNTAwICogTWF0aC5jb3MoIHRoaXMucGhpICk7XG4gICAgICAgICAgICB0aGlzLmNhbWVyYS50YXJnZXQueiA9IDUwMCAqIE1hdGguc2luKCB0aGlzLnBoaSApICogTWF0aC5zaW4oIHRoaXMudGhldGEgKTtcbiAgICAgICAgICAgIHRoaXMuY2FtZXJhLmxvb2tBdCggdGhpcy5jYW1lcmEudGFyZ2V0ICk7XG5cbiAgICAgICAgICAgIGlmKCF0aGlzLlZSTW9kZSl7XG4gICAgICAgICAgICAgICAgdGhpcy5yZW5kZXJlci5yZW5kZXIoIHRoaXMuc2NlbmUsIHRoaXMuY2FtZXJhICk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNle1xuICAgICAgICAgICAgICAgIHZhciB2aWV3UG9ydFdpZHRoID0gdGhpcy53aWR0aCAvIDIsIHZpZXdQb3J0SGVpZ2h0ID0gdGhpcy5oZWlnaHQ7XG4gICAgICAgICAgICAgICAgaWYodHlwZW9mIHZySE1EICE9PSAndW5kZWZpbmVkJyl7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY2FtZXJhTC5wcm9qZWN0aW9uTWF0cml4ID0gVXRpbC5mb3ZUb1Byb2plY3Rpb24oIHRoaXMuZXllRk9WTCwgdHJ1ZSwgdGhpcy5jYW1lcmEubmVhciwgdGhpcy5jYW1lcmEuZmFyICk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY2FtZXJhUi5wcm9qZWN0aW9uTWF0cml4ID0gVXRpbC5mb3ZUb1Byb2plY3Rpb24oIHRoaXMuZXllRk9WUiwgdHJ1ZSwgdGhpcy5jYW1lcmEubmVhciwgdGhpcy5jYW1lcmEuZmFyICk7XG4gICAgICAgICAgICAgICAgfWVsc2V7XG4gICAgICAgICAgICAgICAgICAgIHZhciBsb25MID0gdGhpcy5sb24gKyB0aGlzLnNldHRpbmdzLlZSR2FwRGVncmVlO1xuICAgICAgICAgICAgICAgICAgICB2YXIgbG9uUiA9IHRoaXMubG9uIC0gdGhpcy5zZXR0aW5ncy5WUkdhcERlZ3JlZTtcblxuICAgICAgICAgICAgICAgICAgICB2YXIgdGhldGFMID0gVEhSRUUuTWF0aC5kZWdUb1JhZCggbG9uTCApO1xuICAgICAgICAgICAgICAgICAgICB2YXIgdGhldGFSID0gVEhSRUUuTWF0aC5kZWdUb1JhZCggbG9uUiApO1xuXG4gICAgICAgICAgICAgICAgICAgIHZhciB0YXJnZXRMID0gVXRpbC5kZWVwQ29weSh0aGlzLmNhbWVyYS50YXJnZXQpO1xuICAgICAgICAgICAgICAgICAgICB0YXJnZXRMLnggPSA1MDAgKiBNYXRoLnNpbiggdGhpcy5waGkgKSAqIE1hdGguY29zKCB0aGV0YUwgKTtcbiAgICAgICAgICAgICAgICAgICAgdGFyZ2V0TC56ID0gNTAwICogTWF0aC5zaW4oIHRoaXMucGhpICkgKiBNYXRoLnNpbiggdGhldGFMICk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY2FtZXJhTC5sb29rQXQodGFyZ2V0TCk7XG5cbiAgICAgICAgICAgICAgICAgICAgdmFyIHRhcmdldFIgPSBVdGlsLmRlZXBDb3B5KHRoaXMuY2FtZXJhLnRhcmdldCk7XG4gICAgICAgICAgICAgICAgICAgIHRhcmdldFIueCA9IDUwMCAqIE1hdGguc2luKCB0aGlzLnBoaSApICogTWF0aC5jb3MoIHRoZXRhUiApO1xuICAgICAgICAgICAgICAgICAgICB0YXJnZXRSLnogPSA1MDAgKiBNYXRoLnNpbiggdGhpcy5waGkgKSAqIE1hdGguc2luKCB0aGV0YVIgKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jYW1lcmFSLmxvb2tBdCh0YXJnZXRSKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgLy8gcmVuZGVyIGxlZnQgZXllXG4gICAgICAgICAgICAgICAgdGhpcy5yZW5kZXJlci5zZXRWaWV3cG9ydCggMCwgMCwgdmlld1BvcnRXaWR0aCwgdmlld1BvcnRIZWlnaHQgKTtcbiAgICAgICAgICAgICAgICB0aGlzLnJlbmRlcmVyLnNldFNjaXNzb3IoIDAsIDAsIHZpZXdQb3J0V2lkdGgsIHZpZXdQb3J0SGVpZ2h0ICk7XG4gICAgICAgICAgICAgICAgdGhpcy5yZW5kZXJlci5yZW5kZXIoIHRoaXMuc2NlbmUsIHRoaXMuY2FtZXJhTCApO1xuXG4gICAgICAgICAgICAgICAgLy8gcmVuZGVyIHJpZ2h0IGV5ZVxuICAgICAgICAgICAgICAgIHRoaXMucmVuZGVyZXIuc2V0Vmlld3BvcnQoIHZpZXdQb3J0V2lkdGgsIDAsIHZpZXdQb3J0V2lkdGgsIHZpZXdQb3J0SGVpZ2h0ICk7XG4gICAgICAgICAgICAgICAgdGhpcy5yZW5kZXJlci5zZXRTY2lzc29yKCB2aWV3UG9ydFdpZHRoLCAwLCB2aWV3UG9ydFdpZHRoLCB2aWV3UG9ydEhlaWdodCApO1xuICAgICAgICAgICAgICAgIHRoaXMucmVuZGVyZXIucmVuZGVyKCB0aGlzLnNjZW5lLCB0aGlzLmNhbWVyYVIgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH0pO1xufTtcblxuZXhwb3J0IGRlZmF1bHQgQ2FudmFzO1xuIiwiLyoqXG4gKiBAYXV0aG9yIGFsdGVyZWRxIC8gaHR0cDovL2FsdGVyZWRxdWFsaWEuY29tL1xuICogQGF1dGhvciBtci5kb29iIC8gaHR0cDovL21yZG9vYi5jb20vXG4gKi9cblxuLy9pbiBjYXNlIGl0J3MgcnVubmluZyBvbiBub2RlLmpzXG5sZXQgd2luID0ge307XG5cbmlmICh0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgd2luID0gd2luZG93O1xufVxuXG52YXIgRGV0ZWN0b3IgPSB7XG5cbiAgICBjYW52YXM6ICEhIHdpbi5DYW52YXNSZW5kZXJpbmdDb250ZXh0MkQsXG4gICAgd2ViZ2w6ICggZnVuY3Rpb24gKCkge1xuXG4gICAgICAgIHRyeSB7XG5cbiAgICAgICAgICAgIHZhciBjYW52YXMgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCAnY2FudmFzJyApOyByZXR1cm4gISEgKCB3aW4uV2ViR0xSZW5kZXJpbmdDb250ZXh0ICYmICggY2FudmFzLmdldENvbnRleHQoICd3ZWJnbCcgKSB8fCBjYW52YXMuZ2V0Q29udGV4dCggJ2V4cGVyaW1lbnRhbC13ZWJnbCcgKSApICk7XG5cbiAgICAgICAgfSBjYXRjaCAoIGUgKSB7XG5cbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcblxuICAgICAgICB9XG5cbiAgICB9ICkoKSxcbiAgICB3b3JrZXJzOiAhISB3aW4uV29ya2VyLFxuICAgIGZpbGVhcGk6IHdpbi5GaWxlICYmIHdpbi5GaWxlUmVhZGVyICYmIHdpbi5GaWxlTGlzdCAmJiB3aW4uQmxvYixcblxuICAgICBDaGVja19WZXJzaW9uOiBmdW5jdGlvbigpIHtcbiAgICAgICAgIHZhciBydiA9IC0xOyAvLyBSZXR1cm4gdmFsdWUgYXNzdW1lcyBmYWlsdXJlLlxuXG4gICAgICAgICBpZiAobmF2aWdhdG9yLmFwcE5hbWUgPT0gJ01pY3Jvc29mdCBJbnRlcm5ldCBFeHBsb3JlcicpIHtcblxuICAgICAgICAgICAgIHZhciB1YSA9IG5hdmlnYXRvci51c2VyQWdlbnQsXG4gICAgICAgICAgICAgICAgIHJlID0gbmV3IFJlZ0V4cChcIk1TSUUgKFswLTldezEsfVtcXFxcLjAtOV17MCx9KVwiKTtcblxuICAgICAgICAgICAgIGlmIChyZS5leGVjKHVhKSAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICBydiA9IHBhcnNlRmxvYXQoUmVnRXhwLiQxKTtcbiAgICAgICAgICAgICB9XG4gICAgICAgICB9XG4gICAgICAgICBlbHNlIGlmIChuYXZpZ2F0b3IuYXBwTmFtZSA9PSBcIk5ldHNjYXBlXCIpIHtcbiAgICAgICAgICAgICAvLy8gaW4gSUUgMTEgdGhlIG5hdmlnYXRvci5hcHBWZXJzaW9uIHNheXMgJ3RyaWRlbnQnXG4gICAgICAgICAgICAgLy8vIGluIEVkZ2UgdGhlIG5hdmlnYXRvci5hcHBWZXJzaW9uIGRvZXMgbm90IHNheSB0cmlkZW50XG4gICAgICAgICAgICAgaWYgKG5hdmlnYXRvci5hcHBWZXJzaW9uLmluZGV4T2YoJ1RyaWRlbnQnKSAhPT0gLTEpIHJ2ID0gMTE7XG4gICAgICAgICAgICAgZWxzZXtcbiAgICAgICAgICAgICAgICAgdmFyIHVhID0gbmF2aWdhdG9yLnVzZXJBZ2VudDtcbiAgICAgICAgICAgICAgICAgdmFyIHJlID0gbmV3IFJlZ0V4cChcIkVkZ2VcXC8oWzAtOV17MSx9W1xcXFwuMC05XXswLH0pXCIpO1xuICAgICAgICAgICAgICAgICBpZiAocmUuZXhlYyh1YSkgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgIHJ2ID0gcGFyc2VGbG9hdChSZWdFeHAuJDEpO1xuICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgfVxuICAgICAgICAgfVxuXG4gICAgICAgICByZXR1cm4gcnY7XG4gICAgIH0sXG5cbiAgICBzdXBwb3J0VmlkZW9UZXh0dXJlOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIC8vaWUgMTEgYW5kIGVkZ2UgMTIgZG9lc24ndCBzdXBwb3J0IHZpZGVvIHRleHR1cmUuXG4gICAgICAgIHZhciB2ZXJzaW9uID0gdGhpcy5DaGVja19WZXJzaW9uKCk7XG4gICAgICAgIHJldHVybiAodmVyc2lvbiA9PT0gLTEgfHwgdmVyc2lvbiA+PSAxMyk7XG4gICAgfSxcblxuICAgIGlzTGl2ZVN0cmVhbU9uU2FmYXJpOiBmdW5jdGlvbiAodmlkZW9FbGVtZW50KSB7XG4gICAgICAgIC8vbGl2ZSBzdHJlYW0gb24gc2FmYXJpIGRvZXNuJ3Qgc3VwcG9ydCB2aWRlbyB0ZXh0dXJlXG4gICAgICAgIHZhciB2aWRlb1NvdXJjZXMgPSBbXS5zbGljZS5jYWxsKHZpZGVvRWxlbWVudC5xdWVyeVNlbGVjdG9yQWxsKFwic291cmNlXCIpKTtcbiAgICAgICAgdmFyIHJlc3VsdCA9IGZhbHNlO1xuICAgICAgICBpZih2aWRlb0VsZW1lbnQuc3JjICYmIHZpZGVvRWxlbWVudC5zcmMuaW5kZXhPZignLm0zdTgnKSA+IC0xKXtcbiAgICAgICAgICAgIHZpZGVvU291cmNlcy5wdXNoKHtcbiAgICAgICAgICAgICAgICBzcmM6IHZpZGVvRWxlbWVudC5zcmMsXG4gICAgICAgICAgICAgICAgdHlwZTogXCJhcHBsaWNhdGlvbi94LW1wZWdVUkxcIlxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgZm9yKHZhciBpID0gMDsgaSA8IHZpZGVvU291cmNlcy5sZW5ndGg7IGkrKyl7XG4gICAgICAgICAgICB2YXIgY3VycmVudFZpZGVvU291cmNlID0gdmlkZW9Tb3VyY2VzW2ldO1xuICAgICAgICAgICAgaWYoKGN1cnJlbnRWaWRlb1NvdXJjZS50eXBlID09PSBcImFwcGxpY2F0aW9uL3gtbXBlZ1VSTFwiIHx8IGN1cnJlbnRWaWRlb1NvdXJjZS50eXBlID09PSBcImFwcGxpY2F0aW9uL3ZuZC5hcHBsZS5tcGVndXJsXCIpICYmIC8oU2FmYXJpfEFwcGxlV2ViS2l0KS8udGVzdChuYXZpZ2F0b3IudXNlckFnZW50KSAmJiAvQXBwbGUgQ29tcHV0ZXIvLnRlc3QobmF2aWdhdG9yLnZlbmRvcikpe1xuICAgICAgICAgICAgICAgIHJlc3VsdCA9IHRydWU7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9LFxuXG4gICAgZ2V0V2ViR0xFcnJvck1lc3NhZ2U6IGZ1bmN0aW9uICgpIHtcblxuICAgICAgICB2YXIgZWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoICdkaXYnICk7XG4gICAgICAgIGVsZW1lbnQuaWQgPSAnd2ViZ2wtZXJyb3ItbWVzc2FnZSc7XG5cbiAgICAgICAgaWYgKCAhIHRoaXMud2ViZ2wgKSB7XG5cbiAgICAgICAgICAgIGVsZW1lbnQuaW5uZXJIVE1MID0gd2luLldlYkdMUmVuZGVyaW5nQ29udGV4dCA/IFtcbiAgICAgICAgICAgICAgICAnWW91ciBncmFwaGljcyBjYXJkIGRvZXMgbm90IHNlZW0gdG8gc3VwcG9ydCA8YSBocmVmPVwiaHR0cDovL2tocm9ub3Mub3JnL3dlYmdsL3dpa2kvR2V0dGluZ19hX1dlYkdMX0ltcGxlbWVudGF0aW9uXCIgc3R5bGU9XCJjb2xvcjojMDAwXCI+V2ViR0w8L2E+LjxiciAvPicsXG4gICAgICAgICAgICAgICAgJ0ZpbmQgb3V0IGhvdyB0byBnZXQgaXQgPGEgaHJlZj1cImh0dHA6Ly9nZXQud2ViZ2wub3JnL1wiIHN0eWxlPVwiY29sb3I6IzAwMFwiPmhlcmU8L2E+LidcbiAgICAgICAgICAgIF0uam9pbiggJ1xcbicgKSA6IFtcbiAgICAgICAgICAgICAgICAnWW91ciBicm93c2VyIGRvZXMgbm90IHNlZW0gdG8gc3VwcG9ydCA8YSBocmVmPVwiaHR0cDovL2tocm9ub3Mub3JnL3dlYmdsL3dpa2kvR2V0dGluZ19hX1dlYkdMX0ltcGxlbWVudGF0aW9uXCIgc3R5bGU9XCJjb2xvcjojMDAwXCI+V2ViR0w8L2E+Ljxici8+JyxcbiAgICAgICAgICAgICAgICAnRmluZCBvdXQgaG93IHRvIGdldCBpdCA8YSBocmVmPVwiaHR0cDovL2dldC53ZWJnbC5vcmcvXCIgc3R5bGU9XCJjb2xvcjojMDAwXCI+aGVyZTwvYT4uJ1xuICAgICAgICAgICAgXS5qb2luKCAnXFxuJyApO1xuXG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gZWxlbWVudDtcblxuICAgIH0sXG5cbiAgICBhZGRHZXRXZWJHTE1lc3NhZ2U6IGZ1bmN0aW9uICggcGFyYW1ldGVycyApIHtcblxuICAgICAgICB2YXIgcGFyZW50LCBpZCwgZWxlbWVudDtcblxuICAgICAgICBwYXJhbWV0ZXJzID0gcGFyYW1ldGVycyB8fCB7fTtcblxuICAgICAgICBwYXJlbnQgPSBwYXJhbWV0ZXJzLnBhcmVudCAhPT0gdW5kZWZpbmVkID8gcGFyYW1ldGVycy5wYXJlbnQgOiBkb2N1bWVudC5ib2R5O1xuICAgICAgICBpZCA9IHBhcmFtZXRlcnMuaWQgIT09IHVuZGVmaW5lZCA/IHBhcmFtZXRlcnMuaWQgOiAnb2xkaWUnO1xuXG4gICAgICAgIGVsZW1lbnQgPSBEZXRlY3Rvci5nZXRXZWJHTEVycm9yTWVzc2FnZSgpO1xuICAgICAgICBlbGVtZW50LmlkID0gaWQ7XG5cbiAgICAgICAgcGFyZW50LmFwcGVuZENoaWxkKCBlbGVtZW50ICk7XG5cbiAgICB9XG5cbn07XG5cbmV4cG9ydCBkZWZhdWx0IERldGVjdG9yOyIsIi8qKlxuICogQ3JlYXRlZCBieSB3ZW5zaGVuZy55YW4gb24gNS8yMy8xNi5cbiAqL1xudmFyIEhlbHBlckNhbnZhcyA9IGZ1bmN0aW9uKGJhc2VDb21wb25lbnQpe1xuICAgIHZhciBlbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnY2FudmFzJyk7XG4gICAgZWxlbWVudC5jbGFzc05hbWUgPSBcInZqcy12aWRlby1oZWxwZXItY2FudmFzXCI7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgY29uc3RydWN0b3I6IGZ1bmN0aW9uIGluaXQocGxheWVyLCBvcHRpb25zKXtcbiAgICAgICAgICAgIHRoaXMudmlkZW9FbGVtZW50ID0gb3B0aW9ucy52aWRlbztcbiAgICAgICAgICAgIHRoaXMud2lkdGggPSBvcHRpb25zLndpZHRoO1xuICAgICAgICAgICAgdGhpcy5oZWlnaHQgPSBvcHRpb25zLmhlaWdodDtcblxuICAgICAgICAgICAgZWxlbWVudC53aWR0aCA9IHRoaXMud2lkdGg7XG4gICAgICAgICAgICBlbGVtZW50LmhlaWdodCA9IHRoaXMuaGVpZ2h0O1xuICAgICAgICAgICAgZWxlbWVudC5zdHlsZS5kaXNwbGF5ID0gXCJub25lXCI7XG4gICAgICAgICAgICBvcHRpb25zLmVsID0gZWxlbWVudDtcblxuXG4gICAgICAgICAgICB0aGlzLmNvbnRleHQgPSBlbGVtZW50LmdldENvbnRleHQoJzJkJyk7XG4gICAgICAgICAgICB0aGlzLmNvbnRleHQuZHJhd0ltYWdlKHRoaXMudmlkZW9FbGVtZW50LCAwLCAwLCB0aGlzLndpZHRoLCB0aGlzLmhlaWdodCk7XG4gICAgICAgICAgICBiYXNlQ29tcG9uZW50LmNhbGwodGhpcywgcGxheWVyLCBvcHRpb25zKTtcbiAgICAgICAgfSxcbiAgICAgICAgXG4gICAgICAgIGdldENvbnRleHQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy5jb250ZXh0OyAgXG4gICAgICAgIH0sXG4gICAgICAgIFxuICAgICAgICB1cGRhdGU6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHRoaXMuY29udGV4dC5kcmF3SW1hZ2UodGhpcy52aWRlb0VsZW1lbnQsIDAsIDAsIHRoaXMud2lkdGgsIHRoaXMuaGVpZ2h0KTtcbiAgICAgICAgfSxcblxuICAgICAgICBlbDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmV0dXJuIGVsZW1lbnQ7XG4gICAgICAgIH1cbiAgICB9XG59O1xuXG5leHBvcnQgZGVmYXVsdCBIZWxwZXJDYW52YXM7IiwiLyoqXG4gKiBDcmVhdGVkIGJ5IHlhbndzaCBvbiA2LzYvMTYuXG4gKi9cbnZhciBNb2JpbGVCdWZmZXJpbmcgPSB7XG4gICAgcHJldl9jdXJyZW50VGltZTogMCxcbiAgICBjb3VudGVyOiAwLFxuICAgIFxuICAgIGlzQnVmZmVyaW5nOiBmdW5jdGlvbiAoY3VycmVudFRpbWUpIHtcbiAgICAgICAgaWYgKGN1cnJlbnRUaW1lID09IHRoaXMucHJldl9jdXJyZW50VGltZSkgdGhpcy5jb3VudGVyKys7XG4gICAgICAgIGVsc2UgdGhpcy5jb3VudGVyID0gMDtcbiAgICAgICAgdGhpcy5wcmV2X2N1cnJlbnRUaW1lID0gY3VycmVudFRpbWU7XG4gICAgICAgIGlmKHRoaXMuY291bnRlciA+IDEwKXtcbiAgICAgICAgICAgIC8vbm90IGxldCBjb3VudGVyIG92ZXJmbG93XG4gICAgICAgICAgICB0aGlzLmNvdW50ZXIgPSAxMDtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG59O1xuXG5leHBvcnQgZGVmYXVsdCBNb2JpbGVCdWZmZXJpbmc7IiwiLyoqXG4gKiBDcmVhdGVkIGJ5IHlhbndzaCBvbiA0LzQvMTYuXG4gKi9cblxudmFyIE5vdGljZSA9IGZ1bmN0aW9uKGJhc2VDb21wb25lbnQpe1xuICAgIHZhciBlbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgZWxlbWVudC5jbGFzc05hbWUgPSBcInZqcy12aWRlby1ub3RpY2UtbGFiZWxcIjtcblxuICAgIHJldHVybiB7XG4gICAgICAgIGNvbnN0cnVjdG9yOiBmdW5jdGlvbiBpbml0KHBsYXllciwgb3B0aW9ucyl7XG4gICAgICAgICAgICBpZih0eXBlb2Ygb3B0aW9ucy5Ob3RpY2VNZXNzYWdlID09IFwib2JqZWN0XCIpe1xuICAgICAgICAgICAgICAgIGVsZW1lbnQgPSBvcHRpb25zLk5vdGljZU1lc3NhZ2U7XG4gICAgICAgICAgICAgICAgb3B0aW9ucy5lbCA9IG9wdGlvbnMuTm90aWNlTWVzc2FnZTtcbiAgICAgICAgICAgIH1lbHNlIGlmKHR5cGVvZiBvcHRpb25zLk5vdGljZU1lc3NhZ2UgPT0gXCJzdHJpbmdcIil7XG4gICAgICAgICAgICAgICAgZWxlbWVudC5pbm5lckhUTUwgPSBvcHRpb25zLk5vdGljZU1lc3NhZ2U7XG4gICAgICAgICAgICAgICAgb3B0aW9ucy5lbCA9IGVsZW1lbnQ7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGJhc2VDb21wb25lbnQuY2FsbCh0aGlzLCBwbGF5ZXIsIG9wdGlvbnMpO1xuICAgICAgICB9LFxuXG4gICAgICAgIGVsOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gZWxlbWVudDtcbiAgICAgICAgfVxuICAgIH1cbn07XG5cbmV4cG9ydCBkZWZhdWx0IE5vdGljZTsiLCIvKipcbiAqXG4gKiAoYykgV2Vuc2hlbmcgWWFuIDx5YW53c2hAZ21haWwuY29tPlxuICogRGF0ZTogMTAvMjEvMTZcbiAqXG4gKiBGb3IgdGhlIGZ1bGwgY29weXJpZ2h0IGFuZCBsaWNlbnNlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlldyB0aGUgTElDRU5TRVxuICogZmlsZSB0aGF0IHdhcyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgc291cmNlIGNvZGUuXG4gKi9cbid1c2Ugc3RyaWN0JztcblxuaW1wb3J0IEJhc2VDYW52YXMgZnJvbSAnLi9CYXNlQ2FudmFzJztcbmltcG9ydCBVdGlsIGZyb20gJy4vVXRpbCc7XG5cbnZhciBUaHJlZURDYW52YXMgPSBmdW5jdGlvbiAoYmFzZUNvbXBvbmVudCwgVEhSRUUsIHNldHRpbmdzID0ge30pe1xuICAgIHZhciBwYXJlbnQgPSBCYXNlQ2FudmFzKGJhc2VDb21wb25lbnQsIFRIUkVFLCBzZXR0aW5ncyk7XG4gICAgcmV0dXJuIFV0aWwuZXh0ZW5kKHBhcmVudCwge1xuICAgICAgICBjb25zdHJ1Y3RvcjogZnVuY3Rpb24gaW5pdChwbGF5ZXIsIG9wdGlvbnMpe1xuICAgICAgICAgICAgcGFyZW50LmNvbnN0cnVjdG9yLmNhbGwodGhpcywgcGxheWVyLCBvcHRpb25zKTtcbiAgICAgICAgICAgIC8vb25seSBzaG93IGxlZnQgcGFydCBieSBkZWZhdWx0XG4gICAgICAgICAgICB0aGlzLlZSTW9kZSA9IGZhbHNlO1xuICAgICAgICAgICAgLy9kZWZpbmUgc2NlbmVcbiAgICAgICAgICAgIHRoaXMuc2NlbmUgPSBuZXcgVEhSRUUuU2NlbmUoKTtcblxuICAgICAgICAgICAgdmFyIGFzcGVjdFJhdGlvID0gdGhpcy53aWR0aCAvIHRoaXMuaGVpZ2h0O1xuICAgICAgICAgICAgLy9kZWZpbmUgY2FtZXJhXG4gICAgICAgICAgICB0aGlzLmNhbWVyYUwgPSBuZXcgVEhSRUUuUGVyc3BlY3RpdmVDYW1lcmEob3B0aW9ucy5pbml0Rm92LCBhc3BlY3RSYXRpbywgMSwgMjAwMCk7XG4gICAgICAgICAgICB0aGlzLmNhbWVyYUwudGFyZ2V0ID0gbmV3IFRIUkVFLlZlY3RvcjMoIDAsIDAsIDAgKTtcblxuICAgICAgICAgICAgdGhpcy5jYW1lcmFSID0gbmV3IFRIUkVFLlBlcnNwZWN0aXZlQ2FtZXJhKG9wdGlvbnMuaW5pdEZvdiwgYXNwZWN0UmF0aW8gLyAyLCAxLCAyMDAwKTtcbiAgICAgICAgICAgIHRoaXMuY2FtZXJhUi5wb3NpdGlvbi5zZXQoIDEwMDAsIDAsIDAgKTtcbiAgICAgICAgICAgIHRoaXMuY2FtZXJhUi50YXJnZXQgPSBuZXcgVEhSRUUuVmVjdG9yMyggMTAwMCwgMCwgMCApO1xuXG4gICAgICAgICAgICB2YXIgZ2VvbWV0cnlMID0gbmV3IFRIUkVFLlNwaGVyZUJ1ZmZlckdlb21ldHJ5KDUwMCwgNjAsIDQwKS50b05vbkluZGV4ZWQoKTtcbiAgICAgICAgICAgIHZhciBnZW9tZXRyeVIgPSBuZXcgVEhSRUUuU3BoZXJlQnVmZmVyR2VvbWV0cnkoNTAwLCA2MCwgNDApLnRvTm9uSW5kZXhlZCgpO1xuXG4gICAgICAgICAgICB2YXIgdXZzTCA9IGdlb21ldHJ5TC5hdHRyaWJ1dGVzLnV2LmFycmF5O1xuICAgICAgICAgICAgdmFyIG5vcm1hbHNMID0gZ2VvbWV0cnlMLmF0dHJpYnV0ZXMubm9ybWFsLmFycmF5O1xuICAgICAgICAgICAgZm9yICggdmFyIGkgPSAwOyBpIDwgbm9ybWFsc0wubGVuZ3RoIC8gMzsgaSArKyApIHtcbiAgICAgICAgICAgICAgICB1dnNMWyBpICogMiArIDEgXSA9IHV2c0xbIGkgKiAyICsgMSBdIC8gMjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdmFyIHV2c1IgPSBnZW9tZXRyeVIuYXR0cmlidXRlcy51di5hcnJheTtcbiAgICAgICAgICAgIHZhciBub3JtYWxzUiA9IGdlb21ldHJ5Ui5hdHRyaWJ1dGVzLm5vcm1hbC5hcnJheTtcbiAgICAgICAgICAgIGZvciAoIHZhciBpID0gMDsgaSA8IG5vcm1hbHNSLmxlbmd0aCAvIDM7IGkgKysgKSB7XG4gICAgICAgICAgICAgICAgdXZzUlsgaSAqIDIgKyAxIF0gPSB1dnNSWyBpICogMiArIDEgXSAvIDIgKyAwLjU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGdlb21ldHJ5TC5zY2FsZSggLSAxLCAxLCAxICk7XG4gICAgICAgICAgICBnZW9tZXRyeVIuc2NhbGUoIC0gMSwgMSwgMSApO1xuXG4gICAgICAgICAgICB0aGlzLm1lc2hMID0gbmV3IFRIUkVFLk1lc2goZ2VvbWV0cnlMLFxuICAgICAgICAgICAgICAgIG5ldyBUSFJFRS5NZXNoQmFzaWNNYXRlcmlhbCh7IG1hcDogdGhpcy50ZXh0dXJlfSlcbiAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgIHRoaXMubWVzaFIgPSBuZXcgVEhSRUUuTWVzaChnZW9tZXRyeVIsXG4gICAgICAgICAgICAgICAgbmV3IFRIUkVFLk1lc2hCYXNpY01hdGVyaWFsKHsgbWFwOiB0aGlzLnRleHR1cmV9KVxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIHRoaXMubWVzaFIucG9zaXRpb24uc2V0KDEwMDAsIDAsIDApO1xuXG4gICAgICAgICAgICB0aGlzLnNjZW5lLmFkZCh0aGlzLm1lc2hMKTtcblxuICAgICAgICAgICAgaWYob3B0aW9ucy5jYWxsYmFjaykgb3B0aW9ucy5jYWxsYmFjaygpO1xuICAgICAgICB9LFxuXG4gICAgICAgIGhhbmRsZVJlc2l6ZTogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcGFyZW50LmhhbmRsZVJlc2l6ZS5jYWxsKHRoaXMpO1xuICAgICAgICAgICAgdmFyIGFzcGVjdFJhdGlvID0gdGhpcy53aWR0aCAvIHRoaXMuaGVpZ2h0O1xuICAgICAgICAgICAgaWYoIXRoaXMuVlJNb2RlKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5jYW1lcmFMLmFzcGVjdCA9IGFzcGVjdFJhdGlvO1xuICAgICAgICAgICAgICAgIHRoaXMuY2FtZXJhTC51cGRhdGVQcm9qZWN0aW9uTWF0cml4KCk7XG4gICAgICAgICAgICB9ZWxzZXtcbiAgICAgICAgICAgICAgICBhc3BlY3RSYXRpbyAvPSAyO1xuICAgICAgICAgICAgICAgIHRoaXMuY2FtZXJhTC5hc3BlY3QgPSBhc3BlY3RSYXRpbztcbiAgICAgICAgICAgICAgICB0aGlzLmNhbWVyYVIuYXNwZWN0ID0gYXNwZWN0UmF0aW87XG4gICAgICAgICAgICAgICAgdGhpcy5jYW1lcmFMLnVwZGF0ZVByb2plY3Rpb25NYXRyaXgoKTtcbiAgICAgICAgICAgICAgICB0aGlzLmNhbWVyYVIudXBkYXRlUHJvamVjdGlvbk1hdHJpeCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9LFxuXG4gICAgICAgIGhhbmRsZU1vdXNlV2hlZWw6IGZ1bmN0aW9uKGV2ZW50KXtcbiAgICAgICAgICAgIHBhcmVudC5oYW5kbGVNb3VzZVdoZWVsKGV2ZW50KTtcbiAgICAgICAgICAgIC8vIFdlYktpdFxuICAgICAgICAgICAgaWYgKCBldmVudC53aGVlbERlbHRhWSApIHtcbiAgICAgICAgICAgICAgICB0aGlzLmNhbWVyYUwuZm92IC09IGV2ZW50LndoZWVsRGVsdGFZICogMC4wNTtcbiAgICAgICAgICAgICAgICAvLyBPcGVyYSAvIEV4cGxvcmVyIDlcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoIGV2ZW50LndoZWVsRGVsdGEgKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5jYW1lcmFMLmZvdiAtPSBldmVudC53aGVlbERlbHRhICogMC4wNTtcbiAgICAgICAgICAgICAgICAvLyBGaXJlZm94XG4gICAgICAgICAgICB9IGVsc2UgaWYgKCBldmVudC5kZXRhaWwgKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5jYW1lcmFMLmZvdiArPSBldmVudC5kZXRhaWwgKiAxLjA7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLmNhbWVyYUwuZm92ID0gTWF0aC5taW4odGhpcy5zZXR0aW5ncy5tYXhGb3YsIHRoaXMuY2FtZXJhTC5mb3YpO1xuICAgICAgICAgICAgdGhpcy5jYW1lcmFMLmZvdiA9IE1hdGgubWF4KHRoaXMuc2V0dGluZ3MubWluRm92LCB0aGlzLmNhbWVyYUwuZm92KTtcbiAgICAgICAgICAgIHRoaXMuY2FtZXJhTC51cGRhdGVQcm9qZWN0aW9uTWF0cml4KCk7XG4gICAgICAgICAgICBpZih0aGlzLlZSTW9kZSl7XG4gICAgICAgICAgICAgICAgdGhpcy5jYW1lcmFSLmZvdiA9IHRoaXMuY2FtZXJhTC5mb3Y7XG4gICAgICAgICAgICAgICAgdGhpcy5jYW1lcmFSLnVwZGF0ZVByb2plY3Rpb25NYXRyaXgoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSxcblxuICAgICAgICBlbmFibGVWUjogZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICB0aGlzLlZSTW9kZSA9IHRydWU7XG4gICAgICAgICAgICB0aGlzLnNjZW5lLmFkZCh0aGlzLm1lc2hSKTtcbiAgICAgICAgICAgIHRoaXMuaGFuZGxlUmVzaXplKCk7XG4gICAgICAgIH0sXG5cbiAgICAgICAgZGlzYWJsZVZSOiBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgIHRoaXMuVlJNb2RlID0gZmFsc2U7XG4gICAgICAgICAgICB0aGlzLnNjZW5lLnJlbW92ZSh0aGlzLm1lc2hSKTtcbiAgICAgICAgICAgIHRoaXMuaGFuZGxlUmVzaXplKCk7XG4gICAgICAgIH0sXG5cbiAgICAgICAgcmVuZGVyOiBmdW5jdGlvbigpe1xuICAgICAgICAgICAgcGFyZW50LnJlbmRlci5jYWxsKHRoaXMpO1xuICAgICAgICAgICAgdGhpcy5jYW1lcmFMLnRhcmdldC54ID0gNTAwICogTWF0aC5zaW4oIHRoaXMucGhpICkgKiBNYXRoLmNvcyggdGhpcy50aGV0YSApO1xuICAgICAgICAgICAgdGhpcy5jYW1lcmFMLnRhcmdldC55ID0gNTAwICogTWF0aC5jb3MoIHRoaXMucGhpICk7XG4gICAgICAgICAgICB0aGlzLmNhbWVyYUwudGFyZ2V0LnogPSA1MDAgKiBNYXRoLnNpbiggdGhpcy5waGkgKSAqIE1hdGguc2luKCB0aGlzLnRoZXRhICk7XG4gICAgICAgICAgICB0aGlzLmNhbWVyYUwubG9va0F0KHRoaXMuY2FtZXJhTC50YXJnZXQpO1xuXG4gICAgICAgICAgICBpZih0aGlzLlZSTW9kZSl7XG4gICAgICAgICAgICAgICAgdmFyIHZpZXdQb3J0V2lkdGggPSB0aGlzLndpZHRoIC8gMiwgdmlld1BvcnRIZWlnaHQgPSB0aGlzLmhlaWdodDtcbiAgICAgICAgICAgICAgICB0aGlzLmNhbWVyYVIudGFyZ2V0LnggPSAxMDAwICsgNTAwICogTWF0aC5zaW4oIHRoaXMucGhpICkgKiBNYXRoLmNvcyggdGhpcy50aGV0YSApO1xuICAgICAgICAgICAgICAgIHRoaXMuY2FtZXJhUi50YXJnZXQueSA9IDUwMCAqIE1hdGguY29zKCB0aGlzLnBoaSApO1xuICAgICAgICAgICAgICAgIHRoaXMuY2FtZXJhUi50YXJnZXQueiA9IDUwMCAqIE1hdGguc2luKCB0aGlzLnBoaSApICogTWF0aC5zaW4oIHRoaXMudGhldGEgKTtcbiAgICAgICAgICAgICAgICB0aGlzLmNhbWVyYVIubG9va0F0KCB0aGlzLmNhbWVyYVIudGFyZ2V0ICk7XG5cbiAgICAgICAgICAgICAgICAvLyByZW5kZXIgbGVmdCBleWVcbiAgICAgICAgICAgICAgICB0aGlzLnJlbmRlcmVyLnNldFZpZXdwb3J0KCAwLCAwLCB2aWV3UG9ydFdpZHRoLCB2aWV3UG9ydEhlaWdodCApO1xuICAgICAgICAgICAgICAgIHRoaXMucmVuZGVyZXIuc2V0U2Npc3NvciggMCwgMCwgdmlld1BvcnRXaWR0aCwgdmlld1BvcnRIZWlnaHQgKTtcbiAgICAgICAgICAgICAgICB0aGlzLnJlbmRlcmVyLnJlbmRlciggdGhpcy5zY2VuZSwgdGhpcy5jYW1lcmFMICk7XG5cbiAgICAgICAgICAgICAgICAvLyByZW5kZXIgcmlnaHQgZXllXG4gICAgICAgICAgICAgICAgdGhpcy5yZW5kZXJlci5zZXRWaWV3cG9ydCggdmlld1BvcnRXaWR0aCwgMCwgdmlld1BvcnRXaWR0aCwgdmlld1BvcnRIZWlnaHQgKTtcbiAgICAgICAgICAgICAgICB0aGlzLnJlbmRlcmVyLnNldFNjaXNzb3IoIHZpZXdQb3J0V2lkdGgsIDAsIHZpZXdQb3J0V2lkdGgsIHZpZXdQb3J0SGVpZ2h0ICk7XG4gICAgICAgICAgICAgICAgdGhpcy5yZW5kZXJlci5yZW5kZXIoIHRoaXMuc2NlbmUsIHRoaXMuY2FtZXJhUiApO1xuICAgICAgICAgICAgfWVsc2V7XG4gICAgICAgICAgICAgICAgdGhpcy5yZW5kZXJlci5yZW5kZXIoIHRoaXMuc2NlbmUsIHRoaXMuY2FtZXJhTCApO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfSk7XG59O1xuXG5leHBvcnQgZGVmYXVsdCBUaHJlZURDYW52YXM7IiwiLyoqXG4gKiBDcmVhdGVkIGJ5IHdlbnNoZW5nLnlhbiBvbiA0LzQvMTYuXG4gKi9cbmZ1bmN0aW9uIHdoaWNoVHJhbnNpdGlvbkV2ZW50KCl7XG4gICAgdmFyIHQ7XG4gICAgdmFyIGVsID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZmFrZWVsZW1lbnQnKTtcbiAgICB2YXIgdHJhbnNpdGlvbnMgPSB7XG4gICAgICAgICd0cmFuc2l0aW9uJzondHJhbnNpdGlvbmVuZCcsXG4gICAgICAgICdPVHJhbnNpdGlvbic6J29UcmFuc2l0aW9uRW5kJyxcbiAgICAgICAgJ01velRyYW5zaXRpb24nOid0cmFuc2l0aW9uZW5kJyxcbiAgICAgICAgJ1dlYmtpdFRyYW5zaXRpb24nOid3ZWJraXRUcmFuc2l0aW9uRW5kJ1xuICAgIH07XG5cbiAgICBmb3IodCBpbiB0cmFuc2l0aW9ucyl7XG4gICAgICAgIGlmKCBlbC5zdHlsZVt0XSAhPT0gdW5kZWZpbmVkICl7XG4gICAgICAgICAgICByZXR1cm4gdHJhbnNpdGlvbnNbdF07XG4gICAgICAgIH1cbiAgICB9XG59XG5cbmZ1bmN0aW9uIG1vYmlsZUFuZFRhYmxldGNoZWNrKCkge1xuICAgIHZhciBjaGVjayA9IGZhbHNlO1xuICAgIChmdW5jdGlvbihhKXtpZigvKGFuZHJvaWR8YmJcXGQrfG1lZWdvKS4rbW9iaWxlfGF2YW50Z298YmFkYVxcL3xibGFja2JlcnJ5fGJsYXplcnxjb21wYWx8ZWxhaW5lfGZlbm5lY3xoaXB0b3B8aWVtb2JpbGV8aXAoaG9uZXxvZCl8aXJpc3xraW5kbGV8bGdlIHxtYWVtb3xtaWRwfG1tcHxtb2JpbGUuK2ZpcmVmb3h8bmV0ZnJvbnR8b3BlcmEgbShvYnxpbilpfHBhbG0oIG9zKT98cGhvbmV8cChpeGl8cmUpXFwvfHBsdWNrZXJ8cG9ja2V0fHBzcHxzZXJpZXMoNHw2KTB8c3ltYmlhbnx0cmVvfHVwXFwuKGJyb3dzZXJ8bGluayl8dm9kYWZvbmV8d2FwfHdpbmRvd3MgY2V8eGRhfHhpaW5vfGFuZHJvaWR8aXBhZHxwbGF5Ym9va3xzaWxrL2kudGVzdChhKXx8LzEyMDd8NjMxMHw2NTkwfDNnc298NHRocHw1MFsxLTZdaXw3NzBzfDgwMnN8YSB3YXxhYmFjfGFjKGVyfG9vfHNcXC0pfGFpKGtvfHJuKXxhbChhdnxjYXxjbyl8YW1vaXxhbihleHxueXx5dyl8YXB0dXxhcihjaHxnbyl8YXModGV8dXMpfGF0dHd8YXUoZGl8XFwtbXxyIHxzICl8YXZhbnxiZShja3xsbHxucSl8YmkobGJ8cmQpfGJsKGFjfGF6KXxicihlfHYpd3xidW1ifGJ3XFwtKG58dSl8YzU1XFwvfGNhcGl8Y2N3YXxjZG1cXC18Y2VsbHxjaHRtfGNsZGN8Y21kXFwtfGNvKG1wfG5kKXxjcmF3fGRhKGl0fGxsfG5nKXxkYnRlfGRjXFwtc3xkZXZpfGRpY2F8ZG1vYnxkbyhjfHApb3xkcygxMnxcXC1kKXxlbCg0OXxhaSl8ZW0obDJ8dWwpfGVyKGljfGswKXxlc2w4fGV6KFs0LTddMHxvc3x3YXx6ZSl8ZmV0Y3xmbHkoXFwtfF8pfGcxIHV8ZzU2MHxnZW5lfGdmXFwtNXxnXFwtbW98Z28oXFwud3xvZCl8Z3IoYWR8dW4pfGhhaWV8aGNpdHxoZFxcLShtfHB8dCl8aGVpXFwtfGhpKHB0fHRhKXxocCggaXxpcCl8aHNcXC1jfGh0KGMoXFwtfCB8X3xhfGd8cHxzfHQpfHRwKXxodShhd3x0Yyl8aVxcLSgyMHxnb3xtYSl8aTIzMHxpYWMoIHxcXC18XFwvKXxpYnJvfGlkZWF8aWcwMXxpa29tfGltMWt8aW5ub3xpcGFxfGlyaXN8amEodHx2KWF8amJyb3xqZW11fGppZ3N8a2RkaXxrZWppfGtndCggfFxcLyl8a2xvbnxrcHQgfGt3Y1xcLXxreW8oY3xrKXxsZShub3x4aSl8bGcoIGd8XFwvKGt8bHx1KXw1MHw1NHxcXC1bYS13XSl8bGlid3xseW54fG0xXFwtd3xtM2dhfG01MFxcL3xtYSh0ZXx1aXx4byl8bWMoMDF8MjF8Y2EpfG1cXC1jcnxtZShyY3xyaSl8bWkobzh8b2F8dHMpfG1tZWZ8bW8oMDF8MDJ8Yml8ZGV8ZG98dChcXC18IHxvfHYpfHp6KXxtdCg1MHxwMXx2ICl8bXdicHxteXdhfG4xMFswLTJdfG4yMFsyLTNdfG4zMCgwfDIpfG41MCgwfDJ8NSl8bjcoMCgwfDEpfDEwKXxuZSgoY3xtKVxcLXxvbnx0Znx3Znx3Z3x3dCl8bm9rKDZ8aSl8bnpwaHxvMmltfG9wKHRpfHd2KXxvcmFufG93ZzF8cDgwMHxwYW4oYXxkfHQpfHBkeGd8cGcoMTN8XFwtKFsxLThdfGMpKXxwaGlsfHBpcmV8cGwoYXl8dWMpfHBuXFwtMnxwbyhja3xydHxzZSl8cHJveHxwc2lvfHB0XFwtZ3xxYVxcLWF8cWMoMDd8MTJ8MjF8MzJ8NjB8XFwtWzItN118aVxcLSl8cXRla3xyMzgwfHI2MDB8cmFrc3xyaW05fHJvKHZlfHpvKXxzNTVcXC98c2EoZ2V8bWF8bW18bXN8bnl8dmEpfHNjKDAxfGhcXC18b298cFxcLSl8c2RrXFwvfHNlKGMoXFwtfDB8MSl8NDd8bWN8bmR8cmkpfHNnaFxcLXxzaGFyfHNpZShcXC18bSl8c2tcXC0wfHNsKDQ1fGlkKXxzbShhbHxhcnxiM3xpdHx0NSl8c28oZnR8bnkpfHNwKDAxfGhcXC18dlxcLXx2ICl8c3koMDF8bWIpfHQyKDE4fDUwKXx0NigwMHwxMHwxOCl8dGEoZ3R8bGspfHRjbFxcLXx0ZGdcXC18dGVsKGl8bSl8dGltXFwtfHRcXC1tb3x0byhwbHxzaCl8dHMoNzB8bVxcLXxtM3xtNSl8dHhcXC05fHVwKFxcLmJ8ZzF8c2kpfHV0c3R8djQwMHx2NzUwfHZlcml8dmkocmd8dGUpfHZrKDQwfDVbMC0zXXxcXC12KXx2bTQwfHZvZGF8dnVsY3x2eCg1Mnw1M3w2MHw2MXw3MHw4MHw4MXw4M3w4NXw5OCl8dzNjKFxcLXwgKXx3ZWJjfHdoaXR8d2koZyB8bmN8bncpfHdtbGJ8d29udXx4NzAwfHlhc1xcLXx5b3VyfHpldG98enRlXFwtL2kudGVzdChhLnN1YnN0cigwLDQpKSljaGVjayA9IHRydWV9KShuYXZpZ2F0b3IudXNlckFnZW50fHxuYXZpZ2F0b3IudmVuZG9yfHx3aW5kb3cub3BlcmEpO1xuICAgIHJldHVybiBjaGVjaztcbn1cblxuZnVuY3Rpb24gaXNJb3MoKSB7XG4gICAgcmV0dXJuIC9pUGhvbmV8aVBhZHxpUG9kL2kudGVzdChuYXZpZ2F0b3IudXNlckFnZW50KTtcbn1cblxuZnVuY3Rpb24gaXNSZWFsSXBob25lKCkge1xuICAgIHJldHVybiAvaVBob25lfGlQb2QvaS50ZXN0KG5hdmlnYXRvci5wbGF0Zm9ybSk7XG59XG5cbi8vYWRvcHQgY29kZSBmcm9tOiBodHRwczovL2dpdGh1Yi5jb20vTW96VlIvdnItd2ViLWV4YW1wbGVzL2Jsb2IvbWFzdGVyL3RocmVlanMtdnItYm9pbGVycGxhdGUvanMvVlJFZmZlY3QuanNcbmZ1bmN0aW9uIGZvdlRvTkRDU2NhbGVPZmZzZXQoIGZvdiApIHtcbiAgICB2YXIgcHhzY2FsZSA9IDIuMCAvIChmb3YubGVmdFRhbiArIGZvdi5yaWdodFRhbik7XG4gICAgdmFyIHB4b2Zmc2V0ID0gKGZvdi5sZWZ0VGFuIC0gZm92LnJpZ2h0VGFuKSAqIHB4c2NhbGUgKiAwLjU7XG4gICAgdmFyIHB5c2NhbGUgPSAyLjAgLyAoZm92LnVwVGFuICsgZm92LmRvd25UYW4pO1xuICAgIHZhciBweW9mZnNldCA9IChmb3YudXBUYW4gLSBmb3YuZG93blRhbikgKiBweXNjYWxlICogMC41O1xuICAgIHJldHVybiB7IHNjYWxlOiBbIHB4c2NhbGUsIHB5c2NhbGUgXSwgb2Zmc2V0OiBbIHB4b2Zmc2V0LCBweW9mZnNldCBdIH07XG59XG5cbmZ1bmN0aW9uIGZvdlBvcnRUb1Byb2plY3Rpb24oIGZvdiwgcmlnaHRIYW5kZWQsIHpOZWFyLCB6RmFyICkge1xuXG4gICAgcmlnaHRIYW5kZWQgPSByaWdodEhhbmRlZCA9PT0gdW5kZWZpbmVkID8gdHJ1ZSA6IHJpZ2h0SGFuZGVkO1xuICAgIHpOZWFyID0gek5lYXIgPT09IHVuZGVmaW5lZCA/IDAuMDEgOiB6TmVhcjtcbiAgICB6RmFyID0gekZhciA9PT0gdW5kZWZpbmVkID8gMTAwMDAuMCA6IHpGYXI7XG5cbiAgICB2YXIgaGFuZGVkbmVzc1NjYWxlID0gcmlnaHRIYW5kZWQgPyAtMS4wIDogMS4wO1xuXG4gICAgLy8gc3RhcnQgd2l0aCBhbiBpZGVudGl0eSBtYXRyaXhcbiAgICB2YXIgbW9iaiA9IG5ldyBUSFJFRS5NYXRyaXg0KCk7XG4gICAgdmFyIG0gPSBtb2JqLmVsZW1lbnRzO1xuXG4gICAgLy8gYW5kIHdpdGggc2NhbGUvb2Zmc2V0IGluZm8gZm9yIG5vcm1hbGl6ZWQgZGV2aWNlIGNvb3Jkc1xuICAgIHZhciBzY2FsZUFuZE9mZnNldCA9IGZvdlRvTkRDU2NhbGVPZmZzZXQoZm92KTtcblxuICAgIC8vIFggcmVzdWx0LCBtYXAgY2xpcCBlZGdlcyB0byBbLXcsK3ddXG4gICAgbVswICogNCArIDBdID0gc2NhbGVBbmRPZmZzZXQuc2NhbGVbMF07XG4gICAgbVswICogNCArIDFdID0gMC4wO1xuICAgIG1bMCAqIDQgKyAyXSA9IHNjYWxlQW5kT2Zmc2V0Lm9mZnNldFswXSAqIGhhbmRlZG5lc3NTY2FsZTtcbiAgICBtWzAgKiA0ICsgM10gPSAwLjA7XG5cbiAgICAvLyBZIHJlc3VsdCwgbWFwIGNsaXAgZWRnZXMgdG8gWy13LCt3XVxuICAgIC8vIFkgb2Zmc2V0IGlzIG5lZ2F0ZWQgYmVjYXVzZSB0aGlzIHByb2ogbWF0cml4IHRyYW5zZm9ybXMgZnJvbSB3b3JsZCBjb29yZHMgd2l0aCBZPXVwLFxuICAgIC8vIGJ1dCB0aGUgTkRDIHNjYWxpbmcgaGFzIFk9ZG93biAodGhhbmtzIEQzRD8pXG4gICAgbVsxICogNCArIDBdID0gMC4wO1xuICAgIG1bMSAqIDQgKyAxXSA9IHNjYWxlQW5kT2Zmc2V0LnNjYWxlWzFdO1xuICAgIG1bMSAqIDQgKyAyXSA9IC1zY2FsZUFuZE9mZnNldC5vZmZzZXRbMV0gKiBoYW5kZWRuZXNzU2NhbGU7XG4gICAgbVsxICogNCArIDNdID0gMC4wO1xuXG4gICAgLy8gWiByZXN1bHQgKHVwIHRvIHRoZSBhcHApXG4gICAgbVsyICogNCArIDBdID0gMC4wO1xuICAgIG1bMiAqIDQgKyAxXSA9IDAuMDtcbiAgICBtWzIgKiA0ICsgMl0gPSB6RmFyIC8gKHpOZWFyIC0gekZhcikgKiAtaGFuZGVkbmVzc1NjYWxlO1xuICAgIG1bMiAqIDQgKyAzXSA9ICh6RmFyICogek5lYXIpIC8gKHpOZWFyIC0gekZhcik7XG5cbiAgICAvLyBXIHJlc3VsdCAoPSBaIGluKVxuICAgIG1bMyAqIDQgKyAwXSA9IDAuMDtcbiAgICBtWzMgKiA0ICsgMV0gPSAwLjA7XG4gICAgbVszICogNCArIDJdID0gaGFuZGVkbmVzc1NjYWxlO1xuICAgIG1bMyAqIDQgKyAzXSA9IDAuMDtcblxuICAgIG1vYmoudHJhbnNwb3NlKCk7XG5cbiAgICByZXR1cm4gbW9iajtcbn1cblxuZnVuY3Rpb24gZm92VG9Qcm9qZWN0aW9uKCBmb3YsIHJpZ2h0SGFuZGVkLCB6TmVhciwgekZhciApIHtcbiAgICB2YXIgREVHMlJBRCA9IE1hdGguUEkgLyAxODAuMDtcblxuICAgIHZhciBmb3ZQb3J0ID0ge1xuICAgICAgICB1cFRhbjogTWF0aC50YW4oIGZvdi51cERlZ3JlZXMgKiBERUcyUkFEICksXG4gICAgICAgIGRvd25UYW46IE1hdGgudGFuKCBmb3YuZG93bkRlZ3JlZXMgKiBERUcyUkFEICksXG4gICAgICAgIGxlZnRUYW46IE1hdGgudGFuKCBmb3YubGVmdERlZ3JlZXMgKiBERUcyUkFEICksXG4gICAgICAgIHJpZ2h0VGFuOiBNYXRoLnRhbiggZm92LnJpZ2h0RGVncmVlcyAqIERFRzJSQUQgKVxuICAgIH07XG5cbiAgICByZXR1cm4gZm92UG9ydFRvUHJvamVjdGlvbiggZm92UG9ydCwgcmlnaHRIYW5kZWQsIHpOZWFyLCB6RmFyICk7XG59XG5cbmZ1bmN0aW9uIGV4dGVuZChzdXBlckNsYXNzLCBzdWJDbGFzc01ldGhvZHMgPSB7fSlcbntcbiAgICBmb3IodmFyIG1ldGhvZCBpbiBzdXBlckNsYXNzKXtcbiAgICAgICAgaWYoc3VwZXJDbGFzcy5oYXNPd25Qcm9wZXJ0eShtZXRob2QpICYmICFzdWJDbGFzc01ldGhvZHMuaGFzT3duUHJvcGVydHkobWV0aG9kKSl7XG4gICAgICAgICAgICBzdWJDbGFzc01ldGhvZHNbbWV0aG9kXSA9IHN1cGVyQ2xhc3NbbWV0aG9kXTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gc3ViQ2xhc3NNZXRob2RzO1xufVxuXG5mdW5jdGlvbiBkZWVwQ29weShvYmopIHtcbiAgICB2YXIgdG8gPSB7fTtcblxuICAgIGZvciAodmFyIG5hbWUgaW4gb2JqKVxuICAgIHtcbiAgICAgICAgdG9bbmFtZV0gPSBvYmpbbmFtZV07XG4gICAgfVxuXG4gICAgcmV0dXJuIHRvO1xufVxuXG5mdW5jdGlvbiBnZXRUb3VjaGVzRGlzdGFuY2UodG91Y2hlcyl7XG4gICAgcmV0dXJuIE1hdGguc3FydChcbiAgICAgICAgKHRvdWNoZXNbMF0uY2xpZW50WC10b3VjaGVzWzFdLmNsaWVudFgpICogKHRvdWNoZXNbMF0uY2xpZW50WC10b3VjaGVzWzFdLmNsaWVudFgpICtcbiAgICAgICAgKHRvdWNoZXNbMF0uY2xpZW50WS10b3VjaGVzWzFdLmNsaWVudFkpICogKHRvdWNoZXNbMF0uY2xpZW50WS10b3VjaGVzWzFdLmNsaWVudFkpKTtcbn1cblxuZXhwb3J0IGRlZmF1bHQge1xuICAgIHdoaWNoVHJhbnNpdGlvbkV2ZW50OiB3aGljaFRyYW5zaXRpb25FdmVudCxcbiAgICBtb2JpbGVBbmRUYWJsZXRjaGVjazogbW9iaWxlQW5kVGFibGV0Y2hlY2ssXG4gICAgaXNJb3M6IGlzSW9zLFxuICAgIGlzUmVhbElwaG9uZTogaXNSZWFsSXBob25lLFxuICAgIGZvdlRvUHJvamVjdGlvbjogZm92VG9Qcm9qZWN0aW9uLFxuICAgIGV4dGVuZDogZXh0ZW5kLFxuICAgIGRlZXBDb3B5OiBkZWVwQ29weSxcbiAgICBnZXRUb3VjaGVzRGlzdGFuY2U6IGdldFRvdWNoZXNEaXN0YW5jZVxufTsiLCIvKipcbiAqIENyZWF0ZWQgYnkgeWFud3NoIG9uIDgvMTMvMTYuXG4gKi9cblxudmFyIFZSQnV0dG9uID0gZnVuY3Rpb24oQnV0dG9uQ29tcG9uZW50KXtcbiAgICByZXR1cm4ge1xuICAgICAgICBjb25zdHJ1Y3RvcjogZnVuY3Rpb24gaW5pdChwbGF5ZXIsIG9wdGlvbnMpe1xuICAgICAgICAgICAgQnV0dG9uQ29tcG9uZW50LmNhbGwodGhpcywgcGxheWVyLCBvcHRpb25zKTtcbiAgICAgICAgfSxcblxuICAgICAgICBidWlsZENTU0NsYXNzOiBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgIHJldHVybiBgdmpzLVZSLWNvbnRyb2wgJHtCdXR0b25Db21wb25lbnQucHJvdG90eXBlLmJ1aWxkQ1NTQ2xhc3MuY2FsbCh0aGlzKX1gO1xuICAgICAgICB9LFxuXG4gICAgICAgIGhhbmRsZUNsaWNrOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICB2YXIgY2FudmFzID0gdGhpcy5wbGF5ZXIoKS5nZXRDaGlsZChcIkNhbnZhc1wiKTtcbiAgICAgICAgICAgICghY2FudmFzLlZSTW9kZSk/IGNhbnZhcy5lbmFibGVWUigpIDogY2FudmFzLmRpc2FibGVWUigpO1xuICAgICAgICAgICAgKGNhbnZhcy5WUk1vZGUpPyB0aGlzLmFkZENsYXNzKFwiZW5hYmxlXCIpIDogdGhpcy5yZW1vdmVDbGFzcyhcImVuYWJsZVwiKTtcbiAgICAgICAgICAgIChjYW52YXMuVlJNb2RlKT8gIHRoaXMucGxheWVyKCkudHJpZ2dlcignVlJNb2RlT24nKTogIHRoaXMucGxheWVyKCkudHJpZ2dlcignVlJNb2RlT2ZmJyk7XG4gICAgICAgIH0sXG5cbiAgICAgICAgY29udHJvbFRleHRfOiBcIlZSXCJcbiAgICB9XG59O1xuXG5leHBvcnQgZGVmYXVsdCBWUkJ1dHRvbjsiLCIvKipcbiAqIENyZWF0ZWQgYnkgeWFud3NoIG9uIDQvMy8xNi5cbiAqL1xuJ3VzZSBzdHJpY3QnO1xuXG5pbXBvcnQgdXRpbCBmcm9tICcuL2xpYi9VdGlsJztcbmltcG9ydCBEZXRlY3RvciBmcm9tICcuL2xpYi9EZXRlY3Rvcic7XG5cbmNvbnN0IHJ1bk9uTW9iaWxlID0gKHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIpPyB1dGlsLm1vYmlsZUFuZFRhYmxldGNoZWNrKCkgOiBmYWxzZTtcblxuLy8gRGVmYXVsdCBvcHRpb25zIGZvciB0aGUgcGx1Z2luLlxuY29uc3QgZGVmYXVsdHMgPSB7XG4gICAgY2xpY2tBbmREcmFnOiBydW5Pbk1vYmlsZSxcbiAgICBzaG93Tm90aWNlOiB0cnVlLFxuICAgIE5vdGljZU1lc3NhZ2U6IFwiUGxlYXNlIHVzZSB5b3VyIG1vdXNlIGRyYWcgYW5kIGRyb3AgdGhlIHZpZGVvLlwiLFxuICAgIGF1dG9IaWRlTm90aWNlOiAzMDAwLFxuICAgIC8vbGltaXQgdGhlIHZpZGVvIHNpemUgd2hlbiB1c2VyIHNjcm9sbC5cbiAgICBzY3JvbGxhYmxlOiB0cnVlLFxuICAgIGluaXRGb3Y6IDc1LFxuICAgIG1heEZvdjogMTA1LFxuICAgIG1pbkZvdjogNTEsXG4gICAgLy9pbml0aWFsIHBvc2l0aW9uIGZvciB0aGUgdmlkZW9cbiAgICBpbml0TGF0OiAwLFxuICAgIGluaXRMb246IC0xODAsXG4gICAgLy9BIGZsb2F0IHZhbHVlIGJhY2sgdG8gY2VudGVyIHdoZW4gbW91c2Ugb3V0IHRoZSBjYW52YXMuIFRoZSBoaWdoZXIsIHRoZSBmYXN0ZXIuXG4gICAgcmV0dXJuU3RlcExhdDogMC41LFxuICAgIHJldHVyblN0ZXBMb246IDIsXG4gICAgYmFja1RvVmVydGljYWxDZW50ZXI6ICFydW5Pbk1vYmlsZSxcbiAgICBiYWNrVG9Ib3Jpem9uQ2VudGVyOiAhcnVuT25Nb2JpbGUsXG4gICAgY2xpY2tUb1RvZ2dsZTogZmFsc2UsXG5cbiAgICAvL2xpbWl0IHZpZXdhYmxlIHpvb21cbiAgICBtaW5MYXQ6IC04NSxcbiAgICBtYXhMYXQ6IDg1LFxuXG4gICAgbWluTG9uOiAtSW5maW5pdHksXG4gICAgbWF4TG9uOiBJbmZpbml0eSxcblxuICAgIHZpZGVvVHlwZTogXCJlcXVpcmVjdGFuZ3VsYXJcIixcblxuICAgIHJvdGF0ZVg6IDAsXG4gICAgcm90YXRlWTogMCxcbiAgICByb3RhdGVaOiAwLFxuXG4gICAgYXV0b01vYmlsZU9yaWVudGF0aW9uOiBmYWxzZSxcbiAgICBtb2JpbGVWaWJyYXRpb25WYWx1ZTogKHJ1bk9uTW9iaWxlICYmIHV0aWwuaXNJb3MoKSk/IDAuMDIyIDogMSxcblxuICAgIFZSRW5hYmxlOiB0cnVlLFxuICAgIFZSR2FwRGVncmVlOiAyLjUsXG5cbiAgICBjbG9zZVBhbm9yYW1hOiBmYWxzZSxcblxuICAgIGhlbHBlckNhbnZhczoge30sXG5cbiAgICBkdWFsRmlzaDoge1xuICAgICAgICB3aWR0aDogMTkyMCxcbiAgICAgICAgaGVpZ2h0OiAxMDgwLFxuICAgICAgICBjaXJjbGUxOiB7XG4gICAgICAgICAgICB4OiAwLjI0MDYyNSxcbiAgICAgICAgICAgIHk6IDAuNTUzNzA0LFxuICAgICAgICAgICAgcng6IDAuMjMzMzMsXG4gICAgICAgICAgICByeTogMC40MzE0OCxcbiAgICAgICAgICAgIGNvdmVyWDogMC45MTMsXG4gICAgICAgICAgICBjb3Zlclk6IDAuOVxuICAgICAgICB9LFxuICAgICAgICBjaXJjbGUyOiB7XG4gICAgICAgICAgICB4OiAwLjc1NzI5MixcbiAgICAgICAgICAgIHk6IDAuNTUzNzA0LFxuICAgICAgICAgICAgcng6IDAuMjMyMjkyLFxuICAgICAgICAgICAgcnk6IDAuNDI5NjI5NixcbiAgICAgICAgICAgIGNvdmVyWDogMC45MTMsXG4gICAgICAgICAgICBjb3Zlclk6IDAuOTMwOFxuICAgICAgICB9XG4gICAgfVxufTtcblxuZnVuY3Rpb24gcGxheWVyUmVzaXplKHBsYXllcil7XG4gICAgdmFyIGNhbnZhcyA9IHBsYXllci5nZXRDaGlsZCgnQ2FudmFzJyk7XG4gICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcGxheWVyLmVsKCkuc3R5bGUud2lkdGggPSB3aW5kb3cuaW5uZXJXaWR0aCArIFwicHhcIjtcbiAgICAgICAgcGxheWVyLmVsKCkuc3R5bGUuaGVpZ2h0ID0gd2luZG93LmlubmVySGVpZ2h0ICsgXCJweFwiO1xuICAgICAgICBjYW52YXMuaGFuZGxlUmVzaXplKCk7XG4gICAgfTtcbn1cblxuZnVuY3Rpb24gZnVsbHNjcmVlbk9uSU9TKHBsYXllciwgY2xpY2tGbikge1xuICAgIHZhciByZXNpemVGbiA9IHBsYXllclJlc2l6ZShwbGF5ZXIpO1xuICAgIHBsYXllci5jb250cm9sQmFyLmZ1bGxzY3JlZW5Ub2dnbGUub2ZmKFwidGFwXCIsIGNsaWNrRm4pO1xuICAgIHBsYXllci5jb250cm9sQmFyLmZ1bGxzY3JlZW5Ub2dnbGUub24oXCJ0YXBcIiwgZnVuY3Rpb24gZnVsbHNjcmVlbigpIHtcbiAgICAgICAgdmFyIGNhbnZhcyA9IHBsYXllci5nZXRDaGlsZCgnQ2FudmFzJyk7XG4gICAgICAgIGlmKCFwbGF5ZXIuaXNGdWxsc2NyZWVuKCkpe1xuICAgICAgICAgICAgLy9zZXQgdG8gZnVsbHNjcmVlblxuICAgICAgICAgICAgcGxheWVyLmlzRnVsbHNjcmVlbih0cnVlKTtcbiAgICAgICAgICAgIHBsYXllci5lbnRlckZ1bGxXaW5kb3coKTtcbiAgICAgICAgICAgIHJlc2l6ZUZuKCk7XG4gICAgICAgICAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihcImRldmljZW1vdGlvblwiLCByZXNpemVGbik7XG4gICAgICAgIH1lbHNle1xuICAgICAgICAgICAgcGxheWVyLmlzRnVsbHNjcmVlbihmYWxzZSk7XG4gICAgICAgICAgICBwbGF5ZXIuZXhpdEZ1bGxXaW5kb3coKTtcbiAgICAgICAgICAgIHBsYXllci5lbCgpLnN0eWxlLndpZHRoID0gXCJcIjtcbiAgICAgICAgICAgIHBsYXllci5lbCgpLnN0eWxlLmhlaWdodCA9IFwiXCI7XG4gICAgICAgICAgICBjYW52YXMuaGFuZGxlUmVzaXplKCk7XG4gICAgICAgICAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcihcImRldmljZW1vdGlvblwiLCByZXNpemVGbik7XG4gICAgICAgIH1cbiAgICB9KTtcbn1cblxuLyoqXG4gKiBGdW5jdGlvbiB0byBpbnZva2Ugd2hlbiB0aGUgcGxheWVyIGlzIHJlYWR5LlxuICpcbiAqIFRoaXMgaXMgYSBncmVhdCBwbGFjZSBmb3IgeW91ciBwbHVnaW4gdG8gaW5pdGlhbGl6ZSBpdHNlbGYuIFdoZW4gdGhpc1xuICogZnVuY3Rpb24gaXMgY2FsbGVkLCB0aGUgcGxheWVyIHdpbGwgaGF2ZSBpdHMgRE9NIGFuZCBjaGlsZCBjb21wb25lbnRzXG4gKiBpbiBwbGFjZS5cbiAqXG4gKiBAZnVuY3Rpb24gb25QbGF5ZXJSZWFkeVxuICogQHBhcmFtICAgIHtQbGF5ZXJ9IHBsYXllclxuICogQHBhcmFtICAgIHtPYmplY3R9IFtvcHRpb25zPXt9XVxuICovXG5jb25zdCBvblBsYXllclJlYWR5ID0gKHBsYXllciwgb3B0aW9ucywgc2V0dGluZ3MpID0+IHtcbiAgICBwbGF5ZXIuYWRkQ2xhc3MoJ3Zqcy1wYW5vcmFtYScpO1xuICAgIGlmKCFEZXRlY3Rvci53ZWJnbCl7XG4gICAgICAgIFBvcHVwTm90aWZpY2F0aW9uKHBsYXllciwge1xuICAgICAgICAgICAgTm90aWNlTWVzc2FnZTogRGV0ZWN0b3IuZ2V0V2ViR0xFcnJvck1lc3NhZ2UoKSxcbiAgICAgICAgICAgIGF1dG9IaWRlTm90aWNlOiBvcHRpb25zLmF1dG9IaWRlTm90aWNlXG4gICAgICAgIH0pO1xuICAgICAgICBpZihvcHRpb25zLmNhbGxiYWNrKXtcbiAgICAgICAgICAgIG9wdGlvbnMuY2FsbGJhY2soKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIHBsYXllci5hZGRDaGlsZCgnQ2FudmFzJywgdXRpbC5kZWVwQ29weShvcHRpb25zKSk7XG4gICAgdmFyIGNhbnZhcyA9IHBsYXllci5nZXRDaGlsZCgnQ2FudmFzJyk7XG4gICAgaWYocnVuT25Nb2JpbGUpe1xuICAgICAgICB2YXIgdmlkZW9FbGVtZW50ID0gc2V0dGluZ3MuZ2V0VGVjaChwbGF5ZXIpO1xuICAgICAgICBpZih1dGlsLmlzUmVhbElwaG9uZSgpKXtcbiAgICAgICAgICAgIGxldCBtYWtlVmlkZW9QbGF5YWJsZUlubGluZSA9IHJlcXVpcmUoJ2lwaG9uZS1pbmxpbmUtdmlkZW8nKTtcbiAgICAgICAgICAgIC8vaW9zIDEwIHN1cHBvcnQgcGxheSB2aWRlbyBpbmxpbmVcbiAgICAgICAgICAgIHZpZGVvRWxlbWVudC5zZXRBdHRyaWJ1dGUoXCJwbGF5c2lubGluZVwiLCBcIlwiKTtcbiAgICAgICAgICAgIG1ha2VWaWRlb1BsYXlhYmxlSW5saW5lKHZpZGVvRWxlbWVudCwgdHJ1ZSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYodXRpbC5pc0lvcygpKXtcbiAgICAgICAgICAgIGZ1bGxzY3JlZW5PbklPUyhwbGF5ZXIsIHNldHRpbmdzLmdldEZ1bGxzY3JlZW5Ub2dnbGVDbGlja0ZuKHBsYXllcikpO1xuICAgICAgICB9XG4gICAgICAgIHBsYXllci5hZGRDbGFzcyhcInZqcy1wYW5vcmFtYS1tb2JpbGUtaW5saW5lLXZpZGVvXCIpO1xuICAgICAgICBwbGF5ZXIucmVtb3ZlQ2xhc3MoXCJ2anMtdXNpbmctbmF0aXZlLWNvbnRyb2xzXCIpO1xuICAgICAgICBjYW52YXMucGxheU9uTW9iaWxlKCk7XG4gICAgfVxuICAgIGlmKG9wdGlvbnMuc2hvd05vdGljZSl7XG4gICAgICAgIHBsYXllci5vbihcInBsYXlpbmdcIiwgZnVuY3Rpb24oKXtcbiAgICAgICAgICAgIFBvcHVwTm90aWZpY2F0aW9uKHBsYXllciwgdXRpbC5kZWVwQ29weShvcHRpb25zKSk7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBpZihvcHRpb25zLlZSRW5hYmxlKXtcbiAgICAgICAgcGxheWVyLmNvbnRyb2xCYXIuYWRkQ2hpbGQoJ1ZSQnV0dG9uJywge30sIHBsYXllci5jb250cm9sQmFyLmNoaWxkcmVuKCkubGVuZ3RoIC0gMSk7XG4gICAgfVxuICAgIGNhbnZhcy5oaWRlKCk7XG4gICAgcGxheWVyLm9uKFwicGxheVwiLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNhbnZhcy5zaG93KCk7XG4gICAgfSk7XG4gICAgcGxheWVyLm9uKFwiZnVsbHNjcmVlbmNoYW5nZVwiLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNhbnZhcy5oYW5kbGVSZXNpemUoKTtcbiAgICB9KTtcbiAgICBpZihvcHRpb25zLmNhbGxiYWNrKSBvcHRpb25zLmNhbGxiYWNrKCk7XG59O1xuXG5jb25zdCBQb3B1cE5vdGlmaWNhdGlvbiA9IChwbGF5ZXIsIG9wdGlvbnMgPSB7XG4gICAgTm90aWNlTWVzc2FnZTogXCJcIlxufSkgPT4ge1xuICAgIHZhciBub3RpY2UgPSBwbGF5ZXIuYWRkQ2hpbGQoJ05vdGljZScsIG9wdGlvbnMpO1xuXG4gICAgaWYob3B0aW9ucy5hdXRvSGlkZU5vdGljZSA+IDApe1xuICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIG5vdGljZS5hZGRDbGFzcyhcInZqcy12aWRlby1ub3RpY2UtZmFkZU91dFwiKTtcbiAgICAgICAgICAgIHZhciB0cmFuc2l0aW9uRXZlbnQgPSB1dGlsLndoaWNoVHJhbnNpdGlvbkV2ZW50KCk7XG4gICAgICAgICAgICB2YXIgaGlkZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBub3RpY2UuaGlkZSgpO1xuICAgICAgICAgICAgICAgIG5vdGljZS5yZW1vdmVDbGFzcyhcInZqcy12aWRlby1ub3RpY2UtZmFkZU91dFwiKTtcbiAgICAgICAgICAgICAgICBub3RpY2Uub2ZmKHRyYW5zaXRpb25FdmVudCwgaGlkZSk7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgbm90aWNlLm9uKHRyYW5zaXRpb25FdmVudCwgaGlkZSk7XG4gICAgICAgIH0sIG9wdGlvbnMuYXV0b0hpZGVOb3RpY2UpO1xuICAgIH1cbn07XG5cbmNvbnN0IHBsdWdpbiA9IGZ1bmN0aW9uKHNldHRpbmdzID0ge30pe1xuICAgIC8qKlxuICAgICAqIEEgdmlkZW8uanMgcGx1Z2luLlxuICAgICAqXG4gICAgICogSW4gdGhlIHBsdWdpbiBmdW5jdGlvbiwgdGhlIHZhbHVlIG9mIGB0aGlzYCBpcyBhIHZpZGVvLmpzIGBQbGF5ZXJgXG4gICAgICogaW5zdGFuY2UuIFlvdSBjYW5ub3QgcmVseSBvbiB0aGUgcGxheWVyIGJlaW5nIGluIGEgXCJyZWFkeVwiIHN0YXRlIGhlcmUsXG4gICAgICogZGVwZW5kaW5nIG9uIGhvdyB0aGUgcGx1Z2luIGlzIGludm9rZWQuIFRoaXMgbWF5IG9yIG1heSBub3QgYmUgaW1wb3J0YW50XG4gICAgICogdG8geW91OyBpZiBub3QsIHJlbW92ZSB0aGUgd2FpdCBmb3IgXCJyZWFkeVwiIVxuICAgICAqXG4gICAgICogQGZ1bmN0aW9uIHBhbm9yYW1hXG4gICAgICogQHBhcmFtICAgIHtPYmplY3R9IFtvcHRpb25zPXt9XVxuICAgICAqICAgICAgICAgICBBbiBvYmplY3Qgb2Ygb3B0aW9ucyBsZWZ0IHRvIHRoZSBwbHVnaW4gYXV0aG9yIHRvIGRlZmluZS5cbiAgICAgKi9cbiAgICBjb25zdCB2aWRlb1R5cGVzID0gW1wiZXF1aXJlY3Rhbmd1bGFyXCIsIFwiZmlzaGV5ZVwiLCBcIjNkVmlkZW9cIiwgXCJkdWFsX2Zpc2hleWVcIl07XG4gICAgY29uc3QgcGFub3JhbWEgPSBmdW5jdGlvbihvcHRpb25zKSB7XG4gICAgICAgIGlmKHNldHRpbmdzLm1lcmdlT3B0aW9uKSBvcHRpb25zID0gc2V0dGluZ3MubWVyZ2VPcHRpb24oZGVmYXVsdHMsIG9wdGlvbnMpO1xuICAgICAgICBpZih0eXBlb2Ygc2V0dGluZ3MuX2luaXQgPT09IFwidW5kZWZpbmVkXCIgfHwgdHlwZW9mIHNldHRpbmdzLl9pbml0ICE9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoXCJwbHVnaW4gbXVzdCBpbXBsZW1lbnQgaW5pdCBmdW5jdGlvbigpLlwiKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBpZih2aWRlb1R5cGVzLmluZGV4T2Yob3B0aW9ucy52aWRlb1R5cGUpID09IC0xKSBvcHRpb25zLnZpZGVvVHlwZSA9IGRlZmF1bHRzLnZpZGVvVHlwZTtcbiAgICAgICAgc2V0dGluZ3MuX2luaXQob3B0aW9ucyk7XG4gICAgICAgIC8qIGltcGxlbWVudCBjYWxsYmFjayBmdW5jdGlvbiB3aGVuIHZpZGVvanMgaXMgcmVhZHkgKi9cbiAgICAgICAgdGhpcy5yZWFkeSgoKSA9PiB7XG4gICAgICAgICAgICBvblBsYXllclJlYWR5KHRoaXMsIG9wdGlvbnMsIHNldHRpbmdzKTtcbiAgICAgICAgfSk7XG4gICAgfTtcblxuLy8gSW5jbHVkZSB0aGUgdmVyc2lvbiBudW1iZXIuXG4gICAgcGFub3JhbWEuVkVSU0lPTiA9ICcwLjEuNyc7XG5cbiAgICByZXR1cm4gcGFub3JhbWE7XG59O1xuXG5leHBvcnQgZGVmYXVsdCBwbHVnaW47XG4iLCIndXNlIHN0cmljdCc7XG5cbmltcG9ydCBDYW52YXMgIGZyb20gJy4vbGliL0NhbnZhcyc7XG5pbXBvcnQgVGhyZWVEQ2FudmFzIGZyb20gJy4vbGliL1RocmVlQ2FudmFzJztcbmltcG9ydCBOb3RpY2UgIGZyb20gJy4vbGliL05vdGljZSc7XG5pbXBvcnQgSGVscGVyQ2FudmFzIGZyb20gJy4vbGliL0hlbHBlckNhbnZhcyc7XG5pbXBvcnQgVlJCdXR0b24gZnJvbSAnLi9saWIvVlJCdXR0b24nO1xuaW1wb3J0IHBhbm9yYW1hIGZyb20gJy4vcGx1Z2luJztcblxuZnVuY3Rpb24gZ2V0VGVjaChwbGF5ZXIpIHtcbiAgICByZXR1cm4gcGxheWVyLnRlY2goeyBJV2lsbE5vdFVzZVRoaXNJblBsdWdpbnM6IHRydWUgfSkuZWwoKTtcbn1cblxuZnVuY3Rpb24gZ2V0RnVsbHNjcmVlblRvZ2dsZUNsaWNrRm4ocGxheWVyKSB7XG4gICAgcmV0dXJuIHBsYXllci5jb250cm9sQmFyLmZ1bGxzY3JlZW5Ub2dnbGUuaGFuZGxlQ2xpY2tcbn1cblxudmFyIGNvbXBvbmVudCA9IHZpZGVvanMuZ2V0Q29tcG9uZW50KCdDb21wb25lbnQnKTtcblxudmFyIG5vdGljZSA9IE5vdGljZShjb21wb25lbnQpO1xudmlkZW9qcy5yZWdpc3RlckNvbXBvbmVudCgnTm90aWNlJywgdmlkZW9qcy5leHRlbmQoY29tcG9uZW50LCBub3RpY2UpKTtcblxudmFyIGhlbHBlckNhbnZhcyA9IEhlbHBlckNhbnZhcyhjb21wb25lbnQpO1xudmlkZW9qcy5yZWdpc3RlckNvbXBvbmVudCgnSGVscGVyQ2FudmFzJywgdmlkZW9qcy5leHRlbmQoY29tcG9uZW50LCBoZWxwZXJDYW52YXMpKTtcblxudmFyIGJ1dHRvbiA9IHZpZGVvanMuZ2V0Q29tcG9uZW50KFwiQnV0dG9uXCIpO1xudmFyIHZyQnRuID0gVlJCdXR0b24oYnV0dG9uKTtcbnZpZGVvanMucmVnaXN0ZXJDb21wb25lbnQoJ1ZSQnV0dG9uJywgdmlkZW9qcy5leHRlbmQoYnV0dG9uLCB2ckJ0bikpO1xuXG4vLyBSZWdpc3RlciB0aGUgcGx1Z2luIHdpdGggdmlkZW8uanMuXG52aWRlb2pzLnBsdWdpbigncGFub3JhbWEnLCBwYW5vcmFtYSh7XG4gICAgX2luaXQ6IGZ1bmN0aW9uKG9wdGlvbnMpe1xuICAgICAgICB2YXIgY2FudmFzID0gKG9wdGlvbnMudmlkZW9UeXBlICE9PSBcIjNkVmlkZW9cIik/XG4gICAgICAgICAgICBDYW52YXMoY29tcG9uZW50LCB3aW5kb3cuVEhSRUUsIHtcbiAgICAgICAgICAgICAgICBnZXRUZWNoOiBnZXRUZWNoXG4gICAgICAgICAgICB9KSA6XG4gICAgICAgICAgICBUaHJlZURDYW52YXMoY29tcG9uZW50LCB3aW5kb3cuVEhSRUUsIHtcbiAgICAgICAgICAgICAgICBnZXRUZWNoOiBnZXRUZWNoXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgdmlkZW9qcy5yZWdpc3RlckNvbXBvbmVudCgnQ2FudmFzJywgdmlkZW9qcy5leHRlbmQoY29tcG9uZW50LCBjYW52YXMpKTtcbiAgICB9LFxuICAgIG1lcmdlT3B0aW9uOiBmdW5jdGlvbiAoZGVmYXVsdHMsIG9wdGlvbnMpIHtcbiAgICAgICAgcmV0dXJuIHZpZGVvanMubWVyZ2VPcHRpb25zKGRlZmF1bHRzLCBvcHRpb25zKTtcbiAgICB9LFxuICAgIGdldFRlY2g6IGdldFRlY2gsXG4gICAgZ2V0RnVsbHNjcmVlblRvZ2dsZUNsaWNrRm46IGdldEZ1bGxzY3JlZW5Ub2dnbGVDbGlja0ZuXG59KSk7XG4iXX0=
|