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.

409 lines 51.1 kB
"use strict"; var _a; Object.defineProperty(exports, "__esModule", { value: true }); exports.FileApi = 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_dynamodb_1 = require("aws-cdk-lib/aws-dynamodb"); 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/files'); /** * File API construct. * * @stability stable */ class FileApi extends constructs_1.Construct { /** * @stability stable */ constructor(scope, id, props) { var _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y; super(scope, id); this.categoryTable = new aws_dynamodb_1.Table(this, 'CategoryTable', { partitionKey: { name: 'categoryId', type: aws_dynamodb_1.AttributeType.STRING, }, readCapacity: (_c = (_b = props === null || props === void 0 ? void 0 : props.categoryTableConfig) === null || _b === void 0 ? void 0 : _b.primaryIndex.readCapacity) !== null && _c !== void 0 ? _c : 1, writeCapacity: (_e = (_d = props === null || props === void 0 ? void 0 : props.categoryTableConfig) === null || _d === void 0 ? void 0 : _d.primaryIndex.writeCapacity) !== null && _e !== void 0 ? _e : 1, }); this.categoryTable.addGlobalSecondaryIndex({ indexName: 'query-by-parent-id', partitionKey: { name: 'parentId', type: aws_dynamodb_1.AttributeType.STRING, }, projectionType: aws_dynamodb_1.ProjectionType.ALL, readCapacity: (_g = (_f = props === null || props === void 0 ? void 0 : props.categoryTableConfig) === null || _f === void 0 ? void 0 : _f.indexQueryByParentId.readCapacity) !== null && _g !== void 0 ? _g : 1, writeCapacity: (_j = (_h = props === null || props === void 0 ? void 0 : props.categoryTableConfig) === null || _h === void 0 ? void 0 : _h.indexQueryByParentId.writeCapacity) !== null && _j !== void 0 ? _j : 1, }); this.fileTable = new aws_dynamodb_1.Table(this, 'FileTable', { partitionKey: { name: 'fileId', type: aws_dynamodb_1.AttributeType.STRING, }, readCapacity: (_l = (_k = props === null || props === void 0 ? void 0 : props.fileTableConfig) === null || _k === void 0 ? void 0 : _k.primaryIndex.readCapacity) !== null && _l !== void 0 ? _l : 1, writeCapacity: (_o = (_m = props === null || props === void 0 ? void 0 : props.fileTableConfig) === null || _m === void 0 ? void 0 : _m.primaryIndex.writeCapacity) !== null && _o !== void 0 ? _o : 1, }); this.fileTable.addGlobalSecondaryIndex({ indexName: 'query-by-category-id-and-locale', partitionKey: { name: 'categoryId', type: aws_dynamodb_1.AttributeType.STRING, }, sortKey: { name: 'locale', type: aws_dynamodb_1.AttributeType.STRING, }, projectionType: aws_dynamodb_1.ProjectionType.ALL, readCapacity: (_q = (_p = props === null || props === void 0 ? void 0 : props.fileTableConfig) === null || _p === void 0 ? void 0 : _p.indexQueryByCategoryIdAndLocale.readCapacity) !== null && _q !== void 0 ? _q : 1, writeCapacity: (_s = (_r = props === null || props === void 0 ? void 0 : props.fileTableConfig) === null || _r === void 0 ? void 0 : _r.indexQueryByCategoryIdAndLocale.writeCapacity) !== null && _s !== void 0 ? _s : 1, }); this.fileTable.addGlobalSecondaryIndex({ indexName: 'get-file-by-checksum-and-version', partitionKey: { name: 'checksum', type: aws_dynamodb_1.AttributeType.STRING, }, sortKey: { name: 'version', type: aws_dynamodb_1.AttributeType.STRING, }, projectionType: aws_dynamodb_1.ProjectionType.ALL, readCapacity: (_u = (_t = props === null || props === void 0 ? void 0 : props.fileTableConfig) === null || _t === void 0 ? void 0 : _t.indexGetFileByChecksumAndVersion.readCapacity) !== null && _u !== void 0 ? _u : 1, writeCapacity: (_w = (_v = props === null || props === void 0 ? void 0 : props.fileTableConfig) === null || _v === void 0 ? void 0 : _v.indexGetFileByChecksumAndVersion.writeCapacity) !== null && _w !== void 0 ? _w : 1, }); this._restApi = new cdk_restapi_1.RestApi(this, 'FileRestApi', { enableCors: true, authorizationType: (_x = props === null || props === void 0 ? void 0 : props.authorizationType) !== null && _x !== void 0 ? _x : aws_apigateway_1.AuthorizationType.NONE, authorizer: (_y = props === null || props === void 0 ? void 0 : props.authorizer) !== null && _y !== void 0 ? _y : undefined, resources: [ { path: '/categories', httpMethod: cdk_restapi_1.HttpMethod.POST, lambdaFunction: this.createCreateCategoryFunction(), }, { path: '/categories', httpMethod: cdk_restapi_1.HttpMethod.GET, lambdaFunction: this.createListCategoriesFunction(), }, { path: '/categories/{categoryId}', httpMethod: cdk_restapi_1.HttpMethod.GET, lambdaFunction: this.createGetCategoryFunction(), }, { path: '/categories/{categoryId}', httpMethod: cdk_restapi_1.HttpMethod.PUT, lambdaFunction: this.createUpdateCategoryFunction(), }, { path: '/categories/{categoryId}', httpMethod: cdk_restapi_1.HttpMethod.DELETE, lambdaFunction: this.createDeleteCategoryFunction(), }, { path: '/categories/{categoryId}/files', httpMethod: cdk_restapi_1.HttpMethod.GET, lambdaFunction: this.createListFilesByCategoryFunction(), }, { path: '/files', httpMethod: cdk_restapi_1.HttpMethod.GET, lambdaFunction: this.createListFilesFunction(), }, { path: '/files', httpMethod: cdk_restapi_1.HttpMethod.POST, lambdaFunction: this.createCreateFilesFunction(), }, { path: '/files', httpMethod: cdk_restapi_1.HttpMethod.PUT, lambdaFunction: this.createUpdateFilesFunction(), }, { path: '/files', httpMethod: cdk_restapi_1.HttpMethod.DELETE, lambdaFunction: this.createDeleteFilesFunction(), }, { path: '/files/{checksum}/versions/{version}', httpMethod: cdk_restapi_1.HttpMethod.GET, lambdaFunction: this.createGetFilesFunction(), }, ], }); } /** * File API API ID. * * @stability stable */ get restApiId() { return this._restApi.restApiId; } createCreateCategoryFunction() { var _b; const createCategoryFunction = new aws_lambda_nodejs_1.NodejsFunction(this, 'CreateCategoryFunction', { entry: `${LAMBDA_ASSETS_PATH}/create-category/app.ts`, environment: { CATEGORY_TABLE_NAME: this.categoryTable.tableName, }, }); (_b = createCategoryFunction.role) === null || _b === void 0 ? void 0 : _b.attachInlinePolicy(new aws_iam_1.Policy(this, 'create-category-policy', { statements: [ new aws_iam_1.PolicyStatement({ actions: [ 'dynamodb:GetItem', 'dynamodb:PutItem', ], resources: [ this.categoryTable.tableArn, ], }), ], })); return createCategoryFunction; } createListCategoriesFunction() { var _b; const listCategoriesFunction = new aws_lambda_nodejs_1.NodejsFunction(this, 'ListCategoriesFunction', { entry: `${LAMBDA_ASSETS_PATH}/list-categories/app.ts`, environment: { CATEGORY_TABLE_NAME: this.categoryTable.tableName, }, }); (_b = listCategoriesFunction.role) === null || _b === void 0 ? void 0 : _b.attachInlinePolicy(new aws_iam_1.Policy(this, 'list-categories-policy', { statements: [ new aws_iam_1.PolicyStatement({ actions: [ 'dynamodb:Query', 'dynamodb:Scan', 'dynamodb:GetItem', ], resources: [ this.categoryTable.tableArn, `${this.categoryTable.tableArn}/index/query-by-parent-id`, ], }), ], })); return listCategoriesFunction; } createGetCategoryFunction() { var _b; const getCategoryFunction = new aws_lambda_nodejs_1.NodejsFunction(this, 'GetCategoryFunction', { entry: `${LAMBDA_ASSETS_PATH}/get-category/app.ts`, environment: { CATEGORY_TABLE_NAME: this.categoryTable.tableName, }, }); (_b = getCategoryFunction.role) === null || _b === void 0 ? void 0 : _b.attachInlinePolicy(new aws_iam_1.Policy(this, 'get-category-policy', { statements: [ new aws_iam_1.PolicyStatement({ actions: [ 'dynamodb:GetItem', ], resources: [ this.categoryTable.tableArn, ], }), ], })); return getCategoryFunction; } createUpdateCategoryFunction() { var _b; const updateCategoryFunction = new aws_lambda_nodejs_1.NodejsFunction(this, 'UpdateCategoryFunction', { entry: `${LAMBDA_ASSETS_PATH}/update-category/app.ts`, environment: { CATEGORY_TABLE_NAME: this.categoryTable.tableName, }, }); (_b = updateCategoryFunction.role) === null || _b === void 0 ? void 0 : _b.attachInlinePolicy(new aws_iam_1.Policy(this, 'update-category-policy', { statements: [ new aws_iam_1.PolicyStatement({ actions: [ 'dynamodb:GetItem', 'dynamodb:UpdateItem', ], resources: [ this.categoryTable.tableArn, ], }), ], })); return updateCategoryFunction; } createDeleteCategoryFunction() { var _b; const deleteCategoryFunction = new aws_lambda_nodejs_1.NodejsFunction(this, 'DeleteCategoryFunction', { entry: `${LAMBDA_ASSETS_PATH}/delete-category/app.ts`, environment: { CATEGORY_TABLE_NAME: this.categoryTable.tableName, }, }); (_b = deleteCategoryFunction.role) === null || _b === void 0 ? void 0 : _b.attachInlinePolicy(new aws_iam_1.Policy(this, 'delete-category-policy', { statements: [ new aws_iam_1.PolicyStatement({ actions: [ 'dynamodb:DeleteItem', ], resources: [ this.categoryTable.tableArn, ], }), ], })); return deleteCategoryFunction; } createCreateFilesFunction() { var _b; const createFilesFunction = new aws_lambda_nodejs_1.NodejsFunction(this, 'CreateFilesFunction', { entry: `${LAMBDA_ASSETS_PATH}/create-files/app.ts`, environment: { FILE_TABLE_NAME: this.fileTable.tableName, CATEGORY_TABLE_NAME: this.categoryTable.tableName, }, }); (_b = createFilesFunction.role) === null || _b === void 0 ? void 0 : _b.attachInlinePolicy(new aws_iam_1.Policy(this, 'create-file-policy', { statements: [ new aws_iam_1.PolicyStatement({ actions: [ 'dynamodb:GetItem', 'dynamodb:Query', 'dynamodb:BatchWriteItem', ], resources: [ this.fileTable.tableArn, `${this.fileTable.tableArn}/index/get-file-by-checksum-and-version`, this.categoryTable.tableArn, ], }), ], })); return createFilesFunction; } createListFilesFunction() { var _b; const listFilesFunction = new aws_lambda_nodejs_1.NodejsFunction(this, 'ListFilesFunction', { entry: `${LAMBDA_ASSETS_PATH}/list-files/app.ts`, environment: { FILE_TABLE_NAME: this.fileTable.tableName, }, }); (_b = listFilesFunction.role) === null || _b === void 0 ? void 0 : _b.attachInlinePolicy(new aws_iam_1.Policy(this, 'list-files-policy', { statements: [ new aws_iam_1.PolicyStatement({ actions: [ 'dynamodb:Scan', ], resources: [ this.fileTable.tableArn, ], }), ], })); return listFilesFunction; } createListFilesByCategoryFunction() { var _b; const listFilesByCategoryFunction = new aws_lambda_nodejs_1.NodejsFunction(this, 'ListFilesByCategoryFunction', { entry: `${LAMBDA_ASSETS_PATH}/list-files-by-category/app.ts`, environment: { FILE_TABLE_NAME: this.fileTable.tableName, }, }); (_b = listFilesByCategoryFunction.role) === null || _b === void 0 ? void 0 : _b.attachInlinePolicy(new aws_iam_1.Policy(this, 'list-files-by-category-policy', { statements: [ new aws_iam_1.PolicyStatement({ actions: [ 'dynamodb:Query', ], resources: [ this.fileTable.tableArn, `${this.fileTable.tableArn}/index/query-by-category-id-and-locale`, ], }), ], })); return listFilesByCategoryFunction; } createGetFilesFunction() { var _b; const getFilesFunction = new aws_lambda_nodejs_1.NodejsFunction(this, 'GetFilesFunction', { entry: `${LAMBDA_ASSETS_PATH}/get-files/app.ts`, environment: { FILE_TABLE_NAME: this.fileTable.tableName, }, }); (_b = getFilesFunction.role) === null || _b === void 0 ? void 0 : _b.attachInlinePolicy(new aws_iam_1.Policy(this, 'get-files-policy', { statements: [ new aws_iam_1.PolicyStatement({ actions: [ 'dynamodb:Query', ], resources: [ this.fileTable.tableArn, ], }), ], })); return getFilesFunction; } createUpdateFilesFunction() { var _b; const updateFilesFunction = new aws_lambda_nodejs_1.NodejsFunction(this, 'UpdateFilesFunction', { entry: `${LAMBDA_ASSETS_PATH}/update-files/app.ts`, environment: { FILE_TABLE_NAME: this.fileTable.tableName, }, }); (_b = updateFilesFunction.role) === null || _b === void 0 ? void 0 : _b.attachInlinePolicy(new aws_iam_1.Policy(this, 'update-file-policy', { statements: [ new aws_iam_1.PolicyStatement({ actions: [ 'dynamodb:BatchWriteItem', 'dynamodb:BatchGetItem', ], resources: [ this.fileTable.tableArn, ], }), ], })); return updateFilesFunction; } createDeleteFilesFunction() { var _b; const deleteFilesFunction = new aws_lambda_nodejs_1.NodejsFunction(this, 'DeleteFilesFunction', { entry: `${LAMBDA_ASSETS_PATH}/delete-files/app.ts`, environment: { FILE_TABLE_NAME: this.fileTable.tableName, }, }); (_b = deleteFilesFunction.role) === null || _b === void 0 ? void 0 : _b.attachInlinePolicy(new aws_iam_1.Policy(this, 'delete-file-policy', { statements: [ new aws_iam_1.PolicyStatement({ actions: [ 'dynamodb:BatchWriteItem', ], resources: [ this.fileTable.tableArn, ], }), ], })); return deleteFilesFunction; } } exports.FileApi = FileApi; _a = JSII_RTTI_SYMBOL_1; FileApi[_a] = { fqn: "@softchef/cdk-iot-device-management.FileApi", version: "2.0.0" }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmlsZS1hcGkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvZmlsZS1hcGkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSw2QkFBNkI7QUFDN0IsdURBRytCO0FBQy9CLCtEQUdvQztBQUNwQywyREFJa0M7QUFDbEMsaURBRzZCO0FBQzdCLHFFQUV1QztBQUN2QywyQ0FFb0I7QUFFcEIsTUFBTSxrQkFBa0IsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLFNBQVMsRUFBRSx3QkFBd0IsQ0FBQyxDQUFDOzs7Ozs7QUF5QzdFLE1BQWEsT0FBUSxTQUFRLHNCQUFTOzs7O0lBVXBDLFlBQVksS0FBZ0IsRUFBRSxFQUFVLEVBQUUsS0FBb0I7O1FBQzVELEtBQUssQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFDakIsSUFBSSxDQUFDLGFBQWEsR0FBRyxJQUFJLG9CQUFLLENBQUMsSUFBSSxFQUFFLGVBQWUsRUFBRTtZQUNwRCxZQUFZLEVBQUU7Z0JBQ1osSUFBSSxFQUFFLFlBQVk7Z0JBQ2xCLElBQUksRUFBRSw0QkFBYSxDQUFDLE1BQU07YUFDM0I7WUFDRCxZQUFZLGNBQUUsS0FBSyxhQUFMLEtBQUssdUJBQUwsS0FBSyxDQUFFLG1CQUFtQiwwQ0FBRSxZQUFZLENBQUMsWUFBWSxtQ0FBSSxDQUFDO1lBQ3hFLGFBQWEsY0FBRSxLQUFLLGFBQUwsS0FBSyx1QkFBTCxLQUFLLENBQUUsbUJBQW1CLDBDQUFFLFlBQVksQ0FBQyxhQUFhLG1DQUFJLENBQUM7U0FDM0UsQ0FBQyxDQUFDO1FBQ0gsSUFBSSxDQUFDLGFBQWEsQ0FBQyx1QkFBdUIsQ0FBQztZQUN6QyxTQUFTLEVBQUUsb0JBQW9CO1lBQy9CLFlBQVksRUFBRTtnQkFDWixJQUFJLEVBQUUsVUFBVTtnQkFDaEIsSUFBSSxFQUFFLDRCQUFhLENBQUMsTUFBTTthQUMzQjtZQUNELGNBQWMsRUFBRSw2QkFBYyxDQUFDLEdBQUc7WUFDbEMsWUFBWSxjQUFFLEtBQUss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QkFDVixJQUFJLHlCQUFlLENBQUM7b0JBQ2xCLE9BQU8sRUFBRTt3QkFDUCx5QkFBeUI7cUJBQzFCO29CQUNELFNBQVMsRUFBRTt3QkFDVCxJQUFJLENBQUMsU0FBUyxDQUFDLFFBQVE7cUJBQ3hCO2lCQUNGLENBQUM7YUFDSDtTQUNGLENBQUMsRUFDRjtRQUNGLE9BQU8sbUJBQW1CLENBQUM7SUFDN0IsQ0FBQzs7QUExWkgsMEJBMlpDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgcGF0aCBmcm9tICdwYXRoJztcbmltcG9ydCB7XG4gIFJlc3RBcGksXG4gIEh0dHBNZXRob2QsXG59IGZyb20gJ0Bzb2Z0Y2hlZi9jZGstcmVzdGFwaSc7XG5pbXBvcnQge1xuICBBdXRob3JpemF0aW9uVHlwZSxcbiAgSUF1dGhvcml6ZXIsXG59IGZyb20gJ2F3cy1jZGstbGliL2F3cy1hcGlnYXRld2F5JztcbmltcG9ydCB7XG4gIEF0dHJpYnV0ZVR5cGUsXG4gIFByb2plY3Rpb25UeXBlLFxuICBUYWJsZSxcbn0gZnJvbSAnYXdzLWNkay1saWIvYXdzLWR5bmFtb2RiJztcbmltcG9ydCB7XG4gIFBvbGljeSxcbiAgUG9saWN5U3RhdGVtZW50LFxufSBmcm9tICdhd3MtY2RrLWxpYi9hd3MtaWFtJztcbmltcG9ydCB7XG4gIE5vZGVqc0Z1bmN0aW9uLFxufSBmcm9tICdhd3MtY2RrLWxpYi9hd3MtbGFtYmRhLW5vZGVqcyc7XG5pbXBvcnQge1xuICBDb25zdHJ1Y3QsXG59IGZyb20gJ2NvbnN0cnVjdHMnO1xuXG5jb25zdCBMQU1CREFfQVNTRVRTX1BBVEggPSBwYXRoLnJlc29sdmUoX19kaXJuYW1lLCAnLi4vbGFtYmRhLWFzc2V0cy9maWxlcycpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG5leHBvcnQgaW50ZXJmYWNlIENhcGFjaXR5IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gIHJlYWRvbmx5IHdyaXRlQ2FwYWNpdHk/OiBudW1iZXI7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gIHJlYWRvbmx5IHJlYWRDYXBhY2l0eT86IG51bWJlcjtcbn1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbmV4cG9ydCBpbnRlcmZhY2UgQ2F0ZWdvcnlUYWJsZUNvbmZpZyB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gIHJlYWRvbmx5IHByaW1hcnlJbmRleDogQ2FwYWNpdHk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgcmVhZG9ubHkgaW5kZXhRdWVyeUJ5UGFyZW50SWQ6IENhcGFjaXR5O1xufVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG5leHBvcnQgaW50ZXJmYWNlIEZpbGVUYWJsZUNvbmZpZyB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gIHJlYWRvbmx5IHByaW1hcnlJbmRleDogQ2FwYWNpdHk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICByZWFkb25seSBpbmRleFF1ZXJ5QnlDYXRlZ29yeUlkQW5kTG9jYWxlOiBDYXBhY2l0eTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICByZWFkb25seSBpbmRleEdldEZpbGVCeUNoZWNrc3VtQW5kVmVyc2lvbjogQ2FwYWNpdHk7XG59XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICBcbmV4cG9ydCBpbnRlcmZhY2UgRmlsZUFwaVByb3BzIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgcmVhZG9ubHkgYXV0aG9yaXphdGlvblR5cGU/OiBBdXRob3JpemF0aW9uVHlwZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgcmVhZG9ubHkgYXV0aG9yaXplcj86IElBdXRob3JpemVyIHwgdW5kZWZpbmVkO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gIHJlYWRvbmx5IGNhdGVnb3J5VGFibGVDb25maWc/OiBDYXRlZ29yeVRhYmxlQ29uZmlnO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgcmVhZG9ubHkgZmlsZVRhYmxlQ29uZmlnPzogRmlsZVRhYmxlQ29uZmlnO1xufVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuZXhwb3J0IGNsYXNzIEZpbGVBcGkgZXh0ZW5kcyBDb25zdHJ1Y3Qge1xuICAvKipcbiAgICogVGhlIEZpbGUgQVBJIEdhdGV3YXlcbiAgICovXG4gIHByaXZhdGUgcmVhZG9ubHkgX3Jlc3RBcGk6IFJlc3RBcGk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICBwdWJsaWMgcmVhZG9ubHkgY2F0ZWdvcnlUYWJsZTogVGFibGU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gIHB1YmxpYyByZWFkb25seSBmaWxlVGFibGU6IFRhYmxlO1xuXG4gIGNvbnN0cnVjdG9yKHNjb3BlOiBDb25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHByb3BzPzogRmlsZUFwaVByb3BzKSB7XG4gICAgc3VwZXIoc2NvcGUsIGlkKTtcbiAgICB0aGlzLmNhdGVnb3J5VGFibGUgPSBuZXcgVGFibGUodGhpcywgJ0NhdGVnb3J5VGFibGUnLCB7XG4gICAgICBwYXJ0aXRpb25LZXk6IHtcbiAgICAgICAgbmFtZTogJ2NhdGVnb3J5SWQnLFxuICAgICAgICB0eXBlOiBBdHRyaWJ1dGVUeXBlLlNUUklORyxcbiAgICAgIH0sXG4gICAgICByZWFkQ2FwYWNpdHk6IHByb3BzPy5jYXRlZ29yeVRhYmxlQ29uZmlnPy5wcmltYXJ5SW5kZXgucmVhZENhcGFjaXR5ID8/IDEsXG4gICAgICB3cml0ZUNhcGFjaXR5OiBwcm9wcz8uY2F0ZWdvcnlUYWJsZUNvbmZpZz8ucHJpbWFyeUluZGV4LndyaXRlQ2FwYWNpdHkgPz8gMSxcbiAgICB9KTtcbiAgICB0aGlzLmNhdGVnb3J5VGFibGUuYWRkR2xvYmFsU2Vjb25kYXJ5SW5kZXgoe1xuICAgICAgaW5kZXhOYW1lOiAncXVlcnktYnktcGFyZW50LWlkJyxcbiAgICAgIHBhcnRpdGlvbktleToge1xuICAgICAgICBuYW1lOiAncGFyZW50SWQnLFxuICAgICAgICB0eXBlOiBBdHRyaWJ1dGVUeXBlLlNUUklORyxcbiAgICAgIH0sXG4gICAgICBwcm9qZWN0aW9uVHlwZTogUHJvamVjdGlvblR5cGUuQUxMLFxuICAgICAgcmVhZENhcGFjaXR5OiBwcm9wcz8uY2F0ZWdvcnlUYWJsZUNvbmZpZz8uaW5kZXhRdWVyeUJ5UGFyZW50SWQucmVhZENhcGFjaXR5ID8/IDEsXG4gICAgICB3cml0ZUNhcGFjaXR5OiBwcm9wcz8uY2F0ZWdvcnlUYWJsZUNvbmZpZz8uaW5kZXhRdWVyeUJ5UGFyZW50SWQud3JpdGVDYXBhY2l0eSA/PyAxLFxuICAgIH0pO1xuICAgIHRoaXMuZmlsZVRhYmxlID0gbmV3IFRhYmxlKHRoaXMsICdGaWxlVGFibGUnLCB7XG4gICAgICBwYXJ0aXRpb25LZXk6IHtcbiAgICAgICAgbmFtZTogJ2ZpbGVJZCcsXG4gICAgICAgIHR5cGU6IEF0dHJpYnV0ZVR5cGUuU1RSSU5HLFxuICAgICAgfSxcbiAgICAgIHJlYWRDYXBhY2l0eTogcHJvcHM/LmZpbGVUYWJsZUNvbmZpZz8ucHJpbWFyeUluZGV4LnJlYWRDYXBhY2l0eSA/PyAxLFxuICAgICAgd3JpdGVDYXBhY2l0eTogcHJvcHM/LmZpbGVUYWJsZUNvbmZpZz8ucHJpbWFyeUluZGV4LndyaXRlQ2FwYWNpdHkgPz8gMSxcbiAgICB9KTtcbiAgICB0aGlzLmZpbGVUYWJsZS5hZGRHbG9iYWxTZWNvbmRhcnlJbmRleCh7XG4gICAgICBpbmRleE5hbWU6ICdxdWVyeS1ieS1jYXRlZ29yeS1pZC1hbmQtbG9jYWxlJyxcbiAgICAgIHBhcnRpdGlvbktleToge1xuICAgICAgICBuYW1lOiAnY2F0ZWdvcnlJZCcsXG4gICAgICAgIHR5cGU6IEF0dHJpYnV0ZVR5cGUuU1RSSU5HLFxuICAgICAgfSxcbiAgICAgIHNvcnRLZXk6IHtcbiAgICAgICAgbmFtZTogJ2xvY2FsZScsXG4gICAgICAgIHR5cGU6IEF0dHJpYnV0ZVR5cGUuU1RSSU5HLFxuICAgICAgfSxcbiAgICAgIHByb2plY3Rpb25UeXBlOiBQcm9qZWN0aW9uVHlwZS5BTEwsXG4gICAgICByZWFkQ2FwYWNpdHk6IHByb3BzPy5maWxlVGFibGVDb25maWc/LmluZGV4UXVlcnlCeUNhdGVnb3J5SWRBbmRMb2NhbGUucmVhZENhcGFjaXR5ID8/IDEsXG4gICAgICB3cml0ZUNhcGFjaXR5OiBwcm9wcz8uZmlsZVRhYmxlQ29uZmlnPy5pbmRleFF1ZXJ5QnlDYXRlZ29yeUlkQW5kTG9jYWxlLndyaXRlQ2FwYWNpdHkgPz8gMSxcbiAgICB9KTtcbiAgICB0aGlzLmZpbGVUYWJsZS5hZGRHbG9iYWxTZWNvbmRhcnlJbmRleCh7XG4gICAgICBpbmRleE5hbWU6ICdnZXQtZmlsZS1ieS1jaGVja3N1bS1hbmQtdmVyc2lvbicsXG4gICAgICBwYXJ0aXRpb25LZXk6IHtcbiAgICAgICAgbmFtZTogJ2NoZWNrc3VtJyxcbiAgICAgICAgdHlwZTogQXR0cmlidXRlVHlwZS5TVFJJTkcsXG4gICAgICB9LFxuICAgICAgc29ydEtleToge1xuICAgICAgICBuYW1lOiAndmVyc2lvbicsXG4gICAgICAgIHR5cGU6IEF0dHJpYnV0ZVR5cGUuU1RSSU5HLFxuICAgICAgfSxcbiAgICAgIHByb2plY3Rpb25UeXBlOiBQcm9qZWN0aW9uVHlwZS5BTEwsXG4gICAgICByZWFkQ2FwYWNpdHk6IHByb3BzPy5maWxlVGFibGVDb25maWc/LmluZGV4R2V0RmlsZUJ5Q2hlY2tzdW1BbmRWZXJzaW9uLnJlYWRDYXBhY2l0eSA/PyAxLFxuICAgICAgd3JpdGVDYXBhY2l0eTogcHJvcHM/LmZpbGVUYWJsZUNvbmZpZz8uaW5kZXhHZXRGaWxlQnlDaGVja3N1bUFuZFZlcnNpb24ud3JpdGVDYXBhY2l0eSA/PyAxLFxuICAgIH0pO1xuXG4gICAgdGhpcy5fcmVzdEFwaSA9IG5ldyBSZXN0QXBpKHRoaXMsICdGaWxlUmVzdEFwaScsIHtcbiAgICAgIGVuYWJsZUNvcnM6IHRydWUsXG4gICAgICBhdXRob3JpemF0aW9uVHlwZTogcHJvcHM/LmF1dGhvcml6YXRpb25UeXBlID8/IEF1dGhvcml6YXRpb25UeXBlLk5PTkUsXG4gICAgICBhdXRob3JpemVyOiBwcm9wcz8uYXV0aG9yaXplciA/PyB1bmRlZmluZWQsXG4gICAgICByZXNvdXJjZXM6IFtcbiAgICAgICAge1xuICAgICAgICAgIHBhdGg6ICcvY2F0ZWdvcmllcycsXG4gICAgICAgICAgaHR0cE1ldGhvZDogSHR0cE1ldGhvZC5QT1NULFxuICAgICAgICAgIGxhbWJkYUZ1bmN0aW9uOiB0aGlzLmNyZWF0ZUNyZWF0ZUNhdGVnb3J5RnVuY3Rpb24oKSxcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIHBhdGg6ICcvY2F0ZWdvcmllcycsXG4gICAgICAgICAgaHR0cE1ldGhvZDogSHR0cE1ldGhvZC5HRVQsXG4gICAgICAgICAgbGFtYmRhRnVuY3Rpb246IHRoaXMuY3JlYXRlTGlzdENhdGVnb3JpZXNGdW5jdGlvbigpLFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgcGF0aDogJy9jYXRlZ29yaWVzL3tjYXRlZ29yeUlkfScsXG4gICAgICAgICAgaHR0cE1ldGhvZDogSHR0cE1ldGhvZC5HRVQsXG4gICAgICAgICAgbGFtYmRhRnVuY3Rpb246IHRoaXMuY3JlYXRlR2V0Q2F0ZWdvcnlGdW5jdGlvbigpLFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgcGF0aDogJy9jYXRlZ29yaWVzL3tjYXRlZ29yeUlkfScsXG4gICAgICAgICAgaHR0cE1ldGhvZDogSHR0cE1ldGhvZC5QVVQsXG4gICAgICAgICAgbGFtYmRhRnVuY3Rpb246IHRoaXMuY3JlYXRlVXBkYXRlQ2F0ZWdvcnlGdW5jdGlvbigpLFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgcGF0aDogJy9jYXRlZ29yaWVzL3tjYXRlZ29yeUlkfScsXG4gICAgICAgICAgaHR0cE1ldGhvZDogSHR0cE1ldGhvZC5ERUxFVEUsXG4gICAgICAgICAgbGFtYmRhRnVuY3Rpb246IHRoaXMuY3JlYXRlRGVsZXRlQ2F0ZWdvcnlGdW5jdGlvbigpLFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgcGF0aDogJy9jYXRlZ29yaWVzL3tjYXRlZ29yeUlkfS9maWxlcycsXG4gICAgICAgICAgaHR0cE1ldGhvZDogSHR0cE1ldGhvZC5HRVQsXG4gICAgICAgICAgbGFtYmRhRnVuY3Rpb246IHRoaXMuY3JlYXRlTGlzdEZpbGVzQnlDYXRlZ29yeUZ1bmN0aW9uKCksXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICBwYXRoOiAnL2ZpbGVzJyxcbiAgICAgICAgICBodHRwTWV0aG9kOiBIdHRwTWV0aG9kLkdFVCxcbiAgICAgICAgICBsYW1iZGFGdW5jdGlvbjogdGhpcy5jcmVhdGVMaXN0RmlsZXNGdW5jdGlvbigpLFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgcGF0aDogJy9maWxlcycsXG4gICAgICAgICAgaHR0cE1ldGhvZDogSHR0cE1ldGhvZC5QT1NULFxuICAgICAgICAgIGxhbWJkYUZ1bmN0aW9uOiB0aGlzLmNyZWF0ZUNyZWF0ZUZpbGVzRnVuY3Rpb24oKSxcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIHBhdGg6ICcvZmlsZXMnLFxuICAgICAgICAgIGh0dHBNZXRob2Q6IEh0dHBNZXRob2QuUFVULFxuICAgICAgICAgIGxhbWJkYUZ1bmN0aW9uOiB0aGlzLmNyZWF0ZVVwZGF0ZUZpbGVzRnVuY3Rpb24oKSxcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIHBhdGg6ICcvZmlsZXMnLFxuICAgICAgICAgIGh0dHBNZXRob2Q6IEh0dHBNZXRob2QuREVMRVRFLFxuICAgICAgICAgIGxhbWJkYUZ1bmN0aW9uOiB0aGlzLmNyZWF0ZURlbGV0ZUZpbGVzRnVuY3Rpb24oKSxcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIHBhdGg6ICcvZmlsZXMve2NoZWNrc3VtfS92ZXJzaW9ucy97dmVyc2lvbn0nLFxuICAgICAgICAgIGh0dHBNZXRob2Q6IEh0dHBNZXRob2QuR0VULFxuICAgICAgICAgIGxhbWJkYUZ1bmN0aW9uOiB0aGlzLmNyZWF0ZUdldEZpbGVzRnVuY3Rpb24oKSxcbiAgICAgICAgfSxcbiAgICAgIF0sXG4gICAgfSk7XG4gIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgZ2V0IHJlc3RBcGlJZCgpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLl9yZXN0QXBpLnJlc3RBcGlJZDtcbiAgfVxuXG4gIHByaXZhdGUgY3JlYXRlQ3JlYXRlQ2F0ZWdvcnlGdW5jdGlvbigpOiBOb2RlanNGdW5jdGlvbiB7XG4gICAgY29uc3QgY3JlYXRlQ2F0ZWdvcnlGdW5jdGlvbiA9IG5ldyBOb2RlanNGdW5jdGlvbih0aGlzLCAnQ3JlYXRlQ2F0ZWdvcnlGdW5jdGlvbicsIHtcbiAgICAgIGVudHJ5OiBgJHtMQU1CREFfQVNTRVRTX1BBVEh9L2NyZWF0ZS1jYXRlZ29yeS9hcHAudHNgLFxuICAgICAgZW52aXJvbm1lbnQ6IHtcbiAgICAgICAgQ0FURUdPUllfVEFCTEVfTkFNRTogdGhpcy5jYXRlZ29yeVRhYmxlLnRhYmxlTmFtZSxcbiAgICAgIH0sXG4gICAgfSk7XG4gICAgY3JlYXRlQ2F0ZWdvcnlGdW5jdGlvbi5yb2xlPy5hdHRhY2hJbmxpbmVQb2xpY3koXG4gICAgICBuZXcgUG9saWN5KHRoaXMsICdjcmVhdGUtY2F0ZWdvcnktcG9saWN5Jywge1xuICAgICAgICBzdGF0ZW1lbnRzOiBbXG4gICAgICAgICAgbmV3IFBvbGljeVN0YXRlbWVudCh7XG4gICAgICAgICAgICBhY3Rpb25zOiBbXG4gICAgICAgICAgICAgICdkeW5hbW9kYjpHZXRJdGVtJyxcbiAgICAgICAgICAgICAgJ2R5bmFtb2RiOlB1dEl0ZW0nLFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICAgIHJlc291cmNlczogW1xuICAgICAgICAgICAgICB0aGlzLmNhdGVnb3J5VGFibGUudGFibGVBcm4sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgIH0pLFxuICAgICAgICBdLFxuICAgICAgfSksXG4gICAgKTtcbiAgICByZXR1cm4gY3JlYXRlQ2F0ZWdvcnlGdW5jdGlvbjtcbiAgfVxuXG4gIHByaXZhdGUgY3JlYXRlTGlzdENhdGVnb3JpZXNGdW5jdGlvbigpOiBOb2RlanNGdW5jdGlvbiB7XG4gICAgY29uc3QgbGlzdENhdGVnb3JpZXNGdW5jdGlvbiA9IG5ldyBOb2RlanNGdW5jdGlvbih0aGlzLCAnTGlzdENhdGVnb3JpZXNGdW5jdGlvbicsIHtcbiAgICAgIGVudHJ5OiBgJHtMQU1CREFfQVNTRVRTX1BBVEh9L2xpc3QtY2F0ZWdvcmllcy9hcHAudHNgLFxuICAgICAgZW52aXJvbm1lbnQ6IHtcbiAgICAgICAgQ0FURUdPUllfVEFCTEVfTkFNRTogdGhpcy5jYXRlZ29yeVRhYmxlLnRhYmxlTmFtZSxcbiAgICAgIH0sXG4gICAgfSk7XG4gICAgbGlzdENhdGVnb3JpZXNGdW5jdGlvbi5yb2xlPy5hdHRhY2hJbmxpbmVQb2xpY3koXG4gICAgICBuZXcgUG9saWN5KHRoaXMsICdsaXN0LWNhdGVnb3JpZXMtcG9saWN5Jywge1xuICAgICAgICBzdGF0ZW1lbnRzOiBbXG4gICAgICAgICAgbmV3IFBvbGljeVN0YXRlbWVudCh7XG4gICAgICAgICAgICBhY3Rpb25zOiBbXG4gICAgICAgICAgICAgICdkeW5hbW9kYjpRdWVyeScsXG4gICAgICAgICAgICAgICdkeW5hbW9kYjpTY2FuJyxcbiAgICAgICAgICAgICAgJ2R5bmFtb2RiOkdldEl0ZW0nLFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICAgIHJlc291cmNlczogW1xuICAgICAgICAgICAgICB0aGlzLmNhdGVnb3J5VGFibGUudGFibGVBcm4sXG4gICAgICAgICAgICAgIGAke3RoaXMuY2F0ZWdvcnlUYWJsZS50YWJsZUFybn0vaW5kZXgvcXVlcnktYnktcGFyZW50LWlkYCxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgfSksXG4gICAgICAgIF0sXG4gICAgICB9KSxcbiAgICApO1xuICAgIHJldHVybiBsaXN0Q2F0ZWdvcmllc0Z1bmN0aW9uO1xuICB9XG5cbiAgcHJpdmF0ZSBjcmVhdGVHZXRDYXRlZ29yeUZ1bmN0aW9uKCk6IE5vZGVqc0Z1bmN0aW9uIHtcbiAgICBjb25zdCBnZXRDYXRlZ29yeUZ1bmN0aW9uID0gbmV3IE5vZGVqc0Z1bmN0aW9uKHRoaXMsICdHZXRDYXRlZ29yeUZ1bmN0aW9uJywge1xuICAgICAgZW50cnk6IGAke0xBTUJEQV9BU1NFVFNfUEFUSH0vZ2V0LWNhdGVnb3J5L2FwcC50c2AsXG4gICAgICBlbnZpcm9ubWVudDoge1xuICAgICAgICBDQVRFR09SWV9UQUJMRV9OQU1FOiB0aGlzLmNhdGVnb3J5VGFibGUudGFibGVOYW1lLFxuICAgICAgfSxcbiAgICB9KTtcbiAgICBnZXRDYXRlZ29yeUZ1bmN0aW9uLnJvbGU/LmF0dGFjaElubGluZVBvbGljeShcbiAgICAgIG5ldyBQb2xpY3kodGhpcywgJ2dldC1jYXRlZ29yeS1wb2xpY3knLCB7XG4gICAgICAgIHN0YXRlbWVudHM6IFtcbiAgICAgICAgICBuZXcgUG9saWN5U3RhdGVtZW50KHtcbiAgICAgICAgICAgIGFjdGlvbnM6IFtcbiAgICAgICAgICAgICAgJ2R5bmFtb2RiOkdldEl0ZW0nLFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICAgIHJlc291cmNlczogW1xuICAgICAgICAgICAgICB0aGlzLmNhdGVnb3J5VGFibGUudGFibGVBcm4sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgIH0pLFxuICAgICAgICBdLFxuICAgICAgfSksXG4gICAgKTtcbiAgICByZXR1cm4gZ2V0Q2F0ZWdvcnlGdW5jdGlvbjtcbiAgfVxuXG4gIHByaXZhdGUgY3JlYXRlVXBkYXRlQ2F0ZWdvcnlGdW5jdGlvbigpOiBOb2RlanNGdW5jdGlvbiB7XG4gICAgY29uc3QgdXBkYXRlQ2F0ZWdvcnlGdW5jdGlvbiA9IG5ldyBOb2RlanNGdW5jdGlvbih0aGlzLCAnVXBkYXRlQ2F0ZWdvcnlGdW5jdGlvbicsIHtcbiAgICAgIGVudHJ5OiBgJHtMQU1CREFfQVNTRVRTX1BBVEh9L3VwZGF0ZS1jYXRlZ29yeS9hcHAudHNgLFxuICAgICAgZW52aXJvbm1lbnQ6IHtcbiAgICAgICAgQ0FURUdPUllfVEFCTEVfTkFNRTogdGhpcy5jYXRlZ29yeVRhYmxlLnRhYmxlTmFtZSxcbiAgICAgIH0sXG4gICAgfSk7XG4gICAgdXBkYXRlQ2F0ZWdvcnlGdW5jdGlvbi5yb2xlPy5hdHRhY2hJbmxpbmVQb2xpY3koXG4gICAgICBuZXcgUG9saWN5KHRoaXMsICd1cGRhdGUtY2F0ZWdvcnktcG9saWN5Jywge1xuICAgICAgICBzdGF0ZW1lbnRzOiBbXG4gICAgICAgICAgbmV3IFBvbGljeVN0YXRlbWVudCh7XG4gICAgICAgICAgICBhY3Rpb25zOiBbXG4gICAgICAgICAgICAgICdkeW5hbW9kYjpHZXRJdGVtJyxcbiAgICAgICAgICAgICAgJ2R5bmFtb2RiOlVwZGF0ZUl0ZW0nLFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICAgIHJlc291cmNlczogW1xuICAgICAgICAgICAgICB0aGlzLmNhdGVnb3J5VGFibGUudGFibGVBcm4sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgIH0pLFxuICAgICAgICBdLFxuICAgICAgfSksXG4gICAgKTtcbiAgICByZXR1cm4gdXBkYXRlQ2F0ZWdvcnlGdW5jdGlvbjtcbiAgfVxuXG4gIHByaXZhdGUgY3JlYXRlRGVsZXRlQ2F0ZWdvcnlGdW5jdGlvbigpOiBOb2RlanNGdW5jdGlvbiB7XG4gICAgY29uc3QgZGVsZXRlQ2F0ZWdvcnlGdW5jdGlvbiA9IG5ldyBOb2RlanNGdW5jdGlvbih0aGlzLCAnRGVsZXRlQ2F0ZWdvcnlGdW5jdGlvbicsIHtcbiAgICAgIGVudHJ5OiBgJHtMQU1CREFfQVNTRVRTX1BBVEh9L2RlbGV0ZS1jYXRlZ29yeS9hcHAudHNgLFxuICAgICAgZW52aXJvbm1lbnQ6IHtcbiAgICAgICAgQ0FURUdPUllfVEFCTEVfTkFNRTogdGhpcy5jYXRlZ29yeVRhYmxlLnRhYmxlTmFtZSxcbiAgICAgIH0sXG4gICAgfSk7XG4gICAgZGVsZXRlQ2F0ZWdvcnlGdW5jdGlvbi5yb2xlPy5hdHRhY2hJbmxpbmVQb2xpY3koXG4gICAgICBuZXcgUG9saWN5KHRoaXMsICdkZWxldGUtY2F0ZWdvcnktcG9saWN5Jywge1xuICAgICAgICBzdGF0ZW1lbnRzOiBbXG4gICAgICAgICAgbmV3IFBvbGljeVN0YXRlbWVudCh7XG4gICAgICAgICAgICBhY3Rpb25zOiBbXG4gICAgICAgICAgICAgICdkeW5hbW9kYjpEZWxldGVJdGVtJyxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgICByZXNvdXJjZXM6IFtcbiAgICAgICAgICAgICAgdGhpcy5jYXRlZ29yeVRhYmxlLnRhYmxlQXJuLFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICB9KSxcbiAgICAgICAgXSxcbiAgICAgIH0pLFxuICAgICk7XG4gICAgcmV0dXJuIGRlbGV0ZUNhdGVnb3J5RnVuY3Rpb247XG4gIH1cblxuICBwcml2YXRlIGNyZWF0ZUNyZWF0ZUZpbGVzRnVuY3Rpb24oKTogTm9kZWpzRnVuY3Rpb24ge1xuICAgIGNvbnN0IGNyZWF0ZUZpbGVzRnVuY3Rpb24gPSBuZXcgTm9kZWpzRnVuY3Rpb24odGhpcywgJ0NyZWF0ZUZpbGVzRnVuY3Rpb24nLCB7XG4gICAgICBlbnRyeTogYCR7TEFNQkRBX0FTU0VUU19QQVRIfS9jcmVhdGUtZmlsZXMvYXBwLnRzYCxcbiAgICAgIGVudmlyb25tZW50OiB7XG4gICAgICAgIEZJTEVfVEFCTEVfTkFNRTogdGhpcy5maWxlVGFibGUudGFibGVOYW1lLFxuICAgICAgICBDQVRFR09SWV9UQUJMRV9OQU1FOiB0aGlzLmNhdGVnb3J5VGFibGUudGFibGVOYW1lLFxuICAgICAgfSxcbiAgICB9KTtcbiAgICBjcmVhdGVGaWxlc0Z1bmN0aW9uLnJvbGU/LmF0dGFjaElubGluZVBvbGljeShcbiAgICAgIG5ldyBQb2xpY3kodGhpcywgJ2NyZWF0ZS1maWxlLXBvbGljeScsIHtcbiAgICAgICAgc3RhdGVtZW50czogW1xuICAgICAgICAgIG5ldyBQb2xpY3lTdGF0ZW1lbnQoe1xuICAgICAgICAgICAgYWN0aW9uczogW1xuICAgICAgICAgICAgICAnZHluYW1vZGI6R2V0SXRlbScsXG4gICAgICAgICAgICAgICdkeW5hbW9kYjpRdWVyeScsXG4gICAgICAgICAgICAgICdkeW5hbW9kYjpCYXRjaFdyaXRlSXRlbScsXG4gICAgICAgICAgICBdLFxuICAgICAgICAgICAgcmVzb3VyY2VzOiBbXG4gICAgICAgICAgICAgIHRoaXMuZmlsZVRhYmxlLnRhYmxlQXJuLFxuICAgICAgICAgICAgICBgJHt0aGlzLmZpbGVUYWJsZS50YWJsZUFybn0vaW5kZXgvZ2V0LWZpbGUtYnktY2hlY2tzdW0tYW5kLXZlcnNpb25gLFxuICAgICAgICAgICAgICB0aGlzLmNhdGVnb3J5VGFibGUudGFibGVBcm4sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgIH0pLFxuICAgICAgICBdLFxuICAgICAgfSksXG4gICAgKTtcbiAgICByZXR1cm4gY3JlYXRlRmlsZXNGdW5jdGlvbjtcbiAgfVxuXG4gIHByaXZhdGUgY3JlYXRlTGlzdEZpbGVzRnVuY3Rpb24oKTogTm9kZWpzRnVuY3Rpb24ge1xuICAgIGNvbnN0IGxpc3RGaWxlc0Z1bmN0aW9uID0gbmV3IE5vZGVqc0Z1bmN0aW9uKHRoaXMsICdMaXN0RmlsZXNGdW5jdGlvbicsIHtcbiAgICAgIGVudHJ5OiBgJHtMQU1CREFfQVNTRVRTX1BBVEh9L2xpc3QtZmlsZXMvYXBwLnRzYCxcbiAgICAgIGVudmlyb25tZW50OiB7XG4gICAgICAgIEZJTEVfVEFCTEVfTkFNRTogdGhpcy5maWxlVGFibGUudGFibGVOYW1lLFxuICAgICAgfSxcbiAgICB9KTtcbiAgICBsaXN0RmlsZXNGdW5jdGlvbi5yb2xlPy5hdHRhY2hJbmxpbmVQb2xpY3koXG4gICAgICBuZXcgUG9saWN5KHRoaXMsICdsaXN0LWZpbGVzLXBvbGljeScsIHtcbiAgICAgICAgc3RhdGVtZW50czogW1xuICAgICAgICAgIG5ldyBQb2xpY3lTdGF0ZW1lbnQoe1xuICAgICAgICAgICAgYWN0aW9uczogW1xuICAgICAgICAgICAgICAnZHluYW1vZGI6U2NhbicsXG4gICAgICAgICAgICBdLFxuICAgICAgICAgICAgcmVzb3VyY2VzOiBbXG4gICAgICAgICAgICAgIHRoaXMuZmlsZVRhYmxlLnRhYmxlQXJuLFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICB9KSxcbiAgICAgICAgXSxcbiAgICAgIH0pLFxuICAgICk7XG4gICAgcmV0dXJuIGxpc3RGaWxlc0Z1bmN0aW9uO1xuICB9XG5cbiAgcHJpdmF0ZSBjcmVhdGVMaXN0RmlsZXNCeUNhdGVnb3J5RnVuY3Rpb24oKTogTm9kZWpzRnVuY3Rpb24ge1xuICAgIGNvbnN0IGxpc3RGaWxlc0J5Q2F0ZWdvcnlGdW5jdGlvbiA9IG5ldyBOb2RlanNGdW5jdGlvbih0aGlzLCAnTGlzdEZpbGVzQnlDYXRlZ29yeUZ1bmN0aW9uJywge1xuICAgICAgZW50cnk6IGAke0xBTUJEQV9BU1NFVFNfUEFUSH0vbGlzdC1maWxlcy1ieS1jYXRlZ29yeS9hcHAudHNgLFxuICAgICAgZW52aXJvbm1lbnQ6IHtcbiAgICAgICAgRklMRV9UQUJMRV9OQU1FOiB0aGlzLmZpbGVUYWJsZS50YWJsZU5hbWUsXG4gICAgICB9LFxuICAgIH0pO1xuICAgIGxpc3RGaWxlc0J5Q2F0ZWdvcnlGdW5jdGlvbi5yb2xlPy5hdHRhY2hJbmxpbmVQb2xpY3koXG4gICAgICBuZXcgUG9saWN5KHRoaXMsICdsaXN0LWZpbGVzLWJ5LWNhdGVnb3J5LXBvbGljeScsIHtcbiAgICAgICAgc3RhdGVtZW50czogW1xuICAgICAgICAgIG5ldyBQb2xpY3lTdGF0ZW1lbnQoe1xuICAgICAgICAgICAgYWN0aW9uczogW1xuICAgICAgICAgICAgICAnZHluYW1vZGI6UXVlcnknLFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICAgIHJlc291cmNlczogW1xuICAgICAgICAgICAgICB0aGlzLmZpbGVUYWJsZS50YWJsZUFybixcbiAgICAgICAgICAgICAgYCR7dGhpcy5maWxlVGFibGUudGFibGVBcm59L2luZGV4L3F1ZXJ5LWJ5LWNhdGVnb3J5LWlkLWFuZC1sb2NhbGVgLFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICB9KSxcbiAgICAgICAgXSxcbiAgICAgIH0pLFxuICAgICk7XG4gICAgcmV0dXJuIGxpc3RGaWxlc0J5Q2F0ZWdvcnlGdW5jdGlvbjtcbiAgfVxuXG4gIHByaXZhdGUgY3JlYXRlR2V0RmlsZXNGdW5jdGlvbigpOiBOb2RlanNGdW5jdGlvbiB7XG4gICAgY29uc3QgZ2V0RmlsZXNGdW5jdGlvbiA9IG5ldyBOb2RlanNGdW5jdGlvbih0aGlzLCAnR2V0RmlsZXNGdW5jdGlvbicsIHtcbiAgICAgIGVudHJ5OiBgJHtMQU1CREFfQVNTRVRTX1BBVEh9L2dldC1maWxlcy9hcHAudHNgLFxuICAgICAgZW52aXJvbm1lbnQ6IHtcbiAgICAgICAgRklMRV9UQUJMRV9OQU1FOiB0aGlzLmZpbGVUYWJsZS50YWJsZU5hbWUsXG4gICAgICB9LFxuICAgIH0pO1xuICAgIGdldEZpbGVzRnVuY3Rpb24ucm9sZT8uYXR0YWNoSW5saW5lUG9saWN5KFxuICAgICAgbmV3IFBvbGljeSh0aGlzLCAnZ2V0LWZpbGVzLXBvbGljeScsIHtcbiAgICAgICAgc3RhdGVtZW50czogW1xuICAgICAgICAgIG5ldyBQb2xpY3lTdGF0ZW1lbnQoe1xuICAgICAgICAgICAgYWN0aW9uczogW1xuICAgICAgICAgICAgICAnZHluYW1vZGI6UXVlcnknLFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICAgIHJlc291cmNlczogW1xuICAgICAgICAgICAgICB0aGlzLmZpbGVUYWJsZS50YWJsZUFybixcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgfSksXG4gICAgICAgIF0sXG4gICAgICB9KSxcbiAgICApO1xuICAgIHJldHVybiBnZXRGaWxlc0Z1bmN0aW9uO1xuICB9XG5cbiAgcHJpdmF0ZSBjcmVhdGVVcGRhdGVGaWxlc0Z1bmN0aW9uKCk6IE5vZGVqc0Z1bmN0aW9uIHtcbiAgICBjb25zdCB1cGRhdGVGaWxlc0Z1bmN0aW9uID0gbmV3IE5vZGVqc0Z1bmN0aW9uKHRoaXMsICdVcGRhdGVGaWxlc0Z1bmN0aW9uJywge1xuICAgICAgZW50cnk6IGAke0xBTUJEQV9BU1NFVFNfUEFUSH0vdXBkYXRlLWZpbGVzL2FwcC50c2AsXG4gICAgICBlbnZpcm9ubWVudDoge1xuICAgICAgICBGSUxFX1RBQkxFX05BTUU6IHRoaXMuZmlsZVRhYmxlLnRhYmxlTmFtZSxcbiAgICAgIH0sXG4gICAgfSk7XG4gICAgdXBkYXRlRmlsZXNGdW5jdGlvbi5yb2xlPy5hdHRhY2hJbmxpbmVQb2xpY3koXG4gICAgICBuZXcgUG9saWN5KHRoaXMsICd1cGRhdGUtZmlsZS1wb2xpY3knLCB7XG4gICAgICAgIHN0YXRlbWVudHM6IFtcbiAgICAgICAgICBuZXcgUG9saWN5U3RhdGVtZW50KHtcbiAgICAgICAgICAgIGFjdGlvbnM6IFtcbiAgICAgICAgICAgICAgJ2R5bmFtb2RiOkJhdGNoV3JpdGVJdGVtJyxcbiAgICAgICAgICAgICAgJ2R5bmFtb2RiOkJhdGNoR2V0SXRlbScsXG4gICAgICAgICAgICBdLFxuICAgICAgI