truly-ui
Version:
Web Components for Desktop Applications.
164 lines (162 loc) • 24.7 kB
JavaScript
/*
MIT License
Copyright (c) 2019 Temainfo Software
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
import { Component, ContentChildren, Input, ViewChild, Output, EventEmitter, Optional, Self, } from '@angular/core';
import { TlRadioButton } from './radiobutton';
import { KeyEvent } from '../core/enums/key-events';
import { ValueAccessorBase } from '../input/core/value-accessor';
import { Subscription } from 'rxjs';
import * as i0 from "@angular/core";
import * as i1 from "@angular/forms";
import * as i2 from "@angular/common";
const Orientation = {
VERTICAL: 'vertical',
HORIZONTAL: 'horizontal'
};
export class TlRadioGroup extends ValueAccessorBase {
constructor(ngControl) {
super();
this.ngControl = ngControl;
this.labelGroup = '';
this.orientation = Orientation.HORIZONTAL;
this.colorSelected = '';
this.onCheckRadio = new EventEmitter();
this.onFocusRadio = new EventEmitter();
this.subscription = new Subscription();
this.setControl();
}
get control() {
return this.ngControl?.control;
}
setControl() {
if (this.ngControl) {
this.ngControl.valueAccessor = this;
}
}
ngAfterContentInit() {
this.handleInitialValue();
this.validateProperty();
this.validateCheckedRadios();
this.listenModelChange();
}
listenModelChange() {
if (this.control) {
this.subscription.add(this.control.valueChanges.subscribe((value) => {
this.handleModelValue();
}));
}
}
validateProperty() {
if ((this.orientation !== Orientation.VERTICAL) && (this.orientation !== Orientation.HORIZONTAL)) {
throw new EvalError('The property [orientation] only receive /vertical/ and /horizontal/ values!');
}
}
handleInitialValue() {
if (this.value) {
this.handleModelValue();
}
else {
this.checkFirstItem();
this.handleChecked();
}
}
handleModelValue() {
this.listRadioButton.toArray().forEach((item, index, array) => {
if (this.value === item.value) {
this.itemSelected = item;
}
});
}
handleChecked() {
this.listRadioButton.toArray().forEach((item) => {
this.setItemChecked(item);
});
}
handleKeyDown($event) {
switch ($event.code) {
case KeyEvent.ARROWDOWN:
$event.preventDefault();
break;
case KeyEvent.ARROWUP:
$event.preventDefault();
break;
}
}
setItemChecked(item) {
if (item.checked) {
return this.checkRadio(item);
}
}
checkFirstItem() {
setTimeout(() => {
this.checkRadio(this.listRadioButton.toArray()[0]);
}, 1);
}
getCheckedRadios() {
return this.listRadioButton.filter((item) => {
return item.checked;
});
}
validateCheckedRadios() {
if (this.getCheckedRadios().length > 1) {
throw new EvalError('Only one radiobutton with [checked] property is allowed');
}
}
checkRadio(item, $event) {
if ($event && item.disabled) {
return;
}
this.value = item.value;
this.itemSelected = item;
this.onCheckRadio.emit(this.itemSelected);
}
focusRadio(item) {
this.onFocusRadio.emit(item);
}
ngOnDestroy() {
this.subscription.unsubscribe();
}
}
/** @nocollapse */ TlRadioGroup.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: TlRadioGroup, deps: [{ token: i1.NgControl, optional: true, self: true }], target: i0.ɵɵFactoryTarget.Component });
/** @nocollapse */ TlRadioGroup.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: TlRadioGroup, selector: "tl-radio-group", inputs: { labelGroup: "labelGroup", orientation: "orientation", colorSelected: "colorSelected" }, outputs: { onCheckRadio: "onCheckRadio", onFocusRadio: "onFocusRadio" }, queries: [{ propertyName: "listRadioButton", predicate: TlRadioButton }], viewQueries: [{ propertyName: "radiobutton", first: true, predicate: ["radiobutton"], descendants: true, static: true }], usesInheritance: true, ngImport: i0, template: "<ng-content></ng-content>\n<div class=\"group-radios\" [style.display]=\"orientation == 'vertical' ? 'grid' : 'inline-flex'\">\n <div *ngFor=\"let item of listRadioButton.toArray()\" class=\"radio-container\" [style.padding-top]=\"orientation === 'vertical' ? '10px' : '0'\">\n <input #radiobutton\n [type]=\"'radio'\"\n [attr.name]=\"name\"\n (click)=\"checkRadio(item, $event)\"\n [tabindex]=\"tabindex\"\n [attr.disabled]=\"item.disabled\"\n [value]=\"item.value\"\n (keydown)=\"handleKeyDown($event)\"\n (focus)=\"focusRadio(item)\"\n [(ngModel)]=\"value\">\n <span class=\"radio-ring\" [ngClass]=\"{'disabled': item.disabled }\"></span>\n <span\n [style.top]=\"orientation == 'vertical' ? '13px' : '3px'\"\n *ngIf=\"itemSelected === item\"\n [style.background-color]=\"colorSelected\" class=\"radio-selected\" [ngClass]=\"{'disabled': item.disabled}\"></span>\n <label (click)=\"checkRadio(item, $event)\" class=\"-label\">{{item.label}}</label>\n </div>\n</div>\n", styles: [".radio-container{display:inline-block;position:relative;height:auto;padding-right:10px}.radio-ring{width:16px;height:16px;position:absolute;border-radius:16px}input[type=radio]{width:16px;height:16px;position:absolute;margin:0!important}input[type=radio]:before{left:0}input[type=radio]:after{width:18px;height:18px;border-radius:18px;top:-1px;left:-1px;position:absolute;content:\"\";display:inline-block;visibility:visible;transition:background .15s ease-in-out}input[type=radio]:hover{cursor:pointer}.-label{font-family:Segoe UI,Lato,\"sans-serif\",Arial;font-size:.9em!important;font-weight:400!important;position:relative;padding-left:22px;margin:0!important}.-label:hover{cursor:pointer}.radio-selected{width:10px;height:10px;border-radius:10px;z-index:0;position:absolute;font-size:10px;left:3px}\n"], dependencies: [{ kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.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: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }] });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: TlRadioGroup, decorators: [{
type: Component,
args: [{ selector: 'tl-radio-group', template: "<ng-content></ng-content>\n<div class=\"group-radios\" [style.display]=\"orientation == 'vertical' ? 'grid' : 'inline-flex'\">\n <div *ngFor=\"let item of listRadioButton.toArray()\" class=\"radio-container\" [style.padding-top]=\"orientation === 'vertical' ? '10px' : '0'\">\n <input #radiobutton\n [type]=\"'radio'\"\n [attr.name]=\"name\"\n (click)=\"checkRadio(item, $event)\"\n [tabindex]=\"tabindex\"\n [attr.disabled]=\"item.disabled\"\n [value]=\"item.value\"\n (keydown)=\"handleKeyDown($event)\"\n (focus)=\"focusRadio(item)\"\n [(ngModel)]=\"value\">\n <span class=\"radio-ring\" [ngClass]=\"{'disabled': item.disabled }\"></span>\n <span\n [style.top]=\"orientation == 'vertical' ? '13px' : '3px'\"\n *ngIf=\"itemSelected === item\"\n [style.background-color]=\"colorSelected\" class=\"radio-selected\" [ngClass]=\"{'disabled': item.disabled}\"></span>\n <label (click)=\"checkRadio(item, $event)\" class=\"-label\">{{item.label}}</label>\n </div>\n</div>\n", styles: [".radio-container{display:inline-block;position:relative;height:auto;padding-right:10px}.radio-ring{width:16px;height:16px;position:absolute;border-radius:16px}input[type=radio]{width:16px;height:16px;position:absolute;margin:0!important}input[type=radio]:before{left:0}input[type=radio]:after{width:18px;height:18px;border-radius:18px;top:-1px;left:-1px;position:absolute;content:\"\";display:inline-block;visibility:visible;transition:background .15s ease-in-out}input[type=radio]:hover{cursor:pointer}.-label{font-family:Segoe UI,Lato,\"sans-serif\",Arial;font-size:.9em!important;font-weight:400!important;position:relative;padding-left:22px;margin:0!important}.-label:hover{cursor:pointer}.radio-selected{width:10px;height:10px;border-radius:10px;z-index:0;position:absolute;font-size:10px;left:3px}\n"] }]
}], ctorParameters: function () { return [{ type: i1.NgControl, decorators: [{
type: Optional
}, {
type: Self
}] }]; }, propDecorators: { labelGroup: [{
type: Input
}], orientation: [{
type: Input
}], colorSelected: [{
type: Input
}], radiobutton: [{
type: ViewChild,
args: ['radiobutton', { static: true }]
}], listRadioButton: [{
type: ContentChildren,
args: [TlRadioButton]
}], onCheckRadio: [{
type: Output
}], onFocusRadio: [{
type: Output
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmFkaW9ncm91cC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL3RydWx5LXVpL3NyYy9jb21wb25lbnRzL3JhZGlvYnV0dG9uL3JhZGlvZ3JvdXAudHMiLCIuLi8uLi8uLi8uLi9wcm9qZWN0cy90cnVseS11aS9zcmMvY29tcG9uZW50cy9yYWRpb2J1dHRvbi9yYWRpb2dyb3VwLmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBb0JHO0FBQ0gsT0FBTyxFQUNMLFNBQVMsRUFBZ0IsZUFBZSxFQUFhLEtBQUssRUFBRSxTQUFTLEVBQWlCLE1BQU0sRUFDNUYsWUFBWSxFQUFhLFFBQVEsRUFBRSxJQUFJLEdBQ3hDLE1BQU0sZUFBZSxDQUFDO0FBRXZCLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFFOUMsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBRXBELE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLDhCQUE4QixDQUFDO0FBRWpFLE9BQU8sRUFBQyxZQUFZLEVBQUMsTUFBTSxNQUFNLENBQUM7Ozs7QUFFbEMsTUFBTSxXQUFXLEdBQUc7SUFDbEIsUUFBUSxFQUFFLFVBQVU7SUFDcEIsVUFBVSxFQUFFLFlBQVk7Q0FDekIsQ0FBQztBQU9GLE1BQU0sT0FBTyxZQUFhLFNBQVEsaUJBQXlCO0lBd0J6RCxZQUF1QyxTQUFvQjtRQUN6RCxLQUFLLEVBQUUsQ0FBQztRQUQ2QixjQUFTLEdBQVQsU0FBUyxDQUFXO1FBdEJsRCxlQUFVLEdBQUcsRUFBRSxDQUFDO1FBRWhCLGdCQUFXLEdBQUcsV0FBVyxDQUFDLFVBQVUsQ0FBQztRQUVyQyxrQkFBYSxHQUFHLEVBQUUsQ0FBQztRQU1WLGlCQUFZLEdBQXNCLElBQUksWUFBWSxFQUFFLENBQUM7UUFFckQsaUJBQVksR0FBc0IsSUFBSSxZQUFZLEVBQUUsQ0FBQztRQVEvRCxpQkFB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RVAsZUFBZTtzQkFBaEQsZUFBZTt1QkFBRSxhQUFhO2dCQUViLFlBQVk7c0JBQTdCLE1BQU07Z0JBRVcsWUFBWTtzQkFBN0IsTUFBTSIsInNvdXJjZXNDb250ZW50IjpbIi8qXG4gTUlUIExpY2Vuc2VcblxuIENvcHlyaWdodCAoYykgMjAxOSBUZW1haW5mbyBTb2Z0d2FyZVxuXG4gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGEgY29weVxuIG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlIFwiU29mdHdhcmVcIiksIHRvIGRlYWxcbiBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzXG4gdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLCBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbFxuIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpc1xuIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4gVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWQgaW4gYWxsXG4gY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbiBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTIE9SXG4gSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksXG4gRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFXG4gQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSwgREFNQUdFUyBPUiBPVEhFUlxuIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HIEZST00sXG4gT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEVcbiBTT0ZUV0FSRS5cbiAqL1xuaW1wb3J0IHtcbiAgQ29tcG9uZW50LCBDb250ZW50Q2hpbGQsIENvbnRlbnRDaGlsZHJlbiwgUXVlcnlMaXN0LCBJbnB1dCwgVmlld0NoaWxkLCBBZnRlclZpZXdJbml0LCBPdXRwdXQsXG4gIEV2ZW50RW1pdHRlciwgT25DaGFuZ2VzLCBPcHRpb25hbCwgU2VsZiwgQWZ0ZXJDb250ZW50SW5pdCwgT25EZXN0cm95LFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuaW1wb3J0IHsgVGxSYWRpb0J1dHRvbiB9IGZyb20gJy4vcmFkaW9idXR0b24nO1xuaW1wb3J0IHsgTWFrZVByb3ZpZGVyIH0gZnJvbSAnLi4vY29yZS9iYXNlL3ZhbHVlLWFjY2Vzc29yLXByb3ZpZGVyJztcbmltcG9ydCB7IEtleUV2ZW50IH0gZnJvbSAnLi4vY29yZS9lbnVtcy9rZXktZXZlbnRzJztcbmltcG9ydCB7Rm9ybUNvbnRyb2xOYW1lLCBOR19BU1lOQ19WQUxJREFUT1JTLCBOR19WQUxJREFUT1JTLCBOZ0NvbnRyb2wsIE5nTW9kZWx9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCB7IFZhbHVlQWNjZXNzb3JCYXNlIH0gZnJvbSAnLi4vaW5wdXQvY29yZS92YWx1ZS1hY2Nlc3Nvcic7XG5pbXBvcnQge0ZpeGVkUG9zaXRpb25EaXJlY3RpdmV9IGZyb20gJy4uL21pc2MvZml4ZWQtcG9zaXRpb24uZGlyZWN0aXZlJztcbmltcG9ydCB7U3Vic2NyaXB0aW9ufSBmcm9tICdyeGpzJztcblxuY29uc3QgT3JpZW50YXRpb24gPSB7XG4gIFZFUlRJQ0FMOiAndmVydGljYWwnLFxuICBIT1JJWk9OVEFMOiAnaG9yaXpvbnRhbCdcbn07XG5cbkBDb21wb25lbnQoIHtcbiAgc2VsZWN0b3I6ICd0bC1yYWRpby1ncm91cCcsXG4gIHRlbXBsYXRlVXJsOiAnLi9yYWRpb2dyb3VwLmh0bWwnLFxuICBzdHlsZVVybHM6IFsgJy4vcmFkaW9idXR0b24uc2NzcycgXVxufSApXG5leHBvcnQgY2xhc3MgVGxSYWRpb0dyb3VwIGV4dGVuZHMgVmFsdWVBY2Nlc3NvckJhc2U8c3RyaW5nPiBpbXBsZW1lbnRzIEFmdGVyQ29udGVudEluaXQsIE9uRGVzdHJveSB7XG5cbiAgQElucHV0KCkgbGFiZWxHcm91cCA9ICcnO1xuXG4gIEBJbnB1dCgpIG9yaWVudGF0aW9uID0gT3JpZW50YXRpb24uSE9SSVpPTlRBTDtcblxuICBASW5wdXQoKSBjb2xvclNlbGVjdGVkID0gJyc7XG5cbiAgQFZpZXdDaGlsZCggJ3JhZGlvYnV0dG9uJywge3N0YXRpYzogdHJ1ZX0gKSByYWRpb2J1dHRvbjtcblxuICBAQ29udGVudENoaWxkcmVuKCBUbFJhZGlvQnV0dG9uICkgbGlzdFJhZGlvQnV0dG9uOiBRdWVyeUxpc3Q8VGxSYWRpb0J1dHRvbj47XG5cbiAgQE91dHB1dCgpIHByaXZhdGUgb25DaGVja1JhZGlvOiBFdmVudEVtaXR0ZXI8YW55PiA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcblxuICBAT3V0cHV0KCkgcHJpdmF0ZSBvbkZvY3VzUmFkaW86IEV2ZW50RW1pdHRlcjxhbnk+ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuXG4gIHB1YmxpYyBpdGVtU2VsZWN0ZWQ7XG5cbiAgcHVibGljIG5hbWU7XG5cbiAgcHVibGljIHRhYmluZGV4O1xuXG4gIHByaXZhdGUgc3Vic2NyaXB0aW9uID0gbmV3IFN1YnNjcmlwdGlvbigpO1xuXG4gIGNvbnN0cnVjdG9yKEBPcHRpb25hbCgpIEBTZWxmKCkgcHVibGljIG5nQ29udHJvbDogTmdDb250cm9sKSB7XG4gICAgc3VwZXIoKTtcbiAgICB0aGlzLnNldENvbnRyb2woKTtcbiAgfVxuXG4gIGdldCBjb250cm9sKCkge1xuICAgIHJldHVybiB0aGlzLm5nQ29udHJvbD8uY29udHJvbDtcbiAgfVxuXG4gIHNldENvbnRyb2woKSB7XG4gICAgaWYgKCB0aGlzLm5nQ29udHJvbCApIHtcbiAgICAgIHRoaXMubmdDb250cm9sLnZhbHVlQWNjZXNzb3IgPSB0aGlzO1xuICAgIH1cbiAgfVxuXG4gIG5nQWZ0ZXJDb250ZW50SW5pdCgpIHtcbiAgICB0aGlzLmhhbmRsZUluaXRpYWxWYWx1ZSgpO1xuICAgIHRoaXMudmFsaWRhdGVQcm9wZXJ0eSgpO1xuICAgIHRoaXMudmFsaWRhdGVDaGVja2VkUmFkaW9zKCk7XG4gICAgdGhpcy5saXN0ZW5Nb2RlbENoYW5nZSgpO1xuICB9XG5cbiAgbGlzdGVuTW9kZWxDaGFuZ2UoKSB7XG4gICAgaWYgKCB0aGlzLmNvbnRyb2wgKSB7XG4gICAgICB0aGlzLnN1YnNjcmlwdGlvbi5hZGQodGhpcy5jb250cm9sLnZhbHVlQ2hhbmdlcy5zdWJzY3JpYmUoKHZhbHVlKSA9PiB7XG4gICAgICAgIHRoaXMuaGFuZGxlTW9kZWxWYWx1ZSgpO1xuICAgICAgfSkpO1xuICAgIH1cbiAgfVxuXG4gIHZhbGlkYXRlUHJvcGVydHkoKSB7XG4gICAgaWYgKCAodGhpcy5vcmllbnRhdGlvbiAhPT0gT3JpZW50YXRpb24uVkVSVElDQUwpICYmICh0aGlzLm9yaWVudGF0aW9uICE9PSBPcmllbnRhdGlvbi5IT1JJWk9OVEFMKSApIHtcbiAgICAgIHRocm93IG5ldyBFdmFsRXJyb3IoICdUaGUgcHJvcGVydHkgW29yaWVudGF0aW9uXSBvbmx5IHJlY2VpdmUgL3ZlcnRpY2FsLyBhbmQgL2hvcml6b250YWwvIHZhbHVlcyEnICk7XG4gICAgfVxuICB9XG5cbiAgaGFuZGxlSW5pdGlhbFZhbHVlKCkge1xuICAgIGlmICggdGhpcy52YWx1ZSApIHtcbiAgICAgIHRoaXMuaGFuZGxlTW9kZWxWYWx1ZSgpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmNoZWNrRmlyc3RJdGVtKCk7XG4gICAgICB0aGlzLmhhbmRsZUNoZWNrZWQoKTtcbiAgICB9XG4gIH1cblxuICBoYW5kbGVNb2RlbFZhbHVlKCkge1xuICAgIHRoaXMubGlzdFJhZGlvQnV0dG9uLnRvQXJyYXkoKS5mb3JFYWNoKCAoIGl0ZW0sIGluZGV4LCBhcnJheSApID0+IHtcbiAgICAgIGlmICggdGhpcy52YWx1ZSA9PT0gaXRlbS52YWx1ZSApIHtcbiAgICAgICAgdGhpcy5pdGVtU2VsZWN0ZWQgPSBpdGVtO1xuICAgICAgfVxuICAgIH0gKTtcbiAgfVxuXG4gIGhhbmRsZUNoZWNrZWQoKSB7XG4gICAgdGhpcy5saXN0UmFkaW9CdXR0b24udG9BcnJheSgpLmZvckVhY2goICggaXRlbSApID0+IHtcbiAgICAgIHRoaXMuc2V0SXRlbUNoZWNrZWQoIGl0ZW0gKTtcbiAgICB9ICk7XG4gIH1cblxuICBoYW5kbGVLZXlEb3duKCAkZXZlbnQ6IEtleWJvYXJkRXZlbnQgKSB7XG4gICAgc3dpdGNoICggJGV2ZW50LmNvZGUgKSB7XG4gICAgICBjYXNlIEtleUV2ZW50LkFSUk9XRE9XTjpcbiAgICAgICAgJGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBLZXlFdmVudC5BUlJPV1VQOlxuICAgICAgICAkZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG5cbiAgc2V0SXRlbUNoZWNrZWQoIGl0ZW0gKSB7XG4gICAgaWYgKCBpdGVtLmNoZWNrZWQgKSB7XG4gICAgICByZXR1cm4gdGhpcy5jaGVja1JhZGlvKCBpdGVtICk7XG4gICAgfVxuICB9XG5cbiAgY2hlY2tGaXJzdEl0ZW0oKSB7XG4gICAgc2V0VGltZW91dCggKCkgPT4ge1xuICAgICAgdGhpcy5jaGVja1JhZGlvKCB0aGlzLmxpc3RSYWRpb0J1dHRvbi50b0FycmF5KClbIDAgXSApO1xuICAgIH0sIDEgKTtcbiAgfVxuXG4gIGdldENoZWNrZWRSYWRpb3MoKSB7XG4gICAgcmV0dXJuIHRoaXMubGlzdFJhZGlvQnV0dG9uLmZpbHRlciggKCBpdGVtICkgPT4ge1xuICAgICAgcmV0dXJuIGl0ZW0uY2hlY2tlZDtcbiAgICB9ICk7XG4gIH1cblxuICB2YWxpZGF0ZUNoZWNrZWRSYWRpb3MoKSB7XG4gICAgaWYgKCB0aGlzLmdldENoZWNrZWRSYWRpb3MoKS5sZW5ndGggPiAxICkge1xuICAgICAgdGhyb3cgbmV3IEV2YWxFcnJvciggJ09ubHkgb25lIHJhZGlvYnV0dG9uIHdpdGggW2NoZWNrZWRdIHByb3BlcnR5IGlzIGFsbG93ZWQnICk7XG4gICAgfVxuICB9XG5cbiAgY2hlY2tSYWRpbyggaXRlbSwgJGV2ZW50PyApIHtcbiAgICBpZiAoJGV2ZW50ICYmIGl0ZW0uZGlzYWJsZWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy52YWx1ZSA9IGl0ZW0udmFsdWU7XG4gICAgdGhpcy5pdGVtU2VsZWN0ZWQgPSBpdGVtO1xuICAgIHRoaXMub25DaGVja1JhZGlvLmVtaXQoIHRoaXMuaXRlbVNlbGVjdGVkICk7XG4gIH1cblxuICBmb2N1c1JhZGlvKCBpdGVtICkge1xuICAgIHRoaXMub25Gb2N1c1JhZGlvLmVtaXQoIGl0ZW0gKTtcbiAgfVxuXG4gIG5nT25EZXN0cm95KCkge1xuICAgIHRoaXMuc3Vic2NyaXB0aW9uLnVuc3Vic2NyaWJlKCk7XG4gIH1cblxuXG59XG5cbiIsIjxuZy1jb250ZW50PjwvbmctY29udGVudD5cbjxkaXYgY2xhc3M9XCJncm91cC1yYWRpb3NcIiBbc3R5bGUuZGlzcGxheV09XCJvcmllbnRhdGlvbiA9PSAndmVydGljYWwnID8gJ2dyaWQnIDogJ2lubGluZS1mbGV4J1wiPlxuICAgIDxkaXYgKm5nRm9yPVwibGV0IGl0ZW0gb2YgbGlzdFJhZGlvQnV0dG9uLnRvQXJyYXkoKVwiIGNsYXNzPVwicmFkaW8tY29udGFpbmVyXCIgW3N0eWxlLnBhZGRpbmctdG9wXT1cIm9yaWVudGF0aW9uID09PSAndmVydGljYWwnID8gJzEwcHgnIDogJzAnXCI+XG4gICAgICAgIDxpbnB1dCAjcmFkaW9idXR0b25cbiAgICAgICAgICAgICAgIFt0eXBlXT1cIidyYWRpbydcIlxuICAgICAgICAgICAgICAgW2F0dHIubmFtZV09XCJuYW1lXCJcbiAgICAgICAgICAgICAgIChjbGljayk9XCJjaGVja1JhZGlvKGl0ZW0sICRldmVudClcIlxuICAgICAgICAgICAgICAgW3RhYmluZGV4XT1cInRhYmluZGV4XCJcbiAgICAgICAgICAgICAgIFthdHRyLmRpc2FibGVkXT1cIml0ZW0uZGlzYWJsZWRcIlxuICAgICAgICAgICAgICAgW3ZhbHVlXT1cIml0ZW0udmFsdWVcIlxuICAgICAgICAgICAgICAgKGtleWRvd24pPVwiaGFuZGxlS2V5RG93bigkZXZlbnQpXCJcbiAgICAgICAgICAgICAgIChmb2N1cyk9XCJmb2N1c1JhZGlvKGl0ZW0pXCJcbiAgICAgICAgICAgICAgIFsobmdNb2RlbCldPVwidmFsdWVcIj5cbiAgICAgICAgPHNwYW4gY2xhc3M9XCJyYWRpby1yaW5nXCIgW25nQ2xhc3NdPVwieydkaXNhYmxlZCc6IGl0ZW0uZGlzYWJsZWQgfVwiPjwvc3Bhbj5cbiAgICAgICAgPHNwYW5cbiAgICAgICAgICBbc3R5bGUudG9wXT1cIm9yaWVudGF0aW9uID09ICd2ZXJ0aWNhbCcgPyAnMTNweCcgOiAnM3B4J1wiXG4gICAgICAgICAgKm5nSWY9XCJpdGVtU2VsZWN0ZWQgPT09IGl0ZW1cIlxuICAgICAgICAgIFtzdHlsZS5iYWNrZ3JvdW5kLWNvbG9yXT1cImNvbG9yU2VsZWN0ZWRcIiBjbGFzcz1cInJhZGlvLXNlbGVjdGVkXCIgW25nQ2xhc3NdPVwieydkaXNhYmxlZCc6IGl0ZW0uZGlzYWJsZWR9XCI+PC9zcGFuPlxuICAgICAgICA8bGFiZWwgKGNsaWNrKT1cImNoZWNrUmFkaW8oaXRlbSwgJGV2ZW50KVwiIGNsYXNzPVwiLWxhYmVsXCI+e3tpdGVtLmxhYmVsfX08L2xhYmVsPlxuICAgIDwvZGl2PlxuPC9kaXY+XG4iXX0=