UNPKG

@datorama/akita

Version:

State Management Tailored-Made for JS Applications

358 lines 30.1 kB
/** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ import { EntityService, isDefined } from '@datorama/akita'; import { throwError } from 'rxjs'; import { inject } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { catchError, finalize, map, tap } from 'rxjs/operators'; import { HttpMethod, NgEntityServiceNotifier } from './ng-entity-service-notifier'; import { NgEntityServiceLoader } from './ng-entity-service.loader'; import { defaultConfig, mergeDeep, NG_ENTITY_SERVICE_CONFIG } from './ng-entity-service.config'; import { isID } from './helpers'; import { errorAction, successAction } from './action-factory'; /** @type {?} */ export const mapResponse = (/** * @param {?} config * @return {?} */ (config) => map((/** * @param {?} res * @return {?} */ res => ((config || {}).mapResponseFn ? config.mapResponseFn(res) : res)))); /** * @template S */ export class NgEntityService extends EntityService { /** * @param {?} store * @param {?=} config */ constructor(store, config = {}) { super(); this.store = store; this.config = config; this.globalConfig = {}; this.http = inject(HttpClient); this.loader = inject(NgEntityServiceLoader); this.notifier = inject(NgEntityServiceNotifier); this.globalConfig = inject(NG_ENTITY_SERVICE_CONFIG); this.mergedConfig = mergeDeep(defaultConfig, this.globalConfig, config); this.dispatchSuccess = successAction(this.store.storeName, this.notifier); this.dispatchError = errorAction(this.store.storeName, this.notifier); } /** * @return {?} */ get api() { return `${this.baseUrl || this.getConfigValue('baseUrl')}/${this.resourceName}`; } /** * @return {?} */ get resourceName() { return this.getConfigValue('resourceName') || this.store.storeName; } /** * @param {?} api * @return {?} */ setBaseUrl(api) { this.baseUrl = api; } /** * @template T * @param {?=} idOrConfig * @param {?=} config * @return {?} */ get(idOrConfig, config) { /** @type {?} */ let url; /** @type {?} */ const isSingle = isID(idOrConfig); /** @type {?} */ const _config = (isSingle ? config : idOrConfig) || {}; /** @type {?} */ const method = this.getHttpMethod(HttpMethod.GET); if (_config.url) { url = _config.url; } else { url = isSingle ? `${this.api}/${idOrConfig}` : this.api; } this.loader.dispatch({ method, loading: true, entityId: isSingle ? idOrConfig : null, storeName: this.store.storeName }); return (/** @type {?} */ (this.http[method.toLowerCase()](url, _config).pipe(mapResponse(_config), tap((/** * @param {?} data * @return {?} */ (data) => { if (isSingle) { this.store.upsert((/** @type {?} */ (idOrConfig)), data); } else { _config.append ? this.store.add(data) : this.store.set(data); } this.dispatchSuccess({ method, payload: data, successMsg: _config.successMsg }); })), catchError((/** * @param {?} error * @return {?} */ error => this.handleError(method, error, _config.errorMsg))), finalize((/** * @return {?} */ () => { this.loader.dispatch({ method, loading: false, storeName: this.store.storeName }); }))))); } /** * * Add a new entity - Creates a POST request * * service.add(entity) * service.add(entity, config) * * @template T * @param {?} entity * @param {?=} config * @return {?} */ add(entity, config) { /** @type {?} */ const method = this.getHttpMethod(HttpMethod.POST); this.loader.dispatch({ method, loading: true, storeName: this.store.storeName }); return (/** @type {?} */ (this.http[method.toLowerCase()](this.resolveUrl(config), entity, config).pipe(mapResponse(config), tap((/** * @param {?} entity * @return {?} */ (entity) => { this.store.add(entity, config); this.dispatchSuccess({ method, payload: entity, successMsg: config && config.successMsg }); })), catchError((/** * @param {?} error * @return {?} */ error => this.handleError(method, error, config && config.errorMsg))), finalize((/** * @return {?} */ () => { this.loader.dispatch({ method, loading: false, storeName: this.store.storeName }); }))))); } /** * * Update an entity - Creates a PUT/PATCH request * * service.update(id, entity) * service.update(id, entity, config) * * @template T * @param {?} id * @param {?} entity * @param {?=} config * @return {?} */ update(id, entity, config) { /** @type {?} */ const method = config && config.method ? config.method : this.getHttpMethod(HttpMethod.PUT); this.loader.dispatch({ method, loading: true, entityId: id, storeName: this.store.storeName }); return (/** @type {?} */ (this.http[method.toLocaleLowerCase()](this.resolveUrl(config, id), entity, config).pipe(mapResponse(config), tap((/** * @param {?} entity * @return {?} */ entity => { this.store.update(id, (/** @type {?} */ (entity))); this.dispatchSuccess({ method, payload: entity, successMsg: config && config.successMsg }); })), catchError((/** * @param {?} error * @return {?} */ error => this.handleError(method, error, config && config.errorMsg))), finalize((/** * @return {?} */ () => { this.loader.dispatch({ method, loading: false, entityId: id, storeName: this.store.storeName }); }))))); } /** * * Delete an entity - Creates a DELETE request * * service.delete(id) * service.delete(id, config) * * @template T * @param {?} id * @param {?=} config * @return {?} */ delete(id, config) { /** @type {?} */ const method = this.getHttpMethod(HttpMethod.DELETE); this.loader.dispatch({ method, loading: true, entityId: id, storeName: this.store.storeName }); return (/** @type {?} */ (this.http[method.toLowerCase()](this.resolveUrl(config, id), config).pipe(mapResponse(config), tap((/** * @param {?} res * @return {?} */ res => { this.store.remove(id); this.dispatchSuccess({ method, payload: res, successMsg: config && config.successMsg }); })), catchError((/** * @param {?} error * @return {?} */ error => this.handleError(method, error, config && config.errorMsg))), finalize((/** * @return {?} */ () => { this.loader.dispatch({ method, loading: false, entityId: id, storeName: this.store.storeName }); }))))); } /** * @private * @param {?} type * @return {?} */ getHttpMethod(type) { return this.mergedConfig.httpMethods[type]; } /** * @private * @param {?} key * @return {?} */ getConfigValue(key) { return this.constructor[key] || this.mergedConfig[key]; } /** * @private * @param {?} config * @param {?=} id * @return {?} */ resolveUrl(config, id) { /** @type {?} */ const customUrl = (config || {}).url; if (isDefined(id)) { return customUrl || `${this.api}/${id}`; } return customUrl || this.api; } /** * @private * @param {?} method * @param {?} error * @param {?} errorMsg * @return {?} */ handleError(method, error, errorMsg) { this.dispatchError({ method, errorMsg, payload: error }); return throwError(error); } } if (false) { /** @type {?} */ NgEntityService.prototype.baseUrl; /** @type {?} */ NgEntityService.prototype.loader; /** * @type {?} * @private */ NgEntityService.prototype.http; /** * @type {?} * @private */ NgEntityService.prototype.notifier; /** * @type {?} * @private */ NgEntityService.prototype.globalConfig; /** * @type {?} * @private */ NgEntityService.prototype.mergedConfig; /** * @type {?} * @private */ NgEntityService.prototype.dispatchSuccess; /** * @type {?} * @private */ NgEntityService.prototype.dispatchError; /** * @type {?} * @protected */ NgEntityService.prototype.store; /** * @type {?} * @private */ NgEntityService.prototype.config; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmctZW50aXR5LnNlcnZpY2UuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9AZGF0b3JhbWEvYWtpdGEvYW5ndWxhci9wbGF5Z3JvdW5kL3Byb2plY3RzL25nLWVudGl0eS1zZXJ2aWNlLyIsInNvdXJjZXMiOlsibGliL25nLWVudGl0eS5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7QUFBQSxPQUFPLEVBRUwsYUFBYSxFQUtiLFNBQVMsRUFDVixNQUFNLGlCQUFpQixDQUFDO0FBQ3pCLE9BQU8sRUFBYyxVQUFVLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDOUMsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUN2QyxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDbEQsT0FBTyxFQUFFLFVBQVUsRUFBRSxRQUFRLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRWhFLE9BQU8sRUFBdUIsVUFBVSxFQUFFLHVCQUF1QixFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFDeEcsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDbkUsT0FBTyxFQUNMLGFBQWEsRUFDYixTQUFTLEVBQ1Qsd0JBQXdCLEVBRXpCLE1BQU0sNEJBQTRCLENBQUM7QUFDcEMsT0FBTyxFQUFFLElBQUksRUFBRSxNQUFNLFdBQVcsQ0FBQztBQUNqQyxPQUFPLEVBQUUsV0FBVyxFQUFFLGFBQWEsRUFBRSxNQUFNLGtCQUFrQixDQUFDOztBQUU5RCxNQUFNLE9BQU8sV0FBVzs7OztBQUFHLENBQUMsTUFBa0IsRUFBRSxFQUFFLENBQ2hELEdBQUc7Ozs7QUFBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxNQUFNLElBQUksRUFBRSxDQUFDLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsYUFBYSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsRUFBQyxDQUFBOzs7O0FBRTlFLE1BQU0sT0FBTyxlQUE2QyxTQUFRLGFBQWdCOzs7OztJQVloRixZQUFzQixLQUFxQixFQUFVLFNBQWdDLEVBQUU7UUFDckYsS0FBSyxFQUFFLENBQUM7UUFEWSxVQUFLLEdBQUwsS0FBSyxDQUFnQjtRQUFVLFdBQU0sR0FBTixNQUFNLENBQTRCO1FBTi9FLGlCQUFZLEdBQWdDLEVBQUUsQ0FBQztRQVFyRCxJQUFJLENBQUMsSUFBSSxHQUFHLE1BQU0sQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUMvQixJQUFJLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDO1FBQzVDLElBQUksQ0FBQyxRQUFRLEdBQUcsTUFBTSxDQUFDLHVCQUF1QixDQUFDLENBQUM7UUFDaEQsSUFBSSxDQUFDLFlBQVksR0FBRyxNQUFNLENBQUMsd0JBQXdCLENBQUMsQ0FBQztRQUVyRCxJQUFJLENBQUMsWUFBWSxHQUFHLFNBQVMsQ0FBQyxhQUFhLEVBQUUsSUFBSSxDQUFDLFlBQVksRUFBRSxNQUFNLENBQUMsQ0FBQztRQUV4RSxJQUFJLENBQUMsZUFBZSxHQUFHLGFBQWEsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLFNBQVMsRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDMUUsSUFBSSxDQUFDLGFBQWEsR0FBRyxXQUFXLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxTQUFTLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBQ3hFLENBQUM7Ozs7SUFFRCxJQUFJLEdBQUc7UUFDTCxPQUFPLEdBQUcsSUFBSSxDQUFDLE9BQU8sSUFBSSxJQUFJLENBQUMsY0FBYyxDQUFDLFNBQVMsQ0FBQyxJQUFJLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztJQUNsRixDQUFDOzs7O0lBRUQsSUFBSSxZQUFZO1FBQ2QsT0FBTyxJQUFJLENBQUMsY0FBYyxDQUFDLGNBQWMsQ0FBQyxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDO0lBQ3JFLENBQUM7Ozs7O0lBRUQsVUFBVSxDQUFDLEdBQVc7UUFDcEIsSUFBSSxDQUFDLE9BQU8sR0FBRyxHQUFHLENBQUM7SUFDckIsQ0FBQzs7Ozs7OztJQWVELEdBQUcsQ0FBSSxVQUFzQyxFQUFFLE1BQWdEOztZQUN6RixHQUFXOztjQUNULFFBQVEsR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDOztjQUMzQixPQUFPLEdBQTRDLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxJQUFJLEVBQUU7O2NBQ3pGLE1BQU0sR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUM7UUFFakQsSUFBSSxPQUFPLENBQUMsR0FBRyxFQUFFO1lBQ2YsR0FBRyxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUM7U0FDbkI7YUFBTTtZQUNMLEdBQUcsR0FBRyxRQUFRLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLEdBQUcsSUFBSSxVQUFVLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQztTQUN6RDtRQUVELElBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDO1lBQ25CLE1BQU07WUFDTixPQUFPLEVBQUUsSUFBSTtZQUNiLFFBQVEsRUFBRSxRQUFRLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsSUFBSTtZQUN0QyxTQUFTLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxTQUFTO1NBQ2hDLENBQUMsQ0FBQztRQUVILE9BQU8sbUJBQUEsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsV0FBVyxFQUFFLENBQUMsQ0FBQyxHQUFHLEVBQUUsT0FBTyxDQUFDLENBQUMsSUFBSSxDQUN2RCxXQUFXLENBQUMsT0FBTyxDQUFDLEVBQ3BCLEdBQUc7Ozs7UUFBQyxDQUFDLElBQVMsRUFBRSxFQUFFO1lBQ2hCLElBQUksUUFBUSxFQUFFO2dCQUNaLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLG1CQUFBLFVBQVUsRUFBZ0IsRUFBRSxJQUFJLENBQUMsQ0FBQzthQUNyRDtpQkFBTTtnQkFDTCxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUM7YUFDOUQ7WUFFRCxJQUFJLENBQUMsZUFBZSxDQUFDO2dCQUNuQixNQUFNO2dCQUNOLE9BQU8sRUFBRSxJQUFJO2dCQUNiLFVBQVUsRUFBRSxPQUFPLENBQUMsVUFBVTthQUMvQixDQUFDLENBQUM7UUFDTCxDQUFDLEVBQUMsRUFDRixVQUFVOzs7O1FBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLE1BQU0sRUFBRSxLQUFLLEVBQUUsT0FBTyxDQUFDLFFBQVEsQ0FBQyxFQUFDLEVBQ3RFLFFBQVE7OztRQUFDLEdBQUcsRUFBRTtZQUNaLElBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDO2dCQUNuQixNQUFNO2dCQUNOLE9BQU8sRUFBRSxLQUFLO2dCQUNkLFNBQVMsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLFNBQVM7YUFDaEMsQ0FBQyxDQUFDO1FBQ0wsQ0FBQyxFQUFDLENBQ0gsRUFBaUIsQ0FBQztJQUNyQixDQUFDOzs7Ozs7Ozs7Ozs7O0lBVUQsR0FBRyxDQUFJLE1BQXdCLEVBQUUsTUFBK0Q7O2NBQ3hGLE1BQU0sR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUM7UUFFbEQsSUFBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUM7WUFDbkIsTUFBTTtZQUNOLE9BQU8sRUFBRSxJQUFJO1lBQ2IsU0FBUyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsU0FBUztTQUNoQyxDQUFDLENBQUM7UUFDSCxPQUFPLG1CQUFBLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLFdBQVcsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsRUFBRSxNQUFNLEVBQUUsTUFBTSxDQUFDLENBQUMsSUFBSSxDQUNsRixXQUFXLENBQUMsTUFBTSxDQUFDLEVBQ25CLEdBQUc7Ozs7UUFBQyxDQUFDLE1BQVcsRUFBRSxFQUFFO1lBQ2xCLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLE1BQU0sRUFBRSxNQUFNLENBQUMsQ0FBQztZQUMvQixJQUFJLENBQUMsZUFBZSxDQUFDO2dCQUNuQixNQUFNO2dCQUNOLE9BQU8sRUFBRSxNQUFNO2dCQUNmLFVBQVUsRUFBRSxNQUFNLElBQUksTUFBTSxDQUFDLFVBQVU7YUFDeEMsQ0FBQyxDQUFDO1FBQ0wsQ0FBQyxFQUFDLEVBQ0YsVUFBVTs7OztRQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxNQUFNLEVBQUUsS0FBSyxFQUFFLE1BQU0sSUFBSSxNQUFNLENBQUMsUUFBUSxDQUFDLEVBQUMsRUFDL0UsUUFBUTs7O1FBQUMsR0FBRyxFQUFFO1lBQ1osSUFBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUM7Z0JBQ25CLE1BQU07Z0JBQ04sT0FBTyxFQUFFLEtBQUs7Z0JBQ2QsU0FBUyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsU0FBUzthQUNoQyxDQUFDLENBQUM7UUFDTCxDQUFDLEVBQUMsQ0FDSCxFQUFpQixDQUFDO0lBQ3JCLENBQUM7Ozs7Ozs7Ozs7Ozs7O0lBVUQsTUFBTSxDQUNKLEVBQWdCLEVBQ2hCLE1BQWlDLEVBQ2pDLE1BQXlFOztjQUVuRSxNQUFNLEdBQUcsTUFBTSxJQUFJLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQztRQUUzRixJQUFJLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQztZQUNuQixNQUFNO1lBQ04sT0FBTyxFQUFFLElBQUk7WUFDYixRQUFRLEVBQUUsRUFBRTtZQUNaLFNBQVMsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLFNBQVM7U0FDaEMsQ0FBQyxDQUFDO1FBRUgsT0FBTyxtQkFBQSxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxpQkFBaUIsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUFDLEVBQUUsTUFBTSxFQUFFLE1BQU0sQ0FBQyxDQUFDLElBQUksQ0FDNUYsV0FBVyxDQUFDLE1BQU0sQ0FBQyxFQUNuQixHQUFHOzs7O1FBQUMsTUFBTSxDQUFDLEVBQUU7WUFDWCxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxFQUFFLEVBQUUsbUJBQUEsTUFBTSxFQUFPLENBQUMsQ0FBQztZQUNyQyxJQUFJLENBQUMsZUFBZSxDQUFDO2dCQUNuQixNQUFNO2dCQUNOLE9BQU8sRUFBRSxNQUFNO2dCQUNmLFVBQVUsRUFBRSxNQUFNLElBQUksTUFBTSxDQUFDLFVBQVU7YUFDeEMsQ0FBQyxDQUFDO1FBQ0wsQ0FBQyxFQUFDLEVBQ0YsVUFBVTs7OztRQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxNQUFNLEVBQUUsS0FBSyxFQUFFLE1BQU0sSUFBSSxNQUFNLENBQUMsUUFBUSxDQUFDLEVBQUMsRUFDL0UsUUFBUTs7O1FBQUMsR0FBRyxFQUFFO1lBQ1osSUFBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUM7Z0JBQ25CLE1BQU07Z0JBQ04sT0FBTyxFQUFFLEtBQUs7Z0JBQ2QsUUFBUSxFQUFFLEVBQUU7Z0JBQ1osU0FBUyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsU0FBUzthQUNoQyxDQUFDLENBQUM7UUFDTCxDQUFDLEVBQUMsQ0FDSCxFQUFpQixDQUFDO0lBQ3JCLENBQUM7Ozs7Ozs7Ozs7Ozs7SUFVRCxNQUFNLENBQUksRUFBZ0IsRUFBRSxNQUF5Qjs7Y0FDN0MsTUFBTSxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQztRQUVwRCxJQUFJLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQztZQUNuQixNQUFNO1lBQ04sT0FBTyxFQUFFLElBQUk7WUFDYixRQUFRLEVBQUUsRUFBRTtZQUNaLFNBQVMsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLFNBQVM7U0FDaEMsQ0FBQyxDQUFDO1FBRUgsT0FBTyxtQkFBQSxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxXQUFXLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsTUFBTSxFQUFFLEVBQUUsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxDQUFDLElBQUksQ0FDOUUsV0FBVyxDQUFDLE1BQU0sQ0FBQyxFQUNuQixHQUFHOzs7O1FBQUMsR0FBRyxDQUFDLEVBQUU7WUFDUixJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUN0QixJQUFJLENBQUMsZUFBZSxDQUFDO2dCQUNuQixNQUFNO2dCQUNOLE9BQU8sRUFBRSxHQUFHO2dCQUNaLFVBQVUsRUFBRSxNQUFNLElBQUksTUFBTSxDQUFDLFVBQVU7YUFDeEMsQ0FBQyxDQUFDO1FBQ0wsQ0FBQyxFQUFDLEVBQ0YsVUFBVTs7OztRQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxNQUFNLEVBQUUsS0FBSyxFQUFFLE1BQU0sSUFBSSxNQUFNLENBQUMsUUFBUSxDQUFDLEVBQUMsRUFDL0UsUUFBUTs7O1FBQUMsR0FBRyxFQUFFO1lBQ1osSUFBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUM7Z0JBQ25CLE1BQU07Z0JBQ04sT0FBTyxFQUFFLEtBQUs7Z0JBQ2QsUUFBUSxFQUFFLEVBQUU7Z0JBQ1osU0FBUyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsU0FBUzthQUNoQyxDQUFDLENBQUM7UUFDTCxDQUFDLEVBQUMsQ0FDSCxFQUFpQixDQUFDO0lBQ3JCLENBQUM7Ozs7OztJQUVPLGFBQWEsQ0FBQyxJQUFnQjtRQUNwQyxPQUFPLElBQUksQ0FBQyxZQUFZLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQzdDLENBQUM7Ozs7OztJQUVPLGNBQWMsQ0FBQyxHQUFXO1FBQ2hDLE9BQU8sSUFBSSxDQUFDLFdBQVcsQ0FBQyxHQUFHLENBQUMsSUFBSSxJQUFJLENBQUMsWUFBWSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQ3pELENBQUM7Ozs7Ozs7SUFFTyxVQUFVLENBQUMsTUFBa0IsRUFBRSxFQUFROztjQUN2QyxTQUFTLEdBQUcsQ0FBQyxNQUFNLElBQUksRUFBRSxDQUFDLENBQUMsR0FBRztRQUNwQyxJQUFJLFNBQVMsQ0FBQyxFQUFFLENBQUMsRUFBRTtZQUNqQixPQUFPLFNBQVMsSUFBSSxHQUFHLElBQUksQ0FBQyxHQUFHLElBQUksRUFBRSxFQUFFLENBQUM7U0FDekM7UUFDRCxPQUFPLFNBQVMsSUFBSSxJQUFJLENBQUMsR0FBRyxDQUFDO0lBQy9CLENBQUM7Ozs7Ozs7O0lBRU8sV0FBVyxDQUFDLE1BQWtCLEVBQUUsS0FBVSxFQUFFLFFBQWdCO1FBQ2xFLElBQUksQ0FBQyxhQUFhLENBQUM7WUFDakIsTUFBTTtZQUNOLFFBQVE7WUFDUixPQUFPLEVBQUUsS0FBSztTQUNmLENBQUMsQ0FBQztRQUNILE9BQU8sVUFBVSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQzNCLENBQUM7Q0FDRjs7O0lBL09DLGtDQUFnQjs7SUFDaEIsaUNBQThCOzs7OztJQUU5QiwrQkFBeUI7Ozs7O0lBQ3pCLG1DQUEwQzs7Ozs7SUFDMUMsdUNBQXVEOzs7OztJQUN2RCx1Q0FBMEU7Ozs7O0lBRTFFLDBDQUF3RTs7Ozs7SUFDeEUsd0NBQXNFOzs7OztJQUUxRCxnQ0FBK0I7Ozs7O0lBQUUsaUNBQTBDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQWRkRW50aXRpZXNPcHRpb25zLFxuICBFbnRpdHlTZXJ2aWNlLFxuICBFbnRpdHlTdGF0ZSxcbiAgRW50aXR5U3RvcmUsXG4gIGdldEVudGl0eVR5cGUsXG4gIGdldElEVHlwZSxcbiAgaXNEZWZpbmVkXG59IGZyb20gJ0BkYXRvcmFtYS9ha2l0YSc7XG5pbXBvcnQgeyBPYnNlcnZhYmxlLCB0aHJvd0Vycm9yIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBpbmplY3QgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEh0dHBDbGllbnQgfSBmcm9tICdAYW5ndWxhci9jb21tb24vaHR0cCc7XG5pbXBvcnQgeyBjYXRjaEVycm9yLCBmaW5hbGl6ZSwgbWFwLCB0YXAgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBIdHRwQ29uZmlnLCBNc2csIE5nRW50aXR5U2VydmljZVBhcmFtcyB9IGZyb20gJy4vdHlwZXMnO1xuaW1wb3J0IHsgRW50aXR5U2VydmljZUFjdGlvbiwgSHR0cE1ldGhvZCwgTmdFbnRpdHlTZXJ2aWNlTm90aWZpZXIgfSBmcm9tICcuL25nLWVudGl0eS1zZXJ2aWNlLW5vdGlmaWVyJztcbmltcG9ydCB7IE5nRW50aXR5U2VydmljZUxvYWRlciB9IGZyb20gJy4vbmctZW50aXR5LXNlcnZpY2UubG9hZGVyJztcbmltcG9ydCB7XG4gIGRlZmF1bHRDb25maWcsXG4gIG1lcmdlRGVlcCxcbiAgTkdfRU5USVRZX1NFUlZJQ0VfQ09ORklHLFxuICBOZ0VudGl0eVNlcnZpY2VHbG9iYWxDb25maWdcbn0gZnJvbSAnLi9uZy1lbnRpdHktc2VydmljZS5jb25maWcnO1xuaW1wb3J0IHsgaXNJRCB9IGZyb20gJy4vaGVscGVycyc7XG5pbXBvcnQgeyBlcnJvckFjdGlvbiwgc3VjY2Vzc0FjdGlvbiB9IGZyb20gJy4vYWN0aW9uLWZhY3RvcnknO1xuXG5leHBvcnQgY29uc3QgbWFwUmVzcG9uc2UgPSAoY29uZmlnOiBIdHRwQ29uZmlnKSA9PlxuICBtYXAocmVzID0+ICgoY29uZmlnIHx8IHt9KS5tYXBSZXNwb25zZUZuID8gY29uZmlnLm1hcFJlc3BvbnNlRm4ocmVzKSA6IHJlcykpO1xuXG5leHBvcnQgY2xhc3MgTmdFbnRpdHlTZXJ2aWNlPFMgZXh0ZW5kcyBFbnRpdHlTdGF0ZSA9IGFueT4gZXh0ZW5kcyBFbnRpdHlTZXJ2aWNlPFM+IHtcbiAgYmFzZVVybDogc3RyaW5nO1xuICBsb2FkZXI6IE5nRW50aXR5U2VydmljZUxvYWRlcjtcblxuICBwcml2YXRlIGh0dHA6IEh0dHBDbGllbnQ7XG4gIHByaXZhdGUgbm90aWZpZXI6IE5nRW50aXR5U2VydmljZU5vdGlmaWVyO1xuICBwcml2YXRlIGdsb2JhbENvbmZpZzogTmdFbnRpdHlTZXJ2aWNlR2xvYmFsQ29uZmlnID0ge307XG4gIHByaXZhdGUgbWVyZ2VkQ29uZmlnOiBOZ0VudGl0eVNlcnZpY2VQYXJhbXMgJiBOZ0VudGl0eVNlcnZpY2VHbG9iYWxDb25maWc7XG5cbiAgcHJpdmF0ZSBkaXNwYXRjaFN1Y2Nlc3M6IChhY3Rpb246IFBhcnRpYWw8RW50aXR5U2VydmljZUFjdGlvbj4pID0+IHZvaWQ7XG4gIHByaXZhdGUgZGlzcGF0Y2hFcnJvcjogKGFjdGlvbjogUGFydGlhbDxFbnRpdHlTZXJ2aWNlQWN0aW9uPikgPT4gdm9pZDtcblxuICBjb25zdHJ1Y3Rvcihwcm90ZWN0ZWQgc3RvcmU6IEVudGl0eVN0b3JlPFM+LCBwcml2YXRlIGNvbmZpZzogTmdFbnRpdHlTZXJ2aWNlUGFyYW1zID0ge30pIHtcbiAgICBzdXBlcigpO1xuICAgIHRoaXMuaHR0cCA9IGluamVjdChIdHRwQ2xpZW50KTtcbiAgICB0aGlzLmxvYWRlciA9IGluamVjdChOZ0VudGl0eVNlcnZpY2VMb2FkZXIpO1xuICAgIHRoaXMubm90aWZpZXIgPSBpbmplY3QoTmdFbnRpdHlTZXJ2aWNlTm90aWZpZXIpO1xuICAgIHRoaXMuZ2xvYmFsQ29uZmlnID0gaW5qZWN0KE5HX0VOVElUWV9TRVJWSUNFX0NPTkZJRyk7XG5cbiAgICB0aGlzLm1lcmdlZENvbmZpZyA9IG1lcmdlRGVlcChkZWZhdWx0Q29uZmlnLCB0aGlzLmdsb2JhbENvbmZpZywgY29uZmlnKTtcblxuICAgIHRoaXMuZGlzcGF0Y2hTdWNjZXNzID0gc3VjY2Vzc0FjdGlvbih0aGlzLnN0b3JlLnN0b3JlTmFtZSwgdGhpcy5ub3RpZmllcik7XG4gICAgdGhpcy5kaXNwYXRjaEVycm9yID0gZXJyb3JBY3Rpb24odGhpcy5zdG9yZS5zdG9yZU5hbWUsIHRoaXMubm90aWZpZXIpO1xuICB9XG5cbiAgZ2V0IGFwaSgpIHtcbiAgICByZXR1cm4gYCR7dGhpcy5iYXNlVXJsIHx8IHRoaXMuZ2V0Q29uZmlnVmFsdWUoJ2Jhc2VVcmwnKX0vJHt0aGlzLnJlc291cmNlTmFtZX1gO1xuICB9XG5cbiAgZ2V0IHJlc291cmNlTmFtZSgpIHtcbiAgICByZXR1cm4gdGhpcy5nZXRDb25maWdWYWx1ZSgncmVzb3VyY2VOYW1lJykgfHwgdGhpcy5zdG9yZS5zdG9yZU5hbWU7XG4gIH1cblxuICBzZXRCYXNlVXJsKGFwaTogc3RyaW5nKSB7XG4gICAgdGhpcy5iYXNlVXJsID0gYXBpO1xuICB9XG5cbiAgLyoqXG4gICAqXG4gICAqIEdldCBhbGwgb3Igb25lIGVudGl0eSAtIENyZWF0ZXMgYSBHRVQgcmVxdWVzdFxuICAgKlxuICAgKiBzZXJ2aWNlLmdldCgpLnN1YnNjcmliZSgpXG4gICAqIHNlcnZpY2UuZ2V0KHsgaGVhZGVycywgcGFyYW1zLCB1cmwgfSlcbiAgICpcbiAgICogc2VydmljZS5nZXQoaWQpXG4gICAqIHNlcnZpY2UuZ2V0KGlkLCB7IGhlYWRlcnMsIHBhcmFtcywgdXJsIH0pXG4gICAqXG4gICAqL1xuICBnZXQ8VD4oaWQ/OiBnZXRJRFR5cGU8Uz4sIGNvbmZpZz86IEh0dHBDb25maWcgJiB7IGFwcGVuZD86IGJvb2xlYW4gfSAmIE1zZyk6IE9ic2VydmFibGU8VD47XG4gIGdldDxUPihjb25maWc/OiBIdHRwQ29uZmlnICYgeyBhcHBlbmQ/OiBib29sZWFuIH0gJiBNc2cpOiBPYnNlcnZhYmxlPFQ+O1xuICBnZXQ8VD4oaWRPckNvbmZpZz86IGdldElEVHlwZTxTPiB8IEh0dHBDb25maWcsIGNvbmZpZz86IEh0dHBDb25maWcgJiB7IGFwcGVuZD86IGJvb2xlYW4gfSAmIE1zZyk6IE9ic2VydmFibGU8VD4ge1xuICAgIGxldCB1cmw6IHN0cmluZztcbiAgICBjb25zdCBpc1NpbmdsZSA9IGlzSUQoaWRPckNvbmZpZyk7XG4gICAgY29uc3QgX2NvbmZpZzogSHR0cENvbmZpZyAmIHsgYXBwZW5kPzogYm9vbGVhbiB9ICYgTXNnID0gKGlzU2luZ2xlID8gY29uZmlnIDogaWRPckNvbmZpZykgfHwge307XG4gICAgY29uc3QgbWV0aG9kID0gdGhpcy5nZXRIdHRwTWV0aG9kKEh0dHBNZXRob2QuR0VUKTtcblxuICAgIGlmIChfY29uZmlnLnVybCkge1xuICAgICAgdXJsID0gX2NvbmZpZy51cmw7XG4gICAgfSBlbHNlIHtcbiAgICAgIHVybCA9IGlzU2luZ2xlID8gYCR7dGhpcy5hcGl9LyR7aWRPckNvbmZpZ31gIDogdGhpcy5hcGk7XG4gICAgfVxuXG4gICAgdGhpcy5sb2FkZXIuZGlzcGF0Y2goe1xuICAgICAgbWV0aG9kLFxuICAgICAgbG9hZGluZzogdHJ1ZSxcbiAgICAgIGVudGl0eUlkOiBpc1NpbmdsZSA/IGlkT3JDb25maWcgOiBudWxsLFxuICAgICAgc3RvcmVOYW1lOiB0aGlzLnN0b3JlLnN0b3JlTmFtZVxuICAgIH0pO1xuXG4gICAgcmV0dXJuIHRoaXMuaHR0cFttZXRob2QudG9Mb3dlckNhc2UoKV0odXJsLCBfY29uZmlnKS5waXBlKFxuICAgICAgbWFwUmVzcG9uc2UoX2NvbmZpZyksXG4gICAgICB0YXAoKGRhdGE6IGFueSkgPT4ge1xuICAgICAgICBpZiAoaXNTaW5nbGUpIHtcbiAgICAgICAgICB0aGlzLnN0b3JlLnVwc2VydChpZE9yQ29uZmlnIGFzIGdldElEVHlwZTxTPiwgZGF0YSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgX2NvbmZpZy5hcHBlbmQgPyB0aGlzLnN0b3JlLmFkZChkYXRhKSA6IHRoaXMuc3RvcmUuc2V0KGRhdGEpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5kaXNwYXRjaFN1Y2Nlc3Moe1xuICAgICAgICAgIG1ldGhvZCxcbiAgICAgICAgICBwYXlsb2FkOiBkYXRhLFxuICAgICAgICAgIHN1Y2Nlc3NNc2c6IF9jb25maWcuc3VjY2Vzc01zZ1xuICAgICAgICB9KTtcbiAgICAgIH0pLFxuICAgICAgY2F0Y2hFcnJvcihlcnJvciA9PiB0aGlzLmhhbmRsZUVycm9yKG1ldGhvZCwgZXJyb3IsIF9jb25maWcuZXJyb3JNc2cpKSxcbiAgICAgIGZpbmFsaXplKCgpID0+IHtcbiAgICAgICAgdGhpcy5sb2FkZXIuZGlzcGF0Y2goe1xuICAgICAgICAgIG1ldGhvZCxcbiAgICAgICAgICBsb2FkaW5nOiBmYWxzZSxcbiAgICAgICAgICBzdG9yZU5hbWU6IHRoaXMuc3RvcmUuc3RvcmVOYW1lXG4gICAgICAgIH0pO1xuICAgICAgfSlcbiAgICApIGFzIE9ic2VydmFibGU8VD47XG4gIH1cblxuICAvKipcbiAgICpcbiAgICogQWRkIGEgbmV3IGVudGl0eSAtIENyZWF0ZXMgYSBQT1NUIHJlcXVlc3RcbiAgICpcbiAgICogc2VydmljZS5hZGQoZW50aXR5KVxuICAgKiBzZXJ2aWNlLmFkZChlbnRpdHksIGNvbmZpZylcbiAgICpcbiAgICovXG4gIGFkZDxUPihlbnRpdHk6IGdldEVudGl0eVR5cGU8Uz4sIGNvbmZpZz86IEh0dHBDb25maWcgJiBQaWNrPEFkZEVudGl0aWVzT3B0aW9ucywgJ3ByZXBlbmQnPiAmIE1zZyk6IE9ic2VydmFibGU8VD4ge1xuICAgIGNvbnN0IG1ldGhvZCA9IHRoaXMuZ2V0SHR0cE1ldGhvZChIdHRwTWV0aG9kLlBPU1QpO1xuXG4gICAgdGhpcy5sb2FkZXIuZGlzcGF0Y2goe1xuICAgICAgbWV0aG9kLFxuICAgICAgbG9hZGluZzogdHJ1ZSxcbiAgICAgIHN0b3JlTmFtZTogdGhpcy5zdG9yZS5zdG9yZU5hbWVcbiAgICB9KTtcbiAgICByZXR1cm4gdGhpcy5odHRwW21ldGhvZC50b0xvd2VyQ2FzZSgpXSh0aGlzLnJlc29sdmVVcmwoY29uZmlnKSwgZW50aXR5LCBjb25maWcpLnBpcGUoXG4gICAgICBtYXBSZXNwb25zZShjb25maWcpLFxuICAgICAgdGFwKChlbnRpdHk6IGFueSkgPT4ge1xuICAgICAgICB0aGlzLnN0b3JlLmFkZChlbnRpdHksIGNvbmZpZyk7XG4gICAgICAgIHRoaXMuZGlzcGF0Y2hTdWNjZXNzKHtcbiAgICAgICAgICBtZXRob2QsXG4gICAgICAgICAgcGF5bG9hZDogZW50aXR5LFxuICAgICAgICAgIHN1Y2Nlc3NNc2c6IGNvbmZpZyAmJiBjb25maWcuc3VjY2Vzc01zZ1xuICAgICAgICB9KTtcbiAgICAgIH0pLFxuICAgICAgY2F0Y2hFcnJvcihlcnJvciA9PiB0aGlzLmhhbmRsZUVycm9yKG1ldGhvZCwgZXJyb3IsIGNvbmZpZyAmJiBjb25maWcuZXJyb3JNc2cpKSxcbiAgICAgIGZpbmFsaXplKCgpID0+IHtcbiAgICAgICAgdGhpcy5sb2FkZXIuZGlzcGF0Y2goe1xuICAgICAgICAgIG1ldGhvZCxcbiAgICAgICAgICBsb2FkaW5nOiBmYWxzZSxcbiAgICAgICAgICBzdG9yZU5hbWU6IHRoaXMuc3RvcmUuc3RvcmVOYW1lXG4gICAgICAgIH0pO1xuICAgICAgfSlcbiAgICApIGFzIE9ic2VydmFibGU8VD47XG4gIH1cblxuICAvKipcbiAgICpcbiAgICogVXBkYXRlIGFuIGVudGl0eSAtIENyZWF0ZXMgYSBQVVQvUEFUQ0ggcmVxdWVzdFxuICAgKlxuICAgKiBzZXJ2aWNlLnVwZGF0ZShpZCwgZW50aXR5KVxuICAgKiBzZXJ2aWNlLnVwZGF0ZShpZCwgZW50aXR5LCBjb25maWcpXG4gICAqXG4gICAqL1xuICB1cGRhdGU8VD4oXG4gICAgaWQ6IGdldElEVHlwZTxTPixcbiAgICBlbnRpdHk6IFBhcnRpYWw8Z2V0RW50aXR5VHlwZTxTPj4sXG4gICAgY29uZmlnPzogSHR0cENvbmZpZyAmIHsgbWV0aG9kOiBIdHRwTWV0aG9kLlBVVCB8IEh0dHBNZXRob2QuUEFUQ0ggfSAmIE1zZ1xuICApOiBPYnNlcnZhYmxlPFQ+IHtcbiAgICBjb25zdCBtZXRob2QgPSBjb25maWcgJiYgY29uZmlnLm1ldGhvZCA/IGNvbmZpZy5tZXRob2QgOiB0aGlzLmdldEh0dHBNZXRob2QoSHR0cE1ldGhvZC5QVVQpO1xuXG4gICAgdGhpcy5sb2FkZXIuZGlzcGF0Y2goe1xuICAgICAgbWV0aG9kLFxuICAgICAgbG9hZGluZzogdHJ1ZSxcbiAgICAgIGVudGl0eUlkOiBpZCxcbiAgICAgIHN0b3JlTmFtZTogdGhpcy5zdG9yZS5zdG9yZU5hbWVcbiAgICB9KTtcblxuICAgIHJldHVybiB0aGlzLmh0dHBbbWV0aG9kLnRvTG9jYWxlTG93ZXJDYXNlKCldKHRoaXMucmVzb2x2ZVVybChjb25maWcsIGlkKSwgZW50aXR5LCBjb25maWcpLnBpcGUoXG4gICAgICBtYXBSZXNwb25zZShjb25maWcpLFxuICAgICAgdGFwKGVudGl0eSA9PiB7XG4gICAgICAgIHRoaXMuc3RvcmUudXBkYXRlKGlkLCBlbnRpdHkgYXMgYW55KTtcbiAgICAgICAgdGhpcy5kaXNwYXRjaFN1Y2Nlc3Moe1xuICAgICAgICAgIG1ldGhvZCxcbiAgICAgICAgICBwYXlsb2FkOiBlbnRpdHksXG4gICAgICAgICAgc3VjY2Vzc01zZzogY29uZmlnICYmIGNvbmZpZy5zdWNjZXNzTXNnXG4gICAgICAgIH0pO1xuICAgICAgfSksXG4gICAgICBjYXRjaEVycm9yKGVycm9yID0+IHRoaXMuaGFuZGxlRXJyb3IobWV0aG9kLCBlcnJvciwgY29uZmlnICYmIGNvbmZpZy5lcnJvck1zZykpLFxuICAgICAgZmluYWxpemUoKCkgPT4ge1xuICAgICAgICB0aGlzLmxvYWRlci5kaXNwYXRjaCh7XG4gICAgICAgICAgbWV0aG9kLFxuICAgICAgICAgIGxvYWRpbmc6IGZhbHNlLFxuICAgICAgICAgIGVudGl0eUlkOiBpZCxcbiAgICAgICAgICBzdG9yZU5hbWU6IHRoaXMuc3RvcmUuc3RvcmVOYW1lXG4gICAgICAgIH0pO1xuICAgICAgfSlcbiAgICApIGFzIE9ic2VydmFibGU8VD47XG4gIH1cblxuICAvKipcbiAgICpcbiAgICogRGVsZXRlIGFuIGVudGl0eSAtIENyZWF0ZXMgYSBERUxFVEUgcmVxdWVzdFxuICAgKlxuICAgKiBzZXJ2aWNlLmRlbGV0ZShpZClcbiAgICogc2VydmljZS5kZWxldGUoaWQsIGNvbmZpZylcbiAgICpcbiAgICovXG4gIGRlbGV0ZTxUPihpZDogZ2V0SURUeXBlPFM+LCBjb25maWc/OiBIdHRwQ29uZmlnICYgTXNnKTogT2JzZXJ2YWJsZTxUPiB7XG4gICAgY29uc3QgbWV0aG9kID0gdGhpcy5nZXRIdHRwTWV0aG9kKEh0dHBNZXRob2QuREVMRVRFKTtcblxuICAgIHRoaXMubG9hZGVyLmRpc3BhdGNoKHtcbiAgICAgIG1ldGhvZCxcbiAgICAgIGxvYWRpbmc6IHRydWUsXG4gICAgICBlbnRpdHlJZDogaWQsXG4gICAgICBzdG9yZU5hbWU6IHRoaXMuc3RvcmUuc3RvcmVOYW1lXG4gICAgfSk7XG5cbiAgICByZXR1cm4gdGhpcy5odHRwW21ldGhvZC50b0xvd2VyQ2FzZSgpXSh0aGlzLnJlc29sdmVVcmwoY29uZmlnLCBpZCksIGNvbmZpZykucGlwZShcbiAgICAgIG1hcFJlc3BvbnNlKGNvbmZpZyksXG4gICAgICB0YXAocmVzID0+IHtcbiAgICAgICAgdGhpcy5zdG9yZS5yZW1vdmUoaWQpO1xuICAgICAgICB0aGlzLmRpc3BhdGNoU3VjY2Vzcyh7XG4gICAgICAgICAgbWV0aG9kLFxuICAgICAgICAgIHBheWxvYWQ6IHJlcyxcbiAgICAgICAgICBzdWNjZXNzTXNnOiBjb25maWcgJiYgY29uZmlnLnN1Y2Nlc3NNc2dcbiAgICAgICAgfSk7XG4gICAgICB9KSxcbiAgICAgIGNhdGNoRXJyb3IoZXJyb3IgPT4gdGhpcy5oYW5kbGVFcnJvcihtZXRob2QsIGVycm9yLCBjb25maWcgJiYgY29uZmlnLmVycm9yTXNnKSksXG4gICAgICBmaW5hbGl6ZSgoKSA9PiB7XG4gICAgICAgIHRoaXMubG9hZGVyLmRpc3BhdGNoKHtcbiAgICAgICAgICBtZXRob2QsXG4gICAgICAgICAgbG9hZGluZzogZmFsc2UsXG4gICAgICAgICAgZW50aXR5SWQ6IGlkLFxuICAgICAgICAgIHN0b3JlTmFtZTogdGhpcy5zdG9yZS5zdG9yZU5hbWVcbiAgICAgICAgfSk7XG4gICAgICB9KVxuICAgICkgYXMgT2JzZXJ2YWJsZTxUPjtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0SHR0cE1ldGhvZCh0eXBlOiBIdHRwTWV0aG9kKSB7XG4gICAgcmV0dXJuIHRoaXMubWVyZ2VkQ29uZmlnLmh0dHBNZXRob2RzW3R5cGVdO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRDb25maWdWYWx1ZShrZXk6IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLmNvbnN0cnVjdG9yW2tleV0gfHwgdGhpcy5tZXJnZWRDb25maWdba2V5XTtcbiAgfVxuXG4gIHByaXZhdGUgcmVzb2x2ZVVybChjb25maWc6IEh0dHBDb25maWcsIGlkPzogYW55KSB7XG4gICAgY29uc3QgY3VzdG9tVXJsID0gKGNvbmZpZyB8fCB7fSkudXJsO1xuICAgIGlmIChpc0RlZmluZWQoaWQpKSB7XG4gICAgICByZXR1cm4gY3VzdG9tVXJsIHx8IGAke3RoaXMuYXBpfS8ke2lkfWA7XG4gICAgfVxuICAgIHJldHVybiBjdXN0b21VcmwgfHwgdGhpcy5hcGk7XG4gIH1cblxuICBwcml2YXRlIGhhbmRsZUVycm9yKG1ldGhvZDogSHR0cE1ldGhvZCwgZXJyb3I6IGFueSwgZXJyb3JNc2c6IHN0cmluZykge1xuICAgIHRoaXMuZGlzcGF0Y2hFcnJvcih7XG4gICAgICBtZXRob2QsXG4gICAgICBlcnJvck1zZyxcbiAgICAgIHBheWxvYWQ6IGVycm9yXG4gICAgfSk7XG4gICAgcmV0dXJuIHRocm93RXJyb3IoZXJyb3IpO1xuICB9XG59XG4iXX0=