UNPKG

aws-cdk-neuronx-patterns

Version:
128 lines 22.5 kB
"use strict"; var _a, _b; Object.defineProperty(exports, "__esModule", { value: true }); exports.VllmNxdInferenceCompiler = exports.VllmNxdInferenceCompileImage = void 0; const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti"); const aws_cdk_lib_1 = require("aws-cdk-lib"); const aws_ecs_1 = require("aws-cdk-lib/aws-ecs"); const constructs_1 = require("constructs"); const crypto_1 = require("crypto"); const path_1 = require("path"); const neuronx_1 = require("../base/neuronx"); const neuronx_compiler_1 = require("../base/neuronx-compiler"); const vllm_engine_1 = require("../base/server-engine/vllm-engine"); const vllm_nxd_inference_ecs_patterns_1 = require("./vllm-nxd-inference-ecs-patterns"); /** * Compile runtime container image for vLLM NxD Inference */ class VllmNxdInferenceCompileImage extends vllm_nxd_inference_ecs_patterns_1.VllmNxdInferenceImageBase { constructor(neruonxImage, options) { super(neruonxImage, options); this.image = aws_ecs_1.ContainerImage.fromAsset((0, path_1.join)(__dirname, "../../scripts/compile/vllm-nxd-inference"), { buildArgs: { IMAGE_NAME: neruonxImage.imageName, IMAGE_TAG: neruonxImage.imageTag, VLLM_GIT_BRANCH: this.vllmGitBranch, VLLM_GIT_COMMIT_HASH: this.vllmGitCommitHash, }, }); } } exports.VllmNxdInferenceCompileImage = VllmNxdInferenceCompileImage; _a = JSII_RTTI_SYMBOL_1; VllmNxdInferenceCompileImage[_a] = { fqn: "aws-cdk-neuronx-patterns.VllmNxdInferenceCompileImage", version: "0.0.23" }; /** * Neuronx compiler construct for vLLM on NxD Inference. * Compile the model to work with Neuronx instance and upload it to an S3 bucket. */ class VllmNxdInferenceCompiler extends constructs_1.Construct { constructor(scope, id, props) { super(scope, id); const maxModelLen = props.vllmArgs?.maxModelLen ?? 128; const maxNumSeqs = props.vllmArgs?.maxNumSeqs ?? 1; const memoryFootprint = props.model.options.config ? (0, neuronx_1.calcMemoryFootprint)(props.model.options.config.embeddingDimension, props.model.options.config.layers, neuronx_1.DataTypeBits.BF16_OR_FP16, maxModelLen, maxNumSeqs) : (0, neuronx_1.inferMemoryFootprintFromParameters)(props.model.options.parameters, maxModelLen, maxNumSeqs); const neuronxInstanceTypes = props.neuronxInstanceType ? [props.neuronxInstanceType] : [ neuronx_1.NeuronxInstanceType.INF2_8XLARGE, neuronx_1.NeuronxInstanceType.INF2_24XLARGE, neuronx_1.NeuronxInstanceType.INF2_48XLARGE, ]; const availableInstancePatterns = neuronxInstanceTypes .flatMap((neuronxInstanceType) => (0, neuronx_1.calcTensorParallel)(neuronxInstanceType, memoryFootprint, props.model.options.config?.attentionHeads).map((v) => ({ neuronxInstanceType, ...v, }))) .filter((instanceType) => !props.vllmArgs?.tensorParallelSize || instanceType.tp === props.vllmArgs.tensorParallelSize); if (availableInstancePatterns.length === 0) { throw new Error(`No available instance type. You can use tensorParallelSize are ${availableInstancePatterns.map((p) => p.tp).join(", ")}.`); } const tensorParallelSize = availableInstancePatterns[0].tp; const image = props.image ?? new VllmNxdInferenceCompileImage(neuronx_1.PytorchTrainingNeuronxImage.LATEST); const vllmArgs = { ...props.vllmArgs, model: props.model.modelId, servedModelName: [props.model.modelName], maxModelLen, maxNumSeqs, tensorParallelSize, }; // change dirname every engine args patterns const hash = (str) => (0, crypto_1.createHash)("sha256").update(str).digest("hex"); const artifactS3Prefix = `sdk-${image.sdkVersion}/${hash(JSON.stringify(vllmArgs))}`; const vllmCliArgs = vllm_engine_1.VllmEngineArgumentsParser.cli(vllmArgs); const environment = { ...props.environment, VLLM_NEURON_FRAMEWORK: "neuronx-distributed-inference", NEURON_COMPILED_ARTIFACTS: "neuron-compiled-artifacts", NEURON_RT_NUM_CORES: tensorParallelSize.toString(), XLA_HANDLE_SPECIAL_SCALAR: "1", MODEL_ID: props.model.modelId, MODEL_NAME: props.model.modelName, COMPILED_ARTIFACTS_S3_URI: props.bucket.s3UrlForObject(artifactS3Prefix), COMPILED_ARTIFACTS_S3_PREFIX: artifactS3Prefix, }; const secrets = {}; if (props.vllmArgs?.hfToken) { secrets.HF_TOKEN = props.vllmArgs.hfToken; } const weightSize = aws_cdk_lib_1.Size.gibibytes(props.model.options.parameters.toBillion() * 2.5); const quantizedWightSize = props.vllmArgs?.overrideNeuronConfig?.quantized ? weightSize : aws_cdk_lib_1.Size.bytes(0); const volumeSize = aws_cdk_lib_1.Size.gibibytes(Math.ceil(weightSize.toGibibytes() + quantizedWightSize.toGibibytes() + neuronx_1.PytorchTrainingNeuronxImage.size.toGibibytes() + neuronx_1.NeuronOptimizedMachineImage.size.toGibibytes())); const compiler = new neuronx_compiler_1.NeuronxCompiler(this, "Resource", { ...props, neuronxInstanceType: availableInstancePatterns[0].neuronxInstanceType, artifactS3Prefix, image: image, command: vllmCliArgs, environment, secrets, volumeSize, }); this.vllmArgs = vllmArgs; this.compiler = compiler; } /** * Compile the model and return the compiled model. * @returns The compiled model. */ compile() { return { ...this.compiler.compile(), vllmArgs: this.vllmArgs, }; } } exports.VllmNxdInferenceCompiler = VllmNxdInferenceCompiler; _b = JSII_RTTI_SYMBOL_1; VllmNxdInferenceCompiler[_b] = { fqn: "aws-cdk-neuronx-patterns.VllmNxdInferenceCompiler", version: "0.0.23" }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmxsbS1ueGQtaW5mZXJlbmNlLWNvbXBpbGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3ZsbG0tbnhkLWluZmVyZW5jZS92bGxtLW54ZC1pbmZlcmVuY2UtY29tcGlsZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSw2Q0FBbUM7QUFHbkMsaURBQXFEO0FBRXJELDJDQUF1QztBQUN2QyxtQ0FBb0M7QUFDcEMsK0JBQTRCO0FBQzVCLDZDQVd5QjtBQUN6QiwrREFJa0M7QUFDbEMsbUVBRzJDO0FBQzNDLHVGQUcyQztBQUUzQzs7R0FFRztBQUNILE1BQWEsNEJBQTZCLFNBQVEsMkRBQXlCO0lBS3pFLFlBQ0UsWUFBMkIsRUFDM0IsT0FBc0M7UUFFdEMsS0FBSyxDQUFDLFlBQVksRUFBRSxPQUFPLENBQUMsQ0FBQztRQUM3QixJQUFJLENBQUMsS0FBSyxHQUFHLHdCQUFjLENBQUMsU0FBUyxDQUNuQyxJQUFBLFdBQUksRUFBQyxTQUFTLEVBQUUsMENBQTBDLENBQUMsRUFDM0Q7WUFDRSxTQUFTLEVBQUU7Z0JBQ1QsVUFBVSxFQUFFLFlBQVksQ0FBQyxTQUFTO2dCQUNsQyxTQUFTLEVBQUUsWUFBWSxDQUFDLFFBQVE7Z0JBQ2hDLGVBQWUsRUFBRSxJQUFJLENBQUMsYUFBYTtnQkFDbkMsb0JBQW9CLEVBQUUsSUFBSSxDQUFDLGlCQUFpQjthQUM3QztTQUNGLENBQ0YsQ0FBQztJQUNKLENBQUM7O0FBckJILG9FQXNCQzs7O0FBc0VEOzs7R0FHRztBQUNILE1BQWEsd0JBQXlCLFNBQVEsc0JBQVM7SUFHckQsWUFDRSxLQUFnQixFQUNoQixFQUFVLEVBQ1YsS0FBbUM7UUFFbkMsS0FBSyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQztRQUNqQixNQUFNLFdBQVcsR0FBRyxLQUFLLENBQUMsUUFBUSxFQUFFLFdBQVcsSUFBSSxHQUFHLENBQUM7UUFDdkQsTUFBTSxVQUFVLEdBQUcsS0FBSyxDQUFDLFFBQVEs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QUFRLEdBQUcsSUFBSSxrQ0FBZSxDQUFDLElBQUksRUFBRSxVQUFVLEVBQUU7WUFDckQsR0FBRyxLQUFLO1lBQ1IsbUJBQW1CLEVBQUUseUJBQXlCLENBQUMsQ0FBQyxDQUFDLENBQUMsbUJBQW1CO1lBQ3JFLGdCQUFnQjtZQUNoQixLQUFLLEVBQUUsS0FBSztZQUNaLE9BQU8sRUFBRSxXQUFXO1lBQ3BCLFdBQVc7WUFDWCxPQUFPO1lBQ1AsVUFBVTtTQUNYLENBQUMsQ0FBQztRQUNILElBQUksQ0FBQyxRQUFRLEdBQUcsUUFBUSxDQUFDO1FBQ3pCLElBQUksQ0FBQyxRQUFRLEdBQUcsUUFBUSxDQUFDO0lBQzNCLENBQUM7SUFDRDs7O09BR0c7SUFDSCxPQUFPO1FBQ0wsT0FBTztZQUNMLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxPQUFPLEVBQUU7WUFDMUIsUUFBUSxFQUFFLElBQUksQ0FBQyxRQUFRO1NBQ2dCLENBQUM7SUFDNUMsQ0FBQzs7QUExSEgsNERBMkhDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgU2l6ZSB9IGZyb20gXCJhd3MtY2RrLWxpYlwiO1xuaW1wb3J0ICogYXMgYmF0Y2ggZnJvbSBcImF3cy1jZGstbGliL2F3cy1iYXRjaFwiO1xuaW1wb3J0IHsgSVZwYywgU3VibmV0U2VsZWN0aW9uIH0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1lYzJcIjtcbmltcG9ydCB7IENvbnRhaW5lckltYWdlIH0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1lY3NcIjtcbmltcG9ydCB7IElCdWNrZXQgfSBmcm9tIFwiYXdzLWNkay1saWIvYXdzLXMzXCI7XG5pbXBvcnQgeyBDb25zdHJ1Y3QgfSBmcm9tIFwiY29uc3RydWN0c1wiO1xuaW1wb3J0IHsgY3JlYXRlSGFzaCB9IGZyb20gXCJjcnlwdG9cIjtcbmltcG9ydCB7IGpvaW4gfSBmcm9tIFwicGF0aFwiO1xuaW1wb3J0IHtcbiAgY2FsY01lbW9yeUZvb3RwcmludCxcbiAgY2FsY1RlbnNvclBhcmFsbGVsLFxuICBEYXRhVHlwZUJpdHMsXG4gIElOZXVyb254SW1hZ2UsXG4gIElOZXVyb254SW5zdGFuY2VUeXBlLFxuICBpbmZlck1lbW9yeUZvb3RwcmludEZyb21QYXJhbWV0ZXJzLFxuICBNb2RlbCxcbiAgTmV1cm9uT3B0aW1pemVkTWFjaGluZUltYWdlLFxuICBOZXVyb254SW5zdGFuY2VUeXBlLFxuICBQeXRvcmNoVHJhaW5pbmdOZXVyb254SW1hZ2UsXG59IGZyb20gXCIuLi9iYXNlL25ldXJvbnhcIjtcbmltcG9ydCB7XG4gIElOZXVyb254Q29udGFpbmVySW1hZ2UsXG4gIE5ldXJvbnhDb21waWxlZE1vZGVsLFxuICBOZXVyb254Q29tcGlsZXIsXG59IGZyb20gXCIuLi9iYXNlL25ldXJvbngtY29tcGlsZXJcIjtcbmltcG9ydCB7XG4gIFZsbG1FbmdpbmVBcmd1bWVudHMsXG4gIFZsbG1FbmdpbmVBcmd1bWVudHNQYXJzZXIsXG59IGZyb20gXCIuLi9iYXNlL3NlcnZlci1lbmdpbmUvdmxsbS1lbmdpbmVcIjtcbmltcG9ydCB7XG4gIFZsbG1OeGRJbmZlcmVuY2VJbWFnZUJhc2UsXG4gIFZsbG1OeGRJbmZlcmVuY2VJbWFnZU9wdGlvbnMsXG59IGZyb20gXCIuL3ZsbG0tbnhkLWluZmVyZW5jZS1lY3MtcGF0dGVybnNcIjtcblxuLyoqXG4gKiBDb21waWxlIHJ1bnRpbWUgY29udGFpbmVyIGltYWdlIGZvciB2TExNIE54RCBJbmZlcmVuY2VcbiAqL1xuZXhwb3J0IGNsYXNzIFZsbG1OeGRJbmZlcmVuY2VDb21waWxlSW1hZ2UgZXh0ZW5kcyBWbGxtTnhkSW5mZXJlbmNlSW1hZ2VCYXNlIHtcbiAgLyoqXG4gICAqIFRoZSBjb250YWluZXIgaW1hZ2UuXG4gICAqL1xuICByZWFkb25seSBpbWFnZTogQ29udGFpbmVySW1hZ2U7XG4gIGNvbnN0cnVjdG9yKFxuICAgIG5lcnVvbnhJbWFnZTogSU5ldXJvbnhJbWFnZSxcbiAgICBvcHRpb25zPzogVmxsbU54ZEluZmVyZW5jZUltYWdlT3B0aW9ucyxcbiAgKSB7XG4gICAgc3VwZXIobmVydW9ueEltYWdlLCBvcHRpb25zKTtcbiAgICB0aGlzLmltYWdlID0gQ29udGFpbmVySW1hZ2UuZnJvbUFzc2V0KFxuICAgICAgam9pbihfX2Rpcm5hbWUsIFwiLi4vLi4vc2NyaXB0cy9jb21waWxlL3ZsbG0tbnhkLWluZmVyZW5jZVwiKSxcbiAgICAgIHtcbiAgICAgICAgYnVpbGRBcmdzOiB7XG4gICAgICAgICAgSU1BR0VfTkFNRTogbmVydW9ueEltYWdlLmltYWdlTmFtZSxcbiAgICAgICAgICBJTUFHRV9UQUc6IG5lcnVvbnhJbWFnZS5pbWFnZVRhZyxcbiAgICAgICAgICBWTExNX0dJVF9CUkFOQ0g6IHRoaXMudmxsbUdpdEJyYW5jaCxcbiAgICAgICAgICBWTExNX0dJVF9DT01NSVRfSEFTSDogdGhpcy52bGxtR2l0Q29tbWl0SGFzaCxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgKTtcbiAgfVxufVxuXG4vKipcbiAqIFByb3BzIG9mIFZsbG1OeGRJbmZlcmVuY2VDb21waWxlci5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBWbGxtTnhkSW5mZXJlbmNlQ29tcGlsZVByb3BzIHtcbiAgLyoqXG4gICAqIFZQQyBpbiB3aGljaCB0aGlzIHdpbGwgbGF1bmNoIGNvbXBpbGUgd29ya2VyIGluc3RhbmNlLlxuICAgKi9cbiAgcmVhZG9ubHkgdnBjOiBJVnBjO1xuICAvKipcbiAgICogVGhlIGJ1Y2tldCB0byB1cGxvYWQgY29tcGlsZWQgYXJ0aWZhY3RzLlxuICAgKi9cbiAgcmVhZG9ubHkgYnVja2V0OiBJQnVja2V0O1xuICAvKipcbiAgICogVGhlIGluc3RhbmNlIHR5cGUgb2YgY29tcGlsZSB3b3JrZXIgaW5zdGFuY2UuXG4gICAqL1xuICByZWFkb25seSBuZXVyb254SW5zdGFuY2VUeXBlPzogSU5ldXJvbnhJbnN0YW5jZVR5cGU7XG4gIC8qKlxuICAgKiBUaGUgbW9kZWwgdG8gYmUgY29tcGlsZWQuXG4gICAqL1xuICByZWFkb25seSBtb2RlbDogTW9kZWw7XG4gIC8qKlxuICAgKiBUaGUgcm9vdCB2b2x1bWUgb2Ygd29ya2VyIGluc3RhbmNlLlxuICAgKiBAZGVmYXVsdCAtIE4gYmlsaW9uIHBhcmFtZXRlcnMgKiA1R2lCIEVCU1xuICAgKi9cbiAgcmVhZG9ubHkgdm9sdW1lU2l6ZT86IFNpemU7XG4gIC8qKlxuICAgKiBXaGV0aGVyIG9yIG5vdCB0byB1c2Ugc3BvdCBpbnN0YW5jZXMuIFNwb3QgaW5zdGFuY2VzIGFyZSBsZXNzIGV4cGVuc2l2ZSBFQzIgaW5zdGFuY2VzIHRoYXQgY2FuIGJlIHJlY2xhaW1lZCBieSBFQzIgYXQgYW55IHRpbWU7IHlvdXIgam9iIHdpbGwgYmUgZ2l2ZW4gdHdvIG1pbnV0ZXMgb2Ygbm90aWNlIGJlZm9yZSByZWNsYW1hdGlvbi5cbiAgICpcbiAgICogQGRlZmF1bHQgZmFsc2VcbiAgICovXG4gIHJlYWRvbmx5IHNwb3Q/OiBib29sZWFuO1xuICAvKipcbiAgICogVGhlIFZQQyBTdWJuZXRzIHRoaXMgQ29tcHV0ZSBFbnZpcm9ubWVudCB3aWxsIGxhdW5jaCBpbnN0YW5jZXMgaW4uXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gbmV3IHN1Ym5ldHMgd2lsbCBiZSBjcmVhdGVkXG4gICAqL1xuICByZWFkb25seSB2cGNTdWJuZXRzPzogU3VibmV0U2VsZWN0aW9uO1xuICAvKipcbiAgICogVGhlIGVudmlyb25tZW50IHZhcmlhYmxlcyB0byBwYXNzIHRvIHRoZSBjb250YWluZXIuXG4gICAqIFRoaXMgaXMgb25seSBhcHBsaWNhYmxlIHdoZW4gdXNpbmcgY29udGFpbmVyIHJ1bnRpbWUuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gTm8gZW52aXJvbm1lbnQgdmFyaWFibGVzLlxuICAgKi9cbiAgcmVhZG9ubHkgZW52aXJvbm1lbnQ/OiB7XG4gICAgW2tleTogc3RyaW5nXTogc3RyaW5nO1xuICB9O1xuICAvKipcbiAgICogVGhlIGFyZ3VtZW50cyB0byBwYXNzIHRvIHRoZSB2bGxtIGVuZ2luZS5cbiAgICogQGRlZmF1bHQgLSBubyBzcGVjaWZpYyB2YWx1ZXMuIHVzZSBkZWZhdWx0IHZhbHVlcy5cbiAgICovXG4gIHJlYWRvbmx5IHZsbG1BcmdzPzogVmxsbUVuZ2luZUFyZ3VtZW50cztcbiAgLyoqXG4gICAqIEFuIGltYWdlIG9mIHRoZSBjb250YWluZXIgd2hlcmUgdGhlIGNvbXBpbGUgam9iIGlzIGV4ZWN1dGVkLlxuICAgKiBAZGVmYXVsdCAtIGxhdGVzdCBpbWFnZVxuICAgKi9cbiAgcmVhZG9ubHkgaW1hZ2U/OiBJTmV1cm9ueENvbnRhaW5lckltYWdlO1xufVxuXG4vKipcbiAqIFRoZSBtb2RlbCBjb21waWxlZCBieSBOZXVyb254IGNvbXBpbGVyLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFZsbG1OeGRJbmZlcmVuY2VDb21waWxlZE1vZGVsIGV4dGVuZHMgTmV1cm9ueENvbXBpbGVkTW9kZWwge1xuICAvKipcbiAgICogUGFzc2VkIHRvIHRoZSB2bGxtIGVuZ2luZSBhdCBjb21waWxlIHRpbWUuXG4gICAqL1xuICByZWFkb25seSB2bGxtQXJnczogVmxsbUVuZ2luZUFyZ3VtZW50cztcbn1cblxuLyoqXG4gKiBOZXVyb254IGNvbXBpbGVyIGNvbnN0cnVjdCBmb3IgdkxMTSBvbiBOeEQgSW5mZXJlbmNlLlxuICogQ29tcGlsZSB0aGUgbW9kZWwgdG8gd29yayB3aXRoIE5ldXJvbnggaW5zdGFuY2UgYW5kIHVwbG9hZCBpdCB0byBhbiBTMyBidWNrZXQuXG4gKi9cbmV4cG9ydCBjbGFzcyBWbGxtTnhkSW5mZXJlbmNlQ29tcGlsZXIgZXh0ZW5kcyBDb25zdHJ1Y3Qge1xuICBwcml2YXRlIHJlYWRvbmx5IHZsbG1BcmdzOiBWbGxtRW5naW5lQXJndW1lbnRzO1xuICBwcml2YXRlIHJlYWRvbmx5IGNvbXBpbGVyOiBOZXVyb254Q29tcGlsZXI7XG4gIGNvbnN0cnVjdG9yKFxuICAgIHNjb3BlOiBDb25zdHJ1Y3QsXG4gICAgaWQ6IHN0cmluZyxcbiAgICBwcm9wczogVmxsbU54ZEluZmVyZW5jZUNvbXBpbGVQcm9wcyxcbiAgKSB7XG4gICAgc3VwZXIoc2NvcGUsIGlkKTtcbiAgICBjb25zdCBtYXhNb2RlbExlbiA9IHByb3BzLnZsbG1BcmdzPy5tYXhNb2RlbExlbiA/PyAxMjg7XG4gICAgY29uc3QgbWF4TnVtU2VxcyA9IHByb3BzLnZsbG1BcmdzPy5tYXhOdW1TZXFzID8/IDE7XG4gICAgY29uc3QgbWVtb3J5Rm9vdHByaW50ID0gcHJvcHMubW9kZWwub3B0aW9ucy5jb25maWdcbiAgICAgID8gY2FsY01lbW9yeUZvb3RwcmludChcbiAgICAgICAgICBwcm9wcy5tb2RlbC5vcHRpb25zLmNvbmZpZy5lbWJlZGRpbmdEaW1lbnNpb24sXG4gICAgICAgICAgcHJvcHMubW9kZWwub3B0aW9ucy5jb25maWcubGF5ZXJzLFxuICAgICAgICAgIERhdGFUeXBlQml0cy5CRjE2X09SX0ZQMTYsXG4gICAgICAgICAgbWF4TW9kZWxMZW4sXG4gICAgICAgICAgbWF4TnVtU2VxcyxcbiAgICAgICAgKVxuICAgICAgOiBpbmZlck1lbW9yeUZvb3RwcmludEZyb21QYXJhbWV0ZXJzKFxuICAgICAgICAgIHByb3BzLm1vZGVsLm9wdGlvbnMucGFyYW1ldGVycyxcbiAgICAgICAgICBtYXhNb2RlbExlbixcbiAgICAgICAgICBtYXhOdW1TZXFzLFxuICAgICAgICApO1xuICAgIGNvbnN0IG5ldXJvbnhJbnN0YW5jZVR5cGVzID0gcHJvcHMubmV1cm9ueEluc3RhbmNlVHlwZVxuICAgICAgPyBbcHJvcHMubmV1cm9ueEluc3RhbmNlVHlwZV1cbiAgICAgIDogW1xuICAgICAgICAgIE5ldXJvbnhJbnN0YW5jZVR5cGUuSU5GMl84WExBUkdFLFxuICAgICAgICAgIE5ldXJvbnhJbnN0YW5jZVR5cGUuSU5GMl8yNFhMQVJHRSxcbiAgICAgICAgICBOZXVyb254SW5zdGFuY2VUeXBlLklORjJfNDhYTEFSR0UsXG4gICAgICAgIF07XG4gICAgY29uc3QgYXZhaWxhYmxlSW5zdGFuY2VQYXR0ZXJucyA9IG5ldXJvbnhJbnN0YW5jZVR5cGVzXG4gICAgICAuZmxhdE1hcCgobmV1cm9ueEluc3RhbmNlVHlwZSkgPT5cbiAgICAgICAgY2FsY1RlbnNvclBhcmFsbGVsKFxuICAgICAgICAgIG5ldXJvbnhJbnN0YW5jZVR5cGUsXG4gICAgICAgICAgbWVtb3J5Rm9vdHByaW50LFxuICAgICAgICAgIHByb3BzLm1vZGVsLm9wdGlvbnMuY29uZmlnPy5hdHRlbnRpb25IZWFkcyxcbiAgICAgICAgKS5tYXAoKHYpID0+ICh7XG4gICAgICAgICAgbmV1cm9ueEluc3RhbmNlVHlwZSxcbiAgICAgICAgICAuLi52LFxuICAgICAgICB9KSksXG4gICAgICApXG4gICAgICAuZmlsdGVyKFxuICAgICAgICAoaW5zdGFuY2VUeXBlKSA9PlxuICAgICAgICAgICFwcm9wcy52bGxtQXJncz8udGVuc29yUGFyYWxsZWxTaXplIHx8XG4gICAgICAgICAgaW5zdGFuY2VUeXBlLnRwID09PSBwcm9wcy52bGxtQXJncy50ZW5zb3JQYXJhbGxlbFNpemUsXG4gICAgICApO1xuICAgIGlmIChhdmFpbGFibGVJbnN0YW5jZVBhdHRlcm5zLmxlbmd0aCA9PT0gMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICBgTm8gYXZhaWxhYmxlIGluc3RhbmNlIHR5cGUuIFlvdSBjYW4gdXNlIHRlbnNvclBhcmFsbGVsU2l6ZSBhcmUgJHthdmFpbGFibGVJbnN0YW5jZVBhdHRlcm5zLm1hcCgocCkgPT4gcC50cCkuam9pbihcIiwgXCIpfS5gLFxuICAgICAgKTtcbiAgICB9XG4gICAgY29uc3QgdGVuc29yUGFyYWxsZWxTaXplID0gYXZhaWxhYmxlSW5zdGFuY2VQYXR0ZXJuc1swXS50cDtcbiAgICBjb25zdCBpbWFnZSA9XG4gICAgICBwcm9wcy5pbWFnZSA/P1xuICAgICAgbmV3IFZsbG1OeGRJbmZlcmVuY2VDb21waWxlSW1hZ2UoUHl0b3JjaFRyYWluaW5nTmV1cm9ueEltYWdlLkxBVEVTVCk7XG4gICAgY29uc3QgdmxsbUFyZ3MgPSB7XG4gICAgICAuLi5wcm9wcy52bGxtQXJncyxcbiAgICAgIG1vZGVsOiBwcm9wcy5tb2RlbC5tb2RlbElkLFxuICAgICAgc2VydmVkTW9kZWxOYW1lOiBbcHJvcHMubW9kZWwubW9kZWxOYW1lXSxcbiAgICAgIG1heE1vZGVsTGVuLFxuICAgICAgbWF4TnVtU2VxcyxcbiAgICAgIHRlbnNvclBhcmFsbGVsU2l6ZSxcbiAgICB9IHNhdGlzZmllcyBWbGxtRW5naW5lQXJndW1lbnRzO1xuXG4gICAgLy8gY2hhbmdlIGRpcm5hbWUgZXZlcnkgZW5naW5lIGFyZ3MgcGF0dGVybnNcbiAgICBjb25zdCBoYXNoID0gKHN0cjogc3RyaW5nKSA9PlxuICAgICAgY3JlYXRlSGFzaChcInNoYTI1NlwiKS51cGRhdGUoc3RyKS5kaWdlc3QoXCJoZXhcIik7XG4gICAgY29uc3QgYXJ0aWZhY3RTM1ByZWZpeCA9IGBzZGstJHtpbWFnZS5zZGtWZXJzaW9ufS8ke2hhc2goSlNPTi5zdHJpbmdpZnkodmxsbUFyZ3MpKX1gO1xuICAgIGNvbnN0IHZsbG1DbGlBcmdzID0gVmxsbUVuZ2luZUFyZ3VtZW50c1BhcnNlci5jbGkodmxsbUFyZ3MpO1xuICAgIGNvbnN0IGVudmlyb25tZW50OiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0ge1xuICAgICAgLi4ucHJvcHMuZW52aXJvbm1lbnQsXG4gICAgICBWTExNX05FVVJPTl9GUkFNRVdPUks6IFwibmV1cm9ueC1kaXN0cmlidXRlZC1pbmZlcmVuY2VcIixcbiAgICAgIE5FVVJPTl9DT01QSUxFRF9BUlRJRkFDVFM6IFwibmV1cm9uLWNvbXBpbGVkLWFydGlmYWN0c1wiLFxuICAgICAgTkVVUk9OX1JUX05VTV9DT1JFUzogdGVuc29yUGFyYWxsZWxTaXplLnRvU3RyaW5nKCksXG4gICAgICBYTEFfSEFORExFX1NQRUNJQUxfU0NBTEFSOiBcIjFcIixcbiAgICAgIE1PREVMX0lEOiBwcm9wcy5tb2RlbC5tb2RlbElkLFxuICAgICAgTU9ERUxfTkFNRTogcHJvcHMubW9kZWwubW9kZWxOYW1lLFxuICAgICAgQ09NUElMRURfQVJUSUZBQ1RTX1MzX1VSSTogcHJvcHMuYnVja2V0LnMzVXJsRm9yT2JqZWN0KGFydGlmYWN0UzNQcmVmaXgpLFxuICAgICAgQ09NUElMRURfQVJUSUZBQ1RTX1MzX1BSRUZJWDogYXJ0aWZhY3RTM1ByZWZpeCxcbiAgICB9O1xuICAgIGNvbnN0IHNlY3JldHM6IHsgW2tleTogc3RyaW5nXTogYmF0Y2guU2VjcmV0IH0gPSB7fTtcbiAgICBpZiAocHJvcHMudmxsbUFyZ3M/LmhmVG9rZW4pIHtcbiAgICAgIHNlY3JldHMuSEZfVE9LRU4gPSBwcm9wcy52bGxtQXJncy5oZlRva2VuO1xuICAgIH1cbiAgICBjb25zdCB3ZWlnaHRTaXplID0gU2l6ZS5naWJpYnl0ZXMoXG4gICAgICBwcm9wcy5tb2RlbC5vcHRpb25zLnBhcmFtZXRlcnMudG9CaWxsaW9uKCkgKiAyLjUsXG4gICAgKTtcbiAgICBjb25zdCBxdWFudGl6ZWRXaWdodFNpemUgPSBwcm9wcy52bGxtQXJncz8ub3ZlcnJpZGVOZXVyb25Db25maWc/LnF1YW50aXplZFxuICAgICAgPyB3ZWlnaHRTaXplXG4gICAgICA6IFNpemUuYnl0ZXMoMCk7XG4gICAgY29uc3Qgdm9sdW1lU2l6ZSA9IFNpemUuZ2liaWJ5dGVzKFxuICAgICAgTWF0aC5jZWlsKFxuICAgICAgICB3ZWlnaHRTaXplLnRvR2liaWJ5dGVzKCkgK1xuICAgICAgICAgIHF1YW50aXplZFdpZ2h0U2l6ZS50b0dpYmlieXRlcygpICtcbiAgICAgICAgICBQeXRvcmNoVHJhaW5pbmdOZXVyb254SW1hZ2Uuc2l6ZS50b0dpYmlieXRlcygpICtcbiAgICAgICAgICBOZXVyb25PcHRpbWl6ZWRNYWNoaW5lSW1hZ2Uuc2l6ZS50b0dpYmlieXRlcygpLFxuICAgICAgKSxcbiAgICApO1xuXG4gICAgY29uc3QgY29tcGlsZXIgPSBuZXcgTmV1cm9ueENvbXBpbGVyKHRoaXMsIFwiUmVzb3VyY2VcIiwge1xuICAgICAgLi4ucHJvcHMsXG4gICAgICBuZXVyb254SW5zdGFuY2VUeXBlOiBhdmFpbGFibGVJbnN0YW5jZVBhdHRlcm5zWzBdLm5ldXJvbnhJbnN0YW5jZVR5cGUsXG4gICAgICBhcnRpZmFjdFMzUHJlZml4LFxuICAgICAgaW1hZ2U6IGltYWdlLFxuICAgICAgY29tbWFuZDogdmxsbUNsaUFyZ3MsXG4gICAgICBlbnZpcm9ubWVudCxcbiAgICAgIHNlY3JldHMsXG4gICAgICB2b2x1bWVTaXplLFxuICAgIH0pO1xuICAgIHRoaXMudmxsbUFyZ3MgPSB2bGxtQXJncztcbiAgICB0aGlzLmNvbXBpbGVyID0gY29tcGlsZXI7XG4gIH1cbiAgLyoqXG4gICAqIENvbXBpbGUgdGhlIG1vZGVsIGFuZCByZXR1cm4gdGhlIGNvbXBpbGVkIG1vZGVsLlxuICAgKiBAcmV0dXJucyBUaGUgY29tcGlsZWQgbW9kZWwuXG4gICAqL1xuICBjb21waWxlKCk6IFZsbG1OeGRJbmZlcmVuY2VDb21waWxlZE1vZGVsIHtcbiAgICByZXR1cm4ge1xuICAgICAgLi4udGhpcy5jb21waWxlci5jb21waWxlKCksXG4gICAgICB2bGxtQXJnczogdGhpcy52bGxtQXJncyxcbiAgICB9IHNhdGlzZmllcyBWbGxtTnhkSW5mZXJlbmNlQ29tcGlsZWRNb2RlbDtcbiAgfVxufVxuIl19