UNPKG

@genialis/resolwe

Version:
172 lines (170 loc) 26.8 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var _ = require("lodash"); var Rx = require("rx"); var queryobserver_1 = require("./queryobserver"); var error_1 = require("../core/errors/error"); /** * An abstract resource class. */ var Resource = /** @class */ (function () { /** * Constructs a new resource. * * @param connection Connection with the genesis platform server */ function Resource(_connection) { this._connection = _connection; // Cache query observer identifiers. this._queryObserverIdCache = {}; this._pendingQueries = {}; } Object.defineProperty(Resource.prototype, "connection", { /** * Connection to the genesis-platform server. */ get: function () { return this._connection; }, enumerable: true, configurable: true }); /** * Returns base path that resource path is based upon. */ Resource.prototype.getBasePath = function () { return "/api"; }; /** * Performs any query transformations needed for this resource. The * original query object is not modified. * * @param query Query * @return Transformed query */ Resource.prototype.transformQuery = function (query) { this._validateParameters(query); return _.cloneDeep(this._fixQueryForElasticSearch(query)); }; Resource.prototype._fixQueryForElasticSearch = function (query) { // Move `__in` query keys to the end. // TODO: remove this workaround when elastic search is fixed and these both return results // /api/data?entity__in=2726&collection=246&tags=community%3Aexpressions // /api/data?collection=246&tags=community%3Aexpressions&entity__in=2726 return _.zipObject(_.sortBy(_.pairs(query), function (_a) { var key = _a[0]; return _.endsWith(key, '__in') ? Infinity : -1; })); }; /** * Warn about invalid query parameters, like ?id__in=&... */ Resource.prototype._validateParameters = function (query) { var hasEmptyInArray = _.any(query, function (value, key) { return _.endsWith(key, '__in') && !value; }); if (hasEmptyInArray) throw new error_1.GenError('Invalid parameter *__in=empty in query'); }; /** * Performs a query against this resource and subscribes to subsequent updates. */ Resource.prototype.reactiveRequest = function (query, path, options) { var _this = this; // We assume that the same query object on the same resource will always result in the same // underlying queryset (and therefore query observer). var serializedQuery = JSON.stringify([path, query]); options = _.defaults({}, options || {}, { reactive: false, }); query = this.transformQuery(query); return Rx.Observable.create(function (observer) { if (!options.reactive) { // Reactivity is disabled for this query. var subscription_1 = _this.connection.get(path, query).map(function (response) { // Correctly handle paginated results. if (_.has(response, 'results')) return response.results; return response; }).subscribe(observer); return function () { return subscription_1.dispose(); }; } // Reactivity is enabled. var queryObserverId = _this._queryObserverIdCache[serializedQuery]; var pendingQueries = _this._pendingQueries[serializedQuery]; // Perform a REST query to get the observer identifier and to subscribe to new updates. var subscriptions = []; if (queryObserverId) { // This query observer identifier has already been cached. Check if it exists and in this // case just subscribe to all items. var queryObserver = _this.connection.queryObserverManager().get(queryObserverId, false); if (queryObserver) { if (queryObserver.status === queryobserver_1.QueryObserverStatus.INITIALIZED || queryObserver.status === queryobserver_1.QueryObserverStatus.REINITIALIZING) { subscriptions.push(queryObserver.observable().subscribe(observer)); } if (queryObserver.status === queryobserver_1.QueryObserverStatus.INITIALIZED) { observer.onNext(queryObserver.items); } } } if (_.isEmpty(subscriptions)) { if (pendingQueries) { // A request for the same query is already in progress. pendingQueries.push({ observer: observer, subscriptions: subscriptions }); } else { _this._pendingQueries[serializedQuery] = [{ observer: observer, subscriptions: subscriptions }]; query = _.assign(query, { observe: _this.connection.sessionId() }); _this.connection.queryObserverManager().chainAfterUnsubscribe(function () { return _this.connection.get(path, query); }).subscribe(function (response) { // Populate messages from this request. var queryObserver = _this.connection.queryObserverManager().get(response.observer); _this._queryObserverIdCache[serializedQuery] = response.observer; // Setup a reinitialization handler for this observer. It may be used in case the parameters // of a connection change and the observer needs to be re-created on the server without losing // any of the client-side subscriptions. queryObserver.setReinitializeHandler(function () { return _this.connection.get(path, query); }); if (_.isEmpty(_this._pendingQueries[serializedQuery])) { // Send /api/queryobserver/unsubscribe, same as we would if subscribers got disposed after // pendingQueries resolve, instead of before. queryObserver.observable().subscribe().dispose(); } else { for (var _i = 0, _a = _this._pendingQueries[serializedQuery]; _i < _a.length; _i++) { var pending_1 = _a[_i]; pending_1.subscriptions.push(queryObserver.observable().subscribe(pending_1.observer)); if (queryObserver.status === queryobserver_1.QueryObserverStatus.INITIALIZED) { // If the query observer is already initialized, emit the current items immediately. pending_1.observer.onNext(queryObserver.items); } } } delete _this._pendingQueries[serializedQuery]; if (queryObserver.status !== queryobserver_1.QueryObserverStatus.INITIALIZED) { queryObserver.initialize(response.items); } }, function (error) { observer.onError(error); }); } } return function () { // Dispose of the query observer subscription when all subscriptions to this query are stopped. for (var _i = 0, subscriptions_1 = subscriptions; _i < subscriptions_1.length; _i++) { var subscription = subscriptions_1[_i]; subscription.dispose(); } // If query is still just pending, remove observer before it even becomes disposable. if (_this._pendingQueries[serializedQuery]) { _this._pendingQueries[serializedQuery] = _.reject(_this._pendingQueries[serializedQuery], function (pending) { // Check for same reference, not content! return pending.subscriptions === subscriptions; }); } }; }).publish().refCount(); }; return Resource; }()); exports.Resource = Resource; //# sourceMappingURL=data:application/json;charset=utf8;base64,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QUFDLEtBQUksQ0FBQyxlQUFlLENBQUMsZUFBZSxDQUFDLEVBQUUsVUFBQyxPQUFPO3dCQUM1Rix5Q0FBeUM7d0JBQ3pDLE9BQU8sT0FBTyxDQUFDLGFBQWEsS0FBSyxhQUFhLENBQUM7b0JBQ25ELENBQUMsQ0FBQyxDQUFDO2lCQUNOO1lBQ0wsQ0FBQyxDQUFDO1FBQ04sQ0FBQyxDQUFDLENBQUMsT0FBTyxFQUFFLENBQUMsUUFBUSxFQUFFLENBQUM7SUFDNUIsQ0FBQztJQUNMLGVBQUM7QUFBRCxDQXpLQSxBQXlLQyxJQUFBO0FBektxQiw0QkFBUSIsImZpbGUiOiJhcGkvcmVzb3VyY2UuanMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBfIGZyb20gJ2xvZGFzaCc7XG5pbXBvcnQgKiBhcyBSeCBmcm9tICdyeCc7XG5cbmltcG9ydCB7Q29ubmVjdGlvbiwgUXVlcnlPYnNlcnZlclJlc3BvbnNlfSBmcm9tICcuL2Nvbm5lY3Rpb24nO1xuaW1wb3J0IHtRdWVyeU9ic2VydmVyU3RhdHVzfSBmcm9tICcuL3F1ZXJ5b2JzZXJ2ZXInO1xuaW1wb3J0IHtHZW5FcnJvcn0gZnJvbSAnLi4vY29yZS9lcnJvcnMvZXJyb3InO1xuaW1wb3J0ICogYXMgdHlwZXMgZnJvbSAnLi90eXBlcy9yZXN0JztcblxuLyoqXG4gKiBBIG1hcHBpbmcgb2YgcXVlcmllcyB0byB0aGVpciBxdWVyeSBvYnNlcnZlciBpZGVudGlmaWVycywgc28gdGhhdCB3ZSBkb24ndFxuICogbmVlZCB0byBoaXQgdGhlIHNlcnZlciBpbiBjYXNlIHRoZSBpZGVudGlmaWVyIGlzIGFscmVhZHkga25vd24uXG4gKi9cbmludGVyZmFjZSBRdWVyeU9ic2VydmVySWRDYWNoZSB7XG4gICAgW2luZGV4OiBzdHJpbmddOiBzdHJpbmc7XG59XG5cbmludGVyZmFjZSBQZW5kaW5nUXVlcmllcyB7XG4gICAgW2luZGV4OiBzdHJpbmddOiB7XG4gICAgICAgIHN1YnNjcmlwdGlvbnM6IFJ4LkRpc3Bvc2FibGVbXTtcbiAgICAgICAgb2JzZXJ2ZXI6IFJ4Lk9ic2VydmVyPGFueT47XG4gICAgfVtdO1xufVxuXG4vKipcbiAqIFBlci1xdWVyeSBjb25maWd1cmF0aW9uIG9wdGlvbnMuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUXVlcnlPcHRpb25zIHtcbiAgICByZWFjdGl2ZT86IGJvb2xlYW47XG59XG5cbi8qKlxuICogQW4gYWJzdHJhY3QgcmVzb3VyY2UgY2xhc3MuXG4gKi9cbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBSZXNvdXJjZSB7XG4gICAgLy8gQ2FjaGUgcXVlcnkgb2JzZXJ2ZXIgaWRlbnRpZmllcnMuXG4gICAgcHJpdmF0ZSBfcXVlcnlPYnNlcnZlcklkQ2FjaGU6IFF1ZXJ5T2JzZXJ2ZXJJZENhY2hlID0ge307XG4gICAgcHJpdmF0ZSBfcGVuZGluZ1F1ZXJpZXM6IFBlbmRpbmdRdWVyaWVzID0ge307XG5cbiAgICAvKipcbiAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHJlc291cmNlLlxuICAgICAqXG4gICAgICogQHBhcmFtIGNvbm5lY3Rpb24gQ29ubmVjdGlvbiB3aXRoIHRoZSBnZW5lc2lzIHBsYXRmb3JtIHNlcnZlclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHByaXZhdGUgX2Nvbm5lY3Rpb246IENvbm5lY3Rpb24pIHtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDb25uZWN0aW9uIHRvIHRoZSBnZW5lc2lzLXBsYXRmb3JtIHNlcnZlci5cbiAgICAgKi9cbiAgICBwdWJsaWMgZ2V0IGNvbm5lY3Rpb24oKTogQ29ubmVjdGlvbiB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jb25uZWN0aW9uO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgYmFzZSBwYXRoIHRoYXQgcmVzb3VyY2UgcGF0aCBpcyBiYXNlZCB1cG9uLlxuICAgICAqL1xuICAgIHByb3RlY3RlZCBnZXRCYXNlUGF0aCgpOiBzdHJpbmcge1xuICAgICAgICByZXR1cm4gYC9hcGlgO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFBlcmZvcm1zIGFueSBxdWVyeSB0cmFuc2Zvcm1hdGlvbnMgbmVlZGVkIGZvciB0aGlzIHJlc291cmNlLiBUaGVcbiAgICAgKiBvcmlnaW5hbCBxdWVyeSBvYmplY3QgaXMgbm90IG1vZGlmaWVkLlxuICAgICAqXG4gICAgICogQHBhcmFtIHF1ZXJ5IFF1ZXJ5XG4gICAgICogQHJldHVybiBUcmFuc2Zvcm1lZCBxdWVyeVxuICAgICAqL1xuICAgIHByb3RlY3RlZCB0cmFuc2Zvcm1RdWVyeShxdWVyeTogdHlwZXMuUXVlcnkpOiB0eXBlcy5RdWVyeSB7XG4gICAgICAgIHRoaXMuX3ZhbGlkYXRlUGFyYW1ldGVycyhxdWVyeSk7XG4gICAgICAgIHJldHVybiBfLmNsb25lRGVlcCh0aGlzLl9maXhRdWVyeUZvckVsYXN0aWNTZWFyY2gocXVlcnkpKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIF9maXhRdWVyeUZvckVsYXN0aWNTZWFyY2gocXVlcnk6IHR5cGVzLlF1ZXJ5KTogdHlwZXMuUXVlcnkge1xuICAgICAgICAvLyBNb3ZlIGBfX2luYCBxdWVyeSBrZXlzIHRvIHRoZSBlbmQuXG4gICAgICAgIC8vIFRPRE86IHJlbW92ZSB0aGlzIHdvcmthcm91bmQgd2hlbiBlbGFzdGljIHNlYXJjaCBpcyBmaXhlZCBhbmQgdGhlc2UgYm90aCByZXR1cm4gcmVzdWx0c1xuICAgICAgICAvLyAvYXBpL2RhdGE/ZW50aXR5X19pbj0yNzI2JmNvbGxlY3Rpb249MjQ2JnRhZ3M9Y29tbXVuaXR5JTNBZXhwcmVzc2lvbnNcbiAgICAgICAgLy8gL2FwaS9kYXRhP2NvbGxlY3Rpb249MjQ2JnRhZ3M9Y29tbXVuaXR5JTNBZXhwcmVzc2lvbnMmZW50aXR5X19pbj0yNzI2XG4gICAgICAgIHJldHVybiBfLnppcE9iamVjdChfLnNvcnRCeShfLnBhaXJzKHF1ZXJ5KSwgKFtrZXldKSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gXy5lbmRzV2l0aChrZXksICdfX2luJykgPyBJbmZpbml0eSA6IC0xO1xuICAgICAgICB9KSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogV2FybiBhYm91dCBpbnZhbGlkIHF1ZXJ5IHBhcmFtZXRlcnMsIGxpa2UgP2lkX19pbj0mLi4uXG4gICAgICovXG4gICAgcHJpdmF0ZSBfdmFsaWRhdGVQYXJhbWV0ZXJzKHF1ZXJ5OiB0eXBlcy5RdWVyeSk6IHZvaWQge1xuICAgICAgICBjb25zdCBoYXNFbXB0eUluQXJyYXkgPSBfLmFueShxdWVyeSwgKHZhbHVlLCBrZXkpID0+IF8uZW5kc1dpdGgoa2V5LCAnX19pbicpICYmICF2YWx1ZSk7XG4gICAgICAgIGlmIChoYXNFbXB0eUluQXJyYXkpIHRocm93IG5ldyBHZW5FcnJvcignSW52YWxpZCBwYXJhbWV0ZXIgKl9faW49ZW1wdHkgaW4gcXVlcnknKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBQZXJmb3JtcyBhIHF1ZXJ5IGFnYWluc3QgdGhpcyByZXNvdXJjZSBhbmQgc3Vic2NyaWJlcyB0byBzdWJzZXF1ZW50IHVwZGF0ZXMuXG4gICAgICovXG4gICAgcHJvdGVjdGVkIHJlYWN0aXZlUmVxdWVzdDxUPihxdWVyeTogdHlwZXMuUXVlcnksIHBhdGg6IHN0cmluZywgb3B0aW9ucz86IFF1ZXJ5T3B0aW9ucyk6IFJ4Lk9ic2VydmFibGU8VFtdPiB7XG4gICAgICAgIC8vIFdlIGFzc3VtZSB0aGF0IHRoZSBzYW1lIHF1ZXJ5IG9iamVjdCBvbiB0aGUgc2FtZSByZXNvdXJjZSB3aWxsIGFsd2F5cyByZXN1bHQgaW4gdGhlIHNhbWVcbiAgICAgICAgLy8gdW5kZXJseWluZyBxdWVyeXNldCAoYW5kIHRoZXJlZm9yZSBxdWVyeSBvYnNlcnZlcikuXG4gICAgICAgIGxldCBzZXJpYWxpemVkUXVlcnkgPSBKU09OLnN0cmluZ2lmeShbcGF0aCwgcXVlcnldKTtcbiAgICAgICAgb3B0aW9ucyA9IF8uZGVmYXVsdHMoe30sIG9wdGlvbnMgfHwge30sIHtcbiAgICAgICAgICAgIHJlYWN0aXZlOiBmYWxzZSxcbiAgICAgICAgfSk7XG4gICAgICAgIHF1ZXJ5ID0gdGhpcy50cmFuc2Zvcm1RdWVyeShxdWVyeSk7XG5cbiAgICAgICAgcmV0dXJuIFJ4Lk9ic2VydmFibGUuY3JlYXRlPFRbXT4oKG9ic2VydmVyKSA9PiB7XG4gICAgICAgICAgICBpZiAoIW9wdGlvbnMucmVhY3RpdmUpIHtcbiAgICAgICAgICAgICAgICAvLyBSZWFjdGl2aXR5IGlzIGRpc2FibGVkIGZvciB0aGlzIHF1ZXJ5LlxuICAgICAgICAgICAgICAgIGNvbnN0IHN1YnNjcmlwdGlvbiA9IHRoaXMuY29ubmVjdGlvbi5nZXQocGF0aCwgcXVlcnkpLm1hcCgocmVzcG9uc2U6IGFueSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAvLyBDb3JyZWN0bHkgaGFuZGxlIHBhZ2luYXRlZCByZXN1bHRzLlxuICAgICAgICAgICAgICAgICAgICBpZiAoXy5oYXMocmVzcG9uc2UsICdyZXN1bHRzJykpIHJldHVybiByZXNwb25zZS5yZXN1bHRzO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzcG9uc2U7XG4gICAgICAgICAgICAgICAgfSkuc3Vic2NyaWJlKG9ic2VydmVyKTtcblxuICAgICAgICAgICAgICAgIHJldHVybiAoKSA9PiBzdWJzY3JpcHRpb24uZGlzcG9zZSgpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBSZWFjdGl2aXR5IGlzIGVuYWJsZWQuXG4gICAgICAgICAgICBsZXQgcXVlcnlPYnNlcnZlcklkID0gdGhpcy5fcXVlcnlPYnNlcnZlcklkQ2FjaGVbc2VyaWFsaXplZFF1ZXJ5XTtcbiAgICAgICAgICAgIGxldCBwZW5kaW5nUXVlcmllcyA9IHRoaXMuX3BlbmRpbmdRdWVyaWVzW3NlcmlhbGl6ZWRRdWVyeV07XG5cbiAgICAgICAgICAgIC8vIFBlcmZvcm0gYSBSRVNUIHF1ZXJ5IHRvIGdldCB0aGUgb2JzZXJ2ZXIgaWRlbnRpZmllciBhbmQgdG8gc3Vic2NyaWJlIHRvIG5ldyB1cGRhdGVzLlxuICAgICAgICAgICAgbGV0IHN1YnNjcmlwdGlvbnM6IFJ4LkRpc3Bvc2FibGVbXSA9IFtdO1xuXG4gICAgICAgICAgICBpZiAocXVlcnlPYnNlcnZlcklkKSB7XG4gICAgICAgICAgICAgICAgLy8gVGhpcyBxdWVyeSBvYnNlcnZlciBpZGVudGlmaWVyIGhhcyBhbHJlYWR5IGJlZW4gY2FjaGVkLiBDaGVjayBpZiBpdCBleGlzdHMgYW5kIGluIHRoaXNcbiAgICAgICAgICAgICAgICAvLyBjYXNlIGp1c3Qgc3Vic2NyaWJlIHRvIGFsbCBpdGVtcy5cbiAgICAgICAgICAgICAgICBsZXQgcXVlcnlPYnNlcnZlciA9IHRoaXMuY29ubmVjdGlvbi5xdWVyeU9ic2VydmVyTWFuYWdlcigpLmdldChxdWVyeU9ic2VydmVySWQsIGZhbHNlKTtcbiAgICAgICAgICAgICAgICBpZiAocXVlcnlPYnNlcnZlcikge1xuICAgICAgICAgICAgICAgICAgICBpZiAocXVlcnlPYnNlcnZlci5zdGF0dXMgPT09IFF1ZXJ5T2JzZXJ2ZXJTdGF0dXMuSU5JVElBTElaRUQgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgIHF1ZXJ5T2JzZXJ2ZXIuc3RhdHVzID09PSBRdWVyeU9ic2VydmVyU3RhdHVzLlJFSU5JVElBTElaSU5HKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdWJzY3JpcHRpb25zLnB1c2gocXVlcnlPYnNlcnZlci5vYnNlcnZhYmxlKCkuc3Vic2NyaWJlKG9ic2VydmVyKSk7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICBpZiAocXVlcnlPYnNlcnZlci5zdGF0dXMgPT09IFF1ZXJ5T2JzZXJ2ZXJTdGF0dXMuSU5JVElBTElaRUQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG9ic2VydmVyLm9uTmV4dChxdWVyeU9ic2VydmVyLml0ZW1zKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKF8uaXNFbXB0eShzdWJzY3JpcHRpb25zKSkge1xuICAgICAgICAgICAgICAgIGlmIChwZW5kaW5nUXVlcmllcykge1xuICAgICAgICAgICAgICAgICAgICAvLyBBIHJlcXVlc3QgZm9yIHRoZSBzYW1lIHF1ZXJ5IGlzIGFscmVhZHkgaW4gcHJvZ3Jlc3MuXG4gICAgICAgICAgICAgICAgICAgIHBlbmRpbmdRdWVyaWVzLnB1c2goe29ic2VydmVyLCBzdWJzY3JpcHRpb25zfSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fcGVuZGluZ1F1ZXJpZXNbc2VyaWFsaXplZFF1ZXJ5XSA9IFt7b2JzZXJ2ZXIsIHN1YnNjcmlwdGlvbnN9XTtcblxuICAgICAgICAgICAgICAgICAgICBxdWVyeSA9IF8uYXNzaWduKHF1ZXJ5LCB7b2JzZXJ2ZTogdGhpcy5jb25uZWN0aW9uLnNlc3Npb25JZCgpfSk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY29ubmVjdGlvbi5xdWVyeU9ic2VydmVyTWFuYWdlcigpLmNoYWluQWZ0ZXJVbnN1YnNjcmliZSgoKSA9PiB0aGlzLmNvbm5lY3Rpb24uZ2V0KHBhdGgsIHF1ZXJ5KSkuc3Vic2NyaWJlKFxuICAgICAgICAgICAgICAgICAgICAgICAgKHJlc3BvbnNlOiBRdWVyeU9ic2VydmVyUmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBQb3B1bGF0ZSBtZXNzYWdlcyBmcm9tIHRoaXMgcmVxdWVzdC5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgcXVlcnlPYnNlcnZlciA9IHRoaXMuY29ubmVjdGlvbi5xdWVyeU9ic2VydmVyTWFuYWdlcigpLmdldChyZXNwb25zZS5vYnNlcnZlcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fcXVlcnlPYnNlcnZlcklkQ2FjaGVbc2VyaWFsaXplZFF1ZXJ5XSA9IHJlc3BvbnNlLm9ic2VydmVyO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gU2V0dXAgYSByZWluaXRpYWxpemF0aW9uIGhhbmRsZXIgZm9yIHRoaXMgb2JzZXJ2ZXIuIEl0IG1heSBiZSB1c2VkIGluIGNhc2UgdGhlIHBhcmFtZXRlcnNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBvZiBhIGNvbm5lY3Rpb24gY2hhbmdlIGFuZCB0aGUgb2JzZXJ2ZXIgbmVlZHMgdG8gYmUgcmUtY3JlYXRlZCBvbiB0aGUgc2VydmVyIHdpdGhvdXQgbG9zaW5nXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gYW55IG9mIHRoZSBjbGllbnQtc2lkZSBzdWJzY3JpcHRpb25zLlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHF1ZXJ5T2JzZXJ2ZXIuc2V0UmVpbml0aWFsaXplSGFuZGxlcigoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmNvbm5lY3Rpb24uZ2V0KHBhdGgsIHF1ZXJ5KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfLmlzRW1wdHkodGhpcy5fcGVuZGluZ1F1ZXJpZXNbc2VyaWFsaXplZFF1ZXJ5XSkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gU2VuZCAvYXBpL3F1ZXJ5b2JzZXJ2ZXIvdW5zdWJzY3JpYmUsIHNhbWUgYXMgd2Ugd291bGQgaWYgc3Vic2NyaWJlcnMgZ290IGRpc3Bvc2VkIGFmdGVyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHBlbmRpbmdRdWVyaWVzIHJlc29sdmUsIGluc3RlYWQgb2YgYmVmb3JlLlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBxdWVyeU9ic2VydmVyLm9ic2VydmFibGUoKS5zdWJzY3JpYmUoKS5kaXNwb3NlKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChjb25zdCBwZW5kaW5nIG9mIHRoaXMuX3BlbmRpbmdRdWVyaWVzW3NlcmlhbGl6ZWRRdWVyeV0pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBlbmRpbmcuc3Vic2NyaXB0aW9ucy5wdXNoKHF1ZXJ5T2JzZXJ2ZXIub2JzZXJ2YWJsZSgpLnN1YnNjcmliZShwZW5kaW5nLm9ic2VydmVyKSk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChxdWVyeU9ic2VydmVyLnN0YXR1cyA9PT0gUXVlcnlPYnNlcnZlclN0YXR1cy5JTklUSUFMSVpFRCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIElmIHRoZSBxdWVyeSBvYnNlcnZlciBpcyBhbHJlYWR5IGluaXRpYWxpemVkLCBlbWl0IHRoZSBjdXJyZW50IGl0ZW1zIGltbWVkaWF0ZWx5LlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBlbmRpbmcub2JzZXJ2ZXIub25OZXh0KHF1ZXJ5T2JzZXJ2ZXIuaXRlbXMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMuX3BlbmRpbmdRdWVyaWVzW3NlcmlhbGl6ZWRRdWVyeV07XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocXVlcnlPYnNlcnZlci5zdGF0dXMgIT09IFF1ZXJ5T2JzZXJ2ZXJTdGF0dXMuSU5JVElBTElaRUQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcXVlcnlPYnNlcnZlci5pbml0aWFsaXplKHJlc3BvbnNlLml0ZW1zKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgKGVycm9yKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgb2JzZXJ2ZXIub25FcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgICAgICAgICAgIC8vIERpc3Bvc2Ugb2YgdGhlIHF1ZXJ5IG9ic2VydmVyIHN1YnNjcmlwdGlvbiB3aGVuIGFsbCBzdWJzY3JpcHRpb25zIHRvIHRoaXMgcXVlcnkgYXJlIHN0b3BwZWQuXG4gICAgICAgICAgICAgICAgZm9yIChjb25zdCBzdWJzY3JpcHRpb24gb2Ygc3Vic2NyaXB0aW9ucykge1xuICAgICAgICAgICAgICAgICAgICBzdWJzY3JpcHRpb24uZGlzcG9zZSgpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIC8vIElmIHF1ZXJ5IGlzIHN0aWxsIGp1c3QgcGVuZGluZywgcmVtb3ZlIG9ic2VydmVyIGJlZm9yZSBpdCBldmVuIGJlY29tZXMgZGlzcG9zYWJsZS5cbiAgICAgICAgICAgICAgICBpZiAodGhpcy5fcGVuZGluZ1F1ZXJpZXNbc2VyaWFsaXplZFF1ZXJ5XSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9wZW5kaW5nUXVlcmllc1tzZXJpYWxpemVkUXVlcnldID0gXy5yZWplY3QodGhpcy5fcGVuZGluZ1F1ZXJpZXNbc2VyaWFsaXplZFF1ZXJ5XSwgKHBlbmRpbmcpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIENoZWNrIGZvciBzYW1lIHJlZmVyZW5jZSwgbm90IGNvbnRlbnQhXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcGVuZGluZy5zdWJzY3JpcHRpb25zID09PSBzdWJzY3JpcHRpb25zO1xuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9O1xuICAgICAgICB9KS5wdWJsaXNoKCkucmVmQ291bnQoKTtcbiAgICB9XG59XG4iXX0=