/** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ import { Attribute, ChangeDetectorRef, ContentChildren, Directive, ElementRef, EventEmitter, forwardRef, Inject, Input, Output, QueryList, TemplateRef } from '@angular/core'; import { isDefined } from '../util/util'; import { NgbNavConfig } from './nav-config'; /** @type {?} */ const isValidNavId = (/** * @param {?} id * @return {?} */ (id) => isDefined(id) && id !== ''); const ɵ0 = isValidNavId; /** @type {?} */ let navCounter = 0; /** * Context passed to the nav content template. * * See [this demo](#/components/nav/examples#keep-content) as the example. * * \@since 5.2.0 * @record */ export function NgbNavContentContext() { } if (false) { /** * If `true`, current nav content is visible and active * @type {?} */ NgbNavContentContext.prototype.$implicit; } /** * This directive must be used to wrap content to be displayed in the nav. * * \@since 5.2.0 */ export class NgbNavContent { /** * @param {?} templateRef */ constructor(templateRef) { this.templateRef = templateRef; } } NgbNavContent.decorators = [ { type: Directive, args: [{ selector: 'ng-template[ngbNavContent]' },] } ]; /** @nocollapse */ NgbNavContent.ctorParameters = () => [ { type: TemplateRef } ]; if (false) { /** @type {?} */ NgbNavContent.prototype.templateRef; } /** * The directive used to group nav link and related nav content. As well as set nav identifier and some options. * * \@since 5.2.0 */ export class NgbNavItem { /** * @param {?} nav * @param {?} elementRef */ constructor(nav, elementRef) { 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; // TODO: cf https://github.com/angular/angular/issues/30106 this._nav = nav; } /** * @return {?} */ 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; } /** * @return {?} */ ngOnInit() { if (!isDefined(this.domId)) { this.domId = `ngb-nav-${navCounter++}`; } } /** * @return {?} */ get active() { return this._nav.activeId === this.id; } /** * @return {?} */ get id() { return isValidNavId(this._id) ? this._id : this.domId; } /** * @return {?} */ get panelDomId() { return `${this.domId}-panel`; } /** * @return {?} */ isPanelInDom() { return (isDefined(this.destroyOnHide) ? !this.destroyOnHide : !this._nav.destroyOnHide) || this.active; } } NgbNavItem.decorators = [ { type: Directive, args: [{ selector: '[ngbNavItem]', exportAs: 'ngbNavItem', host: { '[class.nav-item]': 'true' } },] } ]; /** @nocollapse */ NgbNavItem.ctorParameters = () => [ { type: undefined, decorators: [{ type: Inject, args: [forwardRef((/** * @return {?} */ () => NgbNav)),] }] }, { type: ElementRef } ]; NgbNavItem.propDecorators = { destroyOnHide: [{ type: Input }], disabled: [{ type: Input }], domId: [{ type: Input }], _id: [{ type: Input, args: ['ngbNavItem',] }], contentTpls: [{ type: ContentChildren, args: [NgbNavContent, { descendants: false },] }] }; if (false) { /** * @type {?} * @private */ NgbNavItem.prototype._nav; /** * If `true`, non-active current nav item content will be removed from DOM * Otherwise it will just be hidden * @type {?} */ NgbNavItem.prototype.destroyOnHide; /** * 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. * @type {?} */ NgbNavItem.prototype.disabled; /** * The id used for the DOM elements. * Must be unique inside the document in case you have multiple `ngbNav`s on the page. * * Autogenerated as `ngb-nav-XXX` if not provided. * @type {?} */ NgbNavItem.prototype.domId; /** * The id used as a model for active nav. * It can be anything, but must be unique inside one `ngbNav`. * * The only limitation is that it is not possible to have the `''` (empty string) as id, * because ` ngbNavItem `, `ngbNavItem=''` and `[ngbNavItem]="''"` are indistinguishable * @type {?} */ NgbNavItem.prototype._id; /** @type {?} */ NgbNavItem.prototype.contentTpl; /** @type {?} */ NgbNavItem.prototype.contentTpls; /** @type {?} */ NgbNavItem.prototype.elementRef; } /** * A nav directive that helps with implementing tabbed navigation components. * * \@since 5.2.0 */ export class NgbNav { /** * @param {?} role * @param {?} config * @param {?} _cd */ constructor(role, config, _cd) { this.role = role; this._cd = _cd; /** * 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(); /** * 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.destroyOnHide = config.destroyOnHide; this.orientation = config.orientation; this.roles = config.roles; } /** * @param {?} item * @return {?} */ click(item) { if (!item.disabled) { this._updateActiveId(item.id); } } /** * 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. * @param {?} id * @return {?} */ select(id) { this._updateActiveId(id, false); } /** * @return {?} */ ngAfterContentInit() { if (!isDefined(this.activeId)) { /** @type {?} */ const nextId = this.items.first ? this.items.first.id : null; if (isValidNavId(nextId)) { this._updateActiveId(nextId, false); this._cd.detectChanges(); } } } /** * @private * @param {?} nextId * @param {?=} emitNavChange * @return {?} */ _updateActiveId(nextId, emitNavChange = true) { if (this.activeId !== nextId) { /** @type {?} */ let defaultPrevented = false; if (emitNavChange) { this.navChange.emit({ activeId: this.activeId, nextId, preventDefault: (/** * @return {?} */ () => { defaultPrevented = true; }) }); } if (!defaultPrevented) { this.activeId = nextId; this.activeIdChange.emit(nextId); } } } } NgbNav.decorators = [ { type: Directive, args: [{ selector: '[ngbNav]', exportAs: 'ngbNav', 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`, } },] } ]; /** @nocollapse */ NgbNav.ctorParameters = () => [ { type: String, decorators: [{ type: Attribute, args: ['role',] }] }, { type: NgbNavConfig }, { type: ChangeDetectorRef } ]; NgbNav.propDecorators = { activeId: [{ type: Input }], activeIdChange: [{ type: Output }], destroyOnHide: [{ type: Input }], orientation: [{ type: Input }], roles: [{ type: Input }], items: [{ type: ContentChildren, args: [NgbNavItem,] }], navChange: [{ type: Output }] }; if (false) { /** * The id of the nav that should be active * * You could also use the `.select()` method and the `(navChange)` event * @type {?} */ NgbNav.prototype.activeId; /** * 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 * @type {?} */ NgbNav.prototype.activeIdChange; /** * If `true`, non-active nav content will be removed from DOM * Otherwise it will just be hidden * @type {?} */ NgbNav.prototype.destroyOnHide; /** * The orientation of navs. * * Using `vertical` will also add the `aria-orientation` attribute * @type {?} */ NgbNav.prototype.orientation; /** * Role attribute generating strategy: * - `false` - no role attributes will be generated * - `'tablist'` - 'tablist', 'tab' and 'tabpanel' will be generated (default) * @type {?} */ NgbNav.prototype.roles; /** @type {?} */ NgbNav.prototype.items; /** * 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. * @type {?} */ NgbNav.prototype.navChange; /** @type {?} */ NgbNav.prototype.role; /** * @type {?} * @private */ NgbNav.prototype._cd; } /** * A directive to put on the nav link. * * \@since 5.2.0 */ export class NgbNavLink { /** * @param {?} role * @param {?} navItem * @param {?} nav */ constructor(role, navItem, nav) { this.role = role; this.navItem = navItem; this.nav = nav; } /** * @return {?} */ 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; } } NgbNavLink.decorators = [ { type: Directive, args: [{ selector: 'a[ngbNavLink]', host: { '[id]': 'navItem.domId', '[class.nav-link]': 'true', '[class.nav-item]': 'hasNavItemClass()', '[attr.role]': `role ? role : nav.roles ? 'tab' : undefined`, 'href': '', '[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', '(click)': 'nav.click(navItem); $event.preventDefault()' } },] } ]; /** @nocollapse */ NgbNavLink.ctorParameters = () => [ { type: String, decorators: [{ type: Attribute, args: ['role',] }] }, { type: NgbNavItem }, { type: NgbNav } ]; if (false) { /** @type {?} */ NgbNavLink.prototype.role; /** @type {?} */ NgbNavLink.prototype.navItem; /** @type {?} */ NgbNavLink.prototype.nav; } /** * The payload of the 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()`. * * \@since 5.2.0 * @record */ export function NgbNavChangeEvent() { } if (false) { /** * Id of the currently active nav. * @type {?} */ NgbNavChangeEvent.prototype.activeId; /** * Id of the newly selected nav. * @type {?} */ NgbNavChangeEvent.prototype.nextId; /** * Function that will prevent nav change if called. * @type {?} */ NgbNavChangeEvent.prototype.preventDefault; } export { ɵ0 }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmF2LmpzIiwic291cmNlUm9vdCI6Im5nOi8vQG5nLWJvb3RzdHJhcC9uZy1ib290c3RyYXAvIiwic291cmNlcyI6WyJuYXYvbmF2LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7QUFBQSxPQUFPLEVBR0wsU0FBUyxFQUNULGlCQUFpQixFQUNqQixlQUFlLEVBQ2YsU0FBUyxFQUNULFVBQVUsRUFDVixZQUFZLEVBQ1osVUFBVSxFQUNWLE1BQU0sRUFDTixLQUFLLEVBRUwsTUFBTSxFQUNOLFNBQVMsRUFDVCxXQUFXLEVBQ1osTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFDLFNBQVMsRUFBQyxNQUFNLGNBQWMsQ0FBQztBQUN2QyxPQUFPLEVBQUMsWUFBWSxFQUFDLE1BQU0sY0FBYyxDQUFDOztNQUVwQyxZQUFZOzs7O0FBQUcsQ0FBQyxFQUFPLEVBQUUsRUFBRSxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUMsSUFBSSxFQUFFLEtBQUssRUFBRSxDQUFBOzs7SUFFeEQsVUFBVSxHQUFHLENBQUM7Ozs7Ozs7OztBQVNsQiwwQ0FLQzs7Ozs7O0lBREMseUNBQW1COzs7Ozs7O0FBVXJCLE1BQU0sT0FBTyxhQUFhOzs7O0lBQ3hCLFlBQW1CLFdBQTZCO1FBQTdCLGdCQUFXLEdBQVgsV0FBVyxDQUFrQjtJQUFHLENBQUM7OztZQUZyRCxTQUFTLFNBQUMsRUFBQyxRQUFRLEVBQUUsNEJBQTRCLEVBQUM7Ozs7WUE3QmpELFdBQVc7Ozs7SUErQkMsb0NBQW9DOzs7Ozs7O0FBVWxELE1BQU0sT0FBTyxVQUFVOzs7OztJQXFDckIsWUFBOEMsR0FBRyxFQUFTLFVBQTJCO1FBQTNCLGVBQVUsR0FBVixVQUFVLENBQWlCOzs7Ozs7UUF2QjVFLGFBQVEsR0FBRyxLQUFLLENBQUM7UUF3QnhCLDJEQUEyRDtRQUMzRCxJQUFJLENBQUMsSUFBSSxHQUFHLEdBQUcsQ0FBQztJQUNsQixDQUFDOzs7O0lBRUQscUJBQXFCO1FBQ25CLDhGQUE4RjtRQUM5Riw4RUFBOEU7UUFDOUUsaUVBQWlFO1FBQ2pFLDJEQUEyRDtRQUMzRCxJQUFJLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDO0lBQzNDLENBQUM7Ozs7SUFFRCxRQUFRO1FBQ04sSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUU7WUFDMUIsSUFBSSxDQUFDLEtBQUssR0FBRyxXQUFXLFVBQVUsRUFBRSxFQUFFLENBQUM7U0FDeEM7SUFDSCxDQUFDOzs7O0lBRUQsSUFBSSxNQUFNLEtBQUssT0FBTyxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsS0FBSyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQzs7OztJQUV2RCxJQUFJLEVBQUUsS0FBSyxPQUFPLFlBQVksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDOzs7O0lBRW5FLElBQUksVUFBVSxLQUFLLE9BQU8sR0FBRyxJQUFJLENBQUMsS0FBSyxRQUFRLENBQUMsQ0FBQyxDQUFDOzs7O0lBRWxELFlBQVk7UUFDVixPQUFPLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksSUFBSSxDQUFDLE1BQU0sQ0FBQztJQUN6RyxDQUFDOzs7WUFqRUYsU0FBUyxTQUFDLEVBQUMsUUFBUSxFQUFFLGNBQWMsRUFBRSxRQUFRLEVBQUUsWUFBWSxFQUFFLElBQUksRUFBRSxFQUFDLGtCQUFrQixFQUFFLE1BQU0sRUFBQyxFQUFDOzs7OzRDQXNDbEYsTUFBTSxTQUFDLFVBQVU7OztvQkFBQyxHQUFHLEVBQUUsQ0FBQyxNQUFNLEVBQUM7WUF0RjVDLFVBQVU7Ozs0QkF3RFQsS0FBSzt1QkFPTCxLQUFLO29CQVFMLEtBQUs7a0JBU0wsS0FBSyxTQUFDLFlBQVk7MEJBSWxCLGVBQWUsU0FBQyxhQUFhLEVBQUUsRUFBQyxXQUFXLEVBQUUsS0FBSyxFQUFDOzs7Ozs7O0lBbENwRCwwQkFBcUI7Ozs7OztJQU1yQixtQ0FBdUI7Ozs7Ozs7SUFPdkIsOEJBQTBCOzs7Ozs7OztJQVExQiwyQkFBdUI7Ozs7Ozs7OztJQVN2Qix5QkFBOEI7O0lBRTlCLGdDQUFpQzs7SUFFakMsaUNBQTRGOztJQUV6QyxnQ0FBa0M7Ozs7Ozs7QUE4Q3ZGLE1BQU0sT0FBTyxNQUFNOzs7Ozs7SUFzQ2pCLFlBQXNDLElBQVksRUFBRSxNQUFvQixFQUFVLEdBQXNCO1FBQWxFLFNBQUksR0FBSixJQUFJLENBQVE7UUFBZ0MsUUFBRyxHQUFILEdBQUcsQ0FBbUI7Ozs7Ozs7UUF4QjlGLG1CQUFjLEdBQUcsSUFBSSxZQUFZLEVBQU8sQ0FBQzs7Ozs7Ozs7UUFxQ3pDLGNBQVMsR0FBRyxJQUFJLFlBQVksRUFBcUIsQ0FBQztRQVoxRCxJQUFJLENBQUMsYUFBYSxHQUFHLE1BQU0sQ0FBQyxhQUFhLENBQUM7UUFDMUMsSUFBSSxDQUFDLFdBQVcsR0FBRyxNQUFNLENBQUMsV0FBVyxDQUFDO1FBQ3RDLElBQUksQ0FBQyxLQUFLLEdBQUcsTUFBTSxDQUFDLEtBQUssQ0FBQztJQUM1QixDQUFDOzs7OztJQVdELEtBQUssQ0FBQyxJQUFnQjtRQUNwQixJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRTtZQUNsQixJQUFJLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztTQUMvQjtJQUNILENBQUM7Ozs7Ozs7SUFNRCxNQUFNLENBQUMsRUFBTyxJQUFJLElBQUksQ0FBQyxlQUFlLENBQUMsRUFBRSxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQzs7OztJQUVwRCxrQkFBa0I7UUFDaEIsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLEVBQUU7O2tCQUN2QixNQUFNLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSTtZQUM1RCxJQUFJLFlBQVksQ0FBQyxNQUFNLENBQUMsRUFBRTtnQkFDeEIsSUFBSSxDQUFDLGVBQWUsQ0FBQyxNQUFNLEVBQUUsS0FBSyxDQUFDLENBQUM7Z0JBQ3BDLElBQUksQ0FBQyxHQUFHLENBQUMsYUFBYSxFQUFFLENBQUM7YUFDMUI7U0FDRjtJQUNILENBQUM7Ozs7Ozs7SUFFTyxlQUFlLENBQUMsTUFBVyxFQUFFLGFBQWEsR0FBRyxJQUFJO1FBQ3ZELElBQUksSUFBSSxDQUFDLFFBQVEsS0FBSyxNQUFNLEVBQUU7O2dCQUN4QixnQkFBZ0IsR0FBRyxLQUFLO1lBRTVCLElBQUksYUFBYSxFQUFFO2dCQUNqQixJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxFQUFDLFFBQVEsRUFBRSxJQUFJLENBQUMsUUFBUSxFQUFFLE1BQU0sRUFBRSxjQUFjOzs7b0JBQUUsR0FBRyxFQUFFLEdBQUcsZ0JBQWdCLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFBLEVBQUMsQ0FBQyxDQUFDO2FBQzVHO1lBRUQsSUFBSSxDQUFDLGdCQUFnQixFQUFFO2dCQUNyQixJQUFJLENBQUMsUUFBUSxHQUFHLE1BQU0sQ0FBQztnQkFDdkIsSUFBSSxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7YUFDbEM7U0FDRjtJQUNILENBQUM7OztZQWxHRixTQUFTLFNBQUM7Z0JBQ1QsUUFBUSxFQUFFLFVBQVU7Z0JBQ3BCLFFBQVEsRUFBRSxRQUFRO2dCQUNsQixJQUFJLEVBQUU7b0JBQ0osYUFBYSxFQUFFLE1BQU07b0JBQ3JCLHFCQUFxQixFQUFFLDRCQUE0QjtvQkFDbkQseUJBQXlCLEVBQUUsNEVBQTRFO29CQUN2RyxhQUFhLEVBQUUsNkNBQTZDO2lCQUM3RDthQUNGOzs7O3lDQXVDYyxTQUFTLFNBQUMsTUFBTTtZQS9KdkIsWUFBWTtZQWRsQixpQkFBaUI7Ozt1QkE2SWhCLEtBQUs7NkJBUUwsTUFBTTs0QkFNTixLQUFLOzBCQU9MLEtBQUs7b0JBT0wsS0FBSztvQkFFTCxlQUFlLFNBQUMsVUFBVTt3QkFlMUIsTUFBTTs7Ozs7Ozs7O0lBN0NQLDBCQUF1Qjs7Ozs7Ozs7SUFRdkIsZ0NBQW1EOzs7Ozs7SUFNbkQsK0JBQXVCOzs7Ozs7O0lBT3ZCLDZCQUFnRDs7Ozs7OztJQU9oRCx1QkFBa0M7O0lBRWxDLHVCQUEwRDs7Ozs7Ozs7O0lBZTFELDJCQUE0RDs7SUFiaEQsc0JBQXNDOzs7OztJQUF3QixxQkFBOEI7Ozs7Ozs7QUE0RTFHLE1BQU0sT0FBTyxVQUFVOzs7Ozs7SUFDckIsWUFBc0MsSUFBWSxFQUFTLE9BQW1CLEVBQVMsR0FBVztRQUE1RCxTQUFJLEdBQUosSUFBSSxDQUFRO1FBQVMsWUFBTyxHQUFQLE9BQU8sQ0FBWTtRQUFTLFFBQUcsR0FBSCxHQUFHLENBQVE7SUFBRyxDQUFDOzs7O0lBRXRHLGVBQWU7UUFDYix3R0FBd0c7UUFDeEcsT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxhQUFhLENBQUMsUUFBUSxLQUFLLElBQUksQ0FBQyxZQUFZLENBQUM7SUFDOUUsQ0FBQzs7O1lBdkJGLFNBQVMsU0FBQztnQkFDVCxRQUFRLEVBQUUsZUFBZTtnQkFDekIsSUFBSSxFQUFFO29CQUNKLE1BQU0sRUFBRSxlQUFlO29CQUN2QixrQkFBa0IsRUFBRSxNQUFNO29CQUMxQixrQkFBa0IsRUFBRSxtQkFBbUI7b0JBQ3ZDLGFBQWEsRUFBRSw2Q0FBNkM7b0JBQzVELE1BQU0sRUFBRSxFQUFFO29CQUNWLGdCQUFnQixFQUFFLGdCQUFnQjtvQkFDbEMsa0JBQWtCLEVBQUUsa0JBQWtCO29CQUN0QyxpQkFBaUIsRUFBRSxtQ0FBbUM7b0JBQ3RELHNCQUFzQixFQUFFLG9EQUFvRDtvQkFDNUUsc0JBQXNCLEVBQUUsZ0JBQWdCO29CQUN4QyxzQkFBc0IsRUFBRSxrQkFBa0I7b0JBQzFDLFNBQVMsRUFBRSw2Q0FBNkM7aUJBQ3pEO2FBQ0Y7Ozs7eUNBRWMsU0FBUyxTQUFDLE1BQU07WUFBdUMsVUFBVTtZQUFjLE1BQU07Ozs7SUFBdEYsMEJBQXNDOztJQUFFLDZCQUEwQjs7SUFBRSx5QkFBa0I7Ozs7Ozs7Ozs7QUFnQnBHLHVDQWVDOzs7Ozs7SUFYQyxxQ0FBYzs7Ozs7SUFLZCxtQ0FBWTs7Ozs7SUFLWiwyQ0FBMkIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBBZnRlckNvbnRlbnRDaGVja2VkLFxuICBBZnRlckNvbnRlbnRJbml0LFxuICBBdHRyaWJ1dGUsXG4gIENoYW5nZURldGVjdG9yUmVmLFxuICBDb250ZW50Q2hpbGRyZW4sXG4gIERpcmVjdGl2ZSxcbiAgRWxlbWVudFJlZixcbiAgRXZlbnRFbWl0dGVyLFxuICBmb3J3YXJkUmVmLFxuICBJbmplY3QsXG4gIElucHV0LFxuICBPbkluaXQsXG4gIE91dHB1dCxcbiAgUXVlcnlMaXN0LFxuICBUZW1wbGF0ZVJlZlxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7aXNEZWZpbmVkfSBmcm9tICcuLi91dGlsL3V0aWwnO1xuaW1wb3J0IHtOZ2JOYXZDb25maWd9IGZyb20gJy4vbmF2LWNvbmZpZyc7XG5cbmNvbnN0IGlzVmFsaWROYXZJZCA9IChpZDogYW55KSA9PiBpc0RlZmluZWQoaWQpICYmIGlkICE9PSAnJztcblxubGV0IG5hdkNvdW50ZXIgPSAwO1xuXG4vKipcbiAqIENvbnRleHQgcGFzc2VkIHRvIHRoZSBuYXYgY29udGVudCB0ZW1wbGF0ZS5cbiAqXG4gKiBTZWUgW3RoaXMgZGVtb10oIy9jb21wb25lbnRzL25hdi9leGFtcGxlcyNrZWVwLWNvbnRlbnQpIGFzIHRoZSBleGFtcGxlLlxuICpcbiAqIEBzaW5jZSA1LjIuMFxuICovXG5leHBvcnQgaW50ZXJmYWNlIE5nYk5hdkNvbnRlbnRDb250ZXh0IHtcbiAgLyoqXG4gICAqIElmIGB0cnVlYCwgY3VycmVudCBuYXYgY29udGVudCBpcyB2aXNpYmxlIGFuZCBhY3RpdmVcbiAgICovXG4gICRpbXBsaWNpdDogYm9vbGVhbjtcbn1cblxuXG4vKipcbiAqIFRoaXMgZGlyZWN0aXZlIG11c3QgYmUgdXNlZCB0byB3cmFwIGNvbnRlbnQgdG8gYmUgZGlzcGxheWVkIGluIHRoZSBuYXYuXG4gKlxuICogQHNpbmNlIDUuMi4wXG4gKi9cbkBEaXJlY3RpdmUoe3NlbGVjdG9yOiAnbmctdGVtcGxhdGVbbmdiTmF2Q29udGVudF0nfSlcbmV4cG9ydCBjbGFzcyBOZ2JOYXZDb250ZW50IHtcbiAgY29uc3RydWN0b3IocHVibGljIHRlbXBsYXRlUmVmOiBUZW1wbGF0ZVJlZjxhbnk+KSB7fVxufVxuXG5cbi8qKlxuICogVGhlIGRpcmVjdGl2ZSB1c2VkIHRvIGdyb3VwIG5hdiBsaW5rIGFuZCByZWxhdGVkIG5hdiBjb250ZW50LiBBcyB3ZWxsIGFzIHNldCBuYXYgaWRlbnRpZmllciBhbmQgc29tZSBvcHRpb25zLlxuICpcbiAqIEBzaW5jZSA1LjIuMFxuICovXG5ARGlyZWN0aXZlKHtzZWxlY3RvcjogJ1tuZ2JOYXZJdGVtXScsIGV4cG9ydEFzOiAnbmdiTmF2SXRlbScsIGhvc3Q6IHsnW2NsYXNzLm5hdi1pdGVtXSc6ICd0cnVlJ319KVxuZXhwb3J0IGNsYXNzIE5nYk5hdkl0ZW0gaW1wbGVtZW50cyBBZnRlckNvbnRlbnRDaGVja2VkLCBPbkluaXQge1xuICBwcml2YXRlIF9uYXY6IE5nYk5hdjtcblxuICAvKipcbiAgICogSWYgYHRydWVgLCBub24tYWN0aXZlIGN1cnJlbnQgbmF2IGl0ZW0gY29udGVudCB3aWxsIGJlIHJlbW92ZWQgZnJvbSBET01cbiAgICogT3RoZXJ3aXNlIGl0IHdpbGwganVzdCBiZSBoaWRkZW5cbiAgICovXG4gIEBJbnB1dCgpIGRlc3Ryb3lPbkhpZGU7XG5cbiAgLyoqXG4gICAqIElmIGB0cnVlYCwgdGhlIGN1cnJlbnQgbmF2IGl0ZW0gaXMgZGlzYWJsZWQgYW5kIGNhbid0IGJlIHRvZ2dsZWQgYnkgdXNlci5cbiAgICpcbiAgICogTmV2ZXJ0aGVsZXNzIGRpc2FibGVkIG5hdiBjYW4gYmUgc2VsZWN0ZWQgcHJvZ3JhbW1hdGljYWxseSB2aWEgdGhlIGAuc2VsZWN0KClgIG1ldGhvZCBhbmQgdGhlIGBbYWN0aXZlSWRdYCBiaW5kaW5nLlxuICAgKi9cbiAgQElucHV0KCkgZGlzYWJsZWQgPSBmYWxzZTtcblxuICAvKipcbiAgICogVGhlIGlkIHVzZWQgZm9yIHRoZSBET00gZWxlbWVudHMuXG4gICAqIE11c3QgYmUgdW5pcXVlIGluc2lkZSB0aGUgZG9jdW1lbnQgaW4gY2FzZSB5b3UgaGF2ZSBtdWx0aXBsZSBgbmdiTmF2YHMgb24gdGhlIHBhZ2UuXG4gICAqXG4gICAqIEF1dG9nZW5lcmF0ZWQgYXMgYG5nYi1uYXYtWFhYYCBpZiBub3QgcHJvdmlkZWQuXG4gICAqL1xuICBASW5wdXQoKSBkb21JZDogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgaWQgdXNlZCBhcyBhIG1vZGVsIGZvciBhY3RpdmUgbmF2LlxuICAgKiBJdCBjYW4gYmUgYW55dGhpbmcsIGJ1dCBtdXN0IGJlIHVuaXF1ZSBpbnNpZGUgb25lIGBuZ2JOYXZgLlxuICAgKlxuICAgKiBUaGUgb25seSBsaW1pdGF0aW9uIGlzIHRoYXQgaXQgaXMgbm90IHBvc3NpYmxlIHRvIGhhdmUgdGhlIGAnJ2AgKGVtcHR5IHN0cmluZykgYXMgaWQsXG4gICAqIGJlY2F1c2UgYCBuZ2JOYXZJdGVtIGAsIGBuZ2JOYXZJdGVtPScnYCBhbmQgYFtuZ2JOYXZJdGVtXT1cIicnXCJgIGFyZSBpbmRpc3Rpbmd1aXNoYWJsZVxuICAgKi9cbiAgQElucHV0KCduZ2JOYXZJdGVtJykgX2lkOiBhbnk7XG5cbiAgY29udGVudFRwbDogTmdiTmF2Q29udGVudCB8IG51bGw7XG5cbiAgQENvbnRlbnRDaGlsZHJlbihOZ2JOYXZDb250ZW50LCB7ZGVzY2VuZGFudHM6IGZhbHNlfSkgY29udGVudFRwbHM6IFF1ZXJ5TGlzdDxOZ2JOYXZDb250ZW50PjtcblxuICBjb25zdHJ1Y3RvcihASW5qZWN0KGZvcndhcmRSZWYoKCkgPT4gTmdiTmF2KSkgbmF2LCBwdWJsaWMgZWxlbWVudFJlZjogRWxlbWVudFJlZjxhbnk+KSB7XG4gICAgLy8gVE9ETzogY2YgaHR0cHM6Ly9naXRodWIuY29tL2FuZ3VsYXIvYW5ndWxhci9pc3N1ZXMvMzAxMDZcbiAgICB0aGlzLl9uYXYgPSBuYXY7XG4gIH1cblxuICBuZ0FmdGVyQ29udGVudENoZWNrZWQoKSB7XG4gICAgLy8gV2UgYXJlIHVzaW5nIEBDb250ZW50Q2hpbGRyZW4gaW5zdGVhZCBvZiBAQ29udGVudENoaWxkIGFzIGluIHRoZSBBbmd1bGFyIHZlcnNpb24gYmVpbmcgdXNlZFxuICAgIC8vIG9ubHkgQENvbnRlbnRDaGlsZHJlbiBhbGxvd3MgdXMgdG8gc3BlY2lmeSB0aGUge2Rlc2NlbmRhbnRzOiBmYWxzZX0gb3B0aW9uLlxuICAgIC8vIFdpdGhvdXQge2Rlc2NlbmRhbnRzOiBmYWxzZX0gd2UgYXJlIGhpdHRpbmcgYnVncyBkZXNjcmliZWQgaW46XG4gICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL25nLWJvb3RzdHJhcC9uZy1ib290c3RyYXAvaXNzdWVzLzIyNDBcbiAgICB0aGlzLmNvbnRlbnRUcGwgPSB0aGlzLmNvbnRlbnRUcGxzLmZpcnN0O1xuICB9XG5cbiAgbmdPbkluaXQoKSB7XG4gICAgaWYgKCFpc0RlZmluZWQodGhpcy5kb21JZCkpIHtcbiAgICAgIHRoaXMuZG9tSWQgPSBgbmdiLW5hdi0ke25hdkNvdW50ZXIrK31gO1xuICAgIH1cbiAgfVxuXG4gIGdldCBhY3RpdmUoKSB7IHJldHVybiB0aGlzLl9uYXYuYWN0aXZlSWQgPT09IHRoaXMuaWQ7IH1cblxuICBnZXQgaWQoKSB7IHJldHVybiBpc1ZhbGlkTmF2SWQodGhpcy5faWQpID8gdGhpcy5faWQgOiB0aGlzLmRvbUlkOyB9XG5cbiAgZ2V0IHBhbmVsRG9tSWQoKSB7IHJldHVybiBgJHt0aGlzLmRvbUlkfS1wYW5lbGA7IH1cblxuICBpc1BhbmVsSW5Eb20oKSB7XG4gICAgcmV0dXJuIChpc0RlZmluZWQodGhpcy5kZXN0cm95T25IaWRlKSA/ICF0aGlzLmRlc3Ryb3lPbkhpZGUgOiAhdGhpcy5fbmF2LmRlc3Ryb3lPbkhpZGUpIHx8IHRoaXMuYWN0aXZlO1xuICB9XG59XG5cblxuLyoqXG4gKiBBIG5hdiBkaXJlY3RpdmUgdGhhdCBoZWxwcyB3aXRoIGltcGxlbWVudGluZyB0YWJiZWQgbmF2aWdhdGlvbiBjb21wb25lbnRzLlxuICpcbiAqIEBzaW5jZSA1LjIuMFxuICovXG5ARGlyZWN0aXZlKHtcbiAgc2VsZWN0b3I6ICdbbmdiTmF2XScsXG4gIGV4cG9ydEFzOiAnbmdiTmF2JyxcbiAgaG9zdDoge1xuICAgICdbY2xhc3MubmF2XSc6ICd0cnVlJyxcbiAgICAnW2NsYXNzLmZsZXgtY29sdW1uXSc6IGBvcmllbnRhdGlvbiA9PT0gJ3ZlcnRpY2FsJ2AsXG4gICAgJ1thdHRyLmFyaWEtb3JpZW50YXRpb25dJzogYG9yaWVudGF0aW9uID09PSAndmVydGljYWwnICYmIHJvbGVzID09PSAndGFibGlzdCcgPyAndmVydGljYWwnIDogdW5kZWZpbmVkYCxcbiAgICAnW2F0dHIucm9sZV0nOiBgcm9sZSA/IHJvbGUgOiByb2xlcyA/ICd0YWJsaXN0JyA6IHVuZGVmaW5lZGAsXG4gIH1cbn0pXG5leHBvcnQgY2xhc3MgTmdiTmF2IGltcGxlbWVudHMgQWZ0ZXJDb250ZW50SW5pdCB7XG4gIC8qKlxuICAgKiBUaGUgaWQgb2YgdGhlIG5hdiB0aGF0IHNob3VsZCBiZSBhY3RpdmVcbiAgICpcbiAgICogWW91IGNvdWxkIGFsc28gdXNlIHRoZSBgLnNlbGVjdCgpYCBtZXRob2QgYW5kIHRoZSBgKG5hdkNoYW5nZSlgIGV2ZW50XG4gICAqL1xuICBASW5wdXQoKSBhY3RpdmVJZDogYW55O1xuXG4gIC8qKlxuICAgKiBUaGUgZXZlbnQgZW1pdHRlZCBhZnRlciB0aGUgYWN0aXZlIG5hdiBjaGFuZ2VzXG4gICAqIFRoZSBwYXlsb2FkIG9mIHRoZSBldmVudCBpcyB0aGUgbmV3bHkgYWN0aXZlIG5hdiBpZFxuICAgKlxuICAgKiBJZiB5b3Ugd2FudCB0byBwcmV2ZW50IG5hdiBjaGFuZ2UsIHlvdSBzaG91bGQgdXNlIGAobmF2Q2hhbmdlKWAgZXZlbnRcbiAgICovXG4gIEBPdXRwdXQoKSBhY3RpdmVJZENoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8YW55PigpO1xuXG4gIC8qKlxuICAgKiBJZiBgdHJ1ZWAsIG5vbi1hY3RpdmUgbmF2IGNvbnRlbnQgd2lsbCBiZSByZW1vdmVkIGZyb20gRE9NXG4gICAqIE90aGVyd2lzZSBpdCB3aWxsIGp1c3QgYmUgaGlkZGVuXG4gICAqL1xuICBASW5wdXQoKSBkZXN0cm95T25IaWRlO1xuXG4gIC8qKlxuICAgKiBUaGUgb3JpZW50YXRpb24gb2YgbmF2cy5cbiAgICpcbiAgICogVXNpbmcgYHZlcnRpY2FsYCB3aWxsIGFsc28gYWRkIHRoZSBgYXJpYS1vcmllbnRhdGlvbmAgYXR0cmlidXRlXG4gICAqL1xuICBASW5wdXQoKSBvcmllbnRhdGlvbjogJ2hvcml6b250YWwnIHwgJ3ZlcnRpY2FsJztcblxuICAvKipcbiAgICogUm9sZSBhdHRyaWJ1dGUgZ2VuZXJhdGluZyBzdHJhdGVneTpcbiAgICogLSBgZmFsc2VgIC0gbm8gcm9sZSBhdHRyaWJ1dGVzIHdpbGwgYmUgZ2VuZXJhdGVkXG4gICAqIC0gYCd0YWJsaXN0J2AgLSAndGFibGlzdCcsICd0YWInIGFuZCAndGFicGFuZWwnIHdpbGwgYmUgZ2VuZXJhdGVkIChkZWZhdWx0KVxuICAgKi9cbiAgQElucHV0KCkgcm9sZXM6ICd0YWJsaXN0JyB8IGZhbHNlO1xuXG4gIEBDb250ZW50Q2hpbGRyZW4oTmdiTmF2SXRlbSkgaXRlbXM6IFF1ZXJ5TGlzdDxOZ2JOYXZJdGVtPjtcblxuICBjb25zdHJ1Y3RvcihAQXR0cmlidXRlKCdyb2xlJykgcHVibGljIHJvbGU6IHN0cmluZywgY29uZmlnOiBOZ2JOYXZDb25maWcsIHByaXZhdGUgX2NkOiBDaGFuZ2VEZXRlY3RvclJlZikge1xuICAgIHRoaXMuZGVzdHJveU9uSGlkZSA9IGNvbmZpZy5kZXN0cm95T25IaWRlO1xuICAgIHRoaXMub3JpZW50YXRpb24gPSBjb25maWcub3JpZW50YXRpb247XG4gICAgdGhpcy5yb2xlcyA9IGNvbmZpZy5yb2xlcztcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgbmF2IGNoYW5nZSBldmVudCBlbWl0dGVkIHJpZ2h0IGJlZm9yZSB0aGUgbmF2IGNoYW5nZSBoYXBwZW5zIG9uIHVzZXIgY2xpY2suXG4gICAqXG4gICAqIFRoaXMgZXZlbnQgd29uJ3QgYmUgZW1pdHRlZCBpZiBuYXYgaXMgY2hhbmdlZCBwcm9ncmFtbWF0aWNhbGx5IHZpYSBgW2FjdGl2ZUlkXWAgb3IgYC5zZWxlY3QoKWAuXG4gICAqXG4gICAqIFNlZSBbYE5nYk5hdkNoYW5nZUV2ZW50YF0oIy9jb21wb25lbnRzL25hdi9hcGkjTmdiTmF2Q2hhbmdlRXZlbnQpIGZvciBwYXlsb2FkIGRldGFpbHMuXG4gICAqL1xuICBAT3V0cHV0KCkgbmF2Q2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxOZ2JOYXZDaGFuZ2VFdmVudD4oKTtcblxuICBjbGljayhpdGVtOiBOZ2JOYXZJdGVtKSB7XG4gICAgaWYgKCFpdGVtLmRpc2FibGVkKSB7XG4gICAgICB0aGlzLl91cGRhdGVBY3RpdmVJZChpdGVtLmlkKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogU2VsZWN0cyB0aGUgbmF2IHdpdGggdGhlIGdpdmVuIGlkIGFuZCBzaG93cyBpdHMgYXNzb2NpYXRlZCBwYW5lLlxuICAgKiBBbnkgb3RoZXIgbmF2IHRoYXQgd2FzIHByZXZpb3VzbHkgc2VsZWN0ZWQgYmVjb21lcyB1bnNlbGVjdGVkIGFuZCBpdHMgYXNzb2NpYXRlZCBwYW5lIGlzIGhpZGRlbi5cbiAgICovXG4gIHNlbGVjdChpZDogYW55KSB7IHRoaXMuX3VwZGF0ZUFjdGl2ZUlkKGlkLCBmYWxzZSk7IH1cblxuICBuZ0FmdGVyQ29udGVudEluaXQoKSB7XG4gICAgaWYgKCFpc0RlZmluZWQodGhpcy5hY3RpdmVJZCkpIHtcbiAgICAgIGNvbnN0IG5leHRJZCA9IHRoaXMuaXRlbXMuZmlyc3QgPyB0aGlzLml0ZW1zLmZpcnN0LmlkIDogbnVsbDtcbiAgICAgIGlmIChpc1ZhbGlkTmF2SWQobmV4dElkKSkge1xuICAgICAgICB0aGlzLl91cGRhdGVBY3RpdmVJZChuZXh0SWQsIGZhbHNlKTtcbiAgICAgICAgdGhpcy5fY2QuZGV0ZWN0Q2hhbmdlcygpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgX3VwZGF0ZUFjdGl2ZUlkKG5leHRJZDogYW55LCBlbWl0TmF2Q2hhbmdlID0gdHJ1ZSkge1xuICAgIGlmICh0aGlzLmFjdGl2ZUlkICE9PSBuZXh0SWQpIHtcbiAgICAgIGxldCBkZWZhdWx0UHJldmVudGVkID0gZmFsc2U7XG5cbiAgICAgIGlmIChlbWl0TmF2Q2hhbmdlKSB7XG4gICAgICAgIHRoaXMubmF2Q2hhbmdlLmVtaXQoe2FjdGl2ZUlkOiB0aGlzLmFjdGl2ZUlkLCBuZXh0SWQsIHByZXZlbnREZWZhdWx0OiAoKSA9PiB7IGRlZmF1bHRQcmV2ZW50ZWQgPSB0cnVlOyB9fSk7XG4gICAgICB9XG5cbiAgICAgIGlmICghZGVmYXVsdFByZXZlbnRlZCkge1xuICAgICAgICB0aGlzLmFjdGl2ZUlkID0gbmV4dElkO1xuICAgICAgICB0aGlzLmFjdGl2ZUlkQ2hhbmdlLmVtaXQobmV4dElkKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuXG4vKipcbiAqIEEgZGlyZWN0aXZlIHRvIHB1dCBvbiB0aGUgbmF2IGxpbmsuXG4gKlxuICogQHNpbmNlIDUuMi4wXG4gKi9cbkBEaXJlY3RpdmUoe1xuICBzZWxlY3RvcjogJ2FbbmdiTmF2TGlua10nLFxuICBob3N0OiB7XG4gICAgJ1tpZF0nOiAnbmF2SXRlbS5kb21JZCcsXG4gICAgJ1tjbGFzcy5uYXYtbGlua10nOiAndHJ1ZScsXG4gICAgJ1tjbGFzcy5uYXYtaXRlbV0nOiAnaGFzTmF2SXRlbUNsYXNzKCknLFxuICAgICdbYXR0ci5yb2xlXSc6IGByb2xlID8gcm9sZSA6IG5hdi5yb2xlcyA/ICd0YWInIDogdW5kZWZpbmVkYCxcbiAgICAnaHJlZic6ICcnLFxuICAgICdbY2xhc3MuYWN0aXZlXSc6ICduYXZJdGVtLmFjdGl2ZScsXG4gICAgJ1tjbGFzcy5kaXNhYmxlZF0nOiAnbmF2SXRlbS5kaXNhYmxlZCcsXG4gICAgJ1thdHRyLnRhYmluZGV4XSc6ICduYXZJdGVtLmRpc2FibGVkID8gLTEgOiB1bmRlZmluZWQnLFxuICAgICdbYXR0ci5hcmlhLWNvbnRyb2xzXSc6ICduYXZJdGVtLmlzUGFuZWxJbkRvbSgpID8gbmF2SXRlbS5wYW5lbERvbUlkIDogbnVsbCcsXG4gICAgJ1thdHRyLmFyaWEtc2VsZWN0ZWRdJzogJ25hdkl0ZW0uYWN0aXZlJyxcbiAgICAnW2F0dHIuYXJpYS1kaXNhYmxlZF0nOiAnbmF2SXRlbS5kaXNhYmxlZCcsXG4gICAgJyhjbGljayknOiAnbmF2LmNsaWNrKG5hdkl0ZW0pOyAkZXZlbnQucHJldmVudERlZmF1bHQoKSdcbiAgfVxufSlcbmV4cG9ydCBjbGFzcyBOZ2JOYXZMaW5rIHtcbiAgY29uc3RydWN0b3IoQEF0dHJpYnV0ZSgncm9sZScpIHB1YmxpYyByb2xlOiBzdHJpbmcsIHB1YmxpYyBuYXZJdGVtOiBOZ2JOYXZJdGVtLCBwdWJsaWMgbmF2OiBOZ2JOYXYpIHt9XG5cbiAgaGFzTmF2SXRlbUNsYXNzKCkge1xuICAgIC8vIHdpdGggYWx0ZXJuYXRpdmUgbWFya3VwIHdlIGhhdmUgdG8gYWRkIGAubmF2LWl0ZW1gIGNsYXNzLCBiZWNhdXNlIGBuZ2JOYXZJdGVtYCBpcyBvbiB0aGUgbmctY29udGFpbmVyXG4gICAgcmV0dXJuIHRoaXMubmF2SXRlbS5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQubm9kZVR5cGUgPT09IE5vZGUuQ09NTUVOVF9OT0RFO1xuICB9XG59XG5cblxuLyoqXG4gKiBUaGUgcGF5bG9hZCBvZiB0aGUgY2hhbmdlIGV2ZW50IGVtaXR0ZWQgcmlnaHQgYmVmb3JlIHRoZSBuYXYgY2hhbmdlIGhhcHBlbnMgb24gdXNlciBjbGljay5cbiAqXG4gKiBUaGlzIGV2ZW50IHdvbid0IGJlIGVtaXR0ZWQgaWYgbmF2IGlzIGNoYW5nZWQgcHJvZ3JhbW1hdGljYWxseSB2aWEgYFthY3RpdmVJZF1gIG9yIGAuc2VsZWN0KClgLlxuICpcbiAqIEBzaW5jZSA1LjIuMFxuICovXG5leHBvcnQgaW50ZXJmYWNlIE5nYk5hdkNoYW5nZUV2ZW50IHtcbiAgLyoqXG4gICAqIElkIG9mIHRoZSBjdXJyZW50bHkgYWN0aXZlIG5hdi5cbiAgICovXG4gIGFjdGl2ZUlkOiBhbnk7XG5cbiAgLyoqXG4gICAqIElkIG9mIHRoZSBuZXdseSBzZWxlY3RlZCBuYXYuXG4gICAqL1xuICBuZXh0SWQ6IGFueTtcblxuICAvKipcbiAgICogRnVuY3Rpb24gdGhhdCB3aWxsIHByZXZlbnQgbmF2IGNoYW5nZSBpZiBjYWxsZWQuXG4gICAqL1xuICBwcmV2ZW50RGVmYXVsdDogKCkgPT4gdm9pZDtcbn1cbiJdfQ==