UNPKG

@aws-cdk/core

Version:

AWS Cloud Development Kit Core Library

248 lines 28.7 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.TagManager = void 0; 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; } } let _tagFormattersCache; /** * Access tag formatters table * * In a function because we're in a load cycle with cfn-resource that defines `TagType`. */ function TAG_FORMATTERS() { return _tagFormattersCache !== null && _tagFormattersCache !== void 0 ? _tagFormattersCache : (_tagFormattersCache = { [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(this.sortedTags); } /** * Render the tags in a readable format. */ tagValues() { const ret = {}; for (const tag of this.sortedTags) { ret[tag.key] = tag.value; } return ret; } /** * 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); } } } get sortedTags() { return Array.from(this.tags.values()).sort((a, b) => a.key.localeCompare(b.key)); } } exports.TagManager = TagManager; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFnLW1hbmFnZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJ0YWctbWFuYWdlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSxpREFBeUM7QUF5Q3pDOztHQUVHO0FBQ0gsTUFBTSxpQkFBaUI7SUFDZCxTQUFTLENBQUMsZUFBb0IsRUFBRSxRQUFnQjtRQUNyRCxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxlQUFlLENBQUMsRUFBRTtZQUNuQyxNQUFNLElBQUksS0FBSyxDQUFDLHlEQUF5RCxJQUFJLENBQUMsU0FBUyxDQUFDLGVBQWUsQ0FBQyxFQUFFLENBQUMsQ0FBQztTQUM3RztRQUVELE1BQU0sSUFBSSxHQUFVLEVBQUUsQ0FBQztRQUN2QixLQUFLLE1BQU0sR0FBRyxJQUFJLGVBQWUsRUFBRTtZQUNqQyxJQUFJLEdBQUcsQ0FBQyxHQUFHLEtBQUssU0FBUyxJQUFJLEdBQUcsQ0FBQyxLQUFLLEtBQUssU0FBUyxFQUFFO2dCQUNwRCxNQUFNLElBQUksS0FBSyxDQUFDLGdEQUFnRCxJQUFJLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQzthQUN4RjtZQUNELDZDQUE2QztZQUM3QyxJQUFJLENBQUMsSUFBSSxDQUFDO2dCQUNSLEdBQUcsRUFBRSxHQUFHLEdBQUcsQ0FBQyxHQUFHLEVBQUU7Z0JBQ2pCLEtBQUssRUFBRSxHQUFHLEdBQUcsQ0FBQyxLQUFLLEVBQUU7Z0JBQ3JCLFFBQVE7YUFDVCxDQUFDLENBQUM7U0FDSjtRQUNELE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUVNLFVBQVUsQ0FBQyxJQUFXO1FBQzNCLE1BQU0sT0FBTyxHQUFhLEVBQUUsQ0FBQztRQUM3QixLQUFLLE1BQU0sR0FBRyxJQUFJLElBQUksRUFBRTtZQUN0QixPQUFPLENBQUMsSUFBSSxDQUFDO2dCQUNYLEdBQUcsRUFBRSxHQUFHLENBQUMsR0FBRztnQkFDWixLQUFLLEVBQUUsR0FBRyxDQUFDLEtBQUs7YUFD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QUksT0FBTyxJQUFJLE9BQU8sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxJQUFJLE9BQU8sQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUU7WUFDbEYsT0FBTyxLQUFLLENBQUM7U0FDZDtRQUVELE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQzs7OztJQUtNLE9BQU87UUFDWixPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxHQUFHLENBQUMsQ0FBQztJQUM1QixDQUFDO0lBRU8sT0FBTyxDQUFDLEdBQUcsSUFBVztRQUM1QixLQUFLLE1BQU0sR0FBRyxJQUFJLElBQUksRUFBRTtZQUN0QixJQUFJLEdBQUcsQ0FBQyxRQUFRLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDLEVBQUU7Z0JBQ3ZELElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUM7Z0JBQzVCLElBQUksQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLFFBQVEsQ0FBQyxDQUFDO2FBQzVDO1NBQ0Y7SUFDSCxDQUFDO0lBRUQsSUFBWSxVQUFVO1FBQ3BCLE9BQU8sS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7SUFDbkYsQ0FBQztDQUNGO0FBN0dELGdDQTZHQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFRhZ1R5cGUgfSBmcm9tICcuL2Nmbi1yZXNvdXJjZSc7XG5pbXBvcnQgeyBDZm5UYWcgfSBmcm9tICcuL2Nmbi10YWcnO1xuXG5pbnRlcmZhY2UgVGFnIHtcbiAga2V5OiBzdHJpbmc7XG4gIHZhbHVlOiBzdHJpbmc7XG4gIHByaW9yaXR5OiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIEBkZWZhdWx0IHRydWVcbiAgICovXG4gIGFwcGx5VG9MYXVuY2hlZEluc3RhbmNlcz86IGJvb2xlYW47XG59XG5cbmludGVyZmFjZSBDZm5Bc2dUYWcge1xuICBrZXk6IHN0cmluZztcbiAgdmFsdWU6IHN0cmluZztcbiAgcHJvcGFnYXRlQXRMYXVuY2g6IGJvb2xlYW47XG59XG5cbmludGVyZmFjZSBTdGFja1RhZyB7XG4gIEtleTogc3RyaW5nO1xuICBWYWx1ZTogc3RyaW5nO1xufVxuLyoqXG4gKiBJbnRlcmZhY2UgZm9yIGNvbnZlcnRlciBiZXR3ZWVuIENsb3VkRm9ybWF0aW9uIGFuZCBpbnRlcm5hbCB0YWcgcmVwcmVzZW50YXRpb25zXG4gKi9cbmludGVyZmFjZSBJVGFnRm9ybWF0dGVyIHtcbiAgLyoqXG4gICAqIEZvcm1hdCB0aGUgZ2l2ZW4gdGFncyBhcyBDbG91ZEZvcm1hdGlvbiB0YWdzXG4gICAqL1xuICBmb3JtYXRUYWdzKHRhZ3M6IFRhZ1tdKTogYW55O1xuXG4gIC8qKlxuICAgKiBQYXJzZSB0aGUgQ2xvdWRGb3JtYXRpb24gdGFnIHJlcHJlc2VudGF0aW9uIGludG8gaW50ZXJuYWwgcmVwcmVzZW50YXRpb25cbiAgICpcbiAgICogVXNlIHRoZSBnaXZlbiBwcmlvcml0eS5cbiAgICovXG4gIHBhcnNlVGFncyhjZm5Qcm9wZXJ0eVRhZ3M6IGFueSwgcHJpb3JpdHk6IG51bWJlcik6IFRhZ1tdO1xufVxuXG4vKipcbiAqIFN0YW5kYXJkIHRhZ3MgYXJlIGEgbGlzdCBvZiB7IGtleSwgdmFsdWUgfSBvYmplY3RzXG4gKi9cbmNsYXNzIFN0YW5kYXJkRm9ybWF0dGVyIGltcGxlbWVudHMgSVRhZ0Zvcm1hdHRlciB7XG4gIHB1YmxpYyBwYXJzZVRhZ3MoY2ZuUHJvcGVydHlUYWdzOiBhbnksIHByaW9yaXR5OiBudW1iZXIpOiBUYWdbXSB7XG4gICAgaWYgKCFBcnJheS5pc0FycmF5KGNmblByb3BlcnR5VGFncykpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCB0YWcgaW5wdXQgZXhwZWN0ZWQgYXJyYXkgb2Yge2tleSwgdmFsdWV9IGhhdmUgJHtKU09OLnN0cmluZ2lmeShjZm5Qcm9wZXJ0eVRhZ3MpfWApO1xuICAgIH1cblxuICAgIGNvbnN0IHRhZ3M6IFRhZ1tdID0gW107XG4gICAgZm9yIChjb25zdCB0YWcgb2YgY2ZuUHJvcGVydHlUYWdzKSB7XG4gICAgICBpZiAodGFnLmtleSA9PT0gdW5kZWZpbmVkIHx8IHRhZy52YWx1ZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCB0YWcgaW5wdXQgZXhwZWN0ZWQge2tleSwgdmFsdWV9IGhhdmUgJHtKU09OLnN0cmluZ2lmeSh0YWcpfWApO1xuICAgICAgfVxuICAgICAgLy8gdXNpbmcgaW50ZXJwIHRvIGVuc3VyZSBUb2tlbiBpcyBub3cgc3RyaW5nXG4gICAgICB0YWdzLnB1c2goe1xuICAgICAgICBrZXk6IGAke3RhZy5rZXl9YCxcbiAgICAgICAgdmFsdWU6IGAke3RhZy52YWx1ZX1gLFxuICAgICAgICBwcmlvcml0eSxcbiAgICAgIH0pO1xuICAgIH1cbiAgICByZXR1cm4gdGFncztcbiAgfVxuXG4gIHB1YmxpYyBmb3JtYXRUYWdzKHRhZ3M6IFRhZ1tdKTogYW55IHtcbiAgICBjb25zdCBjZm5UYWdzOiBDZm5UYWdbXSA9IFtdO1xuICAgIGZvciAoY29uc3QgdGFnIG9mIHRhZ3MpIHtcbiAgICAgIGNmblRhZ3MucHVzaCh7XG4gICAgICAgIGtleTogdGFnLmtleSxcbiAgICAgICAgdmFsdWU6IHRhZy52YWx1ZSxcbiAgICAgIH0pO1xuICAgIH1cbiAgICByZXR1cm4gY2ZuVGFncy5sZW5ndGggPT09IDAgPyB1bmRlZmluZWQgOiBjZm5UYWdzO1xuICB9XG59XG5cbi8qKlxuICogQVNHIHRhZ3MgYXJlIGEgbGlzdCBvZiB7IGtleSwgdmFsdWUsIHByb3BhZ2F0ZUF0TGF1bmNoIH0gb2JqZWN0c1xuICovXG5jbGFzcyBBc2dGb3JtYXR0ZXIgaW1wbGVtZW50cyBJVGFnRm9ybWF0dGVyIHtcbiAgcHVibGljIHBhcnNlVGFncyhjZm5Qcm9wZXJ0eVRhZ3M6IGFueSwgcHJpb3JpdHk6IG51bWJlcik6IFRhZ1tdIHtcbiAgICBjb25zdCB0YWdzOiBUYWdbXSA9IFtdO1xuICAgIGlmICghQXJyYXkuaXNBcnJheShjZm5Qcm9wZXJ0eVRhZ3MpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgdGFnIGlucHV0IGV4cGVjdGVkIGFycmF5IG9mIHtrZXksIHZhbHVlLCBwcm9wYWdhdGVBdExhdW5jaH0gaGF2ZSAke0pTT04uc3RyaW5naWZ5KGNmblByb3BlcnR5VGFncyl9YCk7XG4gICAgfVxuXG4gICAgZm9yIChjb25zdCB0YWcgb2YgY2ZuUHJvcGVydHlUYWdzKSB7XG4gICAgICBpZiAodGFnLmtleSA9PT0gdW5kZWZpbmVkIHx8XG4gICAgICAgIHRhZy52YWx1ZSA9PT0gdW5kZWZpbmVkIHx8XG4gICAgICAgIHRhZy5wcm9wYWdhdGVBdExhdW5jaCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCB0YWcgaW5wdXQgZXhwZWN0ZWQge2tleSwgdmFsdWUsIHByb3BhZ2F0ZUF0TGF1bmNofSBoYXZlICR7SlNPTi5zdHJpbmdpZnkodGFnKX1gKTtcbiAgICAgIH1cbiAgICAgIC8vIHVzaW5nIGludGVycCB0byBlbnN1cmUgVG9rZW4gaXMgbm93IHN0cmluZ1xuICAgICAgdGFncy5wdXNoKHtcbiAgICAgICAga2V5OiBgJHt0YWcua2V5fWAsXG4gICAgICAgIHZhbHVlOiBgJHt0YWcudmFsdWV9YCxcbiAgICAgICAgcHJpb3JpdHksXG4gICAgICAgIGFwcGx5VG9MYXVuY2hlZEluc3RhbmNlczogISF0YWcucHJvcGFnYXRlQXRMYXVuY2gsXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGFncztcbiAgfVxuXG4gIHB1YmxpYyBmb3JtYXRUYWdzKHRhZ3M6IFRhZ1tdKTogYW55IHtcbiAgICBjb25zdCBjZm5UYWdzOiBDZm5Bc2dUYWdbXSA9IFtdO1xuICAgIGZvciAoY29uc3QgdGFnIG9mIHRhZ3MpIHtcbiAgICAgIGNmblRhZ3MucHVzaCh7XG4gICAgICAgIGtleTogdGFnLmtleSxcbiAgICAgICAgdmFsdWU6IHRhZy52YWx1ZSxcbiAgICAgICAgcHJvcGFnYXRlQXRMYXVuY2g6IHRhZy5hcHBseVRvTGF1bmNoZWRJbnN0YW5jZXMgIT09IGZhbHNlLFxuICAgICAgfSk7XG4gICAgfVxuICAgIHJldHVybiBjZm5UYWdzLmxlbmd0aCA9PT0gMCA/IHVuZGVmaW5lZCA6IGNmblRhZ3M7XG4gIH1cbn1cblxuLyoqXG4gKiBTb21lIENsb3VkRm9ybWF0aW9uIGNvbnN0cnVjdHMgdXNlIGEgeyBrZXk6IHZhbHVlIH0gbWFwIGZvciB0YWdzXG4gKi9cbmNsYXNzIE1hcEZvcm1hdHRlciBpbXBsZW1lbnRzIElUYWdGb3JtYXR0ZXIge1xuICBwdWJsaWMgcGFyc2VUYWdzKGNmblByb3BlcnR5VGFnczogYW55LCBwcmlvcml0eTogbnVtYmVyKTogVGFnW10ge1xuICAgIGNvbnN0IHRhZ3M6IFRhZ1tdID0gW107XG4gICAgaWYgKEFycmF5LmlzQXJyYXkoY2ZuUHJvcGVydHlUYWdzKSB8fCB0eXBlb2YoY2ZuUHJvcGVydHlUYWdzKSAhPT0gJ29iamVjdCcpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCB0YWcgaW5wdXQgZXhwZWN0ZWQgbWFwIG9mIHtrZXk6IHZhbHVlfSBoYXZlICR7SlNPTi5zdHJpbmdpZnkoY2ZuUHJvcGVydHlUYWdzKX1gKTtcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IFtrZXksIHZhbHVlXSBvZiBPYmplY3QuZW50cmllcyhjZm5Qcm9wZXJ0eVRhZ3MpKSB7XG4gICAgICB0YWdzLnB1c2goe1xuICAgICAgICBrZXksXG4gICAgICAgIHZhbHVlOiBgJHt2YWx1ZX1gLFxuICAgICAgICBwcmlvcml0eSxcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHJldHVybiB0YWdzO1xuICB9XG5cbiAgcHVibGljIGZvcm1hdFRhZ3ModGFnczogVGFnW10pOiBhbnkge1xuICAgIGNvbnN0IGNmblRhZ3M6IHtba2V5OiBzdHJpbmddOiBzdHJpbmd9ID0ge307XG4gICAgZm9yIChjb25zdCB0YWcgb2YgdGFncykge1xuICAgICAgY2ZuVGFnc1tgJHt0YWcua2V5fWBdID0gYCR7dGFnLnZhbHVlfWA7XG4gICAgfVxuICAgIHJldHVybiBPYmplY3Qua2V5cyhjZm5UYWdzKS5sZW5ndGggPT09IDAgPyB1bmRlZmluZWQgOiBjZm5UYWdzO1xuICB9XG59XG5cbi8qKlxuICogU3RhY2tUYWdzIGFyZSBvZiB0aGUgZm9ybWF0IHsgS2V5OiBrZXksIFZhbHVlOiB2YWx1ZSB9XG4gKi9cbmNsYXNzIEtleVZhbHVlRm9ybWF0dGVyIGltcGxlbWVudHMgSVRhZ0Zvcm1hdHRlciB7XG4gIHB1YmxpYyBwYXJzZVRhZ3Moa2V5VmFsdWVUYWdzOiBhbnksIHByaW9yaXR5OiBudW1iZXIpOiBUYWdbXSB7XG4gICAgY29uc3QgdGFnczogVGFnW10gPSBbXTtcbiAgICBmb3IgKGNvbnN0IGtleSBpbiBrZXlWYWx1ZVRhZ3MpIHtcbiAgICAgIGlmIChrZXlWYWx1ZVRhZ3MuaGFzT3duUHJvcGVydHkoa2V5KSkge1xuICAgICAgICBjb25zdCB2YWx1ZSA9IGtleVZhbHVlVGFnc1trZXldO1xuICAgICAgICB0YWdzLnB1c2goe1xuICAgICAgICAgIGtleSxcbiAgICAgICAgICB2YWx1ZSxcbiAgICAgICAgICBwcmlvcml0eSxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiB0YWdzO1xuICB9XG4gIHB1YmxpYyBmb3JtYXRUYWdzKHVuZm9ybWF0dGVkVGFnczogVGFnW10pOiBhbnkge1xuICAgIGNvbnN0IHRhZ3M6IFN0YWNrVGFnW10gPSBbXTtcbiAgICB1bmZvcm1hdHRlZFRhZ3MuZm9yRWFjaCh0YWcgPT4ge1xuICAgICAgdGFncy5wdXNoKHtcbiAgICAgICAgS2V5OiB0YWcua2V5LFxuICAgICAgICBWYWx1ZTogdGFnLnZhbHVlLFxuICAgICAgfSk7XG4gICAgfSk7XG4gICAgcmV0dXJuIHRhZ3M7XG4gIH1cbn1cblxuY2xhc3MgTm9Gb3JtYXQgaW1wbGVtZW50cyBJVGFnRm9ybWF0dGVyIHtcbiAgcHVibGljIHBhcnNlVGFncyhfY2ZuUHJvcGVydHlUYWdzOiBhbnkpOiBUYWdbXSB7XG4gICAgcmV0dXJuIFtdO1xuICB9XG4gIHB1YmxpYyBmb3JtYXRUYWdzKF90YWdzOiBUYWdbXSk6IGFueSB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxufVxuXG5cbmxldCBfdGFnRm9ybWF0dGVyc0NhY2hlOiB7W2tleTogc3RyaW5nXTogSVRhZ0Zvcm1hdHRlcn0gfCB1bmRlZmluZWQ7XG5cbi8qKlxuICogQWNjZXNzIHRhZyBmb3JtYXR0ZXJzIHRhYmxlXG4gKlxuICogSW4gYSBmdW5jdGlvbiBiZWNhdXNlIHdlJ3JlIGluIGEgbG9hZCBjeWNsZSB3aXRoIGNmbi1yZXNvdXJjZSB0aGF0IGRlZmluZXMgYFRhZ1R5cGVgLlxuICovXG5mdW5jdGlvbiBUQUdfRk9STUFUVEVSUygpOiB7W2tleTogc3RyaW5nXTogSVRhZ0Zvcm1hdHRlcn0ge1xuICByZXR1cm4gX3RhZ0Zvcm1hdHRlcnNDYWNoZSA/PyAoX3RhZ0Zvcm1hdHRlcnNDYWNoZSA9IHtcbiAgICBbVGFnVHlwZS5BVVRPU0NBTElOR19HUk9VUF06IG5ldyBBc2dGb3JtYXR0ZXIoKSxcbiAgICBbVGFnVHlwZS5TVEFOREFSRF06IG5ldyBTdGFuZGFyZEZvcm1hdHRlcigpLFxuICAgIFtUYWdUeXBlLk1BUF06IG5ldyBNYXBGb3JtYXR0ZXIoKSxcbiAgICBbVGFnVHlwZS5LRVlfVkFMVUVdOiBuZXcgS2V5VmFsdWVGb3JtYXR0ZXIoKSxcbiAgICBbVGFnVHlwZS5OT1RfVEFHR0FCTEVdOiBuZXcgTm9Gb3JtYXQoKSxcbiAgfSk7XG59O1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbmV4cG9ydCBpbnRlcmZhY2UgSVRhZ2dhYmxlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgcmVhZG9ubHkgdGFnczogVGFnTWFuYWdlcjtcbn1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG5leHBvcnQgaW50ZXJmYWNlIFRhZ01hbmFnZXJPcHRpb25zIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICByZWFkb25seSB0YWdQcm9wZXJ0eU5hbWU/OiBzdHJpbmc7XG59XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuZXhwb3J0IGNsYXNzIFRhZ01hbmFnZXIge1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICBwdWJsaWMgc3RhdGljIGlzVGFnZ2FibGUoY29uc3RydWN0OiBhbnkpOiBjb25zdHJ1Y3QgaXMgSVRhZ2dhYmxlIHtcbiAgICByZXR1cm4gKGNvbnN0cnVjdCBhcyBhbnkpLnRhZ3MgIT09IHVuZGVmaW5lZDtcbiAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICBwdWJsaWMgcmVhZG9ubHkgdGFnUHJvcGVydHlOYW1lOiBzdHJpbmc7XG5cbiAgcHJpdmF0ZSByZWFkb25seSB0YWdzID0gbmV3IE1hcDxzdHJpbmcsIFRhZz4oKTtcbiAgcHJpdmF0ZSByZWFkb25seSBwcmlvcml0aWVzID0gbmV3IE1hcDxzdHJpbmcsIG51bWJlcj4oKTtcbiAgcHJpdmF0ZSByZWFkb25seSB0YWdGb3JtYXR0ZXI6IElUYWdGb3JtYXR0ZXI7XG4gIHByaXZhdGUgcmVhZG9ubHkgcmVzb3VyY2VUeXBlTmFtZTogc3RyaW5nO1xuICBwcml2YXRlIHJlYWRvbmx5IGluaXRpYWxUYWdQcmlvcml0eSA9IDUwO1xuXG4gIGNvbnN0cnVjdG9yKHRhZ1R5cGU6IFRhZ1R5cGUsIHJlc291cmNlVHlwZU5hbWU6IHN0cmluZywgdGFnU3RydWN0dXJlPzogYW55LCBvcHRpb25zOiBUYWdNYW5hZ2VyT3B0aW9ucyA9IHsgfSkge1xuICAgIHRoaXMucmVzb3VyY2VUeXBlTmFtZSA9IHJlc291cmNlVHlwZU5hbWU7XG4gICAgdGhpcy50YWdGb3JtYXR0ZXIgPSBUQUdfRk9STUFUVEVSUygpW3RhZ1R5cGVdO1xuICAgIGlmICh0YWdTdHJ1Y3R1cmUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhpcy5fc2V0VGFnKC4uLnRoaXMudGFnRm9ybWF0dGVyLnBhcnNlVGFncyh0YWdTdHJ1Y3R1cmUsIHRoaXMuaW5pdGlhbFRhZ1ByaW9yaXR5KSk7XG4gICAgfVxuICAgIHRoaXMudGFnUHJvcGVydHlOYW1lID0gb3B0aW9ucy50YWdQcm9wZXJ0eU5hbWUgfHwgJ3RhZ3MnO1xuICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gIHB1YmxpYyBzZXRUYWcoa2V5OiBzdHJpbmcsIHZhbHVlOiBzdHJpbmcsIHByaW9yaXR5ID0gMCwgYXBwbHlUb0xhdW5jaGVkSW5zdGFuY2VzID0gdHJ1ZSk6IHZvaWQge1xuICAgIC8vIFRoaXMgbWV0aG9kIG1vc3RseSBleGlzdHMgYmVjYXVzZSB3ZSBkb24ndCB3YW50IHRvIGV4cG9zZSB0aGUgJ1RhZycgdHlwZSB1c2VkIChpdCB3aWxsIGJlIGNvbmZ1c2luZ1xuICAgIC8vIHRvIHVzZXJzKS5cbiAgICB0aGlzLl9zZXRUYWcoeyBrZXksIHZhbHVlLCBwcmlvcml0eSwgYXBwbHlUb0xhdW5jaGVkSW5zdGFuY2VzIH0pO1xuICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gIHB1YmxpYyByZW1vdmVUYWcoa2V5OiBzdHJpbmcsIHByaW9yaXR5OiBudW1iZXIpOiB2b2lkIHtcbiAgICBpZiAocHJpb3JpdHkgPj0gKHRoaXMucHJpb3JpdGllcy5nZXQoa2V5KSB8fCAwKSkge1xuICAgICAgdGhpcy50YWdzLmRlbGV0ZShrZXkpO1xuICAgICAgdGhpcy5wcmlvcml0aWVzLnNldChrZXksIHByaW9yaXR5KTtcbiAgICB9XG4gIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gIHB1YmxpYyByZW5kZXJUYWdzKCk6IGFueSB7XG4gICAgcmV0dXJuIHRoaXMudGFnRm9ybWF0dGVyLmZvcm1hdFRhZ3ModGhpcy5zb3J0ZWRUYWdzKTtcbiAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICBwdWJsaWMgdGFnVmFsdWVzKCk6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4ge1xuICAgIGNvbnN0IHJldDogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHt9O1xuICAgIGZvciAoY29uc3QgdGFnIG9mIHRoaXMuc29ydGVkVGFncykge1xuICAgICAgcmV0W3RhZy5rZXldID0gdGFnLnZhbHVlO1xuICAgIH1cbiAgICByZXR1cm4gcmV0O1xuICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICBwdWJsaWMgYXBwbHlUYWdBc3BlY3RIZXJlKGluY2x1ZGU/OiBzdHJpbmdbXSwgZXhjbHVkZT86IHN0cmluZ1tdKSB7XG4gICAgaWYgKGV4Y2x1ZGUgJiYgZXhjbHVkZS5sZW5ndGggPiAwICYmIGV4Y2x1ZGUuaW5kZXhPZih0aGlzLnJlc291cmNlVHlwZU5hbWUpICE9PSAtMSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBpZiAoaW5jbHVkZSAmJiBpbmNsdWRlLmxlbmd0aCA+IDAgJiYgaW5jbHVkZS5pbmRleE9mKHRoaXMucmVzb3VyY2VUeXBlTmFtZSkgPT09IC0xKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgcHVibGljIGhhc1RhZ3MoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMudGFncy5zaXplID4gMDtcbiAgfVxuXG4gIHByaXZhdGUgX3NldFRhZyguLi50YWdzOiBUYWdbXSkge1xuICAgIGZvciAoY29uc3QgdGFnIG9mIHRhZ3MpIHtcbiAgICAgIGlmICh0YWcucHJpb3JpdHkgPj0gKHRoaXMucHJpb3JpdGllcy5nZXQodGFnLmtleSkgfHwgMCkpIHtcbiAgICAgICAgdGhpcy50YWdzLnNldCh0YWcua2V5LCB0YWcpO1xuICAgICAgICB0aGlzLnByaW9yaXRpZXMuc2V0KHRhZy5rZXksIHRhZy5wcmlvcml0eSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBnZXQgc29ydGVkVGFncygpIHtcbiAgICByZXR1cm4gQXJyYXkuZnJvbSh0aGlzLnRhZ3MudmFsdWVzKCkpLnNvcnQoKGEsIGIpID0+IGEua2V5LmxvY2FsZUNvbXBhcmUoYi5rZXkpKTtcbiAgfVxufVxuIl19