ng-zorro-antd
Version:
An enterprise-class UI components based on Ant Design and Angular
272 lines • 35.6 kB
JavaScript
/**
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/LICENSE
*/
import { ChangeDetectionStrategy, Component, ContentChild, Host, Input, Optional, ViewEncapsulation } from '@angular/core';
import { AbstractControl, FormControlDirective, FormControlName, NgControl, NgModel } from '@angular/forms';
import { Subject, Subscription } from 'rxjs';
import { filter, startWith, takeUntil, tap } from 'rxjs/operators';
import { helpMotion } from 'ng-zorro-antd/core/animation';
import { NzFormStatusService } from 'ng-zorro-antd/core/form';
import { toBoolean } from 'ng-zorro-antd/core/util';
import * as i0 from "@angular/core";
import * as i1 from "./form-item.component";
import * as i2 from "ng-zorro-antd/i18n";
import * as i3 from "./form.directive";
import * as i4 from "ng-zorro-antd/core/form";
import * as i5 from "@angular/common";
import * as i6 from "ng-zorro-antd/core/outlet";
export class NzFormControlComponent {
constructor(elementRef, nzFormItemComponent, cdr, renderer, i18n, nzFormDirective, nzFormStatusService) {
this.nzFormItemComponent = nzFormItemComponent;
this.cdr = cdr;
this.nzFormDirective = nzFormDirective;
this.nzFormStatusService = nzFormStatusService;
this._hasFeedback = false;
this.validateChanges = Subscription.EMPTY;
this.validateString = null;
this.destroyed$ = new Subject();
this.status = '';
this.validateControl = null;
this.innerTip = null;
this.nzAutoTips = {};
this.nzDisableAutoTips = 'default';
renderer.addClass(elementRef.nativeElement, 'ant-form-item-control');
this.subscribeAutoTips(i18n.localeChange.pipe(tap(locale => (this.localeId = locale.locale))));
this.subscribeAutoTips(this.nzFormDirective?.getInputObservable('nzAutoTips'));
this.subscribeAutoTips(this.nzFormDirective
?.getInputObservable('nzDisableAutoTips')
.pipe(filter(() => this.nzDisableAutoTips === 'default')));
}
get disableAutoTips() {
return this.nzDisableAutoTips !== 'default'
? toBoolean(this.nzDisableAutoTips)
: this.nzFormDirective?.nzDisableAutoTips;
}
set nzHasFeedback(value) {
this._hasFeedback = toBoolean(value);
this.nzFormStatusService.formStatusChanges.next({ status: this.status, hasFeedback: this._hasFeedback });
if (this.nzFormItemComponent) {
this.nzFormItemComponent.setHasFeedback(this._hasFeedback);
}
}
get nzHasFeedback() {
return this._hasFeedback;
}
set nzValidateStatus(value) {
if (value instanceof AbstractControl || value instanceof NgModel) {
this.validateControl = value;
this.validateString = null;
this.watchControl();
}
else if (value instanceof FormControlName) {
this.validateControl = value.control;
this.validateString = null;
this.watchControl();
}
else {
this.validateString = value;
this.validateControl = null;
this.setStatus();
}
}
watchControl() {
this.validateChanges.unsubscribe();
/** miss detect https://github.com/angular/angular/issues/10887 **/
if (this.validateControl && this.validateControl.statusChanges) {
this.validateChanges = this.validateControl.statusChanges
.pipe(startWith(null), takeUntil(this.destroyed$))
.subscribe(_ => {
if (!this.disableAutoTips) {
this.updateAutoErrorTip();
}
this.setStatus();
this.cdr.markForCheck();
});
}
}
setStatus() {
this.status = this.getControlStatus(this.validateString);
this.innerTip = this.getInnerTip(this.status);
this.nzFormStatusService.formStatusChanges.next({ status: this.status, hasFeedback: this.nzHasFeedback });
if (this.nzFormItemComponent) {
this.nzFormItemComponent.setWithHelpViaTips(!!this.innerTip);
this.nzFormItemComponent.setStatus(this.status);
}
}
getControlStatus(validateString) {
let status;
if (validateString === 'warning' || this.validateControlStatus('INVALID', 'warning')) {
status = 'warning';
}
else if (validateString === 'error' || this.validateControlStatus('INVALID')) {
status = 'error';
}
else if (validateString === 'validating' ||
validateString === 'pending' ||
this.validateControlStatus('PENDING')) {
status = 'validating';
}
else if (validateString === 'success' || this.validateControlStatus('VALID')) {
status = 'success';
}
else {
status = '';
}
return status;
}
validateControlStatus(validStatus, statusType) {
if (!this.validateControl) {
return false;
}
else {
const { dirty, touched, status } = this.validateControl;
return ((!!dirty || !!touched) && (statusType ? this.validateControl.hasError(statusType) : status === validStatus));
}
}
getInnerTip(status) {
switch (status) {
case 'error':
return (!this.disableAutoTips && this.autoErrorTip) || this.nzErrorTip || null;
case 'validating':
return this.nzValidatingTip || null;
case 'success':
return this.nzSuccessTip || null;
case 'warning':
return this.nzWarningTip || null;
default:
return null;
}
}
updateAutoErrorTip() {
if (this.validateControl) {
const errors = this.validateControl.errors || {};
let autoErrorTip = '';
for (const key in errors) {
if (errors.hasOwnProperty(key)) {
autoErrorTip =
errors[key]?.[this.localeId] ??
this.nzAutoTips?.[this.localeId]?.[key] ??
this.nzAutoTips.default?.[key] ??
this.nzFormDirective?.nzAutoTips?.[this.localeId]?.[key] ??
this.nzFormDirective?.nzAutoTips.default?.[key];
}
if (!!autoErrorTip) {
break;
}
}
this.autoErrorTip = autoErrorTip;
}
}
subscribeAutoTips(observable) {
observable?.pipe(takeUntil(this.destroyed$)).subscribe(() => {
if (!this.disableAutoTips) {
this.updateAutoErrorTip();
this.setStatus();
this.cdr.markForCheck();
}
});
}
ngOnChanges(changes) {
const { nzDisableAutoTips, nzAutoTips, nzSuccessTip, nzWarningTip, nzErrorTip, nzValidatingTip } = changes;
if (nzDisableAutoTips || nzAutoTips) {
this.updateAutoErrorTip();
this.setStatus();
}
else if (nzSuccessTip || nzWarningTip || nzErrorTip || nzValidatingTip) {
this.setStatus();
}
}
ngOnInit() {
this.setStatus();
}
ngOnDestroy() {
this.destroyed$.next();
this.destroyed$.complete();
}
ngAfterContentInit() {
if (!this.validateControl && !this.validateString) {
if (this.defaultValidateControl instanceof FormControlDirective) {
this.nzValidateStatus = this.defaultValidateControl.control;
}
else {
this.nzValidateStatus = this.defaultValidateControl;
}
}
}
}
NzFormControlComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: NzFormControlComponent, deps: [{ token: i0.ElementRef }, { token: i1.NzFormItemComponent, host: true, optional: true }, { token: i0.ChangeDetectorRef }, { token: i0.Renderer2 }, { token: i2.NzI18nService }, { token: i3.NzFormDirective, optional: true }, { token: i4.NzFormStatusService }], target: i0.ɵɵFactoryTarget.Component });
NzFormControlComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: NzFormControlComponent, selector: "nz-form-control", inputs: { nzSuccessTip: "nzSuccessTip", nzWarningTip: "nzWarningTip", nzErrorTip: "nzErrorTip", nzValidatingTip: "nzValidatingTip", nzExtra: "nzExtra", nzAutoTips: "nzAutoTips", nzDisableAutoTips: "nzDisableAutoTips", nzHasFeedback: "nzHasFeedback", nzValidateStatus: "nzValidateStatus" }, providers: [NzFormStatusService], queries: [{ propertyName: "defaultValidateControl", first: true, predicate: NgControl, descendants: true }], exportAs: ["nzFormControl"], usesOnChanges: true, ngImport: i0, template: `
<div class="ant-form-item-control-input">
<div class="ant-form-item-control-input-content">
<ng-content></ng-content>
</div>
</div>
<div class="ant-form-item-explain ant-form-item-explain-connected" *ngIf="innerTip">
<div role="alert" [ngClass]="['ant-form-item-explain-' + status]">
<ng-container *nzStringTemplateOutlet="innerTip; context: { $implicit: validateControl }">{{
innerTip
}}</ng-container>
</div>
</div>
<div class="ant-form-item-extra" *ngIf="nzExtra">
<ng-container *nzStringTemplateOutlet="nzExtra">{{ nzExtra }}</ng-container>
</div>
`, isInline: true, directives: [{ type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i5.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { type: i6.NzStringTemplateOutletDirective, selector: "[nzStringTemplateOutlet]", inputs: ["nzStringTemplateOutletContext", "nzStringTemplateOutlet"], exportAs: ["nzStringTemplateOutlet"] }], animations: [helpMotion], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: NzFormControlComponent, decorators: [{
type: Component,
args: [{
selector: 'nz-form-control',
exportAs: 'nzFormControl',
preserveWhitespaces: false,
animations: [helpMotion],
encapsulation: ViewEncapsulation.None,
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<div class="ant-form-item-control-input">
<div class="ant-form-item-control-input-content">
<ng-content></ng-content>
</div>
</div>
<div class="ant-form-item-explain ant-form-item-explain-connected" *ngIf="innerTip">
<div role="alert" [ngClass]="['ant-form-item-explain-' + status]">
<ng-container *nzStringTemplateOutlet="innerTip; context: { $implicit: validateControl }">{{
innerTip
}}</ng-container>
</div>
</div>
<div class="ant-form-item-extra" *ngIf="nzExtra">
<ng-container *nzStringTemplateOutlet="nzExtra">{{ nzExtra }}</ng-container>
</div>
`,
providers: [NzFormStatusService]
}]
}], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i1.NzFormItemComponent, decorators: [{
type: Optional
}, {
type: Host
}] }, { type: i0.ChangeDetectorRef }, { type: i0.Renderer2 }, { type: i2.NzI18nService }, { type: i3.NzFormDirective, decorators: [{
type: Optional
}] }, { type: i4.NzFormStatusService }]; }, propDecorators: { defaultValidateControl: [{
type: ContentChild,
args: [NgControl, { static: false }]
}], nzSuccessTip: [{
type: Input
}], nzWarningTip: [{
type: Input
}], nzErrorTip: [{
type: Input
}], nzValidatingTip: [{
type: Input
}], nzExtra: [{
type: Input
}], nzAutoTips: [{
type: Input
}], nzDisableAutoTips: [{
type: Input
}], nzHasFeedback: [{
type: Input
}], nzValidateStatus: [{
type: Input
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZm9ybS1jb250cm9sLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL2NvbXBvbmVudHMvZm9ybS9mb3JtLWNvbnRyb2wuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7R0FHRztBQUVILE9BQU8sRUFFTCx1QkFBdUIsRUFFdkIsU0FBUyxFQUNULFlBQVksRUFFWixJQUFJLEVBQ0osS0FBSyxFQUlMLFFBQVEsRUFJUixpQkFBaUIsRUFDbEIsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLGVBQWUsRUFBRSxvQkFBb0IsRUFBRSxlQUFlLEVBQUUsU0FBUyxFQUFFLE9BQU8sRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQzVHLE9BQU8sRUFBYyxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQ3pELE9BQU8sRUFBRSxNQUFNLEVBQUUsU0FBUyxFQUFFLFNBQVMsRUFBRSxHQUFHLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUVuRSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFDMUQsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFFOUQsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLHlCQUF5QixDQUFDOzs7Ozs7OztBQWdDcEQsTUFBTSxPQUFPLHNCQUFzQjtJQXlLakMsWUFDRSxVQUFzQixFQUNNLG1CQUF3QyxFQUM1RCxHQUFzQixFQUM5QixRQUFtQixFQUNuQixJQUFtQixFQUNDLGVBQWdDLEVBQzVDLG1CQUF3QztRQUxwQix3QkFBbUIsR0FBbkIsbUJBQW1CLENBQXFCO1FBQzVELFFBQUcsR0FBSCxHQUFHLENBQW1CO1FBR1Ysb0JBQWUsR0FBZixlQUFlLENBQWlCO1FBQzVDLHdCQUFtQixHQUFuQixtQkFBbUIsQ0FBcUI7UUExSzFDLGlCQUFZLEdBQUcsS0FBSyxDQUFDO1FBQ3JCLG9CQUFlLEdBQWlCLFlBQVks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c0NvbnRlbnQiOlsiLyoqXG4gKiBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhbiBNSVQtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZVxuICogZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZSBhdCBodHRwczovL2dpdGh1Yi5jb20vTkctWk9SUk8vbmctem9ycm8tYW50ZC9ibG9iL21hc3Rlci9MSUNFTlNFXG4gKi9cblxuaW1wb3J0IHtcbiAgQWZ0ZXJDb250ZW50SW5pdCxcbiAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXG4gIENoYW5nZURldGVjdG9yUmVmLFxuICBDb21wb25lbnQsXG4gIENvbnRlbnRDaGlsZCxcbiAgRWxlbWVudFJlZixcbiAgSG9zdCxcbiAgSW5wdXQsXG4gIE9uQ2hhbmdlcyxcbiAgT25EZXN0cm95LFxuICBPbkluaXQsXG4gIE9wdGlvbmFsLFxuICBSZW5kZXJlcjIsXG4gIFNpbXBsZUNoYW5nZXMsXG4gIFRlbXBsYXRlUmVmLFxuICBWaWV3RW5jYXBzdWxhdGlvblxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEFic3RyYWN0Q29udHJvbCwgRm9ybUNvbnRyb2xEaXJlY3RpdmUsIEZvcm1Db250cm9sTmFtZSwgTmdDb250cm9sLCBOZ01vZGVsIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHsgT2JzZXJ2YWJsZSwgU3ViamVjdCwgU3Vic2NyaXB0aW9uIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBmaWx0ZXIsIHN0YXJ0V2l0aCwgdGFrZVVudGlsLCB0YXAgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5cbmltcG9ydCB7IGhlbHBNb3Rpb24gfSBmcm9tICduZy16b3Jyby1hbnRkL2NvcmUvYW5pbWF0aW9uJztcbmltcG9ydCB7IE56Rm9ybVN0YXR1c1NlcnZpY2UgfSBmcm9tICduZy16b3Jyby1hbnRkL2NvcmUvZm9ybSc7XG5pbXBvcnQgeyBCb29sZWFuSW5wdXQsIE56U2FmZUFueSB9IGZyb20gJ25nLXpvcnJvLWFudGQvY29yZS90eXBlcyc7XG5pbXBvcnQgeyB0b0Jvb2xlYW4gfSBmcm9tICduZy16b3Jyby1hbnRkL2NvcmUvdXRpbCc7XG5pbXBvcnQgeyBOekkxOG5TZXJ2aWNlIH0gZnJvbSAnbmctem9ycm8tYW50ZC9pMThuJztcblxuaW1wb3J0IHsgTnpGb3JtQ29udHJvbFN0YXR1c1R5cGUsIE56Rm9ybUl0ZW1Db21wb25lbnQgfSBmcm9tICcuL2Zvcm0taXRlbS5jb21wb25lbnQnO1xuaW1wb3J0IHsgTnpGb3JtRGlyZWN0aXZlIH0gZnJvbSAnLi9mb3JtLmRpcmVjdGl2ZSc7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ256LWZvcm0tY29udHJvbCcsXG4gIGV4cG9ydEFzOiAnbnpGb3JtQ29udHJvbCcsXG4gIHByZXNlcnZlV2hpdGVzcGFjZXM6IGZhbHNlLFxuICBhbmltYXRpb25zOiBbaGVscE1vdGlvbl0sXG4gIGVuY2Fwc3VsYXRpb246IFZpZXdFbmNhcHN1bGF0aW9uLk5vbmUsXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxuICB0ZW1wbGF0ZTogYFxuICAgIDxkaXYgY2xhc3M9XCJhbnQtZm9ybS1pdGVtLWNvbnRyb2wtaW5wdXRcIj5cbiAgICAgIDxkaXYgY2xhc3M9XCJhbnQtZm9ybS1pdGVtLWNvbnRyb2wtaW5wdXQtY29udGVudFwiPlxuICAgICAgICA8bmctY29udGVudD48L25nLWNvbnRlbnQ+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgICA8ZGl2IEBoZWxwTW90aW9uIGNsYXNzPVwiYW50LWZvcm0taXRlbS1leHBsYWluIGFudC1mb3JtLWl0ZW0tZXhwbGFpbi1jb25uZWN0ZWRcIiAqbmdJZj1cImlubmVyVGlwXCI+XG4gICAgICA8ZGl2IHJvbGU9XCJhbGVydFwiIFtuZ0NsYXNzXT1cIlsnYW50LWZvcm0taXRlbS1leHBsYWluLScgKyBzdGF0dXNdXCI+XG4gICAgICAgIDxuZy1jb250YWluZXIgKm56U3RyaW5nVGVtcGxhdGVPdXRsZXQ9XCJpbm5lclRpcDsgY29udGV4dDogeyAkaW1wbGljaXQ6IHZhbGlkYXRlQ29udHJvbCB9XCI+e3tcbiAgICAgICAgICBpbm5lclRpcFxuICAgICAgICB9fTwvbmctY29udGFpbmVyPlxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG4gICAgPGRpdiBjbGFzcz1cImFudC1mb3JtLWl0ZW0tZXh0cmFcIiAqbmdJZj1cIm56RXh0cmFcIj5cbiAgICAgIDxuZy1jb250YWluZXIgKm56U3RyaW5nVGVtcGxhdGVPdXRsZXQ9XCJuekV4dHJhXCI+e3sgbnpFeHRyYSB9fTwvbmctY29udGFpbmVyPlxuICAgIDwvZGl2PlxuICBgLFxuICBwcm92aWRlcnM6IFtOekZvcm1TdGF0dXNTZXJ2aWNlXVxufSlcbmV4cG9ydCBjbGFzcyBOekZvcm1Db250cm9sQ29tcG9uZW50IGltcGxlbWVudHMgT25DaGFuZ2VzLCBPbkRlc3Ryb3ksIE9uSW5pdCwgQWZ0ZXJDb250ZW50SW5pdCwgT25EZXN0cm95IHtcbiAgc3RhdGljIG5nQWNjZXB0SW5wdXRUeXBlX256SGFzRmVlZGJhY2s6IEJvb2xlYW5JbnB1dDtcbiAgc3RhdGljIG5nQWNjZXB0SW5wdXRUeXBlX256UmVxdWlyZWQ6IEJvb2xlYW5JbnB1dDtcbiAgc3RhdGljIG5nQWNjZXB0SW5wdXRUeXBlX256Tm9Db2xvbjogQm9vbGVhbklucHV0O1xuICBzdGF0aWMgbmdBY2NlcHRJbnB1dFR5cGVfbnpEaXNhYmxlQXV0b1RpcHM6IEJvb2xlYW5JbnB1dDtcblxuICBwcml2YXRlIF9oYXNGZWVkYmFjayA9IGZhbHNlO1xuICBwcml2YXRlIHZhbGlkYXRlQ2hhbmdlczogU3Vic2NyaXB0aW9uID0gU3Vic2NyaXB0aW9uLkVNUFRZO1xuICBwcml2YXRlIHZhbGlkYXRlU3RyaW5nOiBzdHJpbmcgfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSBkZXN0cm95ZWQkID0gbmV3IFN1YmplY3Q8dm9pZD4oKTtcbiAgcHJpdmF0ZSBsb2NhbGVJZCE6IHN0cmluZztcbiAgcHJpdmF0ZSBhdXRvRXJyb3JUaXA/OiBzdHJpbmc7XG5cbiAgcHJpdmF0ZSBnZXQgZGlzYWJsZUF1dG9UaXBzKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLm56RGlzYWJsZUF1dG9UaXBzICE9PSAnZGVmYXVsdCdcbiAgICAgID8gdG9Cb29sZWFuKHRoaXMubnpEaXNhYmxlQXV0b1RpcHMpXG4gICAgICA6IHRoaXMubnpGb3JtRGlyZWN0aXZlPy5uekRpc2FibGVBdXRvVGlwcztcbiAgfVxuXG4gIHN0YXR1czogTnpGb3JtQ29udHJvbFN0YXR1c1R5cGUgPSAnJztcbiAgdmFsaWRhdGVDb250cm9sOiBBYnN0cmFjdENvbnRyb2wgfCBOZ01vZGVsIHwgbnVsbCA9IG51bGw7XG4gIGlubmVyVGlwOiBzdHJpbmcgfCBUZW1wbGF0ZVJlZjx7ICRpbXBsaWNpdDogQWJzdHJhY3RDb250cm9sIHwgTmdNb2RlbCB9PiB8IG51bGwgPSBudWxsO1xuXG4gIEBDb250ZW50Q2hpbGQoTmdDb250cm9sLCB7IHN0YXRpYzogZmFsc2UgfSkgZGVmYXVsdFZhbGlkYXRlQ29udHJvbD86IEZvcm1Db250cm9sTmFtZSB8IEZvcm1Db250cm9sRGlyZWN0aXZlO1xuICBASW5wdXQoKSBuelN1Y2Nlc3NUaXA/OiBzdHJpbmcgfCBUZW1wbGF0ZVJlZjx7ICRpbXBsaWNpdDogQWJzdHJhY3RDb250cm9sIHwgTmdNb2RlbCB9PjtcbiAgQElucHV0KCkgbnpXYXJuaW5nVGlwPzogc3RyaW5nIHwgVGVtcGxhdGVSZWY8eyAkaW1wbGljaXQ6IEFic3RyYWN0Q29udHJvbCB8IE5nTW9kZWwgfT47XG4gIEBJbnB1dCgpIG56RXJyb3JUaXA/OiBzdHJpbmcgfCBUZW1wbGF0ZVJlZjx7ICRpbXBsaWNpdDogQWJzdHJhY3RDb250cm9sIHwgTmdNb2RlbCB9PjtcbiAgQElucHV0KCkgbnpWYWxpZGF0aW5nVGlwPzogc3RyaW5nIHwgVGVtcGxhdGVSZWY8eyAkaW1wbGljaXQ6IEFic3RyYWN0Q29udHJvbCB8IE5nTW9kZWwgfT47XG4gIEBJbnB1dCgpIG56RXh0cmE/OiBzdHJpbmcgfCBUZW1wbGF0ZVJlZjx2b2lkPjtcbiAgQElucHV0KCkgbnpBdXRvVGlwczogUmVjb3JkPHN0cmluZywgUmVjb3JkPHN0cmluZywgc3RyaW5nPj4gPSB7fTtcbiAgQElucHV0KCkgbnpEaXNhYmxlQXV0b1RpcHM6IGJvb2xlYW4gfCAnZGVmYXVsdCcgPSAnZGVmYXVsdCc7XG5cbiAgQElucHV0KClcbiAgc2V0IG56SGFzRmVlZGJhY2sodmFsdWU6IGJvb2xlYW4pIHtcbiAgICB0aGlzLl9oYXNGZWVkYmFjayA9IHRvQm9vbGVhbih2YWx1ZSk7XG4gICAgdGhpcy5uekZvcm1TdGF0dXNTZXJ2aWNlLmZvcm1TdGF0dXNDaGFuZ2VzLm5leHQoeyBzdGF0dXM6IHRoaXMuc3RhdHVzLCBoYXNGZWVkYmFjazogdGhpcy5faGFzRmVlZGJhY2sgfSk7XG4gICAgaWYgKHRoaXMubnpGb3JtSXRlbUNvbXBvbmVudCkge1xuICAgICAgdGhpcy5uekZvcm1JdGVtQ29tcG9uZW50LnNldEhhc0ZlZWRiYWNrKHRoaXMuX2hhc0ZlZWRiYWNrKTtcbiAgICB9XG4gIH1cblxuICBnZXQgbnpIYXNGZWVkYmFjaygpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5faGFzRmVlZGJhY2s7XG4gIH1cblxuICBASW5wdXQoKVxuICBzZXQgbnpWYWxpZGF0ZVN0YXR1cyh2YWx1ZTogc3RyaW5nIHwgQWJzdHJhY3RDb250cm9sIHwgRm9ybUNvbnRyb2xOYW1lIHwgTmdNb2RlbCkge1xuICAgIGlmICh2YWx1ZSBpbnN0YW5jZW9mIEFic3RyYWN0Q29udHJvbCB8fCB2YWx1ZSBpbnN0YW5jZW9mIE5nTW9kZWwpIHtcbiAgICAgIHRoaXMudmFsaWRhdGVDb250cm9sID0gdmFsdWU7XG4gICAgICB0aGlzLnZhbGlkYXRlU3RyaW5nID0gbnVsbDtcbiAgICAgIHRoaXMud2F0Y2hDb250cm9sKCk7XG4gICAgfSBlbHNlIGlmICh2YWx1ZSBpbnN0YW5jZW9mIEZvcm1Db250cm9sTmFtZSkge1xuICAgICAgdGhpcy52YWxpZGF0ZUNvbnRyb2wgPSB2YWx1ZS5jb250cm9sO1xuICAgICAgdGhpcy52YWxpZGF0ZVN0cmluZyA9IG51bGw7XG4gICAgICB0aGlzLndhdGNoQ29udHJvbCgpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnZhbGlkYXRlU3RyaW5nID0gdmFsdWU7XG4gICAgICB0aGlzLnZhbGlkYXRlQ29udHJvbCA9IG51bGw7XG4gICAgICB0aGlzLnNldFN0YXR1cygpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgd2F0Y2hDb250cm9sKCk6IHZvaWQge1xuICAgIHRoaXMudmFsaWRhdGVDaGFuZ2VzLnVuc3Vic2NyaWJlKCk7XG4gICAgLyoqIG1pc3MgZGV0ZWN0IGh0dHBzOi8vZ2l0aHViLmNvbS9hbmd1bGFyL2FuZ3VsYXIvaXNzdWVzLzEwODg3ICoqL1xuICAgIGlmICh0aGlzLnZhbGlkYXRlQ29udHJvbCAmJiB0aGlzLnZhbGlkYXRlQ29udHJvbC5zdGF0dXNDaGFuZ2VzKSB7XG4gICAgICB0aGlzLnZhbGlkYXRlQ2hhbmdlcyA9ICh0aGlzLnZhbGlkYXRlQ29udHJvbC5zdGF0dXNDaGFuZ2VzIGFzIE9ic2VydmFibGU8TnpTYWZlQW55PilcbiAgICAgICAgLnBpcGUoc3RhcnRXaXRoKG51bGwpLCB0YWtlVW50aWwodGhpcy5kZXN0cm95ZWQkKSlcbiAgICAgICAgLnN1YnNjcmliZShfID0+IHtcbiAgICAgICAgICBpZiAoIXRoaXMuZGlzYWJsZUF1dG9UaXBzKSB7XG4gICAgICAgICAgICB0aGlzLnVwZGF0ZUF1dG9FcnJvclRpcCgpO1xuICAgICAgICAgIH1cbiAgICAgICAgICB0aGlzLnNldFN0YXR1cygpO1xuICAgICAgICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICAgICAgICB9KTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHNldFN0YXR1cygpOiB2b2lkIHtcbiAgICB0aGlzLnN0YXR1cyA9IHRoaXMuZ2V0Q29udHJvbFN0YXR1cyh0aGlzLnZhbGlkYXRlU3RyaW5nKTtcbiAgICB0aGlzLmlubmVyVGlwID0gdGhpcy5nZXRJbm5lclRpcCh0aGlzLnN0YXR1cyk7XG4gICAgdGhpcy5uekZvcm1TdGF0dXNTZXJ2aWNlLmZvcm1TdGF0dXNDaGFuZ2VzLm5leHQoeyBzdGF0dXM6IHRoaXMuc3RhdHVzLCBoYXNGZWVkYmFjazogdGhpcy5uekhhc0ZlZWRiYWNrIH0pO1xuICAgIGlmICh0aGlzLm56Rm9ybUl0ZW1Db21wb25lbnQpIHtcbiAgICAgIHRoaXMubnpGb3JtSXRlbUNvbXBvbmVudC5zZXRXaXRoSGVscFZpYVRpcHMoISF0aGlzLmlubmVyVGlwKTtcbiAgICAgIHRoaXMubnpGb3JtSXRlbUNvbXBvbmVudC5zZXRTdGF0dXModGhpcy5zdGF0dXMpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgZ2V0Q29udHJvbFN0YXR1cyh2YWxpZGF0ZVN0cmluZzogc3RyaW5nIHwgbnVsbCk6IE56Rm9ybUNvbnRyb2xTdGF0dXNUeXBlIHtcbiAgICBsZXQgc3RhdHVzOiBOekZvcm1Db250cm9sU3RhdHVzVHlwZTtcblxuICAgIGlmICh2YWxpZGF0ZVN0cmluZyA9PT0gJ3dhcm5pbmcnIHx8IHRoaXMudmFsaWRhdGVDb250cm9sU3RhdHVzKCdJTlZBTElEJywgJ3dhcm5pbmcnKSkge1xuICAgICAgc3RhdHVzID0gJ3dhcm5pbmcnO1xuICAgIH0gZWxzZSBpZiAodmFsaWRhdGVTdHJpbmcgPT09ICdlcnJvcicgfHwgdGhpcy52YWxpZGF0ZUNvbnRyb2xTdGF0dXMoJ0lOVkFMSUQnKSkge1xuICAgICAgc3RhdHVzID0gJ2Vycm9yJztcbiAgICB9IGVsc2UgaWYgKFxuICAgICAgdmFsaWRhdGVTdHJpbmcgPT09ICd2YWxpZGF0aW5nJyB8fFxuICAgICAgdmFsaWRhdGVTdHJpbmcgPT09ICdwZW5kaW5nJyB8fFxuICAgICAgdGhpcy52YWxpZGF0ZUNvbnRyb2xTdGF0dXMoJ1BFTkRJTkcnKVxuICAgICkge1xuICAgICAgc3RhdHVzID0gJ3ZhbGlkYXRpbmcnO1xuICAgIH0gZWxzZSBpZiAodmFsaWRhdGVTdHJpbmcgPT09ICdzdWNjZXNzJyB8fCB0aGlzLnZhbGlkYXRlQ29udHJvbFN0YXR1cygnVkFMSUQnKSkge1xuICAgICAgc3RhdHVzID0gJ3N1Y2Nlc3MnO1xuICAgIH0gZWxzZSB7XG4gICAgICBzdGF0dXMgPSAnJztcbiAgICB9XG5cbiAgICByZXR1cm4gc3RhdHVzO1xuICB9XG5cbiAgcHJpdmF0ZSB2YWxpZGF0ZUNvbnRyb2xTdGF0dXModmFsaWRTdGF0dXM6IHN0cmluZywgc3RhdHVzVHlwZT86IE56Rm9ybUNvbnRyb2xTdGF0dXNUeXBlKTogYm9vbGVhbiB7XG4gICAgaWYgKCF0aGlzLnZhbGlkYXRlQ29udHJvbCkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCB7IGRpcnR5LCB0b3VjaGVkLCBzdGF0dXMgfSA9IHRoaXMudmFsaWRhdGVDb250cm9sO1xuICAgICAgcmV0dXJuIChcbiAgICAgICAgKCEhZGlydHkgfHwgISF0b3VjaGVkKSAmJiAoc3RhdHVzVHlwZSA/IHRoaXMudmFsaWRhdGVDb250cm9sLmhhc0Vycm9yKHN0YXR1c1R5cGUpIDogc3RhdHVzID09PSB2YWxpZFN0YXR1cylcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBnZXRJbm5lclRpcChcbiAgICBzdGF0dXM6IE56Rm9ybUNvbnRyb2xTdGF0dXNUeXBlXG4gICk6IHN0cmluZyB8IFRlbXBsYXRlUmVmPHsgJGltcGxpY2l0OiBBYnN0cmFjdENvbnRyb2wgfCBOZ01vZGVsIH0+IHwgbnVsbCB7XG4gICAgc3dpdGNoIChzdGF0dXMpIHtcbiAgICAgIGNhc2UgJ2Vycm9yJzpcbiAgICAgICAgcmV0dXJuICghdGhpcy5kaXNhYmxlQXV0b1RpcHMgJiYgdGhpcy5hdXRvRXJyb3JUaXApIHx8IHRoaXMubnpFcnJvclRpcCB8fCBudWxsO1xuICAgICAgY2FzZSAndmFsaWRhdGluZyc6XG4gICAgICAgIHJldHVybiB0aGlzLm56VmFsaWRhdGluZ1RpcCB8fCBudWxsO1xuICAgICAgY2FzZSAnc3VjY2Vzcyc6XG4gICAgICAgIHJldHVybiB0aGlzLm56U3VjY2Vzc1RpcCB8fCBudWxsO1xuICAgICAgY2FzZSAnd2FybmluZyc6XG4gICAgICAgIHJldHVybiB0aGlzLm56V2FybmluZ1RpcCB8fCBudWxsO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSB1cGRhdGVBdXRvRXJyb3JUaXAoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMudmFsaWRhdGVDb250cm9sKSB7XG4gICAgICBjb25zdCBlcnJvcnMgPSB0aGlzLnZhbGlkYXRlQ29udHJvbC5lcnJvcnMgfHwge307XG4gICAgICBsZXQgYXV0b0Vycm9yVGlwID0gJyc7XG4gICAgICBmb3IgKGNvbnN0IGtleSBpbiBlcnJvcnMpIHtcbiAgICAgICAgaWYgKGVycm9ycy5oYXNPd25Qcm9wZXJ0eShrZXkpKSB7XG4gICAgICAgICAgYXV0b0Vycm9yVGlwID1cbiAgICAgICAgICAgIGVycm9yc1trZXldPy5bdGhpcy5sb2NhbGVJZF0gPz9cbiAgICAgICAgICAgIHRoaXMubnpBdXRvVGlwcz8uW3RoaXMubG9jYWxlSWRdPy5ba2V5XSA/P1xuICAgICAgICAgICAgdGhpcy5uekF1dG9UaXBzLmRlZmF1bHQ/LltrZXldID8/XG4gICAgICAgICAgICB0aGlzLm56Rm9ybURpcmVjdGl2ZT8ubnpBdXRvVGlwcz8uW3RoaXMubG9jYWxlSWRdPy5ba2V5XSA/P1xuICAgICAgICAgICAgdGhpcy5uekZvcm1EaXJlY3RpdmU/Lm56QXV0b1RpcHMuZGVmYXVsdD8uW2tleV07XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCEhYXV0b0Vycm9yVGlwKSB7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHRoaXMuYXV0b0Vycm9yVGlwID0gYXV0b0Vycm9yVGlwO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgc3Vic2NyaWJlQXV0b1RpcHMob2JzZXJ2YWJsZTogT2JzZXJ2YWJsZTxOelNhZmVBbnk+KTogdm9pZCB7XG4gICAgb2JzZXJ2YWJsZT8ucGlwZSh0YWtlVW50aWwodGhpcy5kZXN0cm95ZWQkKSkuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgIGlmICghdGhpcy5kaXNhYmxlQXV0b1RpcHMpIHtcbiAgICAgICAgdGhpcy51cGRhdGVBdXRvRXJyb3JUaXAoKTtcbiAgICAgICAgdGhpcy5zZXRTdGF0dXMoKTtcbiAgICAgICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBjb25zdHJ1Y3RvcihcbiAgICBlbGVtZW50UmVmOiBFbGVtZW50UmVmLFxuICAgIEBPcHRpb25hbCgpIEBIb3N0KCkgcHJpdmF0ZSBuekZvcm1JdGVtQ29tcG9uZW50OiBOekZvcm1JdGVtQ29tcG9uZW50LFxuICAgIHByaXZhdGUgY2RyOiBDaGFuZ2VEZXRlY3RvclJlZixcbiAgICByZW5kZXJlcjogUmVuZGVyZXIyLFxuICAgIGkxOG46IE56STE4blNlcnZpY2UsXG4gICAgQE9wdGlvbmFsKCkgcHJpdmF0ZSBuekZvcm1EaXJlY3RpdmU6IE56Rm9ybURpcmVjdGl2ZSxcbiAgICBwcml2YXRlIG56Rm9ybVN0YXR1c1NlcnZpY2U6IE56Rm9ybVN0YXR1c1NlcnZpY2VcbiAgKSB7XG4gICAgcmVuZGVyZXIuYWRkQ2xhc3MoZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50LCAnYW50LWZvcm0taXRlbS1jb250cm9sJyk7XG5cbiAgICB0aGlzLnN1YnNjcmliZUF1dG9UaXBzKGkxOG4ubG9jYWxlQ2hhbmdlLnBpcGUodGFwKGxvY2FsZSA9PiAodGhpcy5sb2NhbGVJZCA9IGxvY2FsZS5sb2NhbGUpKSkpO1xuICAgIHRoaXMuc3Vic2NyaWJlQXV0b1RpcHModGhpcy5uekZvcm1EaXJlY3RpdmU/LmdldElucHV0T2JzZXJ2YWJsZSgnbnpBdXRvVGlwcycpKTtcbiAgICB0aGlzLnN1YnNjcmliZUF1dG9UaXBzKFxuICAgICAgdGhpcy5uekZvcm1EaXJlY3RpdmVcbiAgICAgICAgPy5nZXRJbnB1dE9ic2VydmFibGUoJ256RGlzYWJsZUF1dG9UaXBzJylcbiAgICAgICAgLnBpcGUoZmlsdGVyKCgpID0+IHRoaXMubnpEaXNhYmxlQXV0b1RpcHMgPT09ICdkZWZhdWx0JykpXG4gICAgKTtcbiAgfVxuXG4gIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpOiB2b2lkIHtcbiAgICBjb25zdCB7IG56RGlzYWJsZUF1dG9UaXBzLCBuekF1dG9UaXBzLCBuelN1Y2Nlc3NUaXAsIG56V2FybmluZ1RpcCwgbnpFcnJvclRpcCwgbnpWYWxpZGF0aW5nVGlwIH0gPSBjaGFuZ2VzO1xuXG4gICAgaWYgKG56RGlzYWJsZUF1dG9UaXBzIHx8IG56QXV0b1RpcHMpIHtcbiAgICAgIHRoaXMudXBkYXRlQXV0b0Vycm9yVGlwKCk7XG4gICAgICB0aGlzLnNldFN0YXR1cygpO1xuICAgIH0gZWxzZSBpZiAobnpTdWNjZXNzVGlwIHx8IG56V2FybmluZ1RpcCB8fCBuekVycm9yVGlwIHx8IG56VmFsaWRhdGluZ1RpcCkge1xuICAgICAgdGhpcy5zZXRTdGF0dXMoKTtcbiAgICB9XG4gIH1cblxuICBuZ09uSW5pdCgpOiB2b2lkIHtcbiAgICB0aGlzLnNldFN0YXR1cygpO1xuICB9XG5cbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgdGhpcy5kZXN0cm95ZWQkLm5leHQoKTtcbiAgICB0aGlzLmRlc3Ryb3llZCQuY29tcGxldGUoKTtcbiAgfVxuXG4gIG5nQWZ0ZXJDb250ZW50SW5pdCgpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMudmFsaWRhdGVDb250cm9sICYmICF0aGlzLnZhbGlkYXRlU3RyaW5nKSB7XG4gICAgICBpZiAodGhpcy5kZWZhdWx0VmFsaWRhdGVDb250cm9sIGluc3RhbmNlb2YgRm9ybUNvbnRyb2xEaXJlY3RpdmUpIHtcbiAgICAgICAgdGhpcy5uelZhbGlkYXRlU3RhdHVzID0gdGhpcy5kZWZhdWx0VmFsaWRhdGVDb250cm9sLmNvbnRyb2w7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLm56VmFsaWRhdGVTdGF0dXMgPSB0aGlzLmRlZmF1bHRWYWxpZGF0ZUNvbnRyb2whO1xuICAgICAgfVxuICAgIH1cbiAgfVxufVxuIl19