ng2-tooltip-directive
Version:
Tooltip for Angular
486 lines • 52.4 kB
JavaScript
import { Directive, HostListener, Input, Output, EventEmitter, Inject, Optional } from '@angular/core';
import { TooltipComponent } from './tooltip.component';
import { TooltipOptionsService } from './options.service';
import { defaultOptions, backwardCompatibilityOptions } from './options';
import * as i0 from "@angular/core";
export class TooltipDirective {
constructor(initOptions, elementRef, componentFactoryResolver, appRef, injector) {
this.initOptions = initOptions;
this.elementRef = elementRef;
this.componentFactoryResolver = componentFactoryResolver;
this.appRef = appRef;
this.injector = injector;
this._options = {};
this._contentType = "string";
this.events = new EventEmitter();
}
set options(value) {
if (value && defaultOptions) {
this._options = value;
}
}
get options() {
return this._options;
}
// Content type
set contentTypeBackwardCompatibility(value) {
if (value) {
this._contentType = value;
}
}
set contentType(value) {
if (value) {
this._contentType = value;
}
}
get contentType() {
return this._contentType;
}
// z-index
set zIndexBackwardCompatibility(value) {
if (value) {
this._zIndex = value;
}
}
set zIndex(value) {
if (value) {
this._zIndex = value;
}
}
get zIndex() {
return this._zIndex;
}
// Animation duration
set animationDurationBackwardCompatibility(value) {
if (value) {
this._animationDuration = value;
}
}
set animationDuration(value) {
if (value) {
this._animationDuration = value;
}
}
get animationDuration() {
return this._animationDuration;
}
// Tooltip class
set tooltipClassBackwardCompatibility(value) {
if (value) {
this._tooltipClass = value;
}
}
set tooltipClass(value) {
if (value) {
this._tooltipClass = value;
}
}
get tooltipClass() {
return this._tooltipClass;
}
// Max width
set maxWidthBackwardCompatibility(value) {
if (value) {
this._maxWidth = value;
}
}
set maxWidth(value) {
if (value) {
this._maxWidth = value;
}
}
get maxWidth() {
return this._maxWidth;
}
// Show delay
set showDelayBackwardCompatibility(value) {
if (value) {
this._showDelay = value;
}
}
set showDelay(value) {
if (value) {
this._showDelay = value;
}
}
get showDelay() {
return this._showDelay;
}
// Hide delay
set hideDelayBackwardCompatibility(value) {
if (value) {
this._hideDelay = value;
}
}
set hideDelay(value) {
if (value) {
this._hideDelay = value;
}
}
get hideDelay() {
return this._hideDelay;
}
get isTooltipDestroyed() {
return this.componentRef && this.componentRef.hostView.destroyed;
}
get destroyDelay() {
if (this._destroyDelay) {
return this._destroyDelay;
}
else {
return Number(this.getHideDelay()) + Number(this.options['animationDuration']);
}
}
set destroyDelay(value) {
this._destroyDelay = value;
}
get tooltipPosition() {
if (this.options['position']) {
return this.options['position'];
}
else {
return this.elementPosition;
}
}
onMouseEnter() {
if (this.isDisplayOnHover == false) {
return;
}
this.show();
}
onMouseLeave() {
if (this.options['trigger'] === 'hover') {
this.destroyTooltip();
}
}
onClick() {
if (this.isDisplayOnClick == false) {
return;
}
this.show();
this.hideAfterClickTimeoutId = window.setTimeout(() => {
this.destroyTooltip();
}, this.options['hideDelayAfterClick']);
}
ngOnInit() {
}
ngOnChanges(changes) {
this.initOptions = this.renameProperties(this.initOptions);
let changedOptions = this.getProperties(changes);
changedOptions = this.renameProperties(changedOptions);
this.applyOptionsDefault(defaultOptions, changedOptions);
}
ngOnDestroy() {
this.destroyTooltip({
fast: true
});
if (this.componentSubscribe) {
this.componentSubscribe.unsubscribe();
}
}
getShowDelay() {
return this.options['showDelay'];
}
getHideDelay() {
const hideDelay = this.options['hideDelay'];
const hideDelayTouchscreen = this.options['hideDelayTouchscreen'];
return this.isTouchScreen ? hideDelayTouchscreen : hideDelay;
}
getProperties(changes) {
let directiveProperties = {};
let customProperties = {};
let allProperties = {};
for (var prop in changes) {
if (prop !== 'options' && prop !== 'tooltipValue') {
directiveProperties[prop] = changes[prop].currentValue;
}
if (prop === 'options') {
customProperties = changes[prop].currentValue;
}
}
allProperties = Object.assign({}, customProperties, directiveProperties);
return allProperties;
}
renameProperties(options) {
for (var prop in options) {
if (backwardCompatibilityOptions[prop]) {
options[backwardCompatibilityOptions[prop]] = options[prop];
delete options[prop];
}
}
return options;
}
getElementPosition() {
this.elementPosition = this.elementRef.nativeElement.getBoundingClientRect();
}
createTooltip() {
this.clearTimeouts();
this.getElementPosition();
this.createTimeoutId = window.setTimeout(() => {
this.appendComponentToBody(TooltipComponent);
}, this.getShowDelay());
this.showTimeoutId = window.setTimeout(() => {
this.showTooltipElem();
}, this.getShowDelay());
}
destroyTooltip(options = {
fast: false
}) {
this.clearTimeouts();
if (this.isTooltipDestroyed == false) {
this.hideTimeoutId = window.setTimeout(() => {
this.hideTooltip();
}, options.fast ? 0 : this.getHideDelay());
this.destroyTimeoutId = window.setTimeout(() => {
if (!this.componentRef || this.isTooltipDestroyed) {
return;
}
this.appRef.detachView(this.componentRef.hostView);
this.componentRef.destroy();
this.events.emit({
type: 'hidden',
position: this.tooltipPosition
});
}, options.fast ? 0 : this.destroyDelay);
}
}
showTooltipElem() {
this.clearTimeouts();
this.componentRef.instance.show = true;
this.events.emit({
type: 'show',
position: this.tooltipPosition
});
}
hideTooltip() {
if (!this.componentRef || this.isTooltipDestroyed) {
return;
}
this.componentRef.instance.show = false;
this.events.emit({
type: 'hide',
position: this.tooltipPosition
});
}
appendComponentToBody(component, data = {}) {
this.componentRef = this.componentFactoryResolver
.resolveComponentFactory(component)
.create(this.injector);
this.componentRef.instance.data = {
value: this.tooltipValue,
element: this.elementRef.nativeElement,
elementPosition: this.tooltipPosition,
options: this.options
};
this.appRef.attachView(this.componentRef.hostView);
const domElem = this.componentRef.hostView.rootNodes[0];
document.body.appendChild(domElem);
this.componentSubscribe = this.componentRef.instance.events.subscribe((event) => {
this.handleEvents(event);
});
}
clearTimeouts() {
if (this.createTimeoutId) {
clearTimeout(this.createTimeoutId);
}
if (this.showTimeoutId) {
clearTimeout(this.showTimeoutId);
}
if (this.hideTimeoutId) {
clearTimeout(this.hideTimeoutId);
}
if (this.destroyTimeoutId) {
clearTimeout(this.destroyTimeoutId);
}
}
get isDisplayOnHover() {
if (this.options['display'] == false) {
return false;
}
if (this.options['displayTouchscreen'] == false && this.isTouchScreen) {
return false;
}
if (this.options['trigger'] !== 'hover') {
return false;
}
return true;
}
get isDisplayOnClick() {
if (this.options['display'] == false) {
return false;
}
if (this.options['displayTouchscreen'] == false && this.isTouchScreen) {
return false;
}
if (this.options['trigger'] != 'click') {
return false;
}
return true;
}
get isTouchScreen() {
var prefixes = ' -webkit- -moz- -o- -ms- '.split(' ');
var mq = function (query) {
return window.matchMedia(query).matches;
};
if (('ontouchstart' in window)) {
return true;
}
// include the 'heartz' as a way to have a non matching MQ to help terminate the join
// https://git.io/vznFH
var query = ['(', prefixes.join('touch-enabled),('), 'heartz', ')'].join('');
return mq(query);
}
applyOptionsDefault(defaultOptions, options) {
this.options = Object.assign({}, defaultOptions, this.initOptions || {}, this.options, options);
}
handleEvents(event) {
if (event.type === 'shown') {
this.events.emit({
type: 'shown',
position: this.tooltipPosition
});
}
}
show() {
if (!this.tooltipValue) {
return;
}
if (!this.componentRef || this.isTooltipDestroyed) {
this.createTooltip();
}
else if (!this.isTooltipDestroyed) {
this.showTooltipElem();
}
}
hide() {
this.destroyTooltip();
}
}
TooltipDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.0.3", ngImport: i0, type: TooltipDirective, deps: [{ token: TooltipOptionsService, optional: true }, { token: i0.ElementRef }, { token: i0.ComponentFactoryResolver }, { token: i0.ApplicationRef }, { token: i0.Injector }], target: i0.ɵɵFactoryTarget.Directive });
TooltipDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "12.0.3", type: TooltipDirective, selector: "[tooltip]", inputs: { options: "options", tooltipValue: ["tooltip", "tooltipValue"], placement: "placement", autoPlacement: "autoPlacement", contentTypeBackwardCompatibility: ["content-type", "contentTypeBackwardCompatibility"], contentType: "contentType", hideDelayMobile: ["hide-delay-mobile", "hideDelayMobile"], hideDelayTouchscreen: "hideDelayTouchscreen", zIndexBackwardCompatibility: ["z-index", "zIndexBackwardCompatibility"], zIndex: "zIndex", animationDurationBackwardCompatibility: ["animation-duration", "animationDurationBackwardCompatibility"], animationDuration: "animationDuration", trigger: "trigger", tooltipClassBackwardCompatibility: ["tooltip-class", "tooltipClassBackwardCompatibility"], tooltipClass: "tooltipClass", display: "display", displayMobile: ["display-mobile", "displayMobile"], displayTouchscreen: "displayTouchscreen", shadow: "shadow", theme: "theme", offset: "offset", width: "width", maxWidthBackwardCompatibility: ["max-width", "maxWidthBackwardCompatibility"], maxWidth: "maxWidth", id: "id", showDelayBackwardCompatibility: ["show-delay", "showDelayBackwardCompatibility"], showDelay: "showDelay", hideDelayBackwardCompatibility: ["hide-delay", "hideDelayBackwardCompatibility"], hideDelay: "hideDelay", hideDelayAfterClick: "hideDelayAfterClick", pointerEvents: "pointerEvents", position: "position" }, outputs: { events: "events" }, host: { listeners: { "focusin": "onMouseEnter()", "mouseenter": "onMouseEnter()", "focusout": "onMouseLeave()", "mouseleave": "onMouseLeave()", "click": "onClick()" } }, exportAs: ["tooltip"], usesOnChanges: true, ngImport: i0 });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.0.3", ngImport: i0, type: TooltipDirective, decorators: [{
type: Directive,
args: [{
selector: '[tooltip]',
exportAs: 'tooltip',
}]
}], ctorParameters: function () { return [{ type: undefined, decorators: [{
type: Optional
}, {
type: Inject,
args: [TooltipOptionsService]
}] }, { type: i0.ElementRef }, { type: i0.ComponentFactoryResolver }, { type: i0.ApplicationRef }, { type: i0.Injector }]; }, propDecorators: { options: [{
type: Input,
args: ['options']
}], tooltipValue: [{
type: Input,
args: ['tooltip']
}], placement: [{
type: Input,
args: ['placement']
}], autoPlacement: [{
type: Input,
args: ['autoPlacement']
}], contentTypeBackwardCompatibility: [{
type: Input,
args: ['content-type']
}], contentType: [{
type: Input,
args: ['contentType']
}], hideDelayMobile: [{
type: Input,
args: ['hide-delay-mobile']
}], hideDelayTouchscreen: [{
type: Input,
args: ['hideDelayTouchscreen']
}], zIndexBackwardCompatibility: [{
type: Input,
args: ['z-index']
}], zIndex: [{
type: Input,
args: ['zIndex']
}], animationDurationBackwardCompatibility: [{
type: Input,
args: ['animation-duration']
}], animationDuration: [{
type: Input,
args: ['animationDuration']
}], trigger: [{
type: Input,
args: ['trigger']
}], tooltipClassBackwardCompatibility: [{
type: Input,
args: ['tooltip-class']
}], tooltipClass: [{
type: Input,
args: ['tooltipClass']
}], display: [{
type: Input,
args: ['display']
}], displayMobile: [{
type: Input,
args: ['display-mobile']
}], displayTouchscreen: [{
type: Input,
args: ['displayTouchscreen']
}], shadow: [{
type: Input,
args: ['shadow']
}], theme: [{
type: Input,
args: ['theme']
}], offset: [{
type: Input,
args: ['offset']
}], width: [{
type: Input,
args: ['width']
}], maxWidthBackwardCompatibility: [{
type: Input,
args: ['max-width']
}], maxWidth: [{
type: Input,
args: ['maxWidth']
}], id: [{
type: Input,
args: ['id']
}], showDelayBackwardCompatibility: [{
type: Input,
args: ['show-delay']
}], showDelay: [{
type: Input,
args: ['showDelay']
}], hideDelayBackwardCompatibility: [{
type: Input,
args: ['hide-delay']
}], hideDelay: [{
type: Input,
args: ['hideDelay']
}], hideDelayAfterClick: [{
type: Input,
args: ['hideDelayAfterClick']
}], pointerEvents: [{
type: Input,
args: ['pointerEvents']
}], position: [{
type: Input,
args: ['position']
}], events: [{
type: Output
}], onMouseEnter: [{
type: HostListener,
args: ['focusin']
}, {
type: HostListener,
args: ['mouseenter']
}], onMouseLeave: [{
type: HostListener,
args: ['focusout']
}, {
type: HostListener,
args: ['mouseleave']
}], onClick: [{
type: HostListener,
args: ['click']
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidG9vbHRpcC5kaXJlY3RpdmUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9uZzItdG9vbHRpcC1kaXJlY3RpdmUvc3JjL2xpYi90b29sdGlwLmRpcmVjdGl2ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFjLFlBQVksRUFBRSxLQUFLLEVBQTZGLE1BQU0sRUFBRSxZQUFZLEVBQWEsTUFBTSxFQUFFLFFBQVEsRUFBaUIsTUFBTSxlQUFlLENBQUM7QUFDeE8sT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDdkQsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFDMUQsT0FBTyxFQUFFLGNBQWMsRUFBRSw0QkFBNEIsRUFBRSxNQUFNLFdBQVcsQ0FBQzs7QUFlekUsTUFBTSxPQUFPLGdCQUFnQjtJQTBMekIsWUFDdUQsV0FBZSxFQUMxRCxVQUFzQixFQUN0Qix3QkFBa0QsRUFDbEQsTUFBc0IsRUFDdEIsUUFBa0I7UUFKeUIsZ0JBQVcsR0FBWCxXQUFXLENBQUk7UUFDMUQsZUFBVSxHQUFWLFVBQVUsQ0FBWTtRQUN0Qiw2QkFBd0IsR0FBeEIsd0JBQXdCLENBQTBCO1FBQ2xELFdBQU0sR0FBTixNQUFNLENBQWdCO1FBQ3RCLGFBQVEsR0FBUixRQUFRLENBQVU7UUFyTDlCLGFBQVEsR0FBUSxFQUFFLENBQUM7UUFJbkIsaUJBQVksR0FBbUMsUUFBUSxDQUFDO1FBMEs5QyxXQUFNLEdBQXlCLElBQUksWUFBWSxFQUFXLENBQUM7SUFPcEMsQ0FBQztJQXpLbEMsSUFBc0IsT0FBTyxDQUFDLEtBQXFCO1FBQy9DLElBQUksS0FBSyxJQUFJLGNBQWMsRUFBRTtZQUN6QixJQUFJLENBQUMsUUFBUSxHQUFHLEtBQUssQ0FBQztTQUN6QjtJQUNMLENBQUM7SUFDRCxJQUFJLE9BQU87UUFDUCxPQUFPLElBQUksQ0FBQyxRQUFRLENB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V0FBVztnQkFVTyw4QkFBOEI7c0JBQXRELEtBQUs7dUJBQUMsWUFBWTtnQkFLSyxTQUFTO3NCQUFoQyxLQUFLO3VCQUFDLFdBQVc7Z0JBU1ksbUJBQW1CO3NCQUFoRCxLQUFLO3VCQUFDLHFCQUFxQjtnQkFDSixhQUFhO3NCQUFwQyxLQUFLO3VCQUFDLGVBQWU7Z0JBQ0gsUUFBUTtzQkFBMUIsS0FBSzt1QkFBQyxVQUFVO2dCQXlCUCxNQUFNO3NCQUFmLE1BQU07Z0JBV1AsWUFBWTtzQkFGWCxZQUFZO3VCQUFDLFNBQVM7O3NCQUN0QixZQUFZO3VCQUFDLFlBQVk7Z0JBVzFCLFlBQVk7c0JBRlgsWUFBWTt1QkFBQyxVQUFVOztzQkFDdkIsWUFBWTt1QkFBQyxZQUFZO2dCQVExQixPQUFPO3NCQUROLFlBQVk7dUJBQUMsT0FBTyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IERpcmVjdGl2ZSwgRWxlbWVudFJlZiwgSG9zdExpc3RlbmVyLCBJbnB1dCwgQ29tcG9uZW50RmFjdG9yeVJlc29sdmVyLCBFbWJlZGRlZFZpZXdSZWYsIEFwcGxpY2F0aW9uUmVmLCBJbmplY3RvciwgQ29tcG9uZW50UmVmLCBPbkluaXQsIE91dHB1dCwgRXZlbnRFbWl0dGVyLCBPbkRlc3Ryb3ksIEluamVjdCwgT3B0aW9uYWwsIFNpbXBsZUNoYW5nZXMgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgVG9vbHRpcENvbXBvbmVudCB9IGZyb20gJy4vdG9vbHRpcC5jb21wb25lbnQnO1xyXG5pbXBvcnQgeyBUb29sdGlwT3B0aW9uc1NlcnZpY2UgfSBmcm9tICcuL29wdGlvbnMuc2VydmljZSc7XHJcbmltcG9ydCB7IGRlZmF1bHRPcHRpb25zLCBiYWNrd2FyZENvbXBhdGliaWxpdHlPcHRpb25zIH0gZnJvbSAnLi9vcHRpb25zJztcclxuaW1wb3J0IHsgVG9vbHRpcE9wdGlvbnMgfSBmcm9tICcuL29wdGlvbnMuaW50ZXJmYWNlJztcclxuXHJcbmV4cG9ydCBpbnRlcmZhY2UgQWRDb21wb25lbnQge1xyXG4gICAgZGF0YTogYW55O1xyXG4gICAgc2hvdzogYm9vbGVhbjtcclxuICAgIGNsb3NlOiBib29sZWFuO1xyXG4gICAgZXZlbnRzOiBhbnk7XHJcbn1cclxuXHJcbkBEaXJlY3RpdmUoe1xyXG4gICAgc2VsZWN0b3I6ICdbdG9vbHRpcF0nLFxyXG4gICAgZXhwb3J0QXM6ICd0b29sdGlwJyxcclxufSlcclxuXHJcbmV4cG9ydCBjbGFzcyBUb29sdGlwRGlyZWN0aXZlIHtcclxuXHJcbiAgICBoaWRlVGltZW91dElkITogbnVtYmVyO1xyXG4gICAgZGVzdHJveVRpbWVvdXRJZCE6IG51bWJlcjtcclxuICAgIGhpZGVBZnRlckNsaWNrVGltZW91dElkITogbnVtYmVyO1xyXG4gICAgY3JlYXRlVGltZW91dElkITogbnVtYmVyO1xyXG4gICAgc2hvd1RpbWVvdXRJZCE6IG51bWJlcjtcclxuICAgIGNvbXBvbmVudFJlZjogYW55O1xyXG4gICAgZWxlbWVudFBvc2l0aW9uOiBhbnk7XHJcbiAgICBfaWQ6IGFueTtcclxuICAgIF9vcHRpb25zOiBhbnkgPSB7fTtcclxuICAgIF9kZWZhdWx0T3B0aW9uczogYW55O1xyXG4gICAgX2Rlc3Ryb3lEZWxheSE6IG51bWJlcjtcclxuICAgIGNvbXBvbmVudFN1YnNjcmliZTogYW55O1xyXG4gICAgX2NvbnRlbnRUeXBlOiBcInN0cmluZ1wiIHwgXCJodG1sXCIgfCBcInRlbXBsYXRlXCIgPSBcInN0cmluZ1wiO1xyXG4gICAgX3Nob3dEZWxheSE6IG51bWJlcjtcclxuICAgIF9oaWRlRGVsYXkhOiBudW1iZXI7XHJcbiAgICBfekluZGV4ITogbnVtYmVyO1xyXG4gICAgX3Rvb2x0aXBDbGFzcyE6IHN0cmluZztcclxuICAgIF9hbmltYXRpb25EdXJhdGlvbiE6IG51bWJlcjtcclxuICAgIF9tYXhXaWR0aCE6IHN0cmluZztcclxuXHJcbiAgICBASW5wdXQoJ29wdGlvbnMnKSBzZXQgb3B0aW9ucyh2YWx1ZTogVG9vbHRpcE9wdGlvbnMpIHtcclxuICAgICAgICBpZiAodmFsdWUgJiYgZGVmYXVsdE9wdGlvbnMpIHtcclxuICAgICAgICAgICAgdGhpcy5fb3B0aW9ucyA9IHZhbHVlO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIGdldCBvcHRpb25zKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9vcHRpb25zO1xyXG4gICAgfVxyXG5cclxuICAgIEBJbnB1dCgndG9vbHRpcCcpIHRvb2x0aXBWYWx1ZSE6IHN0cmluZztcclxuICAgIEBJbnB1dCgncGxhY2VtZW50JykgcGxhY2VtZW50ITogc3RyaW5nO1xyXG4gICAgQElucHV0KCdhdXRvUGxhY2VtZW50JykgYXV0b1BsYWNlbWVudCE6IGJvb2xlYW47XHJcblxyXG4gICAgLy8gQ29udGVudCB0eXBlXHJcbiAgICBASW5wdXQoJ2NvbnRlbnQtdHlwZScpIHNldCBjb250ZW50VHlwZUJhY2t3YXJkQ29tcGF0aWJpbGl0eSh2YWx1ZTogXCJzdHJpbmdcIiB8IFwiaHRtbFwiIHwgXCJ0ZW1wbGF0ZVwiKSB7XHJcbiAgICAgICAgaWYgKHZhbHVlKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX2NvbnRlbnRUeXBlID0gdmFsdWU7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgQElucHV0KCdjb250ZW50VHlwZScpIHNldCBjb250ZW50VHlwZSh2YWx1ZTogXCJzdHJpbmdcIiB8IFwiaHRtbFwiIHwgXCJ0ZW1wbGF0ZVwiKSB7XHJcbiAgICAgICAgaWYgKHZhbHVlKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX2NvbnRlbnRUeXBlID0gdmFsdWU7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgZ2V0IGNvbnRlbnRUeXBlKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9jb250ZW50VHlwZTtcclxuICAgIH1cclxuXHJcbiAgICBASW5wdXQoJ2hpZGUtZGVsYXktbW9iaWxlJykgaGlkZURlbGF5TW9iaWxlITogbnVtYmVyO1xyXG4gICAgQElucHV0KCdoaWRlRGVsYXlUb3VjaHNjcmVlbicpIGhpZGVEZWxheVRvdWNoc2NyZWVuITogbnVtYmVyO1xyXG5cclxuICAgIC8vIHotaW5kZXhcclxuICAgIEBJbnB1dCgnei1pbmRleCcpIHNldCB6SW5kZXhCYWNrd2FyZENvbXBhdGliaWxpdHkodmFsdWU6IG51bWJlcikge1xyXG4gICAgICAgIGlmICh2YWx1ZSkge1xyXG4gICAgICAgICAgICB0aGlzLl96SW5kZXggPSB2YWx1ZTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICBASW5wdXQoJ3pJbmRleCcpIHNldCB6SW5kZXgodmFsdWU6IG51bWJlcikge1xyXG4gICAgICAgIGlmICh2YWx1ZSkge1xyXG4gICAgICAgICAgICB0aGlzLl96SW5kZXggPSB2YWx1ZTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICBnZXQgekluZGV4KCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl96SW5kZXg7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gQW5pbWF0aW9uIGR1cmF0aW9uXHJcbiAgICBASW5wdXQoJ2FuaW1hdGlvbi1kdXJhdGlvbicpIHNldCBhbmltYXRpb25EdXJhdGlvbkJhY2t3YXJkQ29tcGF0aWJpbGl0eSh2YWx1ZTogbnVtYmVyKSB7XHJcbiAgICAgICAgaWYgKHZhbHVlKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX2FuaW1hdGlvbkR1cmF0aW9uID0gdmFsdWU7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgQElucHV0KCdhbmltYXRpb25EdXJhdGlvbicpIHNldCBhbmltYXRpb25EdXJhdGlvbih2YWx1ZTogbnVtYmVyKSB7XHJcbiAgICAgICAgaWYgKHZhbHVlKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX2FuaW1hdGlvbkR1cmF0aW9uID0gdmFsdWU7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgZ2V0IGFuaW1hdGlvbkR1cmF0aW9uKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9hbmltYXRpb25EdXJhdGlvbjtcclxuICAgIH1cclxuXHJcblxyXG4gICAgQElucHV0KCd0cmlnZ2VyJykgdHJpZ2dlciE6IHN0cmluZztcclxuXHJcbiAgICAvLyBUb29sdGlwIGNsYXNzXHJcbiAgICBASW5wdXQoJ3Rvb2x0aXAtY2xhc3MnKSBzZXQgdG9vbHRpcENsYXNzQmFja3dhcmRDb21wYXRpYmlsaXR5KHZhbHVlOiBzdHJpbmcpIHtcclxuICAgICAgICBpZiAodmFsdWUpIHtcclxuICAgICAgICAgICAgdGhpcy5fdG9vbHRpcENsYXNzID0gdmFsdWU7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgQElucHV0KCd0b29sdGlwQ2xhc3MnKSBzZXQgdG9vbHRpcENsYXNzKHZhbHVlOiBzdHJpbmcpIHtcclxuICAgICAgICBpZiAodmFsdWUpIHtcclxuICAgICAgICAgICAgdGhpcy5fdG9vbHRpcENsYXNzID0gdmFsdWU7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgZ2V0IHRvb2x0aXBDbGFzcygpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fdG9vbHRpcENsYXNzO1xyXG4gICAgfVxyXG5cclxuICAgIEBJbnB1dCgnZGlzcGxheScpIGRpc3BsYXkhOiBib29sZWFuO1xyXG4gICAgQElucHV0KCdkaXNwbGF5LW1vYmlsZScpIGRpc3BsYXlNb2JpbGUhOiBib29sZWFuO1xyXG4gICAgQElucHV0KCdkaXNwbGF5VG91Y2hzY3JlZW4nKSBkaXNwbGF5VG91Y2hzY3JlZW4hOiBib29sZWFuO1xyXG4gICAgQElucHV0KCdzaGFkb3cnKSBzaGFkb3chOiBib29sZWFuO1xyXG4gICAgQElucHV0KCd0aGVtZScpIHRoZW1lITogXCJkYXJrXCIgfCBcImxpZ2h0XCI7XHJcbiAgICBASW5wdXQoJ29mZnNldCcpIG9mZnNldCE6IG51bWJlcjtcclxuICAgIEBJbnB1dCgnd2lkdGgnKSB3aWR0aCE6IHN0cmluZztcclxuXHJcbiAgICAvLyBNYXggd2lkdGhcclxuICAgIEBJbnB1dCgnbWF4LXdpZHRoJykgc2V0IG1heFdpZHRoQmFja3dhcmRDb21wYXRpYmlsaXR5KHZhbHVlOiBzdHJpbmcpIHtcclxuICAgICAgICBpZiAodmFsdWUpIHtcclxuICAgICAgICAgICAgdGhpcy5fbWF4V2lkdGggPSB2YWx1ZTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICBASW5wdXQoJ21heFdpZHRoJykgc2V0IG1heFdpZHRoKHZhbHVlOiBzdHJpbmcpIHtcclxuICAgICAgICBpZiAodmFsdWUpIHtcclxuICAgICAgICAgICAgdGhpcy5fbWF4V2lkdGggPSB2YWx1ZTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICBnZXQgbWF4V2lkdGgoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX21heFdpZHRoO1xyXG4gICAgfVxyXG5cclxuXHJcbiAgICBASW5wdXQoJ2lkJykgaWQ6IGFueTtcclxuXHJcbiAgICAvLyBTaG93IGRlbGF5XHJcbiAgICBASW5wdXQoJ3Nob3ctZGVsYXknKSBzZXQgc2hvd0RlbGF5QmFja3dhcmRDb21wYXRpYmlsaXR5KHZhbHVlOiBudW1iZXIpIHtcclxuICAgICAgICBpZiAodmFsdWUpIHtcclxuICAgICAgICAgICAgdGhpcy5fc2hvd0RlbGF5ID0gdmFsdWU7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgQElucHV0KCdzaG93RGVsYXknKSBzZXQgc2hvd0RlbGF5KHZhbHVlOiBudW1iZXIpIHtcclxuICAgICAgICBpZiAodmFsdWUpIHtcclxuICAgICAgICAgICAgdGhpcy5fc2hvd0RlbGF5ID0gdmFsdWU7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgZ2V0IHNob3dEZWxheSgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fc2hvd0RlbGF5O1xyXG4gICAgfVxyXG5cclxuICAgIC8vIEhpZGUgZGVsYXlcclxuICAgIEBJbnB1dCgnaGlkZS1kZWxheScpIHNldCBoaWRlRGVsYXlCYWNrd2FyZENvbXBhdGliaWxpdHkodmFsdWU6IG51bWJlcikge1xyXG4gICAgICAgIGlmICh2YWx1ZSkge1xyXG4gICAgICAgICAgICB0aGlzLl9oaWRlRGVsYXkgPSB2YWx1ZTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICBASW5wdXQoJ2hpZGVEZWxheScpIHNldCBoaWRlRGVsYXkodmFsdWU6IG51bWJlcikge1xyXG4gICAgICAgIGlmICh2YWx1ZSkge1xyXG4gICAgICAgICAgICB0aGlzLl9oaWRlRGVsYXkgPSB2YWx1ZTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICBnZXQgaGlkZURlbGF5KCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9oaWRlRGVsYXk7XHJcbiAgICB9XHJcblxyXG4gICAgQElucHV0KCdoaWRlRGVsYXlBZnRlckNsaWNrJykgaGlkZURlbGF5QWZ0ZXJDbGljayE6IG51bWJlcjtcclxuICAgIEBJbnB1dCgncG9pbnRlckV2ZW50cycpIHBvaW50ZXJFdmVudHMhOiAnYXV0bycgfCAnbm9uZSc7XHJcbiAgICBASW5wdXQoJ3Bvc2l0aW9uJykgcG9zaXRpb24hOiB7dG9wOiBudW1iZXIsIGxlZnQ6IG51bWJlcn07XHJcblxyXG4gICAgZ2V0IGlzVG9vbHRpcERlc3Ryb3llZCgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5jb21wb25lbnRSZWYgJiYgdGhpcy5jb21wb25lbnRSZWYuaG9zdFZpZXcuZGVzdHJveWVkO1xyXG4gICAgfVxyXG5cclxuICAgIGdldCBkZXN0cm95RGVsYXkoKSB7XHJcbiAgICAgICAgaWYgKHRoaXMuX2Rlc3Ryb3lEZWxheSkge1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fZGVzdHJveURlbGF5O1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHJldHVybiBOdW1iZXIodGhpcy5nZXRIaWRlRGVsYXkoKSkgKyBOdW1iZXIodGhpcy5vcHRpb25zWydhbmltYXRpb25EdXJhdGlvbiddKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICBzZXQgZGVzdHJveURlbGF5KHZhbHVlOiBudW1iZXIpIHtcclxuICAgICAgICB0aGlzLl9kZXN0cm95RGVsYXkgPSB2YWx1ZTtcclxuICAgIH1cclxuXHJcbiAgICBnZXQgdG9vbHRpcFBvc2l0aW9uKCkge1xyXG4gICAgICAgIGlmICh0aGlzLm9wdGlvbnNbJ3Bvc2l0aW9uJ10pIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMub3B0aW9uc1sncG9zaXRpb24nXTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5lbGVtZW50UG9zaXRpb247XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIEBPdXRwdXQoKSBldmVudHM6IEV2ZW50RW1pdHRlciA8IGFueSA+ID0gbmV3IEV2ZW50RW1pdHRlciA8IGFueSA+ICgpO1xyXG5cclxuICAgIGNvbnN0cnVjdG9yKFxyXG4gICAgICAgIEBPcHRpb25hbCgpIEBJbmplY3QoVG9vbHRpcE9wdGlvbnNTZXJ2aWNlKSBwcml2YXRlIGluaXRPcHRpb25zOmFueSxcclxuICAgICAgICBwcml2YXRlIGVsZW1lbnRSZWY6IEVsZW1lbnRSZWYsXHJcbiAgICAgICAgcHJpdmF0ZSBjb21wb25lbnRGYWN0b3J5UmVzb2x2ZXI6IENvbXBvbmVudEZhY3RvcnlSZXNvbHZlcixcclxuICAgICAgICBwcml2YXRlIGFwcFJlZjogQXBwbGljYXRpb25SZWYsXHJcbiAgICAgICAgcHJpdmF0ZSBpbmplY3RvcjogSW5qZWN0b3IpIHt9XHJcblxyXG4gICAgQEhvc3RMaXN0ZW5lcignZm9jdXNpbicpXHJcbiAgICBASG9zdExpc3RlbmVyKCdtb3VzZWVudGVyJylcclxuICAgIG9uTW91c2VFbnRlcigpIHtcclxuICAgICAgICBpZiAodGhpcy5pc0Rpc3BsYXlPbkhvdmVyID09IGZhbHNlKSB7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHRoaXMuc2hvdygpO1xyXG4gICAgfVxyXG5cclxuICAgIEBIb3N0TGlzdGVuZXIoJ2ZvY3Vzb3V0JylcclxuICAgIEBIb3N0TGlzdGVuZXIoJ21vdXNlbGVhdmUnKVxyXG4gICAgb25Nb3VzZUxlYXZlKCkge1xyXG4gICAgICAgIGlmICh0aGlzLm9wdGlvbnNbJ3RyaWdnZXInXSA9PT0gJ2hvdmVyJykge1xyXG4gICAgICAgICAgICB0aGlzLmRlc3Ryb3lUb29sdGlwKCk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIEBIb3N0TGlzdGVuZXIoJ2NsaWNrJylcclxuICAgIG9uQ2xpY2soKSB7XHJcbiAgICAgICAgaWYgKHRoaXMuaXNEaXNwbGF5T25DbGljayA9PSBmYWxzZSkge1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0aGlzLnNob3coKTtcclxuICAgICAgICB0aGlzLmhpZGVBZnRlckNsaWNrVGltZW91dElkID0gd2luZG93LnNldFRpbWVvdXQoKCkgPT4ge1xyXG4gICAgICAgICAgICB0aGlzLmRlc3Ryb3lUb29sdGlwKCk7XHJcbiAgICAgICAgfSwgdGhpcy5vcHRpb25zWydoaWRlRGVsYXlBZnRlckNsaWNrJ10pXHJcbiAgICB9XHJcblxyXG4gICAgbmdPbkluaXQoKTogdm9pZCB7XHJcbiAgICB9XHJcblxyXG4gICAgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcykge1xyXG4gICAgICAgIHRoaXMuaW5pdE9wdGlvbnMgPSB0aGlzLnJlbmFtZVByb3BlcnRpZXModGhpcy5pbml0T3B0aW9ucyk7XHJcbiAgICAgICAgbGV0IGNoYW5nZWRPcHRpb25zID0gdGhpcy5nZXRQcm9wZXJ0aWVzKGNoYW5nZXMpO1xyXG4gICAgICAgIGNoYW5nZWRPcHRpb25zID0gdGhpcy5yZW5hbWVQcm9wZXJ0aWVzKGNoYW5nZWRPcHRpb25zKTtcclxuXHJcbiAgICAgICAgdGhpcy5hcHBseU9wdGlvbnNEZWZhdWx0KGRlZmF1bHRPcHRpb25zLCBjaGFuZ2VkT3B0aW9ucyk7XHJcbiAgICB9XHJcblxyXG4gICAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XHJcbiAgICAgICAgdGhpcy5kZXN0cm95VG9vbHRpcCh7XHJcbiAgICAgICAgICAgIGZhc3Q6IHRydWVcclxuICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgaWYgKHRoaXMuY29tcG9uZW50U3Vic2NyaWJlKSB7XHJcbiAgICAgICAgICAgIHRoaXMuY29tcG9uZW50U3Vic2NyaWJlLnVuc3Vic2NyaWJlKCk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGdldFNob3dEZWxheSgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5vcHRpb25zWydzaG93RGVsYXknXTtcclxuICAgIH1cclxuXHJcbiAgICBnZXRIaWRlRGVsYXkoKSB7XHJcbiAgICAgICAgY29uc3QgaGlkZURlbGF5ID0gdGhpcy5vcHRpb25zWydoaWRlRGVsYXknXTtcclxuICAgICAgICBjb25zdCBoaWRlRGVsYXlUb3VjaHNjcmVlbiA9IHRoaXMub3B0aW9uc1snaGlkZURlbGF5VG91Y2hzY3JlZW4nXTtcclxuXHJcbiAgICAgICAgcmV0dXJuIHRoaXMuaXNUb3VjaFNjcmVlbiA/IGhpZGVEZWxheVRvdWNoc2NyZWVuIDogaGlkZURlbGF5O1xyXG4gICAgfVxyXG5cclxuICAgIGdldFByb3BlcnRpZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcyl7XHJcbiAgICAgICAgbGV0IGRpcmVjdGl2ZVByb3BlcnRpZXM6YW55ID0ge307XHJcbiAgICAgICAgbGV0IGN1c3RvbVByb3BlcnRpZXM6YW55ID0ge307XHJcbiAgICAgICAgbGV0IGFsbFByb3BlcnRpZXM6YW55ID0ge307XHJcblxyXG4gICAgICAgIGZvciAodmFyIHByb3AgaW4gY2hhbmdlcykge1xyXG4gICAgICAgICAgICBpZiAocHJvcCAhPT0gJ29wdGlvbnMnICYmIHByb3AgIT09ICd0b29sdGlwVmFsdWUnKXtcclxuICAgICAgICAgICAgICAgIGRpcmVjdGl2ZVByb3BlcnRpZXNbcHJvcF0gPSBjaGFuZ2VzW3Byb3BdLmN1cnJlbnRWYWx1ZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAocHJvcCA9PT0gJ29wdGlvbnMnKXtcclxuICAgICAgICAgICAgICAgIGN1c3RvbVByb3BlcnRpZXMgPSBjaGFuZ2VzW3Byb3BdLmN1cnJlbnRWYWx1ZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgYWxsUHJvcGVydGllcyA9IE9iamVjdC5hc3NpZ24oe30sIGN1c3RvbVByb3BlcnRpZXMsIGRpcmVjdGl2ZVByb3BlcnRpZXMpO1xyXG4gICAgICAgIHJldHVybiBhbGxQcm9wZXJ0aWVzO1xyXG4gICAgfVxyXG5cclxuICAgIHJlbmFtZVByb3BlcnRpZXMob3B0aW9uczphbnkpIHtcclxuICAgICAgICBmb3IgKHZhciBwcm9wIGluIG9wdGlvbnMpIHtcclxuICAgICAgICAgICAgaWYgKGJhY2t3YXJkQ29tcGF0aWJpbGl0eU9wdGlvbnNbcHJvcF0pIHtcclxuICAgICAgICAgICAgICAgIG9wdGlvbnNbYmFja3dhcmRDb21wYXRpYmlsaXR5T3B0aW9uc1twcm9wXV0gPSBvcHRpb25zW3Byb3BdO1xyXG4gICAgICAgICAgICAgICAgZGVsZXRlIG9wdGlvbnNbcHJvcF07XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiBvcHRpb25zO1xyXG4gICAgfVxyXG5cclxuICAgIGdldEVsZW1lbnRQb3NpdGlvbigpOiB2b2lkIHtcclxuICAgICAgICB0aGlzLmVsZW1lbnRQb3NpdGlvbiA9IHRoaXMuZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xyXG4gICAgfVxyXG5cclxuICAgIGNyZWF0ZVRvb2x0aXAoKTogdm9pZCB7XHJcbiAgICAgICAgdGhpcy5jbGVhclRpbWVvdXRzKCk7XHJcbiAgICAgICAgdGhpcy5nZXRFbGVtZW50UG9zaXRpb24oKTtcclxuXHJcbiAgICAgICAgdGhpcy5jcmVhdGVUaW1lb3V0SWQgPSB3aW5kb3cuc2V0VGltZW91dCgoKSA9PiB7XHJcbiAgICAgICAgICAgIHRoaXMuYXBwZW5kQ29tcG9uZW50VG9Cb2R5KFRvb2x0aXBDb21wb25lbnQpO1xyXG4gICAgICAgIH0sIHRoaXMuZ2V0U2hvd0RlbGF5KCkpO1xyXG5cclxuICAgICAgICB0aGlzLnNob3dUaW1lb3V0SWQgPSB3aW5kb3cuc2V0VGltZW91dCgoKSA9PiB7XHJcbiAgICAgICAgICAgIHRoaXMuc2hvd1Rvb2x0aXBFbGVtKCk7XHJcbiAgICAgICAgfSwgdGhpcy5nZXRTaG93RGVsYXkoKSk7XHJcbiAgICB9XHJcblxyXG4gICAgZGVzdHJveVRvb2x0aXAob3B0aW9ucyA9IHtcclxuICAgICAgICBmYXN0OiBmYWxzZVxyXG4gICAgfSk6IHZvaWQge1xyXG4gICAgICAgIHRoaXMuY2xlYXJUaW1lb3V0cygpO1xyXG5cclxuICAgICAgICBpZiAodGhpcy5pc1Rvb2x0aXBEZXN0cm95ZWQgPT0gZmFsc2UpIHtcclxuICAgICAgICAgICAgdGhpcy5oaWRlVGltZW91dElkID0gd2luZG93LnNldFRpbWVvdXQoKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5oaWRlVG9vbHRpcCgpO1xyXG4gICAgICAgICAgICB9LCBvcHRpb25zLmZhc3QgPyAwIDogdGhpcy5nZXRIaWRlRGVsYXkoKSk7XHJcblxyXG4gICAgICAgICAgICB0aGlzLmRlc3Ryb3lUaW1lb3V0SWQgPSB3aW5kb3cuc2V0VGltZW91dCgoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMuY29tcG9uZW50UmVmIHx8IHRoaXMuaXNUb29sdGlwRGVzdHJveWVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIHRoaXMuYXBwUmVmLmRldGFjaFZpZXcodGhpcy5jb21wb25lbnRSZWYuaG9zdFZpZXcpO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5jb21wb25lbnRSZWYuZGVzdHJveSgpO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5ldmVudHMuZW1pdCh7XHJcbiAgICAgICAgICAgICAgICAgICAgdHlwZTogJ2hpZGRlbicsIFxyXG4gICAgICAgICAgICAgICAgICAgIHBvc2l0aW9uOiB0aGlzLnRvb2x0aXBQb3NpdGlvblxyXG4gICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIH0sIG9wdGlvbnMuZmFzdCA/IDAgOiB0aGlzLmRlc3Ryb3lEZWxheSk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHNob3dUb29sdGlwRWxlbSgpOiB2b2lkIHtcclxuICAgICAgICB0aGlzLmNsZWFyVGltZW91dHMoKTtcclxuICAgICAgICAoIDwgQWRDb21wb25lbnQgPiB0aGlzLmNvbXBvbmVudFJlZi5pbnN0YW5jZSkuc2hvdyA9IHRydWU7XHJcbiAgICAgICAgdGhpcy5ldmVudHMuZW1pdCh7XHJcbiAgICAgICAgICAgIHR5cGU6ICdzaG93JyxcclxuICAgICAgICAgICAgcG9zaXRpb246IHRoaXMudG9vbHRpcFBvc2l0aW9uXHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgaGlkZVRvb2x0aXAoKTogdm9pZCB7XHJcbiAgICAgICAgaWYgKCF0aGlzLmNvbXBvbmVudFJlZiB8fCB0aGlzLmlzVG9vbHRpcERlc3Ryb3llZCkge1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG4gICAgICAgICggPCBBZENvbXBvbmVudCA+IHRoaXMuY29tcG9uZW50UmVmLmluc3RhbmNlKS5zaG93ID0gZmFsc2U7XHJcbiAgICAgICAgdGhpcy5ldmVudHMuZW1pdCh7XHJcbiAgICAgICAgICAgIHR5cGU6ICdoaWRlJyxcclxuICAgICAgICAgICAgcG9zaXRpb246IHRoaXMudG9vbHRpcFBvc2l0aW9uXHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgYXBwZW5kQ29tcG9uZW50VG9Cb2R5KGNvbXBvbmVudDogYW55LCBkYXRhOiBhbnkgPSB7fSk6IHZvaWQge1xyXG4gICAgICAgIHRoaXMuY29tcG9uZW50UmVmID0gdGhpcy5jb21wb25lbnRGYWN0b3J5UmVzb2x2ZXJcclxuICAgICAgICAgICAgLnJlc29sdmVDb21wb25lbnRGYWN0b3J5KGNvbXBvbmVudClcclxuICAgICAgICAgICAgLmNyZWF0ZSh0aGlzLmluamVjdG9yKTtcclxuXHJcbiAgICAgICAgKCA8IEFkQ29tcG9uZW50ID4gdGhpcy5jb21wb25lbnRSZWYuaW5zdGFuY2UpLmRhdGEgPSB7XHJcbiAgICAgICAgICAgIHZhbHVlOiB0aGlzLnRvb2x0aXBWYWx1ZSxcclxuICAgICAgICAgICAgZWxlbWVudDogdGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQsXHJcbiAgICAgICAgICAgIGVsZW1lbnRQb3NpdGlvbjogdGhpcy50b29sdGlwUG9zaXRpb24sXHJcbiAgICAgICAgICAgIG9wdGlvbnM6IHRoaXMub3B0aW9uc1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLmFwcFJlZi5hdHRhY2hWaWV3KHRoaXMuY29tcG9uZW50UmVmLmhvc3RWaWV3KTtcclxuICAgICAgICBjb25zdCBkb21FbGVtID0gKHRoaXMuY29tcG9uZW50UmVmLmhvc3RWaWV3IGFzIEVtYmVkZGVkVmlld1JlZiA8IGFueSA+ICkucm9vdE5vZGVzWzBdIGFzIEhUTUxFbGVtZW50O1xyXG4gICAgICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQoZG9tRWxlbSk7XHJcblxyXG4gICAgICAgIHRoaXMuY29tcG9uZW50U3Vic2NyaWJlID0gKCA8IEFkQ29tcG9uZW50ID4gdGhpcy5jb21wb25lbnRSZWYuaW5zdGFuY2UpLmV2ZW50cy5zdWJzY3JpYmUoKGV2ZW50OiBhbnkpID0+IHtcclxuICAgICAgICAgICAgdGhpcy5oYW5kbGVFdmVudHMoZXZlbnQpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIGNsZWFyVGltZW91dHMoKTogdm9pZCB7XHJcbiAgICAgICAgaWYgKHRoaXMuY3JlYXRlVGltZW91dElkKSB7XHJcbiAgICAgICAgICAgIGNsZWFyVGltZW91dCh0aGlzLmNyZWF0ZVRpbWVvdXRJZCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAodGhpcy5zaG93VGltZW91dElkKSB7XHJcbiAgICAgICAgICAgIGNsZWFyVGltZW91dCh0aGlzLnNob3dUaW1lb3V0SWQpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKHRoaXMuaGlkZVRpbWVvdXRJZCkge1xyXG4gICAgICAgICAgICBjbGVhclRpbWVvdXQodGhpcy5oaWRlVGltZW91dElkKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmICh0aGlzLmRlc3Ryb3lUaW1lb3V0SWQpIHtcclxuICAgICAgICAgICAgY2xlYXJUaW1lb3V0KHRoaXMuZGVzdHJveVRpbWVvdXRJZCk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGdldCBpc0Rpc3BsYXlPbkhvdmVyKCk6IGJvb2xlYW4ge1xyXG4gICAgICAgIGlmICh0aGlzLm9wdGlvbnNbJ2Rpc3BsYXknXSA9PSBmYWxzZSkge1xyXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAodGhpcy5vcHRpb25zWydkaXNwbGF5VG91Y2hzY3JlZW4nXSA9PSBmYWxzZSAmJiB0aGlzLmlzVG91Y2hTY3JlZW4pIHtcclxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKHRoaXMub3B0aW9uc1sndHJpZ2dlciddICE9PSAnaG92ZXInKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgfVx