ngx-dynamic-hooks
Version:
Automatically insert live Angular components into a dynamic string of content (based on their selector or any pattern of your choice) and render the result in the DOM.
133 lines • 22 kB
JavaScript
/**
* An element parser to load components with their bindings like in Angular templates.
*/
export class ElementSelectorHookParser {
constructor(config, configResolver, platformService, bindingsValueManager) {
this.configResolver = configResolver;
this.platformService = platformService;
this.bindingsValueManager = bindingsValueManager;
this.savedBindings = {};
this.config = this.configResolver.processConfig(config);
this.name = this.config.name;
}
findHookElements(contentElement, context, options) {
return Array.from(this.platformService.querySelectorAll(contentElement, this.config.selector));
}
loadComponent(hookId, hookValue, context, childNodes, options) {
// Always scrub potential []-input- and ()-output-attrs from anchor elements
this.scrubAngularBindingAttrs(hookValue.element);
return {
component: this.config.component,
hostElementTag: this.config.hostElementTag,
injector: this.config.injector,
environmentInjector: this.config.environmentInjector
};
}
getBindings(hookId, hookValue, context, options) {
let hookBindings = this.savedBindings[hookId];
// Parse bindings once from hookValue, then reuse on subsequent runs (raw values will never change as hookValue.element is a snapshot)
if (hookBindings === undefined) {
hookBindings = this.createBindings(hookValue.elementSnapshot);
this.savedBindings[hookId] = hookBindings;
}
// (Re)evaluate if needed
this.bindingsValueManager.checkInputBindings(hookBindings.inputs, context, this.config, options);
this.bindingsValueManager.checkOutputBindings(hookBindings.outputs, this.config, options);
return {
inputs: this.getValuesFromSavedBindings(hookBindings.inputs),
outputs: this.getValuesFromSavedBindings(hookBindings.outputs)
};
}
// Bindings
// --------------------------------------------------------------------------
/**
* Always removes angular-typical template attrs like []-input and ()-outputs from anchors
*
* @param anchorElement - The element to strub
*/
scrubAngularBindingAttrs(anchorElement) {
const attrsToScrub = Array.from(anchorElement.attributes)
.map((attrObj) => attrObj.name)
.filter((attr) => (attr.startsWith('[') && attr.endsWith(']')) ||
(attr.startsWith('(') && attr.endsWith(')')));
for (const attr of attrsToScrub) {
this.platformService.removeAttribute(anchorElement, attr);
}
}
/**
* Returns RichBindingData for Angular-style inputs & output attrs from an element
*
* @param element - The element to inspect
*/
createBindings(element) {
const rawInputs = this.collectRawBindings(element, 'inputs', this.config.inputsBlacklist || null, this.config.inputsWhitelist || null);
const inputBindings = {};
for (const [rawInputKey, rawInputValue] of Object.entries(rawInputs)) {
inputBindings[rawInputKey] = { raw: rawInputValue, parsed: false, value: null, boundContextVariables: {} };
}
const rawOutputs = this.collectRawBindings(element, 'outputs', this.config.outputsBlacklist || null, this.config.outputsWhitelist || null);
const outputBindings = {};
for (const [rawOutputKey, rawOutputValue] of Object.entries(rawOutputs)) {
outputBindings[rawOutputKey] = { raw: rawOutputValue, parsed: false, value: null, boundContextVariables: {} };
}
return {
inputs: inputBindings,
outputs: outputBindings
};
}
/**
* Returns Angular-style inputs or output attrs from an element
*
* @param element - The element to inspect
* @param type - Whether to return the inputs or outputs
* @param blacklist - A list of inputs/outputs to blacklist
* @param whitelist - A list of inputs/outputs to whitelist
*/
collectRawBindings(element, type, blacklist, whitelist) {
const bindings = {};
// Collect raw bindings
const attrNames = this.platformService.getAttributeNames(element);
for (let attrName of attrNames) {
if (type === 'inputs' && (!attrName.startsWith('(') || !attrName.endsWith(')')) ||
type === 'outputs' && (attrName.startsWith('(') && attrName.endsWith(')'))) {
let binding = this.platformService.getAttribute(element, attrName);
// If input has []-brackets: Transform empty attr to undefined
if (type === 'inputs' && attrName.startsWith('[') && attrName.endsWith(']') && binding === '') {
binding = undefined;
}
// If input has no []-brackets: Should be interpreted as plain strings, so wrap in quotes
if (type === 'inputs' && (!attrName.startsWith('[') || !attrName.endsWith(']'))) {
binding = `'${binding}'`;
}
// Trim [] and () brackets from attr name
attrName = attrName.replace(/^\[|^\(|\]$|\)$/g, '');
bindings[attrName] = binding;
}
}
// Filter bindings
const filteredBindings = {};
for (const [bindingName, bindingValue] of Object.entries(bindings)) {
if (blacklist && blacklist.includes(bindingName)) {
continue;
}
if (whitelist && !whitelist.includes(bindingName)) {
continue;
}
filteredBindings[bindingName] = bindingValue;
}
return filteredBindings;
}
/**
* Transforms a RichBindingData object into a normal bindings object
*
* @param richBindingsObject - The object containing the RichBindingData
*/
getValuesFromSavedBindings(richBindingsObject) {
const result = {};
for (const [key, value] of Object.entries(richBindingsObject)) {
result[key] = value.value;
}
return result;
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWxlbWVudFNlbGVjdG9ySG9va1BhcnNlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL25neC1keW5hbWljLWhvb2tzL3NyYy9saWIvcGFyc2Vycy9zZWxlY3Rvci9lbGVtZW50L2VsZW1lbnRTZWxlY3Rvckhvb2tQYXJzZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBUUE7O0dBRUc7QUFDSCxNQUFNLE9BQU8seUJBQXlCO0lBS3BDLFlBQVksTUFBZ0MsRUFBVSxjQUFnRCxFQUFVLGVBQW9DLEVBQVUsb0JBQTBDO1FBQWxKLG1CQUFjLEdBQWQsY0FBYyxDQUFrQztRQUFVLG9CQUFlLEdBQWYsZUFBZSxDQUFxQjtRQUFVLHlCQUFvQixHQUFwQixvQkFBb0IsQ0FBc0I7UUFGeE0sa0JBQWEsR0FBbUMsRUFBRSxDQUFDO1FBR2pELElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQyxhQUFhLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDeEQsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQztJQUMvQixDQUFDO0lBRU0sZ0JBQWdCLENBQUMsY0FBbUIsRUFBRSxPQUFZLEVBQUUsT0FBcUI7UUFDOUUsT0FBTyxLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxlQUFlLENBQUMsZ0JBQWdCLENBQUMsY0FBYyxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsUUFBUyxDQUFDLENBQUMsQ0FBQztJQUNsRyxDQUFDO0lBRU0sYUFBYSxDQUFDLE1BQWMsRUFBRSxTQUFvQixFQUFFLE9BQVksRUFBRSxVQUFpQixFQUFFLE9BQXFCO1FBRS9HLDZFQUE2RTtRQUM3RSxJQUFJLENBQUMsd0JBQXdCLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBRWpELE9BQU87WUFDTCxTQUFTLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxTQUFTO1lB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UUFFRCxPQUFPLGdCQUFnQixDQUFDO0lBQzFCLENBQUM7SUFFRDs7OztPQUlHO0lBQ0ssMEJBQTBCLENBQUMsa0JBQW9EO1FBQ3JGLE1BQU0sTUFBTSxHQUF5QixFQUFFLENBQUM7UUFDeEMsS0FBSyxNQUFNLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQyxJQUFJLE1BQU0sQ0FBQyxPQUFPLENBQUMsa0JBQWtCLENBQUMsRUFBRSxDQUFDO1lBQzlELE1BQU0sQ0FBQyxHQUFHLENBQUMsR0FBRyxLQUFLLENBQUMsS0FBSyxDQUFDO1FBQzVCLENBQUM7UUFDRCxPQUFPLE1BQU0sQ0FBQztJQUNoQixDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBSaWNoQmluZGluZ0RhdGEsIFNhdmVkQmluZGluZ3MgfSBmcm9tICcuLi8uLi8uLi9pbnRlcmZhY2VzJztcbmltcG9ydCB7IEhvb2tQYXJzZXIsIEhvb2tWYWx1ZSwgSG9va0NvbXBvbmVudERhdGEsIEhvb2tCaW5kaW5ncyB9IGZyb20gJy4uLy4uLy4uL2ludGVyZmFjZXNQdWJsaWMnO1xuaW1wb3J0IHsgQmluZGluZ3NWYWx1ZU1hbmFnZXIgfSBmcm9tICcuLi9iaW5kaW5nc1ZhbHVlTWFuYWdlcic7XG5pbXBvcnQgeyBTZWxlY3Rvckhvb2tQYXJzZXJDb25maWcgfSBmcm9tICcuLi9zZWxlY3Rvckhvb2tQYXJzZXJDb25maWcnO1xuaW1wb3J0IHsgU2VsZWN0b3JIb29rUGFyc2VyQ29uZmlnUmVzb2x2ZXIgfSBmcm9tICcuLi9zZWxlY3Rvckhvb2tQYXJzZXJDb25maWdSZXNvbHZlcic7XG5pbXBvcnQgeyBBdXRvUGxhdGZvcm1TZXJ2aWNlIH0gZnJvbSAnLi4vLi4vLi4vc2VydmljZXMvcGxhdGZvcm0vYXV0b1BsYXRmb3JtU2VydmljZSc7XG5pbXBvcnQgeyBQYXJzZU9wdGlvbnMgfSBmcm9tICcuLi8uLi8uLi9zZXJ2aWNlcy9zZXR0aW5ncy9vcHRpb25zJztcblxuLyoqXG4gKiBBbiBlbGVtZW50IHBhcnNlciB0byBsb2FkIGNvbXBvbmVudHMgd2l0aCB0aGVpciBiaW5kaW5ncyBsaWtlIGluIEFuZ3VsYXIgdGVtcGxhdGVzLlxuICovXG5leHBvcnQgY2xhc3MgRWxlbWVudFNlbGVjdG9ySG9va1BhcnNlciBpbXBsZW1lbnRzIEhvb2tQYXJzZXIge1xuICBuYW1lOiBzdHJpbmd8dW5kZWZpbmVkO1xuICBjb25maWc6IFNlbGVjdG9ySG9va1BhcnNlckNvbmZpZztcbiAgc2F2ZWRCaW5kaW5nczoge1trZXk6IG51bWJlcl06IFNhdmVkQmluZGluZ3N9ID0ge307XG5cbiAgY29uc3RydWN0b3IoY29uZmlnOiBTZWxlY3Rvckhvb2tQYXJzZXJDb25maWcsIHByaXZhdGUgY29uZmlnUmVzb2x2ZXI6IFNlbGVjdG9ySG9va1BhcnNlckNvbmZpZ1Jlc29sdmVyLCBwcml2YXRlIHBsYXRmb3JtU2VydmljZTogQXV0b1BsYXRmb3JtU2VydmljZSwgcHJpdmF0ZSBiaW5kaW5nc1ZhbHVlTWFuYWdlcjogQmluZGluZ3NWYWx1ZU1hbmFnZXIpIHtcbiAgICB0aGlzLmNvbmZpZyA9IHRoaXMuY29uZmlnUmVzb2x2ZXIucHJvY2Vzc0NvbmZpZyhjb25maWcpO1xuICAgIHRoaXMubmFtZSA9IHRoaXMuY29uZmlnLm5hbWU7XG4gIH1cblxuICBwdWJsaWMgZmluZEhvb2tFbGVtZW50cyhjb250ZW50RWxlbWVudDogYW55LCBjb250ZXh0OiBhbnksIG9wdGlvbnM6IFBhcnNlT3B0aW9ucyk6IGFueVtdIHtcbiAgICByZXR1cm4gQXJyYXkuZnJvbSh0aGlzLnBsYXRmb3JtU2VydmljZS5xdWVyeVNlbGVjdG9yQWxsKGNvbnRlbnRFbGVtZW50LCB0aGlzLmNvbmZpZy5zZWxlY3RvciEpKTtcbiAgfVxuXG4gIHB1YmxpYyBsb2FkQ29tcG9uZW50KGhvb2tJZDogbnVtYmVyLCBob29rVmFsdWU6IEhvb2tWYWx1ZSwgY29udGV4dDogYW55LCBjaGlsZE5vZGVzOiBhbnlbXSwgb3B0aW9uczogUGFyc2VPcHRpb25zKTogSG9va0NvbXBvbmVudERhdGEge1xuXG4gICAgLy8gQWx3YXlzIHNjcnViIHBvdGVudGlhbCBbXS1pbnB1dC0gYW5kICgpLW91dHB1dC1hdHRycyBmcm9tIGFuY2hvciBlbGVtZW50cyBcbiAgICB0aGlzLnNjcnViQW5ndWxhckJpbmRpbmdBdHRycyhob29rVmFsdWUuZWxlbWVudCk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgY29tcG9uZW50OiB0aGlzLmNvbmZpZy5jb21wb25lbnQsXG4gICAgICBob3N0RWxlbWVudFRhZzogdGhpcy5jb25maWcuaG9zdEVsZW1lbnRUYWcsXG4gICAgICBpbmplY3RvcjogdGhpcy5jb25maWcuaW5qZWN0b3IsXG4gICAgICBlbnZpcm9ubWVudEluamVjdG9yOiB0aGlzLmNvbmZpZy5lbnZpcm9ubWVudEluamVjdG9yXG4gICAgfTtcbiAgfVxuXG4gIHB1YmxpYyBnZXRCaW5kaW5ncyhob29rSWQ6IG51bWJlciwgaG9va1ZhbHVlOiBIb29rVmFsdWUsIGNvbnRleHQ6IGFueSwgb3B0aW9uczogUGFyc2VPcHRpb25zKTogSG9va0JpbmRpbmdzIHtcbiAgICBsZXQgaG9va0JpbmRpbmdzID0gdGhpcy5zYXZlZEJpbmRpbmdzW2hvb2tJZF07XG5cbiAgICAvLyBQYXJzZSBiaW5kaW5ncyBvbmNlIGZyb20gaG9va1ZhbHVlLCB0aGVuIHJldXNlIG9uIHN1YnNlcXVlbnQgcnVucyAocmF3IHZhbHVlcyB3aWxsIG5ldmVyIGNoYW5nZSBhcyBob29rVmFsdWUuZWxlbWVudCBpcyBhIHNuYXBzaG90KVxuICAgIGlmIChob29rQmluZGluZ3MgPT09IHVuZGVmaW5lZCkge1xuICAgICAgaG9va0JpbmRpbmdzID0gdGhpcy5jcmVhdGVCaW5kaW5ncyhob29rVmFsdWUuZWxlbWVudFNuYXBzaG90ISk7XG4gICAgICB0aGlzLnNhdmVkQmluZGluZ3NbaG9va0lkXSA9IGhvb2tCaW5kaW5ncztcbiAgICB9XG5cbiAgICAvLyAoUmUpZXZhbHVhdGUgaWYgbmVlZGVkXG4gICAgdGhpcy5iaW5kaW5nc1ZhbHVlTWFuYWdlci5jaGVja0lucHV0QmluZGluZ3MoaG9va0JpbmRpbmdzLmlucHV0cyEsIGNvbnRleHQsIHRoaXMuY29uZmlnLCBvcHRpb25zKTtcbiAgICB0aGlzLmJpbmRpbmdzVmFsdWVNYW5hZ2VyLmNoZWNrT3V0cHV0QmluZGluZ3MoaG9va0JpbmRpbmdzLm91dHB1dHMhLCB0aGlzLmNvbmZpZywgb3B0aW9ucyk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgaW5wdXRzOiB0aGlzLmdldFZhbHVlc0Zyb21TYXZlZEJpbmRpbmdzKGhvb2tCaW5kaW5ncy5pbnB1dHMhKSxcbiAgICAgIG91dHB1dHM6IHRoaXMuZ2V0VmFsdWVzRnJvbVNhdmVkQmluZGluZ3MoaG9va0JpbmRpbmdzLm91dHB1dHMhKVxuICAgIH07XG4gIH1cblxuICAvLyBCaW5kaW5nc1xuICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG4gIC8qKlxuICAgKiBBbHdheXMgcmVtb3ZlcyBhbmd1bGFyLXR5cGljYWwgdGVtcGxhdGUgYXR0cnMgbGlrZSBbXS1pbnB1dCBhbmQgKCktb3V0cHV0cyBmcm9tIGFuY2hvcnNcbiAgICpcbiAgICogQHBhcmFtIGFuY2hvckVsZW1lbnQgLSBUaGUgZWxlbWVudCB0byBzdHJ1YlxuICAgKi9cbiAgc2NydWJBbmd1bGFyQmluZGluZ0F0dHJzKGFuY2hvckVsZW1lbnQ6IGFueSkge1xuICAgIGNvbnN0IGF0dHJzVG9TY3J1YiA9IEFycmF5LmZyb20oYW5jaG9yRWxlbWVudC5hdHRyaWJ1dGVzKVxuICAgICAgLm1hcCgoYXR0ck9iajogYW55KSA9PiBhdHRyT2JqLm5hbWUpXG4gICAgICAuZmlsdGVyKChhdHRyOiBzdHJpbmcpID0+IFxuICAgICAgICAoYXR0ci5zdGFydHNXaXRoKCdbJykgJiYgYXR0ci5lbmRzV2l0aCgnXScpKSB8fFxuICAgICAgICAoYXR0ci5zdGFydHNXaXRoKCcoJykgJiYgYXR0ci5lbmRzV2l0aCgnKScpKVxuICAgICAgKTtcblxuICAgIGZvciAoY29uc3QgYXR0ciBvZiBhdHRyc1RvU2NydWIpIHtcbiAgICAgIHRoaXMucGxhdGZvcm1TZXJ2aWNlLnJlbW92ZUF0dHJpYnV0ZShhbmNob3JFbGVtZW50LCBhdHRyKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyBSaWNoQmluZGluZ0RhdGEgZm9yIEFuZ3VsYXItc3R5bGUgaW5wdXRzICYgb3V0cHV0IGF0dHJzIGZyb20gYW4gZWxlbWVudFxuICAgKiBcbiAgICogQHBhcmFtIGVsZW1lbnQgLSBUaGUgZWxlbWVudCB0byBpbnNwZWN0XG4gICAqL1xuICBjcmVhdGVCaW5kaW5ncyhlbGVtZW50OiBhbnkpOiBTYXZlZEJpbmRpbmdzIHtcbiAgICBjb25zdCByYXdJbnB1dHMgPSB0aGlzLmNvbGxlY3RSYXdCaW5kaW5ncyhlbGVtZW50ISwgJ2lucHV0cycsIHRoaXMuY29uZmlnLmlucHV0c0JsYWNrbGlzdCB8fCBudWxsLCB0aGlzLmNvbmZpZy5pbnB1dHNXaGl0ZWxpc3QgfHwgbnVsbCk7XG4gICAgY29uc3QgaW5wdXRCaW5kaW5nczoge1trZXk6IHN0cmluZ106IFJpY2hCaW5kaW5nRGF0YX0gPSB7fTtcbiAgICBmb3IgKGNvbnN0IFtyYXdJbnB1dEtleSwgcmF3SW5wdXRWYWx1ZV0gb2YgT2JqZWN0LmVudHJpZXMocmF3SW5wdXRzKSkge1xuICAgICAgaW5wdXRCaW5kaW5nc1tyYXdJbnB1dEtleV0gPSB7cmF3OiByYXdJbnB1dFZhbHVlLCBwYXJzZWQ6IGZhbHNlLCB2YWx1ZTogbnVsbCwgYm91bmRDb250ZXh0VmFyaWFibGVzOiB7fX07XG4gICAgfVxuXG4gICAgY29uc3QgcmF3T3V0cHV0cyA9IHRoaXMuY29sbGVjdFJhd0JpbmRpbmdzKGVsZW1lbnQhLCAnb3V0cHV0cycsIHRoaXMuY29uZmlnLm91dHB1dHNCbGFja2xpc3QgfHwgbnVsbCwgdGhpcy5jb25maWcub3V0cHV0c1doaXRlbGlzdCB8fCBudWxsKTtcbiAgICBjb25zdCBvdXRwdXRCaW5kaW5nczoge1trZXk6IHN0cmluZ106IFJpY2hCaW5kaW5nRGF0YX0gPSB7fTtcbiAgICBmb3IgKGNvbnN0IFtyYXdPdXRwdXRLZXksIHJhd091dHB1dFZhbHVlXSBvZiBPYmplY3QuZW50cmllcyhyYXdPdXRwdXRzKSkge1xuICAgICAgb3V0cHV0QmluZGluZ3NbcmF3T3V0cHV0S2V5XSA9IHtyYXc6IHJhd091dHB1dFZhbHVlLCBwYXJzZWQ6IGZhbHNlLCB2YWx1ZTogbnVsbCwgYm91bmRDb250ZXh0VmFyaWFibGVzOiB7fX07XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIGlucHV0czogaW5wdXRCaW5kaW5ncyxcbiAgICAgIG91dHB1dHM6IG91dHB1dEJpbmRpbmdzXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIEFuZ3VsYXItc3R5bGUgaW5wdXRzIG9yIG91dHB1dCBhdHRycyBmcm9tIGFuIGVsZW1lbnRcbiAgICogXG4gICAqIEBwYXJhbSBlbGVtZW50IC0gVGhlIGVsZW1lbnQgdG8gaW5zcGVjdFxuICAgKiBAcGFyYW0gdHlwZSAtIFdoZXRoZXIgdG8gcmV0dXJuIHRoZSBpbnB1dHMgb3Igb3V0cHV0c1xuICAgKiBAcGFyYW0gYmxhY2tsaXN0IC0gQSBsaXN0IG9mIGlucHV0cy9vdXRwdXRzIHRvIGJsYWNrbGlzdFxuICAgKiBAcGFyYW0gd2hpdGVsaXN0IC0gQSBsaXN0IG9mIGlucHV0cy9vdXRwdXRzIHRvIHdoaXRlbGlzdFxuICAgKi9cbiAgY29sbGVjdFJhd0JpbmRpbmdzIChlbGVtZW50OiBhbnksIHR5cGU6ICdpbnB1dHMnfCdvdXRwdXRzJywgYmxhY2tsaXN0OiBzdHJpbmdbXXxudWxsLCB3aGl0ZWxpc3Q6IHN0cmluZ1tdfG51bGwpOiB7W2tleTogc3RyaW5nXTogYW55fSB7XG4gICAgY29uc3QgYmluZGluZ3M6IHtba2V5OiBzdHJpbmddOiBhbnl9ID0ge307XG5cbiAgICAvLyBDb2xsZWN0IHJhdyBiaW5kaW5nc1xuICAgIGNvbnN0IGF0dHJOYW1lcyA9IHRoaXMucGxhdGZvcm1TZXJ2aWNlLmdldEF0dHJpYnV0ZU5hbWVzKGVsZW1lbnQpO1xuICAgIGZvciAobGV0IGF0dHJOYW1lIG9mIGF0dHJOYW1lcykge1xuICAgICAgaWYgKFxuICAgICAgICB0eXBlID09PSAnaW5wdXRzJyAmJiAoIWF0dHJOYW1lLnN0YXJ0c1dpdGgoJygnKSB8fCAhYXR0ck5hbWUuZW5kc1dpdGgoJyknKSkgfHxcbiAgICAgICAgdHlwZSA9PT0gJ291dHB1dHMnICYmIChhdHRyTmFtZS5zdGFydHNXaXRoKCcoJykgJiYgYXR0ck5hbWUuZW5kc1dpdGgoJyknKSlcbiAgICAgICkge1xuICAgICAgICBsZXQgYmluZGluZzogYW55ID0gdGhpcy5wbGF0Zm9ybVNlcnZpY2UuZ2V0QXR0cmlidXRlKGVsZW1lbnQsIGF0dHJOYW1lKTtcblxuICAgICAgICAvLyBJZiBpbnB1dCBoYXMgW10tYnJhY2tldHM6IFRyYW5zZm9ybSBlbXB0eSBhdHRyIHRvIHVuZGVmaW5lZFxuICAgICAgICBpZiAodHlwZSA9PT0gJ2lucHV0cycgJiYgYXR0ck5hbWUuc3RhcnRzV2l0aCgnWycpICYmIGF0dHJOYW1lLmVuZHNXaXRoKCddJykgJiYgYmluZGluZyA9PT0gJycpIHtcbiAgICAgICAgICBiaW5kaW5nID0gdW5kZWZpbmVkO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gSWYgaW5wdXQgaGFzIG5vIFtdLWJyYWNrZXRzOiBTaG91bGQgYmUgaW50ZXJwcmV0ZWQgYXMgcGxhaW4gc3RyaW5ncywgc28gd3JhcCBpbiBxdW90ZXNcbiAgICAgICAgaWYgKHR5cGUgPT09ICdpbnB1dHMnICYmICghYXR0ck5hbWUuc3RhcnRzV2l0aCgnWycpIHx8ICFhdHRyTmFtZS5lbmRzV2l0aCgnXScpKSkge1xuICAgICAgICAgIGJpbmRpbmcgPSBgJyR7YmluZGluZ30nYDtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFRyaW0gW10gYW5kICgpIGJyYWNrZXRzIGZyb20gYXR0ciBuYW1lXG4gICAgICAgIGF0dHJOYW1lID0gYXR0ck5hbWUucmVwbGFjZSgvXlxcW3xeXFwofFxcXSR8XFwpJC9nLCAnJyk7XG5cbiAgICAgICAgYmluZGluZ3NbYXR0ck5hbWVdID0gYmluZGluZztcbiAgICAgIH1cbiAgICB9XG4gICAgXG4gICAgLy8gRmlsdGVyIGJpbmRpbmdzXG4gICAgY29uc3QgZmlsdGVyZWRCaW5kaW5nczoge1trZXk6IHN0cmluZ106IGFueX0gPSB7fTtcbiAgICBmb3IgKGNvbnN0IFtiaW5kaW5nTmFtZSwgYmluZGluZ1ZhbHVlXSBvZiBPYmplY3QuZW50cmllcyhiaW5kaW5ncykpIHtcbiAgICAgIGlmIChibGFja2xpc3QgJiYgYmxhY2tsaXN0LmluY2x1ZGVzKGJpbmRpbmdOYW1lKSkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIGlmICh3aGl0ZWxpc3QgJiYgIXdoaXRlbGlzdC5pbmNsdWRlcyhiaW5kaW5nTmFtZSkpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBmaWx0ZXJlZEJpbmRpbmdzW2JpbmRpbmdOYW1lXSA9IGJpbmRpbmdWYWx1ZTtcbiAgICB9XG5cbiAgICByZXR1cm4gZmlsdGVyZWRCaW5kaW5ncztcbiAgfVxuXG4gIC8qKlxuICAgKiBUcmFuc2Zvcm1zIGEgUmljaEJpbmRpbmdEYXRhIG9iamVjdCBpbnRvIGEgbm9ybWFsIGJpbmRpbmdzIG9iamVjdFxuICAgKlxuICAgKiBAcGFyYW0gcmljaEJpbmRpbmdzT2JqZWN0IC0gVGhlIG9iamVjdCBjb250YWluaW5nIHRoZSBSaWNoQmluZGluZ0RhdGFcbiAgICovXG4gIHByaXZhdGUgZ2V0VmFsdWVzRnJvbVNhdmVkQmluZGluZ3MocmljaEJpbmRpbmdzT2JqZWN0OiB7W2tleTogc3RyaW5nXTogUmljaEJpbmRpbmdEYXRhfSk6IHtba2V5OiBzdHJpbmddOiBhbnl9IHtcbiAgICBjb25zdCByZXN1bHQ6IHtba2V5OiBzdHJpbmddOiBhbnl9ID0ge307XG4gICAgZm9yIChjb25zdCBba2V5LCB2YWx1ZV0gb2YgT2JqZWN0LmVudHJpZXMocmljaEJpbmRpbmdzT2JqZWN0KSkge1xuICAgICAgcmVzdWx0W2tleV0gPSB2YWx1ZS52YWx1ZTtcbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxufVxuIl19