UNPKG

knex-firebird-dialect

Version:
293 lines (289 loc) 37.3 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = void 0; var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator")); var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator")); var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass")); var _lodash = require("lodash"); function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t["return"] || t["return"](); } finally { if (u) throw o; } } }; } function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } } function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; } // Firebird_DDL // // // columns and changing datatypes. // ------- var Firebird_DDL = /*#__PURE__*/function () { function Firebird_DDL(client, tableCompiler, pragma, connection) { (0, _classCallCheck2["default"])(this, Firebird_DDL); this.client = client; this.tableCompiler = tableCompiler; this.pragma = pragma; this.tableNameRaw = this.tableCompiler.tableNameRaw; this.alteredName = (0, _lodash.uniqueId)("_knex_temp_alter"); this.connection = connection; this.formatter = client && client.config && client.config.wrapIdentifier ? client.config.wrapIdentifier : function (value) { return value; }; } return (0, _createClass2["default"])(Firebird_DDL, [{ key: "tableName", value: function tableName() { return this.formatter(this.tableNameRaw, function (value) { return value; }); } }, { key: "getColumn", value: function () { var _getColumn = (0, _asyncToGenerator2["default"])(/*#__PURE__*/_regenerator["default"].mark(function _callee(column) { var _this = this; var currentCol; return _regenerator["default"].wrap(function _callee$(_context) { while (1) switch (_context.prev = _context.next) { case 0: currentCol = (0, _lodash.find)(this.pragma, function (col) { return _this.client.wrapIdentifier(col.name).toLowerCase() === _this.client.wrapIdentifier(column).toLowerCase(); }); if (currentCol) { _context.next = 3; break; } throw new Error("The column ".concat(column, " is not in the ").concat(this.tableName(), " table")); case 3: return _context.abrupt("return", currentCol); case 4: case "end": return _context.stop(); } }, _callee, this); })); function getColumn(_x) { return _getColumn.apply(this, arguments); } return getColumn; }() }, { key: "getTableSql", value: function getTableSql() { var _this2 = this; this.trx.disableProcessing(); return this.trx.raw("SELECT name, sql FROM sqlite_master WHERE type=\"table\" AND name=\"".concat(this.tableName(), "\"")).then(function (result) { _this2.trx.enableProcessing(); return result; }); } }, { key: "renameTable", value: function () { var _renameTable = (0, _asyncToGenerator2["default"])(/*#__PURE__*/_regenerator["default"].mark(function _callee2() { return _regenerator["default"].wrap(function _callee2$(_context2) { while (1) switch (_context2.prev = _context2.next) { case 0: return _context2.abrupt("return", this.trx.raw("ALTER TABLE \"".concat(this.tableName(), "\" RENAME TO \"").concat(this.alteredName, "\""))); case 1: case "end": return _context2.stop(); } }, _callee2, this); })); function renameTable() { return _renameTable.apply(this, arguments); } return renameTable; }() }, { key: "dropOriginal", value: function dropOriginal() { return this.trx.raw("DROP TABLE \"".concat(this.tableName(), "\"")); } }, { key: "dropTempTable", value: function dropTempTable() { return this.trx.raw("DROP TABLE \"".concat(this.alteredName, "\"")); } }, { key: "copyData", value: function copyData() { var _this3 = this; return this.trx.raw("SELECT * FROM \"".concat(this.tableName(), "\"")).then(function (result) { return _this3.insertChunked(20, _this3.alteredName, _lodash.identity, result); }); } }, { key: "reinsertData", value: function reinsertData(iterator) { var _this4 = this; return this.trx.raw("SELECT * FROM \"".concat(this.alteredName, "\"")).then(function (result) { return _this4.insertChunked(20, _this4.tableName(), iterator, result); }); } }, { key: "insertChunked", value: function () { var _insertChunked = (0, _asyncToGenerator2["default"])(/*#__PURE__*/_regenerator["default"].mark(function _callee3(chunkSize, target, iterator, result) { var chunked, _iterator, _step, batch; return _regenerator["default"].wrap(function _callee3$(_context3) { while (1) switch (_context3.prev = _context3.next) { case 0: iterator = iterator || _lodash.identity; chunked = (0, _lodash.chunk)(result, chunkSize); _iterator = _createForOfIteratorHelper(chunked); _context3.prev = 3; _iterator.s(); case 5: if ((_step = _iterator.n()).done) { _context3.next = 11; break; } batch = _step.value; _context3.next = 9; return this.trx.queryBuilder().table(target).insert((0, _lodash.map)(batch, iterator)); case 9: _context3.next = 5; break; case 11: _context3.next = 16; break; case 13: _context3.prev = 13; _context3.t0 = _context3["catch"](3); _iterator.e(_context3.t0); case 16: _context3.prev = 16; _iterator.f(); return _context3.finish(16); case 19: case "end": return _context3.stop(); } }, _callee3, this, [[3, 13, 16, 19]]); })); function insertChunked(_x2, _x3, _x4, _x5) { return _insertChunked.apply(this, arguments); } return insertChunked; }() }, { key: "createTempTable", value: function createTempTable(createTable) { return this.trx.raw(createTable.sql.replace(this.tableName(), this.alteredName)); } }, { key: "_doReplace", value: function _doReplace(sql, from, to) { var oneLineSql = sql.replace(/\s+/g, " "); var matched = oneLineSql.match(/^CREATE TABLE\s+(\S+)\s*\((.*)\)/); var tableName = matched[1]; var defs = matched[2]; if (!defs) { throw new Error("No column definitions in this statement!"); } var parens = 0, args = [], ptr = 0; var i = 0; var x = defs.length; for (i = 0; i < x; i++) { switch (defs[i]) { case "(": parens++; break; case ")": parens--; break; case ",": if (parens === 0) { args.push(defs.slice(ptr, i)); ptr = i + 1; } break; case " ": if (ptr === i) { ptr = i + 1; } break; } } args.push(defs.slice(ptr, i)); var fromIdentifier = from.replace(/[`"'[\]]/g, ""); args = args.map(function (item) { item = item.trim(); var split = item.split(" "); var fromMatchCandidates = [new RegExp("`".concat(fromIdentifier, "`"), "i"), new RegExp("\"".concat(fromIdentifier, "\""), "i"), new RegExp("'".concat(fromIdentifier, "'"), "i"), new RegExp("\\[".concat(fromIdentifier, "\\]"), "i")]; if (fromIdentifier.match(/^\S+$/)) { fromMatchCandidates.push(new RegExp("\\b".concat(fromIdentifier, "\\b"), "i")); } var doesMatchFromIdentifier = function doesMatchFromIdentifier(target) { return (0, _lodash.some)(fromMatchCandidates, function (c) { return target.match(c); }); }; var replaceFromIdentifier = function replaceFromIdentifier(target) { return fromMatchCandidates.reduce(function (result, candidate) { return result.replace(candidate, to); }, target); }; if (doesMatchFromIdentifier(split[0])) { // column definition if (to) { split[0] = to; return split.join(" "); } return ""; // for deletions } // skip constraint name var idx = /constraint/i.test(split[0]) ? 2 : 0; // primary key and unique constraints have one or more // columns from this table listed between (); replace // one if it matches if (/primary|unique/i.test(split[idx])) { var ret = item.replace(/\(.*\)/, replaceFromIdentifier); // If any member columns are dropped then uniqueness/pk constraint // can not be retained if (ret !== item && (0, _lodash.isEmpty)(to)) return ""; return ret; } // foreign keys have one or more columns from this table // listed between (); replace one if it matches // foreign keys also have a 'references' clause // which may reference THIS table; if it does, replace // column references in that too! if (/foreign/.test(split[idx])) { split = item.split(/ references /i); // the quoted column names save us from having to do anything // other than a straight replace here var replacedKeySpec = replaceFromIdentifier(split[0]); if (split[0] !== replacedKeySpec) { // If we are removing one or more columns of a foreign // key, then we should not retain the key at all if ((0, _lodash.isEmpty)(to)) return "";else split[0] = replacedKeySpec; } if (split[1].slice(0, tableName.length) === tableName) { // self-referential foreign key var replacedKeyTargetSpec = split[1].replace(/\(.*\)/, replaceFromIdentifier); if (split[1] !== replacedKeyTargetSpec) { // If we are removing one or more columns of a foreign // key, then we should not retain the key at all if ((0, _lodash.isEmpty)(to)) return "";else split[1] = replacedKeyTargetSpec; } } return split.join(" references "); } return item; }); args = args.filter((0, _lodash.negate)(_lodash.isEmpty)); if (args.length === 0) { throw new Error("Unable to drop last column from table"); } return oneLineSql.replace(/\(.*\)/, function () { return "(".concat(args.join(", "), ")"); }).replace(/,\s*([,)])/, "$1"); } }]); }(); var _default = exports["default"] = Firebird_DDL; //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfbG9kYXNoIiwicmVxdWlyZSIsIl9jcmVhdGVGb3JPZkl0ZXJhdG9ySGVscGVyIiwiciIsImUiLCJ0IiwiU3ltYm9sIiwiaXRlcmF0b3IiLCJBcnJheSIsImlzQXJyYXkiLCJfdW5zdXBwb3J0ZWRJdGVyYWJsZVRvQXJyYXkiLCJsZW5ndGgiLCJfbiIsIkYiLCJzIiwibiIsImRvbmUiLCJ2YWx1ZSIsImYiLCJUeXBlRXJyb3IiLCJvIiwiYSIsInUiLCJjYWxsIiwibmV4dCIsIl9hcnJheUxpa2VUb0FycmF5IiwidG9TdHJpbmciLCJzbGljZSIsImNvbnN0cnVjdG9yIiwibmFtZSIsImZyb20iLCJ0ZXN0IiwiRmlyZWJpcmRfRERMIiwiY2xpZW50IiwidGFibGVDb21waWxlciIsInByYWdtYSIsImNvbm5lY3Rpb24iLCJfY2xhc3NDYWxsQ2hlY2syIiwidGFibGVOYW1lUmF3IiwiYWx0ZXJlZE5hbWUiLCJ1bmlxdWVJZCIsImZvcm1hdHRlciIsImNvbmZpZyIsIndyYXBJZGVudGlmaWVyIiwiX2NyZWF0ZUNsYXNzMiIsImtleSIsInRhYmxlTmFtZSIsIl9nZXRDb2x1bW4iLCJfYXN5bmNUb0dlbmVyYXRvcjIiLCJfcmVnZW5lcmF0b3IiLCJtYXJrIiwiX2NhbGxlZSIsImNvbHVtbiIsIl90aGlzIiwiY3VycmVudENvbCIsIndyYXAiLCJfY2FsbGVlJCIsIl9jb250ZXh0IiwicHJldiIsImZpbmQiLCJjb2wiLCJ0b0xvd2VyQ2FzZSIsIkVycm9yIiwiY29uY2F0IiwiYWJydXB0Iiwic3RvcCIsImdldENvbHVtbiIsIl94IiwiYXBwbHkiLCJhcmd1bWVudHMiLCJnZXRUYWJsZVNxbCIsIl90aGlzMiIsInRyeCIsImRpc2FibGVQcm9jZXNzaW5nIiwicmF3IiwidGhlbiIsInJlc3VsdCIsImVuYWJsZVByb2Nlc3NpbmciLCJfcmVuYW1lVGFibGUiLCJfY2FsbGVlMiIsIl9jYWxsZWUyJCIsIl9jb250ZXh0MiIsInJlbmFtZVRhYmxlIiwiZHJvcE9yaWdpbmFsIiwiZHJvcFRlbXBUYWJsZSIsImNvcHlEYXRhIiwiX3RoaXMzIiwiaW5zZXJ0Q2h1bmtlZCIsImlkZW50aXR5IiwicmVpbnNlcnREYXRhIiwiX3RoaXM0IiwiX2luc2VydENodW5rZWQiLCJfY2FsbGVlMyIsImNodW5rU2l6ZSIsInRhcmdldCIsImNodW5rZWQiLCJfaXRlcmF0b3IiLCJfc3RlcCIsImJhdGNoIiwiX2NhbGxlZTMkIiwiX2NvbnRleHQzIiwiY2h1bmsiLCJxdWVyeUJ1aWxkZXIiLCJ0YWJsZSIsImluc2VydCIsIm1hcCIsInQwIiwiZmluaXNoIiwiX3gyIiwiX3gzIiwiX3g0IiwiX3g1IiwiY3JlYXRlVGVtcFRhYmxlIiwiY3JlYXRlVGFibGUiLCJzcWwiLCJyZXBsYWNlIiwiX2RvUmVwbGFjZSIsInRvIiwib25lTGluZVNxbCIsIm1hdGNoZWQiLCJtYXRjaCIsImRlZnMiLCJwYXJlbnMiLCJhcmdzIiwicHRyIiwiaSIsIngiLCJwdXNoIiwiZnJvbUlkZW50aWZpZXIiLCJpdGVtIiwidHJpbSIsInNwbGl0IiwiZnJvbU1hdGNoQ2FuZGlkYXRlcyIsIlJlZ0V4cCIsImRvZXNNYXRjaEZyb21JZGVudGlmaWVyIiwic29tZSIsImMiLCJyZXBsYWNlRnJvbUlkZW50aWZpZXIiLCJyZWR1Y2UiLCJjYW5kaWRhdGUiLCJqb2luIiwiaWR4IiwicmV0IiwiaXNFbXB0eSIsInJlcGxhY2VkS2V5U3BlYyIsInJlcGxhY2VkS2V5VGFyZ2V0U3BlYyIsImZpbHRlciIsIm5lZ2F0ZSIsIl9kZWZhdWx0IiwiZXhwb3J0cyJdLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zY2hlbWEvZGRsLmpzIl0sInNvdXJjZXNDb250ZW50IjpbIi8vIEZpcmViaXJkX0RETFxuLy9cbi8vXG4vLyBjb2x1bW5zIGFuZCBjaGFuZ2luZyBkYXRhdHlwZXMuXG4vLyAtLS0tLS0tXG5cbmltcG9ydCB7XG4gIHVuaXF1ZUlkLFxuICBmaW5kLFxuICBpZGVudGl0eSxcbiAgbWFwLFxuICBzb21lLFxuICBuZWdhdGUsXG4gIGlzRW1wdHksXG4gIGNodW5rLFxufSBmcm9tIFwibG9kYXNoXCI7XG5cbmNsYXNzIEZpcmViaXJkX0RETCB7XG4gIGNvbnN0cnVjdG9yKGNsaWVudCwgdGFibGVDb21waWxlciwgcHJhZ21hLCBjb25uZWN0aW9uKSB7XG4gICAgdGhpcy5jbGllbnQgPSBjbGllbnQ7XG4gICAgdGhpcy50YWJsZUNvbXBpbGVyID0gdGFibGVDb21waWxlcjtcbiAgICB0aGlzLnByYWdtYSA9IHByYWdtYTtcbiAgICB0aGlzLnRhYmxlTmFtZVJhdyA9IHRoaXMudGFibGVDb21waWxlci50YWJsZU5hbWVSYXc7XG4gICAgdGhpcy5hbHRlcmVkTmFtZSA9IHVuaXF1ZUlkKFwiX2tuZXhfdGVtcF9hbHRlclwiKTtcbiAgICB0aGlzLmNvbm5lY3Rpb24gPSBjb25uZWN0aW9uO1xuICAgIHRoaXMuZm9ybWF0dGVyID1cbiAgICAgIGNsaWVudCAmJiBjbGllbnQuY29uZmlnICYmIGNsaWVudC5jb25maWcud3JhcElkZW50aWZpZXJcbiAgICAgICAgPyBjbGllbnQuY29uZmlnLndyYXBJZGVudGlmaWVyXG4gICAgICAgIDogKHZhbHVlKSA9PiB2YWx1ZTtcbiAgfVxuXG4gIHRhYmxlTmFtZSgpIHtcbiAgICByZXR1cm4gdGhpcy5mb3JtYXR0ZXIodGhpcy50YWJsZU5hbWVSYXcsICh2YWx1ZSkgPT4gdmFsdWUpO1xuICB9XG5cbiAgYXN5bmMgZ2V0Q29sdW1uKGNvbHVtbikge1xuICAgIGNvbnN0IGN1cnJlbnRDb2wgPSBmaW5kKHRoaXMucHJhZ21hLCAoY29sKSA9PiB7XG4gICAgICByZXR1cm4gKFxuICAgICAgICB0aGlzLmNsaWVudC53cmFwSWRlbnRpZmllcihjb2wubmFtZSkudG9Mb3dlckNhc2UoKSA9PT1cbiAgICAgICAgdGhpcy5jbGllbnQud3JhcElkZW50aWZpZXIoY29sdW1uKS50b0xvd2VyQ2FzZSgpXG4gICAgICApO1xuICAgIH0pO1xuICAgIGlmICghY3VycmVudENvbClcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgYFRoZSBjb2x1bW4gJHtjb2x1bW59IGlzIG5vdCBpbiB0aGUgJHt0aGlzLnRhYmxlTmFtZSgpfSB0YWJsZWBcbiAgICAgICk7XG4gICAgcmV0dXJuIGN1cnJlbnRDb2w7XG4gIH1cblxuICBnZXRUYWJsZVNxbCgpIHtcbiAgICB0aGlzLnRyeC5kaXNhYmxlUHJvY2Vzc2luZygpO1xuICAgIHJldHVybiB0aGlzLnRyeFxuICAgICAgLnJhdyhcbiAgICAgICAgYFNFTEVDVCBuYW1lLCBzcWwgRlJPTSBzcWxpdGVfbWFzdGVyIFdIRVJFIHR5cGU9XCJ0YWJsZVwiIEFORCBuYW1lPVwiJHt0aGlzLnRhYmxlTmFtZSgpfVwiYFxuICAgICAgKVxuICAgICAgLnRoZW4oKHJlc3VsdCkgPT4ge1xuICAgICAgICB0aGlzLnRyeC5lbmFibGVQcm9jZXNzaW5nKCk7XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9KTtcbiAgfVxuXG4gIGFzeW5jIHJlbmFtZVRhYmxlKCkge1xuICAgIHJldHVybiB0aGlzLnRyeC5yYXcoXG4gICAgICBgQUxURVIgVEFCTEUgXCIke3RoaXMudGFibGVOYW1lKCl9XCIgUkVOQU1FIFRPIFwiJHt0aGlzLmFsdGVyZWROYW1lfVwiYFxuICAgICk7XG4gIH1cblxuICBkcm9wT3JpZ2luYWwoKSB7XG4gICAgcmV0dXJuIHRoaXMudHJ4LnJhdyhgRFJPUCBUQUJMRSBcIiR7dGhpcy50YWJsZU5hbWUoKX1cImApO1xuICB9XG5cbiAgZHJvcFRlbXBUYWJsZSgpIHtcbiAgICByZXR1cm4gdGhpcy50cngucmF3KGBEUk9QIFRBQkxFIFwiJHt0aGlzLmFsdGVyZWROYW1lfVwiYCk7XG4gIH1cblxuICBjb3B5RGF0YSgpIHtcbiAgICByZXR1cm4gdGhpcy50cnhcbiAgICAgIC5yYXcoYFNFTEVDVCAqIEZST00gXCIke3RoaXMudGFibGVOYW1lKCl9XCJgKVxuICAgICAgLnRoZW4oKHJlc3VsdCkgPT5cbiAgICAgICAgdGhpcy5pbnNlcnRDaHVua2VkKDIwLCB0aGlzLmFsdGVyZWROYW1lLCBpZGVudGl0eSwgcmVzdWx0KVxuICAgICAgKTtcbiAgfVxuXG4gIHJlaW5zZXJ0RGF0YShpdGVyYXRvcikge1xuICAgIHJldHVybiB0aGlzLnRyeFxuICAgICAgLnJhdyhgU0VMRUNUICogRlJPTSBcIiR7dGhpcy5hbHRlcmVkTmFtZX1cImApXG4gICAgICAudGhlbigocmVzdWx0KSA9PlxuICAgICAgICB0aGlzLmluc2VydENodW5rZWQoMjAsIHRoaXMudGFibGVOYW1lKCksIGl0ZXJhdG9yLCByZXN1bHQpXG4gICAgICApO1xuICB9XG5cbiAgYXN5bmMgaW5zZXJ0Q2h1bmtlZChjaHVua1NpemUsIHRhcmdldCwgaXRlcmF0b3IsIHJlc3VsdCkge1xuICAgIGl0ZXJhdG9yID0gaXRlcmF0b3IgfHwgaWRlbnRpdHk7XG4gICAgY29uc3QgY2h1bmtlZCA9IGNodW5rKHJlc3VsdCwgY2h1bmtTaXplKTtcbiAgICBmb3IgKGNvbnN0IGJhdGNoIG9mIGNodW5rZWQpIHtcbiAgICAgIGF3YWl0IHRoaXMudHJ4LnF1ZXJ5QnVpbGRlcigpLnRhYmxlKHRhcmdldCkuaW5zZXJ0KG1hcChiYXRjaCwgaXRlcmF0b3IpKTtcbiAgICB9XG4gIH1cblxuICBjcmVhdGVUZW1wVGFibGUoY3JlYXRlVGFibGUpIHtcbiAgICByZXR1cm4gdGhpcy50cngucmF3KFxuICAgICAgY3JlYXRlVGFibGUuc3FsLnJlcGxhY2UodGhpcy50YWJsZU5hbWUoKSwgdGhpcy5hbHRlcmVkTmFtZSlcbiAgICApO1xuICB9XG5cbiAgX2RvUmVwbGFjZShzcWwsIGZyb20sIHRvKSB7XG4gICAgY29uc3Qgb25lTGluZVNxbCA9IHNxbC5yZXBsYWNlKC9cXHMrL2csIFwiIFwiKTtcbiAgICBjb25zdCBtYXRjaGVkID0gb25lTGluZVNxbC5tYXRjaCgvXkNSRUFURSBUQUJMRVxccysoXFxTKylcXHMqXFwoKC4qKVxcKS8pO1xuXG4gICAgY29uc3QgdGFibGVOYW1lID0gbWF0Y2hlZFsxXTtcbiAgICBjb25zdCBkZWZzID0gbWF0Y2hlZFsyXTtcblxuICAgIGlmICghZGVmcykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTm8gY29sdW1uIGRlZmluaXRpb25zIGluIHRoaXMgc3RhdGVtZW50IVwiKTtcbiAgICB9XG5cbiAgICBsZXQgcGFyZW5zID0gMCxcbiAgICAgIGFyZ3MgPSBbXSxcbiAgICAgIHB0ciA9IDA7XG4gICAgbGV0IGkgPSAwO1xuICAgIGNvbnN0IHggPSBkZWZzLmxlbmd0aDtcbiAgICBmb3IgKGkgPSAwOyBpIDwgeDsgaSsrKSB7XG4gICAgICBzd2l0Y2ggKGRlZnNbaV0pIHtcbiAgICAgICAgY2FzZSBcIihcIjpcbiAgICAgICAgICBwYXJlbnMrKztcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBcIilcIjpcbiAgICAgICAgICBwYXJlbnMtLTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBcIixcIjpcbiAgICAgICAgICBpZiAocGFyZW5zID09PSAwKSB7XG4gICAgICAgICAgICBhcmdzLnB1c2goZGVmcy5zbGljZShwdHIsIGkpKTtcbiAgICAgICAgICAgIHB0ciA9IGkgKyAxO1xuICAgICAgICAgIH1cbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBcIiBcIjpcbiAgICAgICAgICBpZiAocHRyID09PSBpKSB7XG4gICAgICAgICAgICBwdHIgPSBpICsgMTtcbiAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuICAgIGFyZ3MucHVzaChkZWZzLnNsaWNlKHB0ciwgaSkpO1xuXG4gICAgY29uc3QgZnJvbUlkZW50aWZpZXIgPSBmcm9tLnJlcGxhY2UoL1tgXCInW1xcXV0vZywgXCJcIik7XG5cbiAgICBhcmdzID0gYXJncy5tYXAoKGl0ZW0pID0+IHtcbiAgICAgIGl0ZW0gPSBpdGVtLnRyaW0oKTtcbiAgICAgIGxldCBzcGxpdCA9IGl0ZW0uc3BsaXQoXCIgXCIpO1xuXG4gICAgICBjb25zdCBmcm9tTWF0Y2hDYW5kaWRhdGVzID0gW1xuICAgICAgICBuZXcgUmVnRXhwKGBcXGAke2Zyb21JZGVudGlmaWVyfVxcYGAsIFwiaVwiKSxcbiAgICAgICAgbmV3IFJlZ0V4cChgXCIke2Zyb21JZGVudGlmaWVyfVwiYCwgXCJpXCIpLFxuICAgICAgICBuZXcgUmVnRXhwKGAnJHtmcm9tSWRlbnRpZmllcn0nYCwgXCJpXCIpLFxuICAgICAgICBuZXcgUmVnRXhwKGBcXFxcWyR7ZnJvbUlkZW50aWZpZXJ9XFxcXF1gLCBcImlcIiksXG4gICAgICBdO1xuICAgICAgaWYgKGZyb21JZGVudGlmaWVyLm1hdGNoKC9eXFxTKyQvKSkge1xuICAgICAgICBmcm9tTWF0Y2hDYW5kaWRhdGVzLnB1c2gobmV3IFJlZ0V4cChgXFxcXGIke2Zyb21JZGVudGlmaWVyfVxcXFxiYCwgXCJpXCIpKTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgZG9lc01hdGNoRnJvbUlkZW50aWZpZXIgPSAodGFyZ2V0KSA9PlxuICAgICAgICBzb21lKGZyb21NYXRjaENhbmRpZGF0ZXMsIChjKSA9PiB0YXJnZXQubWF0Y2goYykpO1xuXG4gICAgICBjb25zdCByZXBsYWNlRnJvbUlkZW50aWZpZXIgPSAodGFyZ2V0KSA9PlxuICAgICAgICBmcm9tTWF0Y2hDYW5kaWRhdGVzLnJlZHVjZShcbiAgICAgICAgICAocmVzdWx0LCBjYW5kaWRhdGUpID0+IHJlc3VsdC5yZXBsYWNlKGNhbmRpZGF0ZSwgdG8pLFxuICAgICAgICAgIHRhcmdldFxuICAgICAgICApO1xuXG4gICAgICBpZiAoZG9lc01hdGNoRnJvbUlkZW50aWZpZXIoc3BsaXRbMF0pKSB7XG4gICAgICAgIC8vIGNvbHVtbiBkZWZpbml0aW9uXG4gICAgICAgIGlmICh0bykge1xuICAgICAgICAgIHNwbGl0WzBdID0gdG87XG4gICAgICAgICAgcmV0dXJuIHNwbGl0LmpvaW4oXCIgXCIpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBcIlwiOyAvLyBmb3IgZGVsZXRpb25zXG4gICAgICB9XG5cbiAgICAgIC8vIHNraXAgY29uc3RyYWludCBuYW1lXG4gICAgICBjb25zdCBpZHggPSAvY29uc3RyYWludC9pLnRlc3Qoc3BsaXRbMF0pID8gMiA6IDA7XG5cbiAgICAgIC8vIHByaW1hcnkga2V5IGFuZCB1bmlxdWUgY29uc3RyYWludHMgaGF2ZSBvbmUgb3IgbW9yZVxuICAgICAgLy8gY29sdW1ucyBmcm9tIHRoaXMgdGFibGUgbGlzdGVkIGJldHdlZW4gKCk7IHJlcGxhY2VcbiAgICAgIC8vIG9uZSBpZiBpdCBtYXRjaGVzXG4gICAgICBpZiAoL3ByaW1hcnl8dW5pcXVlL2kudGVzdChzcGxpdFtpZHhdKSkge1xuICAgICAgICBjb25zdCByZXQgPSBpdGVtLnJlcGxhY2UoL1xcKC4qXFwpLywgcmVwbGFjZUZyb21JZGVudGlmaWVyKTtcbiAgICAgICAgLy8gSWYgYW55IG1lbWJlciBjb2x1bW5zIGFyZSBkcm9wcGVkIHRoZW4gdW5pcXVlbmVzcy9wayBjb25zdHJhaW50XG4gICAgICAgIC8vIGNhbiBub3QgYmUgcmV0YWluZWRcbiAgICAgICAgaWYgKHJldCAhPT0gaXRlbSAmJiBpc0VtcHR5KHRvKSkgcmV0dXJuIFwiXCI7XG4gICAgICAgIHJldHVybiByZXQ7XG4gICAgICB9XG5cbiAgICAgIC8vIGZvcmVpZ24ga2V5cyBoYXZlIG9uZSBvciBtb3JlIGNvbHVtbnMgZnJvbSB0aGlzIHRhYmxlXG4gICAgICAvLyBsaXN0ZWQgYmV0d2VlbiAoKTsgcmVwbGFjZSBvbmUgaWYgaXQgbWF0Y2hlc1xuICAgICAgLy8gZm9yZWlnbiBrZXlzIGFsc28gaGF2ZSBhICdyZWZlcmVuY2VzJyBjbGF1c2VcbiAgICAgIC8vIHdoaWNoIG1heSByZWZlcmVuY2UgVEhJUyB0YWJsZTsgaWYgaXQgZG9lcywgcmVwbGFjZVxuICAgICAgLy8gY29sdW1uIHJlZmVyZW5jZXMgaW4gdGhhdCB0b28hXG4gICAgICBpZiAoL2ZvcmVpZ24vLnRlc3Qoc3BsaXRbaWR4XSkpIHtcbiAgICAgICAgc3BsaXQgPSBpdGVtLnNwbGl0KC8gcmVmZXJlbmNlcyAvaSk7XG4gICAgICAgIC8vIHRoZSBxdW90ZWQgY29sdW1uIG5hbWVzIHNhdmUgdXMgZnJvbSBoYXZpbmcgdG8gZG8gYW55dGhpbmdcbiAgICAgICAgLy8gb3RoZXIgdGhhbiBhIHN0cmFpZ2h0IHJlcGxhY2UgaGVyZVxuICAgICAgICBjb25zdCByZXBsYWNlZEtleVNwZWMgPSByZXBsYWNlRnJvbUlkZW50aWZpZXIoc3BsaXRbMF0pO1xuXG4gICAgICAgIGlmIChzcGxpdFswXSAhPT0gcmVwbGFjZWRLZXlTcGVjKSB7XG4gICAgICAgICAgLy8gSWYgd2UgYXJlIHJlbW92aW5nIG9uZSBvciBtb3JlIGNvbHVtbnMgb2YgYSBmb3JlaWduXG4gICAgICAgICAgLy8ga2V5LCB0aGVuIHdlIHNob3VsZCBub3QgcmV0YWluIHRoZSBrZXkgYXQgYWxsXG4gICAgICAgICAgaWYgKGlzRW1wdHkodG8pKSByZXR1cm4gXCJcIjtcbiAgICAgICAgICBlbHNlIHNwbGl0WzBdID0gcmVwbGFjZWRLZXlTcGVjO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHNwbGl0WzFdLnNsaWNlKDAsIHRhYmxlTmFtZS5sZW5ndGgpID09PSB0YWJsZU5hbWUpIHtcbiAgICAgICAgICAvLyBzZWxmLXJlZmVyZW50aWFsIGZvcmVpZ24ga2V5XG4gICAgICAgICAgY29uc3QgcmVwbGFjZWRLZXlUYXJnZXRTcGVjID0gc3BsaXRbMV0ucmVwbGFjZShcbiAgICAgICAgICAgIC9cXCguKlxcKS8sXG4gICAgICAgICAgICByZXBsYWNlRnJvbUlkZW50aWZpZXJcbiAgICAgICAgICApO1xuICAgICAgICAgIGlmIChzcGxpdFsxXSAhPT0gcmVwbGFjZWRLZXlUYXJnZXRTcGVjKSB7XG4gICAgICAgICAgICAvLyBJZiB3ZSBhcmUgcmVtb3Zpbmcgb25lIG9yIG1vcmUgY29sdW1ucyBvZiBhIGZvcmVpZ25cbiAgICAgICAgICAgIC8vIGtleSwgdGhlbiB3ZSBzaG91bGQgbm90IHJldGFpbiB0aGUga2V5IGF0IGFsbFxuICAgICAgICAgICAgaWYgKGlzRW1wdHkodG8pKSByZXR1cm4gXCJcIjtcbiAgICAgICAgICAgIGVsc2Ugc3BsaXRbMV0gPSByZXBsYWNlZEtleVRhcmdldFNwZWM7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBzcGxpdC5qb2luKFwiIHJlZmVyZW5jZXMgXCIpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gaXRlbTtcbiAgICB9KTtcblxuICAgIGFyZ3MgPSBhcmdzLmZpbHRlcihuZWdhdGUoaXNFbXB0eSkpO1xuXG4gICAgaWYgKGFyZ3MubGVuZ3RoID09PSAwKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJVbmFibGUgdG8gZHJvcCBsYXN0IGNvbHVtbiBmcm9tIHRhYmxlXCIpO1xuICAgIH1cblxuICAgIHJldHVybiBvbmVMaW5lU3FsXG4gICAgICAucmVwbGFjZSgvXFwoLipcXCkvLCAoKSA9PiBgKCR7YXJncy5qb2luKFwiLCBcIil9KWApXG4gICAgICAucmVwbGFjZSgvLFxccyooWywpXSkvLCBcIiQxXCIpO1xuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IEZpcmViaXJkX0RETDtcbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7QUFNQSxJQUFBQSxPQUFBLEdBQUFDLE9BQUE7QUFTZ0IsU0FBQUMsMkJBQUFDLENBQUEsRUFBQUMsQ0FBQSxRQUFBQyxDQUFBLHlCQUFBQyxNQUFBLElBQUFILENBQUEsQ0FBQUcsTUFBQSxDQUFBQyxRQUFBLEtBQUFKLENBQUEscUJBQUFFLENBQUEsUUFBQUcsS0FBQSxDQUFBQyxPQUFBLENBQUFOLENBQUEsTUFBQUUsQ0FBQSxHQUFBSywyQkFBQSxDQUFBUCxDQUFBLE1BQUFDLENBQUEsSUFBQUQsQ0FBQSx1QkFBQUEsQ0FBQSxDQUFBUSxNQUFBLElBQUFOLENBQUEsS0FBQUYsQ0FBQSxHQUFBRSxDQUFBLE9BQUFPLEVBQUEsTUFBQUMsQ0FBQSxZQUFBQSxFQUFBLGVBQUFDLENBQUEsRUFBQUQsQ0FBQSxFQUFBRSxDQUFBLFdBQUFBLEVBQUEsV0FBQUgsRUFBQSxJ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