UNPKG

ng-zorro-antd

Version:

An enterprise-class UI components based on Ant Design and Angular

272 lines 35.7 kB
/** * 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: "15.1.0", 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: "14.0.0", version: "15.1.0", 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 @helpMotion 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, dependencies: [{ kind: "directive", type: i5.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", 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: "15.1.0", 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 @helpMotion 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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ZW50IjpbIi8qKlxuICogVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmVcbiAqIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgYXQgaHR0cHM6Ly9naXRodWIuY29tL05HLVpPUlJPL25nLXpvcnJvLWFudGQvYmxvYi9tYXN0ZXIvTElDRU5TRVxuICovXG5cbmltcG9ydCB7XG4gIEFmdGVyQ29udGVudEluaXQsXG4gIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LFxuICBDaGFuZ2VEZXRlY3RvclJlZixcbiAgQ29tcG9uZW50LFxuICBDb250ZW50Q2hpbGQsXG4gIEVsZW1lbnRSZWYsXG4gIEhvc3QsXG4gIElucHV0LFxuICBPbkNoYW5nZXMsXG4gIE9uRGVzdHJveSxcbiAgT25Jbml0LFxuICBPcHRpb25hbCxcbiAgUmVuZGVyZXIyLFxuICBTaW1wbGVDaGFuZ2VzLFxuICBUZW1wbGF0ZVJlZixcbiAgVmlld0VuY2Fwc3VsYXRpb25cbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBBYnN0cmFjdENvbnRyb2wsIEZvcm1Db250cm9sRGlyZWN0aXZlLCBGb3JtQ29udHJvbE5hbWUsIE5nQ29udHJvbCwgTmdNb2RlbCB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCB7IE9ic2VydmFibGUsIFN1YmplY3QsIFN1YnNjcmlwdGlvbiB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgZmlsdGVyLCBzdGFydFdpdGgsIHRha2VVbnRpbCwgdGFwIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuXG5pbXBvcnQgeyBoZWxwTW90aW9uIH0gZnJvbSAnbmctem9ycm8tYW50ZC9jb3JlL2FuaW1hdGlvbic7XG5pbXBvcnQgeyBOekZvcm1TdGF0dXNTZXJ2aWNlIH0gZnJvbSAnbmctem9ycm8tYW50ZC9jb3JlL2Zvcm0nO1xuaW1wb3J0IHsgQm9vbGVhbklucHV0LCBOelNhZmVBbnkgfSBmcm9tICduZy16b3Jyby1hbnRkL2NvcmUvdHlwZXMnO1xuaW1wb3J0IHsgdG9Cb29sZWFuIH0gZnJvbSAnbmctem9ycm8tYW50ZC9jb3JlL3V0aWwnO1xuaW1wb3J0IHsgTnpJMThuU2VydmljZSB9IGZyb20gJ25nLXpvcnJvLWFudGQvaTE4bic7XG5cbmltcG9ydCB7IE56Rm9ybUNvbnRyb2xTdGF0dXNUeXBlLCBOekZvcm1JdGVtQ29tcG9uZW50IH0gZnJvbSAnLi9mb3JtLWl0ZW0uY29tcG9uZW50JztcbmltcG9ydCB7IE56Rm9ybURpcmVjdGl2ZSB9IGZyb20gJy4vZm9ybS5kaXJlY3RpdmUnO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICduei1mb3JtLWNvbnRyb2wnLFxuICBleHBvcnRBczogJ256Rm9ybUNvbnRyb2wnLFxuICBwcmVzZXJ2ZVdoaXRlc3BhY2VzOiBmYWxzZSxcbiAgYW5pbWF0aW9uczogW2hlbHBNb3Rpb25dLFxuICBlbmNhcHN1bGF0aW9uOiBWaWV3RW5jYXBzdWxhdGlvbi5Ob25lLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbiAgdGVtcGxhdGU6IGBcbiAgICA8ZGl2IGNsYXNzPVwiYW50LWZvcm0taXRlbS1jb250cm9sLWlucHV0XCI+XG4gICAgICA8ZGl2IGNsYXNzPVwiYW50LWZvcm0taXRlbS1jb250cm9sLWlucHV0LWNvbnRlbnRcIj5cbiAgICAgICAgPG5nLWNvbnRlbnQ+PC9uZy1jb250ZW50PlxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG4gICAgPGRpdiBAaGVscE1vdGlvbiBjbGFzcz1cImFudC1mb3JtLWl0ZW0tZXhwbGFpbiBhbnQtZm9ybS1pdGVtLWV4cGxhaW4tY29ubmVjdGVkXCIgKm5nSWY9XCJpbm5lclRpcFwiPlxuICAgICAgPGRpdiByb2xlPVwiYWxlcnRcIiBbbmdDbGFzc109XCJbJ2FudC1mb3JtLWl0ZW0tZXhwbGFpbi0nICsgc3RhdHVzXVwiPlxuICAgICAgICA8bmctY29udGFpbmVyICpuelN0cmluZ1RlbXBsYXRlT3V0bGV0PVwiaW5uZXJUaXA7IGNvbnRleHQ6IHsgJGltcGxpY2l0OiB2YWxpZGF0ZUNvbnRyb2wgfVwiPnt7XG4gICAgICAgICAgaW5uZXJUaXBcbiAgICAgICAgfX08L25nLWNvbnRhaW5lcj5cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuICAgIDxkaXYgY2xhc3M9XCJhbnQtZm9ybS1pdGVtLWV4dHJhXCIgKm5nSWY9XCJuekV4dHJhXCI+XG4gICAgICA8bmctY29udGFpbmVyICpuelN0cmluZ1RlbXBsYXRlT3V0bGV0PVwibnpFeHRyYVwiPnt7IG56RXh0cmEgfX08L25nLWNvbnRhaW5lcj5cbiAgICA8L2Rpdj5cbiAgYCxcbiAgcHJvdmlkZXJzOiBbTnpGb3JtU3RhdHVzU2VydmljZV1cbn0pXG5leHBvcnQgY2xhc3MgTnpGb3JtQ29udHJvbENvbXBvbmVudCBpbXBsZW1lbnRzIE9uQ2hhbmdlcywgT25EZXN0cm95LCBPbkluaXQsIEFmdGVyQ29udGVudEluaXQsIE9uRGVzdHJveSB7XG4gIHN0YXRpYyBuZ0FjY2VwdElucHV0VHlwZV9uekhhc0ZlZWRiYWNrOiBCb29sZWFuSW5wdXQ7XG4gIHN0YXRpYyBuZ0FjY2VwdElucHV0VHlwZV9uelJlcXVpcmVkOiBCb29sZWFuSW5wdXQ7XG4gIHN0YXRpYyBuZ0FjY2VwdElucHV0VHlwZV9uek5vQ29sb246IEJvb2xlYW5JbnB1dDtcbiAgc3RhdGljIG5nQWNjZXB0SW5wdXRUeXBlX256RGlzYWJsZUF1dG9UaXBzOiBCb29sZWFuSW5wdXQ7XG5cbiAgcHJpdmF0ZSBfaGFzRmVlZGJhY2sgPSBmYWxzZTtcbiAgcHJpdmF0ZSB2YWxpZGF0ZUNoYW5nZXM6IFN1YnNjcmlwdGlvbiA9IFN1YnNjcmlwdGlvbi5FTVBUWTtcbiAgcHJpdmF0ZSB2YWxpZGF0ZVN0cmluZzogc3RyaW5nIHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgZGVzdHJveWVkJCA9IG5ldyBTdWJqZWN0PHZvaWQ+KCk7XG4gIHByaXZhdGUgbG9jYWxlSWQhOiBzdHJpbmc7XG4gIHByaXZhdGUgYXV0b0Vycm9yVGlwPzogc3RyaW5nO1xuXG4gIHByaXZhdGUgZ2V0IGRpc2FibGVBdXRvVGlwcygpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5uekRpc2FibGVBdXRvVGlwcyAhPT0gJ2RlZmF1bHQnXG4gICAgICA/IHRvQm9vbGVhbih0aGlzLm56RGlzYWJsZUF1dG9UaXBzKVxuICAgICAgOiB0aGlzLm56Rm9ybURpcmVjdGl2ZT8ubnpEaXNhYmxlQXV0b1RpcHM7XG4gIH1cblxuICBzdGF0dXM6IE56Rm9ybUNvbnRyb2xTdGF0dXNUeXBlID0gJyc7XG4gIHZhbGlkYXRlQ29udHJvbDogQWJzdHJhY3RDb250cm9sIHwgTmdNb2RlbCB8IG51bGwgPSBudWxsO1xuICBpbm5lclRpcDogc3RyaW5nIHwgVGVtcGxhdGVSZWY8eyAkaW1wbGljaXQ6IEFic3RyYWN0Q29udHJvbCB8IE5nTW9kZWwgfT4gfCBudWxsID0gbnVsbDtcblxuICBAQ29udGVudENoaWxkKE5nQ29udHJvbCwgeyBzdGF0aWM6IGZhbHNlIH0pIGRlZmF1bHRWYWxpZGF0ZUNvbnRyb2w/OiBGb3JtQ29udHJvbE5hbWUgfCBGb3JtQ29udHJvbERpcmVjdGl2ZTtcbiAgQElucHV0KCkgbnpTdWNjZXNzVGlwPzogc3RyaW5nIHwgVGVtcGxhdGVSZWY8eyAkaW1wbGljaXQ6IEFic3RyYWN0Q29udHJvbCB8IE5nTW9kZWwgfT47XG4gIEBJbnB1dCgpIG56V2FybmluZ1RpcD86IHN0cmluZyB8IFRlbXBsYXRlUmVmPHsgJGltcGxpY2l0OiBBYnN0cmFjdENvbnRyb2wgfCBOZ01vZGVsIH0+O1xuICBASW5wdXQoKSBuekVycm9yVGlwPzogc3RyaW5nIHwgVGVtcGxhdGVSZWY8eyAkaW1wbGljaXQ6IEFic3RyYWN0Q29udHJvbCB8IE5nTW9kZWwgfT47XG4gIEBJbnB1dCgpIG56VmFsaWRhdGluZ1RpcD86IHN0cmluZyB8IFRlbXBsYXRlUmVmPHsgJGltcGxpY2l0OiBBYnN0cmFjdENvbnRyb2wgfCBOZ01vZGVsIH0+O1xuICBASW5wdXQoKSBuekV4dHJhPzogc3RyaW5nIHwgVGVtcGxhdGVSZWY8dm9pZD47XG4gIEBJbnB1dCgpIG56QXV0b1RpcHM6IFJlY29yZDxzdHJpbmcsIFJlY29yZDxzdHJpbmcsIHN0cmluZz4+ID0ge307XG4gIEBJbnB1dCgpIG56RGlzYWJsZUF1dG9UaXBzOiBib29sZWFuIHwgJ2RlZmF1bHQnID0gJ2RlZmF1bHQnO1xuXG4gIEBJbnB1dCgpXG4gIHNldCBuekhhc0ZlZWRiYWNrKHZhbHVlOiBib29sZWFuKSB7XG4gICAgdGhpcy5faGFzRmVlZGJhY2sgPSB0b0Jvb2xlYW4odmFsdWUpO1xuICAgIHRoaXMubnpGb3JtU3RhdHVzU2VydmljZS5mb3JtU3RhdHVzQ2hhbmdlcy5uZXh0KHsgc3RhdHVzOiB0aGlzLnN0YXR1cywgaGFzRmVlZGJhY2s6IHRoaXMuX2hhc0ZlZWRiYWNrIH0pO1xuICAgIGlmICh0aGlzLm56Rm9ybUl0ZW1Db21wb25lbnQpIHtcbiAgICAgIHRoaXMubnpGb3JtSXRlbUNvbXBvbmVudC5zZXRIYXNGZWVkYmFjayh0aGlzLl9oYXNGZWVkYmFjayk7XG4gICAgfVxuICB9XG5cbiAgZ2V0IG56SGFzRmVlZGJhY2soKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuX2hhc0ZlZWRiYWNrO1xuICB9XG5cbiAgQElucHV0KClcbiAgc2V0IG56VmFsaWRhdGVTdGF0dXModmFsdWU6IHN0cmluZyB8IEFic3RyYWN0Q29udHJvbCB8IEZvcm1Db250cm9sTmFtZSB8IE5nTW9kZWwpIHtcbiAgICBpZiAodmFsdWUgaW5zdGFuY2VvZiBBYnN0cmFjdENvbnRyb2wgfHwgdmFsdWUgaW5zdGFuY2VvZiBOZ01vZGVsKSB7XG4gICAgICB0aGlzLnZhbGlkYXRlQ29udHJvbCA9IHZhbHVlO1xuICAgICAgdGhpcy52YWxpZGF0ZVN0cmluZyA9IG51bGw7XG4gICAgICB0aGlzLndhdGNoQ29udHJvbCgpO1xuICAgIH0gZWxzZSBpZiAodmFsdWUgaW5zdGFuY2VvZiBGb3JtQ29udHJvbE5hbWUpIHtcbiAgICAgIHRoaXMudmFsaWRhdGVDb250cm9sID0gdmFsdWUuY29udHJvbDtcbiAgICAgIHRoaXMudmFsaWRhdGVTdHJpbmcgPSBudWxsO1xuICAgICAgdGhpcy53YXRjaENvbnRyb2woKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy52YWxpZGF0ZVN0cmluZyA9IHZhbHVlO1xuICAgICAgdGhpcy52YWxpZGF0ZUNvbnRyb2wgPSBudWxsO1xuICAgICAgdGhpcy5zZXRTdGF0dXMoKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHdhdGNoQ29udHJvbCgpOiB2b2lkIHtcbiAgICB0aGlzLnZhbGlkYXRlQ2hhbmdlcy51bnN1YnNjcmliZSgpO1xuICAgIC8qKiBtaXNzIGRldGVjdCBodHRwczovL2dpdGh1Yi5jb20vYW5ndWxhci9hbmd1bGFyL2lzc3Vlcy8xMDg4NyAqKi9cbiAgICBpZiAodGhpcy52YWxpZGF0ZUNvbnRyb2wgJiYgdGhpcy52YWxpZGF0ZUNvbnRyb2wuc3RhdHVzQ2hhbmdlcykge1xuICAgICAgdGhpcy52YWxpZGF0ZUNoYW5nZXMgPSAodGhpcy52YWxpZGF0ZUNvbnRyb2wuc3RhdHVzQ2hhbmdlcyBhcyBPYnNlcnZhYmxlPE56U2FmZUFueT4pXG4gICAgICAgIC5waXBlKHN0YXJ0V2l0aChudWxsKSwgdGFrZVVudGlsKHRoaXMuZGVzdHJveWVkJCkpXG4gICAgICAgIC5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgICAgIGlmICghdGhpcy5kaXNhYmxlQXV0b1RpcHMpIHtcbiAgICAgICAgICAgIHRoaXMudXBkYXRlQXV0b0Vycm9yVGlwKCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHRoaXMuc2V0U3RhdHVzKCk7XG4gICAgICAgICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgc2V0U3RhdHVzKCk6IHZvaWQge1xuICAgIHRoaXMuc3RhdHVzID0gdGhpcy5nZXRDb250cm9sU3RhdHVzKHRoaXMudmFsaWRhdGVTdHJpbmcpO1xuICAgIHRoaXMuaW5uZXJUaXAgPSB0aGlzLmdldElubmVyVGlwKHRoaXMuc3RhdHVzKTtcbiAgICB0aGlzLm56Rm9ybVN0YXR1c1NlcnZpY2UuZm9ybVN0YXR1c0NoYW5nZXMubmV4dCh7IHN0YXR1czogdGhpcy5zdGF0dXMsIGhhc0ZlZWRiYWNrOiB0aGlzLm56SGFzRmVlZGJhY2sgfSk7XG4gICAgaWYgKHRoaXMubnpGb3JtSXRlbUNvbXBvbmVudCkge1xuICAgICAgdGhpcy5uekZvcm1JdGVtQ29tcG9uZW50LnNldFdpdGhIZWxwVmlhVGlwcyghIXRoaXMuaW5uZXJUaXApO1xuICAgICAgdGhpcy5uekZvcm1JdGVtQ29tcG9uZW50LnNldFN0YXR1cyh0aGlzLnN0YXR1cyk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBnZXRDb250cm9sU3RhdHVzKHZhbGlkYXRlU3RyaW5nOiBzdHJpbmcgfCBudWxsKTogTnpGb3JtQ29udHJvbFN0YXR1c1R5cGUge1xuICAgIGxldCBzdGF0dXM6IE56Rm9ybUNvbnRyb2xTdGF0dXNUeXBlO1xuXG4gICAgaWYgKHZhbGlkYXRlU3RyaW5nID09PSAnd2FybmluZycgfHwgdGhpcy52YWxpZGF0ZUNvbnRyb2xTdGF0dXMoJ0lOVkFMSUQnLCAnd2FybmluZycpKSB7XG4gICAgICBzdGF0dXMgPSAnd2FybmluZyc7XG4gICAgfSBlbHNlIGlmICh2YWxpZGF0ZVN0cmluZyA9PT0gJ2Vycm9yJyB8fCB0aGlzLnZhbGlkYXRlQ29udHJvbFN0YXR1cygnSU5WQUxJRCcpKSB7XG4gICAgICBzdGF0dXMgPSAnZXJyb3InO1xuICAgIH0gZWxzZSBpZiAoXG4gICAgICB2YWxpZGF0ZVN0cmluZyA9PT0gJ3ZhbGlkYXRpbmcnIHx8XG4gICAgICB2YWxpZGF0ZVN0cmluZyA9PT0gJ3BlbmRpbmcnIHx8XG4gICAgICB0aGlzLnZhbGlkYXRlQ29udHJvbFN0YXR1cygnUEVORElORycpXG4gICAgKSB7XG4gICAgICBzdGF0dXMgPSAndmFsaWRhdGluZyc7XG4gICAgfSBlbHNlIGlmICh2YWxpZGF0ZVN0cmluZyA9PT0gJ3N1Y2Nlc3MnIHx8IHRoaXMudmFsaWRhdGVDb250cm9sU3RhdHVzKCdWQUxJRCcpKSB7XG4gICAgICBzdGF0dXMgPSAnc3VjY2Vzcyc7XG4gICAgfSBlbHNlIHtcbiAgICAgIHN0YXR1cyA9ICcnO1xuICAgIH1cblxuICAgIHJldHVybiBzdGF0dXM7XG4gIH1cblxuICBwcml2YXRlIHZhbGlkYXRlQ29udHJvbFN0YXR1cyh2YWxpZFN0YXR1czogc3RyaW5nLCBzdGF0dXNUeXBlPzogTnpGb3JtQ29udHJvbFN0YXR1c1R5cGUpOiBib29sZWFuIHtcbiAgICBpZiAoIXRoaXMudmFsaWRhdGVDb250cm9sKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IHsgZGlydHksIHRvdWNoZWQsIHN0YXR1cyB9ID0gdGhpcy52YWxpZGF0ZUNvbnRyb2w7XG4gICAgICByZXR1cm4gKFxuICAgICAgICAoISFkaXJ0eSB8fCAhIXRvdWNoZWQpICYmIChzdGF0dXNUeXBlID8gdGhpcy52YWxpZGF0ZUNvbnRyb2wuaGFzRXJyb3Ioc3RhdHVzVHlwZSkgOiBzdGF0dXMgPT09IHZhbGlkU3RhdHVzKVxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGdldElubmVyVGlwKFxuICAgIHN0YXR1czogTnpGb3JtQ29udHJvbFN0YXR1c1R5cGVcbiAgKTogc3RyaW5nIHwgVGVtcGxhdGVSZWY8eyAkaW1wbGljaXQ6IEFic3RyYWN0Q29udHJvbCB8IE5nTW9kZWwgfT4gfCBudWxsIHtcbiAgICBzd2l0Y2ggKHN0YXR1cykge1xuICAgICAgY2FzZSAnZXJyb3InOlxuICAgICAgICByZXR1cm4gKCF0aGlzLmRpc2FibGVBdXRvVGlwcyAmJiB0aGlzLmF1dG9FcnJvclRpcCkgfHwgdGhpcy5uekVycm9yVGlwIHx8IG51bGw7XG4gICAgICBjYXNlICd2YWxpZGF0aW5nJzpcbiAgICAgICAgcmV0dXJuIHRoaXMubnpWYWxpZGF0aW5nVGlwIHx8IG51bGw7XG4gICAgICBjYXNlICdzdWNjZXNzJzpcbiAgICAgICAgcmV0dXJuIHRoaXMubnpTdWNjZXNzVGlwIHx8IG51bGw7XG4gICAgICBjYXNlICd3YXJuaW5nJzpcbiAgICAgICAgcmV0dXJuIHRoaXMubnpXYXJuaW5nVGlwIHx8IG51bGw7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHVwZGF0ZUF1dG9FcnJvclRpcCgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy52YWxpZGF0ZUNvbnRyb2wpIHtcbiAgICAgIGNvbnN0IGVycm9ycyA9IHRoaXMudmFsaWRhdGVDb250cm9sLmVycm9ycyB8fCB7fTtcbiAgICAgIGxldCBhdXRvRXJyb3JUaXAgPSAnJztcbiAgICAgIGZvciAoY29uc3Qga2V5IGluIGVycm9ycykge1xuICAgICAgICBpZiAoZXJyb3JzLmhhc093blByb3BlcnR5KGtleSkpIHtcbiAgICAgICAgICBhdXRvRXJyb3JUaXAgPVxuICAgICAgICAgICAgZXJyb3JzW2tleV0/Llt0aGlzLmxvY2FsZUlkXSA/P1xuICAgICAgICAgICAgdGhpcy5uekF1dG9UaXBzPy5bdGhpcy5sb2NhbGVJZF0/LltrZXldID8/XG4gICAgICAgICAgICB0aGlzLm56QXV0b1RpcHMuZGVmYXVsdD8uW2tleV0gPz9cbiAgICAgICAgICAgIHRoaXMubnpGb3JtRGlyZWN0aXZlPy5uekF1dG9UaXBzPy5bdGhpcy5sb2NhbGVJZF0/LltrZXldID8/XG4gICAgICAgICAgICB0aGlzLm56Rm9ybURpcmVjdGl2ZT8ubnpBdXRvVGlwcy5kZWZhdWx0Py5ba2V5XTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoISFhdXRvRXJyb3JUaXApIHtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgdGhpcy5hdXRvRXJyb3JUaXAgPSBhdXRvRXJyb3JUaXA7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBzdWJzY3JpYmVBdXRvVGlwcyhvYnNlcnZhYmxlOiBPYnNlcnZhYmxlPE56U2FmZUFueT4pOiB2b2lkIHtcbiAgICBvYnNlcnZhYmxlPy5waXBlKHRha2VVbnRpbCh0aGlzLmRlc3Ryb3llZCQpKS5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgaWYgKCF0aGlzLmRpc2FibGVBdXRvVGlwcykge1xuICAgICAgICB0aGlzLnVwZGF0ZUF1dG9FcnJvclRpcCgpO1xuICAgICAgICB0aGlzLnNldFN0YXR1cygpO1xuICAgICAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIGNvbnN0cnVjdG9yKFxuICAgIGVsZW1lbnRSZWY6IEVsZW1lbnRSZWYsXG4gICAgQE9wdGlvbmFsKCkgQEhvc3QoKSBwcml2YXRlIG56Rm9ybUl0ZW1Db21wb25lbnQ6IE56Rm9ybUl0ZW1Db21wb25lbnQsXG4gICAgcHJpdmF0ZSBjZHI6IENoYW5nZURldGVjdG9yUmVmLFxuICAgIHJlbmRlcmVyOiBSZW5kZXJlcjIsXG4gICAgaTE4bjogTnpJMThuU2VydmljZSxcbiAgICBAT3B0aW9uYWwoKSBwcml2YXRlIG56Rm9ybURpcmVjdGl2ZTogTnpGb3JtRGlyZWN0aXZlLFxuICAgIHByaXZhdGUgbnpGb3JtU3RhdHVzU2VydmljZTogTnpGb3JtU3RhdHVzU2VydmljZVxuICApIHtcbiAgICByZW5kZXJlci5hZGRDbGFzcyhlbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQsICdhbnQtZm9ybS1pdGVtLWNvbnRyb2wnKTtcblxuICAgIHRoaXMuc3Vic2NyaWJlQXV0b1RpcHMoaTE4bi5sb2NhbGVDaGFuZ2UucGlwZSh0YXAobG9jYWxlID0+ICh0aGlzLmxvY2FsZUlkID0gbG9jYWxlLmxvY2FsZSkpKSk7XG4gICAgdGhpcy5zdWJzY3JpYmVBdXRvVGlwcyh0aGlzLm56Rm9ybURpcmVjdGl2ZT8uZ2V0SW5wdXRPYnNlcnZhYmxlKCduekF1dG9UaXBzJykpO1xuICAgIHRoaXMuc3Vic2NyaWJlQXV0b1RpcHMoXG4gICAgICB0aGlzLm56Rm9ybURpcmVjdGl2ZVxuICAgICAgICA/LmdldElucHV0T2JzZXJ2YWJsZSgnbnpEaXNhYmxlQXV0b1RpcHMnKVxuICAgICAgICAucGlwZShmaWx0ZXIoKCkgPT4gdGhpcy5uekRpc2FibGVBdXRvVGlwcyA9PT0gJ2RlZmF1bHQnKSlcbiAgICApO1xuICB9XG5cbiAgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcyk6IHZvaWQge1xuICAgIGNvbnN0IHsgbnpEaXNhYmxlQXV0b1RpcHMsIG56QXV0b1RpcHMsIG56U3VjY2Vzc1RpcCwgbnpXYXJuaW5nVGlwLCBuekVycm9yVGlwLCBuelZhbGlkYXRpbmdUaXAgfSA9IGNoYW5nZXM7XG5cbiAgICBpZiAobnpEaXNhYmxlQXV0b1RpcHMgfHwgbnpBdXRvVGlwcykge1xuICAgICAgdGhpcy51cGRhdGVBdXRvRXJyb3JUaXAoKTtcbiAgICAgIHRoaXMuc2V0U3RhdHVzKCk7XG4gICAgfSBlbHNlIGlmIChuelN1Y2Nlc3NUaXAgfHwgbnpXYXJuaW5nVGlwIHx8IG56RXJyb3JUaXAgfHwgbnpWYWxpZGF0aW5nVGlwKSB7XG4gICAgICB0aGlzLnNldFN0YXR1cygpO1xuICAgIH1cbiAgfVxuXG4gIG5nT25Jbml0KCk6IHZvaWQge1xuICAgIHRoaXMuc2V0U3RhdHVzKCk7XG4gIH1cblxuICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICB0aGlzLmRlc3Ryb3llZCQubmV4dCgpO1xuICAgIHRoaXMuZGVzdHJveWVkJC5jb21wbGV0ZSgpO1xuICB9XG5cbiAgbmdBZnRlckNvbnRlbnRJbml0KCk6IHZvaWQge1xuICAgIGlmICghdGhpcy52YWxpZGF0ZUNvbnRyb2wgJiYgIXRoaXMudmFsaWRhdGVTdHJpbmcpIHtcbiAgICAgIGlmICh0aGlzLmRlZmF1bHRWYWxpZGF0ZUNvbnRyb2wgaW5zdGFuY2VvZiBGb3JtQ29udHJvbERpcmVjdGl2ZSkge1xuICAgICAgICB0aGlzLm56VmFsaWRhdGVTdGF0dXMgPSB0aGlzLmRlZmF1bHRWYWxpZGF0ZUNvbnRyb2wuY29udHJvbDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMubnpWYWxpZGF0ZVN0YXR1cyA9IHRoaXMuZGVmYXVsdFZhbGlkYXRlQ29udHJvbCE7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG4iXX0=