custom-input-field
Version:
This library was generated with [Angular CLI](https://github.com/angular/angular-cli) version 14.0.0.
292 lines • 37.5 kB
JavaScript
import { Component, EventEmitter, Input, Output, ViewChild } from '@angular/core';
import * as i0 from "@angular/core";
import * as i1 from "@angular/common";
import * as i2 from "@angular/forms";
import * as i3 from "@angular/material/icon";
export class CustomInputFieldComponent {
constructor(renderer) {
this.renderer = renderer;
//Inputs
this.placeholder = " ";
this.inputLabel = "";
this.readonly = false;
this.isRequired = false;
this.isSearch = true;
this.itemNotFoundMessage = 'Item not found';
this.defaultValue = null;
this.defaultValueName = '';
this.isDefaultDisabled = true;
this.masterList = [];
this.selectedValueChange = new EventEmitter();
this.onSelectionChange = new EventEmitter();
this.selectedName = "";
this.randomNumber = Math.floor(Math.random() * 90000) + 10000;
this.currentMasterList = [];
this.currentOptionElements = [];
this.isItemNotFound = false;
}
ngOnInit() {
}
ngAfterContentInit() {
this.checkDefaultValue();
if (!this.selectedValue)
return;
if (!this.masterList?.length)
return;
this.selectedName = this.masterList.find(x => x.id == this.selectedValue)?.name;
}
ngOnChanges() {
if (!this.selectedValue)
return;
if (!this.masterList?.length)
return;
this.selectedName = this.masterList.find(x => x.id == this.selectedValue)?.name;
}
onSelectOption(item) {
if (item.disabled)
return;
this.selectedValueChange.emit(null);
const optionsElement = this.SelectOptions.nativeElement;
optionsElement.classList.remove("active");
this.selectedValueChange.emit(item.id);
this.selectedName = item.name;
this.onSelectionChange.emit(item);
}
onSelectDefault(event) {
if (this.isDefaultDisabled)
return;
this.selectedValueChange.emit(null);
const optionsElement = this.SelectOptions.nativeElement;
optionsElement.classList.remove("active");
this.selectedValueChange.emit(this.defaultValue);
this.selectedName = this.defaultValueName;
this.onSelectionChange.emit(event);
}
checkDefaultValue() {
if (this.defaultValue == 0 && this.selectedValue == 0) {
this.selectedName = this.defaultValueName;
console.log(this.selectedName);
}
}
validateValue() {
const { value } = this.SelectInput.nativeElement;
const trimmedValue = value?.toString()?.trim();
if (trimmedValue) {
this.renderer.addClass(this.SelectLabel.nativeElement, '--input--selected');
}
else {
this.renderer.removeClass(this.SelectLabel.nativeElement, '--input--selected');
}
}
onFocus() {
this.iconNameChange();
this.currentMasterList = [];
this.currentOptionElements = this.SelectOptions.nativeElement?.children;
const { value } = this.SelectInput.nativeElement;
const currentValue = value?.toString()?.trim();
if (!this.currentOptionElements?.length)
return;
for (let i = 0; i < this.currentOptionElements.length; i++) {
const optionElement = this.currentOptionElements[i];
const optionText = optionElement.innerText?.trim();
this.currentMasterList.push(optionText);
this.renderer.removeClass(optionElement, 'selected-option');
if (currentValue) {
if (currentValue === optionText)
this.renderer.addClass(optionElement, 'selected-option');
}
this.renderer.removeClass(optionElement, 'hide-option');
this.renderer.addClass(optionElement, 'show-option');
this.renderer.addClass(optionElement, 'select-part');
}
this.renderer.removeClass(this.SelectLabel.nativeElement, '--input--selected');
this.renderer.addClass(this.SelectOptions.nativeElement, 'active');
}
onKeyUp(event) {
const { keyCode } = event;
if (keyCode === 9)
return; //Tab
if (!this.isSearch)
return;
this.selectedValueChange.emit(null);
this.isItemNotFound = false;
const inputValue = event.target.value?.toString()?.trim()?.toLowerCase();
if (!this.currentOptionElements?.length)
return;
//FilterOptions
for (let i = 0; i < this.currentMasterList.length; i++) {
const filteredList = this.currentMasterList.filter(x => x?.toString()?.trim()?.toLowerCase().includes(inputValue));
//Check ItemIsFound
if (inputValue && !filteredList.length) {
const currentElement = this.SelectField.nativeElement.querySelectorAll(".input-item");
for (let i = 0; i < currentElement.length; i++) {
const element = currentElement[i];
const isNotFoundElement = element.getAttribute('item-not-found') === 'true';
if (!isNotFoundElement)
element.className = `input-item ${element?.getAttribute('value')} hide-option`;
}
this.isItemNotFound = true;
return;
}
else {
this.isItemNotFound = false;
}
//If Item Found
for (let i = 0; i < this.currentOptionElements.length; i++) {
const optionElement = this.currentOptionElements[i];
const optionText = optionElement.innerText;
this.renderer.removeClass(optionElement, 'selected-option');
if (!inputValue) {
this.renderer.removeClass(optionElement, 'hide-option');
this.renderer.addClass(optionElement, 'show-option');
continue;
}
if (filteredList.find(x => x?.trim() === optionText?.trim())) {
this.renderer.removeClass(optionElement, 'hide-option');
this.renderer.addClass(optionElement, 'show-option');
}
else {
this.renderer.addClass(optionElement, 'hide-option');
this.renderer.removeClass(optionElement, 'show-option');
}
}
}
}
onBlur() {
this.iconNameChange();
this.renderer.removeClass(this.SelectOptions.nativeElement, 'active');
if ((this.defaultValue || this.defaultValue == 0) && this.selectedValue == null) {
this.selectedValueChange.emit(this.defaultValue);
this.selectedName = this.defaultValueName;
this.renderer.addClass(this.SelectField.nativeElement, '--input--selected');
}
else {
if (!this.selectedValue && this.selectedValue != 0) {
this.selectedName = "";
const currentElement = this.SelectField.nativeElement.querySelector('.--input--selected');
if (currentElement)
this.renderer.removeClass(currentElement, "--input--selected");
}
}
}
placeholderActive(selector) {
if (selector.getAttribute('placeholder')) {
return true;
}
return false;
}
iconNameChange() {
const iconName = this.SelectOptions.nativeElement?.nextElementSibling?.innerText;
this.SelectOptions.nativeElement.nextElementSibling.innerText = iconName === 'expand_more' ? 'expand_less' : 'expand_more';
}
}
CustomInputFieldComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.3", ngImport: i0, type: CustomInputFieldComponent, deps: [{ token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Component });
CustomInputFieldComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.1.3", type: CustomInputFieldComponent, selector: "custom-input-field", inputs: { placeholder: "placeholder", inputLabel: "inputLabel", readonly: "readonly", isRequired: "isRequired", isSearch: "isSearch", itemNotFoundMessage: "itemNotFoundMessage", defaultValue: "defaultValue", defaultValueName: "defaultValueName", isDefaultDisabled: "isDefaultDisabled", masterList: "masterList", selectedValue: "selectedValue" }, outputs: { selectedValueChange: "selectedValueChange", onSelectionChange: "onSelectionChange" }, viewQueries: [{ propertyName: "SelectField", first: true, predicate: ["SelectField"], descendants: true }, { propertyName: "SelectInput", first: true, predicate: ["SelectInput"], descendants: true }, { propertyName: "SelectLabel", first: true, predicate: ["SelectLabel"], descendants: true }, { propertyName: "SelectOptions", first: true, predicate: ["SelectOptions"], descendants: true }], usesOnChanges: true, ngImport: i0, template: `
<div class="--input-select-group {{readonly? 'disabled' : ''}}" #SelectField>
<ng-container *ngIf="!readonly">
<input type="text" id="{{randomNumber}}" [readonly]="!isSearch" [placeholder]="placeholder"
(keyup)="onKeyUp($event)" #SelectInput (focus)="onFocus()" (blur)="onBlur()" [(ngModel)]="selectedName"
class="select-part select-input">
</ng-container>
<ng-container *ngIf="readonly">
<input type="text" onclick="return false" [placeholder]="placeholder" id="{{randomNumber}}" onkeydown="return false"
onkeypress="return false" onkeyup="return false" readonly [value]="selectedName" class="select-part select-input">
</ng-container>
<label for="{{randomNumber}}" #SelectLabel class="select-part">{{inputLabel}}<span *ngIf="isRequired"
class="--required-field"></span></label>
<div class="input-select select-part" #SelectOptions>
<ng-container *ngIf="defaultValue || defaultValueName">
<div class="input-item {{isDefaultDisabled? 'disabled' : ''}}" (mousedown)="onSelectDefault($event)"
attr.value="{{defaultValue}}">
{{defaultValueName}}
</div>
</ng-container>
<div *ngFor="let item of masterList;let i=index" class="input-item {{item.disabled ? 'disabled' : ''}}"
(mousedown)="onSelectOption(item)" attr.value="{{item.id}}">
{{item.name}}</div>
<ng-container *ngIf="isItemNotFound">
<div class="input-item show-option item-not-found" item-not-found="true">
{{itemNotFoundMessage}}
</div>
</ng-container>
</div>
<mat-icon class="mat-icon">expand_more</mat-icon>
</div>
`, isInline: true, dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { 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.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }] });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.3", ngImport: i0, type: CustomInputFieldComponent, decorators: [{
type: Component,
args: [{
selector: 'custom-input-field',
template: `
<div class="--input-select-group {{readonly? 'disabled' : ''}}" #SelectField>
<ng-container *ngIf="!readonly">
<input type="text" id="{{randomNumber}}" [readonly]="!isSearch" [placeholder]="placeholder"
(keyup)="onKeyUp($event)" #SelectInput (focus)="onFocus()" (blur)="onBlur()" [(ngModel)]="selectedName"
class="select-part select-input">
</ng-container>
<ng-container *ngIf="readonly">
<input type="text" onclick="return false" [placeholder]="placeholder" id="{{randomNumber}}" onkeydown="return false"
onkeypress="return false" onkeyup="return false" readonly [value]="selectedName" class="select-part select-input">
</ng-container>
<label for="{{randomNumber}}" #SelectLabel class="select-part">{{inputLabel}}<span *ngIf="isRequired"
class="--required-field"></span></label>
<div class="input-select select-part" #SelectOptions>
<ng-container *ngIf="defaultValue || defaultValueName">
<div class="input-item {{isDefaultDisabled? 'disabled' : ''}}" (mousedown)="onSelectDefault($event)"
attr.value="{{defaultValue}}">
{{defaultValueName}}
</div>
</ng-container>
<div *ngFor="let item of masterList;let i=index" class="input-item {{item.disabled ? 'disabled' : ''}}"
(mousedown)="onSelectOption(item)" attr.value="{{item.id}}">
{{item.name}}</div>
<ng-container *ngIf="isItemNotFound">
<div class="input-item show-option item-not-found" item-not-found="true">
{{itemNotFoundMessage}}
</div>
</ng-container>
</div>
<mat-icon class="mat-icon">expand_more</mat-icon>
</div>
`
}]
}], ctorParameters: function () { return [{ type: i0.Renderer2 }]; }, propDecorators: { SelectField: [{
type: ViewChild,
args: ["SelectField"]
}], SelectInput: [{
type: ViewChild,
args: ["SelectInput"]
}], SelectLabel: [{
type: ViewChild,
args: ["SelectLabel"]
}], SelectOptions: [{
type: ViewChild,
args: ["SelectOptions"]
}], placeholder: [{
type: Input
}], inputLabel: [{
type: Input
}], readonly: [{
type: Input
}], isRequired: [{
type: Input
}], isSearch: [{
type: Input
}], itemNotFoundMessage: [{
type: Input
}], defaultValue: [{
type: Input
}], defaultValueName: [{
type: Input
}], isDefaultDisabled: [{
type: Input
}], masterList: [{
type: Input
}], selectedValue: [{
type: Input
}], selectedValueChange: [{
type: Output
}], onSelectionChange: [{
type: Output
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3VzdG9tLWlucHV0LWZpZWxkLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL2N1c3RvbS1pbnB1dC1maWVsZC9zcmMvbGliL2N1c3RvbS1pbnB1dC1maWVsZC5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFvQixTQUFTLEVBQWMsWUFBWSxFQUFFLEtBQUssRUFBcUIsTUFBTSxFQUFhLFNBQVMsRUFBRSxNQUFNLGVBQWUsQ0FBQzs7Ozs7QUFxQzlJLE1BQU0sT0FBTyx5QkFBeUI7SUFHcEMsWUFBb0IsUUFBbUI7UUFBbkIsYUFBUSxHQUFSLFFBQVEsQ0FBVztRQXdCdkMsUUFBUTtRQUNDLGdCQUFXLEdBQVcsR0FBRyxDQUFDO1FBQzFCLGVBQVUsR0FBVyxFQUFFLENBQUM7UUFDeEIsYUFBUSxHQUFZLEtBQUssQ0FBQztRQUMxQixlQUFVLEdBQVksS0FBSyxDQUFDO1FBQzVCLGFBQVEsR0FBWSxJQUFJLENBQUM7UUFDekIsd0JBQW1CLEdBQVcsZ0JBQWdCLENBQUM7UUFDL0MsaUJBQVksR0FBUSxJQUFJLENBQUM7UUFDekIscUJBQWdCLEdBQVcsRUFBRSxDQUFDO1FBQzlCLHNCQUFpQixHQUFZLElBQUksQ0FBQztRQUVsQyxlQUFVLEdBQVUsRUFBRSxDQUFDO1FBRXRCLHdCQUFtQixHQUFHLElBQUksWUFBWSxFQUFPLENBQUM7UUFDOUMsc0JBQWlCLEdBQUcsSUFBSSxZQUFZLEVBQU8sQ0FBQztRQUN0RCxpQkFBWSxHQUFXLEVBQUUsQ0FBQztRQUMxQixpQkFBWSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxHQUFHLEtBQUssQ0FBQyxHQUFHLEtBQUssQ0FBQztRQUN6RCxzQkFBaUIsR0FBYSxFQUFFLENBQUM7UUFDakMsMEJBQXFCLEdBQVUsRUFBRSxDQUFDO1FBQ2xDLG1CQUFjLEdBQVksS0FBSyxDQUFDO0lBM0NXLENBQUM7SUFFNUMsUUFBUTtJQUVSLENBQUM7SUFFRCxrQkFBa0I7UUFDaEIsSUFBSSxDQUFDLGlCQUFpQixFQUFFLENBQUM7UUFDekIsSUFBSSxDQUFDLElBQUksQ0FBQyxhQUFhO1lBQUUsT0FBTztRQUNoQyxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsRUFBRSxNQUFNO1lBQUUsT0FBTztRQUNyQyxJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsSUFBSSxJQUFJLENBQUMsYUFBYSxDQUFDLEVBQUUsSUFBSSxDQUFDO0lBQ2xGLENBQUM7SUFFRCxXQUFXO1FBQ1QsSUFBSSxDQUFDLElBQUksQ0FBQyxhQUFhO1lBQUUsT0FBTztRQUNoQyxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsRUFBRSxNQUFNO1lBQUUsT0FBTztRQUNyQyxJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsSUFBSSxJQUFJLENBQUMsYUFBYSxDQUFDLEVBQUUsSUFBSSxDQUFDO0lBQ2xGLENBQUM7SUE2QkQsY0FBYyxDQUFDLElBQVM7UUFDdEIsSUFBSSxJQUFJLENBQUMsUUFBUTtZQUFFLE9BQU87UUFDMUIsSUFBSSxDQUFDLG1CQUFtQixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNwQyxNQUFNLGNBQWMsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLGFBQTRCLENBQUM7UUFDdkUsY0FBYyxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDMUMsSUFBSSxDQUFDLG1CQUFtQixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDdkMsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDO1FBQzlCLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDcEMsQ0FBQztJQUVELGVBQWUsQ0FBQyxLQUFZO1FBQzFCLElBQUksSUFBSSxDQUFDLGlCQUFpQjtZQUFFLE9BQU87UUFDbkMsSUFBSSxDQUFDLG1CQUFtQixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNwQyxNQUFNLGNBQWMsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLGFBQTRCLENBQUM7UUFDdkUsY0FBYyxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDMUMsSUFBSSxDQUFDLG1CQUFtQixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUM7UUFDakQsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUMsZ0JBQWdCLENBQUM7UUFDMUMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUNyQyxDQUFDO0lBRUQsaUJBQWlCO1FBQ2YsSUFBSSxJQUFJLENBQUMsWUFBWSxJQUFJLENBQUMsSUFBSSxJQUFJLENBQUMsYUFBYSxJQUFJLENBQUMsRUFBRTtZQUNyRCxJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQztZQUMxQyxPQUFPLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQztTQUNoQztJQUNILENBQUM7SUFFRCxhQUFhO1FBQ1gsTUFBTSxFQUFFLEtBQUssRUFBRSxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsYUFBYSxDQUFDO1FBQ2pELE1BQU0sWUFBWSxHQUFHLEtBQUssRUFBRSxRQUFRLEVBQUUsRUFBRSxJQUFJLEVBQUUsQ0FBQztRQUMvQyxJQUFJLFlBQVksRUFBRTtZQUNoQixJQUFJLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLGFBQWEsRUFBRSxtQkFBbUIsQ0FBQyxDQUFDO1NBQzdFO2FBQU07WUFDTCxJQUFJLENBQUMsUUFBUSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLGFBQWEsRUFBRSxtQkFBbUIsQ0FBQyxDQUFDO1NBQ2hGO0lBQ0gsQ0FBQztJQUVELE9BQU87UUFDTCxJQUFJLENBQUMsY0FBYyxFQUFFLENBQUM7UUFDdEIsSUFBSSxDQUFDLGlCQUFpQixHQUFHLEVBQUUsQ0FBQztRQUM1QixJQUFJLENBQUMscUJBQXFCLEdBQUksSUFBSSxDQUFDLGFBQWEsQ0FBQyxhQUFxQixFQUFFLFFBQVEsQ0FBQztRQUNqRixNQUFNLEVBQUUsS0FBSyxFQUFFLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxhQUFhLENBQUM7UUFDakQsTUFBTSxZQUFZLEdBQUcsS0FBSyxFQUFFLFFBQVEsRUFBRSxFQUFFLElBQUksRUFBRSxDQUFDO1FBQy9DLElBQUksQ0FBQyxJQUFJLENBQUMscUJBQXFCLEVBQUUsTUFBTTtZQUFFLE9BQU87UUFDaEQsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUU7WUFDMUQsTUFBTSxhQUFhLEdBQUcsSUFBSSxDQUFDLHFCQUFxQixDQUFDLENBQUMsQ0FBZ0IsQ0FBQztZQUNuRSxNQUFNLFVBQVUsR0FBRyxhQUFhLENBQUMsU0FBUyxFQUFFLElBQUksRUFBRSxDQUFDO1lBQ25ELElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUM7WUFDeEMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxXQUFXLENBQUMsYUFBYSxFQUFFLGlCQUFpQixDQUFDLENBQUM7WUFDNUQsSUFBSSxZQUFZLEVBQUU7Z0JBQ2hCLElBQUksWUFBWSxLQUFLLFVBQVU7b0JBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsYUFBYSxFQUFFLGlCQUFpQixDQUFDLENBQUM7YUFDM0Y7WUFDRCxJQUFJLENBQUMsUUFBUSxDQUFDLFdBQVcsQ0FBQyxhQUFhLEVBQUUsYUFBYSxDQUFDLENBQUM7WUFDeEQsSUFBSSxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsYUFBYSxFQUFFLGFBQWEsQ0FBQyxDQUFDO1lBQ3JELElBQUksQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLGFBQWEsRUFBRSxhQUFhLENBQUMsQ0FBQztTQUN0RDtRQUNELElBQUksQ0FBQyxRQUFRLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsYUFBYSxFQUFFLG1CQUFtQixDQUFDLENBQUM7UUFDL0UsSUFBSSxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxhQUFhLEVBQUUsUUFBUSxDQUFDLENBQUM7SUFDckUsQ0FBQztJQUVELE9BQU8sQ0FBQyxLQUFVO1FBQ2hCLE1BQU0sRUFBRSxPQUFPLEVBQUUsR0FBRyxLQUFLLENBQUM7UUFDMUIsSUFBSSxPQUFPLEtBQUssQ0FBQztZQUFFLE9BQU8sQ0FBQyxLQUFLO1FBQ2hDLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUTtZQUFFLE9BQU87UUFDM0IsSUFBSSxDQUFDLG1CQUFtQixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNwQyxJQUFJLENBQUMsY0FBYyxHQUFHLEtBQUssQ0FBQztRQUM1QixNQUFNLFVBQVUsR0FBRyxLQUFLLENBQUMsTUFBTSxDQUFDLEtBQUssRUFBRSxRQUFRLEVBQUUsRUFBRSxJQUFJLEVBQUUsRUFBRSxXQUFXLEVBQUUsQ0FBQztRQUN6RSxJQUFJLENBQUMsSUFBSSxDQUFDLHFCQUFxQixFQUFFLE1BQU07WUFBRSxPQUFPO1FBRWhELGVBQWU7UUFDZixLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsSUFBSSxDQUFDLGlCQUFpQixDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRTtZQUN0RCxNQUFNLFlBQVksR0FBRyxJQUFJLENBQUMsaUJBQWlCLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLFFBQVEsRUFBRSxFQUFFLElBQUksRUFBRSxFQUFFLFdBQVcsRUFBRSxDQUFDLFFBQVEsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDO1lBQ25ILG1CQUFtQjtZQUNuQixJQUFJLFVBQVUsSUFBSSxDQUFDLFlBQVksQ0FBQyxNQUFNLEVBQUU7Z0JBQ3RDLE1BQU0sY0FBYyxHQUFpQixJQUFJLENBQUMsV0FBVyxDQUFDLGFBQWMsQ0FBQyxnQkFBZ0IsQ0FBQyxhQUFhLENBQUMsQ0FBQztnQkFDckcsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLGNBQWMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUU7b0JBQzlDLE1BQU0sT0FBTyxHQUFHLGNBQWMsQ0FBQyxDQUFDLENBQVEsQ0FBQztvQkFDekMsTUFBTSxpQkFBaUIsR0FBRyxPQUFPLENBQUMsWUFBWSxDQUFDLGdCQUFnQixDQUFDLEtBQUssTUFBTSxDQUFDO29CQUM1RSxJQUFJLENBQUMsaUJBQWlCO3dCQUFFLE9BQU8sQ0FBQyxTQUFTLEdBQUcsY0FBYyxPQUFPLEVBQUUsWUFBWSxDQUFDLE9BQU8sQ0FBQyxjQUFjLENBQUM7aUJBQ3hHO2dCQUNELElBQUksQ0FBQyxjQUFjLEdBQUcsSUFBSSxDQUFDO2dCQUMzQixPQUFPO2FBQ1I7aUJBQU07Z0JBQ0wsSUFBSSxDQUFDLGNBQWMsR0FBRyxLQUFLLENBQUM7YUFDN0I7WUFDRCxlQUFlO1lBQ2YsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUU7Z0JBQzFELE1BQU0sYUFBYSxHQUFHLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDLENBQWdCLENBQUM7Z0JBQ25FLE1BQU0sVUFBVSxHQUFHLGFBQWEsQ0FBQyxTQUFTLENBQUM7Z0JBQzNDLElBQUksQ0FBQyxRQUFRLENBQUMsV0FBVyxDQUFDLGFBQWEsRUFBRSxpQkFBaUIsQ0FBQyxDQUFDO2dCQUM1RCxJQUFJLENBQUMsVUFBVSxFQUFFO29CQUNmLElBQUksQ0FBQyxRQUFRLENBQUMsV0FBVyxDQUFDLGFBQWEsRUFBRSxhQUFhLENBQUMsQ0FBQztvQkFDeEQsSUFBSSxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsYUFBYSxFQUFFLGFBQWEsQ0FBQyxDQUFDO29CQUNyRCxTQUFTO2lCQUNWO2dCQUNELElBQUksWUFBWSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxJQUFJLEVBQUUsS0FBSyxVQUFVLEVBQUUsSUFBSSxFQUFFLENBQUMsRUFBRTtvQkFDNUQsSUFBSSxDQUFDLFFBQVEsQ0FBQyxXQUFXLENBQUMsYUFBYSxFQUFFLGFBQWEsQ0FBQyxDQUFDO29CQUN4RCxJQUFJLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxhQUFhLEVBQUUsYUFBYSxDQUFDLENBQUM7aUJBQ3REO3FCQUFNO29CQUNMLElBQUksQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLGFBQWEsRUFBRSxhQUFhLENBQUMsQ0FBQztvQkFDckQsSUFBSSxDQUFDLFFBQVEsQ0FBQyxXQUFXLENBQUMsYUFBYSxFQUFFLGFBQWEsQ0FBQyxDQUFDO2lCQUN6RDthQUVGO1NBQ0Y7SUFDSCxDQUFDO0lBRUQsTUFBTTtRQUNKLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQztRQUN0QixJQUFJLENBQUMsUUFBUSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLGFBQWEsRUFBRSxRQUFRLENBQUMsQ0FBQztRQUN0RSxJQUFJLENBQUMsSUFBSSxDQUFDLFlBQVksSUFBSSxJQUFJLENBQUMsWUFBWSxJQUFJLENBQUMsQ0FBQyxJQUFJLElBQUksQ0FBQyxhQUFhLElBQUksSUFBSSxFQUFFO1lBQy9FLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDO1lBQ2pELElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixDQUFDO1lBQzFDLElBQUksQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsYUFBYSxFQUFFLG1CQUFtQixDQUFDLENBQUM7U0FDN0U7YUFBTTtZQUNMLElBQUksQ0FBQyxJQUFJLENBQUMsYUFBYSxJQUFJLElBQUksQ0FBQyxhQUFhLElBQUksQ0FBQyxFQUFFO2dCQUNsRCxJQUFJLENBQUMsWUFBWSxHQUFHLEVBQUUsQ0FBQztnQkFDdkIsTUFBTSxjQUFjLEdBQWlCLElBQUksQ0FBQyxXQUFXLENBQUMsYUFBYyxDQUFDLGFBQWEsQ0FDaEYsb0JBQW9CLENBQ3JCLENBQUM7Z0JBQ0YsSUFBSSxjQUFjO29CQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsV0FBVyxDQUFDLGNBQWMsRUFBRSxtQkFBbUIsQ0FBQyxDQUFBO2FBQ25GO1NBQ0Y7SUFDSCxDQUFDO0lBRUQsaUJBQWlCLENBQUMsUUFBMEI7UUFDMUMsSUFBSSxRQUFRLENBQUMsWUFBWSxDQUFDLGFBQWEsQ0FBQyxFQUFFO1lBQ3hDLE9BQU8sSUFBSSxDQUFDO1NBQ2I7UUFDRCxPQUFPLEtBQUssQ0FBQztJQUNmLENBQUM7SUFFRCxjQUFjO1FBQ1osTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxhQUFhLEVBQUUsa0JBQWtCLEVBQUUsU0FBUyxDQUFDO1FBQ2pGLElBQUksQ0FBQyxhQUFhLENBQUMsYUFBYSxDQUFDLGtCQUFrQixDQUFDLFNBQVMsR0FBRyxRQUFRLEtBQUssYUFBYSxDQUFDLENBQUMsQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFDLGFBQWEsQ0FBQztJQUM3SCxDQUFDOztzSEF4TFUseUJBQXlCOzBHQUF6Qix5QkFBeUIsaTVCQWpDMUI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0ErQlQ7MkZBRVUseUJBQXlCO2tCQW5DckMsU0FBUzttQkFBQztvQkFDVCxRQUFRLEVBQUUsb0JBQW9CO29CQUM5QixRQUFRLEVBQUU7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0ErQlQ7aUJBQ0Y7Z0dBdUIyQixXQUFXO3NCQUFwQyxTQUFTO3VCQUFDLGFBQWE7Z0JBQ0UsV0FBVztzQkFBcEMsU0FBUzt1QkFBQyxhQUFhO2dCQUNFLFdBQVc7c0JBQXBDLFNBQVM7dUJBQUMsYUFBYTtnQkFDSSxhQUFhO3NCQUF4QyxTQUFTO3VCQUFDLGVBQWU7Z0JBR2pCLFdBQVc7c0JBQW5CLEtBQUs7Z0JBQ0csVUFBVTtzQkFBbEIsS0FBSztnQkFDRyxRQUFRO3NCQUFoQixLQUFLO2dCQUNHLFVBQVU7c0JBQWxCLEtBQUs7Z0JBQ0csUUFBUTtzQkFBaEIsS0FBSztnQkFDRyxtQkFBbUI7c0JBQTNCLEtBQUs7Z0JBQ0csWUFBWTtzQkFBcEIsS0FBSztnQkFDRyxnQkFBZ0I7c0JBQXhCLEtBQUs7Z0JBQ0csaUJBQWlCO3NCQUF6QixLQUFLO2dCQUVHLFVBQVU7c0JBQWxCLEtBQUs7Z0JBQ0csYUFBYTtzQkFBckIsS0FBSztnQkFDSSxtQkFBbUI7c0JBQTVCLE1BQU07Z0JBQ0csaUJBQWlCO3NCQUExQixNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQWZ0ZXJDb250ZW50SW5pdCwgQ29tcG9uZW50LCBFbGVtZW50UmVmLCBFdmVudEVtaXR0ZXIsIElucHV0LCBPbkNoYW5nZXMsIE9uSW5pdCwgT3V0cHV0LCBSZW5kZXJlcjIsIFZpZXdDaGlsZCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdjdXN0b20taW5wdXQtZmllbGQnLFxuICB0ZW1wbGF0ZTogYFxuPGRpdiBjbGFzcz1cIi0taW5wdXQtc2VsZWN0LWdyb3VwIHt7cmVhZG9ubHk/ICdkaXNhYmxlZCcgOiAnJ319XCIgI1NlbGVjdEZpZWxkPlxuICA8bmctY29udGFpbmVyICpuZ0lmPVwiIXJlYWRvbmx5XCI+XG4gICAgPGlucHV0IHR5cGU9XCJ0ZXh0XCIgaWQ9XCJ7e3JhbmRvbU51bWJlcn19XCIgW3JlYWRvbmx5XT1cIiFpc1NlYXJjaFwiIFtwbGFjZWhvbGRlcl09XCJwbGFjZWhvbGRlclwiXG4gICAgICAoa2V5dXApPVwib25LZXlVcCgkZXZlbnQpXCIgI1NlbGVjdElucHV0IChmb2N1cyk9XCJvbkZvY3VzKClcIiAoYmx1cik9XCJvbkJsdXIoKVwiIFsobmdNb2RlbCldPVwic2VsZWN0ZWROYW1lXCJcbiAgICAgIGNsYXNzPVwic2VsZWN0LXBhcnQgc2VsZWN0LWlucHV0XCI+XG4gIDwvbmctY29udGFpbmVyPlxuICA8bmctY29udGFpbmVyICpuZ0lmPVwicmVhZG9ubHlcIj5cbiAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBvbmNsaWNrPVwicmV0dXJuIGZhbHNlXCIgW3BsYWNlaG9sZGVyXT1cInBsYWNlaG9sZGVyXCIgaWQ9XCJ7e3JhbmRvbU51bWJlcn19XCIgb25rZXlkb3duPVwicmV0dXJuIGZhbHNlXCJcbiAgICAgIG9ua2V5cHJlc3M9XCJyZXR1cm4gZmFsc2VcIiBvbmtleXVwPVwicmV0dXJuIGZhbHNlXCIgcmVhZG9ubHkgW3ZhbHVlXT1cInNlbGVjdGVkTmFtZVwiIGNsYXNzPVwic2VsZWN0LXBhcnQgc2VsZWN0LWlucHV0XCI+XG4gIDwvbmctY29udGFpbmVyPlxuICA8bGFiZWwgZm9yPVwie3tyYW5kb21OdW1iZXJ9fVwiICNTZWxlY3RMYWJlbCBjbGFzcz1cInNlbGVjdC1wYXJ0XCI+e3tpbnB1dExhYmVsfX08c3BhbiAqbmdJZj1cImlzUmVxdWlyZWRcIlxuICAgICAgY2xhc3M9XCItLXJlcXVpcmVkLWZpZWxkXCI+PC9zcGFuPjwvbGFiZWw+XG4gIDxkaXYgY2xhc3M9XCJpbnB1dC1zZWxlY3Qgc2VsZWN0LXBhcnRcIiAjU2VsZWN0T3B0aW9ucz5cbiAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiZGVmYXVsdFZhbHVlIHx8IGRlZmF1bHRWYWx1ZU5hbWVcIj5cbiAgICAgIDxkaXYgY2xhc3M9XCJpbnB1dC1pdGVtIHt7aXNEZWZhdWx0RGlzYWJsZWQ/ICdkaXNhYmxlZCcgOiAnJ319XCIgKG1vdXNlZG93bik9XCJvblNlbGVjdERlZmF1bHQoJGV2ZW50KVwiXG4gICAgICAgIGF0dHIudmFsdWU9XCJ7e2RlZmF1bHRWYWx1ZX19XCI+XG4gICAgICAgIHt7ZGVmYXVsdFZhbHVlTmFtZX19XG4gICAgICA8L2Rpdj5cbiAgICA8L25nLWNvbnRhaW5lcj5cbiAgICA8ZGl2ICpuZ0Zvcj1cImxldCBpdGVtIG9mIG1hc3Rlckxpc3Q7bGV0IGk9aW5kZXhcIiBjbGFzcz1cImlucHV0LWl0ZW0ge3tpdGVtLmRpc2FibGVkID8gJ2Rpc2FibGVkJyA6ICcnfX1cIlxuICAgICAgKG1vdXNlZG93bik9XCJvblNlbGVjdE9wdGlvbihpdGVtKVwiIGF0dHIudmFsdWU9XCJ7e2l0ZW0uaWR9fVwiPlxuICAgICAge3tpdGVtLm5hbWV9fTwvZGl2PlxuICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJpc0l0ZW1Ob3RGb3VuZFwiPlxuICAgICAgPGRpdiBjbGFzcz1cImlucHV0LWl0ZW0gc2hvdy1vcHRpb24gaXRlbS1ub3QtZm91bmRcIiBpdGVtLW5vdC1mb3VuZD1cInRydWVcIj5cbiAgICAgICAge3tpdGVtTm90Rm91bmRNZXNzYWdlfX1cbiAgICAgIDwvZGl2PlxuICAgIDwvbmctY29udGFpbmVyPlxuICA8L2Rpdj5cbiAgPG1hdC1pY29uIGNsYXNzPVwibWF0LWljb25cIj5leHBhbmRfbW9yZTwvbWF0LWljb24+XG48L2Rpdj5cbiAgYFxufSlcbmV4cG9ydCBjbGFzcyBDdXN0b21JbnB1dEZpZWxkQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBPbkNoYW5nZXMsIEFmdGVyQ29udGVudEluaXQge1xuXG5cbiAgY29uc3RydWN0b3IocHJpdmF0ZSByZW5kZXJlcjogUmVuZGVyZXIyKSB7IH1cblxuICBuZ09uSW5pdCgpOiB2b2lkIHtcblxuICB9XG5cbiAgbmdBZnRlckNvbnRlbnRJbml0KCk6IHZvaWQge1xuICAgIHRoaXMuY2hlY2tEZWZhdWx0VmFsdWUoKTtcbiAgICBpZiAoIXRoaXMuc2VsZWN0ZWRWYWx1ZSkgcmV0dXJuO1xuICAgIGlmICghdGhpcy5tYXN0ZXJMaXN0Py5sZW5ndGgpIHJldHVybjtcbiAgICB0aGlzLnNlbGVjdGVkTmFtZSA9IHRoaXMubWFzdGVyTGlzdC5maW5kKHggPT4geC5pZCA9PSB0aGlzLnNlbGVjdGVkVmFsdWUpPy5uYW1lO1xuICB9XG5cbiAgbmdPbkNoYW5nZXMoKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLnNlbGVjdGVkVmFsdWUpIHJldHVybjtcbiAgICBpZiAoIXRoaXMubWFzdGVyTGlzdD8ubGVuZ3RoKSByZXR1cm47XG4gICAgdGhpcy5zZWxlY3RlZE5hbWUgPSB0aGlzLm1hc3Rlckxpc3QuZmluZCh4ID0+IHguaWQgPT0gdGhpcy5zZWxlY3RlZFZhbHVlKT8ubmFtZTtcbiAgfVxuXG4gIEBWaWV3Q2hpbGQoXCJTZWxlY3RGaWVsZFwiKSBTZWxlY3RGaWVsZCE6IEVsZW1lbnRSZWY7XG4gIEBWaWV3Q2hpbGQoXCJTZWxlY3RJbnB1dFwiKSBTZWxlY3RJbnB1dCE6IEVsZW1lbnRSZWY7XG4gIEBWaWV3Q2hpbGQoXCJTZWxlY3RMYWJlbFwiKSBTZWxlY3RMYWJlbCE6IEVsZW1lbnRSZWY7XG4gIEBWaWV3Q2hpbGQoXCJTZWxlY3RPcHRpb25zXCIpIFNlbGVjdE9wdGlvbnMhOiBFbGVtZW50UmVmO1xuXG4gIC8vSW5wdXRzXG4gIEBJbnB1dCgpIHBsYWNlaG9sZGVyOiBzdHJpbmcgPSBcIiBcIjtcbiAgQElucHV0KCkgaW5wdXRMYWJlbDogc3RyaW5nID0gXCJcIjtcbiAgQElucHV0KCkgcmVhZG9ubHk6IGJvb2xlYW4gPSBmYWxzZTtcbiAgQElucHV0KCkgaXNSZXF1aXJlZDogYm9vbGVhbiA9IGZhbHNlO1xuICBASW5wdXQoKSBpc1NlYXJjaDogYm9vbGVhbiA9IHRydWU7XG4gIEBJbnB1dCgpIGl0ZW1Ob3RGb3VuZE1lc3NhZ2U6IHN0cmluZyA9ICdJdGVtIG5vdCBmb3VuZCc7XG4gIEBJbnB1dCgpIGRlZmF1bHRWYWx1ZTogYW55ID0gbnVsbDtcbiAgQElucHV0KCkgZGVmYXVsdFZhbHVlTmFtZTogc3RyaW5nID0gJyc7XG4gIEBJbnB1dCgpIGlzRGVmYXVsdERpc2FibGVkOiBib29sZWFuID0gdHJ1ZTtcblxuICBASW5wdXQoKSBtYXN0ZXJMaXN0OiBhbnlbXSA9IFtdO1xuICBASW5wdXQoKSBzZWxlY3RlZFZhbHVlOiBhbnk7XG4gIEBPdXRwdXQoKSBzZWxlY3RlZFZhbHVlQ2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxhbnk+KCk7XG4gIEBPdXRwdXQoKSBvblNlbGVjdGlvbkNoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8YW55PigpO1xuICBzZWxlY3RlZE5hbWU6IHN0cmluZyA9IFwiXCI7XG4gIHJhbmRvbU51bWJlciA9IE1hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIDkwMDAwKSArIDEwMDAwO1xuICBjdXJyZW50TWFzdGVyTGlzdDogc3RyaW5nW10gPSBbXTtcbiAgY3VycmVudE9wdGlvbkVsZW1lbnRzOiBhbnlbXSA9IFtdO1xuICBpc0l0ZW1Ob3RGb3VuZDogYm9vbGVhbiA9IGZhbHNlO1xuXG5cbiAgb25TZWxlY3RPcHRpb24oaXRlbTogYW55KSB7XG4gICAgaWYgKGl0ZW0uZGlzYWJsZWQpIHJldHVybjtcbiAgICB0aGlzLnNlbGVjdGVkVmFsdWVDaGFuZ2UuZW1pdChudWxsKTtcbiAgICBjb25zdCBvcHRpb25zRWxlbWVudCA9IHRoaXMuU2VsZWN0T3B0aW9ucy5uYXRpdmVFbGVtZW50IGFzIEhUTUxFbGVtZW50O1xuICAgIG9wdGlvbnNFbGVtZW50LmNsYXNzTGlzdC5yZW1vdmUoXCJhY3RpdmVcIik7XG4gICAgdGhpcy5zZWxlY3RlZFZhbHVlQ2hhbmdlLmVtaXQoaXRlbS5pZCk7XG4gICAgdGhpcy5zZWxlY3RlZE5hbWUgPSBpdGVtLm5hbWU7XG4gICAgdGhpcy5vblNlbGVjdGlvbkNoYW5nZS5lbWl0KGl0ZW0pO1xuICB9XG5cbiAgb25TZWxlY3REZWZhdWx0KGV2ZW50OiBFdmVudCkge1xuICAgIGlmICh0aGlzLmlzRGVmYXVsdERpc2FibGVkKSByZXR1cm47XG4gICAgdGhpcy5zZWxlY3RlZFZhbHVlQ2hhbmdlLmVtaXQobnVsbCk7XG4gICAgY29uc3Qgb3B0aW9uc0VsZW1lbnQgPSB0aGlzLlNlbGVjdE9wdGlvbnMubmF0aXZlRWxlbWVudCBhcyBIVE1MRWxlbWVudDtcbiAgICBvcHRpb25zRWxlbWVudC5jbGFzc0xpc3QucmVtb3ZlKFwiYWN0aXZlXCIpO1xuICAgIHRoaXMuc2VsZWN0ZWRWYWx1ZUNoYW5nZS5lbWl0KHRoaXMuZGVmYXVsdFZhbHVlKTtcbiAgICB0aGlzLnNlbGVjdGVkTmFtZSA9IHRoaXMuZGVmYXVsdFZhbHVlTmFtZTtcbiAgICB0aGlzLm9uU2VsZWN0aW9uQ2hhbmdlLmVtaXQoZXZlbnQpO1xuICB9XG5cbiAgY2hlY2tEZWZhdWx0VmFsdWUoKSB7XG4gICAgaWYgKHRoaXMuZGVmYXVsdFZhbHVlID09IDAgJiYgdGhpcy5zZWxlY3RlZFZhbHVlID09IDApIHtcbiAgICAgIHRoaXMuc2VsZWN0ZWROYW1lID0gdGhpcy5kZWZhdWx0VmFsdWVOYW1lO1xuICAgICAgY29uc29sZS5sb2codGhpcy5zZWxlY3RlZE5hbWUpO1xuICAgIH1cbiAgfVxuXG4gIHZhbGlkYXRlVmFsdWUoKSB7XG4gICAgY29uc3QgeyB2YWx1ZSB9ID0gdGhpcy5TZWxlY3RJbnB1dC5uYXRpdmVFbGVtZW50O1xuICAgIGNvbnN0IHRyaW1tZWRWYWx1ZSA9IHZhbHVlPy50b1N0cmluZygpPy50cmltKCk7XG4gICAgaWYgKHRyaW1tZWRWYWx1ZSkge1xuICAgICAgdGhpcy5yZW5kZXJlci5hZGRDbGFzcyh0aGlzLlNlbGVjdExhYmVsLm5hdGl2ZUVsZW1lbnQsICctLWlucHV0LS1zZWxlY3RlZCcpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnJlbmRlcmVyLnJlbW92ZUNsYXNzKHRoaXMuU2VsZWN0TGFiZWwubmF0aXZlRWxlbWVudCwgJy0taW5wdXQtLXNlbGVjdGVkJyk7XG4gICAgfVxuICB9XG5cbiAgb25Gb2N1cygpIHtcbiAgICB0aGlzLmljb25OYW1lQ2hhbmdlKCk7XG4gICAgdGhpcy5jdXJyZW50TWFzdGVyTGlzdCA9IFtdO1xuICAgIHRoaXMuY3VycmVudE9wdGlvbkVsZW1lbnRzID0gKHRoaXMuU2VsZWN0T3B0aW9ucy5uYXRpdmVFbGVtZW50IGFzIGFueSk/LmNoaWxkcmVuO1xuICAgIGNvbnN0IHsgdmFsdWUgfSA9IHRoaXMuU2VsZWN0SW5wdXQubmF0aXZlRWxlbWVudDtcbiAgICBjb25zdCBjdXJyZW50VmFsdWUgPSB2YWx1ZT8udG9TdHJpbmcoKT8udHJpbSgpO1xuICAgIGlmICghdGhpcy5jdXJyZW50T3B0aW9uRWxlbWVudHM/Lmxlbmd0aCkgcmV0dXJuO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5jdXJyZW50T3B0aW9uRWxlbWVudHMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IG9wdGlvbkVsZW1lbnQgPSB0aGlzLmN1cnJlbnRPcHRpb25FbGVtZW50c1tpXSBhcyBIVE1MRWxlbWVudDtcbiAgICAgIGNvbnN0IG9wdGlvblRleHQgPSBvcHRpb25FbGVtZW50LmlubmVyVGV4dD8udHJpbSgpO1xuICAgICAgdGhpcy5jdXJyZW50TWFzdGVyTGlzdC5wdXNoKG9wdGlvblRleHQpO1xuICAgICAgdGhpcy5yZW5kZXJlci5yZW1vdmVDbGFzcyhvcHRpb25FbGVtZW50LCAnc2VsZWN0ZWQtb3B0aW9uJyk7XG4gICAgICBpZiAoY3VycmVudFZhbHVlKSB7XG4gICAgICAgIGlmIChjdXJyZW50VmFsdWUgPT09IG9wdGlvblRleHQpIHRoaXMucmVuZGVyZXIuYWRkQ2xhc3Mob3B0aW9uRWxlbWVudCwgJ3NlbGVjdGVkLW9wdGlvbicpO1xuICAgICAgfVxuICAgICAgdGhpcy5yZW5kZXJlci5yZW1vdmVDbGFzcyhvcHRpb25FbGVtZW50LCAnaGlkZS1vcHRpb24nKTtcbiAgICAgIHRoaXMucmVuZGVyZXIuYWRkQ2xhc3Mob3B0aW9uRWxlbWVudCwgJ3Nob3ctb3B0aW9uJyk7XG4gICAgICB0aGlzLnJlbmRlcmVyLmFkZENsYXNzKG9wdGlvbkVsZW1lbnQsICdzZWxlY3QtcGFydCcpO1xuICAgIH1cbiAgICB0aGlzLnJlbmRlcmVyLnJlbW92ZUNsYXNzKHRoaXMuU2VsZWN0TGFiZWwubmF0aXZlRWxlbWVudCwgJy0taW5wdXQtLXNlbGVjdGVkJyk7XG4gICAgdGhpcy5yZW5kZXJlci5hZGRDbGFzcyh0aGlzLlNlbGVjdE9wdGlvbnMubmF0aXZlRWxlbWVudCwgJ2FjdGl2ZScpO1xuICB9XG5cbiAgb25LZXlVcChldmVudDogYW55KSB7XG4gICAgY29uc3QgeyBrZXlDb2RlIH0gPSBldmVudDtcbiAgICBpZiAoa2V5Q29kZSA9PT0gOSkgcmV0dXJuOyAvL1RhYlxuICAgIGlmICghdGhpcy5pc1NlYXJjaCkgcmV0dXJuO1xuICAgIHRoaXMuc2VsZWN0ZWRWYWx1ZUNoYW5nZS5lbWl0KG51bGwpO1xuICAgIHRoaXMuaXNJdGVtTm90Rm91bmQgPSBmYWxzZTtcbiAgICBjb25zdCBpbnB1dFZhbHVlID0gZXZlbnQudGFyZ2V0LnZhbHVlPy50b1N0cmluZygpPy50cmltKCk/LnRvTG93ZXJDYXNlKCk7XG4gICAgaWYgKCF0aGlzLmN1cnJlbnRPcHRpb25FbGVtZW50cz8ubGVuZ3RoKSByZXR1cm47XG5cbiAgICAvL0ZpbHRlck9wdGlvbnNcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuY3VycmVudE1hc3Rlckxpc3QubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IGZpbHRlcmVkTGlzdCA9IHRoaXMuY3VycmVudE1hc3Rlckxpc3QuZmlsdGVyKHggPT4geD8udG9TdHJpbmcoKT8udHJpbSgpPy50b0xvd2VyQ2FzZSgpLmluY2x1ZGVzKGlucHV0VmFsdWUpKTtcbiAgICAgIC8vQ2hlY2sgSXRlbUlzRm91bmRcbiAgICAgIGlmIChpbnB1dFZhbHVlICYmICFmaWx0ZXJlZExpc3QubGVuZ3RoKSB7XG4gICAgICAgIGNvbnN0IGN1cnJlbnRFbGVtZW50ID0gKDxIVE1MRWxlbWVudD50aGlzLlNlbGVjdEZpZWxkLm5hdGl2ZUVsZW1lbnQpLnF1ZXJ5U2VsZWN0b3JBbGwoXCIuaW5wdXQtaXRlbVwiKTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBjdXJyZW50RWxlbWVudC5sZW5ndGg7IGkrKykge1xuICAgICAgICAgIGNvbnN0IGVsZW1lbnQgPSBjdXJyZW50RWxlbWVudFtpXSBhcyBhbnk7XG4gICAgICAgICAgY29uc3QgaXNOb3RGb3VuZEVsZW1lbnQgPSBlbGVtZW50LmdldEF0dHJpYnV0ZSgnaXRlbS1ub3QtZm91bmQnKSA9PT0gJ3RydWUnO1xuICAgICAgICAgIGlmICghaXNOb3RGb3VuZEVsZW1lbnQpIGVsZW1lbnQuY2xhc3NOYW1lID0gYGlucHV0LWl0ZW0gJHtlbGVtZW50Py5nZXRBdHRyaWJ1dGUoJ3ZhbHVlJyl9IGhpZGUtb3B0aW9uYDtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmlzSXRlbU5vdEZvdW5kID0gdHJ1ZTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5pc0l0ZW1Ob3RGb3VuZCA9IGZhbHNlO1xuICAgICAgfVxuICAgICAgLy9JZiBJdGVtIEZvdW5kXG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuY3VycmVudE9wdGlvbkVsZW1lbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGNvbnN0IG9wdGlvbkVsZW1lbnQgPSB0aGlzLmN1cnJlbnRPcHRpb25FbGVtZW50c1tpXSBhcyBIVE1MRWxlbWVudDtcbiAgICAgICAgY29uc3Qgb3B0aW9uVGV4dCA9IG9wdGlvbkVsZW1lbnQuaW5uZXJUZXh0O1xuICAgICAgICB0aGlzLnJlbmRlcmVyLnJlbW92ZUNsYXNzKG9wdGlvbkVsZW1lbnQsICdzZWxlY3RlZC1vcHRpb24nKTtcbiAgICAgICAgaWYgKCFpbnB1dFZhbHVlKSB7XG4gICAgICAgICAgdGhpcy5yZW5kZXJlci5yZW1vdmVDbGFzcyhvcHRpb25FbGVtZW50LCAnaGlkZS1vcHRpb24nKTtcbiAgICAgICAgICB0aGlzLnJlbmRlcmVyLmFkZENsYXNzKG9wdGlvbkVsZW1lbnQsICdzaG93LW9wdGlvbicpO1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIGlmIChmaWx0ZXJlZExpc3QuZmluZCh4ID0+IHg/LnRyaW0oKSA9PT0gb3B0aW9uVGV4dD8udHJpbSgpKSkge1xuICAgICAgICAgIHRoaXMucmVuZGVyZXIucmVtb3ZlQ2xhc3Mob3B0aW9uRWxlbWVudCwgJ2hpZGUtb3B0aW9uJyk7XG4gICAgICAgICAgdGhpcy5yZW5kZXJlci5hZGRDbGFzcyhvcHRpb25FbGVtZW50LCAnc2hvdy1vcHRpb24nKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLnJlbmRlcmVyLmFkZENsYXNzKG9wdGlvbkVsZW1lbnQsICdoaWRlLW9wdGlvbicpO1xuICAgICAgICAgIHRoaXMucmVuZGVyZXIucmVtb3ZlQ2xhc3Mob3B0aW9uRWxlbWVudCwgJ3Nob3ctb3B0aW9uJyk7XG4gICAgICAgIH1cblxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIG9uQmx1cigpIHtcbiAgICB0aGlzLmljb25OYW1lQ2hhbmdlKCk7XG4gICAgdGhpcy5yZW5kZXJlci5yZW1vdmVDbGFzcyh0aGlzLlNlbGVjdE9wdGlvbnMubmF0aXZlRWxlbWVudCwgJ2FjdGl2ZScpO1xuICAgIGlmICgodGhpcy5kZWZhdWx0VmFsdWUgfHwgdGhpcy5kZWZhdWx0VmFsdWUgPT0gMCkgJiYgdGhpcy5zZWxlY3RlZFZhbHVlID09IG51bGwpIHtcbiAgICAgIHRoaXMuc2VsZWN0ZWRWYWx1ZUNoYW5nZS5lbWl0KHRoaXMuZGVmYXVsdFZhbHVlKTtcbiAgICAgIHRoaXMuc2VsZWN0ZWROYW1lID0gdGhpcy5kZWZhdWx0VmFsdWVOYW1lO1xuICAgICAgdGhpcy5yZW5kZXJlci5hZGRDbGFzcyh0aGlzLlNlbGVjdEZpZWxkLm5hdGl2ZUVsZW1lbnQsICctLWlucHV0LS1zZWxlY3RlZCcpO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAoIXRoaXMuc2VsZWN0ZWRWYWx1ZSAmJiB0aGlzLnNlbGVjdGVkVmFsdWUgIT0gMCkge1xuICAgICAgICB0aGlzLnNlbGVjdGVkTmFtZSA9IFwiXCI7XG4gICAgICAgIGNvbnN0IGN1cnJlbnRFbGVtZW50ID0gKDxIVE1MRWxlbWVudD50aGlzLlNlbGVjdEZpZWxkLm5hdGl2ZUVsZW1lbnQpLnF1ZXJ5U2VsZWN0b3IoXG4gICAgICAgICAgJy4tLWlucHV0LS1zZWxlY3RlZCdcbiAgICAgICAgKTtcbiAgICAgICAgaWYgKGN1cnJlbnRFbGVtZW50KSB0aGlzLnJlbmRlcmVyLnJlbW92ZUNsYXNzKGN1cnJlbnRFbGVtZW50LCBcIi0taW5wdXQtLXNlbGVjdGVkXCIpXG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcGxhY2Vob2xkZXJBY3RpdmUoc2VsZWN0b3I6IEhUTUxJbnB1dEVsZW1lbnQpIHtcbiAgICBpZiAoc2VsZWN0b3IuZ2V0QXR0cmlidXRlKCdwbGFjZWhvbGRlcicpKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgaWNvbk5hbWVDaGFuZ2UoKSB7XG4gICAgY29uc3QgaWNvbk5hbWUgPSB0aGlzLlNlbGVjdE9wdGlvbnMubmF0aXZlRWxlbWVudD8ubmV4dEVsZW1lbnRTaWJsaW5nPy5pbm5lclRleHQ7XG4gICAgdGhpcy5TZWxlY3RPcHRpb25zLm5hdGl2ZUVsZW1lbnQubmV4dEVsZW1lbnRTaWJsaW5nLmlubmVyVGV4dCA9IGljb25OYW1lID09PSAnZXhwYW5kX21vcmUnID8gJ2V4cGFuZF9sZXNzJyA6ICdleHBhbmRfbW9yZSc7XG4gIH1cbn1cbiJdfQ==