UNPKG

aws-cdk-neuronx-patterns

Version:
129 lines 24.3 kB
"use strict"; var _a; Object.defineProperty(exports, "__esModule", { value: true }); exports.NeuronxCompilerBase = void 0; const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti"); const aws_cdk_lib_1 = require("aws-cdk-lib"); const batch = require("aws-cdk-lib/aws-batch"); const aws_iam_1 = require("aws-cdk-lib/aws-iam"); const aws_lambda_1 = require("aws-cdk-lib/aws-lambda"); const custom_resources_1 = require("aws-cdk-lib/custom-resources"); const constructs_1 = require("constructs"); const path_1 = require("path"); /** * Abstract base class for Neuronx compilers. * Provides the common orchestration logic (Lambda, CustomResource, WaitCondition) * while subclasses define how to create the Batch compute environment and job definition. */ class NeuronxCompilerBase extends constructs_1.Construct { constructor(scope, id, props) { super(scope, id); this.model = props.model; this.bucket = props.bucket; this.artifactS3Prefix = props.artifactS3Prefix; this.weightSize = aws_cdk_lib_1.Size.gibibytes(props.model.options.parameters.toBillion() * 2.5); this.neuronxInstanceType = props.neuronxInstanceType; const { computeEnvironment, instanceRole } = this.createComputeEnvironment(props); const jobDefinition = this.createJobDefinition(props); const jobQueue = this.createJobQueue(computeEnvironment); props.model.bucket?.grantRead(instanceRole); props.bucket.grantReadWrite(instanceRole); const jobSubmitFunction = new aws_lambda_1.SingletonFunction(this, "JobSubmitFunction", { code: aws_lambda_1.Code.fromAsset((0, path_1.join)(__dirname, "private/await-compile-job")), handler: "index.onEvent", runtime: aws_lambda_1.Runtime.NODEJS_LATEST, uuid: "1361f469-5c92-4c46-9e11-5d1dbf925bac", environment: { JOB_DEFINITION_ARN: jobDefinition.jobDefinitionArn, JOB_QUEUE_ARN: jobQueue.jobQueueArn, }, }); aws_iam_1.Grant.addToPrincipal({ resourceArns: [jobDefinition.jobDefinitionArn, jobQueue.jobQueueArn], grantee: jobSubmitFunction, actions: ["batch:SubmitJob"], }); const jobMonitoringFunction = new aws_lambda_1.SingletonFunction(this, "JobMonitoringFunction", { code: aws_lambda_1.Code.fromAsset((0, path_1.join)(__dirname, "private/await-compile-job")), handler: "index.isComplete", runtime: aws_lambda_1.Runtime.NODEJS_LATEST, uuid: "df16dba8-5f77-480c-a6ad-cfdf74c3de62", environment: { ARTIFACT_S3_PREFIX: props.artifactS3Prefix, }, }); aws_iam_1.Grant.addToPrincipal({ resourceArns: ["*"], grantee: jobMonitoringFunction, actions: ["batch:DescribeJobs"], }); const provider = new custom_resources_1.Provider(this, "CompileJobProvider", { onEventHandler: jobSubmitFunction, isCompleteHandler: jobMonitoringFunction, queryInterval: aws_cdk_lib_1.Duration.minutes(1), totalTimeout: aws_cdk_lib_1.Duration.hours(12), }); this.entrypoint = new aws_lambda_1.SingletonFunction(this, "JobEntrypointFunction", { code: aws_lambda_1.Code.fromAsset((0, path_1.join)(__dirname, "private/await-compile-job")), handler: "index.entrypoint", environment: { PROVIDER_ARN: provider.serviceToken, }, timeout: aws_cdk_lib_1.Duration.minutes(15), runtime: aws_lambda_1.Runtime.NODEJS_LATEST, uuid: "f6e66997-5042-4df1-8781-bd68b3ac5313", }); aws_lambda_1.Function.fromFunctionArn(this, "ProviderFunction", provider.serviceToken).grantInvoke(this.entrypoint); } createJobQueue(computeEnvironment) { return new batch.JobQueue(this, "JobQueue", { computeEnvironments: [ { computeEnvironment, order: 1, }, ], jobStateTimeLimitActions: [ { state: batch.JobStateTimeLimitActionsState.RUNNABLE, reason: batch.JobStateTimeLimitActionsReason.JOB_RESOURCE_REQUIREMENT, maxTime: aws_cdk_lib_1.Duration.minutes(10), action: batch.JobStateTimeLimitActionsAction.CANCEL, }, ], }); } compile() { if (this.compiledModel) { return this.compiledModel; } const waitConditionHandle = new aws_cdk_lib_1.CfnWaitConditionHandle(this, `WaitConditionHandle${this.artifactS3Prefix}`); const compileJob = new aws_cdk_lib_1.CustomResource(this, "NeuronxCompile", { serviceToken: this.entrypoint.functionArn, resourceType: "Custom::NeuronxCompile", properties: { waitConditionCallbackURL: waitConditionHandle.ref, }, }); const wait = new aws_cdk_lib_1.CfnWaitCondition(this, `WaitCondition${this.artifactS3Prefix}`, { count: 1, timeout: aws_cdk_lib_1.Duration.hours(12).toSeconds().toString(), handle: waitConditionHandle.ref, }); wait.node.addDependency(compileJob); const s3Prefix = aws_cdk_lib_1.Fn.select(3, aws_cdk_lib_1.Fn.split('"', wait.attrData.toString())); this.compiledModel = { modelName: this.model.modelName, recommendedInstanceType: this.neuronxInstanceType, bucket: this.bucket, s3Prefix, s3Uri: this.bucket.s3UrlForObject(s3Prefix), weightSize: this.weightSize, }; return this.compiledModel; } } exports.NeuronxCompilerBase = NeuronxCompilerBase; _a = JSII_RTTI_SYMBOL_1; NeuronxCompilerBase[_a] = { fqn: "aws-cdk-neuronx-patterns.NeuronxCompilerBase", version: "0.3.0" }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmV1cm9ueC1jb21waWxlci1iYXNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2Jhc2UvbmV1cm9ueC1jb21waWxlci9uZXVyb254LWNvbXBpbGVyLWJhc2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSw2Q0FPcUI7QUFDckIsK0NBQStDO0FBRy9DLGlEQUFtRDtBQUNuRCx1REFLZ0M7QUFFaEMsbUVBQXdEO0FBQ3hELDJDQUF1QztBQUN2QywrQkFBNEI7QUFxSTVCOzs7O0dBSUc7QUFDSCxNQUFzQixtQkFDcEIsU0FBUSxzQkFBUztJQVdqQixZQUFZLEtBQWdCLEVBQUUsRUFBVSxFQUFFLEtBQStCO1FBQ3ZFLEtBQUssQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFFakIsSUFBSSxDQUFDLEtBQUssR0FBRyxLQUFLLENBQUMsS0FBSyxDQUFDO1FBQ3pCLElBQUksQ0FBQyxNQUFNLEdBQUcsS0FBSyxDQUFDLE1BQU0sQ0FBQztRQUMzQixJQUFJLENBQUMsZ0JBQWdCLEdBQUcsS0FBSyxDQUFDLGdCQUFnQixDQUFDO1FBQy9DLElBQUksQ0FBQyxVQUFVLEdBQUcsa0JBQUksQ0FBQyxTQUFTLENBQzlCLEtBQUssQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxTQUFTLEVBQUUsR0FBRyxHQUFHLENBQ2pELENBQUM7UUFDRixJQUFJLENBQUMsbUJBQW1CLEdBQUcsS0FBSyxDQUFDLG1CQUFtQixDQUFDO1FBRXJELE1BQU0sRUFBRSxrQkFBa0IsRUFBRSxZQUFZLEVBQUUsR0FDeEMsSUFBSSxDQUFDLHdCQUF3QixDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ3ZDLE1BQU0sYUFBYSxHQUFHLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUN0RCxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsY0FBYyxDQUFDLGtCQUFrQixDQUFDLENBQUM7UUFFekQsS0FBSyxDQUFD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QVUsQ0FBQyxDQUFDO1FBQ3BDLE1BQU0sUUFBUSxHQUFHLGdCQUFFLENBQUMsTUFBTSxDQUFDLENBQUMsRUFBRSxnQkFBRSxDQUFDLEtBQUssQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFFdkUsSUFBSSxDQUFDLGFBQWEsR0FBRztZQUNuQixTQUFTLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxTQUFTO1lBQy9CLHVCQUF1QixFQUFFLElBQUksQ0FBQyxtQkFBbUI7WUFDakQsTUFBTSxFQUFFLElBQUksQ0FBQyxNQUFNO1lBQ25CLFFBQVE7WUFDUixLQUFLLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxjQUFjLENBQUMsUUFBUSxDQUFDO1lBQzNDLFVBQVUsRUFBRSxJQUFJLENBQUMsVUFBVTtTQUM1QixDQUFDO1FBQ0YsT0FBTyxJQUFJLENBQUMsYUFBYSxDQUFDO0lBQzVCLENBQUM7O0FBaEtILGtEQWlLQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIENmbldhaXRDb25kaXRpb24sXG4gIENmbldhaXRDb25kaXRpb25IYW5kbGUsXG4gIEN1c3RvbVJlc291cmNlLFxuICBEdXJhdGlvbixcbiAgRm4sXG4gIFNpemUsXG59IGZyb20gXCJhd3MtY2RrLWxpYlwiO1xuaW1wb3J0ICogYXMgYmF0Y2ggZnJvbSBcImF3cy1jZGstbGliL2F3cy1iYXRjaFwiO1xuaW1wb3J0IHsgSVZwYywgU3VibmV0U2VsZWN0aW9uIH0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1lYzJcIjtcbmltcG9ydCB7IENvbnRhaW5lckltYWdlIH0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1lY3NcIjtcbmltcG9ydCB7IEdyYW50LCBJUm9sZSB9IGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtaWFtXCI7XG5pbXBvcnQge1xuICBDb2RlLFxuICBGdW5jdGlvbixcbiAgUnVudGltZSxcbiAgU2luZ2xldG9uRnVuY3Rpb24sXG59IGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtbGFtYmRhXCI7XG5pbXBvcnQgeyBJQnVja2V0IH0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1zM1wiO1xuaW1wb3J0IHsgUHJvdmlkZXIgfSBmcm9tIFwiYXdzLWNkay1saWIvY3VzdG9tLXJlc291cmNlc1wiO1xuaW1wb3J0IHsgQ29uc3RydWN0IH0gZnJvbSBcImNvbnN0cnVjdHNcIjtcbmltcG9ydCB7IGpvaW4gfSBmcm9tIFwicGF0aFwiO1xuaW1wb3J0IHsgSU5ldXJvbnhJbnN0YW5jZVR5cGUsIE1vZGVsIH0gZnJvbSBcIi4uL25ldXJvbnhcIjtcblxuLyoqXG4gKiBDb21waWxlIHJ1bnRpbWUuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgSU5ldXJvbnhDb250YWluZXJJbWFnZSB7XG4gIC8qKlxuICAgKiBBbiBpbWFnZSBvZiB0aGUgY29udGFpbmVyIHdoZXJlIHRoZSBjb21waWxlIGpvYiBpcyBleGVjdXRlZC5cbiAgICovXG4gIHJlYWRvbmx5IGltYWdlOiBDb250YWluZXJJbWFnZTtcbiAgLyoqXG4gICAqIE5ldXJvbnggdmVyc2lvbiBpbmNsdWRlZCBpbiBjb250YWluZXIgaW1hZ2UuXG4gICAqL1xuICByZWFkb25seSBuZXVyb25TZGtWZXJzaW9uOiBzdHJpbmc7XG59XG5cbi8qKlxuICogVGhlIG1vZGVsIGNvbXBpbGVkIGJ5IE5ldXJvbnggY29tcGlsZXIuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgTmV1cm9ueENvbXBpbGVkTW9kZWwge1xuICAvKipcbiAgICogVGhlIHJlY29tbWVuZGVkIE5ldXJvbiBpbnN0YW5jZSB0eXBlIGZvciBydW5uaW5nIGluZmVyZW5jZSB3aXRoIHRoaXMgY29tcGlsZWQgbW9kZWwuXG4gICAqL1xuICByZWFkb25seSByZWNvbW1lbmRlZEluc3RhbmNlVHlwZTogSU5ldXJvbnhJbnN0YW5jZVR5cGU7XG4gIC8qKlxuICAgKiBUaGUgYnVja2V0IHRvIHVwbG9hZCBjb21waWxlZCBhcnRpZmFjdHMuXG4gICAqL1xuICByZWFkb25seSBidWNrZXQ6IElCdWNrZXQ7XG4gIC8qKlxuICAgKiBTMyBVUkwgdGhhdCBjb21waWxlZCBhcnRpZmFjdCB1cGxvYWRlZC5cbiAgICovXG4gIHJlYWRvbmx5IHMzVXJpOiBzdHJpbmc7XG4gIC8qKlxuICAgKiBTMyBwcmVmaXggdGhhdCBjb21waWxlZCBhcnRpZmFjdCB1cGxvYWRlZC5cbiAgICovXG4gIHJlYWRvbmx5IHMzUHJlZml4OiBzdHJpbmc7XG4gIC8qKlxuICAgKiBUaGUgbW9kZWwgbmFtZS5cbiAgICovXG4gIHJlYWRvbmx5IG1vZGVsTmFtZTogc3RyaW5nO1xuICAvKipcbiAgICogVGhlIHdlaWdodCBzaXplIG9mIHRoZSBtb2RlbC5cbiAgICovXG4gIHJlYWRvbmx5IHdlaWdodFNpemU6IFNpemU7XG59XG5cbi8qKlxuICogSW50ZXJmYWNlIGZvciBOZXVyb254IGNvbXBpbGVycy5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBJTmV1cm9ueENvbXBpbGVyIHtcbiAgY29tcGlsZSgpOiBOZXVyb254Q29tcGlsZWRNb2RlbDtcbn1cblxuLyoqXG4gKiBDb21tb24gcHJvcHMgZm9yIE5ldXJvbnhDb21waWxlckJhc2UuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgTmV1cm9ueENvbXBpbGVyQmFzZVByb3BzIHtcbiAgLyoqXG4gICAqIFZQQyBpbiB3aGljaCB0aGlzIHdpbGwgbGF1bmNoIGNvbXBpbGUgd29ya2VyIGluc3RhbmNlLlxuICAgKi9cbiAgcmVhZG9ubHkgdnBjOiBJVnBjO1xuICAvKipcbiAgICogVGhlIGJ1Y2tldCB0byB1cGxvYWQgY29tcGlsZWQgYXJ0aWZhY3RzLlxuICAgKi9cbiAgcmVhZG9ubHkgYnVja2V0OiBJQnVja2V0O1xuICAvKipcbiAgICogU2VjcmV0cyB0byBwYXNzIHRvIHRoZSBjb250YWluZXIuXG4gICAqL1xuICByZWFkb25seSBzZWNyZXRzPzogeyBba2V5OiBzdHJpbmddOiBiYXRjaC5TZWNyZXQgfTtcbiAgLyoqXG4gICAqIFMzIFByZWZpeCB0aGF0IGNvbXBpbGVkIGFydGlmYWN0IHVwbG9hZGVkLlxuICAgKiBUaGlzIHByb3BlcnR5IGlzIG5vdCBkZXBlbmRzIG9uIGNvbXBpbGUgam9iIGZpbmlzaC5cbiAgICovXG4gIHJlYWRvbmx5IGFydGlmYWN0UzNQcmVmaXg6IHN0cmluZztcbiAgLyoqXG4gICAqIFRoZSBpbnN0YW5jZSB0eXBlIG9mIGNvbXBpbGUgd29ya2VyIGluc3RhbmNlLlxuICAgKi9cbiAgcmVhZG9ubHkgbmV1cm9ueEluc3RhbmNlVHlwZTogSU5ldXJvbnhJbnN0YW5jZVR5cGU7XG4gIC8qKlxuICAgKiBUaGUgbW9kZWwgdG8gYmUgY29tcGlsZWQuXG4gICAqL1xuICByZWFkb25seSBtb2RlbDogTW9kZWw7XG4gIC8qKlxuICAgKiBBbiBpbWFnZSBvZiB0aGUgY29udGFpbmVyIHdoZXJlIHRoZSBjb21waWxlIGpvYiBpcyBleGVjdXRlZC5cbiAgICovXG4gIHJlYWRvbmx5IGltYWdlOiBJTmV1cm9ueENvbnRhaW5lckltYWdlO1xuICAvKipcbiAgICogVGhlIGNvbW1hbmQgdG8gcnVuIGluIHRoZSBjb250YWluZXIuXG4gICAqL1xuICByZWFkb25seSBjb21tYW5kPzogc3RyaW5nW107XG4gIC8qKlxuICAgKiBUaGUgcm9vdCB2b2x1bWUgb2Ygd29ya2VyIGluc3RhbmNlLlxuICAgKiBAZGVmYXVsdCAtIE4gYmlsbGlvbiBwYXJhbWV0ZXJzICogNUdpQiBFQlNcbiAgICovXG4gIHJlYWRvbmx5IHZvbHVtZVNpemU/OiBTaXplO1xuICAvKipcbiAgICogV2hldGhlciBvciBub3QgdG8gdXNlIHNwb3QgaW5zdGFuY2VzLiBTcG90IGluc3RhbmNlcyBhcmUgbGVzcyBleHBlbnNpdmUgRUMyIGluc3RhbmNlcyB0aGF0IGNhbiBiZSByZWNsYWltZWQgYnkgRUMyIGF0IGFueSB0aW1lOyB5b3VyIGpvYiB3aWxsIGJlIGdpdmVuIHR3byBtaW51dGVzIG9mIG5vdGljZSBiZWZvcmUgcmVjbGFtYXRpb24uXG4gICAqXG4gICAqIEBkZWZhdWx0IGZhbHNlXG4gICAqL1xuICByZWFkb25seSBzcG90PzogYm9vbGVhbjtcbiAgLyoqXG4gICAqIFRoZSBWUEMgU3VibmV0cyB0aGlzIENvbXB1dGUgRW52aXJvbm1lbnQgd2lsbCBsYXVuY2ggaW5zdGFuY2VzIGluLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIG5ldyBzdWJuZXRzIHdpbGwgYmUgY3JlYXRlZFxuICAgKi9cbiAgcmVhZG9ubHkgdnBjU3VibmV0cz86IFN1Ym5ldFNlbGVjdGlvbjtcbiAgLyoqXG4gICAqIFRoZSBlbnZpcm9ubWVudCB2YXJpYWJsZXMgdG8gcGFzcyB0byB0aGUgY29udGFpbmVyLlxuICAgKiBUaGlzIGlzIG9ubHkgYXBwbGljYWJsZSB3aGVuIHVzaW5nIGNvbnRhaW5lciBydW50aW1lLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIE5vIGVudmlyb25tZW50IHZhcmlhYmxlcy5cbiAgICovXG4gIHJlYWRvbmx5IGVudmlyb25tZW50Pzoge1xuICAgIFtrZXk6IHN0cmluZ106IHN0cmluZztcbiAgfTtcbn1cblxuLyoqXG4gKiBSZXN1bHQgb2YgY3JlYXRpbmcgYSBjb21wdXRlIGVudmlyb25tZW50LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIENvbXB1dGVFbnZpcm9ubWVudFJlc3VsdCB7XG4gIC8qKlxuICAgKiBUaGUgY29tcHV0ZSBlbnZpcm9ubWVudC5cbiAgICovXG4gIHJlYWRvbmx5IGNvbXB1dGVFbnZpcm9ubWVudDogYmF0Y2guSUNvbXB1dGVFbnZpcm9ubWVudDtcbiAgLyoqXG4gICAqIFRoZSBpbnN0YW5jZSByb2xlIGFzc29jaWF0ZWQgd2l0aCB0aGUgY29tcHV0ZSBlbnZpcm9ubWVudC5cbiAgICovXG4gIHJlYWRvbmx5IGluc3RhbmNlUm9sZTogSVJvbGU7XG59XG5cbi8qKlxuICogQWJzdHJhY3QgYmFzZSBjbGFzcyBmb3IgTmV1cm9ueCBjb21waWxlcnMuXG4gKiBQcm92aWRlcyB0aGUgY29tbW9uIG9yY2hlc3RyYXRpb24gbG9naWMgKExhbWJkYSwgQ3VzdG9tUmVzb3VyY2UsIFdhaXRDb25kaXRpb24pXG4gKiB3aGlsZSBzdWJjbGFzc2VzIGRlZmluZSBob3cgdG8gY3JlYXRlIHRoZSBCYXRjaCBjb21wdXRlIGVudmlyb25tZW50IGFuZCBqb2IgZGVmaW5pdGlvbi5cbiAqL1xuZXhwb3J0IGFic3RyYWN0IGNsYXNzIE5ldXJvbnhDb21waWxlckJhc2VcbiAgZXh0ZW5kcyBDb25zdHJ1Y3RcbiAgaW1wbGVtZW50cyBJTmV1cm9ueENvbXBpbGVyXG57XG4gIHByaXZhdGUgY29tcGlsZWRNb2RlbD86IE5ldXJvbnhDb21waWxlZE1vZGVsO1xuICBwcml2YXRlIHJlYWRvbmx5IGVudHJ5cG9pbnQ6IFNpbmdsZXRvbkZ1bmN0aW9uO1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgYXJ0aWZhY3RTM1ByZWZpeDogc3RyaW5nO1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgd2VpZ2h0U2l6ZTogU2l6ZTtcbiAgcHJvdGVjdGVkIHJlYWRvbmx5IG5ldXJvbnhJbnN0YW5jZVR5cGU6IElOZXVyb254SW5zdGFuY2VUeXBlO1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgbW9kZWw6IE1vZGVsO1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgYnVja2V0OiBJQnVja2V0O1xuXG4gIGNvbnN0cnVjdG9yKHNjb3BlOiBDb25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHByb3BzOiBOZXVyb254Q29tcGlsZXJCYXNlUHJvcHMpIHtcbiAgICBzdXBlcihzY29wZSwgaWQpO1xuXG4gICAgdGhpcy5tb2RlbCA9IHByb3BzLm1vZGVsO1xuICAgIHRoaXMuYnVja2V0ID0gcHJvcHMuYnVja2V0O1xuICAgIHRoaXMuYXJ0aWZhY3RTM1ByZWZpeCA9IHByb3BzLmFydGlmYWN0UzNQcmVmaXg7XG4gICAgdGhpcy53ZWlnaHRTaXplID0gU2l6ZS5naWJpYnl0ZXMoXG4gICAgICBwcm9wcy5tb2RlbC5vcHRpb25zLnBhcmFtZXRlcnMudG9CaWxsaW9uKCkgKiAyLjUsXG4gICAgKTtcbiAgICB0aGlzLm5ldXJvbnhJbnN0YW5jZVR5cGUgPSBwcm9wcy5uZXVyb254SW5zdGFuY2VUeXBlO1xuXG4gICAgY29uc3QgeyBjb21wdXRlRW52aXJvbm1lbnQsIGluc3RhbmNlUm9sZSB9ID1cbiAgICAgIHRoaXMuY3JlYXRlQ29tcHV0ZUVudmlyb25tZW50KHByb3BzKTtcbiAgICBjb25zdCBqb2JEZWZpbml0aW9uID0gdGhpcy5jcmVhdGVKb2JEZWZpbml0aW9uKHByb3BzKTtcbiAgICBjb25zdCBqb2JRdWV1ZSA9IHRoaXMuY3JlYXRlSm9iUXVldWUoY29tcHV0ZUVudmlyb25tZW50KTtcblxuICAgIHByb3BzLm1vZGVsLmJ1Y2tldD8uZ3JhbnRSZWFkKGluc3RhbmNlUm9sZSk7XG4gICAgcHJvcHMuYnVja2V0LmdyYW50UmVhZFdyaXRlKGluc3RhbmNlUm9sZSk7XG5cbiAgICBjb25zdCBqb2JTdWJtaXRGdW5jdGlvbiA9IG5ldyBTaW5nbGV0b25GdW5jdGlvbih0aGlzLCBcIkpvYlN1Ym1pdEZ1bmN0aW9uXCIsIHtcbiAgICAgIGNvZGU6IENvZGUuZnJvbUFzc2V0KGpvaW4oX19kaXJuYW1lLCBcInByaXZhdGUvYXdhaXQtY29tcGlsZS1qb2JcIikpLFxuICAgICAgaGFuZGxlcjogXCJpbmRleC5vbkV2ZW50XCIsXG4gICAgICBydW50aW1lOiBSdW50aW1lLk5PREVKU19MQVRFU1QsXG4gICAgICB1dWlkOiBcIjEzNjFmNDY5LTVjOTItNGM0Ni05ZTExLTVkMWRiZjkyNWJhY1wiLFxuICAgICAgZW52aXJvbm1lbnQ6IHtcbiAgICAgICAgSk9CX0RFRklOSVRJT05fQVJOOiBqb2JEZWZpbml0aW9uLmpvYkRlZmluaXRpb25Bcm4sXG4gICAgICAgIEpPQl9RVUVVRV9BUk46IGpvYlF1ZXVlLmpvYlF1ZXVlQXJuLFxuICAgICAgfSxcbiAgICB9KTtcbiAgICBHcmFudC5hZGRUb1ByaW5jaXBhbCh7XG4gICAgICByZXNvdXJjZUFybnM6IFtqb2JEZWZpbml0aW9uLmpvYkRlZmluaXRpb25Bcm4sIGpvYlF1ZXVlLmpvYlF1ZXVlQXJuXSxcbiAgICAgIGdyYW50ZWU6IGpvYlN1Ym1pdEZ1bmN0aW9uLFxuICAgICAgYWN0aW9uczogW1wiYmF0Y2g6U3VibWl0Sm9iXCJdLFxuICAgIH0pO1xuICAgIGNvbnN0IGpvYk1vbml0b3JpbmdGdW5jdGlvbiA9IG5ldyBTaW5nbGV0b25GdW5jdGlvbihcbiAgICAgIHRoaXMsXG4gICAgICBcIkpvYk1vbml0b3JpbmdGdW5jdGlvblwiLFxuICAgICAge1xuICAgICAgICBjb2RlOiBDb2RlLmZyb21Bc3NldChqb2luKF9fZGlybmFtZSwgXCJwcml2YXRlL2F3YWl0LWNvbXBpbGUtam9iXCIpKSxcbiAgICAgICAgaGFuZGxlcjogXCJpbmRleC5pc0NvbXBsZXRlXCIsXG4gICAgICAgIHJ1bnRpbWU6IFJ1bnRpbWUuTk9ERUpTX0xBVEVTVCxcbiAgICAgICAgdXVpZDogXCJkZjE2ZGJhOC01Zjc3LTQ4MGMtYTZhZC1jZmRmNzRjM2RlNjJcIixcbiAgICAgICAgZW52aXJvbm1lbnQ6IHtcbiAgICAgICAgICBBUlRJRkFDVF9TM19QUkVGSVg6IHByb3BzLmFydGlmYWN0UzNQcmVmaXgsXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgICk7XG4gICAgR3JhbnQuYWRkVG9QcmluY2lwYWwoe1xuICAgICAgcmVzb3VyY2VBcm5zOiBbXCIqXCJdLFxuICAgICAgZ3JhbnRlZTogam9iTW9uaXRvcmluZ0Z1bmN0aW9uLFxuICAgICAgYWN0aW9uczogW1wiYmF0Y2g6RGVzY3JpYmVKb2JzXCJdLFxuICAgIH0pO1xuICAgIGNvbnN0IHByb3ZpZGVyID0gbmV3IFByb3ZpZGVyKHRoaXMsIFwiQ29tcGlsZUpvYlByb3ZpZGVyXCIsIHtcbiAgICAgIG9uRXZlbnRIYW5kbGVyOiBqb2JTdWJtaXRGdW5jdGlvbixcbiAgICAgIGlzQ29tcGxldGVIYW5kbGVyOiBqb2JNb25pdG9yaW5nRnVuY3Rpb24sXG4gICAgICBxdWVyeUludGVydmFsOiBEdXJhdGlvbi5taW51dGVzKDEpLFxuICAgICAgdG90YWxUaW1lb3V0OiBEdXJhdGlvbi5ob3VycygxMiksXG4gICAgfSk7XG4gICAgdGhpcy5lbnRyeXBvaW50ID0gbmV3IFNpbmdsZXRvbkZ1bmN0aW9uKHRoaXMsIFwiSm9iRW50cnlwb2ludEZ1bmN0aW9uXCIsIHtcbiAgICAgIGNvZGU6IENvZGUuZnJvbUFzc2V0KGpvaW4oX19kaXJuYW1lLCBcInByaXZhdGUvYXdhaXQtY29tcGlsZS1qb2JcIikpLFxuICAgICAgaGFuZGxlcjogXCJpbmRleC5lbnRyeXBvaW50XCIsXG4gICAgICBlbnZpcm9ubWVudDoge1xuICAgICAgICBQUk9WSURFUl9BUk46IHByb3ZpZGVyLnNlcnZpY2VUb2tlbixcbiAgICAgIH0sXG4gICAgICB0aW1lb3V0OiBEdXJhdGlvbi5taW51dGVzKDE1KSxcbiAgICAgIHJ1bnRpbWU6IFJ1bnRpbWUuTk9ERUpTX0xBVEVTVCxcbiAgICAgIHV1aWQ6IFwiZjZlNjY5OTctNTA0Mi00ZGYxLTg3ODEtYmQ2OGIzYWM1MzEzXCIsXG4gICAgfSk7XG4gICAgRnVuY3Rpb24uZnJvbUZ1bmN0aW9uQXJuKFxuICAgICAgdGhpcyxcbiAgICAgIFwiUHJvdmlkZXJGdW5jdGlvblwiLFxuICAgICAgcHJvdmlkZXIuc2VydmljZVRva2VuLFxuICAgICkuZ3JhbnRJbnZva2UodGhpcy5lbnRyeXBvaW50KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGUgdGhlIEJhdGNoIGNvbXB1dGUgZW52aXJvbm1lbnQuXG4gICAqIFN1YmNsYXNzZXMgbXVzdCBpbXBsZW1lbnQgdGhpcyB0byBwcm92aWRlIHRoZSBhcHByb3ByaWF0ZSBjb21wdXRlIGVudmlyb25tZW50LlxuICAgKi9cbiAgcHJvdGVjdGVkIGFic3RyYWN0IGNyZWF0ZUNvbXB1dGVFbnZpcm9ubWVudChcbiAgICBwcm9wczogTmV1cm9ueENvbXBpbGVyQmFzZVByb3BzLFxuICApOiBDb21wdXRlRW52aXJvbm1lbnRSZXN1bHQ7XG5cbiAgLyoqXG4gICAqIENyZWF0ZSB0aGUgQmF0Y2ggam9iIGRlZmluaXRpb24uXG4gICAqIFN1YmNsYXNzZXMgbXVzdCBpbXBsZW1lbnQgdGhpcyB0byBwcm92aWRlIHRoZSBhcHByb3ByaWF0ZSBqb2IgZGVmaW5pdGlvbi5cbiAgICovXG4gIHByb3RlY3RlZCBhYnN0cmFjdCBjcmVhdGVKb2JEZWZpbml0aW9uKFxuICAgIHByb3BzOiBOZXVyb254Q29tcGlsZXJCYXNlUHJvcHMsXG4gICk6IGJhdGNoLklKb2JEZWZpbml0aW9uO1xuXG4gIHByaXZhdGUgY3JlYXRlSm9iUXVldWUoXG4gICAgY29tcHV0ZUVudmlyb25tZW50OiBiYXRjaC5JQ29tcHV0ZUVudmlyb25tZW50LFxuICApOiBiYXRjaC5Kb2JRdWV1ZSB7XG4gICAgcmV0dXJuIG5ldyBiYXRjaC5Kb2JRdWV1ZSh0aGlzLCBcIkpvYlF1ZXVlXCIsIHtcbiAgICAgIGNvbXB1dGVFbnZpcm9ubWVudHM6IFtcbiAgICAgICAge1xuICAgICAgICAgIGNvbXB1dGVFbnZpcm9ubWVudCxcbiAgICAgICAgICBvcmRlcjogMSxcbiAgICAgICAgfSxcbiAgICAgIF0sXG4gICAgICBqb2JTdGF0ZVRpbWVMaW1pdEFjdGlvbnM6IFtcbiAgICAgICAge1xuICAgICAgICAgIHN0YXRlOiBiYXRjaC5Kb2JTdGF0ZVRpbWVMaW1pdEFjdGlvbnNTdGF0ZS5SVU5OQUJMRSxcbiAgICAgICAgICByZWFzb246IGJhdGNoLkpvYlN0YXRlVGltZUxpbWl0QWN0aW9uc1JlYXNvbi5KT0JfUkVTT1VSQ0VfUkVRVUlSRU1FTlQsXG4gICAgICAgICAgbWF4VGltZTogRHVyYXRpb24ubWludXRlcygxMCksXG4gICAgICAgICAgYWN0aW9uOiBiYXRjaC5Kb2JTdGF0ZVRpbWVMaW1pdEFjdGlvbnNBY3Rpb24uQ0FOQ0VMLFxuICAgICAgICB9LFxuICAgICAgXSxcbiAgICB9KTtcbiAgfVxuXG4gIGNvbXBpbGUoKTogTmV1cm9ueENvbXBpbGVkTW9kZWwge1xuICAgIGlmICh0aGlzLmNvbXBpbGVkTW9kZWwpIHtcbiAgICAgIHJldHVybiB0aGlzLmNvbXBpbGVkTW9kZWw7XG4gICAgfVxuICAgIGNvbnN0IHdhaXRDb25kaXRpb25IYW5kbGUgPSBuZXcgQ2ZuV2FpdENvbmRpdGlvbkhhbmRsZShcbiAgICAgIHRoaXMsXG4gICAgICBgV2FpdENvbmRpdGlvbkhhbmRsZSR7dGhpcy5hcnRpZmFjdFMzUHJlZml4fWAsXG4gICAgKTtcbiAgICBjb25zdCBjb21waWxlSm9iID0gbmV3IEN1c3RvbVJlc291cmNlKHRoaXMsIFwiTmV1cm9ueENvbXBpbGVcIiwge1xuICAgICAgc2VydmljZVRva2VuOiB0aGlzLmVudHJ5cG9pbnQuZnVuY3Rpb25Bcm4sXG4gICAgICByZXNvdXJjZVR5cGU6IFwiQ3VzdG9tOjpOZXVyb254Q29tcGlsZVwiLFxuICAgICAgcHJvcGVydGllczoge1xuICAgICAgICB3YWl0Q29uZGl0aW9uQ2FsbGJhY2tVUkw6IHdhaXRDb25kaXRpb25IYW5kbGUucmVmLFxuICAgICAgfSxcbiAgICB9KTtcbiAgICBjb25zdCB3YWl0ID0gbmV3IENmbldhaXRDb25kaXRpb24oXG4gICAgICB0aGlzLFxuICAgICAgYFdhaXRDb25kaXRpb24ke3RoaXMuYXJ0aWZhY3RTM1ByZWZpeH1gLFxuICAgICAge1xuICAgICAgICBjb3VudDogMSxcbiAgICAgICAgdGltZW91dDogRHVyYXRpb24uaG91cnMoMTIpLnRvU2Vjb25kcygpLnRvU3RyaW5nKCksXG4gICAgICAgIGhhbmRsZTogd2FpdENvbmRpdGlvbkhhbmRsZS5yZWYsXG4gICAgICB9LFxuICAgICk7XG4gICAgd2FpdC5ub2RlLmFkZERlcGVuZGVuY3koY29tcGlsZUpvYik7XG4gICAgY29uc3QgczNQcmVmaXggPSBGbi5zZWxlY3QoMywgRm4uc3BsaXQoJ1wiJywgd2FpdC5hdHRyRGF0YS50b1N0cmluZygpKSk7XG5cbiAgICB0aGlzLmNvbXBpbGVkTW9kZWwgPSB7XG4gICAgICBtb2RlbE5hbWU6IHRoaXMubW9kZWwubW9kZWxOYW1lLFxuICAgICAgcmVjb21tZW5kZWRJbnN0YW5jZVR5cGU6IHRoaXMubmV1cm9ueEluc3RhbmNlVHlwZSxcbiAgICAgIGJ1Y2tldDogdGhpcy5idWNrZXQsXG4gICAgICBzM1ByZWZpeCxcbiAgICAgIHMzVXJpOiB0aGlzLmJ1Y2tldC5zM1VybEZvck9iamVjdChzM1ByZWZpeCksXG4gICAgICB3ZWlnaHRTaXplOiB0aGlzLndlaWdodFNpemUsXG4gICAgfTtcbiAgICByZXR1cm4gdGhpcy5jb21waWxlZE1vZGVsO1xuICB9XG59XG4iXX0=