UNPKG

@ng-bootstrap/ng-bootstrap

Version:
439 lines 52.4 kB
import { Attribute, ContentChildren, Directive, EventEmitter, forwardRef, Inject, Input, Output, } from '@angular/core'; import { DOCUMENT } from '@angular/common'; import { Subject } from 'rxjs'; import { takeUntil } from 'rxjs/operators'; import { isDefined } from '../util/util'; import { Key } from '../util/key'; import * as i0 from "@angular/core"; import * as i1 from "./nav-config"; const isValidNavId = (id) => isDefined(id) && id !== ''; let navCounter = 0; /** * This directive must be used to wrap content to be displayed in the nav. * * @since 5.2.0 */ class NgbNavContent { constructor(templateRef) { this.templateRef = templateRef; } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.6", ngImport: i0, type: NgbNavContent, deps: [{ token: i0.TemplateRef }], target: i0.ɵɵFactoryTarget.Directive }); } static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.0.6", type: NgbNavContent, isStandalone: true, selector: "ng-template[ngbNavContent]", ngImport: i0 }); } } export { NgbNavContent }; i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.6", ngImport: i0, type: NgbNavContent, decorators: [{ type: Directive, args: [{ selector: 'ng-template[ngbNavContent]', standalone: true }] }], ctorParameters: function () { return [{ type: i0.TemplateRef }]; } }); /** * This directive applies a specific role on a non-container based ngbNavItem. * * @since 14.1.0 */ class NgbNavItemRole { constructor(role, nav) { this.role = role; this.nav = nav; } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.6", ngImport: i0, type: NgbNavItemRole, deps: [{ token: 'role', attribute: true }, { token: forwardRef(() => NgbNav) }], target: i0.ɵɵFactoryTarget.Directive }); } static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.0.6", type: NgbNavItemRole, isStandalone: true, selector: "[ngbNavItem]:not(ng-container)", host: { properties: { "attr.role": "role ? role : nav.roles ? 'presentation' : undefined" } }, ngImport: i0 }); } } export { NgbNavItemRole }; i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.6", ngImport: i0, type: NgbNavItemRole, decorators: [{ type: Directive, args: [{ selector: '[ngbNavItem]:not(ng-container)', standalone: true, host: { '[attr.role]': `role ? role : nav.roles ? 'presentation' : undefined`, }, }] }], ctorParameters: function () { return [{ type: undefined, decorators: [{ type: Attribute, args: ['role'] }] }, { type: NgbNav, decorators: [{ type: Inject, args: [forwardRef(() => NgbNav)] }] }]; } }); /** * The directive used to group nav link and related nav content. As well as set nav identifier and some options. * * @since 5.2.0 */ class NgbNavItem { constructor(_nav, elementRef) { this._nav = _nav; this.elementRef = elementRef; /** * If `true`, the current nav item is disabled and can't be toggled by user. * * Nevertheless disabled nav can be selected programmatically via the `.select()` method and the `[activeId]` binding. */ this.disabled = false; /** * An event emitted when the fade in transition is finished on the related nav content * * @since 8.0.0 */ this.shown = new EventEmitter(); /** * An event emitted when the fade out transition is finished on the related nav content * * @since 8.0.0 */ this.hidden = new EventEmitter(); } ngAfterContentChecked() { // We are using @ContentChildren instead of @ContentChild as in the Angular version being used // only @ContentChildren allows us to specify the {descendants: false} option. // Without {descendants: false} we are hitting bugs described in: // https://github.com/ng-bootstrap/ng-bootstrap/issues/2240 this.contentTpl = this.contentTpls.first; } ngOnInit() { if (!isDefined(this.domId)) { this.domId = `ngb-nav-${navCounter++}`; } } get active() { return this._nav.activeId === this.id; } get id() { return isValidNavId(this._id) ? this._id : this.domId; } get panelDomId() { return `${this.domId}-panel`; } isPanelInDom() { return (isDefined(this.destroyOnHide) ? !this.destroyOnHide : !this._nav.destroyOnHide) || this.active; } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.6", ngImport: i0, type: NgbNavItem, deps: [{ token: forwardRef(() => NgbNav) }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive }); } static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.0.6", type: NgbNavItem, isStandalone: true, selector: "[ngbNavItem]", inputs: { destroyOnHide: "destroyOnHide", disabled: "disabled", domId: "domId", _id: ["ngbNavItem", "_id"] }, outputs: { shown: "shown", hidden: "hidden" }, host: { properties: { "class.nav-item": "true" } }, queries: [{ propertyName: "contentTpls", predicate: NgbNavContent }], exportAs: ["ngbNavItem"], ngImport: i0 }); } } export { NgbNavItem }; i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.6", ngImport: i0, type: NgbNavItem, decorators: [{ type: Directive, args: [{ selector: '[ngbNavItem]', exportAs: 'ngbNavItem', standalone: true, host: { '[class.nav-item]': 'true' } }] }], ctorParameters: function () { return [{ type: NgbNav, decorators: [{ type: Inject, args: [forwardRef(() => NgbNav)] }] }, { type: i0.ElementRef }]; }, propDecorators: { destroyOnHide: [{ type: Input }], disabled: [{ type: Input }], domId: [{ type: Input }], _id: [{ type: Input, args: ['ngbNavItem'] }], shown: [{ type: Output }], hidden: [{ type: Output }], contentTpls: [{ type: ContentChildren, args: [NgbNavContent, { descendants: false }] }] } }); /** * A nav directive that helps with implementing tabbed navigation components. * * @since 5.2.0 */ class NgbNav { constructor(role, config, _cd, _document) { this.role = role; this._cd = _cd; this._document = _document; /** * The event emitted after the active nav changes * The payload of the event is the newly active nav id * * If you want to prevent nav change, you should use `(navChange)` event */ this.activeIdChange = new EventEmitter(); /** * An event emitted when the fade in transition is finished for one of the items. * * Payload of the event is the nav id that was just shown. * * @since 8.0.0 */ this.shown = new EventEmitter(); /** * An event emitted when the fade out transition is finished for one of the items. * * Payload of the event is the nav id that was just hidden. * * @since 8.0.0 */ this.hidden = new EventEmitter(); this.destroy$ = new Subject(); this.navItemChange$ = new Subject(); /** * The nav change event emitted right before the nav change happens on user click. * * This event won't be emitted if nav is changed programmatically via `[activeId]` or `.select()`. * * See [`NgbNavChangeEvent`](#/components/nav/api#NgbNavChangeEvent) for payload details. */ this.navChange = new EventEmitter(); this.animation = config.animation; this.destroyOnHide = config.destroyOnHide; this.orientation = config.orientation; this.roles = config.roles; this.keyboard = config.keyboard; } click(item) { if (!item.disabled) { this._updateActiveId(item.id); } } onKeyDown(event) { if (this.roles !== 'tablist' || !this.keyboard) { return; } /* eslint-disable-next-line deprecation/deprecation */ const key = event.which; const enabledLinks = this.links.filter((link) => !link.navItem.disabled); const { length } = enabledLinks; let position = -1; enabledLinks.forEach((link, index) => { if (link.elRef.nativeElement === this._document.activeElement) { position = index; } }); if (length) { switch (key) { case Key.ArrowLeft: if (this.orientation === 'vertical') { return; } position = (position - 1 + length) % length; break; case Key.ArrowRight: if (this.orientation === 'vertical') { return; } position = (position + 1) % length; break; case Key.ArrowDown: if (this.orientation === 'horizontal') { return; } position = (position + 1) % length; break; case Key.ArrowUp: if (this.orientation === 'horizontal') { return; } position = (position - 1 + length) % length; break; case Key.Home: position = 0; break; case Key.End: position = length - 1; break; } if (this.keyboard === 'changeWithArrows') { this.select(enabledLinks[position].navItem.id); } enabledLinks[position].elRef.nativeElement.focus(); event.preventDefault(); } } /** * Selects the nav with the given id and shows its associated pane. * Any other nav that was previously selected becomes unselected and its associated pane is hidden. */ select(id) { this._updateActiveId(id, false); } ngAfterContentInit() { if (!isDefined(this.activeId)) { const nextId = this.items.first ? this.items.first.id : null; if (isValidNavId(nextId)) { this._updateActiveId(nextId, false); this._cd.detectChanges(); } } this.items.changes.pipe(takeUntil(this.destroy$)).subscribe(() => this._notifyItemChanged(this.activeId)); } ngOnChanges({ activeId }) { if (activeId && !activeId.firstChange) { this._notifyItemChanged(activeId.currentValue); } } ngOnDestroy() { this.destroy$.next(); } _updateActiveId(nextId, emitNavChange = true) { if (this.activeId !== nextId) { let defaultPrevented = false; if (emitNavChange) { this.navChange.emit({ activeId: this.activeId, nextId, preventDefault: () => { defaultPrevented = true; }, }); } if (!defaultPrevented) { this.activeId = nextId; this.activeIdChange.emit(nextId); this._notifyItemChanged(nextId); } } } _notifyItemChanged(nextItemId) { this.navItemChange$.next(this._getItemById(nextItemId)); } _getItemById(itemId) { return (this.items && this.items.find((item) => item.id === itemId)) || null; } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.6", ngImport: i0, type: NgbNav, deps: [{ token: 'role', attribute: true }, { token: i1.NgbNavConfig }, { token: i0.ChangeDetectorRef }, { token: DOCUMENT }], target: i0.ɵɵFactoryTarget.Directive }); } static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.0.6", type: NgbNav, isStandalone: true, selector: "[ngbNav]", inputs: { activeId: "activeId", animation: "animation", destroyOnHide: "destroyOnHide", orientation: "orientation", roles: "roles", keyboard: "keyboard" }, outputs: { activeIdChange: "activeIdChange", shown: "shown", hidden: "hidden", navChange: "navChange" }, host: { listeners: { "keydown.arrowLeft": "onKeyDown($event)", "keydown.arrowRight": "onKeyDown($event)", "keydown.arrowDown": "onKeyDown($event)", "keydown.arrowUp": "onKeyDown($event)", "keydown.Home": "onKeyDown($event)", "keydown.End": "onKeyDown($event)" }, properties: { "class.nav": "true", "class.flex-column": "orientation === 'vertical'", "attr.aria-orientation": "orientation === 'vertical' && roles === 'tablist' ? 'vertical' : undefined", "attr.role": "role ? role : roles ? 'tablist' : undefined" } }, queries: [{ propertyName: "items", predicate: NgbNavItem }, { propertyName: "links", predicate: i0.forwardRef(function () { return NgbNavLinkBase; }), descendants: true }], exportAs: ["ngbNav"], usesOnChanges: true, ngImport: i0 }); } } export { NgbNav }; i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.6", ngImport: i0, type: NgbNav, decorators: [{ type: Directive, args: [{ selector: '[ngbNav]', exportAs: 'ngbNav', standalone: true, host: { '[class.nav]': 'true', '[class.flex-column]': `orientation === 'vertical'`, '[attr.aria-orientation]': `orientation === 'vertical' && roles === 'tablist' ? 'vertical' : undefined`, '[attr.role]': `role ? role : roles ? 'tablist' : undefined`, '(keydown.arrowLeft)': 'onKeyDown($event)', '(keydown.arrowRight)': 'onKeyDown($event)', '(keydown.arrowDown)': 'onKeyDown($event)', '(keydown.arrowUp)': 'onKeyDown($event)', '(keydown.Home)': 'onKeyDown($event)', '(keydown.End)': 'onKeyDown($event)', }, }] }], ctorParameters: function () { return [{ type: undefined, decorators: [{ type: Attribute, args: ['role'] }] }, { type: i1.NgbNavConfig }, { type: i0.ChangeDetectorRef }, { type: undefined, decorators: [{ type: Inject, args: [DOCUMENT] }] }]; }, propDecorators: { activeId: [{ type: Input }], activeIdChange: [{ type: Output }], animation: [{ type: Input }], destroyOnHide: [{ type: Input }], orientation: [{ type: Input }], roles: [{ type: Input }], keyboard: [{ type: Input }], shown: [{ type: Output }], hidden: [{ type: Output }], items: [{ type: ContentChildren, args: [NgbNavItem] }], links: [{ type: ContentChildren, args: [forwardRef(() => NgbNavLinkBase), { descendants: true }] }], navChange: [{ type: Output }] } }); class NgbNavLinkBase { constructor(role, navItem, nav, elRef) { this.role = role; this.navItem = navItem; this.nav = nav; this.elRef = elRef; } hasNavItemClass() { // with alternative markup we have to add `.nav-item` class, because `ngbNavItem` is on the ng-container return this.navItem.elementRef.nativeElement.nodeType === Node.COMMENT_NODE; } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.6", ngImport: i0, type: NgbNavLinkBase, deps: [{ token: 'role', attribute: true }, { token: NgbNavItem }, { token: NgbNav }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive }); } static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.0.6", type: NgbNavLinkBase, isStandalone: true, selector: "[ngbNavLink]", host: { properties: { "id": "navItem.domId", "class.nav-link": "true", "class.nav-item": "hasNavItemClass()", "attr.role": "role ? role : nav.roles ? 'tab' : undefined", "class.active": "navItem.active", "class.disabled": "navItem.disabled", "attr.tabindex": "navItem.disabled ? -1 : undefined", "attr.aria-controls": "navItem.isPanelInDom() ? navItem.panelDomId : null", "attr.aria-selected": "navItem.active", "attr.aria-disabled": "navItem.disabled" } }, ngImport: i0 }); } } export { NgbNavLinkBase }; i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.6", ngImport: i0, type: NgbNavLinkBase, decorators: [{ type: Directive, args: [{ selector: '[ngbNavLink]', standalone: true, host: { '[id]': 'navItem.domId', '[class.nav-link]': 'true', '[class.nav-item]': 'hasNavItemClass()', '[attr.role]': `role ? role : nav.roles ? 'tab' : undefined`, '[class.active]': 'navItem.active', '[class.disabled]': 'navItem.disabled', '[attr.tabindex]': 'navItem.disabled ? -1 : undefined', '[attr.aria-controls]': 'navItem.isPanelInDom() ? navItem.panelDomId : null', '[attr.aria-selected]': 'navItem.active', '[attr.aria-disabled]': 'navItem.disabled', }, }] }], ctorParameters: function () { return [{ type: undefined, decorators: [{ type: Attribute, args: ['role'] }] }, { type: NgbNavItem }, { type: NgbNav }, { type: i0.ElementRef }]; } }); /** * A directive to mark the nav link when used on a button element. */ class NgbNavLinkButton { constructor(navItem, nav) { this.navItem = navItem; this.nav = nav; } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.6", ngImport: i0, type: NgbNavLinkButton, deps: [{ token: NgbNavItem }, { token: NgbNav }], target: i0.ɵɵFactoryTarget.Directive }); } static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.0.6", type: NgbNavLinkButton, isStandalone: true, selector: "button[ngbNavLink]", host: { attributes: { "type": "button" }, listeners: { "click": "nav.click(navItem)" }, properties: { "disabled": "navItem.disabled" } }, hostDirectives: [{ directive: NgbNavLinkBase }], ngImport: i0 }); } } export { NgbNavLinkButton }; i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.6", ngImport: i0, type: NgbNavLinkButton, decorators: [{ type: Directive, args: [{ selector: 'button[ngbNavLink]', standalone: true, hostDirectives: [NgbNavLinkBase], host: { type: 'button', '[disabled]': 'navItem.disabled', '(click)': 'nav.click(navItem)', }, }] }], ctorParameters: function () { return [{ type: NgbNavItem }, { type: NgbNav }]; } }); /** * A directive to mark the nav link when used on a link element. * * @since 5.2.0 */ class NgbNavLink { constructor(navItem, nav) { this.navItem = navItem; this.nav = nav; } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.6", ngImport: i0, type: NgbNavLink, deps: [{ token: NgbNavItem }, { token: NgbNav }], target: i0.ɵɵFactoryTarget.Directive }); } static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.0.6", type: NgbNavLink, isStandalone: true, selector: "a[ngbNavLink]", host: { attributes: { "href": "" }, listeners: { "click": "nav.click(navItem); $event.preventDefault()" } }, hostDirectives: [{ directive: NgbNavLinkBase }], ngImport: i0 }); } } export { NgbNavLink }; i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.6", ngImport: i0, type: NgbNavLink, decorators: [{ type: Directive, args: [{ selector: 'a[ngbNavLink]', standalone: true, hostDirectives: [NgbNavLinkBase], host: { href: '', '(click)': 'nav.click(navItem); $event.preventDefault()', }, }] }], ctorParameters: function () { return [{ type: NgbNavItem }, { type: NgbNav }]; } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmF2LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL25hdi9uYXYudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUdOLFNBQVMsRUFFVCxlQUFlLEVBQ2YsU0FBUyxFQUVULFlBQVksRUFDWixVQUFVLEVBQ1YsTUFBTSxFQUNOLEtBQUssRUFJTCxNQUFNLEdBSU4sTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBRTNDLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDL0IsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRTNDLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFFekMsT0FBTyxFQUFFLEdBQUcsRUFBRSxNQUFNLGFBQWEsQ0FBQzs7O0FBRWxDLE1BQU0sWUFBWSxHQUFHLENBQUMsRUFBTyxFQUFFLEVBQUUsQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDLElBQUksRUFBRSxLQUFLLEVBQUUsQ0FBQztBQUU3RCxJQUFJLFVBQVUsR0FBRyxDQUFDLENBQUM7QUFnQm5COzs7O0dBSUc7QUFDSCxNQUNhLGFBQWE7SUFDekIsWUFBbUIsV0FBNkI7UUFBN0IsZ0JBQVcsR0FBWCxXQUFXLENBQWtCO0lBQUcsQ0FBQzs4R0FEeEMsYUFBYTtrR0FBYixhQUFhOztTQUFiLGFBQWE7MkZBQWIsYUFBYTtrQkFEekIsU0FBUzttQkFBQyxFQUFFLFFBQVEsRUFBRSw0QkFBNEIsRUFBRSxVQUFVLEVBQUUsSUFBSSxFQUFFOztBQUt2RTs7OztHQUlHO0FBQ0gsTUFPYSxjQUFjO0lBQzFCLFlBQXNDLElBQVksRUFBMkMsR0FBVztRQUFsRSxTQUFJLEdBQUosSUFBSSxDQUFRO1FBQTJDLFFBQUcsR0FBSCxHQUFHLENBQVE7SUFBRyxDQUFDOzhHQURoRyxjQUFjLGtCQUNILE1BQU0sOEJBQStCLFVB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QUFFLGdCQUFnQjt3QkFDeEMsc0JBQXNCLEVBQUUsa0JBQWtCO3FCQUMxQztpQkFDRDs7MEJBR0UsU0FBUzsyQkFBQyxNQUFNOztBQVluQjs7R0FFRztBQUNILE1BVWEsZ0JBQWdCO0lBQzVCLFlBQW1CLE9BQW1CLEVBQVMsR0FBVztRQUF2QyxZQUFPLEdBQVAsT0FBTyxDQUFZO1FBQVMsUUFBRyxHQUFILEdBQUcsQ0FBUTtJQUFHLENBQUM7OEdBRGxELGdCQUFnQjtrR0FBaEIsZ0JBQWdCLDhOQTNCaEIsY0FBYzs7U0EyQmQsZ0JBQWdCOzJGQUFoQixnQkFBZ0I7a0JBVjVCLFNBQVM7bUJBQUM7b0JBQ1YsUUFBUSxFQUFFLG9CQUFvQjtvQkFDOUIsVUFBVSxFQUFFLElBQUk7b0JBQ2hCLGNBQWMsRUFBRSxDQUFDLGNBQWMsQ0FBQztvQkFDaEMsSUFBSSxFQUFFO3dCQUNMLElBQUksRUFBRSxRQUFRO3dCQUNkLFlBQVksRUFBRSxrQkFBa0I7d0JBQ2hDLFNBQVMsRUFBRSxvQkFBb0I7cUJBQy9CO2lCQUNEOztBQUtEOzs7O0dBSUc7QUFDSCxNQVNhLFVBQVU7SUFDdEIsWUFBbUIsT0FBbUIsRUFBUyxHQUFXO1FBQXZDLFlBQU8sR0FBUCxPQUFPLENBQVk7UUFBUyxRQUFHLEdBQUgsR0FBRyxDQUFRO0lBQUcsQ0FBQzs4R0FEbEQsVUFBVTtrR0FBVixVQUFVLDRMQTdDVixjQUFjOztTQTZDZCxVQUFVOzJGQUFWLFVBQVU7a0JBVHRCLFNBQVM7bUJBQUM7b0JBQ1YsUUFBUSxFQUFFLGVBQWU7b0JBQ3pCLFVBQVUsRUFBRSxJQUFJO29CQUNoQixjQUFjLEVBQUUsQ0FBQyxjQUFjLENBQUM7b0JBQ2hDLElBQUksRUFBRTt3QkFDTCxJQUFJLEVBQUUsRUFBRTt3QkFDUixTQUFTLEVBQUUsNkNBQTZDO3FCQUN4RDtpQkFDRCIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG5cdEFmdGVyQ29udGVudENoZWNrZWQsXG5cdEFmdGVyQ29udGVudEluaXQsXG5cdEF0dHJpYnV0ZSxcblx0Q2hhbmdlRGV0ZWN0b3JSZWYsXG5cdENvbnRlbnRDaGlsZHJlbixcblx0RGlyZWN0aXZlLFxuXHRFbGVtZW50UmVmLFxuXHRFdmVudEVtaXR0ZXIsXG5cdGZvcndhcmRSZWYsXG5cdEluamVjdCxcblx0SW5wdXQsXG5cdE9uQ2hhbmdlcyxcblx0T25EZXN0cm95LFxuXHRPbkluaXQsXG5cdE91dHB1dCxcblx0UXVlcnlMaXN0LFxuXHRTaW1wbGVDaGFuZ2VzLFxuXHRUZW1wbGF0ZVJlZixcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBET0NVTUVOVCB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5cbmltcG9ydCB7IFN1YmplY3QgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IHRha2VVbnRpbCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcblxuaW1wb3J0IHsgaXNEZWZpbmVkIH0gZnJvbSAnLi4vdXRpbC91dGlsJztcbmltcG9ydCB7IE5nYk5hdkNvbmZpZyB9IGZyb20gJy4vbmF2LWNvbmZpZyc7XG5pbXBvcnQgeyBLZXkgfSBmcm9tICcuLi91dGlsL2tleSc7XG5cbmNvbnN0IGlzVmFsaWROYXZJZCA9IChpZDogYW55KSA9PiBpc0RlZmluZWQoaWQpICYmIGlkICE9PSAnJztcblxubGV0IG5hdkNvdW50ZXIgPSAwO1xuXG4vKipcbiAqIENvbnRleHQgcGFzc2VkIHRvIHRoZSBuYXYgY29udGVudCB0ZW1wbGF0ZS5cbiAqXG4gKiBTZWUgW3RoaXMgZGVtb10oIy9jb21wb25lbnRzL25hdi9leGFtcGxlcyNrZWVwLWNvbnRlbnQpIGFzIHRoZSBleGFtcGxlLlxuICpcbiAqIEBzaW5jZSA1LjIuMFxuICovXG5leHBvcnQgaW50ZXJmYWNlIE5nYk5hdkNvbnRlbnRDb250ZXh0IHtcblx0LyoqXG5cdCAqIElmIGB0cnVlYCwgY3VycmVudCBuYXYgY29udGVudCBpcyB2aXNpYmxlIGFuZCBhY3RpdmVcblx0ICovXG5cdCRpbXBsaWNpdDogYm9vbGVhbjtcbn1cblxuLyoqXG4gKiBUaGlzIGRpcmVjdGl2ZSBtdXN0IGJlIHVzZWQgdG8gd3JhcCBjb250ZW50IHRvIGJlIGRpc3BsYXllZCBpbiB0aGUgbmF2LlxuICpcbiAqIEBzaW5jZSA1LjIuMFxuICovXG5ARGlyZWN0aXZlKHsgc2VsZWN0b3I6ICduZy10ZW1wbGF0ZVtuZ2JOYXZDb250ZW50XScsIHN0YW5kYWxvbmU6IHRydWUgfSlcbmV4cG9ydCBjbGFzcyBOZ2JOYXZDb250ZW50IHtcblx0Y29uc3RydWN0b3IocHVibGljIHRlbXBsYXRlUmVmOiBUZW1wbGF0ZVJlZjxhbnk+KSB7fVxufVxuXG4vKipcbiAqIFRoaXMgZGlyZWN0aXZlIGFwcGxpZXMgYSBzcGVjaWZpYyByb2xlIG9uIGEgbm9uLWNvbnRhaW5lciBiYXNlZCBuZ2JOYXZJdGVtLlxuICpcbiAqIEBzaW5jZSAxNC4xLjBcbiAqL1xuQERpcmVjdGl2ZSh7XG5cdHNlbGVjdG9yOiAnW25nYk5hdkl0ZW1dOm5vdChuZy1jb250YWluZXIpJyxcblx0c3RhbmRhbG9uZTogdHJ1ZSxcblx0aG9zdDoge1xuXHRcdCdbYXR0ci5yb2xlXSc6IGByb2xlID8gcm9sZSA6IG5hdi5yb2xlcyA/ICdwcmVzZW50YXRpb24nIDogdW5kZWZpbmVkYCxcblx0fSxcbn0pXG5leHBvcnQgY2xhc3MgTmdiTmF2SXRlbVJvbGUge1xuXHRjb25zdHJ1Y3RvcihAQXR0cmlidXRlKCdyb2xlJykgcHVibGljIHJvbGU6IHN0cmluZywgQEluamVjdChmb3J3YXJkUmVmKCgpID0+IE5nYk5hdikpIHB1YmxpYyBuYXY6IE5nYk5hdikge31cbn1cblxuLyoqXG4gKiBUaGUgZGlyZWN0aXZlIHVzZWQgdG8gZ3JvdXAgbmF2IGxpbmsgYW5kIHJlbGF0ZWQgbmF2IGNvbnRlbnQuIEFzIHdlbGwgYXMgc2V0IG5hdiBpZGVudGlmaWVyIGFuZCBzb21lIG9wdGlvbnMuXG4gKlxuICogQHNpbmNlIDUuMi4wXG4gKi9cbkBEaXJlY3RpdmUoeyBzZWxlY3RvcjogJ1tuZ2JOYXZJdGVtXScsIGV4cG9ydEFzOiAnbmdiTmF2SXRlbScsIHN0YW5kYWxvbmU6IHRydWUsIGhvc3Q6IHsgJ1tjbGFzcy5uYXYtaXRlbV0nOiAndHJ1ZScgfSB9KVxuZXhwb3J0IGNsYXNzIE5nYk5hdkl0ZW0gaW1wbGVtZW50cyBBZnRlckNvbnRlbnRDaGVja2VkLCBPbkluaXQge1xuXHQvKipcblx0ICogSWYgYHRydWVgLCBub24tYWN0aXZlIGN1cnJlbnQgbmF2IGl0ZW0gY29udGVudCB3aWxsIGJlIHJlbW92ZWQgZnJvbSBET01cblx0ICogT3RoZXJ3aXNlIGl0IHdpbGwganVzdCBiZSBoaWRkZW5cblx0ICovXG5cdEBJbnB1dCgpIGRlc3Ryb3lPbkhpZGU7XG5cblx0LyoqXG5cdCAqIElmIGB0cnVlYCwgdGhlIGN1cnJlbnQgbmF2IGl0ZW0gaXMgZGlzYWJsZWQgYW5kIGNhbid0IGJlIHRvZ2dsZWQgYnkgdXNlci5cblx0ICpcblx0ICogTmV2ZXJ0aGVsZXNzIGRpc2FibGVkIG5hdiBjYW4gYmUgc2VsZWN0ZWQgcHJvZ3JhbW1hdGljYWxseSB2aWEgdGhlIGAuc2VsZWN0KClgIG1ldGhvZCBhbmQgdGhlIGBbYWN0aXZlSWRdYCBiaW5kaW5nLlxuXHQgKi9cblx0QElucHV0KCkgZGlzYWJsZWQgPSBmYWxzZTtcblxuXHQvKipcblx0ICogVGhlIGlkIHVzZWQgZm9yIHRoZSBET00gZWxlbWVudHMuXG5cdCAqIE11c3QgYmUgdW5pcXVlIGluc2lkZSB0aGUgZG9jdW1lbnQgaW4gY2FzZSB5b3UgaGF2ZSBtdWx0aXBsZSBgbmdiTmF2YHMgb24gdGhlIHBhZ2UuXG5cdCAqXG5cdCAqIEF1dG9nZW5lcmF0ZWQgYXMgYG5nYi1uYXYtWFhYYCBpZiBub3QgcHJvdmlkZWQuXG5cdCAqL1xuXHRASW5wdXQoKSBkb21JZDogc3RyaW5nO1xuXG5cdC8qKlxuXHQgKiBUaGUgaWQgdXNlZCBhcyBhIG1vZGVsIGZvciBhY3RpdmUgbmF2LlxuXHQgKiBJdCBjYW4gYmUgYW55dGhpbmcsIGJ1dCBtdXN0IGJlIHVuaXF1ZSBpbnNpZGUgb25lIGBuZ2JOYXZgLlxuXHQgKlxuXHQgKiBUaGUgb25seSBsaW1pdGF0aW9uIGlzIHRoYXQgaXQgaXMgbm90IHBvc3NpYmxlIHRvIGhhdmUgdGhlIGAnJ2AgKGVtcHR5IHN0cmluZykgYXMgaWQsXG5cdCAqIGJlY2F1c2UgYCBuZ2JOYXZJdGVtIGAsIGBuZ2JOYXZJdGVtPScnYCBhbmQgYFtuZ2JOYXZJdGVtXT1cIicnXCJgIGFyZSBpbmRpc3Rpbmd1aXNoYWJsZVxuXHQgKi9cblx0QElucHV0KCduZ2JOYXZJdGVtJykgX2lkOiBhbnk7XG5cblx0LyoqXG5cdCAqIEFuIGV2ZW50IGVtaXR0ZWQgd2hlbiB0aGUgZmFkZSBpbiB0cmFuc2l0aW9uIGlzIGZpbmlzaGVkIG9uIHRoZSByZWxhdGVkIG5hdiBjb250ZW50XG5cdCAqXG5cdCAqIEBzaW5jZSA4LjAuMFxuXHQgKi9cblx0QE91dHB1dCgpIHNob3duID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xuXG5cdC8qKlxuXHQgKiBBbiBldmVudCBlbWl0dGVkIHdoZW4gdGhlIGZhZGUgb3V0IHRyYW5zaXRpb24gaXMgZmluaXNoZWQgb24gdGhlIHJlbGF0ZWQgbmF2IGNvbnRlbnRcblx0ICpcblx0ICogQHNpbmNlIDguMC4wXG5cdCAqL1xuXHRAT3V0cHV0KCkgaGlkZGVuID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xuXG5cdGNvbnRlbnRUcGw6IE5nYk5hdkNvbnRlbnQgfCBudWxsO1xuXG5cdEBDb250ZW50Q2hpbGRyZW4oTmdiTmF2Q29udGVudCwgeyBkZXNjZW5kYW50czogZmFsc2UgfSkgY29udGVudFRwbHM6IFF1ZXJ5TGlzdDxOZ2JOYXZDb250ZW50PjtcblxuXHRjb25zdHJ1Y3RvcihASW5qZWN0KGZvcndhcmRSZWYoKCkgPT4gTmdiTmF2KSkgcHJpdmF0ZSBfbmF2OiBOZ2JOYXYsIHB1YmxpYyBlbGVtZW50UmVmOiBFbGVtZW50UmVmPGFueT4pIHt9XG5cblx0bmdBZnRlckNvbnRlbnRDaGVja2VkKCkge1xuXHRcdC8vIFdlIGFyZSB1c2luZyBAQ29udGVudENoaWxkcmVuIGluc3RlYWQgb2YgQENvbnRlbnRDaGlsZCBhcyBpbiB0aGUgQW5ndWxhciB2ZXJzaW9uIGJlaW5nIHVzZWRcblx0XHQvLyBvbmx5IEBDb250ZW50Q2hpbGRyZW4gYWxsb3dzIHVzIHRvIHNwZWNpZnkgdGhlIHtkZXNjZW5kYW50czogZmFsc2V9IG9wdGlvbi5cblx0XHQvLyBXaXRob3V0IHtkZXNjZW5kYW50czogZmFsc2V9IHdlIGFyZSBoaXR0aW5nIGJ1Z3MgZGVzY3JpYmVkIGluOlxuXHRcdC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9uZy1ib290c3RyYXAvbmctYm9vdHN0cmFwL2lzc3Vlcy8yMjQwXG5cdFx0dGhpcy5jb250ZW50VHBsID0gdGhpcy5jb250ZW50VHBscy5maXJzdDtcblx0fVxuXG5cdG5nT25Jbml0KCkge1xuXHRcdGlmICghaXNEZWZpbmVkKHRoaXMuZG9tSWQpKSB7XG5cdFx0XHR0aGlzLmRvbUlkID0gYG5nYi1uYXYtJHtuYXZDb3VudGVyKyt9YDtcblx0XHR9XG5cdH1cblxuXHRnZXQgYWN0aXZlKCkge1xuXHRcdHJldHVybiB0aGlzLl9uYXYuYWN0aXZlSWQgPT09IHRoaXMuaWQ7XG5cdH1cblxuXHRnZXQgaWQoKSB7XG5cdFx0cmV0dXJuIGlzVmFsaWROYXZJZCh0aGlzLl9pZCkgPyB0aGlzLl9pZCA6IHRoaXMuZG9tSWQ7XG5cdH1cblxuXHRnZXQgcGFuZWxEb21JZCgpIHtcblx0XHRyZXR1cm4gYCR7dGhpcy5kb21JZH0tcGFuZWxgO1xuXHR9XG5cblx0aXNQYW5lbEluRG9tKCkge1xuXHRcdHJldHVybiAoaXNEZWZpbmVkKHRoaXMuZGVzdHJveU9uSGlkZSkgPyAhdGhpcy5kZXN0cm95T25IaWRlIDogIXRoaXMuX25hdi5kZXN0cm95T25IaWRlKSB8fCB0aGlzLmFjdGl2ZTtcblx0fVxufVxuXG4vKipcbiAqIEEgbmF2IGRpcmVjdGl2ZSB0aGF0IGhlbHBzIHdpdGggaW1wbGVtZW50aW5nIHRhYmJlZCBuYXZpZ2F0aW9uIGNvbXBvbmVudHMuXG4gKlxuICogQHNpbmNlIDUuMi4wXG4gKi9cbkBEaXJlY3RpdmUoe1xuXHRzZWxlY3RvcjogJ1tuZ2JOYXZdJyxcblx0ZXhwb3J0QXM6ICduZ2JOYXYnLFxuXHRzdGFuZGFsb25lOiB0cnVlLFxuXHRob3N0OiB7XG5cdFx0J1tjbGFzcy5uYXZdJzogJ3RydWUnLFxuXHRcdCdbY2xhc3MuZmxleC1jb2x1bW5dJzogYG9yaWVudGF0aW9uID09PSAndmVydGljYWwnYCxcblx0XHQnW2F0dHIuYXJpYS1vcmllbnRhdGlvbl0nOiBgb3JpZW50YXRpb24gPT09ICd2ZXJ0aWNhbCcgJiYgcm9sZXMgPT09ICd0YWJsaXN0JyA/ICd2ZXJ0aWNhbCcgOiB1bmRlZmluZWRgLFxuXHRcdCdbYXR0ci5yb2xlXSc6IGByb2xlID8gcm9sZSA6IHJvbGVzID8gJ3RhYmxpc3QnIDogdW5kZWZpbmVkYCxcblx0XHQnKGtleWRvd24uYXJyb3dMZWZ0KSc6ICdvbktleURvd24oJGV2ZW50KScsXG5cdFx0JyhrZXlkb3duLmFycm93UmlnaHQpJzogJ29uS2V5RG93bigkZXZlbnQpJyxcblx0XHQnKGtleWRvd24uYXJyb3dEb3duKSc6ICdvbktleURvd24oJGV2ZW50KScsXG5cdFx0JyhrZXlkb3duLmFycm93VXApJzogJ29uS2V5RG93bigkZXZlbnQpJyxcblx0XHQnKGtleWRvd24uSG9tZSknOiAnb25LZXlEb3duKCRldmVudCknLFxuXHRcdCcoa2V5ZG93bi5FbmQpJzogJ29uS2V5RG93bigkZXZlbnQpJyxcblx0fSxcbn0pXG5leHBvcnQgY2xhc3MgTmdiTmF2IGltcGxlbWVudHMgQWZ0ZXJDb250ZW50SW5pdCwgT25DaGFuZ2VzLCBPbkRlc3Ryb3kge1xuXHRzdGF0aWMgbmdBY2NlcHRJbnB1dFR5cGVfb3JpZW50YXRpb246IHN0cmluZztcblx0c3RhdGljIG5nQWNjZXB0SW5wdXRUeXBlX3JvbGVzOiBib29sZWFuIHwgc3RyaW5nO1xuXG5cdC8qKlxuXHQgKiBUaGUgaWQgb2YgdGhlIG5hdiB0aGF0IHNob3VsZCBiZSBhY3RpdmVcblx0ICpcblx0ICogWW91IGNvdWxkIGFsc28gdXNlIHRoZSBgLnNlbGVjdCgpYCBtZXRob2QgYW5kIHRoZSBgKG5hdkNoYW5nZSlgIGV2ZW50XG5cdCAqL1xuXHRASW5wdXQoKSBhY3RpdmVJZDogYW55O1xuXG5cdC8qKlxuXHQgKiBUaGUgZXZlbnQgZW1pdHRlZCBhZnRlciB0aGUgYWN0aXZlIG5hdiBjaGFuZ2VzXG5cdCAqIFRoZSBwYXlsb2FkIG9mIHRoZSBldmVudCBpcyB0aGUgbmV3bHkgYWN0aXZlIG5hdiBpZFxuXHQgKlxuXHQgKiBJZiB5b3Ugd2FudCB0byBwcmV2ZW50IG5hdiBjaGFuZ2UsIHlvdSBzaG91bGQgdXNlIGAobmF2Q2hhbmdlKWAgZXZlbnRcblx0ICovXG5cdEBPdXRwdXQoKSBhY3RpdmVJZENoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8YW55PigpO1xuXG5cdC8qKlxuXHQgKiBJZiBgdHJ1ZWAsIG5hdiBjaGFuZ2Ugd2lsbCBiZSBhbmltYXRlZC5cblx0ICpcblx0ICogQHNpbmNlIDguMC4wXG5cdCAqL1xuXHRASW5wdXQoKSBhbmltYXRpb246IGJvb2xlYW47XG5cblx0LyoqXG5cdCAqIElmIGB0cnVlYCwgbm9uLWFjdGl2ZSBuYXYgY29udGVudCB3aWxsIGJlIHJlbW92ZWQgZnJvbSBET01cblx0ICogT3RoZXJ3aXNlIGl0IHdpbGwganVzdCBiZSBoaWRkZW5cblx0ICovXG5cdEBJbnB1dCgpIGRlc3Ryb3lPbkhpZGU7XG5cblx0LyoqXG5cdCAqIFRoZSBvcmllbnRhdGlvbiBvZiBuYXZzLlxuXHQgKlxuXHQgKiBVc2luZyBgdmVydGljYWxgIHdpbGwgYWxzbyBhZGQgdGhlIGBhcmlhLW9yaWVudGF0aW9uYCBhdHRyaWJ1dGVcblx0ICovXG5cdEBJbnB1dCgpIG9yaWVudGF0aW9uOiAnaG9yaXpvbnRhbCcgfCAndmVydGljYWwnO1xuXG5cdC8qKlxuXHQgKiBSb2xlIGF0dHJpYnV0ZSBnZW5lcmF0aW5nIHN0cmF0ZWd5OlxuXHQgKiAtIGBmYWxzZWAgLSBubyByb2xlIGF0dHJpYnV0ZXMgd2lsbCBiZSBnZW5lcmF0ZWRcblx0ICogLSBgJ3RhYmxpc3QnYCAtICd0YWJsaXN0JywgJ3RhYicgYW5kICd0YWJwYW5lbCcgd2lsbCBiZSBnZW5lcmF0ZWQgKGRlZmF1bHQpXG5cdCAqL1xuXHRASW5wdXQoKSByb2xlczogJ3RhYmxpc3QnIHwgZmFsc2U7XG5cblx0LyoqXG5cdCAqIEtleWJvYXJkIHN1cHBvcnQgZm9yIG5hdiBmb2N1cy9zZWxlY3Rpb24gdXNpbmcgYXJyb3cga2V5cy5cblx0ICpcblx0ICogKiBgZmFsc2VgIC0gbm8ga2V5Ym9hcmQgc3VwcG9ydC5cblx0ICogKiBgdHJ1ZWAgLSBuYXZzIHdpbGwgYmUgZm9jdXNlZCB1c2luZyBrZXlib2FyZCBhcnJvdyBrZXlzXG5cdCAqICogYCdjaGFuZ2VXaXRoQXJyb3dzJ2AgLSAgbmF2IHdpbGwgYmUgc2VsZWN0ZWQgdXNpbmcga2V5Ym9hcmQgYXJyb3cga2V5c1xuXHQgKlxuXHQgKiBTZWUgdGhlIFtsaXN0IG9mIGF2YWlsYWJsZSBrZXlib2FyZCBzaG9ydGN1dHNdKCMvY29tcG9uZW50cy9uYXYvb3ZlcnZpZXcja2V5Ym9hcmQtc2hvcnRjdXRzKS5cblx0ICpcblx0ICogQHNpbmNlIDYuMS4wXG5cdCAqL1xuXHRASW5wdXQoKSBrZXlib2FyZDogYm9vbGVhbiB8ICdjaGFuZ2VXaXRoQXJyb3dzJztcblxuXHQvKipcblx0ICogQW4gZXZlbnQgZW1pdHRlZCB3aGVuIHRoZSBmYWRlIGluIHRyYW5zaXRpb24gaXMgZmluaXNoZWQgZm9yIG9uZSBvZiB0aGUgaXRlbXMuXG5cdCAqXG5cdCAqIFBheWxvYWQgb2YgdGhlIGV2ZW50IGlzIHRoZSBuYXYgaWQgdGhhdCB3YXMganVzdCBzaG93bi5cblx0ICpcblx0ICogQHNpbmNlIDguMC4wXG5cdCAqL1xuXHRAT3V0cHV0KCkgc2hvd24gPSBuZXcgRXZlbnRFbWl0dGVyPGFueT4oKTtcblxuXHQvKipcblx0ICogQW4gZXZlbnQgZW1pdHRlZCB3aGVuIHRoZSBmYWRlIG91dCB0cmFuc2l0aW9uIGlzIGZpbmlzaGVkIGZvciBvbmUgb2YgdGhlIGl0ZW1zLlxuXHQgKlxuXHQgKiBQYXlsb2FkIG9mIHRoZSBldmVudCBpcyB0aGUgbmF2IGlkIHRoYXQgd2FzIGp1c3QgaGlkZGVuLlxuXHQgKlxuXHQgKiBAc2luY2UgOC4wLjBcblx0ICovXG5cdEBPdXRwdXQoKSBoaWRkZW4gPSBuZXcgRXZlbnRFbWl0dGVyPGFueT4oKTtcblxuXHRAQ29udGVudENoaWxkcmVuKE5nYk5hdkl0ZW0pIGl0ZW1zOiBRdWVyeUxpc3Q8TmdiTmF2SXRlbT47XG5cdEBDb250ZW50Q2hpbGRyZW4oZm9yd2FyZFJlZigoKSA9PiBOZ2JOYXZMaW5rQmFzZSksIHsgZGVzY2VuZGFudHM6IHRydWUgfSkgbGlua3M6IFF1ZXJ5TGlzdDxOZ2JOYXZMaW5rQmFzZT47XG5cblx0ZGVzdHJveSQgPSBuZXcgU3ViamVjdDx2b2lkPigpO1xuXHRuYXZJdGVtQ2hhbmdlJCA9IG5ldyBTdWJqZWN0PE5nYk5hdkl0ZW0gfCBudWxsPigpO1xuXG5cdGNvbnN0cnVjdG9yKFxuXHRcdEBBdHRyaWJ1dGUoJ3JvbGUnKSBwdWJsaWMgcm9sZTogc3RyaW5nLFxuXHRcdGNvbmZpZzogTmdiTmF2Q29uZmlnLFxuXHRcdHByaXZhdGUgX2NkOiBDaGFuZ2VEZXRlY3RvclJlZixcblx0XHRASW5qZWN0KERPQ1VNRU5UKSBwcml2YXRlIF9kb2N1bWVudDogYW55LFxuXHQpIHtcblx0XHR0aGlzLmFuaW1hdGlvbiA9IGNvbmZpZy5hbmltYXRpb247XG5cdFx0dGhpcy5kZXN0cm95T25IaWRlID0gY29uZmlnLmRlc3Ryb3lPbkhpZGU7XG5cdFx0dGhpcy5vcmllbnRhdGlvbiA9IGNvbmZpZy5vcmllbnRhdGlvbjtcblx0XHR0aGlzLnJvbGVzID0gY29uZmlnLnJvbGVzO1xuXHRcdHRoaXMua2V5Ym9hcmQgPSBjb25maWcua2V5Ym9hcmQ7XG5cdH1cblxuXHQvKipcblx0ICogVGhlIG5hdiBjaGFuZ2UgZXZlbnQgZW1pdHRlZCByaWdodCBiZWZvcmUgdGhlIG5hdiBjaGFuZ2UgaGFwcGVucyBvbiB1c2VyIGNsaWNrLlxuXHQgKlxuXHQgKiBUaGlzIGV2ZW50IHdvbid0IGJlIGVtaXR0ZWQgaWYgbmF2IGlzIGNoYW5nZWQgcHJvZ3JhbW1hdGljYWxseSB2aWEgYFthY3RpdmVJZF1gIG9yIGAuc2VsZWN0KClgLlxuXHQgKlxuXHQgKiBTZWUgW2BOZ2JOYXZDaGFuZ2VFdmVudGBdKCMvY29tcG9uZW50cy9uYXYvYXBpI05nYk5hdkNoYW5nZUV2ZW50KSBmb3IgcGF5bG9hZCBkZXRhaWxzLlxuXHQgKi9cblx0QE91dHB1dCgpIG5hdkNoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8TmdiTmF2Q2hhbmdlRXZlbnQ+KCk7XG5cblx0Y2xpY2soaXRlbTogTmdiTmF2SXRlbSkge1xuXHRcdGlmICghaXRlbS5kaXNhYmxlZCkge1xuXHRcdFx0dGhpcy5fdXBkYXRlQWN0aXZlSWQoaXRlbS5pZCk7XG5cdFx0fVxuXHR9XG5cblx0b25LZXlEb3duKGV2ZW50OiBLZXlib2FyZEV2ZW50KSB7XG5cdFx0aWYgKHRoaXMucm9sZXMgIT09ICd0YWJsaXN0JyB8fCAhdGhpcy5rZXlib2FyZCkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblx0XHQvKiBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgZGVwcmVjYXRpb24vZGVwcmVjYXRpb24gKi9cblx0XHRjb25zdCBrZXkgPSBldmVudC53aGljaDtcblx0XHRjb25zdCBlbmFibGVkTGlua3MgPSB0aGlzLmxpbmtzLmZpbHRlcigobGluaykgPT4gIWxpbmsubmF2SXRlbS5kaXNhYmxlZCk7XG5cdFx0Y29uc3QgeyBsZW5ndGggfSA9IGVuYWJsZWRMaW5rcztcblxuXHRcdGxldCBwb3NpdGlvbiA9IC0xO1xuXG5cdFx0ZW5hYmxlZExpbmtzLmZvckVhY2goKGxpbmssIGluZGV4KSA9PiB7XG5cdFx0XHRpZiAobGluay5lbFJlZi5uYXRpdmVFbGVtZW50ID09PSB0aGlzLl9kb2N1bWVudC5hY3RpdmVFbGVtZW50KSB7XG5cdFx0XHRcdHBvc2l0aW9uID0gaW5kZXg7XG5cdFx0XHR9XG5cdFx0fSk7XG5cblx0XHRpZiAobGVuZ3RoKSB7XG5cdFx0XHRzd2l0Y2ggKGtleSkge1xuXHRcdFx0XHRjYXNlIEtleS5BcnJvd0xlZnQ6XG5cdFx0XHRcdFx0aWYgKHRoaXMub3JpZW50YXRpb24gPT09ICd2ZXJ0aWNhbCcpIHtcblx0XHRcdFx0XHRcdHJldHVybjtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0cG9zaXRpb24gPSAocG9zaXRpb24gLSAxICsgbGVuZ3RoKSAlIGxlbmd0aDtcblx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0Y2FzZSBLZXkuQXJyb3dSaWdodDpcblx0XHRcdFx0XHRpZiAodGhpcy5vcmllbnRhdGlvbiA9PT0gJ3ZlcnRpY2FsJykge1xuXHRcdFx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRwb3NpdGlvbiA9IChwb3NpdGlvbiArIDEpICUgbGVuZ3RoO1xuXHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRjYXNlIEtleS5BcnJvd0Rvd246XG5cdFx0XHRcdFx0aWYgKHRoaXMub3JpZW50YXRpb24gPT09ICdob3Jpem9udGFsJykge1xuXHRcdFx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRwb3NpdGlvbiA9IChwb3NpdGlvbiArIDEpICUgbGVuZ3RoO1xuXHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRjYXNlIEtleS5BcnJvd1VwOlxuXHRcdFx0XHRcdGlmICh0aGlzLm9yaWVudGF0aW9uID09PSAnaG9yaXpvbnRhbCcpIHtcblx0XHRcdFx0XHRcdHJldHVybjtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0cG9zaXRpb24gPSAocG9zaXRpb24gLSAxICsgbGVuZ3RoKSAlIGxlbmd0aDtcblx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0Y2FzZSBLZXkuSG9tZTpcblx0XHRcdFx0XHRwb3NpdGlvbiA9IDA7XG5cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdGNhc2UgS2V5LkVuZDpcblx0XHRcdFx0XHRwb3NpdGlvbiA9IGxlbmd0aCAtIDE7XG5cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHR9XG5cdFx0XHRpZiAodGhpcy5rZXlib2FyZCA9PT0gJ2NoYW5nZVdpdGhBcnJvd3MnKSB7XG5cdFx0XHRcdHRoaXMuc2VsZWN0KGVuYWJsZWRMaW5rc1twb3NpdGlvbl0ubmF2SXRlbS5pZCk7XG5cdFx0XHR9XG5cdFx0XHRlbmFibGVkTGlua3NbcG9zaXRpb25dLmVsUmVmLm5hdGl2ZUVsZW1lbnQuZm9jdXMoKTtcblxuXHRcdFx0ZXZlbnQucHJldmVudERlZmF1bHQoKTtcblx0XHR9XG5cdH1cblxuXHQvKipcblx0ICogU2VsZWN0cyB0aGUgbmF2IHdpdGggdGhlIGdpdmVuIGlkIGFuZCBzaG93cyBpdHMgYXNzb2NpYXRlZCBwYW5lLlxuXHQgKiBBbnkgb3RoZXIgbmF2IHRoYXQgd2FzIHByZXZpb3VzbHkgc2VsZWN0ZWQgYmVjb21lcyB1bnNlbGVjdGVkIGFuZCBpdHMgYXNzb2NpYXRlZCBwYW5lIGlzIGhpZGRlbi5cblx0ICovXG5cdHNlbGVjdChpZDogYW55KSB7XG5cdFx0dGhpcy5fdXBkYXRlQWN0aXZlSWQoaWQsIGZhbHNlKTtcblx0fVxuXG5cdG5nQWZ0ZXJDb250ZW50SW5pdCgpIHtcblx0XHRpZiAoIWlzRGVmaW5lZCh0aGlzLmFjdGl2ZUlkKSkge1xuXHRcdFx0Y29uc3QgbmV4dElkID0gdGhpcy5pdGVtcy5maXJzdCA/IHRoaXMuaXRlbXMuZmlyc3QuaWQgOiBudWxsO1xuXHRcdFx0aWYgKGlzVmFsaWROYXZJZChuZXh0SWQpKSB7XG5cdFx0XHRcdHRoaXMuX3VwZGF0ZUFjdGl2ZUlkKG5leHRJZCwgZmFsc2UpO1xuXHRcdFx0XHR0aGlzLl9jZC5kZXRlY3RDaGFuZ2VzKCk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0dGhpcy5pdGVtcy5jaGFuZ2VzLnBpcGUodGFrZVVudGlsKHRoaXMuZGVzdHJveSQpKS5zdWJzY3JpYmUoKCkgPT4gdGhpcy5fbm90aWZ5SXRlbUNoYW5nZWQodGhpcy5hY3RpdmVJZCkpO1xuXHR9XG5cblx0bmdPbkNoYW5nZXMoeyBhY3RpdmVJZCB9OiBTaW1wbGVDaGFuZ2VzKTogdm9pZCB7XG5cdFx0aWYgKGFjdGl2ZUlkICYmICFhY3RpdmVJZC5maXJzdENoYW5nZSkge1xuXHRcdFx0dGhpcy5fbm90aWZ5SXRlbUNoYW5nZWQoYWN0aXZlSWQuY3VycmVudFZhbHVlKTtcblx0XHR9XG5cdH1cblxuXHRuZ09uRGVzdHJveSgpIHtcblx0XHR0aGlzLmRlc3Ryb3kkLm5leHQoKTtcblx0fVxuXG5cdHByaXZhdGUgX3VwZGF0ZUFjdGl2ZUlkKG5leHRJZDogYW55LCBlbWl0TmF2Q2hhbmdlID0gdHJ1ZSkge1xuXHRcdGlmICh0aGlzLmFjdGl2ZUlkICE9PSBuZXh0SWQpIHtcblx0XHRcdGxldCBkZWZhdWx0UHJldmVudGVkID0gZmFsc2U7XG5cblx0XHRcdGlmIChlbWl0TmF2Q2hhbmdlKSB7XG5cdFx0XHRcdHRoaXMubmF2Q2hhbmdlLmVtaXQoe1xuXHRcdFx0XHRcdGFjdGl2ZUlkOiB0aGlzLmFjdGl2ZUlkLFxuXHRcdFx0XHRcdG5leHRJZCxcblx0XHRcdFx0XHRwcmV2ZW50RGVmYXVsdDogKCkgPT4ge1xuXHRcdFx0XHRcdFx0ZGVmYXVsdFByZXZlbnRlZCA9IHRydWU7XG5cdFx0XHRcdFx0fSxcblx0XHRcdFx0fSk7XG5cdFx0XHR9XG5cblx0XHRcdGlmICghZGVmYXVsdFByZXZlbnRlZCkge1xuXHRcdFx0XHR0aGlzLmFjdGl2ZUlkID0gbmV4dElkO1xuXHRcdFx0XHR0aGlzLmFjdGl2ZUlkQ2hhbmdlLmVtaXQobmV4dElkKTtcblx0XHRcdFx0dGhpcy5fbm90aWZ5SXRlbUNoYW5nZWQobmV4dElkKTtcblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHRwcml2YXRlIF9ub3RpZnlJdGVtQ2hhbmdlZChuZXh0SXRlbUlkOiBhbnkpIHtcblx0XHR0aGlzLm5hdkl0ZW1DaGFuZ2UkLm5leHQodGhpcy5fZ2V0SXRlbUJ5SWQobmV4dEl0ZW1JZCkpO1xuXHR9XG5cblx0cHJpdmF0ZSBfZ2V0SXRlbUJ5SWQoaXRlbUlkOiBhbnkpOiBOZ2JOYXZJdGVtIHwgbnVsbCB7XG5cdFx0cmV0dXJuICh0aGlzLml0ZW1zICYmIHRoaXMuaXRlbXMuZmluZCgoaXRlbSkgPT4gaXRlbS5pZCA9PT0gaXRlbUlkKSkgfHwgbnVsbDtcblx0fVxufVxuXG5ARGlyZWN0aXZlKHtcblx0c2VsZWN0b3I6ICdbbmdiTmF2TGlua10nLFxuXHRzdGFuZGFsb25lOiB0cnVlLFxuXHRob3N0OiB7XG5cdFx0J1tpZF0nOiAnbmF2SXRlbS5kb21JZCcsXG5cdFx0J1tjbGFzcy5uYXYtbGlua10nOiAndHJ1ZScsXG5cdFx0J1tjbGFzcy5uYXYtaXRlbV0nOiAnaGFzTmF2SXRlbUNsYXNzKCknLFxuXHRcdCdbYXR0ci5yb2xlXSc6IGByb2xlID8gcm9sZSA6IG5hdi5yb2xlcyA/ICd0YWInIDogdW5kZWZpbmVkYCxcblx0XHQnW2NsYXNzLmFjdGl2ZV0nOiAnbmF2SXRlbS5hY3RpdmUnLFxuXHRcdCdbY2xhc3MuZGlzYWJsZWRdJzogJ25hdkl0ZW0uZGlzYWJsZWQnLFxuXHRcdCdbYXR0ci50YWJpbmRleF0nOiAnbmF2SXRlbS5kaXNhYmxlZCA/IC0xIDogdW5kZWZpbmVkJyxcblx0XHQnW2F0dHIuYXJpYS1jb250cm9sc10nOiAnbmF2SXRlbS5pc1BhbmVsSW5Eb20oKSA/IG5hdkl0ZW0ucGFuZWxEb21JZCA6IG51bGwnLFxuXHRcdCdbYXR0ci5hcmlhLXNlbGVjdGVkXSc6ICduYXZJdGVtLmFjdGl2ZScsXG5cdFx0J1thdHRyLmFyaWEtZGlzYWJsZWRdJzogJ2