UNPKG

kwikui

Version:

KwikID's UI Component Library in Angular

302 lines 44.9 kB
import { Component, EventEmitter, forwardRef, Input, Output } from "@angular/core"; import { FormControl, FormGroup, NG_VALUE_ACCESSOR } from "@angular/forms"; import { TUI_DATE_FORMAT, TUI_DATE_SEPARATOR, TuiDay } from "@taiga-ui/cdk"; import { checkObjectKeyExists, isNotEmptyValue, isNull } from "kwikid-toolkit"; import { Subscription } from "rxjs"; import { distinctUntilChanged } from "rxjs/operators"; import { throwErrorMessage } from "../../../../helpers/kwikui.common.helpers"; import { DEFAULT_VALUES, VALIDATE_KEY_VALUES } from "./input-date.constants"; import { isValidKeyValue } from "./input-date.validation"; import * as i0 from "@angular/core"; import * as i1 from "@taiga-ui/kit"; import * as i2 from "@taiga-ui/core"; import * as i3 from "@angular/forms"; import * as i4 from "@angular/common"; export class KwikUIInputDateComponent { constructor() { this.disabled = DEFAULT_VALUES.disabled; this.focus = DEFAULT_VALUES.focus; this.formControl = new FormControl({}); this.formControlName = DEFAULT_VALUES.formControlName; this.hintContent = DEFAULT_VALUES.hintContent; this.icon = DEFAULT_VALUES.icon; this.id = DEFAULT_VALUES.id; this.invalid = DEFAULT_VALUES.invalid; this.isShowLabelOutside = DEFAULT_VALUES.isShowLabelOutside; this.label = DEFAULT_VALUES.label; this.max = DEFAULT_VALUES.max; this.maxCalculatedFromToday = DEFAULT_VALUES.maxCalculatedFromToday; this.min = DEFAULT_VALUES.min; this.minCalculatedFromToday = { year: 0, month: 0, day: 0 }; this.placeholder = DEFAULT_VALUES.placeholder; this.postfix = DEFAULT_VALUES.postfix; this.prefix = DEFAULT_VALUES.prefix; this.properties = { readOnly: false }; this.size = DEFAULT_VALUES.size; this.validators = { required: true }; this.getKeyValue = new EventEmitter(); this.formGroup = new FormGroup({}); this.subscriptions = new Subscription(); } ngOnInit() { this.formGroup.addControl(this.formControlName, this.formControl); this.focus = this.focus === undefined ? false : this.focus; this.invalid = this.invalid === undefined ? false : this.invalid && this.focus; this.validators = Object.assign({}, this.validators); this.properties = Object.assign({}, this.properties); this.setDisabled(); this.min = isNotEmptyValue(this.min) ? new TuiDay(this.min.year, this.min.month, this.min.day) : this.calculateMinDateFromToday(this.minCalculatedFromToday); this.max = isNotEmptyValue(this.max) ? new TuiDay(this.max.year, this.max.month, this.max.day) : this.calculateMaxDateFromToday(this.maxCalculatedFromToday); this.subscriptions.add(this.formGroup.controls[this.formControlName].valueChanges .pipe(distinctUntilChanged()) // makes sure the value has actually changed. .subscribe((value) => this.handleInputValueChange(value))); } ngOnChanges(changes) { const verifyChange = (key) => { return changes.hasOwnProperty(key) && !changes[key].firstChange; }; for (const change of Object.entries(changes)) { const key = change[0]; const value = change[1].currentValue; this.validateInputProperty(key, value); } if (verifyChange("minCalculatedFromToday")) { this.min = isNotEmptyValue(this.min) ? new TuiDay(this.min.year, this.min.month, this.min.day) : this.calculateMinDateFromToday(this.minCalculatedFromToday); } if (verifyChange("maxCalculatedFromToday")) { this.max = isNotEmptyValue(this.max) ? new TuiDay(this.max.year, this.max.month, this.max.day) : this.calculateMaxDateFromToday(this.maxCalculatedFromToday); } if (verifyChange("formControl")) { this.formControl = changes.formControl.currentValue; } if (verifyChange("invalid")) { this.invalid = Boolean(changes.invalid.currentValue); this.setError(); } if (verifyChange("isShowLabelOutside")) { this.isShowLabelOutside = Boolean(changes.isShowLabelOutside.currentValue); } if (verifyChange("focus")) { this.focus = Boolean(changes.focus.currentValue); } if (verifyChange("disabled")) { this.disabled = Boolean(changes.disabled.currentValue); this.setDisabled(); } } ngOnDestroy() { this.subscriptions.unsubscribe(); // ensure when component is destroyed the subscription is also and not left open. } validateInputProperty(key, value) { if (VALIDATE_KEY_VALUES[key] && !isValidKeyValue(key, value)) { this[key] = DEFAULT_VALUES[key]; throwErrorMessage("kwikui-input-date", this.id, key, value, DEFAULT_VALUES[key]); } } /** * @description Handles setting up of error and focus on the input field is it is invalid */ setDisabled() { if (this.formGroup.controls[this.formControlName] !== undefined) { if (this.disabled === true) { this.formGroup.controls[this.formControlName].disable({ emitEvent: false }); } else { this.formGroup.controls[this.formControlName].enable({ emitEvent: false }); } } } /** * @description Handles setting up of error and focus on the input field is it is invalid */ setReset() { this.formGroup.controls[this.formControlName].reset(); } /** * @description Handles setting up of error and focus on the input field is it is invalid */ setError() { if (this.formGroup.controls[this.formControlName] !== undefined && this.formGroup.controls[this.formControlName].invalid) { this.invalid = true; this.focus = true; } else { this.invalid = false; this.focus = false; } } /** * @description Handles firing of 2 events on (keyup) event * * @param value */ handleInputValueChange(value) { if (isNull(value)) { this.emitEvent(this.getKeyValue, { key: this.formControlName, value: null }); } else { const dateValue = new Date(value.year, value.month, value.day); const minDateValue = new Date(this.min.year, this.min.month, this.min.day); const maxDateValue = new Date(this.max.year, this.max.month, this.max.day); if (minDateValue <= dateValue && maxDateValue >= dateValue) { this.invalid = false; this.focus = false; if (value === this.formControl.value) { this.emitEvent(this.getKeyValue, { key: this.formControlName, value: this.formControl.value }); } } else { this.setReset(); this.setError(); } } } handleFocusedChange(e) { if (!this.invalid) { this.focus = e; } } /** * Calculates the TuiDay object for the min date based on the minCalculatedFromToday input * @returns TuiDay */ calculateMinDateFromToday(minCalculatedFromToday) { const currentDate = new Date(); let minYear = 0; let minMonth = 0; let minDay = 1; if (checkObjectKeyExists(minCalculatedFromToday, "year")) { minYear = Number(currentDate.getFullYear() - minCalculatedFromToday.year); } if (checkObjectKeyExists(minCalculatedFromToday, "month")) { minMonth = Number(currentDate.getMonth() - minCalculatedFromToday.month); } if (checkObjectKeyExists(minCalculatedFromToday, "day")) { minDay = Number(currentDate.getDate() - minCalculatedFromToday.day); } const targetDate = new Date(minYear, minMonth, minDay); const minDate = new TuiDay(targetDate.getFullYear(), targetDate.getMonth(), targetDate.getDate()); return minDate; } /** * Calculates the TuiDay object for the max date based on the maxCalculatedFromToday input * @returns TuiDay */ calculateMaxDateFromToday(maxCalculatedFromToday) { const currentDate = new Date(); let maxYear = 9999; let maxMonth = 11; let maxDay = 31; if (checkObjectKeyExists(maxCalculatedFromToday, "year")) { maxYear = Number(currentDate.getFullYear() + maxCalculatedFromToday.year); } if (checkObjectKeyExists(maxCalculatedFromToday, "month")) { maxMonth = Number(currentDate.getMonth() + maxCalculatedFromToday.month); } if (checkObjectKeyExists(maxCalculatedFromToday, "day")) { maxDay = Number(currentDate.getDate() + maxCalculatedFromToday.day); } const targetDate = new Date(maxYear, maxMonth, maxDay); const maxDate = new TuiDay(targetDate.getFullYear(), targetDate.getMonth(), targetDate.getDate()); return maxDate; } emitEvent(event, data) { event.emit(data); } /** Method Implementations for Abstract Control */ writeValue(value) { } registerOnChange(fn) { } registerOnTouched(fn) { } setDisabledState(isDisabled) { } } /** @nocollapse */ KwikUIInputDateComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.17", ngImport: i0, type: KwikUIInputDateComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); /** @nocollapse */ KwikUIInputDateComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.17", type: KwikUIInputDateComponent, selector: "kwikui-input-date", inputs: { disabled: "disabled", focus: "focus", formControl: "formControl", formControlName: "formControlName", hintContent: "hintContent", icon: "icon", id: "id", invalid: "invalid", isShowLabelOutside: "isShowLabelOutside", label: "label", max: "max", maxCalculatedFromToday: "maxCalculatedFromToday", min: "min", minCalculatedFromToday: "minCalculatedFromToday", placeholder: "placeholder", postfix: "postfix", prefix: "prefix", properties: "properties", size: "size", validators: "validators" }, outputs: { getKeyValue: "getKeyValue" }, providers: [ { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef((() => KwikUIInputDateComponent)), multi: true }, { provide: TUI_DATE_FORMAT, useValue: `DMY` }, { provide: TUI_DATE_SEPARATOR, useValue: `-` } ], usesOnChanges: true, ngImport: i0, template: "<div [formGroup]=\"formGroup\">\n <p\n *ngIf=\"isShowLabelOutside\"\n class=\"tui-space_bottom-2\"\n >\n <b>\n {{ label }}\n <span *ngIf=\"validators.required\">*</span>\n </b>\n </p>\n <tui-input-date\n tuiUnfinishedValidator=\"Finish filling the field\"\n [formControlName]=\"formControlName\"\n [max]=\"max\"\n [min]=\"min\"\n [nativeId]=\"id\"\n [pseudoFocus]=\"focus ?? null\"\n [pseudoInvalid]=\"invalid === undefined ? null : invalid\"\n [readOnly]=\"properties?.readOnly ?? false\"\n [tuiHintContent]=\"hintContent\"\n [tuiTextfieldCleaner]=\"true\"\n [tuiTextfieldLabelOutside]=\"isShowLabelOutside\"\n [tuiTextfieldIconLeft]=\"icon\"\n [tuiTextfieldPostfix]=\"postfix\"\n [tuiTextfieldPrefix]=\"prefix\"\n [tuiTextfieldSize]=\"size\"\n (focusedChange)=\"handleFocusedChange($event)\"\n >\n <div *ngIf=\"!isShowLabelOutside\">\n {{ label }}\n <span\n class=\"tui-required\"\n *ngIf=\"validators.required\"\n ></span>\n </div>\n <div *ngIf=\"isShowLabelOutside\">\n {{ placeholder }}\n </div>\n <input\n tuiTextfield\n [attr.placeholder]=\"placeholder ?? ''\"\n [attr.required]=\"validators.required\"\n />\n </tui-input-date>\n</div>\n", styles: [""], components: [{ type: i1.TuiInputDateComponent, selector: "tui-input-date:not([multiple])", inputs: ["min", "max", "disabledItemHandler", "markerHandler", "items", "defaultActiveYearMonth"] }, { type: i2.TuiTextfieldComponent, selector: "input[tuiTextfield], textarea[tuiTextfield]" }], directives: [{ type: i3.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { type: i3.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i1.TuiInputDateDirective, selector: "tui-input-date:not([multiple])" }, { type: i1.TuiUnfinishedValidatorDirective, selector: "[tuiUnfinishedValidator]" }, { type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i3.FormControlName, selector: "[formControlName]", inputs: ["disabled", "formControlName", "ngModel"], outputs: ["ngModelChange"] }, { type: i2.TuiHintOptionsDirective, selector: "[tuiHintContent]", inputs: ["tuiHintContent", "tuiHintDirection", "tuiHintAppearance", "tuiHintShowDelay", "tuiHintHideDelay"] }, { type: i2.TuiTextfieldCleanerDirective, selector: "[tuiTextfieldCleaner]", inputs: ["tuiTextfieldCleaner"] }, { type: i2.TuiTextfieldLabelOutsideDirective, selector: "[tuiTextfieldLabelOutside]", inputs: ["tuiTextfieldLabelOutside"] }, { type: i2.TuiTextfieldIconLeftDirective, selector: "[tuiTextfieldIconLeft]", inputs: ["tuiTextfieldIconLeft"] }, { type: i2.TuiTextfieldPostfixDirective, selector: "[tuiTextfieldPostfix]", inputs: ["tuiTextfieldPostfix"] }, { type: i2.TuiTextfieldPrefixDirective, selector: "[tuiTextfieldPrefix]", inputs: ["tuiTextfieldPrefix"] }, { type: i2.TuiTextfieldSizeDirective, selector: "[tuiTextfieldSize]", inputs: ["tuiTextfieldSize"] }] }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.17", ngImport: i0, type: KwikUIInputDateComponent, decorators: [{ type: Component, args: [{ selector: "kwikui-input-date", templateUrl: "./input-date.component.html", styleUrls: ["./input-date.component.scss"], providers: [ { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef((() => KwikUIInputDateComponent)), multi: true }, { provide: TUI_DATE_FORMAT, useValue: `DMY` }, { provide: TUI_DATE_SEPARATOR, useValue: `-` } ] }] }], ctorParameters: function () { return []; }, propDecorators: { disabled: [{ type: Input }], focus: [{ type: Input }], formControl: [{ type: Input }], formControlName: [{ type: Input }], hintContent: [{ type: Input }], icon: [{ type: Input }], id: [{ type: Input }], invalid: [{ type: Input }], isShowLabelOutside: [{ type: Input }], label: [{ type: Input }], max: [{ type: Input }], maxCalculatedFromToday: [{ type: Input }], min: [{ type: Input }], minCalculatedFromToday: [{ type: Input }], placeholder: [{ type: Input }], postfix: [{ type: Input }], prefix: [{ type: Input }], properties: [{ type: Input }], size: [{ type: Input }], validators: [{ type: Input }], getKeyValue: [{ type: Output }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5wdXQtZGF0ZS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9rd2lrdWkvc3JjL2xpYi9jb21wb25lbnRzL2NvcmUvaW5wdXRzL2lucHV0LWRhdGUvaW5wdXQtZGF0ZS5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9rd2lrdWkvc3JjL2xpYi9jb21wb25lbnRzL2NvcmUvaW5wdXRzL2lucHV0LWRhdGUvaW5wdXQtZGF0ZS5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsU0FBUyxFQUNULFlBQVksRUFDWixVQUFVLEVBQ1YsS0FBSyxFQUdMLE1BQU0sRUFFUCxNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBRUwsV0FBVyxFQUNYLFNBQVMsRUFDVCxpQkFBaUIsRUFDbEIsTUFBTSxnQkFBZ0IsQ0FBQztBQUN4QixPQUFPLEVBQUUsZUFBZSxFQUFFLGtCQUFrQixFQUFFLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUM1RSxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsZUFBZSxFQUFFLE1BQU0sRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQy9FLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDcEMsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDdEQsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sMkNBQTJDLENBQUM7QUFDOUUsT0FBTyxFQUFFLGNBQWMsRUFBRSxtQkFBbUIsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBRTdFLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQzs7Ozs7O0FBZ0IxRCxNQUFNLE9BQU8sd0JBQXdCO0lBd0RuQztRQXREUyxhQUFRLEdBQVksY0FBYyxDQUFDLFFBQVEsQ0FBQztRQUU1QyxVQUFL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RUFBRSxDQUFDLDZCQUE2QixDQUFDO29CQUMxQyxTQUFTLEVBQUU7d0JBQ1Q7NEJBQ0UsT0FBTyxFQUFFLGlCQUFpQjs0QkFDMUIsV0FBVyxFQUFFLFVBQVUsRUFBQyxHQUFHLEVBQUUseUJBQXlCLEVBQUM7NEJBQ3ZELEtBQUssRUFBRSxJQUFJO3lCQUNaO3dCQUNELEVBQUUsT0FBTyxFQUFFLGVBQWUsRUFBRSxRQUFRLEVBQUUsS0FBSyxFQUFFO3dCQUM3QyxFQUFFLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxRQUFRLEVBQUUsR0FBRyxFQUFFO3FCQUMvQztpQkFDRjswRUFHVSxRQUFRO3NCQUFoQixLQUFLO2dCQUVHLEtBQUs7c0JBQWIsS0FBSztnQkFFRyxXQUFXO3NCQUFuQixLQUFLO2dCQUVHLGVBQWU7c0JBQXZCLEtBQUs7Z0JBRUcsV0FBVztzQkFBbkIsS0FBSztnQkFFRyxJQUFJO3NCQUFaLEtBQUs7Z0JBRUcsRUFBRTtzQkFBVixLQUFLO2dCQUVHLE9BQU87c0JBQWYsS0FBSztnQkFFRyxrQkFBa0I7c0JBQTFCLEtBQUs7Z0JBRUcsS0FBSztzQkFBYixLQUFLO2dCQUVHLEdBQUc7c0JBQVgsS0FBSztnQkFFRyxzQkFBc0I7c0JBQTlCLEtBQUs7Z0JBTUcsR0FBRztzQkFBWCxLQUFLO2dCQUVHLHNCQUFzQjtzQkFBOUIsS0FBSztnQkFNRyxXQUFXO3NCQUFuQixLQUFLO2dCQUVHLE9BQU87c0JBQWYsS0FBSztnQkFFRyxNQUFNO3NCQUFkLEtBQUs7Z0JBRUcsVUFBVTtzQkFBbEIsS0FBSztnQkFFRyxJQUFJO3NCQUFaLEtBQUs7Z0JBRUcsVUFBVTtzQkFBbEIsS0FBSztnQkFFSSxXQUFXO3NCQUFwQixNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQ29tcG9uZW50LFxuICBFdmVudEVtaXR0ZXIsXG4gIGZvcndhcmRSZWYsXG4gIElucHV0LFxuICBPbkNoYW5nZXMsXG4gIE9uSW5pdCxcbiAgT3V0cHV0LFxuICBTaW1wbGVDaGFuZ2VzXG59IGZyb20gXCJAYW5ndWxhci9jb3JlXCI7XG5pbXBvcnQge1xuICBDb250cm9sVmFsdWVBY2Nlc3NvcixcbiAgRm9ybUNvbnRyb2wsXG4gIEZvcm1Hcm91cCxcbiAgTkdfVkFMVUVfQUNDRVNTT1Jcbn0gZnJvbSBcIkBhbmd1bGFyL2Zvcm1zXCI7XG5pbXBvcnQgeyBUVUlfREFURV9GT1JNQVQsIFRVSV9EQVRFX1NFUEFSQVRPUiwgVHVpRGF5IH0gZnJvbSBcIkB0YWlnYS11aS9jZGtcIjtcbmltcG9ydCB7IGNoZWNrT2JqZWN0S2V5RXhpc3RzLCBpc05vdEVtcHR5VmFsdWUsIGlzTnVsbCB9IGZyb20gXCJrd2lraWQtdG9vbGtpdFwiO1xuaW1wb3J0IHsgU3Vic2NyaXB0aW9uIH0gZnJvbSBcInJ4anNcIjtcbmltcG9ydCB7IGRpc3RpbmN0VW50aWxDaGFuZ2VkIH0gZnJvbSBcInJ4anMvb3BlcmF0b3JzXCI7XG5pbXBvcnQgeyB0aHJvd0Vycm9yTWVzc2FnZSB9IGZyb20gXCIuLi8uLi8uLi8uLi9oZWxwZXJzL2t3aWt1aS5jb21tb24uaGVscGVyc1wiO1xuaW1wb3J0IHsgREVGQVVMVF9WQUxVRVMsIFZBTElEQVRFX0tFWV9WQUxVRVMgfSBmcm9tIFwiLi9pbnB1dC1kYXRlLmNvbnN0YW50c1wiO1xuaW1wb3J0IHsgVEt3aWtVSUlucHV0RGF0ZVNpemUgfSBmcm9tIFwiLi9pbnB1dC1kYXRlLmRlZmluaXRpb25zXCI7XG5pbXBvcnQgeyBpc1ZhbGlkS2V5VmFsdWUgfSBmcm9tIFwiLi9pbnB1dC1kYXRlLnZhbGlkYXRpb25cIjtcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiBcImt3aWt1aS1pbnB1dC1kYXRlXCIsXG4gIHRlbXBsYXRlVXJsOiBcIi4vaW5wdXQtZGF0ZS5jb21wb25lbnQuaHRtbFwiLFxuICBzdHlsZVVybHM6IFtcIi4vaW5wdXQtZGF0ZS5jb21wb25lbnQuc2Nzc1wiXSxcbiAgcHJvdmlkZXJzOiBbXG4gICAge1xuICAgICAgcHJvdmlkZTogTkdfVkFMVUVfQUNDRVNTT1IsXG4gICAgICB1c2VFeGlzdGluZzogZm9yd2FyZFJlZigoKSA9PiBLd2lrVUlJbnB1dERhdGVDb21wb25lbnQpLFxuICAgICAgbXVsdGk6IHRydWVcbiAgICB9LFxuICAgIHsgcHJvdmlkZTogVFVJX0RBVEVfRk9STUFULCB1c2VWYWx1ZTogYERNWWAgfSxcbiAgICB7IHByb3ZpZGU6IFRVSV9EQVRFX1NFUEFSQVRPUiwgdXNlVmFsdWU6IGAtYCB9XG4gIF1cbn0pXG5leHBvcnQgY2xhc3MgS3dpa1VJSW5wdXREYXRlQ29tcG9uZW50XG4gIGltcGxlbWVudHMgT25Jbml0LCBPbkNoYW5nZXMsIENvbnRyb2xWYWx1ZUFjY2Vzc29yIHtcbiAgQElucHV0KCkgZGlzYWJsZWQ6IGJvb2xlYW4gPSBERUZBVUxUX1ZBTFVFUy5kaXNhYmxlZDtcblxuICBASW5wdXQoKSBmb2N1czogYm9vbGVhbiA9IERFRkFVTFRfVkFMVUVTLmZvY3VzO1xuXG4gIEBJbnB1dCgpIGZvcm1Db250cm9sOiBGb3JtQ29udHJvbCA9IG5ldyBGb3JtQ29udHJvbCh7fSk7XG5cbiAgQElucHV0KCkgZm9ybUNvbnRyb2xOYW1lOiBzdHJpbmcgPSBERUZBVUxUX1ZBTFVFUy5mb3JtQ29udHJvbE5hbWU7XG5cbiAgQElucHV0KCkgaGludENvbnRlbnQ6IHN0cmluZyA9IERFRkFVTFRfVkFMVUVTLmhpbnRDb250ZW50O1xuXG4gIEBJbnB1dCgpIGljb246IHN0cmluZyA9IERFRkFVTFRfVkFMVUVTLmljb247XG5cbiAgQElucHV0KCkgaWQ6IHN0cmluZyA9IERFRkFVTFRfVkFMVUVTLmlkO1xuXG4gIEBJbnB1dCgpIGludmFsaWQ6IGJvb2xlYW4gPSBERUZBVUxUX1ZBTFVFUy5pbnZhbGlkO1xuXG4gIEBJbnB1dCgpIGlzU2hvd0xhYmVsT3V0c2lkZTogYm9vbGVhbiA9IERFRkFVTFRfVkFMVUVTLmlzU2hvd0xhYmVsT3V0c2lkZTtcblxuICBASW5wdXQoKSBsYWJlbDogc3RyaW5nID0gREVGQVVMVF9WQUxVRVMubGFiZWw7XG5cbiAgQElucHV0KCkgbWF4OiBhbnkgPSBERUZBVUxUX1ZBTFVFUy5tYXg7XG5cbiAgQElucHV0KCkgbWF4Q2FsY3VsYXRlZEZyb21Ub2RheToge1xuICAgIHllYXI/OiBudW1iZXI7XG4gICAgbW9udGg/OiBudW1iZXI7XG4gICAgZGF5PzogbnVtYmVyO1xuICB9ID0gREVGQVVMVF9WQUxVRVMubWF4Q2FsY3VsYXRlZEZyb21Ub2RheTtcblxuICBASW5wdXQoKSBtaW46IGFueSA9IERFRkFVTFRfVkFMVUVTLm1pbjtcblxuICBASW5wdXQoKSBtaW5DYWxjdWxhdGVkRnJvbVRvZGF5OiB7XG4gICAgeWVhcj86IG51bWJlcjtcbiAgICBtb250aD86IG51bWJlcjtcbiAgICBkYXk/OiBudW1iZXI7XG4gIH0gPSB7IHllYXI6IDAsIG1vbnRoOiAwLCBkYXk6IDAgfTtcblxuICBASW5wdXQoKSBwbGFjZWhvbGRlcjogc3RyaW5nID0gREVGQVVMVF9WQUxVRVMucGxhY2Vob2xkZXI7XG5cbiAgQElucHV0KCkgcG9zdGZpeDogc3RyaW5nID0gREVGQVVMVF9WQUxVRVMucG9zdGZpeDtcblxuICBASW5wdXQoKSBwcmVmaXg6IHN0cmluZyA9IERFRkFVTFRfVkFMVUVTLnByZWZpeDtcblxuICBASW5wdXQoKSBwcm9wZXJ0aWVzID0geyByZWFkT25seTogZmFsc2UgfTtcblxuICBASW5wdXQoKSBzaXplOiBUS3dpa1VJSW5wdXREYXRlU2l6ZSA9IERFRkFVTFRfVkFMVUVTLnNpemU7XG5cbiAgQElucHV0KCkgdmFsaWRhdG9ycyA9IHsgcmVxdWlyZWQ6IHRydWUgfTtcblxuICBAT3V0cHV0KCkgZ2V0S2V5VmFsdWU6IEV2ZW50RW1pdHRlcjxhbnk+ID0gbmV3IEV2ZW50RW1pdHRlcjxhbnk+KCk7XG5cbiAgZm9ybUdyb3VwOiBGb3JtR3JvdXAgPSBuZXcgRm9ybUdyb3VwKHt9KTtcblxuICBzdWJzY3JpcHRpb25zID0gbmV3IFN1YnNjcmlwdGlvbigpO1xuXG4gIGNvbnN0cnVjdG9yKCkge31cblxuICBuZ09uSW5pdCgpOiB2b2lkIHtcbiAgICB0aGlzLmZvcm1Hcm91cC5hZGRDb250cm9sKHRoaXMuZm9ybUNvbnRyb2xOYW1lLCB0aGlzLmZvcm1Db250cm9sKTtcbiAgICB0aGlzLmZvY3VzID0gdGhpcy5mb2N1cyA9PT0gdW5kZWZpbmVkID8gZmFsc2UgOiB0aGlzLmZvY3VzO1xuICAgIHRoaXMuaW52YWxpZCA9XG4gICAgICB0aGlzLmludmFsaWQgPT09IHVuZGVmaW5lZCA/IGZhbHNlIDogdGhpcy5pbnZhbGlkICYmIHRoaXMuZm9jdXM7XG4gICAgdGhpcy52YWxpZGF0b3JzID0geyAuLi50aGlzLnZhbGlkYXRvcnMgfTtcbiAgICB0aGlzLnByb3BlcnRpZXMgPSB7IC4uLnRoaXMucHJvcGVydGllcyB9O1xuICAgIHRoaXMuc2V0RGlzYWJsZWQoKTtcblxuICAgIHRoaXMubWluID0gaXNOb3RFbXB0eVZhbHVlKHRoaXMubWluKVxuICAgICAgPyBuZXcgVHVpRGF5KHRoaXMubWluLnllYXIsIHRoaXMubWluLm1vbnRoLCB0aGlzLm1pbi5kYXkpXG4gICAgICA6IHRoaXMuY2FsY3VsYXRlTWluRGF0ZUZyb21Ub2RheSh0aGlzLm1pbkNhbGN1bGF0ZWRGcm9tVG9kYXkpO1xuICAgIHRoaXMubWF4ID0gaXNOb3RFbXB0eVZhbHVlKHRoaXMubWF4KVxuICAgICAgPyBuZXcgVHVpRGF5KHRoaXMubWF4LnllYXIsIHRoaXMubWF4Lm1vbnRoLCB0aGlzLm1heC5kYXkpXG4gICAgICA6IHRoaXMuY2FsY3VsYXRlTWF4RGF0ZUZyb21Ub2RheSh0aGlzLm1heENhbGN1bGF0ZWRGcm9tVG9kYXkpO1xuXG4gICAgdGhpcy5zdWJzY3JpcHRpb25zLmFkZChcbiAgICAgIHRoaXMuZm9ybUdyb3VwLmNvbnRyb2xzW3RoaXMuZm9ybUNvbnRyb2xOYW1lXS52YWx1ZUNoYW5nZXNcbiAgICAgICAgLnBpcGUoZGlzdGluY3RVbnRpbENoYW5nZWQoKSkgLy8gbWFrZXMgc3VyZSB0aGUgdmFsdWUgaGFzIGFjdHVhbGx5IGNoYW5nZWQuXG4gICAgICAgIC5zdWJzY3JpYmUoKHZhbHVlKSA9PiB0aGlzLmhhbmRsZUlucHV0VmFsdWVDaGFuZ2UodmFsdWUpKVxuICAgICk7XG4gIH1cblxuICBuZ09uQ2hhbmdlcyhjaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKSB7XG4gICAgY29uc3QgdmVyaWZ5Q2hhbmdlID0gKGtleTogc3RyaW5nKSA9PiB7XG4gICAgICByZXR1cm4gY2hhbmdlcy5oYXNPd25Qcm9wZXJ0eShrZXkpICYmICFjaGFuZ2VzW2tleV0uZmlyc3RDaGFuZ2U7XG4gICAgfTtcblxuICAgIGZvciAoY29uc3QgY2hhbmdlIG9mIE9iamVjdC5lbnRyaWVzKGNoYW5nZXMpKSB7XG4gICAgICBjb25zdCBrZXk6IHN0cmluZyA9IGNoYW5nZVswXTtcbiAgICAgIGNvbnN0IHZhbHVlOiBhbnkgPSBjaGFuZ2VbMV0uY3VycmVudFZhbHVlO1xuICAgICAgdGhpcy52YWxpZGF0ZUlucHV0UHJvcGVydHkoa2V5LCB2YWx1ZSk7XG4gICAgfVxuXG4gICAgaWYgKHZlcmlmeUNoYW5nZShcIm1pbkNhbGN1bGF0ZWRGcm9tVG9kYXlcIikpIHtcbiAgICAgIHRoaXMubWluID0gaXNOb3RFbXB0eVZhbHVlKHRoaXMubWluKVxuICAgICAgICA/IG5ldyBUdWlEYXkodGhpcy5taW4ueWVhciwgdGhpcy5taW4ubW9udGgsIHRoaXMubWluLmRheSlcbiAgICAgICAgOiB0aGlzLmNhbGN1bGF0ZU1pbkRhdGVGcm9tVG9kYXkodGhpcy5taW5DYWxjdWxhdGVkRnJvbVRvZGF5KTtcbiAgICB9XG4gICAgaWYgKHZlcmlmeUNoYW5nZShcIm1heENhbGN1bGF0ZWRGcm9tVG9kYXlcIikpIHtcbiAgICAgIHRoaXMubWF4ID0gaXNOb3RFbXB0eVZhbHVlKHRoaXMubWF4KVxuICAgICAgICA/IG5ldyBUdWlEYXkodGhpcy5tYXgueWVhciwgdGhpcy5tYXgubW9udGgsIHRoaXMubWF4LmRheSlcbiAgICAgICAgOiB0aGlzLmNhbGN1bGF0ZU1heERhdGVGcm9tVG9kYXkodGhpcy5tYXhDYWxjdWxhdGVkRnJvbVRvZGF5KTtcbiAgICB9XG5cbiAgICBpZiAodmVyaWZ5Q2hhbmdlKFwiZm9ybUNvbnRyb2xcIikpIHtcbiAgICAgIHRoaXMuZm9ybUNvbnRyb2wgPSBjaGFuZ2VzLmZvcm1Db250cm9sLmN1cnJlbnRWYWx1ZTtcbiAgICB9XG4gICAgaWYgKHZlcmlmeUNoYW5nZShcImludmFsaWRcIikpIHtcbiAgICAgIHRoaXMuaW52YWxpZCA9IEJvb2xlYW4oY2hhbmdlcy5pbnZhbGlkLmN1cnJlbnRWYWx1ZSk7XG4gICAgICB0aGlzLnNldEVycm9yKCk7XG4gICAgfVxuICAgIGlmICh2ZXJpZnlDaGFuZ2UoXCJpc1Nob3dMYWJlbE91dHNpZGVcIikpIHtcbiAgICAgIHRoaXMuaXNTaG93TGFiZWxPdXRzaWRlID0gQm9vbGVhbihjaGFuZ2VzLmlzU2hvd0xhYmVsT3V0c2lkZS5jdXJyZW50VmFsdWUpO1xuICAgIH1cbiAgICBpZiAodmVyaWZ5Q2hhbmdlKFwiZm9jdXNcIikpIHtcbiAgICAgIHRoaXMuZm9jdXMgPSBCb29sZWFuKGNoYW5nZXMuZm9jdXMuY3VycmVudFZhbHVlKTtcbiAgICB9XG4gICAgaWYgKHZlcmlmeUNoYW5nZShcImRpc2FibGVkXCIpKSB7XG4gICAgICB0aGlzLmRpc2FibGVkID0gQm9vbGVhbihjaGFuZ2VzLmRpc2FibGVkLmN1cnJlbnRWYWx1ZSk7XG4gICAgICB0aGlzLnNldERpc2FibGVkKCk7XG4gICAgfVxuICB9XG5cbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgdGhpcy5zdWJzY3JpcHRpb25zLnVuc3Vic2NyaWJlKCk7XG4gICAgLy8gZW5zdXJlIHdoZW4gY29tcG9uZW50IGlzIGRlc3Ryb3llZCB0aGUgc3Vic2NyaXB0aW9uIGlzIGFsc28gYW5kIG5vdCBsZWZ0IG9wZW4uXG4gIH1cblxuICBwcml2YXRlIHZhbGlkYXRlSW5wdXRQcm9wZXJ0eShrZXk6IHN0cmluZywgdmFsdWU6IGFueSk6IHZvaWQge1xuICAgIGlmIChWQUxJREFURV9LRVlfVkFMVUVTW2tleV0gJiYgIWlzVmFsaWRLZXlWYWx1ZShrZXksIHZhbHVlKSkge1xuICAgICAgdGhpc1trZXldID0gREVGQVVMVF9WQUxVRVNba2V5XTtcbiAgICAgIHRocm93RXJyb3JNZXNzYWdlKFxuICAgICAgICBcImt3aWt1aS1pbnB1dC1kYXRlXCIsXG4gICAgICAgIHRoaXMuaWQsXG4gICAgICAgIGtleSxcbiAgICAgICAgdmFsdWUsXG4gICAgICAgIERFRkFVTFRfVkFMVUVTW2tleV1cbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBIYW5kbGVzIHNldHRpbmcgdXAgb2YgZXJyb3IgYW5kIGZvY3VzIG9uIHRoZSBpbnB1dCBmaWVsZCBpcyBpdCBpcyBpbnZhbGlkXG4gICAqL1xuICBzZXREaXNhYmxlZCgpIHtcbiAgICBpZiAodGhpcy5mb3JtR3JvdXAuY29udHJvbHNbdGhpcy5mb3JtQ29udHJvbE5hbWVdICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGlmICh0aGlzLmRpc2FibGVkID09PSB0cnVlKSB7XG4gICAgICAgIHRoaXMuZm9ybUdyb3VwLmNvbnRyb2xzW3RoaXMuZm9ybUNvbnRyb2xOYW1lXS5kaXNhYmxlKHtcbiAgICAgICAgICBlbWl0RXZlbnQ6IGZhbHNlXG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5mb3JtR3JvdXAuY29udHJvbHNbdGhpcy5mb3JtQ29udHJvbE5hbWVdLmVuYWJsZSh7XG4gICAgICAgICAgZW1pdEV2ZW50OiBmYWxzZVxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIEhhbmRsZXMgc2V0dGluZyB1cCBvZiBlcnJvciBhbmQgZm9jdXMgb24gdGhlIGlucHV0IGZpZWxkIGlzIGl0IGlzIGludmFsaWRcbiAgICovXG4gIHNldFJlc2V0KCkge1xuICAgIHRoaXMuZm9ybUdyb3VwLmNvbnRyb2xzW3RoaXMuZm9ybUNvbnRyb2xOYW1lXS5yZXNldCgpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBIYW5kbGVzIHNldHRpbmcgdXAgb2YgZXJyb3IgYW5kIGZvY3VzIG9uIHRoZSBpbnB1dCBmaWVsZCBpcyBpdCBpcyBpbnZhbGlkXG4gICAqL1xuICBzZXRFcnJvcigpIHtcbiAgICBpZiAoXG4gICAgICB0aGlzLmZvcm1Hcm91cC5jb250cm9sc1t0aGlzLmZvcm1Db250cm9sTmFtZV0gIT09IHVuZGVmaW5lZCAmJlxuICAgICAgdGhpcy5mb3JtR3JvdXAuY29udHJvbHNbdGhpcy5mb3JtQ29udHJvbE5hbWVdLmludmFsaWRcbiAgICApIHtcbiAgICAgIHRoaXMuaW52YWxpZCA9IHRydWU7XG4gICAgICB0aGlzLmZvY3VzID0gdHJ1ZTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5pbnZhbGlkID0gZmFsc2U7XG4gICAgICB0aGlzLmZvY3VzID0gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBIYW5kbGVzIGZpcmluZyBvZiAyIGV2ZW50cyBvbiAoa2V5dXApIGV2ZW50XG4gICAqXG4gICAqIEBwYXJhbSB2YWx1ZVxuICAgKi9cbiAgaGFuZGxlSW5wdXRWYWx1ZUNoYW5nZSh2YWx1ZTogYW55KSB7XG4gICAgaWYgKGlzTnVsbCh2YWx1ZSkpIHtcbiAgICAgIHRoaXMuZW1pdEV2ZW50KHRoaXMuZ2V0S2V5VmFsdWUsIHtcbiAgICAgICAga2V5OiB0aGlzLmZvcm1Db250cm9sTmFtZSxcbiAgICAgICAgdmFsdWU6IG51bGxcbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBkYXRlVmFsdWUgPSBuZXcgRGF0ZSh2YWx1ZS55ZWFyLCB2YWx1ZS5tb250aCwgdmFsdWUuZGF5KTtcblxuICAgICAgY29uc3QgbWluRGF0ZVZhbHVlID0gbmV3IERhdGUoXG4gICAgICAgIHRoaXMubWluLnllYXIsXG4gICAgICAgIHRoaXMubWluLm1vbnRoLFxuICAgICAgICB0aGlzLm1pbi5kYXlcbiAgICAgICk7XG4gICAgICBjb25zdCBtYXhEYXRlVmFsdWUgPSBuZXcgRGF0ZShcbiAgICAgICAgdGhpcy5tYXgueWVhcixcbiAgICAgICAgdGhpcy5tYXgubW9udGgsXG4gICAgICAgIHRoaXMubWF4LmRheVxuICAgICAgKTtcblxuICAgICAgaWYgKG1pbkRhdGVWYWx1ZSA8PSBkYXRlVmFsdWUgJiYgbWF4RGF0ZVZhbHVlID49IGRhdGVWYWx1ZSkge1xuICAgICAgICB0aGlzLmludmFsaWQgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5mb2N1cyA9IGZhbHNlO1xuICAgICAgICBpZiAodmFsdWUgPT09IHRoaXMuZm9ybUNvbnRyb2wudmFsdWUpIHtcbiAgICAgICAgICB0aGlzLmVtaXRFdmVudCh0aGlzLmdldEtleVZhbHVlLCB7XG4gICAgICAgICAgICBrZXk6IHRoaXMuZm9ybUNvbnRyb2xOYW1lLFxuICAgICAgICAgICAgdmFsdWU6IHRoaXMuZm9ybUNvbnRyb2wudmFsdWVcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5zZXRSZXNldCgpO1xuICAgICAgICB0aGlzLnNldEVycm9yKCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgaGFuZGxlRm9jdXNlZENoYW5nZShlOiBhbnkpIHtcbiAgICBpZiAoIXRoaXMuaW52YWxpZCkge1xuICAgICAgdGhpcy5mb2N1cyA9IGU7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIENhbGN1bGF0ZXMgdGhlIFR1aURheSBvYmplY3QgZm9yIHRoZSBtaW4gZGF0ZSBiYXNlZCBvbiB0aGUgbWluQ2FsY3VsYXRlZEZyb21Ub2RheSBpbnB1dFxuICAgKiBAcmV0dXJucyBUdWlEYXlcbiAgICovXG4gIGNhbGN1bGF0ZU1pbkRhdGVGcm9tVG9kYXkobWluQ2FsY3VsYXRlZEZyb21Ub2RheToge1xuICAgIHllYXI/OiBudW1iZXI7XG4gICAgbW9udGg/OiBudW1iZXI7XG4gICAgZGF5PzogbnVtYmVyO1xuICB9KTogVHVpRGF5IHtcbiAgICBjb25zdCBjdXJyZW50RGF0ZSA9IG5ldyBEYXRlKCk7XG5cbiAgICBsZXQgbWluWWVhciA9IDA7XG4gICAgbGV0IG1pbk1vbnRoID0gMDtcbiAgICBsZXQgbWluRGF5ID0gMTtcblxuICAgIGlmIChjaGVja09iamVjdEtleUV4aXN0cyhtaW5DYWxjdWxhdGVkRnJvbVRvZGF5LCBcInllYXJcIikpIHtcbiAgICAgIG1pblllYXIgPSBOdW1iZXIoY3VycmVudERhdGUuZ2V0RnVsbFllYXIoKSAtIG1pbkNhbGN1bGF0ZWRGcm9tVG9kYXkueWVhcik7XG4gICAgfVxuICAgIGlmIChjaGVja09iamVjdEtleUV4aXN0cyhtaW5DYWxjdWxhdGVkRnJvbVRvZGF5LCBcIm1vbnRoXCIpKSB7XG4gICAgICBtaW5Nb250aCA9IE51bWJlcihjdXJyZW50RGF0ZS5nZXRNb250aCgpIC0gbWluQ2FsY3VsYXRlZEZyb21Ub2RheS5tb250aCk7XG4gICAgfVxuICAgIGlmIChjaGVja09iamVjdEtleUV4aXN0cyhtaW5DYWxjdWxhdGVkRnJvbVRvZGF5LCBcImRheVwiKSkge1xuICAgICAgbWluRGF5ID0gTnVtYmVyKGN1cnJlbnREYXRlLmdldERhdGUoKSAtIG1pbkNhbGN1bGF0ZWRGcm9tVG9kYXkuZGF5KTtcbiAgICB9XG5cbiAgICBjb25zdCB0YXJnZXREYXRlID0gbmV3IERhdGUobWluWWVhciwgbWluTW9udGgsIG1pbkRheSk7XG5cbiAgICBjb25zdCBtaW5EYXRlID0gbmV3IFR1aURheShcbiAgICAgIHRhcmdldERhdGUuZ2V0RnVsbFllYXIoKSxcbiAgICAgIHRhcmdldERhdGUuZ2V0TW9udGgoKSxcbiAgICAgIHRhcmdldERhdGUuZ2V0RGF0ZSgpXG4gICAgKTtcblxuICAgIHJldHVybiBtaW5EYXRlO1xuICB9XG5cbiAgLyoqXG4gICAqIENhbGN1bGF0ZXMgdGhlIFR1aURheSBvYmplY3QgZm9yIHRoZSBtYXggZGF0ZSBiYXNlZCBvbiB0aGUgbWF4Q2FsY3VsYXRlZEZyb21Ub2RheSBpbnB1dFxuICAgKiBAcmV0dXJucyBUdWlEYXlcbiAgICovXG4gIGNhbGN1bGF0ZU1heERhdGVGcm9tVG9kYXkobWF4Q2FsY3VsYXRlZEZyb21Ub2RheToge1xuICAgIHllYXI/OiBudW1iZXI7XG4gICAgbW9udGg/OiBudW1iZXI7XG4gICAgZGF5PzogbnVtYmVyO1xuICB9KTogVHVpRGF5IHtcbiAgICBjb25zdCBjdXJyZW50RGF0ZSA9IG5ldyBEYXRlKCk7XG5cbiAgICBsZXQgbWF4WWVhciA9IDk5OTk7XG4gICAgbGV0IG1heE1vbnRoID0gMTE7XG4gICAgbGV0IG1heERheSA9IDMxO1xuXG4gICAgaWYgKGNoZWNrT2JqZWN0S2V5RXhpc3RzKG1heENhbGN1bGF0ZWRGcm9tVG9kYXksIFwieWVhclwiKSkge1xuICAgICAgbWF4WWVhciA9IE51bWJlcihjdXJyZW50RGF0ZS5nZXRGdWxsWWVhcigpICsgbWF4Q2FsY3VsYXRlZEZyb21Ub2RheS55ZWFyKTtcbiAgICB9XG4gICAgaWYgKGNoZWNrT2JqZWN0S2V5RXhpc3RzKG1heENhbGN1bGF0ZWRGcm9tVG9kYXksIFwibW9udGhcIikpIHtcbiAgICAgIG1heE1vbnRoID0gTnVtYmVyKGN1cnJlbnREYXRlLmdldE1vbnRoKCkgKyBtYXhDYWxjdWxhdGVkRnJvbVRvZGF5Lm1vbnRoKTtcbiAgICB9XG4gICAgaWYgKGNoZWNrT2JqZWN0S2V5RXhpc3RzKG1heENhbGN1bGF0ZWRGcm9tVG9kYXksIFwiZGF5XCIpKSB7XG4gICAgICBtYXhEYXkgPSBOdW1iZXIoY3VycmVudERhdGUuZ2V0RGF0ZSgpICsgbWF4Q2FsY3VsYXRlZEZyb21Ub2RheS5kYXkpO1xuICAgIH1cbiAgICBjb25zdCB0YXJnZXREYXRlID0gbmV3IERhdGUobWF4WWVhciwgbWF4TW9udGgsIG1heERheSk7XG5cbiAgICBjb25zdCBtYXhEYXRlID0gbmV3IFR1aURheShcbiAgICAgIHRhcmdldERhdGUuZ2V0RnVsbFllYXIoKSxcbiAgICAgIHRhcmdldERhdGUuZ2V0TW9udGgoKSxcbiAgICAgIHRhcmdldERhdGUuZ2V0RGF0ZSgpXG4gICAgKTtcblxuICAgIHJldHVybiBtYXhEYXRlO1xuICB9XG5cbiAgZW1pdEV2ZW50KGV2ZW50OiBhbnksIGRhdGE6IGFueSkge1xuICAgIGV2ZW50LmVtaXQoZGF0YSk7XG4gIH1cblxuICAvKiogTWV0aG9kIEltcGxlbWVudGF0aW9ucyBmb3IgQWJzdHJhY3QgQ29udHJvbCAqL1xuICB3cml0ZVZhbHVlKHZhbHVlOiBhbnkpOiB2b2lkIHt9XG5cbiAgcmVnaXN0ZXJPbkNoYW5nZShmbjogYW55KTogdm9pZCB7fVxuXG4gIHJlZ2lzdGVyT25Ub3VjaGVkKGZuOiBhbnkpOiB2b2lkIHt9XG5cbiAgc2V0RGlzYWJsZWRTdGF0ZT8oaXNEaXNhYmxlZDogYm9vbGVhbik6IHZvaWQge31cbn1cbiIsIjxkaXYgW2Zvcm1Hcm91cF09XCJmb3JtR3JvdXBcIj5cbiAgPHBcbiAgICAqbmdJZj1cImlzU2hvd0xhYmVsT3V0c2lkZVwiXG4gICAgY2xhc3M9XCJ0dWktc3BhY2VfYm90dG9tLTJcIlxuICA+XG4gICAgPGI+XG4gICAgICB7eyBsYWJlbCB9fVxuICAgICAgPHNwYW4gKm5nSWY9XCJ2YWxpZGF0b3JzLnJlcXVpcmVkXCI+Kjwvc3Bhbj5cbiAgICA8L2I+XG4gIDwvcD5cbiAgPHR1aS1pbnB1dC1kYXRlXG4gICAgdHVpVW5maW5pc2hlZFZhbGlkYXRvcj1cIkZpbmlzaCBmaWxsaW5nIHRoZSBmaWVsZFwiXG4gICAgW2Zvcm1Db250cm9sTmFtZV09XCJmb3JtQ29udHJvbE5hbWVcIlxuICAgIFttYXhdPVwibWF4XCJcbiAgICBbbWluXT1cIm1pblwiXG4gICAgW25hdGl2ZUlkXT1cImlkXCJcbiAgICBbcHNldWRvRm9jdXNdPVwiZm9jdXMgPz8gbnVsbFwiXG4gICAgW3BzZXVkb0ludmFsaWRdPVwiaW52YWxpZCA9PT0gdW5kZWZpbmVkID8gbnVsbCA6IGludmFsaWRcIlxuICAgIFtyZWFkT25seV09XCJwcm9wZXJ0aWVzPy5yZWFkT25seSA/PyBmYWxzZVwiXG4gICAgW3R1aUhpbnRDb250ZW50XT1cImhpbnRDb250ZW50XCJcbiAgICBbdHVpVGV4dGZpZWxkQ2xlYW5lcl09XCJ0cnVlXCJcbiAgICBbdHVpVGV4dGZpZWxkTGFiZWxPdXRzaWRlXT1cImlzU2hvd0xhYmVsT3V0c2lkZVwiXG4gICAgW3R1aVRleHRmaWVsZEljb25MZWZ0XT1cImljb25cIlxuICAgIFt0dWlUZXh0ZmllbGRQb3N0Zml4XT1cInBvc3RmaXhcIlxuICAgIFt0dWlUZXh0ZmllbGRQcmVmaXhdPVwicHJlZml4XCJcbiAgICBbdHVpVGV4dGZpZWxkU2l6ZV09XCJzaXplXCJcbiAgICAoZm9jdXNlZENoYW5nZSk9XCJoYW5kbGVGb2N1c2VkQ2hhbmdlKCRldmVudClcIlxuICA+XG4gICAgPGRpdiAqbmdJZj1cIiFpc1Nob3dMYWJlbE91dHNpZGVcIj5cbiAgICAgIHt7IGxhYmVsIH19XG4gICAgICA8c3BhblxuICAgICAgICBjbGFzcz1cInR1aS1yZXF1aXJlZFwiXG4gICAgICAgICpuZ0lmPVwidmFsaWRhdG9ycy5yZXF1aXJlZFwiXG4gICAgICA+PC9zcGFuPlxuICAgIDwvZGl2PlxuICAgIDxkaXYgKm5nSWY9XCJpc1Nob3dMYWJlbE91dHNpZGVcIj5cbiAgICAgIHt7IHBsYWNlaG9sZGVyIH19XG4gICAgPC9kaXY+XG4gICAgPGlucHV0XG4gICAgICB0dWlUZXh0ZmllbGRcbiAgICAgIFthdHRyLnBsYWNlaG9sZGVyXT1cInBsYWNlaG9sZGVyID8/ICcnXCJcbiAgICAgIFthdHRyLnJlcXVpcmVkXT1cInZhbGlkYXRvcnMucmVxdWlyZWRcIlxuICAgIC8+XG4gIDwvdHVpLWlucHV0LWRhdGU+XG48L2Rpdj5cbiJdfQ==