UNPKG

@aws-cdk/integ-tests-alpha

Version:

CDK Integration Testing Constructs

252 lines 28.4 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.AssertionsProvider = void 0; const jsiiDeprecationWarnings = require("../../../.warnings.jsii.js"); const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti"); const path = require("path"); const core_1 = require("aws-cdk-lib/core"); const constructs_1 = require("constructs"); const helpers_internal_1 = require("aws-cdk-lib/custom-resources/lib/helpers-internal"); /** * integ-tests can only depend on '@aws-cdk/core' so * this construct creates a lambda function provider using * only CfnResource */ class LambdaFunctionProvider extends constructs_1.Construct { /** * The ARN of the lambda function which can be used * as a serviceToken to a CustomResource */ serviceToken; /** * A Reference to the provider lambda exeuction role ARN */ roleArn; policies = []; constructor(scope, id, props) { super(scope, id); const staging = new core_1.AssetStaging(this, 'Staging', { sourcePath: path.join(__dirname, 'lambda-handler.bundle'), }); const stack = core_1.Stack.of(this); const asset = stack.synthesizer.addFileAsset({ fileName: staging.relativeStagedPath(stack), sourceHash: staging.assetHash, packaging: core_1.FileAssetPackaging.ZIP_DIRECTORY, }); const role = new core_1.CfnResource(this, 'Role', { type: 'AWS::IAM::Role', properties: { AssumeRolePolicyDocument: { Version: '2012-10-17', Statement: [{ Action: 'sts:AssumeRole', Effect: 'Allow', Principal: { Service: 'lambda.amazonaws.com' } }], }, ManagedPolicyArns: [ { 'Fn::Sub': 'arn:${AWS::Partition}:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole' }, ], Policies: core_1.Lazy.any({ produce: () => { const policies = this.policies.length > 0 ? [ { PolicyName: 'Inline', PolicyDocument: { Version: '2012-10-17', Statement: this.policies, }, }, ] : undefined; return policies; }, }), }, }); const functionProperties = { Runtime: (0, core_1.determineLatestNodeRuntimeName)(this), Code: { S3Bucket: asset.bucketName, S3Key: asset.objectKey, }, Timeout: core_1.Duration.minutes(2).toSeconds(), Handler: props?.handler ?? 'index.handler', Role: role.getAtt('Arn'), }; if (props?.logRetention) { const logGroup = new core_1.CfnResource(this, 'LogGroup', { type: 'AWS::Logs::LogGroup', properties: { LogGroupName: `/aws/lambda/${id}`, RetentionInDays: props.logRetention, }, }); functionProperties.LoggingConfig = { LogGroup: logGroup.ref, }; } const handler = new core_1.CfnResource(this, 'Handler', { type: 'AWS::Lambda::Function', properties: functionProperties, }); this.serviceToken = core_1.Token.asString(handler.getAtt('Arn')); this.roleArn = role.getAtt('Arn'); } addPolicies(policies) { this.policies.push(...policies); } } /** * Mimic the singletonfunction construct in '@aws-cdk/aws-lambda' */ class SingletonFunction extends constructs_1.Construct { serviceToken; lambdaFunction; constructor(scope, id, props) { super(scope, id); this.lambdaFunction = this.ensureFunction(props); this.serviceToken = this.lambdaFunction.serviceToken; } ensureFunction(props) { const constructName = 'SingletonFunction' + slugify(props.uuid); const existing = core_1.Stack.of(this).node.tryFindChild(constructName); if (existing) { return existing; } return new LambdaFunctionProvider(core_1.Stack.of(this), constructName, { handler: props.handler, logRetention: props.logRetention, }); } /** * Add an IAM policy statement to the inline policy of the * lambdas function's role * * **Please note**: this is a direct IAM JSON policy blob, *not* a `iam.PolicyStatement` * object like you will see in the rest of the CDK. * * * singleton.addToRolePolicy({ * Effect: 'Allow', * Action: 's3:GetObject', * Resources: '*', * }); */ addToRolePolicy(statement) { this.lambdaFunction.addPolicies([statement]); } /** * Create a policy statement from a specific api call */ addPolicyStatementFromSdkCall(service, api, resources) { this.lambdaFunction.addPolicies([{ Action: [(0, helpers_internal_1.awsSdkToIamAction)(service, api)], Effect: 'Allow', Resource: resources || ['*'], }]); } } /** * Represents an assertions provider. The creates a singletone * Lambda Function that will create a single function per stack * that serves as the custom resource provider for the various * assertion providers */ class AssertionsProvider extends constructs_1.Construct { static [JSII_RTTI_SYMBOL_1] = { fqn: "@aws-cdk/integ-tests-alpha.AssertionsProvider", version: "2.231.0-alpha.0" }; /** * The ARN of the lambda function which can be used * as a serviceToken to a CustomResource */ serviceToken; /** * A reference to the provider Lambda Function * execution Role ARN */ handlerRoleArn; handler; constructor(scope, id, props) { super(scope, id); try { jsiiDeprecationWarnings._aws_cdk_integ_tests_alpha_AssertionsProviderProps(props); } catch (error) { if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") { Error.captureStackTrace(error, AssertionsProvider); } throw error; } this.handler = new SingletonFunction(this, 'AssertionsProvider', { handler: props?.handler, uuid: props?.uuid ?? '1488541a-7b23-4664-81b6-9b4408076b81', logRetention: props?.logRetention, }); this.handlerRoleArn = this.handler.lambdaFunction.roleArn; this.serviceToken = this.handler.serviceToken; } /** * Encode an object so it can be passed * as custom resource parameters. Custom resources will convert * all input parameters to strings so we encode non-strings here * so we can then decode them correctly in the provider function */ encode(obj) { if (!obj) { return obj; } return Object.fromEntries(Object.entries(obj).map(([key, value]) => [key, encodeValue(value)])); function encodeValue(value) { if (ArrayBuffer.isView(value)) { return { $type: 'ArrayBufferView', string: new TextDecoder().decode(value), }; } return JSON.stringify(value); } } /** * Create a policy statement from a specific api call */ addPolicyStatementFromSdkCall(service, api, resources) { this.handler.addPolicyStatementFromSdkCall(service, api, resources); } /** * Add an IAM policy statement to the inline policy of the * lambdas function's role * * **Please note**: this is a direct IAM JSON policy blob, *not* a `iam.PolicyStatement` * object like you will see in the rest of the CDK. * * * @example * declare const provider: AssertionsProvider; * provider.addToRolePolicy({ * Effect: 'Allow', * Action: ['s3:GetObject'], * Resource: ['*'], * }); */ addToRolePolicy(statement) { this.handler.addToRolePolicy(statement); } /** * Grant a principal access to invoke the assertion provider * lambda function * * @param principalArn the ARN of the principal that should be given * permission to invoke the assertion provider */ grantInvoke(principalArn) { new core_1.CfnResource(this, 'Invoke', { type: 'AWS::Lambda::Permission', properties: { Action: 'lambda:InvokeFunction', FunctionName: this.serviceToken, Principal: principalArn, }, }); } } exports.AssertionsProvider = AssertionsProvider; function slugify(x) { return x.replace(/[^a-zA-Z0-9]/g, ''); } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvdmlkZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJwcm92aWRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLDZCQUE2QjtBQUM3QiwyQ0FVMEI7QUFDMUIsMkNBQXVDO0FBQ3ZDLHdGQUFzRjtBQXNCdEY7Ozs7R0FJRztBQUNILE1BQU0sc0JBQXVCLFNBQVEsc0JBQVM7SUFDNUM7OztPQUdHO0lBQ2EsWUFBWSxDQUFTO0lBRXJDOztPQUVHO0lBQ2EsT0FBTyxDQUFZO0lBRWxCLFFBQVEsR0FBVSxFQUFFLENBQUM7SUFFdEMsWUFBWSxLQUFnQixFQUFFLEVBQVUsRUFBRSxLQUFtQztRQUMzRSxLQUFLLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBRWpCLE1BQU0sT0FBTyxHQUFHLElBQUksbUJBQVksQ0FBQyxJQUFJLEVBQUUsU0FBUyxFQUFFO1lBQ2hELFVBQVUsRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRSx1QkFBdUIsQ0FBQztTQUMxRCxDQUFDLENBQUM7UUFFSCxNQUFNLEtBQUssR0FBRyxZQUFLLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQzdCLE1BQU0sS0FBSyxHQUFHLEtBQUssQ0FBQyxXQUFXLENBQUMsWUFBWSxDQUFDO1lBQzNDLFFBQVEsRUFBRSxPQUFPLENBQUMsa0JBQWtCLENBQUMsS0FBSyxDQUFDO1lBQzNDLFVBQVUsRUFBRSxPQUFPLENBQUMsU0FBUztZQUM3QixTQUFTLEVBQUUseUJBQWtCLENBQUMsYUFBYTtTQUM1QyxDQUFDLENBQUM7UUFFSCxNQUFNLElBQUksR0FBRyxJQUFJLGtCQUFXLENBQUMsSUFBSSxFQUFFLE1BQU0sRUFBRTtZQUN6QyxJQUFJLEVBQUUsZ0JBQWdCO1lBQ3RCLFVBQVUsRUFBRTtnQkFDVix3QkFBd0IsRUFBRTtvQkFDeEIsT0FBTyxFQUFFLFlBQVk7b0JBQ3JCLFNBQVMsRUFBRSxDQUFDLEVBQUUsTUFBTSxFQUFFLGdCQUFnQixFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUUsU0FBUyxFQUFFLEVBQUUsT0FBTyxFQUFFLHNCQUFzQixFQUFFLEVBQUUsQ0FBQztpQkFDM0c7Z0JBQ0QsaUJBQWlCLEVBQUU7b0JBQ2pCLEVBQUUsU0FBUyxFQUFFLGdGQUFnRixFQUFFO2lCQUNoRztnQkFDRCxRQUFRLEVBQUUsV0FBSSxDQUFDLEdBQUcsQ0FBQztvQkFDakIsT0FBTyxFQUFFLEdBQUcsRUFBRTt3QkFDWixNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDOzRCQUMxQztnQ0FDRSxVQUFVLEVBQUUsUUFBUTtnQ0FDcEIsY0FBYyxFQUFFO29DQUNkLE9BQU8sRUFBRSxZQUFZO29DQUNyQixTQUFTLEVBQUUsSUFBSSxDQUFDLFFBQVE7aUNBQ3pCOzZCQUNGO3lCQUNGLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQzt3QkFDZCxPQUFPLFFBQVEsQ0FBQztvQkFDbEIsQ0FBQztpQkFDRixDQUFDO2FBQ0g7U0FDRixDQUFDLENBQUM7UUFFSCxNQUFNLGtCQUFrQixHQUFRO1lBQzlCLE9BQU8sRUFBRSxJQUFBLHFDQUE4QixFQUFDLElBQUksQ0FBQztZQUM3QyxJQUFJLEVBQUU7Z0JBQ0osUUFBUSxFQUFFLEtBQUssQ0FBQyxVQUFVO2dCQUMxQixLQUFLLEVBQUUsS0FBSyxDQUFDLFNBQVM7YUFDdkI7WUFDRCxPQUFPLEVBQUUsZUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLEVBQUU7WUFDeEMsT0FBTyxFQUFFLEtBQUssRUFBRSxPQUFPLElBQUksZUFBZTtZQUMxQyxJQUFJLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUM7U0FDekIsQ0FBQztRQUVGLElBQUksS0FBSyxFQUFFLFlBQVksRUFBRSxDQUFDO1lBQ3hCLE1BQU0sUUFBUSxHQUFHLElBQUksa0JBQVcsQ0FBQyxJQUFJLEVBQUUsVUFBVSxFQUFFO2dCQUNqRCxJQUFJLEVBQUUscUJBQXFCO2dCQUMzQixVQUFVLEVBQUU7b0JBQ1YsWUFBWSxFQUFFLGVBQWUsRUFBRSxFQUFFO29CQUNqQyxlQUFlLEVBQUUsS0FBSyxDQUFDLFlBQVk7aUJBQ3BDO2FBQ0YsQ0FBQyxDQUFDO1lBRUgsa0JBQWtCLENBQUMsYUFBYSxHQUFHO2dCQUNqQyxRQUFRLEVBQUUsUUFBUSxDQUFDLEdBQUc7YUFDdkIsQ0FBQztRQUNKLENBQUM7UUFFRCxNQUFNLE9BQU8sR0FBRyxJQUFJLGtCQUFXLENBQUMsSUFBSSxFQUFFLFNBQVMsRUFBRTtZQUMvQyxJQUFJLEVBQUUsdUJBQXVCO1lBQzdCLFVBQVUsRUFBRSxrQkFBa0I7U0FDL0IsQ0FBQyxDQUFDO1FBRUgsSUFBSSxDQUFDLFlBQVksR0FBRyxZQUFLLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztRQUMxRCxJQUFJLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7S0FDbkM7SUFFTSxXQUFXLENBQUMsUUFBZTtRQUNoQyxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxHQUFHLFFBQVEsQ0FBQyxDQUFDO0tBQ2pDO0NBQ0Y7QUFZRDs7R0FFRztBQUNILE1BQU0saUJBQWtCLFNBQVEsc0JBQVM7SUFDdkIsWUFBWSxDQUFTO0lBRXJCLGNBQWMsQ0FBeUI7SUFDdkQsWUFBWSxLQUFnQixFQUFFLEVBQVUsRUFBRSxLQUE2QjtRQUNyRSxLQUFLLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBQ2pCLElBQUksQ0FBQyxjQUFjLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUNqRCxJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQyxjQUFjLENBQUMsWUFBWSxDQUFDO0tBQ3REO0lBRU8sY0FBYyxDQUFDLEtBQTZCO1FBQ2xELE1BQU0sYUFBYSxHQUFHLG1CQUFtQixHQUFHLE9BQU8sQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDaEUsTUFBTSxRQUFRLEdBQUcsWUFBSyxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLGFBQWEsQ0FBQyxDQUFDO1FBQ2pFLElBQUksUUFBUSxFQUFFLENBQUM7WUFDYixPQUFPLFFBQWtDLENBQUM7UUFDNUMsQ0FBQztRQUVELE9BQU8sSUFBSSxzQkFBc0IsQ0FBQyxZQUFLLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxFQUFFLGFBQWEsRUFBRTtZQUMvRCxPQUFPLEVBQUUsS0FBSyxDQUFDLE9BQU87WUFDdEIsWUFBWSxFQUFFLEtBQUssQ0FBQyxZQUFZO1NBQ2pDLENBQUMsQ0FBQztLQUNKO0lBRUQ7Ozs7Ozs7Ozs7Ozs7T0FhRztJQUNJLGVBQWUsQ0FBQyxTQUFjO1FBQ25DLElBQUksQ0FBQyxjQUFjLENBQUMsV0FBVyxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQztLQUM5QztJQUVEOztPQUVHO0lBQ0ksNkJBQTZCLENBQUMsT0FBZSxFQUFFLEdBQVcsRUFBRSxTQUFvQjtRQUNyRixJQUFJLENBQUMsY0FBYyxDQUFDLFdBQVcsQ0FBQyxDQUFDO2dCQUMvQixNQUFNLEVBQUUsQ0FBQyxJQUFBLG9DQUFpQixFQUFDLE9BQU8sRUFBRSxHQUFHLENBQUMsQ0FBQztnQkFDekMsTUFBTSxFQUFFLE9BQU87Z0JBQ2YsUUFBUSxFQUFFLFNBQVMsSUFBSSxDQUFDLEdBQUcsQ0FBQzthQUM3QixDQUFDLENBQUMsQ0FBQztLQUNMO0NBQ0Y7QUFnQkQ7Ozs7O0dBS0c7QUFDSCxNQUFhLGtCQUFtQixTQUFRLHNCQUFTOztJQUMvQzs7O09BR0c7SUFDYSxZQUFZLENBQVM7SUFDckM7OztPQUdHO0lBQ2EsY0FBYyxDQUFZO0lBRXpCLE9BQU8sQ0FBb0I7SUFFNUMsWUFBWSxLQUFnQixFQUFFLEVBQVUsRUFBRSxLQUErQjtRQUN2RSxLQUFLLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFDOzs7Ozs7K0NBZlIsa0JBQWtCOzs7O1FBaUIzQixJQUFJLENBQUMsT0FBTyxHQUFHLElBQUksaUJBQWlCLENBQUMsSUFBSSxFQUFFLG9CQUFvQixFQUFFO1lBQy9ELE9BQU8sRUFBRSxLQUFLLEVBQUUsT0FBTztZQUN2QixJQUFJLEVBQUUsS0FBSyxFQUFFLElBQUksSUFBSSxzQ0FBc0M7WUFDM0QsWUFBWSxFQUFFLEtBQUssRUFBRSxZQUFZO1NBQ2xDLENBQUMsQ0FBQztRQUVILElBQUksQ0FBQyxjQUFjLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxjQUFjLENBQUMsT0FBTyxDQUFDO1FBRTFELElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUM7S0FDL0M7SUFFRDs7Ozs7T0FLRztJQUNJLE1BQU0sQ0FBQyxHQUFRO1FBQ3BCLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQztZQUNULE9BQU8sR0FBRyxDQUFDO1FBQ2IsQ0FBQztRQUNELE9BQU8sTUFBTSxDQUFDLFdBQVcsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLEdBQUcsRUFBRSxXQUFXLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFFaEcsU0FBUyxXQUFXLENBQUMsS0FBVTtZQUM3QixJQUFJLFdBQVcsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQztnQkFDOUIsT0FBTztvQkFDTCxLQUFLLEVBQUUsaUJBQWlCO29CQUN4QixNQUFNLEVBQUUsSUFBSSxXQUFXLEVBQUUsQ0FBQyxNQUFNLENBQUMsS0FBbUIsQ0FBQztpQkFDdEQsQ0FBQztZQUNKLENBQUM7WUFFRCxPQUFPLElBQUksQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDL0IsQ0FBQztLQUNGO0lBRUQ7O09BRUc7SUFDSSw2QkFBNkIsQ0FBQyxPQUFlLEVBQUUsR0FBVyxFQUFFLFNBQW9CO1FBQ3JGLElBQUksQ0FBQyxPQUFPLENBQUMsNkJBQTZCLENBQUMsT0FBTyxFQUFFLEdBQUcsRUFBRSxTQUFTLENBQUMsQ0FBQztLQUNyRTtJQUVEOzs7Ozs7Ozs7Ozs7Ozs7T0FlRztJQUNJLGVBQWUsQ0FBQyxTQUFjO1FBQ25DLElBQUksQ0FBQyxPQUFPLENBQUMsZUFBZSxDQUFDLFNBQVMsQ0FBQyxDQUFDO0tBQ3pDO0lBRUQ7Ozs7OztPQU1HO0lBQ0ksV0FBVyxDQUFDLFlBQW9CO1FBQ3JDLElBQUksa0JBQVcsQ0FBQyxJQUFJLEVBQUUsUUFBUSxFQUFFO1lBQzlCLElBQUksRUFBRSx5QkFBeUI7WUFDL0IsVUFBVSxFQUFFO2dCQUNWLE1BQU0sRUFBRSx1QkFBdUI7Z0JBQy9CLFlBQVksRUFBRSxJQUFJLENBQUMsWUFBWTtnQkFDL0IsU0FBUyxFQUFFLFlBQVk7YUFDeEI7U0FDRixDQUFDLENBQUM7S0FDSjs7QUEvRkgsZ0RBZ0dDO0FBRUQsU0FBUyxPQUFPLENBQUMsQ0FBUztJQUN4QixPQUFPLENBQUMsQ0FBQyxPQUFPLENBQUMsZUFBZSxFQUFFLEVBQUUsQ0FBQyxDQUFDO0FBQ3hDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBwYXRoIGZyb20gJ3BhdGgnO1xuaW1wb3J0IHtcbiAgRHVyYXRpb24sXG4gIENmblJlc291cmNlLFxuICBBc3NldFN0YWdpbmcsXG4gIFN0YWNrLFxuICBGaWxlQXNzZXRQYWNrYWdpbmcsXG4gIFRva2VuLFxuICBMYXp5LFxuICBSZWZlcmVuY2UsXG4gIGRldGVybWluZUxhdGVzdE5vZGVSdW50aW1lTmFtZSxcbn0gZnJvbSAnYXdzLWNkay1saWIvY29yZSc7XG5pbXBvcnQgeyBDb25zdHJ1Y3QgfSBmcm9tICdjb25zdHJ1Y3RzJztcbmltcG9ydCB7IGF3c1Nka1RvSWFtQWN0aW9uIH0gZnJvbSAnYXdzLWNkay1saWIvY3VzdG9tLXJlc291cmNlcy9saWIvaGVscGVycy1pbnRlcm5hbCc7XG5pbXBvcnQgeyBSZXRlbnRpb25EYXlzIH0gZnJvbSAnYXdzLWNkay1saWIvYXdzLWxvZ3MnO1xuXG4vKipcbiAqIFByb3BlcnRpZXMgZm9yIGEgbGFtYmRhIGZ1bmN0aW9uIHByb3ZpZGVyXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgTGFtYmRhRnVuY3Rpb25Qcm92aWRlclByb3BzIHtcbiAgLyoqXG4gICAqIFRoZSBoYW5kbGVyIHRvIHVzZSBmb3IgdGhlIGxhbWJkYSBmdW5jdGlvblxuICAgKlxuICAgKiBAZGVmYXVsdCBpbmRleC5oYW5kbGVyXG4gICAqL1xuICByZWFkb25seSBoYW5kbGVyPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBIb3cgbG9uZywgaW4gZGF5cywgdGhlIGxvZyBjb250ZW50cyB3aWxsIGJlIHJldGFpbmVkLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIG5vIHJldGVudGlvbiBkYXlzIHNwZWNpZmllZFxuICAgKi9cbiAgcmVhZG9ubHkgbG9nUmV0ZW50aW9uPzogUmV0ZW50aW9uRGF5cztcbn1cblxuLyoqXG4gKiBpbnRlZy10ZXN0cyBjYW4gb25seSBkZXBlbmQgb24gJ0Bhd3MtY2RrL2NvcmUnIHNvXG4gKiB0aGlzIGNvbnN0cnVjdCBjcmVhdGVzIGEgbGFtYmRhIGZ1bmN0aW9uIHByb3ZpZGVyIHVzaW5nXG4gKiBvbmx5IENmblJlc291cmNlXG4gKi9cbmNsYXNzIExhbWJkYUZ1bmN0aW9uUHJvdmlkZXIgZXh0ZW5kcyBDb25zdHJ1Y3Qge1xuICAvKipcbiAgICogVGhlIEFSTiBvZiB0aGUgbGFtYmRhIGZ1bmN0aW9uIHdoaWNoIGNhbiBiZSB1c2VkXG4gICAqIGFzIGEgc2VydmljZVRva2VuIHRvIGEgQ3VzdG9tUmVzb3VyY2VcbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBzZXJ2aWNlVG9rZW46IHN0cmluZztcblxuICAvKipcbiAgICogQSBSZWZlcmVuY2UgdG8gdGhlIHByb3ZpZGVyIGxhbWJkYSBleGV1Y3Rpb24gcm9sZSBBUk5cbiAgICovXG4gIHB1YmxpYyByZWFkb25seSByb2xlQXJuOiBSZWZlcmVuY2U7XG5cbiAgcHJpdmF0ZSByZWFkb25seSBwb2xpY2llczogYW55W10gPSBbXTtcblxuICBjb25zdHJ1Y3RvcihzY29wZTogQ29uc3RydWN0LCBpZDogc3RyaW5nLCBwcm9wcz86IExhbWJkYUZ1bmN0aW9uUHJvdmlkZXJQcm9wcykge1xuICAgIHN1cGVyKHNjb3BlLCBpZCk7XG5cbiAgICBjb25zdCBzdGFnaW5nID0gbmV3IEFzc2V0U3RhZ2luZyh0aGlzLCAnU3RhZ2luZycsIHtcbiAgICAgIHNvdXJjZVBhdGg6IHBhdGguam9pbihfX2Rpcm5hbWUsICdsYW1iZGEtaGFuZGxlci5idW5kbGUnKSxcbiAgICB9KTtcblxuICAgIGNvbnN0IHN0YWNrID0gU3RhY2sub2YodGhpcyk7XG4gICAgY29uc3QgYXNzZXQgPSBzdGFjay5zeW50aGVzaXplci5hZGRGaWxlQXNzZXQoe1xuICAgICAgZmlsZU5hbWU6IHN0YWdpbmcucmVsYXRpdmVTdGFnZWRQYXRoKHN0YWNrKSxcbiAgICAgIHNvdXJjZUhhc2g6IHN0YWdpbmcuYXNzZXRIYXNoLFxuICAgICAgcGFja2FnaW5nOiBGaWxlQXNzZXRQYWNrYWdpbmcuWklQX0RJUkVDVE9SWSxcbiAgICB9KTtcblxuICAgIGNvbnN0IHJvbGUgPSBuZXcgQ2ZuUmVzb3VyY2UodGhpcywgJ1JvbGUnLCB7XG4gICAgICB0eXBlOiAnQVdTOjpJQU06OlJvbGUnLFxuICAgICAgcHJvcGVydGllczoge1xuICAgICAgICBBc3N1bWVSb2xlUG9saWN5RG9jdW1lbnQ6IHtcbiAgICAgICAgICBWZXJzaW9uOiAnMjAxMi0xMC0xNycsXG4gICAgICAgICAgU3RhdGVtZW50OiBbeyBBY3Rpb246ICdzdHM6QXNzdW1lUm9sZScsIEVmZmVjdDogJ0FsbG93JywgUHJpbmNpcGFsOiB7IFNlcnZpY2U6ICdsYW1iZGEuYW1hem9uYXdzLmNvbScgfSB9XSxcbiAgICAgICAgfSxcbiAgICAgICAgTWFuYWdlZFBvbGljeUFybnM6IFtcbiAgICAgICAgICB7ICdGbjo6U3ViJzogJ2Fybjoke0FXUzo6UGFydGl0aW9ufTppYW06OmF3czpwb2xpY3kvc2VydmljZS1yb2xlL0FXU0xhbWJkYUJhc2ljRXhlY3V0aW9uUm9sZScgfSxcbiAgICAgICAgXSxcbiAgICAgICAgUG9saWNpZXM6IExhenkuYW55KHtcbiAgICAgICAgICBwcm9kdWNlOiAoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBwb2xpY2llcyA9IHRoaXMucG9saWNpZXMubGVuZ3RoID4gMCA/IFtcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIFBvbGljeU5hbWU6ICdJbmxpbmUnLFxuICAgICAgICAgICAgICAgIFBvbGljeURvY3VtZW50OiB7XG4gICAgICAgICAgICAgICAgICBWZXJzaW9uOiAnMjAxMi0xMC0xNycsXG4gICAgICAgICAgICAgICAgICBTdGF0ZW1lbnQ6IHRoaXMucG9saWNpZXMsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0gOiB1bmRlZmluZWQ7XG4gICAgICAgICAgICByZXR1cm4gcG9saWNpZXM7XG4gICAgICAgICAgfSxcbiAgICAgICAgfSksXG4gICAgICB9LFxuICAgIH0pO1xuXG4gICAgY29uc3QgZnVuY3Rpb25Qcm9wZXJ0aWVzOiBhbnkgPSB7XG4gICAgICBSdW50aW1lOiBkZXRlcm1pbmVMYXRlc3ROb2RlUnVudGltZU5hbWUodGhpcyksXG4gICAgICBDb2RlOiB7XG4gICAgICAgIFMzQnVja2V0OiBhc3NldC5idWNrZXROYW1lLFxuICAgICAgICBTM0tleTogYXNzZXQub2JqZWN0S2V5LFxuICAgICAgfSxcbiAgICAgIFRpbWVvdXQ6IER1cmF0aW9uLm1pbnV0ZXMoMikudG9TZWNvbmRzKCksXG4gICAgICBIYW5kbGVyOiBwcm9wcz8uaGFuZGxlciA/PyAnaW5kZXguaGFuZGxlcicsXG4gICAgICBSb2xlOiByb2xlLmdldEF0dCgnQXJuJyksXG4gICAgfTtcblxuICAgIGlmIChwcm9wcz8ubG9nUmV0ZW50aW9uKSB7XG4gICAgICBjb25zdCBsb2dHcm91cCA9IG5ldyBDZm5SZXNvdXJjZSh0aGlzLCAnTG9nR3JvdXAnLCB7XG4gICAgICAgIHR5cGU6ICdBV1M6OkxvZ3M6OkxvZ0dyb3VwJyxcbiAgICAgICAgcHJvcGVydGllczoge1xuICAgICAgICAgIExvZ0dyb3VwTmFtZTogYC9hd3MvbGFtYmRhLyR7aWR9YCxcbiAgICAgICAgICBSZXRlbnRpb25JbkRheXM6IHByb3BzLmxvZ1JldGVudGlvbixcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuXG4gICAgICBmdW5jdGlvblByb3BlcnRpZXMuTG9nZ2luZ0NvbmZpZyA9IHtcbiAgICAgICAgTG9nR3JvdXA6IGxvZ0dyb3VwLnJlZixcbiAgICAgIH07XG4gICAgfVxuXG4gICAgY29uc3QgaGFuZGxlciA9IG5ldyBDZm5SZXNvdXJjZSh0aGlzLCAnSGFuZGxlcicsIHtcbiAgICAgIHR5cGU6ICdBV1M6OkxhbWJkYTo6RnVuY3Rpb24nLFxuICAgICAgcHJvcGVydGllczogZnVuY3Rpb25Qcm9wZXJ0aWVzLFxuICAgIH0pO1xuXG4gICAgdGhpcy5zZXJ2aWNlVG9rZW4gPSBUb2tlbi5hc1N0cmluZyhoYW5kbGVyLmdldEF0dCgnQXJuJykpO1xuICAgIHRoaXMucm9sZUFybiA9IHJvbGUuZ2V0QXR0KCdBcm4nKTtcbiAgfVxuXG4gIHB1YmxpYyBhZGRQb2xpY2llcyhwb2xpY2llczogYW55W10pOiB2b2lkIHtcbiAgICB0aGlzLnBvbGljaWVzLnB1c2goLi4ucG9saWNpZXMpO1xuICB9XG59XG5cbmludGVyZmFjZSBTaW5nbGV0b25GdW5jdGlvblByb3BzIGV4dGVuZHMgTGFtYmRhRnVuY3Rpb25Qcm92aWRlclByb3BzIHtcbiAgLyoqXG4gICAqIEEgdW5pcXVlIGlkZW50aWZpZXIgdG8gaWRlbnRpZnkgdGhpcyBsYW1iZGFcbiAgICpcbiAgICogVGhlIGlkZW50aWZpZXIgc2hvdWxkIGJlIHVuaXF1ZSBhY3Jvc3MgYWxsIGN1c3RvbSByZXNvdXJjZSBwcm92aWRlcnMuXG4gICAqIFdlIHJlY29tbWVuZCBnZW5lcmF0aW5nIGEgVVVJRCBwZXIgcHJvdmlkZXIuXG4gICAqL1xuICByZWFkb25seSB1dWlkOiBzdHJpbmc7XG59XG5cbi8qKlxuICogTWltaWMgdGhlIHNpbmdsZXRvbmZ1bmN0aW9uIGNvbnN0cnVjdCBpbiAnQGF3cy1jZGsvYXdzLWxhbWJkYSdcbiAqL1xuY2xhc3MgU2luZ2xldG9uRnVuY3Rpb24gZXh0ZW5kcyBDb25zdHJ1Y3Qge1xuICBwdWJsaWMgcmVhZG9ubHkgc2VydmljZVRva2VuOiBzdHJpbmc7XG5cbiAgcHVibGljIHJlYWRvbmx5IGxhbWJkYUZ1bmN0aW9uOiBMYW1iZGFGdW5jdGlvblByb3ZpZGVyO1xuICBjb25zdHJ1Y3RvcihzY29wZTogQ29uc3RydWN0LCBpZDogc3RyaW5nLCBwcm9wczogU2luZ2xldG9uRnVuY3Rpb25Qcm9wcykge1xuICAgIHN1cGVyKHNjb3BlLCBpZCk7XG4gICAgdGhpcy5sYW1iZGFGdW5jdGlvbiA9IHRoaXMuZW5zdXJlRnVuY3Rpb24ocHJvcHMpO1xuICAgIHRoaXMuc2VydmljZVRva2VuID0gdGhpcy5sYW1iZGFGdW5jdGlvbi5zZXJ2aWNlVG9rZW47XG4gIH1cblxuICBwcml2YXRlIGVuc3VyZUZ1bmN0aW9uKHByb3BzOiBTaW5nbGV0b25GdW5jdGlvblByb3BzKTogTGFtYmRhRnVuY3Rpb25Qcm92aWRlciB7XG4gICAgY29uc3QgY29uc3RydWN0TmFtZSA9ICdTaW5nbGV0b25GdW5jdGlvbicgKyBzbHVnaWZ5KHByb3BzLnV1aWQpO1xuICAgIGNvbnN0IGV4aXN0aW5nID0gU3RhY2sub2YodGhpcykubm9kZS50cnlGaW5kQ2hpbGQoY29uc3RydWN0TmFtZSk7XG4gICAgaWYgKGV4aXN0aW5nKSB7XG4gICAgICByZXR1cm4gZXhpc3RpbmcgYXMgTGFtYmRhRnVuY3Rpb25Qcm92aWRlcjtcbiAgICB9XG5cbiAgICByZXR1cm4gbmV3IExhbWJkYUZ1bmN0aW9uUHJvdmlkZXIoU3RhY2sub2YodGhpcyksIGNvbnN0cnVjdE5hbWUsIHtcbiAgICAgIGhhbmRsZXI6IHByb3BzLmhhbmRsZXIsXG4gICAgICBsb2dSZXRlbnRpb246IHByb3BzLmxvZ1JldGVudGlvbixcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBZGQgYW4gSUFNIHBvbGljeSBzdGF0ZW1lbnQgdG8gdGhlIGlubGluZSBwb2xpY3kgb2YgdGhlXG4gICAqIGxhbWJkYXMgZnVuY3Rpb24ncyByb2xlXG4gICAqXG4gICAqICoqUGxlYXNlIG5vdGUqKjogdGhpcyBpcyBhIGRpcmVjdCBJQU0gSlNPTiBwb2xpY3kgYmxvYiwgKm5vdCogYSBgaWFtLlBvbGljeVN0YXRlbWVudGBcbiAgICogb2JqZWN0IGxpa2UgeW91IHdpbGwgc2VlIGluIHRoZSByZXN0IG9mIHRoZSBDREsuXG4gICAqXG4gICAqXG4gICAqIHNpbmdsZXRvbi5hZGRUb1JvbGVQb2xpY3koe1xuICAgKiAgIEVmZmVjdDogJ0FsbG93JyxcbiAgICogICBBY3Rpb246ICdzMzpHZXRPYmplY3QnLFxuICAgKiAgIFJlc291cmNlczogJyonLFxuICAgKiB9KTtcbiAgICovXG4gIHB1YmxpYyBhZGRUb1JvbGVQb2xpY3koc3RhdGVtZW50OiBhbnkpOiB2b2lkIHtcbiAgICB0aGlzLmxhbWJkYUZ1bmN0aW9uLmFkZFBvbGljaWVzKFtzdGF0ZW1lbnRdKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGUgYSBwb2xpY3kgc3RhdGVtZW50IGZyb20gYSBzcGVjaWZpYyBhcGkgY2FsbFxuICAgKi9cbiAgcHVibGljIGFkZFBvbGljeVN0YXRlbWVudEZyb21TZGtDYWxsKHNlcnZpY2U6IHN0cmluZywgYXBpOiBzdHJpbmcsIHJlc291cmNlcz86IHN0cmluZ1tdKTogdm9pZCB7XG4gICAgdGhpcy5sYW1iZGFGdW5jdGlvbi5hZGRQb2xpY2llcyhbe1xuICAgICAgQWN0aW9uOiBbYXdzU2RrVG9JYW1BY3Rpb24oc2VydmljZSwgYXBpKV0sXG4gICAgICBFZmZlY3Q6ICdBbGxvdycsXG4gICAgICBSZXNvdXJjZTogcmVzb3VyY2VzIHx8IFsnKiddLFxuICAgIH1dKTtcbiAgfVxufVxuXG4vKipcbiAqIFByb3BlcnRpZXMgZm9yIGRlZmluaW5nIGFuIEFzc2VydGlvbnNQcm92aWRlclxuICovXG5leHBvcnQgaW50ZXJmYWNlIEFzc2VydGlvbnNQcm92aWRlclByb3BzIGV4dGVuZHMgTGFtYmRhRnVuY3Rpb25Qcm92aWRlclByb3BzIHtcbiAgLyoqXG4gICAqIFRoaXMgZGV0ZXJtaW5lcyB0aGUgdW5pcXVlbmVzcyBvZiBlYWNoIEFzc2VydGlvbnNQcm92aWRlci5cbiAgICogWW91IHNob3VsZCBvbmx5IG5lZWQgdG8gcHJvdmlkZSBzb21ldGhpbmcgZGlmZmVyZW50IGhlcmUgaWYgeW91XG4gICAqIF9rbm93XyB0aGF0IHlvdSBuZWVkIGEgc2VwYXJhdGUgcHJvdmlkZXJcbiAgICpcbiAgICogQGRlZmF1bHQgLSB0aGUgZGVmYXVsdCB1dWlkIGlzIHVzZWRcbiAgICovXG4gIHJlYWRvbmx5IHV1aWQ/OiBzdHJpbmc7XG59XG5cbi8qKlxuICogUmVwcmVzZW50cyBhbiBhc3NlcnRpb25zIHByb3ZpZGVyLiBUaGUgY3JlYXRlcyBhIHNpbmdsZXRvbmVcbiAqIExhbWJkYSBGdW5jdGlvbiB0aGF0IHdpbGwgY3JlYXRlIGEgc2luZ2xlIGZ1bmN0aW9uIHBlciBzdGFja1xuICogdGhhdCBzZXJ2ZXMgYXMgdGhlIGN1c3RvbSByZXNvdXJjZSBwcm92aWRlciBmb3IgdGhlIHZhcmlvdXNcbiAqIGFzc2VydGlvbiBwcm92aWRlcnNcbiAqL1xuZXhwb3J0IGNsYXNzIEFzc2VydGlvbnNQcm92aWRlciBleHRlbmRzIENvbnN0cnVjdCB7XG4gIC8qKlxuICAgKiBUaGUgQVJOIG9mIHRoZSBsYW1iZGEgZnVuY3Rpb24gd2hpY2ggY2FuIGJlIHVzZWRcbiAgICogYXMgYSBzZXJ2aWNlVG9rZW4gdG8gYSBDdXN0b21SZXNvdXJjZVxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IHNlcnZpY2VUb2tlbjogc3RyaW5nO1xuICAvKipcbiAgICogQSByZWZlcmVuY2UgdG8gdGhlIHByb3ZpZGVyIExhbWJkYSBGdW5jdGlvblxuICAgKiBleGVjdXRpb24gUm9sZSBBUk5cbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBoYW5kbGVyUm9sZUFybjogUmVmZXJlbmNlO1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgaGFuZGxlcjogU2luZ2xldG9uRnVuY3Rpb247XG5cbiAgY29uc3RydWN0b3Ioc2NvcGU6IENvbnN0cnVjdCwgaWQ6IHN0cmluZywgcHJvcHM/OiBBc3NlcnRpb25zUHJvdmlkZXJQcm9wcykge1xuICAgIHN1cGVyKHNjb3BlLCBpZCk7XG5cbiAgICB0aGlzLmhhbmRsZXIgPSBuZXcgU2luZ2xldG9uRnVuY3Rpb24odGhpcywgJ0Fzc2VydGlvbnNQcm92aWRlcicsIHtcbiAgICAgIGhhbmRsZXI6IHByb3BzPy5oYW5kbGVyLFxuICAgICAgdXVpZDogcHJvcHM/LnV1aWQgPz8gJzE0ODg1NDFhLTdiMjMtNDY2NC04MWI2LTliNDQwODA3NmI4MScsXG4gICAgICBsb2dSZXRlbnRpb246IHByb3BzPy5sb2dSZXRlbnRpb24sXG4gICAgfSk7XG5cbiAgICB0aGlzLmhhbmRsZXJSb2xlQXJuID0gdGhpcy5oYW5kbGVyLmxhbWJkYUZ1bmN0aW9uLnJvbGVBcm47XG5cbiAgICB0aGlzLnNlcnZpY2VUb2tlbiA9IHRoaXMuaGFuZGxlci5zZXJ2aWNlVG9rZW47XG4gIH1cblxuICAvKipcbiAgICogRW5jb2RlIGFuIG9iamVjdCBzbyBpdCBjYW4gYmUgcGFzc2VkXG4gICAqIGFzIGN1c3RvbSByZXNvdXJjZSBwYXJhbWV0ZXJzLiBDdXN0b20gcmVzb3VyY2VzIHdpbGwgY29udmVydFxuICAgKiBhbGwgaW5wdXQgcGFyYW1ldGVycyB0byBzdHJpbmdzIHNvIHdlIGVuY29kZSBub24tc3RyaW5ncyBoZXJlXG4gICAqIHNvIHdlIGNhbiB0aGVuIGRlY29kZSB0aGVtIGNvcnJlY3RseSBpbiB0aGUgcHJvdmlkZXIgZnVuY3Rpb25cbiAgICovXG4gIHB1YmxpYyBlbmNvZGUob2JqOiBhbnkpOiBhbnkge1xuICAgIGlmICghb2JqKSB7XG4gICAgICByZXR1cm4gb2JqO1xuICAgIH1cbiAgICByZXR1cm4gT2JqZWN0LmZyb21FbnRyaWVzKE9iamVjdC5lbnRyaWVzKG9iaikubWFwKChba2V5LCB2YWx1ZV0pID0+IFtrZXksIGVuY29kZVZhbHVlKHZhbHVlKV0pKTtcblxuICAgIGZ1bmN0aW9uIGVuY29kZVZhbHVlKHZhbHVlOiBhbnkpOiBhbnkge1xuICAgICAgaWYgKEFycmF5QnVmZmVyLmlzVmlldyh2YWx1ZSkpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAkdHlwZTogJ0FycmF5QnVmZmVyVmlldycsXG4gICAgICAgICAgc3RyaW5nOiBuZXcgVGV4dERlY29kZXIoKS5kZWNvZGUodmFsdWUgYXMgVWludDhBcnJheSksXG4gICAgICAgIH07XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBKU09OLnN0cmluZ2lmeSh2YWx1ZSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZSBhIHBvbGljeSBzdGF0ZW1lbnQgZnJvbSBhIHNwZWNpZmljIGFwaSBjYWxsXG4gICAqL1xuICBwdWJsaWMgYWRkUG9saWN5U3RhdGVtZW50RnJvbVNka0NhbGwoc2VydmljZTogc3RyaW5nLCBhcGk6IHN0cmluZywgcmVzb3VyY2VzPzogc3RyaW5nW10pOiB2b2lkIHtcbiAgICB0aGlzLmhhbmRsZXIuYWRkUG9saWN5U3RhdGVtZW50RnJvbVNka0NhbGwoc2VydmljZSwgYXBpLCByZXNvdXJjZXMpO1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZCBhbiBJQU0gcG9saWN5IHN0YXRlbWVudCB0byB0aGUgaW5saW5lIHBvbGljeSBvZiB0aGVcbiAgICogbGFtYmRhcyBmdW5jdGlvbidzIHJvbGVcbiAgICpcbiAgICogKipQbGVhc2Ugbm90ZSoqOiB0aGlzIGlzIGEgZGlyZWN0IElBTSBKU09OIHBvbGljeSBibG9iLCAqbm90KiBhIGBpYW0uUG9saWN5U3RhdGVtZW50YFxuICAgKiBvYmplY3QgbGlrZSB5b3Ugd2lsbCBzZWUgaW4gdGhlIHJlc3Qgb2YgdGhlIENESy5cbiAgICpcbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICogZGVjbGFyZSBjb25zdCBwcm92aWRlcjogQXNzZXJ0aW9uc1Byb3ZpZGVyO1xuICAgKiBwcm92aWRlci5hZGRUb1JvbGVQb2xpY3koe1xuICAgKiAgIEVmZmVjdDogJ0FsbG93JyxcbiAgICogICBBY3Rpb246IFsnczM6R2V0T2JqZWN0J10sXG4gICAqICAgUmVzb3VyY2U6IFsnKiddLFxuICAgKiB9KTtcbiAgICovXG4gIHB1YmxpYyBhZGRUb1JvbGVQb2xpY3koc3RhdGVtZW50OiBhbnkpOiB2b2lkIHtcbiAgICB0aGlzLmhhbmRsZXIuYWRkVG9Sb2xlUG9saWN5KHN0YXRlbWVudCk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnQgYSBwcmluY2lwYWwgYWNjZXNzIHRvIGludm9rZSB0aGUgYXNzZXJ0aW9uIHByb3ZpZGVyXG4gICAqIGxhbWJkYSBmdW5jdGlvblxuICAgKlxuICAgKiBAcGFyYW0gcHJpbmNpcGFsQXJuIHRoZSBBUk4gb2YgdGhlIHByaW5jaXBhbCB0aGF0IHNob3VsZCBiZSBnaXZlblxuICAgKiAgcGVybWlzc2lvbiB0byBpbnZva2UgdGhlIGFzc2VydGlvbiBwcm92aWRlclxuICAgKi9cbiAgcHVibGljIGdyYW50SW52b2tlKHByaW5jaXBhbEFybjogc3RyaW5nKTogdm9pZCB7XG4gICAgbmV3IENmblJlc291cmNlKHRoaXMsICdJbnZva2UnLCB7XG4gICAgICB0eXBlOiAnQVdTOjpMYW1iZGE6OlBlcm1pc3Npb24nLFxuICAgICAgcHJvcGVydGllczoge1xuICAgICAgICBBY3Rpb246ICdsYW1iZGE6SW52b2tlRnVuY3Rpb24nLFxuICAgICAgICBGdW5jdGlvbk5hbWU6IHRoaXMuc2VydmljZVRva2VuLFxuICAgICAgICBQcmluY2lwYWw6IHByaW5jaXBhbEFybixcbiAgICAgIH0sXG4gICAgfSk7XG4gIH1cbn1cblxuZnVuY3Rpb24gc2x1Z2lmeSh4OiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4geC5yZXBsYWNlKC9bXmEtekEtWjAtOV0vZywgJycpO1xufVxuIl19