UNPKG

@aws-cdk/core

Version:

AWS Cloud Development Kit Core Library

223 lines 26.6 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const cfn_resource_1 = require("./cfn-resource"); /** * Standard tags are a list of { key, value } objects */ class StandardFormatter { parseTags(cfnPropertyTags, priority) { if (!Array.isArray(cfnPropertyTags)) { throw new Error(`Invalid tag input expected array of {key, value} have ${JSON.stringify(cfnPropertyTags)}`); } const tags = []; for (const tag of cfnPropertyTags) { if (tag.key === undefined || tag.value === undefined) { throw new Error(`Invalid tag input expected {key, value} have ${JSON.stringify(tag)}`); } // using interp to ensure Token is now string tags.push({ key: `${tag.key}`, value: `${tag.value}`, priority }); } return tags; } formatTags(tags) { const cfnTags = []; for (const tag of tags) { cfnTags.push({ key: tag.key, value: tag.value }); } return cfnTags.length === 0 ? undefined : cfnTags; } } /** * ASG tags are a list of { key, value, propagateAtLaunch } objects */ class AsgFormatter { parseTags(cfnPropertyTags, priority) { const tags = []; if (!Array.isArray(cfnPropertyTags)) { throw new Error(`Invalid tag input expected array of {key, value, propagateAtLaunch} have ${JSON.stringify(cfnPropertyTags)}`); } for (const tag of cfnPropertyTags) { if (tag.key === undefined || tag.value === undefined || tag.propagateAtLaunch === undefined) { throw new Error(`Invalid tag input expected {key, value, propagateAtLaunch} have ${JSON.stringify(tag)}`); } // using interp to ensure Token is now string tags.push({ key: `${tag.key}`, value: `${tag.value}`, priority, applyToLaunchedInstances: !!tag.propagateAtLaunch }); } return tags; } formatTags(tags) { const cfnTags = []; for (const tag of tags) { cfnTags.push({ key: tag.key, value: tag.value, propagateAtLaunch: tag.applyToLaunchedInstances !== false, }); } return cfnTags.length === 0 ? undefined : cfnTags; } } /** * Some CloudFormation constructs use a { key: value } map for tags */ class MapFormatter { parseTags(cfnPropertyTags, priority) { const tags = []; if (Array.isArray(cfnPropertyTags) || typeof (cfnPropertyTags) !== 'object') { throw new Error(`Invalid tag input expected map of {key: value} have ${JSON.stringify(cfnPropertyTags)}`); } for (const [key, value] of Object.entries(cfnPropertyTags)) { tags.push({ key, value: `${value}`, priority }); } return tags; } formatTags(tags) { const cfnTags = {}; for (const tag of tags) { cfnTags[`${tag.key}`] = `${tag.value}`; } return Object.keys(cfnTags).length === 0 ? undefined : cfnTags; } } /** * StackTags are of the format { Key: key, Value: value } */ class KeyValueFormatter { parseTags(keyValueTags, priority) { const tags = []; for (const key in keyValueTags) { if (keyValueTags.hasOwnProperty(key)) { const value = keyValueTags[key]; tags.push({ key, value, priority }); } } return tags; } formatTags(unformattedTags) { const tags = []; unformattedTags.forEach(tag => { tags.push({ Key: tag.key, Value: tag.value }); }); return tags; } } class NoFormat { parseTags(_cfnPropertyTags) { return []; } formatTags(_tags) { return undefined; } } const TAG_FORMATTERS = { [cfn_resource_1.TagType.AUTOSCALING_GROUP]: new AsgFormatter(), [cfn_resource_1.TagType.STANDARD]: new StandardFormatter(), [cfn_resource_1.TagType.MAP]: new MapFormatter(), [cfn_resource_1.TagType.KEY_VALUE]: new KeyValueFormatter(), [cfn_resource_1.TagType.NOT_TAGGABLE]: new NoFormat(), }; /** * TagManager facilitates a common implementation of tagging for Constructs. */ class TagManager { constructor(tagType, resourceTypeName, tagStructure, options = {}) { this.tags = new Map(); this.priorities = new Map(); this.initialTagPriority = 50; this.resourceTypeName = resourceTypeName; this.tagFormatter = TAG_FORMATTERS[tagType]; if (tagStructure !== undefined) { this._setTag(...this.tagFormatter.parseTags(tagStructure, this.initialTagPriority)); } this.tagPropertyName = options.tagPropertyName || 'tags'; } /** * Check whether the given construct is Taggable */ static isTaggable(construct) { return construct.tags !== undefined; } /** * Adds the specified tag to the array of tags * */ setTag(key, value, priority = 0, applyToLaunchedInstances = true) { // This method mostly exists because we don't want to expose the 'Tag' type used (it will be confusing // to users). this._setTag({ key, value, priority, applyToLaunchedInstances }); } /** * Removes the specified tag from the array if it exists * * @param key The tag to remove * @param priority The priority of the remove operation */ removeTag(key, priority) { if (priority >= (this.priorities.get(key) || 0)) { this.tags.delete(key); this.priorities.set(key, priority); } } /** * Renders tags into the proper format based on TagType */ renderTags() { return this.tagFormatter.formatTags(Array.from(this.tags.values())); } /** * Determine if the aspect applies here * * Looks at the include and exclude resourceTypeName arrays to determine if * the aspect applies here */ applyTagAspectHere(include, exclude) { if (exclude && exclude.length > 0 && exclude.indexOf(this.resourceTypeName) !== -1) { return false; } if (include && include.length > 0 && include.indexOf(this.resourceTypeName) === -1) { return false; } return true; } /** * Returns true if there are any tags defined */ hasTags() { return this.tags.size > 0; } _setTag(...tags) { for (const tag of tags) { if (tag.priority >= (this.priorities.get(tag.key) || 0)) { this.tags.set(tag.key, tag); this.priorities.set(tag.key, tag.priority); } } } } exports.TagManager = TagManager; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFnLW1hbmFnZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJ0YWctbWFuYWdlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLGlEQUF5QztBQXlDekM7O0dBRUc7QUFDSCxNQUFNLGlCQUFpQjtJQUNkLFNBQVMsQ0FBQyxlQUFvQixFQUFFLFFBQWdCO1FBQ3JELElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLGVBQWUsQ0FBQyxFQUFFO1lBQ25DLE1BQU0sSUFBSSxLQUFLLENBQUMseURBQXlELElBQUksQ0FBQyxTQUFTLENBQUMsZUFBZSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1NBQzdHO1FBRUQsTUFBTSxJQUFJLEdBQVUsRUFBRSxDQUFDO1FBQ3ZCLEtBQUssTUFBTSxHQUFHLElBQUksZUFBZSxFQUFFO1lBQ2pDLElBQUksR0FBRyxDQUFDLEdBQUcsS0FBSyxTQUFTLElBQUksR0FBRyxDQUFDLEtBQUssS0FBSyxTQUFTLEVBQUU7Z0JBQ3BELE1BQU0sSUFBSSxLQUFLLENBQUMsZ0RBQWdELElBQUksQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDO2FBQ3hGO1lBQ0QsNkNBQTZDO1lBQzdDLElBQUksQ0FBQyxJQUFJLENBQUM7Z0JBQ1IsR0FBRyxFQUFFLEdBQUcsR0FBRyxDQUFDLEdBQUcsRUFBRTtnQkFDakIsS0FBSyxFQUFFLEdBQUcsR0FBRyxDQUFDLEtBQUssRUFBRTtnQkFDckIsUUFBUTthQUNULENBQUMsQ0FBQztTQUNKO1FBQ0QsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRU0sVUFBVSxDQUFDLElBQVc7UUFDM0IsTUFBTSxPQUFPLEdBQWEsRUFBRSxDQUFDO1FBQzdCLEtBQUssTUFBTSxHQUFHLElBQUksSUFBSSxFQUFFO1lBQ3RCLE9BQU8sQ0FBQyxJQUFJLENBQUM7Z0JBQ1gsR0FBRyxFQUFFLEdBQUcsQ0FBQyxHQUFHO2dCQUNaLEtBQUssRUFBRSxHQUFHLENBQUMsS0FBSzthQUNq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QUFDO0lBQzVCLENBQUM7SUFFTyxPQUFPLENBQUMsR0FBRyxJQUFXO1FBQzVCLEtBQUssTUFBTSxHQUFHLElBQUksSUFBSSxFQUFFO1lBQ3RCLElBQUksR0FBRyxDQUFDLFFBQVEsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUMsRUFBRTtnQkFDdkQsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxHQUFHLENBQUMsQ0FBQztnQkFDNUIsSUFBSSxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxHQUFHLENBQUMsUUFBUSxDQUFDLENBQUM7YUFDNUM7U0FDRjtJQUNILENBQUM7Q0FDRjtBQTlGRCxnQ0E4RkMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBUYWdUeXBlIH0gZnJvbSAnLi9jZm4tcmVzb3VyY2UnO1xuaW1wb3J0IHsgQ2ZuVGFnIH0gZnJvbSAnLi9jZm4tdGFnJztcblxuaW50ZXJmYWNlIFRhZyB7XG4gIGtleTogc3RyaW5nO1xuICB2YWx1ZTogc3RyaW5nO1xuICBwcmlvcml0eTogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBAZGVmYXVsdCB0cnVlXG4gICAqL1xuICBhcHBseVRvTGF1bmNoZWRJbnN0YW5jZXM/OiBib29sZWFuO1xufVxuXG5pbnRlcmZhY2UgQ2ZuQXNnVGFnIHtcbiAga2V5OiBzdHJpbmc7XG4gIHZhbHVlOiBzdHJpbmc7XG4gIHByb3BhZ2F0ZUF0TGF1bmNoOiBib29sZWFuO1xufVxuXG5pbnRlcmZhY2UgU3RhY2tUYWcge1xuICBLZXk6IHN0cmluZztcbiAgVmFsdWU6IHN0cmluZztcbn1cbi8qKlxuICogSW50ZXJmYWNlIGZvciBjb252ZXJ0ZXIgYmV0d2VlbiBDbG91ZEZvcm1hdGlvbiBhbmQgaW50ZXJuYWwgdGFnIHJlcHJlc2VudGF0aW9uc1xuICovXG5pbnRlcmZhY2UgSVRhZ0Zvcm1hdHRlciB7XG4gIC8qKlxuICAgKiBGb3JtYXQgdGhlIGdpdmVuIHRhZ3MgYXMgQ2xvdWRGb3JtYXRpb24gdGFnc1xuICAgKi9cbiAgZm9ybWF0VGFncyh0YWdzOiBUYWdbXSk6IGFueTtcblxuICAvKipcbiAgICogUGFyc2UgdGhlIENsb3VkRm9ybWF0aW9uIHRhZyByZXByZXNlbnRhdGlvbiBpbnRvIGludGVybmFsIHJlcHJlc2VudGF0aW9uXG4gICAqXG4gICAqIFVzZSB0aGUgZ2l2ZW4gcHJpb3JpdHkuXG4gICAqL1xuICBwYXJzZVRhZ3MoY2ZuUHJvcGVydHlUYWdzOiBhbnksIHByaW9yaXR5OiBudW1iZXIpOiBUYWdbXTtcbn1cblxuLyoqXG4gKiBTdGFuZGFyZCB0YWdzIGFyZSBhIGxpc3Qgb2YgeyBrZXksIHZhbHVlIH0gb2JqZWN0c1xuICovXG5jbGFzcyBTdGFuZGFyZEZvcm1hdHRlciBpbXBsZW1lbnRzIElUYWdGb3JtYXR0ZXIge1xuICBwdWJsaWMgcGFyc2VUYWdzKGNmblByb3BlcnR5VGFnczogYW55LCBwcmlvcml0eTogbnVtYmVyKTogVGFnW10ge1xuICAgIGlmICghQXJyYXkuaXNBcnJheShjZm5Qcm9wZXJ0eVRhZ3MpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgdGFnIGlucHV0IGV4cGVjdGVkIGFycmF5IG9mIHtrZXksIHZhbHVlfSBoYXZlICR7SlNPTi5zdHJpbmdpZnkoY2ZuUHJvcGVydHlUYWdzKX1gKTtcbiAgICB9XG5cbiAgICBjb25zdCB0YWdzOiBUYWdbXSA9IFtdO1xuICAgIGZvciAoY29uc3QgdGFnIG9mIGNmblByb3BlcnR5VGFncykge1xuICAgICAgaWYgKHRhZy5rZXkgPT09IHVuZGVmaW5lZCB8fCB0YWcudmFsdWUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgdGFnIGlucHV0IGV4cGVjdGVkIHtrZXksIHZhbHVlfSBoYXZlICR7SlNPTi5zdHJpbmdpZnkodGFnKX1gKTtcbiAgICAgIH1cbiAgICAgIC8vIHVzaW5nIGludGVycCB0byBlbnN1cmUgVG9rZW4gaXMgbm93IHN0cmluZ1xuICAgICAgdGFncy5wdXNoKHtcbiAgICAgICAga2V5OiBgJHt0YWcua2V5fWAsXG4gICAgICAgIHZhbHVlOiBgJHt0YWcudmFsdWV9YCxcbiAgICAgICAgcHJpb3JpdHlcbiAgICAgIH0pO1xuICAgIH1cbiAgICByZXR1cm4gdGFncztcbiAgfVxuXG4gIHB1YmxpYyBmb3JtYXRUYWdzKHRhZ3M6IFRhZ1tdKTogYW55IHtcbiAgICBjb25zdCBjZm5UYWdzOiBDZm5UYWdbXSA9IFtdO1xuICAgIGZvciAoY29uc3QgdGFnIG9mIHRhZ3MpIHtcbiAgICAgIGNmblRhZ3MucHVzaCh7XG4gICAgICAgIGtleTogdGFnLmtleSxcbiAgICAgICAgdmFsdWU6IHRhZy52YWx1ZVxuICAgICAgfSk7XG4gICAgfVxuICAgIHJldHVybiBjZm5UYWdzLmxlbmd0aCA9PT0gMCA/IHVuZGVmaW5lZCA6IGNmblRhZ3M7XG4gIH1cbn1cblxuLyoqXG4gKiBBU0cgdGFncyBhcmUgYSBsaXN0IG9mIHsga2V5LCB2YWx1ZSwgcHJvcGFnYXRlQXRMYXVuY2ggfSBvYmplY3RzXG4gKi9cbmNsYXNzIEFzZ0Zvcm1hdHRlciBpbXBsZW1lbnRzIElUYWdGb3JtYXR0ZXIge1xuICBwdWJsaWMgcGFyc2VUYWdzKGNmblByb3BlcnR5VGFnczogYW55LCBwcmlvcml0eTogbnVtYmVyKTogVGFnW10ge1xuICAgIGNvbnN0IHRhZ3M6IFRhZ1tdID0gW107XG4gICAgaWYgKCFBcnJheS5pc0FycmF5KGNmblByb3BlcnR5VGFncykpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCB0YWcgaW5wdXQgZXhwZWN0ZWQgYXJyYXkgb2Yge2tleSwgdmFsdWUsIHByb3BhZ2F0ZUF0TGF1bmNofSBoYXZlICR7SlNPTi5zdHJpbmdpZnkoY2ZuUHJvcGVydHlUYWdzKX1gKTtcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IHRhZyBvZiBjZm5Qcm9wZXJ0eVRhZ3MpIHtcbiAgICAgIGlmICh0YWcua2V5ID09PSB1bmRlZmluZWQgfHxcbiAgICAgICAgdGFnLnZhbHVlID09PSB1bmRlZmluZWQgfHxcbiAgICAgICAgdGFnLnByb3BhZ2F0ZUF0TGF1bmNoID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBJbnZhbGlkIHRhZyBpbnB1dCBleHBlY3RlZCB7a2V5LCB2YWx1ZSwgcHJvcGFnYXRlQXRMYXVuY2h9IGhhdmUgJHtKU09OLnN0cmluZ2lmeSh0YWcpfWApO1xuICAgICAgfVxuICAgICAgLy8gdXNpbmcgaW50ZXJwIHRvIGVuc3VyZSBUb2tlbiBpcyBub3cgc3RyaW5nXG4gICAgICB0YWdzLnB1c2goe1xuICAgICAgICBrZXk6IGAke3RhZy5rZXl9YCxcbiAgICAgICAgdmFsdWU6IGAke3RhZy52YWx1ZX1gLFxuICAgICAgICBwcmlvcml0eSxcbiAgICAgICAgYXBwbHlUb0xhdW5jaGVkSW5zdGFuY2VzOiAhIXRhZy5wcm9wYWdhdGVBdExhdW5jaFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRhZ3M7XG4gIH1cblxuICBwdWJsaWMgZm9ybWF0VGFncyh0YWdzOiBUYWdbXSk6IGFueSB7XG4gICAgY29uc3QgY2ZuVGFnczogQ2ZuQXNnVGFnW10gPSBbXTtcbiAgICBmb3IgKGNvbnN0IHRhZyBvZiB0YWdzKSB7XG4gICAgICBjZm5UYWdzLnB1c2goe1xuICAgICAgICBrZXk6IHRhZy5rZXksXG4gICAgICAgIHZhbHVlOiB0YWcudmFsdWUsXG4gICAgICAgIHByb3BhZ2F0ZUF0TGF1bmNoOiB0YWcuYXBwbHlUb0xhdW5jaGVkSW5zdGFuY2VzICE9PSBmYWxzZSxcbiAgICAgIH0pO1xuICAgIH1cbiAgICByZXR1cm4gY2ZuVGFncy5sZW5ndGggPT09IDAgPyB1bmRlZmluZWQgOiBjZm5UYWdzO1xuICB9XG59XG5cbi8qKlxuICogU29tZSBDbG91ZEZvcm1hdGlvbiBjb25zdHJ1Y3RzIHVzZSBhIHsga2V5OiB2YWx1ZSB9IG1hcCBmb3IgdGFnc1xuICovXG5jbGFzcyBNYXBGb3JtYXR0ZXIgaW1wbGVtZW50cyBJVGFnRm9ybWF0dGVyIHtcbiAgcHVibGljIHBhcnNlVGFncyhjZm5Qcm9wZXJ0eVRhZ3M6IGFueSwgcHJpb3JpdHk6IG51bWJlcik6IFRhZ1tdIHtcbiAgICBjb25zdCB0YWdzOiBUYWdbXSA9IFtdO1xuICAgIGlmIChBcnJheS5pc0FycmF5KGNmblByb3BlcnR5VGFncykgfHwgdHlwZW9mKGNmblByb3BlcnR5VGFncykgIT09ICdvYmplY3QnKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgdGFnIGlucHV0IGV4cGVjdGVkIG1hcCBvZiB7a2V5OiB2YWx1ZX0gaGF2ZSAke0pTT04uc3RyaW5naWZ5KGNmblByb3BlcnR5VGFncyl9YCk7XG4gICAgfVxuXG4gICAgZm9yIChjb25zdCBba2V5LCB2YWx1ZV0gb2YgT2JqZWN0LmVudHJpZXMoY2ZuUHJvcGVydHlUYWdzKSkge1xuICAgICAgdGFncy5wdXNoKHtcbiAgICAgICAga2V5LFxuICAgICAgICB2YWx1ZTogYCR7dmFsdWV9YCxcbiAgICAgICAgcHJpb3JpdHlcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHJldHVybiB0YWdzO1xuICB9XG5cbiAgcHVibGljIGZvcm1hdFRhZ3ModGFnczogVGFnW10pOiBhbnkge1xuICAgIGNvbnN0IGNmblRhZ3M6IHtba2V5OiBzdHJpbmddOiBzdHJpbmd9ID0ge307XG4gICAgZm9yIChjb25zdCB0YWcgb2YgdGFncykge1xuICAgICAgY2ZuVGFnc1tgJHt0YWcua2V5fWBdID0gYCR7dGFnLnZhbHVlfWA7XG4gICAgfVxuICAgIHJldHVybiBPYmplY3Qua2V5cyhjZm5UYWdzKS5sZW5ndGggPT09IDAgPyB1bmRlZmluZWQgOiBjZm5UYWdzO1xuICB9XG59XG5cbi8qKlxuICogU3RhY2tUYWdzIGFyZSBvZiB0aGUgZm9ybWF0IHsgS2V5OiBrZXksIFZhbHVlOiB2YWx1ZSB9XG4gKi9cbmNsYXNzIEtleVZhbHVlRm9ybWF0dGVyIGltcGxlbWVudHMgSVRhZ0Zvcm1hdHRlciB7XG4gIHB1YmxpYyBwYXJzZVRhZ3Moa2V5VmFsdWVUYWdzOiBhbnksIHByaW9yaXR5OiBudW1iZXIpOiBUYWdbXSB7XG4gICAgY29uc3QgdGFnczogVGFnW10gPSBbXTtcbiAgICBmb3IgKGNvbnN0IGtleSBpbiBrZXlWYWx1ZVRhZ3MpIHtcbiAgICAgIGlmIChrZXlWYWx1ZVRhZ3MuaGFzT3duUHJvcGVydHkoa2V5KSkge1xuICAgICAgICBjb25zdCB2YWx1ZSA9IGtleVZhbHVlVGFnc1trZXldO1xuICAgICAgICB0YWdzLnB1c2goe1xuICAgICAgICAgIGtleSxcbiAgICAgICAgICB2YWx1ZSxcbiAgICAgICAgICBwcmlvcml0eVxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHRhZ3M7XG4gIH1cbiAgcHVibGljIGZvcm1hdFRhZ3ModW5mb3JtYXR0ZWRUYWdzOiBUYWdbXSk6IGFueSB7XG4gICAgY29uc3QgdGFnczogU3RhY2tUYWdbXSA9IFtdO1xuICAgIHVuZm9ybWF0dGVkVGFncy5mb3JFYWNoKHRhZyA9PiB7XG4gICAgICB0YWdzLnB1c2goe1xuICAgICAgICBLZXk6IHRhZy5rZXksXG4gICAgICAgIFZhbHVlOiB0YWcudmFsdWVcbiAgICAgIH0pO1xuICAgIH0pO1xuICAgIHJldHVybiB0YWdzO1xuICB9XG59XG5cbmNsYXNzIE5vRm9ybWF0IGltcGxlbWVudHMgSVRhZ0Zvcm1hdHRlciB7XG4gIHB1YmxpYyBwYXJzZVRhZ3MoX2NmblByb3BlcnR5VGFnczogYW55KTogVGFnW10ge1xuICAgIHJldHVybiBbXTtcbiAgfVxuICBwdWJsaWMgZm9ybWF0VGFncyhfdGFnczogVGFnW10pOiBhbnkge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbn1cblxuY29uc3QgVEFHX0ZPUk1BVFRFUlM6IHtba2V5OiBzdHJpbmddOiBJVGFnRm9ybWF0dGVyfSA9IHtcbiAgW1RhZ1R5cGUuQVVUT1NDQUxJTkdfR1JPVVBdOiBuZXcgQXNnRm9ybWF0dGVyKCksXG4gIFtUYWdUeXBlLlNUQU5EQVJEXTogbmV3IFN0YW5kYXJkRm9ybWF0dGVyKCksXG4gIFtUYWdUeXBlLk1BUF06IG5ldyBNYXBGb3JtYXR0ZXIoKSxcbiAgW1RhZ1R5cGUuS0VZX1ZBTFVFXTogbmV3IEtleVZhbHVlRm9ybWF0dGVyKCksXG4gIFtUYWdUeXBlLk5PVF9UQUdHQUJMRV06IG5ldyBOb0Zvcm1hdCgpLFxufTtcblxuLyoqXG4gKiBJbnRlcmZhY2UgdG8gaW1wbGVtZW50IHRhZ3MuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgSVRhZ2dhYmxlIHtcbiAgLyoqXG4gICAqIFRhZ01hbmFnZXIgdG8gc2V0LCByZW1vdmUgYW5kIGZvcm1hdCB0YWdzXG4gICAqL1xuICByZWFkb25seSB0YWdzOiBUYWdNYW5hZ2VyO1xufVxuXG4vKipcbiAqIE9wdGlvbnMgdG8gY29uZmlndXJlIFRhZ01hbmFnZXIgYmVoYXZpb3JcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBUYWdNYW5hZ2VyT3B0aW9ucyB7XG4gIC8qKlxuICAgKiBUaGUgbmFtZSBvZiB0aGUgcHJvcGVydHkgaW4gQ2xvdWRGb3JtYXRpb24gZm9yIHRoZXNlIHRhZ3NcbiAgICpcbiAgICogTm9ybWFsbHkgdGhpcyBpcyBgdGFnc2AsIGJ1dCBDb2duaXRvIFVzZXJQb29sIHVzZXMgVXNlclBvb2xUYWdzXG4gICAqXG4gICAqIEBkZWZhdWx0IFwidGFnc1wiXG4gICAqL1xuICByZWFkb25seSB0YWdQcm9wZXJ0eU5hbWU/OiBzdHJpbmc7XG59XG5cbi8qKlxuICogVGFnTWFuYWdlciBmYWNpbGl0YXRlcyBhIGNvbW1vbiBpbXBsZW1lbnRhdGlvbiBvZiB0YWdnaW5nIGZvciBDb25zdHJ1Y3RzLlxuICovXG5leHBvcnQgY2xhc3MgVGFnTWFuYWdlciB7XG5cbiAgLyoqXG4gICAqIENoZWNrIHdoZXRoZXIgdGhlIGdpdmVuIGNvbnN0cnVjdCBpcyBUYWdnYWJsZVxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBpc1RhZ2dhYmxlKGNvbnN0cnVjdDogYW55KTogY29uc3RydWN0IGlzIElUYWdnYWJsZSB7XG4gICAgcmV0dXJuIChjb25zdHJ1Y3QgYXMgYW55KS50YWdzICE9PSB1bmRlZmluZWQ7XG4gIH1cblxuICAvKipcbiAgICogVGhlIHByb3BlcnR5IG5hbWUgZm9yIHRhZyB2YWx1ZXNcbiAgICpcbiAgICogTm9ybWFsbHkgdGhpcyBpcyBgdGFnc2AgYnV0IHNvbWUgcmVzb3VyY2VzIGNob29zZSBhIGRpZmZlcmVudCBuYW1lLiBDb2duaXRvXG4gICAqIFVzZXJQb29sIHVzZXMgVXNlclBvb2xUYWdzXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgdGFnUHJvcGVydHlOYW1lOiBzdHJpbmc7XG5cbiAgcHJpdmF0ZSByZWFkb25seSB0YWdzID0gbmV3IE1hcDxzdHJpbmcsIFRhZz4oKTtcbiAgcHJpdmF0ZSByZWFkb25seSBwcmlvcml0aWVzID0gbmV3IE1hcDxzdHJpbmcsIG51bWJlcj4oKTtcbiAgcHJpdmF0ZSByZWFkb25seSB0YWdGb3JtYXR0ZXI6IElUYWdGb3JtYXR0ZXI7XG4gIHByaXZhdGUgcmVhZG9ubHkgcmVzb3VyY2VUeXBlTmFtZTogc3RyaW5nO1xuICBwcml2YXRlIHJlYWRvbmx5IGluaXRpYWxUYWdQcmlvcml0eSA9IDUwO1xuXG4gIGNvbnN0cnVjdG9yKHRhZ1R5cGU6IFRhZ1R5cGUsIHJlc291cmNlVHlwZU5hbWU6IHN0cmluZywgdGFnU3RydWN0dXJlPzogYW55LCBvcHRpb25zOiBUYWdNYW5hZ2VyT3B0aW9ucyA9IHsgfSkge1xuICAgIHRoaXMucmVzb3VyY2VUeXBlTmFtZSA9IHJlc291cmNlVHlwZU5hbWU7XG4gICAgdGhpcy50YWdGb3JtYXR0ZXIgPSBUQUdfRk9STUFUVEVSU1t0YWdUeXBlXTtcbiAgICBpZiAodGFnU3RydWN0dXJlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHRoaXMuX3NldFRhZyguLi50aGlzLnRhZ0Zvcm1hdHRlci5wYXJzZVRhZ3ModGFnU3RydWN0dXJlLCB0aGlzLmluaXRpYWxUYWdQcmlvcml0eSkpO1xuICAgIH1cbiAgICB0aGlzLnRhZ1Byb3BlcnR5TmFtZSA9IG9wdGlvbnMudGFnUHJvcGVydHlOYW1lIHx8ICd0YWdzJztcbiAgfVxuXG4gIC8qKlxuICAgKiBBZGRzIHRoZSBzcGVjaWZpZWQgdGFnIHRvIHRoZSBhcnJheSBvZiB0YWdzXG4gICAqXG4gICAqL1xuICBwdWJsaWMgc2V0VGFnKGtleTogc3RyaW5nLCB2YWx1ZTogc3RyaW5nLCBwcmlvcml0eSA9IDAsIGFwcGx5VG9MYXVuY2hlZEluc3RhbmNlcyA9IHRydWUpOiB2b2lkIHtcbiAgICAvLyBUaGlzIG1ldGhvZCBtb3N0bHkgZXhpc3RzIGJlY2F1c2Ugd2UgZG9uJ3Qgd2FudCB0byBleHBvc2UgdGhlICdUYWcnIHR5cGUgdXNlZCAoaXQgd2lsbCBiZSBjb25mdXNpbmdcbiAgICAvLyB0byB1c2VycykuXG4gICAgdGhpcy5fc2V0VGFnKHsga2V5LCB2YWx1ZSwgcHJpb3JpdHksIGFwcGx5VG9MYXVuY2hlZEluc3RhbmNlcyB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZW1vdmVzIHRoZSBzcGVjaWZpZWQgdGFnIGZyb20gdGhlIGFycmF5IGlmIGl0IGV4aXN0c1xuICAgKlxuICAgKiBAcGFyYW0ga2V5IFRoZSB0YWcgdG8gcmVtb3ZlXG4gICAqIEBwYXJhbSBwcmlvcml0eSBUaGUgcHJpb3JpdHkgb2YgdGhlIHJlbW92ZSBvcGVyYXRpb25cbiAgICovXG4gIHB1YmxpYyByZW1vdmVUYWcoa2V5OiBzdHJpbmcsIHByaW9yaXR5OiBudW1iZXIpOiB2b2lkIHtcbiAgICBpZiAocHJpb3JpdHkgPj0gKHRoaXMucHJpb3JpdGllcy5nZXQoa2V5KSB8fCAwKSkge1xuICAgICAgdGhpcy50YWdzLmRlbGV0ZShrZXkpO1xuICAgICAgdGhpcy5wcmlvcml0aWVzLnNldChrZXksIHByaW9yaXR5KTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUmVuZGVycyB0YWdzIGludG8gdGhlIHByb3BlciBmb3JtYXQgYmFzZWQgb24gVGFnVHlwZVxuICAgKi9cbiAgcHVibGljIHJlbmRlclRhZ3MoKTogYW55IHtcbiAgICByZXR1cm4gdGhpcy50YWdGb3JtYXR0ZXIuZm9ybWF0VGFncyhBcnJheS5mcm9tKHRoaXMudGFncy52YWx1ZXMoKSkpO1xuICB9XG5cbiAgLyoqXG4gICAqIERldGVybWluZSBpZiB0aGUgYXNwZWN0IGFwcGxpZXMgaGVyZVxuICAgKlxuICAgKiBMb29rcyBhdCB0aGUgaW5jbHVkZSBhbmQgZXhjbHVkZSByZXNvdXJjZVR5cGVOYW1lIGFycmF5cyB0byBkZXRlcm1pbmUgaWZcbiAgICogdGhlIGFzcGVjdCBhcHBsaWVzIGhlcmVcbiAgICovXG4gIHB1YmxpYyBhcHBseVRhZ0FzcGVjdEhlcmUoaW5jbHVkZT86IHN0cmluZ1tdLCBleGNsdWRlPzogc3RyaW5nW10pIHtcbiAgICBpZiAoZXhjbHVkZSAmJiBleGNsdWRlLmxlbmd0aCA+IDAgJiYgZXhjbHVkZS5pbmRleE9mKHRoaXMucmVzb3VyY2VUeXBlTmFtZSkgIT09IC0xKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGlmIChpbmNsdWRlICYmIGluY2x1ZGUubGVuZ3RoID4gMCAmJiBpbmNsdWRlLmluZGV4T2YodGhpcy5yZXNvdXJjZVR5cGVOYW1lKSA9PT0gLTEpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlcmUgYXJlIGFueSB0YWdzIGRlZmluZWRcbiAgICovXG4gIHB1YmxpYyBoYXNUYWdzKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLnRhZ3Muc2l6ZSA+IDA7XG4gIH1cblxuICBwcml2YXRlIF9zZXRUYWcoLi4udGFnczogVGFnW10pIHtcbiAgICBmb3IgKGNvbnN0IHRhZyBvZiB0YWdzKSB7XG4gICAgICBpZiAodGFnLnByaW9yaXR5ID49ICh0aGlzLnByaW9yaXRpZXMuZ2V0KHRhZy5rZXkpIHx8IDApKSB7XG4gICAgICAgIHRoaXMudGFncy5zZXQodGFnLmtleSwgdGFnKTtcbiAgICAgICAgdGhpcy5wcmlvcml0aWVzLnNldCh0YWcua2V5LCB0YWcucHJpb3JpdHkpO1xuICAgICAgfVxuICAgIH1cbiAgfVxufVxuIl19