UNPKG

@aws-cdk/core

Version:

AWS Cloud Development Kit Core Library

283 lines 39.9 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const cxapi = require("@aws-cdk/cx-api"); // import required to be here, otherwise causes a cycle when running the generated JavaScript // tslint:disable-next-line:ordered-imports const cfn_element_1 = require("./cfn-element"); const cfn_resource_policy_1 = require("./cfn-resource-policy"); const cfn_reference_1 = require("./private/cfn-reference"); const removal_policy_1 = require("./removal-policy"); const tag_manager_1 = require("./tag-manager"); const util_1 = require("./util"); /** * Represents a CloudFormation resource. */ class CfnResource extends cfn_element_1.CfnRefElement { /** * Creates a resource construct. * @param cfnResourceType The CloudFormation type of this resource (e.g. AWS::DynamoDB::Table) */ constructor(scope, id, props) { super(scope, id); // MAINTAINERS NOTE: this class serves as the base class for the generated L1 // ("CFN") resources (such as `s3.CfnBucket`). These resources will have a // property for each CloudFormation property of the resource. This means that // if at some point in the future a property is introduced with a name similar // to one of the properties here, it will be "masked" by the derived class. To // that end, we prefix all properties in this class with `cfnXxx` with the // hope to avoid those conflicts in the future. /** * Options for this resource, such as condition, update policy etc. */ this.cfnOptions = {}; /** * An object to be merged on top of the entire resource definition. */ this.rawOverrides = {}; /** * Logical IDs of dependencies. * * Is filled during prepare(). */ this.dependsOn = new Set(); if (!props.type) { throw new Error('The `type` property is required'); } this.cfnResourceType = props.type; this._cfnProperties = props.properties || {}; // if aws:cdk:enable-path-metadata is set, embed the current construct's // path in the CloudFormation template, so it will be possible to trace // back to the actual construct path. if (this.node.tryGetContext(cxapi.PATH_METADATA_ENABLE_CONTEXT)) { this.cfnOptions.metadata = { [cxapi.PATH_METADATA_KEY]: this.node.path }; } } /** * Check whether the given construct is a CfnResource */ static isCfnResource(construct) { return construct.cfnResourceType !== undefined; } /** * Sets the deletion policy of the resource based on the removal policy specified. */ applyRemovalPolicy(policy, options = {}) { policy = policy || options.default || removal_policy_1.RemovalPolicy.RETAIN; let deletionPolicy; switch (policy) { case removal_policy_1.RemovalPolicy.DESTROY: deletionPolicy = cfn_resource_policy_1.CfnDeletionPolicy.DELETE; break; case removal_policy_1.RemovalPolicy.RETAIN: deletionPolicy = cfn_resource_policy_1.CfnDeletionPolicy.RETAIN; break; default: throw new Error(`Invalid removal policy: ${policy}`); } this.cfnOptions.deletionPolicy = deletionPolicy; if (options.applyToUpdateReplacePolicy !== false) { this.cfnOptions.updateReplacePolicy = deletionPolicy; } } /** * Returns a token for an runtime attribute of this resource. * Ideally, use generated attribute accessors (e.g. `resource.arn`), but this can be used for future compatibility * in case there is no generated attribute. * @param attributeName The name of the attribute. */ getAtt(attributeName) { return cfn_reference_1.CfnReference.for(this, attributeName); } /** * Adds an override to the synthesized CloudFormation resource. To add a * property override, either use `addPropertyOverride` or prefix `path` with * "Properties." (i.e. `Properties.TopicName`). * * @param path The path of the property, you can use dot notation to * override values in complex types. Any intermdediate keys * will be created as needed. * @param value The value. Could be primitive or complex. */ addOverride(path, value) { const parts = path.split('.'); let curr = this.rawOverrides; while (parts.length > 1) { const key = parts.shift(); // if we can't recurse further or the previous value is not an // object overwrite it with an object. const isObject = curr[key] != null && typeof (curr[key]) === 'object' && !Array.isArray(curr[key]); if (!isObject) { curr[key] = {}; } curr = curr[key]; } const lastKey = parts.shift(); curr[lastKey] = value; } /** * Syntactic sugar for `addOverride(path, undefined)`. * @param path The path of the value to delete */ addDeletionOverride(path) { this.addOverride(path, undefined); } /** * Adds an override to a resource property. * * Syntactic sugar for `addOverride("Properties.<...>", value)`. * * @param propertyPath The path of the property * @param value The value */ addPropertyOverride(propertyPath, value) { this.addOverride(`Properties.${propertyPath}`, value); } /** * Adds an override that deletes the value of a property from the resource definition. * @param propertyPath The path to the property. */ addPropertyDeletionOverride(propertyPath) { this.addPropertyOverride(propertyPath, undefined); } /** * Indicates that this resource depends on another resource and cannot be provisioned * unless the other resource has been successfully provisioned. */ addDependsOn(resource) { this.dependsOn.add(resource); } /** * @returns a string representation of this resource */ toString() { return `${super.toString()} [${this.cfnResourceType}]`; } /** * Emits CloudFormation for this resource. * @internal */ _toCloudFormation() { try { const ret = { Resources: { // Post-Resolve operation since otherwise deepMerge is going to mix values into // the Token objects returned by ignoreEmpty. [this.logicalId]: new util_1.PostResolveToken({ Type: this.cfnResourceType, Properties: util_1.ignoreEmpty(this.cfnProperties), DependsOn: util_1.ignoreEmpty(renderDependsOn(this.dependsOn)), CreationPolicy: util_1.capitalizePropertyNames(this, renderCreationPolicy(this.cfnOptions.creationPolicy)), UpdatePolicy: util_1.capitalizePropertyNames(this, this.cfnOptions.updatePolicy), UpdateReplacePolicy: util_1.capitalizePropertyNames(this, this.cfnOptions.updateReplacePolicy), DeletionPolicy: util_1.capitalizePropertyNames(this, this.cfnOptions.deletionPolicy), Metadata: util_1.ignoreEmpty(this.cfnOptions.metadata), Condition: this.cfnOptions.condition && this.cfnOptions.condition.logicalId }, props => { const renderedProps = this.renderProperties(props.Properties || {}); props.Properties = renderedProps && (Object.values(renderedProps).find(v => !!v) ? renderedProps : undefined); return deepMerge(props, this.rawOverrides); }) } }; return ret; } catch (e) { // Change message e.message = `While synthesizing ${this.node.path}: ${e.message}`; // Adjust stack trace (make it look like node built it, too...) const trace = this.creationStack; if (trace) { const creationStack = ['--- resource created at ---', ...trace].join('\n at '); const problemTrace = e.stack.substr(e.stack.indexOf(e.message) + e.message.length); e.stack = `${e.message}\n ${creationStack}\n --- problem discovered at ---${problemTrace}`; } // Re-throw throw e; } // returns the set of logical ID (tokens) this resource depends on // sorted by construct paths to ensure test determinism function renderDependsOn(dependsOn) { return Array .from(dependsOn) .sort((x, y) => x.node.path.localeCompare(y.node.path)) .map(r => r.logicalId); } function renderCreationPolicy(policy) { if (!policy) { return undefined; } const result = Object.assign({}, policy); if (policy.resourceSignal && policy.resourceSignal.timeout) { result.resourceSignal = policy.resourceSignal; } return result; } } get cfnProperties() { const tags = tag_manager_1.TagManager.isTaggable(this) ? this.tags.renderTags() : {}; return deepMerge(this._cfnProperties || {}, { tags }); } renderProperties(props) { return props; } /** * Return properties modified after initiation * * Resources that expose mutable properties should override this function to * collect and return the properties object for this resource. */ get updatedProperites() { return this._cfnProperties; } validateProperties(_properties) { // Nothing } } exports.CfnResource = CfnResource; var TagType; (function (TagType) { TagType["STANDARD"] = "StandardTag"; TagType["AUTOSCALING_GROUP"] = "AutoScalingGroupTag"; TagType["MAP"] = "StringToStringMap"; TagType["KEY_VALUE"] = "KeyValue"; TagType["NOT_TAGGABLE"] = "NotTaggable"; })(TagType = exports.TagType || (exports.TagType = {})); /** * Merges `source` into `target`, overriding any existing values. * `null`s will cause a value to be deleted. */ function deepMerge(target, ...sources) { for (const source of sources) { if (typeof (source) !== 'object' || typeof (target) !== 'object') { throw new Error(`Invalid usage. Both source (${JSON.stringify(source)}) and target (${JSON.stringify(target)}) must be objects`); } for (const key of Object.keys(source)) { const value = source[key]; if (typeof (value) === 'object' && value != null && !Array.isArray(value)) { // if the value at the target is not an object, override it with an // object so we can continue the recursion if (typeof (target[key]) !== 'object') { target[key] = {}; } deepMerge(target[key], value); // if the result of the merge is an empty object, it's because the // eventual value we assigned is `undefined`, and there are no // sibling concrete values alongside, so we can delete this tree. const output = target[key]; if (typeof (output) === 'object' && Object.keys(output).length === 0) { delete target[key]; } } else if (value === undefined) { delete target[key]; } else { target[key] = value; } } } return target; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2ZuLXJlc291cmNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiY2ZuLXJlc291cmNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEseUNBQTBDO0FBRTFDLDZGQUE2RjtBQUM3RiwyQ0FBMkM7QUFDM0MsK0NBQThDO0FBQzlDLCtEQUE4RjtBQUU5RiwyREFBdUQ7QUFDdkQscURBQXVFO0FBRXZFLCtDQUEyQztBQUMzQyxpQ0FBZ0Y7QUFnQmhGOztHQUVHO0FBQ0gsTUFBYSxXQUFZLFNBQVEsMkJBQWE7SUE4QzVDOzs7T0FHRztJQUNILFlBQVksS0FBZ0IsRUFBRSxFQUFVLEVBQUUsS0FBdUI7UUFDL0QsS0FBSyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQztRQTNDbkIsNkVBQTZFO1FBQzdFLDBFQUEwRTtRQUMxRSw2RUFBNkU7UUFDN0UsOEVBQThFO1FBQzlFLDhFQUE4RTtRQUM5RSwwRUFBMEU7UUFDMUUsK0NBQStDO1FBRS9DOztXQUVHO1FBQ2EsZUFBVSxHQUF3QixFQUFFLENBQUM7UUFlckQ7O1dBRUc7UUFDYyxpQkFBWSxHQUFRLEVBQUUsQ0FBQztRQUV4Qzs7OztXQUlHO1FBQ2MsY0FBUyxHQUFHLElBQUksR0FBRyxFQUFlLENBQUM7UUFTbEQsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUU7WUFDZixNQUFNLElBQUksS0FBSyxDQUFDLGlDQUFpQyxDQUFDLENBQUM7U0FDcEQ7UUFFRCxJQUFJLENBQUMsZUFBZSxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUM7UUFDbEMsSUFBSSxDQUFDLGNBQWMsR0FBRyxLQUFLLENBQUMsVUFBVSxJQUFJLEVBQUUsQ0FBQztRQUU3Qyx3RUFBd0U7UUFDeEUsdUVBQXVFO1FBQ3ZFLHFDQUFxQztRQUNyQyxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLEtBQUssQ0FBQyw0QkFBNEIsQ0FBQyxFQUFFO1lBQy9ELElBQUksQ0FBQyxVQUFVLENBQUMsUUFBUSxHQUFH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QUFHLEVBQUUsQ0FBQztpQkFDbEI7Z0JBRUQsU0FBUyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsRUFBRSxLQUFLLENBQUMsQ0FBQztnQkFFOUIsa0VBQWtFO2dCQUNsRSw4REFBOEQ7Z0JBQzlELGlFQUFpRTtnQkFDakUsTUFBTSxNQUFNLEdBQUcsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDO2dCQUMzQixJQUFJLE9BQU0sQ0FBQyxNQUFNLENBQUMsS0FBSyxRQUFRLElBQUksTUFBTSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFO29CQUNuRSxPQUFPLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQztpQkFDcEI7YUFDRjtpQkFBTSxJQUFJLEtBQUssS0FBSyxTQUFTLEVBQUU7Z0JBQzlCLE9BQU8sTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDO2FBQ3BCO2lCQUFNO2dCQUNMLE1BQU0sQ0FBQyxHQUFHLENBQUMsR0FBRyxLQUFLLENBQUM7YUFDckI7U0FDRjtLQUNGO0lBRUQsT0FBTyxNQUFNLENBQUM7QUFDaEIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBjeGFwaSA9IHJlcXVpcmUoJ0Bhd3MtY2RrL2N4LWFwaScpO1xuaW1wb3J0IHsgQ2ZuQ29uZGl0aW9uIH0gZnJvbSAnLi9jZm4tY29uZGl0aW9uJztcbi8vIGltcG9ydCByZXF1aXJlZCB0byBiZSBoZXJlLCBvdGhlcndpc2UgY2F1c2VzIGEgY3ljbGUgd2hlbiBydW5uaW5nIHRoZSBnZW5lcmF0ZWQgSmF2YVNjcmlwdFxuLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm9yZGVyZWQtaW1wb3J0c1xuaW1wb3J0IHsgQ2ZuUmVmRWxlbWVudCB9IGZyb20gJy4vY2ZuLWVsZW1lbnQnO1xuaW1wb3J0IHsgQ2ZuQ3JlYXRpb25Qb2xpY3ksIENmbkRlbGV0aW9uUG9saWN5LCBDZm5VcGRhdGVQb2xpY3kgfSBmcm9tICcuL2Nmbi1yZXNvdXJjZS1wb2xpY3knO1xuaW1wb3J0IHsgQ29uc3RydWN0LCBJQ29uc3RydWN0IH0gZnJvbSAnLi9jb25zdHJ1Y3QnO1xuaW1wb3J0IHsgQ2ZuUmVmZXJlbmNlIH0gZnJvbSAnLi9wcml2YXRlL2Nmbi1yZWZlcmVuY2UnO1xuaW1wb3J0IHsgUmVtb3ZhbFBvbGljeSwgUmVtb3ZhbFBvbGljeU9wdGlvbnMgfSBmcm9tICcuL3JlbW92YWwtcG9saWN5JztcbmltcG9ydCB7IElSZXNvbHZhYmxlIH0gZnJvbSAnLi9yZXNvbHZhYmxlJztcbmltcG9ydCB7IFRhZ01hbmFnZXIgfSBmcm9tICcuL3RhZy1tYW5hZ2VyJztcbmltcG9ydCB7IGNhcGl0YWxpemVQcm9wZXJ0eU5hbWVzLCBpZ25vcmVFbXB0eSwgUG9zdFJlc29sdmVUb2tlbiB9IGZyb20gJy4vdXRpbCc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ2ZuUmVzb3VyY2VQcm9wcyB7XG4gIC8qKlxuICAgKiBDbG91ZEZvcm1hdGlvbiByZXNvdXJjZSB0eXBlIChlLmcuIGBBV1M6OlMzOjpCdWNrZXRgKS5cbiAgICovXG4gIHJlYWRvbmx5IHR5cGU6IHN0cmluZztcblxuICAvKipcbiAgICogUmVzb3VyY2UgcHJvcGVydGllcy5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBObyByZXNvdXJjZSBwcm9wZXJ0aWVzLlxuICAgKi9cbiAgcmVhZG9ubHkgcHJvcGVydGllcz86IHsgW25hbWU6IHN0cmluZ106IGFueSB9O1xufVxuXG4vKipcbiAqIFJlcHJlc2VudHMgYSBDbG91ZEZvcm1hdGlvbiByZXNvdXJjZS5cbiAqL1xuZXhwb3J0IGNsYXNzIENmblJlc291cmNlIGV4dGVuZHMgQ2ZuUmVmRWxlbWVudCB7XG4gIC8qKlxuICAgKiBDaGVjayB3aGV0aGVyIHRoZSBnaXZlbiBjb25zdHJ1Y3QgaXMgYSBDZm5SZXNvdXJjZVxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBpc0NmblJlc291cmNlKGNvbnN0cnVjdDogSUNvbnN0cnVjdCk6IGNvbnN0cnVjdCBpcyBDZm5SZXNvdXJjZSB7XG4gICAgcmV0dXJuIChjb25zdHJ1Y3QgYXMgYW55KS5jZm5SZXNvdXJjZVR5cGUgIT09IHVuZGVmaW5lZDtcbiAgfVxuXG4gIC8vIE1BSU5UQUlORVJTIE5PVEU6IHRoaXMgY2xhc3Mgc2VydmVzIGFzIHRoZSBiYXNlIGNsYXNzIGZvciB0aGUgZ2VuZXJhdGVkIEwxXG4gIC8vIChcIkNGTlwiKSByZXNvdXJjZXMgKHN1Y2ggYXMgYHMzLkNmbkJ1Y2tldGApLiBUaGVzZSByZXNvdXJjZXMgd2lsbCBoYXZlIGFcbiAgLy8gcHJvcGVydHkgZm9yIGVhY2ggQ2xvdWRGb3JtYXRpb24gcHJvcGVydHkgb2YgdGhlIHJlc291cmNlLiBUaGlzIG1lYW5zIHRoYXRcbiAgLy8gaWYgYXQgc29tZSBwb2ludCBpbiB0aGUgZnV0dXJlIGEgcHJvcGVydHkgaXMgaW50cm9kdWNlZCB3aXRoIGEgbmFtZSBzaW1pbGFyXG4gIC8vIHRvIG9uZSBvZiB0aGUgcHJvcGVydGllcyBoZXJlLCBpdCB3aWxsIGJlIFwibWFza2VkXCIgYnkgdGhlIGRlcml2ZWQgY2xhc3MuIFRvXG4gIC8vIHRoYXQgZW5kLCB3ZSBwcmVmaXggYWxsIHByb3BlcnRpZXMgaW4gdGhpcyBjbGFzcyB3aXRoIGBjZm5YeHhgIHdpdGggdGhlXG4gIC8vIGhvcGUgdG8gYXZvaWQgdGhvc2UgY29uZmxpY3RzIGluIHRoZSBmdXR1cmUuXG5cbiAgLyoqXG4gICAqIE9wdGlvbnMgZm9yIHRoaXMgcmVzb3VyY2UsIHN1Y2ggYXMgY29uZGl0aW9uLCB1cGRhdGUgcG9saWN5IGV0Yy5cbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBjZm5PcHRpb25zOiBJQ2ZuUmVzb3VyY2VPcHRpb25zID0ge307XG5cbiAgLyoqXG4gICAqIEFXUyByZXNvdXJjZSB0eXBlLlxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IGNmblJlc291cmNlVHlwZTogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBBV1MgQ2xvdWRGb3JtYXRpb24gcmVzb3VyY2UgcHJvcGVydGllcy5cbiAgICpcbiAgICogVGhpcyBvYmplY3QgaXMgcmV0dXJuZWQgdmlhIGNmblByb3BlcnRpZXNcbiAgICogQGludGVybmFsXG4gICAqL1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgX2NmblByb3BlcnRpZXM6IGFueTtcblxuICAvKipcbiAgICogQW4gb2JqZWN0IHRvIGJlIG1lcmdlZCBvbiB0b3Agb2YgdGhlIGVudGlyZSByZXNvdXJjZSBkZWZpbml0aW9uLlxuICAgKi9cbiAgcHJpdmF0ZSByZWFkb25seSByYXdPdmVycmlkZXM6IGFueSA9IHt9O1xuXG4gIC8qKlxuICAgKiBMb2dpY2FsIElEcyBvZiBkZXBlbmRlbmNpZXMuXG4gICAqXG4gICAqIElzIGZpbGxlZCBkdXJpbmcgcHJlcGFyZSgpLlxuICAgKi9cbiAgcHJpdmF0ZSByZWFkb25seSBkZXBlbmRzT24gPSBuZXcgU2V0PENmblJlc291cmNlPigpO1xuXG4gIC8qKlxuICAgKiBDcmVhdGVzIGEgcmVzb3VyY2UgY29uc3RydWN0LlxuICAgKiBAcGFyYW0gY2ZuUmVzb3VyY2VUeXBlIFRoZSBDbG91ZEZvcm1hdGlvbiB0eXBlIG9mIHRoaXMgcmVzb3VyY2UgKGUuZy4gQVdTOjpEeW5hbW9EQjo6VGFibGUpXG4gICAqL1xuICBjb25zdHJ1Y3RvcihzY29wZTogQ29uc3RydWN0LCBpZDogc3RyaW5nLCBwcm9wczogQ2ZuUmVzb3VyY2VQcm9wcykge1xuICAgIHN1cGVyKHNjb3BlLCBpZCk7XG5cbiAgICBpZiAoIXByb3BzLnR5cGUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignVGhlIGB0eXBlYCBwcm9wZXJ0eSBpcyByZXF1aXJlZCcpO1xuICAgIH1cblxuICAgIHRoaXMuY2ZuUmVzb3VyY2VUeXBlID0gcHJvcHMudHlwZTtcbiAgICB0aGlzLl9jZm5Qcm9wZXJ0aWVzID0gcHJvcHMucHJvcGVydGllcyB8fCB7fTtcblxuICAgIC8vIGlmIGF3czpjZGs6ZW5hYmxlLXBhdGgtbWV0YWRhdGEgaXMgc2V0LCBlbWJlZCB0aGUgY3VycmVudCBjb25zdHJ1Y3Qnc1xuICAgIC8vIHBhdGggaW4gdGhlIENsb3VkRm9ybWF0aW9uIHRlbXBsYXRlLCBzbyBpdCB3aWxsIGJlIHBvc3NpYmxlIHRvIHRyYWNlXG4gICAgLy8gYmFjayB0byB0aGUgYWN0dWFsIGNvbnN0cnVjdCBwYXRoLlxuICAgIGlmICh0aGlzLm5vZGUudHJ5R2V0Q29udGV4dChjeGFwaS5QQVRIX01FVEFEQVRBX0VOQUJMRV9DT05URVhUKSkge1xuICAgICAgdGhpcy5jZm5PcHRpb25zLm1ldGFkYXRhID0ge1xuICAgICAgICBbY3hhcGkuUEFUSF9NRVRBREFUQV9LRVldOiB0aGlzLm5vZGUucGF0aFxuICAgICAgfTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogU2V0cyB0aGUgZGVsZXRpb24gcG9saWN5IG9mIHRoZSByZXNvdXJjZSBiYXNlZCBvbiB0aGUgcmVtb3ZhbCBwb2xpY3kgc3BlY2lmaWVkLlxuICAgKi9cbiAgcHVibGljIGFwcGx5UmVtb3ZhbFBvbGljeShwb2xpY3k6IFJlbW92YWxQb2xpY3kgfCB1bmRlZmluZWQsIG9wdGlvbnM6IFJlbW92YWxQb2xpY3lPcHRpb25zID0ge30pIHtcbiAgICBwb2xpY3kgPSBwb2xpY3kgfHwgb3B0aW9ucy5kZWZhdWx0IHx8IFJlbW92YWxQb2xpY3kuUkVUQUlOO1xuXG4gICAgbGV0IGRlbGV0aW9uUG9saWN5O1xuXG4gICAgc3dpdGNoIChwb2xpY3kpIHtcbiAgICAgIGNhc2UgUmVtb3ZhbFBvbGljeS5ERVNUUk9ZOlxuICAgICAgICBkZWxldGlvblBvbGljeSA9IENmbkRlbGV0aW9uUG9saWN5LkRFTEVURTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgUmVtb3ZhbFBvbGljeS5SRVRBSU46XG4gICAgICAgIGRlbGV0aW9uUG9saWN5ID0gQ2ZuRGVsZXRpb25Qb2xpY3kuUkVUQUlOO1xuICAgICAgICBicmVhaztcblxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBJbnZhbGlkIHJlbW92YWwgcG9saWN5OiAke3BvbGljeX1gKTtcbiAgICB9XG5cbiAgICB0aGlzLmNmbk9wdGlvbnMuZGVsZXRpb25Qb2xpY3kgPSBkZWxldGlvblBvbGljeTtcbiAgICBpZiAob3B0aW9ucy5hcHBseVRvVXBkYXRlUmVwbGFjZVBvbGljeSAhPT0gZmFsc2UpIHtcbiAgICAgIHRoaXMuY2ZuT3B0aW9ucy51cGRhdGVSZXBsYWNlUG9saWN5ID0gZGVsZXRpb25Qb2xpY3k7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgYSB0b2tlbiBmb3IgYW4gcnVudGltZSBhdHRyaWJ1dGUgb2YgdGhpcyByZXNvdXJjZS5cbiAgICogSWRlYWxseSwgdXNlIGdlbmVyYXRlZCBhdHRyaWJ1dGUgYWNjZXNzb3JzIChlLmcuIGByZXNvdXJjZS5hcm5gKSwgYnV0IHRoaXMgY2FuIGJlIHVzZWQgZm9yIGZ1dHVyZSBjb21wYXRpYmlsaXR5XG4gICAqIGluIGNhc2UgdGhlcmUgaXMgbm8gZ2VuZXJhdGVkIGF0dHJpYnV0ZS5cbiAgICogQHBhcmFtIGF0dHJpYnV0ZU5hbWUgVGhlIG5hbWUgb2YgdGhlIGF0dHJpYnV0ZS5cbiAgICovXG4gIHB1YmxpYyBnZXRBdHQoYXR0cmlidXRlTmFtZTogc3RyaW5nKTogSVJlc29sdmFibGUge1xuICAgIHJldHVybiBDZm5SZWZlcmVuY2UuZm9yKHRoaXMsIGF0dHJpYnV0ZU5hbWUpO1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZHMgYW4gb3ZlcnJpZGUgdG8gdGhlIHN5bnRoZXNpemVkIENsb3VkRm9ybWF0aW9uIHJlc291cmNlLiBUbyBhZGQgYVxuICAgKiBwcm9wZXJ0eSBvdmVycmlkZSwgZWl0aGVyIHVzZSBgYWRkUHJvcGVydHlPdmVycmlkZWAgb3IgcHJlZml4IGBwYXRoYCB3aXRoXG4gICAqIFwiUHJvcGVydGllcy5cIiAoaS5lLiBgUHJvcGVydGllcy5Ub3BpY05hbWVgKS5cbiAgICpcbiAgICogQHBhcmFtIHBhdGggIFRoZSBwYXRoIG9mIHRoZSBwcm9wZXJ0eSwgeW91IGNhbiB1c2UgZG90IG5vdGF0aW9uIHRvXG4gICAqICAgICAgICBvdmVycmlkZSB2YWx1ZXMgaW4gY29tcGxleCB0eXBlcy4gQW55IGludGVybWRlZGlhdGUga2V5c1xuICAgKiAgICAgICAgd2lsbCBiZSBjcmVhdGVkIGFzIG5lZWRlZC5cbiAgICogQHBhcmFtIHZhbHVlIFRoZSB2YWx1ZS4gQ291bGQgYmUgcHJpbWl0aXZlIG9yIGNvbXBsZXguXG4gICAqL1xuICBwdWJsaWMgYWRkT3ZlcnJpZGUocGF0aDogc3RyaW5nLCB2YWx1ZTogYW55KSB7XG4gICAgY29uc3QgcGFydHMgPSBwYXRoLnNwbGl0KCcuJyk7XG4gICAgbGV0IGN1cnI6IGFueSA9IHRoaXMucmF3T3ZlcnJpZGVzO1xuXG4gICAgd2hpbGUgKHBhcnRzLmxlbmd0aCA+IDEpIHtcbiAgICAgIGNvbnN0IGtleSA9IHBhcnRzLnNoaWZ0KCkhO1xuXG4gICAgICAvLyBpZiB3ZSBjYW4ndCByZWN1cnNlIGZ1cnRoZXIgb3IgdGhlIHByZXZpb3VzIHZhbHVlIGlzIG5vdCBhblxuICAgICAgLy8gb2JqZWN0IG92ZXJ3cml0ZSBpdCB3aXRoIGFuIG9iamVjdC5cbiAgICAgIGNvbnN0IGlzT2JqZWN0ID0gY3VycltrZXldICE9IG51bGwgJiYgdHlwZW9mKGN1cnJba2V5XSkgPT09ICdvYmplY3QnICYmICFBcnJheS5pc0FycmF5KGN1cnJba2V5XSk7XG4gICAgICBpZiAoIWlzT2JqZWN0KSB7XG4gICAgICAgIGN1cnJba2V5XSA9IHt9O1xuICAgICAgfVxuXG4gICAgICBjdXJyID0gY3VycltrZXldO1xuICAgIH1cblxuICAgIGNvbnN0IGxhc3RLZXkgPSBwYXJ0cy5zaGlmdCgpITtcbiAgICBjdXJyW2xhc3RLZXldID0gdmFsdWU7XG4gIH1cblxuICAvKipcbiAgICogU3ludGFjdGljIHN1Z2FyIGZvciBgYWRkT3ZlcnJpZGUocGF0aCwgdW5kZWZpbmVkKWAuXG4gICAqIEBwYXJhbSBwYXRoIFRoZSBwYXRoIG9mIHRoZSB2YWx1ZSB0byBkZWxldGVcbiAgICovXG4gIHB1YmxpYyBhZGREZWxldGlvbk92ZXJyaWRlKHBhdGg6IHN0cmluZykge1xuICAgIHRoaXMuYWRkT3ZlcnJpZGUocGF0aCwgdW5kZWZpbmVkKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBZGRzIGFuIG92ZXJyaWRlIHRvIGEgcmVzb3VyY2UgcHJvcGVydHkuXG4gICAqXG4gICAqIFN5bnRhY3RpYyBzdWdhciBmb3IgYGFkZE92ZXJyaWRlKFwiUHJvcGVydGllcy48Li4uPlwiLCB2YWx1ZSlgLlxuICAgKlxuICAgKiBAcGFyYW0gcHJvcGVydHlQYXRoIFRoZSBwYXRoIG9mIHRoZSBwcm9wZXJ0eVxuICAgKiBAcGFyYW0gdmFsdWUgVGhlIHZhbHVlXG4gICAqL1xuICBwdWJsaWMgYWRkUHJvcGVydHlPdmVycmlkZShwcm9wZXJ0eVBhdGg6IHN0cmluZywgdmFsdWU6IGFueSkge1xuICAgIHRoaXMuYWRkT3ZlcnJpZGUoYFByb3BlcnRpZXMuJHtwcm9wZXJ0eVBhdGh9YCwgdmFsdWUpO1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZHMgYW4gb3ZlcnJpZGUgdGhhdCBkZWxldGVzIHRoZSB2YWx1ZSBvZiBhIHByb3BlcnR5IGZyb20gdGhlIHJlc291cmNlIGRlZmluaXRpb24uXG4gICAqIEBwYXJhbSBwcm9wZXJ0eVBhdGggVGhlIHBhdGggdG8gdGhlIHByb3BlcnR5LlxuICAgKi9cbiAgcHVibGljIGFkZFByb3BlcnR5RGVsZXRpb25PdmVycmlkZShwcm9wZXJ0eVBhdGg6IHN0cmluZykge1xuICAgIHRoaXMuYWRkUHJvcGVydHlPdmVycmlkZShwcm9wZXJ0eVBhdGgsIHVuZGVmaW5lZCk7XG4gIH1cblxuICAvKipcbiAgICogSW5kaWNhdGVzIHRoYXQgdGhpcyByZXNvdXJjZSBkZXBlbmRzIG9uIGFub3RoZXIgcmVzb3VyY2UgYW5kIGNhbm5vdCBiZSBwcm92aXNpb25lZFxuICAgKiB1bmxlc3MgdGhlIG90aGVyIHJlc291cmNlIGhhcyBiZWVuIHN1Y2Nlc3NmdWxseSBwcm92aXNpb25lZC5cbiAgICovXG4gIHB1YmxpYyBhZGREZXBlbmRzT24ocmVzb3VyY2U6IENmblJlc291cmNlKSB7XG4gICAgdGhpcy5kZXBlbmRzT24uYWRkKHJlc291cmNlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJucyBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGlzIHJlc291cmNlXG4gICAqL1xuICBwdWJsaWMgdG9TdHJpbmcoKSB7XG4gICAgcmV0dXJuIGAke3N1cGVyLnRvU3RyaW5nKCl9IFske3RoaXMuY2ZuUmVzb3VyY2VUeXBlfV1gO1xuICB9XG5cbiAgLyoqXG4gICAqIEVtaXRzIENsb3VkRm9ybWF0aW9uIGZvciB0aGlzIHJlc291cmNlLlxuICAgKiBAaW50ZXJuYWxcbiAgICovXG4gIHB1YmxpYyBfdG9DbG91ZEZvcm1hdGlvbigpOiBvYmplY3Qge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXQgPSB7XG4gICAgICAgIFJlc291cmNlczoge1xuICAgICAgICAgIC8vIFBvc3QtUmVzb2x2ZSBvcGVyYXRpb24gc2luY2Ugb3RoZXJ3aXNlIGRlZXBNZXJnZSBpcyBnb2luZyB0byBtaXggdmFsdWVzIGludG9cbiAgICAgICAgICAvLyB0aGUgVG9rZW4gb2JqZWN0cyByZXR1cm5lZCBieSBpZ25vcmVFbXB0eS5cbiAgICAgICAgICBbdGhpcy5sb2dpY2FsSWRdOiBuZXcgUG9zdFJlc29sdmVUb2tlbih7XG4gICAgICAgICAgICBUeXBlOiB0aGlzLmNmblJlc291cmNlVHlwZSxcbiAgICAgICAgICAgIFByb3BlcnRpZXM6IGlnbm9yZUVtcHR5KHRoaXMuY2ZuUHJvcGVydGllcyksXG4gICAgICAgICAgICBEZXBlbmRzT246IGlnbm9yZUVtcHR5KHJlbmRlckRlcGVuZHNPbih0aGlzLmRlcGVuZHNPbikpLFxuICAgICAgICAgICAgQ3JlYXRpb25Qb2xpY3k6ICBjYXBpdGFsaXplUHJvcGVydHlOYW1lcyh0aGlzLCByZW5kZXJDcmVhdGlvblBvbGljeSh0aGlzLmNmbk9wdGlvbnMuY3JlYXRpb25Qb2xpY3kpKSxcbiAgICAgICAgICAgIFVwZGF0ZVBvbGljeTogY2FwaXRhbGl6ZVByb3BlcnR5TmFtZXModGhpcywgdGhpcy5jZm5PcHRpb25zLnVwZGF0ZVBvbGljeSksXG4gICAgICAgICAgICBVcGRhdGVSZXBsYWNlUG9saWN5OiBjYXBpdGFsaXplUHJvcGVydHlOYW1lcyh0aGlzLCB0aGlzLmNmbk9wdGlvbnMudXBkYXRlUmVwbGFjZVBvbGljeSksXG4gICAgICAgICAgICBEZWxldGlvblBvbGljeTogY2FwaXRhbGl6ZVByb3BlcnR5TmFtZXModGhpcywgdGhpcy5jZm5PcHRpb25zLmRlbGV0aW9uUG9saWN5KSxcbiAgICAgICAgICAgIE1ldGFkYXRhOiBpZ25vcmVFbXB0eSh0aGlzLmNmbk9wdGlvbnMubWV0YWRhdGEpLFxuICAgICAgICAgICAgQ29uZGl0aW9uOiB0aGlzLmNmbk9wdGlvbnMuY29uZGl0aW9uICYmIHRoaXMuY2ZuT3B0aW9ucy5jb25kaXRpb24ubG9naWNhbElkXG4gICAgICAgICAgfSwgcHJvcHMgPT4ge1xuICAgICAgICAgICAgY29uc3QgcmVuZGVyZWRQcm9wcyA9IHRoaXMucmVuZGVyUHJvcGVydGllcyhwcm9wcy5Qcm9wZXJ0aWVzIHx8IHt9KTtcbiAgICAgICAgICAgIHByb3BzLlByb3BlcnRpZXMgPSByZW5kZXJlZFByb3BzICYmIChPYmplY3QudmFsdWVzKHJlbmRlcmVkUHJvcHMpLmZpbmQodiA9PiAhIXYpID8gcmVuZGVyZWRQcm9wcyA6IHVuZGVmaW5lZCk7XG4gICAgICAgICAgICByZXR1cm4gZGVlcE1lcmdlKHByb3BzLCB0aGlzLnJhd092ZXJyaWRlcyk7XG4gICAgICAgICAgfSlcbiAgICAgICAgfVxuICAgICAgfTtcbiAgICAgIHJldHVybiByZXQ7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgLy8gQ2hhbmdlIG1lc3NhZ2VcbiAgICAgIGUubWVzc2FnZSA9IGBXaGlsZSBzeW50aGVzaXppbmcgJHt0aGlzLm5vZGUucGF0aH06ICR7ZS5tZXNzYWdlfWA7XG4gICAgICAvLyBBZGp1c3Qgc3RhY2sgdHJhY2UgKG1ha2UgaXQgbG9vayBsaWtlIG5vZGUgYnVpbHQgaXQsIHRvby4uLilcbiAgICAgIGNvbnN0IHRyYWNlID0gdGhpcy5jcmVhdGlvblN0YWNrO1xuICAgICAgaWYgKHRyYWNlKSB7XG4gICAgICAgIGNvbnN0IGNyZWF0aW9uU3RhY2sgPSBbJy0tLSByZXNvdXJjZSBjcmVhdGVkIGF0IC0tLScsIC4uLnRyYWNlXS5qb2luKCdcXG4gIGF0ICcpO1xuICAgICAgICBjb25zdCBwcm9ibGVtVHJhY2UgPSBlLnN0YWNrLnN1YnN0cihlLnN0YWNrLmluZGV4T2YoZS5tZXNzYWdlKSArIGUubWVzc2FnZS5sZW5ndGgpO1xuICAgICAgICBlLnN0YWNrID0gYCR7ZS5tZXNzYWdlfVxcbiAgJHtjcmVhdGlvblN0YWNrfVxcbiAgLS0tIHByb2JsZW0gZGlzY292ZXJlZCBhdCAtLS0ke3Byb2JsZW1UcmFjZX1gO1xuICAgICAgfVxuXG4gICAgICAvLyBSZS10aHJvd1xuICAgICAgdGhyb3cgZTtcbiAgICB9XG5cbiAgICAvLyByZXR1cm5zIHRoZSBzZXQgb2YgbG9naWNhbCBJRCAodG9rZW5zKSB0aGlzIHJlc291cmNlIGRlcGVuZHMgb25cbiAgICAvLyBzb3J0ZWQgYnkgY29uc3RydWN0IHBhdGhzIHRvIGVuc3VyZSB0ZXN0IGRldGVybWluaXNtXG4gICAgZnVuY3Rpb24gcmVuZGVyRGVwZW5kc09uKGRlcGVuZHNPbjogU2V0PENmblJlc291cmNlPikge1xuICAgICAgcmV0dXJuIEFycmF5XG4gICAgICAgIC5mcm9tKGRlcGVuZHNPbilcbiAgICAgICAgLnNvcnQoKHgsIHkpID0+IHgubm9kZS5wYXRoLmxvY2FsZUNvbXBhcmUoeS5ub2RlLnBhdGgpKVxuICAgICAgICAubWFwKHIgPT4gci5sb2dpY2FsSWQpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHJlbmRlckNyZWF0aW9uUG9saWN5KHBvbGljeTogQ2ZuQ3JlYXRpb25Qb2xpY3kgfCB1bmRlZmluZWQpOiBhbnkge1xuICAgICAgaWYgKCFwb2xpY3kpIHsgcmV0dXJuIHVuZGVmaW5lZDsgfVxuICAgICAgY29uc3QgcmVzdWx0OiBhbnkgPSB7IC4uLnBvbGljeSB9O1xuICAgICAgaWYgKHBvbGljeS5yZXNvdXJjZVNpZ25hbCAmJiBwb2xpY3kucmVzb3VyY2VTaWduYWwudGltZW91dCkge1xuICAgICAgICByZXN1bHQucmVzb3VyY2VTaWduYWwgPSBwb2xpY3kucmVzb3VyY2VTaWduYWw7XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cbiAgfVxuXG4gIHByb3RlY3RlZCBnZXQgY2ZuUHJvcGVydGllcygpOiB7IFtrZXk6IHN0cmluZ106IGFueSB9IHtcbiAgICBjb25zdCB0YWdzID0gVGFnTWFuYWdlci5pc1RhZ2dhYmxlKHRoaXMpID8gdGhpcy50YWdzLnJlbmRlclRhZ3MoKSA6IHt9O1xuICAgIHJldHVybiBkZWVwTWVyZ2UodGhpcy5fY2ZuUHJvcGVydGllcyB8fCB7fSwge3RhZ3N9KTtcbiAgfVxuXG4gIHByb3RlY3RlZCByZW5kZXJQcm9wZXJ0aWVzKHByb3BzOiB7W2tleTogc3RyaW5nXTogYW55fSk6IHsgW2tleTogc3RyaW5nXTogYW55IH0ge1xuICAgIHJldHVybiBwcm9wcztcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm4gcHJvcGVydGllcyBtb2RpZmllZCBhZnRlciBpbml0aWF0aW9uXG4gICAqXG4gICAqIFJlc291cmNlcyB0aGF0IGV4cG9zZSBtdXRhYmxlIHByb3BlcnRpZXMgc2hvdWxkIG92ZXJyaWRlIHRoaXMgZnVuY3Rpb24gdG9cbiAgICogY29sbGVjdCBhbmQgcmV0dXJuIHRoZSBwcm9wZXJ0aWVzIG9iamVjdCBmb3IgdGhpcyByZXNvdXJjZS5cbiAgICovXG4gIHByb3RlY3RlZCBnZXQgdXBkYXRlZFByb3Blcml0ZXMoKTogeyBba2V5OiBzdHJpbmddOiBhbnkgfSB7XG4gICAgcmV0dXJuIHRoaXMuX2NmblByb3BlcnRpZXM7XG4gIH1cblxuICBwcm90ZWN0ZWQgdmFsaWRhdGVQcm9wZXJ0aWVzKF9wcm9wZXJ0aWVzOiBhbnkpIHtcbiAgICAvLyBOb3RoaW5nXG4gIH1cbn1cblxuZXhwb3J0IGVudW0gVGFnVHlwZSB7XG4gIFNUQU5EQVJEID0gJ1N0YW5kYXJkVGFnJyxcbiAgQVVUT1NDQUxJTkdfR1JPVVAgPSAnQXV0b1NjYWxpbmdHcm91cFRhZycsXG4gIE1BUCA9ICdTdHJpbmdUb1N0cmluZ01hcCcsXG4gIEtFWV9WQUxVRSA9ICdLZXlWYWx1ZScsXG4gIE5PVF9UQUdHQUJMRSA9ICdOb3RUYWdnYWJsZScsXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgSUNmblJlc291cmNlT3B0aW9ucyB7XG4gIC8qKlxuICAgKiBBIGNvbmRpdGlvbiB0byBhc3NvY2lhdGUgd2l0aCB0aGlzIHJlc291cmNlLiBUaGlzIG1lYW5zIHRoYXQgb25seSBpZiB0aGUgY29uZGl0aW9uIGV2YWx1YXRlcyB0byAndHJ1ZScgd2hlbiB0aGUgc3RhY2tcbiAgICogaXMgZGVwbG95ZWQsIHRoZSByZXNvdXJjZSB3aWxsIGJlIGluY2x1ZGVkLiBUaGlzIGlzIHByb3ZpZGVkIHRvIGFsbG93IENESyBwcm9qZWN0cyB0byBwcm9kdWNlIGxlZ2FjeSB0ZW1wbGF0ZXMsIGJ1dCBub3JhbWxseVxuICAgKiB0aGVyZSBpcyBubyBuZWVkIHRvIHVzZSBpdCBpbiBDREsgcHJvamVjdHMuXG4gICAqL1xuICBjb25kaXRpb24/OiBDZm5Db25kaXRpb247XG5cbiAgLyoqXG4gICAqIEFzc29jaWF0ZSB0aGUgQ3JlYXRpb25Qb2xpY3kgYXR0cmlidXRlIHdpdGggYSByZXNvdXJjZSB0byBwcmV2ZW50IGl0cyBzdGF0dXMgZnJvbSByZWFjaGluZyBjcmVhdGUgY29tcGxldGUgdW50aWxcbiAgICogQVdTIENsb3VkRm9ybWF0aW9uIHJlY2VpdmVzIGEgc3BlY2lmaWVkIG51bWJlciBvZiBzdWNjZXNzIHNpZ25hbHMgb3IgdGhlIHRpbWVvdXQgcGVyaW9kIGlzIGV4Y2VlZGVkLiBUbyBzaWduYWwgYVxuICAgKiByZXNvdXJjZSwgeW91IGNhbiB1c2UgdGhlIGNmbi1zaWduYWwgaGVscGVyIHNjcmlwdCBvciBTaWduYWxSZXNvdXJjZSBBUEkuIEFXUyBDbG91ZEZvcm1hdGlvbiBwdWJsaXNoZXMgdmFsaWQgc2lnbmFsc1xuICAgKiB0byB0aGUgc3RhY2sgZXZlbnRzIHNvIHRoYXQgeW91IHRyYWNrIHRoZSBudW1iZXIgb2Ygc2lnbmFscyBzZW50LlxuICAgKi9cbiAgY3JlYXRpb25Qb2xpY3k/OiBDZm5DcmVhdGlvblBvbGljeTtcblxuICAvKipcbiAgICogV2l0aCB0aGUgRGVsZXRpb25Qb2xpY3kgYXR0cmlidXRlIHlvdSBjYW4gcHJlc2VydmUgb3IgKGluIHNvbWUgY2FzZXMpIGJhY2t1cCBhIHJlc291cmNlIHdoZW4gaXRzIHN0YWNrIGlzIGRlbGV0ZWQuXG4gICAqIFlvdSBzcGVjaWZ5IGEgRGVsZXRpb25Qb2xpY3kgYXR0cmlidXRlIGZvciBlYWNoIHJlc291cmNlIHRoYXQgeW91IHdhbnQgdG8gY29udHJvbC4gSWYgYSByZXNvdXJjZSBoYXMgbm8gRGVsZXRpb25Qb2xpY3lcbiAgICogYXR0cmlidXRlLCBBV1MgQ2xvdWRGb3JtYXRpb24gZGVsZXRlcyB0aGUgcmVzb3VyY2UgYnkgZGVmYXVsdC4gTm90ZSB0aGF0IHRoaXMgY2FwYWJpbGl0eSBhbHNvIGFwcGxpZXMgdG8gdXBkYXRlIG9wZXJhdGlvbnNcbiAgICogdGhhdCBsZWFkIHRvIHJlc291cmNlcyBiZWluZyByZW1vdmVkLlxuICAgKi9cbiAgZGVsZXRpb25Qb2xpY3k/OiBDZm5EZWxldGlvblBvbGljeTtcblxuICAvKipcbiAgICogVXNlIHRoZSBVcGRhdGVQb2xpY3kgYXR0cmlidXRlIHRvIHNwZWNpZnkgaG93IEFXUyBDbG91ZEZvcm1hdGlvbiBoYW5kbGVzIHVwZGF0ZXMgdG8gdGhlIEFXUzo6QXV0b1NjYWxpbmc6OkF1dG9TY2FsaW5nR3JvdXBcbiAgICogcmVzb3VyY2UuIEFXUyBDbG91ZEZvcm1hdGlvbiBpbnZva2VzIG9uZSBvZiB0aHJlZSB1cGRhdGUgcG9saWNpZXMgZGVwZW5kaW5nIG9uIHRoZSB0eXBlIG9mIGNoYW5nZSB5b3UgbWFrZSBvciB3aGV0aGVyIGFcbiAgICogc2NoZWR1bGVkIGFjdGlvbiBpcyBhc3NvY2lhdGVkIHdpdGggdGhlIEF1dG8gU2NhbGluZyBncm91cC5cbiAgICovXG4gIHVwZGF0ZVBvbGljeT86IENmblVwZGF0ZVBvbGljeTtcblxuICAvKipcbiAgICogVXNlIHRoZSBVcGRhdGVSZXBsYWNlUG9saWN5IGF0dHJpYnV0ZSB0byByZXRhaW4gb3IgKGluIHNvbWUgY2FzZXMpIGJhY2t1cCB0aGUgZXhpc3RpbmcgcGh5c2ljYWwgaW5zdGFuY2Ugb2YgYSByZXNvdXJjZVxuICAgKiB3aGVuIGl0IGlzIHJlcGxhY2VkIGR1cmluZyBhIHN0YWNrIHVwZGF0ZSBvcGVyYXRpb24uXG4gICAqL1xuICB1cGRhdGVSZXBsYWNlUG9saWN5PzogQ2ZuRGVsZXRpb25Qb2xpY3k7XG5cbiAgLyoqXG4gICAqIE1ldGFkYXRhIGFzc29jaWF0ZWQgd2l0aCB0aGUgQ2xvdWRGb3JtYXRpb24gcmVzb3VyY2UuIFRoaXMgaXMgbm90IHRoZSBzYW1lIGFzIHRoZSBjb25zdHJ1Y3QgbWV0YWRhdGEgd2hpY2ggY2FuIGJlIGFkZGVkXG4gICAqIHVzaW5nIGNvbnN0cnVjdC5hZGRNZXRhZGF0YSgpLCBidXQgd291bGQgbm90IGFwcGVhciBpbiB0aGUgQ2xvdWRGb3JtYXRpb24gdGVtcGxhdGUgYXV0b21hdGljYWxseS5cbiAgICovXG4gIG1ldGFkYXRhPzogeyBba2V5OiBzdHJpbmddOiBhbnkgfTtcbn1cblxuLyoqXG4gKiBNZXJnZXMgYHNvdXJjZWAgaW50byBgdGFyZ2V0YCwgb3ZlcnJpZGluZyBhbnkgZXhpc3RpbmcgdmFsdWVzLlxuICogYG51bGxgcyB3aWxsIGNhdXNlIGEgdmFsdWUgdG8gYmUgZGVsZXRlZC5cbiAqL1xuZnVuY3Rpb24gZGVlcE1lcmdlKHRhcmdldDogYW55LCAuLi5zb3VyY2VzOiBhbnlbXSkge1xuICBmb3IgKGNvbnN0IHNvdXJjZSBvZiBzb3VyY2VzKSB7XG4gICAgaWYgKHR5cGVvZihzb3VyY2UpICE9PSAnb2JqZWN0JyB8fCB0eXBlb2YodGFyZ2V0KSAhPT0gJ29iamVjdCcpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCB1c2FnZS4gQm90aCBzb3VyY2UgKCR7SlNPTi5zdHJpbmdpZnkoc291cmNlKX0pIGFuZCB0YXJnZXQgKCR7SlNPTi5zdHJpbmdpZnkodGFyZ2V0KX0pIG11c3QgYmUgb2JqZWN0c2ApO1xuICAgIH1cblxuICAgIGZvciAoY29uc3Qga2V5IG9mIE9iamVjdC5rZXlzKHNvdXJjZSkpIHtcbiAgICAgIGNvbnN0IHZhbHVlID0gc291cmNlW2tleV07XG4gICAgICBpZiAodHlwZW9mKHZhbHVlKSA9PT0gJ29iamVjdCcgJiYgdmFsdWUgIT0gbnVsbCAmJiAhQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHtcbiAgICAgICAgLy8gaWYgdGhlIHZhbHVlIGF0IHRoZSB0YXJnZXQgaXMgbm90IGFuIG9iamVjdCwgb3ZlcnJpZGUgaXQgd2l0aCBhblxuICAgICAgICAvLyBvYmplY3Qgc28gd2UgY2FuIGNvbnRpbnVlIHRoZSByZWN1cnNpb25cbiAgICAgICAgaWYgKHR5cGVvZih0YXJnZXRba2V5XSkgIT09ICdvYmplY3QnKSB7XG4gICAgICAgICAgdGFyZ2V0W2tleV0gPSB7fTtcbiAgICAgICAgfVxuXG4gICAgICAgIGRlZXBNZXJnZSh0YXJnZXRba2V5XSwgdmFsdWUpO1xuXG4gICAgICAgIC8vIGlmIHRoZSByZXN1bHQgb2YgdGhlIG1lcmdlIGlzIGFuIGVtcHR5IG9iamVjdCwgaXQncyBiZWNhdXNlIHRoZVxuICAgICAgICAvLyBldmVudHVhbCB2YWx1ZSB3ZSBhc3NpZ25lZCBpcyBgdW5kZWZpbmVkYCwgYW5kIHRoZXJlIGFyZSBub1xuICAgICAgICAvLyBzaWJsaW5nIGNvbmNyZXRlIHZhbHVlcyBhbG9uZ3NpZGUsIHNvIHdlIGNhbiBkZWxldGUgdGhpcyB0cmVlLlxuICAgICAgICBjb25zdCBvdXRwdXQgPSB0YXJnZXRba2V5XTtcbiAgICAgICAgaWYgKHR5cGVvZihvdXRwdXQpID09PSAnb2JqZWN0JyAmJiBPYmplY3Qua2V5cyhvdXRwdXQpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgIGRlbGV0ZSB0YXJnZXRba2V5XTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmICh2YWx1ZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGRlbGV0ZSB0YXJnZXRba2V5XTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRhcmdldFtrZXldID0gdmFsdWU7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHRhcmdldDtcbn1cbiJdfQ==