cdk-drizzle-migrate
Version:
AWS CDK construct for running Drizzle ORM migrations
97 lines • 16 kB
JavaScript
;
var _a;
Object.defineProperty(exports, "__esModule", { value: true });
exports.DrizzleMigrate = void 0;
const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
const assert_1 = require("assert");
const fs_1 = require("fs");
const path = require("path");
const aws_cdk_lib_1 = require("aws-cdk-lib");
const lambda = require("aws-cdk-lib/aws-lambda");
const aws_lambda_nodejs_1 = require("aws-cdk-lib/aws-lambda-nodejs");
const logs = require("aws-cdk-lib/aws-logs");
const cr = require("aws-cdk-lib/custom-resources");
const constructs_1 = require("constructs");
/**
* A custom resource that runs Drizzle migrations
*/
class DrizzleMigrate extends constructs_1.Construct {
constructor(scope, id, props) {
super(scope, id);
const migrationsDir = path.join(process.cwd(), props.migrationsPath);
(0, assert_1.strict)((0, fs_1.existsSync)(migrationsDir), `Migrations directory ${migrationsDir} does not exist`);
const handlerDir = path.join(__dirname, "handler");
const ts_filename = path.join(handlerDir, "index.ts");
const js_filename = path.join(handlerDir, "index.js");
const entry = (0, fs_1.existsSync)(ts_filename) ? ts_filename : js_filename;
const onEventHandler = new aws_lambda_nodejs_1.NodejsFunction(this, "MigrateHandler", {
runtime: lambda.Runtime.NODEJS_20_X,
entry: entry,
logRetention: logs.RetentionDays.ONE_WEEK,
timeout: aws_cdk_lib_1.Duration.minutes(5),
vpc: props.vpc,
vpcSubnets: props.vpcSubnets,
...props.handlerProps,
environment: {
NO_COLOR: "1",
...(props.handlerProps?.environment || {}),
},
bundling: {
sourceMap: false,
// Include the migrations directory in the bundle
commandHooks: {
beforeBundling(_, outputDir) {
return [
`cp ${handlerDir}/handler.js ${outputDir}`,
`cp -r ${migrationsDir} ${path.join(outputDir, "migrations")}`,
`mkdir -p ${path.join(outputDir, "certs")}`,
`curl --silent -fL https://truststore.pki.rds.amazonaws.com/global/global-bundle.pem -o ${path.join(outputDir, "certs", "global-bundle.pem")}`,
];
},
afterBundling() {
return [];
},
beforeInstall() {
return [];
},
},
...props.handlerProps?.bundling,
},
});
// If the user gave us a security group, assume it can connect to the database.
// If not, make sure the CDK created security group allows access to the DB.
if (props.cluster &&
(!props.handlerProps ||
typeof props.handlerProps.securityGroups === "undefined" ||
props.handlerProps.securityGroups.length === 0)) {
props.cluster.connections.allowDefaultPortFrom(onEventHandler.connections, "Allow drizzle migrate lambda to connect to db");
}
this.handler = onEventHandler;
// Grant the Lambda function permission to read the secret
props.dbSecret.grantRead(onEventHandler);
const provider = new cr.Provider(this, "Provider", {
onEventHandler,
logRetention: logs.RetentionDays.ONE_WEEK,
});
this.resource = new aws_cdk_lib_1.CustomResource(this, "CustomResource", {
serviceToken: provider.serviceToken,
properties: {
secretArn: props.dbSecret.secretArn,
// We're now using a fixed path inside the Lambda bundle
migrationsPath: "migrations",
// Adding a timestamp ensures the resource is updated on each deployment
timestamp: Date.now().toString(),
},
});
const resourceCfn = this.resource.node.defaultChild;
resourceCfn.addPropertyOverride("ServiceTimeout", 900);
// Add dependency to ensure database is created before migrations run
if (props.cluster) {
this.resource.node.addDependency(props.cluster);
}
}
}
exports.DrizzleMigrate = DrizzleMigrate;
_a = JSII_RTTI_SYMBOL_1;
DrizzleMigrate[_a] = { fqn: "cdk-drizzle-migrate.DrizzleMigrate", version: "0.0.11" };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZHJpenpsZS1taWdyYXRlLXByb3ZpZGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2RyaXp6bGUtbWlncmF0ZS1wcm92aWRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLG1DQUF5QztBQUN6QywyQkFBK0I7QUFDL0IsNkJBQTRCO0FBQzVCLDZDQUFtRTtBQUVuRSxpREFBZ0Q7QUFDaEQscUVBQW1GO0FBQ25GLDZDQUE0QztBQUc1QyxtREFBa0Q7QUFDbEQsMkNBQXNDO0FBOEN0Qzs7R0FFRztBQUNILE1BQWEsY0FBZSxTQUFRLHNCQUFTO0lBVzNDLFlBQVksS0FBZ0IsRUFBRSxFQUFVLEVBQUUsS0FBMEI7UUFDbEUsS0FBSyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQTtRQUVoQixNQUFNLGFBQWEsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLEVBQUUsRUFBRSxLQUFLLENBQUMsY0FBYyxDQUFDLENBQUE7UUFDcEUsSUFBQSxlQUFNLEVBQ0osSUFBQSxlQUFVLEVBQUMsYUFBYSxDQUFDLEVBQ3pCLHdCQUF3QixhQUFhLGlCQUFpQixDQUN2RCxDQUFBO1FBQ0QsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsU0FBUyxDQUFDLENBQUE7UUFFbEQsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLEVBQUUsVUFBVSxDQUFDLENBQUE7UUFDckQsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLEVBQUUsVUFBVSxDQUFDLENBQUE7UUFDckQsTUFBTSxLQUFLLEdBQUcsSUFBQSxlQUFVLEVBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsV0FBVyxDQUFBO1FBRWpFLE1BQU0sY0FBYyxHQUFHLElBQUksa0NBQWMsQ0FBQyxJQUFJLEVBQUUsZ0JBQWdCLEVBQUU7WUFD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Q0FBQztZQUNsQixJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFBO1FBQ2pELENBQUM7SUFDSCxDQUFDOztBQXRHSCx3Q0F1R0MiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBzdHJpY3QgYXMgYXNzZXJ0IH0gZnJvbSBcImFzc2VydFwiXG5pbXBvcnQgeyBleGlzdHNTeW5jIH0gZnJvbSBcImZzXCJcbmltcG9ydCAqIGFzIHBhdGggZnJvbSBcInBhdGhcIlxuaW1wb3J0IHsgQ2ZuUmVzb3VyY2UsIEN1c3RvbVJlc291cmNlLCBEdXJhdGlvbiB9IGZyb20gXCJhd3MtY2RrLWxpYlwiXG5pbXBvcnQgKiBhcyBlYzIgZnJvbSBcImF3cy1jZGstbGliL2F3cy1lYzJcIlxuaW1wb3J0ICogYXMgbGFtYmRhIGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtbGFtYmRhXCJcbmltcG9ydCB7IE5vZGVqc0Z1bmN0aW9uLCBOb2RlanNGdW5jdGlvblByb3BzIH0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1sYW1iZGEtbm9kZWpzXCJcbmltcG9ydCAqIGFzIGxvZ3MgZnJvbSBcImF3cy1jZGstbGliL2F3cy1sb2dzXCJcbmltcG9ydCAqIGFzIHJkcyBmcm9tIFwiYXdzLWNkay1saWIvYXdzLXJkc1wiXG5pbXBvcnQgKiBhcyBzZWNyZXRzbWFuYWdlciBmcm9tIFwiYXdzLWNkay1saWIvYXdzLXNlY3JldHNtYW5hZ2VyXCJcbmltcG9ydCAqIGFzIGNyIGZyb20gXCJhd3MtY2RrLWxpYi9jdXN0b20tcmVzb3VyY2VzXCJcbmltcG9ydCB7IENvbnN0cnVjdCB9IGZyb20gXCJjb25zdHJ1Y3RzXCJcblxuLyoqXG4gKiBQcm9wZXJ0aWVzIGZvciBEcml6emxlTWlncmF0ZVxuICovXG5leHBvcnQgaW50ZXJmYWNlIERyaXp6bGVNaWdyYXRlUHJvcHMge1xuICAvKipcbiAgICogVGhlIGRhdGFiYXNlIHNlY3JldCBjb250YWluaW5nIGNvbm5lY3Rpb24gZGV0YWlsc1xuICAgKiBNdXN0IGNvbnRhaW4gc3RhbmRhcmQgQ0RLIGRhdGFiYXNlIHNlY3JldCBwcm9wZXJ0aWVzOiB1c2VybmFtZSwgcGFzc3dvcmQsIGhvc3QsIHBvcnQsIGVuZ2luZSwgZXRjLlxuICAgKi9cbiAgcmVhZG9ubHkgZGJTZWNyZXQ6IHNlY3JldHNtYW5hZ2VyLklTZWNyZXRcblxuICAvKipcbiAgICogVGhlIHBhdGggdG8gdGhlIG1pZ3JhdGlvbnMgZGlyZWN0b3J5XG4gICAqIFRoaXMgZGlyZWN0b3J5IHdpbGwgYmUgYnVuZGxlZCB3aXRoIHRoZSBMYW1iZGEgZnVuY3Rpb25cbiAgICovXG4gIHJlYWRvbmx5IG1pZ3JhdGlvbnNQYXRoOiBzdHJpbmdcblxuICAvKipcbiAgICogT3B0aW9uYWwgcHJvcGVydGllcyB0byBjdXN0b21pemUgdGhlIExhbWJkYSBmdW5jdGlvblxuICAgKiBFeGNsdWRlcyBydW50aW1lLCBlbnRyeSwgYW5kIGhhbmRsZXIgd2hpY2ggYXJlIG1hbmFnZWQgYnkgdGhlIGNvbnN0cnVjdFxuICAgKiBAZGVmYXVsdCAtIERlZmF1bHQgTGFtYmRhIGNvbmZpZ3VyYXRpb24gaXMgdXNlZFxuICAgKi9cbiAgcmVhZG9ubHkgaGFuZGxlclByb3BzPzogTm9kZWpzRnVuY3Rpb25Qcm9wc1xuXG4gIC8qKlxuICAgKiBUaGUgVlBDIHdoZXJlIHRoZSBMYW1iZGEgZnVuY3Rpb24gd2lsbCBiZSBkZXBsb3llZFxuICAgKiBSZXF1aXJlZCB0byBhbGxvdyB0aGUgTGFtYmRhIGZ1bmN0aW9uIHRvIGNvbm5lY3QgdG8gdGhlIGRhdGFiYXNlXG4gICAqL1xuICByZWFkb25seSB2cGM6IGVjMi5JVnBjXG5cbiAgLyoqXG4gICAqIE9wdGlvbmFsIHN1Ym5ldCBzZWxlY3Rpb24gdG8gZGVwbG95IHRoZSBMYW1iZGEgZnVuY3Rpb25cbiAgICogQGRlZmF1bHQgLSBQUklWQVRFX1dJVEhfRUdSRVNTIHN1Ym5ldHNcbiAgICovXG4gIHJlYWRvbmx5IHZwY1N1Ym5ldHM/OiBlYzIuU3VibmV0U2VsZWN0aW9uXG5cbiAgLyoqXG4gICAqIE9wdGlvbmFsIGRhdGFiYXNlIGNsdXN0ZXIgb3IgaW5zdGFuY2VcbiAgICogSWYgcHJvdmlkZWQgYW5kIGEgbmV3IHNlY3VyaXR5IGdyb3VwIGlzIGNyZWF0ZWQsIHRoZSBzZWN1cml0eSBncm91cCB3aWxsIGJlXG4gICAqIGNvbmZpZ3VyZWQgdG8gYWxsb3cgYWNjZXNzIHRvIHRoZSBkYXRhYmFzZVxuICAgKiBAZGVmYXVsdCAtIE5vIGRhdGFiYXNlIGNvbm5lY3Rpb24gaXMgY29uZmlndXJlZFxuICAgKi9cbiAgcmVhZG9ubHkgY2x1c3Rlcj86IHJkcy5JRGF0YWJhc2VDbHVzdGVyIHwgcmRzLklEYXRhYmFzZUluc3RhbmNlXG59XG5cbi8qKlxuICogQSBjdXN0b20gcmVzb3VyY2UgdGhhdCBydW5zIERyaXp6bGUgbWlncmF0aW9uc1xuICovXG5leHBvcnQgY2xhc3MgRHJpenpsZU1pZ3JhdGUgZXh0ZW5kcyBDb25zdHJ1Y3Qge1xuICAvKipcbiAgICogVGhlIGN1c3RvbSByZXNvdXJjZSB0aGF0IHdhcyBjcmVhdGVkXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgcmVzb3VyY2U6IEN1c3RvbVJlc291cmNlXG5cbiAgLyoqXG4gICAqIFRoZSBMYW1iZGEgZnVuY3Rpb24gdGhhdCBleGVjdXRlcyB0aGUgbWlncmF0aW9uc1xuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IGhhbmRsZXI6IE5vZGVqc0Z1bmN0aW9uXG5cbiAgY29uc3RydWN0b3Ioc2NvcGU6IENvbnN0cnVjdCwgaWQ6IHN0cmluZywgcHJvcHM6IERyaXp6bGVNaWdyYXRlUHJvcHMpIHtcbiAgICBzdXBlcihzY29wZSwgaWQpXG5cbiAgICBjb25zdCBtaWdyYXRpb25zRGlyID0gcGF0aC5qb2luKHByb2Nlc3MuY3dkKCksIHByb3BzLm1pZ3JhdGlvbnNQYXRoKVxuICAgIGFzc2VydChcbiAgICAgIGV4aXN0c1N5bmMobWlncmF0aW9uc0RpciksXG4gICAgICBgTWlncmF0aW9ucyBkaXJlY3RvcnkgJHttaWdyYXRpb25zRGlyfSBkb2VzIG5vdCBleGlzdGBcbiAgICApXG4gICAgY29uc3QgaGFuZGxlckRpciA9IHBhdGguam9pbihfX2Rpcm5hbWUsIFwiaGFuZGxlclwiKVxuXG4gICAgY29uc3QgdHNfZmlsZW5hbWUgPSBwYXRoLmpvaW4oaGFuZGxlckRpciwgXCJpbmRleC50c1wiKVxuICAgIGNvbnN0IGpzX2ZpbGVuYW1lID0gcGF0aC5qb2luKGhhbmRsZXJEaXIsIFwiaW5kZXguanNcIilcbiAgICBjb25zdCBlbnRyeSA9IGV4aXN0c1N5bmModHNfZmlsZW5hbWUpID8gdHNfZmlsZW5hbWUgOiBqc19maWxlbmFtZVxuXG4gICAgY29uc3Qgb25FdmVudEhhbmRsZXIgPSBuZXcgTm9kZWpzRnVuY3Rpb24odGhpcywgXCJNaWdyYXRlSGFuZGxlclwiLCB7XG4gICAgICBydW50aW1lOiBsYW1iZGEuUnVudGltZS5OT0RFSlNfMjBfWCxcbiAgICAgIGVudHJ5OiBlbnRyeSxcbiAgICAgIGxvZ1JldGVudGlvbjogbG9ncy5SZXRlbnRpb25EYXlzLk9ORV9XRUVLLFxuICAgICAgdGltZW91dDogRHVyYXRpb24ubWludXRlcyg1KSxcbiAgICAgIHZwYzogcHJvcHMudnBjLFxuICAgICAgdnBjU3VibmV0czogcHJvcHMudnBjU3VibmV0cyxcbiAgICAgIC4uLnByb3BzLmhhbmRsZXJQcm9wcyxcbiAgICAgIGVudmlyb25tZW50OiB7XG4gICAgICAgIE5PX0NPTE9SOiBcIjFcIixcbiAgICAgICAgLi4uKHByb3BzLmhhbmRsZXJQcm9wcz8uZW52aXJvbm1lbnQgfHwge30pLFxuICAgICAgfSxcbiAgICAgIGJ1bmRsaW5nOiB7XG4gICAgICAgIHNvdXJjZU1hcDogZmFsc2UsXG4gICAgICAgIC8vIEluY2x1ZGUgdGhlIG1pZ3JhdGlvbnMgZGlyZWN0b3J5IGluIHRoZSBidW5kbGVcbiAgICAgICAgY29tbWFuZEhvb2tzOiB7XG4gICAgICAgICAgYmVmb3JlQnVuZGxpbmcoXzogc3RyaW5nLCBvdXRwdXREaXI6IHN0cmluZyk6IHN0cmluZ1tdIHtcbiAgICAgICAgICAgIHJldHVybiBbXG4gICAgICAgICAgICAgIGBjcCAke2hhbmRsZXJEaXJ9L2hhbmRsZXIuanMgJHtvdXRwdXREaXJ9YCxcbiAgICAgICAgICAgICAgYGNwIC1yICR7bWlncmF0aW9uc0Rpcn0gJHtwYXRoLmpvaW4ob3V0cHV0RGlyLCBcIm1pZ3JhdGlvbnNcIil9YCxcbiAgICAgICAgICAgICAgYG1rZGlyIC1wICR7cGF0aC5qb2luKG91dHB1dERpciwgXCJjZXJ0c1wiKX1gLFxuICAgICAgICAgICAgICBgY3VybCAtLXNpbGVudCAtZkwgaHR0cHM6Ly90cnVzdHN0b3JlLnBraS5yZHMuYW1hem9uYXdzLmNvbS9nbG9iYWwvZ2xvYmFsLWJ1bmRsZS5wZW0gLW8gJHtwYXRoLmpvaW4ob3V0cHV0RGlyLCBcImNlcnRzXCIsIFwiZ2xvYmFsLWJ1bmRsZS5wZW1cIil9YCxcbiAgICAgICAgICAgIF1cbiAgICAgICAgICB9LFxuICAgICAgICAgIGFmdGVyQnVuZGxpbmcoKTogc3RyaW5nW10ge1xuICAgICAgICAgICAgcmV0dXJuIFtdXG4gICAgICAgICAgfSxcbiAgICAgICAgICBiZWZvcmVJbnN0YWxsKCk6IHN0cmluZ1tdIHtcbiAgICAgICAgICAgIHJldHVybiBbXVxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICAgIC4uLnByb3BzLmhhbmRsZXJQcm9wcz8uYnVuZGxpbmcsXG4gICAgICB9LFxuICAgIH0pXG5cbiAgICAvLyBJZiB0aGUgdXNlciBnYXZlIHVzIGEgc2VjdXJpdHkgZ3JvdXAsIGFzc3VtZSBpdCBjYW4gY29ubmVjdCB0byB0aGUgZGF0YWJhc2UuXG4gICAgLy8gSWYgbm90LCBtYWtlIHN1cmUgdGhlIENESyBjcmVhdGVkIHNlY3VyaXR5IGdyb3VwIGFsbG93cyBhY2Nlc3MgdG8gdGhlIERCLlxuICAgIGlmIChcbiAgICAgIHByb3BzLmNsdXN0ZXIgJiZcbiAgICAgICghcHJvcHMuaGFuZGxlclByb3BzIHx8XG4gICAgICAgIHR5cGVvZiBwcm9wcy5oYW5kbGVyUHJvcHMuc2VjdXJpdHlHcm91cHMgPT09IFwidW5kZWZpbmVkXCIgfHxcbiAgICAgICAgcHJvcHMuaGFuZGxlclByb3BzLnNlY3VyaXR5R3JvdXBzLmxlbmd0aCA9PT0gMClcbiAgICApIHtcbiAgICAgIHByb3BzLmNsdXN0ZXIuY29ubmVjdGlvbnMuYWxsb3dEZWZhdWx0UG9ydEZyb20oXG4gICAgICAgIG9uRXZlbnRIYW5kbGVyLmNvbm5lY3Rpb25zLFxuICAgICAgICBcIkFsbG93IGRyaXp6bGUgbWlncmF0ZSBsYW1iZGEgdG8gY29ubmVjdCB0byBkYlwiXG4gICAgICApXG4gICAgfVxuXG4gICAgdGhpcy5oYW5kbGVyID0gb25FdmVudEhhbmRsZXJcblxuICAgIC8vIEdyYW50IHRoZSBMYW1iZGEgZnVuY3Rpb24gcGVybWlzc2lvbiB0byByZWFkIHRoZSBzZWNyZXRcbiAgICBwcm9wcy5kYlNlY3JldC5ncmFudFJlYWQob25FdmVudEhhbmRsZXIpXG5cbiAgICBjb25zdCBwcm92aWRlciA9IG5ldyBjci5Qcm92aWRlcih0aGlzLCBcIlByb3ZpZGVyXCIsIHtcbiAgICAgIG9uRXZlbnRIYW5kbGVyLFxuICAgICAgbG9nUmV0ZW50aW9uOiBsb2dzLlJldGVudGlvbkRheXMuT05FX1dFRUssXG4gICAgfSlcblxuICAgIHRoaXMucmVzb3VyY2UgPSBuZXcgQ3VzdG9tUmVzb3VyY2UodGhpcywgXCJDdXN0b21SZXNvdXJjZVwiLCB7XG4gICAgICBzZXJ2aWNlVG9rZW46IHByb3ZpZGVyLnNlcnZpY2VUb2tlbixcbiAgICAgIHByb3BlcnRpZXM6IHtcbiAgICAgICAgc2VjcmV0QXJuOiBwcm9wcy5kYlNlY3JldC5zZWNyZXRBcm4sXG4gICAgICAgIC8vIFdlJ3JlIG5vdyB1c2luZyBhIGZpeGVkIHBhdGggaW5zaWRlIHRoZSBMYW1iZGEgYnVuZGxlXG4gICAgICAgIG1pZ3JhdGlvbnNQYXRoOiBcIm1pZ3JhdGlvbnNcIixcbiAgICAgICAgLy8gQWRkaW5nIGEgdGltZXN0YW1wIGVuc3VyZXMgdGhlIHJlc291cmNlIGlzIHVwZGF0ZWQgb24gZWFjaCBkZXBsb3ltZW50XG4gICAgICAgIHRpbWVzdGFtcDogRGF0ZS5ub3coKS50b1N0cmluZygpLFxuICAgICAgfSxcbiAgICB9KVxuXG4gICAgY29uc3QgcmVzb3VyY2VDZm4gPSB0aGlzLnJlc291cmNlLm5vZGUuZGVmYXVsdENoaWxkIGFzIENmblJlc291cmNlXG4gICAgcmVzb3VyY2VDZm4uYWRkUHJvcGVydHlPdmVycmlkZShcIlNlcnZpY2VUaW1lb3V0XCIsIDkwMClcblxuICAgIC8vIEFkZCBkZXBlbmRlbmN5IHRvIGVuc3VyZSBkYXRhYmFzZSBpcyBjcmVhdGVkIGJlZm9yZSBtaWdyYXRpb25zIHJ1blxuICAgIGlmIChwcm9wcy5jbHVzdGVyKSB7XG4gICAgICB0aGlzLnJlc291cmNlLm5vZGUuYWRkRGVwZW5kZW5jeShwcm9wcy5jbHVzdGVyKVxuICAgIH1cbiAgfVxufVxuIl19