@iotize/ionic
Version:
Iotize specific building blocks on top of @ionic/angular.
243 lines • 35.9 kB
JavaScript
import { MonitorEngine } from '@iotize/tap/data';
import '@iotize/tap/ext/data';
import { debug } from '../../logger';
const TAG = 'DataManager';
export class DataHolder {
items;
constructor(items = []) {
this.items = items;
}
item(id) {
const item = this.items.find((v) => v.id == id);
if (!item) {
throw new Error(`Item with id "${id}" does not exist`);
}
return item;
}
add(item, replace) {
if (replace || this.items.find((v) => v.id == item.id) == undefined) {
debug(TAG, 'Added item: ', item);
this.items.push(item);
}
return this.item(item.id);
}
}
// export function newBundleConfigToOldBundleConfig(bundlesConfig: BundleConfig[] | undefined): BundleConfigPredefined[] {
// if (!bundlesConfig) {
// return [];
// }
// return bundlesConfig.map((bundleConfig: BundleSchemaConfig) => {
// const predefinedConfig: BundleConfigPredefined = {
// id: bundleConfig.id,
// converter: undefined,
// name: bundleConfig.name || `Bundle ${bundleConfig.id}`,
// variables: (bundleConfig.variables || []).map((variableConfig: MemoryVariableConfig) => {
// const variableType = VariableType[variableConfig.type];
// if (variableType === undefined) {
// throw new Error(`Invalid variable type: ${variableConfig.type}`);
// }
// let converter: BodyConverter<any> | undefined;
// if (variableConfig.converter) {
// converter = variableConfig.converter;
// } else {
// converter = getConverterFromFormat(variableType, variableConfig.length || 1);
// }
// const predifinedVariableConfig: TapVariable.Config = {
// id: variableConfig.id,
// converter: converter,
// length: variableConfig.length,
// name: variableConfig.name || `Variable ${variableConfig.id}`,
// type: variableType,
// unit: variableConfig.unit
// };
// return predifinedVariableConfig;
// })
// };
// return predefinedConfig;
// });
// }
export class DataManagerIonic {
tap;
constructor(tap) {
this.tap = tap;
// const allVariables: AbstractVariable<VariableByType[VariableKey]>[] = Object.values(data.variables);
// this.tlvConverter = new TlvBundleConverter(allVariables.map((variable: AbstractVariable<any>) => {
// if (!(variable instanceof VariableConfig)) {
// throw new Error(`Variable ${variable.identifier} has no config`);
// }
// return {
// id: variable.config.id,
// name: variable.config.name,
// converter: variable.converter
// };
// }));
// this.dataStream = this.setupDataStream();
// this.dataLogger = DataLogger.fromTap(
// this.tap,
// {
// period: 2000 // TODO change
// }
// );
// this.tap.variables._variables = data.variables as any;
// this.tap.bundles._bundles = data.bundles as any;
// Change variable stream;
// Object.values(this.data.variables).map((variable: any) => {
// const variableName = variable.config.name;
// // console.log('Replacing monitor for ', variable);
// variable._monitor = ObservableMonitor.fromObservable(
// this.dataStream
// .pipe(
// filter(data => variableName in data),
// map(data => data[variableName]),
// rxTap(value => debug(TAG, `Extracted key ${variableName} from monitoring data`, value))
// )
// ,
// MonitorEngine.State.START
// );
// });
// // Change bundle stream;
// Object.values(this.data.bundles).map((bundle: any) => {
// bundle._monitor = ObservableMonitor.fromObservable(
// this.dataStream
// .pipe(
// rxTap(value => debug(TAG, `New bundle value `, value))
// )
// ,
// MonitorEngine.State.START
// );
// // TODO factorize and clean
// Object.values(bundle.variables).map((variable: any) => {
// const variableName = variable.config.name;
// // console.log('Replacing monitor for variable in bundle', variable);
// variable._monitor = ObservableMonitor.fromObservable(
// this.dataStream
// .pipe(
// filter(data => variableName in data),
// map(data => data[variableName]),
// rxTap(value => debug(TAG, `Extracted key ${variableName} from monitoring data`, value))
// )
// ,
// MonitorEngine.State.START
// );
// });
// });
// debug(TAG, 'New data manager instance: ', this);
}
// get variables(): Record<VariableKey, AbstractVariable<VariableByType[VariableKey]>> {
// return this.data.variables;
// }
// get bundles(): Record<BundleKey, Bundle<BundleByType[BundleKey]>> {
// return this.data.bundles;
// }
get sourceController() {
const currentSourceId = this.switchableStreamController.getCurrentSourceId();
return this.sourceControllers[currentSourceId];
}
get isMonitoringRunning() {
for (const value of Object.values(this.sourceControllers)) {
if (value.state == MonitorEngine.State.START) {
return true;
}
}
return false;
}
switchableStreamController;
// dataStream: Observable<Record<string, any>>;
// tlvConverter: TlvBundleConverter<Record<string, Uint8Array>>;
// dataLogger: DataLogger;
sourceControllers = {};
// public static fromSchemaConfig(tap: Tap, schema: TapConfiguratorConfig): DataManagerIonic {
// const bundles = schema.config.data ? schema.config.data.bundles || [] : [];
// return DataManagerIonic.fromBundleConfig(tap, bundles);
// }
// public static fromBundleConfig(tap: Tap, bundles: BundleConfig[]): DataManagerIonic {
// return new DataManagerIonic(
// tap,
// DataManagerIonic.createDataFromSchemaConfig(tap, bundles)
// );
// }
// public static createDataFromSchemaConfig<VariableByType extends Record<string, any>, VariableKey extends string, BundleByType extends Record<string, any>, BundleKey extends string>(tap: Tap, bundlesConfig: BundleSchemaConfig[]) {
// const predifinedConfig: BundleConfigPredefined[] = newBundleConfigToOldBundleConfig(bundlesConfig);
// return DataManagerIonic.createDataFromConfig(tap, predifinedConfig);
// }
// public static createDataFromConfig<VariableByType extends Record<string, any>, VariableKey extends string, BundleByType extends Record<string, any>, BundleKey extends string>(tap: Tap, bundlesConfig: BundleConfigPredefined[]) {
// // let bundleConfigCopy = [...bundlesConfig];
// const bundles: Record<string, any> = {};
// bundlesConfig.forEach((bundleConfig: BundleConfigPredefined) => {
// const bundle: Bundle = Bundle.createFromConfig(bundleConfig, tap.service.bundle, tap.service.variable);
// bundles[bundleConfig.name] = bundle;
// });
// const variables: Record<string, any> = {};
// bundlesConfig.forEach((bundle) => {
// bundle.variables.forEach((variableConfig: TapVariable.Config) => {
// debug(TAG, 'Create from variable config: ', variableConfig);
// variables[variableConfig.name || variableConfig.id.toString()] = TapVariable.createFromConfig(variableConfig, tap.service.variable);
// });
// });
// return {
// bundles: bundles as Record<BundleKey, Bundle<BundleByType[BundleKey]>>,
// variables: variables as Record<VariableKey, AbstractVariable<VariableByType[VariableKey]>>
// };
// }
listVariables() {
return this.tap.data.listVariables();
}
listBundles() {
return this.tap.data.listBundles();
}
// public variable<T extends VariableKey>(key: T): AbstractVariable<VariableByType[T]> {
// if (!(key in this.variables)) {
// throw new Error(`Variable with identifier "${key}" is not configured`);
// }
// return this.variables[key] as AbstractVariable<VariableByType[T]>;
// }
// public bundle<T extends BundleKey>(key: T): Bundle<BundleByType[T]> {
// if (!(key in this.bundles)) {
// throw new Error(`Bundle with identifier "${key}" is not configured`);
// }
// return this.bundles[key] as any;
// }
stopAll() {
debug(TAG, 'Stop monitoring');
// for (const ctrlKey in this.sourceControllers) {
// this.sourceControllers[ctrlKey].state = MonitorEngine.State.PAUSE;
// }
this.tap.data.monitoring.stop();
}
startAll(period) {
// debug(TAG, `[Controller=${this.sourceController.id}] Start monitoring with period ${period || this.sourceController.period.value}`, this.sourceController);
// if (period) {
// this.setMonitoringPeriod(period);
// }
// this.sourceController.state = MonitorEngine.State.START;
this.tap.data.monitoring.start();
}
setMonitoringPeriod(period) {
debug(TAG, 'Changing monitoring period to ', period);
this.sourceController.period.next(period);
}
destroy() {
this.stopAll();
}
refresh() {
if (this.sourceController.refresh) {
this.sourceController.refresh();
}
}
changeDataSource(dataSource) {
switch (dataSource) {
case 'datalog':
this.useDatalogSource();
break;
default:
this.useLiveSource();
}
}
useLiveSource() {
this.switchableStreamController.useSource('live');
}
useDatalogSource() {
this.switchableStreamController.useSource('datalog');
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW1wbC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2lvdGl6ZS1pb25pYy9zcmMvbGliL2V4dGVuc2lvbnMvZGF0YS1tYW5hZ2VyL2ltcGwudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBTUEsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBRWpELE9BQU8sc0JBQXNCLENBQUM7QUFFOUIsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLGNBQWMsQ0FBQztBQVFyQyxNQUFNLEdBQUcsR0FBRyxhQUFhLENBQUM7QUFFMUIsTUFBTSxPQUFPLFVBQVU7SUFDRjtJQUFuQixZQUFtQixRQUFzQixFQUFFO1FBQXhCLFVBQUssR0FBTCxLQUFLLENBQW1CO0lBQUcsQ0FBQztJQUUvQyxJQUFJLENBQUMsRUFBVTtRQUNiLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO1FBQ2hELElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQztZQUNWLE1BQU0sSUFBSSxLQUFLLENBQUMsaUJBQWlCLEVBQUUsa0JBQWtCLENBQUMsQ0FBQztRQUN6RCxDQUFDO1FBQ0QsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQsR0FBRyxDQUFDLElBQWdCLEVBQUUsT0FBZ0I7UUFDcEMsSUFBSSxPQUFPLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLElBQUksSUFBSSxDQUFDLEVBQUUsQ0FBQyxJQUFJLFNBQVMsRUFBRSxDQUFDO1lBQ3BFLEtBQUssQ0FBQyxHQUFHLEVBQUUsY0FBYyxFQUFFLElBQUksQ0FBQyxDQUFDO1lBQ2pDLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFD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XG5pbXBvcnQgeyBUbHZCdW5kbGVDb252ZXJ0ZXIgfSBmcm9tICdAaW90aXplL3RhcC9jbGllbnQvaW1wbCc7XG5pbXBvcnQge1xuICBCdW5kbGVDb25maWcsXG4gIFRhcENvbmZpZ3VyYXRvckNvbmZpZyxcbn0gZnJvbSAnQGlvdGl6ZS90YXAvY29uZmlnL3NjaGVtYS92MSc7XG5pbXBvcnQgeyBNb25pdG9yRW5naW5lIH0gZnJvbSAnQGlvdGl6ZS90YXAvZGF0YSc7XG5pbXBvcnQgeyBEYXRhTG9nZ2VyIH0gZnJvbSAnQGlvdGl6ZS90YXAvZGF0YS1sb2cnO1xuaW1wb3J0ICdAaW90aXplL3RhcC9leHQvZGF0YSc7XG5pbXBvcnQgeyBPYnNlcnZhYmxlIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBkZWJ1ZyB9IGZyb20gJy4uLy4uL2xvZ2dlcic7XG5pbXBvcnQgeyBTd2l0Y2hhYmxlU3RyZWFtTW9uaXRvciBhcyBTd2l0Y2hhYmxlU3RyZWFtQ29udHJvbGxlciB9IGZyb20gJy4uL3N3aXRjaGFibGUtc3RyZWFtLW1vbml0b3InO1xuaW1wb3J0IHtcbiAgRGF0YVNvdXJjZUNvbnRyb2xsZXIsXG4gIERhdGFTb3VyY2VUeXBlLFxuICBJdGVtSG9sZGVyLFxufSBmcm9tICcuL2RlZmluaXRpb25zJztcblxuY29uc3QgVEFHID0gJ0RhdGFNYW5hZ2VyJztcblxuZXhwb3J0IGNsYXNzIERhdGFIb2xkZXIge1xuICBjb25zdHJ1Y3RvcihwdWJsaWMgaXRlbXM6IEl0ZW1Ib2xkZXJbXSA9IFtdKSB7fVxuXG4gIGl0ZW0oaWQ6IHN0cmluZyk6IEl0ZW1Ib2xkZXIge1xuICAgIGNvbnN0IGl0ZW0gPSB0aGlzLml0ZW1zLmZpbmQoKHYpID0+IHYuaWQgPT0gaWQpO1xuICAgIGlmICghaXRlbSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBJdGVtIHdpdGggaWQgXCIke2lkfVwiIGRvZXMgbm90IGV4aXN0YCk7XG4gICAgfVxuICAgIHJldHVybiBpdGVtO1xuICB9XG5cbiAgYWRkKGl0ZW06IEl0ZW1Ib2xkZXIsIHJlcGxhY2U6IGJvb2xlYW4pIHtcbiAgICBpZiAocmVwbGFjZSB8fCB0aGlzLml0ZW1zLmZpbmQoKHYpID0+IHYuaWQgPT0gaXRlbS5pZCkgPT0gdW5kZWZpbmVkKSB7XG4gICAgICBkZWJ1ZyhUQUcsICdBZGRlZCBpdGVtOiAnLCBpdGVtKTtcbiAgICAgIHRoaXMuaXRlbXMucHVzaChpdGVtKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuaXRlbShpdGVtLmlkKTtcbiAgfVxufVxuXG4vLyBleHBvcnQgZnVuY3Rpb24gbmV3QnVuZGxlQ29uZmlnVG9PbGRCdW5kbGVDb25maWcoYnVuZGxlc0NvbmZpZzogQnVuZGxlQ29uZmlnW10gfCB1bmRlZmluZWQpOiBCdW5kbGVDb25maWdQcmVkZWZpbmVkW10ge1xuLy8gICAgIGlmICghYnVuZGxlc0NvbmZpZykge1xuLy8gICAgICAgICByZXR1cm4gW107XG4vLyAgICAgfVxuLy8gICAgIHJldHVybiBidW5kbGVzQ29uZmlnLm1hcCgoYnVuZGxlQ29uZmlnOiBCdW5kbGVTY2hlbWFDb25maWcpID0+IHtcbi8vICAgICAgICAgY29uc3QgcHJlZGVmaW5lZENvbmZpZzogQnVuZGxlQ29uZmlnUHJlZGVmaW5lZCA9IHtcbi8vICAgICAgICAgICAgIGlkOiBidW5kbGVDb25maWcuaWQsXG4vLyAgICAgICAgICAgICBjb252ZXJ0ZXI6IHVuZGVmaW5lZCxcbi8vICAgICAgICAgICAgIG5hbWU6IGJ1bmRsZUNvbmZpZy5uYW1lIHx8IGBCdW5kbGUgJHtidW5kbGVDb25maWcuaWR9YCxcbi8vICAgICAgICAgICAgIHZhcmlhYmxlczogKGJ1bmRsZUNvbmZpZy52YXJpYWJsZXMgfHwgW10pLm1hcCgodmFyaWFibGVDb25maWc6IE1lbW9yeVZhcmlhYmxlQ29uZmlnKSA9PiB7XG4vLyAgICAgICAgICAgICAgICAgY29uc3QgdmFyaWFibGVUeXBlID0gVmFyaWFibGVUeXBlW3ZhcmlhYmxlQ29uZmlnLnR5cGVdO1xuLy8gICAgICAgICAgICAgICAgIGlmICh2YXJpYWJsZVR5cGUgPT09IHVuZGVmaW5lZCkge1xuLy8gICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgdmFyaWFibGUgdHlwZTogJHt2YXJpYWJsZUNvbmZpZy50eXBlfWApO1xuLy8gICAgICAgICAgICAgICAgIH1cbi8vICAgICAgICAgICAgICAgICBsZXQgY29udmVydGVyOiBCb2R5Q29udmVydGVyPGFueT4gfCB1bmRlZmluZWQ7XG4vLyAgICAgICAgICAgICAgICAgaWYgKHZhcmlhYmxlQ29uZmlnLmNvbnZlcnRlcikge1xuLy8gICAgICAgICAgICAgICAgICAgICBjb252ZXJ0ZXIgPSB2YXJpYWJsZUNvbmZpZy5jb252ZXJ0ZXI7XG4vLyAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbi8vICAgICAgICAgICAgICAgICAgICAgY29udmVydGVyID0gZ2V0Q29udmVydGVyRnJvbUZvcm1hdCh2YXJpYWJsZVR5cGUsIHZhcmlhYmxlQ29uZmlnLmxlbmd0aCB8fCAxKTtcbi8vICAgICAgICAgICAgICAgICB9XG4vLyAgICAgICAgICAgICAgICAgY29uc3QgcHJlZGlmaW5lZFZhcmlhYmxlQ29uZmlnOiBUYXBWYXJpYWJsZS5Db25maWcgPSB7XG4vLyAgICAgICAgICAgICAgICAgICAgIGlkOiB2YXJpYWJsZUNvbmZpZy5pZCxcbi8vICAgICAgICAgICAgICAgICAgICAgY29udmVydGVyOiBjb252ZXJ0ZXIsXG4vLyAgICAgICAgICAgICAgICAgICAgIGxlbmd0aDogdmFyaWFibGVDb25maWcubGVuZ3RoLFxuLy8gICAgICAgICAgICAgICAgICAgICBuYW1lOiB2YXJpYWJsZUNvbmZpZy5uYW1lIHx8IGBWYXJpYWJsZSAke3ZhcmlhYmxlQ29uZmlnLmlkfWAsXG4vLyAgICAgICAgICAgICAgICAgICAgIHR5cGU6IHZhcmlhYmxlVHlwZSxcbi8vICAgICAgICAgICAgICAgICAgICAgdW5pdDogdmFyaWFibGVDb25maWcudW5pdFxuLy8gICAgICAgICAgICAgICAgIH07XG4vLyAgICAgICAgICAgICAgICAgcmV0dXJuIHByZWRpZmluZWRWYXJpYWJsZUNvbmZpZztcbi8vICAgICAgICAgICAgIH0pXG4vLyAgICAgICAgIH07XG4vLyAgICAgICAgIHJldHVybiBwcmVkZWZpbmVkQ29uZmlnO1xuLy8gICAgIH0pO1xuLy8gfVxuXG5leHBvcnQgY2xhc3MgRGF0YU1hbmFnZXJJb25pYzxcbiAgVmFyaWFibGVCeVR5cGUgZXh0ZW5kcyBSZWNvcmQ8c3RyaW5nLCBhbnk+ID0gUmVjb3JkPHN0cmluZywgYW55PixcbiAgVmFyaWFibGVLZXkgZXh0ZW5kcyBzdHJpbmcgPSBzdHJpbmcsXG4gIEJ1bmRsZUJ5VHlwZSBleHRlbmRzIFJlY29yZDxzdHJpbmcsIGFueT4gPSBSZWNvcmQ8c3RyaW5nLCBhbnk+LFxuICBCdW5kbGVLZXkgZXh0ZW5kcyBzdHJpbmcgPSBzdHJpbmdcbj4ge1xuICBjb25zdHJ1Y3RvcihwdWJsaWMgdGFwOiBUYXApIHtcbiAgICAvLyBjb25zdCBhbGxWYXJpYWJsZXM6IEFic3RyYWN0VmFyaWFibGU8VmFyaWFibGVCeVR5cGVbVmFyaWFibGVLZXldPltdID0gT2JqZWN0LnZhbHVlcyhkYXRhLnZhcmlhYmxlcyk7XG4gICAgLy8gdGhpcy50bHZDb252ZXJ0ZXIgPSBuZXcgVGx2QnVuZGxlQ29udmVydGVyKGFsbFZhcmlhYmxlcy5tYXAoKHZhcmlhYmxlOiBBYnN0cmFjdFZhcmlhYmxlPGFueT4pID0+IHtcbiAgICAvLyAgICAgaWYgKCEodmFyaWFibGUgaW5zdGFuY2VvZiBWYXJpYWJsZUNvbmZpZykpIHtcbiAgICAvLyAgICAgICAgIHRocm93IG5ldyBFcnJvcihgVmFyaWFibGUgJHt2YXJpYWJsZS5pZGVudGlmaWVyfSBoYXMgbm8gY29uZmlnYCk7XG4gICAgLy8gICAgIH1cbiAgICAvLyAgICAgcmV0dXJuIHtcbiAgICAvLyAgICAgICAgIGlkOiB2YXJpYWJsZS5jb25maWcuaWQsXG4gICAgLy8gICAgICAgICBuYW1lOiB2YXJpYWJsZS5jb25maWcubmFtZSxcbiAgICAvLyAgICAgICAgIGNvbnZlcnRlcjogdmFyaWFibGUuY29udmVydGVyXG4gICAgLy8gICAgIH07XG4gICAgLy8gfSkpO1xuICAgIC8vIHRoaXMuZGF0YVN0cmVhbSA9IHRoaXMuc2V0dXBEYXRhU3RyZWFtKCk7XG4gICAgLy8gdGhpcy5kYXRhTG9nZ2VyID0gRGF0YUxvZ2dlci5mcm9tVGFwKFxuICAgIC8vICAgICB0aGlzLnRhcCxcbiAgICAvLyAgICAge1xuICAgIC8vICAgICAgICAgcGVyaW9kOiAyMDAwIC8vIFRPRE8gY2hhbmdlXG4gICAgLy8gICAgIH1cbiAgICAvLyApO1xuICAgIC8vIHRoaXMudGFwLnZhcmlhYmxlcy5fdmFyaWFibGVzID0gZGF0YS52YXJpYWJsZXMgYXMgYW55O1xuICAgIC8vIHRoaXMudGFwLmJ1bmRsZXMuX2J1bmRsZXMgPSBkYXRhLmJ1bmRsZXMgYXMgYW55O1xuICAgIC8vIENoYW5nZSB2YXJpYWJsZSBzdHJlYW07XG4gICAgLy8gT2JqZWN0LnZhbHVlcyh0aGlzLmRhdGEudmFyaWFibGVzKS5tYXAoKHZhcmlhYmxlOiBhbnkpID0+IHtcbiAgICAvLyAgICAgY29uc3QgdmFyaWFibGVOYW1lID0gdmFyaWFibGUuY29uZmlnLm5hbWU7XG4gICAgLy8gICAgIC8vIGNvbnNvbGUubG9nKCdSZXBsYWNpbmcgbW9uaXRvciBmb3IgJywgdmFyaWFibGUpO1xuICAgIC8vICAgICB2YXJpYWJsZS5fbW9uaXRvciA9IE9ic2VydmFibGVNb25pdG9yLmZyb21PYnNlcnZhYmxlKFxuICAgIC8vICAgICAgICAgdGhpcy5kYXRhU3RyZWFtXG4gICAgLy8gICAgICAgICAgICAgLnBpcGUoXG4gICAgLy8gICAgICAgICAgICAgICAgIGZpbHRlcihkYXRhID0+IHZhcmlhYmxlTmFtZSBpbiBkYXRhKSxcbiAgICAvLyAgICAgICAgICAgICAgICAgbWFwKGRhdGEgPT4gZGF0YVt2YXJpYWJsZU5hbWVdKSxcbiAgICAvLyAgICAgICAgICAgICAgICAgcnhUYXAodmFsdWUgPT4gZGVidWcoVEFHLCBgRXh0cmFjdGVkIGtleSAke3ZhcmlhYmxlTmFtZX0gZnJvbSBtb25pdG9yaW5nIGRhdGFgLCB2YWx1ZSkpXG4gICAgLy8gICAgICAgICAgICAgKVxuICAgIC8vICAgICAgICAgLFxuICAgIC8vICAgICAgICAgTW9uaXRvckVuZ2luZS5TdGF0ZS5TVEFSVFxuICAgIC8vICAgICApO1xuICAgIC8vIH0pO1xuICAgIC8vIC8vIENoYW5nZSBidW5kbGUgc3RyZWFtO1xuICAgIC8vIE9iamVjdC52YWx1ZXModGhpcy5kYXRhLmJ1bmRsZXMpLm1hcCgoYnVuZGxlOiBhbnkpID0+IHtcbiAgICAvLyAgICAgYnVuZGxlLl9tb25pdG9yID0gT2JzZXJ2YWJsZU1vbml0b3IuZnJvbU9ic2VydmFibGUoXG4gICAgLy8gICAgICAgICB0aGlzLmRhdGFTdHJlYW1cbiAgICAvLyAgICAgICAgICAgICAucGlwZShcbiAgICAvLyAgICAgICAgICAgICAgICAgcnhUYXAodmFsdWUgPT4gZGVidWcoVEFHLCBgTmV3IGJ1bmRsZSB2YWx1ZSBgLCB2YWx1ZSkpXG4gICAgLy8gICAgICAgICAgICAgKVxuICAgIC8vICAgICAgICAgLFxuICAgIC8vICAgICAgICAgTW9uaXRvckVuZ2luZS5TdGF0ZS5TVEFSVFxuICAgIC8vICAgICApO1xuICAgIC8vICAgICAvLyBUT0RPIGZhY3Rvcml6ZSBhbmQgY2xlYW5cbiAgICAvLyAgICAgT2JqZWN0LnZhbHVlcyhidW5kbGUudmFyaWFibGVzKS5tYXAoKHZhcmlhYmxlOiBhbnkpID0+IHtcbiAgICAvLyAgICAgICAgIGNvbnN0IHZhcmlhYmxlTmFtZSA9IHZhcmlhYmxlLmNvbmZpZy5uYW1lO1xuICAgIC8vICAgICAgICAgLy8gY29uc29sZS5sb2coJ1JlcGxhY2luZyBtb25pdG9yIGZvciB2YXJpYWJsZSBpbiBidW5kbGUnLCB2YXJpYWJsZSk7XG4gICAgLy8gICAgICAgICB2YXJpYWJsZS5fbW9uaXRvciA9IE9ic2VydmFibGVNb25pdG9yLmZyb21PYnNlcnZhYmxlKFxuICAgIC8vICAgICAgICAgICAgIHRoaXMuZGF0YVN0cmVhbVxuICAgIC8vICAgICAgICAgICAgICAgICAucGlwZShcbiAgICAvLyAgICAgICAgICAgICAgICAgICAgIGZpbHRlcihkYXRhID0+IHZhcmlhYmxlTmFtZSBpbiBkYXRhKSxcbiAgICAvLyAgICAgICAgICAgICAgICAgICAgIG1hcChkYXRhID0+IGRhdGFbdmFyaWFibGVOYW1lXSksXG4gICAgLy8gICAgICAgICAgICAgICAgICAgICByeFRhcCh2YWx1ZSA9PiBkZWJ1ZyhUQUcsIGBFeHRyYWN0ZWQga2V5ICR7dmFyaWFibGVOYW1lfSBmcm9tIG1vbml0b3JpbmcgZGF0YWAsIHZhbHVlKSlcbiAgICAvLyAgICAgICAgICAgICAgICAgKVxuICAgIC8vICAgICAgICAgICAgICxcbiAgICAvLyAgICAgICAgICAgICBNb25pdG9yRW5naW5lLlN0YXRlLlNUQVJUXG4gICAgLy8gICAgICAgICApO1xuICAgIC8vICAgICB9KTtcbiAgICAvLyB9KTtcbiAgICAvLyBkZWJ1ZyhUQUcsICdOZXcgZGF0YSBtYW5hZ2VyIGluc3RhbmNlOiAnLCB0aGlzKTtcbiAgfVxuXG4gIC8vIGdldCB2YXJpYWJsZXMoKTogUmVjb3JkPFZhcmlhYmxlS2V5LCBBYnN0cmFjdFZhcmlhYmxlPFZhcmlhYmxlQnlUeXBlW1ZhcmlhYmxlS2V5XT4+IHtcbiAgLy8gICAgIHJldHVybiB0aGlzLmRhdGEudmFyaWFibGVzO1xuICAvLyB9XG5cbiAgLy8gZ2V0IGJ1bmRsZXMoKTogUmVjb3JkPEJ1bmRsZUtleSwgQnVuZGxlPEJ1bmRsZUJ5VHlwZVtCdW5kbGVLZXldPj4ge1xuICAvLyAgICAgcmV0dXJuIHRoaXMuZGF0YS5idW5kbGVzO1xuICAvLyB9XG5cbiAgcHVibGljIGdldCBzb3VyY2VDb250cm9sbGVyKCk6IERhdGFTb3VyY2VDb250cm9sbGVyIHtcbiAgICBjb25zdCBjdXJyZW50U291cmNlSWQgPVxuICAgICAgdGhpcy5zd2l0Y2hhYmxlU3RyZWFtQ29udHJvbGxlci5nZXRDdXJyZW50U291cmNlSWQoKTtcbiAgICByZXR1cm4gdGhpcy5zb3VyY2VDb250cm9sbGVyc1tjdXJyZW50U291cmNlSWRdO1xuICB9XG5cbiAgZ2V0IGlzTW9uaXRvcmluZ1J1bm5pbmcoKSB7XG4gICAgZm9yIChjb25zdCB2YWx1ZSBvZiBPYmplY3QudmFsdWVzKHRoaXMuc291cmNlQ29udHJvbGxlcnMpKSB7XG4gICAgICBpZiAodmFsdWUuc3RhdGUgPT0gTW9uaXRvckVuZ2luZS5TdGF0ZS5TVEFSVCkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgc3dpdGNoYWJsZVN0cmVhbUNvbnRyb2xsZXIhOiBTd2l0Y2hhYmxlU3RyZWFtQ29udHJvbGxlcjxhbnk+O1xuICAvLyBkYXRhU3RyZWFtOiBPYnNlcnZhYmxlPFJlY29yZDxzdHJpbmcsIGFueT4+O1xuICAvLyB0bHZDb252ZXJ0ZXI6IFRsdkJ1bmRsZUNvbnZlcnRlcjxSZWNvcmQ8c3RyaW5nLCBVaW50OEFycmF5Pj47XG4gIC8vIGRhdGFMb2dnZXI6IERhdGFMb2dnZXI7XG4gIHNvdXJjZUNvbnRyb2xsZXJzOiBSZWNvcmQ8c3RyaW5nLCBEYXRhU291cmNlQ29udHJvbGxlcj4gPSB7fTtcblxuICAvLyBwdWJsaWMgc3RhdGljIGZyb21TY2hlbWFDb25maWcodGFwOiBUYXAsIHNjaGVtYTogVGFwQ29uZmlndXJhdG9yQ29uZmlnKTogRGF0YU1hbmFnZXJJb25pYyB7XG4gIC8vICAgICBjb25zdCBidW5kbGVzID0gc2NoZW1hLmNvbmZpZy5kYXRhID8gc2NoZW1hLmNvbmZpZy5kYXRhLmJ1bmRsZXMgfHwgW10gOiBbXTtcbiAgLy8gICAgIHJldHVybiBEYXRhTWFuYWdlcklvbmljLmZyb21CdW5kbGVDb25maWcodGFwLCBidW5kbGVzKTtcbiAgLy8gfVxuXG4gIC8vIHB1YmxpYyBzdGF0aWMgZnJvbUJ1bmRsZUNvbmZpZyh0YXA6IFRhcCwgYnVuZGxlczogQnVuZGxlQ29uZmlnW10pOiBEYXRhTWFuYWdlcklvbmljIHtcbiAgLy8gICAgIHJldHVybiBuZXcgRGF0YU1hbmFnZXJJb25pYyhcbiAgLy8gICAgICAgICB0YXAsXG4gIC8vICAgICAgICAgRGF0YU1hbmFnZXJJb25pYy5jcmVhdGVEYXRhRnJvbVNjaGVtYUNvbmZpZyh0YXAsIGJ1bmRsZXMpXG4gIC8vICAgICApO1xuICAvLyB9XG5cbiAgLy8gcHVibGljIHN0YXRpYyBjcmVhdGVEYXRhRnJvbVNjaGVtYUNvbmZpZzxWYXJpYWJsZUJ5VHlwZSBleHRlbmRzIFJlY29yZDxzdHJpbmcsIGFueT4sIFZhcmlhYmxlS2V5IGV4dGVuZHMgc3RyaW5nLCBCdW5kbGVCeVR5cGUgZXh0ZW5kcyBSZWNvcmQ8c3RyaW5nLCBhbnk+LCBCdW5kbGVLZXkgZXh0ZW5kcyBzdHJpbmc+KHRhcDogVGFwLCBidW5kbGVzQ29uZmlnOiBCdW5kbGVTY2hlbWFDb25maWdbXSkge1xuICAvLyAgICAgY29uc3QgcHJlZGlmaW5lZENvbmZpZzogQnVuZGxlQ29uZmlnUHJlZGVmaW5lZFtdID0gbmV3QnVuZGxlQ29uZmlnVG9PbGRCdW5kbGVDb25maWcoYnVuZGxlc0NvbmZpZyk7XG5cbiAgLy8gICAgIHJldHVybiBEYXRhTWFuYWdlcklvbmljLmNyZWF0ZURhdGFGcm9tQ29uZmlnKHRhcCwgcHJlZGlmaW5lZENvbmZpZyk7XG4gIC8vIH1cblxuICAvLyBwdWJsaWMgc3RhdGljIGNyZWF0ZURhdGFGcm9tQ29uZmlnPFZhcmlhYmxlQnlUeXBlIGV4dGVuZHMgUmVjb3JkPHN0cmluZywgYW55PiwgVmFyaWFibGVLZXkgZXh0ZW5kcyBzdHJpbmcsIEJ1bmRsZUJ5VHlwZSBleHRlbmRzIFJlY29yZDxzdHJpbmcsIGFueT4sIEJ1bmRsZUtleSBleHRlbmRzIHN0cmluZz4odGFwOiBUYXAsIGJ1bmRsZXNDb25maWc6IEJ1bmRsZUNvbmZpZ1ByZWRlZmluZWRbXSkge1xuICAvLyAgICAgLy8gbGV0IGJ1bmRsZUNvbmZpZ0NvcHkgPSBbLi4uYnVuZGxlc0NvbmZpZ107XG4gIC8vICAgICBjb25zdCBidW5kbGVzOiBSZWNvcmQ8c3RyaW5nLCBhbnk+ID0ge307XG4gIC8vICAgICBidW5kbGVzQ29uZmlnLmZvckVhY2goKGJ1bmRsZUNvbmZpZzogQnVuZGxlQ29uZmlnUHJlZGVmaW5lZCkgPT4ge1xuICAvLyAgICAgICAgIGNvbnN0IGJ1bmRsZTogQnVuZGxlID0gQnVuZGxlLmNyZWF0ZUZyb21Db25maWcoYnVuZGxlQ29uZmlnLCB0YXAuc2VydmljZS5idW5kbGUsIHRhcC5zZXJ2aWNlLnZhcmlhYmxlKTtcbiAgLy8gICAgICAgICBidW5kbGVzW2J1bmRsZUNvbmZpZy5uYW1lXSA9IGJ1bmRsZTtcbiAgLy8gICAgIH0pO1xuXG4gIC8vICAgICBjb25zdCB2YXJpYWJsZXM6IFJlY29yZDxzdHJpbmcsIGFueT4gPSB7fTtcbiAgLy8gICAgIGJ1bmRsZXNDb25maWcuZm9yRWFjaCgoYnVuZGxlKSA9PiB7XG4gIC8vICAgICAgICAgYnVuZGxlLnZhcmlhYmxlcy5mb3JFYWNoKCh2YXJpYWJsZUNvbmZpZzogVGFwVmFyaWFibGUuQ29uZmlnKSA9PiB7XG4gIC8vICAgICAgICAgICAgIGRlYnVnKFRBRywgJ0NyZWF0ZSBmcm9tIHZhcmlhYmxlIGNvbmZpZzogJywgdmFyaWFibGVDb25maWcpO1xuICAvLyAgICAgICAgICAgICB2YXJpYWJsZXNbdmFyaWFibGVDb25maWcubmFtZSB8fCB2YXJpYWJsZUNvbmZpZy5pZC50b1N0cmluZygpXSA9IFRhcFZhcmlhYmxlLmNyZWF0ZUZyb21Db25maWcodmFyaWFibGVDb25maWcsIHRhcC5zZXJ2aWNlLnZhcmlhYmxlKTtcbiAgLy8gICAgICAgICB9KTtcbiAgLy8gICAgIH0pO1xuXG4gIC8vICAgICByZXR1cm4ge1xuICAvLyAgICAgICAgIGJ1bmRsZXM6IGJ1bmRsZXMgYXMgUmVjb3JkPEJ1bmRsZUtleSwgQnVuZGxlPEJ1bmRsZUJ5VHlwZVtCdW5kbGVLZXldPj4sXG4gIC8vICAgICAgICAgdmFyaWFibGVzOiB2YXJpYWJsZXMgYXMgUmVjb3JkPFZhcmlhYmxlS2V5LCBBYnN0cmFjdFZhcmlhYmxlPFZhcmlhYmxlQnlUeXBlW1ZhcmlhYmxlS2V5XT4+XG4gIC8vICAgICB9O1xuICAvLyB9XG5cbiAgbGlzdFZhcmlhYmxlcygpIHtcbiAgICByZXR1cm4gdGhpcy50YXAuZGF0YS5saXN0VmFyaWFibGVzKCk7XG4gIH1cblxuICBsaXN0QnVuZGxlcygpIHtcbiAgICByZXR1cm4gdGhpcy50YXAuZGF0YS5saXN0QnVuZGxlcygpO1xuICB9XG5cbiAgLy8gcHVibGljIHZhcmlhYmxlPFQgZXh0ZW5kcyBWYXJpYWJsZUtleT4oa2V5OiBUKTogQWJzdHJhY3RWYXJpYWJsZTxWYXJpYWJsZUJ5VHlwZVtUXT4ge1xuICAvLyAgICAgaWYgKCEoa2V5IGluIHRoaXMudmFyaWFibGVzKSkge1xuICAvLyAgICAgICAgIHRocm93IG5ldyBFcnJvcihgVmFyaWFibGUgd2l0aCBpZGVudGlmaWVyIFwiJHtrZXl9XCIgaXMgbm90IGNvbmZpZ3VyZWRgKTtcbiAgLy8gICAgIH1cbiAgLy8gICAgIHJldHVybiB0aGlzLnZhcmlhYmxlc1trZXldIGFzIEFic3RyYWN0VmFyaWFibGU8VmFyaWFibGVCeVR5cGVbVF0+O1xuICAvLyB9XG5cbiAgLy8gcHVibGljIGJ1bmRsZTxUIGV4dGVuZHMgQnVuZGxlS2V5PihrZXk6IFQpOiBCdW5kbGU8QnVuZGxlQnlUeXBlW1RdPiB7XG4gIC8vICAgICBpZiAoIShrZXkgaW4gdGhpcy5idW5kbGVzKSkge1xuICAvLyAgICAgICAgIHRocm93IG5ldyBFcnJvcihgQnVuZGxlIHdpdGggaWRlbnRpZmllciBcIiR7a2V5fVwiIGlzIG5vdCBjb25maWd1cmVkYCk7XG4gIC8vICAgICB9XG4gIC8vICAgICByZXR1cm4gdGhpcy5idW5kbGVzW2tleV0gYXMgYW55O1xuICAvLyB9XG5cbiAgcHVibGljIHN0b3BBbGwoKSB7XG4gICAgZGVidWcoVEFHLCAnU3RvcCBtb25pdG9yaW5nJyk7XG4gICAgLy8gZm9yIChjb25zdCBjdHJsS2V5IGluIHRoaXMuc291cmNlQ29udHJvbGxlcnMpIHtcbiAgICAvLyAgICAgdGhpcy5zb3VyY2VDb250cm9sbGVyc1tjdHJsS2V5XS5zdGF0ZSA9IE1vbml0b3JFbmdpbmUuU3RhdGUuUEFVU0U7XG4gICAgLy8gfVxuICAgIHRoaXMudGFwLmRhdGEubW9uaXRvcmluZy5zdG9wKCk7XG4gIH1cblxuICBwdWJsaWMgc3RhcnRBbGwocGVyaW9kPzogbnVtYmVyKSB7XG4gICAgLy8gZGVidWcoVEFHLCBgW0NvbnRyb2xsZXI9JHt0aGlzLnNvdXJjZUNvbnRyb2xsZXIuaWR9XSBTdGFydCBtb25pdG9yaW5nIHdpdGggcGVyaW9kICR7cGVyaW9kIHx8IHRoaXMuc291cmNlQ29udHJvbGxlci5wZXJpb2QudmFsdWV9YCwgdGhpcy5zb3VyY2VDb250cm9sbGVyKTtcbiAgICAvLyBpZiAocGVyaW9kKSB7XG4gICAgLy8gICAgIHRoaXMuc2V0TW9uaXRvcmluZ1BlcmlvZChwZXJpb2QpO1xuICAgIC8vIH1cbiAgICAvLyB0aGlzLnNvdXJjZUNvbnRyb2xsZXIuc3RhdGUgPSBNb25pdG9yRW5naW5lLlN0YXRlLlNUQVJUO1xuICAgIHRoaXMudGFwLmRhdGEubW9uaXRvcmluZy5zdGFydCgpO1xuICB9XG5cbiAgc2V0TW9uaXRvcmluZ1BlcmlvZChwZXJpb2Q6IG51bWJlcikge1xuICAgIGRlYnVnKFRBRywgJ0NoYW5naW5nIG1vbml0b3JpbmcgcGVyaW9kIHRvICcsIHBlcmlvZCk7XG4gICAgdGhpcy5zb3VyY2VDb250cm9sbGVyLnBlcmlvZC5uZXh0KHBlcmlvZCk7XG4gIH1cblxuICBwdWJsaWMgZGVzdHJveSgpIHtcbiAgICB0aGlzLnN0b3BBbGwoKTtcbiAgfVxuXG4gIHB1YmxpYyByZWZyZXNoKCkge1xuICAgIGlmICh0aGlzLnNvdXJjZUNvbnRyb2xsZXIucmVmcmVzaCkge1xuICAgICAgdGhpcy5zb3VyY2VDb250cm9sbGVyLnJlZnJlc2goKTtcbiAgICB9XG4gIH1cblxuICBjaGFuZ2VEYXRhU291cmNlKGRhdGFTb3VyY2U6IERhdGFTb3VyY2VUeXBlKSB7XG4gICAgc3dpdGNoIChkYXRhU291cmNlKSB7XG4gICAgICBjYXNlICdkYXRhbG9nJzpcbiAgICAgICAgdGhpcy51c2VEYXRhbG9nU291cmNlKCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhpcy51c2VMaXZlU291cmNlKCk7XG4gICAgfVxuICB9XG5cbiAgdXNlTGl2ZVNvdXJjZSgpIHtcbiAgICB0aGlzLnN3aXRjaGFibGVTdHJlYW1Db250cm9sbGVyLnVzZVNvdXJjZSgnbGl2ZScpO1xuICB9XG5cbiAgdXNlRGF0YWxvZ1NvdXJjZSgpIHtcbiAgICB0aGlzLnN3aXRjaGFibGVTdHJlYW1Db250cm9sbGVyLnVzZVNvdXJjZSgnZGF0YWxvZycpO1xuICB9XG5cbiAgLy8gc2V0dXBEYXRhU3RyZWFtKCkge1xuICAvLyAgICAgY29uc3QgbW9uaXRvcmluZ1BlcmlvZCA9IDEwMDA7XG4gIC8vICAgICBkZWJ1ZyhUQUcsICdzZXR1cERhdGFTdHJlYW0nLCBgUGVyaW9kOiAke21vbml0b3JpbmdQZXJpb2R9YCk7XG4gIC8vICAgICB0aGlzLnNvdXJjZUNvbnRyb2xsZXJzWydkYXRhbG9nJ10gPSB7XG4gIC8vICAgICAgICAgc3RhdGU6IE1vbml0b3JFbmdpbmUuU3RhdGUuU1RPUCxcbiAgLy8gICAgICAgICBwZXJpb2Q6IG5ldyBCZWhhdmlvclN1YmplY3QobW9uaXRvcmluZ1BlcmlvZCksXG4gIC8vICAgICAgICAgaWQ6IGBkYXRhbG9nYFxuICAvLyAgICAgfTtcbiAgLy8gICAgIGNvbnN0IGRhdGFsb2dTdHJlYW0gPSBPYnNlcnZhYmxlTW9uaXRvci5jcmVhdGVTdHJlYW1Gcm9tQ2FsbGFibGUoXG4gIC8vICAgICAgICAgKCkgPT4ge1xuICAvLyAgICAgICAgICAgICBkZWJ1ZyhUQUcsICdOZXcgZGF0YSBsb2dnZXIgY2FsbCcpO1xuICAvLyAgICAgICAgICAgICByZXR1cm4gdGhpcy5kYXRhTG9nZ2VyLmRlcXVldWUoKVxuICAvLyAgICAgICAgICAgICAgICAgLnRoZW4oKGluZm8pID0+IHtcbiAgLy8gICAgICAgICAgICAgICAgICAgICBkZWJ1ZyhUQUcsICc9PT0+IE5FVyBQQUNLRVQgREVRVUVVRTogJywgaW5mbyk7XG4gIC8vICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGluZm87XG4gIC8vICAgICAgICAgICAgICAgICB9KVxuICAvLyAgICAgICAgICAgICAgICAgLnRoZW4oaW5mbyA9PiBpbmZvLnBhY2tldC5yYXdWYXJpYWJsZXMpXG4gIC8vICAgICAgICAgICAgICAgICAudGhlbigocmF3VmFyaWFibGVzOiBhbnkpID0+IHtcbiAgLy8gICAgICAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IGlkIG9mIE9iamVjdC5rZXlzKHJhd1ZhcmlhYmxlcykpIHtcbiAgLy8gICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdmFyaWFibGU6IGFueSA9IE9iamVjdC52YWx1ZXModGhpcy52YXJpYWJsZXMpLmZpbmQoKHY6IGFueSkgPT4gdi5jb25maWcuaWQgPT0gaWQpO1xuICAvLyAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodmFyaWFibGUpIHtcbiAgLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJhd1ZhcmlhYmxlc1t2YXJpYWJsZS5jb25maWcubmFtZV0gPSB2YXJpYWJsZS5jb252ZXJ0ZXIuZGVjb2RlKHJhd1ZhcmlhYmxlc1tpZF0pO1xuICAvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlIHJhd1ZhcmlhYmxlc1tpZF07XG4gIC8vICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gIC8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWJ1ZyhUQUcsICdWYXJpYWJsZSB3aXRoIGlkICcsIGlkLCAnIGlzIG5vdCByZWdpc3RlcmVkJyk7XG4gIC8vICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgLy8gICAgICAgICAgICAgICAgICAgICB9XG4gIC8vICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJhd1ZhcmlhYmxlcztcbiAgLy8gICAgICAgICAgICAgICAgIH0pXG4gIC8vICAgICAgICAgICAgICAgICAudGhlbigoaW5mbykgPT4ge1xuICAvLyAgICAgICAgICAgICAgICAgICAgIGRlYnVnKFRBRywgJz09PT4gTkVXIFBBQ0tFVCBJTlRFUlBFUlQ6ICcsIGluZm8pO1xuICAvLyAgICAgICAgICAgICAgICAgICAgIHJldHVybiBpbmZvO1xuICAvLyAgICAgICAgICAgICAgICAgfSk7XG4gIC8vICAgICAgICAgfSxcbiAgLy8gICAgICAgICB7XG4gIC8vICAgICAgICAgICAgIGR1ZVRpbWU6IDAsXG4gIC8vICAgICAgICAgICAgIGlnbm9yZUVycm9yczogdHJ1ZVxuICAvLyAgICAgICAgIH0sXG4gIC8vICAgICAgICAgdGhpcy5zb3VyY2VDb250cm9sbGVyc1snZGF0YWxvZyddXG4gIC8vICAgICApO1xuXG4gIC8vICAgICB0aGlzLnNvdXJjZUNvbnRyb2xsZXJzWydsaXZlJ10gPSB7XG4gIC8vICAgICAgICAgc3RhdGU6IE1vbml0b3JFbmdpbmUuU3RhdGUuU1RPUCxcbiAgLy8gICAgICAgICBwZXJpb2Q6IG5ldyBCZWhhdmlvclN1YmplY3QobW9uaXRvcmluZ1BlcmlvZCksXG4gIC8vICAgICAgICAgaWQ6IGBsaXZlYFxuICAvLyAgICAgfTtcbiAgLy8gICAgIGNvbnN0IGxpdmVQcm9maWxlU3RyZWFtID0gT2JzZXJ2YWJsZU1vbml0b3IuY3JlYXRlU3RyZWFtRnJvbUNhbGxhYmxlPGFueT4oXG4gIC8vICAgICAgICAgYXN5bmMgKHRpbWU6IG51bWJlcikgPT4ge1xuICAvLyAgICAgICAgICAgICBkZWJ1ZyhUQUcsIGBOZXcgY2FsbCAke3RpbWV9IHRvIHJlYWQgcHJvZmlsZWApO1xuICAvLyAgICAgICAgICAgICBjb25zdCBwcm9maWxlRGF0YSA9IChhd2FpdCB0aGlzLnRhcC5zZXJ2aWNlLnZhcmlhYmxlLnJlYWRQcm9maWxlKCkpLmJvZHkoKTtcbiAgLy8gICAgICAgICAgICAgcmV0dXJuIHRoaXMudGx2Q29udmVydGVyLmRlY29kZShwcm9maWxlRGF0YSk7XG4gIC8vICAgICAgICAgfSxcbiAgLy8gICAgICAgICB7XG4gIC8vICAgICAgICAgICAgIGR1ZVRpbWU6IDAsXG4gIC8vICAgICAgICAgICAgIGlnbm9yZUVycm9yczogdHJ1ZVxuICAvLyAgICAgICAgIH0sXG4gIC8vICAgICAgICAgdGhpcy5zb3VyY2VDb250cm9sbGVyc1snbGl2ZSddXG4gIC8vICAgICApO1xuXG4gIC8vICAgICB0aGlzLnN3aXRjaGFibGVTdHJlYW1Db250cm9sbGVyID0gbmV3IFN3aXRjaGFibGVTdHJlYW1Db250cm9sbGVyKFxuICAvLyAgICAgICAgIHtcbiAgLy8gICAgICAgICAgICAgJ2xpdmUnOiB7XG4gIC8vICAgICAgICAgICAgICAgICBpZDogJ2xpdmUnLFxuICAvLyAgICAgICAgICAgICAgICAgc3RyZWFtOiBsaXZlUHJvZmlsZVN0cmVhbVxuICAvLyAgICAgICAgICAgICB9LFxuICAvLyAgICAgICAgICAgICAnZGF0YWxvZyc6IHtcbiAgLy8gICAgICAgICAgICAgICAgIGlkOiAnZGF0YWxvZycsXG4gIC8vICAgICAgICAgICAgICAgICBzdHJlYW06IGRhdGFsb2dTdHJlYW1cbiAgLy8gICAgICAgICAgICAgfVxuICAvLyAgICAgICAgIH0sXG4gIC8vICAgICAgICAgJ2xpdmUnXG4gIC8vICAgICApO1xuXG4gIC8vICAgICByZXR1cm4gdGhpcy5zd2l0Y2hhYmxlU3RyZWFtQ29udHJvbGxlci5hc09ic2VydmFibGUoKTtcbiAgLy8gICAgIC8vIC5waXBlKFxuICAvLyAgICAgLy8gICAgIHJ4VGFwKHZhbHVlcyA9PiB7XG4gIC8vICAgICAvLyAgICAgICAgIGRlYnVnKFRBRywgJyMjIyMjIyMjIyMjIyMjIyMjJywgdmFsdWVzKVxuICAvLyAgICAgLy8gICAgIH0pXG4gIC8vICAgICAvLyApO1xuICAvLyB9XG59XG4iXX0=