UNPKG

@taiga-ui/core

Version:

Core library for creating Angular components and applications using Taiga UI

139 lines 33.4 kB
import { NgIf } from '@angular/common'; import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ContentChildren, DestroyRef, forwardRef, inject, Input, isSignal, NgZone, signal, ViewEncapsulation, } from '@angular/core'; import { toSignal } from '@angular/core/rxjs-interop'; import { EMPTY_QUERY } from '@taiga-ui/cdk/constants'; import { tuiQueryListChanges, tuiTakeUntilDestroyed, tuiZonefree, } from '@taiga-ui/cdk/observables'; import { tuiInjectElement } from '@taiga-ui/cdk/utils/dom'; import { tuiIsNativeFocusedIn, tuiMoveFocus } from '@taiga-ui/cdk/utils/focus'; import { tuiIsPresent } from '@taiga-ui/cdk/utils/miscellaneous'; import { TUI_NOTHING_FOUND_MESSAGE } from '@taiga-ui/core/tokens'; import { PolymorpheusOutlet } from '@taiga-ui/polymorpheus'; import { combineLatest, map, ReplaySubject, startWith, switchMap, timer } from 'rxjs'; import { TUI_DATA_LIST_HOST, tuiAsDataListAccessor, } from './data-list.tokens'; import { TuiOptionWithValue } from './option/option.directive'; import { TUI_OPTION_CONTENT, TuiWithOptionContent } from './option/option-content'; import { TuiOption } from './option/option-legacy.component'; import * as i0 from "@angular/core"; export function tuiInjectDataListSize() { const sizes = ['s', 'm', 'l']; const size = inject(TUI_DATA_LIST_HOST, { optional: true })?.size; return size && sizes.includes(size) ? size : 'l'; } // TODO: Consider aria-activedescendant for proper accessibility implementation class TuiDataListComponent { constructor() { // TODO(v5): delete this.legacyOptionsQuery = EMPTY_QUERY; this.optionsQuery = EMPTY_QUERY; this.ngZone = inject(NgZone); this.destroyRef = inject(DestroyRef); this.el = tuiInjectElement(); this.cdr = inject(ChangeDetectorRef); this.contentReady$ = new ReplaySubject(1); this.fallback = toSignal(inject(TUI_NOTHING_FOUND_MESSAGE)); this.empty = signal(false); this.size = tuiInjectDataListSize(); // TODO(v5): use signal `contentChildren` this.options = toSignal(this.contentReady$.pipe(switchMap(() => combineLatest([ tuiQueryListChanges(this.legacyOptionsQuery), tuiQueryListChanges(this.optionsQuery), ])), map(([legacyOptions, options]) => [ ...legacyOptions.map(({ value }) => value), ...options.map(({ value }) => value()), ].filter(tuiIsPresent)), startWith([])), { requireSync: true }); } onKeyDownArrow(current, step) { const { elements } = this; tuiMoveFocus(elements.indexOf(current), elements, step); } handleFocusLossIfNecessary(element = this.el) { if (tuiIsNativeFocusedIn(element)) { this.origin?.focus({ preventScroll: true }); } } ngAfterContentInit() { this.contentReady$.next(true); } // TODO: Refactor to :has after Safari support bumped to 15 ngAfterContentChecked() { timer(0) .pipe(tuiZonefree(this.ngZone), tuiTakeUntilDestroyed(this.destroyRef)) .subscribe(() => { this.empty.set(!this.elements.length); this.cdr.detectChanges(); }); } // TODO(v5): delete getOptions(includeDisabled = false) { return [ ...this.legacyOptionsQuery, ...this.optionsQuery, ] .filter(({ disabled }) => includeDisabled || !disabled) .map(({ value }) => (isSignal(value) ? value() : value)) .filter(tuiIsPresent); } onFocusIn(relatedTarget, currentTarget) { if (!currentTarget.contains(relatedTarget) && !this.origin) { this.origin = relatedTarget; } } get elements() { return Array.from(this.el.querySelectorAll('[tuiOption]')); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: TuiDataListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: TuiDataListComponent, isStandalone: true, selector: "tui-data-list", inputs: { emptyContent: "emptyContent", size: "size" }, host: { attributes: { "role": "listbox" }, listeners: { "focusin": "onFocusIn($event.relatedTarget, $event.currentTarget)", "mousedown.prevent": "(0)", "wheel.zoneless.passive": "handleFocusLossIfNecessary()", "mouseleave": "handleFocusLossIfNecessary($event.target)", "keydown.tab": "handleFocusLossIfNecessary()", "keydown.shift.tab": "handleFocusLossIfNecessary()", "keydown.arrowDown.prevent": "onKeyDownArrow($event.target, 1)", "keydown.arrowUp.prevent": "onKeyDownArrow($event.target, -1)" }, properties: { "attr.data-size": "size" } }, providers: [ tuiAsDataListAccessor(TuiDataListComponent), { provide: TUI_OPTION_CONTENT, useFactory: () => inject(TuiWithOptionContent, { optional: true })?.content ?? // TODO(v5): remove when all legacy controls are deleted inject(TUI_OPTION_CONTENT, { host: true, skipSelf: true, optional: true, }) ?? inject(TUI_OPTION_CONTENT, { skipSelf: true, optional: true }), }, ], queries: [{ propertyName: "legacyOptionsQuery", predicate: i0.forwardRef(function () { return TuiOption; }), descendants: true }, { propertyName: "optionsQuery", predicate: i0.forwardRef(function () { return TuiOptionWithValue; }), descendants: true }], ngImport: i0, template: "<ng-content />\n<div\n *ngIf=\"empty()\"\n class=\"t-empty\"\n>\n <ng-container *polymorpheusOutlet=\"emptyContent || fallback() as text\">\n {{ text }}\n </ng-container>\n</div>\n", styles: ["tui-data-list{--tui-data-list-padding: .25rem;--tui-data-list-margin: .0625rem;display:flex;font:var(--tui-font-text-m);flex-direction:column;padding:calc(var(--tui-data-list-padding) - var(--tui-data-list-margin)) var(--tui-data-list-padding);color:var(--tui-text-tertiary)}tui-data-list:focus-within .t-trap{display:none}tui-data-list:focus-within [tuiOption]._with-dropdown:not(:focus){background-color:transparent}tui-data-list[data-size=s]{--tui-data-list-margin: 0rem}tui-data-list[data-size=s] [tuiOption][new]:not([tuiCell]){gap:.5rem}tui-data-list[data-size=s]>.t-empty,tui-data-list[data-size=s] [tuiOption]{--t-option-padding-inline: .375rem;font:var(--tui-font-text-s);min-block-size:2rem;padding-block-start:.3125rem;padding-block-end:.3125rem}tui-data-list[data-size=s]>.t-empty:before,tui-data-list[data-size=s] [tuiOption]:before{font-size:1rem}tui-data-list[data-size=m] [tuiOption][new]:not([tuiCell]){gap:.75rem}tui-data-list[data-size=m]>.t-empty,tui-data-list[data-size=m] [tuiOption]{--t-option-padding-inline: .5rem;font:var(--tui-font-text-s);min-block-size:2.5rem;padding-block-start:.375rem;padding-block-end:.375rem}tui-data-list[data-size=l]{--tui-data-list-padding: .375rem;--tui-data-list-margin: .125rem}tui-data-list[data-size=l] [tuiOption][new]:not([tuiCell]){gap:1rem}tui-data-list[data-size=l]>.t-empty,tui-data-list[data-size=l] [tuiOption]{--t-option-padding-inline: .625rem;font:var(--tui-font-text-m);min-block-size:2.75rem;padding-block-start:.375rem;padding-block-end:.375rem}tui-data-list>.t-empty{display:flex;align-items:center;box-sizing:border-box;margin:var(--tui-data-list-margin) 0}tui-data-list [tuiOption]:not([new]){justify-content:space-between}tui-data-list [tuiOption]{-webkit-appearance:none;appearance:none;padding:0;border:0;background:none;font:inherit;line-height:inherit;text-decoration:none;transition-property:background;transition-duration:var(--tui-duration, .3s);transition-timing-function:ease-in-out;display:flex;align-items:center;box-sizing:border-box;margin:var(--tui-data-list-margin) 0;text-align:start;color:var(--tui-text-primary);border-radius:var(--tui-radius-s);outline:none;cursor:pointer;background-clip:padding-box}tui-data-list [tuiOption]:disabled{opacity:var(--tui-disabled-opacity);cursor:default}@media (hover: hover) and (pointer: fine){tui-data-list [tuiOption]:hover:not(:disabled){background-color:var(--tui-background-neutral-1)}}tui-data-list [tuiOption]:active:not(:disabled),tui-data-list [tuiOption]:focus-within,tui-data-list [tuiOption]._with-dropdown{background-color:var(--tui-background-neutral-1)}tui-data-list [tuiOption]:not([new]):before{margin-inline-end:.5rem}tui-data-list [tuiOption]:after{font-size:1rem;margin:0 -.625rem 0 auto;border-inline-start:.5rem solid;border-inline-end:.5rem solid}tui-data-list>.t-empty,tui-data-list [tuiOption]{padding-inline-start:var(--t-option-padding-inline);padding-inline-end:var(--t-option-padding-inline)}tui-opt-group{position:relative;display:flex;font:var(--tui-font-text-xs);font-weight:700;color:var(--tui-text-primary);flex-direction:column;line-height:1rem}tui-data-list[data-size=l] tui-opt-group{font:var(--tui-font-text-m);font-weight:700;line-height:1.25rem}tui-data-list[data-size=l] tui-opt-group:before{padding-inline-start:.625rem;padding-inline-end:.625rem}tui-data-list[data-size=l] tui-opt-group:after{left:.625rem;right:.625rem}tui-opt-group:empty:before,tui-opt-group:empty:after{display:none}tui-opt-group:before{content:attr(data-label);padding:var(--tui-data-list-padding) .5rem var(--tui-data-list-padding);margin:var(--tui-data-list-margin) 0;white-space:normal;word-break:break-word}tui-opt-group:after{position:absolute;left:.5rem;right:.5rem;top:var(--tui-data-list-padding);block-size:1px;background:var(--tui-border-normal)}tui-opt-group:not(:empty)~tui-opt-group:before{padding-block-start:calc(.75rem + var(--tui-data-list-padding))}tui-opt-group:not(:empty)~tui-opt-group[data-label=\"\"]:before,tui-opt-group:not(:empty)~tui-opt-group:not([data-label]):before{padding:var(--tui-data-list-padding) 0}tui-opt-group:not(:empty)~tui-opt-group:after{content:\"\"}tui-opt-group[data-label=\"\"]:before,tui-opt-group:not([data-label]):before{content:\"\";padding:0;margin:0}\n"], dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: PolymorpheusOutlet, selector: "[polymorpheusOutlet]", inputs: ["polymorpheusOutlet", "polymorpheusOutletContext"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); } } export { TuiDataListComponent }; i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: TuiDataListComponent, decorators: [{ type: Component, args: [{ standalone: true, selector: 'tui-data-list', imports: [NgIf, PolymorpheusOutlet], encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, providers: [ tuiAsDataListAccessor(TuiDataListComponent), { provide: TUI_OPTION_CONTENT, useFactory: () => inject(TuiWithOptionContent, { optional: true })?.content ?? // TODO(v5): remove when all legacy controls are deleted inject(TUI_OPTION_CONTENT, { host: true, skipSelf: true, optional: true, }) ?? inject(TUI_OPTION_CONTENT, { skipSelf: true, optional: true }), }, ], host: { role: 'listbox', '[attr.data-size]': 'size', '(focusin)': 'onFocusIn($event.relatedTarget, $event.currentTarget)', '(mousedown.prevent)': '(0)', '(wheel.zoneless.passive)': 'handleFocusLossIfNecessary()', '(mouseleave)': 'handleFocusLossIfNecessary($event.target)', '(keydown.tab)': 'handleFocusLossIfNecessary()', '(keydown.shift.tab)': 'handleFocusLossIfNecessary()', '(keydown.arrowDown.prevent)': 'onKeyDownArrow($event.target, 1)', '(keydown.arrowUp.prevent)': 'onKeyDownArrow($event.target, -1)', }, template: "<ng-content />\n<div\n *ngIf=\"empty()\"\n class=\"t-empty\"\n>\n <ng-container *polymorpheusOutlet=\"emptyContent || fallback() as text\">\n {{ text }}\n </ng-container>\n</div>\n", styles: ["tui-data-list{--tui-data-list-padding: .25rem;--tui-data-list-margin: .0625rem;display:flex;font:var(--tui-font-text-m);flex-direction:column;padding:calc(var(--tui-data-list-padding) - var(--tui-data-list-margin)) var(--tui-data-list-padding);color:var(--tui-text-tertiary)}tui-data-list:focus-within .t-trap{display:none}tui-data-list:focus-within [tuiOption]._with-dropdown:not(:focus){background-color:transparent}tui-data-list[data-size=s]{--tui-data-list-margin: 0rem}tui-data-list[data-size=s] [tuiOption][new]:not([tuiCell]){gap:.5rem}tui-data-list[data-size=s]>.t-empty,tui-data-list[data-size=s] [tuiOption]{--t-option-padding-inline: .375rem;font:var(--tui-font-text-s);min-block-size:2rem;padding-block-start:.3125rem;padding-block-end:.3125rem}tui-data-list[data-size=s]>.t-empty:before,tui-data-list[data-size=s] [tuiOption]:before{font-size:1rem}tui-data-list[data-size=m] [tuiOption][new]:not([tuiCell]){gap:.75rem}tui-data-list[data-size=m]>.t-empty,tui-data-list[data-size=m] [tuiOption]{--t-option-padding-inline: .5rem;font:var(--tui-font-text-s);min-block-size:2.5rem;padding-block-start:.375rem;padding-block-end:.375rem}tui-data-list[data-size=l]{--tui-data-list-padding: .375rem;--tui-data-list-margin: .125rem}tui-data-list[data-size=l] [tuiOption][new]:not([tuiCell]){gap:1rem}tui-data-list[data-size=l]>.t-empty,tui-data-list[data-size=l] [tuiOption]{--t-option-padding-inline: .625rem;font:var(--tui-font-text-m);min-block-size:2.75rem;padding-block-start:.375rem;padding-block-end:.375rem}tui-data-list>.t-empty{display:flex;align-items:center;box-sizing:border-box;margin:var(--tui-data-list-margin) 0}tui-data-list [tuiOption]:not([new]){justify-content:space-between}tui-data-list [tuiOption]{-webkit-appearance:none;appearance:none;padding:0;border:0;background:none;font:inherit;line-height:inherit;text-decoration:none;transition-property:background;transition-duration:var(--tui-duration, .3s);transition-timing-function:ease-in-out;display:flex;align-items:center;box-sizing:border-box;margin:var(--tui-data-list-margin) 0;text-align:start;color:var(--tui-text-primary);border-radius:var(--tui-radius-s);outline:none;cursor:pointer;background-clip:padding-box}tui-data-list [tuiOption]:disabled{opacity:var(--tui-disabled-opacity);cursor:default}@media (hover: hover) and (pointer: fine){tui-data-list [tuiOption]:hover:not(:disabled){background-color:var(--tui-background-neutral-1)}}tui-data-list [tuiOption]:active:not(:disabled),tui-data-list [tuiOption]:focus-within,tui-data-list [tuiOption]._with-dropdown{background-color:var(--tui-background-neutral-1)}tui-data-list [tuiOption]:not([new]):before{margin-inline-end:.5rem}tui-data-list [tuiOption]:after{font-size:1rem;margin:0 -.625rem 0 auto;border-inline-start:.5rem solid;border-inline-end:.5rem solid}tui-data-list>.t-empty,tui-data-list [tuiOption]{padding-inline-start:var(--t-option-padding-inline);padding-inline-end:var(--t-option-padding-inline)}tui-opt-group{position:relative;display:flex;font:var(--tui-font-text-xs);font-weight:700;color:var(--tui-text-primary);flex-direction:column;line-height:1rem}tui-data-list[data-size=l] tui-opt-group{font:var(--tui-font-text-m);font-weight:700;line-height:1.25rem}tui-data-list[data-size=l] tui-opt-group:before{padding-inline-start:.625rem;padding-inline-end:.625rem}tui-data-list[data-size=l] tui-opt-group:after{left:.625rem;right:.625rem}tui-opt-group:empty:before,tui-opt-group:empty:after{display:none}tui-opt-group:before{content:attr(data-label);padding:var(--tui-data-list-padding) .5rem var(--tui-data-list-padding);margin:var(--tui-data-list-margin) 0;white-space:normal;word-break:break-word}tui-opt-group:after{position:absolute;left:.5rem;right:.5rem;top:var(--tui-data-list-padding);block-size:1px;background:var(--tui-border-normal)}tui-opt-group:not(:empty)~tui-opt-group:before{padding-block-start:calc(.75rem + var(--tui-data-list-padding))}tui-opt-group:not(:empty)~tui-opt-group[data-label=\"\"]:before,tui-opt-group:not(:empty)~tui-opt-group:not([data-label]):before{padding:var(--tui-data-list-padding) 0}tui-opt-group:not(:empty)~tui-opt-group:after{content:\"\"}tui-opt-group[data-label=\"\"]:before,tui-opt-group:not([data-label]):before{content:\"\";padding:0;margin:0}\n"] }] }], propDecorators: { legacyOptionsQuery: [{ type: ContentChildren, args: [forwardRef(() => TuiOption), { descendants: true }] }], optionsQuery: [{ type: ContentChildren, args: [forwardRef(() => TuiOptionWithValue), { descendants: true }] }], emptyContent: [{ type: Input }], size: [{ type: Input }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0YS1saXN0LmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2NvcmUvY29tcG9uZW50cy9kYXRhLWxpc3QvZGF0YS1saXN0LmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2NvcmUvY29tcG9uZW50cy9kYXRhLWxpc3QvZGF0YS1saXN0LnRlbXBsYXRlLmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFDLElBQUksRUFBQyxNQUFNLGlCQUFpQixDQUFDO0FBQ3JDLE9BQU8sRUFHSCx1QkFBdUIsRUFDdkIsaUJBQWlCLEVBQ2pCLFNBQVMsRUFDVCxlQUFlLEVBQ2YsVUFBVSxFQUNWLFVBQVUsRUFDVixNQUFNLEVBQ04sS0FBSyxFQUNMLFFBQVEsRUFDUixNQUFNLEVBRU4sTUFBTSxFQUNOLGlCQUFpQixHQUNwQixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUMsUUFBUSxFQUFDLE1BQU0sNEJBQTRCLENBQUM7QUFDcEQsT0FBTyxFQUFDLFdBQVcsRUFBQyxNQUFNLHlCQUF5QixDQUFDO0FBQ3BELE9BQU8sRUFDSCxtQkFBbUIsRUFDbkIscUJBQXFCLEVBQ3JCLFdBQVcsR0FDZCxNQUFNLDJCQUEyQixDQUFDO0FBQ25DLE9BQU8sRUFBQyxnQkFBZ0IsRUFBQyxNQUFNLHlCQUF5QixDQUFDO0FBQ3pELE9BQU8sRUFBQyxvQkFBb0IsRUFBRSxZQUFZLEVBQUMsTUFBTSwyQkFBMkIsQ0FBQztBQUM3RSxPQUFPLEVBQUMsWUFBWSxFQUFDLE1BQU0sbUNBQW1DLENBQUM7QUFDL0QsT0FBTyxFQUFDLHlCQUF5QixFQUFDLE1BQU0sdUJBQXVCLENBQUM7QUFFaEUsT0FBTyxFQUEyQixrQkFBa0IsRUFBQyxNQUFNLHdCQUF3QixDQUFDO0FBQ3BGLE9BQU8sRUFBQyxhQUFhLEVBQUUsR0FBRyxFQUFFLGFBQWEsRUFBRSxTQUFTLEVBQUUsU0FBUyxF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eEQsTUFBTSxDQUFDLGtCQUFrQixFQUFFO29DQUN2QixJQUFJLEVBQUUsSUFBSTtvQ0FDVixRQUFRLEVBQUUsSUFBSTtvQ0FDZCxRQUFRLEVBQUUsSUFBSTtpQ0FDakIsQ0FBQztnQ0FDRixNQUFNLENBQUMsa0JBQWtCLEVBQUUsRUFBQyxRQUFRLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUMsQ0FBQzt5QkFDbkU7cUJBQ0osUUFDSzt3QkFDRixJQUFJLEVBQUUsU0FBUzt3QkFDZixrQkFBa0IsRUFBRSxNQUFNO3dCQUMxQixXQUFXLEVBQUUsdURBQXVEO3dCQUNwRSxxQkFBcUIsRUFBRSxLQUFLO3dCQUM1QiwwQkFBMEIsRUFBRSw4QkFBOEI7d0JBQzFELGNBQWMsRUFBRSwyQ0FBMkM7d0JBQzNELGVBQWUsRUFBRSw4QkFBOEI7d0JBQy9DLHFCQUFxQixFQUFFLDhCQUE4Qjt3QkFDckQsNkJBQTZCLEVBQUUsa0NBQWtDO3dCQUNqRSwyQkFBMkIsRUFBRSxtQ0FBbUM7cUJBQ25FOzhCQU9nQixrQkFBa0I7c0JBRGxDLGVBQWU7dUJBQUMsVUFBVSxDQUFDLEdBQUcsRUFBRSxDQUFDLFNBQVMsQ0FBQyxFQUFFLEVBQUMsV0FBVyxFQUFFLElBQUksRUFBQztnQkFJaEQsWUFBWTtzQkFENUIsZUFBZTt1QkFBQyxVQUFVLENBQUMsR0FBRyxFQUFFLENBQUMsa0JBQWtCLENBQUMsRUFBRSxFQUFDLFdBQVcsRUFBRSxJQUFJLEVBQUM7Z0JBY25FLFlBQVk7c0JBRGxCLEtBQUs7Z0JBSUMsSUFBSTtzQkFEVixLQUFLIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtOZ0lmfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHtcbiAgICB0eXBlIEFmdGVyQ29udGVudENoZWNrZWQsXG4gICAgdHlwZSBBZnRlckNvbnRlbnRJbml0LFxuICAgIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LFxuICAgIENoYW5nZURldGVjdG9yUmVmLFxuICAgIENvbXBvbmVudCxcbiAgICBDb250ZW50Q2hpbGRyZW4sXG4gICAgRGVzdHJveVJlZixcbiAgICBmb3J3YXJkUmVmLFxuICAgIGluamVjdCxcbiAgICBJbnB1dCxcbiAgICBpc1NpZ25hbCxcbiAgICBOZ1pvbmUsXG4gICAgdHlwZSBRdWVyeUxpc3QsXG4gICAgc2lnbmFsLFxuICAgIFZpZXdFbmNhcHN1bGF0aW9uLFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7dG9TaWduYWx9IGZyb20gJ0Bhbmd1bGFyL2NvcmUvcnhqcy1pbnRlcm9wJztcbmltcG9ydCB7RU1QVFlfUVVFUll9IGZyb20gJ0B0YWlnYS11aS9jZGsvY29uc3RhbnRzJztcbmltcG9ydCB7XG4gICAgdHVpUXVlcnlMaXN0Q2hhbmdlcyxcbiAgICB0dWlUYWtlVW50aWxEZXN0cm95ZWQsXG4gICAgdHVpWm9uZWZyZWUsXG59IGZyb20gJ0B0YWlnYS11aS9jZGsvb2JzZXJ2YWJsZXMnO1xuaW1wb3J0IHt0dWlJbmplY3RFbGVtZW50fSBmcm9tICdAdGFpZ2EtdWkvY2RrL3V0aWxzL2RvbSc7XG5pbXBvcnQge3R1aUlzTmF0aXZlRm9jdXNlZEluLCB0dWlNb3ZlRm9jdXN9IGZyb20gJ0B0YWlnYS11aS9jZGsvdXRpbHMvZm9jdXMnO1xuaW1wb3J0IHt0dWlJc1ByZXNlbnR9IGZyb20gJ0B0YWlnYS11aS9jZGsvdXRpbHMvbWlzY2VsbGFuZW91cyc7XG5pbXBvcnQge1RVSV9OT1RISU5HX0ZPVU5EX01FU1NBR0V9IGZyb20gJ0B0YWlnYS11aS9jb3JlL3Rva2Vucyc7XG5pbXBvcnQge3R5cGUgVHVpU2l6ZUwsIHR5cGUgVHVpU2l6ZVN9IGZyb20gJ0B0YWlnYS11aS9jb3JlL3R5cGVzJztcbmltcG9ydCB7dHlwZSBQb2x5bW9ycGhldXNDb250ZW50LCBQb2x5bW9ycGhldXNPdXRsZXR9IGZyb20gJ0B0YWlnYS11aS9wb2x5bW9ycGhldXMnO1xuaW1wb3J0IHtjb21iaW5lTGF0ZXN0LCBtYXAsIFJlcGxheVN1YmplY3QsIHN0YXJ0V2l0aCwgc3dpdGNoTWFwLCB0aW1lcn0gZnJvbSAncnhqcyc7XG5cbmltcG9ydCB7XG4gICAgVFVJX0RBVEFfTElTVF9IT1NULFxuICAgIHR1aUFzRGF0YUxpc3RBY2Nlc3NvcixcbiAgICB0eXBlIFR1aURhdGFMaXN0QWNjZXNzb3IsXG59IGZyb20gJy4vZGF0YS1saXN0LnRva2Vucyc7XG5pbXBvcnQge1R1aU9wdGlvbldpdGhWYWx1ZX0gZnJvbSAnLi9vcHRpb24vb3B0aW9uLmRpcmVjdGl2ZSc7XG5pbXBvcnQge1RVSV9PUFRJT05fQ09OVEVOVCwgVHVpV2l0aE9wdGlvbkNvbnRlbnR9IGZyb20gJy4vb3B0aW9uL29wdGlvbi1jb250ZW50JztcbmltcG9ydCB7VHVpT3B0aW9ufSBmcm9tICcuL29wdGlvbi9vcHRpb24tbGVnYWN5LmNvbXBvbmVudCc7XG5cbmV4cG9ydCBmdW5jdGlvbiB0dWlJbmplY3REYXRhTGlzdFNpemUoKTogVHVpU2l6ZUwgfCBUdWlTaXplUyB7XG4gICAgY29uc3Qgc2l6ZXMgPSBbJ3MnLCAnbScsICdsJ10gYXMgY29uc3Q7XG4gICAgY29uc3Qgc2l6ZSA9IGluamVjdChUVUlfREFUQV9MSVNUX0hPU1QsIHtvcHRpb25hbDogdHJ1ZX0pPy5zaXplO1xuXG4gICAgcmV0dXJuIHNpemUgJiYgc2l6ZXMuaW5jbHVkZXMoc2l6ZSkgPyBzaXplIDogJ2wnO1xufVxuXG4vLyBUT0RPOiBDb25zaWRlciBhcmlhLWFjdGl2ZWRlc2NlbmRhbnQgZm9yIHByb3BlciBhY2Nlc3NpYmlsaXR5IGltcGxlbWVudGF0aW9uXG5AQ29tcG9uZW50KHtcbiAgICBzdGFuZGFsb25lOiB0cnVlLFxuICAgIHNlbGVjdG9yOiAndHVpLWRhdGEtbGlzdCcsXG4gICAgaW1wb3J0czogW05nSWYsIFBvbHltb3JwaGV1c091dGxldF0sXG4gICAgdGVtcGxhdGVVcmw6ICcuL2RhdGEtbGlzdC50ZW1wbGF0ZS5odG1sJyxcbiAgICBzdHlsZVVybHM6IFsnLi9kYXRhLWxpc3Quc3R5bGUubGVzcyddLFxuICAgIGVuY2Fwc3VsYXRpb246IFZpZXdFbmNhcHN1bGF0aW9uLk5vbmUsXG4gICAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG4gICAgcHJvdmlkZXJzOiBbXG4gICAgICAgIHR1aUFzRGF0YUxpc3RBY2Nlc3NvcihUdWlEYXRhTGlzdENvbXBvbmVudCksXG4gICAgICAgIHtcbiAgICAgICAgICAgIHByb3ZpZGU6IFRVSV9PUFRJT05fQ09OVEVOVCxcbiAgICAgICAgICAgIHVzZUZhY3Rvcnk6ICgpID0+XG4gICAgICAgICAgICAgICAgaW5qZWN0KFR1aVdpdGhPcHRpb25Db250ZW50LCB7b3B0aW9uYWw6IHRydWV9KT8uY29udGVudCA/P1xuICAgICAgICAgICAgICAgIC8vIFRPRE8odjUpOiByZW1vdmUgd2hlbiBhbGwgbGVnYWN5IGNvbnRyb2xzIGFyZSBkZWxldGVkXG4gICAgICAgICAgICAgICAgaW5qZWN0KFRVSV9PUFRJT05fQ09OVEVOVCwge1xuICAgICAgICAgICAgICAgICAgICBob3N0OiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICBza2lwU2VsZjogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgb3B0aW9uYWw6IHRydWUsXG4gICAgICAgICAgICAgICAgfSkgPz9cbiAgICAgICAgICAgICAgICBpbmplY3QoVFVJX09QVElPTl9DT05URU5ULCB7c2tpcFNlbGY6IHRydWUsIG9wdGlvbmFsOiB0cnVlfSksXG4gICAgICAgIH0sXG4gICAgXSxcbiAgICBob3N0OiB7XG4gICAgICAgIHJvbGU6ICdsaXN0Ym94JyxcbiAgICAgICAgJ1thdHRyLmRhdGEtc2l6ZV0nOiAnc2l6ZScsXG4gICAgICAgICcoZm9jdXNpbiknOiAnb25Gb2N1c0luKCRldmVudC5yZWxhdGVkVGFyZ2V0LCAkZXZlbnQuY3VycmVudFRhcmdldCknLFxuICAgICAgICAnKG1vdXNlZG93bi5wcmV2ZW50KSc6ICcoMCknLFxuICAgICAgICAnKHdoZWVsLnpvbmVsZXNzLnBhc3NpdmUpJzogJ2hhbmRsZUZvY3VzTG9zc0lmTmVjZXNzYXJ5KCknLFxuICAgICAgICAnKG1vdXNlbGVhdmUpJzogJ2hhbmRsZUZvY3VzTG9zc0lmTmVjZXNzYXJ5KCRldmVudC50YXJnZXQpJyxcbiAgICAgICAgJyhrZXlkb3duLnRhYiknOiAnaGFuZGxlRm9jdXNMb3NzSWZOZWNlc3NhcnkoKScsXG4gICAgICAgICcoa2V5ZG93bi5zaGlmdC50YWIpJzogJ2hhbmRsZUZvY3VzTG9zc0lmTmVjZXNzYXJ5KCknLFxuICAgICAgICAnKGtleWRvd24uYXJyb3dEb3duLnByZXZlbnQpJzogJ29uS2V5RG93bkFycm93KCRldmVudC50YXJnZXQsIDEpJyxcbiAgICAgICAgJyhrZXlkb3duLmFycm93VXAucHJldmVudCknOiAnb25LZXlEb3duQXJyb3coJGV2ZW50LnRhcmdldCwgLTEpJyxcbiAgICB9LFxufSlcbmV4cG9ydCBjbGFzcyBUdWlEYXRhTGlzdENvbXBvbmVudDxUPlxuICAgIGltcGxlbWVudHMgVHVpRGF0YUxpc3RBY2Nlc3NvcjxUPiwgQWZ0ZXJDb250ZW50Q2hlY2tlZCwgQWZ0ZXJDb250ZW50SW5pdFxue1xuICAgIC8vIFRPRE8odjUpOiBkZWxldGVcbiAgICBAQ29udGVudENoaWxkcmVuKGZvcndhcmRSZWYoKCkgPT4gVHVpT3B0aW9uKSwge2Rlc2NlbmRhbnRzOiB0cnVlfSlcbiAgICBwcml2YXRlIHJlYWRvbmx5IGxlZ2FjeU9wdGlvbnNRdWVyeTogUXVlcnlMaXN0PFR1aU9wdGlvbjxUPj4gPSBFTVBUWV9RVUVSWTtcblxuICAgIEBDb250ZW50Q2hpbGRyZW4oZm9yd2FyZFJlZigoKSA9PiBUdWlPcHRpb25XaXRoVmFsdWUpLCB7ZGVzY2VuZGFudHM6IHRydWV9KVxuICAgIHByaXZhdGUgcmVhZG9ubHkgb3B0aW9uc1F1ZXJ5OiBRdWVyeUxpc3Q8VHVpT3B0aW9uV2l0aFZhbHVlPFQ+PiA9IEVNUFRZX1FVRVJZO1xuXG4gICAgcHJpdmF0ZSBvcmlnaW4/OiBIVE1MRWxlbWVudDtcbiAgICBwcml2YXRlIHJlYWRvbmx5IG5nWm9uZSA9IGluamVjdChOZ1pvbmUpO1xuICAgIHByaXZhdGUgcmVhZG9ubHkgZGVzdHJveVJlZiA9IGluamVjdChEZXN0cm95UmVmKTtcbiAgICBwcml2YXRlIHJlYWRvbmx5IGVsID0gdHVpSW5qZWN0RWxlbWVudCgpO1xuICAgIHByaXZhdGUgcmVhZG9ubHkgY2RyID0gaW5qZWN0KENoYW5nZURldGVjdG9yUmVmKTtcbiAgICBwcml2YXRlIHJlYWRvbmx5IGNvbnRlbnRSZWFkeSQgPSBuZXcgUmVwbGF5U3ViamVjdDxib29sZWFuPigxKTtcblxuICAgIHByb3RlY3RlZCByZWFkb25seSBmYWxsYmFjayA9IHRvU2lnbmFsKGluamVjdChUVUlfTk9USElOR19GT1VORF9NRVNTQUdFKSk7XG4gICAgcHJvdGVjdGVkIHJlYWRvbmx5IGVtcHR5ID0gc2lnbmFsKGZhbHNlKTtcblxuICAgIEBJbnB1dCgpXG4gICAgcHVibGljIGVtcHR5Q29udGVudDogUG9seW1vcnBoZXVzQ29udGVudDtcblxuICAgIEBJbnB1dCgpXG4gICAgcHVibGljIHNpemUgPSB0dWlJbmplY3REYXRhTGlzdFNpemUoKTtcblxuICAgIC8vIFRPRE8odjUpOiB1c2Ugc2lnbmFsIGBjb250ZW50Q2hpbGRyZW5gXG4gICAgcHVibGljIHJlYWRvbmx5IG9wdGlvbnMgPSB0b1NpZ25hbDxyZWFkb25seSBUW10+KFxuICAgICAgICB0aGlzLmNvbnRlbnRSZWFkeSQucGlwZShcbiAgICAgICAgICAgIHN3aXRjaE1hcCgoKSA9PlxuICAgICAgICAgICAgICAgIGNvbWJpbmVMYXRlc3QoW1xuICAgICAgICAgICAgICAgICAgICB0dWlRdWVyeUxpc3RDaGFuZ2VzKHRoaXMubGVnYWN5T3B0aW9uc1F1ZXJ5KSxcbiAgICAgICAgICAgICAgICAgICAgdHVpUXVlcnlMaXN0Q2hhbmdlcyh0aGlzLm9wdGlvbnNRdWVyeSksXG4gICAgICAgICAgICAgICAgXSksXG4gICAgICAgICAgICApLFxuICAgICAgICAgICAgbWFwKChbbGVnYWN5T3B0aW9ucywgb3B0aW9uc10pID0+XG4gICAgICAgICAgICAgICAgW1xuICAgICAgICAgICAgICAgICAgICAuLi5sZWdhY3lPcHRpb25zLm1hcCgoe3ZhbHVlfSkgPT4gdmFsdWUpLFxuICAgICAgICAgICAgICAgICAgICAuLi5vcHRpb25zLm1hcCgoe3ZhbHVlfSkgPT4gdmFsdWUoKSksXG4gICAgICAgICAgICAgICAgXS5maWx0ZXIodHVpSXNQcmVzZW50KSxcbiAgICAgICAgICAgICksXG4gICAgICAgICAgICBzdGFydFdpdGgoW10pLFxuICAgICAgICApLFxuICAgICAgICB7cmVxdWlyZVN5bmM6IHRydWV9LFxuICAgICk7XG5cbiAgICBwdWJsaWMgb25LZXlEb3duQXJyb3coY3VycmVudDogSFRNTEVsZW1lbnQsIHN0ZXA6IG51bWJlcik6IHZvaWQge1xuICAgICAgICBjb25zdCB7ZWxlbWVudHN9ID0gdGhpcztcblxuICAgICAgICB0dWlNb3ZlRm9jdXMoZWxlbWVudHMuaW5kZXhPZihjdXJyZW50KSwgZWxlbWVudHMsIHN0ZXApO1xuICAgIH1cblxuICAgIHB1YmxpYyBoYW5kbGVGb2N1c0xvc3NJZk5lY2Vzc2FyeShlbGVtZW50OiBFbGVtZW50ID0gdGhpcy5lbCk6IHZvaWQge1xuICAgICAgICBpZiAodHVpSXNOYXRpdmVGb2N1c2VkSW4oZWxlbWVudCkpIHtcbiAgICAgICAgICAgIHRoaXMub3JpZ2luPy5mb2N1cyh7cHJldmVudFNjcm9sbDogdHJ1ZX0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHVibGljIG5nQWZ0ZXJDb250ZW50SW5pdCgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5jb250ZW50UmVhZHkkLm5leHQodHJ1ZSk7XG4gICAgfVxuXG4gICAgLy8gVE9ETzogUmVmYWN0b3IgdG8gOmhhcyBhZnRlciBTYWZhcmkgc3VwcG9ydCBidW1wZWQgdG8gMTVcbiAgICBwdWJsaWMgbmdBZnRlckNvbnRlbnRDaGVja2VkKCk6IHZvaWQge1xuICAgICAgICB0aW1lcigwKVxuICAgICAgICAgICAgLnBpcGUodHVpWm9uZWZyZWUodGhpcy5uZ1pvbmUpLCB0dWlUYWtlVW50aWxEZXN0cm95ZWQodGhpcy5kZXN0cm95UmVmKSlcbiAgICAgICAgICAgIC5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuZW1wdHkuc2V0KCF0aGlzLmVsZW1lbnRzLmxlbmd0aCk7XG4gICAgICAgICAgICAgICAgdGhpcy5jZHIuZGV0ZWN0Q2hhbmdlcygpO1xuICAgICAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLy8gVE9ETyh2NSk6IGRlbGV0ZVxuICAgIHB1YmxpYyBnZXRPcHRpb25zKGluY2x1ZGVEaXNhYmxlZCA9IGZhbHNlKTogcmVhZG9ubHkgVFtdIHtcbiAgICAgICAgcmV0dXJuIFtcbiAgICAgICAgICAgIC4uLnRoaXMubGVnYWN5T3B0aW9uc1F1ZXJ5LCAvLyBUT0RPKHY1KTogZGVsZXRlXG4gICAgICAgICAgICAuLi50aGlzLm9wdGlvbnNRdWVyeSxcbiAgICAgICAgXVxuICAgICAgICAgICAgLmZpbHRlcigoe2Rpc2FibGVkfSkgPT4gaW5jbHVkZURpc2FibGVkIHx8ICFkaXNhYmxlZClcbiAgICAgICAgICAgIC5tYXAoKHt2YWx1ZX0pID0+IChpc1NpZ25hbCh2YWx1ZSkgPyB2YWx1ZSgpIDogdmFsdWUpKVxuICAgICAgICAgICAgLmZpbHRlcih0dWlJc1ByZXNlbnQpO1xuICAgIH1cblxuICAgIHByb3RlY3RlZCBvbkZvY3VzSW4ocmVsYXRlZFRhcmdldDogSFRNTEVsZW1lbnQsIGN1cnJlbnRUYXJnZXQ6IEhUTUxFbGVtZW50KTogdm9pZCB7XG4gICAgICAgIGlmICghY3VycmVudFRhcmdldC5jb250YWlucyhyZWxhdGVkVGFyZ2V0KSAmJiAhdGhpcy5vcmlnaW4pIHtcbiAgICAgICAgICAgIHRoaXMub3JpZ2luID0gcmVsYXRlZFRhcmdldDtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgZ2V0IGVsZW1lbnRzKCk6IHJlYWRvbmx5IEhUTUxFbGVtZW50W10ge1xuICAgICAgICByZXR1cm4gQXJyYXkuZnJvbSh0aGlzLmVsLnF1ZXJ5U2VsZWN0b3JBbGwoJ1t0dWlPcHRpb25dJykpO1xuICAgIH1cbn1cbiIsIjxuZy1jb250ZW50IC8+XG48ZGl2XG4gICAgKm5nSWY9XCJlbXB0eSgpXCJcbiAgICBjbGFzcz1cInQtZW1wdHlcIlxuPlxuICAgIDxuZy1jb250YWluZXIgKnBvbHltb3JwaGV1c091dGxldD1cImVtcHR5Q29udGVudCB8fCBmYWxsYmFjaygpIGFzIHRleHRcIj5cbiAgICAgICAge3sgdGV4dCB9fVxuICAgIDwvbmctY29udGFpbmVyPlxuPC9kaXY+XG4iXX0=