UNPKG

db-migrate-pg-aurora

Version:
633 lines 54.9 kB
"use strict"; var __extends = (this && this.__extends) || (function () { var extendStatics = function (d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; return extendStatics(d, b); }; return function (d, b) { extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __generator = (this && this.__generator) || function (thisArg, body) { var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); while (_) try { if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; case 5: _.label++; y = op[1]; op = [0]; continue; case 7: op = _.ops.pop(); _.trys.pop(); continue; default: if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } if (t[2]) _.ops.pop(); _.trys.pop(); continue; } op = body.call(thisArg, _); } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } }; Object.defineProperty(exports, "__esModule", { value: true }); var AWS = require("aws-sdk"); var Bluebird = require("bluebird"); var semver = require("semver"); // @ts-ignore var Promise = require("bluebird"); var BaseDriver = require("db-migrate-base"); var AuroraDataApiDriver = /** @class */ (function (_super_1) { __extends(AuroraDataApiDriver, _super_1); function AuroraDataApiDriver(internals, rdsParams) { var _this = _super_1.call(this, internals) || this; _this.internals = internals; console.debug("Initializing driver..."); _this._escapeDDL = "\""; _this._escapeString = "'"; _this.internals.rdsParams = rdsParams; _this.internals.connection = new AWS.RDSDataService({ apiVersion: "2018-08-01", region: rdsParams.region, maxRetries: rdsParams.maxRetries !== undefined ? rdsParams.maxRetries : 3, httpOptions: { connectTimeout: rdsParams.connectTimeout !== undefined ? rdsParams.connectTimeout : 45000, }, }); _this.internals.notransactions = false; return _this; } AuroraDataApiDriver.prototype.getConnection = function () { console.debug("Retrieving connection..."); return this.internals.connection; }; AuroraDataApiDriver.prototype.startMigration = function (cb) { console.debug("Starting migration..."); if (!this.internals.notransactions) { return Promise.cast(this.startTransaction).thenReturn().nodeify(cb); } }; AuroraDataApiDriver.prototype.startTransaction = function () { return __awaiter(this, void 0, void 0, function () { var transactionId; return __generator(this, function (_a) { switch (_a.label) { case 0: console.debug("Initializing Transaction..."); return [4 /*yield*/, this.internals.connection .beginTransaction({ resourceArn: this.internals.rdsParams.resourceArn, secretArn: this.internals.rdsParams.secretArn, database: this.internals.rdsParams.database, schema: this.internals.rdsParams.schema, }) .promise()]; case 1: transactionId = (_a.sent()).transactionId; this.internals.currentTransaction = transactionId; return [2 /*return*/]; } }); }); }; AuroraDataApiDriver.prototype.endMigration = function (cb) { console.debug("Finishing migration..."); if (!this.internals.notransactions) { return Promise.cast(this.commitTransaction).thenReturn().nodeify(cb); } }; AuroraDataApiDriver.prototype.commitTransaction = function () { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: console.debug("Committing Transaction..."); return [4 /*yield*/, this.internals.connection .commitTransaction({ resourceArn: this.internals.rdsParams.resourceArn, secretArn: this.internals.rdsParams.secretArn, transactionId: this.internals.currentTransaction, }) .promise()]; case 1: _a.sent(); delete this.internals.currentTransaction; return [2 /*return*/]; } }); }); }; AuroraDataApiDriver.prototype.mapDataType = function (str) { switch (str) { case "json": case "jsonb": return str.toUpperCase(); case "string": return "TEXT"; case "datetime": return "TIMESTAMP"; case "blob": return "BYTEA"; } return _super_1.prototype.mapDataType.call(this, str); }; AuroraDataApiDriver.prototype.createColumnDef = function (name, spec, options) { name = this._escapeDDL + name + this._escapeDDL; var type = this.mapDataType(spec.type); var len = spec.length ? "(" + spec.length + ")" : ""; var constraints = this.createColumnConstraint(spec, options).constraints; return { constraints: [name, type, len, constraints].join(" "), }; }; AuroraDataApiDriver.prototype.createColumnConstraint = function (spec, options, tableName, columnName) { var constraints = []; var cb; if (spec.timezone) { constraints.push("WITH TIME ZONE"); } if (spec.notNull) { constraints.push("NOT NULL"); } if (spec.defaultValue !== undefined) { constraints.push("DEFAULT"); if (typeof spec.defaultValue === "string") { constraints.push("'" + spec.defaultValue + "'"); } else if (typeof spec.defaultValue.prep === "string") { constraints.push(String(spec.defaultValue.prep)); } else { constraints.push(String(spec.defaultValue)); } } // keep foreignKey for backward compatible, push to callbacks in the future if (spec.foreignKey) { cb = this.bindForeignKey(tableName, columnName, spec.foreignKey); } return { foreignKey: cb, constraints: String(constraints.join(" ")), }; }; AuroraDataApiDriver.prototype.renameTable = function (tableName, newTableName) { var sql = "ALTER TABLE IF EXISTS \"" + tableName + "\" RENAME TO \"" + newTableName + "\""; return this.runSql(sql); }; AuroraDataApiDriver.prototype.createDatabase = function (dbName, options) { var createDBSQL = "CREATE DATABASE \"" + dbName + "\""; if (options.ifNotExists) { return this.runSql("CREATE EXTENSION IF NOT EXISTS dblink;\n DO $$\n BEGIN\n PERFORM dblink_exec('', '" + createDBSQL + "');\n EXCEPTION WHEN duplicate_database THEN RAISE NOTICE '%, skipping', SQLERRM USING ERRCODE = SQLSTATE;\n END\n $$;"); } else { return this.runSql(createDBSQL); } }; AuroraDataApiDriver.prototype.dropDatabase = function (dbName, options) { var ifExists = options.ifExists ? "IF EXISTS" : ""; return this.runSql("DROP DATABASE " + ifExists + " \"" + dbName + "\""); }; AuroraDataApiDriver.prototype.createSequence = function (sqName, options) { var _a; var temp = ((_a = options) === null || _a === void 0 ? void 0 : _a.temp) ? "TEMP" : ""; return this.runSql("CREATE " + temp + " SEQUENCE \"" + sqName + "\""); }; AuroraDataApiDriver.prototype.switchDatabase = function (options) { if (typeof options === "object" && typeof options.database === "string") { this.log.info("Ignore database option, not available with postgres. Use schema instead!"); return this.runSql("SET search_path TO \"" + options.database + "\""); } else if (typeof options === "string") { return this.runSql("SET search_path TO \"" + options + "\""); } }; AuroraDataApiDriver.prototype.dropSequence = function (dbName, options) { var ifExists = options.ifExists ? "IF EXISTS" : ""; var rule = options.cascade ? "CASCADE" : options.restrict ? "RESTRICT" : ""; return this.runSql("DROP SEQUENCE " + ifExists + " \"" + dbName + "\" " + rule); }; AuroraDataApiDriver.prototype.removeColumn = function (tableName, columnName) { return this.runSql("ALTER TABLE \"" + tableName + "\"\n DROP COLUMN IF EXISTS \"" + columnName + "\""); }; AuroraDataApiDriver.prototype.createMigrationsTable = function (cb) { var _this = this; var options = { columns: { id: { type: "SERIAL", notNull: true, primaryKey: true, }, name: { type: "TEXT", notNull: true }, run_on: { type: "TIMESTAMP", notNull: true }, }, ifNotExists: true, }; console.debug("Creating migrations table (if necessary)..."); return this.all("show server_version_num") .then(function (result) { if (result && result.length > 0 && result[0].server_version_num) { var version = result[0].server_version_num; var major = Math.floor(version / 10000); var minor = Math.floor((version - major * 10000) / 100); var patch = Math.floor(version - major * 10000 - minor * 100); version = major + "." + minor + "." + patch; options.ifNotExists = semver.gte(version, "9.1.0"); } // Get the current search path so we can change the current schema // if necessary return _this.all("SHOW search_path"); }) // not all DBs support server_version_num, fall back to server_version .catch(function () { return _this.all("show server_version").then(function (result) { if (result && result.length > 0 && result[0].server_version) { var version = result[0].server_version; // handle versions like “10.2 (Ubuntu 10.2)” version = version.split(" ")[0]; // handle missing patch numbers if (version.split(".").length !== 3) { version += ".0"; } options.ifNotExists = semver.gte(version, "9.1.0"); // Get the current search path so we can change the current // schema if necessary return _this.all("SHOW search_path"); } }); }).then(function (result) { var searchPath; var searchPaths = result[0].search_path.split(","); for (var i = 0; i < searchPaths.length; ++i) { if (searchPaths[i].indexOf("\"") !== 0) { searchPaths[i] = "\"" + searchPaths[i].trim() + "\""; } } result[0].search_path = searchPaths.join(","); // if the user specified a different schema, prepend it to the search path. // This will make all DDL/DML/SQL operate on the specified schema. if (_this.schema === "public") { searchPath = result[0].search_path; } else { searchPath = "\"" + _this.schema + "\"," + result[0].search_path; } return _this.all("SET search_path TO " + searchPath); }).then(function () { return _this.all("SELECT table_name FROM information_schema.tables WHERE table_name = '" + _this.internals.migrationTable + "' " + (_this.schema ? " AND table_schema = '${this.schema}'" : "")); }).then(function (result) { var _a; if (((_a = result) === null || _a === void 0 ? void 0 : _a.length) < 1) { console.debug("Creating migrations table with " + JSON.stringify(options) + "..."); return _this.createTable(_this.internals.migrationTable, options); } console.debug("Found existing migrations table, no need to recreate."); return Promise.resolve(); }).nodeify(cb); }; AuroraDataApiDriver.prototype.createSeedsTable = function (cb) { var _this = this; var options = { columns: { id: { type: "SERIAL", notNull: true, primaryKey: true, }, name: { type: "TEXT", notNull: true }, run_on: { type: "TIMESTAMP", notNull: true }, }, ifNotExists: true, }; return this.all("select version() as version") .then(function (result) { if (result && result.length > 0 && result[0].version) { var version = result[0].version; var match = version.match(/\d+\.\d+\.\d+/); if (match && match[0] && semver.gte(match[0], "9.1.0")) { options.ifNotExists = true; } } // Get the current search path so we can change the current schema if necessary return _this.all("SHOW search_path"); }).then(function (result) { var searchPath; // if the user specified a different schema, prepend it to the search path. // This will make all DDL/DML/SQL operate on the specified schema. if (_this.schema === "public") { searchPath = result[0].search_path; } else { searchPath = "\"" + _this.schema + "\"," + result[0].search_path; } return _this.all("SET search_path TO " + searchPath); }).then(function () { return _this.all("SELECT table_name FROM information_schema.tables WHERE table_name = '" + _this.internals.seedTable + "' " + (_this.schema ? " AND table_schema = '${this.schema}'" : "")); }).then(function (result) { var _a; if (((_a = result) === null || _a === void 0 ? void 0 : _a.length) < 1) { return _this.createTable(_this.internals.seedTable, options); } return Promise.resolve(); }).nodeify(cb); }; AuroraDataApiDriver.prototype.createTable = function (tableName, options) { var _a; console.log("creating table: " + tableName); var columnSpecs = options; var opts; if (options.columns !== undefined) { columnSpecs = options.columns; opts = options; } var ifNotExistsSql = ""; if ((_a = opts) === null || _a === void 0 ? void 0 : _a.ifNotExists) { ifNotExistsSql = "IF NOT EXISTS"; } var primaryKeyColumns = []; var columnDefOptions = { emitPrimaryKey: false, }; for (var columnName in columnSpecs) { var columnSpec = this.normalizeColumnSpec(columnSpecs[columnName]); columnSpecs[columnName] = columnSpec; if (columnSpec.primaryKey) { primaryKeyColumns.push({ spec: columnSpec, name: columnName }); } } var pkSql = ""; if (primaryKeyColumns.length > 1) { pkSql = this._handleMultiPrimaryKeys(primaryKeyColumns); } else if (primaryKeyColumns.length === 1) { primaryKeyColumns[0] = primaryKeyColumns[0].name; columnDefOptions.emitPrimaryKey = true; } var columnDefs = []; var extensions = ""; var tableOptions = ""; for (var columnName in columnSpecs) { var columnSpec = columnSpecs[columnName]; this._prepareSpec(columnName, columnSpec, columnDefOptions, tableName); var constraint = this.createColumnDef(columnName, columnSpec, columnDefOptions); columnDefs.push(constraint.constraints); } var sql = "CREATE TABLE " + ifNotExistsSql + " " + this.escapeDDL(tableName) + " (" + columnDefs.join(", ") + extensions + pkSql + ") " + tableOptions; return this.runSql(sql); }; AuroraDataApiDriver.prototype.addIndex = function (tableName, indexName, columns, unique) { if (!Array.isArray(columns)) { columns = [columns]; } var createIndexSQL = "CREATE " + (unique ? "UNIQUE" : "") + " INDEX IF NOT EXISTS \"" + indexName + "\"\n ON \"" + tableName + "\" (" + columns.map(function (column) { return (typeof column === "string" ? column : column.name); }).join(", ") + ");"; return this.runSql(createIndexSQL); }; AuroraDataApiDriver.prototype.removeIndex = function (tableName, indexName) { // tableName is optional for other drivers, but required for mySql. // So, check the args to ensure they are valid if (!indexName) { throw new Error("Illegal arguments, must provide \"tableName\" and \"indexName\""); } return this.runSql("DROP INDEX IF EXISTS \"" + indexName + "\";"); }; AuroraDataApiDriver.prototype.renameColumn = function (tableName, oldColumnName, newColumnName) { return __awaiter(this, void 0, Bluebird, function () { return __generator(this, function (_a) { return [2 /*return*/, this.runSql("ALTER TABLE IF EXISTS \"" + tableName + "\"\n RENAME COLUMN \"" + oldColumnName + "\" TO \"" + newColumnName + "\";")]; }); }); }; AuroraDataApiDriver.prototype.changeColumn = function (tableName, columnName, columnSpec) { return __awaiter(this, void 0, void 0, function () { var setOrDrop, sql, sql, using, sql; return __generator(this, function (_a) { switch (_a.label) { case 0: if (!(columnSpec.notNull !== undefined)) return [3 /*break*/, 2]; setOrDrop = columnSpec.notNull ? "SET" : "DROP"; return [4 /*yield*/, this.runSql("ALTER TABLE IF EXISTS \"" + tableName + "\"\n ALTER COLUMN \"" + columnName + "\" " + setOrDrop + " NOT NULL")]; case 1: _a.sent(); _a.label = 2; case 2: if (!(columnSpec.unique !== undefined)) return [3 /*break*/, 4]; sql = columnSpec.unique ? "ALTER TABLE \"" + tableName + "\" ADD CONSTRAINT \"" + columnName + "\" UNIQUE (" + columnName + ");" : "ALTER TABLE \"" + tableName + "\" DROP CONSTRAINT \"" + columnName + "\";"; return [4 /*yield*/, this.runSql(sql)]; case 3: _a.sent(); _a.label = 4; case 4: if (!(columnSpec.defaultValue !== undefined)) return [3 /*break*/, 6]; sql = "ALTER TABLE \"" + tableName + "\"\n ALTER COLUMN \"" + columnName + "\" SET DEFAULT " + (typeof columnSpec.defaultValue === "string" ? "'" + columnSpec.defaultValue + "'" : columnSpec.defaultValue); return [4 /*yield*/, this.runSql(sql)]; case 5: _a.sent(); _a.label = 6; case 6: if (!(columnSpec.type !== undefined)) return [3 /*break*/, 8]; using = "USING \"" + columnName + "\"::" + this.mapDataType(columnSpec.type); sql = "ALTER TABLE \"" + tableName + "\"\nALTER COLUMN \"" + columnName + "\" TYPE " + this.mapDataType(columnSpec.type) + " " + using; return [4 /*yield*/, this.runSql(sql)]; case 7: _a.sent(); _a.label = 8; case 8: return [2 /*return*/]; } }); }); }; AuroraDataApiDriver.prototype.addPrivateTableData = function (name, tableName, callback) { return this.runSql("INSERT INTO \"" + tableName + "\" (name, run_on) VALUES (:name, CURRENT_TIMESTAMP);", [{ name: "name", value: { stringValue: name } }]).then(function (result) { return callback(undefined, result); }) .catch(function (err) { return callback(err); }); }; AuroraDataApiDriver.prototype.addMigrationRecord = function (name, callback) { console.debug("Adding Migration Record: " + name); return this.addPrivateTableData(name, this.internals.migrationTable, callback); }; /** * Deletes a migration * * @param migrationName - The name of the migration to be deleted */ AuroraDataApiDriver.prototype.deleteMigration = function (migrationName, callback) { return __awaiter(this, void 0, void 0, function () { var sql, result, error; return __generator(this, function (_a) { sql = "DELETE FROM \"" + this.internals.migrationTable + "\" WHERE NAME = :name"; try { result = this.runSql(sql, [ { name: "name", value: { stringValue: migrationName, }, }, ]); } catch (ex) { error = ex; } if (callback) { return [2 /*return*/, callback(error, result)]; } else if (error) { throw error; } return [2 /*return*/, result]; }); }); }; AuroraDataApiDriver.prototype.addSeedRecord = function (name, callback) { return this.addPrivateTableData(name, this.internals.seedTable, callback); }; AuroraDataApiDriver.prototype.addForeignKey = function (tableName, referencedTableName, keyName, fieldMapping, rules) { if (rules === void 0) { rules = {}; } var columns = Object.keys(fieldMapping); var referencedColumns = columns.map(function (key) { return fieldMapping[key]; }); var sql = "ALTER TABLE \"" + tableName + "\"\n ADD CONSTRAINT \"" + keyName + "\"\n FOREIGN KEY (" + this.quoteDDLArr(columns) + ")\n REFERENCES \"" + referencedTableName + "\" (" + this.quoteDDLArr(referencedColumns) + ") ON DELETE " + (rules.onDelete || "NO ACTION"); return this.runSql(sql); }; AuroraDataApiDriver.prototype.removeForeignKey = function (tableName, keyName) { return __awaiter(this, void 0, Bluebird, function () { var sql; return __generator(this, function (_a) { switch (_a.label) { case 0: sql = "ALTER TABLE \"" + tableName + "\"\n DROP CONSTRAINT \"" + keyName + "\""; return [4 /*yield*/, this.runSql(sql)]; case 1: _a.sent(); return [2 /*return*/]; } }); }); }; AuroraDataApiDriver.prototype.insert = function () { var index = 1; if (arguments.length > 3) { index = 2; } arguments[index] = arguments[index].map(function (value) { return typeof value === "string" ? value : JSON.stringify(value); }); return this._super.apply(this, arguments); }; AuroraDataApiDriver.prototype.runSql = function (sql, parameters) { var _a; return __awaiter(this, void 0, Bluebird, function () { var params, exec, result, ex_1; return __generator(this, function (_b) { switch (_b.label) { case 0: this.internals.mod.log.sql.apply(null, [sql, parameters]); if (this.internals.dryRun) { return [2 /*return*/, Bluebird.resolve()]; } if (((_a = parameters) === null || _a === void 0 ? void 0 : _a.length) && sql.indexOf("?") >= 0) { parameters.forEach(function (value) { sql = sql.replace("?", ":" + value.name); }); } params = { secretArn: this.internals.rdsParams.secretArn, resourceArn: this.internals.rdsParams.resourceArn, database: this.internals.rdsParams.database, schema: this.internals.rdsParams.schema, transactionId: this.internals.currentTransaction, includeResultMetadata: true, parameters: parameters, sql: sql, }; exec = Bluebird.promisify(this.internals.connection.executeStatement).bind(this.internals.connection); _b.label = 1; case 1: _b.trys.push([1, 3, , 4]); return [4 /*yield*/, exec(params).then(AuroraDataApiDriver.convertResultsToObjects)]; case 2: result = _b.sent(); return [3 /*break*/, 4]; case 3: ex_1 = _b.sent(); console.error("Error executing " + sql + ": " + ex_1.message); throw ex_1; case 4: return [2 /*return*/, result]; } }); }); }; AuroraDataApiDriver.convertResultsToObjects = function (data) { if (!data || !data.records) { return []; } return data.records.map(function (record) { var result = {}; data.columnMetadata.forEach(function (value, idx) { result[value.name] = record[idx].stringValue || record[idx].longValue || record[idx].doubleValue || record[idx].booleanValue || record[idx].blobValue; }); return result; }); }; // @ts-ignore AuroraDataApiDriver.prototype.all = function (sql, callback) { return __awaiter(this, void 0, void 0, function () { var result, error, ex_2; return __generator(this, function (_a) { switch (_a.label) { case 0: _a.trys.push([0, 2, , 3]); return [4 /*yield*/, this.runSql(sql)]; case 1: result = _a.sent(); return [3 /*break*/, 3]; case 2: ex_2 = _a.sent(); error = ex_2; return [3 /*break*/, 3]; case 3: if (callback) { callback(error, result); } if (error) { throw error; } return [2 /*return*/, result]; } }); }); }; AuroraDataApiDriver.prototype.close = function () { return Bluebird.resolve(); }; return AuroraDataApiDriver; }(BaseDriver)); exports.default = AuroraDataApiDriver; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQXVyb3JhRGF0YUFwaURyaXZlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9BdXJvcmFEYXRhQXBpRHJpdmVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLDZCQUErQjtBQUUvQixtQ0FBc0M7QUFDdEMsK0JBQWtDO0FBRWxDLGFBQWE7QUFDYixJQUFNLE9BQU8sR0FBRyxPQUFPLENBQUMsVUFBVSxDQUFDLENBQUM7QUFDcEMsSUFBTSxVQUFVLEdBQUcsT0FBTyxDQUFDLGlCQUFpQixDQUFDLENBQUM7QUF3QzlDO0lBQWlELHlDQUFVO0lBSXpELDZCQUFvQixTQUEyQixFQUFFLFNBQW9CO1FBQXJFLFlBQ0Usb0JBQU0sU0FBUyxDQUFDLFNBbUJqQjtRQXBCbUIsZUFBUyxHQUFULFNBQVMsQ0FBa0I7UUFHN0MsT0FBTyxDQUFDLEtBQUssQ0FBQyx3QkFBd0IsQ0FBQyxDQUFDO1FBQ3hDLEtBQUksQ0FBQyxVQUFVLEdBQUcsSUFBRyxDQUFDO1FBQ3RCLEtBQUksQ0FBQyxhQUFhLEdBQUcsR0FBRyxDQUFDO1FBRXpCLEtBQUksQ0FBQyxTQUFTLENBQUMsU0FBUyxHQUFHLFNBQVMsQ0FBQztRQUNyQyxLQUFJLENBQUMsU0FBUyxDQUFDLFVBQVUsR0FBRyxJQUFJLEdBQUcsQ0FBQyxjQUFjLENBQUM7WUFDakQsVUFBVSxFQUFFLFlBQVk7WUFDeEIsTUFBTSxFQUFFLFNBQVMsQ0FBQyxNQUFNO1lBQ3hCLFVBQVUsRUFBRSxTQUFTLENBQUMsVUFBVSxLQUFLLFNBQVMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUN6RSxXQUFXLEVBQUU7Z0JBQ1gsY0FBYyxFQUNaLFNBQVMsQ0FBQyxjQUFjLEtBQUssU0FBUztvQkFDcEMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxjQUFjO29CQUMxQixDQUFDLENB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