objection
Version:
An SQL-friendly ORM for Node.js
502 lines (374 loc) • 48.6 kB
JavaScript
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = undefined;
var _getOwnPropertyDescriptor = require('babel-runtime/core-js/object/get-own-property-descriptor');
var _getOwnPropertyDescriptor2 = _interopRequireDefault(_getOwnPropertyDescriptor);
var _keys = require('babel-runtime/core-js/object/keys');
var _keys2 = _interopRequireDefault(_keys);
var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');
var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn');
var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2);
var _inherits2 = require('babel-runtime/helpers/inherits');
var _inherits3 = _interopRequireDefault(_inherits2);
var _desc, _value, _class;
var _lodash = require('lodash');
var _lodash2 = _interopRequireDefault(_lodash);
var _Relation2 = require('../Relation');
var _Relation3 = _interopRequireDefault(_Relation2);
var _inheritModel = require('../../model/inheritModel');
var _inheritModel2 = _interopRequireDefault(_inheritModel);
var _dbUtils = require('../../utils/dbUtils');
var _memoize = require('../../utils/decorators/memoize');
var _memoize2 = _interopRequireDefault(_memoize);
var _ManyToManyFindOperation = require('./ManyToManyFindOperation');
var _ManyToManyFindOperation2 = _interopRequireDefault(_ManyToManyFindOperation);
var _ManyToManyInsertOperation = require('./ManyToManyInsertOperation');
var _ManyToManyInsertOperation2 = _interopRequireDefault(_ManyToManyInsertOperation);
var _ManyToManyRelateOperation = require('./ManyToManyRelateOperation');
var _ManyToManyRelateOperation2 = _interopRequireDefault(_ManyToManyRelateOperation);
var _ManyToManyUnrelateOperation = require('./ManyToManyUnrelateOperation');
var _ManyToManyUnrelateOperation2 = _interopRequireDefault(_ManyToManyUnrelateOperation);
var _ManyToManyUnrelateSqliteOperation = require('./ManyToManyUnrelateSqliteOperation');
var _ManyToManyUnrelateSqliteOperation2 = _interopRequireDefault(_ManyToManyUnrelateSqliteOperation);
var _ManyToManyUpdateOperation = require('./ManyToManyUpdateOperation');
var _ManyToManyUpdateOperation2 = _interopRequireDefault(_ManyToManyUpdateOperation);
var _ManyToManyUpdateSqliteOperation = require('./ManyToManyUpdateSqliteOperation');
var _ManyToManyUpdateSqliteOperation2 = _interopRequireDefault(_ManyToManyUpdateSqliteOperation);
var _ManyToManyDeleteOperation = require('./ManyToManyDeleteOperation');
var _ManyToManyDeleteOperation2 = _interopRequireDefault(_ManyToManyDeleteOperation);
var _ManyToManyDeleteSqliteOperation = require('./ManyToManyDeleteSqliteOperation');
var _ManyToManyDeleteSqliteOperation2 = _interopRequireDefault(_ManyToManyDeleteSqliteOperation);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _applyDecoratedDescriptor(target, property, decorators, descriptor, context) {
var desc = {};
Object['ke' + 'ys'](descriptor).forEach(function (key) {
desc[key] = descriptor[key];
});
desc.enumerable = !!desc.enumerable;
desc.configurable = !!desc.configurable;
if ('value' in desc || desc.initializer) {
desc.writable = true;
}
desc = decorators.slice().reverse().reduce(function (desc, decorator) {
return decorator(target, property, desc) || desc;
}, desc);
if (context && desc.initializer !== void 0) {
desc.value = desc.initializer ? desc.initializer.call(context) : void 0;
desc.initializer = undefined;
}
if (desc.initializer === void 0) {
Object['define' + 'Property'](target, property, desc);
desc = null;
}
return desc;
}
var sqliteBuiltInRowId = '_rowid_';
var ManyToManyRelation = (_class = function (_Relation) {
(0, _inherits3.default)(ManyToManyRelation, _Relation);
function ManyToManyRelation() {
(0, _classCallCheck3.default)(this, ManyToManyRelation);
return (0, _possibleConstructorReturn3.default)(this, _Relation.apply(this, arguments));
}
ManyToManyRelation.prototype.setMapping = function setMapping(mapping) {
var retVal = _Relation.prototype.setMapping.call(this, mapping);
// Avoid require loop and import here.
var Model = require(__dirname + '/../../model/Model').default;
if (!_lodash2.default.isObject(mapping.join.through)) {
this.throwError('join must have the `through` that describes the join table.');
}
if (!mapping.join.through.from || !mapping.join.through.to) {
this.throwError('join.through must be an object that describes the join table. For example: {from: "JoinTable.someId", to: "JoinTable.someOtherId"}');
}
var joinFrom = this.parseReference(mapping.join.from);
var joinTableFrom = this.parseReference(mapping.join.through.from);
var joinTableTo = this.parseReference(mapping.join.through.to);
var joinTableExtra = mapping.join.through.extra || [];
if (!joinTableFrom.table || _lodash2.default.isEmpty(joinTableFrom.columns)) {
this.throwError('join.through.from must have format JoinTable.columnName. For example "JoinTable.someId" or in case of composite key ["JoinTable.a", "JoinTable.b"].');
}
if (!joinTableTo.table || _lodash2.default.isEmpty(joinTableTo.columns)) {
this.throwError('join.through.to must have format JoinTable.columnName. For example "JoinTable.someId" or in case of composite key ["JoinTable.a", "JoinTable.b"].');
}
if (joinTableFrom.table !== joinTableTo.table) {
this.throwError('join.through `from` and `to` must point to the same join table.');
}
this.joinTable = joinTableFrom.table;
if (joinFrom.table === this.ownerModelClass.tableName) {
this.joinTableOwnerCol = joinTableFrom.columns;
this.joinTableRelatedCol = joinTableTo.columns;
} else {
this.joinTableRelatedCol = joinTableFrom.columns;
this.joinTableOwnerCol = joinTableTo.columns;
}
if (mapping.join.through.modelClass) {
this._joinTableModelClass = this.resolveModel(Model, mapping.join.through.modelClass, 'join.through.modelClass');
} else {
this._joinTableModelClass = (0, _inheritModel2.default)(Model);
this._joinTableModelClass.tableName = this.joinTable;
// We cannot know if the join table has a primary key. Therefore we set some
// known column as the idColumn so that inserts will work.
this._joinTableModelClass.idColumn = this.joinTableRelatedCol;
}
this.joinTableOwnerProp = this.propertyName(this.joinTableOwnerCol, this._joinTableModelClass);
this.joinTableRelatedProp = this.propertyName(this.joinTableRelatedCol, this._joinTableModelClass);
this.joinTableExtras = this.parseExtras(joinTableExtra);
return retVal;
};
/**
* @returns {Array.<string>}
*/
ManyToManyRelation.prototype.fullJoinTableOwnerCol = function fullJoinTableOwnerCol() {
var _this2 = this;
return this.joinTableOwnerCol.map(function (col) {
return _this2.joinTable + '.' + col;
});
};
/**
* @returns {Array.<string>}
*/
ManyToManyRelation.prototype.fullJoinTableRelatedCol = function fullJoinTableRelatedCol() {
var _this3 = this;
return this.joinTableRelatedCol.map(function (col) {
return _this3.joinTable + '.' + col;
});
};
/**
* @returns {string}
*/
ManyToManyRelation.prototype.joinTableAlias = function joinTableAlias() {
return this.joinTable + '_rel_' + this.name;
};
/**
* @returns {ManyToManyRelation}
*/
ManyToManyRelation.prototype.bindKnex = function bindKnex(knex) {
var bound = _Relation.prototype.bindKnex.call(this, knex);
bound._joinTableModelClass = this._joinTableModelClass.bindKnex(knex);
return bound;
};
/**
* @returns {QueryBuilder}
*/
ManyToManyRelation.prototype.findQuery = function findQuery(builder, opt) {
var _this4 = this;
builder.join(this.joinTable, function (join) {
var fullRelatedCol = _this4.fullRelatedCol();
var fullJoinTableRelatedCol = _this4.fullJoinTableRelatedCol();
for (var i = 0, l = fullJoinTableRelatedCol.length; i < l; ++i) {
join.on(fullJoinTableRelatedCol[i], fullRelatedCol[i]);
}
});
if (opt.isColumnRef) {
var fullJoinTableOwnerCol = this.fullJoinTableOwnerCol();
for (var i = 0, l = fullJoinTableOwnerCol.length; i < l; ++i) {
builder.whereRef(fullJoinTableOwnerCol[i], opt.ownerIds[i]);
}
} else {
var hasIds = false;
for (var _i = 0, _l = opt.ownerIds.length; _i < _l; ++_i) {
var id = opt.ownerIds[_i];
if (id) {
hasIds = true;
break;
}
}
if (hasIds) {
builder.whereInComposite(this.fullJoinTableOwnerCol(), opt.ownerIds);
} else {
builder.resolve([]);
}
}
return builder.modify(this.modify);
};
/**
* @returns {QueryBuilder}
*/
ManyToManyRelation.prototype.join = function join(builder, opt) {
opt = opt || {};
opt.joinOperation = opt.joinOperation || 'join';
opt.relatedTableAlias = opt.relatedTableAlias || this.relatedTableAlias();
opt.relatedJoinSelectQuery = opt.relatedJoinSelectQuery || this.relatedModelClass.query().childQueryOf(builder);
opt.relatedTable = opt.relatedTable || this.relatedModelClass.tableName;
opt.ownerTable = opt.ownerTable || this.ownerModelClass.tableName;
opt.joinTableAlias = opt.joinTableAlias || opt.relatedTableAlias + '_join';
var joinTableAsAlias = this.joinTable + ' as ' + opt.joinTableAlias;
var joinTableOwnerCol = this.joinTableOwnerCol.map(function (col) {
return opt.joinTableAlias + '.' + col;
});
var joinTableRelatedCol = this.joinTableRelatedCol.map(function (col) {
return opt.joinTableAlias + '.' + col;
});
var relatedCol = this.relatedCol.map(function (col) {
return opt.relatedTableAlias + '.' + col;
});
var ownerCol = this.ownerCol.map(function (col) {
return opt.ownerTable + '.' + col;
});
var relatedJoinSelect = opt.relatedJoinSelectQuery.modify(this.modify).as(opt.relatedTableAlias);
if (relatedJoinSelect.isSelectAll()) {
// No need to join a subquery if the query is `select * from "RelatedTable"`.
relatedJoinSelect = this.relatedModelClass.tableName + ' as ' + opt.relatedTableAlias;
}
return builder[opt.joinOperation](joinTableAsAlias, function (join) {
for (var i = 0, l = joinTableOwnerCol.length; i < l; ++i) {
join.on(joinTableOwnerCol[i], ownerCol[i]);
}
})[opt.joinOperation](relatedJoinSelect, function (join) {
for (var i = 0, l = joinTableRelatedCol.length; i < l; ++i) {
join.on(joinTableRelatedCol[i], relatedCol[i]);
}
});
};
ManyToManyRelation.prototype.find = function find(builder, owners) {
return new _ManyToManyFindOperation2.default('find', {
relation: this,
owners: owners
});
};
ManyToManyRelation.prototype.insert = function insert(builder, owner) {
return new _ManyToManyInsertOperation2.default('insert', {
relation: this,
owner: owner
});
};
ManyToManyRelation.prototype.update = function update(builder, owner) {
if ((0, _dbUtils.isSqlite)(builder.knex())) {
return new _ManyToManyUpdateSqliteOperation2.default('update', {
relation: this,
owner: owner
});
} else {
return new _ManyToManyUpdateOperation2.default('update', {
relation: this,
owner: owner
});
}
};
ManyToManyRelation.prototype.patch = function patch(builder, owner) {
if ((0, _dbUtils.isSqlite)(builder.knex())) {
return new _ManyToManyUpdateSqliteOperation2.default('patch', {
relation: this,
owner: owner,
modelOptions: { patch: true }
});
} else {
return new _ManyToManyUpdateOperation2.default('patch', {
relation: this,
owner: owner,
modelOptions: { patch: true }
});
}
};
ManyToManyRelation.prototype.delete = function _delete(builder, owner) {
if ((0, _dbUtils.isSqlite)(builder.knex())) {
return new _ManyToManyDeleteSqliteOperation2.default('delete', {
relation: this,
owner: owner
});
} else {
return new _ManyToManyDeleteOperation2.default('delete', {
relation: this,
owner: owner
});
}
};
ManyToManyRelation.prototype.relate = function relate(builder, owner) {
return new _ManyToManyRelateOperation2.default('relate', {
relation: this,
owner: owner
});
};
ManyToManyRelation.prototype.unrelate = function unrelate(builder, owner) {
if ((0, _dbUtils.isSqlite)(builder.knex())) {
return new _ManyToManyUnrelateSqliteOperation2.default('unrelate', {
relation: this,
owner: owner
});
} else {
return new _ManyToManyUnrelateOperation2.default('unrelate', {
relation: this,
owner: owner
});
}
};
ManyToManyRelation.prototype.selectForModify = function selectForModify(builder, owner) {
var ownerId = owner.$values(this.ownerProp);
var idQuery = this.joinTableModelClass(builder.knex()).query().childQueryOf(builder).select(this.fullJoinTableRelatedCol()).whereComposite(this.fullJoinTableOwnerCol(), ownerId);
return builder.whereInComposite(this.fullRelatedCol(), idQuery);
};
ManyToManyRelation.prototype.selectForModifySqlite = function selectForModifySqlite(builder, owner) {
var _this5 = this;
var relatedTable = this.relatedModelClass.tableName;
var relatedTableAlias = this.relatedTableAlias();
var relatedTableAsAlias = relatedTable + ' as ' + relatedTableAlias;
var relatedTableAliasRowId = relatedTableAlias + '.' + sqliteBuiltInRowId;
var relatedTableRowId = relatedTable + '.' + sqliteBuiltInRowId;
var selectRelatedQuery = this.joinTableModelClass(builder.knex()).query().childQueryOf(builder).select(relatedTableAliasRowId).whereComposite(this.fullJoinTableOwnerCol(), owner.$values(this.ownerProp)).join(relatedTableAsAlias, function (join) {
var fullJoinTableRelatedCols = _this5.fullJoinTableRelatedCol();
var fullRelatedCol = _this5.fullRelatedCol();
for (var i = 0, l = fullJoinTableRelatedCols.length; i < l; ++i) {
join.on(fullJoinTableRelatedCols[i], fullRelatedCol[i]);
}
});
return builder.whereInComposite(relatedTableRowId, selectRelatedQuery);
};
ManyToManyRelation.prototype.createJoinModels = function createJoinModels(ownerId, related) {
var joinModels = new Array(related.length);
for (var i = 0, lr = related.length; i < lr; ++i) {
var rel = related[i];
var joinModel = {};
for (var j = 0, lp = this.joinTableOwnerProp.length; j < lp; ++j) {
joinModel[this.joinTableOwnerProp[j]] = ownerId[j];
}
for (var _j = 0, _lp = this.joinTableRelatedProp.length; _j < _lp; ++_j) {
joinModel[this.joinTableRelatedProp[_j]] = rel[this.relatedProp[_j]];
}
for (var _j2 = 0, _lp2 = this.joinTableExtras.length; _j2 < _lp2; ++_j2) {
var extra = this.joinTableExtras[_j2];
var extraValue = rel[extra.aliasProp];
if (!_lodash2.default.isUndefined(extraValue)) {
joinModel[extra.joinTableProp] = extraValue;
}
}
joinModels[i] = joinModel;
}
return joinModels;
};
ManyToManyRelation.prototype.omitExtraProps = function omitExtraProps(models) {
if (!_lodash2.default.isEmpty(this.joinTableExtras)) {
var props = this.joinTableExtras.map(function (extra) {
return extra.aliasProp;
});
for (var i = 0, l = models.length; i < l; ++i) {
models[i].$omitFromDatabaseJson(props);
}
}
};
/**
* @protected
*/
ManyToManyRelation.prototype.parseExtras = function parseExtras(extras) {
var _this6 = this;
if (Array.isArray(extras)) {
extras = extras.reduce(function (extras, col) {
extras[col] = col;
return extras;
}, {});
}
return (0, _keys2.default)(extras).map(function (key) {
var val = extras[key];
return {
joinTableCol: val,
joinTableProp: _this6._joinTableModelClass.columnNameToPropertyName(val),
aliasCol: key,
aliasProp: _this6._joinTableModelClass.columnNameToPropertyName(key)
};
});
};
return ManyToManyRelation;
}(_Relation3.default), (_applyDecoratedDescriptor(_class.prototype, 'fullJoinTableOwnerCol', [_memoize2.default], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'fullJoinTableOwnerCol'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'fullJoinTableRelatedCol', [_memoize2.default], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'fullJoinTableRelatedCol'), _class.prototype)), _class);
exports.default = ManyToManyRelation;
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIk1hbnlUb01hbnlSZWxhdGlvbi5qcyJdLCJuYW1lcyI6WyJzcWxpdGVCdWlsdEluUm93SWQiLCJNYW55VG9NYW55UmVsYXRpb24iLCJzZXRNYXBwaW5nIiwibWFwcGluZyIsInJldFZhbCIsIk1vZGVsIiwicmVxdWlyZSIsIl9fZGlybmFtZSIsImRlZmF1bHQiLCJpc09iamVjdCIsImpvaW4iLCJ0aHJvdWdoIiwidGhyb3dFcnJvciIsImZyb20iLCJ0byIsImpvaW5Gcm9tIiwicGFyc2VSZWZlcmVuY2UiLCJqb2luVGFibGVGcm9tIiwiam9pblRhYmxlVG8iLCJqb2luVGFibGVFeHRyYSIsImV4dHJhIiwidGFibGUiLCJpc0VtcHR5IiwiY29sdW1ucyIsImpvaW5UYWJsZSIsIm93bmVyTW9kZWxDbGFzcyIsInRhYmxlTmFtZSIsImpvaW5UYWJsZU93bmVyQ29sIiwiam9pblRhYmxlUmVsYXRlZENvbCIsIm1vZGVsQ2xhc3MiLCJfam9pblRhYmxlTW9kZWxDbGFzcyIsInJlc29sdmVNb2RlbCIsImlkQ29sdW1uIiwiam9pblRhYmxlT3duZXJQcm9wIiwicHJvcGVydHlOYW1lIiwiam9pblRhYmxlUmVsYXRlZFByb3AiLCJqb2luVGFibGVFeHRyYXMiLCJwYXJzZUV4dHJhcyIsImZ1bGxKb2luVGFibGVPd25lckNvbCIsIm1hcCIsImNvbCIsImZ1bGxKb2luVGFibGVSZWxhdGVkQ29sIiwiam9pblRhYmxlQWxpYXMiLCJuYW1lIiwiYmluZEtuZXgiLCJrbmV4IiwiYm91bmQiLCJmaW5kUXVlcnkiLCJidWlsZGVyIiwib3B0IiwiZnVsbFJlbGF0ZWRDb2wiLCJpIiwibCIsImxlbmd0aCIsIm9uIiwiaXNDb2x1bW5SZWYiLCJ3aGVyZVJlZiIsIm93bmVySWRzIiwiaGFzSWRzIiwiaWQiLCJ3aGVyZUluQ29tcG9zaXRlIiwicmVzb2x2ZSIsIm1vZGlmeSIsImpvaW5PcGVyYXRpb24iLCJyZWxhdGVkVGFibGVBbGlhcyIsInJlbGF0ZWRKb2luU2VsZWN0UXVlcnkiLCJyZWxhdGVkTW9kZWxDbGFzcyIsInF1ZXJ5IiwiY2hpbGRRdWVyeU9mIiwicmVsYXRlZFRhYmxlIiwib3duZXJUYWJsZSIsImpvaW5UYWJsZUFzQWxpYXMiLCJyZWxhdGVkQ29sIiwib3duZXJDb2wiLCJyZWxhdGVkSm9pblNlbGVjdCIsImFzIiwiaXNTZWxlY3RBbGwiLCJmaW5kIiwib3duZXJzIiwicmVsYXRpb24iLCJpbnNlcnQiLCJvd25lciIsInVwZGF0ZSIsInBhdGNoIiwibW9kZWxPcHRpb25zIiwiZGVsZXRlIiwicmVsYXRlIiwidW5yZWxhdGUiLCJzZWxlY3RGb3JNb2RpZnkiLCJvd25lcklkIiwiJHZhbHVlcyIsIm93bmVyUHJvcCIsImlkUXVlcnkiLCJqb2luVGFibGVNb2RlbENsYXNzIiwic2VsZWN0Iiwid2hlcmVDb21wb3NpdGUiLCJzZWxlY3RGb3JNb2RpZnlTcWxpdGUiLCJyZWxhdGVkVGFibGVBc0FsaWFzIiwicmVsYXRlZFRhYmxlQWxpYXNSb3dJZCIsInJlbGF0ZWRUYWJsZVJvd0lkIiwic2VsZWN0UmVsYXRlZFF1ZXJ5IiwiZnVsbEpvaW5UYWJsZVJlbGF0ZWRDb2xzIiwiY3JlYXRlSm9pbk1vZGVscyIsInJlbGF0ZWQiLCJqb2luTW9kZWxzIiwiQXJyYXkiLCJsciIsInJlbCIsImpvaW5Nb2RlbCIsImoiLCJscCIsInJlbGF0ZWRQcm9wIiwiZXh0cmFWYWx1ZSIsImFsaWFzUHJvcCIsImlzVW5kZWZpbmVkIiwiam9pblRhYmxlUHJvcCIsIm9taXRFeHRyYVByb3BzIiwibW9kZWxzIiwicHJvcHMiLCIkb21pdEZyb21EYXRhYmFzZUpzb24iLCJleHRyYXMiLCJpc0FycmF5IiwicmVkdWNlIiwidmFsIiwia2V5Iiwiam9pblRhYmxlQ29sIiwiY29sdW1uTmFtZVRvUHJvcGVydHlOYW1lIiwiYWxpYXNDb2wiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUE7Ozs7QUFDQTs7OztBQUNBOzs7O0FBQ0E7O0FBQ0E7Ozs7QUFFQTs7OztBQUNB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QyxFQUEwQyxFQUFFRCxDQUE1QyxFQUErQztBQUM3Q2tFLGVBQU9sRSxDQUFQLEVBQVVvRSxxQkFBVixDQUFnQ0QsS0FBaEM7QUFDRDtBQUNGO0FBQ0YsRzs7QUFFRDs7Ozs7K0JBR0FqRixXLHdCQUFZbUYsTSxFQUFRO0FBQUE7O0FBQ2xCLFFBQUlmLE1BQU1nQixPQUFOLENBQWNELE1BQWQsQ0FBSixFQUEyQjtBQUN6QkEsZUFBU0EsT0FBT0UsTUFBUCxDQUFjLFVBQUNGLE1BQUQsRUFBU2hGLEdBQVQsRUFBaUI7QUFDdENnRixlQUFPaEYsR0FBUCxJQUFjQSxHQUFkO0FBQ0EsZUFBT2dGLE1BQVA7QUFDRCxPQUhRLEVBR04sRUFITSxDQUFUO0FBSUQ7O0FBRUQsV0FBTyxvQkFBWUEsTUFBWixFQUFvQmpGLEdBQXBCLENBQXdCLGVBQU87QUFDcEMsVUFBTW9GLE1BQU1ILE9BQU9JLEdBQVAsQ0FBWjs7QUFFQSxhQUFPO0FBQ0xDLHNCQUFjRixHQURUO0FBRUxSLHVCQUFlLE9BQUtyRixvQkFBTCxDQUEwQmdHLHdCQUExQixDQUFtREgsR0FBbkQsQ0FGVjtBQUdMSSxrQkFBVUgsR0FITDtBQUlMWCxtQkFBVyxPQUFLbkYsb0JBQUwsQ0FBMEJnRyx3QkFBMUIsQ0FBbURGLEdBQW5EO0FBSk4sT0FBUDtBQU1ELEtBVE0sQ0FBUDtBQVVELEc7Ozs7a0JBL1ZrQjNILGtCIiwiZmlsZSI6Ik1hbnlUb01hbnlSZWxhdGlvbi5qcyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBfIGZyb20gJ2xvZGFzaCc7XG5pbXBvcnQgUmVsYXRpb24gZnJvbSAnLi4vUmVsYXRpb24nO1xuaW1wb3J0IGluaGVyaXRNb2RlbCBmcm9tICcuLi8uLi9tb2RlbC9pbmhlcml0TW9kZWwnO1xuaW1wb3J0IHtpc1NxbGl0ZX0gZnJvbSAnLi4vLi4vdXRpbHMvZGJVdGlscyc7XG5pbXBvcnQgbWVtb2l6ZSBmcm9tICcuLi8uLi91dGlscy9kZWNvcmF0b3JzL21lbW9pemUnO1xuXG5pbXBvcnQgTWFueVRvTWFueUZpbmRPcGVyYXRpb24gZnJvbSAnLi9NYW55VG9NYW55RmluZE9wZXJhdGlvbic7XG5pbXBvcnQgTWFueVRvTWFueUluc2VydE9wZXJhdGlvbiBmcm9tICcuL01hbnlUb01hbnlJbnNlcnRPcGVyYXRpb24nO1xuaW1wb3J0IE1hbnlUb01hbnlSZWxhdGVPcGVyYXRpb24gZnJvbSAnLi9NYW55VG9NYW55UmVsYXRlT3BlcmF0aW9uJztcbmltcG9ydCBNYW55VG9NYW55VW5yZWxhdGVPcGVyYXRpb24gZnJvbSAnLi9NYW55VG9NYW55VW5yZWxhdGVPcGVyYXRpb24nO1xuaW1wb3J0IE1hbnlUb01hbnlVbnJlbGF0ZVNxbGl0ZU9wZXJhdGlvbiBmcm9tICcuL01hbnlUb01hbnlVbnJlbGF0ZVNxbGl0ZU9wZXJhdGlvbic7XG5pbXBvcnQgTWFueVRvTWFueVVwZGF0ZU9wZXJhdGlvbiBmcm9tICcuL01hbnlUb01hbnlVcGRhdGVPcGVyYXRpb24nO1xuaW1wb3J0IE1hbnlUb01hbnlVcGRhdGVTcWxpdGVPcGVyYXRpb24gZnJvbSAnLi9NYW55VG9NYW55VXBkYXRlU3FsaXRlT3BlcmF0aW9uJztcbmltcG9ydCBNYW55VG9NYW55RGVsZXRlT3BlcmF0aW9uIGZyb20gJy4vTWFueVRvTWFueURlbGV0ZU9wZXJhdGlvbic7XG5pbXBvcnQgTWFueVRvTWFueURlbGV0ZVNxbGl0ZU9wZXJhdGlvbiBmcm9tICcuL01hbnlUb01hbnlEZWxldGVTcWxpdGVPcGVyYXRpb24nO1xuXG5jb25zdCBzcWxpdGVCdWlsdEluUm93SWQgPSAnX3Jvd2lkXyc7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIE1hbnlUb01hbnlSZWxhdGlvbiBleHRlbmRzIFJlbGF0aW9uIHtcblxuICBzZXRNYXBwaW5nKG1hcHBpbmcpIHtcbiAgICBsZXQgcmV0VmFsID0gc3VwZXIuc2V0TWFwcGluZyhtYXBwaW5nKTtcblxuICAgIC8vIEF2b2lkIHJlcXVpcmUgbG9vcCBhbmQgaW1wb3J0IGhlcmUuXG4gICAgbGV0IE1vZGVsID0gcmVxdWlyZShfX2Rpcm5hbWUgKyAnLy4uLy4uL21vZGVsL01vZGVsJykuZGVmYXVsdDtcblxuICAgIGlmICghXy5pc09iamVjdChtYXBwaW5nLmpvaW4udGhyb3VnaCkpIHtcbiAgICAgIHRoaXMudGhyb3dFcnJvcignam9pbiBtdXN0IGhhdmUgdGhlIGB0aHJvdWdoYCB0aGF0IGRlc2NyaWJlcyB0aGUgam9pbiB0YWJsZS4nKTtcbiAgICB9XG5cbiAgICBpZiAoIW1hcHBpbmcuam9pbi50aHJvdWdoLmZyb20gfHwgIW1hcHBpbmcuam9pbi50aHJvdWdoLnRvKSB7XG4gICAgICB0aGlzLnRocm93RXJyb3IoJ2pvaW4udGhyb3VnaCBtdXN0IGJlIGFuIG9iamVjdCB0aGF0IGRlc2NyaWJlcyB0aGUgam9pbiB0YWJsZS4gRm9yIGV4YW1wbGU6IHtmcm9tOiBcIkpvaW5UYWJsZS5zb21lSWRcIiwgdG86IFwiSm9pblRhYmxlLnNvbWVPdGhlcklkXCJ9Jyk7XG4gICAgfVxuXG4gICAgbGV0IGpvaW5Gcm9tID0gdGhpcy5wYXJzZVJlZmVyZW5jZShtYXBwaW5nLmpvaW4uZnJvbSk7XG4gICAgbGV0IGpvaW5UYWJsZUZyb20gPSB0aGlzLnBhcnNlUmVmZXJlbmNlKG1hcHBpbmcuam9pbi50aHJvdWdoLmZyb20pO1xuICAgIGxldCBqb2luVGFibGVUbyA9IHRoaXMucGFyc2VSZWZlcmVuY2UobWFwcGluZy5qb2luLnRocm91Z2gudG8pO1xuICAgIGxldCBqb2luVGFibGVFeHRyYSA9IG1hcHBpbmcuam9pbi50aHJvdWdoLmV4dHJhIHx8IFtdO1xuXG4gICAgaWYgKCFqb2luVGFibGVGcm9tLnRhYmxlIHx8IF8uaXNFbXB0eShqb2luVGFibGVGcm9tLmNvbHVtbnMpKSB7XG4gICAgICB0aGlzLnRocm93RXJyb3IoJ2pvaW4udGhyb3VnaC5mcm9tIG11c3QgaGF2ZSBmb3JtYXQgSm9pblRhYmxlLmNvbHVtbk5hbWUuIEZvciBleGFtcGxlIFwiSm9pblRhYmxlLnNvbWVJZFwiIG9yIGluIGNhc2Ugb2YgY29tcG9zaXRlIGtleSBbXCJKb2luVGFibGUuYVwiLCBcIkpvaW5UYWJsZS5iXCJdLicpO1xuICAgIH1cblxuICAgIGlmICgham9pblRhYmxlVG8udGFibGUgfHwgXy5pc0VtcHR5KGpvaW5UYWJsZVRvLmNvbHVtbnMpKSB7XG4gICAgICB0aGlzLnRocm93RXJyb3IoJ2pvaW4udGhyb3VnaC50byBtdXN0IGhhdmUgZm9ybWF0IEpvaW5UYWJsZS5jb2x1bW5OYW1lLiBGb3IgZXhhbXBsZSBcIkpvaW5UYWJsZS5zb21lSWRcIiBvciBpbiBjYXNlIG9mIGNvbXBvc2l0ZSBrZXkgW1wiSm9pblRhYmxlLmFcIiwgXCJKb2luVGFibGUuYlwiXS4nKTtcbiAgICB9XG5cbiAgICBpZiAoam9pblRhYmxlRnJvbS50YWJsZSAhPT0gam9pblRhYmxlVG8udGFibGUpIHtcbiAgICAgIHRoaXMudGhyb3dFcnJvcignam9pbi50aHJvdWdoIGBmcm9tYCBhbmQgYHRvYCBtdXN0IHBvaW50IHRvIHRoZSBzYW1lIGpvaW4gdGFibGUuJyk7XG4gICAgfVxuXG4gICAgdGhpcy5qb2luVGFibGUgPSBqb2luVGFibGVGcm9tLnRhYmxlO1xuXG4gICAgaWYgKGpvaW5Gcm9tLnRhYmxlID09PSB0aGlzLm93bmVyTW9kZWxDbGFzcy50YWJsZU5hbWUpIHtcbiAgICAgIHRoaXMuam9pblRhYmxlT3duZXJDb2wgPSBqb2luVGFibGVGcm9tLmNvbHVtbnM7XG4gICAgICB0aGlzLmpvaW5UYWJsZVJlbGF0ZWRDb2wgPSBqb2luVGFibGVUby5jb2x1bW5zO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmpvaW5UYWJsZVJlbGF0ZWRDb2wgPSBqb2luVGFibGVGcm9tLmNvbHVtbnM7XG4gICAgICB0aGlzLmpvaW5UYWJsZU93bmVyQ29sID0gam9pblRhYmxlVG8uY29sdW1ucztcbiAgICB9XG5cbiAgICBpZiAobWFwcGluZy5qb2luLnRocm91Z2gubW9kZWxDbGFzcykge1xuICAgICAgdGhpcy5fam9pblRhYmxlTW9kZWxDbGFzcyA9IHRoaXMucmVzb2x2ZU1vZGVsKE1vZGVsLCBtYXBwaW5nLmpvaW4udGhyb3VnaC5tb2RlbENsYXNzLCAnam9pbi50aHJvdWdoLm1vZGVsQ2xhc3MnKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5fam9pblRhYmxlTW9kZWxDbGFzcyA9IGluaGVyaXRNb2RlbChNb2RlbCk7XG4gICAgICB0aGlzLl9qb2luVGFibGVNb2RlbENsYXNzLnRhYmxlTmFtZSA9IHRoaXMuam9pblRhYmxlO1xuICAgICAgLy8gV2UgY2Fubm90IGtub3cgaWYgdGhlIGpvaW4gdGFibGUgaGFzIGEgcHJpbWFyeSBrZXkuIFRoZXJlZm9yZSB3ZSBzZXQgc29tZVxuICAgICAgLy8ga25vd24gY29sdW1uIGFzIHRoZSBpZENvbHVtbiBzbyB0aGF0IGluc2VydHMgd2lsbCB3b3JrLlxuICAgICAgdGhpcy5fam9pblRhYmxlTW9kZWxDbGFzcy5pZENvbHVtbiA9IHRoaXMuam9pblRhYmxlUmVsYXRlZENvbDtcbiAgICB9XG5cbiAgICB0aGlzLmpvaW5UYWJsZU93bmVyUHJvcCA9IHRoaXMucHJvcGVydHlOYW1lKHRoaXMuam9pblRhYmxlT3duZXJDb2wsIHRoaXMuX2pvaW5UYWJsZU1vZGVsQ2xhc3MpO1xuICAgIHRoaXMuam9pblRhYmxlUmVsYXRlZFByb3AgPSB0aGlzLnByb3BlcnR5TmFtZSh0aGlzLmpvaW5UYWJsZVJlbGF0ZWRDb2wsIHRoaXMuX2pvaW5UYWJsZU1vZGVsQ2xhc3MpO1xuICAgIHRoaXMuam9pblRhYmxlRXh0cmFzID0gdGhpcy5wYXJzZUV4dHJhcyhqb2luVGFibGVFeHRyYSk7XG5cbiAgICByZXR1cm4gcmV0VmFsO1xuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm5zIHtBcnJheS48c3RyaW5nPn1cbiAgICovXG4gIEBtZW1vaXplXG4gIGZ1bGxKb2luVGFibGVPd25lckNvbCgpIHtcbiAgICByZXR1cm4gdGhpcy5qb2luVGFibGVPd25lckNvbC5tYXAoY29sID0+IGAke3RoaXMuam9pblRhYmxlfS4ke2NvbH1gKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJucyB7QXJyYXkuPHN0cmluZz59XG4gICAqL1xuICBAbWVtb2l6ZVxuICBmdWxsSm9pblRhYmxlUmVsYXRlZENvbCgpIHtcbiAgICByZXR1cm4gdGhpcy5qb2luVGFibGVSZWxhdGVkQ29sLm1hcChjb2wgPT4gYCR7dGhpcy5qb2luVGFibGV9LiR7Y29sfWApO1xuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm5zIHtzdHJpbmd9XG4gICAqL1xuICBqb2luVGFibGVBbGlhcygpIHtcbiAgICByZXR1cm4gdGhpcy5qb2luVGFibGUgKyAnX3JlbF8nICsgdGhpcy5uYW1lO1xuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm5zIHtNYW55VG9NYW55UmVsYXRpb259XG4gICAqL1xuICBiaW5kS25leChrbmV4KSB7XG4gICAgbGV0IGJvdW5kID0gc3VwZXIuYmluZEtuZXgoa25leCk7XG4gICAgYm91bmQuX2pvaW5UYWJsZU1vZGVsQ2xhc3MgPSB0aGlzLl9qb2luVGFibGVNb2RlbENsYXNzLmJpbmRLbmV4KGtuZXgpO1xuICAgIHJldHVybiBib3VuZDtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJucyB7UXVlcnlCdWlsZGVyfVxuICAgKi9cbiAgZmluZFF1ZXJ5KGJ1aWxkZXIsIG9wdCkge1xuICAgIGJ1aWxkZXIuam9pbih0aGlzLmpvaW5UYWJsZSwgam9pbiA9PiB7XG4gICAgICBjb25zdCBmdWxsUmVsYXRlZENvbCA9IHRoaXMuZnVsbFJlbGF0ZWRDb2woKTtcbiAgICAgIGNvbnN0IGZ1bGxKb2luVGFibGVSZWxhdGVkQ29sID0gdGhpcy5mdWxsSm9pblRhYmxlUmVsYXRlZENvbCgpO1xuXG4gICAgICBmb3IgKGxldCBpID0gMCwgbCA9IGZ1bGxKb2luVGFibGVSZWxhdGVkQ29sLmxlbmd0aDsgaSA8IGw7ICsraSkge1xuICAgICAgICBqb2luLm9uKGZ1bGxKb2luVGFibGVSZWxhdGVkQ29sW2ldLCBmdWxsUmVsYXRlZENvbFtpXSk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBpZiAob3B0LmlzQ29sdW1uUmVmKSB7XG4gICAgICBjb25zdCBmdWxsSm9pblRhYmxlT3duZXJDb2wgPSB0aGlzLmZ1bGxKb2luVGFibGVPd25lckNvbCgpO1xuXG4gICAgICBmb3IgKGxldCBpID0gMCwgbCA9IGZ1bGxKb2luVGFibGVPd25lckNvbC5sZW5ndGg7IGkgPCBsOyArK2kpIHtcbiAgICAgICAgYnVpbGRlci53aGVyZVJlZihmdWxsSm9pblRhYmxlT3duZXJDb2xbaV0sIG9wdC5vd25lcklkc1tpXSk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGxldCBoYXNJZHMgPSBmYWxzZTtcblxuICAgICAgZm9yIChsZXQgaSA9IDAsIGwgPSBvcHQub3duZXJJZHMubGVuZ3RoOyBpIDwgbDsgKytpKSB7XG4gICAgICAgIGNvbnN0IGlkID0gb3B0Lm93bmVySWRzW2ldO1xuXG4gICAgICAgIGlmIChpZCkge1xuICAgICAgICAgIGhhc0lkcyA9IHRydWU7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKGhhc0lkcykge1xuICAgICAgICBidWlsZGVyLndoZXJlSW5Db21wb3NpdGUodGhpcy5mdWxsSm9pblRhYmxlT3duZXJDb2woKSwgb3B0Lm93bmVySWRzKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGJ1aWxkZXIucmVzb2x2ZShbXSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGJ1aWxkZXIubW9kaWZ5KHRoaXMubW9kaWZ5KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJucyB7UXVlcnlCdWlsZGVyfVxuICAgKi9cbiAgam9pbihidWlsZGVyLCBvcHQpIHtcbiAgICBvcHQgPSBvcHQgfHwge307XG5cbiAgICBvcHQuam9pbk9wZXJhdGlvbiA9IG9wdC5qb2luT3BlcmF0aW9uIHx8ICdqb2luJztcbiAgICBvcHQucmVsYXRlZFRhYmxlQWxpYXMgPSBvcHQucmVsYXRlZFRhYmxlQWxpYXMgfHwgdGhpcy5yZWxhdGVkVGFibGVBbGlhcygpO1xuICAgIG9wdC5yZWxhdGVkSm9pblNlbGVjdFF1ZXJ5ID0gb3B0LnJlbGF0ZWRKb2luU2VsZWN0UXVlcnkgfHwgdGhpcy5yZWxhdGVkTW9kZWxDbGFzcy5xdWVyeSgpLmNoaWxkUXVlcnlPZihidWlsZGVyKTtcbiAgICBvcHQucmVsYXRlZFRhYmxlID0gb3B0LnJlbGF0ZWRUYWJsZSB8fCB0aGlzLnJlbGF0ZWRNb2RlbENsYXNzLnRhYmxlTmFtZTtcbiAgICBvcHQub3duZXJUYWJsZSA9IG9wdC5vd25lclRhYmxlIHx8IHRoaXMub3duZXJNb2RlbENsYXNzLnRhYmxlTmFtZTtcbiAgICBvcHQuam9pblRhYmxlQWxpYXMgPSBvcHQuam9pblRhYmxlQWxpYXMgfHwgYCR7b3B0LnJlbGF0ZWRUYWJsZUFsaWFzfV9qb2luYDtcblxuICAgIGNvbnN0IGpvaW5UYWJsZUFzQWxpYXMgPSBgJHt0aGlzLmpvaW5UYWJsZX0gYXMgJHtvcHQuam9pblRhYmxlQWxpYXN9YDtcbiAgICBjb25zdCBqb2luVGFibGVPd25lckNvbCA9IHRoaXMuam9pblRhYmxlT3duZXJDb2wubWFwKGNvbCA9PiBgJHtvcHQuam9pblRhYmxlQWxpYXN9LiR7Y29sfWApO1xuICAgIGNvbnN0IGpvaW5UYWJsZVJlbGF0ZWRDb2wgPSB0aGlzLmpvaW5UYWJsZVJlbGF0ZWRDb2wubWFwKGNvbCA9PiBgJHtvcHQuam9pblRhYmxlQWxpYXN9LiR7Y29sfWApO1xuXG4gICAgY29uc3QgcmVsYXRlZENvbCA9IHRoaXMucmVsYXRlZENvbC5tYXAoY29sID0+IGAke29wdC5yZWxhdGVkVGFibGVBbGlhc30uJHtjb2x9YCk7XG4gICAgY29uc3Qgb3duZXJDb2wgPSB0aGlzLm93bmVyQ29sLm1hcChjb2wgPT4gYCR7b3B0Lm93bmVyVGFibGV9LiR7Y29sfWApO1xuXG4gICAgbGV0IHJlbGF0ZWRKb2luU2VsZWN0ID0gb3B0LnJlbGF0ZWRKb2luU2VsZWN0UXVlcnlcbiAgICAgIC5tb2RpZnkodGhpcy5tb2RpZnkpXG4gICAgICAuYXMob3B0LnJlbGF0ZWRUYWJsZUFsaWFzKTtcblxuICAgIGlmIChyZWxhdGVkSm9pblNlbGVjdC5pc1NlbGVjdEFsbCgpKSB7XG4gICAgICAvLyBObyBuZWVkIHRvIGpvaW4gYSBzdWJxdWVyeSBpZiB0aGUgcXVlcnkgaXMgYHNlbGVjdCAqIGZyb20gXCJSZWxhdGVkVGFibGVcImAuXG4gICAgICByZWxhdGVkSm9pblNlbGVjdCA9IGAke3RoaXMucmVsYXRlZE1vZGVsQ2xhc3MudGFibGVOYW1lfSBhcyAke29wdC5yZWxhdGVkVGFibGVBbGlhc31gXG4gICAgfVxuXG4gICAgcmV0dXJuIGJ1aWxkZXJcbiAgICAgIFtvcHQuam9pbk9wZXJhdGlvbl0oam9pblRhYmxlQXNBbGlhcywgam9pbiA9PiB7XG4gICAgICAgIGZvciAobGV0IGkgPSAwLCBsID0gam9pblRhYmxlT3duZXJDb2wubGVuZ3RoOyBpIDwgbDsgKytpKSB7XG4gICAgICAgICAgam9pbi5vbihqb2luVGFibGVPd25lckNvbFtpXSwgb3duZXJDb2xbaV0pO1xuICAgICAgICB9XG4gICAgICB9KVxuICAgICAgW29wdC5qb2luT3BlcmF0aW9uXShyZWxhdGVkSm9pblNlbGVjdCwgam9pbiA9PiB7XG4gICAgICAgIGZvciAobGV0IGkgPSAwLCBsID0gam9pblRhYmxlUmVsYXRlZENvbC5sZW5ndGg7IGkgPCBsOyArK2kpIHtcbiAgICAgICAgICBqb2luLm9uKGpvaW5UYWJsZVJlbGF0ZWRDb2xbaV0sIHJlbGF0ZWRDb2xbaV0pO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgfVxuXG4gIGZpbmQoYnVpbGRlciwgb3duZXJzKSB7XG4gICAgcmV0dXJuIG5ldyBNYW55VG9NYW55RmluZE9wZXJhdGlvbignZmluZCcsIHtcbiAgICAgIHJlbGF0aW9uOiB0aGlzLFxuICAgICAgb3duZXJzOiBvd25lcnNcbiAgICB9KTtcbiAgfVxuXG4gIGluc2VydChidWlsZGVyLCBvd25lcikge1xuICAgIHJldHVybiBuZXcgTWFueVRvTWFueUluc2VydE9wZXJhdGlvbignaW5zZXJ0Jywge1xuICAgICAgcmVsYXRpb246IHRoaXMsXG4gICAgICBvd25lcjogb3duZXJcbiAgICB9KTtcbiAgfVxuXG4gIHVwZGF0ZShidWlsZGVyLCBvd25lcikge1xuICAgIGlmIChpc1NxbGl0ZShidWlsZGVyLmtuZXgoKSkpIHtcbiAgICAgIHJldHVybiBuZXcgTWFueVRvTWFueVVwZGF0ZVNxbGl0ZU9wZXJhdGlvbigndXBkYXRlJywge1xuICAgICAgICByZWxhdGlvbjogdGhpcyxcbiAgICAgICAgb3duZXI6IG93bmVyXG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIG5ldyBNYW55VG9NYW55VXBkYXRlT3BlcmF0aW9uKCd1cGRhdGUnLCB7XG4gICAgICAgIHJlbGF0aW9uOiB0aGlzLFxuICAgICAgICBvd25lcjogb3duZXJcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIHBhdGNoKGJ1aWxkZXIsIG93bmVyKSB7XG4gICAgaWYgKGlzU3FsaXRlKGJ1aWxkZXIua25leCgpKSkge1xuICAgICAgcmV0dXJuIG5ldyBNYW55VG9NYW55VXBkYXRlU3FsaXRlT3BlcmF0aW9uKCdwYXRjaCcsIHtcbiAgICAgICAgcmVsYXRpb246IHRoaXMsXG4gICAgICAgIG93bmVyOiBvd25lcixcbiAgICAgICAgbW9kZWxPcHRpb25zOiB7cGF0Y2g6IHRydWV9XG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIG5ldyBNYW55VG9NYW55VXBkYXRlT3BlcmF0aW9uKCdwYXRjaCcsIHtcbiAgICAgICAgcmVsYXRpb246IHRoaXMsXG4gICAgICAgIG93bmVyOiBvd25lcixcbiAgICAgICAgbW9kZWxPcHRpb25zOiB7cGF0Y2g6IHRydWV9XG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICBkZWxldGUoYnVpbGRlciwgb3duZXIpIHtcbiAgICBpZiAoaXNTcWxpdGUoYnVpbGRlci5rbmV4KCkpKSB7XG4gICAgICByZXR1cm4gbmV3IE1hbnlUb01hbnlEZWxldGVTcWxpdGVPcGVyYXRpb24oJ2RlbGV0ZScsIHtcbiAgICAgICAgcmVsYXRpb246IHRoaXMsXG4gICAgICAgIG93bmVyOiBvd25lclxuICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBuZXcgTWFueVRvTWFueURlbGV0ZU9wZXJhdGlvbignZGVsZXRlJywge1xuICAgICAgICByZWxhdGlvbjogdGhpcyxcbiAgICAgICAgb3duZXI6IG93bmVyXG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICByZWxhdGUoYnVpbGRlciwgb3duZXIpIHtcbiAgICByZXR1cm4gbmV3IE1hbnlUb01hbnlSZWxhdGVPcGVyYXRpb24oJ3JlbGF0ZScsIHtcbiAgICAgIHJlbGF0aW9uOiB0aGlzLFxuICAgICAgb3duZXI6IG93bmVyXG4gICAgfSk7XG4gIH1cblxuICB1bnJlbGF0ZShidWlsZGVyLCBvd25lcikge1xuICAgIGlmIChpc1NxbGl0ZShidWlsZGVyLmtuZXgoKSkpIHtcbiAgICAgIHJldHVybiBuZXcgTWFueVRvTWFueVVucmVsYXRlU3FsaXRlT3BlcmF0aW9uKCd1bnJlbGF0ZScsIHtcbiAgICAgICAgcmVsYXRpb246IHRoaXMsXG4gICAgICAgIG93bmVyOiBvd25lclxuICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBuZXcgTWFueVRvTWFueVVucmVsYXRlT3BlcmF0aW9uKCd1bnJlbGF0ZScsIHtcbiAgICAgICAgcmVsYXRpb246IHRoaXMsXG4gICAgICAgIG93bmVyOiBvd25lclxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgc2VsZWN0Rm9yTW9kaWZ5KGJ1aWxkZXIsIG93bmVyKSB7XG4gICAgbGV0IG93bmVySWQgPSBvd25lci4kdmFsdWVzKHRoaXMub3duZXJQcm9wKTtcblxuICAgIGxldCBpZFF1ZXJ5ID0gdGhpcy5qb2luVGFibGVNb2RlbENsYXNzKGJ1aWxkZXIua25leCgpKVxuICAgICAgLnF1ZXJ5KClcbiAgICAgIC5jaGlsZFF1ZXJ5T2YoYnVpbGRlcilcbiAgICAgIC5zZWxlY3QodGhpcy5mdWxsSm9pblRhYmxlUmVsYXRlZENvbCgpKVxuICAgICAgLndoZXJlQ29tcG9zaXRlKHRoaXMuZnVsbEpvaW5UYWJsZU93bmVyQ29sKCksIG93bmVySWQpO1xuXG4gICAgcmV0dXJuIGJ1aWxkZXIud2hlcmVJbkNvbXBvc2l0ZSh0aGlzLmZ1bGxSZWxhdGVkQ29sKCksIGlkUXVlcnkpO1xuICB9XG5cbiAgc2VsZWN0Rm9yTW9kaWZ5U3FsaXRlKGJ1aWxkZXIsIG93bmVyKSB7XG4gICAgY29uc3QgcmVsYXRlZFRhYmxlID0gdGhpcy5yZWxhdGVkTW9kZWxDbGFzcy50YWJsZU5hbWU7XG4gICAgY29uc3QgcmVsYXRlZFRhYmxlQWxpYXMgPSB0aGlzLnJlbGF0ZWRUYWJsZUFsaWFzKCk7XG4gICAgY29uc3QgcmVsYXRlZFRhYmxlQXNBbGlhcyA9IHJlbGF0ZWRUYWJsZSArICcgYXMgJyArIHJlbGF0ZWRUYWJsZUFsaWFzO1xuICAgIGNvbnN0IHJlbGF0ZWRUYWJsZUFsaWFzUm93SWQgPSByZWxhdGVkVGFibGVBbGlhcyArICcuJyArIHNxbGl0ZUJ1aWx0SW5Sb3dJZDtcbiAgICBjb25zdCByZWxhdGVkVGFibGVSb3dJZCA9IHJlbGF0ZWRUYWJsZSArICcuJyArIHNxbGl0ZUJ1aWx0SW5Sb3dJZDtcblxuICAgIGNvbnN0IHNlbGVjdFJlbGF0ZWRRdWVyeSA9IHRoaXMuam9pblRhYmxlTW9kZWxDbGFzcyhidWlsZGVyLmtuZXgoKSlcbiAgICAgIC5xdWVyeSgpXG4gICAgICAuY2hpbGRRdWVyeU9mKGJ1aWxkZXIpXG4gICAgICAuc2VsZWN0KHJlbGF0ZWRUYWJsZUFsaWFzUm93SWQpXG4gICAgICAud2hlcmVDb21wb3NpdGUodGhpcy5mdWxsSm9pblRhYmxlT3duZXJDb2woKSwgb3duZXIuJHZhbHVlcyh0aGlzLm93bmVyUHJvcCkpXG4gICAgICAuam9pbihyZWxhdGVkVGFibGVBc0FsaWFzLCBqb2luID0+IHtcbiAgICAgICAgY29uc3QgZnVsbEpvaW5UYWJsZVJlbGF0ZWRDb2xzID0gdGhpcy5mdWxsSm9pblRhYmxlUmVsYXRlZENvbCgpO1xuICAgICAgICBjb25zdCBmdWxsUmVsYXRlZENvbCA9IHRoaXMuZnVsbFJlbGF0ZWRDb2woKTtcblxuICAgICAgICBmb3IgKGxldCBpID0gMCwgbCA9IGZ1bGxKb2luVGFibGVSZWxhdGVkQ29scy5sZW5ndGg7IGkgPCBsOyArK2kpIHtcbiAgICAgICAgICBqb2luLm9uKGZ1bGxKb2luVGFibGVSZWxhdGVkQ29sc1tpXSwgZnVsbFJlbGF0ZWRDb2xbaV0pO1xuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgIHJldHVybiBidWlsZGVyLndoZXJlSW5Db21wb3NpdGUocmVsYXRlZFRhYmxlUm93SWQsIHNlbGVjdFJlbGF0ZWRRdWVyeSk7XG4gIH1cblxuICBjcmVhdGVKb2luTW9kZWxzKG93bmVySWQsIHJlbGF0ZWQpIHtcbiAgICBjb25zdCBqb2luTW9kZWxzID0gbmV3IEFycmF5KHJlbGF0ZWQubGVuZ3RoKTtcblxuICAgIGZvciAobGV0IGkgPSAwLCBsciA9IHJlbGF0ZWQubGVuZ3RoOyBpIDwgbHI7ICsraSkge1xuICAgICAgY29uc3QgcmVsID0gcmVsYXRlZFtpXTtcbiAgICAgIGxldCBqb2luTW9kZWwgPSB7fTtcblxuICAgICAgZm9yIChsZXQgaiA9IDAsIGxwID0gdGhpcy5qb2luVGFibGVPd25lclByb3AubGVuZ3RoOyBqIDwgbHA7ICsraikge1xuICAgICAgICBqb2luTW9kZWxbdGhpcy5qb2luVGFibGVPd25lclByb3Bbal1dID0gb3duZXJJZFtqXTtcbiAgICAgIH1cblxuICAgICAgZm9yIChsZXQgaiA9IDAsIGxwID0gdGhpcy5qb2luVGFibGVSZWxhdGVkUHJvcC5sZW5ndGg7IGogPCBscDsgKytqKSB7XG4gICAgICAgIGpvaW5Nb2RlbFt0aGlzLmpvaW5UYWJsZVJlbGF0ZWRQcm9wW2pdXSA9IHJlbFt0aGlzLnJlbGF0ZWRQcm9wW2pdXTtcbiAgICAgIH1cblxuICAgICAgZm9yIChsZXQgaiA9IDAsIGxwID0gdGhpcy5qb2luVGFibGVFeHRyYXMubGVuZ3RoOyBqIDwgbHA7ICsraikge1xuICAgICAgICBjb25zdCBleHRyYSA9IHRoaXMuam9pblRhYmxlRXh0cmFzW2pdO1xuICAgICAgICBjb25zdCBleHRyYVZhbHVlID0gcmVsW2V4dHJhLmFsaWFzUHJvcF07XG5cbiAgICAgICAgaWYgKCFfLmlzVW5kZWZpbmVkKGV4dHJhVmFsdWUpKSB7XG4gICAgICAgICAgam9pbk1vZGVsW2V4dHJhLmpvaW5UYWJsZVByb3BdID0gZXh0cmFWYWx1ZTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBqb2luTW9kZWxzW2ldID0gam9pbk1vZGVsO1xuICAgIH1cblxuICAgIHJldHVybiBqb2luTW9kZWxzO1xuICB9XG5cbiAgb21pdEV4dHJhUHJvcHMobW9kZWxzKSB7XG4gICAgaWYgKCFfLmlzRW1wdHkodGhpcy5qb2luVGFibGVFeHRyYXMpKSB7XG4gICAgICBjb25zdCBwcm9wcyA9IHRoaXMuam9pblRhYmxlRXh0cmFzLm1hcChleHRyYSA9PiBleHRyYS5hbGlhc1Byb3ApO1xuXG4gICAgICBmb3IgKGxldCBpID0gMCwgbCA9IG1vZGVscy5sZW5ndGg7IGkgPCBsOyArK2kpIHtcbiAgICAgICAgbW9kZWxzW2ldLiRvbWl0RnJvbURhdGFiYXNlSnNvbihwcm9wcyk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEBwcm90ZWN0ZWRcbiAgICovXG4gIHBhcnNlRXh0cmFzKGV4dHJhcykge1xuICAgIGlmIChBcnJheS5pc0FycmF5KGV4dHJhcykpIHtcbiAgICAgIGV4dHJhcyA9IGV4dHJhcy5yZWR1Y2UoKGV4dHJhcywgY29sKSA9PiB7XG4gICAgICAgIGV4dHJhc1tjb2xdID0gY29sO1xuICAgICAgICByZXR1cm4gZXh0cmFzO1xuICAgICAgfSwge30pO1xuICAgIH1cblxuICAgIHJldHVybiBPYmplY3Qua2V5cyhleHRyYXMpLm1hcChrZXkgPT4ge1xuICAgICAgY29uc3QgdmFsID0gZXh0cmFzW2tleV07XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIGpvaW5UYWJsZUNvbDogdmFsLFxuICAgICAgICBqb2luVGFibGVQcm9wOiB0aGlzLl9qb2luVGFibGVNb2RlbENsYXNzLmNvbHVtbk5hbWVUb1Byb3BlcnR5TmFtZSh2YWwpLFxuICAgICAgICBhbGlhc0NvbDoga2V5LFxuICAgICAgICBhbGlhc1Byb3A6IHRoaXMuX2pvaW5UYWJsZU1vZGVsQ2xhc3MuY29sdW1uTmFtZVRvUHJvcGVydHlOYW1lKGtleSlcbiAgICAgIH07XG4gICAgfSk7XG4gIH1cbn1cbiJdfQ==