UNPKG

@nebular/auth

Version:
270 lines 37.4 kB
/** * @license * Copyright Akveo. All Rights Reserved. * Licensed under the MIT License. See License.txt in the project root for license information. */ import { Injectable } from '@angular/core'; import { HttpErrorResponse } from '@angular/common/http'; import { of as observableOf } from 'rxjs'; import { switchMap, map, catchError } from 'rxjs/operators'; import { NbAuthResult } from '../../services/auth-result'; import { NbAuthStrategy } from '../auth-strategy'; import { passwordStrategyOptions } from './password-strategy-options'; import { NbAuthIllegalTokenError } from '../../services/token/token'; import * as i0 from "@angular/core"; import * as i1 from "@angular/common/http"; import * as i2 from "@angular/router"; /** * The most common authentication provider for email/password strategy. * * Strategy settings. Note, there is no need to copy over the whole object to change the settings you need. * Also, this.getOption call won't work outside of the default options declaration * (which is inside of the `NbPasswordAuthStrategy` class), so you have to replace it with a custom helper function * if you need it. * * ```ts *export class NbPasswordAuthStrategyOptions extends NbAuthStrategyOptions { * name: string; * baseEndpoint? = '/api/auth/'; * login?: boolean | NbPasswordStrategyModule = { * alwaysFail: false, * endpoint: 'login', * method: 'post', * requireValidToken: true, * redirect: { * success: '/', * failure: null, * }, * defaultErrors: ['Login/Email combination is not correct, please try again.'], * defaultMessages: ['You have been successfully logged in.'], * }; * register?: boolean | NbPasswordStrategyModule = { * alwaysFail: false, * endpoint: 'register', * method: 'post', * requireValidToken: true, * redirect: { * success: '/', * failure: null, * }, * defaultErrors: ['Something went wrong, please try again.'], * defaultMessages: ['You have been successfully registered.'], * }; * requestPass?: boolean | NbPasswordStrategyModule = { * endpoint: 'request-pass', * method: 'post', * redirect: { * success: '/', * failure: null, * }, * defaultErrors: ['Something went wrong, please try again.'], * defaultMessages: ['Reset password instructions have been sent to your email.'], * }; * resetPass?: boolean | NbPasswordStrategyReset = { * endpoint: 'reset-pass', * method: 'put', * redirect: { * success: '/', * failure: null, * }, * resetPasswordTokenKey: 'reset_password_token', * defaultErrors: ['Something went wrong, please try again.'], * defaultMessages: ['Your password has been successfully changed.'], * }; * logout?: boolean | NbPasswordStrategyReset = { * alwaysFail: false, * endpoint: 'logout', * method: 'delete', * redirect: { * success: '/', * failure: null, * }, * defaultErrors: ['Something went wrong, please try again.'], * defaultMessages: ['You have been successfully logged out.'], * }; * refreshToken?: boolean | NbPasswordStrategyModule = { * endpoint: 'refresh-token', * method: 'post', * requireValidToken: true, * redirect: { * success: null, * failure: null, * }, * defaultErrors: ['Something went wrong, please try again.'], * defaultMessages: ['Your token has been successfully refreshed.'], * }; * token?: NbPasswordStrategyToken = { * class: NbAuthSimpleToken, * key: 'data.token', * getter: (module: string, res: HttpResponse<Object>, options: NbPasswordAuthStrategyOptions) => getDeepFromObject( * res.body, * options.token.key, * ), * }; * errors?: NbPasswordStrategyMessage = { * key: 'data.errors', * getter: (module: string, res: HttpErrorResponse, options: NbPasswordAuthStrategyOptions) => getDeepFromObject( * res.error, * options.errors.key, * options[module].defaultErrors, * ), * }; * messages?: NbPasswordStrategyMessage = { * key: 'data.messages', * getter: (module: string, res: HttpResponse<Object>, options: NbPasswordAuthStrategyOptions) => getDeepFromObject( * res.body, * options.messages.key, * options[module].defaultMessages, * ), * }; * validation?: { * password?: { * required?: boolean; * minLength?: number | null; * maxLength?: number | null; * regexp?: string | null; * }; * email?: { * required?: boolean; * regexp?: string | null; * }; * fullName?: { * required?: boolean; * minLength?: number | null; * maxLength?: number | null; * regexp?: string | null; * }; * }; *} * ``` */ export class NbPasswordAuthStrategy extends NbAuthStrategy { constructor(http, route) { super(); this.http = http; this.route = route; this.defaultOptions = passwordStrategyOptions; } static setup(options) { return [NbPasswordAuthStrategy, options]; } authenticate(data) { const module = 'login'; const method = this.getOption(`${module}.method`); const url = this.getActionEndpoint(module); const requireValidToken = this.getOption(`${module}.requireValidToken`); return this.http.request(method, url, { body: data, observe: 'response', headers: this.getHeaders() }).pipe(map((res) => { if (this.getOption(`${module}.alwaysFail`)) { throw this.createFailResponse(data); } return res; }), map((res) => { return new NbAuthResult(true, res, this.getOption(`${module}.redirect.success`), [], this.getOption('messages.getter')(module, res, this.options), this.createToken(this.getOption('token.getter')(module, res, this.options), requireValidToken)); }), catchError((res) => { return this.handleResponseError(res, module); })); } register(data) { const module = 'register'; const method = this.getOption(`${module}.method`); const url = this.getActionEndpoint(module); const requireValidToken = this.getOption(`${module}.requireValidToken`); return this.http.request(method, url, { body: data, observe: 'response', headers: this.getHeaders() }).pipe(map((res) => { if (this.getOption(`${module}.alwaysFail`)) { throw this.createFailResponse(data); } return res; }), map((res) => { return new NbAuthResult(true, res, this.getOption(`${module}.redirect.success`), [], this.getOption('messages.getter')(module, res, this.options), this.createToken(this.getOption('token.getter')('login', res, this.options), requireValidToken)); }), catchError((res) => { return this.handleResponseError(res, module); })); } requestPassword(data) { const module = 'requestPass'; const method = this.getOption(`${module}.method`); const url = this.getActionEndpoint(module); return this.http.request(method, url, { body: data, observe: 'response', headers: this.getHeaders() }).pipe(map((res) => { if (this.getOption(`${module}.alwaysFail`)) { throw this.createFailResponse(); } return res; }), map((res) => { return new NbAuthResult(true, res, this.getOption(`${module}.redirect.success`), [], this.getOption('messages.getter')(module, res, this.options)); }), catchError((res) => { return this.handleResponseError(res, module); })); } resetPassword(data = {}) { const module = 'resetPass'; const method = this.getOption(`${module}.method`); const url = this.getActionEndpoint(module); const tokenKey = this.getOption(`${module}.resetPasswordTokenKey`); data[tokenKey] = this.route.snapshot.queryParams[tokenKey]; return this.http.request(method, url, { body: data, observe: 'response', headers: this.getHeaders() }).pipe(map((res) => { if (this.getOption(`${module}.alwaysFail`)) { throw this.createFailResponse(); } return res; }), map((res) => { return new NbAuthResult(true, res, this.getOption(`${module}.redirect.success`), [], this.getOption('messages.getter')(module, res, this.options)); }), catchError((res) => { return this.handleResponseError(res, module); })); } logout() { const module = 'logout'; const method = this.getOption(`${module}.method`); const url = this.getActionEndpoint(module); return observableOf({}).pipe(switchMap((res) => { if (!url) { return observableOf(res); } return this.http.request(method, url, { observe: 'response', headers: this.getHeaders() }); }), map((res) => { if (this.getOption(`${module}.alwaysFail`)) { throw this.createFailResponse(); } return res; }), map((res) => { return new NbAuthResult(true, res, this.getOption(`${module}.redirect.success`), [], this.getOption('messages.getter')(module, res, this.options)); }), catchError((res) => { return this.handleResponseError(res, module); })); } refreshToken(data) { const module = 'refreshToken'; const method = this.getOption(`${module}.method`); const url = this.getActionEndpoint(module); const requireValidToken = this.getOption(`${module}.requireValidToken`); return this.http.request(method, url, { body: data, observe: 'response', headers: this.getHeaders() }).pipe(map((res) => { if (this.getOption(`${module}.alwaysFail`)) { throw this.createFailResponse(data); } return res; }), map((res) => { return new NbAuthResult(true, res, this.getOption(`${module}.redirect.success`), [], this.getOption('messages.getter')(module, res, this.options), this.createToken(this.getOption('token.getter')(module, res, this.options), requireValidToken)); }), catchError((res) => { return this.handleResponseError(res, module); })); } handleResponseError(res, module) { let errors = []; if (res instanceof HttpErrorResponse) { errors = this.getOption('errors.getter')(module, res, this.options); } else if (res instanceof NbAuthIllegalTokenError) { errors.push(res.message); } else { errors.push('Something went wrong.'); } return observableOf(new NbAuthResult(false, res, this.getOption(`${module}.redirect.failure`), errors)); } } NbPasswordAuthStrategy.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.0.0", ngImport: i0, type: NbPasswordAuthStrategy, deps: [{ token: i1.HttpClient }, { token: i2.ActivatedRoute }], target: i0.ɵɵFactoryTarget.Injectable }); NbPasswordAuthStrategy.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.0.0", ngImport: i0, type: NbPasswordAuthStrategy }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.0.0", ngImport: i0, type: NbPasswordAuthStrategy, decorators: [{ type: Injectable }], ctorParameters: function () { return [{ type: i1.HttpClient }, { type: i2.ActivatedRoute }]; } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGFzc3dvcmQtc3RyYXRlZ3kuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9zcmMvZnJhbWV3b3JrL2F1dGgvc3RyYXRlZ2llcy9wYXNzd29yZC9wYXNzd29yZC1zdHJhdGVneS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7OztHQUlHO0FBQ0gsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMzQyxPQUFPLEVBQWMsaUJBQWlCLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUVyRSxPQUFPLEVBQWMsRUFBRSxJQUFJLFlBQVksRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUN0RCxPQUFPLEVBQUUsU0FBUyxFQUFFLEdBQUcsRUFBRSxVQUFVLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUU1RCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDMUQsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBRWxELE9BQU8sRUFBaUMsdUJBQXVCLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUNyRyxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQzs7OztBQUVyRTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBMkhHO0FBRUgsTUFBTSxPQUFPLHNCQUF1QixTQUFRLGNBQWM7SUFPeEQsWUFBc0IsSUFBZ0IsRUFBVSxLQUFxQjtRQUNuRSxLQUFLLEVBQUUsQ0FBQztRQURZLFNBQUksR0FBSixJQUFJLENBQVk7UUFBVSxVQUFLLEdBQUwsS0FBSyxDQUFnQjtRQU4zRCxtQkFBYyxHQUFrQyx1QkFBdUIsQ0FBQztJQVFsRixDQUFDO0lBTkQsTUFBTSxDQUFDLEtBQUssQ0FBQyxPQUFz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QyxlQUFlLENBQUMsQ0FBQyxNQUFNLEVBQUUsR0FBRyxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztTQUNyRTthQUFNLElBQUksR0FBRyxZQUFZLHVCQUF1QixFQUFFO1lBQ2pELE1BQU0sQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1NBQzFCO2FBQU07WUFDTCxNQUFNLENBQUMsSUFBSSxDQUFDLHVCQUF1QixDQUFDLENBQUM7U0FDdEM7UUFDRCxPQUFPLFlBQVksQ0FBQyxJQUFJLFlBQVksQ0FBQyxLQUFLLEVBQUUsR0FBRyxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsR0FBRyxNQUFNLG1CQUFtQixDQUFDLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQztJQUMxRyxDQUFDOzttSEF0TVUsc0JBQXNCO3VIQUF0QixzQkFBc0I7MkZBQXRCLHNCQUFzQjtrQkFEbEMsVUFBVSIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCBBa3Zlby4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS4gU2VlIExpY2Vuc2UudHh0IGluIHRoZSBwcm9qZWN0IHJvb3QgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24uXG4gKi9cbmltcG9ydCB7IEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEh0dHBDbGllbnQsIEh0dHBFcnJvclJlc3BvbnNlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uL2h0dHAnO1xuaW1wb3J0IHsgQWN0aXZhdGVkUm91dGUgfSBmcm9tICdAYW5ndWxhci9yb3V0ZXInO1xuaW1wb3J0IHsgT2JzZXJ2YWJsZSwgb2YgYXMgb2JzZXJ2YWJsZU9mIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBzd2l0Y2hNYXAsIG1hcCwgY2F0Y2hFcnJvciB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcblxuaW1wb3J0IHsgTmJBdXRoUmVzdWx0IH0gZnJvbSAnLi4vLi4vc2VydmljZXMvYXV0aC1yZXN1bHQnO1xuaW1wb3J0IHsgTmJBdXRoU3RyYXRlZ3kgfSBmcm9tICcuLi9hdXRoLXN0cmF0ZWd5JztcbmltcG9ydCB7IE5iQXV0aFN0cmF0ZWd5Q2xhc3MgfSBmcm9tICcuLi8uLi9hdXRoLm9wdGlvbnMnO1xuaW1wb3J0IHsgTmJQYXNzd29yZEF1dGhTdHJhdGVneU9wdGlvbnMsIHBhc3N3b3JkU3RyYXRlZ3lPcHRpb25zIH0gZnJvbSAnLi9wYXNzd29yZC1zdHJhdGVneS1vcHRpb25zJztcbmltcG9ydCB7IE5iQXV0aElsbGVnYWxUb2tlbkVycm9yIH0gZnJvbSAnLi4vLi4vc2VydmljZXMvdG9rZW4vdG9rZW4nO1xuXG4vKipcbiAqIFRoZSBtb3N0IGNvbW1vbiBhdXRoZW50aWNhdGlvbiBwcm92aWRlciBmb3IgZW1haWwvcGFzc3dvcmQgc3RyYXRlZ3kuXG4gKlxuICogU3RyYXRlZ3kgc2V0dGluZ3MuIE5vdGUsIHRoZXJlIGlzIG5vIG5lZWQgdG8gY29weSBvdmVyIHRoZSB3aG9sZSBvYmplY3QgdG8gY2hhbmdlIHRoZSBzZXR0aW5ncyB5b3UgbmVlZC5cbiAqIEFsc28sIHRoaXMuZ2V0T3B0aW9uIGNhbGwgd29uJ3Qgd29yayBvdXRzaWRlIG9mIHRoZSBkZWZhdWx0IG9wdGlvbnMgZGVjbGFyYXRpb25cbiAqICh3aGljaCBpcyBpbnNpZGUgb2YgdGhlIGBOYlBhc3N3b3JkQXV0aFN0cmF0ZWd5YCBjbGFzcyksIHNvIHlvdSBoYXZlIHRvIHJlcGxhY2UgaXQgd2l0aCBhIGN1c3RvbSBoZWxwZXIgZnVuY3Rpb25cbiAqIGlmIHlvdSBuZWVkIGl0LlxuICpcbiAqIGBgYHRzXG4gKmV4cG9ydCBjbGFzcyBOYlBhc3N3b3JkQXV0aFN0cmF0ZWd5T3B0aW9ucyBleHRlbmRzIE5iQXV0aFN0cmF0ZWd5T3B0aW9ucyB7XG4gKiAgbmFtZTogc3RyaW5nO1xuICogIGJhc2VFbmRwb2ludD8gPSAnL2FwaS9hdXRoLyc7XG4gKiAgbG9naW4/OiBib29sZWFuIHwgTmJQYXNzd29yZFN0cmF0ZWd5TW9kdWxlID0ge1xuICogICAgYWx3YXlzRmFpbDogZmFsc2UsXG4gKiAgICBlbmRwb2ludDogJ2xvZ2luJyxcbiAqICAgIG1ldGhvZDogJ3Bvc3QnLFxuICogICAgcmVxdWlyZVZhbGlkVG9rZW46IHRydWUsXG4gKiAgICByZWRpcmVjdDoge1xuICogICAgICBzdWNjZXNzOiAnLycsXG4gKiAgICAgIGZhaWx1cmU6IG51bGwsXG4gKiAgICB9LFxuICogICAgZGVmYXVsdEVycm9yczogWydMb2dpbi9FbWFpbCBjb21iaW5hdGlvbiBpcyBub3QgY29ycmVjdCwgcGxlYXNlIHRyeSBhZ2Fpbi4nXSxcbiAqICAgIGRlZmF1bHRNZXNzYWdlczogWydZb3UgaGF2ZSBiZWVuIHN1Y2Nlc3NmdWxseSBsb2dnZWQgaW4uJ10sXG4gKiAgfTtcbiAqICByZWdpc3Rlcj86IGJvb2xlYW4gfCBOYlBhc3N3b3JkU3RyYXRlZ3lNb2R1bGUgPSB7XG4gKiAgICBhbHdheXNGYWlsOiBmYWxzZSxcbiAqICAgIGVuZHBvaW50OiAncmVnaXN0ZXInLFxuICogICAgbWV0aG9kOiAncG9zdCcsXG4gKiAgICByZXF1aXJlVmFsaWRUb2tlbjogdHJ1ZSxcbiAqICAgIHJlZGlyZWN0OiB7XG4gKiAgICAgIHN1Y2Nlc3M6ICcvJyxcbiAqICAgICAgZmFpbHVyZTogbnVsbCxcbiAqICAgIH0sXG4gKiAgICBkZWZhdWx0RXJyb3JzOiBbJ1NvbWV0aGluZyB3ZW50IHdyb25nLCBwbGVhc2UgdHJ5IGFnYWluLiddLFxuICogICAgZGVmYXVsdE1lc3NhZ2VzOiBbJ1lvdSBoYXZlIGJlZW4gc3VjY2Vzc2Z1bGx5IHJlZ2lzdGVyZWQuJ10sXG4gKiAgfTtcbiAqICByZXF1ZXN0UGFzcz86IGJvb2xlYW4gfCBOYlBhc3N3b3JkU3RyYXRlZ3lNb2R1bGUgPSB7XG4gKiAgICBlbmRwb2ludDogJ3JlcXVlc3QtcGFzcycsXG4gKiAgICBtZXRob2Q6ICdwb3N0JyxcbiAqICAgIHJlZGlyZWN0OiB7XG4gKiAgICAgIHN1Y2Nlc3M6ICcvJyxcbiAqICAgICAgZmFpbHVyZTogbnVsbCxcbiAqICAgIH0sXG4gKiAgICBkZWZhdWx0RXJyb3JzOiBbJ1NvbWV0aGluZyB3ZW50IHdyb25nLCBwbGVhc2UgdHJ5IGFnYWluLiddLFxuICogICAgZGVmYXVsdE1lc3NhZ2VzOiBbJ1Jlc2V0IHBhc3N3b3JkIGluc3RydWN0aW9ucyBoYXZlIGJlZW4gc2VudCB0byB5b3VyIGVtYWlsLiddLFxuICogIH07XG4gKiAgcmVzZXRQYXNzPzogYm9vbGVhbiB8IE5iUGFzc3dvcmRTdHJhdGVneVJlc2V0ID0ge1xuICogICAgZW5kcG9pbnQ6ICdyZXNldC1wYXNzJyxcbiAqICAgIG1ldGhvZDogJ3B1dCcsXG4gKiAgICByZWRpcmVjdDoge1xuICogICAgICBzdWNjZXNzOiAnLycsXG4gKiAgICAgIGZhaWx1cmU6IG51bGwsXG4gKiAgICB9LFxuICogICAgcmVzZXRQYXNzd29yZFRva2VuS2V5OiAncmVzZXRfcGFzc3dvcmRfdG9rZW4nLFxuICogICAgZGVmYXVsdEVycm9yczogWydTb21ldGhpbmcgd2VudCB3cm9uZywgcGxlYXNlIHRyeSBhZ2Fpbi4nXSxcbiAqICAgIGRlZmF1bHRNZXNzYWdlczogWydZb3VyIHBhc3N3b3JkIGhhcyBiZWVuIHN1Y2Nlc3NmdWxseSBjaGFuZ2VkLiddLFxuICogIH07XG4gKiAgbG9nb3V0PzogYm9vbGVhbiB8IE5iUGFzc3dvcmRTdHJhdGVneVJlc2V0ID0ge1xuICogICAgYWx3YXlzRmFpbDogZmFsc2UsXG4gKiAgICBlbmRwb2ludDogJ2xvZ291dCcsXG4gKiAgICBtZXRob2Q6ICdkZWxldGUnLFxuICogICAgcmVkaXJlY3Q6IHtcbiAqICAgICAgc3VjY2VzczogJy8nLFxuICogICAgICBmYWlsdXJlOiBudWxsLFxuICogICAgfSxcbiAqICAgIGRlZmF1bHRFcnJvcnM6IFsnU29tZXRoaW5nIHdlbnQgd3JvbmcsIHBsZWFzZSB0cnkgYWdhaW4uJ10sXG4gKiAgICBkZWZhdWx0TWVzc2FnZXM6IFsnWW91IGhhdmUgYmVlbiBzdWNjZXNzZnVsbHkgbG9nZ2VkIG91dC4nXSxcbiAqICB9O1xuICogIHJlZnJlc2hUb2tlbj86IGJvb2xlYW4gfCBOYlBhc3N3b3JkU3RyYXRlZ3lNb2R1bGUgPSB7XG4gKiAgICBlbmRwb2ludDogJ3JlZnJlc2gtdG9rZW4nLFxuICogICAgbWV0aG9kOiAncG9zdCcsXG4gKiAgICByZXF1aXJlVmFsaWRUb2tlbjogdHJ1ZSxcbiAqICAgIHJlZGlyZWN0OiB7XG4gKiAgICAgIHN1Y2Nlc3M6IG51bGwsXG4gKiAgICAgIGZhaWx1cmU6IG51bGwsXG4gKiAgICB9LFxuICogICAgZGVmYXVsdEVycm9yczogWydTb21ldGhpbmcgd2VudCB3cm9uZywgcGxlYXNlIHRyeSBhZ2Fpbi4nXSxcbiAqICAgIGRlZmF1bHRNZXNzYWdlczogWydZb3VyIHRva2VuIGhhcyBiZWVuIHN1Y2Nlc3NmdWxseSByZWZyZXNoZWQuJ10sXG4gKiAgfTtcbiAqICB0b2tlbj86IE5iUGFzc3dvcmRTdHJhdGVneVRva2VuID0ge1xuICogICAgY2xhc3M6IE5iQXV0aFNpbXBsZVRva2VuLFxuICogICAga2V5OiAnZGF0YS50b2tlbicsXG4gKiAgICBnZXR0ZXI6IChtb2R1bGU6IHN0cmluZywgcmVzOiBIdHRwUmVzcG9uc2U8T2JqZWN0Piwgb3B0aW9uczogTmJQYXNzd29yZEF1dGhTdHJhdGVneU9wdGlvbnMpID0+IGdldERlZXBGcm9tT2JqZWN0KFxuICogICAgICByZXMuYm9keSxcbiAqICAgICAgb3B0aW9ucy50b2tlbi5rZXksXG4gKiAgICApLFxuICogIH07XG4gKiAgZXJyb3JzPzogTmJQYXNzd29yZFN0cmF0ZWd5TWVzc2FnZSA9IHtcbiAqICAgIGtleTogJ2RhdGEuZXJyb3JzJyxcbiAqICAgIGdldHRlcjogKG1vZHVsZTogc3RyaW5nLCByZXM6IEh0dHBFcnJvclJlc3BvbnNlLCBvcHRpb25zOiBOYlBhc3N3b3JkQXV0aFN0cmF0ZWd5T3B0aW9ucykgPT4gZ2V0RGVlcEZyb21PYmplY3QoXG4gKiAgICAgIHJlcy5lcnJvcixcbiAqICAgICAgb3B0aW9ucy5lcnJvcnMua2V5LFxuICogICAgICBvcHRpb25zW21vZHVsZV0uZGVmYXVsdEVycm9ycyxcbiAqICAgICksXG4gKiAgfTtcbiAqICBtZXNzYWdlcz86IE5iUGFzc3dvcmRTdHJhdGVneU1lc3NhZ2UgPSB7XG4gKiAgICBrZXk6ICdkYXRhLm1lc3NhZ2VzJyxcbiAqICAgIGdldHRlcjogKG1vZHVsZTogc3RyaW5nLCByZXM6IEh0dHBSZXNwb25zZTxPYmplY3Q+LCBvcHRpb25zOiBOYlBhc3N3b3JkQXV0aFN0cmF0ZWd5T3B0aW9ucykgPT4gZ2V0RGVlcEZyb21PYmplY3QoXG4gKiAgICAgIHJlcy5ib2R5LFxuICogICAgICBvcHRpb25zLm1lc3NhZ2VzLmtleSxcbiAqICAgICAgb3B0aW9uc1ttb2R1bGVdLmRlZmF1bHRNZXNzYWdlcyxcbiAqICAgICksXG4gKiAgfTtcbiAqICB2YWxpZGF0aW9uPzoge1xuICogICAgcGFzc3dvcmQ/OiB7XG4gKiAgICAgIHJlcXVpcmVkPzogYm9vbGVhbjtcbiAqICAgICAgbWluTGVuZ3RoPzogbnVtYmVyIHwgbnVsbDtcbiAqICAgICAgbWF4TGVuZ3RoPzogbnVtYmVyIHwgbnVsbDtcbiAqICAgICAgcmVnZXhwPzogc3RyaW5nIHwgbnVsbDtcbiAqICAgIH07XG4gKiAgICBlbWFpbD86IHtcbiAqICAgICAgcmVxdWlyZWQ/OiBib29sZWFuO1xuICogICAgICByZWdleHA/OiBzdHJpbmcgfCBudWxsO1xuICogICAgfTtcbiAqICAgIGZ1bGxOYW1lPzoge1xuICogICAgICByZXF1aXJlZD86IGJvb2xlYW47XG4gKiAgICAgIG1pbkxlbmd0aD86IG51bWJlciB8IG51bGw7XG4gKiAgICAgIG1heExlbmd0aD86IG51bWJlciB8IG51bGw7XG4gKiAgICAgIHJlZ2V4cD86IHN0cmluZyB8IG51bGw7XG4gKiAgICB9O1xuICogIH07XG4gKn1cbiAqIGBgYFxuICovXG5ASW5qZWN0YWJsZSgpXG5leHBvcnQgY2xhc3MgTmJQYXNzd29yZEF1dGhTdHJhdGVneSBleHRlbmRzIE5iQXV0aFN0cmF0ZWd5IHtcbiAgcHJvdGVjdGVkIGRlZmF1bHRPcHRpb25zOiBOYlBhc3N3b3JkQXV0aFN0cmF0ZWd5T3B0aW9ucyA9IHBhc3N3b3JkU3RyYXRlZ3lPcHRpb25zO1xuXG4gIHN0YXRpYyBzZXR1cChvcHRpb25zOiBOYlBhc3N3b3JkQXV0aFN0cmF0ZWd5T3B0aW9ucyk6IFtOYkF1dGhTdHJhdGVneUNsYXNzLCBOYlBhc3N3b3JkQXV0aFN0cmF0ZWd5T3B0aW9uc10ge1xuICAgIHJldHVybiBbTmJQYXNzd29yZEF1dGhTdHJhdGVneSwgb3B0aW9uc107XG4gIH1cblxuICBjb25zdHJ1Y3Rvcihwcm90ZWN0ZWQgaHR0cDogSHR0cENsaWVudCwgcHJpdmF0ZSByb3V0ZTogQWN0aXZhdGVkUm91dGUpIHtcbiAgICBzdXBlcigpO1xuICB9XG5cbiAgYXV0aGVudGljYXRlKGRhdGE/OiBhbnkpOiBPYnNlcnZhYmxlPE5iQXV0aFJlc3VsdD4ge1xuICAgIGNvbnN0IG1vZHVsZSA9ICdsb2dpbic7XG4gICAgY29uc3QgbWV0aG9kID0gdGhpcy5nZXRPcHRpb24oYCR7bW9kdWxlfS5tZXRob2RgKTtcbiAgICBjb25zdCB1cmwgPSB0aGlzLmdldEFjdGlvbkVuZHBvaW50KG1vZHVsZSk7XG4gICAgY29uc3QgcmVxdWlyZVZhbGlkVG9rZW4gPSB0aGlzLmdldE9wdGlvbihgJHttb2R1bGV9LnJlcXVpcmVWYWxpZFRva2VuYCk7XG4gICAgcmV0dXJuIHRoaXMuaHR0cC5yZXF1ZXN0KG1ldGhvZCwgdXJsLCB7IGJvZHk6IGRhdGEsIG9ic2VydmU6ICdyZXNwb25zZScsIGhlYWRlcnM6IHRoaXMuZ2V0SGVhZGVycygpIH0pLnBpcGUoXG4gICAgICBtYXAoKHJlcykgPT4ge1xuICAgICAgICBpZiAodGhpcy5nZXRPcHRpb24oYCR7bW9kdWxlfS5hbHdheXNGYWlsYCkpIHtcbiAgICAgICAgICB0aHJvdyB0aGlzLmNyZWF0ZUZhaWxSZXNwb25zZShkYXRhKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzO1xuICAgICAgfSksXG4gICAgICBtYXAoKHJlcykgPT4ge1xuICAgICAgICByZXR1cm4gbmV3IE5iQXV0aFJlc3VsdChcbiAgICAgICAgICB0cnVlLFxuICAgICAgICAgIHJlcyxcbiAgICAgICAgICB0aGlzLmdldE9wdGlvbihgJHttb2R1bGV9LnJlZGlyZWN0LnN1Y2Nlc3NgKSxcbiAgICAgICAgICBbXSxcbiAgICAgICAgICB0aGlzLmdldE9wdGlvbignbWVzc2FnZXMuZ2V0dGVyJykobW9kdWxlLCByZXMsIHRoaXMub3B0aW9ucyksXG4gICAgICAgICAgdGhpcy5jcmVhdGVUb2tlbih0aGlzLmdldE9wdGlvbigndG9rZW4uZ2V0dGVyJykobW9kdWxlLCByZXMsIHRoaXMub3B0aW9ucyksIHJlcXVpcmVWYWxpZFRva2VuKSxcbiAgICAgICAgKTtcbiAgICAgIH0pLFxuICAgICAgY2F0Y2hFcnJvcigocmVzKSA9PiB7XG4gICAgICAgIHJldHVybiB0aGlzLmhhbmRsZVJlc3BvbnNlRXJyb3IocmVzLCBtb2R1bGUpO1xuICAgICAgfSksXG4gICAgKTtcbiAgfVxuXG4gIHJlZ2lzdGVyKGRhdGE/OiBhbnkpOiBPYnNlcnZhYmxlPE5iQXV0aFJlc3VsdD4ge1xuICAgIGNvbnN0IG1vZHVsZSA9ICdyZWdpc3Rlcic7XG4gICAgY29uc3QgbWV0aG9kID0gdGhpcy5nZXRPcHRpb24oYCR7bW9kdWxlfS5tZXRob2RgKTtcbiAgICBjb25zdCB1cmwgPSB0aGlzLmdldEFjdGlvbkVuZHBvaW50KG1vZHVsZSk7XG4gICAgY29uc3QgcmVxdWlyZVZhbGlkVG9rZW4gPSB0aGlzLmdldE9wdGlvbihgJHttb2R1bGV9LnJlcXVpcmVWYWxpZFRva2VuYCk7XG4gICAgcmV0dXJuIHRoaXMuaHR0cC5yZXF1ZXN0KG1ldGhvZCwgdXJsLCB7IGJvZHk6IGRhdGEsIG9ic2VydmU6ICdyZXNwb25zZScsIGhlYWRlcnM6IHRoaXMuZ2V0SGVhZGVycygpIH0pLnBpcGUoXG4gICAgICBtYXAoKHJlcykgPT4ge1xuICAgICAgICBpZiAodGhpcy5nZXRPcHRpb24oYCR7bW9kdWxlfS5hbHdheXNGYWlsYCkpIHtcbiAgICAgICAgICB0aHJvdyB0aGlzLmNyZWF0ZUZhaWxSZXNwb25zZShkYXRhKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiByZXM7XG4gICAgICB9KSxcbiAgICAgIG1hcCgocmVzKSA9PiB7XG4gICAgICAgIHJldHVybiBuZXcgTmJBdXRoUmVzdWx0KFxuICAgICAgICAgIHRydWUsXG4gICAgICAgICAgcmVzLFxuICAgICAgICAgIHRoaXMuZ2V0T3B0aW9uKGAke21vZHVsZX0ucmVkaXJlY3Quc3VjY2Vzc2ApLFxuICAgICAgICAgIFtdLFxuICAgICAgICAgIHRoaXMuZ2V0T3B0aW9uKCdtZXNzYWdlcy5nZXR0ZXInKShtb2R1bGUsIHJlcywgdGhpcy5vcHRpb25zKSxcbiAgICAgICAgICB0aGlzLmNyZWF0ZVRva2VuKHRoaXMuZ2V0T3B0aW9uKCd0b2tlbi5nZXR0ZXInKSgnbG9naW4nLCByZXMsIHRoaXMub3B0aW9ucyksIHJlcXVpcmVWYWxpZFRva2VuKSxcbiAgICAgICAgKTtcbiAgICAgIH0pLFxuICAgICAgY2F0Y2hFcnJvcigocmVzKSA9PiB7XG4gICAgICAgIHJldHVybiB0aGlzLmhhbmRsZVJlc3BvbnNlRXJyb3IocmVzLCBtb2R1bGUpO1xuICAgICAgfSksXG4gICAgKTtcbiAgfVxuXG4gIHJlcXVlc3RQYXNzd29yZChkYXRhPzogYW55KTogT2JzZXJ2YWJsZTxOYkF1dGhSZXN1bHQ+IHtcbiAgICBjb25zdCBtb2R1bGUgPSAncmVxdWVzdFBhc3MnO1xuICAgIGNvbnN0IG1ldGhvZCA9IHRoaXMuZ2V0T3B0aW9uKGAke21vZHVsZX0ubWV0aG9kYCk7XG4gICAgY29uc3QgdXJsID0gdGhpcy5nZXRBY3Rpb25FbmRwb2ludChtb2R1bGUpO1xuICAgIHJldHVybiB0aGlzLmh0dHAucmVxdWVzdChtZXRob2QsIHVybCwgeyBib2R5OiBkYXRhLCBvYnNlcnZlOiAncmVzcG9uc2UnLCBoZWFkZXJzOiB0aGlzLmdldEhlYWRlcnMoKSB9KS5waXBlKFxuICAgICAgbWFwKChyZXMpID0+IHtcbiAgICAgICAgaWYgKHRoaXMuZ2V0T3B0aW9uKGAke21vZHVsZX0uYWx3YXlzRmFpbGApKSB7XG4gICAgICAgICAgdGhyb3cgdGhpcy5jcmVhdGVGYWlsUmVzcG9uc2UoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiByZXM7XG4gICAgICB9KSxcbiAgICAgIG1hcCgocmVzKSA9PiB7XG4gICAgICAgIHJldHVybiBuZXcgTmJBdXRoUmVzdWx0KFxuICAgICAgICAgIHRydWUsXG4gICAgICAgICAgcmVzLFxuICAgICAgICAgIHRoaXMuZ2V0T3B0aW9uKGAke21vZHVsZX0ucmVkaXJlY3Quc3VjY2Vzc2ApLFxuICAgICAgICAgIFtdLFxuICAgICAgICAgIHRoaXMuZ2V0T3B0aW9uKCdtZXNzYWdlcy5nZXR0ZXInKShtb2R1bGUsIHJlcywgdGhpcy5vcHRpb25zKSxcbiAgICAgICAgKTtcbiAgICAgIH0pLFxuICAgICAgY2F0Y2hFcnJvcigocmVzKSA9PiB7XG4gICAgICAgIHJldHVybiB0aGlzLmhhbmRsZVJlc3BvbnNlRXJyb3IocmVzLCBtb2R1bGUpO1xuICAgICAgfSksXG4gICAgKTtcbiAgfVxuXG4gIHJlc2V0UGFzc3dvcmQoZGF0YTogYW55ID0ge30pOiBPYnNlcnZhYmxlPE5iQXV0aFJlc3VsdD4ge1xuICAgIGNvbnN0IG1vZHVsZSA9ICdyZXNldFBhc3MnO1xuICAgIGNvbnN0IG1ldGhvZCA9IHRoaXMuZ2V0T3B0aW9uKGAke21vZHVsZX0ubWV0aG9kYCk7XG4gICAgY29uc3QgdXJsID0gdGhpcy5nZXRBY3Rpb25FbmRwb2ludChtb2R1bGUpO1xuICAgIGNvbnN0IHRva2VuS2V5ID0gdGhpcy5nZXRPcHRpb24oYCR7bW9kdWxlfS5yZXNldFBhc3N3b3JkVG9rZW5LZXlgKTtcbiAgICBkYXRhW3Rva2VuS2V5XSA9IHRoaXMucm91dGUuc25hcHNob3QucXVlcnlQYXJhbXNbdG9rZW5LZXldO1xuICAgIHJldHVybiB0aGlzLmh0dHAucmVxdWVzdChtZXRob2QsIHVybCwgeyBib2R5OiBkYXRhLCBvYnNlcnZlOiAncmVzcG9uc2UnLCBoZWFkZXJzOiB0aGlzLmdldEhlYWRlcnMoKSB9KS5waXBlKFxuICAgICAgbWFwKChyZXMpID0+IHtcbiAgICAgICAgaWYgKHRoaXMuZ2V0T3B0aW9uKGAke21vZHVsZX0uYWx3YXlzRmFpbGApKSB7XG4gICAgICAgICAgdGhyb3cgdGhpcy5jcmVhdGVGYWlsUmVzcG9uc2UoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiByZXM7XG4gICAgICB9KSxcbiAgICAgIG1hcCgocmVzKSA9PiB7XG4gICAgICAgIHJldHVybiBuZXcgTmJBdXRoUmVzdWx0KFxuICAgICAgICAgIHRydWUsXG4gICAgICAgICAgcmVzLFxuICAgICAgICAgIHRoaXMuZ2V0T3B0aW9uKGAke21vZHVsZX0ucmVkaXJlY3Quc3VjY2Vzc2ApLFxuICAgICAgICAgIFtdLFxuICAgICAgICAgIHRoaXMuZ2V0T3B0aW9uKCdtZXNzYWdlcy5nZXR0ZXInKShtb2R1bGUsIHJlcywgdGhpcy5vcHRpb25zKSxcbiAgICAgICAgKTtcbiAgICAgIH0pLFxuICAgICAgY2F0Y2hFcnJvcigocmVzKSA9PiB7XG4gICAgICAgIHJldHVybiB0aGlzLmhhbmRsZVJlc3BvbnNlRXJyb3IocmVzLCBtb2R1bGUpO1xuICAgICAgfSksXG4gICAgKTtcbiAgfVxuXG4gIGxvZ291dCgpOiBPYnNlcnZhYmxlPE5iQXV0aFJlc3VsdD4ge1xuICAgIGNvbnN0IG1vZHVsZSA9ICdsb2dvdXQnO1xuICAgIGNvbnN0IG1ldGhvZCA9IHRoaXMuZ2V0T3B0aW9uKGAke21vZHVsZX0ubWV0aG9kYCk7XG4gICAgY29uc3QgdXJsID0gdGhpcy5nZXRBY3Rpb25FbmRwb2ludChtb2R1bGUpO1xuXG4gICAgcmV0dXJuIG9ic2VydmFibGVPZih7fSkucGlwZShcbiAgICAgIHN3aXRjaE1hcCgocmVzOiBhbnkpID0+IHtcbiAgICAgICAgaWYgKCF1cmwpIHtcbiAgICAgICAgICByZXR1cm4gb2JzZXJ2YWJsZU9mKHJlcyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuaHR0cC5yZXF1ZXN0KG1ldGhvZCwgdXJsLCB7IG9ic2VydmU6ICdyZXNwb25zZScsIGhlYWRlcnM6IHRoaXMuZ2V0SGVhZGVycygpIH0pO1xuICAgICAgfSksXG4gICAgICBtYXAoKHJlcykgPT4ge1xuICAgICAgICBpZiAodGhpcy5nZXRPcHRpb24oYCR7bW9kdWxlfS5hbHdheXNGYWlsYCkpIHtcbiAgICAgICAgICB0aHJvdyB0aGlzLmNyZWF0ZUZhaWxSZXNwb25zZSgpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHJlcztcbiAgICAgIH0pLFxuICAgICAgbWFwKChyZXMpID0+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBOYkF1dGhSZXN1bHQoXG4gICAgICAgICAgdHJ1ZSxcbiAgICAgICAgICByZXMsXG4gICAgICAgICAgdGhpcy5nZXRPcHRpb24oYCR7bW9kdWxlfS5yZWRpcmVjdC5zdWNjZXNzYCksXG4gICAgICAgICAgW10sXG4gICAgICAgICAgdGhpcy5nZXRPcHRpb24oJ21lc3NhZ2VzLmdldHRlcicpKG1vZHVsZSwgcmVzLCB0aGlzLm9wdGlvbnMpLFxuICAgICAgICApO1xuICAgICAgfSksXG4gICAgICBjYXRjaEVycm9yKChyZXMpID0+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaGFuZGxlUmVzcG9uc2VFcnJvcihyZXMsIG1vZHVsZSk7XG4gICAgICB9KSxcbiAgICApO1xuICB9XG5cbiAgcmVmcmVzaFRva2VuKGRhdGE/OiBhbnkpOiBPYnNlcnZhYmxlPE5iQXV0aFJlc3VsdD4ge1xuICAgIGNvbnN0IG1vZHVsZSA9ICdyZWZyZXNoVG9rZW4nO1xuICAgIGNvbnN0IG1ldGhvZCA9IHRoaXMuZ2V0T3B0aW9uKGAke21vZHVsZX0ubWV0aG9kYCk7XG4gICAgY29uc3QgdXJsID0gdGhpcy5nZXRBY3Rpb25FbmRwb2ludChtb2R1bGUpO1xuICAgIGNvbnN0IHJlcXVpcmVWYWxpZFRva2VuID0gdGhpcy5nZXRPcHRpb24oYCR7bW9kdWxlfS5yZXF1aXJlVmFsaWRUb2tlbmApO1xuXG4gICAgcmV0dXJuIHRoaXMuaHR0cC5yZXF1ZXN0KG1ldGhvZCwgdXJsLCB7IGJvZHk6IGRhdGEsIG9ic2VydmU6ICdyZXNwb25zZScsIGhlYWRlcnM6IHRoaXMuZ2V0SGVhZGVycygpIH0pLnBpcGUoXG4gICAgICBtYXAoKHJlcykgPT4ge1xuICAgICAgICBpZiAodGhpcy5nZXRPcHRpb24oYCR7bW9kdWxlfS5hbHdheXNGYWlsYCkpIHtcbiAgICAgICAgICB0aHJvdyB0aGlzLmNyZWF0ZUZhaWxSZXNwb25zZShkYXRhKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiByZXM7XG4gICAgICB9KSxcbiAgICAgIG1hcCgocmVzKSA9PiB7XG4gICAgICAgIHJldHVybiBuZXcgTmJBdXRoUmVzdWx0KFxuICAgICAgICAgIHRydWUsXG4gICAgICAgICAgcmVzLFxuICAgICAgICAgIHRoaXMuZ2V0T3B0aW9uKGAke21vZHVsZX0ucmVkaXJlY3Quc3VjY2Vzc2ApLFxuICAgICAgICAgIFtdLFxuICAgICAgICAgIHRoaXMuZ2V0T3B0aW9uKCdtZXNzYWdlcy5nZXR0ZXInKShtb2R1bGUsIHJlcywgdGhpcy5vcHRpb25zKSxcbiAgICAgICAgICB0aGlzLmNyZWF0ZVRva2VuKHRoaXMuZ2V0T3B0aW9uKCd0b2tlbi5nZXR0ZXInKShtb2R1bGUsIHJlcywgdGhpcy5vcHRpb25zKSwgcmVxdWlyZVZhbGlkVG9rZW4pLFxuICAgICAgICApO1xuICAgICAgfSksXG4gICAgICBjYXRjaEVycm9yKChyZXMpID0+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaGFuZGxlUmVzcG9uc2VFcnJvcihyZXMsIG1vZHVsZSk7XG4gICAgICB9KSxcbiAgICApO1xuICB9XG5cbiAgcHJvdGVjdGVkIGhhbmRsZVJlc3BvbnNlRXJyb3IocmVzOiBhbnksIG1vZHVsZTogc3RyaW5nKTogT2JzZXJ2YWJsZTxOYkF1dGhSZXN1bHQ+IHtcbiAgICBsZXQgZXJyb3JzID0gW107XG4gICAgaWYgKHJlcyBpbnN0YW5jZW9mIEh0dHBFcnJvclJlc3BvbnNlKSB7XG4gICAgICBlcnJvcnMgPSB0aGlzLmdldE9wdGlvbignZXJyb3JzLmdldHRlcicpKG1vZHVsZSwgcmVzLCB0aGlzLm9wdGlvbnMpO1xuICAgIH0gZWxzZSBpZiAocmVzIGluc3RhbmNlb2YgTmJBdXRoSWxsZWdhbFRva2VuRXJyb3IpIHtcbiAgICAgIGVycm9ycy5wdXNoKHJlcy5tZXNzYWdlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgZXJyb3JzLnB1c2goJ1NvbWV0aGluZyB3ZW50IHdyb25nLicpO1xuICAgIH1cbiAgICByZXR1cm4gb2JzZXJ2YWJsZU9mKG5ldyBOYkF1dGhSZXN1bHQoZmFsc2UsIHJlcywgdGhpcy5nZXRPcHRpb24oYCR7bW9kdWxlfS5yZWRpcmVjdC5mYWlsdXJlYCksIGVycm9ycykpO1xuICB9XG59XG4iXX0=