all files / fc-er/ Deferred.js

91.67% Statements 121/132
73.68% Branches 28/38
86.21% Functions 25/29
91.38% Lines 106/116
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 26412×   119×                   178× 54×     124×   124× 124× 62× 62× 62×         124× 16×   108×     124× 124×     130× 62× 61× 61× 61×   58×     58×                         119×   119× 119× 119× 119×   119×           119×   119×               92×       92× 92×   92×           92×         21×       21× 21×   21×           21×                                 65× 65×   65× 65×   65×   65×         105×                   10×   10×   10×   10× 10×   10×   10×           10× 10×                                                                                    
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; Eif ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { Eif (protoProps) defineProperties(Constructor.prototype, protoProps); Eif (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
 
function _classCallCheck(instance, Constructor) { Iif (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
 
Eif (typeof define !== 'function') {
    var define = require('amdefine')(module);
}
 
define(function (require) {
    'use strict';
 
    var util = require('./util');
    var assert = require('./assert');
    var EventTarget = require('fc-mini-event/EventTarget');
 
    var setImmediate = typeof global.setImmediate === 'function' ? global.setImmediate : function (fn) {
        global.setTimeout(fn, 0);
    };
 
    var tryFlush = function tryFlush(deferred) {
        if (deferred.state === 'pending') {
            return;
        }
 
        var callbacks = deferred.state === 'resolved' ? deferred._doneCallbacks.slice() : deferred._failCallbacks.slice();
 
        var flush = function flush() {
            for (var i = 0; i < callbacks.length; i++) {
                var callback = callbacks[i];
                try {
                    callback.apply(deferred.promise, deferred._args);
                } catch (ex) {}
            }
        };
 
        if (deferred.syncModeEnabled) {
            flush();
        } else {
            setImmediate(flush);
        }
 
        deferred._doneCallbacks = [];
        deferred._failCallbacks = [];
    };
 
    var pipe = function pipe(original, deferred, callback, actionType) {
        return function () {
            if (typeof callback === 'function') {
                var resolver = deferred.resolver;
                try {
                    var returnValue = callback.apply(original.promise, arguments);
 
                    Iif (Deferred.isPromise(returnValue)) {
                        returnValue.then(resolver.resolve, resolver.reject);
                    } else {
                        resolver.resolve(returnValue);
                    }
                } catch (error) {
                    Deferred.fire('exception', {
                        deferred: original,
                        args: [error],
                        reason: error
                    });
                    resolver.reject(error);
                }
            } else {
                deferred[actionType].apply(deferred, original._args);
            }
        };
    };
 
    var Deferred = function () {
        function Deferred() {
            _classCallCheck(this, Deferred);
 
            this.state = 'pending';
            this._args = null;
            this._doneCallbacks = [];
            this._failCallbacks = [];
 
            this.promise = {
                done: util.bind(this.done, this),
                fail: util.bind(this.fail, this),
                ensure: util.bind(this.ensure, this),
                then: util.bind(this.then, this)
            };
            this.promise.promise = this.promise;
 
            this.resolver = {
                resolve: util.bind(this.resolve, this),
                reject: util.bind(this.reject, this)
            };
        }
 
        _createClass(Deferred, [{
            key: 'resolve',
            value: function resolve() {
                Iif (this.state !== 'pending') {
                    return;
                }
 
                this.state = 'resolved';
                this._args = [].slice.call(arguments);
 
                Deferred.fire('resolve', {
                    deferred: this,
                    args: this._args,
                    reason: this._args[0]
                });
 
                tryFlush(this);
            }
        }, {
            key: 'reject',
            value: function reject() {
                Iif (this.state !== 'pending') {
                    return;
                }
 
                this.state = 'rejected';
                this._args = [].slice.call(arguments);
 
                Deferred.fire('reject', {
                    deferred: this,
                    args: this._args,
                    reason: this._args[0]
                });
 
                tryFlush(this);
            }
        }, {
            key: 'done',
            value: function done(callback) {
                return this.then(callback);
            }
        }, {
            key: 'fail',
            value: function fail(callback) {
                return this.then(null, callback);
            }
        }, {
            key: 'ensure',
            value: function ensure(callback) {
                return this.then(callback, callback);
            }
        }, {
            key: 'then',
            value: function then(done, fail) {
                var deferred = new Deferred();
                deferred.syncModeEnabled = this.syncModeEnabled;
 
                this._doneCallbacks.push(pipe(this, deferred, done, 'resolve'));
                this._failCallbacks.push(pipe(this, deferred, fail, 'reject'));
 
                tryFlush(this);
 
                return deferred.promise;
            }
        }], [{
            key: 'isPromise',
            value: function isPromise(value) {
                return value && typeof value.then === 'function';
            }
        }, {
            key: 'all',
            value: function all() {
                var workingUnits = [].concat.apply([], arguments);
                var workingCount = workingUnits.length;
 
                if (!workingCount) {
                    return Deferred.resolved();
                }
 
                var actionType = 'resolve';
                var result = [];
 
                var jointDeferred = new Deferred();
 
                var resolveOne = function resolveOne(whichToFill) {
                    workingCount--;
 
                    assert.greaterThanOrEquals(workingCount, 0, 'workingCount should be positive');
 
                    var unitResult = [].slice.call(arguments, 1);
 
                    Eif (unitResult.length <= 1) {
                        unitResult = unitResult[0];
                    }
                    result[whichToFill] = unitResult;
 
                    if (workingCount === 0) {
                        jointDeferred[actionType].apply(jointDeferred, result);
                    }
                };
 
                var rejectOne = function rejectOne() {
                    actionType = 'reject';
                    resolveOne.apply(this, arguments);
                };
 
                for (var i = 0; i < workingUnits.length; i++) {
                    var unit = workingUnits[i];
                    unit.then(util.bind(resolveOne, unit, i), util.bind(rejectOne, unit, i));
                }
 
                return jointDeferred.promise;
            }
        }, {
            key: 'resolved',
            value: function resolved() {
                var deferred = new Deferred();
                deferred.resolve.apply(deferred, arguments);
                return deferred.promise;
            }
        }, {
            key: 'rejected',
            value: function rejected() {
                var deferred = new Deferred();
                deferred.reject.apply(deferred, arguments);
                return deferred.promise;
            }
        }, {
            key: 'when',
            value: function when(value) {
                if (Deferred.isPromise(value)) {
                    return value;
                }
 
                var deferred = new Deferred();
                deferred.syncModeEnabled = true;
                deferred.resolve(value);
                return deferred.promise;
            }
        }, {
            key: 'require',
            value: function (_require) {
                function require(_x) {
                    return _require.apply(this, arguments);
                }
 
                require.toString = function () {
                    return _require.toString();
                };
 
                return require;
            }(function (modules) {
                var deferred = new Deferred();
 
                require(modules, deferred.resolver.resolve);
 
                deferred.promise.abort = deferred.resolver.reject;
 
                return deferred.promise;
            })
        }]);
 
        return Deferred;
    }();
 
    EventTarget.enable(Deferred);
 
    return Deferred;
});
//# sourceMappingURL=data:application/json;base64,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LEVBQTJCLENBQTNCLENBRkosRUFGMEM7aUJBQTlDOztBQVFBLHVCQUFPLGNBQWMsT0FBZCxDQTNDRTs7Ozt1Q0E4Q0s7QUFDZCxvQkFBTSxXQUFXLElBQUksUUFBSixFQUFYLENBRFE7QUFFZCx5QkFBUyxPQUFULENBQWlCLEtBQWpCLENBQXVCLFFBQXZCLEVBQWlDLFNBQWpDLEVBRmM7QUFHZCx1QkFBTyxTQUFTLE9BQVQsQ0FITzs7Ozt1Q0FNQTtBQUNkLG9CQUFNLFdBQVcsSUFBSSxRQUFKLEVBQVgsQ0FEUTtBQUVkLHlCQUFTLE1BQVQsQ0FBZ0IsS0FBaEIsQ0FBc0IsUUFBdEIsRUFBZ0MsU0FBaEMsRUFGYztBQUdkLHVCQUFPLFNBQVMsT0FBVCxDQUhPOzs7O2lDQU1OLE9BQU87QUFDZixvQkFBSSxTQUFTLFNBQVQsQ0FBbUIsS0FBbkIsQ0FBSixFQUErQjtBQUMzQiwyQkFBTyxLQUFQLENBRDJCO2lCQUEvQjs7QUFJQSxvQkFBTSxXQUFXLElBQUksUUFBSixFQUFYLENBTFM7QUFNZix5QkFBUyxlQUFULEdBQTJCLElBQTNCLENBTmU7QUFPZix5QkFBUyxPQUFULENBQWlCLEtBQWpCLEVBUGU7QUFRZix1QkFBTyxTQUFTLE9BQVQsQ0FSUTs7Ozs7Ozs7Ozs7Ozs7d0JBV0osU0FBUztBQUNwQixvQkFBTSxXQUFXLElBQUksUUFBSixFQUFYLENBRGM7O0FBR3BCLHdCQUFRLE9BQVIsRUFBaUIsU0FBUyxRQUFULENBQWtCLE9BQWxCLENBQWpCLENBSG9COztBQUtwQix5QkFBUyxPQUFULENBQWlCLEtBQWpCLEdBQXlCLFNBQVMsUUFBVCxDQUFrQixNQUFsQixDQUxMOztBQU9wQix1QkFBTyxTQUFTLE9BQVQsQ0FQYTs7Ozs7UUEvTk47O0FBME90QixnQkFBWSxNQUFaLENBQW1CLFFBQW5CLEVBMU9zQjs7QUE0T3RCLFdBQU8sUUFBUCxDQTVPc0I7Q0FBbkIsQ0FBUCIsImZpbGUiOiJEZWZlcnJlZC5qcyIsInNvdXJjZXNDb250ZW50IjpbImlmICh0eXBlb2YgZGVmaW5lICE9PSAnZnVuY3Rpb24nKSB7dmFyIGRlZmluZSA9IHJlcXVpcmUoJ2FtZGVmaW5lJykobW9kdWxlKX1cblxuZGVmaW5lKGZ1bmN0aW9uIChyZXF1aXJlKSB7XG4gICAgJ3VzZSBzdHJpY3QnO1xuXG4gICAgY29uc3QgdXRpbCA9IHJlcXVpcmUoJy4vdXRpbCcpO1xuICAgIGNvbnN0IGFzc2VydCA9ICByZXF1aXJlKCcuL2Fzc2VydCcpO1xuICAgIGNvbnN0IEV2ZW50VGFyZ2V0ID0gcmVxdWlyZSgnZmMtbWluaS1ldmVudC9FdmVudFRhcmdldCcpO1xuXG4gICAgY29uc3Qgc2V0SW1tZWRpYXRlID0gdHlwZW9mIGdsb2JhbC5zZXRJbW1lZGlhdGUgPT09ICdmdW5jdGlvbicgPyBnbG9iYWwuc2V0SW1tZWRpYXRlIDogZnVuY3Rpb24gKGZuKSB7XG4gICAgICAgIGdsb2JhbC5zZXRUaW1lb3V0KGZuLCAwKTtcbiAgICB9O1xuXG4gICAgY29uc3QgdHJ5Rmx1c2ggPSAoZGVmZXJyZWQpID0+IHtcbiAgICAgICAgaWYgKGRlZmVycmVkLnN0YXRlID09PSAncGVuZGluZycpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGNhbGxiYWNrcyA9IGRlZmVycmVkLnN0YXRlID09PSAncmVzb2x2ZWQnXG4gICAgICAgICAgICA/IGRlZmVycmVkLl9kb25lQ2FsbGJhY2tzLnNsaWNlKClcbiAgICAgICAgICAgIDogZGVmZXJyZWQuX2ZhaWxDYWxsYmFja3Muc2xpY2UoKTtcblxuICAgICAgICBjb25zdCBmbHVzaCA9ICgpID0+IHtcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgY2FsbGJhY2tzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgY2FsbGJhY2sgPSBjYWxsYmFja3NbaV07XG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgY2FsbGJhY2suYXBwbHkoZGVmZXJyZWQucHJvbWlzZSwgZGVmZXJyZWQuX2FyZ3MpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjYXRjaCAoZXgpIHtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG5cbiAgICAgICAgaWYgKGRlZmVycmVkLnN5bmNNb2RlRW5hYmxlZCkge1xuICAgICAgICAgICAgZmx1c2goKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHNldEltbWVkaWF0ZShmbHVzaCk7XG4gICAgICAgIH1cblxuICAgICAgICBkZWZlcnJlZC5fZG9uZUNhbGxiYWNrcyA9IFtdO1xuICAgICAgICBkZWZlcnJlZC5fZmFpbENhbGxiYWNrcyA9IFtdO1xuICAgIH07XG5cbiAgICBjb25zdCBwaXBlID0gKG9yaWdpbmFsLCBkZWZlcnJlZCwgY2FsbGJhY2ssIGFjdGlvblR5cGUpID0+IHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgY2FsbGJhY2sgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgICAgICBjb25zdCByZXNvbHZlciA9IGRlZmVycmVkLnJlc29sdmVyO1xuICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHJldHVyblZhbHVlID0gY2FsbGJhY2suYXBwbHkob3JpZ2luYWwucHJvbWlzZSwgYXJndW1lbnRzKTtcblxuICAgICAgICAgICAgICAgICAgICBpZiAoRGVmZXJyZWQuaXNQcm9taXNlKChyZXR1cm5WYWx1ZSkpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm5WYWx1ZS50aGVuKHJlc29sdmVyLnJlc29sdmUsIHJlc29sdmVyLnJlamVjdCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlci5yZXNvbHZlKHJldHVyblZhbHVlKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgRGVmZXJyZWQuZmlyZSgnZXhjZXB0aW9uJywge1xuICAgICAgICAgICAgICAgICAgICAgICAgZGVmZXJyZWQ6IG9yaWdpbmFsLFxuICAgICAgICAgICAgICAgICAgICAgICAgYXJnczogW2Vycm9yXSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlYXNvbjogZXJyb3JcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmVyLnJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgZGVmZXJyZWRbYWN0aW9uVHlwZV0uYXBwbHkoZGVmZXJyZWQsIG9yaWdpbmFsLl9hcmdzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICB9O1xuXG4gICAgY2xhc3MgRGVmZXJyZWQge1xuICAgICAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgICAgIHRoaXMuc3RhdGUgPSAncGVuZGluZyc7XG4gICAgICAgICAgICB0aGlzLl9hcmdzID0gbnVsbDtcbiAgICAgICAgICAgIHRoaXMuX2RvbmVDYWxsYmFja3MgPSBbXTtcbiAgICAgICAgICAgIHRoaXMuX2ZhaWxDYWxsYmFja3MgPSBbXTtcblxuICAgICAgICAgICAgdGhpcy5wcm9taXNlID0ge1xuICAgICAgICAgICAgICAgIGRvbmU6IHV0aWwuYmluZCh0aGlzLmRvbmUsIHRoaXMpLFxuICAgICAgICAgICAgICAgIGZhaWw6IHV0aWwuYmluZCh0aGlzLmZhaWwsIHRoaXMpLFxuICAgICAgICAgICAgICAgIGVuc3VyZTogdXRpbC5iaW5kKHRoaXMuZW5zdXJlLCB0aGlzKSxcbiAgICAgICAgICAgICAgICB0aGVuOiB1dGlsLmJpbmQodGhpcy50aGVuLCB0aGlzKVxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIHRoaXMucHJvbWlzZS5wcm9taXNlID0gdGhpcy5wcm9taXNlO1xuXG4gICAgICAgICAgICB0aGlzLnJlc29sdmVyID0ge1xuICAgICAgICAgICAgICAgIHJlc29sdmU6IHV0aWwuYmluZCh0aGlzLnJlc29sdmUsIHRoaXMpLFxuICAgICAgICAgICAgICAgIHJlamVjdDogdXRpbC5iaW5kKHRoaXMucmVqZWN0LCB0aGlzKVxuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJlc29sdmUoKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5zdGF0ZSAhPT0gJ3BlbmRpbmcnKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLnN0YXRlID0gJ3Jlc29sdmVkJztcbiAgICAgICAgICAgIHRoaXMuX2FyZ3MgPSBbXS5zbGljZS5jYWxsKGFyZ3VtZW50cyk7XG5cbiAgICAgICAgICAgIERlZmVycmVkLmZpcmUoJ3Jlc29sdmUnLCB7XG4gICAgICAgICAgICAgICAgZGVmZXJyZWQ6IHRoaXMsXG4gICAgICAgICAgICAgICAgYXJnczogdGhpcy5fYXJncyxcbiAgICAgICAgICAgICAgICByZWFzb246IHRoaXMuX2FyZ3NbMF1cbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICB0cnlGbHVzaCh0aGlzKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJlamVjdCgpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLnN0YXRlICE9PSAncGVuZGluZycpIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHRoaXMuc3RhdGUgPSAncmVqZWN0ZWQnO1xuICAgICAgICAgICAgdGhpcy5fYXJncyA9IFtdLnNsaWNlLmNhbGwoYXJndW1lbnRzKTtcblxuICAgICAgICAgICAgRGVmZXJyZWQuZmlyZSgncmVqZWN0Jywge1xuICAgICAgICAgICAgICAgIGRlZmVycmVkOiB0aGlzLFxuICAgICAgICAgICAgICAgIGFyZ3M6IHRoaXMuX2FyZ3MsXG4gICAgICAgICAgICAgICAgcmVhc29uOiB0aGlzLl9hcmdzWzBdXG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgdHJ5Rmx1c2godGhpcyk7XG4gICAgICAgIH1cblxuICAgICAgICBkb25lKGNhbGxiYWNrKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy50aGVuKGNhbGxiYWNrKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGZhaWwoY2FsbGJhY2spIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnRoZW4obnVsbCwgY2FsbGJhY2spO1xuICAgICAgICB9XG5cbiAgICAgICAgZW5zdXJlKGNhbGxiYWNrKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy50aGVuKGNhbGxiYWNrLCBjYWxsYmFjayk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGVuKGRvbmUsIGZhaWwpIHtcbiAgICAgICAgICAgIGxldCBkZWZlcnJlZCA9IG5ldyBEZWZlcnJlZCgpO1xuICAgICAgICAgICAgZGVmZXJyZWQuc3luY01vZGVFbmFibGVkID0gdGhpcy5zeW5jTW9kZUVuYWJsZWQ7XG5cbiAgICAgICAgICAgIHRoaXMuX2RvbmVDYWxsYmFja3MucHVzaChwaXBlKHRoaXMsIGRlZmVycmVkLCBkb25lLCAncmVzb2x2ZScpKTtcbiAgICAgICAgICAgIHRoaXMuX2ZhaWxDYWxsYmFja3MucHVzaChwaXBlKHRoaXMsIGRlZmVycmVkLCBmYWlsLCAncmVqZWN0JykpO1xuXG4gICAgICAgICAgICB0cnlGbHVzaCh0aGlzKTtcblxuICAgICAgICAgICAgcmV0dXJuIGRlZmVycmVkLnByb21pc2U7XG4gICAgICAgIH1cblxuICAgICAgICBzdGF0aWMgaXNQcm9taXNlKHZhbHVlKSB7XG4gICAgICAgICAgICByZXR1cm4gdmFsdWUgJiYgdHlwZW9mIHZhbHVlLnRoZW4gPT09ICdmdW5jdGlvbic7XG4gICAgICAgIH1cblxuICAgICAgICBzdGF0aWMgYWxsKCkge1xuICAgICAgICAgICAgY29uc3Qgd29ya2luZ1VuaXRzID0gW10uY29uY2F0LmFwcGx5KFtdLCBhcmd1bWVudHMpO1xuICAgICAgICAgICAgbGV0IHdvcmtpbmdDb3VudCA9IHdvcmtpbmdVbml0cy5sZW5ndGg7XG5cbiAgICAgICAgICAgIGlmICghd29ya2luZ0NvdW50KSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIERlZmVycmVkLnJlc29sdmVkKCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGxldCBhY3Rpb25UeXBlID0gJ3Jlc29sdmUnO1xuICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gW107XG5cbiAgICAgICAgICAgIGNvbnN0IGpvaW50RGVmZXJyZWQgPSBuZXcgRGVmZXJyZWQoKTtcblxuICAgICAgICAgICAgY29uc3QgcmVzb2x2ZU9uZSA9IGZ1bmN0aW9uICh3aGljaFRvRmlsbCkge1xuICAgICAgICAgICAgICAgIHdvcmtpbmdDb3VudC0tO1xuXG4gICAgICAgICAgICAgICAgYXNzZXJ0LmdyZWF0ZXJUaGFuT3JFcXVhbHMod29ya2luZ0NvdW50LCAwLCAnd29ya2luZ0NvdW50IHNob3VsZCBiZSBwb3NpdGl2ZScpO1xuXG4gICAgICAgICAgICAgICAgbGV0IHVuaXRSZXN1bHQgPSBbXS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMSk7XG5cbiAgICAgICAgICAgICAgICBpZiAodW5pdFJlc3VsdC5sZW5ndGggPD0gMSkge1xuICAgICAgICAgICAgICAgICAgICB1bml0UmVzdWx0ID0gdW5pdFJlc3VsdFswXTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmVzdWx0W3doaWNoVG9GaWxsXSA9IHVuaXRSZXN1bHQ7XG5cbiAgICAgICAgICAgICAgICBpZiAod29ya2luZ0NvdW50ID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgIGpvaW50RGVmZXJyZWRbYWN0aW9uVHlwZV0uYXBwbHkoam9pbnREZWZlcnJlZCwgcmVzdWx0KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICBjb25zdCByZWplY3RPbmUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgYWN0aW9uVHlwZSA9ICdyZWplY3QnO1xuICAgICAgICAgICAgICAgIHJlc29sdmVPbmUuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgd29ya2luZ1VuaXRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgdW5pdCA9IHdvcmtpbmdVbml0c1tpXTtcbiAgICAgICAgICAgICAgICB1bml0LnRoZW4oXG4gICAgICAgICAgICAgICAgICAgIHV0aWwuYmluZChyZXNvbHZlT25lLCB1bml0LCBpKSxcbiAgICAgICAgICAgICAgICAgICAgdXRpbC5iaW5kKHJlamVjdE9uZSwgdW5pdCwgaSlcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gam9pbnREZWZlcnJlZC5wcm9taXNlO1xuICAgICAgICB9XG5cbiAgICAgICAgc3RhdGljIHJlc29sdmVkKCkge1xuICAgICAgICAgICAgY29uc3QgZGVmZXJyZWQgPSBuZXcgRGVmZXJyZWQoKTtcbiAgICAgICAgICAgIGRlZmVycmVkLnJlc29sdmUuYXBwbHkoZGVmZXJyZWQsIGFyZ3VtZW50cyk7XG4gICAgICAgICAgICByZXR1cm4gZGVmZXJyZWQucHJvbWlzZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHN0YXRpYyByZWplY3RlZCgpIHtcbiAgICAgICAgICAgIGNvbnN0IGRlZmVycmVkID0gbmV3IERlZmVycmVkKCk7XG4gICAgICAgICAgICBkZWZlcnJlZC5yZWplY3QuYXBwbHkoZGVmZXJyZWQsIGFyZ3VtZW50cyk7XG4gICAgICAgICAgICByZXR1cm4gZGVmZXJyZWQucHJvbWlzZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHN0YXRpYyB3aGVuKHZhbHVlKSB7XG4gICAgICAgICAgICBpZiAoRGVmZXJyZWQuaXNQcm9taXNlKHZhbHVlKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3QgZGVmZXJyZWQgPSBuZXcgRGVmZXJyZWQoKTtcbiAgICAgICAgICAgIGRlZmVycmVkLnN5bmNNb2RlRW5hYmxlZCA9IHRydWU7XG4gICAgICAgICAgICBkZWZlcnJlZC5yZXNvbHZlKHZhbHVlKTtcbiAgICAgICAgICAgIHJldHVybiBkZWZlcnJlZC5wcm9taXNlO1xuICAgICAgICB9XG5cbiAgICAgICAgc3RhdGljIHJlcXVpcmUobW9kdWxlcykge1xuICAgICAgICAgICAgY29uc3QgZGVmZXJyZWQgPSBuZXcgRGVmZXJyZWQoKTtcblxuICAgICAgICAgICAgcmVxdWlyZShtb2R1bGVzLCBkZWZlcnJlZC5yZXNvbHZlci5yZXNvbHZlKTtcblxuICAgICAgICAgICAgZGVmZXJyZWQucHJvbWlzZS5hYm9ydCA9IGRlZmVycmVkLnJlc29sdmVyLnJlamVjdDtcblxuICAgICAgICAgICAgcmV0dXJuIGRlZmVycmVkLnByb21pc2U7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBFdmVudFRhcmdldC5lbmFibGUoRGVmZXJyZWQpO1xuXG4gICAgcmV0dXJuIERlZmVycmVkO1xufSk7XG4iXX0=