UNPKG

aws-cdk-neuronx-patterns

Version:
134 lines 18.5 kB
"use strict"; var _a, _b, _c, _d; Object.defineProperty(exports, "__esModule", { value: true }); exports.ApplicationLoadBalancedVllmNxDInferenceService = exports.VllmNxdInferenceTaskDefinition = exports.VllmNxdInferenceImage = exports.VllmNxdInferenceImageBase = void 0; const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti"); const aws_cdk_lib_1 = require("aws-cdk-lib"); const ecs = require("aws-cdk-lib/aws-ecs"); const constructs_1 = require("constructs"); const path_1 = require("path"); const aws_ecs_patterns_1 = require("../base/aws-ecs-patterns"); const neuronx_1 = require("../base/neuronx"); const vllm_engine_1 = require("../base/server-engine/vllm-engine"); /** * Base class for VllmNxdInferenceImage. */ class VllmNxdInferenceImageBase { constructor(neruonxImage, options = {}) { this.sdkVersion = neruonxImage.sdkVersion; this.vllmGitBranch = options.vllmGitBranch ?? "main"; this.vllmGitCommitHash = options.vllmGitCommitHash ?? ""; } } exports.VllmNxdInferenceImageBase = VllmNxdInferenceImageBase; _a = JSII_RTTI_SYMBOL_1; VllmNxdInferenceImageBase[_a] = { fqn: "aws-cdk-neuronx-patterns.VllmNxdInferenceImageBase", version: "0.0.23" }; /** * Inference container image for vLLM on NxD Inference. * @example new VllmNxdInferenceImage(PytorchTrainingNeuronxImage.LATEST) */ class VllmNxdInferenceImage extends VllmNxdInferenceImageBase { constructor(neruonxImage, options) { super(neruonxImage, options); this.image = ecs.ContainerImage.fromAsset((0, path_1.join)(__dirname, "../../scripts/inference/vllm-nxd-inference"), { buildArgs: { IMAGE_NAME: neruonxImage.imageName, IMAGE_TAG: neruonxImage.imageTag, VLLM_GIT_BRANCH: this.vllmGitBranch, VLLM_GIT_COMMIT_HASH: this.vllmGitCommitHash, }, }); } } exports.VllmNxdInferenceImage = VllmNxdInferenceImage; _b = JSII_RTTI_SYMBOL_1; VllmNxdInferenceImage[_b] = { fqn: "aws-cdk-neuronx-patterns.VllmNxdInferenceImage", version: "0.0.23" }; /** * Task definition for VllmNxdInference. */ class VllmNxdInferenceTaskDefinition extends aws_ecs_patterns_1.NeuronxTaskDefinition { constructor(scope, id, props) { const neuronxInstanceType = props.neuronxInstanceType ?? props.compiledModel.compileTimeInstanceType; const tensorParallelSize = props.compiledModel.vllmArgs.tensorParallelSize ?? 1; super(scope, id, { ...props, neuronxInstanceType, tensorParallelSize, }); const image = props.image ?? new VllmNxdInferenceImage(neuronx_1.PytorchTrainingNeuronxImage.LATEST); const port = props.compiledModel.vllmArgs.port ?? 8000; const vllmCliArgs = vllm_engine_1.VllmEngineArgumentsParser.cli(props.compiledModel.vllmArgs); // Prepare environment variables 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_NAME: props.compiledModel.modelName, COMPILED_ARTIFACTS_S3_URI: props.compiledModel.s3Uri, COMPILED_ARTIFACTS_S3_PREFIX: props.compiledModel.s3Prefix, }; this.addContainerWithDefault("vLLM", { image: image.image, portMappings: [ { containerPort: port, }, ], healthCheck: { command: [ "CMD-SHELL", `curl -f http://localhost:${port}/health || exit 1`, ], startPeriod: aws_cdk_lib_1.Duration.minutes(5), }, command: vllmCliArgs, environment, }); } } exports.VllmNxdInferenceTaskDefinition = VllmNxdInferenceTaskDefinition; _c = JSII_RTTI_SYMBOL_1; VllmNxdInferenceTaskDefinition[_c] = { fqn: "aws-cdk-neuronx-patterns.VllmNxdInferenceTaskDefinition", version: "0.0.23" }; /** * ApplicationLoadBalancedVllmNxDInferenceService is a wrapper of ApplicationLoadBalancedNeuronxServiceBase. * It provides a simple way to deploy vLLM on NxD Inference. * @example * const compiler = new VllmNxdInferenceCompiler(this, "Compiler", { * vpc, * bucket, * model: Model.fromHuggingFace("example/example-7b-chat"), * }); * const compiledModel = compiler.compile(); * const taskDefinition = new VllmNxdInferenceTaskDefinition( * this, * "TaskDefinition", * { * vpc, * compiledModel, * }, * ); * new ApplicationLoadBalancedVllmNxDInferenceService(this, "Service", { * taskDefinition, * }); */ class ApplicationLoadBalancedVllmNxDInferenceService extends constructs_1.Construct { constructor(scope, id, props) { super(scope, id); const resource = new aws_ecs_patterns_1.ApplicationLoadBalancedNeuronxService(this, "Resource", props); resource.targetGroup.configureHealthCheck({ path: "/health", }); this.loadBalancer = resource.loadBalancer; this.listener = resource.listener; this.targetGroup = resource.targetGroup; this.service = resource.service; this.taskDefinition = resource.taskDefinition; } } exports.ApplicationLoadBalancedVllmNxDInferenceService = ApplicationLoadBalancedVllmNxDInferenceService; _d = JSII_RTTI_SYMBOL_1; ApplicationLoadBalancedVllmNxDInferenceService[_d] = { fqn: "aws-cdk-neuronx-patterns.ApplicationLoadBalancedVllmNxDInferenceService", version: "0.0.23" }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmxsbS1ueGQtaW5mZXJlbmNlLWVjcy1wYXR0ZXJucy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy92bGxtLW54ZC1pbmZlcmVuY2UvdmxsbS1ueGQtaW5mZXJlbmNlLWVjcy1wYXR0ZXJucy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLDZDQUF1QztBQUN2QywyQ0FBMkM7QUFNM0MsMkNBQXVDO0FBQ3ZDLCtCQUE0QjtBQUM1QiwrREFLa0M7QUFDbEMsNkNBQTZFO0FBRTdFLG1FQUE4RTtBQU85RTs7R0FFRztBQUNILE1BQXNCLHlCQUF5QjtJQXFCN0MsWUFDRSxZQUEyQixFQUMzQixVQUF3QyxFQUFFO1FBRTFDLElBQUksQ0FBQyxVQUFVLEdBQUcsWUFBWSxDQUFDLFVBQVUsQ0FBQztRQUMxQyxJQUFJLENBQUMsYUFBYSxHQUFHLE9BQU8sQ0FBQyxhQUFhLElBQUksTUFBTSxDQUFDO1FBQ3JELElBQUksQ0FBQyxpQkFBaUIsR0FBRyxPQUFPLENBQUMsaUJBQWlCLElBQUksRUFBRSxDQUFDO0lBQzNELENBQUM7O0FBNUJILDhEQTZCQzs7O0FBRUQ7OztHQUdHO0FBQ0gsTUFBYSxxQkFBc0IsU0FBUSx5QkFBeUI7SUFFbEUsWUFDRSxZQUEyQixFQUMzQixPQUFzQztRQUV0QyxLQUFLLENBQUMsWUFBWSxFQUFFLE9BQU8sQ0FBQyxDQUFDO1FBQzdCLElBQUksQ0FBQyxLQUFLLEdBQUcsR0FBRyxDQUFDLGNBQWMsQ0FBQyxTQUFTLENBQ3ZDLElBQUEsV0FBSSxFQUFDLFNBQVMsRUFBRSw0Q0FBNEMsQ0FBQyxFQUM3RDtZQUNFLFNBQVMsRUFBRTtnQkFDVCxVQUFVLEVBQUUsWUFBWSxDQUFDLFNBQVM7Z0JBQ2xDLFNBQVMsRUFBRSxZQUFZLENBQUMsUUFBUTtnQkFDaEMsZUFBZSxFQUFFLElBQUksQ0FBQyxhQUFhO2dCQUNuQyxvQkFBb0IsRUFBRSxJQUFJLENBQUMsaUJBQWlCO2FBQzdDO1NBQ0YsQ0FDRixDQUFD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fSBmcm9tIFwiYXdzLWNkay1saWJcIjtcbmltcG9ydCAqIGFzIGVjcyBmcm9tIFwiYXdzLWNkay1saWIvYXdzLWVjc1wiO1xuaW1wb3J0IHtcbiAgQXBwbGljYXRpb25MaXN0ZW5lcixcbiAgQXBwbGljYXRpb25Mb2FkQmFsYW5jZXIsXG4gIEFwcGxpY2F0aW9uVGFyZ2V0R3JvdXAsXG59IGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtZWxhc3RpY2xvYWRiYWxhbmNpbmd2MlwiO1xuaW1wb3J0IHsgQ29uc3RydWN0IH0gZnJvbSBcImNvbnN0cnVjdHNcIjtcbmltcG9ydCB7IGpvaW4gfSBmcm9tIFwicGF0aFwiO1xuaW1wb3J0IHtcbiAgQXBwbGljYXRpb25Mb2FkQmFsYW5jZWROZXVyb254U2VydmljZSxcbiAgQXBwbGljYXRpb25Mb2FkQmFsYW5jZWROZXVyb254U2VydmljZVByb3BzLFxuICBOZXVyb254VGFza0RlZmluaXRpb24sXG4gIE5ldXJvbnhUYXNrRGVmaW5pdGlvblByb3BzQmFzZSxcbn0gZnJvbSBcIi4uL2Jhc2UvYXdzLWVjcy1wYXR0ZXJuc1wiO1xuaW1wb3J0IHsgSU5ldXJvbnhJbWFnZSwgUHl0b3JjaFRyYWluaW5nTmV1cm9ueEltYWdlIH0gZnJvbSBcIi4uL2Jhc2UvbmV1cm9ueFwiO1xuaW1wb3J0IHsgSU5ldXJvbnhDb250YWluZXJJbWFnZSB9IGZyb20gXCIuLi9iYXNlL25ldXJvbngtY29tcGlsZXJcIjtcbmltcG9ydCB7IFZsbG1FbmdpbmVBcmd1bWVudHNQYXJzZXIgfSBmcm9tIFwiLi4vYmFzZS9zZXJ2ZXItZW5naW5lL3ZsbG0tZW5naW5lXCI7XG5pbXBvcnQgeyBWbGxtTnhkSW5mZXJlbmNlQ29tcGlsZWRNb2RlbCB9IGZyb20gXCIuL3ZsbG0tbnhkLWluZmVyZW5jZS1jb21waWxlclwiO1xuXG5leHBvcnQgaW50ZXJmYWNlIFZsbG1OeGRJbmZlcmVuY2VJbWFnZU9wdGlvbnMge1xuICByZWFkb25seSB2bGxtR2l0QnJhbmNoPzogc3RyaW5nO1xuICByZWFkb25seSB2bGxtR2l0Q29tbWl0SGFzaD86IHN0cmluZztcbn1cbi8qKlxuICogQmFzZSBjbGFzcyBmb3IgVmxsbU54ZEluZmVyZW5jZUltYWdlLlxuICovXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgVmxsbU54ZEluZmVyZW5jZUltYWdlQmFzZVxuICBpbXBsZW1lbnRzIElOZXVyb254Q29udGFpbmVySW1hZ2VcbntcbiAgLyoqXG4gICAqIFRoZSBjb250YWluZXIgaW1hZ2UuXG4gICAqL1xuICBhYnN0cmFjdCByZWFkb25seSBpbWFnZTogZWNzLkNvbnRhaW5lckltYWdlO1xuICAvKipcbiAgICogVGhlIEdpdCBicmFuY2ggbmFtZSBvZiBhd3MtbmV1cm9uL3Vwc3RyZWFtaW5nLXRvLXZsbG0uXG4gICAqIEBzZWUgaHR0cHM6Ly9naXRodWIuY29tL2F3cy1uZXVyb24vdXBzdHJlYW1pbmctdG8tdmxsbVxuICAgKi9cbiAgcmVhZG9ubHkgdmxsbUdpdEJyYW5jaDogc3RyaW5nO1xuICAvKipcbiAgICogVGhlIEdpdCBjb21taXQgZm9zaCBvZiBhd3MtbmV1cm9uL3Vwc3RyZWFtaW5nLXRvLXZsbG0uXG4gICAqIEBzZWUgaHR0cHM6Ly9naXRodWIuY29tL2F3cy1uZXVyb24vdXBzdHJlYW1pbmctdG8tdmxsbVxuICAgKi9cbiAgcmVhZG9ubHkgdmxsbUdpdENvbW1pdEhhc2g6IHN0cmluZztcbiAgLyoqXG4gICAqIFRoZSBuZXVyb254IFNESyB2ZXJzaW9uLlxuICAgKi9cbiAgcmVhZG9ubHkgc2RrVmVyc2lvbjogc3RyaW5nO1xuICBjb25zdHJ1Y3RvcihcbiAgICBuZXJ1b254SW1hZ2U6IElOZXVyb254SW1hZ2UsXG4gICAgb3B0aW9uczogVmxsbU54ZEluZmVyZW5jZUltYWdlT3B0aW9ucyA9IHt9LFxuICApIHtcbiAgICB0aGlzLnNka1ZlcnNpb24gPSBuZXJ1b254SW1hZ2Uuc2RrVmVyc2lvbjtcbiAgICB0aGlzLnZsbG1HaXRCcmFuY2ggPSBvcHRpb25zLnZsbG1HaXRCcmFuY2ggPz8gXCJtYWluXCI7XG4gICAgdGhpcy52bGxtR2l0Q29tbWl0SGFzaCA9IG9wdGlvbnMudmxsbUdpdENvbW1pdEhhc2ggPz8gXCJcIjtcbiAgfVxufVxuXG4vKipcbiAqIEluZmVyZW5jZSBjb250YWluZXIgaW1hZ2UgZm9yIHZMTE0gb24gTnhEIEluZmVyZW5jZS5cbiAqIEBleGFtcGxlIG5ldyBWbGxtTnhkSW5mZXJlbmNlSW1hZ2UoUHl0b3JjaFRyYWluaW5nTmV1cm9ueEltYWdlLkxBVEVTVClcbiAqL1xuZXhwb3J0IGNsYXNzIFZsbG1OeGRJbmZlcmVuY2VJbWFnZSBleHRlbmRzIFZsbG1OeGRJbmZlcmVuY2VJbWFnZUJhc2Uge1xuICByZWFkb25seSBpbWFnZTogZWNzLkNvbnRhaW5lckltYWdlO1xuICBjb25zdHJ1Y3RvcihcbiAgICBuZXJ1b254SW1hZ2U6IElOZXVyb254SW1hZ2UsXG4gICAgb3B0aW9ucz86IFZsbG1OeGRJbmZlcmVuY2VJbWFnZU9wdGlvbnMsXG4gICkge1xuICAgIHN1cGVyKG5lcnVvbnhJbWFnZSwgb3B0aW9ucyk7XG4gICAgdGhpcy5pbWFnZSA9IGVjcy5Db250YWluZXJJbWFnZS5mcm9tQXNzZXQoXG4gICAgICBqb2luKF9fZGlybmFtZSwgXCIuLi8uLi9zY3JpcHRzL2luZmVyZW5jZS92bGxtLW54ZC1pbmZlcmVuY2VcIiksXG4gICAgICB7XG4gICAgICAgIGJ1aWxkQXJnczoge1xuICAgICAgICAgIElNQUdFX05BTUU6IG5lcnVvbnhJbWFnZS5pbWFnZU5hbWUsXG4gICAgICAgICAgSU1BR0VfVEFHOiBuZXJ1b254SW1hZ2UuaW1hZ2VUYWcsXG4gICAgICAgICAgVkxMTV9HSVRfQlJBTkNIOiB0aGlzLnZsbG1HaXRCcmFuY2gsXG4gICAgICAgICAgVkxMTV9HSVRfQ09NTUlUX0hBU0g6IHRoaXMudmxsbUdpdENvbW1pdEhhc2gsXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgICk7XG4gIH1cbn1cblxuLyoqXG4gKiBUYXNrIGRlZmluaXRpb24gZm9yIFZsbG1OeGRJbmZlcmVuY2UuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgVmxsbU54ZEluZmVyZW5jZVRhc2tEZWZpbml0aW9uUHJvcHNcbiAgZXh0ZW5kcyBOZXVyb254VGFza0RlZmluaXRpb25Qcm9wc0Jhc2Uge1xuICAvKipcbiAgICogVGhlIG1vZGVsIHRvIGJlIGNvbXBpbGVkLlxuICAgKi9cbiAgcmVhZG9ubHkgY29tcGlsZWRNb2RlbDogVmxsbU54ZEluZmVyZW5jZUNvbXBpbGVkTW9kZWw7XG4gIC8qKlxuICAgKiBUaGUgaW1hZ2UgdG8gYmUgdXNlZCBmb3IgdGhlIGNvbnRhaW5lci5cbiAgICogQGRlZmF1bHQgLSBsYXRlc3QgVmxsbU54ZEluZmVyZW5jZUltYWdlXG4gICAqL1xuICByZWFkb25seSBpbWFnZT86IFZsbG1OeGRJbmZlcmVuY2VJbWFnZTtcbiAgLyoqXG4gICAqIFRoZSBlbnZpcm9ubWVudCB2YXJpYWJsZXMgdG8gcGFzcyB0byB0aGUgY29udGFpbmVyLlxuICAgKiBUaGlzIGlzIG9ubHkgYXBwbGljYWJsZSB3aGVuIHVzaW5nIGNvbnRhaW5lciBydW50aW1lLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIE5vIGVudmlyb25tZW50IHZhcmlhYmxlcy5cbiAgICovXG4gIHJlYWRvbmx5IGVudmlyb25tZW50Pzoge1xuICAgIFtrZXk6IHN0cmluZ106IHN0cmluZztcbiAgfTtcbn1cblxuLyoqXG4gKiBUYXNrIGRlZmluaXRpb24gZm9yIFZsbG1OeGRJbmZlcmVuY2UuXG4gKi9cbmV4cG9ydCBjbGFzcyBWbGxtTnhkSW5mZXJlbmNlVGFza0RlZmluaXRpb24gZXh0ZW5kcyBOZXVyb254VGFza0RlZmluaXRpb24ge1xuICBjb25zdHJ1Y3RvcihcbiAgICBzY29wZTogQ29uc3RydWN0LFxuICAgIGlkOiBzdHJpbmcsXG4gICAgcHJvcHM6IFZsbG1OeGRJbmZlcmVuY2VUYXNrRGVmaW5pdGlvblByb3BzLFxuICApIHtcbiAgICBjb25zdCBuZXVyb254SW5zdGFuY2VUeXBlID1cbiAgICAgIHByb3BzLm5ldXJvbnhJbnN0YW5jZVR5cGUgPz8gcHJvcHMuY29tcGlsZWRNb2RlbC5jb21waWxlVGltZUluc3RhbmNlVHlwZTtcbiAgICBjb25zdCB0ZW5zb3JQYXJhbGxlbFNpemUgPVxuICAgICAgcHJvcHMuY29tcGlsZWRNb2RlbC52bGxtQXJncy50ZW5zb3JQYXJhbGxlbFNpemUgPz8gMTtcbiAgICBzdXBlcihzY29wZSwgaWQsIHtcbiAgICAgIC4uLnByb3BzLFxuICAgICAgbmV1cm9ueEluc3RhbmNlVHlwZSxcbiAgICAgIHRlbnNvclBhcmFsbGVsU2l6ZSxcbiAgICB9KTtcbiAgICBjb25zdCBpbWFnZSA9XG4gICAgICBwcm9wcy5pbWFnZSA/P1xuICAgICAgbmV3IFZsbG1OeGRJbmZlcmVuY2VJbWFnZShQeXRvcmNoVHJhaW5pbmdOZXVyb254SW1hZ2UuTEFURVNUKTtcbiAgICBjb25zdCBwb3J0ID0gcHJvcHMuY29tcGlsZWRNb2RlbC52bGxtQXJncy5wb3J0ID8/IDgwMDA7XG4gICAgY29uc3QgdmxsbUNsaUFyZ3MgPSBWbGxtRW5naW5lQXJndW1lbnRzUGFyc2VyLmNsaShcbiAgICAgIHByb3BzLmNvbXBpbGVkTW9kZWwudmxsbUFyZ3MsXG4gICAgKTtcbiAgICAvLyBQcmVwYXJlIGVudmlyb25tZW50IHZhcmlhYmxlc1xuICAgIGNvbnN0IGVudmlyb25tZW50OiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0ge1xuICAgICAgLi4ucHJvcHMuZW52aXJvbm1lbnQsXG4gICAgICBWTExNX05FVVJPTl9GUkFNRVdPUks6IFwibmV1cm9ueC1kaXN0cmlidXRlZC1pbmZlcmVuY2VcIixcbiAgICAgIE5FVVJPTl9DT01QSUxFRF9BUlRJRkFDVFM6IFwibmV1cm9uLWNvbXBpbGVkLWFydGlmYWN0c1wiLFxuICAgICAgTkVVUk9OX1JUX05VTV9DT1JFUzogdGVuc29yUGFyYWxsZWxTaXplLnRvU3RyaW5nKCksXG4gICAgICBYTEFfSEFORExFX1NQRUNJQUxfU0NBTEFSOiBcIjFcIixcbiAgICAgIE1PREVMX05BTUU6IHByb3BzLmNvbXBpbGVkTW9kZWwubW9kZWxOYW1lLFxuICAgICAgQ09NUElMRURfQVJUSUZBQ1RTX1MzX1VSSTogcHJvcHMuY29tcGlsZWRNb2RlbC5zM1VyaSxcbiAgICAgIENPTVBJTEVEX0FSVElGQUNUU19TM19QUkVGSVg6IHByb3BzLmNvbXBpbGVkTW9kZWwuczNQcmVmaXgsXG4gICAgfTtcblxuICAgIHRoaXMuYWRkQ29udGFpbmVyV2l0aERlZmF1bHQoXCJ2TExNXCIsIHtcbiAgICAgIGltYWdlOiBpbWFnZS5pbWFnZSxcbiAgICAgIHBvcnRNYXBwaW5nczogW1xuICAgICAgICB7XG4gICAgICAgICAgY29udGFpbmVyUG9ydDogcG9ydCxcbiAgICAgICAgfSxcbiAgICAgIF0sXG4gICAgICBoZWFsdGhDaGVjazoge1xuICAgICAgICBjb21tYW5kOiBbXG4gICAgICAgICAgXCJDTUQtU0hFTExcIixcbiAgICAgICAgICBgY3VybCAtZiBodHRwOi8vbG9jYWxob3N0OiR7cG9ydH0vaGVhbHRoIHx8IGV4aXQgMWAsXG4gICAgICAgIF0sXG4gICAgICAgIHN0YXJ0UGVyaW9kOiBEdXJhdGlvbi5taW51dGVzKDUpLFxuICAgICAgfSxcbiAgICAgIGNvbW1hbmQ6IHZsbG1DbGlBcmdzLFxuICAgICAgZW52aXJvbm1lbnQsXG4gICAgfSk7XG4gIH1cbn1cblxuLyoqXG4gKiBQcm9wcyBmb3IgQXBwbGljYXRpb25Mb2FkQmFsYW5jZWRWbGxtTnhESW5mZXJlbmNlU2VydmljZS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBBcHBsaWNhdGlvbkxvYWRCYWxhbmNlZFZsbG1OeERJbmZlcmVuY2VTZXJ2aWNlUHJvcHNcbiAgZXh0ZW5kcyBBcHBsaWNhdGlvbkxvYWRCYWxhbmNlZE5ldXJvbnhTZXJ2aWNlUHJvcHMge31cblxuLyoqXG4gKiBBcHBsaWNhdGlvbkxvYWRCYWxhbmNlZFZsbG1OeERJbmZlcmVuY2VTZXJ2aWNlIGlzIGEgd3JhcHBlciBvZiBBcHBsaWNhdGlvbkxvYWRCYWxhbmNlZE5ldXJvbnhTZXJ2aWNlQmFzZS5cbiAqIEl0IHByb3ZpZGVzIGEgc2ltcGxlIHdheSB0byBkZXBsb3kgdkxMTSBvbiBOeEQgSW5mZXJlbmNlLlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IGNvbXBpbGVyID0gbmV3IFZsbG1OeGRJbmZlcmVuY2VDb21waWxlcih0aGlzLCBcIkNvbXBpbGVyXCIsIHtcbiAqICAgdnBjLFxuICogICBidWNrZXQsXG4gKiAgIG1vZGVsOiBNb2RlbC5mcm9tSHVnZ2luZ0ZhY2UoXCJleGFtcGxlL2V4YW1wbGUtN2ItY2hhdFwiKSxcbiAqIH0pO1xuICogY29uc3QgY29tcGlsZWRNb2RlbCA9IGNvbXBpbGVyLmNvbXBpbGUoKTtcbiAqIGNvbnN0IHRhc2tEZWZpbml0aW9uID0gbmV3IFZsbG1OeGRJbmZlcmVuY2VUYXNrRGVmaW5pdGlvbihcbiAqICAgdGhpcyxcbiAqICAgXCJUYXNrRGVmaW5pdGlvblwiLFxuICogICB7XG4gKiAgICAgdnBjLFxuICogICAgIGNvbXBpbGVkTW9kZWwsXG4gKiAgIH0sXG4gKiApO1xuICogbmV3IEFwcGxpY2F0aW9uTG9hZEJhbGFuY2VkVmxsbU54REluZmVyZW5jZVNlcnZpY2UodGhpcywgXCJTZXJ2aWNlXCIsIHtcbiAqICAgdGFza0RlZmluaXRpb24sXG4gKiB9KTtcbiAqL1xuZXhwb3J0IGNsYXNzIEFwcGxpY2F0aW9uTG9hZEJhbGFuY2VkVmxsbU54REluZmVyZW5jZVNlcnZpY2UgZXh0ZW5kcyBDb25zdHJ1Y3Qge1xuICByZWFkb25seSBsb2FkQmFsYW5jZXI6IEFwcGxpY2F0aW9uTG9hZEJhbGFuY2VyO1xuICByZWFkb25seSBsaXN0ZW5lcjogQXBwbGljYXRpb25MaXN0ZW5lcjtcbiAgcmVhZG9ubHkgdGFyZ2V0R3JvdXA6IEFwcGxpY2F0aW9uVGFyZ2V0R3JvdXA7XG4gIHJlYWRvbmx5IHNlcnZpY2U6IGVjcy5FYzJTZXJ2aWNlO1xuICByZWFkb25seSB0YXNrRGVmaW5pdGlvbjogZWNzLkVjMlRhc2tEZWZpbml0aW9uO1xuICBjb25zdHJ1Y3RvcihcbiAgICBzY29wZTogQ29uc3RydWN0LFxuICAgIGlkOiBzdHJpbmcsXG4gICAgcHJvcHM6IEFwcGxpY2F0aW9uTG9hZEJhbGFuY2VkVmxsbU54REluZmVyZW5jZVNlcnZpY2VQcm9wcyxcbiAgKSB7XG4gICAgc3VwZXIoc2NvcGUsIGlkKTtcbiAgICBjb25zdCByZXNvdXJjZSA9IG5ldyBBcHBsaWNhdGlvbkxvYWRCYWxhbmNlZE5ldXJvbnhTZXJ2aWNlKFxuICAgICAgdGhpcyxcbiAgICAgIFwiUmVzb3VyY2VcIixcbiAgICAgIHByb3BzLFxuICAgICk7XG4gICAgcmVzb3VyY2UudGFyZ2V0R3JvdXAuY29uZmlndXJlSGVhbHRoQ2hlY2soe1xuICAgICAgcGF0aDogXCIvaGVhbHRoXCIsXG4gICAgfSk7XG4gICAgdGhpcy5sb2FkQmFsYW5jZXIgPSByZXNvdXJjZS5sb2FkQmFsYW5jZXI7XG4gICAgdGhpcy5saXN0ZW5lciA9IHJlc291cmNlLmxpc3RlbmVyO1xuICAgIHRoaXMudGFyZ2V0R3JvdXAgPSByZXNvdXJjZS50YXJnZXRHcm91cDtcbiAgICB0aGlzLnNlcnZpY2UgPSByZXNvdXJjZS5zZXJ2aWNlO1xuICAgIHRoaXMudGFza0RlZmluaXRpb24gPSByZXNvdXJjZS50YXNrRGVmaW5pdGlvbjtcbiAgfVxufVxuIl19