angular2-hotkeys
Version:
Angular 16 and Ivy Compatible. Older versions might work but isn't officially tested.
167 lines • 22.5 kB
JavaScript
import { Inject, Injectable } from '@angular/core';
import { Hotkey } from './hotkey.model';
import { Subject } from 'rxjs';
import { HotkeyOptions } from './hotkey.options';
import * as Mousetrap from 'mousetrap';
import * as i0 from "@angular/core";
export class HotkeysService {
constructor(options) {
this.options = options;
this.hotkeys = [];
this.pausedHotkeys = [];
this.cheatSheetToggle = new Subject();
this.preventIn = ['INPUT', 'SELECT', 'TEXTAREA'];
// noinspection JSUnusedGlobalSymbols,JSUnusedLocalSymbols
Mousetrap.prototype.stopCallback = (event, element, combo, callback) => {
// if the element has the class "mousetrap" then no need to stop
if ((' ' + element.className + ' ').indexOf(' mousetrap ') > -1) {
return false;
}
return (element.contentEditable && element.contentEditable === 'true');
};
this.mousetrap = new Mousetrap.default();
this.initCheatSheet();
}
initCheatSheet() {
if (!this.options.disableCheatSheet) {
this.add(new Hotkey(this.options.cheatSheetHotkey || '?', function (_) {
this.cheatSheetToggle.next();
}.bind(this), [], this.options.cheatSheetDescription || 'Show / hide this help menu'));
}
if (this.options.cheatSheetCloseEsc) {
this.add(new Hotkey('esc', function (_) {
this.cheatSheetToggle.next(false);
}.bind(this), ['HOTKEYS-CHEATSHEET'], this.options.cheatSheetCloseEscDescription || 'Hide this help menu'));
}
}
add(hotkey, specificEvent) {
if (Array.isArray(hotkey)) {
const temp = [];
for (const key of hotkey) {
temp.push(this.add(key, specificEvent));
}
return temp;
}
this.remove(hotkey);
this.hotkeys.push(hotkey);
this.mousetrap.bind(hotkey.combo, (event, combo) => {
let shouldExecute = true;
// if the callback is executed directly `hotkey.get('w').callback()`
// there will be no event, so just execute the callback.
if (event) {
const target = (event.target || event.srcElement); // srcElement is IE only
const nodeName = target.nodeName.toUpperCase();
// check if the input has a mousetrap class, and skip checking preventIn if so
if ((' ' + target.className + ' ').indexOf(' mousetrap ') > -1) {
shouldExecute = true;
}
else if (this.preventIn.indexOf(nodeName) > -1 &&
hotkey.allowIn.map(allow => allow.toUpperCase()).indexOf(nodeName) === -1) {
// don't execute callback if the event was fired from inside an element listed in preventIn but not in allowIn
shouldExecute = false;
}
}
if (shouldExecute) {
return hotkey.callback.apply(this, [event, combo]);
}
}, specificEvent);
return hotkey;
}
remove(hotkey, specificEvent) {
const temp = [];
if (!hotkey) {
for (const key of this.hotkeys) {
temp.push(this.remove(key, specificEvent));
}
return temp;
}
if (Array.isArray(hotkey)) {
for (const key of hotkey) {
temp.push(this.remove(key));
}
return temp;
}
const index = this.findHotkey(hotkey);
if (index > -1) {
this.hotkeys.splice(index, 1);
this.mousetrap.unbind(hotkey.combo, specificEvent);
return hotkey;
}
return null;
}
get(combo) {
if (!combo) {
return this.hotkeys;
}
if (Array.isArray(combo)) {
const temp = [];
for (const key of combo) {
temp.push(this.get(key));
}
return temp;
}
for (const hotkey of this.hotkeys) {
if (hotkey.combo.indexOf(combo) > -1) {
return hotkey;
}
}
return null;
}
// noinspection JSUnusedGlobalSymbols
pause(hotkey) {
if (!hotkey) {
return this.pause(this.hotkeys);
}
if (Array.isArray(hotkey)) {
const temp = [];
for (const key of hotkey.slice()) {
temp.push(this.pause(key));
}
return temp;
}
this.remove(hotkey);
this.pausedHotkeys.push(hotkey);
return hotkey;
}
// noinspection JSUnusedGlobalSymbols
unpause(hotkey) {
if (!hotkey) {
return this.unpause(this.pausedHotkeys);
}
if (Array.isArray(hotkey)) {
const temp = [];
for (const key of hotkey.slice()) {
temp.push(this.unpause(key));
}
return temp;
}
const index = this.pausedHotkeys.indexOf(hotkey);
if (index > -1) {
this.add(hotkey);
return this.pausedHotkeys.splice(index, 1);
}
return null;
}
// noinspection JSUnusedGlobalSymbols
reset() {
this.mousetrap.reset();
this.hotkeys = [];
this.pausedHotkeys = [];
this.initCheatSheet();
}
findHotkey(hotkey) {
return this.hotkeys.indexOf(hotkey);
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.2", ngImport: i0, type: HotkeysService, deps: [{ token: HotkeyOptions }], target: i0.ɵɵFactoryTarget.Injectable }); }
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.2", ngImport: i0, type: HotkeysService, providedIn: 'root' }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.2", ngImport: i0, type: HotkeysService, decorators: [{
type: Injectable,
args: [{
providedIn: 'root'
}]
}], ctorParameters: function () { return [{ type: undefined, decorators: [{
type: Inject,
args: [HotkeyOptions]
}] }]; } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaG90a2V5cy5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2xpYi9ob3RrZXlzLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLE1BQU0sRUFBRSxVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDbkQsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ3hDLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDL0IsT0FBTyxFQUFFLGFBQWEsRUFBa0IsTUFBTSxrQkFBa0IsQ0FBQztBQUVqRSxPQUFPLEtBQUssU0FBUyxNQUFNLFdBQVcsQ0FBQzs7QUFLdkMsTUFBTSxPQUFPLGNBQWM7SUFRdkIsWUFBMkMsT0FBdUI7UUFBdkIsWUFBTyxHQUFQLE9BQU8sQ0FBZ0I7UUFQbEUsWUFBTyxHQUFhLEVBQUUsQ0FBQztRQUN2QixrQkFBYSxHQUFhLEVBQUUsQ0FBQztRQUU3QixxQkFBZ0IsR0FBaUIsSUFBSSxPQUFPLEVBQUUsQ0FBQztRQUV2QyxjQUFTLEdBQUcsQ0FBQyxPQUFPLEVBQUUsUUFBUSxFQUFFLFVBQVUsQ0FBQyxDQUFDO1FBR2hELDBEQUEwRDtRQUMxRCxTQUFTLENBQUMsU0FBUyxDQUFDLFlBQVksR0FBRyxDQUFDLEtBQW9CLEVBQUUsT0FBb0IsRUFBRSxLQUFhLEVBQUUsUUFBa0IsRUFBRSxFQUFFO1lBQ2pILGdFQUFnRTtZQUNoRSxJQUFJLENBQUMsR0FBRyxHQUFHLE9BQU8sQ0FBQyxTQUFTLEdBQUcsR0FBRyxDQUFDLENBQUMsT0FBTyxDQUFDLGFBQWEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFO2dCQUM3RCxPQUFPLEtBQUssQ0FBQzthQUNoQjtZQUNELE9BQU8sQ0FBQyxPQUFPLENBQUMsZUFBZSxJQUFJLE9BQU8sQ0FBQyxlQUFlLEtBQUssTUFBTSxDQUFDLENBQUM7UUFDM0UsQ0FBQyxDQUFDO1FBQ0YsSUFBSSxD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QUFFLE1BQU07aUJBQ3JCOzswQkFTZ0IsTUFBTTsyQkFBQyxhQUFhIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0LCBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBIb3RrZXkgfSBmcm9tICcuL2hvdGtleS5tb2RlbCc7XG5pbXBvcnQgeyBTdWJqZWN0IH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBIb3RrZXlPcHRpb25zLCBJSG90a2V5T3B0aW9ucyB9IGZyb20gJy4vaG90a2V5Lm9wdGlvbnMnO1xuaW1wb3J0IHsgTW91c2V0cmFwSW5zdGFuY2UgfSBmcm9tICdtb3VzZXRyYXAnO1xuaW1wb3J0ICogYXMgTW91c2V0cmFwIGZyb20gJ21vdXNldHJhcCc7XG5cbkBJbmplY3RhYmxlKHtcbiAgICBwcm92aWRlZEluOiAncm9vdCdcbn0pXG5leHBvcnQgY2xhc3MgSG90a2V5c1NlcnZpY2Uge1xuICAgIGhvdGtleXM6IEhvdGtleVtdID0gW107XG4gICAgcGF1c2VkSG90a2V5czogSG90a2V5W10gPSBbXTtcbiAgICBtb3VzZXRyYXA6IE1vdXNldHJhcEluc3RhbmNlO1xuICAgIGNoZWF0U2hlZXRUb2dnbGU6IFN1YmplY3Q8YW55PiA9IG5ldyBTdWJqZWN0KCk7XG5cbiAgICBwcml2YXRlIHByZXZlbnRJbiA9IFsnSU5QVVQnLCAnU0VMRUNUJywgJ1RFWFRBUkVBJ107XG5cbiAgICBjb25zdHJ1Y3RvcihASW5qZWN0KEhvdGtleU9wdGlvbnMpIHByaXZhdGUgb3B0aW9uczogSUhvdGtleU9wdGlvbnMpIHtcbiAgICAgICAgLy8gbm9pbnNwZWN0aW9uIEpTVW51c2VkR2xvYmFsU3ltYm9scyxKU1VudXNlZExvY2FsU3ltYm9sc1xuICAgICAgICBNb3VzZXRyYXAucHJvdG90eXBlLnN0b3BDYWxsYmFjayA9IChldmVudDogS2V5Ym9hcmRFdmVudCwgZWxlbWVudDogSFRNTEVsZW1lbnQsIGNvbWJvOiBzdHJpbmcsIGNhbGxiYWNrOiBGdW5jdGlvbikgPT4ge1xuICAgICAgICAgICAgLy8gaWYgdGhlIGVsZW1lbnQgaGFzIHRoZSBjbGFzcyBcIm1vdXNldHJhcFwiIHRoZW4gbm8gbmVlZCB0byBzdG9wXG4gICAgICAgICAgICBpZiAoKCcgJyArIGVsZW1lbnQuY2xhc3NOYW1lICsgJyAnKS5pbmRleE9mKCcgbW91c2V0cmFwICcpID4gLTEpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gKGVsZW1lbnQuY29udGVudEVkaXRhYmxlICYmIGVsZW1lbnQuY29udGVudEVkaXRhYmxlID09PSAndHJ1ZScpO1xuICAgICAgICB9O1xuICAgICAgICB0aGlzLm1vdXNldHJhcCA9IG5ldyAoTW91c2V0cmFwIGFzIGFueSkuZGVmYXVsdCgpO1xuICAgICAgICB0aGlzLmluaXRDaGVhdFNoZWV0KCk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBpbml0Q2hlYXRTaGVldCgpIHtcbiAgICAgICAgaWYgKCF0aGlzLm9wdGlvbnMuZGlzYWJsZUNoZWF0U2hlZXQpIHtcbiAgICAgICAgICAgIHRoaXMuYWRkKG5ldyBIb3RrZXkoXG4gICAgICAgICAgICAgICAgdGhpcy5vcHRpb25zLmNoZWF0U2hlZXRIb3RrZXkgfHwgJz8nLFxuICAgICAgICAgICAgICAgIGZ1bmN0aW9uKF86IEtleWJvYXJkRXZlbnQpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jaGVhdFNoZWV0VG9nZ2xlLm5leHQoKTtcbiAgICAgICAgICAgICAgICB9LmJpbmQodGhpcyksXG4gICAgICAgICAgICAgICAgW10sXG4gICAgICAgICAgICAgICAgdGhpcy5vcHRpb25zLmNoZWF0U2hlZXREZXNjcmlwdGlvbiB8fCAnU2hvdyAvIGhpZGUgdGhpcyBoZWxwIG1lbnUnLFxuICAgICAgICAgICAgKSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5vcHRpb25zLmNoZWF0U2hlZXRDbG9zZUVzYykge1xuICAgICAgICAgICAgdGhpcy5hZGQobmV3IEhvdGtleShcbiAgICAgICAgICAgICAgICAnZXNjJyxcbiAgICAgICAgICAgICAgICBmdW5jdGlvbihfOiBLZXlib2FyZEV2ZW50KSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY2hlYXRTaGVldFRvZ2dsZS5uZXh0KGZhbHNlKTtcbiAgICAgICAgICAgICAgICB9LmJpbmQodGhpcyksXG4gICAgICAgICAgICAgICAgWydIT1RLRVlTLUNIRUFUU0hFRVQnXSxcbiAgICAgICAgICAgICAgICB0aGlzLm9wdGlvbnMuY2hlYXRTaGVldENsb3NlRXNjRGVzY3JpcHRpb24gfHwgJ0hpZGUgdGhpcyBoZWxwIG1lbnUnLFxuICAgICAgICAgICAgKSk7XG4gICAgICAgIH1cblxuICAgIH1cblxuICAgIGFkZChob3RrZXk6IEhvdGtleSB8IEhvdGtleVtdLCBzcGVjaWZpY0V2ZW50Pzogc3RyaW5nKTogSG90a2V5IHwgSG90a2V5W10ge1xuICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShob3RrZXkpKSB7XG4gICAgICAgICAgICBjb25zdCB0ZW1wOiBIb3RrZXlbXSA9IFtdO1xuICAgICAgICAgICAgZm9yIChjb25zdCBrZXkgb2YgaG90a2V5KSB7XG4gICAgICAgICAgICAgICAgdGVtcC5wdXNoKHRoaXMuYWRkKGtleSwgc3BlY2lmaWNFdmVudCkgYXMgSG90a2V5KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0ZW1wO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMucmVtb3ZlKGhvdGtleSk7XG4gICAgICAgIHRoaXMuaG90a2V5cy5wdXNoKGhvdGtleSBhcyBIb3RrZXkpO1xuICAgICAgICB0aGlzLm1vdXNldHJhcC5iaW5kKChob3RrZXkgYXMgSG90a2V5KS5jb21ibywgKGV2ZW50OiBLZXlib2FyZEV2ZW50LCBjb21ibzogc3RyaW5nKSA9PiB7XG4gICAgICAgICAgICBsZXQgc2hvdWxkRXhlY3V0ZSA9IHRydWU7XG5cbiAgICAgICAgICAgIC8vIGlmIHRoZSBjYWxsYmFjayBpcyBleGVjdXRlZCBkaXJlY3RseSBgaG90a2V5LmdldCgndycpLmNhbGxiYWNrKClgXG4gICAgICAgICAgICAvLyB0aGVyZSB3aWxsIGJlIG5vIGV2ZW50LCBzbyBqdXN0IGV4ZWN1dGUgdGhlIGNhbGxiYWNrLlxuICAgICAgICAgICAgaWYgKGV2ZW50KSB7XG4gICAgICAgICAgICAgICAgY29uc3QgdGFyZ2V0OiBIVE1MRWxlbWVudCA9IChldmVudC50YXJnZXQgfHwgZXZlbnQuc3JjRWxlbWVudCkgYXMgSFRNTEVsZW1lbnQ7IC8vIHNyY0VsZW1lbnQgaXMgSUUgb25seVxuICAgICAgICAgICAgICAgIGNvbnN0IG5vZGVOYW1lOiBzdHJpbmcgPSB0YXJnZXQubm9kZU5hbWUudG9VcHBlckNhc2UoKTtcblxuICAgICAgICAgICAgICAgIC8vIGNoZWNrIGlmIHRoZSBpbnB1dCBoYXMgYSBtb3VzZXRyYXAgY2xhc3MsIGFuZCBza2lwIGNoZWNraW5nIHByZXZlbnRJbiBpZiBzb1xuICAgICAgICAgICAgICAgIGlmICgoJyAnICsgdGFyZ2V0LmNsYXNzTmFtZSArICcgJykuaW5kZXhPZignIG1vdXNldHJhcCAnKSA+IC0xKSB7XG4gICAgICAgICAgICAgICAgICAgIHNob3VsZEV4ZWN1dGUgPSB0cnVlO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAodGhpcy5wcmV2ZW50SW4uaW5kZXhPZihub2RlTmFtZSkgPiAtMSAmJlxuICAgICAgICAgICAgICAgICAgICAoaG90a2V5IGFzIEhvdGtleSkuYWxsb3dJbi5tYXAoYWxsb3cgPT4gYWxsb3cudG9VcHBlckNhc2UoKSkuaW5kZXhPZihub2RlTmFtZSkgPT09IC0xKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIGRvbid0IGV4ZWN1dGUgY2FsbGJhY2sgaWYgdGhlIGV2ZW50IHdhcyBmaXJlZCBmcm9tIGluc2lkZSBhbiBlbGVtZW50IGxpc3RlZCBpbiBwcmV2ZW50SW4gYnV0IG5vdCBpbiBhbGxvd0luXG4gICAgICAgICAgICAgICAgICAgIHNob3VsZEV4ZWN1dGUgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChzaG91bGRFeGVjdXRlKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIChob3RrZXkgYXMgSG90a2V5KS5jYWxsYmFjay5hcHBseSh0aGlzLCBbZXZlbnQsIGNvbWJvXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sIHNwZWNpZmljRXZlbnQpO1xuICAgICAgICByZXR1cm4gaG90a2V5O1xuICAgIH1cblxuICAgIHJlbW92ZShob3RrZXk/OiBIb3RrZXkgfCBIb3RrZXlbXSwgc3BlY2lmaWNFdmVudD86IHN0cmluZyk6IEhvdGtleSB8IEhvdGtleVtdIHtcbiAgICAgICAgY29uc3QgdGVtcDogSG90a2V5W10gPSBbXTtcbiAgICAgICAgaWYgKCFob3RrZXkpIHtcbiAgICAgICAgICAgIGZvciAoY29uc3Qga2V5IG9mIHRoaXMuaG90a2V5cykge1xuICAgICAgICAgICAgICAgIHRlbXAucHVzaCh0aGlzLnJlbW92ZShrZXksIHNwZWNpZmljRXZlbnQpIGFzIEhvdGtleSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdGVtcDtcbiAgICAgICAgfVxuICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShob3RrZXkpKSB7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IGtleSBvZiBob3RrZXkpIHtcbiAgICAgICAgICAgICAgICB0ZW1wLnB1c2godGhpcy5yZW1vdmUoa2V5KSBhcyBIb3RrZXkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRlbXA7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgaW5kZXggPSB0aGlzLmZpbmRIb3RrZXkoaG90a2V5IGFzIEhvdGtleSk7XG4gICAgICAgIGlmIChpbmRleCA+IC0xKSB7XG4gICAgICAgICAgICB0aGlzLmhvdGtleXMuc3BsaWNlKGluZGV4LCAxKTtcbiAgICAgICAgICAgIHRoaXMubW91c2V0cmFwLnVuYmluZCgoaG90a2V5IGFzIEhvdGtleSkuY29tYm8sIHNwZWNpZmljRXZlbnQpO1xuICAgICAgICAgICAgcmV0dXJuIGhvdGtleTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICBnZXQoY29tYm8/OiBzdHJpbmcgfCBzdHJpbmdbXSk6IEhvdGtleSB8IEhvdGtleVtdIHtcbiAgICAgICAgaWYgKCFjb21ibykge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuaG90a2V5cztcbiAgICAgICAgfVxuICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShjb21ibykpIHtcbiAgICAgICAgICAgIGNvbnN0IHRlbXA6IEhvdGtleVtdID0gW107XG4gICAgICAgICAgICBmb3IgKGNvbnN0IGtleSBvZiBjb21ibykge1xuICAgICAgICAgICAgICAgIHRlbXAucHVzaCh0aGlzLmdldChrZXkpIGFzIEhvdGtleSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdGVtcDtcbiAgICAgICAgfVxuICAgICAgICBmb3IgKGNvbnN0IGhvdGtleSBvZiB0aGlzLmhvdGtleXMpIHtcbiAgICAgICAgICAgIGlmIChob3RrZXkuY29tYm8uaW5kZXhPZihjb21ibyBhcyBzdHJpbmcpID4gLTEpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gaG90a2V5O1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIC8vIG5vaW5zcGVjdGlvbiBKU1VudXNlZEdsb2JhbFN5bWJvbHNcbiAgICBwYXVzZShob3RrZXk/OiBIb3RrZXkgfCBIb3RrZXlbXSk6IEhvdGtleSB8IEhvdGtleVtdIHtcbiAgICAgICAgaWYgKCFob3RrZXkpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnBhdXNlKHRoaXMuaG90a2V5cyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkoaG90a2V5KSkge1xuICAgICAgICAgICAgY29uc3QgdGVtcDogSG90a2V5W10gPSBbXTtcbiAgICAgICAgICAgIGZvciAoY29uc3Qga2V5IG9mIGhvdGtleS5zbGljZSgpKSB7XG4gICAgICAgICAgICAgICAgdGVtcC5wdXNoKHRoaXMucGF1c2Uoa2V5KSBhcyBIb3RrZXkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRlbXA7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5yZW1vdmUoaG90a2V5KTtcbiAgICAgICAgdGhpcy5wYXVzZWRIb3RrZXlzLnB1c2goaG90a2V5IGFzIEhvdGtleSk7XG4gICAgICAgIHJldHVybiBob3RrZXk7XG4gICAgfVxuXG4gICAgLy8gbm9pbnNwZWN0aW9uIEpTVW51c2VkR2xvYmFsU3ltYm9sc1xuICAgIHVucGF1c2UoaG90a2V5PzogSG90a2V5IHwgSG90a2V5W10pOiBIb3RrZXkgfCBIb3RrZXlbXSB7XG4gICAgICAgIGlmICghaG90a2V5KSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy51bnBhdXNlKHRoaXMucGF1c2VkSG90a2V5cyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkoaG90a2V5KSkge1xuICAgICAgICAgICAgY29uc3QgdGVtcDogSG90a2V5W10gPSBbXTtcbiAgICAgICAgICAgIGZvciAoY29uc3Qga2V5IG9mIGhvdGtleS5zbGljZSgpKSB7XG4gICAgICAgICAgICAgICAgdGVtcC5wdXNoKHRoaXMudW5wYXVzZShrZXkpIGFzIEhvdGtleSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdGVtcDtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBpbmRleDogbnVtYmVyID0gdGhpcy5wYXVzZWRIb3RrZXlzLmluZGV4T2YoaG90a2V5IGFzIEhvdGtleSk7XG4gICAgICAgIGlmIChpbmRleCA+IC0xKSB7XG4gICAgICAgICAgICB0aGlzLmFkZChob3RrZXkpO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMucGF1c2VkSG90a2V5cy5zcGxpY2UoaW5kZXgsIDEpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIC8vIG5vaW5zcGVjdGlvbiBKU1VudXNlZEdsb2JhbFN5bWJvbHNcbiAgICByZXNldCgpIHtcbiAgICAgICAgdGhpcy5tb3VzZXRyYXAucmVzZXQoKTtcbiAgICAgICAgdGhpcy5ob3RrZXlzID0gW107XG4gICAgICAgIHRoaXMucGF1c2VkSG90a2V5cyA9IFtdO1xuICAgICAgICB0aGlzLmluaXRDaGVhdFNoZWV0KCk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBmaW5kSG90a2V5KGhvdGtleTogSG90a2V5KTogbnVtYmVyIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaG90a2V5cy5pbmRleE9mKGhvdGtleSk7XG4gICAgfVxufVxuXG4iXX0=