@datorama/akita
Version:
State Management Tailored-Made for JS Applications
610 lines • 40.3 kB
JavaScript
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
import * as tslib_1 from "tslib";
import { of } from 'rxjs';
import { distinctUntilChanged, filter, map, switchMap } from 'rxjs/operators';
import { isDefined } from './isDefined';
import { Query } from './query';
import { isFunction } from './isFunction';
import { toBoolean } from './toBoolean';
import { sortByOptions } from './sortByOptions';
import { entitiesToArray } from './entitiesToArray';
import { entitiesToMap } from './entitiesToMap';
import { isArray } from './isArray';
import { isNil } from './isNil';
import { findEntityByPredicate, getEntity } from './getEntity';
import { isUndefined } from './isUndefined';
import { distinctUntilArrayItemChanged } from './arrayFind';
import { mapSkipUndefined } from './mapSkipUndefined';
/**
*
* The Entity Query is similar to the general Query, with additional functionality tailored for EntityStores.
*
* class WidgetsQuery extends QueryEntity<WidgetsState> {
* constructor(protected store: WidgetsStore) {
* super(store);
* }
* }
*
*
*
* @template S, EntityType, IDType
*/
var /**
*
* The Entity Query is similar to the general Query, with additional functionality tailored for EntityStores.
*
* class WidgetsQuery extends QueryEntity<WidgetsState> {
* constructor(protected store: WidgetsStore) {
* super(store);
* }
* }
*
*
*
* @template S, EntityType, IDType
*/
QueryEntity = /** @class */ (function (_super) {
tslib_1.__extends(QueryEntity, _super);
function QueryEntity(store, options) {
if (options === void 0) { options = {}; }
var _this = _super.call(this, store) || this;
_this.options = options;
_this.__store__ = store;
return _this;
}
/**
* @param {?=} options
* @return {?}
*/
QueryEntity.prototype.selectAll = /**
* @param {?=} options
* @return {?}
*/
function (options) {
var _this = this;
if (options === void 0) { options = {
asObject: false
}; }
return this.select((/**
* @param {?} state
* @return {?}
*/
function (state) { return state.entities; })).pipe(map((/**
* @return {?}
*/
function () { return _this.getAll(options); })));
};
/**
* @param {?=} options
* @return {?}
*/
QueryEntity.prototype.getAll = /**
* @param {?=} options
* @return {?}
*/
function (options) {
if (options === void 0) { options = { asObject: false, filterBy: undefined, limitTo: undefined }; }
if (options.asObject) {
return entitiesToMap(this.getValue(), options);
}
sortByOptions(options, this.config || this.options);
return entitiesToArray(this.getValue(), options);
};
/**
* @template R
* @param {?} ids
* @param {?=} project
* @return {?}
*/
QueryEntity.prototype.selectMany = /**
* @template R
* @param {?} ids
* @param {?=} project
* @return {?}
*/
function (ids, project) {
if (!ids || !ids.length)
return of([]);
return this.select((/**
* @param {?} state
* @return {?}
*/
function (state) { return state.entities; })).pipe(map((/**
* @param {?} entities
* @return {?}
*/
function (entities) { return mapSkipUndefined(ids, (/**
* @param {?} id
* @return {?}
*/
function (id) { return getEntity(id, project)(entities); })); })), distinctUntilArrayItemChanged());
};
/**
* @template R
* @param {?} idOrPredicate
* @param {?=} project
* @return {?}
*/
QueryEntity.prototype.selectEntity = /**
* @template R
* @param {?} idOrPredicate
* @param {?=} project
* @return {?}
*/
function (idOrPredicate, project) {
/** @type {?} */
var id = idOrPredicate;
if (isFunction(idOrPredicate)) {
// For performance reason we expect the entity to be in the store
((/** @type {?} */ (id))) = findEntityByPredicate(idOrPredicate, this.getValue().entities);
}
return this.select((/**
* @param {?} state
* @return {?}
*/
function (state) { return state.entities; })).pipe(map(getEntity(id, project)), distinctUntilChanged());
};
/**
* Get an entity by id
*
* @example
*
* this.query.getEntity(1);
*/
/**
* Get an entity by id
*
* \@example
*
* this.query.getEntity(1);
* @param {?} id
* @return {?}
*/
QueryEntity.prototype.getEntity = /**
* Get an entity by id
*
* \@example
*
* this.query.getEntity(1);
* @param {?} id
* @return {?}
*/
function (id) {
return this.getValue().entities[(/** @type {?} */ (id))];
};
/**
* Select the active entity's id
*
* @example
*
* this.query.selectActiveId()
*/
/**
* Select the active entity's id
*
* \@example
*
* this.query.selectActiveId()
* @return {?}
*/
QueryEntity.prototype.selectActiveId = /**
* Select the active entity's id
*
* \@example
*
* this.query.selectActiveId()
* @return {?}
*/
function () {
return this.select((/**
* @param {?} state
* @return {?}
*/
function (state) { return ((/** @type {?} */ (state))).active; }));
};
/**
* Get the active id
*
* @example
*
* this.query.getActiveId()
*/
/**
* Get the active id
*
* \@example
*
* this.query.getActiveId()
* @return {?}
*/
QueryEntity.prototype.getActiveId = /**
* Get the active id
*
* \@example
*
* this.query.getActiveId()
* @return {?}
*/
function () {
return this.getValue().active;
};
/**
* @template R
* @param {?=} project
* @return {?}
*/
QueryEntity.prototype.selectActive = /**
* @template R
* @param {?=} project
* @return {?}
*/
function (project) {
var _this = this;
if (isArray(this.getActive())) {
return this.selectActiveId().pipe(switchMap((/**
* @param {?} ids
* @return {?}
*/
function (ids) { return _this.selectMany(ids, project); })));
}
return this.selectActiveId().pipe(switchMap((/**
* @param {?} ids
* @return {?}
*/
function (ids) { return _this.selectEntity(ids, project); })));
};
/**
* @return {?}
*/
QueryEntity.prototype.getActive = /**
* @return {?}
*/
function () {
var _this = this;
/** @type {?} */
var activeId = this.getActiveId();
if (isArray(activeId)) {
return activeId.map((/**
* @param {?} id
* @return {?}
*/
function (id) { return _this.getValue().entities[(/** @type {?} */ (id))]; }));
}
return toBoolean(activeId) ? this.getEntity(activeId) : undefined;
};
/**
* Select the store's entity collection length
*
* @example
*
* this.query.selectCount()
* this.query.selectCount(entity => entity.completed)
*/
/**
* Select the store's entity collection length
*
* \@example
*
* this.query.selectCount()
* this.query.selectCount(entity => entity.completed)
* @param {?=} predicate
* @return {?}
*/
QueryEntity.prototype.selectCount = /**
* Select the store's entity collection length
*
* \@example
*
* this.query.selectCount()
* this.query.selectCount(entity => entity.completed)
* @param {?=} predicate
* @return {?}
*/
function (predicate) {
var _this = this;
return this.select((/**
* @param {?} state
* @return {?}
*/
function (state) { return state.entities; })).pipe(map((/**
* @return {?}
*/
function () { return _this.getCount(predicate); })));
};
/**
* Get the store's entity collection length
*
* @example
*
* this.query.getCount()
* this.query.getCount(entity => entity.completed)
*/
/**
* Get the store's entity collection length
*
* \@example
*
* this.query.getCount()
* this.query.getCount(entity => entity.completed)
* @param {?=} predicate
* @return {?}
*/
QueryEntity.prototype.getCount = /**
* Get the store's entity collection length
*
* \@example
*
* this.query.getCount()
* this.query.getCount(entity => entity.completed)
* @param {?=} predicate
* @return {?}
*/
function (predicate) {
if (isFunction(predicate)) {
return this.getAll().filter(predicate).length;
}
return this.getValue().ids.length;
};
/**
* @template R
* @param {?=} project
* @return {?}
*/
QueryEntity.prototype.selectLast = /**
* @template R
* @param {?=} project
* @return {?}
*/
function (project) {
return this.selectAt((/**
* @param {?} ids
* @return {?}
*/
function (ids) { return ids[ids.length - 1]; }), project);
};
/**
* @template R
* @param {?=} project
* @return {?}
*/
QueryEntity.prototype.selectFirst = /**
* @template R
* @param {?=} project
* @return {?}
*/
function (project) {
return this.selectAt((/**
* @param {?} ids
* @return {?}
*/
function (ids) { return ids[0]; }), project);
};
/**
* @param {?=} action
* @return {?}
*/
QueryEntity.prototype.selectEntityAction = /**
* @param {?=} action
* @return {?}
*/
function (action) {
if (isUndefined(action)) {
return this.store.selectEntityAction$;
}
return this.store.selectEntityAction$.pipe(filter((/**
* @param {?} ac
* @return {?}
*/
function (ac) { return ac.type === action; })), map((/**
* @param {?} action
* @return {?}
*/
function (action) { return action.ids; })));
};
/**
* @param {?=} projectOrIds
* @return {?}
*/
QueryEntity.prototype.hasEntity = /**
* @param {?=} projectOrIds
* @return {?}
*/
function (projectOrIds) {
var _this = this;
if (isNil(projectOrIds)) {
return this.getValue().ids.length > 0;
}
if (isFunction(projectOrIds)) {
return this.getAll().some(projectOrIds);
}
if (isArray(projectOrIds)) {
return projectOrIds.every((/**
* @param {?} id
* @return {?}
*/
function (id) { return ((/** @type {?} */ (id))) in _this.getValue().entities; }));
}
return ((/** @type {?} */ (projectOrIds))) in this.getValue().entities;
};
/**
* Returns whether entity store has an active entity
*
* @example
*
* this.query.hasActive()
* this.query.hasActive(3)
*
*/
/**
* Returns whether entity store has an active entity
*
* \@example
*
* this.query.hasActive()
* this.query.hasActive(3)
*
* @param {?=} id
* @return {?}
*/
QueryEntity.prototype.hasActive = /**
* Returns whether entity store has an active entity
*
* \@example
*
* this.query.hasActive()
* this.query.hasActive(3)
*
* @param {?=} id
* @return {?}
*/
function (id) {
/** @type {?} */
var active = this.getValue().active;
if (Array.isArray(active)) {
if (isDefined(id)) {
return active.includes(id);
}
return active.length > 0;
}
return isDefined(active);
};
/**
*
* Create sub UI query for querying Entity's UI state
*
* @example
*
*
* export class ProductsQuery extends QueryEntity<ProductsState> {
* ui: EntityUIQuery<ProductsUIState>;
*
* constructor(protected store: ProductsStore) {
* super(store);
* this.createUIQuery();
* }
*
* }
*/
/**
*
* Create sub UI query for querying Entity's UI state
*
* \@example
*
*
* export class ProductsQuery extends QueryEntity<ProductsState> {
* ui: EntityUIQuery<ProductsUIState>;
*
* constructor(protected store: ProductsStore) {
* super(store);
* this.createUIQuery();
* }
*
* }
* @return {?}
*/
QueryEntity.prototype.createUIQuery = /**
*
* Create sub UI query for querying Entity's UI state
*
* \@example
*
*
* export class ProductsQuery extends QueryEntity<ProductsState> {
* ui: EntityUIQuery<ProductsUIState>;
*
* constructor(protected store: ProductsStore) {
* super(store);
* this.createUIQuery();
* }
*
* }
* @return {?}
*/
function () {
this.ui = new EntityUIQuery(this.__store__.ui);
};
/**
* @private
* @template R
* @param {?} mapFn
* @param {?=} project
* @return {?}
*/
QueryEntity.prototype.selectAt = /**
* @private
* @template R
* @param {?} mapFn
* @param {?=} project
* @return {?}
*/
function (mapFn, project) {
var _this = this;
return this.select((/**
* @param {?} state
* @return {?}
*/
function (state) { return (/** @type {?} */ (state.ids)); })).pipe(map(mapFn), distinctUntilChanged(), switchMap((/**
* @param {?} id
* @return {?}
*/
function (id) { return _this.selectEntity(id, project); })));
};
return QueryEntity;
}(Query));
/**
*
* The Entity Query is similar to the general Query, with additional functionality tailored for EntityStores.
*
* class WidgetsQuery extends QueryEntity<WidgetsState> {
* constructor(protected store: WidgetsStore) {
* super(store);
* }
* }
*
*
*
* @template S, EntityType, IDType
*/
export { QueryEntity };
if (false) {
/** @type {?} */
QueryEntity.prototype.ui;
/**
* @type {?}
* @protected
*/
QueryEntity.prototype.store;
/** @type {?} */
QueryEntity.prototype.__store__;
/**
* @type {?}
* @private
*/
QueryEntity.prototype.options;
}
// @internal
/**
* @template UIState, DEPRECATED
*/
var
// @internal
/**
* @template UIState, DEPRECATED
*/
EntityUIQuery = /** @class */ (function (_super) {
tslib_1.__extends(EntityUIQuery, _super);
function EntityUIQuery(store) {
return _super.call(this, store) || this;
}
return EntityUIQuery;
}(QueryEntity));
// @internal
/**
* @template UIState, DEPRECATED
*/
export { EntityUIQuery };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicXVlcnlFbnRpdHkuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9AZGF0b3JhbWEvYWtpdGEvIiwic291cmNlcyI6WyJzcmMvcXVlcnlFbnRpdHkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSxPQUFPLEVBQWMsRUFBRSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQ3RDLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLEVBQUUsR0FBRyxFQUFFLFNBQVMsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQzlFLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFFeEMsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLFNBQVMsQ0FBQztBQUVoQyxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sY0FBYyxDQUFDO0FBQzFDLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFDeEMsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQ2hELE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUNwRCxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFFaEQsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLFdBQVcsQ0FBQztBQUNwQyxPQUFPLEVBQUUsS0FBSyxFQUFFLE1BQU0sU0FBUyxDQUFDO0FBQ2hDLE9BQU8sRUFBRSxxQkFBcUIsRUFBRSxTQUFTLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFFL0QsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUU1QyxPQUFPLEVBQUUsNkJBQTZCLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFDNUQsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sb0JBQW9CLENBQUM7Ozs7Ozs7Ozs7Ozs7OztBQWV0RDs7Ozs7Ozs7Ozs7Ozs7O0lBQThHLHVDQUFRO0lBT3BILHFCQUFZLEtBQXFCLEVBQVUsT0FBZ0M7UUFBaEMsd0JBQUEsRUFBQSxZ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QUE4RCx5Q0FBb0I7SUFDaEYsdUJBQVksS0FBSztlQUNmLGtCQUFNLEtBQUssQ0FBQztJQUNkLENBQUM7SUFDSCxvQkFBQztBQUFELENBQUMsQUFKRCxDQUE4RCxXQUFXLEdBSXhFIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgT2JzZXJ2YWJsZSwgb2YgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IGRpc3RpbmN0VW50aWxDaGFuZ2VkLCBmaWx0ZXIsIG1hcCwgc3dpdGNoTWFwIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgaXNEZWZpbmVkIH0gZnJvbSAnLi9pc0RlZmluZWQnO1xuaW1wb3J0IHsgRW50aXR5U3RvcmUgfSBmcm9tICcuL2VudGl0eVN0b3JlJztcbmltcG9ydCB7IFF1ZXJ5IH0gZnJvbSAnLi9xdWVyeSc7XG5pbXBvcnQgeyBFbnRpdHlTdGF0ZSwgSGFzaE1hcCwgSUQsIEl0ZW1QcmVkaWNhdGUsIE9yQXJyYXksIFNlbGVjdE9wdGlvbnMsIGdldEVudGl0eVR5cGUsIGdldElEVHlwZSB9IGZyb20gJy4vdHlwZXMnO1xuaW1wb3J0IHsgaXNGdW5jdGlvbiB9IGZyb20gJy4vaXNGdW5jdGlvbic7XG5pbXBvcnQgeyB0b0Jvb2xlYW4gfSBmcm9tICcuL3RvQm9vbGVhbic7XG5pbXBvcnQgeyBzb3J0QnlPcHRpb25zIH0gZnJvbSAnLi9zb3J0QnlPcHRpb25zJztcbmltcG9ydCB7IGVudGl0aWVzVG9BcnJheSB9IGZyb20gJy4vZW50aXRpZXNUb0FycmF5JztcbmltcG9ydCB7IGVudGl0aWVzVG9NYXAgfSBmcm9tICcuL2VudGl0aWVzVG9NYXAnO1xuaW1wb3J0IHsgU2VsZWN0QWxsT3B0aW9uc0EsIFNlbGVjdEFsbE9wdGlvbnNCLCBTZWxlY3RBbGxPcHRpb25zQywgU2VsZWN0QWxsT3B0aW9uc0QsIFNlbGVjdEFsbE9wdGlvbnNFIH0gZnJvbSAnLi9zZWxlY3RBbGxPdmVybG9hZHMnO1xuaW1wb3J0IHsgaXNBcnJheSB9IGZyb20gJy4vaXNBcnJheSc7XG5pbXBvcnQgeyBpc05pbCB9IGZyb20gJy4vaXNOaWwnO1xuaW1wb3J0IHsgZmluZEVudGl0eUJ5UHJlZGljYXRlLCBnZXRFbnRpdHkgfSBmcm9tICcuL2dldEVudGl0eSc7XG5pbXBvcnQgeyBFbnRpdHlBY3Rpb24sIEVudGl0eUFjdGlvbnMgfSBmcm9tICcuL2VudGl0eUFjdGlvbnMnO1xuaW1wb3J0IHsgaXNVbmRlZmluZWQgfSBmcm9tICcuL2lzVW5kZWZpbmVkJztcbmltcG9ydCB7IFF1ZXJ5Q29uZmlnT3B0aW9ucyB9IGZyb20gJy4vcXVlcnlDb25maWcnO1xuaW1wb3J0IHsgZGlzdGluY3RVbnRpbEFycmF5SXRlbUNoYW5nZWQgfSBmcm9tICcuL2FycmF5RmluZCc7XG5pbXBvcnQgeyBtYXBTa2lwVW5kZWZpbmVkIH0gZnJvbSAnLi9tYXBTa2lwVW5kZWZpbmVkJztcblxuLyoqXG4gKlxuICogIFRoZSBFbnRpdHkgUXVlcnkgaXMgc2ltaWxhciB0byB0aGUgZ2VuZXJhbCBRdWVyeSwgd2l0aCBhZGRpdGlvbmFsIGZ1bmN0aW9uYWxpdHkgdGFpbG9yZWQgZm9yIEVudGl0eVN0b3Jlcy5cbiAqXG4gKiAgY2xhc3MgV2lkZ2V0c1F1ZXJ5IGV4dGVuZHMgUXVlcnlFbnRpdHk8V2lkZ2V0c1N0YXRlPiB7XG4gKiAgICAgY29uc3RydWN0b3IocHJvdGVjdGVkIHN0b3JlOiBXaWRnZXRzU3RvcmUpIHtcbiAqICAgICAgIHN1cGVyKHN0b3JlKTtcbiAqICAgICB9XG4gKiAgfVxuICpcbiAqXG4gKlxuICovXG5leHBvcnQgY2xhc3MgUXVlcnlFbnRpdHk8UyBleHRlbmRzIEVudGl0eVN0YXRlLCBFbnRpdHlUeXBlID0gZ2V0RW50aXR5VHlwZTxTPiwgSURUeXBlID0gZ2V0SURUeXBlPFM+PiBleHRlbmRzIFF1ZXJ5PFM+IHtcbiAgdWk6IEVudGl0eVVJUXVlcnk8YW55LCBFbnRpdHlUeXBlPjtcbiAgcHJvdGVjdGVkIHN0b3JlOiBFbnRpdHlTdG9yZTxTPjtcblxuICAvLyBAaW50ZXJuYWxcbiAgX19zdG9yZV9fO1xuXG4gIGNvbnN0cnVjdG9yKHN0b3JlOiBFbnRpdHlTdG9yZTxTPiwgcHJpdmF0ZSBvcHRpb25zOiBRdWVyeUNvbmZpZ09wdGlvbnMgPSB7fSkge1xuICAgIHN1cGVyKHN0b3JlKTtcbiAgICB0aGlzLl9fc3RvcmVfXyA9IHN0b3JlO1xuICB9XG5cbiAgLyoqXG4gICAqIFNlbGVjdCB0aGUgZW50aXJlIHN0b3JlJ3MgZW50aXR5IGNvbGxlY3Rpb25cbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICpcbiAgICogdGhpcy5xdWVyeS5zZWxlY3RBbGwoKVxuICAgKlxuICAgKiB0aGlzLnF1ZXJ5LnNlbGVjdEFsbCh7XG4gICAqICAgbGltaXRUbzogNVxuICAgKiAgIGZpbHRlckJ5OiBlbnRpdHkgPT4gZW50aXR5LmNvbXBsZXRlZCA9PT0gdHJ1ZVxuICAgKiB9KVxuICAgKlxuICAgKiB0aGlzLnF1ZXJ5LnNlbGVjdEFsbCh7XG4gICAqICAgYXNPYmplY3Q6IHRydWUsXG4gICAqICAgbGltaXRUbzogM1xuICAgKiB9KVxuICAgKlxuICAgKiAgdGhpcy5xdWVyeS5zZWxlY3RBbGwoe1xuICAgKiAgIHNvcnRCeTogJ3ByaWNlJyxcbiAgICogICBzb3J0QnlPcmRlcjogT3JkZXIuREVTQ1xuICAgKiB9KVxuICAgKlxuICAgKi9cbiAgc2VsZWN0QWxsKG9wdGlvbnM6IFNlbGVjdEFsbE9wdGlvbnNBPEVudGl0eVR5cGU+KTogT2JzZXJ2YWJsZTxIYXNoTWFwPEVudGl0eVR5cGU+PjtcbiAgc2VsZWN0QWxsKG9wdGlvbnM6IFNlbGVjdEFsbE9wdGlvbnNCPEVudGl0eVR5cGU+KTogT2JzZXJ2YWJsZTxFbnRpdHlUeXBlW10+O1xuICBzZWxlY3RBbGwob3B0aW9uczogU2VsZWN0QWxsT3B0aW9uc0M8RW50aXR5VHlwZT4pOiBPYnNlcnZhYmxlPEhhc2hNYXA8RW50aXR5VHlwZT4+O1xuICBzZWxlY3RBbGwob3B0aW9uczogU2VsZWN0QWxsT3B0aW9uc0Q8RW50aXR5VHlwZT4pOiBPYnNlcnZhYmxlPEVudGl0eVR5cGVbXT47XG4gIHNlbGVjdEFsbChvcHRpb25zOiBTZWxlY3RBbGxPcHRpb25zRTxFbnRpdHlUeXBlPik6IE9ic2VydmFibGU8RW50aXR5VHlwZVtdPjtcbiAgc2VsZWN0QWxsKCk6IE9ic2VydmFibGU8RW50aXR5VHlwZVtdPjtcbiAgc2VsZWN0QWxsKFxuICAgIG9wdGlvbnM6IFNlbGVjdE9wdGlvbnM8RW50aXR5VHlwZT4gPSB7XG4gICAgICBhc09iamVjdDogZmFsc2VcbiAgICB9XG4gICk6IE9ic2VydmFibGU8RW50aXR5VHlwZVtdIHwgSGFzaE1hcDxFbnRpdHlUeXBlPj4ge1xuICAgIHJldHVybiB0aGlzLnNlbGVjdChzdGF0ZSA9PiBzdGF0ZS5lbnRpdGllcykucGlwZShtYXAoKCkgPT4gdGhpcy5nZXRBbGwob3B0aW9ucykpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgdGhlIGVudGlyZSBzdG9yZSdzIGVudGl0eSBjb2xsZWN0aW9uXG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqXG4gICAqIHRoaXMucXVlcnkuZ2V0QWxsKClcbiAgICpcbiAgICogdGhpcy5xdWVyeS5nZXRBbGwoe1xuICAgKiAgIGxpbWl0VG86IDVcbiAgICogICBmaWx0ZXJCeTogZW50aXR5ID0+IGVudGl0eS5jb21wbGV0ZWQgPT09IHRydWVcbiAgICogfSlcbiAgICpcbiAgICogdGhpcy5xdWVyeS5nZXRBbGwoe1xuICAgKiAgIGFzT2JqZWN0OiB0cnVlLFxuICAgKiAgIGxpbWl0VG86IDNcbiAgICogfSlcbiAgICpcbiAgICogIHRoaXMucXVlcnkuZ2V0QWxsKHtcbiAgICogICBzb3J0Qnk6ICdwcmljZScsXG4gICAqICAgc29ydEJ5T3JkZXI6IE9yZGVyLkRFU0NcbiAgICogfSlcbiAgICovXG4gIGdldEFsbChvcHRpb25zOiBTZWxlY3RBbGxPcHRpb25zQTxFbnRpdHlUeXBlPik6IEhhc2hNYXA8RW50aXR5VHlwZT47XG4gIGdldEFsbChvcHRpb25zOiBTZWxlY3RBbGxPcHRpb25zQjxFbnRpdHlUeXBlPik6IEVudGl0eVR5cGVbXTtcbiAgZ2V0QWxsKG9wdGlvbnM6IFNlbGVjdEFsbE9wdGlvbnNDPEVudGl0eVR5cGU+KTogSGFzaE1hcDxFbnRpdHlUeXBlPjtcbiAgZ2V0QWxsKG9wdGlvbnM6IFNlbGVjdEFsbE9wdGlvbnNEPEVudGl0eVR5cGU+KTogRW50aXR5VHlwZVtdO1xuICBnZXRBbGwob3B0aW9uczogU2VsZWN0QWxsT3B0aW9uc0U8RW50aXR5VHlwZT4pOiBFbnRpdHlUeXBlW107XG4gIGdldEFsbCgpOiBFbnRpdHlUeXBlW107XG4gIGdldEFsbChvcHRpb25zOiBTZWxlY3RPcHRpb25zPEVudGl0eVR5cGU+ID0geyBhc09iamVjdDogZmFsc2UsIGZpbHRlckJ5OiB1bmRlZmluZWQsIGxpbWl0VG86IHVuZGVmaW5lZCB9KTogRW50aXR5VHlwZVtdIHwgSGFzaE1hcDxFbnRpdHlUeXBlPiB7XG4gICAgaWYgKG9wdGlvbnMuYXNPYmplY3QpIHtcbiAgICAgIHJldHVybiBlbnRpdGllc1RvTWFwKHRoaXMuZ2V0VmFsdWUoKSwgb3B0aW9ucyk7XG4gICAgfVxuICAgIHNvcnRCeU9wdGlvbnMob3B0aW9ucywgdGhpcy5jb25maWcgfHwgdGhpcy5vcHRpb25zKTtcblxuICAgIHJldHVybiBlbnRpdGllc1RvQXJyYXkodGhpcy5nZXRWYWx1ZSgpLCBvcHRpb25zKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTZWxlY3QgbXVsdGlwbGUgZW50aXRpZXMgZnJvbSB0aGUgc3RvcmVcbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICpcbiAgICogdGhpcy5xdWVyeS5zZWxlY3RNYW55KFsxLDIsM10pXG4gICAqIHRoaXMucXVlcnkuc2VsZWN0TWFueShbMSwyXSwgZW50aXR5ID0+IGVudGl0eS50aXRsZSlcbiAgICovXG4gIHNlbGVjdE1hbnk8Uj4oaWRzOiBJRFR5cGVbXSk6IE9ic2VydmFibGU8RW50aXR5VHlwZVtdPjtcbiAgc2VsZWN0TWFueTxSPihpZHM6IElEVHlwZVtdLCBwcm9qZWN0OiAoZW50aXR5OiBFbnRpdHlUeXBlKSA9PiBSKTogT2JzZXJ2YWJsZTxSW10+O1xuICBzZWxlY3RNYW55PFI+KGlkczogSURUeXBlW10sIHByb2plY3Q/OiAoZW50aXR5OiBFbnRpdHlUeXBlKSA9PiBSKTogT2JzZXJ2YWJsZTxFbnRpdHlUeXBlW10gfCBSW10+IHtcbiAgICBpZiAoIWlkcyB8fCAhaWRzLmxlbmd0aCkgcmV0dXJuIG9mKFtdKTtcblxuICAgIHJldHVybiB0aGlzLnNlbGVjdChzdGF0ZSA9PiBzdGF0ZS5lbnRpdGllcykucGlwZShcbiAgICAgIG1hcChlbnRpdGllcyA9PiBtYXBTa2lwVW5kZWZpbmVkKGlkcywgaWQgPT4gZ2V0RW50aXR5KGlkLCBwcm9qZWN0KShlbnRpdGllcykpKSxcbiAgICAgIGRpc3RpbmN0VW50aWxBcnJheUl0ZW1DaGFuZ2VkKClcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIFNlbGVjdCBhbiBlbnRpdHkgb3IgYSBzbGljZSBvZiBhbiBlbnRpdHlcbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICpcbiAgICogdGhpcy5xdWVyeS5zZWxlY3RFbnRpdHkoMSlcbiAgICogdGhpcy5xdWVyeS5zZWxlY3RFbnRpdHkoMSwgZW50aXR5ID0+IGVudGl0eS5jb25maWcuZGF0ZSlcbiAgICogdGhpcy5xdWVyeS5zZWxlY3RFbnRpdHkoMSwgJ2NvbW1lbnRzJylcbiAgICogdGhpcy5xdWVyeS5zZWxlY3RFbnRpdHkoZSA9PiBlLnRpdGxlID09PSAndGl0bGUnKVxuICAgKlxuICAgKi9cbiAgc2VsZWN0RW50aXR5PFI+KGlkOiBJRFR5cGUpOiBPYnNlcnZhYmxlPEVudGl0eVR5cGU+O1xuICBzZWxlY3RFbnRpdHk8SyBleHRlbmRzIGtleW9mIEVudGl0eVR5cGU+KGlkOiBJRFR5cGUsIHByb2plY3Q/OiBLKTogT2JzZXJ2YWJsZTxFbnRpdHlUeXBlW0tdPjtcbiAgc2VsZWN0RW50aXR5PFI+KGlkOiBJRFR5cGUsIHByb2plY3Q6IChlbnRpdHk6IEVudGl0eVR5cGUpID0+IFIpOiBPYnNlcnZhYmxlPFI+O1xuICBzZWxlY3RFbnRpdHk8Uj4ocHJlZGljYXRlOiBJdGVtUHJlZGljYXRlPEVudGl0eVR5cGU+KTogT2JzZXJ2YWJsZTxFbnRpdHlUeXBlPjtcbiAgc2VsZWN0RW50aXR5PFI+KGlkT3JQcmVkaWNhdGU6IElEVHlwZSB8IEl0ZW1QcmVkaWNhdGU8RW50aXR5VHlwZT4sIHByb2plY3Q/OiAoKGVudGl0eTogRW50aXR5VHlwZSkgPT4gUikgfCBrZXlvZiBFbnRpdHlUeXBlKTogT2JzZXJ2YWJsZTxSIHwgRW50aXR5VHlwZT4ge1xuICAgIGxldCBpZCA9IGlkT3JQcmVkaWNhdGU7XG5cbiAgICBpZiAoaXNGdW5jdGlvbihpZE9yUHJlZGljYXRlKSkge1xuICAgICAgLy8gRm9yIHBlcmZvcm1hbmNlIHJlYXNvbiB3ZSBleHBlY3QgdGhlIGVudGl0eSB0byBiZSBpbiB0aGUgc3RvcmVcbiAgICAgIChpZCBhcyBhbnkpID0gZmluZEVudGl0eUJ5UHJlZGljYXRlKGlkT3JQcmVkaWNhdGUsIHRoaXMuZ2V0VmFsdWUoKS5lbnRpdGllcyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuc2VsZWN0KHN0YXRlID0+IHN0YXRlLmVudGl0aWVzKS5waXBlKFxuICAgICAgbWFwKGdldEVudGl0eShpZCwgcHJvamVjdCkpLFxuICAgICAgZGlzdGluY3RVbnRpbENoYW5nZWQoKVxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogR2V0IGFuIGVudGl0eSBieSBpZFxuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKlxuICAgKiB0aGlzLnF1ZXJ5LmdldEVudGl0eSgxKTtcbiAgICovXG4gIGdldEVudGl0eShpZDogSURUeXBlKTogRW50aXR5VHlwZSB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0VmFsdWUoKS5lbnRpdGllc1tpZCBhcyBhbnldO1xuICB9XG5cbiAgLyoqXG4gICAqIFNlbGVjdCB0aGUgYWN0aXZlIGVudGl0eSdzIGlkXG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqXG4gICAqIHRoaXMucXVlcnkuc2VsZWN0QWN0aXZlSWQoKVxuICAgKi9cbiAgc2VsZWN0QWN0aXZlSWQoKTogT2JzZXJ2YWJsZTxTWydhY3RpdmUnXT4ge1xuICAgIHJldHVybiB0aGlzLnNlbGVjdChzdGF0ZSA9PiAoc3RhdGUgYXMgUyAmIHsgYWN0aXZlOiBTWydhY3RpdmUnXSB9KS5hY3RpdmUpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCB0aGUgYWN0aXZlIGlkXG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqXG4gICAqIHRoaXMucXVlcnkuZ2V0QWN0aXZlSWQoKVxuICAgKi9cbiAgZ2V0QWN0aXZlSWQoKTogU1snYWN0aXZlJ10ge1xuICAgIHJldHVybiB0aGlzLmdldFZhbHVlKCkuYWN0aXZlO1xuICB9XG5cbiAgLyoqXG4gICAqIFNlbGVjdCB0aGUgYWN0aXZlIGVudGl0eVxuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKlxuICAgKiB0aGlzLnF1ZXJ5LnNlbGVjdEFjdGl2ZSgpXG4gICAqIHRoaXMucXVlcnkuc2VsZWN0QWN0aXZlKGVudGl0eSA9PiBlbnRpdHkudGl0bGUpXG4gICAqL1xuICBzZWxlY3RBY3RpdmU8Uj4oKTogU1snYWN0aXZlJ10gZXh0ZW5kcyBhbnlbXSA/IE9ic2VydmFibGU8RW50aXR5VHlwZVtdPiA6IE9ic2VydmFibGU8RW50aXR5VHlwZT47XG4gIHNlbGVjdEFjdGl2ZTxSPihwcm9qZWN0PzogKGVudGl0eTogRW50aXR5VHlwZSkgPT4gUik6IFNbJ2FjdGl2ZSddIGV4dGVuZHMgYW55W10gPyBPYnNlcnZhYmxlPFJbXT4gOiBPYnNlcnZhYmxlPFI+O1xuICBzZWxlY3RBY3RpdmU8Uj4ocHJvamVjdD86IChlbnRpdHk6IEVudGl0eVR5cGUpID0+IFIpOiBPYnNlcnZhYmxlPFIgfCBFbnRpdHlUeXBlPiB8IE9ic2VydmFibGU8RW50aXR5VHlwZVtdIHwgUltdPiB7XG4gICAgaWYgKGlzQXJyYXkodGhpcy5nZXRBY3RpdmUoKSkpIHtcbiAgICAgIHJldHVybiB0aGlzLnNlbGVjdEFjdGl2ZUlkKCkucGlwZShzd2l0Y2hNYXAoaWRzID0+IHRoaXMuc2VsZWN0TWFueShpZHMsIHByb2plY3QpKSk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLnNlbGVjdEFjdGl2ZUlkKCkucGlwZShzd2l0Y2hNYXAoaWRzID0+IHRoaXMuc2VsZWN0RW50aXR5KGlkcywgcHJvamVjdCkpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgdGhlIGFjdGl2ZSBlbnRpdHlcbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICpcbiAgICogdGhpcy5xdWVyeS5nZXRBY3RpdmUoKVxuICAgKi9cbiAgZ2V0QWN0aXZlKCk6IFNbJ2FjdGl2ZSddIGV4dGVuZHMgYW55W10gPyBFbnRpdHlUeXBlW10gOiBFbnRpdHlUeXBlO1xuICBnZXRBY3RpdmUoKTogT3JBcnJheTxFbnRpdHlUeXBlPiB7XG4gICAgY29uc3QgYWN0aXZlSWQgPSB0aGlzLmdldEFjdGl2ZUlkKCk7XG4gICAgaWYgKGlzQXJyYXkoYWN0aXZlSWQpKSB7XG4gICAgICByZXR1cm4gYWN0aXZlSWQubWFwKGlkID0+IHRoaXMuZ2V0VmFsdWUoKS5lbnRpdGllc1tpZCBhcyBhbnldKTtcbiAgICB9XG4gICAgcmV0dXJuIHRvQm9vbGVhbihhY3RpdmVJZCkgPyB0aGlzLmdldEVudGl0eShhY3RpdmVJZCkgOiB1bmRlZmluZWQ7XG4gIH1cblxuICAvKipcbiAgICogU2VsZWN0IHRoZSBzdG9yZSdzIGVudGl0eSBjb2xsZWN0aW9uIGxlbmd0aFxuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKlxuICAgKiB0aGlzLnF1ZXJ5LnNlbGVjdENvdW50KClcbiAgICogdGhpcy5xdWVyeS5zZWxlY3RDb3VudChlbnRpdHkgPT4gZW50aXR5LmNvbXBsZXRlZClcbiAgICovXG4gIHNlbGVjdENvdW50KHByZWRpY2F0ZT86IChlbnRpdHk6IEVudGl0eVR5cGUsIGluZGV4OiBudW1iZXIpID0+IGJvb2xlYW4pOiBPYnNlcnZhYmxlPG51bWJlcj4ge1xuICAgIHJldHVybiB0aGlzLnNlbGVjdChzdGF0ZSA9PiBzdGF0ZS5lbnRpdGllcykucGlwZShtYXAoKCkgPT4gdGhpcy5nZXRDb3VudChwcmVkaWNhdGUpKSk7XG4gIH1cblxuICAvKipcbiAgICogR2V0IHRoZSBzdG9yZSdzIGVudGl0eSBjb2xsZWN0aW9uIGxlbmd0aFxuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKlxuICAgKiB0aGlzLnF1ZXJ5LmdldENvdW50KClcbiAgICogdGhpcy5xdWVyeS5nZXRDb3VudChlbnRpdHkgPT4gZW50aXR5LmNvbXBsZXRlZClcbiAgICovXG4gIGdldENvdW50KHByZWRpY2F0ZT86IChlbnRpdHk6IEVudGl0eVR5cGUsIGluZGV4OiBudW1iZXIpID0+IGJvb2xlYW4pOiBudW1iZXIge1xuICAgIGlmIChpc0Z1bmN0aW9uKHByZWRpY2F0ZSkpIHtcbiAgICAgIHJldHVybiB0aGlzLmdldEFsbCgpLmZpbHRlcihwcmVkaWNhdGUpLmxlbmd0aDtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuZ2V0VmFsdWUoKS5pZHMubGVuZ3RoO1xuICB9XG5cbiAgLyoqXG4gICAqXG4gICAqIFNlbGVjdCB0aGUgbGFzdCBlbnRpdHkgZnJvbSB0aGUgc3RvcmVcbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICpcbiAgICogdGhpcy5xdWVyeS5zZWxlY3RMYXN0KClcbiAgICogdGhpcy5xdWVyeS5zZWxlY3RMYXN0KHRvZG8gPT4gdG9kby50aXRsZSlcbiAgICovXG4gIHNlbGVjdExhc3Q8Uj4oKTogT2JzZXJ2YWJsZTxFbnRpdHlUeXBlPjtcbiAgc2VsZWN0TGFzdDxSPihwcm9qZWN0OiAoZW50aXR5OiBFbnRpdHlUeXBlKSA9PiBSKTogT2JzZXJ2YWJsZTxSPjtcbiAgc2VsZWN0TGFzdDxSPihwcm9qZWN0PzogKGVudGl0eTogRW50aXR5VHlwZSkgPT4gUik6IE9ic2VydmFibGU8UiB8IEVudGl0eVR5cGU+IHtcbiAgICByZXR1cm4gdGhpcy5zZWxlY3RBdChpZHMgPT4gaWRzW2lkcy5sZW5ndGggLSAxXSwgcHJvamVjdCk7XG4gIH1cblxuICAvKipcbiAgICpcbiAgICogU2VsZWN0IHRoZSBmaXJzdCBlbnRpdHkgZnJvbSB0aGUgc3RvcmVcbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICpcbiAgICogdGhpcy5xdWVyeS5zZWxlY3RGaXJzdCgpXG4gICAqIHRoaXMucXVlcnkuc2VsZWN0Rmlyc3QodG9kbyA9PiB0b2RvLnRpdGxlKVxuICAgKi9cbiAgc2VsZWN0Rmlyc3Q8Uj4oKTogT2JzZXJ2YWJsZTxFbnRpdHlUeXBlPjtcbiAgc2VsZWN0Rmlyc3Q8Uj4ocHJvamVjdDogKGVudGl0eTogRW50aXR5VHlwZSkgPT4gUik6IE9ic2VydmFibGU8Uj47XG4gIHNlbGVjdEZpcnN0PFI+KHByb2plY3Q/OiAoZW50aXR5OiBFbnRpdHlUeXBlKSA9PiBSKTogT2JzZXJ2YWJsZTxSIHwgRW50aXR5VHlwZT4ge1xuICAgIHJldHVybiB0aGlzLnNlbGVjdEF0KGlkcyA9PiBpZHNbMF0sIHByb2plY3QpO1xuICB9XG5cbiAgLyoqXG4gICAqXG4gICAqIExpc3RlbiBmb3IgZW50aXR5IGFjdGlvbnNcbiAgICpcbiAgICogIEBleGFtcGxlXG4gICAqXG4gICAqICB0aGlzLnF1ZXJ5LnNlbGVjdEVudGl0eUFjdGlvbihFbnRpdHlBY3Rpb25zLkFkZCk7XG4gICAqICB0aGlzLnF1ZXJ5LnNlbGVjdEVudGl0eUFjdGlvbihFbnRpdHlBY3Rpb25zLlVwZGF0ZSk7XG4gICAqICB0aGlzLnF1ZXJ5LnNlbGVjdEVudGl0eUFjdGlvbihFbnRpdHlBY3Rpb25zLlJlbW92ZSk7XG4gICAqXG4gICAqICB0aGlzLnF1ZXJ5LnNlbGVjdEVudGl0eUFjdGlvbigpO1xuICAgKi9cbiAgc2VsZWN0RW50aXR5QWN0aW9uKGFjdGlvbjogRW50aXR5QWN0aW9ucyk6IE9ic2VydmFibGU8SURbXT47XG4gIHNlbGVjdEVudGl0eUFjdGlvbigpOiBPYnNlcnZhYmxlPEVudGl0eUFjdGlvbjxFbnRpdHlUeXBlPj47XG4gIHNlbGVjdEVudGl0eUFjdGlvbihhY3Rpb24/OiBFbnRpdHlBY3Rpb25zKTogT2JzZXJ2YWJsZTxJRFtdIHwgRW50aXR5QWN0aW9uPEVudGl0eVR5cGU+PiB7XG4gICAgaWYgKGlzVW5kZWZpbmVkKGFjdGlvbikpIHtcbiAgICAgIHJldHVybiB0aGlzLnN0b3JlLnNlbGVjdEVudGl0eUFjdGlvbiQ7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLnN0b3JlLnNlbGVjdEVudGl0eUFjdGlvbiQucGlwZShcbiAgICAgIGZpbHRlcihhYyA9PiBhYy50eXBlID09PSBhY3Rpb24pLFxuICAgICAgbWFwKGFjdGlvbiA9PiBhY3Rpb24uaWRzKVxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB3aGV0aGVyIGVudGl0eSBleGlzdHNcbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICpcbiAgICogdGhpcy5xdWVyeS5oYXNFbnRpdHkoMilcbiAgICogdGhpcy5xdWVyeS5oYXNFbnRpdHkoZW50aXR5ID0+IGVudGl0eS5jb21wbGV0ZWQpXG4gICAqIHRoaXMucXVlcnkuaGFzRW50aXR5KFsxLCAyLCAzM10pXG4gICAqXG4gICAqL1xuICBoYXNFbnRpdHkoaWQ6IElEVHlwZSk6IGJvb2xlYW47XG4gIGhhc0VudGl0eShpZDogSURUeXBlW10pOiBib29sZWFuO1xuICBoYXNFbnRpdHkocHJvamVjdDogKGVudGl0eTogRW50aXR5VHlwZSkgPT4gYm9vbGVhbik6IGJvb2xlYW47XG4gIGhhc0VudGl0eSgpOiBib29sZWFuO1xuICBoYXNFbnRpdHkocHJvamVjdE9ySWRzPzogSURUeXBlIHwgSURUeXBlW10gfCAoKGVudGl0eTogRW50aXR5VHlwZSkgPT4gYm9vbGVhbikpOiBib29sZWFuIHtcbiAgICBpZiAoaXNOaWwocHJvamVjdE9ySWRzKSkge1xuICAgICAgcmV0dXJuIHRoaXMuZ2V0VmFsdWUoKS5pZHMubGVuZ3RoID4gMDtcbiAgICB9XG5cbiAgICBpZiAoaXNGdW5jdGlvbihwcm9qZWN0T3JJZHMpKSB7XG4gICAgICByZXR1cm4gdGhpcy5nZXRBbGwoKS5zb21lKHByb2plY3RPcklkcyk7XG4gICAgfVxuXG4gICAgaWYgKGlzQXJyYXkocHJvamVjdE9ySWRzKSkge1xuICAgICAgcmV0dXJuIHByb2plY3RPcklkcy5ldmVyeShpZCA9PiAoaWQgYXMgYW55KSBpbiB0aGlzLmdldFZhbHVlKCkuZW50aXRpZXMpO1xuICAgIH1cblxuICAgIHJldHVybiAocHJvamVjdE9ySWRzIGFzIGFueSkgaW4gdGhpcy5nZXRWYWx1ZSgpLmVudGl0aWVzO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgd2hldGhlciBlbnRpdHkgc3RvcmUgaGFzIGFuIGFjdGl2ZSBlbnRpdHlcbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICpcbiAgICogdGhpcy5xdWVyeS5oYXNBY3RpdmUoKVxuICAgKiB0aGlzLnF1ZXJ5Lmhhc0FjdGl2ZSgzKVxuICAgKlxuICAgKi9cbiAgaGFzQWN0aXZlKGlkPzogSURUeXBlKTogYm9vbGVhbiB7XG4gICAgY29uc3QgYWN0aXZlID0gdGhpcy5nZXRWYWx1ZSgpLmFjdGl2ZTtcbiAgICBpZiAoQXJyYXkuaXNBcnJheShhY3RpdmUpKSB7XG4gICAgICBpZiAoaXNEZWZpbmVkKGlkKSkge1xuICAgICAgICByZXR1cm4gYWN0aXZlLmluY2x1ZGVzKGlkKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBhY3RpdmUubGVuZ3RoID4gMDtcbiAgICB9XG4gICAgcmV0dXJuIGlzRGVmaW5lZChhY3RpdmUpO1xuICB9XG5cbiAgLyoqXG4gICAqXG4gICAqIENyZWF0ZSBzdWIgVUkgcXVlcnkgZm9yIHF1ZXJ5aW5nIEVudGl0eSdzIFVJIHN0YXRlXG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqXG4gICAqXG4gICAqIGV4cG9ydCBjbGFzcyBQcm9kdWN0c1F1ZXJ5IGV4dGVuZHMgUXVlcnlFbnRpdHk8UHJvZHVjdHNTdGF0ZT4ge1xuICAgKiAgIHVpOiBFbnRpdHlVSVF1ZXJ5PFByb2R1Y3RzVUlTdGF0ZT47XG4gICAqXG4gICAqICAgY29uc3RydWN0b3IocHJvdGVjdGVkIHN0b3JlOiBQcm9kdWN0c1N0b3JlKSB7XG4gICAqICAgICBzdXBlcihzdG9yZSk7XG4gICAqICAgICB0aGlzLmNyZWF0ZVVJUXVlcnkoKTtcbiAgICogICB9XG4gICAqXG4gICAqIH1cbiAgICovXG4gIGNyZWF0ZVVJUXVlcnkoKSB7XG4gICAgdGhpcy51aSA9IG5ldyBFbnRpdHlVSVF1ZXJ5KHRoaXMuX19zdG9yZV9fLnVpKTtcbiAgfVxuXG4gIHByaXZhdGUgc2VsZWN0QXQ8Uj4obWFwRm46IChpZHM6IElEVHlwZVtdKSA9PiBJRFR5cGUsIHByb2plY3Q/OiAoZW50aXR5OiBFbnRpdHlUeXBlKSA9PiBSKSB7XG4gICAgcmV0dXJuIHRoaXMuc2VsZWN0KHN0YXRlID0+IHN0YXRlLmlkcyBhcyBhbnlbXSkucGlwZShcbiAgICAgIG1hcChtYXBGbiksXG4gICAgICBkaXN0aW5jdFVudGlsQ2hhbmdlZCgpLFxuICAgICAgc3dpdGNoTWFwKChpZDogSURUeXBlKSA9PiB0aGlzLnNlbGVjdEVudGl0eShpZCwgcHJvamVjdCkpXG4gICAgKTtcbiAgfVxufVxuXG4vLyBAaW50ZXJuYWxcbmV4cG9ydCBjbGFzcyBFbnRpdHlVSVF1ZXJ5PFVJU3RhdGUsIERFUFJFQ0FURUQgPSBhbnk+IGV4dGVuZHMgUXVlcnlFbnRpdHk8VUlTdGF0ZT4ge1xuICBjb25zdHJ1Y3RvcihzdG9yZSkge1xuICAgIHN1cGVyKHN0b3JlKTtcbiAgfVxufVxuIl19