text: "use strict";
  var __values = (this && this.__values) || function (o) {
      var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0;
      if (m) return m.call(o);
      return {
          next: function () {
              if (o && i >= o.length) o = void 0;
              return { value: o && o[i++], done: !o };
          }
      };
  };
  var __read = (this && this.__read) || function (o, n) {
      var m = typeof Symbol === "function" && o[Symbol.iterator];
      if (!m) return o;
      var i = m.call(o), r, ar = [], e;
      try {
          while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
      }
      catch (error) { e = { error: error }; }
      finally {
          try {
              if (r && !r.done && (m = i["return"])) m.call(i);
          }
          finally { if (e) throw e.error; }
      }
      return ar;
  };
  var __spread = (this && this.__spread) || function () {
      for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read(arguments[i]));
      return ar;
  };
  Object.defineProperty(exports, "__esModule", { value: true });
  var types_1 = require("./types");
  var constants_1 = require("./constants");
  function isState(state) {
      if (typeof state === 'string') {
          return false;
      }
      return 'value' in state && 'tree' in state && 'history' in state;
  }
  function keys(value) {
      return Object.keys(value);
  }
  exports.keys = keys;
  function matchesState(parentStateId, childStateId, delimiter) {
      if (delimiter === void 0) { delimiter = constants_1.STATE_DELIMITER; }
      var parentStateValue = toStateValue(parentStateId, delimiter);
      var childStateValue = toStateValue(childStateId, delimiter);
      if (typeof childStateValue === 'string') {
          if (typeof parentStateValue === 'string') {
              return childStateValue === parentStateValue;
          }
          // Parent more specific than child
          return false;
      }
      if (typeof parentStateValue === 'string') {
          return parentStateValue in childStateValue;
      }
      return keys(parentStateValue).every(function (key) {
          if (!(key in childStateValue)) {
              return false;
          }
          return matchesState(parentStateValue[key], childStateValue[key]);
      });
  }
  exports.matchesState = matchesState;
  function getEventType(event) {
      try {
          return typeof event === 'string' || typeof event === 'number'
              ? "" + event
              : event.type;
      }
      catch (e) {
          throw new Error('Events must be strings or objects with a string event.type property.');
      }
  }
  exports.getEventType = getEventType;
  function getActionType(action) {
      try {
          return typeof action === 'string' || typeof action === 'number'
              ? "" + action
              : typeof action === 'function'
                  ? action.name
                  : action.type;
      }
      catch (e) {
          throw new Error('Actions must be strings or objects with a string action.type property.');
      }
  }
  exports.getActionType = getActionType;
  function toStatePath(stateId, delimiter) {
      try {
          if (Array.isArray(stateId)) {
              return stateId;
          }
          return stateId.toString().split(delimiter);
      }
      catch (e) {
          throw new Error("'" + stateId + "' is not a valid state path.");
      }
  }
  exports.toStatePath = toStatePath;
  function toStateValue(stateValue, delimiter) {
      if (isState(stateValue)) {
          return stateValue.value;
      }
      if (Array.isArray(stateValue)) {
          return pathToStateValue(stateValue);
      }
      if (typeof stateValue !== 'string' && !isState(stateValue)) {
          return stateValue;
      }
      var statePath = toStatePath(stateValue, delimiter);
      return pathToStateValue(statePath);
  }
  exports.toStateValue = toStateValue;
  function pathToStateValue(statePath) {
      if (statePath.length === 1) {
          return statePath[0];
      }
      var value = {};
      var marker = value;
      for (var i = 0; i < statePath.length - 1; i++) {
          if (i === statePath.length - 2) {
              marker[statePath[i]] = statePath[i + 1];
          }
          else {
              marker[statePath[i]] = {};
              marker = marker[statePath[i]];
          }
      }
      return value;
  }
  exports.pathToStateValue = pathToStateValue;
  function mapValues(collection, iteratee) {
      var result = {};
      keys(collection).forEach(function (key, i) {
          result[key] = iteratee(collection[key], key, collection, i);
      });
      return result;
  }
  exports.mapValues = mapValues;
  function mapFilterValues(collection, iteratee, predicate) {
      var result = {};
      keys(collection).forEach(function (key) {
          var item = collection[key];
          if (!predicate(item)) {
              return;
          }
          result[key] = iteratee(item, key, collection);
      });
      return result;
  }
  exports.mapFilterValues = mapFilterValues;
  /**
   * Retrieves a value at the given path.
   * @param props The deep path to the prop of the desired value
   */
  exports.path = function (props) { return function (object) {
      var e_1, _a;
      var result = object;
      try {
          for (var props_1 = __values(props), props_1_1 = props_1.next(); !props_1_1.done; props_1_1 = props_1.next()) {
              var prop = props_1_1.value;
              result = result[prop];
          }
      }
      catch (e_1_1) { e_1 = { error: e_1_1 }; }
      finally {
          try {
              if (props_1_1 && !props_1_1.done && (_a = props_1.return)) _a.call(props_1);
          }
          finally { if (e_1) throw e_1.error; }
      }
      return result;
  }; };
  /**
   * Retrieves a value at the given path via the nested accessor prop.
   * @param props The deep path to the prop of the desired value
   */
  function nestedPath(props, accessorProp) {
      return function (object) {
          var e_2, _a;
          var result = object;
          try {
              for (var props_2 = __values(props), props_2_1 = props_2.next(); !props_2_1.done; props_2_1 = props_2.next()) {
                  var prop = props_2_1.value;
                  result = result[accessorProp][prop];
              }
          }
          catch (e_2_1) { e_2 = { error: e_2_1 }; }
          finally {
              try {
                  if (props_2_1 && !props_2_1.done && (_a = props_2.return)) _a.call(props_2);
              }
              finally { if (e_2) throw e_2.error; }
          }
          return result;
      };
  }
  exports.nestedPath = nestedPath;
  exports.toStatePaths = function (stateValue) {
      if (!stateValue) {
          return [[]];
      }
      if (typeof stateValue === 'string') {
          return [[stateValue]];
      }
      var result = flatten(keys(stateValue).map(function (key) {
          var subStateValue = stateValue[key];
          if (typeof subStateValue !== 'string' &&
              !Object.keys(subStateValue).length) {
              return [[key]];
          }
          return exports.toStatePaths(stateValue[key]).map(function (subPath) {
              return [key].concat(subPath);
          });
      }));
      return result;
  };
  exports.pathsToStateValue = function (paths) {
      var e_3, _a;
      var result = {};
      if (paths && paths.length === 1 && paths[0].length === 1) {
          return paths[0][0];
      }
      try {
          for (var paths_1 = __values(paths), paths_1_1 = paths_1.next(); !paths_1_1.done; paths_1_1 = paths_1.next()) {
              var currentPath = paths_1_1.value;
              var marker = result;
              // tslint:disable-next-line:prefer-for-of
              for (var i = 0; i < currentPath.length; i++) {
                  var subPath = currentPath[i];
                  if (i === currentPath.length - 2) {
                      marker[subPath] = currentPath[i + 1];
                      break;
                  }
                  marker[subPath] = marker[subPath] || {};
                  marker = marker[subPath];
              }
          }
      }
      catch (e_3_1) { e_3 = { error: e_3_1 }; }
      finally {
          try {
              if (paths_1_1 && !paths_1_1.done && (_a = paths_1.return)) _a.call(paths_1);
          }
          finally { if (e_3) throw e_3.error; }
      }
      return result;
  };
  function flatten(array) {
      var _a;
      return (_a = []).concat.apply(_a, __spread(array));
  }
  exports.flatten = flatten;
  function toArray(value) {
      if (Array.isArray(value)) {
          return value;
      }
      if (value === undefined) {
          return [];
      }
      return [value];
  }
  exports.toArray = toArray;
  function mapContext(mapper, context, event) {
      var e_4, _a;
      if (typeof mapper === 'function') {
          return mapper(context, event);
      }
      var result = {};
      try {
          for (var _b = __values(keys(mapper)), _c = _b.next(); !_c.done; _c = _b.next()) {
              var key = _c.value;
              var subMapper = mapper[key];
              if (typeof subMapper === 'function') {
                  result[key] = subMapper(context, event);
              }
              else {
                  result[key] = subMapper;
              }
          }
      }
      catch (e_4_1) { e_4 = { error: e_4_1 }; }
      finally {
          try {
              if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
          }
          finally { if (e_4) throw e_4.error; }
      }
      return result;
  }
  exports.mapContext = mapContext;
  function isBuiltInEvent(eventType) {
      // check if event is a "done" event
      if (eventType.indexOf(types_1.ActionTypes.DoneState) === 0 ||
          eventType.indexOf(types_1.ActionTypes.DoneInvoke) === 0) {
          return true;
      }
      // check if event is an "error" event
      if (eventType === types_1.ActionTypes.ErrorCommunication ||
          eventType === types_1.ActionTypes.ErrorCommunication) {
          return true;
      }
      return false;
  }
  exports.isBuiltInEvent = isBuiltInEvent;
  function partition(items, predicate) {
      var e_5, _a;
      var _b = __read([[], []], 2), truthy = _b[0], falsy = _b[1];
      try {
          for (var items_1 = __values(items), items_1_1 = items_1.next(); !items_1_1.done; items_1_1 = items_1.next()) {
              var item = items_1_1.value;
              if (predicate(item)) {
                  truthy.push(item);
              }
              else {
                  falsy.push(item);
              }
          }
      }
      catch (e_5_1) { e_5 = { error: e_5_1 }; }
      finally {
          try {
              if (items_1_1 && !items_1_1.done && (_a = items_1.return)) _a.call(items_1);
          }
          finally { if (e_5) throw e_5.error; }
      }
      return [truthy, falsy];
  }
  exports.partition = partition;
  function updateHistoryStates(hist, stateValue) {
      return mapValues(hist.states, function (subHist, key) {
          if (!subHist) {
              return undefined;
          }
          var subStateValue = (typeof stateValue === 'string' ? undefined : stateValue[key]) ||
              (subHist ? subHist.current : undefined);
          if (!subStateValue) {
              return undefined;
          }
          return {
              current: subStateValue,
              states: updateHistoryStates(subHist, subStateValue)
          };
      });
  }
  exports.updateHistoryStates = updateHistoryStates;
  function updateHistoryValue(hist, stateValue) {
      return {
          current: stateValue,
          states: updateHistoryStates(hist, stateValue)
      };
  }
  exports.updateHistoryValue = updateHistoryValue;
  function updateContext(context, event, assignActions) {
      var updatedContext = context
          ? assignActions.reduce(function (acc, assignAction) {
              var assignment = assignAction.assignment;
              var partialUpdate = {};
              if (typeof assignment === 'function') {
                  partialUpdate = assignment(acc, event || { type: types_1.ActionTypes.Init });
              }
              else {
                  keys(assignment).forEach(function (key) {
                      var propAssignment = assignment[key];
                      partialUpdate[key] =
                          typeof propAssignment === 'function'
                              ? propAssignment(acc, event)
                              : propAssignment;
                  });
              }
              return Object.assign({}, acc, partialUpdate);
          }, context)
          : context;
      return updatedContext;
  }
  exports.updateContext = updateContext;
  