UNPKG

objection

Version:
735 lines (549 loc) 57.2 kB
'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 _create = require('babel-runtime/core-js/object/create'); var _create2 = _interopRequireDefault(_create); var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck'); var _classCallCheck3 = _interopRequireDefault(_classCallCheck2); var _desc, _value, _class; var _lodash = require('lodash'); var _lodash2 = _interopRequireDefault(_lodash); var _path = require('path'); var _path2 = _interopRequireDefault(_path); var _memoize = require('../utils/decorators/memoize'); var _memoize2 = _interopRequireDefault(_memoize); var _classUtils = require('../utils/classUtils'); var _hiddenData = require('../utils/hiddenData'); var _QueryBuilder = require('../queryBuilder/QueryBuilder'); var _QueryBuilder2 = _interopRequireDefault(_QueryBuilder); var _RelationFindOperation = require('./RelationFindOperation'); var _RelationFindOperation2 = _interopRequireDefault(_RelationFindOperation); var _RelationUpdateOperation = require('./RelationUpdateOperation'); var _RelationUpdateOperation2 = _interopRequireDefault(_RelationUpdateOperation); var _RelationDeleteOperation = require('./RelationDeleteOperation'); var _RelationDeleteOperation2 = _interopRequireDefault(_RelationDeleteOperation); 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; } /** * @typedef {Object} RelationJoin * @property {string|Array.<string>} from * @property {string|Array.<string>} to * @property {Object} through * @property {Constructor.<Model>} through.modelClass * @property {string|Array.<string>} through.from * @property {string|Array.<string>} through.to * @property {Array.<string>} through.extra */ /** * @typedef {Object} RelationMapping * * @property {Constructor.<Model>|string} modelClass * @property {Relation} relation * @property {Object|function(QueryBuilder)} modify * @property {Object|function(QueryBuilder)} filter * @property {RelationJoin} [join] */ /** * @abstract */ var Relation = (_class = function () { function Relation(relationName, OwnerClass) { (0, _classCallCheck3.default)(this, Relation); /** * @type {string} */ this.name = relationName; /** * @type {Constructor.<Model>} */ this.ownerModelClass = OwnerClass; /** * @type {Constructor.<Model>} */ this.relatedModelClass = null; /** * @type {Constructor.<Model>} */ this._joinTableModelClass = null; /** * @type {Array.<string>} */ this.ownerCol = null; /** * @type {Array.<string>} */ this.ownerProp = null; /** * @type {Array.<string>} */ this.relatedCol = null; /** * @type {Array.<string>} */ this.relatedProp = null; /** * @type {string} */ this.joinTable = null; /** * @type {Array.<string>} */ this.joinTableOwnerCol = null; /** * @type {Array.<string>} */ this.joinTableOwnerProp = null; /** * @type {Array.<string>} */ this.joinTableRelatedCol = null; /** * @type {Array.<string>} */ this.joinTableRelatedProp = null; /** * @type {Array.<{joinTableCol: string, joinTableProp: string, aliasCol: string, aliasProp: string}>} */ this.joinTableExtras = []; /** * @type {function (QueryBuilder)} */ this.modify = null; (0, _hiddenData.init)(this); } /** * @param {function=} subclassConstructor * @return {Constructor.<Model>} */ Relation.extend = function extend(subclassConstructor) { (0, _classUtils.inherits)(subclassConstructor, this); return subclassConstructor; }; /** * @param {RelationMapping} mapping */ Relation.prototype.setMapping = function setMapping(mapping) { // Avoid require loop and import here. var Model = require(__dirname + '/../model/Model').default; if (!(0, _classUtils.isSubclassOf)(this.ownerModelClass, Model)) { this.throwError('Relation\'s owner is not a subclass of Model'); } if (!mapping.modelClass) { this.throwError('modelClass is not defined'); } this.relatedModelClass = this.resolveModel(Model, mapping.modelClass, 'modelClass'); if (!mapping.relation) { this.throwError('relation is not defined'); } if (!(0, _classUtils.isSubclassOf)(mapping.relation, Relation)) { this.throwError('relation is not a subclass of Relation'); } if (!mapping.join || !mapping.join.from || !mapping.join.to) { this.throwError('join must be an object that maps the columns of the related models together. For example: {from: "SomeTable.id", to: "SomeOtherTable.someModelId"}'); } var joinOwner = null; var joinRelated = null; var joinFrom = this.parseReference(mapping.join.from); var joinTo = this.parseReference(mapping.join.to); if (!joinFrom.table || _lodash2.default.isEmpty(joinFrom.columns)) { this.throwError('join.from must have format TableName.columnName. For example "SomeTable.id" or in case of composite key ["SomeTable.a", "SomeTable.b"].'); } if (!joinTo.table || _lodash2.default.isEmpty(joinTo.columns)) { this.throwError('join.to must have format TableName.columnName. For example "SomeTable.id" or in case of composite key ["SomeTable.a", "SomeTable.b"].'); } if (joinFrom.table === this.ownerModelClass.tableName) { joinOwner = joinFrom; joinRelated = joinTo; } else if (joinTo.table === this.ownerModelClass.tableName) { joinOwner = joinTo; joinRelated = joinFrom; } else { this.throwError('join: either `from` or `to` must point to the owner model table.'); } if (joinRelated.table !== this.relatedModelClass.tableName) { this.throwError('join: either `from` or `to` must point to the related model table.'); } this.ownerCol = joinOwner.columns; this.ownerProp = this.propertyName(this.ownerCol, this.ownerModelClass); this.relatedCol = joinRelated.columns; this.relatedProp = this.propertyName(this.relatedCol, this.relatedModelClass); this.modify = this.parseModify(mapping); }; /** * @return {boolean} */ Relation.prototype.isOneToOne = function isOneToOne() { return false; }; /** * @type {Constructor.<Model>} */ Relation.prototype.joinTableModelClass = function joinTableModelClass(knex) { if (knex && knex !== this._joinTableModelClass.knex()) { return this._joinTableModelClass.bindKnex(knex); } else { return this._joinTableModelClass; } }; /** * @returns {Array.<string>} */ Relation.prototype.fullRelatedCol = function fullRelatedCol() { var _this = this; return this.relatedCol.map(function (col) { return _this.relatedModelClass.tableName + '.' + col; }); }; /** * @returns {Array.<string>} */ Relation.prototype.fullOwnerCol = function fullOwnerCol() { var _this2 = this; return this.ownerCol.map(function (col) { return _this2.ownerModelClass.tableName + '.' + col; }); }; /** * @returns {string} */ Relation.prototype.relatedTableAlias = function relatedTableAlias() { return this.relatedModelClass.tableName + '_rel_' + this.name; }; /** * @returns {Relation} */ Relation.prototype.clone = function clone() { var relation = new this.constructor(this.name, this.ownerModelClass); relation.relatedModelClass = this.relatedModelClass; relation.ownerCol = this.ownerCol; relation.ownerProp = this.ownerProp; relation.relatedCol = this.relatedCol; relation.relatedProp = this.relatedProp; relation.modify = this.modify; relation._joinTableModelClass = this._joinTableModelClass; relation.joinTable = this.joinTable; relation.joinTableOwnerCol = this.joinTableOwnerCol; relation.joinTableOwnerProp = this.joinTableOwnerProp; relation.joinTableRelatedCol = this.joinTableRelatedCol; relation.joinTableRelatedProp = this.joinTableRelatedProp; relation.joinTableExtras = this.joinTableExtras; (0, _hiddenData.copyHiddenData)(this, relation); return relation; }; /** * @param {knex} knex * @returns {Relation} */ Relation.prototype.bindKnex = function bindKnex(knex) { var bound = this.clone(); bound.relatedModelClass = this.relatedModelClass.bindKnex(knex); bound.ownerModelClass = this.ownerModelClass.bindKnex(knex); return bound; }; /** * @param {QueryBuilder} builder * @param {object} opt * @param {Array.<string>|Array.<Array.<(string|number)>>} opt.ownerIds * @param {boolean=} opt.isColumnRef * @returns {QueryBuilder} */ Relation.prototype.findQuery = function findQuery(builder, opt) { var fullRelatedCol = this.fullRelatedCol(); if (opt.isColumnRef) { for (var i = 0, l = fullRelatedCol.length; i < l; ++i) { builder.whereRef(fullRelatedCol[i], opt.ownerIds[i]); } } else if (containsNonNull(opt.ownerIds)) { builder.whereInComposite(fullRelatedCol, opt.ownerIds); } else { builder.resolve([]); } return builder.modify(this.modify); }; /** * @param {QueryBuilder} builder * @param {object=} opt * @returns {QueryBuilder} */ Relation.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; var relatedCol = this.relatedCol.map(function (col) { return opt.relatedTableAlias + '.' + col; }); var ownerCol = this.ownerCol.map(function (col) { return opt.ownerTable + '.' + col; }); var relatedSelect = opt.relatedJoinSelectQuery.modify(this.modify).as(opt.relatedTableAlias); if (relatedSelect.isSelectAll()) { // No need to join a subquery if the query is `select * from "RelatedTable"`. relatedSelect = this.relatedModelClass.tableName + ' as ' + opt.relatedTableAlias; } return builder[opt.joinOperation](relatedSelect, function (join) { for (var i = 0, l = relatedCol.length; i < l; ++i) { join.on(relatedCol[i], '=', ownerCol[i]); } }); }; /* istanbul ignore next */ /** * @abstract * @param {QueryBuilder} builder * @param {Model} owner * @returns {QueryBuilderOperation} */ Relation.prototype.insert = function insert(builder, owner) { this.throwError('not implemented'); }; /** * @param {QueryBuilder} builder * @param {Model} owner * @returns {QueryBuilderOperation} */ Relation.prototype.update = function update(builder, owner) { return new _RelationUpdateOperation2.default('update', { relation: this, owner: owner }); }; /** * @param {QueryBuilder} builder * @param {Model} owner * @returns {QueryBuilderOperation} */ Relation.prototype.patch = function patch(builder, owner) { return new _RelationUpdateOperation2.default('patch', { relation: this, owner: owner, modelOptions: { patch: true } }); }; /** * @param {QueryBuilder} builder * @param {Array.<Model>} owners * @returns {QueryBuilderOperation} */ Relation.prototype.find = function find(builder, owners) { return new _RelationFindOperation2.default('find', { relation: this, owners: owners }); }; /** * @param {QueryBuilder} builder * @param {Model} owner * @returns {QueryBuilderOperation} */ Relation.prototype.delete = function _delete(builder, owner) { return new _RelationDeleteOperation2.default('delete', { relation: this, owner: owner }); }; /* istanbul ignore next */ /** * @abstract * @param {QueryBuilder} builder * @param {Model} owner * @returns {QueryBuilderOperation} */ Relation.prototype.relate = function relate(builder, owner) { this.throwError('not implemented'); }; /* istanbul ignore next */ /** * @abstract * @param {QueryBuilder} builder * @param {Model} owner * @returns {QueryBuilderOperation} */ Relation.prototype.unrelate = function unrelate(builder, owner) { this.throwError('not implemented'); }; /** * @protected */ Relation.prototype.propertyName = function propertyName(columns, modelClass) { var _this3 = this; return columns.map(function (column) { var propertyName = modelClass.columnNameToPropertyName(column); if (!propertyName) { throw new Error(modelClass.name + '.$parseDatabaseJson probably transforms the value of the column ' + column + '.' + ' This is a no-no because ' + column + ' is needed in the relation ' + _this3.ownerModelClass.tableName + '.' + _this3.name); } return propertyName; }); }; /** * @protected */ Relation.prototype.parseModify = function parseModify(mapping) { var modify = mapping.modify || mapping.filter; if (_lodash2.default.isFunction(modify)) { return modify; } else if (_lodash2.default.isObject(modify)) { return function (queryBuilder) { queryBuilder.where(modify); }; } else { return _lodash2.default.noop; } }; /** * @protected */ Relation.prototype.parseReference = function parseReference(ref) { if (!_lodash2.default.isArray(ref)) { ref = [ref]; } var table = null; var columns = []; for (var i = 0; i < ref.length; ++i) { var refItem = ref[i]; var ndx = refItem.lastIndexOf('.'); var tableName = refItem.substr(0, ndx).trim(); var columnName = refItem.substr(ndx + 1, refItem.length).trim(); if (!tableName || table && table !== tableName || !columnName) { return { table: null, columns: [] }; } else { table = tableName; } columns.push(columnName); } return { table: table, columns: columns }; }; /** * @protected */ Relation.prototype.mergeModels = function mergeModels(models1, models2) { var modelClass = void 0; models1 = _lodash2.default.compact(models1); models2 = _lodash2.default.compact(models2); if (_lodash2.default.isEmpty(models1) && _lodash2.default.isEmpty(models2)) { return []; } if (!_lodash2.default.isEmpty(models1)) { modelClass = models1[0].constructor; } else { modelClass = models2[0].constructor; } var idProperty = modelClass.getIdPropertyArray(); var modelsById = (0, _create2.default)(null); for (var i = 0, l = models1.length; i < l; ++i) { var model = models1[i]; var key = model.$propKey(idProperty); modelsById[key] = model; } for (var _i = 0, _l = models2.length; _i < _l; ++_i) { var _model = models2[_i]; var _key = _model.$propKey(idProperty); modelsById[_key] = _model; } return _lodash2.default.sortBy(_lodash2.default.values(modelsById), idProperty); }; /** * @protected */ Relation.prototype.resolveModel = function resolveModel(Model, modelClass, logPrefix) { var requireModel = function requireModel(path) { var ModelClass = void 0; try { // babel 6 style of exposing es6 exports to commonjs https://github.com/babel/babel/issues/2683 var module = require(path); ModelClass = (0, _classUtils.isSubclassOf)(module.default, Model) ? module.default : module; } catch (err) { return null; } if (!(0, _classUtils.isSubclassOf)(ModelClass, Model)) { return null; } return ModelClass; }; if (_lodash2.default.isString(modelClass)) { var ModelClass = null; if (isAbsolutePath(modelClass)) { ModelClass = requireModel(modelClass); } else { // If the path is not a absolute, try the modelPaths of the owner model class. _lodash2.default.each(this.ownerModelClass.modelPaths, function (modelPath) { ModelClass = requireModel(_path2.default.join(modelPath, modelClass)); if ((0, _classUtils.isSubclassOf)(ModelClass, Model)) { // Break the loop. return false; } }); } if (!(0, _classUtils.isSubclassOf)(ModelClass, Model)) { this.throwError(logPrefix + ': ' + modelClass + ' is an invalid file path to a model class'); } return ModelClass; } else { if (!(0, _classUtils.isSubclassOf)(modelClass, Model)) { this.throwError(logPrefix + ' is not a subclass of Model or a file path to a module that exports one.'); } return modelClass; } }; /** * @protected */ Relation.prototype.throwError = function throwError(message) { if (this.ownerModelClass && this.ownerModelClass.name && this.name) { throw new Error(this.ownerModelClass.name + '.relationMappings.' + this.name + ': ' + message); } else { throw new Error(this.constructor.name + ': ' + message); } }; return Relation; }(), (_applyDecoratedDescriptor(_class.prototype, 'fullRelatedCol', [_memoize2.default], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'fullRelatedCol'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'fullOwnerCol', [_memoize2.default], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'fullOwnerCol'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'relatedTableAlias', [_memoize2.default], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'relatedTableAlias'), _class.prototype)), _class); exports.default = Relation; function isAbsolutePath(pth) { return _path2.default.normalize(pth + '/') === _path2.default.normalize(_path2.default.resolve(pth) + '/'); } function containsNonNull(arr) { for (var i = 0, l = arr.length; i < l; ++i) { var val = arr[i]; if (Array.isArray(val) && containsNonNull(val)) { return true; } else if (val !== null && val !== undefined) { return true; } } return false; } //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIlJlbGF0aW9uLmpzIl0sIm5hbWVzIjpbIlJlbGF0aW9uIiwicmVsYXRpb25OYW1lIiwiT3duZXJDbGFzcyIsIm5hbWUiLCJvd25lck1vZGVsQ2xhc3MiLCJyZWxhdGVkTW9kZWxDbGFzcyIsIl9qb2luVGFibGVNb2RlbENsYXNzIiwib3duZXJDb2wiLCJvd25lclByb3AiLCJyZWxhdGVkQ29sIiwicmVsYXRlZFByb3AiLCJqb2luVGFibGUiLCJqb2luVGFibGVPd25lckNvbCIsImpvaW5UYWJsZU93bmVyUHJvcCIsImpvaW5UYWJsZVJlbGF0ZWRDb2wiLCJqb2luVGFibGVSZWxhdGVkUHJvcCIsImpvaW5UYWJsZUV4dHJhcyIsIm1vZGlmeSIsImV4dGVuZCIsInN1YmNsYXNzQ29uc3RydWN0b3IiLCJzZXRNYXBwaW5nIiwibWFwcGluZyIsIk1vZGVsIiwicmVxdWlyZSIsIl9fZGlybmFtZSIsImRlZmF1bHQiLCJ0aHJvd0Vycm9yIiwibW9kZWxDbGFzcyIsInJlc29sdmVNb2RlbCIsInJlbGF0aW9uIiwiam9pbiIsImZyb20iLCJ0byIsImpvaW5Pd25lciIsImpvaW5SZWxhdGVkIiwiam9pbkZyb20iLCJwYXJzZVJlZmVyZW5jZSIsImpvaW5UbyIsInRhYmxlIiwiaXNFbXB0eSIsImNvbHVtbnMiLCJ0YWJsZU5hbWUiLCJwcm9wZXJ0eU5hbWUiLCJwYXJzZU1vZGlmeSIsImlzT25lVG9PbmUiLCJqb2luVGFibGVNb2RlbENsYXNzIiwia25leCIsImJpbmRLbmV4IiwiZnVsbFJlbGF0ZWRDb2wiLCJtYXAiLCJjb2wiLCJmdWxsT3duZXJDb2wiLCJyZWxhdGVkVGFibGVBbGlhcyIsImNsb25lIiwiY29uc3RydWN0b3IiLCJib3VuZCIsImZpbmRRdWVyeSIsImJ1aWxkZXIiLCJvcHQiLCJpc0NvbHVtblJlZiIsImkiLCJsIiwibGVuZ3RoIiwid2hlcmVSZWYiLCJvd25lcklkcyIsImNvbnRhaW5zTm9uTnVsbCIsIndoZXJlSW5Db21wb3NpdGUiLCJyZXNvbHZlIiwiam9pbk9wZXJhdGlvbiIsInJlbGF0ZWRKb2luU2VsZWN0UXVlcnkiLCJxdWVyeSIsImNoaWxkUXVlcnlPZiIsInJlbGF0ZWRUYWJsZSIsIm93bmVyVGFibGUiLCJyZWxhdGVkU2VsZWN0IiwiYXMiLCJpc1NlbGVjdEFsbCIsIm9uIiwiaW5zZXJ0Iiwib3duZXIiLCJ1cGRhdGUiLCJwYXRjaCIsIm1vZGVsT3B0aW9ucyIsImZpbmQiLCJvd25lcnMiLCJkZWxldGUiLCJyZWxhdGUiLCJ1bnJlbGF0ZSIsImNvbHVtbk5hbWVUb1Byb3BlcnR5TmFtZSIsImNvbHVtbiIsIkVycm9yIiwiZmlsdGVyIiwiaXNGdW5jdGlvbiIsImlzT2JqZWN0IiwicXVlcnlCdWlsZGVyIiwid2hlcmUiLCJub29wIiwicmVmIiwiaXNBcnJheSIsInJlZkl0ZW0iLCJuZHgiLCJsYXN0SW5kZXhPZiIsInN1YnN0ciIsInRyaW0iLCJjb2x1bW5OYW1lIiwicHVzaCIsIm1lcmdlTW9kZWxzIiwibW9kZWxzMSIsIm1vZGVsczIiLCJjb21wYWN0IiwiaWRQcm9wZXJ0eSIsImdldElkUHJvcGVydHlBcnJheSIsIm1vZGVsc0J5SWQiLCJtb2RlbCIsImtleSIsIiRwcm9wS2V5Iiwic29ydEJ5IiwidmFsdWVzIiwibG9nUHJlZml4IiwicmVxdWlyZU1vZGVsIiwicGF0aCIsIk1vZGVsQ2xhc3MiLCJtb2R1bGUiLCJlcnIiLCJpc1N0cmluZyIsImlzQWJzb2x1dGVQYXRoIiwiZWFjaCIsIm1vZGVsUGF0aHMiLCJtb2RlbFBhdGgiLCJtZXNzYWdlIiwicHRoIiwibm9ybWFsaXplIiwiYXJyIiwidmFsIiwiQXJyYXkiLCJ1bmRlZmluZWQiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBOzs7O0FBQ0E7Ozs7QUFDQTs7OztBQUNBOztBQUNBOztBQUNBOzs7O0FBRUE7Ozs7QUFDQTs7OztBQUNBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUVBOzs7Ozs7Ozs7Ozs7QUFZQTs7Ozs7Ozs7OztBQVVB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b0U7QUFDbEUsWUFBTSxJQUFJdUYsS0FBSixDQUFhLEtBQUt0RixlQUFMLENBQXFCRCxJQUFsQywwQkFBMkQsS0FBS0EsSUFBaEUsVUFBeUU4SCxPQUF6RSxDQUFOO0FBQ0QsS0FGRCxNQUVPO0FBQ0wsWUFBTSxJQUFJdkMsS0FBSixDQUFhLEtBQUtwQyxXQUFMLENBQWlCbkQsSUFBOUIsVUFBdUM4SCxPQUF2QyxDQUFOO0FBQ0Q7QUFDRixHOzs7O2tCQXJpQmtCakksUTs7O0FBd2lCckIsU0FBUzZILGNBQVQsQ0FBd0JLLEdBQXhCLEVBQTZCO0FBQzNCLFNBQU8sZUFBS0MsU0FBTCxDQUFlRCxNQUFNLEdBQXJCLE1BQThCLGVBQUtDLFNBQUwsQ0FBZSxlQUFLaEUsT0FBTCxDQUFhK0QsR0FBYixJQUFvQixHQUFuQyxDQUFyQztBQUNEOztBQUVELFNBQVNqRSxlQUFULENBQXlCbUUsR0FBekIsRUFBOEI7QUFDNUIsT0FBSyxJQUFJeEUsSUFBSSxDQUFSLEVBQVdDLElBQUl1RSxJQUFJdEUsTUFBeEIsRUFBZ0NGLElBQUlDLENBQXBDLEVBQXVDLEVBQUVELENBQXpDLEVBQTRDO0FBQzFDLFFBQU15RSxNQUFNRCxJQUFJeEUsQ0FBSixDQUFaOztBQUVBLFFBQUkwRSxNQUFNcEMsT0FBTixDQUFjbUMsR0FBZCxLQUFzQnBFLGdCQUFnQm9FLEdBQWhCLENBQTFCLEVBQWdEO0FBQzlDLGFBQU8sSUFBUDtBQUNELEtBRkQsTUFFTyxJQUFJQSxRQUFRLElBQVIsSUFBZ0JBLFFBQVFFLFNBQTVCLEVBQXVDO0FBQzVDLGFBQU8sSUFBUDtBQUNEO0FBQ0Y7O0FBRUQsU0FBTyxLQUFQO0FBQ0QiLCJmaWxlIjoiUmVsYXRpb24uanMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgXyBmcm9tICdsb2Rhc2gnO1xuaW1wb3J0IHBhdGggZnJvbSAncGF0aCc7XG5pbXBvcnQgbWVtb2l6ZSBmcm9tICcuLi91dGlscy9kZWNvcmF0b3JzL21lbW9pemUnO1xuaW1wb3J0IHtpbmhlcml0cywgaXNTdWJjbGFzc09mfSBmcm9tICcuLi91dGlscy9jbGFzc1V0aWxzJztcbmltcG9ydCB7aW5pdCwgY29weUhpZGRlbkRhdGF9IGZyb20gJy4uL3V0aWxzL2hpZGRlbkRhdGEnO1xuaW1wb3J0IFF1ZXJ5QnVpbGRlciBmcm9tICcuLi9xdWVyeUJ1aWxkZXIvUXVlcnlCdWlsZGVyJztcblxuaW1wb3J0IFJlbGF0aW9uRmluZE9wZXJhdGlvbiBmcm9tICcuL1JlbGF0aW9uRmluZE9wZXJhdGlvbic7XG5pbXBvcnQgUmVsYXRpb25VcGRhdGVPcGVyYXRpb24gZnJvbSAnLi9SZWxhdGlvblVwZGF0ZU9wZXJhdGlvbic7XG5pbXBvcnQgUmVsYXRpb25EZWxldGVPcGVyYXRpb24gZnJvbSAnLi9SZWxhdGlvbkRlbGV0ZU9wZXJhdGlvbic7XG5cbi8qKlxuICogQHR5cGVkZWYge09iamVjdH0gUmVsYXRpb25Kb2luXG5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfEFycmF5LjxzdHJpbmc+fSBmcm9tXG4gKiBAcHJvcGVydHkge3N0cmluZ3xBcnJheS48c3RyaW5nPn0gdG9cbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSB0aHJvdWdoXG4gKiBAcHJvcGVydHkge0NvbnN0cnVjdG9yLjxNb2RlbD59IHRocm91Z2gubW9kZWxDbGFzc1xuICogQHByb3BlcnR5IHtzdHJpbmd8QXJyYXkuPHN0cmluZz59IHRocm91Z2guZnJvbVxuICogQHByb3BlcnR5IHtzdHJpbmd8QXJyYXkuPHN0cmluZz59IHRocm91Z2gudG9cbiAqIEBwcm9wZXJ0eSB7QXJyYXkuPHN0cmluZz59IHRocm91Z2guZXh0cmFcbiAqL1xuXG4vKipcbiAqIEB0eXBlZGVmIHtPYmplY3R9IFJlbGF0aW9uTWFwcGluZ1xuICpcbiAqIEBwcm9wZXJ0eSB7Q29uc3RydWN0b3IuPE1vZGVsPnxzdHJpbmd9IG1vZGVsQ2xhc3NcbiAqIEBwcm9wZXJ0eSB7UmVsYXRpb259IHJlbGF0aW9uXG4gKiBAcHJvcGVydHkge09iamVjdHxmdW5jdGlvbihRdWVyeUJ1aWxkZXIpfSBtb2RpZnlcbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fGZ1bmN0aW9uKFF1ZXJ5QnVpbGRlcil9IGZpbHRlclxuICogQHByb3BlcnR5IHtSZWxhdGlvbkpvaW59IFtqb2luXVxuICovXG5cbi8qKlxuICogQGFic3RyYWN0XG4gKi9cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFJlbGF0aW9uIHtcblxuICBjb25zdHJ1Y3RvcihyZWxhdGlvbk5hbWUsIE93bmVyQ2xhc3MpIHtcbiAgICAvKipcbiAgICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgICAqL1xuICAgIHRoaXMubmFtZSA9IHJlbGF0aW9uTmFtZTtcblxuICAgIC8qKlxuICAgICAqIEB0eXBlIHtDb25zdHJ1Y3Rvci48TW9kZWw+fVxuICAgICAqL1xuICAgIHRoaXMub3duZXJNb2RlbENsYXNzID0gT3duZXJDbGFzcztcblxuICAgIC8qKlxuICAgICAqIEB0eXBlIHtDb25zdHJ1Y3Rvci48TW9kZWw+fVxuICAgICAqL1xuICAgIHRoaXMucmVsYXRlZE1vZGVsQ2xhc3MgPSBudWxsO1xuXG4gICAgLyoqXG4gICAgICogQHR5cGUge0NvbnN0cnVjdG9yLjxNb2RlbD59XG4gICAgICovXG4gICAgdGhpcy5fam9pblRhYmxlTW9kZWxDbGFzcyA9IG51bGw7XG5cbiAgICAvKipcbiAgICAgKiBAdHlwZSB7QXJyYXkuPHN0cmluZz59XG4gICAgICovXG4gICAgdGhpcy5vd25lckNvbCA9IG51bGw7XG5cbiAgICAvKipcbiAgICAgKiBAdHlwZSB7QXJyYXkuPHN0cmluZz59XG4gICAgICovXG4gICAgdGhpcy5vd25lclByb3AgPSBudWxsO1xuXG4gICAgLyoqXG4gICAgICogQHR5cGUge0FycmF5LjxzdHJpbmc+fVxuICAgICAqL1xuICAgIHRoaXMucmVsYXRlZENvbCA9IG51bGw7XG5cbiAgICAvKipcbiAgICAgKiBAdHlwZSB7QXJyYXkuPHN0cmluZz59XG4gICAgICovXG4gICAgdGhpcy5yZWxhdGVkUHJvcCA9IG51bGw7XG5cbiAgICAvKipcbiAgICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgICAqL1xuICAgIHRoaXMuam9pblRhYmxlID0gbnVsbDtcblxuICAgIC8qKlxuICAgICAqIEB0eXBlIHtBcnJheS48c3RyaW5nPn1cbiAgICAgKi9cbiAgICB0aGlzLmpvaW5UYWJsZU93bmVyQ29sID0gbnVsbDtcblxuICAgIC8qKlxuICAgICAqIEB0eXBlIHtBcnJheS48c3RyaW5nPn1cbiAgICAgKi9cbiAgICB0aGlzLmpvaW5UYWJsZU93bmVyUHJvcCA9IG51bGw7XG5cbiAgICAvKipcbiAgICAgKiBAdHlwZSB7QXJyYXkuPHN0cmluZz59XG4gICAgICovXG4gICAgdGhpcy5qb2luVGFibGVSZWxhdGVkQ29sID0gbnVsbDtcblxuICAgIC8qKlxuICAgICAqIEB0eXBlIHtBcnJheS48c3RyaW5nPn1cbiAgICAgKi9cbiAgICB0aGlzLmpvaW5UYWJsZVJlbGF0ZWRQcm9wID0gbnVsbDtcblxuICAgIC8qKlxuICAgICAqIEB0eXBlIHtBcnJheS48e2pvaW5UYWJsZUNvbDogc3RyaW5nLCBqb2luVGFibGVQcm9wOiBzdHJpbmcsIGFsaWFzQ29sOiBzdHJpbmcsIGFsaWFzUHJvcDogc3RyaW5nfT59XG4gICAgICovXG4gICAgdGhpcy5qb2luVGFibGVFeHRyYXMgPSBbXTtcblxuICAgIC8qKlxuICAgICAqIEB0eXBlIHtmdW5jdGlvbiAoUXVlcnlCdWlsZGVyKX1cbiAgICAgKi9cbiAgICB0aGlzLm1vZGlmeSA9IG51bGw7XG5cbiAgICBpbml0KHRoaXMpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7ZnVuY3Rpb249fSBzdWJjbGFzc0NvbnN0cnVjdG9yXG4gICAqIEByZXR1cm4ge0NvbnN0cnVjdG9yLjxNb2RlbD59XG4gICAqL1xuICBzdGF0aWMgZXh0ZW5kKHN1YmNsYXNzQ29uc3RydWN0b3IpIHtcbiAgICBpbmhlcml0cyhzdWJjbGFzc0NvbnN0cnVjdG9yLCB0aGlzKTtcbiAgICByZXR1cm4gc3ViY2xhc3NDb25zdHJ1Y3RvcjtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge1JlbGF0aW9uTWFwcGluZ30gbWFwcGluZ1xuICAgKi9cbiAgc2V0TWFwcGluZyhtYXBwaW5nKSB7XG4gICAgLy8gQXZvaWQgcmVxdWlyZSBsb29wIGFuZCBpbXBvcnQgaGVyZS5cbiAgICBsZXQgTW9kZWwgPSByZXF1aXJlKF9fZGlybmFtZSArICcvLi4vbW9kZWwvTW9kZWwnKS5kZWZhdWx0O1xuXG4gICAgaWYgKCFpc1N1YmNsYXNzT2YodGhpcy5vd25lck1vZGVsQ2xhc3MsIE1vZGVsKSkge1xuICAgICAgdGhpcy50aHJvd0Vycm9yKCdSZWxhdGlvblxcJ3Mgb3duZXIgaXMgbm90IGEgc3ViY2xhc3Mgb2YgTW9kZWwnKTtcbiAgICB9XG5cbiAgICBpZiAoIW1hcHBpbmcubW9kZWxDbGFzcykge1xuICAgICAgdGhpcy50aHJvd0Vycm9yKCdtb2RlbENsYXNzIGlzIG5vdCBkZWZpbmVkJyk7XG4gICAgfVxuXG4gICAgdGhpcy5yZWxhdGVkTW9kZWxDbGFzcyA9IHRoaXMucmVzb2x2ZU1vZGVsKE1vZGVsLCBtYXBwaW5nLm1vZGVsQ2xhc3MsICdtb2RlbENsYXNzJyk7XG5cbiAgICBpZiAoIW1hcHBpbmcucmVsYXRpb24pIHtcbiAgICAgIHRoaXMudGhyb3dFcnJvcigncmVsYXRpb24gaXMgbm90IGRlZmluZWQnKTtcbiAgICB9XG5cbiAgICBpZiAoIWlzU3ViY2xhc3NPZihtYXBwaW5nLnJlbGF0aW9uLCBSZWxhdGlvbikpIHtcbiAgICAgIHRoaXMudGhyb3dFcnJvcigncmVsYXRpb24gaXMgbm90IGEgc3ViY2xhc3Mgb2YgUmVsYXRpb24nKTtcbiAgICB9XG5cbiAgICBpZiAoIW1hcHBpbmcuam9pbiB8fCAhbWFwcGluZy5qb2luLmZyb20gfHwgIW1hcHBpbmcuam9pbi50bykge1xuICAgICAgdGhpcy50aHJvd0Vycm9yKCdqb2luIG11c3QgYmUgYW4gb2JqZWN0IHRoYXQgbWFwcyB0aGUgY29sdW1ucyBvZiB0aGUgcmVsYXRlZCBtb2RlbHMgdG9nZXRoZXIuIEZvciBleGFtcGxlOiB7ZnJvbTogXCJTb21lVGFibGUuaWRcIiwgdG86IFwiU29tZU90aGVyVGFibGUuc29tZU1vZGVsSWRcIn0nKTtcbiAgICB9XG5cbiAgICBsZXQgam9pbk93bmVyID0gbnVsbDtcbiAgICBsZXQgam9pblJlbGF0ZWQgPSBudWxsO1xuXG4gICAgbGV0IGpvaW5Gcm9tID0gdGhpcy5wYXJzZVJlZmVyZW5jZShtYXBwaW5nLmpvaW4uZnJvbSk7XG4gICAgbGV0IGpvaW5UbyA9IHRoaXMucGFyc2VSZWZlcmVuY2UobWFwcGluZy5qb2luLnRvKTtcblxuICAgIGlmICgham9pbkZyb20udGFibGUgfHwgXy5pc0VtcHR5KGpvaW5Gcm9tLmNvbHVtbnMpKSB7XG4gICAgICB0aGlzLnRocm93RXJyb3IoJ2pvaW4uZnJvbSBtdXN0IGhhdmUgZm9ybWF0IFRhYmxlTmFtZS5jb2x1bW5OYW1lLiBGb3IgZXhhbXBsZSBcIlNvbWVUYWJsZS5pZFwiIG9yIGluIGNhc2Ugb2YgY29tcG9zaXRlIGtleSBbXCJTb21lVGFibGUuYVwiLCBcIlNvbWVUYWJsZS5iXCJdLicpO1xuICAgIH1cblxuICAgIGlmICgham9pblRvLnRhYmxlIHx8IF8uaXNFbXB0eShqb2luVG8uY29sdW1ucykpIHtcbiAgICAgIHRoaXMudGhyb3dFcnJvcignam9pbi50byBtdXN0IGhhdmUgZm9ybWF0IFRhYmxlTmFtZS5jb2x1bW5OYW1lLiBGb3IgZXhhbXBsZSBcIlNvbWVUYWJsZS5pZFwiIG9yIGluIGNhc2Ugb2YgY29tcG9zaXRlIGtleSBbXCJTb21lVGFibGUuYVwiLCBcIlNvbWVUYWJsZS5iXCJdLicpO1xuICAgIH1cblxuICAgIGlmIChqb2luRnJvbS50YWJsZSA9PT0gdGhpcy5vd25lck1vZGVsQ2xhc3MudGFibGVOYW1lKSB7XG4gICAgICBqb2luT3duZXIgPSBqb2luRnJvbTtcbiAgICAgIGpvaW5SZWxhdGVkID0gam9pblRvO1xuICAgIH0gZWxzZSBpZiAoam9pblRvLnRhYmxlID09PSB0aGlzLm93bmVyTW9kZWxDbGFzcy50YWJsZU5hbWUpIHtcbiAgICAgIGpvaW5Pd25lciA9IGpvaW5UbztcbiAgICAgIGpvaW5SZWxhdGVkID0gam9pbkZyb207XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMudGhyb3dFcnJvcignam9pbjogZWl0aGVyIGBmcm9tYCBvciBgdG9gIG11c3QgcG9pbnQgdG8gdGhlIG93bmVyIG1vZGVsIHRhYmxlLicpO1xuICAgIH1cblxuICAgIGlmIChqb2luUmVsYXRlZC50YWJsZSAhPT0gdGhpcy5yZWxhdGVkTW9kZWxDbGFzcy50YWJsZU5hbWUpIHtcbiAgICAgIHRoaXMudGhyb3dFcnJvcignam9pbjogZWl0aGVyIGBmcm9tYCBvciBgdG9gIG11c3QgcG9pbnQgdG8gdGhlIHJlbGF0ZWQgbW9kZWwgdGFibGUuJyk7XG4gICAgfVxuXG4gICAgdGhpcy5vd25lckNvbCA9IGpvaW5Pd25lci5jb2x1bW5zO1xuICAgIHRoaXMub3duZXJQcm9wID0gdGhpcy5wcm9wZXJ0eU5hbWUodGhpcy5vd25lckNvbCwgdGhpcy5vd25lck1vZGVsQ2xhc3MpO1xuICAgIHRoaXMucmVsYXRlZENvbCA9IGpvaW5SZWxhdGVkLmNvbHVtbnM7XG4gICAgdGhpcy5yZWxhdGVkUHJvcCA9IHRoaXMucHJvcGVydHlOYW1lKHRoaXMucmVsYXRlZENvbCwgdGhpcy5yZWxhdGVkTW9kZWxDbGFzcyk7XG4gICAgdGhpcy5tb2RpZnkgPSB0aGlzLnBhcnNlTW9kaWZ5KG1hcHBpbmcpO1xuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm4ge2Jvb2xlYW59XG4gICAqL1xuICBpc09uZVRvT25lKCkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAdHlwZSB7Q29uc3RydWN0b3IuPE1vZGVsPn1cbiAgICovXG4gIGpvaW5UYWJsZU1vZGVsQ2xhc3Moa25leCkge1xuICAgIGlmIChrbmV4ICYmIGtuZXggIT09IHRoaXMuX2pvaW5UYWJsZU1vZGVsQ2xhc3Mua25leCgpKSB7XG4gICAgICByZXR1cm4gdGhpcy5fam9pblRhYmxlTW9kZWxDbGFzcy5iaW5kS25leChrbmV4KTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHRoaXMuX2pvaW5UYWJsZU1vZGVsQ2xhc3M7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm5zIHtBcnJheS48c3RyaW5nPn1cbiAgICovXG4gIEBtZW1vaXplXG4gIGZ1bGxSZWxhdGVkQ29sKCkge1xuICAgIHJldHVybiB0aGlzLnJlbGF0ZWRDb2wubWFwKGNvbCA9PiB0aGlzLnJlbGF0ZWRNb2RlbENsYXNzLnRhYmxlTmFtZSArICcuJyArIGNvbCk7XG4gIH1cblxuICAvKipcbiAgICogQHJldHVybnMge0FycmF5LjxzdHJpbmc+fVxuICAgKi9cbiAgQG1lbW9pemVcbiAgZnVsbE93bmVyQ29sKCkge1xuICAgIHJldHVybiB0aGlzLm93bmVyQ29sLm1hcChjb2wgPT4gdGhpcy5vd25lck1vZGVsQ2xhc3MudGFibGVOYW1lICsgJy4nICsgY29sKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJucyB7c3RyaW5nfVxuICAgKi9cbiAgQG1lbW9pemVcbiAgcmVsYXRlZFRhYmxlQWxpYXMoKSB7XG4gICAgcmV0dXJuIHRoaXMucmVsYXRlZE1vZGVsQ2xhc3MudGFibGVOYW1lICsgJ19yZWxfJyArIHRoaXMubmFtZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJucyB7UmVsYXRpb259XG4gICAqL1xuICBjbG9uZSgpIHtcbiAgICBjb25zdCByZWxhdGlvbiA9IG5ldyB0aGlzLmNvbnN0cnVjdG9yKHRoaXMubmFtZSwgdGhpcy5vd25lck1vZGVsQ2xhc3MpO1xuXG4gICAgcmVsYXRpb24ucmVsYXRlZE1vZGVsQ2xhc3MgPSB0aGlzLnJlbGF0ZWRNb2RlbENsYXNzO1xuICAgIHJlbGF0aW9uLm93bmVyQ29sID0gdGhpcy5vd25lckNvbDtcbiAgICByZWxhdGlvbi5vd25lclByb3AgPSB0aGlzLm93bmVyUHJvcDtcbiAgICByZWxhdGlvbi5yZWxhdGVkQ29sID0gdGhpcy5yZWxhdGVkQ29sO1xuICAgIHJlbGF0aW9uLnJlbGF0ZWRQcm9wID0gdGhpcy5yZWxhdGVkUHJvcDtcbiAgICByZWxhdGlvbi5tb2RpZnkgPSB0aGlzLm1vZGlmeTtcblxuICAgIHJlbGF0aW9uLl9qb2luVGFibGVNb2RlbENsYXNzID0gdGhpcy5fam9pblRhYmxlTW9kZWxDbGFzcztcbiAgICByZWxhdGlvbi5qb2luVGFibGUgPSB0aGlzLmpvaW5UYWJsZTtcbiAgICByZWxhdGlvbi5qb2luVGFibGVPd25lckNvbCA9IHRoaXMuam9pblRhYmxlT3duZXJDb2w7XG4gICAgcmVsYXRpb24uam9pblRhYmxlT3duZXJQcm9wID0gdGhpcy5qb2luVGFibGVPd25lclByb3A7XG4gICAgcmVsYXRpb24uam9pblRhYmxlUmVsYXRlZENvbCA9IHRoaXMuam9pblRhYmxlUmVsYXRlZENvbDtcbiAgICByZWxhdGlvbi5qb2luVGFibGVSZWxhdGVkUHJvcCA9IHRoaXMuam9pblRhYmxlUmVsYXRlZFByb3A7XG4gICAgcmVsYXRpb24uam9pblRhYmxlRXh0cmFzID0gdGhpcy5qb2luVGFibGVFeHRyYXM7XG5cbiAgICBjb3B5SGlkZGVuRGF0YSh0aGlzLCByZWxhdGlvbik7XG5cbiAgICByZXR1cm4gcmVsYXRpb247XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtrbmV4fSBrbmV4XG4gICAqIEByZXR1cm5zIHtSZWxhdGlvbn1cbiAgICovXG4gIGJpbmRLbmV4KGtuZXgpIHtcbiAgICBjb25zdCBib3VuZCA9IHRoaXMuY2xvbmUoKTtcblxuICAgIGJvdW5kLnJlbGF0ZWRNb2RlbENsYXNzID0gdGhpcy5yZWxhdGVkTW9kZWxDbGFzcy5iaW5kS25leChrbmV4KTtcbiAgICBib3VuZC5vd25lck1vZGVsQ2xhc3MgPSB0aGlzLm93bmVyTW9kZWxDbGFzcy5iaW5kS25leChrbmV4KTtcblxuICAgIHJldHVybiBib3VuZDtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge1F1ZXJ5QnVpbGRlcn0gYnVpbGRlclxuICAgKiBAcGFyYW0ge29iamVjdH0gb3B0XG4gICAqIEBwYXJhbSB7QXJyYXkuPHN0cmluZz58QXJyYXkuPEFycmF5Ljwoc3RyaW5nfG51bWJlcik+Pn0gb3B0Lm93bmVySWRzXG4gICAqIEBwYXJhbSB7Ym9vbGVhbj19IG9wdC5pc0NvbHVtblJlZlxuICAgKiBAcmV0dXJucyB7UXVlcnlCdWlsZGVyfVxuICAgKi9cbiAgZmluZFF1ZXJ5KGJ1aWxkZXIsIG9wdCkge1xuICAgIGNvbnN0IGZ1bGxSZWxhdGVkQ29sID0gdGhpcy5mdWxsUmVsYXRlZENvbCgpO1xuXG4gICAgaWYgKG9wdC5pc0NvbHVtblJlZikge1xuICAgICAgZm9yIChsZXQgaSA9IDAsIGwgPSBmdWxsUmVsYXRlZENvbC5sZW5ndGg7IGkgPCBsOyArK2kpIHtcbiAgICAgICAgYnVpbGRlci53aGVyZVJlZihmdWxsUmVsYXRlZENvbFtpXSwgb3B0Lm93bmVySWRzW2ldKTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGNvbnRhaW5zTm9uTnVsbChvcHQub3duZXJJZHMpKSB7XG4gICAgICBidWlsZGVyLndoZXJlSW5Db21wb3NpdGUoZnVsbFJlbGF0ZWRDb2wsIG9wdC5vd25lcklkcyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGJ1aWxkZXIucmVzb2x2ZShbXSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGJ1aWxkZXIubW9kaWZ5KHRoaXMubW9kaWZ5KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge1F1ZXJ5QnVpbGRlcn0gYnVpbGRlclxuICAgKiBAcGFyYW0ge29iamVjdD19IG9wdFxuICAgKiBAcmV0dXJucyB7UXVlcnlCdWlsZGVyfVxuICAgKi9cbiAgam9pbihidWlsZGVyLCBvcHQpIHtcbiAgICBvcHQgPSBvcHQgfHwge307XG5cbiAgICBvcHQuam9pbk9wZXJhdGlvbiA9IG9wdC5qb2luT3BlcmF0aW9uIHx8ICdqb2luJztcbiAgICBvcHQucmVsYXRlZFRhYmxlQWxpYXMgPSBvcHQucmVsYXRlZFRhYmxlQWxpYXMgfHwgdGhpcy5yZWxhdGVkVGFibGVBbGlhcygpO1xuICAgIG9wdC5yZWxhdGVkSm9pblNlbGVjdFF1ZXJ5ID0gb3B0LnJlbGF0ZWRKb2luU2VsZWN0UXVlcnkgfHwgdGhpcy5yZWxhdGVkTW9kZWxDbGFzcy5xdWVyeSgpLmNoaWxkUXVlcnlPZihidWlsZGVyKTtcbiAgICBvcHQucmVsYXRlZFRhYmxlID0gb3B0LnJlbGF0ZWRUYWJsZSB8fCB0aGlzLnJlbGF0ZWRNb2RlbENsYXNzLnRhYmxlTmFtZTtcbiAgICBvcHQub3duZXJUYWJsZSA9IG9wdC5vd25lclRhYmxlIHx8IHRoaXMub3duZXJNb2RlbENsYXNzLnRhYmxlTmFtZTtcblxuICAgIGNvbnN0IHJlbGF0ZWRDb2wgPSB0aGlzLnJlbGF0ZWRDb2wubWFwKGNvbCA9PiBgJHtvcHQucmVsYXRlZFRhYmxlQWxpYXN9LiR7Y29sfWApO1xuICAgIGNvbnN0IG93bmVyQ29sID0gdGhpcy5vd25lckNvbC5tYXAoY29sID0+IGAke29wdC5vd25lclRhYmxlfS4ke2NvbH1gKTtcblxuICAgIGxldCByZWxhdGVkU2VsZWN0ID0gb3B0LnJlbGF0ZWRKb2luU2VsZWN0UXVlcnlcbiAgICAgIC5tb2RpZnkodGhpcy5tb2RpZnkpXG4gICAgICAuYXMob3B0LnJlbGF0ZWRUYWJsZUFsaWFzKTtcblxuICAgIGlmIChyZWxhdGVkU2VsZWN0LmlzU2VsZWN0QWxsKCkpIHtcbiAgICAgIC8vIE5vIG5lZWQgdG8gam9pbiBhIHN1YnF1ZXJ5IGlmIHRoZSBxdWVyeSBpcyBgc2VsZWN0ICogZnJvbSBcIlJlbGF0ZWRUYWJsZVwiYC5cbiAgICAgIHJlbGF0ZWRTZWxlY3QgPSBgJHt0aGlzLnJlbGF0ZWRNb2RlbENsYXNzLnRhYmxlTmFtZX0gYXMgJHtvcHQucmVsYXRlZFRhYmxlQWxpYXN9YFxuICAgIH1cblxuICAgIHJldHVybiBidWlsZGVyXG4gICAgICBbb3B0LmpvaW5PcGVyYXRpb25dKHJlbGF0ZWRTZWxlY3QsIGpvaW4gPT4ge1xuICAgICAgICBmb3IgKGxldCBpID0gMCwgbCA9IHJlbGF0ZWRDb2wubGVuZ3RoOyBpIDwgbDsgKytpKSB7XG4gICAgICAgICAgam9pbi5vbihyZWxhdGVkQ29sW2ldLCAnPScsIG93bmVyQ29sW2ldKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gIH1cblxuICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICAvKipcbiAgICogQGFic3RyYWN0XG4gICAqIEBwYXJhbSB7UXVlcnlCdWlsZGVyfSBidWlsZGVyXG4gICAqIEBwYXJhbSB7TW9kZWx9IG93bmVyXG4gICAqIEByZXR1cm5zIHtRdWVyeUJ1aWxkZXJPcGVyYXRpb259XG4gICAqL1xuICBpbnNlcnQoYnVpbGRlciwgb3duZXIpIHtcbiAgICB0aGlzLnRocm93RXJyb3IoJ25vdCBpbXBsZW1lbnRlZCcpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7UXVlcnlCdWlsZGVyfSBidWlsZGVyXG4gICAqIEBwYXJhbSB7TW9kZWx9IG93bmVyXG4gICAqIEByZXR1cm5zIHtRdWVyeUJ1aWxkZXJPcGVyYXRpb259XG4gICAqL1xuICB1cGRhdGUoYnVpbGRlciwgb3duZXIpIHtcbiAgICByZXR1cm4gbmV3IFJlbGF0aW9uVXBkYXRlT3BlcmF0aW9uKCd1cGRhdGUnLCB7XG4gICAgICByZWxhdGlvbjogdGhpcyxcbiAgICAgIG93bmVyOiBvd25lclxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7UXVlcnlCdWlsZGVyfSBidWlsZGVyXG4gICAqIEBwYXJhbSB7TW9kZWx9IG93bmVyXG4gICAqIEByZXR1cm5zIHtRdWVyeUJ1aWxkZXJPcGVyYXRpb259XG4gICAqL1xuICBwYXRjaChidWlsZGVyLCBvd25lcikge1xuICAgIHJldHVybiBuZXcgUmVsYXRpb25VcGRhdGVPcGVyYXRpb24oJ3BhdGNoJywge1xuICAgICAgcmVsYXRpb246IHRoaXMsXG4gICAgICBvd25lcjogb3duZXIsXG4gICAgICBtb2RlbE9wdGlvbnM6IHtwYXRjaDogdHJ1ZX1cbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge1F1ZXJ5QnVpbGRlcn0gYnVpbGRlclxuICAgKiBAcGFyYW0ge0FycmF5LjxNb2RlbD59IG93bmVyc1xuICAgKiBAcmV0dXJucyB7UXVlcnlCdWlsZGVyT3BlcmF0aW9ufVxuICAgKi9cbiAgZmluZChidWlsZGVyLCBvd25lcnMpIHtcbiAgICByZXR1cm4gbmV3IFJlbGF0aW9uRmluZE9wZXJhdGlvbignZmluZCcsIHtcbiAgICAgIHJlbGF0aW9uOiB0aGlzLFxuICAgICAgb3duZXJzOiBvd25lcnNcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge1F1ZXJ5QnVpbGRlcn0gYnVpbGRlclxuICAgKiBAcGFyYW0ge01vZGVsfSBvd25lclxuICAgKiBAcmV0dXJucyB7UXVlcnlCdWlsZGVyT3BlcmF0aW9ufVxuICAgKi9cbiAgZGVsZXRlKGJ1aWxkZXIsIG93bmVyKSB7XG4gIC