UNPKG

objection

Version:
445 lines (335 loc) 33.8 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = undefined; var _create = require('babel-runtime/core-js/object/create'); var _create2 = _interopRequireDefault(_create); 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 _createClass2 = require('babel-runtime/helpers/createClass'); var _createClass3 = _interopRequireDefault(_createClass2); var _lodash = require('lodash'); var _lodash2 = _interopRequireDefault(_lodash); var _relationExpressionParser = require('./parsers/relationExpressionParser'); var _relationExpressionParser2 = _interopRequireDefault(_relationExpressionParser); var _ValidationError = require('../model/ValidationError'); var _ValidationError2 = _interopRequireDefault(_ValidationError); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var RECURSIVE_REGEX = /^\^(\d*)$/; var ALL_RECURSIVE_REGEX = /^\*$/; var RelationExpression = function () { function RelationExpression(node, recursionDepth, filters) { (0, _classCallCheck3.default)(this, RelationExpression); node = node || {}; this.name = node.name || null; this.args = node.args || []; this.numChildren = node.numChildren || 0; this.children = node.children || {}; Object.defineProperty(this, '_recursionDepth', { enumerable: false, value: recursionDepth || 0 }); Object.defineProperty(this, '_filters', { enumerable: false, writable: true, value: filters || {} }); } /** * @param {string|RelationExpression} expr * @returns {RelationExpression} */ RelationExpression.parse = function parse(expr) { if (expr instanceof RelationExpression) { return expr; } else if (!_lodash2.default.isString(expr) || _lodash2.default.isEmpty(expr.trim())) { return new RelationExpression(); } else { try { return new RelationExpression(_relationExpressionParser2.default.parse(expr)); } catch (err) { throw new _ValidationError2.default({ message: 'Invalid relation expression "' + expr + '"', cause: err.message }); } } }; /** * @param {Object|Array} graph */ RelationExpression.fromGraph = function fromGraph(graph) { if (!graph) { return new RelationExpression(); } return new RelationExpression(modelGraphToNode(graph, newNode())); }; /** * @param {string|RelationExpression} expr * @returns {RelationExpression} */ RelationExpression.prototype.merge = function merge(expr) { var merged = this.clone(); expr = RelationExpression.parse(expr); merged.numChildren += expr.numChildren; merged.children = _lodash2.default.merge(merged.children, expr.children); merged.args = _lodash2.default.merge(merged.args, expr.args); merged.filters = _lodash2.default.merge(merged.filters, expr.filters); // Handle recursive and all recursive nodes. visit(merged, function (node, childNames) { var maxName = null; var maxDepth = 0; var recurCount = 0; for (var i = 0, l = childNames.length; i < l; ++i) { var name = childNames[i]; var depth = _maxRecursionDepth(name); if (depth > 0) { recurCount++; } if (depth > maxDepth) { maxDepth = depth; maxName = name; } } if (recurCount > 0) { delete node.children[node.name]; } if (recurCount > 1) { for (var _i = 0, _l = childNames.length; _i < _l; ++_i) { var _name = childNames[_i]; if (_name !== maxName) { delete node.children[_name]; } } } }); return merged; }; /** * @param {string|RelationExpression} expr * @returns {boolean} */ RelationExpression.prototype.isSubExpression = function isSubExpression(expr) { var _this = this; expr = RelationExpression.parse(expr); if (this.isAllRecursive()) { return true; } if (expr.isAllRecursive()) { return this.isAllRecursive(); } if (this.name !== expr.name) { return false; } var maxRecursionDepth = expr.maxRecursionDepth(); if (maxRecursionDepth > 0) { return this.isAllRecursive() || this.maxRecursionDepth() >= maxRecursionDepth; } return _lodash2.default.every(expr.children, function (child, childName) { var ownSubExpression = _this.childExpression(childName); var subExpression = expr.childExpression(childName); return ownSubExpression && ownSubExpression.isSubExpression(subExpression); }); }; /** * @returns {number} */ RelationExpression.prototype.maxRecursionDepth = function maxRecursionDepth() { if (this.numChildren !== 1) { return 0; } var key = (0, _keys2.default)(this.children)[0]; return _maxRecursionDepth(key); }; /** * @returns {boolean} */ RelationExpression.prototype.isAllRecursive = function isAllRecursive() { if (this.numChildren !== 1) { return false; } var key = (0, _keys2.default)(this.children)[0]; return ALL_RECURSIVE_REGEX.test(key); }; /** * @returns {RelationExpression} */ RelationExpression.prototype.childExpression = function childExpression(childName) { if (this.isAllRecursive() || childName === this.name && this._recursionDepth < this.maxRecursionDepth() - 1) { return new RelationExpression(this, this._recursionDepth + 1, this._filters); } if (this.children[childName]) { return new RelationExpression(this.children[childName], 0, this._filters); } else { return null; } }; /** * @returns {RelationExpression} */ RelationExpression.prototype.clone = function clone() { var node = { name: this.name, args: this.args, numChildren: this.numChildren, children: _lodash2.default.cloneDeep(this.children) }; var filters = _lodash2.default.clone(this._filters); return new RelationExpression(node, this._recursionDepth, filters); }; RelationExpression.prototype.forEachChild = function forEachChild(cb) { _lodash2.default.forOwn(this.children, function (child, childName) { if (!ALL_RECURSIVE_REGEX.test(childName) && !RECURSIVE_REGEX.test(childName)) { cb(child, childName); } }); }; /** * @param {string|RelationExpression} path * @param {function(QueryBuilder)} filter */ RelationExpression.prototype.addAnonymousFilterAtPath = function addAnonymousFilterAtPath(path, filter) { var filterNodes = this._nodesAtPath(path); var filters = this.filters; var idx = 0; var filterName = '_efe0_'; while (filters[filterName]) { filterName = '_efe' + ++idx + '_'; } if (!_lodash2.default.isEmpty(filterNodes)) { filters[filterName] = filter; _lodash2.default.each(filterNodes, function (node) { return node.args.push(filterName); }); } }; /** * @returns {string} */ RelationExpression.prototype.toString = function toString() { return _toString(this); }; /** * @private * @return {Array.<Object>} */ RelationExpression.prototype._nodesAtPath = function _nodesAtPath(pathExpression) { var path = RelationExpression.parse(pathExpression); var nodes = []; RelationExpression.nodesAtPath(this, path, nodes); return nodes; }; /** * @private */ RelationExpression.nodesAtPath = function nodesAtPath(target, path, expressions) { var _this2 = this; if (path.numChildren == 0) { expressions.push(target); } else { _lodash2.default.forOwn(path.children, function (child) { var targetChild = target.children[child.name]; if (targetChild) { _this2.nodesAtPath(targetChild, child, expressions); } }); } }; (0, _createClass3.default)(RelationExpression, [{ key: 'filters', get: function get() { return this._filters; }, set: function set(filters) { this._filters = filters || {}; } }]); return RelationExpression; }(); exports.default = RelationExpression; function _maxRecursionDepth(key) { var rec = RECURSIVE_REGEX.exec(key); if (rec) { var maxDepth = rec[1]; if (maxDepth) { return parseInt(maxDepth, 10); } else { return Number.POSITIVE_INFINITY; } } else { return 0; } } function visit(node, visitor) { var keys = (0, _keys2.default)(node.children); visitor(node, keys); for (var i = 0, l = keys.length; i < l; ++i) { var key = keys[i]; var childNode = node.children[key]; if (childNode) { visit(childNode, visitor); } } } function _toString(node) { var childExpr = _lodash2.default.values(node.children).map(_toString); if (childExpr.length > 1) { childExpr = '[' + childExpr.join(', ') + ']'; } else { childExpr = childExpr[0]; } var str = node.name; if (node.args.length) { str += '(' + node.args.join(', ') + ')'; } if (childExpr) { if (str) { return str + '.' + childExpr; } else { return childExpr; } } else { return str; } } function modelGraphToNode(models, node) { if (!models) { return; } if (Array.isArray(models)) { for (var i = 0, l = models.length; i < l; ++i) { modelToNode(models[i], node); } } else { modelToNode(models, node); } return node; } function modelToNode(model, node) { var modelClass = model.constructor; var relations = modelClass.getRelationArray(); for (var r = 0, lr = relations.length; r < lr; ++r) { var relName = relations[r].name; if (model.hasOwnProperty(relName)) { var childNode = node.children[relName]; if (!childNode) { childNode = newNode(relName); node.children[relName] = childNode; node.numChildren++; } modelGraphToNode(model[relName], childNode); } } } function newNode(name) { return { name: name || '', args: [], children: (0, _create2.default)(null), numChildren: 0 }; } //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIlJlbGF0aW9uRXhwcmVzc2lvbi5qcyJdLCJuYW1lcyI6WyJSRUNVUlNJVkVfUkVHRVgiLCJBTExfUkVDVVJTSVZFX1JFR0VYIiwiUmVsYXRpb25FeHByZXNzaW9uIiwibm9kZSIsInJlY3Vyc2lvbkRlcHRoIiwiZmlsdGVycyIsIm5hbWUiLCJhcmdzIiwibnVtQ2hpbGRyZW4iLCJjaGlsZHJlbiIsIk9iamVjdCIsImRlZmluZVByb3BlcnR5IiwiZW51bWVyYWJsZSIsInZhbHVlIiwid3JpdGFibGUiLCJwYXJzZSIsImV4cHIiLCJpc1N0cmluZyIsImlzRW1wdHkiLCJ0cmltIiwiZXJyIiwibWVzc2FnZSIsImNhdXNlIiwiZnJvbUdyYXBoIiwiZ3JhcGgiLCJtb2RlbEdyYXBoVG9Ob2RlIiwibmV3Tm9kZSIsIm1lcmdlIiwibWVyZ2VkIiwiY2xvbmUiLCJ2aXNpdCIsImNoaWxkTmFtZXMiLCJtYXhOYW1lIiwibWF4RGVwdGgiLCJyZWN1ckNvdW50IiwiaSIsImwiLCJsZW5ndGgiLCJkZXB0aCIsIm1heFJlY3Vyc2lvbkRlcHRoIiwiaXNTdWJFeHByZXNzaW9uIiwiaXNBbGxSZWN1cnNpdmUiLCJldmVyeSIsImNoaWxkIiwiY2hpbGROYW1lIiwib3duU3ViRXhwcmVzc2lvbiIsImNoaWxkRXhwcmVzc2lvbiIsInN1YkV4cHJlc3Npb24iLCJrZXkiLCJ0ZXN0IiwiX3JlY3Vyc2lvbkRlcHRoIiwiX2ZpbHRlcnMiLCJjbG9uZURlZXAiLCJmb3JFYWNoQ2hpbGQiLCJjYiIsImZvck93biIsImFkZEFub255bW91c0ZpbHRlckF0UGF0aCIsInBhdGgiLCJmaWx0ZXIiLCJmaWx0ZXJOb2RlcyIsIl9ub2Rlc0F0UGF0aCIsImlkeCIsImZpbHRlck5hbWUiLCJlYWNoIiwicHVzaCIsInRvU3RyaW5nIiwicGF0aEV4cHJlc3Npb24iLCJub2RlcyIsIm5vZGVzQXRQYXRoIiwidGFyZ2V0IiwiZXhwcmVzc2lvbnMiLCJ0YXJnZXRDaGlsZCIsInJlYyIsImV4ZWMiLCJwYXJzZUludCIsIk51bWJlciIsIlBPU0lUSVZFX0lORklOSVRZIiwidmlzaXRvciIsImtleXMiLCJjaGlsZE5vZGUiLCJjaGlsZEV4cHIiLCJ2YWx1ZXMiLCJtYXAiLCJqb2luIiwic3RyIiwibW9kZWxzIiwiQXJyYXkiLCJpc0FycmF5IiwibW9kZWxUb05vZGUiLCJtb2RlbCIsIm1vZGVsQ2xhc3MiLCJjb25zdHJ1Y3RvciIsInJlbGF0aW9ucyIsImdldFJlbGF0aW9uQXJyYXkiLCJyIiwibHIiLCJyZWxOYW1lIiwiaGFzT3duUHJvcGVydHkiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUE7Ozs7QUFDQTs7OztBQUNBOzs7Ozs7QUFFQSxJQUFNQSxrQkFBa0IsV0FBeEI7QUFDQSxJQUFNQyxzQkFBc0IsTUFBNUI7O0lBRXFCQyxrQjtBQUVuQiw4QkFBWUMsSUFBWixFQUFrQkMsY0FBbEIsRUFBa0NDLE9BQWxDLEVBQTJDO0FBQUE7O0FBQ3pDRixXQUFPQSxRQUFRLEVBQWY7O0FBRUEsU0FBS0csSUFBTCxHQUFZSCxLQUFLRyxJQUFMLElBQWEsSUFBekI7QUFDQSxTQUFLQyxJQUFMLEdBQVlKLEtBQUtJLElBQUwsSUFBYSxFQUF6QjtBQUNBLFNBQUtDLFdBQUwsR0FBbUJMLEtBQUtLLFdBQUwsSUFBb0IsQ0FBdkM7QUFDQSxTQUFLQyxRQUFMLEdBQWdCTixLQUFLTSxRQUFMLElBQWlCLEVBQWpDOztBQUVBQyxXQUFPQyxjQUFQLENBQXNCLElBQXRCLEVBQTRCLGlCQUE1QixFQUErQztBQUM3Q0Msa0JBQVksS0FEaUM7QUFFN0NDLGFBQU9ULGtCQUFrQjtBQUZvQixLQUEvQzs7QUFLQU0sV0FBT0MsY0FBUCxDQUFzQixJQUF0QixFQUE0QixVQUE1QixFQUF3QztBQUN0Q0Msa0JBQVksS0FEMEI7QUFFdENFLGdCQUFVLElBRjRCO0FBR3RDRCxhQUFPUixXQUFXO0FBSG9CLEtBQXhDO0FBS0Q7O0FBRUQ7Ozs7OztxQkFJT1UsSyxrQkFBTUMsSSxFQUFNO0FBQ2pCLFFBQUlBLGdCQUFn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RCxrQkFBWUgsT0FBT2xELENBQVAsQ0FBWixFQUF1QmhDLElBQXZCO0FBQ0Q7QUFDRixHQUpELE1BSU87QUFDTHFGLGdCQUFZSCxNQUFaLEVBQW9CbEYsSUFBcEI7QUFDRDs7QUFFRCxTQUFPQSxJQUFQO0FBQ0Q7O0FBRUQsU0FBU3FGLFdBQVQsQ0FBcUJDLEtBQXJCLEVBQTRCdEYsSUFBNUIsRUFBa0M7QUFDaEMsTUFBTXVGLGFBQWFELE1BQU1FLFdBQXpCO0FBQ0EsTUFBTUMsWUFBWUYsV0FBV0csZ0JBQVgsRUFBbEI7O0FBRUEsT0FBSyxJQUFJQyxJQUFJLENBQVIsRUFBV0MsS0FBS0gsVUFBVXZELE1BQS9CLEVBQXVDeUQsSUFBSUMsRUFBM0MsRUFBK0MsRUFBRUQsQ0FBakQsRUFBb0Q7QUFDbEQsUUFBTUUsVUFBVUosVUFBVUUsQ0FBVixFQUFheEYsSUFBN0I7O0FBRUEsUUFBSW1GLE1BQU1RLGNBQU4sQ0FBcUJELE9BQXJCLENBQUosRUFBbUM7QUFDakMsVUFBSWpCLFlBQVk1RSxLQUFLTSxRQUFMLENBQWN1RixPQUFkLENBQWhCOztBQUVBLFVBQUksQ0FBQ2pCLFNBQUwsRUFBZ0I7QUFDZEEsb0JBQVlyRCxRQUFRc0UsT0FBUixDQUFaOztBQUVBN0YsYUFBS00sUUFBTCxDQUFjdUYsT0FBZCxJQUF5QmpCLFNBQXpCO0FBQ0E1RSxhQUFLSyxXQUFMO0FBQ0Q7O0FBRURpQix1QkFBaUJnRSxNQUFNTyxPQUFOLENBQWpCLEVBQWlDakIsU0FBakM7QUFDRDtBQUNGO0FBQ0Y7O0FBRUQsU0FBU3JELE9BQVQsQ0FBaUJwQixJQUFqQixFQUF1QjtBQUNyQixTQUFPO0FBQ0xBLFVBQU1BLFFBQVEsRUFEVDtBQUVMQyxVQUFNLEVBRkQ7QUFHTEUsY0FBVSxzQkFBYyxJQUFkLENBSEw7QUFJTEQsaUJBQWE7QUFKUixHQUFQO0FBTUQiLCJmaWxlIjoiUmVsYXRpb25FeHByZXNzaW9uLmpzIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IF8gZnJvbSAnbG9kYXNoJztcbmltcG9ydCBwYXJzZXIgZnJvbSAnLi9wYXJzZXJzL3JlbGF0aW9uRXhwcmVzc2lvblBhcnNlcic7XG5pbXBvcnQgVmFsaWRhdGlvbkVycm9yIGZyb20gJy4uL21vZGVsL1ZhbGlkYXRpb25FcnJvcic7XG5cbmNvbnN0IFJFQ1VSU0lWRV9SRUdFWCA9IC9eXFxeKFxcZCopJC87XG5jb25zdCBBTExfUkVDVVJTSVZFX1JFR0VYID0gL15cXCokLztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgUmVsYXRpb25FeHByZXNzaW9uIHtcblxuICBjb25zdHJ1Y3Rvcihub2RlLCByZWN1cnNpb25EZXB0aCwgZmlsdGVycykge1xuICAgIG5vZGUgPSBub2RlIHx8IHt9O1xuXG4gICAgdGhpcy5uYW1lID0gbm9kZS5uYW1lIHx8IG51bGw7XG4gICAgdGhpcy5hcmdzID0gbm9kZS5hcmdzIHx8IFtdO1xuICAgIHRoaXMubnVtQ2hpbGRyZW4gPSBub2RlLm51bUNoaWxkcmVuIHx8IDA7XG4gICAgdGhpcy5jaGlsZHJlbiA9IG5vZGUuY2hpbGRyZW4gfHwge307XG5cbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywgJ19yZWN1cnNpb25EZXB0aCcsIHtcbiAgICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgICAgdmFsdWU6IHJlY3Vyc2lvbkRlcHRoIHx8IDBcbiAgICB9KTtcblxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCAnX2ZpbHRlcnMnLCB7XG4gICAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICAgIHdyaXRhYmxlOiB0cnVlLFxuICAgICAgdmFsdWU6IGZpbHRlcnMgfHwge31cbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge3N0cmluZ3xSZWxhdGlvbkV4cHJlc3Npb259IGV4cHJcbiAgICogQHJldHVybnMge1JlbGF0aW9uRXhwcmVzc2lvbn1cbiAgICovXG4gIHN0YXRpYyBwYXJzZShleHByKSB7XG4gICAgaWYgKGV4cHIgaW5zdGFuY2VvZiBSZWxhdGlvbkV4cHJlc3Npb24pIHtcbiAgICAgIHJldHVybiBleHByO1xuICAgIH0gZWxzZSBpZiAoIV8uaXNTdHJpbmcoZXhwcikgfHwgXy5pc0VtcHR5KGV4cHIudHJpbSgpKSkge1xuICAgICAgcmV0dXJuIG5ldyBSZWxhdGlvbkV4cHJlc3Npb24oKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdHJ5IHtcbiAgICAgICAgcmV0dXJuIG5ldyBSZWxhdGlvbkV4cHJlc3Npb24ocGFyc2VyLnBhcnNlKGV4cHIpKTtcbiAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICB0aHJvdyBuZXcgVmFsaWRhdGlvbkVycm9yKHtcbiAgICAgICAgICBtZXNzYWdlOiAnSW52YWxpZCByZWxhdGlvbiBleHByZXNzaW9uIFwiJyArIGV4cHIgKyAnXCInLFxuICAgICAgICAgIGNhdXNlOiBlcnIubWVzc2FnZVxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtPYmplY3R8QXJyYXl9IGdyYXBoXG4gICAqL1xuICBzdGF0aWMgZnJvbUdyYXBoKGdyYXBoKSB7XG4gICAgaWYgKCFncmFwaCkge1xuICAgICAgcmV0dXJuIG5ldyBSZWxhdGlvbkV4cHJlc3Npb24oKTtcbiAgICB9XG5cbiAgICByZXR1cm4gbmV3IFJlbGF0aW9uRXhwcmVzc2lvbihtb2RlbEdyYXBoVG9Ob2RlKGdyYXBoLCBuZXdOb2RlKCkpKTtcbiAgfVxuXG4gIGdldCBmaWx0ZXJzKCkge1xuICAgIHJldHVybiB0aGlzLl9maWx0ZXJzO1xuICB9XG5cbiAgc2V0IGZpbHRlcnMoZmlsdGVycykge1xuICAgIHRoaXMuX2ZpbHRlcnMgPSBmaWx0ZXJzIHx8IHt9O1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7c3RyaW5nfFJlbGF0aW9uRXhwcmVzc2lvbn0gZXhwclxuICAgKiBAcmV0dXJucyB7UmVsYXRpb25FeHByZXNzaW9ufVxuICAgKi9cbiAgbWVyZ2UoZXhwcikge1xuICAgIGNvbnN0IG1lcmdlZCA9IHRoaXMuY2xvbmUoKTtcbiAgICBleHByID0gUmVsYXRpb25FeHByZXNzaW9uLnBhcnNlKGV4cHIpO1xuXG4gICAgbWVyZ2VkLm51bUNoaWxkcmVuICs9IGV4cHIubnVtQ2hpbGRyZW47XG4gICAgbWVyZ2VkLmNoaWxkcmVuID0gXy5tZXJnZShtZXJnZWQuY2hpbGRyZW4sIGV4cHIuY2hpbGRyZW4pO1xuICAgIG1lcmdlZC5hcmdzID0gXy5tZXJnZShtZXJnZWQuYXJncywgZXhwci5hcmdzKTtcbiAgICBtZXJnZWQuZmlsdGVycyA9IF8ubWVyZ2UobWVyZ2VkLmZpbHRlcnMsIGV4cHIuZmlsdGVycyk7XG5cbiAgICAvLyBIYW5kbGUgcmVjdXJzaXZlIGFuZCBhbGwgcmVjdXJzaXZlIG5vZGVzLlxuICAgIHZpc2l0KG1lcmdlZCwgKG5vZGUsIGNoaWxkTmFtZXMpID0+IHtcbiAgICAgIGxldCBtYXhOYW1lID0gbnVsbDtcbiAgICAgIGxldCBtYXhEZXB0aCA9IDA7XG4gICAgICBsZXQgcmVjdXJDb3VudCA9IDA7XG5cbiAgICAgIGZvciAobGV0IGkgPSAwLCBsID0gY2hpbGROYW1lcy5sZW5ndGg7IGkgPCBsOyArK2kpIHtcbiAgICAgICAgY29uc3QgbmFtZSA9IGNoaWxkTmFtZXNbaV07XG4gICAgICAgIGNvbnN0IGRlcHRoID0gbWF4UmVjdXJzaW9uRGVwdGgobmFtZSk7XG5cbiAgICAgICAgaWYgKGRlcHRoID4gMCkge1xuICAgICAgICAgIHJlY3VyQ291bnQrKztcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChkZXB0aCA+IG1heERlcHRoKSB7XG4gICAgICAgICAgbWF4RGVwdGggPSBkZXB0aDtcbiAgICAgICAgICBtYXhOYW1lID0gbmFtZTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAocmVjdXJDb3VudCA+IDApIHtcbiAgICAgICAgZGVsZXRlIG5vZGUuY2hpbGRyZW5bbm9kZS5uYW1lXTtcbiAgICAgIH1cblxuICAgICAgaWYgKHJlY3VyQ291bnQgPiAxKSB7XG4gICAgICAgIGZvciAobGV0IGkgPSAwLCBsID0gY2hpbGROYW1lcy5sZW5ndGg7IGkgPCBsOyArK2kpIHtcbiAgICAgICAgICBjb25zdCBuYW1lID0gY2hpbGROYW1lc1tpXTtcblxuICAgICAgICAgIGlmIChuYW1lICE9PSBtYXhOYW1lKSB7XG4gICAgICAgICAgICBkZWxldGUgbm9kZS5jaGlsZHJlbltuYW1lXTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcblxuICAgIHJldHVybiBtZXJnZWQ7XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtzdHJpbmd8UmVsYXRpb25FeHByZXNzaW9ufSBleHByXG4gICAqIEByZXR1cm5zIHtib29sZWFufVxuICAgKi9cbiAgaXNTdWJFeHByZXNzaW9uKGV4cHIpIHtcbiAgICBleHByID0gUmVsYXRpb25FeHByZXNzaW9uLnBhcnNlKGV4cHIpO1xuXG4gICAgaWYgKHRoaXMuaXNBbGxSZWN1cnNpdmUoKSkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgaWYgKGV4cHIuaXNBbGxSZWN1cnNpdmUoKSkge1xuICAgICAgcmV0dXJuIHRoaXMuaXNBbGxSZWN1cnNpdmUoKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5uYW1lICE9PSBleHByLm5hbWUpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBjb25zdCBtYXhSZWN1cnNpb25EZXB0aCA9IGV4cHIubWF4UmVjdXJzaW9uRGVwdGgoKTtcblxuICAgIGlmIChtYXhSZWN1cnNpb25EZXB0aCA+IDApIHtcbiAgICAgIHJldHVybiB0aGlzLmlzQWxsUmVjdXJzaXZlKCkgfHwgdGhpcy5tYXhSZWN1cnNpb25EZXB0aCgpID49IG1heFJlY3Vyc2lvbkRlcHRoO1xuICAgIH1cblxuICAgIHJldHVybiBfLmV2ZXJ5KGV4cHIuY2hpbGRyZW4sIChjaGlsZCwgY2hpbGROYW1lKSA9PiB7XG4gICAgICB2YXIgb3duU3ViRXhwcmVzc2lvbiA9IHRoaXMuY2hpbGRFeHByZXNzaW9uKGNoaWxkTmFtZSk7XG4gICAgICB2YXIgc3ViRXhwcmVzc2lvbiA9IGV4cHIuY2hpbGRFeHByZXNzaW9uKGNoaWxkTmFtZSk7XG5cbiAgICAgIHJldHVybiBvd25TdWJFeHByZXNzaW9uICYmIG93blN1YkV4cHJlc3Npb24uaXNTdWJFeHByZXNzaW9uKHN1YkV4cHJlc3Npb24pO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm5zIHtudW1iZXJ9XG4gICAqL1xuICBtYXhSZWN1cnNpb25EZXB0aCgpIHtcbiAgICBpZiAodGhpcy5udW1DaGlsZHJlbiAhPT0gMSkge1xuICAgICAgcmV0dXJuIDA7XG4gICAgfVxuXG4gICAgY29uc3Qga2V5ID0gT2JqZWN0LmtleXModGhpcy5jaGlsZHJlbilbMF07XG4gICAgcmV0dXJuIG1heFJlY3Vyc2lvbkRlcHRoKGtleSk7XG4gIH1cblxuICAvKipcbiAgICogQHJldHVybnMge2Jvb2xlYW59XG4gICAqL1xuICBpc0FsbFJlY3Vyc2l2ZSgpIHtcbiAgICBpZiAodGhpcy5udW1DaGlsZHJlbiAhPT0gMSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIGNvbnN0IGtleSA9IE9iamVjdC5rZXlzKHRoaXMuY2hpbGRyZW4pWzBdO1xuICAgIHJldHVybiBBTExfUkVDVVJTSVZFX1JFR0VYLnRlc3Qoa2V5KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJucyB7UmVsYXRpb25FeHByZXNzaW9ufVxuICAgKi9cbiAgY2hpbGRFeHByZXNzaW9uKGNoaWxkTmFtZSkge1xuICAgIGlmICh0aGlzLmlzQWxsUmVjdXJzaXZlKCkgfHwgKGNoaWxkTmFtZSA9PT0gdGhpcy5uYW1lICYmIHRoaXMuX3JlY3Vyc2lvbkRlcHRoIDwgdGhpcy5tYXhSZWN1cnNpb25EZXB0aCgpIC0gMSkpIHtcbiAgICAgIHJldHVybiBuZXcgUmVsYXRpb25FeHByZXNzaW9uKHRoaXMsIHRoaXMuX3JlY3Vyc2lvbkRlcHRoICsgMSwgdGhpcy5fZmlsdGVycyk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuY2hpbGRyZW5bY2hpbGROYW1lXSkge1xuICAgICAgcmV0dXJuIG5ldyBSZWxhdGlvbkV4cHJlc3Npb24odGhpcy5jaGlsZHJlbltjaGlsZE5hbWVdLCAwLCB0aGlzLl9maWx0ZXJzKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm5zIHtSZWxhdGlvbkV4cHJlc3Npb259XG4gICAqL1xuICBjbG9uZSgpIHtcbiAgICBjb25zdCBub2RlID0ge1xuICAgICAgbmFtZTogdGhpcy5uYW1lLFxuICAgICAgYXJnczogdGhpcy5hcmdzLFxuICAgICAgbnVtQ2hpbGRyZW46IHRoaXMubnVtQ2hpbGRyZW4sXG4gICAgICBjaGlsZHJlbjogXy5jbG9uZURlZXAodGhpcy5jaGlsZHJlbilcbiAgICB9O1xuXG4gICAgY29uc3QgZmlsdGVycyA9IF8uY2xvbmUodGhpcy5fZmlsdGVycyk7XG4gICAgcmV0dXJuIG5ldyBSZWxhdGlvbkV4cHJlc3Npb24obm9kZSwgdGhpcy5fcmVjdXJzaW9uRGVwdGgsIGZpbHRlcnMpO1xuICB9XG5cbiAgZm9yRWFjaENoaWxkKGNiKSB7XG4gICAgXy5mb3JPd24odGhpcy5jaGlsZHJlbiwgKGNoaWxkLCBjaGlsZE5hbWUpID0+IHtcbiAgICAgIGlmICghQUxMX1JFQ1VSU0lWRV9SRUdFWC50ZXN0KGNoaWxkTmFtZSkgJiYgIVJFQ1VSU0lWRV9SRUdFWC50ZXN0KGNoaWxkTmFtZSkpIHtcbiAgICAgICAgY2IoY2hpbGQsIGNoaWxkTmFtZSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtzdHJpbmd8UmVsYXRpb25FeHByZXNzaW9ufSBwYXRoXG4gICAqIEBwYXJhbSB7ZnVuY3Rpb24oUXVlcnlCdWlsZGVyKX0gZmlsdGVyXG4gICAqL1xuICBhZGRBbm9ueW1vdXNGaWx0ZXJBdFBhdGgocGF0aCwgZmlsdGVyKSB7XG4gICAgbGV0IGZpbHRlck5vZGVzID0gdGhpcy5fbm9kZXNBdFBhdGgocGF0aCk7XG4gICAgbGV0IGZpbHRlcnMgPSB0aGlzLmZpbHRlcnM7XG5cbiAgICBsZXQgaWR4ID0gMDtcbiAgICBsZXQgZmlsdGVyTmFtZSA9IGBfZWZlMF9gO1xuXG4gICAgd2hpbGUgKGZpbHRlcnNbZmlsdGVyTmFtZV0pIHtcbiAgICAgIGZpbHRlck5hbWUgPSBgX2VmZSR7KytpZHh9X2A7XG4gICAgfVxuXG4gICAgaWYgKCFfLmlzRW1wdHkoZmlsdGVyTm9kZXMpKSB7XG4gICAgICBmaWx0ZXJzW2ZpbHRlck5hbWVdID0gZmlsdGVyO1xuICAgICAgXy5lYWNoKGZpbHRlck5vZGVzLCBub2RlID0+IG5vZGUuYXJncy5wdXNoKGZpbHRlck5hbWUpKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQHJldHVybnMge3N0cmluZ31cbiAgICovXG4gIHRvU3RyaW5nKCkge1xuICAgIHJldHVybiB0b1N0cmluZyh0aGlzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcmV0dXJuIHtBcnJheS48T2JqZWN0Pn1cbiAgICovXG4gIF9ub2Rlc0F0UGF0aChwYXRoRXhwcmVzc2lvbikge1xuICAgIGxldCBwYXRoID0gUmVsYXRpb25FeHByZXNzaW9uLnBhcnNlKHBhdGhFeHByZXNzaW9uKTtcbiAgICBsZXQgbm9kZXMgPSBbXTtcblxuICAgIFJlbGF0aW9uRXhwcmVzc2lvbi5ub2Rlc0F0UGF0aCh0aGlzLCBwYXRoLCBub2Rlcyk7XG4gICAgcmV0dXJuIG5vZGVzO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBzdGF0aWMgbm9kZXNBdFBhdGgodGFyZ2V0LCBwYXRoLCBleHByZXNzaW9ucykge1xuICAgIGlmIChwYXRoLm51bUNoaWxkcmVuID09IDApIHtcbiAgICAgIGV4cHJlc3Npb25zLnB1c2godGFyZ2V0KTtcbiAgICB9IGVsc2Uge1xuICAgICAgXy5mb3JPd24ocGF0aC5jaGlsZHJlbiwgY2hpbGQgPT4ge1xuICAgICAgICBjb25zdCB0YXJnZXRDaGlsZCA9IHRhcmdldC5jaGlsZHJlbltjaGlsZC5uYW1lXTtcblxuICAgICAgICBpZiAodGFyZ2V0Q2hpbGQpIHtcbiAgICAgICAgICB0aGlzLm5vZGVzQXRQYXRoKHRhcmdldENoaWxkLCBjaGlsZCwgZXhwcmVzc2lvbnMpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gbWF4UmVjdXJzaW9uRGVwdGgoa2V5KSB7XG4gIGNvbnN0IHJlYyA9IFJFQ1VSU0lWRV9SRUdFWC5leGVjKGtleSk7XG5cbiAgaWYgKHJlYykge1xuICAgIGNvbnN0IG1heERlcHRoID0gcmVjWzFdO1xuXG4gICAgaWYgKG1heERlcHRoKSB7XG4gICAgICByZXR1cm4gcGFyc2VJbnQobWF4RGVwdGgsIDEwKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIE51bWJlci5QT1NJVElWRV9JTkZJTklUWTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIDA7XG4gIH1cbn1cblxuZnVuY3Rpb24gdmlzaXQobm9kZSwgdmlzaXRvcikge1xuICBjb25zdCBrZXlzID0gT2JqZWN0LmtleXMobm9kZS5jaGlsZHJlbik7XG5cbiAgdmlzaXRvcihub2RlLCBrZXlzKTtcblxuICBmb3IgKGxldCBpID0gMCwgbCA9IGtleXMubGVuZ3RoOyBpIDwgbDsgKytpKSB7XG4gICAgY29uc3Qga2V5ID0ga2V5c1tpXTtcbiAgICBjb25zdCBjaGlsZE5vZGUgPSBub2RlLmNoaWxkcmVuW2tleV07XG5cbiAgICBpZiAoY2hpbGROb2RlKSB7XG4gICAgICB2aXNpdChjaGlsZE5vZGUsIHZpc2l0b3IpO1xuICAgIH1cbiAgfVxufVxuXG5cbmZ1bmN0aW9uIHRvU3RyaW5nKG5vZGUpIHtcbiAgbGV0IGNoaWxkRXhwciA9IF8udmFsdWVzKG5vZGUuY2hpbGRyZW4pLm1hcCh0b1N0cmluZyk7XG5cbiAgaWYgKGNoaWxkRXhwci5sZW5ndGggPiAxKSB7XG4gICAgY2hpbGRFeHByID0gYFske2NoaWxkRXhwci5qb2luKCcsICcpfV1gO1xuICB9IGVsc2Uge1xuICAgIGNoaWxkRXhwciA9IGNoaWxkRXhwclswXTtcbiAgfVxuXG4gIGxldCBzdHIgPSBub2RlLm5hbWU7XG5cbiAgaWYgKG5vZGUuYXJncy5sZW5ndGgpIHtcbiAgICBzdHIgKz0gYCgke25vZGUuYXJncy5qb2luKCcsICcpfSlgO1xuICB9XG5cbiAgaWYgKGNoaWxkRXhwcikge1xuICAgIGlmIChzdHIpIHtcbiAgICAgIHJldHVybiBgJHtzdHJ9LiR7Y2hpbGRFeHByfWA7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBjaGlsZEV4cHI7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHJldHVybiBzdHI7XG4gIH1cbn1cblxuZnVuY3Rpb24gbW9kZWxHcmFwaFRvTm9kZShtb2RlbHMsIG5vZGUpIHtcbiAgaWYgKCFtb2RlbHMpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICBpZiAoQXJyYXkuaXNBcnJheShtb2RlbHMpKSB7XG4gICAgZm9yIChsZXQgaSA9IDAsIGwgPSBtb2RlbHMubGVuZ3RoOyBpIDwgbDsgKytpKSB7XG4gICAgICBtb2RlbFRvTm9kZShtb2RlbHNbaV0sIG5vZGUpO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBtb2RlbFRvTm9kZShtb2RlbHMsIG5vZGUpO1xuICB9XG5cbiAgcmV0dXJuIG5vZGU7XG59XG5cbmZ1bmN0aW9uIG1vZGVsVG9Ob2RlKG1vZGVsLCBub2RlKSB7XG4gIGNvbnN0IG1vZGVsQ2xhc3MgPSBtb2RlbC5jb25zdHJ1Y3RvcjtcbiAgY29uc3QgcmVsYXRpb25zID0gbW9kZWxDbGFzcy5nZXRSZWxhdGlvbkFycmF5KCk7XG5cbiAgZm9yIChsZXQgciA9IDAsIGxyID0gcmVsYXRpb25zLmxlbmd0aDsgciA8IGxyOyArK3IpIHtcbiAgICBjb25zdCByZWxOYW1lID0gcmVsYXRpb25zW3JdLm5hbWU7XG5cbiAgICBpZiAobW9kZWwuaGFzT3duUHJvcGVydHkocmVsTmFtZSkpIHtcbiAgICAgIGxldCBjaGlsZE5vZGUgPSBub2RlLmNoaWxkcmVuW3JlbE5hbWVdO1xuXG4gICAgICBpZiAoIWNoaWxkTm9kZSkge1xuICAgICAgICBjaGlsZE5vZGUgPSBuZXdOb2RlKHJlbE5hbWUpO1xuXG4gICAgICAgIG5vZGUuY2hpbGRyZW5bcmVsTmFtZV0gPSBjaGlsZE5vZGU7XG4gICAgICAgIG5vZGUubnVtQ2hpbGRyZW4rKztcbiAgICAgIH1cblxuICAgICAgbW9kZWxHcmFwaFRvTm9kZShtb2RlbFtyZWxOYW1lXSwgY2hpbGROb2RlKTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gbmV3Tm9kZShuYW1lKSB7XG4gIHJldHVybiB7XG4gICAgbmFtZTogbmFtZSB8fCAnJyxcbiAgICBhcmdzOiBbXSxcbiAgICBjaGlsZHJlbjogT2JqZWN0LmNyZWF0ZShudWxsKSxcbiAgICBudW1DaGlsZHJlbjogMFxuICB9O1xufSJdfQ==