@eui/core 17.0.0-rc.7 → 17.0.0-rc.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -24,7 +24,7 @@ export class EuiDynamicMenuService {
24
24
  }
25
25
  filterEuiMenuItemsWithRights(links) {
26
26
  return links.filter((link) => {
27
- if (link.hasChildren) {
27
+ if (link.children != null) {
28
28
  link.children = this.filterEuiMenuItemsWithRights(link.children);
29
29
  }
30
30
  // First check if the user is denied access:
@@ -66,4 +66,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.2", ngImpor
66
66
  providedIn: 'root',
67
67
  }]
68
68
  }], ctorParameters: () => [{ type: i1.EuiPermissionService }, { type: i2.StoreService }] });
69
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZHluYW1pYy1tZW51LnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9zcmMvbGliL3NlcnZpY2VzL2R5bmFtaWMtbWVudS9keW5hbWljLW1lbnUuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzNDLE9BQU8sRUFBRSxZQUFZLEVBQWUsTUFBTSxXQUFXLENBQUM7Ozs7QUFPdEQsOEZBQThGO0FBQzlGLG1IQUFtSDtBQUNuSCw4REFBOEQ7QUFDOUQsTUFBTSxPQUFPLHFCQUFxQjtJQUc5Qiw4REFBOEQ7SUFDOUQsc0ZBQXNGO0lBQ3RGLFlBQ1ksYUFBbUMsRUFDbkMsS0FBbUI7UUFEbkIsa0JBQWEsR0FBYixhQUFhLENBQXNCO1FBQ25DLFVBQUssR0FBTCxLQUFLLENBQWM7UUFOL0IsY0FBUyxHQUFnQixFQUFFLENBQUM7UUFReEIsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsWUFBWSxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUU7WUFDL0MsSUFBSSxJQUFJLENBQUMsU0FBUyxFQUFFO2dCQUNoQixJQUFJLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUM7YUFDbkM7UUFDTCxDQUFDLENBQUMsQ0FBQztJQUNQLENBQUM7SUFFRCxZQUFZO1FBQ1IsT0FBTyxJQUFJLENBQUMsU0FBUyxDQUFDO0lBQzFCLENBQUM7SUFFRCw0QkFBNEIsQ0FBQyxLQUF5QjtRQUNsRCxPQUFPLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRTtZQUN6QixJQUFJLElBQUksQ0FBQyxXQUFXLEVBQUU7Z0JBQ2xCLElBQUksQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDLDRCQUE0QixDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQzthQUNwRTtZQUVELDRDQUE0QztZQUM1QyxJQUFJLElBQUksQ0FBQyxhQUFhLEVBQUU7Z0JBQ3BCLElBQUksSUFBSSxDQUFDLGFBQWEsQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxFQUFFO29CQUNuRCxPQUFPLEtBQUssQ0FBQztpQkFDaEI7YUFDSjtZQUNELElBQUksSUFBSSxDQUFDLGNBQWMsRUFBRTtnQkFDckIsS0FBSyxNQUFNLGFBQWEsSUFBSSxJQUFJLENBQUMsY0FBYyxFQUFFO29CQUM3QyxJQUFJLElBQUksQ0FBQyxhQUFhLENBQUMsVUFBVSxDQUFDLGFBQWEsQ0FBQyxFQUFFO3dCQUM5QyxPQUFPLEtBQUssQ0FBQztxQkFDaEI7aUJBQ0o7YUFDSjtZQUVELGdFQUFnRTtZQUNoRSxJQUFJLElBQUksQ0FBQyxjQUFjLEVBQUU7Z0JBQ3JCLE9BQU8sSUFBSSxDQUFDLGFBQWEsQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxDQUFDO2FBQzdEO1lBQ0QsSUFBSSxJQUFJLENBQUMsZUFBZSxFQUFFO2dCQUN0QixLQUFLLE1BQU0sY0FBYyxJQUFJLElBQUksQ0FBQyxlQUFlLEVBQUU7b0JBQy9DLElBQUksSUFBSSxDQUFDLGFBQWEsQ0FBQyxVQUFVLENBQUMsY0FBYyxDQUFDLEVBQUU7d0JBQy9DLE9BQU8sSUFBSSxDQUFDO3FCQUNmO2lCQUNKO2dCQUNELDREQUE0RDtnQkFDNUQsT0FBTyxLQUFLLENBQUM7YUFDaEI7WUFFRCw2REFBNkQ7WUFDN0QsT0FBTyxJQUFJLENBQUM7UUFDaEIsQ0FBQyxDQUFDLENBQUM7SUFDUCxDQUFDO2lJQXpEUSxxQkFBcUI7cUlBQXJCLHFCQUFxQixjQUxsQixNQUFNOzsyRkFLVCxxQkFBcUI7a0JBTmpDLFVBQVU7bUJBQUM7b0JBQ1IsVUFBVSxFQUFFLE1BQU07aUJBQ3JCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgZ2V0VXNlclN0YXRlLCBFdWlNZW51SXRlbSB9IGZyb20gJ0BldWkvYmFzZSc7XG5pbXBvcnQgeyBFdWlQZXJtaXNzaW9uU2VydmljZSB9IGZyb20gJy4uL3Blcm1pc3Npb24vcGVybWlzc2lvbi5zZXJ2aWNlJztcbmltcG9ydCB7IFN0b3JlU2VydmljZSB9IGZyb20gJy4uL3N0b3JlJztcblxuQEluamVjdGFibGUoe1xuICAgIHByb3ZpZGVkSW46ICdyb290Jyxcbn0pXG4vLyBUT0RPOiBUeXBlIG9mIExJTksgc2hvdWxkIGJlIFV4TGluayBvciBzb21ldGhpbmcgcmVsZXZhbnQuIERvIHdlIG5lZWQgdGhhdCBzZXJ2aWNlIGFueW1vcmU/XG4vLyBUT0RPOiBmaW5kIHRoZSBjb3JyZWN0IHR5cGUgb3IgdHVybiBpbnRvIGEgZ2VuZXJpYywgaHR0cHM6Ly93d3cudHlwZXNjcmlwdGxhbmcub3JnL2RvY3MvaGFuZGJvb2svMi9nZW5lcmljcy5odG1sXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueVxuZXhwb3J0IGNsYXNzIEV1aUR5bmFtaWNNZW51U2VydmljZTxMSU5LID0gYW55PiB7XG4gICAgbWVudUxpbmtzOiBBcnJheTxMSU5LPiA9IFtdO1xuXG4gICAgLy8gVE9ETzogaXQgc2hvdWxkIGJlIG1vdmVkIGV1aXNlcnZpY2UsIG9yIGl0IHNob3VsZCBiZSBzdGF0aWNcbiAgICAvLyBUT0RPOiBjYW4gd2UgbW92ZWQgdGhhdCBzZXJ2aWNlIGluc2lkZSB0aGUgbW9kdWxlIG9mIHRoZSBjb21wb25lbnQgdGhhdCdzIHVzaW5nIGl0P1xuICAgIGNvbnN0cnVjdG9yKFxuICAgICAgICBwcml2YXRlIGV1aVBlcm1pc3Npb246IEV1aVBlcm1pc3Npb25TZXJ2aWNlLFxuICAgICAgICBwcml2YXRlIHN0b3JlOiBTdG9yZVNlcnZpY2UsXG4gICAgKSB7XG4gICAgICAgIHRoaXMuc3RvcmUuc2VsZWN0KGdldFVzZXJTdGF0ZSkuc3Vic2NyaWJlKCh1c2VyKSA9PiB7XG4gICAgICAgICAgICBpZiAodXNlci5tZW51TGlua3MpIHtcbiAgICAgICAgICAgICAgICB0aGlzLm1lbnVMaW5rcyA9IHVzZXIubWVudUxpbmtzO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBnZXRNZW51TGlua3MoKTogTElOS1tdIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubWVudUxpbmtzO1xuICAgIH1cblxuICAgIGZpbHRlckV1aU1lbnVJdGVtc1dpdGhSaWdodHMobGlua3M6IEFycmF5PEV1aU1lbnVJdGVtPik6IEFycmF5PEV1aU1lbnVJdGVtPiB7XG4gICAgICAgIHJldHVybiBsaW5rcy5maWx0ZXIoKGxpbmspID0+IHtcbiAgICAgICAgICAgIGlmIChsaW5rLmhhc0NoaWxkcmVuKSB7XG4gICAgICAgICAgICAgICAgbGluay5jaGlsZHJlbiA9IHRoaXMuZmlsdGVyRXVpTWVudUl0ZW1zV2l0aFJpZ2h0cyhsaW5rLmNoaWxkcmVuKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gRmlyc3QgY2hlY2sgaWYgdGhlIHVzZXIgaXMgZGVuaWVkIGFjY2VzczpcbiAgICAgICAgICAgIGlmIChsaW5rLmRlbmllZFJpZ2h0SWQpIHtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5ldWlQZXJtaXNzaW9uLmNoZWNrUmlnaHQobGluay5kZW5pZWRSaWdodElkKSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGxpbmsuZGVuaWVkUmlnaHRJZHMpIHtcbiAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IGRlbmllZFJpZ2h0SWQgb2YgbGluay5kZW5pZWRSaWdodElkcykge1xuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5ldWlQZXJtaXNzaW9uLmNoZWNrUmlnaHQoZGVuaWVkUmlnaHRJZCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gVGhlbiBjaGVjayBpZiB0aGUgdXNlciBuZWVkcyB0byBiZSBhbGxvd2VkIGFjY2VzcyBleHBsaWNpdGx5OlxuICAgICAgICAgICAgaWYgKGxpbmsuYWxsb3dlZFJpZ2h0SWQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5ldWlQZXJtaXNzaW9uLmNoZWNrUmlnaHQobGluay5hbGxvd2VkUmlnaHRJZCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAobGluay5hbGxvd2VkUmlnaHRJZHMpIHtcbiAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IGFsbG93ZWRSaWdodElkIG9mIGxpbmsuYWxsb3dlZFJpZ2h0SWRzKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLmV1aVBlcm1pc3Npb24uY2hlY2tSaWdodChhbGxvd2VkUmlnaHRJZCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIC8vIFVzZXIgZG9lc24ndCBoYXZlIG9uZSBvZiB0aGUgYWxsb3dlZCByaWdodHMuIERlbnkgYWNjZXNzOlxuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gQWNjZXNzIHRvIHRoZSBtZW51IGl0ZW0gaXMgbm90IGRlbmllZCwgdGhlcmVmb3JlIGFsbG93IGl0OlxuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH0pO1xuICAgIH1cbn1cbiJdfQ==
69
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZHluYW1pYy1tZW51LnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9zcmMvbGliL3NlcnZpY2VzL2R5bmFtaWMtbWVudS9keW5hbWljLW1lbnUuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzNDLE9BQU8sRUFBRSxZQUFZLEVBQWUsTUFBTSxXQUFXLENBQUM7Ozs7QUFPdEQsOEZBQThGO0FBQzlGLG1IQUFtSDtBQUNuSCw4REFBOEQ7QUFDOUQsTUFBTSxPQUFPLHFCQUFxQjtJQUc5Qiw4REFBOEQ7SUFDOUQsc0ZBQXNGO0lBQ3RGLFlBQ1ksYUFBbUMsRUFDbkMsS0FBbUI7UUFEbkIsa0JBQWEsR0FBYixhQUFhLENBQXNCO1FBQ25DLFVBQUssR0FBTCxLQUFLLENBQWM7UUFOL0IsY0FBUyxHQUFnQixFQUFFLENBQUM7UUFReEIsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsWUFBWSxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUU7WUFDL0MsSUFBSSxJQUFJLENBQUMsU0FBUyxFQUFFO2dCQUNoQixJQUFJLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUM7YUFDbkM7UUFDTCxDQUFDLENBQUMsQ0FBQztJQUNQLENBQUM7SUFFRCxZQUFZO1FBQ1IsT0FBTyxJQUFJLENBQUMsU0FBUyxDQUFDO0lBQzFCLENBQUM7SUFFRCw0QkFBNEIsQ0FBQyxLQUF5QjtRQUNsRCxPQUFPLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRTtZQUN6QixJQUFJLElBQUksQ0FBQyxRQUFRLElBQUksSUFBSSxFQUFFO2dCQUN2QixJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyw0QkFBNEIsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7YUFDcEU7WUFFRCw0Q0FBNEM7WUFDNUMsSUFBSSxJQUFJLENBQUMsYUFBYSxFQUFFO2dCQUNwQixJQUFJLElBQUksQ0FBQyxhQUFhLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsRUFBRTtvQkFDbkQsT0FBTyxLQUFLLENBQUM7aUJBQ2hCO2FBQ0o7WUFDRCxJQUFJLElBQUksQ0FBQyxjQUFjLEVBQUU7Z0JBQ3JCLEtBQUssTUFBTSxhQUFhLElBQUksSUFBSSxDQUFDLGNBQWMsRUFBRTtvQkFDN0MsSUFBSSxJQUFJLENBQUMsYUFBYSxDQUFDLFVBQVUsQ0FBQyxhQUFhLENBQUMsRUFBRTt3QkFDOUMsT0FBTyxLQUFLLENBQUM7cUJBQ2hCO2lCQUNKO2FBQ0o7WUFFRCxnRUFBZ0U7WUFDaEUsSUFBSSxJQUFJLENBQUMsY0FBYyxFQUFFO2dCQUNyQixPQUFPLElBQUksQ0FBQyxhQUFhLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsQ0FBQzthQUM3RDtZQUNELElBQUksSUFBSSxDQUFDLGVBQWUsRUFBRTtnQkFDdEIsS0FBSyxNQUFNLGNBQWMsSUFBSSxJQUFJLENBQUMsZUFBZSxFQUFFO29CQUMvQyxJQUFJLElBQUksQ0FBQyxhQUFhLENBQUMsVUFBVSxDQUFDLGNBQWMsQ0FBQyxFQUFFO3dCQUMvQyxPQUFPLElBQUksQ0FBQztxQkFDZjtpQkFDSjtnQkFDRCw0REFBNEQ7Z0JBQzVELE9BQU8sS0FBSyxDQUFDO2FBQ2hCO1lBRUQsNkRBQTZEO1lBQzdELE9BQU8sSUFBSSxDQUFDO1FBQ2hCLENBQUMsQ0FBQyxDQUFDO0lBQ1AsQ0FBQztpSUF6RFEscUJBQXFCO3FJQUFyQixxQkFBcUIsY0FMbEIsTUFBTTs7MkZBS1QscUJBQXFCO2tCQU5qQyxVQUFVO21CQUFDO29CQUNSLFVBQVUsRUFBRSxNQUFNO2lCQUNyQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IGdldFVzZXJTdGF0ZSwgRXVpTWVudUl0ZW0gfSBmcm9tICdAZXVpL2Jhc2UnO1xuaW1wb3J0IHsgRXVpUGVybWlzc2lvblNlcnZpY2UgfSBmcm9tICcuLi9wZXJtaXNzaW9uL3Blcm1pc3Npb24uc2VydmljZSc7XG5pbXBvcnQgeyBTdG9yZVNlcnZpY2UgfSBmcm9tICcuLi9zdG9yZSc7XG5cbkBJbmplY3RhYmxlKHtcbiAgICBwcm92aWRlZEluOiAncm9vdCcsXG59KVxuLy8gVE9ETzogVHlwZSBvZiBMSU5LIHNob3VsZCBiZSBVeExpbmsgb3Igc29tZXRoaW5nIHJlbGV2YW50LiBEbyB3ZSBuZWVkIHRoYXQgc2VydmljZSBhbnltb3JlP1xuLy8gVE9ETzogZmluZCB0aGUgY29ycmVjdCB0eXBlIG9yIHR1cm4gaW50byBhIGdlbmVyaWMsIGh0dHBzOi8vd3d3LnR5cGVzY3JpcHRsYW5nLm9yZy9kb2NzL2hhbmRib29rLzIvZ2VuZXJpY3MuaHRtbFxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcbmV4cG9ydCBjbGFzcyBFdWlEeW5hbWljTWVudVNlcnZpY2U8TElOSyA9IGFueT4ge1xuICAgIG1lbnVMaW5rczogQXJyYXk8TElOSz4gPSBbXTtcblxuICAgIC8vIFRPRE86IGl0IHNob3VsZCBiZSBtb3ZlZCBldWlzZXJ2aWNlLCBvciBpdCBzaG91bGQgYmUgc3RhdGljXG4gICAgLy8gVE9ETzogY2FuIHdlIG1vdmVkIHRoYXQgc2VydmljZSBpbnNpZGUgdGhlIG1vZHVsZSBvZiB0aGUgY29tcG9uZW50IHRoYXQncyB1c2luZyBpdD9cbiAgICBjb25zdHJ1Y3RvcihcbiAgICAgICAgcHJpdmF0ZSBldWlQZXJtaXNzaW9uOiBFdWlQZXJtaXNzaW9uU2VydmljZSxcbiAgICAgICAgcHJpdmF0ZSBzdG9yZTogU3RvcmVTZXJ2aWNlLFxuICAgICkge1xuICAgICAgICB0aGlzLnN0b3JlLnNlbGVjdChnZXRVc2VyU3RhdGUpLnN1YnNjcmliZSgodXNlcikgPT4ge1xuICAgICAgICAgICAgaWYgKHVzZXIubWVudUxpbmtzKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5tZW51TGlua3MgPSB1c2VyLm1lbnVMaW5rcztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgZ2V0TWVudUxpbmtzKCk6IExJTktbXSB7XG4gICAgICAgIHJldHVybiB0aGlzLm1lbnVMaW5rcztcbiAgICB9XG5cbiAgICBmaWx0ZXJFdWlNZW51SXRlbXNXaXRoUmlnaHRzKGxpbmtzOiBBcnJheTxFdWlNZW51SXRlbT4pOiBBcnJheTxFdWlNZW51SXRlbT4ge1xuICAgICAgICByZXR1cm4gbGlua3MuZmlsdGVyKChsaW5rKSA9PiB7XG4gICAgICAgICAgICBpZiAobGluay5jaGlsZHJlbiAhPSBudWxsKSB7XG4gICAgICAgICAgICAgICAgbGluay5jaGlsZHJlbiA9IHRoaXMuZmlsdGVyRXVpTWVudUl0ZW1zV2l0aFJpZ2h0cyhsaW5rLmNoaWxkcmVuKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gRmlyc3QgY2hlY2sgaWYgdGhlIHVzZXIgaXMgZGVuaWVkIGFjY2VzczpcbiAgICAgICAgICAgIGlmIChsaW5rLmRlbmllZFJpZ2h0SWQpIHtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5ldWlQZXJtaXNzaW9uLmNoZWNrUmlnaHQobGluay5kZW5pZWRSaWdodElkKSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGxpbmsuZGVuaWVkUmlnaHRJZHMpIHtcbiAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IGRlbmllZFJpZ2h0SWQgb2YgbGluay5kZW5pZWRSaWdodElkcykge1xuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5ldWlQZXJtaXNzaW9uLmNoZWNrUmlnaHQoZGVuaWVkUmlnaHRJZCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gVGhlbiBjaGVjayBpZiB0aGUgdXNlciBuZWVkcyB0byBiZSBhbGxvd2VkIGFjY2VzcyBleHBsaWNpdGx5OlxuICAgICAgICAgICAgaWYgKGxpbmsuYWxsb3dlZFJpZ2h0SWQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5ldWlQZXJtaXNzaW9uLmNoZWNrUmlnaHQobGluay5hbGxvd2VkUmlnaHRJZCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAobGluay5hbGxvd2VkUmlnaHRJZHMpIHtcbiAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IGFsbG93ZWRSaWdodElkIG9mIGxpbmsuYWxsb3dlZFJpZ2h0SWRzKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLmV1aVBlcm1pc3Npb24uY2hlY2tSaWdodChhbGxvd2VkUmlnaHRJZCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIC8vIFVzZXIgZG9lc24ndCBoYXZlIG9uZSBvZiB0aGUgYWxsb3dlZCByaWdodHMuIERlbnkgYWNjZXNzOlxuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gQWNjZXNzIHRvIHRoZSBtZW51IGl0ZW0gaXMgbm90IGRlbmllZCwgdGhlcmVmb3JlIGFsbG93IGl0OlxuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH0pO1xuICAgIH1cbn1cbiJdfQ==
@@ -1,5 +1,5 @@
1
1
  import { Injectable, Optional } from '@angular/core';
2
- import { of, forkJoin } from 'rxjs';
2
+ import { of, forkJoin, from } from 'rxjs';
3
3
  import { tap, switchMap, take, map, catchError, concatMap } from 'rxjs/operators';
4
4
  import { getApiQueue, getApiQueueItem } from '@eui/base';
5
5
  import { AddApiQueueItemAction, RemoveApiQueueItemAction, EmptyApiQueueAction } from '../store';
@@ -7,6 +7,40 @@ import * as i0 from "@angular/core";
7
7
  import * as i1 from "../store";
8
8
  import * as i2 from "@angular/common/http";
9
9
  import * as i3 from "../log";
10
+ /**
11
+ * Service class for managing and processing a queue of API requests.
12
+ *
13
+ * This service provides functionality to add, remove, process, and manage HTTP requests stored in a queue.
14
+ * It enables sequential or bulk processing of requests, ensuring controlled execution and handling of API calls.
15
+ * The service methods offer features like processing individual items, processing all items in the queue either
16
+ * sequentially or all at once, and removing items from the queue. Each method is designed to handle specific aspects
17
+ * of queue management and processing, with attention to details like order of execution and error handling.
18
+ *
19
+ * Usage of this service is ideal in scenarios where API requests need to be managed in a queue structure, allowing
20
+ * for controlled execution and monitoring of these requests.
21
+ *
22
+ * @example
23
+ * // Adding a new item to the queue
24
+ * apiQueueService.addQueueItem({ id: 'item124', method: 'POST', uri: '/api/data', payload: {...} });
25
+ *
26
+ * // Processing a single item from the queue
27
+ * apiQueueService.processQueueItem('item123').subscribe(result => {
28
+ * console.log('Processed item 123 with result:', result);
29
+ * });
30
+ *
31
+ * // Processing all items in the queue in sequential order
32
+ * apiQueueService.processAllQueueItemsSequential(false).subscribe(results => {
33
+ * console.log('Processed all items in descending order of their timestamp:', results);
34
+ * });
35
+ *
36
+ * // Removing an item from the queue
37
+ * apiQueueService.removeQueueItem('item123');
38
+ *
39
+ * // Processing all items in the queue and continuing on error
40
+ * apiQueueService.processAllQueueItems(true).subscribe(results => {
41
+ * console.log('Processed all items in the queue with continuation on errors:', results);
42
+ * });
43
+ */
10
44
  export class ApiQueueService {
11
45
  constructor(store, http, logService) {
12
46
  this.store = store;
@@ -14,10 +48,26 @@ export class ApiQueueService {
14
48
  this.logService = logService;
15
49
  }
16
50
  /**
17
- * Adds an item in the queue by dispatching an action to the store.
18
- * @param id - The id of the item inside the queue.
19
- * WARNING if matches any other queue item id will overwrite it.
20
- * @param item - an item for Queue
51
+ * Adds an item to the queue by dispatching an action to the store.
52
+ * This function is specifically designed to enqueue API call requests represented by `ApiQueueItem` objects.
53
+ * Each item is identified by a unique `id`, which is used to manage the queue.
54
+ *
55
+ * @param {string} id - The unique identifier for the queue item. It's crucial to ensure that this ID is unique within the queue.
56
+ * If an item with the same ID already exists, the new item will overwrite the existing one.
57
+ * WARNING: Duplicate IDs will lead to overwriting of queue items.
58
+ *
59
+ * @param {ApiQueueItem} item - The item to be enqueued. This should be an object of type `ApiQueueItem`.
60
+ * The `method` property of the item must be one of the allowed methods ('post', 'put', 'get').
61
+ * If an unsupported method is provided, the function will throw an error.
62
+ *
63
+ * @throws {Error} Throws an error if the `method` property of the `item` is not one of the allowed methods.
64
+ * The error message is: `[ApiQueue] method "${item.method}" is not allowed`.
65
+ *
66
+ * @example
67
+ * // Example of adding an item to the API queue
68
+ * addQueueItem('12345', { method: 'post', url: '/api/data', payload: {...} });
69
+ *
70
+ * @returns {void} This function does not return a value. It adds the item to the queue via a dispatch action.
21
71
  */
22
72
  addQueueItem(id, item) {
23
73
  const allowedMethods = ['post', 'put', 'get'];
@@ -27,8 +77,25 @@ export class ApiQueueService {
27
77
  this.store.dispatch(new AddApiQueueItemAction({ id, item }));
28
78
  }
29
79
  /**
30
- * Subscribes to the store to retrieve queue and then converts the queue object to an array of items.
31
- * @return An Observable of array of all items inside the current queue (ApiQueueItem[])
80
+ * Retrieves the current state of the API queue and converts it into an array of Observables.
81
+ *
82
+ * This method subscribes to the store to access the API queue. It then maps the queue object,
83
+ * which is an associative array, into a linear array of ApiQueueItem instances. If the queue is empty,
84
+ * a warning is logged. This method is useful for tracking the state and contents of the API queue
85
+ * at a given moment.
86
+ *
87
+ * Note: This method takes a snapshot of the queue at the time of subscription. It does not provide
88
+ * a continuous stream of queue updates. To get real-time updates, consider subscribing directly
89
+ * to the store's observable.
90
+ *
91
+ * @returns {Observable<ApiQueueItem[]>} An Observable that emits an array of ApiQueueItem.
92
+ * The array represents all items currently in the queue. If the queue is empty, it emits an empty array.
93
+ *
94
+ * @example
95
+ * // Example usage
96
+ * this.getQueue().subscribe(queueItems => {
97
+ * console.log('Current queue items:', queueItems);
98
+ * });
32
99
  */
33
100
  getQueue() {
34
101
  return this.store.select(getApiQueue).pipe(take(1), map((queue) => {
@@ -40,9 +107,29 @@ export class ApiQueueService {
40
107
  }));
41
108
  }
42
109
  /**
43
- * Subscribes to the store to retrieve an item from the queue.
44
- * @param id - id of the item inside the queue
45
- * @return An Observable of ApiQueueItem type
110
+ * Retrieves a specific item from the API queue by its ID.
111
+ *
112
+ * This method subscribes to the store and selects a single item from the API queue based on the provided ID.
113
+ * It employs a pipeline to fetch the item: the `getApiQueueItem` selector is used to retrieve the item,
114
+ * and a `map` operator processes the result. If the item with the specified ID does not exist in the queue,
115
+ * a warning is logged, and `null` is returned.
116
+ *
117
+ * This method is ideal for accessing a specific queue item when its ID is known, allowing for targeted
118
+ * operations or checks on that particular item.
119
+ *
120
+ * @param {string} id - The unique identifier of the item within the queue.
121
+ * @returns {Observable<ApiQueueItem | null>} An Observable emitting the requested ApiQueueItem.
122
+ * If no item with the given ID exists in the queue, the Observable emits `null`.
123
+ *
124
+ * @example
125
+ * // Example usage
126
+ * this.getQueueItem('item123').subscribe(item => {
127
+ * if (item) {
128
+ * console.log('Found item:', item);
129
+ * } else {
130
+ * console.log('Item not found in the queue');
131
+ * }
132
+ * });
46
133
  */
47
134
  getQueueItem(id) {
48
135
  return this.store.select(getApiQueueItem(id)).pipe(take(1), map((queue) => {
@@ -54,24 +141,65 @@ export class ApiQueueService {
54
141
  }));
55
142
  }
56
143
  /**
57
- * Removes a given item from the queue.
58
- * @param id - id of the item inside the queue
144
+ * Removes a specific item from the API queue using its ID.
145
+ *
146
+ * This method dispatches an action to remove an item from the queue, identified by the provided ID.
147
+ * It is essential for managing the queue by eliminating items that are no longer needed or have been processed.
148
+ * The function does not return any value, as it primarily triggers an action within the store.
149
+ *
150
+ * Note: This method assumes the existence of the item in the queue. It does not perform a check
151
+ * to confirm the presence of the item before attempting to remove it. Therefore, it's recommended
152
+ * to verify the item's existence in the queue if uncertainty exists.
153
+ *
154
+ * @param {string} id - The unique identifier of the item to be removed from the queue.
155
+ *
156
+ * @example
157
+ * // Example usage
158
+ * this.removeQueueItem('item123');
159
+ * // The item with ID 'item123' will be dispatched for removal from the queue.
59
160
  */
60
161
  removeQueueItem(id) {
61
162
  this.store.dispatch(new RemoveApiQueueItemAction(id));
62
163
  }
63
164
  /**
64
- * Removes all items placed in the queue.
165
+ * Clears all items from the API queue.
166
+ *
167
+ * This method dispatches an action to empty the entire API queue, effectively removing all items that are currently queued.
168
+ * It is useful for scenarios where a complete reset of the queue is required, such as during initialization or after processing
169
+ * a batch of items. The function does not return any value, as its primary purpose is to trigger a state change in the store.
170
+ *
171
+ * Note: Use this method with caution as it will irreversibly clear all items in the queue. Ensure that this action does not
172
+ * disrupt any ongoing processes that rely on the queue's contents.
173
+ *
174
+ * @example
175
+ * // Example usage
176
+ * this.removeAllQueueItem();
177
+ * // This will dispatch an action to empty the entire API queue.
65
178
  */
66
179
  removeAllQueueItem() {
67
180
  this.store.dispatch(new EmptyApiQueueAction(null));
68
181
  }
69
182
  /**
70
- * Process an item from the queue.
71
- * @param id - id of the item inside the queue
72
- * @return An Observable of type any
183
+ * Processes an item from the API queue identified by its ID.
184
+ *
185
+ * Retrieves the specified item from the queue and applies processing logic as defined in `buildHttpRequest`.
186
+ * If the item is not found, logs a warning and returns an Observable emitting `null`.
187
+ *
188
+ * @param {string} id - The unique identifier of the item within the queue to be processed.
189
+ * @returns {Observable<any>} An Observable that emits the result of processing the queue item.
190
+ * If the item does not exist, the Observable emits `null`.
191
+ *
192
+ * @example
193
+ * // Example usage
194
+ * this.processQueueItem('item123').subscribe(result => {
195
+ * if (result) {
196
+ * console.log('Processing result:', result);
197
+ * } else {
198
+ * console.log('Item not found in the queue');
199
+ * }
200
+ * });
73
201
  */
74
- // TODO: find the correct type or turn into a generic, https://www.typescriptlang.org/docs/handbook/2/generics.html
202
+ // TODO: Replace `any` with a more specific type or make the method generic, https://www.typescriptlang.org/docs/handbook/2/generics.html
75
203
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
76
204
  processQueueItem(id) {
77
205
  return this.store.select(getApiQueueItem(id)).pipe(take(1), switchMap((queue) => {
@@ -83,11 +211,26 @@ export class ApiQueueService {
83
211
  }));
84
212
  }
85
213
  /**
86
- * Process all the items inside the queue.
87
- * @param [continueOnError=true] - in case of an item request fails continue with the rest in queue
88
- * @return An Observable with an array which contains all responses from all items in queue.
214
+ * Processes all items in the API queue and collects their responses.
215
+ *
216
+ * Iterates over each item in the queue and processes them using `buildHttpRequest`. If a request fails,
217
+ * the method can either continue processing the remaining items or stop, based on the `continueOnError` parameter.
218
+ * It returns an Observable that emits an array containing the responses or errors from all the processed items.
219
+ *
220
+ * The function currently returns `Observable<any[]>` indicating an array of any type. Future improvements
221
+ * should aim to specify a more accurate return type or utilize generics for increased type safety.
222
+ *
223
+ * @param {boolean} [continueOnError=true] - Determines whether to continue with the next item in the queue
224
+ * after a request failure. Defaults to `true`.
225
+ * @returns {Observable<any[]>} An Observable emitting an array of either responses or errors from the processed
226
+ * queue items.
227
+ *
228
+ * @example
229
+ * this.processAllQueueItems().subscribe(results => {
230
+ * // Handle the array of responses or errors
231
+ * });
89
232
  */
90
- // TODO: find the correct type or turn into a generic, https://www.typescriptlang.org/docs/handbook/2/generics.html
233
+ // TODO: Refine the return type to be more specific or implement generics, https://www.typescriptlang.org/docs/handbook/2/generics.html
91
234
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
92
235
  processAllQueueItems(continueOnError = true) {
93
236
  return this.store.select(getApiQueue).pipe(map((queue) => Object.entries(queue).map(([key, value]) => this.buildHttpRequest(key, value).pipe(catchError((error) => {
@@ -96,40 +239,80 @@ export class ApiQueueService {
96
239
  throw error;
97
240
  }
98
241
  return of(error);
99
- })))),
100
- // TODO: find the correct type or turn into a generic, https://www.typescriptlang.org/docs/handbook/2/generics.html
101
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
102
- switchMap((obsQueue) => forkJoin(Array.from(obsQueue))));
242
+ })))), switchMap((obsQueue) => forkJoin(Array.from(obsQueue))));
103
243
  }
104
244
  /**
105
- * Process all items in queue after it order them based on their timestamp. Beware that order
106
- * matter in execution of Http Request in queue. When a request completes only then next will begin. Emission
107
- * or Http response follows order.
108
- * @param [ascending=true] - sets the order of queue items based on timestamp
245
+ * Processes all items in the queue sequentially, based on their timestamp ordering.
246
+ *
247
+ * This method first orders the items in the API queue by their timestamp, either in ascending or descending
248
+ * order as specified by the `ascending` parameter. It then processes each item using `buildHttpRequest`, ensuring
249
+ * that each request is completed before the next begins. This sequential processing is crucial when the order of
250
+ * execution matters for HTTP requests in the queue. The method returns an Observable that emits the responses
251
+ * following the same order as the queue items were processed.
252
+ *
253
+ * The function currently returns `Observable<any>`, indicating a broad type. Future improvements should focus on
254
+ * specifying a more accurate return type or utilizing generics for increased type safety.
255
+ *
256
+ * @param {boolean} [ascending=true] - Determines whether the queue items are processed in ascending order of their
257
+ * timestamp. Defaults to `true`.
258
+ * @returns {Observable<any>} An Observable emitting the responses of the HTTP requests in the order they were processed.
259
+ *
260
+ * @example
261
+ * this.processAllQueueItemsSequential().subscribe(response => {
262
+ * // Handle each response in the order of queue processing
263
+ * });
109
264
  */
110
- // TODO: find the correct type or turn into a generic, https://www.typescriptlang.org/docs/handbook/2/generics.html
265
+ // TODO: Refine the return type for more specific or implement generics, https://www.typescriptlang.org/docs/handbook/2/generics.html
111
266
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
112
267
  processAllQueueItemsSequential(ascending = true) {
113
- return this.store.select(getApiQueue).pipe(concatMap((queue) => Object.entries(queue)
268
+ return this.store.select(getApiQueue).pipe(switchMap((queue) => from(Object.entries(queue)
114
269
  .sort((a, b) => (ascending ? this.sortOnTimestamp(a, b) : this.sortOnTimestamp(b, a)))
115
- .map(([id, item]) => this.buildHttpRequest(id, item))));
270
+ .map(([id, item]) => this.buildHttpRequest(id, item)))
271
+ .pipe(concatMap(x => x))));
116
272
  }
117
273
  /**
118
- * Short dates ascending based on input
119
- * @param a - Date one
120
- * @param b - Date two
274
+ * Compares two queue items based on their timestamp and determines their order.
275
+ *
276
+ * This protected method is used to sort queue items. It takes two queue items as input, each represented
277
+ * as a tuple containing an item ID and the `ApiQueueItem` object. The method compares these items based on
278
+ * the `timestamp` property of the `ApiQueueItem` objects. It returns a number indicating the order in which
279
+ * these items should be sorted.
280
+ *
281
+ * A positive return value indicates that the first item should come after the second, a negative value
282
+ * indicates the opposite, and zero indicates that they are equal in terms of timestamp.
121
283
  *
284
+ * @param {[string, ApiQueueItem]} a - The first queue item tuple for comparison.
285
+ * @param {[string, ApiQueueItem]} b - The second queue item tuple for comparison.
286
+ * @returns {number} A number indicating the order of the items: negative if `a` is earlier than `b`,
287
+ * positive if `a` is later than `b`, and zero if they are equal.
122
288
  * @beta
123
289
  */
124
290
  sortOnTimestamp(a, b) {
125
291
  return +new Date(a[1].timestamp) - +new Date(b[1].timestamp);
126
292
  }
127
293
  /**
128
- * build and HttpRequest Observable based on the given queue.
129
- * After successful request completion removes the item from the queue.
130
- * @param id - id of the item inside the queue
131
- * @param item - the item of the queue that matches the id.
132
- * @return An Observable of HttpClient Request
294
+ * Constructs and executes an HTTP request based on the provided queue item details.
295
+ *
296
+ * This private method takes an ID and an `ApiQueueItem` object to build and execute an HTTP request.
297
+ * It determines the HTTP method (like GET, POST, etc.) from the `method` property of the `ApiQueueItem`,
298
+ * and uses the `uri` and `payload` properties for the request's URL and body, respectively. After the
299
+ * request is executed, the corresponding queue item is removed from the queue.
300
+ *
301
+ * The method is generic, allowing the caller to specify the expected response type `T`. By default,
302
+ * it uses `any` type, but specifying a more concrete type enhances type safety and clarity in usage.
303
+ *
304
+ * @param {string} id - The ID of the queue item being processed.
305
+ * @param {ApiQueueItem} item - The queue item containing details for the HTTP request.
306
+ * @returns {Observable<T>} An Observable of type T, representing the response of the HTTP request.
307
+ *
308
+ * @example
309
+ * // Example usage for a specific response type
310
+ * this.buildHttpRequest<MyResponseType>('item123', queueItem)
311
+ * .subscribe(response => {
312
+ * // Handle the response
313
+ * });
314
+ *
315
+ * @template T - The expected type of the HTTP response. Defaults to `any`.
133
316
  */
134
317
  // TODO: add type for T and deprecate old function
135
318
  // TODO: find the correct type or turn into a generic, https://www.typescriptlang.org/docs/handbook/2/generics.html
@@ -148,4 +331,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.2", ngImpor
148
331
  }], ctorParameters: () => [{ type: i1.StoreService }, { type: i2.HttpClient }, { type: i3.LogService, decorators: [{
149
332
  type: Optional
150
333
  }] }] });
151
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXBpLXF1ZXVlLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9zcmMvbGliL3NlcnZpY2VzL3F1ZXVlL2FwaS1xdWV1ZS5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsUUFBUSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBRXJELE9BQU8sRUFBYyxFQUFFLEVBQUUsUUFBUSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQ2hELE9BQU8sRUFBRSxHQUFHLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxHQUFHLEVBQUUsVUFBVSxFQUFFLFNBQVMsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ2xGLE9BQU8sRUFBRSxXQUFXLEVBQUUsZUFBZSxFQUEwQixNQUFNLFdBQVcsQ0FBQztBQUdqRixPQUFPLEVBQWdCLHFCQUFxQixFQUFFLHdCQUF3QixFQUFFLG1CQUFtQixFQUFFLE1BQU0sVUFBVSxDQUFDOzs7OztBQUs5RyxNQUFNLE9BQU8sZUFBZTtJQUN4QixZQUNjLEtBQW1CLEVBQ25CLElBQWdCLEVBQ0osVUFBc0I7UUFGbEMsVUFBSyxHQUFMLEtBQUssQ0FBYztRQUNuQixTQUFJLEdBQUosSUFBSSxDQUFZO1FBQ0osZUFBVSxHQUFWLFVBQVUsQ0FBWTtJQUM3QyxDQUFDO0lBRUo7Ozs7O09BS0c7SUFDSCxZQUFZLENBQUMsRUFBVSxFQUFFLElBQWtCO1FBQ3ZDLE1BQU0sY0FBYyxHQUFHLENBQUMsTUFBTSxFQUFFLEtBQUssRUFBRSxLQUFLLENBQUMsQ0FBQztRQUU5QyxJQUFJLGNBQWMsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsRUFBRTtZQUN6QyxNQUFNLElBQUksS0FBSyxDQUFDLHNCQUFzQixJQUFJLENBQUMsTUFBTSxrQkFBa0IsQ0FBQyxDQUFDO1NBQ3hFO1FBRUQsSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMs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Q0FBQyxDQUF5QixFQUFFLENBQXlCO1FBQzFFLE9BQU8sQ0FBQyxJQUFJLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxJQUFJLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDakUsQ0FBQztJQUVEOzs7Ozs7T0FNRztJQUNILGtEQUFrRDtJQUNsRCxtSEFBbUg7SUFDbkgsOERBQThEO0lBQ3RELGdCQUFnQixDQUFVLEVBQVUsRUFBRSxJQUFrQjtRQUM1RCxPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxXQUFXLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDbEgsQ0FBQztpSUF0S1EsZUFBZTtxSUFBZixlQUFlLGNBRlosTUFBTTs7MkZBRVQsZUFBZTtrQkFIM0IsVUFBVTttQkFBQztvQkFDUixVQUFVLEVBQUUsTUFBTTtpQkFDckI7OzBCQUtRLFFBQVEiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlLCBPcHRpb25hbCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgSHR0cENsaWVudCB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbi9odHRwJztcbmltcG9ydCB7IE9ic2VydmFibGUsIG9mLCBmb3JrSm9pbiB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgdGFwLCBzd2l0Y2hNYXAsIHRha2UsIG1hcCwgY2F0Y2hFcnJvciwgY29uY2F0TWFwIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgZ2V0QXBpUXVldWUsIGdldEFwaVF1ZXVlSXRlbSwgQXBpUXVldWUsIEFwaVF1ZXVlSXRlbSB9IGZyb20gJ0BldWkvYmFzZSc7XG5cbmltcG9ydCB7IExvZ1NlcnZpY2UgfSBmcm9tICcuLi9sb2cnO1xuaW1wb3J0IHsgU3RvcmVTZXJ2aWNlLCBBZGRBcGlRdWV1ZUl0ZW1BY3Rpb24sIFJlbW92ZUFwaVF1ZXVlSXRlbUFjdGlvbiwgRW1wdHlBcGlRdWV1ZUFjdGlvbiB9IGZyb20gJy4uL3N0b3JlJztcblxuQEluamVjdGFibGUoe1xuICAgIHByb3ZpZGVkSW46ICdyb290Jyxcbn0pXG5leHBvcnQgY2xhc3MgQXBpUXVldWVTZXJ2aWNlIHtcbiAgICBjb25zdHJ1Y3RvcihcbiAgICAgICAgcHJvdGVjdGVkIHN0b3JlOiBTdG9yZVNlcnZpY2UsXG4gICAgICAgIHByb3RlY3RlZCBodHRwOiBIdHRwQ2xpZW50LFxuICAgICAgICBAT3B0aW9uYWwoKSBwcm90ZWN0ZWQgbG9nU2VydmljZTogTG9nU2VydmljZSxcbiAgICApIHt9XG5cbiAgICAvKipcbiAgICAgKiBBZGRzIGFuIGl0ZW0gaW4gdGhlIHF1ZXVlIGJ5IGRpc3BhdGNoaW5nIGFuIGFjdGlvbiB0byB0aGUgc3RvcmUuXG4gICAgICogQHBhcmFtIGlkIC0gVGhlIGlkIG9mIHRoZSBpdGVtIGluc2lkZSB0aGUgcXVldWUuXG4gICAgICogV0FSTklORyBpZiBtYXRjaGVzIGFueSBvdGhlciBxdWV1ZSBpdGVtIGlkIHdpbGwgb3ZlcndyaXRlIGl0LlxuICAgICAqIEBwYXJhbSBpdGVtIC0gYW4gaXRlbSBmb3IgUXVldWVcbiAgICAgKi9cbiAgICBhZGRRdWV1ZUl0ZW0oaWQ6IHN0cmluZywgaXRlbTogQXBpUXVldWVJdGVtKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IGFsbG93ZWRNZXRob2RzID0gWydwb3N0JywgJ3B1dCcsICdnZXQnXTtcblxuICAgICAgICBpZiAoYWxsb3dlZE1ldGhvZHMuaW5kZXhPZihpdGVtLm1ldGhvZCkgPCAwKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFtBcGlRdWV1ZV0gbWV0aG9kIFwiJHtpdGVtLm1ldGhvZH1cIiBpcyBub3QgYWxsb3dlZGApO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5zdG9yZS5kaXNwYXRjaChuZXcgQWRkQXBpUXVldWVJdGVtQWN0aW9uKHsgaWQsIGl0ZW0gfSkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFN1YnNjcmliZXMgdG8gdGhlIHN0b3JlIHRvIHJldHJpZXZlIHF1ZXVlIGFuZCB0aGVuIGNvbnZlcnRzIHRoZSBxdWV1ZSBvYmplY3QgdG8gYW4gYXJyYXkgb2YgaXRlbXMuXG4gICAgICogQHJldHVybiBBbiBPYnNlcnZhYmxlIG9mIGFycmF5IG9mIGFsbCBpdGVtcyBpbnNpZGUgdGhlIGN1cnJlbnQgcXVldWUgKEFwaVF1ZXVlSXRlbVtdKVxuICAgICAqL1xuICAgIGdldFF1ZXVlKCk6IE9ic2VydmFibGU8QXBpUXVldWVJdGVtW10+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuc3RvcmUuc2VsZWN0KGdldEFwaVF1ZXVlKS5waXBlKFxuICAgICAgICAgICAgdGFrZSgxKSxcbiAgICAgICAgICAgIG1hcCgocXVldWU6IEFwaVF1ZXVlKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgcXVldWVBcnJheSA9IHF1ZXVlICYmIE9iamVjdC52YWx1ZXM8QXBpUXVldWVJdGVtPihxdWV1ZSk7XG4gICAgICAgICAgICAgICAgaWYgKCFxdWV1ZUFycmF5IHx8IHF1ZXVlQXJyYXkubGVuZ3RoIDwgMSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmxvZ1NlcnZpY2U/Lndhcm4oJ05vIGl0ZW1zIGluIHRoZSBxdWV1ZSBleGlzdC4nKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICByZXR1cm4gcXVldWVBcnJheTtcbiAgICAgICAgICAgIH0pLFxuICAgICAgICApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFN1YnNjcmliZXMgdG8gdGhlIHN0b3JlIHRvIHJldHJpZXZlIGFuIGl0ZW0gZnJvbSB0aGUgcXVldWUuXG4gICAgICogQHBhcmFtIGlkIC0gaWQgb2YgdGhlIGl0ZW0gaW5zaWRlIHRoZSBxdWV1ZVxuICAgICAqIEByZXR1cm4gQW4gT2JzZXJ2YWJsZSBvZiBBcGlRdWV1ZUl0ZW0gdHlwZVxuICAgICAqL1xuICAgIGdldFF1ZXVlSXRlbShpZDogc3RyaW5nKTogT2JzZXJ2YWJsZTxBcGlRdWV1ZUl0ZW0+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuc3RvcmUuc2VsZWN0KGdldEFwaVF1ZXVlSXRlbShpZCkpLnBpcGUoXG4gICAgICAgICAgICB0YWtlKDEpLFxuICAgICAgICAgICAgbWFwKChxdWV1ZTogQXBpUXVldWVJdGVtKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKCFxdWV1ZSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmxvZ1NlcnZpY2U/Lndhcm4oYFF1ZXVlIGl0ZW0gd2l0aCBpZCBcIiR7aWR9XCIgZG9lcyBub3QgZXhpc3RgKTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBxdWV1ZTtcbiAgICAgICAgICAgIH0pLFxuICAgICAgICApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlbW92ZXMgYSBnaXZlbiBpdGVtIGZyb20gdGhlIHF1ZXVlLlxuICAgICAqIEBwYXJhbSBpZCAtIGlkIG9mIHRoZSBpdGVtIGluc2lkZSB0aGUgcXVldWVcbiAgICAgKi9cbiAgICByZW1vdmVRdWV1ZUl0ZW0oaWQ6IHN0cmluZyk6IHZvaWQge1xuICAgICAgICB0aGlzLnN0b3JlLmRpc3BhdGNoKG5ldyBSZW1vdmVBcGlRdWV1ZUl0ZW1BY3Rpb24oaWQpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZW1vdmVzIGFsbCBpdGVtcyBwbGFjZWQgaW4gdGhlIHF1ZXVlLlxuICAgICAqL1xuICAgIHJlbW92ZUFsbFF1ZXVlSXRlbSgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5zdG9yZS5kaXNwYXRjaChuZXcgRW1wdHlBcGlRdWV1ZUFjdGlvbihudWxsKSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUHJvY2VzcyBhbiBpdGVtIGZyb20gdGhlIHF1ZXVlLlxuICAgICAqIEBwYXJhbSBpZCAtIGlkIG9mIHRoZSBpdGVtIGluc2lkZSB0aGUgcXVldWVcbiAgICAgKiBAcmV0dXJuIEFuIE9ic2VydmFibGUgb2YgdHlwZSBhbnlcbiAgICAgKi9cbiAgICAvLyBUT0RPOiBmaW5kIHRoZSBjb3JyZWN0IHR5cGUgb3IgdHVybiBpbnRvIGEgZ2VuZXJpYywgaHR0cHM6Ly93d3cudHlwZXNjcmlwdGxhbmcub3JnL2RvY3MvaGFuZGJvb2svMi9nZW5lcmljcy5odG1sXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcbiAgICBwcm9jZXNzUXVldWVJdGVtKGlkOiBzdHJpbmcpOiBPYnNlcnZhYmxlPGFueT4ge1xuICAgICAgICByZXR1cm4gdGhpcy5zdG9yZS5zZWxlY3QoZ2V0QXBpUXVldWVJdGVtKGlkKSkucGlwZShcbiAgICAgICAgICAgIHRha2UoMSksXG4gICAgICAgICAgICBzd2l0Y2hNYXAoKHF1ZXVlOiBBcGlRdWV1ZUl0ZW0pID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoIXF1ZXVlKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMubG9nU2VydmljZT8ud2FybihgUXVldWUgaXRlbSB3aXRoIGlkIFwiJHtpZH1cIiBkb2VzIG5vdCBleGlzdGApO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gb2YobnVsbCk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuYnVpbGRIdHRwUmVxdWVzdChpZCwgcXVldWUpO1xuICAgICAgICAgICAgfSksXG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUHJvY2VzcyBhbGwgdGhlIGl0ZW1zIGluc2lkZSB0aGUgcXVldWUuXG4gICAgICogQHBhcmFtIFtjb250aW51ZU9uRXJyb3I9dHJ1ZV0gLSBpbiBjYXNlIG9mIGFuIGl0ZW0gcmVxdWVzdCBmYWlscyBjb250aW51ZSB3aXRoIHRoZSByZXN0IGluIHF1ZXVlXG4gICAgICogQHJldHVybiBBbiBPYnNlcnZhYmxlIHdpdGggYW4gYXJyYXkgd2hpY2ggY29udGFpbnMgYWxsIHJlc3BvbnNlcyBmcm9tIGFsbCBpdGVtcyBpbiBxdWV1ZS5cbiAgICAgKi9cbiAgICAvLyBUT0RPOiBmaW5kIHRoZSBjb3JyZWN0IHR5cGUgb3IgdHVybiBpbnRvIGEgZ2VuZXJpYywgaHR0cHM6Ly93d3cudHlwZXNjcmlwdGxhbmcub3JnL2RvY3MvaGFuZGJvb2svMi9nZW5lcmljcy5odG1sXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcbiAgICBwcm9jZXNzQWxsUXVldWVJdGVtcyhjb250aW51ZU9uRXJyb3IgPSB0cnVlKTogT2JzZXJ2YWJsZTxhbnlbXT4ge1xuICAgICAgICByZXR1cm4gdGhpcy5zdG9yZS5zZWxlY3QoZ2V0QXBpUXVldWUpLnBpcGUoXG4gICAgICAgICAgICBtYXAoKHF1ZXVlOiBBcGlRdWV1ZSkgPT5cbiAgICAgICAgICAgICAgICBPYmplY3QuZW50cmllcyhxdWV1ZSkubWFwKChba2V5LCB2YWx1ZV0pID0+XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuYnVpbGRIdHRwUmVxdWVzdChrZXksIHZhbHVlKS5waXBlKFxuICAgICAgICAgICAgICAgICAgICAgICAgY2F0Y2hFcnJvcigoZXJyb3I6IEVycm9yKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5sb2dTZXJ2aWNlPy5lcnJvcihgUXVldWUgSXRlbSB3aXRoIGlkICR7a2V5fSBmYWlsZWQuYCwgZXJyb3IubWVzc2FnZSwgZXJyb3Iuc3RhY2spO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFjb250aW51ZU9uRXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG9mKGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICApLFxuICAgICAgICAgICAgLy8gVE9ETzogZmluZCB0aGUgY29ycmVjdCB0eXBlIG9yIHR1cm4gaW50byBhIGdlbmVyaWMsIGh0dHBzOi8vd3d3LnR5cGVzY3JpcHRsYW5nLm9yZy9kb2NzL2hhbmRib29rLzIvZ2VuZXJpY3MuaHRtbFxuICAgICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcbiAgICAgICAgICAgIHN3aXRjaE1hcCgob2JzUXVldWU6IE9ic2VydmFibGU8YW55PltdKSA9PiBmb3JrSm9pbihBcnJheS5mcm9tKG9ic1F1ZXVlKSkpLFxuICAgICAgICApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFByb2Nlc3MgYWxsIGl0ZW1zIGluIHF1ZXVlIGFmdGVyIGl0IG9yZGVyIHRoZW0gYmFzZWQgb24gdGhlaXIgdGltZXN0YW1wLiBCZXdhcmUgdGhhdCBvcmRlclxuICAgICAqIG1hdHRlciBpbiBleGVjdXRpb24gb2YgSHR0cCBSZXF1ZXN0IGluIHF1ZXVlLiBXaGVuIGEgcmVxdWVzdCBjb21wbGV0ZXMgb25seSB0aGVuIG5leHQgd2lsbCBiZWdpbi4gRW1pc3Npb25cbiAgICAgKiBvciBIdHRwIHJlc3BvbnNlIGZvbGxvd3Mgb3JkZXIuXG4gICAgICogQHBhcmFtIFthc2NlbmRpbmc9dHJ1ZV0gLSBzZXRzIHRoZSBvcmRlciBvZiBxdWV1ZSBpdGVtcyBiYXNlZCBvbiB0aW1lc3RhbXBcbiAgICAgKi9cbiAgICAvLyBUT0RPOiBmaW5kIHRoZSBjb3JyZWN0IHR5cGUgb3IgdHVybiBpbnRvIGEgZ2VuZXJpYywgaHR0cHM6Ly93d3cudHlwZXNjcmlwdGxhbmcub3JnL2RvY3MvaGFuZGJvb2svMi9nZW5lcmljcy5odG1sXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcbiAgICBwcm9jZXNzQWxsUXVldWVJdGVtc1NlcXVlbnRpYWwoYXNjZW5kaW5nID0gdHJ1ZSk6IE9ic2VydmFibGU8YW55PiB7XG4gICAgICAgIHJldHVybiB0aGlzLnN0b3JlLnNlbGVjdChnZXRBcGlRdWV1ZSkucGlwZShcbiAgICAgICAgICAgIGNvbmNhdE1hcCgocXVldWU6IEFwaVF1ZXVlKSA9PlxuICAgICAgICAgICAgICAgIE9iamVjdC5lbnRyaWVzKHF1ZXVlKVxuICAgICAgICAgICAgICAgICAgICAuc29ydCgoYSwgYikgPT4gKGFzY2VuZGluZyA/IHRoaXMuc29ydE9uVGltZXN0YW1wKGEsIGIpIDogdGhpcy5zb3J0T25UaW1lc3RhbXAoYiwgYSkpKVxuICAgICAgICAgICAgICAgICAgICAubWFwKChbaWQsIGl0ZW1dKSA9PiB0aGlzLmJ1aWxkSHR0cFJlcXVlc3QoaWQsIGl0ZW0pKSxcbiAgICAgICAgICAgICksXG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2hvcnQgZGF0ZXMgYXNjZW5kaW5nIGJhc2VkIG9uIGlucHV0XG4gICAgICogQHBhcmFtIGEgLSBEYXRlIG9uZVxuICAgICAqIEBwYXJhbSBiIC0gRGF0ZSB0d29cbiAgICAgKlxuICAgICAqIEBiZXRhXG4gICAgICovXG4gICAgcHJvdGVjdGVkIHNvcnRPblRpbWVzdGFtcChhOiBbc3RyaW5nLCBBcGlRdWV1ZUl0ZW1dLCBiOiBbc3RyaW5nLCBBcGlRdWV1ZUl0ZW1dKTogbnVtYmVyIHtcbiAgICAgICAgcmV0dXJuICtuZXcgRGF0ZShhWzFdLnRpbWVzdGFtcCkgLSArbmV3IERhdGUoYlsxXS50aW1lc3RhbXApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIGJ1aWxkIGFuZCBIdHRwUmVxdWVzdCBPYnNlcnZhYmxlIGJhc2VkIG9uIHRoZSBnaXZlbiBxdWV1ZS5cbiAgICAgKiBBZnRlciBzdWNjZXNzZnVsIHJlcXVlc3QgY29tcGxldGlvbiByZW1vdmVzIHRoZSBpdGVtIGZyb20gdGhlIHF1ZXVlLlxuICAgICAqIEBwYXJhbSBpZCAtIGlkIG9mIHRoZSBpdGVtIGluc2lkZSB0aGUgcXVldWVcbiAgICAgKiBAcGFyYW0gaXRlbSAtIHRoZSBpdGVtIG9mIHRoZSBxdWV1ZSB0aGF0IG1hdGNoZXMgdGhlIGlkLlxuICAgICAqIEByZXR1cm4gQW4gT2JzZXJ2YWJsZSBvZiBIdHRwQ2xpZW50IFJlcXVlc3RcbiAgICAgKi9cbiAgICAvLyBUT0RPOiBhZGQgdHlwZSBmb3IgVCBhbmQgZGVwcmVjYXRlIG9sZCBmdW5jdGlvblxuICAgIC8vIFRPRE86IGZpbmQgdGhlIGNvcnJlY3QgdHlwZSBvciB0dXJuIGludG8gYSBnZW5lcmljLCBodHRwczovL3d3dy50eXBlc2NyaXB0bGFuZy5vcmcvZG9jcy9oYW5kYm9vay8yL2dlbmVyaWNzLmh0bWxcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueVxuICAgIHByaXZhdGUgYnVpbGRIdHRwUmVxdWVzdDxUID0gYW55PihpZDogc3RyaW5nLCBpdGVtOiBBcGlRdWV1ZUl0ZW0pOiBPYnNlcnZhYmxlPFQ+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaHR0cFtpdGVtLm1ldGhvZC50b0xvd2VyQ2FzZSgpXShpdGVtLnVyaSwgaXRlbS5wYXlsb2FkKS5waXBlKHRhcCgoKSA9PiB0aGlzLnJlbW92ZVF1ZXVlSXRlbShpZCkpKTtcbiAgICB9XG59XG4iXX0=
334
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXBpLXF1ZXVlLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9zcmMvbGliL3NlcnZpY2VzL3F1ZXVlL2FwaS1xdWV1ZS5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsUUFBUSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBRXJELE9BQU8sRUFBYyxFQUFFLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUN0RCxPQUFPLEVBQUUsR0FBRyxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUUsR0FBRyxFQUFFLFVBQVUsRUFBRSxTQUFTLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUNsRixPQUFPLEVBQUUsV0FBVyxFQUFFLGVBQWUsRUFBMEIsTUFBTSxXQUFXLENBQUM7QUFHakYsT0FBTyxFQUFnQixxQkFBcUIsRUFBRSx3QkFBd0IsRUFBRSxtQkFBbUIsRUFBRSxNQUFNLFVBQVUsQ0FBQzs7Ozs7QUFFOUc7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQWlDRztBQUlILE1BQU0sT0FBTyxlQUFlO0lBQ3hCLFlBQ2MsS0FBbUIsRUFDbkIsSUFBZ0IsRUFDSixVQUFzQjtRQUZsQyxVQUFLLEdBQUwsS0FBSyxDQUFjO1FBQ25CLFNBQUksR0FBSixJQUFJLENBQVk7UUFDSixlQUFVLEdBQVYsVUFBVSxDQUFZO0lBQzdDLENBQUM7SUFFSjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O09BcUJHO0lBQ0gsWUFBWSxDQUFDLEVBQVUsRUFBRSxJQUFrQjtRQUN2QyxNQUFNLGNBQWMsR0FBRyxDQUFDLE1BQU0sRUFBRSxLQUFLLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFFOUMsSUFBSSxjQUFjLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLEVBQUU7WUFDekMsTUFBTSxJQUFJLEtBQUssQ0FBQyxzQkFBc0IsSUFB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QUFDLENBQUM7YUFDckYsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsSUFBSSxDQUFDLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxFQUFFLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQzthQUNyRCxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FDL0IsQ0FDSixDQUFDO0lBQ04sQ0FBQztJQUVEOzs7Ozs7Ozs7Ozs7Ozs7O09BZ0JHO0lBQ08sZUFBZSxDQUFDLENBQXlCLEVBQUUsQ0FBeUI7UUFDMUUsT0FBTyxDQUFDLElBQUksSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLElBQUksSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUNqRSxDQUFDO0lBRUQ7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O09BdUJHO0lBQ0gsa0RBQWtEO0lBQ2xELG1IQUFtSDtJQUNuSCw4REFBOEQ7SUFDdEQsZ0JBQWdCLENBQVUsRUFBVSxFQUFFLElBQWtCO1FBQzVELE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLFdBQVcsRUFBRSxDQUFDLENBQUksSUFBSSxDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUNySCxDQUFDO2lJQTVUUSxlQUFlO3FJQUFmLGVBQWUsY0FGWixNQUFNOzsyRkFFVCxlQUFlO2tCQUgzQixVQUFVO21CQUFDO29CQUNSLFVBQVUsRUFBRSxNQUFNO2lCQUNyQjs7MEJBS1EsUUFBUSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdGFibGUsIE9wdGlvbmFsIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBIdHRwQ2xpZW50IH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uL2h0dHAnO1xuaW1wb3J0IHsgT2JzZXJ2YWJsZSwgb2YsIGZvcmtKb2luLCBmcm9tIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyB0YXAsIHN3aXRjaE1hcCwgdGFrZSwgbWFwLCBjYXRjaEVycm9yLCBjb25jYXRNYXAgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBnZXRBcGlRdWV1ZSwgZ2V0QXBpUXVldWVJdGVtLCBBcGlRdWV1ZSwgQXBpUXVldWVJdGVtIH0gZnJvbSAnQGV1aS9iYXNlJztcblxuaW1wb3J0IHsgTG9nU2VydmljZSB9IGZyb20gJy4uL2xvZyc7XG5pbXBvcnQgeyBTdG9yZVNlcnZpY2UsIEFkZEFwaVF1ZXVlSXRlbUFjdGlvbiwgUmVtb3ZlQXBpUXVldWVJdGVtQWN0aW9uLCBFbXB0eUFwaVF1ZXVlQWN0aW9uIH0gZnJvbSAnLi4vc3RvcmUnO1xuXG4vKipcbiAqIFNlcnZpY2UgY2xhc3MgZm9yIG1hbmFnaW5nIGFuZCBwcm9jZXNzaW5nIGEgcXVldWUgb2YgQVBJIHJlcXVlc3RzLlxuICpcbiAqIFRoaXMgc2VydmljZSBwcm92aWRlcyBmdW5jdGlvbmFsaXR5IHRvIGFkZCwgcmVtb3ZlLCBwcm9jZXNzLCBhbmQgbWFuYWdlIEhUVFAgcmVxdWVzdHMgc3RvcmVkIGluIGEgcXVldWUuXG4gKiBJdCBlbmFibGVzIHNlcXVlbnRpYWwgb3IgYnVsayBwcm9jZXNzaW5nIG9mIHJlcXVlc3RzLCBlbnN1cmluZyBjb250cm9sbGVkIGV4ZWN1dGlvbiBhbmQgaGFuZGxpbmcgb2YgQVBJIGNhbGxzLlxuICogVGhlIHNlcnZpY2UgbWV0aG9kcyBvZmZlciBmZWF0dXJlcyBsaWtlIHByb2Nlc3NpbmcgaW5kaXZpZHVhbCBpdGVtcywgcHJvY2Vzc2luZyBhbGwgaXRlbXMgaW4gdGhlIHF1ZXVlIGVpdGhlclxuICogc2VxdWVudGlhbGx5IG9yIGFsbCBhdCBvbmNlLCBhbmQgcmVtb3ZpbmcgaXRlbXMgZnJvbSB0aGUgcXVldWUuIEVhY2ggbWV0aG9kIGlzIGRlc2lnbmVkIHRvIGhhbmRsZSBzcGVjaWZpYyBhc3BlY3RzXG4gKiBvZiBxdWV1ZSBtYW5hZ2VtZW50IGFuZCBwcm9jZXNzaW5nLCB3aXRoIGF0dGVudGlvbiB0byBkZXRhaWxzIGxpa2Ugb3JkZXIgb2YgZXhlY3V0aW9uIGFuZCBlcnJvciBoYW5kbGluZy5cbiAqXG4gKiBVc2FnZSBvZiB0aGlzIHNlcnZpY2UgaXMgaWRlYWwgaW4gc2NlbmFyaW9zIHdoZXJlIEFQSSByZXF1ZXN0cyBuZWVkIHRvIGJlIG1hbmFnZWQgaW4gYSBxdWV1ZSBzdHJ1Y3R1cmUsIGFsbG93aW5nXG4gKiBmb3IgY29udHJvbGxlZCBleGVjdXRpb24gYW5kIG1vbml0b3Jpbmcgb2YgdGhlc2UgcmVxdWVzdHMuXG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIEFkZGluZyBhIG5ldyBpdGVtIHRvIHRoZSBxdWV1ZVxuICogYXBpUXVldWVTZXJ2aWNlLmFkZFF1ZXVlSXRlbSh7IGlkOiAnaXRlbTEyNCcsIG1ldGhvZDogJ1BPU1QnLCB1cmk6ICcvYXBpL2RhdGEnLCBwYXlsb2FkOiB7Li4ufSB9KTtcbiAqXG4gKiAvLyBQcm9jZXNzaW5nIGEgc2luZ2xlIGl0ZW0gZnJvbSB0aGUgcXVldWVcbiAqIGFwaVF1ZXVlU2VydmljZS5wcm9jZXNzUXVldWVJdGVtKCdpdGVtMTIzJykuc3Vic2NyaWJlKHJlc3VsdCA9PiB7XG4gKiAgIGNvbnNvbGUubG9nKCdQcm9jZXNzZWQgaXRlbSAxMjMgd2l0aCByZXN1bHQ6JywgcmVzdWx0KTtcbiAqIH0pO1xuICpcbiAqIC8vIFByb2Nlc3NpbmcgYWxsIGl0ZW1zIGluIHRoZSBxdWV1ZSBpbiBzZXF1ZW50aWFsIG9yZGVyXG4gKiBhcGlRdWV1ZVNlcnZpY2UucHJvY2Vzc0FsbFF1ZXVlSXRlbXNTZXF1ZW50aWFsKGZhbHNlKS5zdWJzY3JpYmUocmVzdWx0cyA9PiB7XG4gKiAgIGNvbnNvbGUubG9nKCdQcm9jZXNzZWQgYWxsIGl0ZW1zIGluIGRlc2NlbmRpbmcgb3JkZXIgb2YgdGhlaXIgdGltZXN0YW1wOicsIHJlc3VsdHMpO1xuICogfSk7XG4gKlxuICogLy8gUmVtb3ZpbmcgYW4gaXRlbSBmcm9tIHRoZSBxdWV1ZVxuICogYXBpUXVldWVTZXJ2aWNlLnJlbW92ZVF1ZXVlSXRlbSgnaXRlbTEyMycpO1xuICpcbiAqIC8vIFByb2Nlc3NpbmcgYWxsIGl0ZW1zIGluIHRoZSBxdWV1ZSBhbmQgY29udGludWluZyBvbiBlcnJvclxuICogYXBpUXVldWVTZXJ2aWNlLnByb2Nlc3NBbGxRdWV1ZUl0ZW1zKHRydWUpLnN1YnNjcmliZShyZXN1bHRzID0+IHtcbiAqICAgY29uc29sZS5sb2coJ1Byb2Nlc3NlZCBhbGwgaXRlbXMgaW4gdGhlIHF1ZXVlIHdpdGggY29udGludWF0aW9uIG9uIGVycm9yczonLCByZXN1bHRzKTtcbiAqIH0pO1xuICovXG5ASW5qZWN0YWJsZSh7XG4gICAgcHJvdmlkZWRJbjogJ3Jvb3QnLFxufSlcbmV4cG9ydCBjbGFzcyBBcGlRdWV1ZVNlcnZpY2Uge1xuICAgIGNvbnN0cnVjdG9yKFxuICAgICAgICBwcm90ZWN0ZWQgc3RvcmU6IFN0b3JlU2VydmljZSxcbiAgICAgICAgcHJvdGVjdGVkIGh0dHA6IEh0dHBDbGllbnQsXG4gICAgICAgIEBPcHRpb25hbCgpIHByb3RlY3RlZCBsb2dTZXJ2aWNlOiBMb2dTZXJ2aWNlLFxuICAgICkge31cblxuICAgIC8qKlxuICAgICAqIEFkZHMgYW4gaXRlbSB0byB0aGUgcXVldWUgYnkgZGlzcGF0Y2hpbmcgYW4gYWN0aW9uIHRvIHRoZSBzdG9yZS5cbiAgICAgKiBUaGlzIGZ1bmN0aW9uIGlzIHNwZWNpZmljYWxseSBkZXNpZ25lZCB0byBlbnF1ZXVlIEFQSSBjYWxsIHJlcXVlc3RzIHJlcHJlc2VudGVkIGJ5IGBBcGlRdWV1ZUl0ZW1gIG9iamVjdHMuXG4gICAgICogRWFjaCBpdGVtIGlzIGlkZW50aWZpZWQgYnkgYSB1bmlxdWUgYGlkYCwgd2hpY2ggaXMgdXNlZCB0byBtYW5hZ2UgdGhlIHF1ZXVlLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGlkIC0gVGhlIHVuaXF1ZSBpZGVudGlmaWVyIGZvciB0aGUgcXVldWUgaXRlbS4gSXQncyBjcnVjaWFsIHRvIGVuc3VyZSB0aGF0IHRoaXMgSUQgaXMgdW5pcXVlIHdpdGhpbiB0aGUgcXVldWUuXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgSWYgYW4gaXRlbSB3aXRoIHRoZSBzYW1lIElEIGFscmVhZHkgZXhpc3RzLCB0aGUgbmV3IGl0ZW0gd2lsbCBvdmVyd3JpdGUgdGhlIGV4aXN0aW5nIG9uZS5cbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICBXQVJOSU5HOiBEdXBsaWNhdGUgSURzIHdpbGwgbGVhZCB0byBvdmVyd3JpdGluZyBvZiBxdWV1ZSBpdGVtcy5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7QXBpUXVldWVJdGVtfSBpdGVtIC0gVGhlIGl0ZW0gdG8gYmUgZW5xdWV1ZWQuIFRoaXMgc2hvdWxkIGJlIGFuIG9iamVjdCBvZiB0eXBlIGBBcGlRdWV1ZUl0ZW1gLlxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVGhlIGBtZXRob2RgIHByb3BlcnR5IG9mIHRoZSBpdGVtIG11c3QgYmUgb25lIG9mIHRoZSBhbGxvd2VkIG1ldGhvZHMgKCdwb3N0JywgJ3B1dCcsICdnZXQnKS5cbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElmIGFuIHVuc3VwcG9ydGVkIG1ldGhvZCBpcyBwcm92aWRlZCwgdGhlIGZ1bmN0aW9uIHdpbGwgdGhyb3cgYW4gZXJyb3IuXG4gICAgICpcbiAgICAgKiBAdGhyb3dzIHtFcnJvcn0gVGhyb3dzIGFuIGVycm9yIGlmIHRoZSBgbWV0aG9kYCBwcm9wZXJ0eSBvZiB0aGUgYGl0ZW1gIGlzIG5vdCBvbmUgb2YgdGhlIGFsbG93ZWQgbWV0aG9kcy5cbiAgICAgKiAgICAgICAgICAgICAgICAgVGhlIGVycm9yIG1lc3NhZ2UgaXM6IGBbQXBpUXVldWVdIG1ldGhvZCBcIiR7aXRlbS5tZXRob2R9XCIgaXMgbm90IGFsbG93ZWRgLlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiAvLyBFeGFtcGxlIG9mIGFkZGluZyBhbiBpdGVtIHRvIHRoZSBBUEkgcXVldWVcbiAgICAgKiBhZGRRdWV1ZUl0ZW0oJzEyMzQ1JywgeyBtZXRob2Q6ICdwb3N0JywgdXJsOiAnL2FwaS9kYXRhJywgcGF5bG9hZDogey4uLn0gfSk7XG4gICAgICpcbiAgICAgKiBAcmV0dXJucyB7dm9pZH0gVGhpcyBmdW5jdGlvbiBkb2VzIG5vdCByZXR1cm4gYSB2YWx1ZS4gSXQgYWRkcyB0aGUgaXRlbSB0byB0aGUgcXVldWUgdmlhIGEgZGlzcGF0Y2ggYWN0aW9uLlxuICAgICAqL1xuICAgIGFkZFF1ZXVlSXRlbShpZDogc3RyaW5nLCBpdGVtOiBBcGlRdWV1ZUl0ZW0pOiB2b2lkIHtcbiAgICAgICAgY29uc3QgYWxsb3dlZE1ldGhvZHMgPSBbJ3Bvc3QnLCAncHV0JywgJ2dldCddO1xuXG4gICAgICAgIGlmIChhbGxvd2VkTWV0aG9kcy5pbmRleE9mKGl0ZW0ubWV0aG9kKSA8IDApIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgW0FwaVF1ZXVlXSBtZXRob2QgXCIke2l0ZW0ubWV0aG9kfVwiIGlzIG5vdCBhbGxvd2VkYCk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnN0b3JlLmRpc3BhdGNoKG5ldyBBZGRBcGlRdWV1ZUl0ZW1BY3Rpb24oeyBpZCwgaXRlbSB9KSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0cmlldmVzIHRoZSBjdXJyZW50IHN0YXRlIG9mIHRoZSBBUEkgcXVldWUgYW5kIGNvbnZlcnRzIGl0IGludG8gYW4gYXJyYXkgb2YgT2JzZXJ2YWJsZXMuXG4gICAgICpcbiAgICAgKiBUaGlzIG1ldGhvZCBzdWJzY3JpYmVzIHRvIHRoZSBzdG9yZSB0byBhY2Nlc3MgdGhlIEFQSSBxdWV1ZS4gSXQgdGhlbiBtYXBzIHRoZSBxdWV1ZSBvYmplY3QsXG4gICAgICogd2hpY2ggaXMgYW4gYXNzb2NpYXRpdmUgYXJyYXksIGludG8gYSBsaW5lYXIgYXJyYXkgb2YgQXBpUXVldWVJdGVtIGluc3RhbmNlcy4gSWYgdGhlIHF1ZXVlIGlzIGVtcHR5LFxuICAgICAqIGEgd2FybmluZyBpcyBsb2dnZWQuIFRoaXMgbWV0aG9kIGlzIHVzZWZ1bCBmb3IgdHJhY2tpbmcgdGhlIHN0YXRlIGFuZCBjb250ZW50cyBvZiB0aGUgQVBJIHF1ZXVlXG4gICAgICogYXQgYSBnaXZlbiBtb21lbnQuXG4gICAgICpcbiAgICAgKiBOb3RlOiBUaGlzIG1ldGhvZCB0YWtlcyBhIHNuYXBzaG90IG9mIHRoZSBxdWV1ZSBhdCB0aGUgdGltZSBvZiBzdWJzY3JpcHRpb24uIEl0IGRvZXMgbm90IHByb3ZpZGVcbiAgICAgKiBhIGNvbnRpbnVvdXMgc3RyZWFtIG9mIHF1ZXVlIHVwZGF0ZXMuIFRvIGdldCByZWFsLXRpbWUgdXBkYXRlcywgY29uc2lkZXIgc3Vic2NyaWJpbmcgZGlyZWN0bHlcbiAgICAgKiB0byB0aGUgc3RvcmUncyBvYnNlcnZhYmxlLlxuICAgICAqXG4gICAgICogQHJldHVybnMge09ic2VydmFibGU8QXBpUXVldWVJdGVtW10+fSBBbiBPYnNlcnZhYmxlIHRoYXQgZW1pdHMgYW4gYXJyYXkgb2YgQXBpUXVldWVJdGVtLlxuICAgICAqIFRoZSBhcnJheSByZXByZXNlbnRzIGFsbCBpdGVtcyBjdXJyZW50bHkgaW4gdGhlIHF1ZXVlLiBJZiB0aGUgcXVldWUgaXMgZW1wdHksIGl0IGVtaXRzIGFuIGVtcHR5IGFycmF5LlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiAvLyBFeGFtcGxlIHVzYWdlXG4gICAgICogdGhpcy5nZXRRdWV1ZSgpLnN1YnNjcmliZShxdWV1ZUl0ZW1zID0+IHtcbiAgICAgKiAgIGNvbnNvbGUubG9nKCdDdXJyZW50IHF1ZXVlIGl0ZW1zOicsIHF1ZXVlSXRlbXMpO1xuICAgICAqIH0pO1xuICAgICAqL1xuICAgIGdldFF1ZXVlKCk6IE9ic2VydmFibGU8QXBpUXVldWVJdGVtW10+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuc3RvcmUuc2VsZWN0KGdldEFwaVF1ZXVlKS5waXBlKFxuICAgICAgICAgICAgdGFrZSgxKSxcbiAgICAgICAgICAgIG1hcCgocXVldWU6IEFwaVF1ZXVlKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgcXVldWVBcnJheSA9IHF1ZXVlICYmIE9iamVjdC52YWx1ZXM8QXBpUXVldWVJdGVtPihxdWV1ZSk7XG4gICAgICAgICAgICAgICAgaWYgKCFxdWV1ZUFycmF5IHx8IHF1ZXVlQXJyYXkubGVuZ3RoIDwgMSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmxvZ1NlcnZpY2U/Lndhcm4oJ05vIGl0ZW1zIGluIHRoZSBxdWV1ZSBleGlzdC4nKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICByZXR1cm4gcXVldWVBcnJheTtcbiAgICAgICAgICAgIH0pLFxuICAgICAgICApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHJpZXZlcyBhIHNwZWNpZmljIGl0ZW0gZnJvbSB0aGUgQVBJIHF1ZXVlIGJ5IGl0cyBJRC5cbiAgICAgKlxuICAgICAqIFRoaXMgbWV0aG9kIHN1YnNjcmliZXMgdG8gdGhlIHN0b3JlIGFuZCBzZWxlY3RzIGEgc2luZ2xlIGl0ZW0gZnJvbSB0aGUgQVBJIHF1ZXVlIGJhc2VkIG9uIHRoZSBwcm92aWRlZCBJRC5cbiAgICAgKiBJdCBlbXBsb3lzIGEgcGlwZWxpbmUgdG8gZmV0Y2ggdGhlIGl0ZW06IHRoZSBgZ2V0QXBpUXVldWVJdGVtYCBzZWxlY3RvciBpcyB1c2VkIHRvIHJldHJpZXZlIHRoZSBpdGVtLFxuICAgICAqIGFuZCBhIGBtYXBgIG9wZXJhdG9yIHByb2Nlc3NlcyB0aGUgcmVzdWx0LiBJZiB0aGUgaXRlbSB3aXRoIHRoZSBzcGVjaWZpZWQgSUQgZG9lcyBub3QgZXhpc3QgaW4gdGhlIHF1ZXVlLFxuICAgICAqIGEgd2FybmluZyBpcyBsb2dnZWQsIGFuZCBgbnVsbGAgaXMgcmV0dXJuZWQuXG4gICAgICpcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBpZGVhbCBmb3IgYWNjZXNzaW5nIGEgc3BlY2lmaWMgcXVldWUgaXRlbSB3aGVuIGl0cyBJRCBpcyBrbm93biwgYWxsb3dpbmcgZm9yIHRhcmdldGVkXG4gICAgICogb3BlcmF0aW9ucyBvciBjaGVja3Mgb24gdGhhdCBwYXJ0aWN1bGFyIGl0ZW0uXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gaWQgLSBUaGUgdW5pcXVlIGlkZW50aWZpZXIgb2YgdGhlIGl0ZW0gd2l0aGluIHRoZSBxdWV1ZS5cbiAgICAgKiBAcmV0dXJucyB7T2JzZXJ2YWJsZTxBcGlRdWV1ZUl0ZW0gfCBudWxsPn0gQW4gT2JzZXJ2YWJsZSBlbWl0dGluZyB0aGUgcmVxdWVzdGVkIEFwaVF1ZXVlSXRlbS5cbiAgICAgKiBJZiBubyBpdGVtIHdpdGggdGhlIGdpdmVuIElEIGV4aXN0cyBpbiB0aGUgcXVldWUsIHRoZSBPYnNlcnZhYmxlIGVtaXRzIGBudWxsYC5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogLy8gRXhhbXBsZSB1c2FnZVxuICAgICAqIHRoaXMuZ2V0UXVldWVJdGVtKCdpdGVtMTIzJykuc3Vic2NyaWJlKGl0ZW0gPT4ge1xuICAgICAqICAgaWYgKGl0ZW0pIHtcbiAgICAgKiAgICAgY29uc29sZS5sb2coJ0ZvdW5kIGl0ZW06JywgaXRlbSk7XG4gICAgICogICB9IGVsc2Uge1xuICAgICAqICAgICBjb25zb2xlLmxvZygnSXRlbSBub3QgZm91bmQgaW4gdGhlIHF1ZXVlJyk7XG4gICAgICogICB9XG4gICAgICogfSk7XG4gICAgICovXG4gICAgZ2V0UXVldWVJdGVtKGlkOiBzdHJpbmcpOiBPYnNlcnZhYmxlPEFwaVF1ZXVlSXRlbT4ge1xuICAgICAgICByZXR1cm4gdGhpcy5zdG9yZS5zZWxlY3QoZ2V0QXBpUXVldWVJdGVtKGlkKSkucGlwZShcbiAgICAgICAgICAgIHRha2UoMSksXG4gICAgICAgICAgICBtYXAoKHF1ZXVlOiBBcGlRdWV1ZUl0ZW0pID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoIXF1ZXVlKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMubG9nU2VydmljZT8ud2FybihgUXVldWUgaXRlbSB3aXRoIGlkIFwiJHtpZH1cIiBkb2VzIG5vdCBleGlzdGApO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIHF1ZXVlO1xuICAgICAgICAgICAgfSksXG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmVtb3ZlcyBhIHNwZWNpZmljIGl0ZW0gZnJvbSB0aGUgQVBJIHF1ZXVlIHVzaW5nIGl0cyBJRC5cbiAgICAgKlxuICAgICAqIFRoaXMgbWV0aG9kIGRpc3BhdGNoZXMgYW4gYWN0aW9uIHRvIHJlbW92ZSBhbiBpdGVtIGZyb20gdGhlIHF1ZXVlLCBpZGVudGlmaWVkIGJ5IHRoZSBwcm92aWRlZCBJRC5cbiAgICAgKiBJdCBpcyBlc3NlbnRpYWwgZm9yIG1hbmFnaW5nIHRoZSBxdWV1ZSBieSBlbGltaW5hdGluZyBpdGVtcyB0aGF0IGFyZSBubyBsb25nZXIgbmVlZGVkIG9yIGhhdmUgYmVlbiBwcm9jZXNzZWQuXG4gICAgICogVGhlIGZ1bmN0aW9uIGRvZXMgbm90IHJldHVybiBhbnkgdmFsdWUsIGFzIGl0IHByaW1hcmlseSB0cmlnZ2VycyBhbiBhY3Rpb24gd2l0aGluIHRoZSBzdG9yZS5cbiAgICAgKlxuICAgICAqIE5vdGU6IFRoaXMgbWV0aG9kIGFzc3VtZXMgdGhlIGV4aXN0ZW5jZSBvZiB0aGUgaXRlbSBpbiB0aGUgcXVldWUuIEl0IGRvZXMgbm90IHBlcmZvcm0gYSBjaGVja1xuICAgICAqIHRvIGNvbmZpcm0gdGhlIHByZXNlbmNlIG9mIHRoZSBpdGVtIGJlZm9yZSBhdHRlbXB0aW5nIHRvIHJlbW92ZSBpdC4gVGhlcmVmb3JlLCBpdCdzIHJlY29tbWVuZGVkXG4gICAgICogdG8gdmVyaWZ5IHRoZSBpdGVtJ3MgZXhpc3RlbmNlIGluIHRoZSBxdWV1ZSBpZiB1bmNlcnRhaW50eSBleGlzdHMuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gaWQgLSBUaGUgdW5pcXVlIGlkZW50aWZpZXIgb2YgdGhlIGl0ZW0gdG8gYmUgcmVtb3ZlZCBmcm9tIHRoZSBxdWV1ZS5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogLy8gRXhhbXBsZSB1c2FnZVxuICAgICAqIHRoaXMucmVtb3ZlUXVldWVJdGVtKCdpdGVtMTIzJyk7XG4gICAgICogLy8gVGhlIGl0ZW0gd2l0aCBJRCAnaXRlbTEyMycgd2lsbCBiZSBkaXNwYXRjaGVkIGZvciByZW1vdmFsIGZyb20gdGhlIHF1ZXVlLlxuICAgICAqL1xuICAgIHJlbW92ZVF1ZXVlSXRlbShpZDogc3RyaW5nKTogdm9pZCB7XG4gICAgICAgIHRoaXMuc3RvcmUuZGlzcGF0Y2gobmV3IFJlbW92ZUFwaVF1ZXVlSXRlbUFjdGlvbihpZCkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENsZWFycyBhbGwgaXRlbXMgZnJvbSB0aGUgQVBJIHF1ZXVlLlxuICAgICAqXG4gICAgICogVGhpcyBtZXRob2QgZGlzcGF0Y2hlcyBhbiBhY3Rpb24gdG8gZW1wdHkgdGhlIGVudGlyZSBBUEkgcXVldWUsIGVmZmVjdGl2ZWx5IHJlbW92aW5nIGFsbCBpdGVtcyB0aGF0IGFyZSBjdXJyZW50bHkgcXVldWVkLlxuICAgICAqIEl0IGlzIHVzZWZ1bCBmb3Igc2NlbmFyaW9zIHdoZXJlIGEgY29tcGxldGUgcmVzZXQgb2YgdGhlIHF1ZXVlIGlzIHJlcXVpcmVkLCBzdWNoIGFzIGR1cmluZyBpbml0aWFsaXphdGlvbiBvciBhZnRlciBwcm9jZXNzaW5nXG4gICAgICogYSBiYXRjaCBvZiBpdGVtcy4gVGhlIGZ1bmN0aW9uIGRvZXMgbm90IHJldHVybiBhbnkgdmFsdWUsIGFzIGl0cyBwcmltYXJ5IHB1cnBvc2UgaXMgdG8gdHJpZ2dlciBhIHN0YXRlIGNoYW5nZSBpbiB0aGUgc3RvcmUuXG4gICAgICpcbiAgICAgKiBOb3RlOiBVc2UgdGhpcyBtZXRob2Qgd2l0aCBjYXV0aW9uIGFzIGl0IHdpbGwgaXJyZXZlcnNpYmx5IGNsZWFyIGFsbCBpdGVtcyBpbiB0aGUgcXVldWUuIEVuc3VyZSB0aGF0IHRoaXMgYWN0aW9uIGRvZXMgbm90XG4gICAgICogZGlzcnVwdCBhbnkgb25nb2luZyBwcm9jZXNzZXMgdGhhdCByZWx5IG9uIHRoZSBxdWV1ZSdzIGNvbnRlbnRzLlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiAvLyBFeGFtcGxlIHVzYWdlXG4gICAgICogdGhpcy5yZW1vdmVBbGxRdWV1ZUl0ZW0oKTtcbiAgICAgKiAvLyBUaGlzIHdpbGwgZGlzcGF0Y2ggYW4gYWN0aW9uIHRvIGVtcHR5IHRoZSBlbnRpcmUgQVBJIHF1ZXVlLlxuICAgICAqL1xuICAgIHJlbW92ZUFsbFF1ZXVlSXRlbSgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5zdG9yZS5kaXNwYXRjaChuZXcgRW1wdHlBcGlRdWV1ZUFjdGlvbihudWxsKSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUHJvY2Vzc2VzIGFuIGl0ZW0gZnJvbSB0aGUgQVBJIHF1ZXVlIGlkZW50aWZpZWQgYnkgaXRzIElELlxuICAgICAqXG4gICAgICogUmV0cmlldmVzIHRoZSBzcGVjaWZpZWQgaXRlbSBmcm9tIHRoZSBxdWV1ZSBhbmQgYXBwbGllcyBwcm9jZXNzaW5nIGxvZ2ljIGFzIGRlZmluZWQgaW4gYGJ1aWxkSHR0cFJlcXVlc3RgLlxuICAgICAqIElmIHRoZSBpdGVtIGlzIG5vdCBmb3VuZCwgbG9ncyBhIHdhcm5pbmcgYW5kIHJldHVybnMgYW4gT2JzZXJ2YWJsZSBlbWl0dGluZyBgbnVsbGAuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gaWQgLSBUaGUgdW5pcXVlIGlkZW50aWZpZXIgb2YgdGhlIGl0ZW0gd2l0aGluIHRoZSBxdWV1ZSB0byBiZSBwcm9jZXNzZWQuXG4gICAgICogQHJldHVybnMge09ic2VydmFibGU8YW55Pn0gQW4gT2JzZXJ2YWJsZSB0aGF0IGVtaXRzIHRoZSByZXN1bHQgb2YgcHJvY2Vzc2luZyB0aGUgcXVldWUgaXRlbS5cbiAgICAgKiBJZiB0aGUgaXRlbSBkb2VzIG5vdCBleGlzdCwgdGhlIE9ic2VydmFibGUgZW1pdHMgYG51bGxgLlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiAvLyBFeGFtcGxlIHVzYWdlXG4gICAgICogdGhpcy5wcm9jZXNzUXVldWVJdGVtKCdpdGVtMTIzJykuc3Vic2NyaWJlKHJlc3VsdCA9PiB7XG4gICAgICogICBpZiAocmVzdWx0KSB7XG4gICAgICogICAgIGNvbnNvbGUubG9nKCdQcm9jZXNzaW5nIHJlc3VsdDonLCByZXN1bHQpO1xuICAgICAqICAgfSBlbHNlIHtcbiAgICAgKiAgICAgY29uc29sZS5sb2coJ0l0ZW0gbm90IGZvdW5kIGluIHRoZSBxdWV1ZScpO1xuICAgICAqICAgfVxuICAgICAqIH0pO1xuICAgICAqL1xuICAgIC8vIFRPRE86IFJlcGxhY2UgYGFueWAgd2l0aCBhIG1vcmUgc3BlY2lmaWMgdHlwZSBvciBtYWtlIHRoZSBtZXRob2QgZ2VuZXJpYywgaHR0cHM6Ly93d3cudHlwZXNjcmlwdGxhbmcub3JnL2RvY3MvaGFuZGJvb2svMi9nZW5lcmljcy5odG1sXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcbiAgICBwcm9jZXNzUXVldWVJdGVtKGlkOiBzdHJpbmcpOiBPYnNlcnZhYmxlPGFueT4ge1xuICAgICAgICByZXR1cm4gdGhpcy5zdG9yZS5zZWxlY3QoZ2V0QXBpUXVldWVJdGVtKGlkKSkucGlwZShcbiAgICAgICAgICAgIHRha2UoMSksXG4gICAgICAgICAgICBzd2l0Y2hNYXAoKHF1ZXVlOiBBcGlRdWV1ZUl0ZW0pID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoIXF1ZXVlKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMubG9nU2VydmljZT8ud2FybihgUXVldWUgaXRlbSB3aXRoIGlkIFwiJHtpZH1cIiBkb2VzIG5vdCBleGlzdGApO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gb2YobnVsbCk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuYnVpbGRIdHRwUmVxdWVzdChpZCwgcXVldWUpO1xuICAgICAgICAgICAgfSksXG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUHJvY2Vzc2VzIGFsbCBpdGVtcyBpbiB0aGUgQVBJIHF1ZXVlIGFuZCBjb2xsZWN0cyB0aGVpciByZXNwb25zZXMuXG4gICAgICpcbiAgICAgKiBJdGVyYXRlcyBvdmVyIGVhY2ggaXRlbSBpbiB0aGUgcXVldWUgYW5kIHByb2Nlc3NlcyB0aGVtIHVzaW5nIGBidWlsZEh0dHBSZXF1ZXN0YC4gSWYgYSByZXF1ZXN0IGZhaWxzLFxuICAgICAqIHRoZSBtZXRob2QgY2FuIGVpdGhlciBjb250aW51ZSBwcm9jZXNzaW5nIHRoZSByZW1haW5pbmcgaXRlbXMgb3Igc3RvcCwgYmFzZWQgb24gdGhlIGBjb250aW51ZU9uRXJyb3JgIHBhcmFtZXRlci5cbiAgICAgKiBJdCByZXR1cm5zIGFuIE9ic2VydmFibGUgdGhhdCBlbWl0cyBhbiBhcnJheSBjb250YWluaW5nIHRoZSByZXNwb25zZXMgb3IgZXJyb3JzIGZyb20gYWxsIHRoZSBwcm9jZXNzZWQgaXRlbXMuXG4gICAgICpcbiAgICAgKiBUaGUgZnVuY3Rpb24gY3VycmVudGx5IHJldHVybnMgYE9ic2VydmFibGU8YW55W10+YCBpbmRpY2F0aW5nIGFuIGFycmF5IG9mIGFueSB0eXBlLiBGdXR1cmUgaW1wcm92ZW1lbnRzXG4gICAgICogc2hvdWxkIGFpbSB0byBzcGVjaWZ5IGEgbW9yZSBhY2N1cmF0ZSByZXR1cm4gdHlwZSBvciB1dGlsaXplIGdlbmVyaWNzIGZvciBpbmNyZWFzZWQgdHlwZSBzYWZldHkuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IFtjb250aW51ZU9uRXJyb3I9dHJ1ZV0gLSBEZXRlcm1pbmVzIHdoZXRoZXIgdG8gY29udGludWUgd2l0aCB0aGUgbmV4dCBpdGVtIGluIHRoZSBxdWV1ZVxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFmdGVyIGEgcmVxdWVzdCBmYWlsdXJlLiBEZWZhdWx0cyB0byBgdHJ1ZWAuXG4gICAgICogQHJldHVybnMge09ic2VydmFibGU8YW55W10+fSBBbiBPYnNlcnZhYmxlIGVtaXR0aW5nIGFuIGFycmF5IG9mIGVpdGhlciByZXNwb25zZXMgb3IgZXJyb3JzIGZyb20gdGhlIHByb2Nlc3NlZFxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcXVldWUgaXRlbXMuXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIHRoaXMucHJvY2Vzc0FsbFF1ZXVlSXRlbXMoKS5zdWJzY3JpYmUocmVzdWx0cyA9PiB7XG4gICAgICogICAvLyBIYW5kbGUgdGhlIGFycmF5IG9mIHJlc3BvbnNlcyBvciBlcnJvcnNcbiAgICAgKiB9KTtcbiAgICAgKi9cbiAgICAvLyBUT0RPOiBSZWZpbmUgdGhlIHJldHVybiB0eXBlIHRvIGJlIG1vcmUgc3BlY2lmaWMgb3IgaW1wbGVtZW50IGdlbmVyaWNzLCBodHRwczovL3d3dy50eXBlc2NyaXB0bGFuZy5vcmcvZG9jcy9oYW5kYm9vay8yL2dlbmVyaWNzLmh0bWxcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueVxuICAgIHByb2Nlc3NBbGxRdWV1ZUl0ZW1zPFQgPSBhbnk+KGNvbnRpbnVlT25FcnJvciA9IHRydWUpOiBPYnNlcnZhYmxlPFRbXT4ge1xuICAgICAgICByZXR1cm4gdGhpcy5zdG9yZS5zZWxlY3QoZ2V0QXBpUXVldWUpLnBpcGUoXG4gICAgICAgICAgICBtYXAoKHF1ZXVlOiBBcGlRdWV1ZSkgPT5cbiAgICAgICAgICAgICAgICBPYmplY3QuZW50cmllcyhxdWV1ZSkubWFwKChba2V5LCB2YWx1ZV0pID0+XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuYnVpbGRIdHRwUmVxdWVzdChrZXksIHZhbHVlKS5waXBlKFxuICAgICAgICAgICAgICAgICAgICAgICAgY2F0Y2hFcnJvcigoZXJyb3I6IEVycm9yKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5sb2dTZXJ2aWNlPy5lcnJvcihgUXVldWUgSXRlbSB3aXRoIGlkICR7a2V5fSBmYWlsZWQuYCwgZXJyb3IubWVzc2FnZSwgZXJyb3Iuc3RhY2spO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFjb250aW51ZU9uRXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG9mKGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICApLFxuICAgICAgICAgICAgc3dpdGNoTWFwKChvYnNRdWV1ZTogT2JzZXJ2YWJsZTxUPltdKSA9PiBmb3JrSm9pbihBcnJheS5mcm9tKG9ic1F1ZXVlKSkpLFxuICAgICAgICApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFByb2Nlc3NlcyBhbGwgaXRlbXMgaW4gdGhlIHF1ZXVlIHNlcXVlbnRpYWxseSwgYmFzZWQgb24gdGhlaXIgdGltZXN0YW1wIG9yZGVyaW5nLlxuICAgICAqXG4gICAgICogVGhpcyBtZXRob2QgZmlyc3Qgb3JkZXJzIHRoZSBpdGVtcyBpbiB0aGUgQVBJIHF1ZXVlIGJ5IHRoZWlyIHRpbWVzdGFtcCwgZWl0aGVyIGluIGFzY2VuZGluZyBvciBkZXNjZW5kaW5nXG4gICAgICogb3JkZXIgYXMgc3BlY2lmaWVkIGJ5IHRoZSBgYXNjZW5kaW5nYCBwYXJhbWV0ZXIuIEl0IHRoZW4gcHJvY2Vzc2VzIGVhY2ggaXRlbSB1c2luZyBgYnVpbGRIdHRwUmVxdWVzdGAsIGVuc3VyaW5nXG4gICAgICogdGhhdCBlYWNoIHJlcXVlc3QgaXMgY29tcGxldGVkIGJlZm9yZSB0aGUgbmV4dCBiZWdpbnMuIFRoaXMgc2VxdWVudGlhbCBwcm9jZXNzaW5nIGlzIGNydWNpYWwgd2hlbiB0aGUgb3JkZXIgb2ZcbiAgICAgKiBleGVjdXRpb24gbWF0dGVycyBmb3IgSFRUUCByZXF1ZXN0cyBpbiB0aGUgcXVldWUuIFRoZSBtZXRob2QgcmV0dXJucyBhbiBPYnNlcnZhYmxlIHRoYXQgZW1pdHMgdGhlIHJlc3BvbnNlc1xuICAgICAqIGZvbGxvd2luZyB0aGUgc2FtZSBvcmRlciBhcyB0aGUgcXVldWUgaXRlbXMgd2VyZSBwcm9jZXNzZWQuXG4gICAgICpcbiAgICAgKiBUaGUgZnVuY3Rpb24gY3VycmVudGx5IHJldHVybnMgYE9ic2VydmFibGU8YW55PmAsIGluZGljYXRpbmcgYSBicm9hZCB0eXBlLiBGdXR1cmUgaW1wcm92ZW1lbnRzIHNob3VsZCBmb2N1cyBvblxuICAgICAqIHNwZWNpZnlpbmcgYSBtb3JlIGFjY3VyYXRlIHJldHVybiB0eXBlIG9yIHV0aWxpemluZyBnZW5lcmljcyBmb3IgaW5jcmVhc2VkIHR5cGUgc2FmZXR5LlxuICAgICAqXG4gICAgICogQHBhcmFtIHtib29sZWFufSBbYXNjZW5kaW5nPXRydWVdIC0gRGV0ZXJtaW5lcyB3aGV0aGVyIHRoZSBxdWV1ZSBpdGVtcyBhcmUgcHJvY2Vzc2VkIGluIGFzY2VuZGluZyBvcmRlciBvZiB0aGVpclxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRpbWVzdGFtcC4gRGVmYXVsdHMgdG8gYHRydWVgLlxuICAgICAqIEByZXR1cm5zIHtPYnNlcnZhYmxlPGFueT59IEFuIE9ic2VydmFibGUgZW1pdHRpbmcgdGhlIHJlc3BvbnNlcyBvZiB0aGUgSFRUUCByZXF1ZXN0cyBpbiB0aGUgb3JkZXIgdGhleSB3ZXJlIHByb2Nlc3NlZC5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogdGhpcy5wcm9jZXNzQWxsUXVldWVJdGVtc1NlcXVlbnRpYWwoKS5zdWJzY3JpYmUocmVzcG9uc2UgPT4ge1xuICAgICAqICAgLy8gSGFuZGxlIGVhY2ggcmVzcG9uc2UgaW4gdGhlIG9yZGVyIG9mIHF1ZXVlIHByb2Nlc3NpbmdcbiAgICAgKiB9KTtcbiAgICAgKi9cbiAgICAvLyBUT0RPOiBSZWZpbmUgdGhlIHJldHVybiB0eXBlIGZvciBtb3JlIHNwZWNpZmljIG9yIGltcGxlbWVudCBnZW5lcmljcywgaHR0cHM6Ly93d3cudHlwZXNjcmlwdGxhbmcub3JnL2RvY3MvaGFuZGJvb2svMi9nZW5lcmljcy5odG1sXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcbiAgICBwcm9jZXNzQWxsUXVldWVJdGVtc1NlcXVlbnRpYWwoYXNjZW5kaW5nID0gdHJ1ZSk6IE9ic2VydmFibGU8YW55PiB7XG4gICAgICAgIHJldHVybiB0aGlzLnN0b3JlLnNlbGVjdChnZXRBcGlRdWV1ZSkucGlwZShcbiAgICAgICAgICAgIHN3aXRjaE1hcCgocXVldWU6IEFwaVF1ZXVlKSA9PlxuICAgICAgICAgICAgICAgIGZyb20oT2JqZWN0LmVudHJpZXMocXVldWUpXG4gICAgICAgICAgICAgICAgICAgIC5zb3J0KChhLCBiKSA9PiAoYXNjZW5kaW5nID8gdGhpcy5zb3J0T25UaW1lc3RhbXAoYSwgYikgOiB0aGlzLnNvcnRPblRpbWVzdGFtcChiLCBhKSkpXG4gICAgICAgICAgICAgICAgICAgIC5tYXAoKFtpZCwgaXRlbV0pID0+IHRoaXMuYnVpbGRIdHRwUmVxdWVzdChpZCwgaXRlbSkpKVxuICAgICAgICAgICAgICAgICAgICAucGlwZShjb25jYXRNYXAoeCA9PiB4KSksXG4gICAgICAgICAgICApLFxuICAgICAgICApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENvbXBhcmVzIHR3byBxdWV1ZSBpdGVtcyBiYXNlZCBvbiB0aGVpciB0aW1lc3RhbXAgYW5kIGRldGVybWluZXMgdGhlaXIgb3JkZXIuXG4gICAgICpcbiAgICAgKiBUaGlzIHByb3RlY3RlZCBtZXRob2QgaXMgdXNlZCB0byBzb3J0IHF1ZXVlIGl0ZW1zLiBJdCB0YWtlcyB0d28gcXVldWUgaXRlbXMgYXMgaW5wdXQsIGVhY2ggcmVwcmVzZW50ZWRcbiAgICAgKiBhcyBhIHR1cGxlIGNvbnRhaW5pbmcgYW4gaXRlbSBJRCBhbmQgdGhlIGBBcGlRdWV1ZUl0ZW1gIG9iamVjdC4gVGhlIG1ldGhvZCBjb21wYXJlcyB0aGVzZSBpdGVtcyBiYXNlZCBvblxuICAgICAqIHRoZSBgdGltZXN0YW1wYCBwcm9wZXJ0eSBvZiB0aGUgYEFwaVF1ZXVlSXRlbWAgb2JqZWN0cy4gSXQgcmV0dXJucyBhIG51bWJlciBpbmRpY2F0aW5nIHRoZSBvcmRlciBpbiB3aGljaFxuICAgICAqIHRoZXNlIGl0ZW1zIHNob3VsZCBiZSBzb3J0ZWQuXG4gICAgICpcbiAgICAgKiBBIHBvc2l0aXZlIHJldHVybiB2YWx1ZSBpbmRpY2F0ZXMgdGhhdCB0aGUgZmlyc3QgaXRlbSBzaG91bGQgY29tZSBhZnRlciB0aGUgc2Vjb25kLCBhIG5lZ2F0aXZlIHZhbHVlXG4gICAgICogaW5kaWNhdGVzIHRoZSBvcHBvc2l0ZSwgYW5kIHplcm8gaW5kaWNhdGVzIHRoYXQgdGhleSBhcmUgZXF1YWwgaW4gdGVybXMgb2YgdGltZXN0YW1wLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtbc3RyaW5nLCBBcGlRdWV1ZUl0ZW1dfSBhIC0gVGhlIGZpcnN0IHF1ZXVlIGl0ZW0gdHVwbGUgZm9yIGNvbXBhcmlzb24uXG4gICAgICogQHBhcmFtIHtbc3RyaW5nLCBBcGlRdWV1ZUl0ZW1dfSBiIC0gVGhlIHNlY29uZCBxdWV1ZSBpdGVtIHR1cGxlIGZvciBjb21wYXJpc29uLlxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IEEgbnVtYmVyIGluZGljYXRpbmcgdGhlIG9yZGVyIG9mIHRoZSBpdGVtczogbmVnYXRpdmUgaWYgYGFgIGlzIGVhcmxpZXIgdGhhbiBgYmAsXG4gICAgICogICAgICAgICAgICAgICAgICBwb3NpdGl2ZSBpZiBgYWAgaXMgbGF0ZXIgdGhhbiBgYmAsIGFuZCB6ZXJvIGlmIHRoZXkgYXJlIGVxdWFsLlxuICAgICAqIEBiZXRhXG4gICAgICovXG4gICAgcHJvdGVjdGVkIHNvcnRPblRpbWVzdGFtcChhOiBbc3RyaW5nLCBBcGlRdWV1ZUl0ZW1dLCBiOiBbc3RyaW5nLCBBcGlRdWV1ZUl0ZW1dKTogbnVtYmVyIHtcbiAgICAgICAgcmV0dXJuICtuZXcgRGF0ZShhWzFdLnRpbWVzdGFtcCkgLSArbmV3IERhdGUoYlsxXS50aW1lc3RhbXApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENvbnN0cnVjdHMgYW5kIGV4ZWN1dGVzIGFuIEhUVFAgcmVxdWVzdCBiYXNlZCBvbiB0aGUgcHJvdmlkZWQgcXVldWUgaXRlbSBkZXRhaWxzLlxuICAgICAqXG4gICAgICogVGhpcyBwcml2YXRlIG1ldGhvZCB0YWtlcyBhbiBJRCBhbmQgYW4gYEFwaVF1ZXVlSXRlbWAgb2JqZWN0IHRvIGJ1aWxkIGFuZCBleGVjdXRlIGFuIEhUVFAgcmVxdWVzdC5cbiAgICAgKiBJdCBkZXRlcm1pbmVzIHRoZSBIVFRQIG1ldGhvZCAobGlrZSBHRVQsIFBPU1QsIGV0Yy4pIGZyb20gdGhlIGBtZXRob2RgIHByb3BlcnR5IG9mIHRoZSBgQXBpUXVldWVJdGVtYCxcbiAgICAgKiBhbmQgdXNlcyB0aGUgYHVyaWAgYW5kIGBwYXlsb2FkYCBwcm9wZXJ0aWVzIGZvciB0aGUgcmVxdWVzdCdzIFVSTCBhbmQgYm9keSwgcmVzcGVjdGl2ZWx5LiBBZnRlciB0aGVcbiAgICAgKiByZXF1ZXN0IGlzIGV4ZWN1dGVkLCB0aGUgY29ycmVzcG9uZGluZyBxdWV1ZSBpdGVtIGlzIHJlbW92ZWQgZnJvbSB0aGUgcXVldWUuXG4gICAgICpcbiAgICAgKiBUaGUgbWV0aG9kIGlzIGdlbmVyaWMsIGFsbG93aW5nIHRoZSBjYWxsZXIgdG8gc3BlY2lmeSB0aGUgZXhwZWN0ZWQgcmVzcG9uc2UgdHlwZSBgVGAuIEJ5IGRlZmF1bHQsXG4gICAgICogaXQgdXNlcyBgYW55YCB0eXBlLCBidXQgc3BlY2lmeWluZyBhIG1vcmUgY29uY3JldGUgdHlwZSBlbmhhbmNlcyB0eXBlIHNhZmV0eSBhbmQgY2xhcml0eSBpbiB1c2FnZS5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBpZCAtIFRoZSBJRCBvZiB0aGUgcXVldWUgaXRlbSBiZWluZyBwcm9jZXNzZWQuXG4gICAgICogQHBhcmFtIHtBcGlRdWV1ZUl0ZW19IGl0ZW0gLSBUaGUgcXVldWUgaXRlbSBjb250YWluaW5nIGRldGFpbHMgZm9yIHRoZSBIVFRQIHJlcXVlc3QuXG4gICAgICogQHJldHVybnMge09ic2VydmFibGU8VD59IEFuIE9ic2VydmFibGUgb2YgdHlwZSBULCByZXByZXNlbnRpbmcgdGhlIHJlc3BvbnNlIG9mIHRoZSBIVFRQIHJlcXVlc3QuXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIC8vIEV4YW1wbGUgdXNhZ2UgZm9yIGEgc3BlY2lmaWMgcmVzcG9uc2UgdHlwZVxuICAgICAqIHRoaXMuYnVpbGRIdHRwUmVxdWVzdDxNeVJlc3BvbnNlVHlwZT4oJ2l0ZW0xMjMnLCBxdWV1ZUl0ZW0pXG4gICAgICogICAgIC5zdWJzY3JpYmUocmVzcG9uc2UgPT4ge1xuICAgICAqICAgICAgICAgLy8gSGFuZGxlIHRoZSByZXNwb25zZVxuICAgICAqICAgICB9KTtcbiAgICAgKlxuICAgICAqIEB0ZW1wbGF0ZSBUIC0gVGhlIGV4cGVjdGVkIHR5cGUgb2YgdGhlIEhUVFAgcmVzcG9uc2UuIERlZmF1bHRzIHRvIGBhbnlgLlxuICAgICAqL1xuICAgIC8vIFRPRE86IGFkZCB0eXBlIGZvciBUIGFuZCBkZXByZWNhdGUgb2xkIGZ1bmN0aW9uXG4gICAgLy8gVE9ETzogZmluZCB0aGUgY29ycmVjdCB0eXBlIG9yIHR1cm4gaW50byBhIGdlbmVyaWMsIGh0dHBzOi8vd3d3LnR5cGVzY3JpcHRsYW5nLm9yZy9kb2NzL2hhbmRib29rLzIvZ2VuZXJpY3MuaHRtbFxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55XG4gICAgcHJpdmF0ZSBidWlsZEh0dHBSZXF1ZXN0PFQgPSBhbnk+KGlkOiBzdHJpbmcsIGl0ZW06IEFwaVF1ZXVlSXRlbSk6IE9ic2VydmFibGU8VD4ge1xuICAgICAgICByZXR1cm4gdGhpcy5odHRwW2l0ZW0ubWV0aG9kLnRvTG93ZXJDYXNlKCldPFQ+KGl0ZW0udXJpLCBpdGVtLnBheWxvYWQpLnBpcGUodGFwKCgpID0+IHRoaXMucmVtb3ZlUXVldWVJdGVtKGlkKSkpO1xuICAgIH1cbn1cbiJdfQ==