@crediblefinance/credible-ui
Version:
Credible's standard UI library
174 lines • 32.6 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;
theme = 'dark';
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", theme: "theme", 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 lightgrey;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 lightgrey;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
}], theme: [{
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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2YtbW9iaWxlLW51bWJlci5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9jcmVkaWJsZS11aS9zcmMvbGliL2NmLW1vYmlsZS1udW1iZXIvY2YtbW9iaWxlLW51bWJlci5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9jcmVkaWJsZS11aS9zcmMvbGliL2NmLW1vYmlsZS1udW1iZXIvY2YtbW9iaWxlLW51bWJlci5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0gsU0FBUyxFQUFFLFlBQVksRUFBRSxLQUFLLEVBQXFCLE1BQU0sRUFDNUQsTUFBTSxlQUFlLENBQUM7QUFFdkIsT0FBTyxFQUNILFdBQVcsRUFBRSxTQUFTLEVBQ3pCLE1BQU0sZ0JBQWdCLENBQUM7Ozs7OztBQVF4QixNQUFNLE9BQU8sdUJBQXVCO0lBQ3ZCLFlBQVksR0FBVyxFQUFFLENBQUM7SUFDMUIsT0FBTyxHQUFxQixFQUFFLENBQUM7SUFDL0IsUUFBUSxHQUFXLEVBQUUsQ0FBQztJQUN0QixTQUFTLEdBQVksSUFBSSxDQUFDO0lBQzFCLFFBQVEsR0FBWSxLQUFLLENBQUM7SUFDMUIsS0FBSyxHQUFXLEVBQUUsQ0FBQztJQUNuQixNQUFNLEdBQVcsRUFBRSxDQUFDO0lBQ3BCLFdBQVcsR0FBVyxFQUFFLENBQUM7SUFDekIsSUFBSSxDQUFVO0lBQ2QsRUFBRSxHQUFtQixJQUFJLENBQUM7SUFDMUIsUUFBUSxHQUFZLEtBQUssQ0FBQztJQUMxQixLQUFLLEdBQVcsTUFBTSxDQUFDO0lBRXRCLGVBQWUsR0FBRyxJQUFJLFlBQVksRUFBRSxDQUFDO0lBQ3JDLG1CQUFtQixHQUFHLElBQUksWUFBWSxFQUFFLENBQUM7SUFFMUMsU0FBUyxHQUFrQixJQUFJLENBQUM7SUFDaEMsU0FBUyxHQUFrQixJQUFJLENBQUM7SUFFekMsZUFBZSxHQUFjO1FBQ3pCLFdB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MUIsT0FBTyxJQUFJLENBQUM7UUFFaEIsT0FBTyxLQUFLLENBQUM7SUFDakIsQ0FBQzt1R0EzSlEsdUJBQXVCOzJGQUF2Qix1QkFBdUIsa2pCQ2RwQyxndkZBZ0ZBOzsyRkRsRWEsdUJBQXVCO2tCQUxuQyxTQUFTOytCQUNJLGtCQUFrQjt3REFLbkIsWUFBWTtzQkFBcEIsS0FBSztnQkFDRyxPQUFPO3NCQUFmLEtBQUs7Z0JBQ0csUUFBUTtzQkFBaEIsS0FBSztnQkFDRyxTQUFTO3NCQUFqQixLQUFLO2dCQUNHLFFBQVE7c0JBQWhCLEtBQUs7Z0JBQ0csS0FBSztzQkFBYixLQUFLO2dCQUNHLE1BQU07c0JBQWQsS0FBSztnQkFDRyxXQUFXO3NCQUFuQixLQUFLO2dCQUNHLElBQUk7c0JBQVosS0FBSztnQkFDRyxFQUFFO3NCQUFWLEtBQUs7Z0JBQ0csUUFBUTtzQkFBaEIsS0FBSztnQkFDRyxLQUFLO3NCQUFiLEtBQUs7Z0JBRUksZUFBZTtzQkFBeEIsTUFBTTtnQkFDRyxtQkFBbUI7c0JBQTVCLE1BQU07Z0JBRUUsU0FBUztzQkFBakIsS0FBSztnQkFDRyxTQUFTO3NCQUFqQixLQUFLO2dCQVlHLFNBQVM7c0JBQWpCLEtBQUs7Z0JBQ0csWUFBWTtzQkFBcEIsS0FBSztnQkFDRyxlQUFlO3NCQUF2QixLQUFLIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgICBDb21wb25lbnQsIEV2ZW50RW1pdHRlciwgSW5wdXQsIE9uQ2hhbmdlcywgT25Jbml0LCBPdXRwdXQsIFNpbXBsZUNoYW5nZXNcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBNYXRTZWxlY3RDaGFuZ2UgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9zZWxlY3QnO1xuaW1wb3J0IHtcbiAgICBGb3JtQ29udHJvbCwgRm9ybUdyb3VwXG59IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCBJRGlhbENvZGUgZnJvbSAnLi4vaW50ZXJmYWNlcy9JRGlhbENvZGUnO1xuXG5AQ29tcG9uZW50KHtcbiAgICBzZWxlY3RvcjogJ2NmLW1vYmlsZS1udW1iZXInLFxuICAgIHRlbXBsYXRlVXJsOiAnLi9jZi1tb2JpbGUtbnVtYmVyLmNvbXBvbmVudC5odG1sJyxcbiAgICBzdHlsZVVybHM6IFsnLi9jZi1tb2JpbGUtbnVtYmVyLmNvbXBvbmVudC5zY3NzJ11cbn0pXG5leHBvcnQgY2xhc3MgQ2ZNb2JpbGVOdW1iZXJDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIE9uQ2hhbmdlcyB7XG4gICAgQElucHV0KCkgbW9iaWxlTnVtYmVyOiBzdHJpbmcgPSAnJztcbiAgICBASW5wdXQoKSBvcHRpb25zOiBBcnJheTxJRGlhbENvZGU+ID0gW107XG4gICAgQElucHV0KCkgc2VsZWN0ZWQ6IHN0cmluZyA9ICcnO1xuICAgIEBJbnB1dCgpIHNob3dMYWJlbDogYm9vbGVhbiA9IHRydWU7XG4gICAgQElucHV0KCkgcmVhZG9ubHk6IGJvb2xlYW4gPSBmYWxzZTtcbiAgICBASW5wdXQoKSBsYWJlbDogc3RyaW5nID0gJyc7XG4gICAgQElucHV0KCkgbGVuZ3RoOiBudW1iZXIgPSAxMDtcbiAgICBASW5wdXQoKSBwbGFjZWhvbGRlcjogc3RyaW5nID0gJyc7XG4gICAgQElucHV0KCkgbmFtZT86IHN0cmluZztcbiAgICBASW5wdXQoKSBpZD86IHN0cmluZyB8IG51bGwgPSBudWxsO1xuICAgIEBJbnB1dCgpIGRpc2FibGVkOiBib29sZWFuID0gZmFsc2U7XG4gICAgQElucHV0KCkgdGhlbWU6IHN0cmluZyA9ICdkYXJrJztcblxuICAgIEBPdXRwdXQoKSBkaWFsQ29kZUNoYW5nZWQgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG4gICAgQE91dHB1dCgpIG1vYmlsZU51bWJlckNoYW5nZWQgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG5cbiAgICBASW5wdXQoKSBtYXhMZW5ndGg6IG51bWJlciB8IG51bGwgPSBudWxsO1xuICAgIEBJbnB1dCgpIG1pbkxlbmd0aDogbnVtYmVyIHwgbnVsbCA9IG51bGw7XG5cbiAgICBjdXJyZW50U2VsZWN0ZWQ6IElEaWFsQ29kZSA9IHtcbiAgICAgICAgY291bnRyeUNvZGU6ICcnLFxuICAgICAgICBjb3VudHJ5TmFtZTogJycsXG4gICAgICAgIGRpYWxDb2RlOiAnJyxcbiAgICAgICAgZmxhZ1VybDogJycsXG4gICAgICAgIG1vYmlsZU51bWJlckxlbmd0aDogMTBcbiAgICB9O1xuXG4gICAgYWxsb3dlZEtleXM6IFNldDxzdHJpbmc+ID0gbmV3IFNldCgpO1xuXG4gICAgQElucHV0KCkgZm9ybUdyb3VwITogRm9ybUdyb3VwO1xuICAgIEBJbnB1dCgpIGlucHV0Q29udHJvbCE6IEZvcm1Db250cm9sO1xuICAgIEBJbnB1dCgpIGRpYWxDb2RlQ29udHJvbCE6IEZvcm1Db250cm9sO1xuXG4gICAgLy8gSFRNTCBoZWxwZXJzXG4gICAgb2JqZWN0Rm4gPSBPYmplY3Q7XG5cbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgaWYgKCF0aGlzLmlucHV0Q29udHJvbCAmJiAhdGhpcy5mb3JtR3JvdXAgJiYgIXRoaXMuZGlhbENvZGVDb250cm9sKSB7XG4gICAgICAgICAgICB0aGlzLmZvcm1Hcm91cCA9IG5ldyBGb3JtR3JvdXAoe30pO1xuICAgICAgICAgICAgdGhpcy5pbnB1dENvbnRyb2wgPSBuZXcgRm9ybUNvbnRyb2woJycpO1xuICAgICAgICAgICAgdGhpcy5kaWFsQ29kZUNvbnRyb2wgPSBuZXcgRm9ybUNvbnRyb2woJycpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IGFsbG93ZWRLZXlzID0gW1xuICAgICAgICAgICAgJ0JhY2tzcGFjZScsIC8vIGJhY2tzcGFjZVxuICAgICAgICAgICAgJ0RpZ2l0MCcsIC8vIHplcm9cbiAgICAgICAgICAgICdEaWdpdDEnLCAvLyBvbmVcbiAgICAgICAgICAgICdEaWdpdDInLCAvLyB0d29cbiAgICAgICAgICAgICdEaWdpdDMnLCAvLyB0aHJlZVxuICAgICAgICAgICAgJ0RpZ2l0NCcsIC8vIGZvdXJcbiAgICAgICAgICAgICdEaWdpdDUnLCAvLyBmaXZlXG4gICAgICAgICAgICAnRGlnaXQ2JywgLy8gc2l4XG4gICAgICAgICAgICAnRGlnaXQ3JywgLy8gc2V2ZW5cbiAgICAgICAgICAgICdEaWdpdDgnLCAvLyBlaWdodFxuICAgICAgICAgICAgJ0RpZ2l0OScsIC8vIG5pbmUsXG4gICAgICAgICAgICAnQXJyb3dSaWdodCcsXG4gICAgICAgICAgICAnQXJyb3dMZWZ0JyxcbiAgICAgICAgICAgICdBcnJvd1VwJyxcbiAgICAgICAgICAgICdBcnJvd0Rvd24nXG4gICAgICAgIF07XG5cbiAgICAgICAgdGhpcy5hbGxvd2VkS2V5cyA9IG5ldyBTZXQoYWxsb3dlZEtleXMpO1xuICAgIH1cblxuICAgIHZhbGlkT3B0aW9uKHZhbHVlOiBzdHJpbmcpIHtcbiAgICAgICAgaWYgKHZhbHVlID09PSAnJylcbiAgICAgICAgICAgIHJldHVybiAtMTtcblxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMub3B0aW9ucy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgaWYgKHRoaXMub3B0aW9uc1tpXS5kaWFsQ29kZSA9PT0gdmFsdWUpXG4gICAgICAgICAgICAgICAgcmV0dXJuIGk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gLTE7XG4gICAgfVxuXG4gICAgY2hhbmdlRHJvcGRvd24obWF0U2VsZWN0Q2hhbmdlOiBNYXRTZWxlY3RDaGFuZ2UpIHtcbiAgICAgICAgdGhpcy5jdXJyZW50U2VsZWN0ZWQgPSBtYXRTZWxlY3RDaGFuZ2UudmFsdWU7XG5cbiAgICAgICAgdGhpcy5kaWFsQ29kZUNoYW5nZWQuZW1pdCh0aGlzLmN1cnJlbnRTZWxlY3RlZCk7XG4gICAgfVxuXG4gICAgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcyk6IHZvaWQge1xuICAgICAgICBpZiAoY2hhbmdlcy5tb2JpbGVOdW1iZXIpIHtcbiAgICAgICAgICAgIHRoaXMubW9iaWxlTnVtYmVyID0gY2hhbmdlcy5tb2JpbGVOdW1iZXIuY3VycmVudFZhbHVlO1xuICAgICAgICAgICAgdGhpcy5pbnB1dENvbnRyb2wuc2V0VmFsdWUodGhpcy5tb2JpbGVOdW1iZXIpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGNoYW5nZXMuc2VsZWN0ZWQgJiYgY2hhbmdlcy5zZWxlY3RlZC5jdXJyZW50VmFsdWUpXG4gICAgICAgICAgICB0aGlzLnNldFNlbGVjdGVkVmFsdWUoKTtcblxuICAgICAgICBpZiAoY2hhbmdlcy5vcHRpb25zICYmIGNoYW5nZXMub3B0aW9ucy5jdXJyZW50VmFsdWUpXG4gICAgICAgICAgICB0aGlzLnNldFNlbGVjdGVkVmFsdWUoKTtcbiAgICB9XG5cbiAgICBzZXRTZWxlY3RlZFZhbHVlKCkge1xuICAgICAgICBpZiAodGhpcy5zZWxlY3RlZCA9PT0gJycpXG4gICAgICAgICAgICByZXR1cm47XG5cbiAgICAgICAgaWYgKCF0aGlzLm9wdGlvbnMpXG4gICAgICAgICAgICByZXR1cm47XG5cbiAgICAgICAgaWYgKHRoaXMub3B0aW9ucy5sZW5ndGggPT09IDApXG4gICAgICAgICAgICByZXR1cm47XG5cbiAgICAgICAgY29uc3QgaW5kZXggPSB0aGlzLnZhbGlkT3B0aW9uKHRoaXMuc2VsZWN0ZWQpO1xuXG4gICAgICAgIGlmIChpbmRleCA9PT0gLTEpXG4gICAgICAgICAgICB0aGlzLmN1cnJlbnRTZWxlY3RlZCA9IHRoaXMub3B0aW9uc1swXTtcblxuICAgICAgICBlbHNlXG4gICAgICAgICAgICB0aGlzLmN1cnJlbnRTZWxlY3RlZCA9IHRoaXMub3B0aW9uc1tpbmRleF07XG5cbiAgICAgICAgdGhpcy5kaWFsQ29kZUNvbnRyb2wuc2V0VmFsdWUodGhpcy5jdXJyZW50U2VsZWN0ZWQpO1xuICAgIH1cblxuICAgIHZhbHVlQ2hhbmdlZEhhbmRsZXIoJGV2ZW50OiBhbnkpIHtcbiAgICAgICAgdGhpcy5tb2JpbGVOdW1iZXJDaGFuZ2VkLmVtaXQoJGV2ZW50LnRhcmdldC52YWx1ZSk7XG4gICAgfVxuXG4gICAga2V5ZG93bihldmVudDogS2V5Ym9hcmRFdmVudCkge1xuICAgICAgICBjb25zdCBhbGxvd2VkID0gdGhpcy5hbGxvd2VkS2V5cy5oYXMoZXZlbnQuY29kZSk7XG5cbiAgICAgICAgaWYgKCFhbGxvd2VkKVxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuXG4gICAgICAgIGlmICghdGhpcy5vcHRpb25hbEtleXMoZXZlbnQpKSB7XG4gICAgICAgICAgICAvLyBlcXVhbGl0eSBpcyBuZWVkZWQgdG8gYXZvaWQgdGhlIGVkZ2UgY29uZGl0aW9uXG4gICAgICAgICAgICBpZiAodGhpcy5tb2JpbGVOdW1iZXIubGVuZ3RoID49IHRoaXMubGVuZ3RoKVxuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIG9wdGlvbmFsS2V5cyhldmVudDogS2V5Ym9hcmRFdmVudCkge1xuICAgICAgICBpZiAoZXZlbnQuY29kZSA9PT0gJ0JhY2tzcGFjZScpXG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcblxuICAgICAgICBpZiAoZXZlbnQuY29kZSA9PT0gJ0Fycm93TGVmdCcpXG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcblxuICAgICAgICBpZiAoZXZlbnQuY29kZSA9PT0gJ0Fycm93UmlnaHQnKVxuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG5cbiAgICAgICAgaWYgKGV2ZW50LmNvZGUgPT09ICdBcnJvd1VwJylcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuXG4gICAgICAgIGlmIChldmVudC5jb2RlID09PSAnQXJyb3dEb3duJylcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuXG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG59XG4iLCI8ZGl2IGNsYXNzPVwiY2YtbW9iaWxlLW51bWJlclwiPlxuICAgIDxkaXY+XG4gICAgICAgIDxsYWJlbCBjbGFzcz1cImxhYmVsXCI+e3sgbGFiZWwgfX08L2xhYmVsPlxuICAgIDwvZGl2PlxuXG4gICAgPGRpdlxuICAgICAgICBbY2xhc3MuZXJyb3JdPVwiXG4gICAgICAgICAgICAoaW5wdXRDb250cm9sLmludmFsaWQgJiYgaW5wdXRDb250cm9sLnRvdWNoZWQpIHx8XG4gICAgICAgICAgICAoZGlhbENvZGVDb250cm9sLmludmFsaWQgJiYgZGlhbENvZGVDb250cm9sLnRvdWNoZWQpXG4gICAgICAgIFwiXG4gICAgICAgIGNsYXNzPVwiaG9sZGVyXCJcbiAgICAgICAgW2Zvcm1Hcm91cF09XCJmb3JtR3JvdXBcIlxuICAgID5cbiAgICAgICAgPGRpdiBjbGFzcz1cImRyb3Bkb3duLWhvbGRlclwiPlxuICAgICAgICAgICAgPG1hdC1zZWxlY3RcbiAgICAgICAgICAgICAgICBtYXROYXRpdmVDb250cm9sXG4gICAgICAgICAgICAgICAgW2Zvcm1Db250cm9sXT1cImRpYWxDb2RlQ29udHJvbFwiXG4gICAgICAgICAgICAgICAgKHNlbGVjdGlvbkNoYW5nZSk9XCJjaGFuZ2VEcm9wZG93bigkZXZlbnQpXCJcbiAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICA8bWF0LXNlbGVjdC10cmlnZ2VyPlxuICAgICAgICAgICAgICAgICAgICA8aW1nXG4gICAgICAgICAgICAgICAgICAgICAgICBbc3JjXT1cImN1cnJlbnRTZWxlY3RlZC5mbGFnVXJsXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFthbHRdPVwiY3VycmVudFNlbGVjdGVkLmNvdW50cnlOYW1lXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIHdpZHRoPVwiMzBcIlxuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU9XCJtYXJnaW4tcmlnaHQ6IDAuM3JlbVwiXG4gICAgICAgICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICAgICAgPC9tYXQtc2VsZWN0LXRyaWdnZXI+XG4gICAgICAgICAgICAgICAgPG1hdC1vcHRpb25cbiAgICAgICAgICAgICAgICAgICAgW3ZhbHVlXT1cIml0ZW1cIlxuICAgICAgICAgICAgICAgICAgICAqbmdGb3I9XCJsZXQgaXRlbSBvZiBvcHRpb25zXCJcbiAgICAgICAgICAgICAgICAgICAgW2Rpc2FibGVkXT1cImRpc2FibGVkXCJcbiAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgIDxpbWdcbiAgICAgICAgICAgICAgICAgICAgICAgIFtzcmNdPVwiaXRlbS5mbGFnVXJsXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFthbHRdPVwiaXRlbS5jb3VudHJ5TmFtZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICB3aWR0aD1cIjI1XCJcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlPVwibWFyZ2luLXJpZ2h0OiAwLjVyZW1cIlxuICAgICAgICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgICAgICAgICB7eyBpdGVtLmNvdW50cnlOYW1lIH19XG4gICAgICAgICAgICAgICAgICAgIDxzcGFuIHN0eWxlPVwiY29sb3I6IGdyZXlcIj4oe3sgaXRlbS5kaWFsQ29kZSB9fSk8L3NwYW4+XG4gICAgICAgICAgICAgICAgPC9tYXQtb3B0aW9uPlxuICAgICAgICAgICAgPC9tYXQtc2VsZWN0PlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImlzZC1jb2RlLWhvbGRlclwiICpuZ0lmPVwiY3VycmVudFNlbGVjdGVkXCI+XG4gICAgICAgICAgICA8c3Bhbj4ge3sgY3VycmVudFNlbGVjdGVkLmRpYWxDb2RlIH19IDwvc3Bhbj5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJpbnB1dC1ob2xkZXJcIj5cbiAgICAgICAgICAgIDxzcGFuICpuZ0lmPVwicmVhZG9ubHlcIj4ge3sgbW9iaWxlTnVtYmVyIH19IDwvc3Bhbj5cbiAgICAgICAgICAgIDxpbnB1dFxuICAgICAgICAgICAgICAgIHR5cGU9XCJudW1iZXJcIlxuICAgICAgICAgICAgICAgIGNsYXNzPVwidmFsdWUtc3BhblwiXG4gICAgICAgICAgICAgICAgW25hbWVdPVwibmFtZVwiXG4gICAgICAgICAgICAgICAgW2lkXT1cImlkXCJcbiAgICAgICAgICAgICAgICBbdmFsdWVdPVwibW9iaWxlTnVtYmVyXCJcbiAgICAgICAgICAgICAgICBbcGxhY2Vob2xkZXJdPVwicGxhY2Vob2xkZXJcIlxuICAgICAgICAgICAgICAgIFtmb3JtQ29udHJvbF09XCJpbnB1dENvbnRyb2xcIlxuICAgICAgICAgICAgICAgIFttaW5MZW5ndGhdPVwibWluTGVuZ3RoXCJcbiAgICAgICAgICAgICAgICBbbWF4bGVuZ3RoXT1cIm1heExlbmd0aFwiXG4gICAgICAgICAgICAgICAgKGtleXVwKT1cInZhbHVlQ2hhbmdlZEhhbmRsZXIoJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgKm5nSWY9XCIhcmVhZG9ubHlcIlxuICAgICAgICAgICAgLz5cbiAgICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG4gICAgPGRpdlxuICAgICAgICBjbGFzcz1cInRleHQtZGFuZ2VyXCJcbiAgICAgICAgKm5nSWY9XCJpbnB1dENvbnRyb2wuZXJyb3JzICYmIGlucHV0Q29udHJvbC50b3VjaGVkXCJcbiAgICA+XG4gICAgICAgIHt7IGlucHV0Q29udHJvbC5lcnJvcnNbb2JqZWN0Rm4ua2V5cyhpbnB1dENvbnRyb2wuZXJyb3JzKVswXV0gfX1cbiAgICA8L2Rpdj5cbiAgICA8ZGl2XG4gICAgICAgIGNsYXNzPVwidGV4dC1kYW5nZXJcIlxuICAgICAgICAqbmdJZj1cIlxuICAgICAgICAgICAgZGlhbENvZGVDb250cm9sLmVycm9ycyAmJlxuICAgICAgICAgICAgZGlhbENvZGVDb250cm9sLnRvdWNoZWQgJiZcbiAgICAgICAgICAgICFpbnB1dENvbnRyb2wuZXJyb3JzXG4gICAgICAgIFwiXG4gICAgPlxuICAgICAgICB7eyBkaWFsQ29kZUNvbnRyb2wuZXJyb3JzW29iamVjdEZuLmtleXMoZGlhbENvZGVDb250cm9sLmVycm9ycylbMF1dIH19XG4gICAgPC9kaXY+XG48L2Rpdj5cbiJdfQ==