ng-zorro-antd
Version:
An enterprise-class UI components based on Ant Design and Angular
480 lines • 67 kB
JavaScript
import { __decorate } from "tslib";
import { DOWN_ARROW, ENTER, ESCAPE, LEFT_ARROW, RIGHT_ARROW, TAB, UP_ARROW } from '@angular/cdk/keycodes';
import { ConnectionPositionPair, OverlayConfig } from '@angular/cdk/overlay';
import { TemplatePortal } from '@angular/cdk/portal';
import { DOCUMENT } from '@angular/common';
import { ChangeDetectionStrategy, Component, ContentChild, ElementRef, EventEmitter, Inject, Input, Optional, Output, TemplateRef, ViewChild, ViewChildren } from '@angular/core';
import { fromEvent, merge, Observable, of as observableOf, Subscription } from 'rxjs';
import { distinctUntilChanged, map, startWith, switchMap, takeUntil, withLatestFrom } from 'rxjs/operators';
import { DEFAULT_MENTION_BOTTOM_POSITIONS, DEFAULT_MENTION_TOP_POSITIONS } from 'ng-zorro-antd/core/overlay';
import { NzDestroyService } from 'ng-zorro-antd/core/services';
import { getCaretCoordinates, getMentions, getStatusClassNames, InputBoolean } from 'ng-zorro-antd/core/util';
import { NZ_MENTION_CONFIG } from './config';
import { NzMentionSuggestionDirective } from './mention-suggestions';
import { NzMentionService } from './mention.service';
import * as i0 from "@angular/core";
import * as i1 from "@angular/cdk/bidi";
import * as i2 from "@angular/cdk/overlay";
import * as i3 from "./mention.service";
import * as i4 from "ng-zorro-antd/core/services";
import * as i5 from "ng-zorro-antd/core/form";
import * as i6 from "ng-zorro-antd/empty";
import * as i7 from "@angular/common";
import * as i8 from "ng-zorro-antd/icon";
export class NzMentionComponent {
constructor(ngZone, ngDocument, directionality, cdr, overlay, viewContainerRef, elementRef, renderer, nzMentionService, destroy$, nzFormStatusService, nzFormNoStatusService) {
this.ngZone = ngZone;
this.ngDocument = ngDocument;
this.directionality = directionality;
this.cdr = cdr;
this.overlay = overlay;
this.viewContainerRef = viewContainerRef;
this.elementRef = elementRef;
this.renderer = renderer;
this.nzMentionService = nzMentionService;
this.destroy$ = destroy$;
this.nzFormStatusService = nzFormStatusService;
this.nzFormNoStatusService = nzFormNoStatusService;
this.nzValueWith = value => value;
this.nzPrefix = '@';
this.nzLoading = false;
this.nzNotFoundContent = '无匹配结果,轻敲空格完成输入';
this.nzPlacement = 'bottom';
this.nzSuggestions = [];
this.nzStatus = '';
this.nzOnSelect = new EventEmitter();
this.nzOnSearchChange = new EventEmitter();
this.isOpen = false;
this.filteredSuggestions = [];
this.suggestionTemplate = null;
this.activeIndex = -1;
this.dir = 'ltr';
// status
this.prefixCls = 'ant-mentions';
this.statusCls = {};
this.status = '';
this.hasFeedback = false;
this.previousValue = null;
this.cursorMention = null;
this.overlayRef = null;
}
set suggestionChild(value) {
if (value) {
this.suggestionTemplate = value;
}
}
get triggerNativeElement() {
return this.trigger.el.nativeElement;
}
get focusItemElement() {
const itemArr = this.items?.toArray();
if (itemArr && itemArr[this.activeIndex]) {
return itemArr[this.activeIndex].nativeElement;
}
return null;
}
ngOnInit() {
this.nzFormStatusService?.formStatusChanges
.pipe(distinctUntilChanged((pre, cur) => {
return pre.status === cur.status && pre.hasFeedback === cur.hasFeedback;
}), withLatestFrom(this.nzFormNoStatusService ? this.nzFormNoStatusService.noFormStatus : observableOf(false)), map(([{ status, hasFeedback }, noStatus]) => ({ status: noStatus ? '' : status, hasFeedback })), takeUntil(this.destroy$))
.subscribe(({ status, hasFeedback }) => {
this.setStatusStyles(status, hasFeedback);
});
this.nzMentionService.triggerChanged().subscribe(trigger => {
this.trigger = trigger;
this.bindTriggerEvents();
this.closeDropdown();
this.overlayRef = null;
});
this.dir = this.directionality.value;
this.directionality.change?.pipe(takeUntil(this.destroy$)).subscribe((direction) => {
this.dir = direction;
});
}
ngOnChanges(changes) {
const { nzSuggestions, nzStatus } = changes;
if (nzSuggestions) {
if (this.isOpen) {
this.previousValue = null;
this.activeIndex = -1;
this.resetDropdown(false);
}
}
if (nzStatus) {
this.setStatusStyles(this.nzStatus, this.hasFeedback);
}
}
ngAfterViewInit() {
this.items.changes
.pipe(startWith(this.items), switchMap(() => {
const items = this.items.toArray();
// 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.
return new Observable(subscriber => this.ngZone.runOutsideAngular(() => merge(...items.map(item => fromEvent(item.nativeElement, 'mousedown'))).subscribe(subscriber)));
}))
.subscribe(event => {
event.preventDefault();
});
}
ngOnDestroy() {
this.closeDropdown();
}
closeDropdown() {
if (this.overlayRef && this.overlayRef.hasAttached()) {
this.overlayRef.detach();
this.overlayOutsideClickSubscription.unsubscribe();
this.isOpen = false;
this.cdr.markForCheck();
}
}
openDropdown() {
this.attachOverlay();
this.isOpen = true;
this.cdr.markForCheck();
}
getMentions() {
return this.trigger ? getMentions(this.trigger.value, this.nzPrefix) : [];
}
selectSuggestion(suggestion) {
const value = this.nzValueWith(suggestion);
this.trigger.insertMention({
mention: value,
startPos: this.cursorMentionStart,
endPos: this.cursorMentionEnd
});
this.nzOnSelect.emit(suggestion);
this.closeDropdown();
this.activeIndex = -1;
}
handleInput(event) {
const target = event.target;
this.trigger.onChange(target.value);
this.trigger.value = target.value;
this.resetDropdown();
}
handleKeydown(event) {
const keyCode = event.keyCode;
if (this.isOpen && keyCode === ENTER && this.activeIndex !== -1 && this.filteredSuggestions.length) {
this.selectSuggestion(this.filteredSuggestions[this.activeIndex]);
event.preventDefault();
}
else if (keyCode === LEFT_ARROW || keyCode === RIGHT_ARROW) {
this.resetDropdown();
event.stopPropagation();
}
else {
if (this.isOpen && (keyCode === TAB || keyCode === ESCAPE)) {
this.closeDropdown();
return;
}
if (this.isOpen && keyCode === UP_ARROW) {
this.setPreviousItemActive();
event.preventDefault();
event.stopPropagation();
}
if (this.isOpen && keyCode === DOWN_ARROW) {
this.setNextItemActive();
event.preventDefault();
event.stopPropagation();
}
}
}
handleClick() {
this.resetDropdown();
}
bindTriggerEvents() {
this.trigger.onInput.subscribe((e) => this.handleInput(e));
this.trigger.onKeydown.subscribe((e) => this.handleKeydown(e));
this.trigger.onClick.subscribe(() => this.handleClick());
}
suggestionsFilter(value, emit) {
const suggestions = value.substring(1);
/**
* Should always emit (nzOnSearchChange) when value empty
*
* @[something]... @[empty]... @[empty]
* ^ ^ ^
* preValue preValue (should emit)
*/
if (this.previousValue === value && value !== this.cursorMention[0]) {
return;
}
this.previousValue = value;
if (emit) {
this.nzOnSearchChange.emit({
value: this.cursorMention.substring(1),
prefix: this.cursorMention[0]
});
}
const searchValue = suggestions.toLowerCase();
this.filteredSuggestions = this.nzSuggestions.filter(suggestion => this.nzValueWith(suggestion).toLowerCase().includes(searchValue));
}
resetDropdown(emit = true) {
this.resetCursorMention();
if (typeof this.cursorMention !== 'string' || !this.canOpen()) {
this.closeDropdown();
return;
}
this.suggestionsFilter(this.cursorMention, emit);
const activeIndex = this.filteredSuggestions.indexOf(this.cursorMention.substring(1));
this.activeIndex = activeIndex >= 0 ? activeIndex : 0;
this.openDropdown();
}
setNextItemActive() {
this.activeIndex = this.activeIndex + 1 <= this.filteredSuggestions.length - 1 ? this.activeIndex + 1 : 0;
this.cdr.markForCheck();
this.scrollToFocusItem();
}
setPreviousItemActive() {
this.activeIndex = this.activeIndex - 1 < 0 ? this.filteredSuggestions.length - 1 : this.activeIndex - 1;
this.cdr.markForCheck();
this.scrollToFocusItem();
}
scrollToFocusItem() {
if (this.focusItemElement) {
this.focusItemElement.scrollIntoView({ behavior: 'smooth', block: 'center', inline: 'nearest' });
}
}
canOpen() {
const element = this.triggerNativeElement;
return !element.readOnly && !element.disabled;
}
resetCursorMention() {
const value = this.triggerNativeElement.value.replace(/[\r\n]/g, NZ_MENTION_CONFIG.split) || '';
const selectionStart = this.triggerNativeElement.selectionStart;
const prefix = typeof this.nzPrefix === 'string' ? [this.nzPrefix] : this.nzPrefix;
let i = prefix.length;
while (i >= 0) {
const startPos = value.lastIndexOf(prefix[i], selectionStart);
const endPos = value.indexOf(NZ_MENTION_CONFIG.split, selectionStart) > -1
? value.indexOf(NZ_MENTION_CONFIG.split, selectionStart)
: value.length;
const mention = value.substring(startPos, endPos);
if ((startPos > 0 && value[startPos - 1] !== NZ_MENTION_CONFIG.split) ||
startPos < 0 ||
mention.includes(prefix[i], 1) ||
mention.includes(NZ_MENTION_CONFIG.split)) {
this.cursorMention = null;
this.cursorMentionStart = -1;
this.cursorMentionEnd = -1;
}
else {
this.cursorMention = mention;
this.cursorMentionStart = startPos;
this.cursorMentionEnd = endPos;
return;
}
i--;
}
}
updatePositions() {
const coordinates = getCaretCoordinates(this.triggerNativeElement, this.cursorMentionStart);
const top = coordinates.top -
this.triggerNativeElement.getBoundingClientRect().height -
this.triggerNativeElement.scrollTop +
(this.nzPlacement === 'bottom' ? coordinates.height - 6 : -6);
const left = coordinates.left - this.triggerNativeElement.scrollLeft;
this.positionStrategy.withDefaultOffsetX(left).withDefaultOffsetY(top);
if (this.nzPlacement === 'bottom') {
this.positionStrategy.withPositions([...DEFAULT_MENTION_BOTTOM_POSITIONS]);
}
if (this.nzPlacement === 'top') {
this.positionStrategy.withPositions([...DEFAULT_MENTION_TOP_POSITIONS]);
}
this.positionStrategy.apply();
}
subscribeOverlayOutsideClick() {
const canCloseDropdown = (event) => {
const clickTarget = event.target;
return (this.isOpen &&
clickTarget !== this.trigger.el.nativeElement &&
!this.overlayRef?.overlayElement.contains(clickTarget));
};
const subscription = new Subscription();
subscription.add(this.overlayRef.outsidePointerEvents().subscribe(event => canCloseDropdown(event) && this.closeDropdown()));
subscription.add(this.ngZone.runOutsideAngular(() => fromEvent(this.ngDocument, 'touchend').subscribe(event => canCloseDropdown(event) && this.ngZone.run(() => this.closeDropdown()))));
return subscription;
}
attachOverlay() {
if (!this.overlayRef) {
this.portal = new TemplatePortal(this.suggestionsTemp, this.viewContainerRef);
this.overlayRef = this.overlay.create(this.getOverlayConfig());
}
if (this.overlayRef && !this.overlayRef.hasAttached()) {
this.overlayRef.attach(this.portal);
this.overlayOutsideClickSubscription = this.subscribeOverlayOutsideClick();
}
this.updatePositions();
}
getOverlayConfig() {
return new OverlayConfig({
positionStrategy: this.getOverlayPosition(),
scrollStrategy: this.overlay.scrollStrategies.reposition(),
disposeOnNavigation: true
});
}
getOverlayPosition() {
const positions = [
new ConnectionPositionPair({ originX: 'start', originY: 'bottom' }, { overlayX: 'start', overlayY: 'top' }),
new ConnectionPositionPair({ originX: 'start', originY: 'top' }, { overlayX: 'start', overlayY: 'bottom' })
];
this.positionStrategy = this.overlay
.position()
.flexibleConnectedTo(this.trigger.el)
.withPositions(positions)
.withFlexibleDimensions(false)
.withPush(false);
return this.positionStrategy;
}
setStatusStyles(status, hasFeedback) {
// set inner status
this.status = status;
this.hasFeedback = hasFeedback;
this.cdr.markForCheck();
// render status if nzStatus is set
this.statusCls = getStatusClassNames(this.prefixCls, status, hasFeedback);
Object.keys(this.statusCls).forEach(status => {
if (this.statusCls[status]) {
this.renderer.addClass(this.elementRef.nativeElement, status);
}
else {
this.renderer.removeClass(this.elementRef.nativeElement, status);
}
});
}
}
NzMentionComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: NzMentionComponent, deps: [{ token: i0.NgZone }, { token: DOCUMENT, optional: true }, { token: i1.Directionality, optional: true }, { token: i0.ChangeDetectorRef }, { token: i2.Overlay }, { token: i0.ViewContainerRef }, { token: i0.ElementRef }, { token: i0.Renderer2 }, { token: i3.NzMentionService }, { token: i4.NzDestroyService }, { token: i5.NzFormStatusService, optional: true }, { token: i5.NzFormNoStatusService, optional: true }], target: i0.ɵɵFactoryTarget.Component });
NzMentionComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: NzMentionComponent, selector: "nz-mention", inputs: { nzValueWith: "nzValueWith", nzPrefix: "nzPrefix", nzLoading: "nzLoading", nzNotFoundContent: "nzNotFoundContent", nzPlacement: "nzPlacement", nzSuggestions: "nzSuggestions", nzStatus: "nzStatus" }, outputs: { nzOnSelect: "nzOnSelect", nzOnSearchChange: "nzOnSearchChange" }, host: { properties: { "class.ant-mentions-rtl": "dir === 'rtl'" }, classAttribute: "ant-mentions" }, providers: [NzMentionService, NzDestroyService], queries: [{ propertyName: "suggestionChild", first: true, predicate: NzMentionSuggestionDirective, descendants: true, read: TemplateRef }], viewQueries: [{ propertyName: "suggestionsTemp", first: true, predicate: TemplateRef, descendants: true }, { propertyName: "items", predicate: ["items"], descendants: true, read: ElementRef }], exportAs: ["nzMention"], usesOnChanges: true, ngImport: i0, template: `
<ng-content></ng-content>
<ng-template #suggestions>
<div class="ant-mentions-dropdown">
<ul class="ant-mentions-dropdown-menu" role="menu" tabindex="0">
<li
#items
class="ant-mentions-dropdown-menu-item"
role="menuitem"
tabindex="-1"
*ngFor="let suggestion of filteredSuggestions; let i = index"
[class.ant-mentions-dropdown-menu-item-active]="i === activeIndex"
[class.ant-mentions-dropdown-menu-item-selected]="i === activeIndex"
(click)="selectSuggestion(suggestion)"
>
<ng-container *ngIf="suggestionTemplate; else defaultSuggestion">
<ng-container *ngTemplateOutlet="suggestionTemplate; context: { $implicit: suggestion }"></ng-container>
</ng-container>
<ng-template #defaultSuggestion>{{ nzValueWith(suggestion) }}</ng-template>
</li>
<li
class="ant-mentions-dropdown-menu-item ant-mentions-dropdown-menu-item-disabled"
*ngIf="filteredSuggestions.length === 0"
>
<span *ngIf="nzLoading"><i nz-icon nzType="loading"></i></span>
<span *ngIf="!nzLoading">
<nz-embed-empty nzComponentName="select" [specificContent]="nzNotFoundContent!"></nz-embed-empty>
</span>
</li>
</ul>
</div>
</ng-template>
<nz-form-item-feedback-icon
class="ant-mentions-suffix"
*ngIf="hasFeedback && !!status"
[status]="status"
></nz-form-item-feedback-icon>
`, isInline: true, components: [{ type: i6.NzEmbedEmptyComponent, selector: "nz-embed-empty", inputs: ["nzComponentName", "specificContent"], exportAs: ["nzEmbedEmpty"] }, { type: i5.NzFormItemFeedbackIconComponent, selector: "nz-form-item-feedback-icon", inputs: ["status"], exportAs: ["nzFormFeedbackIcon"] }], directives: [{ type: i7.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i7.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i7.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }, { type: i8.NzIconDirective, selector: "[nz-icon]", inputs: ["nzSpin", "nzRotate", "nzType", "nzTheme", "nzTwotoneColor", "nzIconfont"], exportAs: ["nzIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
__decorate([
InputBoolean()
], NzMentionComponent.prototype, "nzLoading", void 0);
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: NzMentionComponent, decorators: [{
type: Component,
args: [{
selector: 'nz-mention',
exportAs: 'nzMention',
template: `
<ng-content></ng-content>
<ng-template #suggestions>
<div class="ant-mentions-dropdown">
<ul class="ant-mentions-dropdown-menu" role="menu" tabindex="0">
<li
#items
class="ant-mentions-dropdown-menu-item"
role="menuitem"
tabindex="-1"
*ngFor="let suggestion of filteredSuggestions; let i = index"
[class.ant-mentions-dropdown-menu-item-active]="i === activeIndex"
[class.ant-mentions-dropdown-menu-item-selected]="i === activeIndex"
(click)="selectSuggestion(suggestion)"
>
<ng-container *ngIf="suggestionTemplate; else defaultSuggestion">
<ng-container *ngTemplateOutlet="suggestionTemplate; context: { $implicit: suggestion }"></ng-container>
</ng-container>
<ng-template #defaultSuggestion>{{ nzValueWith(suggestion) }}</ng-template>
</li>
<li
class="ant-mentions-dropdown-menu-item ant-mentions-dropdown-menu-item-disabled"
*ngIf="filteredSuggestions.length === 0"
>
<span *ngIf="nzLoading"><i nz-icon nzType="loading"></i></span>
<span *ngIf="!nzLoading">
<nz-embed-empty nzComponentName="select" [specificContent]="nzNotFoundContent!"></nz-embed-empty>
</span>
</li>
</ul>
</div>
</ng-template>
<nz-form-item-feedback-icon
class="ant-mentions-suffix"
*ngIf="hasFeedback && !!status"
[status]="status"
></nz-form-item-feedback-icon>
`,
preserveWhitespaces: false,
changeDetection: ChangeDetectionStrategy.OnPush,
providers: [NzMentionService, NzDestroyService],
host: {
class: 'ant-mentions',
'[class.ant-mentions-rtl]': `dir === 'rtl'`
}
}]
}], ctorParameters: function () { return [{ type: i0.NgZone }, { type: undefined, decorators: [{
type: Optional
}, {
type: Inject,
args: [DOCUMENT]
}] }, { type: i1.Directionality, decorators: [{
type: Optional
}] }, { type: i0.ChangeDetectorRef }, { type: i2.Overlay }, { type: i0.ViewContainerRef }, { type: i0.ElementRef }, { type: i0.Renderer2 }, { type: i3.NzMentionService }, { type: i4.NzDestroyService }, { type: i5.NzFormStatusService, decorators: [{
type: Optional
}] }, { type: i5.NzFormNoStatusService, decorators: [{
type: Optional
}] }]; }, propDecorators: { nzValueWith: [{
type: Input
}], nzPrefix: [{
type: Input
}], nzLoading: [{
type: Input
}], nzNotFoundContent: [{
type: Input
}], nzPlacement: [{
type: Input
}], nzSuggestions: [{
type: Input
}], nzStatus: [{
type: Input
}], nzOnSelect: [{
type: Output
}], nzOnSearchChange: [{
type: Output
}], suggestionsTemp: [{
type: ViewChild,
args: [TemplateRef, { static: false }]
}], items: [{
type: ViewChildren,
args: ['items', { read: ElementRef }]
}], suggestionChild: [{
type: ContentChild,
args: [NzMentionSuggestionDirective, { static: false, read: TemplateRef }]
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWVudGlvbi5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9jb21wb25lbnRzL21lbnRpb24vbWVudGlvbi5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQU1BLE9BQU8sRUFBRSxVQUFVLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxVQUFVLEVBQUUsV0FBVyxFQUFFLEdBQUcsRUFBRSxRQUFRLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUMxRyxPQUFPLEVBQ0wsc0JBQXNCLEVBR3RCLGFBQWEsRUFHZCxNQUFNLHNCQUFzQixDQUFDO0FBQzlCLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUNyRCxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDM0MsT0FBTyxFQUVMLHVCQUF1QixFQUV2QixTQUFTLEVBQ1QsWUFBWSxFQUNaLFVBQVUsRUFDVixZQUFZLEVBQ1osTUFBTSxFQUNOLEtBQUssRUFLTCxRQUFRLEVBQ1IsTUFBTSxFQUlOLFdBQVcsRUFDWCxTQUFTLEVBQ1QsWUFBWSxFQUViLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLFVBQVUsRUFBRSxFQUFFLElBQUksWUFBWSxFQUFFLFlBQVksRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUN0RixPQUFPLEVBQUUsb0JBQW9CLEVBQUUsR0FBRyxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLGNBQWMsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRzVHLE9BQU8sRUFBRSxnQ0FBZ0MsRUFBRSw2QkFBNkIsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBQzdHLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBRS9ELE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxXQUFXLEVBQUUsbUJBQW1CLEVBQUUsWUFBWSxFQUFFLE1BQU0seUJB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QURKLFlBQVk7dUJBQUMsT0FBTyxFQUFFLEVBQUUsSUFBSSxFQUFFLFVBQVUsRUFBRTtnQkFJdkMsZUFBZTtzQkFEbEIsWUFBWTt1QkFBQyw0QkFBNEIsRUFBRSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLFdBQVcsRUFBRSIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmVcbiAqIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgYXQgaHR0cHM6Ly9naXRodWIuY29tL05HLVpPUlJPL25nLXpvcnJvLWFudGQvYmxvYi9tYXN0ZXIvTElDRU5TRVxuICovXG5cbmltcG9ydCB7IERpcmVjdGlvbiwgRGlyZWN0aW9uYWxpdHkgfSBmcm9tICdAYW5ndWxhci9jZGsvYmlkaSc7XG5pbXBvcnQgeyBET1dOX0FSUk9XLCBFTlRFUiwgRVNDQVBFLCBMRUZUX0FSUk9XLCBSSUdIVF9BUlJPVywgVEFCLCBVUF9BUlJPVyB9IGZyb20gJ0Bhbmd1bGFyL2Nkay9rZXljb2Rlcyc7XG5pbXBvcnQge1xuICBDb25uZWN0aW9uUG9zaXRpb25QYWlyLFxuICBGbGV4aWJsZUNvbm5lY3RlZFBvc2l0aW9uU3RyYXRlZ3ksXG4gIE92ZXJsYXksXG4gIE92ZXJsYXlDb25maWcsXG4gIE92ZXJsYXlSZWYsXG4gIFBvc2l0aW9uU3RyYXRlZ3lcbn0gZnJvbSAnQGFuZ3VsYXIvY2RrL292ZXJsYXknO1xuaW1wb3J0IHsgVGVtcGxhdGVQb3J0YWwgfSBmcm9tICdAYW5ndWxhci9jZGsvcG9ydGFsJztcbmltcG9ydCB7IERPQ1VNRU5UIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7XG4gIEFmdGVyVmlld0luaXQsXG4gIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LFxuICBDaGFuZ2VEZXRlY3RvclJlZixcbiAgQ29tcG9uZW50LFxuICBDb250ZW50Q2hpbGQsXG4gIEVsZW1lbnRSZWYsXG4gIEV2ZW50RW1pdHRlcixcbiAgSW5qZWN0LFxuICBJbnB1dCxcbiAgTmdab25lLFxuICBPbkNoYW5nZXMsXG4gIE9uRGVzdHJveSxcbiAgT25Jbml0LFxuICBPcHRpb25hbCxcbiAgT3V0cHV0LFxuICBRdWVyeUxpc3QsXG4gIFJlbmRlcmVyMixcbiAgU2ltcGxlQ2hhbmdlcyxcbiAgVGVtcGxhdGVSZWYsXG4gIFZpZXdDaGlsZCxcbiAgVmlld0NoaWxkcmVuLFxuICBWaWV3Q29udGFpbmVyUmVmXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgZnJvbUV2ZW50LCBtZXJnZSwgT2JzZXJ2YWJsZSwgb2YgYXMgb2JzZXJ2YWJsZU9mLCBTdWJzY3JpcHRpb24gfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IGRpc3RpbmN0VW50aWxDaGFuZ2VkLCBtYXAsIHN0YXJ0V2l0aCwgc3dpdGNoTWFwLCB0YWtlVW50aWwsIHdpdGhMYXRlc3RGcm9tIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuXG5pbXBvcnQgeyBOekZvcm1Ob1N0YXR1c1NlcnZpY2UsIE56Rm9ybVN0YXR1c1NlcnZpY2UgfSBmcm9tICduZy16b3Jyby1hbnRkL2NvcmUvZm9ybSc7XG5pbXBvcnQgeyBERUZBVUxUX01FTlRJT05fQk9UVE9NX1BPU0lUSU9OUywgREVGQVVMVF9NRU5USU9OX1RPUF9QT1NJVElPTlMgfSBmcm9tICduZy16b3Jyby1hbnRkL2NvcmUvb3ZlcmxheSc7XG5pbXBvcnQgeyBOekRlc3Ryb3lTZXJ2aWNlIH0gZnJvbSAnbmctem9ycm8tYW50ZC9jb3JlL3NlcnZpY2VzJztcbmltcG9ydCB7IEJvb2xlYW5JbnB1dCwgTmdDbGFzc0ludGVyZmFjZSwgTnpTYWZlQW55LCBOelN0YXR1cywgTnpWYWxpZGF0ZVN0YXR1cyB9IGZyb20gJ25nLXpvcnJvLWFudGQvY29yZS90eXBlcyc7XG5pbXBvcnQgeyBnZXRDYXJldENvb3JkaW5hdGVzLCBnZXRNZW50aW9ucywgZ2V0U3RhdHVzQ2xhc3NOYW1lcywgSW5wdXRCb29sZWFuIH0gZnJvbSAnbmctem9ycm8tYW50ZC9jb3JlL3V0aWwnO1xuXG5pbXBvcnQgeyBOWl9NRU5USU9OX0NPTkZJRyB9IGZyb20gJy4vY29uZmlnJztcbmltcG9ydCB7IE56TWVudGlvblN1Z2dlc3Rpb25EaXJlY3RpdmUgfSBmcm9tICcuL21lbnRpb24tc3VnZ2VzdGlvbnMnO1xuaW1wb3J0IHsgTnpNZW50aW9uVHJpZ2dlckRpcmVjdGl2ZSB9IGZyb20gJy4vbWVudGlvbi10cmlnZ2VyJztcbmltcG9ydCB7IE56TWVudGlvblNlcnZpY2UgfSBmcm9tICcuL21lbnRpb24uc2VydmljZSc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgTWVudGlvbk9uU2VhcmNoVHlwZXMge1xuICB2YWx1ZTogc3RyaW5nO1xuICBwcmVmaXg6IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBNZW50aW9uIHtcbiAgc3RhcnRQb3M6IG51bWJlcjtcbiAgZW5kUG9zOiBudW1iZXI7XG4gIG1lbnRpb246IHN0cmluZztcbn1cblxuZXhwb3J0IHR5cGUgTWVudGlvblBsYWNlbWVudCA9ICd0b3AnIHwgJ2JvdHRvbSc7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ256LW1lbnRpb24nLFxuICBleHBvcnRBczogJ256TWVudGlvbicsXG4gIHRlbXBsYXRlOiBgXG4gICAgPG5nLWNvbnRlbnQ+PC9uZy1jb250ZW50PlxuICAgIDxuZy10ZW1wbGF0ZSAjc3VnZ2VzdGlvbnM+XG4gICAgICA8ZGl2IGNsYXNzPVwiYW50LW1lbnRpb25zLWRyb3Bkb3duXCI+XG4gICAgICAgIDx1bCBjbGFzcz1cImFudC1tZW50aW9ucy1kcm9wZG93bi1tZW51XCIgcm9sZT1cIm1lbnVcIiB0YWJpbmRleD1cIjBcIj5cbiAgICAgICAgICA8bGlcbiAgICAgICAgICAgICNpdGVtc1xuICAgICAgICAgICAgY2xhc3M9XCJhbnQtbWVudGlvbnMtZHJvcGRvd24tbWVudS1pdGVtXCJcbiAgICAgICAgICAgIHJvbGU9XCJtZW51aXRlbVwiXG4gICAgICAgICAgICB0YWJpbmRleD1cIi0xXCJcbiAgICAgICAgICAgICpuZ0Zvcj1cImxldCBzdWdnZXN0aW9uIG9mIGZpbHRlcmVkU3VnZ2VzdGlvbnM7IGxldCBpID0gaW5kZXhcIlxuICAgICAgICAgICAgW2NsYXNzLmFudC1tZW50aW9ucy1kcm9wZG93bi1tZW51LWl0ZW0tYWN0aXZlXT1cImkgPT09IGFjdGl2ZUluZGV4XCJcbiAgICAgICAgICAgIFtjbGFzcy5hbnQtbWVudGlvbnMtZHJvcGRvd24tbWVudS1pdGVtLXNlbGVjdGVkXT1cImkgPT09IGFjdGl2ZUluZGV4XCJcbiAgICAgICAgICAgIChjbGljayk9XCJzZWxlY3RTdWdnZXN0aW9uKHN1Z2dlc3Rpb24pXCJcbiAgICAgICAgICA+XG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwic3VnZ2VzdGlvblRlbXBsYXRlOyBlbHNlIGRlZmF1bHRTdWdnZXN0aW9uXCI+XG4gICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJzdWdnZXN0aW9uVGVtcGxhdGU7IGNvbnRleHQ6IHsgJGltcGxpY2l0OiBzdWdnZXN0aW9uIH1cIj48L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgPG5nLXRlbXBsYXRlICNkZWZhdWx0U3VnZ2VzdGlvbj57eyBuelZhbHVlV2l0aChzdWdnZXN0aW9uKSB9fTwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgPC9saT5cbiAgICAgICAgICA8bGlcbiAgICAgICAgICAgIGNsYXNzPVwiYW50LW1lbnRpb25zLWRyb3Bkb3duLW1lbnUtaXRlbSBhbnQtbWVudGlvbnMtZHJvcGRvd24tbWVudS1pdGVtLWRpc2FibGVkXCJcbiAgICAgICAgICAgICpuZ0lmPVwiZmlsdGVyZWRTdWdnZXN0aW9ucy5sZW5ndGggPT09IDBcIlxuICAgICAgICAgID5cbiAgICAgICAgICAgIDxzcGFuICpuZ0lmPVwibnpMb2FkaW5nXCI+PGkgbnotaWNvbiBuelR5cGU9XCJsb2FkaW5nXCI+PC9pPjwvc3Bhbj5cbiAgICAgICAgICAgIDxzcGFuICpuZ0lmPVwiIW56TG9hZGluZ1wiPlxuICAgICAgICAgICAgICA8bnotZW1iZWQtZW1wdHkgbnpDb21wb25lbnROYW1lPVwic2VsZWN0XCIgW3NwZWNpZmljQ29udGVudF09XCJuek5vdEZvdW5kQ29udGVudCFcIj48L256LWVtYmVkLWVtcHR5PlxuICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgIDwvbGk+XG4gICAgICAgIDwvdWw+XG4gICAgICA8L2Rpdj5cbiAgICA8L25nLXRlbXBsYXRlPlxuICAgIDxuei1mb3JtLWl0ZW0tZmVlZGJhY2staWNvblxuICAgICAgY2xhc3M9XCJhbnQtbWVudGlvbnMtc3VmZml4XCJcbiAgICAgICpuZ0lmPVwiaGFzRmVlZGJhY2sgJiYgISFzdGF0dXNcIlxuICAgICAgW3N0YXR1c109XCJzdGF0dXNcIlxuICAgID48L256LWZvcm0taXRlbS1mZWVkYmFjay1pY29uPlxuICBgLFxuICBwcmVzZXJ2ZVdoaXRlc3BhY2VzOiBmYWxzZSxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG4gIHByb3ZpZGVyczogW056TWVudGlvblNlcnZpY2UsIE56RGVzdHJveVNlcnZpY2VdLFxuICBob3N0OiB7XG4gICAgY2xhc3M6ICdhbnQtbWVudGlvbnMnLFxuICAgICdbY2xhc3MuYW50LW1lbnRpb25zLXJ0bF0nOiBgZGlyID09PSAncnRsJ2BcbiAgfVxufSlcbmV4cG9ydCBjbGFzcyBOek1lbnRpb25Db21wb25lbnQgaW1wbGVtZW50cyBPbkRlc3Ryb3ksIE9uSW5pdCwgQWZ0ZXJWaWV3SW5pdCwgT25DaGFuZ2VzIHtcbiAgc3RhdGljIG5nQWNjZXB0SW5wdXRUeXBlX256TG9hZGluZzogQm9vbGVhbklucHV0O1xuXG4gIEBJbnB1dCgpIG56VmFsdWVXaXRoOiAodmFsdWU6IE56U2FmZUFueSkgPT4gc3RyaW5nID0gdmFsdWUgPT4gdmFsdWU7XG4gIEBJbnB1dCgpIG56UHJlZml4OiBzdHJpbmcgfCBzdHJpbmdbXSA9ICdAJztcbiAgQElucHV0KCkgQElucHV0Qm9vbGVhbigpIG56TG9hZGluZyA9IGZhbHNlO1xuICBASW5wdXQoKSBuek5vdEZvdW5kQ29udGVudDogc3RyaW5nID0gJ+aXoOWMuemFjee7k+aenO+8jOi9u+aVsuepuuagvOWujOaIkOi+k+WFpSc7XG4gIEBJbnB1dCgpIG56UGxhY2VtZW50OiBNZW50aW9uUGxhY2VtZW50ID0gJ2JvdHRvbSc7XG4gIEBJbnB1dCgpIG56U3VnZ2VzdGlvbnM6IE56U2FmZUFueVtdID0gW107XG4gIEBJbnB1dCgpIG56U3RhdHVzOiBOelN0YXR1cyA9ICcnO1xuICBAT3V0cHV0KCkgcmVhZG9ubHkgbnpPblNlbGVjdDogRXZlbnRFbWl0dGVyPE56U2FmZUFueT4gPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG4gIEBPdXRwdXQoKSByZWFkb25seSBuek9uU2VhcmNoQ2hhbmdlOiBFdmVudEVtaXR0ZXI8TWVudGlvbk9uU2VhcmNoVHlwZXM+ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuXG4gIHRyaWdnZXIhOiBOek1lbnRpb25UcmlnZ2VyRGlyZWN0aXZlO1xuICBAVmlld0NoaWxkKFRlbXBsYXRlUmVmLCB7IHN0YXRpYzogZmFsc2UgfSkgc3VnZ2VzdGlvbnNUZW1wPzogVGVtcGxhdGVSZWY8dm9pZD47XG4gIEBWaWV3Q2hpbGRyZW4oJ2l0ZW1zJywgeyByZWFkOiBFbGVtZW50UmVmIH0pXG4gIGl0ZW1zITogUXVlcnlMaXN0PEVsZW1lbnRSZWY+O1xuXG4gIEBDb250ZW50Q2hpbGQoTnpNZW50aW9uU3VnZ2VzdGlvbkRpcmVjdGl2ZSwgeyBzdGF0aWM6IGZhbHNlLCByZWFkOiBUZW1wbGF0ZVJlZiB9KVxuICBzZXQgc3VnZ2VzdGlvbkNoaWxkKHZhbHVlOiBUZW1wbGF0ZVJlZjx7ICRpbXBsaWNpdDogTnpTYWZlQW55IH0+KSB7XG4gICAgaWYgKHZhbHVlKSB7XG4gICAgICB0aGlzLnN1Z2dlc3Rpb25UZW1wbGF0ZSA9IHZhbHVlO1xuICAgIH1cbiAgfVxuXG4gIGlzT3BlbiA9IGZhbHNlO1xuICBmaWx0ZXJlZFN1Z2dlc3Rpb25zOiBzdHJpbmdbXSA9IFtdO1xuICBzdWdnZXN0aW9uVGVtcGxhdGU6IFRlbXBsYXRlUmVmPHsgJGltcGxpY2l0OiBOelNhZmVBbnkgfT4gfCBudWxsID0gbnVsbDtcbiAgYWN0aXZlSW5kZXggPSAtMTtcbiAgZGlyOiBEaXJlY3Rpb24gPSAnbHRyJztcbiAgLy8gc3RhdHVzXG4gIHByZWZpeENsczogc3RyaW5nID0gJ2FudC1tZW50aW9ucyc7XG4gIHN0YXR1c0NsczogTmdDbGFzc0ludGVyZmFjZSA9IHt9O1xuICBzdGF0dXM6IE56VmFsaWRhdGVTdGF0dXMgPSAnJztcbiAgaGFzRmVlZGJhY2s6IGJvb2xlYW4gPSBmYWxzZTtcblxuICBwcml2YXRlIHByZXZpb3VzVmFsdWU6IHN0cmluZyB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIGN1cnNvck1lbnRpb246IHN0cmlu