UNPKG

aws-ddk-core

Version:

The AWS DataOps Development Kit is an open source development framework for customers that build data workflows and modern data architecture on AWS.

114 lines 17.8 kB
"use strict"; var _a; Object.defineProperty(exports, "__esModule", { value: true }); exports.BaseStack = void 0; const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti"); const cdk = require("aws-cdk-lib"); const iam = require("aws-cdk-lib/aws-iam"); const config_1 = require("../config"); /** * Base Stack to inherit from. * * Includes configurable termination protection, synthesizer, permissions boundary and tags. */ class BaseStack extends cdk.Stack { /** * Create a stack. * * Includes termination protection settings, multi-level (application, environment, * and stack-level) tags, and permissions boundary. * @param scope Scope within which this construct is defined. * @param id Identifier of the stack. * @param props Stack properties. */ constructor(scope, id, props) { const synthesizer = props.synthesizer ? props.synthesizer : props.environmentId ? config_1.getStackSynthesizer({ environmentId: props.environmentId, config: props.config }) : undefined; super(scope, id, { synthesizer: synthesizer, ...props }); if (props.permissionsBoundaryArn) { iam.PermissionsBoundary.of(scope).apply(iam.ManagedPolicy.fromManagedPolicyArn(this, "Permissions Boundary", props.permissionsBoundaryArn)); } } static createDefaultPermissionsBoundary(scope, id, props) { const prefix = props.prefix ?? "ddk"; const environmentId = props.environmentId ?? "dev"; const qualifier = props.qualifier ?? "hnb659fds"; const policyStatements = [ new iam.PolicyStatement({ effect: iam.Effect.DENY, actions: ["s3:PutAccountPublicAccessBlock"], resources: ["*"], }), new iam.PolicyStatement({ effect: iam.Effect.DENY, actions: [ "iam:CreatePolicyVersion", "iam:DeletePolicy", "iam:DeletePolicyVersion", "iam:SetDefaultPolicyVersion", ], resources: [ `arn:${cdk.Stack.of(scope).partition}:iam::${cdk.Stack.of(scope).account}:policy/${prefix}-${environmentId}-${qualifier}-permissions-boundary-${cdk.Stack.of(scope).account}-${cdk.Stack.of(scope).region}`, ], }), new iam.PolicyStatement({ effect: iam.Effect.DENY, actions: ["iam:DeleteRolePermissionsBoundary"], resources: [`arn:${cdk.Stack.of(scope).partition}:iam::${cdk.Stack.of(scope).account}:role/*`], conditions: { "ForAnyValue:StringEquals": { "iam:PermissionsBoundary": `arn:${cdk.Stack.of(scope).partition}:iam::${cdk.Stack.of(scope).account}:policy/${prefix}-${environmentId}-${qualifier}-permissions-boundary-${cdk.Stack.of(scope).account}-${cdk.Stack.of(scope).region}`, }, }, }), new iam.PolicyStatement({ effect: iam.Effect.DENY, actions: ["iam:PutRolePermissionsBoundary"], resources: [`arn:${cdk.Stack.of(scope).partition}:iam::${cdk.Stack.of(scope).account}:role/*`], conditions: { "ForAnyValue:StringNotEquals": { "iam:PermissionsBoundary": `arn:${cdk.Stack.of(scope).partition}:iam::${cdk.Stack.of(scope).account}:policy/${prefix}-${environmentId}-${qualifier}-permissions-boundary-${cdk.Stack.of(scope).account}-${cdk.Stack.of(scope).region}`, }, }, }), new iam.PolicyStatement({ effect: iam.Effect.ALLOW, actions: ["*"], resources: ["*"], }), ]; return new iam.ManagedPolicy(scope, id, { statements: policyStatements, managedPolicyName: `${prefix}-${environmentId}-${qualifier}-permissions-boundary-${cdk.Stack.of(scope).account}-${cdk.Stack.of(scope).region}`, description: "AWS-DDK: Deny dangerous actions that could escalate privilege or cause security incident", }); } /** * Create a CloudFormation Export for a string value * * Returns a string representing the corresponding `Fn.importValue()` * expression for this Export. You can control the name for the export by * passing the `name` option. * * If you don't supply a value for `name`, the value you're exporting must be * a Resource attribute (for example: `bucket.bucketName`) and it will be * given the same name as the automatic cross-stack reference that would be created * if you used the attribute in another Stack. * * One of the uses for this method is to *remove* the relationship between * two Stacks established by automatic cross-stack references. It will * temporarily ensure that the CloudFormation Export still exists while you * remove the reference from the consuming stack. After that, you can remove * the resource and the manual export. */ exportValue(exportedValue, options) { return super.exportValue(exportedValue, options); } } exports.BaseStack = BaseStack; _a = JSII_RTTI_SYMBOL_1; BaseStack[_a] = { fqn: "aws-ddk-core.BaseStack", version: "1.4.1" }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RhY2suanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYmFzZS9zdGFjay50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLG1DQUFtQztBQUNuQywyQ0FBMkM7QUFFM0Msc0NBQStEO0FBNEIvRDs7OztHQUlHO0FBQ0gsTUFBYSxTQUFVLFNBQVEsR0FBRyxDQUFDLEtBQUs7SUEyRXRDOzs7Ozs7OztPQVFHO0lBQ0gsWUFBWSxLQUFnQixFQUFFLEVBQVUsRUFBRSxLQUFxQjtRQUM3RCxNQUFNLFdBQVcsR0FBRyxLQUFLLENBQUMsV0FBVztZQUNuQyxDQUFDLENBQUMsS0FBSyxDQUFDLFdBQVc7WUFDbkIsQ0FBQyxDQUFDLEtBQUssQ0FBQyxhQUFhO2dCQUNyQixDQUFDLENBQUMsNEJBQW1CLENBQUMsRUFBRSxhQUFhLEVBQUUsS0FBSyxDQUFDLGFBQWEsRUFBRSxNQUFNLEVBQUUsS0FBSyxDQUFDLE1BQU0sRUFBRSxDQUFDO2dCQUNuRixDQUFDLENBQUMsU0FBUyxDQUFDO1FBRWQsS0FBSyxDQUFDLEtBQUssRUFBRSxFQUFFLEVBQUUsRUFBRSxXQUFXLEVBQUUsV0FBVyxFQUFFLEdBQUcsS0FBSyxFQUFFLENBQUMsQ0FBQztRQUV6RCxJQUFJLEtBQUssQ0FBQyxzQkFBc0IsRUFBRTtZQUNoQyxHQUFHLENBQUMsbUJBQW1CLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQyxDQUFDLEtBQUssQ0FDckMsR0FBRyxDQUFDLGFBQWEsQ0FBQyxvQkFBb0IsQ0FBQyxJQUFJLEVBQUUsc0JBQXNCLEVBQUUsS0FBSyxDQUFDLHNCQUFzQixDQUFDLENBQ25HLENBQUM7U0FDSDtJQUNILENBQUM7SUFqR00sTUFBTSxDQUFDLGdDQUFnQyxDQUM1QyxLQUFnQixFQUNoQixFQUFVLEVBQ1YsS0FBK0I7UUFFL0IsTUFBTSxNQUFNLEdBQUcsS0FBSyxDQUFDLE1BQU0sSUFBSSxLQUFLLENBQUM7UUFDckMsTUFBTSxhQUFhLEdBQUcsS0FBSyxD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S0FBSyxDQUFDLEVBQUUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxNQUN0QixFQUFFO3FCQUNIO2lCQUNGO2FBQ0YsQ0FBQztZQUNGLElBQUksR0FBRyxDQUFDLGVBQWUsQ0FBQztnQkFDdEIsTUFBTSxFQUFFLEdBQUcsQ0FBQyxNQUFNLENBQUMsS0FBSztnQkFDeEIsT0FBTyxFQUFFLENBQUMsR0FBRyxDQUFDO2dCQUNkLFNBQVMsRUFBRSxDQUFDLEdBQUcsQ0FBQzthQUNqQixDQUFDO1NBQ0gsQ0FBQztRQUNGLE9BQU8sSUFBSSxHQUFHLENBQUMsYUFBYSxDQUFDLEtBQUssRUFBRSxFQUFFLEVBQUU7WUFDdEMsVUFBVSxFQUFFLGdCQUFnQjtZQUM1QixpQkFBaUIsRUFBRSxHQUFHLE1BQU0sSUFBSSxhQUFhLElBQUksU0FBUyx5QkFBeUIsR0FBRyxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsS0FBSyxDQUFDLENBQUMsT0FBTyxJQUM1RyxHQUFHLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxNQUN0QixFQUFFO1lBQ0YsV0FBVyxFQUFFLDBGQUEwRjtTQUN4RyxDQUFDLENBQUM7SUFDTCxDQUFDO0lBMkJEOzs7Ozs7Ozs7Ozs7Ozs7OztPQWlCRztJQUNILFdBQVcsQ0FBQyxhQUFrQixFQUFFLE9BQWdDO1FBQzlELE9BQU8sS0FBSyxDQUFDLFdBQVcsQ0FBQyxhQUFhLEVBQUUsT0FBTyxDQUFDLENBQUM7SUFDbkQsQ0FBQzs7QUF4SEgsOEJBeUhDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgY2RrIGZyb20gXCJhd3MtY2RrLWxpYlwiO1xuaW1wb3J0ICogYXMgaWFtIGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtaWFtXCI7XG5pbXBvcnQgeyBDb25zdHJ1Y3QgfSBmcm9tIFwiY29uc3RydWN0c1wiO1xuaW1wb3J0IHsgQ29uZmlndXJhdGlvbiwgZ2V0U3RhY2tTeW50aGVzaXplciB9IGZyb20gXCIuLi9jb25maWdcIjtcblxuLyoqXG4gKiBQcm9wZXJ0aWVzIG9mIGBCYXNlU3RhY2tgLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEJhc2VTdGFja1Byb3BzIGV4dGVuZHMgY2RrLlN0YWNrUHJvcHMge1xuICAvKipcbiAgICogQVJOIG9mIHRoZSBwZXJtaXNzaW9ucyBib3VuZGFyeSBtYW5hZ2VkIHBvbGljeS5cbiAgICovXG4gIHJlYWRvbmx5IHBlcm1pc3Npb25zQm91bmRhcnlBcm4/OiBzdHJpbmc7XG4gIC8qKlxuICAgKiBJZGVudGlmaWVyIG9mIHRoZSBlbnZpcm9ubWVudC5cbiAgICpcbiAgICogQGRlZmF1bHQgXCJkZXZcIlxuICAgKi9cbiAgcmVhZG9ubHkgZW52aXJvbm1lbnRJZD86IHN0cmluZztcbiAgLyoqXG4gICAqIENvbmZpZ3VyYXRpb24gb3IgcGF0aCB0byBmaWxlIHdoaWNoIGNvbnRhaW5zIHRoZSBjb25maWd1cmF0aW9uLlxuICAgKi9cbiAgcmVhZG9ubHkgY29uZmlnPzogc3RyaW5nIHwgQ29uZmlndXJhdGlvbjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBQZXJtaXNzaW9uc0JvdW5kYXJ5UHJvcHMge1xuICByZWFkb25seSBlbnZpcm9ubWVudElkPzogc3RyaW5nO1xuICByZWFkb25seSBwcmVmaXg/OiBzdHJpbmc7XG4gIHJlYWRvbmx5IHF1YWxpZmllcj86IHN0cmluZztcbn1cblxuLyoqXG4gKiBCYXNlIFN0YWNrIHRvIGluaGVyaXQgZnJvbS5cbiAqXG4gKiBJbmNsdWRlcyBjb25maWd1cmFibGUgdGVybWluYXRpb24gcHJvdGVjdGlvbiwgc3ludGhlc2l6ZXIsIHBlcm1pc3Npb25zIGJvdW5kYXJ5IGFuZCB0YWdzLlxuICovXG5leHBvcnQgY2xhc3MgQmFzZVN0YWNrIGV4dGVuZHMgY2RrLlN0YWNrIHtcbiAgcHVibGljIHN0YXRpYyBjcmVhdGVEZWZhdWx0UGVybWlzc2lvbnNCb3VuZGFyeShcbiAgICBzY29wZTogQ29uc3RydWN0LFxuICAgIGlkOiBzdHJpbmcsXG4gICAgcHJvcHM6IFBlcm1pc3Npb25zQm91bmRhcnlQcm9wcyxcbiAgKTogaWFtLklNYW5hZ2VkUG9saWN5IHtcbiAgICBjb25zdCBwcmVmaXggPSBwcm9wcy5wcmVmaXggPz8gXCJkZGtcIjtcbiAgICBjb25zdCBlbnZpcm9ubWVudElkID0gcHJvcHMuZW52aXJvbm1lbnRJZCA/PyBcImRldlwiO1xuICAgIGNvbnN0IHF1YWxpZmllciA9IHByb3BzLnF1YWxpZmllciA/PyBcImhuYjY1OWZkc1wiO1xuXG4gICAgY29uc3QgcG9saWN5U3RhdGVtZW50cyA9IFtcbiAgICAgIG5ldyBpYW0uUG9saWN5U3RhdGVtZW50KHtcbiAgICAgICAgZWZmZWN0OiBpYW0uRWZmZWN0LkRFTlksXG4gICAgICAgIGFjdGlvbnM6IFtcInMzOlB1dEFjY291bnRQdWJsaWNBY2Nlc3NCbG9ja1wiXSxcbiAgICAgICAgcmVzb3VyY2VzOiBbXCIqXCJdLFxuICAgICAgfSksXG4gICAgICBuZXcgaWFtLlBvbGljeVN0YXRlbWVudCh7XG4gICAgICAgIGVmZmVjdDogaWFtLkVmZmVjdC5ERU5ZLFxuICAgICAgICBhY3Rpb25zOiBbXG4gICAgICAgICAgXCJpYW06Q3JlYXRlUG9saWN5VmVyc2lvblwiLFxuICAgICAgICAgIFwiaWFtOkRlbGV0ZVBvbGljeVwiLFxuICAgICAgICAgIFwiaWFtOkRlbGV0ZVBvbGljeVZlcnNpb25cIixcbiAgICAgICAgICBcImlhbTpTZXREZWZhdWx0UG9saWN5VmVyc2lvblwiLFxuICAgICAgICBdLFxuICAgICAgICByZXNvdXJjZXM6IFtcbiAgICAgICAgICBgYXJuOiR7Y2RrLlN0YWNrLm9mKHNjb3BlKS5wYXJ0aXRpb259OmlhbTo6JHtcbiAgICAgICAgICAgIGNkay5TdGFjay5vZihzY29wZSkuYWNjb3VudFxuICAgICAgICAgIH06cG9saWN5LyR7cHJlZml4fS0ke2Vudmlyb25tZW50SWR9LSR7cXVhbGlmaWVyfS1wZXJtaXNzaW9ucy1ib3VuZGFyeS0ke2Nkay5TdGFjay5vZihzY29wZSkuYWNjb3VudH0tJHtcbiAgICAgICAgICAgIGNkay5TdGFjay5vZihzY29wZSkucmVnaW9uXG4gICAgICAgICAgfWAsXG4gICAgICAgIF0sXG4gICAgICB9KSxcbiAgICAgIG5ldyBpYW0uUG9saWN5U3RhdGVtZW50KHtcbiAgICAgICAgZWZmZWN0OiBpYW0uRWZmZWN0LkRFTlksXG4gICAgICAgIGFjdGlvbnM6IFtcImlhbTpEZWxldGVSb2xlUGVybWlzc2lvbnNCb3VuZGFyeVwiXSxcbiAgICAgICAgcmVzb3VyY2VzOiBbYGFybjoke2Nkay5TdGFjay5vZihzY29wZSkucGFydGl0aW9ufTppYW06OiR7Y2RrLlN0YWNrLm9mKHNjb3BlKS5hY2NvdW50fTpyb2xlLypgXSxcbiAgICAgICAgY29uZGl0aW9uczoge1xuICAgICAgICAgIFwiRm9yQW55VmFsdWU6U3RyaW5nRXF1YWxzXCI6IHtcbiAgICAgICAgICAgIFwiaWFtOlBlcm1pc3Npb25zQm91bmRhcnlcIjogYGFybjoke2Nkay5TdGFjay5vZihzY29wZSkucGFydGl0aW9ufTppYW06OiR7XG4gICAgICAgICAgICAgIGNkay5TdGFjay5vZihzY29wZSkuYWNjb3VudFxuICAgICAgICAgICAgfTpwb2xpY3kvJHtwcmVmaXh9LSR7ZW52aXJvbm1lbnRJZH0tJHtxdWFsaWZpZXJ9LXBlcm1pc3Npb25zLWJvdW5kYXJ5LSR7Y2RrLlN0YWNrLm9mKHNjb3BlKS5hY2NvdW50fS0ke1xuICAgICAgICAgICAgICBjZGsuU3RhY2sub2Yoc2NvcGUpLnJlZ2lvblxuICAgICAgICAgICAgfWAsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgIH0pLFxuICAgICAgbmV3IGlhbS5Qb2xpY3lTdGF0ZW1lbnQoe1xuICAgICAgICBlZmZlY3Q6IGlhbS5FZmZlY3QuREVOWSxcbiAgICAgICAgYWN0aW9uczogW1wiaWFtOlB1dFJvbGVQZXJtaXNzaW9uc0JvdW5kYXJ5XCJdLFxuICAgICAgICByZXNvdXJjZXM6IFtgYXJuOiR7Y2RrLlN0YWNrLm9mKHNjb3BlKS5wYXJ0aXRpb259OmlhbTo6JHtjZGsuU3RhY2sub2Yoc2NvcGUpLmFjY291bnR9OnJvbGUvKmBdLFxuICAgICAgICBjb25kaXRpb25zOiB7XG4gICAgICAgICAgXCJGb3JBbnlWYWx1ZTpTdHJpbmdOb3RFcXVhbHNcIjoge1xuICAgICAgICAgICAgXCJpYW06UGVybWlzc2lvbnNCb3VuZGFyeVwiOiBgYXJuOiR7Y2RrLlN0YWNrLm9mKHNjb3BlKS5wYXJ0aXRpb259OmlhbTo6JHtcbiAgICAgICAgICAgICAgY2RrLlN0YWNrLm9mKHNjb3BlKS5hY2NvdW50XG4gICAgICAgICAgICB9OnBvbGljeS8ke3ByZWZpeH0tJHtlbnZpcm9ubWVudElkfS0ke3F1YWxpZmllcn0tcGVybWlzc2lvbnMtYm91bmRhcnktJHtjZGsuU3RhY2sub2Yoc2NvcGUpLmFjY291bnR9LSR7XG4gICAgICAgICAgICAgIGNkay5TdGFjay5vZihzY29wZSkucmVnaW9uXG4gICAgICAgICAgICB9YCxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgfSksXG4gICAgICBuZXcgaWFtLlBvbGljeVN0YXRlbWVudCh7XG4gICAgICAgIGVmZmVjdDogaWFtLkVmZmVjdC5BTExPVyxcbiAgICAgICAgYWN0aW9uczogW1wiKlwiXSxcbiAgICAgICAgcmVzb3VyY2VzOiBbXCIqXCJdLFxuICAgICAgfSksXG4gICAgXTtcbiAgICByZXR1cm4gbmV3IGlhbS5NYW5hZ2VkUG9saWN5KHNjb3BlLCBpZCwge1xuICAgICAgc3RhdGVtZW50czogcG9saWN5U3RhdGVtZW50cyxcbiAgICAgIG1hbmFnZWRQb2xpY3lOYW1lOiBgJHtwcmVmaXh9LSR7ZW52aXJvbm1lbnRJZH0tJHtxdWFsaWZpZXJ9LXBlcm1pc3Npb25zLWJvdW5kYXJ5LSR7Y2RrLlN0YWNrLm9mKHNjb3BlKS5hY2NvdW50fS0ke1xuICAgICAgICBjZGsuU3RhY2sub2Yoc2NvcGUpLnJlZ2lvblxuICAgICAgfWAsXG4gICAgICBkZXNjcmlwdGlvbjogXCJBV1MtRERLOiBEZW55IGRhbmdlcm91cyBhY3Rpb25zIHRoYXQgY291bGQgZXNjYWxhdGUgcHJpdmlsZWdlIG9yIGNhdXNlIHNlY3VyaXR5IGluY2lkZW50XCIsXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlIGEgc3RhY2suXG4gICAqXG4gICAqIEluY2x1ZGVzIHRlcm1pbmF0aW9uIHByb3RlY3Rpb24gc2V0dGluZ3MsIG11bHRpLWxldmVsIChhcHBsaWNhdGlvbiwgZW52aXJvbm1lbnQsXG4gICAqIGFuZCBzdGFjay1sZXZlbCkgdGFncywgYW5kIHBlcm1pc3Npb25zIGJvdW5kYXJ5LlxuICAgKiBAcGFyYW0gc2NvcGUgU2NvcGUgd2l0aGluIHdoaWNoIHRoaXMgY29uc3RydWN0IGlzIGRlZmluZWQuXG4gICAqIEBwYXJhbSBpZCBJZGVudGlmaWVyIG9mIHRoZSBzdGFjay5cbiAgICogQHBhcmFtIHByb3BzIFN0YWNrIHByb3BlcnRpZXMuXG4gICAqL1xuICBjb25zdHJ1Y3RvcihzY29wZTogQ29uc3RydWN0LCBpZDogc3RyaW5nLCBwcm9wczogQmFzZVN0YWNrUHJvcHMpIHtcbiAgICBjb25zdCBzeW50aGVzaXplciA9IHByb3BzLnN5bnRoZXNpemVyXG4gICAgICA/IHByb3BzLnN5bnRoZXNpemVyXG4gICAgICA6IHByb3BzLmVudmlyb25tZW50SWRcbiAgICAgID8gZ2V0U3RhY2tTeW50aGVzaXplcih7IGVudmlyb25tZW50SWQ6IHByb3BzLmVudmlyb25tZW50SWQsIGNvbmZpZzogcHJvcHMuY29uZmlnIH0pXG4gICAgICA6IHVuZGVmaW5lZDtcblxuICAgIHN1cGVyKHNjb3BlLCBpZCwgeyBzeW50aGVzaXplcjogc3ludGhlc2l6ZXIsIC4uLnByb3BzIH0pO1xuXG4gICAgaWYgKHByb3BzLnBlcm1pc3Npb25zQm91bmRhcnlBcm4pIHtcbiAgICAgIGlhbS5QZXJtaXNzaW9uc0JvdW5kYXJ5Lm9mKHNjb3BlKS5hcHBseShcbiAgICAgICAgaWFtLk1hbmFnZWRQb2xpY3kuZnJvbU1hbmFnZWRQb2xpY3lBcm4odGhpcywgXCJQZXJtaXNzaW9ucyBCb3VuZGFyeVwiLCBwcm9wcy5wZXJtaXNzaW9uc0JvdW5kYXJ5QXJuKSxcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZSBhIENsb3VkRm9ybWF0aW9uIEV4cG9ydCBmb3IgYSBzdHJpbmcgdmFsdWVcbiAgICpcbiAgICogUmV0dXJucyBhIHN0cmluZyByZXByZXNlbnRpbmcgdGhlIGNvcnJlc3BvbmRpbmcgYEZuLmltcG9ydFZhbHVlKClgXG4gICAqIGV4cHJlc3Npb24gZm9yIHRoaXMgRXhwb3J0LiBZb3UgY2FuIGNvbnRyb2wgdGhlIG5hbWUgZm9yIHRoZSBleHBvcnQgYnlcbiAgICogcGFzc2luZyB0aGUgYG5hbWVgIG9wdGlvbi5cbiAgICpcbiAgICogSWYgeW91IGRvbid0IHN1cHBseSBhIHZhbHVlIGZvciBgbmFtZWAsIHRoZSB2YWx1ZSB5b3UncmUgZXhwb3J0aW5nIG11c3QgYmVcbiAgICogYSBSZXNvdXJjZSBhdHRyaWJ1dGUgKGZvciBleGFtcGxlOiBgYnVja2V0LmJ1Y2tldE5hbWVgKSBhbmQgaXQgd2lsbCBiZVxuICAgKiBnaXZlbiB0aGUgc2FtZSBuYW1lIGFzIHRoZSBhdXRvbWF0aWMgY3Jvc3Mtc3RhY2sgcmVmZXJlbmNlIHRoYXQgd291bGQgYmUgY3JlYXRlZFxuICAgKiBpZiB5b3UgdXNlZCB0aGUgYXR0cmlidXRlIGluIGFub3RoZXIgU3RhY2suXG4gICAqXG4gICAqIE9uZSBvZiB0aGUgdXNlcyBmb3IgdGhpcyBtZXRob2QgaXMgdG8gKnJlbW92ZSogdGhlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuXG4gICAqIHR3byBTdGFja3MgZXN0YWJsaXNoZWQgYnkgYXV0b21hdGljIGNyb3NzLXN0YWNrIHJlZmVyZW5jZXMuIEl0IHdpbGxcbiAgICogdGVtcG9yYXJpbHkgZW5zdXJlIHRoYXQgdGhlIENsb3VkRm9ybWF0aW9uIEV4cG9ydCBzdGlsbCBleGlzdHMgd2hpbGUgeW91XG4gICAqIHJlbW92ZSB0aGUgcmVmZXJlbmNlIGZyb20gdGhlIGNvbnN1bWluZyBzdGFjay4gQWZ0ZXIgdGhhdCwgeW91IGNhbiByZW1vdmVcbiAgICogdGhlIHJlc291cmNlIGFuZCB0aGUgbWFudWFsIGV4cG9ydC5cbiAgICovXG4gIGV4cG9ydFZhbHVlKGV4cG9ydGVkVmFsdWU6IGFueSwgb3B0aW9ucz86IGNkay5FeHBvcnRWYWx1ZU9wdGlvbnMpOiBzdHJpbmcge1xuICAgIHJldHVybiBzdXBlci5leHBvcnRWYWx1ZShleHBvcnRlZFZhbHVlLCBvcHRpb25zKTtcbiAgfVxufVxuIl19