jw-bootstrap-switch-ng2
Version:
Bootstrap Switch for Angular 2+
840 lines (832 loc) • 69.1 kB
JavaScript
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@angular/core'), require('@angular/forms'), require('@angular/common')) :
typeof define === 'function' && define.amd ? define('jw-bootstrap-switch-ng2', ['exports', '@angular/core', '@angular/forms', '@angular/common'], factory) :
(factory((global['jw-bootstrap-switch-ng2'] = {}),global.ng.core,global.ng.forms,global.ng.common));
}(this, (function (exports,core,forms,common) { 'use strict';
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/** @type {?} */
var callback = function () {
};
/** @type {?} */
var CUSTOM_INPUT = {
provide: forms.NG_VALUE_ACCESSOR,
useExisting: core.forwardRef(function () { return JwBootstrapSwitchNg2Component; }),
multi: true
};
var JwBootstrapSwitchNg2Component = /** @class */ (function () {
function JwBootstrapSwitchNg2Component(cd, render) {
this.cd = cd;
this.render = render;
// Defining Default Options for Switch
this.handleWidth = 0;
this.labelWidth = 0;
this.labelText = '';
this.inverse = false;
this.baseClass = 'bootstrap-switch';
this.onText = 'ON';
this.offText = 'OFF';
this.disabled = false;
this.readonly = false;
this._focused = false;
this._size = 'normal';
this._animate = true;
this._innerAnimate = true;
this._indeterminate = false;
this._onColor = 'primary';
this._offColor = 'default';
this._wrapperClass = 'wrapper';
this._innerState = false;
this._innerHandleWidth = 'auto';
this._innerLabelWidth = 'auto';
this._dragStart = null;
this._dragEnd = null;
this._onTouchedCallback = callback;
this._onChangeCallback = callback;
this.changeState = new core.EventEmitter();
}
/**
* @private
* @return {?}
*/
JwBootstrapSwitchNg2Component.prototype.$on = /**
* @private
* @return {?}
*/
function () {
return this.on.nativeElement;
};
/**
* @private
* @return {?}
*/
JwBootstrapSwitchNg2Component.prototype.$off = /**
* @private
* @return {?}
*/
function () {
return this.off.nativeElement;
};
/**
* @private
* @return {?}
*/
JwBootstrapSwitchNg2Component.prototype.$label = /**
* @private
* @return {?}
*/
function () {
return this.label.nativeElement;
};
/**
* @private
* @return {?}
*/
JwBootstrapSwitchNg2Component.prototype.$container = /**
* @private
* @return {?}
*/
function () {
return this.container.nativeElement;
};
/**
* @description: Function to set the Classes for the Wrapper Div
* @returns string
*/
/**
* \@description: Function to set the Classes for the Wrapper Div
* @return {?} string
*/
JwBootstrapSwitchNg2Component.prototype.getWrapperClasses = /**
* \@description: Function to set the Classes for the Wrapper Div
* @return {?} string
*/
function () {
/** @type {?} */
var output = this.baseClass + ' ' + this.baseClass + '-' + this._wrapperClass;
if (this._focused) {
output += ' ' + this.baseClass + '-focused';
}
if (this.readonly) {
output += ' ' + this.baseClass + '-readonly';
}
if (this._size != null) {
output += ' ' + this.baseClass + '-' + this._size;
}
if (this._innerState) {
output += ' ' + this.baseClass + '-on';
}
else {
output += ' ' + this.baseClass + '-off';
}
if (this._animate) {
output += ' ' + this.baseClass + '-animate';
}
if (this.disabled) {
output += ' ' + this.baseClass + '-disabled';
}
if (this._indeterminate || this._innerState === null || typeof this._innerState === 'undefined') {
output += ' ' + this.baseClass + '-indeterminate';
}
if (this.inverse) {
output += ' ' + this.baseClass + '-inverse';
}
return output;
};
/**
* @description Function to set the css classes for #on
* @returns string
*/
/**
* \@description Function to set the css classes for #on
* @return {?} string
*/
JwBootstrapSwitchNg2Component.prototype.getOnClasses = /**
* \@description Function to set the css classes for #on
* @return {?} string
*/
function () {
/** @type {?} */
var output = this.baseClass + '-handle-on';
if (this._onColor) {
output += ' ' + this.baseClass + '-' + this._onColor;
}
return output;
};
/**
* @description Function to set the css classes for #off
* @returns string
*/
/**
* \@description Function to set the css classes for #off
* @return {?} string
*/
JwBootstrapSwitchNg2Component.prototype.getOffClasses = /**
* \@description Function to set the css classes for #off
* @return {?} string
*/
function () {
/** @type {?} */
var output = this.baseClass + '-handle-off';
if (this._offColor) {
output += ' ' + this.baseClass + '-' + this._offColor;
}
return output;
};
/**
* @description Function set the marging of the #label when change the state
* @returns string
*/
/**
* \@description Function set the marging of the #label when change the state
* @return {?} string
*/
JwBootstrapSwitchNg2Component.prototype.getLabelMarginLeft = /**
* \@description Function set the marging of the #label when change the state
* @return {?} string
*/
function () {
/** @type {?} */
var width = (this.inverse) ? -this.handleWidth : 0;
if (this._indeterminate || this._innerState === null || typeof this._innerState === 'undefined') {
width = -(this.handleWidth / 2);
}
else if (this._dragEnd) {
width = this._dragEnd;
}
else if (!this._innerState) {
if (!this.inverse) {
width = -this.handleWidth;
}
else {
width = 0;
}
}
return width + 'px';
};
/**
* @param {?} changes
* @return {?}
*/
JwBootstrapSwitchNg2Component.prototype.ngOnChanges = /**
* @param {?} changes
* @return {?}
*/
function (changes) {
if (changes['setLabelText'] ||
changes['setOnText'] ||
changes['setHandleWidth'] ||
changes['setLabelWidth'] ||
changes['setOffText'] ||
changes['setSize']) {
this.calculateWith(true);
}
};
/**
* @return {?}
*/
JwBootstrapSwitchNg2Component.prototype.ngAfterViewInit = /**
* @return {?}
*/
function () {
this.calculateWith();
};
/**
* @return {?}
*/
JwBootstrapSwitchNg2Component.prototype.onClick = /**
* @return {?}
*/
function () {
if (!this.disabled && !this.readonly && !this._dragEnd) {
this.setStateValue(!this._innerState);
}
else if (this._dragEnd) {
this._dragEnd = null;
}
};
/**
* @param {?} e
* @return {?}
*/
JwBootstrapSwitchNg2Component.prototype.onKeyDown = /**
* @param {?} e
* @return {?}
*/
function (e) {
if (!e.which || this.disabled || this.readonly) {
return;
}
switch (e.which) {
case 37:
e.preventDefault();
e.stopImmediatePropagation();
this.setStateValue(false);
break;
case 39:
e.preventDefault();
e.stopImmediatePropagation();
this.setStateValue(true);
break;
}
};
/**
* @private
* @param {?} e
* @return {?}
*/
JwBootstrapSwitchNg2Component.prototype.onDragStart = /**
* @private
* @param {?} e
* @return {?}
*/
function (e) {
if (e.target === this.$label()) {
if (this._dragStart || this.disabled || this.readonly) {
return;
}
e.preventDefault();
e.stopPropagation();
this._dragStart = (e.pageX || e.touches[0].pageX) - parseInt(this.$container().style.marginLeft, 10);
if (this._animate) {
this._animate = !this._animate;
}
}
};
/**
* @private
* @param {?} e
* @return {?}
*/
JwBootstrapSwitchNg2Component.prototype.onDragMove = /**
* @private
* @param {?} e
* @return {?}
*/
function (e) {
if (this._dragStart) {
e.preventDefault();
/** @type {?} */
var difference = (e.pageX || e.touches[0].pageX) - this._dragStart;
if (difference < -Number(this.handleWidth) || difference > 0) {
return;
}
this._dragEnd = difference;
}
};
/**
* @private
* @param {?} e
* @param {?=} removeDragEnd
* @return {?}
*/
JwBootstrapSwitchNg2Component.prototype.onDragEnd = /**
* @private
* @param {?} e
* @param {?=} removeDragEnd
* @return {?}
*/
function (e, removeDragEnd) {
if (removeDragEnd === void 0) {
removeDragEnd = false;
}
if (this._dragStart) {
e.preventDefault();
e.stopPropagation();
if (this._dragEnd) {
/** @type {?} */
var state = this._dragEnd > -(Number(this.handleWidth) / 2);
this.setStateValue((this.inverse) ? !state : state);
}
this._dragStart = null;
if (removeDragEnd) {
this._dragEnd = null;
}
if (this._innerAnimate) {
this._animate = true;
}
}
};
/**
* @param {?} e
* @return {?}
*/
JwBootstrapSwitchNg2Component.prototype.onTouchStart = /**
* @param {?} e
* @return {?}
*/
function (e) {
this.onDragStart(e);
};
/**
* @param {?} e
* @return {?}
*/
JwBootstrapSwitchNg2Component.prototype.onMouseDown = /**
* @param {?} e
* @return {?}
*/
function (e) {
this.onDragStart(e);
};
/**
* @param {?} e
* @return {?}
*/
JwBootstrapSwitchNg2Component.prototype.onTouchMove = /**
* @param {?} e
* @return {?}
*/
function (e) {
this.onDragMove(e);
};
/**
* @param {?} e
* @return {?}
*/
JwBootstrapSwitchNg2Component.prototype.onMouseMove = /**
* @param {?} e
* @return {?}
*/
function (e) {
this.onDragMove(e);
};
/**
* @param {?} e
* @return {?}
*/
JwBootstrapSwitchNg2Component.prototype.onMouseUp = /**
* @param {?} e
* @return {?}
*/
function (e) {
this.onDragEnd(e);
};
/**
* @param {?} e
* @return {?}
*/
JwBootstrapSwitchNg2Component.prototype.onTouchEnd = /**
* @param {?} e
* @return {?}
*/
function (e) {
this.onDragEnd(e, true);
};
/**
* @param {?} e
* @return {?}
*/
JwBootstrapSwitchNg2Component.prototype.onMouseLeave = /**
* @param {?} e
* @return {?}
*/
function (e) {
this.onDragEnd(e, true);
};
/**
* @return {?}
*/
JwBootstrapSwitchNg2Component.prototype.onFocus = /**
* @return {?}
*/
function () {
this._focused = true;
};
/**
* @return {?}
*/
JwBootstrapSwitchNg2Component.prototype.onBlur = /**
* @return {?}
*/
function () {
this._focused = false;
this._onTouchedCallback();
};
/**
* @description Function to make recalculate the size of the elements when options change
* @param disableAnimation
*/
/**
* \@description Function to make recalculate the size of the elements when options change
* @private
* @param {?=} disableAnimation
* @return {?}
*/
JwBootstrapSwitchNg2Component.prototype.calculateWith = /**
* \@description Function to make recalculate the size of the elements when options change
* @private
* @param {?=} disableAnimation
* @return {?}
*/
function (disableAnimation) {
var _this = this;
if (disableAnimation === void 0) {
disableAnimation = false;
}
if (disableAnimation && this._innerAnimate) {
this._animate = false;
}
setTimeout(function () {
_this.render.setStyle(_this.$on(), 'width', 'auto');
_this.render.setStyle(_this.$off(), 'width', 'auto');
_this.render.setStyle(_this.$label(), 'width', 'auto');
/** @type {?} */
var width = (_this._innerHandleWidth === 'auto')
? Math.max(_this.$on().offsetWidth, _this.$off().offsetWidth)
: _this._innerHandleWidth;
if (_this.$label().offsetWidth < width) {
if (_this._innerLabelWidth === 'auto') {
_this.labelWidth = Number(width);
}
else {
_this.labelWidth = Number(_this._innerLabelWidth);
}
}
else {
if (_this._innerLabelWidth === 'auto') {
_this.labelWidth = _this.$label().offsetWidth;
}
else {
_this.labelWidth = Number(_this._innerLabelWidth);
}
}
_this.handleWidth = Number(width);
_this.render.setStyle(_this.$label(), 'width', _this.labelWidth + 'px');
_this.render.setStyle(_this.$on(), 'width', _this.handleWidth + 'px');
_this.render.setStyle(_this.$off(), 'width', _this.handleWidth + 'px');
setTimeout(function () {
if (disableAnimation && _this._innerAnimate) {
_this._animate = true;
}
});
_this.cd.markForCheck();
});
};
Object.defineProperty(JwBootstrapSwitchNg2Component.prototype, "setBaseClass", {
// Functions to set inputs and the private variables of the Switch
set:
// Functions to set inputs and the private variables of the Switch
/**
* @param {?} value
* @return {?}
*/
function (value) {
this.baseClass = value;
},
enumerable: true,
configurable: true
});
Object.defineProperty(JwBootstrapSwitchNg2Component.prototype, "setWrapperClass", {
set: /**
* @param {?} value
* @return {?}
*/ function (value) {
this._wrapperClass = value;
},
enumerable: true,
configurable: true
});
Object.defineProperty(JwBootstrapSwitchNg2Component.prototype, "setOffText", {
set: /**
* @param {?} value
* @return {?}
*/ function (value) {
this.offText = (value) ? value : 'OFF';
},
enumerable: true,
configurable: true
});
Object.defineProperty(JwBootstrapSwitchNg2Component.prototype, "setLabelText", {
set: /**
* @param {?} value
* @return {?}
*/ function (value) {
this.labelText = value;
},
enumerable: true,
configurable: true
});
Object.defineProperty(JwBootstrapSwitchNg2Component.prototype, "setOnText", {
set: /**
* @param {?} value
* @return {?}
*/ function (value) {
this.onText = (value) ? value : 'ON';
},
enumerable: true,
configurable: true
});
Object.defineProperty(JwBootstrapSwitchNg2Component.prototype, "setSize", {
set: /**
* @param {?} value
* @return {?}
*/ function (value) {
if (value) {
this._size = value;
}
},
enumerable: true,
configurable: true
});
Object.defineProperty(JwBootstrapSwitchNg2Component.prototype, "setAnimate", {
set: /**
* @param {?} value
* @return {?}
*/ function (value) {
this._animate = value;
this._innerAnimate = value;
},
enumerable: true,
configurable: true
});
Object.defineProperty(JwBootstrapSwitchNg2Component.prototype, "setOnColor", {
set: /**
* @param {?} value
* @return {?}
*/ function (value) {
if (value) {
this._onColor = value;
}
},
enumerable: true,
configurable: true
});
Object.defineProperty(JwBootstrapSwitchNg2Component.prototype, "setOffColor", {
set: /**
* @param {?} value
* @return {?}
*/ function (value) {
if (value) {
this._offColor = value;
}
},
enumerable: true,
configurable: true
});
Object.defineProperty(JwBootstrapSwitchNg2Component.prototype, "setDisabled", {
set: /**
* @param {?} value
* @return {?}
*/ function (value) {
this.disabled = value;
},
enumerable: true,
configurable: true
});
Object.defineProperty(JwBootstrapSwitchNg2Component.prototype, "setReadOnly", {
set: /**
* @param {?} value
* @return {?}
*/ function (value) {
this.readonly = value;
},
enumerable: true,
configurable: true
});
Object.defineProperty(JwBootstrapSwitchNg2Component.prototype, "setIndeterminate", {
set: /**
* @param {?} value
* @return {?}
*/ function (value) {
this._indeterminate = value;
},
enumerable: true,
configurable: true
});
Object.defineProperty(JwBootstrapSwitchNg2Component.prototype, "setInverse", {
set: /**
* @param {?} value
* @return {?}
*/ function (value) {
this.inverse = value;
},
enumerable: true,
configurable: true
});
Object.defineProperty(JwBootstrapSwitchNg2Component.prototype, "setHandleWidth", {
set: /**
* @param {?} value
* @return {?}
*/ function (value) {
this._innerHandleWidth = (typeof (value) !== 'undefined') ? value : 'auto';
},
enumerable: true,
configurable: true
});
Object.defineProperty(JwBootstrapSwitchNg2Component.prototype, "setLabelWidth", {
set: /**
* @param {?} value
* @return {?}
*/ function (value) {
this._innerLabelWidth = (typeof (value) !== 'undefined') ? value : 'auto';
},
enumerable: true,
configurable: true
});
Object.defineProperty(JwBootstrapSwitchNg2Component.prototype, "value", {
get: /**
* @return {?}
*/ function () {
return this._innerState;
},
set: /**
* @param {?} v
* @return {?}
*/ function (v) {
if (v === null || typeof v === 'undefined') {
this._indeterminate = true;
}
this.setStateValue(v);
},
enumerable: true,
configurable: true
});
/**
* @private
* @param {?} v
* @return {?}
*/
JwBootstrapSwitchNg2Component.prototype.setStateValue = /**
* @private
* @param {?} v
* @return {?}
*/
function (v) {
if (v !== this._innerState) {
this._onChangeCallback(v);
this.changeState.emit({
previousValue: this._innerState,
currentValue: v
});
this._innerState = v;
}
};
/**
* @param {?} value
* @return {?}
*/
JwBootstrapSwitchNg2Component.prototype.writeValue = /**
* @param {?} value
* @return {?}
*/
function (value) {
if (value !== this._innerState) {
this._innerState = value;
this.cd.markForCheck();
}
};
/**
* @param {?} isDisabled
* @return {?}
*/
JwBootstrapSwitchNg2Component.prototype.setDisabledState = /**
* @param {?} isDisabled
* @return {?}
*/
function (isDisabled) {
this.disabled = isDisabled;
};
/**
* @param {?} fn
* @return {?}
*/
JwBootstrapSwitchNg2Component.prototype.registerOnChange = /**
* @param {?} fn
* @return {?}
*/
function (fn) {
this._onChangeCallback = fn;
};
/**
* @param {?} fn
* @return {?}
*/
JwBootstrapSwitchNg2Component.prototype.registerOnTouched = /**
* @param {?} fn
* @return {?}
*/
function (fn) {
this._onTouchedCallback = fn;
};
JwBootstrapSwitchNg2Component.decorators = [
{ type: core.Component, args: [{
selector: 'bSwitch',
providers: [CUSTOM_INPUT],
template: "\n <div [ngClass]=\"getWrapperClasses()\" [style.width]=\"(handleWidth + labelWidth ) +'px'\">\n <div #container [ngClass]=\"baseClass + '-container'\"\n [style.width]=\"((handleWidth * 2) + labelWidth) +'px'\"\n [style.margin-left]=\"getLabelMarginLeft()\"><!--\n --><span #on [innerHTML]=\"(inverse) ? offText : onText\"\n [ngClass]=\"(inverse) ? getOffClasses() : getOnClasses()\"></span><!--\n --><span #label [ngClass]=\"baseClass + '-label'\"> {{ labelText }}</span><!--\n --><span #off [innerHTML]=\"(inverse) ? onText : offText\"\n [ngClass]=\"(inverse) ? getOnClasses() : getOffClasses()\"></span><!--\n --><input type=\"checkbox\" [(ngModel)]=\"value\" [readonly]=\"readonly\" [disabled]=\"disabled\"\n (focus)=\"onFocus()\" (blur)=\"onBlur()\">\n </div>\n </div>"
},] },
];
/** @nocollapse */
JwBootstrapSwitchNg2Component.ctorParameters = function () {
return [
{ type: core.ChangeDetectorRef },
{ type: core.Renderer2 }
];
};
JwBootstrapSwitchNg2Component.propDecorators = {
changeState: [{ type: core.Output }],
container: [{ type: core.ViewChild, args: ['container',] }],
on: [{ type: core.ViewChild, args: ['on',] }],
label: [{ type: core.ViewChild, args: ['label',] }],
off: [{ type: core.ViewChild, args: ['off',] }],
onClick: [{ type: core.HostListener, args: ['click',] }],
onKeyDown: [{ type: core.HostListener, args: ['keydown', ['$event'],] }],
onTouchStart: [{ type: core.HostListener, args: ['touchstart', ['$event'],] }],
onMouseDown: [{ type: core.HostListener, args: ['mousedown', ['$event'],] }],
onTouchMove: [{ type: core.HostListener, args: ['touchmove', ['$event'],] }],
onMouseMove: [{ type: core.HostListener, args: ['mousemove', ['$event'],] }],
onMouseUp: [{ type: core.HostListener, args: ['mouseup', ['$event'],] }],
onTouchEnd: [{ type: core.HostListener, args: ['touchend', ['$event'],] }],
onMouseLeave: [{ type: core.HostListener, args: ['mouseleave', ['$event'],] }],
setBaseClass: [{ type: core.Input, args: ['switch-base-class',] }],
setWrapperClass: [{ type: core.Input, args: ['switch-wrapper-class',] }],
setOffText: [{ type: core.Input, args: ['switch-off-text',] }],
setLabelText: [{ type: core.Input, args: ['switch-label-text',] }],
setOnText: [{ type: core.Input, args: ['switch-on-text',] }],
setSize: [{ type: core.Input, args: ['switch-size',] }],
setAnimate: [{ type: core.Input, args: ['switch-animate',] }],
setOnColor: [{ type: core.Input, args: ['switch-on-color',] }],
setOffColor: [{ type: core.Input, args: ['switch-off-color',] }],
setDisabled: [{ type: core.Input, args: ['switch-disabled',] }],
setReadOnly: [{ type: core.Input, args: ['switch-readonly',] }],
setIndeterminate: [{ type: core.Input, args: ['switch-indeterminate',] }],
setInverse: [{ type: core.Input, args: ['switch-inverse',] }],
setHandleWidth: [{ type: core.Input, args: ['switch-handle-width',] }],
setLabelWidth: [{ type: core.Input, args: ['switch-label-width',] }]
};
return JwBootstrapSwitchNg2Component;
}());
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
var JwBootstrapSwitchNg2Module = /** @class */ (function () {
function JwBootstrapSwitchNg2Module() {
}
JwBootstrapSwitchNg2Module.decorators = [
{ type: core.NgModule, args: [{
imports: [
common.CommonModule,
forms.FormsModule
],
declarations: [JwBootstrapSwitchNg2Component],
exports: [JwBootstrapSwitchNg2Component]
},] },
];
return JwBootstrapSwitchNg2Module;
}());
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
exports.JwBootstrapSwitchNg2Component = JwBootstrapSwitchNg2Component;
exports.JwBootstrapSwitchNg2Module = JwBootstrapSwitchNg2Module;
Object.defineProperty(exports, '__esModule', { value: true });
})));
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoianctYm9vdHN0cmFwLXN3aXRjaC1uZzIudW1kLmpzLm1hcCIsInNvdXJjZXMiOlsibmc6Ly9qdy1ib290c3RyYXAtc3dpdGNoLW5nMi9saWIvanctYm9vdHN0cmFwLXN3aXRjaC1uZzIuY29tcG9uZW50LnRzIiwibmc6Ly9qdy1ib290c3RyYXAtc3dpdGNoLW5nMi9saWIvanctYm9vdHN0cmFwLXN3aXRjaC1uZzIubW9kdWxlLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XHJcbiAgICBDb21wb25lbnQsXHJcbiAgICBFbGVtZW50UmVmLFxyXG4gICAgSW5wdXQsXHJcbiAgICBPdXRwdXQsXHJcbiAgICBIb3N0TGlzdGVuZXIsXHJcbiAgICBBZnRlclZpZXdJbml0LFxyXG4gICAgZm9yd2FyZFJlZixcclxuICAgIFNpbXBsZUNoYW5nZXMsXHJcbiAgICBFdmVudEVtaXR0ZXIsXHJcbiAgICBWaWV3Q2hpbGQsXHJcbiAgICBPbkNoYW5nZXMsXHJcbiAgICBSZW5kZXJlcjIsXHJcbiAgICBDaGFuZ2VEZXRlY3RvclJlZlxyXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQge1xyXG4gICAgQ29udHJvbFZhbHVlQWNjZXNzb3IsXHJcbiAgICBOR19WQUxVRV9BQ0NFU1NPUlxyXG59IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcclxuXHJcbmNvbnN0IGNhbGxiYWNrID0gKCkgPT4ge1xyXG59O1xyXG5cclxuY29uc3QgQ1VTVE9NX0lOUFVUOiBhbnkgPSB7XHJcbiAgICBwcm92aWRlOiBOR19WQUxVRV9BQ0NFU1NPUixcclxuICAgIHVzZUV4aXN0aW5nOiBmb3J3YXJkUmVmKCgpID0+IEp3Qm9vdHN0cmFwU3dpdGNoTmcyQ29tcG9uZW50KSxcclxuICAgIG11bHRpOiB0cnVlXHJcbn07XHJcblxyXG5AQ29tcG9uZW50KHtcclxuICAgIHNlbGVjdG9yOiAnYlN3aXRjaCcsXHJcbiAgICBwcm92aWRlcnM6IFtDVVNUT01fSU5QVVRdLFxyXG4gICAgdGVtcGxhdGU6IGBcclxuICAgICAgPGRpdiBbbmdDbGFzc109XCJnZXRXcmFwcGVyQ2xhc3NlcygpXCIgW3N0eWxlLndpZHRoXT1cIihoYW5kbGVXaWR0aCAgKyBsYWJlbFdpZHRoICkgKydweCdcIj5cclxuICAgICAgICAgIDxkaXYgI2NvbnRhaW5lciBbbmdDbGFzc109XCJiYXNlQ2xhc3MgKyAnLWNvbnRhaW5lcidcIlxyXG4gICAgICAgICAgICAgICBbc3R5bGUud2lkdGhdPVwiKChoYW5kbGVXaWR0aCAqIDIpICsgbGFiZWxXaWR0aCkgKydweCdcIlxyXG4gICAgICAgICAgICAgICBbc3R5bGUubWFyZ2luLWxlZnRdPVwiZ2V0TGFiZWxNYXJnaW5MZWZ0KClcIj48IS0tXHJcbiAgICAgICAgICAgICAgLS0+PHNwYW4gI29uIFtpbm5lckhUTUxdPVwiKGludmVyc2UpID8gb2ZmVGV4dCA6IG9uVGV4dFwiXHJcbiAgICAgICAgICAgICAgICBbbmdDbGFzc109XCIoaW52ZXJzZSkgPyBnZXRPZmZDbGFzc2VzKCkgOiBnZXRPbkNsYXNzZXMoKVwiPjwvc3Bhbj48IS0tXHJcbiAgICAgICAgICAgICAgLS0+PHNwYW4gI2xhYmVsIFtuZ0NsYXNzXT1cImJhc2VDbGFzcyArICctbGFiZWwnXCI+Jm5ic3A7e3sgbGFiZWxUZXh0IH19PC9zcGFuPjwhLS1cclxuICAgICAgICAgICAgICAtLT48c3BhbiAjb2ZmIFtpbm5lckhUTUxdPVwiKGludmVyc2UpID8gb25UZXh0IDogb2ZmVGV4dFwiXHJcbiAgICAgICAgICAgICAgICBbbmdDbGFzc109XCIoaW52ZXJzZSkgPyBnZXRPbkNsYXNzZXMoKSA6IGdldE9mZkNsYXNzZXMoKVwiPjwvc3Bhbj48IS0tXHJcbiAgICAgICAgICAgICAgLS0+PGlucHV0IHR5cGU9XCJjaGVja2JveFwiIFsobmdNb2RlbCldPVwidmFsdWVcIiBbcmVhZG9ubHldPVwicmVhZG9ubHlcIiBbZGlzYWJsZWRdPVwiZGlzYWJsZWRcIlxyXG4gICAgICAgICAgICAgICAgICAgICAoZm9jdXMpPVwib25Gb2N1cygpXCIgKGJsdXIpPVwib25CbHVyKClcIj5cclxuICAgICAgICAgIDwvZGl2PlxyXG4gICAgICA8L2Rpdj5gXHJcbn0pXHJcblxyXG5leHBvcnQgY2xhc3MgSndCb290c3RyYXBTd2l0Y2hOZzJDb21wb25lbnQgaW1wbGVtZW50cyBBZnRlclZpZXdJbml0LCBDb250cm9sVmFsdWVBY2Nlc3NvciwgT25DaGFuZ2VzIHtcclxuICAgIC8vIERlZmluaW5nIERlZmF1bHQgT3B0aW9ucyBmb3IgU3dpdGNoXHJcbiAgICBwdWJsaWMgaGFuZGxlV2lkdGg6IG51bWJlciA9IDA7XHJcbiAgICBwdWJsaWMgbGFiZWxXaWR0aDogbnVtYmVyID0gMDtcclxuICAgIHB1YmxpYyBsYWJlbFRleHQ6IHN0cmluZyA9ICcnO1xyXG4gICAgcHVibGljIGludmVyc2U6IGJvb2xlYW4gPSBmYWxzZTtcclxuICAgIHB1YmxpYyBiYXNlQ2xhc3M6IHN0cmluZyA9ICdib290c3RyYXAtc3dpdGNoJztcclxuICAgIHB1YmxpYyBvblRleHQ6IHN0cmluZyA9ICdPTic7XHJcbiAgICBwdWJsaWMgb2ZmVGV4dDogc3RyaW5nID0gJ09GRic7XHJcbiAgICBwdWJsaWMgZGlzYWJsZWQ6IGJvb2xlYW4gPSBmYWxzZTtcclxuICAgIHB1YmxpYyByZWFkb25seTogYm9vbGVhbiA9IGZhbHNlO1xyXG5cclxuICAgIHByaXZhdGUgX2ZvY3VzZWQ6IGJvb2xlYW4gPSBmYWxzZTtcclxuICAgIHByaXZhdGUgX3NpemU6IGFueSA9ICdub3JtYWwnO1xyXG4gICAgcHJpdmF0ZSBfYW5pbWF0ZTogYm9vbGVhbiA9IHRydWU7XHJcbiAgICBwcml2YXRlIF9pbm5lckFuaW1hdGU6IGJvb2xlYW4gPSB0cnVlO1xyXG4gICAgcHJpdmF0ZSBfaW5kZXRlcm1pbmF0ZTogYm9vbGVhbiA9IGZhbHNlO1xyXG4gICAgcHJpdmF0ZSBfb25Db2xvcjogc3RyaW5nID0gJ3ByaW1hcnknO1xyXG4gICAgcHJpdmF0ZSBfb2ZmQ29sb3I6IHN0cmluZyA9ICdkZWZhdWx0JztcclxuICAgIHByaXZhdGUgX3dyYXBwZXJDbGFzczogc3RyaW5nID0gJ3dyYXBwZXInO1xyXG4gICAgcHJpdmF0ZSBfaW5uZXJTdGF0ZTogYm9vbGVhbiA9IGZhbHNlO1xyXG4gICAgcHJpdmF0ZSBfaW5uZXJIYW5kbGVXaWR0aDogc3RyaW5nIHwgbnVtYmVyID0gJ2F1dG8nO1xyXG4gICAgcHJpdmF0ZSBfaW5uZXJMYWJlbFdpZHRoOiBzdHJpbmcgfCBudW1iZXIgPSAnYXV0byc7XHJcblxyXG4gICAgcHJpdmF0ZSBfZHJhZ1N0YXJ0OiBhbnkgPSBudWxsO1xyXG4gICAgcHJpdmF0ZSBfZHJhZ0VuZDogYW55ID0gbnVsbDtcclxuXHJcbiAgICBwcml2YXRlIF9vblRvdWNoZWRDYWxsYmFjazogKCkgPT4gdm9pZCA9IGNhbGxiYWNrO1xyXG4gICAgcHJpdmF0ZSBfb25DaGFuZ2VDYWxsYmFjazogKF86IGFueSkgPT4gdm9pZCA9IGNhbGxiYWNrO1xyXG5cclxuICAgIEBPdXRwdXQoKSBjaGFuZ2VTdGF0ZTogRXZlbnRFbWl0dGVyPGFueT4gPSBuZXcgRXZlbnRFbWl0dGVyPGFueT4oKTtcclxuXHJcblxyXG4gICAgLy8gRGVmaW5pbmcgRE9NIEVsZW1lbnRzXHJcbiAgICBAVmlld0NoaWxkKCdjb250YWluZXInKSBjb250YWluZXI6IEVsZW1lbnRSZWY7XHJcbiAgICBAVmlld0NoaWxkKCdvbicpIG9uOiBFbGVtZW50UmVmO1xyXG4gICAgQFZpZXdDaGlsZCgnbGFiZWwnKSBsYWJlbDogRWxlbWVudFJlZjtcclxuICAgIEBWaWV3Q2hpbGQoJ29mZicpIG9mZjogRWxlbWVudFJlZjtcclxuXHJcbiAgICBwcml2YXRlICRvbigpOiBhbnkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLm9uLm5hdGl2ZUVsZW1lbnQ7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSAkb2ZmKCk6IGFueSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMub2ZmLm5hdGl2ZUVsZW1lbnQ7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSAkbGFiZWwoKTogYW55IHtcclxuICAgICAgICByZXR1cm4gdGhpcy5sYWJlbC5uYXRpdmVFbGVtZW50O1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgJGNvbnRhaW5lcigpOiBhbnkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLmNvbnRhaW5lci5uYXRpdmVFbGVtZW50O1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQGRlc2NyaXB0aW9uOiAgRnVuY3Rpb24gdG8gc2V0IHRoZSBDbGFzc2VzIGZvciB0aGUgV3JhcHBlciBEaXZcclxuICAgICAqIEByZXR1cm5zIHN0cmluZ1xyXG4gICAgICovXHJcbiAgICBwdWJsaWMgZ2V0V3JhcHBlckNsYXNzZXMoKSB7XHJcbiAgICAgICAgbGV0IG91dHB1dDogc3RyaW5nID0gdGhpcy5iYXNlQ2xhc3MgKyAnICcgKyB0aGlzLmJhc2VDbGFzcyArICctJyArIHRoaXMuX3dyYXBwZXJDbGFzcztcclxuXHJcbiAgICAgICAgaWYgKHRoaXMuX2ZvY3VzZWQpIHtcclxuICAgICAgICAgICAgb3V0cHV0ICs9ICcgJyArIHRoaXMuYmFzZUNsYXNzICsgJy1mb2N1c2VkJztcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKHRoaXMucmVhZG9ubHkpIHtcclxuICAgICAgICAgICAgb3V0cHV0ICs9ICcgJyArIHRoaXMuYmFzZUNsYXNzICsgJy1yZWFkb25seSc7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAodGhpcy5fc2l6ZSAhPSBudWxsKSB7XHJcbiAgICAgICAgICAgIG91dHB1dCArPSAnICcgKyB0aGlzLmJhc2VDbGFzcyArICctJyArIHRoaXMuX3NpemU7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAodGhpcy5faW5uZXJTdGF0ZSkge1xyXG4gICAgICAgICAgICBvdXRwdXQgKz0gJyAnICsgdGhpcy5iYXNlQ2xhc3MgKyAnLW9uJztcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBvdXRwdXQgKz0gJyAnICsgdGhpcy5iYXNlQ2xhc3MgKyAnLW9mZic7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAodGhpcy5fYW5pbWF0ZSkge1xyXG4gICAgICAgICAgICBvdXRwdXQgKz0gJyAnICsgdGhpcy5iYXNlQ2xhc3MgKyAnLWFuaW1hdGUnO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKHRoaXMuZGlzYWJsZWQpIHtcclxuICAgICAgICAgICAgb3V0cHV0ICs9ICcgJyArIHRoaXMuYmFzZUNsYXNzICsgJy1kaXNhYmxlZCc7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAodGhpcy5faW5kZXRlcm1pbmF0ZSB8fCB0aGlzLl9pbm5lclN0YXRlID09PSBudWxsIHx8IHR5cGVvZiB0aGlzLl9pbm5lclN0YXRlID09PSAndW5kZWZpbmVkJykge1xyXG4gICAgICAgICAgICBvdXRwdXQgKz0gJyAnICsgdGhpcy5iYXNlQ2xhc3MgKyAnLWluZGV0ZXJtaW5hdGUnO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKHRoaXMuaW52ZXJzZSkge1xyXG4gICAgICAgICAgICBvdXRwdXQgKz0gJyAnICsgdGhpcy5iYXNlQ2xhc3MgKyAnLWludmVyc2UnO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gb3V0cHV0O1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQGRlc2NyaXB0aW9uIEZ1bmN0aW9uIHRvIHNldCB0aGUgY3NzIGNsYXNzZXMgZm9yICNvblxyXG4gICAgICogQHJldHVybnMgc3RyaW5nXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBnZXRPbkNsYXNzZXMoKTogc3RyaW5nIHtcclxuICAgICAgICBsZXQgb3V0cHV0OiBzdHJpbmcgPSB0aGlzLmJhc2VDbGFzcyArICctaGFuZGxlLW9uJztcclxuXHJcbiAgICAgICAgaWYgKHRoaXMuX29uQ29sb3IpIHtcclxuICAgICAgICAgICAgb3V0cHV0ICs9ICcgJyArIHRoaXMuYmFzZUNsYXNzICsgJy0nICsgdGhpcy5fb25Db2xvcjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiBvdXRwdXQ7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAZGVzY3JpcHRpb24gRnVuY3Rpb24gdG8gc2V0IHRoZSBjc3MgY2xhc3NlcyBmb3IgI29mZlxyXG4gICAgICogQHJldHVybnMgc3RyaW5nXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBnZXRPZmZDbGFzc2VzKCk6IHN0cmluZyB7XHJcbiAgICAgICAgbGV0IG91dHB1dDogc3RyaW5nID0gdGhpcy5iYXNlQ2xhc3MgKyAnLWhhbmRsZS1vZmYnO1xyXG5cclxuICAgICAgICBpZiAodGhpcy5fb2ZmQ29sb3IpIHtcclxuICAgICAgICAgICAgb3V0cHV0ICs9ICcgJyArIHRoaXMuYmFzZUNsYXNzICsgJy0nICsgdGhpcy5fb2ZmQ29sb3I7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gb3V0cHV0O1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQGRlc2NyaXB0aW9uICBGdW5jdGlvbiBzZXQgdGhlIG1hcmdpbmcgb2YgdGhlICNsYWJlbCB3aGVuIGNoYW5nZSB0aGUgc3RhdGVcclxuICAgICAqIEByZXR1cm5zIHN0cmluZ1xyXG4gICAgICovXHJcbiAgICBwdWJsaWMgZ2V0TGFiZWxNYXJnaW5MZWZ0KCk6IHN0cmluZyB7XHJcbiAgICAgICAgbGV0IHdpZHRoID0gKHRoaXMuaW52ZXJzZSkgPyAtdGhpcy5oYW5kbGVXaWR0aCA6IDA7XHJcbiAgICAgICAgaWYgKHRoaXMuX2luZGV0ZXJtaW5hdGUgfHwgdGhpcy5faW5uZXJTdGF0ZSA9PT0gbnVsbCB8fCB0eXBlb2YgdGhpcy5faW5uZXJTdGF0ZSA9PT0gJ3VuZGVmaW5lZCcpIHtcclxuICAgICAgICAgICAgd2lkdGggPSAtKHRoaXMuaGFuZGxlV2lkdGggLyAyKTtcclxuICAgICAgICB9IGVsc2UgaWYgKHRoaXMuX2RyYWdFbmQpIHtcclxuICAgICAgICAgICAgd2lkdGggPSB0aGlzLl9kcmFnRW5kO1xyXG4gICAgICAgIH0gZWxzZSBpZiAoIXRoaXMuX2lubmVyU3RhdGUpIHtcclxuICAgICAgICAgICAgaWYgKCF0aGlzLmludmVyc2UpIHtcclxuICAgICAgICAgICAgICAgIHdpZHRoID0gLXRoaXMuaGFuZGxlV2lkdGg7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICB3aWR0aCA9IDA7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHdpZHRoICsgJ3B4JztcclxuICAgIH1cclxuXHJcbiAgICBjb25zdHJ1Y3Rvcihwcml2YXRlIGNkOiBDaGFuZ2VEZXRlY3RvclJlZiwgcHJpdmF0ZSByZW5kZXI6IFJlbmRlcmVyMikge1xyXG4gICAgfVxyXG5cclxuICAgIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpIHtcclxuICAgICAgICBpZiAoY2hhbmdlc1snc2V0TGFiZWxUZXh0J10gfHxcclxuICAgICAgICAgICAgY2hhbmdlc1snc2V0T25UZXh0J10gfHxcclxuICAgICAgICAgICAgY2hhbmdlc1snc2V0SGFuZGxlV2lkdGgnXSB8fFxyXG4gICAgICAgICAgICBjaGFuZ2VzWydzZXRMYWJlbFdpZHRoJ10gfHxcclxuICAgICAgICAgICAgY2hhbmdlc1snc2V0T2ZmVGV4dCddIHx8XHJcbiAgICAgICAgICAgIGNoYW5nZXNbJ3NldFNpemUnXSkge1xyXG4gICAgICAgICAgICB0aGlzLmNhbGN1bGF0ZVdpdGgodHJ1ZSk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIG5nQWZ0ZXJWaWV3SW5pdCgpIHtcclxuICAgICAgICB0aGlzLmNhbGN1bGF0ZVdpdGgoKTtcclxuICAgIH1cclxuXHJcbiAgICBASG9zdExpc3RlbmVyKCdjbGljaycpIG9uQ2xpY2soKSB7XHJcbiAgICAgICAgaWYgKCF0aGlzLmRpc2FibGVkICYmICF0aGlzLnJlYWRvbmx5ICYmICF0aGlzLl9kcmFnRW5kKSB7XHJcbiAgICAgICAgICAgIHRoaXMuc2V0U3RhdGVWYWx1ZSghdGhpcy5faW5uZXJTdGF0ZSk7XHJcbiAgICAgICAgfSBlbHNlIGlmICh0aGlzLl9kcmFnRW5kKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX2RyYWdFbmQgPSBudWxsO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBASG9zdExpc3RlbmVyKCdrZXlkb3duJywgWyckZXZlbnQnXSkgb25LZXlEb3duKGU6IEtleWJvYXJkRXZlbnQpIHtcclxuICAgICAgICBpZiAoIWUud2hpY2ggfHwgdGhpcy5kaXNhYmxlZCB8fCB0aGlzLnJlYWRvbmx5KSB7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcbiAgICAgICAgc3dpdGNoIChlLndoaWNoKSB7XHJcbiAgICAgICAgICAgIGNhc2UgMzc6XHJcbiAgICAgICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICAgICAgICAgICAgICBlLnN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbigpO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZVZhbHVlKGZhbHNlKTtcclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICBjYXNlIDM5OlxyXG4gICAgICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgICAgICAgICAgICAgZS5zdG9wSW1tZWRpYXRlUHJvcGFnYXRpb24oKTtcclxuICAgICAgICAgICAgICAgIHRoaXMuc2V0U3RhdGVWYWx1ZSh0cnVlKTtcclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG5cclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBvbkRyYWdTdGFydChlOiBhbnkpOiB2b2lkIHtcclxuICAgICAgICBpZiAoZS50YXJnZXQgPT09IHRoaXMuJGxhYmVsKCkpIHtcclxuICAgICAgICAgICAgaWYgKHRoaXMuX2RyYWdTdGFydCB8fCB0aGlzLmRpc2FibGVkIHx8IHRoaXMucmVhZG9ubHkpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICAgICAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XHJcbiAgICAgICAgICAgIHRoaXMuX2RyYWdTdGFydCA9IChlLnBhZ2VYIHx8IGUudG91Y2hlc1swXS5wYWdlWCkgLSBwYXJzZUludCh0aGlzLiRjb250YWluZXIoKS5zdHlsZS5tYXJnaW5MZWZ0LCAxMCk7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLl9hbmltYXRlKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9hbmltYXRlID0gIXRoaXMuX2FuaW1hdGU7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBvbkRyYWdNb3ZlKGU6IGFueSk6IHZvaWQge1xyXG4gICAgICAgIGlmICh0aGlzLl9kcmFnU3RhcnQpIHtcclxuICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgICAgICAgICBjb25zdCBkaWZmZXJlbmNlID0gKGUucGFnZVggfHwgZS50b3VjaGVzWzBdLnBhZ2VYKSAtIHRoaXMuX2RyYWdTdGFydDtcclxuICAgICAgICAgICAgaWYgKGRpZmZlcmVuY2UgPCAtTnVtYmVyKHRoaXMuaGFuZGxlV2lkdGgpIHx8IGRpZmZlcmVuY2UgPiAwKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgdGhpcy5fZHJhZ0VuZCA9IGRpZmZlcmVuY2U7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgb25EcmFnRW5kKGU6IEV2ZW50LCByZW1vdmVEcmFnRW5kOiBib29sZWFuID0gZmFsc2UpIHtcclxuICAgICAgICBpZiAodGhpcy5fZHJhZ1N0YXJ0KSB7XHJcbiAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcclxuICAgICAgICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcclxuICAgICAgICAgICAgaWYgKHRoaXMuX2RyYWdFbmQpIHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IHN0YXRlID0gdGhpcy5fZHJhZ0VuZCA+IC0oTnVtYmVyKHRoaXMuaGFuZGxlV2lkdGgpIC8gMik7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnNldFN0YXRlVmFsdWUoKHRoaXMuaW52ZXJzZSkgPyAhc3RhdGUgOiBzdGF0ZSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgdGhpcy5fZHJhZ1N0YXJ0ID0gbnVsbDtcclxuICAgICAgICAgICAgaWYgKHJlbW92ZURyYWdFbmQpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuX2RyYWdFbmQgPSBudWxsO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmICh0aGlzLl9pbm5lckFuaW1hdGUpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuX2FuaW1hdGUgPSB0cnVlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIEBIb3N0TGlzdGVuZXIoJ3RvdWNoc3RhcnQnLCBbJyRldmVudCddKSBvblRvdWNoU3RhcnQoZTogYW55KSB7XHJcbiAgICAgICAgdGhpcy5vbkRyYWdTdGFydChlKTtcclxuICAgIH1cclxuXHJcbiAgICBASG9zdExpc3RlbmVyKCdtb3VzZWRvd24nLCBbJyRldmVudCddKSBvbk1vdXNlRG93bihlOiBhbnkpIHtcclxuICAgICAgICB0aGlzLm9uRHJhZ1N0YXJ0KGUpO1xyXG4gICAgfVxyXG5cclxuICAgIEBIb3N0TGlzdGVuZXIoJ3RvdWNobW92ZScsIFsnJGV2ZW50J10pIG9uVG91Y2hNb3ZlKGU6IGFueSkge1xyXG4gICAgICAgIHRoaXMub25EcmFnTW92ZShlKTtcclxuICAgIH1cclxuXHJcbiAgICBASG9zdExpc3RlbmVyKCdtb3VzZW1vdmUnLCBbJyRldmVudCddKSBvbk1vdXNlTW92ZShlOiBhbnkpIHtcclxuICAgICAgICB0aGlzLm9uRHJhZ01vdmUoZSk7XHJcbiAgICB9XHJcblxyXG4gICAgQEhvc3RMaXN0ZW5lcignbW91c2V1cCcsIFsnJGV2ZW50J10pIG9uTW91c2VVcChlOiBFdmVudCkge1xyXG4gICAgICAgIHRoaXMub25EcmFnRW5kKGUpO1xyXG4gICAgfVxyXG5cclxuICAgIEBIb3N0TGlzdGVuZXIoJ3RvdWNoZW5kJywgWyckZXZlbnQnXSkgb25Ub3VjaEVuZChlOiBFdmVudCkge1xyXG4gICAgICAgIHRoaXMub25EcmFnRW5kKGUsIHRydWUpO1xyXG4gICAgfVxyXG5cclxuICAgIEBIb3N0TGlzdGVuZXIoJ21vdXNlbGVhdmUnLCBbJyRldmVudCddKSBvbk1vdXNlTGVhdmUoZTogRXZlbnQpIHtcclxuICAgICAgICB0aGlzLm9uRHJhZ0VuZChlLCB0cnVlKTtcclxuICAgIH1cclxuXHJcbiAgICBvbkZvY3VzKCkge1xyXG4gICAgICAgIHRoaXMuX2ZvY3VzZWQgPSB0cnVlO1xyXG4gICAgfVxyXG5cclxuICAgIG9uQmx1cigpIHtcclxuICAgICAgICB0aGlzLl9mb2N1c2VkID0gZmFsc2U7XHJcbiAgICAgICAgdGhpcy5fb25Ub3VjaGVkQ2FsbGJhY2soKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEBkZXNjcmlwdGlvbiBGdW5jdGlvbiB0byBtYWtlIHJlY2FsY3VsYXRlIHRoZSBzaXplIG9mIHRoZSBlbGVtZW50cyB3aGVuIG9wdGlvbnMgY2hhbmdlXHJcbiAgICAgKiBAcGFyYW0gZGlzYWJsZUFuaW1hdGlvblxyXG4gICAgICovXHJcbiAgICBwcml2YXRlIGNhbGN1bGF0ZVdpdGgoZGlzYWJsZUFuaW1hdGlvbjogYm9vbGVhbiA9IGZhbHNlKTogdm9pZCB7XHJcbiAgICAgICAgaWYgKGRpc2FibGVBbmltYXRpb24gJiYgdGhpcy5faW5uZXJBbmltYXRlKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX2FuaW1hdGUgPSBmYWxzZTtcclxuICAgICAgICB9XHJcbiAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XHJcbiAgICAgICAgICAgIHRoaXMucmVuZGVyLnNldFN0eWxlKHRoaXMuJG9uKCksICd3aWR0aCcsICdhdXRvJyk7XHJcbiAgICAgICAgICAgIHRoaXMucmVuZGVyLnNldFN0eWxlKHRoaXMuJG9mZigpLCAnd2lkdGgnLCAnYXV0bycpO1xyXG4gICAgICAgICAgICB0aGlzLnJlbmRlci5zZXRTdHlsZSh0aGlzLiRsYWJlbCgpLCAnd2lkdGgnLCAnYXV0bycpO1xyXG5cclxuICAgICAgICAgICAgY29uc3Qgd2lkdGggPSAodGhpcy5faW5uZXJIYW5kbGVXaWR0aCA9PT0gJ2F1dG8nKVxyXG4gICAgICAgICAgICAgICAgPyBNYXRoLm1heCh0aGlzLiRvbigpLm9mZnNldFdpZHRoLCB0aGlzLiRvZmYoKS5vZmZzZXRXaWR0aClcclxuICAgICAgICAgICAgICAgIDogdGhpcy5faW5uZXJIYW5kbGVXaWR0aDtcclxuXHJcbiAgICAgICAgICAgIGlmICh0aGlzLiRsYWJlbCgpLm9mZnNldFdpZHRoIDwgd2lkdGgpIHtcclxuICAgICAgICAgICAgICAgIGlmICh0aGlzLl9pbm5lckxhYmVsV2lkdGggPT09ICdhdXRvJykge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMubGFiZWxXaWR0aCA9IE51bWJlcih3aWR0aCk7XHJcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMubGFiZWxXaWR0aCA9IE51bWJlcih0aGlzLl9pbm5lckxhYmVsV2lkdGgpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuX2lubmVyTGFiZWxXaWR0aCA9PT0gJ2F1dG8nKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5sYWJlbFdpZHRoID0gdGhpcy4kbGFiZWwoKS5vZmZzZXRXaWR0aDtcclxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5sYWJlbFdpZHRoID0gTnVtYmVyKHRoaXMuX2lubmVyTGFiZWxXaWR0aCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHRoaXMuaGFuZGxlV2lkdGggPSBOdW1iZXIod2lkdGgpO1xyXG5cclxuICAgICAgICAgICAgdGhpcy5yZW5kZXIuc2V0U3R5bGUodGhpcy4kbGFiZWwoKSwgJ3dpZHRoJywgdGhpcy5sYWJlbFdpZHRoICsgJ3B4Jyk7XHJcbiAgICAgICAgICAgIHRoaXMucmVuZGVyLnNldFN0eWxlKHRoaXMuJG9uKCksICd3aWR0aCcsIHRoaXMuaGFuZGxlV2lkdGggKyAncHgnKTtcclxuICAgICAgICAgICAgdGhpcy5yZW5kZXIuc2V0U3R5bGUodGhpcy4kb2ZmKCksICd3aWR0aCcsIHRoaXMuaGFuZGxlV2lkdGggKyAncHgnKTtcclxuICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICBpZiAoZGlzYWJsZUFuaW1hdGlvbiAmJiB0aGlzLl9pbm5lckFuaW1hdGUpIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLl9hbmltYXRlID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIHRoaXMuY2QubWFya0ZvckNoZWNrKCk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gRnVuY3Rpb25zIHRvIHNldCBpbnB1dHMgYW5kIHRoZSBwcml2YXRlIHZhcmlhYmxlcyBvZiB0aGUgU3dpdGNoXHJcbiAgICBASW5wdXQoJ3N3aXRjaC1iYXNlLWNsYXNzJykgc2V0IHNldEJhc2VDbGFzcyh2YWx1ZTogc3RyaW5nKSB7XHJcbiAgICAgICAgdGhpcy5iYXNlQ2xhc3MgPSB2YWx1ZTtcclxuICAgIH1cclxuXHJcbiAgICBASW5wdXQoJ3N3aXRjaC13cmFwcGVyLWNsYXNzJykgc2V0IHNldFdyYXBwZXJDbGFzcyh2YWx1ZTogc3RyaW5nKSB7XHJcbiAgICAgICAgdGhpcy5fd3JhcHBlckNsYXNzID0gdmFsdWU7XHJcbiAgICB9XHJcblxyXG4gICAgQElucHV0KCdzd2l0Y2gtb2ZmLXRleHQnKSBzZXQgc2V0T2ZmVGV4dCh2YWx1ZTogc3RyaW5nKSB7XHJcbiAgICAgICAgdGhpcy5vZmZUZXh0ID0gKHZhbHVlKSA/IHZhbHVlIDogJ09GRic7XHJcbiAgICB9XHJcblxyXG4gICAgQElucHV0KCdzd2l0Y2gtbGFiZWwtdGV4dCcpIHNldCBzZXRMYWJlbFRleHQodmFsdWU6IHN0cmluZykge1xyXG4gICAgICAgIHRoaXMubGFiZWxUZXh0ID0gdmFsdWU7XHJcbiAgICB9XHJcblxyXG4gICAgQElucHV0KCdzd2l0Y2gtb24tdGV4dCcpIHNldCBzZXRPblRleHQodmFsdWU6IHN0cmluZykge1xyXG4gICAgICAgIHRoaXMub25UZXh0ID0gKHZhbHVlKSA/IHZhbHVlIDogJ09OJztcclxuICAgIH1cclxuXHJcbiAgICBASW5wdXQoJ3N3aXRjaC1zaXplJykgc2V0IHNldFNpemUodmFsdWU6IHN0cmluZykge1xyXG4gICAgICAgIGlmICh2YWx1ZSkge1xyXG4gICAgICAgICAgICB0aGlzLl9zaXplID0gdmFsdWU7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIEBJbnB1dCgnc3dpdGNoLWFuaW1hdGUnKSBzZXQgc2V0QW5pbWF0ZSh2YWx1ZTogYm9vbGVhbikge1xyXG4gICAgICAgIHRoaXMuX2FuaW1hdGUgPSB2YWx1ZTtcclxuICAgICAgICB0aGlzLl9pbm5lckFuaW1hdGUgPSB2YWx1ZTtcclxuICAgIH1cclxuXHJcbiAgICBASW5wdXQoJ3N3aXRjaC1vbi1jb2xvcicpIHNldCBzZXRPbkNvbG9yKHZhbHVlOiBzdHJpbmcpIHtcclxuICAgICAgICBpZiAodmFsdWUpIHtcclxuICAgICAgICAgICAgdGhpcy5fb25Db2xvciA9IHZhbHVlO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBASW5wdXQoJ3N3aXRjaC1vZmYtY29sb3InKSBzZXQgc2V0T2ZmQ29sb3IodmFsdWU6IHN0cmluZykge1xyXG4gICAgICAgIGlmICh2YWx1ZSkge1xyXG4gICAgICAgICAgICB0aGlzLl9vZmZDb2xvciA9IHZhbHVlO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBASW5wdXQoJ3N3aXRjaC1kaXNhYmxlZCcpIHNldCBzZXREaXNhYmxlZCh2YWx1ZTogYm9vbGVhbikge1xyXG4gICAgICAgIHRoaXMuZGlzYWJsZWQgPSB2YWx1ZTtcclxuI