UNPKG

@terminus/ngx-tools

Version:

[![CircleCI][circle-badge]][circle-link] [![codecov][codecov-badge]][codecov-project] [![semantic-release][semantic-release-badge]][semantic-release] [![MIT License][license-image]][license-url] <br> [![NPM version][npm-version-image]][npm-url] [![Github

136 lines 23.3 kB
import { __decorate, __param } from "tslib"; import { Inject, Injectable, InjectionToken, Optional, } from '@angular/core'; import { Actions, Effect, ofType, } from '@ngrx/effects'; import { Store } from '@ngrx/store'; import { TsCookieService } from '@terminus/ngx-tools/browser'; import { merge, of, Scheduler, timer, } from 'rxjs'; import { async } from 'rxjs/internal/scheduler/async'; import { delay, filter, flatMap, map, mergeMap, take, withLatestFrom, } from 'rxjs/operators'; import { jwtDecode } from '../jwt-decode/jwt-decode'; import * as JwtTokenProviderActions from './actions'; import { getJwtTokenRoot, getTokens, } from './selectors'; import { INITIAL_TOKEN_NAME } from './tokens'; import { SCHEDULER } from './utilities/retry-with-escalation'; export const SECONDS_BEFORE_EXPIRATION_TO_NOTIFY = new InjectionToken('wait time'); const SECONDS_IN_MINUTE = 60; const DEFAULT_MINUTES_BEFORE_EXPIRATION_TO_NOTIFY = 5; const DEFAULT_SECONDS_BEFORE_EXPIRATION_TO_NOTIFY = DEFAULT_MINUTES_BEFORE_EXPIRATION_TO_NOTIFY * SECONDS_IN_MINUTE; const CLEANUP_DELAY = 100; const TOKENS_EXPIRED_DELAY = 10; const MS_IN_SECONDS = 1000; let JwtTokenProviderEffects = class JwtTokenProviderEffects { constructor(actions$, // eslint-disable-next-line @typescript-eslint/no-explicit-any store, cookieService, initialTokenName, scheduler, timeToWaitBeforeExpiration) { this.actions$ = actions$; this.store = store; this.cookieService = cookieService; this.initialTokenName = initialTokenName; this.scheduler = scheduler; this.timeToWaitBeforeExpiration = timeToWaitBeforeExpiration; this.initializationCleanup$ = of(true) .pipe(delay(CLEANUP_DELAY, this.scheduler || async), withLatestFrom(this.store.select(getTokens())), map(([_, tokens]) => tokens), take(1), flatMap(tokens => { const actions = []; for (const tokenName in tokens) { if (tokens.hasOwnProperty(tokenName)) { const token = tokens[tokenName]; if (token) { actions.push(new JwtTokenProviderActions.StoreToken({ tokenName, token, })); } } } return actions; })); this.allTokensExpired$ = this.actions$ .pipe(ofType(JwtTokenProviderActions.ActionTypes.TokenExpired), delay(TOKENS_EXPIRED_DELAY, this.scheduler || async), withLatestFrom(this.store.select(getTokens())), map(([_, tokens]) => tokens), filter(tokens => Object.keys(tokens).length === 0), map(tokens => new JwtTokenProviderActions.AllTokensExpired())); this.notifyOfTokenExpiration$ = this.actions$ .pipe(ofType(JwtTokenProviderActions.ActionTypes.StoreToken), // eslint-disable-next-line max-len map((action) => [action, jwtDecode(action.token)]), filter((a) => a[1].exp !== undefined), mergeMap(([action, claims]) => { const currentEpoch = Math.ceil((new Date()).getTime() / MS_IN_SECONDS); if (claims.exp > currentEpoch) { const expiresIn = claims.exp - currentEpoch; const expirationBuffer = this.timeToWaitBeforeExpiration || DEFAULT_SECONDS_BEFORE_EXPIRATION_TO_NOTIFY; let expirationNearIn = 0; if (expiresIn < expirationBuffer) { expirationNearIn = 1; } else { expirationNearIn = expiresIn - expirationBuffer; } return merge(this.buildDelayedExpirationObservable(expirationNearIn * MS_IN_SECONDS, action, false), this.buildDelayedExpirationObservable(expiresIn * MS_IN_SECONDS, action, true)); } return of(new JwtTokenProviderActions.TokenExpired({ tokenName: action.tokenName, token: action.token, })); })); this.initialCookieLoader$ = ({ currentState = this.store.select(getJwtTokenRoot()), } = {}) => of(true).pipe(take(1), withLatestFrom(currentState), filter(([_, state]) => !!(state && state.jwtTokens.initialTokenStatus === 'uninitialized')), mergeMap(([a, _]) => { const cookie = this.cookieService.get('jwt_cookie'); if (cookie.length > 0) { return [ new JwtTokenProviderActions.InitialTokenExtracted(cookie), new JwtTokenProviderActions.StoreToken({ tokenName: this.initialTokenName, token: cookie, isDefaultToken: true, }), ]; } return [ new JwtTokenProviderActions.InitialTokenExtracted(cookie), ]; })); } /* * This next function is being excluded from coverage due the complexities of testing the `delay` function. * In order to test as much as possible, each piece has been separated into smaller testable functions. */ buildDelayedExpirationObservable(emitTime, action, expired) { const outputActionArgs = { tokenName: action.tokenName, token: action.token, }; return timer(emitTime, this.scheduler || async).pipe(take(1), map(() => (expired ? new JwtTokenProviderActions.TokenExpired(outputActionArgs) : new JwtTokenProviderActions.TokenNearingExpiration(outputActionArgs)))); } }; JwtTokenProviderEffects.ctorParameters = () => [ { type: Actions }, { type: Store }, { type: TsCookieService }, { type: String, decorators: [{ type: Inject, args: [INITIAL_TOKEN_NAME,] }] }, { type: Scheduler, decorators: [{ type: Optional }, { type: Inject, args: [SCHEDULER,] }] }, { type: Number, decorators: [{ type: Optional }, { type: Inject, args: [SECONDS_BEFORE_EXPIRATION_TO_NOTIFY,] }] } ]; __decorate([ Effect() ], JwtTokenProviderEffects.prototype, "initializationCleanup$", void 0); __decorate([ Effect() ], JwtTokenProviderEffects.prototype, "allTokensExpired$", void 0); __decorate([ Effect() ], JwtTokenProviderEffects.prototype, "notifyOfTokenExpiration$", void 0); __decorate([ Effect() ], JwtTokenProviderEffects.prototype, "initialCookieLoader$", void 0); JwtTokenProviderEffects = __decorate([ Injectable(), __param(3, Inject(INITIAL_TOKEN_NAME)), __param(4, Optional()), __param(4, Inject(SCHEDULER)) // TODO: Scheduler is marked as deprecated to stop others from using although it is not technically deprecated from // what I can tell. The 'correct' path would be to create our own class extending `SchedulerLike`. // https://github.com/GetTerminus/ngx-tools/issues/287 // eslint-disable-next-line deprecation/deprecation , __param(5, Optional()), __param(5, Inject(SECONDS_BEFORE_EXPIRATION_TO_NOTIFY)) ], JwtTokenProviderEffects); export { JwtTokenProviderEffects }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWZmZWN0cy5qcyIsInNvdXJjZVJvb3QiOiJuZzovL0B0ZXJtaW51cy9uZ3gtdG9vbHMvand0LyIsInNvdXJjZXMiOlsiand0LXRva2VuLW1hbmFnbWVudC9lZmZlY3RzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxPQUFPLEVBQ0wsTUFBTSxFQUNOLFVBQVUsRUFDVixjQUFjLEVBQ2QsUUFBUSxHQUNULE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFDTCxPQUFPLEVBQ1AsTUFBTSxFQUNOLE1BQU0sR0FDUCxNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsS0FBSyxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQ3BDLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUM5RCxPQUFPLEVBQ0wsS0FBSyxFQUNMLEVBQUUsRUFDRixTQUFTLEVBQ1QsS0FBSyxHQUNOLE1BQU0sTUFBTSxDQUFDO0FBQ2QsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBQ3RELE9BQU8sRUFDTCxLQUFLLEVBQ0wsTUFBTSxFQUNOLE9BQU8sRUFDUCxHQUFHLEVBQ0gsUUFBUSxFQUNSLElBQUksRUFDSixjQUFjLEdBQ2YsTUFBTSxnQkFBZ0IsQ0FBQztBQUV4QixPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFFckQsT0FBTyxLQUFLLHVCQUF1QixNQUFNLFdBQVcsQ0FBQztBQUNyRCxPQUFPLEVBQ0wsZUFBZSxFQUNmLFNBQVMsR0FDVixNQUFNLGFBQWEsQ0FBQztBQUNyQixPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxVQUFVLENBQUM7QUFDOUMsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLG1DQUFtQyxDQUFDO0FBUzlELE1BQU0sQ0FBQyxNQUFNLG1DQUFtQyxHQUFHLElBQUksY0FBYyxDQUFTLFdBQVcsQ0FBQyxDQUFDO0FBRTNGLE1BQU0saUJBQWlCLEdBQUcsRUFBRSxDQUFDO0FBQzdCLE1B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QU8sS0FBSyxDQUFDLFFBQVEsRUFBRSxJQUFJLENBQUMsU0FBUyxJQUFJLEtBQUssQ0FBQyxDQUFDLElBQUksQ0FDbEQsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUNQLEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDLE9BQU87WUFDaEIsQ0FBQyxDQUFDLElBQUksdUJBQXVCLENBQUMsWUFBWSxDQUFrQixnQkFBZ0IsQ0FBQztZQUM3RSxDQUFDLENBQUMsSUFBSSx1QkFBdUIsQ0FBQyxzQkFBc0IsQ0FBa0IsZ0JBQWdCLENBQUMsQ0FBQyxDQUFDLENBQzVGLENBQUM7SUFDSixDQUFDO0NBQ0YsQ0FBQTs7WUF4SnFCLE9BQU87WUFFVixLQUFLO1lBQ0csZUFBZTt5Q0FFckMsTUFBTSxTQUFDLGtCQUFrQjtZQVNQLFNBQVMsdUJBTjNCLFFBQVEsWUFDUixNQUFNLFNBQUMsU0FBUzt5Q0FPaEIsUUFBUSxZQUNSLE1BQU0sU0FBQyxtQ0FBbUM7O0FBTTdDO0lBREMsTUFBTSxFQUFFO3VFQTRCUjtBQUlEO0lBREMsTUFBTSxFQUFFO2tFQVlSO0FBSUQ7SUFEQyxNQUFNLEVBQUU7eUVBaUNSO0FBSUQ7SUFEQyxNQUFNLEVBQUU7cUVBd0JQO0FBbklTLHVCQUF1QjtJQURuQyxVQUFVLEVBQUU7SUFTUixXQUFBLE1BQU0sQ0FBQyxrQkFBa0IsQ0FBQyxDQUFBO0lBRzFCLFdBQUEsUUFBUSxFQUFFLENBQUE7SUFDVixXQUFBLE1BQU0sQ0FBQyxTQUFTLENBQUMsQ0FBQTtJQUNsQixtSEFBbUg7SUFDbkgsa0dBQWtHO0lBQ2xHLHNEQUFzRDtJQUN0RCxtREFBbUQ7O0lBR2xELFdBQUEsUUFBUSxFQUFFLENBQUE7SUFDVixXQUFBLE1BQU0sQ0FBQyxtQ0FBbUMsQ0FBQyxDQUFBO0dBcEJuQyx1QkFBdUIsQ0EySm5DO1NBM0pZLHVCQUF1QiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIEluamVjdCxcbiAgSW5qZWN0YWJsZSxcbiAgSW5qZWN0aW9uVG9rZW4sXG4gIE9wdGlvbmFsLFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7XG4gIEFjdGlvbnMsXG4gIEVmZmVjdCxcbiAgb2ZUeXBlLFxufSBmcm9tICdAbmdyeC9lZmZlY3RzJztcbmltcG9ydCB7IFN0b3JlIH0gZnJvbSAnQG5ncngvc3RvcmUnO1xuaW1wb3J0IHsgVHNDb29raWVTZXJ2aWNlIH0gZnJvbSAnQHRlcm1pbnVzL25neC10b29scy9icm93c2VyJztcbmltcG9ydCB7XG4gIG1lcmdlLFxuICBvZixcbiAgU2NoZWR1bGVyLFxuICB0aW1lcixcbn0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBhc3luYyB9IGZyb20gJ3J4anMvaW50ZXJuYWwvc2NoZWR1bGVyL2FzeW5jJztcbmltcG9ydCB7XG4gIGRlbGF5LFxuICBmaWx0ZXIsXG4gIGZsYXRNYXAsXG4gIG1hcCxcbiAgbWVyZ2VNYXAsXG4gIHRha2UsXG4gIHdpdGhMYXRlc3RGcm9tLFxufSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5cbmltcG9ydCB7IGp3dERlY29kZSB9IGZyb20gJy4uL2p3dC1kZWNvZGUvand0LWRlY29kZSc7XG5cbmltcG9ydCAqIGFzIEp3dFRva2VuUHJvdmlkZXJBY3Rpb25zIGZyb20gJy4vYWN0aW9ucyc7XG5pbXBvcnQge1xuICBnZXRKd3RUb2tlblJvb3QsXG4gIGdldFRva2Vucyxcbn0gZnJvbSAnLi9zZWxlY3RvcnMnO1xuaW1wb3J0IHsgSU5JVElBTF9UT0tFTl9OQU1FIH0gZnJvbSAnLi90b2tlbnMnO1xuaW1wb3J0IHsgU0NIRURVTEVSIH0gZnJvbSAnLi91dGlsaXRpZXMvcmV0cnktd2l0aC1lc2NhbGF0aW9uJztcblxuXG5leHBvcnQgaW50ZXJmYWNlIENsYWltcyB7IGV4cDogbnVtYmVyOyB9XG5cbmV4cG9ydCBpbnRlcmZhY2UgTWluaW1hbENsYWltTWFwIHtcbiAgW2lkOiBzdHJpbmddOiBDbGFpbXM7XG59XG5cbmV4cG9ydCBjb25zdCBTRUNPTkRTX0JFRk9SRV9FWFBJUkFUSU9OX1RPX05PVElGWSA9IG5ldyBJbmplY3Rpb25Ub2tlbjxudW1iZXI+KCd3YWl0IHRpbWUnKTtcblxuY29uc3QgU0VDT05EU19JTl9NSU5VVEUgPSA2MDtcbmNvbnN0IERFRkFVTFRfTUlOVVRFU19CRUZPUkVfRVhQSVJBVElPTl9UT19OT1RJRlkgPSA1O1xuY29uc3QgREVGQVVMVF9TRUNPTkRTX0JFRk9SRV9FWFBJUkFUSU9OX1RPX05PVElGWSA9IERFRkFVTFRfTUlOVVRFU19CRUZPUkVfRVhQSVJBVElPTl9UT19OT1RJRlkgKiBTRUNPTkRTX0lOX01JTlVURTtcbmNvbnN0IENMRUFOVVBfREVMQVkgPSAxMDA7XG5jb25zdCBUT0tFTlNfRVhQSVJFRF9ERUxBWSA9IDEwO1xuY29uc3QgTVNfSU5fU0VDT05EUyA9IDEwMDA7XG5cbnR5cGUgUGFydGlhbENsYWltVHVwbGUgPSBbXG4gIEp3dFRva2VuUHJvdmlkZXJBY3Rpb25zLlN0b3JlVG9rZW48TWluaW1hbENsYWltTWFwPixcbiAgUGFydGlhbDxDbGFpbXM+XG5dO1xuXG50eXBlIEZ1bGxDbGFpbXNUdXBsZSA9IFtcbiAgSnd0VG9rZW5Qcm92aWRlckFjdGlvbnMuU3RvcmVUb2tlbjxNaW5pbWFsQ2xhaW1NYXA+LFxuICBDbGFpbXNcbl07XG5cblxuQEluamVjdGFibGUoKVxuZXhwb3J0IGNsYXNzIEp3dFRva2VuUHJvdmlkZXJFZmZlY3RzIHtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIGFjdGlvbnMkOiBBY3Rpb25zPEp3dFRva2VuUHJvdmlkZXJBY3Rpb25zLkFjdGlvbnM8TWluaW1hbENsYWltTWFwPj4sXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcbiAgICBwcml2YXRlIHN0b3JlOiBTdG9yZTxhbnk+LFxuICAgIHByaXZhdGUgY29va2llU2VydmljZTogVHNDb29raWVTZXJ2aWNlLFxuXG4gICAgQEluamVjdChJTklUSUFMX1RPS0VOX05BTUUpXG4gICAgcHJpdmF0ZSBpbml0aWFsVG9rZW5OYW1lOiBzdHJpbmcsXG5cbiAgICBAT3B0aW9uYWwoKVxuICAgIEBJbmplY3QoU0NIRURVTEVSKVxuICAgIC8vIFRPRE86IFNjaGVkdWxlciBpcyBtYXJrZWQgYXMgZGVwcmVjYXRlZCB0byBzdG9wIG90aGVycyBmcm9tIHVzaW5nIGFsdGhvdWdoIGl0IGlzIG5vdCB0ZWNobmljYWxseSBkZXByZWNhdGVkIGZyb21cbiAgICAvLyB3aGF0IEkgY2FuIHRlbGwuIFRoZSAnY29ycmVjdCcgcGF0aCB3b3VsZCBiZSB0byBjcmVhdGUgb3VyIG93biBjbGFzcyBleHRlbmRpbmcgYFNjaGVkdWxlckxpa2VgLlxuICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9HZXRUZXJtaW51cy9uZ3gtdG9vbHMvaXNzdWVzLzI4N1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBkZXByZWNhdGlvbi9kZXByZWNhdGlvblxuICAgIHByaXZhdGUgc2NoZWR1bGVyOiBTY2hlZHVsZXIsXG5cbiAgICBAT3B0aW9uYWwoKVxuICAgIEBJbmplY3QoU0VDT05EU19CRUZPUkVfRVhQSVJBVElPTl9UT19OT1RJRlkpXG4gICAgcHJpdmF0ZSB0aW1lVG9XYWl0QmVmb3JlRXhwaXJhdGlvbjogbnVtYmVyLFxuICApIHt9XG5cblxuICBARWZmZWN0KClcbiAgcHVibGljIGluaXRpYWxpemF0aW9uQ2xlYW51cCQgPSBvZih0cnVlKVxuICAgIC5waXBlKFxuICAgICAgZGVsYXkoQ0xFQU5VUF9ERUxBWSwgdGhpcy5zY2hlZHVsZXIgfHwgYXN5bmMpLFxuICAgICAgd2l0aExhdGVzdEZyb20oXG4gICAgICAgIHRoaXMuc3RvcmUuc2VsZWN0KGdldFRva2VuczxNaW5pbWFsQ2xhaW1NYXA+KCkpLFxuICAgICAgKSxcbiAgICAgIG1hcCgoW18sIHRva2Vuc10pID0+IHRva2VucyksXG4gICAgICB0YWtlKDEpLFxuICAgICAgZmxhdE1hcCh0b2tlbnMgPT4ge1xuICAgICAgICBjb25zdCBhY3Rpb25zOiBKd3RUb2tlblByb3ZpZGVyQWN0aW9ucy5TdG9yZVRva2VuPE1pbmltYWxDbGFpbU1hcD5bXSA9IFtdO1xuXG4gICAgICAgIGZvciAoY29uc3QgdG9rZW5OYW1lIGluIHRva2Vucykge1xuICAgICAgICAgIGlmICh0b2tlbnMuaGFzT3duUHJvcGVydHkodG9rZW5OYW1lKSkge1xuICAgICAgICAgICAgY29uc3QgdG9rZW4gPSB0b2tlbnNbdG9rZW5OYW1lXTtcbiAgICAgICAgICAgIGlmICh0b2tlbikge1xuICAgICAgICAgICAgICBhY3Rpb25zLnB1c2goXG4gICAgICAgICAgICAgICAgbmV3IEp3dFRva2VuUHJvdmlkZXJBY3Rpb25zLlN0b3JlVG9rZW4oe1xuICAgICAgICAgICAgICAgICAgdG9rZW5OYW1lLFxuICAgICAgICAgICAgICAgICAgdG9rZW4sXG4gICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBhY3Rpb25zO1xuICAgICAgfSksXG4gICAgKVxuICA7XG5cblxuICBARWZmZWN0KClcbiAgcHVibGljIGFsbFRva2Vuc0V4cGlyZWQkID0gdGhpcy5hY3Rpb25zJFxuICAgIC5waXBlKFxuICAgICAgb2ZUeXBlPG5ldmVyPihKd3RUb2tlblByb3ZpZGVyQWN0aW9ucy5BY3Rpb25UeXBlcy5Ub2tlbkV4cGlyZWQpLFxuICAgICAgZGVsYXkoVE9LRU5TX0VYUElSRURfREVMQVksIHRoaXMuc2NoZWR1bGVyIHx8IGFzeW5jKSxcbiAgICAgIHdpdGhMYXRlc3RGcm9tKFxuICAgICAgICB0aGlzLnN0b3JlLnNlbGVjdChnZXRUb2tlbnM8TWluaW1hbENsYWltTWFwPigpKSxcbiAgICAgICksXG4gICAgICBtYXAoKFtfLCB0b2tlbnNdKSA9PiB0b2tlbnMpLFxuICAgICAgZmlsdGVyKHRva2VucyA9PiBPYmplY3Qua2V5cyh0b2tlbnMpLmxlbmd0aCA9PT0gMCksXG4gICAgICBtYXAodG9rZW5zID0+IG5ldyBKd3RUb2tlblByb3ZpZGVyQWN0aW9ucy5BbGxUb2tlbnNFeHBpcmVkKCkpLFxuICAgIClcbiAgO1xuXG5cbiAgQEVmZmVjdCgpXG4gIHB1YmxpYyBub3RpZnlPZlRva2VuRXhwaXJhdGlvbiQgPSB0aGlzLmFjdGlvbnMkXG4gICAgLnBpcGUoXG4gICAgICBvZlR5cGU8Snd0VG9rZW5Qcm92aWRlckFjdGlvbnMuU3RvcmVUb2tlbjxNaW5pbWFsQ2xhaW1NYXA+PihKd3RUb2tlblByb3ZpZGVyQWN0aW9ucy5BY3Rpb25UeXBlcy5TdG9yZVRva2VuKSxcbiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBtYXgtbGVuXG4gICAgICBtYXAoKGFjdGlvbjogSnd0VG9rZW5Qcm92aWRlckFjdGlvbnMuU3RvcmVUb2tlbjxNaW5pbWFsQ2xhaW1NYXA+KTogUGFydGlhbENsYWltVHVwbGUgPT4gW2FjdGlvbiwgand0RGVjb2RlPFBhcnRpYWw8Q2xhaW1zPj4oYWN0aW9uLnRva2VuKV0pLFxuICAgICAgZmlsdGVyKChhOiBQYXJ0aWFsQ2xhaW1UdXBsZSk6IGEgaXMgRnVsbENsYWltc1R1cGxlID0+IGFbMV0uZXhwICE9PSB1bmRlZmluZWQpLFxuICAgICAgbWVyZ2VNYXAoKFthY3Rpb24sIGNsYWltc10pID0+IHtcbiAgICAgICAgY29uc3QgY3VycmVudEVwb2NoID0gTWF0aC5jZWlsKChuZXcgRGF0ZSgpKS5nZXRUaW1lKCkgLyBNU19JTl9TRUNPTkRTKTtcblxuICAgICAgICBpZiAoY2xhaW1zLmV4cCA+IGN1cnJlbnRFcG9jaCkge1xuICAgICAgICAgIGNvbnN0IGV4cGlyZXNJbiA9IGNsYWltcy5leHAgLSBjdXJyZW50RXBvY2g7XG4gICAgICAgICAgY29uc3QgZXhwaXJhdGlvbkJ1ZmZlciA9IHRoaXMudGltZVRvV2FpdEJlZm9yZUV4cGlyYXRpb24gfHwgREVGQVVMVF9TRUNPTkRTX0JFRk9SRV9FWFBJUkFUSU9OX1RPX05PVElGWTtcbiAgICAgICAgICBsZXQgZXhwaXJhdGlvbk5lYXJJbiA9IDA7XG5cbiAgICAgICAgICBpZiAoZXhwaXJlc0luIDwgZXhwaXJhdGlvbkJ1ZmZlcikge1xuICAgICAgICAgICAgZXhwaXJhdGlvbk5lYXJJbiA9IDE7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGV4cGlyYXRpb25OZWFySW4gPSBleHBpcmVzSW4gLSBleHBpcmF0aW9uQnVmZmVyO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHJldHVybiBtZXJnZShcbiAgICAgICAgICAgIHRoaXMuYnVpbGREZWxheWVkRXhwaXJhdGlvbk9ic2VydmFibGUoZXhwaXJhdGlvbk5lYXJJbiAqIE1TX0lOX1NFQ09ORFMsIGFjdGlvbiwgZmFsc2UpLFxuICAgICAgICAgICAgdGhpcy5idWlsZERlbGF5ZWRFeHBpcmF0aW9uT2JzZXJ2YWJsZShleHBpcmVzSW4gKiBNU19JTl9TRUNPTkRTLCBhY3Rpb24sIHRydWUpLFxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG9mKG5ldyBKd3RUb2tlblByb3ZpZGVyQWN0aW9ucy5Ub2tlbkV4cGlyZWQ8TWluaW1hbENsYWltTWFwPih7XG4gICAgICAgICAgdG9rZW5OYW1lOiBhY3Rpb24udG9rZW5OYW1lLFxuICAgICAgICAgIHRva2VuOiBhY3Rpb24udG9rZW4sXG4gICAgICAgIH0pKTtcblxuICAgICAgfSksXG4gICAgKVxuICA7XG5cblxuICBARWZmZWN0KClcbiAgcHVibGljIGluaXRpYWxDb29raWVMb2FkZXIkID0gKHtcbiAgICBjdXJyZW50U3RhdGUgPSB0aGlzLnN0b3JlLnNlbGVjdChnZXRKd3RUb2tlblJvb3QoKSksXG4gIH0gPSB7fSkgPT4gb2YodHJ1ZSkucGlwZShcbiAgICB0YWtlKDEpLFxuICAgIHdpdGhMYXRlc3RGcm9tKGN1cnJlbnRTdGF0ZSksXG4gICAgZmlsdGVyKChbXywgc3RhdGVdKSA9PiAhIShzdGF0ZSAmJiBzdGF0ZS5qd3RUb2tlbnMuaW5pdGlhbFRva2VuU3RhdHVzID09PSAndW5pbml0aWFsaXplZCcpKSxcbiAgICBtZXJnZU1hcCgoW2EsIF9dKSA9PiB7XG4gICAgICBjb25zdCBjb29raWUgPSB0aGlzLmNvb2tpZVNlcnZpY2UuZ2V0KCdqd3RfY29va2llJyk7XG4gICAgICBpZiAoY29va2llLmxlbmd0aCA+IDApIHtcbiAgICAgICAgcmV0dXJuIFtcbiAgICAgICAgICBuZXcgSnd0VG9rZW5Qcm92aWRlckFjdGlvbnMuSW5pdGlhbFRva2VuRXh0cmFjdGVkKGNvb2tpZSksXG4gICAgICAgICAgbmV3IEp3dFRva2VuUHJvdmlkZXJBY3Rpb25zLlN0b3JlVG9rZW4oe1xuICAgICAgICAgICAgdG9rZW5OYW1lOiB0aGlzLmluaXRpYWxUb2tlbk5hbWUsXG4gICAgICAgICAgICB0b2tlbjogY29va2llLFxuICAgICAgICAgICAgaXNEZWZhdWx0VG9rZW46IHRydWUsXG4gICAgICAgICAgfSksXG4gICAgICAgIF07XG4gICAgICB9XG4gICAgICByZXR1cm4gW1xuICAgICAgICBuZXcgSnd0VG9rZW5Qcm92aWRlckFjdGlvbnMuSW5pdGlhbFRva2VuRXh0cmFjdGVkKGNvb2tpZSksXG4gICAgICBdO1xuXG4gICAgfSksXG4gICk7XG5cblxuICAvKlxuICAgKiBUaGlzIG5leHQgZnVuY3Rpb24gaXMgYmVpbmcgZXhjbHVkZWQgZnJvbSBjb3ZlcmFnZSBkdWUgdGhlIGNvbXBsZXhpdGllcyBvZiB0ZXN0aW5nIHRoZSBgZGVsYXlgIGZ1bmN0aW9uLlxuICAgKiBJbiBvcmRlciB0byB0ZXN0IGFzIG11Y2ggYXMgcG9zc2libGUsIGVhY2ggcGllY2UgaGFzIGJlZW4gc2VwYXJhdGVkIGludG8gc21hbGxlciB0ZXN0YWJsZSBmdW5jdGlvbnMuXG4gICAqL1xuICBwdWJsaWMgYnVpbGREZWxheWVkRXhwaXJhdGlvbk9ic2VydmFibGUoXG4gICAgZW1pdFRpbWU6IG51bWJlciB8IERhdGUsXG4gICAgYWN0aW9uOiBKd3RUb2tlblByb3ZpZGVyQWN0aW9ucy5TdG9yZVRva2VuPE1pbmltYWxDbGFpbU1hcD4sXG4gICAgZXhwaXJlZDogYm9vbGVhbixcbiAgKSB7XG4gICAgY29uc3Qgb3V0cHV0QWN0aW9uQXJncyA9IHtcbiAgICAgIHRva2VuTmFtZTogYWN0aW9uLnRva2VuTmFtZSxcbiAgICAgIHRva2VuOiBhY3Rpb24udG9rZW4sXG4gICAgfTtcblxuICAgIHJldHVybiB0aW1lcihlbWl0VGltZSwgdGhpcy5zY2hlZHVsZXIgfHwgYXN5bmMpLnBpcGUoXG4gICAgICB0YWtlKDEpLFxuICAgICAgbWFwKCgpID0+IChleHBpcmVkXG4gICAgICAgID8gbmV3IEp3dFRva2VuUHJvdmlkZXJBY3Rpb25zLlRva2VuRXhwaXJlZDxNaW5pbWFsQ2xhaW1NYXA+KG91dHB1dEFjdGlvbkFyZ3MpXG4gICAgICAgIDogbmV3IEp3dFRva2VuUHJvdmlkZXJBY3Rpb25zLlRva2VuTmVhcmluZ0V4cGlyYXRpb248TWluaW1hbENsYWltTWFwPihvdXRwdXRBY3Rpb25BcmdzKSkpLFxuICAgICk7XG4gIH1cbn1cbiJdfQ==