ng-zorro-antd
Version:
An enterprise-class UI components based on Ant Design and Angular
195 lines (193 loc) • 27.3 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 { ENTER, ESCAPE } from '@angular/cdk/keycodes';
import { NgIf } from '@angular/common';
import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output, ViewChild, ViewEncapsulation } from '@angular/core';
import { BehaviorSubject, EMPTY, from, fromEvent, Observable } from 'rxjs';
import { switchMap, take, takeUntil, withLatestFrom } from 'rxjs/operators';
import { NzOutletModule } from 'ng-zorro-antd/core/outlet';
import { NzDestroyService } from 'ng-zorro-antd/core/services';
import { NzTransButtonModule } from 'ng-zorro-antd/core/trans-button';
import { NzIconModule } from 'ng-zorro-antd/icon';
import { NzAutosizeDirective, NzInputModule } from 'ng-zorro-antd/input';
import { NzToolTipModule } from 'ng-zorro-antd/tooltip';
import * as i0 from "@angular/core";
import * as i1 from "ng-zorro-antd/i18n";
import * as i2 from "ng-zorro-antd/core/services";
import * as i3 from "ng-zorro-antd/input";
import * as i4 from "ng-zorro-antd/core/trans-button";
import * as i5 from "ng-zorro-antd/icon";
import * as i6 from "ng-zorro-antd/tooltip";
import * as i7 from "ng-zorro-antd/core/outlet";
export class NzTextEditComponent {
set textarea(textarea) {
this.textarea$.next(textarea);
}
constructor(ngZone, host, cdr, i18n, destroy$) {
this.ngZone = ngZone;
this.host = host;
this.cdr = cdr;
this.i18n = i18n;
this.destroy$ = destroy$;
this.editing = false;
this.icon = 'edit';
this.startEditing = new EventEmitter();
this.endEditing = new EventEmitter(true);
this.nativeElement = this.host.nativeElement;
// We could've saved the textarea within some private property (e.g. `_textarea`) and have a getter,
// but having subject makes the code more reactive and cancellable (e.g. event listeners will be
// automatically removed and re-added through the `switchMap` below).
this.textarea$ = new BehaviorSubject(null);
}
ngOnInit() {
this.i18n.localeChange.pipe(takeUntil(this.destroy$)).subscribe(() => {
this.locale = this.i18n.getLocaleData('Text');
this.cdr.markForCheck();
});
this.textarea$
.pipe(switchMap(textarea =>
// Caretaker note: we explicitly should call `subscribe()` within the root zone.
// `runOutsideAngular(() => fromEvent(...))` will just create an observable within the root zone,
// but `addEventListener` is called when the `fromEvent` is subscribed.
textarea
? new Observable(subscriber => this.ngZone.runOutsideAngular(() => fromEvent(textarea.nativeElement, 'keydown').subscribe(subscriber)))
: EMPTY), takeUntil(this.destroy$))
.subscribe(event => {
// Caretaker note: adding modifier at the end (for instance `(keydown.esc)`) will tell Angular to add
// an event listener through the `KeyEventsPlugin`, which always runs `ngZone.runGuarded()` internally.
// We're interested only in escape and enter keyboard buttons, otherwise Angular will run change detection
// on any `keydown` event.
if (event.keyCode !== ESCAPE && event.keyCode !== ENTER) {
return;
}
this.ngZone.run(() => {
if (event.keyCode === ESCAPE) {
this.onCancel();
}
else {
this.onEnter(event);
}
this.cdr.markForCheck();
});
});
this.textarea$
.pipe(switchMap(textarea => textarea
? new Observable(subscriber => this.ngZone.runOutsideAngular(() => fromEvent(textarea.nativeElement, 'input').subscribe(subscriber)))
: EMPTY), takeUntil(this.destroy$))
.subscribe(event => {
this.currentText = event.target.value;
});
}
onClick() {
this.beforeText = this.text;
this.currentText = this.beforeText;
this.editing = true;
this.startEditing.emit();
this.focusAndSetValue();
}
confirm() {
this.editing = false;
this.endEditing.emit(this.currentText);
}
onEnter(event) {
event.stopPropagation();
event.preventDefault();
this.confirm();
}
onCancel() {
this.currentText = this.beforeText;
this.confirm();
}
focusAndSetValue() {
// Note: the zone may be nooped through `BootstrapOptions` when bootstrapping the root module. This means
// the `onStable` will never emit any value.
const onStable$ = this.ngZone.isStable ? from(Promise.resolve()) : this.ngZone.onStable.pipe(take(1));
// Normally this isn't in the zone, but it can cause performance regressions for apps
// using `zone-patch-rxjs` because it'll trigger a change detection when it unsubscribes.
this.ngZone.runOutsideAngular(() => {
onStable$.pipe(withLatestFrom(this.textarea$), takeUntil(this.destroy$)).subscribe(([, textarea]) => {
if (textarea) {
textarea.nativeElement.focus();
textarea.nativeElement.value = this.currentText || '';
this.autosizeDirective.resizeToFitContent();
this.cdr.markForCheck();
}
});
});
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.7", ngImport: i0, type: NzTextEditComponent, deps: [{ token: i0.NgZone }, { token: i0.ElementRef }, { token: i0.ChangeDetectorRef }, { token: i1.NzI18nService }, { token: i2.NzDestroyService }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.0.7", type: NzTextEditComponent, isStandalone: true, selector: "nz-text-edit", inputs: { text: "text", icon: "icon", tooltip: "tooltip" }, outputs: { startEditing: "startEditing", endEditing: "endEditing" }, providers: [NzDestroyService], viewQueries: [{ propertyName: "textarea", first: true, predicate: ["textarea"], descendants: true }, { propertyName: "autosizeDirective", first: true, predicate: NzAutosizeDirective, descendants: true }], exportAs: ["nzTextEdit"], ngImport: i0, template: `
<ng-template [ngIf]="editing" [ngIfElse]="notEditing">
<textarea #textarea nz-input nzAutosize (blur)="confirm()"></textarea>
<button nz-trans-button class="ant-typography-edit-content-confirm" (click)="confirm()">
<span nz-icon nzType="enter"></span>
</button>
</ng-template>
<ng-template #notEditing>
<button
nz-tooltip
nz-trans-button
class="ant-typography-edit"
[nzTooltipTitle]="tooltip === null ? null : tooltip || locale?.edit"
(click)="onClick()"
>
<ng-container *nzStringTemplateOutlet="icon; let icon">
<span nz-icon [nzType]="icon"></span>
</ng-container>
</button>
</ng-template>
`, isInline: true, dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: NzInputModule }, { kind: "directive", type: i3.NzInputDirective, selector: "input[nz-input],textarea[nz-input]", inputs: ["nzBorderless", "nzSize", "nzStepperless", "nzStatus", "disabled"], exportAs: ["nzInput"] }, { kind: "directive", type: i3.NzAutosizeDirective, selector: "textarea[nzAutosize]", inputs: ["nzAutosize"], exportAs: ["nzAutosize"] }, { kind: "ngmodule", type: NzTransButtonModule }, { kind: "directive", type: i4.NzTransButtonDirective, selector: "button[nz-trans-button]" }, { kind: "ngmodule", type: NzIconModule }, { kind: "directive", type: i5.NzIconDirective, selector: "[nz-icon]", inputs: ["nzSpin", "nzRotate", "nzType", "nzTheme", "nzTwotoneColor", "nzIconfont"], exportAs: ["nzIcon"] }, { kind: "ngmodule", type: NzToolTipModule }, { kind: "directive", type: i6.NzTooltipDirective, selector: "[nz-tooltip]", inputs: ["nzTooltipTitle", "nzTooltipTitleContext", "nz-tooltip", "nzTooltipTrigger", "nzTooltipPlacement", "nzTooltipOrigin", "nzTooltipVisible", "nzTooltipMouseEnterDelay", "nzTooltipMouseLeaveDelay", "nzTooltipOverlayClassName", "nzTooltipOverlayStyle", "nzTooltipArrowPointAtCenter", "cdkConnectedOverlayPush", "nzTooltipColor"], outputs: ["nzTooltipVisibleChange"], exportAs: ["nzTooltip"] }, { kind: "ngmodule", type: NzOutletModule }, { kind: "directive", type: i7.NzStringTemplateOutletDirective, selector: "[nzStringTemplateOutlet]", inputs: ["nzStringTemplateOutletContext", "nzStringTemplateOutlet"], exportAs: ["nzStringTemplateOutlet"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.7", ngImport: i0, type: NzTextEditComponent, decorators: [{
type: Component,
args: [{
selector: 'nz-text-edit',
exportAs: 'nzTextEdit',
template: `
<ng-template [ngIf]="editing" [ngIfElse]="notEditing">
<textarea #textarea nz-input nzAutosize (blur)="confirm()"></textarea>
<button nz-trans-button class="ant-typography-edit-content-confirm" (click)="confirm()">
<span nz-icon nzType="enter"></span>
</button>
</ng-template>
<ng-template #notEditing>
<button
nz-tooltip
nz-trans-button
class="ant-typography-edit"
[nzTooltipTitle]="tooltip === null ? null : tooltip || locale?.edit"
(click)="onClick()"
>
<ng-container *nzStringTemplateOutlet="icon; let icon">
<span nz-icon [nzType]="icon"></span>
</ng-container>
</button>
</ng-template>
`,
changeDetection: ChangeDetectionStrategy.OnPush,
encapsulation: ViewEncapsulation.None,
preserveWhitespaces: false,
providers: [NzDestroyService],
imports: [NgIf, NzInputModule, NzTransButtonModule, NzIconModule, NzToolTipModule, NzOutletModule],
standalone: true
}]
}], ctorParameters: () => [{ type: i0.NgZone }, { type: i0.ElementRef }, { type: i0.ChangeDetectorRef }, { type: i1.NzI18nService }, { type: i2.NzDestroyService }], propDecorators: { text: [{
type: Input
}], icon: [{
type: Input
}], tooltip: [{
type: Input
}], startEditing: [{
type: Output
}], endEditing: [{
type: Output
}], textarea: [{
type: ViewChild,
args: ['textarea', { static: false }]
}], autosizeDirective: [{
type: ViewChild,
args: [NzAutosizeDirective, { static: false }]
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGV4dC1lZGl0LmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL2NvbXBvbmVudHMvdHlwb2dyYXBoeS90ZXh0LWVkaXQuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7R0FHRztBQUVILE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDdEQsT0FBTyxFQUFFLElBQUksRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQ3ZDLE9BQU8sRUFDTCx1QkFBdUIsRUFFdkIsU0FBUyxFQUVULFlBQVksRUFDWixLQUFLLEVBR0wsTUFBTSxFQUNOLFNBQVMsRUFDVCxpQkFBaUIsRUFDbEIsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLGVBQWUsRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxVQUFVLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDM0UsT0FBTyxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUUsU0FBUyxFQUFFLGNBQWMsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRTVFLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUMzRCxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUMvRCxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUd0RSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDbEQsT0FBTyxFQUFFLG1CQUFtQixFQUFFLGFBQWEsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQ3pFLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQzs7Ozs7Ozs7O0FBa0N4RCxNQUFNLE9BQU8sbUJBQW1CO0lBUzlCLElBQ0ksUUFBUSxDQUFDLFFBQXFEO1FBQ2hFLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxD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S0FBSztvQkFDMUIsU0FBUyxFQUFFLENBQUMsZ0JBQWdCLENBQUM7b0JBQzdCLE9BQU8sRUFBRSxDQUFDLElBQUksRUFBRSxhQUFhLEVBQUUsbUJBQW1CLEVBQUUsWUFBWSxFQUFFLGVBQWUsRUFBRSxjQUFjLENBQUM7b0JBQ2xHLFVBQVUsRUFBRSxJQUFJO2lCQUNqQjsrTEFLVSxJQUFJO3NCQUFaLEtBQUs7Z0JBQ0csSUFBSTtzQkFBWixLQUFLO2dCQUNHLE9BQU87c0JBQWYsS0FBSztnQkFDYSxZQUFZO3NCQUE5QixNQUFNO2dCQUNZLFVBQVU7c0JBQTVCLE1BQU07Z0JBRUgsUUFBUTtzQkFEWCxTQUFTO3VCQUFDLFVBQVUsRUFBRSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUU7Z0JBSVcsaUJBQWlCO3NCQUFuRSxTQUFTO3VCQUFDLG1CQUFtQixFQUFFLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmVcbiAqIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgYXQgaHR0cHM6Ly9naXRodWIuY29tL05HLVpPUlJPL25nLXpvcnJvLWFudGQvYmxvYi9tYXN0ZXIvTElDRU5TRVxuICovXG5cbmltcG9ydCB7IEVOVEVSLCBFU0NBUEUgfSBmcm9tICdAYW5ndWxhci9jZGsva2V5Y29kZXMnO1xuaW1wb3J0IHsgTmdJZiB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQge1xuICBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSxcbiAgQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gIENvbXBvbmVudCxcbiAgRWxlbWVudFJlZixcbiAgRXZlbnRFbWl0dGVyLFxuICBJbnB1dCxcbiAgTmdab25lLFxuICBPbkluaXQsXG4gIE91dHB1dCxcbiAgVmlld0NoaWxkLFxuICBWaWV3RW5jYXBzdWxhdGlvblxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEJlaGF2aW9yU3ViamVjdCwgRU1QVFksIGZyb20sIGZyb21FdmVudCwgT2JzZXJ2YWJsZSB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgc3dpdGNoTWFwLCB0YWtlLCB0YWtlVW50aWwsIHdpdGhMYXRlc3RGcm9tIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuXG5pbXBvcnQgeyBOek91dGxldE1vZHVsZSB9IGZyb20gJ25nLXpvcnJvLWFudGQvY29yZS9vdXRsZXQnO1xuaW1wb3J0IHsgTnpEZXN0cm95U2VydmljZSB9IGZyb20gJ25nLXpvcnJvLWFudGQvY29yZS9zZXJ2aWNlcyc7XG5pbXBvcnQgeyBOelRyYW5zQnV0dG9uTW9kdWxlIH0gZnJvbSAnbmctem9ycm8tYW50ZC9jb3JlL3RyYW5zLWJ1dHRvbic7XG5pbXBvcnQgeyBOelRTVHlwZSB9IGZyb20gJ25nLXpvcnJvLWFudGQvY29yZS90eXBlcyc7XG5pbXBvcnQgeyBOekkxOG5TZXJ2aWNlLCBOelRleHRJMThuSW50ZXJmYWNlIH0gZnJvbSAnbmctem9ycm8tYW50ZC9pMThuJztcbmltcG9ydCB7IE56SWNvbk1vZHVsZSB9IGZyb20gJ25nLXpvcnJvLWFudGQvaWNvbic7XG5pbXBvcnQgeyBOekF1dG9zaXplRGlyZWN0aXZlLCBOeklucHV0TW9kdWxlIH0gZnJvbSAnbmctem9ycm8tYW50ZC9pbnB1dCc7XG5pbXBvcnQgeyBOelRvb2xUaXBNb2R1bGUgfSBmcm9tICduZy16b3Jyby1hbnRkL3Rvb2x0aXAnO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICduei10ZXh0LWVkaXQnLFxuICBleHBvcnRBczogJ256VGV4dEVkaXQnLFxuICB0ZW1wbGF0ZTogYFxuICAgIDxuZy10ZW1wbGF0ZSBbbmdJZl09XCJlZGl0aW5nXCIgW25nSWZFbHNlXT1cIm5vdEVkaXRpbmdcIj5cbiAgICAgIDx0ZXh0YXJlYSAjdGV4dGFyZWEgbnotaW5wdXQgbnpBdXRvc2l6ZSAoYmx1cik9XCJjb25maXJtKClcIj48L3RleHRhcmVhPlxuICAgICAgPGJ1dHRvbiBuei10cmFucy1idXR0b24gY2xhc3M9XCJhbnQtdHlwb2dyYXBoeS1lZGl0LWNvbnRlbnQtY29uZmlybVwiIChjbGljayk9XCJjb25maXJtKClcIj5cbiAgICAgICAgPHNwYW4gbnotaWNvbiBuelR5cGU9XCJlbnRlclwiPjwvc3Bhbj5cbiAgICAgIDwvYnV0dG9uPlxuICAgIDwvbmctdGVtcGxhdGU+XG5cbiAgICA8bmctdGVtcGxhdGUgI25vdEVkaXRpbmc+XG4gICAgICA8YnV0dG9uXG4gICAgICAgIG56LXRvb2x0aXBcbiAgICAgICAgbnotdHJhbnMtYnV0dG9uXG4gICAgICAgIGNsYXNzPVwiYW50LXR5cG9ncmFwaHktZWRpdFwiXG4gICAgICAgIFtuelRvb2x0aXBUaXRsZV09XCJ0b29sdGlwID09PSBudWxsID8gbnVsbCA6IHRvb2x0aXAgfHwgbG9jYWxlPy5lZGl0XCJcbiAgICAgICAgKGNsaWNrKT1cIm9uQ2xpY2soKVwiXG4gICAgICA+XG4gICAgICAgIDxuZy1jb250YWluZXIgKm56U3RyaW5nVGVtcGxhdGVPdXRsZXQ9XCJpY29uOyBsZXQgaWNvblwiPlxuICAgICAgICAgIDxzcGFuIG56LWljb24gW256VHlwZV09XCJpY29uXCI+PC9zcGFuPlxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgIDwvYnV0dG9uPlxuICAgIDwvbmctdGVtcGxhdGU+XG4gIGAsXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxuICBlbmNhcHN1bGF0aW9uOiBWaWV3RW5jYXBzdWxhdGlvbi5Ob25lLFxuICBwcmVzZXJ2ZVdoaXRlc3BhY2VzOiBmYWxzZSxcbiAgcHJvdmlkZXJzOiBbTnpEZXN0cm95U2VydmljZV0sXG4gIGltcG9ydHM6IFtOZ0lmLCBOeklucHV0TW9kdWxlLCBOelRyYW5zQnV0dG9uTW9kdWxlLCBOekljb25Nb2R1bGUsIE56VG9vbFRpcE1vZHVsZSwgTnpPdXRsZXRNb2R1bGVdLFxuICBzdGFuZGFsb25lOiB0cnVlXG59KVxuZXhwb3J0IGNsYXNzIE56VGV4dEVkaXRDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQge1xuICBlZGl0aW5nID0gZmFsc2U7XG4gIGxvY2FsZSE6IE56VGV4dEkxOG5JbnRlcmZhY2U7XG5cbiAgQElucHV0KCkgdGV4dD86IHN0cmluZztcbiAgQElucHV0KCkgaWNvbjogTnpUU1R5cGUgPSAnZWRpdCc7XG4gIEBJbnB1dCgpIHRvb2x0aXA/OiBudWxsIHwgTnpUU1R5cGU7XG4gIEBPdXRwdXQoKSByZWFkb25seSBzdGFydEVkaXRpbmcgPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XG4gIEBPdXRwdXQoKSByZWFkb25seSBlbmRFZGl0aW5nID0gbmV3IEV2ZW50RW1pdHRlcjxzdHJpbmc+KHRydWUpO1xuICBAVmlld0NoaWxkKCd0ZXh0YXJlYScsIHsgc3RhdGljOiBmYWxzZSB9KVxuICBzZXQgdGV4dGFyZWEodGV4dGFyZWE6IEVsZW1lbnRSZWY8SFRNTFRleHRBcmVhRWxlbWVudD4gfCB1bmRlZmluZWQpIHtcbiAgICB0aGlzLnRleHRhcmVhJC5uZXh0KHRleHRhcmVhKTtcbiAgfVxuICBAVmlld0NoaWxkKE56QXV0b3NpemVEaXJlY3RpdmUsIHsgc3RhdGljOiBmYWxzZSB9KSBhdXRvc2l6ZURpcmVjdGl2ZSE6IE56QXV0b3NpemVEaXJlY3RpdmU7XG5cbiAgYmVmb3JlVGV4dD86IHN0cmluZztcbiAgY3VycmVudFRleHQ/OiBzdHJpbmc7XG4gIG5hdGl2ZUVsZW1lbnQgPSB0aGlzLmhvc3QubmF0aXZlRWxlbWVudDtcblxuICAvLyBXZSBjb3VsZCd2ZSBzYXZlZCB0aGUgdGV4dGFyZWEgd2l0aGluIHNvbWUgcHJpdmF0ZSBwcm9wZXJ0eSAoZS5nLiBgX3RleHRhcmVhYCkgYW5kIGhhdmUgYSBnZXR0ZXIsXG4gIC8vIGJ1dCBoYXZpbmcgc3ViamVjdCBtYWtlcyB0aGUgY29kZSBtb3JlIHJlYWN0aXZlIGFuZCBjYW5jZWxsYWJsZSAoZS5nLiBldmVudCBsaXN0ZW5lcnMgd2lsbCBiZVxuICAvLyBhdXRvbWF0aWNhbGx5IHJlbW92ZWQgYW5kIHJlLWFkZGVkIHRocm91Z2ggdGhlIGBzd2l0Y2hNYXBgIGJlbG93KS5cbiAgcHJpdmF0ZSB0ZXh0YXJlYSQgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PEVsZW1lbnRSZWY8SFRNTFRleHRBcmVhRWxlbWVudD4gfCBudWxsIHwgdW5kZWZpbmVkPihudWxsKTtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIG5nWm9uZTogTmdab25lLFxuICAgIHByaXZhdGUgaG9zdDogRWxlbWVudFJlZjxIVE1MRWxlbWVudD4sXG4gICAgcHJpdmF0ZSBjZHI6IENoYW5nZURldGVjdG9yUmVmLFxuICAgIHByaXZhdGUgaTE4bjogTnpJMThuU2VydmljZSxcbiAgICBwcml2YXRlIGRlc3Ryb3kkOiBOekRlc3Ryb3lTZXJ2aWNlXG4gICkge31cblxuICBuZ09uSW5pdCgpOiB2b2lkIHtcbiAgICB0aGlzLmkxOG4ubG9jYWxlQ2hhbmdlLnBpcGUodGFrZVVudGlsKHRoaXMuZGVzdHJveSQpKS5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgdGhpcy5sb2NhbGUgPSB0aGlzLmkxOG4uZ2V0TG9jYWxlRGF0YSgnVGV4dCcpO1xuICAgICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gICAgfSk7XG5cbiAgICB0aGlzLnRleHRhcmVhJFxuICAgICAgLnBpcGUoXG4gICAgICAgIHN3aXRjaE1hcCh0ZXh0YXJlYSA9PlxuICAgICAgICAgIC8vIENhcmV0YWtlciBub3RlOiB3ZSBleHBsaWNpdGx5IHNob3VsZCBjYWxsIGBzdWJzY3JpYmUoKWAgd2l0aGluIHRoZSByb290IHpvbmUuXG4gICAgICAgICAgLy8gYHJ1bk91dHNpZGVBbmd1bGFyKCgpID0+IGZyb21FdmVudCguLi4pKWAgd2lsbCBqdXN0IGNyZWF0ZSBhbiBvYnNlcnZhYmxlIHdpdGhpbiB0aGUgcm9vdCB6b25lLFxuICAgICAgICAgIC8vIGJ1dCBgYWRkRXZlbnRMaXN0ZW5lcmAgaXMgY2FsbGVkIHdoZW4gdGhlIGBmcm9tRXZlbnRgIGlzIHN1YnNjcmliZWQuXG4gICAgICAgICAgdGV4dGFyZWFcbiAgICAgICAgICAgID8gbmV3IE9ic2VydmFibGU8S2V5Ym9hcmRFdmVudD4oc3Vic2NyaWJlciA9PlxuICAgICAgICAgICAgICAgIHRoaXMubmdab25lLnJ1bk91dHNpZGVBbmd1bGFyKCgpID0+XG4gICAgICAgICAgICAgICAgICBmcm9tRXZlbnQ8S2V5Ym9hcmRFdmVudD4odGV4dGFyZWEubmF0aXZlRWxlbWVudCwgJ2tleWRvd24nKS5zdWJzY3JpYmUoc3Vic2NyaWJlcilcbiAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgIClcbiAgICAgICAgICAgIDogRU1QVFlcbiAgICAgICAgKSxcbiAgICAgICAgdGFrZVVudGlsKHRoaXMuZGVzdHJveSQpXG4gICAgICApXG4gICAgICAuc3Vic2NyaWJlKGV2ZW50ID0+IHtcbiAgICAgICAgLy8gQ2FyZXRha2VyIG5vdGU6IGFkZGluZyBtb2RpZmllciBhdCB0aGUgZW5kIChmb3IgaW5zdGFuY2UgYChrZXlkb3duLmVzYylgKSB3aWxsIHRlbGwgQW5ndWxhciB0byBhZGRcbiAgICAgICAgLy8gYW4gZXZlbnQgbGlzdGVuZXIgdGhyb3VnaCB0aGUgYEtleUV2ZW50c1BsdWdpbmAsIHdoaWNoIGFsd2F5cyBydW5zIGBuZ1pvbmUucnVuR3VhcmRlZCgpYCBpbnRlcm5hbGx5LlxuICAgICAgICAvLyBXZSdyZSBpbnRlcmVzdGVkIG9ubHkgaW4gZXNjYXBlIGFuZCBlbnRlciBrZXlib2FyZCBidXR0b25zLCBvdGhlcndpc2UgQW5ndWxhciB3aWxsIHJ1biBjaGFuZ2UgZGV0ZWN0aW9uXG4gICAgICAgIC8vIG9uIGFueSBga2V5ZG93bmAgZXZlbnQuXG4gICAgICAgIGlmIChldmVudC5rZXlDb2RlICE9PSBFU0NBUEUgJiYgZXZlbnQua2V5Q29kZSAhPT0gRU5URVIpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLm5nWm9uZS5ydW4oKCkgPT4ge1xuICAgICAgICAgIGlmIChldmVudC5rZXlDb2RlID09PSBFU0NBUEUpIHtcbiAgICAgICAgICAgIHRoaXMub25DYW5jZWwoKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5vbkVudGVyKGV2ZW50KTtcbiAgICAgICAgICB9XG4gICAgICAgICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG5cbiAgICB0aGlzLnRleHRhcmVhJFxuICAgICAgLnBpcGUoXG4gICAgICAgIHN3aXRjaE1hcCh0ZXh0YXJlYSA9PlxuICAgICAgICAgIHRleHRhcmVhXG4gICAgICAgICAgICA/IG5ldyBPYnNlcnZhYmxlPEtleWJvYXJkRXZlbnQ+KHN1YnNjcmliZXIgPT5cbiAgICAgICAgICAgICAgICB0aGlzLm5nWm9uZS5ydW5PdXRzaWRlQW5ndWxhcigoKSA9PlxuICAgICAgICAgICAgICAgICAgZnJvbUV2ZW50PEtleWJvYXJkRXZlbnQ+KHRleHRhcmVhLm5hdGl2ZUVsZW1lbnQsICdpbnB1dCcpLnN1YnNjcmliZShzdWJzY3JpYmVyKVxuICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgOiBFTVBUWVxuICAgICAgICApLFxuICAgICAgICB0YWtlVW50aWwodGhpcy5kZXN0cm95JClcbiAgICAgIClcbiAgICAgIC5zdWJzY3JpYmUoZXZlbnQgPT4ge1xuICAgICAgICB0aGlzLmN1cnJlbnRUZXh0ID0gKGV2ZW50LnRhcmdldCBhcyBIVE1MVGV4dEFyZWFFbGVtZW50KS52YWx1ZTtcbiAgICAgIH0pO1xuICB9XG5cbiAgb25DbGljaygpOiB2b2lkIHtcbiAgICB0aGlzLmJlZm9yZVRleHQgPSB0aGlzLnRleHQ7XG4gICAgdGhpcy5jdXJyZW50VGV4dCA9IHRoaXMuYmVmb3JlVGV4dDtcbiAgICB0aGlzLmVkaXRpbmcgPSB0cnVlO1xuICAgIHRoaXMuc3RhcnRFZGl0aW5nLmVtaXQoKTtcbiAgICB0aGlzLmZvY3VzQW5kU2V0VmFsdWUoKTtcbiAgfVxuXG4gIGNvbmZpcm0oKTogdm9pZCB7XG4gICAgdGhpcy5lZGl0aW5nID0gZmFsc2U7XG4gICAgdGhpcy5lbmRFZGl0aW5nLmVtaXQodGhpcy5jdXJyZW50VGV4dCk7XG4gIH1cblxuICBvbkVudGVyKGV2ZW50OiBFdmVudCk6IHZvaWQge1xuICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgdGhpcy5jb25maXJtKCk7XG4gIH1cblxuICBvbkNhbmNlbCgpOiB2b2lkIHtcbiAgICB0aGlzLmN1cnJlbnRUZXh0ID0gdGhpcy5iZWZvcmVUZXh0O1xuICAgIHRoaXMuY29uZmlybSgpO1xuICB9XG5cbiAgZm9jdXNBbmRTZXRWYWx1ZSgpOiB2b2lkIHtcbiAgICAvLyBOb3RlOiB0aGUgem9uZSBtYXkgYmUgbm9vcGVkIHRocm91Z2ggYEJvb3RzdHJhcE9wdGlvbnNgIHdoZW4gYm9vdHN0cmFwcGluZyB0aGUgcm9vdCBtb2R1bGUuIFRoaXMgbWVhbnNcbiAgICAvLyB0aGUgYG9uU3RhYmxlYCB3aWxsIG5ldmVyIGVtaXQgYW55IHZhbHVlLlxuICAgIGNvbnN0IG9uU3RhYmxlJCA9IHRoaXMubmdab25lLmlzU3RhYmxlID8gZnJvbShQcm9taXNlLnJlc29sdmUoKSkgOiB0aGlzLm5nWm9uZS5vblN0YWJsZS5waXBlKHRha2UoMSkpO1xuICAgIC8vIE5vcm1hbGx5IHRoaXMgaXNuJ3QgaW4gdGhlIHpvbmUsIGJ1dCBpdCBjYW4gY2F1c2UgcGVyZm9ybWFuY2UgcmVncmVzc2lvbnMgZm9yIGFwcHNcbiAgICAvLyB1c2luZyBgem9uZS1wYXRjaC1yeGpzYCBiZWNhdXNlIGl0J2xsIHRyaWdnZXIgYSBjaGFuZ2UgZGV0ZWN0aW9uIHdoZW4gaXQgdW5zdWJzY3JpYmVzLlxuICAgIHRoaXMubmdab25lLnJ1bk91dHNpZGVBbmd1bGFyKCgpID0+IHtcbiAgICAgIG9uU3RhYmxlJC5waXBlKHdpdGhMYXRlc3RGcm9tKHRoaXMudGV4dGFyZWEkKSwgdGFrZVVudGlsKHRoaXMuZGVzdHJveSQpKS5zdWJzY3JpYmUoKFssIHRleHRhcmVhXSkgPT4ge1xuICAgICAgICBpZiAodGV4dGFyZWEpIHtcbiAgICAgICAgICB0ZXh0YXJlYS5uYXRpdmVFbGVtZW50LmZvY3VzKCk7XG4gICAgICAgICAgdGV4dGFyZWEubmF0aXZlRWxlbWVudC52YWx1ZSA9IHRoaXMuY3VycmVudFRleHQgfHwgJyc7XG4gICAgICAgICAgdGhpcy5hdXRvc2l6ZURpcmVjdGl2ZS5yZXNpemVUb0ZpdENvbnRlbnQoKTtcbiAgICAgICAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cbn1cbiJdfQ==