UNPKG

ehandler

Version:

Exception handler for Angular Applications

448 lines (438 loc) 38.2 kB
(function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@angular/core'), require('@angular/common/http'), require('rxjs/operators'), require('toastr'), require('@angular/platform-browser/animations')) : typeof define === 'function' && define.amd ? define('ehandler', ['exports', '@angular/core', '@angular/common/http', 'rxjs/operators', 'toastr', '@angular/platform-browser/animations'], factory) : (factory((global.ehandler = {}),global.ng.core,global.ng.common.http,global.rxjs.operators,null,global.ng.platformBrowser.animations)); }(this, (function (exports,i0,http,operators,toastr,animations) { 'use strict'; /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ var HookService = (function () { function HookService(http$$1, config) { this.http = http$$1; this.config = config; } /** * Send Message */ /** * Send Message * @param {?} payload * @return {?} */ HookService.prototype.sendMessage = /** * Send Message * @param {?} payload * @return {?} */ function (payload) { this.http.post(this.config.hook, payload, { observe: 'response', responseType: 'text' }).subscribe(function (response) { console.info('Message sent'); }); }; /** * Send Exception to hook */ /** * Send Exception to hook * @param {?} error * @param {?=} couse * @return {?} */ HookService.prototype.exceptionNotify = /** * Send Exception to hook * @param {?} error * @param {?=} couse * @return {?} */ function (error, couse) { var _this = this; if (couse === void 0) { couse = ''; } /** @type {?} */ var status = error.status ? error.status : 'Application Error'; /** * * Error Payload @type {?} */ var payload = { text: '--------------------------[ ' + status + ' ]--------------------------', attachments: [ { author_name: 'Cause: ' + couse + '\nURL: ' + window.location.href, title: 'Message: ' + error.message, text: 'Date: ' + new Date() + '\nUserAgent: ' + navigator.userAgent + '\n---------------------------------------------------------' } ] }; if (!this.bugged) { /** @type {?} */ var headers = new http.HttpHeaders({ 'Content-Type': 'text/plain' }); this.http.post(this.config.hook, JSON.stringify(payload), { observe: 'response', responseType: 'text', headers: headers }) .pipe(operators.catchError(function (e) { _this.bugged = true; console.log('Hook stopped working'); throw e; })) .subscribe(function (response) { console.log('Exception Sent'); }); } }; HookService.decorators = [ { type: i0.Injectable }, ]; /** @nocollapse */ HookService.ctorParameters = function () { return [ { type: http.HttpClient }, { type: undefined, decorators: [{ type: i0.Inject, args: ['configurations',] }] } ]; }; return HookService; }()); /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ var EHandlerService = (function () { function EHandlerService(injector, config, hook) { this.injector = injector; this.config = config; this.hook = hook; } /** * Global Error Handler */ /** * Global Error Handler * @param {?} error * @return {?} */ EHandlerService.prototype.handleError = /** * Global Error Handler * @param {?} error * @return {?} */ function (error) { /** * * Error Message for view @type {?} */ var message; /** * * Error TimeStamp @type {?} */ var date = new Date(); /** * Handle errors occured while making server call */ if (error instanceof http.HttpErrorResponse) { message = this.config.message.statusException; /** * If UnAuthorized * Else If Server Error */ switch (error.status) { case 400: case 401: this.logout(); break; case 500: message = this.config.message.serverException; } // Backend returns unsuccessful response codes such as 404, 500 etc. this.statusMessage(error, date); } else { // A client-side or network error occurred. this.commonMessage(error, date); message = this.config.message.appException; } this.errorMSG(message); }; /** * Logout of system */ /** * Logout of system * @param {?=} message * @return {?} */ EHandlerService.prototype.logout = /** * Logout of system * @param {?=} message * @return {?} */ function (message) { var _this = this; toastr.error(this.config.message.unAuthenticated); if (message) { toastr.error(message); } setTimeout(function () { window.location.replace(_this.config.logout); }, 5000); }; /** * Show Error Message */ /** * Show Error Message * @param {?} message * @param {?=} code * @return {?} */ EHandlerService.prototype.errorMSG = /** * Show Error Message * @param {?} message * @param {?=} code * @return {?} */ function (message, code) { if (code === void 0) { code = null; } toastr.error(message, code); }; /** * Log Error Message */ /** * Log Error Message * @param {?} error * @param {?=} date * @return {?} */ EHandlerService.prototype.statusMessage = /** * Log Error Message * @param {?} error * @param {?=} date * @return {?} */ function (error, date) { if (date === void 0) { date = new Date(); } console.error('--------------------------------------------\n', 'Backend returned status code: ' + error.status + '\n', 'Response body ehandler:' + error.message + '\n', date + '\n', '--------------------------------------------'); this.hook.exceptionNotify(error.message, '----HTTP Error----'); }; /** * Log Common Error */ /** * Log Common Error * @param {?} error * @param {?=} date * @return {?} */ EHandlerService.prototype.commonMessage = /** * Log Common Error * @param {?} error * @param {?=} date * @return {?} */ function (error, date) { if (date === void 0) { date = new Date(); } console.error('--------------------------------------------\n', 'An error occurred ehandler:' + error.message + '\n', date + '\n', '--------------------------------------------'); this.hook.exceptionNotify(error.message, '----Common Error----'); }; EHandlerService.decorators = [ { type: i0.Injectable, args: [{ providedIn: 'root' },] }, ]; /** @nocollapse */ EHandlerService.ctorParameters = function () { return [ { type: i0.Injector }, { type: undefined, decorators: [{ type: i0.Inject, args: ['configurations',] }] }, { type: HookService } ]; }; /** @nocollapse */ EHandlerService.ngInjectableDef = i0.defineInjectable({ factory: function EHandlerService_Factory() { return new EHandlerService(i0.inject(i0.INJECTOR), i0.inject("configurations"), i0.inject(HookService)); }, token: EHandlerService, providedIn: "root" }); return EHandlerService; }()); /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ var EIntercepterService = (function () { function EIntercepterService(config, eh) { this.config = config; this.eh = eh; } /** * @param {?} req * @param {?} next * @return {?} */ EIntercepterService.prototype.intercept = /** * @param {?} req * @param {?} next * @return {?} */ function (req, next) { var _this = this; return next.handle(req).pipe(operators.map(function (event) { if (event instanceof http.HttpResponse) { /** @type {?} */ var requestData = event.body; if (requestData) { if (requestData.exception && requestData.exception.code) { try { if (_this.config && _this.config.logoutCodes && _this.config.logoutCodes.indexOf(requestData.exception.code) !== -1) { _this.eh.logout(); } else { /** @type {?} */ var error = { code: requestData.exception.code, message: requestData.exception.message }; _this.eh.errorMSG(error.message, error.code); _this.eh.statusMessage(error); } } catch (e) { console.log('There was an error while trying to send message'); } } else if (requestData.error && requestData.error.code) { try { if (_this.config && _this.config.logoutCodes && _this.config.logoutCodes.indexOf(requestData.error.code) !== -1) { _this.eh.logout(); } else { /** @type {?} */ var error = { code: requestData.error.code, message: requestData.error.message }; _this.eh.errorMSG(error.message, error.code); _this.eh.statusMessage(error); } } catch (e) { console.log('There was an error while trying to send message'); } } } } return event; }), operators.catchError(function (error) { _this.eh.handleError(error); throw error; }), operators.finalize(function () { })); }; EIntercepterService.decorators = [ { type: i0.Injectable }, ]; /** @nocollapse */ EIntercepterService.ctorParameters = function () { return [ { type: undefined, decorators: [{ type: i0.Inject, args: ['configurations',] }] }, { type: EHandlerService } ]; }; return EIntercepterService; }()); /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ /** @type {?} */ var InitialConfig = { message: { unAuthenticated: 'Xahiş olunur sistemə daxil olun!', statusException: 'Status xətası', serverException: 'Server xətası', appException: 'Sistem xətası' }, logout: '/logout', logoutCodes: [ 401, 1005, 1006, 1014, 1015, 1016, 1017, 1401, ], hook: 'https://hooks.slack.com/services/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', }; var EHandlerModule = (function () { function EHandlerModule() { } /** * @param {?=} configurations * @return {?} */ EHandlerModule.forRoot = /** * @param {?=} configurations * @return {?} */ function (configurations) { if (configurations === void 0) { configurations = InitialConfig; } return { ngModule: EHandlerModule, providers: [ { provide: 'configurations', useValue: configurations }, ], }; }; /** * @return {?} */ EHandlerModule.forChild = /** * @return {?} */ function () { return { ngModule: EHandlerModule, }; }; EHandlerModule.decorators = [ { type: i0.NgModule, args: [{ imports: [ http.HttpClientModule, animations.BrowserAnimationsModule ], providers: [ { provide: i0.ErrorHandler, useClass: EHandlerService }, { provide: http.HTTP_INTERCEPTORS, useClass: EIntercepterService, multi: true }, HookService ], declarations: [], exports: [] },] }, ]; return EHandlerModule; }()); /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ exports.EHandlerService = EHandlerService; exports.EIntercepterService = EIntercepterService; exports.InitialConfig = InitialConfig; exports.EHandlerModule = EHandlerModule; exports.ɵb = HookService; Object.defineProperty(exports, '__esModule', { value: true }); }))); //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWhhbmRsZXIudW1kLmpzLm1hcCIsInNvdXJjZXMiOlsibmc6Ly9laGFuZGxlci9saWIvaG9vay5zZXJ2aWNlLnRzIiwibmc6Ly9laGFuZGxlci9saWIvZWhhbmRsZXIuc2VydmljZS50cyIsIm5nOi8vZWhhbmRsZXIvbGliL2VpbnRlcmNlcHRlci5zZXJ2aWNlLnRzIiwibmc6Ly9laGFuZGxlci9saWIvZWhhbmRsZXIubW9kdWxlLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7SW5qZWN0LCBJbmplY3RhYmxlfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHtIdHRwQ2xpZW50LCBIdHRwSGVhZGVyc30gZnJvbSAnQGFuZ3VsYXIvY29tbW9uL2h0dHAnO1xyXG5pbXBvcnQge0NvbmZpZ30gZnJvbSAnLi9jb25zdC9jb25maWcnO1xyXG5pbXBvcnQge2NhdGNoRXJyb3IsIG1hcH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xyXG5cclxuQEluamVjdGFibGUoKVxyXG5cclxuZXhwb3J0IGNsYXNzIEhvb2tTZXJ2aWNlIHtcclxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIGh0dHA6IEh0dHBDbGllbnQsIEBJbmplY3QoJ2NvbmZpZ3VyYXRpb25zJykgcHJpdmF0ZSBjb25maWc6IENvbmZpZykge31cclxuICBwcml2YXRlIGJ1Z2dlZDogYm9vbGVhbjtcclxuICAvKipcclxuICAgKiBTZW5kIE1lc3NhZ2VcclxuICAgKi9cclxuICBzZW5kTWVzc2FnZShwYXlsb2FkOiBhbnkpIHtcclxuICAgIHRoaXMuaHR0cC5wb3N0KHRoaXMuY29uZmlnLmhvb2ssIHBheWxvYWQsIHtvYnNlcnZlOiAncmVzcG9uc2UnLCByZXNwb25zZVR5cGU6ICd0ZXh0J30pLnN1YnNjcmliZSggcmVzcG9uc2UgPT4ge1xyXG4gICAgICBjb25zb2xlLmluZm8oJ01lc3NhZ2Ugc2VudCcpO1xyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiAgU2VuZCBFeGNlcHRpb24gdG8gaG9va1xyXG4gICAqL1xyXG4gIGV4Y2VwdGlvbk5vdGlmeShlcnJvciwgY291c2UgPSAnJykge1xyXG4gICAgY29uc3Qgc3RhdHVzID0gZXJyb3Iuc3RhdHVzID8gZXJyb3Iuc3RhdHVzIDogJ0FwcGxpY2F0aW9uIEVycm9yJztcclxuICAgIC8qKlxyXG4gICAgICogRXJyb3IgUGF5bG9hZFxyXG4gICAgICovXHJcbiAgICBjb25zdCBwYXlsb2FkID0ge1xyXG4gICAgICB0ZXh0OiAnLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1bICcgKyBzdGF0dXMgKyAnIF0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLScsXHJcbiAgICAgIGF0dGFjaG1lbnRzOiBbXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgYXV0aG9yX25hbWU6ICdDYXVzZTogJyArIGNvdXNlICsgJ1xcblVSTDogJyArIHdpbmRvdy5sb2NhdGlvbi5ocmVmLFxyXG4gICAgICAgICAgdGl0bGU6ICdNZXNzYWdlOiAnICsgZXJyb3IubWVzc2FnZSxcclxuICAgICAgICAgIHRleHQ6ICdEYXRlOiAnICsgbmV3IERhdGUoKSArICdcXG5Vc2VyQWdlbnQ6ICcgKyBuYXZpZ2F0b3IudXNlckFnZW50ICtcclxuICAgICAgICAgICdcXG4tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0nXHJcbiAgICAgICAgfVxyXG4gICAgICBdXHJcbiAgICB9O1xyXG4gICAgaWYgKCF0aGlzLmJ1Z2dlZCkge1xyXG4gICAgICBjb25zdCBoZWFkZXJzID0gbmV3IEh0dHBIZWFkZXJzKHtcclxuICAgICAgICAnQ29udGVudC1UeXBlJzogJ3RleHQvcGxhaW4nXHJcbiAgICAgIH0pXHJcbiAgICAgIHRoaXMuaHR0cC5wb3N0KHRoaXMuY29uZmlnLmhvb2ssIEpTT04uc3RyaW5naWZ5KHBheWxvYWQpLCB7b2JzZXJ2ZTogJ3Jlc3BvbnNlJywgcmVzcG9uc2VUeXBlOiAndGV4dCcsIGhlYWRlcnN9KVxyXG4gICAgICAgIC5waXBlKFxyXG4gICAgICAgICAgY2F0Y2hFcnJvcihlID0+IHtcclxuICAgICAgICAgICAgdGhpcy5idWdnZWQgPSB0cnVlO1xyXG4gICAgICAgICAgICBjb25zb2xlLmxvZygnSG9vayBzdG9wcGVkIHdvcmtpbmcnKTtcclxuICAgICAgICAgICAgdGhyb3cgZTtcclxuICAgICAgICAgIH0pXHJcbiAgICAgICAgKVxyXG4gICAgICAgIC5zdWJzY3JpYmUoIHJlc3BvbnNlID0+IHtcclxuICAgICAgICAgIGNvbnNvbGUubG9nKCdFeGNlcHRpb24gU2VudCcpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICB9XHJcbn1cclxuIiwiaW1wb3J0IHtFcnJvckhhbmRsZXIsIEluamVjdCwgSW5qZWN0YWJsZSwgSW5qZWN0b3J9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQge0h0dHBFcnJvclJlc3BvbnNlfSBmcm9tICdAYW5ndWxhci9jb21tb24vaHR0cCc7XHJcbmltcG9ydCB7Q29uZmlnfSBmcm9tICcuL2NvbnN0L2NvbmZpZyc7XHJcbmltcG9ydCB7SG9va1NlcnZpY2V9IGZyb20gJy4vaG9vay5zZXJ2aWNlJztcclxuaW1wb3J0ICogYXMgdG9hc3RyIGZyb20gJ3RvYXN0cic7XHJcbkBJbmplY3RhYmxlKHtcclxuICBwcm92aWRlZEluOiAncm9vdCdcclxufSlcclxuZXhwb3J0IGNsYXNzIEVIYW5kbGVyU2VydmljZSBpbXBsZW1lbnRzIEVycm9ySGFuZGxlciB7XHJcbiAgY29uc3RydWN0b3IoXHJcbiAgICBwcml2YXRlIGluamVjdG9yOiBJbmplY3RvcixcclxuICAgIEBJbmplY3QoJ2NvbmZpZ3VyYXRpb25zJykgcHJpdmF0ZSBjb25maWc6IENvbmZpZyxcclxuICAgIHByaXZhdGUgaG9vazogSG9va1NlcnZpY2UsXHJcbiAgKSB7XHJcbiAgfVxyXG4gIC8qKlxyXG4gICAqIEdsb2JhbCBFcnJvciBIYW5kbGVyXHJcbiAgICovXHJcbiAgaGFuZGxlRXJyb3IoZXJyb3I6IGFueSkge1xyXG4gICAgLyoqXHJcbiAgICAgKiBFcnJvciBNZXNzYWdlIGZvciB2aWV3XHJcbiAgICAgKi9cclxuICAgIGxldCBtZXNzYWdlOiBzdHJpbmc7XHJcbiAgICAvKipcclxuICAgICAqIEVycm9yIFRpbWVTdGFtcFxyXG4gICAgICovXHJcbiAgICBjb25zdCBkYXRlOiBEYXRlID0gbmV3IERhdGUoKTtcclxuICAgIC8qKlxyXG4gICAgICogSGFuZGxlIGVycm9ycyBvY2N1cmVkIHdoaWxlIG1ha2luZyBzZXJ2ZXIgY2FsbFxyXG4gICAgICovXHJcbiAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBIdHRwRXJyb3JSZXNwb25zZSkge1xyXG4gICAgICBtZXNzYWdlID0gdGhpcy5jb25maWcubWVzc2FnZS5zdGF0dXNFeGNlcHRpb247XHJcbiAgICAgIC8qKlxyXG4gICAgICAgKiBJZiBVbkF1dGhvcml6ZWRcclxuICAgICAgICogRWxzZSBJZiBTZXJ2ZXIgRXJyb3JcclxuICAgICAgICovXHJcbiAgICAgIHN3aXRjaCAoZXJyb3Iuc3RhdHVzKSB7XHJcbiAgICAgICAgY2FzZSA0MDA6XHJcbiAgICAgICAgY2FzZSA0MDE6XHJcbiAgICAgICAgICB0aGlzLmxvZ291dCgpO1xyXG4gICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgY2FzZSA1MDA6XHJcbiAgICAgICAgICBtZXNzYWdlID0gdGhpcy5jb25maWcubWVzc2FnZS5zZXJ2ZXJFeGNlcHRpb247XHJcbiAgICAgIH1cclxuICAgICAgLy8gQmFja2VuZCByZXR1cm5zIHVuc3VjY2Vzc2Z1bCByZXNwb25zZSBjb2RlcyBzdWNoIGFzIDQwNCwgNTAwIGV0Yy5cclxuICAgICAgdGhpcy5zdGF0dXNNZXNzYWdlKGVycm9yLCBkYXRlKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIC8vIEEgY2xpZW50LXNpZGUgb3IgbmV0d29yayBlcnJvciBvY2N1cnJlZC5cclxuICAgICAgdGhpcy5jb21tb25NZXNzYWdlKGVycm9yLCBkYXRlKTtcclxuICAgICAgbWVzc2FnZSA9IHRoaXMuY29uZmlnLm1lc3NhZ2UuYXBwRXhjZXB0aW9uO1xyXG4gICAgfVxyXG4gICAgdGhpcy5lcnJvck1TRyhtZXNzYWdlKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIExvZ291dCBvZiBzeXN0ZW1cclxuICAgKi9cclxuICBsb2dvdXQobWVzc2FnZT86IHN0cmluZykge1xyXG4gICAgdG9hc3RyLmVycm9yKHRoaXMuY29uZmlnLm1lc3NhZ2UudW5BdXRoZW50aWNhdGVkKTtcclxuICAgIGlmIChtZXNzYWdlKSB7XHJcbiAgICAgIHRvYXN0ci5lcnJvcihtZXNzYWdlKTtcclxuICAgIH1cclxuICAgIHNldFRpbWVvdXQoKCkgPT4ge1xyXG4gICAgICB3aW5kb3cubG9jYXRpb24ucmVwbGFjZSh0aGlzLmNvbmZpZy5sb2dvdXQpO1xyXG4gICAgfSwgNTAwMCk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBTaG93IEVycm9yIE1lc3NhZ2VcclxuICAgKi9cclxuICBlcnJvck1TRyhtZXNzYWdlLCBjb2RlID0gbnVsbCkge1xyXG4gICAgdG9hc3RyLmVycm9yKG1lc3NhZ2UsIGNvZGUpO1xyXG4gIH1cclxuICAvKipcclxuICAgKiBMb2cgRXJyb3IgTWVzc2FnZVxyXG4gICAqL1xyXG4gIHN0YXR1c01lc3NhZ2UoZXJyb3IsIGRhdGUgPSBuZXcgRGF0ZSgpKSB7XHJcbiAgICBjb25zb2xlLmVycm9yKFxyXG4gICAgICAnLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cXG4nLFxyXG4gICAgICAnQmFja2VuZCByZXR1cm5lZCBzdGF0dXMgY29kZTogJyArIGVycm9yLnN0YXR1cyArICdcXG4nLFxyXG4gICAgICAnUmVzcG9uc2UgYm9keSBlaGFuZGxlcjonICsgZXJyb3IubWVzc2FnZSArICdcXG4nLFxyXG4gICAgICBkYXRlICsgJ1xcbicsXHJcbiAgICAgICctLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSdcclxuICAgICk7XHJcbiAgICAgIHRoaXMuaG9vay5leGNlcHRpb25Ob3RpZnkoZXJyb3IubWVzc2FnZSwgJy0tLS1IVFRQIEVycm9yLS0tLScpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogTG9nIENvbW1vbiBFcnJvclxyXG4gICAqL1xyXG4gIGNvbW1vbk1lc3NhZ2UoZXJyb3IsIGRhdGUgPSBuZXcgRGF0ZSgpKSB7XHJcbiAgICBjb25zb2xlLmVycm9yKFxyXG4gICAgICAnLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cXG4nLFxyXG4gICAgICAnQW4gZXJyb3Igb2NjdXJyZWQgZWhhbmRsZXI6JyArIGVycm9yLm1lc3NhZ2UgKyAnXFxuJyxcclxuICAgICAgZGF0ZSArICdcXG4nLFxyXG4gICAgICAnLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0nXHJcbiAgICApO1xyXG4gICAgdGhpcy5ob29rLmV4Y2VwdGlvbk5vdGlmeShlcnJvci5tZXNzYWdlLCAnLS0tLUNvbW1vbiBFcnJvci0tLS0nKTtcclxuICB9XHJcbn1cclxuIiwiaW1wb3J0IHtJbmplY3QsIEluamVjdGFibGV9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHtIdHRwRXZlbnQsIEh0dHBIYW5kbGVyLCBIdHRwSW50ZXJjZXB0b3IsIEh0dHBSZXF1ZXN0LCBIdHRwUmVzcG9uc2V9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbi9odHRwJztcbmltcG9ydCB7T2JzZXJ2YWJsZX0gZnJvbSAncnhqcyc7XG5pbXBvcnQge2NhdGNoRXJyb3IsIGZpbmFsaXplLCBtYXB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCB7Q29uZmlnfSBmcm9tICcuL2NvbnN0L2NvbmZpZyc7XG5pbXBvcnQge0VIYW5kbGVyU2VydmljZX0gZnJvbSAnLi9laGFuZGxlci5zZXJ2aWNlJztcblxuQEluamVjdGFibGUoKVxuZXhwb3J0IGNsYXNzIEVJbnRlcmNlcHRlclNlcnZpY2UgaW1wbGVtZW50cyBIdHRwSW50ZXJjZXB0b3Ige1xuICBjb25zdHJ1Y3RvcihASW5qZWN0KCdjb25maWd1cmF0aW9ucycpIHByaXZhdGUgY29uZmlnOiBDb25maWcsIHByaXZhdGUgZWg6IEVIYW5kbGVyU2VydmljZSkgeyB9XG4gIGludGVyY2VwdChcbiAgICByZXE6IEh0dHBSZXF1ZXN0PGFueT4sXG4gICAgbmV4dDogSHR0cEhhbmRsZXJcbiAgKTogT2JzZXJ2YWJsZTxIdHRwRXZlbnQ8YW55Pj4ge1xuICAgIHJldHVybiBuZXh0LmhhbmRsZShyZXEpLnBpcGUoXG4gICAgICBtYXAoZXZlbnQgPT4ge1xuICAgICAgICBpZiAoZXZlbnQgaW5zdGFuY2VvZiBIdHRwUmVzcG9uc2UpIHtcbiAgICAgICAgICBjb25zdCByZXF1ZXN0RGF0YSA9IGV2ZW50LmJvZHk7XG4gICAgICAgICAgaWYgKHJlcXVlc3REYXRhKSB7XG4gICAgICAgICAgICBpZiAocmVxdWVzdERhdGEuZXhjZXB0aW9uICYmIHJlcXVlc3REYXRhLmV4Y2VwdGlvbi5jb2RlKSB7XG4gICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuY29uZmlnICYmIHRoaXMuY29uZmlnLmxvZ291dENvZGVzICYmIHRoaXMuY29uZmlnLmxvZ291dENvZGVzLmluZGV4T2YocmVxdWVzdERhdGEuZXhjZXB0aW9uLmNvZGUpICE9PSAtMSApIHtcbiAgICAgICAgICAgICAgICAgIHRoaXMuZWgubG9nb3V0KCk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgIGNvbnN0IGVycm9yID0ge1xuICAgICAgICAgICAgICAgICAgICBjb2RlOiByZXF1ZXN0RGF0YS5leGNlcHRpb24uY29kZSxcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZTogcmVxdWVzdERhdGEuZXhjZXB0aW9uLm1lc3NhZ2VcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIHRoaXMuZWguZXJyb3JNU0coZXJyb3IubWVzc2FnZSwgZXJyb3IuY29kZSk7XG4gICAgICAgICAgICAgICAgICB0aGlzLmVoLnN0YXR1c01lc3NhZ2UoZXJyb3IpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKCdUaGVyZSB3YXMgYW4gZXJyb3Igd2hpbGUgdHJ5aW5nIHRvIHNlbmQgbWVzc2FnZScpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHJlcXVlc3REYXRhLmVycm9yICYmIHJlcXVlc3REYXRhLmVycm9yLmNvZGUpIHtcbiAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5jb25maWcgJiYgdGhpcy5jb25maWcubG9nb3V0Q29kZXMgJiYgdGhpcy5jb25maWcubG9nb3V0Q29kZXMuaW5kZXhPZihyZXF1ZXN0RGF0YS5lcnJvci5jb2RlKSAhPT0gLTEgKSB7XG4gICAgICAgICAgICAgICAgICB0aGlzLmVoLmxvZ291dCgpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICBjb25zdCBlcnJvciA9IHtcbiAgICAgICAgICAgICAgICAgICAgY29kZTogcmVxdWVzdERhdGEuZXJyb3IuY29kZSxcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZTogcmVxdWVzdERhdGEuZXJyb3IubWVzc2FnZVxuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgdGhpcy5laC5lcnJvck1TRyhlcnJvci5tZXNzYWdlLCBlcnJvci5jb2RlKTtcbiAgICAgICAgICAgICAgICAgIHRoaXMuZWguc3RhdHVzTWVzc2FnZShlcnJvcik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2coJ1RoZXJlIHdhcyBhbiBlcnJvciB3aGlsZSB0cnlpbmcgdG8gc2VuZCBtZXNzYWdlJyk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGV2ZW50O1xuICAgICAgfSksXG4gICAgICBjYXRjaEVycm9yKGVycm9yID0+IHtcbiAgICAgICAgdGhpcy5laC5oYW5kbGVFcnJvcihlcnJvcik7XG4gICAgICAgIHRocm93IGVycm9yO1xuICAgICAgfSksXG4gICAgICBmaW5hbGl6ZSgoKSA9PiB7fSlcbiAgICApO1xuICB9XG59XG4iLCJpbXBvcnQge0Vycm9ySGFuZGxlciwgTW9kdWxlV2l0aFByb3ZpZGVycywgTmdNb2R1bGV9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHtDb25maWd9IGZyb20gJy4vY29uc3QvY29uZmlnJztcbmltcG9ydCB7RUludGVyY2VwdGVyU2VydmljZX0gZnJvbSAnLi9laW50ZXJjZXB0ZXIuc2VydmljZSc7XG5pbXBvcnQge0VIYW5kbGVyU2VydmljZX0gZnJvbSAnLi9laGFuZGxlci5zZXJ2aWNlJztcbmltcG9ydCB7SFRUUF9JTlRFUkNFUFRPUlMsIEh0dHBDbGllbnRNb2R1bGV9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbi9odHRwJztcbmltcG9ydCB7QnJvd3NlckFuaW1hdGlvbnNNb2R1bGV9IGZyb20gJ0Bhbmd1bGFyL3BsYXRmb3JtLWJyb3dzZXIvYW5pbWF0aW9ucyc7XG5pbXBvcnQge0hvb2tTZXJ2aWNlfSBmcm9tICcuL2hvb2suc2VydmljZSc7XG5cbmV4cG9ydCBjb25zdCBJbml0aWFsQ29uZmlnOiBDb25maWcgPSB7XG4gIG1lc3NhZ2U6IHtcbiAgICB1bkF1dGhlbnRpY2F0ZWQ6ICdYYWhpw4XCnyBvbHVudXIgc2lzdGVtw4nCmSBkYXhpbCBvbHVuIScsXG4gICAgc3RhdHVzRXhjZXB0aW9uOiAnU3RhdHVzIHjDicKZdGFzw4TCsScsXG4gICAgc2VydmVyRXhjZXB0aW9uOiAnU2VydmVyIHjDicKZdGFzw4TCsScsXG4gICAgYXBwRXhjZXB0aW9uOiAnU2lzdGVtIHjDicKZdGFzw4TCsSdcbiAgfSxcbiAgbG9nb3V0OiAnL2xvZ291dCcsXG4gIGxvZ291dENvZGVzOiBbXG4gICAgNDAxLCAgLy8gQnUgw4PCvG52YW5hIGljYXrDicKZbml6IHlveGR1clxuICAgIDEwMDUsIC8vIFlvdSBhcmUgbm90IGFsbG93ZWQgdG8gcmVxdWVzdCB0aGlzIHJlc291cmNlXG4gICAgMTAwNiwgLy8gVG9rZW4gdGFww4TCsWxtYWTDhMKxXG4gICAgMTAxNCwgLy8gVG9rZW4gdGFww4TCsWxtYWTDhMKxLCB6w4nCmWhtw4nCmXQgb2xtYXNhIHNpc3RlbcOJwpkgeWVuaWTDicKZbiBkYXhpbCBvbHVuXG4gICAgMTAxNSwgLy8gU2l6aW4gc2lzdGVtbMOJwplyZMOJwpluIGlzdGlmw4nCmWTDicKZIGjDg8K8cXVxdW51eiB5b3hkdXJcbiAgICAxMDE2LCAvLyBTaXppbiBidSBzaXN0ZW3DicKZIGlzdGlmw4nCmWTDicKZIGjDg8K8cXVxdW51eiB5b3hkdXJcbiAgICAxMDE3LCAvLyBTZXNzaXlhIGJhw4TCn2xhbm3DhMKxw4XCn2TDhMKxciwgesOJwplobcOJwpl0IG9sbWFzYSBzaXN0ZW3DicKZIHllbmlkw4nCmW4gZGF4aWwgb2x1bi5cbiAgICAxNDAxLCAvLyBTZXNzaXlhIG3Dg8K8ZGTDicKZdGkgYml0bWnDhcKfZGlyLCB6w4nCmWhtw4nCmXQgb2xtYXpzYSBzaXN0ZW3DicKZIHllbmlkw4nCmW4gZGF4aWwgb2x1blxuICAgIC8vIDE0MDIgIC8vIFNpemluIGJ1IHNlcnZpc8OJwpkgaWNhesOJwpluaXogeW94ZHVyXG4gIF0sXG4gIGhvb2s6ICdodHRwczovL2hvb2tzLnNsYWNrLmNvbS9zZXJ2aWNlcy9UQzEwR0g0OFovQkMyQTI5WTJaL3RweFYwaUlIaGoyZlRTNkZPMFBBMUN6YycsXG59XG5cbkBOZ01vZHVsZSh7XG4gIGltcG9ydHM6IFtcbiAgICBIdHRwQ2xpZW50TW9kdWxlLFxuICAgIEJyb3dzZXJBbmltYXRpb25zTW9kdWxlXG4gIF0sXG4gIHByb3ZpZGVyczogW1xuICAgIHsgcHJvdmlkZTogRXJyb3JIYW5kbGVyLCB1c2VDbGFzczogRUhhbmRsZXJTZXJ2aWNlIH0sXG4gICAge1xuICAgICAgcHJvdmlkZTogSFRUUF9JTlRFUkNFUFRPUlMsXG4gICAgICB1c2VDbGFzczogRUludGVyY2VwdGVyU2VydmljZSxcbiAgICAgIG11bHRpOiB0cnVlXG4gICAgfSxcbiAgICBIb29rU2VydmljZVxuICBdLFxuICBkZWNsYXJhdGlvbnM6IFtdLFxuICBleHBvcnRzOiBbXVxufSlcbmV4cG9ydCBjbGFzcyBFSGFuZGxlck1vZHVsZSB7XG4gIHN0YXRpYyBmb3JSb290KGNvbmZpZ3VyYXRpb25zID0gSW5pdGlhbENvbmZpZyk6IE1vZHVsZVdpdGhQcm92aWRlcnMge1xuICAgIHJldHVybiB7XG4gICAgICBuZ01vZHVsZTogRUhhbmRsZXJNb2R1bGUsXG4gICAgICBwcm92aWRlcnM6IFtcbiAgICAgICAge3Byb3ZpZGU6ICdjb25maWd1cmF0aW9ucycsIHVzZVZhbHVlOiBjb25maWd1cmF0aW9uc30sXG4gICAgICBdLFxuICAgIH07XG4gIH1cbiAgc3RhdGljIGZvckNoaWxkKCk6IE1vZHVsZVdpdGhQcm92aWRlcnMge1xuXG4gICAgcmV0dXJue1xuICAgICAgbmdNb2R1bGU6IEVIYW5kbGVyTW9kdWxlLFxuICAgIH07XG5cbiAgfVxuXG59XG4iXSwibmFtZXMiOlsiaHR0cCIsIkh0dHBIZWFkZXJzIiwiY2F0Y2hFcnJvciIsIkluamVjdGFibGUiLCJIdHRwQ2xpZW50IiwiSW5qZWN0IiwiSHR0cEVycm9yUmVzcG9uc2UiLCJ0b2FzdHIuZXJyb3IiLCJJbmplY3RvciIsIm1hcCIsIkh0dHBSZXNwb25zZSIsImZpbmFsaXplIiwiTmdNb2R1bGUiLCJIdHRwQ2xpZW50TW9kdWxlIiwiQnJvd3NlckFuaW1hdGlvbnNNb2R1bGUiLCJFcnJvckhhbmRsZXIiLCJIVFRQX0lOVEVSQ0VQVE9SUyJdLCJtYXBwaW5ncyI6Ijs7Ozs7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