UNPKG

@c8y/ngx-components

Version:

Angular modules for Cumulocity IoT applications

242 lines 30.3 kB
import { InjectionToken, Optional, Inject, Injectable } from '@angular/core'; import { camelCase, isUndefined, isEqual } from 'lodash-es'; import { ApplicationOptions } from './ApplicationOptions'; import { hookGeneric } from './extension-hooks'; import { SystemOptionsService, TenantOptionsService } from '@c8y/client'; import { Subject } from 'rxjs'; import { distinctUntilChanged, map, startWith } from 'rxjs/operators'; import * as i0 from "@angular/core"; import * as i1 from "@c8y/client"; /** * @deprecated Consider using the `hookOptions` function instead. */ export const HOOK_OPTIONS = new InjectionToken('HOOK_OPTIONS'); /** * You can either provide a single `ApplicationOptions` as parameter: * ```typescript * hookOptions(...) * ``` * * Or an array to directly register multiple: * ```typescript * hookOptions([...]) * ``` * * Or you provide an Service that implements `ExtensionFactory<ApplicationOptions>` * ```typescript * export class MyApplicationOptionsFactory implements ExtensionFactory<ApplicationOptions> {...} * ... * hookOptions(MyApplicationOptionsFactory) * ``` * A typed alternative to `HOOK_OPTIONS`. * @param options The `ApplicationOptions`'s or `ExtensionFactory` to be provided. * @returns An `Provider` to be provided in your module. */ export function hookOptions(options, hookOptions) { return hookGeneric(options, HOOK_OPTIONS, hookOptions); } /** * A service that allows to set or get application options * which configure the default behavior of the UI. */ export class OptionsService extends ApplicationOptions { constructor(options, systemOptionsService, tenantOptionService) { super(); this.systemOptionsService = systemOptionsService; this.tenantOptionService = tenantOptionService; this._optionsUpdated$ = new Subject(); this.optionsUpdated$ = this._optionsUpdated$.asObservable(); this.setupOptions(options); } /** * Returns an application option used to configure the UI. * @param optionKey The application options key. * @param defaultValue A value to return if non is set. * @param attemptParse Indicates whether the value should be parsed with JSON.parse. */ get(optionKey, defaultValue, attemptParse) { let value = this[optionKey]; if (typeof value === 'undefined') { value = this[camelCase(optionKey)]; } if (attemptParse) { return this.parseOptionRawValue(value, defaultValue); } return typeof value !== 'undefined' ? value : defaultValue; } /** * Returns an observable of an application option used to configure the UI. * @param optionKey The application options key. * @param defaultValue A value to return if non is set. * @param attemptParse Indicates whether the value should be parsed with JSON.parse. */ get$(optionKey, defaultValue, attemptParse) { const fn = () => this.get(optionKey, defaultValue, attemptParse); return this.optionsUpdated$.pipe(map(fn), startWith(fn()), distinctUntilChanged()); } /** * Sets an application option. * @param key The key to set. * @param value The value to set. */ set(key, value) { const camelCasedKey = camelCase(key); const previousValue = this[camelCasedKey]; this[camelCasedKey] = value; if (!isEqual(previousValue, value)) { this._optionsUpdated$.next(); } } /** * Deletes an application option. * @param key The key to remove. */ delete(key) { const camelCasedKey = camelCase(key); const previousValue = this[camelCasedKey]; delete this[camelCasedKey]; const newValue = this[camelCasedKey]; if (!isEqual(previousValue, newValue)) { this._optionsUpdated$.next(); } } /** * Gets support URL from: * - application option `supportUrl`, * - or current tenant's option `configuration / system.support.url`, * - or current tenant's inherited option `configuration / system.support.url`, * - or system option `configuration / system.support.url`, * - otherwise defaults to `false`. * * @returns Returns support url or false. */ async getSupportUrl() { let url = this.supportUrl; if (isUndefined(url)) { url = await this.getCurrentTenantOption('configuration', 'system.support.url'); } if (isUndefined(url)) { url = await this.getInheritedTenantOption('configuration', 'system.support.url'); } if (isUndefined(url)) { url = (await this.getSystemOption('support', 'url')) || false; } this.supportUrl = url; return this.supportUrl; } /** * Returns if the tenant allows to show the activate-support user menu entry. * Note: Only if system-level support-user/enabled is false we can activate it at tenant level. */ async getActivateSupportUser() { const option = await this.getSystemOption('support-user', 'enabled', true); return !option; } /** * Gets a value from the system service and parses it. * * @param category The category for this option. * @param key The key for that option. * @param defaultValue The default if the option was not found. */ async getSystemOption(category, key, defaultValue) { return this.getOptionFromService(category, key, null, this.systemOptionsService, defaultValue); } /** * Gets a value from the tenant service and parses it. * * @param category The category for this option. * @param key The key for that option. * @param defaultValue The default if the option was not found. */ async getTenantOption(category, key, defaultValue) { return this.getOptionFromService(category, key, null, this.tenantOptionService, defaultValue); } /** * Gets an inherited from parent value from the tenant service if inheritance supported based on given parameters. * * @param category The category for this option. * @param key The key for that option. * @param defaultValue The default if the option was not found. */ async getInheritedTenantOption(category, key, defaultValue) { return this.getOptionFromService(category, key, { evaluate: 'inherited' }, this.tenantOptionService, defaultValue); } /** * Gets current tenant option value from the tenant service omitting the inheritance supported based on given parameters. * * @param category The category for this option. * @param key The key for that option. * @param defaultValue The default if the option was not found. */ async getCurrentTenantOption(category, key, defaultValue) { return this.getOptionFromService(category, key, { evaluate: 'current' }, this.tenantOptionService, defaultValue); } setupOptions(options) { if (options) { if (!Array.isArray(options)) { options = [options]; } let combinedOptions = {}; if (options.length === 1) { combinedOptions = options[0]; } else if (options.length > 1) { options.forEach(optionMap => { if (optionMap) { this.applyOptions(optionMap, combinedOptions); } }); } else { return; } if (this.applyOptions(combinedOptions, this)) { this._optionsUpdated$.next(); } } } applyOptions(options, applyTo) { let optionWasChanged = false; Object.entries(options).forEach(([key, value]) => { const camelCasedKey = camelCase(key); const previousValue = applyTo[camelCasedKey]; applyTo[camelCasedKey] = value; if (!isEqual(previousValue, value)) { optionWasChanged = true; } }); return optionWasChanged; } async getOptionFromService(category, key, filter, service, defaultValue) { try { const { data } = await service.detail({ category, key }, filter); return this.parseOptionRawValue(data.value, defaultValue); } catch (ex) { return defaultValue; } } parseOptionRawValue(rawValue, defaultValue) { let value; try { value = JSON.parse(rawValue); } catch (e) { value = isUndefined(rawValue) ? defaultValue : rawValue; } return value; } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: OptionsService, deps: [{ token: HOOK_OPTIONS, optional: true }, { token: i1.SystemOptionsService }, { token: i1.TenantOptionsService }], target: i0.ɵɵFactoryTarget.Injectable }); } static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: OptionsService, providedIn: 'root' }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: OptionsService, decorators: [{ type: Injectable, args: [{ providedIn: 'root' }] }], ctorParameters: () => [{ type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [HOOK_OPTIONS] }] }, { type: i1.SystemOptionsService }, { type: i1.TenantOptionsService }] }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3B0aW9ucy5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vY29yZS9jb21tb24vb3B0aW9ucy5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxjQUFjLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDN0UsT0FBTyxFQUFFLFNBQVMsRUFBRSxXQUFXLEVBQUUsT0FBTyxFQUFFLE1BQU0sV0FBVyxDQUFDO0FBQzVELE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQzFELE9BQU8sRUFHTCxXQUFXLEVBRVosTUFBTSxtQkFBbUIsQ0FBQztBQUMzQixPQUFPLEVBQUUsb0JBQW9CLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFFekUsT0FBTyxFQUFjLE9BQU8sRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUMzQyxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsR0FBRyxFQUFFLFNBQVMsRUFBRSxNQUFNLGdCQUFnQixDQUFDOzs7QUFFdEU7O0dBRUc7QUFDSCxNQUFNLENBQUMsTUFBTSxZQUFZLEdBQUcsSUFBSSxjQUFjLENBQzVDLGNBQWMsQ0FDZixDQUFDO0FBRUY7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBb0JHO0FBQ0gsTUFBTSxVQUFVLFdBQVcsQ0FDekIsT0FBNEMsRUFDNUMsV0FBeUM7SUFFekMsT0FBTyxXQUFXLENBQXFCLE9BQU8sRUFBRSxZQUFZLEVBQUUsV0FBVyxDQUFDLENBQUM7QUFDN0UsQ0FBQztBQUVEOzs7R0FHRztBQUVILE1BQU0sT0FBTyxjQUFlLFNBQVEsa0JBQWtCO0lBSXBELFlBQ29DLE9BQU8sRUFDakMsb0JBQTBDLEVBQzFDLG1CQUF5QztRQUVqRCxLQUFLLEVBQUUsQ0FBQztRQUhBLHlCQUFvQixHQUFwQixvQkFBb0IsQ0FBc0I7UUFDMUMsd0JBQW1CLEdBQW5CLG1CQUFtQixDQUFzQjtRQUozQyxxQkFBZ0IsR0FBRyxJQUFJLE9BQU8sRUFBUSxDQUFDO1FBTzdDLElBQUksQ0FBQyxlQUFlLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixDQUFDLFlBQVksRUFBRSxDQUFDO1FBQzVELElBQUksQ0FBQyxZQUFZLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDN0IsQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0gsR0FBRyxDQUNELFNBQVksRUFDWixZQUFnQyxFQUNoQyxZQUFzQjtRQUV0QixJQUFJLEtBQUssR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDNUIsSUFBSSxPQUFPLEtBQUssS0FBSyxXQUFXLEVBQUUsQ0FBQztZQUNqQyxLQUFLLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDO1FBQ3JDLENBQUM7UUFDRCxJQUFJLFlBQVksRUFBRSxDQUFDO1lBQ2pCLE9BQU8sSUFBSSxDQUFDLG1CQUFtQixDQUFDLEtBQUssRUFBRSxZQUFZLENBQUMsQ0FBQztRQUN2RCxDQUFDO1FBQ0QsT0FBTyxPQUFPLEtBQUssS0FBSyxXQUFXLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsWUFBWSxDQUFDO0lBQzdELENBQUM7SUFFRDs7Ozs7T0FLRztJQUNILElBQUksQ0FDRixTQUFZLEVBQ1osWUFBZ0MsRUFDaEMsWUFBc0I7UUFFdEIsTUFBTSxFQUFFLEdBQUcsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxTQUFTLEVBQUUsWUFBWSxFQUFFLFlBQVksQ0FBQyxDQUFDO1FBQ2pFLE9BQU8sSUFBSSxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxFQUFFLFNBQVMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxFQUFFLG9CQUFvQixFQUFFLENBQUMsQ0FBQztJQUNyRixDQUFDO0lBRUQ7Ozs7T0FJRztJQUNILEdBQUcsQ0FBaUMsR0FBTSxFQUFFLEtBQXdCO1FBQ2xFLE1BQU0sYUFBYSxHQUFHLFNBQVMsQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUNyQyxNQUFNLGFBQWEsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUM7UUFDMUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxHQUFHLEtBQUssQ0FBQztRQUM1QixJQUFJLENBQUMsT0FBTyxDQUFDLGFBQWEsRUFBRSxLQUFLLENBQUMsRUFBRSxDQUFDO1lBQ25DLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUMvQixDQUFDO0lBQ0gsQ0FBQztJQUVEOzs7T0FHRztJQUNILE1BQU0sQ0FBaUMsR0FBTTtRQUMzQyxNQUFNLGFBQWEsR0FBRyxTQUFTLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDckMsTUFBTSxhQUFhLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDO1FBQzFDLE9BQU8sSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDO1FBQzNCLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQztRQUVyQyxJQUFJLENBQUMsT0FBTyxDQUFDLGFBQWEsRUFBRSxRQUFRLENBQUMsRUFBRSxDQUFDO1lBQ3RDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUMvQixDQUFDO0lBQ0gsQ0FBQztJQUVEOzs7Ozs7Ozs7T0FTRztJQUNILEtBQUssQ0FBQyxhQUFhO1FBQ2pCLElBQUksR0FBRyxHQUFxQixJQUFJLENBQUMsVUFBVSxDQUFDO1FBRTVDLElBQUksV0FBVyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUM7WUFDckIsR0FBRyxHQUFHLE1BQU0sSUFBSSxDQUFDLHNCQUFzQixDQUFDLGVBQWUsRUFBRSxvQkFBb0IsQ0FBQyxDQUFDO1FBQ2pGLENBQUM7UUFDRCxJQUFJLFdBQVcsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDO1lBQ3JCLEdBQUcsR0FBRyxNQUFNLElBQUksQ0FBQyx3QkFBd0IsQ0FBQyxlQUFlLEVBQUUsb0JBQW9CLENBQUMsQ0FBQztRQUNuRixDQUFDO1FBQ0QsSUFBSSxXQUFXLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUNyQixHQUFHLEdBQUcsQ0FBQyxNQUFNLElBQUksQ0FBQyxlQUFlLENBQUMsU0FBUyxFQUFFLEtBQUssQ0FBQyxDQUFDLElBQUksS0FBSyxDQUFDO1FBQ2hFLENBQUM7UUFFRCxJQUFJLENBQUMsVUFBVSxHQUFHLEdBQUcsQ0FBQztRQUN0QixPQUFPLElBQUksQ0FBQyxVQUFVLENBQUM7SUFDekIsQ0FBQztJQUVEOzs7T0FHRztJQUNILEtBQUssQ0FBQyxzQkFBc0I7UUFDMUIsTUFBTSxNQUFNLEdBQUcsTUFBTSxJQUFJLENBQUMsZUFBZSxDQUFDLGNBQWMsRUFBRSxTQUFTLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFDM0UsT0FBTyxDQUFDLE1BQU0sQ0FBQztJQUNqQixDQUFDO0lBRUQ7Ozs7OztPQU1HO0lBQ0gsS0FBSyxDQUFDLGVBQWUsQ0FDbkIsUUFBZ0IsRUFDaEIsR0FBVyxFQUNYLFlBQWdCO1FBRWhCLE9BQU8sSUFBSSxDQUFDLG9CQUFvQixDQUM5QixRQUFRLEVBQ1IsR0FBRyxFQUNILElBQUksRUFDSixJQUFJLENBQUMsb0JBQW9CLEVBQ3pCLFlBQVksQ0FDYixDQUFDO0lBQ0osQ0FBQztJQUVEOzs7Ozs7T0FNRztJQUNILEtBQUssQ0FBQyxlQUFlLENBQ25CLFFBQWdCLEVBQ2hCLEdBQVcsRUFDWCxZQUFnQjtRQUVoQixPQUFPLElBQUksQ0FBQyxvQkFBb0IsQ0FDOUIsUUFBUSxFQUNSLEdBQUcsRUFDSCxJQUFJLEVBQ0osSUFBSSxDQUFDLG1CQUFtQixFQUN4QixZQUFZLENBQ2IsQ0FBQztJQUNKLENBQUM7SUFFRDs7Ozs7O09BTUc7SUFDSCxLQUFLLENBQUMsd0JBQXdCLENBQzVCLFFBQWdCLEVBQ2hCLEdBQVcsRUFDWCxZQUFnQjtRQUVoQixPQUFPLElBQUksQ0FBQyxvQkFBb0IsQ0FDOUIsUUFBUSxFQUNSLEdBQUcsRUFDSCxFQUFFLFFBQVEsRUFBRSxXQUFXLEVBQUUsRUFDekIsSUFBSSxDQUFDLG1CQUFtQixFQUN4QixZQUFZLENBQ2IsQ0FBQztJQUNKLENBQUM7SUFFRDs7Ozs7O09BTUc7SUFDSCxLQUFLLENBQUMsc0JBQXNCLENBQzFCLFFBQWdCLEVBQ2hCLEdBQVcsRUFDWCxZQUFnQjtRQUVoQixPQUFPLElBQUksQ0FBQyxvQkFBb0IsQ0FDOUIsUUFBUSxFQUNSLEdBQUcsRUFDSCxFQUFFLFFBQVEsRUFBRSxTQUFTLEVBQUUsRUFDdkIsSUFBSSxDQUFDLG1CQUFtQixFQUN4QixZQUFZLENBQ2IsQ0FBQztJQUNKLENBQUM7SUFFTyxZQUFZLENBQUMsT0FBcUI7UUFDeEMsSUFBSSxPQUFPLEVBQUUsQ0FBQztZQUNaLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7Z0JBQzVCLE9BQU8sR0FBRyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBQ3RCLENBQUM7WUFDRCxJQUFJLGVBQWUsR0FBRyxFQUFFLENBQUM7WUFDekIsSUFBSSxPQUFPLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRSxDQUFDO2dCQUN6QixlQUFlLEdBQUcsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQy9CLENBQUM7aUJBQU0sSUFBSSxPQUFPLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDO2dCQUM5QixPQUFPLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxFQUFFO29CQUMxQixJQUFJLFNBQVMsRUFBRSxDQUFDO3dCQUNkLElBQUksQ0FBQyxZQUFZLENBQUMsU0FBUyxFQUFFLGVBQWUsQ0FBQyxDQUFDO29CQUNoRCxDQUFDO2dCQUNILENBQUMsQ0FBQyxDQUFDO1lBQ0wsQ0FBQztpQkFBTSxDQUFDO2dCQUNOLE9BQU87WUFDVCxDQUFDO1lBQ0QsSUFBSSxJQUFJLENBQUMsWUFBWSxDQUFDLGVBQWUsRUFBRSxJQUFJLENBQUMsRUFBRSxDQUFDO2dCQUM3QyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxFQUFFLENBQUM7WUFDL0IsQ0FBQztRQUNILENBQUM7SUFDSCxDQUFDO0lBRU8sWUFBWSxDQUFDLE9BQTRCLEVBQUUsT0FBWTtRQUM3RCxJQUFJLGdCQUFnQixHQUFHLEtBQUssQ0FBQztRQUM3QixNQUFNLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQyxFQUFFLEVBQUU7WUFDL0MsTUFBTSxhQUFhLEdBQUcsU0FBUyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQ3JDLE1BQU0sYUFBYSxHQUFHLE9BQU8sQ0FBQyxhQUFhLENBQUMsQ0FBQztZQUM3QyxPQUFPLENBQUMsYUFBYSxDQUFDLEdBQUcsS0FBSyxDQUFDO1lBQy9CLElBQUksQ0FBQyxPQUFPLENBQUMsYUFBYSxFQUFFLEtBQUssQ0FBQyxFQUFFLENBQUM7Z0JBQ25DLGdCQUFnQixHQUFHLElBQUksQ0FBQztZQUMxQixDQUFDO1FBQ0gsQ0FBQyxDQUFDLENBQUM7UUFDSCxPQUFPLGdCQUFnQixDQUFDO0lBQzFCLENBQUM7SUFFTyxLQUFLLENBQUMsb0JBQW9CLENBQ2hDLFFBQWdCLEVBQ2hCLEdBQVcsRUFDWCxNQUFpQyxFQUNqQyxPQUFvRCxFQUNwRCxZQUFlO1FBRWYsSUFBSSxDQUFDO1lBQ0gsTUFBTSxFQUFFLElBQUksRUFBRSxHQUFHLE1BQU0sT0FBTyxDQUFDLE1BQU0sQ0FBQyxFQUFFLFFBQVEsRUFBRSxHQUFHLEVBQUUsRUFBRSxNQUFNLENBQUMsQ0FBQztZQUNqRSxPQUFPLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLFlBQVksQ0FBQyxDQUFDO1FBQzVELENBQUM7UUFBQyxPQUFPLEVBQUUsRUFBRSxDQUFDO1lBQ1osT0FBTyxZQUFZLENBQUM7UUFDdEIsQ0FBQztJQUNILENBQUM7SUFFTyxtQkFBbUIsQ0FBYSxRQUFnQixFQUFFLFlBQWU7UUFDdkUsSUFBSSxLQUFpQixDQUFDO1FBQ3RCLElBQUksQ0FBQztZQUNILEtBQUssR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQy9CLENBQUM7UUFBQyxPQUFPLENBQUMsRUFBRSxDQUFDO1lBQ1gsS0FBSyxHQUFHLFdBQVcsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUM7UUFDMUQsQ0FBQztRQUNELE9BQU8sS0FBSyxDQUFDO0lBQ2YsQ0FBQzsrR0FsUVUsY0FBYyxrQkFLSCxZQUFZO21IQUx2QixjQUFjLGNBREQsTUFBTTs7NEZBQ25CLGNBQWM7a0JBRDFCLFVBQVU7bUJBQUMsRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFOzswQkFNN0IsUUFBUTs7MEJBQUksTUFBTTsyQkFBQyxZQUFZIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0aW9uVG9rZW4sIE9wdGlvbmFsLCBJbmplY3QsIEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IGNhbWVsQ2FzZSwgaXNVbmRlZmluZWQsIGlzRXF1YWwgfSBmcm9tICdsb2Rhc2gtZXMnO1xuaW1wb3J0IHsgQXBwbGljYXRpb25PcHRpb25zIH0gZnJvbSAnLi9BcHBsaWNhdGlvbk9wdGlvbnMnO1xuaW1wb3J0IHtcbiAgRXh0ZW5zaW9uRmFjdG9yeSxcbiAgR2VuZXJpY0hvb2tUeXBlLFxuICBob29rR2VuZXJpYyxcbiAgR2VuZXJpY0hvb2tPcHRpb25zXG59IGZyb20gJy4vZXh0ZW5zaW9uLWhvb2tzJztcbmltcG9ydCB7IFN5c3RlbU9wdGlvbnNTZXJ2aWNlLCBUZW5hbnRPcHRpb25zU2VydmljZSB9IGZyb20gJ0BjOHkvY2xpZW50JztcbmltcG9ydCB7IElUZW5hbnRPcHRpb25EZXRhaWxQYXJhbXMgfSBmcm9tICdAYzh5L2NsaWVudCc7XG5pbXBvcnQgeyBPYnNlcnZhYmxlLCBTdWJqZWN0IH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBkaXN0aW5jdFVudGlsQ2hhbmdlZCwgbWFwLCBzdGFydFdpdGggfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5cbi8qKlxuICogQGRlcHJlY2F0ZWQgQ29uc2lkZXIgdXNpbmcgdGhlIGBob29rT3B0aW9uc2AgZnVuY3Rpb24gaW5zdGVhZC5cbiAqL1xuZXhwb3J0IGNvbnN0IEhPT0tfT1BUSU9OUyA9IG5ldyBJbmplY3Rpb25Ub2tlbjxFeHRlbnNpb25GYWN0b3J5PEFwcGxpY2F0aW9uT3B0aW9ucz4+KFxuICAnSE9PS19PUFRJT05TJ1xuKTtcblxuLyoqXG4gKiBZb3UgY2FuIGVpdGhlciBwcm92aWRlIGEgc2luZ2xlIGBBcHBsaWNhdGlvbk9wdGlvbnNgIGFzIHBhcmFtZXRlcjpcbiAqIGBgYHR5cGVzY3JpcHRcbiAqICBob29rT3B0aW9ucyguLi4pXG4gKiBgYGBcbiAqXG4gKiBPciBhbiBhcnJheSB0byBkaXJlY3RseSByZWdpc3RlciBtdWx0aXBsZTpcbiAqIGBgYHR5cGVzY3JpcHRcbiAqICBob29rT3B0aW9ucyhbLi4uXSlcbiAqIGBgYFxuICpcbiAqIE9yIHlvdSBwcm92aWRlIGFuIFNlcnZpY2UgdGhhdCBpbXBsZW1lbnRzIGBFeHRlbnNpb25GYWN0b3J5PEFwcGxpY2F0aW9uT3B0aW9ucz5gXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiAgZXhwb3J0IGNsYXNzIE15QXBwbGljYXRpb25PcHRpb25zRmFjdG9yeSBpbXBsZW1lbnRzIEV4dGVuc2lvbkZhY3Rvcnk8QXBwbGljYXRpb25PcHRpb25zPiB7Li4ufVxuICogIC4uLlxuICogIGhvb2tPcHRpb25zKE15QXBwbGljYXRpb25PcHRpb25zRmFjdG9yeSlcbiAqIGBgYFxuICogQSB0eXBlZCBhbHRlcm5hdGl2ZSB0byBgSE9PS19PUFRJT05TYC5cbiAqIEBwYXJhbSBvcHRpb25zIFRoZSBgQXBwbGljYXRpb25PcHRpb25zYCdzIG9yIGBFeHRlbnNpb25GYWN0b3J5YCB0byBiZSBwcm92aWRlZC5cbiAqIEByZXR1cm5zIEFuIGBQcm92aWRlcmAgdG8gYmUgcHJvdmlkZWQgaW4geW91ciBtb2R1bGUuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBob29rT3B0aW9ucyhcbiAgb3B0aW9uczogR2VuZXJpY0hvb2tUeXBlPEFwcGxpY2F0aW9uT3B0aW9ucz4sXG4gIGhvb2tPcHRpb25zPzogUGFydGlhbDxHZW5lcmljSG9va09wdGlvbnM+XG4pIHtcbiAgcmV0dXJuIGhvb2tHZW5lcmljPEFwcGxpY2F0aW9uT3B0aW9ucz4ob3B0aW9ucywgSE9PS19PUFRJT05TLCBob29rT3B0aW9ucyk7XG59XG5cbi8qKlxuICogQSBzZXJ2aWNlIHRoYXQgYWxsb3dzIHRvIHNldCBvciBnZXQgYXBwbGljYXRpb24gb3B0aW9uc1xuICogd2hpY2ggY29uZmlndXJlIHRoZSBkZWZhdWx0IGJlaGF2aW9yIG9mIHRoZSBVSS5cbiAqL1xuQEluamVjdGFibGUoeyBwcm92aWRlZEluOiAncm9vdCcgfSlcbmV4cG9ydCBjbGFzcyBPcHRpb25zU2VydmljZSBleHRlbmRzIEFwcGxpY2F0aW9uT3B0aW9ucyB7XG4gIG9wdGlvbnNVcGRhdGVkJDogT2JzZXJ2YWJsZTx2b2lkPjtcbiAgW2tleTogc3RyaW5nXTogYW55O1xuICBwcml2YXRlIF9vcHRpb25zVXBkYXRlZCQgPSBuZXcgU3ViamVjdDx2b2lkPigpO1xuICBjb25zdHJ1Y3RvcihcbiAgICBAT3B0aW9uYWwoKSBASW5qZWN0KEhPT0tfT1BUSU9OUykgb3B0aW9ucyxcbiAgICBwcml2YXRlIHN5c3RlbU9wdGlvbnNTZXJ2aWNlOiBTeXN0ZW1PcHRpb25zU2VydmljZSxcbiAgICBwcml2YXRlIHRlbmFudE9wdGlvblNlcnZpY2U6IFRlbmFudE9wdGlvbnNTZXJ2aWNlXG4gICkge1xuICAgIHN1cGVyKCk7XG4gICAgdGhpcy5vcHRpb25zVXBkYXRlZCQgPSB0aGlzLl9vcHRpb25zVXBkYXRlZCQuYXNPYnNlcnZhYmxlKCk7XG4gICAgdGhpcy5zZXR1cE9wdGlvbnMob3B0aW9ucyk7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyBhbiBhcHBsaWNhdGlvbiBvcHRpb24gdXNlZCB0byBjb25maWd1cmUgdGhlIFVJLlxuICAgKiBAcGFyYW0gb3B0aW9uS2V5IFRoZSBhcHBsaWNhdGlvbiBvcHRpb25zIGtleS5cbiAgICogQHBhcmFtIGRlZmF1bHRWYWx1ZSBBIHZhbHVlIHRvIHJldHVybiBpZiBub24gaXMgc2V0LlxuICAgKiBAcGFyYW0gYXR0ZW1wdFBhcnNlIEluZGljYXRlcyB3aGV0aGVyIHRoZSB2YWx1ZSBzaG91bGQgYmUgcGFyc2VkIHdpdGggSlNPTi5wYXJzZS5cbiAgICovXG4gIGdldDxUIGV4dGVuZHMga2V5b2YgT3B0aW9uc1NlcnZpY2U+KFxuICAgIG9wdGlvbktleTogVCxcbiAgICBkZWZhdWx0VmFsdWU/OiBPcHRpb25zU2VydmljZVtUXSxcbiAgICBhdHRlbXB0UGFyc2U/OiBib29sZWFuXG4gICk6IE9wdGlvbnNTZXJ2aWNlW1RdIHtcbiAgICBsZXQgdmFsdWUgPSB0aGlzW29wdGlvbktleV07XG4gICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIHZhbHVlID0gdGhpc1tjYW1lbENhc2Uob3B0aW9uS2V5KV07XG4gICAgfVxuICAgIGlmIChhdHRlbXB0UGFyc2UpIHtcbiAgICAgIHJldHVybiB0aGlzLnBhcnNlT3B0aW9uUmF3VmFsdWUodmFsdWUsIGRlZmF1bHRWYWx1ZSk7XG4gICAgfVxuICAgIHJldHVybiB0eXBlb2YgdmFsdWUgIT09ICd1bmRlZmluZWQnID8gdmFsdWUgOiBkZWZhdWx0VmFsdWU7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyBhbiBvYnNlcnZhYmxlIG9mIGFuIGFwcGxpY2F0aW9uIG9wdGlvbiB1c2VkIHRvIGNvbmZpZ3VyZSB0aGUgVUkuXG4gICAqIEBwYXJhbSBvcHRpb25LZXkgVGhlIGFwcGxpY2F0aW9uIG9wdGlvbnMga2V5LlxuICAgKiBAcGFyYW0gZGVmYXVsdFZhbHVlIEEgdmFsdWUgdG8gcmV0dXJuIGlmIG5vbiBpcyBzZXQuXG4gICAqIEBwYXJhbSBhdHRlbXB0UGFyc2UgSW5kaWNhdGVzIHdoZXRoZXIgdGhlIHZhbHVlIHNob3VsZCBiZSBwYXJzZWQgd2l0aCBKU09OLnBhcnNlLlxuICAgKi9cbiAgZ2V0JDxUIGV4dGVuZHMga2V5b2YgT3B0aW9uc1NlcnZpY2U+KFxuICAgIG9wdGlvbktleTogVCxcbiAgICBkZWZhdWx0VmFsdWU/OiBPcHRpb25zU2VydmljZVtUXSxcbiAgICBhdHRlbXB0UGFyc2U/OiBib29sZWFuXG4gICk6IE9ic2VydmFibGU8T3B0aW9uc1NlcnZpY2VbVF0+IHtcbiAgICBjb25zdCBmbiA9ICgpID0+IHRoaXMuZ2V0KG9wdGlvbktleSwgZGVmYXVsdFZhbHVlLCBhdHRlbXB0UGFyc2UpO1xuICAgIHJldHVybiB0aGlzLm9wdGlvbnNVcGRhdGVkJC5waXBlKG1hcChmbiksIHN0YXJ0V2l0aChmbigpKSwgZGlzdGluY3RVbnRpbENoYW5nZWQoKSk7XG4gIH1cblxuICAvKipcbiAgICogU2V0cyBhbiBhcHBsaWNhdGlvbiBvcHRpb24uXG4gICAqIEBwYXJhbSBrZXkgVGhlIGtleSB0byBzZXQuXG4gICAqIEBwYXJhbSB2YWx1ZSBUaGUgdmFsdWUgdG8gc2V0LlxuICAgKi9cbiAgc2V0PFQgZXh0ZW5kcyBrZXlvZiBPcHRpb25zU2VydmljZT4oa2V5OiBULCB2YWx1ZTogT3B0aW9uc1NlcnZpY2VbVF0pIHtcbiAgICBjb25zdCBjYW1lbENhc2VkS2V5ID0gY2FtZWxDYXNlKGtleSk7XG4gICAgY29uc3QgcHJldmlvdXNWYWx1ZSA9IHRoaXNbY2FtZWxDYXNlZEtleV07XG4gICAgdGhpc1tjYW1lbENhc2VkS2V5XSA9IHZhbHVlO1xuICAgIGlmICghaXNFcXVhbChwcmV2aW91c1ZhbHVlLCB2YWx1ZSkpIHtcbiAgICAgIHRoaXMuX29wdGlvbnNVcGRhdGVkJC5uZXh0KCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIERlbGV0ZXMgYW4gYXBwbGljYXRpb24gb3B0aW9uLlxuICAgKiBAcGFyYW0ga2V5IFRoZSBrZXkgdG8gcmVtb3ZlLlxuICAgKi9cbiAgZGVsZXRlPFQgZXh0ZW5kcyBrZXlvZiBPcHRpb25zU2VydmljZT4oa2V5OiBUKSB7XG4gICAgY29uc3QgY2FtZWxDYXNlZEtleSA9IGNhbWVsQ2FzZShrZXkpO1xuICAgIGNvbnN0IHByZXZpb3VzVmFsdWUgPSB0aGlzW2NhbWVsQ2FzZWRLZXldO1xuICAgIGRlbGV0ZSB0aGlzW2NhbWVsQ2FzZWRLZXldO1xuICAgIGNvbnN0IG5ld1ZhbHVlID0gdGhpc1tjYW1lbENhc2VkS2V5XTtcblxuICAgIGlmICghaXNFcXVhbChwcmV2aW91c1ZhbHVlLCBuZXdWYWx1ZSkpIHtcbiAgICAgIHRoaXMuX29wdGlvbnNVcGRhdGVkJC5uZXh0KCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEdldHMgc3VwcG9ydCBVUkwgZnJvbTpcbiAgICogLSBhcHBsaWNhdGlvbiBvcHRpb24gYHN1cHBvcnRVcmxgLFxuICAgKiAtIG9yIGN1cnJlbnQgdGVuYW50J3Mgb3B0aW9uIGBjb25maWd1cmF0aW9uIC8gc3lzdGVtLnN1cHBvcnQudXJsYCxcbiAgICogLSBvciBjdXJyZW50IHRlbmFudCdzIGluaGVyaXRlZCBvcHRpb24gYGNvbmZpZ3VyYXRpb24gLyBzeXN0ZW0uc3VwcG9ydC51cmxgLFxuICAgKiAtIG9yIHN5c3RlbSBvcHRpb24gYGNvbmZpZ3VyYXRpb24gLyBzeXN0ZW0uc3VwcG9ydC51cmxgLFxuICAgKiAtIG90aGVyd2lzZSBkZWZhdWx0cyB0byBgZmFsc2VgLlxuICAgKlxuICAgKiBAcmV0dXJucyBSZXR1cm5zIHN1cHBvcnQgdXJsIG9yIGZhbHNlLlxuICAgKi9cbiAgYXN5bmMgZ2V0U3VwcG9ydFVybCgpIHtcbiAgICBsZXQgdXJsOiBzdHJpbmcgfCBib29sZWFuID0gdGhpcy5zdXBwb3J0VXJsO1xuXG4gICAgaWYgKGlzVW5kZWZpbmVkKHVybCkpIHtcbiAgICAgIHVybCA9IGF3YWl0IHRoaXMuZ2V0Q3VycmVudFRlbmFudE9wdGlvbignY29uZmlndXJhdGlvbicsICdzeXN0ZW0uc3VwcG9ydC51cmwnKTtcbiAgICB9XG4gICAgaWYgKGlzVW5kZWZpbmVkKHVybCkpIHtcbiAgICAgIHVybCA9IGF3YWl0IHRoaXMuZ2V0SW5oZXJpdGVkVGVuYW50T3B0aW9uKCdjb25maWd1cmF0aW9uJywgJ3N5c3RlbS5zdXBwb3J0LnVybCcpO1xuICAgIH1cbiAgICBpZiAoaXNVbmRlZmluZWQodXJsKSkge1xuICAgICAgdXJsID0gKGF3YWl0IHRoaXMuZ2V0U3lzdGVtT3B0aW9uKCdzdXBwb3J0JywgJ3VybCcpKSB8fCBmYWxzZTtcbiAgICB9XG5cbiAgICB0aGlzLnN1cHBvcnRVcmwgPSB1cmw7XG4gICAgcmV0dXJuIHRoaXMuc3VwcG9ydFVybDtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIGlmIHRoZSB0ZW5hbnQgYWxsb3dzIHRvIHNob3cgdGhlIGFjdGl2YXRlLXN1cHBvcnQgdXNlciBtZW51IGVudHJ5LlxuICAgKiBOb3RlOiBPbmx5IGlmIHN5c3RlbS1sZXZlbCBzdXBwb3J0LXVzZXIvZW5hYmxlZCBpcyBmYWxzZSB3ZSBjYW4gYWN0aXZhdGUgaXQgYXQgdGVuYW50IGxldmVsLlxuICAgKi9cbiAgYXN5bmMgZ2V0QWN0aXZhdGVTdXBwb3J0VXNlcigpIHtcbiAgICBjb25zdCBvcHRpb24gPSBhd2FpdCB0aGlzLmdldFN5c3RlbU9wdGlvbignc3VwcG9ydC11c2VyJywgJ2VuYWJsZWQnLCB0cnVlKTtcbiAgICByZXR1cm4gIW9wdGlvbjtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXRzIGEgdmFsdWUgZnJvbSB0aGUgc3lzdGVtIHNlcnZpY2UgYW5kIHBhcnNlcyBpdC5cbiAgICpcbiAgICogQHBhcmFtIGNhdGVnb3J5IFRoZSBjYXRlZ29yeSBmb3IgdGhpcyBvcHRpb24uXG4gICAqIEBwYXJhbSBrZXkgVGhlIGtleSBmb3IgdGhhdCBvcHRpb24uXG4gICAqIEBwYXJhbSBkZWZhdWx0VmFsdWUgVGhlIGRlZmF1bHQgaWYgdGhlIG9wdGlvbiB3YXMgbm90IGZvdW5kLlxuICAgKi9cbiAgYXN5bmMgZ2V0U3lzdGVtT3B0aW9uPFQgPSBzdHJpbmc+KFxuICAgIGNhdGVnb3J5OiBzdHJpbmcsXG4gICAga2V5OiBzdHJpbmcsXG4gICAgZGVmYXVsdFZhbHVlPzogVFxuICApOiBQcm9taXNlPFQgfCBzdHJpbmc+IHtcbiAgICByZXR1cm4gdGhpcy5nZXRPcHRpb25Gcm9tU2VydmljZTxUPihcbiAgICAgIGNhdGVnb3J5LFxuICAgICAga2V5LFxuICAgICAgbnVsbCxcbiAgICAgIHRoaXMuc3lzdGVtT3B0aW9uc1NlcnZpY2UsXG4gICAgICBkZWZhdWx0VmFsdWVcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldHMgYSB2YWx1ZSBmcm9tIHRoZSB0ZW5hbnQgc2VydmljZSBhbmQgcGFyc2VzIGl0LlxuICAgKlxuICAgKiBAcGFyYW0gY2F0ZWdvcnkgVGhlIGNhdGVnb3J5IGZvciB0aGlzIG9wdGlvbi5cbiAgICogQHBhcmFtIGtleSBUaGUga2V5IGZvciB0aGF0IG9wdGlvbi5cbiAgICogQHBhcmFtIGRlZmF1bHRWYWx1ZSBUaGUgZGVmYXVsdCBpZiB0aGUgb3B0aW9uIHdhcyBub3QgZm91bmQuXG4gICAqL1xuICBhc3luYyBnZXRUZW5hbnRPcHRpb248VCA9IHN0cmluZz4oXG4gICAgY2F0ZWdvcnk6IHN0cmluZyxcbiAgICBrZXk6IHN0cmluZyxcbiAgICBkZWZhdWx0VmFsdWU/OiBUXG4gICk6IFByb21pc2U8VCB8IHN0cmluZz4ge1xuICAgIHJldHVybiB0aGlzLmdldE9wdGlvbkZyb21TZXJ2aWNlPFQ+KFxuICAgICAgY2F0ZWdvcnksXG4gICAgICBrZXksXG4gICAgICBudWxsLFxuICAgICAgdGhpcy50ZW5hbnRPcHRpb25TZXJ2aWNlLFxuICAgICAgZGVmYXVsdFZhbHVlXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXRzIGFuIGluaGVyaXRlZCBmcm9tIHBhcmVudCB2YWx1ZSBmcm9tIHRoZSB0ZW5hbnQgc2VydmljZSBpZiBpbmhlcml0YW5jZSBzdXBwb3J0ZWQgYmFzZWQgb24gZ2l2ZW4gcGFyYW1ldGVycy5cbiAgICpcbiAgICogQHBhcmFtIGNhdGVnb3J5IFRoZSBjYXRlZ29yeSBmb3IgdGhpcyBvcHRpb24uXG4gICAqIEBwYXJhbSBrZXkgVGhlIGtleSBmb3IgdGhhdCBvcHRpb24uXG4gICAqIEBwYXJhbSBkZWZhdWx0VmFsdWUgVGhlIGRlZmF1bHQgaWYgdGhlIG9wdGlvbiB3YXMgbm90IGZvdW5kLlxuICAgKi9cbiAgYXN5bmMgZ2V0SW5oZXJpdGVkVGVuYW50T3B0aW9uPFQgPSBzdHJpbmc+KFxuICAgIGNhdGVnb3J5OiBzdHJpbmcsXG4gICAga2V5OiBzdHJpbmcsXG4gICAgZGVmYXVsdFZhbHVlPzogVFxuICApOiBQcm9taXNlPFQgfCBzdHJpbmc+IHtcbiAgICByZXR1cm4gdGhpcy5nZXRPcHRpb25Gcm9tU2VydmljZTxUPihcbiAgICAgIGNhdGVnb3J5LFxuICAgICAga2V5LFxuICAgICAgeyBldmFsdWF0ZTogJ2luaGVyaXRlZCcgfSxcbiAgICAgIHRoaXMudGVuYW50T3B0aW9uU2VydmljZSxcbiAgICAgIGRlZmF1bHRWYWx1ZVxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogR2V0cyBjdXJyZW50IHRlbmFudCBvcHRpb24gdmFsdWUgZnJvbSB0aGUgdGVuYW50IHNlcnZpY2Ugb21pdHRpbmcgdGhlIGluaGVyaXRhbmNlIHN1cHBvcnRlZCBiYXNlZCBvbiBnaXZlbiBwYXJhbWV0ZXJzLlxuICAgKlxuICAgKiBAcGFyYW0gY2F0ZWdvcnkgVGhlIGNhdGVnb3J5IGZvciB0aGlzIG9wdGlvbi5cbiAgICogQHBhcmFtIGtleSBUaGUga2V5IGZvciB0aGF0IG9wdGlvbi5cbiAgICogQHBhcmFtIGRlZmF1bHRWYWx1ZSBUaGUgZGVmYXVsdCBpZiB0aGUgb3B0aW9uIHdhcyBub3QgZm91bmQuXG4gICAqL1xuICBhc3luYyBnZXRDdXJyZW50VGVuYW50T3B0aW9uPFQgPSBzdHJpbmc+KFxuICAgIGNhdGVnb3J5OiBzdHJpbmcsXG4gICAga2V5OiBzdHJpbmcsXG4gICAgZGVmYXVsdFZhbHVlPzogVFxuICApOiBQcm9taXNlPFQgfCBzdHJpbmc+IHtcbiAgICByZXR1cm4gdGhpcy5nZXRPcHRpb25Gcm9tU2VydmljZTxUPihcbiAgICAgIGNhdGVnb3J5LFxuICAgICAga2V5LFxuICAgICAgeyBldmFsdWF0ZTogJ2N1cnJlbnQnIH0sXG4gICAgICB0aGlzLnRlbmFudE9wdGlvblNlcnZpY2UsXG4gICAgICBkZWZhdWx0VmFsdWVcbiAgICApO1xuICB9XG5cbiAgcHJpdmF0ZSBzZXR1cE9wdGlvbnMob3B0aW9uczogYW55W10gfCBudWxsKSB7XG4gICAgaWYgKG9wdGlvbnMpIHtcbiAgICAgIGlmICghQXJyYXkuaXNBcnJheShvcHRpb25zKSkge1xuICAgICAgICBvcHRpb25zID0gW29wdGlvbnNdO1xuICAgICAgfVxuICAgICAgbGV0IGNvbWJpbmVkT3B0aW9ucyA9IHt9O1xuICAgICAgaWYgKG9wdGlvbnMubGVuZ3RoID09PSAxKSB7XG4gICAgICAgIGNvbWJpbmVkT3B0aW9ucyA9IG9wdGlvbnNbMF07XG4gICAgICB9IGVsc2UgaWYgKG9wdGlvbnMubGVuZ3RoID4gMSkge1xuICAgICAgICBvcHRpb25zLmZvckVhY2gob3B0aW9uTWFwID0+IHtcbiAgICAgICAgICBpZiAob3B0aW9uTWFwKSB7XG4gICAgICAgICAgICB0aGlzLmFwcGx5T3B0aW9ucyhvcHRpb25NYXAsIGNvbWJpbmVkT3B0aW9ucyk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGlmICh0aGlzLmFwcGx5T3B0aW9ucyhjb21iaW5lZE9wdGlvbnMsIHRoaXMpKSB7XG4gICAgICAgIHRoaXMuX29wdGlvbnNVcGRhdGVkJC5uZXh0KCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBhcHBseU9wdGlvbnMob3B0aW9uczogUmVjb3JkPHN0cmluZywgYW55PiwgYXBwbHlUbzogYW55KSB7XG4gICAgbGV0IG9wdGlvbldhc0NoYW5nZWQgPSBmYWxzZTtcbiAgICBPYmplY3QuZW50cmllcyhvcHRpb25zKS5mb3JFYWNoKChba2V5LCB2YWx1ZV0pID0+IHtcbiAgICAgIGNvbnN0IGNhbWVsQ2FzZWRLZXkgPSBjYW1lbENhc2Uoa2V5KTtcbiAgICAgIGNvbnN0IHByZXZpb3VzVmFsdWUgPSBhcHBseVRvW2NhbWVsQ2FzZWRLZXldO1xuICAgICAgYXBwbHlUb1tjYW1lbENhc2VkS2V5XSA9IHZhbHVlO1xuICAgICAgaWYgKCFpc0VxdWFsKHByZXZpb3VzVmFsdWUsIHZhbHVlKSkge1xuICAgICAgICBvcHRpb25XYXNDaGFuZ2VkID0gdHJ1ZTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gb3B0aW9uV2FzQ2hhbmdlZDtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgZ2V0T3B0aW9uRnJvbVNlcnZpY2U8VCA9IHN0cmluZz4oXG4gICAgY2F0ZWdvcnk6IHN0cmluZyxcbiAgICBrZXk6IHN0cmluZyxcbiAgICBmaWx0ZXI6IElUZW5hbnRPcHRpb25EZXRhaWxQYXJhbXMsXG4gICAgc2VydmljZTogU3lzdGVtT3B0aW9uc1NlcnZpY2UgfCBUZW5hbnRPcHRpb25zU2VydmljZSxcbiAgICBkZWZhdWx0VmFsdWU6IFRcbiAgKTogUHJvbWlzZTxUIHwgc3RyaW5nPiB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHsgZGF0YSB9ID0gYXdhaXQgc2VydmljZS5kZXRhaWwoeyBjYXRlZ29yeSwga2V5IH0sIGZpbHRlcik7XG4gICAgICByZXR1cm4gdGhpcy5wYXJzZU9wdGlvblJhd1ZhbHVlKGRhdGEudmFsdWUsIGRlZmF1bHRWYWx1ZSk7XG4gICAgfSBjYXRjaCAoZXgpIHtcbiAgICAgIHJldHVybiBkZWZhdWx0VmFsdWU7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBwYXJzZU9wdGlvblJhd1ZhbHVlPFQgPSBzdHJpbmc+KHJhd1ZhbHVlOiBzdHJpbmcsIGRlZmF1bHRWYWx1ZTogVCk6IFQgfCBzdHJpbmcge1xuICAgIGxldCB2YWx1ZTogVCB8IHN0cmluZztcbiAgICB0cnkge1xuICAgICAgdmFsdWUgPSBKU09OLnBhcnNlKHJhd1ZhbHVlKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICB2YWx1ZSA9IGlzVW5kZWZpbmVkKHJhd1ZhbHVlKSA/IGRlZmF1bHRWYWx1ZSA6IHJhd1ZhbHVlO1xuICAgIH1cbiAgICByZXR1cm4gdmFsdWU7XG4gIH1cbn1cbiJdfQ==