ngx-drag-to-select
Version:
A lightweight, fast, configurable and reactive drag-to-select component for Angular 8 and beyond
152 lines • 20.8 kB
JavaScript
import { isPlatformBrowser } from '@angular/common';
import { Inject, Injectable, PLATFORM_ID } from '@angular/core';
import { merge } from 'rxjs';
import { distinctUntilChanged, map } from 'rxjs/operators';
import { KeyboardEventsService } from './keyboard-events.service';
import { CONFIG } from './tokens';
import * as i0 from "@angular/core";
import * as i1 from "./keyboard-events.service";
const SUPPORTED_META_KEYS = {
alt: true,
shift: true,
meta: true,
ctrl: true,
};
const SUPPORTED_KEYS = /[a-z]/;
const META_KEY = 'meta';
const KEY_ALIASES = {
[META_KEY]: ['ctrl', 'meta'],
};
const SUPPORTED_SHORTCUTS = {
moveRangeStart: true,
disableSelection: true,
toggleSingleItem: true,
addToSelection: true,
removeFromSelection: true,
};
const ERROR_PREFIX = '[ShortcutService]';
export class ShortcutService {
constructor(platformId, config, keyboardEvents) {
this.platformId = platformId;
this.keyboardEvents = keyboardEvents;
this._shortcuts = {};
this._latestShortcut = new Map();
this._shortcuts = this._createShortcutsFromConfig(config.shortcuts);
if (isPlatformBrowser(this.platformId)) {
const keydown$ = this.keyboardEvents.keydown$.pipe(map((event) => ({ code: event.code, pressed: true })));
const keyup$ = this.keyboardEvents.keyup$.pipe(map((event) => ({ code: event.code, pressed: false })));
merge(keydown$, keyup$)
.pipe(distinctUntilChanged((prev, curr) => {
return prev.pressed === curr.pressed && prev.code === curr.code;
}))
.subscribe((keyState) => {
if (keyState.pressed) {
this._latestShortcut.set(keyState.code, true);
}
else {
this._latestShortcut.delete(keyState.code);
}
});
}
}
disableSelection(event) {
return this._isShortcutPressed('disableSelection', event);
}
moveRangeStart(event) {
return this._isShortcutPressed('moveRangeStart', event);
}
toggleSingleItem(event) {
return this._isShortcutPressed('toggleSingleItem', event);
}
addToSelection(event) {
return this._isShortcutPressed('addToSelection', event);
}
removeFromSelection(event) {
return this._isShortcutPressed('removeFromSelection', event);
}
extendedSelectionShortcut(event) {
return this.addToSelection(event) || this.removeFromSelection(event);
}
_createShortcutsFromConfig(shortcuts) {
const shortcutMap = {};
for (const [key, shortcutsForCommand] of Object.entries(shortcuts)) {
if (!this._isSupportedShortcut(key)) {
throw new Error(this._getErrorMessage(`Shortcut ${key} not supported`));
}
shortcutsForCommand
.replace(/ /g, '')
.split(',')
.forEach((shortcut) => {
if (!shortcutMap[key]) {
shortcutMap[key] = [];
}
const combo = shortcut.split('+');
const cleanCombos = this._substituteKey(shortcut, combo, META_KEY);
cleanCombos.forEach((cleanCombo) => {
const unsupportedKey = this._isSupportedCombo(cleanCombo);
if (unsupportedKey) {
throw new Error(this._getErrorMessage(`Key '${unsupportedKey}' in shortcut ${shortcut} not supported`));
}
shortcutMap[key].push(cleanCombo.map((comboKey) => {
return SUPPORTED_META_KEYS[comboKey] ? `${comboKey}Key` : `Key${comboKey.toUpperCase()}`;
}));
});
});
}
return shortcutMap;
}
_substituteKey(shortcut, combo, substituteKey) {
const hasSpecialKey = shortcut.includes(substituteKey);
const substitutedShortcut = [];
if (hasSpecialKey) {
const cleanShortcut = combo.filter((element) => element !== META_KEY);
KEY_ALIASES.meta.forEach((alias) => {
substitutedShortcut.push([...cleanShortcut, alias]);
});
}
else {
substitutedShortcut.push(combo);
}
return substitutedShortcut;
}
_getErrorMessage(message) {
return `${ERROR_PREFIX} ${message}`;
}
_isShortcutPressed(shortcutName, event) {
const shortcuts = this._shortcuts[shortcutName];
return shortcuts.some((shortcut) => {
return shortcut.every((key) => this._isKeyPressed(event, key));
});
}
_isKeyPressed(event, key) {
return key.startsWith('Key') ? this._latestShortcut.has(key) : event[key];
}
_isSupportedCombo(combo) {
let unsupportedKey = null;
combo.forEach((key) => {
if (!SUPPORTED_META_KEYS[key] && (!SUPPORTED_KEYS.test(key) || this._isSingleChar(key))) {
unsupportedKey = key;
return;
}
});
return unsupportedKey;
}
_isSingleChar(key) {
return key.length > 1;
}
_isSupportedShortcut(shortcut) {
return SUPPORTED_SHORTCUTS[shortcut];
}
}
ShortcutService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.0.3", ngImport: i0, type: ShortcutService, deps: [{ token: PLATFORM_ID }, { token: CONFIG }, { token: i1.KeyboardEventsService }], target: i0.ɵɵFactoryTarget.Injectable });
ShortcutService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.0.3", ngImport: i0, type: ShortcutService });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.0.3", ngImport: i0, type: ShortcutService, decorators: [{
type: Injectable
}], ctorParameters: function () { return [{ type: undefined, decorators: [{
type: Inject,
args: [PLATFORM_ID]
}] }, { type: undefined, decorators: [{
type: Inject,
args: [CONFIG]
}] }, { type: i1.KeyboardEventsService }]; } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2hvcnRjdXQuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL25neC1kcmFnLXRvLXNlbGVjdC9zcmMvbGliL3Nob3J0Y3V0LnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDcEQsT0FBTyxFQUFFLE1BQU0sRUFBRSxVQUFVLEVBQUUsV0FBVyxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ2hFLE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDN0IsT0FBTyxFQUFFLG9CQUFvQixFQUFFLEdBQUcsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQzNELE9BQU8sRUFBRSxxQkFBcUIsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBRWxFLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxVQUFVLENBQUM7OztBQUVsQyxNQUFNLG1CQUFtQixHQUFHO0lBQzFCLEdBQUcsRUFBRSxJQUFJO0lBQ1QsS0FBSyxFQUFFLElBQUk7SUFDWCxJQUFJLEVBQUUsSUFBSTtJQUNWLElBQUksRUFBRSxJQUFJO0NBQ1gsQ0FBQztBQUVGLE1BQU0sY0FBYyxHQUFHLE9BQU8sQ0FBQztBQUUvQixNQUFNLFFBQVEsR0FBRyxNQUFNLENBQUM7QUFFeEIsTUFBTSxXQUFXLEdBQUc7SUFDbEIsQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDLE1BQU0sRUFBRSxNQUFNLENBQUM7Q0FDN0IsQ0FBQztBQUVGLE1BQU0sbUJBQW1CLEdBQUc7SUFDMUIsY0FBYyxFQUFFLElBQUk7SUFDcEIsZ0JBQWdCLEVBQUUsSUFBSTtJQUN0QixnQkFBZ0IsRUFBRSxJQUFJO0lBQ3RCLGNBQWMsRUFBRSxJQUFJO0lBQ3BCLG1CQUFtQixFQUFFLElBQUk7Q0FDMUIsQ0FBQztBQUVGLE1BQU0sWUFBWSxHQUFHLG1CQUFtQixDQUFDO0FBUXpDLE1BQU0sT0FB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QUFLLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQztRQUNqRSxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFTyxhQUFhLENBQUMsS0FBWSxFQUFFLEdBQVc7UUFDN0MsT0FBTyxHQUFHLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQzVFLENBQUM7SUFFTyxpQkFBaUIsQ0FBQyxLQUFvQjtRQUM1QyxJQUFJLGNBQWMsR0FBRyxJQUFJLENBQUM7UUFFMUIsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDLEdBQUcsRUFBRSxFQUFFO1lBQ3BCLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxJQUFJLENBQUMsYUFBYSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUU7Z0JBQ3ZGLGNBQWMsR0FBRyxHQUFHLENBQUM7Z0JBQ3JCLE9BQU87YUFDUjtRQUNILENBQUMsQ0FBQyxDQUFDO1FBRUgsT0FBTyxjQUFjLENBQUM7SUFDeEIsQ0FBQztJQUVPLGFBQWEsQ0FBQyxHQUFXO1FBQy9CLE9BQU8sR0FBRyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUM7SUFDeEIsQ0FBQztJQUVPLG9CQUFvQixDQUFDLFFBQWdCO1FBQzNDLE9BQU8sbUJBQW1CLENBQUMsUUFBUSxDQUFDLENBQUM7SUFDdkMsQ0FBQzs7NEdBdkpVLGVBQWUsa0JBTWhCLFdBQVcsYUFDWCxNQUFNO2dIQVBMLGVBQWU7MkZBQWYsZUFBZTtrQkFEM0IsVUFBVTs7MEJBT04sTUFBTTsyQkFBQyxXQUFXOzswQkFDbEIsTUFBTTsyQkFBQyxNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgaXNQbGF0Zm9ybUJyb3dzZXIgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHsgSW5qZWN0LCBJbmplY3RhYmxlLCBQTEFURk9STV9JRCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgbWVyZ2UgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IGRpc3RpbmN0VW50aWxDaGFuZ2VkLCBtYXAgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBLZXlib2FyZEV2ZW50c1NlcnZpY2UgfSBmcm9tICcuL2tleWJvYXJkLWV2ZW50cy5zZXJ2aWNlJztcbmltcG9ydCB7IERyYWdUb1NlbGVjdENvbmZpZyB9IGZyb20gJy4vbW9kZWxzJztcbmltcG9ydCB7IENPTkZJRyB9IGZyb20gJy4vdG9rZW5zJztcblxuY29uc3QgU1VQUE9SVEVEX01FVEFfS0VZUyA9IHtcbiAgYWx0OiB0cnVlLFxuICBzaGlmdDogdHJ1ZSxcbiAgbWV0YTogdHJ1ZSxcbiAgY3RybDogdHJ1ZSxcbn07XG5cbmNvbnN0IFNVUFBPUlRFRF9LRVlTID0gL1thLXpdLztcblxuY29uc3QgTUVUQV9LRVkgPSAnbWV0YSc7XG5cbmNvbnN0IEtFWV9BTElBU0VTID0ge1xuICBbTUVUQV9LRVldOiBbJ2N0cmwnLCAnbWV0YSddLFxufTtcblxuY29uc3QgU1VQUE9SVEVEX1NIT1JUQ1VUUyA9IHtcbiAgbW92ZVJhbmdlU3RhcnQ6IHRydWUsXG4gIGRpc2FibGVTZWxlY3Rpb246IHRydWUsXG4gIHRvZ2dsZVNpbmdsZUl0ZW06IHRydWUsXG4gIGFkZFRvU2VsZWN0aW9uOiB0cnVlLFxuICByZW1vdmVGcm9tU2VsZWN0aW9uOiB0cnVlLFxufTtcblxuY29uc3QgRVJST1JfUFJFRklYID0gJ1tTaG9ydGN1dFNlcnZpY2VdJztcblxuaW50ZXJmYWNlIEtleVN0YXRlIHtcbiAgY29kZTogc3RyaW5nO1xuICBwcmVzc2VkOiBib29sZWFuO1xufVxuXG5ASW5qZWN0YWJsZSgpXG5leHBvcnQgY2xhc3MgU2hvcnRjdXRTZXJ2aWNlIHtcbiAgcHJpdmF0ZSBfc2hvcnRjdXRzOiB7IFtrZXk6IHN0cmluZ106IHN0cmluZ1tdW10gfSA9IHt9O1xuXG4gIHByaXZhdGUgX2xhdGVzdFNob3J0Y3V0OiBNYXA8c3RyaW5nLCBib29sZWFuPiA9IG5ldyBNYXAoKTtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBASW5qZWN0KFBMQVRGT1JNX0lEKSBwcml2YXRlIHBsYXRmb3JtSWQ6IFJlY29yZDxzdHJpbmcsIHVua25vd24+LFxuICAgIEBJbmplY3QoQ09ORklHKSBjb25maWc6IERyYWdUb1NlbGVjdENvbmZpZyxcbiAgICBwcml2YXRlIGtleWJvYXJkRXZlbnRzOiBLZXlib2FyZEV2ZW50c1NlcnZpY2VcbiAgKSB7XG4gICAgdGhpcy5fc2hvcnRjdXRzID0gdGhpcy5fY3JlYXRlU2hvcnRjdXRzRnJvbUNvbmZpZyhjb25maWcuc2hvcnRjdXRzKTtcblxuICAgIGlmIChpc1BsYXRmb3JtQnJvd3Nlcih0aGlzLnBsYXRmb3JtSWQpKSB7XG4gICAgICBjb25zdCBrZXlkb3duJCA9IHRoaXMua2V5Ym9hcmRFdmVudHMua2V5ZG93biQucGlwZShcbiAgICAgICAgbWFwPEtleWJvYXJkRXZlbnQsIEtleVN0YXRlPigoZXZlbnQpID0+ICh7IGNvZGU6IGV2ZW50LmNvZGUsIHByZXNzZWQ6IHRydWUgfSkpXG4gICAgICApO1xuXG4gICAgICBjb25zdCBrZXl1cCQgPSB0aGlzLmtleWJvYXJkRXZlbnRzLmtleXVwJC5waXBlKFxuICAgICAgICBtYXA8S2V5Ym9hcmRFdmVudCwgS2V5U3RhdGU+KChldmVudCkgPT4gKHsgY29kZTogZXZlbnQuY29kZSwgcHJlc3NlZDogZmFsc2UgfSkpXG4gICAgICApO1xuXG4gICAgICBtZXJnZTxLZXlTdGF0ZT4oa2V5ZG93biQsIGtleXVwJClcbiAgICAgICAgLnBpcGUoXG4gICAgICAgICAgZGlzdGluY3RVbnRpbENoYW5nZWQoKHByZXYsIGN1cnIpID0+IHtcbiAgICAgICAgICAgIHJldHVybiBwcmV2LnByZXNzZWQgPT09IGN1cnIucHJlc3NlZCAmJiBwcmV2LmNvZGUgPT09IGN1cnIuY29kZTtcbiAgICAgICAgICB9KVxuICAgICAgICApXG4gICAgICAgIC5zdWJzY3JpYmUoKGtleVN0YXRlKSA9PiB7XG4gICAgICAgICAgaWYgKGtleVN0YXRlLnByZXNzZWQpIHtcbiAgICAgICAgICAgIHRoaXMuX2xhdGVzdFNob3J0Y3V0LnNldChrZXlTdGF0ZS5jb2RlLCB0cnVlKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5fbGF0ZXN0U2hvcnRjdXQuZGVsZXRlKGtleVN0YXRlLmNvZGUpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgZGlzYWJsZVNlbGVjdGlvbihldmVudDogRXZlbnQpIHtcbiAgICByZXR1cm4gdGhpcy5faXNTaG9ydGN1dFByZXNzZWQoJ2Rpc2FibGVTZWxlY3Rpb24nLCBldmVudCk7XG4gIH1cblxuICBtb3ZlUmFuZ2VTdGFydChldmVudDogRXZlbnQpIHtcbiAgICByZXR1cm4gdGhpcy5faXNTaG9ydGN1dFByZXNzZWQoJ21vdmVSYW5nZVN0YXJ0JywgZXZlbnQpO1xuICB9XG5cbiAgdG9nZ2xlU2luZ2xlSXRlbShldmVudDogRXZlbnQpIHtcbiAgICByZXR1cm4gdGhpcy5faXNTaG9ydGN1dFByZXNzZWQoJ3RvZ2dsZVNpbmdsZUl0ZW0nLCBldmVudCk7XG4gIH1cblxuICBhZGRUb1NlbGVjdGlvbihldmVudDogRXZlbnQpIHtcbiAgICByZXR1cm4gdGhpcy5faXNTaG9ydGN1dFByZXNzZWQoJ2FkZFRvU2VsZWN0aW9uJywgZXZlbnQpO1xuICB9XG5cbiAgcmVtb3ZlRnJvbVNlbGVjdGlvbihldmVudDogRXZlbnQpIHtcbiAgICByZXR1cm4gdGhpcy5faXNTaG9ydGN1dFByZXNzZWQoJ3JlbW92ZUZyb21TZWxlY3Rpb24nLCBldmVudCk7XG4gIH1cblxuICBleHRlbmRlZFNlbGVjdGlvblNob3J0Y3V0KGV2ZW50OiBFdmVudCkge1xuICAgIHJldHVybiB0aGlzLmFkZFRvU2VsZWN0aW9uKGV2ZW50KSB8fCB0aGlzLnJlbW92ZUZyb21TZWxlY3Rpb24oZXZlbnQpO1xuICB9XG5cbiAgcHJpdmF0ZSBfY3JlYXRlU2hvcnRjdXRzRnJvbUNvbmZpZyhzaG9ydGN1dHM6IHsgW2tleTogc3RyaW5nXTogc3RyaW5nIH0pIHtcbiAgICBjb25zdCBzaG9ydGN1dE1hcCA9IHt9O1xuXG4gICAgZm9yIChjb25zdCBba2V5LCBzaG9ydGN1dHNGb3JDb21tYW5kXSBvZiBPYmplY3QuZW50cmllcyhzaG9ydGN1dHMpKSB7XG4gICAgICBpZiAoIXRoaXMuX2lzU3VwcG9ydGVkU2hvcnRjdXQoa2V5KSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IodGhpcy5fZ2V0RXJyb3JNZXNzYWdlKGBTaG9ydGN1dCAke2tleX0gbm90IHN1cHBvcnRlZGApKTtcbiAgICAgIH1cblxuICAgICAgc2hvcnRjdXRzRm9yQ29tbWFuZFxuICAgICAgICAucmVwbGFjZSgvIC9nLCAnJylcbiAgICAgICAgLnNwbGl0KCcsJylcbiAgICAgICAgLmZvckVhY2goKHNob3J0Y3V0KSA9PiB7XG4gICAgICAgICAgaWYgKCFzaG9ydGN1dE1hcFtrZXldKSB7XG4gICAgICAgICAgICBzaG9ydGN1dE1hcFtrZXldID0gW107XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgY29uc3QgY29tYm8gPSBzaG9ydGN1dC5zcGxpdCgnKycpO1xuICAgICAgICAgIGNvbnN0IGNsZWFuQ29tYm9zID0gdGhpcy5fc3Vic3RpdHV0ZUtleShzaG9ydGN1dCwgY29tYm8sIE1FVEFfS0VZKTtcblxuICAgICAgICAgIGNsZWFuQ29tYm9zLmZvckVhY2goKGNsZWFuQ29tYm8pID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHVuc3VwcG9ydGVkS2V5ID0gdGhpcy5faXNTdXBwb3J0ZWRDb21ibyhjbGVhbkNvbWJvKTtcblxuICAgICAgICAgICAgaWYgKHVuc3VwcG9ydGVkS2V5KSB7XG4gICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcih0aGlzLl9nZXRFcnJvck1lc3NhZ2UoYEtleSAnJHt1bnN1cHBvcnRlZEtleX0nIGluIHNob3J0Y3V0ICR7c2hvcnRjdXR9IG5vdCBzdXBwb3J0ZWRgKSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHNob3J0Y3V0TWFwW2tleV0ucHVzaChcbiAgICAgICAgICAgICAgY2xlYW5Db21iby5tYXAoKGNvbWJvS2V5KSA9PiB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFNVUFBPUlRFRF9NRVRBX0tFWVNbY29tYm9LZXldID8gYCR7Y29tYm9LZXl9S2V5YCA6IGBLZXkke2NvbWJvS2V5LnRvVXBwZXJDYXNlKCl9YDtcbiAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHJldHVybiBzaG9ydGN1dE1hcDtcbiAgfVxuXG4gIHByaXZhdGUgX3N1YnN0aXR1dGVLZXkoc2hvcnRjdXQ6IHN0cmluZywgY29tYm86IEFycmF5PHN0cmluZz4sIHN1YnN0aXR1dGVLZXk6IHN0cmluZykge1xuICAgIGNvbnN0IGhhc1NwZWNpYWxLZXkgPSBzaG9ydGN1dC5pbmNsdWRlcyhzdWJzdGl0dXRlS2V5KTtcbiAgICBjb25zdCBzdWJzdGl0dXRlZFNob3J0Y3V0OiBzdHJpbmdbXVtdID0gW107XG5cbiAgICBpZiAoaGFzU3BlY2lhbEtleSkge1xuICAgICAgY29uc3QgY2xlYW5TaG9ydGN1dCA9IGNvbWJvLmZpbHRlcigoZWxlbWVudCkgPT4gZWxlbWVudCAhPT0gTUVUQV9LRVkpO1xuXG4gICAgICBLRVlfQUxJQVNFUy5tZXRhLmZvckVhY2goKGFsaWFzKSA9PiB7XG4gICAgICAgIHN1YnN0aXR1dGVkU2hvcnRjdXQucHVzaChbLi4uY2xlYW5TaG9ydGN1dCwgYWxpYXNdKTtcbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICBzdWJzdGl0dXRlZFNob3J0Y3V0LnB1c2goY29tYm8pO1xuICAgIH1cblxuICAgIHJldHVybiBzdWJzdGl0dXRlZFNob3J0Y3V0O1xuICB9XG5cbiAgcHJpdmF0ZSBfZ2V0RXJyb3JNZXNzYWdlKG1lc3NhZ2U6IHN0cmluZykge1xuICAgIHJldHVybiBgJHtFUlJPUl9QUkVGSVh9ICR7bWVzc2FnZX1gO1xuICB9XG5cbiAgcHJpdmF0ZSBfaXNTaG9ydGN1dFByZXNzZWQoc2hvcnRjdXROYW1lOiBzdHJpbmcsIGV2ZW50OiBFdmVudCkge1xuICAgIGNvbnN0IHNob3J0Y3V0cyA9IHRoaXMuX3Nob3J0Y3V0c1tzaG9ydGN1dE5hbWVdO1xuXG4gICAgcmV0dXJuIHNob3J0Y3V0cy5zb21lKChzaG9ydGN1dCkgPT4ge1xuICAgICAgcmV0dXJuIHNob3J0Y3V0LmV2ZXJ5KChrZXkpID0+IHRoaXMuX2lzS2V5UHJlc3NlZChldmVudCwga2V5KSk7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIF9pc0tleVByZXNzZWQoZXZlbnQ6IEV2ZW50LCBrZXk6IHN0cmluZykge1xuICAgIHJldHVybiBrZXkuc3RhcnRzV2l0aCgnS2V5JykgPyB0aGlzLl9sYXRlc3RTaG9ydGN1dC5oYXMoa2V5KSA6IGV2ZW50W2tleV07XG4gIH1cblxuICBwcml2YXRlIF9pc1N1cHBvcnRlZENvbWJvKGNvbWJvOiBBcnJheTxzdHJpbmc+KSB7XG4gICAgbGV0IHVuc3VwcG9ydGVkS2V5ID0gbnVsbDtcblxuICAgIGNvbWJvLmZvckVhY2goKGtleSkgPT4ge1xuICAgICAgaWYgKCFTVVBQT1JURURfTUVUQV9LRVlTW2tleV0gJiYgKCFTVVBQT1JURURfS0VZUy50ZXN0KGtleSkgfHwgdGhpcy5faXNTaW5nbGVDaGFyKGtleSkpKSB7XG4gICAgICAgIHVuc3VwcG9ydGVkS2V5ID0ga2V5O1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICByZXR1cm4gdW5zdXBwb3J0ZWRLZXk7XG4gIH1cblxuICBwcml2YXRlIF9pc1NpbmdsZUNoYXIoa2V5OiBzdHJpbmcpIHtcbiAgICByZXR1cm4ga2V5Lmxlbmd0aCA+IDE7XG4gIH1cblxuICBwcml2YXRlIF9pc1N1cHBvcnRlZFNob3J0Y3V0KHNob3J0Y3V0OiBzdHJpbmcpIHtcbiAgICByZXR1cm4gU1VQUE9SVEVEX1NIT1JUQ1VUU1tzaG9ydGN1dF07XG4gIH1cbn1cbiJdfQ==