UNPKG

@testim/testim-cli

Version:

Command line interface for running Testing on you CI

262 lines (215 loc) 22.4 kB
'use strict'; var _createClass = require('babel-runtime/helpers/create-class')['default']; var _classCallCheck = require('babel-runtime/helpers/class-call-check')['default']; var _Object$keys = require('babel-runtime/core-js/object/keys')['default']; var _Promise = require('babel-runtime/core-js/promise')['default']; var _interopRequireDefault = require('babel-runtime/helpers/interop-require-default')['default']; Object.defineProperty(exports, '__esModule', { value: true }); var _q = require('q'); var _q2 = _interopRequireDefault(_q); /** * Multibrowser */ var Multibrowser = (function () { function Multibrowser() { _classCallCheck(this, Multibrowser); this.instances = {}; this.promiseBucket = []; var defer = _q2['default'].defer(); this.qResolve = defer.resolve.toString(); } /** * add instance to multibrowser instance */ _createClass(Multibrowser, [{ key: 'addInstance', value: function addInstance(browserName, client) { if (this.instances[browserName]) { throw new Error('webdriver instance "' + browserName + '" is already defined'); } this.instances[browserName] = client; } /** * modifier for multibrowser instance */ }, { key: 'getModifier', value: function getModifier() { return multiremoteModifier.bind(this); } /** * flush bucket and return current pending promises */ }, { key: 'flushPromiseBucket', value: function flushPromiseBucket() { var bucket = this.promiseBucket.filter(function (promise) { return promise.inspect().state === 'pending'; }); this.promiseBucket = []; return bucket; } /** * modifier for single webdriverio instances */ }, { key: 'getInstanceModifier', value: function getInstanceModifier() { return instanceModifier.bind(this); } }]); return Multibrowser; })(); function instanceModifier(client) { var _next = client.next; var multibrowser = this; /** * Overwrite next (bind) method to put each command into a bucket. * This provides us useful information about all current running * commands. */ client.next = function () { multibrowser.promiseBucket.push(this.promise); return _next.apply(this, arguments); }; return client; } function multiremoteModifier(client) { var multibrowser = this; var browserNames = _Object$keys(multibrowser.instances); client.next = function () { var _this = this; var promises = []; for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } var fnName = args.pop(); /** * no need for actual function here */ args.shift(); /** * flush promise bucket */ multibrowser.promiseBucket = []; var commandArgs = args.pop(); return this.lastPromise.done(function () { browserNames.forEach(function (browserName) { var instance = multibrowser.instances[browserName]; promises.push(instance[fnName].apply(instance, commandArgs).promise); }); return _Promise.all(promises).then(function (result) { /** * custom event handling since multibrowser instance * actually never executes any command */ var payload = { fnName: fnName }; for (var i = 0; i < browserNames.length; ++i) { payload[browserNames[i]] = result[i]; } if (fnName.match(/(init|end)/)) { _this.emit(fnName, payload); } _this.emit('result', payload); _this.defer.resolve(result); }, function (err) { _this.emit('error', err); _this.defer.reject(err); }); }); }; var _then = client.then; client.then = function (onFulfilled, onRejected) { /** * curry arguments * as multibrowser commands return with an array of results for each instance * respectively (see q.all) we need to curry them (expand arguments) to help * users to better work with the results * * uncurried original version: * ```js * matrix.getTitle().then(function (result) { * expect(result[0]).to.be.equal('title of browser A') * expect(result[1]).to.be.equal('title of browser B') * }) * ``` * * curried version: * ```js * matrix.getTitle().then(function (titleBrowserA, titleBrowserB) { * expect(titleBrowserA).to.be.equal('title of browser A') * expect(titleBrowserB).to.be.equal('title of browser B') * }) * ``` */ var curryArguments = function curryArguments(args) { /** * when returning with a promise within a multibrowser promise like * * ```js * matrix.url(...).getTitle().then(function () { * return matrix.getSource() * }) * ``` * * we will have problems as we are running through curryArguments twice. * Therefor check if the onFulFilled handler is from the Q library and * handle that promise as usual here. * It's an ugly hack but the only way to get around with this and having * nice curried arguments. * */ if (onFulfilled.toString() === multibrowser.qResolve) { return onFulfilled.apply(this, arguments); } if (arguments.length === 1 && !Array.isArray(args)) { return onFulfilled.call(this, args); } if (arguments.length > 1) { args = Array.prototype.slice.call(arguments); } return onFulfilled.apply(this, args); }; if (!onFulfilled && !onRejected) { return this; } if (onFulfilled && !onRejected) { return _then.call(this, curryArguments); } if (onFulfilled && onRejected) { return _then.call(this, curryArguments, onRejected); } return _then.call(this, undefined, onRejected); }; client.select = function (browserName) { var instance = multibrowser.instances[browserName]; if (!instance) { throw new Error('browser name "' + browserName + '" was not defined'); } instance.isMultibrowser = false; return instance; }; client.sync = function () { var bucket = multibrowser.flushPromiseBucket(); return this.call(function () { return _Promise.all(bucket); }); }; var _addCommand = client.addCommand; client.addCommand = function (fnName, fn, forceOverwrite) { _addCommand.call(this, fnName, fn, forceOverwrite); _Object$keys(multibrowser.instances).forEach(function (browserName) { var instance = multibrowser.instances[browserName]; instance.addCommand(fnName, fn, forceOverwrite); }); return this; }; return client; } exports['default'] = Multibrowser; module.exports = exports['default']; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL2xpYi9tdWx0aWJyb3dzZXIuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7OztpQkFBYyxHQUFHOzs7Ozs7OztJQUtYLFlBQVk7QUFDRixhQURWLFlBQVksR0FDQzs4QkFEYixZQUFZOztBQUVWLFlBQUksQ0FBQyxTQUFTLEdBQUcsRUFBRSxDQUFBO0FBQ25CLFlBQUksQ0FBQyxhQUFhLEdBQUcsRUFBRSxDQUFBOztBQUV2QixZQUFJLEtBQUssR0FBRyxlQUFFLEtBQUssRUFBRSxDQUFBO0FBQ3JCLFlBQUksQ0FBQyxRQUFRLEdBQUcsS0FBSyxDQUFDLE9BQU8sQ0FBQyxRQUFRLEVBQUUsQ0FBQTtLQUMzQzs7Ozs7O2lCQVBDLFlBQVk7O2VBWUYscUJBQUMsV0FBVyxFQUFFLE1BQU0sRUFBRTtBQUM5QixnQkFBSSxJQUFJLENBQUMsU0FBUyxDQUFDLFdBQVcsQ0FBQyxFQUFFO0FBQzdCLHNCQUFNLElBQUksS0FBSywwQkFBd0IsV0FBVywwQkFBdUIsQ0FBQTthQUM1RTtBQUNELGdCQUFJLENBQUMsU0FBUyxDQUFDLFdBQVcsQ0FBQyxHQUFHLE1BQU0sQ0FBQTtTQUN2Qzs7Ozs7OztlQUtXLHVCQUFHO0FBQ1gsbUJBQU8sbUJBQW1CLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFBO1NBQ3hDOzs7Ozs7O2VBS2tCLDhCQUFHO0FBQ2xCLGdCQUFJLE1BQU0sR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLE1BQU0sQ0FBQyxVQUFBLE9BQU87dUJBQUksT0FBTyxDQUFDLE9BQU8sRUFBRSxDQUFDLEtBQUssS0FBSyxTQUFTO2FBQUEsQ0FBQyxDQUFBO0FBQ3hGLGdCQUFJLENBQUMsYUFBYSxHQUFHLEVBQUUsQ0FBQTtBQUN2QixtQkFBTyxNQUFNLENBQUE7U0FDaEI7Ozs7Ozs7ZUFLbUIsK0JBQUc7QUFDbkIsbUJBQU8sZ0JBQWdCLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFBO1NBQ3JDOzs7V0F4Q0MsWUFBWTs7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SyxvQkFBa0IsV0FBVyx1QkFBb0IsQ0FBQTtTQUNuRTs7QUFFRCxnQkFBUSxDQUFDLGNBQWMsR0FBRyxLQUFLLENBQUE7QUFDL0IsZUFBTyxRQUFRLENBQUE7S0FDbEIsQ0FBQTs7QUFFRCxVQUFNLENBQUMsSUFBSSxHQUFHLFlBQVk7QUFDdEIsWUFBSSxNQUFNLEdBQUcsWUFBWSxDQUFDLGtCQUFrQixFQUFFLENBQUE7QUFDOUMsZUFBTyxJQUFJLENBQUMsSUFBSSxDQUFDO21CQUFNLFNBQVEsR0FBRyxDQUFDLE1BQU0sQ0FBQztTQUFBLENBQUMsQ0FBQTtLQUM5QyxDQUFBOztBQUVELFFBQUksV0FBVyxHQUFHLE1BQU0sQ0FBQyxVQUFVLENBQUE7QUFDbkMsVUFBTSxDQUFDLFVBQVUsR0FBRyxVQUFVLE1BQU0sRUFBRSxFQUFFLEVBQUUsY0FBYyxFQUFFO0FBQ3RELG1CQUFXLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxNQUFNLEVBQUUsRUFBRSxFQUFFLGNBQWMsQ0FBQyxDQUFBO0FBQ2xELHFCQUFZLFlBQVksQ0FBQyxTQUFTLENBQUMsQ0FBQyxPQUFPLENBQUMsVUFBQyxXQUFXLEVBQUs7QUFDekQsZ0JBQUksUUFBUSxHQUFHLFlBQVksQ0FBQyxTQUFTLENBQUMsV0FBVyxDQUFDLENBQUE7QUFDbEQsb0JBQVEsQ0FBQyxVQUFVLENBQUMsTUFBTSxFQUFFLEVBQUUsRUFBRSxjQUFjLENBQUMsQ0FBQTtTQUNsRCxDQUFDLENBQUE7QUFDRixlQUFPLElBQUksQ0FBQTtLQUNkLENBQUE7O0FBRUQsV0FBTyxNQUFNLENBQUE7Q0FDaEI7O3FCQUVjLFlBQVkiLCJmaWxlIjoibXVsdGlicm93c2VyLmpzIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHEgZnJvbSAncSdcblxuLyoqXG4gKiBNdWx0aWJyb3dzZXJcbiAqL1xuY2xhc3MgTXVsdGlicm93c2VyIHtcbiAgICBjb25zdHJ1Y3RvciAoKSB7XG4gICAgICAgIHRoaXMuaW5zdGFuY2VzID0ge31cbiAgICAgICAgdGhpcy5wcm9taXNlQnVja2V0ID0gW11cblxuICAgICAgICB2YXIgZGVmZXIgPSBxLmRlZmVyKClcbiAgICAgICAgdGhpcy5xUmVzb2x2ZSA9IGRlZmVyLnJlc29sdmUudG9TdHJpbmcoKVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIGFkZCBpbnN0YW5jZSB0byBtdWx0aWJyb3dzZXIgaW5zdGFuY2VcbiAgICAgKi9cbiAgICBhZGRJbnN0YW5jZSAoYnJvd3Nlck5hbWUsIGNsaWVudCkge1xuICAgICAgICBpZiAodGhpcy5pbnN0YW5jZXNbYnJvd3Nlck5hbWVdKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYHdlYmRyaXZlciBpbnN0YW5jZSBcIiR7YnJvd3Nlck5hbWV9XCIgaXMgYWxyZWFkeSBkZWZpbmVkYClcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmluc3RhbmNlc1ticm93c2VyTmFtZV0gPSBjbGllbnRcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBtb2RpZmllciBmb3IgbXVsdGlicm93c2VyIGluc3RhbmNlXG4gICAgICovXG4gICAgZ2V0TW9kaWZpZXIgKCkge1xuICAgICAgICByZXR1cm4gbXVsdGlyZW1vdGVNb2RpZmllci5iaW5kKHRoaXMpXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogZmx1c2ggYnVja2V0IGFuZCByZXR1cm4gY3VycmVudCBwZW5kaW5nIHByb21pc2VzXG4gICAgICovXG4gICAgZmx1c2hQcm9taXNlQnVja2V0ICgpIHtcbiAgICAgICAgdmFyIGJ1Y2tldCA9IHRoaXMucHJvbWlzZUJ1Y2tldC5maWx0ZXIocHJvbWlzZSA9PiBwcm9taXNlLmluc3BlY3QoKS5zdGF0ZSA9PT0gJ3BlbmRpbmcnKVxuICAgICAgICB0aGlzLnByb21pc2VCdWNrZXQgPSBbXVxuICAgICAgICByZXR1cm4gYnVja2V0XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogbW9kaWZpZXIgZm9yIHNpbmdsZSB3ZWJkcml2ZXJpbyBpbnN0YW5jZXNcbiAgICAgKi9cbiAgICBnZXRJbnN0YW5jZU1vZGlmaWVyICgpIHtcbiAgICAgICAgcmV0dXJuIGluc3RhbmNlTW9kaWZpZXIuYmluZCh0aGlzKVxuICAgIH1cbn1cblxuZnVuY3Rpb24gaW5zdGFuY2VNb2RpZmllciAoY2xpZW50KSB7XG4gICAgbGV0IF9uZXh0ID0gY2xpZW50Lm5leHRcbiAgICBsZXQgbXVsdGlicm93c2VyID0gdGhpc1xuXG4gICAgLyoqXG4gICAgICogT3ZlcndyaXRlIG5leHQgKGJpbmQpIG1ldGhvZCB0byBwdXQgZWFjaCBjb21tYW5kIGludG8gYSBidWNrZXQuXG4gICAgICogVGhpcyBwcm92aWRlcyB1cyB1c2VmdWwgaW5mb3JtYXRpb24gYWJvdXQgYWxsIGN1cnJlbnQgcnVubmluZ1xuICAgICAqIGNvbW1hbmRzLlxuICAgICAqL1xuICAgIGNsaWVudC5uZXh0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBtdWx0aWJyb3dzZXIucHJvbWlzZUJ1Y2tldC5wdXNoKHRoaXMucHJvbWlzZSlcbiAgICAgICAgcmV0dXJuIF9uZXh0LmFwcGx5KHRoaXMsIGFyZ3VtZW50cylcbiAgICB9XG5cbiAgICByZXR1cm4gY2xpZW50XG59XG5cbmZ1bmN0aW9uIG11bHRpcmVtb3RlTW9kaWZpZXIgKGNsaWVudCkge1xuICAgIGxldCBtdWx0aWJyb3dzZXIgPSB0aGlzXG4gICAgbGV0IGJyb3dzZXJOYW1lcyA9IE9iamVjdC5rZXlzKG11bHRpYnJvd3Nlci5pbnN0YW5jZXMpXG5cbiAgICBjbGllbnQubmV4dCA9IGZ1bmN0aW9uICguLi5hcmdzKSB7XG4gICAgICAgIGxldCBwcm9taXNlcyA9IFtdXG4gICAgICAgIGxldCBmbk5hbWUgPSBhcmdzLnBvcCgpXG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIG5vIG5lZWQgZm9yIGFjdHVhbCBmdW5jdGlvbiBoZXJlXG4gICAgICAgICAqL1xuICAgICAgICBhcmdzLnNoaWZ0KClcblxuICAgICAgICAvKipcbiAgICAgICAgICogZmx1c2ggcHJvbWlzZSBidWNrZXRcbiAgICAgICAgICovXG4gICAgICAgIG11bHRpYnJvd3Nlci5wcm9taXNlQnVja2V0ID0gW11cbiAgICAgICAgbGV0IGNvbW1hbmRBcmdzID0gYXJncy5wb3AoKVxuICAgICAgICByZXR1cm4gdGhpcy5sYXN0UHJvbWlzZS5kb25lKCgpID0+IHtcbiAgICAgICAgICAgIGJyb3dzZXJOYW1lcy5mb3JFYWNoKChicm93c2VyTmFtZSkgPT4ge1xuICAgICAgICAgICAgICAgIGxldCBpbnN0YW5jZSA9IG11bHRpYnJvd3Nlci5pbnN0YW5jZXNbYnJvd3Nlck5hbWVdXG4gICAgICAgICAgICAgICAgcHJvbWlzZXMucHVzaChpbnN0YW5jZVtmbk5hbWVdLmFwcGx5KGluc3RhbmNlLCBjb21tYW5kQXJncykucHJvbWlzZSlcbiAgICAgICAgICAgIH0pXG5cbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLmFsbChwcm9taXNlcykudGhlbigocmVzdWx0KSA9PiB7XG4gICAgICAgICAgICAgICAgLyoqXG4gICAgICAgICAgICAgICAgICogY3VzdG9tIGV2ZW50IGhhbmRsaW5nIHNpbmNlIG11bHRpYnJvd3NlciBpbnN0YW5jZVxuICAgICAgICAgICAgICAgICAqIGFjdHVhbGx5IG5ldmVyIGV4ZWN1dGVzIGFueSBjb21tYW5kXG4gICAgICAgICAgICAgICAgICovXG4gICAgICAgICAgICAgICAgbGV0IHBheWxvYWQgPSB7XG4gICAgICAgICAgICAgICAgICAgIGZuTmFtZTogZm5OYW1lXG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBicm93c2VyTmFtZXMubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICAgICAgICAgICAgcGF5bG9hZFticm93c2VyTmFtZXNbaV1dID0gcmVzdWx0W2ldXG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgaWYgKGZuTmFtZS5tYXRjaCgvKGluaXR8ZW5kKS8pKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZW1pdChmbk5hbWUsIHBheWxvYWQpXG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdGhpcy5lbWl0KCdyZXN1bHQnLCBwYXlsb2FkKVxuICAgICAgICAgICAgICAgIHRoaXMuZGVmZXIucmVzb2x2ZShyZXN1bHQpXG4gICAgICAgICAgICB9LCAoZXJyKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5lbWl0KCdlcnJvcicsIGVycilcbiAgICAgICAgICAgICAgICB0aGlzLmRlZmVyLnJlamVjdChlcnIpXG4gICAgICAgICAgICB9KVxuICAgICAgICB9KVxuICAgIH1cblxuICAgIHZhciBfdGhlbiA9IGNsaWVudC50aGVuXG4gICAgY2xpZW50LnRoZW4gPSBmdW5jdGlvbiAob25GdWxmaWxsZWQsIG9uUmVqZWN0ZWQpIHtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIGN1cnJ5IGFyZ3VtZW50c1xuICAgICAgICAgKiBhcyBtdWx0aWJyb3dzZXIgY29tbWFuZHMgcmV0dXJuIHdpdGggYW4gYXJyYXkgb2YgcmVzdWx0cyBmb3IgZWFjaCBpbnN0YW5jZVxuICAgICAgICAgKiByZXNwZWN0aXZlbHkgKHNlZSBxLmFsbCkgd2UgbmVlZCB0byBjdXJyeSB0aGVtIChleHBhbmQgYXJndW1lbnRzKSB0byBoZWxwXG4gICAgICAgICAqIHVzZXJzIHRvIGJldHRlciB3b3JrIHdpdGggdGhlIHJlc3VsdHNcbiAgICAgICAgICpcbiAgICAgICAgICogdW5jdXJyaWVkIG9yaWdpbmFsIHZlcnNpb246XG4gICAgICAgICAqIGBgYGpzXG4gICAgICAgICAqIG1hdHJpeC5nZXRUaXRsZSgpLnRoZW4oZnVuY3Rpb24gKHJlc3VsdCkge1xuICAgICAgICAgKiAgICAgZXhwZWN0KHJlc3VsdFswXSkudG8uYmUuZXF1YWwoJ3RpdGxlIG9mIGJyb3dzZXIgQScpXG4gICAgICAgICAqICAgICBleHBlY3QocmVzdWx0WzFdKS50by5iZS5lcXVhbCgndGl0bGUgb2YgYnJvd3NlciBCJylcbiAgICAgICAgICogfSlcbiAgICAgICAgICogYGBgXG4gICAgICAgICAqXG4gICAgICAgICAqIGN1cnJpZWQgdmVyc2lvbjpcbiAgICAgICAgICogYGBganNcbiAgICAgICAgICogbWF0cml4LmdldFRpdGxlKCkudGhlbihmdW5jdGlvbiAodGl0bGVCcm93c2VyQSwgdGl0bGVCcm93c2VyQikge1xuICAgICAgICAgKiAgICAgZXhwZWN0KHRpdGxlQnJvd3NlckEpLnRvLmJlLmVxdWFsKCd0aXRsZSBvZiBicm93c2VyIEEnKVxuICAgICAgICAgKiAgICAgZXhwZWN0KHRpdGxlQnJvd3NlckIpLnRvLmJlLmVxdWFsKCd0aXRsZSBvZiBicm93c2VyIEInKVxuICAgICAgICAgKiB9KVxuICAgICAgICAgKiBgYGBcbiAgICAgICAgICovXG4gICAgICAgIGxldCBjdXJyeUFyZ3VtZW50cyA9IGZ1bmN0aW9uIChhcmdzKSB7XG4gICAgICAgICAgICAvKipcbiAgICAgICAgICAgICAqIHdoZW4gcmV0dXJuaW5nIHdpdGggYSBwcm9taXNlIHdpdGhpbiBhIG11bHRpYnJvd3NlciBwcm9taXNlIGxpa2VcbiAgICAgICAgICAgICAqXG4gICAgICAgICAgICAgKiBgYGBqc1xuICAgICAgICAgICAgICogbWF0cml4LnVybCguLi4pLmdldFRpdGxlKCkudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgKiAgICAgcmV0dXJuIG1hdHJpeC5nZXRTb3VyY2UoKVxuICAgICAgICAgICAgICogfSlcbiAgICAgICAgICAgICAqIGBgYFxuICAgICAgICAgICAgICpcbiAgICAgICAgICAgICAqIHdlIHdpbGwgaGF2ZSBwcm9ibGVtcyBhcyB3ZSBhcmUgcnVubmluZyB0aHJvdWdoIGN1cnJ5QXJndW1lbnRzIHR3aWNlLlxuICAgICAgICAgICAgICogVGhlcmVmb3IgY2hlY2sgaWYgdGhlIG9uRnVsRmlsbGVkIGhhbmRsZXIgaXMgZnJvbSB0aGUgUSBsaWJyYXJ5IGFuZFxuICAgICAgICAgICAgICogaGFuZGxlIHRoYXQgcHJvbWlzZSBhcyB1c3VhbCBoZXJlLlxuICAgICAgICAgICAgICogSXQncyBhbiB1Z2x5IGhhY2sgYnV0IHRoZSBvbmx5IHdheSB0byBnZXQgYXJvdW5kIHdpdGggdGhpcyBhbmQgaGF2aW5nXG4gICAgICAgICAgICAgKiBuaWNlIGN1cnJpZWQgYXJndW1lbnRzLlxuICAgICAgICAgICAgICpcbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgaWYgKG9uRnVsZmlsbGVkLnRvU3RyaW5nKCkgPT09IG11bHRpYnJvd3Nlci5xUmVzb2x2ZSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBvbkZ1bGZpbGxlZC5hcHBseSh0aGlzLCBhcmd1bWVudHMpXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMSAmJiAhQXJyYXkuaXNBcnJheShhcmdzKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBvbkZ1bGZpbGxlZC5jYWxsKHRoaXMsIGFyZ3MpXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID4gMSkge1xuICAgICAgICAgICAgICAgIGFyZ3MgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMpXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiBvbkZ1bGZpbGxlZC5hcHBseSh0aGlzLCBhcmdzKVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCFvbkZ1bGZpbGxlZCAmJiAhb25SZWplY3RlZCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXNcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChvbkZ1bGZpbGxlZCAmJiAhb25SZWplY3RlZCkge1xuICAgICAgICAgICAgcmV0dXJuIF90aGVuLmNhbGwodGhpcywgY3VycnlBcmd1bWVudHMpXG4gICAgICAgIH1cblxuICAgICAgICBpZiAob25GdWxmaWxsZWQgJiYgb25SZWplY3RlZCkge1xuICAgICAgICAgICAgcmV0dXJuIF90aGVuLmNhbGwodGhpcywgY3VycnlBcmd1bWVudHMsIG9uUmVqZWN0ZWQpXG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gX3RoZW4uY2FsbCh0aGlzLCB1bmRlZmluZWQsIG9uUmVqZWN0ZWQpXG4gICAgfVxuXG4gICAgY2xpZW50LnNlbGVjdCA9IGZ1bmN0aW9uIChicm93c2VyTmFtZSkge1xuICAgICAgICB2YXIgaW5zdGFuY2UgPSBtdWx0aWJyb3dzZXIuaW5zdGFuY2VzW2Jyb3dzZXJOYW1lXVxuXG4gICAgICAgIGlmICghaW5zdGFuY2UpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgYnJvd3NlciBuYW1lIFwiJHticm93c2VyTmFtZX1cIiB3YXMgbm90IGRlZmluZWRgKVxuICAgICAgICB9XG5cbiAgICAgICAgaW5zdGFuY2UuaXNNdWx0aWJyb3dzZXIgPSBmYWxzZVxuICAgICAgICByZXR1cm4gaW5zdGFuY2VcbiAgICB9XG5cbiAgICBjbGllbnQuc3luYyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGJ1Y2tldCA9IG11bHRpYnJvd3Nlci5mbHVzaFByb21pc2VCdWNrZXQoKVxuICAgICAgICByZXR1cm4gdGhpcy5jYWxsKCgpID0+IFByb21pc2UuYWxsKGJ1Y2tldCkpXG4gICAgfVxuXG4gICAgdmFyIF9hZGRDb21tYW5kID0gY2xpZW50LmFkZENvbW1hbmRcbiAgICBjbGllbnQuYWRkQ29tbWFuZCA9IGZ1bmN0aW9uIChmbk5hbWUsIGZuLCBmb3JjZU92ZXJ3cml0ZSkge1xuICAgICAgICBfYWRkQ29tbWFuZC5jYWxsKHRoaXMsIGZuTmFtZSwgZm4sIGZvcmNlT3ZlcndyaXRlKVxuICAgICAgICBPYmplY3Qua2V5cyhtdWx0aWJyb3dzZXIuaW5zdGFuY2VzKS5mb3JFYWNoKChicm93c2VyTmFtZSkgPT4ge1xuICAgICAgICAgICAgbGV0IGluc3RhbmNlID0gbXVsdGlicm93c2VyLmluc3RhbmNlc1ticm93c2VyTmFtZV1cbiAgICAgICAgICAgIGluc3RhbmNlLmFkZENvbW1hbmQoZm5OYW1lLCBmbiwgZm9yY2VPdmVyd3JpdGUpXG4gICAgICAgIH0pXG4gICAgICAgIHJldHVybiB0aGlzXG4gICAgfVxuXG4gICAgcmV0dXJuIGNsaWVudFxufVxuXG5leHBvcnQgZGVmYXVsdCBNdWx0aWJyb3dzZXJcbiJdfQ==