UNPKG

theme-lib

Version:

This is a simple example Angular Library published to npm.

474 lines 36.4 kB
/** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /* * @license * Copyright Akveo. All Rights Reserved. * Licensed under the MIT License. See License.txt in the project root for license information. */ import { Injectable } from '@angular/core'; import { Location } from '@angular/common'; import { BehaviorSubject, ReplaySubject, Subject } from 'rxjs'; import { share } from 'rxjs/operators'; import { isUrlPathContain, isUrlPathEqual } from './url-matching-helpers'; /** * @record */ export function NbMenuBag() { } if (false) { /** @type {?} */ NbMenuBag.prototype.tag; /** @type {?} */ NbMenuBag.prototype.item; } /** @type {?} */ const itemClick$ = new Subject(); /** @type {?} */ const addItems$ = new ReplaySubject(1); /** @type {?} */ const navigateHome$ = new ReplaySubject(1); /** @type {?} */ const getSelectedItem$ = new ReplaySubject(1); /** @type {?} */ const itemSelect$ = new ReplaySubject(1); /** @type {?} */ const itemHover$ = new ReplaySubject(1); /** @type {?} */ const submenuToggle$ = new ReplaySubject(1); /** @type {?} */ const collapseAll$ = new ReplaySubject(1); // TODO: check if we need both URL and LINK /* * Menu Item options */ export class NbMenuItem { constructor() { /* * Item is selected when partly or fully equal to the current url * @type {string} */ this.pathMatch = 'full'; } /* * @returns item parents in top-down order */ /** * @param {?} item * @return {?} */ static getParents(item) { /** @type {?} */ const parents = []; /** @type {?} */ let parent = item.parent; while (parent) { parents.unshift(parent); parent = parent.parent; } return parents; } /** * @param {?} item * @param {?} possibleChild * @return {?} */ static isParent(item, possibleChild) { return possibleChild.parent ? possibleChild.parent === item || this.isParent(item, possibleChild.parent) : false; } } if (false) { /** @type {?} */ NbMenuItem.prototype.title; /** @type {?} */ NbMenuItem.prototype.link; /** @type {?} */ NbMenuItem.prototype.url; /** @type {?} */ NbMenuItem.prototype.icon; /** @type {?} */ NbMenuItem.prototype.expanded; /** @type {?} */ NbMenuItem.prototype.children; /** @type {?} */ NbMenuItem.prototype.target; /** @type {?} */ NbMenuItem.prototype.hidden; /** @type {?} */ NbMenuItem.prototype.pathMatch; /** @type {?} */ NbMenuItem.prototype.home; /** @type {?} */ NbMenuItem.prototype.group; /** @type {?} */ NbMenuItem.prototype.queryParams; /** @type {?} */ NbMenuItem.prototype.parent; /** @type {?} */ NbMenuItem.prototype.selected; /** @type {?} */ NbMenuItem.prototype.data; /** @type {?} */ NbMenuItem.prototype.fragment; } // TODO: map select events to router change events // TODO: review the interface /* * Menu Service. Allows you to listen to menu events, or to interact with a menu. */ export class NbMenuService { /* * Add items to the end of the menu items list * @param {List<NbMenuItem>} items * @param {string} tag */ /** * @param {?} items * @param {?=} tag * @return {?} */ addItems(items, tag) { addItems$.next({ tag, items }); } /* * Collapses all menu items * @param {string} tag */ /** * @param {?=} tag * @return {?} */ collapseAll(tag) { collapseAll$.next({ tag }); } /* * Navigate to the home menu item * @param {string} tag */ /** * @param {?=} tag * @return {?} */ navigateHome(tag) { navigateHome$.next({ tag }); } /* * Returns currently selected item. Won't subscribe to the future events. * @param {string} tag * @returns {Observable<{tag: string; item: NbMenuItem}>} */ /** * @param {?=} tag * @return {?} */ getSelectedItem(tag) { /** @type {?} */ const listener = new BehaviorSubject(null); getSelectedItem$.next({ tag, listener }); return listener.asObservable(); } /** * @return {?} */ onItemClick() { return itemClick$.pipe(share()); } /** * @return {?} */ onItemSelect() { return itemSelect$.pipe(share()); } /** * @return {?} */ onItemHover() { return itemHover$.pipe(share()); } /** * @return {?} */ onSubmenuToggle() { return submenuToggle$.pipe(share()); } } NbMenuService.decorators = [ { type: Injectable } ]; export class NbMenuInternalService { /** * @param {?} location */ constructor(location) { this.location = location; } /** * @param {?} items * @return {?} */ prepareItems(items) { /** @type {?} */ const defaultItem = new NbMenuItem(); items.forEach(i => { this.applyDefaults(i, defaultItem); this.setParent(i); }); } /** * @param {?} items * @param {?} tag * @param {?=} collapseOther * @return {?} */ selectFromUrl(items, tag, collapseOther = false) { /** @type {?} */ const selectedItem = this.findItemByUrl(items); if (selectedItem) { this.selectItem(selectedItem, items, collapseOther, tag); } } /** * @param {?} item * @param {?} items * @param {?=} collapseOther * @param {?=} tag * @return {?} */ selectItem(item, items, collapseOther = false, tag) { /** @type {?} */ const unselectedItems = this.resetSelection(items); /** @type {?} */ const collapsedItems = collapseOther ? this.collapseItems(items) : []; for (const parent of NbMenuItem.getParents(item)) { parent.selected = true; // emit event only for items that weren't selected before ('unselectedItems' contains items that were selected) if (!unselectedItems.includes(parent)) { this.itemSelect(parent, tag); } /** @type {?} */ const wasNotExpanded = !parent.expanded; parent.expanded = true; /** @type {?} */ const i = collapsedItems.indexOf(parent); // emit event only for items that weren't expanded before. // 'collapsedItems' contains items that were expanded, so no need to emit event. // in case 'collapseOther' is false, 'collapsedItems' will be empty, // so also check if item isn't expanded already ('wasNotExpanded'). if (i === -1 && wasNotExpanded) { this.submenuToggle(parent, tag); } else { collapsedItems.splice(i, 1); } } item.selected = true; // emit event only for items that weren't selected before ('unselectedItems' contains items that were selected) if (!unselectedItems.includes(item)) { this.itemSelect(item, tag); } // remaining items which wasn't expanded back after expanding all currently selected items for (const collapsedItem of collapsedItems) { this.submenuToggle(collapsedItem, tag); } } /** * @param {?} items * @param {?} tag * @param {?=} except * @return {?} */ collapseAll(items, tag, except) { /** @type {?} */ const collapsedItems = this.collapseItems(items, except); for (const item of collapsedItems) { this.submenuToggle(item, tag); } } /** * @return {?} */ onAddItem() { return addItems$.pipe(share()); } /** * @return {?} */ onNavigateHome() { return navigateHome$.pipe(share()); } /** * @return {?} */ onCollapseAll() { return collapseAll$.pipe(share()); } /** * @return {?} */ onGetSelectedItem() { return getSelectedItem$.pipe(share()); } /** * @param {?} item * @param {?=} tag * @return {?} */ itemHover(item, tag) { itemHover$.next({ tag, item }); } /** * @param {?} item * @param {?=} tag * @return {?} */ submenuToggle(item, tag) { submenuToggle$.next({ tag, item }); } /** * @param {?} item * @param {?=} tag * @return {?} */ itemSelect(item, tag) { itemSelect$.next({ tag, item }); } /** * @param {?} item * @param {?=} tag * @return {?} */ itemClick(item, tag) { itemClick$.next({ tag, item }); } /* * Unselect all given items deeply. * @param items array of items to unselect. * @returns items which selected value was changed. */ /** * @private * @param {?} items * @return {?} */ resetSelection(items) { /** @type {?} */ const unselectedItems = []; for (const item of items) { if (item.selected) { unselectedItems.push(item); } item.selected = false; if (item.children) { unselectedItems.push(...this.resetSelection(item.children)); } } return unselectedItems; } /* * Collapse all given items deeply. * @param items array of items to collapse. * @param except menu item which shouldn't be collapsed, also disables collapsing for parents of this item. * @returns items which expanded value was changed. */ /** * @private * @param {?} items * @param {?=} except * @return {?} */ collapseItems(items, except) { /** @type {?} */ const collapsedItems = []; for (const item of items) { if (except && (item === except || NbMenuItem.isParent(item, except))) { continue; } if (item.expanded) { collapsedItems.push(item); } item.expanded = false; if (item.children) { collapsedItems.push(...this.collapseItems(item.children)); } } return collapsedItems; } /** * @private * @param {?} item * @param {?} defaultItem * @return {?} */ applyDefaults(item, defaultItem) { /** @type {?} */ const menuItem = Object.assign({}, item); Object.assign(item, defaultItem, menuItem); item.children && item.children.forEach(child => { this.applyDefaults(child, defaultItem); }); } /** * @private * @param {?} item * @return {?} */ setParent(item) { item.children && item.children.forEach(child => { child.parent = item; this.setParent(child); }); } /* * Find deepest item which link matches current URL path. * @param items array of items to search in. * @returns found item of undefined. */ /** * @private * @param {?} items * @return {?} */ findItemByUrl(items) { /** @type {?} */ let selectedItem; items.some(item => { if (item.children) { selectedItem = this.findItemByUrl(item.children); } if (!selectedItem && this.isSelectedInUrl(item)) { selectedItem = item; } return selectedItem; }); return selectedItem; } /** * @private * @param {?} item * @return {?} */ isSelectedInUrl(item) { /** @type {?} */ const exact = item.pathMatch === 'full'; return exact ? isUrlPathEqual(this.location.path(), item.link) : isUrlPathContain(this.location.path(), item.link); } } NbMenuInternalService.decorators = [ { type: Injectable } ]; /** @nocollapse */ NbMenuInternalService.ctorParameters = () => [ { type: Location } ]; if (false) { /** * @type {?} * @private */ NbMenuInternalService.prototype.location; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWVudS5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6Im5nOi8vdGhlbWUtbGliLyIsInNvdXJjZXMiOlsibGliL2NvbXBvbmVudHMvbWVudS9tZW51LnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7O0FBTUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMzQyxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFFM0MsT0FBTyxFQUFjLGVBQWUsRUFBRSxhQUFhLEVBQUUsT0FBTyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQzNFLE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUN2QyxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsY0FBYyxFQUFFLE1BQU0sd0JBQXdCLENBQUM7Ozs7QUFFMUUsK0JBQTREOzs7SUFBL0Isd0JBQVk7O0lBQUMseUJBQWdCOzs7TUFFcEQsVUFBVSxHQUFHLElBQUksT0FBTyxFQUFhOztNQUNyQyxTQUFTLEdBQUcsSUFBSSxhQUFhLENBQXVDLENBQUMsQ0FBQzs7TUFDdEUsYUFBYSxHQUFHLElBQUksYUFBYSxDQUFrQixDQUFDLENBQUM7O01BQ3JELGdCQUFnQixHQUNsQixJQUFJLGFBQWEsQ0FBd0QsQ0FBQyxDQUFDOztNQUN6RSxXQUFXLEdBQUcsSUFBSSxhQUFhLENBQVksQ0FBQyxDQUFDOztNQUM3QyxVQUFVLEdBQUcsSUFBSSxhQUFhLENBQVksQ0FBQyxDQUFDOztNQUM1QyxjQUFjLEdBQUcsSUFBSSxhQUFhLENBQVksQ0FBQyxDQUFDOztNQUNoRCxZQUFZLEdBQUcsSUFBSSxhQUFhLENBQWtCLENBQUMsQ0FBQzs7Ozs7QUFNMUQsTUFBTSxPQUFPLFVBQVU7SUFBdkI7Ozs7O1FBNkNFLGNBQVMsR0FBWSxNQUFNLENBQUM7SUF3QzlCLENBQUM7Ozs7Ozs7O0lBakJDLE1BQU0sQ0FBQyxVQUFVLENBQUMsSUFBZ0I7O2NBQzFCLE9BQU8sR0FBRyxF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Q0QsSUFBSSxDQUFDLFlBQVksSUFBSSxJQUFJLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxFQUFFO2dCQUMvQyxZQUFZLEdBQUcsSUFBSSxDQUFDO2FBQ3JCO1lBRUQsT0FBTyxZQUFZLENBQUM7UUFDdEIsQ0FBQyxDQUFDLENBQUM7UUFFSCxPQUFPLFlBQVksQ0FBQztJQUN0QixDQUFDOzs7Ozs7SUFFTyxlQUFlLENBQUMsSUFBZ0I7O2NBQ2hDLEtBQUssR0FBWSxJQUFJLENBQUMsU0FBUyxLQUFLLE1BQU07UUFDaEQsT0FBTyxLQUFLO1lBQ1YsQ0FBQyxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksRUFBRSxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUM7WUFDakQsQ0FBQyxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxFQUFFLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ3hELENBQUM7OztZQTVMRixVQUFVOzs7O1lBNUtGLFFBQVE7Ozs7Ozs7SUErS0gseUNBQTBCIiwic291cmNlc0NvbnRlbnQiOlsiLypcclxuICogQGxpY2Vuc2VcclxuICogQ29weXJpZ2h0IEFrdmVvLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxyXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuIFNlZSBMaWNlbnNlLnR4dCBpbiB0aGUgcHJvamVjdCByb290IGZvciBsaWNlbnNlIGluZm9ybWF0aW9uLlxyXG4gKi9cclxuXHJcbmltcG9ydCB7IEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgTG9jYXRpb24gfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xyXG5pbXBvcnQgeyBQYXJhbXMgfSBmcm9tICdAYW5ndWxhci9yb3V0ZXInO1xyXG5pbXBvcnQgeyBPYnNlcnZhYmxlLCBCZWhhdmlvclN1YmplY3QsIFJlcGxheVN1YmplY3QsIFN1YmplY3QgfSBmcm9tICdyeGpzJztcclxuaW1wb3J0IHsgc2hhcmUgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XHJcbmltcG9ydCB7IGlzVXJsUGF0aENvbnRhaW4sIGlzVXJsUGF0aEVxdWFsIH0gZnJvbSAnLi91cmwtbWF0Y2hpbmctaGVscGVycyc7XHJcblxyXG5leHBvcnQgaW50ZXJmYWNlIE5iTWVudUJhZyB7IHRhZzogc3RyaW5nOyBpdGVtOiBOYk1lbnVJdGVtIH1cclxuXHJcbmNvbnN0IGl0ZW1DbGljayQgPSBuZXcgU3ViamVjdDxOYk1lbnVCYWc+KCk7XHJcbmNvbnN0IGFkZEl0ZW1zJCA9IG5ldyBSZXBsYXlTdWJqZWN0PHsgdGFnOiBzdHJpbmc7IGl0ZW1zOiBOYk1lbnVJdGVtW10gfT4oMSk7XHJcbmNvbnN0IG5hdmlnYXRlSG9tZSQgPSBuZXcgUmVwbGF5U3ViamVjdDx7IHRhZzogc3RyaW5nIH0+KDEpO1xyXG5jb25zdCBnZXRTZWxlY3RlZEl0ZW0kXHJcbiAgPSBuZXcgUmVwbGF5U3ViamVjdDx7IHRhZzogc3RyaW5nOyBsaXN0ZW5lcjogQmVoYXZpb3JTdWJqZWN0PE5iTWVudUJhZz4gfT4oMSk7XHJcbmNvbnN0IGl0ZW1TZWxlY3QkID0gbmV3IFJlcGxheVN1YmplY3Q8TmJNZW51QmFnPigxKTtcclxuY29uc3QgaXRlbUhvdmVyJCA9IG5ldyBSZXBsYXlTdWJqZWN0PE5iTWVudUJhZz4oMSk7XHJcbmNvbnN0IHN1Ym1lbnVUb2dnbGUkID0gbmV3IFJlcGxheVN1YmplY3Q8TmJNZW51QmFnPigxKTtcclxuY29uc3QgY29sbGFwc2VBbGwkID0gbmV3IFJlcGxheVN1YmplY3Q8eyB0YWc6IHN0cmluZyB9PigxKTtcclxuXHJcbi8vIFRPRE86IGNoZWNrIGlmIHdlIG5lZWQgYm90aCBVUkwgYW5kIExJTktcclxuLypcclxuICogTWVudSBJdGVtIG9wdGlvbnNcclxuICovXHJcbmV4cG9ydCBjbGFzcyBOYk1lbnVJdGVtIHtcclxuICAvKlxyXG4gICAqIEl0ZW0gVGl0bGVcclxuICAgKiBAdHlwZSB7c3RyaW5nfVxyXG4gICAqL1xyXG4gIHRpdGxlOiBzdHJpbmc7XHJcbiAgLypcclxuICAgKiBJdGVtIHJlbGF0aXZlIGxpbmsgKGZvciByb3V0ZXJMaW5rKVxyXG4gICAqIEB0eXBlIHtzdHJpbmd9XHJcbiAgICovXHJcbiAgbGluaz86IHN0cmluZztcclxuICAvKlxyXG4gICAqIEl0ZW0gVVJMIChhYnNvbHV0ZSlcclxuICAgKiBAdHlwZSB7c3RyaW5nfVxyXG4gICAqL1xyXG4gIHVybD86IHN0cmluZztcclxuICAvKlxyXG4gICAqIEljb24gY2xhc3MgbmFtZVxyXG4gICAqIEB0eXBlIHtzdHJpbmd9XHJcbiAgICovXHJcbiAgaWNvbj86IHN0cmluZztcclxuICAvKlxyXG4gICAqIEV4cGFuZGVkIGJ5IGRlZmF1bFxyXG4gICAqIEB0eXBlIHtib29sZWFufVxyXG4gICAqL1xyXG4gIGV4cGFuZGVkPzogYm9vbGVhbjtcclxuICAvKlxyXG4gICAqIENoaWxkcmVuIGl0ZW1zXHJcbiAgICogQHR5cGUge0xpc3Q8TmJNZW51SXRlbT59XHJcbiAgICovXHJcbiAgY2hpbGRyZW4/OiBOYk1lbnVJdGVtW107XHJcbiAgLypcclxuICAgKiBIVE1MIExpbmsgdGFyZ2V0XHJcbiAgICogQHR5cGUge3N0cmluZ31cclxuICAgKi9cclxuICB0YXJnZXQ/OiBzdHJpbmc7XHJcbiAgLypcclxuICAgKiBIaWRkZW4gSXRlbVxyXG4gICAqIEB0eXBlIHtib29sZWFufVxyXG4gICAqL1xyXG4gIGhpZGRlbj86IGJvb2xlYW47XHJcbiAgLypcclxuICAgKiBJdGVtIGlzIHNlbGVjdGVkIHdoZW4gcGFydGx5IG9yIGZ1bGx5IGVxdWFsIHRvIHRoZSBjdXJyZW50IHVybFxyXG4gICAqIEB0eXBlIHtzdHJpbmd9XHJcbiAgICovXHJcbiAgcGF0aE1hdGNoPzogc3RyaW5nID0gJ2Z1bGwnO1xyXG4gIC8qXHJcbiAgICogV2hlcmUgdGhpcyBpcyBhIGhvbWUgaXRlbVxyXG4gICAqIEB0eXBlIHtib29sZWFufVxyXG4gICAqL1xyXG4gIGhvbWU/OiBib29sZWFuO1xyXG4gIC8qXHJcbiAgICogV2hldGhlciB0aGUgaXRlbSBpcyBqdXN0IGEgZ3JvdXAgKG5vbi1jbGlja2FibGUpXHJcbiAgICogQHR5cGUge2Jvb2xlYW59XHJcbiAgICovXHJcbiAgZ3JvdXA/OiBib29sZWFuO1xyXG4gIC8qIE1hcCBvZiBxdWVyeSBwYXJhbWV0ZXJzXHJcbiAgICpAdHlwZSB7UGFyYW1zfVxyXG4gICAqL1xyXG4gIHF1ZXJ5UGFyYW1zPzogUGFyYW1zO1xyXG4gIHBhcmVudD86IE5iTWVudUl0ZW07XHJcbiAgc2VsZWN0ZWQ/OiBib29sZWFuO1xyXG4gIGRhdGE/OiBhbnk7XHJcbiAgZnJhZ21lbnQ/OiBzdHJpbmc7XHJcblxyXG4gIC8qXHJcbiAgICogQHJldHVybnMgaXRlbSBwYXJlbnRzIGluIHRvcC1kb3duIG9yZGVyXHJcbiAgICovXHJcbiAgc3RhdGljIGdldFBhcmVudHMoaXRlbTogTmJNZW51SXRlbSk6IE5iTWVudUl0ZW1bXSB7XHJcbiAgICBjb25zdCBwYXJlbnRzID0gW107XHJcblxyXG4gICAgbGV0IHBhcmVudCA9IGl0ZW0ucGFyZW50O1xyXG4gICAgd2hpbGUgKHBhcmVudCkge1xyXG4gICAgICBwYXJlbnRzLnVuc2hpZnQocGFyZW50KTtcclxuICAgICAgcGFyZW50ID0gcGFyZW50LnBhcmVudDtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gcGFyZW50cztcclxuICB9XHJcblxyXG4gIHN0YXRpYyBpc1BhcmVudChpdGVtOiBOYk1lbnVJdGVtLCBwb3NzaWJsZUNoaWxkOiBOYk1lbnVJdGVtKTogYm9vbGVhbiB7XHJcbiAgICByZXR1cm4gcG9zc2libGVDaGlsZC5wYXJlbnRcclxuICAgICAgPyBwb3NzaWJsZUNoaWxkLnBhcmVudCA9PT0gaXRlbSB8fCB0aGlzLmlzUGFyZW50KGl0ZW0sIHBvc3NpYmxlQ2hpbGQucGFyZW50KVxyXG4gICAgICA6IGZhbHNlO1xyXG4gIH1cclxufVxyXG5cclxuLy8gVE9ETzogbWFwIHNlbGVjdCBldmVudHMgdG8gcm91dGVyIGNoYW5nZSBldmVudHNcclxuLy8gVE9ETzogcmV2aWV3IHRoZSBpbnRlcmZhY2VcclxuLypcclxuICogTWVudSBTZXJ2aWNlLiBBbGxvd3MgeW91IHRvIGxpc3RlbiB0byBtZW51IGV2ZW50cywgb3IgdG8gaW50ZXJhY3Qgd2l0aCBhIG1lbnUuXHJcbiAqL1xyXG5ASW5qZWN0YWJsZSgpXHJcbmV4cG9ydCBjbGFzcyBOYk1lbnVTZXJ2aWNlIHtcclxuXHJcbiAgLypcclxuICAgKiBBZGQgaXRlbXMgdG8gdGhlIGVuZCBvZiB0aGUgbWVudSBpdGVtcyBsaXN0XHJcbiAgICogQHBhcmFtIHtMaXN0PE5iTWVudUl0ZW0+fSBpdGVtc1xyXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB0YWdcclxuICAgKi9cclxuICBhZGRJdGVtcyhpdGVtczogTmJNZW51SXRlbVtdLCB0YWc/OiBzdHJpbmcpIHtcclxuICAgIGFkZEl0ZW1zJC5uZXh0KHsgdGFnLCBpdGVtcyB9KTtcclxuICB9XHJcblxyXG4gIC8qXHJcbiAgICogQ29sbGFwc2VzIGFsbCBtZW51IGl0ZW1zXHJcbiAgICogQHBhcmFtIHtzdHJpbmd9IHRhZ1xyXG4gICAqL1xyXG4gIGNvbGxhcHNlQWxsKHRhZz86IHN0cmluZykge1xyXG4gICAgY29sbGFwc2VBbGwkLm5leHQoeyB0YWcgfSk7XHJcbiAgfVxyXG5cclxuICAvKlxyXG4gICAqIE5hdmlnYXRlIHRvIHRoZSBob21lIG1lbnUgaXRlbVxyXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB0YWdcclxuICAgKi9cclxuICBuYXZpZ2F0ZUhvbWUodGFnPzogc3RyaW5nKSB7XHJcbiAgICBuYXZpZ2F0ZUhvbWUkLm5leHQoeyB0YWcgfSk7XHJcbiAgfVxyXG5cclxuICAvKlxyXG4gICAqIFJldHVybnMgY3VycmVudGx5IHNlbGVjdGVkIGl0ZW0uIFdvbid0IHN1YnNjcmliZSB0byB0aGUgZnV0dXJlIGV2ZW50cy5cclxuICAgKiBAcGFyYW0ge3N0cmluZ30gdGFnXHJcbiAgICogQHJldHVybnMge09ic2VydmFibGU8e3RhZzogc3RyaW5nOyBpdGVtOiBOYk1lbnVJdGVtfT59XHJcbiAgICovXHJcbiAgZ2V0U2VsZWN0ZWRJdGVtKHRhZz86IHN0cmluZyk6IE9ic2VydmFibGU8TmJNZW51QmFnPiB7XHJcbiAgICBjb25zdCBsaXN0ZW5lciA9IG5ldyBCZWhhdmlvclN1YmplY3Q8TmJNZW51QmFnPihudWxsKTtcclxuXHJcbiAgICBnZXRTZWxlY3RlZEl0ZW0kLm5leHQoeyB0YWcsIGxpc3RlbmVyIH0pO1xyXG5cclxuICAgIHJldHVybiBsaXN0ZW5lci5hc09ic2VydmFibGUoKTtcclxuICB9XHJcblxyXG4gIG9uSXRlbUNsaWNrKCk6IE9ic2VydmFibGU8TmJNZW51QmFnPiB7XHJcbiAgICByZXR1cm4gaXRlbUNsaWNrJC5waXBlKHNoYXJlKCkpO1xyXG4gIH1cclxuXHJcbiAgb25JdGVtU2VsZWN0KCk6IE9ic2VydmFibGU8TmJNZW51QmFnPiB7XHJcbiAgICByZXR1cm4gaXRlbVNlbGVjdCQucGlwZShzaGFyZSgpKTtcclxuICB9XHJcblxyXG4gIG9uSXRlbUhvdmVyKCk6IE9ic2VydmFibGU8TmJNZW51QmFnPiB7XHJcbiAgICByZXR1cm4gaXRlbUhvdmVyJC5waXBlKHNoYXJlKCkpO1xyXG4gIH1cclxuXHJcbiAgb25TdWJtZW51VG9nZ2xlKCk6IE9ic2VydmFibGU8TmJNZW51QmFnPiB7XHJcbiAgICByZXR1cm4gc3VibWVudVRvZ2dsZSQucGlwZShzaGFyZSgpKTtcclxuICB9XHJcbn1cclxuXHJcbkBJbmplY3RhYmxlKClcclxuZXhwb3J0IGNsYXNzIE5iTWVudUludGVybmFsU2VydmljZSB7XHJcblxyXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgbG9jYXRpb246IExvY2F0aW9uKSB7fVxyXG5cclxuICBwcmVwYXJlSXRlbXMoaXRlbXM6IE5iTWVudUl0ZW1bXSkge1xyXG4gICAgY29uc3QgZGVmYXVsdEl0ZW0gPSBuZXcgTmJNZW51SXRlbSgpO1xyXG4gICAgaXRlbXMuZm9yRWFjaChpID0+IHtcclxuICAgICAgdGhpcy5hcHBseURlZmF1bHRzKGksIGRlZmF1bHRJdGVtKTtcclxuICAgICAgdGhpcy5zZXRQYXJlbnQoaSk7XHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIHNlbGVjdEZyb21VcmwoaXRlbXM6IE5iTWVudUl0ZW1bXSwgdGFnOiBzdHJpbmcsIGNvbGxhcHNlT3RoZXI6IGJvb2xlYW4gPSBmYWxzZSkge1xyXG4gICAgY29uc3Qgc2VsZWN0ZWRJdGVtID0gdGhpcy5maW5kSXRlbUJ5VXJsKGl0ZW1zKTtcclxuICAgIGlmIChzZWxlY3RlZEl0ZW0pIHtcclxuICAgICAgdGhpcy5zZWxlY3RJdGVtKHNlbGVjdGVkSXRlbSwgaXRlbXMsIGNvbGxhcHNlT3RoZXIsIHRhZyk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBzZWxlY3RJdGVtKGl0ZW06IE5iTWVudUl0ZW0sIGl0ZW1zOiBOYk1lbnVJdGVtW10sIGNvbGxhcHNlT3RoZXI6IGJvb2xlYW4gPSBmYWxzZSwgdGFnOiBzdHJpbmcpIHtcclxuICAgIGNvbnN0IHVuc2VsZWN0ZWRJdGVtcyA9IHRoaXMucmVzZXRTZWxlY3Rpb24oaXRlbXMpO1xyXG4gICAgY29uc3QgY29sbGFwc2VkSXRlbXMgPSBjb2xsYXBzZU90aGVyID8gdGhpcy5jb2xsYXBzZUl0ZW1zKGl0ZW1zKSA6IFtdO1xyXG5cclxuICAgIGZvciAoY29uc3QgcGFyZW50IG9mIE5iTWVudUl0ZW0uZ2V0UGFyZW50cyhpdGVtKSkge1xyXG4gICAgICBwYXJlbnQuc2VsZWN0ZWQgPSB0cnVlO1xyXG4gICAgICAvLyBlbWl0IGV2ZW50IG9ubHkgZm9yIGl0ZW1zIHRoYXQgd2VyZW4ndCBzZWxlY3RlZCBiZWZvcmUgKCd1bnNlbGVjdGVkSXRlbXMnIGNvbnRhaW5zIGl0ZW1zIHRoYXQgd2VyZSBzZWxlY3RlZClcclxuICAgICAgaWYgKCF1bnNlbGVjdGVkSXRlbXMuaW5jbHVkZXMocGFyZW50KSkge1xyXG4gICAgICAgIHRoaXMuaXRlbVNlbGVjdChwYXJlbnQsIHRhZyk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGNvbnN0IHdhc05vdEV4cGFuZGVkID0gIXBhcmVudC5leHBhbmRlZDtcclxuICAgICAgcGFyZW50LmV4cGFuZGVkID0gdHJ1ZTtcclxuICAgICAgY29uc3QgaSA9IGNvbGxhcHNlZEl0ZW1zLmluZGV4T2YocGFyZW50KTtcclxuICAgICAgLy8gZW1pdCBldmVudCBvbmx5IGZvciBpdGVtcyB0aGF0IHdlcmVuJ3QgZXhwYW5kZWQgYmVmb3JlLlxyXG4gICAgICAvLyAnY29sbGFwc2VkSXRlbXMnIGNvbnRhaW5zIGl0ZW1zIHRoYXQgd2VyZSBleHBhbmRlZCwgc28gbm8gbmVlZCB0byBlbWl0IGV2ZW50LlxyXG4gICAgICAvLyBpbiBjYXNlICdjb2xsYXBzZU90aGVyJyBpcyBmYWxzZSwgJ2NvbGxhcHNlZEl0ZW1zJyB3aWxsIGJlIGVtcHR5LFxyXG4gICAgICAvLyBzbyBhbHNvIGNoZWNrIGlmIGl0ZW0gaXNuJ3QgZXhwYW5kZWQgYWxyZWFkeSAoJ3dhc05vdEV4cGFuZGVkJykuXHJcbiAgICAgIGlmIChpID09PSAtMSAmJiB3YXNOb3RFeHBhbmRlZCkge1xyXG4gICAgICAgIHRoaXMuc3VibWVudVRvZ2dsZShwYXJlbnQsIHRhZyk7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgY29sbGFwc2VkSXRlbXMuc3BsaWNlKGksIDEpO1xyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgaXRlbS5zZWxlY3RlZCA9IHRydWU7XHJcbiAgICAvLyBlbWl0IGV2ZW50IG9ubHkgZm9yIGl0ZW1zIHRoYXQgd2VyZW4ndCBzZWxlY3RlZCBiZWZvcmUgKCd1bnNlbGVjdGVkSXRlbXMnIGNvbnRhaW5zIGl0ZW1zIHRoYXQgd2VyZSBzZWxlY3RlZClcclxuICAgIGlmICghdW5zZWxlY3RlZEl0ZW1zLmluY2x1ZGVzKGl0ZW0pKSB7XHJcbiAgICAgIHRoaXMuaXRlbVNlbGVjdChpdGVtLCB0YWcpO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIHJlbWFpbmluZyBpdGVtcyB3aGljaCB3YXNuJ3QgZXhwYW5kZWQgYmFjayBhZnRlciBleHBhbmRpbmcgYWxsIGN1cnJlbnRseSBzZWxlY3RlZCBpdGVtc1xyXG4gICAgZm9yIChjb25zdCBjb2xsYXBzZWRJdGVtIG9mIGNvbGxhcHNlZEl0ZW1zKSB7XHJcbiAgICAgIHRoaXMuc3VibWVudVRvZ2dsZShjb2xsYXBzZWRJdGVtLCB0YWcpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgY29sbGFwc2VBbGwoaXRlbXM6IE5iTWVudUl0ZW1bXSwgdGFnOiBzdHJpbmcsIGV4Y2VwdD86IE5iTWVudUl0ZW0pIHtcclxuICAgIGNvbnN0IGNvbGxhcHNlZEl0ZW1zID0gdGhpcy5jb2xsYXBzZUl0ZW1zKGl0ZW1zLCBleGNlcHQpO1xyXG5cclxuICAgIGZvciAoY29uc3QgaXRlbSBvZiBjb2xsYXBzZWRJdGVtcykge1xyXG4gICAgICB0aGlzLnN1Ym1lbnVUb2dnbGUoaXRlbSwgdGFnKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIG9uQWRkSXRlbSgpOiBPYnNlcnZhYmxlPHsgdGFnOiBzdHJpbmc7IGl0ZW1zOiBOYk1lbnVJdGVtW10gfT4ge1xyXG4gICAgcmV0dXJuIGFkZEl0ZW1zJC5waXBlKHNoYXJlKCkpO1xyXG4gIH1cclxuXHJcbiAgb25OYXZpZ2F0ZUhvbWUoKTogT2JzZXJ2YWJsZTx7IHRhZzogc3RyaW5nIH0+IHtcclxuICAgIHJldHVybiBuYXZpZ2F0ZUhvbWUkLnBpcGUoc2hhcmUoKSk7XHJcbiAgfVxyXG5cclxuICBvbkNvbGxhcHNlQWxsKCk6IE9ic2VydmFibGU8eyB0YWc6IHN0cmluZyB9PiB7XHJcbiAgICByZXR1cm4gY29sbGFwc2VBbGwkLnBpcGUoc2hhcmUoKSk7XHJcbiAgfVxyXG5cclxuICBvbkdldFNlbGVjdGVkSXRlbSgpOiBPYnNlcnZhYmxlPHsgdGFnOiBzdHJpbmc7IGxpc3RlbmVyOiBCZWhhdmlvclN1YmplY3Q8TmJNZW51QmFnPiB9PiB7XHJcbiAgICByZXR1cm4gZ2V0U2VsZWN0ZWRJdGVtJC5waXBlKHNoYXJlKCkpO1xyXG4gIH1cclxuXHJcbiAgaXRlbUhvdmVyKGl0ZW06IE5iTWVudUl0ZW0sIHRhZz86IHN0cmluZykge1xyXG4gICAgaXRlbUhvdmVyJC5uZXh0KHt0YWcsIGl0ZW19KTtcclxuICB9XHJcblxyXG4gIHN1Ym1lbnVUb2dnbGUoaXRlbTogTmJNZW51SXRlbSwgdGFnPzogc3RyaW5nKSB7XHJcbiAgICBzdWJtZW51VG9nZ2xlJC5uZXh0KHt0YWcsIGl0ZW19KTtcclxuICB9XHJcblxyXG4gIGl0ZW1TZWxlY3QoaXRlbTogTmJNZW51SXRlbSwgdGFnPzogc3RyaW5nKSB7XHJcbiAgICBpdGVtU2VsZWN0JC5uZXh0KHt0YWcsIGl0ZW19KTtcclxuICB9XHJcblxyXG4gIGl0ZW1DbGljayhpdGVtOiBOYk1lbnVJdGVtLCB0YWc/OiBzdHJpbmcpIHtcclxuICAgIGl0ZW1DbGljayQubmV4dCh7dGFnLCBpdGVtfSk7XHJcbiAgfVxyXG5cclxuICAvKlxyXG4gICAqIFVuc2VsZWN0IGFsbCBnaXZlbiBpdGVtcyBkZWVwbHkuXHJcbiAgICogQHBhcmFtIGl0ZW1zIGFycmF5IG9mIGl0ZW1zIHRvIHVuc2VsZWN0LlxyXG4gICAqIEByZXR1cm5zIGl0ZW1zIHdoaWNoIHNlbGVjdGVkIHZhbHVlIHdhcyBjaGFuZ2VkLlxyXG4gICAqL1xyXG4gIHByaXZhdGUgcmVzZXRTZWxlY3Rpb24oaXRlbXM6IE5iTWVudUl0ZW1bXSk6IE5iTWVudUl0ZW1bXSB7XHJcbiAgICBjb25zdCB1bnNlbGVjdGVkSXRlbXMgPSBbXTtcclxuXHJcbiAgICBmb3IgKGNvbnN0IGl0ZW0gb2YgaXRlbXMpIHtcclxuICAgICAgaWYgKGl0ZW0uc2VsZWN0ZWQpIHtcclxuICAgICAgICB1bnNlbGVjdGVkSXRlbXMucHVzaChpdGVtKTtcclxuICAgICAgfVxyXG4gICAgICBpdGVtLnNlbGVjdGVkID0gZmFsc2U7XHJcblxyXG4gICAgICBpZiAoaXRlbS5jaGlsZHJlbikge1xyXG4gICAgICAgIHVuc2VsZWN0ZWRJdGVtcy5wdXNoKC4uLnRoaXMucmVzZXRTZWxlY3Rpb24oaXRlbS5jaGlsZHJlbikpO1xyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIHVuc2VsZWN0ZWRJdGVtcztcclxuICB9XHJcblxyXG4gIC8qXHJcbiAgICogQ29sbGFwc2UgYWxsIGdpdmVuIGl0ZW1zIGRlZXBseS5cclxuICAgKiBAcGFyYW0gaXRlbXMgYXJyYXkgb2YgaXRlbXMgdG8gY29sbGFwc2UuXHJcbiAgICogQHBhcmFtIGV4Y2VwdCBtZW51IGl0ZW0gd2hpY2ggc2hvdWxkbid0IGJlIGNvbGxhcHNlZCwgYWxzbyBkaXNhYmxlcyBjb2xsYXBzaW5nIGZvciBwYXJlbnRzIG9mIHRoaXMgaXRlbS5cclxuICAgKiBAcmV0dXJucyBpdGVtcyB3aGljaCBleHBhbmRlZCB2YWx1ZSB3YXMgY2hhbmdlZC5cclxuICAgKi9cclxuICBwcml2YXRlIGNvbGxhcHNlSXRlbXMoaXRlbXM6IE5iTWVudUl0ZW1bXSwgZXhjZXB0PzogTmJNZW51SXRlbSk6IE5iTWVudUl0ZW1bXSB7XHJcbiAgICBjb25zdCBjb2xsYXBzZWRJdGVtcyA9IFtdO1xyXG5cclxuICAgIGZvciAoY29uc3QgaXRlbSBvZiBpdGVtcykge1xyXG4gICAgICBpZiAoZXhjZXB0ICYmIChpdGVtID09PSBleGNlcHQgfHwgTmJNZW51SXRlbS5pc1BhcmVudChpdGVtLCBleGNlcHQpKSkge1xyXG4gICAgICAgIGNvbnRpbnVlO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBpZiAoaXRlbS5leHBhbmRlZCkge1xyXG4gICAgICAgIGNvbGxhcHNlZEl0ZW1zLnB1c2goaXRlbSlcclxuICAgICAgfVxyXG4gICAgICBpdGVtLmV4cGFuZGVkID0gZmFsc2U7XHJcblxyXG4gICAgICBpZiAoaXRlbS5jaGlsZHJlbikge1xyXG4gICAgICAgIGNvbGxhcHNlZEl0ZW1zLnB1c2goLi4udGhpcy5jb2xsYXBzZUl0ZW1zKGl0ZW0uY2hpbGRyZW4pKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBjb2xsYXBzZWRJdGVtcztcclxuICB9XHJcblxyXG4gIHByaXZhdGUgYXBwbHlEZWZhdWx0cyhpdGVtLCBkZWZhdWx0SXRlbSkge1xyXG4gICAgY29uc3QgbWVudUl0ZW0gPSB7Li4uaXRlbX07XHJcbiAgICBPYmplY3QuYXNzaWduKGl0ZW0sIGRlZmF1bHRJdGVtLCBtZW51SXRlbSk7XHJcbiAgICBpdGVtLmNoaWxkcmVuICYmIGl0ZW0uY2hpbGRyZW4uZm9yRWFjaChjaGlsZCA9PiB7XHJcbiAgICAgIHRoaXMuYXBwbHlEZWZhdWx0cyhjaGlsZCwgZGVmYXVsdEl0ZW0pO1xyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIHNldFBhcmVudChpdGVtOiBOYk1lbnVJdGVtKSB7XHJcbiAgICBpdGVtLmNoaWxkcmVuICYmIGl0ZW0uY2hpbGRyZW4uZm9yRWFjaChjaGlsZCA9PiB7XHJcbiAgICAgIGNoaWxkLnBhcmVudCA9IGl0ZW07XHJcbiAgICAgIHRoaXMuc2V0UGFyZW50KGNoaWxkKTtcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgLypcclxuICAgKiBGaW5kIGRlZXBlc3QgaXRlbSB3aGljaCBsaW5rIG1hdGNoZXMgY3VycmVudCBVUkwgcGF0aC5cclxuICAgKiBAcGFyYW0gaXRlbXMgYXJyYXkgb2YgaXRlbXMgdG8gc2VhcmNoIGluLlxyXG4gICAqIEByZXR1cm5zIGZvdW5kIGl0ZW0gb2YgdW5kZWZpbmVkLlxyXG4gICAqL1xyXG4gIHByaXZhdGUgZmluZEl0ZW1CeVVybChpdGVtczogTmJNZW51SXRlbVtdKTogTmJNZW51SXRlbSB8IHVuZGVmaW5lZCB7XHJcbiAgICBsZXQgc2VsZWN0ZWRJdGVtO1xyXG5cclxuICAgIGl0ZW1zLnNvbWUoaXRlbSA9PiB7XHJcbiAgICAgIGlmIChpdGVtLmNoaWxkcmVuKSB7XHJcbiAgICAgICAgc2VsZWN0ZWRJdGVtID0gdGhpcy5maW5kSXRlbUJ5VXJsKGl0ZW0uY2hpbGRyZW4pO1xyXG4gICAgICB9XHJcbiAgICAgIGlmICghc2VsZWN0ZWRJdGVtICYmIHRoaXMuaXNTZWxlY3RlZEluVXJsKGl0ZW0pKSB7XHJcbiAgICAgICAgc2VsZWN0ZWRJdGVtID0gaXRlbTtcclxuICAgICAgfVxyXG5cclxuICAgICAgcmV0dXJuIHNlbGVjdGVkSXRlbTtcclxuICAgIH0pO1xyXG5cclxuICAgIHJldHVybiBzZWxlY3RlZEl0ZW07XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGlzU2VsZWN0ZWRJblVybChpdGVtOiBOYk1lbnVJdGVtKTogYm9vbGVhbiB7XHJcbiAgICBjb25zdCBleGFjdDogYm9vbGVhbiA9IGl0ZW0ucGF0aE1hdGNoID09PSAnZnVsbCc7XHJcbiAgICByZXR1cm4gZXhhY3RcclxuICAgICAgPyBpc1VybFBhdGhFcXVhbCh0aGlzLmxvY2F0aW9uLnBhdGgoKSwgaXRlbS5saW5rKVxyXG4gICAgICA6IGlzVXJsUGF0aENvbnRhaW4odGhpcy5sb2NhdGlvbi5wYXRoKCksIGl0ZW0ubGluayk7XHJcbiAgfVxyXG59XHJcbiJdfQ==