1(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){ 2/*! npm.im/intervalometer */ 3'use strict'; 4 5Object.defineProperty(exports, '__esModule', { value: true }); 6 7function intervalometer(cb, request, cancel, requestParameter) { 8 var requestId; 9 var previousLoopTime; 10 function loop(now) { 11 // must be requested before cb() because that might call .stop() 12 requestId = request(loop, requestParameter); 13 14 // called with "ms since last call". 0 on start() 15 cb(now - (previousLoopTime || now)); 16 17 previousLoopTime = now; 18 } 19 return { 20 start: function start() { 21 if (!requestId) { // prevent double starts 22 loop(0); 23 } 24 }, 25 stop: function stop() { 26 cancel(requestId); 27 requestId = null; 28 previousLoopTime = 0; 29 } 30 }; 31} 32 33function frameIntervalometer(cb) { 34 return intervalometer(cb, requestAnimationFrame, cancelAnimationFrame); 35} 36 37function timerIntervalometer(cb, delay) { 38 return intervalometer(cb, setTimeout, clearTimeout, delay); 39} 40 41exports.intervalometer = intervalometer; 42exports.frameIntervalometer = frameIntervalometer; 43exports.timerIntervalometer = timerIntervalometer; 44},{}],2:[function(require,module,exports){ 45/*! npm.im/iphone-inline-video */ 46'use strict'; 47 48function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } 49 50var Symbol = _interopDefault(require('poor-mans-symbol')); 51var intervalometer = require('intervalometer'); 52 53function preventEvent(element, eventName, toggleProperty, preventWithProperty) { 54 function handler(e) { 55 if (Boolean(element[toggleProperty]) === Boolean(preventWithProperty)) { 56 e.stopImmediatePropagation(); 57 // console.log(eventName, 'prevented on', element); 58 } 59 delete element[toggleProperty]; 60 } 61 element.addEventListener(eventName, handler, false); 62 63 // Return handler to allow to disable the prevention. Usage: 64 // const preventionHandler = preventEvent(el, 'click'); 65 // el.removeEventHandler('click', preventionHandler); 66 return handler; 67} 68 69function proxyProperty(object, propertyName, sourceObject, copyFirst) { 70 function get() { 71 return sourceObject[propertyName]; 72 } 73 function set(value) { 74 sourceObject[propertyName] = value; 75 } 76 77 if (copyFirst) { 78 set(object[propertyName]); 79 } 80 81 Object.defineProperty(object, propertyName, {get: get, set: set}); 82} 83 84function proxyEvent(object, eventName, sourceObject) { 85 sourceObject.addEventListener(eventName, function () { return object.dispatchEvent(new Event(eventName)); }); 86} 87 88function dispatchEventAsync(element, type) { 89 Promise.resolve().then(function () { 90 element.dispatchEvent(new Event(type)); 91 }); 92} 93 94// iOS 10 adds support for native inline playback + silent autoplay 95var isWhitelisted = /iPhone|iPod/i.test(navigator.userAgent) && !matchMedia('(-webkit-video-playable-inline)').matches; 96 97var ಠ= Symbol(); 98var ಠevent = Symbol(); 99var ಠplay = Symbol('nativeplay'); 100var ಠpause = Symbol('nativepause'); 101 102/** 103 * UTILS 104 */ 105 106function getAudioFromVideo(video) { 107 var audio = new Audio(); 108 proxyEvent(video, 'play', audio); 109 proxyEvent(video, 'playing', audio); 110 proxyEvent(video, 'pause', audio); 111 audio.crossOrigin = video.crossOrigin; 112 113 // 'data:' causes audio.networkState > 0 114 // which then allows to keep <audio> in a resumable playing state 115 // i.e. once you set a real src it will keep playing if it was if .play() was called 116 audio.src = video.src || video.currentSrc || 'data:'; 117 118 // if (audio.src === 'data:') { 119 // TODO: wait for video to be selected 120 // } 121 return audio; 122} 123 124var lastRequests = []; 125var requestIndex = 0; 126var lastTimeupdateEvent; 127 128function setTime(video, time, rememberOnly) { 129 // allow one timeupdate event every 200+ ms 130 if ((lastTimeupdateEvent || 0) + 200 < Date.now()) { 131 video[ಠevent] = true; 132 lastTimeupdateEvent = Date.now(); 133 } 134 if (!rememberOnly) { 135 video.currentTime = time; 136 } 137 lastRequests[++requestIndex % 3] = time * 100 | 0 / 100; 138} 139 140function isPlayerEnded(player) { 141 return player.driver.currentTime >= player.video.duration; 142} 143 144function update(timeDiff) { 145 var player = this; 146 // console.log('update', player.video.readyState, player.video.networkState, player.driver.readyState, player.driver.networkState, player.driver.paused); 147 if (player.video.readyState >= player.video.HAVE_FUTURE_DATA) { 148 if (!player.hasAudio) { 149 player.driver.currentTime = player.video.currentTime + ((timeDiff * player.video.playbackRate) / 1000); 150 if (player.video.loop && isPlayerEnded(player)) { 151 player.driver.currentTime = 0; 152 } 153 } 154 setTime(player.video, player.driver.currentTime); 155 } else if (player.video.networkState === player.video.NETWORK_IDLE && !player.video.buffered.length) { 156 // this should happen when the source is available but: 157 // - it's potentially playing (.paused === false) 158 // - it's not ready to play 159 // - it's not loading 160 // If it hasAudio, that will be loaded in the 'emptied' handler below 161 player.video.load(); 162 // console.log('Will load'); 163 } 164 165 // console.assert(player.video.currentTime === player.driver.currentTime, 'Video not updating!'); 166 167 if (player.video.ended) { 168 delete player.video[ಠevent]; // allow timeupdate event 169 player.video.pause(true); 170 } 171} 172 173/** 174 * METHODS 175 */ 176 177function play() { 178 // console.log('play'); 179 var video = this; 180 var player = video[ಠ]; 181 182 // if it's fullscreen, use the native player 183 if (video.webkitDisplayingFullscreen) { 184 video[ಠplay](); 185 return; 186 } 187 188 if (player.driver.src !== 'data:' && player.driver.src !== video.src) { 189 // console.log('src changed on play', video.src); 190 setTime(video, 0, true); 191 player.driver.src = video.src; 192 } 193 194 if (!video.paused) { 195 return; 196 } 197 player.paused = false;
198 199 if (!video.buffered.length) { 200 // .load() causes the emptied event 201 // the alternative is .play()+.pause() but that triggers play/pause events, even worse 202 // possibly the alternative is preventing this event only once 203 video.load(); 204 } 205 206 player.driver.play(); 207 player.updater.start(); 208 209 if (!player.hasAudio) { 210 dispatchEventAsync(video, 'play'); 211 if (player.video.readyState >= player.video.HAVE_ENOUGH_DATA) { 212 // console.log('onplay'); 213 dispatchEventAsync(video, 'playing'); 214 } 215 } 216} 217function pause(forceEvents) { 218 // console.log('pause'); 219 var video = this; 220 var player = video[ಠ]; 221 222 player.driver.pause(); 223 player.updater.stop(); 224 225 // if it's fullscreen, the developer the native player.pause() 226 // This is at the end of pause() because it also 227 // needs to make sure that the simulation is paused 228 if (video.webkitDisplayingFullscreen) { 229 video[ಠpause](); 230 } 231 232 if (player.paused && !forceEvents) { 233 return; 234 } 235 236 player.paused = true; 237 if (!player.hasAudio) { 238 dispatchEventAsync(video, 'pause'); 239 } 240 if (video.ended) { 241 video[ಠevent] = true; 242 dispatchEventAsync(video, 'ended'); 243 } 244} 245 246/** 247 * SETUP 248 */ 249 250function addPlayer(video, hasAudio) { 251 var player = video[ಠ] = {}; 252 player.paused = true; // track whether 'pause' events have been fired 253 player.hasAudio = hasAudio; 254 player.video = video; 255 player.updater = intervalometer.frameIntervalometer(update.bind(player)); 256 257 if (hasAudio) { 258 player.driver = getAudioFromVideo(video); 259 } else { 260 video.addEventListener('canplay', function () { 261 if (!video.paused) { 262 // console.log('oncanplay'); 263 dispatchEventAsync(video, 'playing'); 264 } 265 }); 266 player.driver = { 267 src: video.src || video.currentSrc || 'data:', 268 muted: true, 269 paused: true, 270 pause: function () { 271 player.driver.paused = true; 272 }, 273 play: function () { 274 player.driver.paused = false; 275 // media automatically goes to 0 if .play() is called when it's done 276 if (isPlayerEnded(player)) { 277 setTime(video, 0); 278 } 279 }, 280 get ended() { 281 return isPlayerEnded(player); 282 } 283 }; 284 } 285 286 // .load() causes the emptied event 287 video.addEventListener('emptied', function () { 288 // console.log('driver src is', player.driver.src); 289 var wasEmpty = !player.driver.src || player.driver.src === 'data:'; 290 if (player.driver.src && player.driver.src !== video.src) { 291 // console.log('src changed to', video.src); 292 setTime(video, 0, true); 293 player.driver.src = video.src; 294 // playing videos will only keep playing if no src was present when .play()âed 295 if (wasEmpty) { 296 player.driver.play(); 297 } else { 298 player.updater.stop(); 299 } 300 } 301 }, false); 302 303 // stop programmatic player when OS takes over 304 video.addEventListener('webkitbeginfullscreen', function () { 305 if (!video.paused) { 306 // make sure that the <audio> and the syncer/updater are stopped 307 video.pause(); 308 309 // play video natively 310 video[ಠplay](); 311 } else if (hasAudio && !player.driver.buffered.length) { 312 // if the first play is native, 313 // the <audio> needs to be buffered manually 314 // so when the fullscreen ends, it can be set to the same current time 315 player.driver.load(); 316 } 317 }); 318 if (hasAudio) { 319 video.addEventListener('webkitendfullscreen', function () { 320 // sync audio to new video position 321 player.driver.currentTime = video.currentTime; 322 // console.assert(player.driver.currentTime === video.currentTime, 'Audio not synced'); 323 }); 324 325 // allow seeking 326 video.addEventListener('seeking', function () { 327 if (lastRequests.indexOf(video.currentTime * 100 | 0 / 100) < 0) { 328 // console.log('User-requested seeking'); 329 player.driver.currentTime = video.currentTime; 330 } 331 }); 332 } 333} 334 335function overloadAPI(video) { 336 var player = video[ಠ]; 337 video[ಠplay] = video.play; 338 video[ಠpause] = video.pause; 339 video.play = play; 340 video.pause = pause; 341 proxyProperty(video, 'paused', player.driver); 342 proxyProperty(video, 'muted', player.driver, true); 343 proxyProperty(video, 'playbackRate', player.driver, true); 344 proxyProperty(video, 'ended', player.driver); 345 proxyProperty(video, 'loop', player.driver, true); 346 preventEvent(video, 'seeking'); 347 preventEvent(video, 'seeked'); 348 preventEvent(video, 'timeupdate', ಠevent, false); 349 preventEvent(video, 'ended', ಠevent, false); // prevent occasional native ended events 350} 351 352function enableInlineVideo(video, hasAudio, onlyWhitelisted) { 353 if ( hasAudio === void 0 ) hasAudio = true; 354 if ( onlyWhitelisted === void 0 ) onlyWhitelisted = true; 355 356 if ((onlyWhitelisted && !isWhitelisted) || video[ಠ]) { 357 return; 358 } 359 addPlayer(video, hasAudio); 360 overloadAPI(video); 361 video.classList.add('IIV'); 362 if (!hasAudio && video.autoplay) { 363 video.play(); 364 } 365 if (!/iPhone|iPod|iPad/.test(navigator.platform)) { 366 console.warn('iphone-inline-video is not guaranteed to work in emulated environments'); 367 } 368} 369 370enableInlineVideo.isWhitelisted = isWhitelisted; 371 372module.exports = enableInlineVideo; 373},{"intervalometer":1,"poor-mans-symbol":3}],3:[function(require,module,exports){ 374'use strict'; 375 376var index = typeof Symbol === 'undefined' ? function (description) { 377 return '@' + (description || '@') + Math.random(); 378} : Symbol; 379 380module.exports = index; 381},{}],4:[function(require,module,exports){ 382/** 383 * 384 * (c) Wensheng Yan <[email protected]> 385 * Date: 10/30/16 386 * 387 * For the full copyright and license information, please view the LICENSE 388 * file that was distributed with this source code. 389 */ 390'use strict'; 391 392Object.defineProperty(exports, "__esModule", { 393 value: true 394}); 395 396var _Detector = require('../lib/Detector'); 397 398var _Detector2 = _interopRequireDefault(_Detector); 399 400var _MobileBuffering = require('../lib/MobileBuffering'); 401 402var _MobileBuffering2 = _interopRequireDefault(_MobileBuffering); 403 404function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 405 406var HAVE_CURRENT_DATA = 2; 407 408var BaseCanvas = function BaseCanvas(baseComponent, THREE) { 409 var settings = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; 410 411 return { 412 constructor: function init(player, options) { 413 this.settings = options; 414 //basic settings
415 this.width = player.el().offsetWidth, this.height = player.el().offsetHeight; 416 this.lon = options.initLon, this.lat = options.initLat, this.phi = 0, this.theta = 0; 417 this.videoType = options.videoType; 418 this.clickToToggle = options.clickToToggle; 419 this.mouseDown = false; 420 this.isUserInteracting = false; 421 422 //define render 423 this.renderer = new THREE.WebGLRenderer(); 424 this.renderer.setPixelRatio(window.devicePixelRatio); 425 this.renderer.setSize(this.width, this.height); 426 this.renderer.autoClear = false; 427 this.renderer.setClearColor(0x000000, 1); 428 429 //define texture, on ie 11, we need additional helper canvas to solve rendering issue. 430 var video = settings.getTech(player); 431 this.supportVideoTexture = _Detector2.default.supportVideoTexture(); 432 this.liveStreamOnSafari = _Detector2.default.isLiveStreamOnSafari(video); 433 if (this.liveStreamOnSafari) this.supportVideoTexture = false; 434 if (!this.supportVideoTexture) { 435 this.helperCanvas = player.addChild("HelperCanvas", { 436 video: video, 437 width: this.width, 438 height: this.height 439 }); 440 var context = this.helperCanvas.el(); 441 this.texture = new THREE.Texture(context); 442 } else { 443 this.texture = new THREE.Texture(video); 444 } 445 446 video.style.display = "none"; 447 448 this.texture.generateMipmaps = false; 449 this.texture.minFilter = THREE.LinearFilter; 450 this.texture.maxFilter = THREE.LinearFilter; 451 this.texture.format = THREE.RGBFormat; 452 453 this.el_ = this.renderer.domElement; 454 this.el_.classList.add('vjs-video-canvas'); 455 456 options.el = this.el_; 457 baseComponent.call(this, player, options); 458 459 this.attachControlEvents(); 460 this.player().on("play", function () { 461 this.time = new Date().getTime(); 462 this.animate(); 463 }.bind(this)); 464 }, 465 466 attachControlEvents: function attachControlEvents() { 467 this.on('mousemove', this.handleMouseMove.bind(this)); 468 this.on('touchmove', this.handleMouseMove.bind(this)); 469 this.on('mousedown', this.handleMouseDown.bind(this)); 470 this.on('touchstart', this.handleMouseDown.bind(this)); 471 this.on('mouseup', this.handleMouseUp.bind(this)); 472 this.on('touchend', this.handleMouseUp.bind(this)); 473 if (this.settings.scrollable) { 474 this.on('mousewheel', this.handleMouseWheel.bind(this)); 475 this.on('MozMousePixelScroll', this.handleMouseWheel.bind(this)); 476 } 477 this.on('mouseenter', this.handleMouseEnter.bind(this)); 478 this.on('mouseleave', this.handleMouseLease.bind(this)); 479 }, 480 481 handleResize: function handleResize() { 482 this.width = this.player().el().offsetWidth, this.height = this.player().el().offsetHeight; 483 this.renderer.setSize(this.width, this.height); 484 }, 485 486 handleMouseUp: function handleMouseUp(event) { 487 this.mouseDown = false; 488 if (this.clickToToggle) { 489 var clientX = event.clientX || event.changedTouches && event.changedTouches[0].clientX; 490 var clientY = event.clientY || event.changedTouches && event.changedTouches[0].clientY; 491 if (typeof clientX === "undefined" || clientY === "undefined") return; 492 var diffX = Math.abs(clientX - this.onPointerDownPointerX); 493 var diffY = Math.abs(clientY - this.onPointerDownPointerY); 494 if (diffX < 0.1 && diffY < 0.1) this.player().paused() ? this.player().play() : this.player().pause(); 495 } 496 }, 497 498 handleMouseDown: function handleMouseDown(event) { 499 event.preventDefault(); 500 var clientX = event.clientX || event.touches && event.touches[0].clientX; 501 var clientY = event.clientY || event.touches && event.touches[0].clientY; 502 if (typeof clientX === "undefined" || clientY === "undefined") return; 503 this.mouseDown = true; 504 this.onPointerDownPointerX = clientX; 505 this.onPointerDownPointerY = clientY; 506 this.onPointerDownLon = this.lon; 507 this.onPointerDownLat = this.lat; 508 }, 509 510 handleMouseMove: function handleMouseMove(event) { 511 var clientX = event.clientX || event.touches && event.touches[0].clientX; 512 var clientY = event.clientY || event.touches && event.touches[0].clientY; 513 if (typeof clientX === "undefined" || clientY === "undefined") return; 514 if (this.settings.clickAndDrag) { 515 if (this.mouseDown) { 516 this.lon = (this.onPointerDownPointerX - clientX) * 0.2 + this.onPointerDownLon; 517 this.lat = (clientY - this.onPointerDownPointerY) * 0.2 + this.onPointerDownLat; 518 } 519 } else { 520 var x = event.pageX - this.el_.offsetLeft; 521 var y = event.pageY - this.el_.offsetTop; 522 this.lon = x / this.width * 430 - 225; 523 this.lat = y / this.height * -180 + 90; 524 } 525 }, 526 527 handleMobileOrientation: function handleMobileOrientation(event) { 528 if (typeof event.rotationRate === "undefined") return; 529 var x = event.rotationRate.alpha; 530 var y = event.rotationRate.beta; 531 var portrait = typeof event.portrait !== "undefined" ? event.portrait : window.matchMedia("(orientation: portrait)").matches; 532 var landscape = typeof event.landscape !== "undefined" ? event.landscape : window.matchMedia("(orientation: landscape)").matches; 533 var orientation = event.orientation || window.orientation; 534 535 if (portrait) { 536 this.lon = this.lon - y * this.settings.mobileVibrationValue; 537 this.lat = this.lat + x * this.settings.mobileVibrationValue; 538 } else if (landscape) { 539 var orientationDegree = -90; 540 if (typeof orientation != "undefined") { 541 orientationDegree = orientation; 542 } 543 544 this.lon = orientationDegree == -90 ? this.lon + x * this.settings.mobileVibrationValue : this.lon - x * this.settings.mobileVibrationValue; 545 this.lat = orientationDegree == -90 ? this.lat + y * this.settings.mobileVibrationValue : this.lat - y * this.settings.mobileVibrationValue; 546 } 547 }, 548 549 handleMouseWheel: function handleMouseWheel(event) { 550 event.stopPropagation(); 551 event.preventDefault(); 552 }, 553 554 handleMouseEnter: function handleMouseEnter(event) { 555 this.isUserInteracting = true; 556 }, 557 558 handleMouseLease: function handleMouseLease(event) { 559 this.isUserInteracting = false;
560 }, 561 562 animate: function animate() { 563 this.requestAnimationId = requestAnimationFrame(this.animate.bind(this)); 564 if (!this.player().paused()) { 565 if (typeof this.texture !== "undefined" && (!this.isPlayOnMobile && this.player().readyState() >= HAVE_CURRENT_DATA || this.isPlayOnMobile && this.player().hasClass("vjs-playing"))) { 566 var ct = new Date().getTime(); 567 if (ct - this.time >= 30) { 568 this.texture.needsUpdate = true; 569 this.time = ct; 570 } 571 if (this.isPlayOnMobile) { 572 var currentTime = this.player().currentTime(); 573 if (_MobileBuffering2.default.isBuffering(currentTime)) { 574 if (!this.player().hasClass("vjs-panorama-mobile-inline-video-buffering")) { 575 this.player().addClass("vjs-panorama-mobile-inline-video-buffering"); 576 } 577 } else { 578 if (this.player().hasClass("vjs-panorama-mobile-inline-video-buffering")) { 579 this.player().removeClass("vjs-panorama-mobile-inline-video-buffering"); 580 } 581 } 582 } 583 } 584 } 585 this.render(); 586 }, 587 588 render: function render() { 589 if (!this.isUserInteracting) { 590 var symbolLat = this.lat > this.settings.initLat ? -1 : 1; 591 var symbolLon = this.lon > this.settings.initLon ? -1 : 1; 592 if (this.settings.backToVerticalCenter) { 593 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; 594 } 595 if (this.settings.backToHorizonCenter) { 596 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; 597 } 598 } 599 this.lat = Math.max(this.settings.minLat, Math.min(this.settings.maxLat, this.lat)); 600 this.lon = Math.max(this.settings.minLon, Math.min(this.settings.maxLon, this.lon)); 601 this.phi = THREE.Math.degToRad(90 - this.lat); 602 this.theta = THREE.Math.degToRad(this.lon); 603 604 if (!this.supportVideoTexture) { 605 this.helperCanvas.update(); 606 } 607 this.renderer.clear(); 608 }, 609 610 playOnMobile: function playOnMobile() { 611 this.isPlayOnMobile = true; 612 if (this.settings.autoMobileOrientation) window.addEventListener('devicemotion', this.handleMobileOrientation.bind(this)); 613 }, 614 615 el: function el() { 616 return this.el_; 617 } 618 }; 619}; 620 621exports.default = BaseCanvas; 622 623},{"../lib/Detector":6,"../lib/MobileBuffering":8}],5:[function(require,module,exports){ 624'use strict'; 625 626Object.defineProperty(exports, "__esModule", { 627 value: true 628}); 629 630var _BaseCanvas = require('./BaseCanvas'); 631 632var _BaseCanvas2 = _interopRequireDefault(_BaseCanvas); 633 634var _Util = require('./Util'); 635 636var _Util2 = _interopRequireDefault(_Util); 637 638function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 639 640/** 641 * Created by yanwsh on 4/3/16. 642 */ 643 644var Canvas = function Canvas(baseComponent, THREE) { 645 var settings = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; 646 647 var parent = (0, _BaseCanvas2.default)(baseComponent, THREE, settings); 648 649 return _Util2.default.extend(parent, { 650 constructor: function init(player, options) { 651 parent.constructor.call(this, player, options); 652 653 this.VRMode = false; 654 //define scene 655 this.scene = new THREE.Scene(); 656 //define camera 657 this.camera = new THREE.PerspectiveCamera(options.initFov, this.width / this.height, 1, 2000); 658 this.camera.target = new THREE.Vector3(0, 0, 0); 659 660 //define geometry 661 var geometry = this.videoType === "equirectangular" ? new THREE.SphereGeometry(500, 60, 40) : new THREE.SphereBufferGeometry(500, 60, 40).toNonIndexed(); 662 if (this.videoType === "fisheye") { 663 var normals = geometry.attributes.normal.array; 664 var uvs = geometry.attributes.uv.array; 665 for (var i = 0, l = normals.length / 3; i < l; i++) { 666 var x = normals[i * 3 + 0]; 667 var y = normals[i * 3 + 1]; 668 var z = normals[i * 3 + 2]; 669 670 var r = Math.asin(Math.sqrt(x * x + z * z) / Math.sqrt(x * x + y * y + z * z)) / Math.PI; 671 if (y < 0) r = 1 - r; 672 var theta = x == 0 && z == 0 ? 0 : Math.acos(x / Math.sqrt(x * x + z * z)); 673 if (z < 0) theta = theta * -1; 674 uvs[i * 2 + 0] = -0.8 * r * Math.cos(theta) + 0.5; 675 uvs[i * 2 + 1] = 0.8 * r * Math.sin(theta) + 0.5; 676 } 677 geometry.rotateX(options.rotateX); 678 geometry.rotateY(options.rotateY); 679 geometry.rotateZ(options.rotateZ); 680 } 681 geometry.scale(-1, 1, 1); 682 //define mesh 683 this.mesh = new THREE.Mesh(geometry, new THREE.MeshBasicMaterial({ map: this.texture })); 684 //this.mesh.scale.x = -1; 685 this.scene.add(this.mesh); 686 }, 687 688 enableVR: function enableVR() { 689 this.VRMode = true; 690 if (typeof vrHMD !== 'undefined') { 691 var eyeParamsL = vrHMD.getEyeParameters('left'); 692 var eyeParamsR = vrHMD.getEyeParameters('right'); 693 694 this.eyeFOVL = eyeParamsL.recommendedFieldOfView; 695 this.eyeFOVR = eyeParamsR.recommendedFieldOfView; 696 } 697 698 this.cameraL = new THREE.PerspectiveCamera(this.camera.fov, this.width / 2 / this.height, 1, 2000); 699 this.cameraR = new THREE.PerspectiveCamera(this.camera.fov, this.width / 2 / this.height, 1, 2000); 700 }, 701 702 disableVR: function disableVR() { 703 this.VRMode = false;
704 this.renderer.setViewport(0, 0, this.width, this.height); 705 this.renderer.setScissor(0, 0, this.width, this.height); 706 }, 707 708 handleResize: function handleResize() { 709 parent.handleResize.call(this); 710 this.camera.aspect = this.width / this.height; 711 this.camera.updateProjectionMatrix(); 712 if (this.VRMode) { 713 this.cameraL.aspect = this.camera.aspect / 2; 714 this.cameraR.aspect = this.camera.aspect / 2; 715 this.cameraL.updateProjectionMatrix(); 716 this.cameraR.updateProjectionMatrix(); 717 } 718 }, 719 720 handleMouseWheel: function handleMouseWheel(event) { 721 parent.handleMouseWheel(event); 722 // WebKit 723 if (event.wheelDeltaY) { 724 this.camera.fov -= event.wheelDeltaY * 0.05; 725 // Opera / Explorer 9 726 } else if (event.wheelDelta) { 727 this.camera.fov -= event.wheelDelta * 0.05; 728 // Firefox 729 } else if (event.detail) { 730 this.camera.fov += event.detail * 1.0; 731 } 732 this.camera.fov = Math.min(this.settings.maxFov, this.camera.fov); 733 this.camera.fov = Math.max(this.settings.minFov, this.camera.fov); 734 this.camera.updateProjectionMatrix(); 735 if (this.VRMode) { 736 this.cameraL.fov = this.camera.fov; 737 this.cameraR.fov = this.camera.fov; 738 this.cameraL.updateProjectionMatrix(); 739 this.cameraR.updateProjectionMatrix(); 740 } 741 }, 742 743 render: function render() { 744 parent.render.call(this); 745 this.camera.target.x = 500 * Math.sin(this.phi) * Math.cos(this.theta); 746 this.camera.target.y = 500 * Math.cos(this.phi); 747 this.camera.target.z = 500 * Math.sin(this.phi) * Math.sin(this.theta); 748 this.camera.lookAt(this.camera.target); 749 750 if (!this.VRMode) { 751 this.renderer.render(this.scene, this.camera); 752 } else { 753 var viewPortWidth = this.width / 2, 754 viewPortHeight = this.height; 755 if (typeof vrHMD !== 'undefined') { 756 this.cameraL.projectionMatrix = _Util2.default.fovToProjection(this.eyeFOVL, true, this.camera.near, this.camera.far); 757 this.cameraR.projectionMatrix = _Util2.default.fovToProjection(this.eyeFOVR, true, this.camera.near, this.camera.far); 758 } else { 759 var lonL = this.lon + this.settings.VRGapDegree; 760 var lonR = this.lon - this.settings.VRGapDegree; 761 762 var thetaL = THREE.Math.degToRad(lonL); 763 var thetaR = THREE.Math.degToRad(lonR); 764 765 var targetL = _Util2.default.deepCopy(this.camera.target); 766 targetL.x = 500 * Math.sin(this.phi) * Math.cos(thetaL); 767 targetL.z = 500 * Math.sin(this.phi) * Math.sin(thetaL); 768 this.cameraL.lookAt(targetL); 769 770 var targetR = _Util2.default.deepCopy(this.camera.target); 771 targetR.x = 500 * Math.sin(this.phi) * Math.cos(thetaR); 772 targetR.z = 500 * Math.sin(this.phi) * Math.sin(thetaR); 773 this.cameraR.lookAt(targetR); 774 } 775 // render left eye 776 this.renderer.setViewport(0, 0, viewPortWidth, viewPortHeight); 777 this.renderer.setScissor(0, 0, viewPortWidth, viewPortHeight); 778 this.renderer.render(this.scene, this.cameraL); 779 780 // render right eye 781 this.renderer.setViewport(viewPortWidth, 0, viewPortWidth, viewPortHeight); 782 this.renderer.setScissor(viewPortWidth, 0, viewPortWidth, viewPortHeight); 783 this.renderer.render(this.scene, this.cameraR); 784 } 785 } 786 }); 787}; 788 789exports.default = Canvas; 790 791},{"./BaseCanvas":4,"./Util":11}],6:[function(require,module,exports){ 792'use strict'; 793 794Object.defineProperty(exports, "__esModule", { 795 value: true 796}); 797/** 798 * @author alteredq / http://alteredqualia.com/ 799 * @author mr.doob / http://mrdoob.com/ 800 */ 801 802var Detector = { 803 804 canvas: !!window.CanvasRenderingContext2D, 805 webgl: function () { 806 807 try { 808 809 var canvas = document.createElement('canvas');return !!(window.WebGLRenderingContext && (canvas.getContext('webgl') || canvas.getContext('experimental-webgl'))); 810 } catch (e) { 811 812 return false;
813 } 814 }(), 815 workers: !!window.Worker, 816 fileapi: window.File && window.FileReader && window.FileList && window.Blob, 817 818 Check_Version: function Check_Version() { 819 var rv = -1; // Return value assumes failure. 820 821 if (navigator.appName == 'Microsoft Internet Explorer') { 822 823 var ua = navigator.userAgent, 824 re = new RegExp("MSIE ([0-9]{1,}[\\.0-9]{0,})"); 825 826 if (re.exec(ua) !== null) { 827 rv = parseFloat(RegExp.$1); 828 } 829 } else if (navigator.appName == "Netscape") { 830 /// in IE 11 the navigator.appVersion says 'trident' 831 /// in Edge the navigator.appVersion does not say trident 832 if (navigator.appVersion.indexOf('Trident') !== -1) rv = 11;else { 833 var ua = navigator.userAgent; 834 var re = new RegExp("Edge\/([0-9]{1,}[\\.0-9]{0,})"); 835 if (re.exec(ua) !== null) { 836 rv = parseFloat(RegExp.$1); 837 } 838 } 839 } 840 841 return rv; 842 }, 843 844 supportVideoTexture: function supportVideoTexture() { 845 //ie 11 and edge 12 doesn't support video texture. 846 var version = this.Check_Version(); 847 return version === -1 || version >= 13; 848 }, 849 850 isLiveStreamOnSafari: function isLiveStreamOnSafari(videoElement) { 851 //live stream on safari doesn't support video texture 852 var videoSources = videoElement.querySelectorAll("source"); 853 var result = false;
854 for (var i = 0; i < videoSources.length; i++) { 855 var currentVideoSource = videoSources[i]; 856 if (currentVideoSource.type == "application/x-mpegURL" && /Safari/.test(navigator.userAgent) && /Apple Computer/.test(navigator.vendor)) { 857 result = true; 858 } 859 break; 860 } 861 return result; 862 }, 863 864 getWebGLErrorMessage: function getWebGLErrorMessage() { 865 866 var element = document.createElement('div'); 867 element.id = 'webgl-error-message'; 868 869 if (!this.webgl) { 870 871 element.innerHTML = window.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'); 872 } 873 874 return element; 875 }, 876 877 addGetWebGLMessage: function addGetWebGLMessage(parameters) { 878 879 var parent, id, element; 880 881 parameters = parameters || {}; 882 883 parent = parameters.parent !== undefined ? parameters.parent : document.body; 884 id = parameters.id !== undefined ? parameters.id : 'oldie'; 885 886 element = Detector.getWebGLErrorMessage(); 887 element.id = id; 888 889 parent.appendChild(element); 890 } 891 892}; 893 894exports.default = Detector; 895 896},{}],7:[function(require,module,exports){ 897"use strict"; 898 899Object.defineProperty(exports, "__esModule", { 900 value: true 901}); 902/** 903 * Created by wensheng.yan on 5/23/16. 904 */ 905var element = document.createElement('canvas'); 906element.className = "vjs-video-helper-canvas"; 907 908var HelperCanvas = function HelperCanvas(baseComponent) { 909 return { 910 constructor: function init(player, options) { 911 this.videoElement = options.video; 912 this.width = options.width; 913 this.height = options.height; 914 915 element.width = this.width; 916 element.height = this.height; 917 element.style.display = "none"; 918 options.el = element; 919 920 this.context = element.getContext('2d'); 921 this.context.drawImage(this.videoElement, 0, 0, this.width, this.height); 922 baseComponent.call(this, player, options); 923 }, 924 925 getContext: function getContext() { 926 return this.context; 927 }, 928 929 update: function update() { 930 this.context.drawImage(this.videoElement, 0, 0, this.width, this.height); 931 }, 932 933 el: function el() { 934 return element; 935 } 936 }; 937}; 938 939exports.default = HelperCanvas; 940 941},{}],8:[function(require,module,exports){ 942"use strict"; 943 944Object.defineProperty(exports, "__esModule", { 945 value: true 946}); 947/** 948 * Created by yanwsh on 6/6/16. 949 */ 950var MobileBuffering = { 951 prev_currentTime: 0, 952 counter: 0, 953 954 isBuffering: function isBuffering(currentTime) { 955 if (currentTime == this.prev_currentTime) this.counter++;else this.counter = 0; 956 this.prev_currentTime = currentTime; 957 if (this.counter > 10) { 958 //not let counter overflow 959 this.counter = 10; 960 return true; 961 } 962 return false; 963 } 964}; 965 966exports.default = MobileBuffering; 967 968},{}],9:[function(require,module,exports){ 969"use strict"; 970 971Object.defineProperty(exports, "__esModule", { 972 value: true 973}); 974 975var _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; }; 976 977/** 978 * Created by yanwsh on 4/4/16. 979 */ 980 981var Notice = function Notice(baseComponent) { 982 var element = document.createElement('div'); 983 element.className = "vjs-video-notice-label"; 984 985 return { 986 constructor: function init(player, options) { 987 if (_typeof(options.NoticeMessage) == "object") { 988 element = options.NoticeMessage; 989 options.el = options.NoticeMessage; 990 } else if (typeof options.NoticeMessage == "string") { 991 element.innerHTML = options.NoticeMessage; 992 options.el = element; 993 } 994 995 baseComponent.call(this, player, options); 996 }, 997 998 el: function el() { 999 return element; 1000 } 1001 }; 1002}; 1003 1004exports.default = Notice; 1005 1006},{}],10:[function(require,module,exports){ 1007/** 1008 * 1009 * (c) Wensheng Yan <[email protected]> 1010 * Date: 10/21/16 1011 * 1012 * For the full copyright and license information, please view the LICENSE 1013 * file that was distributed with this source code. 1014 */ 1015'use strict'; 1016 1017Object.defineProperty(exports, "__esModule", { 1018 value: true 1019}); 1020 1021var _BaseCanvas = require('./BaseCanvas'); 1022 1023var _BaseCanvas2 = _interopRequireDefault(_BaseCanvas); 1024 1025var _Util = require('./Util'); 1026 1027var _Util2 = _interopRequireDefault(_Util); 1028 1029function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 1030 1031var ThreeDCanvas = function ThreeDCanvas(baseComponent, THREE) { 1032 var settings = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; 1033 1034 var parent = (0, _BaseCanvas2.default)(baseComponent, THREE, settings); 1035 return _Util2.default.extend(parent, { 1036 constructor: function init(player, options) { 1037 parent.constructor.call(this, player, options); 1038 1039 //define scene 1040 this.scene = new THREE.Scene(); 1041 var aspectRatio = this.width / this.height / 2; 1042 //define camera 1043 this.cameraL = new THREE.PerspectiveCamera(options.initFov, aspectRatio, 1, 2000); 1044 this.cameraL.target = new THREE.Vector3(0, 0, 0); 1045 1046 this.cameraR = new THREE.PerspectiveCamera(options.initFov, aspectRatio, 1, 2000); 1047 this.cameraR.position.set(1000, 0, 0); 1048 this.cameraR.target = new THREE.Vector3(1000, 0, 0); 1049 1050 var geometryL = new THREE.SphereBufferGeometry(500, 60, 40).toNonIndexed(); 1051 var geometryR = new THREE.SphereBufferGeometry(500, 60, 40).toNonIndexed(); 1052 1053 var uvsL = geometryL.attributes.uv.array; 1054 var normalsL = geometryL.attributes.normal.array; 1055 for (var i = 0; i < normalsL.length / 3; i++) { 1056 uvsL[i * 2 + 1] = uvsL[i * 2 + 1] / 2; 1057 } 1058 1059 var uvsR = geometryR.attributes.uv.array; 1060 var normalsR = geometryR.attributes.normal.array; 1061 for (var i = 0; i < normalsR.length / 3; i++) { 1062 uvsR[i * 2 + 1] = uvsR[i * 2 + 1] / 2 + 0.5; 1063 } 1064 1065 geometryL.scale(-1, 1, 1); 1066 geometryR.scale(-1, 1, 1); 1067 1068 this.meshL = new THREE.Mesh(geometryL, new THREE.MeshBasicMaterial({ map: this.texture })); 1069 1070 this.meshR = new THREE.Mesh(geometryR, new THREE.MeshBasicMaterial({ map: this.texture })); 1071 this.meshR.position.set(1000, 0, 0); 1072 1073 this.scene.add(this.meshL); 1074 this.scene.add(this.meshR); 1075 1076 if (options.callback) options.callback(); 1077 }, 1078 1079 handleResize: function handleResize() { 1080 parent.handleResize.call(this); 1081 var aspectRatio = this.width / this.height / 2; 1082 this.cameraL.aspect = aspectRatio; 1083 this.cameraR.aspect = aspectRatio; 1084 this.cameraL.updateProjectionMatrix(); 1085 this.cameraR.updateProjectionMatrix(); 1086 }, 1087 1088 handleMouseWheel: function handleMouseWheel(event) { 1089 parent.handleMouseWheel(event); 1090 // WebKit 1091 if (event.wheelDeltaY) { 1092 this.cameraL.fov -= event.wheelDeltaY * 0.05; 1093 // Opera / Explorer 9 1094 } else if (event.wheelDelta) { 1095 this.cameraL.fov -= event.wheelDelta * 0.05; 1096 // Firefox 1097 } else if (event.detail) { 1098 this.cameraL.fov += event.detail * 1.0; 1099 } 1100 this.cameraL.fov = Math.min(this.settings.maxFov, this.cameraL.fov); 1101 this.cameraL.fov = Math.max(this.settings.minFov, this.cameraL.fov); 1102 this.cameraR.fov = this.cameraL.fov; 1103 this.cameraL.updateProjectionMatrix(); 1104 this.cameraR.updateProjectionMatrix(); 1105 }, 1106 1107 render: function render() { 1108 parent.render.call(this); 1109 var viewPortWidth = this.width / 2, 1110 viewPortHeight = this.height; 1111 this.cameraL.target.x = 500 * Math.sin(this.phi) * Math.cos(this.theta); 1112 this.cameraL.target.y = 500 * Math.cos(this.phi); 1113 this.cameraL.target.z = 500 * Math.sin(this.phi) * Math.sin(this.theta); 1114 this.cameraL.lookAt(this.cameraL.target); 1115 1116 this.cameraR.target.x = 1000 + 500 * Math.sin(this.phi) * Math.cos(this.theta); 1117 this.cameraR.target.y = 500 * Math.cos(this.phi); 1118 this.cameraR.target.z = 500 * Math.sin(this.phi) * Math.sin(this.theta); 1119 this.cameraR.lookAt(this.cameraR.target); 1120 1121 // render left eye 1122 this.renderer.setViewport(0, 0, viewPortWidth, viewPortHeight); 1123 this.renderer.setScissor(0, 0, viewPortWidth, viewPortHeight); 1124 this.renderer.render(this.scene, this.cameraL); 1125 1126 // render right eye 1127 this.renderer.setViewport(viewPortWidth, 0, viewPortWidth, viewPortHeight); 1128 this.renderer.setScissor(viewPortWidth, 0, viewPortWidth, viewPortHeight); 1129 this.renderer.render(this.scene, this.cameraR); 1130 } 1131 }); 1132}; 1133 1134exports.default = ThreeDCanvas; 1135 1136},{"./BaseCanvas":4,"./Util":11}],11:[function(require,module,exports){ 1137'use strict'; 1138 1139Object.defineProperty(exports, "__esModule", { 1140 value: true 1141}); 1142/** 1143 * Created by wensheng.yan on 4/4/16. 1144 */ 1145function whichTransitionEvent() { 1146 var t; 1147 var el = document.createElement('fakeelement'); 1148 var transitions = { 1149 'transition': 'transitionend', 1150 'OTransition': 'oTransitionEnd', 1151 'MozTransition': 'transitionend', 1152 'WebkitTransition': 'webkitTransitionEnd' 1153 }; 1154 1155 for (t in transitions) { 1156 if (el.style[t] !== undefined) { 1157 return transitions[t]; 1158 } 1159 } 1160} 1161 1162function mobileAndTabletcheck() { 1163 var check = false;
vendor: 4,723 bytes, lines 1164-1251
1164 (function (a) { 1165 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; 1166 })(navigator.userAgent || navigator.vendor || window.opera); 1167 return check; 1168} 1169 1170function isIos() { 1171 return (/iPhone|iPad|iPod/i.test(navigator.userAgent) 1172 ); 1173} 1174 1175function isRealIphone() { 1176 return (/iPhone|iPod/i.test(navigator.platform) 1177 ); 1178} 1179 1180//adopt code from: https://github.com/MozVR/vr-web-examples/blob/master/threejs-vr-boilerplate/js/VREffect.js 1181function fovToNDCScaleOffset(fov) { 1182 var pxscale = 2.0 / (fov.leftTan + fov.rightTan); 1183 var pxoffset = (fov.leftTan - fov.rightTan) * pxscale * 0.5; 1184 var pyscale = 2.0 / (fov.upTan + fov.downTan); 1185 var pyoffset = (fov.upTan - fov.downTan) * pyscale * 0.5; 1186 return { scale: [pxscale, pyscale], offset: [pxoffset, pyoffset] }; 1187} 1188 1189function fovPortToProjection(fov, rightHanded, zNear, zFar) { 1190 1191 rightHanded = rightHanded === undefined ? true : rightHanded; 1192 zNear = zNear === undefined ? 0.01 : zNear; 1193 zFar = zFar === undefined ? 10000.0 : zFar; 1194 1195 var handednessScale = rightHanded ? -1.0 : 1.0; 1196 1197 // start with an identity matrix 1198 var mobj = new THREE.Matrix4(); 1199 var m = mobj.elements; 1200 1201 // and with scale/offset info for normalized device coords 1202 var scaleAndOffset = fovToNDCScaleOffset(fov); 1203 1204 // X result, map clip edges to [-w,+w] 1205 m[0 * 4 + 0] = scaleAndOffset.scale[0]; 1206 m[0 * 4 + 1] = 0.0; 1207 m[0 * 4 + 2] = scaleAndOffset.offset[0] * handednessScale; 1208 m[0 * 4 + 3] = 0.0; 1209 1210 // Y result, map clip edges to [-w,+w] 1211 // Y offset is negated because this proj matrix transforms from world coords with Y=up, 1212 // but the NDC scaling has Y=down (thanks D3D?) 1213 m[1 * 4 + 0] = 0.0; 1214 m[1 * 4 + 1] = scaleAndOffset.scale[1]; 1215 m[1 * 4 + 2] = -scaleAndOffset.offset[1] * handednessScale; 1216 m[1 * 4 + 3] = 0.0; 1217 1218 // Z result (up to the app) 1219 m[2 * 4 + 0] = 0.0; 1220 m[2 * 4 + 1] = 0.0; 1221 m[2 * 4 + 2] = zFar / (zNear - zFar) * -handednessScale; 1222 m[2 * 4 + 3] = zFar * zNear / (zNear - zFar); 1223 1224 // W result (= Z in) 1225 m[3 * 4 + 0] = 0.0; 1226 m[3 * 4 + 1] = 0.0; 1227 m[3 * 4 + 2] = handednessScale; 1228 m[3 * 4 + 3] = 0.0; 1229 1230 mobj.transpose(); 1231 1232 return mobj; 1233} 1234 1235function fovToProjection(fov, rightHanded, zNear, zFar) { 1236 var DEG2RAD = Math.PI / 180.0; 1237 1238 var fovPort = { 1239 upTan: Math.tan(fov.upDegrees * DEG2RAD), 1240 downTan: Math.tan(fov.downDegrees * DEG2RAD), 1241 leftTan: Math.tan(fov.leftDegrees * DEG2RAD), 1242 rightTan: Math.tan(fov.rightDegrees * DEG2RAD) 1243 }; 1244 1245 return fovPortToProjection(fovPort, rightHanded, zNear, zFar); 1246} 1247 1248function extend(superClass) { 1249 var subClassMethods = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; 1250 1251 for (var method in superClass) {
1252 if (superClass.hasOwnProperty(method) && !subClassMethods.hasOwnProperty(method)) { 1253 subClassMethods[method] = superClass[method]; 1254 } 1255 } 1256 return subClassMethods; 1257} 1258 1259function deepCopy(obj) { 1260 var to = {}; 1261 1262 for (var name in obj) { 1263 to[name] = obj[name]; 1264 } 1265 1266 return to; 1267} 1268 1269exports.default = { 1270 whichTransitionEvent: whichTransitionEvent, 1271 mobileAndTabletcheck: mobileAndTabletcheck, 1272 isIos: isIos, 1273 isRealIphone: isRealIphone, 1274 fovToProjection: fovToProjection, 1275 extend: extend, 1276 deepCopy: deepCopy 1277}; 1278 1279},{}],12:[function(require,module,exports){ 1280"use strict"; 1281 1282Object.defineProperty(exports, "__esModule", { 1283 value: true 1284}); 1285/** 1286 * Created by yanwsh on 8/13/16. 1287 */ 1288 1289var VRButton = function VRButton(ButtonComponent) { 1290 return { 1291 constructor: function init(player, options) { 1292 ButtonComponent.call(this, player, options); 1293 }, 1294 1295 buildCSSClass: function buildCSSClass() { 1296 return "vjs-VR-control " + ButtonComponent.prototype.buildCSSClass.call(this); 1297 }, 1298 1299 handleClick: function handleClick() { 1300 var canvas = this.player().getChild("Canvas"); 1301 !canvas.VRMode ? canvas.enableVR() : canvas.disableVR(); 1302 canvas.VRMode ? this.addClass("enable") : this.removeClass("enable"); 1303 canvas.VRMode ? this.player().trigger('VRModeOn') : this.player().trigger('VRModeOff'); 1304 }, 1305 1306 controlText_: "VR" 1307 }; 1308}; 1309 1310exports.default = VRButton; 1311 1312},{}],13:[function(require,module,exports){ 1313/** 1314 * Created by yanwsh on 4/3/16. 1315 */ 1316'use strict'; 1317 1318Object.defineProperty(exports, "__esModule", { 1319 value: true 1320}); 1321 1322var _Util = require('./lib/Util'); 1323 1324var _Util2 = _interopRequireDefault(_Util); 1325 1326var _Detector = require('./lib/Detector'); 1327 1328var _Detector2 = _interopRequireDefault(_Detector); 1329 1330var _iphoneInlineVideo = require('iphone-inline-video'); 1331 1332var _iphoneInlineVideo2 = _interopRequireDefault(_iphoneInlineVideo); 1333 1334function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 1335 1336var runOnMobile = _Util2.default.mobileAndTabletcheck(); 1337 1338// Default options for the plugin. 1339var defaults = { 1340 clickAndDrag: runOnMobile, 1341 showNotice: true, 1342 NoticeMessage: "Please use your mouse drag and drop the video.", 1343 autoHideNotice: 3000, 1344 //limit the video size when user scroll. 1345 scrollable: true, 1346 initFov: 75, 1347 maxFov: 105, 1348 minFov: 51, 1349 //initial position for the video 1350 initLat: 0, 1351 initLon: -180, 1352 //A float value back to center when mouse out the canvas. The higher, the faster. 1353 returnStepLat: 0.5, 1354 returnStepLon: 2, 1355 backToVerticalCenter: !runOnMobile, 1356 backToHorizonCenter: !runOnMobile, 1357 clickToToggle: false, 1358 1359 //limit viewable zoom 1360 minLat: -85, 1361 maxLat: 85, 1362 1363 minLon: -Infinity, 1364 maxLon: Infinity, 1365 1366 videoType: "equirectangular", 1367 1368 rotateX: 0, 1369 rotateY: 0, 1370 rotateZ: 0, 1371 1372 autoMobileOrientation: false, 1373 mobileVibrationValue: _Util2.default.isIos() ? 0.022 : 1, 1374 1375 VREnable: true, 1376 VRGapDegree: 2.5, 1377 1378 closePanorama: false 1379 1380}; 1381 1382function playerResize(player) { 1383 var canvas = player.getChild('Canvas'); 1384 return function () { 1385 player.el().style.width = window.innerWidth + "px"; 1386 player.el().style.height = window.innerHeight + "px"; 1387 canvas.handleResize(); 1388 }; 1389} 1390 1391function fullscreenOnIOS(player, clickFn) { 1392 var resizeFn = playerResize(player); 1393 player.controlBar.fullscreenToggle.off("tap", clickFn); 1394 player.controlBar.fullscreenToggle.on("tap", function fullscreen() { 1395 var canvas = player.getChild('Canvas'); 1396 if (!player.isFullscreen()) { 1397 //set to fullscreen 1398 player.isFullscreen(true); 1399 player.enterFullWindow(); 1400 resizeFn(); 1401 window.addEventListener("devicemotion", resizeFn); 1402 } else { 1403 player.isFullscreen(false); 1404 player.exitFullWindow(); 1405 player.el().style.width = ""; 1406 player.el().style.height = ""; 1407 canvas.handleResize(); 1408 window.removeEventListener("devicemotion", resizeFn); 1409 } 1410 }); 1411} 1412 1413/**
1414 * Function to invoke when the player is ready. 1415 * 1416 * This is a great place for your plugin to initialize itself. When this 1417 * function is called, the player will have its DOM and child components 1418 * in place. 1419 * 1420 * @function onPlayerReady 1421 * @param {Player} player 1422 * @param {Object} [options={}] 1423 */ 1424var onPlayerReady = function onPlayerReady(player, options, settings) { 1425 player.addClass('vjs-panorama'); 1426 if (!_Detector2.default.webgl) { 1427 PopupNotification(player, { 1428 NoticeMessage: _Detector2.default.getWebGLErrorMessage(), 1429 autoHideNotice: options.autoHideNotice 1430 }); 1431 if (options.callback) { 1432 options.callback(); 1433 } 1434 return; 1435 } 1436 player.addChild('Canvas', _Util2.default.deepCopy(options)); 1437 var canvas = player.getChild('Canvas'); 1438 if (runOnMobile) { 1439 var videoElement = settings.getTech(player); 1440 if (_Util2.default.isRealIphone()) { 1441 //ios 10 support play video inline 1442 videoElement.setAttribute("playsinline", ""); 1443 (0, _iphoneInlineVideo2.default)(videoElement, true); 1444 } 1445 if (_Util2.default.isIos()) { 1446 fullscreenOnIOS(player, settings.getFullscreenToggleClickFn(player)); 1447 } 1448 player.addClass("vjs-panorama-mobile-inline-video"); 1449 player.removeClass("vjs-using-native-controls"); 1450 canvas.playOnMobile(); 1451 } 1452 if (options.showNotice) { 1453 player.on("playing", function () { 1454 PopupNotification(player, _Util2.default.deepCopy(options)); 1455 }); 1456 } 1457 if (options.VREnable && options.videoType !== "3dVideo") { 1458 player.controlBar.addChild('VRButton', {}, player.controlBar.children().length - 1); 1459 } 1460 canvas.hide(); 1461 player.on("play", function () { 1462 canvas.show(); 1463 }); 1464 player.on("fullscreenchange", function () { 1465 canvas.handleResize(); 1466 }); 1467 if (options.callback) options.callback(); 1468}; 1469 1470var PopupNotification = function PopupNotification(player) { 1471 var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : { 1472 NoticeMessage: "" 1473 }; 1474 1475 var notice = player.addChild('Notice', options); 1476 1477 if (options.autoHideNotice > 0) { 1478 setTimeout(function () { 1479 notice.addClass("vjs-video-notice-fadeOut"); 1480 var transitionEvent = _Util2.default.whichTransitionEvent(); 1481 var hide = function hide() { 1482 notice.hide(); 1483 notice.removeClass("vjs-video-notice-fadeOut"); 1484 notice.off(transitionEvent, hide); 1485 }; 1486 notice.on(transitionEvent, hide); 1487 }, options.autoHideNotice); 1488 } 1489}; 1490 1491var plugin = function plugin() { 1492 var settings = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; 1493 1494 /** 1495 * A video.js plugin. 1496 * 1497 * In the plugin function, the value of `this` is a video.js `Player` 1498 * instance. You cannot rely on the player being in a "ready" state here, 1499 * depending on how the plugin is invoked. This may or may not be important 1500 * to you; if not, remove the wait for "ready"! 1501 * 1502 * @function panorama 1503 * @param {Object} [options={}] 1504 * An object of options left to the plugin author to define. 1505 */ 1506 var videoTypes = ["equirectangular", "fisheye", "3dVideo"]; 1507 var panorama = function panorama(options) { 1508 var _this = this; 1509 1510 if (settings.mergeOption) options = settings.mergeOption(defaults, options); 1511 if (typeof settings._init === "undefined" || typeof settings._init !== "function") { 1512 console.error("plugin must implement init function()."); 1513 return; 1514 } 1515 if (videoTypes.indexOf(options.videoType) == -1) options.videoType = defaults.videoType; 1516 settings._init(options); 1517 /* implement callback function when videojs is ready */ 1518 this.ready(function () { 1519 onPlayerReady(_this, options, settings); 1520 }); 1521 }; 1522 1523 // Include the version number. 1524 panorama.VERSION = '0.1.0'; 1525 1526 return panorama; 1527}; 1528 1529exports.default = plugin; 1530 1531},{"./lib/Detector":6,"./lib/Util":11,"iphone-inline-video":2}],14:[function(require,module,exports){ 1532'use strict'; 1533 1534var _Canvas = require('./lib/Canvas'); 1535 1536var _Canvas2 = _interopRequireDefault(_Canvas); 1537 1538var _ThreeCanvas = require('./lib/ThreeCanvas'); 1539 1540var _ThreeCanvas2 = _interopRequireDefault(_ThreeCanvas); 1541 1542var _Notice = require('./lib/Notice'); 1543 1544var _Notice2 = _interopRequireDefault(_Notice); 1545 1546var _HelperCanvas = require('./lib/HelperCanvas'); 1547 1548var _HelperCanvas2 = _interopRequireDefault(_HelperCanvas); 1549 1550var _VRButton = require('./lib/VRButton'); 1551 1552var _VRButton2 = _interopRequireDefault(_VRButton); 1553 1554var _plugin = require('./plugin'); 1555 1556var _plugin2 = _interopRequireDefault(_plugin); 1557 1558function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 1559 1560function getTech(player) { 1561 return player.tech({ IWillNotUseThisInPlugins: true }).el(); 1562} 1563 1564function getFullscreenToggleClickFn(player) { 1565 return player.controlBar.fullscreenToggle.handleClick; 1566} 1567 1568var component = videojs.getComponent('Component'); 1569 1570var notice = (0, _Notice2.default)(component); 1571videojs.registerComponent('Notice', videojs.extend(component, notice)); 1572 1573var helperCanvas = (0, _HelperCanvas2.default)(component); 1574videojs.registerComponent('HelperCanvas', videojs.extend(component, helperCanvas)); 1575 1576var button = videojs.getComponent("Button"); 1577var vrBtn = (0, _VRButton2.default)(button); 1578videojs.registerComponent('VRButton', videojs.extend(button, vrBtn)); 1579 1580// Register the plugin with video.js. 1581videojs.registerPlugin('panorama', (0, _plugin2.default)({ 1582 _init: function _init(options) { 1583 var canvas = options.videoType !== "3dVideo" ? (0, _Canvas2.default)(component, window.THREE, { 1584 getTech: getTech 1585 }) : (0, _ThreeCanvas2.default)(component, window.THREE, { 1586 getTech: getTech 1587 }); 1588 videojs.registerComponent('Canvas', videojs.extend(component, canvas)); 1589 }, 1590 mergeOption: function mergeOption(defaults, options) { 1591 return videojs.mergeOptions(defaults, options); 1592 }, 1593 getTech: getTech, 1594 getFullscreenToggleClickFn: getFullscreenToggleClickFn 1595})); 1596 1597},{"./lib/Canvas":5,"./lib/HelperCanvas":7,"./lib/Notice":9,"./lib/ThreeCanvas":10,"./lib/VRButton":12,"./plugin":13}]},{},[14]) 1598//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJub2RlX21vZHVsZXMvaW50ZXJ2YWxvbWV0ZXIvZGlzdC9pbnRlcnZhbG9tZXRlci5jb21tb24tanMuanMiLCJub2RlX21vZHVsZXMvaXBob25lLWlubGluZS12aWRlby9kaXN0L2lwaG9uZS1pbmxpbmUtdmlkZW8uY29tbW9uLWpzLmpzIiwibm9kZV9tb2R1bGVzL3Bvb3ItbWFucy1zeW1ib2wvZGlzdC9wb29yLW1hbnMtc3ltYm9sLmNvbW1vbi1qcy5qcyIsInNyYy9zY3JpcHRzL2xpYi9CYXNlQ2FudmFzLmpzIiwic3JjL3NjcmlwdHMvbGliL0NhbnZhcy5qcyIsInNyYy9zY3JpcHRzL2xpYi9
1598EZXRlY3Rvci5qcyIsInNyYy9zY3JpcHRzL2xpYi9IZWxwZXJDYW52YXMuanMiLCJzcmMvc2NyaXB0cy9saWIvTW9iaWxlQnVmZmVyaW5nLmpzIiwic3JjL3NjcmlwdHMvbGliL05vdGljZS5qcyIsInNyYy9zY3JpcHRzL2xpYi9UaHJlZUNhbnZhcy5qcyIsInNyYy9zY3JpcHRzL2xpYi9VdGlsLmpzIiwic3JjL3NjcmlwdHMvbGliL1ZSQnV0dG9uLmpzIiwic3JjL3NjcmlwdHMvcGx1Z2luLmpzIiwic3JjL3NjcmlwdHMvcGx1Z2luX3Y1LmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBO0FDQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E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vbiBlKHQsbixyKXtmdW5jdGlvbiBzKG8sdSl7aWYoIW5bb10pe2lmKCF0W29dKXt2YXIgYT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2lmKCF1JiZhKXJldHVybiBhKG8sITApO2lmKGkpcmV0dXJuIGkobywhMCk7dmFyIGY9bmV3IEVycm9yKFwiQ2Fubm90IGZpbmQgbW9kdWxlICdcIitvK1wiJ1wiKTt0aHJvdyBmLmNvZGU9XCJNT0RVTEVfTk9UX0ZPVU5EXCIsZn12YXIgbD1uW29dPXtleHBvcnRzOnt9fTt0W29dWzBdLmNhbGwobC5leHBvcnRzLGZ1bmN0aW9uKGUpe3ZhciBuPXRbb11bMV1bZV07cmV0dXJuIHMobj9uOmUpfSxsLGwuZXhwb3J0cyxlLHQsbixyKX1yZXR1cm4gbltvXS5leHBvcnRzfXZhciBpPXR5cGVvZiByZXF1aXJlPT1cImZ1bmN0aW9uXCImJnJlcXVpcmU7Zm9yKHZhciBvPTA7bzxyLmxlbmd0aDtvKyspcyhyW29dKTtyZXR1cm4gc30pIiwiLyohIG5wbS5pbS9pbnRlcnZhbG9tZXRlciAqL1xuJ3VzZSBzdHJpY3QnO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgJ19fZXNNb2R1bGUnLCB7IHZhbHVlOiB0cnVlIH0pO1xuXG5mdW5jdGlvbiBpbnRlcnZhbG9tZXRlcihjYiwgcmVxdWVzdCwgY2FuY2VsLCByZXF1ZXN0UGFyYW1ldGVyKSB7XG5cdHZhciByZXF1ZXN0SWQ7XG5cdHZhciBwcmV2aW91c0xvb3BUaW1lO1xuXHRmdW5jdGlvbiBsb29wKG5vdykge1xuXHRcdC8vIG11c3QgYmUgcmVxdWVzdGVkIGJlZm9yZSBjYigpIGJlY2F1c2UgdGhhdCBtaWdodCBjYWxsIC5zdG9wKClcblx0XHRyZXF1ZXN0SWQgPSByZXF1ZXN0KGxvb3AsIHJlcXVlc3RQYXJhbWV0ZXIpO1xuXG5cdFx0Ly8gY2FsbGVkIHdpdGggXCJtcyBzaW5jZSBsYXN0IGNhbGxcIi4gMCBvbiBzdGFydCgpXG5cdFx0Y2Iobm93IC0gKHByZXZpb3VzTG9vcFRpbWUgfHwgbm93KSk7XG5cblx0XHRwcmV2aW91c0xvb3BUaW1lID0gbm93O1xuXHR9XG5cdHJldHVybiB7XG5cdFx0c3RhcnQ6IGZ1bmN0aW9uIHN0YXJ0KCkge1xuXHRcdFx0aWYgKCFyZXF1ZXN0SWQpIHsgLy8gcHJldmVudCBkb3VibGUgc3RhcnRzXG5cdFx0XHRcdGxvb3AoMCk7XG5cdFx0XHR9XG5cdFx0fSxcblx0XHRzdG9wOiBmdW5jdGlvbiBzdG9wKCkge1xuXHRcdFx0Y2FuY2VsKHJlcXVlc3RJZCk7XG5cdFx0XHRyZXF1ZXN0SWQgPSBudWxsO1xuXHRcdFx0cHJldmlvdXNMb29wVGltZSA9IDA7XG5cdFx0fVxuXHR9O1xufVxuXG5mdW5jdGlvbiBmcmFtZUludGVydmFsb21ldGVyKGNiKSB7XG5cdHJldHVybiBpbnRlcnZhbG9tZXRlcihjYiwgcmVxdWVzdEFuaW1hdGlvbkZyYW1lLCBjYW5jZWxBbmltYXRpb25GcmFtZSk7XG59XG5cbmZ1bmN0aW9uIHRpbWVySW50ZXJ2YWxvbWV0ZXIoY2IsIGRlbGF5KSB7XG5cdHJldHVybi
1598BpbnRlcnZhbG9tZXRlcihjYiwgc2V0VGltZW91dCwgY2xlYXJUaW1lb3V0LCBkZWxheSk7XG59XG5cbmV4cG9ydHMuaW50ZXJ2YWxvbWV0ZXIgPSBpbnRlcnZhbG9tZXRlcjtcbmV4cG9ydHMuZnJhbWVJbnRlcnZhbG9tZXRlciA9IGZyYW1lSW50ZXJ2YWxvbWV0ZXI7XG5leHBvcnRzLnRpbWVySW50ZXJ2YWxvbWV0ZXIgPSB0aW1lckludGVydmFsb21ldGVyOyIsIi8qISBucG0uaW0vaXBob25lLWlubGluZS12aWRlbyAqL1xuJ3VzZSBzdHJpY3QnO1xuXG5mdW5jdGlvbiBfaW50ZXJvcERlZmF1bHQgKGV4KSB7IHJldHVybiAoZXggJiYgKHR5cGVvZiBleCA9PT0gJ29iamVjdCcpICYmICdkZWZhdWx0JyBpbiBleCkgPyBleFsnZGVmYXVsdCddIDogZXg7IH1cblxudmFyIFN5bWJvbCA9IF9pbnRlcm9wRGVmYXVsdChyZXF1aXJlKCdwb29yLW1hbnMtc3ltYm9sJykpO1xudmFyIGludGVydmFsb21ldGVyID0gcmVxdWlyZSgnaW50ZXJ2YWxvbWV0ZXInKTtcblxuZnVuY3Rpb24gcHJldmVudEV2ZW50KGVsZW1lbnQsIGV2ZW50TmFtZSwgdG9nZ2xlUHJvcGVydHksIHByZXZlbnRXaXRoUHJvcGVydHkpIHtcblx0ZnVuY3Rpb24gaGFuZGxlcihlKSB7XG5cdFx0aWYgKEJvb2xlYW4oZWxlbWVudFt0b2dnbGVQcm9wZXJ0eV0pID09PSBCb29sZWFuKHByZXZlbnRXaXRoUHJvcGVydHkpKSB7XG5cdFx0XHRlLnN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbigpO1xuXHRcdFx0Ly8gY29uc29sZS5sb2coZXZlbnROYW1lLCAncHJldmVudGVkIG9uJywgZWxlbWVudCk7XG5cdFx0fVxuXHRcdGRlbGV0ZSBlbGVtZW50W3RvZ2dsZVByb3BlcnR5XTtcblx0fVxuXHRlbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoZXZlbnROYW1lLCBoYW5kbGVyLCBmYWxzZSk7XG5cblx0Ly8gUmV0dXJuIGhhbmRsZXIgdG8gYWxsb3cgdG8gZGlzYWJsZSB0aGUgcHJldmVudGlvbi4gVXNhZ2U6XG5cdC8vIGNvbnN0IHByZXZlbnRpb25IYW5kbGVyID0gcHJldmVudEV2ZW50KGVsLCAnY2xpY2snKTtcblx0Ly8gZWwucmVtb3ZlRXZlbnRIYW5kbGVyKCdjbGljaycsIHByZXZlbnRpb25IYW5kbGVyKTtcblx0cmV0dXJuIGhhbmRsZXI7XG59XG5cbmZ1bmN0aW9uIHByb3h5UHJvcGVydHkob2JqZWN0LCBwcm9wZXJ0eU5hbWUsIHNvdXJjZU9iamVjdCwgY29weUZpcnN0KSB7XG5cdGZ1bmN0aW9uIGdldCgpIHtcblx0XHRyZXR1cm4gc291cmNlT2JqZWN0W3Byb3BlcnR5TmFtZV07XG5cdH1cblx0ZnVuY3Rpb24gc2V0KHZhbHVlKSB7XG5cdFx0c291cmNlT2JqZWN0W3Byb3BlcnR5TmFtZV0gPSB2YWx1ZTtcblx0fVxuXG5cdGlmIChjb3B5Rmlyc3QpIHtcblx0XHRzZXQob2JqZWN0W3Byb3BlcnR5TmFtZV0pO1xuXHR9XG5cblx0T2JqZWN0LmRlZmluZVByb3BlcnR5KG9iamVjdCwgcHJvcGVydHlOYW1lLCB7Z2V0OiBnZXQsIHNldDogc2V0fSk7XG59XG5cbmZ1bmN0aW9uIHByb3h5RXZlbnQob2JqZWN0LCBldmVudE5hbWUsIHNvdXJjZU9iamVjdCkge1xuXHRzb3VyY2VPYmplY3QuYWRkRXZlbnRMaXN0ZW5lcihldmVudE5hbWUsIGZ1bmN0aW9uICgpIHsgcmV0dXJuIG9iamVjdC5kaXNwYXRjaEV2ZW50KG5ldyBFdmVudChldmVudE5hbWUpKTsgfSk7XG59XG5cbmZ1bmN0aW9uIGRpc3BhdGNoRXZlbnRBc3luYyhlbGVtZW50LCB0eXBlKSB7XG5cdFByb21pc2UucmVzb2x2ZSgpLnRoZW4oZnVuY3Rpb24gKCkge1xuXHRcdGVsZW1lbnQuZGlzcGF0Y2hFdmVudChuZXcgRXZlbnQodHlwZSkpO1xuXHR9KTtcbn1cblxuLy8gaU9TIDEwIGFkZHMgc3VwcG9ydCBmb3IgbmF0aXZlIGlubGluZSBwbGF5YmFjayArIHNpbGVudCBhdXRvcGxheVxudmFyIGlzV2hpdGVsaXN0ZWQgPSAvaVBob25lfGlQb2QvaS50ZXN0KG5hdmlnYXRvci51c2VyQWdlbnQpICYmICFtYXRjaE1lZGlhKCcoLXdlYmtpdC12aWRlby1wbGF5YWJsZS1pbmxpbmUpJykubWF0Y2hlcztcblxudmFyIOCyoCA9IFN5bWJvbCgpO1xudmFyIOCyoGV2ZW50ID0gU3ltYm9sKCk7XG52YXIg4LKgcGxheSA9IFN5bWJvbCgnbmF0aXZlcGxheScpO1xudmFyIOCyoHBhdXNlID0gU3ltYm9sKCduYXRpdmVwYXVzZScpO1xuXG4vKipcbiAqIFVUSUxTXG4gKi9cblxuZnVuY3Rpb24gZ2V0QXVkaW9Gcm9tVmlkZW8odmlkZW8pIHtcblx0dmFyIGF1ZGlvID0gbmV3IEF1ZGlvKCk7XG5cdHByb3h5RXZlbnQodmlkZW8sICdwbGF5JywgYXVkaW8pO1xuXHRwcm94eUV2ZW50KHZpZGVvLCAncGxheWluZycsIGF1ZGlvKTtcblx0cHJveHlFdmVudCh2aWRlbywgJ3BhdXNlJywgYXVkaW8pO1xuXHRhdWRpby5jcm9zc09yaWdpbiA9IHZpZGVvLmNyb3NzT3JpZ2luO1xuXG5cdC8vICdkYXRhOicgY2F1c2VzIGF1ZGlvLm5ldHdvcmtTdGF0ZSA+IDBcblx0Ly8gd2hpY2ggdGhlbiBhbGxvd3MgdG8ga2VlcCA8YXVkaW8+IGluIGEgcmVzdW1hYmxlIHBsYXlpbmcgc3RhdGVcblx0Ly8gaS5lLiBvbmNlIHlvdSBzZXQgYSByZWFsIHNyYyBpdCB3aWxsIGtlZXAgcGxheWluZyBpZiBpdCB3YXMgaWYgLnBsYXkoKSB3YXMgY2FsbGVkXG5cdGF1ZGlvLnNyYyA9IHZpZGVvLnNyYyB8fCB2aWRlby5jdXJyZW50U3JjIHx8ICdkYXRhOic7XG5cblx0Ly8gaWYgKGF1ZGlvLnNyYyA9PT0gJ2RhdGE6Jykge1xuXHQvLyAgIFRPRE86IHdhaXQgZm9yIHZpZGVvIHRvIGJlIHNlbGVjdGVkXG5cdC8vIH1cblx0cmV0dXJuIGF1ZGlvO1xufVxuXG52YXIgbGFzdFJlcXVlc3RzID0gW107XG52YXIgcmVxdWVzdEluZGV4ID0gMDtcbnZhciBsYXN0VGltZXVwZGF0ZUV2ZW50O1xuXG5mdW5jdGlvbiBzZXRUaW1lKHZpZGVvLCB0aW1lLCByZW1lbWJlck9ubHkpIHtcblx0Ly8gYWxsb3cgb25lIHRpbWV1cGRhdGUgZXZlbnQgZXZlcnkgMjAwKyBtc1xuXHRpZiAoKGxhc3RUaW1ldXBkYXRlRXZlbnQgfHwgMCkgKyAyMDAgPCBEYXRlLm5vdygpKSB7XG5cdFx0dmlkZW9b4LKgZXZlbnRdID0gdHJ1ZTtcblx0XHRsYXN0VGltZXVwZGF0ZUV2ZW50ID0gRGF0ZS5ub3coKTtcblx0fVxuXHRpZiAoIXJlbWVtYmVyT25seSkge1xuXHRcdHZpZGVvLmN1cnJlbnRUaW1lID0gdGltZTtcblx0fVxuXHRsYXN0UmVxdWVzdHNbKytyZXF1ZXN0SW5kZXggJSAzXSA9IHRpbWUgKiAxMDAgfCAwIC8gMTAwO1xufVxuXG5mdW5jdGlvbiBpc1BsYXllckVuZGVkKHBsYXllcikge1xuXHRyZXR1cm4gcGxheWVyLmRyaXZlci5jdXJyZW50VGltZSA+PSBwbGF5ZXIudmlkZW8uZHVyYXRpb247XG59XG5cbmZ1bmN0aW9uIHVwZGF0ZSh0aW1lRGlmZikge1xuXHR2YXIgcGxheWVyID0gdGhpcztcblx0Ly8gY29uc29sZS5sb2coJ3VwZGF0ZScsIHBsYXllci52aWRlby5yZWFkeVN0YXRlLCBwbGF5ZXIudmlkZW8ubmV0d29ya1N0YXRlLCBwbGF5ZXIuZHJpdmVyLnJlYWR5U3RhdGUsIHBsYXllci5kcml2ZXIubmV0d29ya1N0YXRlLCBwbGF5ZXIuZHJpdmVyLnBhdXNlZCk7XG5cdGlmIChwbGF5ZXIudmlkZW8ucmVhZHlTdGF0ZSA+PSBwbGF5ZXIudmlkZW8uSEFWRV9GVVRVUkVfREFUQSkge1xuXHRcdGlmICghcGxheWVyLmhhc0F1ZGlvKSB7XG5cdFx0XHRwbGF5ZXIuZHJpdmVyLmN1cnJlbnRUaW1lID0gcGxheWVyLnZpZGVvLmN1cnJlbnRUaW1lICsgKCh0aW1lRGlmZiAqIHBsYXllci52aWRlby5wbGF5YmFja1JhdGUpIC8gMTAwMCk7XG5cdFx0XHRpZiAocGxheWVyLnZpZGVvLmxvb3AgJiYgaXNQbGF5ZXJFbmRlZChwbGF5ZXIpKSB7XG5cdFx0XHRcdHBsYXllci5kcml2ZXIuY3VycmVudFRpbWUgPSAwO1xuXHRcdFx0fVxuXHRcdH1cblx0XHRzZXRUaW
15981lKHBsYXllci52aWRlbywgcGxheWVyLmRyaXZlci5jdXJyZW50VGltZSk7XG5cdH0gZWxzZSBpZiAocGxheWVyLnZpZGVvLm5ldHdvcmtTdGF0ZSA9PT0gcGxheWVyLnZpZGVvLk5FVFdPUktfSURMRSAmJiAhcGxheWVyLnZpZGVvLmJ1ZmZlcmVkLmxlbmd0aCkge1xuXHRcdC8vIHRoaXMgc2hvdWxkIGhhcHBlbiB3aGVuIHRoZSBzb3VyY2UgaXMgYXZhaWxhYmxlIGJ1dDpcblx0XHQvLyAtIGl0J3MgcG90ZW50aWFsbHkgcGxheWluZyAoLnBhdXNlZCA9PT0gZmFsc2UpXG5cdFx0Ly8gLSBpdCdzIG5vdCByZWFkeSB0byBwbGF5XG5cdFx0Ly8gLSBpdCdzIG5vdCBsb2FkaW5nXG5cdFx0Ly8gSWYgaXQgaGFzQXVkaW8sIHRoYXQgd2lsbCBiZSBsb2FkZWQgaW4gdGhlICdlbXB0aWVkJyBoYW5kbGVyIGJlbG93XG5cdFx0cGxheWVyLnZpZGVvLmxvYWQoKTtcblx0XHQvLyBjb25zb2xlLmxvZygnV2lsbCBsb2FkJyk7XG5cdH1cblxuXHQvLyBjb25zb2xlLmFzc2VydChwbGF5ZXIudmlkZW8uY3VycmVudFRpbWUgPT09IHBsYXllci5kcml2ZXIuY3VycmVudFRpbWUsICdWaWRlbyBub3QgdXBkYXRpbmchJyk7XG5cblx0aWYgKHBsYXllci52aWRlby5lbmRlZCkge1xuXHRcdGRlbGV0ZSBwbGF5ZXIudmlkZW9b4LKgZXZlbnRdOyAvLyBhbGxvdyB0aW1ldXBkYXRlIGV2ZW50XG5cdFx0cGxheWVyLnZpZGVvLnBhdXNlKHRydWUpO1xuXHR9XG59XG5cbi8qKlxuICogTUVUSE9EU1xuICovXG5cbmZ1bmN0aW9uIHBsYXkoKSB7XG5cdC8vIGNvbnNvbGUubG9nKCdwbGF5Jyk7XG5cdHZhciB2aWRlbyA9IHRoaXM7XG5cdHZhciBwbGF5ZXIgPSB2aWRlb1vgsqBdO1xuXG5cdC8vIGlmIGl0J3MgZnVsbHNjcmVlbiwgdXNlIHRoZSBuYXRpdmUgcGxheWVyXG5cdGlmICh2aWRlby53ZWJraXREaXNwbGF5aW5nRnVsbHNjcmVlbikge1xuXHRcdHZpZGVvW+CyoHBsYXldKCk7XG5cdFx0cmV0dXJuO1xuXHR9XG5cblx0aWYgKHBsYXllci5kcml2ZXIuc3JjICE9PSAnZGF0YTonICYmIHBsYXllci5kcml2ZXIuc3JjICE9PSB2aWRlby5zcmMpIHtcblx0XHQvLyBjb25zb2xlLmxvZygnc3JjIGNoYW5nZWQgb24gcGxheScsIHZpZGVvLnNyYyk7XG5cdFx0c2V0VGltZS
1598h2aWRlbywgMCwgdHJ1ZSk7XG5cdFx0cGxheWVyLmRyaXZlci5zcmMgPSB2aWRlby5zcmM7XG5cdH1cblxuXHRpZiAoIXZpZGVvLnBhdXNlZCkge1xuXHRcdHJldHVybjtcblx0fVxuXHRwbGF5ZXIucGF1c2VkID0gZmFsc2U7XG5cblx0aWYgKCF2aWRlby5idWZmZXJlZC5sZW5ndGgpIHtcblx0XHQvLyAubG9hZCgpIGNhdXNlcyB0aGUgZW1wdGllZCBldmVudFxuXHRcdC8vIHRoZSBhbHRlcm5hdGl2ZSBpcyAucGxheSgpKy5wYXVzZSgpIGJ1dCB0aGF0IHRyaWdnZXJzIHBsYXkvcGF1c2UgZXZlbnRzLCBldmVuIHdvcnNlXG5cdFx0Ly8gcG9zc2libHkgdGhlIGFsdGVybmF0aXZlIGlzIHByZXZlbnRpbmcgdGhpcyBldmVudCBvbmx5IG9uY2Vcblx0XHR2aWRlby5sb2FkKCk7XG5cdH1cblxuXHRwbGF5ZXIuZHJpdmVyLnBsYXkoKTtcblx0cGxheWVyLnVwZGF0ZXIuc3RhcnQoKTtcblxuXHRpZiAoIXBsYXllci5oYXNBdWRpbykge1xuXHRcdGRpc3BhdGNoRXZlbnRBc3luYyh2aWRlbywgJ3BsYXknKTtcblx0XHRpZiAocGxheWVyLnZpZGVvLnJlYWR5U3RhdGUgPj0gcGxheWVyLnZpZGVvLkhBVkVfRU5PVUdIX0RBVEEpIHtcblx0XHRcdC8vIGNvbnNvbGUubG9nKCdvbnBsYXknKTtcblx0XHRcdGRpc3BhdGNoRXZlbnRBc3luYyh2aWRlbywgJ3BsYXlpbmcnKTtcblx0XHR9XG5cdH1cbn1cbmZ1bmN0aW9uIHBhdXNlKGZvcmNlRXZlbnRzKSB7XG5cdC8vIGNvbnNvbGUubG9nKCdwYXVzZScpO1xuXHR2YXIgdmlkZW8gPSB0aGlzO1xuXHR2YXIgcGxheWVyID0gdmlkZW9b4LKgXTtcblxuXHRwbGF5ZXIuZHJpdmVyLnBhdXNlKCk7XG5cdHBsYXllci51cGRhdGVyLnN0b3AoKTtcblxuXHQvLyBpZiBpdCdzIGZ1bGxzY3JlZW4sIHRoZSBkZXZlbG9wZXIgdGhlIG5hdGl2ZSBwbGF5ZXIucGF1c2UoKVxuXHQvLyBUaGlzIGlzIGF0IHRoZSBlbmQgb2YgcGF1c2UoKSBiZWNhdXNlIGl0IGFsc29cblx0Ly8gbmVlZHMgdG8gbWFrZSBzdXJlIHRoYXQgdGhlIHNpbXVsYXRpb24gaXMgcGF1c2VkXG5cdGlmICh2aWRlby53ZWJraXREaXNwbGF5aW5nRnVsbHNjcmVlbikge1xuXHRcdHZpZGVvW+CyoHBhdXNlXSgpO1xuXHR9XG5cblx0aWYgKHBsYXllci5wYXVzZWQgJiYgIWZvcmNlRXZlbnRzKSB7XG5cdFx0cmV0dXJuO1xuXHR9XG5cblx0cGxheWVyLnBhdXNlZCA9IHRydWU7XG5cdGlmICghcGxheWVyLmhhc0F1ZGlvKSB7XG5cdFx0ZGlzcGF0Y2hFdmVudEFzeW5jKHZpZGVvLCAncGF1c2UnKTtcblx0fVxuXHRpZiAodmlkZW8uZW5kZWQpIHtcblx0XHR2aWRlb1vgsqBldmVudF0gPSB0cnVlO1xuXHRcdGRpc3BhdGNoRXZlbnRBc3luYyh2aWRlbywgJ2VuZGVkJyk7XG5cdH1cbn1cblxuLyoqXG4gKiBTRVRVUFxuICovXG5cbmZ1bmN0aW9uIGFkZFBsYXllcih2aWRlbywgaGFzQXVkaW8pIHtcblx0dmFyIHBsYXllciA9IHZpZGVvW+CyoF0gPSB7fTtcblx0cGxheWVyLnBhdXNlZCA9IHRydWU7IC8vIHRyYWNrIHdoZXRoZXIgJ3BhdXNlJyBldmVudHMgaGF2ZSBiZWVuIGZpcmVkXG5cdHBsYXllci5oYXNBdWRpbyA9IGhhc0F1ZGlvO1xuXHRwbGF5ZXIudmlkZW8gPSB2aWRlbztcblx0cGxheWVyLnVwZGF0ZXIgPSBpbnRlcnZhbG9tZXRlci5mcmFtZUludGVydmFsb21ldGVyKHVwZGF0ZS5iaW5kKHBsYXllcikpO1xuXG5cdGlmIChoYXNBdWRpbykge1xuXHRcdHBsYXllci5kcml2ZXIgPSBnZXRBdWRpb0Zyb21WaWRlbyh2aWRlbyk7XG5cdH0gZWxzZSB7XG5cdFx0dmlkZW8uYWRkRXZlbnRMaXN0ZW5lcignY2FucGxheScsIGZ1bmN0aW9uICgpIHtcblx0XHRcdGlmICghdmlkZW8ucGF1c2VkKSB7XG5cdFx0XHRcdC8vIGNvbnNvbGUubG9nKCdvbmNhbnBsYXknKTtcblx0XHRcdFx0ZGlzcGF0Y2hFdmVudEFzeW5jKHZpZGVvLCAncGxheWluZycpO1xuXHRcdFx0fVxuXHRcdH0pO1xuXHRcdHBsYXllci5kcml2ZXIgPSB7XG5cdFx0XHRzcmM6IHZpZGVvLnNyYyB8fCB2aWRlby5jdXJyZW50U3JjIHx8ICdkYXRhOicsXG5cdFx0XHRtdXRlZDogdHJ1ZSxcblx0XHRcdHBhdXNlZDogdHJ1ZSxcblx0XHRcdHBhdXNlOiBmdW5jdGlvbiAoKSB7XG5cdFx0XHRcdHBsYXllci5kcml2ZXIucGF1c2VkID0gdHJ1ZTtcblx0XHRcdH0sXG5cdFx0XHRwbGF5OiBmdW5jdGlvbiAoKSB7XG5cdFx0XHRcdHBsYXllci5kcml2ZXIucGF1c2VkID0gZmFsc2U7XG5cdFx0XHRcdC8vIG1lZGlhIGF1dG9tYXRpY2FsbHkgZ29lcyB0byAwIGlmIC5wbGF5KCkgaXMgY2FsbGVkIHdoZW4gaXQncyBkb25lXG5cdFx0XHRcdGlmIChpc1BsYXllckVuZGVkKHBsYXllcikpIHtcblx0XHRcdFx0XHRzZXRUaW1lKHZpZGVvLCAwKTtcblx0XHRcdFx0fVxuXHRcdFx0fSxcblx0XHRcdGdldCBlbmRlZCgpIHtcblx0XHRcdFx0cmV0dXJuIGlzUGxheWVyRW5kZWQocGxheWVyKTtcblx0XHRcdH1cblx0XHR9O1xuXHR9XG5cblx0Ly8gLmxvYWQoKSBjYXVzZXMgdGhlIGVtcHRpZWQgZXZlbnRcblx0dmlkZW8uYWRkRXZlbnRMaXN0ZW5lcignZW1wdGllZCcsIGZ1bmN0aW9uICgpIHtcblx0XHQvLyBjb25zb2xlLmxvZygnZHJpdmVyIHNyYyBpcycsIHBsYXllci5kcml2ZXIuc3JjKTtcblx0XHR2YXIgd2FzRW1wdHkgPSAhcGxheWVyLmRyaXZlci5zcmMgfHwgcGxheWVyLmRyaXZlci5zcmMgPT09ICdkYXRhOic7XG5cdFx0aWYgKHBsYXllci5kcml2ZXIuc3JjICYmIHBsYXllci5kcml2ZXIuc3JjICE9PSB2aWRlby5zcmMpIHtcblx0XHRcdC8vIGNvbnNvbGUubG9nKCdzcmMgY2hhbmdlZCB0bycsIHZpZGVvLnNyYyk7XG5cdFx0XHRzZXRUaW1lKHZpZGVvLCAwLCB0cnVlKTtcblx0XHRcdHBsYXllci5kcml2ZXIuc3JjID0gdmlkZW8uc3JjO1xuXHRcdFx0Ly8gcGxheWluZyB2aWRlb3Mgd2lsbCBvbmx5IGtlZXAgcGxheWluZyBpZiBubyBzcmMgd2FzIHByZXNlbnQgd2hlbiAucGxheSgp4oCZZWRcblx0XHRcdGlmICh3YXNFbXB0eSkge1xuXHRcdFx0XHRwbGF5ZXIuZHJpdmVyLnBsYXkoKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHBsYXllci51cGRhdGVyLnN0b3AoKTtcblx0XHRcdH1cblx0XHR9XG5cdH0sIGZhbHNlKTtcblxuXHQvLyBzdG9wIHByb2dyYW1tYXRpYyBwbGF5ZXIgd2hlbiBPUyB0YWtlcyBvdmVyXG5cdHZpZGVvLmFkZEV2ZW50TGlzdGVuZXIoJ3dlYmtpdGJlZ2luZnVsbHNjcmVlbicsIGZ1bmN0aW9uICgpIHtcblx0XHRpZiAoIXZpZG
1598VvLnBhdXNlZCkge1xuXHRcdFx0Ly8gbWFrZSBzdXJlIHRoYXQgdGhlIDxhdWRpbz4gYW5kIHRoZSBzeW5jZXIvdXBkYXRlciBhcmUgc3RvcHBlZFxuXHRcdFx0dmlkZW8ucGF1c2UoKTtcblxuXHRcdFx0Ly8gcGxheSB2aWRlbyBuYXRpdmVseVxuXHRcdFx0dmlkZW9b4LKgcGxheV0oKTtcblx0XHR9IGVsc2UgaWYgKGhhc0F1ZGlvICYmICFwbGF5ZXIuZHJpdmVyLmJ1ZmZlcmVkLmxlbmd0aCkge1xuXHRcdFx0Ly8gaWYgdGhlIGZpcnN0IHBsYXkgaXMgbmF0aXZlLFxuXHRcdFx0Ly8gdGhlIDxhdWRpbz4gbmVlZHMgdG8gYmUgYnVmZmVyZWQgbWFudWFsbHlcblx0XHRcdC8vIHNvIHdoZW4gdGhlIGZ1bGxzY3JlZW4gZW5kcywgaXQgY2FuIGJlIHNldCB0byB0aGUgc2FtZSBjdXJyZW50IHRpbWVcblx0XHRcdHBsYXllci5kcml2ZXIubG9hZCgpO1xuXHRcdH1cblx0fSk7XG5cdGlmIChoYXNBdWRpbykge1xuXHRcdHZpZGVvLmFkZEV2ZW50TGlzdGVuZXIoJ3dlYmtpdGVuZGZ1bGxzY3JlZW4nLCBmdW5jdGlvbiAoKSB7XG5cdFx0XHQvLyBzeW5jIGF1ZGlvIHRvIG5ldyB2aWRlbyBwb3NpdGlvblxuXHRcdFx0cGxheWVyLmRyaXZlci5jdXJyZW50VGltZSA9IHZpZGVvLmN1cnJlbnRUaW1lO1xuXHRcdFx0Ly8gY29uc29sZS5hc3NlcnQocGxheWVyLmRyaXZlci5jdXJyZW50VGltZSA9PT0gdmlkZW8uY3VycmVudFRpbWUsICdBdWRpbyBub3Qgc3luY2VkJyk7XG5cdFx0fSk7XG5cblx0XHQvLyBhbGxvdyBzZWVraW5nXG5cdFx0dmlkZW8uYWRkRXZlbnRMaXN0ZW5lcignc2Vla2luZycsIGZ1bmN0aW9uICgpIHtcblx0XHRcdGlmIChsYXN0UmVxdWVzdHMuaW5kZXhPZih2aWRlby5jdXJyZW50VGltZSAqIDEwMCB8IDAgLyAxMDApIDwgMCkge1xuXHRcdFx0XHQvLyBjb25zb2xlLmxvZygnVXNlci1yZXF1ZXN0ZWQgc2Vla2luZycpO1xuXHRcdFx0XHRwbGF5ZXIuZHJpdmVyLmN1cnJlbnRUaW1lID0gdmlkZW8uY3VycmVudFRpbWU7XG5cdFx0XHR9XG5cdFx0fSk7XG5cdH1cbn1cblxuZnVuY3Rpb24gb3ZlcmxvYWRBUEkodmlkZW8pIHtcblx0dmFyIHBsYXllciA9IHZpZGVvW+CyoF07XG5cdHZpZGVvW+CyoHBsYXldID0gdmlkZW8ucGxheTtcblx0dmlkZW9b4LKgcGF1c2VdID0gdmlkZW8ucGF1c2U7XG5cdHZpZGVvLnBsYXkgPSBwbGF5O1xuXHR2aWRlby5wYXVzZSA9IHBhdXNlO1xuXHRwcm94eVByb3BlcnR5KHZpZGVvLCAncGF1c2VkJywgcGxheWVyLmRyaXZlcik7XG5cdHByb3h5UHJvcGVydHkodmlkZW8sICdtdXRlZCcsIHBsYXllci5kcml2ZXIsIHRydWUpO1xuXHRwcm94eVByb3BlcnR5KHZpZGVvLCAncGxheWJhY2tSYXRlJywgcGxheWVyLmRyaXZlciwgdHJ1ZSk7XG5cdHByb3h5UHJvcGVydHkodmlkZW8sICdlbmRlZCcsIHBsYXllci5kcml2ZXIpO1xuXHRwcm94eVByb3BlcnR5KHZpZGVvLCAnbG9vcCcsIHBsYXllci5kcml2ZXIsIHRydWUpO1xuXHRwcmV2ZW50RXZlbnQodmlkZW8sICdzZWVraW5nJyk7XG5cdHByZXZlbnRFdmVudCh2aWRlbywgJ3NlZWtlZCcpO1xuXHRwcmV2ZW50RXZlbnQodmlkZW8sICd0aW1ldXBkYXRlJywg4LKgZXZlbnQsIGZhbHNlKTtcblx0cHJldmVudEV2ZW50KHZpZGVvLCAnZW5kZWQnLCDgsqBldmVudCwgZmFsc2UpOyAvLyBwcmV2ZW50IG9jY2FzaW9uYWwgbmF0aXZlIGVuZGVkIGV2ZW50c1xufVxuXG5mdW5jdGlvbiBlbmFibGVJbmxpbmVWaWRlbyh2aWRlbywgaGFzQXVkaW8sIG9ubHlXaGl0ZWxpc3RlZCkge1xuXHRpZiAoIGhhc0F1ZGlvID09PSB2b2lkIDAgKSBoYXNBdWRpbyA9IHRydWU7XG5cdGlmICggb25seVdoaXRlbGlzdGVkID09PSB2b2lkIDAgKSBvbmx5V2hpdGVsaXN0ZWQgPSB0cnVlO1xuXG5cdGlmICgob25seVdoaXRlbGlzdGVkICYmICFpc1doaXRlbGlzdGVkKSB8fCB2aWRlb1vgsqBdKSB7XG5cdFx0cmV0dXJuO1xuXHR9XG5cdGFkZFBsYXllcih2aWRlbywgaGFzQXVkaW8pO1xuXHRvdmVybG9hZEFQSSh2aWRlbyk7XG5cdHZpZGVvLmNsYXNzTGlzdC5hZGQoJ0lJVicpO1xuXHRpZiAoIWhhc0F1ZGlvICYmIHZpZGVvLmF1dG9wbGF5KSB7XG5cdFx0dmlkZW8ucGxheSgpO1xuXHR9XG5cdGlmICghL2lQaG9uZXxpUG9kfGlQYWQvLnRlc3QobmF2aWdhdG9yLnBsYXRmb3JtKSkge1xuXHRcdGNvbnNvbGUud2FybignaXBob25lLWlubGluZS12aWRlbyBpcyBub3QgZ3VhcmFudGVlZCB0byB3b3JrIGluIGVtdWxhdGVkIGVudmlyb25tZW50cycpO1xuXHR9XG59XG5cbmVuYWJsZUlubGluZVZpZGVvLmlzV2hpdGVsaXN0ZWQgPSBpc1doaXRlbGlzdGVkO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGVuYWJsZUlubGluZVZpZGVvOyIsIid1c2Ugc3RyaWN0JztcblxudmFyIGluZGV4ID0gdHlwZW9mIFN5bWJvbCA9PT0gJ3VuZGVmaW5lZCcgPyBmdW5jdGlvbiAoZGVzY3JpcHRpb24pIHtcblx0cmV0dXJuICdAJyArIChkZXNjcmlwdGlvbiB8fCAnQCcpICsgTWF0aC5yYW5kb20oKTtcbn0gOiBTeW1ib2w7XG5cbm1vZHVsZS5leHBvcnRzID0gaW5kZXg7IiwiLyoqXG4gKlxuICogKGMpIFdlbnNoZW5nIFlhbiA8eWFud3NoQGdtYWlsLmNvbT5cbiAqIERhdGU6IDEwLzMwLzE2XG4gKlxuICogRm9yIHRoZSBmdWxsIGNvcHlyaWdodCBhbmQgbGljZW5zZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpZXcgdGhlIExJQ0VOU0VcbiAqIGZpbGUgdGhhdCB3YXMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHNvdXJjZSBjb2RlLlxuICovXG4ndXNlIHN0cmljdCc7XG5cbmltcG9ydCBEZXRlY3RvciBmcm9tICcuLi9saWIvRGV0ZWN0b3InO1xuaW1wb3J0IE1vYmlsZUJ1ZmZlcmluZyBmcm9tICcuLi9saWIvTW9iaWxlQnVmZmVyaW5nJztcblxuY29uc3QgSEFWRV9DVVJSRU5UX0RBVEEgPSAyO1xuXG52YXIgQmFzZUNhbnZhcyA9IGZ1bmN0aW9uIChiYXNlQ29tcG9uZW50LCBUSFJFRSwgc2V0dGluZ3MgPSB7fSkge1xuICAgIHJldHVybiB7XG4gICAgICAgIGNvbnN0cnVjdG9yOiBmdW5jdGlvbiBpbml0KHBsYXllciwgb3B0aW9ucyl7XG4gICAgICAgICAgICB0aGlzLnNldHRpbmdzID0gb3B0aW9ucztcbiAgICAgICAgICAgIC8vYmFzaWMgc2V0dGluZ3NcbiAgICAgICAgICAgIHRoaXMud2lkdGggPSBwbGF5ZXIuZWwoKS5vZmZzZXRXaWR0aCwgdGhpcy5oZWlnaHQgPSBwbGF5ZXIuZWwoKS5vZmZzZXRIZWlnaHQ7XG4gICAgICAgICAgICB0aGlzLmxvbiA9IG9wdGlvbnMuaW5pdExvbiwgdGhpcy5sYXQgPSBvcHRpb25zLmluaXRMYXQsIHRoaXMucGhpID0gMCwgdGhpcy50aGV0YSA9IDA7XG4gICAgICAgICAgICB0aGlzLnZpZGVvVHlwZSA9IG9wdGlvbnMudmlkZW9UeXBlO1xuICAgICAgICAgICAgdGhpcy5jbGlja1RvVG9nZ2xlID0gb3B0aW9ucy5jbGlja1RvVG9nZ2xlO1xuICAgICAgICAgICAgdGhpcy5tb3VzZURvd24gPSBmYWxzZTtcbiAgICAgICAgICAgI
1598HRoaXMuaXNVc2VySW50ZXJhY3RpbmcgPSBmYWxzZTtcblxuICAgICAgICAgICAgLy9kZWZpbmUgcmVuZGVyXG4gICAgICAgICAgICB0aGlzLnJlbmRlcmVyID0gbmV3IFRIUkVFLldlYkdMUmVuZGVyZXIoKTtcbiAgICAgICAgICAgIHRoaXMucmVuZGVyZXIuc2V0UGl4ZWxSYXRpbyh3aW5kb3cuZGV2aWNlUGl4ZWxSYXRpbyk7XG4gICAgICAgICAgICB0aGlzLnJlbmRlcmVyLnNldFNpemUodGhpcy53aWR0aCwgdGhpcy5oZWlnaHQpO1xuICAgICAgICAgICAgdGhpcy5yZW5kZXJlci5hdXRvQ2xlYXIgPSBmYWxzZTtcbiAgICAgICAgICAgIHRoaXMucmVuZGVyZXIuc2V0Q2xlYXJDb2xvcigweDAwMDAwMCwgMSk7XG5cbiAgICAgICAgICAgIC8vZGVmaW5lIHRleHR1cmUsIG9uIGllIDExLCB3ZSBuZWVkIGFkZGl0aW9uYWwgaGVscGVyIGNhbnZhcyB0byBzb2x2ZSByZW5kZXJpbmcgaXNzdWUuXG4gICAgICAgICAgICB2YXIgdmlkZW8gPSBzZXR0aW5ncy5nZXRUZWNoKHBsYXllcik7XG4gICAgICAgICAgICB0aGlzLnN1cHBvcnRWaWRlb1RleHR1cmUgPSBEZXRlY3Rvci5zdXBwb3J0VmlkZW9UZXh0dXJlKCk7XG4gICAgICAgICAgICB0aGlzLmxpdmVTdHJlYW1PblNhZmFyaSA9IERldGVjdG9yLmlzTGl2ZVN0cmVhbU9uU2FmYXJpKHZpZGVvKTtcbiAgICAgICAgICAgIGlmKHRoaXMubGl2ZVN0cmVhbU9uU2FmYXJpKSB0aGlzLnN1cHBvcnRWaWRlb1RleHR1cmUgPSBmYWxzZTtcbiAgICAgICAgICAgIGlmKCF0aGlzLnN1cHBvcnRWaWRlb1RleHR1cmUpe1xuICAgICAgICAgICAgICAgIHRoaXMuaGVscGVyQ2FudmFzID0gcGxheWVyLmFkZENoaWxkKFwiSGVscGVyQ2FudmFzXCIsIHtcbiAgICAgICAgICAgICAgICAgICAgdmlkZW86IHZpZGVvLFxuICAgICAgICAgICAgICAgICAgICB3aWR0aDogdGhpcy53aWR0aCxcbiAgICAgICAgICAgICAgICAgICAgaGVpZ2h0OiB0aGlzLmhlaWdodFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIHZhciBjb250ZXh0ID0gdGhpcy5oZWxwZXJDYW52YXMuZWwoKTtcbiAgICAgICAgICAgICAgICB0aGlzLnRleHR1cmUgPSBuZXcgVEhSRUUuVGV4dHVyZShjb250ZXh0KTtcbiAgICAgICAgICAgIH1lbHNle1xuICAgICAgICAgICAgICAgIHRoaXMudGV4dHVyZSA9IG5ldyBUSFJFRS5UZXh0dXJlKHZpZGVvKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdmlkZW8uc3R5bGUuZGlzcGxheSA9IFwibm9uZVwiO1xuXG4gICAgICAgICAgICB0aGlzLnRleHR1cmUuZ2VuZXJhdGVNaXBtYXBzID0gZmFsc2U7XG4gICAgICAgICAgICB0aGlzLnRleHR1cmUubWluRmlsdGVyID0gVEhSRUUuTGluZWFyRmlsdGVyO1xuICAgICAgICAgICAgdGhpcy50ZXh0dXJlLm1heEZpbHRlciA9IFRIUkVFLkxpbmVhckZpbHRlcjtcbiAgICAgICAgICAgIHRoaXMudGV4dHVyZS5mb3JtYXQgPSBUSFJFRS5SR0JGb3JtYXQ7XG5cbiAgICAgICAgICAgIHRoaXMuZWxfID0gdGhpcy5yZW5kZXJlci5kb21FbGVtZW50O1xuICAgICAgICAgICAgdGhpcy5lbF8uY2xhc3NMaXN0LmFkZCgndmpzLXZpZGVvLWNhbnZhcycpO1xuXG4gICAgICAgICAgICBvcHRpb25zLmVsID0gdGhpcy5lbF87XG4gICAgICAgICAgICBiYXNlQ29tcG9uZW50LmNhbGwodGhpcywgcGxheWVyLCBvcHRpb25zKTtcblxuICAgICAgICAgICAgdGhpcy5hdHRhY2hDb250cm9sRXZlbnRzKCk7XG4gICAgICAgICAgICB0aGlzLnBsYXllcigpLm9uKFwicGxheVwiLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgdGhpcy50aW1lID0gbmV3IERhdGUoKS5nZXRUaW1lKCk7XG4gICAgICAgICAgICAgICAgdGhpcy5hbmltYXRlKCk7XG4gICAgICAgICAgICB9LmJpbmQodGhpcykpO1xuICAgICAgICB9LFxuXG4gICAgICAgIGF0dGFjaENvbnRyb2xFdmVudHM6IGZ1bmN0aW9uKCl7XG4gICAgICAgICAgICB0aGlzLm9uKCdtb3VzZW1vdmUnLCB0aGlzLmhhbmRsZU1vdXNlTW92ZS5iaW5kKHRoaXMpKTtcbiAgICAgICAgICAgIHRoaXMub24oJ3RvdWNobW92ZScsIHRoaXMuaGFuZGxlTW91c2VNb3ZlLmJpbmQodGhpcykpO1xuICAgICAgICAgICAgdGhpcy5vbignbW91c2Vkb3duJywgdGhpcy5oYW5kbGVNb3VzZURvd24uYmluZCh0aGlzKSk7XG4gICAgICAgICAgICB0aGlzLm9uKCd0b3VjaHN0YXJ0Jyx0aGlzLmhhbmRsZU1vdXNlRG93bi5iaW5kKHRoaXMpKTtcbiAgICAgICAgICAgIHRoaXMub24oJ21vdXNldXAnLCB0aGlzLmhhbmRsZU1vdXNlVXAuYmluZCh0aGlzKSk7XG4gICAgICAgICAgICB0aGlzLm9uKCd0b3VjaGVuZCcsIHRoaXMuaGFuZGxlTW91c2VVcC5iaW5kKHRoaXMpKTtcbiAgICAgICAgICAgIGlmKHRoaXMuc2V0dGluZ3Muc2Nyb2xsYWJsZSl7XG4gICAgICAgICAgICAgICAgdGhpcy5vbignbW91c2V3aGVlbCcsIHRoaXMuaGFuZGxlTW91c2VXaGVlbC5iaW5kKHRoaXMpKTtcbiAgICAgICAgICAgICAgICB0aGlzLm9uKCdNb3pNb3VzZVBpeGVsU2Nyb2xsJywgdGhpcy5oYW5kbGVNb3VzZVdoZWVsLmJpbmQodGhpcykpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5vbignbW91c2VlbnRlcicsIHRoaXMuaGFuZGxlTW91c2VFbnRlci5iaW5kKHRoaXMpKTtcbiAgICAgICAgICAgIHRoaXMub24oJ21vdXNlbGVhdmUnLCB0aGlzLmhhbmRsZU1vdXNlTGVhc2UuYmluZCh0aGlzKSk7XG4gICAgICAgIH0sXG5cbiAgICAgICAgaGFuZGxlUmVzaXplOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICB0aGlzLndpZHRoID0gdGhpcy5wbGF5ZXIoKS5lbCgpLm9mZnNldFdpZHRoLCB0aGlzLmhlaWdodCA9IHRoaXMucGxheWVyKCkuZWwoKS5vZmZzZXRIZWlnaHQ7XG4gICAgICAgICAgICB0aGlzLnJlbmRlcmVyLnNldFNpemUoIHRoaXMud2lkdGgsIHRoaXMuaGVpZ2h0ICk7XG4gICAgICAgIH0sXG5cbiAgICAgICAgaGFuZGxlTW91c2VVcDogZnVuY3Rpb24oZXZlbnQpe1xuICAgICAgICAgICAgdGhpcy5tb3VzZURvd24gPSBmYWxzZTtcbiAgICAgICAgICAgIGlmKHRoaXMuY2xpY2tUb1RvZ2dsZSl7XG4gICAgICAgICAgICAgICAgdmFyIGNsaWVudFggPSBldmVudC5jbGllbnRYIHx8IGV2ZW50LmNoYW5nZWRUb3VjaGVzICYmIGV2ZW50LmNoYW5nZWRUb3VjaGVzWzBdLmNsaWVudFg7XG4gICAgICAgICAgICAgICAgdmFyIGNsaWVudFkgPSBldmVudC5jbGllbnRZIHx8IGV2ZW50LmNoYW5nZWRUb3VjaGVzICYmIGV2ZW50LmNoYW5nZWRUb3VjaGVzWzBdLmNsaWVudFk7XG4gICAgICAgICAgICAgICAgaWYodHlwZW9mIGNsaWVudFggPT09IFwidW5kZWZpbmVkXCIgfHwgY2xpZW50WSA9PT0gXCJ1bmRlZmluZWRcIikgcmV0dXJuO1xuICAgICAgICAgICAgICAgI
1598HZhciBkaWZmWCA9IE1hdGguYWJzKGNsaWVudFggLSB0aGlzLm9uUG9pbnRlckRvd25Qb2ludGVyWCk7XG4gICAgICAgICAgICAgICAgdmFyIGRpZmZZID0gTWF0aC5hYnMoY2xpZW50WSAtIHRoaXMub25Qb2ludGVyRG93blBvaW50ZXJZKTtcbiAgICAgICAgICAgICAgICBpZihkaWZmWCA8IDAuMSAmJiBkaWZmWSA8IDAuMSlcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wbGF5ZXIoKS5wYXVzZWQoKSA/IHRoaXMucGxheWVyKCkucGxheSgpIDogdGhpcy5wbGF5ZXIoKS5wYXVzZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9LFxuXG4gICAgICAgIGhhbmRsZU1vdXNlRG93bjogZnVuY3Rpb24oZXZlbnQpe1xuICAgICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgIHZhciBjbGllbnRYID0gZXZlbnQuY2xpZW50WCB8fCBldmVudC50b3VjaGVzICYmIGV2ZW50LnRvdWNoZXNbMF0uY2xpZW50WDtcbiAgICAgICAgICAgIHZhciBjbGllbnRZID0gZXZlbnQuY2xpZW50WSB8fCBldmVudC50b3VjaGVzICYmIGV2ZW50LnRvdWNoZXNbMF0uY2xpZW50WTtcbiAgICAgICAgICAgIGlmKHR5cGVvZiBjbGllbnRYID09PSBcInVuZGVmaW5lZFwiIHx8IGNsaWVudFkgPT09IFwidW5kZWZpbmVkXCIpIHJldHVybjtcbiAgICAgICAgICAgIHRoaXMubW91c2VEb3duID0gdHJ1ZTtcbiAgICAgICAgICAgIHRoaXMub25Qb2ludGVyRG93blBvaW50ZXJYID0gY2xpZW50WDtcbiAgICAgICAgICAgIHRoaXMub25Qb2ludGVyRG93blBvaW50ZXJZID0gY2xpZW50WTtcbiAgICAgICAgICAgIHRoaXMub25Qb2ludGVyRG93bkxvbiA9IHRoaXMubG9uO1xuICAgICAgICAgICAgdGhpcy5vblBvaW50ZXJEb3duTGF0ID0gdGhpcy5sYXQ7XG4gICAgICAgIH0sXG5cbiAgICAgICAgaGFuZGxlTW91c2VNb3ZlOiBmdW5jdGlvbihldmVudCl7XG4gICAgICAgICAgICB2Y
1598XIgY2xpZW50WCA9IGV2ZW50LmNsaWVudFggfHwgZXZlbnQudG91Y2hlcyAmJiBldmVudC50b3VjaGVzWzBdLmNsaWVudFg7XG4gICAgICAgICAgICB2YXIgY2xpZW50WSA9IGV2ZW50LmNsaWVudFkgfHwgZXZlbnQudG91Y2hlcyAmJiBldmVudC50b3VjaGVzWzBdLmNsaWVudFk7XG4gICAgICAgICAgICBpZih0eXBlb2YgY2xpZW50WCA9PT0gXCJ1bmRlZmluZWRcIiB8fCBjbGllbnRZID09PSBcInVuZGVmaW5lZFwiKSByZXR1cm47XG4gICAgICAgICAgICBpZih0aGlzLnNldHRpbmdzLmNsaWNrQW5kRHJhZyl7XG4gICAgICAgICAgICAgICAgaWYodGhpcy5tb3VzZURvd24pe1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmxvbiA9ICggdGhpcy5vblBvaW50ZXJEb3duUG9pbnRlclggLSBjbGllbnRYICkgKiAwLjIgKyB0aGlzLm9uUG9pbnRlckRvd25Mb247XG4gICAgICAgICAgICAgICAgICAgIHRoaXMubGF0ID0gKCBjbGllbnRZIC0gdGhpcy5vblBvaW50ZXJEb3duUG9pbnRlclkgKSAqIDAuMiArIHRoaXMub25Qb2ludGVyRG93bkxhdDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9ZWxzZXtcbiAgICAgICAgICAgICAgICB2YXIgeCA9IGV2ZW50LnBhZ2VYIC0gdGhpcy5lbF8ub2Zmc2V0TGVmdDtcbiAgICAgICAgICAgICAgICB2YXIgeSA9IGV2ZW50LnBhZ2VZIC0gdGhpcy5lbF8ub2Zmc2V0VG9wO1xuICAgICAgICAgICAgICAgIHRoaXMubG9uID0gKHggLyB0aGlzLndpZHRoKSAqIDQzMCAtIDIyNTtcbiAgICAgICAgICAgICAgICB0aGlzLmxhdCA9ICh5IC8gdGhpcy5oZWlnaHQpICogLTE4MCArIDkwO1xuICAgICAgICAgICAgfVxuICAgICAgICB9LFxuXG4gICAgICAgIGhhbmRsZU1vYmlsZU9yaWVudGF0aW9uOiBmdW5jdGlvbiAoZXZlbnQpIHtcbiAgICAgICAgICAgIGlmKHR5cGVvZiBldmVudC5yb3RhdGlvblJhdGUgPT09IFwidW5kZWZpbmVkXCIpIHJldHVybjtcbiAgICAgICAgICAgIHZhciB4ID0gZXZlbnQucm90YXRpb25SYXRlLmFscGhhO1xuICAgICAgICAgICAgdmFyIHkgPSBldmVudC5yb3RhdGlvblJhdGUuYmV0YTtcbiAgICAgICAgICAgIHZhciBwb3J0cmFpdCA9ICh0eXBlb2YgZXZlbnQucG9ydHJhaXQgIT09IFwidW5kZWZpbmVkXCIpPyBldmVudC5wb3J0cmFpdCA6IHdpbmRvdy5tYXRjaE1lZGlhKFwiKG9yaWVudGF0aW9uOiBwb3J0cmFpdClcIikubWF0Y2hlcztcbiAgICAgICAgICAgIHZhciBsYW5kc2NhcGUgPSAodHlwZW9mIGV2ZW50LmxhbmRzY2FwZSAhPT0gXCJ1bmRlZmluZWRcIik/IGV2ZW50LmxhbmRzY2FwZSA6IHdpbmRvdy5tYXRjaE1lZGlhKFwiKG9yaWVudGF0aW9uOiBsYW5kc2NhcGUpXCIpLm1hdGNoZXM7XG4gICAgICAgICAgICB2Y
1598XIgb3JpZW50YXRpb24gPSBldmVudC5vcmllbnRhdGlvbiB8fCB3aW5kb3cub3JpZW50YXRpb247XG5cbiAgICAgICAgICAgIGlmIChwb3J0cmFpdCkge1xuICAgICAgICAgICAgICAgIHRoaXMubG9uID0gdGhpcy5sb24gLSB5ICogdGhpcy5zZXR0aW5ncy5tb2JpbGVWaWJyYXRpb25WYWx1ZTtcbiAgICAgICAgICAgICAgICB0aGlzLmxhdCA9IHRoaXMubGF0ICsgeCAqIHRoaXMuc2V0dGluZ3MubW9iaWxlVmlicmF0aW9uVmFsdWU7XG4gICAgICAgICAgICB9ZWxzZSBpZihsYW5kc2NhcGUpe1xuICAgICAgICAgICAgICAgIHZhciBvcmllbnRhdGlvbkRlZ3JlZSA9IC05MDtcbiAgICAgICAgICAgICAgICBpZih0eXBlb2Ygb3JpZW50YXRpb24gIT0gXCJ1bmRlZmluZWRcIil7XG4gICAgICAgICAgICAgICAgICAgIG9yaWVudGF0aW9uRGVncmVlID0gb3JpZW50YXRpb247XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdGhpcy5sb24gPSAob3JpZW50YXRpb25EZWdyZWUgPT0gLTkwKT8gdGhpcy5sb24gKyB4ICogdGhpcy5zZXR0aW5ncy5tb2JpbGVWaWJyYXRpb25WYWx1ZSA6IHRoaXMubG9uIC0geCAqIHRoaXMuc2V0dGluZ3MubW9iaWxlVmlicmF0aW9uVmFsdWU7XG4gICAgICAgICAgICAgICAgdGhpcy5sYXQgPSAob3JpZW50YXRpb25EZWdyZWUgPT0gLTkwKT8gdGhpcy5sYXQgKyB5ICogdGhpcy5zZXR0aW5ncy5tb2JpbGVWaWJyYXRpb25WYWx1ZSA6IHRoaXMubGF0IC0geSAqIHRoaXMuc2V0dGluZ3MubW9iaWxlVmlicmF0aW9uVmFsdWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG5cbiAgICAgICAgaGFuZGxlTW91c2VXaGVlbDogZnVuY3Rpb24oZXZlbnQpe1xuICAgICAgICAgICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICB9LFxuXG4gICAgICAgIGhhbmRsZU1vdXNlRW50ZXI6IGZ1bmN0aW9uIChldmVudCkge1xuICAgICAgICAgICAgdGhpcy5pc1VzZXJJbnRlcmFjdGluZyA9IHRydWU7XG4gICAgICAgIH0sXG5cbiAgICAgICAgaGFuZGxlTW91c2VMZWFzZTogZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgICAgICAgICB0aGlzLmlzVXNlckludGVyYWN0aW5nID0gZmFsc2U7XG4gICAgICAgIH0sXG5cbiAgICAgICAgYW5pbWF0ZTogZnVuY3Rpb24oKXtcbiAgICAgICAgICAgIHRoaXMucmVxdWVzdEFuaW1hdGlvbklkID0gcmVxdWVzdEFuaW1hdGlvbkZyYW1lKCB0aGlzLmFuaW1hdGUuYmluZCh0aGlzKSApO1xuICAgICAgICAgICAgaWYoIXRoaXMucGxheWVyKCkucGF1c2VkKCkpe1xuICAgICAgICAgICAgICAgIGlmKHR5cGVvZih0aGlzLnRleHR1cmUpICE9PSBcInVuZGVmaW5lZFwiICYmICghdGhpcy5pc1BsYXlPbk1vYmlsZSAmJiB0aGlzLnBsYXllcigpLnJlYWR5U3RhdGUoKSA+PSBIQVZFX0NVUlJFTlRfREFUQSB8fCB0aGlzLmlzUGxheU9uTW9iaWxlICYmIHRoaXMucGxheWVyKCkuaGFzQ2xhc3MoXCJ2anMtcGxheWluZ1wiKSkpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGN0ID0gbmV3IERhdGUoKS5nZXRUaW1lKCk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChjdCAtIHRoaXMudGltZSA+PSAzMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy50ZXh0dXJlLm5lZWRzVXBkYXRlID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMudGltZSA9IGN0O1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmKHRoaXMuaXNQbGF5T25Nb2JpbGUpe1xuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGN1cnJlbnRUaW1lID0gdGhpcy5wbGF5ZXIoKS5jdXJyZW50VGltZSgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYoTW9iaWxlQnVmZmVyaW5nLmlzQnVmZmVyaW5nKGN1cnJlbnRUaW1lKSl7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYoIXRoaXMucGxheWVyKCkuaGFzQ2xhc3MoXCJ2anMtcGFub3JhbWEtbW9iaWxlLWlubGluZS12aWRlby1idWZmZXJpbmdcIikpe1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnBsYXllcigpLmFkZENsYXNzKFwidmpzLXBhbm9yYW1hLW1vYmlsZS1pbmxpbmUtdmlkZW8tYnVmZmVyaW5nXCIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH1lbHNle1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmKHRoaXMucGxheWVyKCkuaGFzQ2xhc3MoXCJ2anMtcGFub3JhbWEtbW9iaWxlLWlubGluZS12aWRlby1idWZmZXJpbmdcIikpe1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnBsYXllcigpLnJlbW92ZUNsYXNzKFwidmpzLXBhbm9yYW1hLW1vYmlsZS1pbmxpbmUtdmlkZW8tYnVmZmVyaW5nXCIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMucmVuZGVyKCk7XG4gICAgICAgIH0sXG5cbiAgICAgICAgcmVuZGVyOiBmdW5jdGlvbigpe1xuICAgICAgICAgICAgaWYoIXRoaXMuaXNVc2VySW50ZXJhY3Rpbmcpe1xuICAgICAgICAgICAgICAgIHZhciBzeW1ib2xMYXQgPSAodGhpcy5sYXQgPiB0aGlzLnNldHRpbmdzLmluaXRMYXQpPyAgLTEgOiAxO1xuICAgICAgICAgICAgICAgIHZhciBzeW1ib2xMb24gPSAodGhpcy5sb24gPiB0aGlzLnNldHRpbmdzLmluaXRMb24pPyAgLTEgOiAxO1xuICAgICAgICAgICAgICAgIGlmKHRoaXMuc2V0dGluZ3MuYmFja1RvVmVydGljYWxDZW50ZXIpe1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmxhdCA9IChcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubGF0ID4gKHRoaXMuc2V0dGluZ3MuaW5pdExhdCAtIE1hdGguYWJzKHRoaXMuc2V0dGluZ3MucmV0dXJuU3RlcExhdCkpICYmXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmxhdCA8ICh0aGlzLnNldHRpbmdzLmluaXRMYXQgKyBNYXRoLmFicyh0aGlzLnNldHRpbmdzLnJldHVyblN0ZXBMYXQpKVxuICAgICAgICAgICAgICAgICAgICApPyB0aGlzLnNldHRpbmdzLmluaXRMYXQgOiB0aGlzLmxhdCArIH
1598RoaXMuc2V0dGluZ3MucmV0dXJuU3RlcExhdCAqIHN5bWJvbExhdDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYodGhpcy5zZXR0aW5ncy5iYWNrVG9Ib3Jpem9uQ2VudGVyKXtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5sb24gPSAoXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmxvbiA+ICh0aGlzLnNldHRpbmdzLmluaXRMb24gLSBNYXRoLmFicyh0aGlzLnNldHRpbmdzLnJldHVyblN0ZXBMb24pKSAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5sb24gPCAodGhpcy5zZXR0aW5ncy5pbml0TG9uICsgTWF0aC5hYnModGhpcy5zZXR0aW5ncy5yZXR1cm5TdGVwTG9uKSlcbiAgICAgICAgICAgICAgICAgICAgKT8gdGhpcy5zZXR0aW5ncy5pbml0TG9uIDogdGhpcy5sb24gKyB0aGlzLnNldHRpbmdzLnJldHVyblN0ZXBMb24gKiBzeW1ib2xMb247XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5sYXQgPSBNYXRoLm1heCggdGhpcy5zZXR0aW5ncy5taW5MYXQsIE1hdGgubWluKCB0aGlzLnNldHRpbmdzLm1heExhdCwgdGhpcy5sYXQgKSApO1xuICAgICAgICAgICAgdGhpcy5sb24gPSBNYXRoLm1heCggdGhpcy5zZXR0aW5ncy5taW5Mb24sIE1hdGgubWluKCB0aGlzLnNldHRpbmdzLm1heExvbiwgdGhpcy5sb24gKSApO1xuICAgICAgICAgICAgdGhpcy5waGkgPSBUSFJFRS5NYXRoLmRlZ1RvUmFkKCA5MCAtIHRoaXMubGF0ICk7XG4gICAgICAgICAgICB0aGlzLnRoZXRhID0gVEhSRUUuTWF0aC5kZWdUb1JhZCggdGhpcy5sb24gKTtcblxuICAgICAgICAgICAgaWYoIXRoaXMuc3VwcG9ydFZpZGVvVGV4dHVyZSl7XG4gICAgICAgICAgICAgICAgdGhpcy5oZWxwZXJDYW52YXMudXBkYXRlKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLnJlbmRlcmVyLmNsZWFyKCk7XG4gICAgICAgIH0sXG5cbiAgICAgICAgcGxheU9uTW9iaWxlOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICB0aGlzLmlzUGxheU9uTW9iaWxlID0gdHJ1ZTtcbiAgICAgICAgICAgIGlmKHRoaXMuc2V0dGluZ3MuYXV0b01vYmlsZU9yaWVudGF0aW9uKVxuICAgICAgICAgICAgICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdkZXZpY2Vtb3Rpb24nLCB0aGlzLmhhbmRsZU1vYmlsZU9yaWVudGF0aW9uLmJpbmQodGhpcykpO1xuICAgICAgICB9LFxuXG4gICAgICAgIGVsOiBmdW5jdGlvbigpe1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZWxfO1xuICAgICAgICB9XG4gICAgfVxufTtcblxuZXhwb3J0IGRlZmF1bHQgQmFzZUNhbnZhcztcbiIsIi8qKlxuICogQ3JlYXRlZCBieSB5YW53c2ggb24gNC8zLzE2LlxuICovXG5cbmltcG9ydCBCYXNlQ2FudmFzIGZyb20gJy4vQmFzZUNhbnZhcyc7XG5pbXBvcnQgVXRpbCBmcm9tICcuL1V0aWwnO1xuXG52YXIgQ2FudmFzID0gZnVuY3Rpb24gKGJhc2VDb21wb25lbnQsIFRIUkVFLCBzZXR0aW5ncyA9IHt9KSB7XG4gICAgdmFyIHBhcmVudCA9IEJhc2VDYW52YXMoYmFzZUNvbXBvbmVudCwgVEhSRUUsIHNldHRpbmdzKTtcblxuICAgIHJldHVybiBVdGlsLmV4dGVuZChwYXJlbnQsIHtcbiAgICAgICAgY29uc3RydWN0b3I6IGZ1bmN0aW9uIGluaXQocGxheWVyLCBvcHRpb25zKXtcbiAgICAgICAgICAgIHBhcmVudC5jb25zdHJ1Y3Rvci5jYWxsKHRoaXMsIHBsYXllciwgb3B0aW9ucyk7XG5cbiAgICAgICAgICAgIHRoaXMuVlJNb2RlID0gZmFsc2U7XG4gICAgICAgICAgICAvL2RlZmluZSBzY2VuZVxuICAgICAgICAgICAgdGhpcy5zY2VuZSA9IG5ldyBUSFJFRS5TY2VuZSgpO1xuICAgICAgICAgICAgLy9kZWZpbmUgY2FtZXJhXG4gICAgICAgICAgICB0aGlzLmNhbWVyYSA9IG5ldyBUSFJFRS5QZXJzcGVjdGl2ZUNhbWVyYShvcHRpb25zLmluaXRGb3YsIHRoaXMud2lkdGggLyB0aGlzLmhlaWdodCwgMSwgMjAwMCk7XG4gICAgICAgICAgICB0aGlzLmNhbWVyYS50YXJnZXQgPSBuZXcgVEhSRUUuVmVjdG9yMyggMCwgMCwgMCApO1xuXG4gICAgICAgICAgICAvL2RlZmluZSBnZW9tZXRyeVxuICAgICAgICAgICAgdmFyIGdlb21ldHJ5ID0gKHRoaXMudmlkZW9UeXBlID09PSBcImVxdWlyZWN0YW5ndWxhclwiKT8gbmV3IFRIUkVFLlNwaGVyZUdlb21ldHJ5KDUwMCwgNjAsIDQwKTogbmV3IFRIUkVFLlNwaGVyZUJ1ZmZlckdlb21ldHJ5KCA1MDAsIDYwLCA0MCApLnRvTm9uSW5kZXhlZCgpO1xuICAgICAgICAgICAgaWYodGhpcy52aWRlb1R5cGUgPT09IFwiZmlzaGV5ZVwiKXtcbiAgICAgICAgICAgICAgICB2Y
1598XIgbm9ybWFscyA9IGdlb21ldHJ5LmF0dHJpYnV0ZXMubm9ybWFsLmFycmF5O1xuICAgICAgICAgICAgICAgIHZhciB1dnMgPSBnZW9tZXRyeS5hdHRyaWJ1dGVzLnV2LmFycmF5O1xuICAgICAgICAgICAgICAgIGZvciAoIHZhciBpID0gMCwgbCA9IG5vcm1hbHMubGVuZ3RoIC8gMzsgaSA8IGw7IGkgKysgKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciB4ID0gbm9ybWFsc1sgaSAqIDMgKyAwIF07XG4gICAgICAgICAgICAgICAgICAgIHZhciB5ID0gbm9ybWFsc1sgaSAqIDMgKyAxIF07XG4gICAgICAgICAgICAgICAgICAgIHZhciB6ID0gbm9ybWFsc1sgaSAqIDMgKyAyIF07XG5cbiAgICAgICAgICAgICAgICAgICAgdmFyIHIgPSBNYXRoLmFzaW4oTWF0aC5zcXJ0KHggKiB4ICsgeiAqIHopIC8gTWF0aC5zcXJ0KHggKiB4ICArIHkgKiB5ICsgeiAqIHopKSAvIE1hdGguUEk7XG4gICAgICAgICAgICAgICAgICAgIGlmKHkgPCAwKSByID0gMSAtIHI7XG4gICAgICAgICAgICAgICAgICAgIHZhciB0aGV0YSA9ICh4ID09IDAgJiYgeiA9PSAwKT8gMCA6IE1hdGguYWNvcyh4IC8gTWF0aC5zcXJ0KHggKiB4ICsgeiAqIHopKTtcbiAgICAgICAgICAgICAgICAgICAgaWYoeiA8IDApIHRoZXRhID0gdGhldGEgKiAtMTtcbiAgICAgICAgICAgICAgICAgICAgdXZzWyBpICogMiArIDAgXSA9IC0wLjggKiByICogTWF0aC5jb3ModGhldGEpICsgMC41O1xuICAgICAgICAgICAgICAgICAgICB1dnNbIGkgKiAyICsgMSBdID0gMC44ICogciAqIE1hdGguc2luKHRoZXRhKSArIDAuNTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZ2VvbWV0cnkucm90YXRlWCggb3B0aW9ucy5yb3RhdGVYKTtcbiAgICAgICAgICAgICAgICBnZW9tZXRyeS5yb3RhdGVZKCBvcHRpb25zLnJvdGF0ZVkpO1xuICAgICAgICAgICAgICAgIGdlb21ldHJ5LnJvdGF0ZVooIG9wdGlvbnMucm90YXRlWik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBnZW9tZXRyeS5zY2FsZSggLSAxLCAxLCAxICk7XG4gICAgICAgICAgICAvL2RlZmluZSBtZXNoXG4gICAgICAgICAgICB0aGlzLm1lc2ggPSBuZXcgVEhSRUUuTWVzaChnZW9tZXRyeSxcbiAgICAgICAgICAgICAgICBuZXcgVEhSRUUuTWVzaEJhc2ljTWF0ZXJpYWwoeyBtYXA6IHRoaXMudGV4dHVyZX0pXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgLy90aGlzLm1lc2guc2NhbGUueCA9IC0xO1xuICAgICAgICAgICAgdGhpcy5zY2VuZS5hZGQodGhpcy5tZXNoKTtcbiAgICAgICAgfSxcblxuICAgICAgICBlbmFibGVWUjogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgdGhpcy5WUk1vZGUgPSB0cnVlO1xuICAgICAgICAgICAgaWYodHlwZW9mIHZySE1EICE9PSAndW5kZWZpbmVkJyl7XG4gICAgICAgICAgICAgICAgdmFyIGV5ZVBhcmFtc0wgPSB2ckhNRC5nZXRFeWVQYXJhbWV0ZXJzKCAnbGVmdCcgKTtcbiAgICAgICAgICAgICAgICB2Y
1598XIgZXllUGFyYW1zUiA9IHZySE1ELmdldEV5ZVBhcmFtZXRlcnMoICdyaWdodCcgKTtcblxuICAgICAgICAgICAgICAgIHRoaXMuZXllRk9WTCA9IGV5ZVBhcmFtc0wucmVjb21tZW5kZWRGaWVsZE9mVmlldztcbiAgICAgICAgICAgICAgICB0aGlzLmV5ZUZPVlIgPSBleWVQYXJhbXNSLnJlY29tbWVuZGVkRmllbGRPZlZpZXc7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHRoaXMuY2FtZXJhTCA9IG5ldyBUSFJFRS5QZXJzcGVjdGl2ZUNhbWVyYSh0aGlzLmNhbWVyYS5mb3YsIHRoaXMud2lkdGggLzIgLyB0aGlzLmhlaWdodCwgMSwgMjAwMCk7XG4gICAgICAgICAgICB0aGlzLmNhbWVyYVIgPSBuZXcgVEhSRUUuUGVyc3BlY3RpdmVDYW1lcmEodGhpcy5jYW1lcmEuZm92LCB0aGlzLndpZHRoIC8yIC8gdGhpcy5oZWlnaHQsIDEsIDIwMDApO1xuICAgICAgICB9LFxuXG4gICAgICAgIGRpc2FibGVWUjogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgdGhpcy5WUk1vZGUgPSBmYWxzZTtcbiAgICAgICAgICAgIHRoaXMucmVuZGVyZXIuc2V0Vmlld3BvcnQoIDAsIDAsIHRoaXMud2lkdGgsIHRoaXMuaGVpZ2h0ICk7XG4gICAgICAgICAgICB0aGlzLnJlbmRlcmVyLnNldFNjaXNzb3IoIDAsIDAsIHRoaXMud2lkdGgsIHRoaXMuaGVpZ2h0ICk7XG4gICAgICAgIH0sXG5cbiAgICAgICAgaGFuZGxlUmVzaXplOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBwYXJlbnQuaGFuZGxlUmVzaXplLmNhbGwodGhpcyk7XG4gICAgICAgICAgICB0aGlzLmNhbWVyYS5hc3BlY3QgPSB0aGlzLndpZHRoIC8gdGhpcy5oZWlnaHQ7XG4gICAgICAgICAgICB0aGlzLmNhbWVyYS51cGRhdGVQcm9qZWN0aW9uTWF0cml4KCk7XG4gICAgICAgICAgICBpZih0aGlzLlZSTW9kZSl7XG4gICAgICAgICAgICAgICAgdGhpcy5jYW1lcmFMLmFzcGVjdCA9IHRoaXMuY2FtZXJhLmFzcGVjdCAvIDI7XG4gICAgICAgICAgICAgICAgdGhpcy5jYW1lcmFSLmFzcGVjdCA9IHRoaXMuY2FtZXJhLmFzcGVjdCAvIDI7XG4gICAgICAgICAgICAgICAgdGhpcy5jYW1lcmFMLnVwZGF0ZVByb2plY3Rpb25NYXRyaXgoKTtcbiAgICAgICAgICAgICAgICB0aGlzLmNhbWVyYVIudXBkYXRlUHJvamVjdGlvbk1hdHJpeCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9LFxuXG4gICAgICAgIGhhbmRsZU1vdXNlV2hlZWw6IGZ1bmN0aW9uKGV2ZW50KXtcbiAgICAgICAgICAgIHBhcmVudC5oYW5kbGVNb3VzZVdoZWVsKGV2ZW50KTtcbiAgICAgICAgICAgIC8vIFdlYktpdFxuICAgICAgICAgICAgaWYgKCBldmVudC53aGVlbERlbHRhWSApIHtcbiAgICAgICAgICAgICAgICB0aGlzLmNhbWVyYS5mb3YgLT0gZXZlbnQud2hlZWxEZWx0YVkgKiAwLjA1O1xuICAgICAgICAgICAgICAgIC8vIE9wZXJhIC8gRXhwbG9yZXIgOVxuICAgICAgICAgICAgfSBlbHNlIGlmICggZXZlbnQud2hlZWxEZWx0YSApIHtcbiAgICAgICAgICAgICAgICB0aGlzLmNhbWVyYS5mb3YgLT0gZXZlbnQud2hlZWxEZWx0YSAqIDAuMDU7XG4gICAgICAgICAgICAgICAgLy8gRmlyZWZveFxuICAgICAgICAgICAgfSBlbHNlIGlmICggZXZlbnQuZGV0YWlsICkge1xuICAgICAgICAgICAgICAgIHRoaXMuY2FtZXJhLmZvdiArPSBldmVudC5kZXRhaWwgKiAxLjA7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLmNhbWVyYS5mb3YgPSBNYXRoLm1pbih0aGlzLnNldHRpbmdzLm1heEZvdiwgdGhpcy5jYW1lcmEuZm92KTtcbiAgICAgICAgICAgIHRoaXMuY2FtZXJhLmZvdiA9IE1hdGgubWF4KHRoaXMuc2V0dGluZ3MubWluRm92LCB0aGlzLmNhbWVyYS5mb3YpO1xuICAgICAgICAgICAgdGhpcy5jYW1lcmEudXBkYXRlUHJvamVjdGlvbk1hdHJpeCgpO1xuICAgICAgICAgICAgaWYodGhpcy5WUk1vZGUpe1xuICAgICAgICAgICAgICAgIHRoaXMuY2FtZXJhTC5mb3YgPSB0aGlzLmNhbWVyYS5mb3Y7XG4gICAgICAgICAgICAgICAgdGhpcy5jYW1lcmFSLmZvdiA9IHRoaXMuY2FtZXJhLmZvdjtcbiAgICAgICAgICAgICAgICB0aGlzLmNhbWVyYUwudXBkYXRlUHJvamVjdGlvbk1hdHJpeCgpO1xuICAgICAgICAgICAgICAgIHRoaXMuY2FtZXJhUi51cGRhdGVQcm9qZWN0aW9uTWF0cml4KCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG5cbiAgICAgICAgcmVuZGVyOiBmdW5jdGlvbigpe1xuICAgICAgICAgICAgcGFyZW50LnJlbmRlci5jYWxsKHRoaXMpO1xuICAgICAgICAgICAgdGhpcy5jYW1lcmEudGFyZ2V0LnggPSA1MDAgKiBNYXRoLnNpbiggdGhpcy5waGkgKSAqIE1hdGguY29zKCB0aGlzLnRoZXRhICk7XG4gICAgICAgICAgICB0aGlzLmNhbWVyYS50YXJnZXQueSA9IDUwMCAqIE1hdGguY29zKCB0aGlzLnBoaSApO1xuICAgICAgICAgICAgdGhpcy5jYW1lcmEudGFyZ2V0LnogPSA1MDAgKiBNYXRoLnNpbiggdGhpcy5waGkgKSAqIE1hdGguc2luKCB0aGlzLnRoZXRhICk7XG4gICAgICAgICAgICB0aGlzLmNhbWVyYS5sb29rQXQoIHRoaXMuY2FtZXJhLnRhcmdldCApO1xuXG4gICAgICAgICAgICBpZighdGhpcy5WUk1vZGUpe1xuICAgICAgICAgICAgICAgIHRoaXMucmVuZGVyZXIucmVuZGVyKCB0aGlzLnNjZW5lLCB0aGlzLmNhbWVyYSApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZXtcbiAgICAgICAgICAgICAgICB2Y
1598XIgdmlld1BvcnRXaWR0aCA9IHRoaXMud2lkdGggLyAyLCB2aWV3UG9ydEhlaWdodCA9IHRoaXMuaGVpZ2h0O1xuICAgICAgICAgICAgICAgIGlmKHR5cGVvZiB2ckhNRCAhPT0gJ3VuZGVmaW5lZCcpe1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmNhbWVyYUwucHJvamVjdGlvbk1hdHJpeCA9IFV0aWwuZm92VG9Qcm9qZWN0aW9uKCB0aGlzLmV5ZUZPVkwsIHRydWUsIHRoaXMuY2FtZXJhLm5lYXIsIHRoaXMuY2FtZXJhLmZhciApO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmNhbWVyYVIucHJvamVjdGlvbk1hdHJpeCA9IFV0aWwuZm92VG9Qcm9qZWN0aW9uKCB0aGlzLmV5ZUZPVlIsIHRydWUsIHRoaXMuY2FtZXJhLm5lYXIsIHRoaXMuY2FtZXJhLmZhciApO1xuICAgICAgICAgICAgICAgIH1lbHNle1xuICAgICAgICAgICAgICAgICAgICB2YXIgbG9uTCA9IHRoaXMubG9uICsgdGhpcy5zZXR0aW5ncy5WUkdhcERlZ3JlZTtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGxvblIgPSB0aGlzLmxvbiAtIHRoaXMuc2V0dGluZ3MuVlJHYXBEZWdyZWU7XG5cbiAgICAgICAgICAgICAgICAgICAgdmFyIHRoZXRhTCA9IFRIUkVFLk1hdGguZGVnVG9SYWQoIGxvbkwgKTtcbiAgICAgICAgICAgICAgICAgICAgdmFyIHRoZXRhUiA9IFRIUkVFLk1hdGguZGVnVG9SYWQoIGxvblIgKTtcblxuICAgICAgICAgICAgICAgICAgICB2YXIgdGFyZ2V0TCA9IFV0aWwuZGVlcENvcHkodGhpcy5jYW1lcmEudGFyZ2V0KTtcbiAgICAgICAgICAgICAgICAgICAgdGFyZ2V0TC54ID0gNTAwICogTWF0aC5zaW4oIHRoaXMucGhpICkgKiBNYXRoLmNvcyggdGhldGFMICk7XG4gICAgICAgICAgICAgICAgICAgIHRhcmdldEwueiA9IDUwMCAqIE1hdGguc2luKCB0aGlzLnBoaSApICogTWF0aC5zaW4oIHRoZXRhTCApO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmNhbWVyYUwubG9va0F0KHRhcmdldEwpO1xuXG4gICAgICAgICAgICAgICAgICAgIHZhciB0YXJnZXRSID0gVXRpbC5kZWVwQ29weSh0aGlzLmNhbWVyYS50YXJnZXQpO1xuICAgICAgICAgICAgICAgICAgICB0YXJnZXRSLnggPSA1MDAgKiBNYXRoLnNpbiggdGhpcy5waGkgKSAqIE1hdGguY29zKCB0aGV0YVIgKTtcbiAgICAgICAgICAgICAgICAgICAgdGFyZ2V0Ui56ID0gNTAwICogTWF0aC5zaW4oIHRoaXMucGhpICkgKiBNYXRoLnNpbiggdGhldGFSICk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY2FtZXJhUi5sb29rQXQodGFyZ2V0Uik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIC8vIHJlbmRlciBsZWZ0IGV5ZVxuICAgICAgICAgICAgICAgIHRoaXMucmVuZGVyZXIuc2V0Vmlld3BvcnQoIDAsIDAsIHZpZXdQb3J0V2lkdGgsIHZpZXdQb3J0SGVpZ2h0ICk7XG4gICAgICAgICAgICAgICAgdGhpcy5yZW5kZXJlci5zZXRTY2lzc29yKCAwLCAwLCB2aWV3UG9ydFdpZHRoLCB2aWV3UG9ydEhlaWdodCApO1xuICAgICAgICAgICAgICAgIHRoaXMucmVuZGVyZXIucmVuZGVyKCB0aGlzLnNjZW5lLCB0aGlzLmNhbWVyYUwgKTtcblxuICAgICAgICAgICAgICAgIC8vIHJlbmRlciByaWdodCBleWVcbiAgICAgICAgICAgICAgICB0aGlzLnJlbmRlcmVyLnNldFZpZXdwb3J0KCB2aWV3UG9ydFdpZHRoLCAwLCB2aWV3UG9ydFdpZHRoLCB2aWV3UG9ydEhlaWdodCApO1xuICAgICAgICAgICAgICAgIHRoaXMucmVuZGVyZXIuc2V0U2Npc3Nvciggdmlld1BvcnRXaWR0aCwgMCwgdmlld1BvcnRXaWR0aCwgdmlld1BvcnRIZWlnaHQgKTtcbiAgICAgICAgICAgICAgICB0aGlzLnJlbmRlcmVyLnJlbmRlciggdGhpcy5zY2VuZSwgdGhpcy5jYW1lcmFSICk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9KTtcbn07XG5cbmV4cG9ydCBkZWZhdWx0IENhbnZhcztcbiIsIi8qKlxuICogQGF1dGhvciBhbHRlcmVkcSAvIGh0dHA6Ly9hbHRlcmVkcXVhbGlhLmNvbS9cbiAqIEBhdXRob3IgbXIuZG9vYiAvIGh0dHA6Ly9tcmRvb2IuY29tL1xuICovXG5cbnZhciBEZXRlY3RvciA9IHtcblxuICAgIGNhbnZhczogISEgd2luZG93LkNhbnZhc1JlbmRlcmluZ0NvbnRleHQyRCxcbiAgICB3ZWJnbDogKCBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgdHJ5IHtcblxuICAgICAgICAgICAgdmFyIGNhbnZhcyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoICdjYW52YXMnICk7IHJldHVybiAhISAoIHdpbmRvdy5XZWJHTFJlbmRlcmluZ0NvbnRleHQgJiYgKCBjYW52YXMuZ2V0Q29udGV4dCggJ3dlYmdsJyApIHx8IGNhbnZhcy5nZXRDb250ZXh0KCAnZXhwZXJpbWVudGFsLXdlYmdsJyApICkgKTtcblxuICAgICAgICB9IGNhdGNoICggZSApIHtcblxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuXG4gICAgICAgIH1cblxuICAgIH0gKSgpLFxuICAgIHdvcmtlcnM6ICEhIHdpbmRvdy5Xb3JrZXIsXG4gICAgZmlsZWFwaTogd2luZG93LkZpbGUgJiYgd2luZG93LkZpbGVSZWFkZXIgJiYgd2luZG93LkZpbGVMaXN0ICYmIHdpbmRvdy5CbG9iLFxuXG4gICAgIENoZWNrX1ZlcnNpb246IGZ1bmN0aW9uKCkge1xuICAgICAgICAgdmFyIHJ2ID0gLTE7IC8vIFJldHVybiB2YWx1ZSBhc3N1bWVzIGZhaWx1cmUuXG5cbiAgICAgICAgIGlmIChuYXZpZ2F0b3IuYXBwTmFtZSA9PSAnTWljcm9zb2Z0IEludGVybmV0IEV4cGxvcmVyJykge1xuXG4gICAgICAgICAgICAgdmFyIHVhID0gbmF2aWdhdG9yLnVzZXJBZ2VudCxcbiAgICAgICAgICAgICAgICAgcmUgPSBuZXcgUmVnRXhwKFwiTVNJRSAoWzAtOV17MSx9W1xcXFwuMC05XXswLH0pXCIpO1xuXG4gICAgICAgICAgICAgaWYgKHJlLmV4ZWModWEpICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgIHJ2ID0gcGFyc2VGbG9hdChSZWdFeHAuJDEpO1xuICAgICAgICAgICAgIH1cbiAgICAgICAgIH1cbiAgICAgICAgIGVsc2UgaWYgKG5hdmlnYXRvci5hcHBOYW1lID09IFwiTmV0c2NhcGVcIikge1xuICAgICAgICAgICAgIC8vLyBpbiBJRSAxMSB0aGUgbmF2aWdhdG9yLmFwcFZlcnNpb24gc2F5cyAndHJpZGVudCdcbiAgICAgICAgICAgICAvLy8gaW4gRWRnZSB0aGUgbmF2aWdhdG9yLmFwcFZlcnNpb24gZG9lcyBub3Qgc2F5IHRyaWRlbnRcbiAgICAgICAgICAgICBpZiAobmF2aWdhdG9yLmFwcFZlcnNpb24uaW5kZXhPZignVHJpZGVudCcpICE9PSAtMSkgcnYgPSAxMTtcbiAgICAgICAgICAgICBlbHNle1xuICAgICAgICAgICAgICAgICB2Y
1598XIgdWEgPSBuYXZpZ2F0b3IudXNlckFnZW50O1xuICAgICAgICAgICAgICAgICB2YXIgcmUgPSBuZXcgUmVnRXhwKFwiRWRnZVxcLyhbMC05XXsxLH1bXFxcXC4wLTldezAsfSlcIik7XG4gICAgICAgICAgICAgICAgIGlmIChyZS5leGVjKHVhKSAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICAgcnYgPSBwYXJzZUZsb2F0KFJlZ0V4cC4kMSk7XG4gICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICB9XG4gICAgICAgICB9XG5cbiAgICAgICAgIHJldHVybiBydjtcbiAgICAgfSxcblxuICAgIHN1cHBvcnRWaWRlb1RleHR1cmU6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgLy9pZSAxMSBhbmQgZWRnZSAxMiBkb2Vzbid0IHN1cHBvcnQgdmlkZW8gdGV4dHVyZS5cbiAgICAgICAgdmFyIHZlcnNpb24gPSB0aGlzLkNoZWNrX1ZlcnNpb24oKTtcbiAgICAgICAgcmV0dXJuICh2ZXJzaW9uID09PSAtMSB8fCB2ZXJzaW9uID49IDEzKTtcbiAgICB9LFxuXG4gICAgaXNMaXZlU3RyZWFtT25TYWZhcmk6IGZ1bmN0aW9uICh2aWRlb0VsZW1lbnQpIHtcbiAgICAgICAgLy9saXZlIHN0cmVhbSBvbiBzYWZhcmkgZG9lc24ndCBzdXBwb3J0IHZpZGVvIHRleHR1cmVcbiAgICAgICAgdmFyIHZpZGVvU291cmNlcyA9IHZpZGVvRWxlbWVudC5xdWVyeVNlbGVjdG9yQWxsKFwic291cmNlXCIpO1xuICAgICAgICB2YXIgcmVzdWx0ID0gZmFsc2U7XG4gICAgICAgIGZvcih2YXIgaSA9IDA7IGkgPCB2aWRlb1NvdXJjZXMubGVuZ3RoOyBpKyspe1xuICAgICAgICAgICAgdmFyIGN1cnJlbnRWaWRlb1NvdXJjZSA9IHZpZGVvU291cmNlc1tpXTtcbiAgICAgICAgICAgIGlmKGN1cnJlbnRWaWRlb1NvdXJjZS50eXBlID09IFwiYXBwbGljYXRpb24veC1tcGVnVVJMXCIgJiYgL1NhZmFyaS8udGVzdChuYXZpZ2F0b3IudXNlckFnZW50KSAmJiAvQXBwbGUgQ29tcHV0ZXIvLnRlc3QobmF2aWdhdG9yLnZlbmRvcikpe1xuICAgICAgICAgICAgICAgIHJlc3VsdCA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH0sXG5cbiAgICBnZXRXZWJHTEVycm9yTWVzc2FnZTogZnVuY3Rpb24gKCkge1xuXG4gICAgICAgIHZhciBlbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCggJ2RpdicgKTtcbiAgICAgICAgZWxlbWVudC5pZCA9ICd3ZWJnbC1lcnJvci1tZXNzYWdlJztcblxuICAgICAgICBpZiAoICEgdGhpcy53ZWJnbCApIHtcblxuICAgICAgICAgICAgZWxlbWVudC5pbm5lckhUTUwgPSB3aW5kb3cuV2ViR0xSZW5kZXJpbmdDb250ZXh0ID8gW1xuICAgICAgICAgICAgICAgICdZb3VyIGdyYXBoaWNzIGNhcmQgZG9lcyBub3Qgc2VlbSB0byBzdXBwb3J0IDxhIGhyZWY9XCJodHRwOi8va2hyb25vcy5vcmcvd2ViZ2wvd2lraS9HZXR0aW5nX2FfV2ViR0xfSW1wbGVtZW50YXRpb25cIiBzdHlsZT1cImNvbG9yOiMwMDBcIj5XZWJHTDwvYT4uPGJyIC8+JyxcbiAgICAgICAgICAgICAgICAnRmluZCBvdXQgaG93IHRvIGdldCBpdCA8YSBocmVmPVwiaHR0cDovL2dldC53ZWJnbC5vcmcvXCIgc3R5bGU9XCJjb2xvcjojMDAwXCI+aGVyZTwvYT4uJ1xuICAgICAgICAgICAgXS5qb2luKCAnXFxuJyApIDogW1xuICAgICAgICAgICAgICAgICdZb3VyIGJyb3dzZXIgZG9lcyBub3Qgc2VlbSB0byBzdXBwb3J0IDxhIGhyZWY9XCJodHRwOi8va2hyb25vcy5vcmcvd2ViZ2wvd2lraS9HZXR0aW5nX2FfV2ViR0xfSW1wbGVtZW50YXRpb25cIiBzdHlsZT1cImNvbG9yOiMwMDBcIj5XZWJHTDwvYT4uPGJyLz4nLFxuICAgICAgICAgICAgICAgICdGaW5kIG91dCBob3cgdG8gZ2V0IGl0IDxhIGhyZWY9XCJodHRwOi8vZ2V0LndlYmdsLm9yZy9cIiBzdHlsZT1cImNvbG9yOiMwMDBcIj5oZXJlPC9hPi4nXG4gICAgICAgICAgICBdLmpvaW4oICdcXG4nICk7XG5cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBlbGVtZW50O1xuXG4gICAgfSxcblxuICAgIGFkZEdldFdlYkdMTWVzc2FnZTogZnVuY3Rpb24gKCBwYXJhbWV0ZXJzICkge1xuXG4gICAgICAgIHZhciBwYXJlbnQsIGlkLCBlbGVtZW50O1xuXG4gICAgICAgIHBhcmFtZXRlcnMgPSBwYXJhbWV0ZXJzIHx8IHt9O1xuXG4gICAgICAgIHBhcmVudCA9IHBhcmFtZXRlcnMucGFyZW50ICE9PSB1bmRlZmluZWQgPyBwYXJhbWV0ZXJzLnBhcmVudCA6IGRvY3VtZW50LmJvZHk7XG4gICAgICAgIGlkID0gcGFyYW1ldGVycy5pZCAhPT0gdW5kZWZpbmVkID8gcGFyYW1ldGVycy5pZCA6ICdvbGRpZSc7XG5cbiAgICAgICAgZWxlbWVudCA9IERldGVjdG9yLmdldFdlYkdMRXJyb3JNZXNzYWdlKCk7XG4gICAgICAgIGVsZW1lbnQuaWQgPSBpZDtcblxuICAgICAgICBwYXJlbnQuYXBwZW5kQ2hpbGQoIGVsZW1lbnQgKTtcblxuICAgIH1cblxufTtcblxuZXhwb3J0IGRlZmF1bHQgRGV0ZWN0b3I7IiwiLyoqXG4gKiBDcmVhdGVkIGJ5IHdlbnNoZW5nLnlhbiBvbiA1LzIzLzE2LlxuICovXG52YXIgZWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2NhbnZhcycpO1xuZWxlbWVudC5jbGFzc05hbWUgPSBcInZqcy12aWRlby1oZWxwZXItY2FudmFzXCI7XG5cbnZhciBIZWxwZXJDYW52YXMgPSBmdW5jdGlvbihiYXNlQ29tcG9uZW50KXtcbiAgICByZXR1cm4ge1xuICAgICAgICBjb25zdHJ1Y3RvcjogZnVuY3Rpb24gaW5pdChwbGF5ZXIsIG9wdGlvbnMpe1xuICAgICAgICAgICAgdGhpcy52aWRlb0VsZW1lbnQgPSBvcHRpb25zLnZpZGVvO1xuICAgICAgICAgICAgdGhpcy53aWR0aCA9IG9wdGlvbnMud2lkdGg7XG4gICAgICAgICAgICB0aGlzLmhlaWdodCA9IG9wdGlvbnMuaGVpZ2h0O1xuXG4gICAgICAgICAgICBlbGVtZW50LndpZHRoID0gdGhpcy53aWR0aDtcbiAgICAgICAgICAgIGVsZW1lbnQuaGVpZ2h0ID0gdGhpcy5oZWlnaHQ7XG4gICAgICAgICAgICBlbGVtZW50LnN0eWxlLmRpc3BsYXkgPSBcIm5vbmVcIjtcbiAgICAgICAgICAgIG9wdGlvbnMuZWwgPSBlbGVtZW50O1xuXG5cbiAgICAgICAgICAgIHRoaXMuY29udGV4dCA9IGVsZW1lbnQuZ2V0Q29udGV4dCgnMmQnKTtcbiAgICAgICAgICAgI
1598HRoaXMuY29udGV4dC5kcmF3SW1hZ2UodGhpcy52aWRlb0VsZW1lbnQsIDAsIDAsIHRoaXMud2lkdGgsIHRoaXMuaGVpZ2h0KTtcbiAgICAgICAgICAgIGJhc2VDb21wb25lbnQuY2FsbCh0aGlzLCBwbGF5ZXIsIG9wdGlvbnMpO1xuICAgICAgICB9LFxuICAgICAgICBcbiAgICAgICAgZ2V0Q29udGV4dDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgIHJldHVybiB0aGlzLmNvbnRleHQ7ICBcbiAgICAgICAgfSxcbiAgICAgICAgXG4gICAgICAgIHVwZGF0ZTogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgdGhpcy5jb250ZXh0LmRyYXdJbWFnZSh0aGlzLnZpZGVvRWxlbWVudCwgMCwgMCwgdGhpcy53aWR0aCwgdGhpcy5oZWlnaHQpO1xuICAgICAgICB9LFxuXG4gICAgICAgIGVsOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gZWxlbWVudDtcbiAgICAgICAgfVxuICAgIH1cbn07XG5cbmV4cG9ydCBkZWZhdWx0IEhlbHBlckNhbnZhczsiLCIvKipcbiAqIENyZWF0ZWQgYnkgeWFud3NoIG9uIDYvNi8xNi5cbiAqL1xudmFyIE1vYmlsZUJ1ZmZlcmluZyA9IHtcbiAgICBwcmV2X2N1cnJlbnRUaW1lOiAwLFxuICAgIGNvdW50ZXI6IDAsXG4gICAgXG4gICAgaXNCdWZmZXJpbmc6IGZ1bmN0aW9uIChjdXJyZW50VGltZSkge1xuICAgICAgICBpZiAoY3VycmVudFRpbWUgPT0gdGhpcy5wcmV2X2N1cnJlbnRUaW1lKSB0aGlzLmNvdW50ZXIrKztcbiAgICAgICAgZWxzZSB0aGlzLmNvdW50ZXIgPSAwO1xuICAgICAgICB0aGlzLnByZXZfY3VycmVudFRpbWUgPSBjdXJyZW50VGltZTtcbiAgICAgICAgaWYodGhpcy5jb3VudGVyID4gMTApe1xuICAgICAgICAgICAgLy9ub3QgbGV0IGNvdW50ZXIgb3ZlcmZsb3dcbiAgICAgICAgICAgIHRoaXMuY291bnRlciA9IDEwO1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbn07XG5cbmV4cG9ydCBkZWZhdWx0IE1vYmlsZUJ1ZmZlcmluZzsiLCIvKipcbiAqIENyZWF0ZWQgYnkgeWFud3NoIG9uIDQvNC8xNi5cbiAqL1xuXG52YXIgTm90aWNlID0gZnVuY3Rpb24oYmFzZUNvbXBvbmVudCl7XG4gICAgdmFyIGVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICBlbGVtZW50LmNsYXNzTmFtZSA9IFwidmpzLXZpZGVvLW5vdGljZS1sYWJlbFwiO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgICAgY29uc3RydWN0b3I6IGZ1bmN0aW9uIGluaXQocGxheWVyLCBvcHRpb25zKXtcbiAgICAgICAgICAgIGlmKHR5cGVvZiBvcHRpb25zLk5vdGljZU1lc3NhZ2UgPT0gXCJvYmplY3RcIil7XG4gICAgICAgICAgICAgICAgZWxlbWVudCA9IG9wdGlvbnMuTm90aWNlTWVzc2FnZTtcbiAgICAgICAgICAgICAgICBvcHRpb25zLmVsID0gb3B0aW9ucy5Ob3RpY2VNZXNzYWdlO1xuICAgICAgICAgICAgfWVsc2UgaWYodHlwZW9mIG9wdGlvbnMuTm90aWNlTWVzc2FnZSA9PSBcInN0cmluZ1wiKXtcbiAgICAgICAgICAgICAgICBlbGVtZW50LmlubmVySFRNTCA9IG9wdGlvbnMuTm90aWNlTWVzc2FnZTtcbiAgICAgICAgICAgICAgICBvcHRpb25zLmVsID0gZWxlbWVudDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgYmFzZUNvbXBvbmVudC5jYWxsKHRoaXMsIHBsYXllciwgb3B0aW9ucyk7XG4gICAgICAgIH0sXG5cbiAgICAgICAgZWw6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHJldHVybiBlbGVtZW50O1xuICAgICAgICB9XG4gICAgfVxufTtcblxuZXhwb3J0IGRlZmF1bHQgTm90aWNlOyIsIi8qKlxuICpcbiAqIChjKSBXZW5zaGVuZyBZYW4gPHlhbndzaEBnbWFpbC5jb20+XG4gKiBEYXRlOiAxMC8yMS8xNlxuICpcbiAqIEZvciB0aGUgZnVsbCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5mb3JtYXRpb24sIHBsZWFzZSB2aWV3IHRoZSBMSUNFTlNFXG4gKiBmaWxlIHRoYXQgd2FzIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyBzb3VyY2UgY29kZS5cbiAqL1xuJ3VzZSBzdHJpY3QnO1xuXG5pbXBvcnQgQmFzZUNhbnZhcyBmcm9tICcuL0Jhc2VDYW52YXMnO1xuaW1wb3J0IFV0aWwgZnJvbSAnLi9VdGlsJztcblxudmFyIFRocmVlRENhbnZhcyA9IGZ1bmN0aW9uIChiYXNlQ29tcG9uZW50LCBUSFJFRSwgc2V0dGluZ3MgPSB7fSl7XG4gICAgdmFyIHBhcmVudCA9IEJhc2VDYW52YXMoYmFzZUNvbXBvbmVudCwgVEhSRUUsIHNldHRpbmdzKTtcbiAgICByZXR1cm4gVXRpbC5leHRlbmQocGFyZW50LCB7XG4gICAgICAgIGNvbnN0cnVjdG9yOiBmdW5jdGlvbiBpbml0KHBsYXllciwgb3B0aW9ucyl7XG4gICAgICAgICAgICBwYXJlbnQuY29uc3RydWN0b3IuY2FsbCh0aGlzLCBwbGF5ZXIsIG9wdGlvbnMpO1xuXG4gICAgICAgICAgICAvL2RlZmluZSBzY2VuZVxuICAgICAgICAgICAgdGhpcy5zY2VuZSA9IG5ldyBUSFJFRS5TY2VuZSgpO1xuICAgICAgICAgICAgdmFyIGFzcGVjdFJhdGlvID0gdGhpcy53aWR0aCAvIHRoaXMuaGVpZ2h0IC8gMjtcbiAgICAgICAgICAgIC8vZGVmaW5lIGNhbWVyYVxuICAgICAgICAgICAgdGhpcy5jYW1lcmFMID0gbmV3IFRIUkVFLlBlcnNwZWN0aXZlQ2FtZXJhKG9wdGlvbnMuaW5pdEZvdiwgYXNwZWN0UmF0aW8sIDEsIDIwMDApO1xuICAgICAgICAgICAgdGhpcy5jYW1lcmFMLnRhcmdldCA9IG5ldyBUSFJFRS5WZWN0b3IzKCAwLCAwLCAwICk7XG5cbiAgICAgICAgICAgIHRoaXMuY2FtZXJhUiA9IG5ldyBUSFJFRS5QZXJzcGVjdGl2ZUNhbWVyYShvcHRpb25zLmluaXRGb3YsIGFzcGVjdFJhdGlvLCAxLCAyMDAwKTtcbiAgICAgICAgICAgIHRoaXMuY2FtZXJhUi5wb3NpdGlvbi5zZXQoIDEwMDAsIDAsIDAgKTtcbiAgICAgICAgICAgIHRoaXMuY2FtZXJhUi50YXJnZXQgPSBuZXcgVEhSRUUuVmVjdG9yMyggMTAwMCwgMCwgMCApO1xuXG4gICAgICAgICAgICB2Y
1598XIgZ2VvbWV0cnlMID0gbmV3IFRIUkVFLlNwaGVyZUJ1ZmZlckdlb21ldHJ5KDUwMCwgNjAsIDQwKS50b05vbkluZGV4ZWQoKTtcbiAgICAgICAgICAgIHZhciBnZW9tZXRyeVIgPSBuZXcgVEhSRUUuU3BoZXJlQnVmZmVyR2VvbWV0cnkoNTAwLCA2MCwgNDApLnRvTm9uSW5kZXhlZCgpO1xuXG4gICAgICAgICAgICB2YXIgdXZzTCA9IGdlb21ldHJ5TC5hdHRyaWJ1dGVzLnV2LmFycmF5O1xuICAgICAgICAgICAgdmFyIG5vcm1hbHNMID0gZ2VvbWV0cnlMLmF0dHJpYnV0ZXMubm9ybWFsLmFycmF5O1xuICAgICAgICAgICAgZm9yICggdmFyIGkgPSAwOyBpIDwgbm9ybWFsc0wubGVuZ3RoIC8gMzsgaSArKyApIHtcbiAgICAgICAgICAgICAgICB1dnNMWyBpICogMiArIDEgXSA9IHV2c0xbIGkgKiAyICsgMSBdIC8gMjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdmFyIHV2c1IgPSBnZW9tZXRyeVIuYXR0cmlidXRlcy51di5hcnJheTtcbiAgICAgICAgICAgIHZhciBub3JtYWxzUiA9IGdlb21ldHJ5Ui5hdHRyaWJ1dGVzLm5vcm1hbC5hcnJheTtcbiAgICAgICAgICAgIGZvciAoIHZhciBpID0gMDsgaSA8IG5vcm1hbHNSLmxlbmd0aCAvIDM7IGkgKysgKSB7XG4gICAgICAgICAgICAgICAgdXZzUlsgaSAqIDIgKyAxIF0gPSB1dnNSWyBpICogMiArIDEgXSAvIDIgKyAwLjU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGdlb21ldHJ5TC5zY2FsZSggLSAxLCAxLCAxICk7XG4gICAgICAgICAgICBnZW9tZXRyeVIuc2NhbGUoIC0gMSwgMSwgMSApO1xuXG4gICAgICAgICAgICB0aGlzLm1lc2hMID0gbmV3IFRIUkVFLk1lc2goZ2VvbWV0cnlMLFxuICAgICAgICAgICAgICAgIG5ldyBUSFJFRS5NZXNoQmFzaWNNYXRlcmlhbCh7IG1hcDogdGhpcy50ZXh0dXJlfSlcbiAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgIHRoaXMubWVzaFIgPSBuZXcgVEhSRUUuTWVzaChnZW9tZXRyeVIsXG4gICAgICAgICAgICAgICAgbmV3IFRIUkVFLk1lc2hCYXNpY01hdGVyaWFsKHsgbWFwOiB0aGlzLnRleHR1cmV9KVxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIHRoaXMubWVzaFIucG9zaXRpb24uc2V0KDEwMDAsIDAsIDApO1xuXG4gICAgICAgICAgICB0aGlzLnNjZW5lLmFkZCh0aGlzLm1lc2hMKTtcbiAgICAgICAgICAgIHRoaXMuc2NlbmUuYWRkKHRoaXMubWVzaFIpO1xuXG4gICAgICAgICAgICBpZihvcHRpb25zLmNhbGxiYWNrKSBvcHRpb25zLmNhbGxiYWNrKCk7XG4gICAgICAgIH0sXG5cbiAgICAgICAgaGFuZGxlUmVzaXplOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBwYXJlbnQuaGFuZGxlUmVzaXplLmNhbGwodGhpcyk7XG4gICAgICAgICAgICB2Y
1598XIgYXNwZWN0UmF0aW8gPSB0aGlzLndpZHRoIC8gdGhpcy5oZWlnaHQgLyAyO1xuICAgICAgICAgICAgdGhpcy5jYW1lcmFMLmFzcGVjdCA9IGFzcGVjdFJhdGlvO1xuICAgICAgICAgICAgdGhpcy5jYW1lcmFSLmFzcGVjdCA9IGFzcGVjdFJhdGlvO1xuICAgICAgICAgICAgdGhpcy5jYW1lcmFMLnVwZGF0ZVByb2plY3Rpb25NYXRyaXgoKTtcbiAgICAgICAgICAgIHRoaXMuY2FtZXJhUi51cGRhdGVQcm9qZWN0aW9uTWF0cml4KCk7XG4gICAgICAgIH0sXG5cbiAgICAgICAgaGFuZGxlTW91c2VXaGVlbDogZnVuY3Rpb24oZXZlbnQpe1xuICAgICAgICAgICAgcGFyZW50LmhhbmRsZU1vdXNlV2hlZWwoZXZlbnQpO1xuICAgICAgICAgICAgLy8gV2ViS2l0XG4gICAgICAgICAgICBpZiAoIGV2ZW50LndoZWVsRGVsdGFZICkge1xuICAgICAgICAgICAgICAgIHRoaXMuY2FtZXJhTC5mb3YgLT0gZXZlbnQud2hlZWxEZWx0YVkgKiAwLjA1O1xuICAgICAgICAgICAgICAgIC8vIE9wZXJhIC8gRXhwbG9yZXIgOVxuICAgICAgICAgICAgfSBlbHNlIGlmICggZXZlbnQud2hlZWxEZWx0YSApIHtcbiAgICAgICAgICAgICAgICB0aGlzLmNhbWVyYUwuZm92IC09IGV2ZW50LndoZWVsRGVsdGEgKiAwLjA1O1xuICAgICAgICAgICAgICAgIC8vIEZpcmVmb3hcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoIGV2ZW50LmRldGFpbCApIHtcbiAgICAgICAgICAgICAgICB0aGlzLmNhbWVyYUwuZm92ICs9IGV2ZW50LmRldGFpbCAqIDEuMDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuY2FtZXJhTC5mb3YgPSBNYXRoLm1pbih0aGlzLnNldHRpbmdzLm1heEZvdiwgdGhpcy5jYW1lcmFMLmZvdik7XG4gICAgICAgICAgICB0aGlzLmNhbWVyYUwuZm92ID0gTWF0aC5tYXgodGhpcy5zZXR0aW5ncy5taW5Gb3YsIHRoaXMuY2FtZXJhTC5mb3YpO1xuICAgICAgICAgICAgdGhpcy5jYW1lcmFSLmZvdiA9IHRoaXMuY2FtZXJhTC5mb3Y7XG4gICAgICAgICAgICB0aGlzLmNhbWVyYUwudXBkYXRlUHJvamVjdGlvbk1hdHJpeCgpO1xuICAgICAgICAgICAgdGhpcy5jYW1lcmFSLnVwZGF0ZVByb2plY3Rpb25NYXRyaXgoKTtcbiAgICAgICAgfSxcblxuICAgICAgICByZW5kZXI6IGZ1bmN0aW9uKCl7XG4gICAgICAgICAgICBwYXJlbnQucmVuZGVyLmNhbGwodGhpcyk7XG4gICAgICAgICAgICB2Y
1598XIgdmlld1BvcnRXaWR0aCA9IHRoaXMud2lkdGggLyAyLCB2aWV3UG9ydEhlaWdodCA9IHRoaXMuaGVpZ2h0O1xuICAgICAgICAgICAgdGhpcy5jYW1lcmFMLnRhcmdldC54ID0gNTAwICogTWF0aC5zaW4oIHRoaXMucGhpICkgKiBNYXRoLmNvcyggdGhpcy50aGV0YSApO1xuICAgICAgICAgICAgdGhpcy5jYW1lcmFMLnRhcmdldC55ID0gNTAwICogTWF0aC5jb3MoIHRoaXMucGhpICk7XG4gICAgICAgICAgICB0aGlzLmNhbWVyYUwudGFyZ2V0LnogPSA1MDAgKiBNYXRoLnNpbiggdGhpcy5waGkgKSAqIE1hdGguc2luKCB0aGlzLnRoZXRhICk7XG4gICAgICAgICAgICB0aGlzLmNhbWVyYUwubG9va0F0KHRoaXMuY2FtZXJhTC50YXJnZXQpO1xuXG4gICAgICAgICAgICB0aGlzLmNhbWVyYVIudGFyZ2V0LnggPSAxMDAwICsgNTAwICogTWF0aC5zaW4oIHRoaXMucGhpICkgKiBNYXRoLmNvcyggdGhpcy50aGV0YSApO1xuICAgICAgICAgICAgdGhpcy5jYW1lcmFSLnRhcmdldC55ID0gNTAwICogTWF0aC5jb3MoIHRoaXMucGhpICk7XG4gICAgICAgICAgICB0aGlzLmNhbWVyYVIudGFyZ2V0LnogPSA1MDAgKiBNYXRoLnNpbiggdGhpcy5waGkgKSAqIE1hdGguc2luKCB0aGlzLnRoZXRhICk7XG4gICAgICAgICAgICB0aGlzLmNhbWVyYVIubG9va0F0KCB0aGlzLmNhbWVyYVIudGFyZ2V0ICk7XG5cbiAgICAgICAgICAgIC8vIHJlbmRlciBsZWZ0IGV5ZVxuICAgICAgICAgICAgdGhpcy5yZW5kZXJlci5zZXRWaWV3cG9ydCggMCwgMCwgdmlld1BvcnRXaWR0aCwgdmlld1BvcnRIZWlnaHQgKTtcbiAgICAgICAgICAgIHRoaXMucmVuZGVyZXIuc2V0U2Npc3NvciggMCwgMCwgdmlld1BvcnRXaWR0aCwgdmlld1BvcnRIZWlnaHQgKTtcbiAgICAgICAgICAgIHRoaXMucmVuZGVyZXIucmVuZGVyKCB0aGlzLnNjZW5lLCB0aGlzLmNhbWVyYUwgKTtcblxuICAgICAgICAgICAgLy8gcmVuZGVyIHJpZ2h0IGV5ZVxuICAgICAgICAgICAgdGhpcy5yZW5kZXJlci5zZXRWaWV3cG9ydCggdmlld1BvcnRXaWR0aCwgMCwgdmlld1BvcnRXaWR0aCwgdmlld1BvcnRIZWlnaHQgKTtcbiAgICAgICAgICAgIHRoaXMucmVuZGVyZXIuc2V0U2Npc3Nvciggdmlld1BvcnRXaWR0aCwgMCwgdmlld1BvcnRXaWR0aCwgdmlld1BvcnRIZWlnaHQgKTtcbiAgICAgICAgICAgIHRoaXMucmVuZGVyZXIucmVuZGVyKCB0aGlzLnNjZW5lLCB0aGlzLmNhbWVyYVIgKTtcbiAgICAgICAgfVxuICAgIH0pO1xufTtcblxuZXhwb3J0IGRlZmF1bHQgVGhyZWVEQ2FudmFzOyIsIi8qKlxuICogQ3JlYXRlZCBieSB3ZW5zaGVuZy55YW4gb24gNC80LzE2LlxuICovXG5mdW5jdGlvbiB3aGljaFRyYW5zaXRpb25FdmVudCgpe1xuICAgIHZhciB0O1xuICAgIHZhciBlbCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2Zha2VlbGVtZW50Jyk7XG4gICAgdmFyIHRyYW5zaXRpb25zID0ge1xuICAgICAgICAndHJhbnNpdGlvbic6J3RyYW5zaXRpb25lbmQnLFxuICAgICAgICAnT1RyYW5zaXRpb24nOidvVHJhbnNpdGlvbkVuZCcsXG4gICAgICAgICdNb3pUcmFuc2l0aW9uJzondHJhbnNpdGlvbmVuZCcsXG4gICAgICAgICdXZWJraXRUcmFuc2l0aW9uJzond2Via2l0VHJhbnNpdGlvbkVuZCdcbiAgICB9O1xuXG4gICAgZm9yKHQgaW4gdHJhbnNpdGlvbnMpe1xuICAgICAgICBpZiggZWwuc3R5bGVbdF0gIT09IHVuZGVmaW5lZCApe1xuICAgICAgICAgICAgcmV0dXJuIHRyYW5zaXRpb25zW3RdO1xuICAgICAgICB9XG4gICAgfVxufVxuXG5mdW5jdGlvbiBtb2JpbGVBbmRUYWJsZXRjaGVjaygpIHtcbiAgICB2YXIgY2hlY2sgPSBmYWxzZTtcbiAgICAoZnVuY3Rpb24oYSl7aWYoLyhhbmRyb2lkfGJiXFxkK3xtZWVnbykuK21vYmlsZXxhdmFudGdvfGJhZGFcXC98YmxhY2tiZXJyeXxibGF6ZXJ8Y29tcGFsfGVsYWluZXxmZW5uZWN8aGlwdG9wfGllbW9iaWxlfGlwKGhvbmV8b2QpfGlyaXN8a2luZGxlfGxnZSB8bWFlbW98bWlkcHxtbXB8bW9iaWxlLitmaXJlZm94fG5ldGZyb250fG9wZXJhIG0ob2J8aW4paXxwYWxtKCBvcyk/fHBob25lfHAoaXhpfHJlKVxcL3xwbHVja2VyfHBvY2tldHxwc3B8c2VyaWVzKDR8NikwfHN5bWJpYW58dHJlb3x1cFxcLihicm93c2VyfGxpbmspfHZvZGFmb25lfHdhcHx3aW5kb3dzIGNlfHhkYXx4aWlub3xhbmRyb2lkfGlwYWR8cGxheWJvb2t8c2lsay9pLnRlc3QoYSl8fC8xMjA3fDYzMTB8NjU5MHwzZ3NvfDR0aHB8NTBbMS02XWl8Nzcwc3w4MDJzfGEgd2F8YWJhY3xhYyhlcnxvb3xzXFwtKXxhaShrb3xybil8YWwoYXZ8Y2F8Y28pfGFtb2l8YW4oZXh8bnl8eXcpfGFwdHV8YXIoY2h8Z28pfGFzKHRlfHVzKXxhdHR3fGF1KGRpfFxcLW18ciB8cyApfGF2YW58YmUoY2t8bGx8bnEpfGJpKGxifHJkKXxibChhY3xheil8YnIoZXx2KXd8YnVtYnxid1xcLShufHUpfGM1NVxcL3xjYXBpfGNjd2F8Y2RtXFwtfGNlbGx8Y2h0bXxjbGRjfGNtZFxcLXxjbyhtcHxuZCl8Y3Jhd3xkYShpdHxsbHxuZyl8ZGJ0ZXxkY1xcLXN8ZGV2aXxkaWNhfGRtb2J8ZG8oY3xwKW98ZHMoMTJ8XFwtZCl8ZWwoNDl8YWkpfGVtKGwyfHVsKXxlcihpY3xrMCl8ZXNsOHxleihbNC03XTB8b3N8d2F8emUpfGZldGN8Zmx5KFxcLXxfKXxnMSB1fGc1NjB8Z2VuZXxnZlxcLTV8Z1xcLW1vfGdvKFxcLnd8b2QpfGdyKGFkfHVuKXxoYWllfGhjaXR8aGRcXC0obXxwfHQpfGhlaVxcLXxoaShwdHx0YSl8aHAoIGl8aXApfGhzXFwtY3xodChjKFxcLXwgfF98YXxnfHB8c3x0KXx0cCl8aHUoYXd8dGMpfGlcXC0oMjB8Z298bWEpfGkyMzB8aWFjKCB8XFwtfFxcLyl8aWJyb3xpZGVhfGlnMDF8aWtvbXxpbTFrfGlubm98aXBhcXxpcmlzfGphKHR8dilhfGpicm98amVtdXxqaWdzfGtkZGl8a2VqaXxrZ3QoIHxcXC8pfGtsb258a3B0IHxrd2NcXC18a3lvKGN8ayl8bGUobm98eGkpfGxnKCBnfFxcLyhrfGx8dSl8NTB8NTR8XFwtW2Etd10pfGxpYnd8bHlueHxtMVxcLXd8bTNnYXxtNTBcXC98bWEodGV8dWl8eG8pfG1jKDAxfDIxfGNhKXxtXFwtY3J8bWUocmN8cmkpfG1pKG84fG9hfHRzKXxtbWVmfG1vKDAxfDAyfGJpfGRlfGRvfHQoXFwtfCB8b3x2KXx6eil8bXQoNTB8cDF8diApfG13YnB8bXl3YXxuMTBbMC0yXXxuMjBbMi0zXXxuMzAoMHwyKXxuNTAoMHwyfDUpfG43KDAoMHwxKXwxMCl8bmUoKGN8bSlcXC18b258dGZ8d2Z8d2d8d3QpfG5vayg2fGkpfG56cGh8bzJpbXxvcCh0aXx3dil8b3Jhbnxvd2cxfHA4MDB8cGFuKGF8ZHx0KXxwZHhnfHBnKDEzfFxcLShbMS04XXxjKSl8cGhpbHxwaXJlfHBsKGF5fHVjKXxwblxcLTJ8cG8oY2t8cnR8c2UpfHByb3h8cHNpb3xwdFxcLWd8cWFcXC1hfHFjKDA3fDEyfDIxfDMyfDYwfFxcLVsyLTddfGlcXC0pfHF0ZWt8cjM4MHxyNjAwfHJha3N8cmltOXxybyh2ZXx6byl8czU1XFwvfHNhKGdlfG1hfG1tfG1zfG55fHZhKXxzYygwMXxoXFwtfG9vfHBcXC0pfHNka1xcL3xzZShjKFxcLXwwfDEpfDQ3fG1jfG5kfHJpKXxzZ2hcXC18c2hhcnxzaWUoXFwtfG0pfHNrXFwtMHxzbCg0NXxpZCl8c20oYWx8YXJ8YjN8aXR8dDUpfHNvKGZ0fG55KXxzcCgwMXxoXFwtfHZcXC18diApfHN5KDAxfG1iKXx0MigxOHw1MCl8dDYoMDB8MTB8MTgpfHRhKGd0fGxrKXx0Y2xcXC18dGRnXFwtfHRlbChpfG0pfHRpbVxcLXx0XFwtbW98dG8ocGx8c2gpfHRzKDcwfG1cXC18bTN8bTUpfHR4XFwtOXx1cChcXC5ifGcxfHNpKXx1dHN0fHY0MDB8djc1MHx2ZXJpfHZpKHJnfHRlKXx2ayg0MHw1WzAtM118XFwtdil8dm00MHx2b2RhfHZ1bGN8dngoNTJ8NTN8NjB8NjF8NzB8ODB8ODF8ODN8ODV8OTgpfHczYyhcXC18ICl8d2ViY3x3aGl0fHdpKGcgfG5jfG53KXx3bWxifHdvbnV8eDcwMHx5YXNcXC18eW91cnx6ZXRvfHp0ZVxcLS9pLnRlc3QoYS5zdWJzdHIoMCw0KSkpY2hlY2sgPSB0cnVlfSkobmF2aWdhdG9yLnVzZXJBZ2VudHx8bmF2aWdhdG9yLnZlbmRvcnx8d2luZG93Lm9wZXJhKTtcbiAgICByZXR1cm4gY2hlY2s7XG59XG5cbmZ1bmN0aW9uIGlzSW9zKCkge1xuICAgIHJldHVybiAvaVBob25lfGlQYWR8aVBvZC9pLnRlc3QobmF2aWdhdG9yLnVzZXJBZ2VudCk7XG59XG5cbmZ1bmN0aW9uIGlzUmVhbElwaG9uZSgpIHtcbiAgICByZXR1cm4gL2lQaG9uZXxpUG9kL2kudGVzdChuYXZpZ2F0b3IucGxhdGZvcm0pO1xufVxuXG4vL2Fkb3B0IGNvZGUgZnJvbTogaHR0cHM6Ly9naXRodWIuY29tL01velZSL3ZyLXdlYi1leGFtcGxlcy9ibG9iL21hc3Rlci90aHJlZWpzLXZyLWJvaWxlcnBsYXRlL2pzL1ZSRWZmZWN0LmpzXG5mdW5jdGlvbiBmb3ZUb05EQ1NjYWxlT2Zmc2V0KCBmb3YgKSB7XG4gICAgdmFyIHB4c2NhbGUgPSAyLjAgLyAoZm92LmxlZnRUYW4gKyBmb3YucmlnaHRUYW4pO1xuICAgIHZhciBweG9mZnNldCA9IChmb3YubGVmdFRhbiAtIGZvdi5yaWdodFRhbikgKiBweHNjYWxlICogMC41O1xuICAgIHZhciBweXNjYWxlID0gMi4wIC8gKGZvdi51cF
1598RhbiArIGZvdi5kb3duVGFuKTtcbiAgICB2YXIgcHlvZmZzZXQgPSAoZm92LnVwVGFuIC0gZm92LmRvd25UYW4pICogcHlzY2FsZSAqIDAuNTtcbiAgICByZXR1cm4geyBzY2FsZTogWyBweHNjYWxlLCBweXNjYWxlIF0sIG9mZnNldDogWyBweG9mZnNldCwgcHlvZmZzZXQgXSB9O1xufVxuXG5mdW5jdGlvbiBmb3ZQb3J0VG9Qcm9qZWN0aW9uKCBmb3YsIHJpZ2h0SGFuZGVkLCB6TmVhciwgekZhciApIHtcblxuICAgIHJpZ2h0SGFuZGVkID0gcmlnaHRIYW5kZWQgPT09IHVuZGVmaW5lZCA/IHRydWUgOiByaWdodEhhbmRlZDtcbiAgICB6TmVhciA9IHpOZWFyID09PSB1bmRlZmluZWQgPyAwLjAxIDogek5lYXI7XG4gICAgekZhciA9IHpGYXIgPT09IHVuZGVmaW5lZCA/IDEwMDAwLjAgOiB6RmFyO1xuXG4gICAgdmFyIGhhbmRlZG5lc3NTY2FsZSA9IHJpZ2h0SGFuZGVkID8gLTEuMCA6IDEuMDtcblxuICAgIC8vIHN0YXJ0IHdpdGggYW4gaWRlbnRpdHkgbWF0cml4XG4gICAgdmFyIG1vYmogPSBuZXcgVEhSRUUuTWF0cml4NCgpO1xuICAgIHZhciBtID0gbW9iai5lbGVtZW50cztcblxuICAgIC8vIGFuZCB3aXRoIHNjYWxlL29mZnNldCBpbmZvIGZvciBub3JtYWxpemVkIGRldmljZSBjb29yZHNcbiAgICB2YXIgc2NhbGVBbmRPZmZzZXQgPSBmb3ZUb05EQ1NjYWxlT2Zmc2V0KGZvdik7XG5cbiAgICAvLyBYIHJlc3VsdCwgbWFwIGNsaXAgZWRnZXMgdG8gWy13LCt3XVxuICAgIG1bMCAqIDQgKyAwXSA9IHNjYWxlQW5kT2Zmc2V0LnNjYWxlWzBdO1xuICAgIG1bMCAqIDQgKyAxXSA9IDAuMDtcbiAgICBtWzAgKiA0ICsgMl0gPSBzY2FsZUFuZE9mZnNldC5vZmZzZXRbMF0gKiBoYW5kZWRuZXNzU2NhbGU7XG4gICAgbVswICogNCArIDNdID0gMC4wO1xuXG4gICAgLy8gWSByZXN1bHQsIG1hcCBjbGlwIGVkZ2VzIHRvIFstdywrd11cbiAgICAvLyBZIG9mZnNldCBpcyBuZWdhdGVkIGJlY2F1c2UgdGhpcyBwcm9qIG1hdHJpeCB0cmFuc2Zvcm1zIGZyb20gd29ybGQgY29vcmRzIHdpdGggWT11cCxcbiAgICAvLyBidXQgdGhlIE5EQyBzY2FsaW5nIGhhcyBZPWRvd24gKHRoYW5rcyBEM0Q/KVxuICAgIG1bMSAqIDQgKyAwXSA9IDAuMDtcbiAgICBtWzEgKiA0ICsgMV0gPSBzY2FsZUFuZE9mZnNldC5zY2FsZVsxXTtcbiAgICBtWzEgKiA0ICsgMl0gPSAtc2NhbGVBbmRPZmZzZXQub2Zmc2V0WzFdICogaGFuZGVkbmVzc1NjYWxlO1xuICAgIG1bMSAqIDQgKyAzXSA9IDAuMDtcblxuICAgIC8vIFogcmVzdWx0ICh1cCB0byB0aGUgYXBwKVxuICAgIG1bMiAqIDQgKyAwXSA9IDAuMDtcbiAgICBtWzIgKiA0ICsgMV0gPSAwLjA7XG4gICAgbVsyICogNCArIDJdID0gekZhciAvICh6TmVhciAtIHpGYXIpICogLWhhbmRlZG5lc3NTY2FsZTtcbiAgICBtWzIgKiA0ICsgM10gPSAoekZhciAqIHpOZWFyKSAvICh6TmVhciAtIHpGYXIpO1xuXG4gICAgLy8gVyByZXN1bHQgKD0gWiBpbilcbiAgICBtWzMgKiA0ICsgMF0gPSAwLjA7XG4gICAgbVszICogNCArIDFdID0gMC4wO1xuICAgIG1bMyAqIDQgKyAyXSA9IGhhbmRlZG5lc3NTY2FsZTtcbiAgICBtWzMgKiA0ICsgM10gPSAwLjA7XG5cbiAgICBtb2JqLnRyYW5zcG9zZSgpO1xuXG4gICAgcmV0dXJuIG1vYmo7XG59XG5cbmZ1bmN0aW9uIGZvdlRvUHJvamVjdGlvbiggZm92LCByaWdodEhhbmRlZCwgek5lYXIsIHpGYXIgKSB7XG4gICAgdmFyIERFRzJSQUQgPSBNYXRoLlBJIC8gMTgwLjA7XG5cbiAgICB2YXIgZm92UG9ydCA9IHtcbiAgICAgICAgdXBUYW46IE1hdGgudGFuKCBmb3YudXBEZWdyZWVzICogREVHMlJBRCApLFxuICAgICAgICBkb3duVGFuOiBNYXRoLnRhbiggZm92LmRvd25EZWdyZWVzICogREVHMlJBRCApLFxuICAgICAgICBsZWZ0VGFuOiBNYXRoLnRhbiggZm92LmxlZnREZWdyZWVzICogREVHMlJBRCApLFxuICAgICAgICByaWdodFRhbjogTWF0aC50YW4oIGZvdi5yaWdodERlZ3JlZXMgKiBERUcyUkFEIClcbiAgICB9O1xuXG4gICAgcmV0dXJuIGZvdlBvcnRUb1Byb2plY3Rpb24oIGZvdlBvcnQsIHJpZ2h0SGFuZGVkLCB6TmVhciwgekZhciApO1xufVxuXG5mdW5jdGlvbiBleHRlbmQoc3VwZXJDbGFzcywgc3ViQ2xhc3NNZXRob2RzID0ge30pXG57XG4gICAgZm9yKHZhciBtZXRob2QgaW4gc3VwZXJDbGFzcyl7XG4gICAgICAgIGlmKHN1cGVyQ2xhc3MuaGFzT3duUHJvcGVydHkobWV0aG9kKSAmJiAhc3ViQ2xhc3NNZXRob2RzLmhhc093blByb3BlcnR5KG1ldGhvZCkpe1xuICAgICAgICAgICAgc3ViQ2xhc3NNZXRob2RzW21ldGhvZF0gPSBzdXBlckNsYXNzW21ldGhvZF07XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHN1YkNsYXNzTWV0aG9kcztcbn1cblxuZnVuY3Rpb24gZGVlcENvcHkob2JqKSB7XG4gICAgdmFyIHRvID0ge307XG5cbiAgICBmb3IgKHZhciBuYW1lIGluIG9iailcbiAgICB7XG4gICAgICAgIHRvW25hbWVdID0gb2JqW25hbWVdO1xuICAgIH1cblxuICAgIHJldHVybiB0bztcbn1cblxuZXhwb3J0IGRlZmF1bHQge1xuICAgIHdoaWNoVHJhbnNpdGlvbkV2ZW50OiB3aGljaFRyYW5zaXRpb25FdmVudCxcbiAgICBtb2JpbGVBbmRUYWJsZXRjaGVjazogbW9iaWxlQW5kVGFibGV0Y2hlY2ssXG4gICAgaXNJb3M6IGlzSW9zLFxuICAgIGlzUmVhbElwaG9uZTogaXNSZWFsSXBob25lLFxuICAgIGZvdlRvUHJvamVjdGlvbjogZm92VG9Qcm9qZWN0aW9uLFxuICAgIGV4dGVuZDogZXh0ZW5kLFxuICAgIGRlZXBDb3B5OiBkZWVwQ29weVxufTsiLCIvKipcbiAqIENyZWF0ZWQgYnkgeWFud3NoIG9uIDgvMTMvMTYuXG4gKi9cblxudmFyIFZSQnV0dG9uID0gZnVuY3Rpb24oQnV0dG9uQ29tcG9uZW50KXtcbiAgICByZXR1cm4ge1xuICAgICAgICBjb25zdHJ1Y3RvcjogZnVuY3Rpb24gaW5pdChwbGF5ZXIsIG9wdGlvbnMpe1xuICAgICAgICAgICAgQnV0dG9uQ29tcG9uZW50LmNhbGwodGhpcywgcGxheWVyLCBvcHRpb25zKTtcbiAgICAgICAgfSxcblxuICAgICAgICBidWlsZENTU0NsYXNzOiBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgIHJldHVybiBgdmpzLVZSLWNvbnRyb2wgJHtCdXR0b25Db21wb25lbnQucHJvdG90eXBlLmJ1aWxkQ1NTQ2xhc3MuY2FsbCh0aGlzKX1gO1xuICAgICAgICB9LFxuXG4gICAgICAgIGhhbmRsZUNsaWNrOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICB2Y
1598XIgY2FudmFzID0gdGhpcy5wbGF5ZXIoKS5nZXRDaGlsZChcIkNhbnZhc1wiKTtcbiAgICAgICAgICAgICghY2FudmFzLlZSTW9kZSk/IGNhbnZhcy5lbmFibGVWUigpIDogY2FudmFzLmRpc2FibGVWUigpO1xuICAgICAgICAgICAgKGNhbnZhcy5WUk1vZGUpPyB0aGlzLmFkZENsYXNzKFwiZW5hYmxlXCIpIDogdGhpcy5yZW1vdmVDbGFzcyhcImVuYWJsZVwiKTtcbiAgICAgICAgICAgIChjYW52YXMuVlJNb2RlKT8gIHRoaXMucGxheWVyKCkudHJpZ2dlcignVlJNb2RlT24nKTogIHRoaXMucGxheWVyKCkudHJpZ2dlcignVlJNb2RlT2ZmJyk7XG4gICAgICAgIH0sXG5cbiAgICAgICAgY29udHJvbFRleHRfOiBcIlZSXCJcbiAgICB9XG59O1xuXG5leHBvcnQgZGVmYXVsdCBWUkJ1dHRvbjsiLCIvKipcbiAqIENyZWF0ZWQgYnkgeWFud3NoIG9uIDQvMy8xNi5cbiAqL1xuJ3VzZSBzdHJpY3QnO1xuXG5pbXBvcnQgdXRpbCBmcm9tICcuL2xpYi9VdGlsJztcbmltcG9ydCBEZXRlY3RvciBmcm9tICcuL2xpYi9EZXRlY3Rvcic7XG5pbXBvcnQgbWFrZVZpZGVvUGxheWFibGVJbmxpbmUgZnJvbSAnaXBob25lLWlubGluZS12aWRlbyc7XG5cbmNvbnN0IHJ1bk9uTW9iaWxlID0gKHV0aWwubW9iaWxlQW5kVGFibGV0Y2hlY2soKSk7XG5cbi8vIERlZmF1bHQgb3B0aW9ucyBmb3IgdGhlIHBsdWdpbi5cbmNvbnN0IGRlZmF1bHRzID0ge1xuICAgIGNsaWNrQW5kRHJhZzogcnVuT25Nb2JpbGUsXG4gICAgc2hvd05vdGljZTogdHJ1ZSxcbiAgICBOb3RpY2VNZXNzYWdlOiBcIlBsZWFzZSB1c2UgeW91ciBtb3VzZSBkcmFnIGFuZCBkcm9wIHRoZSB2aWRlby5cIixcbiAgICBhdXRvSGlkZU5vdGljZTogMzAwMCxcbiAgICAvL2xpbWl0IHRoZSB2aWRlbyBzaXplIHdoZW4gdXNlciBzY3JvbGwuXG4gICAgc2Nyb2xsYWJsZTogdHJ1ZSxcbiAgICBpbml0Rm92OiA3NSxcbiAgICBtYXhGb3Y6IDEwNSxcbiAgICBtaW5Gb3Y6IDUxLFxuICAgIC8vaW5pdGlhbCBwb3NpdGlvbiBmb3IgdGhlIHZpZGVvXG4gICAgaW5pdExhdDogMCxcbiAgICBpbml0TG9uOiAtMTgwLFxuICAgIC8vQSBmbG9hdCB2YWx1ZSBiYWNrIHRvIGNlbnRlciB3aGVuIG1vdXNlIG91dCB0aGUgY2FudmFzLiBUaGUgaGlnaGVyLCB0aGUgZmFzdGVyLlxuICAgIHJldHVyblN0ZXBMYXQ6IDAuNSxcbiAgICByZXR1cm5TdGVwTG9uOiAyLFxuICAgIGJhY2tUb1ZlcnRpY2FsQ2VudGVyOiAhcnVuT25Nb2JpbGUsXG4gICAgYmFja1RvSG9yaXpvbkNlbnRlcjogIXJ1bk9uTW9iaWxlLFxuICAgIGNsaWNrVG9Ub2dnbGU6IGZhbHNlLFxuXG4gICAgLy9saW1pdCB2aWV3YWJsZSB6b29tXG4gICAgbWluTGF0OiAtODUsXG4gICAgbWF4TGF0OiA4NSxcblxuICAgIG1pbkxvbjogLUluZmluaXR5LFxuICAgIG1heExvbjogSW5maW5pdHksXG5cbiAgICB2aWRlb1R5cGU6IFwiZXF1aXJlY3Rhbmd1bGFyXCIsXG5cbiAgICByb3RhdGVYOiAwLFxuICAgIHJvdGF0ZVk6IDAsXG4gICAgcm90YXRlWjogMCxcblxuICAgIGF1dG9Nb2JpbGVPcmllbnRhdGlvbjogZmFsc2UsXG4gICAgbW9iaWxlVmlicmF0aW9uVmFsdWU6IHV0aWwuaXNJb3MoKT8gMC4wMjIgOiAxLFxuXG4gICAgVlJFbmFibGU6IHRydWUsXG4gICAgVlJHYXBEZWdyZWU6IDIuNSxcblxuICAgIGNsb3NlUGFub3JhbWE6IGZhbHNlXG5cblxufTtcblxuZnVuY3Rpb24gcGxheWVyUmVzaXplKHBsYXllcil7XG4gICAgdmFyIGNhbnZhcyA9IHBsYXllci5nZXRDaGlsZCgnQ2FudmFzJyk7XG4gICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcGxheWVyLmVsKCkuc3R5bGUud2lkdGggPSB3aW5kb3cuaW5uZXJXaWR0aCArIFwicHhcIjtcbiAgICAgICAgcGxheWVyLmVsKCkuc3R5bGUuaGVpZ2h0ID0gd2luZG93LmlubmVySGVpZ2h0ICsgXCJweFwiO1xuICAgICAgICBjYW52YXMuaGFuZGxlUmVzaXplKCk7XG4gICAgfTtcbn1cblxuZnVuY3Rpb24gZnVsbHNjcmVlbk9uSU9TKHBsYXllciwgY2xpY2tGbikge1xuICAgIHZhciByZXNpemVGbiA9IHBsYXllclJlc2l6ZShwbGF5ZXIpO1xuICAgIHBsYXllci5jb250cm9sQmFyLmZ1bGxzY3JlZW5Ub2dnbGUub2ZmKFwidGFwXCIsIGNsaWNrRm4pO1xuICAgIHBsYXllci5jb250cm9sQmFyLmZ1bGxzY3JlZW5Ub2dnbGUub24oXCJ0YXBcIiwgZnVuY3Rpb24gZnVsbHNjcmVlbigpIHtcbiAgICAgICAgdmFyIGNhbnZhcyA9IHBsYXllci5nZXRDaGlsZCgnQ2FudmFzJyk7XG4gICAgICAgIGlmKCFwbGF5ZXIuaXNGdWxsc2NyZWVuKCkpe1xuICAgICAgICAgICAgLy9zZXQgdG8gZnVsbHNjcmVlblxuICAgICAgICAgICAgcGxheWVyLmlzRnVsbHNjcmVlbih0cnVlKTtcbiAgICAgICAgICAgIHBsYXllci5lbnRlckZ1bGxXaW5kb3coKTtcbiAgICAgICAgICAgIHJlc2l6ZUZuKCk7XG4gICAgICAgICAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihcImRldmljZW1vdGlvblwiLCByZXNpemVGbik7XG4gICAgICAgIH1lbHNle1xuICAgICAgICAgICAgcGxheWVyLmlzRnVsbHNjcmVlbihmYWxzZSk7XG4gICAgICAgICAgICBwbGF5ZXIuZXhpdEZ1bGxXaW5kb3coKTtcbiAgICAgICAgICAgIHBsYXllci5lbCgpLnN0eWxlLndpZHRoID0gXCJcIjtcbiAgICAgICAgICAgIHBsYXllci5lbCgpLnN0eWxlLmhlaWdodCA9IFwiXCI7XG4gICAgICAgICAgICBjYW52YXMuaGFuZGxlUmVzaXplKCk7XG4gICAgICAgICAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcihcImRldmljZW1vdGlvblwiLCByZXNpemVGbik7XG4gICAgICAgIH1cbiAgICB9KTtcbn1cblxuLyoqXG4gKiBGdW5jdGlvbiB0byBpbnZva2Ugd2hlbiB0aGUgcGxheWVyIGlzIHJlYWR5LlxuICpcbiAqIFRoaXMgaXMgYSBncmVhdCBwbGFjZSBmb3IgeW91ciBwbHVnaW4gdG8gaW5pdGlhbGl6ZSBpdHNlbGYuIFdoZW4gdGhpc1xuICogZnVuY3Rpb24gaXMgY2FsbGVkLCB0aGUgcGxheWVyIHdpbGwgaGF2ZSBpdHMgRE9NIGFuZCBjaGlsZCBjb21wb25lbnRzXG4gKiBpbiBwbGFjZS5cbiAqXG4gKiBAZnVuY3Rpb24gb25QbGF5ZXJSZWFkeVxuICogQHBhcmFtICAgIHtQbGF5ZXJ9IHBsYXllclxuICogQHBhcmFtICAgIHtPYmplY3R9IFtvcHRpb25zPXt9XVxuICovXG5jb25zdCBvblBsYXllclJlYWR5ID0gKHBsYXllciwgb3B0aW9ucywgc2V0dGluZ3MpID0+IHtcbiAgICBwbGF5ZXIuYWRkQ2xhc3MoJ3Zqcy1wYW5vcmFtYScpO1xuICAgIGlmKCFEZXRlY3Rvci53ZWJnbCl7XG4gICAgICAgIFBvcHVwTm90aWZpY2F0aW9uKHBsYXllciwge1xuICAgICAgICAgICAgTm90aWNlTWVzc2FnZTogRGV0ZWN0b3IuZ2V0V2ViR0xFcnJvck1lc3NhZ2UoKSxcbiAgICAgICAgICAgIGF1dG9IaWRlTm90aWNlOiBvcHRpb25zLmF1dG9IaWRlTm90aWNlXG4gICAgICAgI
1598H0pO1xuICAgICAgICBpZihvcHRpb25zLmNhbGxiYWNrKXtcbiAgICAgICAgICAgIG9wdGlvbnMuY2FsbGJhY2soKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIHBsYXllci5hZGRDaGlsZCgnQ2FudmFzJywgdXRpbC5kZWVwQ29weShvcHRpb25zKSk7XG4gICAgdmFyIGNhbnZhcyA9IHBsYXllci5nZXRDaGlsZCgnQ2FudmFzJyk7XG4gICAgaWYocnVuT25Nb2JpbGUpe1xuICAgICAgICB2YXIgdmlkZW9FbGVtZW50ID0gc2V0dGluZ3MuZ2V0VGVjaChwbGF5ZXIpO1xuICAgICAgICBpZih1dGlsLmlzUmVhbElwaG9uZSgpKXtcbiAgICAgICAgICAgIC8vaW9zIDEwIHN1cHBvcnQgcGxheSB2aWRlbyBpbmxpbmVcbiAgICAgICAgICAgIHZpZGVvRWxlbWVudC5zZXRBdHRyaWJ1dGUoXCJwbGF5c2lubGluZVwiLCBcIlwiKTtcbiAgICAgICAgICAgIG1ha2VWaWRlb1BsYXlhYmxlSW5saW5lKHZpZGVvRWxlbWVudCwgdHJ1ZSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYodXRpbC5pc0lvcygpKXtcbiAgICAgICAgICAgIGZ1bGxzY3JlZW5PbklPUyhwbGF5ZXIsIHNldHRpbmdzLmdldEZ1bGxzY3JlZW5Ub2dnbGVDbGlja0ZuKHBsYXllcikpO1xuICAgICAgICB9XG4gICAgICAgIHBsYXllci5hZGRDbGFzcyhcInZqcy1wYW5vcmFtYS1tb2JpbGUtaW5saW5lLXZpZGVvXCIpO1xuICAgICAgICBwbGF5ZXIucmVtb3ZlQ2xhc3MoXCJ2anMtdXNpbmctbmF0aXZlLWNvbnRyb2xzXCIpO1xuICAgICAgICBjYW52YXMucGxheU9uTW9iaWxlKCk7XG4gICAgfVxuICAgIGlmKG9wdGlvbnMuc2hvd05vdGljZSl7XG4gICAgICAgIHBsYXllci5vbihcInBsYXlpbmdcIiwgZnVuY3Rpb24oKXtcbiAgICAgICAgICAgIFBvcHVwTm90aWZpY2F0aW9uKHBsYXllciwgdXRpbC5kZWVwQ29weShvcHRpb25zKSk7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBpZihvcHRpb25zLlZSRW5hYmxlICYmIG9wdGlvbnMudmlkZW9UeXBlICE9PSBcIjNkVmlkZW9cIil7XG4gICAgICAgIHBsYXllci5jb250cm9sQmFyLmFkZENoaWxkKCdWUkJ1dHRvbicsIHt9LCBwbGF5ZXIuY29udHJvbEJhci5jaGlsZHJlbigpLmxlbmd0aCAtIDEpO1xuICAgIH1cbiAgICBjYW52YXMuaGlkZSgpO1xuICAgIHBsYXllci5vbihcInBsYXlcIiwgZnVuY3Rpb24gKCkge1xuICAgICAgICBjYW52YXMuc2hvdygpO1xuICAgIH0pO1xuICAgIHBsYXllci5vbihcImZ1bGxzY3JlZW5jaGFuZ2VcIiwgZnVuY3Rpb24gKCkge1xuICAgICAgICBjYW52YXMuaGFuZGxlUmVzaXplKCk7XG4gICAgfSk7XG4gICAgaWYob3B0aW9ucy5jYWxsYmFjaykgb3B0aW9ucy5jYWxsYmFjaygpO1xufTtcblxuY29uc3QgUG9wdXBOb3RpZmljYXRpb24gPSAocGxheWVyLCBvcHRpb25zID0ge1xuICAgIE5vdGljZU1lc3NhZ2U6IFwiXCJcbn0pID0+IHtcbiAgICB2YXIgbm90aWNlID0gcGxheWVyLmFkZENoaWxkKCdOb3RpY2UnLCBvcHRpb25zKTtcblxuICAgIGlmKG9wdGlvbnMuYXV0b0hpZGVOb3RpY2UgPiAwKXtcbiAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBub3RpY2UuYWRkQ2xhc3MoXCJ2anMtdmlkZW8tbm90aWNlLWZhZGVPdXRcIik7XG4gICAgICAgICAgICB2Y
1598XIgdHJhbnNpdGlvbkV2ZW50ID0gdXRpbC53aGljaFRyYW5zaXRpb25FdmVudCgpO1xuICAgICAgICAgICAgdmFyIGhpZGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgbm90aWNlLmhpZGUoKTtcbiAgICAgICAgICAgICAgICBub3RpY2UucmVtb3ZlQ2xhc3MoXCJ2anMtdmlkZW8tbm90aWNlLWZhZGVPdXRcIik7XG4gICAgICAgICAgICAgICAgbm90aWNlLm9mZih0cmFuc2l0aW9uRXZlbnQsIGhpZGUpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIG5vdGljZS5vbih0cmFuc2l0aW9uRXZlbnQsIGhpZGUpO1xuICAgICAgICB9LCBvcHRpb25zLmF1dG9IaWRlTm90aWNlKTtcbiAgICB9XG59O1xuXG5jb25zdCBwbHVnaW4gPSBmdW5jdGlvbihzZXR0aW5ncyA9IHt9KXtcbiAgICAvKipcbiAgICAgKiBBIHZpZGVvLmpzIHBsdWdpbi5cbiAgICAgKlxuICAgICAqIEluIHRoZSBwbHVnaW4gZnVuY3Rpb24sIHRoZSB2YWx1ZSBvZiBgdGhpc2AgaXMgYSB2aWRlby5qcyBgUGxheWVyYFxuICAgICAqIGluc3RhbmNlLiBZb3UgY2Fubm90IHJlbHkgb24gdGhlIHBsYXllciBiZWluZyBpbiBhIFwicmVhZHlcIiBzdGF0ZSBoZXJlLFxuICAgICAqIGRlcGVuZGluZyBvbiBob3cgdGhlIHBsdWdpbiBpcyBpbnZva2VkLiBUaGlzIG1heSBvciBtYXkgbm90IGJlIGltcG9ydGFudFxuICAgICAqIHRvIHlvdTsgaWYgbm90LCByZW1vdmUgdGhlIHdhaXQgZm9yIFwicmVhZHlcIiFcbiAgICAgKlxuICAgICAqIEBmdW5jdGlvbiBwYW5vcmFtYVxuICAgICAqIEBwYXJhbSAgICB7T2JqZWN0fSBbb3B0aW9ucz17fV1cbiAgICAgKiAgICAgICAgICAgQW4gb2JqZWN0IG9mIG9wdGlvbnMgbGVmdCB0byB0aGUgcGx1Z2luIGF1dGhvciB0byBkZWZpbmUuXG4gICAgICovXG4gICAgY29uc3QgdmlkZW9UeXBlcyA9IFtcImVxdWlyZWN0YW5ndWxhclwiLCBcImZpc2hleWVcIiwgXCIzZFZpZGVvXCJdO1xuICAgIGNvbnN0IHBhbm9yYW1hID0gZnVuY3Rpb24ob3B0aW9ucykge1xuICAgICAgICBpZihzZXR0aW5ncy5tZXJnZU9wdGlvbikgb3B0aW9ucyA9IHNldHRpbmdzLm1lcmdlT3B0aW9uKGRlZmF1bHRzLCBvcHRpb25zKTtcbiAgICAgICAgaWYodHlwZW9mIHNldHRpbmdzLl9pbml0ID09PSBcInVuZGVmaW5lZFwiIHx8IHR5cGVvZiBzZXR0aW5ncy5faW5pdCAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKFwicGx1Z2luIG11c3QgaW1wbGVtZW50IGluaXQgZnVuY3Rpb24oKS5cIik7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgaWYodmlkZW9UeXBlcy5pbmRleE9mKG9wdGlvbnMudmlkZW9UeXBlKSA9PSAtMSkgb3B0aW9ucy52aWRlb1R5cGUgPSBkZWZhdWx0cy52aWRlb1R5cGU7XG4gICAgICAgIHNldHRpbmdzLl9pbml0KG9wdGlvbnMpO1xuICAgICAgICAvKiBpbXBsZW1lbnQgY2FsbGJhY2sgZnVuY3Rpb24gd2hlbiB2aWRlb2pzIGlzIHJlYWR5ICovXG4gICAgICAgIHRoaXMucmVhZHkoKCkgPT4ge1xuICAgICAgICAgICAgb25QbGF5ZXJSZWFkeSh0aGlzLCBvcHRpb25zLCBzZXR0aW5ncyk7XG4gICAgICAgIH0pO1xuICAgIH07XG5cbi8vIEluY2x1ZGUgdGhlIHZlcnNpb24gbnVtYmVyLlxuICAgIHBhbm9yYW1hLlZFUlNJT04gPSAnMC4xLjAnO1xuXG4gICAgcmV0dXJuIHBhbm9yYW1hO1xufTtcblxuZXhwb3J0IGRlZmF1bHQgcGx1Z2luO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5pbXBvcnQgQ2FudmFzICBmcm9tICcuL2xpYi9DYW52YXMnO1xuaW1wb3J0IFRocmVlRENhbnZhcyBmcm9tICcuL2xpYi9UaHJlZUNhbnZhcyc7XG5pbXBvcnQgTm90aWNlICBmcm9tICcuL2xpYi9Ob3RpY2UnO1xuaW1wb3J0IEhlbHBlckNhbnZhcyBmcm9tICcuL2xpYi9IZWxwZXJDYW52YXMnO1xuaW1wb3J0IFZSQnV0dG9uIGZyb20gJy4vbGliL1ZSQnV0dG9uJztcbmltcG9ydCBwYW5vcmFtYSBmcm9tICcuL3BsdWdpbic7XG5cbmZ1bmN0aW9uIGdldFRlY2gocGxheWVyKSB7XG4gICAgcmV0dXJuIHBsYXllci50ZWNoKHsgSVdpbGxOb3RVc2VUaGlzSW5QbHVnaW5zOiB0cnVlIH0pLmVsKCk7XG59XG5cbmZ1bmN0aW9uIGdldEZ1bGxzY3JlZW5Ub2dnbGVDbGlja0ZuKHBsYXllcikge1xuICAgIHJldHVybiBwbGF5ZXIuY29udHJvbEJhci5mdWxsc2NyZWVuVG9nZ2xlLmhhbmRsZUNsaWNrXG59XG5cbnZhciBjb21wb25lbnQgPSB2aWRlb2pzLmdldENvbXBvbmVudCgnQ29tcG9uZW50Jyk7XG5cbnZhciBub3RpY2UgPSBOb3RpY2UoY29tcG9uZW50KTtcbnZpZGVvanMucmVnaXN0ZXJDb21wb25lbnQoJ05vdGljZScsIHZpZGVvanMuZXh0ZW5kKGNvbXBvbmVudCwgbm90aWNlKSk7XG5cbnZhciBoZWxwZXJDYW52YXMgPSBIZWxwZXJDYW52YXMoY29tcG9uZW50KTtcbnZpZGVvanMucmVnaXN0ZXJDb21wb25lbnQoJ0hlbHBlckNhbnZhcycsIHZpZGVvanMuZXh0ZW5kKGNvbXBvbmVudCwgaGVscGVyQ2FudmFzKSk7XG5cbnZhciBidXR0b24gPSB2aWRlb2pzLmdldENvbXBvbmVudChcIkJ1dHRvblwiKTtcbnZhciB2ckJ0biA9IFZSQnV0dG9uKGJ1dHRvbik7XG52aWRlb2pzLnJlZ2lzdGVyQ29tcG9uZW50KCdWUkJ1dHRvbicsIHZpZGVvanMuZXh0ZW5kKGJ1dHRvbiwgdnJCdG4pKTtcblxuLy8gUmVnaXN0ZXIgdGhlIHBsdWdpbiB3aXRoIHZpZGVvLmpzLlxudmlkZW9qcy5wbHVnaW4oJ3Bhbm9yYW1hJywgcGFub3JhbWEoe1xuICAgIF9pbml0OiBmdW5jdGlvbihvcHRpb25zKXtcbiAgICAgICAgdmFyIGNhbnZhcyA9IChvcHRpb25zLnZpZGVvVHlwZSAhPT0gXCIzZFZpZGVvXCIpP1xuICAgICAgICAgICAgQ2FudmFzKGNvbXBvbmVudCwgd2luZG93LlRIUkVFLCB7XG4gICAgICAgICAgICAgICAgZ2V0VGVjaDogZ2V0VGVjaFxuICAgICAgICAgICAgfSkgOlxuICAgICAgICAgICAgVGhyZWVEQ2FudmFzKGNvbXBvbmVudCwgd2luZG93LlRIUkVFLCB7XG4gICAgICAgICAgICAgICAgZ2V0VGVjaDogZ2V0VGVjaFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIHZpZGVvanMucmVnaXN0ZXJDb21wb25lbnQoJ0NhbnZhcycsIHZpZGVvanMuZXh0ZW5kKGNvbXBvbmVudCwgY2FudmFzKSk7XG4gICAgfSxcbiAgICBtZXJnZU9wdGlvbjogZnVuY3Rpb24gKGRlZmF1bHRzLCBvcHRpb25zKSB7XG4gICAgICAgI
1598HJldHVybiB2aWRlb2pzLm1lcmdlT3B0aW9ucyhkZWZhdWx0cywgb3B0aW9ucyk7XG4gICAgfSxcbiAgICBnZXRUZWNoOiBnZXRUZWNoLFxuICAgIGdldEZ1bGxzY3JlZW5Ub2dnbGVDbGlja0ZuOiBnZXRGdWxsc2NyZWVuVG9nZ2xlQ2xpY2tGblxufSkpO1xuIl19
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.