@crediblefinance/credible-ui
Version:
Credible's standard UI library
171 lines • 32.4 kB
JavaScript
import { Component, EventEmitter, Input, Output } from '@angular/core';
import { FormControl, FormGroup } from '@angular/forms';
import * as i0 from "@angular/core";
import * as i1 from "@angular/common";
import * as i2 from "@angular/forms";
import * as i3 from "@angular/material/select";
import * as i4 from "@angular/material/core";
export class CfMobileNumberComponent {
mobileNumber = '';
options = [];
selected = '';
showLabel = true;
readonly = false;
label = '';
length = 10;
placeholder = '';
name;
id = null;
disabled = false;
dialCodeChanged = new EventEmitter();
mobileNumberChanged = new EventEmitter();
maxLength = null;
minLength = null;
currentSelected = {
countryCode: '',
countryName: '',
dialCode: '',
flagUrl: '',
mobileNumberLength: 10
};
allowedKeys = new Set();
formGroup;
inputControl;
dialCodeControl;
// HTML helpers
objectFn = Object;
constructor() {
if (!this.inputControl && !this.formGroup && !this.dialCodeControl) {
this.formGroup = new FormGroup({});
this.inputControl = new FormControl('');
this.dialCodeControl = new FormControl('');
}
}
ngOnInit() {
const allowedKeys = [
'Backspace',
'Digit0',
'Digit1',
'Digit2',
'Digit3',
'Digit4',
'Digit5',
'Digit6',
'Digit7',
'Digit8',
'Digit9',
'ArrowRight',
'ArrowLeft',
'ArrowUp',
'ArrowDown'
];
this.allowedKeys = new Set(allowedKeys);
}
validOption(value) {
if (value === '')
return -1;
for (let i = 0; i < this.options.length; i++) {
if (this.options[i].dialCode === value)
return i;
}
return -1;
}
changeDropdown(matSelectChange) {
this.currentSelected = matSelectChange.value;
this.dialCodeChanged.emit(this.currentSelected);
}
ngOnChanges(changes) {
if (changes.mobileNumber) {
this.mobileNumber = changes.mobileNumber.currentValue;
this.inputControl.setValue(this.mobileNumber);
}
if (changes.selected && changes.selected.currentValue)
this.setSelectedValue();
if (changes.options && changes.options.currentValue)
this.setSelectedValue();
}
setSelectedValue() {
if (this.selected === '')
return;
if (!this.options)
return;
if (this.options.length === 0)
return;
const index = this.validOption(this.selected);
if (index === -1)
this.currentSelected = this.options[0];
else
this.currentSelected = this.options[index];
this.dialCodeControl.setValue(this.currentSelected);
}
valueChangedHandler($event) {
this.mobileNumberChanged.emit($event.target.value);
}
keydown(event) {
const allowed = this.allowedKeys.has(event.code);
if (!allowed)
return false;
if (!this.optionalKeys(event)) {
// equality is needed to avoid the edge condition
if (this.mobileNumber.length >= this.length)
return false;
}
return true;
}
optionalKeys(event) {
if (event.code === 'Backspace')
return true;
if (event.code === 'ArrowLeft')
return true;
if (event.code === 'ArrowRight')
return true;
if (event.code === 'ArrowUp')
return true;
if (event.code === 'ArrowDown')
return true;
return false;
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.9", ngImport: i0, type: CfMobileNumberComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.0.9", type: CfMobileNumberComponent, selector: "cf-mobile-number", inputs: { mobileNumber: "mobileNumber", options: "options", selected: "selected", showLabel: "showLabel", readonly: "readonly", label: "label", length: "length", placeholder: "placeholder", name: "name", id: "id", disabled: "disabled", maxLength: "maxLength", minLength: "minLength", formGroup: "formGroup", inputControl: "inputControl", dialCodeControl: "dialCodeControl" }, outputs: { dialCodeChanged: "dialCodeChanged", mobileNumberChanged: "mobileNumberChanged" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"cf-mobile-number\">\n <div>\n <label class=\"label\">{{ label }}</label>\n </div>\n\n <div\n [class.error]=\"\n (inputControl.invalid && inputControl.touched) ||\n (dialCodeControl.invalid && dialCodeControl.touched)\n \"\n class=\"holder\"\n [formGroup]=\"formGroup\"\n >\n <div class=\"dropdown-holder\">\n <mat-select\n matNativeControl\n [formControl]=\"dialCodeControl\"\n (selectionChange)=\"changeDropdown($event)\"\n >\n <mat-select-trigger>\n <img\n [src]=\"currentSelected.flagUrl\"\n [alt]=\"currentSelected.countryName\"\n width=\"30\"\n style=\"margin-right: 0.3rem\"\n />\n </mat-select-trigger>\n <mat-option\n [value]=\"item\"\n *ngFor=\"let item of options\"\n [disabled]=\"disabled\"\n >\n <img\n [src]=\"item.flagUrl\"\n [alt]=\"item.countryName\"\n width=\"25\"\n style=\"margin-right: 0.5rem\"\n />\n {{ item.countryName }}\n <span style=\"color: grey\">({{ item.dialCode }})</span>\n </mat-option>\n </mat-select>\n </div>\n <div class=\"isd-code-holder\" *ngIf=\"currentSelected\">\n <span> {{ currentSelected.dialCode }} </span>\n </div>\n <div class=\"input-holder\">\n <span *ngIf=\"readonly\"> {{ mobileNumber }} </span>\n <input\n type=\"number\"\n class=\"value-span\"\n [name]=\"name\"\n [id]=\"id\"\n [value]=\"mobileNumber\"\n [placeholder]=\"placeholder\"\n [formControl]=\"inputControl\"\n [minLength]=\"minLength\"\n [maxlength]=\"maxLength\"\n (keyup)=\"valueChangedHandler($event)\"\n *ngIf=\"!readonly\"\n />\n </div>\n </div>\n <div\n class=\"text-danger\"\n *ngIf=\"inputControl.errors && inputControl.touched\"\n >\n {{ inputControl.errors[objectFn.keys(inputControl.errors)[0]] }}\n </div>\n <div\n class=\"text-danger\"\n *ngIf=\"\n dialCodeControl.errors &&\n dialCodeControl.touched &&\n !inputControl.errors\n \"\n >\n {{ dialCodeControl.errors[objectFn.keys(dialCodeControl.errors)[0]] }}\n </div>\n</div>\n", styles: [".cf-mobile-number{padding:0 1rem;height:max-content;margin-left:auto;margin-right:auto;margin-bottom:1rem}.cf-mobile-number .error{border:.5px solid #dc3545!important}.cf-mobile-number .error .dropdown-holder{border-right:1px solid #dc3545!important}.cf-mobile-number .holder{border:.1px solid #f5f5f5;border-radius:9px;padding:.2rem .5rem;display:flex}.cf-mobile-number .isd-code-holder{display:flex;justify-content:space-between;align-items:center}.cf-mobile-number .isd-code-holder span{border:none;color:gray;padding-left:.5rem}.cf-mobile-number .input-holder{display:flex;justify-content:space-between;align-items:center;padding-left:5px;width:100%}.cf-mobile-number .input-holder span{border:none}.cf-mobile-number .input-holder input{border:none;width:100%}.cf-mobile-number .input-holder .fa-copy{margin-left:1rem}.cf-mobile-number .label{font-weight:700;font-size:.8rem}.cf-mobile-number .dropdown-holder{width:max-content;border-right:1px solid rgba(0,0,0,.1);padding-right:5px}@media only screen and (max-width: 500px){span,input,.label{font-size:1rem!important}}::ng-deep .cf-mobile-number .mat-select-value{max-width:unset}input:focus,select:focus,textarea:focus,button:focus{outline:none}input:-webkit-autofill,input:-webkit-autofill:hover,input:-webkit-autofill:focus,input:-webkit-autofill:active{-webkit-box-shadow:0 0 0 30px white inset!important}input::-webkit-inner-spin-button,input::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}input[type=number]{appearance:textfield}\n"], 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.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { 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.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { kind: "directive", type: i2.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: i3.MatSelect, selector: "mat-select", inputs: ["disabled", "disableRipple", "tabIndex", "aria-describedby", "panelClass", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "directive", type: i3.MatSelectTrigger, selector: "mat-select-trigger" }, { kind: "component", type: i4.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.9", ngImport: i0, type: CfMobileNumberComponent, decorators: [{
type: Component,
args: [{ selector: 'cf-mobile-number', template: "<div class=\"cf-mobile-number\">\n <div>\n <label class=\"label\">{{ label }}</label>\n </div>\n\n <div\n [class.error]=\"\n (inputControl.invalid && inputControl.touched) ||\n (dialCodeControl.invalid && dialCodeControl.touched)\n \"\n class=\"holder\"\n [formGroup]=\"formGroup\"\n >\n <div class=\"dropdown-holder\">\n <mat-select\n matNativeControl\n [formControl]=\"dialCodeControl\"\n (selectionChange)=\"changeDropdown($event)\"\n >\n <mat-select-trigger>\n <img\n [src]=\"currentSelected.flagUrl\"\n [alt]=\"currentSelected.countryName\"\n width=\"30\"\n style=\"margin-right: 0.3rem\"\n />\n </mat-select-trigger>\n <mat-option\n [value]=\"item\"\n *ngFor=\"let item of options\"\n [disabled]=\"disabled\"\n >\n <img\n [src]=\"item.flagUrl\"\n [alt]=\"item.countryName\"\n width=\"25\"\n style=\"margin-right: 0.5rem\"\n />\n {{ item.countryName }}\n <span style=\"color: grey\">({{ item.dialCode }})</span>\n </mat-option>\n </mat-select>\n </div>\n <div class=\"isd-code-holder\" *ngIf=\"currentSelected\">\n <span> {{ currentSelected.dialCode }} </span>\n </div>\n <div class=\"input-holder\">\n <span *ngIf=\"readonly\"> {{ mobileNumber }} </span>\n <input\n type=\"number\"\n class=\"value-span\"\n [name]=\"name\"\n [id]=\"id\"\n [value]=\"mobileNumber\"\n [placeholder]=\"placeholder\"\n [formControl]=\"inputControl\"\n [minLength]=\"minLength\"\n [maxlength]=\"maxLength\"\n (keyup)=\"valueChangedHandler($event)\"\n *ngIf=\"!readonly\"\n />\n </div>\n </div>\n <div\n class=\"text-danger\"\n *ngIf=\"inputControl.errors && inputControl.touched\"\n >\n {{ inputControl.errors[objectFn.keys(inputControl.errors)[0]] }}\n </div>\n <div\n class=\"text-danger\"\n *ngIf=\"\n dialCodeControl.errors &&\n dialCodeControl.touched &&\n !inputControl.errors\n \"\n >\n {{ dialCodeControl.errors[objectFn.keys(dialCodeControl.errors)[0]] }}\n </div>\n</div>\n", styles: [".cf-mobile-number{padding:0 1rem;height:max-content;margin-left:auto;margin-right:auto;margin-bottom:1rem}.cf-mobile-number .error{border:.5px solid #dc3545!important}.cf-mobile-number .error .dropdown-holder{border-right:1px solid #dc3545!important}.cf-mobile-number .holder{border:.1px solid #f5f5f5;border-radius:9px;padding:.2rem .5rem;display:flex}.cf-mobile-number .isd-code-holder{display:flex;justify-content:space-between;align-items:center}.cf-mobile-number .isd-code-holder span{border:none;color:gray;padding-left:.5rem}.cf-mobile-number .input-holder{display:flex;justify-content:space-between;align-items:center;padding-left:5px;width:100%}.cf-mobile-number .input-holder span{border:none}.cf-mobile-number .input-holder input{border:none;width:100%}.cf-mobile-number .input-holder .fa-copy{margin-left:1rem}.cf-mobile-number .label{font-weight:700;font-size:.8rem}.cf-mobile-number .dropdown-holder{width:max-content;border-right:1px solid rgba(0,0,0,.1);padding-right:5px}@media only screen and (max-width: 500px){span,input,.label{font-size:1rem!important}}::ng-deep .cf-mobile-number .mat-select-value{max-width:unset}input:focus,select:focus,textarea:focus,button:focus{outline:none}input:-webkit-autofill,input:-webkit-autofill:hover,input:-webkit-autofill:focus,input:-webkit-autofill:active{-webkit-box-shadow:0 0 0 30px white inset!important}input::-webkit-inner-spin-button,input::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}input[type=number]{appearance:textfield}\n"] }]
}], ctorParameters: () => [], propDecorators: { mobileNumber: [{
type: Input
}], options: [{
type: Input
}], selected: [{
type: Input
}], showLabel: [{
type: Input
}], readonly: [{
type: Input
}], label: [{
type: Input
}], length: [{
type: Input
}], placeholder: [{
type: Input
}], name: [{
type: Input
}], id: [{
type: Input
}], disabled: [{
type: Input
}], dialCodeChanged: [{
type: Output
}], mobileNumberChanged: [{
type: Output
}], maxLength: [{
type: Input
}], minLength: [{
type: Input
}], formGroup: [{
type: Input
}], inputControl: [{
type: Input
}], dialCodeControl: [{
type: Input
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2YtbW9iaWxlLW51bWJlci5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9jcmVkaWJsZS11aS9zcmMvbGliL2NmLW1vYmlsZS1udW1iZXIvY2YtbW9iaWxlLW51bWJlci5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9jcmVkaWJsZS11aS9zcmMvbGliL2NmLW1vYmlsZS1udW1iZXIvY2YtbW9iaWxlLW51bWJlci5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0gsU0FBUyxFQUFFLFlBQVksRUFBRSxLQUFLLEVBQXFCLE1BQU0sRUFDNUQsTUFBTSxlQUFlLENBQUM7QUFFdkIsT0FBTyxFQUNILFdBQVcsRUFBRSxTQUFTLEVBQ3pCLE1BQU0sZ0JBQWdCLENBQUM7Ozs7OztBQVF4QixNQUFNLE9BQU8sdUJBQXVCO0lBQ3ZCLFlBQVksR0FBVyxFQUFFLENBQUM7SUFDMUIsT0FBTyxHQUFxQixFQUFFLENBQUM7SUFDL0IsUUFBUSxHQUFXLEVBQUUsQ0FBQztJQUN0QixTQUFTLEdBQVksSUFBSSxDQUFDO0lBQzFCLFFBQVEsR0FBWSxLQUFLLENBQUM7SUFDMUIsS0FBSyxHQUFXLEVBQUUsQ0FBQztJQUNuQixNQUFNLEdBQVcsRUFBRSxDQUFDO0lBQ3BCLFdBQVcsR0FBVyxFQUFFLENBQUM7SUFDekIsSUFBSSxDQUFVO0lBQ2QsRUFBRSxHQUFtQixJQUFJLENBQUM7SUFDMUIsUUFBUSxHQUFZLEtBQUssQ0FBQztJQUV6QixlQUFlLEdBQUcsSUFBSSxZQUFZLEVBQUUsQ0FBQztJQUNyQyxtQkFBbUIsR0FBRyxJQUFJLFlBQVksRUFBRSxDQUFDO0lBRTFDLFNBQVMsR0FBa0IsSUFBSSxDQUFDO0lBQ2hDLFNBQVMsR0FBa0IsSUFBSSxDQUFDO0lBRXpDLGVBQWUsR0FBYztRQUN6QixXQUFXLEVBQUUsRUFBRTtRQUNmLFdBQVcsRUFB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QU8sS0FBSyxDQUFDO0lBQ2pCLENBQUM7dUdBMUpRLHVCQUF1QjsyRkFBdkIsdUJBQXVCLGtpQkNkcEMsZ3ZGQWdGQTs7MkZEbEVhLHVCQUF1QjtrQkFMbkMsU0FBUzsrQkFDSSxrQkFBa0I7d0RBS25CLFlBQVk7c0JBQXBCLEtBQUs7Z0JBQ0csT0FBTztzQkFBZixLQUFLO2dCQUNHLFFBQVE7c0JBQWhCLEtBQUs7Z0JBQ0csU0FBUztzQkFBakIsS0FBSztnQkFDRyxRQUFRO3NCQUFoQixLQUFLO2dCQUNHLEtBQUs7c0JBQWIsS0FBSztnQkFDRyxNQUFNO3NCQUFkLEtBQUs7Z0JBQ0csV0FBVztzQkFBbkIsS0FBSztnQkFDRyxJQUFJO3NCQUFaLEtBQUs7Z0JBQ0csRUFBRTtzQkFBVixLQUFLO2dCQUNHLFFBQVE7c0JBQWhCLEtBQUs7Z0JBRUksZUFBZTtzQkFBeEIsTUFBTTtnQkFDRyxtQkFBbUI7c0JBQTVCLE1BQU07Z0JBRUUsU0FBUztzQkFBakIsS0FBSztnQkFDRyxTQUFTO3NCQUFqQixLQUFLO2dCQVlHLFNBQVM7c0JBQWpCLEtBQUs7Z0JBQ0csWUFBWTtzQkFBcEIsS0FBSztnQkFDRyxlQUFlO3NCQUF2QixLQUFLIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgICBDb21wb25lbnQsIEV2ZW50RW1pdHRlciwgSW5wdXQsIE9uQ2hhbmdlcywgT25Jbml0LCBPdXRwdXQsIFNpbXBsZUNoYW5nZXNcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBNYXRTZWxlY3RDaGFuZ2UgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9zZWxlY3QnO1xuaW1wb3J0IHtcbiAgICBGb3JtQ29udHJvbCwgRm9ybUdyb3VwXG59IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCBJRGlhbENvZGUgZnJvbSAnLi4vaW50ZXJmYWNlcy9JRGlhbENvZGUnO1xuXG5AQ29tcG9uZW50KHtcbiAgICBzZWxlY3RvcjogJ2NmLW1vYmlsZS1udW1iZXInLFxuICAgIHRlbXBsYXRlVXJsOiAnLi9jZi1tb2JpbGUtbnVtYmVyLmNvbXBvbmVudC5odG1sJyxcbiAgICBzdHlsZVVybHM6IFsnLi9jZi1tb2JpbGUtbnVtYmVyLmNvbXBvbmVudC5zY3NzJ11cbn0pXG5leHBvcnQgY2xhc3MgQ2ZNb2JpbGVOdW1iZXJDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIE9uQ2hhbmdlcyB7XG4gICAgQElucHV0KCkgbW9iaWxlTnVtYmVyOiBzdHJpbmcgPSAnJztcbiAgICBASW5wdXQoKSBvcHRpb25zOiBBcnJheTxJRGlhbENvZGU+ID0gW107XG4gICAgQElucHV0KCkgc2VsZWN0ZWQ6IHN0cmluZyA9ICcnO1xuICAgIEBJbnB1dCgpIHNob3dMYWJlbDogYm9vbGVhbiA9IHRydWU7XG4gICAgQElucHV0KCkgcmVhZG9ubHk6IGJvb2xlYW4gPSBmYWxzZTtcbiAgICBASW5wdXQoKSBsYWJlbDogc3RyaW5nID0gJyc7XG4gICAgQElucHV0KCkgbGVuZ3RoOiBudW1iZXIgPSAxMDtcbiAgICBASW5wdXQoKSBwbGFjZWhvbGRlcjogc3RyaW5nID0gJyc7XG4gICAgQElucHV0KCkgbmFtZT86IHN0cmluZztcbiAgICBASW5wdXQoKSBpZD86IHN0cmluZyB8IG51bGwgPSBudWxsO1xuICAgIEBJbnB1dCgpIGRpc2FibGVkOiBib29sZWFuID0gZmFsc2U7XG5cbiAgICBAT3V0cHV0KCkgZGlhbENvZGVDaGFuZ2VkID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuICAgIEBPdXRwdXQoKSBtb2JpbGVOdW1iZXJDaGFuZ2VkID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuXG4gICAgQElucHV0KCkgbWF4TGVuZ3RoOiBudW1iZXIgfCBudWxsID0gbnVsbDtcbiAgICBASW5wdXQoKSBtaW5MZW5ndGg6IG51bWJlciB8IG51bGwgPSBudWxsO1xuXG4gICAgY3VycmVudFNlbGVjdGVkOiBJRGlhbENvZGUgPSB7XG4gICAgICAgIGNvdW50cnlDb2RlOiAnJyxcbiAgICAgICAgY291bnRyeU5hbWU6ICcnLFxuICAgICAgICBkaWFsQ29kZTogJycsXG4gICAgICAgIGZsYWdVcmw6ICcnLFxuICAgICAgICBtb2JpbGVOdW1iZXJMZW5ndGg6IDEwXG4gICAgfTtcblxuICAgIGFsbG93ZWRLZXlzOiBTZXQ8c3RyaW5nPiA9IG5ldyBTZXQoKTtcblxuICAgIEBJbnB1dCgpIGZvcm1Hcm91cCE6IEZvcm1Hcm91cDtcbiAgICBASW5wdXQoKSBpbnB1dENvbnRyb2whOiBGb3JtQ29udHJvbDtcbiAgICBASW5wdXQoKSBkaWFsQ29kZUNvbnRyb2whOiBGb3JtQ29udHJvbDtcblxuICAgIC8vIEhUTUwgaGVscGVyc1xuICAgIG9iamVjdEZuID0gT2JqZWN0O1xuXG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIGlmICghdGhpcy5pbnB1dENvbnRyb2wgJiYgIXRoaXMuZm9ybUdyb3VwICYmICF0aGlzLmRpYWxDb2RlQ29udHJvbCkge1xuICAgICAgICAgICAgdGhpcy5mb3JtR3JvdXAgPSBuZXcgRm9ybUdyb3VwKHt9KTtcbiAgICAgICAgICAgIHRoaXMuaW5wdXRDb250cm9sID0gbmV3IEZvcm1Db250cm9sKCcnKTtcbiAgICAgICAgICAgIHRoaXMuZGlhbENvZGVDb250cm9sID0gbmV3IEZvcm1Db250cm9sKCcnKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIG5nT25Jbml0KCk6IHZvaWQge1xuICAgICAgICBjb25zdCBhbGxvd2VkS2V5cyA9IFtcbiAgICAgICAgICAgICdCYWNrc3BhY2UnLCAvLyBiYWNrc3BhY2VcbiAgICAgICAgICAgICdEaWdpdDAnLCAvLyB6ZXJvXG4gICAgICAgICAgICAnRGlnaXQxJywgLy8gb25lXG4gICAgICAgICAgICAnRGlnaXQyJywgLy8gdHdvXG4gICAgICAgICAgICAnRGlnaXQzJywgLy8gdGhyZWVcbiAgICAgICAgICAgICdEaWdpdDQnLCAvLyBmb3VyXG4gICAgICAgICAgICAnRGlnaXQ1JywgLy8gZml2ZVxuICAgICAgICAgICAgJ0RpZ2l0NicsIC8vIHNpeFxuICAgICAgICAgICAgJ0RpZ2l0NycsIC8vIHNldmVuXG4gICAgICAgICAgICAnRGlnaXQ4JywgLy8gZWlnaHRcbiAgICAgICAgICAgICdEaWdpdDknLCAvLyBuaW5lLFxuICAgICAgICAgICAgJ0Fycm93UmlnaHQnLFxuICAgICAgICAgICAgJ0Fycm93TGVmdCcsXG4gICAgICAgICAgICAnQXJyb3dVcCcsXG4gICAgICAgICAgICAnQXJyb3dEb3duJ1xuICAgICAgICBdO1xuXG4gICAgICAgIHRoaXMuYWxsb3dlZEtleXMgPSBuZXcgU2V0KGFsbG93ZWRLZXlzKTtcbiAgICB9XG5cbiAgICB2YWxpZE9wdGlvbih2YWx1ZTogc3RyaW5nKSB7XG4gICAgICAgIGlmICh2YWx1ZSA9PT0gJycpXG4gICAgICAgICAgICByZXR1cm4gLTE7XG5cbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLm9wdGlvbnMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGlmICh0aGlzLm9wdGlvbnNbaV0uZGlhbENvZGUgPT09IHZhbHVlKVxuICAgICAgICAgICAgICAgIHJldHVybiBpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIC0xO1xuICAgIH1cblxuICAgIGNoYW5nZURyb3Bkb3duKG1hdFNlbGVjdENoYW5nZTogTWF0U2VsZWN0Q2hhbmdlKSB7XG4gICAgICAgIHRoaXMuY3VycmVudFNlbGVjdGVkID0gbWF0U2VsZWN0Q2hhbmdlLnZhbHVlO1xuXG4gICAgICAgIHRoaXMuZGlhbENvZGVDaGFuZ2VkLmVtaXQodGhpcy5jdXJyZW50U2VsZWN0ZWQpO1xuICAgIH1cblxuICAgIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpOiB2b2lkIHtcbiAgICAgICAgaWYgKGNoYW5nZXMubW9iaWxlTnVtYmVyKSB7XG4gICAgICAgICAgICB0aGlzLm1vYmlsZU51bWJlciA9IGNoYW5nZXMubW9iaWxlTnVtYmVyLmN1cnJlbnRWYWx1ZTtcbiAgICAgICAgICAgIHRoaXMuaW5wdXRDb250cm9sLnNldFZhbHVlKHRoaXMubW9iaWxlTnVtYmVyKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChjaGFuZ2VzLnNlbGVjdGVkICYmIGNoYW5nZXMuc2VsZWN0ZWQuY3VycmVudFZhbHVlKVxuICAgICAgICAgICAgdGhpcy5zZXRTZWxlY3RlZFZhbHVlKCk7XG5cbiAgICAgICAgaWYgKGNoYW5nZXMub3B0aW9ucyAmJiBjaGFuZ2VzLm9wdGlvbnMuY3VycmVudFZhbHVlKVxuICAgICAgICAgICAgdGhpcy5zZXRTZWxlY3RlZFZhbHVlKCk7XG4gICAgfVxuXG4gICAgc2V0U2VsZWN0ZWRWYWx1ZSgpIHtcbiAgICAgICAgaWYgKHRoaXMuc2VsZWN0ZWQgPT09ICcnKVxuICAgICAgICAgICAgcmV0dXJuO1xuXG4gICAgICAgIGlmICghdGhpcy5vcHRpb25zKVxuICAgICAgICAgICAgcmV0dXJuO1xuXG4gICAgICAgIGlmICh0aGlzLm9wdGlvbnMubGVuZ3RoID09PSAwKVxuICAgICAgICAgICAgcmV0dXJuO1xuXG4gICAgICAgIGNvbnN0IGluZGV4ID0gdGhpcy52YWxpZE9wdGlvbih0aGlzLnNlbGVjdGVkKTtcblxuICAgICAgICBpZiAoaW5kZXggPT09IC0xKVxuICAgICAgICAgICAgdGhpcy5jdXJyZW50U2VsZWN0ZWQgPSB0aGlzLm9wdGlvbnNbMF07XG5cbiAgICAgICAgZWxzZVxuICAgICAgICAgICAgdGhpcy5jdXJyZW50U2VsZWN0ZWQgPSB0aGlzLm9wdGlvbnNbaW5kZXhdO1xuXG4gICAgICAgIHRoaXMuZGlhbENvZGVDb250cm9sLnNldFZhbHVlKHRoaXMuY3VycmVudFNlbGVjdGVkKTtcbiAgICB9XG5cbiAgICB2YWx1ZUNoYW5nZWRIYW5kbGVyKCRldmVudDogYW55KSB7XG4gICAgICAgIHRoaXMubW9iaWxlTnVtYmVyQ2hhbmdlZC5lbWl0KCRldmVudC50YXJnZXQudmFsdWUpO1xuICAgIH1cblxuICAgIGtleWRvd24oZXZlbnQ6IEtleWJvYXJkRXZlbnQpIHtcbiAgICAgICAgY29uc3QgYWxsb3dlZCA9IHRoaXMuYWxsb3dlZEtleXMuaGFzKGV2ZW50LmNvZGUpO1xuXG4gICAgICAgIGlmICghYWxsb3dlZClcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcblxuICAgICAgICBpZiAoIXRoaXMub3B0aW9uYWxLZXlzKGV2ZW50KSkge1xuICAgICAgICAgICAgLy8gZXF1YWxpdHkgaXMgbmVlZGVkIHRvIGF2b2lkIHRoZSBlZGdlIGNvbmRpdGlvblxuICAgICAgICAgICAgaWYgKHRoaXMubW9iaWxlTnVtYmVyLmxlbmd0aCA+PSB0aGlzLmxlbmd0aClcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICBvcHRpb25hbEtleXMoZXZlbnQ6IEtleWJvYXJkRXZlbnQpIHtcbiAgICAgICAgaWYgKGV2ZW50LmNvZGUgPT09ICdCYWNrc3BhY2UnKVxuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG5cbiAgICAgICAgaWYgKGV2ZW50LmNvZGUgPT09ICdBcnJvd0xlZnQnKVxuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG5cbiAgICAgICAgaWYgKGV2ZW50LmNvZGUgPT09ICdBcnJvd1JpZ2h0JylcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuXG4gICAgICAgIGlmIChldmVudC5jb2RlID09PSAnQXJyb3dVcCcpXG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcblxuICAgICAgICBpZiAoZXZlbnQuY29kZSA9PT0gJ0Fycm93RG93bicpXG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcblxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxufVxuIiwiPGRpdiBjbGFzcz1cImNmLW1vYmlsZS1udW1iZXJcIj5cbiAgICA8ZGl2PlxuICAgICAgICA8bGFiZWwgY2xhc3M9XCJsYWJlbFwiPnt7IGxhYmVsIH19PC9sYWJlbD5cbiAgICA8L2Rpdj5cblxuICAgIDxkaXZcbiAgICAgICAgW2NsYXNzLmVycm9yXT1cIlxuICAgICAgICAgICAgKGlucHV0Q29udHJvbC5pbnZhbGlkICYmIGlucHV0Q29udHJvbC50b3VjaGVkKSB8fFxuICAgICAgICAgICAgKGRpYWxDb2RlQ29udHJvbC5pbnZhbGlkICYmIGRpYWxDb2RlQ29udHJvbC50b3VjaGVkKVxuICAgICAgICBcIlxuICAgICAgICBjbGFzcz1cImhvbGRlclwiXG4gICAgICAgIFtmb3JtR3JvdXBdPVwiZm9ybUdyb3VwXCJcbiAgICA+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJkcm9wZG93bi1ob2xkZXJcIj5cbiAgICAgICAgICAgIDxtYXQtc2VsZWN0XG4gICAgICAgICAgICAgICAgbWF0TmF0aXZlQ29udHJvbFxuICAgICAgICAgICAgICAgIFtmb3JtQ29udHJvbF09XCJkaWFsQ29kZUNvbnRyb2xcIlxuICAgICAgICAgICAgICAgIChzZWxlY3Rpb25DaGFuZ2UpPVwiY2hhbmdlRHJvcGRvd24oJGV2ZW50KVwiXG4gICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgPG1hdC1zZWxlY3QtdHJpZ2dlcj5cbiAgICAgICAgICAgICAgICAgICAgPGltZ1xuICAgICAgICAgICAgICAgICAgICAgICAgW3NyY109XCJjdXJyZW50U2VsZWN0ZWQuZmxhZ1VybFwiXG4gICAgICAgICAgICAgICAgICAgICAgICBbYWx0XT1cImN1cnJlbnRTZWxlY3RlZC5jb3VudHJ5TmFtZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICB3aWR0aD1cIjMwXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlPVwibWFyZ2luLXJpZ2h0OiAwLjNyZW1cIlxuICAgICAgICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgICAgIDwvbWF0LXNlbGVjdC10cmlnZ2VyPlxuICAgICAgICAgICAgICAgIDxtYXQtb3B0aW9uXG4gICAgICAgICAgICAgICAgICAgIFt2YWx1ZV09XCJpdGVtXCJcbiAgICAgICAgICAgICAgICAgICAgKm5nRm9yPVwibGV0IGl0ZW0gb2Ygb3B0aW9uc1wiXG4gICAgICAgICAgICAgICAgICAgIFtkaXNhYmxlZF09XCJkaXNhYmxlZFwiXG4gICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICA8aW1nXG4gICAgICAgICAgICAgICAgICAgICAgICBbc3JjXT1cIml0ZW0uZmxhZ1VybFwiXG4gICAgICAgICAgICAgICAgICAgICAgICBbYWx0XT1cIml0ZW0uY291bnRyeU5hbWVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGg9XCIyNVwiXG4gICAgICAgICAgICAgICAgICAgICAgICBzdHlsZT1cIm1hcmdpbi1yaWdodDogMC41cmVtXCJcbiAgICAgICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgICAgICAge3sgaXRlbS5jb3VudHJ5TmFtZSB9fVxuICAgICAgICAgICAgICAgICAgICA8c3BhbiBzdHlsZT1cImNvbG9yOiBncmV5XCI+KHt7IGl0ZW0uZGlhbENvZGUgfX0pPC9zcGFuPlxuICAgICAgICAgICAgICAgIDwvbWF0LW9wdGlvbj5cbiAgICAgICAgICAgIDwvbWF0LXNlbGVjdD5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJpc2QtY29kZS1ob2xkZXJcIiAqbmdJZj1cImN1cnJlbnRTZWxlY3RlZFwiPlxuICAgICAgICAgICAgPHNwYW4+IHt7IGN1cnJlbnRTZWxlY3RlZC5kaWFsQ29kZSB9fSA8L3NwYW4+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8ZGl2IGNsYXNzPVwiaW5wdXQtaG9sZGVyXCI+XG4gICAgICAgICAgICA8c3BhbiAqbmdJZj1cInJlYWRvbmx5XCI+IHt7IG1vYmlsZU51bWJlciB9fSA8L3NwYW4+XG4gICAgICAgICAgICA8aW5wdXRcbiAgICAgICAgICAgICAgICB0eXBlPVwibnVtYmVyXCJcbiAgICAgICAgICAgICAgICBjbGFzcz1cInZhbHVlLXNwYW5cIlxuICAgICAgICAgICAgICAgIFtuYW1lXT1cIm5hbWVcIlxuICAgICAgICAgICAgICAgIFtpZF09XCJpZFwiXG4gICAgICAgICAgICAgICAgW3ZhbHVlXT1cIm1vYmlsZU51bWJlclwiXG4gICAgICAgICAgICAgICAgW3BsYWNlaG9sZGVyXT1cInBsYWNlaG9sZGVyXCJcbiAgICAgICAgICAgICAgICBbZm9ybUNvbnRyb2xdPVwiaW5wdXRDb250cm9sXCJcbiAgICAgICAgICAgICAgICBbbWluTGVuZ3RoXT1cIm1pbkxlbmd0aFwiXG4gICAgICAgICAgICAgICAgW21heGxlbmd0aF09XCJtYXhMZW5ndGhcIlxuICAgICAgICAgICAgICAgIChrZXl1cCk9XCJ2YWx1ZUNoYW5nZWRIYW5kbGVyKCRldmVudClcIlxuICAgICAgICAgICAgICAgICpuZ0lmPVwiIXJlYWRvbmx5XCJcbiAgICAgICAgICAgIC8+XG4gICAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuICAgIDxkaXZcbiAgICAgICAgY2xhc3M9XCJ0ZXh0LWRhbmdlclwiXG4gICAgICAgICpuZ0lmPVwiaW5wdXRDb250cm9sLmVycm9ycyAmJiBpbnB1dENvbnRyb2wudG91Y2hlZFwiXG4gICAgPlxuICAgICAgICB7eyBpbnB1dENvbnRyb2wuZXJyb3JzW29iamVjdEZuLmtleXMoaW5wdXRDb250cm9sLmVycm9ycylbMF1dIH19XG4gICAgPC9kaXY+XG4gICAgPGRpdlxuICAgICAgICBjbGFzcz1cInRleHQtZGFuZ2VyXCJcbiAgICAgICAgKm5nSWY9XCJcbiAgICAgICAgICAgIGRpYWxDb2RlQ29udHJvbC5lcnJvcnMgJiZcbiAgICAgICAgICAgIGRpYWxDb2RlQ29udHJvbC50b3VjaGVkICYmXG4gICAgICAgICAgICAhaW5wdXRDb250cm9sLmVycm9yc1xuICAgICAgICBcIlxuICAgID5cbiAgICAgICAge3sgZGlhbENvZGVDb250cm9sLmVycm9yc1tvYmplY3RGbi5rZXlzKGRpYWxDb2RlQ29udHJvbC5lcnJvcnMpWzBdXSB9fVxuICAgIDwvZGl2PlxuPC9kaXY+XG4iXX0=