Code coverage report for lib/Store.js

Statements: 94.95% (94 / 99)      Branches: 76.79% (43 / 56)      Functions: 100% (16 / 16)      Lines: 97.67% (84 / 86)      Ignored: none     

All files » lib/ » Store.js
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    2   1   1   87                     1   1   1         1 87   87   87 87     1   1     90                 40 3   3     40 30 30   10 10   10 10               15 6 6   9 9               6 4   2               53   53 1 52             3   3         3 9   9   9 5   4       3             1             42 42 42 42 42     42 42   42 10   5 2   5   2 2   1   3 2   3           35   35             39 41     39 39 39   39 39   39 29 29     39 39 39               1     1     1 56      
"use strict";
 
var _interopRequire = function (obj) { return obj && obj.__esModule ? obj["default"] : obj; };
 
var _prototypeProperties = function (child, staticProps, instanceProps) { Eif (staticProps) Object.defineProperties(child, staticProps); Eif (instanceProps) Object.defineProperties(child.prototype, instanceProps); };
 
var _inherits = function (subClass, superClass) { Iif (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); Eif (superClass) subClass.__proto__ = superClass; };
 
var _classCallCheck = function (instance, Constructor) { Iif (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } };
 
/**
 * Store
 *
 * Stores hold application state. They respond to actions sent by the dispatcher
 * and broadcast change events to listeners, so they can grab the latest data.
 * The key thing to remember is that the only way stores receive information
 * from the outside world is via the dispatcher.
 */
 
var EventEmitter = _interopRequire(require("eventemitter3"));
 
var assign = _interopRequire(require("object-assign"));
 
var Store = (function (EventEmitter) {
  /**
   * Stores are initialized with a reference
   * @type {Object}
   */
  function Store() {
    _classCallCheck(this, Store);
 
    this.state = null;
 
    this._handlers = {};
    this._asyncHandlers = {};
  }
 
  _inherits(Store, EventEmitter);
 
  _prototypeProperties(Store, {
    assignState: {
      value: function assignState(oldState, newState) {
        return assign({}, oldState, newState);
      },
      writable: true,
      configurable: true
    }
  }, {
    setState: {
      value: function setState(newState) {
        // Do a transactional state update if a function is passed
        if (typeof newState === "function") {
          var prevState = this._isHandlingDispatch ? this._pendingState : this.state;
 
          newState = newState(prevState);
        }
 
        if (this._isHandlingDispatch) {
          this._pendingState = this.constructor.assignState(this._pendingState, newState);
          this._emitChangeAfterHandlingDispatch = true;
        } else {
          Eif (process.env.NODE_ENV !== "production") {
            console.warn("Store#setState() called from outside an action handler. This is likely " + "a mistake. Flux stores should manage their own state.");
          }
          this.state = this.constructor.assignState(this.state, newState);
          this.emit("change");
        }
      },
      writable: true,
      configurable: true
    },
    replaceState: {
      value: function replaceState(newState) {
        if (this._isHandlingDispatch) {
          this._pendingState = this.constructor.assignState(undefined, newState);
          this._emitChangeAfterHandlingDispatch = true;
        } else {
          this.state = this.constructor.assignState(undefined, newState);
          this.emit("change");
        }
      },
      writable: true,
      configurable: true
    },
    forceUpdate: {
      value: function forceUpdate() {
        if (this._isHandlingDispatch) {
          this._emitChangeAfterHandlingDispatch = true;
        } else {
          this.emit("change");
        }
      },
      writable: true,
      configurable: true
    },
    register: {
      value: function register(actionId, handler) {
        actionId = ensureActionId(actionId);
 
        if (typeof handler !== "function") {
          return;
        }this._handlers[actionId] = handler.bind(this);
      },
      writable: true,
      configurable: true
    },
    registerAsync: {
      value: function registerAsync(actionId, beginHandler, successHandler, failureHandler) {
        actionId = ensureActionId(actionId);
 
        var asyncHandlers = {
          begin: beginHandler,
          success: successHandler,
          failure: failureHandler };
 
        for (var key in asyncHandlers) {
          Iif (!asyncHandlers.hasOwnProperty(key)) continue;
 
          var handler = asyncHandlers[key];
 
          if (typeof handler === "function") {
            asyncHandlers[key] = handler.bind(this);
          } else {
            delete asyncHandlers[key];
          }
        }
 
        this._asyncHandlers[actionId] = asyncHandlers;
      },
      writable: true,
      configurable: true
    },
    waitFor: {
      value: function waitFor(tokensOrStores) {
        this._waitFor(tokensOrStores);
      },
      writable: true,
      configurable: true
    },
    handler: {
      value: function handler(payload) {
        var body = payload.body;
        var actionId = payload.actionId;
        var _async = payload.async;
        var actionArgs = payload.actionArgs;
        var error = payload.error;
 
 
        var _handler = this._handlers[actionId];
        var _asyncHandler = this._asyncHandlers[actionId] && this._asyncHandlers[actionId][_async];
 
        if (_async) {
          switch (_async) {
            case "begin":
              if (typeof _asyncHandler === "function") {
                this._performHandler.apply(this, [_asyncHandler].concat(actionArgs));
              }
              return;
            case "failure":
              Eif (typeof _asyncHandler === "function") {
                this._performHandler(_asyncHandler, error);
              }
              return;
            case "success":
              if (typeof _asyncHandler === "function") {
                _handler = _asyncHandler;
              }
              break;
            default:
              return;
          }
        }
 
        Iif (typeof _handler !== "function") {
          return;
        }this._performHandler(_handler, body);
      },
      writable: true,
      configurable: true
    },
    _performHandler: {
      value: function _performHandler(_handler) {
        for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
          args[_key - 1] = arguments[_key];
        }
 
        this._isHandlingDispatch = true;
        this._pendingState = this.constructor.assignState(undefined, this.state);
        this._emitChangeAfterHandlingDispatch = false;
 
        try {
          _handler.apply(this, args);
        } finally {
          if (this._emitChangeAfterHandlingDispatch) {
            this.state = this._pendingState;
            this.emit("change");
          }
 
          this._isHandlingDispatch = false;
          this._pendingState = undefined;
          this._emitChangeAfterHandlingDispatch = false;
        }
      },
      writable: true,
      configurable: true
    }
  });
 
  return Store;
})(EventEmitter);
 
module.exports = Store;
 
 
function ensureActionId(actionOrActionId) {
  return typeof actionOrActionId === "function" ? actionOrActionId._id : actionOrActionId;
}
 
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInNyYy9TdG9yZS5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7O0lBU08sWUFBWSwyQkFBTSxlQUFlOztJQUNqQyxNQUFNLDJCQUFNLGVBQWU7O0lBRWIsS0FBSyxjQUFTLFlBQVk7Ozs7O0FBTWxDLFdBTlEsS0FBSzswQkFBTCxLQUFLOztBQU90QixRQUFJLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQzs7QUFFbEIsUUFBSSxDQUFDLFNBQVMsR0FBRyxFQUFFLENBQUM7QUFDcEIsUUFBSSxDQUFDLGNBQWMsR0FBRyxFQUFFLENBQUM7R0FDMUI7O1lBWGtCLEtBQUssRUFBUyxZQUFZOzt1QkFBMUIsS0FBSztBQWlEakIsZUFBVzthQUFBLHFCQUFDLFFBQVEsRUFBRSxRQUFRLEVBQUU7QUFDckMsZUFBTyxNQUFNLENBQUMsRUFBRSxFQUFFLFFBQVEsRUFBRSxRQUFRLENBQUMsQ0FBQztPQUN2Qzs7Ozs7QUF0Q0QsWUFBUTthQUFBLGtCQUFDLFFBQVEsRUFBRTs7QUFFakIsWUFBSSxPQUFPLFFBQVEsS0FBSyxVQUFVLEVBQUU7QUFDbEMsY0FBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLG1CQUFtQixHQUN0QyxJQUFJLENBQUMsYUFBYSxHQUNsQixJQUFJLENBQUMsS0FBSyxDQUFDOztBQUVmLGtCQUFRLEdBQUcsUUFBUSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1NBQ2hDOztBQUVELFlBQUksSUFBSSxDQUFDLG1CQUFtQixFQUFFO0FBQzVCLGNBQUksQ0FBQyxhQUFhLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLGFBQWEsRUFBRSxRQUFRLENBQUMsQ0FBQztBQUNoRixjQUFJLENBQUMsZ0NBQWdDLEdBQUcsSUFBSSxDQUFDO1NBQzlDLE1BQU07QUFFTCxjQUFJLE9BQU8sQ0FBQyxHQUFHLENBQUMsUUFBUSxLQUFLLFlBQVksRUFBRTtBQUN6QyxtQkFBTyxDQUFDLElBQUksQ0FDVix5RUFBeUUsR0FDekUsdURBQXVELENBQ3hELENBQUM7V0FDSDtBQUNELGNBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxRQUFRLENBQUMsQ0FBQztBQUNoRSxjQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1NBQ3JCO09BQ0Y7Ozs7QUFFRCxnQkFBWTthQUFBLHNCQUFDLFFBQVEsRUFBRTtBQUNyQixZQUFJLElBQUksQ0FBQyxtQkFBbUIsRUFBRTtBQUM1QixjQUFJLENBQUMsYUFBYSxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsV0FBVyxDQUFDLFNBQVMsRUFBRSxRQUFRLENBQUMsQ0FBQztBQUN2RSxjQUFJLENBQUMsZ0NBQWdDLEdBQUcsSUFBSSxDQUFDO1NBQzlDLE1BQU07QUFDTCxjQUFJLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsV0FBVyxDQUFDLFNBQVMsRUFBRSxRQUFRLENBQUMsQ0FBQztBQUMvRCxjQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1NBQ3JCO09BQ0Y7Ozs7QUFNRCxlQUFXO2FBQUEsdUJBQUc7QUFDWixZQUFJLElBQUksQ0FBQyxtQkFBbUIsRUFBRTtBQUM1QixjQUFJLENBQUMsZ0NBQWdDLEdBQUcsSUFBSSxDQUFDO1NBQzlDLE1BQU07QUFDTCxjQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1NBQ3JCO09BQ0Y7Ozs7QUFFRCxZQUFRO2FBQUEsa0JBQUMsUUFBUSxFQUFFLE9BQU8sRUFBRTtBQUMxQixnQkFBUSxHQUFHLGNBQWMsQ0FBQyxRQUFRLENBQUMsQ0FBQzs7QUFFcEMsWUFBSSxPQUFPLE9BQU8sS0FBSyxVQUFVO0FBQUUsaUJBQU87U0FBQSxBQUUxQyxJQUFJLENBQUMsU0FBUyxDQUFDLFFBQVEsQ0FBQyxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7T0FDL0M7Ozs7QUFFRCxpQkFBYTthQUFBLHVCQUFDLFFBQVEsRUFBRSxZQUFZLEVBQUUsY0FBYyxFQUFFLGNBQWMsRUFBRTtBQUNwRSxnQkFBUSxHQUFHLGNBQWMsQ0FBQyxRQUFRLENBQUMsQ0FBQzs7QUFFcEMsWUFBSSxhQUFhLEdBQUc7QUFDbEIsZUFBSyxFQUFFLFlBQVk7QUFDbkIsaUJBQU8sRUFBRSxjQUFjO0FBQ3ZCLGlCQUFPLEVBQUUsY0FBYyxFQUN4QixDQUFDOztBQUVGLGFBQUssSUFBSSxHQUFHLElBQUksYUFBYSxFQUFFO0FBQzdCLGNBQUksQ0FBQyxhQUFhLENBQUMsY0FBYyxDQUFDLEdBQUcsQ0FBQyxFQUFFLFNBQVM7O0FBRWpELGNBQUksT0FBTyxHQUFHLGFBQWEsQ0FBQyxHQUFHLENBQUMsQ0FBQzs7QUFFakMsY0FBSSxPQUFPLE9BQU8sS0FBSyxVQUFVLEVBQUU7QUFDakMseUJBQWEsQ0FBQyxHQUFHLENBQUMsR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO1dBQ3pDLE1BQU07QUFDTCxtQkFBTyxhQUFhLENBQUMsR0FBRyxDQUFDLENBQUM7V0FDM0I7U0FDRjs7QUFFRCxZQUFJLENBQUMsY0FBYyxDQUFDLFFBQVEsQ0FBQyxHQUFHLGFBQWEsQ0FBQztPQUMvQzs7OztBQUVELFdBQU87YUFBQSxpQkFBQyxjQUFjLEVBQUU7QUFDdEIsWUFBSSxDQUFDLFFBQVEsQ0FBQyxjQUFjLENBQUMsQ0FBQztPQUMvQjs7OztBQUVELFdBQU87YUFBQSxpQkFBQyxPQUFPLEVBQUU7WUFFYixJQUFJLEdBS0YsT0FBTyxDQUxULElBQUk7WUFDSixRQUFRLEdBSU4sT0FBTyxDQUpULFFBQVE7WUFDRCxNQUFNLEdBR1gsT0FBTyxDQUhULEtBQUs7WUFDTCxVQUFVLEdBRVIsT0FBTyxDQUZULFVBQVU7WUFDVixLQUFLLEdBQ0gsT0FBTyxDQURULEtBQUs7OztBQUdQLFlBQUksUUFBUSxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsUUFBUSxDQUFDLENBQUM7QUFDeEMsWUFBSSxhQUFhLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQyxRQUFRLENBQUMsSUFDNUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxRQUFRLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQzs7QUFFM0MsWUFBSSxNQUFNLEVBQUU7QUFDVixrQkFBUSxNQUFNO0FBQ1osaUJBQUssT0FBTztBQUNWLGtCQUFJLE9BQU8sYUFBYSxLQUFLLFVBQVUsRUFBRTtBQUN2QyxvQkFBSSxDQUFDLGVBQWUsQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLENBQUMsYUFBYSxDQUFDLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUM7ZUFDdEU7QUFDRCxxQkFBTztBQUFBLEFBQ1QsaUJBQUssU0FBUztBQUNaLGtCQUFJLE9BQU8sYUFBYSxLQUFLLFVBQVUsRUFBRTtBQUN2QyxvQkFBSSxDQUFDLGVBQWUsQ0FBQyxhQUFhLEVBQUUsS0FBSyxDQUFDLENBQUM7ZUFDNUM7QUFDRCxxQkFBTztBQUFBLEFBQ1QsaUJBQUssU0FBUztBQUNaLGtCQUFJLE9BQU8sYUFBYSxLQUFLLFVBQVUsRUFBRTtBQUN2Qyx3QkFBUSxHQUFHLGFBQWEsQ0FBQztlQUMxQjtBQUNELG9CQUFNO0FBQUEsQUFDUjtBQUNFLHFCQUFPO0FBQUEsV0FDVjtTQUNGOztBQUVELFlBQUksT0FBTyxRQUFRLEtBQUssVUFBVTtBQUFFLGlCQUFPO1NBQUEsQUFDM0MsSUFBSSxDQUFDLGVBQWUsQ0FBQyxRQUFRLEVBQUUsSUFBSSxDQUFDLENBQUM7T0FDdEM7Ozs7QUFFRCxtQkFBZTthQUFBLHlCQUFDLFFBQVEsRUFBVzswQ0FBTixJQUFJO0FBQUosY0FBSTs7O0FBQy9CLFlBQUksQ0FBQyxtQkFBbUIsR0FBRyxJQUFJLENBQUM7QUFDaEMsWUFBSSxDQUFDLGFBQWEsR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLFdBQVcsQ0FBQyxTQUFTLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO0FBQ3pFLFlBQUksQ0FBQyxnQ0FBZ0MsR0FBRyxLQUFLLENBQUM7O0FBRTlDLFlBQUk7QUFDRixrQkFBUSxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUM7U0FDNUIsU0FBUztBQUNSLGNBQUksSUFBSSxDQUFDLGdDQUFnQyxFQUFFO0FBQ3pDLGdCQUFJLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUM7QUFDaEMsZ0JBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7V0FDckI7O0FBRUQsY0FBSSxDQUFDLG1CQUFtQixHQUFHLEtBQUssQ0FBQztBQUNqQyxjQUFJLENBQUMsYUFBYSxHQUFHLFNBQVMsQ0FBQztBQUMvQixjQUFJLENBQUMsZ0NBQWdDLEdBQUcsS0FBSyxDQUFDO1NBQy9DO09BQ0Y7Ozs7OztTQXpKa0IsS0FBSztHQUFTLFlBQVk7O2lCQUExQixLQUFLOzs7QUE0SjFCLFNBQVMsY0FBYyxDQUFDLGdCQUFnQixFQUFFO0FBQ3hDLFNBQU8sT0FBTyxnQkFBZ0IsS0FBSyxVQUFVLEdBQ3pDLGdCQUFnQixDQUFDLEdBQUcsR0FDcEIsZ0JBQWdCLENBQUM7Q0FDdEIiLCJmaWxlIjoibGliL1N0b3JlLmpzIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBTdG9yZVxuICpcbiAqIFN0b3JlcyBob2xkIGFwcGxpY2F0aW9uIHN0YXRlLiBUaGV5IHJlc3BvbmQgdG8gYWN0aW9ucyBzZW50IGJ5IHRoZSBkaXNwYXRjaGVyXG4gKiBhbmQgYnJvYWRjYXN0IGNoYW5nZSBldmVudHMgdG8gbGlzdGVuZXJzLCBzbyB0aGV5IGNhbiBncmFiIHRoZSBsYXRlc3QgZGF0YS5cbiAqIFRoZSBrZXkgdGhpbmcgdG8gcmVtZW1iZXIgaXMgdGhhdCB0aGUgb25seSB3YXkgc3RvcmVzIHJlY2VpdmUgaW5mb3JtYXRpb25cbiAqIGZyb20gdGhlIG91dHNpZGUgd29ybGQgaXMgdmlhIHRoZSBkaXNwYXRjaGVyLlxuICovXG5cbmltcG9ydCBFdmVudEVtaXR0ZXIgZnJvbSAnZXZlbnRlbWl0dGVyMyc7XG5pbXBvcnQgYXNzaWduIGZyb20gJ29iamVjdC1hc3NpZ24nO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBTdG9yZSBleHRlbmRzIEV2ZW50RW1pdHRlciB7XG5cbiAgLyoqXG4gICAqIFN0b3JlcyBhcmUgaW5pdGlhbGl6ZWQgd2l0aCBhIHJlZmVyZW5jZVxuICAgKiBAdHlwZSB7T2JqZWN0fVxuICAgKi9cbiAgY29uc3RydWN0b3IoKSB7XG4gICAgdGhpcy5zdGF0ZSA9IG51bGw7XG5cbiAgICB0aGlzLl9oYW5kbGVycyA9IHt9O1xuICAgIHRoaXMuX2FzeW5jSGFuZGxlcnMgPSB7fTtcbiAgfVxuXG4gIHNldFN0YXRlKG5ld1N0YXRlKSB7XG4gICAgLy8gRG8gYSB0cmFuc2FjdGlvbmFsIHN0YXRlIHVwZGF0ZSBpZiBhIGZ1bmN0aW9uIGlzIHBhc3NlZFxuICAgIGlmICh0eXBlb2YgbmV3U3RhdGUgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIGNvbnN0IHByZXZTdGF0ZSA9IHRoaXMuX2lzSGFuZGxpbmdEaXNwYXRjaFxuICAgICAgICA/IHRoaXMuX3BlbmRpbmdTdGF0ZVxuICAgICAgICA6IHRoaXMuc3RhdGU7XG5cbiAgICAgIG5ld1N0YXRlID0gbmV3U3RhdGUocHJldlN0YXRlKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5faXNIYW5kbGluZ0Rpc3BhdGNoKSB7XG4gICAgICB0aGlzLl9wZW5kaW5nU3RhdGUgPSB0aGlzLmNvbnN0cnVjdG9yLmFzc2lnblN0YXRlKHRoaXMuX3BlbmRpbmdTdGF0ZSwgbmV3U3RhdGUpO1xuICAgICAgdGhpcy5fZW1pdENoYW5nZUFmdGVySGFuZGxpbmdEaXNwYXRjaCA9IHRydWU7XG4gICAgfSBlbHNlIHtcblxuICAgICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpIHtcbiAgICAgICAgY29uc29sZS53YXJuKFxuICAgICAgICAgICdTdG9yZSNzZXRTdGF0ZSgpIGNhbGxlZCBmcm9tIG91dHNpZGUgYW4gYWN0aW9uIGhhbmRsZXIuIFRoaXMgaXMgbGlrZWx5ICdcbiAgICAgICAgKyAnYSBtaXN0YWtlLiBGbHV4IHN0b3JlcyBzaG91bGQgbWFuYWdlIHRoZWlyIG93biBzdGF0ZS4nXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICB0aGlzLnN0YXRlID0gdGhpcy5jb25zdHJ1Y3Rvci5hc3NpZ25TdGF0ZSh0aGlzLnN0YXRlLCBuZXdTdGF0ZSk7XG4gICAgICB0aGlzLmVtaXQoJ2NoYW5nZScpO1xuICAgIH1cbiAgfVxuXG4gIHJlcGxhY2VTdGF0ZShuZXdTdGF0ZSkge1xuICAgIGlmICh0aGlzLl9pc0hhbmRsaW5nRGlzcGF0Y2gpIHtcbiAgICAgIHRoaXMuX3BlbmRpbmdTdGF0ZSA9IHRoaXMuY29uc3RydWN0b3IuYXNzaWduU3RhdGUodW5kZWZpbmVkLCBuZXdTdGF0ZSk7XG4gICAgICB0aGlzLl9lbWl0Q2hhbmdlQWZ0ZXJIYW5kbGluZ0Rpc3BhdGNoID0gdHJ1ZTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5zdGF0ZSA9IHRoaXMuY29uc3RydWN0b3IuYXNzaWduU3RhdGUodW5kZWZpbmVkLCBuZXdTdGF0ZSk7XG4gICAgICB0aGlzLmVtaXQoJ2NoYW5nZScpO1xuICAgIH1cbiAgfVxuXG4gIHN0YXRpYyBhc3NpZ25TdGF0ZShvbGRTdGF0ZSwgbmV3U3RhdGUpIHtcbiAgICByZXR1cm4gYXNzaWduKHt9LCBvbGRTdGF0ZSwgbmV3U3RhdGUpO1xuICB9XG5cbiAgZm9yY2VVcGRhdGUoKSB7XG4gICAgaWYgKHRoaXMuX2lzSGFuZGxpbmdEaXNwYXRjaCkge1xuICAgICAgdGhpcy5fZW1pdENoYW5nZUFmdGVySGFuZGxpbmdEaXNwYXRjaCA9IHRydWU7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuZW1pdCgnY2hhbmdlJyk7XG4gICAgfVxuICB9XG5cbiAgcmVnaXN0ZXIoYWN0aW9uSWQsIGhhbmRsZXIpIHtcbiAgICBhY3Rpb25JZCA9IGVuc3VyZUFjdGlvbklkKGFjdGlvbklkKTtcblxuICAgIGlmICh0eXBlb2YgaGFuZGxlciAhPT0gJ2Z1bmN0aW9uJykgcmV0dXJuO1xuXG4gICAgdGhpcy5faGFuZGxlcnNbYWN0aW9uSWRdID0gaGFuZGxlci5iaW5kKHRoaXMpO1xuICB9XG5cbiAgcmVnaXN0ZXJBc3luYyhhY3Rpb25JZCwgYmVnaW5IYW5kbGVyLCBzdWNjZXNzSGFuZGxlciwgZmFpbHVyZUhhbmRsZXIpIHtcbiAgICBhY3Rpb25JZCA9IGVuc3VyZUFjdGlvbklkKGFjdGlvbklkKTtcblxuICAgIGxldCBhc3luY0hhbmRsZXJzID0ge1xuICAgICAgYmVnaW46IGJlZ2luSGFuZGxlcixcbiAgICAgIHN1Y2Nlc3M6IHN1Y2Nlc3NIYW5kbGVyLFxuICAgICAgZmFpbHVyZTogZmFpbHVyZUhhbmRsZXIsXG4gICAgfTtcblxuICAgIGZvciAobGV0IGtleSBpbiBhc3luY0hhbmRsZXJzKSB7XG4gICAgICBpZiAoIWFzeW5jSGFuZGxlcnMuaGFzT3duUHJvcGVydHkoa2V5KSkgY29udGludWU7XG5cbiAgICAgIGxldCBoYW5kbGVyID0gYXN5bmNIYW5kbGVyc1trZXldO1xuXG4gICAgICBpZiAodHlwZW9mIGhhbmRsZXIgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgYXN5bmNIYW5kbGVyc1trZXldID0gaGFuZGxlci5iaW5kKHRoaXMpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZGVsZXRlIGFzeW5jSGFuZGxlcnNba2V5XTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aGlzLl9hc3luY0hhbmRsZXJzW2FjdGlvbklkXSA9IGFzeW5jSGFuZGxlcnM7XG4gIH1cblxuICB3YWl0Rm9yKHRva2Vuc09yU3RvcmVzKSB7XG4gICAgdGhpcy5fd2FpdEZvcih0b2tlbnNPclN0b3Jlcyk7XG4gIH1cblxuICBoYW5kbGVyKHBheWxvYWQpIHtcbiAgICBsZXQge1xuICAgICAgYm9keSxcbiAgICAgIGFjdGlvbklkLFxuICAgICAgYXN5bmM6IF9hc3luYyxcbiAgICAgIGFjdGlvbkFyZ3MsXG4gICAgICBlcnJvclxuICAgIH0gPSBwYXlsb2FkO1xuXG4gICAgbGV0IF9oYW5kbGVyID0gdGhpcy5faGFuZGxlcnNbYWN0aW9uSWRdO1xuICAgIGxldCBfYXN5bmNIYW5kbGVyID0gdGhpcy5fYXN5bmNIYW5kbGVyc1thY3Rpb25JZF1cbiAgICAgICYmIHRoaXMuX2FzeW5jSGFuZGxlcnNbYWN0aW9uSWRdW19hc3luY107XG5cbiAgICBpZiAoX2FzeW5jKSB7XG4gICAgICBzd2l0Y2ggKF9hc3luYykge1xuICAgICAgICBjYXNlICdiZWdpbic6XG4gICAgICAgICAgaWYgKHR5cGVvZiBfYXN5bmNIYW5kbGVyID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICB0aGlzLl9wZXJmb3JtSGFuZGxlci5hcHBseSh0aGlzLCBbX2FzeW5jSGFuZGxlcl0uY29uY2F0KGFjdGlvbkFyZ3MpKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICBjYXNlICdmYWlsdXJlJzpcbiAgICAgICAgICBpZiAodHlwZW9mIF9hc3luY0hhbmRsZXIgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIHRoaXMuX3BlcmZvcm1IYW5kbGVyKF9hc3luY0hhbmRsZXIsIGVycm9yKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICBjYXNlICdzdWNjZXNzJzpcbiAgICAgICAgICBpZiAodHlwZW9mIF9hc3luY0hhbmRsZXIgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIF9oYW5kbGVyID0gX2FzeW5jSGFuZGxlcjtcbiAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICh0eXBlb2YgX2hhbmRsZXIgIT09ICdmdW5jdGlvbicpIHJldHVybjtcbiAgICB0aGlzLl9wZXJmb3JtSGFuZGxlcihfaGFuZGxlciwgYm9keSk7XG4gIH1cblxuICBfcGVyZm9ybUhhbmRsZXIoX2hhbmRsZXIsIC4uLmFyZ3MpIHtcbiAgICB0aGlzLl9pc0hhbmRsaW5nRGlzcGF0Y2ggPSB0cnVlO1xuICAgIHRoaXMuX3BlbmRpbmdTdGF0ZSA9IHRoaXMuY29uc3RydWN0b3IuYXNzaWduU3RhdGUodW5kZWZpbmVkLCB0aGlzLnN0YXRlKTtcbiAgICB0aGlzLl9lbWl0Q2hhbmdlQWZ0ZXJIYW5kbGluZ0Rpc3BhdGNoID0gZmFsc2U7XG5cbiAgICB0cnkge1xuICAgICAgX2hhbmRsZXIuYXBwbHkodGhpcywgYXJncyk7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIGlmICh0aGlzLl9lbWl0Q2hhbmdlQWZ0ZXJIYW5kbGluZ0Rpc3BhdGNoKSB7XG4gICAgICAgIHRoaXMuc3RhdGUgPSB0aGlzLl9wZW5kaW5nU3RhdGU7XG4gICAgICAgIHRoaXMuZW1pdCgnY2hhbmdlJyk7XG4gICAgICB9XG5cbiAgICAgIHRoaXMuX2lzSGFuZGxpbmdEaXNwYXRjaCA9IGZhbHNlO1xuICAgICAgdGhpcy5fcGVuZGluZ1N0YXRlID0gdW5kZWZpbmVkO1xuICAgICAgdGhpcy5fZW1pdENoYW5nZUFmdGVySGFuZGxpbmdEaXNwYXRjaCA9IGZhbHNlO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBlbnN1cmVBY3Rpb25JZChhY3Rpb25PckFjdGlvbklkKSB7XG4gIHJldHVybiB0eXBlb2YgYWN0aW9uT3JBY3Rpb25JZCA9PT0gJ2Z1bmN0aW9uJ1xuICAgID8gYWN0aW9uT3JBY3Rpb25JZC5faWRcbiAgICA6IGFjdGlvbk9yQWN0aW9uSWQ7XG59XG4iXX0=