UNPKG

@spartacus/cart

Version:

`@spartacus/cart` is a package that you can include in your application, which allows you to use various cart features.

324 lines 39.9 kB
import { Injectable } from '@angular/core'; import { defaultQuickOrderConfig, } from '@spartacus/cart/quick-order/root'; import { CartAddEntryFailEvent, CartAddEntrySuccessEvent, HttpErrorModel, } from '@spartacus/core'; import { BehaviorSubject, of, Subject, timer, } from 'rxjs'; import { filter, first, map, switchMap, take, tap } from 'rxjs/operators'; import * as i0 from "@angular/core"; import * as i1 from "@spartacus/core"; export class QuickOrderService { constructor(activeCartService, productAdapter, // TODO(#14059): Remove this service eventService, productSearchConnector //TODO(#14059): Make it required ) { this.activeCartService = activeCartService; this.productAdapter = productAdapter; this.eventService = eventService; this.productSearchConnector = productSearchConnector; this.productAdded$ = new Subject(); this.entries$ = new BehaviorSubject([]); this.softDeletedEntries$ = new BehaviorSubject({}); this.nonPurchasableProductError$ = new BehaviorSubject(null); this.hardDeleteTimeout = 5000; this.quickOrderListLimit = 0; this.clearDeleteTimeouts = {}; } ngOnDestroy() { this.clearDeletedEntries(); } /** * Get entries */ getEntries() { return this.entries$; } /** * @deprecated since 4.2 - use searchProducts instead * Search product using SKU */ search(productCode) { return this.productAdapter.load(productCode); } /** * Search products using query */ searchProducts(query, maxProducts) { var _a, _b; // TODO(#14059): Remove condition if (this.productSearchConnector) { const searchConfig = { pageSize: maxProducts || ((_b = (_a = defaultQuickOrderConfig.quickOrder) === null || _a === void 0 ? void 0 : _a.searchForm) === null || _b === void 0 ? void 0 : _b.maxProducts), }; return this.productSearchConnector .search(query, searchConfig) .pipe(map((searchPage) => searchPage.products || [])); } else { return of([]); } } /** * Clear a list of added entries */ clearList() { this.entries$.next([]); } /** * Get information about the possibility to add the next product */ canAdd(code) { if (code) { return of(this.isProductOnTheList(code) || !this.isLimitExceeded()); } else { return of(!this.isLimitExceeded()); } } /** * Set quick order list limit property */ setListLimit(limit) { this.quickOrderListLimit = limit; } /** * Load a list of entries */ loadEntries(entries = []) { this.entries$.next(entries); } /** * Load a list of entries */ updateEntryQuantity(entryIndex, quantity) { const entries = this.entries$.getValue() || []; entries[entryIndex].quantity = quantity; this.entries$.next(entries); } /** * Delete single entry from the list */ softDeleteEntry(index) { this.entries$.pipe(take(1)).subscribe((entries) => { const entriesList = entries; this.addSoftEntryDeletion(entriesList[index], true); entriesList.splice(index, 1); this.entries$.next(entriesList); }); } /** * @deprecated since 4.2 - use softDeleteEntry instead */ removeEntry(index) { this.softDeleteEntry(index); } /** * Add product to the quick order list */ addProduct(product, quantity = 1) { const entry = this.generateOrderEntry(product, quantity); this.addEntry(entry); } /** * Return product added subject */ getProductAdded() { return this.productAdded$; } /** * Set product added subject */ setProductAdded(productCode) { this.productAdded$.next(productCode); } /** * Adding to cart all products from the list */ addToCart() { let entries = []; const events = []; const subscription = this.eventService .get(CartAddEntrySuccessEvent) .subscribe((cartEvent) => { if (cartEvent.quantityAdded === 0 || (!!cartEvent.quantityAdded && cartEvent.quantityAdded < cartEvent.quantity)) { events.push(this.createQuickOrderResultEvent(cartEvent)); } }); subscription.add(this.eventService .get(CartAddEntryFailEvent) .subscribe((cartEvent) => { events.push(this.createQuickOrderResultEvent(cartEvent)); })); return this.getEntries().pipe(first(), switchMap((elements) => { entries = elements; this.activeCartService.addEntries(elements); this.clearList(); return this.activeCartService.isStable(); }), filter((isStable) => isStable), map(() => [entries, events]), tap(() => subscription.unsubscribe())); } /** * Return soft deleted entries */ getSoftDeletedEntries() { return this.softDeletedEntries$; } /** * Restore soft deleted entry */ restoreSoftDeletedEntry(productCode) { const entry = this.getSoftDeletedEntry(productCode); this.addEntry(entry); this.hardDeleteEntry(productCode); } /** * Clear deleted entry from the list */ hardDeleteEntry(productCode) { const entry = this.getSoftDeletedEntry(productCode); const deletedEntries = this.softDeletedEntries$.getValue(); if (entry) { delete deletedEntries[productCode]; this.softDeletedEntries$.next(deletedEntries); } this.clearDeleteTimeout(productCode); } /** * Clear all deleted entries and timeout subscriptions */ clearDeletedEntries() { Object.values(this.clearDeleteTimeouts).forEach((subscription) => subscription.unsubscribe()); this.softDeletedEntries$.next({}); this.clearDeleteTimeouts = {}; } /** * Return non purchasable product error */ getNonPurchasableProductError() { return this.nonPurchasableProductError$; } /** * Set error that selected product is not purchasable */ setNonPurchasableProductError(product) { this.nonPurchasableProductError$.next(product); } /** * Clear not purchasable product error */ clearNonPurchasableProductError() { this.nonPurchasableProductError$.next(null); } /** * Add soft deleted entry to the cached list */ addSoftEntryDeletion(entry, clearTimeout = true) { var _a; const deletedEntries = this.softDeletedEntries$.getValue(); const productCode = (_a = entry === null || entry === void 0 ? void 0 : entry.product) === null || _a === void 0 ? void 0 : _a.code; if (productCode) { deletedEntries[productCode] = entry; this.softDeletedEntries$.next(deletedEntries); if (clearTimeout) { const subscription = timer(this.hardDeleteTimeout).subscribe(() => { this.hardDeleteEntry(productCode); }); this.clearDeleteTimeouts[productCode] = subscription; } } } /** * Get soft deletion entry */ getSoftDeletedEntry(productCode) { const deletedEntries = this.softDeletedEntries$.getValue(); return deletedEntries[productCode]; } /** * Generate Order Entry from Product */ generateOrderEntry(product, quantity) { return { basePrice: product.price, product, quantity, totalPrice: product.price, }; } /** * Add single entry to the list */ addEntry(entry) { var _a, _b, _c, _d, _e; if (((_a = entry === null || entry === void 0 ? void 0 : entry.product) === null || _a === void 0 ? void 0 : _a.code) && !this.isProductOnTheList(entry.product.code) && this.isLimitExceeded()) { return; } const entries = this.entries$.getValue() || []; const entryStockLevel = (_c = (_b = entry.product) === null || _b === void 0 ? void 0 : _b.stock) === null || _c === void 0 ? void 0 : _c.stockLevel; if (entryStockLevel && entry.quantity && entry.quantity > entryStockLevel) { entry.quantity = entryStockLevel; } if (((_d = entry.product) === null || _d === void 0 ? void 0 : _d.code) && this.isProductOnTheList(entry.product.code)) { const entryIndex = entries.findIndex((item) => { var _a, _b; return ((_a = item.product) === null || _a === void 0 ? void 0 : _a.code) === ((_b = entry.product) === null || _b === void 0 ? void 0 : _b.code); }); let quantity = entries[entryIndex].quantity; if (quantity && entry.quantity) { entries[entryIndex].quantity = quantity + (entry === null || entry === void 0 ? void 0 : entry.quantity); let newQuantity = entries[entryIndex].quantity; if (newQuantity && entryStockLevel && newQuantity > entryStockLevel) { entries[entryIndex].quantity = entryStockLevel; } this.entries$.next([...entries]); } } else { this.entries$.next([...entries, ...[entry]]); } this.productAdded$.next((_e = entry.product) === null || _e === void 0 ? void 0 : _e.code); } /** * Verify if product is already on the list */ isProductOnTheList(productCode) { const entries = this.entries$.getValue() || []; return !!entries.find((item) => { var _a; return ((_a = item.product) === null || _a === void 0 ? void 0 : _a.code) === productCode; }); } isLimitExceeded() { const entries = this.entries$.getValue() || []; return entries.length >= this.quickOrderListLimit; } createQuickOrderResultEvent(cartEvent) { var _a, _b, _c; const evt = { productCode: cartEvent.productCode, quantity: cartEvent.quantity, }; if ('entry' in cartEvent) { evt.entry = cartEvent.entry; } if ('quantityAdded' in cartEvent) { evt.quantityAdded = cartEvent.quantityAdded; } if ('error' in cartEvent && cartEvent.error instanceof HttpErrorModel) { evt.error = cartEvent.error; } if ((_b = (_a = evt.error) === null || _a === void 0 ? void 0 : _a.details) === null || _b === void 0 ? void 0 : _b.length) { const isOutOfStock = (_c = evt.error) === null || _c === void 0 ? void 0 : _c.details.some((e) => e.type === 'InsufficientStockError'); evt.quantityAdded = isOutOfStock ? 0 : evt.quantity; } return evt; } clearDeleteTimeout(productCode) { const clearMessageTimout = this.clearDeleteTimeouts[productCode]; if (clearMessageTimout) { clearMessageTimout.unsubscribe(); delete this.clearDeleteTimeouts[productCode]; } } } QuickOrderService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.0.5", ngImport: i0, type: QuickOrderService, deps: [{ token: i1.ActiveCartService }, { token: i1.ProductAdapter }, { token: i1.EventService }, { token: i1.ProductSearchConnector }], target: i0.ɵɵFactoryTarget.Injectable }); QuickOrderService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.0.5", ngImport: i0, type: QuickOrderService }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.0.5", ngImport: i0, type: QuickOrderService, decorators: [{ type: Injectable }], ctorParameters: function () { return [{ type: i1.ActiveCartService }, { type: i1.ProductAdapter }, { type: i1.EventService }, { type: i1.ProductSearchConnector }]; } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicXVpY2stb3JkZXIuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL2ZlYXR1cmUtbGlicy9jYXJ0L3F1aWNrLW9yZGVyL2NvcmUvc2VydmljZXMvcXVpY2stb3JkZXIuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFhLE1BQU0sZUFBZSxDQUFDO0FBQ3RELE9BQU8sRUFDTCx1QkFBdUIsR0FHeEIsTUFBTSxrQ0FBa0MsQ0FBQztBQUMxQyxPQUFPLEVBRUwscUJBQXFCLEVBQ3JCLHdCQUF3QixFQUV4QixjQUFjLEdBT2YsTUFBTSxpQkFBaUIsQ0FBQztBQUN6QixPQUFPLEVBQ0wsZUFBZSxFQUVmLEVBQUUsRUFDRixPQUFPLEVBRVAsS0FBSyxHQUNOLE1BQU0sTUFBTSxDQUFDO0FBQ2QsT0FBTyxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsR0FBRyxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUUsR0FBRyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7OztBQUcxRSxNQUFNLE9BQU8saUJBQWlCO0lBd0I1QixZQUNZLGlCQUFvQyxFQUNwQyxjQUE4QixFQUFFLG9DQUFvQztJQUNwRSxZQUEwQixFQUMxQixzQkFBK0MsQ0FBQyxnQ0FBZ0M7O1FBSGhGLHNCQUFpQixHQUFqQixpQkFBaUIsQ0FBbUI7UUFDcEMsbUJBQWMsR0FBZCxjQUFjLENBQWdCO1FBQzlCLGlCQUFZLEdBQVosWUFBWSxDQUFjO1FBQzFCLDJCQUFzQixHQUF0QixzQkFBc0IsQ0FBeUI7UUEzQmpELGtCQUFhLEdBQW9CLElBQUksT0FBTyxFQUFVLENBQUM7UUFDdkQsYUFBUSxHQUFrQyxJQUFJLGVBQWUsQ0FFckUsRUFBRSxDQUFDLENBQUM7UUFDSSx3QkFBbUIsR0FDM0IsSUFBSSxlQUFlLENBQTZCLEVBQUUsQ0FBQyxDQUFDO1FBQzVDLGdDQUEyQixHQUNuQyxJQUFJLGVBQWUsQ0FBaUIsSUFB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QUFHLFNBQVMsQ0FBQyxhQUFhLENBQUM7U0FDN0M7UUFDRCxJQUFJLE9BQU8sSUFBSSxTQUFTLElBQUksU0FBUyxDQUFDLEtBQUssWUFBWSxjQUFjLEVBQUU7WUFDckUsR0FBRyxDQUFDLEtBQUssR0FBRyxTQUFTLENBQUMsS0FBSyxDQUFDO1NBQzdCO1FBRUQsSUFBSSxNQUFBLE1BQUEsR0FBRyxDQUFDLEtBQUssMENBQUUsT0FBTywwQ0FBRSxNQUFNLEVBQUU7WUFDOUIsTUFBTSxZQUFZLEdBQUcsTUFBQSxHQUFHLENBQUMsS0FBSywwQ0FBRSxPQUFPLENBQUMsSUFBSSxDQUMxQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksS0FBSyx3QkFBd0IsQ0FDM0MsQ0FBQztZQUNGLEdBQUcsQ0FBQyxhQUFhLEdBQUcsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUM7U0FDckQ7UUFFRCxPQUFPLEdBQUcsQ0FBQztJQUNiLENBQUM7SUFFUyxrQkFBa0IsQ0FBQyxXQUFtQjtRQUM5QyxNQUFNLGtCQUFrQixHQUFHLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxXQUFXLENBQUMsQ0FBQztRQUVqRSxJQUFJLGtCQUFrQixFQUFFO1lBQ3RCLGtCQUFrQixDQUFDLFdBQVcsRUFBRSxDQUFDO1lBQ2pDLE9BQU8sSUFBSSxDQUFDLG1CQUFtQixDQUFDLFdBQVcsQ0FBQyxDQUFDO1NBQzlDO0lBQ0gsQ0FBQzs7OEdBclpVLGlCQUFpQjtrSEFBakIsaUJBQWlCOzJGQUFqQixpQkFBaUI7a0JBRDdCLFVBQVUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlLCBPbkRlc3Ryb3kgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7XG4gIGRlZmF1bHRRdWlja09yZGVyQ29uZmlnLFxuICBRdWlja09yZGVyQWRkRW50cnlFdmVudCxcbiAgUXVpY2tPcmRlckZhY2FkZSxcbn0gZnJvbSAnQHNwYXJ0YWN1cy9jYXJ0L3F1aWNrLW9yZGVyL3Jvb3QnO1xuaW1wb3J0IHtcbiAgQWN0aXZlQ2FydFNlcnZpY2UsXG4gIENhcnRBZGRFbnRyeUZhaWxFdmVudCxcbiAgQ2FydEFkZEVudHJ5U3VjY2Vzc0V2ZW50LFxuICBFdmVudFNlcnZpY2UsXG4gIEh0dHBFcnJvck1vZGVsLFxuICBPcmRlckVudHJ5LFxuICBQcm9kdWN0LFxuICBQcm9kdWN0QWRhcHRlcixcbiAgUHJvZHVjdFNlYXJjaENvbm5lY3RvcixcbiAgUHJvZHVjdFNlYXJjaFBhZ2UsXG4gIFNlYXJjaENvbmZpZyxcbn0gZnJvbSAnQHNwYXJ0YWN1cy9jb3JlJztcbmltcG9ydCB7XG4gIEJlaGF2aW9yU3ViamVjdCxcbiAgT2JzZXJ2YWJsZSxcbiAgb2YsXG4gIFN1YmplY3QsXG4gIFN1YnNjcmlwdGlvbixcbiAgdGltZXIsXG59IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgZmlsdGVyLCBmaXJzdCwgbWFwLCBzd2l0Y2hNYXAsIHRha2UsIHRhcCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcblxuQEluamVjdGFibGUoKVxuZXhwb3J0IGNsYXNzIFF1aWNrT3JkZXJTZXJ2aWNlIGltcGxlbWVudHMgUXVpY2tPcmRlckZhY2FkZSwgT25EZXN0cm95IHtcbiAgcHJvdGVjdGVkIHByb2R1Y3RBZGRlZCQ6IFN1YmplY3Q8c3RyaW5nPiA9IG5ldyBTdWJqZWN0PHN0cmluZz4oKTtcbiAgcHJvdGVjdGVkIGVudHJpZXMkOiBCZWhhdmlvclN1YmplY3Q8T3JkZXJFbnRyeVtdPiA9IG5ldyBCZWhhdmlvclN1YmplY3Q8XG4gICAgT3JkZXJFbnRyeVtdXG4gID4oW10pO1xuICBwcm90ZWN0ZWQgc29mdERlbGV0ZWRFbnRyaWVzJDogQmVoYXZpb3JTdWJqZWN0PFJlY29yZDxzdHJpbmcsIE9yZGVyRW50cnk+PiA9XG4gICAgbmV3IEJlaGF2aW9yU3ViamVjdDxSZWNvcmQ8c3RyaW5nLCBPcmRlckVudHJ5Pj4oe30pO1xuICBwcm90ZWN0ZWQgbm9uUHVyY2hhc2FibGVQcm9kdWN0RXJyb3IkOiBCZWhhdmlvclN1YmplY3Q8UHJvZHVjdCB8IG51bGw+ID1cbiAgICBuZXcgQmVoYXZpb3JTdWJqZWN0PFByb2R1Y3QgfCBudWxsPihudWxsKTtcbiAgcHJvdGVjdGVkIGhhcmREZWxldGVUaW1lb3V0ID0gNTAwMDtcbiAgcHJvdGVjdGVkIHF1aWNrT3JkZXJMaXN0TGltaXQgPSAwO1xuICBwcm90ZWN0ZWQgY2xlYXJEZWxldGVUaW1lb3V0czogUmVjb3JkPHN0cmluZywgU3Vic2NyaXB0aW9uPiA9IHt9O1xuXG4gIC8qKlxuICAgKiBAZGVwcmVjYXRlZCBzaW5jZSB2ZXJzaW9uIDQuMlxuICAgKiBVc2UgY29uc3RydWN0b3IoYWN0aXZlQ2FydFNlcnZpY2U6IEFjdGl2ZUNhcnRTZXJ2aWNlLCBwcm9kdWN0QWRhcHRlcjogUHJvZHVjdEFkYXB0ZXIsIGV2ZW50U2VydmljZTogRXZlbnRTZXJ2aWNlLCBwcm9kdWN0U2VhcmNoQ29ubmVjdG9yOiBQcm9kdWN0U2VhcmNoQ29ubmVjdG9yKTsgaW5zdGVhZFxuICAgKi9cbiAgLy8gVE9ETygjMTQwNTkpOiBSZW1vdmUgZGVwcmVjYXRlZCBjb25zdHJ1Y3RvclxuICBjb25zdHJ1Y3RvcihcbiAgICBhY3RpdmVDYXJ0U2VydmljZTogQWN0aXZlQ2FydFNlcnZpY2UsXG4gICAgcHJvZHVjdEFkYXB0ZXI6IFByb2R1Y3RBZGFwdGVyLFxuICAgIGV2ZW50U2VydmljZTogRXZlbnRTZXJ2aWNlXG4gICk7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJvdGVjdGVkIGFjdGl2ZUNhcnRTZXJ2aWNlOiBBY3RpdmVDYXJ0U2VydmljZSxcbiAgICBwcm90ZWN0ZWQgcHJvZHVjdEFkYXB0ZXI6IFByb2R1Y3RBZGFwdGVyLCAvLyBUT0RPKCMxNDA1OSk6IFJlbW92ZSB0aGlzIHNlcnZpY2VcbiAgICBwcm90ZWN0ZWQgZXZlbnRTZXJ2aWNlOiBFdmVudFNlcnZpY2UsXG4gICAgcHJvdGVjdGVkIHByb2R1Y3RTZWFyY2hDb25uZWN0b3I/OiBQcm9kdWN0U2VhcmNoQ29ubmVjdG9yIC8vVE9ETygjMTQwNTkpOiBNYWtlIGl0IHJlcXVpcmVkXG4gICkge31cblxuICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICB0aGlzLmNsZWFyRGVsZXRlZEVudHJpZXMoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgZW50cmllc1xuICAgKi9cbiAgZ2V0RW50cmllcygpOiBCZWhhdmlvclN1YmplY3Q8T3JkZXJFbnRyeVtdPiB7XG4gICAgcmV0dXJuIHRoaXMuZW50cmllcyQ7XG4gIH1cblxuICAvKipcbiAgICogQGRlcHJlY2F0ZWQgc2luY2UgNC4yIC0gdXNlIHNlYXJjaFByb2R1Y3RzIGluc3RlYWRcbiAgICogU2VhcmNoIHByb2R1Y3QgdXNpbmcgU0tVXG4gICAqL1xuICBzZWFyY2gocHJvZHVjdENvZGU6IHN0cmluZyk6IE9ic2VydmFibGU8UHJvZHVjdD4ge1xuICAgIHJldHVybiB0aGlzLnByb2R1Y3RBZGFwdGVyLmxvYWQocHJvZHVjdENvZGUpO1xuICB9XG5cbiAgLyoqXG4gICAqIFNlYXJjaCBwcm9kdWN0cyB1c2luZyBxdWVyeVxuICAgKi9cbiAgc2VhcmNoUHJvZHVjdHMocXVlcnk6IHN0cmluZywgbWF4UHJvZHVjdHM/OiBudW1iZXIpOiBPYnNlcnZhYmxlPFByb2R1Y3RbXT4ge1xuICAgIC8vIFRPRE8oIzE0MDU5KTogUmVtb3ZlIGNvbmRpdGlvblxuICAgIGlmICh0aGlzLnByb2R1Y3RTZWFyY2hDb25uZWN0b3IpIHtcbiAgICAgIGNvbnN0IHNlYXJjaENvbmZpZzogU2VhcmNoQ29uZmlnID0ge1xuICAgICAgICBwYWdlU2l6ZTpcbiAgICAgICAgICBtYXhQcm9kdWN0cyB8fFxuICAgICAgICAgIGRlZmF1bHRRdWlja09yZGVyQ29uZmlnLnF1aWNrT3JkZXI/LnNlYXJjaEZvcm0/Lm1heFByb2R1Y3RzLFxuICAgICAgfTtcbiAgICAgIHJldHVybiB0aGlzLnByb2R1Y3RTZWFyY2hDb25uZWN0b3JcbiAgICAgICAgLnNlYXJjaChxdWVyeSwgc2VhcmNoQ29uZmlnKVxuICAgICAgICAucGlwZShcbiAgICAgICAgICBtYXAoKHNlYXJjaFBhZ2U6IFByb2R1Y3RTZWFyY2hQYWdlKSA9PiBzZWFyY2hQYWdlLnByb2R1Y3RzIHx8IFtdKVxuICAgICAgICApO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gb2YoW10pO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBDbGVhciBhIGxpc3Qgb2YgYWRkZWQgZW50cmllc1xuICAgKi9cbiAgY2xlYXJMaXN0KCk6IHZvaWQge1xuICAgIHRoaXMuZW50cmllcyQubmV4dChbXSk7XG4gIH1cblxuICAvKipcbiAgICogR2V0IGluZm9ybWF0aW9uIGFib3V0IHRoZSBwb3NzaWJpbGl0eSB0byBhZGQgdGhlIG5leHQgcHJvZHVjdFxuICAgKi9cbiAgY2FuQWRkKGNvZGU/OiBzdHJpbmcpOiBPYnNlcnZhYmxlPGJvb2xlYW4+IHtcbiAgICBpZiAoY29kZSkge1xuICAgICAgcmV0dXJuIG9mKHRoaXMuaXNQcm9kdWN0T25UaGVMaXN0KGNvZGUpIHx8ICF0aGlzLmlzTGltaXRFeGNlZWRlZCgpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIG9mKCF0aGlzLmlzTGltaXRFeGNlZWRlZCgpKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogU2V0IHF1aWNrIG9yZGVyIGxpc3QgbGltaXQgcHJvcGVydHlcbiAgICovXG4gIHNldExpc3RMaW1pdChsaW1pdDogbnVtYmVyKTogdm9pZCB7XG4gICAgdGhpcy5xdWlja09yZGVyTGlzdExpbWl0ID0gbGltaXQ7XG4gIH1cblxuICAvKipcbiAgICogTG9hZCBhIGxpc3Qgb2YgZW50cmllc1xuICAgKi9cbiAgbG9hZEVudHJpZXMoZW50cmllczogT3JkZXJFbnRyeVtdID0gW10pOiB2b2lkIHtcbiAgICB0aGlzLmVudHJpZXMkLm5leHQoZW50cmllcyk7XG4gIH1cblxuICAvKipcbiAgICogTG9hZCBhIGxpc3Qgb2YgZW50cmllc1xuICAgKi9cbiAgdXBkYXRlRW50cnlRdWFudGl0eShlbnRyeUluZGV4OiBudW1iZXIsIHF1YW50aXR5OiBudW1iZXIpOiB2b2lkIHtcbiAgICBjb25zdCBlbnRyaWVzID0gdGhpcy5lbnRyaWVzJC5nZXRWYWx1ZSgpIHx8IFtdO1xuICAgIGVudHJpZXNbZW50cnlJbmRleF0ucXVhbnRpdHkgPSBxdWFudGl0eTtcblxuICAgIHRoaXMuZW50cmllcyQubmV4dChlbnRyaWVzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEZWxldGUgc2luZ2xlIGVudHJ5IGZyb20gdGhlIGxpc3RcbiAgICovXG4gIHNvZnREZWxldGVFbnRyeShpbmRleDogbnVtYmVyKTogdm9pZCB7XG4gICAgdGhpcy5lbnRyaWVzJC5waXBlKHRha2UoMSkpLnN1YnNjcmliZSgoZW50cmllczogT3JkZXJFbnRyeVtdKSA9PiB7XG4gICAgICBjb25zdCBlbnRyaWVzTGlzdCA9IGVudHJpZXM7XG4gICAgICB0aGlzLmFkZFNvZnRFbnRyeURlbGV0aW9uKGVudHJpZXNMaXN0W2luZGV4XSwgdHJ1ZSk7XG4gICAgICBlbnRyaWVzTGlzdC5zcGxpY2UoaW5kZXgsIDEpO1xuICAgICAgdGhpcy5lbnRyaWVzJC5uZXh0KGVudHJpZXNMaXN0KTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVwcmVjYXRlZCBzaW5jZSA0LjIgLSB1c2Ugc29mdERlbGV0ZUVudHJ5IGluc3RlYWRcbiAgICovXG4gIHJlbW92ZUVudHJ5KGluZGV4OiBudW1iZXIpOiB2b2lkIHtcbiAgICB0aGlzLnNvZnREZWxldGVFbnRyeShpbmRleCk7XG4gIH1cblxuICAvKipcbiAgICogQWRkIHByb2R1Y3QgdG8gdGhlIHF1aWNrIG9yZGVyIGxpc3RcbiAgICovXG4gIGFkZFByb2R1Y3QocHJvZHVjdDogUHJvZHVjdCwgcXVhbnRpdHk6IG51bWJlciA9IDEpOiB2b2lkIHtcbiAgICBjb25zdCBlbnRyeSA9IHRoaXMuZ2VuZXJhdGVPcmRlckVudHJ5KHByb2R1Y3QsIHF1YW50aXR5KTtcbiAgICB0aGlzLmFkZEVudHJ5KGVudHJ5KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm4gcHJvZHVjdCBhZGRlZCBzdWJqZWN0XG4gICAqL1xuICBnZXRQcm9kdWN0QWRkZWQoKTogU3ViamVjdDxzdHJpbmc+IHtcbiAgICByZXR1cm4gdGhpcy5wcm9kdWN0QWRkZWQkO1xuICB9XG5cbiAgLyoqXG4gICAqIFNldCBwcm9kdWN0IGFkZGVkIHN1YmplY3RcbiAgICovXG4gIHNldFByb2R1Y3RBZGRlZChwcm9kdWN0Q29kZTogc3RyaW5nKTogdm9pZCB7XG4gICAgdGhpcy5wcm9kdWN0QWRkZWQkLm5leHQocHJvZHVjdENvZGUpO1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZGluZyB0byBjYXJ0IGFsbCBwcm9kdWN0cyBmcm9tIHRoZSBsaXN0XG4gICAqL1xuICBhZGRUb0NhcnQoKTogT2JzZXJ2YWJsZTxbT3JkZXJFbnRyeVtdLCBRdWlja09yZGVyQWRkRW50cnlFdmVudFtdXT4ge1xuICAgIGxldCBlbnRyaWVzOiBPcmRlckVudHJ5W10gPSBbXTtcbiAgICBjb25zdCBldmVudHM6IFF1aWNrT3JkZXJBZGRFbnRyeUV2ZW50W10gPSBbXTtcbiAgICBjb25zdCBzdWJzY3JpcHRpb24gPSB0aGlzLmV2ZW50U2VydmljZVxuICAgICAgLmdldChDYXJ0QWRkRW50cnlTdWNjZXNzRXZlbnQpXG4gICAgICAuc3Vic2NyaWJlKChjYXJ0RXZlbnQ6IENhcnRBZGRFbnRyeVN1Y2Nlc3NFdmVudCkgPT4ge1xuICAgICAgICBpZiAoXG4gICAgICAgICAgY2FydEV2ZW50LnF1YW50aXR5QWRkZWQgPT09IDAgfHxcbiAgICAgICAgICAoISFjYXJ0RXZlbnQucXVhbnRpdHlBZGRlZCAmJlxuICAgICAgICAgICAgY2FydEV2ZW50LnF1YW50aXR5QWRkZWQgPCBjYXJ0RXZlbnQucXVhbnRpdHkpXG4gICAgICAgICkge1xuICAgICAgICAgIGV2ZW50cy5wdXNoKHRoaXMuY3JlYXRlUXVpY2tPcmRlclJlc3VsdEV2ZW50KGNhcnRFdmVudCkpO1xuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgIHN1YnNjcmlwdGlvbi5hZGQoXG4gICAgICB0aGlzLmV2ZW50U2VydmljZVxuICAgICAgICAuZ2V0KENhcnRBZGRFbnRyeUZhaWxFdmVudClcbiAgICAgICAgLnN1YnNjcmliZSgoY2FydEV2ZW50OiBDYXJ0QWRkRW50cnlGYWlsRXZlbnQpID0+IHtcbiAgICAgICAgICBldmVudHMucHVzaCh0aGlzLmNyZWF0ZVF1aWNrT3JkZXJSZXN1bHRFdmVudChjYXJ0RXZlbnQpKTtcbiAgICAgICAgfSlcbiAgICApO1xuXG4gICAgcmV0dXJuIHRoaXMuZ2V0RW50cmllcygpLnBpcGUoXG4gICAgICBmaXJzdCgpLFxuICAgICAgc3dpdGNoTWFwKChlbGVtZW50cykgPT4ge1xuICAgICAgICBlbnRyaWVzID0gZWxlbWVudHM7XG4gICAgICAgIHRoaXMuYWN0aXZlQ2FydFNlcnZpY2UuYWRkRW50cmllcyhlbGVtZW50cyk7XG4gICAgICAgIHRoaXMuY2xlYXJMaXN0KCk7XG5cbiAgICAgICAgcmV0dXJuIHRoaXMuYWN0aXZlQ2FydFNlcnZpY2UuaXNTdGFibGUoKTtcbiAgICAgIH0pLFxuICAgICAgZmlsdGVyKChpc1N0YWJsZSkgPT4gaXNTdGFibGUpLFxuICAgICAgbWFwKCgpID0+IFtlbnRyaWVzLCBldmVudHNdIGFzIFtPcmRlckVudHJ5W10sIFF1aWNrT3JkZXJBZGRFbnRyeUV2ZW50W11dKSxcbiAgICAgIHRhcCgoKSA9PiBzdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKSlcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybiBzb2Z0IGRlbGV0ZWQgZW50cmllc1xuICAgKi9cbiAgZ2V0U29mdERlbGV0ZWRFbnRyaWVzKCk6IE9ic2VydmFibGU8UmVjb3JkPHN0cmluZywgT3JkZXJFbnRyeT4+IHtcbiAgICByZXR1cm4gdGhpcy5zb2Z0RGVsZXRlZEVudHJpZXMkO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlc3RvcmUgc29mdCBkZWxldGVkIGVudHJ5XG4gICAqL1xuICByZXN0b3JlU29mdERlbGV0ZWRFbnRyeShwcm9kdWN0Q29kZTogc3RyaW5nKTogdm9pZCB7XG4gICAgY29uc3QgZW50cnkgPSB0aGlzLmdldFNvZnREZWxldGVkRW50cnkocHJvZHVjdENvZGUpO1xuXG4gICAgdGhpcy5hZGRFbnRyeShlbnRyeSk7XG4gICAgdGhpcy5oYXJkRGVsZXRlRW50cnkocHJvZHVjdENvZGUpO1xuICB9XG5cbiAgLyoqXG4gICAqIENsZWFyIGRlbGV0ZWQgZW50cnkgZnJvbSB0aGUgbGlzdFxuICAgKi9cbiAgaGFyZERlbGV0ZUVudHJ5KHByb2R1Y3RDb2RlOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBjb25zdCBlbnRyeSA9IHRoaXMuZ2V0U29mdERlbGV0ZWRFbnRyeShwcm9kdWN0Q29kZSk7XG4gICAgY29uc3QgZGVsZXRlZEVudHJpZXMgPSB0aGlzLnNvZnREZWxldGVkRW50cmllcyQuZ2V0VmFsdWUoKTtcblxuICAgIGlmIChlbnRyeSkge1xuICAgICAgZGVsZXRlIGRlbGV0ZWRFbnRyaWVzW3Byb2R1Y3RDb2RlXTtcbiAgICAgIHRoaXMuc29mdERlbGV0ZWRFbnRyaWVzJC5uZXh0KGRlbGV0ZWRFbnRyaWVzKTtcbiAgICB9XG5cbiAgICB0aGlzLmNsZWFyRGVsZXRlVGltZW91dChwcm9kdWN0Q29kZSk7XG4gIH1cblxuICAvKipcbiAgICogQ2xlYXIgYWxsIGRlbGV0ZWQgZW50cmllcyBhbmQgdGltZW91dCBzdWJzY3JpcHRpb25zXG4gICAqL1xuICBjbGVhckRlbGV0ZWRFbnRyaWVzKCk6IHZvaWQge1xuICAgIE9iamVjdC52YWx1ZXModGhpcy5jbGVhckRlbGV0ZVRpbWVvdXRzKS5mb3JFYWNoKFxuICAgICAgKHN1YnNjcmlwdGlvbjogU3Vic2NyaXB0aW9uKSA9PiBzdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKVxuICAgICk7XG5cbiAgICB0aGlzLnNvZnREZWxldGVkRW50cmllcyQubmV4dCh7fSk7XG4gICAgdGhpcy5jbGVhckRlbGV0ZVRpbWVvdXRzID0ge307XG4gIH1cblxuICAvKipcbiAgICogIFJldHVybiBub24gcHVyY2hhc2FibGUgcHJvZHVjdCBlcnJvclxuICAgKi9cbiAgZ2V0Tm9uUHVyY2hhc2FibGVQcm9kdWN0RXJyb3IoKTogT2JzZXJ2YWJsZTxQcm9kdWN0IHwgbnVsbD4ge1xuICAgIHJldHVybiB0aGlzLm5vblB1cmNoYXNhYmxlUHJvZHVjdEVycm9yJDtcbiAgfVxuXG4gIC8qKlxuICAgKiBTZXQgZXJyb3IgdGhhdCBzZWxlY3RlZCBwcm9kdWN0IGlzIG5vdCBwdXJjaGFzYWJsZVxuICAgKi9cbiAgc2V0Tm9uUHVyY2hhc2FibGVQcm9kdWN0RXJyb3IocHJvZHVjdDogUHJvZHVjdCk6IHZvaWQge1xuICAgIHRoaXMubm9uUHVyY2hhc2FibGVQcm9kdWN0RXJyb3IkLm5leHQocHJvZHVjdCk7XG4gIH1cblxuICAvKipcbiAgICogQ2xlYXIgbm90IHB1cmNoYXNhYmxlIHByb2R1Y3QgZXJyb3JcbiAgICovXG4gIGNsZWFyTm9uUHVyY2hhc2FibGVQcm9kdWN0RXJyb3IoKTogdm9pZCB7XG4gICAgdGhpcy5ub25QdXJjaGFzYWJsZVByb2R1Y3RFcnJvciQubmV4dChudWxsKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBZGQgc29mdCBkZWxldGVkIGVudHJ5IHRvIHRoZSBjYWNoZWQgbGlzdFxuICAgKi9cbiAgcHJvdGVjdGVkIGFkZFNvZnRFbnRyeURlbGV0aW9uKFxuICAgIGVudHJ5OiBPcmRlckVudHJ5LFxuICAgIGNsZWFyVGltZW91dDogYm9vbGVhbiA9IHRydWVcbiAgKTogdm9pZCB7XG4gICAgY29uc3QgZGVsZXRlZEVudHJpZXMgPSB0aGlzLnNvZnREZWxldGVkRW50cmllcyQuZ2V0VmFsdWUoKTtcbiAgICBjb25zdCBwcm9kdWN0Q29kZSA9IGVudHJ5Py5wcm9kdWN0Py5jb2RlO1xuXG4gICAgaWYgKHByb2R1Y3RDb2RlKSB7XG4gICAgICBkZWxldGVkRW50cmllc1twcm9kdWN0Q29kZV0gPSBlbnRyeTtcblxuICAgICAgdGhpcy5zb2Z0RGVsZXRlZEVudHJpZXMkLm5leHQoZGVsZXRlZEVudHJpZXMpO1xuXG4gICAgICBpZiAoY2xlYXJUaW1lb3V0KSB7XG4gICAgICAgIGNvbnN0IHN1YnNjcmlwdGlvbjogU3Vic2NyaXB0aW9uID0gdGltZXIoXG4gICAgICAgICAgdGhpcy5oYXJkRGVsZXRlVGltZW91dFxuICAgICAgICApLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgICAgdGhpcy5oYXJkRGVsZXRlRW50cnkocHJvZHVjdENvZGUpO1xuICAgICAgICB9KTtcblxuICAgICAgICB0aGlzLmNsZWFyRGVsZXRlVGltZW91dHNbcHJvZHVjdENvZGVdID0gc3Vic2NyaXB0aW9uO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgc29mdCBkZWxldGlvbiBlbnRyeVxuICAgKi9cbiAgcHJvdGVjdGVkIGdldFNvZnREZWxldGVkRW50cnkocHJvZHVjdENvZGU6IHN0cmluZyk6IE9yZGVyRW50cnkge1xuICAgIGNvbnN0IGRlbGV0ZWRFbnRyaWVzID0gdGhpcy5zb2Z0RGVsZXRlZEVudHJpZXMkLmdldFZhbHVlKCk7XG5cbiAgICByZXR1cm4gZGVsZXRlZEVudHJpZXNbcHJvZHVjdENvZGVdO1xuICB9XG5cbiAgLyoqXG4gICAqIEdlbmVyYXRlIE9yZGVyIEVudHJ5IGZyb20gUHJvZHVjdFxuICAgKi9cbiAgcHJvdGVjdGVkIGdlbmVyYXRlT3JkZXJFbnRyeShcbiAgICBwcm9kdWN0OiBQcm9kdWN0LFxuICAgIHF1YW50aXR5PzogbnVtYmVyXG4gICk6IE9yZGVyRW50cnkge1xuICAgIHJldHVybiB7XG4gICAgICBiYXNlUHJpY2U6IHByb2R1Y3QucHJpY2UsXG4gICAgICBwcm9kdWN0LFxuICAgICAgcXVhbnRpdHksXG4gICAgICB0b3RhbFByaWNlOiBwcm9kdWN0LnByaWNlLFxuICAgIH0gYXMgT3JkZXJFbnRyeTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBZGQgc2luZ2xlIGVudHJ5IHRvIHRoZSBsaXN0XG4gICAqL1xuICBwcm90ZWN0ZWQgYWRkRW50cnkoZW50cnk6IE9yZGVyRW50cnkpOiB2b2lkIHtcbiAgICBpZiAoXG4gICAgICBlbnRyeT8ucHJvZHVjdD8uY29kZSAmJlxuICAgICAgIXRoaXMuaXNQcm9kdWN0T25UaGVMaXN0KGVudHJ5LnByb2R1Y3QuY29kZSkgJiZcbiAgICAgIHRoaXMuaXNMaW1pdEV4Y2VlZGVkKClcbiAgICApIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBlbnRyaWVzID0gdGhpcy5lbnRyaWVzJC5nZXRWYWx1ZSgpIHx8IFtdO1xuICAgIGNvbnN0IGVudHJ5U3RvY2tMZXZlbCA9IGVudHJ5LnByb2R1Y3Q/LnN0b2NrPy5zdG9ja0xldmVsO1xuXG4gICAgaWYgKGVudHJ5U3RvY2tMZXZlbCAmJiBlbnRyeS5xdWFudGl0eSAmJiBlbnRyeS5xdWFudGl0eSA+IGVudHJ5U3RvY2tMZXZlbCkge1xuICAgICAgZW50cnkucXVhbnRpdHkgPSBlbnRyeVN0b2NrTGV2ZWw7XG4gICAgfVxuXG4gICAgaWYgKGVudHJ5LnByb2R1Y3Q/LmNvZGUgJiYgdGhpcy5pc1Byb2R1Y3RPblRoZUxpc3QoZW50cnkucHJvZHVjdC5jb2RlKSkge1xuICAgICAgY29uc3QgZW50cnlJbmRleCA9IGVudHJpZXMuZmluZEluZGV4KFxuICAgICAgICAoaXRlbTogT3JkZXJFbnRyeSkgPT4gaXRlbS5wcm9kdWN0Py5jb2RlID09PSBlbnRyeS5wcm9kdWN0Py5jb2RlXG4gICAgICApO1xuICAgICAgbGV0IHF1YW50aXR5ID0gZW50cmllc1tlbnRyeUluZGV4XS5xdWFudGl0eTtcblxuICAgICAgaWYgKHF1YW50aXR5ICYmIGVudHJ5LnF1YW50aXR5KSB7XG4gICAgICAgIGVudHJpZXNbZW50cnlJbmRleF0ucXVhbnRpdHkgPSBxdWFudGl0eSArIGVudHJ5Py5xdWFudGl0eTtcbiAgICAgICAgbGV0IG5ld1F1YW50aXR5ID0gZW50cmllc1tlbnRyeUluZGV4XS5xdWFudGl0eTtcblxuICAgICAgICBpZiAobmV3UXVhbnRpdHkgJiYgZW50cnlTdG9ja0xldmVsICYmIG5ld1F1YW50aXR5ID4gZW50cnlTdG9ja0xldmVsKSB7XG4gICAgICAgICAgZW50cmllc1tlbnRyeUluZGV4XS5xdWFudGl0eSA9IGVudHJ5U3RvY2tMZXZlbDtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuZW50cmllcyQubmV4dChbLi4uZW50cmllc10pO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmVudHJpZXMkLm5leHQoWy4uLmVudHJpZXMsIC4uLltlbnRyeV1dKTtcbiAgICB9XG5cbiAgICB0aGlzLnByb2R1Y3RBZGRlZCQubmV4dChlbnRyeS5wcm9kdWN0Py5jb2RlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBWZXJpZnkgaWYgcHJvZHVjdCBpcyBhbHJlYWR5IG9uIHRoZSBsaXN0XG4gICAqL1xuICBwcm90ZWN0ZWQgaXNQcm9kdWN0T25UaGVMaXN0KHByb2R1Y3RDb2RlOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICBjb25zdCBlbnRyaWVzID0gdGhpcy5lbnRyaWVzJC5nZXRWYWx1ZSgpIHx8IFtdO1xuXG4gICAgcmV0dXJuICEhZW50cmllcy5maW5kKFxuICAgICAgKGl0ZW06IE9yZGVyRW50cnkpID0+IGl0ZW0ucHJvZHVjdD8uY29kZSA9PT0gcHJvZHVjdENvZGVcbiAgICApO1xuICB9XG5cbiAgcHJvdGVjdGVkIGlzTGltaXRFeGNlZWRlZCgpOiBib29sZWFuIHtcbiAgICBjb25zdCBlbnRyaWVzID0gdGhpcy5lbnRyaWVzJC5nZXRWYWx1ZSgpIHx8IFtdO1xuXG4gICAgcmV0dXJuIGVudHJpZXMubGVuZ3RoID49IHRoaXMucXVpY2tPcmRlckxpc3RMaW1pdDtcbiAgfVxuXG4gIHByaXZhdGUgY3JlYXRlUXVpY2tPcmRlclJlc3VsdEV2ZW50KFxuICAgIGNhcnRFdmVudDogQ2FydEFkZEVudHJ5U3VjY2Vzc0V2ZW50IHwgQ2FydEFkZEVudHJ5RmFpbEV2ZW50XG4gICk6IFF1aWNrT3JkZXJBZGRFbnRyeUV2ZW50IHtcbiAgICBjb25zdCBldnQ6IFF1aWNrT3JkZXJBZGRFbnRyeUV2ZW50ID0ge1xuICAgICAgcHJvZHVjdENvZGU6IGNhcnRFdmVudC5wcm9kdWN0Q29kZSxcbiAgICAgIHF1YW50aXR5OiBjYXJ0RXZlbnQucXVhbnRpdHksXG4gICAgfTtcblxuICAgIGlmICgnZW50cnknIGluIGNhcnRFdmVudCkge1xuICAgICAgZXZ0LmVudHJ5ID0gY2FydEV2ZW50LmVudHJ5O1xuICAgIH1cbiAgICBpZiAoJ3F1YW50aXR5QWRkZWQnIGluIGNhcnRFdmVudCkge1xuICAgICAgZXZ0LnF1YW50aXR5QWRkZWQgPSBjYXJ0RXZlbnQucXVhbnRpdHlBZGRlZDtcbiAgICB9XG4gICAgaWYgKCdlcnJvcicgaW4gY2FydEV2ZW50ICYmIGNhcnRFdmVudC5lcnJvciBpbnN0YW5jZW9mIEh0dHBFcnJvck1vZGVsKSB7XG4gICAgICBldnQuZXJyb3IgPSBjYXJ0RXZlbnQuZXJyb3I7XG4gICAgfVxuXG4gICAgaWYgKGV2dC5lcnJvcj8uZGV0YWlscz8ubGVuZ3RoKSB7XG4gICAgICBjb25zdCBpc091dE9mU3RvY2sgPSBldnQuZXJyb3I/LmRldGFpbHMuc29tZShcbiAgICAgICAgKGUpID0+IGUudHlwZSA9PT0gJ0luc3VmZmljaWVudFN0b2NrRXJyb3InXG4gICAgICApO1xuICAgICAgZXZ0LnF1YW50aXR5QWRkZWQgPSBpc091dE9mU3RvY2sgPyAwIDogZXZ0LnF1YW50aXR5O1xuICAgIH1cblxuICAgIHJldHVybiBldnQ7XG4gIH1cblxuICBwcm90ZWN0ZWQgY2xlYXJEZWxldGVUaW1lb3V0KHByb2R1Y3RDb2RlOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBjb25zdCBjbGVhck1lc3NhZ2VUaW1vdXQgPSB0aGlzLmNsZWFyRGVsZXRlVGltZW91dHNbcHJvZHVjdENvZGVdO1xuXG4gICAgaWYgKGNsZWFyTWVzc2FnZVRpbW91dCkge1xuICAgICAgY2xlYXJNZXNzYWdlVGltb3V0LnVuc3Vic2NyaWJlKCk7XG4gICAgICBkZWxldGUgdGhpcy5jbGVhckRlbGV0ZVRpbWVvdXRzW3Byb2R1Y3RDb2RlXTtcbiAgICB9XG4gIH1cbn1cbiJdfQ==