UNPKG

@softchef/cdk-iot-device-management

Version:

IoT device management is composed of things, thing types, thing groups, jobs, files API services. The constructs can be used independently, that are based on full-managed service to create an API Gateway & Lambda function.

471 lines 56.2 kB
"use strict"; var _a; Object.defineProperty(exports, "__esModule", { value: true }); exports.JobApi = void 0; const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti"); const path = require("path"); const cdk_restapi_1 = require("@softchef/cdk-restapi"); const aws_apigateway_1 = require("aws-cdk-lib/aws-apigateway"); const aws_iam_1 = require("aws-cdk-lib/aws-iam"); const aws_lambda_nodejs_1 = require("aws-cdk-lib/aws-lambda-nodejs"); const constructs_1 = require("constructs"); const LAMBDA_ASSETS_PATH = path.resolve(__dirname, '../lambda-assets/jobs'); /** * Job API construct. * * @stability stable */ class JobApi extends constructs_1.Construct { /** * @stability stable */ constructor(scope, id, props) { var _b, _c, _d, _e; super(scope, id); this._restApi = new cdk_restapi_1.RestApi(this, 'JobRestApi', { enableCors: true, authorizationType: (_b = props === null || props === void 0 ? void 0 : props.authorizationType) !== null && _b !== void 0 ? _b : aws_apigateway_1.AuthorizationType.NONE, authorizer: (_c = props === null || props === void 0 ? void 0 : props.authorizer) !== null && _c !== void 0 ? _c : undefined, resources: [ { path: '/jobs/{jobId}/associate', httpMethod: cdk_restapi_1.HttpMethod.PUT, lambdaFunction: this.createAssociateTargetsWithJobFunction(), }, { path: '/jobs', httpMethod: cdk_restapi_1.HttpMethod.POST, lambdaFunction: this.createCreateJobFunction(), }, { path: '/jobs', httpMethod: cdk_restapi_1.HttpMethod.GET, lambdaFunction: this.createListJobsFunction(), }, { path: '/jobs/{jobId}', httpMethod: cdk_restapi_1.HttpMethod.GET, lambdaFunction: this.createGetJobFunction(), }, { path: '/jobs/{jobId}', httpMethod: cdk_restapi_1.HttpMethod.PUT, lambdaFunction: this.createUpdateJobFunction(), }, { path: '/jobs/{jobId}', httpMethod: cdk_restapi_1.HttpMethod.DELETE, lambdaFunction: this.createDeleteJobFunction(), }, { path: '/jobs/{jobId}/cancel', httpMethod: cdk_restapi_1.HttpMethod.PUT, lambdaFunction: this.createCancelJobFunction(), }, { path: '/jobs/{jobId}/document', httpMethod: cdk_restapi_1.HttpMethod.GET, lambdaFunction: this.createGetJobDocumentFunction(), }, { path: '/jobs/{jobId}/things/{thingName}', httpMethod: cdk_restapi_1.HttpMethod.GET, lambdaFunction: this.createGetJobExecutionFunction(), }, { path: 'jobs/{jobId}/status', httpMethod: cdk_restapi_1.HttpMethod.GET, lambdaFunction: this.createListJobExecutionsForJobFunction(), }, { path: '/things/{thingName}/jobs', httpMethod: cdk_restapi_1.HttpMethod.GET, lambdaFunction: this.createListJobExecutionsForThingFunction(), }, { path: '/jobs/{jobId}/things/{thingName}', httpMethod: cdk_restapi_1.HttpMethod.DELETE, lambdaFunction: this.createDeleteJobExecutionFunction(), }, { path: '/jobs/{jobId}/things/{thingName}/cancel', httpMethod: cdk_restapi_1.HttpMethod.PUT, lambdaFunction: this.createCancelJobExecutionFunction(), }, { path: '/job-templates', httpMethod: cdk_restapi_1.HttpMethod.POST, lambdaFunction: this.createCreateJobTemplateFunction(), }, { path: '/job-templates', httpMethod: cdk_restapi_1.HttpMethod.GET, lambdaFunction: this.createListJobTemplatesFunction(), }, { path: '/job-templates/{jobTemplateId}', httpMethod: cdk_restapi_1.HttpMethod.GET, lambdaFunction: this.createGetJobTemplateFunction(), }, { path: '/job-templates/{jobTemplateId}', httpMethod: cdk_restapi_1.HttpMethod.DELETE, lambdaFunction: this.createDeleteJobTemplateFunction(), }, ], }); if (props === null || props === void 0 ? void 0 : props.scheduleFunction) { const targetType = 'CreateJob'; props.scheduleFunction.addTargetFunction(targetType, { targetFunction: this.createCreateScheduleJobFunction(), }); (_d = props === null || props === void 0 ? void 0 : props.scheduleFunction) === null || _d === void 0 ? void 0 : _d.listSchedulesFunction.addEnvironment('FIXED_TARGET_TYPE', targetType); (_e = props === null || props === void 0 ? void 0 : props.scheduleFunction) === null || _e === void 0 ? void 0 : _e.createScheduleFunction.addEnvironment('FIXED_TARGET_TYPE', targetType); this._restApi.addResources([ { path: '/schedules', httpMethod: cdk_restapi_1.HttpMethod.GET, lambdaFunction: props === null || props === void 0 ? void 0 : props.scheduleFunction.listSchedulesFunction, }, { path: '/schedules', httpMethod: cdk_restapi_1.HttpMethod.POST, lambdaFunction: props === null || props === void 0 ? void 0 : props.scheduleFunction.createScheduleFunction, }, { path: '/schedules/{scheduleId}', httpMethod: cdk_restapi_1.HttpMethod.GET, lambdaFunction: props === null || props === void 0 ? void 0 : props.scheduleFunction.fetchScheduleFunction, }, { path: '/schedules/{scheduleId}', httpMethod: cdk_restapi_1.HttpMethod.PUT, lambdaFunction: props === null || props === void 0 ? void 0 : props.scheduleFunction.updateScheduleFunction, }, { path: '/schedules/{scheduleId}', httpMethod: cdk_restapi_1.HttpMethod.DELETE, lambdaFunction: props === null || props === void 0 ? void 0 : props.scheduleFunction.deleteScheduleFunction, }, ]); } } /** * Job API API ID. * * @stability stable */ get restApiId() { return this._restApi.restApiId; } createCreateScheduleJobFunction() { var _b; const createJobFunction = new aws_lambda_nodejs_1.NodejsFunction(this, 'CreateScheduleJobFunction', { entry: `${LAMBDA_ASSETS_PATH}/create-schedule-job/app.ts`, }); (_b = createJobFunction.role) === null || _b === void 0 ? void 0 : _b.attachInlinePolicy(new aws_iam_1.Policy(this, 'iot-create-schedule-job-policy', { statements: [ new aws_iam_1.PolicyStatement({ actions: [ 'iot:CreateJob', ], resources: ['*'], }), ], })); return createJobFunction; } createAssociateTargetsWithJobFunction() { var _b; const createJobFunction = new aws_lambda_nodejs_1.NodejsFunction(this, 'AssociateTargetsWithJobFunction', { entry: `${LAMBDA_ASSETS_PATH}/associate-targets-with-job/app.ts`, }); (_b = createJobFunction.role) === null || _b === void 0 ? void 0 : _b.attachInlinePolicy(new aws_iam_1.Policy(this, 'iot-associate-targets-with-job', { statements: [ new aws_iam_1.PolicyStatement({ actions: [ 'iot:AssociateTargetsWithJob', ], resources: ['*'], }), ], })); return createJobFunction; } createCreateJobFunction() { var _b; const createJobFunction = new aws_lambda_nodejs_1.NodejsFunction(this, 'CreateJobFunction', { entry: `${LAMBDA_ASSETS_PATH}/create-job/app.ts`, }); (_b = createJobFunction.role) === null || _b === void 0 ? void 0 : _b.attachInlinePolicy(new aws_iam_1.Policy(this, 'iot-create-job-policy', { statements: [ new aws_iam_1.PolicyStatement({ actions: [ 'iot:CreateJob', ], resources: ['*'], }), ], })); return createJobFunction; } createListJobsFunction() { var _b; const listJobsFunction = new aws_lambda_nodejs_1.NodejsFunction(this, 'ListJobsFunction', { entry: `${LAMBDA_ASSETS_PATH}/list-jobs/app.ts`, }); (_b = listJobsFunction.role) === null || _b === void 0 ? void 0 : _b.attachInlinePolicy(new aws_iam_1.Policy(this, 'iot-list-jobs-policy', { statements: [ new aws_iam_1.PolicyStatement({ actions: [ 'iot:ListJobs', ], resources: ['*'], }), ], })); return listJobsFunction; } createGetJobFunction() { var _b; const getJobFunction = new aws_lambda_nodejs_1.NodejsFunction(this, 'GetJobFunction', { entry: `${LAMBDA_ASSETS_PATH}/get-job/app.ts`, }); (_b = getJobFunction.role) === null || _b === void 0 ? void 0 : _b.attachInlinePolicy(new aws_iam_1.Policy(this, 'iot-describe-job-policy', { statements: [ new aws_iam_1.PolicyStatement({ actions: [ 'iot:DescribeJob', ], resources: ['*'], }), ], })); return getJobFunction; } createUpdateJobFunction() { var _b; const updateJobFunction = new aws_lambda_nodejs_1.NodejsFunction(this, 'UpdateJobFunction', { entry: `${LAMBDA_ASSETS_PATH}/update-job/app.ts`, }); (_b = updateJobFunction.role) === null || _b === void 0 ? void 0 : _b.attachInlinePolicy(new aws_iam_1.Policy(this, 'iot-update-job-policy', { statements: [ new aws_iam_1.PolicyStatement({ actions: [ 'iot:UpdateJob', ], resources: ['*'], }), ], })); return updateJobFunction; } createDeleteJobFunction() { var _b; const deleteJobFunction = new aws_lambda_nodejs_1.NodejsFunction(this, 'DeleteJobFunction', { entry: `${LAMBDA_ASSETS_PATH}/delete-job/app.ts`, }); (_b = deleteJobFunction.role) === null || _b === void 0 ? void 0 : _b.attachInlinePolicy(new aws_iam_1.Policy(this, 'iot-delete-job-policy', { statements: [ new aws_iam_1.PolicyStatement({ actions: [ 'iot:DeleteJob', ], resources: ['*'], }), ], })); return deleteJobFunction; } createCancelJobFunction() { var _b; const cancelJobFunction = new aws_lambda_nodejs_1.NodejsFunction(this, 'CancelJobFunction', { entry: `${LAMBDA_ASSETS_PATH}/cancel-job/app.ts`, }); (_b = cancelJobFunction.role) === null || _b === void 0 ? void 0 : _b.attachInlinePolicy(new aws_iam_1.Policy(this, 'iot-cancel-job-policy', { statements: [ new aws_iam_1.PolicyStatement({ actions: [ 'iot:CancelJob', ], resources: ['*'], }), ], })); return cancelJobFunction; } createGetJobExecutionFunction() { var _b; const getJobExecutionFunction = new aws_lambda_nodejs_1.NodejsFunction(this, 'GetJobExecutionFunction', { entry: `${LAMBDA_ASSETS_PATH}/get-job-execution/app.ts`, }); (_b = getJobExecutionFunction.role) === null || _b === void 0 ? void 0 : _b.attachInlinePolicy(new aws_iam_1.Policy(this, 'iot-describe-job-execution-policy', { statements: [ new aws_iam_1.PolicyStatement({ actions: [ 'iot:DescribeJobExecution', ], resources: ['*'], }), ], })); return getJobExecutionFunction; } createListJobExecutionsForJobFunction() { var _b; const listJobExecutionsForJob = new aws_lambda_nodejs_1.NodejsFunction(this, 'listJobExecutionsForJob', { entry: `${LAMBDA_ASSETS_PATH}/list-job-executions-for-job/app.ts`, }); (_b = listJobExecutionsForJob.role) === null || _b === void 0 ? void 0 : _b.attachInlinePolicy(new aws_iam_1.Policy(this, 'list-job-execution-for-job', { statements: [ new aws_iam_1.PolicyStatement({ actions: [ 'iot:ListJobExecutionsForJob', ], resources: ['*'], }), ], })); return listJobExecutionsForJob; } createListJobExecutionsForThingFunction() { var _b; const listJobExecutionsForThing = new aws_lambda_nodejs_1.NodejsFunction(this, 'listJobExecutionsForThing', { entry: `${LAMBDA_ASSETS_PATH}/list-job-executions-for-thing/app.ts`, }); (_b = listJobExecutionsForThing.role) === null || _b === void 0 ? void 0 : _b.attachInlinePolicy(new aws_iam_1.Policy(this, 'list-job-executions-for-thing', { statements: [ new aws_iam_1.PolicyStatement({ actions: [ 'iot:ListJobExecutionsForThing', ], resources: ['*'], }), ], })); return listJobExecutionsForThing; } createDeleteJobExecutionFunction() { var _b; const deleteJobExecutionFunction = new aws_lambda_nodejs_1.NodejsFunction(this, 'DeleteJobExecutionFunction', { entry: `${LAMBDA_ASSETS_PATH}/delete-job-execution/app.ts`, }); (_b = deleteJobExecutionFunction.role) === null || _b === void 0 ? void 0 : _b.attachInlinePolicy(new aws_iam_1.Policy(this, 'iot-delete-job-execution-policy', { statements: [ new aws_iam_1.PolicyStatement({ actions: [ 'iot:DeleteJobExecution', ], resources: ['*'], }), ], })); return deleteJobExecutionFunction; } createCancelJobExecutionFunction() { var _b; const cancelJobExecutionFunction = new aws_lambda_nodejs_1.NodejsFunction(this, 'CancelJobExecutionFunction', { entry: `${LAMBDA_ASSETS_PATH}/cancel-job-execution/app.ts`, }); (_b = cancelJobExecutionFunction.role) === null || _b === void 0 ? void 0 : _b.attachInlinePolicy(new aws_iam_1.Policy(this, 'iot-cancel-job-execution-policy', { statements: [ new aws_iam_1.PolicyStatement({ actions: [ 'iot:CancelJobExecution', ], resources: ['*'], }), ], })); return cancelJobExecutionFunction; } createGetJobDocumentFunction() { var _b; const getJobDocumentFunction = new aws_lambda_nodejs_1.NodejsFunction(this, 'GetJobDocumentFunction', { entry: `${LAMBDA_ASSETS_PATH}/get-job-document/app.ts`, }); (_b = getJobDocumentFunction.role) === null || _b === void 0 ? void 0 : _b.attachInlinePolicy(new aws_iam_1.Policy(this, 'iot-get-job-document', { statements: [ new aws_iam_1.PolicyStatement({ actions: [ 'iot:GetJobDocument', ], resources: ['*'], }), ], })); return getJobDocumentFunction; } createCreateJobTemplateFunction() { var _b; const createJobTemplateFunction = new aws_lambda_nodejs_1.NodejsFunction(this, 'CreateJobTemplateFunction', { entry: `${LAMBDA_ASSETS_PATH}/create-job-template/app.ts`, }); (_b = createJobTemplateFunction.role) === null || _b === void 0 ? void 0 : _b.attachInlinePolicy(new aws_iam_1.Policy(this, 'iot-create-job-template-policy', { statements: [ new aws_iam_1.PolicyStatement({ actions: [ 'iot:CreateJobTemplate', ], resources: ['*'], }), ], })); return createJobTemplateFunction; } createListJobTemplatesFunction() { var _b; const listJobTemplatesFunction = new aws_lambda_nodejs_1.NodejsFunction(this, 'ListJobTemplatesFunction', { entry: `${LAMBDA_ASSETS_PATH}/list-job-templates/app.ts`, }); (_b = listJobTemplatesFunction.role) === null || _b === void 0 ? void 0 : _b.attachInlinePolicy(new aws_iam_1.Policy(this, 'iot-list-job-templates-policy', { statements: [ new aws_iam_1.PolicyStatement({ actions: [ 'iot:ListJobTemplates', ], resources: ['*'], }), ], })); return listJobTemplatesFunction; } createGetJobTemplateFunction() { var _b; const getJobTemplateFunction = new aws_lambda_nodejs_1.NodejsFunction(this, 'GetJobTemplateFunction', { entry: `${LAMBDA_ASSETS_PATH}/get-job-template/app.ts`, }); (_b = getJobTemplateFunction.role) === null || _b === void 0 ? void 0 : _b.attachInlinePolicy(new aws_iam_1.Policy(this, 'iot-get-job-template', { statements: [ new aws_iam_1.PolicyStatement({ actions: [ 'iot:DescribeJobTemplate', ], resources: ['*'], }), ], })); return getJobTemplateFunction; } createDeleteJobTemplateFunction() { var _b; const deleteJobTemplateFunction = new aws_lambda_nodejs_1.NodejsFunction(this, 'DeleteJobTemplateFunction', { entry: `${LAMBDA_ASSETS_PATH}/delete-job-template/app.ts`, }); (_b = deleteJobTemplateFunction.role) === null || _b === void 0 ? void 0 : _b.attachInlinePolicy(new aws_iam_1.Policy(this, 'iot-delete-job-template-policy', { statements: [ new aws_iam_1.PolicyStatement({ actions: [ 'iot:DeleteJobTemplate', ], resources: ['*'], }), ], })); return deleteJobTemplateFunction; } } exports.JobApi = JobApi; _a = JSII_RTTI_SYMBOL_1; JobApi[_a] = { fqn: "@softchef/cdk-iot-device-management.JobApi", version: "2.0.0" }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiam9iLWFwaS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9qb2ItYXBpLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsNkJBQTZCO0FBQzdCLHVEQUcrQjtBQUkvQiwrREFHb0M7QUFDcEMsaURBRzZCO0FBQzdCLHFFQUV1QztBQUN2QywyQ0FFb0I7QUFFcEIsTUFBTSxrQkFBa0IsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLFNBQVMsRUFBRSx1QkFBdUIsQ0FBQyxDQUFDOzs7Ozs7QUFhNUUsTUFBYSxNQUFPLFNBQVEsc0JBQVM7Ozs7SUFNbkMsWUFBWSxLQUFnQixFQUFFLEVBQVUsRUFBRSxLQUFtQjs7UUFDM0QsS0FBSyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQztRQUNqQixJQUFJLENBQUMsUUFBUSxHQUFHLElBQUkscUJBQU8sQ0FBQyxJQUFJLEVBQUUsWUFBWSxFQUFFO1lBQzlDLFVBQVUsRUFBRSxJQUFJO1lBQ2hCLGlCQUFpQixRQUFFLEtBQUssYUFBTCxLQUFLLHVCQUFMLEtBQUssQ0FBRSxpQkFBaUIsbUNBQUksa0NBQWlCLENBQUMsSUFBSTtZQUNyRSxVQUFVLFFBQUUsS0FBSyxhQUFMLEtBQUssdUJBQUwsS0FBSyxDQUFFLFVBQVUsbUNBQUksU0FBUztZQUMxQyxTQUFTLEVBQUU7Z0JBQ1Q7b0JBQ0UsSUFBSSxFQUFFLHlCQUF5QjtvQkFDL0IsVUFBVSxFQUFFLHdCQUFVLENBQUMsR0FBRztvQkFDMUIsY0FBYyxFQUFFLElBQUksQ0FBQyxxQ0FBcUMsRUFBRTtpQkFDN0Q7Z0JBQ0Q7b0JBQ0UsSUFBSSxFQUFFLE9BQU87b0JBQ2IsVUFBVSxFQUFFLHdCQUFVLENBQUMsSUFBSTtvQkFDM0IsY0FBYyxFQUFFLElBQUksQ0FBQyx1QkFBdUIsRUFBRTtpQkFDL0M7Z0JBQ0Q7b0JBQ0UsSUFBSSxFQUFFLE9BQU87b0JBQ2IsVUFBVSxFQUFFLHdCQUFVLENBQUMsR0FBRztvQkFDMUIsY0FBYyxFQUFFLElBQUksQ0FBQyxzQkFBc0IsRUFBRTtpQkFDOUM7Z0JBQ0Q7b0JBQ0UsSUFBSSxFQUFFLGVBQWU7b0JBQ3JCLFVBQVUsRUFBRSx3QkFBVSxDQUFDLEdBQUc7b0JBQzFCLGNBQWMsRUFBRSxJQUFJLENBQUMsb0JBQW9CLEVBQUU7aUJBQzVDO2dCQUNEO29CQUNFLElBQUksRUFBRSxlQUFlO29CQUNyQixVQUFVLEVBQUUsd0JBQVUsQ0FBQyxHQUFHO29CQUMxQixjQUFjLEVBQUUsSUFBSSxDQUFDLHVCQUF1QixFQUFFO2lCQUMvQztnQkFDRDtvQkFDRSxJQUFJLEVBQUUsZUFBZTtvQkFDckIsVUFBVSxFQUFFLHdCQUFVLENBQUMsTUFBTTtvQkFDN0IsY0FBYyxFQUFFLElBQUksQ0FBQyx1QkFBdUIsRUFBRTtpQkFDL0M7Z0JBQ0Q7b0JBQ0UsSUFBSSxFQUFFLHNCQUFzQjtvQkFDNUIsVUFBVSxFQUFFLHdCQUFVLENBQUMsR0FBRztvQkFDMUIsY0FBYyxFQUFFLElBQUksQ0FBQyx1QkFBdUIsRUFBRTtpQkFDL0M7Z0JBQ0Q7b0JBQ0UsSUFBSSxFQUFFLHdCQUF3QjtvQkFDOUIsVUFBVSxFQUFFLHdCQUFVLENBQUMsR0FBRztvQkFDMUIsY0FBYyxFQUFFLElBQUksQ0FBQyw0QkFBNEIsRUFBRTtpQkFDcEQ7Z0JBQ0Q7b0JBQ0UsSUFBSSxFQUFFLGtDQUFrQztvQkFDeEMsVUFBVSxFQUFFLHdCQUFVLENBQUMsR0FBRztvQkFDMUIsY0FBYyxFQUFFLElBQUksQ0FBQyw2QkFBNkIsRUFBRTtpQkFDckQ7Z0JBQ0Q7b0JBQ0UsSUFBSSxFQUFFLHFCQUFxQjtvQkFDM0IsVUFBVSxFQUFFLHdCQUFVLENBQUMsR0FBRztvQkFDMUIsY0FBYyxFQUFFLElBQUksQ0FBQyxxQ0FBcUMsRUFBRTtpQkFDN0Q7Z0JBQ0Q7b0JBQ0UsSUFBSSxFQUFFLDBCQUEwQjtvQkFDaEMsVUFBVSxFQUFFLHdCQUFVLENBQUMsR0FBRztvQkFDMUIsY0FBYyxFQUFFLElBQUksQ0FBQyx1Q0FBdUMsRUFBRTtpQkFDL0Q7Z0JBQ0Q7b0JBQ0UsSUFBSSxFQUFFLGtDQUFrQztvQkFDeEMsVUFBVSxFQUFFLHdCQUFVLENBQUMsTUFBTTtvQkFDN0IsY0FBYyxFQUFFLElBQUksQ0FBQyxnQ0FBZ0MsRUFBRTtpQkFDeEQ7Z0JBQ0Q7b0JBQ0UsSUFBSSxFQUFFLHlDQUF5QztvQkFDL0MsVUFBVSxFQUFFLHdCQUFVLENBQUMsR0FBRztvQkFDMUIsY0FBYyxFQUFFLElBQUksQ0FBQyxnQ0FBZ0MsRUFBRTtpQkFDeEQ7Z0JBQ0Q7b0JBQ0UsSUFBSSxFQUFFLGdCQUFnQjtvQkFDdEIsVUFBVSxFQUFFLHdCQUFVLENBQUMsSUFBSTtvQkFDM0IsY0FBYyxFQUFFLElBQUksQ0FBQywrQkFBK0IsRUFBRTtpQkFDdkQ7Z0JBQ0Q7b0JBQ0UsSUFBSSxFQUFFLGdCQUFnQjtvQkFDdEIsVUFBVSxFQUFFLHdCQUFVLENBQUMsR0FBRztvQkFDMUIsY0FBYyxFQUFFLElBQUksQ0FBQyw4QkFBOEIsRUFBRTtpQkFDdEQ7Z0JBQ0Q7b0JBQ0UsSUFBSSxFQUFFLGdDQUFnQztvQkFDdEMsVUFBVSxFQUFFLHdCQUFVLENBQUMsR0FBRztvQkFDMUIsY0FBYyxFQUFFLElBQUksQ0FBQyw0QkFBNEIsRUFBRTtpQkFDcEQ7Z0JBQ0Q7b0JBQ0UsSUFBSSxFQUFFLGdDQUFnQztvQkFDdEMsVUFBVSxFQUFFLHdCQUFVLENBQUMsTUFBTTtvQkFDN0IsY0FBYyxFQUFFLElBQUksQ0FBQywrQkFBK0IsRUFBRTtpQkFDdkQ7YUFDRjtTQUNGLENBQUMsQ0FBQztRQUNILElBQUksS0FBSyxhQUFMLEtBQUssdUJBQUwsS0FBSyxDQUFFLGdCQUFnQixFQUFFO1lBQzNCLE1BQU0sVUFBVSxHQUFXLFdBQVcsQ0FBQztZQUN2QyxLQUFLLENBQUMsZ0JBQWdCLENBQUMsaUJBQWlCLENBQUMsVUFBVSxFQUFFO2dCQUNuRCxjQUFjLEVBQUUsSUFBSSxDQUFDLCtCQUErQixFQUFFO2FBQ3ZELENBQUMsQ0FBQztZQUNILE1BQUEsS0FBSyxhQUFMLEtBQUssdUJBQUwsS0FBSyxDQUFFLGdCQUFnQiwwQ0FBRSxxQkFBcUIsQ0FBQyxjQUFjLENBQUMsbUJBQW1CLEVBQUUsVUFBVSxFQUFFO1lBQy9GLE1BQUEsS0FBSyxhQUFMLEtBQUssdUJBQUwsS0FBSyxDQUFFLGdCQUFnQiwwQ0FBRSxzQkFBc0IsQ0FBQyxjQUFjLENBQUMsbUJBQW1CLEVBQUUsVUFBVSxFQUFFO1lBQ2hHLElBQUksQ0FBQyxRQUFRLENBQUMsWUFBWSxDQUFDO2dCQUN6QjtvQkFDRSxJQUFJLEVBQUUsWUFBWTtvQkFDbEIsVUFBVSxFQUFFLHdCQUFVLENBQUMsR0FBRztvQkFDMUIsY0FBYyxFQUFFLEtBQUssYUFBTCxLQUFLLHVCQUFMLEtBQUssQ0FBRSxnQkFBZ0IsQ0FBQyxxQkFBcUI7aUJBQzlEO2dCQUNEO29CQUNFLElBQUksRUFBRSxZQUFZO29CQUNsQixVQUFVLEVBQUUsd0JBQVUsQ0FBQyxJQUFJO29CQUMzQixjQUFjLEVBQUUsS0FBSyxhQUFMLEtBQUssdUJBQUwsS0FBSyxDQUFFLGdCQUFnQixDQUFDLHNCQUFzQjtpQkFDL0Q7Z0JBQ0Q7b0JBQ0UsSUFBSSxFQUFFLHlCQUF5QjtvQkFDL0IsVUFBVSxFQUFFLHdCQUFVLENBQUMsR0FBRztvQkFDMUIsY0FBYyxFQUFFLEtBQUssYUFBTCxLQUFLLHVCQUFMLEtBQUssQ0FBRSxnQkFBZ0IsQ0FBQyxxQkFBcUI7aUJBQzlEO2dCQUNEO29CQUNFLElBQUksRUFBRSx5QkFBeUI7b0JBQy9CLFVBQVUsRUFBRSx3QkFBVSxDQUFDLEdBQUc7b0JBQzFCLGNBQWMsRUFBRSxLQUFLLGFBQUwsS0FBSyx1QkFBTCxLQUFLLENBQUUsZ0JBQWdCLENBQUMsc0JBQXNCO2lCQUMvRDtnQkFDRDtvQkFDRSxJQUFJLEVBQUUseUJBQXlCO29CQUMvQixVQUFVLEVBQUUsd0JBQVUsQ0FBQyxNQUFNO29CQUM3QixjQUFjLEVBQUUsS0FBSyxhQUFMLEtBQUssdUJBQUwsS0FBSyxDQUFFLGdCQUFnQixDQUFDLHNCQUFzQjtpQkFDL0Q7YUFDRixDQUFDLENBQUM7U0FDSjtJQUNILENBQUM7Ozs7OztJQUdELElBQUksU0FBUztRQUNYLE9BQU8sSUFBSSxDQUFDLFFBQVEsQ0FBQyxTQUFTLENBQUM7SUFDakMsQ0FBQztJQUVPLCtCQUErQjs7UUFDckMsTUFBTSxpQkFBaUIsR0FBRyxJQUFJLGtDQUFjLENBQUMsSUFBSSxFQUFFLDJCQUEyQixFQUFFO1lBQzlFLEtBQUssRUFBRSxHQUFHLGtCQUFrQiw2QkFBNkI7U0FDMUQsQ0FBQyxDQUFDO1FBQ0gsTUFBQSxpQkFBaUIsQ0FBQyxJQUFJLDBDQUFFLGtCQUFrQixDQUN4QyxJQUFJLGdCQUFNLENBQUMsSUFBSSxFQUFFLGdDQUFnQyxFQUFFO1lBQ2pELFVBQVUsRUFBRTtnQkFDVixJQUFJLHlCQUFlLENBQUM7b0JBQ2xCLE9BQU8sRUFBRTt3QkFDUCxlQUFlO3FCQUNoQjtvQkFDRCxTQUFTLEVBQUUsQ0FBQyxHQUFHLENBQUM7aUJBQ2pCLENBQUM7YUFDSDtTQUNGLENBQUMsRUFDRjtRQUNGLE9BQU8saUJBQWlCLENBQUM7SUFDM0IsQ0FBQztJQUVPLHFDQUFxQzs7UUFDM0MsTUFBTSxpQkFBaUIsR0FBRyxJQUFJLGtDQUFjLENBQUMsSUFBSSxFQUFFLGlDQUFpQyxFQUFFO1lBQ3BGLEtBQUssRUFBRSxHQUFHLGtCQUFrQixvQ0FBb0M7U0FDakUsQ0FBQyxDQUFDO1FBQ0gsTUFBQSxpQkFBaUIsQ0FBQyxJQUFJLDBDQUFFLGtCQUFrQixDQUN4QyxJQUFJLGdCQUFNLENBQUMsSUFBSSxFQUFFLGdDQUFnQyxFQUFFO1lBQ2pELFVBQVUsRUFBRTtnQkFDVixJQUFJLHlCQUFlLENBQUM7b0JBQ2xCLE9BQU8sRUFBRTt3QkFDUCw2QkFBNkI7cUJBQzlCO29CQUNELFNBQVMsRUFBRSxDQUFDLEdBQUcsQ0FBQztpQkFDakIsQ0FBQzthQUNIO1NBQ0YsQ0FBQyxFQUNGO1FBQ0YsT0FBTyxpQkFBaUIsQ0FBQztJQUMzQixDQUFDO0lBRU8sdUJBQXVCOztRQUM3QixNQUFNLGlCQUFpQixHQUFHLElBQUksa0NBQWMsQ0FBQyxJQUFJLEVBQUUsbUJBQW1CLEVBQUU7WUFDdEUsS0FBSyxFQUFFLEdBQUcsa0JBQWtCLG9CQUFvQjtTQUNqRCxDQUFDLENBQUM7UUFDSCxNQUFBLGlCQUFpQixDQUFDLElBQUksMENBQUUsa0JBQWtCLENBQ3hDLElBQUksZ0JBQU0sQ0FBQyxJQUFJLEVBQUUsdUJBQXVCLEVBQUU7WUFDeEMsVUFBVSxFQUFFO2dCQUNWLElBQUkseUJBQWUsQ0FBQztvQkFDbEIsT0FBTyxFQUFFO3dCQUNQLGVBQWU7cUJBQ2hCO29CQUNELFNBQVMsRUFBRSxDQUFDLEdBQUcsQ0FBQztpQkFDakIsQ0FBQzthQUNIO1NBQ0YsQ0FBQyxFQUNGO1FBQ0YsT0FBTyxpQkFBaUIsQ0FBQztJQUMzQixDQUFDO0lBRU8sc0JBQXNCOztRQUM1QixNQUFNLGdCQUFnQixHQUFHLElBQUksa0NBQWMsQ0FBQyxJQUFJLEVBQUUsa0JBQWtCLEVBQUU7WUFDcEUsS0FBSyxFQUFFLEdBQUcsa0JBQWtCLG1CQUFtQjtTQUNoRCxDQUFDLENBQUM7UUFDSCxNQUFBLGdCQUFnQixDQUFDLElBQUksMENBQUUsa0JBQWtCLENBQ3ZDLElBQUksZ0JBQU0sQ0FBQyxJQUFJLEVBQUUsc0JBQXNCLEVBQUU7WUFDdkMsVUFBVSxFQUFFO2dCQUNWLElBQUkseUJBQWUsQ0FBQztvQkFDbEIsT0FBTyxFQUFFO3dCQUNQLGNBQWM7cUJBQ2Y7b0JBQ0QsU0FBUyxFQUFFLENBQUMsR0FBRyxDQUFDO2lCQUNqQixDQUFDO2FBQ0g7U0FDRixDQUFDLEVBQ0Y7UUFDRixPQUFPLGdCQUFnQixDQUFDO0lBQzFCLENBQUM7SUFFTyxvQkFBb0I7O1FBQzFCLE1BQU0sY0FBYyxHQUFHLElBQUksa0NBQWMsQ0FBQyxJQUFJLEVBQUUsZ0JBQWdCLEVBQUU7WUFDaEUsS0FBSyxFQUFFLEdBQUcsa0JBQWtCLGlCQUFpQjtTQUM5QyxDQUFDLENBQUM7UUFDSCxNQUFBLGNBQWMsQ0FBQyxJQUFJLDBDQUFFLGtCQUFrQixDQUNyQyxJQUFJLGdCQUFNLENBQUMsSUFBSSxFQUFFLHlCQUF5QixFQUFFO1lBQzFDLFVBQVUsRUFBRTtnQkFDVixJQUFJLHlCQUFlLENBQUM7b0JBQ2xCLE9BQU8sRUFBRTt3QkFDUCxpQkFBaUI7cUJBQ2xCO29CQUNELFNBQVMsRUFBRSxDQUFDLEdBQUcsQ0FBQztpQkFDakIsQ0FBQzthQUNIO1NBQ0YsQ0FBQyxFQUNGO1FBQ0YsT0FBTyxjQUFjLENBQUM7SUFDeEIsQ0FBQztJQUVPLHVCQUF1Qjs7UUFDN0IsTUFBTSxpQkFBaUIsR0FBRyxJQUFJLGtDQUFjLENBQUMsSUFBSSxFQUFFLG1CQUFtQixFQUFFO1lBQ3RFLEtBQUssRUFBRSxHQUFHLGtCQUFrQixvQkFBb0I7U0FDakQsQ0FBQyxDQUFDO1FBQ0gsTUFBQSxpQkFBaUIsQ0FBQyxJQUFJLDBDQUFFLGtCQUFrQixDQUN4QyxJQUFJLGdCQUFNLENBQUMsSUFBSSxFQUFFLHVCQUF1QixFQUFFO1lBQ3hDLFVBQVUsRUFBRTtnQkFDVixJQUFJLHlCQUFlLENBQUM7b0JBQ2xCLE9BQU8sRUFBRTt3QkFDUCxlQUFlO3FCQUNoQjtvQkFDRCxTQUFTLEVBQUUsQ0FBQyxHQUFHLENBQUM7aUJBQ2pCLENBQUM7YUFDSDtTQUNGLENBQUMsRUFDRjtRQUNGLE9BQU8saUJBQWlCLENBQUM7SUFDM0IsQ0FBQztJQUVPLHVCQUF1Qjs7UUFDN0IsTUFBTSxpQkFBaUIsR0FBRyxJQUFJLGtDQUFjLENBQUMsSUFBSSxFQUFFLG1CQUFtQixFQUFFO1lBQ3RFLEtBQUssRUFBRSxHQUFHLGtCQUFrQixvQkFBb0I7U0FDakQsQ0FBQyxDQUFDO1FBQ0gsTUFBQSxpQkFBaUIsQ0FBQyxJQUFJLDBDQUFFLGtCQUFrQixDQUN4QyxJQUFJLGdCQUFNLENBQUMsSUFBSSxFQUFFLHVCQUF1QixFQUFFO1lBQ3hDLFVBQVUsRUFBRTtnQkFDVixJQUFJLHlCQUFlLENBQUM7b0JBQ2xCLE9BQU8sRUFBRTt3QkFDUCxlQUFlO3FCQUNoQjtvQkFDRCxTQUFTLEVBQUUsQ0FBQyxHQUFHLENBQUM7aUJBQ2pCLENBQUM7YUFDSDtTQUNGLENBQUMsRUFDRjtRQUNGLE9BQU8saUJBQWlCLENBQUM7SUFDM0IsQ0FBQztJQUVPLHVCQUF1Qjs7UUFDN0IsTUFBTSxpQkFBaUIsR0FBRyxJQUFJLGtDQUFjLENBQUMsSUFBSSxFQUFFLG1CQUFtQixFQUFFO1lBQ3RFLEtBQUssRUFBRSxHQUFHLGtCQUFrQixvQkFBb0I7U0FDakQsQ0FBQyxDQUFDO1FBQ0gsTUFBQSxpQkFBaUIsQ0FBQyxJQUFJLDBDQUFFLGtCQUFrQixDQUN4QyxJQUFJLGdCQUFNLENBQUMsSUFBSSxFQUFFLHVCQUF1QixFQUFFO1lBQ3hDLFVBQVUsRUFBRTtnQkFDVixJQUFJLHlCQUFlLENBQUM7b0JBQ2xCLE9BQU8sRUFBRTt3QkFDUCxlQUFlO3FCQUNoQjtvQkFDRCxTQUFTLEVBQUUsQ0FBQyxHQUFHLENBQUM7aUJBQ2pCLENBQUM7YUFDSDtTQUNGLENBQUMsRUFDRjtRQUNGLE9BQU8saUJBQWlCLENBQUM7SUFDM0IsQ0FBQztJQUVPLDZCQUE2Qjs7UUFDbkMsTUFBTSx1QkFBdUIsR0FBRyxJQUFJLGtDQUFjLENBQUMsSUFBSSxFQUFFLHlCQUF5QixFQUFFO1lBQ2xGLEtBQUssRUFBRSxHQUFHLGtCQUFrQiwyQkFBMkI7U0FDeEQsQ0FBQyxDQUFDO1FBQ0gsTUFBQSx1QkFBdUIsQ0FBQyxJQUFJLDBDQUFFLGtCQUFrQixDQUM5QyxJQUFJLGdCQUFNLENBQUMsSUFBSSxFQUFFLG1DQUFtQyxFQUFFO1lBQ3BELFVBQVUsRUFBRTtnQkFDVixJQUFJLHlCQUFlLENBQUM7b0JBQ2xCLE9BQU8sRUFBRTt3QkFDUCwwQkFBMEI7cUJBQzNCO29CQUNELFNBQVMsRUFBRSxDQUFDLEdBQUcsQ0FBQztpQkFDakIsQ0FBQzthQUNIO1NBQ0YsQ0FBQyxFQUNGO1FBQ0YsT0FBTyx1QkFBdUIsQ0FBQztJQUNqQyxDQUFDO0lBRU8scUNBQXFDOztRQUMzQyxNQUFNLHVCQUF1QixHQUFHLElBQUksa0NBQWMsQ0FBQyxJQUFJLEVBQUUseUJBQXlCLEVBQUU7WUFDbEYsS0FBSyxFQUFFLEdBQUcsa0JBQWtCLHFDQUFxQztTQUNsRSxDQUFDLENBQUM7UUFDSCxNQUFBLHVCQUF1QixDQUFDLElBQUksMENBQUUsa0JBQWtCLENBQzlDLElBQUksZ0JBQU0sQ0FBQyxJQUFJLEVBQUUsNEJBQTRCLEVBQUU7WUFDN0MsVUFBVSxFQUFFO2dCQUNWLElBQUkseUJBQWUsQ0FBQztvQkFDbEIsT0FBTyxFQUFFO3dCQUNQLDZCQUE2QjtxQkFDOUI7b0JBQ0QsU0FBUyxFQUFFLENBQUMsR0FBRyxDQUFDO2lCQUNqQixDQUFDO2FBQ0g7U0FDRixDQUFDLEVBQ0Y7UUFDRixPQUFPLHVCQUF1QixDQUFDO0lBQ2pDLENBQUM7SUFFTyx1Q0FBdUM7O1FBQzdDLE1BQU0seUJBQXlCLEdBQUcsSUFBSSxrQ0FBYyxDQUFDLElBQUksRUFBRSwyQkFBMkIsRUFBRTtZQUN0RixLQUFLLEVBQUUsR0FBRyxrQkFBa0IsdUNBQXVDO1NBQ3BFLENBQUMsQ0FBQztRQUNILE1BQUEseUJBQXlCLENBQUMsSUFBSSwwQ0FBRSxrQkFBa0IsQ0FDaEQsSUFBSSxnQkFBTSxDQUFDLElBQUksRUFBRSwrQkFBK0IsRUFBRTtZQUNoRCxVQUFVLEVBQUU7Z0JBQ1YsSUFBSSx5QkFBZSxDQUFDO29CQUNsQixPQUFPLEVBQUU7d0JBQ1AsK0JBQStCO3FCQUNoQztvQkFDRCxTQUFTLEVBQUUsQ0FBQyxHQUFHLENBQUM7aUJBQ2pCLENBQUM7YUFDSDtTQUNGLENBQUMsRUFDRjtRQUNGLE9BQU8seUJBQXlCLENBQUM7SUFDbkMsQ0FBQztJQUVPLGdDQUFnQzs7UUFDdEMsTUFBTSwwQkFBMEIsR0FBRyxJQUFJLGtDQUFjLENBQUMsSUFBSSxFQUFFLDRCQUE0QixFQUFFO1lBQ3hGLEtBQUssRUFBRSxHQUFHLGtCQUFrQiw4QkFBOEI7U0FDM0QsQ0FBQyxDQUFDO1FBQ0gsTUFBQSwwQkFBMEIsQ0FBQyxJQUFJLDBDQUFFLGtCQUFrQixDQUNqRCxJQUFJLGdCQUFNLENBQUMsSUFBSSxFQUFFLGlDQUFpQyxFQUFFO1lBQ2xELFVBQVUsRUFBRTtnQkFDVixJQUFJLHlCQUFlLENBQUM7b0JBQ2xCLE9BQU8sRUFBRTt3QkFDUCx3QkFBd0I7cUJBQ3pCO29CQUNELFNBQVMsRUFBRSxDQUFDLEdBQUcsQ0FBQztpQkFDakIsQ0FBQzthQUNIO1NBQ0YsQ0FBQyxFQUNGO1FBQ0YsT0FBTywwQkFBMEIsQ0FBQztJQUNwQyxDQUFDO0lBRU8sZ0NBQWdDOztRQUN0QyxNQUFNLDBCQUEwQixHQUFHLElBQUksa0NBQWMsQ0FBQyxJQUFJLEVBQUUsNEJBQTRCLEVBQUU7WUFDeEYsS0FBSyxFQUFFLEdBQUcsa0JBQWtCLDhCQUE4QjtTQUMzRCxDQUFDLENBQUM7UUFDSCxNQUFBLDBCQUEwQixDQUFDLElBQUksMENBQUUsa0JBQWtCLENBQ2pELElBQUksZ0JBQU0sQ0FBQyxJQUFJLEVBQUUsaUNBQWlDLEVBQUU7WUFDbEQsVUFBVSxFQUFFO2dCQUNWLElBQUkseUJBQWUsQ0FBQztvQkFDbEIsT0FBTyxFQUFFO3dCQUNQLHdCQUF3QjtxQkFDekI7b0JBQ0QsU0FBUyxFQUFFLENBQUMsR0FBRyxDQUFDO2lCQUNqQixDQUFDO2FBQ0g7U0FDRixDQUFDLEVBQ0Y7UUFDRixPQUFPLDBCQUEwQixDQUFDO0lBQ3BDLENBQUM7SUFFTyw0QkFBNEI7O1FBQ2xDLE1BQU0sc0JBQXNCLEdBQUcsSUFBSSxrQ0FBYyxDQUFDLElBQUksRUFBRSx3QkFBd0IsRUFBRTtZQUNoRixLQUFLLEVBQUUsR0FBRyxrQkFBa0IsMEJBQTBCO1NBQ3ZELENBQUMsQ0FBQztRQUNILE1BQUEsc0JBQXNCLENBQUMsSUFBSSwwQ0FBRSxrQkFBa0IsQ0FDN0MsSUFBSSxnQkFBTSxDQUFDLElBQUksRUFBRSxzQkFBc0IsRUFBRTtZQUN2QyxVQUFVLEVBQUU7Z0JBQ1YsSUFBSSx5QkFBZSxDQUFDO29CQUNsQixPQUFPLEVBQUU7d0JBQ1Asb0JBQW9CO3FCQUNyQjtvQkFDRCxTQUFTLEVBQUUsQ0FBQyxHQUFHLENBQUM7aUJBQ2pCLENBQUM7YUFDSDtTQUNGLENBQUMsRUFDRjtRQUNGLE9BQU8sc0JBQXNCLENBQUM7SUFDaEMsQ0FBQztJQUVPLCtCQUErQjs7UUFDckMsTUFBTSx5QkFBeUIsR0FBRyxJQUFJLGtDQUFjLENBQUMsSUFBSSxFQUFFLDJCQUEyQixFQUFFO1lBQ3RGLEtBQUssRUFBRSxHQUFHLGtCQUFrQiw2QkFBNkI7U0FDMUQsQ0FBQyxDQUFDO1FBQ0gsTUFBQSx5QkFBeUIsQ0FBQyxJQUFJLDBDQUFFLGtCQUFrQixDQUNoRCxJQUFJLGdCQUFNLENBQUMsSUFBSSxFQUFFLGdDQUFnQyxFQUFFO1lBQ2pELFVBQVUsRUFBRTtnQkFDVixJQUFJLHlCQUFlLENBQUM7b0JBQ2xCLE9BQU8sRUFBRTt3QkFDUCx1QkFBdUI7cUJBQ3hCO29CQUNELFNBQVMsRUFBRSxDQUFDLEdBQUcsQ0FBQztpQkFDakIsQ0FBQzthQUNIO1NBQ0YsQ0FBQyxFQUNGO1FBQ0YsT0FBTyx5QkFBeUIsQ0FBQztJQUNuQyxDQUFDO0lBQ08sOEJBQThCOztRQUNwQyxNQUFNLHdCQUF3QixHQUFHLElBQUksa0NBQWMsQ0FBQyxJQUFJLEVBQUUsMEJBQTBCLEVBQUU7WUFDcEYsS0FBSyxFQUFFLEdBQUcsa0JBQWtCLDRCQUE0QjtTQUN6RCxDQUFDLENBQUM7UUFDSCxNQUFBLHdCQUF3QixDQUFDLElBQUksMENBQUUsa0JBQWtCLENBQy9DLElBQUksZ0JBQU0sQ0FBQyxJQUFJLEVBQUUsK0JBQStCLEVBQUU7WUFDaEQsVUFBVSxFQUFFO2dCQUNWLElBQUkseUJBQWUsQ0FBQztvQkFDbEIsT0FBTyxFQUFFO3dCQUNQLHNCQUFzQjtxQkFDdkI7b0JBQ0QsU0FBUyxFQUFFLENBQUMsR0FBRyxDQUFDO2lCQUNqQixDQUFDO2FBQ0g7U0FDRixDQUFDLEVBQ0Y7UUFDRixPQUFPLHdCQUF3QixDQUFDO0lBQ2xDLENBQUM7SUFFTyw0QkFBNEI7O1FBQ2xDLE1BQU0sc0JBQXNCLEdBQUcsSUFBSSxrQ0FBYyxDQUFDLElBQUksRUFBRSx3QkFBd0IsRUFBRTtZQUNoRixLQUFLLEVBQUUsR0FBRyxrQkFBa0IsMEJBQTBCO1NBQ3ZELENBQUMsQ0FBQztRQUNILE1BQUEsc0JBQXNCLENBQUMsSUFBSSwwQ0FBRSxrQkFBa0IsQ0FDN0MsSUFBSSxnQkFBTSxDQUFDLElBQUksRUFBRSxzQkFBc0IsRUFBRTtZQUN2QyxVQUFVLEVBQUU7Z0JBQ1YsSUFBSSx5QkFBZSxDQUFDO29CQUNsQixPQUFPLEVBQUU7d0JBQ1AseUJBQXlCO3FCQUMxQjtvQkFDRCxTQUFTLEVBQUUsQ0FBQyxHQUFHLENBQUM7aUJBQ2pCLENBQUM7YUFDSDtTQUNGLENBQUMsRUFDRjtRQUNGLE9BQU8sc0JBQXNCLENBQUM7SUFDaEMsQ0FBQztJQUVPLCtCQUErQjs7UUFDckMsTUFBTSx5QkFBeUIsR0FBRyxJQUFJLGtDQUFjLENBQUMsSUFBSSxFQUFFLDJCQUEyQixFQUFFO1lBQ3RGLEtBQUssRUFBRSxHQUFHLGtCQUFrQiw2QkFBNkI7U0FDMUQsQ0FBQyxDQUFDO1FBQ0gsTUFBQSx5QkFBeUIsQ0FBQyxJQUFJLDBDQUFFLGtCQUFrQixDQUNoRCxJQUFJLGdCQUFNLENBQUMsSUFBSSxFQUFFLGdDQUFnQyxFQUFFO1lBQ2pELFVBQVUsRUFBRTtnQkFDVixJQUFJLHlCQUFlLENBQUM7b0JBQ2xCLE9BQU8sRUFBRTt3QkFDUCx1QkFBdUI7cUJBQ3hCO29CQUNELFNBQVMsRUFBRSxDQUFDLEdBQUcsQ0FBQztpQkFDakIsQ0FBQzthQUNIO1NBQ0YsQ0FBQyxFQUNGO1FBQ0YsT0FBTyx5QkFBeUIsQ0FBQztJQUNuQyxDQUFDOztBQWplSCx3QkFrZUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBwYXRoIGZyb20gJ3BhdGgnO1xuaW1wb3J0IHtcbiAgUmVzdEFwaSxcbiAgSHR0cE1ldGhvZCxcbn0gZnJvbSAnQHNvZnRjaGVmL2Nkay1yZXN0YXBpJztcbmltcG9ydCB7XG4gIFNjaGVkdWxlRnVuY3Rpb24sXG59IGZyb20gJ0Bzb2Z0Y2hlZi9jZGstc2NoZWR1bGUtZnVuY3Rpb24nO1xuaW1wb3J0IHtcbiAgQXV0aG9yaXphdGlvblR5cGUsXG4gIElBdXRob3JpemVyLFxufSBmcm9tICdhd3MtY2RrLWxpYi9hd3MtYXBpZ2F0ZXdheSc7XG5pbXBvcnQge1xuICBQb2xpY3ksXG4gIFBvbGljeVN0YXRlbWVudCxcbn0gZnJvbSAnYXdzLWNkay1saWIvYXdzLWlhbSc7XG5pbXBvcnQge1xuICBOb2RlanNGdW5jdGlvbixcbn0gZnJvbSAnYXdzLWNkay1saWIvYXdzLWxhbWJkYS1ub2RlanMnO1xuaW1wb3J0IHtcbiAgQ29uc3RydWN0LFxufSBmcm9tICdjb25zdHJ1Y3RzJztcblxuY29uc3QgTEFNQkRBX0FTU0VUU19QQVRIID0gcGF0aC5yZXNvbHZlKF9fZGlybmFtZSwgJy4uL2xhbWJkYS1hc3NldHMvam9icycpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBcbmV4cG9ydCBpbnRlcmZhY2UgSm9iQXBpUHJvcHMge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICByZWFkb25seSBhdXRob3JpemF0aW9uVHlwZT86IEF1dGhvcml6YXRpb25UeXBlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICByZWFkb25seSBhdXRob3JpemVyPzogSUF1dGhvcml6ZXIgfCB1bmRlZmluZWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgcmVhZG9ubHkgc2NoZWR1bGVGdW5jdGlvbj86IFNjaGVkdWxlRnVuY3Rpb247XG59XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbmV4cG9ydCBjbGFzcyBKb2JBcGkgZXh0ZW5kcyBDb25zdHJ1Y3Qge1xuICAvKipcbiAgICogVGhlIEpvYiBBUEkgR2F0ZXdheVxuICAgKi9cbiAgcHJpdmF0ZSByZWFkb25seSBfcmVzdEFwaTogUmVzdEFwaTtcblxuICBjb25zdHJ1Y3RvcihzY29wZTogQ29uc3RydWN0LCBpZDogc3RyaW5nLCBwcm9wcz86IEpvYkFwaVByb3BzKSB7XG4gICAgc3VwZXIoc2NvcGUsIGlkKTtcbiAgICB0aGlzLl9yZXN0QXBpID0gbmV3IFJlc3RBcGkodGhpcywgJ0pvYlJlc3RBcGknLCB7XG4gICAgICBlbmFibGVDb3JzOiB0cnVlLFxuICAgICAgYXV0aG9yaXphdGlvblR5cGU6IHByb3BzPy5hdXRob3JpemF0aW9uVHlwZSA/PyBBdXRob3JpemF0aW9uVHlwZS5OT05FLFxuICAgICAgYXV0aG9yaXplcjogcHJvcHM/LmF1dGhvcml6ZXIgPz8gdW5kZWZpbmVkLFxuICAgICAgcmVzb3VyY2VzOiBbXG4gICAgICAgIHtcbiAgICAgICAgICBwYXRoOiAnL2pvYnMve2pvYklkfS9hc3NvY2lhdGUnLFxuICAgICAgICAgIGh0dHBNZXRob2Q6IEh0dHBNZXRob2QuUFVULFxuICAgICAgICAgIGxhbWJkYUZ1bmN0aW9uOiB0aGlzLmNyZWF0ZUFzc29jaWF0ZVRhcmdldHNXaXRoSm9iRnVuY3Rpb24oKSxcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIHBhdGg6ICcvam9icycsXG4gICAgICAgICAgaHR0cE1ldGhvZDogSHR0cE1ldGhvZC5QT1NULFxuICAgICAgICAgIGxhbWJkYUZ1bmN0aW9uOiB0aGlzLmNyZWF0ZUNyZWF0ZUpvYkZ1bmN0aW9uKCksXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICBwYXRoOiAnL2pvYnMnLFxuICAgICAgICAgIGh0dHBNZXRob2Q6IEh0dHBNZXRob2QuR0VULFxuICAgICAgICAgIGxhbWJkYUZ1bmN0aW9uOiB0aGlzLmNyZWF0ZUxpc3RKb2JzRnVuY3Rpb24oKSxcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIHBhdGg6ICcvam9icy97am9iSWR9JyxcbiAgICAgICAgICBodHRwTWV0aG9kOiBIdHRwTWV0aG9kLkdFVCxcbiAgICAgICAgICBsYW1iZGFGdW5jdGlvbjogdGhpcy5jcmVhdGVHZXRKb2JGdW5jdGlvbigpLFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgcGF0aDogJy9qb2JzL3tqb2JJZH0nLFxuICAgICAgICAgIGh0dHBNZXRob2Q6IEh0dHBNZXRob2QuUFVULFxuICAgICAgICAgIGxhbWJkYUZ1bmN0aW9uOiB0aGlzLmNyZWF0ZVVwZGF0ZUpvYkZ1bmN0aW9uKCksXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICBwYXRoOiAnL2pvYnMve2pvYklkfScsXG4gICAgICAgICAgaHR0cE1ldGhvZDogSHR0cE1ldGhvZC5ERUxFVEUsXG4gICAgICAgICAgbGFtYmRhRnVuY3Rpb246IHRoaXMuY3JlYXRlRGVsZXRlSm9iRnVuY3Rpb24oKSxcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIHBhdGg6ICcvam9icy97am9iSWR9L2NhbmNlbCcsXG4gICAgICAgICAgaHR0cE1ldGhvZDogSHR0cE1ldGhvZC5QVVQsXG4gICAgICAgICAgbGFtYmRhRnVuY3Rpb246IHRoaXMuY3JlYXRlQ2FuY2VsSm9iRnVuY3Rpb24oKSxcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIHBhdGg6ICcvam9icy97am9iSWR9L2RvY3VtZW50JyxcbiAgICAgICAgICBodHRwTWV0aG9kOiBIdHRwTWV0aG9kLkdFVCxcbiAgICAgICAgICBsYW1iZGFGdW5jdGlvbjogdGhpcy5jcmVhdGVHZXRKb2JEb2N1bWVudEZ1bmN0aW9uKCksXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICBwYXRoOiAnL2pvYnMve2pvYklkfS90aGluZ3Mve3RoaW5nTmFtZX0nLFxuICAgICAgICAgIGh0dHBNZXRob2Q6IEh0dHBNZXRob2QuR0VULFxuICAgICAgICAgIGxhbWJkYUZ1bmN0aW9uOiB0aGlzLmNyZWF0ZUdldEpvYkV4ZWN1dGlvbkZ1bmN0aW9uKCksXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICBwYXRoOiAnam9icy97am9iSWR9L3N0YXR1cycsXG4gICAgICAgICAgaHR0cE1ldGhvZDogSHR0cE1ldGhvZC5HRVQsXG4gICAgICAgICAgbGFtYmRhRnVuY3Rpb246IHRoaXMuY3JlYXRlTGlzdEpvYkV4ZWN1dGlvbnNGb3JKb2JGdW5jdGlvbigpLFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgcGF0aDogJy90aGluZ3Mve3RoaW5nTmFtZX0vam9icycsXG4gICAgICAgICAgaHR0cE1ldGhvZDogSHR0cE1ldGhvZC5HRVQsXG4gICAgICAgICAgbGFtYmRhRnVuY3Rpb246IHRoaXMuY3JlYXRlTGlzdEpvYkV4ZWN1dGlvbnNGb3JUaGluZ0Z1bmN0aW9uKCksXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICBwYXRoOiAnL2pvYnMve2pvYklkfS90aGluZ3Mve3RoaW5nTmFtZX0nLFxuICAgICAgICAgIGh0dHBNZXRob2Q6IEh0dHBNZXRob2QuREVMRVRFLFxuICAgICAgICAgIGxhbWJkYUZ1bmN0aW9uOiB0aGlzLmNyZWF0ZURlbGV0ZUpvYkV4ZWN1dGlvbkZ1bmN0aW9uKCksXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICBwYXRoOiAnL2pvYnMve2pvYklkfS90aGluZ3Mve3RoaW5nTmFtZX0vY2FuY2VsJyxcbiAgICAgICAgICBodHRwTWV0aG9kOiBIdHRwTWV0aG9kLlBVVCxcbiAgICAgICAgICBsYW1iZGFGdW5jdGlvbjogdGhpcy5jcmVhdGVDYW5jZWxKb2JFeGVjdXRpb25GdW5jdGlvbigpLFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgcGF0aDogJy9qb2ItdGVtcGxhdGVzJyxcbiAgICAgICAgICBodHRwTWV0aG9kOiBIdHRwTWV0aG9kLlBPU1QsXG4gICAgICAgICAgbGFtYmRhRnVuY3Rpb246IHRoaXMuY3JlYXRlQ3JlYXRlSm9iVGVtcGxhdGVGdW5jdGlvbigpLFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgcGF0aDogJy9qb2ItdGVtcGxhdGVzJyxcbiAgICAgICAgICBodHRwTWV0aG9kOiBIdHRwTWV0aG9kLkdFVCxcbiAgICAgICAgICBsYW1iZGFGdW5jdGlvbjogdGhpcy5jcmVhdGVMaXN0Sm9iVGVtcGxhdGVzRnVuY3Rpb24oKSxcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIHBhdGg6ICcvam9iLXRlbXBsYXRlcy97am9iVGVtcGxhdGVJZH0nLFxuICAgICAgICAgIGh0dHBNZXRob2Q6IEh0dHBNZXRob2QuR0VULFxuICAgICAgICAgIGxhbWJkYUZ1bmN0aW9uOiB0aGlzLmNyZWF0ZUdldEpvYlRlbXBsYXRlRnVuY3Rpb24oKSxcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIHBhdGg6ICcvam9iLXRlbXBsYXRlcy97am9iVGVtcGxhdGVJZH0nLFxuICAgICAgICAgIGh0dHBNZXRob2Q6IEh0dHBNZXRob2QuREVMRVRFLFxuICAgICAgICAgIGxhbWJkYUZ1bmN0aW9uOiB0aGlzLmNyZWF0ZURlbGV0ZUpvYlRlbXBsYXRlRnVuY3Rpb24oKSxcbiAgICAgICAgfSxcbiAgICAgIF0sXG4gICAgfSk7XG4gICAgaWYgKHByb3BzPy5zY2hlZHVsZUZ1bmN0aW9uKSB7XG4gICAgICBjb25zdCB0YXJnZXRUeXBlOiBzdHJpbmcgPSAnQ3JlYXRlSm9iJztcbiAgICAgIHByb3BzLnNjaGVkdWxlRnVuY3Rpb24uYWRkVGFyZ2V0RnVuY3Rpb24odGFyZ2V0VHlwZSwge1xuICAgICAgICB0YXJnZXRGdW5jdGlvbjogdGhpcy5jcmVhdGVDcmVhdGVTY2hlZHVsZUpvYkZ1bmN0aW9uKCksXG4gICAgICB9KTtcbiAgICAgIHByb3BzPy5zY2hlZHVsZUZ1bmN0aW9uPy5saXN0U2NoZWR1bGVzRnVuY3Rpb24uYWRkRW52aXJvbm1lbnQoJ0ZJWEVEX1RBUkdFVF9UWVBFJywgdGFyZ2V0VHlwZSk7XG4gICAgICBwcm9wcz8uc2NoZWR1bGVGdW5jdGlvbj8uY3JlYXRlU2NoZWR1bGVGdW5jdGlvbi5hZGRFbnZpcm9ubWVudCgnRklYRURfVEFSR0VUX1RZUEUnLCB0YXJnZXRUeXBlKTtcbiAgICAgIHRoaXMuX3Jlc3RBcGkuYWRkUmVzb3VyY2VzKFtcbiAgICAgICAge1xuICAgICAgICAgIHBhdGg6ICcvc2NoZWR1bGVzJyxcbiAgICAgICAgICBodHRwTWV0aG9kOiBIdHRwTWV0aG9kLkdFVCxcbiAgICAgICAgICBsYW1iZGFGdW5jdGlvbjogcHJvcHM/LnNjaGVkdWxlRnVuY3Rpb24ubGlzdFNjaGVkdWxlc0Z1bmN0aW9uLFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgcGF0aDogJy9zY2hlZHVsZXMnLFxuICAgICAgICAgIGh0dHBNZXRob2Q6IEh0dHBNZXRob2QuUE9TVCxcbiAgICAgICAgICBsYW1iZGFGdW5jdGlvbjogcHJvcHM/LnNjaGVkdWxlRnVuY3Rpb24uY3JlYXRlU2NoZWR1bGVGdW5jdGlvbixcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIHBhdGg6ICcvc2NoZWR1bGVzL3tzY2hlZHVsZUlkfScsXG4gICAgICAgICAgaHR0cE1ldGhvZDogSHR0cE1ldGhvZC5HRVQsXG4gICAgICAgICAgbGFtYmRhRnVuY3Rpb246IHByb3BzPy5zY2hlZHVsZUZ1bmN0aW9uLmZldGNoU2NoZWR1bGVGdW5jdGlvbixcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIHBhdGg6ICcvc2NoZWR1bGVzL3tzY2hlZHVsZUlkfScsXG4gICAgICAgICAgaHR0cE1ldGhvZDogSHR0cE1ldGhvZC5QVVQsXG4gICAgICAgICAgbGFtYmRhRnVuY3Rpb246IHByb3BzPy5zY2hlZHVsZUZ1bmN0aW9uLnVwZGF0ZVNjaGVkdWxlRnVuY3Rpb24sXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICBwYXRoOiAnL3NjaGVkdWxlcy97c2NoZWR1bGVJZH0nLFxuICAgICAgICAgIGh0dHBNZXRob2Q6IEh0dHBNZXRob2QuREVMRVRFLFxuICAgICAgICAgIGxhbWJkYUZ1bmN0aW9uOiBwcm9wcz8uc2NoZWR1bGVGdW5jdGlvbi5kZWxldGVTY2hlZHVsZUZ1bmN0aW9uLFxuICAgICAgICB9LFxuICAgICAgXSk7XG4gICAgfVxuICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgZ2V0IHJlc3RBcGlJZCgpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLl9yZXN0QXBpLnJlc3RBcGlJZDtcbiAgfVxuXG4gIHByaXZhdGUgY3JlYXRlQ3JlYXRlU2NoZWR1bGVKb2JGdW5jdGlvbigpOiBOb2RlanNGdW5jdGlvbiB7XG4gICAgY29uc3QgY3JlYXRlSm9iRnVuY3Rpb24gPSBuZXcgTm9kZWpzRnVuY3Rpb24odGhpcywgJ0NyZWF0ZVNjaGVkdWxlSm9iRnVuY3Rpb24nLCB7XG4gICAgICBlbnRyeTogYCR7TEFNQkRBX0FTU0VUU19QQVRIfS9jcmVhdGUtc2NoZWR1bGUtam9iL2FwcC50c2AsXG4gICAgfSk7XG4gICAgY3JlYXRlSm9iRnVuY3Rpb24ucm9sZT8uYXR0YWNoSW5saW5lUG9saWN5KFxuICAgICAgbmV3IFBvbGljeSh0aGlzLCAnaW90LWNyZWF0ZS1zY2hlZHVsZS1qb2ItcG9saWN5Jywge1xuICAgICAgICBzdGF0ZW1lbnRzOiBbXG4gICAgICAgICAgbmV3IFBvbGljeVN0YXRlbWVudCh7XG4gICAgICAgICAgICBhY3Rpb25zOiBbXG4gICAgICAgICAgICAgICdpb3Q6Q3JlYXRlSm9iJyxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgICByZXNvdXJjZXM6IFsnKiddLFxuICAgICAgICAgIH0pLFxuICAgICAgICBdLFxuICAgICAgfSksXG4gICAgKTtcbiAgICByZXR1cm4gY3JlYXRlSm9iRnVuY3Rpb247XG4gIH1cblxuICBwcml2YXRlIGNyZWF0ZUFzc29jaWF0ZVRhcmdldHNXaXRoSm9iRnVuY3Rpb24oKTogTm9kZWpzRnVuY3Rpb24ge1xuICAgIGNvbnN0IGNyZWF0ZUpvYkZ1bmN0aW9uID0gbmV3IE5vZGVqc0Z1bmN0aW9uKHRoaXMsICdBc3NvY2lhdGVUYXJnZXRzV2l0aEpvYkZ1bmN0aW9uJywge1xuICAgICAgZW50cnk6IGAke0xBTUJEQV9BU1NFVFNfUEFUSH0vYXNzb2NpYXRlLXRhcmdldHMtd2l0aC1qb2IvYXBwLnRzYCxcbiAgICB9KTtcbiAgICBjcmVhdGVKb2JGdW5jdGlvbi5yb2xlPy5hdHRhY2hJbmxpbmVQb2xpY3koXG4gICAgICBuZXcgUG9saWN5KHRoaXMsICdpb3QtYXNzb2NpYXRlLXRhcmdldHMtd2l0aC1qb2InLCB7XG4gICAgICAgIHN0YXRlbWVudHM6IFtcbiAgICAgICAgICBuZXcgUG9saWN5U3RhdGVtZW50KHtcbiAgICAgICAgICAgIGFjdGlvbnM6IFtcbiAgICAgICAgICAgICAgJ2lvdDpBc3NvY2lhdGVUYXJnZXRzV2l0aEpvYicsXG4gICAgICAgICAgICBdLFxuICAgICAgICAgICAgcmVzb3VyY2VzOiBbJyonXSxcbiAgICAgICAgICB9KSxcbiAgICAgICAgXSxcbiAgICAgIH0pLFxuICAgICk7XG4gICAgcmV0dXJuIGNyZWF0ZUpvYkZ1bmN0aW9uO1xuICB9XG5cbiAgcHJpdmF0ZSBjcmVhdGVDcmVhdGVKb2JGdW5jdGlvbigpOiBOb2RlanNGdW5jdGlvbiB7XG4gICAgY29uc3QgY3JlYXRlSm9iRnVuY3Rpb24gPSBuZXcgTm9kZWpzRnVuY3Rpb24odGhpcywgJ0NyZWF0ZUpvYkZ1bmN0aW9uJywge1xuICAgICAgZW50cnk6IGAke0xBTUJEQV9BU1NFVFNfUEFUSH0vY3JlYXRlLWpvYi9hcHAudHNgLFxuICAgIH0pO1xuICAgIGNyZWF0ZUpvYkZ1bmN0aW9uLnJvbGU/LmF0dGFjaElubGluZVBvbGljeShcbiAgICAgIG5ldyBQb2xpY3kodGhpcywgJ2lvdC1jcmVhdGUtam9iLXBvbGljeScsIHtcbiAgICAgICAgc3RhdGVtZW50czogW1xuICAgICAgICAgIG5ldyBQb2xpY3lTdGF0ZW1lbnQoe1xuICAgICAgICAgICAgYWN0aW9uczogW1xuICAgICAgICAgICAgICAnaW90OkNyZWF0ZUpvYicsXG4gICAgICAgICAgICBdLFxuICAgICAgICAgICAgcmVzb3VyY2VzOiBbJyonXSxcbiAgICAgICAgICB9KSxcbiAgICAgICAgXSxcbiAgICAgIH0pLFxuICAgICk7XG4gICAgcmV0dXJuIGNyZWF0ZUpvYkZ1bmN0aW9uO1xuICB9XG5cbiAgcHJpdmF0ZSBjcmVhdGVMaXN0Sm9ic0Z1bmN0aW9uKCk6IE5vZGVqc0Z1bmN0aW9uIHtcbiAgICBjb25zdCBsaXN0Sm9ic0Z1bmN0aW9uID0gbmV3IE5vZGVqc0Z1bmN0aW9uKHRoaXMsICdMaXN0Sm9ic0Z1bmN0aW9uJywge1xuICAgICAgZW50cnk6IGAke0xBTUJEQV9BU1NFVFNfUEFUSH0vbGlzdC1qb2JzL2FwcC50c2AsXG4gICAgfSk7XG4gICAgbGlzdEpvYnNGdW5jdGlvbi5yb2xlPy5hdHRhY2hJbmxpbmVQb2xpY3koXG4gICAgICBuZXcgUG9saWN5KHRoaXMsICdpb3QtbGlzdC1qb2JzLXBvbGljeScsIHtcbiAgICAgICAgc3RhdGVtZW50czogW1xuICAgICAgICAgIG5ldyBQb2xpY3lTdGF0ZW1lbnQoe1xuICAgICAgICAgICAgYWN0aW9uczogW1xuICAgICAgICAgICAgICAnaW90Okxpc3RKb2JzJyxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgICByZXNvdXJjZXM6IFsnKiddLFxuICAgICAgICAgIH0pLFxuICAgICAgICBdLFxuICAgICAgfSksXG4gICAgKTtcbiAgICByZXR1cm4gbGlzdEpvYnNGdW5jdGlvbjtcbiAgfVxuXG4gIHByaXZhdGUgY3JlYXRlR2V0Sm9iRnVuY3Rpb24oKTogTm9kZWpzRnVuY3Rpb24ge1xuICAgIGNvbnN0IGdldEpvYkZ1bmN0aW9uID0gbmV3IE5vZGVqc0Z1bmN0aW9uKHRoaXMsICdHZXRKb2JGdW5jdGlvbicsIHtcbiAgICAgIGVudHJ5OiBgJHtMQU1CREFfQVNTRVRTX1BBVEh9L2dldC1qb2IvYXBwLnRzYCxcbiAgICB9KTtcbiAgICBnZXRKb2JGdW5jdGlvbi5yb2xlPy5hdHRhY2hJbmxpbmVQb2xpY3koXG4gICAgICBuZXcgUG9saWN5KHRoaXMsICdpb3QtZGVzY3JpYmUtam9iLXBvbGljeScsIHtcbiAgICAgICAgc3RhdGVtZW50czogW1xuICAgICAgICAgIG5ldyBQb2xpY3lTdGF0ZW1lbnQoe1xuICAgICAgICAgICAgYWN0aW9uczogW1xuICAgICAgICAgICAgICAnaW90OkRlc2NyaWJlSm9iJyxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgICByZXNvdXJjZXM6IFsnKiddLFxuICAgICAgICAgIH0pLFxuICAgICAgICBdLFxuICAgICAgfSksXG4gICAgKTtcbiAgICByZXR1cm4gZ2V0Sm9iRnVuY3Rpb247XG4gIH1cblxuICBwcml2YXRlIGNyZWF0ZVVwZGF0ZUpvYkZ1bmN0aW9uKCk6IE5vZGVqc0Z1bmN0aW9uIHtcbiAgICBjb25zdCB1cGRhdGVKb2JGdW5jdGlvbiA9IG5ldyBOb2RlanNGdW5jdGlvbih0aGlzLCAnVXBkYXRlSm9iRnVuY3Rpb24nLCB7XG4gICAgICBlbnRyeTogYCR7TEFNQkRBX0FTU0VUU19QQVRIfS91cGRhdGUtam9iL2FwcC50c2AsXG4gICAgfSk7XG4gICAgdXBkYXRlSm9iRnVuY3Rpb24ucm9sZT8uYXR0YWNoSW5saW5lUG9saWN5KFxuICAgICAgbmV3IFBvbGljeSh0aGlzLCAnaW90LXVwZGF0ZS1qb2ItcG9saWN5Jywge1xuICAgICAgICBzdGF0ZW1lbnRzOiBbXG4gICAgICAgICAgbmV3IFBvbGljeVN0YXRlbWVudCh7XG4gICAgICAgICAgICBhY3Rpb25zOiBbXG4gICAgICAgICAgICAgICdpb3Q6VXBkYXRlSm9iJyxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgICByZXNvdXJjZXM6IFsnKiddLFxuICAgICAgICAgIH0pLFxuICAgICAgICBdLFxuICAgICAgfSksXG4gICAgKTtcbiAgICByZXR1cm4gdXBkYXRlSm9iRnVuY3Rpb247XG4gIH1cblxuICBwcml2YXRlIGNyZWF0ZURlbGV0ZUpvYkZ1bmN0aW9uKCk6IE5vZGVqc0Z1bmN0aW9uIHtcbiAgICBjb25zdCBkZWxldGVKb2JGdW5jdGlvbiA9IG5ldyBOb2RlanNGdW5jdGlvbih0aGlzLCAnRGVsZXRlSm9iRnVuY3Rpb24nLCB7XG4gICAgICBlbnRyeTogYCR7TEFNQkRBX0FTU0VUU19QQVRIfS9kZWxldGUtam9iL2FwcC50c2AsXG4gICAgfSk7XG4gICAgZGVsZXRlSm9iRnVuY3Rpb24ucm9sZT8uYXR0YWNoSW5saW5lUG9saWN5KFxuICAgICAgbmV3IFBvbGljeSh0aGlzLCAnaW90LWRlbGV0ZS1qb2ItcG9saWN5Jywge1xuICAgICAgICBzdGF0ZW1lbnRzOiBbXG4gICAgICAgICAgbmV3IFBvbGljeVN0YXRlbWVudCh7XG4gICAgICAgICAgICBhY3Rpb25zOiBbXG4gICAgICAgICAgICAgICdpb3Q6RGVsZXRlSm9iJyxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgICByZXNvdXJjZXM6IFsnKiddLFxuICAgICAgICAgIH0pLFxuICAgICAgICBdLFxuICAgICAgfSksXG4gICAgKTtcbiAgICByZXR1cm4gZGVsZXRlSm9iRnVuY3Rpb247XG4gIH1cblxuICBwcml2YXRlIGNyZWF0ZUNhbmNlbEpvYkZ1bmN0aW9uKCk6IE5vZGVqc0Z1bmN0aW9uIHtcbiAgICBjb25zdCBjYW5jZWxKb2JGdW5jdGlvbiA9IG5ldyBOb2RlanNGdW5jdGlvbih0aGlzLCAnQ2FuY2VsSm9iRnVuY3Rpb24nLCB7XG4gICAgICBlbnRyeTogYCR7TEFNQkRBX0FTU0VUU19QQVRIfS9jYW5jZWwtam9iL2FwcC50c2AsXG4gICAgfSk7XG4gICAgY2FuY2VsSm9iRnVuY3Rpb24ucm9sZT8uYXR0YWNoSW5saW5lUG9saWN5KFxuICAgICAgbmV3IFBvbGljeSh0aGlzLCAnaW90LWNhbmNlbC1qb2ItcG9saWN5Jywge1xuICAgICAgICBzdGF0ZW1lbnRzOiBbXG4gICAgICAgICAgbmV3IFBvbGljeVN0YXRlbWVudCh7XG4gICAgICAgICAgICBhY3Rpb25zOiBbXG4gICAgICAgICAgICAgICdpb3Q6Q2FuY2VsSm9iJyxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgICByZXNvdXJjZXM6IFsnKiddLFxuICAgICAgICAgIH0pLFxuICAgICAgICBdLFxuICAgICAgfSksXG4gICAgKTtcbiAgICByZXR1cm4gY2FuY2VsSm9iRnVuY3Rpb247XG4gIH1cblxuICBwcml2YXRlIGNyZWF0ZUdldEpvYkV4ZWN1dGlvbkZ1bmN0aW9uKCk6IE5vZGVqc0Z1bmN0aW9uIHtcbiAgICBjb25zdCBnZXRKb2JFeGVjdXRpb25GdW5jdGlvbiA9IG5ldyBOb2RlanNGdW5jdGlvbih0aGlzLCAnR2V0Sm9iRXhlY3V0aW9uRnVuY3Rpb24nLCB7XG4gICAgICBlbnRyeTogYCR7TEFNQkRBX0FTU0VUU19QQVRIfS9nZXQtam9iLWV4ZWN1dGlvbi9hcHAudHNgLFxuICAgIH0pO1xuICAgIGdldEpvYkV4ZWN1dGlvbkZ1bmN0aW9uLnJvbGU/LmF0dGFjaElubGluZVBvbGljeShcbiAgICAgIG5ldyBQb2xpY3kodGhpcywgJ2lvdC1kZXNjcmliZS1qb2ItZXhlY3V0aW9uLXBvbGljeScsIHtcbiAgICAgICAgc3RhdGVtZW50czogW1xuICAgICAgICAgIG5ldyBQb2xpY3lTdGF0ZW1lbnQoe1xuICAgICAgICAgICAgYWN0aW9uczogW1xuICAgICAgICAgICAgICAnaW90OkRlc2NyaWJlSm9iRXhlY3V0aW9uJyxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgICByZXNvdXJjZXM6IFsnKiddLFxuICAgICAgICAgIH0pLFxuICAgICAgICBdLFxuICAgICAgfSksXG4gICAgKTtcbiAgICByZXR1cm4gZ2V0Sm9iRXhlY3V0aW9uRnVuY3Rpb247XG4gIH1cblxuICBwcml2YXRlIGNyZWF0ZUxpc3RKb2JFeGVjdXRpb25zRm9ySm9iRnVuY3Rpb24oKTogTm9kZWpzRnVuY3Rpb24ge1xuICAgIGNvbnN0IGxpc3RKb2JFeGVjdXRpb25zRm9ySm9iID0gbmV3IE5vZGVqc0Z1bmN0aW9uKHRoaXMsICdsaXN0Sm9iRXhlY3V0aW9uc0ZvckpvYicsIHtcbiAgICAgIGVudHJ5OiBgJHtMQU1CREFfQVNTRVRTX1BBVEh9L2xpc3Qtam9iLWV4ZWN1dGlvbnMtZm9yLWpvYi9hcHAudHNgLFxuICAgIH0pO1xuICAgIGxpc3RKb2JFeGVjdXRpb25zRm9ySm9iLnJvbGU/LmF0dGFjaElubGluZVBvbGljeShcbiAgICAgIG5ldyBQb2xpY3kodGhpcywgJ2xpc3Qtam9iLWV4ZWN1dGlvbi1mb3Itam9iJywge1xuICAgICAgICBzdGF0ZW1lbnRzOiBbXG4gICAgICAgICAgbmV3IFBvbGljeVN0YXRlbWVudCh7XG4gICAgICAgICAgICBhY3Rpb25zOiBbXG4gICAgICAgICAgICAgICdpb3Q6TGlzdEpvYkV4ZWN1dGlvbnNGb3JKb2InLFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICAgIHJlc291cmNlczogWycqJ10sXG4gICAgICAgICAgfSksXG4gICAgICAgIF0sXG4gICAgICB9KSxcbiAgICApO1xuICAgIHJldHVybiBsaXN0Sm9iRXhlY3V0aW9uc0ZvckpvYjtcbiAgfVxuXG4gIHByaXZhdGUgY3JlYXRlTGlzdEpvYkV4ZWN1dGlvbnNGb3JUaGluZ0Z1bmN0aW9uKCk6IE5vZGVqc0Z1bmN0aW9uIHtcbiAgICBjb25zdCBsaXN0Sm9iRXhlY3V0aW9uc0ZvclRoaW5nID0gbmV3IE5vZGVqc0Z1bmN0aW9uKHRoaXMsICdsaXN0Sm9iRXhlY3V0aW9uc0ZvclRoaW5nJywge1xuICAgICAgZW50cnk6IGAke0xBTUJEQV9BU1NFVFNfU