UNPKG

ng2-idle-timeout

Version:

Zoneless-friendly session timeout management for Angular 16-20.

160 lines 23.1 kB
import { DestroyRef, Injectable, NgZone, inject } from '@angular/core'; import { DOCUMENT } from '@angular/common'; import { Subject } from 'rxjs'; import { DEFAULT_SESSION_TIMEOUT_CONFIG } from '../defaults'; import * as i0 from "@angular/core"; const PASSIVE_EVENT_OPTIONS = { passive: true }; const DOM_EVENT_SPECS = { mousemove: { target: 'document', debounce: 'mouse', options: PASSIVE_EVENT_OPTIONS }, mousedown: { target: 'document', debounce: 'mouse', options: PASSIVE_EVENT_OPTIONS }, click: { target: 'document', debounce: 'mouse', options: PASSIVE_EVENT_OPTIONS }, wheel: { target: 'document', debounce: 'mouse', options: PASSIVE_EVENT_OPTIONS }, scroll: { target: 'document', debounce: 'mouse', options: PASSIVE_EVENT_OPTIONS }, keydown: { target: 'document', debounce: 'key' }, keyup: { target: 'document', debounce: 'key' }, touchstart: { target: 'document', debounce: 'mouse', options: PASSIVE_EVENT_OPTIONS }, touchend: { target: 'document', debounce: 'mouse', options: PASSIVE_EVENT_OPTIONS }, touchmove: { target: 'document', debounce: 'mouse', options: PASSIVE_EVENT_OPTIONS }, visibilitychange: { target: 'document', debounce: 'none' } }; export class ActivityDomService { destroyRef = inject(DestroyRef); zone = inject(NgZone); document = inject(DOCUMENT, { optional: true }); eventsSubject = new Subject(); events$ = this.eventsSubject.asObservable(); config = DEFAULT_SESSION_TIMEOUT_CONFIG; listenerCleanupByEvent = new Map(); destroyHookRegistered = false; lastMouseEventAt = 0; lastKeyEventAt = 0; updateConfig(config) { this.config = config; this.syncEventListeners(); } syncEventListeners() { const doc = this.document; if (!doc || typeof window === 'undefined') { this.cleanupListeners(); return; } const win = doc.defaultView; if (!win) { this.cleanupListeners(); return; } const desired = new Set(configuredEvents(this.config.domActivityEvents)); for (const [eventName, cleanup] of this.listenerCleanupByEvent) { if (!desired.has(eventName)) { cleanup(); this.listenerCleanupByEvent.delete(eventName); } } const toAdd = []; for (const eventName of desired) { if (!this.listenerCleanupByEvent.has(eventName)) { toAdd.push(eventName); } } if (toAdd.length === 0) { this.ensureDestroyHook(); return; } this.zone.runOutsideAngular(() => { for (const eventName of toAdd) { const spec = DOM_EVENT_SPECS[eventName]; if (!spec) { continue; } const target = spec.target === 'window' ? win : doc; const handler = (event) => this.handleEvent(event, spec.debounce); target.addEventListener(eventName, handler, spec.options); this.listenerCleanupByEvent.set(eventName, () => { target.removeEventListener(eventName, handler, spec.options); }); } }); this.ensureDestroyHook(); } ensureDestroyHook() { if (this.destroyHookRegistered) { return; } this.destroyRef.onDestroy(() => { this.cleanupListeners(); }); this.destroyHookRegistered = true; } handleEvent(event, debounce) { if (!this.document) { return; } if (event.type === 'visibilitychange' && this.document.visibilityState !== 'visible') { return; } const now = Date.now(); if (debounce === 'mouse') { if (now - this.lastMouseEventAt < this.config.debounceMouseMs) { return; } this.lastMouseEventAt = now; } else if (debounce === 'key') { if (now - this.lastKeyEventAt < this.config.debounceKeyMs) { return; } this.lastKeyEventAt = now; } if (this.document.visibilityState === 'hidden' && event.type !== 'visibilitychange') { return; } const meta = { type: event.type }; if (typeof KeyboardEvent !== 'undefined' && event instanceof KeyboardEvent) { meta['key'] = event.key; meta['ctrlKey'] = event.ctrlKey; meta['shiftKey'] = event.shiftKey; meta['altKey'] = event.altKey; } else if (typeof MouseEvent !== 'undefined' && event instanceof MouseEvent) { meta['button'] = event.button; meta['clientX'] = Math.round(event.clientX); meta['clientY'] = Math.round(event.clientY); } else if (typeof TouchEvent !== 'undefined' && event instanceof TouchEvent) { meta['touches'] = event.touches?.length ?? 0; } else if (typeof InputEvent !== 'undefined' && event instanceof InputEvent) { meta['inputType'] = event.inputType; } const target = event.target; if (target instanceof Element) { meta['target'] = target.tagName.toLowerCase(); } this.eventsSubject.next({ source: 'dom', at: now, meta }); } cleanupListeners() { for (const [, cleanup] of this.listenerCleanupByEvent) { cleanup(); } this.listenerCleanupByEvent.clear(); } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.0", ngImport: i0, type: ActivityDomService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.0", ngImport: i0, type: ActivityDomService, providedIn: 'root' }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.0", ngImport: i0, type: ActivityDomService, decorators: [{ type: Injectable, args: [{ providedIn: 'root' }] }] }); function configuredEvents(events) { if (!events) { return DEFAULT_SESSION_TIMEOUT_CONFIG.domActivityEvents; } return events; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWN0aXZpdHktZG9tLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbGliL3NlcnZpY2VzL2FjdGl2aXR5LWRvbS5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDdkUsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQzNDLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFJL0IsT0FBTyxFQUFFLDhCQUE4QixFQUFFLE1BQU0sYUFBYSxDQUFDOztBQVU3RCxNQUFNLHFCQUFxQixHQUE0QixFQUFFLE9BQU8sRUFBRSxJQUFJLEVBQUUsQ0FBQztBQUV6RSxNQUFNLGVBQWUsR0FBK0M7SUFDbEUsU0FBUyxFQUFFLEVBQUUsTUFBTSxFQUFFLFVBQVUsRUFBRSxRQUFRLEVBQUUsT0FBTyxFQUFFLE9BQU8sRUFBRSxxQkFBcUIsRUFBRTtJQUNwRixTQUFTLEVBQUUsRUFBRSxNQUFNLEVBQUUsVUFBVSxFQUFFLFFBQVEsRUFBRSxPQUFPLEVBQUUsT0FBTyxFQUFFLHFCQUFxQixFQUFFO0lBQ3BGLEtBQUssRUFBRSxFQUFFLE1BQU0sRUFBRSxVQUFVLEVBQUUsUUFBUSxFQUFFLE9BQU8sRUFBRSxPQUFPLEVBQUUscUJBQXFCLEVBQUU7SUFDaEYsS0FBSyxFQUFFLEVBQUUsTUFBTSxFQUFFLFVBQVUsRUFBRSxRQUFRLEVBQUUsT0FBTyxFQUFFLE9BQU8sRUFBRSxxQkFBcUIsRUFBRTtJQUNoRixNQUFNLEVBQUUsRUFBRSxNQUFNLEVBQUUsVUFBVSxFQUFFLFFBQVEsRUFBRSxPQUFPLEVBQUUsT0FBTyxFQUFFLHFCQUFxQixFQUFFO0lBQ2pGLE9BQU8sRUFBRSxFQUFFLE1BQU0sRUFBRSxVQUFVLEVBQUUsUUFBUSxFQUFFLEtBQUssRUFB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QUFFLEtBQUs7WUFDYixFQUFFLEVBQUUsR0FBRztZQUNQLElBQUk7U0FDTCxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRU8sZ0JBQWdCO1FBQ3RCLEtBQUssTUFBTSxDQUFDLEVBQUUsT0FBTyxDQUFDLElBQUksSUFBSSxDQUFDLHNCQUFzQixFQUFFLENBQUM7WUFDdEQsT0FBTyxFQUFFLENBQUM7UUFDWixDQUFDO1FBQ0QsSUFBSSxDQUFDLHNCQUFzQixDQUFDLEtBQUssRUFBRSxDQUFDO0lBQ3RDLENBQUM7dUdBaEpVLGtCQUFrQjsyR0FBbEIsa0JBQWtCLGNBREwsTUFBTTs7MkZBQ25CLGtCQUFrQjtrQkFEOUIsVUFBVTttQkFBQyxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUU7O0FBb0psQyxTQUFTLGdCQUFnQixDQUFDLE1BQW1EO0lBQzNFLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUNaLE9BQU8sOEJBQThCLENBQUMsaUJBQWlCLENBQUM7SUFDMUQsQ0FBQztJQUNELE9BQU8sTUFBTSxDQUFDO0FBQ2hCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBEZXN0cm95UmVmLCBJbmplY3RhYmxlLCBOZ1pvbmUsIGluamVjdCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBET0NVTUVOVCB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XHJcbmltcG9ydCB7IFN1YmplY3QgfSBmcm9tICdyeGpzJztcclxuXHJcbmltcG9ydCB0eXBlIHsgQWN0aXZpdHlFdmVudCB9IGZyb20gJy4uL21vZGVscy9hY3Rpdml0eS1ldmVudCc7XHJcbmltcG9ydCB0eXBlIHsgU2Vzc2lvblRpbWVvdXRDb25maWcsIERvbUFjdGl2aXR5RXZlbnROYW1lIH0gZnJvbSAnLi4vbW9kZWxzL3Nlc3Npb24tdGltZW91dC1jb25maWcnO1xyXG5pbXBvcnQgeyBERUZBVUxUX1NFU1NJT05fVElNRU9VVF9DT05GSUcgfSBmcm9tICcuLi9kZWZhdWx0cyc7XHJcblxyXG50eXBlIEV2ZW50RGVib3VuY2UgPSAnbW91c2UnIHwgJ2tleScgfCAnbm9uZSc7XHJcblxyXG5pbnRlcmZhY2UgRG9tRXZlbnRTcGVjIHtcclxuICB0YXJnZXQ6ICdkb2N1bWVudCcgfCAnd2luZG93JztcclxuICBkZWJvdW5jZTogRXZlbnREZWJvdW5jZTtcclxuICBvcHRpb25zPzogQWRkRXZlbnRMaXN0ZW5lck9wdGlvbnM7XHJcbn1cclxuXHJcbmNvbnN0IFBBU1NJVkVfRVZFTlRfT1BUSU9OUzogQWRkRXZlbnRMaXN0ZW5lck9wdGlvbnMgPSB7IHBhc3NpdmU6IHRydWUgfTtcclxuXHJcbmNvbnN0IERPTV9FVkVOVF9TUEVDUzogUmVjb3JkPERvbUFjdGl2aXR5RXZlbnROYW1lLCBEb21FdmVudFNwZWM+ID0ge1xyXG4gIG1vdXNlbW92ZTogeyB0YXJnZXQ6ICdkb2N1bWVudCcsIGRlYm91bmNlOiAnbW91c2UnLCBvcHRpb25zOiBQQVNTSVZFX0VWRU5UX09QVElPTlMgfSxcclxuICBtb3VzZWRvd246IHsgdGFyZ2V0OiAnZG9jdW1lbnQnLCBkZWJvdW5jZTogJ21vdXNlJywgb3B0aW9uczogUEFTU0lWRV9FVkVOVF9PUFRJT05TIH0sXHJcbiAgY2xpY2s6IHsgdGFyZ2V0OiAnZG9jdW1lbnQnLCBkZWJvdW5jZTogJ21vdXNlJywgb3B0aW9uczogUEFTU0lWRV9FVkVOVF9PUFRJT05TIH0sXHJcbiAgd2hlZWw6IHsgdGFyZ2V0OiAnZG9jdW1lbnQnLCBkZWJvdW5jZTogJ21vdXNlJywgb3B0aW9uczogUEFTU0lWRV9FVkVOVF9PUFRJT05TIH0sXHJcbiAgc2Nyb2xsOiB7IHRhcmdldDogJ2RvY3VtZW50JywgZGVib3VuY2U6ICdtb3VzZScsIG9wdGlvbnM6IFBBU1NJVkVfRVZFTlRfT1BUSU9OUyB9LFxyXG4gIGtleWRvd246IHsgdGFyZ2V0OiAnZG9jdW1lbnQnLCBkZWJvdW5jZTogJ2tleScgfSxcclxuICBrZXl1cDogeyB0YXJnZXQ6ICdkb2N1bWVudCcsIGRlYm91bmNlOiAna2V5JyB9LFxyXG4gIHRvdWNoc3RhcnQ6IHsgdGFyZ2V0OiAnZG9jdW1lbnQnLCBkZWJvdW5jZTogJ21vdXNlJywgb3B0aW9uczogUEFTU0lWRV9FVkVOVF9PUFRJT05TIH0sXHJcbiAgdG91Y2hlbmQ6IHsgdGFyZ2V0OiAnZG9jdW1lbnQnLCBkZWJvdW5jZTogJ21vdXNlJywgb3B0aW9uczogUEFTU0lWRV9FVkVOVF9PUFRJT05TIH0sXHJcbiAgdG91Y2htb3ZlOiB7IHRhcmdldDogJ2RvY3VtZW50JywgZGVib3VuY2U6ICdtb3VzZScsIG9wdGlvbnM6IFBBU1NJVkVfRVZFTlRfT1BUSU9OUyB9LFxyXG4gIHZpc2liaWxpdHljaGFuZ2U6IHsgdGFyZ2V0OiAnZG9jdW1lbnQnLCBkZWJvdW5jZTogJ25vbmUnIH1cclxufSBhcyBjb25zdDtcclxuXHJcbkBJbmplY3RhYmxlKHsgcHJvdmlkZWRJbjogJ3Jvb3QnIH0pXHJcbmV4cG9ydCBjbGFzcyBBY3Rpdml0eURvbVNlcnZpY2Uge1xyXG4gIHByaXZhdGUgcmVhZG9ubHkgZGVzdHJveVJlZiA9IGluamVjdChEZXN0cm95UmVmKTtcclxuICBwcml2YXRlIHJlYWRvbmx5IHpvbmUgPSBpbmplY3QoTmdab25lKTtcclxuICBwcml2YXRlIHJlYWRvbmx5IGRvY3VtZW50ID0gaW5qZWN0KERPQ1VNRU5ULCB7IG9wdGlvbmFsOiB0cnVlIH0pIGFzIERvY3VtZW50IHwgdW5kZWZpbmVkO1xyXG5cclxuICBwcml2YXRlIHJlYWRvbmx5IGV2ZW50c1N1YmplY3QgPSBuZXcgU3ViamVjdDxBY3Rpdml0eUV2ZW50PigpO1xyXG4gIHJlYWRvbmx5IGV2ZW50cyQgPSB0aGlzLmV2ZW50c1N1YmplY3QuYXNPYnNlcnZhYmxlKCk7XHJcblxyXG4gIHByaXZhdGUgY29uZmlnOiBTZXNzaW9uVGltZW91dENvbmZpZyA9IERFRkFVTFRfU0VTU0lPTl9USU1FT1VUX0NPTkZJRztcclxuICBwcml2YXRlIHJlYWRvbmx5IGxpc3RlbmVyQ2xlYW51cEJ5RXZlbnQgPSBuZXcgTWFwPERvbUFjdGl2aXR5RXZlbnROYW1lLCAoKSA9PiB2b2lkPigpO1xyXG4gIHByaXZhdGUgZGVzdHJveUhvb2tSZWdpc3RlcmVkID0gZmFsc2U7XHJcbiAgcHJpdmF0ZSBsYXN0TW91c2VFdmVudEF0ID0gMDtcclxuICBwcml2YXRlIGxhc3RLZXlFdmVudEF0ID0gMDtcclxuXHJcbiAgdXBkYXRlQ29uZmlnKGNvbmZpZzogU2Vzc2lvblRpbWVvdXRDb25maWcpOiB2b2lkIHtcclxuICAgIHRoaXMuY29uZmlnID0gY29uZmlnO1xyXG4gICAgdGhpcy5zeW5jRXZlbnRMaXN0ZW5lcnMoKTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgc3luY0V2ZW50TGlzdGVuZXJzKCk6IHZvaWQge1xyXG4gICAgY29uc3QgZG9jID0gdGhpcy5kb2N1bWVudDtcclxuICAgIGlmICghZG9jIHx8IHR5cGVvZiB3aW5kb3cgPT09ICd1bmRlZmluZWQnKSB7XHJcbiAgICAgIHRoaXMuY2xlYW51cExpc3RlbmVycygpO1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgY29uc3Qgd2luID0gZG9jLmRlZmF1bHRWaWV3O1xyXG4gICAgaWYgKCF3aW4pIHtcclxuICAgICAgdGhpcy5jbGVhbnVwTGlzdGVuZXJzKCk7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICBjb25zdCBkZXNpcmVkID0gbmV3IFNldChjb25maWd1cmVkRXZlbnRzKHRoaXMuY29uZmlnLmRvbUFjdGl2aXR5RXZlbnRzKSk7XHJcblxyXG4gICAgZm9yIChjb25zdCBbZXZlbnROYW1lLCBjbGVhbnVwXSBvZiB0aGlzLmxpc3RlbmVyQ2xlYW51cEJ5RXZlbnQpIHtcclxuICAgICAgaWYgKCFkZXNpcmVkLmhhcyhldmVudE5hbWUpKSB7XHJcbiAgICAgICAgY2xlYW51cCgpO1xyXG4gICAgICAgIHRoaXMubGlzdGVuZXJDbGVhbnVwQnlFdmVudC5kZWxldGUoZXZlbnROYW1lKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGNvbnN0IHRvQWRkOiBEb21BY3Rpdml0eUV2ZW50TmFtZVtdID0gW107XHJcbiAgICBmb3IgKGNvbnN0IGV2ZW50TmFtZSBvZiBkZXNpcmVkKSB7XHJcbiAgICAgIGlmICghdGhpcy5saXN0ZW5lckNsZWFudXBCeUV2ZW50LmhhcyhldmVudE5hbWUpKSB7XHJcbiAgICAgICAgdG9BZGQucHVzaChldmVudE5hbWUpO1xyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHRvQWRkLmxlbmd0aCA9PT0gMCkge1xyXG4gICAgICB0aGlzLmVuc3VyZURlc3Ryb3lIb29rKCk7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICB0aGlzLnpvbmUucnVuT3V0c2lkZUFuZ3VsYXIoKCkgPT4ge1xyXG4gICAgICBmb3IgKGNvbnN0IGV2ZW50TmFtZSBvZiB0b0FkZCkge1xyXG4gICAgICAgIGNvbnN0IHNwZWMgPSBET01fRVZFTlRfU1BFQ1NbZXZlbnROYW1lXTtcclxuICAgICAgICBpZiAoIXNwZWMpIHtcclxuICAgICAgICAgIGNvbnRpbnVlO1xyXG4gICAgICAgIH1cclxuICAgICAgICBjb25zdCB0YXJnZXQgPSBzcGVjLnRhcmdldCA9PT0gJ3dpbmRvdycgPyB3aW4gOiBkb2M7XHJcbiAgICAgICAgY29uc3QgaGFuZGxlciA9IChldmVudDogRXZlbnQpID0+IHRoaXMuaGFuZGxlRXZlbnQoZXZlbnQsIHNwZWMuZGVib3VuY2UpO1xyXG4gICAgICAgIHRhcmdldC5hZGRFdmVudExpc3RlbmVyKGV2ZW50TmFtZSwgaGFuZGxlciwgc3BlYy5vcHRpb25zKTtcclxuICAgICAgICB0aGlzLmxpc3RlbmVyQ2xlYW51cEJ5RXZlbnQuc2V0KGV2ZW50TmFtZSwgKCkgPT4ge1xyXG4gICAgICAgICAgdGFyZ2V0LnJlbW92ZUV2ZW50TGlzdGVuZXIoZXZlbnROYW1lLCBoYW5kbGVyLCBzcGVjLm9wdGlvbnMpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICB9XHJcbiAgICB9KTtcclxuXHJcbiAgICB0aGlzLmVuc3VyZURlc3Ryb3lIb29rKCk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGVuc3VyZURlc3Ryb3lIb29rKCk6IHZvaWQge1xyXG4gICAgaWYgKHRoaXMuZGVzdHJveUhvb2tSZWdpc3RlcmVkKSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuICAgIHRoaXMuZGVzdHJveVJlZi5vbkRlc3Ryb3koKCkgPT4ge1xyXG4gICAgICB0aGlzLmNsZWFudXBMaXN0ZW5lcnMoKTtcclxuICAgIH0pO1xyXG4gICAgdGhpcy5kZXN0cm95SG9va1JlZ2lzdGVyZWQgPSB0cnVlO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBoYW5kbGVFdmVudChldmVudDogRXZlbnQsIGRlYm91bmNlOiBFdmVudERlYm91bmNlKTogdm9pZCB7XHJcbiAgICBpZiAoIXRoaXMuZG9jdW1lbnQpIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChldmVudC50eXBlID09PSAndmlzaWJpbGl0eWNoYW5nZScgJiYgdGhpcy5kb2N1bWVudC52aXNpYmlsaXR5U3RhdGUgIT09ICd2aXNpYmxlJykge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgY29uc3Qgbm93ID0gRGF0ZS5ub3coKTtcclxuXHJcbiAgICBpZiAoZGVib3VuY2UgPT09ICdtb3VzZScpIHtcclxuICAgICAgaWYgKG5vdyAtIHRoaXMubGFzdE1vdXNlRXZlbnRBdCA8IHRoaXMuY29uZmlnLmRlYm91bmNlTW91c2VNcykge1xyXG4gICAgICAgIHJldHVybjtcclxuICAgICAgfVxyXG4gICAgICB0aGlzLmxhc3RNb3VzZUV2ZW50QXQgPSBub3c7XHJcbiAgICB9IGVsc2UgaWYgKGRlYm91bmNlID09PSAna2V5Jykge1xyXG4gICAgICBpZiAobm93IC0gdGhpcy5sYXN0S2V5RXZlbnRBdCA8IHRoaXMuY29uZmlnLmRlYm91bmNlS2V5TXMpIHtcclxuICAgICAgICByZXR1cm47XHJcbiAgICAgIH1cclxuICAgICAgdGhpcy5sYXN0S2V5RXZlbnRBdCA9IG5vdztcclxuICAgIH1cclxuXHJcbiAgICBpZiAodGhpcy5kb2N1bWVudC52aXNpYmlsaXR5U3RhdGUgPT09ICdoaWRkZW4nICYmIGV2ZW50LnR5cGUgIT09ICd2aXNpYmlsaXR5Y2hhbmdlJykge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgY29uc3QgbWV0YTogUmVjb3JkPHN0cmluZywgdW5rbm93bj4gPSB7XHJcbiAgICAgIHR5cGU6IGV2ZW50LnR5cGVcclxuICAgIH07XHJcblxyXG4gICAgaWYgKHR5cGVvZiBLZXlib2FyZEV2ZW50ICE9PSAndW5kZWZpbmVkJyAmJiBldmVudCBpbnN0YW5jZW9mIEtleWJvYXJkRXZlbnQpIHtcclxuICAgICAgbWV0YVsna2V5J10gPSBldmVudC5rZXk7XHJcbiAgICAgIG1ldGFbJ2N0cmxLZXknXSA9IGV2ZW50LmN0cmxLZXk7XHJcbiAgICAgIG1ldGFbJ3NoaWZ0S2V5J10gPSBldmVudC5zaGlmdEtleTtcclxuICAgICAgbWV0YVsnYWx0S2V5J10gPSBldmVudC5hbHRLZXk7XHJcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBNb3VzZUV2ZW50ICE9PSAndW5kZWZpbmVkJyAmJiBldmVudCBpbnN0YW5jZW9mIE1vdXNlRXZlbnQpIHtcclxuICAgICAgbWV0YVsnYnV0dG9uJ10gPSBldmVudC5idXR0b247XHJcbiAgICAgIG1ldGFbJ2NsaWVudFgnXSA9IE1hdGgucm91bmQoZXZlbnQuY2xpZW50WCk7XHJcbiAgICAgIG1ldGFbJ2NsaWVudFknXSA9IE1hdGgucm91bmQoZXZlbnQuY2xpZW50WSk7XHJcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBUb3VjaEV2ZW50ICE9PSAndW5kZWZpbmVkJyAmJiBldmVudCBpbnN0YW5jZW9mIFRvdWNoRXZlbnQpIHtcclxuICAgICAgbWV0YVsndG91Y2hlcyddID0gZXZlbnQudG91Y2hlcz8ubGVuZ3RoID8/IDA7XHJcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBJbnB1dEV2ZW50ICE9PSAndW5kZWZpbmVkJyAmJiBldmVudCBpbnN0YW5jZW9mIElucHV0RXZlbnQpIHtcclxuICAgICAgbWV0YVsnaW5wdXRUeXBlJ10gPSBldmVudC5pbnB1dFR5cGU7XHJcbiAgICB9XHJcblxyXG4gICAgY29uc3QgdGFyZ2V0ID0gZXZlbnQudGFyZ2V0IGFzIEVsZW1lbnQgfCBudWxsO1xyXG4gICAgaWYgKHRhcmdldCBpbnN0YW5jZW9mIEVsZW1lbnQpIHtcclxuICAgICAgbWV0YVsndGFyZ2V0J10gPSB0YXJnZXQudGFnTmFtZS50b0xvd2VyQ2FzZSgpO1xyXG4gICAgfVxyXG5cclxuICAgIHRoaXMuZXZlbnRzU3ViamVjdC5uZXh0KHtcclxuICAgICAgc291cmNlOiAnZG9tJyxcclxuICAgICAgYXQ6IG5vdyxcclxuICAgICAgbWV0YVxyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGNsZWFudXBMaXN0ZW5lcnMoKTogdm9pZCB7XHJcbiAgICBmb3IgKGNvbnN0IFssIGNsZWFudXBdIG9mIHRoaXMubGlzdGVuZXJDbGVhbnVwQnlFdmVudCkge1xyXG4gICAgICBjbGVhbnVwKCk7XHJcbiAgICB9XHJcbiAgICB0aGlzLmxpc3RlbmVyQ2xlYW51cEJ5RXZlbnQuY2xlYXIoKTtcclxuICB9XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGNvbmZpZ3VyZWRFdmVudHMoZXZlbnRzOiByZWFkb25seSBEb21BY3Rpdml0eUV2ZW50TmFtZVtdIHwgdW5kZWZpbmVkKTogcmVhZG9ubHkgRG9tQWN0aXZpdHlFdmVudE5hbWVbXSB7XHJcbiAgaWYgKCFldmVudHMpIHtcclxuICAgIHJldHVybiBERUZBVUxUX1NFU1NJT05fVElNRU9VVF9DT05GSUcuZG9tQWN0aXZpdHlFdmVudHM7XHJcbiAgfVxyXG4gIHJldHVybiBldmVudHM7XHJcbn1cclxuIl19