@codaglobal/ng-jwt-authentication
Version:
<a> <br> <h1 align="center">ng-jwt-authentication</h1> </a>
420 lines (410 loc) • 45.3 kB
JavaScript
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@angular/core'), require('@angular/common/http'), require('ngx-cookie-service'), require('rxjs'), require('rxjs/operators'), require('ngx-cookie-service/cookie-service/cookie.service')) :
typeof define === 'function' && define.amd ? define('@codaglobal/ng-jwt-authentication', ['exports', '@angular/core', '@angular/common/http', 'ngx-cookie-service', 'rxjs', 'rxjs/operators', 'ngx-cookie-service/cookie-service/cookie.service'], factory) :
(factory((global.codaglobal = global.codaglobal || {}, global.codaglobal['ng-jwt-authentication'] = {}),global.ng.core,global.ng.common.http,null,global.rxjs,global.rxjs.operators,null));
}(this, (function (exports,i0,i1,ngxCookieService,rxjs,operators,i2) { 'use strict';
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
/** @enum {string} */
var METHODS = {
GET: 'GET',
POST: 'POST',
PATCH: 'PATCH',
DELETE: 'DELETE',
PUT: 'PUT',
};
var Config = (function () {
function Config() {
}
return Config;
}());
/** @type {?} */
var DEFAULTS = {
refreshUrl: null,
headerKeyName: 'Authorization',
accessTokenKey: 'accessToken',
refreshTokenKey: 'refreshToken',
expiresInKey: 'expiresIn',
errorStatusCode: 401,
authorizationSchema: 'Bearer',
contentTypeKeyName: 'Content-Type',
contentType: 'application/json',
jwtResponse: 'body'
};
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
var JwtAuthenticationService = (function () {
function JwtAuthenticationService(http, cookie, config) {
this.http = http;
this.cookie = cookie;
this.config = config;
this.libraryConfig = new Config();
this.libraryConfig.refreshUrl = this.config.refreshUrl || DEFAULTS.refreshUrl;
this.libraryConfig.headerKeyName = this.config.headerKeyName || DEFAULTS.headerKeyName;
this.libraryConfig.accessTokenKey = this.config.accessTokenKey || DEFAULTS.accessTokenKey;
this.libraryConfig.refreshTokenKey = this.config.refreshTokenKey || DEFAULTS.refreshTokenKey;
this.libraryConfig.expiresInKey = this.config.expiresInKey || DEFAULTS.expiresInKey;
this.libraryConfig.errorStatusCode = this.config.errorStatusCode || DEFAULTS.errorStatusCode;
this.libraryConfig.authorizationSchema = this.config.authorizationSchema || DEFAULTS.authorizationSchema;
this.libraryConfig.contentTypeKeyName = DEFAULTS.contentTypeKeyName;
this.libraryConfig.contentType = DEFAULTS.contentType;
this.libraryConfig.jwtResponse = this.config.jwtResponse || DEFAULTS.jwtResponse;
}
/**
* @param {?} customHeaders
* @return {?}
*/
JwtAuthenticationService.prototype.setHeaders = /**
* @param {?} customHeaders
* @return {?}
*/
function (customHeaders) {
/** @type {?} */
var headers;
/**
* If custom header available append the Authorization header,
* Otherwise creating the header with Authorization and default Content type
*/
if (customHeaders) {
headers = customHeaders;
}
else {
headers = new i1.HttpHeaders();
}
if (!headers.has(this.libraryConfig.contentTypeKeyName)) {
headers = headers.set(this.libraryConfig.contentTypeKeyName, this.libraryConfig.contentType);
}
headers = headers.set(this.libraryConfig.headerKeyName, this.libraryConfig.authorizationSchema + " " + this.cookie.get(this.libraryConfig.accessTokenKey));
return headers;
};
/**
* @param {?} url
* @param {?=} options
* @return {?}
*/
JwtAuthenticationService.prototype.jwtAuthGet = /**
* @param {?} url
* @param {?=} options
* @return {?}
*/
function (url, options) {
var _this = this;
/** @type {?} */
var observeParameter = 'body';
/** @type {?} */
var requestHeader = this.setHeaders(options ? options.headers : undefined);
if (options) {
observeParameter = options.observe ? options.observe : 'body';
}
return this.http.get(url, {
headers: requestHeader,
observe: observeParameter
}).pipe(operators.map(function (res) { return res; }), operators.catchError(function (error) { return _this.handleServerError(error, url, METHODS.GET, options); }));
};
/**
* @param {?} url
* @param {?} body
* @param {?=} options
* @return {?}
*/
JwtAuthenticationService.prototype.jwtAuthPost = /**
* @param {?} url
* @param {?} body
* @param {?=} options
* @return {?}
*/
function (url, body, options) {
var _this = this;
/** @type {?} */
var observeParameter = 'body';
/** @type {?} */
var requestHeader = this.setHeaders(options ? options.headers : undefined);
if (options) {
observeParameter = options.observe ? options.observe : 'body';
}
return this.http.post(url, body, {
headers: requestHeader,
observe: observeParameter
}).pipe(operators.map(function (res) { return res; }), operators.catchError(function (error) { return _this.handleServerError(error, url, METHODS.POST, body, options); }));
};
/**
* @param {?} url
* @param {?} body
* @param {?=} options
* @return {?}
*/
JwtAuthenticationService.prototype.jwtAuthPut = /**
* @param {?} url
* @param {?} body
* @param {?=} options
* @return {?}
*/
function (url, body, options) {
var _this = this;
/** @type {?} */
var observeParameter = 'body';
/** @type {?} */
var requestHeader = this.setHeaders(options ? options.headers : undefined);
if (options) {
observeParameter = options.observe ? options.observe : 'body';
}
return this.http.put(url, body, {
headers: requestHeader,
observe: observeParameter
}).pipe(operators.map(function (res) { return res; }), operators.catchError(function (error) { return _this.handleServerError(error, url, METHODS.PUT, body, options); }));
};
/**
* @param {?} url
* @param {?=} options
* @return {?}
*/
JwtAuthenticationService.prototype.jwtAuthDelete = /**
* @param {?} url
* @param {?=} options
* @return {?}
*/
function (url, options) {
var _this = this;
/** @type {?} */
var observeParameter = 'body';
/** @type {?} */
var requestHeader = this.setHeaders(options ? options.headers : undefined);
if (options) {
observeParameter = options.observe ? options.observe : 'body';
}
return this.http.delete(url, {
headers: requestHeader,
observe: observeParameter
}).pipe(operators.map(function (res) { return res; }), operators.catchError(function (error) { return _this.handleServerError(error, url, METHODS.DELETE, options); }));
};
/**
* @param {?} url
* @param {?} body
* @param {?=} options
* @return {?}
*/
JwtAuthenticationService.prototype.jwtAuthPatch = /**
* @param {?} url
* @param {?} body
* @param {?=} options
* @return {?}
*/
function (url, body, options) {
var _this = this;
/** @type {?} */
var observeParameter = 'body';
/** @type {?} */
var requestHeader = this.setHeaders(options ? options.headers : undefined);
if (options) {
observeParameter = options.observe ? options.observe : 'body';
}
return this.http.patch(url, body, {
headers: requestHeader,
observe: observeParameter
}).pipe(operators.map(function (res) { return res; }), operators.catchError(function (error) { return _this.handleServerError(error, url, METHODS.PATCH, body, options); }));
};
/**
* @param {?} error
* @param {?} url
* @param {?} method
* @param {?=} body
* @param {?=} options
* @return {?}
*/
JwtAuthenticationService.prototype.handleServerError = /**
* @param {?} error
* @param {?} url
* @param {?} method
* @param {?=} body
* @param {?=} options
* @return {?}
*/
function (error, url, method, body, options) {
var _this = this;
/** @type {?} */
var observeParameter = 'body';
if (options) {
observeParameter = options.observe ? options.observe : 'body';
}
if (this.libraryConfig.refreshUrl) {
if (error.status === this.libraryConfig.errorStatusCode) {
return this.getToken()
.pipe(operators.switchMap(function (data) {
_this.cookie.set(_this.libraryConfig.accessTokenKey, data[_this.libraryConfig.accessTokenKey]);
_this.cookie.set(_this.libraryConfig.expiresInKey, data[_this.libraryConfig.expiresInKey]);
switch (method) {
case METHODS.GET: return _this.http.get(url, { headers: _this.setHeaders(options ? options.headers : undefined),
observe: observeParameter }).pipe(operators.map(function (res) { return res; }));
case METHODS.POST: return _this.http.post(url, JSON.stringify(body), { headers: _this.setHeaders(options ? options.headers : undefined),
observe: observeParameter }).pipe(operators.map(function (res) { return res; }));
case METHODS.PUT: return _this.http.put(url, JSON.stringify(body), { headers: _this.setHeaders(options ? options.headers : undefined),
observe: observeParameter }).pipe(operators.map(function (res) { return res; }));
case METHODS.DELETE: return _this.http.delete(url, { headers: _this.setHeaders(options ? options.headers : undefined),
observe: observeParameter }).pipe(operators.map(function (res) { return res; }));
case METHODS.PATCH: return _this.http.patch(url, { headers: _this.setHeaders(options ? options.headers : undefined),
observe: observeParameter }).pipe(operators.map(function (res) { return res; }));
}
}));
}
}
return rxjs.throwError(error || 'Server error');
};
/**
* @return {?}
*/
JwtAuthenticationService.prototype.getToken = /**
* @return {?}
*/
function () {
/** @type {?} */
var data;
data = {};
data[this.libraryConfig.accessTokenKey] = this.cookie.get(this.libraryConfig.accessTokenKey);
data[this.libraryConfig.refreshTokenKey] = this.cookie.get(this.libraryConfig.refreshTokenKey);
data[this.libraryConfig.expiresInKey] = this.cookie.get(this.libraryConfig.expiresInKey);
return this.refreshToken(this.libraryConfig.refreshUrl, data);
};
/**
* @param {?} url
* @param {?} data
* @return {?}
*/
JwtAuthenticationService.prototype.refreshToken = /**
* @param {?} url
* @param {?} data
* @return {?}
*/
function (url, data) {
/** @type {?} */
var headers = new i1.HttpHeaders()
.set(this.libraryConfig.contentTypeKeyName, this.libraryConfig.contentType)
.set(this.libraryConfig.headerKeyName, this.libraryConfig.authorizationSchema + " " + this.cookie.get(this.libraryConfig.accessTokenKey));
/** @type {?} */
var observeParameter = this.libraryConfig.jwtResponse ? this.libraryConfig.jwtResponse : 'body';
return this.http.post(url, JSON.stringify(data), {
headers: headers,
observe: observeParameter
}).pipe(operators.map(function (res) { return res; }));
};
/**
* @param {?} accessToken
* @param {?} refreshToken
* @param {?} expiresIn
* @return {?}
*/
JwtAuthenticationService.prototype.saveJwtToken = /**
* @param {?} accessToken
* @param {?} refreshToken
* @param {?} expiresIn
* @return {?}
*/
function (accessToken, refreshToken, expiresIn) {
this.cookie.set(this.libraryConfig.accessTokenKey, accessToken);
this.cookie.set(this.libraryConfig.refreshTokenKey, refreshToken);
this.cookie.set(this.libraryConfig.expiresInKey, expiresIn);
};
/**
* @return {?}
*/
JwtAuthenticationService.prototype.clearJwtTokens = /**
* @return {?}
*/
function () {
this.cookie.delete(this.libraryConfig.accessTokenKey);
this.cookie.delete(this.libraryConfig.refreshTokenKey);
this.cookie.delete(this.libraryConfig.expiresInKey);
};
JwtAuthenticationService.decorators = [
{ type: i0.Injectable, args: [{
providedIn: 'root'
},] },
];
/** @nocollapse */
JwtAuthenticationService.ctorParameters = function () {
return [
{ type: i1.HttpClient },
{ type: ngxCookieService.CookieService },
{ type: Config, decorators: [{ type: i0.Inject, args: ['config',] }] }
];
};
/** @nocollapse */ JwtAuthenticationService.ngInjectableDef = i0.defineInjectable({ factory: function JwtAuthenticationService_Factory() { return new JwtAuthenticationService(i0.inject(i1.HttpClient), i0.inject(i2.CookieService), i0.inject("config")); }, token: JwtAuthenticationService, providedIn: "root" });
return JwtAuthenticationService;
}());
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
var AngularJwtComponent = (function () {
function AngularJwtComponent() {
}
/**
* @return {?}
*/
AngularJwtComponent.prototype.ngOnInit = /**
* @return {?}
*/
function () {
};
AngularJwtComponent.decorators = [
{ type: i0.Component, args: [{
selector: 'lib-angular-jwt',
template: "",
styles: []
},] },
];
/** @nocollapse */
AngularJwtComponent.ctorParameters = function () { return []; };
return AngularJwtComponent;
}());
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
var JwtAuthenticationModule = (function () {
function JwtAuthenticationModule() {
}
/**
* @param {?} config
* @return {?}
*/
JwtAuthenticationModule.forRoot = /**
* @param {?} config
* @return {?}
*/
function (config) {
return {
ngModule: JwtAuthenticationModule,
providers: [JwtAuthenticationService, { provide: 'config', useValue: config }]
};
};
JwtAuthenticationModule.decorators = [
{ type: i0.NgModule, args: [{
imports: [
i1.HttpClientModule
],
declarations: [AngularJwtComponent],
exports: [AngularJwtComponent],
providers: [ngxCookieService.CookieService]
},] },
];
return JwtAuthenticationModule;
}());
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
exports.JwtAuthenticationService = JwtAuthenticationService;
exports.JwtAuthenticationModule = JwtAuthenticationModule;
exports.ɵb = AngularJwtComponent;
exports.ɵa = Config;
Object.defineProperty(exports, '__esModule', { value: true });
})));
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29kYWdsb2JhbC1uZy1qd3QtYXV0aGVudGljYXRpb24udW1kLmpzLm1hcCIsInNvdXJjZXMiOlsibmc6Ly9AY29kYWdsb2JhbC9uZy1qd3QtYXV0aGVudGljYXRpb24vbGliL2FuZ3VsYXItand0LmNvbnN0YW50cy50cyIsIm5nOi8vQGNvZGFnbG9iYWwvbmctand0LWF1dGhlbnRpY2F0aW9uL2xpYi9hbmd1bGFyLWp3dC5zZXJ2aWNlLnRzIiwibmc6Ly9AY29kYWdsb2JhbC9uZy1qd3QtYXV0aGVudGljYXRpb24vbGliL2FuZ3VsYXItand0LmNvbXBvbmVudC50cyIsIm5nOi8vQGNvZGFnbG9iYWwvbmctand0LWF1dGhlbnRpY2F0aW9uL2xpYi9hbmd1bGFyLWp3dC5tb2R1bGUudHMiXSwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IGVudW0gTUVUSE9EUyB7XG4gIEdFVCA9ICdHRVQnLFxuICBQT1NUID0gJ1BPU1QnLFxuICBQQVRDSCA9ICdQQVRDSCcsXG4gIERFTEVURSA9ICdERUxFVEUnLFxuICBQVVQgPSAnUFVUJ1xufVxuXG5leHBvcnQgY2xhc3MgQ29uZmlnIHtcbiAgcmVmcmVzaFVybDogc3RyaW5nO1xuICBoZWFkZXJLZXlOYW1lOiBzdHJpbmc7XG4gIGFjY2Vzc1Rva2VuS2V5OiBzdHJpbmc7XG4gIHJlZnJlc2hUb2tlbktleTogc3RyaW5nO1xuICBleHBpcmVzSW5LZXk6IHN0cmluZztcbiAgZXJyb3JTdGF0dXNDb2RlOiBudW1iZXI7XG4gIGF1dGhvcml6YXRpb25TY2hlbWE6IHN0cmluZztcbiAgY29udGVudFR5cGVLZXlOYW1lOiBzdHJpbmc7XG4gIGNvbnRlbnRUeXBlOiBzdHJpbmc7XG4gIGp3dFJlc3BvbnNlOiBzdHJpbmc7XG59XG5cblxuZXhwb3J0IGNvbnN0IERFRkFVTFRTOiBDb25maWcgPSB7XG4gIHJlZnJlc2hVcmw6IG51bGwsXG4gIGhlYWRlcktleU5hbWU6ICdBdXRob3JpemF0aW9uJyxcbiAgYWNjZXNzVG9rZW5LZXk6ICdhY2Nlc3NUb2tlbicsXG4gIHJlZnJlc2hUb2tlbktleTogJ3JlZnJlc2hUb2tlbicsXG4gIGV4cGlyZXNJbktleTogJ2V4cGlyZXNJbicsXG4gIGVycm9yU3RhdHVzQ29kZTogNDAxLFxuICBhdXRob3JpemF0aW9uU2NoZW1hOiAnQmVhcmVyJyxcbiAgY29udGVudFR5cGVLZXlOYW1lOiAnQ29udGVudC1UeXBlJyxcbiAgY29udGVudFR5cGU6ICdhcHBsaWNhdGlvbi9qc29uJyxcbiAgand0UmVzcG9uc2U6ICdib2R5J1xufTtcbiIsImltcG9ydCB7IEluamVjdGFibGUsIEluamVjdCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgSHR0cENsaWVudCwgSHR0cEhlYWRlcnMsIEh0dHBFcnJvclJlc3BvbnNlLCBIdHRwUmVzcG9uc2UgfSBmcm9tICdAYW5ndWxhci9jb21tb24vaHR0cCc7XG5pbXBvcnQgeyBDb29raWVTZXJ2aWNlIH0gZnJvbSAnbmd4LWNvb2tpZS1zZXJ2aWNlJztcbmltcG9ydCB7IE9ic2VydmFibGUsIHRocm93RXJyb3IgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IG1hcCwgY2F0Y2hFcnJvciwgc3dpdGNoTWFwIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgTUVUSE9EUywgQ29uZmlnLCBERUZBVUxUUyB9IGZyb20gJy4vYW5ndWxhci1qd3QuY29uc3RhbnRzJztcblxuQEluamVjdGFibGUoe1xuICBwcm92aWRlZEluOiAncm9vdCdcbn0pXG5leHBvcnQgY2xhc3MgSnd0QXV0aGVudGljYXRpb25TZXJ2aWNlIHtcblxuICBsaWJyYXJ5Q29uZmlnOiBDb25maWcgPSBuZXcgQ29uZmlnKCk7XG5cbiAgY29uc3RydWN0b3IocHJpdmF0ZSBodHRwOiBIdHRwQ2xpZW50LCBwcml2YXRlIGNvb2tpZTogQ29va2llU2VydmljZSwgQEluamVjdCgnY29uZmlnJykgcHJpdmF0ZSBjb25maWc6IENvbmZpZykge1xuICAgIHRoaXMubGlicmFyeUNvbmZpZy5yZWZyZXNoVXJsID0gdGhpcy5jb25maWcucmVmcmVzaFVybCB8fCBERUZBVUxUUy5yZWZyZXNoVXJsO1xuICAgIHRoaXMubGlicmFyeUNvbmZpZy5oZWFkZXJLZXlOYW1lID0gdGhpcy5jb25maWcuaGVhZGVyS2V5TmFtZSB8fCBERUZBVUxUUy5oZWFkZXJLZXlOYW1lO1xuICAgIHRoaXMubGlicmFyeUNvbmZpZy5hY2Nlc3NUb2tlbktleSA9IHRoaXMuY29uZmlnLmFjY2Vzc1Rva2VuS2V5IHx8IERFRkFVTFRTLmFjY2Vzc1Rva2VuS2V5O1xuICAgIHRoaXMubGlicmFyeUNvbmZpZy5yZWZyZXNoVG9rZW5LZXkgPSB0aGlzLmNvbmZpZy5yZWZyZXNoVG9rZW5LZXkgfHwgREVGQVVMVFMucmVmcmVzaFRva2VuS2V5O1xuICAgIHRoaXMubGlicmFyeUNvbmZpZy5leHBpcmVzSW5LZXkgPSB0aGlzLmNvbmZpZy5leHBpcmVzSW5LZXkgfHwgREVGQVVMVFMuZXhwaXJlc0luS2V5O1xuICAgIHRoaXMubGlicmFyeUNvbmZpZy5lcnJvclN0YXR1c0NvZGUgPSB0aGlzLmNvbmZpZy5lcnJvclN0YXR1c0NvZGUgfHwgREVGQVVMVFMuZXJyb3JTdGF0dXNDb2RlO1xuICAgIHRoaXMubGlicmFyeUNvbmZpZy5hdXRob3JpemF0aW9uU2NoZW1hID0gdGhpcy5jb25maWcuYXV0aG9yaXphdGlvblNjaGVtYSB8fCBERUZBVUxUUy5hdXRob3JpemF0aW9uU2NoZW1hO1xuICAgIHRoaXMubGlicmFyeUNvbmZpZy5jb250ZW50VHlwZUtleU5hbWUgPSBERUZBVUxUUy5jb250ZW50VHlwZUtleU5hbWU7XG4gICAgdGhpcy5saWJyYXJ5Q29uZmlnLmNvbnRlbnRUeXBlID0gREVGQVVMVFMuY29udGVudFR5cGU7XG4gICAgdGhpcy5saWJyYXJ5Q29uZmlnLmp3dFJlc3BvbnNlID0gdGhpcy5jb25maWcuand0UmVzcG9uc2UgfHwgREVGQVVMVFMuand0UmVzcG9uc2U7XG4gIH1cblxuICBwcml2YXRlIHNldEhlYWRlcnMoY3VzdG9tSGVhZGVyczogSHR0cEhlYWRlcnMpIHtcbiAgICBsZXQgaGVhZGVyczogSHR0cEhlYWRlcnM7XG4gICAgLyoqXG4gICAgICogSWYgY3VzdG9tIGhlYWRlciBhdmFpbGFibGUgYXBwZW5kIHRoZSBBdXRob3JpemF0aW9uIGhlYWRlcixcbiAgICAgKiBPdGhlcndpc2UgY3JlYXRpbmcgdGhlICBoZWFkZXIgd2l0aCBBdXRob3JpemF0aW9uIGFuZCBkZWZhdWx0IENvbnRlbnQgdHlwZVxuICAgICAqL1xuICAgIGlmIChjdXN0b21IZWFkZXJzKSB7XG4gICAgICBoZWFkZXJzID0gY3VzdG9tSGVhZGVycztcbiAgICB9IGVsc2Uge1xuICAgICAgaGVhZGVycyA9IG5ldyBIdHRwSGVhZGVycygpO1xuICAgIH1cbiAgICBpZiAoIWhlYWRlcnMuaGFzKHRoaXMubGlicmFyeUNvbmZpZy5jb250ZW50VHlwZUtleU5hbWUpKSB7XG4gICAgICBoZWFkZXJzID0gaGVhZGVycy5zZXQodGhpcy5saWJyYXJ5Q29uZmlnLmNvbnRlbnRUeXBlS2V5TmFtZSwgdGhpcy5saWJyYXJ5Q29uZmlnLmNvbnRlbnRUeXBlKTtcbiAgICB9XG4gICAgaGVhZGVycyA9IGhlYWRlcnMuc2V0KHRoaXMubGlicmFyeUNvbmZpZy5oZWFkZXJLZXlOYW1lLFxuICAgICAgYCR7dGhpcy5saWJyYXJ5Q29uZmlnLmF1dGhvcml6YXRpb25TY2hlbWF9ICR7dGhpcy5jb29raWUuZ2V0KHRoaXMubGlicmFyeUNvbmZpZy5hY2Nlc3NUb2tlbktleSl9YCk7XG4gICAgcmV0dXJuIGhlYWRlcnM7XG4gIH1cblxuICBqd3RBdXRoR2V0KHVybDogc3RyaW5nLCBvcHRpb25zPzogeyBoZWFkZXJzPzogSHR0cEhlYWRlcnMsIG9ic2VydmU/OiBhbnkgfSkge1xuICAgIGxldCBvYnNlcnZlUGFyYW1ldGVyOiBhbnkgPSAnYm9keSc7XG4gICAgY29uc3QgcmVxdWVzdEhlYWRlcjogSHR0cEhlYWRlcnMgPSB0aGlzLnNldEhlYWRlcnMob3B0aW9ucyA/IG9wdGlvbnMuaGVhZGVycyA6IHVuZGVmaW5lZCk7XG4gICAgaWYgKG9wdGlvbnMpIHtcbiAgICAgIG9ic2VydmVQYXJhbWV0ZXIgPSBvcHRpb25zLm9ic2VydmUgPyBvcHRpb25zLm9ic2VydmUgOiAnYm9keSc7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmh0dHAuZ2V0KHVybCwge1xuICAgICAgaGVhZGVyczogcmVxdWVzdEhlYWRlcixcbiAgICAgIG9ic2VydmU6IG9ic2VydmVQYXJhbWV0ZXJcbiAgICB9KS5waXBlKG1hcCgocmVzOiBhbnkpID0+IHJlcyksIGNhdGNoRXJyb3IoXG4gICAgICAoZXJyb3IpID0+IHRoaXMuaGFuZGxlU2VydmVyRXJyb3IoXG4gICAgICAgIGVycm9yLCB1cmwsIE1FVEhPRFMuR0VULCBvcHRpb25zKSkpO1xuXG4gIH1cblxuICBqd3RBdXRoUG9zdCh1cmw6IHN0cmluZywgYm9keTogYW55LCBvcHRpb25zPzogeyBoZWFkZXJzPzogSHR0cEhlYWRlcnMsIG9ic2VydmU/OiBhbnkgfSkge1xuICAgIGxldCBvYnNlcnZlUGFyYW1ldGVyOiBhbnkgPSAnYm9keSc7XG4gICAgY29uc3QgcmVxdWVzdEhlYWRlcjogSHR0cEhlYWRlcnMgPSB0aGlzLnNldEhlYWRlcnMob3B0aW9ucyA/IG9wdGlvbnMuaGVhZGVycyA6IHVuZGVmaW5lZCk7XG4gICAgaWYgKG9wdGlvbnMpIHtcbiAgICAgIG9ic2VydmVQYXJhbWV0ZXIgPSBvcHRpb25zLm9ic2VydmUgPyBvcHRpb25zLm9ic2VydmUgOiAnYm9keSc7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmh0dHAucG9zdCh1cmwsIGJvZHksIHtcbiAgICAgIGhlYWRlcnM6IHJlcXVlc3RIZWFkZXIsXG4gICAgICBvYnNlcnZlOiBvYnNlcnZlUGFyYW1ldGVyXG4gICAgfSkucGlwZShcbiAgICAgIG1hcCgocmVzOiBIdHRwUmVzcG9uc2U8YW55PikgPT4gcmVzKSxcbiAgICAgIGNhdGNoRXJyb3IoKGVycm9yKSA9PiB0aGlzLmhhbmRsZVNlcnZlckVycm9yKFxuICAgICAgICBlcnJvciwgdXJsLCBNRVRIT0RTLlBPU1QsIGJvZHksIG9wdGlvbnMpKSk7XG5cbiAgfVxuXG4gIGp3dEF1dGhQdXQodXJsOiBzdHJpbmcsIGJvZHk6IGFueSwgb3B0aW9ucz86IHsgaGVhZGVycz86IEh0dHBIZWFkZXJzLCBvYnNlcnZlPzogYW55IH0pIHtcbiAgICBsZXQgb2JzZXJ2ZVBhcmFtZXRlcjogYW55ID0gJ2JvZHknO1xuICAgIGNvbnN0IHJlcXVlc3RIZWFkZXI6IEh0dHBIZWFkZXJzID0gdGhpcy5zZXRIZWFkZXJzKG9wdGlvbnMgPyBvcHRpb25zLmhlYWRlcnMgOiB1bmRlZmluZWQpO1xuICAgIGlmIChvcHRpb25zKSB7XG4gICAgICBvYnNlcnZlUGFyYW1ldGVyID0gb3B0aW9ucy5vYnNlcnZlID8gb3B0aW9ucy5vYnNlcnZlIDogJ2JvZHknO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5odHRwLnB1dCh1cmwsIGJvZHksIHtcbiAgICAgIGhlYWRlcnM6IHJlcXVlc3RIZWFkZXIsXG4gICAgICBvYnNlcnZlOiBvYnNlcnZlUGFyYW1ldGVyXG4gICAgfSkucGlwZShtYXAoKHJlczogYW55KSA9PiByZXMpLFxuICAgICAgY2F0Y2hFcnJvcigoZXJyb3IpID0+IHRoaXMuaGFuZGxlU2VydmVyRXJyb3IoXG4gICAgICAgIGVycm9yLCB1cmwsIE1FVEhPRFMuUFVULCBib2R5LCBvcHRpb25zKSkpO1xuXG4gIH1cblxuICBqd3RBdXRoRGVsZXRlKHVybDogc3RyaW5nLCBvcHRpb25zPzogeyBoZWFkZXJzPzogSHR0cEhlYWRlcnMsIG9ic2VydmU/OiBhbnkgfSkge1xuICAgIGxldCBvYnNlcnZlUGFyYW1ldGVyOiBhbnkgPSAnYm9keSc7XG4gICAgY29uc3QgcmVxdWVzdEhlYWRlcjogSHR0cEhlYWRlcnMgPSB0aGlzLnNldEhlYWRlcnMob3B0aW9ucyA/IG9wdGlvbnMuaGVhZGVycyA6IHVuZGVmaW5lZCk7XG4gICAgaWYgKG9wdGlvbnMpIHtcbiAgICAgIG9ic2VydmVQYXJhbWV0ZXIgPSBvcHRpb25zLm9ic2VydmUgPyBvcHRpb25zLm9ic2VydmUgOiAnYm9keSc7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmh0dHAuZGVsZXRlKHVybCwge1xuICAgICAgaGVhZGVyczogcmVxdWVzdEhlYWRlcixcbiAgICAgIG9ic2VydmU6IG9ic2VydmVQYXJhbWV0ZXJcbiAgICB9KS5waXBlKG1hcCgocmVzOiBhbnkpID0+IHJlcyksXG4gICAgICBjYXRjaEVycm9yKChlcnJvcikgPT4gdGhpcy5oYW5kbGVTZXJ2ZXJFcnJvcihcbiAgICAgICAgZXJyb3IsIHVybCwgTUVUSE9EUy5ERUxFVEUsIG9wdGlvbnMpKSk7XG4gIH1cblxuICBqd3RBdXRoUGF0Y2godXJsOiBzdHJpbmcsIGJvZHk6IGFueSwgb3B0aW9ucz86IHsgaGVhZGVycz86IEh0dHBIZWFkZXJzLCBvYnNlcnZlPzogYW55IH0pIHtcbiAgICBsZXQgb2JzZXJ2ZVBhcmFtZXRlcjogYW55ID0gJ2JvZHknO1xuICAgIGNvbnN0IHJlcXVlc3RIZWFkZXI6IEh0dHBIZWFkZXJzID0gdGhpcy5zZXRIZWFkZXJzKG9wdGlvbnMgPyBvcHRpb25zLmhlYWRlcnMgOiB1bmRlZmluZWQpO1xuICAgIGlmIChvcHRpb25zKSB7XG4gICAgICBvYnNlcnZlUGFyYW1ldGVyID0gb3B0aW9ucy5vYnNlcnZlID8gb3B0aW9ucy5vYnNlcnZlIDogJ2JvZHknO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5odHRwLnBhdGNoKHVybCwgYm9keSwge1xuICAgICAgaGVhZGVyczogcmVxdWVzdEhlYWRlcixcbiAgICAgIG9ic2VydmU6IG9ic2VydmVQYXJhbWV0ZXJcbiAgICB9KS5waXBlKG1hcCgocmVzOiBhbnkpID0+IHJlcyksXG4gICAgICBjYXRjaEVycm9yKChlcnJvcikgPT4gdGhpcy5oYW5kbGVTZXJ2ZXJFcnJvcihcbiAgICAgICAgZXJyb3IsIHVybCwgTUVUSE9EUy5QQVRDSCwgYm9keSwgb3B0aW9ucykpKTtcbiAgfVxuXG4gIHByaXZhdGUgaGFuZGxlU2VydmVyRXJyb3IoZXJyb3I6IEh0dHBFcnJvclJlc3BvbnNlLCB1cmw6IHN0cmluZywgbWV0aG9kOiBzdHJpbmcsIGJvZHk/OiBhbnksXG4gICAgb3B0aW9ucz86IHsgaGVhZGVycz86IEh0dHBIZWFkZXJzOyBvYnNlcnZlPzogYW55IH0pIHtcbiAgICBsZXQgb2JzZXJ2ZVBhcmFtZXRlcjogYW55ID0gJ2JvZHknO1xuICAgIGlmIChvcHRpb25zKSB7XG4gICAgICBvYnNlcnZlUGFyYW1ldGVyID0gb3B0aW9ucy5vYnNlcnZlID8gb3B0aW9ucy5vYnNlcnZlIDogJ2JvZHknO1xuICAgIH1cbiAgICBpZiAodGhpcy5saWJyYXJ5Q29uZmlnLnJlZnJlc2hVcmwpIHtcbiAgICAgIGlmIChlcnJvci5zdGF0dXMgPT09IHRoaXMubGlicmFyeUNvbmZpZy5lcnJvclN0YXR1c0NvZGUpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0VG9rZW4oKVxuICAgICAgICAgIC5waXBlKHN3aXRjaE1hcChkYXRhID0+IHtcbiAgICAgICAgICAgIHRoaXMuY29va2llLnNldCh0aGlzLmxpYnJhcnlDb25maWcuYWNjZXNzVG9rZW5LZXksIGRhdGFbdGhpcy5saWJyYXJ5Q29uZmlnLmFjY2Vzc1Rva2VuS2V5XSk7XG4gICAgICAgICAgICB0aGlzLmNvb2tpZS5zZXQodGhpcy5saWJyYXJ5Q29uZmlnLmV4cGlyZXNJbktleSwgZGF0YVt0aGlzLmxpYnJhcnlDb25maWcuZXhwaXJlc0luS2V5XSk7XG4gICAgICAgICAgICBzd2l0Y2ggKG1ldGhvZCkge1xuICAgICAgICAgICAgICBjYXNlIE1FVEhPRFMuR0VUOiByZXR1cm4gdGhpcy5odHRwLmdldCh1cmwsXG4gICAgICAgICAgICAgICAgeyBoZWFkZXJzOiB0aGlzLnNldEhlYWRlcnMob3B0aW9ucyA/IG9wdGlvbnMuaGVhZGVycyA6IHVuZGVmaW5lZCksXG4gICAgICAgICAgICAgICAgICBvYnNlcnZlOiBvYnNlcnZlUGFyYW1ldGVyIH0pLnBpcGUobWFwKChyZXM6IGFueSkgPT4gcmVzKSk7XG4gICAgICAgICAgICAgIGNhc2UgTUVUSE9EUy5QT1NUOiByZXR1cm4gdGhpcy5odHRwLnBvc3QodXJsLCBKU09OLnN0cmluZ2lmeShib2R5KSxcbiAgICAgICAgICAgICAgICB7IGhlYWRlcnM6IHRoaXMuc2V0SGVhZGVycyhvcHRpb25zID8gb3B0aW9ucy5oZWFkZXJzIDogdW5kZWZpbmVkKSxcbiAgICAgICAgICAgICAgICAgIG9ic2VydmU6IG9ic2VydmVQYXJhbWV0ZXIgfSkucGlwZShtYXAoKHJlczogYW55KSA9PiByZXMpKTtcbiAgICAgICAgICAgICAgY2FzZSBNRVRIT0RTLlBVVDogcmV0dXJuIHRoaXMuaHR0cC5wdXQodXJsLCBKU09OLnN0cmluZ2lmeShib2R5KSxcbiAgICAgICAgICAgICAgICB7IGhlYWRlcnM6IHRoaXMuc2V0SGVhZGVycyhvcHRpb25zID8gb3B0aW9ucy5oZWFkZXJzIDogdW5kZWZpbmVkKSxcbiAgICAgICAgICAgICAgICAgIG9ic2VydmU6IG9ic2VydmVQYXJhbWV0ZXIgfSkucGlwZShtYXAoKHJlczogYW55KSA9PiByZXMpKTtcbiAgICAgICAgICAgICAgY2FzZSBNRVRIT0RTLkRFTEVURTogcmV0dXJuIHRoaXMuaHR0cC5kZWxldGUodXJsLFxuICAgICAgICAgICAgICAgIHsgaGVhZGVyczogdGhpcy5zZXRIZWFkZXJzKG9wdGlvbnMgPyBvcHRpb25zLmhlYWRlcnMgOiB1bmRlZmluZWQpLFxuICAgICAgICAgICAgICAgICAgb2JzZXJ2ZTogb2JzZXJ2ZVBhcmFtZXRlciB9KS5waXBlKG1hcCgocmVzOiBhbnkpID0+IHJlcykpO1xuICAgICAgICAgICAgICBjYXNlIE1FVEhPRFMuUEFUQ0g6IHJldHVybiB0aGlzLmh0dHAucGF0Y2godXJsLFxuICAgICAgICAgICAgICAgIHsgaGVhZGVyczogdGhpcy5zZXRIZWFkZXJzKG9wdGlvbnMgPyBvcHRpb25zLmhlYWRlcnMgOiB1bmRlZmluZWQpLFxuICAgICAgICAgICAgICAgICAgb2JzZXJ2ZTogb2JzZXJ2ZVBhcmFtZXRlciB9KS5waXBlKG1hcCgocmVzOiBhbnkpID0+IHJlcykpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pKTtcblxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB0aHJvd0Vycm9yKGVycm9yIHx8ICdTZXJ2ZXIgZXJyb3InKTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0VG9rZW4oKSB7XG4gICAgbGV0IGRhdGE7XG4gICAgZGF0YSA9IHt9O1xuICAgIGRhdGFbdGhpcy5saWJyYXJ5Q29uZmlnLmFjY2Vzc1Rva2VuS2V5XSA9IHRoaXMuY29va2llLmdldCh0aGlzLmxpYnJhcnlDb25maWcuYWNjZXNzVG9rZW5LZXkpO1xuICAgIGRhdGFbdGhpcy5saWJyYXJ5Q29uZmlnLnJlZnJlc2hUb2tlbktleV0gPSB0aGlzLmNvb2tpZS5nZXQodGhpcy5saWJyYXJ5Q29uZmlnLnJlZnJlc2hUb2tlbktleSk7XG4gICAgZGF0YVt0aGlzLmxpYnJhcnlDb25maWcuZXhwaXJlc0luS2V5XSA9IHRoaXMuY29va2llLmdldCh0aGlzLmxpYnJhcnlDb25maWcuZXhwaXJlc0luS2V5KTtcbiAgICByZXR1cm4gdGhpcy5yZWZyZXNoVG9rZW4odGhpcy5saWJyYXJ5Q29uZmlnLnJlZnJlc2hVcmwsIGRhdGEpO1xuICB9XG5cbiAgcHJpdmF0ZSByZWZyZXNoVG9rZW4odXJsLCBkYXRhKSB7XG4gICAgY29uc3QgaGVhZGVycyA9IG5ldyBIdHRwSGVhZGVycygpXG4gICAgICAuc2V0KHRoaXMubGlicmFyeUNvbmZpZy5jb250ZW50VHlwZUtleU5hbWUsIHRoaXMubGlicmFyeUNvbmZpZy5jb250ZW50VHlwZSlcbiAgICAgIC5zZXQodGhpcy5saWJyYXJ5Q29uZmlnLmhlYWRlcktleU5hbWUsXG4gICAgICAgIGAke3RoaXMubGlicmFyeUNvbmZpZy5hdXRob3JpemF0aW9uU2NoZW1hfSAke3RoaXMuY29va2llLmdldCh0aGlzLmxpYnJhcnlDb25maWcuYWNjZXNzVG9rZW5LZXkpfWApO1xuICAgIGNvbnN0IG9ic2VydmVQYXJhbWV0ZXI6IGFueSA9IHRoaXMubGlicmFyeUNvbmZpZy5qd3RSZXNwb25zZSA/IHRoaXMubGlicmFyeUNvbmZpZy5qd3RSZXNwb25zZSA6ICdib2R5JztcbiAgICByZXR1cm4gdGhpcy5odHRwLnBvc3QodXJsLCBKU09OLnN0cmluZ2lmeShkYXRhKSxcbiAgICAgIHtcbiAgICAgICAgaGVhZGVyczogaGVhZGVycyxcbiAgICAgICAgb2JzZXJ2ZTogb2JzZXJ2ZVBhcmFtZXRlclxuICAgICAgfSkucGlwZShtYXAoKHJlczogYW55KSA9PiByZXMpKTtcbiAgfVxuXG4gIHNhdmVKd3RUb2tlbihhY2Nlc3NUb2tlbiwgcmVmcmVzaFRva2VuLCBleHBpcmVzSW4pIHtcbiAgICB0aGlzLmNvb2tpZS5zZXQodGhpcy5saWJyYXJ5Q29uZmlnLmFjY2Vzc1Rva2VuS2V5LCBhY2Nlc3NUb2tlbik7XG4gICAgdGhpcy5jb29raWUuc2V0KHRoaXMubGlicmFyeUNvbmZpZy5yZWZyZXNoVG9rZW5LZXksIHJlZnJlc2hUb2tlbik7XG4gICAgdGhpcy5jb29raWUuc2V0KHRoaXMubGlicmFyeUNvbmZpZy5leHBpcmVzSW5LZXksIGV4cGlyZXNJbik7XG4gIH1cblxuICBjbGVhckp3dFRva2VucygpIHtcbiAgICB0aGlzLmNvb2tpZS5kZWxldGUodGhpcy5saWJyYXJ5Q29uZmlnLmFjY2Vzc1Rva2VuS2V5KTtcbiAgICB0aGlzLmNvb2tpZS5kZWxldGUodGhpcy5saWJyYXJ5Q29uZmlnLnJlZnJlc2hUb2tlbktleSk7XG4gICAgdGhpcy5jb29raWUuZGVsZXRlKHRoaXMubGlicmFyeUNvbmZpZy5leHBpcmVzSW5LZXkpO1xuICB9XG59XG4iLCJpbXBvcnQgeyBDb21wb25lbnQsIE9uSW5pdCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdsaWItYW5ndWxhci1qd3QnLFxuICB0ZW1wbGF0ZTogYGAsXG4gIHN0eWxlczogW11cbn0pXG5leHBvcnQgY2xhc3MgQW5ndWxhckp3dENvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCB7XG5cbiAgY29uc3RydWN0b3IoKSB7IH1cblxuICBuZ09uSW5pdCgpIHtcbiAgfVxuXG59XG4iLCJpbXBvcnQgeyBOZ01vZHVsZSwgTW9kdWxlV2l0aFByb3ZpZGVycyB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQW5ndWxhckp3dENvbXBvbmVudCB9IGZyb20gJy4vYW5ndWxhci1qd3QuY29tcG9uZW50JztcbmltcG9ydCB7IENvb2tpZVNlcnZpY2UgfSBmcm9tICduZ3gtY29va2llLXNlcnZpY2UnO1xuaW1wb3J0IHsgSHR0cENsaWVudE1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbi9odHRwJztcbmltcG9ydCB7IEp3dEF1dGhlbnRpY2F0aW9uU2VydmljZSB9IGZyb20gJy4vYW5ndWxhci1qd3Quc2VydmljZSc7XG5ATmdNb2R1bGUoe1xuICBpbXBvcnRzOiBbXG4gICAgSHR0cENsaWVudE1vZHVsZVxuICBdLFxuICBkZWNsYXJhdGlvbnM6IFtBbmd1bGFySnd0Q29tcG9uZW50XSxcbiAgZXhwb3J0czogW0FuZ3VsYXJKd3RDb21wb25lbnRdLFxuICBwcm92aWRlcnM6IFtDb29raWVTZXJ2aWNlXVxufSlcbmV4cG9ydCBjbGFzcyBKd3RBdXRoZW50aWNhdGlvbk1vZHVsZSB7XG5cbiAgc3RhdGljIGZvclJvb3QoY29uZmlnOiBhbnkpOiBNb2R1bGVXaXRoUHJvdmlkZXJzIHtcbiAgICByZXR1cm4ge1xuICAgICAgbmdNb2R1bGU6IEp3dEF1dGhlbnRpY2F0aW9uTW9kdWxlLFxuICAgICAgcHJvdmlkZXJzOiBbSnd0QXV0aGVudGljYXRpb25TZXJ2aWNlLCB7IHByb3ZpZGU6ICdjb25maWcnLCB1c2VWYWx1ZTogY29uZmlnIH1dXG4gICAgfTtcbiAgfVxufVxuIl0sIm5hbWVzIjpbIkh0dHBIZWFkZXJzIiwibWFwIiwiY2F0Y2hFcnJvciIsInN3aXRjaE1hcCIsInRocm93RXJyb3IiLCJJbmplY3RhYmxlIiwiSHR0cENsaWVudCIsIkNvb2tpZVNlcnZpY2UiLCJJbmplY3QiLCJDb21wb25lbnQiLCJOZ01vZHVsZSIsIkh0dHBDbGllbnRNb2R1bGUiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7OztRQUNFLEtBQU0sS0FBSztRQUNYLE1BQU8sTUFBTTtRQUNiLE9BQVEsT0FBTztRQUNmLFFBQVMsUUFBUTtRQUNqQixLQUFNLEtBQUs7O1FBR2I7OztxQkFSQTtRQW1CQyxDQUFBO0FBWEQ7QUFjQSxRQUFhLFFBQVEsR0FBVztRQUM5QixVQUFVLEVBQUUsSUFBSTtRQUNoQixhQUFhLEVBQUUsZUFBZTtRQUM5QixjQUFjLEVBQUUsYUFBYTtRQUM3QixlQUFlLEVBQUUsY0FBYztRQUMvQixZQUFZLEVBQUUsV0FBVztRQUN6QixlQUFlLEVBQUUsR0FBRztRQUNwQixtQkFBbUIsRUFBRSxRQUFRO1FBQzdCLGtCQUFrQixFQUFFLGNBQWM7UUFDbEMsV0FBVyxFQUFFLGtCQUFrQjtRQUMvQixXQUFXLEVBQUUsTUFBTTtLQUNwQixDQUFDOzs7Ozs7QUNqQ0Y7UUFjRSxrQ0FBb0IsSUFBZ0IsRUFBVSxNQUFxQixFQUE0QixNQUFjO1lBQXpGLFNBQUksR0FBSixJQUFJLENBQVk7WUFBVSxXQUFNLEdBQU4sTUFBTSxDQUFlO1lBQTRCLFdBQU0sR0FBTixNQUFNLENBQVE7aUNBRnJGLElBQUksTUFBTSxFQUFFO1lBR2xDLElBQUksQ0FBQyxhQUFhLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsVUFBVSxJQUFJLFFBQVEsQ0FBQyxVQUFVLENBQUM7WUFDOUUsSUFBSSxDQUFDLGFBQWEsQ0FBQyxhQUFhLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxhQUFhLElBQUksUUFBUSxDQUFDLGFBQWEsQ0FBQztZQUN2RixJQUFJLENBQUMsYUFBYSxDQUFDLGNBQWMsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLGNBQWMsSUFBSSxRQUFRLENBQUMsY0FBYyxDQUFDO1lBQzFG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