| Server IP : 85.158.181.41 / Your IP : 216.73.217.12 Web Server : Apache System : Linux cloud9-vm129 6.1.178+1-ph #ph SMP PREEMPT_DYNAMIC Wed Jul 29 09:00:54 UTC 2026 x86_64 User : moncbefd ( 1024) PHP Version : 7.3.33 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : ON | Sudo : OFF | Pkexec : OFF Directory : /home/moncbefd/www.moneta.at/public/tmp/theme210318125255/javascripts/system/widgets/ |
Upload File : |
'use strict';
/* --------------------------------------------------------------
swiper.js 2017-08-03
Gambio GmbH
http://www.gambio.de
Copyright (c) 2017 Gambio GmbH
Released under the GNU General Public License (Version 2)
[http://www.gnu.org/licenses/gpl-2.0.html]
--------------------------------------------------------------
*/
/* globals Swiper */
/**
* Widget that binds the swiper plugin (third party) to a DOM element
*
* @todo Remove the try - catch blocks and and correct the swiper issues.
*/
gambio.widgets.module('swiper', [gambio.source + '/libs/events', gambio.source + '/libs/responsive'], function (data) {
'use strict';
// ########## VARIABLE INITIALIZATION ##########
var $this = $(this),
$body = $('body'),
$slides = null,
$controls = null,
$target = null,
$theme = null,
init = true,
swiper = null,
sliderOptions = null,
hasThumbnails = true,
mode = null,
breakpointDataset = null,
duplicates = false,
preventSlideStart = false,
sliderDefaults = { // Default configuration for the swiper
pagination: '.swiper-pagination',
nextButton: '.swiper-button-next',
prevButton: '.swiper-button-prev',
paginationClickable: true,
loop: true,
autoplay: 3,
autoplayDisableOnInteraction: false
},
defaults = {
// JSON that gets merged with the sliderDefaults and is passed to "swiper" directly.
sliderOptions: null,
// If this instance is a "main" swiper, the given selector selects the "control" swiper.
controls: null,
// If this instance is a "control" swiper, the given selector selects the "main" swiper.
target: null,
// Sets the initial slide (needed to prevent different init slides in main/controller slider).
initSlide: null,
// Detect if a swiper is needed for the breakpoint. If not, turn it off
autoOff: false,
// The translucence fix enables support for a fade effect between images with different aspect ratio,
// but causing a delay between the change
disableTranslucenceFix: false,
breakpoints: [{
// Until which breakpoint this settings is available
breakpoint: 40,
// If true, the paging bullets will be replaced with the preview images.
usePreviewBullets: false,
// This and all other settings belonging to the swiper plugin.
slidesPerView: 2,
// If true, the current slide gets centered in view (most usefull with an even slidesPerView
// count).
centeredSlides: true
}, {
breakpoint: 60,
usePreviewBullets: true,
slidesPerView: 3
}, {
breakpoint: 80,
usePreviewBullets: true,
slidesPerView: 3
}, {
breakpoint: 100,
usePreviewBullets: true,
slidesPerView: 5
}]
},
options = $.extend({}, defaults, data),
module = {};
// ########## HELPER FUNCTIONS ##########
/**
* Function that generates the markup for
* the preview bullets
* @param {Swiper} swiper Swiper object
* @param {integer} index Index of the slide
* @param {string} className The classname that must be add to the markup
* @return {string} The preview image html string
* @private
*/
var _generatePreviewButtons = function _generatePreviewButtons(swiper, index, className) {
var $currentSlide = $slides.eq(index),
$image = $currentSlide.find('img'),
altTxt = $image.attr('alt'),
thumbImage = $currentSlide.data('thumbImage');
if (thumbImage) {
return '<img src="' + thumbImage + '" alt="' + altTxt + '" class="' + className + '" />';
}
return '';
};
/**
* Helper function to get the index of the
* active slide
* @return {integer} The index of the active slide
* @private
*/
var _getIndex = function _getIndex() {
var index = $this.find('.swiper-slide-active').index();
// If there are duplicate slides (generated
// by the swiper) recalculate the index
index = duplicates ? index - 1 : index;
index = index || 0;
return index;
};
/**
* Helper function to add the active
* class to the active slide
* @param {integer} index The index of the active slide
* @private
*/
var _setActive = function _setActive(index) {
$slides = $this.find('.swiper-slide:not(.swiper-slide-duplicate)');
index = duplicates ? index + 1 : index;
$slides.removeClass('active').eq(index).addClass('active');
};
// ########## EVENT HANDLER ##########
/**
* Event handler for the mouseenter event.
* It disables the autoplay
* @private
*/
var _mouseEnterHandler = function _mouseEnterHandler() {
try {
if (swiper) {
swiper.stopAutoplay();
}
} catch (e) {
// Do not log the error
}
};
/**
* Event handler for the mouseleave event.
* It enables the autoplay
* @private
*/
var _mouseLeaveHandler = function _mouseLeaveHandler() {
try {
if (swiper) {
swiper.startAutoplay();
}
} catch (e) {
// Do not log the error
}
};
/**
* Event handler for the goto event.
* It switches the current slide to the given index
* and adds the active class to the new active slide
* @param {object} e jQuery event object
* @param {number} d Index of the slide to show
* @private
*/
var _gotoHandler = function _gotoHandler(e, d) {
e.stopPropagation();
// Set the active slide
_setActive(d);
// Temporary deactivate the onSlideChangeStart event
// to prevent looping through the goto / changeStart
// events
preventSlideStart = true;
// Remove the autoplay after a goto event
$this.off('mouseleave.swiper');
swiper.stopAutoplay();
// Try to correct the index between sliders
// with and without duplicates
var index = duplicates ? d + 1 : d;
if (index > $slides.length) {
index = 0;
}
// Goto the desired slide
swiper.slideTo(index);
// Reactivate the onSlideChangeEvent
preventSlideStart = false;
};
/**
* Click event handler that triggers a
* "goto" event to the target swiper
* @param {object} e jQuery event object
* @private
*/
var _clickHandler = function _clickHandler(e) {
e.preventDefault();
e.stopPropagation();
var $self = $(this),
index = $self.index();
index = duplicates ? index - 1 : index;
// Set the active slide
_setActive(index);
// Inform the main swiper
$target.trigger(jse.libs.theme.events.SWIPER_GOTO(), index);
};
/**
* Event that gets triggered on slideChange.
* If the slide gets changed, the controls
* will follow the current slide in position
* @private
*/
var _triggerSlideChange = function _triggerSlideChange() {
if (!preventSlideStart) {
var index = _getIndex(),
lastIndex = $slides.length - 2;
// Recalculate index if duplicate slides are inside the slider
if (index < 0) {
index = $slides.length - 3;
} else {
index = duplicates && index === lastIndex ? index - lastIndex : index;
}
// Set the active slide
_setActive(index);
// Inform the controls
$controls.trigger(jse.libs.theme.events.SWIPER_GOTO(), index);
}
};
/**
* Workaround for the translucence issue
* that happens on small screens with enabled
* fade effect. Maybe it can be removed, if the
* swiper gets updated itself
* @private
*/
var _translucenceWorkaround = function _translucenceWorkaround() {
if (!options.disableTranslucenceFix && sliderOptions && sliderOptions.effect === 'fade') {
$this.find('.swiper-slide').filter(':not(.swiper-slide-active)').fadeTo(300, 0, function () {
$(this).css('visibility', 'hidden');
});
$this.find('.swiper-slide').filter('.swiper-slide-active').fadeTo(300, 1, function () {
$(this).css('visibility', '');
});
}
};
/**
* The breakpoint handler initializes the swiper
* with the settings for the current breakpoint.
* Therefore it uses the default slider options,
* the custom slider options given by the options
* object and the breakpoint options object also
* given by the options (in this order)
* @private
*/
var _breakpointHandler = function _breakpointHandler() {
// Get the current viewmode
var oldMode = mode || {},
newMode = jse.libs.theme.responsive.breakpoint(),
extendOptions = options.breakpoints[0] || {},
newBreakpointDataset = null;
// Only do something if the view was changed
if (newMode.id !== oldMode.id) {
// Store the new viewmode
mode = $.extend({}, newMode);
// Iterate through the breakpoints object to detect
// the correct settings for the current breakpoint
$.each(options.breakpoints, function (i, v) {
if (v.breakpoint > newMode.id) {
return false;
}
newBreakpointDataset = i;
extendOptions = v;
});
if (options.sliderOptions && options.sliderOptions.breakpoints) {
$.each(options.sliderOptions.breakpoints, function (i, v) {
if (v.breakpoint === newMode.id) {
extendOptions = v;
return false;
}
});
}
// Only do something if the settings change due browser
// resize or if it's the first time run
if (newBreakpointDataset !== breakpointDataset || init) {
// Combine the settings
sliderOptions = $.extend({}, sliderDefaults, options.sliderOptions || {}, extendOptions);
// Add the preview image bullets function to the options object
if (sliderOptions.usePreviewBullets && hasThumbnails) {
sliderOptions.paginationBulletRender = _generatePreviewButtons;
}
// Add the autoplay interval to the options object
sliderOptions.autoplay = sliderOptions.autoplay ? sliderOptions.autoplay * 1000 : 0;
// Disable loop if there is only one slider.
if ($this.find('.swiper-slide').length === 1) {
sliderOptions.loop = false;
}
// If an swiper exists, get the current
// slide no. and remove the old swiper
if (swiper) {
sliderOptions.initialSlide = _getIndex();
try {
swiper.destroy(true, true);
} catch (ignore) {
swiper = null;
}
} else {
sliderOptions.initialSlide = options.initSlide || sliderOptions.initialSlide || 0;
}
var $duplicate = $this.find('.swiper-slide:not(.swiper-slide-duplicate)');
if (!options.autoOff || $duplicate.length > sliderOptions.slidesPerView && options.autoOff) {
$this.addClass('swiper-is-active').removeClass('swiper-is-not-active');
// Initialize the swiper
try {
swiper = new Swiper($this, sliderOptions);
} catch (e) {
return; // Swiper might throw an error upon initialization that should not halt the script execution.
}
swiper.off('onTransitionEnd onSlideChangeStart').on('onTransitionEnd', _translucenceWorkaround);
// If this is a "main" swiper and has external controls, an
// goto event is triggered if the current slide is changed
if ($controls.length) {
swiper.on('onSlideChangeStart', _triggerSlideChange);
}
// Add the event handler
$this.off('mouseenter.swiper mouseleave.swiper ' + jse.libs.theme.events.SWIPER_GOTO() + ' ' + jse.libs.theme.events.SLIDES_UPDATE()).on('mouseenter.swiper', _mouseEnterHandler).on('mouseleave.swiper', _mouseLeaveHandler).on(jse.libs.theme.events.SWIPER_GOTO(), _gotoHandler).on(jse.libs.theme.events.SLIDES_UPDATE(), _updateSlides);
if (init) {
// Check if there are duplicates slides (generated by the swiper)
// after the first time init of the swiper
duplicates = !!$this.find('.swiper-slide-duplicate').length;
}
// Set the active slide
var index = init && options.initSlide ? options.initSlide : _getIndex();
_setActive(index);
// Inform the controls that the main swiper has changed
// In case that the other slider isn't initialized yet,
// set an data attribute to the markup element to inform
// it on init
if ($controls.length) {
$controls.attr('data-swiper-init-slide', index);
_triggerSlideChange();
}
// Unset the init flag
init = false;
setTimeout(function () {
return swiper.update();
});
} else {
// Disable the swiper buttons
$this.removeClass('swiper-is-active').addClass('swiper-is-not-active');
init = true;
}
}
}
};
/**
* Event handler that adds & removes slides from the
* swiper. After the slides were processed, the first
* slide is shown
* @param {object} e jQuery event object
* @param {object} d JSON object that contains the categories / images
* @private
*/
var _updateSlides = function _updateSlides(e, d) {
// Loops through each category inside the images array
$.each(d, function (category, dataset) {
var catName = category + '-category',
add = [],
remove = [],
markup = $theme.html();
// Get all indexes from the slides
// of the same category and remove
// them from the slider
$slides.filter('.' + catName).each(function () {
var $self = $(this),
index = $self.data().swiperSlideIndex;
index = index === undefined ? $self.index() : index;
remove.push(index);
});
swiper.removeSlide(remove);
// Generate the markup for the new slides
// and add them to the slider
$.each(dataset || [], function (i, v) {
v.className = catName;
v.srcattr = 'src="' + v.src + '"';
add.push(Mustache.render(markup, v));
});
swiper.appendSlide(add);
});
$slides = $this.find('.swiper-slide');
// To prevent an inconsistent state
// in control / main slider combinations
// slide to the first slide
_setActive(0);
var index = duplicates ? 1 : 0;
swiper.slideTo(index, 0);
};
/**
* Prevent text selection by clicking on swiper buttons
* @private
*/
var _preventTextSelection = function _preventTextSelection() {
$(options.sliderOptions.nextButton).on('selectstart', function () {
return false;
});
$(options.sliderOptions.prevButton).on('selectstart', function () {
return false;
});
};
/**
* Sets the initial height for one swiper image container to prevent cut off images on smaller swiper heights
* @private
*/
var _scaleThumbnailHeight = function _scaleThumbnailHeight() {
var swiperContainer = $('.swiper-container-vertical .swiper-slide');
var $containerHeight = swiperContainer.css('height');
// Workaround for IE Browsers
if ($('.swiper-container-vertical').hasClass('swiper-wp8-vertical')) {
$containerHeight = swiperContainer.height() + 5;
swiperContainer.css('height', $containerHeight);
}
if ($containerHeight === '0px') {
$containerHeight = $('.product-info-thumbnails-mobile').css('height');
}
$('.align-middle').css('height', $containerHeight);
};
// ########## INITIALIZATION ##########
/**
* Init function of the widget
* @constructor
*/
module.init = function (done) {
$slides = $this.find('.swiper-slide');
$controls = $(options.controls);
$target = $(options.target);
$theme = $this.find('theme');
// Check if all images inside the swiper have
// thumbnail image given
$slides.each(function () {
if (!$(this).data().thumbImage) {
hasThumbnails = false;
return false;
}
});
// Add the breakpoint handler ty dynamically
// set the options corresponding to the browser size (slider responsive will re-initialize the swiper).
_breakpointHandler();
// If this instance is a "control" swiper the target is the main swiper
// which will be updated on a click inside this control swiper
if (options.target) {
$this.on('click.swiper', '.swiper-slide', _clickHandler);
}
$(document).ready(function () {
$('.swiper-vertical .swiper-slide[data-index]').css('display', 'inline-block');
$('.product-info-image .swiper-slide[data-index]').css('z-index', 'inherit');
$('.product-info-image .swiper-slide[data-index] .swiper-slide-inside img.img-responsive').fadeIn(1000);
});
_translucenceWorkaround();
_preventTextSelection();
_scaleThumbnailHeight();
// Fix for invisible Thumbnail-Images for switching from Tablet-Portrait to Tablet-Landscape
$body.on(jse.libs.theme.events.BREAKPOINT(), function () {
_scaleThumbnailHeight();
});
done();
};
// Return data to widget engine
return module;
});
//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndpZGdldHMvc3dpcGVyLmpzIl0sIm5hbWVzIjpbImdhbWJpbyIsIndpZGdldHMiLCJtb2R1bGUiLCJzb3VyY2UiLCJkYXRhIiwiJHRoaXMiLCIkIiwiJGJvZHkiLCIkc2xpZGVzIiwiJGNvbnRyb2xzIiwiJHRhcmdldCIsIiR0aGVtZSIsImluaXQiLCJzd2lwZXIiLCJzbGlkZXJPcHRpb25zIiwiaGFzVGh1bWJuYWlscyIsIm1vZGUiLCJicmVha3BvaW50RGF0YXNldCIsImR1cGxpY2F0ZXMiLCJwcmV2ZW50U2xpZGVTdGFydCIsInNsaWRlckRlZmF1bHRzIiwicGFnaW5hdGlvbiIsIm5leHRCdXR0b24iLCJwcmV2QnV0dG9uIiwicGFnaW5hdGlvbkNsaWNrYWJsZSIsImxvb3AiLCJhdXRvcGxheSIsImF1dG9wbGF5RGlzYWJsZU9uSW50ZXJhY3Rpb24iLCJkZWZhdWx0cyIsImNvbnRyb2xzIiwidGFyZ2V0IiwiaW5pdFNsaWRlIiwiYXV0b09mZiIsImRpc2FibGVUcmFuc2x1Y2VuY2VGaXgiLCJicmVha3BvaW50cyIsImJyZWFrcG9pbnQiLCJ1c2VQcmV2aWV3QnVsbGV0cyIsInNsaWRlc1BlclZpZXciLCJjZW50ZXJlZFNsaWRlcyIsIm9wdGlvbnMiLCJleHRlbmQiLCJfZ2VuZXJhdGVQcmV2aWV3QnV0dG9ucyIsImluZGV4IiwiY2xhc3NOYW1lIiwiJGN1cnJlbnRTbGlkZSIsImVxIiwiJGltYWdlIiwiZmluZCIsImFsdFR4dCIsImF0dHIiLCJ0aHVtYkltYWdlIiwiX2dldEluZGV4IiwiX3NldEFjdGl2ZSIsInJlbW92ZUNsYXNzIiwiYWRkQ2xhc3MiLCJfbW91c2VFbnRlckhhbmRsZXIiLCJzdG9wQXV0b3BsYXkiLCJlIiwiX21vdXNlTGVhdmVIYW5kbGVyIiwic3RhcnRBdXRvcGxheSIsIl9nb3RvSGFuZGxlciIsImQiLCJzdG9wUHJvcGFnYXRpb24iLCJvZmYiLCJsZW5ndGgiLCJzbGlkZVRvIiwiX2NsaWNrSGFuZGxlciIsInByZXZlbnREZWZhdWx0IiwiJHNlbGYiLCJ0cmlnZ2VyIiwianNlIiwibGlicyIsInRoZW1lIiwiZXZlbnRzIiwiU1dJUEVSX0dPVE8iLCJfdHJpZ2dlclNsaWRlQ2hhbmdlIiwibGFzdEluZGV4IiwiX3RyYW5zbHVjZW5jZVdvcmthcm91bmQiLCJlZmZlY3QiLCJmaWx0ZXIiLCJmYWRlVG8iLCJjc3MiLCJfYnJlYWtwb2ludEhhbmRsZXIiLCJvbGRNb2RlIiwibmV3TW9kZSIsInJlc3BvbnNpdmUiLCJleHRlbmRPcHRpb25zIiwibmV3QnJlYWtwb2ludERhdGFzZXQiLCJpZCIsImVhY2giLCJpIiwidiIsInBhZ2luYXRpb25CdWxsZXRSZW5kZXIiLCJpbml0aWFsU2xpZGUiLCJkZXN0cm95IiwiaWdub3JlIiwiJGR1cGxpY2F0ZSIsIlN3aXBlciIsIm9uIiwiU0xJREVTX1VQREFURSIsIl91cGRhdGVTbGlkZXMiLCJzZXRUaW1lb3V0IiwidXBkYXRlIiwiY2F0ZWdvcnkiLCJkYXRhc2V0IiwiY2F0TmFtZSIsImFkZCIsInJlbW92ZSIsIm1hcmt1cCIsImh0bWwiLCJzd2lwZXJTbGlkZUluZGV4IiwidW5kZWZpbmVkIiwicHVzaCIsInJlbW92ZVNsaWRlIiwic3JjYXR0ciIsInNyYyIsIk11c3RhY2hlIiwicmVuZGVyIiwiYXBwZW5kU2xpZGUiLCJfcHJldmVudFRleHRTZWxlY3Rpb24iLCJfc2NhbGVUaHVtYm5haWxIZWlnaHQiLCJzd2lwZXJDb250YWluZXIiLCIkY29udGFpbmVySGVpZ2h0IiwiaGFzQ2xhc3MiLCJoZWlnaHQiLCJkb25lIiwiZG9jdW1lbnQiLCJyZWFkeSIsImZhZGVJbiIsIkJSRUFLUE9JTlQiXSwibWFwcGluZ3MiOiI7O0FBQUE7Ozs7Ozs7Ozs7QUFVQTs7QUFFQTs7Ozs7QUFLQUEsT0FBT0MsT0FBUCxDQUFlQyxNQUFmLENBQ0ksUUFESixFQUdJLENBQ09GLE9BQU9HLE1BRGQsbUJBRU9ILE9BQU9HLE1BRmQsc0JBSEosRUFRSSxVQUFVQyxJQUFWLEVBQWdCOztBQUVaOztBQUVSOztBQUVRLFFB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O0FBQ2hCekIsa0JBQU02RixFQUFOLENBQVMsY0FBVCxFQUF5QixlQUF6QixFQUEwQ2hDLGFBQTFDO0FBQ0g7O0FBRUQ1RCxVQUFFd0gsUUFBRixFQUFZQyxLQUFaLENBQWtCLFlBQVk7QUFDMUJ6SCxjQUFFLDRDQUFGLEVBQWdEMkUsR0FBaEQsQ0FBb0QsU0FBcEQsRUFBK0QsY0FBL0Q7QUFDQTNFLGNBQUUsK0NBQUYsRUFBbUQyRSxHQUFuRCxDQUF1RCxTQUF2RCxFQUFrRSxTQUFsRTtBQUNBM0UsY0FBRSx1RkFBRixFQUEyRjBILE1BQTNGLENBQWtHLElBQWxHO0FBQ0gsU0FKRDs7QUFNQW5EO0FBQ0EwQztBQUNBQzs7QUFFQTtBQUNBakgsY0FBTTJGLEVBQU4sQ0FBUzVCLElBQUlDLElBQUosQ0FBU0MsS0FBVCxDQUFlQyxNQUFmLENBQXNCd0QsVUFBdEIsRUFBVCxFQUE2QyxZQUFZO0FBQ3JEVDtBQUNILFNBRkQ7O0FBSUFLO0FBQ0gsS0ExQ0Q7O0FBNENBO0FBQ0EsV0FBTzNILE1BQVA7QUFDSCxDQTFqQkwiLCJmaWxlIjoid2lkZ2V0cy9zd2lwZXIuanMiLCJzb3VyY2VzQ29udGVudCI6WyIvKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuIHN3aXBlci5qcyAyMDE3LTA4LTAzXG4gR2FtYmlvIEdtYkhcbiBodHRwOi8vd3d3LmdhbWJpby5kZVxuIENvcHlyaWdodCAoYykgMjAxNyBHYW1iaW8gR21iSFxuIFJlbGVhc2VkIHVuZGVyIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSAoVmVyc2lvbiAyKVxuIFtodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvZ3BsLTIuMC5odG1sXVxuIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gKi9cblxuLyogZ2xvYmFscyBTd2lwZXIgKi9cblxuLyoqXG4gKiBXaWRnZXQgdGhhdCBiaW5kcyB0aGUgc3dpcGVyIHBsdWdpbiAodGhpcmQgcGFydHkpIHRvIGEgRE9NIGVsZW1lbnRcbiAqXG4gKiBAdG9kbyBSZW1vdmUgdGhlIHRyeSAtIGNhdGNoIGJsb2NrcyBhbmQgYW5kIGNvcnJlY3QgdGhlIHN3aXBlciBpc3N1ZXMuXG4gKi9cbmdhbWJpby53aWRnZXRzLm1vZHVsZShcbiAgICAnc3dpcGVyJyxcblxuICAgIFtcbiAgICAgICAgYCR7Z2FtYmlvLnNvdXJjZX0vbGlicy9ldmVudHNgLFxuICAgICAgICBgJHtnYW1iaW8uc291cmNlfS9saWJzL3Jlc3BvbnNpdmVgXG4gICAgXSxcblxuICAgIGZ1bmN0aW9uIChkYXRhKSB7XG5cbiAgICAgICAgJ3VzZSBzdHJpY3QnO1xuXG4vLyAjIyMjIyMjIyMjIFZBUklBQkxFIElOSVRJQUxJWkFUSU9OICMjIyMjIyMjIyNcblxuICAgICAgICB2YXIgJHRoaXMgPSAkKHRoaXMpLFxuICAgICAgICAgICAgJGJvZHkgPSAkKCdib2R5JyksXG4gICAgICAgICAgICAkc2xpZGVzID0gbnVsbCxcbiAgICAgICAgICAgICRjb250cm9scyA9IG51bGwsXG4gICAgICAgICAgICAkdGFyZ2V0ID0gbnVsbCxcbiAgICAgICAgICAgICR0aGVtZSA9IG51bGwsXG4gICAgICAgICAgICBpbml0ID0gdHJ1ZSxcbiAgICAgICAgICAgIHN3aXBlciA9IG51bGwsXG4gICAgICAgICAgICBzbGlkZXJPcHRpb25zID0gbnVsbCxcbiAgICAgICAgICAgIGhhc1RodW1ibmFpbHMgPSB0cnVlLFxuICAgICAgICAgICAgbW9kZSA9IG51bGwsXG4gICAgICAgICAgICBicmVha3BvaW50RGF0YXNldCA9IG51bGwsXG4gICAgICAgICAgICBkdXBsaWNhdGVzID0gZmFsc2UsXG4gICAgICAgICAgICBwcmV2ZW50U2xpZGVTdGFydCA9IGZhbHNlLFxuICAgICAgICAgICAgc2xpZGVyRGVmYXVsdHMgPSB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBEZWZhdWx0IGNvbmZpZ3VyYXRpb24gZm9yIHRoZSBzd2lwZXJcbiAgICAgICAgICAgICAgICBwYWdpbmF0aW9uOiAnLnN3aXBlci1wYWdpbmF0aW9uJyxcbiAgICAgICAgICAgICAgICBuZXh0QnV0dG9uOiAnLnN3aXBlci1idXR0b24tbmV4dCcsXG4gICAgICAgICAgICAgICAgcHJldkJ1dHRvbjogJy5zd2lwZXItYnV0dG9uLXByZXYnLFxuICAgICAgICAgICAgICAgIHBhZ2luYXRpb25DbGlja2FibGU6IHRydWUsXG4gICAgICAgICAgICAgICAgbG9vcDogdHJ1ZSxcbiAgICAgICAgICAgICAgICBhdXRvcGxheTogMyxcbiAgICAgICAgICAgICAgICBhdXRvcGxheURpc2FibGVPbkludGVyYWN0aW9uOiBmYWxzZVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGRlZmF1bHRzID0ge1xuICAgICAgICAgICAgICAgIC8vIEpTT04gdGhhdCBnZXRzIG1lcmdlZCB3aXRoIHRoZSBzbGlkZXJEZWZhdWx0cyBhbmQgaXMgcGFzc2VkIHRvIFwic3dpcGVyXCIgZGlyZWN0bHkuXG4gICAgICAgICAgICAgICAgc2xpZGVyT3B0aW9uczogbnVsbCxcbiAgICAgICAgICAgICAgICAvLyBJZiB0aGlzIGluc3RhbmNlIGlzIGEgXCJtYWluXCIgc3dpcGVyLCB0aGUgZ2l2ZW4gc2VsZWN0b3Igc2VsZWN0cyB0aGUgXCJjb250cm9sXCIgc3dpcGVyLlxuICAgICAgICAgICAgICAgIGNvbnRyb2xzOiBudWxsLFxuICAgICAgICAgICAgICAgIC8vIElmIHRoaXMgaW5zdGFuY2UgaXMgYSBcImNvbnRyb2xcIiBzd2lwZXIsIHRoZSBnaXZlbiBzZWxlY3RvciBzZWxlY3RzIHRoZSBcIm1haW5cIiBzd2lwZXIuXG4gICAgICAgICAgICAgICAgdGFyZ2V0OiBudWxsLFxuICAgICAgICAgICAgICAgIC8vIFNldHMgdGhlIGluaXRpYWwgc2xpZGUgKG5lZWRlZCB0byBwcmV2ZW50IGRpZmZlcmVudCBpbml0IHNsaWRlcyBpbiBtYWluL2NvbnRyb2xsZXIgc2xpZGVyKS5cbiAgICAgICAgICAgICAgICBpbml0U2xpZGU6IG51bGwsXG4gICAgICAgICAgICAgICAgLy8gRGV0ZWN0IGlmIGEgc3dpcGVyIGlzIG5lZWRlZCBmb3IgdGhlIGJyZWFrcG9pbnQuIElmIG5vdCwgdHVybiBpdCBvZmZcbiAgICAgICAgICAgICAgICBhdXRvT2ZmOiBmYWxzZSxcbiAgICAgICAgICAgICAgICAvLyBUaGUgdHJhbnNsdWNlbmNlIGZpeCBlbmFibGVzIHN1cHBvcnQgZm9yIGEgZmFkZSBlZmZlY3QgYmV0d2VlbiBpbWFnZXMgd2l0aCBkaWZmZXJlbnQgYXNwZWN0IHJhdGlvLFxuICAgICAgICAgICAgICAgIC8vIGJ1dCBjYXVzaW5nIGEgZGVsYXkgYmV0d2VlbiB0aGUgY2hhbmdlXG4gICAgICAgICAgICAgICAgZGlzYWJsZVRyYW5zbHVjZW5jZUZpeDogZmFsc2UsXG4gICAgICAgICAgICAgICAgYnJlYWtwb2ludHM6IFtcbiAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gVW50aWwgd2hpY2ggYnJlYWtwb2ludCB0aGlzIHNldHRpbmdzIGlzIGF2YWlsYWJsZVxuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWtwb2ludDogNDAsXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBJZiB0cnVlLCB0aGUgcGFnaW5nIGJ1bGxldHMgd2lsbCBiZSByZXBsYWNlZCB3aXRoIHRoZSBwcmV2aWV3IGltYWdlcy5cbiAgICAgICAgICAgICAgICAgICAgICAgIHVzZVByZXZpZXdCdWxsZXRzOiBmYWxzZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFRoaXMgYW5kIGFsbCBvdGhlciBzZXR0aW5ncyBiZWxvbmdpbmcgdG8gdGhlIHN3aXBlciBwbHVnaW4uXG4gICAgICAgICAgICAgICAgICAgICAgICBzbGlkZXNQZXJWaWV3OiAyLFxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gSWYgdHJ1ZSwgdGhlIGN1cnJlbnQgc2xpZGUgZ2V0cyBjZW50ZXJlZCBpbiB2aWV3IChtb3N0IHVzZWZ1bGwgd2l0aCBhbiBldmVuIHNsaWRlc1BlclZpZXdcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNvdW50KS5cbiAgICAgICAgICAgICAgICAgICAgICAgIGNlbnRlcmVkU2xpZGVzOiB0cnVlXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrcG9pbnQ6IDYwLFxuICAgICAgICAgICAgICAgICAgICAgICAgdXNlUHJldmlld0J1bGxldHM6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgICAgICBzbGlkZXNQZXJWaWV3OiAzXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrcG9pbnQ6IDgwLFxuICAgICAgICAgICAgICAgICAgICAgICAgdXNlUHJldmlld0J1bGxldHM6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgICAgICBzbGlkZXNQZXJWaWV3OiAzXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrcG9pbnQ6IDEwMCxcbiAgICAgICAgICAgICAgICAgICAgICAgIHVzZVByZXZpZXdCdWxsZXRzOiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICAgICAgc2xpZGVzUGVyVmlldzogNVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgXVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIG9wdGlvbnMgPSAkLmV4dGVuZCh7fSwgZGVmYXVsdHMsIGRhdGEpLFxuICAgICAgICAgICAgbW9kdWxlID0ge307XG5cblxuLy8gIyMjIyMjIyMjIyBIRUxQRVIgRlVOQ1RJT05TICMjIyMjIyMjIyNcblxuICAgICAgICAvKipcbiAgICAgICAgICogRnVuY3Rpb24gdGhhdCBnZW5lcmF0ZXMgdGhlIG1hcmt1cCBmb3JcbiAgICAgICAgICogdGhlIHByZXZpZXcgYnVsbGV0c1xuICAgICAgICAgKiBAcGFyYW0gICAgICAge1N3aXBlcn0gICAgICAgIHN3aXBlciAgICAgICAgICBTd2lwZXIgb2JqZWN0XG4gICAgICAgICAqIEBwYXJhbSAgICAgICB7aW50ZWdlcn0gICAgICAgaW5kZXggICAgICAgICAgIEluZGV4IG9mIHRoZSBzbGlkZVxuICAgICAgICAgKiBAcGFyYW0gICAgICAge3N0cmluZ30gICAgICAgIGNsYXNzTmFtZSAgICAgICBUaGUgY2xhc3NuYW1lIHRoYXQgbXVzdCBiZSBhZGQgdG8gdGhlIG1hcmt1cFxuICAgICAgICAgKiBAcmV0dXJuICAgICAge3N0cmluZ30gICAgICAgICAgICAgICAgICAgICAgICBUaGUgcHJldmlldyBpbWFnZSBodG1sIHN0cmluZ1xuICAgICAgICAgKiBAcHJpdmF0ZVxuICAgICAgICAgKi9cbiAgICAgICAgdmFyIF9nZW5lcmF0ZVByZXZpZXdCdXR0b25zID0gZnVuY3Rpb24gKHN3aXBlciwgaW5kZXgsIGNsYXNzTmFtZSkge1xuICAgICAgICAgICAgdmFyICRjdXJyZW50U2xpZGUgPSAkc2xpZGVzLmVxKGluZGV4KSxcbiAgICAgICAgICAgICAgICAkaW1hZ2UgPSAkY3VycmVudFNsaWRlLmZpbmQoJ2ltZycpLFxuICAgICAgICAgICAgICAgIGFsdFR4dCA9ICRpbWFnZS5hdHRyKCdhbHQnKSxcbiAgICAgICAgICAgICAgICB0aHVtYkltYWdlID0gJGN1cnJlbnRTbGlkZS5kYXRhKCd0aHVtYkltYWdlJyk7XG5cbiAgICAgICAgICAgIGlmICh0aHVtYkltYWdlKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuICc8aW1nIHNyYz1cIicgKyB0aHVtYkltYWdlICsgJ1wiIGFsdD1cIicgKyBhbHRUeHQgKyAnXCIgY2xhc3M9XCInICsgY2xhc3NOYW1lICsgJ1wiIC8+JztcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuICcnO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBIZWxwZXIgZnVuY3Rpb24gdG8gZ2V0IHRoZSBpbmRleCBvZiB0aGVcbiAgICAgICAgICogYWN0aXZlIHNsaWRlXG4gICAgICAgICAqIEByZXR1cm4gICAgIHtpbnRlZ2VyfSAgICAgICAgICAgICAgICAgICAgICAgVGhlIGluZGV4IG9mIHRoZSBhY3RpdmUgc2xpZGVcbiAgICAgICAgICogQHByaXZhdGVcbiAgICAgICAgICovXG4gICAgICAgIHZhciBfZ2V0SW5kZXggPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICB2YXIgaW5kZXggPSAkdGhpc1xuICAgICAgICAgICAgICAgIC5maW5kKCcuc3dpcGVyLXNsaWRlLWFjdGl2ZScpXG4gICAgICAgICAgICAgICAgLmluZGV4KCk7XG5cbiAgICAgICAgICAgIC8vIElmIHRoZXJlIGFyZSBkdXBsaWNhdGUgc2xpZGVzIChnZW5lcmF0ZWRcbiAgICAgICAgICAgIC8vIGJ5IHRoZSBzd2lwZXIpIHJlY2FsY3VsYXRlIHRoZSBpbmRleFxuICAgICAgICAgICAgaW5kZXggPSBkdXBsaWNhdGVzID8gaW5kZXggLSAxIDogaW5kZXg7XG4gICAgICAgICAgICBpbmRleCA9IGluZGV4IHx8IDA7XG5cbiAgICAgICAgICAgIHJldHVybiBpbmRleDtcbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogSGVscGVyIGZ1bmN0aW9uIHRvIGFkZCB0aGUgYWN0aXZlXG4gICAgICAgICAqIGNsYXNzIHRvIHRoZSBhY3RpdmUgc2xpZGVcbiAgICAgICAgICogQHBhcmFtICAgICAgIHtpbnRlZ2VyfSAgICAgICAgICAgaW5kZXggICAgICAgVGhlIGluZGV4IG9mIHRoZSBhY3RpdmUgc2xpZGVcbiAgICAgICAgICogQHByaXZhdGVcbiAgICAgICAgICovXG4gICAgICAgIHZhciBfc2V0QWN0aXZlID0gZnVuY3Rpb24gKGluZGV4KSB7XG4gICAgICAgICAgICAkc2xpZGVzID0gJHRoaXMuZmluZCgnLnN3aXBlci1zbGlkZTpub3QoLnN3aXBlci1zbGlkZS1kdXBsaWNhdGUpJyk7XG4gICAgICAgICAgICBpbmRleCA9IGR1cGxpY2F0ZXMgPyBpbmRleCArIDEgOiBpbmRleDtcbiAgICAgICAgICAgICRzbGlkZXNcbiAgICAgICAgICAgICAgICAucmVtb3ZlQ2xhc3MoJ2FjdGl2ZScpXG4gICAgICAgICAgICAgICAgLmVxKGluZGV4KVxuICAgICAgICAgICAgICAgIC5hZGRDbGFzcygnYWN0aXZlJyk7XG4gICAgICAgIH07XG5cblxuLy8gIyMjIyMjIyMjIyBFVkVOVCBIQU5ETEVSICMjIyMjIyMjIyNcblxuICAgICAgICAvKipcbiAgICAgICAgICogRXZlbnQgaGFuZGxlciBmb3IgdGhlIG1vdXNlZW50ZXIgZXZlbnQuXG4gICAgICAgICAqIEl0IGRpc2FibGVzIHRoZSBhdXRvcGxheVxuICAgICAgICAgKiBAcHJpdmF0ZVxuICAgICAgICAgKi9cbiAgICAgICAgdmFyIF9tb3VzZUVudGVySGFuZGxlciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgaWYgKHN3aXBlcikge1xuICAgICAgICAgICAgICAgICAgICBzd2lwZXIuc3RvcEF1dG9wbGF5KCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgIC8vIERvIG5vdCBsb2cgdGhlIGVycm9yXG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIEV2ZW50IGhhbmRsZXIgZm9yIHRoZSBtb3VzZWxlYXZlIGV2ZW50LlxuICAgICAgICAgKiBJdCBlbmFibGVzIHRoZSBhdXRvcGxheVxuICAgICAgICAgKiBAcHJpdmF0ZVxuICAgICAgICAgKi9cbiAgICAgICAgdmFyIF9tb3VzZUxlYXZlSGFuZGxlciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgaWYgKHN3aXBlcikge1xuICAgICAgICAgICAgICAgICAgICBzd2lwZXIuc3RhcnRBdXRvcGxheSgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICAvLyBEbyBub3QgbG9nIHRoZSBlcnJvclxuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBFdmVudCBoYW5kbGVyIGZvciB0aGUgZ290byBldmVudC5cbiAgICAgICAgICogSXQgc3dpdGNoZXMgdGhlIGN1cnJlbnQgc2xpZGUgdG8gdGhlIGdpdmVuIGluZGV4XG4gICAgICAgICAqIGFuZCBhZGRzIHRoZSBhY3RpdmUgY2xhc3MgdG8gdGhlIG5ldyBhY3RpdmUgc2xpZGVcbiAgICAgICAgICogQHBhcmFtICAgICAgIHtvYmplY3R9ICAgIGUgICAgICAgalF1ZXJ5IGV2ZW50IG9iamVjdFxuICAgICAgICAgKiBAcGFyYW0gICAgICAge251bWJlcn0gICAgZCAgICAgICBJbmRleCBvZiB0aGUgc2xpZGUgdG8gc2hvd1xuICAgICAgICAgKiBAcHJpdmF0ZVxuICAgICAgICAgKi9cbiAgICAgICAgdmFyIF9nb3RvSGFuZGxlciA9IGZ1bmN0aW9uIChlLCBkKSB7XG4gICAgICAgICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuXG4gICAgICAgICAgICAvLyBTZXQgdGhlIGFjdGl2ZSBzbGlkZVxuICAgICAgICAgICAgX3NldEFjdGl2ZShkKTtcblxuICAgICAgICAgICAgLy8gVGVtcG9yYXJ5IGRlYWN0aXZhdGUgdGhlIG9uU2xpZGVDaGFuZ2VTdGFydCBldmVudFxuICAgICAgICAgICAgLy8gdG8gcHJldmVudCBsb29waW5nIHRocm91Z2ggdGhlIGdvdG8gLyBjaGFuZ2VTdGFydFxuICAgICAgICAgICAgLy8gZXZlbnRzXG4gICAgICAgICAgICBwcmV2ZW50U2xpZGVTdGFydCA9IHRydWU7XG5cbiAgICAgICAgICAgIC8vIFJlbW92ZSB0aGUgYXV0b3BsYXkgYWZ0ZXIgYSBnb3RvIGV2ZW50XG4gICAgICAgICAgICAkdGhpcy5vZmYoJ21vdXNlbGVhdmUuc3dpcGVyJyk7XG4gICAgICAgICAgICBzd2lwZXIuc3RvcEF1dG9wbGF5KCk7XG5cbiAgICAgICAgICAgIC8vIFRyeSB0byBjb3JyZWN0IHRoZSBpbmRleCBiZXR3ZWVuIHNsaWRlcnNcbiAgICAgICAgICAgIC8vIHdpdGggYW5kIHdpdGhvdXQgZHVwbGljYXRlc1xuICAgICAgICAgICAgdmFyIGluZGV4ID0gZHVwbGljYXRlcyA/IGQgKyAxIDogZDtcbiAgICAgICAgICAgIGlmIChpbmRleCA+ICRzbGlkZXMubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgaW5kZXggPSAwO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBHb3RvIHRoZSBkZXNpcmVkIHNsaWRlXG4gICAgICAgICAgICBzd2lwZXIuc2xpZGVUbyhpbmRleCk7XG5cbiAgICAgICAgICAgIC8vIFJlYWN0aXZhdGUgdGhlIG9uU2xpZGVDaGFuZ2VFdmVudFxuICAgICAgICAgICAgcHJldmVudFNsaWRlU3RhcnQgPSBmYWxzZTtcbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogQ2xpY2sgZXZlbnQgaGFuZGxlciB0aGF0IHRyaWdnZXJzIGFcbiAgICAgICAgICogXCJnb3RvXCIgZXZlbnQgdG8gdGhlIHRhcmdldCBzd2lwZXJcbiAgICAgICAgICogQHBhcmFtICAgICAgIHtvYmplY3R9ICAgICAgICBlICAgICAgIGpRdWVyeSBldmVudCBvYmplY3RcbiAgICAgICAgICogQHByaXZhdGVcbiAgICAgICAgICovXG4gICAgICAgIHZhciBfY2xpY2tIYW5kbGVyID0gZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XG5cbiAgICAgICAgICAgIHZhciAkc2VsZiA9ICQodGhpcyksXG4gICAgICAgICAgICAgICAgaW5kZXggPSAkc2VsZi5pbmRleCgpO1xuXG4gICAgICAgICAgICBpbmRleCA9IGR1cGxpY2F0ZXMgPyBpbmRleCAtIDEgOiBpbmRleDtcblxuICAgICAgICAgICAgLy8gU2V0IHRoZSBhY3RpdmUgc2xpZGVcbiAgICAgICAgICAgIF9zZXRBY3RpdmUoaW5kZXgpO1xuXG4gICAgICAgICAgICAvLyBJbmZvcm0gdGhlIG1haW4gc3dpcGVyXG4gICAgICAgICAgICAkdGFyZ2V0LnRyaWdnZXIoanNlLmxpYnMudGhlbWUuZXZlbnRzLlNXSVBFUl9HT1RPKCksIGluZGV4KTtcbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogRXZlbnQgdGhhdCBnZXRzIHRyaWdnZXJlZCBvbiBzbGlkZUNoYW5nZS5cbiAgICAgICAgICogSWYgdGhlIHNsaWRlIGdldHMgY2hhbmdlZCwgdGhlIGNvbnRyb2xzXG4gICAgICAgICAqIHdpbGwgZm9sbG93IHRoZSBjdXJyZW50IHNsaWRlIGluIHBvc2l0aW9uXG4gICAgICAgICAqIEBwcml2YXRlXG4gICAgICAgICAqL1xuICAgICAgICB2YXIgX3RyaWdnZXJTbGlkZUNoYW5nZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGlmICghcHJldmVudFNsaWRlU3RhcnQpIHtcbiAgICAgICAgICAgICAgICB2YXIgaW5kZXggPSBfZ2V0SW5kZXgoKSxcbiAgICAgICAgICAgICAgICAgICAgbGFzdEluZGV4ID0gJHNsaWRlcy5sZW5ndGggLSAyO1xuXG5cbiAgICAgICAgICAgICAgICAvLyBSZWNhbGN1bGF0ZSBpbmRleCBpZiBkdXBsaWNhdGUgc2xpZGVzIGFyZSBpbnNpZGUgdGhlIHNsaWRlclxuICAgICAgICAgICAgICAgIGlmIChpbmRleCA8IDApIHtcbiAgICAgICAgICAgICAgICAgICAgaW5kZXggPSAkc2xpZGVzLmxlbmd0aCAtIDM7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgaW5kZXggPSAoZHVwbGljYXRlcyAmJiBpbmRleCA9PT0gbGFzdEluZGV4KSA/IGluZGV4IC0gbGFzdEluZGV4IDogaW5kZXg7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgLy8gU2V0IHRoZSBhY3RpdmUgc2xpZGVcbiAgICAgICAgICAgICAgICBfc2V0QWN0aXZlKGluZGV4KTtcblxuICAgICAgICAgICAgICAgIC8vIEluZm9ybSB0aGUgY29udHJvbHNcbiAgICAgICAgICAgICAgICAkY29udHJvbHMudHJpZ2dlcihqc2UubGlicy50aGVtZS5ldmVudHMuU1dJUEVSX0dPVE8oKSwgaW5kZXgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuXG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIFdvcmthcm91bmQgZm9yIHRoZSB0cmFuc2x1Y2VuY2UgaXNzdWVcbiAgICAgICAgICogdGhhdCBoYXBwZW5zIG9uIHNtYWxsIHNjcmVlbnMgd2l0aCBlbmFibGVkXG4gICAgICAgICAqIGZhZGUgZWZmZWN0LiBNYXliZSBpdCBjYW4gYmUgcmVtb3ZlZCwgaWYgdGhlXG4gICAgICAgICAqIHN3aXBlciBnZXRzIHVwZGF0ZWQgaXRzZWxmXG4gICAgICAgICAqIEBwcml2YXRlXG4gICAgICAgICAqL1xuICAgICAgICB2YXIgX3RyYW5zbHVjZW5jZVdvcmthcm91bmQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBpZiAoIW9wdGlvbnMuZGlzYWJsZVRyYW5zbHVjZW5jZUZpeCAmJiBzbGlkZXJPcHRpb25zICYmIHNsaWRlck9wdGlvbnMuZWZmZWN0ID09PSAnZmFkZScpIHtcbiAgICAgICAgICAgICAgICAkdGhpcy5maW5kKCcuc3dpcGVyLXNsaWRlJylcbiAgICAgICAgICAgICAgICAgICAgLmZpbHRlcignOm5vdCguc3dpcGVyLXNsaWRlLWFjdGl2ZSknKVxuICAgICAgICAgICAgICAgICAgICAuZmFkZVRvKDMwMCwgMCwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgJCh0aGlzKS5jc3MoJ3Zpc2liaWxpdHknLCAnaGlkZGVuJyk7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgJHRoaXMuZmluZCgnLnN3aXBlci1zbGlkZScpXG4gICAgICAgICAgICAgICAgICAgIC5maWx0ZXIoJy5zd2lwZXItc2xpZGUtYWN0aXZlJylcbiAgICAgICAgICAgICAgICAgICAgLmZhZGVUbygzMDAsIDEsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICQodGhpcykuY3NzKCd2aXNpYmlsaXR5JywgJycpO1xuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIGJyZWFrcG9pbnQgaGFuZGxlciBpbml0aWFsaXplcyB0aGUgc3dpcGVyXG4gICAgICAgICAqIHdpdGggdGhlIHNldHRpbmdzIGZvciB0aGUgY3VycmVudCBicmVha3BvaW50LlxuICAgICAgICAgKiBUaGVyZWZvcmUgaXQgdXNlcyB0aGUgZGVmYXVsdCBzbGlkZXIgb3B0aW9ucyxcbiAgICAgICAgICogdGhlIGN1c3RvbSBzbGlkZXIgb3B0aW9ucyBnaXZlbiBieSB0aGUgb3B0aW9uc1xuICAgICAgICAgKiBvYmplY3QgYW5kIHRoZSBicmVha3BvaW50IG9wdGlvbnMgb2JqZWN0IGFsc29cbiAgICAgICAgICogZ2l2ZW4gYnkgdGhlIG9wdGlvbnMgKGluIHRoaXMgb3JkZXIpXG4gICAgICAgICAqIEBwcml2YXRlXG4gICAgICAgICAqL1xuICAgICAgICB2YXIgX2JyZWFrcG9pbnRIYW5kbGVyID0gZnVuY3Rpb24gKCkge1xuXG4gICAgICAgICAgICAvLyBHZXQgdGhlIGN1cnJlbnQgdmlld21vZGVcbiAgICAgICAgICAgIHZhciBvbGRNb2RlID0gbW9kZSB8fCB7fSxcbiAgICAgICAgICAgICAgICBuZXdNb2RlID0ganNlLmxpYnMudGhlbWUucmVzcG9uc2l2ZS5icmVha3BvaW50KCksXG4gICAgICAgICAgICAgICAgZXh0ZW5kT3B0aW9ucyA9IG9wdGlvbnMuYnJlYWtwb2ludHNbMF0gfHwge30sXG4gICAgICAgICAgICAgICAgbmV3QnJlYWtwb2ludERhdGFzZXQgPSBudWxsO1xuXG4gICAgICAgICAgICAvLyBPbmx5IGRvIHNvbWV0aGluZyBpZiB0aGUgdmlldyB3YXMgY2hhbmdlZFxuICAgICAgICAgICAgaWYgKG5ld01vZGUuaWQgIT09IG9sZE1vZGUuaWQpIHtcblxuICAgICAgICAgICAgICAgIC8vIFN0b3JlIHRoZSBuZXcgdmlld21vZGVcbiAgICAgICAgICAgICAgICBtb2RlID0gJC5leHRlbmQoe30sIG5ld01vZGUpO1xuXG4gICAgICAgICAgICAgICAgLy8gSXRlcmF0ZSB0aHJvdWdoIHRoZSBicmVha3BvaW50cyBvYmplY3QgdG8gZGV0ZWN0XG4gICAgICAgICAgICAgICAgLy8gdGhlIGNvcnJlY3Qgc2V0dGluZ3MgZm9yIHRoZSBjdXJyZW50IGJyZWFrcG9pbnRcbiAgICAgICAgICAgICAgICAkLmVhY2gob3B0aW9ucy5icmVha3BvaW50cywgZnVuY3Rpb24gKGksIHYpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHYuYnJlYWtwb2ludCA+IG5ld01vZGUuaWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBuZXdCcmVha3BvaW50RGF0YXNldCA9IGk7XG4gICAgICAgICAgICAgICAgICAgIGV4dGVuZE9wdGlvbnMgPSB2O1xuICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgaWYgKG9wdGlvbnMuc2xpZGVyT3B0aW9ucyAmJiBvcHRpb25zLnNsaWRlck9wdGlvbnMuYnJlYWtwb2ludHMpIHtcbiAgICAgICAgICAgICAgICAgICAgJC5lYWNoKG9wdGlvbnMuc2xpZGVyT3B0aW9ucy5icmVha3BvaW50cywgZnVuY3Rpb24gKGksIHYpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh2LmJyZWFrcG9pbnQgPT09IG5ld01vZGUuaWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBleHRlbmRPcHRpb25zID0gdjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIC8vIE9ubHkgZG8gc29tZXRoaW5nIGlmIHRoZSBzZXR0aW5ncyBjaGFuZ2UgZHVlIGJyb3dzZXJcbiAgICAgICAgICAgICAgICAvLyByZXNpemUgb3IgaWYgaXQncyB0aGUgZmlyc3QgdGltZSBydW5cbiAgICAgICAgICAgICAgICBpZiAobmV3QnJlYWtwb2ludERhdGFzZXQgIT09IGJyZWFrcG9pbnREYXRhc2V0IHx8IGluaXQpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gQ29tYmluZSB0aGUgc2V0dGluZ3NcbiAgICAgICAgICAgICAgICAgICAgc2xpZGVyT3B0aW9ucyA9ICQuZXh0ZW5kKHt9LCBzbGlkZXJEZWZhdWx0cywgb3B0aW9ucy5zbGlkZXJPcHRpb25zIHx8IHt9LCBleHRlbmRPcHRpb25zKTtcblxuICAgICAgICAgICAgICAgICAgICAvLyBBZGQgdGhlIHByZXZpZXcgaW1hZ2UgYnVsbGV0cyBmdW5jdGlvbiB0byB0aGUgb3B0aW9ucyBvYmplY3RcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNsaWRlck9wdGlvbnMudXNlUHJldmlld0J1bGxldHMgJiYgaGFzVGh1bWJuYWlscykge1xuICAgICAgICAgICAgICAgICAgICAgICAgc2xpZGVyT3B0aW9ucy5wYWdpbmF0aW9uQnVsbGV0UmVuZGVyID0gX2dlbmVyYXRlUHJldmlld0J1dHRvbnM7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAvLyBBZGQgdGhlIGF1dG9wbGF5IGludGVydmFsIHRvIHRoZSBvcHRpb25zIG9iamVjdFxuICAgICAgICAgICAgICAgICAgICBzbGlkZXJPcHRpb25zLmF1dG9wbGF5ID0gKHNsaWRlck9wdGlvbnMuYXV0b3BsYXkpID8gKHNsaWRlck9wdGlvbnMuYXV0b3BsYXkgKiAxMDAwKSA6IDA7XG5cbiAgICAgICAgICAgICAgICAgICAgLy8gRGlzYWJsZSBsb29wIGlmIHRoZXJlIGlzIG9ubHkgb25lIHNsaWRlci4gXG4gICAgICAgICAgICAgICAgICAgIGlmICgkdGhpcy5maW5kKCcuc3dpcGVyLXNsaWRlJykubGVuZ3RoID09PSAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzbGlkZXJPcHRpb25zLmxvb3AgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIC8vIElmIGFuIHN3aXBlciBleGlzdHMsIGdldCB0aGUgY3VycmVudFxuICAgICAgICAgICAgICAgICAgICAvLyBzbGlkZSBuby4gYW5kIHJlbW92ZSB0aGUgb2xkIHN3aXBlclxuICAgICAgICAgICAgICAgICAgICBpZiAoc3dpcGVyKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzbGlkZXJPcHRpb25zLmluaXRpYWxTbGlkZSA9IF9nZXRJbmRleCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzd2lwZXIuZGVzdHJveSh0cnVlLCB0cnVlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGlnbm9yZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN3aXBlciA9IG51bGw7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNsaWRlck9wdGlvbnMuaW5pdGlhbFNsaWRlID0gb3B0aW9ucy5pbml0U2xpZGUgfHwgc2xpZGVyT3B0aW9ucy5pbml0aWFsU2xpZGUgfHwgMDtcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIHZhciAkZHVwbGljYXRlID0gJHRoaXMuZmluZCgnLnN3aXBlci1zbGlkZTpub3QoLnN3aXBlci1zbGlkZS1kdXBsaWNhdGUpJyk7XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKCFvcHRpb25zLmF1dG9PZmYgfHwgKCRkdXBsaWNhdGUubGVuZ3RoID4gc2xpZGVyT3B0aW9ucy5zbGlkZXNQZXJWaWV3ICYmIG9wdGlvbnMuYXV0b09mZikpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLmFkZENsYXNzKCdzd2lwZXItaXMtYWN0aXZlJylcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAucmVtb3ZlQ2xhc3MoJ3N3aXBlci1pcy1ub3QtYWN0aXZlJyk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIEluaXRpYWxpemUgdGhlIHN3aXBlclxuICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzd2lwZXIgPSBuZXcgU3dpcGVyKCR0aGlzLCBzbGlkZXJPcHRpb25zKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47IC8vIFN3aXBlciBtaWdodCB0aHJvdyBhbiBlcnJvciB1cG9uIGluaXRpYWxpemF0aW9uIHRoYXQgc2hvdWxkIG5vdCBoYWx0IHRoZSBzY3JpcHQgZXhlY3V0aW9uLlxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICBzd2lwZXJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAub2ZmKCdvblRyYW5zaXRpb25FbmQgb25TbGlkZUNoYW5nZVN0YXJ0JylcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAub24oJ29uVHJhbnNpdGlvbkVuZCcsIF90cmFuc2x1Y2VuY2VXb3JrYXJvdW5kKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gSWYgdGhpcyBpcyBhIFwibWFpblwiIHN3aXBlciBhbmQgaGFzIGV4dGVybmFsIGNvbnRyb2xzLCBhblxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gZ290byBldmVudCBpcyB0cmlnZ2VyZWQgaWYgdGhlIGN1cnJlbnQgc2xpZGUgaXMgY2hhbmdlZFxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCRjb250cm9scy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzd2lwZXIub24oJ29uU2xpZGVDaGFuZ2VTdGFydCcsIF90cmlnZ2VyU2xpZGVDaGFuZ2UpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBBZGQgdGhlIGV2ZW50IGhhbmRsZXJcbiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLm9mZignbW91c2VlbnRlci5zd2lwZXIgbW91c2VsZWF2ZS5zd2lwZXIgJyArIGpzZS5saWJzLnRoZW1lLmV2ZW50cy5TV0lQRVJfR09UTygpICsgJyAnXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsganNlLmxpYnMudGhlbWUuZXZlbnRzLlNMSURFU19VUERBVEUoKSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAub24oJ21vdXNlZW50ZXIuc3dpcGVyJywgX21vdXNlRW50ZXJIYW5kbGVyKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5vbignbW91c2VsZWF2ZS5zd2lwZXInLCBfbW91c2VMZWF2ZUhhbmRsZXIpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLm9uKGpzZS5saWJzLnRoZW1lLmV2ZW50cy5TV0lQRVJfR09UTygpLCBfZ290b0hhbmRsZXIpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLm9uKGpzZS5saWJzLnRoZW1lLmV2ZW50cy5TTElERVNfVVBEQVRFKCksIF91cGRhdGVTbGlkZXMpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoaW5pdCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIENoZWNrIGlmIHRoZXJlIGFyZSBkdXBsaWNhdGVzIHNsaWRlcyAoZ2VuZXJhdGVkIGJ5IHRoZSBzd2lwZXIpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gYWZ0ZXIgdGhlIGZpcnN0IHRpbWUgaW5pdCBvZiB0aGUgc3dpcGVyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZHVwbGljYXRlcyA9ICEhJHRoaXMuZmluZCgnLnN3aXBlci1zbGlkZS1kdXBsaWNhdGUnKS5sZW5ndGg7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFNldCB0aGUgYWN0aXZlIHNsaWRlXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgaW5kZXggPSAoaW5pdCAmJiBvcHRpb25zLmluaXRTbGlkZSkgPyBvcHRpb25zLmluaXRTbGlkZSA6IF9nZXRJbmRleCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgX3NldEFjdGl2ZShpbmRleCk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIEluZm9ybSB0aGUgY29udHJvbHMgdGhhdCB0aGUgbWFpbiBzd2lwZXIgaGFzIGNoYW5nZWRcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIEluIGNhc2UgdGhhdCB0aGUgb3RoZXIgc2xpZGVyIGlzbid0IGluaXRpYWxpemVkIHlldCxcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIHNldCBhbiBkYXRhIGF0dHJpYnV0ZSB0byB0aGUgbWFya3VwIGVsZW1lbnQgdG8gaW5mb3JtXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBpdCBvbiBpbml0XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoJGNvbnRyb2xzLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICRjb250cm9scy5hdHRyKCdkYXRhLXN3aXBlci1pbml0LXNsaWRlJywgaW5kZXgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF90cmlnZ2VyU2xpZGVDaGFuZ2UoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gVW5zZXQgdGhlIGluaXQgZmxhZ1xuICAgICAgICAgICAgICAgICAgICAgICAgaW5pdCA9IGZhbHNlO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHN3aXBlci51cGRhdGUoKSk7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBEaXNhYmxlIHRoZSBzd2lwZXIgYnV0dG9uc1xuICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAucmVtb3ZlQ2xhc3MoJ3N3aXBlci1pcy1hY3RpdmUnKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5hZGRDbGFzcygnc3dpcGVyLWlzLW5vdC1hY3RpdmUnKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGluaXQgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogRXZlbnQgaGFuZGxlciB0aGF0IGFkZHMgJiByZW1vdmVzIHNsaWRlcyBmcm9tIHRoZVxuICAgICAgICAgKiBzd2lwZXIuIEFmdGVyIHRoZSBzbGlkZXMgd2VyZSBwcm9jZXNzZWQsIHRoZSBmaXJzdFxuICAgICAgICAgKiBzbGlkZSBpcyBzaG93blxuICAgICAgICAgKiBAcGFyYW0gICAgICAge29iamVjdH0gICAgZSAgICAgICBqUXVlcnkgZXZlbnQgb2JqZWN0XG4gICAgICAgICAqIEBwYXJhbSAgICAgICB7b2JqZWN0fSAgICBkICAgICAgIEpTT04gb2JqZWN0IHRoYXQgY29udGFpbnMgdGhlIGNhdGVnb3JpZXMgLyBpbWFnZXNcbiAgICAgICAgICogQHByaXZhdGVcbiAgICAgICAgICovXG4gICAgICAgIHZhciBfdXBkYXRlU2xpZGVzID0gZnVuY3Rpb24gKGUsIGQpIHtcblxuICAgICAgICAgICAgLy8gTG9vcHMgdGhyb3VnaCBlYWNoIGNhdGVnb3J5IGluc2lkZSB0aGUgaW1hZ2VzIGFycmF5XG4gICAgICAgICAgICAkLmVhY2goZCwgZnVuY3Rpb24gKGNhdGVnb3J5LCBkYXRhc2V0KSB7XG4gICAgICAgICAgICAgICAgdmFyIGNhdE5hbWUgPSBjYXRlZ29yeSArICctY2F0ZWdvcnknLFxuICAgICAgICAgICAgICAgICAgICBhZGQgPSBbXSxcbiAgICAgICAgICAgICAgICAgICAgcmVtb3ZlID0gW10sXG4gICAgICAgICAgICAgICAgICAgIG1hcmt1cCA9ICR0aGVtZS5odG1sKCk7XG5cbiAgICAgICAgICAgICAgICAvLyBHZXQgYWxsIGluZGV4ZXMgZnJvbSB0aGUgc2xpZGVzXG4gICAgICAgICAgICAgICAgLy8gb2YgdGhlIHNhbWUgY2F0ZWdvcnkgYW5kIHJlbW92ZVxuICAgICAgICAgICAgICAgIC8vIHRoZW0gZnJvbSB0aGUgc2xpZGVyXG4gICAgICAgICAgICAgICAgJHNsaWRlc1xuICAgICAgICAgICAgICAgICAgICAuZmlsdGVyKCcuJyArIGNhdE5hbWUpXG4gICAgICAgICAgICAgICAgICAgIC5lYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciAkc2VsZiA9ICQodGhpcyksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5kZXggPSAkc2VsZi5kYXRhKCkuc3dpcGVyU2xpZGVJbmRleDtcblxuICAgICAgICAgICAgICAgICAgICAgICAgaW5kZXggPSBpbmRleCA9PT0gdW5kZWZpbmVkID8gJHNlbGYuaW5kZXgoKSA6IGluZGV4O1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVtb3ZlLnB1c2goaW5kZXgpO1xuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBzd2lwZXIucmVtb3ZlU2xpZGUocmVtb3ZlKTtcblxuICAgICAgICAgICAgICAgIC8vIEdlbmVyYXRlIHRoZSBtYXJrdXAgZm9yIHRoZSBuZXcgc2xpZGVzXG4gICAgICAgICAgICAgICAgLy8gYW5kIGFkZCB0aGVtIHRvIHRoZSBzbGlkZXJcbiAgICAgICAgICAgICAgICAkLmVhY2goZGF0YXNldCB8fCBbXSwgZnVuY3Rpb24gKGksIHYpIHtcbiAgICAgICAgICAgICAgICAgICAgdi5jbGFzc05hbWUgPSBjYXROYW1lO1xuICAgICAgICAgICAgICAgICAgICB2LnNyY2F0dHIgPSAnc3JjPVwiJyArIHYuc3JjICsgJ1wiJztcbiAgICAgICAgICAgICAgICAgICAgYWRkLnB1c2goTXVzdGFjaGUucmVuZGVyKG1hcmt1cCwgdikpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIHN3aXBlci5hcHBlbmRTbGlkZShhZGQpO1xuXG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgJHNsaWRlcyA9ICR0aGlzLmZpbmQoJy5zd2lwZXItc2xpZGUnKTtcblxuICAgICAgICAgICAgLy8gVG8gcHJldmVudCBhbiBpbmNvbnNpc3RlbnQgc3RhdGVcbiAgICAgICAgICAgIC8vIGluIGNvbnRyb2wgLyBtYWluIHNsaWRlciBjb21iaW5hdGlvbnNcbiAgICAgICAgICAgIC8vIHNsaWRlIHRvIHRoZSBmaXJzdCBzbGlkZVxuICAgICAgICAgICAgX3NldEFjdGl2ZSgwKTtcbiAgICAgICAgICAgIHZhciBpbmRleCA9IGR1cGxpY2F0ZXMgPyAxIDogMDtcbiAgICAgICAgICAgIHN3aXBlci5zbGlkZVRvKGluZGV4LCAwKTtcblxuICAgICAgICB9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBQcmV2ZW50IHRleHQgc2VsZWN0aW9uIGJ5IGNsaWNraW5nIG9uIHN3aXBlciBidXR0b25zXG4gICAgICAgICAqIEBwcml2YXRlXG4gICAgICAgICAqL1xuICAgICAgICB2YXIgX3ByZXZlbnRUZXh0U2VsZWN0aW9uID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgJChvcHRpb25zLnNsaWRlck9wdGlvbnMubmV4dEJ1dHRvbikub24oJ3NlbGVjdHN0YXJ0JywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgJChvcHRpb25zLnNsaWRlck9wdGlvbnMucHJldkJ1dHRvbikub24oJ3NlbGVjdHN0YXJ0JywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBTZXRzIHRoZSBpbml0aWFsIGhlaWdodCBmb3Igb25lIHN3aXBlciBpbWFnZSBjb250YWluZXIgdG8gcHJldmVudCBjdXQgb2ZmIGltYWdlcyBvbiBzbWFsbGVyIHN3aXBlciBoZWlnaHRzXG4gICAgICAgICAqIEBwcml2YXRlXG4gICAgICAgICAqL1xuICAgICAgICB2YXIgX3NjYWxlVGh1bWJuYWlsSGVpZ2h0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgdmFyIHN3aXBlckNvbnRhaW5lciA9ICQoJy5zd2lwZXItY29udGFpbmVyLXZlcnRpY2FsIC5zd2lwZXItc2xpZGUnKTtcbiAgICAgICAgICAgIHZhciAkY29udGFpbmVySGVpZ2h0ID0gc3dpcGVyQ29udGFpbmVyLmNzcygnaGVpZ2h0Jyk7XG5cblxuICAgICAgICAgICAgLy8gV29ya2Fyb3VuZCBmb3IgSUUgQnJvd3NlcnNcbiAgICAgICAgICAgIGlmICgkKCcuc3dpcGVyLWNvbnRhaW5lci12ZXJ0aWNhbCcpLmhhc0NsYXNzKCdzd2lwZXItd3A4LXZlcnRpY2FsJykpIHtcbiAgICAgICAgICAgICAgICAkY29udGFpbmVySGVpZ2h0ID0gc3dpcGVyQ29udGFpbmVyLmhlaWdodCgpICsgNTtcblxuICAgICAgICAgICAgICAgIHN3aXBlckNvbnRhaW5lci5jc3MoJ2hlaWdodCcsICRjb250YWluZXJIZWlnaHQpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoJGNvbnRhaW5lckhlaWdodCA9PT0gJzBweCcpIHtcbiAgICAgICAgICAgICAgICAkY29udGFpbmVySGVpZ2h0ID0gJCgnLnByb2R1Y3QtaW5mby10aHVtYm5haWxzLW1vYmlsZScpLmNzcygnaGVpZ2h0Jyk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICQoJy5hbGlnbi1taWRkbGUnKS5jc3MoJ2hlaWdodCcsICRjb250YWluZXJIZWlnaHQpO1xuICAgICAgICB9O1xuXG4vLyAjIyMjIyMjIyMjIElOSVRJQUxJWkFUSU9OICMjIyMjIyMjIyNcblxuICAgICAgICAvKipcbiAgICAgICAgICogSW5pdCBmdW5jdGlvbiBvZiB0aGUgd2lkZ2V0XG4gICAgICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAgICAgKi9cbiAgICAgICAgbW9kdWxlLmluaXQgPSBmdW5jdGlvbiAoZG9uZSkge1xuXG4gICAgICAgICAgICAkc2xpZGVzID0gJHRoaXMuZmluZCgnLnN3aXBlci1zbGlkZScpO1xuICAgICAgICAgICAgJGNvbnRyb2xzID0gJChvcHRpb25zLmNvbnRyb2xzKTtcbiAgICAgICAgICAgICR0YXJnZXQgPSAkKG9wdGlvbnMudGFyZ2V0KTtcbiAgICAgICAgICAgICR0aGVtZSA9ICR0aGlzLmZpbmQoJ3RoZW1lJyk7XG5cbiAgICAgICAgICAgIC8vIENoZWNrIGlmIGFsbCBpbWFnZXMgaW5zaWRlIHRoZSBzd2lwZXIgaGF2ZVxuICAgICAgICAgICAgLy8gdGh1bWJuYWlsIGltYWdlIGdpdmVuXG4gICAgICAgICAgICAkc2xpZGVzLmVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIGlmICghJCh0aGlzKS5kYXRhKCkudGh1bWJJbWFnZSkge1xuICAgICAgICAgICAgICAgICAgICBoYXNUaHVtYm5haWxzID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgLy8gQWRkIHRoZSBicmVha3BvaW50IGhhbmRsZXIgdHkgZHluYW1pY2FsbHlcbiAgICAgICAgICAgIC8vIHNldCB0aGUgb3B0aW9ucyBjb3JyZXNwb25kaW5nIHRvIHRoZSBicm93c2VyIHNpemUgKHNsaWRlciByZXNwb25zaXZlIHdpbGwgcmUtaW5pdGlhbGl6ZSB0aGUgc3dpcGVyKS5cbiAgICAgICAgICAgIF9icmVha3BvaW50SGFuZGxlcigpO1xuXG4gICAgICAgICAgICAvLyBJZiB0aGlzIGluc3RhbmNlIGlzIGEgXCJjb250cm9sXCIgc3dpcGVyIHRoZSB0YXJnZXQgaXMgdGhlIG1haW4gc3dpcGVyXG4gICAgICAgICAgICAvLyB3aGljaCB3aWxsIGJlIHVwZGF0ZWQgb24gYSBjbGljayBpbnNpZGUgdGhpcyBjb250cm9sIHN3aXBlclxuICAgICAgICAgICAgaWYgKG9wdGlvbnMudGFyZ2V0KSB7XG4gICAgICAgICAgICAgICAgJHRoaXMub24oJ2NsaWNrLnN3aXBlcicsICcuc3dpcGVyLXNsaWRlJywgX2NsaWNrSGFuZGxlcik7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICQoZG9jdW1lbnQpLnJlYWR5KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAkKCcuc3dpcGVyLXZlcnRpY2FsIC5zd2lwZXItc2xpZGVbZGF0YS1pbmRleF0nKS5jc3MoJ2Rpc3BsYXknLCAnaW5saW5lLWJsb2NrJyk7XG4gICAgICAgICAgICAgICAgJCgnLnByb2R1Y3QtaW5mby1pbWFnZSAuc3dpcGVyLXNsaWRlW2RhdGEtaW5kZXhdJykuY3NzKCd6LWluZGV4JywgJ2luaGVyaXQnKTtcbiAgICAgICAgICAgICAgICAkKCcucHJvZHVjdC1pbmZvLWltYWdlIC5zd2lwZXItc2xpZGVbZGF0YS1pbmRleF0gLnN3aXBlci1zbGlkZS1pbnNpZGUgaW1nLmltZy1yZXNwb25zaXZlJykuZmFkZUluKDEwMDApO1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIF90cmFuc2x1Y2VuY2VXb3JrYXJvdW5kKCk7XG4gICAgICAgICAgICBfcHJldmVudFRleHRTZWxlY3Rpb24oKTtcbiAgICAgICAgICAgIF9zY2FsZVRodW1ibmFpbEhlaWdodCgpO1xuXG4gICAgICAgICAgICAvLyBGaXggZm9yIGludmlzaWJsZSBUaHVtYm5haWwtSW1hZ2VzIGZvciBzd2l0Y2hpbmcgZnJvbSBUYWJsZXQtUG9ydHJhaXQgdG8gVGFibGV0LUxhbmRzY2FwZVxuICAgICAgICAgICAgJGJvZHkub24oanNlLmxpYnMudGhlbWUuZXZlbnRzLkJSRUFLUE9JTlQoKSwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIF9zY2FsZVRodW1ibmFpbEhlaWdodCgpO1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIGRvbmUoKTtcbiAgICAgICAgfTtcblxuICAgICAgICAvLyBSZXR1cm4gZGF0YSB0byB3aWRnZXQgZW5naW5lXG4gICAgICAgIHJldHVybiBtb2R1bGU7XG4gICAgfSk7XG4iXX0=