UNPKG

ontimize-web-ngx

Version:
245 lines 43.8 kB
import { __decorate, __metadata } from "tslib"; import { Component, ElementRef, forwardRef, Inject, Injector, Optional, ViewChild, ViewEncapsulation } from '@angular/core'; import moment from 'moment'; import { NgxMaterialTimepickerComponent } from 'ngx-material-timepicker'; import { BooleanInputConverter, NumberConverter } from '../../../decorators/input-converter'; import { Codes } from '../../../util/codes'; import { Util } from '../../../util/util'; import { OValidators } from '../../../validators/o-validators'; import { OFormValue } from '../../form/o-form-value'; import { OFormComponent } from '../../form/o-form.component'; import { OFormDataComponent } from '../../o-form-data-component.class'; import { OValueChangeEvent } from '../../o-value-change-event.class'; import * as i0 from "@angular/core"; import * as i1 from "@angular/flex-layout/flex"; import * as i2 from "@angular/forms"; import * as i3 from "../../../directives/o-mat-error.directive"; import * as i4 from "@angular/material/button"; import * as i5 from "@angular/material/icon"; import * as i6 from "@angular/material/input"; import * as i7 from "@angular/material/form-field"; import * as i8 from "@angular/material/tooltip"; import * as i9 from "@angular/common"; import * as i10 from "ngx-material-timepicker"; import * as i11 from "../../../pipes/o-translate.pipe"; import * as i12 from "../../form/o-form.component"; export const DEFAULT_INPUTS_O_HOUR_INPUT = [ 'format', 'textInputEnabled: text-input-enabled', 'min', 'max', 'valueType: value-type' ]; export class OHourInputComponent extends OFormDataComponent { constructor(form, elRef, injector) { super(form, elRef, injector); this.textInputEnabled = true; this._format = Codes.TWENTY_FOUR_HOUR_FORMAT; this.onKeyboardInputDone = false; this._valueType = 'timestamp'; this._defaultSQLTypeKey = 'TIMESTAMP'; } initialize() { super.initialize(); const formControl = this.getFormControl(); if (formControl) { const self = this; formControl.getValue = function () { return self.getValue(); }; } } ngAfterViewInit() { super.ngAfterViewInit(); this.modifyPickerMethods(); } onKeyDown(e) { if (!Codes.isHourInputAllowed(e)) { e.preventDefault(); } } innerOnBlur(event) { if (this.onKeyboardInputDone) { this.updateValeOnInputChange(event); } super.innerOnBlur(event); } registerOnFormControlChange() { } get formatString() { return (this.format === Codes.TWENTY_FOUR_HOUR_FORMAT ? Codes.HourFormat.TWENTY_FOUR : Codes.HourFormat.TWELVE); } open(e) { if (Util.isDefined(e)) { e.stopPropagation(); } if (this.picker) { this.picker.open(); } } setTime(event) { event.preventDefault(); event.stopPropagation(); const value = super.getValue(); this.picker.updateTime(value); } setTimestampValue(value, options) { let parsedValue; const momentV = Util.isDefined(value) ? moment(value) : value; if (momentV && momentV.isValid()) { parsedValue = momentV.utcOffset(0).format(this.formatString); } this.setValue(parsedValue, options); } resolveValidators() { const validators = super.resolveValidators(); if (this.format === Codes.TWENTY_FOUR_HOUR_FORMAT) { validators.push(OValidators.twentyFourHourFormatValidator); } else { validators.push(OValidators.twelveHourFormatValidator); } return validators; } set format(val) { const old = this._format; let parsedVal = NumberConverter(val); if (parsedVal !== Codes.TWELVE_FOUR_HOUR_FORMAT && parsedVal !== Codes.TWENTY_FOUR_HOUR_FORMAT) { parsedVal = Codes.TWENTY_FOUR_HOUR_FORMAT; } this._format = parsedVal; if (parsedVal !== old) { this.updateValidators(); } } get format() { return this._format; } set valueType(val) { this._valueType = this.convertToOHourValueType(val); } get valueType() { return this._valueType; } convertToOHourValueType(val) { const result = 'string'; const lowerVal = (val || '').toLowerCase(); if (lowerVal === 'string' || lowerVal === 'timestamp') { return lowerVal; } return result; } onChangeEvent(arg) { this.onTimepickerChange(arg.target.value); } onTimepickerChange(event) { let value = event; if (Util.isDefined(value) && this.valueType === 'timestamp') { const valueTimestamp = moment(value, this.formatString).valueOf(); if (!isNaN(valueTimestamp)) { value = valueTimestamp; } } this.setValue(value, { changeType: OValueChangeEvent.USER_CHANGE, emitEvent: false, emitModelToViewChange: false }); } modifyPickerMethods() { if (this.picker && this.picker.inputElement) { this.picker.inputElement.addEventListener('change', () => { this.onKeyboardInputDone = true; }); } } setFormValue(val, options, setDirty = false) { let stringValue = val; if (Util.isDefined(val) && this.valueType === 'timestamp') { let value = val instanceof OFormValue ? val.value : val; stringValue = this.getValueAsString(value); } this.ensureOFormValue(val); if (!this._fControl) { this._fControl = this.getControl(); } if (this._fControl) { this.updateOFormControlValue(stringValue, options, setDirty); } this.oldValue = this.value.value; } updateValeOnInputChange(blurEvent) { if (this.onKeyboardInputDone) { const value = this.parseHour(blurEvent.currentTarget.value); this.setValue(value); } this.onKeyboardInputDone = false; } parseHour(value) { const strArray = value.split(':'); let hour = strArray[0]; if (Codes.TWELVE_FOUR_HOUR_FORMAT === this.format) { if (hour) { hour = parseInt(hour, 10); const period = hour <= 12 ? ' AM' : ' PM'; if (hour > 12) { hour = hour - 12; } strArray[0] = hour; value = strArray.join(':') + period; } } else if (Codes.TWENTY_FOUR_HOUR_FORMAT === this.format) { } return value; } emitOnValueChange(type, newValue, oldValue) { this.onChange.emit(newValue); super.emitOnValueChange(type, newValue, oldValue); } getValueAsString(val) { let value; if (typeof val === 'number') { value = moment(val).format(this.formatString); } else { value = this.convertToFormatString(val); } return value; } convertToFormatString(value) { if (value === '00:00' || !Util.isDefined(value)) { return value; } const formatStr = this.format === Codes.TWENTY_FOUR_HOUR_FORMAT ? 'HH:mm' : 'hh:mm a'; let result; if (typeof value === 'number') { result = moment(value).format(formatStr); } else { result = value ? moment(value, 'h:mm A').format(formatStr) : value; } return result; } } OHourInputComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: OHourInputComponent, deps: [{ token: forwardRef(() => OFormComponent), optional: true }, { token: i0.ElementRef }, { token: i0.Injector }], target: i0.ɵɵFactoryTarget.Component }); OHourInputComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: OHourInputComponent, selector: "o-hour-input", inputs: { format: "format", textInputEnabled: ["text-input-enabled", "textInputEnabled"], min: "min", max: "max", valueType: ["value-type", "valueType"] }, host: { properties: { "class.o-hour-input": "true" } }, viewQueries: [{ propertyName: "picker", first: true, predicate: ["picker"], descendants: true }], usesInheritance: true, ngImport: i0, template: "<div fxLayout=\"row\" fxLayoutAlign=\"space-between center\" [formGroup]=\"getFormGroup()\" [matTooltip]=\"tooltip\" [matTooltipClass]=\"tooltipClass\"\n [matTooltipPosition]=\"tooltipPosition\" [matTooltipShowDelay]=\"tooltipShowDelay\" [matTooltipHideDelay]=\"tooltipHideDelay\">\n <mat-form-field [appearance]=\"appearance\" [floatLabel]=\"floatLabel\" fxFill [hideRequiredMarker]=\"hideRequiredMarker\" class=\"icon-field\"\n [subscriptSizing]=\"subscriptSizing\">\n <mat-label *ngIf=\"labelVisible\">{{ olabel | oTranslate }}</mat-label>\n <input matInput [ngxTimepicker]=\"picker\" [id]=\"getAttribute()\" [placeholder]=\"placeHolder\" [formControlName]=\"getAttribute()\"\n [readonly]=\"isReadOnly || !textInputEnabled\" (focus)=\"innerOnFocus($event)\" (blur)=\"innerOnBlur($event)\" [required]=\"isRequired\"\n (change)=\"onChangeEvent($event)\" [min]=\"min\" [max]=\"max\" (keydown)=\"onKeyDown($event)\" [format]=\"format\" [disableClick]=\"true\">\n\n <button type=\"button\" *ngIf=\"showClearButton\" matSuffix mat-icon-button (click)=\"onClickClearValue($event)\">\n <mat-icon svgIcon=\"ontimize:close\"></mat-icon>\n </button>\n <button type=\"button\" matSuffix mat-icon-button [disabled]=\"isReadOnly || !enabled\" (click)=\"open($event)\">\n <mat-icon ngxMaterialTimepickerToggleIcon svgIcon=\"ontimize:clock\"></mat-icon>\n </button>\n\n <mat-error *oMatError=\"hasError('required')\">\n {{ 'FORM_VALIDATION.REQUIRED' | oTranslate }}\n </mat-error>\n <mat-error *oMatError=\"hasError('invalidFormatHour')\">\n {{ 'FORM_VALIDATION.HOUR_FORMAT' | oTranslate }} {{ formatString }}\n </mat-error>\n <mat-error *ngFor=\"let oError of getActiveOErrors()\">\n {{ oError.text | oTranslate }}\n </mat-error>\n </mat-form-field>\n</div>\n\n<ngx-material-timepicker #picker (timeSet)=\"onTimepickerChange($event)\" [confirmBtnTmpl]=\"confirmBtn\" [cancelBtnTmpl]=\"cancelBtn\">\n</ngx-material-timepicker>\n\n<ng-template #confirmBtn>\n <button mat-stroked-button type=\"button\"><span>{{'OK' | oTranslate}}</span></button>\n</ng-template>\n\n<ng-template #cancelBtn>\n <button mat-stroked-button type=\"button\"><span>{{'CANCEL' | oTranslate}}</span></button>\n</ng-template>\n", styles: ["ngx-material-timepicker-container button.mat-mdc-outlined-button{margin:0 6px}ngx-material-timepicker-container .timepicker-backdrop-overlay,ngx-material-timepicker-container .timepicker-overlay{z-index:1001!important}\n"], dependencies: [{ kind: "directive", type: i1.DefaultLayoutDirective, selector: " [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]", inputs: ["fxLayout", "fxLayout.xs", "fxLayout.sm", "fxLayout.md", "fxLayout.lg", "fxLayout.xl", "fxLayout.lt-sm", "fxLayout.lt-md", "fxLayout.lt-lg", "fxLayout.lt-xl", "fxLayout.gt-xs", "fxLayout.gt-sm", "fxLayout.gt-md", "fxLayout.gt-lg"] }, { kind: "directive", type: i1.DefaultLayoutAlignDirective, selector: " [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]", inputs: ["fxLayoutAlign", "fxLayoutAlign.xs", "fxLayoutAlign.sm", "fxLayoutAlign.md", "fxLayoutAlign.lg", "fxLayoutAlign.xl", "fxLayoutAlign.lt-sm", "fxLayoutAlign.lt-md", "fxLayoutAlign.lt-lg", "fxLayoutAlign.lt-xl", "fxLayoutAlign.gt-xs", "fxLayoutAlign.gt-sm", "fxLayoutAlign.gt-md", "fxLayoutAlign.gt-lg"] }, { kind: "directive", type: i1.FlexFillDirective, selector: "[fxFill], [fxFlexFill]" }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i3.OMatErrorDirective, selector: "[oMatError]", inputs: ["oMatError"] }, { kind: "component", type: i4.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "component", type: i4.MatIconButton, selector: "button[mat-icon-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "component", type: i5.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i6.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i7.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i7.MatLabel, selector: "mat-label" }, { kind: "directive", type: i7.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i7.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "directive", type: i8.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }, { kind: "directive", type: i9.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i9.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i10.NgxMaterialTimepickerComponent, selector: "ngx-material-timepicker", inputs: ["ESC", "hoursOnly", "ngxMaterialTimepickerTheme", "format", "minutesGap", "cancelBtnTmpl", "editableHintTmpl", "confirmBtnTmpl", "enableKeyboardInput", "preventOverlayClick", "disableAnimation", "appendToInput", "defaultTime", "timepickerClass", "theme"], outputs: ["timeSet", "opened", "closed", "hourSelected", "timeChanged"] }, { kind: "directive", type: i10.TimepickerDirective, selector: "[ngxTimepicker]", inputs: ["format", "value", "min", "max", "ngxTimepicker", "disabled", "disableClick"] }, { kind: "directive", type: i10.NgxMaterialTimepickerToggleIconDirective, selector: "[ngxMaterialTimepickerToggleIcon]" }, { kind: "pipe", type: i11.OTranslatePipe, name: "oTranslate" }], encapsulation: i0.ViewEncapsulation.None }); __decorate([ BooleanInputConverter(), __metadata("design:type", Boolean) ], OHourInputComponent.prototype, "textInputEnabled", void 0); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: OHourInputComponent, decorators: [{ type: Component, args: [{ selector: 'o-hour-input', encapsulation: ViewEncapsulation.None, inputs: DEFAULT_INPUTS_O_HOUR_INPUT, host: { '[class.o-hour-input]': 'true' }, template: "<div fxLayout=\"row\" fxLayoutAlign=\"space-between center\" [formGroup]=\"getFormGroup()\" [matTooltip]=\"tooltip\" [matTooltipClass]=\"tooltipClass\"\n [matTooltipPosition]=\"tooltipPosition\" [matTooltipShowDelay]=\"tooltipShowDelay\" [matTooltipHideDelay]=\"tooltipHideDelay\">\n <mat-form-field [appearance]=\"appearance\" [floatLabel]=\"floatLabel\" fxFill [hideRequiredMarker]=\"hideRequiredMarker\" class=\"icon-field\"\n [subscriptSizing]=\"subscriptSizing\">\n <mat-label *ngIf=\"labelVisible\">{{ olabel | oTranslate }}</mat-label>\n <input matInput [ngxTimepicker]=\"picker\" [id]=\"getAttribute()\" [placeholder]=\"placeHolder\" [formControlName]=\"getAttribute()\"\n [readonly]=\"isReadOnly || !textInputEnabled\" (focus)=\"innerOnFocus($event)\" (blur)=\"innerOnBlur($event)\" [required]=\"isRequired\"\n (change)=\"onChangeEvent($event)\" [min]=\"min\" [max]=\"max\" (keydown)=\"onKeyDown($event)\" [format]=\"format\" [disableClick]=\"true\">\n\n <button type=\"button\" *ngIf=\"showClearButton\" matSuffix mat-icon-button (click)=\"onClickClearValue($event)\">\n <mat-icon svgIcon=\"ontimize:close\"></mat-icon>\n </button>\n <button type=\"button\" matSuffix mat-icon-button [disabled]=\"isReadOnly || !enabled\" (click)=\"open($event)\">\n <mat-icon ngxMaterialTimepickerToggleIcon svgIcon=\"ontimize:clock\"></mat-icon>\n </button>\n\n <mat-error *oMatError=\"hasError('required')\">\n {{ 'FORM_VALIDATION.REQUIRED' | oTranslate }}\n </mat-error>\n <mat-error *oMatError=\"hasError('invalidFormatHour')\">\n {{ 'FORM_VALIDATION.HOUR_FORMAT' | oTranslate }} {{ formatString }}\n </mat-error>\n <mat-error *ngFor=\"let oError of getActiveOErrors()\">\n {{ oError.text | oTranslate }}\n </mat-error>\n </mat-form-field>\n</div>\n\n<ngx-material-timepicker #picker (timeSet)=\"onTimepickerChange($event)\" [confirmBtnTmpl]=\"confirmBtn\" [cancelBtnTmpl]=\"cancelBtn\">\n</ngx-material-timepicker>\n\n<ng-template #confirmBtn>\n <button mat-stroked-button type=\"button\"><span>{{'OK' | oTranslate}}</span></button>\n</ng-template>\n\n<ng-template #cancelBtn>\n <button mat-stroked-button type=\"button\"><span>{{'CANCEL' | oTranslate}}</span></button>\n</ng-template>\n", styles: ["ngx-material-timepicker-container button.mat-mdc-outlined-button{margin:0 6px}ngx-material-timepicker-container .timepicker-backdrop-overlay,ngx-material-timepicker-container .timepicker-overlay{z-index:1001!important}\n"] }] }], ctorParameters: function () { return [{ type: i12.OFormComponent, decorators: [{ type: Optional }, { type: Inject, args: [forwardRef(() => OFormComponent)] }] }, { type: i0.ElementRef }, { type: i0.Injector }]; }, propDecorators: { textInputEnabled: [], picker: [{ type: ViewChild, args: ['picker'] }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiby1ob3VyLWlucHV0LmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL29udGltaXplLXdlYi1uZ3gvc3JjL2xpYi9jb21wb25lbnRzL2lucHV0L2hvdXItaW5wdXQvby1ob3VyLWlucHV0LmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL29udGltaXplLXdlYi1uZ3gvc3JjL2xpYi9jb21wb25lbnRzL2lucHV0L2hvdXItaW5wdXQvby1ob3VyLWlucHV0LmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxPQUFPLEVBQWlCLFNBQVMsRUFBRSxVQUFVLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSxRQUFRLEVBQVUsUUFBUSxFQUFFLFNBQVMsRUFBRSxpQkFBaUIsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUVuSixPQUFPLE1BQU0sTUFBTSxRQUFRLENBQUM7QUFDNUIsT0FBTyxFQUFFLDhCQUE4QixFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFFekUsT0FBTyxFQUFFLHFCQUFxQixFQUFFLGVBQWUsRUFBRSxNQUFNLHFDQUFxQyxDQUFDO0FBRTdGLE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUM1QyxPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDMUMsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLGtDQUFrQyxDQUFDO0FBQy9ELE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUNyRCxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFDN0QsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sbUNBQW1DLENBQUM7QUFDdkUsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sa0NBQWtDLENBQUM7Ozs7Ozs7Ozs7Ozs7O0FBS3JFLE1BQU0sQ0FBQyxNQUFN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QU07MkJBQUMsVUFBVSxDQUFDLEdBQUcsRUFBRSxDQUFDLGNBQWMsQ0FBQzs0RkFYL0MsZ0JBQWdCLE1BUWhCLE1BQU07c0JBRFosU0FBUzt1QkFBQyxRQUFRIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQWZ0ZXJWaWV3SW5pdCwgQ29tcG9uZW50LCBFbGVtZW50UmVmLCBmb3J3YXJkUmVmLCBJbmplY3QsIEluamVjdG9yLCBPbkluaXQsIE9wdGlvbmFsLCBWaWV3Q2hpbGQsIFZpZXdFbmNhcHN1bGF0aW9uIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBWYWxpZGF0b3JGbiB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCBtb21lbnQgZnJvbSAnbW9tZW50JztcbmltcG9ydCB7IE5neE1hdGVyaWFsVGltZXBpY2tlckNvbXBvbmVudCB9IGZyb20gJ25neC1tYXRlcmlhbC10aW1lcGlja2VyJztcblxuaW1wb3J0IHsgQm9vbGVhbklucHV0Q29udmVydGVyLCBOdW1iZXJDb252ZXJ0ZXIgfSBmcm9tICcuLi8uLi8uLi9kZWNvcmF0b3JzL2lucHV0LWNvbnZlcnRlcic7XG5pbXBvcnQgeyBGb3JtVmFsdWVPcHRpb25zIH0gZnJvbSAnLi4vLi4vLi4vdHlwZXMvZm9ybS12YWx1ZS1vcHRpb25zLnR5cGUnO1xuaW1wb3J0IHsgQ29kZXMgfSBmcm9tICcuLi8uLi8uLi91dGlsL2NvZGVzJztcbmltcG9ydCB7IFV0aWwgfSBmcm9tICcuLi8uLi8uLi91dGlsL3V0aWwnO1xuaW1wb3J0IHsgT1ZhbGlkYXRvcnMgfSBmcm9tICcuLi8uLi8uLi92YWxpZGF0b3JzL28tdmFsaWRhdG9ycyc7XG5pbXBvcnQgeyBPRm9ybVZhbHVlIH0gZnJvbSAnLi4vLi4vZm9ybS9vLWZvcm0tdmFsdWUnO1xuaW1wb3J0IHsgT0Zvcm1Db21wb25lbnQgfSBmcm9tICcuLi8uLi9mb3JtL28tZm9ybS5jb21wb25lbnQnO1xuaW1wb3J0IHsgT0Zvcm1EYXRhQ29tcG9uZW50IH0gZnJvbSAnLi4vLi4vby1mb3JtLWRhdGEtY29tcG9uZW50LmNsYXNzJztcbmltcG9ydCB7IE9WYWx1ZUNoYW5nZUV2ZW50IH0gZnJvbSAnLi4vLi4vby12YWx1ZS1jaGFuZ2UtZXZlbnQuY2xhc3MnO1xuaW1wb3J0IHsgT0Zvcm1Db250cm9sIH0gZnJvbSAnLi4vby1mb3JtLWNvbnRyb2wuY2xhc3MnO1xuXG5leHBvcnQgdHlwZSBPSG91clZhbHVlVHlwZSA9ICdzdHJpbmcnIHwgJ3RpbWVzdGFtcCc7XG5cbmV4cG9ydCBjb25zdCBERUZBVUxUX0lOUFVUU19PX0hPVVJfSU5QVVQgPSBbXG4gICdmb3JtYXQnLFxuICAndGV4dElucHV0RW5hYmxlZDogdGV4dC1pbnB1dC1lbmFibGVkJyxcbiAgJ21pbicsXG4gICdtYXgnLFxuICAndmFsdWVUeXBlOiB2YWx1ZS10eXBlJ1xuXTtcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnby1ob3VyLWlucHV0JyxcbiAgdGVtcGxhdGVVcmw6ICcuL28taG91ci1pbnB1dC5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL28taG91ci1pbnB1dC5jb21wb25lbnQuc2NzcyddLFxuICBlbmNhcHN1bGF0aW9uOiBWaWV3RW5jYXBzdWxhdGlvbi5Ob25lLFxuICBpbnB1dHM6IERFRkFVTFRfSU5QVVRTX09fSE9VUl9JTlBVVCxcbiAgaG9zdDoge1xuICAgICdbY2xhc3Muby1ob3VyLWlucHV0XSc6ICd0cnVlJ1xuICB9XG59KVxuZXhwb3J0IGNsYXNzIE9Ib3VySW5wdXRDb21wb25lbnQgZXh0ZW5kcyBPRm9ybURhdGFDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIEFmdGVyVmlld0luaXQge1xuXG4gIEBCb29sZWFuSW5wdXRDb252ZXJ0ZXIoKVxuICBwdWJsaWMgdGV4dElucHV0RW5hYmxlZDogYm9vbGVhbiA9IHRydWU7XG4gIHB1YmxpYyBtaW46IHN0cmluZztcbiAgcHVibGljIG1heDogc3RyaW5nO1xuICBwcm90ZWN0ZWQgX2Zvcm1hdDogbnVtYmVyID0gQ29kZXMuVFdFTlRZX0ZPVVJfSE9VUl9GT1JNQVQ7XG4gIHByb3RlY3RlZCBvbktleWJvYXJkSW5wdXREb25lID0gZmFsc2U7XG4gIHByb3RlY3RlZCBfdmFsdWVUeXBlOiBPSG91clZhbHVlVHlwZSA9ICd0aW1lc3RhbXAnO1xuXG4gIEBWaWV3Q2hpbGQoJ3BpY2tlcicpXG4gIHB1YmxpYyBwaWNrZXI6IE5neE1hdGVyaWFsVGltZXBpY2tlckNvbXBvbmVudDtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBAT3B0aW9uYWwoKSBASW5qZWN0KGZvcndhcmRSZWYoKCkgPT4gT0Zvcm1Db21wb25lbnQpKSBmb3JtOiBPRm9ybUNvbXBvbmVudCxcbiAgICBlbFJlZjogRWxlbWVudFJlZixcbiAgICBpbmplY3RvcjogSW5qZWN0b3JcbiAgKSB7XG4gICAgc3VwZXIoZm9ybSwgZWxSZWYsIGluamVjdG9yKTtcbiAgICB0aGlzLl9kZWZhdWx0U1FMVHlwZUtleSA9ICdUSU1FU1RBTVAnO1xuICB9XG5cbiAgaW5pdGlhbGl6ZSgpOiB2b2lkIHtcbiAgICBzdXBlci5pbml0aWFsaXplKCk7XG4gICAgY29uc3QgZm9ybUNvbnRyb2wgPSB0aGlzLmdldEZvcm1Db250cm9sKCkgYXMgT0Zvcm1Db250cm9sO1xuICAgIGlmIChmb3JtQ29udHJvbCkge1xuICAgICAgY29uc3Qgc2VsZiA9IHRoaXM7XG4gICAgICBmb3JtQ29udHJvbC5nZXRWYWx1ZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHNlbGYuZ2V0VmFsdWUoKTtcbiAgICAgIH07XG4gICAgfVxuICB9XG5cbiAgcHVibGljIG5nQWZ0ZXJWaWV3SW5pdCgpOiB2b2lkIHtcbiAgICBzdXBlci5uZ0FmdGVyVmlld0luaXQoKTtcbiAgICB0aGlzLm1vZGlmeVBpY2tlck1ldGhvZHMoKTtcbiAgfVxuXG4gIHB1YmxpYyBvbktleURvd24oZTogS2V5Ym9hcmRFdmVudCk6IHZvaWQge1xuICAgIGlmICghQ29kZXMuaXNIb3VySW5wdXRBbGxvd2VkKGUpKSB7XG4gICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgfVxuICB9XG5cbiAgcHVibGljIGlubmVyT25CbHVyKGV2ZW50OiBhbnkpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5vbktleWJvYXJkSW5wdXREb25lKSB7XG4gICAgICB0aGlzLnVwZGF0ZVZhbGVPbklucHV0Q2hhbmdlKGV2ZW50KTtcbiAgICB9XG4gICAgc3VwZXIuaW5uZXJPbkJsdXIoZXZlbnQpO1xuICB9XG5cbiAgcHVibGljIHJlZ2lzdGVyT25Gb3JtQ29udHJvbENoYW5nZSgpOiB2b2lkIHtcbiAgICAvLyBUaGlzIGNvbXBvbmVudCBkb2VzIG5vdCBuZWVkIHRoaXMgc3Vic2NyaXB0aW9uXG4gIH1cblxuICBnZXQgZm9ybWF0U3RyaW5nKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuICh0aGlzLmZvcm1hdCA9PT0gQ29kZXMuVFdFTlRZX0ZPVVJfSE9VUl9GT1JNQVQgPyBDb2Rlcy5Ib3VyRm9ybWF0LlRXRU5UWV9GT1VSIDogQ29kZXMuSG91ckZvcm1hdC5UV0VMVkUpO1xuICB9XG5cbiAgcHVibGljIG9wZW4oZT86IEV2ZW50KTogdm9pZCB7XG4gICAgaWYgKFV0aWwuaXNEZWZpbmVkKGUpKSB7XG4gICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIH1cbiAgICBpZiAodGhpcy5waWNrZXIpIHtcbiAgICAgIHRoaXMucGlja2VyLm9wZW4oKTtcbiAgICB9XG4gIH1cblxuICBzZXRUaW1lKGV2ZW50KSB7XG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAvLyBnZXR0aW5nIHZhbHVlIGZyb20gc3VwZXIgc28gd2UgY2FuIGFsd2F5cyBnZXQgYSBzdHJpbmcgdmFsdWVcbiAgICBjb25zdCB2YWx1ZSA9IHN1cGVyLmdldFZhbHVlKCk7XG4gICAgdGhpcy5waWNrZXIudXBkYXRlVGltZSh2YWx1ZSk7XG4gIH1cblxuICBwdWJsaWMgc2V0VGltZXN0YW1wVmFsdWUodmFsdWU6IGFueSwgb3B0aW9ucz86IEZvcm1WYWx1ZU9wdGlvbnMpOiB2b2lkIHtcbiAgICBsZXQgcGFyc2VkVmFsdWU7XG4gICAgY29uc3QgbW9tZW50ViA9IFV0aWwuaXNEZWZpbmVkKHZhbHVlKSA/IG1vbWVudCh2YWx1ZSkgOiB2YWx1ZTtcbiAgICBpZiAobW9tZW50ViAmJiBtb21lbnRWLmlzVmFsaWQoKSkge1xuICAgICAgcGFyc2VkVmFsdWUgPSBtb21lbnRWLnV0Y09mZnNldCgwKS5mb3JtYXQodGhpcy5mb3JtYXRTdHJpbmcpO1xuICAgIH1cbiAgICB0aGlzLnNldFZhbHVlKHBhcnNlZFZhbHVlLCBvcHRpb25zKTtcbiAgfVxuXG4gIHB1YmxpYyByZXNvbHZlVmFsaWRhdG9ycygpOiBWYWxpZGF0b3JGbltdIHtcbiAgICBjb25zdCB2YWxpZGF0b3JzOiBWYWxpZGF0b3JGbltdID0gc3VwZXIucmVzb2x2ZVZhbGlkYXRvcnMoKTtcbiAgICBpZiAodGhpcy5mb3JtYXQgPT09IENvZGVzLlRXRU5UWV9GT1VSX0hPVVJfRk9STUFUKSB7XG4gICAgICB2YWxpZGF0b3JzLnB1c2goT1ZhbGlkYXRvcnMudHdlbnR5Rm91ckhvdXJGb3JtYXRWYWxpZGF0b3IpO1xuICAgIH0gZWxzZSB7XG4gICAgICB2YWxpZGF0b3JzLnB1c2goT1ZhbGlkYXRvcnMudHdlbHZlSG91ckZvcm1hdFZhbGlkYXRvcik7XG4gICAgfVxuICAgIHJldHVybiB2YWxpZGF0b3JzO1xuICB9XG5cbiAgc2V0IGZvcm1hdCh2YWw6IG51bWJlcikge1xuICAgIGNvbnN0IG9sZCA9IHRoaXMuX2Zvcm1hdDtcbiAgICBsZXQgcGFyc2VkVmFsID0gTnVtYmVyQ29udmVydGVyKHZhbCk7XG4gICAgaWYgKHBhcnNlZFZhbCAhPT0gQ29kZXMuVFdFTFZFX0ZPVVJfSE9VUl9GT1JNQVQgJiYgcGFyc2VkVmFsICE9PSBDb2Rlcy5UV0VOVFlfRk9VUl9IT1VSX0ZPUk1BVCkge1xuICAgICAgcGFyc2VkVmFsID0gQ29kZXMuVFdFTlRZX0ZPVVJfSE9VUl9GT1JNQVQ7XG4gICAgfVxuICAgIHRoaXMuX2Zvcm1hdCA9IHBhcnNlZFZhbDtcbiAgICBpZiAocGFyc2VkVmFsICE9PSBvbGQpIHtcbiAgICAgIHRoaXMudXBkYXRlVmFsaWRhdG9ycygpO1xuICAgIH1cbiAgfVxuXG4gIGdldCBmb3JtYXQoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5fZm9ybWF0O1xuICB9XG5cbiAgc2V0IHZhbHVlVHlwZSh2YWw6IGFueSkge1xuICAgIHRoaXMuX3ZhbHVlVHlwZSA9IHRoaXMuY29udmVydFRvT0hvdXJWYWx1ZVR5cGUodmFsKTtcbiAgfVxuXG4gIGdldCB2YWx1ZVR5cGUoKTogYW55IHtcbiAgICByZXR1cm4gdGhpcy5fdmFsdWVUeXBlO1xuICB9XG5cbiAgcHVibGljIGNvbnZlcnRUb09Ib3VyVmFsdWVUeXBlKHZhbDogYW55KTogT0hvdXJWYWx1ZVR5cGUge1xuICAgIGNvbnN0IHJlc3VsdDogT0hvdXJWYWx1ZVR5cGUgPSAnc3RyaW5nJztcbiAgICBjb25zdCBsb3dlclZhbCA9ICh2YWwgfHwgJycpLnRvTG93ZXJDYXNlKCk7XG4gICAgaWYgKGxvd2VyVmFsID09PSAnc3RyaW5nJyB8fCBsb3dlclZhbCA9PT0gJ3RpbWVzdGFtcCcpIHtcbiAgICAgIHJldHVybiBsb3dlclZhbDtcbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIHB1YmxpYyBvbkNoYW5nZUV2ZW50KGFyZzogYW55KTogdm9pZCB7XG4gICAgdGhpcy5vblRpbWVwaWNrZXJDaGFuZ2UoYXJnLnRhcmdldC52YWx1ZSk7XG4gIH1cblxuICBwdWJsaWMgb25UaW1lcGlja2VyQ2hhbmdlKGV2ZW50OiBzdHJpbmcpOiB2b2lkIHtcbiAgICBsZXQgdmFsdWU6IGFueSA9IGV2ZW50O1xuICAgIGlmIChVdGlsLmlzRGVmaW5lZCh2YWx1ZSkgJiYgdGhpcy52YWx1ZVR5cGUgPT09ICd0aW1lc3RhbXAnKSB7XG4gICAgICBjb25zdCB2YWx1ZVRpbWVzdGFtcCA9IG1vbWVudCh2YWx1ZSwgdGhpcy5mb3JtYXRTdHJpbmcpLnZhbHVlT2YoKTtcbiAgICAgIGlmICghaXNOYU4odmFsdWVUaW1lc3RhbXApKSB7XG4gICAgICAgIHZhbHVlID0gdmFsdWVUaW1lc3RhbXA7XG4gICAgICB9XG4gICAgfVxuICAgIC8qKiBlbWl0TW9kZWxUb1ZpZXdDaGFuZ2U6IGZhbHNlICBiZWNhdXNlIG9uQ2hhbmdlIGV2ZW50IGlzIHRyaWdnZXIgaW4gbmdNb2RlbENoYW5nZSAqL1xuICAgIHRoaXMuc2V0VmFsdWUodmFsdWUsIHtcbiAgICAgIGNoYW5nZVR5cGU6IE9WYWx1ZUNoYW5nZUV2ZW50LlVTRVJfQ0hBTkdFLFxuICAgICAgZW1pdEV2ZW50OiBmYWxzZSxcbiAgICAgIGVtaXRNb2RlbFRvVmlld0NoYW5nZTogZmFsc2VcbiAgICB9KTtcbiAgfVxuXG4gIHByb3RlY3RlZCBtb2RpZnlQaWNrZXJNZXRob2RzKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLnBpY2tlciAmJiB0aGlzLnBpY2tlci5pbnB1dEVsZW1lbnQpIHtcbiAgICAgIHRoaXMucGlja2VyLmlucHV0RWxlbWVudC5hZGRFdmVudExpc3RlbmVyKCdjaGFuZ2UnLCAoKSA9PiB7XG4gICAgICAgIHRoaXMub25LZXlib2FyZElucHV0RG9uZSA9IHRydWU7XG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICBwcm90ZWN0ZWQgc2V0Rm9ybVZhbHVlKHZhbDogYW55LCBvcHRpb25zPzogRm9ybVZhbHVlT3B0aW9ucywgc2V0RGlydHk6IGJvb2xlYW4gPSBmYWxzZSk6IHZvaWQge1xuICAgIGxldCBzdHJpbmdWYWx1ZSA9IHZhbDtcbiAgICBpZiAoVXRpbC5pc0RlZmluZWQodmFsKSAmJiB0aGlzLnZhbHVlVHlwZSA9PT0gJ3RpbWVzdGFtcCcpIHtcbiAgICAgIC8vIGJlY2F1c2Ugb2YgdGhlIG5neC1tYXRlcmlhbC10aW1lcGlja2VyIGVzcGVjaWZpY2F0aW9uLCBpdHMgc3RvcmVkIHZhbHVlIG11c3QgYmUgYWx3YXlzIGEgc3RyaW5nXG4gICAgICBsZXQgdmFsdWUgPSB2YWwgaW5zdGFuY2VvZiBPRm9ybVZhbHVlID8gdmFsLnZhbHVlIDogdmFsO1xuICAgICAgc3RyaW5nVmFsdWUgPSB0aGlzLmdldFZhbHVlQXNTdHJpbmcodmFsdWUpO1xuICAgIH1cbiAgICB0aGlzLmVuc3VyZU9Gb3JtVmFsdWUodmFsKTtcbiAgICBpZiAoIXRoaXMuX2ZDb250cm9sKSB7XG4gICAgICAvLyBlbnN1cmluZyBfZkNvbnRyb2wgY3JlYXRpb25cbiAgICAgIHRoaXMuX2ZDb250cm9sID0gdGhpcy5nZXRDb250cm9sKCk7XG4gICAgfVxuICAgIGlmICh0aGlzLl9mQ29udHJvbCkge1xuICAgICAgdGhpcy51cGRhdGVPRm9ybUNvbnRyb2xWYWx1ZShzdHJpbmdWYWx1ZSwgb3B0aW9ucywgc2V0RGlydHkpO1xuICAgIH1cbiAgICB0aGlzLm9sZFZhbHVlID0gdGhpcy52YWx1ZS52YWx1ZTtcbiAgfVxuXG4gIHByb3RlY3RlZCB1cGRhdGVWYWxlT25JbnB1dENoYW5nZShibHVyRXZlbnQ6IGFueSk6IHZvaWQge1xuICAgIGlmICh0aGlzLm9uS2V5Ym9hcmRJbnB1dERvbmUpIHtcbiAgICAgIC8vIG5neC1tYXRlcmlhbC10aW1lcGlja2VyIGRvZXMgbm90IGFsbG93IHdyaXRpbmcgY2hhcmFjdGVycyBvbiBpbnB1dCwgc28gd2UgYWRkICdBTS9QTScgaW4gb3JkZXIgdG8gbWFrZSB2YWxpZGF0aW9uIHdvcmsgcHJvcGVybHlcbiAgICAgIGNvbnN0IHZhbHVlID0gdGhpcy5wYXJzZUhvdXIoYmx1ckV2ZW50LmN1cnJlbnRUYXJnZXQudmFsdWUpO1xuICAgICAgdGhpcy5zZXRWYWx1ZSh2YWx1ZSk7XG4gICAgfVxuICAgIHRoaXMub25LZXlib2FyZElucHV0RG9uZSA9IGZhbHNlO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlY2VpdmVzIGFuIGhvdXIgaW5wdXQgaW50cm9kdWNlZCBieSB0aGUgdXNlciBhbmQgcmV0dXJucyB0aGUgaG91ciBmb3JtYXRlZCBhY29yZGluZyBjdXJyZW50IGZvcm1hdFxuICAgKiBAcGFyYW0gdmFsdWVcbiAgICovXG4gIHByb3RlY3RlZCBwYXJzZUhvdXIodmFsdWU6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgY29uc3Qgc3RyQXJyYXkgPSB2YWx1ZS5zcGxpdCgnOicpO1xuICAgIGxldCBob3VyOiBhbnkgPSBzdHJBcnJheVswXTtcblxuICAgIGlmIChDb2Rlcy5UV0VMVkVfRk9VUl9IT1VSX0ZPUk1BVCA9PT0gdGhpcy5mb3JtYXQpIHtcbiAgICAgIGlmIChob3VyKSB7XG4gICAgICAgIGhvdXIgPSBwYXJzZUludChob3VyLCAxMCk7XG4gICAgICAgIGNvbnN0IHBlcmlvZCA9IGhvdXIgPD0gMTIgPyAnIEFNJyA6ICcgUE0nO1xuICAgICAgICBpZiAoaG91ciA+IDEyKSB7XG4gICAgICAgICAgaG91ciA9IGhvdXIgLSAxMjtcbiAgICAgICAgfVxuICAgICAgICBzdHJBcnJheVswXSA9IGhvdXI7XG4gICAgICAgIHZhbHVlID0gc3RyQXJyYXkuam9pbignOicpICsgcGVyaW9kO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoQ29kZXMuVFdFTlRZX0ZPVVJfSE9VUl9GT1JNQVQgPT09IHRoaXMuZm9ybWF0KSB7XG4gICAgICAvLyBkbyBub3RoaW5nXG4gICAgfVxuICAgIHJldHVybiB2YWx1ZTtcbiAgfVxuXG4gIHByb3RlY3RlZCBlbWl0T25WYWx1ZUNoYW5nZSh0eXBlLCBuZXdWYWx1ZSwgb2xkVmFsdWUpOiB2b2lkIHtcbiAgICB0aGlzLm9uQ2hhbmdlLmVtaXQobmV3VmFsdWUpO1xuICAgIHN1cGVyLmVtaXRPblZhbHVlQ2hhbmdlKHR5cGUsIG5ld1ZhbHVlLCBvbGRWYWx1ZSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgZ2V0VmFsdWVBc1N0cmluZyh2YWw6IGFueSk6IHN0cmluZyB7XG4gICAgbGV0IHZhbHVlO1xuICAgIGlmICh0eXBlb2YgdmFsID09PSAnbnVtYmVyJykge1xuICAgICAgdmFsdWUgPSBtb21lbnQodmFsKS5mb3JtYXQodGhpcy5mb3JtYXRTdHJpbmcpO1xuICAgIH0gZWxzZSB7XG4gICAgICB2YWx1ZSA9IHRoaXMuY29udmVydFRvRm9ybWF0U3RyaW5nKHZhbCk7XG4gICAgfVxuICAgIHJldHVybiB2YWx1ZTtcbiAgfVxuXG4gIHByb3RlY3RlZCBjb252ZXJ0VG9Gb3JtYXRTdHJpbmcodmFsdWUpOiBzdHJpbmcge1xuICAgIGlmICh2YWx1ZSA9PT0gJzAwOjAwJyB8fCAhVXRpbC5pc0RlZmluZWQodmFsdWUpKSB7XG4gICAgICByZXR1cm4gdmFsdWU7XG4gICAgfVxuICAgIGNvbnN0IGZvcm1hdFN0ciA9IHRoaXMuZm9ybWF0ID09PSBDb2Rlcy5UV0VOVFlfRk9VUl9IT1VSX0ZPUk1BVCA/ICdISDptbScgOiAnaGg6bW0gYSc7XG4gICAgbGV0IHJlc3VsdDtcbiAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJykge1xuICAgICAgcmVzdWx0ID0gbW9tZW50KHZhbHVlKS5mb3JtYXQoZm9ybWF0U3RyKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmVzdWx0ID0gdmFsdWUgPyBtb21lbnQodmFsdWUsICdoOm1tIEEnKS5mb3JtYXQoZm9ybWF0U3RyKSA6IHZhbHVlO1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG59XG4iLCI8ZGl2IGZ4TGF5b3V0PVwicm93XCIgZnhMYXlvdXRBbGlnbj1cInNwYWNlLWJldHdlZW4gY2VudGVyXCIgW2Zvcm1Hcm91cF09XCJnZXRGb3JtR3JvdXAoKVwiIFttYXRUb29sdGlwXT1cInRvb2x0aXBcIiBbbWF0VG9vbHRpcENsYXNzXT1cInRvb2x0aXBDbGFzc1wiXG4gIFttYXRUb29sdGlwUG9zaXRpb25dPVwidG9vbHRpcFBvc2l0aW9uXCIgW21hdFRvb2x0aXBTaG93RGVsYXldPVwidG9vbHRpcFNob3dEZWxheVwiIFttYXRUb29sdGlwSGlkZURlbGF5XT1cInRvb2x0aXBIaWRlRGVsYXlcIj5cbiAgPG1hdC1mb3JtLWZpZWxkIFthcHBlYXJhbmNlXT1cImFwcGVhcmFuY2VcIiBbZmxvYXRMYWJlbF09XCJmbG9hdExhYmVsXCIgZnhGaWxsIFtoaWRlUmVxdWlyZWRNYXJrZXJdPVwiaGlkZVJlcXVpcmVkTWFya2VyXCIgY2xhc3M9XCJpY29uLWZpZWxkXCJcbiAgICBbc3Vic2NyaXB0U2l6aW5nXT1cInN1YnNjcmlwdFNpemluZ1wiPlxuICAgIDxtYXQtbGFiZWwgKm5nSWY9XCJsYWJlbFZpc2libGVcIj57eyBvbGFiZWwgfCBvVHJhbnNsYXRlIH19PC9tYXQtbGFiZWw+XG4gICAgPGlucHV0IG1hdElucHV0IFtuZ3hUaW1lcGlja2VyXT1cInBpY2tlclwiIFtpZF09XCJnZXRBdHRyaWJ1dGUoKVwiIFtwbGFjZWhvbGRlcl09XCJwbGFjZUhvbGRlclwiIFtmb3JtQ29udHJvbE5hbWVdPVwiZ2V0QXR0cmlidXRlKClcIlxuICAgICAgW3JlYWRvbmx5XT1cImlzUmVhZE9ubHkgfHwgIXRleHRJbnB1dEVuYWJsZWRcIiAoZm9jdXMpPVwiaW5uZXJPbkZvY3VzKCRldmVudClcIiAoYmx1cik9XCJpbm5lck9uQmx1cigkZXZlbnQpXCIgW3JlcXVpcmVkXT1cImlzUmVxdWlyZWRcIlxuICAgICAgKGNoYW5nZSk9XCJvbkNoYW5nZUV2ZW50KCRldmVudClcIiBbbWluXT1cIm1pblwiIFttYXhdPVwibWF4XCIgKGtleWRvd24pPVwib25LZXlEb3duKCRldmVudClcIiBbZm9ybWF0XT1cImZvcm1hdFwiIFtkaXNhYmxlQ2xpY2tdPVwidHJ1ZVwiPlxuXG4gICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgKm5nSWY9XCJzaG93Q2xlYXJCdXR0b25cIiBtYXRTdWZmaXggbWF0LWljb24tYnV0dG9uIChjbGljayk9XCJvbkNsaWNrQ2xlYXJWYWx1ZSgkZXZlbnQpXCI+XG4gICAgICA8bWF0LWljb24gc3ZnSWNvbj1cIm9udGltaXplOmNsb3NlXCI+PC9tYXQtaWNvbj5cbiAgICA8L2J1dHRvbj5cbiAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBtYXRTdWZmaXggbWF0LWljb24tYnV0dG9uIFtkaXNhYmxlZF09XCJpc1JlYWRPbmx5IHx8ICFlbmFibGVkXCIgKGNsaWNrKT1cIm9wZW4oJGV2ZW50KVwiPlxuICAgICAgPG1hdC1pY29uIG5neE1hdGVyaWFsVGltZXBpY2tlclRvZ2dsZUljb24gc3ZnSWNvbj1cIm9udGltaXplOmNsb2NrXCI+PC9tYXQtaWNvbj5cbiAgICA8L2J1dHRvbj5cblxuICAgIDxtYXQtZXJyb3IgKm9NYXRFcnJvcj1cImhhc0Vycm9yKCdyZXF1aXJlZCcpXCI+XG4gICAgICB7eyAnRk9STV9WQUxJREFUSU9OLlJFUVVJUkVEJyB8IG9UcmFuc2xhdGUgfX1cbiAgICA8L21hdC1lcnJvcj5cbiAgICA8bWF0LWVycm9yICpvTWF0RXJyb3I9XCJoYXNFcnJvcignaW52YWxpZEZvcm1hdEhvdXInKVwiPlxuICAgICAge3sgJ0ZPUk1fVkFMSURBVElPTi5IT1VSX0ZPUk1BVCcgfCBvVHJhbnNsYXRlIH19IHt7IGZvcm1hdFN0cmluZyB9fVxuICAgIDwvbWF0LWVycm9yPlxuICAgIDxtYXQtZXJyb3IgKm5nRm9yPVwibGV0IG9FcnJvciBvZiBnZXRBY3RpdmVPRXJyb3JzKClcIj5cbiAgICAgIHt7IG9FcnJvci50ZXh0IHwgb1RyYW5zbGF0ZSB9fVxuICAgIDwvbWF0LWVycm9yPlxuICA8L21hdC1mb3JtLWZpZWxkPlxuPC9kaXY+XG5cbjxuZ3gtbWF0ZXJpYWwtdGltZXBpY2tlciAjcGlja2VyICh0aW1lU2V0KT1cIm9uVGltZXBpY2tlckNoYW5nZSgkZXZlbnQpXCIgW2NvbmZpcm1CdG5UbXBsXT1cImNvbmZpcm1CdG5cIiBbY2FuY2VsQnRuVG1wbF09XCJjYW5jZWxCdG5cIj5cbjwvbmd4LW1hdGVyaWFsLXRpbWVwaWNrZXI+XG5cbjxuZy10ZW1wbGF0ZSAjY29uZmlybUJ0bj5cbiAgPGJ1dHRvbiBtYXQtc3Ryb2tlZC1idXR0b24gdHlwZT1cImJ1dHRvblwiPjxzcGFuPnt7J09LJyB8IG9UcmFuc2xhdGV9fTwvc3Bhbj48L2J1dHRvbj5cbjwvbmctdGVtcGxhdGU+XG5cbjxuZy10ZW1wbGF0ZSAjY2FuY2VsQnRuPlxuICA8YnV0dG9uIG1hdC1zdHJva2VkLWJ1dHRvbiB0eXBlPVwiYnV0dG9uXCI+PHNwYW4+e3snQ0FOQ0VMJyB8IG9UcmFuc2xhdGV9fTwvc3Bhbj48L2J1dHRvbj5cbjwvbmctdGVtcGxhdGU+XG4iXX0=