// The PayPal SDK is released under the following license:
// 
//     Copyright (c) <2018> PAYPAL, INC.
// 
//     SDK LICENSE
// 
//     NOTICE TO USER:  PayPal, Inc. is providing the Software and Documentation for use under the terms of 
//     this Agreement. Any use, reproduction, modification or distribution of the Software or Documentation, 
//     or any derivatives or portions hereof, constitutes your acceptance of this Agreement.
// 
//     As used in this Agreement, "PayPal" means PayPal, Inc.  "Software" means the software code accompanying
//     this agreement. "Documentation" means the documents, specifications and all other items accompanying 
//     this Agreement other than the Software.   
// 
//     1.  LICENSE GRANT Subject to the terms of this Agreement, PayPal hereby grants you a non-exclusive, 
//     worldwide, royalty free license to use, reproduce, prepare derivative works from, publicly display, 
//     publicly perform, distribute and sublicense the Software for any purpose, provided the copyright notice
//     below appears in a conspicuous location within the source code of the distributed Software and this 
//     license is distributed in the supporting documentation of the Software you distribute. Furthermore, 
//     you must comply with all third party licenses in order to use the third party software contained in the 
//     Software.
// 
//     Subject to the terms of this Agreement, PayPal hereby grants you a non-exclusive, worldwide, royalty free
//     license to use, reproduce, publicly display, publicly perform, distribute and sublicense the Documentation 
//     for any purpose.  You may not modify the Documentation.
// 
//     No title to the intellectual property in the Software or Documentation is transferred to you under the 
//     terms of this Agreement. You do not acquire any rights to the Software or the Documentation except as 
//     expressly set forth in this Agreement.
// 
//     If you choose to distribute the Software in a commercial product, you do so with the understanding that 
//     you agree to defend, indemnify and hold harmless PayPal and its suppliers against any losses, damages and 
//     costs arising from the claims, lawsuits or other legal actions arising out of such distribution.  You may 
//     distribute the Software in object code form under your own license, provided that your license agreement:
// 
//     (a)     complies with the terms and conditions of this license agreement; 
// 
//     (b)     effectively disclaims all warranties and conditions, express or implied, on behalf of PayPal;
// 
//     (c)     effectively excludes all liability for damages on behalf of PayPal;
// 
//     (d)     states that any provisions that differ from this Agreement are offered by you alone and not PayPal; and
// 
//     (e)     states that the Software is available from you or PayPal and informs licensees how to obtain it in a 
//     reasonable manner on or through a medium customarily used for software exchange.  
// 
//     2.  DISCLAIMER OF WARRANTY
//     PAYPAL LICENSES THE SOFTWARE AND DOCUMENTATION TO YOU ONLY ON AN "AS IS" BASIS WITHOUT WARRANTIES OR CONDITIONS 
//     OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY WARRANTIES OR CONDITIONS OF TITLE, 
//     NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  PAYPAL MAKES NO WARRANTY THAT THE 
//     SOFTWARE OR DOCUMENTATION WILL BE ERROR-FREE. Each user of the Software or Documentation is solely responsible 
//     for determining the appropriateness of using and distributing the Software and Documentation and assumes all 
//     risks associated with its exercise of rights under this Agreement, including but not limited to the risks and 
//     costs of program errors, compliance with applicable laws, damage to or loss of data, programs, or equipment, 
//     and unavailability or interruption of operations.  Use of the Software and Documentation is made with the 
//     understanding that PayPal will not provide you with any technical or customer support or maintenance.  Some 
//     states or jurisdictions do not allow the exclusion of implied warranties or limitations on how long an implied 
//     warranty may last, so the above limitations may not apply to you.  To the extent permissible, any implied 
//     warranties are limited to ninety (90) days.
// 
// 
//     3.  LIMITATION OF LIABILITY
//     PAYPAL AND ITS SUPPLIERS SHALL NOT BE LIABLE FOR LOSS OR DAMAGE ARISING OUT OF THIS AGREEMENT OR FROM THE USE 
//     OF THE SOFTWARE OR DOCUMENTATION.  IN NO EVENT WILL PAYPAL OR ITS SUPPLIERS BE LIABLE TO YOU OR ANY THIRD PARTY 
//     FOR ANY DIRECT, INDIRECT, CONSEQUENTIAL, INCIDENTAL, OR SPECIAL DAMAGES INCLUDING LOST PROFITS, LOST SAVINGS, 
//     COSTS, FEES, OR EXPENSES OF ANY KIND ARISING OUT OF ANY PROVISION OF THIS AGREEMENT OR THE USE OR THE INABILITY 
//     TO USE THE SOFTWARE OR DOCUMENTATION, HOWEVER CAUSED AND UNDER ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
//     STRICT LIABILITY OR TORT INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 
//     PAYPAL'S AGGREGATE LIABILITY AND THAT OF ITS SUPPLIERS UNDER OR IN CONNECTION WITH THIS AGREEMENT SHALL BE 
//     LIMITED TO THE AMOUNT PAID BY YOU FOR THE SOFTWARE AND DOCUMENTATION. 
// 
//     4.  TRADEMARK USAGE
//     PayPal is a trademark of PayPal, Inc. in the United States and other countries.  Such trademarks may not be used 
//     to endorse or promote any product unless expressly permitted under separate agreement with PayPal.  
// 
// 	5.	CERTIFICATIONS
// 	Please note that if you modify the source code and redistribute these modifications for commercial purposes, you agree and understand you may need to certify or comply with any relevant certification or compliance entities to process payments. 
// 
// 	6.  TERM
//     Your rights under this Agreement shall terminate if you fail to comply with any of the material terms or 
//     conditions of this Agreement and do not cure such failure in a reasonable period of time after becoming 
//     aware of such noncompliance.  If all your rights under this Agreement terminate, you agree to cease use 
//     and distribution of the Software and Documentation as soon as reasonably practicable. 
// 
//     7. GOVERNING LAW AND JURISDICTION. This Agreement is governed by the statutes and laws of the State of 
//     California, without regard to the conflicts of law principles thereof.  If any part of this Agreement is 
//     found void and unenforceable, it will not affect the validity of the balance of the Agreement, which shall 
//     remain valid and enforceable according to its terms.  Any dispute arising out of or related to this Agreement 
//     shall be brought in the courts of Santa Clara County, California, USA.
// 
(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({"/Users/aravidas/Documents/Git/retail-sdk/js/common/CachedServerFile.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

var _manticore = require('manticore');

var _manticore2 = _interopRequireDefault(_manticore);

var _manticoreLog = require('manticore-log');

var _manticoreLog2 = _interopRequireDefault(_manticoreLog);

var _retailSDKUtil = require('../common/retailSDKUtil');

var retailSDKUtil = _interopRequireWildcard(_retailSDKUtil);

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

var Log = (0, _manticoreLog2.default)('cachedServerFile');

/**
 * The ServerBackedFile class is responsible to retrieve and cache a server backed file
 */

var CachedServerFile = function () {

  /**
   * @param fileId    - Unique Id to the file
   * @param remoteUrl - Server URL for the file
   */
  function CachedServerFile(fileId, remoteUrl) {
    _classCallCheck(this, CachedServerFile);

    this.url = remoteUrl;
    this.fileId = fileId;
    this.storageType = retailSDKUtil.StorageType.Secure;
  }

  /**
   * Looks for a JSON file from local cache store, server and returns the most recent version
   * @param callback  -   Callback will be invoked with the error (if any) and http response as first and second parameters
   */


  CachedServerFile.prototype.get = function get(callback) {
    var _this = this;

    this._retrieveCachedFile(function (e, cachedJson) {
      var request = { url: _this.url, format: 'json', headers: {} };
      if (cachedJson && cachedJson.headers) {
        var lm = cachedJson.headers['Last-Modified'];
        var eTag = cachedJson.headers.ETag;

        if (lm) {
          request.headers['If-Modified-Since'] = lm;
        }

        if (eTag) {
          request.headers['If-None-Match'] = eTag;
        }
      }

      Log.debug(function () {
        return 'GET File ' + _this.fileId + '\nRequest: ' + JSON.stringify(request);
      });
      _manticore2.default.http(request, function (err, response) {
        if (err || response && response.statusCode >= 300) {
          Log[response && response.statusCode === 304 ? 'debug' : 'error'](function () {
            return 'Remote file load did not return new file. statusCode: ' + response.statusCode + ', ' + (err ? err.message : 'undefined');
          });
          callback(null, cachedJson ? cachedJson.body : null);
        } else if (response.body) {
          _manticore2.default.setItem(_this.fileId, _this.storageType, JSON.stringify(response), function () {
            Log.debug(function () {
              return 'Using server version of ' + _this.fileId;
            });
            callback(null, response.body);
          });
        } else {
          Log.debug(function () {
            return 'Using CACHED version of ' + _this.fileId;
          });
          callback(null, cachedJson ? cachedJson.body : null);
        }
      });
    });
  };

  CachedServerFile.prototype._retrieveCachedFile = function _retrieveCachedFile(callback) {
    var _this2 = this;

    _manticore2.default.getItem(this.fileId, this.storageType, function (e, cachedData) {
      if (e) {
        Log.warn('Failed to get cached file with Id ' + _this2.fileId + ' from storage Type: \'' + _this2.storageType + '\'. Error: ' + e);
        callback(e, null);
      }

      try {
        callback(null, cachedData ? JSON.parse(cachedData) : null);
      } catch (err) {
        Log.warn('Unable to parse cached file ' + cachedData + ' to json. Error : ' + err);
        callback(err, null);
      }
    });
  };

  return CachedServerFile;
}();

exports.default = CachedServerFile;

},{"../common/retailSDKUtil":"/Users/aravidas/Documents/Git/retail-sdk/js/common/retailSDKUtil.js","manticore":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore/browser.js","manticore-log":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-log/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/js/common/Features.js":[function(require,module,exports){
'use strict';

var _manticoreLog = require('manticore-log');

var _manticoreLog2 = _interopRequireDefault(_manticoreLog);

var _CachedServerFile = require('./CachedServerFile');

var _CachedServerFile2 = _interopRequireDefault(_CachedServerFile);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

var FeatureMapJson = require('../../resources/feature-map.json');

var Log = (0, _manticoreLog2.default)('features');

var Features = function () {
  function Features() {
    _classCallCheck(this, Features);

    this.map = FeatureMapJson;
  }

  /**
   * Loads the remote feature map
   */


  Features.prototype.loadRemoteFeatureMap = function loadRemoteFeatureMap() {
    var _this = this;

    var url = 'https://www.paypalobjects.com/webstatic/mobile/retail-sdk/feature-map.json';
    var file = new _CachedServerFile2.default(Features.FileId, url);

    file.get(function (err, remoteMap) {
      if (err || !remoteMap) {
        Log.error('Could not retrieve remote feature. Error: ' + err);
        return;
      }

      Log.info('Version of local feature map: ' + _this.map.VERSION + ' remote/cached: ' + remoteMap.VERSION);
      if (parseFloat(_this.map.VERSION) < parseFloat(remoteMap.VERSION)) {
        Log.debug('Replacing local feature map with remote');
        _this.map = remoteMap;
      }
    });
  };

  return Features;
}();

Features.FileId = 'FeatureMapStoreKey';

module.exports = new Features();

},{"../../resources/feature-map.json":"/Users/aravidas/Documents/Git/retail-sdk/resources/feature-map.json","./CachedServerFile":"/Users/aravidas/Documents/Git/retail-sdk/js/common/CachedServerFile.js","manticore-log":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-log/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/js/common/Merchant.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

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; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

var _manticoreLog = require('manticore-log');

var _manticoreLog2 = _interopRequireDefault(_manticoreLog);

var _paypalrestManticore = require('paypalrest-manticore');

var _paypalInvoicing = require('paypal-invoicing');

var _retailPageTracker = require('retail-page-tracker');

var _events = require('events');

var _async = require('async');

var _async2 = _interopRequireDefault(_async);

var _sdkErrors = require('./sdkErrors');

var _Features = require('./Features');

var _Features2 = _interopRequireDefault(_Features);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (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 } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var Log = (0, _manticoreLog2.default)('merchant');
var BN = require('bignumber.js');

var $$ = function $$(a) {
  return a === undefined || a === null ? null : new BN(a);
};

function simpleUrl(host, service, op) {
  if (service === 'retail') {
    return 'https://' + host + '.paypal.com/v1/retail/' + op;
  } else if (service === 'auth') {
    return 'https://' + host + '.paypal.com/v1/identity/openidconnect/' + op;
  } else if (service === 'payments') {
    return 'https://' + host + '.paypal.com/v1/payments/' + op;
  } else if (service === 'devices') {
    return 'https://' + host + '.paypal.com/v2/devices/' + op;
  }
  return null;
}

/**
 * The merchant represents the account that all calls to the PayPal services will affect. Essentially this is
 * where all collected money will go, which account locations and checkin operations will occur under, etc.
 * @class
 * @property {string} emailAddress The email address of the merchant. @readonly
 * @property {string} businessName The name of the business operated by the merchant. @readonly
 * @property {string} currency The "home" currency of the merchant. @readonly
 * @property {InvoiceAddress} address The business address of the merchant @readonly
 * @property {string} environment The PayPal environment this merchant exists in - live or sandbox. Sandbox means the money is not real!
 * @property {decimal} signatureRequiredAbove The invoice total amount above which signature would be collected for swipe transactions.
 * @property {bool} isCertificationMode Run in certification mode.
 * @property {string} referrerCode The Partner Attribution Id code that is used for analytics
 * PLEASE NOTE: manipulating this setting (especially upwards) may cause you to be liable for chargebacks in the event we cannot retrieve
 * a signature for the transaction. MODIFY THIS SETTING AT YOUR OWN RISK!
 */

var Merchant = function (_EventEmitter) {
  _inherits(Merchant, _EventEmitter);

  /**
   * Only JS will make Merchants.
   * @private
   */
  function Merchant(data) {
    _classCallCheck(this, Merchant);

    var _this = _possibleConstructorReturn(this, _EventEmitter.call(this));

    _this.api = null;
    _this.userInfo = {};
    _this.status = {};
    _this.cbs = [];
    _this.environment = 'live';

    if (data) {
      _this._validateAndSetCompositeToken(data);
      _this._buildObjectWithData(data);
    }
    return _this;
  }

  Merchant.prototype.initialize = function initialize(token, repository, callback) {
    this._setToken(token, repository);
    this._fetchMerchantInfo(callback);
    return true;
  };

  Merchant.prototype._validateAndSetCompositeToken = function _validateAndSetCompositeToken(data) {
    if (data && data.compositeToken && data.compositeToken.length > 0 && data.repository) {
      this._setToken(data.compositeToken, data.repository);
      return;
    }
    throw _sdkErrors.merchant.invalidToken;
  };

  Merchant.prototype._makeInvoiceResolver = function _makeInvoiceResolver(api) {
    var _this2 = this;

    var env = api.env;
    return function (service, opts) {
      opts.headers = opts.headers || {};
      opts.headers['X-PAYPAL-REQUEST-SOURCE'] = 'MPA-DEVICE';
      if (Merchant.apiUserAgent) {
        // The Merchant.apiUserAgent User-Agent must ONLY be used for API calls made to PayPal Here Services
        opts.headers['User-Agent'] = Merchant.apiUserAgent;
      }
      if (_this2.referrerCode) {
        opts.headers['PayPal-Partner-Attribution-Id'] = _this2.referrerCode;
      }
      if (env === 'live') {
        return 'https://api.paypal.com/v1/invoicing/' + opts.op;
      } else if (env === 'sandbox') {
        return 'https://api.sandbox.paypal.com/v1/invoicing/' + opts.op;
      }
      return 'https://api.' + env + '.stage.paypal.com:12326/v1/invoicing/' + opts.op;
    };
  };

  Merchant._resolver = function _resolver(api, options) {
    var env = api.env;
    var service = options.service;
    var op = options.op;
    options.headers = options.headers || {};
    if (Merchant.apiUserAgent) {
      // The Merchant.apiUserAgent User-Agent must ONLY be used for API calls made to PayPal Here Services
      options.headers['User-Agent'] = Merchant.apiUserAgent;
    }

    if (!env || env === 'live') {
      return simpleUrl('api', service, op);
    } else if (env.indexOf('stage2') === 0) {
      if (service === 'retail') {
        return 'https://www.' + env + '.stage.paypal.com:12326/v1/retail/' + op;
      } else if (service === 'auth') {
        return 'https://www.' + env + '.stage.paypal.com/webapps/auth/protocol/openidconnect/v1/' + op;
      } else if (service === 'payments') {
        return 'https://api.' + env + '.stage.paypal.com:12326/v1/payments/' + op;
      } else if (service === 'devices') {
        return 'https://api.' + env + '.stage.paypal.com:12326/v2/devices/' + op;
      }
    } else if (env === 'sandbox') {
      return simpleUrl('api.sandbox', service, op);
    }
    return null;
  };

  Merchant.prototype._setToken = function _setToken(token, repository) {
    var _this3 = this;

    require('paypal-invoicing').InvoicingRequester.api = this.api = _paypalrestManticore.PayPalREST.fromToken(token); // eslint-disable-line global-require
    this.environment = this.api.env;
    this.repository = repository;
    this.api.addResolver('retail', Merchant._resolver);
    this.api.addResolver('auth', Merchant._resolver);
    this.api.addResolver('invoicing', this._makeInvoiceResolver(this.api));
    this.api.addResolver('payments', Merchant._resolver);
    this.api.addResolver('devices', Merchant._resolver);

    // This is a "non-server SDK" generally, so warn if they have app info
    if (this.api.app) {
      Log.warn('Using debug-only SDK token with embedded app secret. DO NOT USE IN LIVE APPS.');
    }
    Log.debug(function () {
      return 'Set environment: \'' + _this3.environment + '\' repository: \'' + _this3.repository + '\' at: \'' + _this3.api.at + '\'';
    });
  };

  Merchant.prototype._fetchMerchantInfo = function _fetchMerchantInfo(callback) {
    var _this4 = this;

    _async2.default.parallel([this._loadMerchantUserInfo.bind(this), this._loadMerchantStatus.bind(this)], function (err) {
      _this4._merchantInitialized(err, callback);
    });
  };

  Merchant.prototype._loadMerchantUserInfo = function _loadMerchantUserInfo(cb) {
    var _this5 = this;

    Log.debug('Loading merchant user info...');
    this.api.request({
      service: 'auth',
      op: 'userinfo?schema=openid',
      format: 'json'
    }, function (err, userInfo) {
      // TODO Remove me after auth/capture UAT
      err = null;
      userInfo = {
        body: {
          address: {
            street_address: '6338747 West 39th Street 2800 Byrd Industrial Drive',
            locality: 'Summit',
            region: 'NJ',
            postal_code: '07901',
            country: 'US'
          },
          email: 'ppotnis-us-b1@paypal.com',
          name: 'ppotnis'
        }
      };
      if (err && err.code === 400 && !_this5._retriedUserInfo) {
        // Bug PPPLPAYPT-2414 still not fixed...
        _this5._retriedUserInfo = true;
        _this5.api.refresh(function (refreshError) {
          if (refreshError) {
            cb(refreshError, _this5);
            return;
          }
          _this5._loadMerchantUserInfo(cb);
        });
        return;
      }
      // Shouldn't really be possible to come through here again, but just for correctness...
      delete _this5._retriedUserInfo;
      _this5.userInfo = userInfo ? userInfo.body : null;
      if (err) {
        cb(err, _this5);
        return;
      }
      if (!_this5.userInfo) {
        Log.error('Failed to load merchant information. Empty response.');
        cb(_sdkErrors.merchant.failedToLoad, null);
        return;
      }

      if (!_this5._validateUserInfo(_this5.userInfo)) {
        Log.error('Failed to load required merchant information like address, country code, email or name. ' + 'May be the scope used to generate token was not right?');
        Log.error('Error loading merchant user info\n' + JSON.stringify(_this5.userInfo, null, 4));
        cb(_sdkErrors.merchant.requiredInfoNotLoaded, null);
        return;
      }

      _paypalInvoicing.Invoice.DefaultMerchant = {
        emailAddress: _this5.emailAddress,
        businessName: _this5.businessName,
        address: _this5.address
      };

      Log.info('Successfully loaded merchant user info!');
      Log.debug(function () {
        return 'Merchant Info: \n' + JSON.stringify(userInfo.body, null, 4);
      });
      Log.debug(function () {
        return 'DefaultMerchant : \n' + JSON.stringify(_paypalInvoicing.Invoice.DefaultMerchant, null, 4);
      });
      cb(err, _this5);
    });
  };

  // TODO userInfo sometimes returns non-200 status
  // TODO Move on to Here Api status calls.


  Merchant.prototype._loadMerchantStatus = function _loadMerchantStatus(cb) {
    var _this6 = this;

    Log.debug('Loading merchant status...');
    this.api.request({
      service: 'retail',
      op: 'status',
      format: 'json'
    }, function (err, hereApiStatus) {
      if (err) {
        cb(err, _this6);
        return;
      }

      var status = hereApiStatus.body;
      if (!_this6._validateStatus(status)) {
        Log.error('Failed to load required merchant status information like currency code, status, payment types.');
        Log.error('Error loading merchant retail status info\n' + JSON.stringify(status, null, 4));
        cb(_sdkErrors.merchant.requiredInfoNotLoaded, null);
        return;
      }
      _this6.status = status;
      _paypalInvoicing.Invoice.DefaultCurrency = _this6.currency;
      Log.debug(function () {
        return 'Successfully loaded merchant status ' + JSON.stringify(status, null, 4);
      });
      cb(err, _this6);
    });
  };

  Merchant.prototype._validateUserInfo = function _validateUserInfo(userInfo) {
    return userInfo && userInfo.address && userInfo.address.country && userInfo.email && (userInfo.businessName || userInfo.name);
  };

  Merchant.prototype._validateStatus = function _validateStatus(status) {
    return status && status.status && status.currencyCode && status.businessCategoryExists && status.paymentTypes;
  };

  Merchant.prototype._buildObjectWithData = function _buildObjectWithData(merchantData) {
    Log.debug('Building the merchant object');
    if (!merchantData) {
      throw _sdkErrors.merchant.merchantDataNotProvided;
    }
    if (!this._validateUserInfo(merchantData.userInfo)) {
      throw _sdkErrors.merchant.merchantUserInfoNotProvided;
    }
    if (!this._validateStatus(merchantData.status)) {
      throw _sdkErrors.merchant.merchantStatusNotProvided;
    }

    this.userInfo = merchantData.userInfo;
    this.status = merchantData.status;

    _paypalInvoicing.Invoice.DefaultMerchant = {
      emailAddress: this.emailAddress,
      businessName: this.businessName,
      address: this.address
    };
    _paypalInvoicing.Invoice.DefaultCurrency = this.currency;
    Log.debug(function () {
      return 'Successfully created Default merchant : \n' + JSON.stringify(_paypalInvoicing.Invoice.DefaultMerchant, null, 4);
    });

    this._merchantInitialized();
  };

  Merchant.prototype._merchantInitialized = function _merchantInitialized(err, callback) {
    if (err) {
      Log.error('Merchant initialize failed: ' + err);
    } else {
      Merchant.active = this;
    }
    Merchant.events.emit('initialized', err);
    if (callback) {
      callback(err, this);
    }
  };

  Merchant.prototype.request = function request(options, callback) {
    return this.api.request(options, callback);
  };

  /**
   * Forward a receipt for an invoice.
   * @param {Invoice} invoice The invoice object for which the receipt is supposed
   * @param {string} emailOrSms Either send a receipt as an email or as an sms to a phone number
   * @param {string} txNumber The transactionNumber or the handle
   * @param {string} txType The status of the invoice
   * @param {string} customerId The customer identification number if any
   * @param {string} receiptPreferenceToken The receipt preference token if any
   * @param {Merchant~receiptForwarded} callback Error callback if any or null
   */
  Merchant.prototype.forwardReceipt = function forwardReceipt(invoice, emailOrSms, txNumber, txType, customerId, receiptPreferenceToken, callback) {
    Log.debug(function () {
      return 'Inside Forward Receipt';
    });
    var rq = {
      invoiceId: invoice.payPalId,
      transactionType: txType
    };
    if (emailOrSms.indexOf('@') > 0) {
      rq.email = emailOrSms;
      _retailPageTracker.Tracker.publishPageView(null, _retailPageTracker.pages.paymentReceiptEmail);
    } else {
      rq.phoneNumber = emailOrSms;
      _retailPageTracker.Tracker.publishPageView(null, _retailPageTracker.pages.paymentReceiptSms);
    }
    rq.customerId = customerId;
    rq.receiptPreferenceToken = receiptPreferenceToken;

    var op = void 0;
    if (txNumber) {
      op = 'checkouts/' + txNumber + '/sendReceipt';
    } else {
      op = 'checkouts/sendReceipt';
    }
    Log.debug(function () {
      return 'SendReceipt op: ' + op + '\n' + JSON.stringify(rq);
    });
    Merchant.active.request({
      service: 'retail',
      op: op,
      format: 'json',
      method: 'POST',
      debug: true,
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(rq)
    }, callback);
  };

  _createClass(Merchant, [{
    key: 'signatureRequiredAbove',
    get: function get() {
      return $$(this._signatureRequiredAbove) || $$(this.cardSettings.signatureRequiredAbove) || $$(0);
    },
    set: function set(value) {
      this._signatureRequiredAbove = value;
    }
  }, {
    key: 'featureMap',
    get: function get() {
      return _Features2.default.map[this.country];
    }
  }, {
    key: 'emailAddress',
    get: function get() {
      return this.userInfo ? this.userInfo.email : null;
    }
  }, {
    key: 'businessName',
    get: function get() {
      return this.userInfo ? this.userInfo.businessName || this.userInfo.name : null;
    }
  }, {
    key: 'currency',
    get: function get() {
      return this.status.currencyCode;
    }
  }, {
    key: 'country',
    get: function get() {
      return this.address.country;
    }
  }, {
    key: 'cardSettings',
    get: function get() {
      var cardSettings = this.status.cardSettings;
      if (typeof cardSettings === 'string' || cardSettings instanceof String) {
        var cardSettingsJson = JSON.parse(cardSettings);
        return cardSettingsJson;
      }
      return cardSettings;
    }
  }, {
    key: 'address',
    get: function get() {
      if (this._address) {
        return this._address;
      }
      var u = this.userInfo;
      var a = this._address = new _paypalInvoicing.InvoiceAddress();
      if (u && u.address) {
        u = u.address;
        a.country = u.country;
        a.postalCode = u.postal_code;
        a.city = u.locality;
        a.line1 = u.street_address;
        a.state = u.region;
      }
      return a;
    }
  }]);

  return Merchant;
}(_events.EventEmitter);

/**
 * After an attempt has been made to send your receipt to the PayPal servers,
 * the completion handler will be called with the error (if any, or null if not)
 * @callback Merchant~receiptForwarded
 * @param {PayPalError} error The error that occurred, if any
 */


exports.default = Merchant;
Merchant.events = new _events.EventEmitter();

},{"./Features":"/Users/aravidas/Documents/Git/retail-sdk/js/common/Features.js","./sdkErrors":"/Users/aravidas/Documents/Git/retail-sdk/js/common/sdkErrors.js","async":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/async/lib/async.js","bignumber.js":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/bignumber.js/bignumber.js","events":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/events/events.js","manticore-log":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-log/index.js","paypal-invoicing":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/index.js","paypalrest-manticore":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypalrest-manticore/build/index.js","retail-page-tracker":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-page-tracker/build/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/js/common/NetworkHandler/NetworkRequest.js":[function(require,module,exports){
"use strict";

exports.__esModule = true;

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

/**
 * The NetworkRequest class represents the HTTP Request object from the SDK
 * @class
 * @property {string} url Request Url
 * @property {string} method HTTP Request method
 * @property {string} format Format of the HTTP Request
 * @property {object} headers HTTP Request headers
 * @property {string} body Request body
 */
var NetworkRequest = function () {
  /**
   * @private
   */
  function NetworkRequest(callback) {
    _classCallCheck(this, NetworkRequest);

    this.callback = callback;
  }

  /**
   *
   * @param {error} err Error (if any) from handling network request
   * @param {bool} didHandle Indicates if the request was handled or not. When set to false, the SDK will fallback to
   * default network handler for handling the network requests
   * @param {NetworkResponse} response response to HTTP request. Can be null if didHandle is set to 'false'
   */


  NetworkRequest.prototype.continueWithResponse = function continueWithResponse(err, didHandle, response) {
    this.callback(err, didHandle, response);
  };

  return NetworkRequest;
}();

exports.default = NetworkRequest;

},{}],"/Users/aravidas/Documents/Git/retail-sdk/js/common/NetworkHandler/NetworkResponse.js":[function(require,module,exports){
"use strict";

exports.__esModule = true;

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

/* eslint-disable no-useless-constructor,no-empty-function */

/**
 * NetworkResponse class represents contains the response from HTTPRequest in a format that is compatible with the SDK
 * @class
 * @property {string} statusCode Response status code
 * @property {string} format Format of the response body
 * @property {object} headers Response headers
 * @property {string} body Response body
 */
var NetworkResponse =
/**
 * @constructor
 */
function NetworkResponse() {
  _classCallCheck(this, NetworkResponse);
};

/* eslint-enable no-useless-constructor,no-empty-function */


exports.default = NetworkResponse;

},{}],"/Users/aravidas/Documents/Git/retail-sdk/js/common/NetworkHandler/networkInterceptor.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;
exports.default = setNetworkHandler;

var _manticore = require('manticore');

var _manticore2 = _interopRequireDefault(_manticore);

var _manticoreLog = require('manticore-log');

var _manticoreLog2 = _interopRequireDefault(_manticoreLog);

var _NetworkRequest = require('./NetworkRequest');

var _NetworkRequest2 = _interopRequireDefault(_NetworkRequest);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var Log = (0, _manticoreLog2.default)('NetworkInterceptor');

/**
 * Add a network handler to intercept all outgoing SDK network calls
 * @param {SDK~intercept} interceptor
 */
function setNetworkHandler(interceptor) {
  var prevHttp = _manticore2.default.http;
  _manticore2.default.http = function (opt, callback) {
    var networkRequest = new _NetworkRequest2.default(function (err, didHandleRequest, networkResponse) {
      if (!didHandleRequest) {
        prevHttp(opt, callback); // Falling back to internal network handler
        return;
      }
      Log.debug(function () {
        return 'Request ' + opt.url + ' was handled by custom handler';
      });
      if (networkResponse.format === 'json') {
        try {
          networkResponse.body = JSON.parse(networkResponse.body);
        } catch (x) {
          Log.error('Error parsing provided JSON body ' + networkResponse.body + '\n' + x);
          throw x;
        }
      }
      callback(err, networkResponse);
    });
    networkRequest.url = opt.url;
    networkRequest.method = opt.method;
    networkRequest.headers = opt.headers;
    networkRequest.body = opt.body;

    try {
      interceptor(networkRequest);
    } catch (x) {
      Log.error('Error invoking custom network interceptor... Will fallback to default\n' + x);
      prevHttp(opt, callback);
    }
  };
}

},{"./NetworkRequest":"/Users/aravidas/Documents/Git/retail-sdk/js/common/NetworkHandler/NetworkRequest.js","manticore":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore/browser.js","manticore-log":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-log/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/js/common/RetailInvoice.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;
exports.RetailInvoicePayment = exports.RetailInvoice = undefined;

var _paypalInvoicing = require('paypal-invoicing');

var _manticoreLog = require('manticore-log');

var _manticoreLog2 = _interopRequireDefault(_manticoreLog);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (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 } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /* eslint no-useless-constructor: "off"*/


var Log = (0, _manticoreLog2.default)('retail.invoice');
/**
 * The "Retail" Implementation of Invoice that is used by PPH only. Contains receiptDetails such as store ID,
 * TerminalID, and countryCode.
 * This class is a specific version implementation of the Invoice.
 *
 * @class
 * @extends Invoice
 *
 * @property {string} name Transaction type of the Invoice
 * @property {decimal} total Total Invoice amount
 * @property {string} txnHandle The transaction handle
 * @property {string} countryCode The country object that contains the country code and country name
 * @property {string} storeId The store id where the receipt was generated
 * @property {string} terminalId The terminal ID where the actual receipt was generated
 * @property {string} sellerId The seller Id (Normally set to Primary users' full name)
 * @property {Invoice.Status} status The current status of the invoice
 * @property {[InvoicePayment]} payments an array of payment objects
 * @property {string} deviceName The device name
 * @property {string} footer The custom footer text
 * @property {string} payPalId The id assigned by PayPal for an invoice. This is basically same the
 *                    super class' payPalId. This is added to open the setter on the native side.
 * @property {bool} isCancelled Check if the transaction was cancelled by the user
 * @property {bool} isFailed Check if the payment was declined by the api
 */

var RetailInvoice = exports.RetailInvoice = function (_Invoice) {
  _inherits(RetailInvoice, _Invoice);

  /**
   * Creates a Retail Invoice object with the following Receipt Details.
   * @constructor
   * @param {string} currencyCode Currency code identifying the currency for amounts on the invoice.
   */
  function RetailInvoice(currencyCode) {
    _classCallCheck(this, RetailInvoice);

    return _possibleConstructorReturn(this, _Invoice.call(this, currencyCode));
  }

  RetailInvoice.prototype.toJSON = function toJSON() {
    var invoiceJSON = _Invoice.prototype.toJSON.call(this);
    // Check if invoiceJSON contains a field called 'additional data' and it is a valid JSON object
    this._buildAdditionalDataObject(invoiceJSON);
    // Return the invoiceJSON as is
    return invoiceJSON;
  };

  RetailInvoice.prototype.readJSON = function readJSON(serverJSON, hasDetails) {
    _Invoice.prototype.readJSON.call(this, serverJSON, hasDetails);
    this._parseJSONResponse(serverJSON);
  };

  RetailInvoice.prototype._buildAdditionalDataObject = function _buildAdditionalDataObject(invoiceJSON) {
    var additionalData = {};
    if (invoiceJSON.additional_data) {
      try {
        additionalData = JSON.parse(invoiceJSON.additional_data);
      } catch (x) {
        // CANNOT DO MUCH HERE... LOG WARNING AND QUIT
        Log.warn('Error parsing JSON for "additional data object".. ');
        return;
      }
    }
    additionalData.dname = this.deviceName;
    additionalData.footer = additionalData.footer || {};
    additionalData.footer.customText = this.footer || additionalData.footer.customText;
    additionalData.merchant = additionalData.merchant || {};
    additionalData.merchant.sellerId = this.sellerId || additionalData.merchant.sellerId;
    additionalData.merchant.storeId = this.storeId || additionalData.merchant.storeId;
    additionalData.merchant.terminalId = this.terminalId || additionalData.merchant.terminalId;
    invoiceJSON.additional_data = JSON.stringify(additionalData);
  };

  RetailInvoice.prototype._parseJSONResponse = function _parseJSONResponse(serverJSON) {
    /*
     Parse the stringified additional Data and set it to the respective variables.
     */
    var jsonAdditionalData = void 0;
    if (serverJSON.additional_data) {
      try {
        jsonAdditionalData = JSON.parse(serverJSON.additional_data);
      } catch (e) {
        // Valid JSON not present .. Dont parse any values from it.
        Log.warn('Error parsing JSON for "additional data object" from server.. ');
        return;
      }
      this.deviceName = jsonAdditionalData.dname;
      if (jsonAdditionalData.footer) {
        this.footer = jsonAdditionalData.footer.customText;
      }
      if (jsonAdditionalData.merchant) {
        if (jsonAdditionalData.merchant.seller) {
          this.sellerId = jsonAdditionalData.merchant.seller.sellerId;
        }
        this.terminalId = jsonAdditionalData.merchant.terminalId;
        this.storeId = jsonAdditionalData.merchant.storeId;
      }
      // Do nothing if Additional Data is not present
    }
  };

  return RetailInvoice;
}(_paypalInvoicing.Invoice);

/**
 * This class is only used to expose properties useful for retail invoice payments.
 *
 * @class
 *
 * @extends InvoicePayment
 * @property {string} transactionID PayPal payment transaction id. (Same name hides super class' field, Also since
 *                                  super class' field is readonly, no setters are generated)
 * @property {Invoice.PaymentMethod} method The payment method (cash, check etc.)
 */


var RetailInvoicePayment = exports.RetailInvoicePayment = function (_InvoicePayment) {
  _inherits(RetailInvoicePayment, _InvoicePayment);

  function RetailInvoicePayment() {
    _classCallCheck(this, RetailInvoicePayment);

    return _possibleConstructorReturn(this, _InvoicePayment.apply(this, arguments));
  }

  return RetailInvoicePayment;
}(_paypalInvoicing.InvoicePayment);

},{"manticore-log":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-log/index.js","paypal-invoicing":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/js/common/SdkEnvironmentInfo.js":[function(require,module,exports){
"use strict";

exports.__esModule = true;

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

/**
 * The executing environment of the SDK
 * @class
 * @property {string} merchantId Merchant identifier like PayerId, etc.
 * @property {string} osName Operating system name
 * @property {string} osVersion Operating system version
 * @property {string} appName Name of the integrating App
 * @property {string} appVersion Version of the integrating App
 * @property {string} appBuild Build number of the integrating app
 */
var SdkEnvironmentInfo = exports.SdkEnvironmentInfo = function () {
  function SdkEnvironmentInfo() {
    _classCallCheck(this, SdkEnvironmentInfo);
  }

  // eslint-disable-line import/prefer-default-export
  SdkEnvironmentInfo.prototype.toString = function toString() {
    return JSON.stringify(this.toJSON());
  };

  SdkEnvironmentInfo.prototype.toJSON = function toJSON() {
    return {
      merchantId: this.merchantId,
      os: "v" + this.osName + "-" + this.osVersion,
      app: this.appName + "_v" + this.appVersion + "-" + this.appBuild
    };
  };

  return SdkEnvironmentInfo;
}();

},{}],"/Users/aravidas/Documents/Git/retail-sdk/js/common/TokenExpirationHandler.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

var _manticoreLog = require('manticore-log');

var _manticoreLog2 = _interopRequireDefault(_manticoreLog);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

var Log = (0, _manticoreLog2.default)('tokenExpiration.handler');

/**
 * When user session times-out during a transaction, it will emit the SessionTimeoutHandler handler
 * @class
 */

var TokenExpirationHandler = function () {
  function TokenExpirationHandler(cb) {
    _classCallCheck(this, TokenExpirationHandler);

    this._cb = cb;
  }

  /**
   * Quit the current activity
   */


  TokenExpirationHandler.prototype.quit = function quit() {
    Log.debug('Quitting current action');
    this._cb(TokenExpirationHandler.action.end);
  };

  /**
   * Restart the last action with a valid access token
   * @param {string} accessToken Valid access token
   */


  TokenExpirationHandler.prototype.continueWithNewToken = function continueWithNewToken(accessToken) {
    Log.debug(function () {
      return 'Continuing transaction with ' + accessToken;
    });
    this._cb(TokenExpirationHandler.action.resume, accessToken);
  };

  return TokenExpirationHandler;
}();

exports.default = TokenExpirationHandler;


TokenExpirationHandler.action = {
  end: 0,
  resume: 1
};

},{"manticore-log":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-log/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/js/common/cal.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;
exports.attach = attach;
exports.configure = configure;
exports.detach = detach;
exports.flush = flush;
exports.newGroup = newGroup;
exports.setInvoiceId = setInvoiceId;
exports.setRequestSourceId = setRequestSourceId;

var _manticore = require('manticore');

var _manticore2 = _interopRequireDefault(_manticore);

var _manticoreLog = require('manticore-log');

var _manticoreLog2 = _interopRequireDefault(_manticoreLog);

var _stringify = require('qs/lib/stringify');

var _stringify2 = _interopRequireDefault(_stringify);

var _retailSDKUtil = require('../common/retailSDKUtil');

var retailSDKUtil = _interopRequireWildcard(_retailSDKUtil);

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function generateGroupId() {
  return Date.now() + '-' + Math.random();
}

var Log = (0, _manticoreLog2.default)('cal');
var MAX_CAL_EVENT_LENGTH = 50;
var MAX_HTTP_CAL_LENGTH = 20;
var CAL_LOG_SUCCESS = 0;
var CAL_LOG_FAIL = -1;
var CAL_LOG_STORE_KEY = 'CalLogStore';
var RootCalConfig = {
  level: 'INFO',
  children: {}
};

var queueDetails = void 0;
var logGroup = generateGroupId();
var logInvoiceId = '';
var requestSource = 'RetailSDK';
var savingLogStore = false;
var overlappedSaves = [];
var messageRunCounter = 0;

function saveLogStore(cb) {
  if (savingLogStore) {
    // Even if it's null, because we need to know to save again
    overlappedSaves.push(cb);
    return;
  }
  _manticore2.default.setItem(CAL_LOG_STORE_KEY, retailSDKUtil.StorageType.SecureBlob, JSON.stringify(queueDetails), function (saveError) {
    savingLogStore = false;
    if (overlappedSaves.length) {
      var nextSaves = overlappedSaves;
      overlappedSaves = [];
      saveLogStore(function (e) {
        for (var _iterator = nextSaves, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
          var _ref;

          if (_isArray) {
            if (_i >= _iterator.length) break;
            _ref = _iterator[_i++];
          } else {
            _i = _iterator.next();
            if (_i.done) break;
            _ref = _i.value;
          }

          var savedCallback = _ref;

          if (savedCallback) {
            savedCallback(e);
          }
        }
      });
    }
    if (cb) {
      cb(saveError);
    }
  });
}

function setDefaultCalLogData(calLogData, level) {
  // Set the actionId to message if not specified
  if (!calLogData.actionId) {
    calLogData.actionId = 'message';
  }
  // Set the status based on level, if not specified in calLogData
  if (!calLogData.status) {
    switch (level.toLowerCase()) {
      case 'debug':
        calLogData.status = CAL_LOG_SUCCESS;
        break;
      case 'info':
        calLogData.status = CAL_LOG_SUCCESS;
        break;
      case 'error':
        calLogData.status = CAL_LOG_FAIL;
        break;
      case 'warn':
        calLogData.status = CAL_LOG_FAIL;
        break;
      default:
        calLogData.status = CAL_LOG_FAIL;
        break;
    }
  }

  // Build the msgId which is an incrementing-per-sdk-launch "runId", a forever-incrementing message counter, and a
  // per-run message counter
  messageRunCounter += 1;
  queueDetails.msgCounter += 1;
  calLogData.msgId = queueDetails.runCounter + '.' + queueDetails.msgCounter + '.' + messageRunCounter;
}

function buildCalConfigMapping(component) {
  // Build the association of CAL configuration to manticore-log component
  var loggers = component.name.split('.');
  var myComponent = RootCalConfig;
  var parent = RootCalConfig;
  for (var i = 0; i < loggers.length; i++) {
    if (!myComponent.children[loggers[i]]) {
      myComponent.children[loggers[i]] = { children: {}, parent: parent };
    }
    myComponent = myComponent.children[loggers[i]];
    parent = myComponent;
  }
  component.calConfig = myComponent;
}

function addCalEvent(calLogEvent) {
  var logOverflow = function logOverflow() {
    return MAX_CAL_EVENT_LENGTH <= queueDetails.events.length;
  };
  if (logOverflow()) {
    Log.warn('CAL log overflow. Max messages: ' + MAX_CAL_EVENT_LENGTH);
  }

  // if the previous flush attempt was not successful, then remove an element from the array
  while (logOverflow()) {
    queueDetails.events.shift();
    if (queueDetails.saving) {
      queueDetails.saving -= 1;
    }
  }
  queueDetails.events.push(calLogEvent);
  saveLogStore();
}

/**
 * Cal logging framework for the SDK.
 * Cal logs require: name, actionId, status (0=success, -1 = fail), type (always set to "BIZ")
 * and logData consisting of actionId dependent values such as
 * timestamp (universal yyyy-MM-dd HH:mm:ss:fff +0000), duration, message details
 * The method signature is the same as the manticore log, with one additional Cal logging parameter: calLogData
 * manticore logs are verbose messages that can be logged as-is. These will be logged with "message" actionId (ToDo).
 * We could have a configuration that specifies what level of logs should be sent to Cal as messages.
 * For non-message logs, e.g. ClientInfo, NetworkResponse etc., the code will include Cal-specific log calls
 * These Cal-specific calls will send cal-specific information in the calLogData object.
 * Open for discussion: What comes first? manticore-log, and that in turn calls Cal log,
 * or Start with Cal log, and then call Manticore log from Cal?
 * @param level Debug, Trace, Info, Warn, Error
 * @param component ?
 * @param fnOrString Log message. You can pass a string, or use an es6 template INSIDE a function (for best performance).
 * @param calLogData json object with actionId dependent values
 * e.g. actionId=SWIPE/CreateInvoice etc., status=0/-1 (Success = 0, Fail = -1+ ...
 */
function calLog(level, component, fnOrString, calLogData) {
  // avoid recursive calls.
  if (component.name === 'cal') {
    return;
  }

  if (!component.calConfig) {
    buildCalConfigMapping(component);
  }

  if (_manticoreLog2.default.Ranks[level] < _manticoreLog2.default.levelFor(component.calConfig)) {
    return;
  }

  // default actionId = message
  if (!calLogData) {
    calLogData = { actionId: 'Message' }; // eslint-disable-line no-param-reassign
  }

  setDefaultCalLogData(calLogData, level, fnOrString);

  // ToDo: calculate status based on the level, if it is not available in calLogData
  var calLogEvent = {
    status: calLogData.status,
    type: 'BIZ',
    name: calLogData.actionId + '.CLIENT'
  };

  // cal log data expects the status as 'result', so change that before stringifying the json object.
  calLogData.result = calLogData.status;
  delete calLogData.status;
  if (typeof fnOrString === 'function') {
    // ToDo:Question save this in details or reason?
    calLogData.details = fnOrString().toString();
  } else {
    calLogData.details = fnOrString.toString();
  }
  calLogData.logGroup = logGroup;
  calLogData.invoiceId = logInvoiceId;
  calLogData.component = component && component.name;
  calLogEvent.data = (0, _stringify2.default)(calLogData, { encode: false });
  _manticore2.default.setTimeout(function () {
    return addCalEvent(calLogEvent);
  }, 0);
}

function removePostedLogs(cb) {
  queueDetails.events.splice(0, queueDetails.saving);
  Log.debug(function () {
    return 'Removed ' + queueDetails.saving + ' posted logs. New queue size: ' + queueDetails.events.length;
  });
  queueDetails.saving = 0;
  saveLogStore(cb);
}

function doHttpPost(calLogMessageBody, cb) {
  var Merchant = require('../common/Merchant').default; // eslint-disable-line global-require
  var saved = queueDetails.saving;
  if (Merchant.active) {
    Merchant.active.request({
      service: 'retail',
      op: 'secure-terminal-config/cal',
      method: 'POST',
      headers: {
        'X-PAYPAL-REQUEST-SOURCE': requestSource,
        'Content-Type': 'application/json'
      },
      body: calLogMessageBody
    }, function (error, rz) {
      if (!error && rz && rz.statusCode === 200) {
        removePostedLogs(function (e) {
          if (cb) {
            cb(e, saved);
          }
        });
      } else {
        queueDetails.saving = 0;
        // TODO decide whether to re-post now or some other time... Or whether
        // someone else should handle that decision based on the callback
        if (cb) {
          cb(error);
        }
      }
    });
  } else if (cb) {
    cb(new Error('No merchant available, cannot post CAL logs'));
  }
}

/**
 * Attach the CAL logger to the manticore logging infra and setup the various counters.
 * @param callback
 */
function attach(callback) {
  // Load the existing log set
  _manticore2.default.getItem(CAL_LOG_STORE_KEY, retailSDKUtil.StorageType.Secure, function (e, jsonString) {
    if (e) {
      Log.error('Failed to get persisted CAL queue ' + e.message);
    }
    if (jsonString) {
      queueDetails = JSON.parse(jsonString);
      // Increment the run counter since this is a new run
      queueDetails.runCounter += 1;
    } else {
      queueDetails = {
        // Currently queued events
        events: [],
        // When we're in the process of posting, we need to know how many we're saving
        // so that we can recover gracefully
        saving: 0,
        runCounter: 1,
        msgCounter: 0
      };
    }
    _manticoreLog2.default.addLogger(calLog);
    callback(e);
  });
}

function configure(json) {
  _manticoreLog2.default.configure(json, RootCalConfig);
}

/**
 * Mostly for testing purposes, but this will shut down CAL logging and unregister from manticore logging
 * @param callback
 */
function detach(callback) {
  saveLogStore(function (e) {
    _manticoreLog2.default.removeLogger(calLog);
    if (callback) {
      callback(e);
    }
  });
}

/**
 * Flush the queued logs to the server
 * @param cb
 */
function flush(cb) {
  if (queueDetails.saving) {
    if (cb) {
      cb(new Error('Save already in progress.'));
    }
    return;
  }
  if (queueDetails.events.length) {
    var logData = queueDetails.events.slice(0, MAX_HTTP_CAL_LENGTH);
    var body = JSON.stringify({ events: logData });
    queueDetails.saving = logData.length;
    Log.debug(function () {
      return 'Flushing ' + queueDetails.saving + ' logs to CAL server.';
    });
    doHttpPost(body, cb);
  } else if (cb) {
    cb(null, 0);
  }
}

// TODO these won't work like this if and when we don't have a single active transaction. We should restructure
// this soon to avoid the problem later. Easiest thing is probably to have some closure trick that will create a
// "logging facade" that stores this info and merges it with the fourth argument to regular logging.

// Log grouping
// Logs can grouped by associating a logGroup with each log within a transaction
// The transaction manager can invoke newLogGroup() to generate a new log group

function newGroup(groupId) {
  logGroup = groupId || generateGroupId();
  logInvoiceId = '';
  Log.debug(function () {
    return 'Set group Id to ' + logGroup;
  });
  return logGroup;
}

function setInvoiceId(invoiceId) {
  logInvoiceId = invoiceId;
}

function setRequestSourceId(id) {
  if (id) {
    requestSource = 'RetailSDK.' + id.substr(0, 150);
  }
}

},{"../common/Merchant":"/Users/aravidas/Documents/Git/retail-sdk/js/common/Merchant.js","../common/retailSDKUtil":"/Users/aravidas/Documents/Git/retail-sdk/js/common/retailSDKUtil.js","manticore":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore/browser.js","manticore-log":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-log/index.js","qs/lib/stringify":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/qs/lib/stringify.js"}],"/Users/aravidas/Documents/Git/retail-sdk/js/common/flow.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

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; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

var _manticoreLog = require('manticore-log');

var _manticoreLog2 = _interopRequireDefault(_manticoreLog);

var _events = require('events');

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (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 } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var Log = (0, _manticoreLog2.default)('flow');
var FACADE = Symbol('flow');

/**
 * Present a protected view of the flow to a particular step so that it can't call the
 * true flow step after it is deactivated.
 */

var FlowFacade = function (_EventEmitter) {
  _inherits(FlowFacade, _EventEmitter);

  function FlowFacade(flow) {
    _classCallCheck(this, FlowFacade);

    var _this = _possibleConstructorReturn(this, _EventEmitter.call(this));

    _this.active = true;
    _this.flow = flow;
    return _this;
  }

  FlowFacade.prototype._prepareForChange = function _prepareForChange(noPush) {
    var f = this.flow;
    if (!noPush) {
      f.previousSteps.push(f.stepIndex);
    }
    if (f[FACADE]) {
      f[FACADE].active = false;
    }
    f[FACADE] = new FlowFacade(f);
  };

  FlowFacade.prototype._check = function _check() {
    if (!this.active) {
      Log.error('Flow step completion function called by inactive step ' + this.stepName + '!');
      this.flow.emit('flowError', new Error('Flow step completion function called by inactive step!'));
      return false;
    }
    return true;
  };

  FlowFacade.prototype._executeStep = function _executeStep(index) {
    var _this2 = this;

    var direction = index < this.flow.stepIndex ? 'regressing' : 'advancing';
    this.flow.stepIndex = index;
    var stepFn = this.flow.steps[index];
    Log.debug(function () {
      return 'Flow ' + direction + ' to ' + _this2.stepName;
    });

    try {
      stepFn.call(this.flow.owner, this.flow[FACADE]);
    } catch (e) {
      Log.error(this.stepName + ' execution returned an error: ' + e);
      this.flow[FACADE].abortFlow(e);
    }
  };

  /**
   * A flow step should call next to advance to the next step, or complete if it's the last
   */


  FlowFacade.prototype.next = function next() {
    if (!this._check()) {
      Log.debug('Flow::next called out of turn!');
      return;
    }
    var f = this.flow;
    if (f.stepIndex + 1 >= f.steps.length) {
      this.completeFlow();
      return;
    }
    f.emit('next', f.stepIndex);
    this._prepareForChange();
    this._executeStep(f.stepIndex + 1);
  };

  /**
   * A flow step should call back to end the current step and go back to the previous step
   * (or abort if you're the first)
   * TODO how do we continue to go back if the previous step was skipped?
   */


  FlowFacade.prototype.back = function back() {
    if (!this._check()) {
      Log.debug('Flow::back called out of turn!');
      return;
    }
    var f = this.flow;
    if (f.previousSteps.length === 0) {
      this.abortFlow();
      return;
    }
    f.emit('back', f.steps[f.stepIndex], f.steps[f.stepIndex - 1]);
    this._prepareForChange(true);
    this._executeStep(f.previousSteps.pop());
  };

  /**
   * Immediately complete the flow, firing the completed event
   */


  FlowFacade.prototype.completeFlow = function completeFlow() {
    var _this3 = this;

    if (!this._check()) {
      Log.debug('Flow::complete called out of turn!');
      return;
    }
    Log.debug(function () {
      return (_this3.flow.name || 'Anonymous') + ' Flow completed.';
    });
    var f = this.flow;
    this._prepareForChange();
    f.stepIndex = null;
    f[FACADE] = null;
    f.emit('completed', f.data);
    f.emit('ended', f.data);
  };

  /**
   * Immediately abort the flow, firing the aborted event
   */


  FlowFacade.prototype.abortFlow = function abortFlow(error) {
    if (!this._check()) {
      Log.debug('Flow::abortFlow called out of order!');
      return;
    }
    Log.debug((this.flow.name || 'Anonymous') + ' Flow aborted');
    var f = this.flow;
    if (error) {
      f.data.error = error;
    }
    f[FACADE].emit('aborted');
    this._prepareForChange();
    f.stepIndex = null;
    f[FACADE] = null;
    f.emit('aborted', f.data);
    f.emit('ended', f.data);
  };

  FlowFacade.prototype.nextOrAbort = function nextOrAbort(error) {
    if (error) {
      this.abortFlow(error);
    } else {
      this.next();
    }
  };

  _createClass(FlowFacade, [{
    key: 'stepName',
    get: function get() {
      var fn = this.flow.steps[this.flow.stepIndex];
      return fn ? fn.fnName || fn.name : undefined;
    }
  }, {
    key: 'data',
    get: function get() {
      return this.flow.data;
    }
  }, {
    key: 'stepIndex',
    get: function get() {
      return this.flow.stepIndex;
    }
  }, {
    key: 'previousSteps',
    get: function get() {
      return this.flow.previousSteps;
    }
  }]);

  return FlowFacade;
}(_events.EventEmitter);

/**
 * A flow is a series of steps in order to complete a process. Each step may complete, cancel, go forward or back
 * in the process. In code, a flow is an array of functions. The functions take one argument - a flow controller -
 * which exposes methods to control the next step in the flow.
 *
 */


var Flow = function (_EventEmitter2) {
  _inherits(Flow, _EventEmitter2);

  /**
   * Construct a new flow with steps pass as individual arguments (each a function) OR
   * as a single array as the second argument.
   * Call start() after setting up appropriate event handlers.
   */
  function Flow(thisForSteps, allSteps) {
    _classCallCheck(this, Flow);

    var _this4 = _possibleConstructorReturn(this, _EventEmitter2.call(this));

    _this4.owner = thisForSteps;
    if (Array.isArray(allSteps)) {
      _this4.steps = allSteps;
    } else {
      _this4.steps = Array.prototype.slice.call(arguments, 1); // eslint-disable-line prefer-rest-params
    }
    /**
     * A grab bag of data that can be used to share information among steps
     * @type {object}
     */
    _this4.data = {};
    _this4[FACADE] = null;
    _this4.stepIndex = 0;
    _this4.previousSteps = [];
    return _this4;
  }

  Flow.prototype.start = function start() {
    this[FACADE] = new FlowFacade(this);
    this[FACADE]._executeStep(0);
    return this;
  };

  Flow.prototype.abortFlow = function abortFlow(error) {
    if (!this[FACADE]) {
      Log.error('Abort called on an inactive flow!');
      return;
    }
    this[FACADE].abortFlow(error);
  };

  return Flow;
}(_events.EventEmitter);

exports.default = Flow;

},{"events":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/events/events.js","manticore-log":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-log/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/js/common/flowAsync.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

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; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

var _manticoreLog = require('manticore-log');

var _manticoreLog2 = _interopRequireDefault(_manticoreLog);

var _events = require('events');

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (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 } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var Log = (0, _manticoreLog2.default)('flowAsync');
var FACADE = Symbol('flowAsync');

/**
 * Present a protected view of the flow to a particular step so that it can't call the
 * true flow step after it is deactivated.
 */

var FlowFacadeAsync = function (_EventEmitter) {
  _inherits(FlowFacadeAsync, _EventEmitter);

  function FlowFacadeAsync(flow) {
    _classCallCheck(this, FlowFacadeAsync);

    var _this = _possibleConstructorReturn(this, _EventEmitter.call(this));

    _this.active = true;
    _this.flow = flow;
    return _this;
  }

  FlowFacadeAsync.prototype.toJSON = function toJSON() {
    return {
      stepName: this.stepName,
      active: this.active,
      flow: this.flow
    };
  };

  FlowFacadeAsync.prototype._prepareForChange = function _prepareForChange(noPush) {
    var f;
    return regeneratorRuntime.async(function _prepareForChange$(_context) {
      while (1) {
        switch (_context.prev = _context.next) {
          case 0:
            f = this.flow;

            if (!noPush) {
              f.previousSteps.push(f.stepIndex);
            }

            if (f[FACADE]) {
              f[FACADE].active = false;
            }
            f[FACADE] = new FlowFacadeAsync(f);

          case 4:
          case 'end':
            return _context.stop();
        }
      }
    }, null, this);
  };

  FlowFacadeAsync.prototype._check = function _check() {
    if (!this.active) {
      Log.error('Flow step completion function called by inactive step ' + this.stepName + '!');
      this.flow.emit('flowError', new Error('Flow step completion function called by inactive step!'));
      return false;
    }
    return true;
  };

  FlowFacadeAsync.prototype._executeStep = function _executeStep(index) {
    var _this2 = this;

    var direction, stepFn;
    return regeneratorRuntime.async(function _executeStep$(_context2) {
      while (1) {
        switch (_context2.prev = _context2.next) {
          case 0:
            direction = index < this.flow.stepIndex ? 'regressing' : 'advancing';

            this.flow.stepIndex = index;
            stepFn = this.flow.steps[index];

            Log.debug(function () {
              return 'Flow ' + direction + ' to ' + _this2.stepName;
            });

            _context2.prev = 4;
            _context2.next = 7;
            return regeneratorRuntime.awrap(stepFn.call(this.flow.owner, this.flow[FACADE]));

          case 7:
            _context2.next = 14;
            break;

          case 9:
            _context2.prev = 9;
            _context2.t0 = _context2['catch'](4);

            Log.error(this.stepName + ' execution returned an error: ' + _context2.t0);
            _context2.next = 14;
            return regeneratorRuntime.awrap(this.flow[FACADE].abortFlow(_context2.t0));

          case 14:
          case 'end':
            return _context2.stop();
        }
      }
    }, null, this, [[4, 9]]);
  };

  /**
   * A flow step should call next to advance to the next step, or complete if it's the last
   */


  FlowFacadeAsync.prototype.next = function next() {
    var f;
    return regeneratorRuntime.async(function next$(_context3) {
      while (1) {
        switch (_context3.prev = _context3.next) {
          case 0:
            if (this._check()) {
              _context3.next = 3;
              break;
            }

            Log.debug(function () {
              return 'Flow::next called out of turn!';
            });
            return _context3.abrupt('return');

          case 3:
            f = this.flow;

            if (!(f.stepIndex + 1 >= f.steps.length)) {
              _context3.next = 8;
              break;
            }

            _context3.next = 7;
            return regeneratorRuntime.awrap(this.completeFlow());

          case 7:
            return _context3.abrupt('return');

          case 8:
            f.emit('next', f.stepIndex);
            _context3.next = 11;
            return regeneratorRuntime.awrap(this._prepareForChange());

          case 11:
            _context3.next = 13;
            return regeneratorRuntime.awrap(this._executeStep(f.stepIndex + 1));

          case 13:
          case 'end':
            return _context3.stop();
        }
      }
    }, null, this);
  };

  /**
   * A flow step should call back to end the current step and go back to the previous step
   * (or abort if you're the first)
   * TODO how do we continue to go back if the previous step was skipped?
   */


  FlowFacadeAsync.prototype.back = function back() {
    var f;
    return regeneratorRuntime.async(function back$(_context4) {
      while (1) {
        switch (_context4.prev = _context4.next) {
          case 0:
            if (this._check()) {
              _context4.next = 3;
              break;
            }

            Log.debug(function () {
              return 'Flow::back called out of turn!';
            });
            return _context4.abrupt('return');

          case 3:
            f = this.flow;

            if (!(f.previousSteps.length === 0)) {
              _context4.next = 8;
              break;
            }

            _context4.next = 7;
            return regeneratorRuntime.awrap(this.abortFlow());

          case 7:
            return _context4.abrupt('return');

          case 8:
            f.emit('back', f.steps[f.stepIndex], f.steps[f.stepIndex - 1]);
            _context4.next = 11;
            return regeneratorRuntime.awrap(this._prepareForChange(true));

          case 11:
            _context4.next = 13;
            return regeneratorRuntime.awrap(this._executeStep(f.previousSteps.pop()));

          case 13:
          case 'end':
            return _context4.stop();
        }
      }
    }, null, this);
  };

  /**
   * Immediately complete the flow, firing the completed event
   */


  FlowFacadeAsync.prototype.completeFlow = function completeFlow() {
    var _this3 = this;

    var f;
    return regeneratorRuntime.async(function completeFlow$(_context5) {
      while (1) {
        switch (_context5.prev = _context5.next) {
          case 0:
            if (this._check()) {
              _context5.next = 3;
              break;
            }

            Log.debug(function () {
              return 'Flow::complete called out of turn!';
            });
            return _context5.abrupt('return');

          case 3:
            Log.debug(function () {
              return (_this3.flow.name || 'Anonymous') + ' Flow completed.';
            });
            f = this.flow;
            _context5.next = 7;
            return regeneratorRuntime.awrap(this._prepareForChange());

          case 7:
            f.stepIndex = null;
            f[FACADE] = null;
            f.emit('completed', f.data);
            f.emit('ended', f.data);

          case 11:
          case 'end':
            return _context5.stop();
        }
      }
    }, null, this);
  };

  /**
   * Immediately abort the flow, firing the aborted event
   */


  FlowFacadeAsync.prototype.abortFlow = function abortFlow(error) {
    var _this4 = this;

    var f;
    return regeneratorRuntime.async(function abortFlow$(_context6) {
      while (1) {
        switch (_context6.prev = _context6.next) {
          case 0:
            if (this._check()) {
              _context6.next = 3;
              break;
            }

            Log.debug(function () {
              return 'Flow::abortFlow called out of order!';
            });
            return _context6.abrupt('return');

          case 3:
            Log.debug(function () {
              return (_this4.flow.name || 'Anonymous') + ' Flow aborted';
            });
            f = this.flow;

            if (error) {
              f.data.error = error;
            }
            f[FACADE].emit('aborted');
            _context6.next = 9;
            return regeneratorRuntime.awrap(this._prepareForChange());

          case 9:
            f.stepIndex = null;
            f[FACADE] = null;
            f.emit('aborted', f.data);
            f.emit('ended', f.data);

          case 13:
          case 'end':
            return _context6.stop();
        }
      }
    }, null, this);
  };

  FlowFacadeAsync.prototype.nextOrAbort = function nextOrAbort(error) {
    return regeneratorRuntime.async(function nextOrAbort$(_context7) {
      while (1) {
        switch (_context7.prev = _context7.next) {
          case 0:
            if (!error) {
              _context7.next = 5;
              break;
            }

            _context7.next = 3;
            return regeneratorRuntime.awrap(this.abortFlow(error));

          case 3:
            _context7.next = 7;
            break;

          case 5:
            _context7.next = 7;
            return regeneratorRuntime.awrap(this.next());

          case 7:
          case 'end':
            return _context7.stop();
        }
      }
    }, null, this);
  };

  _createClass(FlowFacadeAsync, [{
    key: 'stepName',
    get: function get() {
      var fn = this.flow.steps[this.flow.stepIndex];
      return fn ? fn.fnName || fn.name : undefined;
    }
  }, {
    key: 'data',
    get: function get() {
      return this.flow.data;
    }
  }, {
    key: 'stepIndex',
    get: function get() {
      return this.flow.stepIndex;
    }
  }, {
    key: 'previousSteps',
    get: function get() {
      return this.flow.previousSteps;
    }
  }]);

  return FlowFacadeAsync;
}(_events.EventEmitter);

/**
 * A flow is a series of steps in order to complete a process. Each step may complete, cancel, go forward or back
 * in the process. In code, a flow is an array of functions. The functions take one argument - a flow controller -
 * which exposes methods to control the next step in the flow.
 *
 */


var FlowAsync = function (_EventEmitter2) {
  _inherits(FlowAsync, _EventEmitter2);

  /**
   * Construct a new flow with steps pass as individual arguments (each a function) OR
   * as a single array as the second argument.
   * Call start() after setting up appropriate event handlers.
   */
  function FlowAsync(thisForSteps, allSteps) {
    _classCallCheck(this, FlowAsync);

    var _this5 = _possibleConstructorReturn(this, _EventEmitter2.call(this));

    _this5.owner = thisForSteps;
    if (Array.isArray(allSteps)) {
      _this5.steps = allSteps;
    } else {
      _this5.steps = Array.prototype.slice.call(arguments, 1); // eslint-disable-line prefer-rest-params
    }
    /**
     * A grab bag of data that can be used to share information among steps
     * @type {object}
     */
    _this5.data = {};
    _this5[FACADE] = null;
    _this5.stepIndex = 0;
    _this5.previousSteps = [];
    return _this5;
  }

  FlowAsync.prototype.toJSON = function toJSON() {
    return {
      data: this.data,
      stepIndex: this.stepIndex,
      previousSteps: this.previousSteps
    };
  };

  FlowAsync.prototype.start = function start() {
    return regeneratorRuntime.async(function start$(_context8) {
      while (1) {
        switch (_context8.prev = _context8.next) {
          case 0:
            this[FACADE] = new FlowFacadeAsync(this);
            _context8.next = 3;
            return regeneratorRuntime.awrap(this[FACADE]._executeStep(0));

          case 3:
            return _context8.abrupt('return', this);

          case 4:
          case 'end':
            return _context8.stop();
        }
      }
    }, null, this);
  };

  FlowAsync.prototype.abortFlow = function abortFlow(error) {
    return regeneratorRuntime.async(function abortFlow$(_context9) {
      while (1) {
        switch (_context9.prev = _context9.next) {
          case 0:
            if (this[FACADE]) {
              _context9.next = 3;
              break;
            }

            Log.error('Abort called on an inactive flow!');
            return _context9.abrupt('return');

          case 3:
            _context9.next = 5;
            return regeneratorRuntime.awrap(this[FACADE].abortFlow(error));

          case 5:
          case 'end':
            return _context9.stop();
        }
      }
    }, null, this);
  };

  _createClass(FlowAsync, [{
    key: 'stepName',
    get: function get() {
      return this[FACADE].stepName;
    }
  }]);

  return FlowAsync;
}(_events.EventEmitter);

exports.default = FlowAsync;

},{"events":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/events/events.js","manticore-log":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-log/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/js/common/l10n.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

var _en = require('./localized/en');

var _en2 = _interopRequireDefault(_en);

var _jp = require('./localized/jp');

var _jp2 = _interopRequireDefault(_jp);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

/**
 * Load the overall retail SDK localization files
 */
exports.default = require('l10n-manticore')({ en: _en2.default, jp: _jp2.default }); // eslint-disable-line global-require

},{"./localized/en":"/Users/aravidas/Documents/Git/retail-sdk/js/common/localized/en.js","./localized/jp":"/Users/aravidas/Documents/Git/retail-sdk/js/common/localized/jp.js","l10n-manticore":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/l10n-manticore/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/js/common/localized/en.js":[function(require,module,exports){
'use strict';

/* eslint-disable no-template-curly-in-string, max-len */

module.exports = {
  Done: 'Done',
  Cancel: 'Cancel',
  Ok: 'OK',
  Yes: 'Yes',
  No: 'No',
  Error: 'Oops!',
  RemoveCard: '\nPlease remove card.',
  Sig: {
    Title: 'Charge ${amount} to ${cardIssuer} *${lastFour}',
    Here: 'Sign Here',
    Footer: 'I agree to pay the amount above according to the terms applicable to my card.'
  },
  Rcpt: {
    Title: '${amount}',
    Prompt: 'Would you like a receipt?',
    EmailButtonTitle: 'Email',
    SMSButtonTitle: 'Text',
    NoThanksButtonTitle: 'No Thanks',
    Sending: 'Sending Receipt...',
    Disclaimer: 'Receipts will be delivered by PayPal. See your receipt for PayPal\'s Privacy Policy',
    Email: {
      Title: 'EMAIL RECEIPT',
      Placeholder: 'me@somewhere.com',
      Disclaimer: 'By entering my email, I agree to receive emails for all future PayPal Here transactions.',
      SendButtonTitle: 'Send'
    },
    SMS: {
      Title: 'TEXT RECEIPT',
      Placeholder: '+14085551212',
      Disclaimer: 'You agree that you\'re authorized to add this phone number and consent to receiving automated texts. Message and data rates may apply. Receipts will be delivered by PayPal. See your receipt for PayPal\'s Privacy Policy.',
      SendButtonTitle: 'Send'
    }
  },
  Tx: {
    Alert: {
      Ready: {
        Title: 'Ready',
        Msg: 'Tap, Insert or Swipe a card when ready.'
      },
      EnterPin: {
        Title: '${amount}',
        Message: 'Please enter the PIN on the card reader keypad'
      },
      IncorrectPin: {
        Title: 'Incorrect PIN',
        Message: 'The PIN is incorrect. Please try again.'
      },
      ReadyForInsertOrSwipeOnly: {
        Title: 'Ready',
        Msg: 'Insert or swipe a card when ready.'
      },
      ReadyForSwipeOnly: {
        Title: 'Please Swipe Card',
        Msg: 'Swipe the card at the top of the reader'
      },
      ReadyForInsertOnly: {
        Title: 'Ready',
        Msg: 'Insert a card when ready.'
      },
      Cancelled: {
        Title: 'Cancelled',
        Msg: 'Transaction Cancelled'
      },
      Cancel: {
        Title: 'Cancel',
        Msg: 'Would you like to cancel this transaction?'
      },
      TimeOut: {
        Title: 'Transaction Timed Out',
        Msg: 'Transaction was not completed.',
        Button: 'Cancel transaction'
      },
      NfcNotAllowed: {
        Title: 'Insert or swipe card',
        Msg: 'Card provider requires that you insert or swipe card.'
      },
      NfcFallback: {
        Title: 'Unable to Read Card',
        Msg: 'Insert or swipe card now, or try a different card.'
      },
      NfcPaymentDeclined: {
        Title: 'Contactless Transaction Declined',
        Msg: 'Do you want to try again by inserting the card?'
      },
      InsertOrSwipe: {
        Title: 'Insert or Swipe Card',
        Msg: 'Card issuer requires\nthat you insert or swipe card',
        Button: 'Cancel transaction'
      },
      IncorrectOnlinePin: {
        Title: 'Incorrect PIN',
        Msg: 'The PIN entered was incorrect. Please try again.'
      },
      GenericError: {
        Title: 'Transaction cancelled',
        PaymentMessage: 'Unable to process payment',
        RefundMessage: 'Unable to process refund'
      },
      TapDifferentCard: {
        Title: 'Unable to read card',
        Msg: 'Please insert or swipe card now, or press OK and tap a different card'
      },
      BlockedCard: {
        Title: 'Declined',
        Msg: 'Contact the card issuer for more information'
      },
      BlockedCardTapped: {
        Title: 'Declined',
        Msg: 'Please contact the card issuer for more information'
      },
      BlockedCardSwiped: {
        Title: 'Declined',
        Msg: 'Please contact the card issuer for more information'
      },
      ChipCardSwiped: {
        Title: 'Chip card detected',
        Msg: 'Please insert card'
      },
      UnsuccessfulInsert: {
        Title: 'Unable to read card',
        Msg: 'Please try again. Firmly insert the card, chip first, into the bottom of the reader'
      },
      AmountTooLow: {
        Title: 'Amount Too Low',
        Msg: 'The minimum amount for card payments is ${amount}. Please enter a new amount or choose a different payment method.'
      },
      AmountTooHigh: {
        Title: 'Amount Too High',
        Msg: 'The maximum amount for card payments is ${amount}. Please enter a new amount or choose a different payment method.'
      },
      Refund: {
        Title: 'Refund type',
        Msg: 'Please select a type',
        Buttons: {
          WithCard: 'Refund With Card',
          WithoutCard: 'Refund Without Card'
        },
        CardMismatch: {
          Title: 'Card Mismatch',
          Msg: 'Card presented for refund is not the one used for the original payment'
        }
      },
      MultipleContactlessCardsDetected: {
        Title: 'Please present only one card',
        Msg: 'Multiple Contactless Cards Detected'
      },
      LowBattery: {
        Title: 'Battery Low',
        Msg: 'Please recharge your card reader'
      }
    },
    Retry: 'Try again?',
    CancelledByUser: 'Payment Cancelled',
    TransactionFailed: 'Payment Declined',
    TransactionSuccessful: 'Payment Successful',
    RefundSuccessful: 'Refund Complete',
    RefundFailed: 'Refund Failed'
  },
  SwUpgrade: {
    Required: {
      Title: 'Update Required',
      Msg: 'Your card reader must be updated before you can process transactions.'
    },
    Optional: {
      Title: 'Update available',
      Msg: 'An update is available for your card reader.'
    },
    Buttons: {
      Ok: 'OK',
      UpdateNow: 'Update Now',
      NotNow: 'Not Now',
      Retry: 'Try again'
    },
    Failed: {
      Title: 'Software Update Failed',
      Msg: 'Sorry, the update could not be completed.',
      BatteryLow: 'Please recharge the card reader.'
    },
    Updating: {
      Title: 'Updating Reader',
      Msg: '\nPlease do not close the app or disconnect the reader'
    },
    Success: {
      Title: 'Update Successful',
      Msg: 'Your card reader is ready.\nYou can now accept card payments.'
    },
    Downloading: 'Downloading ${count}/${total}',
    Initializing: 'Initializing card reader...\nPlease do not close the app or disconnect the reader',
    ValidatingSecurityKeys: 'Validating security keys...\nPlease do not close the app or disconnect the reader',
    SecurityKeysInstalled: 'Security keys installed.',
    UpdatingWithDetails: 'Updating ${stage} ${progress}%\nPlease do not close the app or disconnect the reader',
    Restarting: 'Restarting card reader...\nPlease do not close the app',
    Reconnecting: 'Reconnecting to card reader...\nPlease do not close the app',
    RestartInstruction: {
      Title: 'Start Reader',
      Msg: 'Please start the reader to proceed with the update'
    },
    Connected: 'Connected',
    Usb: {
      UsbUnplug: 'Please unplug your USB reader and press OK',
      UsbWait: 'Please wait before plugging in your USB reader.',
      UsbPlug: 'Please reconnect your USB reader.'
    }
  },
  EMV: {
    Tip: {
      Title: 'Waiting for customer input...',
      Buttons: {
        NoTip: 'No Tip'
      }
    },
    QuickChip: 'Card May Be Removed\nTransaction Still Processing...',
    Processing: 'Processing...',
    ProcessingPinOk: 'Processing... PIN OK',
    PinOk: 'PIN OK',
    ProcessingRefund: 'Processing Refund...',
    Cancelling: 'Cancelling...',
    Finalize: 'Completing Payment...',
    DoNotRemove: 'Do not remove card.',
    Remove: 'Please remove card.',
    Complete: '${amount} paid',
    RefundComplete: '${amount} refunded',
    Select: 'Choose an application:'
  },
  MultiCard: {
    Title: 'Select a device',
    Msg: 'Please select the PayPal card reader you would like to use:'
  },
  Device: {
    Connecting: {
      Title: 'Connecting to\n${deviceId}'
    },
    Connected: {
      Title: 'Card reader connected',
      Buttons: {
        Switch: 'Switch Card Readers'
      }
    },
    RetryConnection: {
      Title: 'Sorry, we could not connect to this reader',
      Message: 'Please make sure the card reader is turned on and the battery is charged',
      Buttons: {
        Retry: 'Try Again'
      }
    },
    ConnectingFailed: {
      Title: 'Could not\nconnect to\n${deviceId}',
      Buttons: {
        Cancel: 'OK'
      }
    },
    LastReaderUsed: {
      titleLastReaderUsed: 'Last reader used',
      titleConnected: 'Card Reader Connected',
      msgConnecting: 'Connecting',
      msgConnectionFailed: 'Sorry, we could not connect to this reader',
      msgFindFailed: 'Sorry, we couldn\'t find any available card readers',
      msgCheckReader: 'Please check that the card reader is turned on and the battery is charged',
      btnConnect: 'Connect',
      btnFindAnother: 'Find Another Reader',
      btnDone: 'Done',
      btnSwitchCardReader: 'Switch Card Readers',
      btnTryAgain: 'Try Again',
      btnCancel: 'Cancel'
    },
    ChipAndSwipe: 'PayPal Chip and Swipe Reader',
    Chip: 'PayPal Chip Card Reader',
    ChipAndTap: 'PayPal Chip and Tap Reader',
    Swipe: 'PayPal Swipe Reader'
  }
};
/* eslint-enable no-template-curly-in-string, max-len */

},{}],"/Users/aravidas/Documents/Git/retail-sdk/js/common/localized/jp.js":[function(require,module,exports){
'use strict';

/* eslint-disable no-template-curly-in-string, max-len */

module.exports = {
  Done: '完了',
  Cancel: 'キャンセル',
  Ok: 'OK',
  Yes: 'はい',
  No: 'いいえ',
  Error: '申し訳ありません。',
  Sig: {
    Title: '${cardIssuer}　*${lastFour}に${amount}を請求します',
    Here: 'ここにサイン',
    Footer: 'カードに適用される利用条件に従い、上記の金額を支払うことに同意します。'
  },
  Rcpt: {
    Title: '${amount}',
    Prompt: 'レシートを発行しますか? ',
    EmailButtonTitle: 'メール',
    SMSButtonTitle: 'テキスト',
    NoThanksButtonTitle: '不要',
    Sending: 'レシートを送信中…',
    Disclaimer: 'レシートはPayPalからお送りします。PayPalのプライバシーポリシーについては、レシートをご確認ください',
    Email: {
      Title: 'メールで送信',
      Placeholder: 'me@somewhere.com',
      Disclaimer: 'メールアドレスを入力することで、今後のすべてのPayPal Here取引についてメールを受け取ることに同意します。',
      SendButtonTitle: '送信'
    },
    SMS: {
      Title: 'SMSで送信',
      Placeholder: '14085551212',
      Disclaimer: 'この電話番号を追加する権限があることと、自動送信メールを受け取ることに同意します。メール・データ料金が適用される場合があります。レシートはPayPalからお送りします。PayPalのプライバシーポリシーについては、レシートをご確認ください。',
      SendButtonTitle: '送信'
    }
  },
  Tx: {
    Alert: {
      Ready: {
        Title: '準備完了',
        Msg: '用意ができたらカードをタップ、挿入、またはスワイプします。'
      },
      EnterPin: {
        Title: '${amount}',
        Message: 'カードリーダーのキーパッドに暗証番号を入力してください'
      },
      IncorrectPin: {
        Title: '暗証番号が間違っています',
        Message: '暗証番号が間違っています。もう一度お試しください。'
      },
      ReadyForInsertOrSwipeOnly: {
        Title: '準備完了',
        Msg: '用意ができたらカードを挿入またはスワイプします。'
      },
      ReadyForSwipeOnly: {
        Title: 'カードをリーダーに通してください',
        Msg: 'カードをリーダーの上部で通してください'
      },
      ReadyForInsertOnly: {
        Title: '準備完了',
        Msg: '用意ができたらカードを挿入します。'
      },
      Cancelled: {
        Title: 'キャンセルされました',
        Msg: '取引がキャンセルされました'
      },
      Cancel: {
        Title: 'キャンセル',
        Msg: 'この取引をキャンセルしますか? '
      },
      TimeOut: {
        Title: '取引がタイムアウトになりました',
        Msg: '取引は完了しませんでした。',
        Button: '取引のキャンセル'
      },
      NfcNotAllowed: {
        Title: 'カードの挿入またはリーダーに通す',
        Msg: 'クレジットカード会社により、カードの挿入またはスワイプが求められています。'
      },
      NfcFallback: {
        Title: 'カードを読み取れません',
        Msg: 'カードを挿入するかスワイプしてください。または別のカードをお試しください。'
      },
      NfcPaymentDeclined: {
        Title: '非接触式取引が拒否されました',
        Msg: 'カードを挿入して再度実行しますか? '
      },
      InsertOrSwipe: {
        Title: 'カードの挿入またはスワイプ',
        Msg: 'カード会社により、\nカードの挿入またはスワイプが求められています',
        Button: '取引のキャンセル'
      },
      IncorrectOnlinePin: {
        Title: '暗証番号が間違っています',
        Msg: '入力された暗証番号が正しくありません。もう一度お試しください。'
      },
      GenericError: {
        Title: '取引がキャンセルされました',
        PaymentMessage: '支払いを実行できません',
        RefundMessage: '返金を実行できません'
      },
      TapDifferentCard: {
        Title: 'カードを読み取れません',
        Msg: 'カードを挿入するかスワイプしてください。または[OK]を押して別のカードをタップしてください。'
      },
      BlockedCard: {
        Title: '拒否済み',
        Msg: '詳細についてはカード会社にお問い合わせください'
      },
      BlockedCardInserted: {
        Title: '拒否済み',
        Msg: 'カードを取り外し、カード会社に詳細をお問い合わせください'
      },
      BlockedCardTapped: {
        Title: '拒否済み',
        Msg: '詳細についてはカード会社にお問い合わせください'
      },
      BlockedCardSwiped: {
        Title: '拒否済み',
        Msg: '詳細についてはカード会社にお問い合わせください'
      },
      ChipCardSwiped: {
        Title: 'ICカードを認識しました',
        Msg: 'カードを挿入してください'
      },
      UnsuccessfulInsert: {
        Title: 'カードを読み取れません',
        Msg: 'もう一度お試しください。カードリーダーの下部にある挿入口にICチップ側を先にしてカードをしっかり入れます'
      },
      AmountTooLow: {
        Title: '金額が低すぎます',
        Msg: 'カード支払いの場合の最低ご利用額は${amount}です。金額を入力し直すか、別の支払方法をお選びください。'
      },
      AmountTooHigh: {
        Title: '金額が高すぎます',
        Msg: 'カード支払いの場合のご利用最高額は${amount}です。金額を入力し直すか、別の支払方法をお選びください。'
      },
      Refund: {
        Title: '返金の種類',
        Msg: '種類を選択してください',
        Buttons: {
          WithCard: 'カードを使用して返金',
          WithoutCard: 'カードを使用せずに返金'
        },
        CardMismatch: {
          Title: 'カードが一致しません',
          Msg: '返金用に提示されたカードは最初の支払い時に使用されたものではありません'
        }
      }
    },
    Retry: '再度実行しますか? ',
    CancelledByUser: '支払いのキャンセル',
    TransactionFailed: '支払いが拒否されました',
    TransactionSuccessful: '支払い完了',
    RefundSuccessful: '返金が完了しました',
    RefundFailed: '返金に失敗しました'
  },
  SwUpgrade: {
    Required: {
      Title: '更新が必要です',
      Msg: '取引を処理する前に、カードリーダーを更新する必要があります。'
    },
    Optional: {
      Title: '更新を利用できます',
      Msg: 'カードリーダーの更新を利用できます。'
    },
    Buttons: {
      Ok: 'OK',
      UpdateNow: '今すぐ更新する',
      NotNow: '後で実行',
      Retry: '再度実行'
    },
    Failed: {
      Title: 'ソフトウェアの更新に失敗しました',
      Msg: '申し訳ありませんが、更新を完了できませんでした。',
      BatteryLow: 'カードリーダーを充電してください。'
    },
    Updating: {
      Title: 'カードリーダーを更新しています',
      Msg: 'カードリーダーを取り外さないでください'
    },
    Success: {
      Title: 'ソフトウェアの更新が完了しました'
    },
    Downloading: '${count}/${total}をダウンロードしています',
    Initializing: 'カードリーダーを初期化中...取り外さないでください',
    ValidatingSecurityKeys: 'セキュリティキーを確認しています...取り外さないでください',
    SecurityKeysInstalled: 'セキュリティキーをインストールしました。',
    UpdatingWithDetails: '${stage} ${progress}%を更新しています...取り外さないでください',
    Restarting: 'カードリーダーを再起動しています....取り外さないでください',
    Reconnecting: 'カードリーダーに再接続しています...取り外さないでください',
    Connected: '接続済みです',
    Usb: {
      UsbUnplug: 'USBリーダーを抜いて[OK]を押してください',
      UsbWait: '時間をおいてからUSBリーダーを接続してください。',
      UsbPlug: 'USBリーダーを再度接続してください。'
    }
  },
  EMV: {
    Tip: {
      Title: '顧客の入力を待機中…',
      Buttons: {
        NoTip: 'チップ不要'
      }
    },
    Processing: '処理中...',
    ProcessingPinOk: '処理中...暗証番号はOKです',
    PinOk: '暗証番号はOKです',
    ProcessingRefund: '返金処理中...',
    Cancelling: '取消中...',
    Finalize: '支払い処理を完了中...',
    DoNotRemove: 'カードを取り出さないでください。',
    Remove: 'カードを取り出してください。',
    Complete: '${amount}を支払いました',
    RefundComplete: '${amount}を返金しました',
    Select: 'アプリを選択します: '
  },
  MultiCard: {
    Title: '端末を選択します',
    Msg: '使用するPayPalカードリーダーを選択してください: '
  },
  Device: {
    Connecting: {
      Title: '${deviceId}に\n接続しています'
    },
    RetryConnecting: {
      Title: '${deviceId}に\n接続しますか? ',
      Message: '端末が起動していることを確認します',
      Buttons: {
        Retry: '再度実行',
        NotNow: '後で実行'
      }
    },
    ConnectingFailed: {
      Title: '${deviceId}に\n接続できません\nでした',
      Buttons: {
        Cancel: 'OK'
      }
    }
  }
};
/* eslint-enable no-template-curly-in-string, max-len */

},{}],"/Users/aravidas/Documents/Git/retail-sdk/js/common/logLevel.js":[function(require,module,exports){
"use strict";

exports.__esModule = true;
/**
 * The log level for the SDK
 * @enum {int}
 */
var logLevel = {
  /**
   * No logs statements will be included in the output
   */
  quiet: 0,
  /**
   * Error logs will be forwarded to the output
   */
  error: 1,
  /**
   * Warn and Error logs will be forwarded to the output
   */
  warn: 2,
  /**
   * Info, Warn & Error logs will be forwarded to output
   */
  info: 3,
  /**
   * Debug, Info, Warn & Error logs will be forwarded to output
   */
  debug: 4
};

exports.default = logLevel;

},{}],"/Users/aravidas/Documents/Git/retail-sdk/js/common/retailSDKUtil.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;
exports.currencySymbols = undefined;
exports.getEnumName = getEnumName;
exports.transactionCancelledError = transactionCancelledError;
exports.getDeviceModelName = getDeviceModelName;
exports.hereAPICardDataFromCard = hereAPICardDataFromCard;
exports.getInvoiceEnumFromPaymentType = getInvoiceEnumFromPaymentType;
exports.getAmountWithCurrencySymbol = getAmountWithCurrencySymbol;
exports.getRandomId = getRandomId;
exports.isDatesWithinOffset = isDatesWithinOffset;
exports.getCardReaderModel = getCardReaderModel;
exports.getCardReaderManufacturer = getCardReaderManufacturer;
exports.getCardReaderIcon = getCardReaderIcon;
exports.getCardReaderDescription = getCardReaderDescription;
exports.isRoamSwiper = isRoamSwiper;
exports.saveLastActiveReader = saveLastActiveReader;
exports.getLastActiveReader = getLastActiveReader;
exports.isNullOrUndefined = isNullOrUndefined;

var _moment = require('moment');

var _moment2 = _interopRequireDefault(_moment);

var _retailPaymentDevice = require('retail-payment-device');

var _manticoreUtil = require('manticore-util');

var _manticoreLog = require('manticore-log');

var _manticoreLog2 = _interopRequireDefault(_manticoreLog);

var _manticore = require('manticore');

var _manticore2 = _interopRequireDefault(_manticore);

var _paypalInvoicing = require('paypal-invoicing');

var _bignumber = require('bignumber.js');

var _bignumber2 = _interopRequireDefault(_bignumber);

var _sdkErrors = require('./sdkErrors');

var _PaymentType = require('../transaction/PaymentType');

var _PaymentType2 = _interopRequireDefault(_PaymentType);

var _l10n = require('../common/l10n');

var _l10n2 = _interopRequireDefault(_l10n);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var storageType = {
  Secure: 'S',
  Blob: 'B',
  String: 'V',
  SecureBlob: 'E'
};

var itemKeyActiveReader = 'last-active-card-reader';
var Log = (0, _manticoreLog2.default)('sdkUtil');

module.exports.StorageType = storageType;

function getEnumName(obj, val) {
  for (var prop in obj) {
    if ({}.hasOwnProperty.call(obj, prop)) {
      if (obj[prop] === val) {
        return prop;
      }
    }
  }

  return val;
}

function transactionCancelledError(error) {
  return error && (error.code === _retailPaymentDevice.deviceError.paymentCancelled.code && error.domain === _retailPaymentDevice.deviceErrorDomain || error.code === _sdkErrors.transaction.customerCancel.code && error.domain === _sdkErrors.domain.transaction);
}

function getDeviceModelName(readerModel) {
  if (readerModel === _retailPaymentDevice.ReaderModel.M003) {
    return 'M000';
  }
  var modelName = (0, _manticoreUtil.getPropertyName)(_retailPaymentDevice.ReaderModel, readerModel);
  return modelName ? modelName.toUpperCase() : '';
}

function hereAPICardDataFromCard(card) {
  var cardData = {
    reader: {
      vendor: card.reader.manufacturer.toUpperCase(),
      readerSerialNumber: card.reader.serialNumber,
      deviceModel: getDeviceModelName(card.reader.model)
    }
  };

  if (card.formFactor === _retailPaymentDevice.FormFactor.MagneticCardSwipe) {
    cardData.reader.keySerialNumber = card.ksn;
    cardData.inputType = card.isMSRFallbackAllowed ? 'fallback_swipe' : 'swipe';
    cardData.track1 = card.track1;
    cardData.track2 = card.track2;
    cardData.track3 = card.track3;
    // TODO Remove the following M010 specific code once US837438 is live
    if (card.isMSRFallbackAllowed && cardData.reader.vendor === _retailPaymentDevice.deviceManufacturer.miura) {
      cardData.reader.vendor = 'MIURA_FB_SWIPE';
      cardData.inputType = 'swipe';
    }
  } else if (card.formFactor === _retailPaymentDevice.FormFactor.ManualCardEntry) {
    cardData.inputType = 'keyIn';
    cardData.emvData = card.emvData;
    if (card.expiration && card.expiration.length > 2) {
      cardData.expirationMonth = card.expiration.substring(2);
      cardData.expirationYear = parseInt(card.expiration.substring(0, 2), 10) + 2000;
    }
    cardData.cvv = card.cvv;
  } else if (card.formFactor === _retailPaymentDevice.FormFactor.Chip) {
    cardData.inputType = 'chip';
    cardData.emvData = card.emvData.apdu.data.toString('hex');
  } else if (card.formFactor === _retailPaymentDevice.FormFactor.EmvCertifiedContactless) {
    cardData.inputType = card.isContactlessMSD ? 'contactless_msd' : 'contactless_chip';
    cardData.emvData = card.emvData.apdu.data.toString('hex');
  } else {
    throw new Error('Cannot generate HereAPI card data from ' + card);
  }

  return cardData;
}

function getInvoiceEnumFromPaymentType(paymentType) {
  switch (paymentType) {
    case _PaymentType2.default.card:
    case _PaymentType2.default.keyIn:
      return _paypalInvoicing.InvoiceEnums.PaymentMethod.CREDIT_CARD;

    case _PaymentType2.default.cash:
      return _paypalInvoicing.InvoiceEnums.PaymentMethod.CASH;

    case _PaymentType2.default.check:
      return _paypalInvoicing.InvoiceEnums.PaymentMethod.CHECK;

    default:
      return _paypalInvoicing.InvoiceEnums.PaymentMethod.NONE;
  }
}

var currencySymbols = exports.currencySymbols = {
  USD: '$',
  AUD: '$',
  CAD: '$',
  HKD: '$',
  GBP: '£',
  EUR: '€'
};

function getAmountWithCurrencySymbol(currencyCode, amount) {
  var symbol = currencySymbols[currencyCode] || '$';
  var formatted = _paypalInvoicing.Currency.round(currencyCode, amount).toFormat(2, _bignumber2.default.ROUND_HALF_UP);
  return '' + symbol + formatted;
}

function getRandomId() {
  return Math.floor(Math.random() * 10000000000000);
}

function isDatesWithinOffset(startDate, endDate, offsetDays) {
  var momentStartDate = (0, _moment2.default)(startDate);
  var momentEndDate = (0, _moment2.default)(endDate);

  var daysDifference = momentEndDate.diff(momentStartDate, 'days', true);

  return daysDifference >= 0 && daysDifference <= offsetDays;
}

function getCardReaderModel(name) {
  if (!name) {
    return _retailPaymentDevice.ReaderModel.Unknown;
  }

  if (name === 'PayPal Audio Reader' || name.indexOf('Roam') === 0) {
    return _retailPaymentDevice.ReaderModel.Swiper;
  }

  if (name.indexOf('PayPal ') === 0) {
    return _retailPaymentDevice.ReaderModel.M010;
  }

  if (name.indexOf('PayPal-') === 0 || name.indexOf('MOB') === 0) {
    return _retailPaymentDevice.ReaderModel.Moby3000;
  }

  if (name.indexOf('PPHere-') === 0 || name.indexOf('RP') === 0) {
    return _retailPaymentDevice.ReaderModel.RP450;
  }

  return _retailPaymentDevice.ReaderModel.Unknown;
}

function getCardReaderManufacturer(name) {
  var model = getCardReaderModel(name);
  if (model === _retailPaymentDevice.ReaderModel.M010) {
    return _retailPaymentDevice.deviceManufacturer.miura;
  }

  if (model === _retailPaymentDevice.ReaderModel.Moby3000 || model === _retailPaymentDevice.ReaderModel.RP450) {
    return _retailPaymentDevice.deviceManufacturer.ingenico;
  }

  if (model === _retailPaymentDevice.ReaderModel.Swiper) {
    return _retailPaymentDevice.deviceManufacturer.roam;
  }

  return _retailPaymentDevice.deviceManufacturer.miura;
}

function getCardReaderIcon(name) {
  var model = getCardReaderModel(name);
  if (model === _retailPaymentDevice.ReaderModel.Moby3000) {
    return 'ic_chipnswipe';
  }

  if (model === _retailPaymentDevice.ReaderModel.RP450) {
    return 'ic_chipntap_waves';
  }

  if (model === _retailPaymentDevice.ReaderModel.M010) {
    return 'chip_emv_chippin';
  }

  if (model === _retailPaymentDevice.ReaderModel.Swiper) {
    return 'triangle_swiper';
  }

  return null;
}

function getCardReaderDescription(name) {
  var model = getCardReaderModel(name);
  if (model === _retailPaymentDevice.ReaderModel.Moby3000) {
    return (0, _l10n2.default)('Device.ChipAndSwipe');
  }

  if (model === _retailPaymentDevice.ReaderModel.RP450) {
    return (0, _l10n2.default)('Device.ChipAndTap');
  }

  if (model === _retailPaymentDevice.ReaderModel.M010) {
    return (0, _l10n2.default)('Device.Chip');
  }

  if (model === _retailPaymentDevice.ReaderModel.Swiper) {
    return (0, _l10n2.default)('Device.Swipe');
  }

  return null;
}

function isRoamSwiper(name) {
  var model = getCardReaderModel(name);
  return model === _retailPaymentDevice.ReaderModel.Swiper;
}

function saveLastActiveReader(cardReader, cb) {
  var data = JSON.stringify({
    id: cardReader.id,
    address: cardReader.address
  });
  _manticore2.default.setItem(itemKeyActiveReader, storageType.SecureBlob, data, function (err, path) {
    if (err) {
      Log.error('lastReader> Error saving \'' + data + '\': ' + JSON.stringify(err));
    } else {
      Log.debug(function () {
        return 'lastReader> Successfully saved \'' + data + '\' to ' + path;
      });
    }
    if (cb) {
      cb();
    }
  });
}

function getLastActiveReader(cb) {
  _manticore2.default.getItem(itemKeyActiveReader, storageType.SecureBlob, function (err, data) {
    if (err || !data) {
      Log.warn('lastReader> Unable to retrieve last active reader. Key: ' + itemKeyActiveReader + '. Error: ' + JSON.stringify(err));
      cb(null);
      return;
    }
    Log.debug(function () {
      return 'lastReader> Found last connected card reader with details: ' + data;
    });
    var lastActiveReader = JSON.parse(data);
    cb(lastActiveReader);
  });
}

function isNullOrUndefined(val) {
  // There are many ways to acheive the same (e.g. val == null, typeof val === 'undefined', etc.), but using this one as it is more readable
  return val === null || val === undefined;
}

},{"../common/l10n":"/Users/aravidas/Documents/Git/retail-sdk/js/common/l10n.js","../transaction/PaymentType":"/Users/aravidas/Documents/Git/retail-sdk/js/transaction/PaymentType.js","./sdkErrors":"/Users/aravidas/Documents/Git/retail-sdk/js/common/sdkErrors.js","bignumber.js":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/bignumber.js/bignumber.js","manticore":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore/browser.js","manticore-log":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-log/index.js","manticore-util":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-util/build/index.js","moment":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/moment/moment.js","paypal-invoicing":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/index.js","retail-payment-device":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/js/common/sdkErrors.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;
exports.sdk = exports.network = exports.retail = exports.merchant = exports.transaction = exports.domain = undefined;
exports.payPalError = payPalError;

var _manticorePaypalerror = require('manticore-paypalerror');

var domain = exports.domain = {
  transaction: 'transaction',
  merchant: 'merchant',
  retail: 'retail',
  sdk: 'sdk',
  network: 'network'
};

function payPalError(errDomain, code, message) {
  var errorInfo = new _manticorePaypalerror.PayPalErrorInfo();
  errorInfo.code = code.toString();
  errorInfo.domain = errDomain;
  errorInfo.message = message;
  return _manticorePaypalerror.PayPalError.makeError(null, errorInfo);
}

/**
 * All errors are belong to here. One assignment per domain will keep auto-complete happy.
 */
var transaction = exports.transaction = {
  customerCancel: payPalError(domain.transaction, 1, 'Transaction cancelled by customer'),
  genericCancel: payPalError(domain.transaction, 2, 'The transaction was cancelled'),
  cardCantContinue: payPalError(domain.transaction, 3, 'Cannot continue with specified card.'),
  noFunctionalDevices: payPalError(domain.transaction, 4, 'No functional devices.'),
  invoiceStatusMismatch: payPalError(domain.transaction, 5, 'The invoice status is not eligible for the given transaction method'),
  amountTooLow: payPalError(domain.transaction, 6, 'The invoice amount was too low'),
  amountTooHigh: payPalError(domain.transaction, 7, 'The invoice amount was too high'),
  failedToCollectSignature: payPalError(domain.transaction, 8, 'Failed to collect signature'),
  cannotSwipeChipCard: payPalError(domain.transaction, 9, 'Cannot swipe a chip card'),
  mustSwipeCard: payPalError(domain.transaction, 10, 'Must swipe the card'),
  refundCardMismatch: payPalError(domain.transaction, 11, 'Card presented for refund is not the one used for the original payment'),
  cardTypeMismatch: payPalError(domain.transaction, 12, 'Presented card is not of the expected type'),
  locationError: payPalError(domain.transaction, 13, 'Unable to retrieve location information'),
  missingInvoiceId: payPalError(domain.transaction, 14, 'Invoice ID is required to complete this refund.'),
  missingTransactionNumber: payPalError(domain.transaction, 15, 'Transaction number is required to complete this refund.'),
  cannotDiscardCard: payPalError(domain.transaction, 16, 'Cannot discard the presented card'),
  multipleContactlessCardsDetected: payPalError(domain.transaction, 17, 'Multiple Contactless Cards Detected.'),
  tryDifferentInterface: payPalError(domain.transaction, 18, 'Try different interface'),
  cannotClearActiveTransaction: payPalError(domain.transaction, 19, 'Cannot clear transaction when payment is in progress'),
  authorizationFailed: payPalError(domain.transaction, 20, 'The authorization request has failed'),
  captureFailed: payPalError(domain.transaction, 21, 'The capture request has failed'),
  invalidAuthorization: payPalError(domain.transaction, 22, 'Authorization is not possible on this payment mode'),
  retrieveAuthListFailed: payPalError(domain.transaction, 23, 'Unable to retrieve list of authorizations'),
  voidFailed: payPalError(domain.transaction, 24, 'Unable to void the authorization')
};

var merchant = exports.merchant = {
  failedToLoad: payPalError(domain.merchant, 1, 'Failed to load the merchant information.'),
  requiredInfoNotLoaded: payPalError(domain.merchant, 2, 'Failed to load required merchant information'),
  notInitialized: payPalError(domain.merchant, 3, 'Merchant not initialized'),
  accessTokenNotProvided: payPalError(domain.merchant, 4, 'Access token is missing from provided credentials'),
  environmentNotProvided: payPalError(domain.merchant, 5, 'Environment is missing from provided credentials'),
  merchantDataNotProvided: payPalError(domain.merchant, 6, 'Data required to create the merchant object are missing.'),
  merchantUserInfoNotProvided: payPalError(domain.merchant, 7, 'User info data required to create the merchant object are missing.'),
  merchantStatusNotProvided: payPalError(domain.merchant, 8, 'Status data required to create the merchant object are missing.'),
  invalidToken: payPalError(domain.merchant, 9, 'The token is either invalid or missing.'),
  tokenDataNotProvided: payPalError(domain.merchant, 10, 'The token data to build the composite token' + ' is either invalid or missing.')
};

// The error codes used here must match the codes returned by the retail payments endpoint
var retail = exports.retail = {
  nfcPaymentDeclined: payPalError(domain.retail, 600075),
  incorrectOnlinePin: payPalError(domain.retail, 6000164),
  onlinePinMaxRetryExceed: payPalError(domain.retail, 6000165),
  contactIssuer: payPalError(domain.retail, 580031)
};

var network = exports.network = {
  requestFailed: payPalError(domain.network, 1, 'Request failed'),
  networkOffline: payPalError(domain.network, -1001)
};

var sdk = exports.sdk = {
  userCancelled: payPalError(domain.sdk, 1, 'Action was cancelled by user'),
  fileNotFound: payPalError(domain.sdk, 2, 'Unable to retrieve file from device storage'),
  validationError: payPalError(domain.sdk, 3, 'The arguments passed are invalid.'),
  cardReaderScannerNotInitialized: payPalError(domain.sdk, 4, 'Card reader scanner not initialized'),
  noReaderFound: payPalError(domain.sdk, 5, 'No reader found'),
  bluetoothDisabled: payPalError(domain.sdk, 6, 'Bluetooth disabled')
};

},{"manticore-paypalerror":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-paypalerror/build/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/js/debug.js":[function(require,module,exports){
'use strict';

var m = require('manticore');

m.miuraSwRepo = 'dev-stage-2';

},{"manticore":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore/browser.js"}],"/Users/aravidas/Documents/Git/retail-sdk/js/flows/BaseFlowAsync.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

var _manticoreLog = require('manticore-log');

var _manticoreLog2 = _interopRequireDefault(_manticoreLog);

var _flowAsync = require('../common/flowAsync');

var _flowAsync2 = _interopRequireDefault(_flowAsync);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

var Log = (0, _manticoreLog2.default)('flow.baseFlow');

/**
 * Base class to manage All flows..
 */

var BaseFlowAsync = function () {
  function BaseFlowAsync() {
    _classCallCheck(this, BaseFlowAsync);
  } // eslint-disable-line no-useless-constructor


  /**
   * Sets the flow steps for the controller
   * @param flowName - Name for the flow
   * @param flowSteps - Sequence flow steps that will be executed by the flow controller
   * @returns {BaseFlowAsync} - Returns 'this' object for enabling Fluent Interface
   */


  BaseFlowAsync.prototype.setFlowSteps = function setFlowSteps(flowName, flowSteps) {
    this.flowSteps = flowSteps;
    this.flow = new _flowAsync2.default(this, this.flowSteps);
    this.flow.name = flowName;
    return this;
  };

  BaseFlowAsync.prototype.addFlowEndedHandler = function addFlowEndedHandler(handler) {
    this._check();
    this.flow.once('ended', handler);
    return this;
  };

  BaseFlowAsync.prototype.addFlowAbortedHandler = function addFlowAbortedHandler(handler) {
    this._check();
    this.flow.once('aborted', handler);
    return this;
  };

  BaseFlowAsync.prototype.addFlowCompletedHandler = function addFlowCompletedHandler(handler) {
    this._check();
    this.flow.once('completed', handler);
    return this;
  };

  BaseFlowAsync.prototype._check = function _check() {
    if (!this.flow) {
      throw new Error('Flow needs to be initialized first');
    }
  };

  /**
   * Sets the flow that should be triggered on completion of the flowSteps registered via 'setFlowSteps' function
   * @param completionFlowName - Name fr the completion flow
   * @param flowCompletionSteps - List of flow steps
   * @returns {BaseFlowAsync} - Returns 'this' object for enabling Fluent Interface
   */


  BaseFlowAsync.prototype.setCompletionSteps = function setCompletionSteps(completionFlowName, flowCompletionSteps) {
    this.completionFlowName = completionFlowName;
    this.completionFlowSteps = flowCompletionSteps;
    return this;
  };

  /**
   * Displays an alert dialog on the application.
   * @param messageHelperFunc A function that contains the message to be displayed.
   * @returns {Function} The current flow step.
   */


  BaseFlowAsync.prototype.createFlowMessageStep = function createFlowMessageStep(messageHelperFunc) {
    var _this = this;

    return function (flow) {
      messageHelperFunc(_this.context, flow.data, function (alert) {
        _this.alert = alert;
        flow.next();
      });
    };
  };

  /**
   * Starts executing the flow steps that were set by the 'setFlowSteps' function
   */


  BaseFlowAsync.prototype.startFlow = function startFlow() {
    var _this2 = this;

    return regeneratorRuntime.async(function startFlow$(_context) {
      while (1) {
        switch (_context.prev = _context.next) {
          case 0:
            Log.debug(function () {
              return 'Start executing ' + _this2.flowSteps.length + ' steps for ' + _this2.flow.name + ' flow';
            });
            _context.next = 3;
            return regeneratorRuntime.awrap(this.flow.start());

          case 3:
          case 'end':
            return _context.stop();
        }
      }
    }, null, this);
  };

  return BaseFlowAsync;
}();

exports.default = BaseFlowAsync;

},{"../common/flowAsync":"/Users/aravidas/Documents/Git/retail-sdk/js/common/flowAsync.js","manticore-log":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-log/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/js/flows/BaseTransactionFlow.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

var _manticoreLog = require('manticore-log');

var _manticoreLog2 = _interopRequireDefault(_manticoreLog);

var _retailPaymentDevice = require('retail-payment-device');

var _paypalrestManticore = require('paypalrest-manticore');

var _manticoreUtil = require('manticore-util');

var _sdkErrors = require('../common/sdkErrors');

var _PaymentErrorHandler = require('./PaymentErrorHandler');

var _PaymentErrorHandler2 = _interopRequireDefault(_PaymentErrorHandler);

var _flow = require('../common/flow');

var _flow2 = _interopRequireDefault(_flow);

var _cal = require('../common/cal');

var Cal = _interopRequireWildcard(_cal);

var _messageHelper = require('./messageHelper');

var messageHelper = _interopRequireWildcard(_messageHelper);

var _TokenExpirationHandler = require('../common/TokenExpirationHandler');

var _TokenExpirationHandler2 = _interopRequireDefault(_TokenExpirationHandler);

var _Merchant = require('../common/Merchant');

var _Merchant2 = _interopRequireDefault(_Merchant);

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

var Log = (0, _manticoreLog2.default)('flow.baseTransactionFlow');
var AuthCode = _retailPaymentDevice.PaymentDevice.authCode;

/**
 * Parent class to manage payment flows (swipe, nfc and emv)
 */

var BaseTransactionFlow = function () {
  function BaseTransactionFlow(card, context, onCompleteCallback) {
    var _this = this;

    _classCallCheck(this, BaseTransactionFlow);

    this.card = card;
    this.context = context;
    this.onCompleteCallback = onCompleteCallback;
    this.transactionCancelRequested = function () {
      Log.info('Transaction cancel was requested from device ' + _this.card.reader.id);
      _this.card.reader.abortTransaction(_this.context, function () {
        Log.info('Deactivated card reader ' + _this.card.reader.id);
        _this.flow.abortFlow(_retailPaymentDevice.deviceError.paymentCancelled);
      });
    };
    this.transactionCancelled = function () {
      Log.info('Transaction on device ' + _this.card.reader.id + ' was cancelled');
      _this.flow.abortFlow(_retailPaymentDevice.deviceError.paymentCancelled);
    };
  }

  /**
   * Sets the flow steps for the controller
   * @param flowName - Name for the flow
   * @param flowSteps - Sequence flow steps that will be executed by the flow controller
   * @returns {BaseTransactionFlow} - Returns 'this' object for enabling Fluent Interface
   */


  BaseTransactionFlow.prototype.setFlowSteps = function setFlowSteps(flowName, flowSteps) {
    this.flowName = flowName;
    this.flowSteps = flowSteps;
    this.flow = new _flow2.default(this, this.flowSteps);
    return this;
  };

  BaseTransactionFlow.prototype.addFlowEndedHandler = function addFlowEndedHandler(handler) {
    if (this.flow === undefined) {
      throw new Error('Flow needs to be initialized first');
    }
    this.flow.on('ended', handler);
    return this;
  };

  /**
   * Sets the flow that should be triggered on completion of the flowSteps registered via 'setFlowSteps' function
   * @param completionFlowName - Name fr the completion flow
   * @param flowCompletionSteps - List of flow steps
   * @returns {BaseTransactionFlow} - Returns 'this' object for enabling Fluent Interface
   */


  BaseTransactionFlow.prototype.setCompletionSteps = function setCompletionSteps(completionFlowName, flowCompletionSteps) {
    this.completionFlowName = completionFlowName;
    this.completionFlowSteps = flowCompletionSteps;
    return this;
  };

  /**
   * Starts executing the flow steps that were set by the 'setFlowSteps' function
   */


  BaseTransactionFlow.prototype.startFlow = function startFlow() {
    var _this2 = this;

    Log.debug(function () {
      return 'Start executing ' + _this2.flowSteps.length + ' steps for ' + _this2.flowName + ' flow';
    });
    this.flow.name = this.flowName;
    this.context.setPaymentFlowStarted();
    this.flow.on('completed', function (data) {
      _this2.completeTransaction(data);
    });
    this.flow.on('aborted', function (data) {
      _this2.abortTransaction(data);
    });

    this.flow.start();
  };

  BaseTransactionFlow.prototype.invokeCompleteCallback = function invokeCompleteCallback(flowData, action, opt) {
    if (flowData.alert && (action === _PaymentErrorHandler2.default.action.abort || action === _PaymentErrorHandler2.default.action.offlineDecline)) {
      flowData.alert.dismiss();
    }
    var transactionRecord = flowData.tx || {};
    transactionRecord.card = transactionRecord.card || this.card;
    this.onCompleteCallback(flowData.error, action, transactionRecord, opt);
  };

  BaseTransactionFlow.prototype.completeTransaction = function completeTransaction(data, action) {
    var _this3 = this;

    Log.debug(function () {
      return 'Starting completion steps for ' + _this3.flowName + ' flow';
    });
    if (!this.completionFlowSteps) {
      Log.debug(function () {
        return 'Flow ended and completion steps not defined. Proceeding to invoke complete callback';
      });
      this.invokeCompleteCallback(data, action);
      return;
    }

    this.completionFlow = new _flow2.default(this, this.completionFlowSteps);
    this.completionFlow.name = this.completionFlowName;
    this.completionFlow.data = data;
    this.completionFlow.on('ended', function (dt) {
      Log.debug(function () {
        return 'Flow ended. Proceeding to invoke flow complete callback (error: ' + dt.error + ')';
      });
      _this3.invokeCompleteCallback(dt, action);
    });

    if (this.completionFlow) {
      if (this.card && this.card.reader) {
        // Reset the terminal
        this.card.reader.postTransactionCleanup(function () {
          _this3.completionFlow.start();
        });
      } else {
        this.completionFlow.start();
      }
    } else {
      Log.debug('Did not find any completionFlow');
    }
  };

  BaseTransactionFlow.prototype.abortTransaction = function abortTransaction(data) {
    var _this4 = this;

    Log.debug(function () {
      return 'Aborting ' + _this4.context.id;
    });
    this.voidPaymentIfApplicable(data);
    var err = data.error;
    var formFactor = this.card && this.card.formFactor;
    var reader = this.card && this.card.reader;

    if (!err) {
      if (reader) {
        reader.display({
          id: _retailPaymentDevice.PaymentDevice.Message.TransactionCancelled,
          substitutions: messageHelper.formattedInvoiceTotal(this.context.invoice)
        }, function () {
          return _this4.completeTransaction(data);
        });
      } else {
        this.completeTransaction(data);
      }
      return;
    }

    Log.warn('Flow (' + (0, _manticoreUtil.getPropertyName)(_retailPaymentDevice.FormFactor, formFactor) + ') aborted with error code: \'' + err.code + '\' domain: ' + err.domain + '\n' + err);
    if (this.context.timeoutHandler && err.domain === _paypalrestManticore.paypalRestErrorDomain && err.code === _paypalrestManticore.restError.unauthorized.code) {
      var timeoutHandler = new _TokenExpirationHandler2.default(function (timeoutAction) {
        Log.debug(function () {
          return 'TokenExpirationHandler was invoked with handler: ' + (0, _manticoreUtil.getPropertyName)(_TokenExpirationHandler2.default.action, timeoutAction);
        });
        if (timeoutAction === _TokenExpirationHandler2.default.action.resume) {
          throw new Error('Not implemented');
        }
        _this4.invokeCompleteCallback(data);
      });
      if (data.alert) {
        data.alert.dismiss();
      }
      this.context.timeoutHandler(timeoutHandler);
      return;
    }

    var handler = new _PaymentErrorHandler2.default(this.context);
    handler.handle(err, formFactor, reader, function (action, opt) {
      if (action === _PaymentErrorHandler2.default.action.abort) {
        _this4.completeTransaction(data, action);
      } else {
        _this4.invokeCompleteCallback(data, action, opt);
      }
    });
  };

  BaseTransactionFlow.prototype.voidPaymentIfApplicable = function voidPaymentIfApplicable(data) {
    var _this5 = this;

    Log.debug(function () {
      return 'voidPaymentIfApplicable data.error: ' + JSON.stringify(data.error);
    });
    if (!(data && data.tx && data.tx.transactionHandle)) {
      Log.debug('Will not void transaction as transaction handle was not assigned');
      return;
    }

    if (data.error && data.error.code === _sdkErrors.retail.contactIssuer.code) {
      Log.debug(function () {
        return 'Will not void transaction. Declined with error: ' + JSON.stringify(data.error);
      });
      return;
    }

    var body = { invoiceId: this.context.invoice.payPalId };
    if (data.tx.responseCode) {
      body.responseCode = data.tx.responseCode;
    }

    if (data.cardResponse && data.cardResponse.apdu && data.cardResponse.apdu.data) {
      body.emvData = data.cardResponse.apdu.data.toString('hex');
    }

    var transactionQueryParam = data.tx.transactionHandle;
    if (this.context.type === _retailPaymentDevice.TransactionType.Auth) {
      transactionQueryParam = data.tx.transactionNumber;
    }
    var op = 'checkouts/' + transactionQueryParam + '/void';
    Log.debug(function () {
      return 'Invoice void request:' + JSON.stringify(body, null, 4);
    });
    _Merchant2.default.active.request({
      service: 'retail',
      op: op,
      format: 'json',
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(body)
    }, function (error, voidRz) {
      if (error) {
        Log.error('Void request ' + op + ' returned an error for payload: ' + JSON.stringify(body, null, 4) + '\n' + error + ' ');
        return;
      }
      Log.info('Successfully voided invoice id: ' + _this5.context.invoice.payPalId + '. ' + JSON.stringify(voidRz));
    });
  };

  BaseTransactionFlow.prototype.saveInvoiceStep = function saveInvoiceStep(flow) {
    var _this6 = this;

    Log.debug(function () {
      return 'Saving invoice\n' + JSON.stringify(_this6.context.invoice, null, 4);
    });
    this.context.invoice.save(function (error) {
      if (error && _this6.card && _this6.card.reader) {
        Log.error('Unable to save invoice. Error: ' + error + '\n' + JSON.stringify(_this6.context.invoice, null, 4));
        var authCode = AuthCode.TransactionFailure;
        if (error.code === _sdkErrors.network.networkOffline.code) {
          authCode = AuthCode.NoNetwork;
        }
        Log.debug('Pushing authCode : ' + authCode);
        _this6.card.reader.completeTransaction(authCode, function (err) {
          if (err) {
            Log.error('Error response on pushing auth code to terminal ' + JSON.stringify(err));
          }
          return flow.abortFlow(error);
        });
      } else if (error) {
        flow.abortFlow(error);
      } else {
        Log.debug(function () {
          return 'Saved invoice successfully ' + JSON.stringify(_this6.context.invoice, null, 4);
        });
        Cal.setInvoiceId(_this6.context.invoice.payPalId);
        flow.next();
      }
    });
  };

  BaseTransactionFlow.prototype.createFlowMessageStep = function createFlowMessageStep(messageHelperFunc) {
    var _this7 = this;

    return function (flow) {
      messageHelperFunc(_this7.context, flow.data, function () {
        flow.next();
      });
    };
  };

  return BaseTransactionFlow;
}();

exports.default = BaseTransactionFlow;

},{"../common/Merchant":"/Users/aravidas/Documents/Git/retail-sdk/js/common/Merchant.js","../common/TokenExpirationHandler":"/Users/aravidas/Documents/Git/retail-sdk/js/common/TokenExpirationHandler.js","../common/cal":"/Users/aravidas/Documents/Git/retail-sdk/js/common/cal.js","../common/flow":"/Users/aravidas/Documents/Git/retail-sdk/js/common/flow.js","../common/sdkErrors":"/Users/aravidas/Documents/Git/retail-sdk/js/common/sdkErrors.js","./PaymentErrorHandler":"/Users/aravidas/Documents/Git/retail-sdk/js/flows/PaymentErrorHandler.js","./messageHelper":"/Users/aravidas/Documents/Git/retail-sdk/js/flows/messageHelper.js","manticore-log":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-log/index.js","manticore-util":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-util/build/index.js","paypalrest-manticore":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypalrest-manticore/build/index.js","retail-payment-device":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/js/flows/CreditCardFlow.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

var _manticoreLog = require('manticore-log');

var _manticoreLog2 = _interopRequireDefault(_manticoreLog);

var _retailPaymentDevice = require('retail-payment-device');

var _messageHelper = require('./messageHelper');

var messageHelper = _interopRequireWildcard(_messageHelper);

var _BaseTransactionFlow2 = require('./BaseTransactionFlow');

var _BaseTransactionFlow3 = _interopRequireDefault(_BaseTransactionFlow2);

var _MerchantTakePaymentStep = require('./steps/MerchantTakePaymentStep');

var _MerchantTakePaymentStep2 = _interopRequireDefault(_MerchantTakePaymentStep);

var _SignatureStep = require('./steps/SignatureStep');

var _SignatureStep2 = _interopRequireDefault(_SignatureStep);

var _FinalizePaymentStep = require('./steps/FinalizePaymentStep');

var _FinalizePaymentStep2 = _interopRequireDefault(_FinalizePaymentStep);

var _UpdateInvoicePaymentStep = require('./steps/UpdateInvoicePaymentStep');

var _UpdateInvoicePaymentStep2 = _interopRequireDefault(_UpdateInvoicePaymentStep);

var _RemoveCardStep = require('./steps/RemoveCardStep');

var _RemoveCardStep2 = _interopRequireDefault(_RemoveCardStep);

var _ReceiptStep = require('./steps/ReceiptStep');

var _ReceiptStep2 = _interopRequireDefault(_ReceiptStep);

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (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 } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var Log = (0, _manticoreLog2.default)('flow.creditCardFlow');

var CreditCardFlow = function (_BaseTransactionFlow) {
  _inherits(CreditCardFlow, _BaseTransactionFlow);

  function CreditCardFlow(card, context, callback) {
    _classCallCheck(this, CreditCardFlow);

    Log.debug('Initializing Credit Flow');

    var _this = _possibleConstructorReturn(this, _BaseTransactionFlow.call(this, card, context, callback));

    _BaseTransactionFlow.prototype.setFlowSteps.call(_this, 'Credit', [function addPaymentCancelListeners(flow) {
      if (context.allowInProgressPaymentCancel) {
        this.card.reader.once(_retailPaymentDevice.PaymentDevice.Event.cardRemoved, this.transactionCancelRequested);
        this.card.reader.once(_retailPaymentDevice.PaymentDevice.Event.cancelRequested, this.transactionCancelRequested);
        this.card.reader.once(_retailPaymentDevice.PaymentDevice.Event.disconnected, this.transactionCancelRequested);
        this.card.reader.once(_retailPaymentDevice.PaymentDevice.Event.cancelled, this.transactionCancelled);
      }
      flow.next();
    }, _this.createFlowMessageStep(messageHelper.showProcessingMessage), _this.saveInvoiceStep, new _MerchantTakePaymentStep2.default(context, _this.voidPaymentIfApplicable).flowStep, new _SignatureStep2.default(context).flowStep, _this.createFlowMessageStep(messageHelper.showFinalizeMessage), function removePaymentCancelListeners(flow) {
      this._removePaymentCancelListeners();
      flow.next();
    }, new _FinalizePaymentStep2.default(context).flowStep, new _RemoveCardStep2.default(context).flowStep, _this.createFlowMessageStep(messageHelper.showCompleteMessage)]).addFlowEndedHandler(function () {
      return _this._removePaymentCancelListeners();
    }).setCompletionSteps('Credit-Receipt', [new _UpdateInvoicePaymentStep2.default(context).flowStep, _this.createFlowMessageStep(messageHelper.ifFailureShowMessage), new _ReceiptStep2.default(_this.context).flowStep]).startFlow();
    return _this;
  }

  CreditCardFlow.prototype._removePaymentCancelListeners = function _removePaymentCancelListeners() {
    var r = this.card.reader;
    if (this.context.allowInProgressPaymentCancel) {
      r.removeListener(_retailPaymentDevice.PaymentDevice.Event.cardRemoved, this.transactionCancelRequested);
      r.removeListener(_retailPaymentDevice.PaymentDevice.Event.cancelRequested, this.transactionCancelRequested);
      r.removeListener(_retailPaymentDevice.PaymentDevice.Event.disconnected, this.transactionCancelRequested);
      r.removeListener(_retailPaymentDevice.PaymentDevice.Event.cancelled, this.transactionCancelled);
    }
  };

  return CreditCardFlow;
}(_BaseTransactionFlow3.default);

exports.default = CreditCardFlow;

},{"./BaseTransactionFlow":"/Users/aravidas/Documents/Git/retail-sdk/js/flows/BaseTransactionFlow.js","./messageHelper":"/Users/aravidas/Documents/Git/retail-sdk/js/flows/messageHelper.js","./steps/FinalizePaymentStep":"/Users/aravidas/Documents/Git/retail-sdk/js/flows/steps/FinalizePaymentStep.js","./steps/MerchantTakePaymentStep":"/Users/aravidas/Documents/Git/retail-sdk/js/flows/steps/MerchantTakePaymentStep.js","./steps/ReceiptStep":"/Users/aravidas/Documents/Git/retail-sdk/js/flows/steps/ReceiptStep.js","./steps/RemoveCardStep":"/Users/aravidas/Documents/Git/retail-sdk/js/flows/steps/RemoveCardStep.js","./steps/SignatureStep":"/Users/aravidas/Documents/Git/retail-sdk/js/flows/steps/SignatureStep.js","./steps/UpdateInvoicePaymentStep":"/Users/aravidas/Documents/Git/retail-sdk/js/flows/steps/UpdateInvoicePaymentStep.js","manticore-log":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-log/index.js","retail-payment-device":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/js/flows/OfferReceiptFlow.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

var _manticoreLog = require('manticore-log');

var _manticoreLog2 = _interopRequireDefault(_manticoreLog);

var _flow = require('../common/flow');

var _flow2 = _interopRequireDefault(_flow);

var _ReceiptStep = require('./steps/ReceiptStep');

var _ReceiptStep2 = _interopRequireDefault(_ReceiptStep);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

var Log = (0, _manticoreLog2.default)('flow.OfferReceipt');

var OfferReceiptFlow = function () {
  function OfferReceiptFlow(err, context, callback) {
    _classCallCheck(this, OfferReceiptFlow);

    this.err = err;
    this.context = context;
    this.callback = callback;
    Log.debug('Initializing Offer receipt flow');
  }

  OfferReceiptFlow.prototype.startFlow = function startFlow() {
    var _this = this;

    this.offerReceipt = new _flow2.default(this, [new _ReceiptStep2.default(this.context).flowStep]);

    this.offerReceipt.data.error = this.err;
    this.offerReceipt.on('ended', function (data) {
      return _this.callback(data);
    });
    this.offerReceipt.start();
  };

  return OfferReceiptFlow;
}();

exports.default = OfferReceiptFlow;

},{"../common/flow":"/Users/aravidas/Documents/Git/retail-sdk/js/common/flow.js","./steps/ReceiptStep":"/Users/aravidas/Documents/Git/retail-sdk/js/flows/steps/ReceiptStep.js","manticore-log":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-log/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/js/flows/OfflineDeclineFlow.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

var _manticoreLog = require('manticore-log');

var _manticoreLog2 = _interopRequireDefault(_manticoreLog);

var _paypalrestManticore = require('paypalrest-manticore');

var _manticoreUtil = require('manticore-util');

var _flow = require('../common/flow');

var _flow2 = _interopRequireDefault(_flow);

var _ReceiptStep = require('./steps/ReceiptStep');

var _ReceiptStep2 = _interopRequireDefault(_ReceiptStep);

var _l10n = require('../common/l10n');

var _l10n2 = _interopRequireDefault(_l10n);

var _messageHelper = require('./messageHelper');

var _retailSDKUtil = require('../common/retailSDKUtil');

var retailSDKUtils = _interopRequireWildcard(_retailSDKUtil);

var _TokenExpirationHandler = require('../common/TokenExpirationHandler');

var _TokenExpirationHandler2 = _interopRequireDefault(_TokenExpirationHandler);

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

var Log = (0, _manticoreLog2.default)('flow.OfflineDeclineFlow');

var OfflineDeclineFlow = function () {
  function OfflineDeclineFlow(err, context, callback) {
    _classCallCheck(this, OfflineDeclineFlow);

    this.err = err;
    this.context = context;
    this.callback = callback;
    Log.debug('Initializing Offline Decline Flow');
  }

  OfflineDeclineFlow.prototype.startFlow = function startFlow() {
    var _this2 = this;

    (0, _messageHelper.showSimpleMessage)((0, _l10n2.default)('Cancelling transaction..', ''), null, false, this);
    this.cancellationFlow = new _flow2.default(this, [function saveInvoiceStep(flow) {
      var _this = this;

      this.context.invoice.isCancelled = retailSDKUtils.transactionCancelledError(this.err);
      this.context.invoice.isFailed = true;
      this.context.invoice.save(function (e) {
        if (e) {
          Log.error('Unable to save invoice. Error: ' + e + '\n' + JSON.stringify(_this.context.invoice, null, 4)); // eslint-disable-line max-len
          flow.abortFlow(e);
          return;
        }
        flow.next();
      });
    }, new _ReceiptStep2.default(this.context).flowStep]);

    this.cancellationFlow.data.error = this.err;
    this.cancellationFlow.on('ended', function (data) {
      return _this2.callback(data);
    });
    this.cancellationFlow.on('aborted', function (data) {
      return _this2.abortedFlow(data);
    });
    this.cancellationFlow.start();
  };

  OfflineDeclineFlow.prototype.abortedFlow = function abortedFlow(data) {
    var err = data.error;
    if (!err) {
      return;
    }
    Log.warn('OfflineDeclineFlow aborted with error code: \'' + err.code + '\' domain: ' + err.domain + ' \n' + err);
    if (this.context.timeoutHandler && err.domain === _paypalrestManticore.paypalRestErrorDomain && err.code === _paypalrestManticore.restError.unauthorized.code) {
      var timeoutHandler = new _TokenExpirationHandler2.default(function (timeoutAction) {
        Log.debug(function () {
          return 'TokenExpirationHandler was invoked with handler: ' + (0, _manticoreUtil.getPropertyName)(_TokenExpirationHandler2.default.action, timeoutAction);
        });
        if (timeoutAction === _TokenExpirationHandler2.default.action.resume) {
          throw new Error('Not implemented');
        }
      });
      this.context.timeoutHandler(timeoutHandler);
      return;
    }
    Log.warn('OfflineDeclineFlow aborted with error code: \'' + err.code + '\' domain: ' + err.domain + ' might need proper treatment!');
  };

  return OfflineDeclineFlow;
}();

exports.default = OfflineDeclineFlow;

},{"../common/TokenExpirationHandler":"/Users/aravidas/Documents/Git/retail-sdk/js/common/TokenExpirationHandler.js","../common/flow":"/Users/aravidas/Documents/Git/retail-sdk/js/common/flow.js","../common/l10n":"/Users/aravidas/Documents/Git/retail-sdk/js/common/l10n.js","../common/retailSDKUtil":"/Users/aravidas/Documents/Git/retail-sdk/js/common/retailSDKUtil.js","./messageHelper":"/Users/aravidas/Documents/Git/retail-sdk/js/flows/messageHelper.js","./steps/ReceiptStep":"/Users/aravidas/Documents/Git/retail-sdk/js/flows/steps/ReceiptStep.js","manticore-log":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-log/index.js","manticore-util":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-util/build/index.js","paypalrest-manticore":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypalrest-manticore/build/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/js/flows/PaymentErrorHandler.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

var _manticoreLog = require('manticore-log');

var _manticoreLog2 = _interopRequireDefault(_manticoreLog);

var _manticore = require('manticore');

var _manticore2 = _interopRequireDefault(_manticore);

var _retailPaymentDevice = require('retail-payment-device');

var _manticoreUtil = require('manticore-util');

var _l10n = require('../common/l10n');

var _l10n2 = _interopRequireDefault(_l10n);

var _sdkErrors = require('../common/sdkErrors');

var _messageHelper = require('./messageHelper');

var messageHelper = _interopRequireWildcard(_messageHelper);

var _Merchant = require('../common/Merchant');

var _Merchant2 = _interopRequireDefault(_Merchant);

var _transactionStates = require('../transaction/transactionStates');

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

var Log = (0, _manticoreLog2.default)('flow.paymentErrorHandler');

/**
 * The PaymentErrorHandler class is responsible for displaying appropriate alerts on the App and terminal based on
 * the errorCode and formFactor properties on the error object.
 */

var PaymentErrorHandler = function () {
  function PaymentErrorHandler(context) {
    var _this = this,
        _nfcHandlersForDevice,
        _insertHandlersForDev,
        _swipeHandlersForDevi,
        _commonHandlersForDev,
        _nfcHandlersForApiErr,
        _insertHandlersForApi,
        _swiperHandlersForApi,
        _commonHandlersForApi,
        _swipeHandlersForTran,
        _multipleContactlessC,
        _commonHandlersForTra,
        _deviceErrorDomain,
        _sdkErrorDomain$retai,
        _sdkErrorDomain$trans,
        _errorHandlers;

    _classCallCheck(this, PaymentErrorHandler);

    this.context = context;
    this.formattedAmount = this.context.isRefund() && this.context.refundAmount ? messageHelper.formattedRefundTotal(this.context) : messageHelper.formattedInvoiceTotal(this.context.invoice);
    var action = PaymentErrorHandler.action;
    var errors = PaymentErrorHandler.errors;
    var displayMessage = PaymentErrorHandler.displayMessage;
    var nfcContactIssuer = void 0;
    var swipeContactIssuer = void 0;
    var nfcHandlersForDeviceErrors = (_nfcHandlersForDevice = {}, _nfcHandlersForDevice[_retailPaymentDevice.deviceError.nfcTimeout.code] = function (pd, cb) {
      Log.debug(function () {
        return 'Received an NFC timeout. Retrying again.';
      });
      cb(action.retry);
    }, _nfcHandlersForDevice[_retailPaymentDevice.deviceError.nfcNotAllowed.code] = function (pd, cb) {
      _this._nfcPaymentDeclineErrorHandler(pd, function (performAction) {
        if (performAction === PaymentErrorHandler.action.retryWithInsertOrSwipe) {
          cb(performAction);
        } else {
          cb(action.offlineDecline);
        }
      });
    }, _nfcHandlersForDevice[_retailPaymentDevice.deviceError.tryDifferentCard.code] = function (pd, cb) {
      _this._updateDisplay(pd, _retailPaymentDevice.PaymentDevice.Message.UnableToReadNfcCard, _this.formattedAmount, {
        title: (0, _l10n2.default)('Tx.Alert.TapDifferentCard.Title'),
        message: (0, _l10n2.default)('Tx.Alert.TapDifferentCard.Msg'),
        cancel: (0, _l10n2.default)('Ok')
      }, function () {
        _this.context.promptForPaymentInstrument();
        cb(action.retry);
      });
    }, _nfcHandlersForDevice[_retailPaymentDevice.deviceError.contactIssuer.code] = nfcContactIssuer = function nfcContactIssuer(pd, cb) {
      _this._updateDisplay(pd, _retailPaymentDevice.PaymentDevice.Message.ContactIssuer, _this.formattedAmount, {
        title: (0, _l10n2.default)('Tx.Alert.BlockedCardTapped.Title'),
        message: (0, _l10n2.default)('Tx.Alert.BlockedCardTapped.Msg'),
        cancel: (0, _l10n2.default)('Ok')
      }, function () {
        return cb(action.abort);
      });
    }, _nfcHandlersForDevice[_retailPaymentDevice.deviceError.contactlessPaymentAbortedByCardInsert.code] = PaymentErrorHandler._doNothing, _nfcHandlersForDevice[_retailPaymentDevice.deviceError.contactlessPaymentAbortedByCardSwipe.code] = PaymentErrorHandler._doNothing, _nfcHandlersForDevice);

    var insertHandlersForDeviceErrors = (_insertHandlersForDev = {}, _insertHandlersForDev[_retailPaymentDevice.deviceError.cardBlocked.code] = function (pd, cb) {
      return _this._insertContactIssuer(pd, cb, true);
    }, _insertHandlersForDev[_retailPaymentDevice.deviceError.contactIssuer.code] = function (pd, cb) {
      return _this._insertContactIssuer(pd, cb, true);
    }, _insertHandlersForDev[_retailPaymentDevice.deviceError.smartCardNotInSlot.code] = function (pd, cb) {
      _this._updateDisplay(pd, _retailPaymentDevice.PaymentDevice.Message.TransactionCancelled, _this.formattedAmount, {
        title: (0, _l10n2.default)('EMV.Cancelling')
      }, function () {
        pd.abortTransaction(_this.context);
        cb(action.offlineDecline);
      });
    }, _insertHandlersForDev[_retailPaymentDevice.deviceError.lowOnBattery.code] = function (pd, cb) {
      Log.debug(function () {
        return 'low battery error occured!!! ' + pd.id;
      });
      _this._updateDisplay(null, null, null, {
        title: (0, _l10n2.default)('Tx.Alert.LowBattery.Title'),
        message: (0, _l10n2.default)('Tx.Alert.LowBattery.Msg'),
        cancel: (0, _l10n2.default)('Cancel')
      }, function () {
        pd.disconnect();
        cb(action.abort);
      });
    }, _insertHandlersForDev[_retailPaymentDevice.deviceError.invalidChip.code] = function (pd, cb) {
      Log.debug(function () {
        return 'Invalid chip card (Attempt: ' + (_this.context.retryCountInvalidChip + 1) + ')';
      });
      if (_this.context.retryCountInvalidChip >= _retailPaymentDevice.PaymentDevice.constant.InvalidChipRetryCount) {
        _this._updateDisplay(null, null, null, {
          title: (0, _l10n2.default)('Tx.Alert.ReadyForSwipeOnly.Title'),
          message: (0, _l10n2.default)('Tx.Alert.ReadyForSwipeOnly.Msg'),
          imageIcon: 'img_emv_swipe',
          cancel: (0, _l10n2.default)('Ok')
        }, function () {
          if (_this.alert) {
            _this.alert.dismiss();
          }
        });
        _this.context.allowFallBackSwipe = true;
        pd.waitForCardRemoval(function () {
          cb(action.retryWithSwipe);
        });
        return;
      }

      _this.context.retryCountInvalidChip += 1;
      pd.waitForCardRemoval(function () {
        _this.context.promptForPaymentInstrument(null, new Set([_retailPaymentDevice.FormFactor.MagneticCardSwipe, _retailPaymentDevice.FormFactor.Chip]));
        cb(action.retryWithInsertOrSwipe);
      });

      _this._updateDisplay(null, null, null, {
        title: (0, _l10n2.default)('Tx.Alert.UnsuccessfulInsert.Title'),
        message: (0, _l10n2.default)('Tx.Alert.UnsuccessfulInsert.Msg'),
        imageIcon: 'img_emv_insert',
        cancel: (0, _l10n2.default)('Cancel')
      }, function () {
        return cb(action.abort);
      });
    }, _insertHandlersForDev);

    var swipeHandlersForDeviceErrors = (_swipeHandlersForDevi = {}, _swipeHandlersForDevi[_retailPaymentDevice.deviceError.contactIssuer.code] = swipeContactIssuer = function swipeContactIssuer(pd, cb) {
      _this._updateDisplay(pd, _retailPaymentDevice.PaymentDevice.Message.ContactIssuer, _this.formattedAmount, {
        title: (0, _l10n2.default)('Tx.Alert.BlockedCardSwiped.Title'),
        message: (0, _l10n2.default)('Tx.Alert.BlockedCardSwiped.Msg'),
        cancel: (0, _l10n2.default)('Ok')
      }, function () {
        return cb(action.abort);
      });
    }, _swipeHandlersForDevi);

    // Handler for errors from payment device that apply to all card presentation types
    var commonHandlersForDeviceErrors = (_commonHandlersForDev = {}, _commonHandlersForDev[_retailPaymentDevice.deviceError.mustSwipeCard.code] = function (pd, cb) {
      _this._mustSwipeCardHandler(pd, cb);
    }, _commonHandlersForDev[_retailPaymentDevice.deviceError.generic.code] = function (pd, cb) {
      _this.errorHandlerCompletion(pd, cb, action.abort, false, _this.formattedAmount, _retailPaymentDevice.PaymentDevice.Message.TransactionCancelled, _retailPaymentDevice.PaymentDevice.Message.TransactionCancelledRemoveCard, errors.genericError, displayMessage.ok);
    }, _commonHandlersForDev[_retailPaymentDevice.deviceError.paymentCancelled.code] = function (pd, cb) {
      _this.errorHandlerCompletion(pd, cb, action.abort, false, _this.formattedAmount, _retailPaymentDevice.PaymentDevice.Message.TransactionCancelled, _retailPaymentDevice.PaymentDevice.Message.TransactionCancelledRemoveCard, errors.cancelled, displayMessage.done);
    }, _commonHandlersForDev[_retailPaymentDevice.deviceError.cancelReadCardData.code] = function (pd, cb) {
      _this.errorHandlerCompletion(pd, cb, action.offlineDecline, false, _this.formattedAmount, _retailPaymentDevice.PaymentDevice.Message.TransactionCancelled, _retailPaymentDevice.PaymentDevice.Message.TransactionCancelledRemoveCard, errors.cancelled, displayMessage.done);
    }, _commonHandlersForDev);

    var nfcHandlersForApiErrors = (_nfcHandlersForApiErr = {}, _nfcHandlersForApiErr[_sdkErrors.retail.nfcPaymentDeclined.code] = function (pd, cb) {
      _this._updateDisplay(pd, _retailPaymentDevice.PaymentDevice.Message.NfcDecline, null, null, function () {
        _this.context.promptForPaymentInstrument(null, new Set([_retailPaymentDevice.FormFactor.MagneticCardSwipe, _retailPaymentDevice.FormFactor.Chip]), {
          title: (0, _l10n2.default)('Tx.Alert.NfcPaymentDeclined.Title'),
          message: (0, _l10n2.default)('Tx.Alert.NfcPaymentDeclined.Msg'),
          error: _sdkErrors.retail.nfcPaymentDeclined
        });
        cb(PaymentErrorHandler.action.retryWithInsertOrSwipe, {
          showPrompt: false,
          syncInvoiceTotal: false
        });
      });
    }, _nfcHandlersForApiErr[_sdkErrors.retail.onlinePinMaxRetryExceed.code] = nfcContactIssuer, _nfcHandlersForApiErr[_sdkErrors.retail.contactIssuer.code] = nfcContactIssuer, _nfcHandlersForApiErr);

    var insertHandlersForApiErrors = (_insertHandlersForApi = {}, _insertHandlersForApi[_sdkErrors.retail.contactIssuer.code] = function (pd, cb) {
      return _this._insertContactIssuer(pd, cb, false);
    }, _insertHandlersForApi[_sdkErrors.retail.onlinePinMaxRetryExceed.code] = function (pd, cb) {
      return _this._insertContactIssuer(pd, cb, false);
    }, _insertHandlersForApi);

    var swiperHandlersForApiErrors = (_swiperHandlersForApi = {}, _swiperHandlersForApi[_sdkErrors.retail.contactIssuer.code] = swipeContactIssuer, _swiperHandlersForApi);

    var commonHandlersForApiErrors = (_commonHandlersForApi = {}, _commonHandlersForApi[_sdkErrors.retail.incorrectOnlinePin.code] = function (pd, cb) {
      _this._updateDisplay(pd, _retailPaymentDevice.PaymentDevice.Message.IncorrectPin, _this.formattedAmount, {
        title: (0, _l10n2.default)('Tx.Alert.IncorrectOnlinePin.Title'),
        message: (0, _l10n2.default)('Tx.Alert.IncorrectOnlinePin.Msg'),
        cancel: (0, _l10n2.default)('Ok')
      }, function () {
        _this.context.promptForPaymentInstrument();
        cb(action.retry);
      });
    }, _commonHandlersForApi);

    var swipeHandlersForTransactionErrors = (_swipeHandlersForTran = {}, _swipeHandlersForTran[_sdkErrors.transaction.cannotSwipeChipCard.code] = function (pd, cb) {
      _this._updateDisplay(null, null, null, {
        title: (0, _l10n2.default)('Tx.Alert.ChipCardSwiped.Title'),
        message: (0, _l10n2.default)('Tx.Alert.ChipCardSwiped.Msg'),
        cancel: (0, _l10n2.default)('Ok')
      }, function () {
        _this.context.promptForPaymentInstrument(null, new Set([_retailPaymentDevice.FormFactor.Chip]));
      });
      cb(action.retryWithInsert);
    }, _swipeHandlersForTran);

    var multipleContactlessCardsDetectedForTransactionErrors = (_multipleContactlessC = {}, _multipleContactlessC[_sdkErrors.transaction.multipleContactlessCardsDetected.code] = function (pd, cb) {
      _this._updateDisplay(null, null, null, {
        title: (0, _l10n2.default)('Tx.Alert.MultipleContactlessCardsDetected.Title'),
        message: (0, _l10n2.default)('Tx.Alert.MultipleContactlessCardsDetected.Msg'),
        cancel: (0, _l10n2.default)('Ok')
      }, function () {
        cb(action.retry);
      });
    }, _multipleContactlessC);

    // Handlers that apply to all form of transactions (insert, tap & swipe)
    var commonHandlersForTransactionErrors = (_commonHandlersForTra = {}, _commonHandlersForTra[_sdkErrors.transaction.mustSwipeCard.code] = function (pd, cb) {
      _this._mustSwipeCardHandler(pd, cb);
    }, _commonHandlersForTra[_sdkErrors.transaction.amountTooLow.code] = function (pd, cb) {
      var allowedMin = messageHelper.formattedAmount(_this.context.invoice.currency, _Merchant2.default.active.cardSettings.minimum);
      _this.errorHandlerCompletion(pd, cb, action.retry, true, allowedMin, _retailPaymentDevice.PaymentDevice.Message.AmountTooLow, _retailPaymentDevice.PaymentDevice.Message.AmountTooLowRemoveCard, errors.amountTooLow, displayMessage.ok);
    }, _commonHandlersForTra[_sdkErrors.transaction.amountTooHigh.code] = function (pd, cb) {
      var allowedMax = messageHelper.formattedAmount(_this.context.invoice.currency, _Merchant2.default.active.cardSettings.maximum);
      _this.errorHandlerCompletion(pd, cb, action.retry, true, allowedMax, _retailPaymentDevice.PaymentDevice.Message.AmountTooHigh, _retailPaymentDevice.PaymentDevice.Message.AmountTooHighRemoveCard, errors.amountTooHigh, displayMessage.ok);
    }, _commonHandlersForTra[_sdkErrors.transaction.refundCardMismatch.code] = function (pd, cb) {
      _this.errorHandlerCompletion(pd, cb, action.abort, false, _this.formattedAmount, _retailPaymentDevice.PaymentDevice.Message.RefundCardMismatch, _retailPaymentDevice.PaymentDevice.Message.RefundCardMismatchRemoveCard, errors.refundCardMismatch, displayMessage.ok);
    }, _commonHandlersForTra[_sdkErrors.transaction.customerCancel.code] = function (pd, cb) {
      _this.errorHandlerCompletion(pd, cb, action.abort, false, _this.formattedAmount, _retailPaymentDevice.PaymentDevice.Message.TransactionCancelled, _retailPaymentDevice.PaymentDevice.Message.TransactionCancelledRemoveCard, errors.cancelled, displayMessage.ok);
    }, _commonHandlersForTra[_sdkErrors.transaction.tryDifferentInterface.code] = function (pd, cb) {
      Log.debug(function () {
        return 'Will activate Chip & Swipe form factors for handling tryDifferentInterface API Error for ' + _this.context.id;
      });
      _this._startListeningForPayments();
      _this._updateDisplay(pd, _retailPaymentDevice.PaymentDevice.Message.UnableToReadNfcCard, _this.formattedAmount, {
        title: (0, _l10n2.default)('Tx.Alert.TapDifferentCard.Title'),
        message: (0, _l10n2.default)('Tx.Alert.TapDifferentCard.Msg'),
        cancel: (0, _l10n2.default)('Ok')
      }, function () {
        _this.context.promptForPaymentInstrument();
        cb(action.retry);
      });
    }, _commonHandlersForTra);

    this.errorHandlers = (_errorHandlers = {}, _errorHandlers[_retailPaymentDevice.deviceErrorDomain] = (_deviceErrorDomain = {}, _deviceErrorDomain[_retailPaymentDevice.FormFactor.None] = commonHandlersForDeviceErrors, _deviceErrorDomain[_retailPaymentDevice.FormFactor.EmvCertifiedContactless] = (0, _manticoreUtil.extend)(nfcHandlersForDeviceErrors, commonHandlersForDeviceErrors), _deviceErrorDomain[_retailPaymentDevice.FormFactor.Chip] = (0, _manticoreUtil.extend)(insertHandlersForDeviceErrors, commonHandlersForDeviceErrors), _deviceErrorDomain[_retailPaymentDevice.FormFactor.MagneticCardSwipe] = (0, _manticoreUtil.extend)(swipeHandlersForDeviceErrors, commonHandlersForDeviceErrors), _deviceErrorDomain), _errorHandlers[_sdkErrors.domain.retail] = (_sdkErrorDomain$retai = {}, _sdkErrorDomain$retai[_retailPaymentDevice.FormFactor.None] = commonHandlersForApiErrors, _sdkErrorDomain$retai[_retailPaymentDevice.FormFactor.EmvCertifiedContactless] = (0, _manticoreUtil.extend)(nfcHandlersForApiErrors, commonHandlersForApiErrors), _sdkErrorDomain$retai[_retailPaymentDevice.FormFactor.Chip] = (0, _manticoreUtil.extend)(insertHandlersForApiErrors, commonHandlersForApiErrors), _sdkErrorDomain$retai[_retailPaymentDevice.FormFactor.MagneticCardSwipe] = (0, _manticoreUtil.extend)(swiperHandlersForApiErrors, commonHandlersForApiErrors), _sdkErrorDomain$retai), _errorHandlers[_sdkErrors.domain.transaction] = (_sdkErrorDomain$trans = {}, _sdkErrorDomain$trans[_retailPaymentDevice.FormFactor.None] = commonHandlersForTransactionErrors, _sdkErrorDomain$trans[_retailPaymentDevice.FormFactor.EmvCertifiedContactless] = (0, _manticoreUtil.extend)(multipleContactlessCardsDetectedForTransactionErrors, commonHandlersForTransactionErrors), _sdkErrorDomain$trans[_retailPaymentDevice.FormFactor.Chip] = commonHandlersForTransactionErrors, _sdkErrorDomain$trans[_retailPaymentDevice.FormFactor.MagneticCardSwipe] = (0, _manticoreUtil.extend)(swipeHandlersForTransactionErrors, commonHandlersForTransactionErrors), _sdkErrorDomain$trans[_retailPaymentDevice.FormFactor.ManualCardEntry] = commonHandlersForTransactionErrors, _sdkErrorDomain$trans), _errorHandlers);
  }

  PaymentErrorHandler._doNothing = function _doNothing(pd, cb) {
    cb(null);
  };

  PaymentErrorHandler.prototype.errorHandlerCompletion = function errorHandlerCompletion(pd, cb, action, amountError, amountSubstitution, pdMessage, pdMessageRemoveCard, appMessageKey, alertButtonKey) {
    var pdDisplayMessage = pdMessage;
    var shouldPromptCardRemoval = pd && pd.isConnected() && pd.cardInSlot;
    var appUpdateDisplay = {
      title: (0, _l10n2.default)('Tx.Alert.' + appMessageKey + '.Title'),
      message: amountError ? (0, _l10n2.default)('Tx.Alert.' + appMessageKey + '.Msg', amountSubstitution) : (0, _l10n2.default)('Tx.Alert.' + appMessageKey + '.Msg'),
      cancel: (0, _l10n2.default)('' + alertButtonKey)
    };
    if (appMessageKey === PaymentErrorHandler.errors.genericError) {
      appUpdateDisplay.message = (0, _l10n2.default)('Tx.Alert.GenericError.' + (this.context.isRefund() ? PaymentErrorHandler.displayMessage.refundMessage : PaymentErrorHandler.displayMessage.paymentMessage));
    }
    if (shouldPromptCardRemoval) {
      appUpdateDisplay = this._cardInSlotHelper(pd, cb, action, appUpdateDisplay);
      pdDisplayMessage = pdMessageRemoveCard;
    }
    this._updateDisplay(pd, pdDisplayMessage, amountSubstitution, appUpdateDisplay, function () {
      if (!shouldPromptCardRemoval) {
        cb(action);
      }
    });
  };

  PaymentErrorHandler.prototype._cardInSlotHelper = function _cardInSlotHelper(pd, cb, action, appUpdateDisplay) {
    var _this2 = this;

    appUpdateDisplay.message = appUpdateDisplay.message.concat((0, _l10n2.default)(PaymentErrorHandler.displayMessage.removeCard));
    delete appUpdateDisplay.cancel;
    pd.waitForCardRemoval(function () {
      if (_this2.alert) {
        _this2.alert.dismiss();
      }
      cb(action);
    });
    return appUpdateDisplay;
  };

  PaymentErrorHandler.prototype._startListeningForPayments = function _startListeningForPayments() {
    var _this3 = this;

    Log.debug(function () {
      return 'Will activate Chip & Swipe form factors for ' + _this3.context.id;
    });
    this.context.setPaymentState(_transactionStates.PaymentState.retry);
    this.context.deviceController.activate({
      showPrompt: false,
      formFactors: [_retailPaymentDevice.FormFactor.Chip, _retailPaymentDevice.FormFactor.MagneticCardSwipe],
      syncInvoiceTotal: false
    });
  };

  PaymentErrorHandler.prototype._mustSwipeCardHandler = function _mustSwipeCardHandler(pd, cb) {
    this._updateDisplay(pd, null, null, {
      title: (0, _l10n2.default)('Tx.Alert.ReadyForSwipeOnly.Title'),
      message: (0, _l10n2.default)('Tx.Alert.ReadyForSwipeOnly.Msg'),
      imageIcon: 'img_emv_swipe'
    });
    this.context.allowFallBackSwipe = true;
    cb(PaymentErrorHandler.action.retryWithSwipe);
  };

  PaymentErrorHandler.prototype._nfcPaymentDeclineErrorHandler = function _nfcPaymentDeclineErrorHandler(pd, cb) {
    var _this4 = this;

    this._updateDisplay(pd, _retailPaymentDevice.PaymentDevice.Message.NfcDecline, null, {
      title: (0, _l10n2.default)('Tx.Alert.NfcPaymentDeclined.Title'),
      message: (0, _l10n2.default)('Tx.Alert.NfcPaymentDeclined.Msg'),
      buttons: [(0, _l10n2.default)('Ok')],
      cancel: (0, _l10n2.default)('Cancel')
    }, function (a, ix) {
      if (ix === 0) {
        _this4.context.promptForPaymentInstrument(null, new Set([_retailPaymentDevice.FormFactor.Chip, _retailPaymentDevice.FormFactor.MagneticCardSwipe]));
        cb(PaymentErrorHandler.action.retryWithInsertOrSwipe);
      } else {
        cb(PaymentErrorHandler.action.abort);
      }
    });
  };

  PaymentErrorHandler.prototype._insertContactIssuer = function _insertContactIssuer(pd, cb, isOffline) {
    var action = isOffline ? PaymentErrorHandler.action.offlineDecline : PaymentErrorHandler.action.abort;
    this.errorHandlerCompletion(pd, cb, action, false, this.formattedAmount, _retailPaymentDevice.PaymentDevice.Message.ContactIssuer, _retailPaymentDevice.PaymentDevice.Message.ContactIssuerRemoveCard, PaymentErrorHandler.errors.blockedCard, PaymentErrorHandler.displayMessage.ok);
  };

  /**
   * Display alerts on the payment device and app
   */


  PaymentErrorHandler.prototype._updateDisplay = function _updateDisplay(pd, deviceMessageId, deviceMessageSubstitutions, alertOptions, cb) {
    var _this5 = this;

    var onDeviceDisplay = function onDeviceDisplay() {
      if (!alertOptions) {
        if (cb) {
          cb();
        }
        return;
      }
      _this5.alert = _manticore2.default.alert(alertOptions, function (a, ix) {
        if (_this5.alert) {
          _this5.alert.dismiss();
        }
        if (cb) {
          cb(a, ix);
        }
      });
      if (!alertOptions.cancel && !alertOptions.buttons && cb) {
        cb(_this5.alert);
      }
    };

    if (pd && deviceMessageId) {
      pd.display({ id: deviceMessageId, substitutions: deviceMessageSubstitutions }, onDeviceDisplay);
    } else {
      onDeviceDisplay();
    }
  };

  /**
   * Handles payment errors by displaying appropriate alerts on the terminal and app side.
   * @param {PayPalError} error
   * @param formFactor
   * @param paymentDevice
   * @param cb Callback to invoke after the error was handled. A single parameter with value action.abort or
   *                  action.retry will be passed to the callback function.
   */


  PaymentErrorHandler.prototype.handle = function handle(error, formFactor, paymentDevice, cb) {
    Log.debug(function () {
      return 'Handling error with code: ' + error.code + ', domain: ' + error.domain + ', formFactor: ' + (0, _manticoreUtil.getPropertyName)(_retailPaymentDevice.FormFactor, formFactor) + ', device: ' + (paymentDevice ? paymentDevice.id : '<no device>');
    });
    if (error.domain && formFactor && this.errorHandlers[error.domain] && this.errorHandlers[error.domain][formFactor] && this.errorHandlers[error.domain][formFactor][error.code]) {
      var handler = this.errorHandlers[error.domain][formFactor][error.code];
      try {
        handler(paymentDevice, cb);
        return;
      } catch (x) {
        Log.error('Error (' + error.domain + ':' + error.code + ') executing handler ' + handler + '\n' + x);
        throw x;
      }
    }

    Log.warn('No handlers were defined for domain: \'' + error.domain + '\' form factor : \'' + (0, _manticoreUtil.getPropertyName)(_retailPaymentDevice.FormFactor, formFactor) + '\' and Error code ' + error.code);
    this.errorHandlerCompletion(paymentDevice, cb, PaymentErrorHandler.action.abort, false, this.formattedAmount, _retailPaymentDevice.PaymentDevice.Message.TransactionCancelled, _retailPaymentDevice.PaymentDevice.Message.TransactionCancelledRemoveCard, PaymentErrorHandler.errors.genericError, PaymentErrorHandler.displayMessage.ok);
  };

  return PaymentErrorHandler;
}();

/**
 * Contains the list of actions PaymentErrorHandler class could request the caller of Handle function to perform
 * @type {{Abort: string, Retry: string}}
 * @private
 */


exports.default = PaymentErrorHandler;
PaymentErrorHandler.action = {
  offlineDecline: 'OfflineDecline',
  abort: 'abort',
  retry: 'retry',
  retryWithInsertOrSwipe: 'retryWithInsertOrSwipe',
  retryWithInsert: 'retryWithInsert',
  retryWithSwipe: 'retryWithSwipe'
};
PaymentErrorHandler.errors = {
  genericError: 'GenericError',
  cancelled: 'Cancelled',
  amountTooLow: 'AmountTooLow',
  amountTooHigh: 'AmountTooHigh',
  refundCardMismatch: 'Refund.CardMismatch',
  blockedCard: 'BlockedCard'
};
PaymentErrorHandler.displayMessage = {
  ok: 'Ok',
  done: 'Done',
  cancel: 'Cancel',
  removeCard: 'RemoveCard',
  refundMessage: 'RefundMessage',
  paymentMessage: 'PaymentMessage'
};

},{"../common/Merchant":"/Users/aravidas/Documents/Git/retail-sdk/js/common/Merchant.js","../common/l10n":"/Users/aravidas/Documents/Git/retail-sdk/js/common/l10n.js","../common/sdkErrors":"/Users/aravidas/Documents/Git/retail-sdk/js/common/sdkErrors.js","../transaction/transactionStates":"/Users/aravidas/Documents/Git/retail-sdk/js/transaction/transactionStates.js","./messageHelper":"/Users/aravidas/Documents/Git/retail-sdk/js/flows/messageHelper.js","manticore":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore/browser.js","manticore-log":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-log/index.js","manticore-util":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-util/build/index.js","retail-payment-device":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/js/flows/PaymentFlow.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

var _manticoreLog = require('manticore-log');

var _manticoreLog2 = _interopRequireDefault(_manticoreLog);

var _messageHelper = require('./messageHelper');

var messageHelper = _interopRequireWildcard(_messageHelper);

var _BaseTransactionFlow2 = require('./BaseTransactionFlow');

var _BaseTransactionFlow3 = _interopRequireDefault(_BaseTransactionFlow2);

var _MerchantTakePaymentStep = require('./steps/MerchantTakePaymentStep');

var _MerchantTakePaymentStep2 = _interopRequireDefault(_MerchantTakePaymentStep);

var _UpdateInvoicePaymentStep = require('./steps/UpdateInvoicePaymentStep');

var _UpdateInvoicePaymentStep2 = _interopRequireDefault(_UpdateInvoicePaymentStep);

var _ReceiptStep = require('./steps/ReceiptStep');

var _ReceiptStep2 = _interopRequireDefault(_ReceiptStep);

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (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 } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var Log = (0, _manticoreLog2.default)('flow.paymentFlow');

var PaymentFlow = function (_BaseTransactionFlow) {
  _inherits(PaymentFlow, _BaseTransactionFlow);

  function PaymentFlow(context, callback) {
    _classCallCheck(this, PaymentFlow);

    Log.debug('Initializing Payment Flow');

    var _this = _possibleConstructorReturn(this, _BaseTransactionFlow.call(this, null, context, callback));

    _BaseTransactionFlow.prototype.setFlowSteps.call(_this, 'Payment', [_this.createFlowMessageStep(messageHelper.showProcessingMessage), _this.saveInvoiceStep, new _MerchantTakePaymentStep2.default(context).flowStep, _this.createFlowMessageStep(messageHelper.showCompleteMessage)]).setCompletionSteps('Payment-Receipt', [new _UpdateInvoicePaymentStep2.default(context).flowStep, new _ReceiptStep2.default(_this.context).flowStep]).startFlow();
    return _this;
  }

  return PaymentFlow;
}(_BaseTransactionFlow3.default);

exports.default = PaymentFlow;

},{"./BaseTransactionFlow":"/Users/aravidas/Documents/Git/retail-sdk/js/flows/BaseTransactionFlow.js","./messageHelper":"/Users/aravidas/Documents/Git/retail-sdk/js/flows/messageHelper.js","./steps/MerchantTakePaymentStep":"/Users/aravidas/Documents/Git/retail-sdk/js/flows/steps/MerchantTakePaymentStep.js","./steps/ReceiptStep":"/Users/aravidas/Documents/Git/retail-sdk/js/flows/steps/ReceiptStep.js","./steps/UpdateInvoicePaymentStep":"/Users/aravidas/Documents/Git/retail-sdk/js/flows/steps/UpdateInvoicePaymentStep.js","manticore-log":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-log/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/js/flows/QuickChipCreditCardFlow.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

var _manticoreLog = require('manticore-log');

var _manticoreLog2 = _interopRequireDefault(_manticoreLog);

var _retailPaymentDevice = require('retail-payment-device');

var _messageHelper = require('./messageHelper');

var messageHelper = _interopRequireWildcard(_messageHelper);

var _BaseTransactionFlow2 = require('./BaseTransactionFlow');

var _BaseTransactionFlow3 = _interopRequireDefault(_BaseTransactionFlow2);

var _MerchantTakePaymentStep = require('./steps/MerchantTakePaymentStep');

var _MerchantTakePaymentStep2 = _interopRequireDefault(_MerchantTakePaymentStep);

var _SignatureStep = require('./steps/SignatureStep');

var _SignatureStep2 = _interopRequireDefault(_SignatureStep);

var _FinalizePaymentStep = require('./steps/FinalizePaymentStep');

var _FinalizePaymentStep2 = _interopRequireDefault(_FinalizePaymentStep);

var _UpdateInvoicePaymentStep = require('./steps/UpdateInvoicePaymentStep');

var _UpdateInvoicePaymentStep2 = _interopRequireDefault(_UpdateInvoicePaymentStep);

var _QuickChipStep = require('./steps/QuickChipStep');

var _QuickChipStep2 = _interopRequireDefault(_QuickChipStep);

var _ReceiptStep = require('./steps/ReceiptStep');

var _ReceiptStep2 = _interopRequireDefault(_ReceiptStep);

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (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 } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var Log = (0, _manticoreLog2.default)('flow.QuickChipCreditCardFlow');

/**
 * This step is to handle Quick Chip Flow
 *
 * . Once the card data is read (QuickChipStep), send 'Z3' auth code to reader
 * . Send "Remove card" message to he reader (QuickChipStep)
 * . Remove cardRemoved listener
 * . Do not send the Auth code from server to reader (#MerchantTakePaymentStep)
 * . Change the message in Signature Step
 *
 */

var QuickChipCreditCardFlow = function (_BaseTransactionFlow) {
  _inherits(QuickChipCreditCardFlow, _BaseTransactionFlow);

  function QuickChipCreditCardFlow(card, context, callback) {
    _classCallCheck(this, QuickChipCreditCardFlow);

    Log.debug('Initializing Quick Chip Credit Flow');

    var _this = _possibleConstructorReturn(this, _BaseTransactionFlow.call(this, card, context, callback));

    _this.quickChipEnabled = context.paymentOptions.quickChipEnabled;

    _this.quickChipStep = new _QuickChipStep2.default(context);
    _this.qcTransactionCancelRequested = function () {
      // qcAuthSend will be set by QuickChipStep after sending QC AUTH Code
      if (!_this.card.qcAuthSend) {
        _this.transactionCancelRequested();
      } else {
        Log.info('qcRemoveCard was requested from device ' + _this.card.reader.id);
      }
    };

    _BaseTransactionFlow.prototype.setFlowSteps.call(_this, 'QCCredit', [function addPaymentCancelListeners(flow) {
      if (context.allowInProgressPaymentCancel) {
        this.card.reader.once(_retailPaymentDevice.PaymentDevice.Event.cardRemoved, this.qcTransactionCancelRequested);
        this.card.reader.once(_retailPaymentDevice.PaymentDevice.Event.cancelRequested, this.transactionCancelRequested);
        this.card.reader.once(_retailPaymentDevice.PaymentDevice.Event.disconnected, this.transactionCancelRequested);
        this.card.reader.once(_retailPaymentDevice.PaymentDevice.Event.cancelled, this.transactionCancelled);
      }
      flow.next();
    }, _this.quickChipStep.flowStep, _this.saveInvoiceStep, new _MerchantTakePaymentStep2.default(context, _this.voidPaymentIfApplicable).flowStep, new _SignatureStep2.default(context).flowStep, _this.createFlowMessageStep(messageHelper.showFinalizeMessage), function removePaymentCancelListeners(flow) {
      this._removePaymentCancelListeners();
      flow.next();
    }, new _FinalizePaymentStep2.default(context).flowStep, _this.createFlowMessageStep(messageHelper.showCompleteMessage)]).addFlowEndedHandler(function () {
      return _this._removePaymentCancelListeners();
    }).setCompletionSteps('Credit-Receipt', [new _UpdateInvoicePaymentStep2.default(context).flowStep, _this.createFlowMessageStep(messageHelper.ifFailureShowMessage), new _ReceiptStep2.default(_this.context).flowStep]).startFlow();
    return _this;
  }

  QuickChipCreditCardFlow.prototype._removePaymentCancelListeners = function _removePaymentCancelListeners() {
    var r = this.card.reader;
    if (this.context.allowInProgressPaymentCancel) {
      r.removeListener(_retailPaymentDevice.PaymentDevice.Event.cardRemoved, this.qcTransactionCancelRequested);
      r.removeListener(_retailPaymentDevice.PaymentDevice.Event.cancelRequested, this.transactionCancelRequested);
      r.removeListener(_retailPaymentDevice.PaymentDevice.Event.disconnected, this.transactionCancelRequested);
      r.removeListener(_retailPaymentDevice.PaymentDevice.Event.cancelled, this.transactionCancelled);
    }
  };

  return QuickChipCreditCardFlow;
}(_BaseTransactionFlow3.default);

exports.default = QuickChipCreditCardFlow;

},{"./BaseTransactionFlow":"/Users/aravidas/Documents/Git/retail-sdk/js/flows/BaseTransactionFlow.js","./messageHelper":"/Users/aravidas/Documents/Git/retail-sdk/js/flows/messageHelper.js","./steps/FinalizePaymentStep":"/Users/aravidas/Documents/Git/retail-sdk/js/flows/steps/FinalizePaymentStep.js","./steps/MerchantTakePaymentStep":"/Users/aravidas/Documents/Git/retail-sdk/js/flows/steps/MerchantTakePaymentStep.js","./steps/QuickChipStep":"/Users/aravidas/Documents/Git/retail-sdk/js/flows/steps/QuickChipStep.js","./steps/ReceiptStep":"/Users/aravidas/Documents/Git/retail-sdk/js/flows/steps/ReceiptStep.js","./steps/SignatureStep":"/Users/aravidas/Documents/Git/retail-sdk/js/flows/steps/SignatureStep.js","./steps/UpdateInvoicePaymentStep":"/Users/aravidas/Documents/Git/retail-sdk/js/flows/steps/UpdateInvoicePaymentStep.js","manticore-log":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-log/index.js","retail-payment-device":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/js/flows/ReaderTippingFlow.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

var _manticoreLog = require('manticore-log');

var _manticoreLog2 = _interopRequireDefault(_manticoreLog);

var _manticore = require('manticore');

var _manticore2 = _interopRequireDefault(_manticore);

var _retailPaymentDevice = require('retail-payment-device');

var _BaseFlowAsync2 = require('./BaseFlowAsync');

var _BaseFlowAsync3 = _interopRequireDefault(_BaseFlowAsync2);

var _l10n = require('../common/l10n');

var _l10n2 = _interopRequireDefault(_l10n);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (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 } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var Log = (0, _manticoreLog2.default)('flow.ReaderTippingFlow');

var ReaderTippingFlow = function (_BaseFlowAsync) {
  _inherits(ReaderTippingFlow, _BaseFlowAsync);

  function ReaderTippingFlow(device, amountBasedTip, invoice, callback) {
    _classCallCheck(this, ReaderTippingFlow);

    Log.debug('Initializing Tipping Flow');

    var _this = _possibleConstructorReturn(this, _BaseFlowAsync.call(this));

    _this.device = device;
    _this.amountBasedTip = amountBasedTip;
    _this.invoice = invoice;
    _this.completionCallback = callback;
    return _this;
  }

  ReaderTippingFlow.prototype.start = function start() {
    var _this2 = this;

    return regeneratorRuntime.async(function start$(_context) {
      while (1) {
        switch (_context.prev = _context.next) {
          case 0:
            _context.next = 2;
            return regeneratorRuntime.awrap(_BaseFlowAsync.prototype.setFlowSteps.call(this, 'Tipping', [this._stopBatteryPollStep, this._createFlowMessageStep, this._requestForTip, this._receiveTip, this._confirmTip]));

          case 2:
            _BaseFlowAsync.prototype.addFlowEndedHandler.call(this, function () {
              return _this2._completeTippingFlow();
            });
            _context.next = 5;
            return regeneratorRuntime.awrap(_BaseFlowAsync.prototype.startFlow.call(this));

          case 5:
          case 'end':
            return _context.stop();
        }
      }
    }, null, this);
  };

  ReaderTippingFlow.prototype._stopBatteryPollStep = function _stopBatteryPollStep(flow) {
    return regeneratorRuntime.async(function _stopBatteryPollStep$(_context2) {
      while (1) {
        switch (_context2.prev = _context2.next) {
          case 0:
            Log.debug('Stop polling for key in TippingOnReader');
            this.device.stopPollForBattery();
            _context2.next = 4;
            return regeneratorRuntime.awrap(flow.next());

          case 4:
          case 'end':
            return _context2.stop();
        }
      }
    }, null, this);
  };

  ReaderTippingFlow.prototype._createFlowMessageStep = function _createFlowMessageStep(flow) {
    var _this3 = this;

    var alertOpts;
    return regeneratorRuntime.async(function _createFlowMessageStep$(_context3) {
      while (1) {
        switch (_context3.prev = _context3.next) {
          case 0:
            Log.debug('_createFlowMessageStep');

            _context3.prev = 1;
            alertOpts = {
              title: (0, _l10n2.default)('EMV.Tip.Title'),
              buttons: [(0, _l10n2.default)('EMV.Tip.Buttons.NoTip')]
            };

            this.alert = _manticore2.default.alert(alertOpts, function (a, ix) {
              if (_this3.alert) {
                _this3.alert.dismiss();
              }
              Log.debug('No Tip button pushed so aborting...');
              if (ix === 0) {
                // No Tip button
                // clear any persisting transactions on the reader
                _this3.device.abortTipping().then(function () {
                  return Log.debug('aborted tipping on the terminal');
                }).catch(function (error) {
                  Log.warn('could not abort tipping on terminal with error: ' + error);
                });
                _this3.abort();
              }
            });
            _context3.next = 12;
            break;

          case 6:
            _context3.prev = 6;
            _context3.t0 = _context3['catch'](1);

            Log.warn('Aborting the ReaderTipping flow with error : ' + _context3.t0 + ' ');
            _context3.next = 11;
            return regeneratorRuntime.awrap(this.abort(_context3.t0));

          case 11:
            return _context3.abrupt('return');

          case 12:
            _context3.next = 14;
            return regeneratorRuntime.awrap(flow.next());

          case 14:
          case 'end':
            return _context3.stop();
        }
      }
    }, null, this, [[1, 6]]);
  };

  ReaderTippingFlow.prototype._requestForTip = function _requestForTip(flow) {
    return regeneratorRuntime.async(function _requestForTip$(_context4) {
      while (1) {
        switch (_context4.prev = _context4.next) {
          case 0:
            Log.debug('Request Tip');

            _context4.prev = 1;
            _context4.next = 4;
            return regeneratorRuntime.awrap(this.device.requestForTip(this.invoice));

          case 4:
            _context4.next = 12;
            break;

          case 6:
            _context4.prev = 6;
            _context4.t0 = _context4['catch'](1);

            Log.warn('Aborting the ReaderTipping requestForTip flow with error : ' + _context4.t0 + ' ');
            _context4.next = 11;
            return regeneratorRuntime.awrap(this.abort(_context4.t0));

          case 11:
            return _context4.abrupt('return');

          case 12:
            _context4.next = 14;
            return regeneratorRuntime.awrap(this._registerKeyPressListeners(flow));

          case 14:
          case 'end':
            return _context4.stop();
        }
      }
    }, null, this, [[1, 6]]);
  };

  ReaderTippingFlow.prototype._receiveTip = function _receiveTip(flow) {
    var tip;
    return regeneratorRuntime.async(function _receiveTip$(_context5) {
      while (1) {
        switch (_context5.prev = _context5.next) {
          case 0:
            Log.debug('Receiving Tip');
            tip = 0;
            _context5.prev = 2;
            _context5.next = 5;
            return regeneratorRuntime.awrap(this.device.promptForTip(this.amountBasedTip));

          case 5:
            tip = _context5.sent;
            _context5.next = 14;
            break;

          case 8:
            _context5.prev = 8;
            _context5.t0 = _context5['catch'](2);

            Log.warn('Aborting the tipping flow receiveTip with error : ' + _context5.t0 + ' & tip : ' + tip);
            _context5.next = 13;
            return regeneratorRuntime.awrap(this.abort(_context5.t0));

          case 13:
            return _context5.abrupt('return');

          case 14:
            if (tip) {
              _context5.next = 19;
              break;
            }

            Log.warn('Aborting the tipping flow receiveTip with failed tip : ' + tip);
            _context5.next = 18;
            return regeneratorRuntime.awrap(this.abort());

          case 18:
            return _context5.abrupt('return');

          case 19:

            Log.info('Tip received : ' + tip);
            if (this.amountBasedTip) {
              this.invoice.gratuityAmount = tip;
            } else {
              // percentage based tip
              this.invoice.gratuityAmount = (tip * this.invoice.subTotal / 100).toFixed(2);
            }
            _context5.next = 23;
            return regeneratorRuntime.awrap(flow.next());

          case 23:
          case 'end':
            return _context5.stop();
        }
      }
    }, null, this, [[2, 8]]);
  };

  ReaderTippingFlow.prototype._confirmTip = function _confirmTip(flow) {
    return regeneratorRuntime.async(function _confirmTip$(_context6) {
      while (1) {
        switch (_context6.prev = _context6.next) {
          case 0:
            Log.debug('Confirm Tip');

            _context6.prev = 1;

            flow.confirmTip = true;
            _context6.next = 5;
            return regeneratorRuntime.awrap(this.device.confirmTip(this.invoice));

          case 5:
            _context6.next = 13;
            break;

          case 7:
            _context6.prev = 7;
            _context6.t0 = _context6['catch'](1);

            Log.warn('Aborting the ReaderTipping confirmTip flow with error : ' + _context6.t0 + ' ');
            _context6.next = 12;
            return regeneratorRuntime.awrap(this.abort(_context6.t0));

          case 12:
            return _context6.abrupt('return');

          case 13:
            _context6.next = 15;
            return regeneratorRuntime.awrap(this._registerKeyPressListeners(flow));

          case 15:
          case 'end':
            return _context6.stop();
        }
      }
    }, null, this, [[1, 7]]);
  };

  ReaderTippingFlow.prototype._registerKeyPressListeners = function _registerKeyPressListeners(flow) {
    var _this4 = this;

    return regeneratorRuntime.async(function _registerKeyPressListeners$(_context7) {
      while (1) {
        switch (_context7.prev = _context7.next) {
          case 0:
            this.device.once(_retailPaymentDevice.PaymentDevice.Event.cancelRequested, function () {
              return _this4._proceedWithFlow(flow, true);
            });
            this.device.once(_retailPaymentDevice.PaymentDevice.Event.proceed, function () {
              return _this4._proceedWithFlow(flow, false);
            });

          case 2:
          case 'end':
            return _context7.stop();
        }
      }
    }, null, this);
  };

  ReaderTippingFlow.prototype._proceedWithFlow = function _proceedWithFlow(flow, abort) {
    return regeneratorRuntime.async(function _proceedWithFlow$(_context8) {
      while (1) {
        switch (_context8.prev = _context8.next) {
          case 0:
            Log.debug('_proceedWithFlow');
            _context8.next = 3;
            return regeneratorRuntime.awrap(this._deRegisterKeyPressListeners());

          case 3:
            if (!abort) {
              _context8.next = 16;
              break;
            }

            if (!flow.confirmTip) {
              _context8.next = 11;
              break;
            }

            flow.confirmTip = false;
            Log.debug('confirmTip cancelled so going back');
            _context8.next = 9;
            return regeneratorRuntime.awrap(flow.back());

          case 9:
            _context8.next = 14;
            break;

          case 11:
            Log.debug('Tip Cancelled');
            _context8.next = 14;
            return regeneratorRuntime.awrap(this.abort());

          case 14:
            _context8.next = 18;
            break;

          case 16:
            _context8.next = 18;
            return regeneratorRuntime.awrap(flow.next());

          case 18:
          case 'end':
            return _context8.stop();
        }
      }
    }, null, this);
  };

  ReaderTippingFlow.prototype._deRegisterKeyPressListeners = function _deRegisterKeyPressListeners() {
    return regeneratorRuntime.async(function _deRegisterKeyPressListeners$(_context9) {
      while (1) {
        switch (_context9.prev = _context9.next) {
          case 0:
            _context9.next = 2;
            return regeneratorRuntime.awrap(this._removeListeners());

          case 2:
          case 'end':
            return _context9.stop();
        }
      }
    }, null, this);
  };

  ReaderTippingFlow.prototype._removeListeners = function _removeListeners() {
    var events, _iterator, _isArray, _i, _ref, e, _iterator2, _isArray2, _i2, _ref2, l;

    return regeneratorRuntime.async(function _removeListeners$(_context10) {
      while (1) {
        switch (_context10.prev = _context10.next) {
          case 0:
            Log.debug('_removeListeners');
            events = [_retailPaymentDevice.PaymentDevice.Event.cancelRequested, _retailPaymentDevice.PaymentDevice.Event.proceed];
            _iterator = events, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();

          case 3:
            if (!_isArray) {
              _context10.next = 9;
              break;
            }

            if (!(_i >= _iterator.length)) {
              _context10.next = 6;
              break;
            }

            return _context10.abrupt('break', 31);

          case 6:
            _ref = _iterator[_i++];
            _context10.next = 13;
            break;

          case 9:
            _i = _iterator.next();

            if (!_i.done) {
              _context10.next = 12;
              break;
            }

            return _context10.abrupt('break', 31);

          case 12:
            _ref = _i.value;

          case 13:
            e = _ref;
            _iterator2 = this.device.listeners(e), _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();

          case 15:
            if (!_isArray2) {
              _context10.next = 21;
              break;
            }

            if (!(_i2 >= _iterator2.length)) {
              _context10.next = 18;
              break;
            }

            return _context10.abrupt('break', 29);

          case 18:
            _ref2 = _iterator2[_i2++];
            _context10.next = 25;
            break;

          case 21:
            _i2 = _iterator2.next();

            if (!_i2.done) {
              _context10.next = 24;
              break;
            }

            return _context10.abrupt('break', 29);

          case 24:
            _ref2 = _i2.value;

          case 25:
            l = _ref2;

            this.device.removeListener(e, l);

          case 27:
            _context10.next = 15;
            break;

          case 29:
            _context10.next = 3;
            break;

          case 31:
          case 'end':
            return _context10.stop();
        }
      }
    }, null, this);
  };

  ReaderTippingFlow.prototype.abort = function abort(err) {
    return regeneratorRuntime.async(function abort$(_context11) {
      while (1) {
        switch (_context11.prev = _context11.next) {
          case 0:
            Log.debug(function () {
              return 'abort with error: ' + err;
            });

            if (this.alert) {
              this.alert.dismiss();
              delete this.alert;
            }
            _context11.next = 4;
            return regeneratorRuntime.awrap(this._clearTip());

          case 4:
            _context11.next = 6;
            return regeneratorRuntime.awrap(this.flow.abortFlow(err));

          case 6:
          case 'end':
            return _context11.stop();
        }
      }
    }, null, this);
  };

  ReaderTippingFlow.prototype._clearTip = function _clearTip() {
    return regeneratorRuntime.async(function _clearTip$(_context12) {
      while (1) {
        switch (_context12.prev = _context12.next) {
          case 0:
            Log.debug('Tip Cleared');
            this.invoice.gratuityAmount = 0;

          case 2:
          case 'end':
            return _context12.stop();
        }
      }
    }, null, this);
  };

  ReaderTippingFlow.prototype._completeTippingFlow = function _completeTippingFlow() {
    var _this5 = this;

    return regeneratorRuntime.async(function _completeTippingFlow$(_context13) {
      while (1) {
        switch (_context13.prev = _context13.next) {
          case 0:
            Log.debug(function () {
              return 'completeTippingFlow with tipAmount: ' + _this5.invoice.gratuityAmount;
            });

            if (this.alert) {
              this.alert.dismiss();
              delete this.alert;
            }

            _context13.next = 4;
            return regeneratorRuntime.awrap(this._removeListeners());

          case 4:
            Log.debug('Start polling for battery');
            _context13.next = 7;
            return regeneratorRuntime.awrap(this.device.startPollForBattery());

          case 7:

            this.completionCallback();

          case 8:
          case 'end':
            return _context13.stop();
        }
      }
    }, null, this);
  };

  return ReaderTippingFlow;
}(_BaseFlowAsync3.default);

exports.default = ReaderTippingFlow;

},{"../common/l10n":"/Users/aravidas/Documents/Git/retail-sdk/js/common/l10n.js","./BaseFlowAsync":"/Users/aravidas/Documents/Git/retail-sdk/js/flows/BaseFlowAsync.js","manticore":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore/browser.js","manticore-log":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-log/index.js","retail-payment-device":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/js/flows/messageHelper.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;
exports.formattedAmount = formattedAmount;
exports.formattedInvoiceTotal = formattedInvoiceTotal;
exports.formattedRefundTotal = formattedRefundTotal;
exports.readerDisplay = readerDisplay;
exports.showSimpleMessage = showSimpleMessage;
exports.showProcessingMessage = showProcessingMessage;
exports.showRemoveCardForQCMessage = showRemoveCardForQCMessage;
exports.showProcessingWithPinMessage = showProcessingWithPinMessage;
exports.showCancellationMessage = showCancellationMessage;
exports.showFinalizeMessage = showFinalizeMessage;
exports.showRefundProcessingMessage = showRefundProcessingMessage;
exports.showRemoveCardMessage = showRemoveCardMessage;
exports.showCompleteMessage = showCompleteMessage;
exports.ifFailureShowMessage = ifFailureShowMessage;
exports.showSelectApplicationPrompt = showSelectApplicationPrompt;

var _retailPaymentDevice = require('retail-payment-device');

var _manticore = require('manticore');

var _manticore2 = _interopRequireDefault(_manticore);

var _l10n = require('../common/l10n');

var _l10n2 = _interopRequireDefault(_l10n);

var _retailSDKUtil = require('../common/retailSDKUtil');

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function formattedAmount(currency, total) {
  return {
    amount: (0, _retailSDKUtil.getAmountWithCurrencySymbol)(currency, total)
  };
}

function formattedInvoiceTotal(invoice) {
  return formattedAmount(invoice.currency, invoice.total);
}

function formattedRefundTotal(context) {
  return formattedAmount(context.invoice.currency, context.refundAmount);
}

function displayOrReuseAlert(flowData, options) {
  flowData.alert = _manticore2.default.alert(options, function () {});
  return flowData.alert;
}

function readerDisplay(context, messageId, substitutions, cb, displaySystemIcons) {
  var reader = context.deviceController.selectedDevice;
  if (context.card && context.card.reader) {
    reader = context.card.reader;
  }
  if (reader) {
    reader.display({ id: messageId, substitutions: substitutions, displaySystemIcons: displaySystemIcons }, cb);
  } else if (cb) {
    cb();
  }
}

function showSimpleMessage(title, message, showActivity, flowData) {
  return displayOrReuseAlert(flowData, {
    title: title,
    message: message,
    showActivity: showActivity,
    replace: true
  });
}

function showProcessingMessage(context, flowData, cb) {
  var chip = context.card && context.card.formFactor === _retailPaymentDevice.FormFactor.Chip;
  var alertOptions = {
    title: chip ? (0, _l10n2.default)('EMV.DoNotRemove') : (0, _l10n2.default)('EMV.Processing'),
    message: chip ? (0, _l10n2.default)('EMV.Processing') : null,
    showActivity: true,
    replace: true,
    audio: {
      file: 'success_card_read.mp3'
    }
  };

  if (context.pinPresent) {
    alertOptions.message = chip ? (0, _l10n2.default)('EMV.ProcessingPinOk') : (0, _l10n2.default)('EMV.PinOk');
  }

  var alert = _manticore2.default.alert(alertOptions, function () {});
  flowData.alert = alert;

  var messageId = chip ? _retailPaymentDevice.PaymentDevice.Message.ProcessingContact : _retailPaymentDevice.PaymentDevice.Message.Processing;
  if (context.pinPresent) {
    messageId = chip ? _retailPaymentDevice.PaymentDevice.Message.ProcessingContactWithPin : _retailPaymentDevice.PaymentDevice.Message.ProcessingWithPin;
  }
  var amount = context.isRefund() ? formattedRefundTotal(context) : formattedInvoiceTotal(context.invoice);
  readerDisplay(context, messageId, amount, function () {
    return cb(alert);
  });
}

function showRemoveCardForQCMessage(context, flowData, cb) {
  var alert = showSimpleMessage((0, _l10n2.default)('EMV.QuickChip'), null, true, flowData);

  readerDisplay(context, _retailPaymentDevice.PaymentDevice.Message.QuickChip, null, function () {
    return cb(alert);
  });
}

function showProcessingWithPinMessage(context, flowData, cb) {
  readerDisplay(context, _retailPaymentDevice.PaymentDevice.Message.ProcessingWithPin, null, cb);
}

function showCancellationMessage(context, flowData, cb) {
  var alert = showSimpleMessage((0, _l10n2.default)('EMV.Cancelling'), null, true, flowData);
  readerDisplay(context, _retailPaymentDevice.PaymentDevice.Message.TransactionCancelling, null, function () {
    return cb(alert);
  });
}

function showFinalizeMessage(context, flowData, cb) {
  // Showing "Completing payment" dialog irrespective of payment type
  var alert = showSimpleMessage((0, _l10n2.default)('EMV.Finalize'), null, true, flowData);
  var amt = formattedInvoiceTotal(context.invoice);
  readerDisplay(context, _retailPaymentDevice.PaymentDevice.Message.CompletingPayment, amt, function () {
    return cb(alert);
  });
}

function showRefundProcessingMessage(context, flowData, cb) {
  return cb(showSimpleMessage((0, _l10n2.default)('EMV.ProcessingRefund'), null, true, flowData));
}

function showRemoveCardMessage(context, flowData, cb) {
  var amt = formattedInvoiceTotal(context.invoice);
  var appTitle = 'EMV.Complete';
  var appMessage = 'EMV.Remove';
  var messageId = _retailPaymentDevice.PaymentDevice.Message.PaidRemoveCard;
  if (context.isRefund()) {
    amt = formattedRefundTotal(context);
    appTitle = 'EMV.RefundComplete';
    messageId = _retailPaymentDevice.PaymentDevice.Message.RefundRemoveCard;
  }
  if (flowData.error) {
    appTitle = 'EMV.Remove';
    appMessage = '';
    messageId = '';
    amt = '';
  }
  var alert = showSimpleMessage((0, _l10n2.default)(appTitle, amt), (0, _l10n2.default)(appMessage), false, flowData);

  // TODO Remove the cb parameter in this and showAuthMessage, showFinalizeMessage functions after device EMV device display method
  // is updated to not require a cb
  readerDisplay(context, messageId, amt, function () {
    return cb(alert);
  });
}

function showCompleteMessage(context, flowData, cb) {
  var amt = context.isRefund() ? formattedRefundTotal(context) : formattedInvoiceTotal(context.invoice);
  var msgId = context.isRefund() ? _retailPaymentDevice.PaymentDevice.Message.Refund : _retailPaymentDevice.PaymentDevice.Message.Paid;
  readerDisplay(context, msgId, amt, function () {
    return cb(flowData);
  });
}

function ifFailureShowMessage(context, flowData, cb) {
  if (context.isRefund() && flowData.error) {
    var amt = formattedRefundTotal(context);
    var msgId = _retailPaymentDevice.PaymentDevice.Message.RefundFailed;
    readerDisplay(context, msgId, amt, function () {
      return cb(flowData);
    });
  } else {
    cb(flowData);
  }
}

function showSelectApplicationPrompt(context, flowData, applicationPairs, cb) {
  var buttons = [];
  for (var _iterator = applicationPairs, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
    var _ref;

    if (_isArray) {
      if (_i >= _iterator.length) break;
      _ref = _iterator[_i++];
    } else {
      _i = _iterator.next();
      if (_i.done) break;
      _ref = _i.value;
    }

    var app = _ref;

    buttons.push(app[1] || app[0]);
  }

  flowData.alert = _manticore2.default.alert({
    title: (0, _l10n2.default)('EMV.Select'),
    buttons: buttons
  }, function (error, ix) {
    if (cb) {
      var applicationId = applicationPairs[ix][0];
      var applicationName = applicationPairs[ix][1];
      cb(applicationId, applicationName);
    }
  });

  return flowData.alert;
}

},{"../common/l10n":"/Users/aravidas/Documents/Git/retail-sdk/js/common/l10n.js","../common/retailSDKUtil":"/Users/aravidas/Documents/Git/retail-sdk/js/common/retailSDKUtil.js","manticore":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore/browser.js","retail-payment-device":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/js/flows/refundFlow.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

var _retailPaymentDevice = require('retail-payment-device');

var _manticoreLog = require('manticore-log');

var _manticoreLog2 = _interopRequireDefault(_manticoreLog);

var _messageHelper = require('./messageHelper');

var messageHelper = _interopRequireWildcard(_messageHelper);

var _UpdateInvoicePaymentStep = require('./steps/UpdateInvoicePaymentStep');

var _UpdateInvoicePaymentStep2 = _interopRequireDefault(_UpdateInvoicePaymentStep);

var _BaseTransactionFlow2 = require('./BaseTransactionFlow');

var _BaseTransactionFlow3 = _interopRequireDefault(_BaseTransactionFlow2);

var _CheckRefundEligibilityStep = require('./steps/CheckRefundEligibilityStep');

var _CheckRefundEligibilityStep2 = _interopRequireDefault(_CheckRefundEligibilityStep);

var _IssueRefundStep = require('./steps/IssueRefundStep');

var _IssueRefundStep2 = _interopRequireDefault(_IssueRefundStep);

var _RemoveCardStep = require('./steps/RemoveCardStep');

var _RemoveCardStep2 = _interopRequireDefault(_RemoveCardStep);

var _ReceiptStep = require('./steps/ReceiptStep');

var _ReceiptStep2 = _interopRequireDefault(_ReceiptStep);

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (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 } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var Log = (0, _manticoreLog2.default)('flow.refundFlow');

var RefundFlow = function (_BaseTransactionFlow) {
  _inherits(RefundFlow, _BaseTransactionFlow);

  function RefundFlow(card, context, callback) {
    _classCallCheck(this, RefundFlow);

    Log.debug('Initializing Refund Flow');

    var _this = _possibleConstructorReturn(this, _BaseTransactionFlow.call(this, card, context, callback));

    _BaseTransactionFlow.prototype.setFlowSteps.call(_this, 'Refund', [function addPaymentCancelListeners(flow) {
      if (this.card) {
        this.card.reader.once(_retailPaymentDevice.PaymentDevice.Event.cardRemoved, this.transactionCancelRequested);
        this.card.reader.once(_retailPaymentDevice.PaymentDevice.Event.cancelRequested, this.transactionCancelRequested);
        this.card.reader.once(_retailPaymentDevice.PaymentDevice.Event.cancelled, this.transactionCancelled);
      }
      flow.next();
    }, _this.createFlowMessageStep(messageHelper.showProcessingMessage), function endTransactionOnTerminal(flow) {
      if (this.card) {
        this.card.reader.abortTransaction(this.context, function () {
          flow.next();
        });
      } else {
        flow.next();
      }
    }, new _CheckRefundEligibilityStep2.default(context).flowStep, _this.createFlowMessageStep(messageHelper.showRefundProcessingMessage), function removePaymentCancelListeners(flow) {
      this._removePaymentCancelListeners();
      flow.next();
    }, new _IssueRefundStep2.default(context).flowStep, new _RemoveCardStep2.default(context).flowStep, _this.createFlowMessageStep(messageHelper.showCompleteMessage)]).addFlowEndedHandler(function () {
      return _this._removePaymentCancelListeners();
    }).setCompletionSteps('Refund-Receipt', [new _UpdateInvoicePaymentStep2.default(context).flowStep, _this.createFlowMessageStep(messageHelper.ifFailureShowMessage), new _ReceiptStep2.default(_this.context).flowStep]);

    var paymentToRefund = context.invoice.payments && context.invoice.payments[0];
    _this.flow.data.invoiceId = context.invoice.payPalId;
    Log.debug('PaymentToRefund : ' + JSON.stringify(paymentToRefund) + ' with actual refund amount : ' + context.refundAmount);
    if (paymentToRefund) {
      _this.flow.data.transactionNumber = paymentToRefund.transactionID;
      _this.flow.data.paymentMethod = paymentToRefund.method;
    }

    _this.startFlow();
    return _this;
  }

  RefundFlow.prototype._removePaymentCancelListeners = function _removePaymentCancelListeners() {
    if (this.card) {
      this.card.reader.removeListener(_retailPaymentDevice.PaymentDevice.Event.cardRemoved, this.transactionCancelRequested);
      this.card.reader.removeListener(_retailPaymentDevice.PaymentDevice.Event.cancelRequested, this.transactionCancelRequested);
      this.card.reader.removeListener(_retailPaymentDevice.PaymentDevice.Event.cancelled, this.transactionCancelled);
    }
  };

  return RefundFlow;
}(_BaseTransactionFlow3.default);

exports.default = RefundFlow;

},{"./BaseTransactionFlow":"/Users/aravidas/Documents/Git/retail-sdk/js/flows/BaseTransactionFlow.js","./messageHelper":"/Users/aravidas/Documents/Git/retail-sdk/js/flows/messageHelper.js","./steps/CheckRefundEligibilityStep":"/Users/aravidas/Documents/Git/retail-sdk/js/flows/steps/CheckRefundEligibilityStep.js","./steps/IssueRefundStep":"/Users/aravidas/Documents/Git/retail-sdk/js/flows/steps/IssueRefundStep.js","./steps/ReceiptStep":"/Users/aravidas/Documents/Git/retail-sdk/js/flows/steps/ReceiptStep.js","./steps/RemoveCardStep":"/Users/aravidas/Documents/Git/retail-sdk/js/flows/steps/RemoveCardStep.js","./steps/UpdateInvoicePaymentStep":"/Users/aravidas/Documents/Git/retail-sdk/js/flows/steps/UpdateInvoicePaymentStep.js","manticore-log":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-log/index.js","retail-payment-device":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/js/flows/steps/CheckRefundEligibilityStep.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

var _manticoreLog = require('manticore-log');

var _manticoreLog2 = _interopRequireDefault(_manticoreLog);

var _moment = require('moment');

var _moment2 = _interopRequireDefault(_moment);

var _FlowStep2 = require('./FlowStep');

var _FlowStep3 = _interopRequireDefault(_FlowStep2);

var _Merchant = require('../../common/Merchant');

var _Merchant2 = _interopRequireDefault(_Merchant);

var _retailSDKUtil = require('../../common/retailSDKUtil');

var retailSDKUtil = _interopRequireWildcard(_retailSDKUtil);

var _sdkErrors = require('../../common/sdkErrors');

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (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 } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var Log = (0, _manticoreLog2.default)('flow.step.checkRefundEligibility');

var CheckRefundEligibilityFlowStep = function (_FlowStep) {
  _inherits(CheckRefundEligibilityFlowStep, _FlowStep);

  function CheckRefundEligibilityFlowStep(context) {
    _classCallCheck(this, CheckRefundEligibilityFlowStep);

    var _this = _possibleConstructorReturn(this, _FlowStep.call(this));

    _this.context = context;
    return _this;
  }

  CheckRefundEligibilityFlowStep.prototype.execute = function execute(flow) {
    if (!this.context.card) {
      flow.next();
      return;
    }

    if (flow.data.error) {
      Log.warn('Skip Issuing refund. Reason: One/more of previous steps logged an error');
      flow.next();
      return;
    }

    var rq = this._buildRequest(flow);
    _Merchant2.default.active.request({
      service: 'retail',
      op: 'checkouts/' + flow.data.transactionNumber + '/validateCard',
      format: 'json',
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(rq)
    }, function (error, refundResponse) {
      var actualError = null;
      if (!error && refundResponse.body && refundResponse.body.status !== 'ELIGIBLE') {
        actualError = _sdkErrors.transaction.refundCardMismatch;
      }
      flow.nextOrAbort(actualError);
    });
  };

  CheckRefundEligibilityFlowStep.prototype._buildRequest = function _buildRequest() {
    return {
      invoiceId: this.context.invoice.payPalId,
      dateTime: (0, _moment2.default)().format('YYYY-MM-DDTHH:mm:ssZZ'),
      card: retailSDKUtil.hereAPICardDataFromCard(this.context.card)
    };
  };

  return CheckRefundEligibilityFlowStep;
}(_FlowStep3.default);

exports.default = CheckRefundEligibilityFlowStep;

},{"../../common/Merchant":"/Users/aravidas/Documents/Git/retail-sdk/js/common/Merchant.js","../../common/retailSDKUtil":"/Users/aravidas/Documents/Git/retail-sdk/js/common/retailSDKUtil.js","../../common/sdkErrors":"/Users/aravidas/Documents/Git/retail-sdk/js/common/sdkErrors.js","./FlowStep":"/Users/aravidas/Documents/Git/retail-sdk/js/flows/steps/FlowStep.js","manticore-log":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-log/index.js","moment":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/moment/moment.js"}],"/Users/aravidas/Documents/Git/retail-sdk/js/flows/steps/FinalizePaymentStep.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

var _manticoreLog = require('manticore-log');

var _manticoreLog2 = _interopRequireDefault(_manticoreLog);

var _sdkErrors = require('../../common/sdkErrors');

var _FlowStep2 = require('./FlowStep');

var _FlowStep3 = _interopRequireDefault(_FlowStep2);

var _Merchant = require('../../common/Merchant');

var _Merchant2 = _interopRequireDefault(_Merchant);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (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 } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var Log = (0, _manticoreLog2.default)('flow.step.mft');

var FinalizePaymentStep = function (_FlowStep) {
  _inherits(FinalizePaymentStep, _FlowStep);

  function FinalizePaymentStep(context) {
    _classCallCheck(this, FinalizePaymentStep);

    var _this = _possibleConstructorReturn(this, _FlowStep.call(this));

    _this.context = context;
    _this.isContaclessMSDTransaction = context.card.isContactlessMSD;
    return _this;
  }

  FinalizePaymentStep.prototype.execute = function execute(flow) {
    var _this2 = this;

    if (flow.data.error) {
      Log.warn('Skipping Finalize payment. Reason: One/more of previous steps logged an error');
      flow.next();
      return;
    }

    if (!flow.data.signature) {
      if (!flow.data.cardResponse || this.isContaclessMSDTransaction) {
        Log.debug('Skipping Finalize payment');
        flow.next();
        return;
      }
    }
    var rq = this.buildRequest(flow);
    Log.debug('MFT request:\n' + JSON.stringify(rq, null, 4));
    _Merchant2.default.active.request({
      service: 'retail',
      op: 'checkouts/' + flow.data.tx.transactionHandle,
      format: 'json',
      method: 'PUT',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(rq)
    }, function (err, finalizeRz) {
      var mftError = err;
      var apiErrorCode = finalizeRz && finalizeRz.body && finalizeRz.body.errorCode;
      if (apiErrorCode) {
        // Give priority to here-api errors
        mftError = (0, _sdkErrors.payPalError)(_sdkErrors.domain.retail, apiErrorCode, finalizeRz.body.message).withDebugId(finalizeRz.body.correlationId);
      }
      Log.debug('MFT response:\n' + JSON.stringify(finalizeRz, null, '\t') + '\n');
      var sdkError = null;
      if (!finalizeRz || mftError) {
        Log.error('MFT Error: ' + JSON.stringify(mftError) + ', Invoice Total: ' + _this2.context.invoice.currency + ' ' + _this2.context.invoice.total + '\n ' + JSON.stringify(finalizeRz));
        sdkError = mftError || _sdkErrors.network.requestFailed;
        flow.abortFlow(sdkError);
        return;
      }

      if (!finalizeRz.body) {
        flow.abortFlow(_sdkErrors.network.requestFailed);
        return;
      }

      flow.data.tx.updateFromFinalize(finalizeRz.body);
      Log.info('(' + _this2.context.id + ') Finalize payment response received for invoice total: ' + _this2.context.invoice.currency + ' ' + _this2.context.invoice.total + ', ' + flow.data.tx.toString());
      flow.next();
    });
  };

  FinalizePaymentStep.prototype.buildRequest = function buildRequest(flow) {
    // TODO get the signature if available...
    var rq = { invoiceId: this.context.invoice.payPalId };
    // For contactless msd transactions, we should not be sending the emv data. Otherwise, the backend would throw an invoice already paid error.
    if (flow.data.cardResponse && !this.isContaclessMSDTransaction) {
      rq.emvData = flow.data.cardResponse.apdu.data.toString('hex');
      rq.responseCode = flow.data.tx.responseCode;
    }
    if (flow.data.signature) {
      rq.signature = flow.data.signature.toString('utf-8');
    }
    return rq;
  };

  return FinalizePaymentStep;
}(_FlowStep3.default);

exports.default = FinalizePaymentStep;

},{"../../common/Merchant":"/Users/aravidas/Documents/Git/retail-sdk/js/common/Merchant.js","../../common/sdkErrors":"/Users/aravidas/Documents/Git/retail-sdk/js/common/sdkErrors.js","./FlowStep":"/Users/aravidas/Documents/Git/retail-sdk/js/flows/steps/FlowStep.js","manticore-log":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-log/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/js/flows/steps/FlowStep.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

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; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

var FlowStep = function () {
  function FlowStep() {
    _classCallCheck(this, FlowStep);
  }

  FlowStep.prototype.execute = function execute() {
    throw new Error('FlowStep must define execute method.');
  };

  _createClass(FlowStep, [{
    key: 'flowStep',
    get: function get() {
      var self = this;
      var stepFn = function stepFn(flow) {
        self.execute(flow);
      };
      stepFn.fnName = this.constructor.name;
      return stepFn;
    }
  }]);

  return FlowStep;
}();

exports.default = FlowStep;

},{}],"/Users/aravidas/Documents/Git/retail-sdk/js/flows/steps/IssueRefundStep.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

var _manticoreLog = require('manticore-log');

var _manticoreLog2 = _interopRequireDefault(_manticoreLog);

var _paypalInvoicing = require('paypal-invoicing');

var _l10n = require('../../common/l10n');

var _l10n2 = _interopRequireDefault(_l10n);

var _Merchant = require('../../common/Merchant');

var _Merchant2 = _interopRequireDefault(_Merchant);

var _FlowStep2 = require('./FlowStep');

var _FlowStep3 = _interopRequireDefault(_FlowStep2);

var _TransactionRecord = require('../../transaction/TransactionRecord');

var _TransactionRecord2 = _interopRequireDefault(_TransactionRecord);

var _sdkErrors = require('../../common/sdkErrors');

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (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 } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var Log = (0, _manticoreLog2.default)('flow.step.issueRefund');

var IssueRefundStep = function (_FlowStep) {
  _inherits(IssueRefundStep, _FlowStep);

  function IssueRefundStep(context) {
    _classCallCheck(this, IssueRefundStep);

    var _this = _possibleConstructorReturn(this, _FlowStep.call(this));

    _this.context = context;
    return _this;
  }

  IssueRefundStep.prototype.execute = function execute(flow) {
    var _this2 = this;

    if (flow.data.error) {
      Log.warn('Skip Issuing refund. Reason: One/more of previous steps logged an error');
      flow.next();
      return;
    }
    var merchant = _Merchant2.default.active;
    var service = void 0;
    var op = void 0;
    var rq = void 0;
    if (flow.data.paymentMethod === _paypalInvoicing.InvoiceEnums.PaymentMethod.CASH || flow.data.paymentMethod === _paypalInvoicing.InvoiceEnums.PaymentMethod.CHECK) {
      if (!flow.data.invoiceId) {
        Log.error('No invoiceId found for refund. Aborting.');
        flow.abortFlow(_sdkErrors.transaction.missingInvoiceId);
        return;
      }
      service = 'invoicing';
      op = 'invoices/' + flow.data.invoiceId + '/record-refund';
      rq = {};
      Log.info('Issuing refund for check/cash with invoiceId: ' + flow.data.invoiceId + ', amount: ' + this.context.refundAmount);
    } else {
      if (!flow.data.transactionNumber) {
        Log.error('No transaction transactionNumber found. Aborting.');
        flow.abortFlow(_sdkErrors.transaction.missingTransactionNumber);
        return;
      }
      service = 'payments';
      op = 'sale/' + flow.data.transactionNumber + '/refund';
      rq = this._buildRequest(merchant);
      Log.info('(' + this.context.id + ') Issuing refund for transaction number: ' + flow.data.transactionNumber + ', amount: ' + this.context.refundAmount);
    }
    merchant.request({
      service: service,
      op: op,
      format: 'json',
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(rq)
    }, function (error, refundRz) {
      _this2._processResult(flow, error, refundRz);
    });
  };

  IssueRefundStep.prototype._buildRequest = function _buildRequest(merchant) {
    var rb = { is_non_platform_transaction: 'YES' };
    if (this.context.refundAmount) {
      rb.amount = {
        total: this.context.refundAmount,
        currency: merchant.currency
      };
    }
    return rb;
  };

  IssueRefundStep.prototype._processResult = function _processResult(flow, error, refundRz) {
    Log.debug(function () {
      return 'Response from refund is ' + JSON.stringify(refundRz, null, 4);
    });
    flow.data.tx = {};
    if (refundRz && refundRz.body) {
      flow.data.tx = new _TransactionRecord2.default(refundRz.body);
    } else if (flow.data.paymentMethod === _paypalInvoicing.InvoiceEnums.PaymentMethod.CASH || flow.data.paymentMethod === _paypalInvoicing.InvoiceEnums.PaymentMethod.CHECK) {
      // check/cash refund returns empty body
      flow.data.tx = new _TransactionRecord2.default({ invoiceId: flow.data.invoiceId });
    } else {
      Log.error('Neither card nor cash/check case! Check it out!');
    }

    if (error) {
      error.message = (0, _l10n2.default)('Tx.RefundFailed');
    } else {
      Log.info('(' + this.context.id + ') Successfully refunded. txRecord: ' + flow.data.tx);
    }
    flow.nextOrAbort(error);
  };

  return IssueRefundStep;
}(_FlowStep3.default);

exports.default = IssueRefundStep;

},{"../../common/Merchant":"/Users/aravidas/Documents/Git/retail-sdk/js/common/Merchant.js","../../common/l10n":"/Users/aravidas/Documents/Git/retail-sdk/js/common/l10n.js","../../common/sdkErrors":"/Users/aravidas/Documents/Git/retail-sdk/js/common/sdkErrors.js","../../transaction/TransactionRecord":"/Users/aravidas/Documents/Git/retail-sdk/js/transaction/TransactionRecord.js","./FlowStep":"/Users/aravidas/Documents/Git/retail-sdk/js/flows/steps/FlowStep.js","manticore-log":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-log/index.js","paypal-invoicing":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/js/flows/steps/MerchantTakePaymentStep.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

var _manticore = require('manticore');

var _manticore2 = _interopRequireDefault(_manticore);

var _moment = require('moment');

var _moment2 = _interopRequireDefault(_moment);

var _retailPaymentDevice = require('retail-payment-device');

var _manticoreLog = require('manticore-log');

var _manticoreLog2 = _interopRequireDefault(_manticoreLog);

var _manticoreUtil = require('manticore-util');

var _sdkErrors = require('../../common/sdkErrors');

var _FlowStep2 = require('./FlowStep');

var _FlowStep3 = _interopRequireDefault(_FlowStep2);

var _TransactionRecord = require('../../transaction/TransactionRecord');

var _TransactionRecord2 = _interopRequireDefault(_TransactionRecord);

var _retailSDKUtil = require('../../common/retailSDKUtil');

var retailSDKUtil = _interopRequireWildcard(_retailSDKUtil);

var _Merchant = require('../../common/Merchant');

var _Merchant2 = _interopRequireDefault(_Merchant);

var _PaymentType = require('../../transaction/PaymentType');

var _PaymentType2 = _interopRequireDefault(_PaymentType);

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (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 } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var Log = (0, _manticoreLog2.default)('flow.step.mtp');
var AuthCode = _retailPaymentDevice.PaymentDevice.authCode;

var MerchantTakePaymentStep = function (_FlowStep) {
  _inherits(MerchantTakePaymentStep, _FlowStep);

  function MerchantTakePaymentStep(context, voidFunc) {
    _classCallCheck(this, MerchantTakePaymentStep);

    var _this = _possibleConstructorReturn(this, _FlowStep.call(this));

    _this.context = context;
    _this.instrument = context.card;
    _this.voidFunc = voidFunc;
    _this.quickChipEnabled = context.paymentOptions && context.paymentOptions.quickChipEnabled;
    return _this;
  }

  MerchantTakePaymentStep.prototype.execute = function execute(flow) {
    var _this2 = this;

    if (this.context.paymentType === _PaymentType2.default.keyIn && !(this.instrument instanceof _retailPaymentDevice.ManuallyEnteredCard)) {
      flow.abort(_sdkErrors.transaction.cardTypeMismatch.withDevMessage('Expected card to be of type ManuallyEnteredCard'));
      return;
    }

    this._getLocation(function (err, location) {
      if (err) {
        Log.error('Error while retrieving location: ' + err);
        flow.abort(_sdkErrors.transaction.locationError.withDevMessage('Error while retrieving location information.'));
        return;
      }
      Log.debug('Retrieved location information : ' + JSON.stringify(location));
      flow.data.location = location;
      _this2._performMTP(flow);
    });
  };

  MerchantTakePaymentStep.prototype._performMTP = function _performMTP(flow) {
    var _this3 = this;

    var merchant = _Merchant2.default.active;
    var rq = this._buildRequest(flow.data.location);
    Log.debug(function () {
      return 'MTP request :\n' + JSON.stringify(rq, null, 4);
    });
    merchant.request({
      service: 'retail',
      op: 'checkouts',
      format: 'json',
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(rq)
    }, function (err, mtpRz) {
      var mtpError = err;
      var apiErrorCode = mtpRz && mtpRz.body && mtpRz.body.errorCode;
      var apiWarningsErrorCode = mtpRz && mtpRz.body && mtpRz.body.warnings && mtpRz.body.warnings[0];
      if (apiErrorCode) {
        // Give priority to here-api errors
        mtpError = (0, _sdkErrors.payPalError)(_sdkErrors.domain.retail, apiErrorCode, mtpRz.body.message).withDebugId(mtpRz.body.correlationId);
      }
      if (apiWarningsErrorCode) {
        // Give priority to here-api errors
        mtpError = (0, _sdkErrors.payPalError)(_sdkErrors.domain.retail, mtpRz.body.warnings[0].errorCode, mtpRz.body.warnings[0].message).withDebugId(mtpRz.body.correlationId);
      }
      Log.debug(function () {
        return 'MTP response: ' + JSON.stringify(mtpRz, null, 4);
      });
      flow.data.tx = mtpRz && mtpRz.body ? new _TransactionRecord2.default(mtpRz.body) : {};
      flow.data.tx.card = _this3.context.card;

      // For all non card reader transactions, finish the flow and move on.
      if (_this3.context.paymentType !== _PaymentType2.default.card) {
        flow.nextOrAbort(mtpError);
        return;
      }

      var mtpRzAuthCode = mtpRz && mtpRz.body && mtpRz.body.authCode && mtpRz.body.authCode !== 'null' ? mtpRz.body.authCode : null;

      var isEmv = rq && rq.card && rq.card.emvData && (_this3.instrument.formFactor === _retailPaymentDevice.FormFactor.Chip || _this3.instrument.formFactor === _retailPaymentDevice.FormFactor.EmvCertifiedContactless);

      if (mtpError) {
        Log.error('MTP Error: ' + JSON.stringify(mtpError) + ', isEmv: ' + isEmv + ', formFactor: ' + _this3.instrument.formFactor + ',' + ('Invoice Total: ' + _this3.context.invoice.currency + ' ' + _this3.context.invoice.total + ',') + ('rz.statusCode: ' + (mtpRz ? mtpRz.statusCode : 'empty') + ', rz.body: ' + JSON.stringify(mtpRz ? mtpRz.body : {})));
      } else {
        Log.info('(' + _this3.context.id + ') MTP response received for invoice total: ' + _this3.context.invoice.currency + ' ' + _this3.context.invoice.total + ',' + ('ff: ' + (0, _manticoreUtil.getPropertyName)(_retailPaymentDevice.FormFactor, _this3.instrument.formFactor) + ', AuthCode: ' + (mtpRz && mtpRz.body && mtpRz.body.authCode) + ',') + ('' + flow.data.tx.toString()));
      }

      _this3._processResult(isEmv, mtpRzAuthCode, flow, mtpError);
    });
  };

  MerchantTakePaymentStep.prototype._processResult = function _processResult(isEmv, rzAuthCode, flow, mtpError) {
    var _this4 = this;

    var cbStepComplete = function cbStepComplete(error, rz) {
      flow.data.cardResponse = rz;

      // If we encountered an error while waiting on an MTP response and it eventually succeeded then we need to void.
      if (flow.data.error) {
        Log.info('(' + _this4.context.id + ') Voiding tx as flow was aborted when MTP request was in flight with error: ' + JSON.stringify(flow.data.error));
        if (_this4.voidFunc) {
          _this4.voidFunc(flow.data);
        }
        return;
      }

      flow.nextOrAbort(mtpError || error);
    };

    if (isEmv) {
      // For EMV, even if we don't get an auth code from the server, we need to make one so the card
      // can function correctly. So if we got an error, we can assume failure.
      // TODO really, we want to assume success?
      if (rzAuthCode) {
        // Before we go to the next step in the flow for EMV, we need to tell the card what we got from MTP
        flow.data.tx.authCode = rzAuthCode;
      } else {
        flow.data.tx.authCode = AuthCode.TransactionSuccess;
        if (mtpError) {
          flow.data.tx.authCode = mtpError.code === _sdkErrors.network.networkOffline.code ? AuthCode.NoNetwork : AuthCode.TransactionFailure;
        }
      }
      if (this.quickChipEnabled) {
        // use the same EMV data for Finalize Payment
        cbStepComplete(null, this.instrument.emvData);
      } else {
        this._pushAuthCode(flow.data.tx.authCode, cbStepComplete);
      }
    } else {
      cbStepComplete(null, null);
    }
  };

  MerchantTakePaymentStep.prototype._pushAuthCode = function _pushAuthCode(authCode, cb) {
    var _this5 = this;

    // Before we go to the next step in the flow for EMV, we need to tell the card what we got from MTP
    Log.debug('Pushing authCode : ' + authCode + ' to ' + this.instrument.reader.id);
    this.instrument.reader.completeTransaction(authCode, function (error, rz) {
      if (error) {
        Log.error('(' + _this5.context.id + ') Error response on pushing auth code to terminal-' + error);
        cb(error, rz);
        return;
      }
      Log.info('(' + _this5.context.id + ') Pushed auth code (' + authCode + ') to reader ' + _this5.instrument.reader.id + '. Response template: ' + (rz.apdu ? rz.apdu.template : ''));
      cb(null, rz);
    });
  };

  MerchantTakePaymentStep.prototype._getLocation = function _getLocation(callback) {
    Log.debug('getLocation');
    _manticore2.default.getLocation(callback);
  };

  MerchantTakePaymentStep.prototype._buildRequest = function _buildRequest(location) {
    var _this6 = this;

    var request = {
      invoiceId: this.context.invoice.payPalId,
      paymentType: this.context.paymentType,
      latitude: location.latitude || 0,
      longitude: location.longitude || 0,
      dateTime: (0, _moment2.default)().format()
    };

    if (this.context.type === _retailPaymentDevice.TransactionType.Auth) {
      Log.debug(function () {
        return _this6.context.id + ' MTP setting the transaction type to AUTH, expiry & honor period';
      });
      request.paymentAction = 'authorization';
      if (_Merchant2.default.active.status && _Merchant2.default.active.status.cardSettings) {
        request.authExpiryPeriod = _Merchant2.default.active.status.cardSettings.authExpiryPeriod;
        request.authHonorPeriod = _Merchant2.default.active.status.cardSettings.authHonorPeriod;
      }
    }

    if (this.context.paymentType === _PaymentType2.default.card) {
      var card = retailSDKUtil.hereAPICardDataFromCard(this.instrument);
      if (this.instrument.formFactor !== _retailPaymentDevice.FormFactor.MagneticCardSwipe) {
        card.pinPresent = !!this.context.pinPresent;
      }
      card.signatureRequired = this.instrument.isSignatureRequired;
      request.dateTime = this.instrument.timestamp || request.dateTime;
      request.card = card;
    }

    if (this.context.paymentType === _PaymentType2.default.keyIn) {
      var expiration = this.instrument.getExpiration() || ''; // in format MMYYYY
      request.paymentType = _PaymentType2.default.card;
      request.card = {
        inputType: _PaymentType2.default.keyIn,
        accountNumber: this.instrument.getCardNumber(),
        expirationMonth: expiration.substr(0, 2),
        expirationYear: expiration.substr(2, 4),
        cvv: this.instrument.getCVV()
      };
    }
    return request;
  };

  return MerchantTakePaymentStep;
}(_FlowStep3.default);

exports.default = MerchantTakePaymentStep;

},{"../../common/Merchant":"/Users/aravidas/Documents/Git/retail-sdk/js/common/Merchant.js","../../common/retailSDKUtil":"/Users/aravidas/Documents/Git/retail-sdk/js/common/retailSDKUtil.js","../../common/sdkErrors":"/Users/aravidas/Documents/Git/retail-sdk/js/common/sdkErrors.js","../../transaction/PaymentType":"/Users/aravidas/Documents/Git/retail-sdk/js/transaction/PaymentType.js","../../transaction/TransactionRecord":"/Users/aravidas/Documents/Git/retail-sdk/js/transaction/TransactionRecord.js","./FlowStep":"/Users/aravidas/Documents/Git/retail-sdk/js/flows/steps/FlowStep.js","manticore":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore/browser.js","manticore-log":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-log/index.js","manticore-util":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-util/build/index.js","moment":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/moment/moment.js","retail-payment-device":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/js/flows/steps/QuickChipStep.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

var _retailPaymentDevice = require('retail-payment-device');

var _manticoreLog = require('manticore-log');

var _manticoreLog2 = _interopRequireDefault(_manticoreLog);

var _FlowStep2 = require('./FlowStep');

var _FlowStep3 = _interopRequireDefault(_FlowStep2);

var _messageHelper = require('../messageHelper');

var messageHelper = _interopRequireWildcard(_messageHelper);

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (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 } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var Log = (0, _manticoreLog2.default)('flow.step.qc');
var AuthCode = _retailPaymentDevice.PaymentDevice.authCode;

/**
 * Handles Quick Chip Steps,
 * . Send 'Z3' auth code to reader
 * . Send "Remove card" message to he reader
 * . Remove cardRemoved listener
 */

var QuickChipStep = function (_FlowStep) {
  _inherits(QuickChipStep, _FlowStep);

  function QuickChipStep(context) {
    _classCallCheck(this, QuickChipStep);

    var _this = _possibleConstructorReturn(this, _FlowStep.call(this));

    _this.context = context;
    _this.card = context.card;
    return _this;
  }

  QuickChipStep.prototype.execute = function execute(flow) {
    var _this2 = this;

    var cbStepComplete = function cbStepComplete(error, rz) {
      flow.data.cardResponse = rz;

      messageHelper.showRemoveCardForQCMessage(_this2.context, flow.data, function (alert) {
        flow.data.alert = alert;
        flow.next();
      });
    };
    if (this.card && this.card.formFactor === _retailPaymentDevice.FormFactor.Chip) {
      this._pushAuthCode(AuthCode.NoNetwork, this.card, cbStepComplete);
    } else {
      flow.next();
    }
  };

  QuickChipStep.prototype._pushAuthCode = function _pushAuthCode(authCode, card, cb) {
    Log.debug(function () {
      return 'Pushing authCode: ' + authCode + ' to ' + card.reader.id;
    });
    card.reader.completeTransaction(authCode, function (error, rz) {
      card.qcAuthSend = true;
      cb(null, rz);
    });
  };

  return QuickChipStep;
}(_FlowStep3.default);

exports.default = QuickChipStep;

},{"../messageHelper":"/Users/aravidas/Documents/Git/retail-sdk/js/flows/messageHelper.js","./FlowStep":"/Users/aravidas/Documents/Git/retail-sdk/js/flows/steps/FlowStep.js","manticore-log":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-log/index.js","retail-payment-device":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/js/flows/steps/ReceiptStep.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

var _retailPaymentDevice = require('retail-payment-device');

var _manticore = require('manticore');

var _manticore2 = _interopRequireDefault(_manticore);

var _manticoreLog = require('manticore-log');

var _manticoreLog2 = _interopRequireDefault(_manticoreLog);

var _retailPageTracker = require('retail-page-tracker');

var _ReceiptViewContent = require('../../transaction/ReceiptViewContent');

var _l10n = require('../../common/l10n');

var _l10n2 = _interopRequireDefault(_l10n);

var _FlowStep2 = require('./FlowStep');

var _FlowStep3 = _interopRequireDefault(_FlowStep2);

var _retailSDKUtil = require('../../common/retailSDKUtil');

var _Merchant = require('../../common/Merchant');

var _Merchant2 = _interopRequireDefault(_Merchant);

var _ReceiptDestination = require('../../transaction/ReceiptDestination');

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (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 } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var Log = (0, _manticoreLog2.default)('flow.step.receipt');

var ReceiptStep = function (_FlowStep) {
  _inherits(ReceiptStep, _FlowStep);

  function ReceiptStep(context) {
    _classCallCheck(this, ReceiptStep);

    var _this = _possibleConstructorReturn(this, _FlowStep.call(this));

    _this.context = context;
    return _this;
  }

  ReceiptStep.prototype.execute = function execute(flow) {
    var _this2 = this;

    var ff = [_retailPaymentDevice.FormFactor.Chip, _retailPaymentDevice.FormFactor.EmvCertifiedContactless, _retailPaymentDevice.FormFactor.MagneticCardSwipe];
    this.context.deactivateFormFactors(ff, function () {});

    if (flow.data.alert) {
      flow.data.alert.dismiss();
      delete flow.data.alert;
    }

    if (this.context.type === _retailPaymentDevice.TransactionType.Auth) {
      Log.debug('Skipping receipt step for Auth');
      flow.next();
      return;
    }

    flow.data.tx = flow.data.tx || {}; // Failures prior to payment/refund may not have the transaction record
    var invoice = this.context.invoice;
    var tx = flow.data.tx;
    var error = flow.data.error;
    var amount = (0, _retailSDKUtil.getAmountWithCurrencySymbol)(invoice.currency, this.context.refundAmount || invoice.total);
    var viewContent = new _ReceiptViewContent.ReceiptViewContent(amount, this.context.isRefund(), error, tx && tx.payer && tx.payer.maskedEmail, tx && tx.payer && tx.payer.maskedPhone, this.context.additionalReceiptOptions);

    _manticore2.default.offerReceipt({
      invoice: invoice,
      error: flow.data.error,
      viewContent: viewContent
    }, function (err, option) {
      if (option) {
        if (option.name === 'emailOrSms') {
          _this2._sendReceipt(flow, option.value, invoice, tx);
        } else {
          Log.info('(' + _this2.context.id + ') Custom receipt option selected ' + option.value + ':' + option.name);
          if (_this2.context.receiptHandler) {
            _this2.context.receiptHandler(option.value, option.name, flow.data.tx);
          }
          _retailPageTracker.Tracker.publishPageView(null, _this2.context.isRefund() ? _retailPageTracker.pages.refundReceiptCustom.withAction(option.name) : _retailPageTracker.pages.paymentReceiptCustom.withAction(option.name));
        }
      } else {
        _retailPageTracker.Tracker.publishPageView(null, _this2.context.isRefund() ? _retailPageTracker.pages.refundReceiptNoThanks : _retailPageTracker.pages.paymentReceiptNoThanks);
        Log.debug(function () {
          return 'Email/SMS receipt forwarding not required. Skipping receipt step. Native response: ' + option;
        });
        flow.next();
      }
    });
  };

  ReceiptStep.prototype._sendReceipt = function _sendReceipt(flow, emailOrSms, invoice, tx) {
    var _this3 = this;

    Log.debug(function () {
      return 'Forward receipt to ' + emailOrSms;
    });
    var alert = _manticore2.default.alert({
      showActivity: true,
      title: (0, _l10n2.default)('Rcpt.Sending')
    }, function () {
      // TODO add cancel button support.
    });
    var txNumber = tx && (tx.transactionHandle || tx.transactionNumber) || flow.data.transactionNumber;
    var txType = this._transactionType(flow);
    var customerId = void 0;
    var receiptPreferenceToken = void 0;
    if (tx && tx.payer) {
      customerId = tx.payer.customerId;
      receiptPreferenceToken = tx.payer.receiptPreferenceToken;
    }
    _Merchant2.default.active.forwardReceipt(invoice, emailOrSms, txNumber, txType, customerId, receiptPreferenceToken, function (err) {
      if (err) {
        Log.error('Send receipt failed with ' + JSON.stringify(err));
      } else {
        Log.info('(' + _this3.context.id + ') Successfully forwarded receipt to ' + emailOrSms + ' for txNumber: ' + txNumber);
        if (!tx.receiptDestination) {
          tx.receiptDestination = new _ReceiptDestination.ReceiptDestination();
        }
        if (emailOrSms.indexOf('@') > 0) {
          tx.receiptDestination.type = _ReceiptDestination.ReceiptDestinationType.email;
          tx.receiptDestination.email = emailOrSms;
        } else {
          tx.receiptDestination.type = _ReceiptDestination.ReceiptDestinationType.text;
        }
      }
      alert.dismiss();
      flow.next();
    });
  };

  ReceiptStep.prototype._transactionType = function _transactionType(flow) {
    if (flow.data.error) {
      return (0, _retailSDKUtil.transactionCancelledError)(flow.data.error) ? 'VOID' : 'DECLINE';
    }
    if (this.context.type === _retailPaymentDevice.TransactionType.Refund) {
      return 'REFUND';
    } else if (this.context.type === _retailPaymentDevice.TransactionType.PartialRefund) {
      return 'PARTIAL';
    }
    return 'SALE';
  };

  return ReceiptStep;
}(_FlowStep3.default);

exports.default = ReceiptStep;

},{"../../common/Merchant":"/Users/aravidas/Documents/Git/retail-sdk/js/common/Merchant.js","../../common/l10n":"/Users/aravidas/Documents/Git/retail-sdk/js/common/l10n.js","../../common/retailSDKUtil":"/Users/aravidas/Documents/Git/retail-sdk/js/common/retailSDKUtil.js","../../transaction/ReceiptDestination":"/Users/aravidas/Documents/Git/retail-sdk/js/transaction/ReceiptDestination.js","../../transaction/ReceiptViewContent":"/Users/aravidas/Documents/Git/retail-sdk/js/transaction/ReceiptViewContent.js","./FlowStep":"/Users/aravidas/Documents/Git/retail-sdk/js/flows/steps/FlowStep.js","manticore":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore/browser.js","manticore-log":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-log/index.js","retail-page-tracker":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-page-tracker/build/index.js","retail-payment-device":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/js/flows/steps/RemoveCardStep.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

var _retailPaymentDevice = require('retail-payment-device');

var _FlowStep2 = require('./FlowStep');

var _FlowStep3 = _interopRequireDefault(_FlowStep2);

var _messageHelper = require('../messageHelper');

var messageHelper = _interopRequireWildcard(_messageHelper);

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (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 } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

/**
 * Wait for the card to be removed from the reader before continuing.
 */
var RemoveCardStep = function (_FlowStep) {
  _inherits(RemoveCardStep, _FlowStep);

  function RemoveCardStep(context) {
    _classCallCheck(this, RemoveCardStep);

    var _this = _possibleConstructorReturn(this, _FlowStep.call(this));

    _this.context = context;
    return _this;
  }

  RemoveCardStep.prototype.execute = function execute(flow) {
    var cardContext = this.context.card;
    if (cardContext && cardContext.formFactor === _retailPaymentDevice.FormFactor.Chip) {
      cardContext.reader.waitForCardRemoval(function () {
        if (flow.data.alert) {
          flow.data.alert.dismiss();
          delete flow.data.alert;
        }
        flow.next();
      });
      messageHelper.showRemoveCardMessage(this.context, flow.data, function (alert) {
        flow.data.alert = alert;
      });
    } else {
      flow.next();
    }
  };

  return RemoveCardStep;
}(_FlowStep3.default);

exports.default = RemoveCardStep;

},{"../messageHelper":"/Users/aravidas/Documents/Git/retail-sdk/js/flows/messageHelper.js","./FlowStep":"/Users/aravidas/Documents/Git/retail-sdk/js/flows/steps/FlowStep.js","retail-payment-device":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/js/flows/steps/SignatureStep.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

var _retailPaymentDevice = require('retail-payment-device');

var _manticoreLog = require('manticore-log');

var _manticoreLog2 = _interopRequireDefault(_manticoreLog);

var _SignatureReceiver = require('../../transaction/SignatureReceiver');

var _SignatureReceiver2 = _interopRequireDefault(_SignatureReceiver);

var _transactionEvent = require('../../transaction/transactionEvent');

var _transactionEvent2 = _interopRequireDefault(_transactionEvent);

var _FlowStep2 = require('./FlowStep');

var _FlowStep3 = _interopRequireDefault(_FlowStep2);

var _messageHelper = require('../messageHelper');

var messageHelper = _interopRequireWildcard(_messageHelper);

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (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 } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var Log = (0, _manticoreLog2.default)('flow.step.signature');
var Message = _retailPaymentDevice.PaymentDevice.Message;

var SignatureStep = function (_FlowStep) {
  _inherits(SignatureStep, _FlowStep);

  function SignatureStep(context) {
    _classCallCheck(this, SignatureStep);

    var _this = _possibleConstructorReturn(this, _FlowStep.call(this));

    _this.context = context;
    _this.quickChipEnabled = context.paymentOptions && context.paymentOptions.quickChipEnabled;
    return _this;
  }

  SignatureStep.prototype.execute = function execute(flow) {
    var _this2 = this;

    if (this.context.card.isSignatureRequired === false || this.context.type === _retailPaymentDevice.TransactionType.Auth) {
      Log.debug('Skipping signature step. Reason: Signature not required for this transaction');
      flow.next();
      return;
    }

    this.context.emit(_transactionEvent2.default.willPresentSignature);
    if (flow.data.error) {
      Log.debug('Skipping signature step. Reason: One/more of previous steps logged an error');
      flow.next();
      return;
    }

    var signatureReceiver = new _SignatureReceiver2.default(this.context, function (err, b64Signature) {
      flow.removeListener('aborted', _this2.dismissSignature);
      flow.data.signature = b64Signature;
      Log.info('(' + _this2.context.id + ') Signature collected. err? ' + !!err);
      flow.nextOrAbort(err);
    });

    this.dismissSignature = function () {
      signatureReceiver.dismiss();
    };
    flow.once('aborted', this.dismissSignature);
    var substitutions = messageHelper.formattedInvoiceTotal(this.context.invoice);
    var messageId = SignatureStep.getReaderDisplayMessage(this.context.card, this.quickChipEnabled);

    this.context.card.reader.display({ id: messageId, substitutions: substitutions }, function () {
      if (flow.data.alert) {
        flow.data.alert.dismiss();
      }
      if (_this2.context._signatureCollector) {
        _this2.context._signatureCollector(signatureReceiver);
      } else {
        signatureReceiver.acquireSignature();
      }
    });
  };

  SignatureStep.getReaderDisplayMessage = function getReaderDisplayMessage(card, quickChipEnabled) {
    if (card.formFactor === _retailPaymentDevice.FormFactor.Chip) {
      return quickChipEnabled ? Message.SignatureForInsertQCCR : Message.SignatureForInsert;
    }

    if (card.formFactor === _retailPaymentDevice.FormFactor.EmvCertifiedContactless && !card.isContactlessMSD) {
      return Message.SignatureForTap;
    }
    return Message.SignatureForNonEmv;
  };

  return SignatureStep;
}(_FlowStep3.default);

exports.default = SignatureStep;

},{"../../transaction/SignatureReceiver":"/Users/aravidas/Documents/Git/retail-sdk/js/transaction/SignatureReceiver.js","../../transaction/transactionEvent":"/Users/aravidas/Documents/Git/retail-sdk/js/transaction/transactionEvent.js","../messageHelper":"/Users/aravidas/Documents/Git/retail-sdk/js/flows/messageHelper.js","./FlowStep":"/Users/aravidas/Documents/Git/retail-sdk/js/flows/steps/FlowStep.js","manticore-log":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-log/index.js","retail-payment-device":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/js/flows/steps/UpdateInvoicePaymentStep.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

var _moment = require('moment');

var _moment2 = _interopRequireDefault(_moment);

var _retailPaymentDevice = require('retail-payment-device');

var _paypalInvoicing = require('paypal-invoicing');

var _FlowStep2 = require('./FlowStep');

var _FlowStep3 = _interopRequireDefault(_FlowStep2);

var _retailSDKUtil = require('../../common/retailSDKUtil');

var retailSDKUtils = _interopRequireWildcard(_retailSDKUtil);

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (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 } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var UpdateInvoicePaymentStep = function (_FlowStep) {
  _inherits(UpdateInvoicePaymentStep, _FlowStep);

  function UpdateInvoicePaymentStep(context) {
    _classCallCheck(this, UpdateInvoicePaymentStep);

    var _this = _possibleConstructorReturn(this, _FlowStep.call(this));

    _this.context = context;
    return _this;
  }

  UpdateInvoicePaymentStep.prototype.execute = function execute(flow) {
    var error = flow.data.error;
    if (!error) {
      var invoice = this.context.invoice;
      var stubPayment = new _paypalInvoicing.InvoicePayment();
      stubPayment.type = _paypalInvoicing.InvoiceEnums.PaymentType.EXTERNAL;
      stubPayment.transactionID = flow.data.tx.transactionNumber;
      stubPayment.transactionType = this.context.type === _retailPaymentDevice.TransactionType.Auth ? 'AUTHORIZATION' : 'SALE';
      stubPayment.date = (0, _moment2.default)();
      stubPayment.method = retailSDKUtils.getInvoiceEnumFromPaymentType(this.context.paymentType);
      stubPayment.amount = invoice.total;
      stubPayment.currency = invoice.currency;
      if (invoice.payments) {
        invoice.payments.push(stubPayment);
      } else {
        invoice.payments = [stubPayment];
      }
      invoice.status = _paypalInvoicing.InvoiceEnums.Status.PAID;
      if (this.context.refundAmount) {
        stubPayment.transactionType = 'REFUND';
        invoice.status = _paypalInvoicing.InvoiceEnums.Status.REFUNDED;
        if (this.context.refundAmount.lessThan(invoice.total)) {
          invoice.status = _paypalInvoicing.InvoiceEnums.Status.PARTIALLY_REFUNDED;
        }
        invoice.refundedAmount = this.context.refundAmount;
      }
    } else if (retailSDKUtils.transactionCancelledError(error)) {
      this.context.invoice.isCancelled = true;
    } else {
      this.context.invoice.isFailed = true;
    }
    flow.next();
  };

  return UpdateInvoicePaymentStep;
}(_FlowStep3.default);

exports.default = UpdateInvoicePaymentStep;

},{"../../common/retailSDKUtil":"/Users/aravidas/Documents/Git/retail-sdk/js/common/retailSDKUtil.js","./FlowStep":"/Users/aravidas/Documents/Git/retail-sdk/js/flows/steps/FlowStep.js","moment":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/moment/moment.js","paypal-invoicing":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/index.js","retail-payment-device":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/js/index.js":[function(require,module,exports){
(function (global){
'use strict';

var _NetworkResponse = require('./common/NetworkHandler/NetworkResponse');

var _NetworkResponse2 = _interopRequireDefault(_NetworkResponse);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

if (!global._babelPolyfill) {
  require('core-js/es6/symbol');
  require('core-js/es6/set');
  require('core-js/fn/string/includes');
  require('core-js/fn/object/is');
  require('core-js/fn/array/of');
  require('core-js/fn/array/from');
  require('core-js/fn/array/find');
  require('core-js/fn/array/find-index');
  require('core-js/fn/symbol/iterator');
} /* eslint-disable global-require */


var Log = require('manticore-log')('root');

// TODO configure logging

var SDK = require('./sdk');
var m = require('manticore');

global.Promise = require('yaku');
global.regeneratorRuntime = require('babel-regenerator-runtime');

if (!global.setTimeout) {
  global.setTimeout = function _setTimeout(fn, time) {
    return m.setTimeout(fn, time || 0);
  };
}

try {
  Log.debug('Beginning SDK initialization.');
  m.export(require('retail-payment-device'));
  m.export(require('./paymentDevice/index'));
  m.export(require('./transaction/index'));
  m.export(_NetworkResponse2.default);
  m.export(require('paypal-invoicing'));
  m.export(require('manticore-paypalerror'));
  m.export(require('./common/RetailInvoice'));
  m.export(require('./common/SdkEnvironmentInfo'));
  m.ready(SDK);
  Log.debug('SDK initialization complete.');
} catch (error) {
  Log.error('Failed to complete initialization: ' + error.message + '\n' + error.stack);
}

// // Alert dialog samples
// require('./alertDialogSamples');

/* eslint-enable global-require */

}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
},{"./common/NetworkHandler/NetworkResponse":"/Users/aravidas/Documents/Git/retail-sdk/js/common/NetworkHandler/NetworkResponse.js","./common/RetailInvoice":"/Users/aravidas/Documents/Git/retail-sdk/js/common/RetailInvoice.js","./common/SdkEnvironmentInfo":"/Users/aravidas/Documents/Git/retail-sdk/js/common/SdkEnvironmentInfo.js","./paymentDevice/index":"/Users/aravidas/Documents/Git/retail-sdk/js/paymentDevice/index.js","./sdk":"/Users/aravidas/Documents/Git/retail-sdk/js/sdk.js","./transaction/index":"/Users/aravidas/Documents/Git/retail-sdk/js/transaction/index.js","babel-regenerator-runtime":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/babel-regenerator-runtime/runtime.js","core-js/es6/set":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/es6/set.js","core-js/es6/symbol":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/es6/symbol.js","core-js/fn/array/find":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/fn/array/find.js","core-js/fn/array/find-index":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/fn/array/find-index.js","core-js/fn/array/from":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/fn/array/from.js","core-js/fn/array/of":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/fn/array/of.js","core-js/fn/object/is":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/fn/object/is.js","core-js/fn/string/includes":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/fn/string/includes.js","core-js/fn/symbol/iterator":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/fn/symbol/iterator.js","manticore":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore/browser.js","manticore-log":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-log/index.js","manticore-paypalerror":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-paypalerror/build/index.js","paypal-invoicing":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/index.js","retail-payment-device":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/index.js","yaku":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/yaku/lib/yaku.js"}],"/Users/aravidas/Documents/Git/retail-sdk/js/ingenico-emv/CardStatus.js":[function(require,module,exports){
(function (Buffer){
'use strict';

exports.__esModule = true;

var _retailPaymentDevice = require('retail-payment-device');

var _manticoreLog = require('manticore-log');

var _manticoreLog2 = _interopRequireDefault(_manticoreLog);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

var Log = (0, _manticoreLog2.default)('ingenico.cardStatus');

/**
 * Contain the details of card events on the Ingenico terminal such as insertion,
 * swipe, removal, etc.
 */

var CardStatus = function () {
  function CardStatus(response) {
    var _this = this;

    _classCallCheck(this, CardStatus);

    this.response = response;
    this.isSignatureRequired = false;
    var statusBuf = this.response.getStatus();
    if (statusBuf === 0x91 || statusBuf === 0x90) {
      // 0x90 is for contact refund decline
      this.formFactor = _retailPaymentDevice.FormFactor.Chip;
    } else if (statusBuf === 0x94 || statusBuf === 0x93) {
      // 0x93 is for contactless refunds
      this.formFactor = _retailPaymentDevice.FormFactor.EmvCertifiedContactless;
    } else if (statusBuf === 0x95) {
      this.formFactor = _retailPaymentDevice.FormFactor.MagneticCardSwipe;
    }

    for (var _iterator = this.response.apdu.tlvs.values, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
      var _ref;

      if (_isArray) {
        if (_i >= _iterator.length) break;
        _ref = _iterator[_i++];
      } else {
        _i = _iterator.next();
        if (_i.done) break;
        _ref = _i.value;
      }

      var v = _ref;

      if (v.tagNumber === 0x9f39) {
        (function () {
          var contactlessInfoByte = v.parse();
          Log.debug(function () {
            return 'contactlessInfoByte = ' + contactlessInfoByte;
          });
          _this.emv = contactlessInfoByte === 0x07;
        })();
      } else if (v.tagNumber === 0xdf8225) {
        Log.debug('parsing ksn (tag 0xdf8225)');
        this.ksn = v.parse();
        Log.debug(function () {
          return 'ksn (tag 0xdf8225) = ' + _this.ksn.toString('hex');
        });
      } else if (v.tagNumber === 0xdf8223) {
        this.sredData = v.parse();
      } else if (v.tagNumber === 0xdf8256) {
        this.maskedTrack1 = v.parse();
      } else if (v.tagNumber === 0xdf8257) {
        this.maskedTrack2 = v.parse();
      } else if (v.tagNumber === 0xdfae03) {
        Log.debug('parsing ksn (tag 0xdfae03)');
        this.ksn = v.parse();
        Log.debug(function () {
          return 'ksn (tag 0xdfae03) = ' + _this.ksn.toString('hex');
        });
      } else if (v.tagNumber === 0xdfae02) {
        this.sredData = v.parse();
      } else if (v.tagNumber === 0x9f34 && this.formFactor === _retailPaymentDevice.FormFactor.Chip) {
        (function () {
          // Contact cvm
          var contactCvmVal = v.parse();
          _this.checkVal = contactCvmVal[0];
          Log.debug(function () {
            return 'checkval = ' + _this.checkVal;
          });
          Log.debug(function () {
            return 'tag 0x9f34 = ' + contactCvmVal.toString('hex');
          });
          _this.isSignatureRequired = (contactCvmVal[0] & 0x3f) === 0x1e;
          Log.debug(function () {
            return 'tag 0x9f34 isSignatureRequired= ' + _this.isSignatureRequired;
          });
        })();
      } else if (v.tagNumber === 0xdf6f && this.formFactor === _retailPaymentDevice.FormFactor.EmvCertifiedContactless) {
        (function () {
          // Contactless cvm
          var contactlessCvmVal = v.parse();
          Log.debug(function () {
            return 'tag 0xdf6f = ' + contactlessCvmVal.toString('hex');
          });
          _this.isSignatureRequired = (contactlessCvmVal[1] & 0x01) === 0x01;
          Log.debug(function () {
            return 'tag 0xdf6f isSignatureRequired= ' + _this.isSignatureRequired;
          });
        })();
      }
    }
    this.p2pe = this.response.apdu.data.slice(1).toString('hex');
  }

  CardStatus.prototype.getPresentedCard = function getPresentedCard(reader) {
    var _this2 = this;

    var card = void 0;

    Log.debug('getPresentedCard');
    if (this.formFactor === _retailPaymentDevice.FormFactor.MagneticCardSwipe) {
      Log.debug('Card Swiped');
      return this._magstripe(reader);
    }
    for (var _iterator2 = this.response.apdu.tlvs.values, _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) {
      var _ref2;

      if (_isArray2) {
        if (_i2 >= _iterator2.length) break;
        _ref2 = _iterator2[_i2++];
      } else {
        _i2 = _iterator2.next();
        if (_i2.done) break;
        _ref2 = _i2.value;
      }

      var v = _ref2;

      if (v.tagNumber === 0x50) {
        var cardIssuer = v.parse();
        if (typeof cardIssuer === 'string' && /^[a-zA-Z\s]+$/.test(cardIssuer)) {
          this.cardIssuer = _retailPaymentDevice.CardDataUtil.getCardIssuerFromEmvAppLabel(cardIssuer);
        }
      }
      if (v.tagNumber === 0x57) {
        var lastFour = v.parse();
        lastFour = lastFour.toString('hex');
        var lastFourNumbers = lastFour.substr(0, lastFour.indexOf('d'));
        this.lastFour = lastFourNumbers.substr(lastFourNumbers.length - 4);
      }
    }
    if (this.formFactor === _retailPaymentDevice.FormFactor.Chip) {
      card = new _retailPaymentDevice.Card();
      card.formFactor = _retailPaymentDevice.FormFactor.Chip;
      card.reader = reader;
      card.emvData = this.response;
      card.cardIssuer = this.cardIssuer;
      card.lastFourDigits = this.lastFour;
      card.isSignatureRequired = this.isSignatureRequired;
      Log.debug('EMV Card Inserted');
      return card;
    }

    if (this.formFactor === _retailPaymentDevice.FormFactor.EmvCertifiedContactless) {
      Log.debug('EMV Card Contactless');
      card = new _retailPaymentDevice.Card();
      card.formFactor = _retailPaymentDevice.FormFactor.EmvCertifiedContactless;
      card.emvData = this.response;
      card.reader = reader;
      card.isContactlessMSD = !this.emv;
      card.cardIssuer = this.cardIssuer;
      card.lastFourDigits = this.lastFour;
      card.isSignatureRequired = this.isSignatureRequired;
      return card;
    }
    Log.debug(function () {
      return 'Unknown formFactor ' + _this2.formFactor;
    });
    return null;
  };

  CardStatus.prototype._magstripe = function _magstripe(reader) {
    var card = new _retailPaymentDevice.MagneticCard();
    var track = this.maskedTrack1 || this.maskedTrack2;
    var maskedTrack2 = new Buffer(this.maskedTrack2, 'hex').toString();
    var separatorIndex = maskedTrack2.indexOf('='); // https://en.m.wikipedia.org/wiki/ISO/IEC_7813#Track_2
    var pan = maskedTrack2.substring(1, separatorIndex);
    card.cardIssuer = _retailPaymentDevice.CardDataUtil.getCardIssuerFromCardNumber(pan.substr(0, 6));
    card.lastFourDigits = pan.substr(pan.length - 4);
    if (separatorIndex >= 0) {
      var serviceCode = maskedTrack2.substring(separatorIndex + 5, separatorIndex + 6);
      if (serviceCode === '2' || serviceCode === '6') {
        Log.debug('Chip card was swiped');
        card.chipCard = true;
      }
    }

    card.formFactor = _retailPaymentDevice.FormFactor.MagneticCardSwipe;
    card.ksn = this.ksn ? this.ksn.toString('hex') : '';
    card.reader = reader;
    if (!track || !track.length) {
      Log.error('Missing track 1 and 2 from card swipe data');
      card.failed = true;
      return card;
    }
    card.track2 = this.response.apdu.data.toString('hex');
    return card;
  };

  CardStatus.prototype.toString = function toString() {
    var parts = [];
    if (this.ksn) {
      parts.push('\nKSN: ');
      parts.push(this.ksn.toString('hex'));
    }
    if (this.track2) {
      parts.push('\nTrack 2: ');
      parts.push(this.track2.toString('hex'));
    }
    if (this.maskedTrack1) {
      parts.push('\nMasked Track 1: ');
      parts.push(this.maskedTrack1.toString('hex'));
    }
    if (this.maskedTrack2) {
      parts.push('\nMasked Track 2: ');
      parts.push(this.maskedTrack2.toString('hex'));
    }
    if (this.sredData) {
      parts.push('\nSRED: ');
      parts.push(this.sredData.toString('hex'));
    }

    return parts.join('');
  };

  return CardStatus;
}();

exports.default = CardStatus;

}).call(this,require("buffer").Buffer)
},{"buffer":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/buffer/index.js","manticore-log":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-log/index.js","retail-payment-device":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/js/ingenico-emv/ConnectionFlow.js":[function(require,module,exports){
(function (Buffer){
'use strict';

exports.__esModule = true;

var _manticoreLog = require('manticore-log');

var _manticoreLog2 = _interopRequireDefault(_manticoreLog);

var _manticoreUtil = require('manticore-util');

var _async = require('async');

var _async2 = _interopRequireDefault(_async);

var _retailPaymentDevice = require('retail-payment-device');

var _BaseFlowAsync2 = require('../flows/BaseFlowAsync');

var _BaseFlowAsync3 = _interopRequireDefault(_BaseFlowAsync2);

var _IngenicoDeviceUpdate = require('./SoftwareUpdate/IngenicoDeviceUpdate');

var _IngenicoDeviceUpdate2 = _interopRequireDefault(_IngenicoDeviceUpdate);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (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 } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var Log = (0, _manticoreLog2.default)('ingenico.connectionFlow');

var ConnectionFlow = function (_BaseFlowAsync) {
  _inherits(ConnectionFlow, _BaseFlowAsync);

  function ConnectionFlow(device, callback) {
    _classCallCheck(this, ConnectionFlow);

    var _this = _possibleConstructorReturn(this, _BaseFlowAsync.call(this));

    _this.device = device;
    _this.completionCallback = callback;
    return _this;
  }

  ConnectionFlow.prototype.start = function start() {
    var _this2 = this;

    return regeneratorRuntime.async(function start$(_context) {
      while (1) {
        switch (_context.prev = _context.next) {
          case 0:
            _context.next = 2;
            return regeneratorRuntime.awrap(_BaseFlowAsync.prototype.setFlowSteps.call(this, 'Ingenico Connection', [this._retrieveBatteryInfo, this._tryQuickConnect, this._retrieveVersionInfo, this._retrieveDeviceCapabilities, this._checkFirmwareUpdate]));

          case 2:
            _BaseFlowAsync.prototype.addFlowEndedHandler.call(this, function (data) {
              if (!data.error) {
                _this2.device.performQuickConnect = true;
              }
              _this2.completionCallback(data.error);
            });
            Log.debug(function () {
              return 'Starting the connection flow for ' + _this2.device.id;
            });
            _context.next = 6;
            return regeneratorRuntime.awrap(_BaseFlowAsync.prototype.startFlow.call(this));

          case 6:
          case 'end':
            return _context.stop();
        }
      }
    }, null, this);
  };

  ConnectionFlow.prototype._tryQuickConnect = function _tryQuickConnect(flow) {
    var _this3 = this;

    if (this.device.performQuickConnect) {
      Log.debug(function () {
        return 'Performing quick connect on ' + _this3.device.id;
      });
      flow.completeFlow();
      return;
    }
    flow.next();
  };

  ConnectionFlow.prototype._checkFirmwareUpdate = function _checkFirmwareUpdate(flow) {
    var _this4 = this;

    if (this.device.pendingUpdate && this.device.pendingUpdate.updateInProgress) {
      Log.debug(function () {
        return 'Skipping firmware check as firmware update is in progress on ' + _this4.device.id;
      });
      flow.next();
      return;
    }
    _async2.default.parallel([function (cb) {
      return _this4.device.terminal.getFirmwareChecksum(cb);
    }, function (cb) {
      return _this4.device.terminal.getConfigVersion(cb);
    }], function (err) {
      if (err) {
        Log.warn(function () {
          return 'Error querying for firmware updates... Will retry on the next connect for ' + _this4.device.id;
        });
        flow.next();
      } else {
        _this4._fetchSWInfoFromServer(flow);
      }
    });
  };

  ConnectionFlow.prototype._retrieveBatteryInfo = function _retrieveBatteryInfo(flow) {
    return regeneratorRuntime.async(function _retrieveBatteryInfo$(_context2) {
      while (1) {
        switch (_context2.prev = _context2.next) {
          case 0:
            _context2.prev = 0;
            _context2.next = 3;
            return regeneratorRuntime.awrap(this.device.retrieveBatteryInfoAsync());

          case 3:
            _context2.next = 10;
            break;

          case 5:
            _context2.prev = 5;
            _context2.t0 = _context2['catch'](0);
            _context2.next = 9;
            return regeneratorRuntime.awrap(flow.abortFlow(_context2.t0));

          case 9:
            return _context2.abrupt('return');

          case 10:
            _context2.next = 12;
            return regeneratorRuntime.awrap(flow.next());

          case 12:
          case 'end':
            return _context2.stop();
        }
      }
    }, null, this, [[0, 5]]);
  };

  ConnectionFlow.prototype._retrieveVersionInfo = function _retrieveVersionInfo(flow) {
    var vInfoResponse;
    return regeneratorRuntime.async(function _retrieveVersionInfo$(_context3) {
      while (1) {
        switch (_context3.prev = _context3.next) {
          case 0:
            _context3.prev = 0;
            _context3.next = 3;
            return regeneratorRuntime.awrap(this.device.terminal.getFirmwareVersionInfoAsync());

          case 3:
            vInfoResponse = _context3.sent;

            this.setDeviceModel(vInfoResponse);
            _context3.next = 12;
            break;

          case 7:
            _context3.prev = 7;
            _context3.t0 = _context3['catch'](0);
            _context3.next = 11;
            return regeneratorRuntime.awrap(flow.abortFlow(_context3.t0));

          case 11:
            return _context3.abrupt('return');

          case 12:
            _context3.next = 14;
            return regeneratorRuntime.awrap(flow.next());

          case 14:
          case 'end':
            return _context3.stop();
        }
      }
    }, null, this, [[0, 7]]);
  };

  ConnectionFlow.prototype.setDeviceModel = function setDeviceModel(vInfoResponse) {
    var viBuf = new Buffer(vInfoResponse, 'hex');
    var versionInfoStr = viBuf.toString();
    var versionFirst3 = versionInfoStr.substr(0, 3).toLowerCase();
    Log.debug(function () {
      return 'versionInfo string : ' + versionInfoStr;
    });
    this.device.isMoby = versionFirst3 === 'mob';
    if (this.device.isMoby) {
      this.device.model = _retailPaymentDevice.ReaderModel.Moby3000;
    }
    Log.info(this.device.id + ' device.model identified as: ' + (0, _manticoreUtil.getPropertyName)(_retailPaymentDevice.ReaderModel, this.device.model));
  };

  ConnectionFlow.prototype._retrieveFirmwareChecksum = function _retrieveFirmwareChecksum(flow) {
    var _this5 = this;

    return regeneratorRuntime.async(function _retrieveFirmwareChecksum$(_context4) {
      while (1) {
        switch (_context4.prev = _context4.next) {
          case 0:
            if (!(this.device.pendingUpdate && this.device.pendingUpdate.updateInProgress)) {
              _context4.next = 4;
              break;
            }

            Log.debug(function () {
              return 'Skipping firmware check as firmware update is in progress on ' + _this5.device.id;
            });
            flow.completeFlow();
            return _context4.abrupt('return');

          case 4:
            _context4.prev = 4;
            _context4.next = 7;
            return regeneratorRuntime.awrap(this.device.terminal.getFirmwareChecksumAsync());

          case 7:
            _context4.next = 14;
            break;

          case 9:
            _context4.prev = 9;
            _context4.t0 = _context4['catch'](4);
            _context4.next = 13;
            return regeneratorRuntime.awrap(flow.abort(_context4.t0));

          case 13:
            return _context4.abrupt('return');

          case 14:
            _context4.next = 16;
            return regeneratorRuntime.awrap(flow.next());

          case 16:
          case 'end':
            return _context4.stop();
        }
      }
    }, null, this, [[4, 9]]);
  };

  ConnectionFlow.prototype._retrieveConfigVersion = function _retrieveConfigVersion(flow) {
    return regeneratorRuntime.async(function _retrieveConfigVersion$(_context5) {
      while (1) {
        switch (_context5.prev = _context5.next) {
          case 0:
            _context5.prev = 0;
            _context5.next = 3;
            return regeneratorRuntime.awrap(this.device.terminal.getConfigVersionAsync());

          case 3:
            _context5.next = 10;
            break;

          case 5:
            _context5.prev = 5;
            _context5.t0 = _context5['catch'](0);
            _context5.next = 9;
            return regeneratorRuntime.awrap(flow.abort(_context5.t0));

          case 9:
            return _context5.abrupt('return');

          case 10:
            _context5.next = 12;
            return regeneratorRuntime.awrap(flow.next());

          case 12:
          case 'end':
            return _context5.stop();
        }
      }
    }, null, this, [[0, 5]]);
  };

  ConnectionFlow.prototype._retrieveDeviceCapabilities = function _retrieveDeviceCapabilities(flow) {
    var _this6 = this;

    var response, capabilities, startIndex, serialNumber;
    return regeneratorRuntime.async(function _retrieveDeviceCapabilities$(_context6) {
      while (1) {
        switch (_context6.prev = _context6.next) {
          case 0:
            response = void 0;
            _context6.prev = 1;
            _context6.next = 4;
            return regeneratorRuntime.awrap(this.device.terminal.getDeviceCapabilitiesAsync());

          case 4:
            response = _context6.sent;
            _context6.next = 12;
            break;

          case 7:
            _context6.prev = 7;
            _context6.t0 = _context6['catch'](1);
            _context6.next = 11;
            return regeneratorRuntime.awrap(flow.abortFlow(_context6.t0));

          case 11:
            return _context6.abrupt('return');

          case 12:

            Log.debug(function () {
              return 'Device Capabilities response : ' + response;
            });
            capabilities = new Buffer(response, 'hex');

            capabilities = capabilities.toString();
            Log.debug(function () {
              return 'Device Capabilities response string: ' + capabilities;
            });
            startIndex = capabilities.indexOf('RP');
            serialNumber = capabilities.substring(startIndex + 2, startIndex + 10);

            if (serialNumber) {
              _context6.next = 23;
              break;
            }

            _context6.next = 21;
            return regeneratorRuntime.awrap(flow.abortFlow());

          case 21:
            _context6.next = 28;
            break;

          case 23:
            this.device.serialNumber = serialNumber;
            this.device.setCardReaderToMerchant(serialNumber);
            Log.debug(function () {
              return 'Reader Serial Number : ' + _this6.device.serialNumber;
            });
            _context6.next = 28;
            return regeneratorRuntime.awrap(flow.next());

          case 28:
          case 'end':
            return _context6.stop();
        }
      }
    }, null, this, [[1, 7]]);
  };

  ConnectionFlow.prototype._generateUpdateRequest = function _generateUpdateRequest(d) {
    var configVersion = d.terminal.firmwareCustomVersion & 0xffff;
    var capkeysVersion = d.terminal.firmwareCustomVersion >> 16 & 0xffff;
    var components = [{
      name: 'ingenico_firmware',
      version: '' + d.terminal.firmwareChecksum
    }, {
      name: 'ingenico_config',
      version: '' + configVersion
    }, {
      name: 'ingenico_capkeys',
      version: '' + capkeysVersion
    }];
    return { components: components };
  };

  ConnectionFlow.prototype._fetchSWInfoFromServer = function _fetchSWInfoFromServer(flow) {
    var _this7 = this;

    var body = this._generateUpdateRequest(this.device);
    this.device.app.getFirmwareUpdates(body, this.device.manufacturer, this.device.model, function (err, rz) {
      if (err || !rz || !rz.body) {
        Log.error('Unable to retrieve firmware update information. Error: ' + err);
        if (rz && rz.body) {
          Log.warn(JSON.stringify(rz.body, null, '\t'));
        }
        flow.next();
        return;
      }
      _this7.serverSwInfo = rz;
      Log.debug(function () {
        return 'Received firmware update response for this.device: ' + _this7.device;
      });
      if (!rz || !rz.body) {
        Log.warn('Unable to retrieve firmware update information due to rz');
        if (rz.body) {
          Log.warn(JSON.stringify(rz.body, null, '\t'));
        }
        flow.next();
        return;
      }

      if (rz.statusCode === 304) {
        Log.debug(function () {
          return _this7.device.id + ' Software update not needed';
        });
        flow.next();
        return;
      }
      _this7._checkUpdate(rz.body.modules, flow);
    });
  };

  ConnectionFlow.prototype._checkUpdate = function _checkUpdate(modules, flow) {
    Log.debug('Checking update');
    if (_IngenicoDeviceUpdate2.default.needsUpdate(this.device, modules)) {
      this.device.updates = modules;
      this.updateRequired = true;
      this._notifyReaderUpdateRequired();
    }
    flow.next();
  };

  ConnectionFlow.prototype._notifyReaderUpdateRequired = function _notifyReaderUpdateRequired() {
    var _this8 = this;

    Log.debug(function () {
      return 'notifying reader status for ' + _this8.device.id;
    });
    if (this.device.updates) {
      Log.info(this.device.id + ' needs update.\nUpdates(Modules: ' + (this.device.updates ? this.device.updates.length : 0) + ')\n' + JSON.stringify(this.device.updates));
      this.device.updateRequired(new _IngenicoDeviceUpdate2.default(this.device));
    }
  };

  return ConnectionFlow;
}(_BaseFlowAsync3.default);

exports.default = ConnectionFlow;

}).call(this,require("buffer").Buffer)
},{"../flows/BaseFlowAsync":"/Users/aravidas/Documents/Git/retail-sdk/js/flows/BaseFlowAsync.js","./SoftwareUpdate/IngenicoDeviceUpdate":"/Users/aravidas/Documents/Git/retail-sdk/js/ingenico-emv/SoftwareUpdate/IngenicoDeviceUpdate.js","async":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/async/lib/async.js","buffer":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/buffer/index.js","manticore-log":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-log/index.js","manticore-util":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-util/build/index.js","retail-payment-device":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/js/ingenico-emv/IngenicoCommand.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

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; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

var _uniqueId = 0;

var IngenicoCommand = function () {
  function IngenicoCommand(name, apduCommand) {
    _classCallCheck(this, IngenicoCommand);

    this.id = _uniqueId += 1;
    this.name = name;
    this.apduCommand = apduCommand;
    this.callbacks = [];
    this.nativeCommand = null;
    this.sendAttempt = 0;
  }

  IngenicoCommand.prototype.toJSON = function toJSON() {
    return {
      id: this.id,
      name: this.name,
      apduCommand: this.apduCommand ? this.apduCommand.toString('hex') : this._rawHex,
      isRawHex: !!this._rawHex,
      reuseIfQueued: this._reuseIfQueued,
      callbacks: this.callbacks.length,
      nativeCommandName: this.nativeCommand && this.nativeCommand.name
    };
  };

  IngenicoCommand.prototype.toString = function toString() {
    return JSON.stringify(this.toJSON());
  };

  _createClass(IngenicoCommand, [{
    key: 'rawHexCommand',
    set: function set(value) {
      this._rawHex = value;
    },
    get: function get() {
      return this._rawHex;
    }
  }, {
    key: 'nameWithId',
    get: function get() {
      return this.name + '-' + this.id;
    }

    /**
     * If an existing command is in the command pipeline to be sent/awaiting response, the command writer will append the
     * provided callback to the response of the existing command. This command will not be resent
     * @param value
     */

  }, {
    key: 'reuseIfQueued',
    set: function set(value) {
      this._reuseIfQueued = value;
    },
    get: function get() {
      return this._reuseIfQueued;
    }
  }]);

  return IngenicoCommand;
}();

exports.default = IngenicoCommand;

},{}],"/Users/aravidas/Documents/Git/retail-sdk/js/ingenico-emv/IngenicoDevice.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

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; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

var _manticoreLog = require('manticore-log');

var _manticoreLog2 = _interopRequireDefault(_manticoreLog);

var _retailPaymentDevice = require('retail-payment-device');

var _manticoreUtil = require('manticore-util');

var Util = _interopRequireWildcard(_manticoreUtil);

var _ConnectionFlow = require('./ConnectionFlow');

var _ConnectionFlow2 = _interopRequireDefault(_ConnectionFlow);

var _Terminal = require('./Terminal');

var _Terminal2 = _interopRequireDefault(_Terminal);

var _eventType = require('./eventType');

var _eventType2 = _interopRequireDefault(_eventType);

var _ingenicoReaderError = require('./ingenicoReaderError');

var _ingenicoReaderError2 = _interopRequireDefault(_ingenicoReaderError);

var _CardStatus = require('./CardStatus');

var _CardStatus2 = _interopRequireDefault(_CardStatus);

var _sdkErrors = require('../common/sdkErrors');

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (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 } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var Log = (0, _manticoreLog2.default)('ingenico');

var IngenicoDevice = function (_PaymentDevice) {
  _inherits(IngenicoDevice, _PaymentDevice);

  function IngenicoDevice(uniqueId, nativeInterface, appInterface, isUsb, hardwareAddress) {
    _classCallCheck(this, IngenicoDevice);

    var _this = _possibleConstructorReturn(this, _PaymentDevice.call(this, uniqueId, nativeInterface, appInterface, isUsb, hardwareAddress));

    _this.manufacturer = _retailPaymentDevice.deviceManufacturer.ingenico;
    _this.terminal = new _Terminal2.default(_this.native, _this);
    _this.model = appInterface.model;
    _this.type = _retailPaymentDevice.readerType.Emv;
    _this.connectionType = _retailPaymentDevice.readerConnectionType.Bluetooth;
    _this.performQuickConnect = false;
    return _this;
  }

  IngenicoDevice.prototype.beginDeviceRemoved = function beginDeviceRemoved(callback) {
    this.native.removed(callback);
  };

  IngenicoDevice.prototype.beginDeviceConnect = function beginDeviceConnect(callback) {
    var _this2 = this;

    if (this.native.isConnected()) {
      Log.debug(function () {
        return 'Connect called, but ' + _this2.id + ' is already connected.';
      });
      callback();
      return;
    }
    Log.debug(function () {
      return 'Connecting to Ingenico device ' + _this2.id;
    });
    this.native.connect(function (error) {
      if (error) {
        Log.error('Connect response Error ' + error);
        callback(error);
        return;
      }
      Log.debug(function () {
        return 'Established BT connection with ' + _this2.id + '. Will begin the connection flow...';
      });
      new _ConnectionFlow2.default(_this2, callback).start().then(function () {
        Log.debug('Connection flow done');
      }).catch(function (err) {
        Log.error('Connection flow failed ' + err);
        if (callback) {
          callback();
        }
      });
    });
  };

  IngenicoDevice.prototype.listenForCardRemoval = function listenForCardRemoval(callback) {
    var _this3 = this;

    this.deactivateFormFactors([_retailPaymentDevice.FormFactor.MagneticCardSwipe, _retailPaymentDevice.FormFactor.Chip, _retailPaymentDevice.FormFactor.EmvCertifiedContactless], function () {
      _this3._waitForCardRemoval(false, callback);
    });
  };

  IngenicoDevice.prototype.beginDeviceDisconnect = function beginDeviceDisconnect(callback) {
    var _this4 = this;

    if (this.connectionInProgress && this.native.cancelConnect) {
      Log.debug(function () {
        return _this4.id + ' Connection is in progress... Will stop it';
      });
      this.native.cancelConnect();
    }
    if (!this.isConnected()) {
      Log.debug(function () {
        return 'Disconnect called, but ' + _this4.id + ' is already dis-connected.';
      });
      callback(null);
      return;
    }
    this.terminal.disconnect();
    this.native.disconnect(callback);
  };

  IngenicoDevice.prototype.getFirmwareVersionInfo = function getFirmwareVersionInfo(callback) {
    this.terminal.getFirmwareVersionInfo(callback);
  };

  IngenicoDevice.prototype.getVersionInfo = function getVersionInfo() {
    var os = this.terminal.firmwareChecksum || '';
    var mpi = this.terminal.firmwareCustomVersion || '';
    return { os: os, mpi: mpi };
  };

  IngenicoDevice.prototype.activateForPayment = function activateForPayment(context, ffToActivate, showPrompt) {
    var _this5 = this;

    // eslint-disable-line no-unused-vars
    this.context = context;
    Log.info(this.id + ' activateForPayment context=' + context + ', formFactors=' + Util.getPropertyName(_retailPaymentDevice.FormFactor, ffToActivate) + ', showPrompt=' + showPrompt);
    var ff = new Set(ffToActivate);
    if (ff.has(_retailPaymentDevice.FormFactor.EmvCertifiedContactless) && ff.size === 1) {
      // TxContext does incremental activation for Miura but Ingenico does abort first for any formfactor diffs and activate for the incremental formfactor.
      // Because of that, we do activate all if only contactless formfactor requested from tx context.
      ffToActivate = [_retailPaymentDevice.FormFactor.MagneticCardSwipe, _retailPaymentDevice.FormFactor.Chip, _retailPaymentDevice.FormFactor.EmvCertifiedContactless]; // eslint-disable-line no-param-reassign
      Log.info(this.id + ' only EmvCertifiedContactless requested so having ALL formFactors, formFactors=' + Util.getPropertyName(_retailPaymentDevice.FormFactor, ffToActivate));
    }
    var invoice = context.invoice;
    var startActivation = function startActivation() {
      // reset cardInSlot before activation
      _this5.cardInSlot = false;
      _PaymentDevice.prototype.activateForPayment.call(_this5, context, ffToActivate, showPrompt);
      var transactionType = context.type === _retailPaymentDevice.TransactionType.Sale ? 0 : 20;

      var handleResponse = function handleResponse(err, response) {
        if (err && (context.type === _retailPaymentDevice.TransactionType.Sale || context.type === _retailPaymentDevice.TransactionType.Refund && err.code !== _retailPaymentDevice.deviceError.nfcNotAllowed.code)) {
          // Essentially, in case of refunds, treat the decline as a success and move on.
          Log.info(_this5.id + '  IngenicoDevice handling err: ' + err.code);

          if (err.code === _ingenicoReaderError2.default.batteryTooLowError) {
            Log.debug(function () {
              return _this5.id + '  IngenicoDevice low battery err: ' + err.code;
            });
            _this5.emit(_retailPaymentDevice.PaymentDevice.Event.cardPresented, _retailPaymentDevice.deviceError.lowOnBattery, null, _retailPaymentDevice.FormFactor.Chip);
            return;
          }

          if (!context.isPaymentInRetryOrProgress() && (err.code === _ingenicoReaderError2.default.cardReaderNotConnected || err.code === _ingenicoReaderError2.default.cardReaderConnectionLost || err === _retailPaymentDevice.deviceError.deviceNotConnected)) {
            Log.debug(function () {
              return _this5.id + '  IngenicoDevice NO emit any cardPresented for err: ' + err.code;
            });
            _this5.abortTransaction(context, function () {
              Log.debug(function () {
                return _this5.id + ' IngenicoDevice ' + err.code + ' aborted...';
              });
            });
            return;
          }

          if (err.code === _ingenicoReaderError2.default.transactionCancelled) {
            _this5.emit(_retailPaymentDevice.PaymentDevice.Event.cancelled);
            return;
          }
          if (err.code === _ingenicoReaderError2.default.noMutuallySupportedAIDs) {
            Log.info(_this5.id + ' IngenicoDevice noMutuallySupportedAIDs abort and emit cardPresented, tryDifferentInterface');
            _this5.abortTransaction(context, function () {
              Log.info(_this5.id + ' IngenicoDevice noMutuallySupportedAIDs aborted... emit cardPresented, tryDifferentInterface');
              _this5.emit(_retailPaymentDevice.PaymentDevice.Event.cardPresented, _sdkErrors.transaction.tryDifferentInterface, null, _retailPaymentDevice.FormFactor.EmvCertifiedContactless);
            });
            return;
          }
          if (err.code === _ingenicoReaderError2.default.applicationBlocked) {
            Log.info(_this5.id + ' IngenicoDevice applicationBlocked abort and emit cardPresented, cardBlocked');
            if (_this5.cardInSlot) {
              _this5._waitForCardRemoval(false, function () {
                Log.info(_this5.id + ' waitForCardRemoval complete');
              });
            }
            // ApplicationBlocked error is for chip only
            _this5.emit(_retailPaymentDevice.PaymentDevice.Event.cardPresented, _retailPaymentDevice.deviceError.cardBlocked, null, _retailPaymentDevice.FormFactor.Chip);
            return;
          }
          if (err.code === _retailPaymentDevice.deviceError.nfcNotAllowed.code) {
            Log.info(_this5.id + ' IngenicoDevice offline decline');
            _this5.emit(_retailPaymentDevice.PaymentDevice.Event.cardPresented, _retailPaymentDevice.deviceError.nfcNotAllowed, null, _retailPaymentDevice.FormFactor.EmvCertifiedContactless);
            return;
          }
          _this5.emit(_retailPaymentDevice.PaymentDevice.Event.cardPresented, err, _retailPaymentDevice.CardPresentEvent.cardDataRead, _retailPaymentDevice.FormFactor.Chip);
          return;
        }

        if (response instanceof _retailPaymentDevice.AvailableApplications) {
          _this5.emit(_retailPaymentDevice.PaymentDevice.Event.cardPresented, null, _retailPaymentDevice.CardPresentEvent.appSelectionRequired, _retailPaymentDevice.FormFactor.Chip, { card: null, availableApps: response });
          return;
        }

        var card = new _CardStatus2.default(response).getPresentedCard(_this5);
        Log.debug(function () {
          return 'Received ICC response from \'' + Util.getPropertyName(_retailPaymentDevice.FormFactor, card.formFactor) + '\'\n' + response + '\nCard: ' + card;
        });
        _this5.emit(_retailPaymentDevice.PaymentDevice.Event.cardPresented, null, _retailPaymentDevice.CardPresentEvent.cardDataRead, card.formFactor, { card: card });
      };
      _this5.terminal.startTransaction(transactionType, invoice, ffToActivate, handleResponse);
    };

    // Ingenico device does not allow activation without aborting the previous activation.
    if (this.isActivated) {
      Log.info(this.id + ' Abort and re-activate with formFactors: ' + ffToActivate);
      this.abortTransaction(context, startActivation);
    } else {
      startActivation();
    }
  };

  IngenicoDevice.prototype.completeTransaction = function completeTransaction(authCode, callback) {
    if (!this.isConnected()) {
      if (callback) {
        callback(_retailPaymentDevice.deviceError.deviceNotConnected);
      }
      return;
    }
    this.terminal.completeTransaction(authCode, function (err, rz) {
      Log.debug('Auth code sent. Response : ' + rz);
      if (callback) {
        callback(err, rz);
      }
    });
  };

  IngenicoDevice.prototype.deactivateFormFactors = function deactivateFormFactors(formFactors) {
    var _this6 = this;

    var callback = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : function () {};

    if (!formFactors || formFactors.length === 0 || !this.isActivated) {
      Log.debug(function () {
        return 'No form factors to deactivate. WasActivated? ' + _this6.isActivated;
      });
      callback();
      return;
    }

    var sPrevFF = this.getSetOfActiveFormFactors();
    _PaymentDevice.prototype.deactivateFormFactors.call(this, [_retailPaymentDevice.FormFactor.Chip, _retailPaymentDevice.FormFactor.MagneticCardSwipe, _retailPaymentDevice.FormFactor.EmvCertifiedContactless]);
    Log.debug(function () {
      return 'Deactivating form factors \'' + Util.getPropertyName(_retailPaymentDevice.FormFactor, formFactors) + '\' on \'' + _this6.id + '\'. ' + ('Previously active: \'' + Util.getPropertyName(_retailPaymentDevice.FormFactor, [].concat(_toConsumableArray(sPrevFF))) + '\', Currently active: \'' + Util.getPropertyName(_retailPaymentDevice.FormFactor, [].concat(_toConsumableArray(_this6.getSetOfActiveFormFactors()))) + '\'');
    });
    this.terminal.stopTransaction(function () {
      for (var _iterator = formFactors, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
        var _ref;

        if (_isArray) {
          if (_i >= _iterator.length) break;
          _ref = _iterator[_i++];
        } else {
          _i = _iterator.next();
          if (_i.done) break;
          _ref = _i.value;
        }

        var ff = _ref;

        sPrevFF.delete(ff);
      }
      Log.debug(function () {
        return 'Deactivated all formFactors on ' + _this6.id + '. Will reactivate \'' + Util.getPropertyName(_retailPaymentDevice.FormFactor, [].concat(_toConsumableArray(sPrevFF))) + '\'';
      });
      if (sPrevFF.size > 0) {
        _this6.activateForPayment(_this6.context, [].concat(_toConsumableArray(sPrevFF)));
      }
      callback();
    });
  };

  IngenicoDevice.prototype.abortTransaction = function abortTransaction(context, callback) {
    var _this7 = this;

    Log.debug(function () {
      return 'Aborting tx on \'' + _this7.id + '\'';
    });
    this.terminal.stopTransaction(function () {
      _PaymentDevice.prototype.abortTransaction.call(_this7, context, callback);
    });
  };

  IngenicoDevice.prototype.postTransactionCleanup = function postTransactionCleanup(callback) {
    var _this8 = this;

    Log.debug(function () {
      return 'postTransactionCleanup on \'' + _this8.id + '\'';
    });
    this.cardInSlot = false;
    this.terminal.postTransactionCleanup(callback);
  };

  IngenicoDevice.prototype.display = function display(opt, callback) {
    if (callback) {
      callback();
    }
  };

  IngenicoDevice.prototype.received = function received(args) {
    var _this9 = this;

    try {
      this.lastError = null;
      if (!args) {
        Log.warn('Received empty unsolicited message');
        return;
      }

      if (!args.event) {
        Log.warn('Received unsolicited message without event type');
        return;
      }

      var err = args.error;
      var eventName = Util.getPropertyName(_eventType2.default, args.event);

      if (!err) {
        Log.debug(function () {
          return 'UNSOLICITED Message received for event:\'' + eventName + '\', raw data: ' + args.data;
        });
      } else {
        this.lastError = err;
        Log.error('UNSOLICITED event:\'' + eventName + '\' Error with message:\'' + err.message + '\', code: \'' + err.code + '\'');
      }

      if (args.event === _eventType2.default.cardInserted) {
        Log.debug(function () {
          return 'Card insert detected on ' + _this9.id;
        });
        this.cardInSlot = true;
        this.canAbortTx = true;
        if (!err) {
          this.emit(_retailPaymentDevice.PaymentDevice.Event.cardPresented, null, _retailPaymentDevice.CardPresentEvent.insertDetected, _retailPaymentDevice.FormFactor.Chip);
          return;
        }
        if (err.code === _ingenicoReaderError2.default.invalidChip) {
          this.canAbortTx = false;
          this.emit(_retailPaymentDevice.PaymentDevice.Event.cardPresented, _retailPaymentDevice.deviceError.invalidChip, null, _retailPaymentDevice.FormFactor.Chip);
          return;
        }
        if (err.code === _ingenicoReaderError2.default.invalidChipSwipeCard) {
          this.canAbortTx = false;
          this.emit(_retailPaymentDevice.PaymentDevice.Event.cardPresented, _retailPaymentDevice.deviceError.mustSwipeCard, null, _retailPaymentDevice.FormFactor.Chip);
          return;
        }
      }

      if (args.event === _eventType2.default.cardRemoved) {
        Log.debug(function () {
          return 'Card remove detected on ' + _this9.id;
        });
        this.cardInSlot = false;
        if (this.isActivated && this.canAbortTx) {
          Log.debug(function () {
            return 'cardRemoved detected but startTxInProgress TRUE on ' + _this9.id + ' so aborting it!';
          });
          this.abortTransaction(this.context, function () {
            Log.debug(function () {
              return _this9.id + ' IngenicoDevice aborted transaction due to cardRemoved event...';
            });
          });
        }
        this.emit(_retailPaymentDevice.PaymentDevice.Event.cardRemoved);
        return;
      }
      if (args.event === _eventType2.default.cardSwiped) {
        if (err.code === _ingenicoReaderError2.default.pleaseInsertCard) {
          this.emit(_retailPaymentDevice.PaymentDevice.Event.cardPresented, _sdkErrors.transaction.cannotSwipeChipCard, _retailPaymentDevice.CardPresentEvent.insertDetected, _retailPaymentDevice.FormFactor.MagneticCardSwipe);
          return;
        }
      }

      if (args.event === _eventType2.default.cardTapped) {
        if (err.code === _ingenicoReaderError2.default.multipleContactlessCardsDetected) {
          this.emit(_retailPaymentDevice.PaymentDevice.Event.cardPresented, _sdkErrors.transaction.multipleContactlessCardsDetected, _retailPaymentDevice.CardPresentEvent.insertDetected, _retailPaymentDevice.FormFactor.EmvCertifiedContactless);
        }
        if (err.code === _ingenicoReaderError2.default.contactlessInterfaceFailedTryContact) {
          this.emit(_retailPaymentDevice.PaymentDevice.Event.cardPresented, _retailPaymentDevice.deviceError.nfcNotAllowed, null, _retailPaymentDevice.FormFactor.EmvCertifiedContactless);
        }
        if (err.code === _ingenicoReaderError2.default.pleaseSeePhone) {
          this.app.display({ message: 'Please ask customer to SEE PHONE', cancel: 'done' }, function (a) {
            a.dismiss();
          });
          return;
        }
      }
    } catch (x) {
      Log.error('Error handling unsolicited message ' + args + ' \n' + x);
      throw x;
    }
  };

  IngenicoDevice.prototype.getBatteryInfo = function getBatteryInfo(callback) {
    this.terminal.getBatteryLevel(true, callback);
  };

  IngenicoDevice.prototype.getBatteryInfoAsync = function getBatteryInfoAsync() {
    return regeneratorRuntime.async(function getBatteryInfoAsync$(_context) {
      while (1) {
        switch (_context.prev = _context.next) {
          case 0:
            _context.next = 2;
            return regeneratorRuntime.awrap(Util.callbackToPromise(this.getBatteryInfo.bind(this)));

          case 2:
            return _context.abrupt('return', _context.sent);

          case 3:
          case 'end':
            return _context.stop();
        }
      }
    }, null, this);
  };

  IngenicoDevice.prototype.retrieveBatteryInfoAsync = function retrieveBatteryInfoAsync() {
    return regeneratorRuntime.async(function retrieveBatteryInfoAsync$(_context2) {
      while (1) {
        switch (_context2.prev = _context2.next) {
          case 0:
            _context2.next = 2;
            return regeneratorRuntime.awrap(Util.callbackToPromise(this.retrieveBatteryInfo.bind(this)));

          case 2:
            return _context2.abrupt('return', _context2.sent);

          case 3:
          case 'end':
            return _context2.stop();
        }
      }
    }, null, this);
  };

  IngenicoDevice.prototype._waitForCardRemoval = function _waitForCardRemoval(useTimeout, callback) {
    this.terminal.waitForCardRemoval(useTimeout, callback);
  };

  IngenicoDevice.prototype.selectPaymentApplication = function selectPaymentApplication(appId) {
    var _this10 = this;

    this.terminal.selectApplication(appId, function (err, rz) {
      if (err) {
        _this10.emit(_retailPaymentDevice.PaymentDevice.Event.cardPresented, err, _retailPaymentDevice.CardPresentEvent.cardDataRead, _retailPaymentDevice.FormFactor.Chip);
        return;
      }
      Log.debug(function () {
        return 'Received ICC card data from Application select: ' + rz;
      });
      var card = new _CardStatus2.default(rz).getPresentedCard(_this10);
      _this10.emit(_retailPaymentDevice.PaymentDevice.Event.cardPresented, null, _retailPaymentDevice.CardPresentEvent.cardDataRead, card.formFactor, { card: card });
    });
  };

  IngenicoDevice.prototype.doesHaveCapability = function doesHaveCapability(capability) {
    switch (capability) {
      case _retailPaymentDevice.deviceCapabilityType.contactless:
        return this.model === _retailPaymentDevice.ReaderModel.RP450;
      default:
        return false;
    }
  };

  _createClass(IngenicoDevice, [{
    key: 'formFactors',
    get: function get() {
      var ff = this.isMoby ? [_retailPaymentDevice.FormFactor.Chip, _retailPaymentDevice.FormFactor.MagneticCardSwipe] : [_retailPaymentDevice.FormFactor.Chip, _retailPaymentDevice.FormFactor.EmvCertifiedContactless, _retailPaymentDevice.FormFactor.MagneticCardSwipe];
      return ff;
    }
  }]);

  return IngenicoDevice;
}(_retailPaymentDevice.PaymentDevice);

exports.default = IngenicoDevice;

},{"../common/sdkErrors":"/Users/aravidas/Documents/Git/retail-sdk/js/common/sdkErrors.js","./CardStatus":"/Users/aravidas/Documents/Git/retail-sdk/js/ingenico-emv/CardStatus.js","./ConnectionFlow":"/Users/aravidas/Documents/Git/retail-sdk/js/ingenico-emv/ConnectionFlow.js","./Terminal":"/Users/aravidas/Documents/Git/retail-sdk/js/ingenico-emv/Terminal.js","./eventType":"/Users/aravidas/Documents/Git/retail-sdk/js/ingenico-emv/eventType.js","./ingenicoReaderError":"/Users/aravidas/Documents/Git/retail-sdk/js/ingenico-emv/ingenicoReaderError.js","manticore-log":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-log/index.js","manticore-util":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-util/build/index.js","retail-payment-device":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/js/ingenico-emv/IngenicoTags.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

var _tlvlib = require('tlvlib');

/* eslint max-len: "off" */
var IngenicoTags = {
  // Amount DOL
  ApplicationEffectiveDate: new _tlvlib.DefinedTag('ApplicationEffectiveDate', 0x5F25, _tlvlib.ValueFormat.Binary, 3),
  ApplicationLabel: new _tlvlib.DefinedTag('ApplicationLabel', 0x50, _tlvlib.ValueFormat.Binary, 16),
  CardHolderName: new _tlvlib.DefinedTag('CardHolderName', 0x5F20, _tlvlib.ValueFormat.Binary, 26),
  ApplicationPreferredName: new _tlvlib.DefinedTag('ApplicationPreferredName', 0x9F12, _tlvlib.ValueFormat.Binary, 16),
  ApplicationExpirationDate: new _tlvlib.DefinedTag('ApplicationExpirationDate', 0x5F24, _tlvlib.ValueFormat.Binary, 3),
  CertificationVerificationValue: new _tlvlib.DefinedTag('CertificationVerificationValue', 0xDF50, _tlvlib.ValueFormat.Binary, 12),
  PAN: new _tlvlib.DefinedTag('PAN', 0x5A, _tlvlib.ValueFormat.Binary, 10),
  PANSequenceNumber: new _tlvlib.DefinedTag('PANSequenceNumber', 0x5F34, _tlvlib.ValueFormat.Binary, 1),
  TerminalApplicationIdentifier: new _tlvlib.DefinedTag('TerminalApplicationIdentifier', 0x9F06, _tlvlib.ValueFormat.Binary),
  // Online DOL
  TerminalVerificationResults: new _tlvlib.DefinedTag('TerminalVerificationResults', 0x95, _tlvlib.ValueFormat.Binary, 5),
  ApplicationCryptogram: new _tlvlib.DefinedTag('ApplicationCryptogram', 0x9F26, _tlvlib.ValueFormat.Binary, 8),
  ApplicationTransactionCounter: new _tlvlib.DefinedTag('ApplicationTransactionCounter', 0x9F36, _tlvlib.ValueFormat.Binary, 2),
  CardholderVerificationMethodResult: new _tlvlib.DefinedTag('CardholderVerificationMethodResult', 0x9F34, _tlvlib.ValueFormat.Binary, 3),
  CryptogramInformationData: new _tlvlib.DefinedTag('CryptogramInformationData', 0x9F27, _tlvlib.ValueFormat.Binary, 1),
  IssuerApplicationData: new _tlvlib.DefinedTag('IssuerApplicationData', 0x9F10, _tlvlib.ValueFormat.Binary, 32),
  TransactionStatusInformation: new _tlvlib.DefinedTag('TransactionStatusInformation', 0x9B, _tlvlib.ValueFormat.Binary, 2),
  UnpredictableNumber: new _tlvlib.DefinedTag('UnpredictableNumber', 0x9F37, _tlvlib.ValueFormat.Binary, 4),
  // Command Tags
  AmountAuthorizedBinary: new _tlvlib.DefinedTag('AmountAuthorizedBinary', 0x81, _tlvlib.ValueFormat.CompressedNumeric, 4),
  AmountOtherBinary: new _tlvlib.DefinedTag('AmountOtherBinary', 0x9F04, _tlvlib.ValueFormat.CompressedNumeric, 4),
  TransactionCurrencyExponent: new _tlvlib.DefinedTag('TransactionCurrencyExponent', 0x5F36, _tlvlib.ValueFormat.Numeric, 1),
  OverallContactlessTransactionLimit: new _tlvlib.DefinedTag('OverallContactlessTransactionLimit', 0xDF65, _tlvlib.ValueFormat.CompressedAlpha, 4),
  AuthorizationResponseCodeList: new _tlvlib.DefinedTag('AuthorizationResponseCodeList', 0xDF16, _tlvlib.ValueFormat.CompressedAlpha),
  POSEntryMode: new _tlvlib.DefinedTag('POSEntryMode', 0x9F39, _tlvlib.ValueFormat.CompressedNumeric, 1),
  DOLAnswerFormat: new _tlvlib.DefinedTag('DOLAnswerFormat', 0xDF8229, _tlvlib.ValueFormat.CompressedAlpha),
  TerminalCountryCode: new _tlvlib.DefinedTag('TerminalCountryCode', 0x9F1A, _tlvlib.ValueFormat.CompressedNumeric, 2),
  TerminalCapabilities: new _tlvlib.DefinedTag('TerminalCapabilities', 0x9F33, _tlvlib.ValueFormat.CompressedAlpha, 3),
  AdditionalTerminalCapabilities: new _tlvlib.DefinedTag('AdditionalTerminalCapabilities', 0x9F40, _tlvlib.ValueFormat.CompressedAlpha, 5),
  TerminalIdentification: new _tlvlib.DefinedTag('TerminalIdentification', 0x9F1C, _tlvlib.ValueFormat.CompressedNumeric, 8),
  ExtraProgressMessageFlag: new _tlvlib.DefinedTag('ExtraProgressMessageFlag', 0xDF68, _tlvlib.ValueFormat.CompressedNumeric, 1),
  TerminalApplicationVersionNumber: new _tlvlib.DefinedTag('TerminalApplicationVersionNumber', 0x9F09, _tlvlib.ValueFormat.CompressedNumeric, 2),
  GenerateACControl: new _tlvlib.DefinedTag('GenerateACControl', 0xDF72, _tlvlib.ValueFormat.CompressedNumeric, 1),
  TerminalType: new _tlvlib.DefinedTag('TerminalType', 0x9F35, _tlvlib.ValueFormat.CompressedNumeric, 1),
  TransactionCategoryCode: new _tlvlib.DefinedTag('TransactionCategoryCode', 0x9F53, _tlvlib.ValueFormat.CompressedNumeric, 1),
  ContactlessInformationOut: new _tlvlib.DefinedTag('ContactlessInformationOut', 0xDF6F, _tlvlib.ValueFormat.Binary, 2),
  BatteryLevelThreshold: new _tlvlib.DefinedTag('BatteryLevelThreshold', 0xDF8239, _tlvlib.ValueFormat.CompressedNumeric, 1),

  // Others
  AcquirerExclusionList: new _tlvlib.DefinedTag('AcquirerExclusionList', 0xFF7F, _tlvlib.ValueFormat.Binary),
  RFParam: new _tlvlib.DefinedTag('RFParam', 0xDF8240, _tlvlib.ValueFormat.CompressedNumeric, 2),
  AcquirerIdentifier: 0x9F01,
  AlternateMessageForRemoveCardPrompt: 0xDF73,
  AmexExpresspayPseudoTrack1Data: 0xDF45,
  AmexExpresspayPseudoTrack2Data: 0xDF46,
  DiscoverDPASPseudoTrack1Data: 0xDF56,
  DiscoverDPASPseudoTrack2Data: 0xDF57,
  AmexExpresspayUnpredictableNumberRange: 0xDF44,
  DefaultValueForDDOL: 0xDF15,
  AmountAuthorizedNumeric: 0x9F02,
  AmountOfLasttransactionWithSameCard: 0xDF25,
  AmountOtherNumeric: 0x9F03,
  AmountReferenceCurrency: 0x9F3A,
  ApplicationCurrencyExponent: 0x9F44,
  ApplicationCurrencyCode: 0x9F42,
  ApplicationDiscretionaryData: 0x9F05,
  ServiceCode: 0x5F30,
  ApplicationFileLocator: 0x94,
  ApplicationIdentifier: 0x4F,
  ApplicationInterchangeProfile: 0x82,
  ApplicationPriorityIndicator: 0x87,
  ApplicationTemplate: 0x61,
  ApplicationUsageControl: 0x9F07,
  ApplicationVersionNumber: 0x9F08,
  AuthorizationCode: 0x89,
  AuthorizationResponseCode: 0x8A,
  BankIndentifierCode: 0x5F54,
  CanadianFlag: 0xDF8222,
  CardAdditionalProcesses: 0x9F68,
  CardholderLanguage: 0xDF12,
  CardholderVerificationMethodList: 0x8E,
  CardIsInTheHotlist: 0xDF26,
  CardRiskManagementDataObjectList1: 0x8C,
  CardRiskManagementDataObjectList2: 0x8D,
  CertificationAuthorityPublicKeyIndex: 0x8F,
  ContactlessKernelIdentifier: 0xDF6C,
  ContactlessSignatureCheckResult: 0xDF6E,
  CustomerExclusiveData: 0x9F7C,
  CVMOUTresult: 0xDF38,
  DedicatedFileName: 84,
  DefaultValueForTDOL: 0xDF18,
  DirectoryDefinitionFile: 0x9D,
  DirectoryDiscretionaryTemplate: 0x73,
  DynamicDataAuthenticationDataObjectList: 0x9F49,
  FileControlInformationIssuerDiscretionaryData: 0xBF0C,
  FileControlInformationTemplate: 0xA5,
  FDDAVersion: 0x9F69,
  FormFactorIndicator: 0x9F6E,

  HandOverCardFlag: 0xDF71,
  ICCDynamicNumber: 0x9F4C,
  ICCPINEnciphermentPublicKeyCertificate: 0x9F2D,
  ICCPINEnciphermentPublicKeyExponent: 0x9F2E,
  ICCPINEnciphermentPublicKeyRemainder: 0x9F2F,
  ICCPublicKeyCertificate: 0x9F46,
  ICCPublicKeyExponent: 0x9F47,
  ICCPublicKeyRemainder: 0x9F48,
  InterfaceDeviceSerialNumber: 0x9F1E,
  InternationalBankAccountNumber: 0x5F53,
  IssuerAuthenticationData: 0x91,
  IssuerCountryCode: 0x5F28,
  IssuerCountryCodeAlpha2: 0x5F55,
  IssuerCountryCodeAlpha3: 0x5F56,
  IssuerIdentificationNumber: 42,
  IssuerPublicKeyExponent: 0x9F32,
  IssuerPublicKeyRemainder: 0x92,
  IssuerScript1: 0x71,
  IssuerScript2: 0x72,
  IssuerScriptCommand: 0x86,
  IssuerScriptResults: 0xDF11,
  IssuerScriptResultsForProcessor: 0x9F5B,
  KSN: 0xDF8225,
  ListOfTransactionTypesUsedByTheApplication: 0xDF3A,
  LanguagePreference: 0x5F2D,
  LogFormat: 0x9F4F,
  MACData: 0xDF8205,
  MACDOL: 0xDF8204,
  MACInitialisationVector: 0xDF8206,
  MasterSessionKeyLocator: 0xDF8220,
  Maximumtargetpercentage: 0xDF09,
  MerchantCategoryCode: 0x9F15,
  MerchantIdentifier: 0x9F16,
  OnlinePINBlock: 0xDF4F,
  OnlinePINBlockFormat: 0xDF8202,
  OnlinePINBlockKeyLocator: 0xDF8200,
  OnlinePINSMID: 0xDF4E,
  PayPassThirdPartyData: 0x9F6E,
  PayPassTransactionOutcome: 0xDF6D,
  PINEntryDisplayPromptString: 0xDF69,
  ProcessingOptionsDataObjectList: 0x9F38,
  ReaderRiskParameterRecord: 0xDF6B,
  ResponseMessageTemplateFormat1: 80,
  ResponseMessageTemplateFormat2: 77,
  ResultofOnlineProcess: 0xDF39,
  RetryConfigurationFlag: 0xDF74,
  RoamEncryptedEMVdata: 0xDF8223,
  EncryptedTrack: 0xDF8223,
  ManuallyEnteredPAN: 0xDF8226,
  ManuallyEnteredExpiryDate: 0xDF8227,
  SignedDynamicApplicationData: 0x9F4B,
  SignedStaticApplicationData: 0x93,
  StaticDataAuthenticationTagList: 0x9F4A,
  TargetPercentage: 0xDF08,
  TerminalActionCodeDefault: 0xDF03,
  TerminalActionCodeDenial: 0xDF04,
  TerminalActionCodeOnline: 0xDF05,
  TerminalConfiguration: 0xDF3D,
  TerminalDecisionafterGenerateAC: 0xDF31,
  TerminalFloorLimit: 0x9F1B,
  TerminalOptions: 0xDF0B,
  TerminalRiskManagementData: 0x9F1D,
  ThresholdValue: 0xDF07,
  Track1Data: 0x56,
  Track2DataMasterCard: 0x9F6B,
  Track2EquivalentData: 57,
  TransactionCertificateDataObjectList: 0x97,
  TransactionCertificateHashValue: 0x98,
  TransactionClass: 0xDF4D,
  TransactionCurrencyCode: 0x5F2A,
  TransactionDate: 0x9A,
  TransactionForcedOnline: 0xDF1C,
  TransactionPersonalIdentificationNumberData: 0x99,
  TransactionReferenceCurrency: 0x9F3C,
  TransactionReferenceCurrencyExponent: 0x9F3D,
  TransactionSequenceCounter: 0x9F41,
  TransactionTime: 0x9F21,
  TransactionType: 0x9C,
  TransactionTypeDescription: 0xDF70,
  VerificationonlyTransactionFlag: 0xDF75,
  VisaContactlessOfflineAvailableSpendingAmount: 0x9F5D,
  VisaDebitOptOut: 0xDF8221,
  VisaTerminalEntryCapability: 0xDF6A,
  WrapperforIssuerScriptTagWithIncorrectLength: 0xDF0C,
  ApplicationReferenceCurrency: 0x9F3B,
  ApplicationReferenceCurrencyExponent: 0x9F43,
  CardholderNameExtended: 0x9F0B,
  DataAuthenticationCode: 0x9F45,
  FCITemplate: 0x6F,
  IssuerActionCodeDefault: 0x9F0D,
  IssuerActionCodeDenial: 0x9F0E,
  IssuerActionCodeOnline: 0x9F0F,
  IssuerCodeTableIndex: 0x9F11,
  IssuerPublicKeyCertificate: 0x90,
  LowerConsecutiveOfflineLimit: 0x9F14,
  PersonalIdentificationNumberTryCounter: 0x9F17,
  ShortFileIndicator: 0x88,
  Track1DiscretionaryData: 0x9F1F,
  Track2DiscretionaryData: 0x9F20,
  UpperConsecutiveOfflineLimit: 0x9F23,
  CVC3: 0x9F61,
  PCVC3: 0x9F62,
  LogEntry: 0x9F4D,
  IssuerURL: 0x5F50,
  VLPAvailableFunds: 0x9F79,
  VLPFundsLimit: 0x9F77,
  VLPIssuerAuthorisationCode: 0x9F74,
  VLPSingleTransactionLimit: 0x9F78,
  TerminalCompatibilityIndicator: 0x9F52,
  VLPResetThreshold: 0x9F6D,
  VLPTerminalTransactionLimit: 0x9F7B,
  LastOnlineApplicationTransactionCounterRegister: 0x9F13,
  PUNATCTrack1: 0x9F63,
  NATCTrack2: 0x9F67,
  CVC3Track1: 0x9F60,
  NATCTrack1: 0x9F64,
  PCVC3rack2: 0x9F65,
  Track2DataContactless: 0x9F6B,
  CertificationAuthorityPKI: 0x9F22,
  IssuerScriptIdentifier: 0x9F18,
  MerchantNameLocation: 0x9F4E,
  VLPTerminalSupportIndicator: 0x9F7A,
  AccountType: 0x5F57,
  PUNATCTrack2: 0x9F66,
  CardTransactionQualifiers: 0x9F6C,
  ApplicationProgramIdentifier: 0x9F5A,
  OutcomeParameterSet: 0xDF8129
};

exports.default = IngenicoTags;

},{"tlvlib":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/tlvlib/build/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/js/ingenico-emv/Parser.js":[function(require,module,exports){
(function (Buffer){
'use strict';

exports.__esModule = true;
exports.parseStatus = parseStatus;
exports.parseCardData = parseCardData;

var _manticoreLog = require('manticore-log');

var _manticoreLog2 = _interopRequireDefault(_manticoreLog);

var _TransactionDataResponse = require('./TransactionDataResponse');

var _TransactionDataResponse2 = _interopRequireDefault(_TransactionDataResponse);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var Log = (0, _manticoreLog2.default)('ingenico.parser');

function parseStatus(data) {
  try {
    var status = data.slice(0, 2);
    status = new Buffer(status, 'hex');
    return status[0];
  } catch (x) {
    Log.error('Failed parsing card status ' + data + ': ' + x.message + ', stack: ' + x.stack + ', ' + x);
    throw x;
  }
}

function parseCardData(data) {
  try {
    // TODO Check for unsolicited events here.

    var status = parseStatus(data);
    var raw = data.slice(2, data.length);
    raw = new Buffer(raw, 'hex');

    return new _TransactionDataResponse2.default(status, raw, false);
  } catch (x) {
    Log.error('Failed parsing Ingenico packet ' + data + ': ' + x.message + ', stack: ' + x.stack + ', ' + x);
    throw x;
  }
}

}).call(this,require("buffer").Buffer)
},{"./TransactionDataResponse":"/Users/aravidas/Documents/Git/retail-sdk/js/ingenico-emv/TransactionDataResponse.js","buffer":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/buffer/index.js","manticore-log":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-log/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/js/ingenico-emv/SoftwareUpdate/IngenicoDeviceUpdate.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

var _retailPaymentDevice = require('retail-payment-device');

var _manticoreLog = require('manticore-log');

var _manticoreLog2 = _interopRequireDefault(_manticoreLog);

var _async = require('async');

var _async2 = _interopRequireDefault(_async);

var _manticore = require('manticore');

var _manticore2 = _interopRequireDefault(_manticore);

var _manticoreUtil = require('manticore-util');

var _moment = require('moment');

var _moment2 = _interopRequireDefault(_moment);

var _flow = require('../../common/flow');

var _flow2 = _interopRequireDefault(_flow);

var _retailSDKUtil = require('../../common/retailSDKUtil');

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (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 } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } // TODO add more alerts to show progress.

var Log = (0, _manticoreLog2.default)('ingenico.fwUpdate');
var blobDecodedStorage = 'BD';
var maxAttempts = 2;
var INGENICO_CONNECTION_RETRY_LIMIT = 10;
var INGENICO_CONNECTION_RETRY_TIMEOUT = 20000;

var lastIngenicoLogState = void 0;
var switchedOff = void 0;
var isProgressFileFetches = {};

/**
 * Shut off the Ingenico debug logs except our own component,
 * then reset them to where they were when done.
 * @param on
 */
function ingenicoLogs(on) {
  var exl = require('manticore-log')('paymentDevice.ingenicoDevice'); // eslint-disable-line global-require
  if (on && switchedOff) {
    switchedOff = false;
    if (lastIngenicoLogState) {
      exl.Config.level = lastIngenicoLogState;
    } else {
      delete exl.Config.level;
    }
    delete Log.Config.level;
    Log.debug('Re-enabled logs.');
  } else if (!on && !switchedOff) {
    Log.debug('Squelching Ingenico debug logs.');
    lastIngenicoLogState = exl.Config.level;
    switchedOff = true;
    exl.Config.level = 'INFO';
    Log.Config.level = 'DEBUG';
  }
}

function getNameFromUrl(url) {
  var finalName = url.split('/');
  finalName = finalName[finalName.length - 1];
  return finalName;
}

function pushModules(requiredUrlArray, urls, version) {
  if (requiredUrlArray) {
    for (var _iterator = urls, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
      var _ref;

      if (_isArray) {
        if (_i >= _iterator.length) break;
        _ref = _iterator[_i++];
      } else {
        _i = _iterator.next();
        if (_i.done) break;
        _ref = _i.value;
      }

      var url = _ref;

      requiredUrlArray.push({ url: url, version: version });
    }
  }
}

function _addObjectToRemoteConfig(remoteConfig, newConfig) {
  var combinedConfig = remoteConfig;
  if (combinedConfig) {
    for (var key in newConfig) {
      if (Object.prototype.hasOwnProperty.call(newConfig, key)) {
        combinedConfig[key] = newConfig[key];
      }
    }
  } else {
    combinedConfig = newConfig;
  }
  return combinedConfig;
}

function getOne(iDeviceUpdate, fileInfo, cb) {
  var retryCount = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 0;

  var url = fileInfo.url;
  var itemNameUrl = fileInfo.url + fileInfo.version;
  // Add version to the file name to ensure that we get a new file when available
  _manticore2.default.getItem(itemNameUrl, blobDecodedStorage, function (error, item) {
    if (item) {
      Log.debug(function () {
        return 'Retrieved from CACHE ' + url;
      });
      _manticore2.default.setTimeout(function () {
        return cb(null, item);
      }, 0);
      return;
    }
    // If a fetch is already in progress, and we're not it, don't do it twice.
    if (retryCount === 0) {
      if (isProgressFileFetches[url]) {
        Log.debug(function () {
          return 'Waiting for existing fetch of ' + url;
        });
        isProgressFileFetches[url].push(cb);
        return;
      }
      isProgressFileFetches[url] = [cb];
    }
    Log.debug(function () {
      return 'Fetching firmware update file ' + url;
    });

    var start = (0, _moment2.default)();
    var fileName = getNameFromUrl(url).toLowerCase();
    Log.debug(function () {
      return 'fileName: ' + fileName;
    });
    var format = fileName.substr(-5) === '.json' ? 'json' : 'binary';
    Log.debug(function () {
      return 'fileName: ' + fileName + ' format: ' + format;
    });
    _manticore2.default.http({
      url: url,
      format: format
    }, function (err, rz) {
      var timeDiff = iDeviceUpdate.device.terminal.getTimeDiff(start);
      if (err) {
        Log.error('Attempt ' + (retryCount || 0) + '/' + maxAttempts + '. Duration: ' + timeDiff + 's. Download failed for ' + url + ' with error: ' + err + ')');
      } else {
        Log.debug(function () {
          return 'Download duration: ' + timeDiff + '. Done with ' + url;
        });
      }
      if (!err && format === 'json') {
        var remoteConfig = iDeviceUpdate.device.terminal.remoteConfig;
        iDeviceUpdate.device.terminal.remoteConfig = _addObjectToRemoteConfig(remoteConfig, rz.body);
        // When we have only one config update, retain the version number of the other one
        // So default = firmwareCustomVersion
        iDeviceUpdate.device.terminal.remoteConfig.version = iDeviceUpdate.device.terminal.remoteConfig.version || iDeviceUpdate.device.terminal.firmwareCustomVersion;
        var fileInfoVersion = parseInt(fileInfo.version, 10);
        Log.debug(function () {
          return 'file ' + fileName + ' fileInfoVersion: ' + fileInfoVersion;
        });
        if (fileName === 'ingenico_capkeys.json') {
          fileInfoVersion = parseInt(fileInfo.version, 10) << 16;
          iDeviceUpdate.device.terminal.remoteConfig.version &= 0xffff; // Clear bytes of the old capKeys version
          Log.debug(function () {
            return 'file ' + fileName + ' fileInfoVersion: ' + fileInfoVersion;
          });
          Log.debug(function () {
            return fileName + ' remote.Configversion: ' + iDeviceUpdate.device.terminal.remoteConfig.version;
          });
        } else {
          iDeviceUpdate.device.terminal.remoteConfig.version &= 0xffff0000; // Clear bytes of the old config version
          Log.debug(function () {
            return fileName + ' remote.Configversion: ' + iDeviceUpdate.device.terminal.remoteConfig.version;
          });
        }
        iDeviceUpdate.device.terminal.remoteConfig.version |= fileInfoVersion;
        Log.debug(function () {
          return 'remoteConfig.version: ' + iDeviceUpdate.device.terminal.remoteConfig.version;
        });
      } else if (!err) {
        // Add version to the file name to ensure that we get a new file when available
        _manticore2.default.setItem(itemNameUrl, blobDecodedStorage, rz.body, null);
      } else if (retryCount < maxAttempts) {
        Log.warn(function () {
          return 'Fetch failed for ' + url + '. Starting retry #{retryCount+1}';
        });
        getOne(iDeviceUpdate, fileInfo, cb, (retryCount || 0) + 1);
        return;
      }
      for (var _iterator2 = isProgressFileFetches[url], _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) {
        var _ref2;

        if (_isArray2) {
          if (_i2 >= _iterator2.length) break;
          _ref2 = _iterator2[_i2++];
        } else {
          _i2 = _iterator2.next();
          if (_i2.done) break;
          _ref2 = _i2.value;
        }

        var callback = _ref2;

        callback(err, rz);
      }
      delete isProgressFileFetches[url];
    });
  });
}

var IngenicoDeviceUpdate = function (_DeviceUpdate) {
  _inherits(IngenicoDeviceUpdate, _DeviceUpdate);

  function IngenicoDeviceUpdate(device) {
    _classCallCheck(this, IngenicoDeviceUpdate);

    var _this = _possibleConstructorReturn(this, _DeviceUpdate.call(this, device));

    _this.files = {};
    _this.updates = {};
    return _this;
  }

  IngenicoDeviceUpdate.prototype.beginDeviceUpdate = function beginDeviceUpdate(callback) {
    var _this2 = this;

    // TODO Move transactionErrors to retail-payment-device when we rebase with the latest develop branch
    Log.info('Beginning SW Update on ' + this.device.id);
    isProgressFileFetches = {};
    var updateSteps = [];

    if (this.device.updates) {
      Log.debug(function () {
        return 'Found ' + _this2.device.updates.length + ' module updates';
      });
      updateSteps.push(this.updateSWModules);
    }

    var flow = new _flow2.default(this, updateSteps);
    flow.name = 'Firmware Update';
    flow.on('ended', function (data) {
      var err = data.error;
      var timeDiff = _this2.device.terminal.getTimeDiff(_this2.startTime);
      if (err) {
        Log.error('SW Update on ' + _this2.device.id + ' failed with error: ' + err + '. Duration: ' + timeDiff);
        if (err.domain === _retailPaymentDevice.deviceError.corruptFirmware.domain && err.code === _retailPaymentDevice.deviceError.corruptFirmware.code) {
          _this2.isRequired = false;
          Log.info('Marking firmware update on ' + _this2.device.id + ' as optional as the downloaded file was corrupt');
        }
      } else {
        Log.info('Firmware update completed on ' + _this2.device.id + '. Duration: ' + timeDiff); // TODO Add total time taken
      }
      if (_this2.appAlert) {
        _this2.appAlert.dismiss();
      }
      callback(err, !err);
    });
    this.startTime = (0, _moment2.default)();
    flow.start();
  };

  IngenicoDeviceUpdate.prototype.validateUpdateEligibility = function validateUpdateEligibility(callback) {
    var canUpdate = !(this.device.batteryInfo && this.device.batteryInfo.isLevelUpdateCritical);
    if (canUpdate) {
      callback();
    }
  };

  IngenicoDeviceUpdate.prototype._disableLogs = function _disableLogs(flow) {
    Log.debug('Disabling ingenico logs');
    ingenicoLogs(false);
    flow.next(null);
  };

  IngenicoDeviceUpdate.prototype._enableLogs = function _enableLogs(flow) {
    Log.debug('Enabling logs');
    ingenicoLogs(true);
    flow.next(null);
  };

  IngenicoDeviceUpdate.prototype.updateSWModules = function updateSWModules(flow) {
    var _this3 = this;

    var moduleUpdateFlow = new _flow2.default(this, this._gatherFiles, this._calculateUpdateSteps, this._updateOs, this._tryReconnect, this._retrieveVersionInfo, this._updateConfig, this._verifyUpdate, this._updateDeviceName);

    moduleUpdateFlow.name = 'Software Module Update Flow';
    moduleUpdateFlow.on('ended', function (data) {
      Log.info('Software modules update ended on ' + _this3.device.id + '. Error: ' + data.error);
      _this3._alertProgress(moduleUpdateFlow, 'Configuration', true);
      if (_this3.appAlert) {
        _this3.appAlert.dismiss();
      }
      flow.nextOrAbort(data.error);
    });
    this.appAlert = this.device.app.display({
      title: _retailPaymentDevice.appMessage.SwUpdateInProgress.title,
      message: _retailPaymentDevice.appMessage.SwUpdateInProgress.message,
      showActivity: true
    });

    moduleUpdateFlow.start();
  };

  IngenicoDeviceUpdate.prototype._generateSteps = function _generateSteps(module) {
    var steps = [];
    if (module.urls) {
      for (var _iterator3 = module.urls, _isArray3 = Array.isArray(_iterator3), _i3 = 0, _iterator3 = _isArray3 ? _iterator3 : _iterator3[Symbol.iterator]();;) {
        var _ref3;

        if (_isArray3) {
          if (_i3 >= _iterator3.length) break;
          _ref3 = _iterator3[_i3++];
        } else {
          _i3 = _iterator3.next();
          if (_i3.done) break;
          _ref3 = _i3.value;
        }

        var url = _ref3;

        steps.push({
          name: getNameFromUrl(url),
          url: url,
          version: module.version,
          reload: module.reload
        });
      }
    }

    if (module.subcomponents) {
      for (var _iterator4 = module.subcomponents, _isArray4 = Array.isArray(_iterator4), _i4 = 0, _iterator4 = _isArray4 ? _iterator4 : _iterator4[Symbol.iterator]();;) {
        var _ref4;

        if (_isArray4) {
          if (_i4 >= _iterator4.length) break;
          _ref4 = _iterator4[_i4++];
        } else {
          _i4 = _iterator4.next();
          if (_i4.done) break;
          _ref4 = _i4.value;
        }

        var component = _ref4;

        steps.push.apply(steps, _toConsumableArray(this._generateSteps(component)));
      }
    }
    return steps;
  };

  IngenicoDeviceUpdate.prototype._gatherFiles = function _gatherFiles(flow) {
    var _this4 = this;

    var _loop = function _loop() {
      if (_isArray5) {
        if (_i5 >= _iterator5.length) return 'break';
        _ref5 = _iterator5[_i5++];
      } else {
        _i5 = _iterator5.next();
        if (_i5.done) return 'break';
        _ref5 = _i5.value;
      }

      var u = _ref5;

      var steps = _this4._generateSteps(u);
      _this4.updates[u.name] = steps;
      Log.debug(function () {
        return 'Gathered update ' + u.name + '\n' + JSON.stringify(steps);
      });
    };

    for (var _iterator5 = this.device.updates, _isArray5 = Array.isArray(_iterator5), _i5 = 0, _iterator5 = _isArray5 ? _iterator5 : _iterator5[Symbol.iterator]();;) {
      var _ref5;

      var _ret = _loop();

      if (_ret === 'break') break;
    }
    this._fetchFiles(this.device, function (e) {
      Log.debug('Ready for software update.');
      flow.nextOrAbort(e);
    });
  };

  IngenicoDeviceUpdate.prototype._fetchFiles = function _fetchFiles(device, callback) {
    var _this5 = this;

    var filesToFetch = [];
    // let fetchCtr = 0;
    IngenicoDeviceUpdate.needsUpdate(device, device.updates, filesToFetch);
    Log.debug(function () {
      return 'Preparing to download ' + filesToFetch.length + ' files';
    });
    _async2.default.eachSeries(filesToFetch, function (fileInfo, cb) {
      getOne(_this5, fileInfo, cb);
    }, callback);
  };

  IngenicoDeviceUpdate.needsUpdate = function needsUpdate(device, modules, requiredUrlArray) {
    var hasUpdate = false;
    for (var _iterator6 = modules, _isArray6 = Array.isArray(_iterator6), _i6 = 0, _iterator6 = _isArray6 ? _iterator6 : _iterator6[Symbol.iterator]();;) {
      var _ref6;

      if (_isArray6) {
        if (_i6 >= _iterator6.length) break;
        _ref6 = _iterator6[_i6++];
      } else {
        _i6 = _iterator6.next();
        if (_i6.done) break;
        _ref6 = _i6.value;
      }

      var module = _ref6;

      if (module.name === 'ingenico_firmware') {
        hasUpdate = true;
        device._expectedFirmwareChecksum = module.version;
        Log.info(device.id + ' OS will be updated from ' + device.terminal.firmwareChecksum + ' to ' + module.version);
        pushModules(requiredUrlArray, module.urls, module.version);
      } else if (module.name === 'Ingenico_CONFIG' && module.subcomponents) {
        hasUpdate = true;
        Log.info(device.id + ' CFG will be updated with ' + module.subcomponents.length + ' sub components.');
        for (var _iterator7 = module.subcomponents, _isArray7 = Array.isArray(_iterator7), _i7 = 0, _iterator7 = _isArray7 ? _iterator7 : _iterator7[Symbol.iterator]();;) {
          var _ref7;

          if (_isArray7) {
            if (_i7 >= _iterator7.length) break;
            _ref7 = _iterator7[_i7++];
          } else {
            _i7 = _iterator7.next();
            if (_i7.done) break;
            _ref7 = _i7.value;
          }

          var component = _ref7;

          Log.info(device.id + ' Sub components version: ' + component.version);
          pushModules(requiredUrlArray, component.urls, component.version);
        }
      }
    }
    if (!hasUpdate) {
      Log.debug(function () {
        return device.id + ' does not need an upgrade.';
      });
    } else {
      device.terminal.remoteConfig = {};
    }
    return hasUpdate;
  };

  IngenicoDeviceUpdate.prototype._calculateUpdateSteps = function _calculateUpdateSteps(flow) {
    var pkLen = this.device.terminal.remoteConfig.PublicKeys ? this.device.terminal.remoteConfig.PublicKeys.length : 0;
    // If FW update is required, the number of steps will be known on the first progress message
    flow.data.configUpdateStepCount = pkLen + 16; // FW update steps will be added later, if required
    flow.data.fwUpdateStepCount = 1;
    flow.data.currentStepNumber = 0;
    flow.next();
    // Count and add public keys to updateSteps
  };

  IngenicoDeviceUpdate.prototype._fWUpdateProgressHandler = function _fWUpdateProgressHandler(flow, updateProgressMessage) {
    var _updateProgressMessage = updateProgressMessage || '0/0';
    var updateProgressParts = _updateProgressMessage.split('/');
    flow.data.fwUpdateStepCount = parseInt(updateProgressParts[1], 10) + 1;
    flow.data.currentStepNumber = parseInt(updateProgressParts[0], 10);

    this._alertProgress(flow, 'OS');
  };

  IngenicoDeviceUpdate.prototype._addAndAlertProgress = function _addAndAlertProgress(flow, stageId, updateCount) {
    var _this6 = this;

    Log.debug(function () {
      return _this6.device.id + ' _addAndAlertProgress ' + stageId + ' updateCount: ' + updateCount;
    });
    flow.data.currentStepNumber += updateCount;
    Log.debug(function () {
      return '_addAndAlertProgress currentStepNumber: ' + flow.data.currentStepNumber;
    });
    this._alertProgress(flow, stageId);
  };

  IngenicoDeviceUpdate.prototype._alertProgress = function _alertProgress(flow, stageId, complete) {
    var _this7 = this;

    var totalSteps = flow.data.fwUpdateStepCount + flow.data.configUpdateStepCount;
    var currentStep = complete ? totalSteps : flow.data.currentStepNumber;
    var prevProgressPercent = flow.data.progressPercent;
    flow.data.progressPercent = parseInt(currentStep * 100 / totalSteps, 10);
    var updateApp = prevProgressPercent !== flow.data.progressPercent;
    Log.debug(function () {
      return _this7.device.id + ' Total steps: ' + totalSteps + ', current step: ' + currentStep + ', prevProgressPercent: ' + prevProgressPercent + ' progressPercent: ' + flow.data.progressPercent + ', updateApp: ' + updateApp;
    });

    if (updateApp) {
      this.appAlert = this.device.app.display({
        title: _retailPaymentDevice.appMessage.SwUpdateInProgressWithDetails.title,
        message: {
          id: _retailPaymentDevice.appMessage.SwUpdateInProgressWithDetails.message,
          substitutions: { stage: stageId, progress: flow.data.progressPercent }
        },
        showActivity: true
      });
    }
  };

  IngenicoDeviceUpdate.prototype._updateOs = function _updateOs(flow) {
    var _this8 = this;

    var osUpdates = this.updates.ingenico_firmware;
    if (!osUpdates || osUpdates.length === 0) {
      Log.debug('OS update not needed.');
      flow.data.restartRequired = false;
      flow.next(null);
      return;
    }

    // Add version to the file name to ensure that we get a new file when available
    var url = osUpdates[0].url + osUpdates[0].version;
    this.device.terminal.updateFirmware(url, function (updateProgressMessage) {
      // Pass the current flow to the progress handler
      _this8._fWUpdateProgressHandler(flow, updateProgressMessage);
    }, function (err) {
      flow.data.restartRequired = true;
      _this8._addAndAlertProgress(flow, 'OS', 1);
      flow.nextOrAbort(err);
    });
  };

  IngenicoDeviceUpdate.prototype._retrieveVersionInfo = function _retrieveVersionInfo(flow) {
    this._addAndAlertProgress(flow, 'Configuration', 1);
    this.device.terminal.getFirmwareVersionInfo(function (err) {
      return flow.nextOrAbort(err);
    });
  };

  IngenicoDeviceUpdate.prototype._tryReconnect = function _tryReconnect(flow) {
    var _this9 = this;

    if (!flow.data.restartRequired) {
      Log.debug('Restart not required');
      this._addAndAlertProgress(flow, 'Configuration', 1);
      flow.next();
      return;
    }
    this.appAlert = this.device.app.display({
      title: this.device.isMoby ? _retailPaymentDevice.appMessage.SwUpdateRestartInstruction.title : _retailPaymentDevice.appMessage.SwUpdateReconnecting.title,
      message: this.device.isMoby ? _retailPaymentDevice.appMessage.SwUpdateRestartInstruction.message : _retailPaymentDevice.appMessage.SwUpdateReconnecting.message,
      showActivity: true
    });
    this._pollUntilConnect(INGENICO_CONNECTION_RETRY_LIMIT, INGENICO_CONNECTION_RETRY_TIMEOUT, function (err) {
      _this9._addAndAlertProgress(flow, 'OS', 1);
      flow.nextOrAbort(err);
    });
  };

  IngenicoDeviceUpdate.prototype._pollUntilConnect = function _pollUntilConnect(remainingAttempts, msWaitTime, cb) {
    var _this10 = this;

    Log.debug(function () {
      return 'Disconnecting ' + _this10.device.id + ' as part of reconnection';
    });
    this.device.forceDisconnect(function () {
      Log.debug(function () {
        return 'Disconnected ' + _this10.device.id + '!. Proceeding to reconnect';
      });
      _manticore2.default.setTimeout(function () {
        Log.debug(function () {
          return 'Attempting reconnect to ' + _this10.device.id + '. Remaining attempts: ' + remainingAttempts;
        });
        _this10.device.connect(function (e) {
          if (e) {
            Log.warn('Reconnect failed with error ' + e + '. Remaining attempts: ' + remainingAttempts);
            var newCount = remainingAttempts - 1;
            if (newCount <= 0) {
              Log.error('Giving up device connection with ' + _this10.device.id + ' as all retry attempts were exhausted');
              cb(e);
            } else {
              _this10._pollUntilConnect(newCount, msWaitTime, cb);
            }
          } else {
            Log.info(_this10.device.id + ' was successfully connected after restart. Remaining attempts: ' + remainingAttempts);
            cb(null);
          }
        });
      }, msWaitTime);
    });
  };

  IngenicoDeviceUpdate.prototype._configUpdateProgressCallback = function _configUpdateProgressCallback(flow, err, nextOrAbort) {
    this._addAndAlertProgress(flow.data.updateFlow, 'Configuration', 1);
    if (nextOrAbort) {
      flow.nextOrAbort(err);
    } else {
      flow.next();
    }
  };

  IngenicoDeviceUpdate.prototype._verifyUpdate = function _verifyUpdate(flow) {
    var _this11 = this;

    if (!this.device._expectedFirmwareChecksum) {
      Log.info('Will not validate firmware checksum as there was no UNS file update on ' + this.device.id);
      flow.next();
      return;
    }

    this.device.terminal.getFirmwareChecksum(function (err) {
      Log.info('Firmware checksum BEFORE : \'' + _this11.device._expectedFirmwareChecksum + '\', AFTER \'' + _this11.device.terminal.firmwareChecksum + '\'');
      if (_this11.device._expectedFirmwareChecksum !== _this11.device.terminal.firmwareChecksum) {
        flow.nextOrAbort(_retailPaymentDevice.deviceError.swUpdateFailed.withDevMessage('Checksum did not match after firmware update. Expected \'' + _this11.device._expectedFirmwareChecksum + '\', Actual: \'' + _this11.device.terminal.firmwareChecksum + '\''));
      } else {
        flow.nextOrAbort(err);
      }
    });
  };

  IngenicoDeviceUpdate.prototype._updateConfig = function _updateConfig(flow) {
    var cfgUpdates = this.updates.Ingenico_CONFIG;
    if (!cfgUpdates || cfgUpdates.length === 0) {
      Log.debug('Config update not needed.');
      flow.next();
      return;
    }
    var configFlow = new _flow2.default(this, this._clearAidList, this._clearPublicKeys, this._configureContactAidList, this._configureContactlessAidList, this._configurePublicKeys, this._configureAmountDol, this._configureOnlineDol, this._configureResponseDol, this._configureContactlessOnlineResponseDol, this._configureContactlessResponseDol, this._configureMagstripeDol, this._configureContactlessOptions, this._sendConfigCommands, this._setConfigVersion);
    configFlow.name = 'Ingenico config';
    configFlow.data.restartRequired = true;
    configFlow.data.updateFlow = flow;
    configFlow.on('completed', function (data) {
      Log.debug(function () {
        return 'Config flow completed. Error: ' + data.error;
      });
      flow.next();
    });
    configFlow.on('aborted', function (data) {
      Log.debug(function () {
        return 'Config flow aborted. Error: ' + data.error;
      });
      flow.abort(data.error);
    });
    Log.debug('Starting the config flow');
    this._addAndAlertProgress(flow, 'Configuration', 1);
    configFlow.start();
  };

  IngenicoDeviceUpdate.prototype._configureOnlineDol = function _configureOnlineDol(flow) {
    var _this12 = this;

    this.device.terminal.configureOnlineDol(function (err) {
      return _this12._configUpdateProgressCallback(flow, err, true);
    });
  };

  IngenicoDeviceUpdate.prototype._configureAmountDol = function _configureAmountDol(flow) {
    var _this13 = this;

    this.device.terminal.configureAmountDol(function (err) {
      return _this13._configUpdateProgressCallback(flow, err, true);
    });
  };

  IngenicoDeviceUpdate.prototype._configureResponseDol = function _configureResponseDol(flow) {
    var _this14 = this;

    this.device.terminal.configureResponseDol(function (err) {
      return _this14._configUpdateProgressCallback(flow, err, true);
    });
  };

  IngenicoDeviceUpdate.prototype._configureContactlessResponseDol = function _configureContactlessResponseDol(flow) {
    var _this15 = this;

    if (this.device.model === _retailPaymentDevice.ReaderModel.Moby3000) {
      Log.debug('Not configuring contactless DOL.');
      this._configUpdateProgressCallback(flow, null, false);
    } else {
      this.device.terminal.configureContactlessResponseDol(function (err) {
        return _this15._configUpdateProgressCallback(flow, err, true);
      });
    }
  };

  IngenicoDeviceUpdate.prototype._configureContactlessOnlineResponseDol = function _configureContactlessOnlineResponseDol(flow) {
    var _this16 = this;

    if (this.device.model === _retailPaymentDevice.ReaderModel.Moby3000) {
      Log.debug('Not configuring contactless response DOL');
      this._configUpdateProgressCallback(flow, null, false);
    } else {
      this.device.terminal.configureContactlessOnlineDol(function (err) {
        return _this16._configUpdateProgressCallback(flow, err, true);
      });
    }
  };

  IngenicoDeviceUpdate.prototype._configureMagstripeDol = function _configureMagstripeDol(flow) {
    var _this17 = this;

    this.device.terminal.configureMagstripeDol(function (err) {
      return _this17._configUpdateProgressCallback(flow, err, true);
    });
  };

  IngenicoDeviceUpdate.prototype._clearAidList = function _clearAidList(flow) {
    var _this18 = this;

    this.device.terminal.clearAidList(function (err) {
      return _this18._configUpdateProgressCallback(flow, err, true);
    });
  };

  IngenicoDeviceUpdate.prototype._clearPublicKeys = function _clearPublicKeys(flow) {
    var _this19 = this;

    this.device.terminal.clearPublicKeys(function (err) {
      return _this19._configUpdateProgressCallback(flow, err, true);
    });
  };

  IngenicoDeviceUpdate.prototype._configurePublicKeys = function _configurePublicKeys(flow) {
    var _this20 = this;

    this.device.terminal.configurePublicKeys(function () {
      _this20._addAndAlertProgress(flow.data.updateFlow, 'Configuration', 1);
    }, function (err) {
      return _this20._configUpdateProgressCallback(flow, err, true);
    });
  };

  IngenicoDeviceUpdate.prototype._configureContactAidList = function _configureContactAidList(flow) {
    var _this21 = this;

    this.device.terminal.configureContactAidList(function (err) {
      return _this21._configUpdateProgressCallback(flow, err, true);
    });
  };

  IngenicoDeviceUpdate.prototype._configureContactlessAidList = function _configureContactlessAidList(flow) {
    var _this22 = this;

    if (this.device.model === _retailPaymentDevice.ReaderModel.Moby3000) {
      Log.debug('Not configuring contactless AidList');
      this._configUpdateProgressCallback(flow, null, false);
    } else {
      this.device.terminal.configureContactlessAidList(function (err) {
        return _this22._configUpdateProgressCallback(flow, err, true);
      });
    }
  };

  IngenicoDeviceUpdate.prototype._configureContactlessOptions = function _configureContactlessOptions(flow) {
    var _this23 = this;

    if (this.device.model === _retailPaymentDevice.ReaderModel.Moby3000) {
      Log.debug('Not configuring contactless options');
      this._configUpdateProgressCallback(flow, null, false);
    } else {
      this.device.terminal.configureContactlessOptions(function (err) {
        return _this23._configUpdateProgressCallback(flow, err, true);
      });
    }
  };

  IngenicoDeviceUpdate.prototype._sendConfigCommands = function _sendConfigCommands(flow) {
    var _this24 = this;

    this.device.terminal.sendConfigCommands(function (err) {
      return _this24._configUpdateProgressCallback(flow, err, true);
    });
  };

  IngenicoDeviceUpdate.prototype._setConfigVersion = function _setConfigVersion(flow) {
    var _this25 = this;

    this.device.terminal.setConfigVersion(function (err, response) {
      Log[err ? 'error' : 'info']('versionInfo> Custom version of \'' + _this25.device.id + '\' set. Response: ' + response);
      _this25.device.terminal.getConfigVersion(function () {
        _this25._configUpdateProgressCallback(flow, err, true);
      });
    });
  };

  IngenicoDeviceUpdate.prototype._updateDeviceName = function _updateDeviceName(flow) {
    var _this26 = this;

    if (this.device.model === _retailPaymentDevice.ReaderModel.RP450 && this.device.id.indexOf('PayPal-') === 0) {
      var oldId = this.device.id;
      this.device.id = this.device.id.replace('PayPal-', 'PPHere-');
      Log.info(function () {
        return (0, _manticoreUtil.getPropertyName)(_retailPaymentDevice.ReaderModel, _this26.device.model) + ' (address=\'' + _this26.device.address + '\') ID changed from \'' + oldId + '\' to \'' + _this26.device.id + '\'';
      });
      (0, _retailSDKUtil.saveLastActiveReader)(this.device, function () {
        flow.next();
      });
    } else {
      flow.next();
    }
  };

  IngenicoDeviceUpdate.prototype._getCachedFile = function _getCachedFile(url, cb) {
    _manticore2.default.getItem(url, blobDecodedStorage, function (e, file) {
      cb(file ? null : _retailPaymentDevice.deviceError.swUpdateFailed.withDevMessage('File with url: ' + url + ' was not found on the device'), file);
    });
  };

  return IngenicoDeviceUpdate;
}(_retailPaymentDevice.DeviceUpdate);

exports.default = IngenicoDeviceUpdate;

},{"../../common/flow":"/Users/aravidas/Documents/Git/retail-sdk/js/common/flow.js","../../common/retailSDKUtil":"/Users/aravidas/Documents/Git/retail-sdk/js/common/retailSDKUtil.js","async":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/async/lib/async.js","manticore":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore/browser.js","manticore-log":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-log/index.js","manticore-util":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-util/build/index.js","moment":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/moment/moment.js","retail-payment-device":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/js/ingenico-emv/Terminal.js":[function(require,module,exports){
(function (Buffer){
'use strict';

exports.__esModule = true;

var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };

var _manticoreLog = require('manticore-log');

var _manticoreLog2 = _interopRequireDefault(_manticoreLog);

var _paypalInvoicing = require('paypal-invoicing');

var _events = require('events');

var _tlvlib = require('tlvlib');

var _retailPaymentDevice = require('retail-payment-device');

var _manticore = require('manticore');

var _manticore2 = _interopRequireDefault(_manticore);

var _manticoreUtil = require('manticore-util');

var _moment = require('moment');

var _moment2 = _interopRequireDefault(_moment);

var _async = require('async');

var _async2 = _interopRequireDefault(_async);

var _eventType = require('./eventType');

var _eventType2 = _interopRequireDefault(_eventType);

var _IngenicoTags = require('./IngenicoTags');

var _IngenicoTags2 = _interopRequireDefault(_IngenicoTags);

var _Parser = require('./Parser');

var _Writer = require('./Writer');

var _Writer2 = _interopRequireDefault(_Writer);

var _IngenicoCommand = require('./IngenicoCommand');

var _IngenicoCommand2 = _interopRequireDefault(_IngenicoCommand);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (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 } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var defaultConfiguration = require('./ingenico_config.json');

var Log = (0, _manticoreLog2.default)('ingenico.terminal');
var TransactionTypeRefund = 20;
var blobDecodedStorage = 'BD';
var disableChip = 0x01;
var disableEmvCertifiedContactless = 0x02;
var disableMagneticCardSwipe = 0x04;

function createApduCommand(cls, ins, p1, p2, len, data) {
  return new _tlvlib.ApduCommand(cls, ins, p1, p2, len, data, true);
}

function buildTlvListForTx(txType, amount, currencyCode, formFactors) {
  var tlvList = new _tlvlib.TlvList();
  var now = new Date();

  // Transaction data
  tlvList.add(_tlvlib.Tags.TransactionCurrencyCode, currencyCode); // 5f2a
  tlvList.add(_IngenicoTags2.default.AmountAuthorizedBinary, _IngenicoTags2.default.AmountAuthorizedBinary.format.toBytes(amount, _IngenicoTags2.default.AmountAuthorizedBinary.length)); // 81
  tlvList.add(_tlvlib.Tags.TransactionType, txType); // 9c
  tlvList.add(_tlvlib.Tags.AmountAuthorized, _tlvlib.Tags.AmountAuthorized.format.toBytes(amount, 6)); // 9f02
  tlvList.add(_tlvlib.Tags.AmountOther, _tlvlib.Tags.AmountOther.format.toBytes(0, 6)); // 9f03
  tlvList.add(_IngenicoTags2.default.AmountOtherBinary, _IngenicoTags2.default.AmountOtherBinary.format.toBytes(0, _IngenicoTags2.default.AmountOtherBinary.length)); // 9f04

  // Application data
  tlvList.add(_IngenicoTags2.default.TransactionCurrencyExponent, 2); // 5f36
  tlvList.add(_tlvlib.Tags.TransactionDate, now); // 9a
  tlvList.add(_IngenicoTags2.default.TerminalCountryCode, currencyCode); // 9f1a
  tlvList.add(_IngenicoTags2.default.TerminalIdentification, '3132333435363738'); // 9f1c
  tlvList.add(_tlvlib.Tags.TransactionTime, now); // 9f21
  tlvList.add(_IngenicoTags2.default.POSEntryMode, 0); // 9f39
  tlvList.add(_IngenicoTags2.default.AuthorizationResponseCodeList, '59315A3159325A3259335A333030303530313034'); // df16
  tlvList.add(_IngenicoTags2.default.ExtraProgressMessageFlag, '01'); // DF68
  tlvList.add(_IngenicoTags2.default.TerminalApplicationVersionNumber, '0020'); // 9F09
  // the battery level threshold is used to decide the battery level under which the start transaction does not execute
  // it is 12 by default. Setting it to 0 makes it behave like Miura device
  tlvList.add(_IngenicoTags2.default.BatteryLevelThreshold, '00'); // DF8239
  // GenerateACControl
  tlvList.add(_tlvlib.Tags.GenerateACControl, txType === TransactionTypeRefund ? 0x02 : 0x00); // df72

  if (formFactors.has(_retailPaymentDevice.FormFactor.EmvCertifiedContactless)) {
    tlvList.add(_IngenicoTags2.default.OverallContactlessTransactionLimit, 'FFFFFFFF'); // df65
  }

  if (formFactors.has(_retailPaymentDevice.FormFactor.Chip)) {
    tlvList.add(_IngenicoTags2.default.TerminalCapabilities, 'E028C8'); // 9F33
    tlvList.add(_IngenicoTags2.default.AdditionalTerminalCapabilities, 'F000F0A001'); // 9F40
    tlvList.add(_IngenicoTags2.default.TerminalType, 22); // 9F35
    tlvList.add(_IngenicoTags2.default.TransactionCategoryCode, 52); // 9F53
  }

  tlvList.add(_IngenicoTags2.default.RFParam, '0400'); // DF8240
  return tlvList;
}

function getCurrencyIso(currency) {
  switch (currency) {
    case 'AUD':
      return 36;
    case 'GBP':
      return 826;
    case 'USD':
      return 840;
    case 'HKD':
      return 344;
    case 'EUR':
      return 978;
    case 'CAD':
      return 124;
    default:
      return null;
  }
}

function buildAidApps(dr, response) {
  var appId = void 0;
  var appLabel = null;
  var respTlvList = new _tlvlib.TlvList(response);
  for (var _iterator = respTlvList.values, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
    var _ref;

    if (_isArray) {
      if (_i >= _iterator.length) break;
      _ref = _iterator[_i++];
    } else {
      _i = _iterator.next();
      if (_i.done) break;
      _ref = _i.value;
    }

    var v = _ref;

    var parsed = v.parse();
    if (v.tag === _tlvlib.Tags.TerminalApplicationIdentifier) {
      if (appId) {
        dr.apps.push([appId, appLabel]);
        appLabel = null;
      }
      appId = parsed;
    } else if (v.tag === _tlvlib.Tags.ApplicationLabel) {
      if (appLabel && appId) {
        dr.apps.push([appId, appLabel]);
        appId = null;
      }
      appLabel = parsed;
    }
  }
  if (appId) {
    dr.apps.push([appId, appLabel.toString()]);
  }
}

function buildApps(dr, response) {
  for (var _iterator2 = response.apdu.tlvs.values, _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) {
    var _ref2;

    if (_isArray2) {
      if (_i2 >= _iterator2.length) break;
      _ref2 = _iterator2[_i2++];
    } else {
      _i2 = _iterator2.next();
      if (_i2.done) break;
      _ref2 = _i2.value;
    }

    var v = _ref2;

    if (v.tag === _tlvlib.Tags.ApplicationTemplate) {
      var aidResp = v.parse();
      buildAidApps(dr, aidResp);
    }
  }
}

function toHex(value, padLength) {
  var padLengthOrDefault = 2;
  if (padLength !== undefined) {
    padLengthOrDefault = padLength;
  }
  var hexStr = value.toString(16);
  while (hexStr.length < padLengthOrDefault) {
    hexStr = '0' + hexStr;
  }
  return hexStr;
}

function getTlvData(aid) {
  var tlv = aid.tlvData;
  var tlvData = '';
  for (var key in tlv) {
    if (Object.prototype.hasOwnProperty.call(tlv, key)) {
      tlvData += key;
      var curTlv = tlv[key];
      var curTlvLength = curTlv.length / 2;
      tlvData += toHex(curTlvLength);
      tlvData += curTlv;
    }
  }
  var tlvDataLength = tlvData.length / 2;
  tlvData = toHex(tlvDataLength, 4) + tlvData;
  return tlvData;
}

function getContactlessData(aid) {
  var aidData = aid.FloorLimit;
  aidData += aid.CVMLimit;
  aidData += aid.TxnLimit;
  aidData += aid.TermCaps;
  aidData += getTlvData(aid);

  return aidData;
}

var TerminalStatus = {
  Contact: {
    Decline: function Decline(status) {
      return status === 0x00 || status === 0x90;
    },
    OnlineDol: function OnlineDol(status) {
      return status === 0x01 || status === 0x91;
    },
    DecisionRequired: function DecisionRequired(status) {
      return status === 0x91;
    }
  },
  Contactless: {
    OfflineDecline: function OfflineDecline(status) {
      return status === 0x03 || status === 0x93;
    },
    OnlineDol: function OnlineDol(status) {
      return status === 0x04 || status === 0x94;
    },
    DecisionRequired: function DecisionRequired(status) {
      return status === 0x01;
    },
    Magstripe: function Magstripe(status) {
      return status === 0x02;
    }
  },
  AmountDol: function AmountDol(status) {
    return status === 0x00 || status === 0x90;
  }
};

/* eslint max-len: "off" */

var Terminal = function (_EventEmitter) {
  _inherits(Terminal, _EventEmitter);

  function Terminal(sendFn, reader) {
    _classCallCheck(this, Terminal);

    var _this = _possibleConstructorReturn(this, _EventEmitter.call(this));

    _this.nativeShim = sendFn;
    _this.reader = reader;
    _this.remoteConfig = {};
    _this.firmwareChecksum = '';
    _this.writer = new _Writer2.default(reader);
    return _this;
  }

  Terminal.prototype.disconnect = function disconnect() {
    Log.debug('Clearing the writer queue and re-creating it');
    this.writer.clear();
    this.writer = new _Writer2.default(this.reader);
  };

  Terminal.prototype.getFirmwareVersionInfo = function getFirmwareVersionInfo(callback) {
    var apdu = createApduCommand(0xFF, 0x00, 0x01, 0);
    this.writer.send(new _IngenicoCommand2.default('get-firmware-version', apdu), callback);
  };

  Terminal.prototype.getFirmwareVersionInfoAsync = function getFirmwareVersionInfoAsync() {
    return regeneratorRuntime.async(function getFirmwareVersionInfoAsync$(_context) {
      while (1) {
        switch (_context.prev = _context.next) {
          case 0:
            _context.next = 2;
            return regeneratorRuntime.awrap((0, _manticoreUtil.callbackToPromise)(this.getFirmwareVersionInfo.bind(this)));

          case 2:
            return _context.abrupt('return', _context.sent);

          case 3:
          case 'end':
            return _context.stop();
        }
      }
    }, null, this);
  };

  Terminal.prototype.getFirmwareChecksum = function getFirmwareChecksum(callback) {
    var _this2 = this;

    var apdu = createApduCommand(0xFF, 0x88, 0x09, 0x06);
    this.writer.send(new _IngenicoCommand2.default('get-firmware-checksum', apdu), function (err, rz) {
      if (err) {
        callback(err);
        return;
      }
      var rzBuf = new Buffer(rz, 'hex');
      var checksumInfo = JSON.parse(rzBuf.toString());
      if (checksumInfo && checksumInfo.FW) {
        _this2.firmwareChecksum = checksumInfo.FW.Chk;
      }
      Log.debug(function () {
        return _this2.reader.id + ' firmwareChecksum: ' + _this2.firmwareChecksum + '. Response: ' + rzBuf.toString();
      });
      callback(err, rz);
    });
  };

  Terminal.prototype.getFirmwareChecksumAsync = function getFirmwareChecksumAsync() {
    return regeneratorRuntime.async(function getFirmwareChecksumAsync$(_context2) {
      while (1) {
        switch (_context2.prev = _context2.next) {
          case 0:
            _context2.next = 2;
            return regeneratorRuntime.awrap((0, _manticoreUtil.callbackToPromise)(this.getFirmwareChecksum.bind(this)));

          case 2:
            return _context2.abrupt('return', _context2.sent);

          case 3:
          case 'end':
            return _context2.stop();
        }
      }
    }, null, this);
  };

  Terminal.prototype.getConfigVersion = function getConfigVersion(callback) {
    var _this3 = this;

    var apdu = createApduCommand(0xFF, 0x88, 0x09, 0x04);
    this.writer.send(new _IngenicoCommand2.default('get-config-version', apdu), function (err, rz) {
      if (err) {
        callback(err);
        return;
      }
      var rzBuf = new Buffer(rz, 'hex');
      var versionInfo = JSON.parse(rzBuf.toString());
      if (versionInfo && versionInfo.SW) {
        _this3.firmwareCustomVersion = parseInt(versionInfo.SW.name, 16);
      }
      Log.info(_this3.reader.id + ' versionInfo> Got configVersion: \'' + (_this3.firmwareCustomVersion & 0xffff) + '\', capkeysVersion: \'' + (_this3.firmwareCustomVersion >> 16 & 0xffff) + '\', firmwareCustomVersion: \'' + _this3.firmwareCustomVersion + '\' versionInfo: \'' + JSON.stringify(versionInfo) + '\', full response: ' + rzBuf.toString());
      callback(err, rz);
    });
  };

  Terminal.prototype.getConfigVersionAsync = function getConfigVersionAsync() {
    return regeneratorRuntime.async(function getConfigVersionAsync$(_context3) {
      while (1) {
        switch (_context3.prev = _context3.next) {
          case 0:
            _context3.next = 2;
            return regeneratorRuntime.awrap((0, _manticoreUtil.callbackToPromise)(this.getConfigVersion.bind(this)));

          case 2:
            return _context3.abrupt('return', _context3.sent);

          case 3:
          case 'end':
            return _context3.stop();
        }
      }
    }, null, this);
  };

  Terminal.prototype.setConfigVersion = function setConfigVersion(callback) {
    var _this4 = this;

    var customVersion = this.remoteConfig.version || 0;
    var terminalCustomVersion = '000000000000' + toHex(customVersion, 8);
    var terminalCustomVersionCommand = 'ff8809010a' + terminalCustomVersion + '00';
    var ingenicoCommand = new _IngenicoCommand2.default('set-config-version');
    ingenicoCommand.rawHexCommand = terminalCustomVersionCommand;
    Log.info(this.reader.id + ' versionInfo> Setting config version to remote version \'' + this.remoteConfig.version + '\'. TerminalCustomVersion: \'' + terminalCustomVersion + '\', cmd: \'' + terminalCustomVersionCommand + '\'');
    this.writer.send(ingenicoCommand, function (err, rz) {
      Log[err ? 'error' : 'debug'](function () {
        return _this4.reader.id + ' versionInfo> Received response to setConfigVersion ' + customVersion + ' with Error: ' + err + ', rz: ' + rz;
      });
      _this4.firmwareCustomVersion = customVersion;
      callback(err, terminalCustomVersion);
    });
  };

  Terminal.prototype.updateFirmware = function updateFirmware(url, progressCallback, callback) {
    var _this5 = this;

    Log.debug(function () {
      return 'Firmware update file ' + url;
    });
    var uStart = (0, _moment2.default)();
    _manticore2.default.getItemPath(url, blobDecodedStorage, function (fErr, fwFileLocation) {
      Log.debug(function () {
        return 'File path: ' + fwFileLocation + ', error: ' + fErr;
      });
      if (fErr) {
        callback(fErr);
        return;
      }

      if (!_this5.nativeShim.isUnsFileValid(fwFileLocation)) {
        _manticore2.default.deleteItem(url, blobDecodedStorage, function (delErr, delResponse) {
          Log.debug(function () {
            return 'Delete update file. Error: ' + delErr + ', response: ' + delResponse;
          });
          callback(_retailPaymentDevice.deviceError.corruptFirmware);
        });
        return;
      }

      var cmdEnableFWUpdate = new _IngenicoCommand2.default('enableFirmwareUpdateMode');
      cmdEnableFWUpdate.nativeCommand = true;
      _this5.writer.send(cmdEnableFWUpdate, function (fwmErr, fwmResponse) {
        Log.debug(function () {
          return 'Enabled firmware update mode. err: ' + fwmErr + ' response: ' + fwmResponse;
        });
        if (fwmErr) {
          callback(fwmErr);
          return;
        }
        Log.debug(function () {
          return 'fwFileLocation = ' + fwFileLocation + ' this.nativeShim.updateFirmware';
        });
        var cmdUpdateFirmware = new _IngenicoCommand2.default('updateFirmware');
        cmdUpdateFirmware.nativeCommand = {
          fwFileLocation: fwFileLocation,
          progressCallback: progressCallback
        };
        _this5.writer.send(cmdUpdateFirmware, function (uErr, uRz) {
          Log.debug(function () {
            return 'Update firmware complete. Push duration: ' + _this5.getTimeDiff(uStart) + ' error: ' + uErr + ', response: ' + uRz;
          });
          _manticore2.default.deleteItem(url, blobDecodedStorage, function (delErr, delResponse) {
            Log.debug(function () {
              return 'Delete update file. Error: ' + delErr + ', response: ' + delResponse;
            });
            callback(uErr, uRz);
          });
        });
      });
    });
  };

  Terminal.prototype.getTimeDiff = function getTimeDiff(then) {
    var now = (0, _moment2.default)();
    var diff = now.diff(then);
    return _moment2.default.utc(diff).format('HH:mm:ss:SSS');
  };

  Terminal.prototype.getCardInsertionStatus = function getCardInsertionStatus(callback) {
    var apdu = createApduCommand(0xFF, 0x01, 0x00, 0);
    this.writer.send(new _IngenicoCommand2.default('get-card-insertion-status', apdu), callback);
  };

  // TODO


  Terminal.prototype.waitForCardRemoval = function waitForCardRemoval(useTimeout, callback) {
    var _this6 = this;

    // ea60 = One minute timeout, ffff = infinite timeout
    var waitTimeout = useTimeout ? 'ea60' : 'ffff';
    var waitForCardRemovalCommand = 'ff01020002' + waitTimeout + '00';
    var ingenicoCommand = new _IngenicoCommand2.default('wait-for-card-removal');
    ingenicoCommand.rawHexCommand = waitForCardRemovalCommand;
    this.writer.send(ingenicoCommand, function (err, rz) {
      Log.debug(function () {
        return 'Received response to waitForCardRemoval with Error : ' + JSON.stringify(err) + ' \n and response : ' + rz;
      });
      _this6.reader.received({ event: _eventType2.default.cardRemoved });
      callback(err, rz);
    });
  };

  Terminal.prototype.getDeviceCapabilities = function getDeviceCapabilities(callback) {
    var apdu = createApduCommand(0xFF, 0x00, 0x02, 0);
    this.writer.send(new _IngenicoCommand2.default('get-device-capabilities', apdu), callback);
  };

  Terminal.prototype.getDeviceCapabilitiesAsync = function getDeviceCapabilitiesAsync() {
    return regeneratorRuntime.async(function getDeviceCapabilitiesAsync$(_context4) {
      while (1) {
        switch (_context4.prev = _context4.next) {
          case 0:
            _context4.next = 2;
            return regeneratorRuntime.awrap((0, _manticoreUtil.callbackToPromise)(this.getDeviceCapabilities.bind(this)));

          case 2:
            return _context4.abrupt('return', _context4.sent);

          case 3:
          case 'end':
            return _context4.stop();
        }
      }
    }, null, this);
  };

  Terminal.prototype._configurationHasKey = function _configurationHasKey(key) {
    return this.remoteConfig && key in this.remoteConfig;
  };

  Terminal.prototype._getConfigurationTagsForKey = function _getConfigurationTagsForKey(key) {
    var _this7 = this;

    if (this.remoteConfig && key in this.remoteConfig) {
      Log.debug(function () {
        return 'Got the tags for key : ' + key + ' ' + JSON.stringify(_this7.remoteConfig[key]);
      });
      return this.remoteConfig[key];
    }
    Log.debug(function () {
      return 'Returning null for key : ' + key;
    });
    return null;
  };

  Terminal.prototype.configureOnlineDol = function configureOnlineDol(callback) {
    if (this._configurationHasKey('OnlineDol')) {
      var apdu = createApduCommand(0xFF, 0x81, 0x07, 0x01);
      var config = this._getConfigurationTagsForKey('OnlineDol', defaultConfiguration.OnlineDol);
      apdu.appendBytes(new Buffer(config, 'hex'));
      this.writer.send(new _IngenicoCommand2.default('configure-online-dol', apdu), callback);
    } else {
      Log.warn('Skip configureOnlineDol. OnlineDol not found in configuration for ' + this.reader.id);
      callback();
    }
  };

  Terminal.prototype.configureResponseDol = function configureResponseDol(callback) {
    if (this._configurationHasKey('ResponseDol')) {
      var apdu = createApduCommand(0xFF, 0x81, 0x07, 0x02);
      var config = this._getConfigurationTagsForKey('ResponseDol', defaultConfiguration.ResponseDol);
      apdu.appendBytes(new Buffer(config, 'hex'));
      this.writer.send(new _IngenicoCommand2.default('configure-response-dol', apdu), callback);
    } else {
      Log.warn('Skip configureResponseDol. ResponseDol not found in configuration for ' + this.reader.id);
      callback();
    }
  };

  Terminal.prototype.configureContactlessResponseDol = function configureContactlessResponseDol(callback) {
    if (this._configurationHasKey('ContactlessResponseDol')) {
      var apdu = createApduCommand(0xFF, 0x81, 0x07, 0x03);
      var config = this._getConfigurationTagsForKey('ContactlessResponseDol', defaultConfiguration.ContactlessResponseDol);
      apdu.appendBytes(new Buffer(config, 'hex'));
      this.writer.send(new _IngenicoCommand2.default('configure-contactless-response-dol', apdu), callback);
    } else {
      Log.warn('Skip configureContactlessResponseDol. ContactlessResponseDol not found in configuration for ' + this.reader.id);
      callback();
    }
  };

  Terminal.prototype.configureContactlessOnlineDol = function configureContactlessOnlineDol(callback) {
    if (this._configurationHasKey('ContactlessOnlineDol')) {
      var apdu = createApduCommand(0xFF, 0x81, 0x07, 0x04);
      var config = this._getConfigurationTagsForKey('ContactlessOnlineDol', defaultConfiguration.ContactlessOnlineDol);
      apdu.appendBytes(new Buffer(config, 'hex'));
      this.writer.send(new _IngenicoCommand2.default('configure-contactless-online-dol', apdu), callback);
    } else {
      Log.warn('Skip configureContactlessOnlineDol. ContactlessOnlineDol not found in configuration for ' + this.reader.id);
      callback();
    }
  };

  Terminal.prototype.clearAidList = function clearAidList(callback) {
    if (this._configurationHasKey('aidList')) {
      var apdu = createApduCommand(0xFF, 0x81, 0x01, 0x00);
      apdu.appendBytes(new Buffer('', 'hex'));
      this.writer.send(new _IngenicoCommand2.default('clear-aid-list', apdu), callback);
    } else {
      Log.warn('Skip clearAidList. aidList not found in configuration for ' + this.reader.id);
      callback();
    }
  };

  Terminal.prototype.configureContactAidList = function configureContactAidList(callback) {
    var config = this._getConfigurationTagsForKey('aidList', defaultConfiguration.aidList);
    if (config && config.Contact) {
      var aidData = this._getCommonAidData(config.Contact, getTlvData);
      var apdu = createApduCommand(0xFF, 0x81, 0x00, config.Contact.P2 || 0x03);
      apdu.appendBytes(new Buffer(aidData, 'hex'));
      this.writer.send(new _IngenicoCommand2.default('configure-contact-aid-list', apdu), callback);
    } else {
      Log.warn('Skip contact aid configuration, not found for ' + this.reader.id);
      callback();
    }
  };

  Terminal.prototype.configureContactlessAidList = function configureContactlessAidList(callback) {
    var config = this._getConfigurationTagsForKey('aidList', defaultConfiguration.aidList);
    if (config && config.Contactless) {
      var aidData = this._getCommonAidData(config.Contactless, getContactlessData);
      var apdu = createApduCommand(0xFF, 0x81, 0x00, config.Contactless.P2 || 0x02);
      apdu.appendBytes(new Buffer(aidData, 'hex'));
      this.writer.send(new _IngenicoCommand2.default('configure-contactless-aid-list', apdu), callback);
    } else {
      Log.warn('Skip contactless aid configuration, not found for ' + this.reader.id);
      callback();
    }
  };

  Terminal.prototype.clearPublicKeys = function clearPublicKeys(callback) {
    if (this._configurationHasKey('PublicKeys')) {
      var apdu = createApduCommand(0xFF, 0x81, 0x04, 0x00);
      apdu.appendBytes(new Buffer('', 'hex'));
      this.writer.send(new _IngenicoCommand2.default('clear-public-keys', apdu), callback);
    } else {
      Log.warn('Skip clearPublicKeys. PublicKeys not found in configuration for ' + this.reader.id);
      callback();
    }
  };

  Terminal.prototype.configurePublicKeys = function configurePublicKeys(progressCallback, callback) {
    var _this8 = this;

    if (this._configurationHasKey('PublicKeys')) {
      var config = this._getConfigurationTagsForKey('PublicKeys', defaultConfiguration.PublicKeys);
      var errorList = [];
      var publicKeyCmdList = [];

      var _loop = function _loop() {
        if (_isArray3) {
          if (_i3 >= _iterator3.length) return 'break';
          _ref3 = _iterator3[_i3++];
        } else {
          _i3 = _iterator3.next();
          if (_i3.done) return 'break';
          _ref3 = _i3.value;
        }

        var pKey = _ref3;

        Log.debug(function () {
          return 'Add key ' + JSON.stringify(pKey);
        });
        var pKeyData = pKey.RID + pKey.CAPublicKeyIndex + toHex(pKey.PublicKey.length / 2) + pKey.PublicKey + pKey.ExponentOfPublicKey + pKey.Checksum;
        var cmd = createApduCommand(0xFF, 0x81, 0x02, 0x00);
        cmd.appendBytes(new Buffer(pKeyData, 'hex'));
        publicKeyCmdList.push({ pKey: pKey, cmd: cmd, pKeyData: pKeyData });
      };

      for (var _iterator3 = config, _isArray3 = Array.isArray(_iterator3), _i3 = 0, _iterator3 = _isArray3 ? _iterator3 : _iterator3[Symbol.iterator]();;) {
        var _ref3;

        var _ret = _loop();

        if (_ret === 'break') break;
      }

      Log.debug(function () {
        return 'publicKeyCmdList length: ' + publicKeyCmdList.length;
      });
      _async2.default.eachSeries(publicKeyCmdList, function (cmdData, cb) {
        _this8.writer.send(new _IngenicoCommand2.default('configure-public-keys', cmdData.cmd), function (err, response) {
          progressCallback();
          Log.debug(function () {
            return 'configurePublicKeys key: ' + JSON.stringify(cmdData.pKey) + ' pKeyData: ' + cmdData.pKeyData + ' error: ' + err + ', response: ' + response;
          });
          if (err) {
            errorList.push(err);
          }
          if (cb) {
            cb(err);
          }
        });
      }, function () {
        _this8._callbackFromPublicKeyList(errorList, callback);
      });
    } else {
      Log.warn('Skip configurePublicKeys. PublicKeys not found in configuration for ' + this.reader.id);
      callback();
    }
  };

  Terminal.prototype._callbackFromPublicKeyList = function _callbackFromPublicKeyList(errorList, callback) {
    Log.debug('Done from _callbackFromPublicKeyList async.eachSeries');
    var callbackError = null;
    if (errorList.length > 0) {
      Log.warn('Error in configurePublicKeys for ' + this.reader.id);
      callbackError = errorList;
    }
    callback(callbackError, null);
  };

  Terminal.prototype._getCommonAidData = function _getCommonAidData(aidRoot, currentAidProcessor) {
    var aidData = '';
    var aid = aidRoot.AID;
    var noAid = 0;
    for (var key in aid) {
      if (Object.prototype.hasOwnProperty.call(aid, key)) {
        if (key.length > 0 && key.length % 2 === 0) {
          noAid += 1;
          var aidLen = toHex(key.length / 2);
          var curAid = aid[key];

          aidData += aidLen;
          aidData += key;
          aidData += curAid.TermAppVer;
          aidData += curAid.LowestAppVer;
          aidData += curAid.Priority;
          aidData += curAid.AppSelect;
          if (currentAidProcessor) {
            aidData += currentAidProcessor(curAid);
          }
        } else {
          Log.error('Invalid aid length ' + key.length + ' for aid \'' + key + '\' for ' + this.reader.id);
        }
      }
    }
    return toHex(noAid) + aidData;
  };

  Terminal.prototype.configureMagstripeDol = function configureMagstripeDol(callback) {
    if (this._configurationHasKey('MagstripeDol')) {
      var apdu = createApduCommand(0xFF, 0x81, 0x07, 0x05);
      var config = this._getConfigurationTagsForKey('MagstripeDol', defaultConfiguration.MagstripeDol);
      apdu.appendBytes(new Buffer(config, 'hex'));
      this.writer.send(new _IngenicoCommand2.default('configure-magstripe-dol', apdu), callback);
    } else {
      Log.warn('Skip configureMagstripeDol. MagstripeDol not found in configuration for ' + this.reader.id);
      callback();
    }
  };

  Terminal.prototype.configureAmountDol = function configureAmountDol(callback) {
    if (this._configurationHasKey('AmountDol')) {
      var apdu = createApduCommand(0xFF, 0x81, 0x07, 0x00);
      var config = this._getConfigurationTagsForKey('AmountDol', defaultConfiguration.AmountDol);
      apdu.appendBytes(new Buffer(config, 'hex'));
      this.writer.send(new _IngenicoCommand2.default('configure-amount-dol', apdu), callback);
    } else {
      Log.warn('Skip configureAmountDol. AmountDol not found in configuration for ' + this.reader.id);
      callback();
    }
  };

  Terminal.prototype.configureContactlessOptions = function configureContactlessOptions(callback) {
    if (this._configurationHasKey('ContactlessOptions')) {
      var configCmd = new _IngenicoCommand2.default('contactless-options');
      configCmd.rawHexCommand = this._getConfigurationTagsForKey('ContactlessOptions', defaultConfiguration.ContactlessOptions);
      this.writer.send(configCmd, callback);
    } else {
      Log.warn('Skip contactless options configuration, not found for ' + this.reader.id);
      callback();
    }
  };

  Terminal.prototype.sendConfigCommands = function sendConfigCommands(callback) {
    var _this9 = this;

    if (this._configurationHasKey('ReaderCommands')) {
      var configCmds = this._getConfigurationTagsForKey('ReaderCommands', defaultConfiguration.ReaderCommands);
      Log.debug(function () {
        return 'sendConfigCommands to ' + _this9.reader.id + ': ' + JSON.stringify(configCmds);
      });
      _async2.default.eachSeries(configCmds, function (configCmd, cb) {
        if (configCmd.Command) {
          var cmd = new _IngenicoCommand2.default(configCmd.Description);
          cmd.rawHexCommand = configCmd.Command;
          _this9.writer.send(cmd, cb);
        } else {
          cb();
        }
      }, callback);
    } else {
      Log.warn('ReaderCommands configuration, not found for ' + this.reader.id);
      callback();
    }
  };

  Terminal.prototype.stopTransaction = function stopTransaction(callback) {
    this.writer.deactivateReader(callback);
  };

  Terminal.prototype.postTransactionCleanup = function postTransactionCleanup(callback) {
    Log.debug('postTransactionCleanup');
    delete this._activeTxType;
    this.stopTransaction(callback);
  };

  Terminal.prototype.startTransaction = function startTransaction(txType, invoice, stFormFactors, callback) {
    var _this10 = this;

    var amount = _paypalInvoicing.Currency.toCents(invoice.currency, invoice.total);
    var currencyCode = getCurrencyIso(invoice.currency);
    this.invoice = invoice;
    this._activeTxType = txType;
    var ffSet = new Set(stFormFactors);
    var cmdP2 = 0x00;
    // disable interfaces
    if (!ffSet.has(_retailPaymentDevice.FormFactor.Chip)) {
      cmdP2 |= disableChip;
    }
    if (!ffSet.has(_retailPaymentDevice.FormFactor.EmvCertifiedContactless)) {
      cmdP2 |= disableEmvCertifiedContactless;
    }
    if (!ffSet.has(_retailPaymentDevice.FormFactor.MagneticCardSwipe)) {
      cmdP2 |= disableMagneticCardSwipe;
    }
    Log.debug(function () {
      return 'startTransaction P2 = ' + cmdP2 + ' for ' + _this10.reader.id;
    });
    var tlvList = buildTlvListForTx(txType, amount, currencyCode, ffSet);
    var apdu = createApduCommand(0xFF, 0x81, 0x10, cmdP2);
    apdu.appendBytes(tlvList.toBytes());

    if (ffSet.has(_retailPaymentDevice.FormFactor.Chip)) {
      apdu.appendBytes(new Buffer('DF15039F3704DF8229010100DF82000400010001DF82020100DF0B0101DF3A050000090220', 'hex'));
    } else {
      apdu.appendBytes(new Buffer('DF8229010100', 'hex'));
    }

    var cmd = new _IngenicoCommand2.default(_Writer2.default.cmdName.startTx, apdu);
    this.writer.send(cmd, function (err, response) {
      _this10._parseResponseForTxStart(err, response, callback);
    });
  };

  Terminal.prototype._parseResponseForTxStart = function _parseResponseForTxStart(err, response, callback) {
    var _this11 = this;

    var txType = this._activeTxType;
    Log.debug(function () {
      return 'Received response for startTransaction command. Error: ' + JSON.stringify(err) + ' rz: ' + response;
    });
    if (err) {
      callback(err);
      return;
    }

    var rzStatus = (0, _Parser.parseStatus)(response);
    Log.debug(function () {
      return 'Transaction response status from presenting card: 0x' + (rzStatus ? rzStatus.toString(16) : 'undefined');
    });

    if (TerminalStatus.AmountDol(rzStatus)) {
      Log.debug('Amount DOL detected in the transaction response... Will request for transaction data');
      if (this.reader.cardInsertedHandler) {
        Log.debug(function () {
          return 'Invoke CardInsertHandler for chip insert: ' + _this11.reader.context.id;
        });
        this.reader.cardInsertedHandler(new _retailPaymentDevice.CardInsertedHandler(function () {
          _this11.emit(_retailPaymentDevice.PaymentDevice.Event.cardPresented, null, _retailPaymentDevice.CardPresentEvent.insertDetected, _retailPaymentDevice.FormFactor.Chip);
          Log.debug(function () {
            return 'Continue CardDataRead: ' + _this11.reader.context.id;
          });
          _this11._sendTransactionData(function (e, rz) {
            _this11._parseResponseForTxComplete(e, rz, callback);
          });
        }));
      } else {
        Log.debug(function () {
          return 'Continue CardDataRead without cardInsertedHandler: ' + _this11.reader.context.id;
        });
        this._sendTransactionData(function (e, rz) {
          _this11._parseResponseForTxComplete(e, rz, callback);
        });
      }
      return;
    } else if (TerminalStatus.Contact.DecisionRequired(rzStatus)) {
      this.buildAppActivation = function () {
        var aidResp = (0, _Parser.parseCardData)(response);
        var dr = new _retailPaymentDevice.AvailableApplications(response);
        buildApps(dr, aidResp);
        Log.debug(function () {
          return 'dr : ' + JSON.stringify(dr);
        });
        callback(null, dr);
      };
      if (this.reader.cardInsertedHandler) {
        Log.debug(function () {
          return 'Invoke CardInsertHandler for multi-app: ' + _this11.reader.context.id;
        });
        this.reader.cardInsertedHandler(new _retailPaymentDevice.CardInsertedHandler(function () {
          Log.debug(function () {
            return 'Multi app card with cardInsertedHandler: ' + _this11.reader.context.id;
          });
          _this11.buildAppActivation();
        }));
      } else {
        Log.debug(function () {
          return 'Multi app card without cardInsertedHandler: ' + _this11.reader.context.id;
        });
        this.buildAppActivation();
      }
      return;
    } else if (TerminalStatus.Contactless.OfflineDecline(rzStatus) && txType !== TransactionTypeRefund) {
      Log.debug('Contactless Offline Decline.');
      callback(_retailPaymentDevice.deviceError.nfcNotAllowed);
      return;
    }

    if (!response) {
      callback(new Error('Invalid card data'));
      return;
    }

    var cardData = void 0;
    try {
      // TODO : For now, need to clean it up.
      var rz = response.replace('9F4100', '');
      cardData = (0, _Parser.parseCardData)(rz);
    } catch (x) {
      Log.error('Unable to parse card data: ' + x);
      callback(_retailPaymentDevice.deviceError.dataRetrievalFailed.withDevMessage(x.message));
      return;
    }
    callback(null, cardData);
  };

  Terminal.prototype._parseResponseForTxComplete = function _parseResponseForTxComplete(e, raw, callback) {
    var txType = this._activeTxType;
    delete this._activeTxType;
    if (e) {
      callback(e);
      return;
    }

    if (!raw) {
      callback(new Error('Invalid card data'));
      return;
    }

    try {
      var _ret2 = function () {
        // TODO : For now, need to clean it up.
        var rz = raw.replace('9F4100', '');
        var cardData = (0, _Parser.parseCardData)(rz);

        if (txType !== TransactionTypeRefund) {
          var decisionFound = false;
          for (var _iterator4 = cardData.apdu.tlvs.values, _isArray4 = Array.isArray(_iterator4), _i4 = 0, _iterator4 = _isArray4 ? _iterator4 : _iterator4[Symbol.iterator]();;) {
            var _ref4;

            if (_isArray4) {
              if (_i4 >= _iterator4.length) break;
              _ref4 = _iterator4[_i4++];
            } else {
              _i4 = _iterator4.next();
              if (_i4.done) break;
              _ref4 = _i4.value;
            }

            var _v = _ref4;

            if (_v.tagNumber === 0xdf31) {
              var _ret4 = function () {
                decisionFound = true;
                var status = _v.parse();
                if (status[0] === 0x00) {
                  Log.debug(function () {
                    return 'Decline for status: 0x' + cardData.getStatus().toString(16) + ' and tag (0xDF31) status  = 0x' + status.toString('hex');
                  });
                  callback(_retailPaymentDevice.deviceError.contactIssuer, cardData);
                  return {
                    v: {
                      v: void 0
                    }
                  };
                } else if (status[0] === 0x01) {
                  Log.debug(function () {
                    return 'online approval for status: 0x' + cardData.getStatus().toString(16) + ' and tag (0xDF31) status  = 0x' + status.toString('hex');
                  });
                } else {
                  Log.debug(function () {
                    return 'unexpected tag (0xDF31) status  = 0x' + status.toString('hex') + ' for status: 0x' + cardData.getStatus().toString(16);
                  });
                }
              }();

              if ((typeof _ret4 === 'undefined' ? 'undefined' : _typeof(_ret4)) === "object") return _ret4.v;
            }
          }

          if (!decisionFound) {
            for (var _iterator5 = cardData.apdu.tlvs.values, _isArray5 = Array.isArray(_iterator5), _i5 = 0, _iterator5 = _isArray5 ? _iterator5 : _iterator5[Symbol.iterator]();;) {
              var _ref5;

              if (_isArray5) {
                if (_i5 >= _iterator5.length) break;
                _ref5 = _iterator5[_i5++];
              } else {
                _i5 = _iterator5.next();
                if (_i5.done) break;
                _ref5 = _i5.value;
              }

              var v = _ref5;

              if (v.tagNumber === 0x9f27) {
                var _ret3 = function () {
                  var status = v.parse();
                  if (status[0] === 0x00) {
                    Log.debug(function () {
                      return 'Decline for status: 0x' + cardData.getStatus().toString(16) + ' and tag (0x9F27) status  = 0x' + status.toString('hex');
                    });
                    callback(_retailPaymentDevice.deviceError.contactIssuer, cardData);
                    return {
                      v: {
                        v: void 0
                      }
                    };
                  } else if (status[0] === 0x40) {
                    Log.debug(function () {
                      return 'online approval for status: 0x' + cardData.getStatus().toString(16) + ' and tag (0x9F27) status  = 0x' + status.toString('hex');
                    });
                  } else {
                    Log.debug(function () {
                      return 'unexpected tag (0x9F27) status  = 0x' + status.toString('hex') + ' for status: 0x' + cardData.getStatus().toString(16);
                    });
                  }
                }();

                if ((typeof _ret3 === 'undefined' ? 'undefined' : _typeof(_ret3)) === "object") return _ret3.v;
              }
            }
          }
        }

        callback(null, cardData);
      }();

      if ((typeof _ret2 === 'undefined' ? 'undefined' : _typeof(_ret2)) === "object") return _ret2.v;
    } catch (x) {
      Log.error('Unable to parse card data: ' + x);
      callback(x);
    }
  };

  Terminal.prototype.completeTransaction = function completeTransaction(authCode, callback) {
    var _this12 = this;

    var apdu = createApduCommand(0xFF, 0x81, 0x15, 0);
    var tlvData = new _tlvlib.TlvList();
    tlvData.add(0xDF39, new Buffer('01', 'hex'));
    apdu.appendBytes(tlvData.toBytes());
    apdu.appendHex(authCode.toString('hex'));
    this.writer.send(new _IngenicoCommand2.default('complete-transaction', apdu), function (err, rz) {
      _this12._parseResponseForTxComplete(err, rz, callback);
    });
  };

  Terminal.prototype._sendTransactionData = function _sendTransactionData(callback) {
    var apdu = createApduCommand(0xFF, 0x81, 0x13, 0);
    var tlvData = new _tlvlib.TlvList();
    tlvData.add(0x9F1B, new Buffer('00000000', 'hex'));
    tlvData.add(0xDF07, new Buffer('00000000', 'hex'));
    tlvData.add(0xDF08, new Buffer('00', 'hex'));
    tlvData.add(0xDF09, new Buffer('00', 'hex'));
    tlvData.add(0xDF03, new Buffer('00000000', 'hex'));
    tlvData.add(0xDF04, new Buffer('00000000', 'hex'));
    tlvData.add(0xDF05, new Buffer('00000000', 'hex'));
    if (this.invoice) {
      var amount = _paypalInvoicing.Currency.toCents(this.invoice.currency, this.invoice.total);
      Log.debug(function () {
        return 'in the TransactionData command, finalizing the invoice amount = ' + amount;
      });
      tlvData.add(_tlvlib.Tags.AmountAuthorized, _tlvlib.Tags.AmountAuthorized.format.toBytes(amount, 6)); // 0x9f02
    }
    apdu.appendBytes(tlvData.toBytes());
    this.writer.send(new _IngenicoCommand2.default('transaction-data', apdu), callback);
  };

  Terminal.prototype.getBatteryLevel = function getBatteryLevel(reuseIfQueued, callback) {
    var _this13 = this;

    // This command returns battery level/isCharging flag. So when the card reader is charging, we make a second call to retrieve battery information.
    var apduBatteryLevelOrChargingStatus = createApduCommand(0xFF, 0x88, 0, 0x01);
    var cmd = new _IngenicoCommand2.default('get-battery-or-charging-status', apduBatteryLevelOrChargingStatus);
    cmd.reuseIfQueued = reuseIfQueued;
    this.writer.send(cmd, function (err, hexBatteryOrChargingStatus) {
      if (err) {
        Log.error('Unable to retrieve battery level+charging status on ' + _this13.reader.id + ': ' + err);
        callback(err, null);
        return;
      }
      var level = parseInt(hexBatteryOrChargingStatus, 16);
      if (level === 255) {
        var apduBatteryLevelOnly = createApduCommand(0xFF, 0x88, 0, 0);
        apduBatteryLevelOnly.reuseIfQueued = reuseIfQueued;
        _this13.writer.send(new _IngenicoCommand2.default('get-battery-level', apduBatteryLevelOnly), function (errLevel, hexBatteryLevel) {
          if (errLevel) {
            Log.error('Unable to retrieve battery level on ' + _this13.reader.id + ': ' + err);
            callback(err, null);
            return;
          }
          level = parseInt(hexBatteryLevel, 16);
          Log.debug(function () {
            return 'charging battery level ' + level;
          });
          var batteryInfo = new _retailPaymentDevice.BatteryInfo(level, true, new Date(), _retailPaymentDevice.batteryStatus.charging);
          callback(null, batteryInfo);
        });
      } else {
        Log.debug(function () {
          return 'draining battery level ' + level;
        });
        var batteryInfo = new _retailPaymentDevice.BatteryInfo(level, false, new Date(), _retailPaymentDevice.batteryStatus.draining);
        callback(null, batteryInfo);
      }
    });
  };

  Terminal.prototype.selectApplication = function selectApplication(aid, callback) {
    var _this14 = this;

    Log.debug(function () {
      return 'Selected AID to be sent : ' + aid;
    });
    var apdu = createApduCommand(0xFF, 0x81, 0x12, 0);
    apdu.appendHex(aid);
    this.writer.send(new _IngenicoCommand2.default('select-app', apdu), function (err, rz) {
      _this14._parseResponseForTxStart(err, rz, callback);
    });
  };

  return Terminal;
}(_events.EventEmitter);

exports.default = Terminal;

}).call(this,require("buffer").Buffer)
},{"./IngenicoCommand":"/Users/aravidas/Documents/Git/retail-sdk/js/ingenico-emv/IngenicoCommand.js","./IngenicoTags":"/Users/aravidas/Documents/Git/retail-sdk/js/ingenico-emv/IngenicoTags.js","./Parser":"/Users/aravidas/Documents/Git/retail-sdk/js/ingenico-emv/Parser.js","./Writer":"/Users/aravidas/Documents/Git/retail-sdk/js/ingenico-emv/Writer.js","./eventType":"/Users/aravidas/Documents/Git/retail-sdk/js/ingenico-emv/eventType.js","./ingenico_config.json":"/Users/aravidas/Documents/Git/retail-sdk/js/ingenico-emv/ingenico_config.json","async":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/async/lib/async.js","buffer":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/buffer/index.js","events":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/events/events.js","manticore":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore/browser.js","manticore-log":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-log/index.js","manticore-util":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-util/build/index.js","moment":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/moment/moment.js","paypal-invoicing":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/index.js","retail-payment-device":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/index.js","tlvlib":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/tlvlib/build/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/js/ingenico-emv/TransactionDataResponse.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

var _tlvlib = require('tlvlib');

var _retailPaymentDevice = require('retail-payment-device');

var _manticoreLog = require('manticore-log');

var _manticoreLog2 = _interopRequireDefault(_manticoreLog);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (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 } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var Log = (0, _manticoreLog2.default)('ingenico.TransactionDataResponse');

var TransactionDataResponse = function (_CardReaderResponse) {
  _inherits(TransactionDataResponse, _CardReaderResponse);

  function TransactionDataResponse(status, dataBuffer, unsolicited) {
    _classCallCheck(this, TransactionDataResponse);

    var _this = _possibleConstructorReturn(this, _CardReaderResponse.call(this, dataBuffer, dataBuffer.length, unsolicited));

    _this.status = status;
    var tlvList = new _tlvlib.TlvList(dataBuffer);
    try {
      _this.apdu = new _tlvlib.ApduResponse(tlvList);
      // parsing from tlvList creates duplicate tags, so replace the raw data
      _this.apdu.data = dataBuffer;
      Log.debug(function () {
        return 'Ingenico response template: ' + (_this.apdu.template ? _this.apdu.template.toString(16) : '<empty>') + ' SW1: ' + _this.apdu.sw1.toString(16) + ' SW2: ' + _this.apdu.sw2.toString(16) + ' Raw: ' + dataBuffer.toString('hex');
      });
    } catch (x) {
      Log.error('Failed to parse APDU from raw response: ' + dataBuffer.toString('hex') + '\nError: ' + x.message);
    }
    return _this;
  }

  TransactionDataResponse.prototype.getStatus = function getStatus() {
    return this.status;
  };

  return TransactionDataResponse;
}(_retailPaymentDevice.CardReaderResponse);

exports.default = TransactionDataResponse;

},{"manticore-log":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-log/index.js","retail-payment-device":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/index.js","tlvlib":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/tlvlib/build/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/js/ingenico-emv/Writer.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };

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; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

var _machina = require('machina');

var _machina2 = _interopRequireDefault(_machina);

var _manticoreLog = require('manticore-log');

var _manticoreLog2 = _interopRequireDefault(_manticoreLog);

var _events = require('events');

var _manticore = require('manticore');

var _manticore2 = _interopRequireDefault(_manticore);

var _retailPaymentDevice = require('retail-payment-device');

var _IngenicoCommand = require('./IngenicoCommand');

var _IngenicoCommand2 = _interopRequireDefault(_IngenicoCommand);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

var Log = (0, _manticoreLog2.default)('ingenico.writer');

var maxRetry = 3;
var msRetryPause = 300;
var errCardReaderBusy = 'CardReaderBusy';

var Writer = function () {
  function Writer(device) {
    var _this = this;

    _classCallCheck(this, Writer);

    this.device = device;
    this.channel = new _machina2.default.Fsm({
      namespace: 'ingenico-command-queue',
      initialState: 'idle',
      initialize: function initialize() {
        _this._queue = [];
        _this._isAwaiting = function () {
          return _this._queue.length > 0 && _this._queue[0].awaiting;
        };
        _this._isAwaitingOn = function (cmdName) {
          return _this._queue.length > 0 && _this._queue[0].awaiting && _this._queue[0].name === cmdName;
        };
        _this._queueToString = function () {
          return 'Q = [' + (_this._queue.length ? _this._queue.map(function (c) {
            return '' + (c.awaiting ? '<AWAIT>' : '') + c.name + '-' + c.id;
          }).join(',') : '<none>') + ']';
        };
        _this._addCommandToQueue = function (cmd) {
          if (cmd.reuseIfQueued) {
            var _loop = function _loop() {
              if (_isArray) {
                if (_i >= _iterator.length) return 'break';
                _ref = _iterator[_i++];
              } else {
                _i = _iterator.next();
                if (_i.done) return 'break';
                _ref = _i.value;
              }

              var qCmd = _ref;

              if (qCmd.name === cmd.name) {
                var _qCmd$callbacks;

                (_qCmd$callbacks = qCmd.callbacks).push.apply(_qCmd$callbacks, _toConsumableArray(cmd.callbacks));
                Log.debug(function () {
                  return '[' + _this.channel.state + '] =*= Will not send ' + cmd.nameWithId + '.. callback will be added to ' + qCmd.id + '. ' + _this._queueToString();
                });
                return {
                  v: void 0
                };
              }
            };

            _loop2: for (var _iterator = _this._queue, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
              var _ref;

              var _ret = _loop();

              switch (_ret) {
                case 'break':
                  break _loop2;

                default:
                  if ((typeof _ret === 'undefined' ? 'undefined' : _typeof(_ret)) === "object") return _ret.v;
              }
            }
          }
          if (cmd.name === Writer.cmdName.startTx) {
            if (_this._isAwaitingOn(cmd.name)) {
              Log.warn(function () {
                return '[' + _this.channel.state + '] Discarding ' + cmd + ' as device is currently active with command ' + _this._queue[0];
              });
              return;
            }

            var _loop3 = function _loop3(i) {
              if (_this._queue[i].name === cmd.name) {
                Log.debug(function () {
                  return '[' + _this.channel.state + '] ' + cmd.nameWithId + ' will replace existing command ' + _this._queue[i].nameWithId + ' at position ' + i;
                });
                _this._queue[i] = cmd;
                return {
                  v: void 0
                };
              }
            };

            for (var i = 1; i < _this._queue.length; i++) {
              var _ret2 = _loop3(i);

              if ((typeof _ret2 === 'undefined' ? 'undefined' : _typeof(_ret2)) === "object") return _ret2.v;
            }
          }
          if (cmd.name === Writer.cmdName.stopTx) {
            if (_this._isAwaitingOn(cmd.name)) {
              Log.debug(function () {
                return '[' + _this.channel.state + '] Discarding ' + cmd.nameWithId + ' as we are already awaiting on a stop transaction ' + _this._queue[0].nameWithId;
              });
              _this._queue[0].callbacks.push(cmd.callbacks[0]);
              return;
            }

            // Remove all non awaiting start transaction commands

            var _loop4 = function _loop4(i) {
              var qCmd = _this._queue[i];
              if (qCmd.name === Writer.cmdName.startTx) {
                Log.debug(function () {
                  return '[' + _this.channel.state + '] Discarding unsent ' + qCmd.nameWithId + ' in response to ' + cmd.nameWithId;
                });
                _this._queue.splice(i, 1);
              }
            };

            for (var i = _this._queue.length - 1; i > 0; i--) {
              _loop4(i);
            }

            // Merge this stop transaction with ones on the queue
            var callBacks = [];
            for (var i = _this._queue.length - 1; i >= 0; i--) {
              var _qCmd = _this._queue[i];
              if (_qCmd.name === Writer.cmdName.stopTx) {
                _this._queue.splice(i, 1);
                callBacks = callBacks.concat(_qCmd.callbacks);
              }
            }

            if (callBacks.length > 0) {
              Log.debug(function () {
                return '[' + _this.channel.state + '] ' + callBacks.length + ' callbacks of unsent \'' + cmd.name + '\' command will be added to ' + cmd.nameWithId;
              });
            }
            callBacks = callBacks.concat(cmd.callbacks);
            cmd.callbacks = callBacks;

            if (!_this._isAwaiting()) {
              _this._queue.unshift(cmd);
            } else {
              _this._queue.splice(1, 0, cmd);
            }
            Log.debug(function () {
              return '[' + _this.channel.state + '][' + cmd.nameWithId + '] Added to top of Queue. ' + _this._queueToString();
            });
            return;
          }

          Log.debug(function () {
            return '[' + _this.channel.state + '] Enqueue command ' + cmd.nameWithId + '. ' + _this._queueToString();
          });
          _this._queue.push(cmd);
        };
        _this._dequeueAndInvokeCallback = function (err, rz, cb) {
          var cmd = _this._queue.shift();
          if (err && err.code === errCardReaderBusy) {
            Log.warn('[' + _this.channel.state + '] <==== CardReaderBusy RESPONSE received ' + cmd.nameWithId);
            if (cmd.sendAttempt > maxRetry) {
              Log.error('[' + _this.channel.state + '] <==== RESPONSE indicates card reader is busy and already re-tried ' + cmd.sendAttempt + ' times. Will error out');
            } else {
              Log.warn('[' + _this.channel.state + '] <==== RESPONSE indicates card reader is busy. Will retry ' + cmd.nameWithId + ' in ' + msRetryPause + 'ms. Attempts so far: ' + cmd.sendAttempt + '/' + maxRetry);
              _this._queue.unshift(cmd);
              _manticore2.default.setTimeout(function () {
                Log.debug(function () {
                  return '[' + _this.channel.state + '] Transitioning to \'process\' state after the ' + msRetryPause + ' timeout';
                });
                cb('sendCommand');
              }, msRetryPause);
              return; // return here so that we do not get back to idle state immediately
            }
          } else if (err && err === _retailPaymentDevice.deviceError.deviceNotConnected) {
            Log.debug(function () {
              return '[' + _this.channel.state + '] <==== RESPONSE Device not connected! Will error out ' + cmd.nameWithId;
            });
          } else if (err && err.code === 'CommandCancelledUponReceiptOfACancelWaitCommand') {
            Log.debug(function () {
              return '[' + _this.channel.state + '] <==== Received expected error: \'' + JSON.stringify(err) + '\' from cancelling last command';
            });
          } else {
            Log[err ? 'error' : 'debug'](function () {
              return '[' + _this.channel.state + '] <==== RESPONSE ' + (err ? 'Error: ' + JSON.stringify(err) + ' ' : '') + 'will be handled by ' + cmd.nameWithId + ' CallbackCount: ' + cmd.callbacks.length + '. rz: ' + JSON.stringify(rz);
            });
          }
          _this.device.lastError = err;

          var _loop5 = function _loop5() {
            if (_isArray2) {
              if (_i2 >= _iterator2.length) return 'break';
              _ref2 = _iterator2[_i2++];
            } else {
              _i2 = _iterator2.next();
              if (_i2.done) return 'break';
              _ref2 = _i2.value;
            }

            var callback = _ref2;

            if (callback) {
              // Invoking the callback asynchronously in order to avoid state transitions from within the callback
              _manticore2.default.setTimeout(function () {
                try {
                  callback(err, rz);
                } catch (e) {
                  Log.error('[' + _this.channel.state + '] Error from invoking callback for command ' + cmd.nameWithId + ' with response ' + rz + '\ncb: ' + callback + ' \ne stack: ' + e.stack + ' :\ne  message : ' + (e.msg || e.message));
                }
              }, 0);
            }
          };

          for (var _iterator2 = cmd.callbacks, _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) {
            var _ref2;

            var _ret4 = _loop5();

            if (_ret4 === 'break') break;
          }
          cb('idle');
        };
        _this._deviceRemovedHandler = function () {
          Writer.Events.emit('response', _retailPaymentDevice.deviceError.deviceNotConnected);
        };
        _this._deviceResponseHandler = function (err, rz) {
          _this._dequeueAndInvokeCallback(err, rz, function (transitionTo) {
            _this._removeListeners();
            _this.channel.transition(transitionTo);
          });
        };
        _this._removeListeners = function () {
          Writer.Events.removeListener('response', _this._deviceResponseHandler);
          _this.device.removeListener(_retailPaymentDevice.PaymentDevice.Event.disconnected, _this._deviceRemovedHandler);
          _this.device.removeListener(_retailPaymentDevice.PaymentDevice.Event.deviceRemoved, _this._deviceRemovedHandler);
        };
        Log.debug(function () {
          return 'Command channel queue initialized for ' + _this.device.id;
        });
      },
      states: {
        idle: {
          _onEnter: function _onEnter() {
            Log.debug(function () {
              return '[idle]-->enter Queue size: ' + _this._queue.length;
            });
            if (_this._queue.length > 0) {
              _this.channel.transition('sendCommand');
            }
          },
          enqueue: function enqueue(cmd) {
            _this._addCommandToQueue(cmd);
            _this.channel.transition('sendCommand');
          }
        },
        sendCommand: {
          _onEnter: function _onEnter() {
            Log.debug(function () {
              return '[' + _this.channel.state + ']-->enter. ' + _this._queueToString();
            });
            if (!_this._queue.length) {
              Log.debug(function () {
                return '[' + _this.channel.state + '] No commands to send, Transitioning to \'idle\'';
              });
              _this.channel.transition('idle');
              return;
            }
            _this.channel.handle('send');
          },
          send: function send() {
            if (!_this.device.isConnected()) {
              _this._dequeueAndInvokeCallback(_retailPaymentDevice.deviceError.deviceNotConnected, null, function (transitionTo) {
                _this.channel.transition(transitionTo);
              });
              return;
            }

            // Push the command to card reader
            var cmd = _this._queue[0];
            var cb = function cb(err, rz) {
              _manticore2.default.setTimeout(function () {
                Writer.Events.emit('response', err, rz);
              }, 0);
            };
            _this.device.lastError = null;
            cmd.awaiting = true;
            cmd.sendAttempt += 1;
            if (cmd.nativeCommand) {
              Log.debug(function () {
                return '[' + _this.channel.state + '] ====> Sending native command ' + cmd.nameWithId + '. CallbackCount ' + cmd.callbacks.length;
              });
              _this.device.native[cmd.name](cmd.nativeCommand, cb);
            } else {
              var apduHex = cmd.apduCommand ? cmd.apduCommand.toBytes().toString('hex') : cmd.rawHexCommand;
              Log.debug(function () {
                return '[' + _this.channel.state + '] ====> Sending ' + cmd.nameWithId + ':' + apduHex + '. CallbackCount ' + cmd.callbacks.length;
              });
              _this.device.native.send(cmd.name + ':' + cmd.id, apduHex, cb);
            }

            if (cmd.name === Writer.cmdName.startTx) {
              _this.channel.transition('waitForCardData', cmd);
            } else {
              _this.channel.transition('wait', cmd);
            }
          },
          enqueue: function enqueue(cmd) {
            _this._addCommandToQueue(cmd);
          }
        },
        wait: {
          _onEnter: function _onEnter() {
            Log.debug(function () {
              return '[' + _this.channel.state + ']-->enter. ' + _this._queueToString();
            });
            _this.channel.handle('awaitResponse');
          },
          awaitResponse: function awaitResponse() {
            Writer.Events.once('response', _this._deviceResponseHandler);
            _this.device.once(_retailPaymentDevice.PaymentDevice.Event.disconnected, _this._deviceRemovedHandler);
            _this.device.once(_retailPaymentDevice.PaymentDevice.Event.deviceRemoved, _this._deviceRemovedHandler);
          },
          enqueue: function enqueue(cmd) {
            _this._addCommandToQueue(cmd);
          }
        },
        waitForCardData: {
          _onEnter: function _onEnter(cmd) {
            Log.debug(function () {
              return '[' + _this.channel.state + ']-->enter. ' + _this._queueToString();
            });
            _this.channel.handle('awaitResponse', cmd);
          },
          awaitResponse: function awaitResponse() {
            Writer.Events.once('response', _this._deviceResponseHandler);
            _this.device.once(_retailPaymentDevice.PaymentDevice.Event.disconnected, _this._deviceRemovedHandler);
            _this.device.once(_retailPaymentDevice.PaymentDevice.Event.deviceRemoved, _this._deviceRemovedHandler);
          },
          cancelLastCommand: function cancelLastCommand() {
            _this._removeListeners();
            var discard = _this._queue.shift();
            var cancelCommand = new _IngenicoCommand2.default('cancel-last-command');
            cancelCommand.rawHexCommand = 'ff0b000000';
            _this._queue.unshift(cancelCommand);
            Log.debug(function () {
              return '[' + _this.channel.state + '][cancelLastCommand] Pushed ' + cancelCommand.nameWithId + ' to top of queue and abandoned ' + (discard ? '' + discard.nameWithId : '<none>');
            });
            _this.channel.transition('sendCommand');
          },
          enqueue: function enqueue(cmd) {
            _this._addCommandToQueue(cmd);
          }
        }
      },
      enqueue: function enqueue(cmd) {
        _this.channel.handle('enqueue', cmd);
      },
      deactivateReader: function deactivateReader(callback) {
        Log.debug(function () {
          return '[' + _this.channel.state + '] ***** Reader de-activate requested. ' + _this._queueToString();
        });
        _this.channel.handle('cancelLastCommand');
        var stopTxCommand = new _IngenicoCommand2.default(Writer.cmdName.stopTx);
        stopTxCommand.rawHexCommand = 'FF811600000000';
        stopTxCommand.callbacks.push(callback);
        _this.channel.handle('enqueue', stopTxCommand);
      }
    });
  }

  Writer.prototype.send = function send(ingenicoCommand, callback) {
    if (ingenicoCommand instanceof _IngenicoCommand2.default) {
      ingenicoCommand.callbacks.push(callback);
      this.channel.enqueue(ingenicoCommand);
    } else {
      Log.error('Received command ' + ingenicoCommand + ' that is not of type IngenicoCommand');
      if (callback) {
        callback(_retailPaymentDevice.deviceError.unexpectedRequest);
      }
    }
  };

  Writer.prototype.clear = function clear() {
    Log.info('Reset queue of size : ' + this._queue.length);
    this._queue = [];
    this._removeListeners();
  };

  Writer.prototype.deactivateReader = function deactivateReader(callback) {
    this.channel.deactivateReader(callback);
  };

  _createClass(Writer, [{
    key: 'commandQueue',
    get: function get() {
      return this._queue;
    }
  }]);

  return Writer;
}();

exports.default = Writer;


Writer.cmdName = {
  stopTx: 'stop-transaction',
  startTx: 'start-transaction'
};

Writer.Events = new _events.EventEmitter();

},{"./IngenicoCommand":"/Users/aravidas/Documents/Git/retail-sdk/js/ingenico-emv/IngenicoCommand.js","events":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/events/events.js","machina":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/machina/lib/machina.js","manticore":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore/browser.js","manticore-log":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-log/index.js","retail-payment-device":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/js/ingenico-emv/eventType.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;
var eventType = {
  cardInserted: 'cardInserted',
  cardRemoved: 'cardRemoved',
  cardSwiped: 'cardSwiped',
  cardTapped: 'cardTapped',
  commandSent: 'commandSent'
};

exports.default = eventType;

},{}],"/Users/aravidas/Documents/Git/retail-sdk/js/ingenico-emv/index.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

var _IngenicoDevice = require('./IngenicoDevice');

Object.defineProperty(exports, 'default', {
  enumerable: true,
  get: function get() {
    return _interopRequireDefault(_IngenicoDevice).default;
  }
});

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

},{"./IngenicoDevice":"/Users/aravidas/Documents/Git/retail-sdk/js/ingenico-emv/IngenicoDevice.js"}],"/Users/aravidas/Documents/Git/retail-sdk/js/ingenico-emv/ingenicoReaderError.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;
var ingenicoReaderError = {
  invalidChip: 'C009',
  invalidChipSwipeCard: 'C00A',
  pleaseInsertCard: 'C00C',
  multipleContactlessCardsDetected: 'C00E',
  pleaseSeePhone: 'C01A',
  contactlessInterfaceFailedTryContact: 'C017',
  transactionCancelled: 'CommandCancelledUponReceiptOfACancelWaitCommand',
  mandatoryEMVTLVDataMissing: 'MandatoryEMVTLVDataMissing',
  noMutuallySupportedAIDs: 'NoMutuallySupportedAIDs',
  applicationBlocked: 'ApplicationBlocked',
  cardReaderNotConnected: 'CardReaderNotConnected',
  cardReaderConnectionLost: 'ConnectionLost',
  batteryTooLowError: 'BatteryTooLowError'
};

exports.default = ingenicoReaderError;

},{}],"/Users/aravidas/Documents/Git/retail-sdk/js/ingenico-emv/ingenico_config.json":[function(require,module,exports){
module.exports={
  "AmountDol": "9F02065F25035F24034F1050109F121087019F36025A0A5F3401950557139B02",
  "OnlineDol": "5F24039F09025F30029F02069F03069F26084F10820250109F36029F07029F34039F270184109F1E089F10205F28025F34019F39019F06109F33039F1A029F350195059F53015F2A029A039F41049B029C019F37045713DF822520DF8223F0",
  "ResponseDol": "5F24039F09029F02069F03069F26084F10820250109F36029F07029F34039F270184109F1E089F10205F28025F34019F39019F06109F33039F1A029F350195059F53015F2A029A039F41049B029C019F37045713DF822520DF8223F0",
  "ContactlessResponseDol": "9F63069F64019F62069F65029F7C209F6B139F67019F66049F60028202841095059A039C015F34019F02069F03069F09029F10209F1A029F1E089F26089F27019F33039F34039F35019F36029F37049F41049F53019F6E205F24039F61025F201ADF31015713DF822520DF8223F0DF6F02DFDF413EDFDF4227",
  "ContactlessOnlineDol": "9F63069F64019F62069F65029F7C209F6B139F67019F66049F60029F07029F39019F06105F28025F30024F1050108202841095059A039C015F2A025F34019F02069F03069F09029F10209F1A029F1E089F26089F27019F33039F34039F35019F36029F37049F41049F53019F6E205F24039F61025F201A5713DF822520DF8223F0DF6F02DFDF413EDFDF4227",
  "MagstripeDol": "DF822520DF8223F0DF82564CDF82574CDF82584CDF82604C00",
  "ContactlessOptions": "ff8124000002df9d00",
  "ReaderCommands":
  [
    {
      "Description": "buzzerCmd",
      "Command": "ff880700010200"
    },
    {
      "Description": "indefiniteWait",
      "Command": "FF8106000006FFFF656e010100"
    },
    {
      "Description": "savingModeCmd",
      "Command": "ff88040002000a00"
    },
    {
      "Description": "shutDownTimeoutCmd",
      "Command": "ff88040102007800"
    }
  ],
  "aidList": {
    "Contact": {
      "AID": {
        "A0000000031010": {
          "TermAppVer": "0096",
          "LowestAppVer": "0096",
          "Priority": "00",
          "AppSelect": "01",
          "tlvData": {
            "DF03": "DC4000A800",
            "DF04": "0010000000",
            "DF05": "DC4004F800",
            "9F01": "000000000000",
            "9F40": "600000A001",
            "9F35": "22",
            "9F33": "6028C8"
          }
        },
        "A0000000032010": {
          "TermAppVer": "0096",
          "LowestAppVer": "0096",
          "Priority": "00",
          "AppSelect": "01",
          "tlvData": {
            "DF03": "DC4000A800",
            "DF04": "0010000000",
            "DF05": "DC4004F800",
            "9F01": "000000000000",
            "9F40": "600000A001",
            "9F35": "22",
            "9F33": "6028C8"
          }
        },
        "A0000000041010": {
          "TermAppVer": "0002",
          "LowestAppVer": "0002",
          "Priority": "00",
          "AppSelect": "01",
          "tlvData": {
            "DF03": "FE5080F800",
            "DF04": "0000000000",
            "DF05": "FE5080F800",
            "9F01": "000000000000",
            "9F40": "600000A001",
            "9F35": "22",
            "9F33": "6028C8"
          }
        },
        "A0000001523010": {
          "TermAppVer": "0001",
          "LowestAppVer": "0001",
          "Priority": "00",
          "AppSelect": "01",
          "tlvData": {
            "DF03": "DC00002000",
            "DF04": "0010000000",
            "DF05": "FCE09CF800",
            "9F01": "000000000000",
            "9F40": "600000A001",
            "9F35": "22",
            "9F33": "6028C8"
          }
        },
        "A00000002501": {
          "TermAppVer": "0001",
          "LowestAppVer": "0001",
          "Priority": "00",
          "AppSelect": "01",
          "tlvData": {
            "DF03": "C800000000",
            "DF04": "0000000000",
            "DF05": "C800000000",
            "9F01": "000000000000",
            "9F40": "600000A001",
            "9F35": "22",
            "9F33": "6028C8"
          }
        }
      }
    },
    "Contactless": {
      "AID": {
        "A0000000031010": {
          "TermAppVer": "0096",
          "LowestAppVer": "0096",
          "Priority": "00",
          "AppSelect": "01",
          "FloorLimit": "00000000",
          "CVMLimit": "00001388",
          "TxnLimit": "000F4240",
          "TermCaps": "6028C8",
          "tlvData": {
            "DF03": "0000000000",
            "DF04": "0000000000",
            "DF05": "0000000000",
            "DF07": "00000000",
            "DF08": "00",
            "DF09": "00",
            "DF15": "9F37049F02065F2A029F6905",
            "DF18": "9F0206",
            "9F40": "600000A001",
            "9F6D": "0001",
            "9F35": "22"
          }
        },
        "A0000000032010": {
          "TermAppVer": "0096",
          "LowestAppVer": "0096",
          "Priority": "00",
          "AppSelect": "01",
          "FloorLimit": "00000000",
          "CVMLimit": "00001388",
          "TxnLimit": "000F4240",
          "TermCaps": "6028C8",
          "tlvData": {
            "DF03": "0000000000",
            "DF04": "0000000000",
            "DF05": "0000000000",
            "DF07": "00000000",
            "DF08": "00",
            "DF09": "00",
            "DF15": "9F37049F02065F2A029F6905",
            "DF18": "9F0206",
            "9F40": "600000A001",
            "9F6D": "0001",
            "9F35": "22"
          }
        },
        "A0000000041010": {
          "TermAppVer": "0002",
          "LowestAppVer": "0002",
          "Priority": "00",
          "AppSelect": "01",
          "FloorLimit": "00000000",
          "CVMLimit": "00001388",
          "TxnLimit": "000F4240",
          "TermCaps": "6028C8",
          "tlvData": {
            "DF07": "00000000",
            "DF08": "00",
            "DF09": "00",
            "DF03": "FC50808800",
            "DF04": "0000000000",
            "DF05": "FC50808800",
            "9F40": "600000A001",
            "9F6D": "0001",
            "9F35": "22",
            "9F1D": "2C28000000000000",
            "DF15": "9F37049F02065F2A029F6905",
            "DF18": "9F02065F2A029A039C0195059F3704",
            "DF54": "9F6A04",
            "DF811E": "10",
            "DF811B": "20",
            "DF812C": "00",
            "DF8118": "20",
            "DF8119": "08",
            "DF8124": "000001000000",
            "DF8125": "000001000000",
            "DF8126": "000000005000",
            "DF811C": "003C",
            "DF811D": "01"
          }
        },
        "A0000001523010": {
          "TermAppVer": "0100",
          "LowestAppVer": "0100",
          "Priority": "00",
          "AppSelect": "01",
          "FloorLimit": "00000000",
          "CVMLimit": "00001388",
          "TxnLimit": "000F4240",
          "TermCaps": "6028C8",
          "tlvData": {
            "DF03": "0000000000",
            "DF04": "0000000000",
            "DF05": "0000000000",
            "DF07": "00000000",
            "DF08": "00",
            "DF09": "00",
            "DF15": "9F37049F02065F2A029F6905",
            "9F40": "600000A001",
            "9F6D": "0001",
            "9F35": "22"
          }
        },
        "A0000003241010": {
          "TermAppVer": "0100",
          "LowestAppVer": "0100",
          "Priority": "00",
          "AppSelect": "01",
          "FloorLimit": "00000000",
          "CVMLimit": "00001388",
          "TxnLimit": "000F4240",
          "TermCaps": "6028C8",
          "tlvData": {
            "DF03": "0000000000",
            "DF04": "0000000000",
            "DF05": "0000000000",
            "DF07": "00000000",
            "DF08": "00",
            "DF09": "00",
            "DF15": "9F37049F02065F2A029F6905",
            "9F6D": "0001",
            "9F40": "600000A001",
            "9F35": "22"
          }
        },
        "A00000002501": {
          "TermAppVer": "0001",
          "LowestAppVer": "0001",
          "Priority": "00",
          "AppSelect": "01",
          "FloorLimit": "00000000",
          "CVMLimit": "00001388",
          "TxnLimit": "000F4240",
          "TermCaps": "6028C8",
          "tlvData": {
            "DF07": "00000000",
            "DF08": "00",
            "DF09": "00",
            "DF03": "DC50840000",
            "DF04": "0000000000",
            "DF05": "C400000000",
            "9F40": "600000A001",
            "DF15": "9F37049F02065F2A029F6905",
            "DF44": "003C",
            "9F6D": "0001",
            "9F35": "22",
            "9F6E": "D8A00000"
          }
        }
      }
    }
  }
}

},{}],"/Users/aravidas/Documents/Git/retail-sdk/js/paymentDevice/CardReaderDisplayController.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

var _manticoreLog = require('manticore-log');

var _manticoreLog2 = _interopRequireDefault(_manticoreLog);

var _retailPaymentDevice = require('retail-payment-device');

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

var Log = (0, _manticoreLog2.default)('paymentDevice.displayController');

var CardReaderDisplayController = function () {
  function CardReaderDisplayController() {
    _classCallCheck(this, CardReaderDisplayController);

    this._lastDisplayCommand = {};
  }

  /**
   * Updates the card reader display only when the provided priority is greater than the priority of the most recent
   * display command that was pushed to the card reader
   * @param {int} priority
   * @param {PaymentDevice} cardReader
   * @param {object} displayArgs
   * @param {function} [cb]
   */


  CardReaderDisplayController.prototype.display = function display(priority, cardReader, displayArgs, cb) {
    var _this = this;

    var needsUpdate = false;
    var lastCommand = this._lastDisplayCommand[cardReader.id];
    if (!lastCommand) {
      Log.debug(function () {
        return 'Will push ' + displayArgs.id + ' to ' + cardReader.id + ' as no previous commands were found';
      });

      // If the device disconnects at a later point, clear the prevailing state during the disconnect
      cardReader.once(_retailPaymentDevice.PaymentDevice.Event.disconnected, function () {
        return delete _this._lastDisplayCommand[cardReader.id];
      });
      needsUpdate = true;
    } else if (lastCommand.priority > priority) {
      Log.debug(function () {
        return 'Will NOT push ' + priority + ':' + displayArgs.id + ' to ' + cardReader.id + ' as last pushed command ' + lastCommand.priority + ':' + lastCommand.displayArgs.id + ' was higher in priority';
      });
      needsUpdate = false;
    } else {
      Log.debug(function () {
        return 'Will push ' + priority + ':' + displayArgs.id + ' to ' + cardReader.id + ' as last pushed command ' + lastCommand.priority + ':' + lastCommand.displayArgs.id + ' was lower in priority';
      });
      needsUpdate = true;
    }

    if (needsUpdate) {
      this._lastDisplayCommand[cardReader.id] = {
        priority: priority,
        displayArgs: displayArgs
      };
      cardReader.display(displayArgs, function (err) {
        if (err) {
          delete _this._lastDisplayCommand[cardReader.id];
        }
        if (cb) {
          cb(err);
        }
      });
    }
  };

  CardReaderDisplayController.prototype.resetAll = function resetAll() {
    this._lastDisplayCommand = {};
  };

  return CardReaderDisplayController;
}();

var displayController = new CardReaderDisplayController();
exports.default = displayController;

},{"manticore-log":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-log/index.js","retail-payment-device":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/js/paymentDevice/CardReaderScanAndDiscoverOptions.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

var _events = require('events');

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (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 } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

/**
 * Card Reader Scan and Discover options to send it over to native side
 * @class
 */
var CardReaderScanAndDiscoverOptions = function (_EventEmitter) {
  _inherits(CardReaderScanAndDiscoverOptions, _EventEmitter);

  function CardReaderScanAndDiscoverOptions() {
    _classCallCheck(this, CardReaderScanAndDiscoverOptions);

    return _possibleConstructorReturn(this, _EventEmitter.apply(this, arguments));
  }

  /**
   * Select to the card reader with this id
   * @param {string} id the id of the card reader to be connected
   */
  CardReaderScanAndDiscoverOptions.prototype.connectToCardReader = function connectToCardReader(id) {} // eslint-disable-line no-unused-vars


  // TODO This should definitely change... We should not expect the integrating an listener to notify the SDK after adding listeners. This breaks how event emitter works on other parts of SDK
  /**
   * let the DeviceScanner know after the observers added
   */
  ;

  CardReaderScanAndDiscoverOptions.prototype.onAddedObserver = function onAddedObserver() {// eslint-disable-line no-unused-vars
  };

  return CardReaderScanAndDiscoverOptions;
}(_events.EventEmitter);

/**
 * A Card Reader has been discovered.
 * @event CardReaderScanAndDiscoverOptions#onCardReaderDiscovered
 * @param {DiscoveredCardReader} device The device info that has been discovered
 */

/**
 * The procedure for scaning and discovering card readers is ended.
 * @event CardReaderScanAndDiscoverOptions#onScanComplete
 * @param {error} error Error from Scan and Discover
 */

/**
 * A PaymentDevice has been discovered. For further events, such as device readiness, removal or the
 * need for a software upgrade, your application should subscribe to the relevant events on the device
 * parameter. Please note that this doesn't always mean the device is present. In certain cases (e.g. Bluetooth)
 * we may know about the device independently of whether it's currently connected or available.
 * @event CardReaderScanAndDiscoverOptions#onConnectionStatus
 * @param {error} error Error from connection
 * @param {DiscoveredCardReader} device The device that has been connected
 */

exports.default = CardReaderScanAndDiscoverOptions;
CardReaderScanAndDiscoverOptions.Events = {
  onCardReaderDiscovered: 'onCardReaderDiscovered',
  onScanComplete: 'onScanComplete',
  onConnectionStatus: 'onConnectionStatus'
};

},{"events":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/events/events.js"}],"/Users/aravidas/Documents/Git/retail-sdk/js/paymentDevice/DeviceBuilder.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

var _manticoreLog = require('manticore-log');

var _manticoreLog2 = _interopRequireDefault(_manticoreLog);

var _miuraEmv = require('miura-emv');

var _miuraEmv2 = _interopRequireDefault(_miuraEmv);

var _manticore = require('manticore');

var _manticore2 = _interopRequireDefault(_manticore);

var _retailPaymentDevice = require('retail-payment-device');

var _Merchant = require('../common/Merchant');

var _Merchant2 = _interopRequireDefault(_Merchant);

var _l10n = require('../common/l10n');

var _l10n2 = _interopRequireDefault(_l10n);

var _retailSDKUtil = require('../common/retailSDKUtil');

var _sdkErrors = require('../common/sdkErrors');

var _RoamSwiperDevice = require('./RoamSwiperDevice');

var _RoamSwiperDevice2 = _interopRequireDefault(_RoamSwiperDevice);

var _IngenicoDevice = require('../ingenico-emv/IngenicoDevice');

var _IngenicoDevice2 = _interopRequireDefault(_IngenicoDevice);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

var Log = (0, _manticoreLog2.default)('sdk.deviceBuilder');

function getHost(env) {
  var host = void 0;
  if (env === 'live') {
    host = 'api.paypal.com';
  } else if (env === 'sandbox') {
    host = 'api.sandbox.paypal.com';
  } else {
    // host = `api.${env}.stage.paypal.com:12326`;
    host = 'www.' + env + '.stage.paypal.com:12326';
  }
  return host;
}

function generateSwUpdateUrl(env) {
  return 'https://' + getHost(env) + '/v2/retail/validate-config';
}

function generateRKIUrl(env) {
  return 'https://' + getHost(env) + '/v2/retail/secure-terminal-configs';
}

function getRemoteKeys(rqBody, deviceVendor, model, callback) {
  var url = generateRKIUrl(_Merchant2.default.active.environment);
  var body = rqBody || {};
  body.vendor = deviceVendor.toLowerCase();
  body.model = (0, _retailSDKUtil.getDeviceModelName)(model).toLowerCase();
  Log.debug(function () {
    return 'Checking for RKI info from ' + url + '\n' + JSON.stringify(body, null, 4);
  });
  _Merchant2.default.active.request({
    url: url,
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(body),
    format: 'json'
  }, function (err, rz) {
    Log.debug('Received response for RKI update request');
    if (err) {
      Log.error('Error response to firmware update request ' + url + '. Error: ' + err + '\n' + JSON.stringify(rz));
    } else {
      Log.debug(function () {
        return 'Received firmware update response ' + JSON.stringify(rz, null, 4);
      });
    }
    callback(err, rz);
  });
}

function checkForUpdates(rqBody, deviceVendor, model, callback) {
  var url = generateSwUpdateUrl(_Merchant2.default.active.environment);
  var body = rqBody || {};
  body.country_code = _Merchant2.default.active.country.toLowerCase();
  body.vendor = deviceVendor.toLowerCase();
  body.model = (0, _retailSDKUtil.getDeviceModelName)(model).toLowerCase();
  body.environment = _Merchant2.default.active.repository;
  body.client_type = 'app';
  Log.debug(function () {
    return 'versionInfo> Checking for firmware updates from ' + url + '\n' + JSON.stringify(body, null, 4);
  });
  _Merchant2.default.active.request({
    url: url,
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(body),
    format: 'json'
  }, function (err, rz) {
    if (err) {
      Log.error('versionInfo> Error response to firmware update request ' + url + '. Error: ' + err + '\n' + JSON.stringify(rz));
    } else {
      Log.debug(function () {
        return 'versionInfo> Received firmware update response ' + JSON.stringify(rz, null, 4);
      });
    }
    callback(err, rz);
  });
}

function displayParse(val) {
  if (!val) {
    return '';
  }
  return val.id ? (0, _l10n2.default)(val.id, val.substitutions) : (0, _l10n2.default)(val);
}

/**
 * This class is intended to be used by the Native layers to create an
 * instance of payment device as soon as one is discovered
 */

var DeviceBuilder = function () {
  function DeviceBuilder() {
    _classCallCheck(this, DeviceBuilder);
  }

  DeviceBuilder.prototype.build = function build(manufacturer, id, isUsb, native, model, hardwareAddress) {
    Log.info('build: Building device with manufacturer: ' + manufacturer + ', id: ' + id + ', isUsb: ' + isUsb + ', model: ' + model + ', hardwareAddress: ' + hardwareAddress + '. Current devices: ' + _retailPaymentDevice.PaymentDevice.devices.length);
    for (var _iterator = _retailPaymentDevice.PaymentDevice.devices, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
      var _ref;

      if (_isArray) {
        if (_i >= _iterator.length) break;
        _ref = _iterator[_i++];
      } else {
        _i = _iterator.next();
        if (_i.done) break;
        _ref = _i.value;
      }

      var existingDevice = _ref;

      if (existingDevice.equals(id, manufacturer)) {
        Log.info('build: Found matching device ' + existingDevice + '. Will re-use it');
        existingDevice.native = native;
        return existingDevice;
      }
    }
    Log.debug(function () {
      return 'Device with id ' + id + ', manufacturer: ' + manufacturer + ' not found in cache... Will provision one';
    });
    if (manufacturer.toUpperCase() === _retailPaymentDevice.deviceManufacturer.miura) {
      return new _miuraEmv2.default(id, native, {
        display: this.display,
        getFirmwareUpdates: this.getFirmwareUpdates,
        getRemoteCardReaderKeys: this.getRemoteCardReaderKeys,
        getMerchant: this.getMerchant
      }, isUsb, hardwareAddress);
    } else if (manufacturer.toUpperCase() === _retailPaymentDevice.deviceManufacturer.roam) {
      return new _RoamSwiperDevice2.default(id, native, {
        display: this.display,
        getMerchant: this.getMerchant
      }, isUsb);
    } else if (manufacturer.toUpperCase() === _retailPaymentDevice.deviceManufacturer.ingenico) {
      // TODO See if we can consolidate getSwUpdateUrl and getConfigUrl when we implement Sw Update for Ingenico
      var params = {
        display: this.display,
        getFirmwareUpdates: this.getFirmwareUpdates,
        getMerchant: this.getMerchant
      };
      if (model.toUpperCase() === 'MOBY3000') {
        // Any Moby 3000 related params could be added here
        params.model = _retailPaymentDevice.ReaderModel.Moby3000;
      } else if (model.toUpperCase() === 'RP450') {
        // Any RP 450 related params could be added here
        params.contactlessEnabled = true;
        params.model = _retailPaymentDevice.ReaderModel.RP450;
      }
      return new _IngenicoDevice2.default(id, native, params, isUsb, hardwareAddress);
    }
    // TODO Perhaps make PaymentDevice.discovered private and invoke it here instead of doing it on native side?
    return null;
  };

  DeviceBuilder.prototype.getRemoteCardReaderKeys = function getRemoteCardReaderKeys(rqBody, deviceVendor, model, callback) {
    Log.debug(function () {
      return 'Received card reader remote keys request for \'' + deviceVendor + '-' + model + '\'';
    });
    if (_Merchant2.default.active) {
      getRemoteKeys(rqBody, deviceVendor, model, callback);
      return;
    }
    _Merchant2.default.events.once('initialized', function (e) {
      if (e) {
        Log.warn('Will not check for RKI for ' + model + ' as merchant initialize failed with error: ' + e);
        callback(e);
        return;
      }
      getRemoteKeys(rqBody, deviceVendor, model, callback);
    });
  };

  DeviceBuilder.prototype.getFirmwareUpdates = function getFirmwareUpdates(rqBody, deviceVendor, model, callback) {
    Log.debug(function () {
      return 'Received firmware update check request for \'' + deviceVendor + '-' + model + '\'';
    });
    if (_Merchant2.default.active) {
      checkForUpdates(rqBody, deviceVendor, model, callback);
    } else {
      callback(_sdkErrors.merchant.notInitialized);
    }
  };

  DeviceBuilder.prototype.getMerchant = function getMerchant() {
    return _Merchant2.default.active;
  };

  DeviceBuilder.prototype.display = function display(args, callback) {
    Log.debug(function () {
      return 'Card reader wants to display an alert on App: ' + JSON.stringify(args);
    });
    var alertOptions = {
      title: displayParse(args.title),
      message: displayParse(args.message),
      cancel: displayParse(args.cancel),
      showActivity: args.showActivity,
      audio: args.audio,
      replace: args.replace,
      setCancellable: args.setCancellable
    };

    if (args.buttons) {
      alertOptions.buttons = [];
      for (var _iterator2 = args.buttons, _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) {
        var _ref2;

        if (_isArray2) {
          if (_i2 >= _iterator2.length) break;
          _ref2 = _iterator2[_i2++];
        } else {
          _i2 = _iterator2.next();
          if (_i2.done) break;
          _ref2 = _i2.value;
        }

        var button = _ref2;

        alertOptions.buttons.push(displayParse(button));
      }
    }

    var cb = callback;
    if (!cb) {
      cb = function cb() {}; // eslint-disable-line func-names
    }
    return _manticore2.default.alert(alertOptions, cb);
  };

  return DeviceBuilder;
}();

exports.default = DeviceBuilder;

},{"../common/Merchant":"/Users/aravidas/Documents/Git/retail-sdk/js/common/Merchant.js","../common/l10n":"/Users/aravidas/Documents/Git/retail-sdk/js/common/l10n.js","../common/retailSDKUtil":"/Users/aravidas/Documents/Git/retail-sdk/js/common/retailSDKUtil.js","../common/sdkErrors":"/Users/aravidas/Documents/Git/retail-sdk/js/common/sdkErrors.js","../ingenico-emv/IngenicoDevice":"/Users/aravidas/Documents/Git/retail-sdk/js/ingenico-emv/IngenicoDevice.js","./RoamSwiperDevice":"/Users/aravidas/Documents/Git/retail-sdk/js/paymentDevice/RoamSwiperDevice.js","manticore":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore/browser.js","manticore-log":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-log/index.js","miura-emv":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/build/index.js","retail-payment-device":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/js/paymentDevice/DeviceConnector.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

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; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

var _manticore = require('manticore');

var _manticore2 = _interopRequireDefault(_manticore);

var _manticoreLog = require('manticore-log');

var _manticoreLog2 = _interopRequireDefault(_manticoreLog);

var _retailPaymentDevice = require('retail-payment-device');

var _l10n = require('../common/l10n');

var _l10n2 = _interopRequireDefault(_l10n);

var _retailSDKUtil = require('../common/retailSDKUtil');

var _DeviceConnectorOptions = require('./DeviceConnectorOptions');

var _DeviceConnectorOptions2 = _interopRequireDefault(_DeviceConnectorOptions);

var _DeviceManager = require('../transaction/DeviceManager');

var _DeviceManager2 = _interopRequireDefault(_DeviceManager);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

var Log = (0, _manticoreLog2.default)('deviceConnector');

/**
 * Purpose of this class is to provide APIs to connect to last active card reader and the actual connection flow
 */

var DeviceConnector = function () {
  function DeviceConnector() {
    _classCallCheck(this, DeviceConnector);
  }

  DeviceConnector.prototype.connectToLastActiveReaderOrFindAnother = function connectToLastActiveReaderOrFindAnother(cb) {
    var _this = this;

    this._promptInProgress = true;
    this._createdCardReader = null;
    (0, _retailSDKUtil.getLastActiveReader)(function (activeReader) {
      Log.debug(function () {
        return 'Last Active reader id: ' + (activeReader ? activeReader.id : '<null>');
      });
      var scanner = _DeviceManager2.default.getDeviceScanner();
      if (scanner && scanner.connectedDevice && activeReader && scanner.connectedDevice.id === activeReader.id) {
        Log.debug(function () {
          return 'Last Active reader id: ' + scanner.connectedDevice.id + ' is already connected! Do NOT show the dialog!';
        });
        cb(null, scanner.connectedDevice);
        _this._promptInProgress = false;
        return;
      }
      if (!activeReader || (0, _retailSDKUtil.isRoamSwiper)(activeReader.id)) {
        if (scanner) {
          scanner.updateLastActiveIfBTPaired(function () {
            _this._connectToLastActiveReaderOrFindAnother(cb);
          });
          return;
        }
      }
      _this._connectToLastActiveReaderOrFindAnother(cb);
    });
  };

  DeviceConnector.prototype._connectToLastActiveReaderOrFindAnother = function _connectToLastActiveReaderOrFindAnother(cb) {
    var _this2 = this;

    (0, _retailSDKUtil.getLastActiveReader)(function (lastActiveReader) {
      if (!lastActiveReader) {
        if (cb) {
          cb(_retailPaymentDevice.deviceError.lastActiveReaderNotFound);
        }
        _this2._promptInProgress = false;
        return;
      }
      if ((0, _retailSDKUtil.isRoamSwiper)(lastActiveReader.id)) {
        // ROAM Swiper's are discovered and connected outside of this flow fully on the native side. Do nothing here
        Log.debug('Will not execute "connectLastReaderPrompt" flow as the last connected card reader was ROAM Swiper.');
        if (cb) {
          cb(null, null);
        }
        _this2._promptInProgress = false;
        return;
      }
      var opt = new _DeviceConnectorOptions2.default();
      opt.readerId = '' + lastActiveReader.id;
      opt.readerDescription = (0, _retailSDKUtil.getCardReaderDescription)(lastActiveReader.id);
      opt.readerImgId = (0, _retailSDKUtil.getCardReaderIcon)(lastActiveReader.id);
      opt.errorImgId = 'ic_critical';
      opt.hardwareAddress = lastActiveReader.address;
      opt.titleLastReaderUsed = (0, _l10n2.default)('Device.LastReaderUsed.titleLastReaderUsed');
      opt.titleConnected = (0, _l10n2.default)('Device.LastReaderUsed.titleConnected');
      opt.msgConnecting = (0, _l10n2.default)('Device.LastReaderUsed.msgConnecting');
      opt.msgConnectionFailed = (0, _l10n2.default)('Device.LastReaderUsed.msgConnectionFailed');
      opt.msgFindFailed = (0, _l10n2.default)('Device.LastReaderUsed.msgFindFailed');
      opt.msgCheckReader = (0, _l10n2.default)('Device.LastReaderUsed.msgCheckReader');
      opt.btnConnect = (0, _l10n2.default)('Device.LastReaderUsed.btnConnect');
      opt.btnFindAnother = (0, _l10n2.default)('Device.LastReaderUsed.btnFindAnother');
      opt.btnDone = (0, _l10n2.default)('Device.LastReaderUsed.btnDone');
      opt.btnSwitchCardReader = (0, _l10n2.default)('Device.LastReaderUsed.btnSwitchCardReader');
      opt.btnTryAgain = (0, _l10n2.default)('Device.LastReaderUsed.btnTryAgain');
      opt.btnCancel = (0, _l10n2.default)('Device.LastReaderUsed.btnCancel');
      opt.connectToLastReader = function () {
        if (!_manticore2.default.isCardReaderAvailable(lastActiveReader.id, lastActiveReader.address)) {
          Log.info('Card reader with Id: \'' + lastActiveReader.id + '\' and address \'' + lastActiveReader.address + '\' is not available. Will not prompt user to connect to it');
          opt.emit(_DeviceConnectorOptions2.default.Events.connectionResult, _retailPaymentDevice.deviceError.cardReaderNotAvailable);
        } else {
          _this2.createAndConnect(lastActiveReader.id, lastActiveReader.address, function (errCreate, pd) {
            opt.emit(_DeviceConnectorOptions2.default.Events.connectionResult, errCreate, pd);
          });
        }
      };
      Log.debug(function () {
        return 'Invoking connectLastReaderPrompt with ' + JSON.stringify(opt, null, 4);
      });
      _manticore2.default.connectLastReaderPrompt(opt, function (action) {
        Log.debug(function () {
          return 'Completed \'connectLastReaderPrompt\' with action=\'' + action + '\'';
        });
        _this2._promptInProgress = false;
        if (action === 'cancel') {
          if (_this2._createdCardReader) {
            _this2._createdCardReader.disconnect(function (errDisc) {
              Log.debug(function () {
                return 'Disconnected from ' + _this2._createdCardReader.id + '. Error: ' + errDisc;
              });
            });
          }
          if (cb) {
            cb(_retailPaymentDevice.deviceError.actionCancelled);
          }
        } else if (action === 'scan') {
          try {
            _DeviceManager2.default.searchAndConnect();
          } catch (x) {
            Log.error('Error selecting devices: ' + x);
            cb(_retailPaymentDevice.deviceError.dataRetrievalFailed.withDevMessage(x.toString()));
          }
        } else {
          var reader = _DeviceManager2.default.getActiveReader();
          if (!reader) {
            if (cb) {
              cb();
            }
            return;
          }
          Log.info('Set active reader to \'' + reader.id + '\', firmwareUpdate: ' + reader.isUpdateRequired());
          if (cb) {
            cb(null, reader);
          }
        }
      });
    });
  };

  DeviceConnector.prototype.createAndConnect = function createAndConnect(readerId, address, cb) {
    var _this3 = this;

    Log.debug(function () {
      return 'Card reader ' + readerId + ' with address (' + address + ') is available. Will prompt to connect';
    });
    var name = readerId;
    var manufacturer = (0, _retailSDKUtil.getCardReaderManufacturer)(name);
    _manticore2.default.createCardReader({ name: name, address: address, manufacturer: manufacturer }, function (errCreate, cardReader) {
      if (errCreate) {
        Log.error('Error provisioning card reader with ' + name + '-' + address + '-' + manufacturer + ' : ' + JSON.stringify(errCreate));
        if (cb) {
          cb(errCreate);
        }
        return;
      }
      _this3._createdCardReader = cardReader;
      Log.debug(function () {
        return 'Successfully created card reader ' + cardReader.id + '-' + cardReader.address + '. Will attempt to connect to it';
      });
      cardReader.connect(function (err) {
        if (err) {
          Log.error('Connection to card reader \'' + cardReader.id + '\' failed with error : ' + JSON.stringify(err));
        } else {
          Log.debug(function () {
            return 'Successfully connected to card reader ' + cardReader.id + '.';
          });
        }
        if (cb) {
          cb(err, cardReader);
        }
      });
    });
  };

  _createClass(DeviceConnector, [{
    key: 'isInProgress',
    get: function get() {
      return this._promptInProgress;
    },
    set: function set(value) {
      throw new Error('The readOnly _promptInProgress property cannot be written. ' + value + ' was passed.');
    }
  }]);

  return DeviceConnector;
}();

var deviceConnector = new DeviceConnector();
exports.default = deviceConnector;

},{"../common/l10n":"/Users/aravidas/Documents/Git/retail-sdk/js/common/l10n.js","../common/retailSDKUtil":"/Users/aravidas/Documents/Git/retail-sdk/js/common/retailSDKUtil.js","../transaction/DeviceManager":"/Users/aravidas/Documents/Git/retail-sdk/js/transaction/DeviceManager.js","./DeviceConnectorOptions":"/Users/aravidas/Documents/Git/retail-sdk/js/paymentDevice/DeviceConnectorOptions.js","manticore":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore/browser.js","manticore-log":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-log/index.js","retail-payment-device":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/js/paymentDevice/DeviceConnectorOptions.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

var _events = require('events');

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (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 } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

/**
 * Device connector options to send it over to native side
 * @class
 * @property {string} readerId Card reader name as it shows up in the bluetooth settings page
 * @property {string} readerDescription Card reader description
 * @property {string} readerImgId Image identifier
 * @property {string} hardwareAddress Bluetooth card reader hardware mac address
 * @property {string} titleLastReaderUsed Title for last reader used prompt
 * @property {string} titleConnected Title for connected prompt
 * @property {string} msgConnecting Connecting message
 * @property {string} msgConnectionFailed Connection failed message
 * @property {string} btnConnect Connect button text
 * @property {string} btnFindAnother Find another button text
 * @property {string} btnDone Done button text
 * @property {string} btnSwitchCardReader Switch card reader button text
 * @property {string} btnTryAgain Try again button text
 * @property {string} btnCancel Cancel button text
 */
var DeviceConnectorOptions = function (_EventEmitter) {
  _inherits(DeviceConnectorOptions, _EventEmitter);

  function DeviceConnectorOptions() {
    _classCallCheck(this, DeviceConnectorOptions);

    return _possibleConstructorReturn(this, _EventEmitter.apply(this, arguments));
  }

  /**
   * Connect to the last active reader
   */
  DeviceConnectorOptions.prototype.connectToLastReader = function connectToLastReader() {};

  return DeviceConnectorOptions;
}(_events.EventEmitter);

/**
 * A PaymentDevice has been discovered. For further events, such as device readiness, removal or the
 * need for a software upgrade, your application should subscribe to the relevant events on the device
 * parameter. Please note that this doesn't always mean the device is present. In certain cases (e.g. Bluetooth)
 * we may know about the device independently of whether it's currently connected or available.
 * @event DeviceConnectorOptions#onConnectionResult
 * @param {error} Error Error from connection
 * @param {PaymentDevice} device The device that has been connected
 */

exports.default = DeviceConnectorOptions;
DeviceConnectorOptions.Events = {
  connectionResult: 'onConnectionResult'
};

},{"events":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/events/events.js"}],"/Users/aravidas/Documents/Git/retail-sdk/js/paymentDevice/DeviceScanner.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

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; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

var _manticore = require('manticore');

var _manticore2 = _interopRequireDefault(_manticore);

var _manticoreLog = require('manticore-log');

var _manticoreLog2 = _interopRequireDefault(_manticoreLog);

var _retailPaymentDevice = require('retail-payment-device');

var _events = require('events');

var _l10n = require('../common/l10n');

var _l10n2 = _interopRequireDefault(_l10n);

var _retailSDKUtil = require('../common/retailSDKUtil');

var _DeviceConnector = require('./DeviceConnector');

var _DeviceConnector2 = _interopRequireDefault(_DeviceConnector);

var _DiscoveredCardReader = require('./DiscoveredCardReader');

var _DiscoveredCardReader2 = _interopRequireDefault(_DiscoveredCardReader);

var _CardReaderScanAndDiscoverOptions = require('./CardReaderScanAndDiscoverOptions');

var _CardReaderScanAndDiscoverOptions2 = _interopRequireDefault(_CardReaderScanAndDiscoverOptions);

var _sdkErrors = require('../common/sdkErrors');

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

var Log = (0, _manticoreLog2.default)('DeviceScanner');

var deviceScannerError = {
  bluetoothdDisabled: 'bluetoothDisabled'
};
/**
* DeviceScanner is responsible for searching the available devices and
* managing the connected device
* When user selects one, it emits the connected event.
* When the connected device gets disconnected, it emits disconnected event.
* At any given time, one device is connected from DeviceScanner
* @class
* @protected
*/

var DeviceScanner = function () {
  /**
   * Construct a new DeviceScanner
   */
  function DeviceScanner(nativeInterface) {
    var _this = this;

    _classCallCheck(this, DeviceScanner);

    this.native = nativeInterface;
    this._connectedPaymentDevice = null;
    _retailPaymentDevice.PaymentDevice.Events.on('deviceDiscovered', function (pd) {
      return _this.discovered(pd);
    });
    this._discoveredDevices = [];
    this._setDiscovered = new Set();
    DeviceScanner.Events.emit(DeviceScanner.Events.constructor, this);
  }

  DeviceScanner.prototype.discovered = function discovered(pd) {
    var _this2 = this;

    Log.info('a new device discovered by DeviceScanner: ' + pd.id);
    pd.once(_retailPaymentDevice.PaymentDevice.Event.deviceRemoved, function (device) {
      return _this2._removedDevice(device);
    });
    pd.on(_retailPaymentDevice.PaymentDevice.Event.disconnected, function () {
      return _this2._disconnectedDevice(pd);
    });
    pd.on(_retailPaymentDevice.PaymentDevice.Event.connected, function () {
      return _this2._connectedDevice(pd);
    });
    if ((0, _retailSDKUtil.isRoamSwiper)(pd.id)) {
      if (this._selectionInProgress && this._scanInProgress) {
        Log.debug('Roam swiper just plugged during scan in Progress. This will update the MCR list');
        this.onDiscovered({
          id: pd.id,
          address: 'RoamSwiper',
          isConnected: false
        });
      } else if (this._connectedPaymentDevice) {
        // if the connected device is BT, the swiper plugin shall trigger the MCR!
        Log.debug(function () {
          return 'Roam swiper just plugged in which will trigger scan and discover given the current connected device: ' + _this2._connectedPaymentDevice;
        });
        this.searchAndConnectWithUI();
      } else {
        Log.info('connecting to ' + pd.id + ' without searchAndConnectWithUI');
        if (!_DeviceConnector2.default.isInProgress) {
          pd.connect(function (err) {
            if (err) {
              Log.error('Connection to card reader \'' + pd.id + '\' failed with error : ' + JSON.stringify(err));
            } else {
              Log.debug(function () {
                return 'Successfully connected to card reader ' + pd.id + '.';
              });
            }
          });
        } else {
          Log.debug(function () {
            return 'Due to in-progress connection prompt, NOT connecting to ' + pd.id;
          });
        }
      }
    }
  };

  DeviceScanner.prototype._removedDevice = function _removedDevice(pd) {
    Log.debug(function () {
      return 'removed  device \'' + (pd && pd.id) + '\'!';
    });
    // For ingenico devices, removed happens before disconnected event.
    // Here the idea is that if we receive the 'removed' event before 'disconnected',
    // we handle it same way.
    this._disconnectedDevice(pd);
  };

  DeviceScanner.prototype._disconnectedDevice = function _disconnectedDevice(pd) {
    if (pd && this._connectedPaymentDevice === pd) {
      Log.debug(function () {
        return 'unsetting connected device \'' + (pd && pd.id) + '\' to null';
      });
      this._connectedPaymentDevice = null;
      DeviceScanner.Events.emit(DeviceScanner.Event.disconnected, pd);
    } else {
      Log.debug(function () {
        return 'the device \'' + (pd && pd.id) + '\' is not connected device anymore!';
      });
    }
  };

  DeviceScanner.prototype._connectedDevice = function _connectedDevice(pd) {
    var _this3 = this;

    if (!this._connectedPaymentDevice) {
      this._setConnectedDevice(pd);
      return;
    }

    if (pd && this._connectedPaymentDevice !== pd) {
      Log.debug(function () {
        return 'connected -> disconnecting the connected device: ' + JSON.stringify(_this3._connectedPaymentDevice, null, 4);
      });
      this._connectedPaymentDevice.disconnect(function () {
        _this3._setConnectedDevice(pd);
      });
    } else {
      Log.debug(function () {
        return 'SAME  device \'' + (pd && pd.id) + '\' connected!';
      });
    }
  };

  DeviceScanner.prototype._setConnectedDevice = function _setConnectedDevice(pd) {
    this._connectedPaymentDevice = pd;
    Log.debug(function () {
      return 'Setting connected device to \'' + (pd && pd.id) + '\'';
    });
    DeviceScanner.Events.emit(DeviceScanner.Event.connected, pd);
    (0, _retailSDKUtil.saveLastActiveReader)(pd);
  };

  DeviceScanner.prototype.updateLastActiveIfBTPaired = function updateLastActiveIfBTPaired(cb) {
    var checkAndSave = function checkAndSave(pd) {
      var id = pd.id;
      var address = pd.address;
      if ((0, _retailSDKUtil.getCardReaderModel)(id) === _retailPaymentDevice.ReaderModel.Unknown || (0, _retailSDKUtil.getCardReaderModel)(id) === _retailPaymentDevice.ReaderModel.Swiper) {
        Log.debug(function () {
          return 'non-BT device model discovered: ' + id;
        });
        return false;
      }
      Log.debug('Saving reader id: ' + id + ' and address:: ' + address);
      (0, _retailSDKUtil.saveLastActiveReader)({ id: id, address: address }, cb);
      return true;
    };

    Log.debug(function () {
      return 'Discovered readers: ' + JSON.stringify(_retailPaymentDevice.PaymentDevice.devices);
    });
    for (var _iterator = _retailPaymentDevice.PaymentDevice.devices, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
      var _ref;

      if (_isArray) {
        if (_i >= _iterator.length) break;
        _ref = _iterator[_i++];
      } else {
        _i = _iterator.next();
        if (_i.done) break;
        _ref = _i.value;
      }

      var pd = _ref;

      if (checkAndSave(pd)) {
        return;
      }
    }

    this.native.getBTList(function (readers) {
      Log.debug(function () {
        return 'BT paired readers: ' + JSON.stringify(readers, null, 2);
      });
      for (var _iterator2 = readers, _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) {
        var _ref2;

        if (_isArray2) {
          if (_i2 >= _iterator2.length) break;
          _ref2 = _iterator2[_i2++];
        } else {
          _i2 = _iterator2.next();
          if (_i2.done) break;
          _ref2 = _i2.value;
        }

        var pd = _ref2;

        if (checkAndSave(pd)) {
          return;
        }
      }

      if (cb) {
        cb();
      }
    });
  };

  DeviceScanner.prototype.onDiscovered = function onDiscovered(args) {
    Log.debug(function () {
      return 'onDiscovered args: ' + JSON.stringify(args, null, 4);
    });
    if (!args || !args.id || !args.address) {
      Log.warn('Received empty args message');
      return;
    }
    var id = args.id;
    var address = args.address;
    if ((0, _retailSDKUtil.getCardReaderModel)(id) === _retailPaymentDevice.ReaderModel.Unknown) {
      Log.debug(function () {
        return 'unknown device model discovered: ' + id;
      });
      return;
    }

    Log.debug(function () {
      return 'onDiscovered -> new device: \'' + id + '\' and address: ' + address;
    });

    if (this._scanInProgress && this._selectionInProgress) {
      if (!this._setDiscovered.has(address)) {
        Log.debug(function () {
          return 'onDiscovered -> prompting the new device: ' + JSON.stringify(args, null, 2);
        });
        this._setDiscovered.add(address);
        this._discoveredDevices.push({ id: id, address: address });
        // this._promptForDeviceConnection();
        var discoveredReader = new _DiscoveredCardReader2.default();
        discoveredReader.readerId = id;
        discoveredReader.readerDescription = (0, _retailSDKUtil.getCardReaderDescription)(id);
        discoveredReader.readerImgId = (0, _retailSDKUtil.getCardReaderIcon)(id);
        discoveredReader.isConnected = !!args.isConnected;
        Log.debug(function () {
          return 'Emitting discoveredReader with ' + JSON.stringify(discoveredReader, null, 4);
        });
        this.opt.emit(_CardReaderScanAndDiscoverOptions2.default.Events.onCardReaderDiscovered, discoveredReader);
      } else {
        Log.debug(function () {
          return 'already added to discovered list ' + args.id + ':' + args.address + ' ';
        });
      }
    } else {
      Log.debug(function () {
        return 'we shall NOT discover any device ' + args.id + ' when scan is NOT in Progress!!! ';
      });
    }
  };

  DeviceScanner.prototype.searchAndConnectWithUI = function searchAndConnectWithUI(cb) {
    var _this4 = this;

    Log.debug(function () {
      return 'searchAndConnectWithUI started. the current selected device: ' + _this4._connectedPaymentDevice;
    });
    if (!this._connectedPaymentDevice) {
      // whenever it is null, go for selection step.
      this._searchAndConnect(cb);
    } else if (!this._connectedPaymentDevice.cardPresented) {
      this._searchAndConnect(cb);
    } else {
      Log.info('Will not prompt for device selection due to payment in progress? \'' + (this._connectedPaymentDevice && this._connectedPaymentDevice.cardPresented) + '\'');
    }
  };

  DeviceScanner.prototype._searchAndConnect = function _searchAndConnect(cb) {
    var _this5 = this;

    this._scanInProgress = true;
    this._selectionInProgress = true;
    this._discoveredDevices = [];
    this._setDiscovered.clear();

    var opt = new _CardReaderScanAndDiscoverOptions2.default();
    this.opt = opt;
    opt.connectToCardReader = function (id) {
      if (!_this5._selectionInProgress) {
        Log.warn('connectToCardReader  called for ' + id + ' even though selection is OVER!');
        return;
      }
      Log.info('connectToCardReader  called for ' + id);
      var connectToReader = void 0;
      for (var _iterator3 = _this5._discoveredDevices, _isArray3 = Array.isArray(_iterator3), _i3 = 0, _iterator3 = _isArray3 ? _iterator3 : _iterator3[Symbol.iterator]();;) {
        var _ref3;

        if (_isArray3) {
          if (_i3 >= _iterator3.length) break;
          _ref3 = _iterator3[_i3++];
        } else {
          _i3 = _iterator3.next();
          if (_i3.done) break;
          _ref3 = _i3.value;
        }

        var pd = _ref3;

        if (pd.id === id) {
          connectToReader = pd;
          Log.info('Found matching device ' + connectToReader.id + '. Will connect it');
        }
      }
      var createAndConnect = function createAndConnect() {
        Log.info('connecting to ' + connectToReader.id);
        _this5._connectionInProgress = connectToReader;
        _DeviceConnector2.default.createAndConnect(connectToReader.id, connectToReader.address, function (errCreate, pd) {
          _this5._connectionInProgress = null;
          if (errCreate) {
            Log.error('Error for card reader with ' + connectToReader.id + '-' + connectToReader.address + ' : ' + JSON.stringify(errCreate));
            _this5._emitConnected(errCreate, pd);
            _this5._selectionInProgress = true; // allow "try again" button after the failure
            return;
          }
          _this5._emitConnected(errCreate, pd);
          if (cb) {
            cb(null, pd);
          }
        });
      };

      if (!_this5._connectedPaymentDevice) {
        createAndConnect();
      } else if (_this5._connectedPaymentDevice.id !== connectToReader.id) {
        Log.debug(function () {
          return 'UI -> disconnecting the connected device: ' + JSON.stringify(_this5._connectedPaymentDevice, null, 4);
        });
        _this5._connectedPaymentDevice.disconnect(function () {
          createAndConnect();
        });
      } else {
        Log.info('SAME device selected by user ==>> ' + _this5._connectedPaymentDevice.id + '. Connected? ' + _this5._connectedPaymentDevice.isConnected());
        var onConnected = function onConnected(err) {
          _this5._emitConnected(err, _this5._connectedPaymentDevice);
          if (cb) {
            cb(err, _this5._connectedPaymentDevice);
          }
        };
        if (_this5._connectedPaymentDevice.isConnected()) {
          onConnected(null);
        } else {
          _this5._connectedPaymentDevice.connect(function (errConnect) {
            return onConnected(errConnect);
          });
        }
      }

      if (_this5._scanInProgress) {
        Log.info('stopping scanAndDiscover since the user selected ' + connectToReader.id);
        _this5.native.stop();
      }
      _this5._selectionInProgress = false;
    };

    opt.onAddedObserver = function () {
      Log.debug('Native side added the observers so we can start scanning');
      if (_this5._connectedPaymentDevice) {
        // first update UI about connected Card Reader
        Log.debug(function () {
          return 'Adding first the connected device (address: ' + _this5._connectedPaymentDevice.address + '): ' + JSON.stringify(_this5._connectedPaymentDevice, null, 4);
        });
        _this5.onDiscovered({
          id: _this5._connectedPaymentDevice.id,
          address: _this5._connectedPaymentDevice.address,
          isConnected: true
        });
      }

      _this5.native.start(function (err) {
        // scan is complete
        Log.debug('scan complete');
        _this5._scanInProgress = false;

        var emitError = null;
        if (err) {
          Log.error('Scanning ended with error: ' + JSON.stringify(err, null, 2));
          if (err.code && err.code === deviceScannerError.bluetoothdDisabled) {
            // 1: bluetooth disabled
            emitError = _sdkErrors.sdk.bluetoothDisabled;
          } else {
            emitError = err.code ? new Error(err.code) : new Error('error');
          }
        }
        if (_this5._discoveredDevices.length <= 0) {
          emitError = _sdkErrors.sdk.noReaderFound;
        }
        _this5.opt.emit(_CardReaderScanAndDiscoverOptions2.default.Events.onScanComplete, emitError);
      });
    };

    Log.debug(function () {
      return 'Invoking searchAndConnectWithUI with ' + JSON.stringify(opt, null, 4);
    });

    _manticore2.default.scanAndDiscover(opt, function (action) {
      if (action === 'cancel') {
        // Try canceling an in-progress connection
        if (_this5._connectionInProgress) {
          Log.debug(function () {
            return 'Trying to cancel in-progress connection to ' + _this5._connectionInProgress.id + '. Total discovered devices: ' + _retailPaymentDevice.PaymentDevice.devices.length;
          });

          var _loop = function _loop() {
            if (_isArray4) {
              if (_i4 >= _iterator4.length) return 'break';
              _ref4 = _iterator4[_i4++];
            } else {
              _i4 = _iterator4.next();
              if (_i4.done) return 'break';
              _ref4 = _i4.value;
            }

            var pd = _ref4;

            if (pd.id === _this5._connectionInProgress.id && pd.manufacturer === _retailPaymentDevice.deviceManufacturer.ingenico) {
              Log.debug(function () {
                return 'Will stop connection to ' + pd.id;
              });
              pd.disconnect(function () {
                Log.debug(function () {
                  return 'Disconnected from ' + pd.id;
                });
              });
            }
          };

          for (var _iterator4 = _retailPaymentDevice.PaymentDevice.devices, _isArray4 = Array.isArray(_iterator4), _i4 = 0, _iterator4 = _isArray4 ? _iterator4 : _iterator4[Symbol.iterator]();;) {
            var _ref4;

            var _ret = _loop();

            if (_ret === 'break') break;
          }
        }

        if (cb) {
          cb(_retailPaymentDevice.deviceError.actionCancelled);
        }
        if (_this5._scanInProgress) {
          Log.info('stopping scanAndDiscover since the user selected ' + action);
          _this5.native.stop();
        }
        _this5._selectionInProgress = false;
      } else if (action === 'scan') {
        _this5._searchAndConnect(cb);
      } else {
        // For action == 'done', the callback is called within connectToCardReader
        Log.debug(function () {
          return 'Device discover and connect flow completed... will check for firmware update if any. SelectedDevice: ' + (_this5._connectedPaymentDevice && _this5._connectedPaymentDevice.id) + ', firmwareUpdate: ' + (_this5._connectedPaymentDevice && _this5._connectedPaymentDevice.isUpdateRequired());
        });
      }
    });
  };

  DeviceScanner.prototype._emitConnected = function _emitConnected(err, pd) {
    var connectedReader = void 0;
    if (pd) {
      connectedReader = new _DiscoveredCardReader2.default();
      connectedReader.readerId = pd.id;
      connectedReader.readerDescription = (0, _retailSDKUtil.getCardReaderDescription)(pd.id);
      connectedReader.readerImgId = (0, _retailSDKUtil.getCardReaderIcon)(pd.id);
      connectedReader.isConnected = true;
    }
    Log.debug(function () {
      return 'Emitting onConnectionStatus: ' + JSON.stringify(connectedReader, null, 2);
    });
    this.opt.emit(_CardReaderScanAndDiscoverOptions2.default.Events.onConnectionStatus, err, connectedReader);
  };

  DeviceScanner.prototype._promptForDeviceConnection = function _promptForDeviceConnection() {
    var _this6 = this;

    var imgs = [];
    var ids = [];

    for (var _iterator5 = this._discoveredDevices, _isArray5 = Array.isArray(_iterator5), _i5 = 0, _iterator5 = _isArray5 ? _iterator5 : _iterator5[Symbol.iterator]();;) {
      var _ref5;

      if (_isArray5) {
        if (_i5 >= _iterator5.length) break;
        _ref5 = _iterator5[_i5++];
      } else {
        _i5 = _iterator5.next();
        if (_i5.done) break;
        _ref5 = _i5.value;
      }

      var device = _ref5;

      Log.info('_promptForDeviceConnection: ' + JSON.stringify(device, null, 2));
      imgs.push((0, _retailSDKUtil.getCardReaderIcon)(device.id));
      ids.push(device.id);
    }

    this.alert = _manticore2.default.alert({
      title: (0, _l10n2.default)('MultiCard.Title'),
      message: (0, _l10n2.default)('MultiCard.Msg'),
      buttonsImages: imgs,
      buttonsIds: ids,
      mcrDialog: true
    }, function (alert, index) {
      Log.debug(function () {
        return 'index selected: ' + index;
      });
      if (_this6.alert) {
        _this6.alert.dismiss();
      }
      if (index >= 0 && index <= _this6._discoveredDevices.length - 1) {
        var _pd = _this6._discoveredDevices[index];
        Log.info('MCR - Found matching device ' + JSON.stringify(_pd, null, 2) + '. Will connect it');
        _this6.opt.connectToCardReader(_pd.id);
      } else {
        Log.error('wrong index selected for the card reader: ' + index);
      }
      _this6._selectionInProgress = false;
      if (_this6._scanInProgress) {
        Log.info('_promptForDeviceConnection -> native.stop()');
        _this6.native.stop();
      }
    });
  };

  _createClass(DeviceScanner, [{
    key: 'connectedDevice',
    get: function get() {
      return this._connectedPaymentDevice;
    },
    set: function set(value) {
      throw new Error('The readOnly connectedPaymentDevice property cannot be written. ' + value + ' was passed.');
    }
  }]);

  return DeviceScanner;
}();

exports.default = DeviceScanner;


DeviceScanner.Event = {
  constructor: 'constructor',
  connected: 'connected',
  disconnected: 'disconnected'
};

DeviceScanner.Events = new _events.EventEmitter();

},{"../common/l10n":"/Users/aravidas/Documents/Git/retail-sdk/js/common/l10n.js","../common/retailSDKUtil":"/Users/aravidas/Documents/Git/retail-sdk/js/common/retailSDKUtil.js","../common/sdkErrors":"/Users/aravidas/Documents/Git/retail-sdk/js/common/sdkErrors.js","./CardReaderScanAndDiscoverOptions":"/Users/aravidas/Documents/Git/retail-sdk/js/paymentDevice/CardReaderScanAndDiscoverOptions.js","./DeviceConnector":"/Users/aravidas/Documents/Git/retail-sdk/js/paymentDevice/DeviceConnector.js","./DiscoveredCardReader":"/Users/aravidas/Documents/Git/retail-sdk/js/paymentDevice/DiscoveredCardReader.js","events":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/events/events.js","manticore":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore/browser.js","manticore-log":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-log/index.js","retail-payment-device":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/js/paymentDevice/DeviceSelector.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

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; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

var _manticore = require('manticore');

var _manticore2 = _interopRequireDefault(_manticore);

var _manticoreLog = require('manticore-log');

var _manticoreLog2 = _interopRequireDefault(_manticoreLog);

var _retailPaymentDevice = require('retail-payment-device');

var _CardReaderDisplayController = require('./CardReaderDisplayController');

var _CardReaderDisplayController2 = _interopRequireDefault(_CardReaderDisplayController);

var _displayPriority = require('./displayPriority');

var _displayPriority2 = _interopRequireDefault(_displayPriority);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

var Log = (0, _manticoreLog2.default)('DeviceSelector');

/**
 * DeviceSelector is responsible for deciding the device used in a transaction.
 * It tracks the 'deviceDiscovered' and 'deviceRemoved' events to make a decision
 * for the selected device. If more than 1 devices available, it prompts user to
 * decide it. It also provides an API 'selectDevice(id) to select the device
 * based on the id
 * Note that if any device is discovered during an active transaction, selection
 * will be postponed by the next event.
 * Note that If the selected device is removed and it has an active transaction,
 * it will postpone the selection to the next event.
 */

var DeviceSelector = function () {
  function DeviceSelector() {
    var _this = this;

    _classCallCheck(this, DeviceSelector);

    this._selectedPaymentDevice = null;
    _retailPaymentDevice.PaymentDevice.Events.on('deviceDiscovered', function (pd) {
      return _this.discovered(pd);
    });
  }

  DeviceSelector.prototype._setSelectedDevice = function _setSelectedDevice(pd) {
    Log.debug(function () {
      return 'Setting selected device to \'' + (pd && pd.id) + '\'';
    });
    this._selectedPaymentDevice = pd;
    if (pd) {
      _retailPaymentDevice.PaymentDevice.Events.emit(_retailPaymentDevice.PaymentDevice.Event.selected, pd);
    }
  };

  DeviceSelector.prototype.discovered = function discovered(pd) {
    var _this2 = this;

    Log.info('a new device discovered by DeviceSelector: ' + pd.id);
    pd.once(_retailPaymentDevice.PaymentDevice.Event.deviceRemoved, function (device) {
      return _this2.removed(device);
    });
    pd.on(_retailPaymentDevice.PaymentDevice.Event.disconnected, function () {
      return _this2._startDeviceSelection();
    });
    pd.on(_retailPaymentDevice.PaymentDevice.Event.connected, function () {
      return _this2._startDeviceSelection();
    });
  };

  DeviceSelector.prototype.removed = function removed(pd) {
    Log.info('a new device removed by DeviceSelector: ' + pd.id);
    if (pd === this._selectedPaymentDevice && pd.cardPresented) {
      // Corner case: don't bother the current transaction.
      this._setSelectedDevice(null);
      Log.debug(function () {
        return 'The selected device:' + pd.id + ' having active transaction is removed!';
      });
      return;
    }
    if (!this._selectedPaymentDevice || pd === this._selectedPaymentDevice || this._selectionInProgress) {
      Log.debug('a new device removed and to be select new one -->>>>');
      this._promptForDeviceSelection();
    }
  };

  DeviceSelector.prototype.isConnectedToMiura = function isConnectedToMiura() {
    for (var _iterator = _retailPaymentDevice.PaymentDevice.devices, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
      var _ref;

      if (_isArray) {
        if (_i >= _iterator.length) break;
        _ref = _iterator[_i++];
      } else {
        _i = _iterator.next();
        if (_i.done) break;
        _ref = _i.value;
      }

      var device = _ref;

      if (device.manufacturer.toUpperCase() === _retailPaymentDevice.deviceManufacturer.miura) {
        return true;
      }
    }
    return false;
  };

  DeviceSelector.prototype.promptDevicesToSelect = function promptDevicesToSelect() {
    this._promptForDeviceSelection(function () {});
  };

  DeviceSelector.prototype._startDeviceSelection = function _startDeviceSelection() {
    var _this3 = this;

    Log.debug(function () {
      return '_startDeviceSelection started. the current selected device: ' + _this3._selectedPaymentDevice;
    });
    if (!this._selectedPaymentDevice) {
      // whenever it is null, go for selection step.
      this._promptForDeviceSelection();
    } else if (!this._selectedPaymentDevice.cardPresented) {
      this._promptForDeviceSelection();
    } else {
      this._setSelectedDevice(this._selectedPaymentDevice);
      Log.info('Will not prompt for device selection due to one of the reasons. Device already selected? \'' + !!this._selectedPaymentDevice + '\', Payment in progress? \'' + (this._selectedPaymentDevice && this._selectedPaymentDevice.cardPresented) + '\'');
    }
  };

  DeviceSelector.prototype.selectDevice = function selectDevice(id) {
    var found, _iterator2, _isArray2, _i2, _ref2, device;

    return regeneratorRuntime.async(function selectDevice$(_context) {
      while (1) {
        switch (_context.prev = _context.next) {
          case 0:
            if (id) {
              _context.next = 4;
              break;
            }

            _context.next = 3;
            return regeneratorRuntime.awrap(this._promptForDeviceSelection());

          case 3:
            return _context.abrupt('return');

          case 4:
            found = false;
            _iterator2 = _retailPaymentDevice.PaymentDevice.devices, _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();

          case 6:
            if (!_isArray2) {
              _context.next = 12;
              break;
            }

            if (!(_i2 >= _iterator2.length)) {
              _context.next = 9;
              break;
            }

            return _context.abrupt('break', 21);

          case 9:
            _ref2 = _iterator2[_i2++];
            _context.next = 16;
            break;

          case 12:
            _i2 = _iterator2.next();

            if (!_i2.done) {
              _context.next = 15;
              break;
            }

            return _context.abrupt('break', 21);

          case 15:
            _ref2 = _i2.value;

          case 16:
            device = _ref2;

            /*
            In case of MCR, call abort on the all other devices and update the display for each
            of them.
             */
            if (device.id === id && device.isConnected()) {
              found = true;
              this._setSelectedDevice(device);
              this._selectedPaymentDevice.emit(_retailPaymentDevice.PaymentDevice.Event.selected, this._selectedPaymentDevice);
              Log.info('selected device with id ==>> ' + this._selectedPaymentDevice.id);
            } else {
              device.abortTransaction();
            }
            this._displayReadyMsg();

          case 19:
            _context.next = 6;
            break;

          case 21:
            if (!found) {
              Log.info('NO device is found with id ==>> ' + id + ' or it is disconnected');
            }

          case 22:
          case 'end':
            return _context.stop();
        }
      }
    }, null, this);
  };

  DeviceSelector.prototype._promptForDeviceSelection = function _promptForDeviceSelection() {
    var _this4 = this;

    var connectedDevices, _loop, _iterator3, _isArray3, _i3, _ref3, _ret;

    return regeneratorRuntime.async(function _promptForDeviceSelection$(_context2) {
      while (1) {
        switch (_context2.prev = _context2.next) {
          case 0:
            Log.debug(function () {
              return 'total number of devices is  ' + _retailPaymentDevice.PaymentDevice.devices.length;
            });
            if (this.alert) {
              this.alert.dismiss();
            }
            connectedDevices = [];

            _loop = function _loop() {
              if (_isArray3) {
                if (_i3 >= _iterator3.length) return 'break';
                _ref3 = _iterator3[_i3++];
              } else {
                _i3 = _iterator3.next();
                if (_i3.done) return 'break';
                _ref3 = _i3.value;
              }

              var device = _ref3;

              if (device.isConnected()) {
                Log.debug(function () {
                  return 'connected device:' + device.id;
                });
                connectedDevices.push(device);
              }
            };

            _iterator3 = _retailPaymentDevice.PaymentDevice.devices, _isArray3 = Array.isArray(_iterator3), _i3 = 0, _iterator3 = _isArray3 ? _iterator3 : _iterator3[Symbol.iterator]();

          case 5:
            _ret = _loop();

            if (!(_ret === 'break')) {
              _context2.next = 8;
              break;
            }

            return _context2.abrupt('break', 10);

          case 8:
            _context2.next = 5;
            break;

          case 10:
            Log.debug(function () {
              return 'total number of connected devices is  ' + connectedDevices.length;
            });
            if (connectedDevices.length <= 0) {
              this._setSelectedDevice(null);
              Log.info('No device is selected since there is no available device');
            } else if (connectedDevices.length === 1) {
              if (this._selectedPaymentDevice !== connectedDevices[0]) {
                if (this._selectedPaymentDevice) {
                  this._selectedPaymentDevice.abortTransaction();
                }
                this._setSelectedDevice(connectedDevices[0]);
                Log.info('Selected device set to ' + this._selectedPaymentDevice.id);
                _manticore2.default.setTimeout(function () {
                  if (_this4._selectedPaymentDevice) {
                    _this4._selectedPaymentDevice.emit(_retailPaymentDevice.PaymentDevice.Event.selected);
                  }
                }, 0);
                this._displayReadyMsg();
              } else {
                Log.info('SAME device selected by default ==>> ' + this._selectedPaymentDevice.id);
                this._setSelectedDevice(this._selectedPaymentDevice);
              }
            } else if (connectedDevices.length > 1) {
              Log.error('There should NOT be ' + connectedDevices.length + ' connected devices more than 1!!!');
            }

          case 12:
          case 'end':
            return _context2.stop();
        }
      }
    }, null, this);
  };

  DeviceSelector.prototype._displayReadyMsg = function _displayReadyMsg() {
    for (var _iterator4 = _retailPaymentDevice.PaymentDevice.devices, _isArray4 = Array.isArray(_iterator4), _i4 = 0, _iterator4 = _isArray4 ? _iterator4 : _iterator4[Symbol.iterator]();;) {
      var _ref4;

      if (_isArray4) {
        if (_i4 >= _iterator4.length) break;
        _ref4 = _iterator4[_i4++];
      } else {
        _i4 = _iterator4.next();
        if (_i4.done) break;
        _ref4 = _i4.value;
      }

      var _device = _ref4;

      if (_device.model === _retailPaymentDevice.ReaderModel.M010) {
        var displayParams = {
          id: _retailPaymentDevice.PaymentDevice.Message.NotReady,
          displaySystemIcons: true
        };
        if (_device !== this._selectedPaymentDevice) {
          _device.display(displayParams);
        } else {
          displayParams.id = _retailPaymentDevice.PaymentDevice.Message.ReadyWithId;
          displayParams.substitutions = { id: _device.id };
          _CardReaderDisplayController2.default.display(_displayPriority2.default.low, _device, displayParams);
        }
      }
    }
  };

  _createClass(DeviceSelector, [{
    key: 'selectedDevice',
    get: function get() {
      return this._selectedPaymentDevice;
    },
    set: function set(value) {
      throw new Error('The readOnly selectedPaymentDevice property cannot be written. ' + value + ' was passed.');
    }
  }]);

  return DeviceSelector;
}();

var deviceSelector = new DeviceSelector();
exports.default = deviceSelector;

},{"./CardReaderDisplayController":"/Users/aravidas/Documents/Git/retail-sdk/js/paymentDevice/CardReaderDisplayController.js","./displayPriority":"/Users/aravidas/Documents/Git/retail-sdk/js/paymentDevice/displayPriority.js","manticore":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore/browser.js","manticore-log":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-log/index.js","retail-payment-device":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/js/paymentDevice/DiscoveredCardReader.js":[function(require,module,exports){
"use strict";

exports.__esModule = true;

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

/* eslint-disable no-useless-constructor,no-empty-function */
/**
 * DiscoveredCardReader class contains the device info discovered from DeviceScanner to be shown on the UI
 * @class
 * @property {string} readerId Card reader name as it shows up in the bluetooth settings page
 * @property {string} readerDescription Card reader description
 * @property {string} readerImgId Image identifier
 * @property {bool} isConnected status of the device
 */
var DiscoveredCardReader =
/**
 * @constructor
 */
function DiscoveredCardReader() {
  _classCallCheck(this, DiscoveredCardReader);
};

/* eslint-enable no-useless-constructor,no-empty-function */


exports.default = DiscoveredCardReader;

},{}],"/Users/aravidas/Documents/Git/retail-sdk/js/paymentDevice/MagtekRawUsbReaderDevice.js":[function(require,module,exports){
(function (Buffer){
'use strict';

exports.__esModule = true;

var _retailPaymentDevice = require('retail-payment-device');

var _manticoreLog = require('manticore-log');

var _manticoreLog2 = _interopRequireDefault(_manticoreLog);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (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 } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var Log = (0, _manticoreLog2.default)('paymentDevice.magtekRawUsbReaderDevice');

function getMagnetPrint(swipe, buf) {
  swipe.magneprint = {
    status: buf.slice(344, 347).toString('hex'),
    length: buf[348]
  };
  if (swipe.magneprint.length) {
    swipe.magneprint.data = buf.slice(349, 349 + swipe.magneprint.length).toString('hex');
  }
}

function getTracks(swipe, buf) {
  var track1ok = (buf[0] & 0x1) === 0;
  var track2ok = (buf[1] & 0x1) === 0;
  var track3ok = (buf[2] & 0x1) === 0;
  var track1length = buf[3];
  var track2length = buf[4];
  var track3length = buf[5];

  if (track1ok && track1length) {
    swipe.track1 = buf.slice(7, 7 + track1length).toString('hex');
  }
  if (track2ok && track2length) {
    swipe.track2 = buf.slice(119, 119 + track2length).toString('hex');
  }
  if (track3ok && track3length) {
    swipe.track3 = buf.slice(231, 231 + track3length).toString('hex');
  }
}

function magtekVersion1(swipe, buf) {
  // http://www.magtek.com/documentation/public/99875338-3.01.pdf
  swipe.counter = buf.slice(493, 500).toString('hex');
  swipe.crypto = {
    enabled: (buf[501] & 0x1) === 0x1,
    keyInjected: (buf[501] & 0x2) === 0x2
  };
  if (buf[501] & 0x4) {
    swipe.crypto.keysExhausted = true;
    Log.error('DUKPT keys exhausted on Magtek reader.');
  }
  swipe.ksn = buf.slice(555, 565).toString('hex');
}

function magtekVersion2(swipe, buf) {
  // http://www.magtek.com/documentation/public/99875474-10.01.pdf, except it's not up
  swipe.counter = buf.slice(856, 858).toString('hex');
  swipe.crypto = {
    enabled: (buf[494] & 0x4) === 0x4,
    keyInjected: (buf[494] & 0x2) === 0x2
  };
  if (buf[494] & 0x1) {
    swipe.crypto.keysExhausted = true;
    Log.error('DUKPT keys exhausted on Magtek reader.');
  }
  swipe.ksn = buf.slice(495, 505).toString('hex');
  swipe.counter = buf.slice(856, 858).toString('hex');

  var maskedLen = buf[505];
  if (maskedLen) {
    swipe.track1masked = buf.slice(508, 508 + maskedLen).toString('ascii');
  }
  maskedLen = buf[506];
  if (maskedLen) {
    swipe.track2masked = buf.slice(620, 620 + maskedLen).toString('ascii');
  }
  maskedLen = buf[507];
  if (maskedLen) {
    swipe.track3masked = buf.slice(732, 732 + maskedLen).toString('ascii');
  }
}

/**
 * Specialization of card reader that does its own interpretation of USB data
 */

var MagtekRawUsbReaderDevice = function (_MagneticReaderDevice) {
  _inherits(MagtekRawUsbReaderDevice, _MagneticReaderDevice);

  function MagtekRawUsbReaderDevice(uniqueName, native) {
    _classCallCheck(this, MagtekRawUsbReaderDevice);

    var _this = _possibleConstructorReturn(this, _MagneticReaderDevice.call(this, uniqueName, native));

    _this.manufacturer = 'Magtek';
    return _this;
  }

  MagtekRawUsbReaderDevice.prototype.received = function received(event) {
    try {
      var buf = new Buffer(event, 'base64');
      if (buf.length < 565) {
        Log.error('Invalid MagTek data length: ' + buf.length);
        return;
      }

      var card = new _retailPaymentDevice.MagneticCard();
      card.formFactor = _retailPaymentDevice.FormFactor.MagneticCardSwipe;
      card.reader = this;
      getTracks(card, buf);
      getMagnetPrint(card, buf);

      if (this.productId === 0x0E || buf.length === 565) {
        magtekVersion1(card, buf);
      } else if (this.productId === 0x11 || buf.length === 887) {
        magtekVersion2(card, buf);
      }

      if (!this.serialNumber && card.ksn) {
        // Magtek serial is first 14 of ksn. For some reason this doesn't match serial
        // reported in the packet.
        this.serialNumber = card.ksn.substring(0, 14);
      }

      _MagneticReaderDevice.prototype.received.call(this, card);
    } catch (x) {
      Log.error('Failed to parse Magtek card event: ' + x.message + '\n' + x.stack);
    }
  };

  return MagtekRawUsbReaderDevice;
}(_retailPaymentDevice.MagneticReaderDevice);

exports.default = MagtekRawUsbReaderDevice;

}).call(this,require("buffer").Buffer)
},{"buffer":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/buffer/index.js","manticore-log":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-log/index.js","retail-payment-device":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/js/paymentDevice/RoamSwiper/CardStatus.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

var _retailPaymentDevice = require('retail-payment-device');

var _manticoreLog = require('manticore-log');

var _manticoreLog2 = _interopRequireDefault(_manticoreLog);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

var Log = (0, _manticoreLog2.default)('RoamSwiper.cardStatus');

/**
 * Contain the details of card events on the Roam swiper such as
 * swipe, etc.
 */

var CardStatus = function () {
  function CardStatus(cardResponse) {
    _classCallCheck(this, CardStatus);

    this.response = cardResponse;

    try {
      var secureData = this.response.secureData;
      this.track1 = secureData.track1;
      this.track2 = secureData.track2;
      this.ksn = secureData.ksn;
      this.type = secureData.type;
      this.lastFour = secureData.lastFour;
      this.firstFour = secureData.firstFour;
    } catch (err) {
      Log.error('Roam swiper secure data Json parse Failed: ' + err);
    }
  }

  CardStatus.prototype.getPresentedCard = function getPresentedCard(reader) {
    var card = new _retailPaymentDevice.MagneticCard();
    var track = this.track1 || this.track2;
    card.formFactor = _retailPaymentDevice.FormFactor.MagneticCardSwipe;
    card.ksn = this.ksn ? this.ksn.toString('hex') : '';
    card.reader = reader;

    if (!track || !track.length) {
      Log.error('Missing track  from roam card swipe data');
      card.failed = true;
      return card;
    }

    card.track1 = this.track1;
    card.track2 = this.track2;
    card.lastFourDigits = this.lastFour;
    card.cardIssuer = this.response.CardIssuer;
    card.isSignatureRequired = false;
    if (this.response.IsSignatureRequired === 'true') {
      card.isSignatureRequired = true;
    }
    card.cardholderName = this.response.CardHolderName;

    return card;
  };

  CardStatus.prototype.toString = function toString() {
    var parts = [this.response.toString(), '\nChip flags ', this.chipFlags.toString(16), ' Magstripe flags ', this.magstripeFlags.toString(16)];
    if (this.ksn) {
      parts.push('\nKSN: ');
      parts.push(this.ksn.toString('hex'));
    }
    if (this.track1) {
      parts.push('\nTrack 1: ');
      parts.push(this.track1.toString('hex'));
    }
    if (this.track2) {
      parts.push('\nTrack 2: ');
      parts.push(this.track2.toString('hex'));
    }
    if (this.maskedTrack2) {
      parts.push('\nMasked Track 2: ');
      parts.push(this.maskedTrack2);
    }
    if (this.sredData) {
      parts.push('\nSRED: ');
      parts.push(this.sredData.toString('hex'));
    }

    return parts.join('');
  };

  return CardStatus;
}();

exports.default = CardStatus;

},{"manticore-log":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-log/index.js","retail-payment-device":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/js/paymentDevice/RoamSwiper/Parser.js":[function(require,module,exports){
(function (Buffer){
'use strict';

exports.__esModule = true;

var _retailPaymentDevice = require('retail-payment-device');

var _manticoreLog = require('manticore-log');

var _manticoreLog2 = _interopRequireDefault(_manticoreLog);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

var Log = (0, _manticoreLog2.default)('RoamSwiper.Parser');

/**
 * Contain the details of card events on the Roam swiper such as
 * swipe, etc.
 */

var Parser = function () {
  function Parser() {
    _classCallCheck(this, Parser);
  }

  Parser.prototype.getCardInfo = function getCardInfo(rawData) {
    var cardInfo = {};
    try {
      var data = rawData.decodeData;
      var decodeData = Buffer.isBuffer(data) ? data : new Buffer(data, 'base64');
      var decodeJsonData = JSON.parse(decodeData.toString('ascii'));

      cardInfo.secureData = {};
      cardInfo.secureData.track1 = rawData.track1;
      cardInfo.secureData.serial = decodeJsonData.ksn;
      cardInfo.secureData.ksn = decodeJsonData.ksn;
      cardInfo.secureData.type = 'ROAM';
      cardInfo.secureData.firstFour = null;
      cardInfo.secureData.lastFour = null;
      if (typeof decodeJsonData.maskedPAN === 'string' || decodeJsonData.maskedPAN instanceof String) {
        var len = decodeJsonData.maskedPAN.length;
        cardInfo.secureData.firstFour = decodeJsonData.maskedPAN.substring(0, 4);
        cardInfo.secureData.lastFour = decodeJsonData.maskedPAN.substring(len - 4, len);
        cardInfo.firstFour = cardInfo.secureData.firstFour;
        cardInfo.lastFour = cardInfo.secureData.lastFour;
      }
      cardInfo.CVV = null;
      cardInfo.ExpiryDate = null;
      cardInfo.PostalCode = null;
      cardInfo.IsSignatureRequired = false;
      cardInfo.WasPinRequired = false;

      // The cardholderName has the format : lastname/firstname
      var firstName = '';
      var lastName = '';
      if (decodeJsonData.cardholderName && decodeJsonData.cardholderName.indexOf('/') > -1) {
        var name = decodeJsonData.cardholderName.split('/');
        lastName = name[0];
        firstName = name[1];
      } else {
        firstName = decodeJsonData.cardholderName;
      }
      cardInfo.CardHolderName = firstName + ' ' + lastName;
      cardInfo.CardIssuer = _retailPaymentDevice.CardDataUtil.getCardIssuerFromCardNumber(cardInfo.firstFour);

      Log.debug(function () {
        return 'cardInfo : ' + JSON.stringify(cardInfo, null, 2);
      });
    } catch (err) {
      Log.error('Roam Swiper Parser throws ' + err);
    }
    return cardInfo;
  };

  return Parser;
}();

exports.default = Parser;

}).call(this,require("buffer").Buffer)
},{"buffer":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/buffer/index.js","manticore-log":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-log/index.js","retail-payment-device":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/js/paymentDevice/RoamSwiperDevice.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

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; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

var _retailPaymentDevice = require('retail-payment-device');

var _manticoreLog = require('manticore-log');

var _manticoreLog2 = _interopRequireDefault(_manticoreLog);

var _Parser = require('./RoamSwiper/Parser');

var _Parser2 = _interopRequireDefault(_Parser);

var _CardStatus = require('./RoamSwiper/CardStatus');

var _CardStatus2 = _interopRequireDefault(_CardStatus);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (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 } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var Log = (0, _manticoreLog2.default)('roamSwiperDevice');

/**
 * Represents a payment swiper device manufactured by Roam for PayPal
 * @class
 * @protected
 */

var RoamSwiperDevice = function (_PaymentDevice) {
  _inherits(RoamSwiperDevice, _PaymentDevice);

  /**
   * Construct a new PaymentDevice given a native function capable of sending data to the device
   */
  function RoamSwiperDevice(uniqueId, nativeInterface, appInterface, isUsb) {
    var address = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 'RoamSwiper';

    _classCallCheck(this, RoamSwiperDevice);

    var _this = _possibleConstructorReturn(this, _PaymentDevice.call(this, uniqueId, nativeInterface, appInterface, isUsb, address));

    _this.manufacturer = _retailPaymentDevice.deviceManufacturer.roam;
    _this.model = _retailPaymentDevice.ReaderModel.Swiper;
    _this.parser = new _Parser2.default();
    _this.type = _retailPaymentDevice.readerType.Magstripe;
    _this.connectionType = _retailPaymentDevice.readerConnectionType.AudioJack;
    return _this;
  }

  RoamSwiperDevice.prototype.beginDeviceRemoved = function beginDeviceRemoved(callback) {
    this.native.removed(callback);
  };

  RoamSwiperDevice.prototype.beginDeviceConnect = function beginDeviceConnect(callback) {
    var _this2 = this;

    if (this.native.isConnected()) {
      Log.debug(function () {
        return 'Connect called, but ' + _this2.id + ' is already connected.';
      });
      callback();
      return;
    }

    Log.debug(function () {
      return 'Connecting to Roam swiper device ' + _this2.id;
    });
    this.native.connect(function (error) {
      if (error) {
        callback(error);
        return;
      }
      callback();
    });
  };

  RoamSwiperDevice.prototype.listenForCardRemoval = function listenForCardRemoval(callback) {
    callback();
  };

  RoamSwiperDevice.prototype.beginDeviceDisconnect = function beginDeviceDisconnect(callback) {
    if (!this.isConnected()) {
      Log.debug('Device already disconnected. Will not attempt to invoke native.disconnect');
      if (callback) {
        callback(null);
      }
      return;
    }

    this.native.disconnect(callback);
  };

  RoamSwiperDevice.prototype.receivedKsn = function receivedKsn(ksn) {
    Log.info('Received KSN for ' + this.id + ': ' + ksn);
    this.setCardReaderToMerchant(ksn);
  };

  RoamSwiperDevice.prototype.received = function received(rawData) {
    try {
      var cardInfo = this.parser.getCardInfo(rawData);
      var card = new _CardStatus2.default(cardInfo).getPresentedCard(this);
      this.transactionActive = true;
      Log.debug(function () {
        return 'RoamSwiper received ' + card;
      });
      this.emit(_retailPaymentDevice.PaymentDevice.Event.cardPresented, null, _retailPaymentDevice.CardPresentEvent.cardDataRead, _retailPaymentDevice.FormFactor.MagneticCardSwipe, { card: card });
    } catch (err) {
      Log.error('RoamSwiper received throw ' + err);
    }
  };

  RoamSwiperDevice.prototype.send = function send(data, cb) {
    this.native.send(data, cb);
  };

  RoamSwiperDevice.prototype.display = function display(opt, callback) {
    if (!this.isConnected()) {
      if (callback) {
        callback(_retailPaymentDevice.deviceError.deviceNotConnected);
      }
      return;
    }

    if (callback) {
      callback();
    }
  };

  RoamSwiperDevice.prototype.getFirmwareVersionInfo = function getFirmwareVersionInfo(callback) {
    Log.warn('there is no way to know the firmware version info of  RoamSwiper!');

    if (callback) {
      callback();
    }
  };

  RoamSwiperDevice.prototype.activateForPayment = function activateForPayment(context) {
    Log.debug('activate roam swiper for payment');
    _PaymentDevice.prototype.activateForPayment.call(this, context, [_retailPaymentDevice.FormFactor.MagneticCardSwipe]);
    this.send('listenForCardEvents', function (err) {
      if (err) {
        Log.error('Failed to register for Roam keyboard events: ' + err.message);
      } else {
        Log.debug('Sent listenForCardEvents');
      }
    });
  };

  RoamSwiperDevice.prototype.getBatteryInfo = function getBatteryInfo(callback) {
    if (callback) {
      callback(null, new _retailPaymentDevice.BatteryInfo(100, false, new Date(), _retailPaymentDevice.batteryStatus.unknown));
    }
  };

  RoamSwiperDevice.prototype.deactivateFormFactors = function deactivateFormFactors(formFactors, callback) {
    var _this3 = this;

    Log.debug(function () {
      return 'Deactivating form factors [' + formFactors + '] on \'' + _this3.id + '\'';
    });
    if (!formFactors || formFactors.length === 0) {
      if (callback) {
        callback();
      }
      return;
    }
    _PaymentDevice.prototype.deactivateFormFactors.call(this, formFactors);
    var sFormFactors = new Set(formFactors);
    if (sFormFactors.has(_retailPaymentDevice.FormFactor.MagneticCardSwipe)) {
      this.send('stopListeningForCardEvents', function (err) {
        if (err) {
          Log.error('Failed to stop listening for Roam swiper events: ' + err.message);
        } else {
          Log.debug('Sent stopListeningForCardEvents');
        }

        if (callback) {
          callback(err);
        }
      });
      return;
    }
    Log.debug('Ignoring deactivate request as supported form factor not received');
    if (callback) {
      callback();
    }
  };

  RoamSwiperDevice.prototype.abortTransaction = function abortTransaction(context, cb) {
    var _this4 = this;

    Log.info(function () {
      return 'Deactivating ' + _this4.id + ' with ' + (_this4.cardPresented ? 'an active transaction.' : 'NO active transaction.');
    });
    _PaymentDevice.prototype.abortTransaction.call(this, context);
    if (cb) {
      cb();
    }
  };

  RoamSwiperDevice.prototype.completeTransaction = function completeTransaction(authCode, cb) {
    this.transactionActive = false;
    Log.debug(function () {
      return 'Roam swiper completeTransaction';
    });
    if (cb) {
      cb();
    }
  };

  RoamSwiperDevice.prototype.postTransactionCleanup = function postTransactionCleanup(callback) {
    Log.debug(function () {
      return 'Roam swiper postTransactionCleanup';
    });
    if (callback) {
      callback();
    }
  };

  _createClass(RoamSwiperDevice, [{
    key: 'formFactors',
    get: function get() {
      return _retailPaymentDevice.FormFactor.MagneticCardSwipe;
    }
  }]);

  return RoamSwiperDevice;
}(_retailPaymentDevice.PaymentDevice);

exports.default = RoamSwiperDevice;

},{"./RoamSwiper/CardStatus":"/Users/aravidas/Documents/Git/retail-sdk/js/paymentDevice/RoamSwiper/CardStatus.js","./RoamSwiper/Parser":"/Users/aravidas/Documents/Git/retail-sdk/js/paymentDevice/RoamSwiper/Parser.js","manticore-log":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-log/index.js","retail-payment-device":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/js/paymentDevice/displayPriority.js":[function(require,module,exports){
"use strict";

exports.__esModule = true;
/**
 * Display priority. Currently, the following three priorities are sufficient, but rework on the enum scheme if more
 * enum values are required
 * @type {{low: number, medium: number, high: number}}
 */
var displayPriority = {
  low: 1,
  medium: 2,
  high: 3
};

exports.default = displayPriority;

},{}],"/Users/aravidas/Documents/Git/retail-sdk/js/paymentDevice/index.js":[function(require,module,exports){
'use strict';

var _miuraEmv = require('miura-emv');

var _miuraEmv2 = _interopRequireDefault(_miuraEmv);

var _DeviceBuilder = require('./DeviceBuilder');

var _DeviceBuilder2 = _interopRequireDefault(_DeviceBuilder);

var _RoamSwiperDevice = require('./RoamSwiperDevice');

var _RoamSwiperDevice2 = _interopRequireDefault(_RoamSwiperDevice);

var _DeviceScanner = require('./DeviceScanner');

var _DeviceScanner2 = _interopRequireDefault(_DeviceScanner);

var _DiscoveredCardReader = require('./DiscoveredCardReader');

var _DiscoveredCardReader2 = _interopRequireDefault(_DiscoveredCardReader);

var _CardReaderScanAndDiscoverOptions = require('./CardReaderScanAndDiscoverOptions');

var _CardReaderScanAndDiscoverOptions2 = _interopRequireDefault(_CardReaderScanAndDiscoverOptions);

var _MagtekRawUsbReaderDevice = require('./MagtekRawUsbReaderDevice');

var _MagtekRawUsbReaderDevice2 = _interopRequireDefault(_MagtekRawUsbReaderDevice);

var _ingenicoEmv = require('../ingenico-emv');

var _ingenicoEmv2 = _interopRequireDefault(_ingenicoEmv);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

module.exports = {
  DeviceBuilder: _DeviceBuilder2.default,
  MiuraDevice: _miuraEmv2.default,
  MagtekRawUsbReaderDevice: _MagtekRawUsbReaderDevice2.default,
  RoamSwiperDevice: _RoamSwiperDevice2.default,
  IngenicoDevice: _ingenicoEmv2.default,
  DeviceScanner: _DeviceScanner2.default,
  DiscoveredCardReader: _DiscoveredCardReader2.default,
  CardReaderScanAndDiscoverOptions: _CardReaderScanAndDiscoverOptions2.default
};

},{"../ingenico-emv":"/Users/aravidas/Documents/Git/retail-sdk/js/ingenico-emv/index.js","./CardReaderScanAndDiscoverOptions":"/Users/aravidas/Documents/Git/retail-sdk/js/paymentDevice/CardReaderScanAndDiscoverOptions.js","./DeviceBuilder":"/Users/aravidas/Documents/Git/retail-sdk/js/paymentDevice/DeviceBuilder.js","./DeviceScanner":"/Users/aravidas/Documents/Git/retail-sdk/js/paymentDevice/DeviceScanner.js","./DiscoveredCardReader":"/Users/aravidas/Documents/Git/retail-sdk/js/paymentDevice/DiscoveredCardReader.js","./MagtekRawUsbReaderDevice":"/Users/aravidas/Documents/Git/retail-sdk/js/paymentDevice/MagtekRawUsbReaderDevice.js","./RoamSwiperDevice":"/Users/aravidas/Documents/Git/retail-sdk/js/paymentDevice/RoamSwiperDevice.js","miura-emv":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/build/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/js/sdk.js":[function(require,module,exports){
(function (Buffer){
'use strict';

var _manticoreLog = require('manticore-log');

var _manticoreLog2 = _interopRequireDefault(_manticoreLog);

var _events = require('events');

var _retailPaymentDevice = require('retail-payment-device');

var _manticore = require('manticore');

var _manticore2 = _interopRequireDefault(_manticore);

var _retailPageTracker = require('retail-page-tracker');

var _sdkErrors = require('./common/sdkErrors');

var _TransactionContext = require('./transaction/TransactionContext');

var _TransactionContext2 = _interopRequireDefault(_TransactionContext);

var _Merchant = require('./common/Merchant');

var _Merchant2 = _interopRequireDefault(_Merchant);

var _cal = require('./common/cal');

var Cal = _interopRequireWildcard(_cal);

var _Features = require('./common/Features');

var _Features2 = _interopRequireDefault(_Features);

var _networkInterceptor = require('./common/NetworkHandler/networkInterceptor');

var _networkInterceptor2 = _interopRequireDefault(_networkInterceptor);

var _DeviceManager = require('./transaction/DeviceManager');

var _DeviceManager2 = _interopRequireDefault(_DeviceManager);

var _TransactionManager = require('./transaction/TransactionManager');

var _TransactionManager2 = _interopRequireDefault(_TransactionManager);

var _logLevel = require('./common/logLevel');

var _logLevel2 = _interopRequireDefault(_logLevel);

var _package = require('../package.json');

var _package2 = _interopRequireDefault(_package);

var _CardReaderDisplayController = require('./paymentDevice/CardReaderDisplayController');

var _CardReaderDisplayController2 = _interopRequireDefault(_CardReaderDisplayController);

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (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 } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } // PLEASE NOTE! This is a bit of a funny class on the native side. It exposes top level
// events and methods (maybe properties someday too) but it is not directly exposed
// to partners. Instead, they are presented with a "singleton" type interface typically called
// PayPalRetailSDK. Then the methods/events/properties of THIS object are proxied via that singleton
// to the instance that the engine startup process makes.
// SO.... this means a few unpleasant things that were deemed ok for now:
//      1. If you change comments here, you will need to manually update PayPalRetailSDK in each platform
//      2. If you change or add events or methods here you will need to update each platform
//      3. Because of 1 and 2, ask yourself - does my event/property REALLY belong at the top level?

// eslint-disable-line no-duplicate-imports, import/no-duplicates
// eslint-disable-line no-duplicate-imports, import/no-duplicates


var Log = (0, _manticoreLog2.default)('sdk');

/**
 * The PayPal Here SDK object is the main entry point for all SDK operations. Because we provide
 * native-specific versions of the highest level interface, this class is essentially used
 * as a helper for binding top level events (such as a new card reader) to the native partner objects.
 * @protected
 * @class
 */

var SDK = function (_EventEmitter) {
  _inherits(SDK, _EventEmitter);

  function SDK() {
    _classCallCheck(this, SDK);

    var _this = _possibleConstructorReturn(this, _EventEmitter.call(this));

    _retailPaymentDevice.PaymentDevice.Events.on(SDK.Event.deviceDiscovered, function (d) {
      return _this.emit(SDK.Event.deviceDiscovered, d);
    });
    _retailPageTracker.Tracker.events.on('pageViewed', function (err, page) {
      return _this.emit(SDK.Event.pageViewed, err, page);
    });
    _Features2.default.loadRemoteFeatureMap();
    _this.setupCalLogging();
    return _this;
  }

  SDK.prototype.setupCalLogging = function setupCalLogging() {
    Cal.newGroup(Date.now());
    var flushLogs = function flushLogs() {
      var pauseAndFlush = function pauseAndFlush() {
        return _manticore2.default.setTimeout(flushLogs, 10 * 1000);
      };
      if (_Merchant2.default.active) {
        Cal.flush(function (err, count) {
          if (count || err) {
            Log.debug(function () {
              return 'Flushed ' + (count || 0) + ' cal log messages. ' + (err ? 'Error: ' + err : '');
            });
          }
          pauseAndFlush();
        });
      } else {
        pauseAndFlush();
      }
    };

    Cal.attach(flushLogs);
  };

  SDK.prototype.buildCompositeToken = function buildCompositeToken(tokenObj) {
    Log.debug(function () {
      return 'Received composite token ' + JSON.stringify(tokenObj);
    });
    if (!tokenObj) {
      throw _sdkErrors.merchant.tokenDataNotProvided;
    }
    if (!tokenObj.accessToken) {
      throw _sdkErrors.merchant.accessTokenNotProvided;
    }
    if (!tokenObj.environment) {
      throw _sdkErrors.merchant.environmentNotProvided;
    }

    tokenObj.environment = tokenObj.environment.toLowerCase();
    var appIdSecret = new Buffer(tokenObj.appId + ':' + tokenObj.appSecret).toString('base64');
    var tokenParts = [tokenObj.accessToken, 28880, tokenObj.refreshUrl, tokenObj.refreshToken, appIdSecret];
    return tokenObj.environment + ':' + new Buffer(JSON.stringify(tokenParts)).toString('base64');
  };

  SDK.prototype.initializeMerchant = function initializeMerchant(token, repository, callback) {
    var _this2 = this;

    new _Merchant2.default().initialize(token, repository, function (e, m) {
      if (!e && m) {
        _this2.emit('merchantInitialized', m);
      }
      callback(e, m);
    });
  };

  SDK.prototype.error = function error(message) {
    return new Error(message);
  };

  SDK.prototype.setMerchant = function setMerchant(merchantObj) {
    Log.debug(function () {
      return 'Received the merchant object : ' + JSON.stringify(merchantObj);
    });
    if (!merchantObj) {
      throw _sdkErrors.merchant.merchantDataNotProvided;
    }
    merchantObj.compositeToken = this.buildCompositeToken(merchantObj.token);
    return new _Merchant2.default(merchantObj);
  };

  /**
   * Get the active merchant
   * @returns {Merchant} merchant
   */


  SDK.prototype.getMerchant = function getMerchant() {
    return _Merchant2.default.active;
  };

  /*
   * Create a transaction context for an invoice
   * @param {Invoice} invoice
   * @returns {TransactionContext} context
   */


  SDK.prototype.createTransaction = function createTransaction(invoice) {
    if (!_Merchant2.default.active) {
      throw _sdkErrors.merchant.notInitialized.withDevMessage('You must have an active merchant to create a transaction.' + 'Call InitializeMerchant first, and wait for it to complete.');
    }
    return new _TransactionContext2.default(invoice, _Merchant2.default.active);
  };

  /**
   * Log a message via the Javascript logging framework (called by native to get all the side benefits of JS logging, like CAL)
   * @param {string} level
   * @param {string} component
   * @param {string} message
   * @param {object} extraData
   */


  SDK.prototype.logViaJs = function logViaJs(level, component, message, extraData) {
    // eslint-disable-line no-unused-vars
    try {
      (0, _manticoreLog2.default)(component)[level](message);
    } catch (x) {
      Log.debug('Failed to log native message: ' + level + ' ' + component + ' ' + message);
    }
  };

  /**
   * Information that represents the executing platform
   * @param {SdkEnvironmentInfo} sdkEnvInfo Executing environment info
   */


  SDK.prototype.setExecutingEnvironment = function setExecutingEnvironment(sdkEnvInfo) {
    this.envInfo = (sdkEnvInfo.osName + '-' + sdkEnvInfo.osVersion + ';app-' + sdkEnvInfo.appVersion + '-' + sdkEnvInfo.appBuild + ';.sdk-' + _package2.default.version + '.m-' + sdkEnvInfo.merchantId).replace(/\s+/g, '');
    Cal.setRequestSourceId(this.envInfo);
    // The apiUserAgent must ONLY be used for API calls made to PayPal Here Services
    _Merchant2.default.apiUserAgent = 'pph_sdk_v' + _package2.default.version + '-' + sdkEnvInfo.osName + '_' + sdkEnvInfo.osVersion + '-' + sdkEnvInfo.appName + '_v' + sdkEnvInfo.appVersion + '_' + sdkEnvInfo.appBuild + (sdkEnvInfo.merchantId ? '-' + sdkEnvInfo.merchantId : '');
    Log.info('Setting RetailSDK executing environment to: ' + this.envInfo + ' and userAgent to ' + _Merchant2.default.apiUserAgent);
  };

  /*
   * Register a PaymentDevice and notify listeners of the new device.
   * @param {PaymentDevice} pd
   */


  SDK.prototype.discoveredPaymentDevice = function discoveredPaymentDevice(pd) {
    _retailPaymentDevice.PaymentDevice.discovered(pd);
  };

  /*
   * Perform cleanup before shutting down the host application
   */


  SDK.prototype.logout = function logout() {
    try {
      Log.info('SDK logout was invoked. Active Transaction: ' + (_TransactionContext2.default.active ? _TransactionContext2.default.active.id : '<none>') + '. Connected devices: ' + _retailPaymentDevice.PaymentDevice.devices);
      _CardReaderDisplayController2.default.resetAll();
      if (_TransactionContext2.default.active) {
        Log.info('Ending ' + _TransactionContext2.default.active.id + ' as part of user SDK logout');
        _TransactionContext2.default.active.end(_sdkErrors.sdk.userCancelled, null, false);
      }
      if (_Merchant2.default.active) {
        Log.info('Ending Merchant ' + _Merchant2.default.active + ' as part of user SDK logout');
        _Merchant2.default.active = null;
      }

      var _loop = function _loop() {
        if (_isArray) {
          if (_i >= _iterator.length) return 'break';
          _ref = _iterator[_i++];
        } else {
          _i = _iterator.next();
          if (_i.done) return 'break';
          _ref = _i.value;
        }

        var pd = _ref;

        if (pd.disconnectUsb) {
          Log.debug(function () {
            return 'Disconnecting USB from ' + pd.id;
          });
          pd.disconnectUsb(function () {});
        }
        Log.debug(function () {
          return 'Removing ' + pd.id;
        });
        pd.removed();
      };

      for (var _iterator = _retailPaymentDevice.PaymentDevice.devices, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
        var _ref;

        var _ret = _loop();

        if (_ret === 'break') break;
      }
    } catch (x) {
      Log.error('Error on executing log-out ' + x);
    }
  };

  /**
   * Set the log level for SDK
   * @param {logLevel} level
   */


  SDK.prototype.setLogLevel = function setLogLevel(level) {
    var manticoreLogLevel = _manticoreLog2.default.Level.DEBUG;
    if (level === _logLevel2.default.quiet) {
      manticoreLogLevel = 'QUIET';
    } else if (level === _logLevel2.default.error) {
      manticoreLogLevel = _manticoreLog2.default.Level.ERROR;
    } else if (level === _logLevel2.default.warn) {
      manticoreLogLevel = _manticoreLog2.default.Level.WARN;
    } else if (level === _logLevel2.default.info) {
      manticoreLogLevel = _manticoreLog2.default.Level.INFO;
    } else if (level === _logLevel2.default.debug) {
      manticoreLogLevel = _manticoreLog2.default.Level.DEBUG;
    }
    Log.debug(function () {
      return 'Set SDK log level to ' + manticoreLogLevel;
    });
    require('manticore-log').Root.level = manticoreLogLevel; // eslint-disable-line global-require
  };

  /**
   * Provide an interceptor for all HTTP calls made by the SDK
   * @param {SDK~intercept} interceptor
   */


  SDK.prototype.setNetworkInterceptor = function setNetworkInterceptor(interceptor) {
    Log.info('Adding network interceptor ' + interceptor);
    (0, _networkInterceptor2.default)(interceptor);
  };

  /**
   * Returns the SDK device manager
   * @returns {DeviceManager} device manager
   */


  SDK.prototype.getDeviceManager = function getDeviceManager() {
    return _DeviceManager2.default;
  };

  /**
   * Returns the Transaction Manager
   * @returns {TransactionManager} device manager
   */


  SDK.prototype.getTransactionManager = function getTransactionManager() {
    return _TransactionManager2.default;
  };

  return SDK;
}(_events.EventEmitter);

SDK.Event = {
  deviceDiscovered: 'deviceDiscovered',
  pageViewed: 'pageViewed'
};

/**
 * A PaymentDevice has been discovered. For further events, such as device readiness, removal or the
 * need for a software upgrade, your application should subscribe to the relevant events on the device
 * parameter. Please note that this doesn't always mean the device is present. In certain cases (e.g. Bluetooth)
 * we may know about the device independently of whether it's currently connected or available.
 * @event SDK#deviceDiscovered
 * @param {PaymentDevice} device The device that has been discovered.
 */

/**
 * A page has been viewed
 * @event SDK#pageViewed
 * @param {error} error Error reported on the page
 * @param {Page} page Page that was viewed
 */

/**
 * This callback will be invoked every time the SDK wants to do a HTTP Request, the listener could intercept this call
 * and provide
 * @callback SDK~intercept
 * @param {NetworkRequest} request HTTP Network request
 */

var sdk = module.exports = new SDK(); // eslint-disable-line no-unused-vars

}).call(this,require("buffer").Buffer)
},{"../package.json":"/Users/aravidas/Documents/Git/retail-sdk/package.json","./common/Features":"/Users/aravidas/Documents/Git/retail-sdk/js/common/Features.js","./common/Merchant":"/Users/aravidas/Documents/Git/retail-sdk/js/common/Merchant.js","./common/NetworkHandler/networkInterceptor":"/Users/aravidas/Documents/Git/retail-sdk/js/common/NetworkHandler/networkInterceptor.js","./common/cal":"/Users/aravidas/Documents/Git/retail-sdk/js/common/cal.js","./common/logLevel":"/Users/aravidas/Documents/Git/retail-sdk/js/common/logLevel.js","./common/sdkErrors":"/Users/aravidas/Documents/Git/retail-sdk/js/common/sdkErrors.js","./paymentDevice/CardReaderDisplayController":"/Users/aravidas/Documents/Git/retail-sdk/js/paymentDevice/CardReaderDisplayController.js","./transaction/DeviceManager":"/Users/aravidas/Documents/Git/retail-sdk/js/transaction/DeviceManager.js","./transaction/TransactionContext":"/Users/aravidas/Documents/Git/retail-sdk/js/transaction/TransactionContext.js","./transaction/TransactionManager":"/Users/aravidas/Documents/Git/retail-sdk/js/transaction/TransactionManager.js","buffer":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/buffer/index.js","events":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/events/events.js","manticore":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore/browser.js","manticore-log":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-log/index.js","retail-page-tracker":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-page-tracker/build/index.js","retail-payment-device":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/js/transaction/AuthStatus.js":[function(require,module,exports){
"use strict";

exports.__esModule = true;
/**
 * This enum represents the state of the auth transaction
 * @enum {int}
 */
var AuthStatus = {
  /**
   * Authorization is still pending. Yet to capture
   */
  pending: 0,

  /**
   * Authorization has been cancelled
   */
  canceled: 1
};
exports.default = AuthStatus;

},{}],"/Users/aravidas/Documents/Git/retail-sdk/js/transaction/AuthorizedTransaction.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

var _moment = require('moment');

var _moment2 = _interopRequireDefault(_moment);

var _paypalInvoicing = require('paypal-invoicing');

var _voidManager = require('./voidManager');

var _voidManager2 = _interopRequireDefault(_voidManager);

var _captureManager = require('./captureManager');

var _captureManager2 = _interopRequireDefault(_captureManager);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

/**
 * Information about a completed capture
 * @class
 * @property {string} authorizationId The PayPal transaction reference number for this authorization @readonly
 * @property {string} invoiceId The PayPal invoice id for this authorization @readonly
 * @property {Date} timeCreated Time at which this authorization activity was created
 * @property {decimal} authorizedAmount Amount authorized for this transaction
 * @property {string} currency Currency in which the net amount was authorized @readonly
 * @property {string} status Status of the current authorization
 */
var AuthorizedTransaction = function () {
  /**
   * @private
   */
  function AuthorizedTransaction(response) {
    _classCallCheck(this, AuthorizedTransaction);

    this.authorizationId = response.id;
    this.invoiceId = response.extension.invoice_number;
    this.timeCreated = (0, _moment2.default)(response.time_created).toDate();
    this.authorizedAmount = (0, _paypalInvoicing.$$)(response.gross.value);
    this.currency = response.gross.currency_code;
    this.status = response.status;
  }

  AuthorizedTransaction.prototype.toJSON = function toJSON() {
    return {
      authorizationId: this.authorizationId,
      invoiceId: this.invoiceId,
      timeCreated: this.timeCreated,
      authorizedAmount: this.authorizedAmount,
      currency: this.currency,
      status: this.status
    };
  };

  /**
   * Void this authorized transaction
   * @param {AuthorizedTransaction~voidComplete} callback
   */


  AuthorizedTransaction.prototype.voidTransaction = function voidTransaction(callback) {
    (0, _voidManager2.default)(this.authorizationId, callback);
  };

  /**
   * Capture this authorized transaction
   * @param {decimal} totalAmount the total amount that has to be captured.
   * @param {decimal} gratuityAmount (optional) the gratuity amount that is also part of the totalAmount. If present, should be less than total Amount.
   * @param {AuthorizedTransaction~captureComplete} callback
   */


  AuthorizedTransaction.prototype.captureTransaction = function captureTransaction(totalAmount, gratuityAmount, callback) {
    (0, _captureManager2.default)(this.authorizationId, this.invoiceId, totalAmount, gratuityAmount, this.currency, callback);
  };

  AuthorizedTransaction.prototype.toString = function toString() {
    return JSON.stringify(this.toJSON());
  };

  return AuthorizedTransaction;
}();

/**
 * @callback AuthorizedTransaction~voidComplete
 * @param {error} error Error (if any)
 */

/**
 * @callback AuthorizedTransaction~captureComplete
 * @param {error} error Error (if any)
 * @param {string} captureId Id after a successful capture
 */


exports.default = AuthorizedTransaction;

},{"./captureManager":"/Users/aravidas/Documents/Git/retail-sdk/js/transaction/captureManager.js","./voidManager":"/Users/aravidas/Documents/Git/retail-sdk/js/transaction/voidManager.js","moment":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/moment/moment.js","paypal-invoicing":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/js/transaction/CardPresentedHandler.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

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; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

var _manticore = require('manticore');

var _manticore2 = _interopRequireDefault(_manticore);

var _manticoreLog = require('manticore-log');

var _manticoreLog2 = _interopRequireDefault(_manticoreLog);

var _retailPaymentDevice = require('retail-payment-device');

var _manticoreUtil = require('manticore-util');

var Util = _interopRequireWildcard(_manticoreUtil);

var _tlvlib = require('tlvlib');

var _transactionEvent = require('./transactionEvent');

var _transactionEvent2 = _interopRequireDefault(_transactionEvent);

var _PaymentErrorHandler = require('../flows/PaymentErrorHandler');

var _PaymentErrorHandler2 = _interopRequireDefault(_PaymentErrorHandler);

var _l10n = require('../common/l10n');

var _l10n2 = _interopRequireDefault(_l10n);

var _retailSDKUtil = require('../common/retailSDKUtil');

var _messageHelper = require('../flows/messageHelper');

var messageHelper = _interopRequireWildcard(_messageHelper);

var _sdkErrors = require('../common/sdkErrors');

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

var Log = (0, _manticoreLog2.default)('tx.cardPresentedHandler');

var CardPresentedHandler = function () {
  function CardPresentedHandler(tx) {
    _classCallCheck(this, CardPresentedHandler);

    this.context = tx;
  }

  CardPresentedHandler.prototype.handleCardPresent = function handleCardPresent(err, subType, ff, result, device) {
    var amountAllowedError = null;
    if (subType !== _retailPaymentDevice.CardPresentEvent.insertDetected) {
      // insertDetected is emitted just before cardDataRead
      // cardDataRead already handles this error case.
      if (this.context.isInvoiceAmountBelowAllowedMinimum()) {
        amountAllowedError = _sdkErrors.transaction.amountTooLow;
      } else if (this.context.isInvoiceAmountAboveAllowedMaximum()) {
        amountAllowedError = _sdkErrors.transaction.amountTooHigh;
      }
    }
    if (err || amountAllowedError) {
      // Note that this setPaymentInProgress() is needed here when offline decline happens
      this.context.setPaymentInProgress();
      this._handleError(err || amountAllowedError, ff, device);
      return;
    }
    Log.info('Received card present event with sub type \'' + Util.getPropertyName(_retailPaymentDevice.CardPresentEvent, subType) + ', ff: ' + Util.getPropertyName(_retailPaymentDevice.FormFactor, ff) + ' for ' + this.context);
    if (subType === _retailPaymentDevice.CardPresentEvent.cardDataRead) {
      this._handleCardData(result);
    } else if (subType === _retailPaymentDevice.CardPresentEvent.pinEvent) {
      this._handlePinEvent(result);
    } else if (subType === _retailPaymentDevice.CardPresentEvent.appSelectionRequired) {
      this._handleApplicationSelect(device, ff, result);
    } else if (subType === _retailPaymentDevice.CardPresentEvent.insertDetected) {
      this._handleCardInsertDetectedEvent(device);
    } else {
      Log.error('Received unknown card presented event from ' + device.id + ' event subType: ' + subType + ',      formFactor: ' + ff + ', result: ' + result);
    }
  };

  CardPresentedHandler.prototype.handleTxCancelled = function handleTxCancelled(device) {
    var _this = this;

    Log.warn('Tx cancelled listener was invoked for device : ' + device.id);
    device.display({ id: _retailPaymentDevice.PaymentDevice.Message.TransactionCancelled, substitutions: this._formattedAmount }, function () {
      _this.context.alert = _manticore2.default.alert({
        title: (0, _l10n2.default)('Tx.Alert.Cancelled.Title'),
        message: (0, _l10n2.default)('Tx.Alert.Cancelled.Msg'),
        cancel: (0, _l10n2.default)('Done')
      }, function () {
        _this.context.alert.dismiss();
        _this.context.end(_sdkErrors.transaction.genericCancel);
      });
    });
  };

  CardPresentedHandler.prototype.handleContactlessReaderDeactivated = function handleContactlessReaderDeactivated(device) {
    var _this2 = this;

    Log.debug(function () {
      return 'Contactless reader was deactivated on ' + device.id;
    });
    this.context.deviceController.syncOnce(device);
    Log.debug(function () {
      return 'Emitting contactlessReaderDeactivated event for ' + _this2.context;
    });
    this.context.emit(_transactionEvent2.default.contactlessReaderDeactivated);
  };

  CardPresentedHandler.prototype._handleCardInsertDetectedEvent = function _handleCardInsertDetectedEvent(device) {
    Log.debug(function () {
      return 'Card insert detected on ' + device.id;
    });
    this.context.alert = _manticore2.default.alert({
      title: (0, _l10n2.default)('EMV.DoNotRemove'),
      message: (0, _l10n2.default)('EMV.Processing'),
      showActivity: true,
      replace: true
    }, function () {});
    var substitutions = this.context.isRefund() ? messageHelper.formattedRefundTotal(this.context) : messageHelper.formattedInvoiceTotal(this.context.invoice);
    device.display({ id: _retailPaymentDevice.PaymentDevice.Message.ProcessingContact, substitutions: substitutions }, function () {});
  };

  CardPresentedHandler.prototype._validateFormFactor = function _validateFormFactor(card, allowFallbackSwipe) {
    // Only allow fallback swipes for chip cards
    var sActiveFormFactors = this.context.getSetOfActiveFormFactors();
    if (!allowFallbackSwipe && card.chipCard && card.formFactor === _retailPaymentDevice.FormFactor.MagneticCardSwipe) {
      if (sActiveFormFactors.has(_retailPaymentDevice.FormFactor.Chip)) {
        // TODO Temporary provision that must be removed post certification
        return _sdkErrors.transaction.cannotSwipeChipCard;
      }
      Log.info('Allow fallback swipes on chip card as chip reader was not enabled');
    }

    // Do not accept card inserts if Chip form factor was not enabled
    if (card.formFactor === _retailPaymentDevice.FormFactor.Chip && !sActiveFormFactors.has(_retailPaymentDevice.FormFactor.Chip)) {
      return _sdkErrors.transaction.mustSwipeCard;
    }

    return null;
  };

  CardPresentedHandler.prototype._handleCardData = function _handleCardData(cardData) {
    var card = cardData.card;
    Log.debug(function () {
      return 'Card presented using form factor: \'' + Util.getPropertyName(_retailPaymentDevice.FormFactor, card.formFactor) + '\'';
    });
    this.context.card = card;
    var error = this._validateFormFactor(card, this.context.allowFallBackSwipe);
    if (error) {
      this._handleError(error, card.formFactor, card.reader);
      return;
    }

    if (card.chipCard && card.formFactor === _retailPaymentDevice.FormFactor.MagneticCardSwipe) {
      Log.info('Allowing fallback swipe on the chip card');
      card.isMSRFallbackAllowed = true;
    }

    if (this._isOnlinePINVerificationRequired(card.emvData)) {
      Log.debug('Online PIN authorization required... Will set pinPresent to true');
      this.context.pinPresent = true;
    }

    if (this.context.cardPresentedHandler) {
      // Dismiss any alert before we transfer control to the app for iOS
      if (this.context.alert) {
        this.context.alert.dismiss();
      }
      this.context.cardPresentedHandler(card);
    } else {
      // Because there are no listeners, we assume you want to just proceed with the
      // transaction and be notified on completion.
      this.context.continueWithCard(card);
    }
  };

  CardPresentedHandler.prototype._handlePinEvent = function _handlePinEvent(pinEvent) {
    var _this3 = this;

    Log.debug(function () {
      return 'Received PinEvent ' + JSON.stringify(pinEvent);
    });
    var promptForPin = function promptForPin() {
      var formattedValues = _this3.context.isRefund() ? messageHelper.formattedRefundTotal(_this3.context) : messageHelper.formattedInvoiceTotal(_this3.context.invoice);
      _this3.context.alert = _manticore2.default.alert({
        title: (0, _l10n2.default)('Tx.Alert.EnterPin.Title', formattedValues),
        message: (0, _l10n2.default)('Tx.Alert.EnterPin.Message')
      }, function () {});
    };
    if (pinEvent.correct) {
      this.context.pinPresent = true;
    } else if (pinEvent.digits === 0) {
      this.context.pinRequired = true;
      if (this._incorrectPin) {
        this._incorrectPin = false;
        return;
      }
      promptForPin();
    } else if (pinEvent.failureReason) {
      this._incorrectPin = true;
      this.context.alert = _manticore2.default.alert({
        title: (0, _l10n2.default)('Tx.Alert.IncorrectPin.Title'),
        message: (0, _l10n2.default)('Tx.Alert.IncorrectPin.Message'),
        cancel: (0, _l10n2.default)('OK')
      }, promptForPin);
    }
  };

  CardPresentedHandler.prototype._isOnlinePINVerificationRequired = function _isOnlinePINVerificationRequired(emvData) {
    if (!this.context.pinRequired || !emvData.tlvs) {
      return false;
    }
    var cvmResult = emvData.tlvs.find(_tlvlib.Tags.CardholderVerificationMethodResults);
    if (!cvmResult || !cvmResult.bytes[0]) {
      return false;
    }
    Log.debug(function () {
      return 'Checking for online PIN Authorization... Value of bytes[0] for CVM tag is ' + cvmResult.bytes[0];
    });
    // CVM codes value for left most byte of 010000 indicates 'Enciphered PIN verified online' event
    return (cvmResult.bytes[0] & 63) === 2;
  };

  CardPresentedHandler.prototype._handleApplicationSelect = function _handleApplicationSelect(device, ff, data) {
    var _this4 = this;

    var buttons = [];
    var availableApps = data.availableApps;
    for (var _iterator = availableApps.apps, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
      var _ref;

      if (_isArray) {
        if (_i >= _iterator.length) break;
        _ref = _iterator[_i++];
      } else {
        _i = _iterator.next();
        if (_i.done) break;
        _ref = _i.value;
      }

      var app = _ref;

      buttons.push(app[1] || app[0]);
    }

    var onCardRemoved = function onCardRemoved() {
      return _this4._handleError(_retailPaymentDevice.deviceError.smartCardNotInSlot, _retailPaymentDevice.FormFactor.Chip, device);
    };
    device.once(_retailPaymentDevice.PaymentDevice.Event.cardRemoved, onCardRemoved);
    this.context.alert = _manticore2.default.alert({
      title: (0, _l10n2.default)('EMV.Select'),
      buttons: buttons,
      replace: true
    }, function (error, ix) {
      var applicationId = availableApps.apps[ix][0];
      var applicationName = availableApps.apps[ix][1];
      Log.info(_this4.context.id + ' User selected application ' + applicationId + ':' + applicationName);
      _this4.context.alert = _manticore2.default.alert({
        title: (0, _l10n2.default)('EMV.DoNotRemove'),
        message: (0, _l10n2.default)('EMV.Processing'),
        showActivity: true,
        replace: true
      }, function () {});
      device.removeListener(_retailPaymentDevice.PaymentDevice.Event.cardRemoved, onCardRemoved);
      device.selectPaymentApplication(applicationId, data.card);
    });
  };

  CardPresentedHandler.prototype._handleError = function _handleError(error, ff, pd) {
    var _this5 = this;

    if (error.code === _retailPaymentDevice.deviceError.contactlessPaymentAbortedByCardInsert.code || error.code === _retailPaymentDevice.deviceError.contactlessPaymentAbortedByCardSwipe.code) {
      Log.debug('Contactless payment aborted by card insert/swipe');
    } else {
      Log.error('Transaction failed with error \'' + error.domain + '.' + error.code + '\'');
    }

    var errorHandler = new _PaymentErrorHandler2.default(this.context);
    errorHandler.handle(error, ff, pd, function (action) {
      return _this5.context.processErrorHandlerResponse(error, action, ff);
    });
  };

  _createClass(CardPresentedHandler, [{
    key: '_formattedAmount',
    get: function get() {
      return {
        amount: (0, _retailSDKUtil.getAmountWithCurrencySymbol)(this.context.invoice.currency, this.context.invoice.total)
      };
    }
  }]);

  return CardPresentedHandler;
}();

exports.default = CardPresentedHandler;

},{"../common/l10n":"/Users/aravidas/Documents/Git/retail-sdk/js/common/l10n.js","../common/retailSDKUtil":"/Users/aravidas/Documents/Git/retail-sdk/js/common/retailSDKUtil.js","../common/sdkErrors":"/Users/aravidas/Documents/Git/retail-sdk/js/common/sdkErrors.js","../flows/PaymentErrorHandler":"/Users/aravidas/Documents/Git/retail-sdk/js/flows/PaymentErrorHandler.js","../flows/messageHelper":"/Users/aravidas/Documents/Git/retail-sdk/js/flows/messageHelper.js","./transactionEvent":"/Users/aravidas/Documents/Git/retail-sdk/js/transaction/transactionEvent.js","manticore":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore/browser.js","manticore-log":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-log/index.js","manticore-util":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-util/build/index.js","retail-payment-device":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/index.js","tlvlib":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/tlvlib/build/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/js/transaction/DeviceController.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

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; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

var _manticoreLog = require('manticore-log');

var _manticoreLog2 = _interopRequireDefault(_manticoreLog);

var _retailPaymentDevice = require('retail-payment-device');

var _paypalInvoicing = require('paypal-invoicing');

var _events = require('events');

var _manticoreUtil = require('manticore-util');

var _CardPresentedHandler = require('./CardPresentedHandler');

var _CardPresentedHandler2 = _interopRequireDefault(_CardPresentedHandler);

var _DeviceSelector = require('../paymentDevice/DeviceSelector');

var _DeviceSelector2 = _interopRequireDefault(_DeviceSelector);

var _InvoiceSynchronizer = require('./InvoiceSynchronizer');

var _InvoiceSynchronizer2 = _interopRequireDefault(_InvoiceSynchronizer);

var _sdkErrors = require('../common/sdkErrors');

var _Merchant = require('../common/Merchant');

var _Merchant2 = _interopRequireDefault(_Merchant);

var _messageHelper = require('../flows/messageHelper');

var _retailSDKUtil = require('../common/retailSDKUtil');

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (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 } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var Log = (0, _manticoreLog2.default)('transactionContext.deviceController');

/**
 * DeviceController is responsible for maintaining the state of devices used in a transaction.
 * It tracks the state of each device, form factors and and provides methods to
 * activate/deactivate the devices
 */

var DeviceController = function (_EventEmitter) {
  _inherits(DeviceController, _EventEmitter);

  function DeviceController(context) {
    _classCallCheck(this, DeviceController);

    var _this = _possibleConstructorReturn(this, _EventEmitter.call(this));

    _this.context = context;
    _this.activeDevices = new Set();
    _this._invoiceSynchronizer = new _InvoiceSynchronizer2.default(context, _this);
    _this._invoiceSynchronizer.start();
    _this._cardPresentedHandlers = new _CardPresentedHandler2.default(_this.context);
    return _this;
  }
  /**
   * List of all devices that are available for the transaction.
   * (Not all available devices will be approved for the transaction.
   * The filter criteria to determine an approved device is defined in
   * `DeviceManager.availabilityFilter` )
   */


  /**
   * Returns a set of form factors approved for the current transaction
   * @param {[FormFactor]} preferredFormFactors List of form factors preferred for the given transaction
   * @returns {[FormFactor]} List of form factors approved for this transaction
   */
  DeviceController.prototype.getApprovedFormFactors = function getApprovedFormFactors(preferredFormFactors) {
    var availableDevices = this.devices.filter(function (pd) {
      return pd.isReadyForTransaction().isReady;
    });
    var sAvailableFormFactors = new Set([].concat.apply([], availableDevices.map(function (pd) {
      return pd.formFactors;
    }))); // eslint-disable-line prefer-spread

    if (sAvailableFormFactors.has(_retailPaymentDevice.FormFactor.EmvCertifiedContactless)) {
      if (this._isNFCContactlessLimitReached()) {
        sAvailableFormFactors.delete(_retailPaymentDevice.FormFactor.EmvCertifiedContactless);
      }
    }
    return preferredFormFactors && preferredFormFactors.length > 0 ? preferredFormFactors.filter(function (ff) {
      return sAvailableFormFactors.has(ff);
    }) : [].concat(_toConsumableArray(sAvailableFormFactors));
  };

  DeviceController.prototype._isNFCContactlessLimitReached = function _isNFCContactlessLimitReached() {
    var _this2 = this;

    var merchant = _Merchant2.default.active;
    if (merchant.featureMap) {
      var nfcLimit = merchant.isCertificationMode ? '*' : merchant.featureMap.CONTACTLESS_LIMIT;
      if (nfcLimit !== '*' && this.context.invoice.total.greaterThan((0, _paypalInvoicing.$$)(nfcLimit) || 0)) {
        Log.debug(function () {
          return 'Cannot perform NFC. Invoice total ' + _this2.context.invoice.total + ' is above contactless limit of ' + nfcLimit;
        }); // eslint-disable-line max-len
        return true;
      }
      return false;
    }
    return false;
  };

  DeviceController.prototype._isMerchantFromUK = function _isMerchantFromUK() {
    var merchantCurrency = _Merchant2.default.active.currency;
    return merchantCurrency === 'GBP';
  };

  DeviceController.prototype._showInsertOrSwipeMessageOnDevice = function _showInsertOrSwipeMessageOnDevice(selectedDevice, invTotal) {
    selectedDevice.display({
      id: _retailPaymentDevice.PaymentDevice.Message.ReadyForInsertAndSwipePayment,
      substitutions: invTotal
    }, function () {
      // Nothing to do yet
    });
  };

  /**
   * Gets the selected device
   */


  DeviceController.prototype.cardInsertDetected = function cardInsertDetected() {
    if (_DeviceSelector2.default.selectedDevice) {
      this._cardPresentedHandlers.handleCardPresent(null, _retailPaymentDevice.CardPresentEvent.insertDetected, _retailPaymentDevice.FormFactor.Chip, null, _DeviceSelector2.default.selectedDevice);
    }
  };

  /**
  * Activates the devices that are available for payment. The provided callback
  * will be invoked with the activated devices. The devices that failed activation
  * would be notified.
  * @param {object} opt Configuration options with following properties
   *   showPrompt    - true to show payment prompt on card reader display (if available)
  *    formFactors   - List of payment form factors that needs to be activated.
  *                    Will be defaulted to `this.formFactors`
  *    syncInvoiceTotal - true to synchronize invoice total on card reader display
  */


  DeviceController.prototype.activate = function activate(opt) {
    var _this3 = this;

    var showPrompt = opt.showPrompt;
    var formFactors = opt.formFactors;
    var syncInvoiceTotal = (0, _retailSDKUtil.isNullOrUndefined)(opt.syncInvoiceTotal) ? true : opt.syncInvoiceTotal;
    var device = _DeviceSelector2.default.selectedDevice;
    Log.debug(function () {
      return '(' + _this3.context.id + ') Begin device activation for invoice total: ' + _this3.context.invoice.total + ', sync: ' + syncInvoiceTotal;
    });
    if (!device) {
      Log.warn('Exiting device activation for ' + this.context.id + ' as selected device was not set');
      return { error: _sdkErrors.transaction.noFunctionalDevices };
    }

    Log.debug(function () {
      return '(' + _this3.context.id + ') Continue device activation for invoice total: ' + _this3.context.invoice.total + ', sync: ' + syncInvoiceTotal + ' on ' + device.id;
    });
    if (this.updateDeviceDisplayIfError(device)) {
      return { error: _sdkErrors.transaction.noFunctionalDevices };
    }

    if (syncInvoiceTotal) {
      this._invoiceSynchronizer.start();
    } else {
      Log.debug(function () {
        return 'Will not sync invoice total of ' + _this3.context.invoice.total + ' on ' + device.id;
      });
    }
    device.stopPollForBattery(); // Will restart battery poll on tx.end();

    if (this.listenersAddedTo === device) {
      Log.debug(function () {
        return 'Skip add listeners for ' + _this3.context.id + '. Listeners already added';
      });
    } else {
      this.removeListenerOnDevice(device);
      Log.debug(function () {
        return 'Adding listeners for ' + _this3.context.id + ' to ' + device.id;
      });
      this.listenersAddedTo = device;
      this._addListener(device, _retailPaymentDevice.PaymentDevice.Event.cardPresented, function (err, subType, ff, result) {
        device.cardPresented = true;
        if (!err) {
          // The invoice synchronization should be stopped so that the 'Processing...' display message on the card reader is not replaced with invoice amount
          // This is specifically needed for in-app tipping for M010. Without this, the 'Processing...' message gets replaced with invoice total
          _this3._invoiceSynchronizer.stop();
        }
        _this3._cardPresentedHandlers.handleCardPresent(err, subType, ff, result, device);
      });
      this._addListener(device, _retailPaymentDevice.PaymentDevice.Event.cancelled, function () {
        return _this3._cardPresentedHandlers.handleTxCancelled(device);
      });
      this._addListener(device, _retailPaymentDevice.PaymentDevice.Event.cancelRequested, function () {
        return _this3.context.cancel;
      });
      this._addListener(device, _retailPaymentDevice.PaymentDevice.Event.contactlessReaderDeactivated, function () {
        return _this3._cardPresentedHandlers.handleContactlessReaderDeactivated(device);
      });
    }

    if (device.manufacturer.toUpperCase() === _retailPaymentDevice.deviceManufacturer.miura) {
      if (this._isNFCContactlessLimitReached()) {
        // UK contactless limit check and show the right image on the device
        this._showInsertOrSwipeMessageOnDevice(device, (0, _messageHelper.formattedInvoiceTotal)(this.context.invoice));
      }
    }

    var approvedFormFactors = this.getApprovedFormFactors(formFactors);
    Log.info('(' + this.context.id + ') Activating ' + device.id + ' for form factors [' + (0, _manticoreUtil.getPropertyName)(_retailPaymentDevice.FormFactor, approvedFormFactors) + '] & showPrompt: ' + showPrompt);
    device.cardInsertedHandler = this.context.cardInsertedHandler;
    device.activateForPayment(this.context, approvedFormFactors, showPrompt);
    this.activeDevices.add(device);
    Log.debug(function () {
      return 'Device \'' + device.id + ' activated for ' + approvedFormFactors + ' form factors\'';
    });
    return {
      device: device,
      formFactors: approvedFormFactors
    };
  };

  DeviceController.prototype.updateDeviceDisplayIfError = function updateDeviceDisplayIfError(device) {
    var deviceStatus = device.isReadyForTransaction();
    if (!deviceStatus.isReady) {
      Log.warn('Selected device ' + device.id + ' failed availability check due to ' + deviceStatus.error);
      if (deviceStatus.error === _retailPaymentDevice.deviceError.lowOnBattery) {
        device.display({ id: _retailPaymentDevice.PaymentDevice.Message.RechargeNow }, function () {});
      } else if (deviceStatus.error === _retailPaymentDevice.deviceError.swUpdatePending) {
        device.display({ id: _retailPaymentDevice.PaymentDevice.Message.SoftwareUpdateRequired }, function () {});
      }
      return true;
    }
    return false;
  };

  DeviceController.prototype.syncOnce = function syncOnce(device) {
    this._invoiceSynchronizer.pushOnce(device || _DeviceSelector2.default.selectedDevice, this.context.invoice.total, function () {});
  };

  DeviceController.prototype.abort = function abort(cb) {
    this._invoiceSynchronizer.stop();
    this.removeListeners();
    var pd = _DeviceSelector2.default.selectedDevice;
    if (!pd) {
      Log.info('Aborting transaction ' + this.context.id);
      if (cb) {
        cb();
      }
      return;
    }
    Log.info('Aborting transaction ' + this.context.id + ' on ' + pd.id + ' active with form factor\'s - \'' + (0, _manticoreUtil.getPropertyName)(_retailPaymentDevice.FormFactor, [].concat(_toConsumableArray(pd.getSetOfActiveFormFactors()))) + '\'');
    pd.abortTransaction(this.context, function () {
      pd.display({
        id: _retailPaymentDevice.PaymentDevice.Message.ReadyWithId,
        substitutions: { id: pd.id },
        displaySystemIcons: true
      }, function () {
        cb(pd);
      });
    });
  };

  DeviceController.prototype.deactivateFormFactors = function deactivateFormFactors(formFactors, cb) {
    if (_DeviceSelector2.default.selectedDevice) {
      _DeviceSelector2.default.selectedDevice.deactivateFormFactors(formFactors, function () {
        if (cb) {
          cb(_DeviceSelector2.default.selectedDevice);
        }
      });
    } else {
      Log.debug('Will not deactivate tx as no device selected! Will immediately invoke callback');
      if (cb) {
        cb();
      }
    }
  };

  DeviceController.prototype.syncInvoice = function syncInvoice() {
    this._invoiceSynchronizer.start();
  };

  DeviceController.prototype.stopInvoiceSync = function stopInvoiceSync() {
    this._invoiceSynchronizer.stop();
  };

  DeviceController.prototype.startPollingForBattery = function startPollingForBattery() {
    if (_DeviceSelector2.default.selectedDevice) {
      _DeviceSelector2.default.selectedDevice.startPollForBattery();
    }
  };

  DeviceController.prototype.stopPollingForBattery = function stopPollingForBattery() {
    if (_DeviceSelector2.default.selectedDevice) {
      _DeviceSelector2.default.selectedDevice.stopPollForBattery();
    }
  };

  DeviceController.prototype._addListener = function _addListener(pd, event, listener) {
    listener.txContextId = this.context.id;
    pd.on(event, listener);
  };

  /**
   * Removes transaction context listeners on the payment device
   * @param devices
   */


  DeviceController.prototype.removeListeners = function removeListeners() {
    var devices = _retailPaymentDevice.PaymentDevice.devices;
    for (var _iterator = devices, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
      var _ref;

      if (_isArray) {
        if (_i >= _iterator.length) break;
        _ref = _iterator[_i++];
      } else {
        _i = _iterator.next();
        if (_i.done) break;
        _ref = _i.value;
      }

      var pd = _ref;

      this.removeListenerOnDevice(pd);
    }
    this.listenersAddedTo = null;
  };

  DeviceController.prototype.removeListenerOnDevice = function removeListenerOnDevice(pd) {
    var _this4 = this;

    var events = [_retailPaymentDevice.PaymentDevice.Event.cardPresented, _retailPaymentDevice.PaymentDevice.Event.cancelled, _retailPaymentDevice.PaymentDevice.Event.cancelRequested, _retailPaymentDevice.PaymentDevice.Event.contactlessReaderDeactivated];

    var _loop = function _loop() {
      if (_isArray2) {
        if (_i2 >= _iterator2.length) return 'break';
        _ref2 = _iterator2[_i2++];
      } else {
        _i2 = _iterator2.next();
        if (_i2.done) return 'break';
        _ref2 = _i2.value;
      }

      var e = _ref2;

      var listenerCount = pd.listenerCount(e);
      var listeners = [];
      for (var _iterator3 = pd.listeners(e), _isArray3 = Array.isArray(_iterator3), _i3 = 0, _iterator3 = _isArray3 ? _iterator3 : _iterator3[Symbol.iterator]();;) {
        var _ref3;

        if (_isArray3) {
          if (_i3 >= _iterator3.length) break;
          _ref3 = _iterator3[_i3++];
        } else {
          _i3 = _iterator3.next();
          if (_i3.done) break;
          _ref3 = _i3.value;
        }

        var l = _ref3;

        pd.removeListener(e, l);
        listeners.push(l.id);
      }
      if (listenerCount) {
        Log.debug(function () {
          return 'Removed ' + listenerCount + ' \'' + e + '\' listener(s) from ' + pd.id + ' for ' + _this4.context.id + '. Listeners - ' + listeners;
        });
      }
    };

    for (var _iterator2 = events, _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) {
      var _ref2;

      var _ret = _loop();

      if (_ret === 'break') break;
    }
  };

  _createClass(DeviceController, [{
    key: 'devices',
    get: function get() {
      return this.context.paymentDevices || _retailPaymentDevice.PaymentDevice.devices;
    }
  }, {
    key: 'selectedDevice',
    get: function get() {
      return _DeviceSelector2.default.selectedDevice;
    }
  }]);

  return DeviceController;
}(_events.EventEmitter);

/**
 * Enumeration indicating possible device availability filter criterias
 * @type {{BatteryStatus: number, SoftwareUpdate: number}}
 */


exports.default = DeviceController;
DeviceController.FilterCriteria = {
  Ready: 'Ready',
  BatteryStatus: 'BatteryStatus',
  SoftwareUpdate: 'SoftwareUpdate'
};

},{"../common/Merchant":"/Users/aravidas/Documents/Git/retail-sdk/js/common/Merchant.js","../common/retailSDKUtil":"/Users/aravidas/Documents/Git/retail-sdk/js/common/retailSDKUtil.js","../common/sdkErrors":"/Users/aravidas/Documents/Git/retail-sdk/js/common/sdkErrors.js","../flows/messageHelper":"/Users/aravidas/Documents/Git/retail-sdk/js/flows/messageHelper.js","../paymentDevice/DeviceSelector":"/Users/aravidas/Documents/Git/retail-sdk/js/paymentDevice/DeviceSelector.js","./CardPresentedHandler":"/Users/aravidas/Documents/Git/retail-sdk/js/transaction/CardPresentedHandler.js","./InvoiceSynchronizer":"/Users/aravidas/Documents/Git/retail-sdk/js/transaction/InvoiceSynchronizer.js","events":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/events/events.js","manticore-log":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-log/index.js","manticore-util":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-util/build/index.js","paypal-invoicing":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/index.js","retail-payment-device":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/js/transaction/DeviceManager.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

var _manticoreLog = require('manticore-log');

var _manticoreLog2 = _interopRequireDefault(_manticoreLog);

var _retailPaymentDevice = require('retail-payment-device');

var _DeviceSelector = require('../paymentDevice/DeviceSelector');

var _DeviceSelector2 = _interopRequireDefault(_DeviceSelector);

var _DeviceScanner = require('../paymentDevice/DeviceScanner');

var _DeviceScanner2 = _interopRequireDefault(_DeviceScanner);

var _DeviceConnector = require('../paymentDevice/DeviceConnector');

var _DeviceConnector2 = _interopRequireDefault(_DeviceConnector);

var _sdkErrors = require('../common/sdkErrors');

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

var Log = (0, _manticoreLog2.default)('DeviceManager');

/**
 * DeviceManager is responsible for exposing APIs regarding the devices.
 * Currently, you can use DeviceManager to prompt the List to select the device
 * or set/get the active device.
 * @class
 */

var DeviceManager = function () {
  /**
   * Construct a new DeviceManger
   * @private
   */
  function DeviceManager() {
    var _this = this;

    _classCallCheck(this, DeviceManager);

    _DeviceScanner2.default.Events.once(_DeviceScanner2.default.Events.constructor, function (scanner) {
      _this.scanner = scanner;
    });
  }

  DeviceManager.prototype.getDeviceScanner = function getDeviceScanner() {
    return this.scanner;
  };

  /**
  * Show a list of connected credit card readers.
  * If there is more than 1 devices. Select one of them to use it*
  * for transaction.
  * @param {DeviceManager~connection} callback
  */


  DeviceManager.prototype.searchAndConnect = function searchAndConnect(callback) {
    if (this.scanner) {
      this.scanner.searchAndConnectWithUI(callback);
    } else {
      callback(_sdkErrors.sdk.cardReaderScannerNotInitialized, null);
    }
  };

  /**
   * Try connecting to the last active credit card reader
   * @param {DeviceManager~connection} callback
   */


  DeviceManager.prototype.connectToLastActiveReader = function connectToLastActiveReader(callback) {
    _DeviceConnector2.default.connectToLastActiveReaderOrFindAnother(callback);
  };

  /**
   * Sets the active reader
   * @param {PaymentDevice} pd The device that is to be set to Active
   */


  DeviceManager.prototype.setActiveReader = function setActiveReader(pd) {
    if (pd) {
      _DeviceSelector2.default.selectDevice(pd.id);
    } else {
      Log.warn('The payment device cannot be null');
    }
  };

  /**
   * checks if any Miura devive is connected
   * @returns {bool} Returns the bool if any miura device connected
   */


  DeviceManager.prototype.isConnectedToMiura = function isConnectedToMiura() {
    return _DeviceSelector2.default.isConnectedToMiura();
  };

  /**
   * Returns the selected device
   * @returns {PaymentDevice} Returns the payment device that is selected
   */


  DeviceManager.prototype.getActiveReader = function getActiveReader() {
    return _DeviceSelector2.default.selectedDevice;
  };

  /**
   * Get a list of paired/discovered devices
   * @returns {[PaymentDevice]} Devices list
   */


  DeviceManager.prototype.getDiscoveredDevices = function getDiscoveredDevices() {
    return _retailPaymentDevice.PaymentDevice.devices;
  };

  return DeviceManager;
}();

/**
 * The callback invoked while connecting to the last active card reader
 * @callback DeviceManager~connection
 * @param {error} error Error reported while connecting to a card reader
 * @param {PaymentDevice} cardReader Card reader which was successfully connected to
 */

var deviceManager = new DeviceManager(); // eslint-disable-line no-unused-vars
exports.default = deviceManager;

},{"../common/sdkErrors":"/Users/aravidas/Documents/Git/retail-sdk/js/common/sdkErrors.js","../paymentDevice/DeviceConnector":"/Users/aravidas/Documents/Git/retail-sdk/js/paymentDevice/DeviceConnector.js","../paymentDevice/DeviceScanner":"/Users/aravidas/Documents/Git/retail-sdk/js/paymentDevice/DeviceScanner.js","../paymentDevice/DeviceSelector":"/Users/aravidas/Documents/Git/retail-sdk/js/paymentDevice/DeviceSelector.js","manticore-log":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-log/index.js","retail-payment-device":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/js/transaction/InvoiceSynchronizer.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

var _manticore = require('manticore');

var _manticore2 = _interopRequireDefault(_manticore);

var _retailPaymentDevice = require('retail-payment-device');

var _manticoreLog = require('manticore-log');

var _manticoreLog2 = _interopRequireDefault(_manticoreLog);

var _paypalInvoicing = require('paypal-invoicing');

var _events = require('events');

var _transactionEvent = require('./transactionEvent');

var _transactionEvent2 = _interopRequireDefault(_transactionEvent);

var _CardReaderDisplayController = require('../paymentDevice/CardReaderDisplayController');

var _CardReaderDisplayController2 = _interopRequireDefault(_CardReaderDisplayController);

var _displayPriority = require('../paymentDevice/displayPriority');

var _displayPriority2 = _interopRequireDefault(_displayPriority);

var _retailSDKUtil = require('../common/retailSDKUtil');

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (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 } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var InvoiceEvent = _paypalInvoicing.Invoice.event;
var Log = (0, _manticoreLog2.default)('transactionContext.invoiceSynchronizer');

var syncInvoice = true; // TODO: This is just hack for now. Need to come up with a better strategy.

/**
 * InvoiceSynchronizer is responsible for synchoronizing the invoice with the transaction.
 * Whenever the invoice total changes, it will trigger the total changed event which will
 * eventually update the device display
 */

var InvoiceSynchronizer = function (_EventEmitter) {
  _inherits(InvoiceSynchronizer, _EventEmitter);

  function InvoiceSynchronizer(context, deviceController) {
    _classCallCheck(this, InvoiceSynchronizer);

    var _this = _possibleConstructorReturn(this, _EventEmitter.call(this));

    _this.context = context;
    _this.invoice = context.invoice;
    _this.deviceController = deviceController;
    _this._preferredFormFactors = new Set();
    return _this;
  }

  /**
   * Begin syncing invoice.total with the device display
   */


  InvoiceSynchronizer.prototype.start = function start() {
    var _this2 = this;

    syncInvoice = true;
    Log.debug(function () {
      return 'Starting invoice sync on ' + (_this2.deviceController.selectedDevice ? _this2.deviceController.selectedDevice.id : '(no device selected)') + ' for invoice total ' + _this2.invoice.total + '. context.id: ' + _this2.context.id;
    });
    try {
      var amount = this.context.isRefund() ? this.context.refundAmount : this.invoice.total;
      if (this._q) {
        this._q.push(amount);
        return;
      }

      this._q = {
        tasks: [],
        invoiceSyncInProgress: false,
        kill: function kill() {
          _this2._q.tasks = [];
        },
        process: function process() {
          if (!_this2._q || !_this2._q.tasks.length || !syncInvoice) {
            return;
          }
          var tasks = _this2._q.tasks.splice(0, _this2._q.tasks.length);
          var mostRecentTotal = tasks.pop();
          _this2._q.invoiceSyncInProgress = true;
          var pd = _this2.deviceController.selectedDevice;
          if (!pd) {
            _this2._q.invoiceSyncInProgress = false;
            return;
          }
          _this2.pushOnce(pd, mostRecentTotal, function () {
            _this2.emit('onTaskComplete');
            if (!_this2._q) {
              return;
            }
            _this2._q.invoiceSyncInProgress = false;
            if (_this2._q.tasks.length > 0) {
              _manticore2.default.setTimeout(function () {
                Log.debug('manticore timeout syncInvoice: ' + syncInvoice);
                _this2._q.process();
              }, 0);
            }
          });
        },
        push: function push(data) {
          _this2._q.tasks.push(data);
          if (!_this2._q.invoiceSyncInProgress) {
            Log.debug('push syncInvoice: ' + syncInvoice);
            _this2._q.process();
          }
        }
      };
      var listener = function listener() {
        return _this2._q.push(_this2.invoice.total);
      };
      var refundListener = function refundListener() {
        return _this2._q.push(_this2.context.refundAmount);
      };
      listener.txContext = this.context;
      this.invoice.on(InvoiceEvent.totalMayHaveChanged, listener);
      this.context.on(_transactionEvent2.default.invoiceDisplayFooterUpdated, listener);
      this.context.on(_transactionEvent2.default.refundAmountEntered, refundListener);
      this._q.push(this.invoice.total);
    } catch (x) {
      Log.error('Invoice Synchronizer failed stopping with error ' + x);
    }
  };

  InvoiceSynchronizer.prototype.pushOnce = function pushOnce(pd, invoiceTotal, callback) {
    var _this3 = this;

    if (!pd) {
      return;
    }
    var deviceStatus = pd.isReadyForTransaction();
    if (!deviceStatus.isReady) {
      Log.debug(function () {
        return 'Cannot push ' + invoiceTotal + ' to ' + pd.id + ' as card reader is not ready. Error: ' + deviceStatus.error;
      });
      return;
    }
    if (pd.pendingUpdate && pd.pendingUpdate.isRequired && !pd.pendingUpdate.wasInstalled) {
      pd.display({
        id: _retailPaymentDevice.PaymentDevice.Message.SoftwareUpdateRequired,
        displaySystemIcons: true
      }, callback);
      return;
    }

    var isAmountValid = invoiceTotal.greaterThan(0.0);
    Log.debug(function () {
      return 'InvoiceSync display for invoice total ' + _this3.invoice.total + '. context.id: ' + _this3.context.id;
    });
    _CardReaderDisplayController2.default.display(_displayPriority2.default.medium, pd, {
      id: isAmountValid ? _retailPaymentDevice.PaymentDevice.Message.InvoiceTotal : _retailPaymentDevice.PaymentDevice.Message.ReadyWithId,
      substitutions: {
        amount: (0, _retailSDKUtil.getAmountWithCurrencySymbol)(this.invoice.currency, invoiceTotal),
        footer: this.context.totalDisplayFooter,
        id: pd.id
      },
      displaySystemIcons: !isAmountValid
    }, callback);
  };

  /**
   * Stops syncing the device display with the invoice total
   */


  InvoiceSynchronizer.prototype.stop = function stop() {
    var _this4 = this;

    syncInvoice = false;
    Log.debug(function () {
      return 'Stopping invoice sync on ' + (_this4.deviceController.selectedDevice ? _this4.deviceController.selectedDevice.id : ', ') + ', this.shouldSync: ' + syncInvoice + ' for invoice total ' + _this4.invoice.total + '. context.id: ' + _this4.context.id;
    });
    try {
      var invoiceEvents = [InvoiceEvent.totalMayHaveChanged];
      var transactionEvents = [_transactionEvent2.default.invoiceDisplayFooterUpdated, _transactionEvent2.default.refundAmountEntered];
      for (var _iterator = invoiceEvents, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
        var _ref;

        if (_isArray) {
          if (_i >= _iterator.length) break;
          _ref = _iterator[_i++];
        } else {
          _i = _iterator.next();
          if (_i.done) break;
          _ref = _i.value;
        }

        var e = _ref;

        var _loop = function _loop() {
          if (_isArray3) {
            if (_i3 >= _iterator3.length) return 'break';
            _ref3 = _iterator3[_i3++];
          } else {
            _i3 = _iterator3.next();
            if (_i3.done) return 'break';
            _ref3 = _i3.value;
          }

          var l = _ref3;

          if (Object.is(l.txContext, _this4.context)) {
            _this4.invoice.removeListener(e, l);
          } else {
            Log.debug(function () {
              return 'Skip remove of listener for invoice total ' + _this4.invoice.total + ' this.context.id: ' + _this4.context.id + ', listener.txContext: ' + l.txContext.id;
            });
          }
        };

        for (var _iterator3 = this.invoice.listeners(e), _isArray3 = Array.isArray(_iterator3), _i3 = 0, _iterator3 = _isArray3 ? _iterator3 : _iterator3[Symbol.iterator]();;) {
          var _ref3;

          var _ret = _loop();

          if (_ret === 'break') break;
        }
      }

      for (var _iterator2 = transactionEvents, _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) {
        var _ref2;

        if (_isArray2) {
          if (_i2 >= _iterator2.length) break;
          _ref2 = _iterator2[_i2++];
        } else {
          _i2 = _iterator2.next();
          if (_i2.done) break;
          _ref2 = _i2.value;
        }

        var _e = _ref2;

        for (var _iterator4 = this.context.listeners(_e), _isArray4 = Array.isArray(_iterator4), _i4 = 0, _iterator4 = _isArray4 ? _iterator4 : _iterator4[Symbol.iterator]();;) {
          var _ref4;

          if (_isArray4) {
            if (_i4 >= _iterator4.length) break;
            _ref4 = _iterator4[_i4++];
          } else {
            _i4 = _iterator4.next();
            if (_i4.done) break;
            _ref4 = _i4.value;
          }

          var _l = _ref4;

          this.context.removeListener(_e, _l);
        }
      }

      if (!this._q) {
        return;
      }

      this._q.kill();
      this._q = null;
    } catch (x) {
      Log.error('Invoice Synchronizer failed stopping with error ' + x);
    }
  };

  return InvoiceSynchronizer;
}(_events.EventEmitter);

exports.default = InvoiceSynchronizer;

},{"../common/retailSDKUtil":"/Users/aravidas/Documents/Git/retail-sdk/js/common/retailSDKUtil.js","../paymentDevice/CardReaderDisplayController":"/Users/aravidas/Documents/Git/retail-sdk/js/paymentDevice/CardReaderDisplayController.js","../paymentDevice/displayPriority":"/Users/aravidas/Documents/Git/retail-sdk/js/paymentDevice/displayPriority.js","./transactionEvent":"/Users/aravidas/Documents/Git/retail-sdk/js/transaction/transactionEvent.js","events":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/events/events.js","manticore":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore/browser.js","manticore-log":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-log/index.js","paypal-invoicing":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/index.js","retail-payment-device":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/js/transaction/Payer.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

var _manticoreUtil = require('manticore-util');

var util = _interopRequireWildcard(_manticoreUtil);

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

/**
 * Information about the payer of a transaction, including saved receipt information if
 * available
 * @class
 * @property {string} customerId An identifier for this customer that is specific to your merchant account
 * @property {string} receiptPreferenceToken A token used to send receipts and save/use previously used email address or phone number
 * @property {string} maskedEmail An email address previously used for this payment instrument, with portions masked for privacy
 * @property {string} maskedPhone A masked phone number previously used for this payment instrument
 */
var Payer = function Payer(response) {
  _classCallCheck(this, Payer);

  if (response) {
    util.assignSome(this, response, ['customerId', 'receiptPreferenceToken', 'maskedEmail', 'maskedPhone']);
  }
};

exports.default = Payer;

},{"manticore-util":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-util/build/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/js/transaction/PaymentType.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;
var PaymentType = {
  card: 'card',
  keyIn: 'keyIn',
  cash: 'cash',
  check: 'check'
};

exports.default = PaymentType;

},{}],"/Users/aravidas/Documents/Git/retail-sdk/js/transaction/ReceiptDestination.js":[function(require,module,exports){
"use strict";

exports.__esModule = true;

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

/**
* List of possible receipt destination options, as selected by the user.
* @enum {int}
*/
var ReceiptDestinationType = exports.ReceiptDestinationType = {
  /**
   * User chose the no receipt option.
   */
  none: 0,
  /**
   * User chose the email option and sent the receipt to the email provided.
   */
  email: 1,
  /**
   * User chose the text option and sent the receipt to the provided phone number.
   */
  text: 2
};

/**
 * Contains information about the receipt status.
 * @class
 * @property {ReceiptDestinationType} type Indicates whether an email or a text
 * @property {string} email email address of the receipt is sent @readonly
 * receipt was sent or not. @readonly
 */

var ReceiptDestination = exports.ReceiptDestination = function ReceiptDestination(type, email) {
  _classCallCheck(this, ReceiptDestination);

  this.type = type || ReceiptDestinationType.none;
  this.email = email || null;
};

},{}],"/Users/aravidas/Documents/Git/retail-sdk/js/transaction/ReceiptViewContent.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;
exports.ReceiptViewContent = exports.ReceiptSMSEntryViewContent = exports.ReceiptEmailEntryViewContent = exports.ReceiptOptionsViewContent = undefined;

var _l10n = require('../common/l10n');

var _l10n2 = _interopRequireDefault(_l10n);

var _retailSDKUtil = require('../common/retailSDKUtil');

var retailSDKUtil = _interopRequireWildcard(_retailSDKUtil);

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

/**
 * The content to be presented natively in the receipt options screen.
 * @class
 * @property {string} title
 * @property {string} message
 * @property {string} titleIconFilename
 * @property {string} maskedEmail
 * @property {string} maskedPhone
 * @property {string} disclaimer
 * @property {string} emailButtonTitle
 * @property {string} smsButtonTitle
 * @property {string} noThanksButtonTitle
 * @property {[string]} additionalReceiptOptions
 */
var ReceiptOptionsViewContent = exports.ReceiptOptionsViewContent = function ReceiptOptionsViewContent(amount, isRefund, error, maskedEmail, maskedPhone, additionalReceiptOptions) {
  _classCallCheck(this, ReceiptOptionsViewContent);

  if (isRefund) {
    this.message = error ? (0, _l10n2.default)('Tx.RefundFailed') : (0, _l10n2.default)('Tx.RefundSuccessful');
  } else {
    if (retailSDKUtil.transactionCancelledError(error)) {
      // eslint-disable-line no-lonely-if
      this.message = (0, _l10n2.default)('Tx.CancelledByUser');
    } else if (error) {
      this.message = (0, _l10n2.default)('Tx.TransactionFailed');
    } else {
      this.message = (0, _l10n2.default)('Tx.TransactionSuccessful');
    }
  }

  this.title = (0, _l10n2.default)('Rcpt.Title', { amount: amount });
  this.titleIconFilename = error ? 'ic_x_declined' : 'check_icon_green';
  this.maskedEmail = maskedEmail;
  this.maskedPhone = maskedPhone;
  this.disclaimer = (0, _l10n2.default)('Rcpt.Disclaimer');
  this.emailButtonTitle = (0, _l10n2.default)('Rcpt.EmailButtonTitle');
  this.smsButtonTitle = (0, _l10n2.default)('Rcpt.SMSButtonTitle');
  this.noThanksButtonTitle = (0, _l10n2.default)('Rcpt.NoThanksButtonTitle');
  this.additionalReceiptOptions = additionalReceiptOptions;
  this.prompt = (0, _l10n2.default)('Rcpt.Prompt');
};

/**
 * The content to be presented natively in the receipt email entry screen.
 * @class
 * @property {string} title
 * @property {string} placeholder
 * @property {string} disclaimer
 * @property {string} sendButtonTitle
 */


var ReceiptEmailEntryViewContent = exports.ReceiptEmailEntryViewContent = function ReceiptEmailEntryViewContent() {
  _classCallCheck(this, ReceiptEmailEntryViewContent);

  this.title = (0, _l10n2.default)('Rcpt.Email.Title');
  this.placeholder = (0, _l10n2.default)('Rcpt.Email.Placeholder');
  this.disclaimer = (0, _l10n2.default)('Rcpt.Email.Disclaimer');
  this.sendButtonTitle = (0, _l10n2.default)('Rcpt.Email.SendButtonTitle');
};

/**
 * The content to be presented natively in the receipt sms entry screen.
 * @class
 * @property {string} title
 * @property {string} placeholder
 * @property {string} disclaimer
 * @property {string} sendButtonTitle
 */


var ReceiptSMSEntryViewContent = exports.ReceiptSMSEntryViewContent = function ReceiptSMSEntryViewContent() {
  _classCallCheck(this, ReceiptSMSEntryViewContent);

  this.title = (0, _l10n2.default)('Rcpt.SMS.Title');
  this.placeholder = (0, _l10n2.default)('Rcpt.SMS.Placeholder');
  this.disclaimer = (0, _l10n2.default)('Rcpt.SMS.Disclaimer');
  this.sendButtonTitle = (0, _l10n2.default)('Rcpt.SMS.SendButtonTitle');
};

/**
 * All the content to be displayed in the native receipt flow
 * @class
 * @property {ReceiptOptionsViewContent} receiptOptionsViewContent
 * @property {ReceiptEmailEntryViewContent} receiptEmailEntryViewContent
 * @property {ReceiptSMSEntryViewContent} receiptSMSEntryViewContent
 */


var ReceiptViewContent = exports.ReceiptViewContent = function ReceiptViewContent(amount, isRefund, error, maskedEmail, maskedPhone, additionalReceiptOptions) {
  _classCallCheck(this, ReceiptViewContent);

  this.receiptOptionsViewContent = new ReceiptOptionsViewContent(amount, isRefund, error, maskedEmail, maskedPhone, additionalReceiptOptions);
  this.receiptEmailEntryViewContent = new ReceiptEmailEntryViewContent();
  this.receiptSMSEntryViewContent = new ReceiptSMSEntryViewContent();
};

},{"../common/l10n":"/Users/aravidas/Documents/Git/retail-sdk/js/common/l10n.js","../common/retailSDKUtil":"/Users/aravidas/Documents/Git/retail-sdk/js/common/retailSDKUtil.js"}],"/Users/aravidas/Documents/Git/retail-sdk/js/transaction/SignatureReceiver.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

var _manticore = require('manticore');

var _manticore2 = _interopRequireDefault(_manticore);

var _retailPaymentDevice = require('retail-payment-device');

var _retailPageTracker = require('retail-page-tracker');

var _events = require('events');

var _l10n = require('../common/l10n');

var _l10n2 = _interopRequireDefault(_l10n);

var _messageHelper = require('../flows/messageHelper');

var messageHelper = _interopRequireWildcard(_messageHelper);

var _transactionEvent = require('../transaction/transactionEvent');

var _transactionEvent2 = _interopRequireDefault(_transactionEvent);

var _sdkErrors = require('../common/sdkErrors');

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (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 } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

/**
 * When signature is collected by external code, it will be passed a SignatureReceiver object
 * @class
 * @property {TransactionContext} context @readonly
 */
var SignatureReceiver = function (_EventEmitter) {
  _inherits(SignatureReceiver, _EventEmitter);

  /**
   * @private
   */
  function SignatureReceiver(context, cb) {
    _classCallCheck(this, SignatureReceiver);

    var _this = _possibleConstructorReturn(this, _EventEmitter.call(this));

    _this.context = context;
    _this.cb = cb;
    return _this;
  }

  /**
   * Continue processing the transaction with the supplied signature.
   * @param {string} base64SignatureJpeg The signature as a base64 encoded JPEG image. Try to keep it under 100k
   */


  SignatureReceiver.prototype.continueWithSignature = function continueWithSignature(base64SignatureJpeg) {
    this.context.emit(_transactionEvent2.default.didCompleteSignature, null);
    this.cb(null, base64SignatureJpeg);
  };

  /**
   * Acquire signature using the normal PayPal Retail SDK mechanism (i.e. on screen signing)
   */


  SignatureReceiver.prototype.acquireSignature = function acquireSignature() {
    var _this2 = this;

    var formattedValues = messageHelper.formattedInvoiceTotal(this.context.invoice);
    var titleSubstitutions = {
      amount: formattedValues.amount,
      cardIssuer: this.context.card.cardIssuer && this.context.card.cardIssuer !== _retailPaymentDevice.CardIssuer.Unknown ? _retailPaymentDevice.CardDataUtil.getCardIssuerDisplayName(this.context.card.cardIssuer) : '',
      lastFour: this.context.card.lastFourDigits
    };

    this.sigHandle = _manticore2.default.collectSignature({
      done: (0, _l10n2.default)('Done'),
      footer: (0, _l10n2.default)('Sig.Footer'),
      title: (0, _l10n2.default)('Sig.Title', titleSubstitutions),
      signHere: (0, _l10n2.default)('Sig.Here'),
      cancel: this.context.allowInProgressPaymentCancel ? (0, _l10n2.default)('Cancel') : null
    }, function (error, signature, cancel) {
      if (error) {
        _this2.cb(error);
        return;
      }

      if (cancel) {
        // TODO Use flow.data.alert
        _this2.alert = _manticore2.default.alert({
          title: (0, _l10n2.default)('Tx.Alert.Cancel.Title'),
          message: (0, _l10n2.default)('Tx.Alert.Cancel.Msg'),
          buttons: [(0, _l10n2.default)('Yes')],
          cancel: (0, _l10n2.default)('No')
        }, function (a, ix) {
          a.dismiss();
          if (ix === 0) {
            _this2.cancel();
          }
        });
        return;
      }

      _retailPageTracker.Tracker.publishPageView(null, _retailPageTracker.pages.signature.withAction(_retailPageTracker.action.acquire));
      _this2.continueWithSignature(signature);
    });
  };

  /**
   * Cancel the transaction because of a signature failure.
   */


  SignatureReceiver.prototype.cancel = function cancel() {
    _retailPageTracker.Tracker.publishPageView(null, _retailPageTracker.pages.signature.withAction(_retailPageTracker.action.cancel));
    var error = _sdkErrors.transaction.customerCancel;
    this.context.emit(_transactionEvent2.default.didCompleteSignature, error);
    this.cb(error);
    this.dismiss();
  };

  /**
   * Dismiss any open alert windows and emit 'cancelled' in order to notify custom signature collectors to dismiss their
   * signature collection display
   * @private
   */


  SignatureReceiver.prototype.dismiss = function dismiss() {
    this.emit(SignatureReceiver.event.cancelled);
    if (this.sigHandle) {
      this.sigHandle.dismiss();
    }
  };

  /**
   * Called when the transaction is cancelled while waiting to collect the signature
   * @event SignatureReceiver#cancelled
   */


  return SignatureReceiver;
}(_events.EventEmitter);

exports.default = SignatureReceiver;


SignatureReceiver.event = {
  cancelled: 'cancelled'
};

},{"../common/l10n":"/Users/aravidas/Documents/Git/retail-sdk/js/common/l10n.js","../common/sdkErrors":"/Users/aravidas/Documents/Git/retail-sdk/js/common/sdkErrors.js","../flows/messageHelper":"/Users/aravidas/Documents/Git/retail-sdk/js/flows/messageHelper.js","../transaction/transactionEvent":"/Users/aravidas/Documents/Git/retail-sdk/js/transaction/transactionEvent.js","events":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/events/events.js","manticore":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore/browser.js","retail-page-tracker":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-page-tracker/build/index.js","retail-payment-device":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/js/transaction/TransactionBeginOptions.js":[function(require,module,exports){
"use strict";

exports.__esModule = true;

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

/**
 * TransactionOptions provides the list of customizations for a given transaction
 * @class
 * @property {bool} showPromptInCardReader Show a payment prompt on the card reader's screen (if available) to
 * indicate that the customer/cashier should insert, swipe or tap a card
 * @property {bool} showPromptInApp Show a payment prompt in-app to indicate that the customer/cahsier should
 * insert, swipe or tap a card
 * @property {[FormFactor]} preferredFormFactors Use this property to set the preferred list of form factors for the
 * transaction. The actual list of form factors that will be used for a transaction will be an intersection of
 * available form factors and preferred list
 * @property {bool} tippingOnReaderEnabled Set the flag if the tipping on the reader is enabled
 * @property {bool} amountBasedTipping Set the flag if the amount based tipping type used, otherwise, percentage based used
 * @property {bool} isAuthCapture Setting this to true will only authorize the transaction and a payment will NOT be taken.
 * The money will be moved only when a capture call is made on an authorized transaction.
 * @property {bool} quickChipEnabled Set the flag if Quick Chip feature is Enabled
 */
var TransactionBeginOptions = function () {
  function TransactionBeginOptions() {
    _classCallCheck(this, TransactionBeginOptions);
  }

  TransactionBeginOptions.prototype.toJSON = function toJSON() {
    return {
      showPromptInCardReader: this.showPromptInCardReader,
      showPromptInApp: this.showPromptInApp,
      preferredFormFactors: this.preferredFormFactors,
      tippingOnReaderEnabled: this.tippingOnReaderEnabled,
      amountBasedTipping: this.amountBasedTipping,
      isAuthCapture: this.isAuthCapture,
      quickChipEnabled: this.quickChipEnabled
    };
  };

  TransactionBeginOptions.prototype.toString = function toString() {
    return JSON.stringify(this);
  };

  return TransactionBeginOptions;
}();

exports.default = TransactionBeginOptions;

},{}],"/Users/aravidas/Documents/Git/retail-sdk/js/transaction/TransactionContext.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

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; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

var _manticore = require('manticore');

var _manticore2 = _interopRequireDefault(_manticore);

var _manticoreLog = require('manticore-log');

var _manticoreLog2 = _interopRequireDefault(_manticoreLog);

var _paypalInvoicing = require('paypal-invoicing');

var _retailPageTracker = require('retail-page-tracker');

var _retailPaymentDevice = require('retail-payment-device');

var _manticoreUtil = require('manticore-util');

var _events = require('events');

var _async = require('async');

var _async2 = _interopRequireDefault(_async);

var _l10n = require('../common/l10n');

var _l10n2 = _interopRequireDefault(_l10n);

var _sdkErrors = require('../common/sdkErrors');

var _TransactionStateManager = require('./TransactionStateManager');

var _TransactionStateManager2 = _interopRequireDefault(_TransactionStateManager);

var _transactionStates = require('./transactionStates');

var _PaymentErrorHandler = require('../flows/PaymentErrorHandler');

var _PaymentErrorHandler2 = _interopRequireDefault(_PaymentErrorHandler);

var _Merchant = require('../common/Merchant');

var _Merchant2 = _interopRequireDefault(_Merchant);

var _messageHelper = require('../flows/messageHelper');

var messageHelper = _interopRequireWildcard(_messageHelper);

var _DeviceController = require('./DeviceController');

var _DeviceController2 = _interopRequireDefault(_DeviceController);

var _DeviceSelector = require('../paymentDevice/DeviceSelector');

var _DeviceSelector2 = _interopRequireDefault(_DeviceSelector);

var _transactionEvent = require('./transactionEvent');

var _transactionEvent2 = _interopRequireDefault(_transactionEvent);

var _PaymentType = require('./PaymentType');

var _PaymentType2 = _interopRequireDefault(_PaymentType);

var _OfflineDeclineFlow = require('../flows/OfflineDeclineFlow');

var _OfflineDeclineFlow2 = _interopRequireDefault(_OfflineDeclineFlow);

var _OfferReceiptFlow = require('../flows/OfferReceiptFlow');

var _OfferReceiptFlow2 = _interopRequireDefault(_OfferReceiptFlow);

var _retailSDKUtil = require('../common/retailSDKUtil');

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (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 } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var Log = (0, _manticoreLog2.default)('transactionContext');
var ErrorAction = _PaymentErrorHandler2.default.action;

/**
 * The TransactionContext class is returned by RetailSDK.createTransaction and allows
 * you to control many aspects of the payment or refund flow and observe events that
 * occur during the flows. Simply creating a TransactionContext will not kick off any behaviors,
 * so that you have a chance to configure the transaction context as you wish (choose payment
 * devices, specify transaction options, etc). When you're ready to proceed with the payment flow,
 * call begin()
 * @class
 * @property {Invoice} invoice The invoice being processed for this transaction @readonly
 * @property {TransactionType} type The type of transaction being attempted
 *  (defaults to Sale if the invoice is not already paid, Refund if it is already paid)
 * @property {bool} isSignatureRequired Given the current state of the invoice and transaction,
 *  is a signature required to secure payment? @readonly
 * @property {[PaymentDevice]} paymentDevices If you set the paymentDevices property, this context
 *  will only use the devices you specify to accept
 * payment. This can be useful for cases where a single terminal is managing multiple payment
 *  devices with transactions proceeding in parallel. (This feature is still experimental for
 *  certain payment factors, as any UI will still be single-instance.)
 * @property {string} totalDisplayFooter While building your invoice, the running total
 *  will be displayed on PaymentDevices capable of displaying messages. If you set
 *  totalDisplayFooter, that will be displayed (centered) after the total
 *  amount. Note that once the payment flow starts, EMV certification requires that the display
 *  just show the total and iconography corresponding to expected payment types. Your message
 *  will not be on that screen.
 */

var TransactionContext = function (_EventEmitter) {
  _inherits(TransactionContext, _EventEmitter);

  /**
   * Only JS constructs this
   * @private
   * @param {Invoice} invoice The invoice for this transaction
   * @param {Merchant} merchant The merchant to use for this transaction
   */
  function TransactionContext(invoice, merchant) {
    _classCallCheck(this, TransactionContext);

    var _this = _possibleConstructorReturn(this, _EventEmitter.call(this));

    _this.invoice = invoice;
    _this.merchant = merchant;
    _this.id = 'tx-' + (0, _retailSDKUtil.getRandomId)();
    _this._state = new _TransactionStateManager2.default(_this);
    _this.deviceController = new _DeviceController2.default(_this);
    if (invoice.status === _paypalInvoicing.InvoiceEnums.Status.PAID || invoice.status === _paypalInvoicing.InvoiceEnums.Status.MARKED_AS_PAID || invoice.status === _paypalInvoicing.InvoiceEnums.Status.PARTIALLY_REFUNDED) {
      _this.type = _retailPaymentDevice.TransactionType.Refund;
    } else {
      _this.type = _retailPaymentDevice.TransactionType.Sale;
    }
    Log.debug(function () {
      return 'CREATE transaction with Id ' + _this.id + ' and invoice total: ' + (_this.invoice ? _this.invoice.total : '');
    });

    _this._deferredBeginHandler = function () {
      if (!_DeviceSelector2.default.selectedDevice) {
        Log.error(_this.id + ' Deferred transaction begin invoked without a connected device');
        return;
      }

      if (!_this._deferredActivateOptions) {
        Log.debug(function () {
          return _this.id + ' Deferred transaction begin invoked but options are missing';
        });
        return;
      }
      Log.info('Deferred transaction begin was invoked for \'' + _DeviceSelector2.default.selectedDevice.id + '\'');
      _this.beginPayment(_this._deferredActivateOptions);
    };
    return _this;
  }

  TransactionContext.prototype.toString = function toString() {
    return JSON.stringify(this.toJSON());
  };

  TransactionContext.prototype.toJSON = function toJSON() {
    return {
      id: this.id,
      type: this.type,
      currency: this.invoice ? this.invoice.currency : '',
      total: this.invoice ? this.invoice.total : '',
      state: this._state.toJSON()
    };
  };

  TransactionContext.prototype.processErrorHandlerResponse = function processErrorHandlerResponse(error, errAction, ff, opt) {
    var _this2 = this;

    Log.info('(' + this.id + ') Response from error handler for handling the error-' + error.domain + ':' + error.code + ', ff: ' + (0, _manticoreUtil.getPropertyName)(_retailPaymentDevice.FormFactor, ff) + ' was \'' + (0, _manticoreUtil.getPropertyName)(ErrorAction, errAction) + '\'');
    if (!errAction) {
      return;
    }
    if (errAction === ErrorAction.offlineDecline) {
      var returnError = error.code === _retailPaymentDevice.deviceError.cancelReadCardData.code || error.code === _retailPaymentDevice.deviceError.smartCardNotInSlot.code ? _sdkErrors.transaction.customerCancel : _retailPaymentDevice.deviceError.contactIssuer;

      var offlineDeclineFlow = new _OfflineDeclineFlow2.default(returnError, this, function (data) {
        _this2.end(data.error, data.tx);
      });
      offlineDeclineFlow.startFlow();
      return;
    }

    if (errAction === ErrorAction.abort) {
      var _returnError = error || _sdkErrors.transaction.genericCancel;
      if (error.code === _retailPaymentDevice.deviceError.paymentCancelled.code) {
        _returnError = _sdkErrors.transaction.customerCancel;
      }
      this.end(_returnError);
      return;
    }

    // Setting the payment state to 'retry' to re-ask for tipping when on-reader tipping is enabled
    this._state.setPaymentState(_transactionStates.PaymentState.retry);
    var deactivateFF = [];
    var activateFF = [];
    if (errAction === ErrorAction.retry) {
      activateFF = [_retailPaymentDevice.FormFactor.Chip, _retailPaymentDevice.FormFactor.MagneticCardSwipe, _retailPaymentDevice.FormFactor.EmvCertifiedContactless];
    } else if (errAction === ErrorAction.retryWithInsertOrSwipe) {
      deactivateFF = [_retailPaymentDevice.FormFactor.EmvCertifiedContactless];
      activateFF = [_retailPaymentDevice.FormFactor.Chip, _retailPaymentDevice.FormFactor.MagneticCardSwipe];
    } else if (errAction === ErrorAction.retryWithSwipe) {
      deactivateFF = [_retailPaymentDevice.FormFactor.Chip, _retailPaymentDevice.FormFactor.EmvCertifiedContactless];
      activateFF = [_retailPaymentDevice.FormFactor.MagneticCardSwipe];
    } else if (errAction === ErrorAction.retryWithInsert) {
      deactivateFF = [_retailPaymentDevice.FormFactor.MagneticCardSwipe, _retailPaymentDevice.FormFactor.EmvCertifiedContactless];
      activateFF = [_retailPaymentDevice.FormFactor.Chip];
    }

    var showPrompt = opt && !(0, _retailSDKUtil.isNullOrUndefined)(opt.showPrompt) ? opt.showPrompt : true;
    var syncInvoiceTotal = opt && !(0, _retailSDKUtil.isNullOrUndefined)(opt.syncInvoiceTotal) ? opt.syncInvoiceTotal : true;
    this.deviceController.selectedDevice.deactivateFormFactors(deactivateFF, function () {
      _this2.deviceController.activate({
        showPrompt: showPrompt,
        syncInvoiceTotal: syncInvoiceTotal,
        formFactors: activateFF });
    });
  };

  TransactionContext.prototype.getSetOfActiveFormFactors = function getSetOfActiveFormFactors() {
    return this._state.getSetOfActiveFormFactors();
  };

  /**
   * Returns the current state of payment
   * @returns {PaymentState} Payment state of current transaction
   */


  TransactionContext.prototype.getPaymentState = function getPaymentState() {
    return this._state.getPaymentState();
  };

  /**
   * Returns the current state of tipping
   * @returns {TippingState} Tipping state of current transaction
   */


  TransactionContext.prototype.getTippingState = function getTippingState() {
    return this._state.getTippingState();
  };

  TransactionContext.prototype.setPaymentState = function setPaymentState(state) {
    this._state.setPaymentState(state);
  };

  /**
   * Clear the on-reader tip that was acquired for this transaction
   */


  TransactionContext.prototype.clearOnReaderTip = function clearOnReaderTip() {
    var _this3 = this;

    Log.debug(function () {
      return 'Clearing tip. Will reset acquired on-reader tip amount of ' + _this3.invoice.gratuityAmount + ' to 0';
    });
    this._state.setTippingState(_transactionStates.TippingState.notStarted);
    this.invoice.gratuityAmount = 0;
  };

  /**
   * Begin the flow (activate payment devices, listen for relevant events from devices)
   * @param {TransactionBeginOptions} options Custom options for the transaction
   * @returns {TransactionContext} Returns this object just to make chaining easier
   */


  TransactionContext.prototype.beginPayment = function beginPayment(options) {
    var _this4 = this;

    Log.debug(function () {
      return 'Begin payment on ' + _this4.id + ' with options ' + JSON.stringify(options) + '. PaymentState: ' + (0, _manticoreUtil.getPropertyName)(_transactionStates.PaymentState, _this4.getPaymentState());
    });
    if (this._state.getPaymentState() !== _transactionStates.PaymentState.idle && this._state.getPaymentState() !== _transactionStates.PaymentState.complete) {
      Log.warn('[' + this.id + '] Payment currently in progress. Will not begin payment. Payment State: ' + (0, _manticoreUtil.getPropertyName)(_transactionStates.PaymentState, this.getPaymentState()));
      return this;
    }
    _retailPageTracker.Tracker.publishPageView(null, _retailPageTracker.pages.transaction);
    if (this.type !== _retailPaymentDevice.TransactionType.Sale) {
      this.end(_sdkErrors.transaction.invoiceStatusMismatch);
      return this;
    }

    if (options.isAuthCapture) {
      this.type = _retailPaymentDevice.TransactionType.Auth;
    }

    // If a device is not connected by the time the begin is invoked, defer the invoke to until after the device is connected
    if (!_DeviceSelector2.default.selectedDevice || !_DeviceSelector2.default.selectedDevice.isConnected()) {
      if (!_DeviceSelector2.default.selectedDevice) {
        Log.info(this.id + ' Cannot continue with tx.begin as no device is selected');
      } else {
        Log.info(this.id + ' Cannot continue with tx.begin as ' + _DeviceSelector2.default.selectedDevice.id + ' is not connected and ready');
      }
      this._deferredActivateOptions = options;
      _retailPaymentDevice.PaymentDevice.Events.removeListener(_retailPaymentDevice.PaymentDevice.Event.selected, this._deferredBeginHandler);
      _retailPaymentDevice.PaymentDevice.Events.once(_retailPaymentDevice.PaymentDevice.Event.selected, this._deferredBeginHandler);
      return this;
    }

    _retailPaymentDevice.PaymentDevice.Events.removeListener(_retailPaymentDevice.PaymentDevice.Event.selected, this._deferredBeginHandler);
    if (!options.tippingOnReaderEnabled && this.isInvoiceAmountInvalidForCardReaderTransaction()) {
      options.showPromptInCardReader = false;
      options.showPromptInApp = false;
      options.preferredFormFactors = [_retailPaymentDevice.FormFactor.MagneticCardSwipe, _retailPaymentDevice.FormFactor.Chip];
    }
    this.paymentOptions = options;

    if (options.showPromptInCardReader && options.tippingOnReaderEnabled) {
      this._beginTippingOnReader(options.amountBasedTipping, true, function () {
        Log.debug(function () {
          return 'After tipping, validated invoices... Proceeding to activate ' + _retailPaymentDevice.PaymentDevice.devices.length + ' connected devices for ' + _this4.id;
        });
        if (_this4.isInvoiceAmountInvalidForCardReaderTransaction()) {
          options.showPromptInCardReader = false;
          options.showPromptInApp = false;
          options.preferredFormFactors = [_retailPaymentDevice.FormFactor.MagneticCardSwipe, _retailPaymentDevice.FormFactor.Chip];
        }
        _this4._activateReaders({
          showPromptInCardReader: options.showPromptInCardReader,
          showPromptInApp: options.showPromptInApp,
          formFactors: options.preferredFormFactors,
          syncInvoiceTotal: !options.showPromptInCardReader
        });
      });
    } else {
      Log.debug(function () {
        return 'Validated invoices... Proceeding to activate ' + _retailPaymentDevice.PaymentDevice.devices.length + ' connected devices for ' + _this4.id;
      });
      this._activateReaders({
        showPromptInCardReader: options.showPromptInCardReader,
        showPromptInApp: options.showPromptInApp,
        formFactors: options.preferredFormFactors
      });
    }

    return this;
  };

  TransactionContext.prototype._beginTippingOnReader = function _beginTippingOnReader(amountBasedTip) {
    var _this5 = this;

    var deactivateNeeded = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
    var cb = arguments[2];

    var tipState = this._state.getTippingState();
    var paymentState = this._state.getPaymentState();
    var doTipping = true;
    Log.debug(function () {
      return _this5.id + ' Trying to begin tipping. TippingState: ' + (0, _manticoreUtil.getPropertyName)(_transactionStates.TippingState, tipState) + ', PaymentState: ' + (0, _manticoreUtil.getPropertyName)(_transactionStates.PaymentState, paymentState);
    });
    if (tipState === _transactionStates.TippingState.inProgress || paymentState === _transactionStates.PaymentState.inProgress) {
      Log.debug('Will not start tipping flow as either tipping or payment is in progress');
      doTipping = false;
    } else if (tipState === _transactionStates.TippingState.complete) {
      // Re-acquire tip while retrying a payment
      if (paymentState === _transactionStates.PaymentState.retry && !this.card.isMSRFallbackAllowed) {
        Log.debug('Tipping was complete, but will restart tipping as payment is being retried');
        doTipping = true;
      } else {
        Log.debug('Will not start tipping flow as tipping flow is complete');
        doTipping = false;
      }
    }

    if (!doTipping) {
      Log.debug(function () {
        return _this5.id + ' Bypassing tipping as it cannot be performed in current transaction state';
      });
      if (cb) {
        cb();
      }
      return;
    }

    var activeReader = this.deviceController.selectedDevice;
    if (!activeReader || !activeReader.doesHaveCapability(_retailPaymentDevice.deviceCapabilityType.display)) {
      if (!activeReader) {
        Log.debug(function () {
          return _this5.id + ' Bypassing tipping since there is no active reader';
        });
      } else {
        Log.debug(function () {
          return _this5.id + ' Bypassing tipping since \'' + activeReader.id + '\' does not have display capability';
        });
      }
      if (cb) {
        cb();
      }
      return;
    }
    Log.info('Beginning tipping on on reader. Amount based=' + amountBasedTip + '. ' + this._state);
    this._state.setTippingState(_transactionStates.TippingState.inProgress);
    var TipFlow = require('./../flows/ReaderTippingFlow').default; // eslint-disable-line global-require
    this.tippingFlow = new TipFlow(activeReader, amountBasedTip, this.invoice, function () {
      Log.debug('Tipping on Reader flow completed');
      _this5._state.setTippingState(_transactionStates.TippingState.complete);
      _this5.emit(_transactionEvent2.default.readerTippingCompleted, _this5.invoice.gratuityAmount);
      if (cb) {
        cb();
      }
    });

    var flowStart = function flowStart() {
      _this5._stopInvoiceSync();
      _this5.tippingFlow.start().then(function () {
        Log.debug('Tipping on Reader flow done');
      }, function (error) {
        _this5._state.setTippingState(_transactionStates.TippingState.complete);
        Log.error('Tipping flow failed ' + error);
        if (cb) {
          cb();
        }
      });
    };
    // We don't want card swipes or inserts to be processed during tipping flow
    // That's the reason we do deactivate form factors before starting the tipping flow
    if (deactivateNeeded) {
      this.deactivateFormFactors([].concat(_toConsumableArray(this.getSetOfActiveFormFactors())), flowStart);
    } else {
      flowStart();
    }
  };

  /**
   * Begin the flow to issue a refund on the current invoice.
   * @param {bool} cardPresent true to ask for card data to check against the payment
   * method originally used on the invoice
   * @param {decimal} amount the amount to refund
   * @returns {TransactionContext} Returns this object just to make chaining easier
   */


  TransactionContext.prototype.beginRefund = function beginRefund(cardPresent, amount) {
    var _this6 = this;

    if (this.type !== _retailPaymentDevice.TransactionType.Refund) {
      this.end(_sdkErrors.transaction.invoiceStatusMismatch);
      return this;
    }

    _retailPageTracker.Tracker.publishPageView(null, _retailPageTracker.pages.refund);
    this._reset();
    this.refundAmount = (0, _paypalInvoicing.$$)(amount);
    if (cardPresent) {
      if (this.deviceController.selectedDevice) {
        this.emit(_transactionEvent2.default.refundAmountEntered);
        var alertOpts = {
          title: (0, _l10n2.default)('Tx.Alert.Refund.Title'),
          message: (0, _l10n2.default)('Tx.Alert.Refund.Msg'),
          buttons: [(0, _l10n2.default)('Tx.Alert.Refund.Buttons.WithCard'), (0, _l10n2.default)('Tx.Alert.Refund.Buttons.WithoutCard')],
          cancel: (0, _l10n2.default)('Cancel')
        };
        this.alert = _manticore2.default.alert(alertOpts, function (a, ix) {
          if (_this6.alert) {
            _this6.alert.dismiss();
          }
          if (ix === 2) {
            // Cancel
            return;
          } else if (ix === 0) {
            // Refund with Card
            if (_this6.deviceController.selectedDevice) {
              _this6._activateReaders({ showPromptInCardReader: true, showPromptInApp: true });
            } else {
              _this6.continueWithCard(null);
            }
          } else if (ix === 1) {
            // Refund without Card
            _this6.continueWithCard(null);
          }
        });
      } else {
        this.continueWithCard(null);
      }
    }

    return this;
  };

  TransactionContext.prototype._validateInvoice = function _validateInvoice(cb) {
    var _this7 = this;

    if (!_Merchant2.default.active.cardSettings) {
      cb();
    }

    var deviceMessageId = void 0;
    var alertOpts = void 0;
    var values = void 0;
    var error = void 0;
    if (this.isInvoiceAmountBelowAllowedMinimum()) {
      error = _sdkErrors.transaction.amountTooLow;
      deviceMessageId = _retailPaymentDevice.PaymentDevice.Message.AmountTooLow;
      values = messageHelper.formattedAmount(this.invoice.currency, _Merchant2.default.active.cardSettings.minimum);
      alertOpts = {
        title: (0, _l10n2.default)('Tx.Alert.AmountTooLow.Title'),
        message: (0, _l10n2.default)('Tx.Alert.AmountTooLow.Msg', values),
        cancel: (0, _l10n2.default)('Ok')
      };
      Log.debug(function () {
        return 'Amount too Low for ' + _this7.id;
      });
    } else if (this.isInvoiceAmountAboveAllowedMaximum()) {
      error = _sdkErrors.transaction.amountTooHigh;
      deviceMessageId = _retailPaymentDevice.PaymentDevice.Message.AmountTooHigh;
      values = messageHelper.formattedAmount(this.invoice.currency, _Merchant2.default.active.cardSettings.maximum);
      alertOpts = {
        title: (0, _l10n2.default)('Tx.Alert.AmountTooHigh.Title'),
        message: (0, _l10n2.default)('Tx.Alert.AmountTooHigh.Msg', values),
        cancel: (0, _l10n2.default)('Ok')
      };
      Log.debug(function () {
        return 'Amount too High for ' + _this7.id;
      });
    } else {
      cb();
      return;
    }
    _async2.default.each(this.deviceController.devices, function (pd, callback) {
      return pd.display({ id: deviceMessageId, substitutions: values }, callback);
    }, function () {
      _this7.alert = _manticore2.default.alert(alertOpts, function () {
        cb(error);
      });
    });
  };

  TransactionContext.prototype.isInvoiceAmountBelowAllowedMinimum = function isInvoiceAmountBelowAllowedMinimum() {
    if (!_Merchant2.default.active.cardSettings || !_Merchant2.default.active.cardSettings.minimum) {
      return false;
    }

    var amount = this.isRefund() ? this.refundAmount : this.invoice.total;
    return amount.lessThan(_Merchant2.default.active.cardSettings.minimum);
  };

  TransactionContext.prototype.isInvoiceAmountAboveAllowedMaximum = function isInvoiceAmountAboveAllowedMaximum() {
    if (!_Merchant2.default.active.cardSettings || !_Merchant2.default.active.cardSettings.maximum) {
      return false;
    }

    var amount = this.isRefund() ? this.refundAmount : this.invoice.total;
    return amount.greaterThan(_Merchant2.default.active.cardSettings.maximum);
  };

  TransactionContext.prototype.isInvoiceAmountInvalidForCardReaderTransaction = function isInvoiceAmountInvalidForCardReaderTransaction() {
    return this.isInvoiceAmountBelowAllowedMinimum() || this.isInvoiceAmountAboveAllowedMaximum();
  };

  TransactionContext.prototype._activateReaders = function _activateReaders(opt) {
    var _this8 = this;

    var showPromptInCardReader = opt.showPromptInCardReader;
    var showPromptInApp = opt.showPromptInApp;
    var preferredFormFactors = opt.formFactors;
    var activeReader = this.deviceController.selectedDevice;
    var deviceId = activeReader ? activeReader.id : '<no reader>';
    Log.debug(function () {
      return 'Activating ' + deviceId + ' for \'' + (0, _manticoreUtil.getPropertyName)(_retailPaymentDevice.FormFactor, preferredFormFactors) + '\'';
    });
    if (!preferredFormFactors || preferredFormFactors.length === 0) {
      preferredFormFactors = [_retailPaymentDevice.FormFactor.Chip, _retailPaymentDevice.FormFactor.EmvCertifiedContactless, _retailPaymentDevice.FormFactor.MagneticCardSwipe];
    }

    if (this._state.getPaymentState() === _transactionStates.PaymentState.inProgress || this._state.getTippingState() === _transactionStates.TippingState.inProgress) {
      Log.debug(function () {
        return 'Will not activate reader as ' + _this8.id + ' is not ready. ' + _this8._state;
      });
      return;
    }

    var sActiveFormFactors = this._state.getSetOfActiveFormFactors();
    var ffToActivate = [];

    var _loop = function _loop() {
      if (_isArray) {
        if (_i >= _iterator.length) return 'break';
        _ref = _iterator[_i++];
      } else {
        _i = _iterator.next();
        if (_i.done) return 'break';
        _ref = _i.value;
      }

      var ff = _ref;

      if (!sActiveFormFactors.has(ff)) {
        Log.debug(function () {
          return 'Activate ' + deviceId + '.\'' + (0, _manticoreUtil.getPropertyName)(_retailPaymentDevice.FormFactor, ff) + '\' for ' + _this8.id;
        });
        ffToActivate.push(ff);
      } else {
        Log.debug(function () {
          return 'Will NOT activate \'' + (0, _manticoreUtil.getPropertyName)(_retailPaymentDevice.FormFactor, ff) + '\' on ' + deviceId + ' for ' + _this8.id + ' as it was previously activated';
        });
      }
    };

    for (var _iterator = preferredFormFactors, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
      var _ref;

      var _ret = _loop();

      if (_ret === 'break') break;
    }

    if (ffToActivate.length === 0) {
      Log.info('(' + this.id + ') Will not activate as all provided form factors \'' + (0, _manticoreUtil.getPropertyName)(_retailPaymentDevice.FormFactor, preferredFormFactors) + '\' are already active');
      this.deviceController.updateDeviceDisplayIfError(activeReader);
      return;
    }

    this._reset();
    var active = this.deviceController.activate({ showPrompt: showPromptInCardReader,
      formFactors: ffToActivate,
      syncInvoiceTotal: opt.syncInvoiceTotal
    });
    if (active.error) {
      if (active.error === _sdkErrors.transaction.noFunctionalDevices) {
        // Do not end the transaction. Let it be open for other forms of payment like cash, check, etc.
        Log.warn('Device activate failed as there were no functional devices for ' + this.id);
      } else {
        this.end(active.error);
      }
      return;
    }

    var pd = active.device;
    Log.info('(' + this.id + ') Activated ' + pd.id + ' device for invoice total ' + this.invoice.currency + ' ' + this.invoice.total + ' for form factors: [' + (0, _manticoreUtil.getPropertyName)(_retailPaymentDevice.FormFactor, active.formFactors) + ']');
    if (showPromptInApp) {
      this.promptForPaymentInstrument(pd);
    }
  };

  /**
   * Is the transaction a type of refund?
   * @returns {bool}
   */


  TransactionContext.prototype.isRefund = function isRefund() {
    return this.type === _retailPaymentDevice.TransactionType.Refund || this.type === _retailPaymentDevice.TransactionType.PartialRefund;
  };

  /**
   * Display an alert on the app prompting for payment
   * @param {PaymentDevice} selectedDevice Payment device that was selected for this transaction
   * @param {Set(FormFactor)} sFormFactors (optional) Set of form factors to include in the payment prompt.
   *  Default value will be the form factors approved on the connected devices
   * @param {object} opt Alert options
   * @private
   */


  TransactionContext.prototype.promptForPaymentInstrument = function promptForPaymentInstrument(selectedDevice, sFormFactors, opt) {
    var _this9 = this;

    var ff = sFormFactors || this._state.getSetOfActiveFormFactors();
    var alertId = void 0;
    var imageId = void 0;

    if (selectedDevice && selectedDevice.model && selectedDevice.model === _retailPaymentDevice.ReaderModel.Swiper) {
      // Roam device
      if (ff.has(_retailPaymentDevice.FormFactor.MagneticCardSwipe)) {
        alertId = 'Ready';
        imageId = 'img_reader_status_connected_160';
      }
    } else if (ff.has(_retailPaymentDevice.FormFactor.EmvCertifiedContactless) && ff.has(_retailPaymentDevice.FormFactor.MagneticCardSwipe) && ff.has(_retailPaymentDevice.FormFactor.Chip)) {
      // must be MIURA device
      alertId = 'Ready';
      imageId = 'img_emv_insert_tap_swipe';
    } else if (ff.has(_retailPaymentDevice.FormFactor.MagneticCardSwipe) && ff.has(_retailPaymentDevice.FormFactor.Chip)) {
      alertId = 'ReadyForInsertOrSwipeOnly';
      imageId = 'img_emv_insert_swipe';
    } else if (ff.has(_retailPaymentDevice.FormFactor.MagneticCardSwipe)) {
      alertId = 'ReadyForSwipeOnly';
      imageId = 'img_emv_swipe';
    } else if (ff.has(_retailPaymentDevice.FormFactor.Chip)) {
      alertId = 'ReadyForInsertOnly';
      imageId = 'img_emv_insert';
    }

    if (!alertId) {
      return;
    }

    var title = (0, _l10n2.default)('Tx.Alert.' + alertId + '.Title');
    var message = (0, _l10n2.default)('Tx.Alert.' + alertId + '.Msg');

    if (opt && opt.title) {
      title = opt.title;
    }

    if (opt && opt.message) {
      message = opt.message;
    }

    this.alert = _manticore2.default.alert({
      title: title,
      message: message,
      cancel: (0, _l10n2.default)('Cancel'),
      imageIcon: imageId
    }, function () {
      _this9.alert.dismiss();
      if (_this9.card && _this9.card.emvData && _this9.invoice.payPalId) {
        var offerReceiptFlow = new _OfferReceiptFlow2.default(opt && opt.error, _this9, function (data) {
          _this9.end(data.error, data.tx);
        });
        offerReceiptFlow.startFlow();
        return;
      }
      _this9.end(_sdkErrors.sdk.userCancelled);
    });
  };

  /**
   * Deactivate form factors without ending the transaction. Once deactivated, you should re-begin the transaction to
   * start taking payments
   * @param {[FormFactor]} formFactors Form factors to deactivate
   * @param {TransactionContext~complete} callback
   */


  TransactionContext.prototype.deactivateFormFactors = function deactivateFormFactors(formFactors, callback) {
    var _this10 = this;

    Log.debug(function () {
      return 'Deactivate form factors \'' + (0, _manticoreUtil.getPropertyName)(_retailPaymentDevice.FormFactor, formFactors) + '\' for ' + _this10.id;
    });
    if (this._deferredActivateOptions && this._deferredActivateOptions.preferredFormFactors) {
      for (var _iterator2 = formFactors, _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) {
        var _ref2;

        if (_isArray2) {
          if (_i2 >= _iterator2.length) break;
          _ref2 = _iterator2[_i2++];
        } else {
          _i2 = _iterator2.next();
          if (_i2.done) break;
          _ref2 = _i2.value;
        }

        var _ff = _ref2;

        var i = this._deferredActivateOptions.preferredFormFactors.indexOf(_ff);
        if (i !== -1) {
          this._deferredActivateOptions.preferredFormFactors.splice(i, 1);
        }
      }
    }
    this.deviceController.deactivateFormFactors(formFactors, function (pd) {
      Log.debug(function () {
        return 'Deactivated ' + (0, _manticoreUtil.getPropertyName)(_retailPaymentDevice.FormFactor, formFactors) + ' on ' + (pd ? pd.id : '<no device>');
      });
      if (callback) {
        callback(null);
      }
    });
  };

  /**
   * A transaction is not complete until the end function is called. This function
   * takes care of de-registering various event listeners and clears variables that
   * track transaction state.
   * @private
   */


  TransactionContext.prototype.end = function end(error, txRecord) {
    var _this11 = this;

    var invokeHandler = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;

    Log.debug(function () {
      return 'END ' + _this11.id;
    });
    this._signatureCollector = null;
    this.tokenExpirationHandler = null;
    this.deviceController.startPollingForBattery();
    if (error) {
      Log.error('Ending transaction due to error ' + JSON.stringify(error) + ' ' + this.id);
    } else {
      Log.info('(' + this.id + ') Ending transaction and removing all listeners from ' + this.deviceController.activeDevices.size + ' devices'); // eslint-disable-line max-len
    }
    if (this.alert) {
      this.alert.dismiss();
    }

    if (this.isRefund()) {
      _retailPageTracker.Tracker.publishPageView(error, error ? _retailPageTracker.pages.refundDecline : _retailPageTracker.pages.refundComplete);
    } else {
      _retailPageTracker.Tracker.publishPageView(error, error ? _retailPageTracker.pages.paymentDecline : _retailPageTracker.pages.paymentComplete);
    }
    this._reset();
    if (TransactionContext.active === this) {
      Log.debug(function () {
        return _this11.id + ' is no longer active. TransactionContext.active = null';
      });
      delete TransactionContext.active;
    }
    Log.debug(function () {
      return _this11.id + ' ENDED... Will invoke cancel';
    });
    this._cancel(function () {
      _this11._state.setPaymentState(_transactionStates.PaymentState.complete);
      _this11._state.setPaymentFlowStartedState(false);
      if (_this11.completedHandler && invokeHandler) {
        Log.debug(function () {
          return 'Invoking completed handler \'' + _this11.completedHandler.id + '\' for ' + _this11.id;
        });
        _this11.completedHandler(error, txRecord);
      } else {
        Log.debug(function () {
          return 'Cannot invoke completion handler as it was not set/removed from ' + _this11.id;
        });
      }
      _this11.dropHandlers();
      _this11.deviceController.removeListeners();
    });
  };

  /**
   * Determines if an in-progress payment could be cancelled
   * @private
   */


  TransactionContext.prototype._reset = function _reset() {
    var _this12 = this;

    Log.debug(function () {
      return 'Resetting state of ' + _this12.id;
    });
    this.retryCountInvalidChip = 0;
    this.pinPresent = false;
    this.pinRequired = false;
    this.allowFallBackSwipe = false;
    if (this.card) {
      this.card.isMSRFallbackAllowed = false;
    }
  };

  TransactionContext.prototype.on = function on(eventName, listener) {
    var _this13 = this;

    listener.id = 'tx-listener-' + (0, _retailSDKUtil.getRandomId)();
    _EventEmitter.prototype.on.call(this, eventName, listener);
    Log.debug(function () {
      return 'Listener: ' + _this13.id + ' Added \'' + listener.id + '\' for \'' + eventName + '\' ' + _this13.id + '. ListenerCount: ' + _this13.listenerCount(eventName);
    });
  };

  TransactionContext.prototype.emit = function emit(eventName) {
    var _this14 = this,
        _EventEmitter$prototy;

    Log.debug(function () {
      return 'Listener: ' + _this14.id + ' Emitting \'' + eventName + '\' event to ' + _this14.listenerCount(eventName) + ' listener(s). \'' + _this14.id + '\'';
    });

    var _loop2 = function _loop2() {
      if (_isArray3) {
        if (_i3 >= _iterator3.length) return 'break';
        _ref3 = _iterator3[_i3++];
      } else {
        _i3 = _iterator3.next();
        if (_i3.done) return 'break';
        _ref3 = _i3.value;
      }

      var listener = _ref3;

      Log.debug(function () {
        return '   ' + _this14.id + ' Emitting to \'' + listener.id + '\' listener';
      });
    };

    for (var _iterator3 = this.listeners(eventName), _isArray3 = Array.isArray(_iterator3), _i3 = 0, _iterator3 = _isArray3 ? _iterator3 : _iterator3[Symbol.iterator]();;) {
      var _ref3;

      var _ret2 = _loop2();

      if (_ret2 === 'break') break;
    }

    for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
      args[_key - 1] = arguments[_key];
    }

    (_EventEmitter$prototy = _EventEmitter.prototype.emit).call.apply(_EventEmitter$prototy, [this, eventName].concat(args));
  };

  TransactionContext.prototype.removeListener = function removeListener(eventName, listener) {
    var _this15 = this;

    _EventEmitter.prototype.removeListener.call(this, eventName, listener);
    Log.debug(function () {
      return 'Listener: ' + _this15.id + ' Removed listener \'' + listener.id + '\' for \'' + eventName + '\'. \'' + _this15.id + '\'.  Remaining listeners: ' + _this15.listenerCount(eventName);
    });
  };

  /**
   * Abort an idle transaction abandoning activated readers and all event listeners. The completed event
   * will NOT be fired for this TransactionContext given that you have explicitly abandoned it
   * @param {TransactionContext~complete} callback Callback to invoke after clearing the context
   */


  TransactionContext.prototype.clear = function clear(callback) {
    var _this16 = this;

    if (this._state.getPaymentState() === _transactionStates.PaymentState.inProgress) {
      Log.debug(function () {
        return 'Cannot CLEAR transaction ' + _this16.id + ' as card was presented';
      });
      callback(_sdkErrors.transaction.cannotClearActiveTransaction);
      return;
    }
    Log.debug(function () {
      return 'CLEAR ' + _this16.id + '. Will drop all listeners';
    });
    this._cancel(function () {
      _this16.dropHandlers();
      callback();
    });
  };

  /**
   * Check to see if payment is in 'retry' state. This check helps with
   * disconnection/connection logic when the app goes in the background.
   * @returns {bool} True if the payment is in retry, false otherwise
   */


  TransactionContext.prototype.isPaymentInRetryOrProgress = function isPaymentInRetryOrProgress() {
    return this._state.getPaymentState() === _transactionStates.PaymentState.retry || this._state.getPaymentState() === _transactionStates.PaymentState.inProgress;
  };

  /**
   * Request to cancel an ongoing payment. The request will only be accepted if card was presented and the presented
   * form factor accepts cancellation.
   * @returns {bool} Returns true if payment cancellation was be requested. (This does not guarantee a cancellation)
   */


  TransactionContext.prototype.requestPaymentCancellation = function requestPaymentCancellation() {
    throw new Error('NOT IMPLEMENTED');
    // if (this._state.getPaymentState() === transactionState.idle) {
    //   Log.debug(() => `RequestPaymentCancel: Cancelling as transaction '${this.id}' is in idle state`);
    //   this.end(transactionError.customerCancel, {});
    //   return true;
    // }
    //
    // if (this._state.getPaymentState() === transactionState.paymentInProgress) {
    //   const cardFormFactor = this.card ? getPropertyName(FormFactor, this.card.formFactor) : null;
    //   if (this.card && this.card.reader && this.allowInProgressPaymentCancel()) {
    //     Log.debug(() => `RequestPaymentCancel: Emitting cancel requested event for tx '${this.id}' on reader '${this.card.reader.id}'`);
    //     this.card.reader.emit(PaymentDevice.Event.cancelRequested);
    //     return true;
    //   }
    //   Log.debug(() => `RequestPaymentCancel: Ignoring as transaction '${this.id}' cannot be cancelled. Card presented via ${cardFormFactor}`);
    // }
    // return false;
  };

  // TODO Rename once requestPaymentCancellation is implemented


  TransactionContext.prototype._cancel = function _cancel(callback) {
    var _this17 = this;

    var activeReader = this.deviceController.selectedDevice;
    Log.debug(function () {
      return 'CANCEL ' + _this17.id + ' for active device \'' + (activeReader ? activeReader.id : '<no device>') + '\'. Will drop all listeners';
    });
    if (this._state.getTippingState() === _transactionStates.TippingState.inProgress) {
      Log.debug('The tip flow was cancelled');
      if (this.tippingFlow) {
        this.tippingFlow.abort();
      }
    }

    this._deferredActivateOptions = null;
    _retailPaymentDevice.PaymentDevice.Events.removeListener(_retailPaymentDevice.PaymentDevice.Event.selected, this._deferredBeginHandler);
    this.deviceController.abort(function (pd) {
      Log.debug(function () {
        return 'Aborted tx on ' + (pd ? pd.id : '<no device>') + ' for ' + _this17.id;
      });
      _this17.deviceController.startPollingForBattery();
      var ff = [_retailPaymentDevice.FormFactor.Chip, _retailPaymentDevice.FormFactor.EmvCertifiedContactless, _retailPaymentDevice.FormFactor.MagneticCardSwipe];
      _this17.deactivateFormFactors(ff, function () {
        Log.debug(function () {
          return _this17.id + ' was successfully cancelled. Active ff: \'' + (0, _manticoreUtil.getPropertyName)(_retailPaymentDevice.FormFactor, [].concat(_toConsumableArray(_this17.getSetOfActiveFormFactors()))) + '\'';
        });
        callback();
      });
    });
  };

  /**
   * Remove all handlers
   */


  TransactionContext.prototype.dropHandlers = function dropHandlers() {
    var _this18 = this;

    Log.debug(function () {
      return 'Dropping all response handlers for ' + _this18.id;
    });
    this.completedHandler = null;
    this.cardPresentedHandler = null;
    this.timeoutHandler = null;
    this.cardInsertedHandler = null;
    this.receiptHandler = null;
    for (var property in _transactionEvent2.default) {
      if ({}.hasOwnProperty.call(_transactionEvent2.default, property)) {
        var event = _transactionEvent2.default[property];
        for (var _iterator4 = this.listeners(event), _isArray4 = Array.isArray(_iterator4), _i4 = 0, _iterator4 = _isArray4 ? _iterator4 : _iterator4[Symbol.iterator]();;) {
          var _ref4;

          if (_isArray4) {
            if (_i4 >= _iterator4.length) break;
            _ref4 = _iterator4[_i4++];
          } else {
            _i4 = _iterator4.next();
            if (_i4.done) break;
            _ref4 = _i4.value;
          }

          var l = _ref4;

          this.removeListener(event, l);
        }
      }
    }
  };

  TransactionContext.prototype.setPaymentFlowStarted = function setPaymentFlowStarted() {
    this._state.setPaymentFlowStartedState(true);
  };

  TransactionContext.prototype.getPaymentFlowStarted = function getPaymentFlowStarted() {
    return this._state.getPaymentFlowStartState();
  };

  TransactionContext.prototype.setPaymentInProgress = function setPaymentInProgress() {
    var _this19 = this;

    this._state.setPaymentState(_transactionStates.PaymentState.inProgress);
    Log.debug(function () {
      return 'TransactionContext.active=' + _this19.id;
    });
    TransactionContext.active = this;
  };

  /**
   * Discard the presented card for non-EMV transactions only
   * @param {Card} card The card that was presented
   */


  TransactionContext.prototype.discardPresentedCard = function discardPresentedCard(card) {
    if (!card) {
      return;
    }

    if (this._state.getPaymentState() === _transactionStates.PaymentState.inProgress) {
      var error = _sdkErrors.transaction.cannotDiscardCard.withDevMessage('Cannot discard when payment is in progress');
      Log.error('discardPresentedCard failed with error: ' + error);
      throw error;
    }

    if (card.formFactor === _retailPaymentDevice.FormFactor.Chip || card.formFactor === _retailPaymentDevice.FormFactor.EmvCertifiedContactless) {
      var _error = _sdkErrors.transaction.cannotDiscardCard.withDevMessage('Can only discard non EMV payments after card data read');
      Log.error('discardPresentedCard failed with error: ' + _error);
      throw _error;
    }
    Log.debug(function () {
      return 'Will discard presented card ' + card;
    });
    this.card = null;
  };

  /**
   * Continue processing a transaction - the behavior of which depends on the presented card.
   * If it's a magnetic card or an NFC tap, payment will be attempted and money will move
   * (if successful). If it's an EMV card insertion, we will start the EMV flow which includes
   * a few calls to the server, potentially asking the user to enter a PIN, etc.
   * @param {Card} card The card, typically received via cardPresented, but in certain
   * regions you can simply provide a card number, address verification (AVS) fields such
   * as postal code, expiration and CVV.
   */


  TransactionContext.prototype.continueWithCard = function continueWithCard(card) {
    var _this20 = this;

    if (this._state.getPaymentFlowStartState()) {
      Log.warn(this.id + ' Will not process continueWithCard as payment is in progress');
      return;
    }
    Log.debug(function () {
      return 'Continue with CARD invoked for ' + _this20.id;
    });
    if (card) {
      Log.info(this.id + ' Card (type: ' + card.constructor.name + ') with formFactor \'' + (0, _manticoreUtil.getPropertyName)(_retailPaymentDevice.FormFactor, card.formFactor) + '\' was presented ' + card);
      if (!card.isContactlessMSD && (card.formFactor === _retailPaymentDevice.FormFactor.Chip || card.formFactor === _retailPaymentDevice.FormFactor.EmvCertifiedContactless)) {
        _retailPageTracker.Tracker.publishPageView(null, _retailPageTracker.pages.emv);
      } else if (card.formFactor === _retailPaymentDevice.FormFactor.MagneticCardSwipe) {
        _retailPageTracker.Tracker.publishPageView(null, _retailPageTracker.pages.swipe);
      } else if (card.formFactor === _retailPaymentDevice.FormFactor.ManualCardEntry) {
        _retailPageTracker.Tracker.publishPageView(null, _retailPageTracker.pages.keyIn);
      }

      if (card.formFactor === _retailPaymentDevice.FormFactor.ManualCardEntry) {
        this.card = card;
        var amountError = null;
        if (this.isInvoiceAmountBelowAllowedMinimum()) {
          amountError = _sdkErrors.transaction.amountTooLow;
        } else if (this.isInvoiceAmountAboveAllowedMaximum()) {
          amountError = _sdkErrors.transaction.amountTooHigh;
        }
        if (amountError) {
          var errorHandler = new _PaymentErrorHandler2.default(this);
          errorHandler.handle(amountError, card.formFactor, this.deviceController.selectedDevice, function () {
            return _this20.processErrorHandlerResponse(amountError, null, card.formFactor);
          });
        } else {
          this._continuePayment(_PaymentType2.default.keyIn);
        }
        return;
      }
    } else {
      Log.debug(function () {
        return 'No card presented ' + _this20.id;
      });
    }

    var initializationForFlow = function initializationForFlow() {
      _this20.setPaymentInProgress();
      _this20.deviceController.removeListeners();
    };
    // From this point onwards, the events will be handled by the flow controllers
    var cbFlowComplete = function cbFlowComplete(err, errAction, txRecord, opt) {
      Log[err ? 'error' : 'info']('Transaction flow complete handler was invoked with action: \'' + errAction + '\' and error ' + err + ' ' + _this20.id);
      if (errAction && errAction !== ErrorAction.abort) {
        _this20._state.setPaymentFlowStartedState(false); // Allow payment flows to re-start for online retry scenarios
        _this20.processErrorHandlerResponse(err, errAction, card.formFactor, opt);
      } else {
        _this20.end(err, txRecord);
      }
    };
    if (this.type === _retailPaymentDevice.TransactionType.Sale) {
      this.card = card;
      if (card instanceof _retailPaymentDevice.MagneticCard) {
        Log.debug(function () {
          return 'Magnetic card detected. isMSRFallbackAllowed: ' + card.isMSRFallbackAllowed;
        });
        card.isSignatureRequired = card.isMSRFallbackAllowed || this.invoice.total.greaterThanOrEqualTo(_Merchant2.default.active.signatureRequiredAbove);
      }
      this.paymentType = _PaymentType2.default.card;
      var CCFlow = this.paymentOptions.quickChipEnabled ? require('./../flows/QuickChipCreditCardFlow').default : // eslint-disable-line global-require
      require('./../flows/CreditCardFlow').default; // eslint-disable-line global-require

      // After reading card data, the tipping amount can be added to the tender only for card swipes
      if (this.paymentOptions.tippingOnReaderEnabled && card && card.formFactor === _retailPaymentDevice.FormFactor.MagneticCardSwipe && (this._state.getPaymentState() === _transactionStates.PaymentState.retry || this._state.getTippingState() === _transactionStates.TippingState.notStarted)) {
        this._beginTippingOnReader(this.paymentOptions.amountBasedTipping, false, function () {
          Log.debug(function () {
            return 'After tipping, started the credit card flow for ' + _this20.id;
          });
          initializationForFlow();
          _this20.flow = new CCFlow(card, _this20, cbFlowComplete);
        });
      } else {
        Log.debug(function () {
          return _this20.id + ' Will not start tipping flow tippingOnReaderEnabled=' + _this20.paymentOptions.tippingOnReaderEnabled + ', state=' + _this20._state;
        });
        initializationForFlow();
        this.flow = new CCFlow(card, this, cbFlowComplete);
      }
    } else if (this.type === _retailPaymentDevice.TransactionType.Auth) {
      Log.debug(function () {
        return _this20.id + ' is an AUTH transaction';
      });
      this.card = card;
      if (card instanceof _retailPaymentDevice.MagneticCard) {
        Log.debug(function () {
          return 'Magnetic card detected. isMSRFallbackAllowed: ' + card.isMSRFallbackAllowed;
        });
        card.isSignatureRequired = card.isMSRFallbackAllowed || this.invoice.total.greaterThanOrEqualTo(_Merchant2.default.active.signatureRequiredAbove);
      }
      this.paymentType = _PaymentType2.default.card;
      var _CCFlow = require('./../flows/CreditCardFlow').default; // eslint-disable-line global-require
      initializationForFlow();
      this.flow = new _CCFlow(card, this, cbFlowComplete);
    } else {
      initializationForFlow();
      this.card = card;
      var RefundFlow = require('./../flows/refundFlow').default; // eslint-disable-line global-require
      this.flow = new RefundFlow(card, this, cbFlowComplete);
    }
  };

  /**
   * Sync the Invoice total to the reader display. Use this function to sync
   * invoice amount on the app to the reader. This automatic invoice syncing will stop based on the transaction state.
   * Use 'syncInvoiceOnce' to do an on-demand push invoice total to the card reader display
   */


  TransactionContext.prototype.startInvoiceSync = function startInvoiceSync() {
    this.deviceController.syncInvoice();
  };

  /**
   * Do a one time sync of invoice total to card reader
   */


  TransactionContext.prototype.syncInvoiceOnce = function syncInvoiceOnce() {
    this.deviceController.syncOnce();
  };

  TransactionContext.prototype._stopInvoiceSync = function _stopInvoiceSync() {
    this.deviceController.stopInvoiceSync();
  };

  /**
   * Continue processing a cash transaction.
   */


  TransactionContext.prototype.continueWithCash = function continueWithCash() {
    var _this21 = this;

    Log.debug(function () {
      return 'Continue with CASH invoked for ' + _this21.id;
    });
    if (this.type === _retailPaymentDevice.TransactionType.Auth) {
      Log.error(function () {
        return 'CASH is not supported for an authorization';
      });
      this.end(_sdkErrors.transaction.invalidAuthorization);
      return;
    }
    this._continuePayment(_PaymentType2.default.cash);
  };

  /**
   * Continue processing a check transaction.
   */


  TransactionContext.prototype.continueWithCheck = function continueWithCheck() {
    var _this22 = this;

    Log.debug(function () {
      return 'Continue with CHECK invoked for ' + _this22.id;
    });
    if (this.type === _retailPaymentDevice.TransactionType.Auth) {
      Log.error(function () {
        return 'CHECK is not supported for an authorization';
      });
      this.end(_sdkErrors.transaction.invalidAuthorization);
      return;
    }
    this._continuePayment(_PaymentType2.default.check);
  };

  TransactionContext.prototype._continuePayment = function _continuePayment(paymentType) {
    var _this23 = this;

    if (this._state.getPaymentFlowStartState()) {
      Log.warn(this.id + ' Will not process _continuePayment as payment is in progress');
      return;
    }
    this.setPaymentInProgress();
    this.deactivateFormFactors([_retailPaymentDevice.FormFactor.EmvCertifiedContactless], function () {
      _this23.deviceController.removeListeners();
      _this23.paymentType = paymentType;
      _this23._stopInvoiceSync();
      var PaymentFlow = require('./../flows/PaymentFlow').default; // eslint-disable-line global-require
      _this23.flow = new PaymentFlow(_this23, function (err, action, record) {
        return _this23.end(err, record);
      });
    });
  };

  /**
   * If you acquire signatures yourself, for example from a Topaz Pen Pad or with an external
   * camera, set this property to a handler that will be invoked when signature should be
   * collected. Once you've collected the signature, call the supplied signatureReceiver
   * with a base64 encoded JPG of the signature. Try to keep it under 100k.
   * @param {TransactionContext~signatureCollector} collector The function that will be
   *  called when a signature should be acquired
   */


  TransactionContext.prototype.setSignatureCollector = function setSignatureCollector(collector) {
    this._signatureCollector = collector;
  };

  /**
   * Provide a token expiration handler if you want to handle token expirations during a transaction
   * @param {TransactionContext~tokenExpirationHandler} expirationHandler
   */


  TransactionContext.prototype.setTokenExpiredHandler = function setTokenExpiredHandler(expirationHandler) {
    var _this24 = this;

    if (!expirationHandler) {
      this.timeoutHandler = null;
      return;
    }
    var handler = function handler(handle) {
      Log.debug(function () {
        return 'Invoking token expiration handler ' + handler.id + ' for ' + _this24.id;
      });
      expirationHandler(handle);
    };
    handler.id = 'timeout-' + (0, _retailSDKUtil.getRandomId)();
    this.timeoutHandler = handler;
    Log.debug(function () {
      return 'Set token expiration handler to ' + handler.id + ' for ' + _this24.id;
    });
  };

  /**
   * Provide a handler to get notified after chip card insert is detected but before EMV data is read.
   * cardInsertedHandler.continueWithCardDataRead must be invoked to continue with transaction
   * @param {TransactionContext~cardInsertedHandler} cardInsertedHandler
   */


  TransactionContext.prototype.setCardInsertedHandler = function setCardInsertedHandler(cardInsertedHandler) {
    var _this25 = this;

    if (!cardInsertedHandler) {
      this.cardInsertedHandler = null;
      return;
    }
    var handler = function handler(handle) {
      Log.debug(function () {
        return 'Invoking card inserted handler ' + handler.id + ' for ' + _this25.id;
      });
      var cardInsertedHandle = new _retailPaymentDevice.CardInsertedHandler(function () {
        Log.debug('Card Inserted Handler : about to read card data.');
        _this25.deviceController.cardInsertDetected();
        _this25.deviceController.stopPollingForBattery();
        _this25._stopInvoiceSync();
        handle.continueWithCardDataRead();
      });
      cardInsertedHandle.dismissSDKUIPrompt = function () {
        if (_this25.alert) {
          _this25.alert.dismiss();
        }
      };
      cardInsertedHandler(cardInsertedHandle);
    };
    handler.id = 'cardInserted-' + (0, _retailSDKUtil.getRandomId)();
    this.cardInsertedHandler = handler;
    Log.debug(function () {
      return 'Set card inserted handler to ' + handler.id + ' for ' + _this25.id;
    });
  };

  /**
   * Provide a handler to get notified when card was presented.
   * @param {TransactionContext~cardPresented} cardPresentedHandler
   */


  TransactionContext.prototype.setCardPresentedHandler = function setCardPresentedHandler(cardPresentedHandler) {
    var _this26 = this;

    if (!cardPresentedHandler) {
      this.cardPresentedHandler = null;
      return;
    }
    var handler = function handler(card) {
      Log.debug(function () {
        return 'Invoking card PRESENTED handler ' + handler.id + ' for ' + _this26.id;
      });
      cardPresentedHandler(card);
    };
    handler.id = 'cardPresented-' + (0, _retailSDKUtil.getRandomId)();
    this.cardPresentedHandler = handler;
    Log.debug(function () {
      return 'Set card presented handler to ' + handler.id + ' for ' + _this26.id;
    });
  };

  /**
   * Provide a handler to get notified once transaction is complete
   * @param {TransactionContext~transactionCompleted} completedHandler
   */


  TransactionContext.prototype.setCompletedHandler = function setCompletedHandler(completedHandler) {
    var _this27 = this;

    if (!completedHandler) {
      this.completedHandler = null;
      return;
    }
    var handler = function handler(err, txRecord) {
      Log.debug(function () {
        return 'Invoking COMPLETION handler ' + handler.id + ' for ' + _this27.id;
      });
      completedHandler(err, txRecord);
    };
    handler.id = 'completed-' + (0, _retailSDKUtil.getRandomId)();
    this.completedHandler = handler;
    Log.debug(function () {
      return 'Set completed handler to ' + handler.id + ' for ' + _this27.id;
    });
  };

  /**
   * If you would like to display additional receipt options such as print, etc., you can provide them here. These
   * options would be presented on the receipt screen below the Email and Text options.
   * @param {[string]} additionalReceiptOptions Additional options to display on the receipt page
   * @param {TransactionContext~receiptOptionHandler} receiptHandler Provide a handler to get notified when an additional receipt option is selected
   */


  TransactionContext.prototype.setAdditionalReceiptOptions = function setAdditionalReceiptOptions(additionalReceiptOptions, receiptHandler) {
    var _this28 = this;

    if (!receiptHandler) {
      this.receiptHandler = null;
      return;
    }
    var handler = function handler(index, name, txRecord) {
      Log.debug(function () {
        return 'Invoking additional receipt options handler ' + handler.id + ' for ' + _this28.id + ' with index: ' + index + ', name: ' + name;
      });
      receiptHandler(index, name, txRecord);
    };
    handler.id = 'receiptOptions-' + (0, _retailSDKUtil.getRandomId)();
    this.receiptHandler = handler;
    this.additionalReceiptOptions = additionalReceiptOptions;
    Log.debug(function () {
      return 'Set additional receipt options handler to ' + handler.id + ' for ' + _this28.id;
    });
  };

  _createClass(TransactionContext, [{
    key: 'totalDisplayFooter',
    get: function get() {
      return this._totalDisplayFooter;
    },
    set: function set(value) {
      this._totalDisplayFooter = value;
      this.emit(_transactionEvent2.default.invoiceDisplayFooterUpdated);
    }
  }, {
    key: 'allowInProgressPaymentCancel',
    get: function get() {
      return this.card && this.card.formFactor !== _retailPaymentDevice.FormFactor.MagneticCardSwipe && !this.card.isContactlessMSD;
    }
  }]);

  return TransactionContext;
}(_events.EventEmitter);

/**
 * Called when either payment completes or fails.
 * Note that other events may be fired in the meantime.
 * @callback TransactionContext~transactionCompleted
 * @param {error} error The error that caused the transaction to fail, if any
 * @param {TransactionRecord} record The transaction record for successful transactions
 *  and failed transactions that reached PayPal.
 */

/**
 * Depending on your region and the buyer payment type, this can mean a magnetic
 * card was swiped, an EMV card was inserted, or an NFC card/device was tapped.
 * @callback TransactionContext~cardPresented
 * @param {Card} card Information about the card.
 */

/**
 * Contactless reader was de-activated and the transaction still remains active.
 * @event TransactionContext#contactlessReaderDeactivated
 */

/**
 * Called when PIN entry is in progress or complete
 * @protected
 * @event TransactionContext#pinEntry
 * @param {bool} complete The PIN entry is complete
 * @param {bool} correct The PIN entry is correct
 * @param {int} pinDigits The number of digits entered
 * @param {bool} lastAttempt Whether this is the last attempt before pin lockout
 */

/**
 * Called when the signature input interface will be displayed
 * @event TransactionContext#willPresentSignature
 */

/**
 * Called when the tipping on reader flow has been completed
 * @event TransactionContext#readerTippingCompleted
 * @param {decimal} tipAmount The tip amount set in the invoice after tipping on reader flow completes
 */

/**
 * Called when the signature entry is completed
 * @event TransactionContext#didCompleteSignature
 * @param {error} error The error which caused the signature not to be acquired or saved,
 *  or null if it worked
 */

/**
 * @callback TransactionContext~signatureCollector
 * @param {SignatureReceiver} signatureReceiver Call continueWithSignature or
 *  cancel on this object once signature acquisition is complete.
 */

/**
 * @callback TransactionContext~tokenExpirationHandler
 * @param {TokenExpirationHandler} tokenExpirationHandler Call quit to abort the transaction or call continueWithNewToken
 * by providing a valid composite token
 */

/**
 * @callback TransactionContext~cardInsertedHandler
 * @param {CardInsertedHandler} cardInsertedHandler Call continue to read EMV data from inserted chip card
 */

/**
 * Called when one of the additional receipt option is selected.
 * @callback TransactionContext~receiptOptionHandler
 * @param {int} index The index of the selected receipt option.
 * @param {string} name The name of the selected receipt option.
 * @param {TransactionRecord} record The transaction record for successful transactions
 *  and failed transactions that reached PayPal. @readonly
 */

/**
 * @callback TransactionContext~complete
 * @param {error} error Error (if any)
 */


exports.default = TransactionContext;

},{"../common/Merchant":"/Users/aravidas/Documents/Git/retail-sdk/js/common/Merchant.js","../common/l10n":"/Users/aravidas/Documents/Git/retail-sdk/js/common/l10n.js","../common/retailSDKUtil":"/Users/aravidas/Documents/Git/retail-sdk/js/common/retailSDKUtil.js","../common/sdkErrors":"/Users/aravidas/Documents/Git/retail-sdk/js/common/sdkErrors.js","../flows/OfferReceiptFlow":"/Users/aravidas/Documents/Git/retail-sdk/js/flows/OfferReceiptFlow.js","../flows/OfflineDeclineFlow":"/Users/aravidas/Documents/Git/retail-sdk/js/flows/OfflineDeclineFlow.js","../flows/PaymentErrorHandler":"/Users/aravidas/Documents/Git/retail-sdk/js/flows/PaymentErrorHandler.js","../flows/messageHelper":"/Users/aravidas/Documents/Git/retail-sdk/js/flows/messageHelper.js","../paymentDevice/DeviceSelector":"/Users/aravidas/Documents/Git/retail-sdk/js/paymentDevice/DeviceSelector.js","./../flows/CreditCardFlow":"/Users/aravidas/Documents/Git/retail-sdk/js/flows/CreditCardFlow.js","./../flows/PaymentFlow":"/Users/aravidas/Documents/Git/retail-sdk/js/flows/PaymentFlow.js","./../flows/QuickChipCreditCardFlow":"/Users/aravidas/Documents/Git/retail-sdk/js/flows/QuickChipCreditCardFlow.js","./../flows/ReaderTippingFlow":"/Users/aravidas/Documents/Git/retail-sdk/js/flows/ReaderTippingFlow.js","./../flows/refundFlow":"/Users/aravidas/Documents/Git/retail-sdk/js/flows/refundFlow.js","./DeviceController":"/Users/aravidas/Documents/Git/retail-sdk/js/transaction/DeviceController.js","./PaymentType":"/Users/aravidas/Documents/Git/retail-sdk/js/transaction/PaymentType.js","./TransactionStateManager":"/Users/aravidas/Documents/Git/retail-sdk/js/transaction/TransactionStateManager.js","./transactionEvent":"/Users/aravidas/Documents/Git/retail-sdk/js/transaction/transactionEvent.js","./transactionStates":"/Users/aravidas/Documents/Git/retail-sdk/js/transaction/transactionStates.js","async":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/async/lib/async.js","events":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/events/events.js","manticore":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore/browser.js","manticore-log":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-log/index.js","manticore-util":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-util/build/index.js","paypal-invoicing":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/index.js","retail-page-tracker":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-page-tracker/build/index.js","retail-payment-device":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/js/transaction/TransactionManager.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

var _manticoreLog = require('manticore-log');

var _manticoreLog2 = _interopRequireDefault(_manticoreLog);

var _paypalInvoicing = require('paypal-invoicing');

var _Merchant = require('../common/Merchant');

var _Merchant2 = _interopRequireDefault(_Merchant);

var _sdkErrors = require('../common/sdkErrors');

var _TransactionContext = require('./TransactionContext');

var _TransactionContext2 = _interopRequireDefault(_TransactionContext);

var _RetailInvoice = require('../common/RetailInvoice');

var _authManager = require('./authManager');

var _authManager2 = _interopRequireDefault(_authManager);

var _voidManager = require('./voidManager');

var _voidManager2 = _interopRequireDefault(_voidManager);

var _captureManager = require('./captureManager');

var _captureManager2 = _interopRequireDefault(_captureManager);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

var Log = (0, _manticoreLog2.default)('TxManager');

/**
 * TransactionManager is a public facing facade to everything related to a Transaction.
 * @class
 */

var TransactionManager = function () {
  function TransactionManager() {
    _classCallCheck(this, TransactionManager);
  }

  /**
   * Create a transaction using the provided Invoice. An existing transaction will be canceled
   * @param {Invoice} invoice
   * @param {TransactionManager~transaction} callback
   */
  TransactionManager.prototype.createTransaction = function createTransaction(invoice, callback) {
    var _this = this;

    if (!_Merchant2.default.active) {
      callback(_sdkErrors.merchant.notInitialized.withDevMessage('You must have an active merchant to create a transaction.' + 'Call InitializeMerchant first, and wait for it to complete.'));
      return;
    }
    this._tryClearCurrentTx(function (err) {
      if (err) {
        Log.error('Unable to clear existing transaction ' + _this._tx + ' due to error ' + err);
      }
      _this._tx = new _TransactionContext2.default(invoice, _Merchant2.default.active);
      callback(null, _this._tx);
    });
  };

  /**
   * Create a refund transaction. An existing transaction will be canceled
   * @param {string} invoiceId
   * @param {string} transactionNumber
   * @param {Invoice.PaymentMethod} paymentMethod
   * @param {TransactionManager~transaction} callback
   */


  TransactionManager.prototype.createRefundTransaction = function createRefundTransaction(invoiceId, transactionNumber, paymentMethod, callback) {
    var _this2 = this;

    if (!_Merchant2.default.active) {
      callback(_sdkErrors.merchant.notInitialized.withDevMessage('You must have an active merchant to create a transaction.' + 'Call InitializeMerchant first, and wait for it to complete.'));
      return;
    }
    this._tryClearCurrentTx(function (err) {
      if (err) {
        Log.error('Unable to clear existing transaction ' + _this2._tx + ' due to error ' + err);
      }

      var payment = new _RetailInvoice.RetailInvoicePayment();
      payment.transactionID = transactionNumber;
      payment.method = paymentMethod;

      var invoice = new _RetailInvoice.RetailInvoice(_Merchant2.default.active.currency);
      invoice.payPalId = invoiceId;
      invoice.status = _paypalInvoicing.InvoiceEnums.Status.PAID;
      invoice.payments = [payment];
      _this2._tx = new _TransactionContext2.default(invoice, _Merchant2.default.active);
      callback(null, _this2._tx);
    });
  };

  TransactionManager.prototype._tryClearCurrentTx = function _tryClearCurrentTx(cb) {
    if (!this._tx) {
      cb(null);
      return;
    }
    this._tx.clear(cb);
  };

  /**
   * Retrieve the list of authorized transactions.
   * @param {Date} startDateTime start date time for listing the authorized transactions. Cannot be greater than endDateTime or current date-time.
   * @param {Date} endDateTime end date time for listing the authorized transactions. Defaults to startDateTime + 5 days.
   * If provided it should be less than or equal to (startDateTime + 5 days)
   * @param {int} pageSize number of authorized transactions to be returned per API call. Has to be greater than 0 and less than 31.
   * @param {[AuthStatus]} status list of status that need to be retrieved. Optional, defaults to all status.
   * @param {TransactionManager~retrieveAuthorizedTransactions} callback
   */


  TransactionManager.prototype.retrieveAuthorization = function retrieveAuthorization(startDateTime, endDateTime, pageSize, status, callback) {
    if (!_Merchant2.default.active) {
      callback(_sdkErrors.merchant.notInitialized.withDevMessage('You must have an active merchant to capture an ' + 'authorized transaction. Call InitializeMerchant first, and wait for it to complete.'));
      return;
    }
    (0, _authManager2.default)(startDateTime, endDateTime, pageSize, status, null, callback);
  };

  /**
   * Retrieve the next list of authorized transactions using the nextPageToken.
   * @param {string} nextPageToken token to retrive the next page of objects. Cannot be null.
   * @param {TransactionManager~retrieveAuthorizedTransactions} callback
   */


  TransactionManager.prototype.retrieveAuthorizationUsingToken = function retrieveAuthorizationUsingToken(nextPageToken, callback) {
    if (!_Merchant2.default.active) {
      callback(_sdkErrors.merchant.notInitialized.withDevMessage('You must have an active merchant to capture an ' + 'authorized transaction. Call InitializeMerchant first, and wait for it to complete.'), null, null);
      return;
    }
    if (!nextPageToken || nextPageToken === '') {
      callback(_sdkErrors.sdk.validationError.withDevMessage('nextPageToken cannot be null'), null, null);
      return;
    }
    (0, _authManager2.default)(null, null, null, null, nextPageToken, callback);
  };

  /**
   * Void an authorized transaction
   * @param {string} authorizationId The authorization id of the transaction. Cannot be null.
   * @param {TransactionManager~voidAuthorization} callback
   */


  TransactionManager.prototype.voidAuthorization = function voidAuthorization(authorizationId, callback) {
    if (!_Merchant2.default.active) {
      callback(_sdkErrors.merchant.notInitialized.withDevMessage('You must have an active merchant to void an ' + 'authorized transaction. Call InitializeMerchant first, and wait for it to complete.'));
      return;
    }
    (0, _voidManager2.default)(authorizationId, callback);
  };

  /**
   * Capture a previously authorized transaction.
   * @param {string} authorizationId the authorizationId to be captured.
   * @param {string} invoiceId the invoice id associated with the authorization.
   * @param {decimal} totalAmount the total amount that has to be captured.
   * @param {decimal} gratuityAmount (optional) the gratuity amount that is also part of the totalAmount. If present, should be less than total Amount.
   * @param {string} currency the currency in which authorization was placed.
   * @param {TransactionManager~captureAuthorizedTransaction} callback
   */


  TransactionManager.prototype.captureAuthorization = function captureAuthorization(authorizationId, invoiceId, totalAmount, gratuityAmount, currency, callback) {
    if (!_Merchant2.default.active) {
      callback(_sdkErrors.merchant.notInitialized.withDevMessage('You must have an active merchant to capture an ' + 'authorized transaction. Call InitializeMerchant first, and wait for it to complete.'));
      return;
    }
    (0, _captureManager2.default)(authorizationId, invoiceId, totalAmount, gratuityAmount, currency, callback);
  };

  return TransactionManager;
}();

/**
 * The callback for creating a transaction
 * @callback TransactionManager~transaction
 * @param {error} error Error reported while created a transaction
 * @param {TransactionContext} context Transaction context
 */

/**
 * The callback for retrieveAuthorizedTransactions completion
 * @callback TransactionManager~retrieveAuthorizedTransactions
 * @param {error} error Error reported while trying to retrieve list of authorized transactions
 * @param {[AuthorizedTransaction]} listOfAuths list of authorized transactions
 * @param {string} nextPageToken token to retrieve the next page of objects. Will be null if there is no next page.
 * as a object
 */

/**
 * The callback for voidTransaction completion
 * @callback TransactionManager~voidAuthorization
 * @param {error} error Error reported while trying to void an authorized transaction
 */

/**
 * The callback for captureAuthorizedTransaction completion
 * @callback TransactionManager~captureAuthorizedTransaction
 * @param {error} error Error reported while trying to capture the authorized transaction
 * @param {string} captureId Id after a successful capture
 */

var transactionManager = new TransactionManager();
exports.default = transactionManager;

},{"../common/Merchant":"/Users/aravidas/Documents/Git/retail-sdk/js/common/Merchant.js","../common/RetailInvoice":"/Users/aravidas/Documents/Git/retail-sdk/js/common/RetailInvoice.js","../common/sdkErrors":"/Users/aravidas/Documents/Git/retail-sdk/js/common/sdkErrors.js","./TransactionContext":"/Users/aravidas/Documents/Git/retail-sdk/js/transaction/TransactionContext.js","./authManager":"/Users/aravidas/Documents/Git/retail-sdk/js/transaction/authManager.js","./captureManager":"/Users/aravidas/Documents/Git/retail-sdk/js/transaction/captureManager.js","./voidManager":"/Users/aravidas/Documents/Git/retail-sdk/js/transaction/voidManager.js","manticore-log":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-log/index.js","paypal-invoicing":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/js/transaction/TransactionRecord.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

var _manticoreUtil = require('manticore-util');

var util = _interopRequireWildcard(_manticoreUtil);

var _Payer = require('./Payer');

var _Payer2 = _interopRequireDefault(_Payer);

var _ReceiptDestination = require('./ReceiptDestination');

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

/**
 * Information about a completed transaction
 * @class
 * @property {string} transactionNumber The PayPal transaction reference number @readonly
 * @property {string} invoiceId The PayPal invoice id @readonly
 * @property {string} authCode The PayPal authCode @readonly
 * @property {string} transactionHandle An identifier available throughout the EMV transaction flow
 * (allocated before the transaction is complete, unlike transactionNumber) @readonly
 * @property {string} responseCode The acquirer response code @readonly
 * @property {Payer} payer Information about the payer, if available @readonly
 * @property {string} correlationId The correlationId used for obtaining additional support
 * from PayPal for this transaction attempt @readonly
 * @property {Card} card card that was presented by the consumer for this transaction @readonly
 * @property {ReceiptDestination} receiptDestination Indicates whether an email or a text
 * receipt was sent or not. @readonly
 */
var TransactionRecord = function () {
  /**
   * @private
   */
  function TransactionRecord(response) {
    _classCallCheck(this, TransactionRecord);

    // AuthCode is not an externally accessible value, but we use it internally so we copy it over.
    util.assignSome(this, response, ['correlationId', 'transactionNumber', 'invoiceId', 'transactionHandle', 'responseCode', 'authCode', 'errorCode']);
    if (response.payerInfo) {
      this.payer = new _Payer2.default(response.payerInfo);
    }
    // In case of refunds, the transaction number is returned as an `id`
    if (response.id) {
      this.transactionNumber = response.id;
    }
    // For some reason, in a few of the MTP failures, the transaction handle is returned as `txnHandle` instead of `transactionHandle` :-(
    if (response.txnHandle && !this.transactionHandle) {
      this.transactionHandle = response.txnHandle;
    }
    if (response.invoiceId) {
      this.invoiceId = response.invoiceId;
    }

    this.receiptDestination = new _ReceiptDestination.ReceiptDestination();
  }

  /**
   * @private
   */


  TransactionRecord.prototype.updateFromFinalize = function updateFromFinalize(finalize) {
    if (!this.transactionNumber) {
      this.transactionNumber = finalize.transactionNumber;
    }

    if (finalize.correlationId && this.correlationId) {
      this.correlationId = this.correlationId + ',' + finalize.correlationId;
    } else if (finalize.correlationId) {
      this.correlationId = finalize.correlationId;
    }
    if (finalize.payerInfo) {
      this.payer = new _Payer2.default(finalize.payerInfo);
    }
  };

  TransactionRecord.prototype.toString = function toString() {
    return 'invoiceId: ' + this.invoiceId + ', transactionNumber: ' + this.transactionNumber + ', transactionHandle: ' + this.transactionHandle + ', ' + ('responseCode: ' + this.responseCode + ', correlationId: ' + this.correlationId);
  };

  return TransactionRecord;
}();

exports.default = TransactionRecord;


TransactionRecord.Error = {
  ContactlessNotAcceptable: 600075,
  IncorrectOnlinePin: 6000164
};

},{"./Payer":"/Users/aravidas/Documents/Git/retail-sdk/js/transaction/Payer.js","./ReceiptDestination":"/Users/aravidas/Documents/Git/retail-sdk/js/transaction/ReceiptDestination.js","manticore-util":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-util/build/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/js/transaction/TransactionStateManager.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

var _manticoreLog = require('manticore-log');

var _manticoreLog2 = _interopRequireDefault(_manticoreLog);

var _manticoreUtil = require('manticore-util');

var _retailPaymentDevice = require('retail-payment-device');

var _transactionStates = require('./transactionStates');

var _DeviceSelector = require('../paymentDevice/DeviceSelector');

var _DeviceSelector2 = _interopRequireDefault(_DeviceSelector);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

var Log = (0, _manticoreLog2.default)('transaction.State');

var TransactionStateManager = function () {
  function TransactionStateManager(context) {
    _classCallCheck(this, TransactionStateManager);

    this._paymentState = _transactionStates.PaymentState.idle;
    this._tippingState = _transactionStates.TippingState.notStarted;
    this._sActiveFormFactors = new Set();
    this._context = context;
  }

  TransactionStateManager.prototype.toString = function toString() {
    return JSON.stringify(this.toJSON());
  };

  TransactionStateManager.prototype.toJSON = function toJSON() {
    return {
      paymentState: (0, _manticoreUtil.getPropertyName)(_transactionStates.PaymentState, this.getPaymentState()),
      tippingState: (0, _manticoreUtil.getPropertyName)(_transactionStates.TippingState, this.getTippingState()),
      connectedDevices: _retailPaymentDevice.PaymentDevice.devices.length,
      selectedDevice: _DeviceSelector2.default.selectedDevice ? _DeviceSelector2.default.selectedDevice.id : '<none>',
      activeFormFactors: (0, _manticoreUtil.getPropertyName)(_retailPaymentDevice.FormFactor, [].concat(_toConsumableArray(this.getSetOfActiveFormFactors())))
    };
  };

  TransactionStateManager.prototype.getPaymentState = function getPaymentState() {
    return this._paymentState;
  };

  TransactionStateManager.prototype.setPaymentState = function setPaymentState(value) {
    var _this = this;

    this._paymentState = value;
    Log.debug(function () {
      return 'Setting PAYMENT state of ' + _this._context.id + ' to ' + (0, _manticoreUtil.getPropertyName)(_transactionStates.PaymentState, value);
    });
  };

  TransactionStateManager.prototype.getTippingState = function getTippingState() {
    return this._tippingState;
  };

  TransactionStateManager.prototype.setTippingState = function setTippingState(value) {
    var _this2 = this;

    this._tippingState = value;
    Log.debug(function () {
      return 'Setting TIPPING state of ' + _this2._context.id + ' to ' + (0, _manticoreUtil.getPropertyName)(_transactionStates.TippingState, value);
    });
  };

  TransactionStateManager.prototype.setPaymentFlowStartedState = function setPaymentFlowStartedState(value) {
    var _this3 = this;

    this._paymentFlowStarted = value;
    Log.debug(function () {
      return 'Setting PaymentFlowStarted state of ' + _this3._context.id + ' to ' + value;
    });
  };

  TransactionStateManager.prototype.getPaymentFlowStartState = function getPaymentFlowStartState() {
    return this._paymentFlowStarted;
  };

  TransactionStateManager.prototype.getSetOfActiveFormFactors = function getSetOfActiveFormFactors() {
    return _DeviceSelector2.default.selectedDevice ? _DeviceSelector2.default.selectedDevice.getSetOfActiveFormFactors() : new Set();
  };

  TransactionStateManager.prototype.isFormFactorActive = function isFormFactorActive(formFactor) {
    return _DeviceSelector2.default.selectedDevice ? _DeviceSelector2.default.selectedDevice.isFormFactorActive(formFactor) : false;
  };

  return TransactionStateManager;
}();

exports.default = TransactionStateManager;

},{"../paymentDevice/DeviceSelector":"/Users/aravidas/Documents/Git/retail-sdk/js/paymentDevice/DeviceSelector.js","./transactionStates":"/Users/aravidas/Documents/Git/retail-sdk/js/transaction/transactionStates.js","manticore-log":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-log/index.js","manticore-util":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-util/build/index.js","retail-payment-device":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/js/transaction/authManager.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };

exports.default = retrieveAuthorizedTransactions;

var _manticoreLog = require('manticore-log');

var _manticoreLog2 = _interopRequireDefault(_manticoreLog);

var _moment = require('moment');

var _moment2 = _interopRequireDefault(_moment);

var _retailSDKUtil = require('../common/retailSDKUtil');

var _sdkErrors = require('../common/sdkErrors');

var _authorizedTransactionsRetriever = require('./authorizedTransactionsRetriever');

var _authorizedTransactionsRetriever2 = _interopRequireDefault(_authorizedTransactionsRetriever);

var _AuthStatus = require('./AuthStatus');

var _AuthStatus2 = _interopRequireDefault(_AuthStatus);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var Log = (0, _manticoreLog2.default)('authManager');

function _getQueryParams(startDateTime, endDateTime, pageSize, status, nextPageToken, callback) {
  var queryParams = null;
  // If there is a next page token use that, if not build the queryParam
  if (nextPageToken) {
    queryParams = nextPageToken;
  } else {
    var validationErrorDeveloperMessage = null;
    // Start date time is a required field and should be less than current date time
    if (!startDateTime || !(0, _moment2.default)(startDateTime).isValid() || (0, _moment2.default)(startDateTime) > (0, _moment2.default)()) {
      validationErrorDeveloperMessage = 'startDateTime is missing or is invalid';
    } else if (endDateTime && !(0, _moment2.default)(endDateTime).isValid()) {
      validationErrorDeveloperMessage = 'endDateTime is invalid';
    } else if (endDateTime && startDateTime.getTime() > endDateTime.getTime()) {
      validationErrorDeveloperMessage = 'startDateTime should not greater than endDateTime';
    } else if (endDateTime && !(0, _retailSDKUtil.isDatesWithinOffset)(startDateTime, endDateTime, 5)) {
      // We are limiting the difference in days to 5 because of server side limitations
      validationErrorDeveloperMessage = 'endDateTime - startDateTime cannot be greater than 5 days';
    } else if (!Number.isInteger(pageSize) || pageSize <= 0 || pageSize > 30) {
      validationErrorDeveloperMessage = 'pageSize is invalid. It should be greater than 0 and less than 31';
    }

    if (validationErrorDeveloperMessage) {
      Log.error('Invalid input: ' + validationErrorDeveloperMessage);
      var validationError = _sdkErrors.sdk.validationError;
      validationError.developerMessage = validationErrorDeveloperMessage;
      callback(validationError);
      return undefined;
    }

    // End date time is optional, if missing set it to startDateTime + 5 days
    var finalEndTime = null;
    if (!endDateTime) {
      finalEndTime = new Date(startDateTime);
      finalEndTime.setDate(finalEndTime.getDate() + 5);
    } else {
      finalEndTime = endDateTime;
    }

    queryParams = 'start_time=' + (0, _moment2.default)(startDateTime).toISOString();
    queryParams = queryParams + '&end_time=' + (0, _moment2.default)(finalEndTime).toISOString();
    queryParams = queryParams + '&page_size=' + pageSize;

    // status filter is optional, so fill in the list of provided status into queryParams
    if (status && status.length > 0) {
      queryParams = queryParams + '&statuses=';
      status.forEach(function (id) {
        switch (id) {
          case _AuthStatus2.default.pending:
            queryParams = queryParams + 'PENDING,';
            break;
          case _AuthStatus2.default.canceled:
            queryParams = queryParams + 'CANCELED,';
            break;
          default:
        }
      });
      // Remove the extra comma(,) in the end
      queryParams = queryParams.substring(0, queryParams.length - 1);
    }
  }
  Log.debug(function () {
    return 'the query params are ' + queryParams;
  });

  return queryParams;
}

function retrieveAuthorizedTransactions(startDateTime, endDateTime) {
  var pageSize = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 10;
  var status = arguments[3];
  var nextPageToken = arguments[4];
  var callback = arguments[5];

  Log.debug(function () {
    return 'the startTime object is ' + JSON.stringify(startDateTime) + ' and is of the type ' + (typeof startDateTime === 'undefined' ? 'undefined' : _typeof(startDateTime));
  });
  Log.debug(function () {
    return 'the endTime object is ' + JSON.stringify(endDateTime) + ' and is of the type ' + (typeof endDateTime === 'undefined' ? 'undefined' : _typeof(endDateTime));
  });
  Log.debug(function () {
    return 'the pageSize object is ' + JSON.stringify(pageSize) + ' and is of the type ' + (typeof pageSize === 'undefined' ? 'undefined' : _typeof(pageSize));
  });
  Log.debug(function () {
    return 'the status object is ' + JSON.stringify(status) + ' and is of the type ' + (typeof status === 'undefined' ? 'undefined' : _typeof(status));
  });
  Log.debug(function () {
    return 'the nextPageToken object is ' + JSON.stringify(nextPageToken) + ' and is of the type ' + (typeof nextPageToken === 'undefined' ? 'undefined' : _typeof(nextPageToken));
  });

  var queryParams = _getQueryParams(startDateTime, endDateTime, pageSize, status, nextPageToken, callback);
  if (queryParams) {
    (0, _authorizedTransactionsRetriever2.default)(queryParams, callback);
  }
}

},{"../common/retailSDKUtil":"/Users/aravidas/Documents/Git/retail-sdk/js/common/retailSDKUtil.js","../common/sdkErrors":"/Users/aravidas/Documents/Git/retail-sdk/js/common/sdkErrors.js","./AuthStatus":"/Users/aravidas/Documents/Git/retail-sdk/js/transaction/AuthStatus.js","./authorizedTransactionsRetriever":"/Users/aravidas/Documents/Git/retail-sdk/js/transaction/authorizedTransactionsRetriever.js","manticore-log":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-log/index.js","moment":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/moment/moment.js"}],"/Users/aravidas/Documents/Git/retail-sdk/js/transaction/authorizedTransactionsRetriever.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;
exports.default = retrieveTransactions;

var _manticoreLog = require('manticore-log');

var _manticoreLog2 = _interopRequireDefault(_manticoreLog);

var _sdkErrors = require('../common/sdkErrors');

var _Merchant = require('../common/Merchant');

var _Merchant2 = _interopRequireDefault(_Merchant);

var _AuthorizedTransaction = require('./AuthorizedTransaction');

var _AuthorizedTransaction2 = _interopRequireDefault(_AuthorizedTransaction);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var Log = (0, _manticoreLog2.default)('AuthorizedTransactionsRetriever');

function retrieveTransactions(queryParams, callback) {
  var listOfAuths = [];
  var nextPageToken = null;

  Log.debug(function () {
    return 'Retrieve list of authorizations with the queryParams: ' + queryParams;
  });
  var op = 'checkouts?' + queryParams;
  _Merchant2.default.active.request({
    service: 'retail',
    op: op,
    format: 'json'
  }, function (error, response) {
    var actualError = null;
    if (error || !response || !response.body) {
      Log.error('Error received when trying to retrieve list of authorizations: ' + JSON.stringify(error));
      actualError = _sdkErrors.transaction.retrieveAuthListFailed;
    } else if (response && response.body) {
      Log.debug(function () {
        return 'this is the response object ' + JSON.stringify(response);
      });

      // Get the list of auth
      if (response.body.items && response.body.items.length > 0) {
        response.body.items.forEach(function (item) {
          var auth = new _AuthorizedTransaction2.default(item);
          listOfAuths.push(auth);
        });
      }
      Log.info('Successfully retrieved the list of transactions containing ' + listOfAuths.length + ' authorized transactions');

      // Get the next page token from the array of links
      if (response.body.links) {
        response.body.links.forEach(function (link) {
          if (link.rel === 'next' && link.method === 'GET') {
            nextPageToken = link.href.split('?')[1];
          }
        });
      }
    }
    callback(actualError, listOfAuths, nextPageToken);
  });
}

},{"../common/Merchant":"/Users/aravidas/Documents/Git/retail-sdk/js/common/Merchant.js","../common/sdkErrors":"/Users/aravidas/Documents/Git/retail-sdk/js/common/sdkErrors.js","./AuthorizedTransaction":"/Users/aravidas/Documents/Git/retail-sdk/js/transaction/AuthorizedTransaction.js","manticore-log":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-log/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/js/transaction/captureManager.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };

exports.default = captureAuthorization;

var _manticoreLog = require('manticore-log');

var _manticoreLog2 = _interopRequireDefault(_manticoreLog);

var _sdkErrors = require('../common/sdkErrors');

var _Merchant = require('../common/Merchant');

var _Merchant2 = _interopRequireDefault(_Merchant);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var Log = (0, _manticoreLog2.default)('captureManager');

function captureAuthorization(authorizationId, invoiceId, totalAmount, gratuityAmount, currency, callback) {
  var totalAmountInDecimal = parseFloat(totalAmount);
  var gratuityAmountInDecimal = parseFloat(gratuityAmount);
  Log.debug(function () {
    return 'the authorization id is ' + JSON.stringify(authorizationId) + ' and is of the type ' + (typeof authorizationId === 'undefined' ? 'undefined' : _typeof(authorizationId));
  });
  Log.debug(function () {
    return 'the invoice id is ' + JSON.stringify(invoiceId) + ' and is of the type ' + (typeof invoiceId === 'undefined' ? 'undefined' : _typeof(invoiceId));
  });
  Log.debug(function () {
    return 'the totalAmount is ' + JSON.stringify(totalAmountInDecimal) + ' and is of the type ' + (typeof totalAmountInDecimal === 'undefined' ? 'undefined' : _typeof(totalAmountInDecimal));
  });
  Log.debug(function () {
    return 'the gratuity is ' + JSON.stringify(gratuityAmountInDecimal) + ' and is of the type ' + (typeof gratuityAmountInDecimal === 'undefined' ? 'undefined' : _typeof(gratuityAmountInDecimal));
  });

  var validationErrorDeveloperMessage = null;
  if (!authorizationId) {
    validationErrorDeveloperMessage = 'authorization id is missing';
  } else if (!invoiceId) {
    validationErrorDeveloperMessage = 'invoice id is missing';
  } else if (!totalAmountInDecimal || totalAmountInDecimal < 0) {
    validationErrorDeveloperMessage = 'totalAmount is missing or invalid';
  } else if (gratuityAmountInDecimal && (gratuityAmountInDecimal < 0 || gratuityAmountInDecimal > totalAmountInDecimal)) {
    validationErrorDeveloperMessage = 'gratuity should be greater than 0 and less than totalAmount';
  } else if (!currency) {
    validationErrorDeveloperMessage = 'currency is missing';
  }

  if (validationErrorDeveloperMessage) {
    Log.error('Invalid input: ' + validationErrorDeveloperMessage);
    var validationError = _sdkErrors.sdk.validationError;
    validationError.developerMessage = validationErrorDeveloperMessage;
    callback(validationError);
    return;
  }

  // Set the total amount and currency
  var total = {
    currency: currency,
    value: totalAmountInDecimal.toFixed(2)
  };
  var requestBody = {
    totalAmount: total,
    finalCapture: true,
    invoiceId: invoiceId
  };

  // Set the gratuity if present
  if (gratuityAmount) {
    requestBody.gratuity = {
      currency: currency,
      value: gratuityAmountInDecimal.toFixed(2)
    };
  }

  Log.debug(function () {
    return 'the capture request is ' + JSON.stringify(requestBody);
  });
  var op = 'checkouts/' + authorizationId + '/capture';
  _Merchant2.default.active.request({
    service: 'retail',
    op: op,
    format: 'json',
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(requestBody)
  }, function (error, response) {
    if (error || !response || !response.body || !response.body.id || response.body.state !== 'completed') {
      Log.error('Capture request ' + op + ' returned an error: ' + JSON.stringify(error));
      var developerMessage = null;
      if (response && response.body) {
        developerMessage = response.body.developerMessage;
      }
      callback(_sdkErrors.transaction.captureFailed.withDevMessage(developerMessage));
    } else {
      Log.info('Successfully captured auth id: ' + authorizationId + '. Response: ' + JSON.stringify(response, null, 4));
      callback(null, response.body.id);
    }
  });
}

},{"../common/Merchant":"/Users/aravidas/Documents/Git/retail-sdk/js/common/Merchant.js","../common/sdkErrors":"/Users/aravidas/Documents/Git/retail-sdk/js/common/sdkErrors.js","manticore-log":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-log/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/js/transaction/index.js":[function(require,module,exports){
'use strict';

var _Payer = require('./Payer');

var _Payer2 = _interopRequireDefault(_Payer);

var _TransactionRecord = require('./TransactionRecord');

var _TransactionRecord2 = _interopRequireDefault(_TransactionRecord);

var _TransactionBeginOptions = require('./TransactionBeginOptions');

var _TransactionBeginOptions2 = _interopRequireDefault(_TransactionBeginOptions);

var _ReceiptDestination = require('./ReceiptDestination');

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

module.exports = {
  Payer: _Payer2.default,
  ReceiptDestinationType: _ReceiptDestination.ReceiptDestinationType,
  ReceiptDestination: _ReceiptDestination.ReceiptDestination,
  TransactionRecord: _TransactionRecord2.default,
  TransactionBeginOptions: _TransactionBeginOptions2.default
};

},{"./Payer":"/Users/aravidas/Documents/Git/retail-sdk/js/transaction/Payer.js","./ReceiptDestination":"/Users/aravidas/Documents/Git/retail-sdk/js/transaction/ReceiptDestination.js","./TransactionBeginOptions":"/Users/aravidas/Documents/Git/retail-sdk/js/transaction/TransactionBeginOptions.js","./TransactionRecord":"/Users/aravidas/Documents/Git/retail-sdk/js/transaction/TransactionRecord.js"}],"/Users/aravidas/Documents/Git/retail-sdk/js/transaction/transactionEvent.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;
/**
 * List of events that could be emitted by the Transaction context
 */
var TransactionEvent = {
  /**
   * Signature collection was completed
   */
  didCompleteSignature: 'didCompleteSignature',

  /**
   * Signature was required for this transaction and the assigned signature collector will be activated
   */
  willPresentSignature: 'willPresentSignature',

  /**
   * A footer was added to invoice total that will be display on the connected reader
   */
  invoiceDisplayFooterUpdated: 'invoiceDisplayFooterUpdated',

  /**
   * A device form factor not previously known was discovered
   */
  formFactorAdded: 'formFactorAdded',

  /**
   * Contactless reader was deactivated
   */
  contactlessReaderDeactivated: 'contactlessReaderDeactivated',

  /**
   * Tipping flow on reader was completed
   */
  readerTippingCompleted: 'readerTippingCompleted',
  /**
   * Amount to be refunded entered
   */
  refundAmountEntered: 'refundAmountEntered'
};

exports.default = TransactionEvent;

},{}],"/Users/aravidas/Documents/Git/retail-sdk/js/transaction/transactionStates.js":[function(require,module,exports){
"use strict";

exports.__esModule = true;
/**
 * This enum represents the state of the current payment
 * @enum {int}
 */
var PaymentState = exports.PaymentState = {
  /**
   * Transaction is in idle state
   */
  idle: 0,

  /**
   * Card is currently presented and payment is in progress
   */
  inProgress: 1,

  /**
   * Payment was retried
   */
  retry: 2,

  /**
   * A payment was completed
   */
  complete: 3
};

/**
 * This enum represents the state of the current tipping
 * @enum {int}
 */
var TippingState = exports.TippingState = {
  /**
   * Tipping flow has not started
   */
  notStarted: 0,

  /**
   * Tipping flow is in progress
   */
  inProgress: 1,

  /**
   * Tipping flow is complete
   */
  complete: 2
};

},{}],"/Users/aravidas/Documents/Git/retail-sdk/js/transaction/voidManager.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };

exports.default = voidAuthorization;

var _manticoreLog = require('manticore-log');

var _manticoreLog2 = _interopRequireDefault(_manticoreLog);

var _sdkErrors = require('../common/sdkErrors');

var _Merchant = require('../common/Merchant');

var _Merchant2 = _interopRequireDefault(_Merchant);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var Log = (0, _manticoreLog2.default)('voidManager');

function voidAuthorization(authorizationId, callback) {
  Log.debug(function () {
    return 'the authorization id is ' + JSON.stringify(authorizationId) + ' and is of the type ' + (typeof authorizationId === 'undefined' ? 'undefined' : _typeof(authorizationId));
  });
  if (!authorizationId) {
    callback(_sdkErrors.sdk.validationError.withDevMessage('authorization id cannot be null'));
    return;
  }

  var op = 'checkouts/' + authorizationId + '/void';
  var request = {
    paymentAction: 'authorization'
  };
  _Merchant2.default.active.request({
    service: 'retail',
    op: op,
    format: 'json',
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(request)
  }, function (error, response) {
    if (error || !response || !response.body || !response.body.id || response.body.state !== 'voided') {
      Log.error('Void request ' + op + ' returned an error: ' + JSON.stringify(error));
      var developerMessage = null;
      if (response && response.body) {
        developerMessage = response.body.developerMessage;
      }
      callback(_sdkErrors.transaction.voidFailed.withDevMessage(developerMessage));
    } else {
      Log.info('Successfully voided auth id: ' + authorizationId + '.Response: ' + JSON.stringify(response, null, 4));
      callback(null);
    }
  });
}

},{"../common/Merchant":"/Users/aravidas/Documents/Git/retail-sdk/js/common/Merchant.js","../common/sdkErrors":"/Users/aravidas/Documents/Git/retail-sdk/js/common/sdkErrors.js","manticore-log":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-log/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/assert/assert.js":[function(require,module,exports){
(function (global){
'use strict';

// compare and isBuffer taken from https://github.com/feross/buffer/blob/680e9e5e488f22aac27599a57dc844a6315928dd/index.js
// original notice:

/*!
 * The buffer module from node.js, for the browser.
 *
 * @author   Feross Aboukhadijeh <feross@feross.org> <http://feross.org>
 * @license  MIT
 */
function compare(a, b) {
  if (a === b) {
    return 0;
  }

  var x = a.length;
  var y = b.length;

  for (var i = 0, len = Math.min(x, y); i < len; ++i) {
    if (a[i] !== b[i]) {
      x = a[i];
      y = b[i];
      break;
    }
  }

  if (x < y) {
    return -1;
  }
  if (y < x) {
    return 1;
  }
  return 0;
}
function isBuffer(b) {
  if (global.Buffer && typeof global.Buffer.isBuffer === 'function') {
    return global.Buffer.isBuffer(b);
  }
  return !!(b != null && b._isBuffer);
}

// based on node assert, original notice:

// http://wiki.commonjs.org/wiki/Unit_Testing/1.0
//
// THIS IS NOT TESTED NOR LIKELY TO WORK OUTSIDE V8!
//
// Originally from narwhal.js (http://narwhaljs.org)
// Copyright (c) 2009 Thomas Robinson <280north.com>
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the 'Software'), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

var util = require('util/');
var hasOwn = Object.prototype.hasOwnProperty;
var pSlice = Array.prototype.slice;
var functionsHaveNames = (function () {
  return function foo() {}.name === 'foo';
}());
function pToString (obj) {
  return Object.prototype.toString.call(obj);
}
function isView(arrbuf) {
  if (isBuffer(arrbuf)) {
    return false;
  }
  if (typeof global.ArrayBuffer !== 'function') {
    return false;
  }
  if (typeof ArrayBuffer.isView === 'function') {
    return ArrayBuffer.isView(arrbuf);
  }
  if (!arrbuf) {
    return false;
  }
  if (arrbuf instanceof DataView) {
    return true;
  }
  if (arrbuf.buffer && arrbuf.buffer instanceof ArrayBuffer) {
    return true;
  }
  return false;
}
// 1. The assert module provides functions that throw
// AssertionError's when particular conditions are not met. The
// assert module must conform to the following interface.

var assert = module.exports = ok;

// 2. The AssertionError is defined in assert.
// new assert.AssertionError({ message: message,
//                             actual: actual,
//                             expected: expected })

var regex = /\s*function\s+([^\(\s]*)\s*/;
// based on https://github.com/ljharb/function.prototype.name/blob/adeeeec8bfcc6068b187d7d9fb3d5bb1d3a30899/implementation.js
function getName(func) {
  if (!util.isFunction(func)) {
    return;
  }
  if (functionsHaveNames) {
    return func.name;
  }
  var str = func.toString();
  var match = str.match(regex);
  return match && match[1];
}
assert.AssertionError = function AssertionError(options) {
  this.name = 'AssertionError';
  this.actual = options.actual;
  this.expected = options.expected;
  this.operator = options.operator;
  if (options.message) {
    this.message = options.message;
    this.generatedMessage = false;
  } else {
    this.message = getMessage(this);
    this.generatedMessage = true;
  }
  var stackStartFunction = options.stackStartFunction || fail;
  if (Error.captureStackTrace) {
    Error.captureStackTrace(this, stackStartFunction);
  } else {
    // non v8 browsers so we can have a stacktrace
    var err = new Error();
    if (err.stack) {
      var out = err.stack;

      // try to strip useless frames
      var fn_name = getName(stackStartFunction);
      var idx = out.indexOf('\n' + fn_name);
      if (idx >= 0) {
        // once we have located the function frame
        // we need to strip out everything before it (and its line)
        var next_line = out.indexOf('\n', idx + 1);
        out = out.substring(next_line + 1);
      }

      this.stack = out;
    }
  }
};

// assert.AssertionError instanceof Error
util.inherits(assert.AssertionError, Error);

function truncate(s, n) {
  if (typeof s === 'string') {
    return s.length < n ? s : s.slice(0, n);
  } else {
    return s;
  }
}
function inspect(something) {
  if (functionsHaveNames || !util.isFunction(something)) {
    return util.inspect(something);
  }
  var rawname = getName(something);
  var name = rawname ? ': ' + rawname : '';
  return '[Function' +  name + ']';
}
function getMessage(self) {
  return truncate(inspect(self.actual), 128) + ' ' +
         self.operator + ' ' +
         truncate(inspect(self.expected), 128);
}

// At present only the three keys mentioned above are used and
// understood by the spec. Implementations or sub modules can pass
// other keys to the AssertionError's constructor - they will be
// ignored.

// 3. All of the following functions must throw an AssertionError
// when a corresponding condition is not met, with a message that
// may be undefined if not provided.  All assertion methods provide
// both the actual and expected values to the assertion error for
// display purposes.

function fail(actual, expected, message, operator, stackStartFunction) {
  throw new assert.AssertionError({
    message: message,
    actual: actual,
    expected: expected,
    operator: operator,
    stackStartFunction: stackStartFunction
  });
}

// EXTENSION! allows for well behaved errors defined elsewhere.
assert.fail = fail;

// 4. Pure assertion tests whether a value is truthy, as determined
// by !!guard.
// assert.ok(guard, message_opt);
// This statement is equivalent to assert.equal(true, !!guard,
// message_opt);. To test strictly for the value true, use
// assert.strictEqual(true, guard, message_opt);.

function ok(value, message) {
  if (!value) fail(value, true, message, '==', assert.ok);
}
assert.ok = ok;

// 5. The equality assertion tests shallow, coercive equality with
// ==.
// assert.equal(actual, expected, message_opt);

assert.equal = function equal(actual, expected, message) {
  if (actual != expected) fail(actual, expected, message, '==', assert.equal);
};

// 6. The non-equality assertion tests for whether two objects are not equal
// with != assert.notEqual(actual, expected, message_opt);

assert.notEqual = function notEqual(actual, expected, message) {
  if (actual == expected) {
    fail(actual, expected, message, '!=', assert.notEqual);
  }
};

// 7. The equivalence assertion tests a deep equality relation.
// assert.deepEqual(actual, expected, message_opt);

assert.deepEqual = function deepEqual(actual, expected, message) {
  if (!_deepEqual(actual, expected, false)) {
    fail(actual, expected, message, 'deepEqual', assert.deepEqual);
  }
};

assert.deepStrictEqual = function deepStrictEqual(actual, expected, message) {
  if (!_deepEqual(actual, expected, true)) {
    fail(actual, expected, message, 'deepStrictEqual', assert.deepStrictEqual);
  }
};

function _deepEqual(actual, expected, strict, memos) {
  // 7.1. All identical values are equivalent, as determined by ===.
  if (actual === expected) {
    return true;
  } else if (isBuffer(actual) && isBuffer(expected)) {
    return compare(actual, expected) === 0;

  // 7.2. If the expected value is a Date object, the actual value is
  // equivalent if it is also a Date object that refers to the same time.
  } else if (util.isDate(actual) && util.isDate(expected)) {
    return actual.getTime() === expected.getTime();

  // 7.3 If the expected value is a RegExp object, the actual value is
  // equivalent if it is also a RegExp object with the same source and
  // properties (`global`, `multiline`, `lastIndex`, `ignoreCase`).
  } else if (util.isRegExp(actual) && util.isRegExp(expected)) {
    return actual.source === expected.source &&
           actual.global === expected.global &&
           actual.multiline === expected.multiline &&
           actual.lastIndex === expected.lastIndex &&
           actual.ignoreCase === expected.ignoreCase;

  // 7.4. Other pairs that do not both pass typeof value == 'object',
  // equivalence is determined by ==.
  } else if ((actual === null || typeof actual !== 'object') &&
             (expected === null || typeof expected !== 'object')) {
    return strict ? actual === expected : actual == expected;

  // If both values are instances of typed arrays, wrap their underlying
  // ArrayBuffers in a Buffer each to increase performance
  // This optimization requires the arrays to have the same type as checked by
  // Object.prototype.toString (aka pToString). Never perform binary
  // comparisons for Float*Arrays, though, since e.g. +0 === -0 but their
  // bit patterns are not identical.
  } else if (isView(actual) && isView(expected) &&
             pToString(actual) === pToString(expected) &&
             !(actual instanceof Float32Array ||
               actual instanceof Float64Array)) {
    return compare(new Uint8Array(actual.buffer),
                   new Uint8Array(expected.buffer)) === 0;

  // 7.5 For all other Object pairs, including Array objects, equivalence is
  // determined by having the same number of owned properties (as verified
  // with Object.prototype.hasOwnProperty.call), the same set of keys
  // (although not necessarily the same order), equivalent values for every
  // corresponding key, and an identical 'prototype' property. Note: this
  // accounts for both named and indexed properties on Arrays.
  } else if (isBuffer(actual) !== isBuffer(expected)) {
    return false;
  } else {
    memos = memos || {actual: [], expected: []};

    var actualIndex = memos.actual.indexOf(actual);
    if (actualIndex !== -1) {
      if (actualIndex === memos.expected.indexOf(expected)) {
        return true;
      }
    }

    memos.actual.push(actual);
    memos.expected.push(expected);

    return objEquiv(actual, expected, strict, memos);
  }
}

function isArguments(object) {
  return Object.prototype.toString.call(object) == '[object Arguments]';
}

function objEquiv(a, b, strict, actualVisitedObjects) {
  if (a === null || a === undefined || b === null || b === undefined)
    return false;
  // if one is a primitive, the other must be same
  if (util.isPrimitive(a) || util.isPrimitive(b))
    return a === b;
  if (strict && Object.getPrototypeOf(a) !== Object.getPrototypeOf(b))
    return false;
  var aIsArgs = isArguments(a);
  var bIsArgs = isArguments(b);
  if ((aIsArgs && !bIsArgs) || (!aIsArgs && bIsArgs))
    return false;
  if (aIsArgs) {
    a = pSlice.call(a);
    b = pSlice.call(b);
    return _deepEqual(a, b, strict);
  }
  var ka = objectKeys(a);
  var kb = objectKeys(b);
  var key, i;
  // having the same number of owned properties (keys incorporates
  // hasOwnProperty)
  if (ka.length !== kb.length)
    return false;
  //the same set of keys (although not necessarily the same order),
  ka.sort();
  kb.sort();
  //~~~cheap key test
  for (i = ka.length - 1; i >= 0; i--) {
    if (ka[i] !== kb[i])
      return false;
  }
  //equivalent values for every corresponding key, and
  //~~~possibly expensive deep test
  for (i = ka.length - 1; i >= 0; i--) {
    key = ka[i];
    if (!_deepEqual(a[key], b[key], strict, actualVisitedObjects))
      return false;
  }
  return true;
}

// 8. The non-equivalence assertion tests for any deep inequality.
// assert.notDeepEqual(actual, expected, message_opt);

assert.notDeepEqual = function notDeepEqual(actual, expected, message) {
  if (_deepEqual(actual, expected, false)) {
    fail(actual, expected, message, 'notDeepEqual', assert.notDeepEqual);
  }
};

assert.notDeepStrictEqual = notDeepStrictEqual;
function notDeepStrictEqual(actual, expected, message) {
  if (_deepEqual(actual, expected, true)) {
    fail(actual, expected, message, 'notDeepStrictEqual', notDeepStrictEqual);
  }
}


// 9. The strict equality assertion tests strict equality, as determined by ===.
// assert.strictEqual(actual, expected, message_opt);

assert.strictEqual = function strictEqual(actual, expected, message) {
  if (actual !== expected) {
    fail(actual, expected, message, '===', assert.strictEqual);
  }
};

// 10. The strict non-equality assertion tests for strict inequality, as
// determined by !==.  assert.notStrictEqual(actual, expected, message_opt);

assert.notStrictEqual = function notStrictEqual(actual, expected, message) {
  if (actual === expected) {
    fail(actual, expected, message, '!==', assert.notStrictEqual);
  }
};

function expectedException(actual, expected) {
  if (!actual || !expected) {
    return false;
  }

  if (Object.prototype.toString.call(expected) == '[object RegExp]') {
    return expected.test(actual);
  }

  try {
    if (actual instanceof expected) {
      return true;
    }
  } catch (e) {
    // Ignore.  The instanceof check doesn't work for arrow functions.
  }

  if (Error.isPrototypeOf(expected)) {
    return false;
  }

  return expected.call({}, actual) === true;
}

function _tryBlock(block) {
  var error;
  try {
    block();
  } catch (e) {
    error = e;
  }
  return error;
}

function _throws(shouldThrow, block, expected, message) {
  var actual;

  if (typeof block !== 'function') {
    throw new TypeError('"block" argument must be a function');
  }

  if (typeof expected === 'string') {
    message = expected;
    expected = null;
  }

  actual = _tryBlock(block);

  message = (expected && expected.name ? ' (' + expected.name + ').' : '.') +
            (message ? ' ' + message : '.');

  if (shouldThrow && !actual) {
    fail(actual, expected, 'Missing expected exception' + message);
  }

  var userProvidedMessage = typeof message === 'string';
  var isUnwantedException = !shouldThrow && util.isError(actual);
  var isUnexpectedException = !shouldThrow && actual && !expected;

  if ((isUnwantedException &&
      userProvidedMessage &&
      expectedException(actual, expected)) ||
      isUnexpectedException) {
    fail(actual, expected, 'Got unwanted exception' + message);
  }

  if ((shouldThrow && actual && expected &&
      !expectedException(actual, expected)) || (!shouldThrow && actual)) {
    throw actual;
  }
}

// 11. Expected to throw an error:
// assert.throws(block, Error_opt, message_opt);

assert.throws = function(block, /*optional*/error, /*optional*/message) {
  _throws(true, block, error, message);
};

// EXTENSION! This is annoying to write outside this module.
assert.doesNotThrow = function(block, /*optional*/error, /*optional*/message) {
  _throws(false, block, error, message);
};

assert.ifError = function(err) { if (err) throw err; };

var objectKeys = Object.keys || function (obj) {
  var keys = [];
  for (var key in obj) {
    if (hasOwn.call(obj, key)) keys.push(key);
  }
  return keys;
};

}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
},{"util/":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/util/util.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/async/lib/async.js":[function(require,module,exports){
(function (process,global){
/*!
 * async
 * https://github.com/caolan/async
 *
 * Copyright 2010-2014 Caolan McMahon
 * Released under the MIT license
 */
(function () {

    var async = {};
    function noop() {}
    function identity(v) {
        return v;
    }
    function toBool(v) {
        return !!v;
    }
    function notId(v) {
        return !v;
    }

    // global on the server, window in the browser
    var previous_async;

    // Establish the root object, `window` (`self`) in the browser, `global`
    // on the server, or `this` in some virtual machines. We use `self`
    // instead of `window` for `WebWorker` support.
    var root = typeof self === 'object' && self.self === self && self ||
            typeof global === 'object' && global.global === global && global ||
            this;

    if (root != null) {
        previous_async = root.async;
    }

    async.noConflict = function () {
        root.async = previous_async;
        return async;
    };

    function only_once(fn) {
        return function() {
            if (fn === null) throw new Error("Callback was already called.");
            fn.apply(this, arguments);
            fn = null;
        };
    }

    function _once(fn) {
        return function() {
            if (fn === null) return;
            fn.apply(this, arguments);
            fn = null;
        };
    }

    //// cross-browser compatiblity functions ////

    var _toString = Object.prototype.toString;

    var _isArray = Array.isArray || function (obj) {
        return _toString.call(obj) === '[object Array]';
    };

    // Ported from underscore.js isObject
    var _isObject = function(obj) {
        var type = typeof obj;
        return type === 'function' || type === 'object' && !!obj;
    };

    function _isArrayLike(arr) {
        return _isArray(arr) || (
            // has a positive integer length property
            typeof arr.length === "number" &&
            arr.length >= 0 &&
            arr.length % 1 === 0
        );
    }

    function _arrayEach(arr, iterator) {
        var index = -1,
            length = arr.length;

        while (++index < length) {
            iterator(arr[index], index, arr);
        }
    }

    function _map(arr, iterator) {
        var index = -1,
            length = arr.length,
            result = Array(length);

        while (++index < length) {
            result[index] = iterator(arr[index], index, arr);
        }
        return result;
    }

    function _range(count) {
        return _map(Array(count), function (v, i) { return i; });
    }

    function _reduce(arr, iterator, memo) {
        _arrayEach(arr, function (x, i, a) {
            memo = iterator(memo, x, i, a);
        });
        return memo;
    }

    function _forEachOf(object, iterator) {
        _arrayEach(_keys(object), function (key) {
            iterator(object[key], key);
        });
    }

    function _indexOf(arr, item) {
        for (var i = 0; i < arr.length; i++) {
            if (arr[i] === item) return i;
        }
        return -1;
    }

    var _keys = Object.keys || function (obj) {
        var keys = [];
        for (var k in obj) {
            if (obj.hasOwnProperty(k)) {
                keys.push(k);
            }
        }
        return keys;
    };

    function _keyIterator(coll) {
        var i = -1;
        var len;
        var keys;
        if (_isArrayLike(coll)) {
            len = coll.length;
            return function next() {
                i++;
                return i < len ? i : null;
            };
        } else {
            keys = _keys(coll);
            len = keys.length;
            return function next() {
                i++;
                return i < len ? keys[i] : null;
            };
        }
    }

    // Similar to ES6's rest param (http://ariya.ofilabs.com/2013/03/es6-and-rest-parameter.html)
    // This accumulates the arguments passed into an array, after a given index.
    // From underscore.js (https://github.com/jashkenas/underscore/pull/2140).
    function _restParam(func, startIndex) {
        startIndex = startIndex == null ? func.length - 1 : +startIndex;
        return function() {
            var length = Math.max(arguments.length - startIndex, 0);
            var rest = Array(length);
            for (var index = 0; index < length; index++) {
                rest[index] = arguments[index + startIndex];
            }
            switch (startIndex) {
                case 0: return func.call(this, rest);
                case 1: return func.call(this, arguments[0], rest);
            }
            // Currently unused but handle cases outside of the switch statement:
            // var args = Array(startIndex + 1);
            // for (index = 0; index < startIndex; index++) {
            //     args[index] = arguments[index];
            // }
            // args[startIndex] = rest;
            // return func.apply(this, args);
        };
    }

    function _withoutIndex(iterator) {
        return function (value, index, callback) {
            return iterator(value, callback);
        };
    }

    //// exported async module functions ////

    //// nextTick implementation with browser-compatible fallback ////

    // capture the global reference to guard against fakeTimer mocks
    var _setImmediate = typeof setImmediate === 'function' && setImmediate;

    var _delay = _setImmediate ? function(fn) {
        // not a direct alias for IE10 compatibility
        _setImmediate(fn);
    } : function(fn) {
        setTimeout(fn, 0);
    };

    if (typeof process === 'object' && typeof process.nextTick === 'function') {
        async.nextTick = process.nextTick;
    } else {
        async.nextTick = _delay;
    }
    async.setImmediate = _setImmediate ? _delay : async.nextTick;


    async.forEach =
    async.each = function (arr, iterator, callback) {
        return async.eachOf(arr, _withoutIndex(iterator), callback);
    };

    async.forEachSeries =
    async.eachSeries = function (arr, iterator, callback) {
        return async.eachOfSeries(arr, _withoutIndex(iterator), callback);
    };


    async.forEachLimit =
    async.eachLimit = function (arr, limit, iterator, callback) {
        return _eachOfLimit(limit)(arr, _withoutIndex(iterator), callback);
    };

    async.forEachOf =
    async.eachOf = function (object, iterator, callback) {
        callback = _once(callback || noop);
        object = object || [];

        var iter = _keyIterator(object);
        var key, completed = 0;

        while ((key = iter()) != null) {
            completed += 1;
            iterator(object[key], key, only_once(done));
        }

        if (completed === 0) callback(null);

        function done(err) {
            completed--;
            if (err) {
                callback(err);
            }
            // Check key is null in case iterator isn't exhausted
            // and done resolved synchronously.
            else if (key === null && completed <= 0) {
                callback(null);
            }
        }
    };

    async.forEachOfSeries =
    async.eachOfSeries = function (obj, iterator, callback) {
        callback = _once(callback || noop);
        obj = obj || [];
        var nextKey = _keyIterator(obj);
        var key = nextKey();
        function iterate() {
            var sync = true;
            if (key === null) {
                return callback(null);
            }
            iterator(obj[key], key, only_once(function (err) {
                if (err) {
                    callback(err);
                }
                else {
                    key = nextKey();
                    if (key === null) {
                        return callback(null);
                    } else {
                        if (sync) {
                            async.setImmediate(iterate);
                        } else {
                            iterate();
                        }
                    }
                }
            }));
            sync = false;
        }
        iterate();
    };



    async.forEachOfLimit =
    async.eachOfLimit = function (obj, limit, iterator, callback) {
        _eachOfLimit(limit)(obj, iterator, callback);
    };

    function _eachOfLimit(limit) {

        return function (obj, iterator, callback) {
            callback = _once(callback || noop);
            obj = obj || [];
            var nextKey = _keyIterator(obj);
            if (limit <= 0) {
                return callback(null);
            }
            var done = false;
            var running = 0;
            var errored = false;

            (function replenish () {
                if (done && running <= 0) {
                    return callback(null);
                }

                while (running < limit && !errored) {
                    var key = nextKey();
                    if (key === null) {
                        done = true;
                        if (running <= 0) {
                            callback(null);
                        }
                        return;
                    }
                    running += 1;
                    iterator(obj[key], key, only_once(function (err) {
                        running -= 1;
                        if (err) {
                            callback(err);
                            errored = true;
                        }
                        else {
                            replenish();
                        }
                    }));
                }
            })();
        };
    }


    function doParallel(fn) {
        return function (obj, iterator, callback) {
            return fn(async.eachOf, obj, iterator, callback);
        };
    }
    function doParallelLimit(fn) {
        return function (obj, limit, iterator, callback) {
            return fn(_eachOfLimit(limit), obj, iterator, callback);
        };
    }
    function doSeries(fn) {
        return function (obj, iterator, callback) {
            return fn(async.eachOfSeries, obj, iterator, callback);
        };
    }

    function _asyncMap(eachfn, arr, iterator, callback) {
        callback = _once(callback || noop);
        arr = arr || [];
        var results = _isArrayLike(arr) ? [] : {};
        eachfn(arr, function (value, index, callback) {
            iterator(value, function (err, v) {
                results[index] = v;
                callback(err);
            });
        }, function (err) {
            callback(err, results);
        });
    }

    async.map = doParallel(_asyncMap);
    async.mapSeries = doSeries(_asyncMap);
    async.mapLimit = doParallelLimit(_asyncMap);

    // reduce only has a series version, as doing reduce in parallel won't
    // work in many situations.
    async.inject =
    async.foldl =
    async.reduce = function (arr, memo, iterator, callback) {
        async.eachOfSeries(arr, function (x, i, callback) {
            iterator(memo, x, function (err, v) {
                memo = v;
                callback(err);
            });
        }, function (err) {
            callback(err, memo);
        });
    };

    async.foldr =
    async.reduceRight = function (arr, memo, iterator, callback) {
        var reversed = _map(arr, identity).reverse();
        async.reduce(reversed, memo, iterator, callback);
    };

    async.transform = function (arr, memo, iterator, callback) {
        if (arguments.length === 3) {
            callback = iterator;
            iterator = memo;
            memo = _isArray(arr) ? [] : {};
        }

        async.eachOf(arr, function(v, k, cb) {
            iterator(memo, v, k, cb);
        }, function(err) {
            callback(err, memo);
        });
    };

    function _filter(eachfn, arr, iterator, callback) {
        var results = [];
        eachfn(arr, function (x, index, callback) {
            iterator(x, function (v) {
                if (v) {
                    results.push({index: index, value: x});
                }
                callback();
            });
        }, function () {
            callback(_map(results.sort(function (a, b) {
                return a.index - b.index;
            }), function (x) {
                return x.value;
            }));
        });
    }

    async.select =
    async.filter = doParallel(_filter);

    async.selectLimit =
    async.filterLimit = doParallelLimit(_filter);

    async.selectSeries =
    async.filterSeries = doSeries(_filter);

    function _reject(eachfn, arr, iterator, callback) {
        _filter(eachfn, arr, function(value, cb) {
            iterator(value, function(v) {
                cb(!v);
            });
        }, callback);
    }
    async.reject = doParallel(_reject);
    async.rejectLimit = doParallelLimit(_reject);
    async.rejectSeries = doSeries(_reject);

    function _createTester(eachfn, check, getResult) {
        return function(arr, limit, iterator, cb) {
            function done() {
                if (cb) cb(getResult(false, void 0));
            }
            function iteratee(x, _, callback) {
                if (!cb) return callback();
                iterator(x, function (v) {
                    if (cb && check(v)) {
                        cb(getResult(true, x));
                        cb = iterator = false;
                    }
                    callback();
                });
            }
            if (arguments.length > 3) {
                eachfn(arr, limit, iteratee, done);
            } else {
                cb = iterator;
                iterator = limit;
                eachfn(arr, iteratee, done);
            }
        };
    }

    async.any =
    async.some = _createTester(async.eachOf, toBool, identity);

    async.someLimit = _createTester(async.eachOfLimit, toBool, identity);

    async.all =
    async.every = _createTester(async.eachOf, notId, notId);

    async.everyLimit = _createTester(async.eachOfLimit, notId, notId);

    function _findGetResult(v, x) {
        return x;
    }
    async.detect = _createTester(async.eachOf, identity, _findGetResult);
    async.detectSeries = _createTester(async.eachOfSeries, identity, _findGetResult);
    async.detectLimit = _createTester(async.eachOfLimit, identity, _findGetResult);

    async.sortBy = function (arr, iterator, callback) {
        async.map(arr, function (x, callback) {
            iterator(x, function (err, criteria) {
                if (err) {
                    callback(err);
                }
                else {
                    callback(null, {value: x, criteria: criteria});
                }
            });
        }, function (err, results) {
            if (err) {
                return callback(err);
            }
            else {
                callback(null, _map(results.sort(comparator), function (x) {
                    return x.value;
                }));
            }

        });

        function comparator(left, right) {
            var a = left.criteria, b = right.criteria;
            return a < b ? -1 : a > b ? 1 : 0;
        }
    };

    async.auto = function (tasks, concurrency, callback) {
        if (typeof arguments[1] === 'function') {
            // concurrency is optional, shift the args.
            callback = concurrency;
            concurrency = null;
        }
        callback = _once(callback || noop);
        var keys = _keys(tasks);
        var remainingTasks = keys.length;
        if (!remainingTasks) {
            return callback(null);
        }
        if (!concurrency) {
            concurrency = remainingTasks;
        }

        var results = {};
        var runningTasks = 0;

        var hasError = false;

        var listeners = [];
        function addListener(fn) {
            listeners.unshift(fn);
        }
        function removeListener(fn) {
            var idx = _indexOf(listeners, fn);
            if (idx >= 0) listeners.splice(idx, 1);
        }
        function taskComplete() {
            remainingTasks--;
            _arrayEach(listeners.slice(0), function (fn) {
                fn();
            });
        }

        addListener(function () {
            if (!remainingTasks) {
                callback(null, results);
            }
        });

        _arrayEach(keys, function (k) {
            if (hasError) return;
            var task = _isArray(tasks[k]) ? tasks[k]: [tasks[k]];
            var taskCallback = _restParam(function(err, args) {
                runningTasks--;
                if (args.length <= 1) {
                    args = args[0];
                }
                if (err) {
                    var safeResults = {};
                    _forEachOf(results, function(val, rkey) {
                        safeResults[rkey] = val;
                    });
                    safeResults[k] = args;
                    hasError = true;

                    callback(err, safeResults);
                }
                else {
                    results[k] = args;
                    async.setImmediate(taskComplete);
                }
            });
            var requires = task.slice(0, task.length - 1);
            // prevent dead-locks
            var len = requires.length;
            var dep;
            while (len--) {
                if (!(dep = tasks[requires[len]])) {
                    throw new Error('Has nonexistent dependency in ' + requires.join(', '));
                }
                if (_isArray(dep) && _indexOf(dep, k) >= 0) {
                    throw new Error('Has cyclic dependencies');
                }
            }
            function ready() {
                return runningTasks < concurrency && _reduce(requires, function (a, x) {
                    return (a && results.hasOwnProperty(x));
                }, true) && !results.hasOwnProperty(k);
            }
            if (ready()) {
                runningTasks++;
                task[task.length - 1](taskCallback, results);
            }
            else {
                addListener(listener);
            }
            function listener() {
                if (ready()) {
                    runningTasks++;
                    removeListener(listener);
                    task[task.length - 1](taskCallback, results);
                }
            }
        });
    };



    async.retry = function(times, task, callback) {
        var DEFAULT_TIMES = 5;
        var DEFAULT_INTERVAL = 0;

        var attempts = [];

        var opts = {
            times: DEFAULT_TIMES,
            interval: DEFAULT_INTERVAL
        };

        function parseTimes(acc, t){
            if(typeof t === 'number'){
                acc.times = parseInt(t, 10) || DEFAULT_TIMES;
            } else if(typeof t === 'object'){
                acc.times = parseInt(t.times, 10) || DEFAULT_TIMES;
                acc.interval = parseInt(t.interval, 10) || DEFAULT_INTERVAL;
            } else {
                throw new Error('Unsupported argument type for \'times\': ' + typeof t);
            }
        }

        var length = arguments.length;
        if (length < 1 || length > 3) {
            throw new Error('Invalid arguments - must be either (task), (task, callback), (times, task) or (times, task, callback)');
        } else if (length <= 2 && typeof times === 'function') {
            callback = task;
            task = times;
        }
        if (typeof times !== 'function') {
            parseTimes(opts, times);
        }
        opts.callback = callback;
        opts.task = task;

        function wrappedTask(wrappedCallback, wrappedResults) {
            function retryAttempt(task, finalAttempt) {
                return function(seriesCallback) {
                    task(function(err, result){
                        seriesCallback(!err || finalAttempt, {err: err, result: result});
                    }, wrappedResults);
                };
            }

            function retryInterval(interval){
                return function(seriesCallback){
                    setTimeout(function(){
                        seriesCallback(null);
                    }, interval);
                };
            }

            while (opts.times) {

                var finalAttempt = !(opts.times-=1);
                attempts.push(retryAttempt(opts.task, finalAttempt));
                if(!finalAttempt && opts.interval > 0){
                    attempts.push(retryInterval(opts.interval));
                }
            }

            async.series(attempts, function(done, data){
                data = data[data.length - 1];
                (wrappedCallback || opts.callback)(data.err, data.result);
            });
        }

        // If a callback is passed, run this as a controll flow
        return opts.callback ? wrappedTask() : wrappedTask;
    };

    async.waterfall = function (tasks, callback) {
        callback = _once(callback || noop);
        if (!_isArray(tasks)) {
            var err = new Error('First argument to waterfall must be an array of functions');
            return callback(err);
        }
        if (!tasks.length) {
            return callback();
        }
        function wrapIterator(iterator) {
            return _restParam(function (err, args) {
                if (err) {
                    callback.apply(null, [err].concat(args));
                }
                else {
                    var next = iterator.next();
                    if (next) {
                        args.push(wrapIterator(next));
                    }
                    else {
                        args.push(callback);
                    }
                    ensureAsync(iterator).apply(null, args);
                }
            });
        }
        wrapIterator(async.iterator(tasks))();
    };

    function _parallel(eachfn, tasks, callback) {
        callback = callback || noop;
        var results = _isArrayLike(tasks) ? [] : {};

        eachfn(tasks, function (task, key, callback) {
            task(_restParam(function (err, args) {
                if (args.length <= 1) {
                    args = args[0];
                }
                results[key] = args;
                callback(err);
            }));
        }, function (err) {
            callback(err, results);
        });
    }

    async.parallel = function (tasks, callback) {
        _parallel(async.eachOf, tasks, callback);
    };

    async.parallelLimit = function(tasks, limit, callback) {
        _parallel(_eachOfLimit(limit), tasks, callback);
    };

    async.series = function(tasks, callback) {
        _parallel(async.eachOfSeries, tasks, callback);
    };

    async.iterator = function (tasks) {
        function makeCallback(index) {
            function fn() {
                if (tasks.length) {
                    tasks[index].apply(null, arguments);
                }
                return fn.next();
            }
            fn.next = function () {
                return (index < tasks.length - 1) ? makeCallback(index + 1): null;
            };
            return fn;
        }
        return makeCallback(0);
    };

    async.apply = _restParam(function (fn, args) {
        return _restParam(function (callArgs) {
            return fn.apply(
                null, args.concat(callArgs)
            );
        });
    });

    function _concat(eachfn, arr, fn, callback) {
        var result = [];
        eachfn(arr, function (x, index, cb) {
            fn(x, function (err, y) {
                result = result.concat(y || []);
                cb(err);
            });
        }, function (err) {
            callback(err, result);
        });
    }
    async.concat = doParallel(_concat);
    async.concatSeries = doSeries(_concat);

    async.whilst = function (test, iterator, callback) {
        callback = callback || noop;
        if (test()) {
            var next = _restParam(function(err, args) {
                if (err) {
                    callback(err);
                } else if (test.apply(this, args)) {
                    iterator(next);
                } else {
                    callback.apply(null, [null].concat(args));
                }
            });
            iterator(next);
        } else {
            callback(null);
        }
    };

    async.doWhilst = function (iterator, test, callback) {
        var calls = 0;
        return async.whilst(function() {
            return ++calls <= 1 || test.apply(this, arguments);
        }, iterator, callback);
    };

    async.until = function (test, iterator, callback) {
        return async.whilst(function() {
            return !test.apply(this, arguments);
        }, iterator, callback);
    };

    async.doUntil = function (iterator, test, callback) {
        return async.doWhilst(iterator, function() {
            return !test.apply(this, arguments);
        }, callback);
    };

    async.during = function (test, iterator, callback) {
        callback = callback || noop;

        var next = _restParam(function(err, args) {
            if (err) {
                callback(err);
            } else {
                args.push(check);
                test.apply(this, args);
            }
        });

        var check = function(err, truth) {
            if (err) {
                callback(err);
            } else if (truth) {
                iterator(next);
            } else {
                callback(null);
            }
        };

        test(check);
    };

    async.doDuring = function (iterator, test, callback) {
        var calls = 0;
        async.during(function(next) {
            if (calls++ < 1) {
                next(null, true);
            } else {
                test.apply(this, arguments);
            }
        }, iterator, callback);
    };

    function _queue(worker, concurrency, payload) {
        if (concurrency == null) {
            concurrency = 1;
        }
        else if(concurrency === 0) {
            throw new Error('Concurrency must not be zero');
        }
        function _insert(q, data, pos, callback) {
            if (callback != null && typeof callback !== "function") {
                throw new Error("task callback must be a function");
            }
            q.started = true;
            if (!_isArray(data)) {
                data = [data];
            }
            if(data.length === 0 && q.idle()) {
                // call drain immediately if there are no tasks
                return async.setImmediate(function() {
                    q.drain();
                });
            }
            _arrayEach(data, function(task) {
                var item = {
                    data: task,
                    callback: callback || noop
                };

                if (pos) {
                    q.tasks.unshift(item);
                } else {
                    q.tasks.push(item);
                }

                if (q.tasks.length === q.concurrency) {
                    q.saturated();
                }
            });
            async.setImmediate(q.process);
        }
        function _next(q, tasks) {
            return function(){
                workers -= 1;

                var removed = false;
                var args = arguments;
                _arrayEach(tasks, function (task) {
                    _arrayEach(workersList, function (worker, index) {
                        if (worker === task && !removed) {
                            workersList.splice(index, 1);
                            removed = true;
                        }
                    });

                    task.callback.apply(task, args);
                });
                if (q.tasks.length + workers === 0) {
                    q.drain();
                }
                q.process();
            };
        }

        var workers = 0;
        var workersList = [];
        var q = {
            tasks: [],
            concurrency: concurrency,
            payload: payload,
            saturated: noop,
            empty: noop,
            drain: noop,
            started: false,
            paused: false,
            push: function (data, callback) {
                _insert(q, data, false, callback);
            },
            kill: function () {
                q.drain = noop;
                q.tasks = [];
            },
            unshift: function (data, callback) {
                _insert(q, data, true, callback);
            },
            process: function () {
                while(!q.paused && workers < q.concurrency && q.tasks.length){

                    var tasks = q.payload ?
                        q.tasks.splice(0, q.payload) :
                        q.tasks.splice(0, q.tasks.length);

                    var data = _map(tasks, function (task) {
                        return task.data;
                    });

                    if (q.tasks.length === 0) {
                        q.empty();
                    }
                    workers += 1;
                    workersList.push(tasks[0]);
                    var cb = only_once(_next(q, tasks));
                    worker(data, cb);
                }
            },
            length: function () {
                return q.tasks.length;
            },
            running: function () {
                return workers;
            },
            workersList: function () {
                return workersList;
            },
            idle: function() {
                return q.tasks.length + workers === 0;
            },
            pause: function () {
                q.paused = true;
            },
            resume: function () {
                if (q.paused === false) { return; }
                q.paused = false;
                var resumeCount = Math.min(q.concurrency, q.tasks.length);
                // Need to call q.process once per concurrent
                // worker to preserve full concurrency after pause
                for (var w = 1; w <= resumeCount; w++) {
                    async.setImmediate(q.process);
                }
            }
        };
        return q;
    }

    async.queue = function (worker, concurrency) {
        var q = _queue(function (items, cb) {
            worker(items[0], cb);
        }, concurrency, 1);

        return q;
    };

    async.priorityQueue = function (worker, concurrency) {

        function _compareTasks(a, b){
            return a.priority - b.priority;
        }

        function _binarySearch(sequence, item, compare) {
            var beg = -1,
                end = sequence.length - 1;
            while (beg < end) {
                var mid = beg + ((end - beg + 1) >>> 1);
                if (compare(item, sequence[mid]) >= 0) {
                    beg = mid;
                } else {
                    end = mid - 1;
                }
            }
            return beg;
        }

        function _insert(q, data, priority, callback) {
            if (callback != null && typeof callback !== "function") {
                throw new Error("task callback must be a function");
            }
            q.started = true;
            if (!_isArray(data)) {
                data = [data];
            }
            if(data.length === 0) {
                // call drain immediately if there are no tasks
                return async.setImmediate(function() {
                    q.drain();
                });
            }
            _arrayEach(data, function(task) {
                var item = {
                    data: task,
                    priority: priority,
                    callback: typeof callback === 'function' ? callback : noop
                };

                q.tasks.splice(_binarySearch(q.tasks, item, _compareTasks) + 1, 0, item);

                if (q.tasks.length === q.concurrency) {
                    q.saturated();
                }
                async.setImmediate(q.process);
            });
        }

        // Start with a normal queue
        var q = async.queue(worker, concurrency);

        // Override push to accept second parameter representing priority
        q.push = function (data, priority, callback) {
            _insert(q, data, priority, callback);
        };

        // Remove unshift function
        delete q.unshift;

        return q;
    };

    async.cargo = function (worker, payload) {
        return _queue(worker, 1, payload);
    };

    function _console_fn(name) {
        return _restParam(function (fn, args) {
            fn.apply(null, args.concat([_restParam(function (err, args) {
                if (typeof console === 'object') {
                    if (err) {
                        if (console.error) {
                            console.error(err);
                        }
                    }
                    else if (console[name]) {
                        _arrayEach(args, function (x) {
                            console[name](x);
                        });
                    }
                }
            })]));
        });
    }
    async.log = _console_fn('log');
    async.dir = _console_fn('dir');
    /*async.info = _console_fn('info');
    async.warn = _console_fn('warn');
    async.error = _console_fn('error');*/

    async.memoize = function (fn, hasher) {
        var memo = {};
        var queues = {};
        var has = Object.prototype.hasOwnProperty;
        hasher = hasher || identity;
        var memoized = _restParam(function memoized(args) {
            var callback = args.pop();
            var key = hasher.apply(null, args);
            if (has.call(memo, key)) {   
                async.setImmediate(function () {
                    callback.apply(null, memo[key]);
                });
            }
            else if (has.call(queues, key)) {
                queues[key].push(callback);
            }
            else {
                queues[key] = [callback];
                fn.apply(null, args.concat([_restParam(function (args) {
                    memo[key] = args;
                    var q = queues[key];
                    delete queues[key];
                    for (var i = 0, l = q.length; i < l; i++) {
                        q[i].apply(null, args);
                    }
                })]));
            }
        });
        memoized.memo = memo;
        memoized.unmemoized = fn;
        return memoized;
    };

    async.unmemoize = function (fn) {
        return function () {
            return (fn.unmemoized || fn).apply(null, arguments);
        };
    };

    function _times(mapper) {
        return function (count, iterator, callback) {
            mapper(_range(count), iterator, callback);
        };
    }

    async.times = _times(async.map);
    async.timesSeries = _times(async.mapSeries);
    async.timesLimit = function (count, limit, iterator, callback) {
        return async.mapLimit(_range(count), limit, iterator, callback);
    };

    async.seq = function (/* functions... */) {
        var fns = arguments;
        return _restParam(function (args) {
            var that = this;

            var callback = args[args.length - 1];
            if (typeof callback == 'function') {
                args.pop();
            } else {
                callback = noop;
            }

            async.reduce(fns, args, function (newargs, fn, cb) {
                fn.apply(that, newargs.concat([_restParam(function (err, nextargs) {
                    cb(err, nextargs);
                })]));
            },
            function (err, results) {
                callback.apply(that, [err].concat(results));
            });
        });
    };

    async.compose = function (/* functions... */) {
        return async.seq.apply(null, Array.prototype.reverse.call(arguments));
    };


    function _applyEach(eachfn) {
        return _restParam(function(fns, args) {
            var go = _restParam(function(args) {
                var that = this;
                var callback = args.pop();
                return eachfn(fns, function (fn, _, cb) {
                    fn.apply(that, args.concat([cb]));
                },
                callback);
            });
            if (args.length) {
                return go.apply(this, args);
            }
            else {
                return go;
            }
        });
    }

    async.applyEach = _applyEach(async.eachOf);
    async.applyEachSeries = _applyEach(async.eachOfSeries);


    async.forever = function (fn, callback) {
        var done = only_once(callback || noop);
        var task = ensureAsync(fn);
        function next(err) {
            if (err) {
                return done(err);
            }
            task(next);
        }
        next();
    };

    function ensureAsync(fn) {
        return _restParam(function (args) {
            var callback = args.pop();
            args.push(function () {
                var innerArgs = arguments;
                if (sync) {
                    async.setImmediate(function () {
                        callback.apply(null, innerArgs);
                    });
                } else {
                    callback.apply(null, innerArgs);
                }
            });
            var sync = true;
            fn.apply(this, args);
            sync = false;
        });
    }

    async.ensureAsync = ensureAsync;

    async.constant = _restParam(function(values) {
        var args = [null].concat(values);
        return function (callback) {
            return callback.apply(this, args);
        };
    });

    async.wrapSync =
    async.asyncify = function asyncify(func) {
        return _restParam(function (args) {
            var callback = args.pop();
            var result;
            try {
                result = func.apply(this, args);
            } catch (e) {
                return callback(e);
            }
            // if result is Promise object
            if (_isObject(result) && typeof result.then === "function") {
                result.then(function(value) {
                    callback(null, value);
                })["catch"](function(err) {
                    callback(err.message ? err : new Error(err));
                });
            } else {
                callback(null, result);
            }
        });
    };

    // Node.js
    if (typeof module === 'object' && module.exports) {
        module.exports = async;
    }
    // AMD / RequireJS
    else if (typeof define === 'function' && define.amd) {
        define([], function () {
            return async;
        });
    }
    // included directly via <script> tag
    else {
        root.async = async;
    }

}());

}).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
},{"_process":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/process/browser.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/babel-regenerator-runtime/runtime.js":[function(require,module,exports){
(function (process,global){
/**
 * Copyright (c) 2014, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * https://raw.github.com/facebook/regenerator/master/LICENSE file. An
 * additional grant of patent rights can be found in the PATENTS file in
 * the same directory.
 */

!(function(global) {
  "use strict";

  var hasOwn = Object.prototype.hasOwnProperty;
  var undefined; // More compressible than void 0.
  var iteratorSymbol =
    typeof Symbol === "function" && Symbol.iterator || "@@iterator";

  var inModule = typeof module === "object";
  var runtime = global.regeneratorRuntime;
  if (runtime) {
    if (inModule) {
      // If regeneratorRuntime is defined globally and we're in a module,
      // make the exports object identical to regeneratorRuntime.
      module.exports = runtime;
    }
    // Don't bother evaluating the rest of this file if the runtime was
    // already defined globally.
    return;
  }

  // Define the runtime globally (as expected by generated code) as either
  // module.exports (if we're in a module) or a new, empty object.
  runtime = global.regeneratorRuntime = inModule ? module.exports : {};

  function wrap(innerFn, outerFn, self, tryLocsList) {
    // If outerFn provided, then outerFn.prototype instanceof Generator.
    var generator = Object.create((outerFn || Generator).prototype);
    var context = new Context(tryLocsList || []);

    // The ._invoke method unifies the implementations of the .next,
    // .throw, and .return methods.
    generator._invoke = makeInvokeMethod(innerFn, self, context);

    return generator;
  }
  runtime.wrap = wrap;

  // Try/catch helper to minimize deoptimizations. Returns a completion
  // record like context.tryEntries[i].completion. This interface could
  // have been (and was previously) designed to take a closure to be
  // invoked without arguments, but in all the cases we care about we
  // already have an existing method we want to call, so there's no need
  // to create a new function object. We can even get away with assuming
  // the method takes exactly one argument, since that happens to be true
  // in every case, so we don't have to touch the arguments object. The
  // only additional allocation required is the completion record, which
  // has a stable shape and so hopefully should be cheap to allocate.
  function tryCatch(fn, obj, arg) {
    try {
      return { type: "normal", arg: fn.call(obj, arg) };
    } catch (err) {
      return { type: "throw", arg: err };
    }
  }

  var GenStateSuspendedStart = "suspendedStart";
  var GenStateSuspendedYield = "suspendedYield";
  var GenStateExecuting = "executing";
  var GenStateCompleted = "completed";

  // Returning this object from the innerFn has the same effect as
  // breaking out of the dispatch switch statement.
  var ContinueSentinel = {};

  // Dummy constructor functions that we use as the .constructor and
  // .constructor.prototype properties for functions that return Generator
  // objects. For full spec compliance, you may wish to configure your
  // minifier not to mangle the names of these two functions.
  function Generator() {}
  function GeneratorFunction() {}
  function GeneratorFunctionPrototype() {}

  var Gp = GeneratorFunctionPrototype.prototype = Generator.prototype;
  GeneratorFunction.prototype = Gp.constructor = GeneratorFunctionPrototype;
  GeneratorFunctionPrototype.constructor = GeneratorFunction;
  GeneratorFunction.displayName = "GeneratorFunction";

  // Helper for defining the .next, .throw, and .return methods of the
  // Iterator interface in terms of a single ._invoke method.
  function defineIteratorMethods(prototype) {
    ["next", "throw", "return"].forEach(function(method) {
      prototype[method] = function(arg) {
        return this._invoke(method, arg);
      };
    });
  }

  runtime.isGeneratorFunction = function(genFun) {
    var ctor = typeof genFun === "function" && genFun.constructor;
    return ctor
      ? ctor === GeneratorFunction ||
        // For the native GeneratorFunction constructor, the best we can
        // do is to check its .name property.
        (ctor.displayName || ctor.name) === "GeneratorFunction"
      : false;
  };

  runtime.mark = function(genFun) {
    if (Object.setPrototypeOf) {
      Object.setPrototypeOf(genFun, GeneratorFunctionPrototype);
    } else {
      genFun.__proto__ = GeneratorFunctionPrototype;
    }
    genFun.prototype = Object.create(Gp);
    return genFun;
  };

  // Within the body of any async function, `await x` is transformed to
  // `yield regeneratorRuntime.awrap(x)`, so that the runtime can test
  // `value instanceof AwaitArgument` to determine if the yielded value is
  // meant to be awaited. Some may consider the name of this method too
  // cutesy, but they are curmudgeons.
  runtime.awrap = function(arg) {
    return new AwaitArgument(arg);
  };

  function AwaitArgument(arg) {
    this.arg = arg;
  }

  function AsyncIterator(generator) {
    // This invoke function is written in a style that assumes some
    // calling function (or Promise) will handle exceptions.
    function invoke(method, arg) {
      var result = generator[method](arg);
      var value = result.value;
      return value instanceof AwaitArgument
        ? Promise.resolve(value.arg).then(invokeNext, invokeThrow)
        : Promise.resolve(value).then(function(unwrapped) {
            // When a yielded Promise is resolved, its final value becomes
            // the .value of the Promise<{value,done}> result for the
            // current iteration. If the Promise is rejected, however, the
            // result for this iteration will be rejected with the same
            // reason. Note that rejections of yielded Promises are not
            // thrown back into the generator function, as is the case
            // when an awaited Promise is rejected. This difference in
            // behavior between yield and await is important, because it
            // allows the consumer to decide what to do with the yielded
            // rejection (swallow it and continue, manually .throw it back
            // into the generator, abandon iteration, whatever). With
            // await, by contrast, there is no opportunity to examine the
            // rejection reason outside the generator function, so the
            // only option is to throw it from the await expression, and
            // let the generator function handle the exception.
            result.value = unwrapped;
            return result;
          });
    }

    if (typeof process === "object" && process.domain) {
      invoke = process.domain.bind(invoke);
    }

    var invokeNext = invoke.bind(generator, "next");
    var invokeThrow = invoke.bind(generator, "throw");
    var invokeReturn = invoke.bind(generator, "return");
    var previousPromise;

    function enqueue(method, arg) {
      function callInvokeWithMethodAndArg() {
        return invoke(method, arg);
      }

      return previousPromise =
        // If enqueue has been called before, then we want to wait until
        // all previous Promises have been resolved before calling invoke,
        // so that results are always delivered in the correct order. If
        // enqueue has not been called before, then it is important to
        // call invoke immediately, without waiting on a callback to fire,
        // so that the async generator function has the opportunity to do
        // any necessary setup in a predictable way. This predictability
        // is why the Promise constructor synchronously invokes its
        // executor callback, and why async functions synchronously
        // execute code before the first await. Since we implement simple
        // async functions in terms of async generators, it is especially
        // important to get this right, even though it requires care.
        previousPromise ? previousPromise.then(
          callInvokeWithMethodAndArg,
          // Avoid propagating failures to Promises returned by later
          // invocations of the iterator.
          callInvokeWithMethodAndArg
        ) : new Promise(function (resolve) {
          resolve(callInvokeWithMethodAndArg());
        });
    }

    // Define the unified helper method that is used to implement .next,
    // .throw, and .return (see defineIteratorMethods).
    this._invoke = enqueue;
  }

  defineIteratorMethods(AsyncIterator.prototype);

  // Note that simple async functions are implemented on top of
  // AsyncIterator objects; they just return a Promise for the value of
  // the final result produced by the iterator.
  runtime.async = function(innerFn, outerFn, self, tryLocsList) {
    var iter = new AsyncIterator(
      wrap(innerFn, outerFn, self, tryLocsList)
    );

    return runtime.isGeneratorFunction(outerFn)
      ? iter // If outerFn is a generator, return the full iterator.
      : iter.next().then(function(result) {
          return result.done ? result.value : iter.next();
        });
  };

  function makeInvokeMethod(innerFn, self, context) {
    var state = GenStateSuspendedStart;

    return function invoke(method, arg) {
      if (state === GenStateExecuting) {
        throw new Error("Generator is already running");
      }

      if (state === GenStateCompleted) {
        if (method === "throw") {
          throw arg;
        }

        // Be forgiving, per 25.3.3.3.3 of the spec:
        // https://people.mozilla.org/~jorendorff/es6-draft.html#sec-generatorresume
        return doneResult();
      }

      while (true) {
        var delegate = context.delegate;
        if (delegate) {
          if (method === "return" ||
              (method === "throw" && delegate.iterator[method] === undefined)) {
            // A return or throw (when the delegate iterator has no throw
            // method) always terminates the yield* loop.
            context.delegate = null;

            // If the delegate iterator has a return method, give it a
            // chance to clean up.
            var returnMethod = delegate.iterator["return"];
            if (returnMethod) {
              var record = tryCatch(returnMethod, delegate.iterator, arg);
              if (record.type === "throw") {
                // If the return method threw an exception, let that
                // exception prevail over the original return or throw.
                method = "throw";
                arg = record.arg;
                continue;
              }
            }

            if (method === "return") {
              // Continue with the outer return, now that the delegate
              // iterator has been terminated.
              continue;
            }
          }

          var record = tryCatch(
            delegate.iterator[method],
            delegate.iterator,
            arg
          );

          if (record.type === "throw") {
            context.delegate = null;

            // Like returning generator.throw(uncaught), but without the
            // overhead of an extra function call.
            method = "throw";
            arg = record.arg;
            continue;
          }

          // Delegate generator ran and handled its own exceptions so
          // regardless of what the method was, we continue as if it is
          // "next" with an undefined arg.
          method = "next";
          arg = undefined;

          var info = record.arg;
          if (info.done) {
            context[delegate.resultName] = info.value;
            context.next = delegate.nextLoc;
          } else {
            state = GenStateSuspendedYield;
            return info;
          }

          context.delegate = null;
        }

        if (method === "next") {
          context._sent = arg;

          if (state === GenStateSuspendedYield) {
            context.sent = arg;
          } else {
            context.sent = undefined;
          }
        } else if (method === "throw") {
          if (state === GenStateSuspendedStart) {
            state = GenStateCompleted;
            throw arg;
          }

          if (context.dispatchException(arg)) {
            // If the dispatched exception was caught by a catch block,
            // then let that catch block handle the exception normally.
            method = "next";
            arg = undefined;
          }

        } else if (method === "return") {
          context.abrupt("return", arg);
        }

        state = GenStateExecuting;

        var record = tryCatch(innerFn, self, context);
        if (record.type === "normal") {
          // If an exception is thrown from innerFn, we leave state ===
          // GenStateExecuting and loop back for another invocation.
          state = context.done
            ? GenStateCompleted
            : GenStateSuspendedYield;

          var info = {
            value: record.arg,
            done: context.done
          };

          if (record.arg === ContinueSentinel) {
            if (context.delegate && method === "next") {
              // Deliberately forget the last sent value so that we don't
              // accidentally pass it on to the delegate.
              arg = undefined;
            }
          } else {
            return info;
          }

        } else if (record.type === "throw") {
          state = GenStateCompleted;
          // Dispatch the exception by looping back around to the
          // context.dispatchException(arg) call above.
          method = "throw";
          arg = record.arg;
        }
      }
    };
  }

  // Define Generator.prototype.{next,throw,return} in terms of the
  // unified ._invoke helper method.
  defineIteratorMethods(Gp);

  Gp[iteratorSymbol] = function() {
    return this;
  };

  Gp.toString = function() {
    return "[object Generator]";
  };

  function pushTryEntry(locs) {
    var entry = { tryLoc: locs[0] };

    if (1 in locs) {
      entry.catchLoc = locs[1];
    }

    if (2 in locs) {
      entry.finallyLoc = locs[2];
      entry.afterLoc = locs[3];
    }

    this.tryEntries.push(entry);
  }

  function resetTryEntry(entry) {
    var record = entry.completion || {};
    record.type = "normal";
    delete record.arg;
    entry.completion = record;
  }

  function Context(tryLocsList) {
    // The root entry object (effectively a try statement without a catch
    // or a finally block) gives us a place to store values thrown from
    // locations where there is no enclosing try statement.
    this.tryEntries = [{ tryLoc: "root" }];
    tryLocsList.forEach(pushTryEntry, this);
    this.reset(true);
  }

  runtime.keys = function(object) {
    var keys = [];
    for (var key in object) {
      keys.push(key);
    }
    keys.reverse();

    // Rather than returning an object with a next method, we keep
    // things simple and return the next function itself.
    return function next() {
      while (keys.length) {
        var key = keys.pop();
        if (key in object) {
          next.value = key;
          next.done = false;
          return next;
        }
      }

      // To avoid creating an additional object, we just hang the .value
      // and .done properties off the next function object itself. This
      // also ensures that the minifier will not anonymize the function.
      next.done = true;
      return next;
    };
  };

  function values(iterable) {
    if (iterable) {
      var iteratorMethod = iterable[iteratorSymbol];
      if (iteratorMethod) {
        return iteratorMethod.call(iterable);
      }

      if (typeof iterable.next === "function") {
        return iterable;
      }

      if (!isNaN(iterable.length)) {
        var i = -1, next = function next() {
          while (++i < iterable.length) {
            if (hasOwn.call(iterable, i)) {
              next.value = iterable[i];
              next.done = false;
              return next;
            }
          }

          next.value = undefined;
          next.done = true;

          return next;
        };

        return next.next = next;
      }
    }

    // Return an iterator with no values.
    return { next: doneResult };
  }
  runtime.values = values;

  function doneResult() {
    return { value: undefined, done: true };
  }

  Context.prototype = {
    constructor: Context,

    reset: function(skipTempReset) {
      this.prev = 0;
      this.next = 0;
      this.sent = undefined;
      this.done = false;
      this.delegate = null;

      this.tryEntries.forEach(resetTryEntry);

      if (!skipTempReset) {
        for (var name in this) {
          // Not sure about the optimal order of these conditions:
          if (name.charAt(0) === "t" &&
              hasOwn.call(this, name) &&
              !isNaN(+name.slice(1))) {
            this[name] = undefined;
          }
        }
      }
    },

    stop: function() {
      this.done = true;

      var rootEntry = this.tryEntries[0];
      var rootRecord = rootEntry.completion;
      if (rootRecord.type === "throw") {
        throw rootRecord.arg;
      }

      return this.rval;
    },

    dispatchException: function(exception) {
      if (this.done) {
        throw exception;
      }

      var context = this;
      function handle(loc, caught) {
        record.type = "throw";
        record.arg = exception;
        context.next = loc;
        return !!caught;
      }

      for (var i = this.tryEntries.length - 1; i >= 0; --i) {
        var entry = this.tryEntries[i];
        var record = entry.completion;

        if (entry.tryLoc === "root") {
          // Exception thrown outside of any try block that could handle
          // it, so set the completion value of the entire function to
          // throw the exception.
          return handle("end");
        }

        if (entry.tryLoc <= this.prev) {
          var hasCatch = hasOwn.call(entry, "catchLoc");
          var hasFinally = hasOwn.call(entry, "finallyLoc");

          if (hasCatch && hasFinally) {
            if (this.prev < entry.catchLoc) {
              return handle(entry.catchLoc, true);
            } else if (this.prev < entry.finallyLoc) {
              return handle(entry.finallyLoc);
            }

          } else if (hasCatch) {
            if (this.prev < entry.catchLoc) {
              return handle(entry.catchLoc, true);
            }

          } else if (hasFinally) {
            if (this.prev < entry.finallyLoc) {
              return handle(entry.finallyLoc);
            }

          } else {
            throw new Error("try statement without catch or finally");
          }
        }
      }
    },

    abrupt: function(type, arg) {
      for (var i = this.tryEntries.length - 1; i >= 0; --i) {
        var entry = this.tryEntries[i];
        if (entry.tryLoc <= this.prev &&
            hasOwn.call(entry, "finallyLoc") &&
            this.prev < entry.finallyLoc) {
          var finallyEntry = entry;
          break;
        }
      }

      if (finallyEntry &&
          (type === "break" ||
           type === "continue") &&
          finallyEntry.tryLoc <= arg &&
          arg <= finallyEntry.finallyLoc) {
        // Ignore the finally entry if control is not jumping to a
        // location outside the try/catch block.
        finallyEntry = null;
      }

      var record = finallyEntry ? finallyEntry.completion : {};
      record.type = type;
      record.arg = arg;

      if (finallyEntry) {
        this.next = finallyEntry.finallyLoc;
      } else {
        this.complete(record);
      }

      return ContinueSentinel;
    },

    complete: function(record, afterLoc) {
      if (record.type === "throw") {
        throw record.arg;
      }

      if (record.type === "break" ||
          record.type === "continue") {
        this.next = record.arg;
      } else if (record.type === "return") {
        this.rval = record.arg;
        this.next = "end";
      } else if (record.type === "normal" && afterLoc) {
        this.next = afterLoc;
      }
    },

    finish: function(finallyLoc) {
      for (var i = this.tryEntries.length - 1; i >= 0; --i) {
        var entry = this.tryEntries[i];
        if (entry.finallyLoc === finallyLoc) {
          this.complete(entry.completion, entry.afterLoc);
          resetTryEntry(entry);
          return ContinueSentinel;
        }
      }
    },

    "catch": function(tryLoc) {
      for (var i = this.tryEntries.length - 1; i >= 0; --i) {
        var entry = this.tryEntries[i];
        if (entry.tryLoc === tryLoc) {
          var record = entry.completion;
          if (record.type === "throw") {
            var thrown = record.arg;
            resetTryEntry(entry);
          }
          return thrown;
        }
      }

      // The context.catch method must only be called with a location
      // argument that corresponds to a known catch block.
      throw new Error("illegal catch attempt");
    },

    delegateYield: function(iterable, resultName, nextLoc) {
      this.delegate = {
        iterator: values(iterable),
        resultName: resultName,
        nextLoc: nextLoc
      };

      return ContinueSentinel;
    }
  };
})(
  // Among the various tricks for obtaining a reference to the global
  // object, this seems to be the most reliable technique that does not
  // use indirect eval (which violates Content Security Policy).
  typeof global === "object" ? global :
  typeof window === "object" ? window :
  typeof self === "object" ? self : this
);

}).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
},{"_process":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/process/browser.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/base64-js/index.js":[function(require,module,exports){
'use strict'

exports.byteLength = byteLength
exports.toByteArray = toByteArray
exports.fromByteArray = fromByteArray

var lookup = []
var revLookup = []
var Arr = typeof Uint8Array !== 'undefined' ? Uint8Array : Array

var code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
for (var i = 0, len = code.length; i < len; ++i) {
  lookup[i] = code[i]
  revLookup[code.charCodeAt(i)] = i
}

revLookup['-'.charCodeAt(0)] = 62
revLookup['_'.charCodeAt(0)] = 63

function placeHoldersCount (b64) {
  var len = b64.length
  if (len % 4 > 0) {
    throw new Error('Invalid string. Length must be a multiple of 4')
  }

  // the number of equal signs (place holders)
  // if there are two placeholders, than the two characters before it
  // represent one byte
  // if there is only one, then the three characters before it represent 2 bytes
  // this is just a cheap hack to not do indexOf twice
  return b64[len - 2] === '=' ? 2 : b64[len - 1] === '=' ? 1 : 0
}

function byteLength (b64) {
  // base64 is 4/3 + up to two characters of the original data
  return (b64.length * 3 / 4) - placeHoldersCount(b64)
}

function toByteArray (b64) {
  var i, l, tmp, placeHolders, arr
  var len = b64.length
  placeHolders = placeHoldersCount(b64)

  arr = new Arr((len * 3 / 4) - placeHolders)

  // if there are placeholders, only get up to the last complete 4 chars
  l = placeHolders > 0 ? len - 4 : len

  var L = 0

  for (i = 0; i < l; i += 4) {
    tmp = (revLookup[b64.charCodeAt(i)] << 18) | (revLookup[b64.charCodeAt(i + 1)] << 12) | (revLookup[b64.charCodeAt(i + 2)] << 6) | revLookup[b64.charCodeAt(i + 3)]
    arr[L++] = (tmp >> 16) & 0xFF
    arr[L++] = (tmp >> 8) & 0xFF
    arr[L++] = tmp & 0xFF
  }

  if (placeHolders === 2) {
    tmp = (revLookup[b64.charCodeAt(i)] << 2) | (revLookup[b64.charCodeAt(i + 1)] >> 4)
    arr[L++] = tmp & 0xFF
  } else if (placeHolders === 1) {
    tmp = (revLookup[b64.charCodeAt(i)] << 10) | (revLookup[b64.charCodeAt(i + 1)] << 4) | (revLookup[b64.charCodeAt(i + 2)] >> 2)
    arr[L++] = (tmp >> 8) & 0xFF
    arr[L++] = tmp & 0xFF
  }

  return arr
}

function tripletToBase64 (num) {
  return lookup[num >> 18 & 0x3F] + lookup[num >> 12 & 0x3F] + lookup[num >> 6 & 0x3F] + lookup[num & 0x3F]
}

function encodeChunk (uint8, start, end) {
  var tmp
  var output = []
  for (var i = start; i < end; i += 3) {
    tmp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2])
    output.push(tripletToBase64(tmp))
  }
  return output.join('')
}

function fromByteArray (uint8) {
  var tmp
  var len = uint8.length
  var extraBytes = len % 3 // if we have 1 byte left, pad 2 bytes
  var output = ''
  var parts = []
  var maxChunkLength = 16383 // must be multiple of 3

  // go through the array every three bytes, we'll deal with trailing stuff later
  for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) {
    parts.push(encodeChunk(uint8, i, (i + maxChunkLength) > len2 ? len2 : (i + maxChunkLength)))
  }

  // pad the end with zeros, but make sure to not forget the extra bytes
  if (extraBytes === 1) {
    tmp = uint8[len - 1]
    output += lookup[tmp >> 2]
    output += lookup[(tmp << 4) & 0x3F]
    output += '=='
  } else if (extraBytes === 2) {
    tmp = (uint8[len - 2] << 8) + (uint8[len - 1])
    output += lookup[tmp >> 10]
    output += lookup[(tmp >> 4) & 0x3F]
    output += lookup[(tmp << 2) & 0x3F]
    output += '='
  }

  parts.push(output)

  return parts.join('')
}

},{}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/bignumber.js/bignumber.js":[function(require,module,exports){
/*! bignumber.js v2.3.0 https://github.com/MikeMcl/bignumber.js/LICENCE */

;(function (globalObj) {
    'use strict';

    /*
      bignumber.js v2.3.0
      A JavaScript library for arbitrary-precision arithmetic.
      https://github.com/MikeMcl/bignumber.js
      Copyright (c) 2016 Michael Mclaughlin <M8ch88l@gmail.com>
      MIT Expat Licence
    */


    var cryptoObj, parseNumeric,
        isNumeric = /^-?(\d+(\.\d*)?|\.\d+)(e[+-]?\d+)?$/i,
        mathceil = Math.ceil,
        mathfloor = Math.floor,
        notBool = ' not a boolean or binary digit',
        roundingMode = 'rounding mode',
        tooManyDigits = 'number type has more than 15 significant digits',
        ALPHABET = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$_',
        BASE = 1e14,
        LOG_BASE = 14,
        MAX_SAFE_INTEGER = 0x1fffffffffffff,         // 2^53 - 1
        // MAX_INT32 = 0x7fffffff,                   // 2^31 - 1
        POWS_TEN = [1, 10, 100, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10, 1e11, 1e12, 1e13],
        SQRT_BASE = 1e7,

        /*
         * The limit on the value of DECIMAL_PLACES, TO_EXP_NEG, TO_EXP_POS, MIN_EXP, MAX_EXP, and
         * the arguments to toExponential, toFixed, toFormat, and toPrecision, beyond which an
         * exception is thrown (if ERRORS is true).
         */
        MAX = 1E9;                                   // 0 to MAX_INT32

    if ( typeof crypto != 'undefined' ) cryptoObj = crypto;


    /*
     * Create and return a BigNumber constructor.
     */
    function constructorFactory(configObj) {
        var div,

            // id tracks the caller function, so its name can be included in error messages.
            id = 0,
            P = BigNumber.prototype,
            ONE = new BigNumber(1),


            /********************************* EDITABLE DEFAULTS **********************************/


            /*
             * The default values below must be integers within the inclusive ranges stated.
             * The values can also be changed at run-time using BigNumber.config.
             */

            // The maximum number of decimal places for operations involving division.
            DECIMAL_PLACES = 20,                     // 0 to MAX

            /*
             * The rounding mode used when rounding to the above decimal places, and when using
             * toExponential, toFixed, toFormat and toPrecision, and round (default value).
             * UP         0 Away from zero.
             * DOWN       1 Towards zero.
             * CEIL       2 Towards +Infinity.
             * FLOOR      3 Towards -Infinity.
             * HALF_UP    4 Towards nearest neighbour. If equidistant, up.
             * HALF_DOWN  5 Towards nearest neighbour. If equidistant, down.
             * HALF_EVEN  6 Towards nearest neighbour. If equidistant, towards even neighbour.
             * HALF_CEIL  7 Towards nearest neighbour. If equidistant, towards +Infinity.
             * HALF_FLOOR 8 Towards nearest neighbour. If equidistant, towards -Infinity.
             */
            ROUNDING_MODE = 4,                       // 0 to 8

            // EXPONENTIAL_AT : [TO_EXP_NEG , TO_EXP_POS]

            // The exponent value at and beneath which toString returns exponential notation.
            // Number type: -7
            TO_EXP_NEG = -7,                         // 0 to -MAX

            // The exponent value at and above which toString returns exponential notation.
            // Number type: 21
            TO_EXP_POS = 21,                         // 0 to MAX

            // RANGE : [MIN_EXP, MAX_EXP]

            // The minimum exponent value, beneath which underflow to zero occurs.
            // Number type: -324  (5e-324)
            MIN_EXP = -1e7,                          // -1 to -MAX

            // The maximum exponent value, above which overflow to Infinity occurs.
            // Number type:  308  (1.7976931348623157e+308)
            // For MAX_EXP > 1e7, e.g. new BigNumber('1e100000000').plus(1) may be slow.
            MAX_EXP = 1e7,                           // 1 to MAX

            // Whether BigNumber Errors are ever thrown.
            ERRORS = true,                           // true or false

            // Change to intValidatorNoErrors if ERRORS is false.
            isValidInt = intValidatorWithErrors,     // intValidatorWithErrors/intValidatorNoErrors

            // Whether to use cryptographically-secure random number generation, if available.
            CRYPTO = false,                          // true or false

            /*
             * The modulo mode used when calculating the modulus: a mod n.
             * The quotient (q = a / n) is calculated according to the corresponding rounding mode.
             * The remainder (r) is calculated as: r = a - n * q.
             *
             * UP        0 The remainder is positive if the dividend is negative, else is negative.
             * DOWN      1 The remainder has the same sign as the dividend.
             *             This modulo mode is commonly known as 'truncated division' and is
             *             equivalent to (a % n) in JavaScript.
             * FLOOR     3 The remainder has the same sign as the divisor (Python %).
             * HALF_EVEN 6 This modulo mode implements the IEEE 754 remainder function.
             * EUCLID    9 Euclidian division. q = sign(n) * floor(a / abs(n)).
             *             The remainder is always positive.
             *
             * The truncated division, floored division, Euclidian division and IEEE 754 remainder
             * modes are commonly used for the modulus operation.
             * Although the other rounding modes can also be used, they may not give useful results.
             */
            MODULO_MODE = 1,                         // 0 to 9

            // The maximum number of significant digits of the result of the toPower operation.
            // If POW_PRECISION is 0, there will be unlimited significant digits.
            POW_PRECISION = 100,                     // 0 to MAX

            // The format specification used by the BigNumber.prototype.toFormat method.
            FORMAT = {
                decimalSeparator: '.',
                groupSeparator: ',',
                groupSize: 3,
                secondaryGroupSize: 0,
                fractionGroupSeparator: '\xA0',      // non-breaking space
                fractionGroupSize: 0
            };


        /******************************************************************************************/


        // CONSTRUCTOR


        /*
         * The BigNumber constructor and exported function.
         * Create and return a new instance of a BigNumber object.
         *
         * n {number|string|BigNumber} A numeric value.
         * [b] {number} The base of n. Integer, 2 to 64 inclusive.
         */
        function BigNumber( n, b ) {
            var c, e, i, num, len, str,
                x = this;

            // Enable constructor usage without new.
            if ( !( x instanceof BigNumber ) ) {

                // 'BigNumber() constructor call without new: {n}'
                if (ERRORS) raise( 26, 'constructor call without new', n );
                return new BigNumber( n, b );
            }

            // 'new BigNumber() base not an integer: {b}'
            // 'new BigNumber() base out of range: {b}'
            if ( b == null || !isValidInt( b, 2, 64, id, 'base' ) ) {

                // Duplicate.
                if ( n instanceof BigNumber ) {
                    x.s = n.s;
                    x.e = n.e;
                    x.c = ( n = n.c ) ? n.slice() : n;
                    id = 0;
                    return;
                }

                if ( ( num = typeof n == 'number' ) && n * 0 == 0 ) {
                    x.s = 1 / n < 0 ? ( n = -n, -1 ) : 1;

                    // Fast path for integers.
                    if ( n === ~~n ) {
                        for ( e = 0, i = n; i >= 10; i /= 10, e++ );
                        x.e = e;
                        x.c = [n];
                        id = 0;
                        return;
                    }

                    str = n + '';
                } else {
                    if ( !isNumeric.test( str = n + '' ) ) return parseNumeric( x, str, num );
                    x.s = str.charCodeAt(0) === 45 ? ( str = str.slice(1), -1 ) : 1;
                }
            } else {
                b = b | 0;
                str = n + '';

                // Ensure return value is rounded to DECIMAL_PLACES as with other bases.
                // Allow exponential notation to be used with base 10 argument.
                if ( b == 10 ) {
                    x = new BigNumber( n instanceof BigNumber ? n : str );
                    return round( x, DECIMAL_PLACES + x.e + 1, ROUNDING_MODE );
                }

                // Avoid potential interpretation of Infinity and NaN as base 44+ values.
                // Any number in exponential form will fail due to the [Ee][+-].
                if ( ( num = typeof n == 'number' ) && n * 0 != 0 ||
                  !( new RegExp( '^-?' + ( c = '[' + ALPHABET.slice( 0, b ) + ']+' ) +
                    '(?:\\.' + c + ')?$',b < 37 ? 'i' : '' ) ).test(str) ) {
                    return parseNumeric( x, str, num, b );
                }

                if (num) {
                    x.s = 1 / n < 0 ? ( str = str.slice(1), -1 ) : 1;

                    if ( ERRORS && str.replace( /^0\.0*|\./, '' ).length > 15 ) {

                        // 'new BigNumber() number type has more than 15 significant digits: {n}'
                        raise( id, tooManyDigits, n );
                    }

                    // Prevent later check for length on converted number.
                    num = false;
                } else {
                    x.s = str.charCodeAt(0) === 45 ? ( str = str.slice(1), -1 ) : 1;
                }

                str = convertBase( str, 10, b, x.s );
            }

            // Decimal point?
            if ( ( e = str.indexOf('.') ) > -1 ) str = str.replace( '.', '' );

            // Exponential form?
            if ( ( i = str.search( /e/i ) ) > 0 ) {

                // Determine exponent.
                if ( e < 0 ) e = i;
                e += +str.slice( i + 1 );
                str = str.substring( 0, i );
            } else if ( e < 0 ) {

                // Integer.
                e = str.length;
            }

            // Determine leading zeros.
            for ( i = 0; str.charCodeAt(i) === 48; i++ );

            // Determine trailing zeros.
            for ( len = str.length; str.charCodeAt(--len) === 48; );
            str = str.slice( i, len + 1 );

            if (str) {
                len = str.length;

                // Disallow numbers with over 15 significant digits if number type.
                // 'new BigNumber() number type has more than 15 significant digits: {n}'
                if ( num && ERRORS && len > 15 && ( n > MAX_SAFE_INTEGER || n !== mathfloor(n) ) ) {
                    raise( id, tooManyDigits, x.s * n );
                }

                e = e - i - 1;

                 // Overflow?
                if ( e > MAX_EXP ) {

                    // Infinity.
                    x.c = x.e = null;

                // Underflow?
                } else if ( e < MIN_EXP ) {

                    // Zero.
                    x.c = [ x.e = 0 ];
                } else {
                    x.e = e;
                    x.c = [];

                    // Transform base

                    // e is the base 10 exponent.
                    // i is where to slice str to get the first element of the coefficient array.
                    i = ( e + 1 ) % LOG_BASE;
                    if ( e < 0 ) i += LOG_BASE;

                    if ( i < len ) {
                        if (i) x.c.push( +str.slice( 0, i ) );

                        for ( len -= LOG_BASE; i < len; ) {
                            x.c.push( +str.slice( i, i += LOG_BASE ) );
                        }

                        str = str.slice(i);
                        i = LOG_BASE - str.length;
                    } else {
                        i -= len;
                    }

                    for ( ; i--; str += '0' );
                    x.c.push( +str );
                }
            } else {

                // Zero.
                x.c = [ x.e = 0 ];
            }

            id = 0;
        }


        // CONSTRUCTOR PROPERTIES


        BigNumber.another = constructorFactory;

        BigNumber.ROUND_UP = 0;
        BigNumber.ROUND_DOWN = 1;
        BigNumber.ROUND_CEIL = 2;
        BigNumber.ROUND_FLOOR = 3;
        BigNumber.ROUND_HALF_UP = 4;
        BigNumber.ROUND_HALF_DOWN = 5;
        BigNumber.ROUND_HALF_EVEN = 6;
        BigNumber.ROUND_HALF_CEIL = 7;
        BigNumber.ROUND_HALF_FLOOR = 8;
        BigNumber.EUCLID = 9;


        /*
         * Configure infrequently-changing library-wide settings.
         *
         * Accept an object or an argument list, with one or many of the following properties or
         * parameters respectively:
         *
         *   DECIMAL_PLACES  {number}  Integer, 0 to MAX inclusive
         *   ROUNDING_MODE   {number}  Integer, 0 to 8 inclusive
         *   EXPONENTIAL_AT  {number|number[]}  Integer, -MAX to MAX inclusive or
         *                                      [integer -MAX to 0 incl., 0 to MAX incl.]
         *   RANGE           {number|number[]}  Non-zero integer, -MAX to MAX inclusive or
         *                                      [integer -MAX to -1 incl., integer 1 to MAX incl.]
         *   ERRORS          {boolean|number}   true, false, 1 or 0
         *   CRYPTO          {boolean|number}   true, false, 1 or 0
         *   MODULO_MODE     {number}           0 to 9 inclusive
         *   POW_PRECISION   {number}           0 to MAX inclusive
         *   FORMAT          {object}           See BigNumber.prototype.toFormat
         *      decimalSeparator       {string}
         *      groupSeparator         {string}
         *      groupSize              {number}
         *      secondaryGroupSize     {number}
         *      fractionGroupSeparator {string}
         *      fractionGroupSize      {number}
         *
         * (The values assigned to the above FORMAT object properties are not checked for validity.)
         *
         * E.g.
         * BigNumber.config(20, 4) is equivalent to
         * BigNumber.config({ DECIMAL_PLACES : 20, ROUNDING_MODE : 4 })
         *
         * Ignore properties/parameters set to null or undefined.
         * Return an object with the properties current values.
         */
        BigNumber.config = function () {
            var v, p,
                i = 0,
                r = {},
                a = arguments,
                o = a[0],
                has = o && typeof o == 'object'
                  ? function () { if ( o.hasOwnProperty(p) ) return ( v = o[p] ) != null; }
                  : function () { if ( a.length > i ) return ( v = a[i++] ) != null; };

            // DECIMAL_PLACES {number} Integer, 0 to MAX inclusive.
            // 'config() DECIMAL_PLACES not an integer: {v}'
            // 'config() DECIMAL_PLACES out of range: {v}'
            if ( has( p = 'DECIMAL_PLACES' ) && isValidInt( v, 0, MAX, 2, p ) ) {
                DECIMAL_PLACES = v | 0;
            }
            r[p] = DECIMAL_PLACES;

            // ROUNDING_MODE {number} Integer, 0 to 8 inclusive.
            // 'config() ROUNDING_MODE not an integer: {v}'
            // 'config() ROUNDING_MODE out of range: {v}'
            if ( has( p = 'ROUNDING_MODE' ) && isValidInt( v, 0, 8, 2, p ) ) {
                ROUNDING_MODE = v | 0;
            }
            r[p] = ROUNDING_MODE;

            // EXPONENTIAL_AT {number|number[]}
            // Integer, -MAX to MAX inclusive or [integer -MAX to 0 inclusive, 0 to MAX inclusive].
            // 'config() EXPONENTIAL_AT not an integer: {v}'
            // 'config() EXPONENTIAL_AT out of range: {v}'
            if ( has( p = 'EXPONENTIAL_AT' ) ) {

                if ( isArray(v) ) {
                    if ( isValidInt( v[0], -MAX, 0, 2, p ) && isValidInt( v[1], 0, MAX, 2, p ) ) {
                        TO_EXP_NEG = v[0] | 0;
                        TO_EXP_POS = v[1] | 0;
                    }
                } else if ( isValidInt( v, -MAX, MAX, 2, p ) ) {
                    TO_EXP_NEG = -( TO_EXP_POS = ( v < 0 ? -v : v ) | 0 );
                }
            }
            r[p] = [ TO_EXP_NEG, TO_EXP_POS ];

            // RANGE {number|number[]} Non-zero integer, -MAX to MAX inclusive or
            // [integer -MAX to -1 inclusive, integer 1 to MAX inclusive].
            // 'config() RANGE not an integer: {v}'
            // 'config() RANGE cannot be zero: {v}'
            // 'config() RANGE out of range: {v}'
            if ( has( p = 'RANGE' ) ) {

                if ( isArray(v) ) {
                    if ( isValidInt( v[0], -MAX, -1, 2, p ) && isValidInt( v[1], 1, MAX, 2, p ) ) {
                        MIN_EXP = v[0] | 0;
                        MAX_EXP = v[1] | 0;
                    }
                } else if ( isValidInt( v, -MAX, MAX, 2, p ) ) {
                    if ( v | 0 ) MIN_EXP = -( MAX_EXP = ( v < 0 ? -v : v ) | 0 );
                    else if (ERRORS) raise( 2, p + ' cannot be zero', v );
                }
            }
            r[p] = [ MIN_EXP, MAX_EXP ];

            // ERRORS {boolean|number} true, false, 1 or 0.
            // 'config() ERRORS not a boolean or binary digit: {v}'
            if ( has( p = 'ERRORS' ) ) {

                if ( v === !!v || v === 1 || v === 0 ) {
                    id = 0;
                    isValidInt = ( ERRORS = !!v ) ? intValidatorWithErrors : intValidatorNoErrors;
                } else if (ERRORS) {
                    raise( 2, p + notBool, v );
                }
            }
            r[p] = ERRORS;

            // CRYPTO {boolean|number} true, false, 1 or 0.
            // 'config() CRYPTO not a boolean or binary digit: {v}'
            // 'config() crypto unavailable: {crypto}'
            if ( has( p = 'CRYPTO' ) ) {

                if ( v === !!v || v === 1 || v === 0 ) {
                    CRYPTO = !!( v && cryptoObj );
                    if ( v && !CRYPTO && ERRORS ) raise( 2, 'crypto unavailable', cryptoObj );
                } else if (ERRORS) {
                    raise( 2, p + notBool, v );
                }
            }
            r[p] = CRYPTO;

            // MODULO_MODE {number} Integer, 0 to 9 inclusive.
            // 'config() MODULO_MODE not an integer: {v}'
            // 'config() MODULO_MODE out of range: {v}'
            if ( has( p = 'MODULO_MODE' ) && isValidInt( v, 0, 9, 2, p ) ) {
                MODULO_MODE = v | 0;
            }
            r[p] = MODULO_MODE;

            // POW_PRECISION {number} Integer, 0 to MAX inclusive.
            // 'config() POW_PRECISION not an integer: {v}'
            // 'config() POW_PRECISION out of range: {v}'
            if ( has( p = 'POW_PRECISION' ) && isValidInt( v, 0, MAX, 2, p ) ) {
                POW_PRECISION = v | 0;
            }
            r[p] = POW_PRECISION;

            // FORMAT {object}
            // 'config() FORMAT not an object: {v}'
            if ( has( p = 'FORMAT' ) ) {

                if ( typeof v == 'object' ) {
                    FORMAT = v;
                } else if (ERRORS) {
                    raise( 2, p + ' not an object', v );
                }
            }
            r[p] = FORMAT;

            return r;
        };


        /*
         * Return a new BigNumber whose value is the maximum of the arguments.
         *
         * arguments {number|string|BigNumber}
         */
        BigNumber.max = function () { return maxOrMin( arguments, P.lt ); };


        /*
         * Return a new BigNumber whose value is the minimum of the arguments.
         *
         * arguments {number|string|BigNumber}
         */
        BigNumber.min = function () { return maxOrMin( arguments, P.gt ); };


        /*
         * Return a new BigNumber with a random value equal to or greater than 0 and less than 1,
         * and with dp, or DECIMAL_PLACES if dp is omitted, decimal places (or less if trailing
         * zeros are produced).
         *
         * [dp] {number} Decimal places. Integer, 0 to MAX inclusive.
         *
         * 'random() decimal places not an integer: {dp}'
         * 'random() decimal places out of range: {dp}'
         * 'random() crypto unavailable: {crypto}'
         */
        BigNumber.random = (function () {
            var pow2_53 = 0x20000000000000;

            // Return a 53 bit integer n, where 0 <= n < 9007199254740992.
            // Check if Math.random() produces more than 32 bits of randomness.
            // If it does, assume at least 53 bits are produced, otherwise assume at least 30 bits.
            // 0x40000000 is 2^30, 0x800000 is 2^23, 0x1fffff is 2^21 - 1.
            var random53bitInt = (Math.random() * pow2_53) & 0x1fffff
              ? function () { return mathfloor( Math.random() * pow2_53 ); }
              : function () { return ((Math.random() * 0x40000000 | 0) * 0x800000) +
                  (Math.random() * 0x800000 | 0); };

            return function (dp) {
                var a, b, e, k, v,
                    i = 0,
                    c = [],
                    rand = new BigNumber(ONE);

                dp = dp == null || !isValidInt( dp, 0, MAX, 14 ) ? DECIMAL_PLACES : dp | 0;
                k = mathceil( dp / LOG_BASE );

                if (CRYPTO) {

                    // Browsers supporting crypto.getRandomValues.
                    if ( cryptoObj && cryptoObj.getRandomValues ) {

                        a = cryptoObj.getRandomValues( new Uint32Array( k *= 2 ) );

                        for ( ; i < k; ) {

                            // 53 bits:
                            // ((Math.pow(2, 32) - 1) * Math.pow(2, 21)).toString(2)
                            // 11111 11111111 11111111 11111111 11100000 00000000 00000000
                            // ((Math.pow(2, 32) - 1) >>> 11).toString(2)
                            //                                     11111 11111111 11111111
                            // 0x20000 is 2^21.
                            v = a[i] * 0x20000 + (a[i + 1] >>> 11);

                            // Rejection sampling:
                            // 0 <= v < 9007199254740992
                            // Probability that v >= 9e15, is
                            // 7199254740992 / 9007199254740992 ~= 0.0008, i.e. 1 in 1251
                            if ( v >= 9e15 ) {
                                b = cryptoObj.getRandomValues( new Uint32Array(2) );
                                a[i] = b[0];
                                a[i + 1] = b[1];
                            } else {

                                // 0 <= v <= 8999999999999999
                                // 0 <= (v % 1e14) <= 99999999999999
                                c.push( v % 1e14 );
                                i += 2;
                            }
                        }
                        i = k / 2;

                    // Node.js supporting crypto.randomBytes.
                    } else if ( cryptoObj && cryptoObj.randomBytes ) {

                        // buffer
                        a = cryptoObj.randomBytes( k *= 7 );

                        for ( ; i < k; ) {

                            // 0x1000000000000 is 2^48, 0x10000000000 is 2^40
                            // 0x100000000 is 2^32, 0x1000000 is 2^24
                            // 11111 11111111 11111111 11111111 11111111 11111111 11111111
                            // 0 <= v < 9007199254740992
                            v = ( ( a[i] & 31 ) * 0x1000000000000 ) + ( a[i + 1] * 0x10000000000 ) +
                                  ( a[i + 2] * 0x100000000 ) + ( a[i + 3] * 0x1000000 ) +
                                  ( a[i + 4] << 16 ) + ( a[i + 5] << 8 ) + a[i + 6];

                            if ( v >= 9e15 ) {
                                cryptoObj.randomBytes(7).copy( a, i );
                            } else {

                                // 0 <= (v % 1e14) <= 99999999999999
                                c.push( v % 1e14 );
                                i += 7;
                            }
                        }
                        i = k / 7;
                    } else if (ERRORS) {
                        raise( 14, 'crypto unavailable', cryptoObj );
                    }
                }

                // Use Math.random: CRYPTO is false or crypto is unavailable and ERRORS is false.
                if (!i) {

                    for ( ; i < k; ) {
                        v = random53bitInt();
                        if ( v < 9e15 ) c[i++] = v % 1e14;
                    }
                }

                k = c[--i];
                dp %= LOG_BASE;

                // Convert trailing digits to zeros according to dp.
                if ( k && dp ) {
                    v = POWS_TEN[LOG_BASE - dp];
                    c[i] = mathfloor( k / v ) * v;
                }

                // Remove trailing elements which are zero.
                for ( ; c[i] === 0; c.pop(), i-- );

                // Zero?
                if ( i < 0 ) {
                    c = [ e = 0 ];
                } else {

                    // Remove leading elements which are zero and adjust exponent accordingly.
                    for ( e = -1 ; c[0] === 0; c.shift(), e -= LOG_BASE);

                    // Count the digits of the first element of c to determine leading zeros, and...
                    for ( i = 1, v = c[0]; v >= 10; v /= 10, i++);

                    // adjust the exponent accordingly.
                    if ( i < LOG_BASE ) e -= LOG_BASE - i;
                }

                rand.e = e;
                rand.c = c;
                return rand;
            };
        })();


        // PRIVATE FUNCTIONS


        // Convert a numeric string of baseIn to a numeric string of baseOut.
        function convertBase( str, baseOut, baseIn, sign ) {
            var d, e, k, r, x, xc, y,
                i = str.indexOf( '.' ),
                dp = DECIMAL_PLACES,
                rm = ROUNDING_MODE;

            if ( baseIn < 37 ) str = str.toLowerCase();

            // Non-integer.
            if ( i >= 0 ) {
                k = POW_PRECISION;

                // Unlimited precision.
                POW_PRECISION = 0;
                str = str.replace( '.', '' );
                y = new BigNumber(baseIn);
                x = y.pow( str.length - i );
                POW_PRECISION = k;

                // Convert str as if an integer, then restore the fraction part by dividing the
                // result by its base raised to a power.
                y.c = toBaseOut( toFixedPoint( coeffToString( x.c ), x.e ), 10, baseOut );
                y.e = y.c.length;
            }

            // Convert the number as integer.
            xc = toBaseOut( str, baseIn, baseOut );
            e = k = xc.length;

            // Remove trailing zeros.
            for ( ; xc[--k] == 0; xc.pop() );
            if ( !xc[0] ) return '0';

            if ( i < 0 ) {
                --e;
            } else {
                x.c = xc;
                x.e = e;

                // sign is needed for correct rounding.
                x.s = sign;
                x = div( x, y, dp, rm, baseOut );
                xc = x.c;
                r = x.r;
                e = x.e;
            }

            d = e + dp + 1;

            // The rounding digit, i.e. the digit to the right of the digit that may be rounded up.
            i = xc[d];
            k = baseOut / 2;
            r = r || d < 0 || xc[d + 1] != null;

            r = rm < 4 ? ( i != null || r ) && ( rm == 0 || rm == ( x.s < 0 ? 3 : 2 ) )
                       : i > k || i == k &&( rm == 4 || r || rm == 6 && xc[d - 1] & 1 ||
                         rm == ( x.s < 0 ? 8 : 7 ) );

            if ( d < 1 || !xc[0] ) {

                // 1^-dp or 0.
                str = r ? toFixedPoint( '1', -dp ) : '0';
            } else {
                xc.length = d;

                if (r) {

                    // Rounding up may mean the previous digit has to be rounded up and so on.
                    for ( --baseOut; ++xc[--d] > baseOut; ) {
                        xc[d] = 0;

                        if ( !d ) {
                            ++e;
                            xc.unshift(1);
                        }
                    }
                }

                // Determine trailing zeros.
                for ( k = xc.length; !xc[--k]; );

                // E.g. [4, 11, 15] becomes 4bf.
                for ( i = 0, str = ''; i <= k; str += ALPHABET.charAt( xc[i++] ) );
                str = toFixedPoint( str, e );
            }

            // The caller will add the sign.
            return str;
        }


        // Perform division in the specified base. Called by div and convertBase.
        div = (function () {

            // Assume non-zero x and k.
            function multiply( x, k, base ) {
                var m, temp, xlo, xhi,
                    carry = 0,
                    i = x.length,
                    klo = k % SQRT_BASE,
                    khi = k / SQRT_BASE | 0;

                for ( x = x.slice(); i--; ) {
                    xlo = x[i] % SQRT_BASE;
                    xhi = x[i] / SQRT_BASE | 0;
                    m = khi * xlo + xhi * klo;
                    temp = klo * xlo + ( ( m % SQRT_BASE ) * SQRT_BASE ) + carry;
                    carry = ( temp / base | 0 ) + ( m / SQRT_BASE | 0 ) + khi * xhi;
                    x[i] = temp % base;
                }

                if (carry) x.unshift(carry);

                return x;
            }

            function compare( a, b, aL, bL ) {
                var i, cmp;

                if ( aL != bL ) {
                    cmp = aL > bL ? 1 : -1;
                } else {

                    for ( i = cmp = 0; i < aL; i++ ) {

                        if ( a[i] != b[i] ) {
                            cmp = a[i] > b[i] ? 1 : -1;
                            break;
                        }
                    }
                }
                return cmp;
            }

            function subtract( a, b, aL, base ) {
                var i = 0;

                // Subtract b from a.
                for ( ; aL--; ) {
                    a[aL] -= i;
                    i = a[aL] < b[aL] ? 1 : 0;
                    a[aL] = i * base + a[aL] - b[aL];
                }

                // Remove leading zeros.
                for ( ; !a[0] && a.length > 1; a.shift() );
            }

            // x: dividend, y: divisor.
            return function ( x, y, dp, rm, base ) {
                var cmp, e, i, more, n, prod, prodL, q, qc, rem, remL, rem0, xi, xL, yc0,
                    yL, yz,
                    s = x.s == y.s ? 1 : -1,
                    xc = x.c,
                    yc = y.c;

                // Either NaN, Infinity or 0?
                if ( !xc || !xc[0] || !yc || !yc[0] ) {

                    return new BigNumber(

                      // Return NaN if either NaN, or both Infinity or 0.
                      !x.s || !y.s || ( xc ? yc && xc[0] == yc[0] : !yc ) ? NaN :

                        // Return ±0 if x is ±0 or y is ±Infinity, or return ±Infinity as y is ±0.
                        xc && xc[0] == 0 || !yc ? s * 0 : s / 0
                    );
                }

                q = new BigNumber(s);
                qc = q.c = [];
                e = x.e - y.e;
                s = dp + e + 1;

                if ( !base ) {
                    base = BASE;
                    e = bitFloor( x.e / LOG_BASE ) - bitFloor( y.e / LOG_BASE );
                    s = s / LOG_BASE | 0;
                }

                // Result exponent may be one less then the current value of e.
                // The coefficients of the BigNumbers from convertBase may have trailing zeros.
                for ( i = 0; yc[i] == ( xc[i] || 0 ); i++ );
                if ( yc[i] > ( xc[i] || 0 ) ) e--;

                if ( s < 0 ) {
                    qc.push(1);
                    more = true;
                } else {
                    xL = xc.length;
                    yL = yc.length;
                    i = 0;
                    s += 2;

                    // Normalise xc and yc so highest order digit of yc is >= base / 2.

                    n = mathfloor( base / ( yc[0] + 1 ) );

                    // Not necessary, but to handle odd bases where yc[0] == ( base / 2 ) - 1.
                    // if ( n > 1 || n++ == 1 && yc[0] < base / 2 ) {
                    if ( n > 1 ) {
                        yc = multiply( yc, n, base );
                        xc = multiply( xc, n, base );
                        yL = yc.length;
                        xL = xc.length;
                    }

                    xi = yL;
                    rem = xc.slice( 0, yL );
                    remL = rem.length;

                    // Add zeros to make remainder as long as divisor.
                    for ( ; remL < yL; rem[remL++] = 0 );
                    yz = yc.slice();
                    yz.unshift(0);
                    yc0 = yc[0];
                    if ( yc[1] >= base / 2 ) yc0++;
                    // Not necessary, but to prevent trial digit n > base, when using base 3.
                    // else if ( base == 3 && yc0 == 1 ) yc0 = 1 + 1e-15;

                    do {
                        n = 0;

                        // Compare divisor and remainder.
                        cmp = compare( yc, rem, yL, remL );

                        // If divisor < remainder.
                        if ( cmp < 0 ) {

                            // Calculate trial digit, n.

                            rem0 = rem[0];
                            if ( yL != remL ) rem0 = rem0 * base + ( rem[1] || 0 );

                            // n is how many times the divisor goes into the current remainder.
                            n = mathfloor( rem0 / yc0 );

                            //  Algorithm:
                            //  1. product = divisor * trial digit (n)
                            //  2. if product > remainder: product -= divisor, n--
                            //  3. remainder -= product
                            //  4. if product was < remainder at 2:
                            //    5. compare new remainder and divisor
                            //    6. If remainder > divisor: remainder -= divisor, n++

                            if ( n > 1 ) {

                                // n may be > base only when base is 3.
                                if (n >= base) n = base - 1;

                                // product = divisor * trial digit.
                                prod = multiply( yc, n, base );
                                prodL = prod.length;
                                remL = rem.length;

                                // Compare product and remainder.
                                // If product > remainder.
                                // Trial digit n too high.
                                // n is 1 too high about 5% of the time, and is not known to have
                                // ever been more than 1 too high.
                                while ( compare( prod, rem, prodL, remL ) == 1 ) {
                                    n--;

                                    // Subtract divisor from product.
                                    subtract( prod, yL < prodL ? yz : yc, prodL, base );
                                    prodL = prod.length;
                                    cmp = 1;
                                }
                            } else {

                                // n is 0 or 1, cmp is -1.
                                // If n is 0, there is no need to compare yc and rem again below,
                                // so change cmp to 1 to avoid it.
                                // If n is 1, leave cmp as -1, so yc and rem are compared again.
                                if ( n == 0 ) {

                                    // divisor < remainder, so n must be at least 1.
                                    cmp = n = 1;
                                }

                                // product = divisor
                                prod = yc.slice();
                                prodL = prod.length;
                            }

                            if ( prodL < remL ) prod.unshift(0);

                            // Subtract product from remainder.
                            subtract( rem, prod, remL, base );
                            remL = rem.length;

                             // If product was < remainder.
                            if ( cmp == -1 ) {

                                // Compare divisor and new remainder.
                                // If divisor < new remainder, subtract divisor from remainder.
                                // Trial digit n too low.
                                // n is 1 too low about 5% of the time, and very rarely 2 too low.
                                while ( compare( yc, rem, yL, remL ) < 1 ) {
                                    n++;

                                    // Subtract divisor from remainder.
                                    subtract( rem, yL < remL ? yz : yc, remL, base );
                                    remL = rem.length;
                                }
                            }
                        } else if ( cmp === 0 ) {
                            n++;
                            rem = [0];
                        } // else cmp === 1 and n will be 0

                        // Add the next digit, n, to the result array.
                        qc[i++] = n;

                        // Update the remainder.
                        if ( rem[0] ) {
                            rem[remL++] = xc[xi] || 0;
                        } else {
                            rem = [ xc[xi] ];
                            remL = 1;
                        }
                    } while ( ( xi++ < xL || rem[0] != null ) && s-- );

                    more = rem[0] != null;

                    // Leading zero?
                    if ( !qc[0] ) qc.shift();
                }

                if ( base == BASE ) {

                    // To calculate q.e, first get the number of digits of qc[0].
                    for ( i = 1, s = qc[0]; s >= 10; s /= 10, i++ );
                    round( q, dp + ( q.e = i + e * LOG_BASE - 1 ) + 1, rm, more );

                // Caller is convertBase.
                } else {
                    q.e = e;
                    q.r = +more;
                }

                return q;
            };
        })();


        /*
         * Return a string representing the value of BigNumber n in fixed-point or exponential
         * notation rounded to the specified decimal places or significant digits.
         *
         * n is a BigNumber.
         * i is the index of the last digit required (i.e. the digit that may be rounded up).
         * rm is the rounding mode.
         * caller is caller id: toExponential 19, toFixed 20, toFormat 21, toPrecision 24.
         */
        function format( n, i, rm, caller ) {
            var c0, e, ne, len, str;

            rm = rm != null && isValidInt( rm, 0, 8, caller, roundingMode )
              ? rm | 0 : ROUNDING_MODE;

            if ( !n.c ) return n.toString();
            c0 = n.c[0];
            ne = n.e;

            if ( i == null ) {
                str = coeffToString( n.c );
                str = caller == 19 || caller == 24 && ne <= TO_EXP_NEG
                  ? toExponential( str, ne )
                  : toFixedPoint( str, ne );
            } else {
                n = round( new BigNumber(n), i, rm );

                // n.e may have changed if the value was rounded up.
                e = n.e;

                str = coeffToString( n.c );
                len = str.length;

                // toPrecision returns exponential notation if the number of significant digits
                // specified is less than the number of digits necessary to represent the integer
                // part of the value in fixed-point notation.

                // Exponential notation.
                if ( caller == 19 || caller == 24 && ( i <= e || e <= TO_EXP_NEG ) ) {

                    // Append zeros?
                    for ( ; len < i; str += '0', len++ );
                    str = toExponential( str, e );

                // Fixed-point notation.
                } else {
                    i -= ne;
                    str = toFixedPoint( str, e );

                    // Append zeros?
                    if ( e + 1 > len ) {
                        if ( --i > 0 ) for ( str += '.'; i--; str += '0' );
                    } else {
                        i += e - len;
                        if ( i > 0 ) {
                            if ( e + 1 == len ) str += '.';
                            for ( ; i--; str += '0' );
                        }
                    }
                }
            }

            return n.s < 0 && c0 ? '-' + str : str;
        }


        // Handle BigNumber.max and BigNumber.min.
        function maxOrMin( args, method ) {
            var m, n,
                i = 0;

            if ( isArray( args[0] ) ) args = args[0];
            m = new BigNumber( args[0] );

            for ( ; ++i < args.length; ) {
                n = new BigNumber( args[i] );

                // If any number is NaN, return NaN.
                if ( !n.s ) {
                    m = n;
                    break;
                } else if ( method.call( m, n ) ) {
                    m = n;
                }
            }

            return m;
        }


        /*
         * Return true if n is an integer in range, otherwise throw.
         * Use for argument validation when ERRORS is true.
         */
        function intValidatorWithErrors( n, min, max, caller, name ) {
            if ( n < min || n > max || n != truncate(n) ) {
                raise( caller, ( name || 'decimal places' ) +
                  ( n < min || n > max ? ' out of range' : ' not an integer' ), n );
            }

            return true;
        }


        /*
         * Strip trailing zeros, calculate base 10 exponent and check against MIN_EXP and MAX_EXP.
         * Called by minus, plus and times.
         */
        function normalise( n, c, e ) {
            var i = 1,
                j = c.length;

             // Remove trailing zeros.
            for ( ; !c[--j]; c.pop() );

            // Calculate the base 10 exponent. First get the number of digits of c[0].
            for ( j = c[0]; j >= 10; j /= 10, i++ );

            // Overflow?
            if ( ( e = i + e * LOG_BASE - 1 ) > MAX_EXP ) {

                // Infinity.
                n.c = n.e = null;

            // Underflow?
            } else if ( e < MIN_EXP ) {

                // Zero.
                n.c = [ n.e = 0 ];
            } else {
                n.e = e;
                n.c = c;
            }

            return n;
        }


        // Handle values that fail the validity test in BigNumber.
        parseNumeric = (function () {
            var basePrefix = /^(-?)0([xbo])(?=\w[\w.]*$)/i,
                dotAfter = /^([^.]+)\.$/,
                dotBefore = /^\.([^.]+)$/,
                isInfinityOrNaN = /^-?(Infinity|NaN)$/,
                whitespaceOrPlus = /^\s*\+(?=[\w.])|^\s+|\s+$/g;

            return function ( x, str, num, b ) {
                var base,
                    s = num ? str : str.replace( whitespaceOrPlus, '' );

                // No exception on ±Infinity or NaN.
                if ( isInfinityOrNaN.test(s) ) {
                    x.s = isNaN(s) ? null : s < 0 ? -1 : 1;
                } else {
                    if ( !num ) {

                        // basePrefix = /^(-?)0([xbo])(?=\w[\w.]*$)/i
                        s = s.replace( basePrefix, function ( m, p1, p2 ) {
                            base = ( p2 = p2.toLowerCase() ) == 'x' ? 16 : p2 == 'b' ? 2 : 8;
                            return !b || b == base ? p1 : m;
                        });

                        if (b) {
                            base = b;

                            // E.g. '1.' to '1', '.1' to '0.1'
                            s = s.replace( dotAfter, '$1' ).replace( dotBefore, '0.$1' );
                        }

                        if ( str != s ) return new BigNumber( s, base );
                    }

                    // 'new BigNumber() not a number: {n}'
                    // 'new BigNumber() not a base {b} number: {n}'
                    if (ERRORS) raise( id, 'not a' + ( b ? ' base ' + b : '' ) + ' number', str );
                    x.s = null;
                }

                x.c = x.e = null;
                id = 0;
            }
        })();


        // Throw a BigNumber Error.
        function raise( caller, msg, val ) {
            var error = new Error( [
                'new BigNumber',     // 0
                'cmp',               // 1
                'config',            // 2
                'div',               // 3
                'divToInt',          // 4
                'eq',                // 5
                'gt',                // 6
                'gte',               // 7
                'lt',                // 8
                'lte',               // 9
                'minus',             // 10
                'mod',               // 11
                'plus',              // 12
                'precision',         // 13
                'random',            // 14
                'round',             // 15
                'shift',             // 16
                'times',             // 17
                'toDigits',          // 18
                'toExponential',     // 19
                'toFixed',           // 20
                'toFormat',          // 21
                'toFraction',        // 22
                'pow',               // 23
                'toPrecision',       // 24
                'toString',          // 25
                'BigNumber'          // 26
            ][caller] + '() ' + msg + ': ' + val );

            error.name = 'BigNumber Error';
            id = 0;
            throw error;
        }


        /*
         * Round x to sd significant digits using rounding mode rm. Check for over/under-flow.
         * If r is truthy, it is known that there are more digits after the rounding digit.
         */
        function round( x, sd, rm, r ) {
            var d, i, j, k, n, ni, rd,
                xc = x.c,
                pows10 = POWS_TEN;

            // if x is not Infinity or NaN...
            if (xc) {

                // rd is the rounding digit, i.e. the digit after the digit that may be rounded up.
                // n is a base 1e14 number, the value of the element of array x.c containing rd.
                // ni is the index of n within x.c.
                // d is the number of digits of n.
                // i is the index of rd within n including leading zeros.
                // j is the actual index of rd within n (if < 0, rd is a leading zero).
                out: {

                    // Get the number of digits of the first element of xc.
                    for ( d = 1, k = xc[0]; k >= 10; k /= 10, d++ );
                    i = sd - d;

                    // If the rounding digit is in the first element of xc...
                    if ( i < 0 ) {
                        i += LOG_BASE;
                        j = sd;
                        n = xc[ ni = 0 ];

                        // Get the rounding digit at index j of n.
                        rd = n / pows10[ d - j - 1 ] % 10 | 0;
                    } else {
                        ni = mathceil( ( i + 1 ) / LOG_BASE );

                        if ( ni >= xc.length ) {

                            if (r) {

                                // Needed by sqrt.
                                for ( ; xc.length <= ni; xc.push(0) );
                                n = rd = 0;
                                d = 1;
                                i %= LOG_BASE;
                                j = i - LOG_BASE + 1;
                            } else {
                                break out;
                            }
                        } else {
                            n = k = xc[ni];

                            // Get the number of digits of n.
                            for ( d = 1; k >= 10; k /= 10, d++ );

                            // Get the index of rd within n.
                            i %= LOG_BASE;

                            // Get the index of rd within n, adjusted for leading zeros.
                            // The number of leading zeros of n is given by LOG_BASE - d.
                            j = i - LOG_BASE + d;

                            // Get the rounding digit at index j of n.
                            rd = j < 0 ? 0 : n / pows10[ d - j - 1 ] % 10 | 0;
                        }
                    }

                    r = r || sd < 0 ||

                    // Are there any non-zero digits after the rounding digit?
                    // The expression  n % pows10[ d - j - 1 ]  returns all digits of n to the right
                    // of the digit at j, e.g. if n is 908714 and j is 2, the expression gives 714.
                      xc[ni + 1] != null || ( j < 0 ? n : n % pows10[ d - j - 1 ] );

                    r = rm < 4
                      ? ( rd || r ) && ( rm == 0 || rm == ( x.s < 0 ? 3 : 2 ) )
                      : rd > 5 || rd == 5 && ( rm == 4 || r || rm == 6 &&

                        // Check whether the digit to the left of the rounding digit is odd.
                        ( ( i > 0 ? j > 0 ? n / pows10[ d - j ] : 0 : xc[ni - 1] ) % 10 ) & 1 ||
                          rm == ( x.s < 0 ? 8 : 7 ) );

                    if ( sd < 1 || !xc[0] ) {
                        xc.length = 0;

                        if (r) {

                            // Convert sd to decimal places.
                            sd -= x.e + 1;

                            // 1, 0.1, 0.01, 0.001, 0.0001 etc.
                            xc[0] = pows10[ ( LOG_BASE - sd % LOG_BASE ) % LOG_BASE ];
                            x.e = -sd || 0;
                        } else {

                            // Zero.
                            xc[0] = x.e = 0;
                        }

                        return x;
                    }

                    // Remove excess digits.
                    if ( i == 0 ) {
                        xc.length = ni;
                        k = 1;
                        ni--;
                    } else {
                        xc.length = ni + 1;
                        k = pows10[ LOG_BASE - i ];

                        // E.g. 56700 becomes 56000 if 7 is the rounding digit.
                        // j > 0 means i > number of leading zeros of n.
                        xc[ni] = j > 0 ? mathfloor( n / pows10[ d - j ] % pows10[j] ) * k : 0;
                    }

                    // Round up?
                    if (r) {

                        for ( ; ; ) {

                            // If the digit to be rounded up is in the first element of xc...
                            if ( ni == 0 ) {

                                // i will be the length of xc[0] before k is added.
                                for ( i = 1, j = xc[0]; j >= 10; j /= 10, i++ );
                                j = xc[0] += k;
                                for ( k = 1; j >= 10; j /= 10, k++ );

                                // if i != k the length has increased.
                                if ( i != k ) {
                                    x.e++;
                                    if ( xc[0] == BASE ) xc[0] = 1;
                                }

                                break;
                            } else {
                                xc[ni] += k;
                                if ( xc[ni] != BASE ) break;
                                xc[ni--] = 0;
                                k = 1;
                            }
                        }
                    }

                    // Remove trailing zeros.
                    for ( i = xc.length; xc[--i] === 0; xc.pop() );
                }

                // Overflow? Infinity.
                if ( x.e > MAX_EXP ) {
                    x.c = x.e = null;

                // Underflow? Zero.
                } else if ( x.e < MIN_EXP ) {
                    x.c = [ x.e = 0 ];
                }
            }

            return x;
        }


        // PROTOTYPE/INSTANCE METHODS


        /*
         * Return a new BigNumber whose value is the absolute value of this BigNumber.
         */
        P.absoluteValue = P.abs = function () {
            var x = new BigNumber(this);
            if ( x.s < 0 ) x.s = 1;
            return x;
        };


        /*
         * Return a new BigNumber whose value is the value of this BigNumber rounded to a whole
         * number in the direction of Infinity.
         */
        P.ceil = function () {
            return round( new BigNumber(this), this.e + 1, 2 );
        };


        /*
         * Return
         * 1 if the value of this BigNumber is greater than the value of BigNumber(y, b),
         * -1 if the value of this BigNumber is less than the value of BigNumber(y, b),
         * 0 if they have the same value,
         * or null if the value of either is NaN.
         */
        P.comparedTo = P.cmp = function ( y, b ) {
            id = 1;
            return compare( this, new BigNumber( y, b ) );
        };


        /*
         * Return the number of decimal places of the value of this BigNumber, or null if the value
         * of this BigNumber is ±Infinity or NaN.
         */
        P.decimalPlaces = P.dp = function () {
            var n, v,
                c = this.c;

            if ( !c ) return null;
            n = ( ( v = c.length - 1 ) - bitFloor( this.e / LOG_BASE ) ) * LOG_BASE;

            // Subtract the number of trailing zeros of the last number.
            if ( v = c[v] ) for ( ; v % 10 == 0; v /= 10, n-- );
            if ( n < 0 ) n = 0;

            return n;
        };


        /*
         *  n / 0 = I
         *  n / N = N
         *  n / I = 0
         *  0 / n = 0
         *  0 / 0 = N
         *  0 / N = N
         *  0 / I = 0
         *  N / n = N
         *  N / 0 = N
         *  N / N = N
         *  N / I = N
         *  I / n = I
         *  I / 0 = I
         *  I / N = N
         *  I / I = N
         *
         * Return a new BigNumber whose value is the value of this BigNumber divided by the value of
         * BigNumber(y, b), rounded according to DECIMAL_PLACES and ROUNDING_MODE.
         */
        P.dividedBy = P.div = function ( y, b ) {
            id = 3;
            return div( this, new BigNumber( y, b ), DECIMAL_PLACES, ROUNDING_MODE );
        };


        /*
         * Return a new BigNumber whose value is the integer part of dividing the value of this
         * BigNumber by the value of BigNumber(y, b).
         */
        P.dividedToIntegerBy = P.divToInt = function ( y, b ) {
            id = 4;
            return div( this, new BigNumber( y, b ), 0, 1 );
        };


        /*
         * Return true if the value of this BigNumber is equal to the value of BigNumber(y, b),
         * otherwise returns false.
         */
        P.equals = P.eq = function ( y, b ) {
            id = 5;
            return compare( this, new BigNumber( y, b ) ) === 0;
        };


        /*
         * Return a new BigNumber whose value is the value of this BigNumber rounded to a whole
         * number in the direction of -Infinity.
         */
        P.floor = function () {
            return round( new BigNumber(this), this.e + 1, 3 );
        };


        /*
         * Return true if the value of this BigNumber is greater than the value of BigNumber(y, b),
         * otherwise returns false.
         */
        P.greaterThan = P.gt = function ( y, b ) {
            id = 6;
            return compare( this, new BigNumber( y, b ) ) > 0;
        };


        /*
         * Return true if the value of this BigNumber is greater than or equal to the value of
         * BigNumber(y, b), otherwise returns false.
         */
        P.greaterThanOrEqualTo = P.gte = function ( y, b ) {
            id = 7;
            return ( b = compare( this, new BigNumber( y, b ) ) ) === 1 || b === 0;

        };


        /*
         * Return true if the value of this BigNumber is a finite number, otherwise returns false.
         */
        P.isFinite = function () {
            return !!this.c;
        };


        /*
         * Return true if the value of this BigNumber is an integer, otherwise return false.
         */
        P.isInteger = P.isInt = function () {
            return !!this.c && bitFloor( this.e / LOG_BASE ) > this.c.length - 2;
        };


        /*
         * Return true if the value of this BigNumber is NaN, otherwise returns false.
         */
        P.isNaN = function () {
            return !this.s;
        };


        /*
         * Return true if the value of this BigNumber is negative, otherwise returns false.
         */
        P.isNegative = P.isNeg = function () {
            return this.s < 0;
        };


        /*
         * Return true if the value of this BigNumber is 0 or -0, otherwise returns false.
         */
        P.isZero = function () {
            return !!this.c && this.c[0] == 0;
        };


        /*
         * Return true if the value of this BigNumber is less than the value of BigNumber(y, b),
         * otherwise returns false.
         */
        P.lessThan = P.lt = function ( y, b ) {
            id = 8;
            return compare( this, new BigNumber( y, b ) ) < 0;
        };


        /*
         * Return true if the value of this BigNumber is less than or equal to the value of
         * BigNumber(y, b), otherwise returns false.
         */
        P.lessThanOrEqualTo = P.lte = function ( y, b ) {
            id = 9;
            return ( b = compare( this, new BigNumber( y, b ) ) ) === -1 || b === 0;
        };


        /*
         *  n - 0 = n
         *  n - N = N
         *  n - I = -I
         *  0 - n = -n
         *  0 - 0 = 0
         *  0 - N = N
         *  0 - I = -I
         *  N - n = N
         *  N - 0 = N
         *  N - N = N
         *  N - I = N
         *  I - n = I
         *  I - 0 = I
         *  I - N = N
         *  I - I = N
         *
         * Return a new BigNumber whose value is the value of this BigNumber minus the value of
         * BigNumber(y, b).
         */
        P.minus = P.sub = function ( y, b ) {
            var i, j, t, xLTy,
                x = this,
                a = x.s;

            id = 10;
            y = new BigNumber( y, b );
            b = y.s;

            // Either NaN?
            if ( !a || !b ) return new BigNumber(NaN);

            // Signs differ?
            if ( a != b ) {
                y.s = -b;
                return x.plus(y);
            }

            var xe = x.e / LOG_BASE,
                ye = y.e / LOG_BASE,
                xc = x.c,
                yc = y.c;

            if ( !xe || !ye ) {

                // Either Infinity?
                if ( !xc || !yc ) return xc ? ( y.s = -b, y ) : new BigNumber( yc ? x : NaN );

                // Either zero?
                if ( !xc[0] || !yc[0] ) {

                    // Return y if y is non-zero, x if x is non-zero, or zero if both are zero.
                    return yc[0] ? ( y.s = -b, y ) : new BigNumber( xc[0] ? x :

                      // IEEE 754 (2008) 6.3: n - n = -0 when rounding to -Infinity
                      ROUNDING_MODE == 3 ? -0 : 0 );
                }
            }

            xe = bitFloor(xe);
            ye = bitFloor(ye);
            xc = xc.slice();

            // Determine which is the bigger number.
            if ( a = xe - ye ) {

                if ( xLTy = a < 0 ) {
                    a = -a;
                    t = xc;
                } else {
                    ye = xe;
                    t = yc;
                }

                t.reverse();

                // Prepend zeros to equalise exponents.
                for ( b = a; b--; t.push(0) );
                t.reverse();
            } else {

                // Exponents equal. Check digit by digit.
                j = ( xLTy = ( a = xc.length ) < ( b = yc.length ) ) ? a : b;

                for ( a = b = 0; b < j; b++ ) {

                    if ( xc[b] != yc[b] ) {
                        xLTy = xc[b] < yc[b];
                        break;
                    }
                }
            }

            // x < y? Point xc to the array of the bigger number.
            if (xLTy) t = xc, xc = yc, yc = t, y.s = -y.s;

            b = ( j = yc.length ) - ( i = xc.length );

            // Append zeros to xc if shorter.
            // No need to add zeros to yc if shorter as subtract only needs to start at yc.length.
            if ( b > 0 ) for ( ; b--; xc[i++] = 0 );
            b = BASE - 1;

            // Subtract yc from xc.
            for ( ; j > a; ) {

                if ( xc[--j] < yc[j] ) {
                    for ( i = j; i && !xc[--i]; xc[i] = b );
                    --xc[i];
                    xc[j] += BASE;
                }

                xc[j] -= yc[j];
            }

            // Remove leading zeros and adjust exponent accordingly.
            for ( ; xc[0] == 0; xc.shift(), --ye );

            // Zero?
            if ( !xc[0] ) {

                // Following IEEE 754 (2008) 6.3,
                // n - n = +0  but  n - n = -0  when rounding towards -Infinity.
                y.s = ROUNDING_MODE == 3 ? -1 : 1;
                y.c = [ y.e = 0 ];
                return y;
            }

            // No need to check for Infinity as +x - +y != Infinity && -x - -y != Infinity
            // for finite x and y.
            return normalise( y, xc, ye );
        };


        /*
         *   n % 0 =  N
         *   n % N =  N
         *   n % I =  n
         *   0 % n =  0
         *  -0 % n = -0
         *   0 % 0 =  N
         *   0 % N =  N
         *   0 % I =  0
         *   N % n =  N
         *   N % 0 =  N
         *   N % N =  N
         *   N % I =  N
         *   I % n =  N
         *   I % 0 =  N
         *   I % N =  N
         *   I % I =  N
         *
         * Return a new BigNumber whose value is the value of this BigNumber modulo the value of
         * BigNumber(y, b). The result depends on the value of MODULO_MODE.
         */
        P.modulo = P.mod = function ( y, b ) {
            var q, s,
                x = this;

            id = 11;
            y = new BigNumber( y, b );

            // Return NaN if x is Infinity or NaN, or y is NaN or zero.
            if ( !x.c || !y.s || y.c && !y.c[0] ) {
                return new BigNumber(NaN);

            // Return x if y is Infinity or x is zero.
            } else if ( !y.c || x.c && !x.c[0] ) {
                return new BigNumber(x);
            }

            if ( MODULO_MODE == 9 ) {

                // Euclidian division: q = sign(y) * floor(x / abs(y))
                // r = x - qy    where  0 <= r < abs(y)
                s = y.s;
                y.s = 1;
                q = div( x, y, 0, 3 );
                y.s = s;
                q.s *= s;
            } else {
                q = div( x, y, 0, MODULO_MODE );
            }

            return x.minus( q.times(y) );
        };


        /*
         * Return a new BigNumber whose value is the value of this BigNumber negated,
         * i.e. multiplied by -1.
         */
        P.negated = P.neg = function () {
            var x = new BigNumber(this);
            x.s = -x.s || null;
            return x;
        };


        /*
         *  n + 0 = n
         *  n + N = N
         *  n + I = I
         *  0 + n = n
         *  0 + 0 = 0
         *  0 + N = N
         *  0 + I = I
         *  N + n = N
         *  N + 0 = N
         *  N + N = N
         *  N + I = N
         *  I + n = I
         *  I + 0 = I
         *  I + N = N
         *  I + I = I
         *
         * Return a new BigNumber whose value is the value of this BigNumber plus the value of
         * BigNumber(y, b).
         */
        P.plus = P.add = function ( y, b ) {
            var t,
                x = this,
                a = x.s;

            id = 12;
            y = new BigNumber( y, b );
            b = y.s;

            // Either NaN?
            if ( !a || !b ) return new BigNumber(NaN);

            // Signs differ?
             if ( a != b ) {
                y.s = -b;
                return x.minus(y);
            }

            var xe = x.e / LOG_BASE,
                ye = y.e / LOG_BASE,
                xc = x.c,
                yc = y.c;

            if ( !xe || !ye ) {

                // Return ±Infinity if either ±Infinity.
                if ( !xc || !yc ) return new BigNumber( a / 0 );

                // Either zero?
                // Return y if y is non-zero, x if x is non-zero, or zero if both are zero.
                if ( !xc[0] || !yc[0] ) return yc[0] ? y : new BigNumber( xc[0] ? x : a * 0 );
            }

            xe = bitFloor(xe);
            ye = bitFloor(ye);
            xc = xc.slice();

            // Prepend zeros to equalise exponents. Faster to use reverse then do unshifts.
            if ( a = xe - ye ) {
                if ( a > 0 ) {
                    ye = xe;
                    t = yc;
                } else {
                    a = -a;
                    t = xc;
                }

                t.reverse();
                for ( ; a--; t.push(0) );
                t.reverse();
            }

            a = xc.length;
            b = yc.length;

            // Point xc to the longer array, and b to the shorter length.
            if ( a - b < 0 ) t = yc, yc = xc, xc = t, b = a;

            // Only start adding at yc.length - 1 as the further digits of xc can be ignored.
            for ( a = 0; b; ) {
                a = ( xc[--b] = xc[b] + yc[b] + a ) / BASE | 0;
                xc[b] %= BASE;
            }

            if (a) {
                xc.unshift(a);
                ++ye;
            }

            // No need to check for zero, as +x + +y != 0 && -x + -y != 0
            // ye = MAX_EXP + 1 possible
            return normalise( y, xc, ye );
        };


        /*
         * Return the number of significant digits of the value of this BigNumber.
         *
         * [z] {boolean|number} Whether to count integer-part trailing zeros: true, false, 1 or 0.
         */
        P.precision = P.sd = function (z) {
            var n, v,
                x = this,
                c = x.c;

            // 'precision() argument not a boolean or binary digit: {z}'
            if ( z != null && z !== !!z && z !== 1 && z !== 0 ) {
                if (ERRORS) raise( 13, 'argument' + notBool, z );
                if ( z != !!z ) z = null;
            }

            if ( !c ) return null;
            v = c.length - 1;
            n = v * LOG_BASE + 1;

            if ( v = c[v] ) {

                // Subtract the number of trailing zeros of the last element.
                for ( ; v % 10 == 0; v /= 10, n-- );

                // Add the number of digits of the first element.
                for ( v = c[0]; v >= 10; v /= 10, n++ );
            }

            if ( z && x.e + 1 > n ) n = x.e + 1;

            return n;
        };


        /*
         * Return a new BigNumber whose value is the value of this BigNumber rounded to a maximum of
         * dp decimal places using rounding mode rm, or to 0 and ROUNDING_MODE respectively if
         * omitted.
         *
         * [dp] {number} Decimal places. Integer, 0 to MAX inclusive.
         * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive.
         *
         * 'round() decimal places out of range: {dp}'
         * 'round() decimal places not an integer: {dp}'
         * 'round() rounding mode not an integer: {rm}'
         * 'round() rounding mode out of range: {rm}'
         */
        P.round = function ( dp, rm ) {
            var n = new BigNumber(this);

            if ( dp == null || isValidInt( dp, 0, MAX, 15 ) ) {
                round( n, ~~dp + this.e + 1, rm == null ||
                  !isValidInt( rm, 0, 8, 15, roundingMode ) ? ROUNDING_MODE : rm | 0 );
            }

            return n;
        };


        /*
         * Return a new BigNumber whose value is the value of this BigNumber shifted by k places
         * (powers of 10). Shift to the right if n > 0, and to the left if n < 0.
         *
         * k {number} Integer, -MAX_SAFE_INTEGER to MAX_SAFE_INTEGER inclusive.
         *
         * If k is out of range and ERRORS is false, the result will be ±0 if k < 0, or ±Infinity
         * otherwise.
         *
         * 'shift() argument not an integer: {k}'
         * 'shift() argument out of range: {k}'
         */
        P.shift = function (k) {
            var n = this;
            return isValidInt( k, -MAX_SAFE_INTEGER, MAX_SAFE_INTEGER, 16, 'argument' )

              // k < 1e+21, or truncate(k) will produce exponential notation.
              ? n.times( '1e' + truncate(k) )
              : new BigNumber( n.c && n.c[0] && ( k < -MAX_SAFE_INTEGER || k > MAX_SAFE_INTEGER )
                ? n.s * ( k < 0 ? 0 : 1 / 0 )
                : n );
        };


        /*
         *  sqrt(-n) =  N
         *  sqrt( N) =  N
         *  sqrt(-I) =  N
         *  sqrt( I) =  I
         *  sqrt( 0) =  0
         *  sqrt(-0) = -0
         *
         * Return a new BigNumber whose value is the square root of the value of this BigNumber,
         * rounded according to DECIMAL_PLACES and ROUNDING_MODE.
         */
        P.squareRoot = P.sqrt = function () {
            var m, n, r, rep, t,
                x = this,
                c = x.c,
                s = x.s,
                e = x.e,
                dp = DECIMAL_PLACES + 4,
                half = new BigNumber('0.5');

            // Negative/NaN/Infinity/zero?
            if ( s !== 1 || !c || !c[0] ) {
                return new BigNumber( !s || s < 0 && ( !c || c[0] ) ? NaN : c ? x : 1 / 0 );
            }

            // Initial estimate.
            s = Math.sqrt( +x );

            // Math.sqrt underflow/overflow?
            // Pass x to Math.sqrt as integer, then adjust the exponent of the result.
            if ( s == 0 || s == 1 / 0 ) {
                n = coeffToString(c);
                if ( ( n.length + e ) % 2 == 0 ) n += '0';
                s = Math.sqrt(n);
                e = bitFloor( ( e + 1 ) / 2 ) - ( e < 0 || e % 2 );

                if ( s == 1 / 0 ) {
                    n = '1e' + e;
                } else {
                    n = s.toExponential();
                    n = n.slice( 0, n.indexOf('e') + 1 ) + e;
                }

                r = new BigNumber(n);
            } else {
                r = new BigNumber( s + '' );
            }

            // Check for zero.
            // r could be zero if MIN_EXP is changed after the this value was created.
            // This would cause a division by zero (x/t) and hence Infinity below, which would cause
            // coeffToString to throw.
            if ( r.c[0] ) {
                e = r.e;
                s = e + dp;
                if ( s < 3 ) s = 0;

                // Newton-Raphson iteration.
                for ( ; ; ) {
                    t = r;
                    r = half.times( t.plus( div( x, t, dp, 1 ) ) );

                    if ( coeffToString( t.c   ).slice( 0, s ) === ( n =
                         coeffToString( r.c ) ).slice( 0, s ) ) {

                        // The exponent of r may here be one less than the final result exponent,
                        // e.g 0.0009999 (e-4) --> 0.001 (e-3), so adjust s so the rounding digits
                        // are indexed correctly.
                        if ( r.e < e ) --s;
                        n = n.slice( s - 3, s + 1 );

                        // The 4th rounding digit may be in error by -1 so if the 4 rounding digits
                        // are 9999 or 4999 (i.e. approaching a rounding boundary) continue the
                        // iteration.
                        if ( n == '9999' || !rep && n == '4999' ) {

                            // On the first iteration only, check to see if rounding up gives the
                            // exact result as the nines may infinitely repeat.
                            if ( !rep ) {
                                round( t, t.e + DECIMAL_PLACES + 2, 0 );

                                if ( t.times(t).eq(x) ) {
                                    r = t;
                                    break;
                                }
                            }

                            dp += 4;
                            s += 4;
                            rep = 1;
                        } else {

                            // If rounding digits are null, 0{0,4} or 50{0,3}, check for exact
                            // result. If not, then there are further digits and m will be truthy.
                            if ( !+n || !+n.slice(1) && n.charAt(0) == '5' ) {

                                // Truncate to the first rounding digit.
                                round( r, r.e + DECIMAL_PLACES + 2, 1 );
                                m = !r.times(r).eq(x);
                            }

                            break;
                        }
                    }
                }
            }

            return round( r, r.e + DECIMAL_PLACES + 1, ROUNDING_MODE, m );
        };


        /*
         *  n * 0 = 0
         *  n * N = N
         *  n * I = I
         *  0 * n = 0
         *  0 * 0 = 0
         *  0 * N = N
         *  0 * I = N
         *  N * n = N
         *  N * 0 = N
         *  N * N = N
         *  N * I = N
         *  I * n = I
         *  I * 0 = N
         *  I * N = N
         *  I * I = I
         *
         * Return a new BigNumber whose value is the value of this BigNumber times the value of
         * BigNumber(y, b).
         */
        P.times = P.mul = function ( y, b ) {
            var c, e, i, j, k, m, xcL, xlo, xhi, ycL, ylo, yhi, zc,
                base, sqrtBase,
                x = this,
                xc = x.c,
                yc = ( id = 17, y = new BigNumber( y, b ) ).c;

            // Either NaN, ±Infinity or ±0?
            if ( !xc || !yc || !xc[0] || !yc[0] ) {

                // Return NaN if either is NaN, or one is 0 and the other is Infinity.
                if ( !x.s || !y.s || xc && !xc[0] && !yc || yc && !yc[0] && !xc ) {
                    y.c = y.e = y.s = null;
                } else {
                    y.s *= x.s;

                    // Return ±Infinity if either is ±Infinity.
                    if ( !xc || !yc ) {
                        y.c = y.e = null;

                    // Return ±0 if either is ±0.
                    } else {
                        y.c = [0];
                        y.e = 0;
                    }
                }

                return y;
            }

            e = bitFloor( x.e / LOG_BASE ) + bitFloor( y.e / LOG_BASE );
            y.s *= x.s;
            xcL = xc.length;
            ycL = yc.length;

            // Ensure xc points to longer array and xcL to its length.
            if ( xcL < ycL ) zc = xc, xc = yc, yc = zc, i = xcL, xcL = ycL, ycL = i;

            // Initialise the result array with zeros.
            for ( i = xcL + ycL, zc = []; i--; zc.push(0) );

            base = BASE;
            sqrtBase = SQRT_BASE;

            for ( i = ycL; --i >= 0; ) {
                c = 0;
                ylo = yc[i] % sqrtBase;
                yhi = yc[i] / sqrtBase | 0;

                for ( k = xcL, j = i + k; j > i; ) {
                    xlo = xc[--k] % sqrtBase;
                    xhi = xc[k] / sqrtBase | 0;
                    m = yhi * xlo + xhi * ylo;
                    xlo = ylo * xlo + ( ( m % sqrtBase ) * sqrtBase ) + zc[j] + c;
                    c = ( xlo / base | 0 ) + ( m / sqrtBase | 0 ) + yhi * xhi;
                    zc[j--] = xlo % base;
                }

                zc[j] = c;
            }

            if (c) {
                ++e;
            } else {
                zc.shift();
            }

            return normalise( y, zc, e );
        };


        /*
         * Return a new BigNumber whose value is the value of this BigNumber rounded to a maximum of
         * sd significant digits using rounding mode rm, or ROUNDING_MODE if rm is omitted.
         *
         * [sd] {number} Significant digits. Integer, 1 to MAX inclusive.
         * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive.
         *
         * 'toDigits() precision out of range: {sd}'
         * 'toDigits() precision not an integer: {sd}'
         * 'toDigits() rounding mode not an integer: {rm}'
         * 'toDigits() rounding mode out of range: {rm}'
         */
        P.toDigits = function ( sd, rm ) {
            var n = new BigNumber(this);
            sd = sd == null || !isValidInt( sd, 1, MAX, 18, 'precision' ) ? null : sd | 0;
            rm = rm == null || !isValidInt( rm, 0, 8, 18, roundingMode ) ? ROUNDING_MODE : rm | 0;
            return sd ? round( n, sd, rm ) : n;
        };


        /*
         * Return a string representing the value of this BigNumber in exponential notation and
         * rounded using ROUNDING_MODE to dp fixed decimal places.
         *
         * [dp] {number} Decimal places. Integer, 0 to MAX inclusive.
         * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive.
         *
         * 'toExponential() decimal places not an integer: {dp}'
         * 'toExponential() decimal places out of range: {dp}'
         * 'toExponential() rounding mode not an integer: {rm}'
         * 'toExponential() rounding mode out of range: {rm}'
         */
        P.toExponential = function ( dp, rm ) {
            return format( this,
              dp != null && isValidInt( dp, 0, MAX, 19 ) ? ~~dp + 1 : null, rm, 19 );
        };


        /*
         * Return a string representing the value of this BigNumber in fixed-point notation rounding
         * to dp fixed decimal places using rounding mode rm, or ROUNDING_MODE if rm is omitted.
         *
         * Note: as with JavaScript's number type, (-0).toFixed(0) is '0',
         * but e.g. (-0.00001).toFixed(0) is '-0'.
         *
         * [dp] {number} Decimal places. Integer, 0 to MAX inclusive.
         * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive.
         *
         * 'toFixed() decimal places not an integer: {dp}'
         * 'toFixed() decimal places out of range: {dp}'
         * 'toFixed() rounding mode not an integer: {rm}'
         * 'toFixed() rounding mode out of range: {rm}'
         */
        P.toFixed = function ( dp, rm ) {
            return format( this, dp != null && isValidInt( dp, 0, MAX, 20 )
              ? ~~dp + this.e + 1 : null, rm, 20 );
        };


        /*
         * Return a string representing the value of this BigNumber in fixed-point notation rounded
         * using rm or ROUNDING_MODE to dp decimal places, and formatted according to the properties
         * of the FORMAT object (see BigNumber.config).
         *
         * FORMAT = {
         *      decimalSeparator : '.',
         *      groupSeparator : ',',
         *      groupSize : 3,
         *      secondaryGroupSize : 0,
         *      fractionGroupSeparator : '\xA0',    // non-breaking space
         *      fractionGroupSize : 0
         * };
         *
         * [dp] {number} Decimal places. Integer, 0 to MAX inclusive.
         * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive.
         *
         * 'toFormat() decimal places not an integer: {dp}'
         * 'toFormat() decimal places out of range: {dp}'
         * 'toFormat() rounding mode not an integer: {rm}'
         * 'toFormat() rounding mode out of range: {rm}'
         */
        P.toFormat = function ( dp, rm ) {
            var str = format( this, dp != null && isValidInt( dp, 0, MAX, 21 )
              ? ~~dp + this.e + 1 : null, rm, 21 );

            if ( this.c ) {
                var i,
                    arr = str.split('.'),
                    g1 = +FORMAT.groupSize,
                    g2 = +FORMAT.secondaryGroupSize,
                    groupSeparator = FORMAT.groupSeparator,
                    intPart = arr[0],
                    fractionPart = arr[1],
                    isNeg = this.s < 0,
                    intDigits = isNeg ? intPart.slice(1) : intPart,
                    len = intDigits.length;

                if (g2) i = g1, g1 = g2, g2 = i, len -= i;

                if ( g1 > 0 && len > 0 ) {
                    i = len % g1 || g1;
                    intPart = intDigits.substr( 0, i );

                    for ( ; i < len; i += g1 ) {
                        intPart += groupSeparator + intDigits.substr( i, g1 );
                    }

                    if ( g2 > 0 ) intPart += groupSeparator + intDigits.slice(i);
                    if (isNeg) intPart = '-' + intPart;
                }

                str = fractionPart
                  ? intPart + FORMAT.decimalSeparator + ( ( g2 = +FORMAT.fractionGroupSize )
                    ? fractionPart.replace( new RegExp( '\\d{' + g2 + '}\\B', 'g' ),
                      '$&' + FORMAT.fractionGroupSeparator )
                    : fractionPart )
                  : intPart;
            }

            return str;
        };


        /*
         * Return a string array representing the value of this BigNumber as a simple fraction with
         * an integer numerator and an integer denominator. The denominator will be a positive
         * non-zero value less than or equal to the specified maximum denominator. If a maximum
         * denominator is not specified, the denominator will be the lowest value necessary to
         * represent the number exactly.
         *
         * [md] {number|string|BigNumber} Integer >= 1 and < Infinity. The maximum denominator.
         *
         * 'toFraction() max denominator not an integer: {md}'
         * 'toFraction() max denominator out of range: {md}'
         */
        P.toFraction = function (md) {
            var arr, d0, d2, e, exp, n, n0, q, s,
                k = ERRORS,
                x = this,
                xc = x.c,
                d = new BigNumber(ONE),
                n1 = d0 = new BigNumber(ONE),
                d1 = n0 = new BigNumber(ONE);

            if ( md != null ) {
                ERRORS = false;
                n = new BigNumber(md);
                ERRORS = k;

                if ( !( k = n.isInt() ) || n.lt(ONE) ) {

                    if (ERRORS) {
                        raise( 22,
                          'max denominator ' + ( k ? 'out of range' : 'not an integer' ), md );
                    }

                    // ERRORS is false:
                    // If md is a finite non-integer >= 1, round it to an integer and use it.
                    md = !k && n.c && round( n, n.e + 1, 1 ).gte(ONE) ? n : null;
                }
            }

            if ( !xc ) return x.toString();
            s = coeffToString(xc);

            // Determine initial denominator.
            // d is a power of 10 and the minimum max denominator that specifies the value exactly.
            e = d.e = s.length - x.e - 1;
            d.c[0] = POWS_TEN[ ( exp = e % LOG_BASE ) < 0 ? LOG_BASE + exp : exp ];
            md = !md || n.cmp(d) > 0 ? ( e > 0 ? d : n1 ) : n;

            exp = MAX_EXP;
            MAX_EXP = 1 / 0;
            n = new BigNumber(s);

            // n0 = d1 = 0
            n0.c[0] = 0;

            for ( ; ; )  {
                q = div( n, d, 0, 1 );
                d2 = d0.plus( q.times(d1) );
                if ( d2.cmp(md) == 1 ) break;
                d0 = d1;
                d1 = d2;
                n1 = n0.plus( q.times( d2 = n1 ) );
                n0 = d2;
                d = n.minus( q.times( d2 = d ) );
                n = d2;
            }

            d2 = div( md.minus(d0), d1, 0, 1 );
            n0 = n0.plus( d2.times(n1) );
            d0 = d0.plus( d2.times(d1) );
            n0.s = n1.s = x.s;
            e *= 2;

            // Determine which fraction is closer to x, n0/d0 or n1/d1
            arr = div( n1, d1, e, ROUNDING_MODE ).minus(x).abs().cmp(
                  div( n0, d0, e, ROUNDING_MODE ).minus(x).abs() ) < 1
                    ? [ n1.toString(), d1.toString() ]
                    : [ n0.toString(), d0.toString() ];

            MAX_EXP = exp;
            return arr;
        };


        /*
         * Return the value of this BigNumber converted to a number primitive.
         */
        P.toNumber = function () {
            return +this;
        };


        /*
         * Return a BigNumber whose value is the value of this BigNumber raised to the power n.
         * If m is present, return the result modulo m.
         * If n is negative round according to DECIMAL_PLACES and ROUNDING_MODE.
         * If POW_PRECISION is non-zero and m is not present, round to POW_PRECISION using
         * ROUNDING_MODE.
         *
         * The modular power operation works efficiently when x, n, and m are positive integers,
         * otherwise it is equivalent to calculating x.toPower(n).modulo(m) (with POW_PRECISION 0).
         *
         * n {number} Integer, -MAX_SAFE_INTEGER to MAX_SAFE_INTEGER inclusive.
         * [m] {number|string|BigNumber} The modulus.
         *
         * 'pow() exponent not an integer: {n}'
         * 'pow() exponent out of range: {n}'
         *
         * Performs 54 loop iterations for n of 9007199254740991.
         */
        P.toPower = P.pow = function ( n, m ) {
            var k, y, z,
                i = mathfloor( n < 0 ? -n : +n ),
                x = this;

            if ( m != null ) {
                id = 23;
                m = new BigNumber(m);
            }

            // Pass ±Infinity to Math.pow if exponent is out of range.
            if ( !isValidInt( n, -MAX_SAFE_INTEGER, MAX_SAFE_INTEGER, 23, 'exponent' ) &&
              ( !isFinite(n) || i > MAX_SAFE_INTEGER && ( n /= 0 ) ||
                parseFloat(n) != n && !( n = NaN ) ) || n == 0 ) {
                k = Math.pow( +x, n );
                return new BigNumber( m ? k % m : k );
            }

            if (m) {
                if ( n > 1 && x.gt(ONE) && x.isInt() && m.gt(ONE) && m.isInt() ) {
                    x = x.mod(m);
                } else {
                    z = m;

                    // Nullify m so only a single mod operation is performed at the end.
                    m = null;
                }
            } else if (POW_PRECISION) {

                // Truncating each coefficient array to a length of k after each multiplication
                // equates to truncating significant digits to POW_PRECISION + [28, 41],
                // i.e. there will be a minimum of 28 guard digits retained.
                // (Using + 1.5 would give [9, 21] guard digits.)
                k = mathceil( POW_PRECISION / LOG_BASE + 2 );
            }

            y = new BigNumber(ONE);

            for ( ; ; ) {
                if ( i % 2 ) {
                    y = y.times(x);
                    if ( !y.c ) break;
                    if (k) {
                        if ( y.c.length > k ) y.c.length = k;
                    } else if (m) {
                        y = y.mod(m);
                    }
                }

                i = mathfloor( i / 2 );
                if ( !i ) break;
                x = x.times(x);
                if (k) {
                    if ( x.c && x.c.length > k ) x.c.length = k;
                } else if (m) {
                    x = x.mod(m);
                }
            }

            if (m) return y;
            if ( n < 0 ) y = ONE.div(y);

            return z ? y.mod(z) : k ? round( y, POW_PRECISION, ROUNDING_MODE ) : y;
        };


        /*
         * Return a string representing the value of this BigNumber rounded to sd significant digits
         * using rounding mode rm or ROUNDING_MODE. If sd is less than the number of digits
         * necessary to represent the integer part of the value in fixed-point notation, then use
         * exponential notation.
         *
         * [sd] {number} Significant digits. Integer, 1 to MAX inclusive.
         * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive.
         *
         * 'toPrecision() precision not an integer: {sd}'
         * 'toPrecision() precision out of range: {sd}'
         * 'toPrecision() rounding mode not an integer: {rm}'
         * 'toPrecision() rounding mode out of range: {rm}'
         */
        P.toPrecision = function ( sd, rm ) {
            return format( this, sd != null && isValidInt( sd, 1, MAX, 24, 'precision' )
              ? sd | 0 : null, rm, 24 );
        };


        /*
         * Return a string representing the value of this BigNumber in base b, or base 10 if b is
         * omitted. If a base is specified, including base 10, round according to DECIMAL_PLACES and
         * ROUNDING_MODE. If a base is not specified, and this BigNumber has a positive exponent
         * that is equal to or greater than TO_EXP_POS, or a negative exponent equal to or less than
         * TO_EXP_NEG, return exponential notation.
         *
         * [b] {number} Integer, 2 to 64 inclusive.
         *
         * 'toString() base not an integer: {b}'
         * 'toString() base out of range: {b}'
         */
        P.toString = function (b) {
            var str,
                n = this,
                s = n.s,
                e = n.e;

            // Infinity or NaN?
            if ( e === null ) {

                if (s) {
                    str = 'Infinity';
                    if ( s < 0 ) str = '-' + str;
                } else {
                    str = 'NaN';
                }
            } else {
                str = coeffToString( n.c );

                if ( b == null || !isValidInt( b, 2, 64, 25, 'base' ) ) {
                    str = e <= TO_EXP_NEG || e >= TO_EXP_POS
                      ? toExponential( str, e )
                      : toFixedPoint( str, e );
                } else {
                    str = convertBase( toFixedPoint( str, e ), b | 0, 10, s );
                }

                if ( s < 0 && n.c[0] ) str = '-' + str;
            }

            return str;
        };


        /*
         * Return a new BigNumber whose value is the value of this BigNumber truncated to a whole
         * number.
         */
        P.truncated = P.trunc = function () {
            return round( new BigNumber(this), this.e + 1, 1 );
        };



        /*
         * Return as toString, but do not accept a base argument, and include the minus sign for
         * negative zero.
         */
        P.valueOf = P.toJSON = function () {
            var str,
                n = this,
                e = n.e;

            if ( e === null ) return n.toString();

            str = coeffToString( n.c );

            str = e <= TO_EXP_NEG || e >= TO_EXP_POS
                ? toExponential( str, e )
                : toFixedPoint( str, e );

            return n.s < 0 ? '-' + str : str;
        };


        // Aliases for BigDecimal methods.
        //P.add = P.plus;         // P.add included above
        //P.subtract = P.minus;   // P.sub included above
        //P.multiply = P.times;   // P.mul included above
        //P.divide = P.div;
        //P.remainder = P.mod;
        //P.compareTo = P.cmp;
        //P.negate = P.neg;


        if ( configObj != null ) BigNumber.config(configObj);

        return BigNumber;
    }


    // PRIVATE HELPER FUNCTIONS


    function bitFloor(n) {
        var i = n | 0;
        return n > 0 || n === i ? i : i - 1;
    }


    // Return a coefficient array as a string of base 10 digits.
    function coeffToString(a) {
        var s, z,
            i = 1,
            j = a.length,
            r = a[0] + '';

        for ( ; i < j; ) {
            s = a[i++] + '';
            z = LOG_BASE - s.length;
            for ( ; z--; s = '0' + s );
            r += s;
        }

        // Determine trailing zeros.
        for ( j = r.length; r.charCodeAt(--j) === 48; );
        return r.slice( 0, j + 1 || 1 );
    }


    // Compare the value of BigNumbers x and y.
    function compare( x, y ) {
        var a, b,
            xc = x.c,
            yc = y.c,
            i = x.s,
            j = y.s,
            k = x.e,
            l = y.e;

        // Either NaN?
        if ( !i || !j ) return null;

        a = xc && !xc[0];
        b = yc && !yc[0];

        // Either zero?
        if ( a || b ) return a ? b ? 0 : -j : i;

        // Signs differ?
        if ( i != j ) return i;

        a = i < 0;
        b = k == l;

        // Either Infinity?
        if ( !xc || !yc ) return b ? 0 : !xc ^ a ? 1 : -1;

        // Compare exponents.
        if ( !b ) return k > l ^ a ? 1 : -1;

        j = ( k = xc.length ) < ( l = yc.length ) ? k : l;

        // Compare digit by digit.
        for ( i = 0; i < j; i++ ) if ( xc[i] != yc[i] ) return xc[i] > yc[i] ^ a ? 1 : -1;

        // Compare lengths.
        return k == l ? 0 : k > l ^ a ? 1 : -1;
    }


    /*
     * Return true if n is a valid number in range, otherwise false.
     * Use for argument validation when ERRORS is false.
     * Note: parseInt('1e+1') == 1 but parseFloat('1e+1') == 10.
     */
    function intValidatorNoErrors( n, min, max ) {
        return ( n = truncate(n) ) >= min && n <= max;
    }


    function isArray(obj) {
        return Object.prototype.toString.call(obj) == '[object Array]';
    }


    /*
     * Convert string of baseIn to an array of numbers of baseOut.
     * Eg. convertBase('255', 10, 16) returns [15, 15].
     * Eg. convertBase('ff', 16, 10) returns [2, 5, 5].
     */
    function toBaseOut( str, baseIn, baseOut ) {
        var j,
            arr = [0],
            arrL,
            i = 0,
            len = str.length;

        for ( ; i < len; ) {
            for ( arrL = arr.length; arrL--; arr[arrL] *= baseIn );
            arr[ j = 0 ] += ALPHABET.indexOf( str.charAt( i++ ) );

            for ( ; j < arr.length; j++ ) {

                if ( arr[j] > baseOut - 1 ) {
                    if ( arr[j + 1] == null ) arr[j + 1] = 0;
                    arr[j + 1] += arr[j] / baseOut | 0;
                    arr[j] %= baseOut;
                }
            }
        }

        return arr.reverse();
    }


    function toExponential( str, e ) {
        return ( str.length > 1 ? str.charAt(0) + '.' + str.slice(1) : str ) +
          ( e < 0 ? 'e' : 'e+' ) + e;
    }


    function toFixedPoint( str, e ) {
        var len, z;

        // Negative exponent?
        if ( e < 0 ) {

            // Prepend zeros.
            for ( z = '0.'; ++e; z += '0' );
            str = z + str;

        // Positive exponent
        } else {
            len = str.length;

            // Append zeros.
            if ( ++e > len ) {
                for ( z = '0', e -= len; --e; z += '0' );
                str += z;
            } else if ( e < len ) {
                str = str.slice( 0, e ) + '.' + str.slice(e);
            }
        }

        return str;
    }


    function truncate(n) {
        n = parseFloat(n);
        return n < 0 ? mathceil(n) : mathfloor(n);
    }


    // EXPORT


   // AMD.
    if ( typeof define == 'function' && define.amd ) {
        define( function () { return constructorFactory(); } );

    // Node.js and other environments that support module.exports.
    } else if ( typeof module != 'undefined' && module.exports ) {
        module.exports = constructorFactory();

        // Split string stops browserify adding crypto shim.
        if ( !cryptoObj ) try { cryptoObj = require('cry' + 'pto'); } catch (e) {}

    // Browser.
    } else {
        if ( !globalObj ) globalObj = typeof self != 'undefined' ? self : Function('return this')();
        globalObj.BigNumber = constructorFactory();
    }
})(this);

},{}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/buffer/index.js":[function(require,module,exports){
(function (global){
/*!
 * The buffer module from node.js, for the browser.
 *
 * @author   Feross Aboukhadijeh <feross@feross.org> <http://feross.org>
 * @license  MIT
 */
/* eslint-disable no-proto */

'use strict'

var base64 = require('base64-js')
var ieee754 = require('ieee754')
var isArray = require('isarray')

exports.Buffer = Buffer
exports.SlowBuffer = SlowBuffer
exports.INSPECT_MAX_BYTES = 50

/**
 * If `Buffer.TYPED_ARRAY_SUPPORT`:
 *   === true    Use Uint8Array implementation (fastest)
 *   === false   Use Object implementation (most compatible, even IE6)
 *
 * Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+,
 * Opera 11.6+, iOS 4.2+.
 *
 * Due to various browser bugs, sometimes the Object implementation will be used even
 * when the browser supports typed arrays.
 *
 * Note:
 *
 *   - Firefox 4-29 lacks support for adding new properties to `Uint8Array` instances,
 *     See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438.
 *
 *   - Chrome 9-10 is missing the `TypedArray.prototype.subarray` function.
 *
 *   - IE10 has a broken `TypedArray.prototype.subarray` function which returns arrays of
 *     incorrect length in some situations.

 * We detect these buggy browsers and set `Buffer.TYPED_ARRAY_SUPPORT` to `false` so they
 * get the Object implementation, which is slower but behaves correctly.
 */
Buffer.TYPED_ARRAY_SUPPORT = global.TYPED_ARRAY_SUPPORT !== undefined
  ? global.TYPED_ARRAY_SUPPORT
  : typedArraySupport()

/*
 * Export kMaxLength after typed array support is determined.
 */
exports.kMaxLength = kMaxLength()

function typedArraySupport () {
  try {
    var arr = new Uint8Array(1)
    arr.__proto__ = {__proto__: Uint8Array.prototype, foo: function () { return 42 }}
    return arr.foo() === 42 && // typed array instances can be augmented
        typeof arr.subarray === 'function' && // chrome 9-10 lack `subarray`
        arr.subarray(1, 1).byteLength === 0 // ie10 has broken `subarray`
  } catch (e) {
    return false
  }
}

function kMaxLength () {
  return Buffer.TYPED_ARRAY_SUPPORT
    ? 0x7fffffff
    : 0x3fffffff
}

function createBuffer (that, length) {
  if (kMaxLength() < length) {
    throw new RangeError('Invalid typed array length')
  }
  if (Buffer.TYPED_ARRAY_SUPPORT) {
    // Return an augmented `Uint8Array` instance, for best performance
    that = new Uint8Array(length)
    that.__proto__ = Buffer.prototype
  } else {
    // Fallback: Return an object instance of the Buffer class
    if (that === null) {
      that = new Buffer(length)
    }
    that.length = length
  }

  return that
}

/**
 * The Buffer constructor returns instances of `Uint8Array` that have their
 * prototype changed to `Buffer.prototype`. Furthermore, `Buffer` is a subclass of
 * `Uint8Array`, so the returned instances will have all the node `Buffer` methods
 * and the `Uint8Array` methods. Square bracket notation works as expected -- it
 * returns a single octet.
 *
 * The `Uint8Array` prototype remains unmodified.
 */

function Buffer (arg, encodingOrOffset, length) {
  if (!Buffer.TYPED_ARRAY_SUPPORT && !(this instanceof Buffer)) {
    return new Buffer(arg, encodingOrOffset, length)
  }

  // Common case.
  if (typeof arg === 'number') {
    if (typeof encodingOrOffset === 'string') {
      throw new Error(
        'If encoding is specified then the first argument must be a string'
      )
    }
    return allocUnsafe(this, arg)
  }
  return from(this, arg, encodingOrOffset, length)
}

Buffer.poolSize = 8192 // not used by this implementation

// TODO: Legacy, not needed anymore. Remove in next major version.
Buffer._augment = function (arr) {
  arr.__proto__ = Buffer.prototype
  return arr
}

function from (that, value, encodingOrOffset, length) {
  if (typeof value === 'number') {
    throw new TypeError('"value" argument must not be a number')
  }

  if (typeof ArrayBuffer !== 'undefined' && value instanceof ArrayBuffer) {
    return fromArrayBuffer(that, value, encodingOrOffset, length)
  }

  if (typeof value === 'string') {
    return fromString(that, value, encodingOrOffset)
  }

  return fromObject(that, value)
}

/**
 * Functionally equivalent to Buffer(arg, encoding) but throws a TypeError
 * if value is a number.
 * Buffer.from(str[, encoding])
 * Buffer.from(array)
 * Buffer.from(buffer)
 * Buffer.from(arrayBuffer[, byteOffset[, length]])
 **/
Buffer.from = function (value, encodingOrOffset, length) {
  return from(null, value, encodingOrOffset, length)
}

if (Buffer.TYPED_ARRAY_SUPPORT) {
  Buffer.prototype.__proto__ = Uint8Array.prototype
  Buffer.__proto__ = Uint8Array
  if (typeof Symbol !== 'undefined' && Symbol.species &&
      Buffer[Symbol.species] === Buffer) {
    // Fix subarray() in ES2016. See: https://github.com/feross/buffer/pull/97
    Object.defineProperty(Buffer, Symbol.species, {
      value: null,
      configurable: true
    })
  }
}

function assertSize (size) {
  if (typeof size !== 'number') {
    throw new TypeError('"size" argument must be a number')
  } else if (size < 0) {
    throw new RangeError('"size" argument must not be negative')
  }
}

function alloc (that, size, fill, encoding) {
  assertSize(size)
  if (size <= 0) {
    return createBuffer(that, size)
  }
  if (fill !== undefined) {
    // Only pay attention to encoding if it's a string. This
    // prevents accidentally sending in a number that would
    // be interpretted as a start offset.
    return typeof encoding === 'string'
      ? createBuffer(that, size).fill(fill, encoding)
      : createBuffer(that, size).fill(fill)
  }
  return createBuffer(that, size)
}

/**
 * Creates a new filled Buffer instance.
 * alloc(size[, fill[, encoding]])
 **/
Buffer.alloc = function (size, fill, encoding) {
  return alloc(null, size, fill, encoding)
}

function allocUnsafe (that, size) {
  assertSize(size)
  that = createBuffer(that, size < 0 ? 0 : checked(size) | 0)
  if (!Buffer.TYPED_ARRAY_SUPPORT) {
    for (var i = 0; i < size; ++i) {
      that[i] = 0
    }
  }
  return that
}

/**
 * Equivalent to Buffer(num), by default creates a non-zero-filled Buffer instance.
 * */
Buffer.allocUnsafe = function (size) {
  return allocUnsafe(null, size)
}
/**
 * Equivalent to SlowBuffer(num), by default creates a non-zero-filled Buffer instance.
 */
Buffer.allocUnsafeSlow = function (size) {
  return allocUnsafe(null, size)
}

function fromString (that, string, encoding) {
  if (typeof encoding !== 'string' || encoding === '') {
    encoding = 'utf8'
  }

  if (!Buffer.isEncoding(encoding)) {
    throw new TypeError('"encoding" must be a valid string encoding')
  }

  var length = byteLength(string, encoding) | 0
  that = createBuffer(that, length)

  var actual = that.write(string, encoding)

  if (actual !== length) {
    // Writing a hex string, for example, that contains invalid characters will
    // cause everything after the first invalid character to be ignored. (e.g.
    // 'abxxcd' will be treated as 'ab')
    that = that.slice(0, actual)
  }

  return that
}

function fromArrayLike (that, array) {
  var length = array.length < 0 ? 0 : checked(array.length) | 0
  that = createBuffer(that, length)
  for (var i = 0; i < length; i += 1) {
    that[i] = array[i] & 255
  }
  return that
}

function fromArrayBuffer (that, array, byteOffset, length) {
  array.byteLength // this throws if `array` is not a valid ArrayBuffer

  if (byteOffset < 0 || array.byteLength < byteOffset) {
    throw new RangeError('\'offset\' is out of bounds')
  }

  if (array.byteLength < byteOffset + (length || 0)) {
    throw new RangeError('\'length\' is out of bounds')
  }

  if (byteOffset === undefined && length === undefined) {
    array = new Uint8Array(array)
  } else if (length === undefined) {
    array = new Uint8Array(array, byteOffset)
  } else {
    array = new Uint8Array(array, byteOffset, length)
  }

  if (Buffer.TYPED_ARRAY_SUPPORT) {
    // Return an augmented `Uint8Array` instance, for best performance
    that = array
    that.__proto__ = Buffer.prototype
  } else {
    // Fallback: Return an object instance of the Buffer class
    that = fromArrayLike(that, array)
  }
  return that
}

function fromObject (that, obj) {
  if (Buffer.isBuffer(obj)) {
    var len = checked(obj.length) | 0
    that = createBuffer(that, len)

    if (that.length === 0) {
      return that
    }

    obj.copy(that, 0, 0, len)
    return that
  }

  if (obj) {
    if ((typeof ArrayBuffer !== 'undefined' &&
        obj.buffer instanceof ArrayBuffer) || 'length' in obj) {
      if (typeof obj.length !== 'number' || isnan(obj.length)) {
        return createBuffer(that, 0)
      }
      return fromArrayLike(that, obj)
    }

    if (obj.type === 'Buffer' && isArray(obj.data)) {
      return fromArrayLike(that, obj.data)
    }
  }

  throw new TypeError('First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.')
}

function checked (length) {
  // Note: cannot use `length < kMaxLength()` here because that fails when
  // length is NaN (which is otherwise coerced to zero.)
  if (length >= kMaxLength()) {
    throw new RangeError('Attempt to allocate Buffer larger than maximum ' +
                         'size: 0x' + kMaxLength().toString(16) + ' bytes')
  }
  return length | 0
}

function SlowBuffer (length) {
  if (+length != length) { // eslint-disable-line eqeqeq
    length = 0
  }
  return Buffer.alloc(+length)
}

Buffer.isBuffer = function isBuffer (b) {
  return !!(b != null && b._isBuffer)
}

Buffer.compare = function compare (a, b) {
  if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) {
    throw new TypeError('Arguments must be Buffers')
  }

  if (a === b) return 0

  var x = a.length
  var y = b.length

  for (var i = 0, len = Math.min(x, y); i < len; ++i) {
    if (a[i] !== b[i]) {
      x = a[i]
      y = b[i]
      break
    }
  }

  if (x < y) return -1
  if (y < x) return 1
  return 0
}

Buffer.isEncoding = function isEncoding (encoding) {
  switch (String(encoding).toLowerCase()) {
    case 'hex':
    case 'utf8':
    case 'utf-8':
    case 'ascii':
    case 'latin1':
    case 'binary':
    case 'base64':
    case 'ucs2':
    case 'ucs-2':
    case 'utf16le':
    case 'utf-16le':
      return true
    default:
      return false
  }
}

Buffer.concat = function concat (list, length) {
  if (!isArray(list)) {
    throw new TypeError('"list" argument must be an Array of Buffers')
  }

  if (list.length === 0) {
    return Buffer.alloc(0)
  }

  var i
  if (length === undefined) {
    length = 0
    for (i = 0; i < list.length; ++i) {
      length += list[i].length
    }
  }

  var buffer = Buffer.allocUnsafe(length)
  var pos = 0
  for (i = 0; i < list.length; ++i) {
    var buf = list[i]
    if (!Buffer.isBuffer(buf)) {
      throw new TypeError('"list" argument must be an Array of Buffers')
    }
    buf.copy(buffer, pos)
    pos += buf.length
  }
  return buffer
}

function byteLength (string, encoding) {
  if (Buffer.isBuffer(string)) {
    return string.length
  }
  if (typeof ArrayBuffer !== 'undefined' && typeof ArrayBuffer.isView === 'function' &&
      (ArrayBuffer.isView(string) || string instanceof ArrayBuffer)) {
    return string.byteLength
  }
  if (typeof string !== 'string') {
    string = '' + string
  }

  var len = string.length
  if (len === 0) return 0

  // Use a for loop to avoid recursion
  var loweredCase = false
  for (;;) {
    switch (encoding) {
      case 'ascii':
      case 'latin1':
      case 'binary':
        return len
      case 'utf8':
      case 'utf-8':
      case undefined:
        return utf8ToBytes(string).length
      case 'ucs2':
      case 'ucs-2':
      case 'utf16le':
      case 'utf-16le':
        return len * 2
      case 'hex':
        return len >>> 1
      case 'base64':
        return base64ToBytes(string).length
      default:
        if (loweredCase) return utf8ToBytes(string).length // assume utf8
        encoding = ('' + encoding).toLowerCase()
        loweredCase = true
    }
  }
}
Buffer.byteLength = byteLength

function slowToString (encoding, start, end) {
  var loweredCase = false

  // No need to verify that "this.length <= MAX_UINT32" since it's a read-only
  // property of a typed array.

  // This behaves neither like String nor Uint8Array in that we set start/end
  // to their upper/lower bounds if the value passed is out of range.
  // undefined is handled specially as per ECMA-262 6th Edition,
  // Section 13.3.3.7 Runtime Semantics: KeyedBindingInitialization.
  if (start === undefined || start < 0) {
    start = 0
  }
  // Return early if start > this.length. Done here to prevent potential uint32
  // coercion fail below.
  if (start > this.length) {
    return ''
  }

  if (end === undefined || end > this.length) {
    end = this.length
  }

  if (end <= 0) {
    return ''
  }

  // Force coersion to uint32. This will also coerce falsey/NaN values to 0.
  end >>>= 0
  start >>>= 0

  if (end <= start) {
    return ''
  }

  if (!encoding) encoding = 'utf8'

  while (true) {
    switch (encoding) {
      case 'hex':
        return hexSlice(this, start, end)

      case 'utf8':
      case 'utf-8':
        return utf8Slice(this, start, end)

      case 'ascii':
        return asciiSlice(this, start, end)

      case 'latin1':
      case 'binary':
        return latin1Slice(this, start, end)

      case 'base64':
        return base64Slice(this, start, end)

      case 'ucs2':
      case 'ucs-2':
      case 'utf16le':
      case 'utf-16le':
        return utf16leSlice(this, start, end)

      default:
        if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)
        encoding = (encoding + '').toLowerCase()
        loweredCase = true
    }
  }
}

// The property is used by `Buffer.isBuffer` and `is-buffer` (in Safari 5-7) to detect
// Buffer instances.
Buffer.prototype._isBuffer = true

function swap (b, n, m) {
  var i = b[n]
  b[n] = b[m]
  b[m] = i
}

Buffer.prototype.swap16 = function swap16 () {
  var len = this.length
  if (len % 2 !== 0) {
    throw new RangeError('Buffer size must be a multiple of 16-bits')
  }
  for (var i = 0; i < len; i += 2) {
    swap(this, i, i + 1)
  }
  return this
}

Buffer.prototype.swap32 = function swap32 () {
  var len = this.length
  if (len % 4 !== 0) {
    throw new RangeError('Buffer size must be a multiple of 32-bits')
  }
  for (var i = 0; i < len; i += 4) {
    swap(this, i, i + 3)
    swap(this, i + 1, i + 2)
  }
  return this
}

Buffer.prototype.swap64 = function swap64 () {
  var len = this.length
  if (len % 8 !== 0) {
    throw new RangeError('Buffer size must be a multiple of 64-bits')
  }
  for (var i = 0; i < len; i += 8) {
    swap(this, i, i + 7)
    swap(this, i + 1, i + 6)
    swap(this, i + 2, i + 5)
    swap(this, i + 3, i + 4)
  }
  return this
}

Buffer.prototype.toString = function toString () {
  var length = this.length | 0
  if (length === 0) return ''
  if (arguments.length === 0) return utf8Slice(this, 0, length)
  return slowToString.apply(this, arguments)
}

Buffer.prototype.equals = function equals (b) {
  if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer')
  if (this === b) return true
  return Buffer.compare(this, b) === 0
}

Buffer.prototype.inspect = function inspect () {
  var str = ''
  var max = exports.INSPECT_MAX_BYTES
  if (this.length > 0) {
    str = this.toString('hex', 0, max).match(/.{2}/g).join(' ')
    if (this.length > max) str += ' ... '
  }
  return '<Buffer ' + str + '>'
}

Buffer.prototype.compare = function compare (target, start, end, thisStart, thisEnd) {
  if (!Buffer.isBuffer(target)) {
    throw new TypeError('Argument must be a Buffer')
  }

  if (start === undefined) {
    start = 0
  }
  if (end === undefined) {
    end = target ? target.length : 0
  }
  if (thisStart === undefined) {
    thisStart = 0
  }
  if (thisEnd === undefined) {
    thisEnd = this.length
  }

  if (start < 0 || end > target.length || thisStart < 0 || thisEnd > this.length) {
    throw new RangeError('out of range index')
  }

  if (thisStart >= thisEnd && start >= end) {
    return 0
  }
  if (thisStart >= thisEnd) {
    return -1
  }
  if (start >= end) {
    return 1
  }

  start >>>= 0
  end >>>= 0
  thisStart >>>= 0
  thisEnd >>>= 0

  if (this === target) return 0

  var x = thisEnd - thisStart
  var y = end - start
  var len = Math.min(x, y)

  var thisCopy = this.slice(thisStart, thisEnd)
  var targetCopy = target.slice(start, end)

  for (var i = 0; i < len; ++i) {
    if (thisCopy[i] !== targetCopy[i]) {
      x = thisCopy[i]
      y = targetCopy[i]
      break
    }
  }

  if (x < y) return -1
  if (y < x) return 1
  return 0
}

// Finds either the first index of `val` in `buffer` at offset >= `byteOffset`,
// OR the last index of `val` in `buffer` at offset <= `byteOffset`.
//
// Arguments:
// - buffer - a Buffer to search
// - val - a string, Buffer, or number
// - byteOffset - an index into `buffer`; will be clamped to an int32
// - encoding - an optional encoding, relevant is val is a string
// - dir - true for indexOf, false for lastIndexOf
function bidirectionalIndexOf (buffer, val, byteOffset, encoding, dir) {
  // Empty buffer means no match
  if (buffer.length === 0) return -1

  // Normalize byteOffset
  if (typeof byteOffset === 'string') {
    encoding = byteOffset
    byteOffset = 0
  } else if (byteOffset > 0x7fffffff) {
    byteOffset = 0x7fffffff
  } else if (byteOffset < -0x80000000) {
    byteOffset = -0x80000000
  }
  byteOffset = +byteOffset  // Coerce to Number.
  if (isNaN(byteOffset)) {
    // byteOffset: it it's undefined, null, NaN, "foo", etc, search whole buffer
    byteOffset = dir ? 0 : (buffer.length - 1)
  }

  // Normalize byteOffset: negative offsets start from the end of the buffer
  if (byteOffset < 0) byteOffset = buffer.length + byteOffset
  if (byteOffset >= buffer.length) {
    if (dir) return -1
    else byteOffset = buffer.length - 1
  } else if (byteOffset < 0) {
    if (dir) byteOffset = 0
    else return -1
  }

  // Normalize val
  if (typeof val === 'string') {
    val = Buffer.from(val, encoding)
  }

  // Finally, search either indexOf (if dir is true) or lastIndexOf
  if (Buffer.isBuffer(val)) {
    // Special case: looking for empty string/buffer always fails
    if (val.length === 0) {
      return -1
    }
    return arrayIndexOf(buffer, val, byteOffset, encoding, dir)
  } else if (typeof val === 'number') {
    val = val & 0xFF // Search for a byte value [0-255]
    if (Buffer.TYPED_ARRAY_SUPPORT &&
        typeof Uint8Array.prototype.indexOf === 'function') {
      if (dir) {
        return Uint8Array.prototype.indexOf.call(buffer, val, byteOffset)
      } else {
        return Uint8Array.prototype.lastIndexOf.call(buffer, val, byteOffset)
      }
    }
    return arrayIndexOf(buffer, [ val ], byteOffset, encoding, dir)
  }

  throw new TypeError('val must be string, number or Buffer')
}

function arrayIndexOf (arr, val, byteOffset, encoding, dir) {
  var indexSize = 1
  var arrLength = arr.length
  var valLength = val.length

  if (encoding !== undefined) {
    encoding = String(encoding).toLowerCase()
    if (encoding === 'ucs2' || encoding === 'ucs-2' ||
        encoding === 'utf16le' || encoding === 'utf-16le') {
      if (arr.length < 2 || val.length < 2) {
        return -1
      }
      indexSize = 2
      arrLength /= 2
      valLength /= 2
      byteOffset /= 2
    }
  }

  function read (buf, i) {
    if (indexSize === 1) {
      return buf[i]
    } else {
      return buf.readUInt16BE(i * indexSize)
    }
  }

  var i
  if (dir) {
    var foundIndex = -1
    for (i = byteOffset; i < arrLength; i++) {
      if (read(arr, i) === read(val, foundIndex === -1 ? 0 : i - foundIndex)) {
        if (foundIndex === -1) foundIndex = i
        if (i - foundIndex + 1 === valLength) return foundIndex * indexSize
      } else {
        if (foundIndex !== -1) i -= i - foundIndex
        foundIndex = -1
      }
    }
  } else {
    if (byteOffset + valLength > arrLength) byteOffset = arrLength - valLength
    for (i = byteOffset; i >= 0; i--) {
      var found = true
      for (var j = 0; j < valLength; j++) {
        if (read(arr, i + j) !== read(val, j)) {
          found = false
          break
        }
      }
      if (found) return i
    }
  }

  return -1
}

Buffer.prototype.includes = function includes (val, byteOffset, encoding) {
  return this.indexOf(val, byteOffset, encoding) !== -1
}

Buffer.prototype.indexOf = function indexOf (val, byteOffset, encoding) {
  return bidirectionalIndexOf(this, val, byteOffset, encoding, true)
}

Buffer.prototype.lastIndexOf = function lastIndexOf (val, byteOffset, encoding) {
  return bidirectionalIndexOf(this, val, byteOffset, encoding, false)
}

function hexWrite (buf, string, offset, length) {
  offset = Number(offset) || 0
  var remaining = buf.length - offset
  if (!length) {
    length = remaining
  } else {
    length = Number(length)
    if (length > remaining) {
      length = remaining
    }
  }

  // must be an even number of digits
  var strLen = string.length
  if (strLen % 2 !== 0) throw new TypeError('Invalid hex string')

  if (length > strLen / 2) {
    length = strLen / 2
  }
  for (var i = 0; i < length; ++i) {
    var parsed = parseInt(string.substr(i * 2, 2), 16)
    if (isNaN(parsed)) return i
    buf[offset + i] = parsed
  }
  return i
}

function utf8Write (buf, string, offset, length) {
  return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length)
}

function asciiWrite (buf, string, offset, length) {
  return blitBuffer(asciiToBytes(string), buf, offset, length)
}

function latin1Write (buf, string, offset, length) {
  return asciiWrite(buf, string, offset, length)
}

function base64Write (buf, string, offset, length) {
  return blitBuffer(base64ToBytes(string), buf, offset, length)
}

function ucs2Write (buf, string, offset, length) {
  return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length)
}

Buffer.prototype.write = function write (string, offset, length, encoding) {
  // Buffer#write(string)
  if (offset === undefined) {
    encoding = 'utf8'
    length = this.length
    offset = 0
  // Buffer#write(string, encoding)
  } else if (length === undefined && typeof offset === 'string') {
    encoding = offset
    length = this.length
    offset = 0
  // Buffer#write(string, offset[, length][, encoding])
  } else if (isFinite(offset)) {
    offset = offset | 0
    if (isFinite(length)) {
      length = length | 0
      if (encoding === undefined) encoding = 'utf8'
    } else {
      encoding = length
      length = undefined
    }
  // legacy write(string, encoding, offset, length) - remove in v0.13
  } else {
    throw new Error(
      'Buffer.write(string, encoding, offset[, length]) is no longer supported'
    )
  }

  var remaining = this.length - offset
  if (length === undefined || length > remaining) length = remaining

  if ((string.length > 0 && (length < 0 || offset < 0)) || offset > this.length) {
    throw new RangeError('Attempt to write outside buffer bounds')
  }

  if (!encoding) encoding = 'utf8'

  var loweredCase = false
  for (;;) {
    switch (encoding) {
      case 'hex':
        return hexWrite(this, string, offset, length)

      case 'utf8':
      case 'utf-8':
        return utf8Write(this, string, offset, length)

      case 'ascii':
        return asciiWrite(this, string, offset, length)

      case 'latin1':
      case 'binary':
        return latin1Write(this, string, offset, length)

      case 'base64':
        // Warning: maxLength not taken into account in base64Write
        return base64Write(this, string, offset, length)

      case 'ucs2':
      case 'ucs-2':
      case 'utf16le':
      case 'utf-16le':
        return ucs2Write(this, string, offset, length)

      default:
        if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)
        encoding = ('' + encoding).toLowerCase()
        loweredCase = true
    }
  }
}

Buffer.prototype.toJSON = function toJSON () {
  return {
    type: 'Buffer',
    data: Array.prototype.slice.call(this._arr || this, 0)
  }
}

function base64Slice (buf, start, end) {
  if (start === 0 && end === buf.length) {
    return base64.fromByteArray(buf)
  } else {
    return base64.fromByteArray(buf.slice(start, end))
  }
}

function utf8Slice (buf, start, end) {
  end = Math.min(buf.length, end)
  var res = []

  var i = start
  while (i < end) {
    var firstByte = buf[i]
    var codePoint = null
    var bytesPerSequence = (firstByte > 0xEF) ? 4
      : (firstByte > 0xDF) ? 3
      : (firstByte > 0xBF) ? 2
      : 1

    if (i + bytesPerSequence <= end) {
      var secondByte, thirdByte, fourthByte, tempCodePoint

      switch (bytesPerSequence) {
        case 1:
          if (firstByte < 0x80) {
            codePoint = firstByte
          }
          break
        case 2:
          secondByte = buf[i + 1]
          if ((secondByte & 0xC0) === 0x80) {
            tempCodePoint = (firstByte & 0x1F) << 0x6 | (secondByte & 0x3F)
            if (tempCodePoint > 0x7F) {
              codePoint = tempCodePoint
            }
          }
          break
        case 3:
          secondByte = buf[i + 1]
          thirdByte = buf[i + 2]
          if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80) {
            tempCodePoint = (firstByte & 0xF) << 0xC | (secondByte & 0x3F) << 0x6 | (thirdByte & 0x3F)
            if (tempCodePoint > 0x7FF && (tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF)) {
              codePoint = tempCodePoint
            }
          }
          break
        case 4:
          secondByte = buf[i + 1]
          thirdByte = buf[i + 2]
          fourthByte = buf[i + 3]
          if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80 && (fourthByte & 0xC0) === 0x80) {
            tempCodePoint = (firstByte & 0xF) << 0x12 | (secondByte & 0x3F) << 0xC | (thirdByte & 0x3F) << 0x6 | (fourthByte & 0x3F)
            if (tempCodePoint > 0xFFFF && tempCodePoint < 0x110000) {
              codePoint = tempCodePoint
            }
          }
      }
    }

    if (codePoint === null) {
      // we did not generate a valid codePoint so insert a
      // replacement char (U+FFFD) and advance only 1 byte
      codePoint = 0xFFFD
      bytesPerSequence = 1
    } else if (codePoint > 0xFFFF) {
      // encode to utf16 (surrogate pair dance)
      codePoint -= 0x10000
      res.push(codePoint >>> 10 & 0x3FF | 0xD800)
      codePoint = 0xDC00 | codePoint & 0x3FF
    }

    res.push(codePoint)
    i += bytesPerSequence
  }

  return decodeCodePointsArray(res)
}

// Based on http://stackoverflow.com/a/22747272/680742, the browser with
// the lowest limit is Chrome, with 0x10000 args.
// We go 1 magnitude less, for safety
var MAX_ARGUMENTS_LENGTH = 0x1000

function decodeCodePointsArray (codePoints) {
  var len = codePoints.length
  if (len <= MAX_ARGUMENTS_LENGTH) {
    return String.fromCharCode.apply(String, codePoints) // avoid extra slice()
  }

  // Decode in chunks to avoid "call stack size exceeded".
  var res = ''
  var i = 0
  while (i < len) {
    res += String.fromCharCode.apply(
      String,
      codePoints.slice(i, i += MAX_ARGUMENTS_LENGTH)
    )
  }
  return res
}

function asciiSlice (buf, start, end) {
  var ret = ''
  end = Math.min(buf.length, end)

  for (var i = start; i < end; ++i) {
    ret += String.fromCharCode(buf[i] & 0x7F)
  }
  return ret
}

function latin1Slice (buf, start, end) {
  var ret = ''
  end = Math.min(buf.length, end)

  for (var i = start; i < end; ++i) {
    ret += String.fromCharCode(buf[i])
  }
  return ret
}

function hexSlice (buf, start, end) {
  var len = buf.length

  if (!start || start < 0) start = 0
  if (!end || end < 0 || end > len) end = len

  var out = ''
  for (var i = start; i < end; ++i) {
    out += toHex(buf[i])
  }
  return out
}

function utf16leSlice (buf, start, end) {
  var bytes = buf.slice(start, end)
  var res = ''
  for (var i = 0; i < bytes.length; i += 2) {
    res += String.fromCharCode(bytes[i] + bytes[i + 1] * 256)
  }
  return res
}

Buffer.prototype.slice = function slice (start, end) {
  var len = this.length
  start = ~~start
  end = end === undefined ? len : ~~end

  if (start < 0) {
    start += len
    if (start < 0) start = 0
  } else if (start > len) {
    start = len
  }

  if (end < 0) {
    end += len
    if (end < 0) end = 0
  } else if (end > len) {
    end = len
  }

  if (end < start) end = start

  var newBuf
  if (Buffer.TYPED_ARRAY_SUPPORT) {
    newBuf = this.subarray(start, end)
    newBuf.__proto__ = Buffer.prototype
  } else {
    var sliceLen = end - start
    newBuf = new Buffer(sliceLen, undefined)
    for (var i = 0; i < sliceLen; ++i) {
      newBuf[i] = this[i + start]
    }
  }

  return newBuf
}

/*
 * Need to make sure that buffer isn't trying to write out of bounds.
 */
function checkOffset (offset, ext, length) {
  if ((offset % 1) !== 0 || offset < 0) throw new RangeError('offset is not uint')
  if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length')
}

Buffer.prototype.readUIntLE = function readUIntLE (offset, byteLength, noAssert) {
  offset = offset | 0
  byteLength = byteLength | 0
  if (!noAssert) checkOffset(offset, byteLength, this.length)

  var val = this[offset]
  var mul = 1
  var i = 0
  while (++i < byteLength && (mul *= 0x100)) {
    val += this[offset + i] * mul
  }

  return val
}

Buffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) {
  offset = offset | 0
  byteLength = byteLength | 0
  if (!noAssert) {
    checkOffset(offset, byteLength, this.length)
  }

  var val = this[offset + --byteLength]
  var mul = 1
  while (byteLength > 0 && (mul *= 0x100)) {
    val += this[offset + --byteLength] * mul
  }

  return val
}

Buffer.prototype.readUInt8 = function readUInt8 (offset, noAssert) {
  if (!noAssert) checkOffset(offset, 1, this.length)
  return this[offset]
}

Buffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) {
  if (!noAssert) checkOffset(offset, 2, this.length)
  return this[offset] | (this[offset + 1] << 8)
}

Buffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) {
  if (!noAssert) checkOffset(offset, 2, this.length)
  return (this[offset] << 8) | this[offset + 1]
}

Buffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) {
  if (!noAssert) checkOffset(offset, 4, this.length)

  return ((this[offset]) |
      (this[offset + 1] << 8) |
      (this[offset + 2] << 16)) +
      (this[offset + 3] * 0x1000000)
}

Buffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) {
  if (!noAssert) checkOffset(offset, 4, this.length)

  return (this[offset] * 0x1000000) +
    ((this[offset + 1] << 16) |
    (this[offset + 2] << 8) |
    this[offset + 3])
}

Buffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) {
  offset = offset | 0
  byteLength = byteLength | 0
  if (!noAssert) checkOffset(offset, byteLength, this.length)

  var val = this[offset]
  var mul = 1
  var i = 0
  while (++i < byteLength && (mul *= 0x100)) {
    val += this[offset + i] * mul
  }
  mul *= 0x80

  if (val >= mul) val -= Math.pow(2, 8 * byteLength)

  return val
}

Buffer.prototype.readIntBE = function readIntBE (offset, byteLength, noAssert) {
  offset = offset | 0
  byteLength = byteLength | 0
  if (!noAssert) checkOffset(offset, byteLength, this.length)

  var i = byteLength
  var mul = 1
  var val = this[offset + --i]
  while (i > 0 && (mul *= 0x100)) {
    val += this[offset + --i] * mul
  }
  mul *= 0x80

  if (val >= mul) val -= Math.pow(2, 8 * byteLength)

  return val
}

Buffer.prototype.readInt8 = function readInt8 (offset, noAssert) {
  if (!noAssert) checkOffset(offset, 1, this.length)
  if (!(this[offset] & 0x80)) return (this[offset])
  return ((0xff - this[offset] + 1) * -1)
}

Buffer.prototype.readInt16LE = function readInt16LE (offset, noAssert) {
  if (!noAssert) checkOffset(offset, 2, this.length)
  var val = this[offset] | (this[offset + 1] << 8)
  return (val & 0x8000) ? val | 0xFFFF0000 : val
}

Buffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) {
  if (!noAssert) checkOffset(offset, 2, this.length)
  var val = this[offset + 1] | (this[offset] << 8)
  return (val & 0x8000) ? val | 0xFFFF0000 : val
}

Buffer.prototype.readInt32LE = function readInt32LE (offset, noAssert) {
  if (!noAssert) checkOffset(offset, 4, this.length)

  return (this[offset]) |
    (this[offset + 1] << 8) |
    (this[offset + 2] << 16) |
    (this[offset + 3] << 24)
}

Buffer.prototype.readInt32BE = function readInt32BE (offset, noAssert) {
  if (!noAssert) checkOffset(offset, 4, this.length)

  return (this[offset] << 24) |
    (this[offset + 1] << 16) |
    (this[offset + 2] << 8) |
    (this[offset + 3])
}

Buffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) {
  if (!noAssert) checkOffset(offset, 4, this.length)
  return ieee754.read(this, offset, true, 23, 4)
}

Buffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) {
  if (!noAssert) checkOffset(offset, 4, this.length)
  return ieee754.read(this, offset, false, 23, 4)
}

Buffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) {
  if (!noAssert) checkOffset(offset, 8, this.length)
  return ieee754.read(this, offset, true, 52, 8)
}

Buffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) {
  if (!noAssert) checkOffset(offset, 8, this.length)
  return ieee754.read(this, offset, false, 52, 8)
}

function checkInt (buf, value, offset, ext, max, min) {
  if (!Buffer.isBuffer(buf)) throw new TypeError('"buffer" argument must be a Buffer instance')
  if (value > max || value < min) throw new RangeError('"value" argument is out of bounds')
  if (offset + ext > buf.length) throw new RangeError('Index out of range')
}

Buffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) {
  value = +value
  offset = offset | 0
  byteLength = byteLength | 0
  if (!noAssert) {
    var maxBytes = Math.pow(2, 8 * byteLength) - 1
    checkInt(this, value, offset, byteLength, maxBytes, 0)
  }

  var mul = 1
  var i = 0
  this[offset] = value & 0xFF
  while (++i < byteLength && (mul *= 0x100)) {
    this[offset + i] = (value / mul) & 0xFF
  }

  return offset + byteLength
}

Buffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) {
  value = +value
  offset = offset | 0
  byteLength = byteLength | 0
  if (!noAssert) {
    var maxBytes = Math.pow(2, 8 * byteLength) - 1
    checkInt(this, value, offset, byteLength, maxBytes, 0)
  }

  var i = byteLength - 1
  var mul = 1
  this[offset + i] = value & 0xFF
  while (--i >= 0 && (mul *= 0x100)) {
    this[offset + i] = (value / mul) & 0xFF
  }

  return offset + byteLength
}

Buffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) {
  value = +value
  offset = offset | 0
  if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0)
  if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)
  this[offset] = (value & 0xff)
  return offset + 1
}

function objectWriteUInt16 (buf, value, offset, littleEndian) {
  if (value < 0) value = 0xffff + value + 1
  for (var i = 0, j = Math.min(buf.length - offset, 2); i < j; ++i) {
    buf[offset + i] = (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>>
      (littleEndian ? i : 1 - i) * 8
  }
}

Buffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) {
  value = +value
  offset = offset | 0
  if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)
  if (Buffer.TYPED_ARRAY_SUPPORT) {
    this[offset] = (value & 0xff)
    this[offset + 1] = (value >>> 8)
  } else {
    objectWriteUInt16(this, value, offset, true)
  }
  return offset + 2
}

Buffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) {
  value = +value
  offset = offset | 0
  if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)
  if (Buffer.TYPED_ARRAY_SUPPORT) {
    this[offset] = (value >>> 8)
    this[offset + 1] = (value & 0xff)
  } else {
    objectWriteUInt16(this, value, offset, false)
  }
  return offset + 2
}

function objectWriteUInt32 (buf, value, offset, littleEndian) {
  if (value < 0) value = 0xffffffff + value + 1
  for (var i = 0, j = Math.min(buf.length - offset, 4); i < j; ++i) {
    buf[offset + i] = (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff
  }
}

Buffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) {
  value = +value
  offset = offset | 0
  if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)
  if (Buffer.TYPED_ARRAY_SUPPORT) {
    this[offset + 3] = (value >>> 24)
    this[offset + 2] = (value >>> 16)
    this[offset + 1] = (value >>> 8)
    this[offset] = (value & 0xff)
  } else {
    objectWriteUInt32(this, value, offset, true)
  }
  return offset + 4
}

Buffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) {
  value = +value
  offset = offset | 0
  if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)
  if (Buffer.TYPED_ARRAY_SUPPORT) {
    this[offset] = (value >>> 24)
    this[offset + 1] = (value >>> 16)
    this[offset + 2] = (value >>> 8)
    this[offset + 3] = (value & 0xff)
  } else {
    objectWriteUInt32(this, value, offset, false)
  }
  return offset + 4
}

Buffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) {
  value = +value
  offset = offset | 0
  if (!noAssert) {
    var limit = Math.pow(2, 8 * byteLength - 1)

    checkInt(this, value, offset, byteLength, limit - 1, -limit)
  }

  var i = 0
  var mul = 1
  var sub = 0
  this[offset] = value & 0xFF
  while (++i < byteLength && (mul *= 0x100)) {
    if (value < 0 && sub === 0 && this[offset + i - 1] !== 0) {
      sub = 1
    }
    this[offset + i] = ((value / mul) >> 0) - sub & 0xFF
  }

  return offset + byteLength
}

Buffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, noAssert) {
  value = +value
  offset = offset | 0
  if (!noAssert) {
    var limit = Math.pow(2, 8 * byteLength - 1)

    checkInt(this, value, offset, byteLength, limit - 1, -limit)
  }

  var i = byteLength - 1
  var mul = 1
  var sub = 0
  this[offset + i] = value & 0xFF
  while (--i >= 0 && (mul *= 0x100)) {
    if (value < 0 && sub === 0 && this[offset + i + 1] !== 0) {
      sub = 1
    }
    this[offset + i] = ((value / mul) >> 0) - sub & 0xFF
  }

  return offset + byteLength
}

Buffer.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) {
  value = +value
  offset = offset | 0
  if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80)
  if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)
  if (value < 0) value = 0xff + value + 1
  this[offset] = (value & 0xff)
  return offset + 1
}

Buffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) {
  value = +value
  offset = offset | 0
  if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)
  if (Buffer.TYPED_ARRAY_SUPPORT) {
    this[offset] = (value & 0xff)
    this[offset + 1] = (value >>> 8)
  } else {
    objectWriteUInt16(this, value, offset, true)
  }
  return offset + 2
}

Buffer.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) {
  value = +value
  offset = offset | 0
  if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)
  if (Buffer.TYPED_ARRAY_SUPPORT) {
    this[offset] = (value >>> 8)
    this[offset + 1] = (value & 0xff)
  } else {
    objectWriteUInt16(this, value, offset, false)
  }
  return offset + 2
}

Buffer.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) {
  value = +value
  offset = offset | 0
  if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)
  if (Buffer.TYPED_ARRAY_SUPPORT) {
    this[offset] = (value & 0xff)
    this[offset + 1] = (value >>> 8)
    this[offset + 2] = (value >>> 16)
    this[offset + 3] = (value >>> 24)
  } else {
    objectWriteUInt32(this, value, offset, true)
  }
  return offset + 4
}

Buffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) {
  value = +value
  offset = offset | 0
  if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)
  if (value < 0) value = 0xffffffff + value + 1
  if (Buffer.TYPED_ARRAY_SUPPORT) {
    this[offset] = (value >>> 24)
    this[offset + 1] = (value >>> 16)
    this[offset + 2] = (value >>> 8)
    this[offset + 3] = (value & 0xff)
  } else {
    objectWriteUInt32(this, value, offset, false)
  }
  return offset + 4
}

function checkIEEE754 (buf, value, offset, ext, max, min) {
  if (offset + ext > buf.length) throw new RangeError('Index out of range')
  if (offset < 0) throw new RangeError('Index out of range')
}

function writeFloat (buf, value, offset, littleEndian, noAssert) {
  if (!noAssert) {
    checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38)
  }
  ieee754.write(buf, value, offset, littleEndian, 23, 4)
  return offset + 4
}

Buffer.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) {
  return writeFloat(this, value, offset, true, noAssert)
}

Buffer.prototype.writeFloatBE = function writeFloatBE (value, offset, noAssert) {
  return writeFloat(this, value, offset, false, noAssert)
}

function writeDouble (buf, value, offset, littleEndian, noAssert) {
  if (!noAssert) {
    checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308)
  }
  ieee754.write(buf, value, offset, littleEndian, 52, 8)
  return offset + 8
}

Buffer.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) {
  return writeDouble(this, value, offset, true, noAssert)
}

Buffer.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) {
  return writeDouble(this, value, offset, false, noAssert)
}

// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length)
Buffer.prototype.copy = function copy (target, targetStart, start, end) {
  if (!start) start = 0
  if (!end && end !== 0) end = this.length
  if (targetStart >= target.length) targetStart = target.length
  if (!targetStart) targetStart = 0
  if (end > 0 && end < start) end = start

  // Copy 0 bytes; we're done
  if (end === start) return 0
  if (target.length === 0 || this.length === 0) return 0

  // Fatal error conditions
  if (targetStart < 0) {
    throw new RangeError('targetStart out of bounds')
  }
  if (start < 0 || start >= this.length) throw new RangeError('sourceStart out of bounds')
  if (end < 0) throw new RangeError('sourceEnd out of bounds')

  // Are we oob?
  if (end > this.length) end = this.length
  if (target.length - targetStart < end - start) {
    end = target.length - targetStart + start
  }

  var len = end - start
  var i

  if (this === target && start < targetStart && targetStart < end) {
    // descending copy from end
    for (i = len - 1; i >= 0; --i) {
      target[i + targetStart] = this[i + start]
    }
  } else if (len < 1000 || !Buffer.TYPED_ARRAY_SUPPORT) {
    // ascending copy from start
    for (i = 0; i < len; ++i) {
      target[i + targetStart] = this[i + start]
    }
  } else {
    Uint8Array.prototype.set.call(
      target,
      this.subarray(start, start + len),
      targetStart
    )
  }

  return len
}

// Usage:
//    buffer.fill(number[, offset[, end]])
//    buffer.fill(buffer[, offset[, end]])
//    buffer.fill(string[, offset[, end]][, encoding])
Buffer.prototype.fill = function fill (val, start, end, encoding) {
  // Handle string cases:
  if (typeof val === 'string') {
    if (typeof start === 'string') {
      encoding = start
      start = 0
      end = this.length
    } else if (typeof end === 'string') {
      encoding = end
      end = this.length
    }
    if (val.length === 1) {
      var code = val.charCodeAt(0)
      if (code < 256) {
        val = code
      }
    }
    if (encoding !== undefined && typeof encoding !== 'string') {
      throw new TypeError('encoding must be a string')
    }
    if (typeof encoding === 'string' && !Buffer.isEncoding(encoding)) {
      throw new TypeError('Unknown encoding: ' + encoding)
    }
  } else if (typeof val === 'number') {
    val = val & 255
  }

  // Invalid ranges are not set to a default, so can range check early.
  if (start < 0 || this.length < start || this.length < end) {
    throw new RangeError('Out of range index')
  }

  if (end <= start) {
    return this
  }

  start = start >>> 0
  end = end === undefined ? this.length : end >>> 0

  if (!val) val = 0

  var i
  if (typeof val === 'number') {
    for (i = start; i < end; ++i) {
      this[i] = val
    }
  } else {
    var bytes = Buffer.isBuffer(val)
      ? val
      : utf8ToBytes(new Buffer(val, encoding).toString())
    var len = bytes.length
    for (i = 0; i < end - start; ++i) {
      this[i + start] = bytes[i % len]
    }
  }

  return this
}

// HELPER FUNCTIONS
// ================

var INVALID_BASE64_RE = /[^+\/0-9A-Za-z-_]/g

function base64clean (str) {
  // Node strips out invalid characters like \n and \t from the string, base64-js does not
  str = stringtrim(str).replace(INVALID_BASE64_RE, '')
  // Node converts strings with length < 2 to ''
  if (str.length < 2) return ''
  // Node allows for non-padded base64 strings (missing trailing ===), base64-js does not
  while (str.length % 4 !== 0) {
    str = str + '='
  }
  return str
}

function stringtrim (str) {
  if (str.trim) return str.trim()
  return str.replace(/^\s+|\s+$/g, '')
}

function toHex (n) {
  if (n < 16) return '0' + n.toString(16)
  return n.toString(16)
}

function utf8ToBytes (string, units) {
  units = units || Infinity
  var codePoint
  var length = string.length
  var leadSurrogate = null
  var bytes = []

  for (var i = 0; i < length; ++i) {
    codePoint = string.charCodeAt(i)

    // is surrogate component
    if (codePoint > 0xD7FF && codePoint < 0xE000) {
      // last char was a lead
      if (!leadSurrogate) {
        // no lead yet
        if (codePoint > 0xDBFF) {
          // unexpected trail
          if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
          continue
        } else if (i + 1 === length) {
          // unpaired lead
          if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
          continue
        }

        // valid lead
        leadSurrogate = codePoint

        continue
      }

      // 2 leads in a row
      if (codePoint < 0xDC00) {
        if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
        leadSurrogate = codePoint
        continue
      }

      // valid surrogate pair
      codePoint = (leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00) + 0x10000
    } else if (leadSurrogate) {
      // valid bmp char, but last char was a lead
      if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
    }

    leadSurrogate = null

    // encode utf8
    if (codePoint < 0x80) {
      if ((units -= 1) < 0) break
      bytes.push(codePoint)
    } else if (codePoint < 0x800) {
      if ((units -= 2) < 0) break
      bytes.push(
        codePoint >> 0x6 | 0xC0,
        codePoint & 0x3F | 0x80
      )
    } else if (codePoint < 0x10000) {
      if ((units -= 3) < 0) break
      bytes.push(
        codePoint >> 0xC | 0xE0,
        codePoint >> 0x6 & 0x3F | 0x80,
        codePoint & 0x3F | 0x80
      )
    } else if (codePoint < 0x110000) {
      if ((units -= 4) < 0) break
      bytes.push(
        codePoint >> 0x12 | 0xF0,
        codePoint >> 0xC & 0x3F | 0x80,
        codePoint >> 0x6 & 0x3F | 0x80,
        codePoint & 0x3F | 0x80
      )
    } else {
      throw new Error('Invalid code point')
    }
  }

  return bytes
}

function asciiToBytes (str) {
  var byteArray = []
  for (var i = 0; i < str.length; ++i) {
    // Node's code seems to be doing this and not & 0x7F..
    byteArray.push(str.charCodeAt(i) & 0xFF)
  }
  return byteArray
}

function utf16leToBytes (str, units) {
  var c, hi, lo
  var byteArray = []
  for (var i = 0; i < str.length; ++i) {
    if ((units -= 2) < 0) break

    c = str.charCodeAt(i)
    hi = c >> 8
    lo = c % 256
    byteArray.push(lo)
    byteArray.push(hi)
  }

  return byteArray
}

function base64ToBytes (str) {
  return base64.toByteArray(base64clean(str))
}

function blitBuffer (src, dst, offset, length) {
  for (var i = 0; i < length; ++i) {
    if ((i + offset >= dst.length) || (i >= src.length)) break
    dst[i + offset] = src[i]
  }
  return i
}

function isnan (val) {
  return val !== val // eslint-disable-line no-self-compare
}

}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
},{"base64-js":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/base64-js/index.js","ieee754":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/ieee754/index.js","isarray":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/isarray/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/charenc/charenc.js":[function(require,module,exports){
var charenc = {
  // UTF-8 encoding
  utf8: {
    // Convert a string to a byte array
    stringToBytes: function(str) {
      return charenc.bin.stringToBytes(unescape(encodeURIComponent(str)));
    },

    // Convert a byte array to a string
    bytesToString: function(bytes) {
      return decodeURIComponent(escape(charenc.bin.bytesToString(bytes)));
    }
  },

  // Binary encoding
  bin: {
    // Convert a string to a byte array
    stringToBytes: function(str) {
      for (var bytes = [], i = 0; i < str.length; i++)
        bytes.push(str.charCodeAt(i) & 0xFF);
      return bytes;
    },

    // Convert a byte array to a string
    bytesToString: function(bytes) {
      for (var str = [], i = 0; i < bytes.length; i++)
        str.push(String.fromCharCode(bytes[i]));
      return str.join('');
    }
  }
};

module.exports = charenc;

},{}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/es6/set.js":[function(require,module,exports){
require('../modules/es6.object.to-string');
require('../modules/es6.string.iterator');
require('../modules/web.dom.iterable');
require('../modules/es6.set');
module.exports = require('../modules/_core').Set;

},{"../modules/_core":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_core.js","../modules/es6.object.to-string":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/es6.object.to-string.js","../modules/es6.set":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/es6.set.js","../modules/es6.string.iterator":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/es6.string.iterator.js","../modules/web.dom.iterable":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/web.dom.iterable.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/es6/symbol.js":[function(require,module,exports){
require('../modules/es6.symbol');
require('../modules/es6.object.to-string');
module.exports = require('../modules/_core').Symbol;

},{"../modules/_core":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_core.js","../modules/es6.object.to-string":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/es6.object.to-string.js","../modules/es6.symbol":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/es6.symbol.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/fn/array/find-index.js":[function(require,module,exports){
require('../../modules/es6.array.find-index');
module.exports = require('../../modules/_core').Array.findIndex;

},{"../../modules/_core":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_core.js","../../modules/es6.array.find-index":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/es6.array.find-index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/fn/array/find.js":[function(require,module,exports){
require('../../modules/es6.array.find');
module.exports = require('../../modules/_core').Array.find;

},{"../../modules/_core":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_core.js","../../modules/es6.array.find":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/es6.array.find.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/fn/array/from.js":[function(require,module,exports){
require('../../modules/es6.string.iterator');
require('../../modules/es6.array.from');
module.exports = require('../../modules/_core').Array.from;

},{"../../modules/_core":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_core.js","../../modules/es6.array.from":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/es6.array.from.js","../../modules/es6.string.iterator":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/es6.string.iterator.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/fn/array/of.js":[function(require,module,exports){
require('../../modules/es6.array.of');
module.exports = require('../../modules/_core').Array.of;

},{"../../modules/_core":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_core.js","../../modules/es6.array.of":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/es6.array.of.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/fn/object/is.js":[function(require,module,exports){
require('../../modules/es6.object.is');
module.exports = require('../../modules/_core').Object.is;

},{"../../modules/_core":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_core.js","../../modules/es6.object.is":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/es6.object.is.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/fn/string/includes.js":[function(require,module,exports){
require('../../modules/es6.string.includes');
module.exports = require('../../modules/_core').String.includes;

},{"../../modules/_core":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_core.js","../../modules/es6.string.includes":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/es6.string.includes.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/fn/symbol/iterator.js":[function(require,module,exports){
require('../../modules/es6.string.iterator');
require('../../modules/web.dom.iterable');
module.exports = require('../../modules/_wks-ext').f('iterator');

},{"../../modules/_wks-ext":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_wks-ext.js","../../modules/es6.string.iterator":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/es6.string.iterator.js","../../modules/web.dom.iterable":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/web.dom.iterable.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_a-function.js":[function(require,module,exports){
module.exports = function (it) {
  if (typeof it != 'function') throw TypeError(it + ' is not a function!');
  return it;
};

},{}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_add-to-unscopables.js":[function(require,module,exports){
// 22.1.3.31 Array.prototype[@@unscopables]
var UNSCOPABLES = require('./_wks')('unscopables');
var ArrayProto = Array.prototype;
if (ArrayProto[UNSCOPABLES] == undefined) require('./_hide')(ArrayProto, UNSCOPABLES, {});
module.exports = function (key) {
  ArrayProto[UNSCOPABLES][key] = true;
};

},{"./_hide":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_hide.js","./_wks":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_wks.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_an-instance.js":[function(require,module,exports){
module.exports = function (it, Constructor, name, forbiddenField) {
  if (!(it instanceof Constructor) || (forbiddenField !== undefined && forbiddenField in it)) {
    throw TypeError(name + ': incorrect invocation!');
  } return it;
};

},{}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_an-object.js":[function(require,module,exports){
var isObject = require('./_is-object');
module.exports = function (it) {
  if (!isObject(it)) throw TypeError(it + ' is not an object!');
  return it;
};

},{"./_is-object":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_is-object.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_array-includes.js":[function(require,module,exports){
// false -> Array#indexOf
// true  -> Array#includes
var toIObject = require('./_to-iobject');
var toLength = require('./_to-length');
var toAbsoluteIndex = require('./_to-absolute-index');
module.exports = function (IS_INCLUDES) {
  return function ($this, el, fromIndex) {
    var O = toIObject($this);
    var length = toLength(O.length);
    var index = toAbsoluteIndex(fromIndex, length);
    var value;
    // Array#includes uses SameValueZero equality algorithm
    // eslint-disable-next-line no-self-compare
    if (IS_INCLUDES && el != el) while (length > index) {
      value = O[index++];
      // eslint-disable-next-line no-self-compare
      if (value != value) return true;
    // Array#indexOf ignores holes, Array#includes - not
    } else for (;length > index; index++) if (IS_INCLUDES || index in O) {
      if (O[index] === el) return IS_INCLUDES || index || 0;
    } return !IS_INCLUDES && -1;
  };
};

},{"./_to-absolute-index":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_to-absolute-index.js","./_to-iobject":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_to-iobject.js","./_to-length":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_to-length.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_array-methods.js":[function(require,module,exports){
// 0 -> Array#forEach
// 1 -> Array#map
// 2 -> Array#filter
// 3 -> Array#some
// 4 -> Array#every
// 5 -> Array#find
// 6 -> Array#findIndex
var ctx = require('./_ctx');
var IObject = require('./_iobject');
var toObject = require('./_to-object');
var toLength = require('./_to-length');
var asc = require('./_array-species-create');
module.exports = function (TYPE, $create) {
  var IS_MAP = TYPE == 1;
  var IS_FILTER = TYPE == 2;
  var IS_SOME = TYPE == 3;
  var IS_EVERY = TYPE == 4;
  var IS_FIND_INDEX = TYPE == 6;
  var NO_HOLES = TYPE == 5 || IS_FIND_INDEX;
  var create = $create || asc;
  return function ($this, callbackfn, that) {
    var O = toObject($this);
    var self = IObject(O);
    var f = ctx(callbackfn, that, 3);
    var length = toLength(self.length);
    var index = 0;
    var result = IS_MAP ? create($this, length) : IS_FILTER ? create($this, 0) : undefined;
    var val, res;
    for (;length > index; index++) if (NO_HOLES || index in self) {
      val = self[index];
      res = f(val, index, O);
      if (TYPE) {
        if (IS_MAP) result[index] = res;   // map
        else if (res) switch (TYPE) {
          case 3: return true;             // some
          case 5: return val;              // find
          case 6: return index;            // findIndex
          case 2: result.push(val);        // filter
        } else if (IS_EVERY) return false; // every
      }
    }
    return IS_FIND_INDEX ? -1 : IS_SOME || IS_EVERY ? IS_EVERY : result;
  };
};

},{"./_array-species-create":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_array-species-create.js","./_ctx":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_ctx.js","./_iobject":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_iobject.js","./_to-length":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_to-length.js","./_to-object":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_to-object.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_array-species-constructor.js":[function(require,module,exports){
var isObject = require('./_is-object');
var isArray = require('./_is-array');
var SPECIES = require('./_wks')('species');

module.exports = function (original) {
  var C;
  if (isArray(original)) {
    C = original.constructor;
    // cross-realm fallback
    if (typeof C == 'function' && (C === Array || isArray(C.prototype))) C = undefined;
    if (isObject(C)) {
      C = C[SPECIES];
      if (C === null) C = undefined;
    }
  } return C === undefined ? Array : C;
};

},{"./_is-array":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_is-array.js","./_is-object":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_is-object.js","./_wks":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_wks.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_array-species-create.js":[function(require,module,exports){
// 9.4.2.3 ArraySpeciesCreate(originalArray, length)
var speciesConstructor = require('./_array-species-constructor');

module.exports = function (original, length) {
  return new (speciesConstructor(original))(length);
};

},{"./_array-species-constructor":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_array-species-constructor.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_classof.js":[function(require,module,exports){
// getting tag from 19.1.3.6 Object.prototype.toString()
var cof = require('./_cof');
var TAG = require('./_wks')('toStringTag');
// ES3 wrong here
var ARG = cof(function () { return arguments; }()) == 'Arguments';

// fallback for IE11 Script Access Denied error
var tryGet = function (it, key) {
  try {
    return it[key];
  } catch (e) { /* empty */ }
};

module.exports = function (it) {
  var O, T, B;
  return it === undefined ? 'Undefined' : it === null ? 'Null'
    // @@toStringTag case
    : typeof (T = tryGet(O = Object(it), TAG)) == 'string' ? T
    // builtinTag case
    : ARG ? cof(O)
    // ES3 arguments fallback
    : (B = cof(O)) == 'Object' && typeof O.callee == 'function' ? 'Arguments' : B;
};

},{"./_cof":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_cof.js","./_wks":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_wks.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_cof.js":[function(require,module,exports){
var toString = {}.toString;

module.exports = function (it) {
  return toString.call(it).slice(8, -1);
};

},{}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_collection-strong.js":[function(require,module,exports){
'use strict';
var dP = require('./_object-dp').f;
var create = require('./_object-create');
var redefineAll = require('./_redefine-all');
var ctx = require('./_ctx');
var anInstance = require('./_an-instance');
var forOf = require('./_for-of');
var $iterDefine = require('./_iter-define');
var step = require('./_iter-step');
var setSpecies = require('./_set-species');
var DESCRIPTORS = require('./_descriptors');
var fastKey = require('./_meta').fastKey;
var validate = require('./_validate-collection');
var SIZE = DESCRIPTORS ? '_s' : 'size';

var getEntry = function (that, key) {
  // fast case
  var index = fastKey(key);
  var entry;
  if (index !== 'F') return that._i[index];
  // frozen object case
  for (entry = that._f; entry; entry = entry.n) {
    if (entry.k == key) return entry;
  }
};

module.exports = {
  getConstructor: function (wrapper, NAME, IS_MAP, ADDER) {
    var C = wrapper(function (that, iterable) {
      anInstance(that, C, NAME, '_i');
      that._t = NAME;         // collection type
      that._i = create(null); // index
      that._f = undefined;    // first entry
      that._l = undefined;    // last entry
      that[SIZE] = 0;         // size
      if (iterable != undefined) forOf(iterable, IS_MAP, that[ADDER], that);
    });
    redefineAll(C.prototype, {
      // 23.1.3.1 Map.prototype.clear()
      // 23.2.3.2 Set.prototype.clear()
      clear: function clear() {
        for (var that = validate(this, NAME), data = that._i, entry = that._f; entry; entry = entry.n) {
          entry.r = true;
          if (entry.p) entry.p = entry.p.n = undefined;
          delete data[entry.i];
        }
        that._f = that._l = undefined;
        that[SIZE] = 0;
      },
      // 23.1.3.3 Map.prototype.delete(key)
      // 23.2.3.4 Set.prototype.delete(value)
      'delete': function (key) {
        var that = validate(this, NAME);
        var entry = getEntry(that, key);
        if (entry) {
          var next = entry.n;
          var prev = entry.p;
          delete that._i[entry.i];
          entry.r = true;
          if (prev) prev.n = next;
          if (next) next.p = prev;
          if (that._f == entry) that._f = next;
          if (that._l == entry) that._l = prev;
          that[SIZE]--;
        } return !!entry;
      },
      // 23.2.3.6 Set.prototype.forEach(callbackfn, thisArg = undefined)
      // 23.1.3.5 Map.prototype.forEach(callbackfn, thisArg = undefined)
      forEach: function forEach(callbackfn /* , that = undefined */) {
        validate(this, NAME);
        var f = ctx(callbackfn, arguments.length > 1 ? arguments[1] : undefined, 3);
        var entry;
        while (entry = entry ? entry.n : this._f) {
          f(entry.v, entry.k, this);
          // revert to the last existing entry
          while (entry && entry.r) entry = entry.p;
        }
      },
      // 23.1.3.7 Map.prototype.has(key)
      // 23.2.3.7 Set.prototype.has(value)
      has: function has(key) {
        return !!getEntry(validate(this, NAME), key);
      }
    });
    if (DESCRIPTORS) dP(C.prototype, 'size', {
      get: function () {
        return validate(this, NAME)[SIZE];
      }
    });
    return C;
  },
  def: function (that, key, value) {
    var entry = getEntry(that, key);
    var prev, index;
    // change existing entry
    if (entry) {
      entry.v = value;
    // create new entry
    } else {
      that._l = entry = {
        i: index = fastKey(key, true), // <- index
        k: key,                        // <- key
        v: value,                      // <- value
        p: prev = that._l,             // <- previous entry
        n: undefined,                  // <- next entry
        r: false                       // <- removed
      };
      if (!that._f) that._f = entry;
      if (prev) prev.n = entry;
      that[SIZE]++;
      // add to index
      if (index !== 'F') that._i[index] = entry;
    } return that;
  },
  getEntry: getEntry,
  setStrong: function (C, NAME, IS_MAP) {
    // add .keys, .values, .entries, [@@iterator]
    // 23.1.3.4, 23.1.3.8, 23.1.3.11, 23.1.3.12, 23.2.3.5, 23.2.3.8, 23.2.3.10, 23.2.3.11
    $iterDefine(C, NAME, function (iterated, kind) {
      this._t = validate(iterated, NAME); // target
      this._k = kind;                     // kind
      this._l = undefined;                // previous
    }, function () {
      var that = this;
      var kind = that._k;
      var entry = that._l;
      // revert to the last existing entry
      while (entry && entry.r) entry = entry.p;
      // get next entry
      if (!that._t || !(that._l = entry = entry ? entry.n : that._t._f)) {
        // or finish the iteration
        that._t = undefined;
        return step(1);
      }
      // return step by kind
      if (kind == 'keys') return step(0, entry.k);
      if (kind == 'values') return step(0, entry.v);
      return step(0, [entry.k, entry.v]);
    }, IS_MAP ? 'entries' : 'values', !IS_MAP, true);

    // add [@@species], 23.1.2.2, 23.2.2.2
    setSpecies(NAME);
  }
};

},{"./_an-instance":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_an-instance.js","./_ctx":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_ctx.js","./_descriptors":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_descriptors.js","./_for-of":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_for-of.js","./_iter-define":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_iter-define.js","./_iter-step":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_iter-step.js","./_meta":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_meta.js","./_object-create":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_object-create.js","./_object-dp":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_object-dp.js","./_redefine-all":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_redefine-all.js","./_set-species":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_set-species.js","./_validate-collection":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_validate-collection.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_collection.js":[function(require,module,exports){
'use strict';
var global = require('./_global');
var $export = require('./_export');
var redefine = require('./_redefine');
var redefineAll = require('./_redefine-all');
var meta = require('./_meta');
var forOf = require('./_for-of');
var anInstance = require('./_an-instance');
var isObject = require('./_is-object');
var fails = require('./_fails');
var $iterDetect = require('./_iter-detect');
var setToStringTag = require('./_set-to-string-tag');
var inheritIfRequired = require('./_inherit-if-required');

module.exports = function (NAME, wrapper, methods, common, IS_MAP, IS_WEAK) {
  var Base = global[NAME];
  var C = Base;
  var ADDER = IS_MAP ? 'set' : 'add';
  var proto = C && C.prototype;
  var O = {};
  var fixMethod = function (KEY) {
    var fn = proto[KEY];
    redefine(proto, KEY,
      KEY == 'delete' ? function (a) {
        return IS_WEAK && !isObject(a) ? false : fn.call(this, a === 0 ? 0 : a);
      } : KEY == 'has' ? function has(a) {
        return IS_WEAK && !isObject(a) ? false : fn.call(this, a === 0 ? 0 : a);
      } : KEY == 'get' ? function get(a) {
        return IS_WEAK && !isObject(a) ? undefined : fn.call(this, a === 0 ? 0 : a);
      } : KEY == 'add' ? function add(a) { fn.call(this, a === 0 ? 0 : a); return this; }
        : function set(a, b) { fn.call(this, a === 0 ? 0 : a, b); return this; }
    );
  };
  if (typeof C != 'function' || !(IS_WEAK || proto.forEach && !fails(function () {
    new C().entries().next();
  }))) {
    // create collection constructor
    C = common.getConstructor(wrapper, NAME, IS_MAP, ADDER);
    redefineAll(C.prototype, methods);
    meta.NEED = true;
  } else {
    var instance = new C();
    // early implementations not supports chaining
    var HASNT_CHAINING = instance[ADDER](IS_WEAK ? {} : -0, 1) != instance;
    // V8 ~  Chromium 40- weak-collections throws on primitives, but should return false
    var THROWS_ON_PRIMITIVES = fails(function () { instance.has(1); });
    // most early implementations doesn't supports iterables, most modern - not close it correctly
    var ACCEPT_ITERABLES = $iterDetect(function (iter) { new C(iter); }); // eslint-disable-line no-new
    // for early implementations -0 and +0 not the same
    var BUGGY_ZERO = !IS_WEAK && fails(function () {
      // V8 ~ Chromium 42- fails only with 5+ elements
      var $instance = new C();
      var index = 5;
      while (index--) $instance[ADDER](index, index);
      return !$instance.has(-0);
    });
    if (!ACCEPT_ITERABLES) {
      C = wrapper(function (target, iterable) {
        anInstance(target, C, NAME);
        var that = inheritIfRequired(new Base(), target, C);
        if (iterable != undefined) forOf(iterable, IS_MAP, that[ADDER], that);
        return that;
      });
      C.prototype = proto;
      proto.constructor = C;
    }
    if (THROWS_ON_PRIMITIVES || BUGGY_ZERO) {
      fixMethod('delete');
      fixMethod('has');
      IS_MAP && fixMethod('get');
    }
    if (BUGGY_ZERO || HASNT_CHAINING) fixMethod(ADDER);
    // weak collections should not contains .clear method
    if (IS_WEAK && proto.clear) delete proto.clear;
  }

  setToStringTag(C, NAME);

  O[NAME] = C;
  $export($export.G + $export.W + $export.F * (C != Base), O);

  if (!IS_WEAK) common.setStrong(C, NAME, IS_MAP);

  return C;
};

},{"./_an-instance":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_an-instance.js","./_export":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_export.js","./_fails":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_fails.js","./_for-of":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_for-of.js","./_global":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_global.js","./_inherit-if-required":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_inherit-if-required.js","./_is-object":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_is-object.js","./_iter-detect":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_iter-detect.js","./_meta":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_meta.js","./_redefine":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_redefine.js","./_redefine-all":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_redefine-all.js","./_set-to-string-tag":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_set-to-string-tag.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_core.js":[function(require,module,exports){
var core = module.exports = { version: '2.5.3' };
if (typeof __e == 'number') __e = core; // eslint-disable-line no-undef

},{}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_create-property.js":[function(require,module,exports){
'use strict';
var $defineProperty = require('./_object-dp');
var createDesc = require('./_property-desc');

module.exports = function (object, index, value) {
  if (index in object) $defineProperty.f(object, index, createDesc(0, value));
  else object[index] = value;
};

},{"./_object-dp":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_object-dp.js","./_property-desc":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_property-desc.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_ctx.js":[function(require,module,exports){
// optional / simple context binding
var aFunction = require('./_a-function');
module.exports = function (fn, that, length) {
  aFunction(fn);
  if (that === undefined) return fn;
  switch (length) {
    case 1: return function (a) {
      return fn.call(that, a);
    };
    case 2: return function (a, b) {
      return fn.call(that, a, b);
    };
    case 3: return function (a, b, c) {
      return fn.call(that, a, b, c);
    };
  }
  return function (/* ...args */) {
    return fn.apply(that, arguments);
  };
};

},{"./_a-function":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_a-function.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_defined.js":[function(require,module,exports){
// 7.2.1 RequireObjectCoercible(argument)
module.exports = function (it) {
  if (it == undefined) throw TypeError("Can't call method on  " + it);
  return it;
};

},{}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_descriptors.js":[function(require,module,exports){
// Thank's IE8 for his funny defineProperty
module.exports = !require('./_fails')(function () {
  return Object.defineProperty({}, 'a', { get: function () { return 7; } }).a != 7;
});

},{"./_fails":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_fails.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_dom-create.js":[function(require,module,exports){
var isObject = require('./_is-object');
var document = require('./_global').document;
// typeof document.createElement is 'object' in old IE
var is = isObject(document) && isObject(document.createElement);
module.exports = function (it) {
  return is ? document.createElement(it) : {};
};

},{"./_global":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_global.js","./_is-object":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_is-object.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_enum-bug-keys.js":[function(require,module,exports){
// IE 8- don't enum bug keys
module.exports = (
  'constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf'
).split(',');

},{}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_enum-keys.js":[function(require,module,exports){
// all enumerable object keys, includes symbols
var getKeys = require('./_object-keys');
var gOPS = require('./_object-gops');
var pIE = require('./_object-pie');
module.exports = function (it) {
  var result = getKeys(it);
  var getSymbols = gOPS.f;
  if (getSymbols) {
    var symbols = getSymbols(it);
    var isEnum = pIE.f;
    var i = 0;
    var key;
    while (symbols.length > i) if (isEnum.call(it, key = symbols[i++])) result.push(key);
  } return result;
};

},{"./_object-gops":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_object-gops.js","./_object-keys":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_object-keys.js","./_object-pie":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_object-pie.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_export.js":[function(require,module,exports){
var global = require('./_global');
var core = require('./_core');
var hide = require('./_hide');
var redefine = require('./_redefine');
var ctx = require('./_ctx');
var PROTOTYPE = 'prototype';

var $export = function (type, name, source) {
  var IS_FORCED = type & $export.F;
  var IS_GLOBAL = type & $export.G;
  var IS_STATIC = type & $export.S;
  var IS_PROTO = type & $export.P;
  var IS_BIND = type & $export.B;
  var target = IS_GLOBAL ? global : IS_STATIC ? global[name] || (global[name] = {}) : (global[name] || {})[PROTOTYPE];
  var exports = IS_GLOBAL ? core : core[name] || (core[name] = {});
  var expProto = exports[PROTOTYPE] || (exports[PROTOTYPE] = {});
  var key, own, out, exp;
  if (IS_GLOBAL) source = name;
  for (key in source) {
    // contains in native
    own = !IS_FORCED && target && target[key] !== undefined;
    // export native or passed
    out = (own ? target : source)[key];
    // bind timers to global for call from export context
    exp = IS_BIND && own ? ctx(out, global) : IS_PROTO && typeof out == 'function' ? ctx(Function.call, out) : out;
    // extend global
    if (target) redefine(target, key, out, type & $export.U);
    // export
    if (exports[key] != out) hide(exports, key, exp);
    if (IS_PROTO && expProto[key] != out) expProto[key] = out;
  }
};
global.core = core;
// type bitmap
$export.F = 1;   // forced
$export.G = 2;   // global
$export.S = 4;   // static
$export.P = 8;   // proto
$export.B = 16;  // bind
$export.W = 32;  // wrap
$export.U = 64;  // safe
$export.R = 128; // real proto method for `library`
module.exports = $export;

},{"./_core":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_core.js","./_ctx":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_ctx.js","./_global":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_global.js","./_hide":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_hide.js","./_redefine":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_redefine.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_fails-is-regexp.js":[function(require,module,exports){
var MATCH = require('./_wks')('match');
module.exports = function (KEY) {
  var re = /./;
  try {
    '/./'[KEY](re);
  } catch (e) {
    try {
      re[MATCH] = false;
      return !'/./'[KEY](re);
    } catch (f) { /* empty */ }
  } return true;
};

},{"./_wks":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_wks.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_fails.js":[function(require,module,exports){
module.exports = function (exec) {
  try {
    return !!exec();
  } catch (e) {
    return true;
  }
};

},{}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_for-of.js":[function(require,module,exports){
var ctx = require('./_ctx');
var call = require('./_iter-call');
var isArrayIter = require('./_is-array-iter');
var anObject = require('./_an-object');
var toLength = require('./_to-length');
var getIterFn = require('./core.get-iterator-method');
var BREAK = {};
var RETURN = {};
var exports = module.exports = function (iterable, entries, fn, that, ITERATOR) {
  var iterFn = ITERATOR ? function () { return iterable; } : getIterFn(iterable);
  var f = ctx(fn, that, entries ? 2 : 1);
  var index = 0;
  var length, step, iterator, result;
  if (typeof iterFn != 'function') throw TypeError(iterable + ' is not iterable!');
  // fast case for arrays with default iterator
  if (isArrayIter(iterFn)) for (length = toLength(iterable.length); length > index; index++) {
    result = entries ? f(anObject(step = iterable[index])[0], step[1]) : f(iterable[index]);
    if (result === BREAK || result === RETURN) return result;
  } else for (iterator = iterFn.call(iterable); !(step = iterator.next()).done;) {
    result = call(iterator, f, step.value, entries);
    if (result === BREAK || result === RETURN) return result;
  }
};
exports.BREAK = BREAK;
exports.RETURN = RETURN;

},{"./_an-object":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_an-object.js","./_ctx":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_ctx.js","./_is-array-iter":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_is-array-iter.js","./_iter-call":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_iter-call.js","./_to-length":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_to-length.js","./core.get-iterator-method":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/core.get-iterator-method.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_global.js":[function(require,module,exports){
// https://github.com/zloirock/core-js/issues/86#issuecomment-115759028
var global = module.exports = typeof window != 'undefined' && window.Math == Math
  ? window : typeof self != 'undefined' && self.Math == Math ? self
  // eslint-disable-next-line no-new-func
  : Function('return this')();
if (typeof __g == 'number') __g = global; // eslint-disable-line no-undef

},{}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_has.js":[function(require,module,exports){
var hasOwnProperty = {}.hasOwnProperty;
module.exports = function (it, key) {
  return hasOwnProperty.call(it, key);
};

},{}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_hide.js":[function(require,module,exports){
var dP = require('./_object-dp');
var createDesc = require('./_property-desc');
module.exports = require('./_descriptors') ? function (object, key, value) {
  return dP.f(object, key, createDesc(1, value));
} : function (object, key, value) {
  object[key] = value;
  return object;
};

},{"./_descriptors":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_descriptors.js","./_object-dp":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_object-dp.js","./_property-desc":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_property-desc.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_html.js":[function(require,module,exports){
var document = require('./_global').document;
module.exports = document && document.documentElement;

},{"./_global":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_global.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_ie8-dom-define.js":[function(require,module,exports){
module.exports = !require('./_descriptors') && !require('./_fails')(function () {
  return Object.defineProperty(require('./_dom-create')('div'), 'a', { get: function () { return 7; } }).a != 7;
});

},{"./_descriptors":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_descriptors.js","./_dom-create":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_dom-create.js","./_fails":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_fails.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_inherit-if-required.js":[function(require,module,exports){
var isObject = require('./_is-object');
var setPrototypeOf = require('./_set-proto').set;
module.exports = function (that, target, C) {
  var S = target.constructor;
  var P;
  if (S !== C && typeof S == 'function' && (P = S.prototype) !== C.prototype && isObject(P) && setPrototypeOf) {
    setPrototypeOf(that, P);
  } return that;
};

},{"./_is-object":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_is-object.js","./_set-proto":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_set-proto.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_iobject.js":[function(require,module,exports){
// fallback for non-array-like ES3 and non-enumerable old V8 strings
var cof = require('./_cof');
// eslint-disable-next-line no-prototype-builtins
module.exports = Object('z').propertyIsEnumerable(0) ? Object : function (it) {
  return cof(it) == 'String' ? it.split('') : Object(it);
};

},{"./_cof":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_cof.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_is-array-iter.js":[function(require,module,exports){
// check on default Array iterator
var Iterators = require('./_iterators');
var ITERATOR = require('./_wks')('iterator');
var ArrayProto = Array.prototype;

module.exports = function (it) {
  return it !== undefined && (Iterators.Array === it || ArrayProto[ITERATOR] === it);
};

},{"./_iterators":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_iterators.js","./_wks":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_wks.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_is-array.js":[function(require,module,exports){
// 7.2.2 IsArray(argument)
var cof = require('./_cof');
module.exports = Array.isArray || function isArray(arg) {
  return cof(arg) == 'Array';
};

},{"./_cof":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_cof.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_is-object.js":[function(require,module,exports){
module.exports = function (it) {
  return typeof it === 'object' ? it !== null : typeof it === 'function';
};

},{}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_is-regexp.js":[function(require,module,exports){
// 7.2.8 IsRegExp(argument)
var isObject = require('./_is-object');
var cof = require('./_cof');
var MATCH = require('./_wks')('match');
module.exports = function (it) {
  var isRegExp;
  return isObject(it) && ((isRegExp = it[MATCH]) !== undefined ? !!isRegExp : cof(it) == 'RegExp');
};

},{"./_cof":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_cof.js","./_is-object":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_is-object.js","./_wks":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_wks.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_iter-call.js":[function(require,module,exports){
// call something on iterator step with safe closing on error
var anObject = require('./_an-object');
module.exports = function (iterator, fn, value, entries) {
  try {
    return entries ? fn(anObject(value)[0], value[1]) : fn(value);
  // 7.4.6 IteratorClose(iterator, completion)
  } catch (e) {
    var ret = iterator['return'];
    if (ret !== undefined) anObject(ret.call(iterator));
    throw e;
  }
};

},{"./_an-object":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_an-object.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_iter-create.js":[function(require,module,exports){
'use strict';
var create = require('./_object-create');
var descriptor = require('./_property-desc');
var setToStringTag = require('./_set-to-string-tag');
var IteratorPrototype = {};

// 25.1.2.1.1 %IteratorPrototype%[@@iterator]()
require('./_hide')(IteratorPrototype, require('./_wks')('iterator'), function () { return this; });

module.exports = function (Constructor, NAME, next) {
  Constructor.prototype = create(IteratorPrototype, { next: descriptor(1, next) });
  setToStringTag(Constructor, NAME + ' Iterator');
};

},{"./_hide":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_hide.js","./_object-create":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_object-create.js","./_property-desc":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_property-desc.js","./_set-to-string-tag":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_set-to-string-tag.js","./_wks":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_wks.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_iter-define.js":[function(require,module,exports){
'use strict';
var LIBRARY = require('./_library');
var $export = require('./_export');
var redefine = require('./_redefine');
var hide = require('./_hide');
var has = require('./_has');
var Iterators = require('./_iterators');
var $iterCreate = require('./_iter-create');
var setToStringTag = require('./_set-to-string-tag');
var getPrototypeOf = require('./_object-gpo');
var ITERATOR = require('./_wks')('iterator');
var BUGGY = !([].keys && 'next' in [].keys()); // Safari has buggy iterators w/o `next`
var FF_ITERATOR = '@@iterator';
var KEYS = 'keys';
var VALUES = 'values';

var returnThis = function () { return this; };

module.exports = function (Base, NAME, Constructor, next, DEFAULT, IS_SET, FORCED) {
  $iterCreate(Constructor, NAME, next);
  var getMethod = function (kind) {
    if (!BUGGY && kind in proto) return proto[kind];
    switch (kind) {
      case KEYS: return function keys() { return new Constructor(this, kind); };
      case VALUES: return function values() { return new Constructor(this, kind); };
    } return function entries() { return new Constructor(this, kind); };
  };
  var TAG = NAME + ' Iterator';
  var DEF_VALUES = DEFAULT == VALUES;
  var VALUES_BUG = false;
  var proto = Base.prototype;
  var $native = proto[ITERATOR] || proto[FF_ITERATOR] || DEFAULT && proto[DEFAULT];
  var $default = (!BUGGY && $native) || getMethod(DEFAULT);
  var $entries = DEFAULT ? !DEF_VALUES ? $default : getMethod('entries') : undefined;
  var $anyNative = NAME == 'Array' ? proto.entries || $native : $native;
  var methods, key, IteratorPrototype;
  // Fix native
  if ($anyNative) {
    IteratorPrototype = getPrototypeOf($anyNative.call(new Base()));
    if (IteratorPrototype !== Object.prototype && IteratorPrototype.next) {
      // Set @@toStringTag to native iterators
      setToStringTag(IteratorPrototype, TAG, true);
      // fix for some old engines
      if (!LIBRARY && !has(IteratorPrototype, ITERATOR)) hide(IteratorPrototype, ITERATOR, returnThis);
    }
  }
  // fix Array#{values, @@iterator}.name in V8 / FF
  if (DEF_VALUES && $native && $native.name !== VALUES) {
    VALUES_BUG = true;
    $default = function values() { return $native.call(this); };
  }
  // Define iterator
  if ((!LIBRARY || FORCED) && (BUGGY || VALUES_BUG || !proto[ITERATOR])) {
    hide(proto, ITERATOR, $default);
  }
  // Plug for library
  Iterators[NAME] = $default;
  Iterators[TAG] = returnThis;
  if (DEFAULT) {
    methods = {
      values: DEF_VALUES ? $default : getMethod(VALUES),
      keys: IS_SET ? $default : getMethod(KEYS),
      entries: $entries
    };
    if (FORCED) for (key in methods) {
      if (!(key in proto)) redefine(proto, key, methods[key]);
    } else $export($export.P + $export.F * (BUGGY || VALUES_BUG), NAME, methods);
  }
  return methods;
};

},{"./_export":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_export.js","./_has":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_has.js","./_hide":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_hide.js","./_iter-create":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_iter-create.js","./_iterators":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_iterators.js","./_library":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_library.js","./_object-gpo":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_object-gpo.js","./_redefine":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_redefine.js","./_set-to-string-tag":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_set-to-string-tag.js","./_wks":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_wks.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_iter-detect.js":[function(require,module,exports){
var ITERATOR = require('./_wks')('iterator');
var SAFE_CLOSING = false;

try {
  var riter = [7][ITERATOR]();
  riter['return'] = function () { SAFE_CLOSING = true; };
  // eslint-disable-next-line no-throw-literal
  Array.from(riter, function () { throw 2; });
} catch (e) { /* empty */ }

module.exports = function (exec, skipClosing) {
  if (!skipClosing && !SAFE_CLOSING) return false;
  var safe = false;
  try {
    var arr = [7];
    var iter = arr[ITERATOR]();
    iter.next = function () { return { done: safe = true }; };
    arr[ITERATOR] = function () { return iter; };
    exec(arr);
  } catch (e) { /* empty */ }
  return safe;
};

},{"./_wks":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_wks.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_iter-step.js":[function(require,module,exports){
module.exports = function (done, value) {
  return { value: value, done: !!done };
};

},{}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_iterators.js":[function(require,module,exports){
module.exports = {};

},{}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_library.js":[function(require,module,exports){
module.exports = false;

},{}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_meta.js":[function(require,module,exports){
var META = require('./_uid')('meta');
var isObject = require('./_is-object');
var has = require('./_has');
var setDesc = require('./_object-dp').f;
var id = 0;
var isExtensible = Object.isExtensible || function () {
  return true;
};
var FREEZE = !require('./_fails')(function () {
  return isExtensible(Object.preventExtensions({}));
});
var setMeta = function (it) {
  setDesc(it, META, { value: {
    i: 'O' + ++id, // object ID
    w: {}          // weak collections IDs
  } });
};
var fastKey = function (it, create) {
  // return primitive with prefix
  if (!isObject(it)) return typeof it == 'symbol' ? it : (typeof it == 'string' ? 'S' : 'P') + it;
  if (!has(it, META)) {
    // can't set metadata to uncaught frozen object
    if (!isExtensible(it)) return 'F';
    // not necessary to add metadata
    if (!create) return 'E';
    // add missing metadata
    setMeta(it);
  // return object ID
  } return it[META].i;
};
var getWeak = function (it, create) {
  if (!has(it, META)) {
    // can't set metadata to uncaught frozen object
    if (!isExtensible(it)) return true;
    // not necessary to add metadata
    if (!create) return false;
    // add missing metadata
    setMeta(it);
  // return hash weak collections IDs
  } return it[META].w;
};
// add metadata on freeze-family methods calling
var onFreeze = function (it) {
  if (FREEZE && meta.NEED && isExtensible(it) && !has(it, META)) setMeta(it);
  return it;
};
var meta = module.exports = {
  KEY: META,
  NEED: false,
  fastKey: fastKey,
  getWeak: getWeak,
  onFreeze: onFreeze
};

},{"./_fails":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_fails.js","./_has":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_has.js","./_is-object":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_is-object.js","./_object-dp":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_object-dp.js","./_uid":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_uid.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_object-create.js":[function(require,module,exports){
// 19.1.2.2 / 15.2.3.5 Object.create(O [, Properties])
var anObject = require('./_an-object');
var dPs = require('./_object-dps');
var enumBugKeys = require('./_enum-bug-keys');
var IE_PROTO = require('./_shared-key')('IE_PROTO');
var Empty = function () { /* empty */ };
var PROTOTYPE = 'prototype';

// Create object with fake `null` prototype: use iframe Object with cleared prototype
var createDict = function () {
  // Thrash, waste and sodomy: IE GC bug
  var iframe = require('./_dom-create')('iframe');
  var i = enumBugKeys.length;
  var lt = '<';
  var gt = '>';
  var iframeDocument;
  iframe.style.display = 'none';
  require('./_html').appendChild(iframe);
  iframe.src = 'javascript:'; // eslint-disable-line no-script-url
  // createDict = iframe.contentWindow.Object;
  // html.removeChild(iframe);
  iframeDocument = iframe.contentWindow.document;
  iframeDocument.open();
  iframeDocument.write(lt + 'script' + gt + 'document.F=Object' + lt + '/script' + gt);
  iframeDocument.close();
  createDict = iframeDocument.F;
  while (i--) delete createDict[PROTOTYPE][enumBugKeys[i]];
  return createDict();
};

module.exports = Object.create || function create(O, Properties) {
  var result;
  if (O !== null) {
    Empty[PROTOTYPE] = anObject(O);
    result = new Empty();
    Empty[PROTOTYPE] = null;
    // add "__proto__" for Object.getPrototypeOf polyfill
    result[IE_PROTO] = O;
  } else result = createDict();
  return Properties === undefined ? result : dPs(result, Properties);
};

},{"./_an-object":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_an-object.js","./_dom-create":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_dom-create.js","./_enum-bug-keys":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_enum-bug-keys.js","./_html":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_html.js","./_object-dps":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_object-dps.js","./_shared-key":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_shared-key.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_object-dp.js":[function(require,module,exports){
var anObject = require('./_an-object');
var IE8_DOM_DEFINE = require('./_ie8-dom-define');
var toPrimitive = require('./_to-primitive');
var dP = Object.defineProperty;

exports.f = require('./_descriptors') ? Object.defineProperty : function defineProperty(O, P, Attributes) {
  anObject(O);
  P = toPrimitive(P, true);
  anObject(Attributes);
  if (IE8_DOM_DEFINE) try {
    return dP(O, P, Attributes);
  } catch (e) { /* empty */ }
  if ('get' in Attributes || 'set' in Attributes) throw TypeError('Accessors not supported!');
  if ('value' in Attributes) O[P] = Attributes.value;
  return O;
};

},{"./_an-object":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_an-object.js","./_descriptors":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_descriptors.js","./_ie8-dom-define":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_ie8-dom-define.js","./_to-primitive":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_to-primitive.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_object-dps.js":[function(require,module,exports){
var dP = require('./_object-dp');
var anObject = require('./_an-object');
var getKeys = require('./_object-keys');

module.exports = require('./_descriptors') ? Object.defineProperties : function defineProperties(O, Properties) {
  anObject(O);
  var keys = getKeys(Properties);
  var length = keys.length;
  var i = 0;
  var P;
  while (length > i) dP.f(O, P = keys[i++], Properties[P]);
  return O;
};

},{"./_an-object":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_an-object.js","./_descriptors":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_descriptors.js","./_object-dp":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_object-dp.js","./_object-keys":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_object-keys.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_object-gopd.js":[function(require,module,exports){
var pIE = require('./_object-pie');
var createDesc = require('./_property-desc');
var toIObject = require('./_to-iobject');
var toPrimitive = require('./_to-primitive');
var has = require('./_has');
var IE8_DOM_DEFINE = require('./_ie8-dom-define');
var gOPD = Object.getOwnPropertyDescriptor;

exports.f = require('./_descriptors') ? gOPD : function getOwnPropertyDescriptor(O, P) {
  O = toIObject(O);
  P = toPrimitive(P, true);
  if (IE8_DOM_DEFINE) try {
    return gOPD(O, P);
  } catch (e) { /* empty */ }
  if (has(O, P)) return createDesc(!pIE.f.call(O, P), O[P]);
};

},{"./_descriptors":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_descriptors.js","./_has":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_has.js","./_ie8-dom-define":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_ie8-dom-define.js","./_object-pie":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_object-pie.js","./_property-desc":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_property-desc.js","./_to-iobject":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_to-iobject.js","./_to-primitive":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_to-primitive.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_object-gopn-ext.js":[function(require,module,exports){
// fallback for IE11 buggy Object.getOwnPropertyNames with iframe and window
var toIObject = require('./_to-iobject');
var gOPN = require('./_object-gopn').f;
var toString = {}.toString;

var windowNames = typeof window == 'object' && window && Object.getOwnPropertyNames
  ? Object.getOwnPropertyNames(window) : [];

var getWindowNames = function (it) {
  try {
    return gOPN(it);
  } catch (e) {
    return windowNames.slice();
  }
};

module.exports.f = function getOwnPropertyNames(it) {
  return windowNames && toString.call(it) == '[object Window]' ? getWindowNames(it) : gOPN(toIObject(it));
};

},{"./_object-gopn":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_object-gopn.js","./_to-iobject":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_to-iobject.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_object-gopn.js":[function(require,module,exports){
// 19.1.2.7 / 15.2.3.4 Object.getOwnPropertyNames(O)
var $keys = require('./_object-keys-internal');
var hiddenKeys = require('./_enum-bug-keys').concat('length', 'prototype');

exports.f = Object.getOwnPropertyNames || function getOwnPropertyNames(O) {
  return $keys(O, hiddenKeys);
};

},{"./_enum-bug-keys":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_enum-bug-keys.js","./_object-keys-internal":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_object-keys-internal.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_object-gops.js":[function(require,module,exports){
exports.f = Object.getOwnPropertySymbols;

},{}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_object-gpo.js":[function(require,module,exports){
// 19.1.2.9 / 15.2.3.2 Object.getPrototypeOf(O)
var has = require('./_has');
var toObject = require('./_to-object');
var IE_PROTO = require('./_shared-key')('IE_PROTO');
var ObjectProto = Object.prototype;

module.exports = Object.getPrototypeOf || function (O) {
  O = toObject(O);
  if (has(O, IE_PROTO)) return O[IE_PROTO];
  if (typeof O.constructor == 'function' && O instanceof O.constructor) {
    return O.constructor.prototype;
  } return O instanceof Object ? ObjectProto : null;
};

},{"./_has":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_has.js","./_shared-key":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_shared-key.js","./_to-object":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_to-object.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_object-keys-internal.js":[function(require,module,exports){
var has = require('./_has');
var toIObject = require('./_to-iobject');
var arrayIndexOf = require('./_array-includes')(false);
var IE_PROTO = require('./_shared-key')('IE_PROTO');

module.exports = function (object, names) {
  var O = toIObject(object);
  var i = 0;
  var result = [];
  var key;
  for (key in O) if (key != IE_PROTO) has(O, key) && result.push(key);
  // Don't enum bug & hidden keys
  while (names.length > i) if (has(O, key = names[i++])) {
    ~arrayIndexOf(result, key) || result.push(key);
  }
  return result;
};

},{"./_array-includes":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_array-includes.js","./_has":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_has.js","./_shared-key":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_shared-key.js","./_to-iobject":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_to-iobject.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_object-keys.js":[function(require,module,exports){
// 19.1.2.14 / 15.2.3.14 Object.keys(O)
var $keys = require('./_object-keys-internal');
var enumBugKeys = require('./_enum-bug-keys');

module.exports = Object.keys || function keys(O) {
  return $keys(O, enumBugKeys);
};

},{"./_enum-bug-keys":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_enum-bug-keys.js","./_object-keys-internal":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_object-keys-internal.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_object-pie.js":[function(require,module,exports){
exports.f = {}.propertyIsEnumerable;

},{}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_property-desc.js":[function(require,module,exports){
module.exports = function (bitmap, value) {
  return {
    enumerable: !(bitmap & 1),
    configurable: !(bitmap & 2),
    writable: !(bitmap & 4),
    value: value
  };
};

},{}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_redefine-all.js":[function(require,module,exports){
var redefine = require('./_redefine');
module.exports = function (target, src, safe) {
  for (var key in src) redefine(target, key, src[key], safe);
  return target;
};

},{"./_redefine":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_redefine.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_redefine.js":[function(require,module,exports){
var global = require('./_global');
var hide = require('./_hide');
var has = require('./_has');
var SRC = require('./_uid')('src');
var TO_STRING = 'toString';
var $toString = Function[TO_STRING];
var TPL = ('' + $toString).split(TO_STRING);

require('./_core').inspectSource = function (it) {
  return $toString.call(it);
};

(module.exports = function (O, key, val, safe) {
  var isFunction = typeof val == 'function';
  if (isFunction) has(val, 'name') || hide(val, 'name', key);
  if (O[key] === val) return;
  if (isFunction) has(val, SRC) || hide(val, SRC, O[key] ? '' + O[key] : TPL.join(String(key)));
  if (O === global) {
    O[key] = val;
  } else if (!safe) {
    delete O[key];
    hide(O, key, val);
  } else if (O[key]) {
    O[key] = val;
  } else {
    hide(O, key, val);
  }
// add fake Function#toString for correct work wrapped methods / constructors with methods like LoDash isNative
})(Function.prototype, TO_STRING, function toString() {
  return typeof this == 'function' && this[SRC] || $toString.call(this);
});

},{"./_core":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_core.js","./_global":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_global.js","./_has":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_has.js","./_hide":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_hide.js","./_uid":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_uid.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_same-value.js":[function(require,module,exports){
// 7.2.9 SameValue(x, y)
module.exports = Object.is || function is(x, y) {
  // eslint-disable-next-line no-self-compare
  return x === y ? x !== 0 || 1 / x === 1 / y : x != x && y != y;
};

},{}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_set-proto.js":[function(require,module,exports){
// Works with __proto__ only. Old v8 can't work with null proto objects.
/* eslint-disable no-proto */
var isObject = require('./_is-object');
var anObject = require('./_an-object');
var check = function (O, proto) {
  anObject(O);
  if (!isObject(proto) && proto !== null) throw TypeError(proto + ": can't set as prototype!");
};
module.exports = {
  set: Object.setPrototypeOf || ('__proto__' in {} ? // eslint-disable-line
    function (test, buggy, set) {
      try {
        set = require('./_ctx')(Function.call, require('./_object-gopd').f(Object.prototype, '__proto__').set, 2);
        set(test, []);
        buggy = !(test instanceof Array);
      } catch (e) { buggy = true; }
      return function setPrototypeOf(O, proto) {
        check(O, proto);
        if (buggy) O.__proto__ = proto;
        else set(O, proto);
        return O;
      };
    }({}, false) : undefined),
  check: check
};

},{"./_an-object":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_an-object.js","./_ctx":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_ctx.js","./_is-object":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_is-object.js","./_object-gopd":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_object-gopd.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_set-species.js":[function(require,module,exports){
'use strict';
var global = require('./_global');
var dP = require('./_object-dp');
var DESCRIPTORS = require('./_descriptors');
var SPECIES = require('./_wks')('species');

module.exports = function (KEY) {
  var C = global[KEY];
  if (DESCRIPTORS && C && !C[SPECIES]) dP.f(C, SPECIES, {
    configurable: true,
    get: function () { return this; }
  });
};

},{"./_descriptors":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_descriptors.js","./_global":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_global.js","./_object-dp":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_object-dp.js","./_wks":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_wks.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_set-to-string-tag.js":[function(require,module,exports){
var def = require('./_object-dp').f;
var has = require('./_has');
var TAG = require('./_wks')('toStringTag');

module.exports = function (it, tag, stat) {
  if (it && !has(it = stat ? it : it.prototype, TAG)) def(it, TAG, { configurable: true, value: tag });
};

},{"./_has":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_has.js","./_object-dp":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_object-dp.js","./_wks":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_wks.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_shared-key.js":[function(require,module,exports){
var shared = require('./_shared')('keys');
var uid = require('./_uid');
module.exports = function (key) {
  return shared[key] || (shared[key] = uid(key));
};

},{"./_shared":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_shared.js","./_uid":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_uid.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_shared.js":[function(require,module,exports){
var global = require('./_global');
var SHARED = '__core-js_shared__';
var store = global[SHARED] || (global[SHARED] = {});
module.exports = function (key) {
  return store[key] || (store[key] = {});
};

},{"./_global":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_global.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_string-at.js":[function(require,module,exports){
var toInteger = require('./_to-integer');
var defined = require('./_defined');
// true  -> String#at
// false -> String#codePointAt
module.exports = function (TO_STRING) {
  return function (that, pos) {
    var s = String(defined(that));
    var i = toInteger(pos);
    var l = s.length;
    var a, b;
    if (i < 0 || i >= l) return TO_STRING ? '' : undefined;
    a = s.charCodeAt(i);
    return a < 0xd800 || a > 0xdbff || i + 1 === l || (b = s.charCodeAt(i + 1)) < 0xdc00 || b > 0xdfff
      ? TO_STRING ? s.charAt(i) : a
      : TO_STRING ? s.slice(i, i + 2) : (a - 0xd800 << 10) + (b - 0xdc00) + 0x10000;
  };
};

},{"./_defined":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_defined.js","./_to-integer":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_to-integer.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_string-context.js":[function(require,module,exports){
// helper for String#{startsWith, endsWith, includes}
var isRegExp = require('./_is-regexp');
var defined = require('./_defined');

module.exports = function (that, searchString, NAME) {
  if (isRegExp(searchString)) throw TypeError('String#' + NAME + " doesn't accept regex!");
  return String(defined(that));
};

},{"./_defined":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_defined.js","./_is-regexp":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_is-regexp.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_to-absolute-index.js":[function(require,module,exports){
var toInteger = require('./_to-integer');
var max = Math.max;
var min = Math.min;
module.exports = function (index, length) {
  index = toInteger(index);
  return index < 0 ? max(index + length, 0) : min(index, length);
};

},{"./_to-integer":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_to-integer.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_to-integer.js":[function(require,module,exports){
// 7.1.4 ToInteger
var ceil = Math.ceil;
var floor = Math.floor;
module.exports = function (it) {
  return isNaN(it = +it) ? 0 : (it > 0 ? floor : ceil)(it);
};

},{}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_to-iobject.js":[function(require,module,exports){
// to indexed object, toObject with fallback for non-array-like ES3 strings
var IObject = require('./_iobject');
var defined = require('./_defined');
module.exports = function (it) {
  return IObject(defined(it));
};

},{"./_defined":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_defined.js","./_iobject":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_iobject.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_to-length.js":[function(require,module,exports){
// 7.1.15 ToLength
var toInteger = require('./_to-integer');
var min = Math.min;
module.exports = function (it) {
  return it > 0 ? min(toInteger(it), 0x1fffffffffffff) : 0; // pow(2, 53) - 1 == 9007199254740991
};

},{"./_to-integer":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_to-integer.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_to-object.js":[function(require,module,exports){
// 7.1.13 ToObject(argument)
var defined = require('./_defined');
module.exports = function (it) {
  return Object(defined(it));
};

},{"./_defined":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_defined.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_to-primitive.js":[function(require,module,exports){
// 7.1.1 ToPrimitive(input [, PreferredType])
var isObject = require('./_is-object');
// instead of the ES6 spec version, we didn't implement @@toPrimitive case
// and the second argument - flag - preferred type is a string
module.exports = function (it, S) {
  if (!isObject(it)) return it;
  var fn, val;
  if (S && typeof (fn = it.toString) == 'function' && !isObject(val = fn.call(it))) return val;
  if (typeof (fn = it.valueOf) == 'function' && !isObject(val = fn.call(it))) return val;
  if (!S && typeof (fn = it.toString) == 'function' && !isObject(val = fn.call(it))) return val;
  throw TypeError("Can't convert object to primitive value");
};

},{"./_is-object":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_is-object.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_uid.js":[function(require,module,exports){
var id = 0;
var px = Math.random();
module.exports = function (key) {
  return 'Symbol('.concat(key === undefined ? '' : key, ')_', (++id + px).toString(36));
};

},{}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_validate-collection.js":[function(require,module,exports){
var isObject = require('./_is-object');
module.exports = function (it, TYPE) {
  if (!isObject(it) || it._t !== TYPE) throw TypeError('Incompatible receiver, ' + TYPE + ' required!');
  return it;
};

},{"./_is-object":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_is-object.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_wks-define.js":[function(require,module,exports){
var global = require('./_global');
var core = require('./_core');
var LIBRARY = require('./_library');
var wksExt = require('./_wks-ext');
var defineProperty = require('./_object-dp').f;
module.exports = function (name) {
  var $Symbol = core.Symbol || (core.Symbol = LIBRARY ? {} : global.Symbol || {});
  if (name.charAt(0) != '_' && !(name in $Symbol)) defineProperty($Symbol, name, { value: wksExt.f(name) });
};

},{"./_core":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_core.js","./_global":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_global.js","./_library":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_library.js","./_object-dp":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_object-dp.js","./_wks-ext":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_wks-ext.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_wks-ext.js":[function(require,module,exports){
exports.f = require('./_wks');

},{"./_wks":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_wks.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_wks.js":[function(require,module,exports){
var store = require('./_shared')('wks');
var uid = require('./_uid');
var Symbol = require('./_global').Symbol;
var USE_SYMBOL = typeof Symbol == 'function';

var $exports = module.exports = function (name) {
  return store[name] || (store[name] =
    USE_SYMBOL && Symbol[name] || (USE_SYMBOL ? Symbol : uid)('Symbol.' + name));
};

$exports.store = store;

},{"./_global":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_global.js","./_shared":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_shared.js","./_uid":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_uid.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/core.get-iterator-method.js":[function(require,module,exports){
var classof = require('./_classof');
var ITERATOR = require('./_wks')('iterator');
var Iterators = require('./_iterators');
module.exports = require('./_core').getIteratorMethod = function (it) {
  if (it != undefined) return it[ITERATOR]
    || it['@@iterator']
    || Iterators[classof(it)];
};

},{"./_classof":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_classof.js","./_core":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_core.js","./_iterators":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_iterators.js","./_wks":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_wks.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/es6.array.find-index.js":[function(require,module,exports){
'use strict';
// 22.1.3.9 Array.prototype.findIndex(predicate, thisArg = undefined)
var $export = require('./_export');
var $find = require('./_array-methods')(6);
var KEY = 'findIndex';
var forced = true;
// Shouldn't skip holes
if (KEY in []) Array(1)[KEY](function () { forced = false; });
$export($export.P + $export.F * forced, 'Array', {
  findIndex: function findIndex(callbackfn /* , that = undefined */) {
    return $find(this, callbackfn, arguments.length > 1 ? arguments[1] : undefined);
  }
});
require('./_add-to-unscopables')(KEY);

},{"./_add-to-unscopables":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_add-to-unscopables.js","./_array-methods":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_array-methods.js","./_export":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_export.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/es6.array.find.js":[function(require,module,exports){
'use strict';
// 22.1.3.8 Array.prototype.find(predicate, thisArg = undefined)
var $export = require('./_export');
var $find = require('./_array-methods')(5);
var KEY = 'find';
var forced = true;
// Shouldn't skip holes
if (KEY in []) Array(1)[KEY](function () { forced = false; });
$export($export.P + $export.F * forced, 'Array', {
  find: function find(callbackfn /* , that = undefined */) {
    return $find(this, callbackfn, arguments.length > 1 ? arguments[1] : undefined);
  }
});
require('./_add-to-unscopables')(KEY);

},{"./_add-to-unscopables":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_add-to-unscopables.js","./_array-methods":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_array-methods.js","./_export":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_export.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/es6.array.from.js":[function(require,module,exports){
'use strict';
var ctx = require('./_ctx');
var $export = require('./_export');
var toObject = require('./_to-object');
var call = require('./_iter-call');
var isArrayIter = require('./_is-array-iter');
var toLength = require('./_to-length');
var createProperty = require('./_create-property');
var getIterFn = require('./core.get-iterator-method');

$export($export.S + $export.F * !require('./_iter-detect')(function (iter) { Array.from(iter); }), 'Array', {
  // 22.1.2.1 Array.from(arrayLike, mapfn = undefined, thisArg = undefined)
  from: function from(arrayLike /* , mapfn = undefined, thisArg = undefined */) {
    var O = toObject(arrayLike);
    var C = typeof this == 'function' ? this : Array;
    var aLen = arguments.length;
    var mapfn = aLen > 1 ? arguments[1] : undefined;
    var mapping = mapfn !== undefined;
    var index = 0;
    var iterFn = getIterFn(O);
    var length, result, step, iterator;
    if (mapping) mapfn = ctx(mapfn, aLen > 2 ? arguments[2] : undefined, 2);
    // if object isn't iterable or it's array with default iterator - use simple case
    if (iterFn != undefined && !(C == Array && isArrayIter(iterFn))) {
      for (iterator = iterFn.call(O), result = new C(); !(step = iterator.next()).done; index++) {
        createProperty(result, index, mapping ? call(iterator, mapfn, [step.value, index], true) : step.value);
      }
    } else {
      length = toLength(O.length);
      for (result = new C(length); length > index; index++) {
        createProperty(result, index, mapping ? mapfn(O[index], index) : O[index]);
      }
    }
    result.length = index;
    return result;
  }
});

},{"./_create-property":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_create-property.js","./_ctx":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_ctx.js","./_export":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_export.js","./_is-array-iter":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_is-array-iter.js","./_iter-call":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_iter-call.js","./_iter-detect":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_iter-detect.js","./_to-length":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_to-length.js","./_to-object":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_to-object.js","./core.get-iterator-method":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/core.get-iterator-method.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/es6.array.iterator.js":[function(require,module,exports){
'use strict';
var addToUnscopables = require('./_add-to-unscopables');
var step = require('./_iter-step');
var Iterators = require('./_iterators');
var toIObject = require('./_to-iobject');

// 22.1.3.4 Array.prototype.entries()
// 22.1.3.13 Array.prototype.keys()
// 22.1.3.29 Array.prototype.values()
// 22.1.3.30 Array.prototype[@@iterator]()
module.exports = require('./_iter-define')(Array, 'Array', function (iterated, kind) {
  this._t = toIObject(iterated); // target
  this._i = 0;                   // next index
  this._k = kind;                // kind
// 22.1.5.2.1 %ArrayIteratorPrototype%.next()
}, function () {
  var O = this._t;
  var kind = this._k;
  var index = this._i++;
  if (!O || index >= O.length) {
    this._t = undefined;
    return step(1);
  }
  if (kind == 'keys') return step(0, index);
  if (kind == 'values') return step(0, O[index]);
  return step(0, [index, O[index]]);
}, 'values');

// argumentsList[@@iterator] is %ArrayProto_values% (9.4.4.6, 9.4.4.7)
Iterators.Arguments = Iterators.Array;

addToUnscopables('keys');
addToUnscopables('values');
addToUnscopables('entries');

},{"./_add-to-unscopables":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_add-to-unscopables.js","./_iter-define":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_iter-define.js","./_iter-step":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_iter-step.js","./_iterators":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_iterators.js","./_to-iobject":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_to-iobject.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/es6.array.of.js":[function(require,module,exports){
'use strict';
var $export = require('./_export');
var createProperty = require('./_create-property');

// WebKit Array.of isn't generic
$export($export.S + $export.F * require('./_fails')(function () {
  function F() { /* empty */ }
  return !(Array.of.call(F) instanceof F);
}), 'Array', {
  // 22.1.2.3 Array.of( ...items)
  of: function of(/* ...args */) {
    var index = 0;
    var aLen = arguments.length;
    var result = new (typeof this == 'function' ? this : Array)(aLen);
    while (aLen > index) createProperty(result, index, arguments[index++]);
    result.length = aLen;
    return result;
  }
});

},{"./_create-property":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_create-property.js","./_export":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_export.js","./_fails":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_fails.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/es6.object.is.js":[function(require,module,exports){
// 19.1.3.10 Object.is(value1, value2)
var $export = require('./_export');
$export($export.S, 'Object', { is: require('./_same-value') });

},{"./_export":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_export.js","./_same-value":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_same-value.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/es6.object.to-string.js":[function(require,module,exports){
'use strict';
// 19.1.3.6 Object.prototype.toString()
var classof = require('./_classof');
var test = {};
test[require('./_wks')('toStringTag')] = 'z';
if (test + '' != '[object z]') {
  require('./_redefine')(Object.prototype, 'toString', function toString() {
    return '[object ' + classof(this) + ']';
  }, true);
}

},{"./_classof":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_classof.js","./_redefine":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_redefine.js","./_wks":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_wks.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/es6.set.js":[function(require,module,exports){
'use strict';
var strong = require('./_collection-strong');
var validate = require('./_validate-collection');
var SET = 'Set';

// 23.2 Set Objects
module.exports = require('./_collection')(SET, function (get) {
  return function Set() { return get(this, arguments.length > 0 ? arguments[0] : undefined); };
}, {
  // 23.2.3.1 Set.prototype.add(value)
  add: function add(value) {
    return strong.def(validate(this, SET), value = value === 0 ? 0 : value, value);
  }
}, strong);

},{"./_collection":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_collection.js","./_collection-strong":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_collection-strong.js","./_validate-collection":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_validate-collection.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/es6.string.includes.js":[function(require,module,exports){
// 21.1.3.7 String.prototype.includes(searchString, position = 0)
'use strict';
var $export = require('./_export');
var context = require('./_string-context');
var INCLUDES = 'includes';

$export($export.P + $export.F * require('./_fails-is-regexp')(INCLUDES), 'String', {
  includes: function includes(searchString /* , position = 0 */) {
    return !!~context(this, searchString, INCLUDES)
      .indexOf(searchString, arguments.length > 1 ? arguments[1] : undefined);
  }
});

},{"./_export":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_export.js","./_fails-is-regexp":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_fails-is-regexp.js","./_string-context":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_string-context.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/es6.string.iterator.js":[function(require,module,exports){
'use strict';
var $at = require('./_string-at')(true);

// 21.1.3.27 String.prototype[@@iterator]()
require('./_iter-define')(String, 'String', function (iterated) {
  this._t = String(iterated); // target
  this._i = 0;                // next index
// 21.1.5.2.1 %StringIteratorPrototype%.next()
}, function () {
  var O = this._t;
  var index = this._i;
  var point;
  if (index >= O.length) return { value: undefined, done: true };
  point = $at(O, index);
  this._i += point.length;
  return { value: point, done: false };
});

},{"./_iter-define":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_iter-define.js","./_string-at":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_string-at.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/es6.symbol.js":[function(require,module,exports){
'use strict';
// ECMAScript 6 symbols shim
var global = require('./_global');
var has = require('./_has');
var DESCRIPTORS = require('./_descriptors');
var $export = require('./_export');
var redefine = require('./_redefine');
var META = require('./_meta').KEY;
var $fails = require('./_fails');
var shared = require('./_shared');
var setToStringTag = require('./_set-to-string-tag');
var uid = require('./_uid');
var wks = require('./_wks');
var wksExt = require('./_wks-ext');
var wksDefine = require('./_wks-define');
var enumKeys = require('./_enum-keys');
var isArray = require('./_is-array');
var anObject = require('./_an-object');
var isObject = require('./_is-object');
var toIObject = require('./_to-iobject');
var toPrimitive = require('./_to-primitive');
var createDesc = require('./_property-desc');
var _create = require('./_object-create');
var gOPNExt = require('./_object-gopn-ext');
var $GOPD = require('./_object-gopd');
var $DP = require('./_object-dp');
var $keys = require('./_object-keys');
var gOPD = $GOPD.f;
var dP = $DP.f;
var gOPN = gOPNExt.f;
var $Symbol = global.Symbol;
var $JSON = global.JSON;
var _stringify = $JSON && $JSON.stringify;
var PROTOTYPE = 'prototype';
var HIDDEN = wks('_hidden');
var TO_PRIMITIVE = wks('toPrimitive');
var isEnum = {}.propertyIsEnumerable;
var SymbolRegistry = shared('symbol-registry');
var AllSymbols = shared('symbols');
var OPSymbols = shared('op-symbols');
var ObjectProto = Object[PROTOTYPE];
var USE_NATIVE = typeof $Symbol == 'function';
var QObject = global.QObject;
// Don't use setters in Qt Script, https://github.com/zloirock/core-js/issues/173
var setter = !QObject || !QObject[PROTOTYPE] || !QObject[PROTOTYPE].findChild;

// fallback for old Android, https://code.google.com/p/v8/issues/detail?id=687
var setSymbolDesc = DESCRIPTORS && $fails(function () {
  return _create(dP({}, 'a', {
    get: function () { return dP(this, 'a', { value: 7 }).a; }
  })).a != 7;
}) ? function (it, key, D) {
  var protoDesc = gOPD(ObjectProto, key);
  if (protoDesc) delete ObjectProto[key];
  dP(it, key, D);
  if (protoDesc && it !== ObjectProto) dP(ObjectProto, key, protoDesc);
} : dP;

var wrap = function (tag) {
  var sym = AllSymbols[tag] = _create($Symbol[PROTOTYPE]);
  sym._k = tag;
  return sym;
};

var isSymbol = USE_NATIVE && typeof $Symbol.iterator == 'symbol' ? function (it) {
  return typeof it == 'symbol';
} : function (it) {
  return it instanceof $Symbol;
};

var $defineProperty = function defineProperty(it, key, D) {
  if (it === ObjectProto) $defineProperty(OPSymbols, key, D);
  anObject(it);
  key = toPrimitive(key, true);
  anObject(D);
  if (has(AllSymbols, key)) {
    if (!D.enumerable) {
      if (!has(it, HIDDEN)) dP(it, HIDDEN, createDesc(1, {}));
      it[HIDDEN][key] = true;
    } else {
      if (has(it, HIDDEN) && it[HIDDEN][key]) it[HIDDEN][key] = false;
      D = _create(D, { enumerable: createDesc(0, false) });
    } return setSymbolDesc(it, key, D);
  } return dP(it, key, D);
};
var $defineProperties = function defineProperties(it, P) {
  anObject(it);
  var keys = enumKeys(P = toIObject(P));
  var i = 0;
  var l = keys.length;
  var key;
  while (l > i) $defineProperty(it, key = keys[i++], P[key]);
  return it;
};
var $create = function create(it, P) {
  return P === undefined ? _create(it) : $defineProperties(_create(it), P);
};
var $propertyIsEnumerable = function propertyIsEnumerable(key) {
  var E = isEnum.call(this, key = toPrimitive(key, true));
  if (this === ObjectProto && has(AllSymbols, key) && !has(OPSymbols, key)) return false;
  return E || !has(this, key) || !has(AllSymbols, key) || has(this, HIDDEN) && this[HIDDEN][key] ? E : true;
};
var $getOwnPropertyDescriptor = function getOwnPropertyDescriptor(it, key) {
  it = toIObject(it);
  key = toPrimitive(key, true);
  if (it === ObjectProto && has(AllSymbols, key) && !has(OPSymbols, key)) return;
  var D = gOPD(it, key);
  if (D && has(AllSymbols, key) && !(has(it, HIDDEN) && it[HIDDEN][key])) D.enumerable = true;
  return D;
};
var $getOwnPropertyNames = function getOwnPropertyNames(it) {
  var names = gOPN(toIObject(it));
  var result = [];
  var i = 0;
  var key;
  while (names.length > i) {
    if (!has(AllSymbols, key = names[i++]) && key != HIDDEN && key != META) result.push(key);
  } return result;
};
var $getOwnPropertySymbols = function getOwnPropertySymbols(it) {
  var IS_OP = it === ObjectProto;
  var names = gOPN(IS_OP ? OPSymbols : toIObject(it));
  var result = [];
  var i = 0;
  var key;
  while (names.length > i) {
    if (has(AllSymbols, key = names[i++]) && (IS_OP ? has(ObjectProto, key) : true)) result.push(AllSymbols[key]);
  } return result;
};

// 19.4.1.1 Symbol([description])
if (!USE_NATIVE) {
  $Symbol = function Symbol() {
    if (this instanceof $Symbol) throw TypeError('Symbol is not a constructor!');
    var tag = uid(arguments.length > 0 ? arguments[0] : undefined);
    var $set = function (value) {
      if (this === ObjectProto) $set.call(OPSymbols, value);
      if (has(this, HIDDEN) && has(this[HIDDEN], tag)) this[HIDDEN][tag] = false;
      setSymbolDesc(this, tag, createDesc(1, value));
    };
    if (DESCRIPTORS && setter) setSymbolDesc(ObjectProto, tag, { configurable: true, set: $set });
    return wrap(tag);
  };
  redefine($Symbol[PROTOTYPE], 'toString', function toString() {
    return this._k;
  });

  $GOPD.f = $getOwnPropertyDescriptor;
  $DP.f = $defineProperty;
  require('./_object-gopn').f = gOPNExt.f = $getOwnPropertyNames;
  require('./_object-pie').f = $propertyIsEnumerable;
  require('./_object-gops').f = $getOwnPropertySymbols;

  if (DESCRIPTORS && !require('./_library')) {
    redefine(ObjectProto, 'propertyIsEnumerable', $propertyIsEnumerable, true);
  }

  wksExt.f = function (name) {
    return wrap(wks(name));
  };
}

$export($export.G + $export.W + $export.F * !USE_NATIVE, { Symbol: $Symbol });

for (var es6Symbols = (
  // 19.4.2.2, 19.4.2.3, 19.4.2.4, 19.4.2.6, 19.4.2.8, 19.4.2.9, 19.4.2.10, 19.4.2.11, 19.4.2.12, 19.4.2.13, 19.4.2.14
  'hasInstance,isConcatSpreadable,iterator,match,replace,search,species,split,toPrimitive,toStringTag,unscopables'
).split(','), j = 0; es6Symbols.length > j;)wks(es6Symbols[j++]);

for (var wellKnownSymbols = $keys(wks.store), k = 0; wellKnownSymbols.length > k;) wksDefine(wellKnownSymbols[k++]);

$export($export.S + $export.F * !USE_NATIVE, 'Symbol', {
  // 19.4.2.1 Symbol.for(key)
  'for': function (key) {
    return has(SymbolRegistry, key += '')
      ? SymbolRegistry[key]
      : SymbolRegistry[key] = $Symbol(key);
  },
  // 19.4.2.5 Symbol.keyFor(sym)
  keyFor: function keyFor(sym) {
    if (!isSymbol(sym)) throw TypeError(sym + ' is not a symbol!');
    for (var key in SymbolRegistry) if (SymbolRegistry[key] === sym) return key;
  },
  useSetter: function () { setter = true; },
  useSimple: function () { setter = false; }
});

$export($export.S + $export.F * !USE_NATIVE, 'Object', {
  // 19.1.2.2 Object.create(O [, Properties])
  create: $create,
  // 19.1.2.4 Object.defineProperty(O, P, Attributes)
  defineProperty: $defineProperty,
  // 19.1.2.3 Object.defineProperties(O, Properties)
  defineProperties: $defineProperties,
  // 19.1.2.6 Object.getOwnPropertyDescriptor(O, P)
  getOwnPropertyDescriptor: $getOwnPropertyDescriptor,
  // 19.1.2.7 Object.getOwnPropertyNames(O)
  getOwnPropertyNames: $getOwnPropertyNames,
  // 19.1.2.8 Object.getOwnPropertySymbols(O)
  getOwnPropertySymbols: $getOwnPropertySymbols
});

// 24.3.2 JSON.stringify(value [, replacer [, space]])
$JSON && $export($export.S + $export.F * (!USE_NATIVE || $fails(function () {
  var S = $Symbol();
  // MS Edge converts symbol values to JSON as {}
  // WebKit converts symbol values to JSON as null
  // V8 throws on boxed symbols
  return _stringify([S]) != '[null]' || _stringify({ a: S }) != '{}' || _stringify(Object(S)) != '{}';
})), 'JSON', {
  stringify: function stringify(it) {
    var args = [it];
    var i = 1;
    var replacer, $replacer;
    while (arguments.length > i) args.push(arguments[i++]);
    $replacer = replacer = args[1];
    if (!isObject(replacer) && it === undefined || isSymbol(it)) return; // IE8 returns string on undefined
    if (!isArray(replacer)) replacer = function (key, value) {
      if (typeof $replacer == 'function') value = $replacer.call(this, key, value);
      if (!isSymbol(value)) return value;
    };
    args[1] = replacer;
    return _stringify.apply($JSON, args);
  }
});

// 19.4.3.4 Symbol.prototype[@@toPrimitive](hint)
$Symbol[PROTOTYPE][TO_PRIMITIVE] || require('./_hide')($Symbol[PROTOTYPE], TO_PRIMITIVE, $Symbol[PROTOTYPE].valueOf);
// 19.4.3.5 Symbol.prototype[@@toStringTag]
setToStringTag($Symbol, 'Symbol');
// 20.2.1.9 Math[@@toStringTag]
setToStringTag(Math, 'Math', true);
// 24.3.3 JSON[@@toStringTag]
setToStringTag(global.JSON, 'JSON', true);

},{"./_an-object":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_an-object.js","./_descriptors":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_descriptors.js","./_enum-keys":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_enum-keys.js","./_export":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_export.js","./_fails":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_fails.js","./_global":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_global.js","./_has":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_has.js","./_hide":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_hide.js","./_is-array":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_is-array.js","./_is-object":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_is-object.js","./_library":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_library.js","./_meta":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_meta.js","./_object-create":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_object-create.js","./_object-dp":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_object-dp.js","./_object-gopd":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_object-gopd.js","./_object-gopn":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_object-gopn.js","./_object-gopn-ext":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_object-gopn-ext.js","./_object-gops":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_object-gops.js","./_object-keys":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_object-keys.js","./_object-pie":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_object-pie.js","./_property-desc":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_property-desc.js","./_redefine":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_redefine.js","./_set-to-string-tag":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_set-to-string-tag.js","./_shared":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_shared.js","./_to-iobject":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_to-iobject.js","./_to-primitive":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_to-primitive.js","./_uid":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_uid.js","./_wks":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_wks.js","./_wks-define":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_wks-define.js","./_wks-ext":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_wks-ext.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/web.dom.iterable.js":[function(require,module,exports){
var $iterators = require('./es6.array.iterator');
var getKeys = require('./_object-keys');
var redefine = require('./_redefine');
var global = require('./_global');
var hide = require('./_hide');
var Iterators = require('./_iterators');
var wks = require('./_wks');
var ITERATOR = wks('iterator');
var TO_STRING_TAG = wks('toStringTag');
var ArrayValues = Iterators.Array;

var DOMIterables = {
  CSSRuleList: true, // TODO: Not spec compliant, should be false.
  CSSStyleDeclaration: false,
  CSSValueList: false,
  ClientRectList: false,
  DOMRectList: false,
  DOMStringList: false,
  DOMTokenList: true,
  DataTransferItemList: false,
  FileList: false,
  HTMLAllCollection: false,
  HTMLCollection: false,
  HTMLFormElement: false,
  HTMLSelectElement: false,
  MediaList: true, // TODO: Not spec compliant, should be false.
  MimeTypeArray: false,
  NamedNodeMap: false,
  NodeList: true,
  PaintRequestList: false,
  Plugin: false,
  PluginArray: false,
  SVGLengthList: false,
  SVGNumberList: false,
  SVGPathSegList: false,
  SVGPointList: false,
  SVGStringList: false,
  SVGTransformList: false,
  SourceBufferList: false,
  StyleSheetList: true, // TODO: Not spec compliant, should be false.
  TextTrackCueList: false,
  TextTrackList: false,
  TouchList: false
};

for (var collections = getKeys(DOMIterables), i = 0; i < collections.length; i++) {
  var NAME = collections[i];
  var explicit = DOMIterables[NAME];
  var Collection = global[NAME];
  var proto = Collection && Collection.prototype;
  var key;
  if (proto) {
    if (!proto[ITERATOR]) hide(proto, ITERATOR, ArrayValues);
    if (!proto[TO_STRING_TAG]) hide(proto, TO_STRING_TAG, NAME);
    Iterators[NAME] = ArrayValues;
    if (explicit) for (key in $iterators) if (!proto[key]) redefine(proto, key, $iterators[key], true);
  }
}

},{"./_global":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_global.js","./_hide":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_hide.js","./_iterators":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_iterators.js","./_object-keys":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_object-keys.js","./_redefine":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_redefine.js","./_wks":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/_wks.js","./es6.array.iterator":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/core-js/modules/es6.array.iterator.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/crypt/crypt.js":[function(require,module,exports){
(function() {
  var base64map
      = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/',

  crypt = {
    // Bit-wise rotation left
    rotl: function(n, b) {
      return (n << b) | (n >>> (32 - b));
    },

    // Bit-wise rotation right
    rotr: function(n, b) {
      return (n << (32 - b)) | (n >>> b);
    },

    // Swap big-endian to little-endian and vice versa
    endian: function(n) {
      // If number given, swap endian
      if (n.constructor == Number) {
        return crypt.rotl(n, 8) & 0x00FF00FF | crypt.rotl(n, 24) & 0xFF00FF00;
      }

      // Else, assume array and swap all items
      for (var i = 0; i < n.length; i++)
        n[i] = crypt.endian(n[i]);
      return n;
    },

    // Generate an array of any length of random bytes
    randomBytes: function(n) {
      for (var bytes = []; n > 0; n--)
        bytes.push(Math.floor(Math.random() * 256));
      return bytes;
    },

    // Convert a byte array to big-endian 32-bit words
    bytesToWords: function(bytes) {
      for (var words = [], i = 0, b = 0; i < bytes.length; i++, b += 8)
        words[b >>> 5] |= bytes[i] << (24 - b % 32);
      return words;
    },

    // Convert big-endian 32-bit words to a byte array
    wordsToBytes: function(words) {
      for (var bytes = [], b = 0; b < words.length * 32; b += 8)
        bytes.push((words[b >>> 5] >>> (24 - b % 32)) & 0xFF);
      return bytes;
    },

    // Convert a byte array to a hex string
    bytesToHex: function(bytes) {
      for (var hex = [], i = 0; i < bytes.length; i++) {
        hex.push((bytes[i] >>> 4).toString(16));
        hex.push((bytes[i] & 0xF).toString(16));
      }
      return hex.join('');
    },

    // Convert a hex string to a byte array
    hexToBytes: function(hex) {
      for (var bytes = [], c = 0; c < hex.length; c += 2)
        bytes.push(parseInt(hex.substr(c, 2), 16));
      return bytes;
    },

    // Convert a byte array to a base-64 string
    bytesToBase64: function(bytes) {
      for (var base64 = [], i = 0; i < bytes.length; i += 3) {
        var triplet = (bytes[i] << 16) | (bytes[i + 1] << 8) | bytes[i + 2];
        for (var j = 0; j < 4; j++)
          if (i * 8 + j * 6 <= bytes.length * 8)
            base64.push(base64map.charAt((triplet >>> 6 * (3 - j)) & 0x3F));
          else
            base64.push('=');
      }
      return base64.join('');
    },

    // Convert a base-64 string to a byte array
    base64ToBytes: function(base64) {
      // Remove non-base-64 characters
      base64 = base64.replace(/[^A-Z0-9+\/]/ig, '');

      for (var bytes = [], i = 0, imod4 = 0; i < base64.length;
          imod4 = ++i % 4) {
        if (imod4 == 0) continue;
        bytes.push(((base64map.indexOf(base64.charAt(i - 1))
            & (Math.pow(2, -2 * imod4 + 8) - 1)) << (imod4 * 2))
            | (base64map.indexOf(base64.charAt(i)) >>> (6 - imod4 * 2)));
      }
      return bytes;
    }
  };

  module.exports = crypt;
})();

},{}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/deep-equal/index.js":[function(require,module,exports){
var pSlice = Array.prototype.slice;
var objectKeys = require('./lib/keys.js');
var isArguments = require('./lib/is_arguments.js');

var deepEqual = module.exports = function (actual, expected, opts) {
  if (!opts) opts = {};
  // 7.1. All identical values are equivalent, as determined by ===.
  if (actual === expected) {
    return true;

  } else if (actual instanceof Date && expected instanceof Date) {
    return actual.getTime() === expected.getTime();

  // 7.3. Other pairs that do not both pass typeof value == 'object',
  // equivalence is determined by ==.
  } else if (!actual || !expected || typeof actual != 'object' && typeof expected != 'object') {
    return opts.strict ? actual === expected : actual == expected;

  // 7.4. For all other Object pairs, including Array objects, equivalence is
  // determined by having the same number of owned properties (as verified
  // with Object.prototype.hasOwnProperty.call), the same set of keys
  // (although not necessarily the same order), equivalent values for every
  // corresponding key, and an identical 'prototype' property. Note: this
  // accounts for both named and indexed properties on Arrays.
  } else {
    return objEquiv(actual, expected, opts);
  }
}

function isUndefinedOrNull(value) {
  return value === null || value === undefined;
}

function isBuffer (x) {
  if (!x || typeof x !== 'object' || typeof x.length !== 'number') return false;
  if (typeof x.copy !== 'function' || typeof x.slice !== 'function') {
    return false;
  }
  if (x.length > 0 && typeof x[0] !== 'number') return false;
  return true;
}

function objEquiv(a, b, opts) {
  var i, key;
  if (isUndefinedOrNull(a) || isUndefinedOrNull(b))
    return false;
  // an identical 'prototype' property.
  if (a.prototype !== b.prototype) return false;
  //~~~I've managed to break Object.keys through screwy arguments passing.
  //   Converting to array solves the problem.
  if (isArguments(a)) {
    if (!isArguments(b)) {
      return false;
    }
    a = pSlice.call(a);
    b = pSlice.call(b);
    return deepEqual(a, b, opts);
  }
  if (isBuffer(a)) {
    if (!isBuffer(b)) {
      return false;
    }
    if (a.length !== b.length) return false;
    for (i = 0; i < a.length; i++) {
      if (a[i] !== b[i]) return false;
    }
    return true;
  }
  try {
    var ka = objectKeys(a),
        kb = objectKeys(b);
  } catch (e) {//happens when one is a string literal and the other isn't
    return false;
  }
  // having the same number of owned properties (keys incorporates
  // hasOwnProperty)
  if (ka.length != kb.length)
    return false;
  //the same set of keys (although not necessarily the same order),
  ka.sort();
  kb.sort();
  //~~~cheap key test
  for (i = ka.length - 1; i >= 0; i--) {
    if (ka[i] != kb[i])
      return false;
  }
  //equivalent values for every corresponding key, and
  //~~~possibly expensive deep test
  for (i = ka.length - 1; i >= 0; i--) {
    key = ka[i];
    if (!deepEqual(a[key], b[key], opts)) return false;
  }
  return typeof a === typeof b;
}

},{"./lib/is_arguments.js":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/deep-equal/lib/is_arguments.js","./lib/keys.js":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/deep-equal/lib/keys.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/deep-equal/lib/is_arguments.js":[function(require,module,exports){
var supportsArgumentsClass = (function(){
  return Object.prototype.toString.call(arguments)
})() == '[object Arguments]';

exports = module.exports = supportsArgumentsClass ? supported : unsupported;

exports.supported = supported;
function supported(object) {
  return Object.prototype.toString.call(object) == '[object Arguments]';
};

exports.unsupported = unsupported;
function unsupported(object){
  return object &&
    typeof object == 'object' &&
    typeof object.length == 'number' &&
    Object.prototype.hasOwnProperty.call(object, 'callee') &&
    !Object.prototype.propertyIsEnumerable.call(object, 'callee') ||
    false;
};

},{}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/deep-equal/lib/keys.js":[function(require,module,exports){
exports = module.exports = typeof Object.keys === 'function'
  ? Object.keys : shim;

exports.shim = shim;
function shim (obj) {
  var keys = [];
  for (var key in obj) keys.push(key);
  return keys;
}

},{}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/events/events.js":[function(require,module,exports){
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.

function EventEmitter() {
  this._events = this._events || {};
  this._maxListeners = this._maxListeners || undefined;
}
module.exports = EventEmitter;

// Backwards-compat with node 0.10.x
EventEmitter.EventEmitter = EventEmitter;

EventEmitter.prototype._events = undefined;
EventEmitter.prototype._maxListeners = undefined;

// By default EventEmitters will print a warning if more than 10 listeners are
// added to it. This is a useful default which helps finding memory leaks.
EventEmitter.defaultMaxListeners = 10;

// Obviously not all Emitters should be limited to 10. This function allows
// that to be increased. Set to zero for unlimited.
EventEmitter.prototype.setMaxListeners = function(n) {
  if (!isNumber(n) || n < 0 || isNaN(n))
    throw TypeError('n must be a positive number');
  this._maxListeners = n;
  return this;
};

EventEmitter.prototype.emit = function(type) {
  var er, handler, len, args, i, listeners;

  if (!this._events)
    this._events = {};

  // If there is no 'error' event listener then throw.
  if (type === 'error') {
    if (!this._events.error ||
        (isObject(this._events.error) && !this._events.error.length)) {
      er = arguments[1];
      if (er instanceof Error) {
        throw er; // Unhandled 'error' event
      } else {
        // At least give some kind of context to the user
        var err = new Error('Uncaught, unspecified "error" event. (' + er + ')');
        err.context = er;
        throw err;
      }
    }
  }

  handler = this._events[type];

  if (isUndefined(handler))
    return false;

  if (isFunction(handler)) {
    switch (arguments.length) {
      // fast cases
      case 1:
        handler.call(this);
        break;
      case 2:
        handler.call(this, arguments[1]);
        break;
      case 3:
        handler.call(this, arguments[1], arguments[2]);
        break;
      // slower
      default:
        args = Array.prototype.slice.call(arguments, 1);
        handler.apply(this, args);
    }
  } else if (isObject(handler)) {
    args = Array.prototype.slice.call(arguments, 1);
    listeners = handler.slice();
    len = listeners.length;
    for (i = 0; i < len; i++)
      listeners[i].apply(this, args);
  }

  return true;
};

EventEmitter.prototype.addListener = function(type, listener) {
  var m;

  if (!isFunction(listener))
    throw TypeError('listener must be a function');

  if (!this._events)
    this._events = {};

  // To avoid recursion in the case that type === "newListener"! Before
  // adding it to the listeners, first emit "newListener".
  if (this._events.newListener)
    this.emit('newListener', type,
              isFunction(listener.listener) ?
              listener.listener : listener);

  if (!this._events[type])
    // Optimize the case of one listener. Don't need the extra array object.
    this._events[type] = listener;
  else if (isObject(this._events[type]))
    // If we've already got an array, just append.
    this._events[type].push(listener);
  else
    // Adding the second element, need to change to array.
    this._events[type] = [this._events[type], listener];

  // Check for listener leak
  if (isObject(this._events[type]) && !this._events[type].warned) {
    if (!isUndefined(this._maxListeners)) {
      m = this._maxListeners;
    } else {
      m = EventEmitter.defaultMaxListeners;
    }

    if (m && m > 0 && this._events[type].length > m) {
      this._events[type].warned = true;
      console.error('(node) warning: possible EventEmitter memory ' +
                    'leak detected. %d listeners added. ' +
                    'Use emitter.setMaxListeners() to increase limit.',
                    this._events[type].length);
      if (typeof console.trace === 'function') {
        // not supported in IE 10
        console.trace();
      }
    }
  }

  return this;
};

EventEmitter.prototype.on = EventEmitter.prototype.addListener;

EventEmitter.prototype.once = function(type, listener) {
  if (!isFunction(listener))
    throw TypeError('listener must be a function');

  var fired = false;

  function g() {
    this.removeListener(type, g);

    if (!fired) {
      fired = true;
      listener.apply(this, arguments);
    }
  }

  g.listener = listener;
  this.on(type, g);

  return this;
};

// emits a 'removeListener' event iff the listener was removed
EventEmitter.prototype.removeListener = function(type, listener) {
  var list, position, length, i;

  if (!isFunction(listener))
    throw TypeError('listener must be a function');

  if (!this._events || !this._events[type])
    return this;

  list = this._events[type];
  length = list.length;
  position = -1;

  if (list === listener ||
      (isFunction(list.listener) && list.listener === listener)) {
    delete this._events[type];
    if (this._events.removeListener)
      this.emit('removeListener', type, listener);

  } else if (isObject(list)) {
    for (i = length; i-- > 0;) {
      if (list[i] === listener ||
          (list[i].listener && list[i].listener === listener)) {
        position = i;
        break;
      }
    }

    if (position < 0)
      return this;

    if (list.length === 1) {
      list.length = 0;
      delete this._events[type];
    } else {
      list.splice(position, 1);
    }

    if (this._events.removeListener)
      this.emit('removeListener', type, listener);
  }

  return this;
};

EventEmitter.prototype.removeAllListeners = function(type) {
  var key, listeners;

  if (!this._events)
    return this;

  // not listening for removeListener, no need to emit
  if (!this._events.removeListener) {
    if (arguments.length === 0)
      this._events = {};
    else if (this._events[type])
      delete this._events[type];
    return this;
  }

  // emit removeListener for all listeners on all events
  if (arguments.length === 0) {
    for (key in this._events) {
      if (key === 'removeListener') continue;
      this.removeAllListeners(key);
    }
    this.removeAllListeners('removeListener');
    this._events = {};
    return this;
  }

  listeners = this._events[type];

  if (isFunction(listeners)) {
    this.removeListener(type, listeners);
  } else if (listeners) {
    // LIFO order
    while (listeners.length)
      this.removeListener(type, listeners[listeners.length - 1]);
  }
  delete this._events[type];

  return this;
};

EventEmitter.prototype.listeners = function(type) {
  var ret;
  if (!this._events || !this._events[type])
    ret = [];
  else if (isFunction(this._events[type]))
    ret = [this._events[type]];
  else
    ret = this._events[type].slice();
  return ret;
};

EventEmitter.prototype.listenerCount = function(type) {
  if (this._events) {
    var evlistener = this._events[type];

    if (isFunction(evlistener))
      return 1;
    else if (evlistener)
      return evlistener.length;
  }
  return 0;
};

EventEmitter.listenerCount = function(emitter, type) {
  return emitter.listenerCount(type);
};

function isFunction(arg) {
  return typeof arg === 'function';
}

function isNumber(arg) {
  return typeof arg === 'number';
}

function isObject(arg) {
  return typeof arg === 'object' && arg !== null;
}

function isUndefined(arg) {
  return arg === void 0;
}

},{}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/ieee754/index.js":[function(require,module,exports){
exports.read = function (buffer, offset, isLE, mLen, nBytes) {
  var e, m
  var eLen = nBytes * 8 - mLen - 1
  var eMax = (1 << eLen) - 1
  var eBias = eMax >> 1
  var nBits = -7
  var i = isLE ? (nBytes - 1) : 0
  var d = isLE ? -1 : 1
  var s = buffer[offset + i]

  i += d

  e = s & ((1 << (-nBits)) - 1)
  s >>= (-nBits)
  nBits += eLen
  for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8) {}

  m = e & ((1 << (-nBits)) - 1)
  e >>= (-nBits)
  nBits += mLen
  for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8) {}

  if (e === 0) {
    e = 1 - eBias
  } else if (e === eMax) {
    return m ? NaN : ((s ? -1 : 1) * Infinity)
  } else {
    m = m + Math.pow(2, mLen)
    e = e - eBias
  }
  return (s ? -1 : 1) * m * Math.pow(2, e - mLen)
}

exports.write = function (buffer, value, offset, isLE, mLen, nBytes) {
  var e, m, c
  var eLen = nBytes * 8 - mLen - 1
  var eMax = (1 << eLen) - 1
  var eBias = eMax >> 1
  var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0)
  var i = isLE ? 0 : (nBytes - 1)
  var d = isLE ? 1 : -1
  var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0

  value = Math.abs(value)

  if (isNaN(value) || value === Infinity) {
    m = isNaN(value) ? 1 : 0
    e = eMax
  } else {
    e = Math.floor(Math.log(value) / Math.LN2)
    if (value * (c = Math.pow(2, -e)) < 1) {
      e--
      c *= 2
    }
    if (e + eBias >= 1) {
      value += rt / c
    } else {
      value += rt * Math.pow(2, 1 - eBias)
    }
    if (value * c >= 2) {
      e++
      c /= 2
    }

    if (e + eBias >= eMax) {
      m = 0
      e = eMax
    } else if (e + eBias >= 1) {
      m = (value * c - 1) * Math.pow(2, mLen)
      e = e + eBias
    } else {
      m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen)
      e = 0
    }
  }

  for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {}

  e = (e << mLen) | m
  eLen += mLen
  for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {}

  buffer[offset + i - d] |= s * 128
}

},{}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/is-buffer/index.js":[function(require,module,exports){
/*!
 * Determine if an object is a Buffer
 *
 * @author   Feross Aboukhadijeh <https://feross.org>
 * @license  MIT
 */

// The _isBuffer check is for Safari 5-7 support, because it's missing
// Object.prototype.constructor. Remove this eventually
module.exports = function (obj) {
  return obj != null && (isBuffer(obj) || isSlowBuffer(obj) || !!obj._isBuffer)
}

function isBuffer (obj) {
  return !!obj.constructor && typeof obj.constructor.isBuffer === 'function' && obj.constructor.isBuffer(obj)
}

// For Node v0.10 support. Remove this eventually.
function isSlowBuffer (obj) {
  return typeof obj.readFloatLE === 'function' && typeof obj.slice === 'function' && isBuffer(obj.slice(0, 0))
}

},{}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/isarray/index.js":[function(require,module,exports){
var toString = {}.toString;

module.exports = Array.isArray || function (arr) {
  return toString.call(arr) == '[object Array]';
};

},{}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/l10n-manticore/index.js":[function(require,module,exports){
'use strict';

var parse = require('es6-template-strings/compile');

/**
 * Lazy loading wouldn't really help here because we're mostly just using browserify and that's
 * going to pack the whole bundle. We would need tighter native integration to delay load stuff.
 * TODO see if this matters
 */
var Log = require('manticore-log')('l10n'),
    cultureOrder = ['en-US','en'];

/**
 * Return an instance of l10n against the specified JSON settings
 * @param allCultures
 * @returns {Function}
 */
module.exports = function (allCultures) {
    /**
     * Look from most specific culture to least specific for a value
     * for the given string key. The values are stored in JSON files
     * with a hierarchical structure (e.g. category.screen.stringName: value)
     * and accessed with dotted notation keys.
     * @param key The name of the string value you seek
     * @param substitutions If present, the values used to substitute template values in the string
     * @returns string The string value for the key, or the key if there isn't one.
     */
    return function l10n(key, substitutions) {
        var parts = key.split('.');
        var rawValue = key;
        for (var i = 0; i < cultureOrder.length; i++) {
            var vals = allCultures[cultureOrder[i]];
            if (vals) {
                var value = vals, j = 0;
                for (j = 0; j < parts.length && value; j++) {
                    value = value[parts[j]];
                }
                if (j === parts.length && value) {
                    rawValue = value;
                    break;
                }
            }
        }
        if (substitutions) {
            return subst(rawValue, substitutions);
        }
        return rawValue;
    };
};

var fnPattern = /^\s*l10n\s*\(\s*['"](.*)['"]\s*\)\s*$/;

function subst(rawValue, substitutions) {
    var parsed = parse(rawValue), l = parsed.literals;
    var merged = [];
    for (var lit = 0, len = l.length-1; lit < len; lit++) {
        merged.push(l[lit]);
        var s = (parsed.substitutions[lit] === null || parsed.substitutions[lit] === undefined) ? '' : parsed.substitutions[lit];
        // You can't use full expressions in l10n strings, but you can use
        // l10n(keyname) to at least compose strings
        if (s.indexOf('l10n(') === 0) {
            s = module.exports(s.match(fnPattern)[1], substitutions);
        } else {
            s = (substitutions[s] === null || substitutions[s] === undefined) ? '' : substitutions[s];
        }
        merged.push(s);
    }
    merged.push(l[l.length-1]);
    return merged.join('');
}

/**
 * Change the active culture order
 * @param culture
 */
module.exports.setCultures = function (cultures) {
    cultureOrder = cultures;
};

/**
 * Run straight variable substitution
 */
module.exports.subst = subst;

},{"es6-template-strings/compile":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/l10n-manticore/node_modules/es6-template-strings/compile.js","manticore-log":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-log/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/l10n-manticore/node_modules/es6-template-strings/compile.js":[function(require,module,exports){
'use strict';

var current, literals, substitutions, sOut, sEscape, sAhead, sIn, sInEscape;

sOut = function (char) {
	if (char === '\\') return sEscape;
	if (char === '$') return sAhead;
	current += char;
	return sOut;
};
sEscape = function (char) {
	if ((char !== '\\') && (char !== '$')) current += '\\';
	current += char;
	return sOut;
};
sAhead = function (char) {
	if (char === '{') {
		literals.push(current);
		current = '';
		return sIn;
	}
	if (char === '$') {
		current += '$';
		return sAhead;
	}
	current += '$' + char;
	return sOut;
};
sIn = function (char) {
	if (char === '\\') return sInEscape;
	if (char === '}') {
		substitutions.push(current);
		current = '';
		return sOut;
	}
	current += char;
	return sIn;
};
sInEscape = function (char) {
	if ((char !== '\\') && (char !== '}')) current += '\\';
	current += char;
	return sIn;
};

module.exports = function (str) {
	var length, state, i, result;
	current = '';
	literals = [];
	substitutions = [];

	str = String(str);
	length = str.length;

	state = sOut;
	for (i = 0; i < length; ++i) state = state(str[i]);
	if (state === sOut) {
		literals.push(current);
	} else if (state === sEscape) {
		literals.push(current + '\\');
	} else if (state === sAhead) {
		literals.push(current + '$');
	} else if (state === sIn) {
		literals[literals.length - 1] += '${' + current;
	} else if (state === sInEscape) {
		literals[literals.length - 1] += '${' + current + '\\';
	}
	result = { literals: literals, substitutions: substitutions };
	literals = substitutions = null;
	return result;
};

},{}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/lodash/index.js":[function(require,module,exports){
(function (global){
/**
 * @license
 * lodash 3.10.1 (Custom Build) <https://lodash.com/>
 * Build: `lodash modern -d -o ./index.js`
 * Copyright 2012-2015 The Dojo Foundation <http://dojofoundation.org/>
 * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
 * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
 * Available under MIT license <https://lodash.com/license>
 */
;(function() {

  /** Used as a safe reference for `undefined` in pre-ES5 environments. */
  var undefined;

  /** Used as the semantic version number. */
  var VERSION = '3.10.1';

  /** Used to compose bitmasks for wrapper metadata. */
  var BIND_FLAG = 1,
      BIND_KEY_FLAG = 2,
      CURRY_BOUND_FLAG = 4,
      CURRY_FLAG = 8,
      CURRY_RIGHT_FLAG = 16,
      PARTIAL_FLAG = 32,
      PARTIAL_RIGHT_FLAG = 64,
      ARY_FLAG = 128,
      REARG_FLAG = 256;

  /** Used as default options for `_.trunc`. */
  var DEFAULT_TRUNC_LENGTH = 30,
      DEFAULT_TRUNC_OMISSION = '...';

  /** Used to detect when a function becomes hot. */
  var HOT_COUNT = 150,
      HOT_SPAN = 16;

  /** Used as the size to enable large array optimizations. */
  var LARGE_ARRAY_SIZE = 200;

  /** Used to indicate the type of lazy iteratees. */
  var LAZY_FILTER_FLAG = 1,
      LAZY_MAP_FLAG = 2;

  /** Used as the `TypeError` message for "Functions" methods. */
  var FUNC_ERROR_TEXT = 'Expected a function';

  /** Used as the internal argument placeholder. */
  var PLACEHOLDER = '__lodash_placeholder__';

  /** `Object#toString` result references. */
  var argsTag = '[object Arguments]',
      arrayTag = '[object Array]',
      boolTag = '[object Boolean]',
      dateTag = '[object Date]',
      errorTag = '[object Error]',
      funcTag = '[object Function]',
      mapTag = '[object Map]',
      numberTag = '[object Number]',
      objectTag = '[object Object]',
      regexpTag = '[object RegExp]',
      setTag = '[object Set]',
      stringTag = '[object String]',
      weakMapTag = '[object WeakMap]';

  var arrayBufferTag = '[object ArrayBuffer]',
      float32Tag = '[object Float32Array]',
      float64Tag = '[object Float64Array]',
      int8Tag = '[object Int8Array]',
      int16Tag = '[object Int16Array]',
      int32Tag = '[object Int32Array]',
      uint8Tag = '[object Uint8Array]',
      uint8ClampedTag = '[object Uint8ClampedArray]',
      uint16Tag = '[object Uint16Array]',
      uint32Tag = '[object Uint32Array]';

  /** Used to match empty string literals in compiled template source. */
  var reEmptyStringLeading = /\b__p \+= '';/g,
      reEmptyStringMiddle = /\b(__p \+=) '' \+/g,
      reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g;

  /** Used to match HTML entities and HTML characters. */
  var reEscapedHtml = /&(?:amp|lt|gt|quot|#39|#96);/g,
      reUnescapedHtml = /[&<>"'`]/g,
      reHasEscapedHtml = RegExp(reEscapedHtml.source),
      reHasUnescapedHtml = RegExp(reUnescapedHtml.source);

  /** Used to match template delimiters. */
  var reEscape = /<%-([\s\S]+?)%>/g,
      reEvaluate = /<%([\s\S]+?)%>/g,
      reInterpolate = /<%=([\s\S]+?)%>/g;

  /** Used to match property names within property paths. */
  var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\n\\]|\\.)*?\1)\]/,
      reIsPlainProp = /^\w*$/,
      rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\n\\]|\\.)*?)\2)\]/g;

  /**
   * Used to match `RegExp` [syntax characters](http://ecma-international.org/ecma-262/6.0/#sec-patterns)
   * and those outlined by [`EscapeRegExpPattern`](http://ecma-international.org/ecma-262/6.0/#sec-escaperegexppattern).
   */
  var reRegExpChars = /^[:!,]|[\\^$.*+?()[\]{}|\/]|(^[0-9a-fA-Fnrtuvx])|([\n\r\u2028\u2029])/g,
      reHasRegExpChars = RegExp(reRegExpChars.source);

  /** Used to match [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks). */
  var reComboMark = /[\u0300-\u036f\ufe20-\ufe23]/g;

  /** Used to match backslashes in property paths. */
  var reEscapeChar = /\\(\\)?/g;

  /** Used to match [ES template delimiters](http://ecma-international.org/ecma-262/6.0/#sec-template-literal-lexical-components). */
  var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g;

  /** Used to match `RegExp` flags from their coerced string values. */
  var reFlags = /\w*$/;

  /** Used to detect hexadecimal string values. */
  var reHasHexPrefix = /^0[xX]/;

  /** Used to detect host constructors (Safari > 5). */
  var reIsHostCtor = /^\[object .+?Constructor\]$/;

  /** Used to detect unsigned integer values. */
  var reIsUint = /^\d+$/;

  /** Used to match latin-1 supplementary letters (excluding mathematical operators). */
  var reLatin1 = /[\xc0-\xd6\xd8-\xde\xdf-\xf6\xf8-\xff]/g;

  /** Used to ensure capturing order of template delimiters. */
  var reNoMatch = /($^)/;

  /** Used to match unescaped characters in compiled string literals. */
  var reUnescapedString = /['\n\r\u2028\u2029\\]/g;

  /** Used to match words to create compound words. */
  var reWords = (function() {
    var upper = '[A-Z\\xc0-\\xd6\\xd8-\\xde]',
        lower = '[a-z\\xdf-\\xf6\\xf8-\\xff]+';

    return RegExp(upper + '+(?=' + upper + lower + ')|' + upper + '?' + lower + '|' + upper + '+|[0-9]+', 'g');
  }());

  /** Used to assign default `context` object properties. */
  var contextProps = [
    'Array', 'ArrayBuffer', 'Date', 'Error', 'Float32Array', 'Float64Array',
    'Function', 'Int8Array', 'Int16Array', 'Int32Array', 'Math', 'Number',
    'Object', 'RegExp', 'Set', 'String', '_', 'clearTimeout', 'isFinite',
    'parseFloat', 'parseInt', 'setTimeout', 'TypeError', 'Uint8Array',
    'Uint8ClampedArray', 'Uint16Array', 'Uint32Array', 'WeakMap'
  ];

  /** Used to make template sourceURLs easier to identify. */
  var templateCounter = -1;

  /** Used to identify `toStringTag` values of typed arrays. */
  var typedArrayTags = {};
  typedArrayTags[float32Tag] = typedArrayTags[float64Tag] =
  typedArrayTags[int8Tag] = typedArrayTags[int16Tag] =
  typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] =
  typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] =
  typedArrayTags[uint32Tag] = true;
  typedArrayTags[argsTag] = typedArrayTags[arrayTag] =
  typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =
  typedArrayTags[dateTag] = typedArrayTags[errorTag] =
  typedArrayTags[funcTag] = typedArrayTags[mapTag] =
  typedArrayTags[numberTag] = typedArrayTags[objectTag] =
  typedArrayTags[regexpTag] = typedArrayTags[setTag] =
  typedArrayTags[stringTag] = typedArrayTags[weakMapTag] = false;

  /** Used to identify `toStringTag` values supported by `_.clone`. */
  var cloneableTags = {};
  cloneableTags[argsTag] = cloneableTags[arrayTag] =
  cloneableTags[arrayBufferTag] = cloneableTags[boolTag] =
  cloneableTags[dateTag] = cloneableTags[float32Tag] =
  cloneableTags[float64Tag] = cloneableTags[int8Tag] =
  cloneableTags[int16Tag] = cloneableTags[int32Tag] =
  cloneableTags[numberTag] = cloneableTags[objectTag] =
  cloneableTags[regexpTag] = cloneableTags[stringTag] =
  cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] =
  cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true;
  cloneableTags[errorTag] = cloneableTags[funcTag] =
  cloneableTags[mapTag] = cloneableTags[setTag] =
  cloneableTags[weakMapTag] = false;

  /** Used to map latin-1 supplementary letters to basic latin letters. */
  var deburredLetters = {
    '\xc0': 'A',  '\xc1': 'A', '\xc2': 'A', '\xc3': 'A', '\xc4': 'A', '\xc5': 'A',
    '\xe0': 'a',  '\xe1': 'a', '\xe2': 'a', '\xe3': 'a', '\xe4': 'a', '\xe5': 'a',
    '\xc7': 'C',  '\xe7': 'c',
    '\xd0': 'D',  '\xf0': 'd',
    '\xc8': 'E',  '\xc9': 'E', '\xca': 'E', '\xcb': 'E',
    '\xe8': 'e',  '\xe9': 'e', '\xea': 'e', '\xeb': 'e',
    '\xcC': 'I',  '\xcd': 'I', '\xce': 'I', '\xcf': 'I',
    '\xeC': 'i',  '\xed': 'i', '\xee': 'i', '\xef': 'i',
    '\xd1': 'N',  '\xf1': 'n',
    '\xd2': 'O',  '\xd3': 'O', '\xd4': 'O', '\xd5': 'O', '\xd6': 'O', '\xd8': 'O',
    '\xf2': 'o',  '\xf3': 'o', '\xf4': 'o', '\xf5': 'o', '\xf6': 'o', '\xf8': 'o',
    '\xd9': 'U',  '\xda': 'U', '\xdb': 'U', '\xdc': 'U',
    '\xf9': 'u',  '\xfa': 'u', '\xfb': 'u', '\xfc': 'u',
    '\xdd': 'Y',  '\xfd': 'y', '\xff': 'y',
    '\xc6': 'Ae', '\xe6': 'ae',
    '\xde': 'Th', '\xfe': 'th',
    '\xdf': 'ss'
  };

  /** Used to map characters to HTML entities. */
  var htmlEscapes = {
    '&': '&amp;',
    '<': '&lt;',
    '>': '&gt;',
    '"': '&quot;',
    "'": '&#39;',
    '`': '&#96;'
  };

  /** Used to map HTML entities to characters. */
  var htmlUnescapes = {
    '&amp;': '&',
    '&lt;': '<',
    '&gt;': '>',
    '&quot;': '"',
    '&#39;': "'",
    '&#96;': '`'
  };

  /** Used to determine if values are of the language type `Object`. */
  var objectTypes = {
    'function': true,
    'object': true
  };

  /** Used to escape characters for inclusion in compiled regexes. */
  var regexpEscapes = {
    '0': 'x30', '1': 'x31', '2': 'x32', '3': 'x33', '4': 'x34',
    '5': 'x35', '6': 'x36', '7': 'x37', '8': 'x38', '9': 'x39',
    'A': 'x41', 'B': 'x42', 'C': 'x43', 'D': 'x44', 'E': 'x45', 'F': 'x46',
    'a': 'x61', 'b': 'x62', 'c': 'x63', 'd': 'x64', 'e': 'x65', 'f': 'x66',
    'n': 'x6e', 'r': 'x72', 't': 'x74', 'u': 'x75', 'v': 'x76', 'x': 'x78'
  };

  /** Used to escape characters for inclusion in compiled string literals. */
  var stringEscapes = {
    '\\': '\\',
    "'": "'",
    '\n': 'n',
    '\r': 'r',
    '\u2028': 'u2028',
    '\u2029': 'u2029'
  };

  /** Detect free variable `exports`. */
  var freeExports = objectTypes[typeof exports] && exports && !exports.nodeType && exports;

  /** Detect free variable `module`. */
  var freeModule = objectTypes[typeof module] && module && !module.nodeType && module;

  /** Detect free variable `global` from Node.js. */
  var freeGlobal = freeExports && freeModule && typeof global == 'object' && global && global.Object && global;

  /** Detect free variable `self`. */
  var freeSelf = objectTypes[typeof self] && self && self.Object && self;

  /** Detect free variable `window`. */
  var freeWindow = objectTypes[typeof window] && window && window.Object && window;

  /** Detect the popular CommonJS extension `module.exports`. */
  var moduleExports = freeModule && freeModule.exports === freeExports && freeExports;

  /**
   * Used as a reference to the global object.
   *
   * The `this` value is used if it's the global object to avoid Greasemonkey's
   * restricted `window` object, otherwise the `window` object is used.
   */
  var root = freeGlobal || ((freeWindow !== (this && this.window)) && freeWindow) || freeSelf || this;

  /*--------------------------------------------------------------------------*/

  /**
   * The base implementation of `compareAscending` which compares values and
   * sorts them in ascending order without guaranteeing a stable sort.
   *
   * @private
   * @param {*} value The value to compare.
   * @param {*} other The other value to compare.
   * @returns {number} Returns the sort order indicator for `value`.
   */
  function baseCompareAscending(value, other) {
    if (value !== other) {
      var valIsNull = value === null,
          valIsUndef = value === undefined,
          valIsReflexive = value === value;

      var othIsNull = other === null,
          othIsUndef = other === undefined,
          othIsReflexive = other === other;

      if ((value > other && !othIsNull) || !valIsReflexive ||
          (valIsNull && !othIsUndef && othIsReflexive) ||
          (valIsUndef && othIsReflexive)) {
        return 1;
      }
      if ((value < other && !valIsNull) || !othIsReflexive ||
          (othIsNull && !valIsUndef && valIsReflexive) ||
          (othIsUndef && valIsReflexive)) {
        return -1;
      }
    }
    return 0;
  }

  /**
   * The base implementation of `_.findIndex` and `_.findLastIndex` without
   * support for callback shorthands and `this` binding.
   *
   * @private
   * @param {Array} array The array to search.
   * @param {Function} predicate The function invoked per iteration.
   * @param {boolean} [fromRight] Specify iterating from right to left.
   * @returns {number} Returns the index of the matched value, else `-1`.
   */
  function baseFindIndex(array, predicate, fromRight) {
    var length = array.length,
        index = fromRight ? length : -1;

    while ((fromRight ? index-- : ++index < length)) {
      if (predicate(array[index], index, array)) {
        return index;
      }
    }
    return -1;
  }

  /**
   * The base implementation of `_.indexOf` without support for binary searches.
   *
   * @private
   * @param {Array} array The array to search.
   * @param {*} value The value to search for.
   * @param {number} fromIndex The index to search from.
   * @returns {number} Returns the index of the matched value, else `-1`.
   */
  function baseIndexOf(array, value, fromIndex) {
    if (value !== value) {
      return indexOfNaN(array, fromIndex);
    }
    var index = fromIndex - 1,
        length = array.length;

    while (++index < length) {
      if (array[index] === value) {
        return index;
      }
    }
    return -1;
  }

  /**
   * The base implementation of `_.isFunction` without support for environments
   * with incorrect `typeof` results.
   *
   * @private
   * @param {*} value The value to check.
   * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
   */
  function baseIsFunction(value) {
    // Avoid a Chakra JIT bug in compatibility modes of IE 11.
    // See https://github.com/jashkenas/underscore/issues/1621 for more details.
    return typeof value == 'function' || false;
  }

  /**
   * Converts `value` to a string if it's not one. An empty string is returned
   * for `null` or `undefined` values.
   *
   * @private
   * @param {*} value The value to process.
   * @returns {string} Returns the string.
   */
  function baseToString(value) {
    return value == null ? '' : (value + '');
  }

  /**
   * Used by `_.trim` and `_.trimLeft` to get the index of the first character
   * of `string` that is not found in `chars`.
   *
   * @private
   * @param {string} string The string to inspect.
   * @param {string} chars The characters to find.
   * @returns {number} Returns the index of the first character not found in `chars`.
   */
  function charsLeftIndex(string, chars) {
    var index = -1,
        length = string.length;

    while (++index < length && chars.indexOf(string.charAt(index)) > -1) {}
    return index;
  }

  /**
   * Used by `_.trim` and `_.trimRight` to get the index of the last character
   * of `string` that is not found in `chars`.
   *
   * @private
   * @param {string} string The string to inspect.
   * @param {string} chars The characters to find.
   * @returns {number} Returns the index of the last character not found in `chars`.
   */
  function charsRightIndex(string, chars) {
    var index = string.length;

    while (index-- && chars.indexOf(string.charAt(index)) > -1) {}
    return index;
  }

  /**
   * Used by `_.sortBy` to compare transformed elements of a collection and stable
   * sort them in ascending order.
   *
   * @private
   * @param {Object} object The object to compare.
   * @param {Object} other The other object to compare.
   * @returns {number} Returns the sort order indicator for `object`.
   */
  function compareAscending(object, other) {
    return baseCompareAscending(object.criteria, other.criteria) || (object.index - other.index);
  }

  /**
   * Used by `_.sortByOrder` to compare multiple properties of a value to another
   * and stable sort them.
   *
   * If `orders` is unspecified, all valuess are sorted in ascending order. Otherwise,
   * a value is sorted in ascending order if its corresponding order is "asc", and
   * descending if "desc".
   *
   * @private
   * @param {Object} object The object to compare.
   * @param {Object} other The other object to compare.
   * @param {boolean[]} orders The order to sort by for each property.
   * @returns {number} Returns the sort order indicator for `object`.
   */
  function compareMultiple(object, other, orders) {
    var index = -1,
        objCriteria = object.criteria,
        othCriteria = other.criteria,
        length = objCriteria.length,
        ordersLength = orders.length;

    while (++index < length) {
      var result = baseCompareAscending(objCriteria[index], othCriteria[index]);
      if (result) {
        if (index >= ordersLength) {
          return result;
        }
        var order = orders[index];
        return result * ((order === 'asc' || order === true) ? 1 : -1);
      }
    }
    // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications
    // that causes it, under certain circumstances, to provide the same value for
    // `object` and `other`. See https://github.com/jashkenas/underscore/pull/1247
    // for more details.
    //
    // This also ensures a stable sort in V8 and other engines.
    // See https://code.google.com/p/v8/issues/detail?id=90 for more details.
    return object.index - other.index;
  }

  /**
   * Used by `_.deburr` to convert latin-1 supplementary letters to basic latin letters.
   *
   * @private
   * @param {string} letter The matched letter to deburr.
   * @returns {string} Returns the deburred letter.
   */
  function deburrLetter(letter) {
    return deburredLetters[letter];
  }

  /**
   * Used by `_.escape` to convert characters to HTML entities.
   *
   * @private
   * @param {string} chr The matched character to escape.
   * @returns {string} Returns the escaped character.
   */
  function escapeHtmlChar(chr) {
    return htmlEscapes[chr];
  }

  /**
   * Used by `_.escapeRegExp` to escape characters for inclusion in compiled regexes.
   *
   * @private
   * @param {string} chr The matched character to escape.
   * @param {string} leadingChar The capture group for a leading character.
   * @param {string} whitespaceChar The capture group for a whitespace character.
   * @returns {string} Returns the escaped character.
   */
  function escapeRegExpChar(chr, leadingChar, whitespaceChar) {
    if (leadingChar) {
      chr = regexpEscapes[chr];
    } else if (whitespaceChar) {
      chr = stringEscapes[chr];
    }
    return '\\' + chr;
  }

  /**
   * Used by `_.template` to escape characters for inclusion in compiled string literals.
   *
   * @private
   * @param {string} chr The matched character to escape.
   * @returns {string} Returns the escaped character.
   */
  function escapeStringChar(chr) {
    return '\\' + stringEscapes[chr];
  }

  /**
   * Gets the index at which the first occurrence of `NaN` is found in `array`.
   *
   * @private
   * @param {Array} array The array to search.
   * @param {number} fromIndex The index to search from.
   * @param {boolean} [fromRight] Specify iterating from right to left.
   * @returns {number} Returns the index of the matched `NaN`, else `-1`.
   */
  function indexOfNaN(array, fromIndex, fromRight) {
    var length = array.length,
        index = fromIndex + (fromRight ? 0 : -1);

    while ((fromRight ? index-- : ++index < length)) {
      var other = array[index];
      if (other !== other) {
        return index;
      }
    }
    return -1;
  }

  /**
   * Checks if `value` is object-like.
   *
   * @private
   * @param {*} value The value to check.
   * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
   */
  function isObjectLike(value) {
    return !!value && typeof value == 'object';
  }

  /**
   * Used by `trimmedLeftIndex` and `trimmedRightIndex` to determine if a
   * character code is whitespace.
   *
   * @private
   * @param {number} charCode The character code to inspect.
   * @returns {boolean} Returns `true` if `charCode` is whitespace, else `false`.
   */
  function isSpace(charCode) {
    return ((charCode <= 160 && (charCode >= 9 && charCode <= 13) || charCode == 32 || charCode == 160) || charCode == 5760 || charCode == 6158 ||
      (charCode >= 8192 && (charCode <= 8202 || charCode == 8232 || charCode == 8233 || charCode == 8239 || charCode == 8287 || charCode == 12288 || charCode == 65279)));
  }

  /**
   * Replaces all `placeholder` elements in `array` with an internal placeholder
   * and returns an array of their indexes.
   *
   * @private
   * @param {Array} array The array to modify.
   * @param {*} placeholder The placeholder to replace.
   * @returns {Array} Returns the new array of placeholder indexes.
   */
  function replaceHolders(array, placeholder) {
    var index = -1,
        length = array.length,
        resIndex = -1,
        result = [];

    while (++index < length) {
      if (array[index] === placeholder) {
        array[index] = PLACEHOLDER;
        result[++resIndex] = index;
      }
    }
    return result;
  }

  /**
   * An implementation of `_.uniq` optimized for sorted arrays without support
   * for callback shorthands and `this` binding.
   *
   * @private
   * @param {Array} array The array to inspect.
   * @param {Function} [iteratee] The function invoked per iteration.
   * @returns {Array} Returns the new duplicate-value-free array.
   */
  function sortedUniq(array, iteratee) {
    var seen,
        index = -1,
        length = array.length,
        resIndex = -1,
        result = [];

    while (++index < length) {
      var value = array[index],
          computed = iteratee ? iteratee(value, index, array) : value;

      if (!index || seen !== computed) {
        seen = computed;
        result[++resIndex] = value;
      }
    }
    return result;
  }

  /**
   * Used by `_.trim` and `_.trimLeft` to get the index of the first non-whitespace
   * character of `string`.
   *
   * @private
   * @param {string} string The string to inspect.
   * @returns {number} Returns the index of the first non-whitespace character.
   */
  function trimmedLeftIndex(string) {
    var index = -1,
        length = string.length;

    while (++index < length && isSpace(string.charCodeAt(index))) {}
    return index;
  }

  /**
   * Used by `_.trim` and `_.trimRight` to get the index of the last non-whitespace
   * character of `string`.
   *
   * @private
   * @param {string} string The string to inspect.
   * @returns {number} Returns the index of the last non-whitespace character.
   */
  function trimmedRightIndex(string) {
    var index = string.length;

    while (index-- && isSpace(string.charCodeAt(index))) {}
    return index;
  }

  /**
   * Used by `_.unescape` to convert HTML entities to characters.
   *
   * @private
   * @param {string} chr The matched character to unescape.
   * @returns {string} Returns the unescaped character.
   */
  function unescapeHtmlChar(chr) {
    return htmlUnescapes[chr];
  }

  /*--------------------------------------------------------------------------*/

  /**
   * Create a new pristine `lodash` function using the given `context` object.
   *
   * @static
   * @memberOf _
   * @category Utility
   * @param {Object} [context=root] The context object.
   * @returns {Function} Returns a new `lodash` function.
   * @example
   *
   * _.mixin({ 'foo': _.constant('foo') });
   *
   * var lodash = _.runInContext();
   * lodash.mixin({ 'bar': lodash.constant('bar') });
   *
   * _.isFunction(_.foo);
   * // => true
   * _.isFunction(_.bar);
   * // => false
   *
   * lodash.isFunction(lodash.foo);
   * // => false
   * lodash.isFunction(lodash.bar);
   * // => true
   *
   * // using `context` to mock `Date#getTime` use in `_.now`
   * var mock = _.runInContext({
   *   'Date': function() {
   *     return { 'getTime': getTimeMock };
   *   }
   * });
   *
   * // or creating a suped-up `defer` in Node.js
   * var defer = _.runInContext({ 'setTimeout': setImmediate }).defer;
   */
  function runInContext(context) {
    // Avoid issues with some ES3 environments that attempt to use values, named
    // after built-in constructors like `Object`, for the creation of literals.
    // ES5 clears this up by stating that literals must use built-in constructors.
    // See https://es5.github.io/#x11.1.5 for more details.
    context = context ? _.defaults(root.Object(), context, _.pick(root, contextProps)) : root;

    /** Native constructor references. */
    var Array = context.Array,
        Date = context.Date,
        Error = context.Error,
        Function = context.Function,
        Math = context.Math,
        Number = context.Number,
        Object = context.Object,
        RegExp = context.RegExp,
        String = context.String,
        TypeError = context.TypeError;

    /** Used for native method references. */
    var arrayProto = Array.prototype,
        objectProto = Object.prototype,
        stringProto = String.prototype;

    /** Used to resolve the decompiled source of functions. */
    var fnToString = Function.prototype.toString;

    /** Used to check objects for own properties. */
    var hasOwnProperty = objectProto.hasOwnProperty;

    /** Used to generate unique IDs. */
    var idCounter = 0;

    /**
     * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
     * of values.
     */
    var objToString = objectProto.toString;

    /** Used to restore the original `_` reference in `_.noConflict`. */
    var oldDash = root._;

    /** Used to detect if a method is native. */
    var reIsNative = RegExp('^' +
      fnToString.call(hasOwnProperty).replace(/[\\^$.*+?()[\]{}|]/g, '\\$&')
      .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
    );

    /** Native method references. */
    var ArrayBuffer = context.ArrayBuffer,
        clearTimeout = context.clearTimeout,
        parseFloat = context.parseFloat,
        pow = Math.pow,
        propertyIsEnumerable = objectProto.propertyIsEnumerable,
        Set = getNative(context, 'Set'),
        setTimeout = context.setTimeout,
        splice = arrayProto.splice,
        Uint8Array = context.Uint8Array,
        WeakMap = getNative(context, 'WeakMap');

    /* Native method references for those with the same name as other `lodash` methods. */
    var nativeCeil = Math.ceil,
        nativeCreate = getNative(Object, 'create'),
        nativeFloor = Math.floor,
        nativeIsArray = getNative(Array, 'isArray'),
        nativeIsFinite = context.isFinite,
        nativeKeys = getNative(Object, 'keys'),
        nativeMax = Math.max,
        nativeMin = Math.min,
        nativeNow = getNative(Date, 'now'),
        nativeParseInt = context.parseInt,
        nativeRandom = Math.random;

    /** Used as references for `-Infinity` and `Infinity`. */
    var NEGATIVE_INFINITY = Number.NEGATIVE_INFINITY,
        POSITIVE_INFINITY = Number.POSITIVE_INFINITY;

    /** Used as references for the maximum length and index of an array. */
    var MAX_ARRAY_LENGTH = 4294967295,
        MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1,
        HALF_MAX_ARRAY_LENGTH = MAX_ARRAY_LENGTH >>> 1;

    /**
     * Used as the [maximum length](http://ecma-international.org/ecma-262/6.0/#sec-number.max_safe_integer)
     * of an array-like value.
     */
    var MAX_SAFE_INTEGER = 9007199254740991;

    /** Used to store function metadata. */
    var metaMap = WeakMap && new WeakMap;

    /** Used to lookup unminified function names. */
    var realNames = {};

    /*------------------------------------------------------------------------*/

    /**
     * Creates a `lodash` object which wraps `value` to enable implicit chaining.
     * Methods that operate on and return arrays, collections, and functions can
     * be chained together. Methods that retrieve a single value or may return a
     * primitive value will automatically end the chain returning the unwrapped
     * value. Explicit chaining may be enabled using `_.chain`. The execution of
     * chained methods is lazy, that is, execution is deferred until `_#value`
     * is implicitly or explicitly called.
     *
     * Lazy evaluation allows several methods to support shortcut fusion. Shortcut
     * fusion is an optimization strategy which merge iteratee calls; this can help
     * to avoid the creation of intermediate data structures and greatly reduce the
     * number of iteratee executions.
     *
     * Chaining is supported in custom builds as long as the `_#value` method is
     * directly or indirectly included in the build.
     *
     * In addition to lodash methods, wrappers have `Array` and `String` methods.
     *
     * The wrapper `Array` methods are:
     * `concat`, `join`, `pop`, `push`, `reverse`, `shift`, `slice`, `sort`,
     * `splice`, and `unshift`
     *
     * The wrapper `String` methods are:
     * `replace` and `split`
     *
     * The wrapper methods that support shortcut fusion are:
     * `compact`, `drop`, `dropRight`, `dropRightWhile`, `dropWhile`, `filter`,
     * `first`, `initial`, `last`, `map`, `pluck`, `reject`, `rest`, `reverse`,
     * `slice`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, `toArray`,
     * and `where`
     *
     * The chainable wrapper methods are:
     * `after`, `ary`, `assign`, `at`, `before`, `bind`, `bindAll`, `bindKey`,
     * `callback`, `chain`, `chunk`, `commit`, `compact`, `concat`, `constant`,
     * `countBy`, `create`, `curry`, `debounce`, `defaults`, `defaultsDeep`,
     * `defer`, `delay`, `difference`, `drop`, `dropRight`, `dropRightWhile`,
     * `dropWhile`, `fill`, `filter`, `flatten`, `flattenDeep`, `flow`, `flowRight`,
     * `forEach`, `forEachRight`, `forIn`, `forInRight`, `forOwn`, `forOwnRight`,
     * `functions`, `groupBy`, `indexBy`, `initial`, `intersection`, `invert`,
     * `invoke`, `keys`, `keysIn`, `map`, `mapKeys`, `mapValues`, `matches`,
     * `matchesProperty`, `memoize`, `merge`, `method`, `methodOf`, `mixin`,
     * `modArgs`, `negate`, `omit`, `once`, `pairs`, `partial`, `partialRight`,
     * `partition`, `pick`, `plant`, `pluck`, `property`, `propertyOf`, `pull`,
     * `pullAt`, `push`, `range`, `rearg`, `reject`, `remove`, `rest`, `restParam`,
     * `reverse`, `set`, `shuffle`, `slice`, `sort`, `sortBy`, `sortByAll`,
     * `sortByOrder`, `splice`, `spread`, `take`, `takeRight`, `takeRightWhile`,
     * `takeWhile`, `tap`, `throttle`, `thru`, `times`, `toArray`, `toPlainObject`,
     * `transform`, `union`, `uniq`, `unshift`, `unzip`, `unzipWith`, `values`,
     * `valuesIn`, `where`, `without`, `wrap`, `xor`, `zip`, `zipObject`, `zipWith`
     *
     * The wrapper methods that are **not** chainable by default are:
     * `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clone`, `cloneDeep`,
     * `deburr`, `endsWith`, `escape`, `escapeRegExp`, `every`, `find`, `findIndex`,
     * `findKey`, `findLast`, `findLastIndex`, `findLastKey`, `findWhere`, `first`,
     * `floor`, `get`, `gt`, `gte`, `has`, `identity`, `includes`, `indexOf`,
     * `inRange`, `isArguments`, `isArray`, `isBoolean`, `isDate`, `isElement`,
     * `isEmpty`, `isEqual`, `isError`, `isFinite` `isFunction`, `isMatch`,
     * `isNative`, `isNaN`, `isNull`, `isNumber`, `isObject`, `isPlainObject`,
     * `isRegExp`, `isString`, `isUndefined`, `isTypedArray`, `join`, `kebabCase`,
     * `last`, `lastIndexOf`, `lt`, `lte`, `max`, `min`, `noConflict`, `noop`,
     * `now`, `pad`, `padLeft`, `padRight`, `parseInt`, `pop`, `random`, `reduce`,
     * `reduceRight`, `repeat`, `result`, `round`, `runInContext`, `shift`, `size`,
     * `snakeCase`, `some`, `sortedIndex`, `sortedLastIndex`, `startCase`,
     * `startsWith`, `sum`, `template`, `trim`, `trimLeft`, `trimRight`, `trunc`,
     * `unescape`, `uniqueId`, `value`, and `words`
     *
     * The wrapper method `sample` will return a wrapped value when `n` is provided,
     * otherwise an unwrapped value is returned.
     *
     * @name _
     * @constructor
     * @category Chain
     * @param {*} value The value to wrap in a `lodash` instance.
     * @returns {Object} Returns the new `lodash` wrapper instance.
     * @example
     *
     * var wrapped = _([1, 2, 3]);
     *
     * // returns an unwrapped value
     * wrapped.reduce(function(total, n) {
     *   return total + n;
     * });
     * // => 6
     *
     * // returns a wrapped value
     * var squares = wrapped.map(function(n) {
     *   return n * n;
     * });
     *
     * _.isArray(squares);
     * // => false
     *
     * _.isArray(squares.value());
     * // => true
     */
    function lodash(value) {
      if (isObjectLike(value) && !isArray(value) && !(value instanceof LazyWrapper)) {
        if (value instanceof LodashWrapper) {
          return value;
        }
        if (hasOwnProperty.call(value, '__chain__') && hasOwnProperty.call(value, '__wrapped__')) {
          return wrapperClone(value);
        }
      }
      return new LodashWrapper(value);
    }

    /**
     * The function whose prototype all chaining wrappers inherit from.
     *
     * @private
     */
    function baseLodash() {
      // No operation performed.
    }

    /**
     * The base constructor for creating `lodash` wrapper objects.
     *
     * @private
     * @param {*} value The value to wrap.
     * @param {boolean} [chainAll] Enable chaining for all wrapper methods.
     * @param {Array} [actions=[]] Actions to peform to resolve the unwrapped value.
     */
    function LodashWrapper(value, chainAll, actions) {
      this.__wrapped__ = value;
      this.__actions__ = actions || [];
      this.__chain__ = !!chainAll;
    }

    /**
     * An object environment feature flags.
     *
     * @static
     * @memberOf _
     * @type Object
     */
    var support = lodash.support = {};

    /**
     * By default, the template delimiters used by lodash are like those in
     * embedded Ruby (ERB). Change the following template settings to use
     * alternative delimiters.
     *
     * @static
     * @memberOf _
     * @type Object
     */
    lodash.templateSettings = {

      /**
       * Used to detect `data` property values to be HTML-escaped.
       *
       * @memberOf _.templateSettings
       * @type RegExp
       */
      'escape': reEscape,

      /**
       * Used to detect code to be evaluated.
       *
       * @memberOf _.templateSettings
       * @type RegExp
       */
      'evaluate': reEvaluate,

      /**
       * Used to detect `data` property values to inject.
       *
       * @memberOf _.templateSettings
       * @type RegExp
       */
      'interpolate': reInterpolate,

      /**
       * Used to reference the data object in the template text.
       *
       * @memberOf _.templateSettings
       * @type string
       */
      'variable': '',

      /**
       * Used to import variables into the compiled template.
       *
       * @memberOf _.templateSettings
       * @type Object
       */
      'imports': {

        /**
         * A reference to the `lodash` function.
         *
         * @memberOf _.templateSettings.imports
         * @type Function
         */
        '_': lodash
      }
    };

    /*------------------------------------------------------------------------*/

    /**
     * Creates a lazy wrapper object which wraps `value` to enable lazy evaluation.
     *
     * @private
     * @param {*} value The value to wrap.
     */
    function LazyWrapper(value) {
      this.__wrapped__ = value;
      this.__actions__ = [];
      this.__dir__ = 1;
      this.__filtered__ = false;
      this.__iteratees__ = [];
      this.__takeCount__ = POSITIVE_INFINITY;
      this.__views__ = [];
    }

    /**
     * Creates a clone of the lazy wrapper object.
     *
     * @private
     * @name clone
     * @memberOf LazyWrapper
     * @returns {Object} Returns the cloned `LazyWrapper` object.
     */
    function lazyClone() {
      var result = new LazyWrapper(this.__wrapped__);
      result.__actions__ = arrayCopy(this.__actions__);
      result.__dir__ = this.__dir__;
      result.__filtered__ = this.__filtered__;
      result.__iteratees__ = arrayCopy(this.__iteratees__);
      result.__takeCount__ = this.__takeCount__;
      result.__views__ = arrayCopy(this.__views__);
      return result;
    }

    /**
     * Reverses the direction of lazy iteration.
     *
     * @private
     * @name reverse
     * @memberOf LazyWrapper
     * @returns {Object} Returns the new reversed `LazyWrapper` object.
     */
    function lazyReverse() {
      if (this.__filtered__) {
        var result = new LazyWrapper(this);
        result.__dir__ = -1;
        result.__filtered__ = true;
      } else {
        result = this.clone();
        result.__dir__ *= -1;
      }
      return result;
    }

    /**
     * Extracts the unwrapped value from its lazy wrapper.
     *
     * @private
     * @name value
     * @memberOf LazyWrapper
     * @returns {*} Returns the unwrapped value.
     */
    function lazyValue() {
      var array = this.__wrapped__.value(),
          dir = this.__dir__,
          isArr = isArray(array),
          isRight = dir < 0,
          arrLength = isArr ? array.length : 0,
          view = getView(0, arrLength, this.__views__),
          start = view.start,
          end = view.end,
          length = end - start,
          index = isRight ? end : (start - 1),
          iteratees = this.__iteratees__,
          iterLength = iteratees.length,
          resIndex = 0,
          takeCount = nativeMin(length, this.__takeCount__);

      if (!isArr || arrLength < LARGE_ARRAY_SIZE || (arrLength == length && takeCount == length)) {
        return baseWrapperValue((isRight && isArr) ? array.reverse() : array, this.__actions__);
      }
      var result = [];

      outer:
      while (length-- && resIndex < takeCount) {
        index += dir;

        var iterIndex = -1,
            value = array[index];

        while (++iterIndex < iterLength) {
          var data = iteratees[iterIndex],
              iteratee = data.iteratee,
              type = data.type,
              computed = iteratee(value);

          if (type == LAZY_MAP_FLAG) {
            value = computed;
          } else if (!computed) {
            if (type == LAZY_FILTER_FLAG) {
              continue outer;
            } else {
              break outer;
            }
          }
        }
        result[resIndex++] = value;
      }
      return result;
    }

    /*------------------------------------------------------------------------*/

    /**
     * Creates a cache object to store key/value pairs.
     *
     * @private
     * @static
     * @name Cache
     * @memberOf _.memoize
     */
    function MapCache() {
      this.__data__ = {};
    }

    /**
     * Removes `key` and its value from the cache.
     *
     * @private
     * @name delete
     * @memberOf _.memoize.Cache
     * @param {string} key The key of the value to remove.
     * @returns {boolean} Returns `true` if the entry was removed successfully, else `false`.
     */
    function mapDelete(key) {
      return this.has(key) && delete this.__data__[key];
    }

    /**
     * Gets the cached value for `key`.
     *
     * @private
     * @name get
     * @memberOf _.memoize.Cache
     * @param {string} key The key of the value to get.
     * @returns {*} Returns the cached value.
     */
    function mapGet(key) {
      return key == '__proto__' ? undefined : this.__data__[key];
    }

    /**
     * Checks if a cached value for `key` exists.
     *
     * @private
     * @name has
     * @memberOf _.memoize.Cache
     * @param {string} key The key of the entry to check.
     * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
     */
    function mapHas(key) {
      return key != '__proto__' && hasOwnProperty.call(this.__data__, key);
    }

    /**
     * Sets `value` to `key` of the cache.
     *
     * @private
     * @name set
     * @memberOf _.memoize.Cache
     * @param {string} key The key of the value to cache.
     * @param {*} value The value to cache.
     * @returns {Object} Returns the cache object.
     */
    function mapSet(key, value) {
      if (key != '__proto__') {
        this.__data__[key] = value;
      }
      return this;
    }

    /*------------------------------------------------------------------------*/

    /**
     *
     * Creates a cache object to store unique values.
     *
     * @private
     * @param {Array} [values] The values to cache.
     */
    function SetCache(values) {
      var length = values ? values.length : 0;

      this.data = { 'hash': nativeCreate(null), 'set': new Set };
      while (length--) {
        this.push(values[length]);
      }
    }

    /**
     * Checks if `value` is in `cache` mimicking the return signature of
     * `_.indexOf` by returning `0` if the value is found, else `-1`.
     *
     * @private
     * @param {Object} cache The cache to search.
     * @param {*} value The value to search for.
     * @returns {number} Returns `0` if `value` is found, else `-1`.
     */
    function cacheIndexOf(cache, value) {
      var data = cache.data,
          result = (typeof value == 'string' || isObject(value)) ? data.set.has(value) : data.hash[value];

      return result ? 0 : -1;
    }

    /**
     * Adds `value` to the cache.
     *
     * @private
     * @name push
     * @memberOf SetCache
     * @param {*} value The value to cache.
     */
    function cachePush(value) {
      var data = this.data;
      if (typeof value == 'string' || isObject(value)) {
        data.set.add(value);
      } else {
        data.hash[value] = true;
      }
    }

    /*------------------------------------------------------------------------*/

    /**
     * Creates a new array joining `array` with `other`.
     *
     * @private
     * @param {Array} array The array to join.
     * @param {Array} other The other array to join.
     * @returns {Array} Returns the new concatenated array.
     */
    function arrayConcat(array, other) {
      var index = -1,
          length = array.length,
          othIndex = -1,
          othLength = other.length,
          result = Array(length + othLength);

      while (++index < length) {
        result[index] = array[index];
      }
      while (++othIndex < othLength) {
        result[index++] = other[othIndex];
      }
      return result;
    }

    /**
     * Copies the values of `source` to `array`.
     *
     * @private
     * @param {Array} source The array to copy values from.
     * @param {Array} [array=[]] The array to copy values to.
     * @returns {Array} Returns `array`.
     */
    function arrayCopy(source, array) {
      var index = -1,
          length = source.length;

      array || (array = Array(length));
      while (++index < length) {
        array[index] = source[index];
      }
      return array;
    }

    /**
     * A specialized version of `_.forEach` for arrays without support for callback
     * shorthands and `this` binding.
     *
     * @private
     * @param {Array} array The array to iterate over.
     * @param {Function} iteratee The function invoked per iteration.
     * @returns {Array} Returns `array`.
     */
    function arrayEach(array, iteratee) {
      var index = -1,
          length = array.length;

      while (++index < length) {
        if (iteratee(array[index], index, array) === false) {
          break;
        }
      }
      return array;
    }

    /**
     * A specialized version of `_.forEachRight` for arrays without support for
     * callback shorthands and `this` binding.
     *
     * @private
     * @param {Array} array The array to iterate over.
     * @param {Function} iteratee The function invoked per iteration.
     * @returns {Array} Returns `array`.
     */
    function arrayEachRight(array, iteratee) {
      var length = array.length;

      while (length--) {
        if (iteratee(array[length], length, array) === false) {
          break;
        }
      }
      return array;
    }

    /**
     * A specialized version of `_.every` for arrays without support for callback
     * shorthands and `this` binding.
     *
     * @private
     * @param {Array} array The array to iterate over.
     * @param {Function} predicate The function invoked per iteration.
     * @returns {boolean} Returns `true` if all elements pass the predicate check,
     *  else `false`.
     */
    function arrayEvery(array, predicate) {
      var index = -1,
          length = array.length;

      while (++index < length) {
        if (!predicate(array[index], index, array)) {
          return false;
        }
      }
      return true;
    }

    /**
     * A specialized version of `baseExtremum` for arrays which invokes `iteratee`
     * with one argument: (value).
     *
     * @private
     * @param {Array} array The array to iterate over.
     * @param {Function} iteratee The function invoked per iteration.
     * @param {Function} comparator The function used to compare values.
     * @param {*} exValue The initial extremum value.
     * @returns {*} Returns the extremum value.
     */
    function arrayExtremum(array, iteratee, comparator, exValue) {
      var index = -1,
          length = array.length,
          computed = exValue,
          result = computed;

      while (++index < length) {
        var value = array[index],
            current = +iteratee(value);

        if (comparator(current, computed)) {
          computed = current;
          result = value;
        }
      }
      return result;
    }

    /**
     * A specialized version of `_.filter` for arrays without support for callback
     * shorthands and `this` binding.
     *
     * @private
     * @param {Array} array The array to iterate over.
     * @param {Function} predicate The function invoked per iteration.
     * @returns {Array} Returns the new filtered array.
     */
    function arrayFilter(array, predicate) {
      var index = -1,
          length = array.length,
          resIndex = -1,
          result = [];

      while (++index < length) {
        var value = array[index];
        if (predicate(value, index, array)) {
          result[++resIndex] = value;
        }
      }
      return result;
    }

    /**
     * A specialized version of `_.map` for arrays without support for callback
     * shorthands and `this` binding.
     *
     * @private
     * @param {Array} array The array to iterate over.
     * @param {Function} iteratee The function invoked per iteration.
     * @returns {Array} Returns the new mapped array.
     */
    function arrayMap(array, iteratee) {
      var index = -1,
          length = array.length,
          result = Array(length);

      while (++index < length) {
        result[index] = iteratee(array[index], index, array);
      }
      return result;
    }

    /**
     * Appends the elements of `values` to `array`.
     *
     * @private
     * @param {Array} array The array to modify.
     * @param {Array} values The values to append.
     * @returns {Array} Returns `array`.
     */
    function arrayPush(array, values) {
      var index = -1,
          length = values.length,
          offset = array.length;

      while (++index < length) {
        array[offset + index] = values[index];
      }
      return array;
    }

    /**
     * A specialized version of `_.reduce` for arrays without support for callback
     * shorthands and `this` binding.
     *
     * @private
     * @param {Array} array The array to iterate over.
     * @param {Function} iteratee The function invoked per iteration.
     * @param {*} [accumulator] The initial value.
     * @param {boolean} [initFromArray] Specify using the first element of `array`
     *  as the initial value.
     * @returns {*} Returns the accumulated value.
     */
    function arrayReduce(array, iteratee, accumulator, initFromArray) {
      var index = -1,
          length = array.length;

      if (initFromArray && length) {
        accumulator = array[++index];
      }
      while (++index < length) {
        accumulator = iteratee(accumulator, array[index], index, array);
      }
      return accumulator;
    }

    /**
     * A specialized version of `_.reduceRight` for arrays without support for
     * callback shorthands and `this` binding.
     *
     * @private
     * @param {Array} array The array to iterate over.
     * @param {Function} iteratee The function invoked per iteration.
     * @param {*} [accumulator] The initial value.
     * @param {boolean} [initFromArray] Specify using the last element of `array`
     *  as the initial value.
     * @returns {*} Returns the accumulated value.
     */
    function arrayReduceRight(array, iteratee, accumulator, initFromArray) {
      var length = array.length;
      if (initFromArray && length) {
        accumulator = array[--length];
      }
      while (length--) {
        accumulator = iteratee(accumulator, array[length], length, array);
      }
      return accumulator;
    }

    /**
     * A specialized version of `_.some` for arrays without support for callback
     * shorthands and `this` binding.
     *
     * @private
     * @param {Array} array The array to iterate over.
     * @param {Function} predicate The function invoked per iteration.
     * @returns {boolean} Returns `true` if any element passes the predicate check,
     *  else `false`.
     */
    function arraySome(array, predicate) {
      var index = -1,
          length = array.length;

      while (++index < length) {
        if (predicate(array[index], index, array)) {
          return true;
        }
      }
      return false;
    }

    /**
     * A specialized version of `_.sum` for arrays without support for callback
     * shorthands and `this` binding..
     *
     * @private
     * @param {Array} array The array to iterate over.
     * @param {Function} iteratee The function invoked per iteration.
     * @returns {number} Returns the sum.
     */
    function arraySum(array, iteratee) {
      var length = array.length,
          result = 0;

      while (length--) {
        result += +iteratee(array[length]) || 0;
      }
      return result;
    }

    /**
     * Used by `_.defaults` to customize its `_.assign` use.
     *
     * @private
     * @param {*} objectValue The destination object property value.
     * @param {*} sourceValue The source object property value.
     * @returns {*} Returns the value to assign to the destination object.
     */
    function assignDefaults(objectValue, sourceValue) {
      return objectValue === undefined ? sourceValue : objectValue;
    }

    /**
     * Used by `_.template` to customize its `_.assign` use.
     *
     * **Note:** This function is like `assignDefaults` except that it ignores
     * inherited property values when checking if a property is `undefined`.
     *
     * @private
     * @param {*} objectValue The destination object property value.
     * @param {*} sourceValue The source object property value.
     * @param {string} key The key associated with the object and source values.
     * @param {Object} object The destination object.
     * @returns {*} Returns the value to assign to the destination object.
     */
    function assignOwnDefaults(objectValue, sourceValue, key, object) {
      return (objectValue === undefined || !hasOwnProperty.call(object, key))
        ? sourceValue
        : objectValue;
    }

    /**
     * A specialized version of `_.assign` for customizing assigned values without
     * support for argument juggling, multiple sources, and `this` binding `customizer`
     * functions.
     *
     * @private
     * @param {Object} object The destination object.
     * @param {Object} source The source object.
     * @param {Function} customizer The function to customize assigned values.
     * @returns {Object} Returns `object`.
     */
    function assignWith(object, source, customizer) {
      var index = -1,
          props = keys(source),
          length = props.length;

      while (++index < length) {
        var key = props[index],
            value = object[key],
            result = customizer(value, source[key], key, object, source);

        if ((result === result ? (result !== value) : (value === value)) ||
            (value === undefined && !(key in object))) {
          object[key] = result;
        }
      }
      return object;
    }

    /**
     * The base implementation of `_.assign` without support for argument juggling,
     * multiple sources, and `customizer` functions.
     *
     * @private
     * @param {Object} object The destination object.
     * @param {Object} source The source object.
     * @returns {Object} Returns `object`.
     */
    function baseAssign(object, source) {
      return source == null
        ? object
        : baseCopy(source, keys(source), object);
    }

    /**
     * The base implementation of `_.at` without support for string collections
     * and individual key arguments.
     *
     * @private
     * @param {Array|Object} collection The collection to iterate over.
     * @param {number[]|string[]} props The property names or indexes of elements to pick.
     * @returns {Array} Returns the new array of picked elements.
     */
    function baseAt(collection, props) {
      var index = -1,
          isNil = collection == null,
          isArr = !isNil && isArrayLike(collection),
          length = isArr ? collection.length : 0,
          propsLength = props.length,
          result = Array(propsLength);

      while(++index < propsLength) {
        var key = props[index];
        if (isArr) {
          result[index] = isIndex(key, length) ? collection[key] : undefined;
        } else {
          result[index] = isNil ? undefined : collection[key];
        }
      }
      return result;
    }

    /**
     * Copies properties of `source` to `object`.
     *
     * @private
     * @param {Object} source The object to copy properties from.
     * @param {Array} props The property names to copy.
     * @param {Object} [object={}] The object to copy properties to.
     * @returns {Object} Returns `object`.
     */
    function baseCopy(source, props, object) {
      object || (object = {});

      var index = -1,
          length = props.length;

      while (++index < length) {
        var key = props[index];
        object[key] = source[key];
      }
      return object;
    }

    /**
     * The base implementation of `_.callback` which supports specifying the
     * number of arguments to provide to `func`.
     *
     * @private
     * @param {*} [func=_.identity] The value to convert to a callback.
     * @param {*} [thisArg] The `this` binding of `func`.
     * @param {number} [argCount] The number of arguments to provide to `func`.
     * @returns {Function} Returns the callback.
     */
    function baseCallback(func, thisArg, argCount) {
      var type = typeof func;
      if (type == 'function') {
        return thisArg === undefined
          ? func
          : bindCallback(func, thisArg, argCount);
      }
      if (func == null) {
        return identity;
      }
      if (type == 'object') {
        return baseMatches(func);
      }
      return thisArg === undefined
        ? property(func)
        : baseMatchesProperty(func, thisArg);
    }

    /**
     * The base implementation of `_.clone` without support for argument juggling
     * and `this` binding `customizer` functions.
     *
     * @private
     * @param {*} value The value to clone.
     * @param {boolean} [isDeep] Specify a deep clone.
     * @param {Function} [customizer] The function to customize cloning values.
     * @param {string} [key] The key of `value`.
     * @param {Object} [object] The object `value` belongs to.
     * @param {Array} [stackA=[]] Tracks traversed source objects.
     * @param {Array} [stackB=[]] Associates clones with source counterparts.
     * @returns {*} Returns the cloned value.
     */
    function baseClone(value, isDeep, customizer, key, object, stackA, stackB) {
      var result;
      if (customizer) {
        result = object ? customizer(value, key, object) : customizer(value);
      }
      if (result !== undefined) {
        return result;
      }
      if (!isObject(value)) {
        return value;
      }
      var isArr = isArray(value);
      if (isArr) {
        result = initCloneArray(value);
        if (!isDeep) {
          return arrayCopy(value, result);
        }
      } else {
        var tag = objToString.call(value),
            isFunc = tag == funcTag;

        if (tag == objectTag || tag == argsTag || (isFunc && !object)) {
          result = initCloneObject(isFunc ? {} : value);
          if (!isDeep) {
            return baseAssign(result, value);
          }
        } else {
          return cloneableTags[tag]
            ? initCloneByTag(value, tag, isDeep)
            : (object ? value : {});
        }
      }
      // Check for circular references and return its corresponding clone.
      stackA || (stackA = []);
      stackB || (stackB = []);

      var length = stackA.length;
      while (length--) {
        if (stackA[length] == value) {
          return stackB[length];
        }
      }
      // Add the source value to the stack of traversed objects and associate it with its clone.
      stackA.push(value);
      stackB.push(result);

      // Recursively populate clone (susceptible to call stack limits).
      (isArr ? arrayEach : baseForOwn)(value, function(subValue, key) {
        result[key] = baseClone(subValue, isDeep, customizer, key, value, stackA, stackB);
      });
      return result;
    }

    /**
     * The base implementation of `_.create` without support for assigning
     * properties to the created object.
     *
     * @private
     * @param {Object} prototype The object to inherit from.
     * @returns {Object} Returns the new object.
     */
    var baseCreate = (function() {
      function object() {}
      return function(prototype) {
        if (isObject(prototype)) {
          object.prototype = prototype;
          var result = new object;
          object.prototype = undefined;
        }
        return result || {};
      };
    }());

    /**
     * The base implementation of `_.delay` and `_.defer` which accepts an index
     * of where to slice the arguments to provide to `func`.
     *
     * @private
     * @param {Function} func The function to delay.
     * @param {number} wait The number of milliseconds to delay invocation.
     * @param {Object} args The arguments provide to `func`.
     * @returns {number} Returns the timer id.
     */
    function baseDelay(func, wait, args) {
      if (typeof func != 'function') {
        throw new TypeError(FUNC_ERROR_TEXT);
      }
      return setTimeout(function() { func.apply(undefined, args); }, wait);
    }

    /**
     * The base implementation of `_.difference` which accepts a single array
     * of values to exclude.
     *
     * @private
     * @param {Array} array The array to inspect.
     * @param {Array} values The values to exclude.
     * @returns {Array} Returns the new array of filtered values.
     */
    function baseDifference(array, values) {
      var length = array ? array.length : 0,
          result = [];

      if (!length) {
        return result;
      }
      var index = -1,
          indexOf = getIndexOf(),
          isCommon = indexOf == baseIndexOf,
          cache = (isCommon && values.length >= LARGE_ARRAY_SIZE) ? createCache(values) : null,
          valuesLength = values.length;

      if (cache) {
        indexOf = cacheIndexOf;
        isCommon = false;
        values = cache;
      }
      outer:
      while (++index < length) {
        var value = array[index];

        if (isCommon && value === value) {
          var valuesIndex = valuesLength;
          while (valuesIndex--) {
            if (values[valuesIndex] === value) {
              continue outer;
            }
          }
          result.push(value);
        }
        else if (indexOf(values, value, 0) < 0) {
          result.push(value);
        }
      }
      return result;
    }

    /**
     * The base implementation of `_.forEach` without support for callback
     * shorthands and `this` binding.
     *
     * @private
     * @param {Array|Object|string} collection The collection to iterate over.
     * @param {Function} iteratee The function invoked per iteration.
     * @returns {Array|Object|string} Returns `collection`.
     */
    var baseEach = createBaseEach(baseForOwn);

    /**
     * The base implementation of `_.forEachRight` without support for callback
     * shorthands and `this` binding.
     *
     * @private
     * @param {Array|Object|string} collection The collection to iterate over.
     * @param {Function} iteratee The function invoked per iteration.
     * @returns {Array|Object|string} Returns `collection`.
     */
    var baseEachRight = createBaseEach(baseForOwnRight, true);

    /**
     * The base implementation of `_.every` without support for callback
     * shorthands and `this` binding.
     *
     * @private
     * @param {Array|Object|string} collection The collection to iterate over.
     * @param {Function} predicate The function invoked per iteration.
     * @returns {boolean} Returns `true` if all elements pass the predicate check,
     *  else `false`
     */
    function baseEvery(collection, predicate) {
      var result = true;
      baseEach(collection, function(value, index, collection) {
        result = !!predicate(value, index, collection);
        return result;
      });
      return result;
    }

    /**
     * Gets the extremum value of `collection` invoking `iteratee` for each value
     * in `collection` to generate the criterion by which the value is ranked.
     * The `iteratee` is invoked with three arguments: (value, index|key, collection).
     *
     * @private
     * @param {Array|Object|string} collection The collection to iterate over.
     * @param {Function} iteratee The function invoked per iteration.
     * @param {Function} comparator The function used to compare values.
     * @param {*} exValue The initial extremum value.
     * @returns {*} Returns the extremum value.
     */
    function baseExtremum(collection, iteratee, comparator, exValue) {
      var computed = exValue,
          result = computed;

      baseEach(collection, function(value, index, collection) {
        var current = +iteratee(value, index, collection);
        if (comparator(current, computed) || (current === exValue && current === result)) {
          computed = current;
          result = value;
        }
      });
      return result;
    }

    /**
     * The base implementation of `_.fill` without an iteratee call guard.
     *
     * @private
     * @param {Array} array The array to fill.
     * @param {*} value The value to fill `array` with.
     * @param {number} [start=0] The start position.
     * @param {number} [end=array.length] The end position.
     * @returns {Array} Returns `array`.
     */
    function baseFill(array, value, start, end) {
      var length = array.length;

      start = start == null ? 0 : (+start || 0);
      if (start < 0) {
        start = -start > length ? 0 : (length + start);
      }
      end = (end === undefined || end > length) ? length : (+end || 0);
      if (end < 0) {
        end += length;
      }
      length = start > end ? 0 : (end >>> 0);
      start >>>= 0;

      while (start < length) {
        array[start++] = value;
      }
      return array;
    }

    /**
     * The base implementation of `_.filter` without support for callback
     * shorthands and `this` binding.
     *
     * @private
     * @param {Array|Object|string} collection The collection to iterate over.
     * @param {Function} predicate The function invoked per iteration.
     * @returns {Array} Returns the new filtered array.
     */
    function baseFilter(collection, predicate) {
      var result = [];
      baseEach(collection, function(value, index, collection) {
        if (predicate(value, index, collection)) {
          result.push(value);
        }
      });
      return result;
    }

    /**
     * The base implementation of `_.find`, `_.findLast`, `_.findKey`, and `_.findLastKey`,
     * without support for callback shorthands and `this` binding, which iterates
     * over `collection` using the provided `eachFunc`.
     *
     * @private
     * @param {Array|Object|string} collection The collection to search.
     * @param {Function} predicate The function invoked per iteration.
     * @param {Function} eachFunc The function to iterate over `collection`.
     * @param {boolean} [retKey] Specify returning the key of the found element
     *  instead of the element itself.
     * @returns {*} Returns the found element or its key, else `undefined`.
     */
    function baseFind(collection, predicate, eachFunc, retKey) {
      var result;
      eachFunc(collection, function(value, key, collection) {
        if (predicate(value, key, collection)) {
          result = retKey ? key : value;
          return false;
        }
      });
      return result;
    }

    /**
     * The base implementation of `_.flatten` with added support for restricting
     * flattening and specifying the start index.
     *
     * @private
     * @param {Array} array The array to flatten.
     * @param {boolean} [isDeep] Specify a deep flatten.
     * @param {boolean} [isStrict] Restrict flattening to arrays-like objects.
     * @param {Array} [result=[]] The initial result value.
     * @returns {Array} Returns the new flattened array.
     */
    function baseFlatten(array, isDeep, isStrict, result) {
      result || (result = []);

      var index = -1,
          length = array.length;

      while (++index < length) {
        var value = array[index];
        if (isObjectLike(value) && isArrayLike(value) &&
            (isStrict || isArray(value) || isArguments(value))) {
          if (isDeep) {
            // Recursively flatten arrays (susceptible to call stack limits).
            baseFlatten(value, isDeep, isStrict, result);
          } else {
            arrayPush(result, value);
          }
        } else if (!isStrict) {
          result[result.length] = value;
        }
      }
      return result;
    }

    /**
     * The base implementation of `baseForIn` and `baseForOwn` which iterates
     * over `object` properties returned by `keysFunc` invoking `iteratee` for
     * each property. Iteratee functions may exit iteration early by explicitly
     * returning `false`.
     *
     * @private
     * @param {Object} object The object to iterate over.
     * @param {Function} iteratee The function invoked per iteration.
     * @param {Function} keysFunc The function to get the keys of `object`.
     * @returns {Object} Returns `object`.
     */
    var baseFor = createBaseFor();

    /**
     * This function is like `baseFor` except that it iterates over properties
     * in the opposite order.
     *
     * @private
     * @param {Object} object The object to iterate over.
     * @param {Function} iteratee The function invoked per iteration.
     * @param {Function} keysFunc The function to get the keys of `object`.
     * @returns {Object} Returns `object`.
     */
    var baseForRight = createBaseFor(true);

    /**
     * The base implementation of `_.forIn` without support for callback
     * shorthands and `this` binding.
     *
     * @private
     * @param {Object} object The object to iterate over.
     * @param {Function} iteratee The function invoked per iteration.
     * @returns {Object} Returns `object`.
     */
    function baseForIn(object, iteratee) {
      return baseFor(object, iteratee, keysIn);
    }

    /**
     * The base implementation of `_.forOwn` without support for callback
     * shorthands and `this` binding.
     *
     * @private
     * @param {Object} object The object to iterate over.
     * @param {Function} iteratee The function invoked per iteration.
     * @returns {Object} Returns `object`.
     */
    function baseForOwn(object, iteratee) {
      return baseFor(object, iteratee, keys);
    }

    /**
     * The base implementation of `_.forOwnRight` without support for callback
     * shorthands and `this` binding.
     *
     * @private
     * @param {Object} object The object to iterate over.
     * @param {Function} iteratee The function invoked per iteration.
     * @returns {Object} Returns `object`.
     */
    function baseForOwnRight(object, iteratee) {
      return baseForRight(object, iteratee, keys);
    }

    /**
     * The base implementation of `_.functions` which creates an array of
     * `object` function property names filtered from those provided.
     *
     * @private
     * @param {Object} object The object to inspect.
     * @param {Array} props The property names to filter.
     * @returns {Array} Returns the new array of filtered property names.
     */
    function baseFunctions(object, props) {
      var index = -1,
          length = props.length,
          resIndex = -1,
          result = [];

      while (++index < length) {
        var key = props[index];
        if (isFunction(object[key])) {
          result[++resIndex] = key;
        }
      }
      return result;
    }

    /**
     * The base implementation of `get` without support for string paths
     * and default values.
     *
     * @private
     * @param {Object} object The object to query.
     * @param {Array} path The path of the property to get.
     * @param {string} [pathKey] The key representation of path.
     * @returns {*} Returns the resolved value.
     */
    function baseGet(object, path, pathKey) {
      if (object == null) {
        return;
      }
      if (pathKey !== undefined && pathKey in toObject(object)) {
        path = [pathKey];
      }
      var index = 0,
          length = path.length;

      while (object != null && index < length) {
        object = object[path[index++]];
      }
      return (index && index == length) ? object : undefined;
    }

    /**
     * The base implementation of `_.isEqual` without support for `this` binding
     * `customizer` functions.
     *
     * @private
     * @param {*} value The value to compare.
     * @param {*} other The other value to compare.
     * @param {Function} [customizer] The function to customize comparing values.
     * @param {boolean} [isLoose] Specify performing partial comparisons.
     * @param {Array} [stackA] Tracks traversed `value` objects.
     * @param {Array} [stackB] Tracks traversed `other` objects.
     * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
     */
    function baseIsEqual(value, other, customizer, isLoose, stackA, stackB) {
      if (value === other) {
        return true;
      }
      if (value == null || other == null || (!isObject(value) && !isObjectLike(other))) {
        return value !== value && other !== other;
      }
      return baseIsEqualDeep(value, other, baseIsEqual, customizer, isLoose, stackA, stackB);
    }

    /**
     * A specialized version of `baseIsEqual` for arrays and objects which performs
     * deep comparisons and tracks traversed objects enabling objects with circular
     * references to be compared.
     *
     * @private
     * @param {Object} object The object to compare.
     * @param {Object} other The other object to compare.
     * @param {Function} equalFunc The function to determine equivalents of values.
     * @param {Function} [customizer] The function to customize comparing objects.
     * @param {boolean} [isLoose] Specify performing partial comparisons.
     * @param {Array} [stackA=[]] Tracks traversed `value` objects.
     * @param {Array} [stackB=[]] Tracks traversed `other` objects.
     * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
     */
    function baseIsEqualDeep(object, other, equalFunc, customizer, isLoose, stackA, stackB) {
      var objIsArr = isArray(object),
          othIsArr = isArray(other),
          objTag = arrayTag,
          othTag = arrayTag;

      if (!objIsArr) {
        objTag = objToString.call(object);
        if (objTag == argsTag) {
          objTag = objectTag;
        } else if (objTag != objectTag) {
          objIsArr = isTypedArray(object);
        }
      }
      if (!othIsArr) {
        othTag = objToString.call(other);
        if (othTag == argsTag) {
          othTag = objectTag;
        } else if (othTag != objectTag) {
          othIsArr = isTypedArray(other);
        }
      }
      var objIsObj = objTag == objectTag,
          othIsObj = othTag == objectTag,
          isSameTag = objTag == othTag;

      if (isSameTag && !(objIsArr || objIsObj)) {
        return equalByTag(object, other, objTag);
      }
      if (!isLoose) {
        var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'),
            othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__');

        if (objIsWrapped || othIsWrapped) {
          return equalFunc(objIsWrapped ? object.value() : object, othIsWrapped ? other.value() : other, customizer, isLoose, stackA, stackB);
        }
      }
      if (!isSameTag) {
        return false;
      }
      // Assume cyclic values are equal.
      // For more information on detecting circular references see https://es5.github.io/#JO.
      stackA || (stackA = []);
      stackB || (stackB = []);

      var length = stackA.length;
      while (length--) {
        if (stackA[length] == object) {
          return stackB[length] == other;
        }
      }
      // Add `object` and `other` to the stack of traversed objects.
      stackA.push(object);
      stackB.push(other);

      var result = (objIsArr ? equalArrays : equalObjects)(object, other, equalFunc, customizer, isLoose, stackA, stackB);

      stackA.pop();
      stackB.pop();

      return result;
    }

    /**
     * The base implementation of `_.isMatch` without support for callback
     * shorthands and `this` binding.
     *
     * @private
     * @param {Object} object The object to inspect.
     * @param {Array} matchData The propery names, values, and compare flags to match.
     * @param {Function} [customizer] The function to customize comparing objects.
     * @returns {boolean} Returns `true` if `object` is a match, else `false`.
     */
    function baseIsMatch(object, matchData, customizer) {
      var index = matchData.length,
          length = index,
          noCustomizer = !customizer;

      if (object == null) {
        return !length;
      }
      object = toObject(object);
      while (index--) {
        var data = matchData[index];
        if ((noCustomizer && data[2])
              ? data[1] !== object[data[0]]
              : !(data[0] in object)
            ) {
          return false;
        }
      }
      while (++index < length) {
        data = matchData[index];
        var key = data[0],
            objValue = object[key],
            srcValue = data[1];

        if (noCustomizer && data[2]) {
          if (objValue === undefined && !(key in object)) {
            return false;
          }
        } else {
          var result = customizer ? customizer(objValue, srcValue, key) : undefined;
          if (!(result === undefined ? baseIsEqual(srcValue, objValue, customizer, true) : result)) {
            return false;
          }
        }
      }
      return true;
    }

    /**
     * The base implementation of `_.map` without support for callback shorthands
     * and `this` binding.
     *
     * @private
     * @param {Array|Object|string} collection The collection to iterate over.
     * @param {Function} iteratee The function invoked per iteration.
     * @returns {Array} Returns the new mapped array.
     */
    function baseMap(collection, iteratee) {
      var index = -1,
          result = isArrayLike(collection) ? Array(collection.length) : [];

      baseEach(collection, function(value, key, collection) {
        result[++index] = iteratee(value, key, collection);
      });
      return result;
    }

    /**
     * The base implementation of `_.matches` which does not clone `source`.
     *
     * @private
     * @param {Object} source The object of property values to match.
     * @returns {Function} Returns the new function.
     */
    function baseMatches(source) {
      var matchData = getMatchData(source);
      if (matchData.length == 1 && matchData[0][2]) {
        var key = matchData[0][0],
            value = matchData[0][1];

        return function(object) {
          if (object == null) {
            return false;
          }
          return object[key] === value && (value !== undefined || (key in toObject(object)));
        };
      }
      return function(object) {
        return baseIsMatch(object, matchData);
      };
    }

    /**
     * The base implementation of `_.matchesProperty` which does not clone `srcValue`.
     *
     * @private
     * @param {string} path The path of the property to get.
     * @param {*} srcValue The value to compare.
     * @returns {Function} Returns the new function.
     */
    function baseMatchesProperty(path, srcValue) {
      var isArr = isArray(path),
          isCommon = isKey(path) && isStrictComparable(srcValue),
          pathKey = (path + '');

      path = toPath(path);
      return function(object) {
        if (object == null) {
          return false;
        }
        var key = pathKey;
        object = toObject(object);
        if ((isArr || !isCommon) && !(key in object)) {
          object = path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1));
          if (object == null) {
            return false;
          }
          key = last(path);
          object = toObject(object);
        }
        return object[key] === srcValue
          ? (srcValue !== undefined || (key in object))
          : baseIsEqual(srcValue, object[key], undefined, true);
      };
    }

    /**
     * The base implementation of `_.merge` without support for argument juggling,
     * multiple sources, and `this` binding `customizer` functions.
     *
     * @private
     * @param {Object} object The destination object.
     * @param {Object} source The source object.
     * @param {Function} [customizer] The function to customize merged values.
     * @param {Array} [stackA=[]] Tracks traversed source objects.
     * @param {Array} [stackB=[]] Associates values with source counterparts.
     * @returns {Object} Returns `object`.
     */
    function baseMerge(object, source, customizer, stackA, stackB) {
      if (!isObject(object)) {
        return object;
      }
      var isSrcArr = isArrayLike(source) && (isArray(source) || isTypedArray(source)),
          props = isSrcArr ? undefined : keys(source);

      arrayEach(props || source, function(srcValue, key) {
        if (props) {
          key = srcValue;
          srcValue = source[key];
        }
        if (isObjectLike(srcValue)) {
          stackA || (stackA = []);
          stackB || (stackB = []);
          baseMergeDeep(object, source, key, baseMerge, customizer, stackA, stackB);
        }
        else {
          var value = object[key],
              result = customizer ? customizer(value, srcValue, key, object, source) : undefined,
              isCommon = result === undefined;

          if (isCommon) {
            result = srcValue;
          }
          if ((result !== undefined || (isSrcArr && !(key in object))) &&
              (isCommon || (result === result ? (result !== value) : (value === value)))) {
            object[key] = result;
          }
        }
      });
      return object;
    }

    /**
     * A specialized version of `baseMerge` for arrays and objects which performs
     * deep merges and tracks traversed objects enabling objects with circular
     * references to be merged.
     *
     * @private
     * @param {Object} object The destination object.
     * @param {Object} source The source object.
     * @param {string} key The key of the value to merge.
     * @param {Function} mergeFunc The function to merge values.
     * @param {Function} [customizer] The function to customize merged values.
     * @param {Array} [stackA=[]] Tracks traversed source objects.
     * @param {Array} [stackB=[]] Associates values with source counterparts.
     * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
     */
    function baseMergeDeep(object, source, key, mergeFunc, customizer, stackA, stackB) {
      var length = stackA.length,
          srcValue = source[key];

      while (length--) {
        if (stackA[length] == srcValue) {
          object[key] = stackB[length];
          return;
        }
      }
      var value = object[key],
          result = customizer ? customizer(value, srcValue, key, object, source) : undefined,
          isCommon = result === undefined;

      if (isCommon) {
        result = srcValue;
        if (isArrayLike(srcValue) && (isArray(srcValue) || isTypedArray(srcValue))) {
          result = isArray(value)
            ? value
            : (isArrayLike(value) ? arrayCopy(value) : []);
        }
        else if (isPlainObject(srcValue) || isArguments(srcValue)) {
          result = isArguments(value)
            ? toPlainObject(value)
            : (isPlainObject(value) ? value : {});
        }
        else {
          isCommon = false;
        }
      }
      // Add the source value to the stack of traversed objects and associate
      // it with its merged value.
      stackA.push(srcValue);
      stackB.push(result);

      if (isCommon) {
        // Recursively merge objects and arrays (susceptible to call stack limits).
        object[key] = mergeFunc(result, srcValue, customizer, stackA, stackB);
      } else if (result === result ? (result !== value) : (value === value)) {
        object[key] = result;
      }
    }

    /**
     * The base implementation of `_.property` without support for deep paths.
     *
     * @private
     * @param {string} key The key of the property to get.
     * @returns {Function} Returns the new function.
     */
    function baseProperty(key) {
      return function(object) {
        return object == null ? undefined : object[key];
      };
    }

    /**
     * A specialized version of `baseProperty` which supports deep paths.
     *
     * @private
     * @param {Array|string} path The path of the property to get.
     * @returns {Function} Returns the new function.
     */
    function basePropertyDeep(path) {
      var pathKey = (path + '');
      path = toPath(path);
      return function(object) {
        return baseGet(object, path, pathKey);
      };
    }

    /**
     * The base implementation of `_.pullAt` without support for individual
     * index arguments and capturing the removed elements.
     *
     * @private
     * @param {Array} array The array to modify.
     * @param {number[]} indexes The indexes of elements to remove.
     * @returns {Array} Returns `array`.
     */
    function basePullAt(array, indexes) {
      var length = array ? indexes.length : 0;
      while (length--) {
        var index = indexes[length];
        if (index != previous && isIndex(index)) {
          var previous = index;
          splice.call(array, index, 1);
        }
      }
      return array;
    }

    /**
     * The base implementation of `_.random` without support for argument juggling
     * and returning floating-point numbers.
     *
     * @private
     * @param {number} min The minimum possible value.
     * @param {number} max The maximum possible value.
     * @returns {number} Returns the random number.
     */
    function baseRandom(min, max) {
      return min + nativeFloor(nativeRandom() * (max - min + 1));
    }

    /**
     * The base implementation of `_.reduce` and `_.reduceRight` without support
     * for callback shorthands and `this` binding, which iterates over `collection`
     * using the provided `eachFunc`.
     *
     * @private
     * @param {Array|Object|string} collection The collection to iterate over.
     * @param {Function} iteratee The function invoked per iteration.
     * @param {*} accumulator The initial value.
     * @param {boolean} initFromCollection Specify using the first or last element
     *  of `collection` as the initial value.
     * @param {Function} eachFunc The function to iterate over `collection`.
     * @returns {*} Returns the accumulated value.
     */
    function baseReduce(collection, iteratee, accumulator, initFromCollection, eachFunc) {
      eachFunc(collection, function(value, index, collection) {
        accumulator = initFromCollection
          ? (initFromCollection = false, value)
          : iteratee(accumulator, value, index, collection);
      });
      return accumulator;
    }

    /**
     * The base implementation of `setData` without support for hot loop detection.
     *
     * @private
     * @param {Function} func The function to associate metadata with.
     * @param {*} data The metadata.
     * @returns {Function} Returns `func`.
     */
    var baseSetData = !metaMap ? identity : function(func, data) {
      metaMap.set(func, data);
      return func;
    };

    /**
     * The base implementation of `_.slice` without an iteratee call guard.
     *
     * @private
     * @param {Array} array The array to slice.
     * @param {number} [start=0] The start position.
     * @param {number} [end=array.length] The end position.
     * @returns {Array} Returns the slice of `array`.
     */
    function baseSlice(array, start, end) {
      var index = -1,
          length = array.length;

      start = start == null ? 0 : (+start || 0);
      if (start < 0) {
        start = -start > length ? 0 : (length + start);
      }
      end = (end === undefined || end > length) ? length : (+end || 0);
      if (end < 0) {
        end += length;
      }
      length = start > end ? 0 : ((end - start) >>> 0);
      start >>>= 0;

      var result = Array(length);
      while (++index < length) {
        result[index] = array[index + start];
      }
      return result;
    }

    /**
     * The base implementation of `_.some` without support for callback shorthands
     * and `this` binding.
     *
     * @private
     * @param {Array|Object|string} collection The collection to iterate over.
     * @param {Function} predicate The function invoked per iteration.
     * @returns {boolean} Returns `true` if any element passes the predicate check,
     *  else `false`.
     */
    function baseSome(collection, predicate) {
      var result;

      baseEach(collection, function(value, index, collection) {
        result = predicate(value, index, collection);
        return !result;
      });
      return !!result;
    }

    /**
     * The base implementation of `_.sortBy` which uses `comparer` to define
     * the sort order of `array` and replaces criteria objects with their
     * corresponding values.
     *
     * @private
     * @param {Array} array The array to sort.
     * @param {Function} comparer The function to define sort order.
     * @returns {Array} Returns `array`.
     */
    function baseSortBy(array, comparer) {
      var length = array.length;

      array.sort(comparer);
      while (length--) {
        array[length] = array[length].value;
      }
      return array;
    }

    /**
     * The base implementation of `_.sortByOrder` without param guards.
     *
     * @private
     * @param {Array|Object|string} collection The collection to iterate over.
     * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by.
     * @param {boolean[]} orders The sort orders of `iteratees`.
     * @returns {Array} Returns the new sorted array.
     */
    function baseSortByOrder(collection, iteratees, orders) {
      var callback = getCallback(),
          index = -1;

      iteratees = arrayMap(iteratees, function(iteratee) { return callback(iteratee); });

      var result = baseMap(collection, function(value) {
        var criteria = arrayMap(iteratees, function(iteratee) { return iteratee(value); });
        return { 'criteria': criteria, 'index': ++index, 'value': value };
      });

      return baseSortBy(result, function(object, other) {
        return compareMultiple(object, other, orders);
      });
    }

    /**
     * The base implementation of `_.sum` without support for callback shorthands
     * and `this` binding.
     *
     * @private
     * @param {Array|Object|string} collection The collection to iterate over.
     * @param {Function} iteratee The function invoked per iteration.
     * @returns {number} Returns the sum.
     */
    function baseSum(collection, iteratee) {
      var result = 0;
      baseEach(collection, function(value, index, collection) {
        result += +iteratee(value, index, collection) || 0;
      });
      return result;
    }

    /**
     * The base implementation of `_.uniq` without support for callback shorthands
     * and `this` binding.
     *
     * @private
     * @param {Array} array The array to inspect.
     * @param {Function} [iteratee] The function invoked per iteration.
     * @returns {Array} Returns the new duplicate-value-free array.
     */
    function baseUniq(array, iteratee) {
      var index = -1,
          indexOf = getIndexOf(),
          length = array.length,
          isCommon = indexOf == baseIndexOf,
          isLarge = isCommon && length >= LARGE_ARRAY_SIZE,
          seen = isLarge ? createCache() : null,
          result = [];

      if (seen) {
        indexOf = cacheIndexOf;
        isCommon = false;
      } else {
        isLarge = false;
        seen = iteratee ? [] : result;
      }
      outer:
      while (++index < length) {
        var value = array[index],
            computed = iteratee ? iteratee(value, index, array) : value;

        if (isCommon && value === value) {
          var seenIndex = seen.length;
          while (seenIndex--) {
            if (seen[seenIndex] === computed) {
              continue outer;
            }
          }
          if (iteratee) {
            seen.push(computed);
          }
          result.push(value);
        }
        else if (indexOf(seen, computed, 0) < 0) {
          if (iteratee || isLarge) {
            seen.push(computed);
          }
          result.push(value);
        }
      }
      return result;
    }

    /**
     * The base implementation of `_.values` and `_.valuesIn` which creates an
     * array of `object` property values corresponding to the property names
     * of `props`.
     *
     * @private
     * @param {Object} object The object to query.
     * @param {Array} props The property names to get values for.
     * @returns {Object} Returns the array of property values.
     */
    function baseValues(object, props) {
      var index = -1,
          length = props.length,
          result = Array(length);

      while (++index < length) {
        result[index] = object[props[index]];
      }
      return result;
    }

    /**
     * The base implementation of `_.dropRightWhile`, `_.dropWhile`, `_.takeRightWhile`,
     * and `_.takeWhile` without support for callback shorthands and `this` binding.
     *
     * @private
     * @param {Array} array The array to query.
     * @param {Function} predicate The function invoked per iteration.
     * @param {boolean} [isDrop] Specify dropping elements instead of taking them.
     * @param {boolean} [fromRight] Specify iterating from right to left.
     * @returns {Array} Returns the slice of `array`.
     */
    function baseWhile(array, predicate, isDrop, fromRight) {
      var length = array.length,
          index = fromRight ? length : -1;

      while ((fromRight ? index-- : ++index < length) && predicate(array[index], index, array)) {}
      return isDrop
        ? baseSlice(array, (fromRight ? 0 : index), (fromRight ? index + 1 : length))
        : baseSlice(array, (fromRight ? index + 1 : 0), (fromRight ? length : index));
    }

    /**
     * The base implementation of `wrapperValue` which returns the result of
     * performing a sequence of actions on the unwrapped `value`, where each
     * successive action is supplied the return value of the previous.
     *
     * @private
     * @param {*} value The unwrapped value.
     * @param {Array} actions Actions to peform to resolve the unwrapped value.
     * @returns {*} Returns the resolved value.
     */
    function baseWrapperValue(value, actions) {
      var result = value;
      if (result instanceof LazyWrapper) {
        result = result.value();
      }
      var index = -1,
          length = actions.length;

      while (++index < length) {
        var action = actions[index];
        result = action.func.apply(action.thisArg, arrayPush([result], action.args));
      }
      return result;
    }

    /**
     * Performs a binary search of `array` to determine the index at which `value`
     * should be inserted into `array` in order to maintain its sort order.
     *
     * @private
     * @param {Array} array The sorted array to inspect.
     * @param {*} value The value to evaluate.
     * @param {boolean} [retHighest] Specify returning the highest qualified index.
     * @returns {number} Returns the index at which `value` should be inserted
     *  into `array`.
     */
    function binaryIndex(array, value, retHighest) {
      var low = 0,
          high = array ? array.length : low;

      if (typeof value == 'number' && value === value && high <= HALF_MAX_ARRAY_LENGTH) {
        while (low < high) {
          var mid = (low + high) >>> 1,
              computed = array[mid];

          if ((retHighest ? (computed <= value) : (computed < value)) && computed !== null) {
            low = mid + 1;
          } else {
            high = mid;
          }
        }
        return high;
      }
      return binaryIndexBy(array, value, identity, retHighest);
    }

    /**
     * This function is like `binaryIndex` except that it invokes `iteratee` for
     * `value` and each element of `array` to compute their sort ranking. The
     * iteratee is invoked with one argument; (value).
     *
     * @private
     * @param {Array} array The sorted array to inspect.
     * @param {*} value The value to evaluate.
     * @param {Function} iteratee The function invoked per iteration.
     * @param {boolean} [retHighest] Specify returning the highest qualified index.
     * @returns {number} Returns the index at which `value` should be inserted
     *  into `array`.
     */
    function binaryIndexBy(array, value, iteratee, retHighest) {
      value = iteratee(value);

      var low = 0,
          high = array ? array.length : 0,
          valIsNaN = value !== value,
          valIsNull = value === null,
          valIsUndef = value === undefined;

      while (low < high) {
        var mid = nativeFloor((low + high) / 2),
            computed = iteratee(array[mid]),
            isDef = computed !== undefined,
            isReflexive = computed === computed;

        if (valIsNaN) {
          var setLow = isReflexive || retHighest;
        } else if (valIsNull) {
          setLow = isReflexive && isDef && (retHighest || computed != null);
        } else if (valIsUndef) {
          setLow = isReflexive && (retHighest || isDef);
        } else if (computed == null) {
          setLow = false;
        } else {
          setLow = retHighest ? (computed <= value) : (computed < value);
        }
        if (setLow) {
          low = mid + 1;
        } else {
          high = mid;
        }
      }
      return nativeMin(high, MAX_ARRAY_INDEX);
    }

    /**
     * A specialized version of `baseCallback` which only supports `this` binding
     * and specifying the number of arguments to provide to `func`.
     *
     * @private
     * @param {Function} func The function to bind.
     * @param {*} thisArg The `this` binding of `func`.
     * @param {number} [argCount] The number of arguments to provide to `func`.
     * @returns {Function} Returns the callback.
     */
    function bindCallback(func, thisArg, argCount) {
      if (typeof func != 'function') {
        return identity;
      }
      if (thisArg === undefined) {
        return func;
      }
      switch (argCount) {
        case 1: return function(value) {
          return func.call(thisArg, value);
        };
        case 3: return function(value, index, collection) {
          return func.call(thisArg, value, index, collection);
        };
        case 4: return function(accumulator, value, index, collection) {
          return func.call(thisArg, accumulator, value, index, collection);
        };
        case 5: return function(value, other, key, object, source) {
          return func.call(thisArg, value, other, key, object, source);
        };
      }
      return function() {
        return func.apply(thisArg, arguments);
      };
    }

    /**
     * Creates a clone of the given array buffer.
     *
     * @private
     * @param {ArrayBuffer} buffer The array buffer to clone.
     * @returns {ArrayBuffer} Returns the cloned array buffer.
     */
    function bufferClone(buffer) {
      var result = new ArrayBuffer(buffer.byteLength),
          view = new Uint8Array(result);

      view.set(new Uint8Array(buffer));
      return result;
    }

    /**
     * Creates an array that is the composition of partially applied arguments,
     * placeholders, and provided arguments into a single array of arguments.
     *
     * @private
     * @param {Array|Object} args The provided arguments.
     * @param {Array} partials The arguments to prepend to those provided.
     * @param {Array} holders The `partials` placeholder indexes.
     * @returns {Array} Returns the new array of composed arguments.
     */
    function composeArgs(args, partials, holders) {
      var holdersLength = holders.length,
          argsIndex = -1,
          argsLength = nativeMax(args.length - holdersLength, 0),
          leftIndex = -1,
          leftLength = partials.length,
          result = Array(leftLength + argsLength);

      while (++leftIndex < leftLength) {
        result[leftIndex] = partials[leftIndex];
      }
      while (++argsIndex < holdersLength) {
        result[holders[argsIndex]] = args[argsIndex];
      }
      while (argsLength--) {
        result[leftIndex++] = args[argsIndex++];
      }
      return result;
    }

    /**
     * This function is like `composeArgs` except that the arguments composition
     * is tailored for `_.partialRight`.
     *
     * @private
     * @param {Array|Object} args The provided arguments.
     * @param {Array} partials The arguments to append to those provided.
     * @param {Array} holders The `partials` placeholder indexes.
     * @returns {Array} Returns the new array of composed arguments.
     */
    function composeArgsRight(args, partials, holders) {
      var holdersIndex = -1,
          holdersLength = holders.length,
          argsIndex = -1,
          argsLength = nativeMax(args.length - holdersLength, 0),
          rightIndex = -1,
          rightLength = partials.length,
          result = Array(argsLength + rightLength);

      while (++argsIndex < argsLength) {
        result[argsIndex] = args[argsIndex];
      }
      var offset = argsIndex;
      while (++rightIndex < rightLength) {
        result[offset + rightIndex] = partials[rightIndex];
      }
      while (++holdersIndex < holdersLength) {
        result[offset + holders[holdersIndex]] = args[argsIndex++];
      }
      return result;
    }

    /**
     * Creates a `_.countBy`, `_.groupBy`, `_.indexBy`, or `_.partition` function.
     *
     * @private
     * @param {Function} setter The function to set keys and values of the accumulator object.
     * @param {Function} [initializer] The function to initialize the accumulator object.
     * @returns {Function} Returns the new aggregator function.
     */
    function createAggregator(setter, initializer) {
      return function(collection, iteratee, thisArg) {
        var result = initializer ? initializer() : {};
        iteratee = getCallback(iteratee, thisArg, 3);

        if (isArray(collection)) {
          var index = -1,
              length = collection.length;

          while (++index < length) {
            var value = collection[index];
            setter(result, value, iteratee(value, index, collection), collection);
          }
        } else {
          baseEach(collection, function(value, key, collection) {
            setter(result, value, iteratee(value, key, collection), collection);
          });
        }
        return result;
      };
    }

    /**
     * Creates a `_.assign`, `_.defaults`, or `_.merge` function.
     *
     * @private
     * @param {Function} assigner The function to assign values.
     * @returns {Function} Returns the new assigner function.
     */
    function createAssigner(assigner) {
      return restParam(function(object, sources) {
        var index = -1,
            length = object == null ? 0 : sources.length,
            customizer = length > 2 ? sources[length - 2] : undefined,
            guard = length > 2 ? sources[2] : undefined,
            thisArg = length > 1 ? sources[length - 1] : undefined;

        if (typeof customizer == 'function') {
          customizer = bindCallback(customizer, thisArg, 5);
          length -= 2;
        } else {
          customizer = typeof thisArg == 'function' ? thisArg : undefined;
          length -= (customizer ? 1 : 0);
        }
        if (guard && isIterateeCall(sources[0], sources[1], guard)) {
          customizer = length < 3 ? undefined : customizer;
          length = 1;
        }
        while (++index < length) {
          var source = sources[index];
          if (source) {
            assigner(object, source, customizer);
          }
        }
        return object;
      });
    }

    /**
     * Creates a `baseEach` or `baseEachRight` function.
     *
     * @private
     * @param {Function} eachFunc The function to iterate over a collection.
     * @param {boolean} [fromRight] Specify iterating from right to left.
     * @returns {Function} Returns the new base function.
     */
    function createBaseEach(eachFunc, fromRight) {
      return function(collection, iteratee) {
        var length = collection ? getLength(collection) : 0;
        if (!isLength(length)) {
          return eachFunc(collection, iteratee);
        }
        var index = fromRight ? length : -1,
            iterable = toObject(collection);

        while ((fromRight ? index-- : ++index < length)) {
          if (iteratee(iterable[index], index, iterable) === false) {
            break;
          }
        }
        return collection;
      };
    }

    /**
     * Creates a base function for `_.forIn` or `_.forInRight`.
     *
     * @private
     * @param {boolean} [fromRight] Specify iterating from right to left.
     * @returns {Function} Returns the new base function.
     */
    function createBaseFor(fromRight) {
      return function(object, iteratee, keysFunc) {
        var iterable = toObject(object),
            props = keysFunc(object),
            length = props.length,
            index = fromRight ? length : -1;

        while ((fromRight ? index-- : ++index < length)) {
          var key = props[index];
          if (iteratee(iterable[key], key, iterable) === false) {
            break;
          }
        }
        return object;
      };
    }

    /**
     * Creates a function that wraps `func` and invokes it with the `this`
     * binding of `thisArg`.
     *
     * @private
     * @param {Function} func The function to bind.
     * @param {*} [thisArg] The `this` binding of `func`.
     * @returns {Function} Returns the new bound function.
     */
    function createBindWrapper(func, thisArg) {
      var Ctor = createCtorWrapper(func);

      function wrapper() {
        var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
        return fn.apply(thisArg, arguments);
      }
      return wrapper;
    }

    /**
     * Creates a `Set` cache object to optimize linear searches of large arrays.
     *
     * @private
     * @param {Array} [values] The values to cache.
     * @returns {null|Object} Returns the new cache object if `Set` is supported, else `null`.
     */
    function createCache(values) {
      return (nativeCreate && Set) ? new SetCache(values) : null;
    }

    /**
     * Creates a function that produces compound words out of the words in a
     * given string.
     *
     * @private
     * @param {Function} callback The function to combine each word.
     * @returns {Function} Returns the new compounder function.
     */
    function createCompounder(callback) {
      return function(string) {
        var index = -1,
            array = words(deburr(string)),
            length = array.length,
            result = '';

        while (++index < length) {
          result = callback(result, array[index], index);
        }
        return result;
      };
    }

    /**
     * Creates a function that produces an instance of `Ctor` regardless of
     * whether it was invoked as part of a `new` expression or by `call` or `apply`.
     *
     * @private
     * @param {Function} Ctor The constructor to wrap.
     * @returns {Function} Returns the new wrapped function.
     */
    function createCtorWrapper(Ctor) {
      return function() {
        // Use a `switch` statement to work with class constructors.
        // See http://ecma-international.org/ecma-262/6.0/#sec-ecmascript-function-objects-call-thisargument-argumentslist
        // for more details.
        var args = arguments;
        switch (args.length) {
          case 0: return new Ctor;
          case 1: return new Ctor(args[0]);
          case 2: return new Ctor(args[0], args[1]);
          case 3: return new Ctor(args[0], args[1], args[2]);
          case 4: return new Ctor(args[0], args[1], args[2], args[3]);
          case 5: return new Ctor(args[0], args[1], args[2], args[3], args[4]);
          case 6: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5]);
          case 7: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5], args[6]);
        }
        var thisBinding = baseCreate(Ctor.prototype),
            result = Ctor.apply(thisBinding, args);

        // Mimic the constructor's `return` behavior.
        // See https://es5.github.io/#x13.2.2 for more details.
        return isObject(result) ? result : thisBinding;
      };
    }

    /**
     * Creates a `_.curry` or `_.curryRight` function.
     *
     * @private
     * @param {boolean} flag The curry bit flag.
     * @returns {Function} Returns the new curry function.
     */
    function createCurry(flag) {
      function curryFunc(func, arity, guard) {
        if (guard && isIterateeCall(func, arity, guard)) {
          arity = undefined;
        }
        var result = createWrapper(func, flag, undefined, undefined, undefined, undefined, undefined, arity);
        result.placeholder = curryFunc.placeholder;
        return result;
      }
      return curryFunc;
    }

    /**
     * Creates a `_.defaults` or `_.defaultsDeep` function.
     *
     * @private
     * @param {Function} assigner The function to assign values.
     * @param {Function} customizer The function to customize assigned values.
     * @returns {Function} Returns the new defaults function.
     */
    function createDefaults(assigner, customizer) {
      return restParam(function(args) {
        var object = args[0];
        if (object == null) {
          return object;
        }
        args.push(customizer);
        return assigner.apply(undefined, args);
      });
    }

    /**
     * Creates a `_.max` or `_.min` function.
     *
     * @private
     * @param {Function} comparator The function used to compare values.
     * @param {*} exValue The initial extremum value.
     * @returns {Function} Returns the new extremum function.
     */
    function createExtremum(comparator, exValue) {
      return function(collection, iteratee, thisArg) {
        if (thisArg && isIterateeCall(collection, iteratee, thisArg)) {
          iteratee = undefined;
        }
        iteratee = getCallback(iteratee, thisArg, 3);
        if (iteratee.length == 1) {
          collection = isArray(collection) ? collection : toIterable(collection);
          var result = arrayExtremum(collection, iteratee, comparator, exValue);
          if (!(collection.length && result === exValue)) {
            return result;
          }
        }
        return baseExtremum(collection, iteratee, comparator, exValue);
      };
    }

    /**
     * Creates a `_.find` or `_.findLast` function.
     *
     * @private
     * @param {Function} eachFunc The function to iterate over a collection.
     * @param {boolean} [fromRight] Specify iterating from right to left.
     * @returns {Function} Returns the new find function.
     */
    function createFind(eachFunc, fromRight) {
      return function(collection, predicate, thisArg) {
        predicate = getCallback(predicate, thisArg, 3);
        if (isArray(collection)) {
          var index = baseFindIndex(collection, predicate, fromRight);
          return index > -1 ? collection[index] : undefined;
        }
        return baseFind(collection, predicate, eachFunc);
      };
    }

    /**
     * Creates a `_.findIndex` or `_.findLastIndex` function.
     *
     * @private
     * @param {boolean} [fromRight] Specify iterating from right to left.
     * @returns {Function} Returns the new find function.
     */
    function createFindIndex(fromRight) {
      return function(array, predicate, thisArg) {
        if (!(array && array.length)) {
          return -1;
        }
        predicate = getCallback(predicate, thisArg, 3);
        return baseFindIndex(array, predicate, fromRight);
      };
    }

    /**
     * Creates a `_.findKey` or `_.findLastKey` function.
     *
     * @private
     * @param {Function} objectFunc The function to iterate over an object.
     * @returns {Function} Returns the new find function.
     */
    function createFindKey(objectFunc) {
      return function(object, predicate, thisArg) {
        predicate = getCallback(predicate, thisArg, 3);
        return baseFind(object, predicate, objectFunc, true);
      };
    }

    /**
     * Creates a `_.flow` or `_.flowRight` function.
     *
     * @private
     * @param {boolean} [fromRight] Specify iterating from right to left.
     * @returns {Function} Returns the new flow function.
     */
    function createFlow(fromRight) {
      return function() {
        var wrapper,
            length = arguments.length,
            index = fromRight ? length : -1,
            leftIndex = 0,
            funcs = Array(length);

        while ((fromRight ? index-- : ++index < length)) {
          var func = funcs[leftIndex++] = arguments[index];
          if (typeof func != 'function') {
            throw new TypeError(FUNC_ERROR_TEXT);
          }
          if (!wrapper && LodashWrapper.prototype.thru && getFuncName(func) == 'wrapper') {
            wrapper = new LodashWrapper([], true);
          }
        }
        index = wrapper ? -1 : length;
        while (++index < length) {
          func = funcs[index];

          var funcName = getFuncName(func),
              data = funcName == 'wrapper' ? getData(func) : undefined;

          if (data && isLaziable(data[0]) && data[1] == (ARY_FLAG | CURRY_FLAG | PARTIAL_FLAG | REARG_FLAG) && !data[4].length && data[9] == 1) {
            wrapper = wrapper[getFuncName(data[0])].apply(wrapper, data[3]);
          } else {
            wrapper = (func.length == 1 && isLaziable(func)) ? wrapper[funcName]() : wrapper.thru(func);
          }
        }
        return function() {
          var args = arguments,
              value = args[0];

          if (wrapper && args.length == 1 && isArray(value) && value.length >= LARGE_ARRAY_SIZE) {
            return wrapper.plant(value).value();
          }
          var index = 0,
              result = length ? funcs[index].apply(this, args) : value;

          while (++index < length) {
            result = funcs[index].call(this, result);
          }
          return result;
        };
      };
    }

    /**
     * Creates a function for `_.forEach` or `_.forEachRight`.
     *
     * @private
     * @param {Function} arrayFunc The function to iterate over an array.
     * @param {Function} eachFunc The function to iterate over a collection.
     * @returns {Function} Returns the new each function.
     */
    function createForEach(arrayFunc, eachFunc) {
      return function(collection, iteratee, thisArg) {
        return (typeof iteratee == 'function' && thisArg === undefined && isArray(collection))
          ? arrayFunc(collection, iteratee)
          : eachFunc(collection, bindCallback(iteratee, thisArg, 3));
      };
    }

    /**
     * Creates a function for `_.forIn` or `_.forInRight`.
     *
     * @private
     * @param {Function} objectFunc The function to iterate over an object.
     * @returns {Function} Returns the new each function.
     */
    function createForIn(objectFunc) {
      return function(object, iteratee, thisArg) {
        if (typeof iteratee != 'function' || thisArg !== undefined) {
          iteratee = bindCallback(iteratee, thisArg, 3);
        }
        return objectFunc(object, iteratee, keysIn);
      };
    }

    /**
     * Creates a function for `_.forOwn` or `_.forOwnRight`.
     *
     * @private
     * @param {Function} objectFunc The function to iterate over an object.
     * @returns {Function} Returns the new each function.
     */
    function createForOwn(objectFunc) {
      return function(object, iteratee, thisArg) {
        if (typeof iteratee != 'function' || thisArg !== undefined) {
          iteratee = bindCallback(iteratee, thisArg, 3);
        }
        return objectFunc(object, iteratee);
      };
    }

    /**
     * Creates a function for `_.mapKeys` or `_.mapValues`.
     *
     * @private
     * @param {boolean} [isMapKeys] Specify mapping keys instead of values.
     * @returns {Function} Returns the new map function.
     */
    function createObjectMapper(isMapKeys) {
      return function(object, iteratee, thisArg) {
        var result = {};
        iteratee = getCallback(iteratee, thisArg, 3);

        baseForOwn(object, function(value, key, object) {
          var mapped = iteratee(value, key, object);
          key = isMapKeys ? mapped : key;
          value = isMapKeys ? value : mapped;
          result[key] = value;
        });
        return result;
      };
    }

    /**
     * Creates a function for `_.padLeft` or `_.padRight`.
     *
     * @private
     * @param {boolean} [fromRight] Specify padding from the right.
     * @returns {Function} Returns the new pad function.
     */
    function createPadDir(fromRight) {
      return function(string, length, chars) {
        string = baseToString(string);
        return (fromRight ? string : '') + createPadding(string, length, chars) + (fromRight ? '' : string);
      };
    }

    /**
     * Creates a `_.partial` or `_.partialRight` function.
     *
     * @private
     * @param {boolean} flag The partial bit flag.
     * @returns {Function} Returns the new partial function.
     */
    function createPartial(flag) {
      var partialFunc = restParam(function(func, partials) {
        var holders = replaceHolders(partials, partialFunc.placeholder);
        return createWrapper(func, flag, undefined, partials, holders);
      });
      return partialFunc;
    }

    /**
     * Creates a function for `_.reduce` or `_.reduceRight`.
     *
     * @private
     * @param {Function} arrayFunc The function to iterate over an array.
     * @param {Function} eachFunc The function to iterate over a collection.
     * @returns {Function} Returns the new each function.
     */
    function createReduce(arrayFunc, eachFunc) {
      return function(collection, iteratee, accumulator, thisArg) {
        var initFromArray = arguments.length < 3;
        return (typeof iteratee == 'function' && thisArg === undefined && isArray(collection))
          ? arrayFunc(collection, iteratee, accumulator, initFromArray)
          : baseReduce(collection, getCallback(iteratee, thisArg, 4), accumulator, initFromArray, eachFunc);
      };
    }

    /**
     * Creates a function that wraps `func` and invokes it with optional `this`
     * binding of, partial application, and currying.
     *
     * @private
     * @param {Function|string} func The function or method name to reference.
     * @param {number} bitmask The bitmask of flags. See `createWrapper` for more details.
     * @param {*} [thisArg] The `this` binding of `func`.
     * @param {Array} [partials] The arguments to prepend to those provided to the new function.
     * @param {Array} [holders] The `partials` placeholder indexes.
     * @param {Array} [partialsRight] The arguments to append to those provided to the new function.
     * @param {Array} [holdersRight] The `partialsRight` placeholder indexes.
     * @param {Array} [argPos] The argument positions of the new function.
     * @param {number} [ary] The arity cap of `func`.
     * @param {number} [arity] The arity of `func`.
     * @returns {Function} Returns the new wrapped function.
     */
    function createHybridWrapper(func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity) {
      var isAry = bitmask & ARY_FLAG,
          isBind = bitmask & BIND_FLAG,
          isBindKey = bitmask & BIND_KEY_FLAG,
          isCurry = bitmask & CURRY_FLAG,
          isCurryBound = bitmask & CURRY_BOUND_FLAG,
          isCurryRight = bitmask & CURRY_RIGHT_FLAG,
          Ctor = isBindKey ? undefined : createCtorWrapper(func);

      function wrapper() {
        // Avoid `arguments` object use disqualifying optimizations by
        // converting it to an array before providing it to other functions.
        var length = arguments.length,
            index = length,
            args = Array(length);

        while (index--) {
          args[index] = arguments[index];
        }
        if (partials) {
          args = composeArgs(args, partials, holders);
        }
        if (partialsRight) {
          args = composeArgsRight(args, partialsRight, holdersRight);
        }
        if (isCurry || isCurryRight) {
          var placeholder = wrapper.placeholder,
              argsHolders = replaceHolders(args, placeholder);

          length -= argsHolders.length;
          if (length < arity) {
            var newArgPos = argPos ? arrayCopy(argPos) : undefined,
                newArity = nativeMax(arity - length, 0),
                newsHolders = isCurry ? argsHolders : undefined,
                newHoldersRight = isCurry ? undefined : argsHolders,
                newPartials = isCurry ? args : undefined,
                newPartialsRight = isCurry ? undefined : args;

            bitmask |= (isCurry ? PARTIAL_FLAG : PARTIAL_RIGHT_FLAG);
            bitmask &= ~(isCurry ? PARTIAL_RIGHT_FLAG : PARTIAL_FLAG);

            if (!isCurryBound) {
              bitmask &= ~(BIND_FLAG | BIND_KEY_FLAG);
            }
            var newData = [func, bitmask, thisArg, newPartials, newsHolders, newPartialsRight, newHoldersRight, newArgPos, ary, newArity],
                result = createHybridWrapper.apply(undefined, newData);

            if (isLaziable(func)) {
              setData(result, newData);
            }
            result.placeholder = placeholder;
            return result;
          }
        }
        var thisBinding = isBind ? thisArg : this,
            fn = isBindKey ? thisBinding[func] : func;

        if (argPos) {
          args = reorder(args, argPos);
        }
        if (isAry && ary < args.length) {
          args.length = ary;
        }
        if (this && this !== root && this instanceof wrapper) {
          fn = Ctor || createCtorWrapper(func);
        }
        return fn.apply(thisBinding, args);
      }
      return wrapper;
    }

    /**
     * Creates the padding required for `string` based on the given `length`.
     * The `chars` string is truncated if the number of characters exceeds `length`.
     *
     * @private
     * @param {string} string The string to create padding for.
     * @param {number} [length=0] The padding length.
     * @param {string} [chars=' '] The string used as padding.
     * @returns {string} Returns the pad for `string`.
     */
    function createPadding(string, length, chars) {
      var strLength = string.length;
      length = +length;

      if (strLength >= length || !nativeIsFinite(length)) {
        return '';
      }
      var padLength = length - strLength;
      chars = chars == null ? ' ' : (chars + '');
      return repeat(chars, nativeCeil(padLength / chars.length)).slice(0, padLength);
    }

    /**
     * Creates a function that wraps `func` and invokes it with the optional `this`
     * binding of `thisArg` and the `partials` prepended to those provided to
     * the wrapper.
     *
     * @private
     * @param {Function} func The function to partially apply arguments to.
     * @param {number} bitmask The bitmask of flags. See `createWrapper` for more details.
     * @param {*} thisArg The `this` binding of `func`.
     * @param {Array} partials The arguments to prepend to those provided to the new function.
     * @returns {Function} Returns the new bound function.
     */
    function createPartialWrapper(func, bitmask, thisArg, partials) {
      var isBind = bitmask & BIND_FLAG,
          Ctor = createCtorWrapper(func);

      function wrapper() {
        // Avoid `arguments` object use disqualifying optimizations by
        // converting it to an array before providing it `func`.
        var argsIndex = -1,
            argsLength = arguments.length,
            leftIndex = -1,
            leftLength = partials.length,
            args = Array(leftLength + argsLength);

        while (++leftIndex < leftLength) {
          args[leftIndex] = partials[leftIndex];
        }
        while (argsLength--) {
          args[leftIndex++] = arguments[++argsIndex];
        }
        var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
        return fn.apply(isBind ? thisArg : this, args);
      }
      return wrapper;
    }

    /**
     * Creates a `_.ceil`, `_.floor`, or `_.round` function.
     *
     * @private
     * @param {string} methodName The name of the `Math` method to use when rounding.
     * @returns {Function} Returns the new round function.
     */
    function createRound(methodName) {
      var func = Math[methodName];
      return function(number, precision) {
        precision = precision === undefined ? 0 : (+precision || 0);
        if (precision) {
          precision = pow(10, precision);
          return func(number * precision) / precision;
        }
        return func(number);
      };
    }

    /**
     * Creates a `_.sortedIndex` or `_.sortedLastIndex` function.
     *
     * @private
     * @param {boolean} [retHighest] Specify returning the highest qualified index.
     * @returns {Function} Returns the new index function.
     */
    function createSortedIndex(retHighest) {
      return function(array, value, iteratee, thisArg) {
        var callback = getCallback(iteratee);
        return (iteratee == null && callback === baseCallback)
          ? binaryIndex(array, value, retHighest)
          : binaryIndexBy(array, value, callback(iteratee, thisArg, 1), retHighest);
      };
    }

    /**
     * Creates a function that either curries or invokes `func` with optional
     * `this` binding and partially applied arguments.
     *
     * @private
     * @param {Function|string} func The function or method name to reference.
     * @param {number} bitmask The bitmask of flags.
     *  The bitmask may be composed of the following flags:
     *     1 - `_.bind`
     *     2 - `_.bindKey`
     *     4 - `_.curry` or `_.curryRight` of a bound function
     *     8 - `_.curry`
     *    16 - `_.curryRight`
     *    32 - `_.partial`
     *    64 - `_.partialRight`
     *   128 - `_.rearg`
     *   256 - `_.ary`
     * @param {*} [thisArg] The `this` binding of `func`.
     * @param {Array} [partials] The arguments to be partially applied.
     * @param {Array} [holders] The `partials` placeholder indexes.
     * @param {Array} [argPos] The argument positions of the new function.
     * @param {number} [ary] The arity cap of `func`.
     * @param {number} [arity] The arity of `func`.
     * @returns {Function} Returns the new wrapped function.
     */
    function createWrapper(func, bitmask, thisArg, partials, holders, argPos, ary, arity) {
      var isBindKey = bitmask & BIND_KEY_FLAG;
      if (!isBindKey && typeof func != 'function') {
        throw new TypeError(FUNC_ERROR_TEXT);
      }
      var length = partials ? partials.length : 0;
      if (!length) {
        bitmask &= ~(PARTIAL_FLAG | PARTIAL_RIGHT_FLAG);
        partials = holders = undefined;
      }
      length -= (holders ? holders.length : 0);
      if (bitmask & PARTIAL_RIGHT_FLAG) {
        var partialsRight = partials,
            holdersRight = holders;

        partials = holders = undefined;
      }
      var data = isBindKey ? undefined : getData(func),
          newData = [func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity];

      if (data) {
        mergeData(newData, data);
        bitmask = newData[1];
        arity = newData[9];
      }
      newData[9] = arity == null
        ? (isBindKey ? 0 : func.length)
        : (nativeMax(arity - length, 0) || 0);

      if (bitmask == BIND_FLAG) {
        var result = createBindWrapper(newData[0], newData[2]);
      } else if ((bitmask == PARTIAL_FLAG || bitmask == (BIND_FLAG | PARTIAL_FLAG)) && !newData[4].length) {
        result = createPartialWrapper.apply(undefined, newData);
      } else {
        result = createHybridWrapper.apply(undefined, newData);
      }
      var setter = data ? baseSetData : setData;
      return setter(result, newData);
    }

    /**
     * A specialized version of `baseIsEqualDeep` for arrays with support for
     * partial deep comparisons.
     *
     * @private
     * @param {Array} array The array to compare.
     * @param {Array} other The other array to compare.
     * @param {Function} equalFunc The function to determine equivalents of values.
     * @param {Function} [customizer] The function to customize comparing arrays.
     * @param {boolean} [isLoose] Specify performing partial comparisons.
     * @param {Array} [stackA] Tracks traversed `value` objects.
     * @param {Array} [stackB] Tracks traversed `other` objects.
     * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`.
     */
    function equalArrays(array, other, equalFunc, customizer, isLoose, stackA, stackB) {
      var index = -1,
          arrLength = array.length,
          othLength = other.length;

      if (arrLength != othLength && !(isLoose && othLength > arrLength)) {
        return false;
      }
      // Ignore non-index properties.
      while (++index < arrLength) {
        var arrValue = array[index],
            othValue = other[index],
            result = customizer ? customizer(isLoose ? othValue : arrValue, isLoose ? arrValue : othValue, index) : undefined;

        if (result !== undefined) {
          if (result) {
            continue;
          }
          return false;
        }
        // Recursively compare arrays (susceptible to call stack limits).
        if (isLoose) {
          if (!arraySome(other, function(othValue) {
                return arrValue === othValue || equalFunc(arrValue, othValue, customizer, isLoose, stackA, stackB);
              })) {
            return false;
          }
        } else if (!(arrValue === othValue || equalFunc(arrValue, othValue, customizer, isLoose, stackA, stackB))) {
          return false;
        }
      }
      return true;
    }

    /**
     * A specialized version of `baseIsEqualDeep` for comparing objects of
     * the same `toStringTag`.
     *
     * **Note:** This function only supports comparing values with tags of
     * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.
     *
     * @private
     * @param {Object} object The object to compare.
     * @param {Object} other The other object to compare.
     * @param {string} tag The `toStringTag` of the objects to compare.
     * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
     */
    function equalByTag(object, other, tag) {
      switch (tag) {
        case boolTag:
        case dateTag:
          // Coerce dates and booleans to numbers, dates to milliseconds and booleans
          // to `1` or `0` treating invalid dates coerced to `NaN` as not equal.
          return +object == +other;

        case errorTag:
          return object.name == other.name && object.message == other.message;

        case numberTag:
          // Treat `NaN` vs. `NaN` as equal.
          return (object != +object)
            ? other != +other
            : object == +other;

        case regexpTag:
        case stringTag:
          // Coerce regexes to strings and treat strings primitives and string
          // objects as equal. See https://es5.github.io/#x15.10.6.4 for more details.
          return object == (other + '');
      }
      return false;
    }

    /**
     * A specialized version of `baseIsEqualDeep` for objects with support for
     * partial deep comparisons.
     *
     * @private
     * @param {Object} object The object to compare.
     * @param {Object} other The other object to compare.
     * @param {Function} equalFunc The function to determine equivalents of values.
     * @param {Function} [customizer] The function to customize comparing values.
     * @param {boolean} [isLoose] Specify performing partial comparisons.
     * @param {Array} [stackA] Tracks traversed `value` objects.
     * @param {Array} [stackB] Tracks traversed `other` objects.
     * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
     */
    function equalObjects(object, other, equalFunc, customizer, isLoose, stackA, stackB) {
      var objProps = keys(object),
          objLength = objProps.length,
          othProps = keys(other),
          othLength = othProps.length;

      if (objLength != othLength && !isLoose) {
        return false;
      }
      var index = objLength;
      while (index--) {
        var key = objProps[index];
        if (!(isLoose ? key in other : hasOwnProperty.call(other, key))) {
          return false;
        }
      }
      var skipCtor = isLoose;
      while (++index < objLength) {
        key = objProps[index];
        var objValue = object[key],
            othValue = other[key],
            result = customizer ? customizer(isLoose ? othValue : objValue, isLoose? objValue : othValue, key) : undefined;

        // Recursively compare objects (susceptible to call stack limits).
        if (!(result === undefined ? equalFunc(objValue, othValue, customizer, isLoose, stackA, stackB) : result)) {
          return false;
        }
        skipCtor || (skipCtor = key == 'constructor');
      }
      if (!skipCtor) {
        var objCtor = object.constructor,
            othCtor = other.constructor;

        // Non `Object` object instances with different constructors are not equal.
        if (objCtor != othCtor &&
            ('constructor' in object && 'constructor' in other) &&
            !(typeof objCtor == 'function' && objCtor instanceof objCtor &&
              typeof othCtor == 'function' && othCtor instanceof othCtor)) {
          return false;
        }
      }
      return true;
    }

    /**
     * Gets the appropriate "callback" function. If the `_.callback` method is
     * customized this function returns the custom method, otherwise it returns
     * the `baseCallback` function. If arguments are provided the chosen function
     * is invoked with them and its result is returned.
     *
     * @private
     * @returns {Function} Returns the chosen function or its result.
     */
    function getCallback(func, thisArg, argCount) {
      var result = lodash.callback || callback;
      result = result === callback ? baseCallback : result;
      return argCount ? result(func, thisArg, argCount) : result;
    }

    /**
     * Gets metadata for `func`.
     *
     * @private
     * @param {Function} func The function to query.
     * @returns {*} Returns the metadata for `func`.
     */
    var getData = !metaMap ? noop : function(func) {
      return metaMap.get(func);
    };

    /**
     * Gets the name of `func`.
     *
     * @private
     * @param {Function} func The function to query.
     * @returns {string} Returns the function name.
     */
    function getFuncName(func) {
      var result = func.name,
          array = realNames[result],
          length = array ? array.length : 0;

      while (length--) {
        var data = array[length],
            otherFunc = data.func;
        if (otherFunc == null || otherFunc == func) {
          return data.name;
        }
      }
      return result;
    }

    /**
     * Gets the appropriate "indexOf" function. If the `_.indexOf` method is
     * customized this function returns the custom method, otherwise it returns
     * the `baseIndexOf` function. If arguments are provided the chosen function
     * is invoked with them and its result is returned.
     *
     * @private
     * @returns {Function|number} Returns the chosen function or its result.
     */
    function getIndexOf(collection, target, fromIndex) {
      var result = lodash.indexOf || indexOf;
      result = result === indexOf ? baseIndexOf : result;
      return collection ? result(collection, target, fromIndex) : result;
    }

    /**
     * Gets the "length" property value of `object`.
     *
     * **Note:** This function is used to avoid a [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792)
     * that affects Safari on at least iOS 8.1-8.3 ARM64.
     *
     * @private
     * @param {Object} object The object to query.
     * @returns {*} Returns the "length" value.
     */
    var getLength = baseProperty('length');

    /**
     * Gets the propery names, values, and compare flags of `object`.
     *
     * @private
     * @param {Object} object The object to query.
     * @returns {Array} Returns the match data of `object`.
     */
    function getMatchData(object) {
      var result = pairs(object),
          length = result.length;

      while (length--) {
        result[length][2] = isStrictComparable(result[length][1]);
      }
      return result;
    }

    /**
     * Gets the native function at `key` of `object`.
     *
     * @private
     * @param {Object} object The object to query.
     * @param {string} key The key of the method to get.
     * @returns {*} Returns the function if it's native, else `undefined`.
     */
    function getNative(object, key) {
      var value = object == null ? undefined : object[key];
      return isNative(value) ? value : undefined;
    }

    /**
     * Gets the view, applying any `transforms` to the `start` and `end` positions.
     *
     * @private
     * @param {number} start The start of the view.
     * @param {number} end The end of the view.
     * @param {Array} transforms The transformations to apply to the view.
     * @returns {Object} Returns an object containing the `start` and `end`
     *  positions of the view.
     */
    function getView(start, end, transforms) {
      var index = -1,
          length = transforms.length;

      while (++index < length) {
        var data = transforms[index],
            size = data.size;

        switch (data.type) {
          case 'drop':      start += size; break;
          case 'dropRight': end -= size; break;
          case 'take':      end = nativeMin(end, start + size); break;
          case 'takeRight': start = nativeMax(start, end - size); break;
        }
      }
      return { 'start': start, 'end': end };
    }

    /**
     * Initializes an array clone.
     *
     * @private
     * @param {Array} array The array to clone.
     * @returns {Array} Returns the initialized clone.
     */
    function initCloneArray(array) {
      var length = array.length,
          result = new array.constructor(length);

      // Add array properties assigned by `RegExp#exec`.
      if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) {
        result.index = array.index;
        result.input = array.input;
      }
      return result;
    }

    /**
     * Initializes an object clone.
     *
     * @private
     * @param {Object} object The object to clone.
     * @returns {Object} Returns the initialized clone.
     */
    function initCloneObject(object) {
      var Ctor = object.constructor;
      if (!(typeof Ctor == 'function' && Ctor instanceof Ctor)) {
        Ctor = Object;
      }
      return new Ctor;
    }

    /**
     * Initializes an object clone based on its `toStringTag`.
     *
     * **Note:** This function only supports cloning values with tags of
     * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.
     *
     * @private
     * @param {Object} object The object to clone.
     * @param {string} tag The `toStringTag` of the object to clone.
     * @param {boolean} [isDeep] Specify a deep clone.
     * @returns {Object} Returns the initialized clone.
     */
    function initCloneByTag(object, tag, isDeep) {
      var Ctor = object.constructor;
      switch (tag) {
        case arrayBufferTag:
          return bufferClone(object);

        case boolTag:
        case dateTag:
          return new Ctor(+object);

        case float32Tag: case float64Tag:
        case int8Tag: case int16Tag: case int32Tag:
        case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag:
          var buffer = object.buffer;
          return new Ctor(isDeep ? bufferClone(buffer) : buffer, object.byteOffset, object.length);

        case numberTag:
        case stringTag:
          return new Ctor(object);

        case regexpTag:
          var result = new Ctor(object.source, reFlags.exec(object));
          result.lastIndex = object.lastIndex;
      }
      return result;
    }

    /**
     * Invokes the method at `path` on `object`.
     *
     * @private
     * @param {Object} object The object to query.
     * @param {Array|string} path The path of the method to invoke.
     * @param {Array} args The arguments to invoke the method with.
     * @returns {*} Returns the result of the invoked method.
     */
    function invokePath(object, path, args) {
      if (object != null && !isKey(path, object)) {
        path = toPath(path);
        object = path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1));
        path = last(path);
      }
      var func = object == null ? object : object[path];
      return func == null ? undefined : func.apply(object, args);
    }

    /**
     * Checks if `value` is array-like.
     *
     * @private
     * @param {*} value The value to check.
     * @returns {boolean} Returns `true` if `value` is array-like, else `false`.
     */
    function isArrayLike(value) {
      return value != null && isLength(getLength(value));
    }

    /**
     * Checks if `value` is a valid array-like index.
     *
     * @private
     * @param {*} value The value to check.
     * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
     * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
     */
    function isIndex(value, length) {
      value = (typeof value == 'number' || reIsUint.test(value)) ? +value : -1;
      length = length == null ? MAX_SAFE_INTEGER : length;
      return value > -1 && value % 1 == 0 && value < length;
    }

    /**
     * Checks if the provided arguments are from an iteratee call.
     *
     * @private
     * @param {*} value The potential iteratee value argument.
     * @param {*} index The potential iteratee index or key argument.
     * @param {*} object The potential iteratee object argument.
     * @returns {boolean} Returns `true` if the arguments are from an iteratee call, else `false`.
     */
    function isIterateeCall(value, index, object) {
      if (!isObject(object)) {
        return false;
      }
      var type = typeof index;
      if (type == 'number'
          ? (isArrayLike(object) && isIndex(index, object.length))
          : (type == 'string' && index in object)) {
        var other = object[index];
        return value === value ? (value === other) : (other !== other);
      }
      return false;
    }

    /**
     * Checks if `value` is a property name and not a property path.
     *
     * @private
     * @param {*} value The value to check.
     * @param {Object} [object] The object to query keys on.
     * @returns {boolean} Returns `true` if `value` is a property name, else `false`.
     */
    function isKey(value, object) {
      var type = typeof value;
      if ((type == 'string' && reIsPlainProp.test(value)) || type == 'number') {
        return true;
      }
      if (isArray(value)) {
        return false;
      }
      var result = !reIsDeepProp.test(value);
      return result || (object != null && value in toObject(object));
    }

    /**
     * Checks if `func` has a lazy counterpart.
     *
     * @private
     * @param {Function} func The function to check.
     * @returns {boolean} Returns `true` if `func` has a lazy counterpart, else `false`.
     */
    function isLaziable(func) {
      var funcName = getFuncName(func);
      if (!(funcName in LazyWrapper.prototype)) {
        return false;
      }
      var other = lodash[funcName];
      if (func === other) {
        return true;
      }
      var data = getData(other);
      return !!data && func === data[0];
    }

    /**
     * Checks if `value` is a valid array-like length.
     *
     * **Note:** This function is based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength).
     *
     * @private
     * @param {*} value The value to check.
     * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
     */
    function isLength(value) {
      return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
    }

    /**
     * Checks if `value` is suitable for strict equality comparisons, i.e. `===`.
     *
     * @private
     * @param {*} value The value to check.
     * @returns {boolean} Returns `true` if `value` if suitable for strict
     *  equality comparisons, else `false`.
     */
    function isStrictComparable(value) {
      return value === value && !isObject(value);
    }

    /**
     * Merges the function metadata of `source` into `data`.
     *
     * Merging metadata reduces the number of wrappers required to invoke a function.
     * This is possible because methods like `_.bind`, `_.curry`, and `_.partial`
     * may be applied regardless of execution order. Methods like `_.ary` and `_.rearg`
     * augment function arguments, making the order in which they are executed important,
     * preventing the merging of metadata. However, we make an exception for a safe
     * common case where curried functions have `_.ary` and or `_.rearg` applied.
     *
     * @private
     * @param {Array} data The destination metadata.
     * @param {Array} source The source metadata.
     * @returns {Array} Returns `data`.
     */
    function mergeData(data, source) {
      var bitmask = data[1],
          srcBitmask = source[1],
          newBitmask = bitmask | srcBitmask,
          isCommon = newBitmask < ARY_FLAG;

      var isCombo =
        (srcBitmask == ARY_FLAG && bitmask == CURRY_FLAG) ||
        (srcBitmask == ARY_FLAG && bitmask == REARG_FLAG && data[7].length <= source[8]) ||
        (srcBitmask == (ARY_FLAG | REARG_FLAG) && bitmask == CURRY_FLAG);

      // Exit early if metadata can't be merged.
      if (!(isCommon || isCombo)) {
        return data;
      }
      // Use source `thisArg` if available.
      if (srcBitmask & BIND_FLAG) {
        data[2] = source[2];
        // Set when currying a bound function.
        newBitmask |= (bitmask & BIND_FLAG) ? 0 : CURRY_BOUND_FLAG;
      }
      // Compose partial arguments.
      var value = source[3];
      if (value) {
        var partials = data[3];
        data[3] = partials ? composeArgs(partials, value, source[4]) : arrayCopy(value);
        data[4] = partials ? replaceHolders(data[3], PLACEHOLDER) : arrayCopy(source[4]);
      }
      // Compose partial right arguments.
      value = source[5];
      if (value) {
        partials = data[5];
        data[5] = partials ? composeArgsRight(partials, value, source[6]) : arrayCopy(value);
        data[6] = partials ? replaceHolders(data[5], PLACEHOLDER) : arrayCopy(source[6]);
      }
      // Use source `argPos` if available.
      value = source[7];
      if (value) {
        data[7] = arrayCopy(value);
      }
      // Use source `ary` if it's smaller.
      if (srcBitmask & ARY_FLAG) {
        data[8] = data[8] == null ? source[8] : nativeMin(data[8], source[8]);
      }
      // Use source `arity` if one is not provided.
      if (data[9] == null) {
        data[9] = source[9];
      }
      // Use source `func` and merge bitmasks.
      data[0] = source[0];
      data[1] = newBitmask;

      return data;
    }

    /**
     * Used by `_.defaultsDeep` to customize its `_.merge` use.
     *
     * @private
     * @param {*} objectValue The destination object property value.
     * @param {*} sourceValue The source object property value.
     * @returns {*} Returns the value to assign to the destination object.
     */
    function mergeDefaults(objectValue, sourceValue) {
      return objectValue === undefined ? sourceValue : merge(objectValue, sourceValue, mergeDefaults);
    }

    /**
     * A specialized version of `_.pick` which picks `object` properties specified
     * by `props`.
     *
     * @private
     * @param {Object} object The source object.
     * @param {string[]} props The property names to pick.
     * @returns {Object} Returns the new object.
     */
    function pickByArray(object, props) {
      object = toObject(object);

      var index = -1,
          length = props.length,
          result = {};

      while (++index < length) {
        var key = props[index];
        if (key in object) {
          result[key] = object[key];
        }
      }
      return result;
    }

    /**
     * A specialized version of `_.pick` which picks `object` properties `predicate`
     * returns truthy for.
     *
     * @private
     * @param {Object} object The source object.
     * @param {Function} predicate The function invoked per iteration.
     * @returns {Object} Returns the new object.
     */
    function pickByCallback(object, predicate) {
      var result = {};
      baseForIn(object, function(value, key, object) {
        if (predicate(value, key, object)) {
          result[key] = value;
        }
      });
      return result;
    }

    /**
     * Reorder `array` according to the specified indexes where the element at
     * the first index is assigned as the first element, the element at
     * the second index is assigned as the second element, and so on.
     *
     * @private
     * @param {Array} array The array to reorder.
     * @param {Array} indexes The arranged array indexes.
     * @returns {Array} Returns `array`.
     */
    function reorder(array, indexes) {
      var arrLength = array.length,
          length = nativeMin(indexes.length, arrLength),
          oldArray = arrayCopy(array);

      while (length--) {
        var index = indexes[length];
        array[length] = isIndex(index, arrLength) ? oldArray[index] : undefined;
      }
      return array;
    }

    /**
     * Sets metadata for `func`.
     *
     * **Note:** If this function becomes hot, i.e. is invoked a lot in a short
     * period of time, it will trip its breaker and transition to an identity function
     * to avoid garbage collection pauses in V8. See [V8 issue 2070](https://code.google.com/p/v8/issues/detail?id=2070)
     * for more details.
     *
     * @private
     * @param {Function} func The function to associate metadata with.
     * @param {*} data The metadata.
     * @returns {Function} Returns `func`.
     */
    var setData = (function() {
      var count = 0,
          lastCalled = 0;

      return function(key, value) {
        var stamp = now(),
            remaining = HOT_SPAN - (stamp - lastCalled);

        lastCalled = stamp;
        if (remaining > 0) {
          if (++count >= HOT_COUNT) {
            return key;
          }
        } else {
          count = 0;
        }
        return baseSetData(key, value);
      };
    }());

    /**
     * A fallback implementation of `Object.keys` which creates an array of the
     * own enumerable property names of `object`.
     *
     * @private
     * @param {Object} object The object to query.
     * @returns {Array} Returns the array of property names.
     */
    function shimKeys(object) {
      var props = keysIn(object),
          propsLength = props.length,
          length = propsLength && object.length;

      var allowIndexes = !!length && isLength(length) &&
        (isArray(object) || isArguments(object));

      var index = -1,
          result = [];

      while (++index < propsLength) {
        var key = props[index];
        if ((allowIndexes && isIndex(key, length)) || hasOwnProperty.call(object, key)) {
          result.push(key);
        }
      }
      return result;
    }

    /**
     * Converts `value` to an array-like object if it's not one.
     *
     * @private
     * @param {*} value The value to process.
     * @returns {Array|Object} Returns the array-like object.
     */
    function toIterable(value) {
      if (value == null) {
        return [];
      }
      if (!isArrayLike(value)) {
        return values(value);
      }
      return isObject(value) ? value : Object(value);
    }

    /**
     * Converts `value` to an object if it's not one.
     *
     * @private
     * @param {*} value The value to process.
     * @returns {Object} Returns the object.
     */
    function toObject(value) {
      return isObject(value) ? value : Object(value);
    }

    /**
     * Converts `value` to property path array if it's not one.
     *
     * @private
     * @param {*} value The value to process.
     * @returns {Array} Returns the property path array.
     */
    function toPath(value) {
      if (isArray(value)) {
        return value;
      }
      var result = [];
      baseToString(value).replace(rePropName, function(match, number, quote, string) {
        result.push(quote ? string.replace(reEscapeChar, '$1') : (number || match));
      });
      return result;
    }

    /**
     * Creates a clone of `wrapper`.
     *
     * @private
     * @param {Object} wrapper The wrapper to clone.
     * @returns {Object} Returns the cloned wrapper.
     */
    function wrapperClone(wrapper) {
      return wrapper instanceof LazyWrapper
        ? wrapper.clone()
        : new LodashWrapper(wrapper.__wrapped__, wrapper.__chain__, arrayCopy(wrapper.__actions__));
    }

    /*------------------------------------------------------------------------*/

    /**
     * Creates an array of elements split into groups the length of `size`.
     * If `collection` can't be split evenly, the final chunk will be the remaining
     * elements.
     *
     * @static
     * @memberOf _
     * @category Array
     * @param {Array} array The array to process.
     * @param {number} [size=1] The length of each chunk.
     * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.
     * @returns {Array} Returns the new array containing chunks.
     * @example
     *
     * _.chunk(['a', 'b', 'c', 'd'], 2);
     * // => [['a', 'b'], ['c', 'd']]
     *
     * _.chunk(['a', 'b', 'c', 'd'], 3);
     * // => [['a', 'b', 'c'], ['d']]
     */
    function chunk(array, size, guard) {
      if (guard ? isIterateeCall(array, size, guard) : size == null) {
        size = 1;
      } else {
        size = nativeMax(nativeFloor(size) || 1, 1);
      }
      var index = 0,
          length = array ? array.length : 0,
          resIndex = -1,
          result = Array(nativeCeil(length / size));

      while (index < length) {
        result[++resIndex] = baseSlice(array, index, (index += size));
      }
      return result;
    }

    /**
     * Creates an array with all falsey values removed. The values `false`, `null`,
     * `0`, `""`, `undefined`, and `NaN` are falsey.
     *
     * @static
     * @memberOf _
     * @category Array
     * @param {Array} array The array to compact.
     * @returns {Array} Returns the new array of filtered values.
     * @example
     *
     * _.compact([0, 1, false, 2, '', 3]);
     * // => [1, 2, 3]
     */
    function compact(array) {
      var index = -1,
          length = array ? array.length : 0,
          resIndex = -1,
          result = [];

      while (++index < length) {
        var value = array[index];
        if (value) {
          result[++resIndex] = value;
        }
      }
      return result;
    }

    /**
     * Creates an array of unique `array` values not included in the other
     * provided arrays using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
     * for equality comparisons.
     *
     * @static
     * @memberOf _
     * @category Array
     * @param {Array} array The array to inspect.
     * @param {...Array} [values] The arrays of values to exclude.
     * @returns {Array} Returns the new array of filtered values.
     * @example
     *
     * _.difference([1, 2, 3], [4, 2]);
     * // => [1, 3]
     */
    var difference = restParam(function(array, values) {
      return (isObjectLike(array) && isArrayLike(array))
        ? baseDifference(array, baseFlatten(values, false, true))
        : [];
    });

    /**
     * Creates a slice of `array` with `n` elements dropped from the beginning.
     *
     * @static
     * @memberOf _
     * @category Array
     * @param {Array} array The array to query.
     * @param {number} [n=1] The number of elements to drop.
     * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.
     * @returns {Array} Returns the slice of `array`.
     * @example
     *
     * _.drop([1, 2, 3]);
     * // => [2, 3]
     *
     * _.drop([1, 2, 3], 2);
     * // => [3]
     *
     * _.drop([1, 2, 3], 5);
     * // => []
     *
     * _.drop([1, 2, 3], 0);
     * // => [1, 2, 3]
     */
    function drop(array, n, guard) {
      var length = array ? array.length : 0;
      if (!length) {
        return [];
      }
      if (guard ? isIterateeCall(array, n, guard) : n == null) {
        n = 1;
      }
      return baseSlice(array, n < 0 ? 0 : n);
    }

    /**
     * Creates a slice of `array` with `n` elements dropped from the end.
     *
     * @static
     * @memberOf _
     * @category Array
     * @param {Array} array The array to query.
     * @param {number} [n=1] The number of elements to drop.
     * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.
     * @returns {Array} Returns the slice of `array`.
     * @example
     *
     * _.dropRight([1, 2, 3]);
     * // => [1, 2]
     *
     * _.dropRight([1, 2, 3], 2);
     * // => [1]
     *
     * _.dropRight([1, 2, 3], 5);
     * // => []
     *
     * _.dropRight([1, 2, 3], 0);
     * // => [1, 2, 3]
     */
    function dropRight(array, n, guard) {
      var length = array ? array.length : 0;
      if (!length) {
        return [];
      }
      if (guard ? isIterateeCall(array, n, guard) : n == null) {
        n = 1;
      }
      n = length - (+n || 0);
      return baseSlice(array, 0, n < 0 ? 0 : n);
    }

    /**
     * Creates a slice of `array` excluding elements dropped from the end.
     * Elements are dropped until `predicate` returns falsey. The predicate is
     * bound to `thisArg` and invoked with three arguments: (value, index, array).
     *
     * If a property name is provided for `predicate` the created `_.property`
     * style callback returns the property value of the given element.
     *
     * If a value is also provided for `thisArg` the created `_.matchesProperty`
     * style callback returns `true` for elements that have a matching property
     * value, else `false`.
     *
     * If an object is provided for `predicate` the created `_.matches` style
     * callback returns `true` for elements that match the properties of the given
     * object, else `false`.
     *
     * @static
     * @memberOf _
     * @category Array
     * @param {Array} array The array to query.
     * @param {Function|Object|string} [predicate=_.identity] The function invoked
     *  per iteration.
     * @param {*} [thisArg] The `this` binding of `predicate`.
     * @returns {Array} Returns the slice of `array`.
     * @example
     *
     * _.dropRightWhile([1, 2, 3], function(n) {
     *   return n > 1;
     * });
     * // => [1]
     *
     * var users = [
     *   { 'user': 'barney',  'active': true },
     *   { 'user': 'fred',    'active': false },
     *   { 'user': 'pebbles', 'active': false }
     * ];
     *
     * // using the `_.matches` callback shorthand
     * _.pluck(_.dropRightWhile(users, { 'user': 'pebbles', 'active': false }), 'user');
     * // => ['barney', 'fred']
     *
     * // using the `_.matchesProperty` callback shorthand
     * _.pluck(_.dropRightWhile(users, 'active', false), 'user');
     * // => ['barney']
     *
     * // using the `_.property` callback shorthand
     * _.pluck(_.dropRightWhile(users, 'active'), 'user');
     * // => ['barney', 'fred', 'pebbles']
     */
    function dropRightWhile(array, predicate, thisArg) {
      return (array && array.length)
        ? baseWhile(array, getCallback(predicate, thisArg, 3), true, true)
        : [];
    }

    /**
     * Creates a slice of `array` excluding elements dropped from the beginning.
     * Elements are dropped until `predicate` returns falsey. The predicate is
     * bound to `thisArg` and invoked with three arguments: (value, index, array).
     *
     * If a property name is provided for `predicate` the created `_.property`
     * style callback returns the property value of the given element.
     *
     * If a value is also provided for `thisArg` the created `_.matchesProperty`
     * style callback returns `true` for elements that have a matching property
     * value, else `false`.
     *
     * If an object is provided for `predicate` the created `_.matches` style
     * callback returns `true` for elements that have the properties of the given
     * object, else `false`.
     *
     * @static
     * @memberOf _
     * @category Array
     * @param {Array} array The array to query.
     * @param {Function|Object|string} [predicate=_.identity] The function invoked
     *  per iteration.
     * @param {*} [thisArg] The `this` binding of `predicate`.
     * @returns {Array} Returns the slice of `array`.
     * @example
     *
     * _.dropWhile([1, 2, 3], function(n) {
     *   return n < 3;
     * });
     * // => [3]
     *
     * var users = [
     *   { 'user': 'barney',  'active': false },
     *   { 'user': 'fred',    'active': false },
     *   { 'user': 'pebbles', 'active': true }
     * ];
     *
     * // using the `_.matches` callback shorthand
     * _.pluck(_.dropWhile(users, { 'user': 'barney', 'active': false }), 'user');
     * // => ['fred', 'pebbles']
     *
     * // using the `_.matchesProperty` callback shorthand
     * _.pluck(_.dropWhile(users, 'active', false), 'user');
     * // => ['pebbles']
     *
     * // using the `_.property` callback shorthand
     * _.pluck(_.dropWhile(users, 'active'), 'user');
     * // => ['barney', 'fred', 'pebbles']
     */
    function dropWhile(array, predicate, thisArg) {
      return (array && array.length)
        ? baseWhile(array, getCallback(predicate, thisArg, 3), true)
        : [];
    }

    /**
     * Fills elements of `array` with `value` from `start` up to, but not
     * including, `end`.
     *
     * **Note:** This method mutates `array`.
     *
     * @static
     * @memberOf _
     * @category Array
     * @param {Array} array The array to fill.
     * @param {*} value The value to fill `array` with.
     * @param {number} [start=0] The start position.
     * @param {number} [end=array.length] The end position.
     * @returns {Array} Returns `array`.
     * @example
     *
     * var array = [1, 2, 3];
     *
     * _.fill(array, 'a');
     * console.log(array);
     * // => ['a', 'a', 'a']
     *
     * _.fill(Array(3), 2);
     * // => [2, 2, 2]
     *
     * _.fill([4, 6, 8], '*', 1, 2);
     * // => [4, '*', 8]
     */
    function fill(array, value, start, end) {
      var length = array ? array.length : 0;
      if (!length) {
        return [];
      }
      if (start && typeof start != 'number' && isIterateeCall(array, value, start)) {
        start = 0;
        end = length;
      }
      return baseFill(array, value, start, end);
    }

    /**
     * This method is like `_.find` except that it returns the index of the first
     * element `predicate` returns truthy for instead of the element itself.
     *
     * If a property name is provided for `predicate` the created `_.property`
     * style callback returns the property value of the given element.
     *
     * If a value is also provided for `thisArg` the created `_.matchesProperty`
     * style callback returns `true` for elements that have a matching property
     * value, else `false`.
     *
     * If an object is provided for `predicate` the created `_.matches` style
     * callback returns `true` for elements that have the properties of the given
     * object, else `false`.
     *
     * @static
     * @memberOf _
     * @category Array
     * @param {Array} array The array to search.
     * @param {Function|Object|string} [predicate=_.identity] The function invoked
     *  per iteration.
     * @param {*} [thisArg] The `this` binding of `predicate`.
     * @returns {number} Returns the index of the found element, else `-1`.
     * @example
     *
     * var users = [
     *   { 'user': 'barney',  'active': false },
     *   { 'user': 'fred',    'active': false },
     *   { 'user': 'pebbles', 'active': true }
     * ];
     *
     * _.findIndex(users, function(chr) {
     *   return chr.user == 'barney';
     * });
     * // => 0
     *
     * // using the `_.matches` callback shorthand
     * _.findIndex(users, { 'user': 'fred', 'active': false });
     * // => 1
     *
     * // using the `_.matchesProperty` callback shorthand
     * _.findIndex(users, 'active', false);
     * // => 0
     *
     * // using the `_.property` callback shorthand
     * _.findIndex(users, 'active');
     * // => 2
     */
    var findIndex = createFindIndex();

    /**
     * This method is like `_.findIndex` except that it iterates over elements
     * of `collection` from right to left.
     *
     * If a property name is provided for `predicate` the created `_.property`
     * style callback returns the property value of the given element.
     *
     * If a value is also provided for `thisArg` the created `_.matchesProperty`
     * style callback returns `true` for elements that have a matching property
     * value, else `false`.
     *
     * If an object is provided for `predicate` the created `_.matches` style
     * callback returns `true` for elements that have the properties of the given
     * object, else `false`.
     *
     * @static
     * @memberOf _
     * @category Array
     * @param {Array} array The array to search.
     * @param {Function|Object|string} [predicate=_.identity] The function invoked
     *  per iteration.
     * @param {*} [thisArg] The `this` binding of `predicate`.
     * @returns {number} Returns the index of the found element, else `-1`.
     * @example
     *
     * var users = [
     *   { 'user': 'barney',  'active': true },
     *   { 'user': 'fred',    'active': false },
     *   { 'user': 'pebbles', 'active': false }
     * ];
     *
     * _.findLastIndex(users, function(chr) {
     *   return chr.user == 'pebbles';
     * });
     * // => 2
     *
     * // using the `_.matches` callback shorthand
     * _.findLastIndex(users, { 'user': 'barney', 'active': true });
     * // => 0
     *
     * // using the `_.matchesProperty` callback shorthand
     * _.findLastIndex(users, 'active', false);
     * // => 2
     *
     * // using the `_.property` callback shorthand
     * _.findLastIndex(users, 'active');
     * // => 0
     */
    var findLastIndex = createFindIndex(true);

    /**
     * Gets the first element of `array`.
     *
     * @static
     * @memberOf _
     * @alias head
     * @category Array
     * @param {Array} array The array to query.
     * @returns {*} Returns the first element of `array`.
     * @example
     *
     * _.first([1, 2, 3]);
     * // => 1
     *
     * _.first([]);
     * // => undefined
     */
    function first(array) {
      return array ? array[0] : undefined;
    }

    /**
     * Flattens a nested array. If `isDeep` is `true` the array is recursively
     * flattened, otherwise it is only flattened a single level.
     *
     * @static
     * @memberOf _
     * @category Array
     * @param {Array} array The array to flatten.
     * @param {boolean} [isDeep] Specify a deep flatten.
     * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.
     * @returns {Array} Returns the new flattened array.
     * @example
     *
     * _.flatten([1, [2, 3, [4]]]);
     * // => [1, 2, 3, [4]]
     *
     * // using `isDeep`
     * _.flatten([1, [2, 3, [4]]], true);
     * // => [1, 2, 3, 4]
     */
    function flatten(array, isDeep, guard) {
      var length = array ? array.length : 0;
      if (guard && isIterateeCall(array, isDeep, guard)) {
        isDeep = false;
      }
      return length ? baseFlatten(array, isDeep) : [];
    }

    /**
     * Recursively flattens a nested array.
     *
     * @static
     * @memberOf _
     * @category Array
     * @param {Array} array The array to recursively flatten.
     * @returns {Array} Returns the new flattened array.
     * @example
     *
     * _.flattenDeep([1, [2, 3, [4]]]);
     * // => [1, 2, 3, 4]
     */
    function flattenDeep(array) {
      var length = array ? array.length : 0;
      return length ? baseFlatten(array, true) : [];
    }

    /**
     * Gets the index at which the first occurrence of `value` is found in `array`
     * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
     * for equality comparisons. If `fromIndex` is negative, it is used as the offset
     * from the end of `array`. If `array` is sorted providing `true` for `fromIndex`
     * performs a faster binary search.
     *
     * @static
     * @memberOf _
     * @category Array
     * @param {Array} array The array to search.
     * @param {*} value The value to search for.
     * @param {boolean|number} [fromIndex=0] The index to search from or `true`
     *  to perform a binary search on a sorted array.
     * @returns {number} Returns the index of the matched value, else `-1`.
     * @example
     *
     * _.indexOf([1, 2, 1, 2], 2);
     * // => 1
     *
     * // using `fromIndex`
     * _.indexOf([1, 2, 1, 2], 2, 2);
     * // => 3
     *
     * // performing a binary search
     * _.indexOf([1, 1, 2, 2], 2, true);
     * // => 2
     */
    function indexOf(array, value, fromIndex) {
      var length = array ? array.length : 0;
      if (!length) {
        return -1;
      }
      if (typeof fromIndex == 'number') {
        fromIndex = fromIndex < 0 ? nativeMax(length + fromIndex, 0) : fromIndex;
      } else if (fromIndex) {
        var index = binaryIndex(array, value);
        if (index < length &&
            (value === value ? (value === array[index]) : (array[index] !== array[index]))) {
          return index;
        }
        return -1;
      }
      return baseIndexOf(array, value, fromIndex || 0);
    }

    /**
     * Gets all but the last element of `array`.
     *
     * @static
     * @memberOf _
     * @category Array
     * @param {Array} array The array to query.
     * @returns {Array} Returns the slice of `array`.
     * @example
     *
     * _.initial([1, 2, 3]);
     * // => [1, 2]
     */
    function initial(array) {
      return dropRight(array, 1);
    }

    /**
     * Creates an array of unique values that are included in all of the provided
     * arrays using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
     * for equality comparisons.
     *
     * @static
     * @memberOf _
     * @category Array
     * @param {...Array} [arrays] The arrays to inspect.
     * @returns {Array} Returns the new array of shared values.
     * @example
     * _.intersection([1, 2], [4, 2], [2, 1]);
     * // => [2]
     */
    var intersection = restParam(function(arrays) {
      var othLength = arrays.length,
          othIndex = othLength,
          caches = Array(length),
          indexOf = getIndexOf(),
          isCommon = indexOf == baseIndexOf,
          result = [];

      while (othIndex--) {
        var value = arrays[othIndex] = isArrayLike(value = arrays[othIndex]) ? value : [];
        caches[othIndex] = (isCommon && value.length >= 120) ? createCache(othIndex && value) : null;
      }
      var array = arrays[0],
          index = -1,
          length = array ? array.length : 0,
          seen = caches[0];

      outer:
      while (++index < length) {
        value = array[index];
        if ((seen ? cacheIndexOf(seen, value) : indexOf(result, value, 0)) < 0) {
          var othIndex = othLength;
          while (--othIndex) {
            var cache = caches[othIndex];
            if ((cache ? cacheIndexOf(cache, value) : indexOf(arrays[othIndex], value, 0)) < 0) {
              continue outer;
            }
          }
          if (seen) {
            seen.push(value);
          }
          result.push(value);
        }
      }
      return result;
    });

    /**
     * Gets the last element of `array`.
     *
     * @static
     * @memberOf _
     * @category Array
     * @param {Array} array The array to query.
     * @returns {*} Returns the last element of `array`.
     * @example
     *
     * _.last([1, 2, 3]);
     * // => 3
     */
    function last(array) {
      var length = array ? array.length : 0;
      return length ? array[length - 1] : undefined;
    }

    /**
     * This method is like `_.indexOf` except that it iterates over elements of
     * `array` from right to left.
     *
     * @static
     * @memberOf _
     * @category Array
     * @param {Array} array The array to search.
     * @param {*} value The value to search for.
     * @param {boolean|number} [fromIndex=array.length-1] The index to search from
     *  or `true` to perform a binary search on a sorted array.
     * @returns {number} Returns the index of the matched value, else `-1`.
     * @example
     *
     * _.lastIndexOf([1, 2, 1, 2], 2);
     * // => 3
     *
     * // using `fromIndex`
     * _.lastIndexOf([1, 2, 1, 2], 2, 2);
     * // => 1
     *
     * // performing a binary search
     * _.lastIndexOf([1, 1, 2, 2], 2, true);
     * // => 3
     */
    function lastIndexOf(array, value, fromIndex) {
      var length = array ? array.length : 0;
      if (!length) {
        return -1;
      }
      var index = length;
      if (typeof fromIndex == 'number') {
        index = (fromIndex < 0 ? nativeMax(length + fromIndex, 0) : nativeMin(fromIndex || 0, length - 1)) + 1;
      } else if (fromIndex) {
        index = binaryIndex(array, value, true) - 1;
        var other = array[index];
        if (value === value ? (value === other) : (other !== other)) {
          return index;
        }
        return -1;
      }
      if (value !== value) {
        return indexOfNaN(array, index, true);
      }
      while (index--) {
        if (array[index] === value) {
          return index;
        }
      }
      return -1;
    }

    /**
     * Removes all provided values from `array` using
     * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
     * for equality comparisons.
     *
     * **Note:** Unlike `_.without`, this method mutates `array`.
     *
     * @static
     * @memberOf _
     * @category Array
     * @param {Array} array The array to modify.
     * @param {...*} [values] The values to remove.
     * @returns {Array} Returns `array`.
     * @example
     *
     * var array = [1, 2, 3, 1, 2, 3];
     *
     * _.pull(array, 2, 3);
     * console.log(array);
     * // => [1, 1]
     */
    function pull() {
      var args = arguments,
          array = args[0];

      if (!(array && array.length)) {
        return array;
      }
      var index = 0,
          indexOf = getIndexOf(),
          length = args.length;

      while (++index < length) {
        var fromIndex = 0,
            value = args[index];

        while ((fromIndex = indexOf(array, value, fromIndex)) > -1) {
          splice.call(array, fromIndex, 1);
        }
      }
      return array;
    }

    /**
     * Removes elements from `array` corresponding to the given indexes and returns
     * an array of the removed elements. Indexes may be specified as an array of
     * indexes or as individual arguments.
     *
     * **Note:** Unlike `_.at`, this method mutates `array`.
     *
     * @static
     * @memberOf _
     * @category Array
     * @param {Array} array The array to modify.
     * @param {...(number|number[])} [indexes] The indexes of elements to remove,
     *  specified as individual indexes or arrays of indexes.
     * @returns {Array} Returns the new array of removed elements.
     * @example
     *
     * var array = [5, 10, 15, 20];
     * var evens = _.pullAt(array, 1, 3);
     *
     * console.log(array);
     * // => [5, 15]
     *
     * console.log(evens);
     * // => [10, 20]
     */
    var pullAt = restParam(function(array, indexes) {
      indexes = baseFlatten(indexes);

      var result = baseAt(array, indexes);
      basePullAt(array, indexes.sort(baseCompareAscending));
      return result;
    });

    /**
     * Removes all elements from `array` that `predicate` returns truthy for
     * and returns an array of the removed elements. The predicate is bound to
     * `thisArg` and invoked with three arguments: (value, index, array).
     *
     * If a property name is provided for `predicate` the created `_.property`
     * style callback returns the property value of the given element.
     *
     * If a value is also provided for `thisArg` the created `_.matchesProperty`
     * style callback returns `true` for elements that have a matching property
     * value, else `false`.
     *
     * If an object is provided for `predicate` the created `_.matches` style
     * callback returns `true` for elements that have the properties of the given
     * object, else `false`.
     *
     * **Note:** Unlike `_.filter`, this method mutates `array`.
     *
     * @static
     * @memberOf _
     * @category Array
     * @param {Array} array The array to modify.
     * @param {Function|Object|string} [predicate=_.identity] The function invoked
     *  per iteration.
     * @param {*} [thisArg] The `this` binding of `predicate`.
     * @returns {Array} Returns the new array of removed elements.
     * @example
     *
     * var array = [1, 2, 3, 4];
     * var evens = _.remove(array, function(n) {
     *   return n % 2 == 0;
     * });
     *
     * console.log(array);
     * // => [1, 3]
     *
     * console.log(evens);
     * // => [2, 4]
     */
    function remove(array, predicate, thisArg) {
      var result = [];
      if (!(array && array.length)) {
        return result;
      }
      var index = -1,
          indexes = [],
          length = array.length;

      predicate = getCallback(predicate, thisArg, 3);
      while (++index < length) {
        var value = array[index];
        if (predicate(value, index, array)) {
          result.push(value);
          indexes.push(index);
        }
      }
      basePullAt(array, indexes);
      return result;
    }

    /**
     * Gets all but the first element of `array`.
     *
     * @static
     * @memberOf _
     * @alias tail
     * @category Array
     * @param {Array} array The array to query.
     * @returns {Array} Returns the slice of `array`.
     * @example
     *
     * _.rest([1, 2, 3]);
     * // => [2, 3]
     */
    function rest(array) {
      return drop(array, 1);
    }

    /**
     * Creates a slice of `array` from `start` up to, but not including, `end`.
     *
     * **Note:** This method is used instead of `Array#slice` to support node
     * lists in IE < 9 and to ensure dense arrays are returned.
     *
     * @static
     * @memberOf _
     * @category Array
     * @param {Array} array The array to slice.
     * @param {number} [start=0] The start position.
     * @param {number} [end=array.length] The end position.
     * @returns {Array} Returns the slice of `array`.
     */
    function slice(array, start, end) {
      var length = array ? array.length : 0;
      if (!length) {
        return [];
      }
      if (end && typeof end != 'number' && isIterateeCall(array, start, end)) {
        start = 0;
        end = length;
      }
      return baseSlice(array, start, end);
    }

    /**
     * Uses a binary search to determine the lowest index at which `value` should
     * be inserted into `array` in order to maintain its sort order. If an iteratee
     * function is provided it is invoked for `value` and each element of `array`
     * to compute their sort ranking. The iteratee is bound to `thisArg` and
     * invoked with one argument; (value).
     *
     * If a property name is provided for `iteratee` the created `_.property`
     * style callback returns the property value of the given element.
     *
     * If a value is also provided for `thisArg` the created `_.matchesProperty`
     * style callback returns `true` for elements that have a matching property
     * value, else `false`.
     *
     * If an object is provided for `iteratee` the created `_.matches` style
     * callback returns `true` for elements that have the properties of the given
     * object, else `false`.
     *
     * @static
     * @memberOf _
     * @category Array
     * @param {Array} array The sorted array to inspect.
     * @param {*} value The value to evaluate.
     * @param {Function|Object|string} [iteratee=_.identity] The function invoked
     *  per iteration.
     * @param {*} [thisArg] The `this` binding of `iteratee`.
     * @returns {number} Returns the index at which `value` should be inserted
     *  into `array`.
     * @example
     *
     * _.sortedIndex([30, 50], 40);
     * // => 1
     *
     * _.sortedIndex([4, 4, 5, 5], 5);
     * // => 2
     *
     * var dict = { 'data': { 'thirty': 30, 'forty': 40, 'fifty': 50 } };
     *
     * // using an iteratee function
     * _.sortedIndex(['thirty', 'fifty'], 'forty', function(word) {
     *   return this.data[word];
     * }, dict);
     * // => 1
     *
     * // using the `_.property` callback shorthand
     * _.sortedIndex([{ 'x': 30 }, { 'x': 50 }], { 'x': 40 }, 'x');
     * // => 1
     */
    var sortedIndex = createSortedIndex();

    /**
     * This method is like `_.sortedIndex` except that it returns the highest
     * index at which `value` should be inserted into `array` in order to
     * maintain its sort order.
     *
     * @static
     * @memberOf _
     * @category Array
     * @param {Array} array The sorted array to inspect.
     * @param {*} value The value to evaluate.
     * @param {Function|Object|string} [iteratee=_.identity] The function invoked
     *  per iteration.
     * @param {*} [thisArg] The `this` binding of `iteratee`.
     * @returns {number} Returns the index at which `value` should be inserted
     *  into `array`.
     * @example
     *
     * _.sortedLastIndex([4, 4, 5, 5], 5);
     * // => 4
     */
    var sortedLastIndex = createSortedIndex(true);

    /**
     * Creates a slice of `array` with `n` elements taken from the beginning.
     *
     * @static
     * @memberOf _
     * @category Array
     * @param {Array} array The array to query.
     * @param {number} [n=1] The number of elements to take.
     * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.
     * @returns {Array} Returns the slice of `array`.
     * @example
     *
     * _.take([1, 2, 3]);
     * // => [1]
     *
     * _.take([1, 2, 3], 2);
     * // => [1, 2]
     *
     * _.take([1, 2, 3], 5);
     * // => [1, 2, 3]
     *
     * _.take([1, 2, 3], 0);
     * // => []
     */
    function take(array, n, guard) {
      var length = array ? array.length : 0;
      if (!length) {
        return [];
      }
      if (guard ? isIterateeCall(array, n, guard) : n == null) {
        n = 1;
      }
      return baseSlice(array, 0, n < 0 ? 0 : n);
    }

    /**
     * Creates a slice of `array` with `n` elements taken from the end.
     *
     * @static
     * @memberOf _
     * @category Array
     * @param {Array} array The array to query.
     * @param {number} [n=1] The number of elements to take.
     * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.
     * @returns {Array} Returns the slice of `array`.
     * @example
     *
     * _.takeRight([1, 2, 3]);
     * // => [3]
     *
     * _.takeRight([1, 2, 3], 2);
     * // => [2, 3]
     *
     * _.takeRight([1, 2, 3], 5);
     * // => [1, 2, 3]
     *
     * _.takeRight([1, 2, 3], 0);
     * // => []
     */
    function takeRight(array, n, guard) {
      var length = array ? array.length : 0;
      if (!length) {
        return [];
      }
      if (guard ? isIterateeCall(array, n, guard) : n == null) {
        n = 1;
      }
      n = length - (+n || 0);
      return baseSlice(array, n < 0 ? 0 : n);
    }

    /**
     * Creates a slice of `array` with elements taken from the end. Elements are
     * taken until `predicate` returns falsey. The predicate is bound to `thisArg`
     * and invoked with three arguments: (value, index, array).
     *
     * If a property name is provided for `predicate` the created `_.property`
     * style callback returns the property value of the given element.
     *
     * If a value is also provided for `thisArg` the created `_.matchesProperty`
     * style callback returns `true` for elements that have a matching property
     * value, else `false`.
     *
     * If an object is provided for `predicate` the created `_.matches` style
     * callback returns `true` for elements that have the properties of the given
     * object, else `false`.
     *
     * @static
     * @memberOf _
     * @category Array
     * @param {Array} array The array to query.
     * @param {Function|Object|string} [predicate=_.identity] The function invoked
     *  per iteration.
     * @param {*} [thisArg] The `this` binding of `predicate`.
     * @returns {Array} Returns the slice of `array`.
     * @example
     *
     * _.takeRightWhile([1, 2, 3], function(n) {
     *   return n > 1;
     * });
     * // => [2, 3]
     *
     * var users = [
     *   { 'user': 'barney',  'active': true },
     *   { 'user': 'fred',    'active': false },
     *   { 'user': 'pebbles', 'active': false }
     * ];
     *
     * // using the `_.matches` callback shorthand
     * _.pluck(_.takeRightWhile(users, { 'user': 'pebbles', 'active': false }), 'user');
     * // => ['pebbles']
     *
     * // using the `_.matchesProperty` callback shorthand
     * _.pluck(_.takeRightWhile(users, 'active', false), 'user');
     * // => ['fred', 'pebbles']
     *
     * // using the `_.property` callback shorthand
     * _.pluck(_.takeRightWhile(users, 'active'), 'user');
     * // => []
     */
    function takeRightWhile(array, predicate, thisArg) {
      return (array && array.length)
        ? baseWhile(array, getCallback(predicate, thisArg, 3), false, true)
        : [];
    }

    /**
     * Creates a slice of `array` with elements taken from the beginning. Elements
     * are taken until `predicate` returns falsey. The predicate is bound to
     * `thisArg` and invoked with three arguments: (value, index, array).
     *
     * If a property name is provided for `predicate` the created `_.property`
     * style callback returns the property value of the given element.
     *
     * If a value is also provided for `thisArg` the created `_.matchesProperty`
     * style callback returns `true` for elements that have a matching property
     * value, else `false`.
     *
     * If an object is provided for `predicate` the created `_.matches` style
     * callback returns `true` for elements that have the properties of the given
     * object, else `false`.
     *
     * @static
     * @memberOf _
     * @category Array
     * @param {Array} array The array to query.
     * @param {Function|Object|string} [predicate=_.identity] The function invoked
     *  per iteration.
     * @param {*} [thisArg] The `this` binding of `predicate`.
     * @returns {Array} Returns the slice of `array`.
     * @example
     *
     * _.takeWhile([1, 2, 3], function(n) {
     *   return n < 3;
     * });
     * // => [1, 2]
     *
     * var users = [
     *   { 'user': 'barney',  'active': false },
     *   { 'user': 'fred',    'active': false},
     *   { 'user': 'pebbles', 'active': true }
     * ];
     *
     * // using the `_.matches` callback shorthand
     * _.pluck(_.takeWhile(users, { 'user': 'barney', 'active': false }), 'user');
     * // => ['barney']
     *
     * // using the `_.matchesProperty` callback shorthand
     * _.pluck(_.takeWhile(users, 'active', false), 'user');
     * // => ['barney', 'fred']
     *
     * // using the `_.property` callback shorthand
     * _.pluck(_.takeWhile(users, 'active'), 'user');
     * // => []
     */
    function takeWhile(array, predicate, thisArg) {
      return (array && array.length)
        ? baseWhile(array, getCallback(predicate, thisArg, 3))
        : [];
    }

    /**
     * Creates an array of unique values, in order, from all of the provided arrays
     * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
     * for equality comparisons.
     *
     * @static
     * @memberOf _
     * @category Array
     * @param {...Array} [arrays] The arrays to inspect.
     * @returns {Array} Returns the new array of combined values.
     * @example
     *
     * _.union([1, 2], [4, 2], [2, 1]);
     * // => [1, 2, 4]
     */
    var union = restParam(function(arrays) {
      return baseUniq(baseFlatten(arrays, false, true));
    });

    /**
     * Creates a duplicate-free version of an array, using
     * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
     * for equality comparisons, in which only the first occurence of each element
     * is kept. Providing `true` for `isSorted` performs a faster search algorithm
     * for sorted arrays. If an iteratee function is provided it is invoked for
     * each element in the array to generate the criterion by which uniqueness
     * is computed. The `iteratee` is bound to `thisArg` and invoked with three
     * arguments: (value, index, array).
     *
     * If a property name is provided for `iteratee` the created `_.property`
     * style callback returns the property value of the given element.
     *
     * If a value is also provided for `thisArg` the created `_.matchesProperty`
     * style callback returns `true` for elements that have a matching property
     * value, else `false`.
     *
     * If an object is provided for `iteratee` the created `_.matches` style
     * callback returns `true` for elements that have the properties of the given
     * object, else `false`.
     *
     * @static
     * @memberOf _
     * @alias unique
     * @category Array
     * @param {Array} array The array to inspect.
     * @param {boolean} [isSorted] Specify the array is sorted.
     * @param {Function|Object|string} [iteratee] The function invoked per iteration.
     * @param {*} [thisArg] The `this` binding of `iteratee`.
     * @returns {Array} Returns the new duplicate-value-free array.
     * @example
     *
     * _.uniq([2, 1, 2]);
     * // => [2, 1]
     *
     * // using `isSorted`
     * _.uniq([1, 1, 2], true);
     * // => [1, 2]
     *
     * // using an iteratee function
     * _.uniq([1, 2.5, 1.5, 2], function(n) {
     *   return this.floor(n);
     * }, Math);
     * // => [1, 2.5]
     *
     * // using the `_.property` callback shorthand
     * _.uniq([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x');
     * // => [{ 'x': 1 }, { 'x': 2 }]
     */
    function uniq(array, isSorted, iteratee, thisArg) {
      var length = array ? array.length : 0;
      if (!length) {
        return [];
      }
      if (isSorted != null && typeof isSorted != 'boolean') {
        thisArg = iteratee;
        iteratee = isIterateeCall(array, isSorted, thisArg) ? undefined : isSorted;
        isSorted = false;
      }
      var callback = getCallback();
      if (!(iteratee == null && callback === baseCallback)) {
        iteratee = callback(iteratee, thisArg, 3);
      }
      return (isSorted && getIndexOf() == baseIndexOf)
        ? sortedUniq(array, iteratee)
        : baseUniq(array, iteratee);
    }

    /**
     * This method is like `_.zip` except that it accepts an array of grouped
     * elements and creates an array regrouping the elements to their pre-zip
     * configuration.
     *
     * @static
     * @memberOf _
     * @category Array
     * @param {Array} array The array of grouped elements to process.
     * @returns {Array} Returns the new array of regrouped elements.
     * @example
     *
     * var zipped = _.zip(['fred', 'barney'], [30, 40], [true, false]);
     * // => [['fred', 30, true], ['barney', 40, false]]
     *
     * _.unzip(zipped);
     * // => [['fred', 'barney'], [30, 40], [true, false]]
     */
    function unzip(array) {
      if (!(array && array.length)) {
        return [];
      }
      var index = -1,
          length = 0;

      array = arrayFilter(array, function(group) {
        if (isArrayLike(group)) {
          length = nativeMax(group.length, length);
          return true;
        }
      });
      var result = Array(length);
      while (++index < length) {
        result[index] = arrayMap(array, baseProperty(index));
      }
      return result;
    }

    /**
     * This method is like `_.unzip` except that it accepts an iteratee to specify
     * how regrouped values should be combined. The `iteratee` is bound to `thisArg`
     * and invoked with four arguments: (accumulator, value, index, group).
     *
     * @static
     * @memberOf _
     * @category Array
     * @param {Array} array The array of grouped elements to process.
     * @param {Function} [iteratee] The function to combine regrouped values.
     * @param {*} [thisArg] The `this` binding of `iteratee`.
     * @returns {Array} Returns the new array of regrouped elements.
     * @example
     *
     * var zipped = _.zip([1, 2], [10, 20], [100, 200]);
     * // => [[1, 10, 100], [2, 20, 200]]
     *
     * _.unzipWith(zipped, _.add);
     * // => [3, 30, 300]
     */
    function unzipWith(array, iteratee, thisArg) {
      var length = array ? array.length : 0;
      if (!length) {
        return [];
      }
      var result = unzip(array);
      if (iteratee == null) {
        return result;
      }
      iteratee = bindCallback(iteratee, thisArg, 4);
      return arrayMap(result, function(group) {
        return arrayReduce(group, iteratee, undefined, true);
      });
    }

    /**
     * Creates an array excluding all provided values using
     * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
     * for equality comparisons.
     *
     * @static
     * @memberOf _
     * @category Array
     * @param {Array} array The array to filter.
     * @param {...*} [values] The values to exclude.
     * @returns {Array} Returns the new array of filtered values.
     * @example
     *
     * _.without([1, 2, 1, 3], 1, 2);
     * // => [3]
     */
    var without = restParam(function(array, values) {
      return isArrayLike(array)
        ? baseDifference(array, values)
        : [];
    });

    /**
     * Creates an array of unique values that is the [symmetric difference](https://en.wikipedia.org/wiki/Symmetric_difference)
     * of the provided arrays.
     *
     * @static
     * @memberOf _
     * @category Array
     * @param {...Array} [arrays] The arrays to inspect.
     * @returns {Array} Returns the new array of values.
     * @example
     *
     * _.xor([1, 2], [4, 2]);
     * // => [1, 4]
     */
    function xor() {
      var index = -1,
          length = arguments.length;

      while (++index < length) {
        var array = arguments[index];
        if (isArrayLike(array)) {
          var result = result
            ? arrayPush(baseDifference(result, array), baseDifference(array, result))
            : array;
        }
      }
      return result ? baseUniq(result) : [];
    }

    /**
     * Creates an array of grouped elements, the first of which contains the first
     * elements of the given arrays, the second of which contains the second elements
     * of the given arrays, and so on.
     *
     * @static
     * @memberOf _
     * @category Array
     * @param {...Array} [arrays] The arrays to process.
     * @returns {Array} Returns the new array of grouped elements.
     * @example
     *
     * _.zip(['fred', 'barney'], [30, 40], [true, false]);
     * // => [['fred', 30, true], ['barney', 40, false]]
     */
    var zip = restParam(unzip);

    /**
     * The inverse of `_.pairs`; this method returns an object composed from arrays
     * of property names and values. Provide either a single two dimensional array,
     * e.g. `[[key1, value1], [key2, value2]]` or two arrays, one of property names
     * and one of corresponding values.
     *
     * @static
     * @memberOf _
     * @alias object
     * @category Array
     * @param {Array} props The property names.
     * @param {Array} [values=[]] The property values.
     * @returns {Object} Returns the new object.
     * @example
     *
     * _.zipObject([['fred', 30], ['barney', 40]]);
     * // => { 'fred': 30, 'barney': 40 }
     *
     * _.zipObject(['fred', 'barney'], [30, 40]);
     * // => { 'fred': 30, 'barney': 40 }
     */
    function zipObject(props, values) {
      var index = -1,
          length = props ? props.length : 0,
          result = {};

      if (length && !values && !isArray(props[0])) {
        values = [];
      }
      while (++index < length) {
        var key = props[index];
        if (values) {
          result[key] = values[index];
        } else if (key) {
          result[key[0]] = key[1];
        }
      }
      return result;
    }

    /**
     * This method is like `_.zip` except that it accepts an iteratee to specify
     * how grouped values should be combined. The `iteratee` is bound to `thisArg`
     * and invoked with four arguments: (accumulator, value, index, group).
     *
     * @static
     * @memberOf _
     * @category Array
     * @param {...Array} [arrays] The arrays to process.
     * @param {Function} [iteratee] The function to combine grouped values.
     * @param {*} [thisArg] The `this` binding of `iteratee`.
     * @returns {Array} Returns the new array of grouped elements.
     * @example
     *
     * _.zipWith([1, 2], [10, 20], [100, 200], _.add);
     * // => [111, 222]
     */
    var zipWith = restParam(function(arrays) {
      var length = arrays.length,
          iteratee = length > 2 ? arrays[length - 2] : undefined,
          thisArg = length > 1 ? arrays[length - 1] : undefined;

      if (length > 2 && typeof iteratee == 'function') {
        length -= 2;
      } else {
        iteratee = (length > 1 && typeof thisArg == 'function') ? (--length, thisArg) : undefined;
        thisArg = undefined;
      }
      arrays.length = length;
      return unzipWith(arrays, iteratee, thisArg);
    });

    /*------------------------------------------------------------------------*/

    /**
     * Creates a `lodash` object that wraps `value` with explicit method
     * chaining enabled.
     *
     * @static
     * @memberOf _
     * @category Chain
     * @param {*} value The value to wrap.
     * @returns {Object} Returns the new `lodash` wrapper instance.
     * @example
     *
     * var users = [
     *   { 'user': 'barney',  'age': 36 },
     *   { 'user': 'fred',    'age': 40 },
     *   { 'user': 'pebbles', 'age': 1 }
     * ];
     *
     * var youngest = _.chain(users)
     *   .sortBy('age')
     *   .map(function(chr) {
     *     return chr.user + ' is ' + chr.age;
     *   })
     *   .first()
     *   .value();
     * // => 'pebbles is 1'
     */
    function chain(value) {
      var result = lodash(value);
      result.__chain__ = true;
      return result;
    }

    /**
     * This method invokes `interceptor` and returns `value`. The interceptor is
     * bound to `thisArg` and invoked with one argument; (value). The purpose of
     * this method is to "tap into" a method chain in order to perform operations
     * on intermediate results within the chain.
     *
     * @static
     * @memberOf _
     * @category Chain
     * @param {*} value The value to provide to `interceptor`.
     * @param {Function} interceptor The function to invoke.
     * @param {*} [thisArg] The `this` binding of `interceptor`.
     * @returns {*} Returns `value`.
     * @example
     *
     * _([1, 2, 3])
     *  .tap(function(array) {
     *    array.pop();
     *  })
     *  .reverse()
     *  .value();
     * // => [2, 1]
     */
    function tap(value, interceptor, thisArg) {
      interceptor.call(thisArg, value);
      return value;
    }

    /**
     * This method is like `_.tap` except that it returns the result of `interceptor`.
     *
     * @static
     * @memberOf _
     * @category Chain
     * @param {*} value The value to provide to `interceptor`.
     * @param {Function} interceptor The function to invoke.
     * @param {*} [thisArg] The `this` binding of `interceptor`.
     * @returns {*} Returns the result of `interceptor`.
     * @example
     *
     * _('  abc  ')
     *  .chain()
     *  .trim()
     *  .thru(function(value) {
     *    return [value];
     *  })
     *  .value();
     * // => ['abc']
     */
    function thru(value, interceptor, thisArg) {
      return interceptor.call(thisArg, value);
    }

    /**
     * Enables explicit method chaining on the wrapper object.
     *
     * @name chain
     * @memberOf _
     * @category Chain
     * @returns {Object} Returns the new `lodash` wrapper instance.
     * @example
     *
     * var users = [
     *   { 'user': 'barney', 'age': 36 },
     *   { 'user': 'fred',   'age': 40 }
     * ];
     *
     * // without explicit chaining
     * _(users).first();
     * // => { 'user': 'barney', 'age': 36 }
     *
     * // with explicit chaining
     * _(users).chain()
     *   .first()
     *   .pick('user')
     *   .value();
     * // => { 'user': 'barney' }
     */
    function wrapperChain() {
      return chain(this);
    }

    /**
     * Executes the chained sequence and returns the wrapped result.
     *
     * @name commit
     * @memberOf _
     * @category Chain
     * @returns {Object} Returns the new `lodash` wrapper instance.
     * @example
     *
     * var array = [1, 2];
     * var wrapped = _(array).push(3);
     *
     * console.log(array);
     * // => [1, 2]
     *
     * wrapped = wrapped.commit();
     * console.log(array);
     * // => [1, 2, 3]
     *
     * wrapped.last();
     * // => 3
     *
     * console.log(array);
     * // => [1, 2, 3]
     */
    function wrapperCommit() {
      return new LodashWrapper(this.value(), this.__chain__);
    }

    /**
     * Creates a new array joining a wrapped array with any additional arrays
     * and/or values.
     *
     * @name concat
     * @memberOf _
     * @category Chain
     * @param {...*} [values] The values to concatenate.
     * @returns {Array} Returns the new concatenated array.
     * @example
     *
     * var array = [1];
     * var wrapped = _(array).concat(2, [3], [[4]]);
     *
     * console.log(wrapped.value());
     * // => [1, 2, 3, [4]]
     *
     * console.log(array);
     * // => [1]
     */
    var wrapperConcat = restParam(function(values) {
      values = baseFlatten(values);
      return this.thru(function(array) {
        return arrayConcat(isArray(array) ? array : [toObject(array)], values);
      });
    });

    /**
     * Creates a clone of the chained sequence planting `value` as the wrapped value.
     *
     * @name plant
     * @memberOf _
     * @category Chain
     * @returns {Object} Returns the new `lodash` wrapper instance.
     * @example
     *
     * var array = [1, 2];
     * var wrapped = _(array).map(function(value) {
     *   return Math.pow(value, 2);
     * });
     *
     * var other = [3, 4];
     * var otherWrapped = wrapped.plant(other);
     *
     * otherWrapped.value();
     * // => [9, 16]
     *
     * wrapped.value();
     * // => [1, 4]
     */
    function wrapperPlant(value) {
      var result,
          parent = this;

      while (parent instanceof baseLodash) {
        var clone = wrapperClone(parent);
        if (result) {
          previous.__wrapped__ = clone;
        } else {
          result = clone;
        }
        var previous = clone;
        parent = parent.__wrapped__;
      }
      previous.__wrapped__ = value;
      return result;
    }

    /**
     * Reverses the wrapped array so the first element becomes the last, the
     * second element becomes the second to last, and so on.
     *
     * **Note:** This method mutates the wrapped array.
     *
     * @name reverse
     * @memberOf _
     * @category Chain
     * @returns {Object} Returns the new reversed `lodash` wrapper instance.
     * @example
     *
     * var array = [1, 2, 3];
     *
     * _(array).reverse().value()
     * // => [3, 2, 1]
     *
     * console.log(array);
     * // => [3, 2, 1]
     */
    function wrapperReverse() {
      var value = this.__wrapped__;

      var interceptor = function(value) {
        return (wrapped && wrapped.__dir__ < 0) ? value : value.reverse();
      };
      if (value instanceof LazyWrapper) {
        var wrapped = value;
        if (this.__actions__.length) {
          wrapped = new LazyWrapper(this);
        }
        wrapped = wrapped.reverse();
        wrapped.__actions__.push({ 'func': thru, 'args': [interceptor], 'thisArg': undefined });
        return new LodashWrapper(wrapped, this.__chain__);
      }
      return this.thru(interceptor);
    }

    /**
     * Produces the result of coercing the unwrapped value to a string.
     *
     * @name toString
     * @memberOf _
     * @category Chain
     * @returns {string} Returns the coerced string value.
     * @example
     *
     * _([1, 2, 3]).toString();
     * // => '1,2,3'
     */
    function wrapperToString() {
      return (this.value() + '');
    }

    /**
     * Executes the chained sequence to extract the unwrapped value.
     *
     * @name value
     * @memberOf _
     * @alias run, toJSON, valueOf
     * @category Chain
     * @returns {*} Returns the resolved unwrapped value.
     * @example
     *
     * _([1, 2, 3]).value();
     * // => [1, 2, 3]
     */
    function wrapperValue() {
      return baseWrapperValue(this.__wrapped__, this.__actions__);
    }

    /*------------------------------------------------------------------------*/

    /**
     * Creates an array of elements corresponding to the given keys, or indexes,
     * of `collection`. Keys may be specified as individual arguments or as arrays
     * of keys.
     *
     * @static
     * @memberOf _
     * @category Collection
     * @param {Array|Object|string} collection The collection to iterate over.
     * @param {...(number|number[]|string|string[])} [props] The property names
     *  or indexes of elements to pick, specified individually or in arrays.
     * @returns {Array} Returns the new array of picked elements.
     * @example
     *
     * _.at(['a', 'b', 'c'], [0, 2]);
     * // => ['a', 'c']
     *
     * _.at(['barney', 'fred', 'pebbles'], 0, 2);
     * // => ['barney', 'pebbles']
     */
    var at = restParam(function(collection, props) {
      return baseAt(collection, baseFlatten(props));
    });

    /**
     * Creates an object composed of keys generated from the results of running
     * each element of `collection` through `iteratee`. The corresponding value
     * of each key is the number of times the key was returned by `iteratee`.
     * The `iteratee` is bound to `thisArg` and invoked with three arguments:
     * (value, index|key, collection).
     *
     * If a property name is provided for `iteratee` the created `_.property`
     * style callback returns the property value of the given element.
     *
     * If a value is also provided for `thisArg` the created `_.matchesProperty`
     * style callback returns `true` for elements that have a matching property
     * value, else `false`.
     *
     * If an object is provided for `iteratee` the created `_.matches` style
     * callback returns `true` for elements that have the properties of the given
     * object, else `false`.
     *
     * @static
     * @memberOf _
     * @category Collection
     * @param {Array|Object|string} collection The collection to iterate over.
     * @param {Function|Object|string} [iteratee=_.identity] The function invoked
     *  per iteration.
     * @param {*} [thisArg] The `this` binding of `iteratee`.
     * @returns {Object} Returns the composed aggregate object.
     * @example
     *
     * _.countBy([4.3, 6.1, 6.4], function(n) {
     *   return Math.floor(n);
     * });
     * // => { '4': 1, '6': 2 }
     *
     * _.countBy([4.3, 6.1, 6.4], function(n) {
     *   return this.floor(n);
     * }, Math);
     * // => { '4': 1, '6': 2 }
     *
     * _.countBy(['one', 'two', 'three'], 'length');
     * // => { '3': 2, '5': 1 }
     */
    var countBy = createAggregator(function(result, value, key) {
      hasOwnProperty.call(result, key) ? ++result[key] : (result[key] = 1);
    });

    /**
     * Checks if `predicate` returns truthy for **all** elements of `collection`.
     * The predicate is bound to `thisArg` and invoked with three arguments:
     * (value, index|key, collection).
     *
     * If a property name is provided for `predicate` the created `_.property`
     * style callback returns the property value of the given element.
     *
     * If a value is also provided for `thisArg` the created `_.matchesProperty`
     * style callback returns `true` for elements that have a matching property
     * value, else `false`.
     *
     * If an object is provided for `predicate` the created `_.matches` style
     * callback returns `true` for elements that have the properties of the given
     * object, else `false`.
     *
     * @static
     * @memberOf _
     * @alias all
     * @category Collection
     * @param {Array|Object|string} collection The collection to iterate over.
     * @param {Function|Object|string} [predicate=_.identity] The function invoked
     *  per iteration.
     * @param {*} [thisArg] The `this` binding of `predicate`.
     * @returns {boolean} Returns `true` if all elements pass the predicate check,
     *  else `false`.
     * @example
     *
     * _.every([true, 1, null, 'yes'], Boolean);
     * // => false
     *
     * var users = [
     *   { 'user': 'barney', 'active': false },
     *   { 'user': 'fred',   'active': false }
     * ];
     *
     * // using the `_.matches` callback shorthand
     * _.every(users, { 'user': 'barney', 'active': false });
     * // => false
     *
     * // using the `_.matchesProperty` callback shorthand
     * _.every(users, 'active', false);
     * // => true
     *
     * // using the `_.property` callback shorthand
     * _.every(users, 'active');
     * // => false
     */
    function every(collection, predicate, thisArg) {
      var func = isArray(collection) ? arrayEvery : baseEvery;
      if (thisArg && isIterateeCall(collection, predicate, thisArg)) {
        predicate = undefined;
      }
      if (typeof predicate != 'function' || thisArg !== undefined) {
        predicate = getCallback(predicate, thisArg, 3);
      }
      return func(collection, predicate);
    }

    /**
     * Iterates over elements of `collection`, returning an array of all elements
     * `predicate` returns truthy for. The predicate is bound to `thisArg` and
     * invoked with three arguments: (value, index|key, collection).
     *
     * If a property name is provided for `predicate` the created `_.property`
     * style callback returns the property value of the given element.
     *
     * If a value is also provided for `thisArg` the created `_.matchesProperty`
     * style callback returns `true` for elements that have a matching property
     * value, else `false`.
     *
     * If an object is provided for `predicate` the created `_.matches` style
     * callback returns `true` for elements that have the properties of the given
     * object, else `false`.
     *
     * @static
     * @memberOf _
     * @alias select
     * @category Collection
     * @param {Array|Object|string} collection The collection to iterate over.
     * @param {Function|Object|string} [predicate=_.identity] The function invoked
     *  per iteration.
     * @param {*} [thisArg] The `this` binding of `predicate`.
     * @returns {Array} Returns the new filtered array.
     * @example
     *
     * _.filter([4, 5, 6], function(n) {
     *   return n % 2 == 0;
     * });
     * // => [4, 6]
     *
     * var users = [
     *   { 'user': 'barney', 'age': 36, 'active': true },
     *   { 'user': 'fred',   'age': 40, 'active': false }
     * ];
     *
     * // using the `_.matches` callback shorthand
     * _.pluck(_.filter(users, { 'age': 36, 'active': true }), 'user');
     * // => ['barney']
     *
     * // using the `_.matchesProperty` callback shorthand
     * _.pluck(_.filter(users, 'active', false), 'user');
     * // => ['fred']
     *
     * // using the `_.property` callback shorthand
     * _.pluck(_.filter(users, 'active'), 'user');
     * // => ['barney']
     */
    function filter(collection, predicate, thisArg) {
      var func = isArray(collection) ? arrayFilter : baseFilter;
      predicate = getCallback(predicate, thisArg, 3);
      return func(collection, predicate);
    }

    /**
     * Iterates over elements of `collection`, returning the first element
     * `predicate` returns truthy for. The predicate is bound to `thisArg` and
     * invoked with three arguments: (value, index|key, collection).
     *
     * If a property name is provided for `predicate` the created `_.property`
     * style callback returns the property value of the given element.
     *
     * If a value is also provided for `thisArg` the created `_.matchesProperty`
     * style callback returns `true` for elements that have a matching property
     * value, else `false`.
     *
     * If an object is provided for `predicate` the created `_.matches` style
     * callback returns `true` for elements that have the properties of the given
     * object, else `false`.
     *
     * @static
     * @memberOf _
     * @alias detect
     * @category Collection
     * @param {Array|Object|string} collection The collection to search.
     * @param {Function|Object|string} [predicate=_.identity] The function invoked
     *  per iteration.
     * @param {*} [thisArg] The `this` binding of `predicate`.
     * @returns {*} Returns the matched element, else `undefined`.
     * @example
     *
     * var users = [
     *   { 'user': 'barney',  'age': 36, 'active': true },
     *   { 'user': 'fred',    'age': 40, 'active': false },
     *   { 'user': 'pebbles', 'age': 1,  'active': true }
     * ];
     *
     * _.result(_.find(users, function(chr) {
     *   return chr.age < 40;
     * }), 'user');
     * // => 'barney'
     *
     * // using the `_.matches` callback shorthand
     * _.result(_.find(users, { 'age': 1, 'active': true }), 'user');
     * // => 'pebbles'
     *
     * // using the `_.matchesProperty` callback shorthand
     * _.result(_.find(users, 'active', false), 'user');
     * // => 'fred'
     *
     * // using the `_.property` callback shorthand
     * _.result(_.find(users, 'active'), 'user');
     * // => 'barney'
     */
    var find = createFind(baseEach);

    /**
     * This method is like `_.find` except that it iterates over elements of
     * `collection` from right to left.
     *
     * @static
     * @memberOf _
     * @category Collection
     * @param {Array|Object|string} collection The collection to search.
     * @param {Function|Object|string} [predicate=_.identity] The function invoked
     *  per iteration.
     * @param {*} [thisArg] The `this` binding of `predicate`.
     * @returns {*} Returns the matched element, else `undefined`.
     * @example
     *
     * _.findLast([1, 2, 3, 4], function(n) {
     *   return n % 2 == 1;
     * });
     * // => 3
     */
    var findLast = createFind(baseEachRight, true);

    /**
     * Performs a deep comparison between each element in `collection` and the
     * source object, returning the first element that has equivalent property
     * values.
     *
     * **Note:** This method supports comparing arrays, booleans, `Date` objects,
     * numbers, `Object` objects, regexes, and strings. Objects are compared by
     * their own, not inherited, enumerable properties. For comparing a single
     * own or inherited property value see `_.matchesProperty`.
     *
     * @static
     * @memberOf _
     * @category Collection
     * @param {Array|Object|string} collection The collection to search.
     * @param {Object} source The object of property values to match.
     * @returns {*} Returns the matched element, else `undefined`.
     * @example
     *
     * var users = [
     *   { 'user': 'barney', 'age': 36, 'active': true },
     *   { 'user': 'fred',   'age': 40, 'active': false }
     * ];
     *
     * _.result(_.findWhere(users, { 'age': 36, 'active': true }), 'user');
     * // => 'barney'
     *
     * _.result(_.findWhere(users, { 'age': 40, 'active': false }), 'user');
     * // => 'fred'
     */
    function findWhere(collection, source) {
      return find(collection, baseMatches(source));
    }

    /**
     * Iterates over elements of `collection` invoking `iteratee` for each element.
     * The `iteratee` is bound to `thisArg` and invoked with three arguments:
     * (value, index|key, collection). Iteratee functions may exit iteration early
     * by explicitly returning `false`.
     *
     * **Note:** As with other "Collections" methods, objects with a "length" property
     * are iterated like arrays. To avoid this behavior `_.forIn` or `_.forOwn`
     * may be used for object iteration.
     *
     * @static
     * @memberOf _
     * @alias each
     * @category Collection
     * @param {Array|Object|string} collection The collection to iterate over.
     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
     * @param {*} [thisArg] The `this` binding of `iteratee`.
     * @returns {Array|Object|string} Returns `collection`.
     * @example
     *
     * _([1, 2]).forEach(function(n) {
     *   console.log(n);
     * }).value();
     * // => logs each value from left to right and returns the array
     *
     * _.forEach({ 'a': 1, 'b': 2 }, function(n, key) {
     *   console.log(n, key);
     * });
     * // => logs each value-key pair and returns the object (iteration order is not guaranteed)
     */
    var forEach = createForEach(arrayEach, baseEach);

    /**
     * This method is like `_.forEach` except that it iterates over elements of
     * `collection` from right to left.
     *
     * @static
     * @memberOf _
     * @alias eachRight
     * @category Collection
     * @param {Array|Object|string} collection The collection to iterate over.
     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
     * @param {*} [thisArg] The `this` binding of `iteratee`.
     * @returns {Array|Object|string} Returns `collection`.
     * @example
     *
     * _([1, 2]).forEachRight(function(n) {
     *   console.log(n);
     * }).value();
     * // => logs each value from right to left and returns the array
     */
    var forEachRight = createForEach(arrayEachRight, baseEachRight);

    /**
     * Creates an object composed of keys generated from the results of running
     * each element of `collection` through `iteratee`. The corresponding value
     * of each key is an array of the elements responsible for generating the key.
     * The `iteratee` is bound to `thisArg` and invoked with three arguments:
     * (value, index|key, collection).
     *
     * If a property name is provided for `iteratee` the created `_.property`
     * style callback returns the property value of the given element.
     *
     * If a value is also provided for `thisArg` the created `_.matchesProperty`
     * style callback returns `true` for elements that have a matching property
     * value, else `false`.
     *
     * If an object is provided for `iteratee` the created `_.matches` style
     * callback returns `true` for elements that have the properties of the given
     * object, else `false`.
     *
     * @static
     * @memberOf _
     * @category Collection
     * @param {Array|Object|string} collection The collection to iterate over.
     * @param {Function|Object|string} [iteratee=_.identity] The function invoked
     *  per iteration.
     * @param {*} [thisArg] The `this` binding of `iteratee`.
     * @returns {Object} Returns the composed aggregate object.
     * @example
     *
     * _.groupBy([4.2, 6.1, 6.4], function(n) {
     *   return Math.floor(n);
     * });
     * // => { '4': [4.2], '6': [6.1, 6.4] }
     *
     * _.groupBy([4.2, 6.1, 6.4], function(n) {
     *   return this.floor(n);
     * }, Math);
     * // => { '4': [4.2], '6': [6.1, 6.4] }
     *
     * // using the `_.property` callback shorthand
     * _.groupBy(['one', 'two', 'three'], 'length');
     * // => { '3': ['one', 'two'], '5': ['three'] }
     */
    var groupBy = createAggregator(function(result, value, key) {
      if (hasOwnProperty.call(result, key)) {
        result[key].push(value);
      } else {
        result[key] = [value];
      }
    });

    /**
     * Checks if `value` is in `collection` using
     * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
     * for equality comparisons. If `fromIndex` is negative, it is used as the offset
     * from the end of `collection`.
     *
     * @static
     * @memberOf _
     * @alias contains, include
     * @category Collection
     * @param {Array|Object|string} collection The collection to search.
     * @param {*} target The value to search for.
     * @param {number} [fromIndex=0] The index to search from.
     * @param- {Object} [guard] Enables use as a callback for functions like `_.reduce`.
     * @returns {boolean} Returns `true` if a matching element is found, else `false`.
     * @example
     *
     * _.includes([1, 2, 3], 1);
     * // => true
     *
     * _.includes([1, 2, 3], 1, 2);
     * // => false
     *
     * _.includes({ 'user': 'fred', 'age': 40 }, 'fred');
     * // => true
     *
     * _.includes('pebbles', 'eb');
     * // => true
     */
    function includes(collection, target, fromIndex, guard) {
      var length = collection ? getLength(collection) : 0;
      if (!isLength(length)) {
        collection = values(collection);
        length = collection.length;
      }
      if (typeof fromIndex != 'number' || (guard && isIterateeCall(target, fromIndex, guard))) {
        fromIndex = 0;
      } else {
        fromIndex = fromIndex < 0 ? nativeMax(length + fromIndex, 0) : (fromIndex || 0);
      }
      return (typeof collection == 'string' || !isArray(collection) && isString(collection))
        ? (fromIndex <= length && collection.indexOf(target, fromIndex) > -1)
        : (!!length && getIndexOf(collection, target, fromIndex) > -1);
    }

    /**
     * Creates an object composed of keys generated from the results of running
     * each element of `collection` through `iteratee`. The corresponding value
     * of each key is the last element responsible for generating the key. The
     * iteratee function is bound to `thisArg` and invoked with three arguments:
     * (value, index|key, collection).
     *
     * If a property name is provided for `iteratee` the created `_.property`
     * style callback returns the property value of the given element.
     *
     * If a value is also provided for `thisArg` the created `_.matchesProperty`
     * style callback returns `true` for elements that have a matching property
     * value, else `false`.
     *
     * If an object is provided for `iteratee` the created `_.matches` style
     * callback returns `true` for elements that have the properties of the given
     * object, else `false`.
     *
     * @static
     * @memberOf _
     * @category Collection
     * @param {Array|Object|string} collection The collection to iterate over.
     * @param {Function|Object|string} [iteratee=_.identity] The function invoked
     *  per iteration.
     * @param {*} [thisArg] The `this` binding of `iteratee`.
     * @returns {Object} Returns the composed aggregate object.
     * @example
     *
     * var keyData = [
     *   { 'dir': 'left', 'code': 97 },
     *   { 'dir': 'right', 'code': 100 }
     * ];
     *
     * _.indexBy(keyData, 'dir');
     * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } }
     *
     * _.indexBy(keyData, function(object) {
     *   return String.fromCharCode(object.code);
     * });
     * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } }
     *
     * _.indexBy(keyData, function(object) {
     *   return this.fromCharCode(object.code);
     * }, String);
     * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } }
     */
    var indexBy = createAggregator(function(result, value, key) {
      result[key] = value;
    });

    /**
     * Invokes the method at `path` of each element in `collection`, returning
     * an array of the results of each invoked method. Any additional arguments
     * are provided to each invoked method. If `methodName` is a function it is
     * invoked for, and `this` bound to, each element in `collection`.
     *
     * @static
     * @memberOf _
     * @category Collection
     * @param {Array|Object|string} collection The collection to iterate over.
     * @param {Array|Function|string} path The path of the method to invoke or
     *  the function invoked per iteration.
     * @param {...*} [args] The arguments to invoke the method with.
     * @returns {Array} Returns the array of results.
     * @example
     *
     * _.invoke([[5, 1, 7], [3, 2, 1]], 'sort');
     * // => [[1, 5, 7], [1, 2, 3]]
     *
     * _.invoke([123, 456], String.prototype.split, '');
     * // => [['1', '2', '3'], ['4', '5', '6']]
     */
    var invoke = restParam(function(collection, path, args) {
      var index = -1,
          isFunc = typeof path == 'function',
          isProp = isKey(path),
          result = isArrayLike(collection) ? Array(collection.length) : [];

      baseEach(collection, function(value) {
        var func = isFunc ? path : ((isProp && value != null) ? value[path] : undefined);
        result[++index] = func ? func.apply(value, args) : invokePath(value, path, args);
      });
      return result;
    });

    /**
     * Creates an array of values by running each element in `collection` through
     * `iteratee`. The `iteratee` is bound to `thisArg` and invoked with three
     * arguments: (value, index|key, collection).
     *
     * If a property name is provided for `iteratee` the created `_.property`
     * style callback returns the property value of the given element.
     *
     * If a value is also provided for `thisArg` the created `_.matchesProperty`
     * style callback returns `true` for elements that have a matching property
     * value, else `false`.
     *
     * If an object is provided for `iteratee` the created `_.matches` style
     * callback returns `true` for elements that have the properties of the given
     * object, else `false`.
     *
     * Many lodash methods are guarded to work as iteratees for methods like
     * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`.
     *
     * The guarded methods are:
     * `ary`, `callback`, `chunk`, `clone`, `create`, `curry`, `curryRight`,
     * `drop`, `dropRight`, `every`, `fill`, `flatten`, `invert`, `max`, `min`,
     * `parseInt`, `slice`, `sortBy`, `take`, `takeRight`, `template`, `trim`,
     * `trimLeft`, `trimRight`, `trunc`, `random`, `range`, `sample`, `some`,
     * `sum`, `uniq`, and `words`
     *
     * @static
     * @memberOf _
     * @alias collect
     * @category Collection
     * @param {Array|Object|string} collection The collection to iterate over.
     * @param {Function|Object|string} [iteratee=_.identity] The function invoked
     *  per iteration.
     * @param {*} [thisArg] The `this` binding of `iteratee`.
     * @returns {Array} Returns the new mapped array.
     * @example
     *
     * function timesThree(n) {
     *   return n * 3;
     * }
     *
     * _.map([1, 2], timesThree);
     * // => [3, 6]
     *
     * _.map({ 'a': 1, 'b': 2 }, timesThree);
     * // => [3, 6] (iteration order is not guaranteed)
     *
     * var users = [
     *   { 'user': 'barney' },
     *   { 'user': 'fred' }
     * ];
     *
     * // using the `_.property` callback shorthand
     * _.map(users, 'user');
     * // => ['barney', 'fred']
     */
    function map(collection, iteratee, thisArg) {
      var func = isArray(collection) ? arrayMap : baseMap;
      iteratee = getCallback(iteratee, thisArg, 3);
      return func(collection, iteratee);
    }

    /**
     * Creates an array of elements split into two groups, the first of which
     * contains elements `predicate` returns truthy for, while the second of which
     * contains elements `predicate` returns falsey for. The predicate is bound
     * to `thisArg` and invoked with three arguments: (value, index|key, collection).
     *
     * If a property name is provided for `predicate` the created `_.property`
     * style callback returns the property value of the given element.
     *
     * If a value is also provided for `thisArg` the created `_.matchesProperty`
     * style callback returns `true` for elements that have a matching property
     * value, else `false`.
     *
     * If an object is provided for `predicate` the created `_.matches` style
     * callback returns `true` for elements that have the properties of the given
     * object, else `false`.
     *
     * @static
     * @memberOf _
     * @category Collection
     * @param {Array|Object|string} collection The collection to iterate over.
     * @param {Function|Object|string} [predicate=_.identity] The function invoked
     *  per iteration.
     * @param {*} [thisArg] The `this` binding of `predicate`.
     * @returns {Array} Returns the array of grouped elements.
     * @example
     *
     * _.partition([1, 2, 3], function(n) {
     *   return n % 2;
     * });
     * // => [[1, 3], [2]]
     *
     * _.partition([1.2, 2.3, 3.4], function(n) {
     *   return this.floor(n) % 2;
     * }, Math);
     * // => [[1.2, 3.4], [2.3]]
     *
     * var users = [
     *   { 'user': 'barney',  'age': 36, 'active': false },
     *   { 'user': 'fred',    'age': 40, 'active': true },
     *   { 'user': 'pebbles', 'age': 1,  'active': false }
     * ];
     *
     * var mapper = function(array) {
     *   return _.pluck(array, 'user');
     * };
     *
     * // using the `_.matches` callback shorthand
     * _.map(_.partition(users, { 'age': 1, 'active': false }), mapper);
     * // => [['pebbles'], ['barney', 'fred']]
     *
     * // using the `_.matchesProperty` callback shorthand
     * _.map(_.partition(users, 'active', false), mapper);
     * // => [['barney', 'pebbles'], ['fred']]
     *
     * // using the `_.property` callback shorthand
     * _.map(_.partition(users, 'active'), mapper);
     * // => [['fred'], ['barney', 'pebbles']]
     */
    var partition = createAggregator(function(result, value, key) {
      result[key ? 0 : 1].push(value);
    }, function() { return [[], []]; });

    /**
     * Gets the property value of `path` from all elements in `collection`.
     *
     * @static
     * @memberOf _
     * @category Collection
     * @param {Array|Object|string} collection The collection to iterate over.
     * @param {Array|string} path The path of the property to pluck.
     * @returns {Array} Returns the property values.
     * @example
     *
     * var users = [
     *   { 'user': 'barney', 'age': 36 },
     *   { 'user': 'fred',   'age': 40 }
     * ];
     *
     * _.pluck(users, 'user');
     * // => ['barney', 'fred']
     *
     * var userIndex = _.indexBy(users, 'user');
     * _.pluck(userIndex, 'age');
     * // => [36, 40] (iteration order is not guaranteed)
     */
    function pluck(collection, path) {
      return map(collection, property(path));
    }

    /**
     * Reduces `collection` to a value which is the accumulated result of running
     * each element in `collection` through `iteratee`, where each successive
     * invocation is supplied the return value of the previous. If `accumulator`
     * is not provided the first element of `collection` is used as the initial
     * value. The `iteratee` is bound to `thisArg` and invoked with four arguments:
     * (accumulator, value, index|key, collection).
     *
     * Many lodash methods are guarded to work as iteratees for methods like
     * `_.reduce`, `_.reduceRight`, and `_.transform`.
     *
     * The guarded methods are:
     * `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `sortByAll`,
     * and `sortByOrder`
     *
     * @static
     * @memberOf _
     * @alias foldl, inject
     * @category Collection
     * @param {Array|Object|string} collection The collection to iterate over.
     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
     * @param {*} [accumulator] The initial value.
     * @param {*} [thisArg] The `this` binding of `iteratee`.
     * @returns {*} Returns the accumulated value.
     * @example
     *
     * _.reduce([1, 2], function(total, n) {
     *   return total + n;
     * });
     * // => 3
     *
     * _.reduce({ 'a': 1, 'b': 2 }, function(result, n, key) {
     *   result[key] = n * 3;
     *   return result;
     * }, {});
     * // => { 'a': 3, 'b': 6 } (iteration order is not guaranteed)
     */
    var reduce = createReduce(arrayReduce, baseEach);

    /**
     * This method is like `_.reduce` except that it iterates over elements of
     * `collection` from right to left.
     *
     * @static
     * @memberOf _
     * @alias foldr
     * @category Collection
     * @param {Array|Object|string} collection The collection to iterate over.
     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
     * @param {*} [accumulator] The initial value.
     * @param {*} [thisArg] The `this` binding of `iteratee`.
     * @returns {*} Returns the accumulated value.
     * @example
     *
     * var array = [[0, 1], [2, 3], [4, 5]];
     *
     * _.reduceRight(array, function(flattened, other) {
     *   return flattened.concat(other);
     * }, []);
     * // => [4, 5, 2, 3, 0, 1]
     */
    var reduceRight = createReduce(arrayReduceRight, baseEachRight);

    /**
     * The opposite of `_.filter`; this method returns the elements of `collection`
     * that `predicate` does **not** return truthy for.
     *
     * @static
     * @memberOf _
     * @category Collection
     * @param {Array|Object|string} collection The collection to iterate over.
     * @param {Function|Object|string} [predicate=_.identity] The function invoked
     *  per iteration.
     * @param {*} [thisArg] The `this` binding of `predicate`.
     * @returns {Array} Returns the new filtered array.
     * @example
     *
     * _.reject([1, 2, 3, 4], function(n) {
     *   return n % 2 == 0;
     * });
     * // => [1, 3]
     *
     * var users = [
     *   { 'user': 'barney', 'age': 36, 'active': false },
     *   { 'user': 'fred',   'age': 40, 'active': true }
     * ];
     *
     * // using the `_.matches` callback shorthand
     * _.pluck(_.reject(users, { 'age': 40, 'active': true }), 'user');
     * // => ['barney']
     *
     * // using the `_.matchesProperty` callback shorthand
     * _.pluck(_.reject(users, 'active', false), 'user');
     * // => ['fred']
     *
     * // using the `_.property` callback shorthand
     * _.pluck(_.reject(users, 'active'), 'user');
     * // => ['barney']
     */
    function reject(collection, predicate, thisArg) {
      var func = isArray(collection) ? arrayFilter : baseFilter;
      predicate = getCallback(predicate, thisArg, 3);
      return func(collection, function(value, index, collection) {
        return !predicate(value, index, collection);
      });
    }

    /**
     * Gets a random element or `n` random elements from a collection.
     *
     * @static
     * @memberOf _
     * @category Collection
     * @param {Array|Object|string} collection The collection to sample.
     * @param {number} [n] The number of elements to sample.
     * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.
     * @returns {*} Returns the random sample(s).
     * @example
     *
     * _.sample([1, 2, 3, 4]);
     * // => 2
     *
     * _.sample([1, 2, 3, 4], 2);
     * // => [3, 1]
     */
    function sample(collection, n, guard) {
      if (guard ? isIterateeCall(collection, n, guard) : n == null) {
        collection = toIterable(collection);
        var length = collection.length;
        return length > 0 ? collection[baseRandom(0, length - 1)] : undefined;
      }
      var index = -1,
          result = toArray(collection),
          length = result.length,
          lastIndex = length - 1;

      n = nativeMin(n < 0 ? 0 : (+n || 0), length);
      while (++index < n) {
        var rand = baseRandom(index, lastIndex),
            value = result[rand];

        result[rand] = result[index];
        result[index] = value;
      }
      result.length = n;
      return result;
    }

    /**
     * Creates an array of shuffled values, using a version of the
     * [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher-Yates_shuffle).
     *
     * @static
     * @memberOf _
     * @category Collection
     * @param {Array|Object|string} collection The collection to shuffle.
     * @returns {Array} Returns the new shuffled array.
     * @example
     *
     * _.shuffle([1, 2, 3, 4]);
     * // => [4, 1, 3, 2]
     */
    function shuffle(collection) {
      return sample(collection, POSITIVE_INFINITY);
    }

    /**
     * Gets the size of `collection` by returning its length for array-like
     * values or the number of own enumerable properties for objects.
     *
     * @static
     * @memberOf _
     * @category Collection
     * @param {Array|Object|string} collection The collection to inspect.
     * @returns {number} Returns the size of `collection`.
     * @example
     *
     * _.size([1, 2, 3]);
     * // => 3
     *
     * _.size({ 'a': 1, 'b': 2 });
     * // => 2
     *
     * _.size('pebbles');
     * // => 7
     */
    function size(collection) {
      var length = collection ? getLength(collection) : 0;
      return isLength(length) ? length : keys(collection).length;
    }

    /**
     * Checks if `predicate` returns truthy for **any** element of `collection`.
     * The function returns as soon as it finds a passing value and does not iterate
     * over the entire collection. The predicate is bound to `thisArg` and invoked
     * with three arguments: (value, index|key, collection).
     *
     * If a property name is provided for `predicate` the created `_.property`
     * style callback returns the property value of the given element.
     *
     * If a value is also provided for `thisArg` the created `_.matchesProperty`
     * style callback returns `true` for elements that have a matching property
     * value, else `false`.
     *
     * If an object is provided for `predicate` the created `_.matches` style
     * callback returns `true` for elements that have the properties of the given
     * object, else `false`.
     *
     * @static
     * @memberOf _
     * @alias any
     * @category Collection
     * @param {Array|Object|string} collection The collection to iterate over.
     * @param {Function|Object|string} [predicate=_.identity] The function invoked
     *  per iteration.
     * @param {*} [thisArg] The `this` binding of `predicate`.
     * @returns {boolean} Returns `true` if any element passes the predicate check,
     *  else `false`.
     * @example
     *
     * _.some([null, 0, 'yes', false], Boolean);
     * // => true
     *
     * var users = [
     *   { 'user': 'barney', 'active': true },
     *   { 'user': 'fred',   'active': false }
     * ];
     *
     * // using the `_.matches` callback shorthand
     * _.some(users, { 'user': 'barney', 'active': false });
     * // => false
     *
     * // using the `_.matchesProperty` callback shorthand
     * _.some(users, 'active', false);
     * // => true
     *
     * // using the `_.property` callback shorthand
     * _.some(users, 'active');
     * // => true
     */
    function some(collection, predicate, thisArg) {
      var func = isArray(collection) ? arraySome : baseSome;
      if (thisArg && isIterateeCall(collection, predicate, thisArg)) {
        predicate = undefined;
      }
      if (typeof predicate != 'function' || thisArg !== undefined) {
        predicate = getCallback(predicate, thisArg, 3);
      }
      return func(collection, predicate);
    }

    /**
     * Creates an array of elements, sorted in ascending order by the results of
     * running each element in a collection through `iteratee`. This method performs
     * a stable sort, that is, it preserves the original sort order of equal elements.
     * The `iteratee` is bound to `thisArg` and invoked with three arguments:
     * (value, index|key, collection).
     *
     * If a property name is provided for `iteratee` the created `_.property`
     * style callback returns the property value of the given element.
     *
     * If a value is also provided for `thisArg` the created `_.matchesProperty`
     * style callback returns `true` for elements that have a matching property
     * value, else `false`.
     *
     * If an object is provided for `iteratee` the created `_.matches` style
     * callback returns `true` for elements that have the properties of the given
     * object, else `false`.
     *
     * @static
     * @memberOf _
     * @category Collection
     * @param {Array|Object|string} collection The collection to iterate over.
     * @param {Function|Object|string} [iteratee=_.identity] The function invoked
     *  per iteration.
     * @param {*} [thisArg] The `this` binding of `iteratee`.
     * @returns {Array} Returns the new sorted array.
     * @example
     *
     * _.sortBy([1, 2, 3], function(n) {
     *   return Math.sin(n);
     * });
     * // => [3, 1, 2]
     *
     * _.sortBy([1, 2, 3], function(n) {
     *   return this.sin(n);
     * }, Math);
     * // => [3, 1, 2]
     *
     * var users = [
     *   { 'user': 'fred' },
     *   { 'user': 'pebbles' },
     *   { 'user': 'barney' }
     * ];
     *
     * // using the `_.property` callback shorthand
     * _.pluck(_.sortBy(users, 'user'), 'user');
     * // => ['barney', 'fred', 'pebbles']
     */
    function sortBy(collection, iteratee, thisArg) {
      if (collection == null) {
        return [];
      }
      if (thisArg && isIterateeCall(collection, iteratee, thisArg)) {
        iteratee = undefined;
      }
      var index = -1;
      iteratee = getCallback(iteratee, thisArg, 3);

      var result = baseMap(collection, function(value, key, collection) {
        return { 'criteria': iteratee(value, key, collection), 'index': ++index, 'value': value };
      });
      return baseSortBy(result, compareAscending);
    }

    /**
     * This method is like `_.sortBy` except that it can sort by multiple iteratees
     * or property names.
     *
     * If a property name is provided for an iteratee the created `_.property`
     * style callback returns the property value of the given element.
     *
     * If an object is provided for an iteratee the created `_.matches` style
     * callback returns `true` for elements that have the properties of the given
     * object, else `false`.
     *
     * @static
     * @memberOf _
     * @category Collection
     * @param {Array|Object|string} collection The collection to iterate over.
     * @param {...(Function|Function[]|Object|Object[]|string|string[])} iteratees
     *  The iteratees to sort by, specified as individual values or arrays of values.
     * @returns {Array} Returns the new sorted array.
     * @example
     *
     * var users = [
     *   { 'user': 'fred',   'age': 48 },
     *   { 'user': 'barney', 'age': 36 },
     *   { 'user': 'fred',   'age': 42 },
     *   { 'user': 'barney', 'age': 34 }
     * ];
     *
     * _.map(_.sortByAll(users, ['user', 'age']), _.values);
     * // => [['barney', 34], ['barney', 36], ['fred', 42], ['fred', 48]]
     *
     * _.map(_.sortByAll(users, 'user', function(chr) {
     *   return Math.floor(chr.age / 10);
     * }), _.values);
     * // => [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 42]]
     */
    var sortByAll = restParam(function(collection, iteratees) {
      if (collection == null) {
        return [];
      }
      var guard = iteratees[2];
      if (guard && isIterateeCall(iteratees[0], iteratees[1], guard)) {
        iteratees.length = 1;
      }
      return baseSortByOrder(collection, baseFlatten(iteratees), []);
    });

    /**
     * This method is like `_.sortByAll` except that it allows specifying the
     * sort orders of the iteratees to sort by. If `orders` is unspecified, all
     * values are sorted in ascending order. Otherwise, a value is sorted in
     * ascending order if its corresponding order is "asc", and descending if "desc".
     *
     * If a property name is provided for an iteratee the created `_.property`
     * style callback returns the property value of the given element.
     *
     * If an object is provided for an iteratee the created `_.matches` style
     * callback returns `true` for elements that have the properties of the given
     * object, else `false`.
     *
     * @static
     * @memberOf _
     * @category Collection
     * @param {Array|Object|string} collection The collection to iterate over.
     * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by.
     * @param {boolean[]} [orders] The sort orders of `iteratees`.
     * @param- {Object} [guard] Enables use as a callback for functions like `_.reduce`.
     * @returns {Array} Returns the new sorted array.
     * @example
     *
     * var users = [
     *   { 'user': 'fred',   'age': 48 },
     *   { 'user': 'barney', 'age': 34 },
     *   { 'user': 'fred',   'age': 42 },
     *   { 'user': 'barney', 'age': 36 }
     * ];
     *
     * // sort by `user` in ascending order and by `age` in descending order
     * _.map(_.sortByOrder(users, ['user', 'age'], ['asc', 'desc']), _.values);
     * // => [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 42]]
     */
    function sortByOrder(collection, iteratees, orders, guard) {
      if (collection == null) {
        return [];
      }
      if (guard && isIterateeCall(iteratees, orders, guard)) {
        orders = undefined;
      }
      if (!isArray(iteratees)) {
        iteratees = iteratees == null ? [] : [iteratees];
      }
      if (!isArray(orders)) {
        orders = orders == null ? [] : [orders];
      }
      return baseSortByOrder(collection, iteratees, orders);
    }

    /**
     * Performs a deep comparison between each element in `collection` and the
     * source object, returning an array of all elements that have equivalent
     * property values.
     *
     * **Note:** This method supports comparing arrays, booleans, `Date` objects,
     * numbers, `Object` objects, regexes, and strings. Objects are compared by
     * their own, not inherited, enumerable properties. For comparing a single
     * own or inherited property value see `_.matchesProperty`.
     *
     * @static
     * @memberOf _
     * @category Collection
     * @param {Array|Object|string} collection The collection to search.
     * @param {Object} source The object of property values to match.
     * @returns {Array} Returns the new filtered array.
     * @example
     *
     * var users = [
     *   { 'user': 'barney', 'age': 36, 'active': false, 'pets': ['hoppy'] },
     *   { 'user': 'fred',   'age': 40, 'active': true, 'pets': ['baby puss', 'dino'] }
     * ];
     *
     * _.pluck(_.where(users, { 'age': 36, 'active': false }), 'user');
     * // => ['barney']
     *
     * _.pluck(_.where(users, { 'pets': ['dino'] }), 'user');
     * // => ['fred']
     */
    function where(collection, source) {
      return filter(collection, baseMatches(source));
    }

    /*------------------------------------------------------------------------*/

    /**
     * Gets the number of milliseconds that have elapsed since the Unix epoch
     * (1 January 1970 00:00:00 UTC).
     *
     * @static
     * @memberOf _
     * @category Date
     * @example
     *
     * _.defer(function(stamp) {
     *   console.log(_.now() - stamp);
     * }, _.now());
     * // => logs the number of milliseconds it took for the deferred function to be invoked
     */
    var now = nativeNow || function() {
      return new Date().getTime();
    };

    /*------------------------------------------------------------------------*/

    /**
     * The opposite of `_.before`; this method creates a function that invokes
     * `func` once it is called `n` or more times.
     *
     * @static
     * @memberOf _
     * @category Function
     * @param {number} n The number of calls before `func` is invoked.
     * @param {Function} func The function to restrict.
     * @returns {Function} Returns the new restricted function.
     * @example
     *
     * var saves = ['profile', 'settings'];
     *
     * var done = _.after(saves.length, function() {
     *   console.log('done saving!');
     * });
     *
     * _.forEach(saves, function(type) {
     *   asyncSave({ 'type': type, 'complete': done });
     * });
     * // => logs 'done saving!' after the two async saves have completed
     */
    function after(n, func) {
      if (typeof func != 'function') {
        if (typeof n == 'function') {
          var temp = n;
          n = func;
          func = temp;
        } else {
          throw new TypeError(FUNC_ERROR_TEXT);
        }
      }
      n = nativeIsFinite(n = +n) ? n : 0;
      return function() {
        if (--n < 1) {
          return func.apply(this, arguments);
        }
      };
    }

    /**
     * Creates a function that accepts up to `n` arguments ignoring any
     * additional arguments.
     *
     * @static
     * @memberOf _
     * @category Function
     * @param {Function} func The function to cap arguments for.
     * @param {number} [n=func.length] The arity cap.
     * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.
     * @returns {Function} Returns the new function.
     * @example
     *
     * _.map(['6', '8', '10'], _.ary(parseInt, 1));
     * // => [6, 8, 10]
     */
    function ary(func, n, guard) {
      if (guard && isIterateeCall(func, n, guard)) {
        n = undefined;
      }
      n = (func && n == null) ? func.length : nativeMax(+n || 0, 0);
      return createWrapper(func, ARY_FLAG, undefined, undefined, undefined, undefined, n);
    }

    /**
     * Creates a function that invokes `func`, with the `this` binding and arguments
     * of the created function, while it is called less than `n` times. Subsequent
     * calls to the created function return the result of the last `func` invocation.
     *
     * @static
     * @memberOf _
     * @category Function
     * @param {number} n The number of calls at which `func` is no longer invoked.
     * @param {Function} func The function to restrict.
     * @returns {Function} Returns the new restricted function.
     * @example
     *
     * jQuery('#add').on('click', _.before(5, addContactToList));
     * // => allows adding up to 4 contacts to the list
     */
    function before(n, func) {
      var result;
      if (typeof func != 'function') {
        if (typeof n == 'function') {
          var temp = n;
          n = func;
          func = temp;
        } else {
          throw new TypeError(FUNC_ERROR_TEXT);
        }
      }
      return function() {
        if (--n > 0) {
          result = func.apply(this, arguments);
        }
        if (n <= 1) {
          func = undefined;
        }
        return result;
      };
    }

    /**
     * Creates a function that invokes `func` with the `this` binding of `thisArg`
     * and prepends any additional `_.bind` arguments to those provided to the
     * bound function.
     *
     * The `_.bind.placeholder` value, which defaults to `_` in monolithic builds,
     * may be used as a placeholder for partially applied arguments.
     *
     * **Note:** Unlike native `Function#bind` this method does not set the "length"
     * property of bound functions.
     *
     * @static
     * @memberOf _
     * @category Function
     * @param {Function} func The function to bind.
     * @param {*} thisArg The `this` binding of `func`.
     * @param {...*} [partials] The arguments to be partially applied.
     * @returns {Function} Returns the new bound function.
     * @example
     *
     * var greet = function(greeting, punctuation) {
     *   return greeting + ' ' + this.user + punctuation;
     * };
     *
     * var object = { 'user': 'fred' };
     *
     * var bound = _.bind(greet, object, 'hi');
     * bound('!');
     * // => 'hi fred!'
     *
     * // using placeholders
     * var bound = _.bind(greet, object, _, '!');
     * bound('hi');
     * // => 'hi fred!'
     */
    var bind = restParam(function(func, thisArg, partials) {
      var bitmask = BIND_FLAG;
      if (partials.length) {
        var holders = replaceHolders(partials, bind.placeholder);
        bitmask |= PARTIAL_FLAG;
      }
      return createWrapper(func, bitmask, thisArg, partials, holders);
    });

    /**
     * Binds methods of an object to the object itself, overwriting the existing
     * method. Method names may be specified as individual arguments or as arrays
     * of method names. If no method names are provided all enumerable function
     * properties, own and inherited, of `object` are bound.
     *
     * **Note:** This method does not set the "length" property of bound functions.
     *
     * @static
     * @memberOf _
     * @category Function
     * @param {Object} object The object to bind and assign the bound methods to.
     * @param {...(string|string[])} [methodNames] The object method names to bind,
     *  specified as individual method names or arrays of method names.
     * @returns {Object} Returns `object`.
     * @example
     *
     * var view = {
     *   'label': 'docs',
     *   'onClick': function() {
     *     console.log('clicked ' + this.label);
     *   }
     * };
     *
     * _.bindAll(view);
     * jQuery('#docs').on('click', view.onClick);
     * // => logs 'clicked docs' when the element is clicked
     */
    var bindAll = restParam(function(object, methodNames) {
      methodNames = methodNames.length ? baseFlatten(methodNames) : functions(object);

      var index = -1,
          length = methodNames.length;

      while (++index < length) {
        var key = methodNames[index];
        object[key] = createWrapper(object[key], BIND_FLAG, object);
      }
      return object;
    });

    /**
     * Creates a function that invokes the method at `object[key]` and prepends
     * any additional `_.bindKey` arguments to those provided to the bound function.
     *
     * This method differs from `_.bind` by allowing bound functions to reference
     * methods that may be redefined or don't yet exist.
     * See [Peter Michaux's article](http://peter.michaux.ca/articles/lazy-function-definition-pattern)
     * for more details.
     *
     * The `_.bindKey.placeholder` value, which defaults to `_` in monolithic
     * builds, may be used as a placeholder for partially applied arguments.
     *
     * @static
     * @memberOf _
     * @category Function
     * @param {Object} object The object the method belongs to.
     * @param {string} key The key of the method.
     * @param {...*} [partials] The arguments to be partially applied.
     * @returns {Function} Returns the new bound function.
     * @example
     *
     * var object = {
     *   'user': 'fred',
     *   'greet': function(greeting, punctuation) {
     *     return greeting + ' ' + this.user + punctuation;
     *   }
     * };
     *
     * var bound = _.bindKey(object, 'greet', 'hi');
     * bound('!');
     * // => 'hi fred!'
     *
     * object.greet = function(greeting, punctuation) {
     *   return greeting + 'ya ' + this.user + punctuation;
     * };
     *
     * bound('!');
     * // => 'hiya fred!'
     *
     * // using placeholders
     * var bound = _.bindKey(object, 'greet', _, '!');
     * bound('hi');
     * // => 'hiya fred!'
     */
    var bindKey = restParam(function(object, key, partials) {
      var bitmask = BIND_FLAG | BIND_KEY_FLAG;
      if (partials.length) {
        var holders = replaceHolders(partials, bindKey.placeholder);
        bitmask |= PARTIAL_FLAG;
      }
      return createWrapper(key, bitmask, object, partials, holders);
    });

    /**
     * Creates a function that accepts one or more arguments of `func` that when
     * called either invokes `func` returning its result, if all `func` arguments
     * have been provided, or returns a function that accepts one or more of the
     * remaining `func` arguments, and so on. The arity of `func` may be specified
     * if `func.length` is not sufficient.
     *
     * The `_.curry.placeholder` value, which defaults to `_` in monolithic builds,
     * may be used as a placeholder for provided arguments.
     *
     * **Note:** This method does not set the "length" property of curried functions.
     *
     * @static
     * @memberOf _
     * @category Function
     * @param {Function} func The function to curry.
     * @param {number} [arity=func.length] The arity of `func`.
     * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.
     * @returns {Function} Returns the new curried function.
     * @example
     *
     * var abc = function(a, b, c) {
     *   return [a, b, c];
     * };
     *
     * var curried = _.curry(abc);
     *
     * curried(1)(2)(3);
     * // => [1, 2, 3]
     *
     * curried(1, 2)(3);
     * // => [1, 2, 3]
     *
     * curried(1, 2, 3);
     * // => [1, 2, 3]
     *
     * // using placeholders
     * curried(1)(_, 3)(2);
     * // => [1, 2, 3]
     */
    var curry = createCurry(CURRY_FLAG);

    /**
     * This method is like `_.curry` except that arguments are applied to `func`
     * in the manner of `_.partialRight` instead of `_.partial`.
     *
     * The `_.curryRight.placeholder` value, which defaults to `_` in monolithic
     * builds, may be used as a placeholder for provided arguments.
     *
     * **Note:** This method does not set the "length" property of curried functions.
     *
     * @static
     * @memberOf _
     * @category Function
     * @param {Function} func The function to curry.
     * @param {number} [arity=func.length] The arity of `func`.
     * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.
     * @returns {Function} Returns the new curried function.
     * @example
     *
     * var abc = function(a, b, c) {
     *   return [a, b, c];
     * };
     *
     * var curried = _.curryRight(abc);
     *
     * curried(3)(2)(1);
     * // => [1, 2, 3]
     *
     * curried(2, 3)(1);
     * // => [1, 2, 3]
     *
     * curried(1, 2, 3);
     * // => [1, 2, 3]
     *
     * // using placeholders
     * curried(3)(1, _)(2);
     * // => [1, 2, 3]
     */
    var curryRight = createCurry(CURRY_RIGHT_FLAG);

    /**
     * Creates a debounced function that delays invoking `func` until after `wait`
     * milliseconds have elapsed since the last time the debounced function was
     * invoked. The debounced function comes with a `cancel` method to cancel
     * delayed invocations. Provide an options object to indicate that `func`
     * should be invoked on the leading and/or trailing edge of the `wait` timeout.
     * Subsequent calls to the debounced function return the result of the last
     * `func` invocation.
     *
     * **Note:** If `leading` and `trailing` options are `true`, `func` is invoked
     * on the trailing edge of the timeout only if the the debounced function is
     * invoked more than once during the `wait` timeout.
     *
     * See [David Corbacho's article](http://drupalmotion.com/article/debounce-and-throttle-visual-explanation)
     * for details over the differences between `_.debounce` and `_.throttle`.
     *
     * @static
     * @memberOf _
     * @category Function
     * @param {Function} func The function to debounce.
     * @param {number} [wait=0] The number of milliseconds to delay.
     * @param {Object} [options] The options object.
     * @param {boolean} [options.leading=false] Specify invoking on the leading
     *  edge of the timeout.
     * @param {number} [options.maxWait] The maximum time `func` is allowed to be
     *  delayed before it is invoked.
     * @param {boolean} [options.trailing=true] Specify invoking on the trailing
     *  edge of the timeout.
     * @returns {Function} Returns the new debounced function.
     * @example
     *
     * // avoid costly calculations while the window size is in flux
     * jQuery(window).on('resize', _.debounce(calculateLayout, 150));
     *
     * // invoke `sendMail` when the click event is fired, debouncing subsequent calls
     * jQuery('#postbox').on('click', _.debounce(sendMail, 300, {
     *   'leading': true,
     *   'trailing': false
     * }));
     *
     * // ensure `batchLog` is invoked once after 1 second of debounced calls
     * var source = new EventSource('/stream');
     * jQuery(source).on('message', _.debounce(batchLog, 250, {
     *   'maxWait': 1000
     * }));
     *
     * // cancel a debounced call
     * var todoChanges = _.debounce(batchLog, 1000);
     * Object.observe(models.todo, todoChanges);
     *
     * Object.observe(models, function(changes) {
     *   if (_.find(changes, { 'user': 'todo', 'type': 'delete'})) {
     *     todoChanges.cancel();
     *   }
     * }, ['delete']);
     *
     * // ...at some point `models.todo` is changed
     * models.todo.completed = true;
     *
     * // ...before 1 second has passed `models.todo` is deleted
     * // which cancels the debounced `todoChanges` call
     * delete models.todo;
     */
    function debounce(func, wait, options) {
      var args,
          maxTimeoutId,
          result,
          stamp,
          thisArg,
          timeoutId,
          trailingCall,
          lastCalled = 0,
          maxWait = false,
          trailing = true;

      if (typeof func != 'function') {
        throw new TypeError(FUNC_ERROR_TEXT);
      }
      wait = wait < 0 ? 0 : (+wait || 0);
      if (options === true) {
        var leading = true;
        trailing = false;
      } else if (isObject(options)) {
        leading = !!options.leading;
        maxWait = 'maxWait' in options && nativeMax(+options.maxWait || 0, wait);
        trailing = 'trailing' in options ? !!options.trailing : trailing;
      }

      function cancel() {
        if (timeoutId) {
          clearTimeout(timeoutId);
        }
        if (maxTimeoutId) {
          clearTimeout(maxTimeoutId);
        }
        lastCalled = 0;
        maxTimeoutId = timeoutId = trailingCall = undefined;
      }

      function complete(isCalled, id) {
        if (id) {
          clearTimeout(id);
        }
        maxTimeoutId = timeoutId = trailingCall = undefined;
        if (isCalled) {
          lastCalled = now();
          result = func.apply(thisArg, args);
          if (!timeoutId && !maxTimeoutId) {
            args = thisArg = undefined;
          }
        }
      }

      function delayed() {
        var remaining = wait - (now() - stamp);
        if (remaining <= 0 || remaining > wait) {
          complete(trailingCall, maxTimeoutId);
        } else {
          timeoutId = setTimeout(delayed, remaining);
        }
      }

      function maxDelayed() {
        complete(trailing, timeoutId);
      }

      function debounced() {
        args = arguments;
        stamp = now();
        thisArg = this;
        trailingCall = trailing && (timeoutId || !leading);

        if (maxWait === false) {
          var leadingCall = leading && !timeoutId;
        } else {
          if (!maxTimeoutId && !leading) {
            lastCalled = stamp;
          }
          var remaining = maxWait - (stamp - lastCalled),
              isCalled = remaining <= 0 || remaining > maxWait;

          if (isCalled) {
            if (maxTimeoutId) {
              maxTimeoutId = clearTimeout(maxTimeoutId);
            }
            lastCalled = stamp;
            result = func.apply(thisArg, args);
          }
          else if (!maxTimeoutId) {
            maxTimeoutId = setTimeout(maxDelayed, remaining);
          }
        }
        if (isCalled && timeoutId) {
          timeoutId = clearTimeout(timeoutId);
        }
        else if (!timeoutId && wait !== maxWait) {
          timeoutId = setTimeout(delayed, wait);
        }
        if (leadingCall) {
          isCalled = true;
          result = func.apply(thisArg, args);
        }
        if (isCalled && !timeoutId && !maxTimeoutId) {
          args = thisArg = undefined;
        }
        return result;
      }
      debounced.cancel = cancel;
      return debounced;
    }

    /**
     * Defers invoking the `func` until the current call stack has cleared. Any
     * additional arguments are provided to `func` when it is invoked.
     *
     * @static
     * @memberOf _
     * @category Function
     * @param {Function} func The function to defer.
     * @param {...*} [args] The arguments to invoke the function with.
     * @returns {number} Returns the timer id.
     * @example
     *
     * _.defer(function(text) {
     *   console.log(text);
     * }, 'deferred');
     * // logs 'deferred' after one or more milliseconds
     */
    var defer = restParam(function(func, args) {
      return baseDelay(func, 1, args);
    });

    /**
     * Invokes `func` after `wait` milliseconds. Any additional arguments are
     * provided to `func` when it is invoked.
     *
     * @static
     * @memberOf _
     * @category Function
     * @param {Function} func The function to delay.
     * @param {number} wait The number of milliseconds to delay invocation.
     * @param {...*} [args] The arguments to invoke the function with.
     * @returns {number} Returns the timer id.
     * @example
     *
     * _.delay(function(text) {
     *   console.log(text);
     * }, 1000, 'later');
     * // => logs 'later' after one second
     */
    var delay = restParam(function(func, wait, args) {
      return baseDelay(func, wait, args);
    });

    /**
     * Creates a function that returns the result of invoking the provided
     * functions with the `this` binding of the created function, where each
     * successive invocation is supplied the return value of the previous.
     *
     * @static
     * @memberOf _
     * @category Function
     * @param {...Function} [funcs] Functions to invoke.
     * @returns {Function} Returns the new function.
     * @example
     *
     * function square(n) {
     *   return n * n;
     * }
     *
     * var addSquare = _.flow(_.add, square);
     * addSquare(1, 2);
     * // => 9
     */
    var flow = createFlow();

    /**
     * This method is like `_.flow` except that it creates a function that
     * invokes the provided functions from right to left.
     *
     * @static
     * @memberOf _
     * @alias backflow, compose
     * @category Function
     * @param {...Function} [funcs] Functions to invoke.
     * @returns {Function} Returns the new function.
     * @example
     *
     * function square(n) {
     *   return n * n;
     * }
     *
     * var addSquare = _.flowRight(square, _.add);
     * addSquare(1, 2);
     * // => 9
     */
    var flowRight = createFlow(true);

    /**
     * Creates a function that memoizes the result of `func`. If `resolver` is
     * provided it determines the cache key for storing the result based on the
     * arguments provided to the memoized function. By default, the first argument
     * provided to the memoized function is coerced to a string and used as the
     * cache key. The `func` is invoked with the `this` binding of the memoized
     * function.
     *
     * **Note:** The cache is exposed as the `cache` property on the memoized
     * function. Its creation may be customized by replacing the `_.memoize.Cache`
     * constructor with one whose instances implement the [`Map`](http://ecma-international.org/ecma-262/6.0/#sec-properties-of-the-map-prototype-object)
     * method interface of `get`, `has`, and `set`.
     *
     * @static
     * @memberOf _
     * @category Function
     * @param {Function} func The function to have its output memoized.
     * @param {Function} [resolver] The function to resolve the cache key.
     * @returns {Function} Returns the new memoizing function.
     * @example
     *
     * var upperCase = _.memoize(function(string) {
     *   return string.toUpperCase();
     * });
     *
     * upperCase('fred');
     * // => 'FRED'
     *
     * // modifying the result cache
     * upperCase.cache.set('fred', 'BARNEY');
     * upperCase('fred');
     * // => 'BARNEY'
     *
     * // replacing `_.memoize.Cache`
     * var object = { 'user': 'fred' };
     * var other = { 'user': 'barney' };
     * var identity = _.memoize(_.identity);
     *
     * identity(object);
     * // => { 'user': 'fred' }
     * identity(other);
     * // => { 'user': 'fred' }
     *
     * _.memoize.Cache = WeakMap;
     * var identity = _.memoize(_.identity);
     *
     * identity(object);
     * // => { 'user': 'fred' }
     * identity(other);
     * // => { 'user': 'barney' }
     */
    function memoize(func, resolver) {
      if (typeof func != 'function' || (resolver && typeof resolver != 'function')) {
        throw new TypeError(FUNC_ERROR_TEXT);
      }
      var memoized = function() {
        var args = arguments,
            key = resolver ? resolver.apply(this, args) : args[0],
            cache = memoized.cache;

        if (cache.has(key)) {
          return cache.get(key);
        }
        var result = func.apply(this, args);
        memoized.cache = cache.set(key, result);
        return result;
      };
      memoized.cache = new memoize.Cache;
      return memoized;
    }

    /**
     * Creates a function that runs each argument through a corresponding
     * transform function.
     *
     * @static
     * @memberOf _
     * @category Function
     * @param {Function} func The function to wrap.
     * @param {...(Function|Function[])} [transforms] The functions to transform
     * arguments, specified as individual functions or arrays of functions.
     * @returns {Function} Returns the new function.
     * @example
     *
     * function doubled(n) {
     *   return n * 2;
     * }
     *
     * function square(n) {
     *   return n * n;
     * }
     *
     * var modded = _.modArgs(function(x, y) {
     *   return [x, y];
     * }, square, doubled);
     *
     * modded(1, 2);
     * // => [1, 4]
     *
     * modded(5, 10);
     * // => [25, 20]
     */
    var modArgs = restParam(function(func, transforms) {
      transforms = baseFlatten(transforms);
      if (typeof func != 'function' || !arrayEvery(transforms, baseIsFunction)) {
        throw new TypeError(FUNC_ERROR_TEXT);
      }
      var length = transforms.length;
      return restParam(function(args) {
        var index = nativeMin(args.length, length);
        while (index--) {
          args[index] = transforms[index](args[index]);
        }
        return func.apply(this, args);
      });
    });

    /**
     * Creates a function that negates the result of the predicate `func`. The
     * `func` predicate is invoked with the `this` binding and arguments of the
     * created function.
     *
     * @static
     * @memberOf _
     * @category Function
     * @param {Function} predicate The predicate to negate.
     * @returns {Function} Returns the new function.
     * @example
     *
     * function isEven(n) {
     *   return n % 2 == 0;
     * }
     *
     * _.filter([1, 2, 3, 4, 5, 6], _.negate(isEven));
     * // => [1, 3, 5]
     */
    function negate(predicate) {
      if (typeof predicate != 'function') {
        throw new TypeError(FUNC_ERROR_TEXT);
      }
      return function() {
        return !predicate.apply(this, arguments);
      };
    }

    /**
     * Creates a function that is restricted to invoking `func` once. Repeat calls
     * to the function return the value of the first call. The `func` is invoked
     * with the `this` binding and arguments of the created function.
     *
     * @static
     * @memberOf _
     * @category Function
     * @param {Function} func The function to restrict.
     * @returns {Function} Returns the new restricted function.
     * @example
     *
     * var initialize = _.once(createApplication);
     * initialize();
     * initialize();
     * // `initialize` invokes `createApplication` once
     */
    function once(func) {
      return before(2, func);
    }

    /**
     * Creates a function that invokes `func` with `partial` arguments prepended
     * to those provided to the new function. This method is like `_.bind` except
     * it does **not** alter the `this` binding.
     *
     * The `_.partial.placeholder` value, which defaults to `_` in monolithic
     * builds, may be used as a placeholder for partially applied arguments.
     *
     * **Note:** This method does not set the "length" property of partially
     * applied functions.
     *
     * @static
     * @memberOf _
     * @category Function
     * @param {Function} func The function to partially apply arguments to.
     * @param {...*} [partials] The arguments to be partially applied.
     * @returns {Function} Returns the new partially applied function.
     * @example
     *
     * var greet = function(greeting, name) {
     *   return greeting + ' ' + name;
     * };
     *
     * var sayHelloTo = _.partial(greet, 'hello');
     * sayHelloTo('fred');
     * // => 'hello fred'
     *
     * // using placeholders
     * var greetFred = _.partial(greet, _, 'fred');
     * greetFred('hi');
     * // => 'hi fred'
     */
    var partial = createPartial(PARTIAL_FLAG);

    /**
     * This method is like `_.partial` except that partially applied arguments
     * are appended to those provided to the new function.
     *
     * The `_.partialRight.placeholder` value, which defaults to `_` in monolithic
     * builds, may be used as a placeholder for partially applied arguments.
     *
     * **Note:** This method does not set the "length" property of partially
     * applied functions.
     *
     * @static
     * @memberOf _
     * @category Function
     * @param {Function} func The function to partially apply arguments to.
     * @param {...*} [partials] The arguments to be partially applied.
     * @returns {Function} Returns the new partially applied function.
     * @example
     *
     * var greet = function(greeting, name) {
     *   return greeting + ' ' + name;
     * };
     *
     * var greetFred = _.partialRight(greet, 'fred');
     * greetFred('hi');
     * // => 'hi fred'
     *
     * // using placeholders
     * var sayHelloTo = _.partialRight(greet, 'hello', _);
     * sayHelloTo('fred');
     * // => 'hello fred'
     */
    var partialRight = createPartial(PARTIAL_RIGHT_FLAG);

    /**
     * Creates a function that invokes `func` with arguments arranged according
     * to the specified indexes where the argument value at the first index is
     * provided as the first argument, the argument value at the second index is
     * provided as the second argument, and so on.
     *
     * @static
     * @memberOf _
     * @category Function
     * @param {Function} func The function to rearrange arguments for.
     * @param {...(number|number[])} indexes The arranged argument indexes,
     *  specified as individual indexes or arrays of indexes.
     * @returns {Function} Returns the new function.
     * @example
     *
     * var rearged = _.rearg(function(a, b, c) {
     *   return [a, b, c];
     * }, 2, 0, 1);
     *
     * rearged('b', 'c', 'a')
     * // => ['a', 'b', 'c']
     *
     * var map = _.rearg(_.map, [1, 0]);
     * map(function(n) {
     *   return n * 3;
     * }, [1, 2, 3]);
     * // => [3, 6, 9]
     */
    var rearg = restParam(function(func, indexes) {
      return createWrapper(func, REARG_FLAG, undefined, undefined, undefined, baseFlatten(indexes));
    });

    /**
     * Creates a function that invokes `func` with the `this` binding of the
     * created function and arguments from `start` and beyond provided as an array.
     *
     * **Note:** This method is based on the [rest parameter](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/rest_parameters).
     *
     * @static
     * @memberOf _
     * @category Function
     * @param {Function} func The function to apply a rest parameter to.
     * @param {number} [start=func.length-1] The start position of the rest parameter.
     * @returns {Function} Returns the new function.
     * @example
     *
     * var say = _.restParam(function(what, names) {
     *   return what + ' ' + _.initial(names).join(', ') +
     *     (_.size(names) > 1 ? ', & ' : '') + _.last(names);
     * });
     *
     * say('hello', 'fred', 'barney', 'pebbles');
     * // => 'hello fred, barney, & pebbles'
     */
    function restParam(func, start) {
      if (typeof func != 'function') {
        throw new TypeError(FUNC_ERROR_TEXT);
      }
      start = nativeMax(start === undefined ? (func.length - 1) : (+start || 0), 0);
      return function() {
        var args = arguments,
            index = -1,
            length = nativeMax(args.length - start, 0),
            rest = Array(length);

        while (++index < length) {
          rest[index] = args[start + index];
        }
        switch (start) {
          case 0: return func.call(this, rest);
          case 1: return func.call(this, args[0], rest);
          case 2: return func.call(this, args[0], args[1], rest);
        }
        var otherArgs = Array(start + 1);
        index = -1;
        while (++index < start) {
          otherArgs[index] = args[index];
        }
        otherArgs[start] = rest;
        return func.apply(this, otherArgs);
      };
    }

    /**
     * Creates a function that invokes `func` with the `this` binding of the created
     * function and an array of arguments much like [`Function#apply`](https://es5.github.io/#x15.3.4.3).
     *
     * **Note:** This method is based on the [spread operator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator).
     *
     * @static
     * @memberOf _
     * @category Function
     * @param {Function} func The function to spread arguments over.
     * @returns {Function} Returns the new function.
     * @example
     *
     * var say = _.spread(function(who, what) {
     *   return who + ' says ' + what;
     * });
     *
     * say(['fred', 'hello']);
     * // => 'fred says hello'
     *
     * // with a Promise
     * var numbers = Promise.all([
     *   Promise.resolve(40),
     *   Promise.resolve(36)
     * ]);
     *
     * numbers.then(_.spread(function(x, y) {
     *   return x + y;
     * }));
     * // => a Promise of 76
     */
    function spread(func) {
      if (typeof func != 'function') {
        throw new TypeError(FUNC_ERROR_TEXT);
      }
      return function(array) {
        return func.apply(this, array);
      };
    }

    /**
     * Creates a throttled function that only invokes `func` at most once per
     * every `wait` milliseconds. The throttled function comes with a `cancel`
     * method to cancel delayed invocations. Provide an options object to indicate
     * that `func` should be invoked on the leading and/or trailing edge of the
     * `wait` timeout. Subsequent calls to the throttled function return the
     * result of the last `func` call.
     *
     * **Note:** If `leading` and `trailing` options are `true`, `func` is invoked
     * on the trailing edge of the timeout only if the the throttled function is
     * invoked more than once during the `wait` timeout.
     *
     * See [David Corbacho's article](http://drupalmotion.com/article/debounce-and-throttle-visual-explanation)
     * for details over the differences between `_.throttle` and `_.debounce`.
     *
     * @static
     * @memberOf _
     * @category Function
     * @param {Function} func The function to throttle.
     * @param {number} [wait=0] The number of milliseconds to throttle invocations to.
     * @param {Object} [options] The options object.
     * @param {boolean} [options.leading=true] Specify invoking on the leading
     *  edge of the timeout.
     * @param {boolean} [options.trailing=true] Specify invoking on the trailing
     *  edge of the timeout.
     * @returns {Function} Returns the new throttled function.
     * @example
     *
     * // avoid excessively updating the position while scrolling
     * jQuery(window).on('scroll', _.throttle(updatePosition, 100));
     *
     * // invoke `renewToken` when the click event is fired, but not more than once every 5 minutes
     * jQuery('.interactive').on('click', _.throttle(renewToken, 300000, {
     *   'trailing': false
     * }));
     *
     * // cancel a trailing throttled call
     * jQuery(window).on('popstate', throttled.cancel);
     */
    function throttle(func, wait, options) {
      var leading = true,
          trailing = true;

      if (typeof func != 'function') {
        throw new TypeError(FUNC_ERROR_TEXT);
      }
      if (options === false) {
        leading = false;
      } else if (isObject(options)) {
        leading = 'leading' in options ? !!options.leading : leading;
        trailing = 'trailing' in options ? !!options.trailing : trailing;
      }
      return debounce(func, wait, { 'leading': leading, 'maxWait': +wait, 'trailing': trailing });
    }

    /**
     * Creates a function that provides `value` to the wrapper function as its
     * first argument. Any additional arguments provided to the function are
     * appended to those provided to the wrapper function. The wrapper is invoked
     * with the `this` binding of the created function.
     *
     * @static
     * @memberOf _
     * @category Function
     * @param {*} value The value to wrap.
     * @param {Function} wrapper The wrapper function.
     * @returns {Function} Returns the new function.
     * @example
     *
     * var p = _.wrap(_.escape, function(func, text) {
     *   return '<p>' + func(text) + '</p>';
     * });
     *
     * p('fred, barney, & pebbles');
     * // => '<p>fred, barney, &amp; pebbles</p>'
     */
    function wrap(value, wrapper) {
      wrapper = wrapper == null ? identity : wrapper;
      return createWrapper(wrapper, PARTIAL_FLAG, undefined, [value], []);
    }

    /*------------------------------------------------------------------------*/

    /**
     * Creates a clone of `value`. If `isDeep` is `true` nested objects are cloned,
     * otherwise they are assigned by reference. If `customizer` is provided it is
     * invoked to produce the cloned values. If `customizer` returns `undefined`
     * cloning is handled by the method instead. The `customizer` is bound to
     * `thisArg` and invoked with two argument; (value [, index|key, object]).
     *
     * **Note:** This method is loosely based on the
     * [structured clone algorithm](http://www.w3.org/TR/html5/infrastructure.html#internal-structured-cloning-algorithm).
     * The enumerable properties of `arguments` objects and objects created by
     * constructors other than `Object` are cloned to plain `Object` objects. An
     * empty object is returned for uncloneable values such as functions, DOM nodes,
     * Maps, Sets, and WeakMaps.
     *
     * @static
     * @memberOf _
     * @category Lang
     * @param {*} value The value to clone.
     * @param {boolean} [isDeep] Specify a deep clone.
     * @param {Function} [customizer] The function to customize cloning values.
     * @param {*} [thisArg] The `this` binding of `customizer`.
     * @returns {*} Returns the cloned value.
     * @example
     *
     * var users = [
     *   { 'user': 'barney' },
     *   { 'user': 'fred' }
     * ];
     *
     * var shallow = _.clone(users);
     * shallow[0] === users[0];
     * // => true
     *
     * var deep = _.clone(users, true);
     * deep[0] === users[0];
     * // => false
     *
     * // using a customizer callback
     * var el = _.clone(document.body, function(value) {
     *   if (_.isElement(value)) {
     *     return value.cloneNode(false);
     *   }
     * });
     *
     * el === document.body
     * // => false
     * el.nodeName
     * // => BODY
     * el.childNodes.length;
     * // => 0
     */
    function clone(value, isDeep, customizer, thisArg) {
      if (isDeep && typeof isDeep != 'boolean' && isIterateeCall(value, isDeep, customizer)) {
        isDeep = false;
      }
      else if (typeof isDeep == 'function') {
        thisArg = customizer;
        customizer = isDeep;
        isDeep = false;
      }
      return typeof customizer == 'function'
        ? baseClone(value, isDeep, bindCallback(customizer, thisArg, 1))
        : baseClone(value, isDeep);
    }

    /**
     * Creates a deep clone of `value`. If `customizer` is provided it is invoked
     * to produce the cloned values. If `customizer` returns `undefined` cloning
     * is handled by the method instead. The `customizer` is bound to `thisArg`
     * and invoked with two argument; (value [, index|key, object]).
     *
     * **Note:** This method is loosely based on the
     * [structured clone algorithm](http://www.w3.org/TR/html5/infrastructure.html#internal-structured-cloning-algorithm).
     * The enumerable properties of `arguments` objects and objects created by
     * constructors other than `Object` are cloned to plain `Object` objects. An
     * empty object is returned for uncloneable values such as functions, DOM nodes,
     * Maps, Sets, and WeakMaps.
     *
     * @static
     * @memberOf _
     * @category Lang
     * @param {*} value The value to deep clone.
     * @param {Function} [customizer] The function to customize cloning values.
     * @param {*} [thisArg] The `this` binding of `customizer`.
     * @returns {*} Returns the deep cloned value.
     * @example
     *
     * var users = [
     *   { 'user': 'barney' },
     *   { 'user': 'fred' }
     * ];
     *
     * var deep = _.cloneDeep(users);
     * deep[0] === users[0];
     * // => false
     *
     * // using a customizer callback
     * var el = _.cloneDeep(document.body, function(value) {
     *   if (_.isElement(value)) {
     *     return value.cloneNode(true);
     *   }
     * });
     *
     * el === document.body
     * // => false
     * el.nodeName
     * // => BODY
     * el.childNodes.length;
     * // => 20
     */
    function cloneDeep(value, customizer, thisArg) {
      return typeof customizer == 'function'
        ? baseClone(value, true, bindCallback(customizer, thisArg, 1))
        : baseClone(value, true);
    }

    /**
     * Checks if `value` is greater than `other`.
     *
     * @static
     * @memberOf _
     * @category Lang
     * @param {*} value The value to compare.
     * @param {*} other The other value to compare.
     * @returns {boolean} Returns `true` if `value` is greater than `other`, else `false`.
     * @example
     *
     * _.gt(3, 1);
     * // => true
     *
     * _.gt(3, 3);
     * // => false
     *
     * _.gt(1, 3);
     * // => false
     */
    function gt(value, other) {
      return value > other;
    }

    /**
     * Checks if `value` is greater than or equal to `other`.
     *
     * @static
     * @memberOf _
     * @category Lang
     * @param {*} value The value to compare.
     * @param {*} other The other value to compare.
     * @returns {boolean} Returns `true` if `value` is greater than or equal to `other`, else `false`.
     * @example
     *
     * _.gte(3, 1);
     * // => true
     *
     * _.gte(3, 3);
     * // => true
     *
     * _.gte(1, 3);
     * // => false
     */
    function gte(value, other) {
      return value >= other;
    }

    /**
     * Checks if `value` is classified as an `arguments` object.
     *
     * @static
     * @memberOf _
     * @category Lang
     * @param {*} value The value to check.
     * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
     * @example
     *
     * _.isArguments(function() { return arguments; }());
     * // => true
     *
     * _.isArguments([1, 2, 3]);
     * // => false
     */
    function isArguments(value) {
      return isObjectLike(value) && isArrayLike(value) &&
        hasOwnProperty.call(value, 'callee') && !propertyIsEnumerable.call(value, 'callee');
    }

    /**
     * Checks if `value` is classified as an `Array` object.
     *
     * @static
     * @memberOf _
     * @category Lang
     * @param {*} value The value to check.
     * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
     * @example
     *
     * _.isArray([1, 2, 3]);
     * // => true
     *
     * _.isArray(function() { return arguments; }());
     * // => false
     */
    var isArray = nativeIsArray || function(value) {
      return isObjectLike(value) && isLength(value.length) && objToString.call(value) == arrayTag;
    };

    /**
     * Checks if `value` is classified as a boolean primitive or object.
     *
     * @static
     * @memberOf _
     * @category Lang
     * @param {*} value The value to check.
     * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
     * @example
     *
     * _.isBoolean(false);
     * // => true
     *
     * _.isBoolean(null);
     * // => false
     */
    function isBoolean(value) {
      return value === true || value === false || (isObjectLike(value) && objToString.call(value) == boolTag);
    }

    /**
     * Checks if `value` is classified as a `Date` object.
     *
     * @static
     * @memberOf _
     * @category Lang
     * @param {*} value The value to check.
     * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
     * @example
     *
     * _.isDate(new Date);
     * // => true
     *
     * _.isDate('Mon April 23 2012');
     * // => false
     */
    function isDate(value) {
      return isObjectLike(value) && objToString.call(value) == dateTag;
    }

    /**
     * Checks if `value` is a DOM element.
     *
     * @static
     * @memberOf _
     * @category Lang
     * @param {*} value The value to check.
     * @returns {boolean} Returns `true` if `value` is a DOM element, else `false`.
     * @example
     *
     * _.isElement(document.body);
     * // => true
     *
     * _.isElement('<body>');
     * // => false
     */
    function isElement(value) {
      return !!value && value.nodeType === 1 && isObjectLike(value) && !isPlainObject(value);
    }

    /**
     * Checks if `value` is empty. A value is considered empty unless it is an
     * `arguments` object, array, string, or jQuery-like collection with a length
     * greater than `0` or an object with own enumerable properties.
     *
     * @static
     * @memberOf _
     * @category Lang
     * @param {Array|Object|string} value The value to inspect.
     * @returns {boolean} Returns `true` if `value` is empty, else `false`.
     * @example
     *
     * _.isEmpty(null);
     * // => true
     *
     * _.isEmpty(true);
     * // => true
     *
     * _.isEmpty(1);
     * // => true
     *
     * _.isEmpty([1, 2, 3]);
     * // => false
     *
     * _.isEmpty({ 'a': 1 });
     * // => false
     */
    function isEmpty(value) {
      if (value == null) {
        return true;
      }
      if (isArrayLike(value) && (isArray(value) || isString(value) || isArguments(value) ||
          (isObjectLike(value) && isFunction(value.splice)))) {
        return !value.length;
      }
      return !keys(value).length;
    }

    /**
     * Performs a deep comparison between two values to determine if they are
     * equivalent. If `customizer` is provided it is invoked to compare values.
     * If `customizer` returns `undefined` comparisons are handled by the method
     * instead. The `customizer` is bound to `thisArg` and invoked with three
     * arguments: (value, other [, index|key]).
     *
     * **Note:** This method supports comparing arrays, booleans, `Date` objects,
     * numbers, `Object` objects, regexes, and strings. Objects are compared by
     * their own, not inherited, enumerable properties. Functions and DOM nodes
     * are **not** supported. Provide a customizer function to extend support
     * for comparing other values.
     *
     * @static
     * @memberOf _
     * @alias eq
     * @category Lang
     * @param {*} value The value to compare.
     * @param {*} other The other value to compare.
     * @param {Function} [customizer] The function to customize value comparisons.
     * @param {*} [thisArg] The `this` binding of `customizer`.
     * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
     * @example
     *
     * var object = { 'user': 'fred' };
     * var other = { 'user': 'fred' };
     *
     * object == other;
     * // => false
     *
     * _.isEqual(object, other);
     * // => true
     *
     * // using a customizer callback
     * var array = ['hello', 'goodbye'];
     * var other = ['hi', 'goodbye'];
     *
     * _.isEqual(array, other, function(value, other) {
     *   if (_.every([value, other], RegExp.prototype.test, /^h(?:i|ello)$/)) {
     *     return true;
     *   }
     * });
     * // => true
     */
    function isEqual(value, other, customizer, thisArg) {
      customizer = typeof customizer == 'function' ? bindCallback(customizer, thisArg, 3) : undefined;
      var result = customizer ? customizer(value, other) : undefined;
      return  result === undefined ? baseIsEqual(value, other, customizer) : !!result;
    }

    /**
     * Checks if `value` is an `Error`, `EvalError`, `RangeError`, `ReferenceError`,
     * `SyntaxError`, `TypeError`, or `URIError` object.
     *
     * @static
     * @memberOf _
     * @category Lang
     * @param {*} value The value to check.
     * @returns {boolean} Returns `true` if `value` is an error object, else `false`.
     * @example
     *
     * _.isError(new Error);
     * // => true
     *
     * _.isError(Error);
     * // => false
     */
    function isError(value) {
      return isObjectLike(value) && typeof value.message == 'string' && objToString.call(value) == errorTag;
    }

    /**
     * Checks if `value` is a finite primitive number.
     *
     * **Note:** This method is based on [`Number.isFinite`](http://ecma-international.org/ecma-262/6.0/#sec-number.isfinite).
     *
     * @static
     * @memberOf _
     * @category Lang
     * @param {*} value The value to check.
     * @returns {boolean} Returns `true` if `value` is a finite number, else `false`.
     * @example
     *
     * _.isFinite(10);
     * // => true
     *
     * _.isFinite('10');
     * // => false
     *
     * _.isFinite(true);
     * // => false
     *
     * _.isFinite(Object(10));
     * // => false
     *
     * _.isFinite(Infinity);
     * // => false
     */
    function isFinite(value) {
      return typeof value == 'number' && nativeIsFinite(value);
    }

    /**
     * Checks if `value` is classified as a `Function` object.
     *
     * @static
     * @memberOf _
     * @category Lang
     * @param {*} value The value to check.
     * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
     * @example
     *
     * _.isFunction(_);
     * // => true
     *
     * _.isFunction(/abc/);
     * // => false
     */
    function isFunction(value) {
      // The use of `Object#toString` avoids issues with the `typeof` operator
      // in older versions of Chrome and Safari which return 'function' for regexes
      // and Safari 8 equivalents which return 'object' for typed array constructors.
      return isObject(value) && objToString.call(value) == funcTag;
    }

    /**
     * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`.
     * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
     *
     * @static
     * @memberOf _
     * @category Lang
     * @param {*} value The value to check.
     * @returns {boolean} Returns `true` if `value` is an object, else `false`.
     * @example
     *
     * _.isObject({});
     * // => true
     *
     * _.isObject([1, 2, 3]);
     * // => true
     *
     * _.isObject(1);
     * // => false
     */
    function isObject(value) {
      // Avoid a V8 JIT bug in Chrome 19-20.
      // See https://code.google.com/p/v8/issues/detail?id=2291 for more details.
      var type = typeof value;
      return !!value && (type == 'object' || type == 'function');
    }

    /**
     * Performs a deep comparison between `object` and `source` to determine if
     * `object` contains equivalent property values. If `customizer` is provided
     * it is invoked to compare values. If `customizer` returns `undefined`
     * comparisons are handled by the method instead. The `customizer` is bound
     * to `thisArg` and invoked with three arguments: (value, other, index|key).
     *
     * **Note:** This method supports comparing properties of arrays, booleans,
     * `Date` objects, numbers, `Object` objects, regexes, and strings. Functions
     * and DOM nodes are **not** supported. Provide a customizer function to extend
     * support for comparing other values.
     *
     * @static
     * @memberOf _
     * @category Lang
     * @param {Object} object The object to inspect.
     * @param {Object} source The object of property values to match.
     * @param {Function} [customizer] The function to customize value comparisons.
     * @param {*} [thisArg] The `this` binding of `customizer`.
     * @returns {boolean} Returns `true` if `object` is a match, else `false`.
     * @example
     *
     * var object = { 'user': 'fred', 'age': 40 };
     *
     * _.isMatch(object, { 'age': 40 });
     * // => true
     *
     * _.isMatch(object, { 'age': 36 });
     * // => false
     *
     * // using a customizer callback
     * var object = { 'greeting': 'hello' };
     * var source = { 'greeting': 'hi' };
     *
     * _.isMatch(object, source, function(value, other) {
     *   return _.every([value, other], RegExp.prototype.test, /^h(?:i|ello)$/) || undefined;
     * });
     * // => true
     */
    function isMatch(object, source, customizer, thisArg) {
      customizer = typeof customizer == 'function' ? bindCallback(customizer, thisArg, 3) : undefined;
      return baseIsMatch(object, getMatchData(source), customizer);
    }

    /**
     * Checks if `value` is `NaN`.
     *
     * **Note:** This method is not the same as [`isNaN`](https://es5.github.io/#x15.1.2.4)
     * which returns `true` for `undefined` and other non-numeric values.
     *
     * @static
     * @memberOf _
     * @category Lang
     * @param {*} value The value to check.
     * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`.
     * @example
     *
     * _.isNaN(NaN);
     * // => true
     *
     * _.isNaN(new Number(NaN));
     * // => true
     *
     * isNaN(undefined);
     * // => true
     *
     * _.isNaN(undefined);
     * // => false
     */
    function isNaN(value) {
      // An `NaN` primitive is the only value that is not equal to itself.
      // Perform the `toStringTag` check first to avoid errors with some host objects in IE.
      return isNumber(value) && value != +value;
    }

    /**
     * Checks if `value` is a native function.
     *
     * @static
     * @memberOf _
     * @category Lang
     * @param {*} value The value to check.
     * @returns {boolean} Returns `true` if `value` is a native function, else `false`.
     * @example
     *
     * _.isNative(Array.prototype.push);
     * // => true
     *
     * _.isNative(_);
     * // => false
     */
    function isNative(value) {
      if (value == null) {
        return false;
      }
      if (isFunction(value)) {
        return reIsNative.test(fnToString.call(value));
      }
      return isObjectLike(value) && reIsHostCtor.test(value);
    }

    /**
     * Checks if `value` is `null`.
     *
     * @static
     * @memberOf _
     * @category Lang
     * @param {*} value The value to check.
     * @returns {boolean} Returns `true` if `value` is `null`, else `false`.
     * @example
     *
     * _.isNull(null);
     * // => true
     *
     * _.isNull(void 0);
     * // => false
     */
    function isNull(value) {
      return value === null;
    }

    /**
     * Checks if `value` is classified as a `Number` primitive or object.
     *
     * **Note:** To exclude `Infinity`, `-Infinity`, and `NaN`, which are classified
     * as numbers, use the `_.isFinite` method.
     *
     * @static
     * @memberOf _
     * @category Lang
     * @param {*} value The value to check.
     * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
     * @example
     *
     * _.isNumber(8.4);
     * // => true
     *
     * _.isNumber(NaN);
     * // => true
     *
     * _.isNumber('8.4');
     * // => false
     */
    function isNumber(value) {
      return typeof value == 'number' || (isObjectLike(value) && objToString.call(value) == numberTag);
    }

    /**
     * Checks if `value` is a plain object, that is, an object created by the
     * `Object` constructor or one with a `[[Prototype]]` of `null`.
     *
     * **Note:** This method assumes objects created by the `Object` constructor
     * have no inherited enumerable properties.
     *
     * @static
     * @memberOf _
     * @category Lang
     * @param {*} value The value to check.
     * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.
     * @example
     *
     * function Foo() {
     *   this.a = 1;
     * }
     *
     * _.isPlainObject(new Foo);
     * // => false
     *
     * _.isPlainObject([1, 2, 3]);
     * // => false
     *
     * _.isPlainObject({ 'x': 0, 'y': 0 });
     * // => true
     *
     * _.isPlainObject(Object.create(null));
     * // => true
     */
    function isPlainObject(value) {
      var Ctor;

      // Exit early for non `Object` objects.
      if (!(isObjectLike(value) && objToString.call(value) == objectTag && !isArguments(value)) ||
          (!hasOwnProperty.call(value, 'constructor') && (Ctor = value.constructor, typeof Ctor == 'function' && !(Ctor instanceof Ctor)))) {
        return false;
      }
      // IE < 9 iterates inherited properties before own properties. If the first
      // iterated property is an object's own property then there are no inherited
      // enumerable properties.
      var result;
      // In most environments an object's own properties are iterated before
      // its inherited properties. If the last iterated property is an object's
      // own property then there are no inherited enumerable properties.
      baseForIn(value, function(subValue, key) {
        result = key;
      });
      return result === undefined || hasOwnProperty.call(value, result);
    }

    /**
     * Checks if `value` is classified as a `RegExp` object.
     *
     * @static
     * @memberOf _
     * @category Lang
     * @param {*} value The value to check.
     * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
     * @example
     *
     * _.isRegExp(/abc/);
     * // => true
     *
     * _.isRegExp('/abc/');
     * // => false
     */
    function isRegExp(value) {
      return isObject(value) && objToString.call(value) == regexpTag;
    }

    /**
     * Checks if `value` is classified as a `String` primitive or object.
     *
     * @static
     * @memberOf _
     * @category Lang
     * @param {*} value The value to check.
     * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
     * @example
     *
     * _.isString('abc');
     * // => true
     *
     * _.isString(1);
     * // => false
     */
    function isString(value) {
      return typeof value == 'string' || (isObjectLike(value) && objToString.call(value) == stringTag);
    }

    /**
     * Checks if `value` is classified as a typed array.
     *
     * @static
     * @memberOf _
     * @category Lang
     * @param {*} value The value to check.
     * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
     * @example
     *
     * _.isTypedArray(new Uint8Array);
     * // => true
     *
     * _.isTypedArray([]);
     * // => false
     */
    function isTypedArray(value) {
      return isObjectLike(value) && isLength(value.length) && !!typedArrayTags[objToString.call(value)];
    }

    /**
     * Checks if `value` is `undefined`.
     *
     * @static
     * @memberOf _
     * @category Lang
     * @param {*} value The value to check.
     * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`.
     * @example
     *
     * _.isUndefined(void 0);
     * // => true
     *
     * _.isUndefined(null);
     * // => false
     */
    function isUndefined(value) {
      return value === undefined;
    }

    /**
     * Checks if `value` is less than `other`.
     *
     * @static
     * @memberOf _
     * @category Lang
     * @param {*} value The value to compare.
     * @param {*} other The other value to compare.
     * @returns {boolean} Returns `true` if `value` is less than `other`, else `false`.
     * @example
     *
     * _.lt(1, 3);
     * // => true
     *
     * _.lt(3, 3);
     * // => false
     *
     * _.lt(3, 1);
     * // => false
     */
    function lt(value, other) {
      return value < other;
    }

    /**
     * Checks if `value` is less than or equal to `other`.
     *
     * @static
     * @memberOf _
     * @category Lang
     * @param {*} value The value to compare.
     * @param {*} other The other value to compare.
     * @returns {boolean} Returns `true` if `value` is less than or equal to `other`, else `false`.
     * @example
     *
     * _.lte(1, 3);
     * // => true
     *
     * _.lte(3, 3);
     * // => true
     *
     * _.lte(3, 1);
     * // => false
     */
    function lte(value, other) {
      return value <= other;
    }

    /**
     * Converts `value` to an array.
     *
     * @static
     * @memberOf _
     * @category Lang
     * @param {*} value The value to convert.
     * @returns {Array} Returns the converted array.
     * @example
     *
     * (function() {
     *   return _.toArray(arguments).slice(1);
     * }(1, 2, 3));
     * // => [2, 3]
     */
    function toArray(value) {
      var length = value ? getLength(value) : 0;
      if (!isLength(length)) {
        return values(value);
      }
      if (!length) {
        return [];
      }
      return arrayCopy(value);
    }

    /**
     * Converts `value` to a plain object flattening inherited enumerable
     * properties of `value` to own properties of the plain object.
     *
     * @static
     * @memberOf _
     * @category Lang
     * @param {*} value The value to convert.
     * @returns {Object} Returns the converted plain object.
     * @example
     *
     * function Foo() {
     *   this.b = 2;
     * }
     *
     * Foo.prototype.c = 3;
     *
     * _.assign({ 'a': 1 }, new Foo);
     * // => { 'a': 1, 'b': 2 }
     *
     * _.assign({ 'a': 1 }, _.toPlainObject(new Foo));
     * // => { 'a': 1, 'b': 2, 'c': 3 }
     */
    function toPlainObject(value) {
      return baseCopy(value, keysIn(value));
    }

    /*------------------------------------------------------------------------*/

    /**
     * Recursively merges own enumerable properties of the source object(s), that
     * don't resolve to `undefined` into the destination object. Subsequent sources
     * overwrite property assignments of previous sources. If `customizer` is
     * provided it is invoked to produce the merged values of the destination and
     * source properties. If `customizer` returns `undefined` merging is handled
     * by the method instead. The `customizer` is bound to `thisArg` and invoked
     * with five arguments: (objectValue, sourceValue, key, object, source).
     *
     * @static
     * @memberOf _
     * @category Object
     * @param {Object} object The destination object.
     * @param {...Object} [sources] The source objects.
     * @param {Function} [customizer] The function to customize assigned values.
     * @param {*} [thisArg] The `this` binding of `customizer`.
     * @returns {Object} Returns `object`.
     * @example
     *
     * var users = {
     *   'data': [{ 'user': 'barney' }, { 'user': 'fred' }]
     * };
     *
     * var ages = {
     *   'data': [{ 'age': 36 }, { 'age': 40 }]
     * };
     *
     * _.merge(users, ages);
     * // => { 'data': [{ 'user': 'barney', 'age': 36 }, { 'user': 'fred', 'age': 40 }] }
     *
     * // using a customizer callback
     * var object = {
     *   'fruits': ['apple'],
     *   'vegetables': ['beet']
     * };
     *
     * var other = {
     *   'fruits': ['banana'],
     *   'vegetables': ['carrot']
     * };
     *
     * _.merge(object, other, function(a, b) {
     *   if (_.isArray(a)) {
     *     return a.concat(b);
     *   }
     * });
     * // => { 'fruits': ['apple', 'banana'], 'vegetables': ['beet', 'carrot'] }
     */
    var merge = createAssigner(baseMerge);

    /**
     * Assigns own enumerable properties of source object(s) to the destination
     * object. Subsequent sources overwrite property assignments of previous sources.
     * If `customizer` is provided it is invoked to produce the assigned values.
     * The `customizer` is bound to `thisArg` and invoked with five arguments:
     * (objectValue, sourceValue, key, object, source).
     *
     * **Note:** This method mutates `object` and is based on
     * [`Object.assign`](http://ecma-international.org/ecma-262/6.0/#sec-object.assign).
     *
     * @static
     * @memberOf _
     * @alias extend
     * @category Object
     * @param {Object} object The destination object.
     * @param {...Object} [sources] The source objects.
     * @param {Function} [customizer] The function to customize assigned values.
     * @param {*} [thisArg] The `this` binding of `customizer`.
     * @returns {Object} Returns `object`.
     * @example
     *
     * _.assign({ 'user': 'barney' }, { 'age': 40 }, { 'user': 'fred' });
     * // => { 'user': 'fred', 'age': 40 }
     *
     * // using a customizer callback
     * var defaults = _.partialRight(_.assign, function(value, other) {
     *   return _.isUndefined(value) ? other : value;
     * });
     *
     * defaults({ 'user': 'barney' }, { 'age': 36 }, { 'user': 'fred' });
     * // => { 'user': 'barney', 'age': 36 }
     */
    var assign = createAssigner(function(object, source, customizer) {
      return customizer
        ? assignWith(object, source, customizer)
        : baseAssign(object, source);
    });

    /**
     * Creates an object that inherits from the given `prototype` object. If a
     * `properties` object is provided its own enumerable properties are assigned
     * to the created object.
     *
     * @static
     * @memberOf _
     * @category Object
     * @param {Object} prototype The object to inherit from.
     * @param {Object} [properties] The properties to assign to the object.
     * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.
     * @returns {Object} Returns the new object.
     * @example
     *
     * function Shape() {
     *   this.x = 0;
     *   this.y = 0;
     * }
     *
     * function Circle() {
     *   Shape.call(this);
     * }
     *
     * Circle.prototype = _.create(Shape.prototype, {
     *   'constructor': Circle
     * });
     *
     * var circle = new Circle;
     * circle instanceof Circle;
     * // => true
     *
     * circle instanceof Shape;
     * // => true
     */
    function create(prototype, properties, guard) {
      var result = baseCreate(prototype);
      if (guard && isIterateeCall(prototype, properties, guard)) {
        properties = undefined;
      }
      return properties ? baseAssign(result, properties) : result;
    }

    /**
     * Assigns own enumerable properties of source object(s) to the destination
     * object for all destination properties that resolve to `undefined`. Once a
     * property is set, additional values of the same property are ignored.
     *
     * **Note:** This method mutates `object`.
     *
     * @static
     * @memberOf _
     * @category Object
     * @param {Object} object The destination object.
     * @param {...Object} [sources] The source objects.
     * @returns {Object} Returns `object`.
     * @example
     *
     * _.defaults({ 'user': 'barney' }, { 'age': 36 }, { 'user': 'fred' });
     * // => { 'user': 'barney', 'age': 36 }
     */
    var defaults = createDefaults(assign, assignDefaults);

    /**
     * This method is like `_.defaults` except that it recursively assigns
     * default properties.
     *
     * **Note:** This method mutates `object`.
     *
     * @static
     * @memberOf _
     * @category Object
     * @param {Object} object The destination object.
     * @param {...Object} [sources] The source objects.
     * @returns {Object} Returns `object`.
     * @example
     *
     * _.defaultsDeep({ 'user': { 'name': 'barney' } }, { 'user': { 'name': 'fred', 'age': 36 } });
     * // => { 'user': { 'name': 'barney', 'age': 36 } }
     *
     */
    var defaultsDeep = createDefaults(merge, mergeDefaults);

    /**
     * This method is like `_.find` except that it returns the key of the first
     * element `predicate` returns truthy for instead of the element itself.
     *
     * If a property name is provided for `predicate` the created `_.property`
     * style callback returns the property value of the given element.
     *
     * If a value is also provided for `thisArg` the created `_.matchesProperty`
     * style callback returns `true` for elements that have a matching property
     * value, else `false`.
     *
     * If an object is provided for `predicate` the created `_.matches` style
     * callback returns `true` for elements that have the properties of the given
     * object, else `false`.
     *
     * @static
     * @memberOf _
     * @category Object
     * @param {Object} object The object to search.
     * @param {Function|Object|string} [predicate=_.identity] The function invoked
     *  per iteration.
     * @param {*} [thisArg] The `this` binding of `predicate`.
     * @returns {string|undefined} Returns the key of the matched element, else `undefined`.
     * @example
     *
     * var users = {
     *   'barney':  { 'age': 36, 'active': true },
     *   'fred':    { 'age': 40, 'active': false },
     *   'pebbles': { 'age': 1,  'active': true }
     * };
     *
     * _.findKey(users, function(chr) {
     *   return chr.age < 40;
     * });
     * // => 'barney' (iteration order is not guaranteed)
     *
     * // using the `_.matches` callback shorthand
     * _.findKey(users, { 'age': 1, 'active': true });
     * // => 'pebbles'
     *
     * // using the `_.matchesProperty` callback shorthand
     * _.findKey(users, 'active', false);
     * // => 'fred'
     *
     * // using the `_.property` callback shorthand
     * _.findKey(users, 'active');
     * // => 'barney'
     */
    var findKey = createFindKey(baseForOwn);

    /**
     * This method is like `_.findKey` except that it iterates over elements of
     * a collection in the opposite order.
     *
     * If a property name is provided for `predicate` the created `_.property`
     * style callback returns the property value of the given element.
     *
     * If a value is also provided for `thisArg` the created `_.matchesProperty`
     * style callback returns `true` for elements that have a matching property
     * value, else `false`.
     *
     * If an object is provided for `predicate` the created `_.matches` style
     * callback returns `true` for elements that have the properties of the given
     * object, else `false`.
     *
     * @static
     * @memberOf _
     * @category Object
     * @param {Object} object The object to search.
     * @param {Function|Object|string} [predicate=_.identity] The function invoked
     *  per iteration.
     * @param {*} [thisArg] The `this` binding of `predicate`.
     * @returns {string|undefined} Returns the key of the matched element, else `undefined`.
     * @example
     *
     * var users = {
     *   'barney':  { 'age': 36, 'active': true },
     *   'fred':    { 'age': 40, 'active': false },
     *   'pebbles': { 'age': 1,  'active': true }
     * };
     *
     * _.findLastKey(users, function(chr) {
     *   return chr.age < 40;
     * });
     * // => returns `pebbles` assuming `_.findKey` returns `barney`
     *
     * // using the `_.matches` callback shorthand
     * _.findLastKey(users, { 'age': 36, 'active': true });
     * // => 'barney'
     *
     * // using the `_.matchesProperty` callback shorthand
     * _.findLastKey(users, 'active', false);
     * // => 'fred'
     *
     * // using the `_.property` callback shorthand
     * _.findLastKey(users, 'active');
     * // => 'pebbles'
     */
    var findLastKey = createFindKey(baseForOwnRight);

    /**
     * Iterates over own and inherited enumerable properties of an object invoking
     * `iteratee` for each property. The `iteratee` is bound to `thisArg` and invoked
     * with three arguments: (value, key, object). Iteratee functions may exit
     * iteration early by explicitly returning `false`.
     *
     * @static
     * @memberOf _
     * @category Object
     * @param {Object} object The object to iterate over.
     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
     * @param {*} [thisArg] The `this` binding of `iteratee`.
     * @returns {Object} Returns `object`.
     * @example
     *
     * function Foo() {
     *   this.a = 1;
     *   this.b = 2;
     * }
     *
     * Foo.prototype.c = 3;
     *
     * _.forIn(new Foo, function(value, key) {
     *   console.log(key);
     * });
     * // => logs 'a', 'b', and 'c' (iteration order is not guaranteed)
     */
    var forIn = createForIn(baseFor);

    /**
     * This method is like `_.forIn` except that it iterates over properties of
     * `object` in the opposite order.
     *
     * @static
     * @memberOf _
     * @category Object
     * @param {Object} object The object to iterate over.
     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
     * @param {*} [thisArg] The `this` binding of `iteratee`.
     * @returns {Object} Returns `object`.
     * @example
     *
     * function Foo() {
     *   this.a = 1;
     *   this.b = 2;
     * }
     *
     * Foo.prototype.c = 3;
     *
     * _.forInRight(new Foo, function(value, key) {
     *   console.log(key);
     * });
     * // => logs 'c', 'b', and 'a' assuming `_.forIn ` logs 'a', 'b', and 'c'
     */
    var forInRight = createForIn(baseForRight);

    /**
     * Iterates over own enumerable properties of an object invoking `iteratee`
     * for each property. The `iteratee` is bound to `thisArg` and invoked with
     * three arguments: (value, key, object). Iteratee functions may exit iteration
     * early by explicitly returning `false`.
     *
     * @static
     * @memberOf _
     * @category Object
     * @param {Object} object The object to iterate over.
     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
     * @param {*} [thisArg] The `this` binding of `iteratee`.
     * @returns {Object} Returns `object`.
     * @example
     *
     * function Foo() {
     *   this.a = 1;
     *   this.b = 2;
     * }
     *
     * Foo.prototype.c = 3;
     *
     * _.forOwn(new Foo, function(value, key) {
     *   console.log(key);
     * });
     * // => logs 'a' and 'b' (iteration order is not guaranteed)
     */
    var forOwn = createForOwn(baseForOwn);

    /**
     * This method is like `_.forOwn` except that it iterates over properties of
     * `object` in the opposite order.
     *
     * @static
     * @memberOf _
     * @category Object
     * @param {Object} object The object to iterate over.
     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
     * @param {*} [thisArg] The `this` binding of `iteratee`.
     * @returns {Object} Returns `object`.
     * @example
     *
     * function Foo() {
     *   this.a = 1;
     *   this.b = 2;
     * }
     *
     * Foo.prototype.c = 3;
     *
     * _.forOwnRight(new Foo, function(value, key) {
     *   console.log(key);
     * });
     * // => logs 'b' and 'a' assuming `_.forOwn` logs 'a' and 'b'
     */
    var forOwnRight = createForOwn(baseForOwnRight);

    /**
     * Creates an array of function property names from all enumerable properties,
     * own and inherited, of `object`.
     *
     * @static
     * @memberOf _
     * @alias methods
     * @category Object
     * @param {Object} object The object to inspect.
     * @returns {Array} Returns the new array of property names.
     * @example
     *
     * _.functions(_);
     * // => ['after', 'ary', 'assign', ...]
     */
    function functions(object) {
      return baseFunctions(object, keysIn(object));
    }

    /**
     * Gets the property value at `path` of `object`. If the resolved value is
     * `undefined` the `defaultValue` is used in its place.
     *
     * @static
     * @memberOf _
     * @category Object
     * @param {Object} object The object to query.
     * @param {Array|string} path The path of the property to get.
     * @param {*} [defaultValue] The value returned if the resolved value is `undefined`.
     * @returns {*} Returns the resolved value.
     * @example
     *
     * var object = { 'a': [{ 'b': { 'c': 3 } }] };
     *
     * _.get(object, 'a[0].b.c');
     * // => 3
     *
     * _.get(object, ['a', '0', 'b', 'c']);
     * // => 3
     *
     * _.get(object, 'a.b.c', 'default');
     * // => 'default'
     */
    function get(object, path, defaultValue) {
      var result = object == null ? undefined : baseGet(object, toPath(path), path + '');
      return result === undefined ? defaultValue : result;
    }

    /**
     * Checks if `path` is a direct property.
     *
     * @static
     * @memberOf _
     * @category Object
     * @param {Object} object The object to query.
     * @param {Array|string} path The path to check.
     * @returns {boolean} Returns `true` if `path` is a direct property, else `false`.
     * @example
     *
     * var object = { 'a': { 'b': { 'c': 3 } } };
     *
     * _.has(object, 'a');
     * // => true
     *
     * _.has(object, 'a.b.c');
     * // => true
     *
     * _.has(object, ['a', 'b', 'c']);
     * // => true
     */
    function has(object, path) {
      if (object == null) {
        return false;
      }
      var result = hasOwnProperty.call(object, path);
      if (!result && !isKey(path)) {
        path = toPath(path);
        object = path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1));
        if (object == null) {
          return false;
        }
        path = last(path);
        result = hasOwnProperty.call(object, path);
      }
      return result || (isLength(object.length) && isIndex(path, object.length) &&
        (isArray(object) || isArguments(object)));
    }

    /**
     * Creates an object composed of the inverted keys and values of `object`.
     * If `object` contains duplicate values, subsequent values overwrite property
     * assignments of previous values unless `multiValue` is `true`.
     *
     * @static
     * @memberOf _
     * @category Object
     * @param {Object} object The object to invert.
     * @param {boolean} [multiValue] Allow multiple values per key.
     * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.
     * @returns {Object} Returns the new inverted object.
     * @example
     *
     * var object = { 'a': 1, 'b': 2, 'c': 1 };
     *
     * _.invert(object);
     * // => { '1': 'c', '2': 'b' }
     *
     * // with `multiValue`
     * _.invert(object, true);
     * // => { '1': ['a', 'c'], '2': ['b'] }
     */
    function invert(object, multiValue, guard) {
      if (guard && isIterateeCall(object, multiValue, guard)) {
        multiValue = undefined;
      }
      var index = -1,
          props = keys(object),
          length = props.length,
          result = {};

      while (++index < length) {
        var key = props[index],
            value = object[key];

        if (multiValue) {
          if (hasOwnProperty.call(result, value)) {
            result[value].push(key);
          } else {
            result[value] = [key];
          }
        }
        else {
          result[value] = key;
        }
      }
      return result;
    }

    /**
     * Creates an array of the own enumerable property names of `object`.
     *
     * **Note:** Non-object values are coerced to objects. See the
     * [ES spec](http://ecma-international.org/ecma-262/6.0/#sec-object.keys)
     * for more details.
     *
     * @static
     * @memberOf _
     * @category Object
     * @param {Object} object The object to query.
     * @returns {Array} Returns the array of property names.
     * @example
     *
     * function Foo() {
     *   this.a = 1;
     *   this.b = 2;
     * }
     *
     * Foo.prototype.c = 3;
     *
     * _.keys(new Foo);
     * // => ['a', 'b'] (iteration order is not guaranteed)
     *
     * _.keys('hi');
     * // => ['0', '1']
     */
    var keys = !nativeKeys ? shimKeys : function(object) {
      var Ctor = object == null ? undefined : object.constructor;
      if ((typeof Ctor == 'function' && Ctor.prototype === object) ||
          (typeof object != 'function' && isArrayLike(object))) {
        return shimKeys(object);
      }
      return isObject(object) ? nativeKeys(object) : [];
    };

    /**
     * Creates an array of the own and inherited enumerable property names of `object`.
     *
     * **Note:** Non-object values are coerced to objects.
     *
     * @static
     * @memberOf _
     * @category Object
     * @param {Object} object The object to query.
     * @returns {Array} Returns the array of property names.
     * @example
     *
     * function Foo() {
     *   this.a = 1;
     *   this.b = 2;
     * }
     *
     * Foo.prototype.c = 3;
     *
     * _.keysIn(new Foo);
     * // => ['a', 'b', 'c'] (iteration order is not guaranteed)
     */
    function keysIn(object) {
      if (object == null) {
        return [];
      }
      if (!isObject(object)) {
        object = Object(object);
      }
      var length = object.length;
      length = (length && isLength(length) &&
        (isArray(object) || isArguments(object)) && length) || 0;

      var Ctor = object.constructor,
          index = -1,
          isProto = typeof Ctor == 'function' && Ctor.prototype === object,
          result = Array(length),
          skipIndexes = length > 0;

      while (++index < length) {
        result[index] = (index + '');
      }
      for (var key in object) {
        if (!(skipIndexes && isIndex(key, length)) &&
            !(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) {
          result.push(key);
        }
      }
      return result;
    }

    /**
     * The opposite of `_.mapValues`; this method creates an object with the
     * same values as `object` and keys generated by running each own enumerable
     * property of `object` through `iteratee`.
     *
     * @static
     * @memberOf _
     * @category Object
     * @param {Object} object The object to iterate over.
     * @param {Function|Object|string} [iteratee=_.identity] The function invoked
     *  per iteration.
     * @param {*} [thisArg] The `this` binding of `iteratee`.
     * @returns {Object} Returns the new mapped object.
     * @example
     *
     * _.mapKeys({ 'a': 1, 'b': 2 }, function(value, key) {
     *   return key + value;
     * });
     * // => { 'a1': 1, 'b2': 2 }
     */
    var mapKeys = createObjectMapper(true);

    /**
     * Creates an object with the same keys as `object` and values generated by
     * running each own enumerable property of `object` through `iteratee`. The
     * iteratee function is bound to `thisArg` and invoked with three arguments:
     * (value, key, object).
     *
     * If a property name is provided for `iteratee` the created `_.property`
     * style callback returns the property value of the given element.
     *
     * If a value is also provided for `thisArg` the created `_.matchesProperty`
     * style callback returns `true` for elements that have a matching property
     * value, else `false`.
     *
     * If an object is provided for `iteratee` the created `_.matches` style
     * callback returns `true` for elements that have the properties of the given
     * object, else `false`.
     *
     * @static
     * @memberOf _
     * @category Object
     * @param {Object} object The object to iterate over.
     * @param {Function|Object|string} [iteratee=_.identity] The function invoked
     *  per iteration.
     * @param {*} [thisArg] The `this` binding of `iteratee`.
     * @returns {Object} Returns the new mapped object.
     * @example
     *
     * _.mapValues({ 'a': 1, 'b': 2 }, function(n) {
     *   return n * 3;
     * });
     * // => { 'a': 3, 'b': 6 }
     *
     * var users = {
     *   'fred':    { 'user': 'fred',    'age': 40 },
     *   'pebbles': { 'user': 'pebbles', 'age': 1 }
     * };
     *
     * // using the `_.property` callback shorthand
     * _.mapValues(users, 'age');
     * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)
     */
    var mapValues = createObjectMapper();

    /**
     * The opposite of `_.pick`; this method creates an object composed of the
     * own and inherited enumerable properties of `object` that are not omitted.
     *
     * @static
     * @memberOf _
     * @category Object
     * @param {Object} object The source object.
     * @param {Function|...(string|string[])} [predicate] The function invoked per
     *  iteration or property names to omit, specified as individual property
     *  names or arrays of property names.
     * @param {*} [thisArg] The `this` binding of `predicate`.
     * @returns {Object} Returns the new object.
     * @example
     *
     * var object = { 'user': 'fred', 'age': 40 };
     *
     * _.omit(object, 'age');
     * // => { 'user': 'fred' }
     *
     * _.omit(object, _.isNumber);
     * // => { 'user': 'fred' }
     */
    var omit = restParam(function(object, props) {
      if (object == null) {
        return {};
      }
      if (typeof props[0] != 'function') {
        var props = arrayMap(baseFlatten(props), String);
        return pickByArray(object, baseDifference(keysIn(object), props));
      }
      var predicate = bindCallback(props[0], props[1], 3);
      return pickByCallback(object, function(value, key, object) {
        return !predicate(value, key, object);
      });
    });

    /**
     * Creates a two dimensional array of the key-value pairs for `object`,
     * e.g. `[[key1, value1], [key2, value2]]`.
     *
     * @static
     * @memberOf _
     * @category Object
     * @param {Object} object The object to query.
     * @returns {Array} Returns the new array of key-value pairs.
     * @example
     *
     * _.pairs({ 'barney': 36, 'fred': 40 });
     * // => [['barney', 36], ['fred', 40]] (iteration order is not guaranteed)
     */
    function pairs(object) {
      object = toObject(object);

      var index = -1,
          props = keys(object),
          length = props.length,
          result = Array(length);

      while (++index < length) {
        var key = props[index];
        result[index] = [key, object[key]];
      }
      return result;
    }

    /**
     * Creates an object composed of the picked `object` properties. Property
     * names may be specified as individual arguments or as arrays of property
     * names. If `predicate` is provided it is invoked for each property of `object`
     * picking the properties `predicate` returns truthy for. The predicate is
     * bound to `thisArg` and invoked with three arguments: (value, key, object).
     *
     * @static
     * @memberOf _
     * @category Object
     * @param {Object} object The source object.
     * @param {Function|...(string|string[])} [predicate] The function invoked per
     *  iteration or property names to pick, specified as individual property
     *  names or arrays of property names.
     * @param {*} [thisArg] The `this` binding of `predicate`.
     * @returns {Object} Returns the new object.
     * @example
     *
     * var object = { 'user': 'fred', 'age': 40 };
     *
     * _.pick(object, 'user');
     * // => { 'user': 'fred' }
     *
     * _.pick(object, _.isString);
     * // => { 'user': 'fred' }
     */
    var pick = restParam(function(object, props) {
      if (object == null) {
        return {};
      }
      return typeof props[0] == 'function'
        ? pickByCallback(object, bindCallback(props[0], props[1], 3))
        : pickByArray(object, baseFlatten(props));
    });

    /**
     * This method is like `_.get` except that if the resolved value is a function
     * it is invoked with the `this` binding of its parent object and its result
     * is returned.
     *
     * @static
     * @memberOf _
     * @category Object
     * @param {Object} object The object to query.
     * @param {Array|string} path The path of the property to resolve.
     * @param {*} [defaultValue] The value returned if the resolved value is `undefined`.
     * @returns {*} Returns the resolved value.
     * @example
     *
     * var object = { 'a': [{ 'b': { 'c1': 3, 'c2': _.constant(4) } }] };
     *
     * _.result(object, 'a[0].b.c1');
     * // => 3
     *
     * _.result(object, 'a[0].b.c2');
     * // => 4
     *
     * _.result(object, 'a.b.c', 'default');
     * // => 'default'
     *
     * _.result(object, 'a.b.c', _.constant('default'));
     * // => 'default'
     */
    function result(object, path, defaultValue) {
      var result = object == null ? undefined : object[path];
      if (result === undefined) {
        if (object != null && !isKey(path, object)) {
          path = toPath(path);
          object = path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1));
          result = object == null ? undefined : object[last(path)];
        }
        result = result === undefined ? defaultValue : result;
      }
      return isFunction(result) ? result.call(object) : result;
    }

    /**
     * Sets the property value of `path` on `object`. If a portion of `path`
     * does not exist it is created.
     *
     * @static
     * @memberOf _
     * @category Object
     * @param {Object} object The object to augment.
     * @param {Array|string} path The path of the property to set.
     * @param {*} value The value to set.
     * @returns {Object} Returns `object`.
     * @example
     *
     * var object = { 'a': [{ 'b': { 'c': 3 } }] };
     *
     * _.set(object, 'a[0].b.c', 4);
     * console.log(object.a[0].b.c);
     * // => 4
     *
     * _.set(object, 'x[0].y.z', 5);
     * console.log(object.x[0].y.z);
     * // => 5
     */
    function set(object, path, value) {
      if (object == null) {
        return object;
      }
      var pathKey = (path + '');
      path = (object[pathKey] != null || isKey(path, object)) ? [pathKey] : toPath(path);

      var index = -1,
          length = path.length,
          lastIndex = length - 1,
          nested = object;

      while (nested != null && ++index < length) {
        var key = path[index];
        if (isObject(nested)) {
          if (index == lastIndex) {
            nested[key] = value;
          } else if (nested[key] == null) {
            nested[key] = isIndex(path[index + 1]) ? [] : {};
          }
        }
        nested = nested[key];
      }
      return object;
    }

    /**
     * An alternative to `_.reduce`; this method transforms `object` to a new
     * `accumulator` object which is the result of running each of its own enumerable
     * properties through `iteratee`, with each invocation potentially mutating
     * the `accumulator` object. The `iteratee` is bound to `thisArg` and invoked
     * with four arguments: (accumulator, value, key, object). Iteratee functions
     * may exit iteration early by explicitly returning `false`.
     *
     * @static
     * @memberOf _
     * @category Object
     * @param {Array|Object} object The object to iterate over.
     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
     * @param {*} [accumulator] The custom accumulator value.
     * @param {*} [thisArg] The `this` binding of `iteratee`.
     * @returns {*} Returns the accumulated value.
     * @example
     *
     * _.transform([2, 3, 4], function(result, n) {
     *   result.push(n *= n);
     *   return n % 2 == 0;
     * });
     * // => [4, 9]
     *
     * _.transform({ 'a': 1, 'b': 2 }, function(result, n, key) {
     *   result[key] = n * 3;
     * });
     * // => { 'a': 3, 'b': 6 }
     */
    function transform(object, iteratee, accumulator, thisArg) {
      var isArr = isArray(object) || isTypedArray(object);
      iteratee = getCallback(iteratee, thisArg, 4);

      if (accumulator == null) {
        if (isArr || isObject(object)) {
          var Ctor = object.constructor;
          if (isArr) {
            accumulator = isArray(object) ? new Ctor : [];
          } else {
            accumulator = baseCreate(isFunction(Ctor) ? Ctor.prototype : undefined);
          }
        } else {
          accumulator = {};
        }
      }
      (isArr ? arrayEach : baseForOwn)(object, function(value, index, object) {
        return iteratee(accumulator, value, index, object);
      });
      return accumulator;
    }

    /**
     * Creates an array of the own enumerable property values of `object`.
     *
     * **Note:** Non-object values are coerced to objects.
     *
     * @static
     * @memberOf _
     * @category Object
     * @param {Object} object The object to query.
     * @returns {Array} Returns the array of property values.
     * @example
     *
     * function Foo() {
     *   this.a = 1;
     *   this.b = 2;
     * }
     *
     * Foo.prototype.c = 3;
     *
     * _.values(new Foo);
     * // => [1, 2] (iteration order is not guaranteed)
     *
     * _.values('hi');
     * // => ['h', 'i']
     */
    function values(object) {
      return baseValues(object, keys(object));
    }

    /**
     * Creates an array of the own and inherited enumerable property values
     * of `object`.
     *
     * **Note:** Non-object values are coerced to objects.
     *
     * @static
     * @memberOf _
     * @category Object
     * @param {Object} object The object to query.
     * @returns {Array} Returns the array of property values.
     * @example
     *
     * function Foo() {
     *   this.a = 1;
     *   this.b = 2;
     * }
     *
     * Foo.prototype.c = 3;
     *
     * _.valuesIn(new Foo);
     * // => [1, 2, 3] (iteration order is not guaranteed)
     */
    function valuesIn(object) {
      return baseValues(object, keysIn(object));
    }

    /*------------------------------------------------------------------------*/

    /**
     * Checks if `n` is between `start` and up to but not including, `end`. If
     * `end` is not specified it is set to `start` with `start` then set to `0`.
     *
     * @static
     * @memberOf _
     * @category Number
     * @param {number} n The number to check.
     * @param {number} [start=0] The start of the range.
     * @param {number} end The end of the range.
     * @returns {boolean} Returns `true` if `n` is in the range, else `false`.
     * @example
     *
     * _.inRange(3, 2, 4);
     * // => true
     *
     * _.inRange(4, 8);
     * // => true
     *
     * _.inRange(4, 2);
     * // => false
     *
     * _.inRange(2, 2);
     * // => false
     *
     * _.inRange(1.2, 2);
     * // => true
     *
     * _.inRange(5.2, 4);
     * // => false
     */
    function inRange(value, start, end) {
      start = +start || 0;
      if (end === undefined) {
        end = start;
        start = 0;
      } else {
        end = +end || 0;
      }
      return value >= nativeMin(start, end) && value < nativeMax(start, end);
    }

    /**
     * Produces a random number between `min` and `max` (inclusive). If only one
     * argument is provided a number between `0` and the given number is returned.
     * If `floating` is `true`, or either `min` or `max` are floats, a floating-point
     * number is returned instead of an integer.
     *
     * @static
     * @memberOf _
     * @category Number
     * @param {number} [min=0] The minimum possible value.
     * @param {number} [max=1] The maximum possible value.
     * @param {boolean} [floating] Specify returning a floating-point number.
     * @returns {number} Returns the random number.
     * @example
     *
     * _.random(0, 5);
     * // => an integer between 0 and 5
     *
     * _.random(5);
     * // => also an integer between 0 and 5
     *
     * _.random(5, true);
     * // => a floating-point number between 0 and 5
     *
     * _.random(1.2, 5.2);
     * // => a floating-point number between 1.2 and 5.2
     */
    function random(min, max, floating) {
      if (floating && isIterateeCall(min, max, floating)) {
        max = floating = undefined;
      }
      var noMin = min == null,
          noMax = max == null;

      if (floating == null) {
        if (noMax && typeof min == 'boolean') {
          floating = min;
          min = 1;
        }
        else if (typeof max == 'boolean') {
          floating = max;
          noMax = true;
        }
      }
      if (noMin && noMax) {
        max = 1;
        noMax = false;
      }
      min = +min || 0;
      if (noMax) {
        max = min;
        min = 0;
      } else {
        max = +max || 0;
      }
      if (floating || min % 1 || max % 1) {
        var rand = nativeRandom();
        return nativeMin(min + (rand * (max - min + parseFloat('1e-' + ((rand + '').length - 1)))), max);
      }
      return baseRandom(min, max);
    }

    /*------------------------------------------------------------------------*/

    /**
     * Converts `string` to [camel case](https://en.wikipedia.org/wiki/CamelCase).
     *
     * @static
     * @memberOf _
     * @category String
     * @param {string} [string=''] The string to convert.
     * @returns {string} Returns the camel cased string.
     * @example
     *
     * _.camelCase('Foo Bar');
     * // => 'fooBar'
     *
     * _.camelCase('--foo-bar');
     * // => 'fooBar'
     *
     * _.camelCase('__foo_bar__');
     * // => 'fooBar'
     */
    var camelCase = createCompounder(function(result, word, index) {
      word = word.toLowerCase();
      return result + (index ? (word.charAt(0).toUpperCase() + word.slice(1)) : word);
    });

    /**
     * Capitalizes the first character of `string`.
     *
     * @static
     * @memberOf _
     * @category String
     * @param {string} [string=''] The string to capitalize.
     * @returns {string} Returns the capitalized string.
     * @example
     *
     * _.capitalize('fred');
     * // => 'Fred'
     */
    function capitalize(string) {
      string = baseToString(string);
      return string && (string.charAt(0).toUpperCase() + string.slice(1));
    }

    /**
     * Deburrs `string` by converting [latin-1 supplementary letters](https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table)
     * to basic latin letters and removing [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks).
     *
     * @static
     * @memberOf _
     * @category String
     * @param {string} [string=''] The string to deburr.
     * @returns {string} Returns the deburred string.
     * @example
     *
     * _.deburr('déjà vu');
     * // => 'deja vu'
     */
    function deburr(string) {
      string = baseToString(string);
      return string && string.replace(reLatin1, deburrLetter).replace(reComboMark, '');
    }

    /**
     * Checks if `string` ends with the given target string.
     *
     * @static
     * @memberOf _
     * @category String
     * @param {string} [string=''] The string to search.
     * @param {string} [target] The string to search for.
     * @param {number} [position=string.length] The position to search from.
     * @returns {boolean} Returns `true` if `string` ends with `target`, else `false`.
     * @example
     *
     * _.endsWith('abc', 'c');
     * // => true
     *
     * _.endsWith('abc', 'b');
     * // => false
     *
     * _.endsWith('abc', 'b', 2);
     * // => true
     */
    function endsWith(string, target, position) {
      string = baseToString(string);
      target = (target + '');

      var length = string.length;
      position = position === undefined
        ? length
        : nativeMin(position < 0 ? 0 : (+position || 0), length);

      position -= target.length;
      return position >= 0 && string.indexOf(target, position) == position;
    }

    /**
     * Converts the characters "&", "<", ">", '"', "'", and "\`", in `string` to
     * their corresponding HTML entities.
     *
     * **Note:** No other characters are escaped. To escape additional characters
     * use a third-party library like [_he_](https://mths.be/he).
     *
     * Though the ">" character is escaped for symmetry, characters like
     * ">" and "/" don't need escaping in HTML and have no special meaning
     * unless they're part of a tag or unquoted attribute value.
     * See [Mathias Bynens's article](https://mathiasbynens.be/notes/ambiguous-ampersands)
     * (under "semi-related fun fact") for more details.
     *
     * Backticks are escaped because in Internet Explorer < 9, they can break out
     * of attribute values or HTML comments. See [#59](https://html5sec.org/#59),
     * [#102](https://html5sec.org/#102), [#108](https://html5sec.org/#108), and
     * [#133](https://html5sec.org/#133) of the [HTML5 Security Cheatsheet](https://html5sec.org/)
     * for more details.
     *
     * When working with HTML you should always [quote attribute values](http://wonko.com/post/html-escaping)
     * to reduce XSS vectors.
     *
     * @static
     * @memberOf _
     * @category String
     * @param {string} [string=''] The string to escape.
     * @returns {string} Returns the escaped string.
     * @example
     *
     * _.escape('fred, barney, & pebbles');
     * // => 'fred, barney, &amp; pebbles'
     */
    function escape(string) {
      // Reset `lastIndex` because in IE < 9 `String#replace` does not.
      string = baseToString(string);
      return (string && reHasUnescapedHtml.test(string))
        ? string.replace(reUnescapedHtml, escapeHtmlChar)
        : string;
    }

    /**
     * Escapes the `RegExp` special characters "\", "/", "^", "$", ".", "|", "?",
     * "*", "+", "(", ")", "[", "]", "{" and "}" in `string`.
     *
     * @static
     * @memberOf _
     * @category String
     * @param {string} [string=''] The string to escape.
     * @returns {string} Returns the escaped string.
     * @example
     *
     * _.escapeRegExp('[lodash](https://lodash.com/)');
     * // => '\[lodash\]\(https:\/\/lodash\.com\/\)'
     */
    function escapeRegExp(string) {
      string = baseToString(string);
      return (string && reHasRegExpChars.test(string))
        ? string.replace(reRegExpChars, escapeRegExpChar)
        : (string || '(?:)');
    }

    /**
     * Converts `string` to [kebab case](https://en.wikipedia.org/wiki/Letter_case#Special_case_styles).
     *
     * @static
     * @memberOf _
     * @category String
     * @param {string} [string=''] The string to convert.
     * @returns {string} Returns the kebab cased string.
     * @example
     *
     * _.kebabCase('Foo Bar');
     * // => 'foo-bar'
     *
     * _.kebabCase('fooBar');
     * // => 'foo-bar'
     *
     * _.kebabCase('__foo_bar__');
     * // => 'foo-bar'
     */
    var kebabCase = createCompounder(function(result, word, index) {
      return result + (index ? '-' : '') + word.toLowerCase();
    });

    /**
     * Pads `string` on the left and right sides if it's shorter than `length`.
     * Padding characters are truncated if they can't be evenly divided by `length`.
     *
     * @static
     * @memberOf _
     * @category String
     * @param {string} [string=''] The string to pad.
     * @param {number} [length=0] The padding length.
     * @param {string} [chars=' '] The string used as padding.
     * @returns {string} Returns the padded string.
     * @example
     *
     * _.pad('abc', 8);
     * // => '  abc   '
     *
     * _.pad('abc', 8, '_-');
     * // => '_-abc_-_'
     *
     * _.pad('abc', 3);
     * // => 'abc'
     */
    function pad(string, length, chars) {
      string = baseToString(string);
      length = +length;

      var strLength = string.length;
      if (strLength >= length || !nativeIsFinite(length)) {
        return string;
      }
      var mid = (length - strLength) / 2,
          leftLength = nativeFloor(mid),
          rightLength = nativeCeil(mid);

      chars = createPadding('', rightLength, chars);
      return chars.slice(0, leftLength) + string + chars;
    }

    /**
     * Pads `string` on the left side if it's shorter than `length`. Padding
     * characters are truncated if they exceed `length`.
     *
     * @static
     * @memberOf _
     * @category String
     * @param {string} [string=''] The string to pad.
     * @param {number} [length=0] The padding length.
     * @param {string} [chars=' '] The string used as padding.
     * @returns {string} Returns the padded string.
     * @example
     *
     * _.padLeft('abc', 6);
     * // => '   abc'
     *
     * _.padLeft('abc', 6, '_-');
     * // => '_-_abc'
     *
     * _.padLeft('abc', 3);
     * // => 'abc'
     */
    var padLeft = createPadDir();

    /**
     * Pads `string` on the right side if it's shorter than `length`. Padding
     * characters are truncated if they exceed `length`.
     *
     * @static
     * @memberOf _
     * @category String
     * @param {string} [string=''] The string to pad.
     * @param {number} [length=0] The padding length.
     * @param {string} [chars=' '] The string used as padding.
     * @returns {string} Returns the padded string.
     * @example
     *
     * _.padRight('abc', 6);
     * // => 'abc   '
     *
     * _.padRight('abc', 6, '_-');
     * // => 'abc_-_'
     *
     * _.padRight('abc', 3);
     * // => 'abc'
     */
    var padRight = createPadDir(true);

    /**
     * Converts `string` to an integer of the specified radix. If `radix` is
     * `undefined` or `0`, a `radix` of `10` is used unless `value` is a hexadecimal,
     * in which case a `radix` of `16` is used.
     *
     * **Note:** This method aligns with the [ES5 implementation](https://es5.github.io/#E)
     * of `parseInt`.
     *
     * @static
     * @memberOf _
     * @category String
     * @param {string} string The string to convert.
     * @param {number} [radix] The radix to interpret `value` by.
     * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.
     * @returns {number} Returns the converted integer.
     * @example
     *
     * _.parseInt('08');
     * // => 8
     *
     * _.map(['6', '08', '10'], _.parseInt);
     * // => [6, 8, 10]
     */
    function parseInt(string, radix, guard) {
      // Firefox < 21 and Opera < 15 follow ES3 for `parseInt`.
      // Chrome fails to trim leading <BOM> whitespace characters.
      // See https://code.google.com/p/v8/issues/detail?id=3109 for more details.
      if (guard ? isIterateeCall(string, radix, guard) : radix == null) {
        radix = 0;
      } else if (radix) {
        radix = +radix;
      }
      string = trim(string);
      return nativeParseInt(string, radix || (reHasHexPrefix.test(string) ? 16 : 10));
    }

    /**
     * Repeats the given string `n` times.
     *
     * @static
     * @memberOf _
     * @category String
     * @param {string} [string=''] The string to repeat.
     * @param {number} [n=0] The number of times to repeat the string.
     * @returns {string} Returns the repeated string.
     * @example
     *
     * _.repeat('*', 3);
     * // => '***'
     *
     * _.repeat('abc', 2);
     * // => 'abcabc'
     *
     * _.repeat('abc', 0);
     * // => ''
     */
    function repeat(string, n) {
      var result = '';
      string = baseToString(string);
      n = +n;
      if (n < 1 || !string || !nativeIsFinite(n)) {
        return result;
      }
      // Leverage the exponentiation by squaring algorithm for a faster repeat.
      // See https://en.wikipedia.org/wiki/Exponentiation_by_squaring for more details.
      do {
        if (n % 2) {
          result += string;
        }
        n = nativeFloor(n / 2);
        string += string;
      } while (n);

      return result;
    }

    /**
     * Converts `string` to [snake case](https://en.wikipedia.org/wiki/Snake_case).
     *
     * @static
     * @memberOf _
     * @category String
     * @param {string} [string=''] The string to convert.
     * @returns {string} Returns the snake cased string.
     * @example
     *
     * _.snakeCase('Foo Bar');
     * // => 'foo_bar'
     *
     * _.snakeCase('fooBar');
     * // => 'foo_bar'
     *
     * _.snakeCase('--foo-bar');
     * // => 'foo_bar'
     */
    var snakeCase = createCompounder(function(result, word, index) {
      return result + (index ? '_' : '') + word.toLowerCase();
    });

    /**
     * Converts `string` to [start case](https://en.wikipedia.org/wiki/Letter_case#Stylistic_or_specialised_usage).
     *
     * @static
     * @memberOf _
     * @category String
     * @param {string} [string=''] The string to convert.
     * @returns {string} Returns the start cased string.
     * @example
     *
     * _.startCase('--foo-bar');
     * // => 'Foo Bar'
     *
     * _.startCase('fooBar');
     * // => 'Foo Bar'
     *
     * _.startCase('__foo_bar__');
     * // => 'Foo Bar'
     */
    var startCase = createCompounder(function(result, word, index) {
      return result + (index ? ' ' : '') + (word.charAt(0).toUpperCase() + word.slice(1));
    });

    /**
     * Checks if `string` starts with the given target string.
     *
     * @static
     * @memberOf _
     * @category String
     * @param {string} [string=''] The string to search.
     * @param {string} [target] The string to search for.
     * @param {number} [position=0] The position to search from.
     * @returns {boolean} Returns `true` if `string` starts with `target`, else `false`.
     * @example
     *
     * _.startsWith('abc', 'a');
     * // => true
     *
     * _.startsWith('abc', 'b');
     * // => false
     *
     * _.startsWith('abc', 'b', 1);
     * // => true
     */
    function startsWith(string, target, position) {
      string = baseToString(string);
      position = position == null
        ? 0
        : nativeMin(position < 0 ? 0 : (+position || 0), string.length);

      return string.lastIndexOf(target, position) == position;
    }

    /**
     * Creates a compiled template function that can interpolate data properties
     * in "interpolate" delimiters, HTML-escape interpolated data properties in
     * "escape" delimiters, and execute JavaScript in "evaluate" delimiters. Data
     * properties may be accessed as free variables in the template. If a setting
     * object is provided it takes precedence over `_.templateSettings` values.
     *
     * **Note:** In the development build `_.template` utilizes
     * [sourceURLs](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl)
     * for easier debugging.
     *
     * For more information on precompiling templates see
     * [lodash's custom builds documentation](https://lodash.com/custom-builds).
     *
     * For more information on Chrome extension sandboxes see
     * [Chrome's extensions documentation](https://developer.chrome.com/extensions/sandboxingEval).
     *
     * @static
     * @memberOf _
     * @category String
     * @param {string} [string=''] The template string.
     * @param {Object} [options] The options object.
     * @param {RegExp} [options.escape] The HTML "escape" delimiter.
     * @param {RegExp} [options.evaluate] The "evaluate" delimiter.
     * @param {Object} [options.imports] An object to import into the template as free variables.
     * @param {RegExp} [options.interpolate] The "interpolate" delimiter.
     * @param {string} [options.sourceURL] The sourceURL of the template's compiled source.
     * @param {string} [options.variable] The data object variable name.
     * @param- {Object} [otherOptions] Enables the legacy `options` param signature.
     * @returns {Function} Returns the compiled template function.
     * @example
     *
     * // using the "interpolate" delimiter to create a compiled template
     * var compiled = _.template('hello <%= user %>!');
     * compiled({ 'user': 'fred' });
     * // => 'hello fred!'
     *
     * // using the HTML "escape" delimiter to escape data property values
     * var compiled = _.template('<b><%- value %></b>');
     * compiled({ 'value': '<script>' });
     * // => '<b>&lt;script&gt;</b>'
     *
     * // using the "evaluate" delimiter to execute JavaScript and generate HTML
     * var compiled = _.template('<% _.forEach(users, function(user) { %><li><%- user %></li><% }); %>');
     * compiled({ 'users': ['fred', 'barney'] });
     * // => '<li>fred</li><li>barney</li>'
     *
     * // using the internal `print` function in "evaluate" delimiters
     * var compiled = _.template('<% print("hello " + user); %>!');
     * compiled({ 'user': 'barney' });
     * // => 'hello barney!'
     *
     * // using the ES delimiter as an alternative to the default "interpolate" delimiter
     * var compiled = _.template('hello ${ user }!');
     * compiled({ 'user': 'pebbles' });
     * // => 'hello pebbles!'
     *
     * // using custom template delimiters
     * _.templateSettings.interpolate = /{{([\s\S]+?)}}/g;
     * var compiled = _.template('hello {{ user }}!');
     * compiled({ 'user': 'mustache' });
     * // => 'hello mustache!'
     *
     * // using backslashes to treat delimiters as plain text
     * var compiled = _.template('<%= "\\<%- value %\\>" %>');
     * compiled({ 'value': 'ignored' });
     * // => '<%- value %>'
     *
     * // using the `imports` option to import `jQuery` as `jq`
     * var text = '<% jq.each(users, function(user) { %><li><%- user %></li><% }); %>';
     * var compiled = _.template(text, { 'imports': { 'jq': jQuery } });
     * compiled({ 'users': ['fred', 'barney'] });
     * // => '<li>fred</li><li>barney</li>'
     *
     * // using the `sourceURL` option to specify a custom sourceURL for the template
     * var compiled = _.template('hello <%= user %>!', { 'sourceURL': '/basic/greeting.jst' });
     * compiled(data);
     * // => find the source of "greeting.jst" under the Sources tab or Resources panel of the web inspector
     *
     * // using the `variable` option to ensure a with-statement isn't used in the compiled template
     * var compiled = _.template('hi <%= data.user %>!', { 'variable': 'data' });
     * compiled.source;
     * // => function(data) {
     * //   var __t, __p = '';
     * //   __p += 'hi ' + ((__t = ( data.user )) == null ? '' : __t) + '!';
     * //   return __p;
     * // }
     *
     * // using the `source` property to inline compiled templates for meaningful
     * // line numbers in error messages and a stack trace
     * fs.writeFileSync(path.join(cwd, 'jst.js'), '\
     *   var JST = {\
     *     "main": ' + _.template(mainText).source + '\
     *   };\
     * ');
     */
    function template(string, options, otherOptions) {
      // Based on John Resig's `tmpl` implementation (http://ejohn.org/blog/javascript-micro-templating/)
      // and Laura Doktorova's doT.js (https://github.com/olado/doT).
      var settings = lodash.templateSettings;

      if (otherOptions && isIterateeCall(string, options, otherOptions)) {
        options = otherOptions = undefined;
      }
      string = baseToString(string);
      options = assignWith(baseAssign({}, otherOptions || options), settings, assignOwnDefaults);

      var imports = assignWith(baseAssign({}, options.imports), settings.imports, assignOwnDefaults),
          importsKeys = keys(imports),
          importsValues = baseValues(imports, importsKeys);

      var isEscaping,
          isEvaluating,
          index = 0,
          interpolate = options.interpolate || reNoMatch,
          source = "__p += '";

      // Compile the regexp to match each delimiter.
      var reDelimiters = RegExp(
        (options.escape || reNoMatch).source + '|' +
        interpolate.source + '|' +
        (interpolate === reInterpolate ? reEsTemplate : reNoMatch).source + '|' +
        (options.evaluate || reNoMatch).source + '|$'
      , 'g');

      // Use a sourceURL for easier debugging.
      var sourceURL = '//# sourceURL=' +
        ('sourceURL' in options
          ? options.sourceURL
          : ('lodash.templateSources[' + (++templateCounter) + ']')
        ) + '\n';

      string.replace(reDelimiters, function(match, escapeValue, interpolateValue, esTemplateValue, evaluateValue, offset) {
        interpolateValue || (interpolateValue = esTemplateValue);

        // Escape characters that can't be included in string literals.
        source += string.slice(index, offset).replace(reUnescapedString, escapeStringChar);

        // Replace delimiters with snippets.
        if (escapeValue) {
          isEscaping = true;
          source += "' +\n__e(" + escapeValue + ") +\n'";
        }
        if (evaluateValue) {
          isEvaluating = true;
          source += "';\n" + evaluateValue + ";\n__p += '";
        }
        if (interpolateValue) {
          source += "' +\n((__t = (" + interpolateValue + ")) == null ? '' : __t) +\n'";
        }
        index = offset + match.length;

        // The JS engine embedded in Adobe products requires returning the `match`
        // string in order to produce the correct `offset` value.
        return match;
      });

      source += "';\n";

      // If `variable` is not specified wrap a with-statement around the generated
      // code to add the data object to the top of the scope chain.
      var variable = options.variable;
      if (!variable) {
        source = 'with (obj) {\n' + source + '\n}\n';
      }
      // Cleanup code by stripping empty strings.
      source = (isEvaluating ? source.replace(reEmptyStringLeading, '') : source)
        .replace(reEmptyStringMiddle, '$1')
        .replace(reEmptyStringTrailing, '$1;');

      // Frame code as the function body.
      source = 'function(' + (variable || 'obj') + ') {\n' +
        (variable
          ? ''
          : 'obj || (obj = {});\n'
        ) +
        "var __t, __p = ''" +
        (isEscaping
           ? ', __e = _.escape'
           : ''
        ) +
        (isEvaluating
          ? ', __j = Array.prototype.join;\n' +
            "function print() { __p += __j.call(arguments, '') }\n"
          : ';\n'
        ) +
        source +
        'return __p\n}';

      var result = attempt(function() {
        return Function(importsKeys, sourceURL + 'return ' + source).apply(undefined, importsValues);
      });

      // Provide the compiled function's source by its `toString` method or
      // the `source` property as a convenience for inlining compiled templates.
      result.source = source;
      if (isError(result)) {
        throw result;
      }
      return result;
    }

    /**
     * Removes leading and trailing whitespace or specified characters from `string`.
     *
     * @static
     * @memberOf _
     * @category String
     * @param {string} [string=''] The string to trim.
     * @param {string} [chars=whitespace] The characters to trim.
     * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.
     * @returns {string} Returns the trimmed string.
     * @example
     *
     * _.trim('  abc  ');
     * // => 'abc'
     *
     * _.trim('-_-abc-_-', '_-');
     * // => 'abc'
     *
     * _.map(['  foo  ', '  bar  '], _.trim);
     * // => ['foo', 'bar']
     */
    function trim(string, chars, guard) {
      var value = string;
      string = baseToString(string);
      if (!string) {
        return string;
      }
      if (guard ? isIterateeCall(value, chars, guard) : chars == null) {
        return string.slice(trimmedLeftIndex(string), trimmedRightIndex(string) + 1);
      }
      chars = (chars + '');
      return string.slice(charsLeftIndex(string, chars), charsRightIndex(string, chars) + 1);
    }

    /**
     * Removes leading whitespace or specified characters from `string`.
     *
     * @static
     * @memberOf _
     * @category String
     * @param {string} [string=''] The string to trim.
     * @param {string} [chars=whitespace] The characters to trim.
     * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.
     * @returns {string} Returns the trimmed string.
     * @example
     *
     * _.trimLeft('  abc  ');
     * // => 'abc  '
     *
     * _.trimLeft('-_-abc-_-', '_-');
     * // => 'abc-_-'
     */
    function trimLeft(string, chars, guard) {
      var value = string;
      string = baseToString(string);
      if (!string) {
        return string;
      }
      if (guard ? isIterateeCall(value, chars, guard) : chars == null) {
        return string.slice(trimmedLeftIndex(string));
      }
      return string.slice(charsLeftIndex(string, (chars + '')));
    }

    /**
     * Removes trailing whitespace or specified characters from `string`.
     *
     * @static
     * @memberOf _
     * @category String
     * @param {string} [string=''] The string to trim.
     * @param {string} [chars=whitespace] The characters to trim.
     * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.
     * @returns {string} Returns the trimmed string.
     * @example
     *
     * _.trimRight('  abc  ');
     * // => '  abc'
     *
     * _.trimRight('-_-abc-_-', '_-');
     * // => '-_-abc'
     */
    function trimRight(string, chars, guard) {
      var value = string;
      string = baseToString(string);
      if (!string) {
        return string;
      }
      if (guard ? isIterateeCall(value, chars, guard) : chars == null) {
        return string.slice(0, trimmedRightIndex(string) + 1);
      }
      return string.slice(0, charsRightIndex(string, (chars + '')) + 1);
    }

    /**
     * Truncates `string` if it's longer than the given maximum string length.
     * The last characters of the truncated string are replaced with the omission
     * string which defaults to "...".
     *
     * @static
     * @memberOf _
     * @category String
     * @param {string} [string=''] The string to truncate.
     * @param {Object|number} [options] The options object or maximum string length.
     * @param {number} [options.length=30] The maximum string length.
     * @param {string} [options.omission='...'] The string to indicate text is omitted.
     * @param {RegExp|string} [options.separator] The separator pattern to truncate to.
     * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.
     * @returns {string} Returns the truncated string.
     * @example
     *
     * _.trunc('hi-diddly-ho there, neighborino');
     * // => 'hi-diddly-ho there, neighbo...'
     *
     * _.trunc('hi-diddly-ho there, neighborino', 24);
     * // => 'hi-diddly-ho there, n...'
     *
     * _.trunc('hi-diddly-ho there, neighborino', {
     *   'length': 24,
     *   'separator': ' '
     * });
     * // => 'hi-diddly-ho there,...'
     *
     * _.trunc('hi-diddly-ho there, neighborino', {
     *   'length': 24,
     *   'separator': /,? +/
     * });
     * // => 'hi-diddly-ho there...'
     *
     * _.trunc('hi-diddly-ho there, neighborino', {
     *   'omission': ' [...]'
     * });
     * // => 'hi-diddly-ho there, neig [...]'
     */
    function trunc(string, options, guard) {
      if (guard && isIterateeCall(string, options, guard)) {
        options = undefined;
      }
      var length = DEFAULT_TRUNC_LENGTH,
          omission = DEFAULT_TRUNC_OMISSION;

      if (options != null) {
        if (isObject(options)) {
          var separator = 'separator' in options ? options.separator : separator;
          length = 'length' in options ? (+options.length || 0) : length;
          omission = 'omission' in options ? baseToString(options.omission) : omission;
        } else {
          length = +options || 0;
        }
      }
      string = baseToString(string);
      if (length >= string.length) {
        return string;
      }
      var end = length - omission.length;
      if (end < 1) {
        return omission;
      }
      var result = string.slice(0, end);
      if (separator == null) {
        return result + omission;
      }
      if (isRegExp(separator)) {
        if (string.slice(end).search(separator)) {
          var match,
              newEnd,
              substring = string.slice(0, end);

          if (!separator.global) {
            separator = RegExp(separator.source, (reFlags.exec(separator) || '') + 'g');
          }
          separator.lastIndex = 0;
          while ((match = separator.exec(substring))) {
            newEnd = match.index;
          }
          result = result.slice(0, newEnd == null ? end : newEnd);
        }
      } else if (string.indexOf(separator, end) != end) {
        var index = result.lastIndexOf(separator);
        if (index > -1) {
          result = result.slice(0, index);
        }
      }
      return result + omission;
    }

    /**
     * The inverse of `_.escape`; this method converts the HTML entities
     * `&amp;`, `&lt;`, `&gt;`, `&quot;`, `&#39;`, and `&#96;` in `string` to their
     * corresponding characters.
     *
     * **Note:** No other HTML entities are unescaped. To unescape additional HTML
     * entities use a third-party library like [_he_](https://mths.be/he).
     *
     * @static
     * @memberOf _
     * @category String
     * @param {string} [string=''] The string to unescape.
     * @returns {string} Returns the unescaped string.
     * @example
     *
     * _.unescape('fred, barney, &amp; pebbles');
     * // => 'fred, barney, & pebbles'
     */
    function unescape(string) {
      string = baseToString(string);
      return (string && reHasEscapedHtml.test(string))
        ? string.replace(reEscapedHtml, unescapeHtmlChar)
        : string;
    }

    /**
     * Splits `string` into an array of its words.
     *
     * @static
     * @memberOf _
     * @category String
     * @param {string} [string=''] The string to inspect.
     * @param {RegExp|string} [pattern] The pattern to match words.
     * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.
     * @returns {Array} Returns the words of `string`.
     * @example
     *
     * _.words('fred, barney, & pebbles');
     * // => ['fred', 'barney', 'pebbles']
     *
     * _.words('fred, barney, & pebbles', /[^, ]+/g);
     * // => ['fred', 'barney', '&', 'pebbles']
     */
    function words(string, pattern, guard) {
      if (guard && isIterateeCall(string, pattern, guard)) {
        pattern = undefined;
      }
      string = baseToString(string);
      return string.match(pattern || reWords) || [];
    }

    /*------------------------------------------------------------------------*/

    /**
     * Attempts to invoke `func`, returning either the result or the caught error
     * object. Any additional arguments are provided to `func` when it is invoked.
     *
     * @static
     * @memberOf _
     * @category Utility
     * @param {Function} func The function to attempt.
     * @returns {*} Returns the `func` result or error object.
     * @example
     *
     * // avoid throwing errors for invalid selectors
     * var elements = _.attempt(function(selector) {
     *   return document.querySelectorAll(selector);
     * }, '>_>');
     *
     * if (_.isError(elements)) {
     *   elements = [];
     * }
     */
    var attempt = restParam(function(func, args) {
      try {
        return func.apply(undefined, args);
      } catch(e) {
        return isError(e) ? e : new Error(e);
      }
    });

    /**
     * Creates a function that invokes `func` with the `this` binding of `thisArg`
     * and arguments of the created function. If `func` is a property name the
     * created callback returns the property value for a given element. If `func`
     * is an object the created callback returns `true` for elements that contain
     * the equivalent object properties, otherwise it returns `false`.
     *
     * @static
     * @memberOf _
     * @alias iteratee
     * @category Utility
     * @param {*} [func=_.identity] The value to convert to a callback.
     * @param {*} [thisArg] The `this` binding of `func`.
     * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.
     * @returns {Function} Returns the callback.
     * @example
     *
     * var users = [
     *   { 'user': 'barney', 'age': 36 },
     *   { 'user': 'fred',   'age': 40 }
     * ];
     *
     * // wrap to create custom callback shorthands
     * _.callback = _.wrap(_.callback, function(callback, func, thisArg) {
     *   var match = /^(.+?)__([gl]t)(.+)$/.exec(func);
     *   if (!match) {
     *     return callback(func, thisArg);
     *   }
     *   return function(object) {
     *     return match[2] == 'gt'
     *       ? object[match[1]] > match[3]
     *       : object[match[1]] < match[3];
     *   };
     * });
     *
     * _.filter(users, 'age__gt36');
     * // => [{ 'user': 'fred', 'age': 40 }]
     */
    function callback(func, thisArg, guard) {
      if (guard && isIterateeCall(func, thisArg, guard)) {
        thisArg = undefined;
      }
      return isObjectLike(func)
        ? matches(func)
        : baseCallback(func, thisArg);
    }

    /**
     * Creates a function that returns `value`.
     *
     * @static
     * @memberOf _
     * @category Utility
     * @param {*} value The value to return from the new function.
     * @returns {Function} Returns the new function.
     * @example
     *
     * var object = { 'user': 'fred' };
     * var getter = _.constant(object);
     *
     * getter() === object;
     * // => true
     */
    function constant(value) {
      return function() {
        return value;
      };
    }

    /**
     * This method returns the first argument provided to it.
     *
     * @static
     * @memberOf _
     * @category Utility
     * @param {*} value Any value.
     * @returns {*} Returns `value`.
     * @example
     *
     * var object = { 'user': 'fred' };
     *
     * _.identity(object) === object;
     * // => true
     */
    function identity(value) {
      return value;
    }

    /**
     * Creates a function that performs a deep comparison between a given object
     * and `source`, returning `true` if the given object has equivalent property
     * values, else `false`.
     *
     * **Note:** This method supports comparing arrays, booleans, `Date` objects,
     * numbers, `Object` objects, regexes, and strings. Objects are compared by
     * their own, not inherited, enumerable properties. For comparing a single
     * own or inherited property value see `_.matchesProperty`.
     *
     * @static
     * @memberOf _
     * @category Utility
     * @param {Object} source The object of property values to match.
     * @returns {Function} Returns the new function.
     * @example
     *
     * var users = [
     *   { 'user': 'barney', 'age': 36, 'active': true },
     *   { 'user': 'fred',   'age': 40, 'active': false }
     * ];
     *
     * _.filter(users, _.matches({ 'age': 40, 'active': false }));
     * // => [{ 'user': 'fred', 'age': 40, 'active': false }]
     */
    function matches(source) {
      return baseMatches(baseClone(source, true));
    }

    /**
     * Creates a function that compares the property value of `path` on a given
     * object to `value`.
     *
     * **Note:** This method supports comparing arrays, booleans, `Date` objects,
     * numbers, `Object` objects, regexes, and strings. Objects are compared by
     * their own, not inherited, enumerable properties.
     *
     * @static
     * @memberOf _
     * @category Utility
     * @param {Array|string} path The path of the property to get.
     * @param {*} srcValue The value to match.
     * @returns {Function} Returns the new function.
     * @example
     *
     * var users = [
     *   { 'user': 'barney' },
     *   { 'user': 'fred' }
     * ];
     *
     * _.find(users, _.matchesProperty('user', 'fred'));
     * // => { 'user': 'fred' }
     */
    function matchesProperty(path, srcValue) {
      return baseMatchesProperty(path, baseClone(srcValue, true));
    }

    /**
     * Creates a function that invokes the method at `path` on a given object.
     * Any additional arguments are provided to the invoked method.
     *
     * @static
     * @memberOf _
     * @category Utility
     * @param {Array|string} path The path of the method to invoke.
     * @param {...*} [args] The arguments to invoke the method with.
     * @returns {Function} Returns the new function.
     * @example
     *
     * var objects = [
     *   { 'a': { 'b': { 'c': _.constant(2) } } },
     *   { 'a': { 'b': { 'c': _.constant(1) } } }
     * ];
     *
     * _.map(objects, _.method('a.b.c'));
     * // => [2, 1]
     *
     * _.invoke(_.sortBy(objects, _.method(['a', 'b', 'c'])), 'a.b.c');
     * // => [1, 2]
     */
    var method = restParam(function(path, args) {
      return function(object) {
        return invokePath(object, path, args);
      };
    });

    /**
     * The opposite of `_.method`; this method creates a function that invokes
     * the method at a given path on `object`. Any additional arguments are
     * provided to the invoked method.
     *
     * @static
     * @memberOf _
     * @category Utility
     * @param {Object} object The object to query.
     * @param {...*} [args] The arguments to invoke the method with.
     * @returns {Function} Returns the new function.
     * @example
     *
     * var array = _.times(3, _.constant),
     *     object = { 'a': array, 'b': array, 'c': array };
     *
     * _.map(['a[2]', 'c[0]'], _.methodOf(object));
     * // => [2, 0]
     *
     * _.map([['a', '2'], ['c', '0']], _.methodOf(object));
     * // => [2, 0]
     */
    var methodOf = restParam(function(object, args) {
      return function(path) {
        return invokePath(object, path, args);
      };
    });

    /**
     * Adds all own enumerable function properties of a source object to the
     * destination object. If `object` is a function then methods are added to
     * its prototype as well.
     *
     * **Note:** Use `_.runInContext` to create a pristine `lodash` function to
     * avoid conflicts caused by modifying the original.
     *
     * @static
     * @memberOf _
     * @category Utility
     * @param {Function|Object} [object=lodash] The destination object.
     * @param {Object} source The object of functions to add.
     * @param {Object} [options] The options object.
     * @param {boolean} [options.chain=true] Specify whether the functions added
     *  are chainable.
     * @returns {Function|Object} Returns `object`.
     * @example
     *
     * function vowels(string) {
     *   return _.filter(string, function(v) {
     *     return /[aeiou]/i.test(v);
     *   });
     * }
     *
     * _.mixin({ 'vowels': vowels });
     * _.vowels('fred');
     * // => ['e']
     *
     * _('fred').vowels().value();
     * // => ['e']
     *
     * _.mixin({ 'vowels': vowels }, { 'chain': false });
     * _('fred').vowels();
     * // => ['e']
     */
    function mixin(object, source, options) {
      if (options == null) {
        var isObj = isObject(source),
            props = isObj ? keys(source) : undefined,
            methodNames = (props && props.length) ? baseFunctions(source, props) : undefined;

        if (!(methodNames ? methodNames.length : isObj)) {
          methodNames = false;
          options = source;
          source = object;
          object = this;
        }
      }
      if (!methodNames) {
        methodNames = baseFunctions(source, keys(source));
      }
      var chain = true,
          index = -1,
          isFunc = isFunction(object),
          length = methodNames.length;

      if (options === false) {
        chain = false;
      } else if (isObject(options) && 'chain' in options) {
        chain = options.chain;
      }
      while (++index < length) {
        var methodName = methodNames[index],
            func = source[methodName];

        object[methodName] = func;
        if (isFunc) {
          object.prototype[methodName] = (function(func) {
            return function() {
              var chainAll = this.__chain__;
              if (chain || chainAll) {
                var result = object(this.__wrapped__),
                    actions = result.__actions__ = arrayCopy(this.__actions__);

                actions.push({ 'func': func, 'args': arguments, 'thisArg': object });
                result.__chain__ = chainAll;
                return result;
              }
              return func.apply(object, arrayPush([this.value()], arguments));
            };
          }(func));
        }
      }
      return object;
    }

    /**
     * Reverts the `_` variable to its previous value and returns a reference to
     * the `lodash` function.
     *
     * @static
     * @memberOf _
     * @category Utility
     * @returns {Function} Returns the `lodash` function.
     * @example
     *
     * var lodash = _.noConflict();
     */
    function noConflict() {
      root._ = oldDash;
      return this;
    }

    /**
     * A no-operation function that returns `undefined` regardless of the
     * arguments it receives.
     *
     * @static
     * @memberOf _
     * @category Utility
     * @example
     *
     * var object = { 'user': 'fred' };
     *
     * _.noop(object) === undefined;
     * // => true
     */
    function noop() {
      // No operation performed.
    }

    /**
     * Creates a function that returns the property value at `path` on a
     * given object.
     *
     * @static
     * @memberOf _
     * @category Utility
     * @param {Array|string} path The path of the property to get.
     * @returns {Function} Returns the new function.
     * @example
     *
     * var objects = [
     *   { 'a': { 'b': { 'c': 2 } } },
     *   { 'a': { 'b': { 'c': 1 } } }
     * ];
     *
     * _.map(objects, _.property('a.b.c'));
     * // => [2, 1]
     *
     * _.pluck(_.sortBy(objects, _.property(['a', 'b', 'c'])), 'a.b.c');
     * // => [1, 2]
     */
    function property(path) {
      return isKey(path) ? baseProperty(path) : basePropertyDeep(path);
    }

    /**
     * The opposite of `_.property`; this method creates a function that returns
     * the property value at a given path on `object`.
     *
     * @static
     * @memberOf _
     * @category Utility
     * @param {Object} object The object to query.
     * @returns {Function} Returns the new function.
     * @example
     *
     * var array = [0, 1, 2],
     *     object = { 'a': array, 'b': array, 'c': array };
     *
     * _.map(['a[2]', 'c[0]'], _.propertyOf(object));
     * // => [2, 0]
     *
     * _.map([['a', '2'], ['c', '0']], _.propertyOf(object));
     * // => [2, 0]
     */
    function propertyOf(object) {
      return function(path) {
        return baseGet(object, toPath(path), path + '');
      };
    }

    /**
     * Creates an array of numbers (positive and/or negative) progressing from
     * `start` up to, but not including, `end`. If `end` is not specified it is
     * set to `start` with `start` then set to `0`. If `end` is less than `start`
     * a zero-length range is created unless a negative `step` is specified.
     *
     * @static
     * @memberOf _
     * @category Utility
     * @param {number} [start=0] The start of the range.
     * @param {number} end The end of the range.
     * @param {number} [step=1] The value to increment or decrement by.
     * @returns {Array} Returns the new array of numbers.
     * @example
     *
     * _.range(4);
     * // => [0, 1, 2, 3]
     *
     * _.range(1, 5);
     * // => [1, 2, 3, 4]
     *
     * _.range(0, 20, 5);
     * // => [0, 5, 10, 15]
     *
     * _.range(0, -4, -1);
     * // => [0, -1, -2, -3]
     *
     * _.range(1, 4, 0);
     * // => [1, 1, 1]
     *
     * _.range(0);
     * // => []
     */
    function range(start, end, step) {
      if (step && isIterateeCall(start, end, step)) {
        end = step = undefined;
      }
      start = +start || 0;
      step = step == null ? 1 : (+step || 0);

      if (end == null) {
        end = start;
        start = 0;
      } else {
        end = +end || 0;
      }
      // Use `Array(length)` so engines like Chakra and V8 avoid slower modes.
      // See https://youtu.be/XAqIpGU8ZZk#t=17m25s for more details.
      var index = -1,
          length = nativeMax(nativeCeil((end - start) / (step || 1)), 0),
          result = Array(length);

      while (++index < length) {
        result[index] = start;
        start += step;
      }
      return result;
    }

    /**
     * Invokes the iteratee function `n` times, returning an array of the results
     * of each invocation. The `iteratee` is bound to `thisArg` and invoked with
     * one argument; (index).
     *
     * @static
     * @memberOf _
     * @category Utility
     * @param {number} n The number of times to invoke `iteratee`.
     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
     * @param {*} [thisArg] The `this` binding of `iteratee`.
     * @returns {Array} Returns the array of results.
     * @example
     *
     * var diceRolls = _.times(3, _.partial(_.random, 1, 6, false));
     * // => [3, 6, 4]
     *
     * _.times(3, function(n) {
     *   mage.castSpell(n);
     * });
     * // => invokes `mage.castSpell(n)` three times with `n` of `0`, `1`, and `2`
     *
     * _.times(3, function(n) {
     *   this.cast(n);
     * }, mage);
     * // => also invokes `mage.castSpell(n)` three times
     */
    function times(n, iteratee, thisArg) {
      n = nativeFloor(n);

      // Exit early to avoid a JSC JIT bug in Safari 8
      // where `Array(0)` is treated as `Array(1)`.
      if (n < 1 || !nativeIsFinite(n)) {
        return [];
      }
      var index = -1,
          result = Array(nativeMin(n, MAX_ARRAY_LENGTH));

      iteratee = bindCallback(iteratee, thisArg, 1);
      while (++index < n) {
        if (index < MAX_ARRAY_LENGTH) {
          result[index] = iteratee(index);
        } else {
          iteratee(index);
        }
      }
      return result;
    }

    /**
     * Generates a unique ID. If `prefix` is provided the ID is appended to it.
     *
     * @static
     * @memberOf _
     * @category Utility
     * @param {string} [prefix] The value to prefix the ID with.
     * @returns {string} Returns the unique ID.
     * @example
     *
     * _.uniqueId('contact_');
     * // => 'contact_104'
     *
     * _.uniqueId();
     * // => '105'
     */
    function uniqueId(prefix) {
      var id = ++idCounter;
      return baseToString(prefix) + id;
    }

    /*------------------------------------------------------------------------*/

    /**
     * Adds two numbers.
     *
     * @static
     * @memberOf _
     * @category Math
     * @param {number} augend The first number to add.
     * @param {number} addend The second number to add.
     * @returns {number} Returns the sum.
     * @example
     *
     * _.add(6, 4);
     * // => 10
     */
    function add(augend, addend) {
      return (+augend || 0) + (+addend || 0);
    }

    /**
     * Calculates `n` rounded up to `precision`.
     *
     * @static
     * @memberOf _
     * @category Math
     * @param {number} n The number to round up.
     * @param {number} [precision=0] The precision to round up to.
     * @returns {number} Returns the rounded up number.
     * @example
     *
     * _.ceil(4.006);
     * // => 5
     *
     * _.ceil(6.004, 2);
     * // => 6.01
     *
     * _.ceil(6040, -2);
     * // => 6100
     */
    var ceil = createRound('ceil');

    /**
     * Calculates `n` rounded down to `precision`.
     *
     * @static
     * @memberOf _
     * @category Math
     * @param {number} n The number to round down.
     * @param {number} [precision=0] The precision to round down to.
     * @returns {number} Returns the rounded down number.
     * @example
     *
     * _.floor(4.006);
     * // => 4
     *
     * _.floor(0.046, 2);
     * // => 0.04
     *
     * _.floor(4060, -2);
     * // => 4000
     */
    var floor = createRound('floor');

    /**
     * Gets the maximum value of `collection`. If `collection` is empty or falsey
     * `-Infinity` is returned. If an iteratee function is provided it is invoked
     * for each value in `collection` to generate the criterion by which the value
     * is ranked. The `iteratee` is bound to `thisArg` and invoked with three
     * arguments: (value, index, collection).
     *
     * If a property name is provided for `iteratee` the created `_.property`
     * style callback returns the property value of the given element.
     *
     * If a value is also provided for `thisArg` the created `_.matchesProperty`
     * style callback returns `true` for elements that have a matching property
     * value, else `false`.
     *
     * If an object is provided for `iteratee` the created `_.matches` style
     * callback returns `true` for elements that have the properties of the given
     * object, else `false`.
     *
     * @static
     * @memberOf _
     * @category Math
     * @param {Array|Object|string} collection The collection to iterate over.
     * @param {Function|Object|string} [iteratee] The function invoked per iteration.
     * @param {*} [thisArg] The `this` binding of `iteratee`.
     * @returns {*} Returns the maximum value.
     * @example
     *
     * _.max([4, 2, 8, 6]);
     * // => 8
     *
     * _.max([]);
     * // => -Infinity
     *
     * var users = [
     *   { 'user': 'barney', 'age': 36 },
     *   { 'user': 'fred',   'age': 40 }
     * ];
     *
     * _.max(users, function(chr) {
     *   return chr.age;
     * });
     * // => { 'user': 'fred', 'age': 40 }
     *
     * // using the `_.property` callback shorthand
     * _.max(users, 'age');
     * // => { 'user': 'fred', 'age': 40 }
     */
    var max = createExtremum(gt, NEGATIVE_INFINITY);

    /**
     * Gets the minimum value of `collection`. If `collection` is empty or falsey
     * `Infinity` is returned. If an iteratee function is provided it is invoked
     * for each value in `collection` to generate the criterion by which the value
     * is ranked. The `iteratee` is bound to `thisArg` and invoked with three
     * arguments: (value, index, collection).
     *
     * If a property name is provided for `iteratee` the created `_.property`
     * style callback returns the property value of the given element.
     *
     * If a value is also provided for `thisArg` the created `_.matchesProperty`
     * style callback returns `true` for elements that have a matching property
     * value, else `false`.
     *
     * If an object is provided for `iteratee` the created `_.matches` style
     * callback returns `true` for elements that have the properties of the given
     * object, else `false`.
     *
     * @static
     * @memberOf _
     * @category Math
     * @param {Array|Object|string} collection The collection to iterate over.
     * @param {Function|Object|string} [iteratee] The function invoked per iteration.
     * @param {*} [thisArg] The `this` binding of `iteratee`.
     * @returns {*} Returns the minimum value.
     * @example
     *
     * _.min([4, 2, 8, 6]);
     * // => 2
     *
     * _.min([]);
     * // => Infinity
     *
     * var users = [
     *   { 'user': 'barney', 'age': 36 },
     *   { 'user': 'fred',   'age': 40 }
     * ];
     *
     * _.min(users, function(chr) {
     *   return chr.age;
     * });
     * // => { 'user': 'barney', 'age': 36 }
     *
     * // using the `_.property` callback shorthand
     * _.min(users, 'age');
     * // => { 'user': 'barney', 'age': 36 }
     */
    var min = createExtremum(lt, POSITIVE_INFINITY);

    /**
     * Calculates `n` rounded to `precision`.
     *
     * @static
     * @memberOf _
     * @category Math
     * @param {number} n The number to round.
     * @param {number} [precision=0] The precision to round to.
     * @returns {number} Returns the rounded number.
     * @example
     *
     * _.round(4.006);
     * // => 4
     *
     * _.round(4.006, 2);
     * // => 4.01
     *
     * _.round(4060, -2);
     * // => 4100
     */
    var round = createRound('round');

    /**
     * Gets the sum of the values in `collection`.
     *
     * @static
     * @memberOf _
     * @category Math
     * @param {Array|Object|string} collection The collection to iterate over.
     * @param {Function|Object|string} [iteratee] The function invoked per iteration.
     * @param {*} [thisArg] The `this` binding of `iteratee`.
     * @returns {number} Returns the sum.
     * @example
     *
     * _.sum([4, 6]);
     * // => 10
     *
     * _.sum({ 'a': 4, 'b': 6 });
     * // => 10
     *
     * var objects = [
     *   { 'n': 4 },
     *   { 'n': 6 }
     * ];
     *
     * _.sum(objects, function(object) {
     *   return object.n;
     * });
     * // => 10
     *
     * // using the `_.property` callback shorthand
     * _.sum(objects, 'n');
     * // => 10
     */
    function sum(collection, iteratee, thisArg) {
      if (thisArg && isIterateeCall(collection, iteratee, thisArg)) {
        iteratee = undefined;
      }
      iteratee = getCallback(iteratee, thisArg, 3);
      return iteratee.length == 1
        ? arraySum(isArray(collection) ? collection : toIterable(collection), iteratee)
        : baseSum(collection, iteratee);
    }

    /*------------------------------------------------------------------------*/

    // Ensure wrappers are instances of `baseLodash`.
    lodash.prototype = baseLodash.prototype;

    LodashWrapper.prototype = baseCreate(baseLodash.prototype);
    LodashWrapper.prototype.constructor = LodashWrapper;

    LazyWrapper.prototype = baseCreate(baseLodash.prototype);
    LazyWrapper.prototype.constructor = LazyWrapper;

    // Add functions to the `Map` cache.
    MapCache.prototype['delete'] = mapDelete;
    MapCache.prototype.get = mapGet;
    MapCache.prototype.has = mapHas;
    MapCache.prototype.set = mapSet;

    // Add functions to the `Set` cache.
    SetCache.prototype.push = cachePush;

    // Assign cache to `_.memoize`.
    memoize.Cache = MapCache;

    // Add functions that return wrapped values when chaining.
    lodash.after = after;
    lodash.ary = ary;
    lodash.assign = assign;
    lodash.at = at;
    lodash.before = before;
    lodash.bind = bind;
    lodash.bindAll = bindAll;
    lodash.bindKey = bindKey;
    lodash.callback = callback;
    lodash.chain = chain;
    lodash.chunk = chunk;
    lodash.compact = compact;
    lodash.constant = constant;
    lodash.countBy = countBy;
    lodash.create = create;
    lodash.curry = curry;
    lodash.curryRight = curryRight;
    lodash.debounce = debounce;
    lodash.defaults = defaults;
    lodash.defaultsDeep = defaultsDeep;
    lodash.defer = defer;
    lodash.delay = delay;
    lodash.difference = difference;
    lodash.drop = drop;
    lodash.dropRight = dropRight;
    lodash.dropRightWhile = dropRightWhile;
    lodash.dropWhile = dropWhile;
    lodash.fill = fill;
    lodash.filter = filter;
    lodash.flatten = flatten;
    lodash.flattenDeep = flattenDeep;
    lodash.flow = flow;
    lodash.flowRight = flowRight;
    lodash.forEach = forEach;
    lodash.forEachRight = forEachRight;
    lodash.forIn = forIn;
    lodash.forInRight = forInRight;
    lodash.forOwn = forOwn;
    lodash.forOwnRight = forOwnRight;
    lodash.functions = functions;
    lodash.groupBy = groupBy;
    lodash.indexBy = indexBy;
    lodash.initial = initial;
    lodash.intersection = intersection;
    lodash.invert = invert;
    lodash.invoke = invoke;
    lodash.keys = keys;
    lodash.keysIn = keysIn;
    lodash.map = map;
    lodash.mapKeys = mapKeys;
    lodash.mapValues = mapValues;
    lodash.matches = matches;
    lodash.matchesProperty = matchesProperty;
    lodash.memoize = memoize;
    lodash.merge = merge;
    lodash.method = method;
    lodash.methodOf = methodOf;
    lodash.mixin = mixin;
    lodash.modArgs = modArgs;
    lodash.negate = negate;
    lodash.omit = omit;
    lodash.once = once;
    lodash.pairs = pairs;
    lodash.partial = partial;
    lodash.partialRight = partialRight;
    lodash.partition = partition;
    lodash.pick = pick;
    lodash.pluck = pluck;
    lodash.property = property;
    lodash.propertyOf = propertyOf;
    lodash.pull = pull;
    lodash.pullAt = pullAt;
    lodash.range = range;
    lodash.rearg = rearg;
    lodash.reject = reject;
    lodash.remove = remove;
    lodash.rest = rest;
    lodash.restParam = restParam;
    lodash.set = set;
    lodash.shuffle = shuffle;
    lodash.slice = slice;
    lodash.sortBy = sortBy;
    lodash.sortByAll = sortByAll;
    lodash.sortByOrder = sortByOrder;
    lodash.spread = spread;
    lodash.take = take;
    lodash.takeRight = takeRight;
    lodash.takeRightWhile = takeRightWhile;
    lodash.takeWhile = takeWhile;
    lodash.tap = tap;
    lodash.throttle = throttle;
    lodash.thru = thru;
    lodash.times = times;
    lodash.toArray = toArray;
    lodash.toPlainObject = toPlainObject;
    lodash.transform = transform;
    lodash.union = union;
    lodash.uniq = uniq;
    lodash.unzip = unzip;
    lodash.unzipWith = unzipWith;
    lodash.values = values;
    lodash.valuesIn = valuesIn;
    lodash.where = where;
    lodash.without = without;
    lodash.wrap = wrap;
    lodash.xor = xor;
    lodash.zip = zip;
    lodash.zipObject = zipObject;
    lodash.zipWith = zipWith;

    // Add aliases.
    lodash.backflow = flowRight;
    lodash.collect = map;
    lodash.compose = flowRight;
    lodash.each = forEach;
    lodash.eachRight = forEachRight;
    lodash.extend = assign;
    lodash.iteratee = callback;
    lodash.methods = functions;
    lodash.object = zipObject;
    lodash.select = filter;
    lodash.tail = rest;
    lodash.unique = uniq;

    // Add functions to `lodash.prototype`.
    mixin(lodash, lodash);

    /*------------------------------------------------------------------------*/

    // Add functions that return unwrapped values when chaining.
    lodash.add = add;
    lodash.attempt = attempt;
    lodash.camelCase = camelCase;
    lodash.capitalize = capitalize;
    lodash.ceil = ceil;
    lodash.clone = clone;
    lodash.cloneDeep = cloneDeep;
    lodash.deburr = deburr;
    lodash.endsWith = endsWith;
    lodash.escape = escape;
    lodash.escapeRegExp = escapeRegExp;
    lodash.every = every;
    lodash.find = find;
    lodash.findIndex = findIndex;
    lodash.findKey = findKey;
    lodash.findLast = findLast;
    lodash.findLastIndex = findLastIndex;
    lodash.findLastKey = findLastKey;
    lodash.findWhere = findWhere;
    lodash.first = first;
    lodash.floor = floor;
    lodash.get = get;
    lodash.gt = gt;
    lodash.gte = gte;
    lodash.has = has;
    lodash.identity = identity;
    lodash.includes = includes;
    lodash.indexOf = indexOf;
    lodash.inRange = inRange;
    lodash.isArguments = isArguments;
    lodash.isArray = isArray;
    lodash.isBoolean = isBoolean;
    lodash.isDate = isDate;
    lodash.isElement = isElement;
    lodash.isEmpty = isEmpty;
    lodash.isEqual = isEqual;
    lodash.isError = isError;
    lodash.isFinite = isFinite;
    lodash.isFunction = isFunction;
    lodash.isMatch = isMatch;
    lodash.isNaN = isNaN;
    lodash.isNative = isNative;
    lodash.isNull = isNull;
    lodash.isNumber = isNumber;
    lodash.isObject = isObject;
    lodash.isPlainObject = isPlainObject;
    lodash.isRegExp = isRegExp;
    lodash.isString = isString;
    lodash.isTypedArray = isTypedArray;
    lodash.isUndefined = isUndefined;
    lodash.kebabCase = kebabCase;
    lodash.last = last;
    lodash.lastIndexOf = lastIndexOf;
    lodash.lt = lt;
    lodash.lte = lte;
    lodash.max = max;
    lodash.min = min;
    lodash.noConflict = noConflict;
    lodash.noop = noop;
    lodash.now = now;
    lodash.pad = pad;
    lodash.padLeft = padLeft;
    lodash.padRight = padRight;
    lodash.parseInt = parseInt;
    lodash.random = random;
    lodash.reduce = reduce;
    lodash.reduceRight = reduceRight;
    lodash.repeat = repeat;
    lodash.result = result;
    lodash.round = round;
    lodash.runInContext = runInContext;
    lodash.size = size;
    lodash.snakeCase = snakeCase;
    lodash.some = some;
    lodash.sortedIndex = sortedIndex;
    lodash.sortedLastIndex = sortedLastIndex;
    lodash.startCase = startCase;
    lodash.startsWith = startsWith;
    lodash.sum = sum;
    lodash.template = template;
    lodash.trim = trim;
    lodash.trimLeft = trimLeft;
    lodash.trimRight = trimRight;
    lodash.trunc = trunc;
    lodash.unescape = unescape;
    lodash.uniqueId = uniqueId;
    lodash.words = words;

    // Add aliases.
    lodash.all = every;
    lodash.any = some;
    lodash.contains = includes;
    lodash.eq = isEqual;
    lodash.detect = find;
    lodash.foldl = reduce;
    lodash.foldr = reduceRight;
    lodash.head = first;
    lodash.include = includes;
    lodash.inject = reduce;

    mixin(lodash, (function() {
      var source = {};
      baseForOwn(lodash, function(func, methodName) {
        if (!lodash.prototype[methodName]) {
          source[methodName] = func;
        }
      });
      return source;
    }()), false);

    /*------------------------------------------------------------------------*/

    // Add functions capable of returning wrapped and unwrapped values when chaining.
    lodash.sample = sample;

    lodash.prototype.sample = function(n) {
      if (!this.__chain__ && n == null) {
        return sample(this.value());
      }
      return this.thru(function(value) {
        return sample(value, n);
      });
    };

    /*------------------------------------------------------------------------*/

    /**
     * The semantic version number.
     *
     * @static
     * @memberOf _
     * @type string
     */
    lodash.VERSION = VERSION;

    // Assign default placeholders.
    arrayEach(['bind', 'bindKey', 'curry', 'curryRight', 'partial', 'partialRight'], function(methodName) {
      lodash[methodName].placeholder = lodash;
    });

    // Add `LazyWrapper` methods for `_.drop` and `_.take` variants.
    arrayEach(['drop', 'take'], function(methodName, index) {
      LazyWrapper.prototype[methodName] = function(n) {
        var filtered = this.__filtered__;
        if (filtered && !index) {
          return new LazyWrapper(this);
        }
        n = n == null ? 1 : nativeMax(nativeFloor(n) || 0, 0);

        var result = this.clone();
        if (filtered) {
          result.__takeCount__ = nativeMin(result.__takeCount__, n);
        } else {
          result.__views__.push({ 'size': n, 'type': methodName + (result.__dir__ < 0 ? 'Right' : '') });
        }
        return result;
      };

      LazyWrapper.prototype[methodName + 'Right'] = function(n) {
        return this.reverse()[methodName](n).reverse();
      };
    });

    // Add `LazyWrapper` methods that accept an `iteratee` value.
    arrayEach(['filter', 'map', 'takeWhile'], function(methodName, index) {
      var type = index + 1,
          isFilter = type != LAZY_MAP_FLAG;

      LazyWrapper.prototype[methodName] = function(iteratee, thisArg) {
        var result = this.clone();
        result.__iteratees__.push({ 'iteratee': getCallback(iteratee, thisArg, 1), 'type': type });
        result.__filtered__ = result.__filtered__ || isFilter;
        return result;
      };
    });

    // Add `LazyWrapper` methods for `_.first` and `_.last`.
    arrayEach(['first', 'last'], function(methodName, index) {
      var takeName = 'take' + (index ? 'Right' : '');

      LazyWrapper.prototype[methodName] = function() {
        return this[takeName](1).value()[0];
      };
    });

    // Add `LazyWrapper` methods for `_.initial` and `_.rest`.
    arrayEach(['initial', 'rest'], function(methodName, index) {
      var dropName = 'drop' + (index ? '' : 'Right');

      LazyWrapper.prototype[methodName] = function() {
        return this.__filtered__ ? new LazyWrapper(this) : this[dropName](1);
      };
    });

    // Add `LazyWrapper` methods for `_.pluck` and `_.where`.
    arrayEach(['pluck', 'where'], function(methodName, index) {
      var operationName = index ? 'filter' : 'map',
          createCallback = index ? baseMatches : property;

      LazyWrapper.prototype[methodName] = function(value) {
        return this[operationName](createCallback(value));
      };
    });

    LazyWrapper.prototype.compact = function() {
      return this.filter(identity);
    };

    LazyWrapper.prototype.reject = function(predicate, thisArg) {
      predicate = getCallback(predicate, thisArg, 1);
      return this.filter(function(value) {
        return !predicate(value);
      });
    };

    LazyWrapper.prototype.slice = function(start, end) {
      start = start == null ? 0 : (+start || 0);

      var result = this;
      if (result.__filtered__ && (start > 0 || end < 0)) {
        return new LazyWrapper(result);
      }
      if (start < 0) {
        result = result.takeRight(-start);
      } else if (start) {
        result = result.drop(start);
      }
      if (end !== undefined) {
        end = (+end || 0);
        result = end < 0 ? result.dropRight(-end) : result.take(end - start);
      }
      return result;
    };

    LazyWrapper.prototype.takeRightWhile = function(predicate, thisArg) {
      return this.reverse().takeWhile(predicate, thisArg).reverse();
    };

    LazyWrapper.prototype.toArray = function() {
      return this.take(POSITIVE_INFINITY);
    };

    // Add `LazyWrapper` methods to `lodash.prototype`.
    baseForOwn(LazyWrapper.prototype, function(func, methodName) {
      var checkIteratee = /^(?:filter|map|reject)|While$/.test(methodName),
          retUnwrapped = /^(?:first|last)$/.test(methodName),
          lodashFunc = lodash[retUnwrapped ? ('take' + (methodName == 'last' ? 'Right' : '')) : methodName];

      if (!lodashFunc) {
        return;
      }
      lodash.prototype[methodName] = function() {
        var args = retUnwrapped ? [1] : arguments,
            chainAll = this.__chain__,
            value = this.__wrapped__,
            isHybrid = !!this.__actions__.length,
            isLazy = value instanceof LazyWrapper,
            iteratee = args[0],
            useLazy = isLazy || isArray(value);

        if (useLazy && checkIteratee && typeof iteratee == 'function' && iteratee.length != 1) {
          // Avoid lazy use if the iteratee has a "length" value other than `1`.
          isLazy = useLazy = false;
        }
        var interceptor = function(value) {
          return (retUnwrapped && chainAll)
            ? lodashFunc(value, 1)[0]
            : lodashFunc.apply(undefined, arrayPush([value], args));
        };

        var action = { 'func': thru, 'args': [interceptor], 'thisArg': undefined },
            onlyLazy = isLazy && !isHybrid;

        if (retUnwrapped && !chainAll) {
          if (onlyLazy) {
            value = value.clone();
            value.__actions__.push(action);
            return func.call(value);
          }
          return lodashFunc.call(undefined, this.value())[0];
        }
        if (!retUnwrapped && useLazy) {
          value = onlyLazy ? value : new LazyWrapper(this);
          var result = func.apply(value, args);
          result.__actions__.push(action);
          return new LodashWrapper(result, chainAll);
        }
        return this.thru(interceptor);
      };
    });

    // Add `Array` and `String` methods to `lodash.prototype`.
    arrayEach(['join', 'pop', 'push', 'replace', 'shift', 'sort', 'splice', 'split', 'unshift'], function(methodName) {
      var func = (/^(?:replace|split)$/.test(methodName) ? stringProto : arrayProto)[methodName],
          chainName = /^(?:push|sort|unshift)$/.test(methodName) ? 'tap' : 'thru',
          retUnwrapped = /^(?:join|pop|replace|shift)$/.test(methodName);

      lodash.prototype[methodName] = function() {
        var args = arguments;
        if (retUnwrapped && !this.__chain__) {
          return func.apply(this.value(), args);
        }
        return this[chainName](function(value) {
          return func.apply(value, args);
        });
      };
    });

    // Map minified function names to their real names.
    baseForOwn(LazyWrapper.prototype, function(func, methodName) {
      var lodashFunc = lodash[methodName];
      if (lodashFunc) {
        var key = lodashFunc.name,
            names = realNames[key] || (realNames[key] = []);

        names.push({ 'name': methodName, 'func': lodashFunc });
      }
    });

    realNames[createHybridWrapper(undefined, BIND_KEY_FLAG).name] = [{ 'name': 'wrapper', 'func': undefined }];

    // Add functions to the lazy wrapper.
    LazyWrapper.prototype.clone = lazyClone;
    LazyWrapper.prototype.reverse = lazyReverse;
    LazyWrapper.prototype.value = lazyValue;

    // Add chaining functions to the `lodash` wrapper.
    lodash.prototype.chain = wrapperChain;
    lodash.prototype.commit = wrapperCommit;
    lodash.prototype.concat = wrapperConcat;
    lodash.prototype.plant = wrapperPlant;
    lodash.prototype.reverse = wrapperReverse;
    lodash.prototype.toString = wrapperToString;
    lodash.prototype.run = lodash.prototype.toJSON = lodash.prototype.valueOf = lodash.prototype.value = wrapperValue;

    // Add function aliases to the `lodash` wrapper.
    lodash.prototype.collect = lodash.prototype.map;
    lodash.prototype.head = lodash.prototype.first;
    lodash.prototype.select = lodash.prototype.filter;
    lodash.prototype.tail = lodash.prototype.rest;

    return lodash;
  }

  /*--------------------------------------------------------------------------*/

  // Export lodash.
  var _ = runInContext();

  // Some AMD build optimizers like r.js check for condition patterns like the following:
  if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) {
    // Expose lodash to the global object when an AMD loader is present to avoid
    // errors in cases where lodash is loaded by a script tag and not intended
    // as an AMD module. See http://requirejs.org/docs/errors.html#mismatch for
    // more details.
    root._ = _;

    // Define as an anonymous module so, through path mapping, it can be
    // referenced as the "underscore" module.
    define(function() {
      return _;
    });
  }
  // Check for `exports` after `define` in case a build optimizer adds an `exports` object.
  else if (freeExports && freeModule) {
    // Export for Node.js or RingoJS.
    if (moduleExports) {
      (freeModule.exports = _)._ = _;
    }
    // Export for Rhino with CommonJS support.
    else {
      freeExports._ = _;
    }
  }
  else {
    // Export for a browser or Rhino.
    root._ = _;
  }
}.call(this));

}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
},{}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/machina/lib/machina.js":[function(require,module,exports){
/*!
 *  * machina - A library for creating powerful and flexible finite state machines. Loosely inspired by Erlang/OTP's gen_fsm behavior.
 *  * Author: Jim Cowart (http://ifandelse.com)
 *  * Version: v2.0.0
 *  * Url: http://machina-js.org/
 *  * License(s): 
 */
(function webpackUniversalModuleDefinition(root, factory) {
	if(typeof exports === 'object' && typeof module === 'object')
		module.exports = factory(require("lodash"));
	else if(typeof define === 'function' && define.amd)
		define(["lodash"], factory);
	else if(typeof exports === 'object')
		exports["machina"] = factory(require("lodash"));
	else
		root["machina"] = factory(root["_"]);
})(this, function(__WEBPACK_EXTERNAL_MODULE_1__) {
return /******/ (function(modules) { // webpackBootstrap
/******/ 	// The module cache
/******/ 	var installedModules = {};
/******/
/******/ 	// The require function
/******/ 	function __webpack_require__(moduleId) {
/******/
/******/ 		// Check if module is in cache
/******/ 		if(installedModules[moduleId])
/******/ 			return installedModules[moduleId].exports;
/******/
/******/ 		// Create a new module (and put it into the cache)
/******/ 		var module = installedModules[moduleId] = {
/******/ 			exports: {},
/******/ 			id: moduleId,
/******/ 			loaded: false
/******/ 		};
/******/
/******/ 		// Execute the module function
/******/ 		modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ 		// Flag the module as loaded
/******/ 		module.loaded = true;
/******/
/******/ 		// Return the exports of the module
/******/ 		return module.exports;
/******/ 	}
/******/
/******/
/******/ 	// expose the modules object (__webpack_modules__)
/******/ 	__webpack_require__.m = modules;
/******/
/******/ 	// expose the module cache
/******/ 	__webpack_require__.c = installedModules;
/******/
/******/ 	// __webpack_public_path__
/******/ 	__webpack_require__.p = "";
/******/
/******/ 	// Load entry module and return exports
/******/ 	return __webpack_require__(0);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ function(module, exports, __webpack_require__) {

	var _ = __webpack_require__( 1 );
	var emitter = __webpack_require__( 2 );
	
	module.exports = _.merge( emitter.instance, {
		Fsm: __webpack_require__( 5 ),
		BehavioralFsm: __webpack_require__( 6 ),
		utils: __webpack_require__( 3 ),
		eventListeners: {
			newFsm: []
		}
	} );


/***/ },
/* 1 */
/***/ function(module, exports) {

	module.exports = __WEBPACK_EXTERNAL_MODULE_1__;

/***/ },
/* 2 */
/***/ function(module, exports, __webpack_require__) {

	var utils = __webpack_require__( 3 );
	var _ = __webpack_require__( 1 );
	
	function getInstance() {
		return {
			emit: function( eventName ) {
				var args = utils.getLeaklessArgs( arguments );
				if ( this.eventListeners[ "*" ] ) {
					_.each( this.eventListeners[ "*" ], function( callback ) {
						if ( !this.useSafeEmit ) {
							callback.apply( this, args );
						} else {
							try {
								callback.apply( this, args );
							} catch ( exception ) {
								/* istanbul ignore else  */
								if ( console && typeof console.log !== "undefined" ) {
									console.log( exception.stack );
								}
							}
						}
					}, this );
				}
				if ( this.eventListeners[ eventName ] ) {
					_.each( this.eventListeners[ eventName ], function( callback ) {
						if ( !this.useSafeEmit ) {
							callback.apply( this, args.slice( 1 ) );
						} else {
							try {
								callback.apply( this, args.slice( 1 ) );
							} catch ( exception ) {
								/* istanbul ignore else  */
								if ( console && typeof console.log !== "undefined" ) {
									console.log( exception.stack );
								}
							}
						}
					}, this );
				}
			},
	
			on: function( eventName, callback ) {
				var self = this;
				self.eventListeners = self.eventListeners || { "*": [] };
				if ( !self.eventListeners[ eventName ] ) {
					self.eventListeners[ eventName ] = [];
				}
				self.eventListeners[ eventName ].push( callback );
				return {
					eventName: eventName,
					callback: callback,
					off: function() {
						self.off( eventName, callback );
					}
				};
			},
	
			off: function( eventName, callback ) {
				this.eventListeners = this.eventListeners || { "*": [] };
				if ( !eventName ) {
					this.eventListeners = {};
				} else {
					if ( callback ) {
						this.eventListeners[ eventName ] = _.without( this.eventListeners[ eventName ], callback );
					} else {
						this.eventListeners[ eventName ] = [];
					}
				}
			}
		};
	}
	
	module.exports = {
		getInstance: getInstance,
		instance: getInstance()
	};


/***/ },
/* 3 */
/***/ function(module, exports, __webpack_require__) {

	var slice = [].slice;
	var events = __webpack_require__( 4 );
	var _ = __webpack_require__( 1 );
	
	var makeFsmNamespace = ( function() {
		var machinaCount = 0;
		return function() {
			return "fsm." + machinaCount++;
		};
	} )();
	
	function getDefaultBehavioralOptions() {
		return {
			initialState: "uninitialized",
			eventListeners: {
				"*": []
			},
			states: {},
			namespace: makeFsmNamespace(),
			useSafeEmit: false,
			hierarchy: {},
			pendingDelegations: {}
		};
	}
	
	function getDefaultClientMeta() {
		return {
			inputQueue: [],
			targetReplayState: "",
			state: undefined,
			priorState: undefined,
			priorAction: "",
			currentAction: "",
			currentActionArgs: undefined,
			inExitHandler: false
		};
	}
	
	function getLeaklessArgs( args, startIdx ) {
		var result = [];
		for ( var i = ( startIdx || 0 ); i < args.length; i++ ) {
			result[ i ] = args[ i ];
		}
		return result;
	}
	/*
		handle ->
			child = stateObj._child && stateObj._child.instance;
	
		transition ->
			newStateObj._child = getChildFsmInstance( newStateObj._child );
			child = newStateObj._child && newStateObj._child.instance;
	*/
	function getChildFsmInstance( config ) {
		if ( !config ) {
			return;
		}
		var childFsmDefinition = {};
		if ( typeof config === "object" ) {
			// is this a config object with a factory?
			if ( config.factory ) {
				childFsmDefinition = config;
				childFsmDefinition.instance = childFsmDefinition.factory();
			} else {
				// assuming this is a machina instance
				childFsmDefinition.factory = function() {
					return config;
				};
			}
		} else if ( typeof config === "function" ) {
			childFsmDefinition.factory = config;
		}
		childFsmDefinition.instance = childFsmDefinition.factory();
		return childFsmDefinition;
	}
	
	function listenToChild( fsm, child ) {
		// Need to investigate potential for discarded event
		// listener memory leak in long-running, deeply-nested hierarchies.
		return child.on( "*", function( eventName, data ) {
			switch ( eventName ) {
				case events.NO_HANDLER:
					if ( !data.ticket && !data.delegated && data.namespace !== fsm.namespace ) {
						// Ok - we're dealing w/ a child handling input that should bubble up
						data.args[ 1 ].bubbling = true;
					}
					// we do NOT bubble _reset inputs up to the parent
					if ( data.inputType !== "_reset" ) {
						fsm.handle.apply( fsm, data.args );
					}
					break;
				case events.HANDLING :
					var ticket = data.ticket;
					if ( ticket && fsm.pendingDelegations[ ticket ] ) {
						delete fsm.pendingDelegations[ ticket ];
					}
					fsm.emit( eventName, data ); // possibly transform payload?
					break;
				default:
					fsm.emit( eventName, data ); // possibly transform payload?
					break;
			}
		} );
	}
	
	// _machKeys are members we want to track across the prototype chain of an extended FSM constructor
	// Since we want to eventually merge the aggregate of those values onto the instance so that FSMs
	// that share the same extended prototype won't share state *on* those prototypes.
	var _machKeys = [ "states", "initialState" ];
	var extend = function( protoProps, staticProps ) {
		var parent = this;
		var fsm; // placeholder for instance constructor
		var machObj = {}; // object used to hold initialState & states from prototype for instance-level merging
		var Ctor = function() {}; // placeholder ctor function used to insert level in prototype chain
	
		// The constructor function for the new subclass is either defined by you
		// (the "constructor" property in your `extend` definition), or defaulted
		// by us to simply call the parent's constructor.
		if ( protoProps && protoProps.hasOwnProperty( "constructor" ) ) {
			fsm = protoProps.constructor;
		} else {
			// The default machina constructor (when using inheritance) creates a
			// deep copy of the states/initialState values from the prototype and
			// extends them over the instance so that they'll be instance-level.
			// If an options arg (args[0]) is passed in, a states or intialState
			// value will be preferred over any data pulled up from the prototype.
			fsm = function() {
				var args = slice.call( arguments, 0 );
				args[ 0 ] = args[ 0 ] || {};
				var blendedState;
				var instanceStates = args[ 0 ].states || {};
				blendedState = _.merge( _.cloneDeep( machObj ), { states: instanceStates } );
				blendedState.initialState = args[ 0 ].initialState || this.initialState;
				_.extend( args[ 0 ], blendedState );
				parent.apply( this, args );
			};
		}
	
		// Inherit class (static) properties from parent.
		_.merge( fsm, parent );
	
		// Set the prototype chain to inherit from `parent`, without calling
		// `parent`'s constructor function.
		Ctor.prototype = parent.prototype;
		fsm.prototype = new Ctor();
	
		// Add prototype properties (instance properties) to the subclass,
		// if supplied.
		if ( protoProps ) {
			_.extend( fsm.prototype, protoProps );
			_.merge( machObj, _.transform( protoProps, function( accum, val, key ) {
				if ( _machKeys.indexOf( key ) !== -1 ) {
					accum[ key ] = val;
				}
			} ) );
		}
	
		// Add static properties to the constructor function, if supplied.
		if ( staticProps ) {
			_.merge( fsm, staticProps );
		}
	
		// Correctly set child's `prototype.constructor`.
		fsm.prototype.constructor = fsm;
	
		// Set a convenience property in case the parent's prototype is needed later.
		fsm.__super__ = parent.prototype;
		return fsm;
	};
	
	function createUUID() {
		var s = [];
		var hexDigits = "0123456789abcdef";
		for ( var i = 0; i < 36; i++ ) {
			s[ i ] = hexDigits.substr( Math.floor( Math.random() * 0x10 ), 1 );
		}
		s[ 14 ] = "4"; // bits 12-15 of the time_hi_and_version field to 0010
		/* jshint ignore:start */
		s[ 19 ] = hexDigits.substr( ( s[ 19 ] & 0x3 ) | 0x8, 1 ); // bits 6-7 of the clock_seq_hi_and_reserved to 01
		/* jshint ignore:end */
		s[ 8 ] = s[ 13 ] = s[ 18 ] = s[ 23 ] = "-";
		return s.join( "" );
	}
	
	module.exports = {
		createUUID: createUUID,
		extend: extend,
		getDefaultBehavioralOptions: getDefaultBehavioralOptions,
		getDefaultOptions: getDefaultBehavioralOptions,
		getDefaultClientMeta: getDefaultClientMeta,
		getChildFsmInstance: getChildFsmInstance,
		getLeaklessArgs: getLeaklessArgs,
		listenToChild: listenToChild,
		makeFsmNamespace: makeFsmNamespace
	};


/***/ },
/* 4 */
/***/ function(module, exports) {

	module.exports = {
		NEXT_TRANSITION: "transition",
		HANDLING: "handling",
		HANDLED: "handled",
		NO_HANDLER: "nohandler",
		TRANSITION: "transition",
		TRANSITIONED: "transitioned",
		INVALID_STATE: "invalidstate",
		DEFERRED: "deferred",
		NEW_FSM: "newfsm"
	};


/***/ },
/* 5 */
/***/ function(module, exports, __webpack_require__) {

	var BehavioralFsm = __webpack_require__( 6 );
	var utils = __webpack_require__( 3 );
	var _ = __webpack_require__( 1 );
	
	var Fsm = {
		constructor: function() {
			BehavioralFsm.apply( this, arguments );
			this.ensureClientMeta();
		},
		initClient: function initClient() {
			var initialState = this.initialState;
			if ( !initialState ) {
				throw new Error( "You must specify an initial state for this FSM" );
			}
			if ( !this.states[ initialState ] ) {
				throw new Error( "The initial state specified does not exist in the states object." );
			}
			this.transition( initialState );
		},
		ensureClientMeta: function ensureClientMeta() {
			if ( !this._stamped ) {
				this._stamped = true;
				_.defaults( this, _.cloneDeep( utils.getDefaultClientMeta() ) );
				this.initClient();
			}
			return this;
		},
	
		ensureClientArg: function( args ) {
			var _args = args;
			// we need to test the args and verify that if a client arg has
			// been passed, it must be this FSM instance (this isn't a behavioral FSM)
			if ( typeof _args[ 0 ] === "object" && !( "inputType" in _args[ 0 ] ) && _args[ 0 ] !== this ) {
				_args.splice( 0, 1, this );
			} else if ( typeof _args[ 0 ] !== "object" || ( typeof _args[ 0 ] === "object" && ( "inputType" in _args[ 0 ] ) ) ) {
				_args.unshift( this );
			}
			return _args;
		},
	
		getHandlerArgs: function( args, isCatchAll ) {
			// index 0 is the client, index 1 is inputType
			// if we're in a catch-all handler, input type needs to be included in the args
			// inputType might be an object, so we need to just get the inputType string if so
			var _args = args;
			var input = _args[ 1 ];
			if ( typeof inputType === "object" ) {
				_args.splice( 1, 1, input.inputType );
			}
			return isCatchAll ?
				_args.slice( 1 ) :
				_args.slice( 2 );
		},
	
		getSystemHandlerArgs: function( args, client ) {
			return args;
		},
	
		// "classic" machina FSM do not emit the client property on events (which would be the FSM itself)
		buildEventPayload: function() {
			var args = this.ensureClientArg( utils.getLeaklessArgs( arguments ) );
			var data = args[ 1 ];
			if ( _.isPlainObject( data ) ) {
				return _.extend( data, { namespace: this.namespace } );
			} else {
				return { data: data || null, namespace: this.namespace };
			}
		}
	};
	
	_.each( [
		"handle",
		"transition",
		"deferUntilTransition",
		"processQueue",
		"clearQueue"
	], function( methodWithClientInjected ) {
		Fsm[ methodWithClientInjected ] = function() {
			var args = this.ensureClientArg( utils.getLeaklessArgs( arguments ) );
			return BehavioralFsm.prototype[ methodWithClientInjected ].apply( this, args );
		};
	} );
	
	Fsm = BehavioralFsm.extend( Fsm );
	
	module.exports = Fsm;


/***/ },
/* 6 */
/***/ function(module, exports, __webpack_require__) {

	var _ = __webpack_require__( 1 );
	var utils = __webpack_require__( 3 );
	var emitter = __webpack_require__( 2 );
	var topLevelEmitter = emitter.instance;
	var events = __webpack_require__( 4 );
	
	var MACHINA_PROP = "__machina__";
	
	function BehavioralFsm( options ) {
		_.extend( this, options );
		_.defaults( this, utils.getDefaultBehavioralOptions() );
		this.initialize.apply( this, arguments );
		topLevelEmitter.emit( events.NEW_FSM, this );
	}
	
	_.extend( BehavioralFsm.prototype, {
		initialize: function() {},
	
		initClient: function initClient( client ) {
			var initialState = this.initialState;
			if ( !initialState ) {
				throw new Error( "You must specify an initial state for this FSM" );
			}
			if ( !this.states[ initialState ] ) {
				throw new Error( "The initial state specified does not exist in the states object." );
			}
			this.transition( client, initialState );
		},
	
		configForState: function configForState( newState ) {
			var newStateObj = this.states[ newState ];
			var child;
			_.each( this.hierarchy, function( childListener, key ) {
				if ( childListener && typeof childListener.off === "function" ) {
					childListener.off();
				}
			} );
	
			if ( newStateObj._child ) {
				newStateObj._child = utils.getChildFsmInstance( newStateObj._child );
				child = newStateObj._child && newStateObj._child.instance;
				this.hierarchy[ child.namespace ] = utils.listenToChild( this, child );
			}
	
			return child;
		},
	
		ensureClientMeta: function ensureClientMeta( client ) {
			if ( typeof client !== "object" ) {
				throw new Error( "An FSM client must be an object." );
			}
			client[ MACHINA_PROP ] = client[ MACHINA_PROP ] || {};
			if ( !client[ MACHINA_PROP ][ this.namespace ] ) {
				client[ MACHINA_PROP ][ this.namespace ] = _.cloneDeep( utils.getDefaultClientMeta() );
				this.initClient( client );
			}
			return client[ MACHINA_PROP ][ this.namespace ];
		},
	
		buildEventPayload: function( client, data ) {
			if ( _.isPlainObject( data ) ) {
				return _.extend( data, { client: client, namespace: this.namespace } );
			} else {
				return { client: client, data: data || null, namespace: this.namespace };
			}
		},
	
		getHandlerArgs: function( args, isCatchAll ) {
			// index 0 is the client, index 1 is inputType
			// if we're in a catch-all handler, input type needs to be included in the args
			// inputType might be an object, so we need to just get the inputType string if so
			var _args = args.slice( 0 );
			var input = _args[ 1 ];
			if ( typeof input === "object" ) {
				_args.splice( 1, 1, input.inputType );
			}
			return isCatchAll ?
				_args :
				[ _args[ 0 ] ].concat( _args.slice( 2 ) );
		},
	
		getSystemHandlerArgs: function( args, client ) {
			return [ client ].concat( args );
		},
	
		handle: function( client, input ) {
			var inputDef = input;
			if ( typeof input === "undefined" ) {
				throw new Error( "The input argument passed to the FSM's handle method is undefined. Did you forget to pass the input name?" );
			}
			if ( typeof input === "string" ) {
				inputDef = { inputType: input, delegated: false, ticket: undefined };
			}
			var clientMeta = this.ensureClientMeta( client );
			var args = utils.getLeaklessArgs( arguments );
			if ( typeof input !== "object" ) {
				args.splice( 1, 1, inputDef );
			}
			clientMeta.currentActionArgs = args.slice( 1 );
			var currentState = clientMeta.state;
			var stateObj = this.states[ currentState ];
			var handlerName;
			var handler;
			var isCatchAll = false;
			var child;
			var result;
			var action;
			if ( !clientMeta.inExitHandler ) {
				child = this.configForState( currentState );
				if ( child && !this.pendingDelegations[ inputDef.ticket ] && !inputDef.bubbling ) {
					inputDef.ticket = ( inputDef.ticket || utils.createUUID() );
					inputDef.delegated = true;
					this.pendingDelegations[ inputDef.ticket ] = { delegatedTo: child.namespace };
					// WARNING - returning a value from `handle` on child FSMs is not really supported.
					// If you need to return values from child FSM input handlers, use events instead.
					result = child.handle.apply( child, args );
				} else {
					if ( inputDef.ticket && this.pendingDelegations[ inputDef.ticket ] ) {
						delete this.pendingDelegations[ inputDef.ticket ];
					}
					handlerName = stateObj[ inputDef.inputType ] ? inputDef.inputType : "*";
					isCatchAll = ( handlerName === "*" );
					handler = ( stateObj[ handlerName ] || this[ handlerName ] ) || this[ "*" ];
					action = clientMeta.state + "." + handlerName;
					clientMeta.currentAction = action;
					var eventPayload = this.buildEventPayload(
						client,
						{ inputType: inputDef.inputType, delegated: inputDef.delegated, ticket: inputDef.ticket }
					);
					if ( !handler ) {
						this.emit( events.NO_HANDLER, _.extend( { args: args }, eventPayload ) );
					} else {
						this.emit( events.HANDLING, eventPayload );
						if ( typeof handler === "function" ) {
							result = handler.apply( this, this.getHandlerArgs( args, isCatchAll ) );
						} else {
							result = handler;
							this.transition( client, handler );
						}
						this.emit( events.HANDLED, eventPayload );
					}
					clientMeta.priorAction = clientMeta.currentAction;
					clientMeta.currentAction = "";
					clientMeta.currentActionArgs = undefined;
				}
			}
			return result;
		},
	
		transition: function( client, newState ) {
			var clientMeta = this.ensureClientMeta( client );
			var curState = clientMeta.state;
			var curStateObj = this.states[ curState ];
			var newStateObj = this.states[ newState ];
			var child;
			var args = utils.getLeaklessArgs( arguments ).slice( 2 );
			if ( !clientMeta.inExitHandler && newState !== curState ) {
				if ( newStateObj ) {
					child = this.configForState( newState );
					if ( curStateObj && curStateObj._onExit ) {
						clientMeta.inExitHandler = true;
						curStateObj._onExit.call( this, client );
						clientMeta.inExitHandler = false;
					}
					clientMeta.targetReplayState = newState;
					clientMeta.priorState = curState;
					clientMeta.state = newState;
					var eventPayload = this.buildEventPayload( client, {
						fromState: clientMeta.priorState,
						action: clientMeta.currentAction,
						toState: newState
					} );
					this.emit( events.TRANSITION, eventPayload );
					if ( newStateObj._onEnter ) {
						newStateObj._onEnter.apply( this, this.getSystemHandlerArgs( args, client ) );
						this.emit( events.TRANSITIONED, eventPayload );
					}
					if ( child ) {
						child.handle( client, "_reset" );
					}
	
					if ( clientMeta.targetReplayState === newState ) {
						this.processQueue( client, events.NEXT_TRANSITION );
					}
					return;
				}
				this.emit( events.INVALID_STATE, this.buildEventPayload( client, {
					state: clientMeta.state,
					attemptedState: newState
				} ) );
			}
		},
	
		deferUntilTransition: function( client, stateName ) {
			var clientMeta = this.ensureClientMeta( client );
			if ( clientMeta.currentActionArgs ) {
				var queued = {
					type: events.NEXT_TRANSITION,
					untilState: stateName,
					args: clientMeta.currentActionArgs
				};
				clientMeta.inputQueue.push( queued );
				var eventPayload = this.buildEventPayload( client, {
					state: clientMeta.state,
					queuedArgs: queued
				} );
				this.emit( events.DEFERRED, eventPayload );
			}
		},
	
		deferAndTransition: function( client, stateName ) {
			this.deferUntilTransition( client, stateName );
			this.transition( client, stateName );
		},
	
		processQueue: function( client ) {
			var clientMeta = this.ensureClientMeta( client );
			var filterFn = function( item ) {
				return ( ( !item.untilState ) || ( item.untilState === clientMeta.state ) );
			};
			var toProcess = _.filter( clientMeta.inputQueue, filterFn );
			clientMeta.inputQueue = _.difference( clientMeta.inputQueue, toProcess );
			_.each( toProcess, function( item ) {
				this.handle.apply( this, [ client ].concat( item.args ) );
			}, this );
		},
	
		clearQueue: function( client, name ) {
			var clientMeta = this.ensureClientMeta( client );
			if ( !name ) {
				clientMeta.inputQueue = [];
			} else {
				var filter = function( evnt ) {
					return ( name ? evnt.untilState !== name : true );
				};
				clientMeta.inputQueue = _.filter( clientMeta.inputQueue, filter );
			}
		},
	
		compositeState: function( client ) {
			var clientMeta = this.ensureClientMeta( client );
			var state = clientMeta.state;
			var child = this.states[state]._child && this.states[state]._child.instance;
			if ( child ) {
				state += "." + child.compositeState( client );
			}
			return state;
		}
	}, emitter.getInstance() );
	
	BehavioralFsm.extend = utils.extend;
	
	module.exports = BehavioralFsm;


/***/ }
/******/ ])
});
;

},{"lodash":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/lodash/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-log/index.js":[function(require,module,exports){
'use strict';

var manticore = require('manticore');

/**
 * Common logging framework for the SDK. You can pass a string,
 * or use an es6 template INSIDE a function (for best performance).
 * @example
 * // Simple string logging
 * Log.debug('Hello World');
 * @example
 * // Use a template but only evaluate the template when logging is enabled
 * Log.debug(() => `Hello ${world}`);
 * @private
 */

var Level = {
    DEBUG: 'DEBUG',
    INFO: 'INFO',
    WARN: 'WARN',
    ERROR: 'ERROR'
};

var Ranks = {
    DEBUG: 1,
    INFO: 2,
    WARN: 3,
    ERROR: 4,
    QUIET: 5
};

var Names = {
    1: 'DEBUG',
    2: 'INFO',
    3: 'WARN',
    4: 'ERROR',
    5: 'QUIET'
};

function manticoreLogger(level, component, message, extraData) {
    manticore.log(level, component.name, message, extraData);
}

// There's probably a smarter way to do this, but at least this is better
// than rampant strings
var RootLogger = {
    name: '*',
    level: 'DEBUG',
    children: {}
}, LogWriters = [manticoreLogger];

function componentLogger(component) {
    var loggers = component.split('.'), myComponent = RootLogger, parent = RootLogger, name;
    for (var i = 0; i < loggers.length; i++) {
        if (name) {
            name += '.' + loggers[i];
        } else {
            name = loggers[i];
        }
        if (!myComponent.children[loggers[i]]) {
            myComponent.children[loggers[i]] = {name: name, children: {}, parent: parent};
        }
        myComponent = myComponent.children[loggers[i]];
        parent = myComponent;
    }
    var closure = {
        debug: function debug(item, extraData) {
            log(Ranks.DEBUG, myComponent, item, extraData);
        },
        info: function info(item, extraData) {
            log(Ranks.INFO, myComponent, item, extraData);
        },
        warn: function warn(item, extraData) {
            log(Ranks.WARN, myComponent, item, extraData);
        },
        error: function error(item, extraData) {
            log(Ranks.ERROR, myComponent, item, extraData);
        },
        withContext: function loggerWithBaseData(context) {
            return makeContextualLogger(closure, context);
        },
        Config: myComponent,
        Root: RootLogger
    };
    return closure;
}

function makeContextualLogger(baseLogger, context) {
    var closure = {
        context: context,
        debug: function debug(item, extraData) {
            baseLogger.debug(item, extend(extraData, context));
        },
        info: function info(item, extraData) {
            baseLogger.info(item, extend(extraData, context));
        },
        warn: function warn(item, extraData) {
            baseLogger.warn(item, extend(extraData, context));
        },
        error: function error(item, extraData) {
            baseLogger.error(item, extend(extraData, context));
        },
        withContext: function loggerWithBaseData(context) {
            return makeContextualLogger(closure, context);
        },
        Config: baseLogger.Config,
        Root: RootLogger
    };
    return closure;
}

function extend(dest, src) {
    if (!dest && !src) {
        return null;
    } else if (!dest || !src) {
        return dest || src;
    }
    for (var prop in src) {
        if (!Object.prototype.hasOwnProperty.call(dest, prop)) {
            dest[prop] = src[prop];
        }
    }
    return dest;
}

module.exports = componentLogger;

/**
 * You can build your own hierarchy by passing some other "Root" object as parent.
 * Otherwise we're configuring from RootLogger and then using levelFor
 * @param json Configuration specification for the log subsystem
 * @param parent Typically null, and we will configure the RootLogger.
 */
function configLogging(json, parent) {
    parent = parent || RootLogger;
    for (var c in json) {
        var v = json[c];
        var component = parent.children[c];
        if (!component) {
            component = parent.children[c] = {};
        }
        component.name = v.name || c;
        component.parent = parent;
        component.children = component.children || {};
        if (v.level) {
            component.level = v.level;
        } else {
            delete component.level;
        }
        if (v.children) {
            configLogging(v.children, component);
        }
    }
}

module.exports.configure = configLogging;
module.exports.Config = module.exports.Root = RootLogger;
module.exports.Level = Level;
module.exports.Ranks = Ranks;

/**
 * Add a function that will be "cc'ed" on log messages. Only messages that
 * are configured to be logged will make it to this function (i.e. we still
 * check log levels and such)
 */
module.exports.addLogger = function (fn) {
    LogWriters.push(fn);
};

module.exports.removeLogger = function (fn) {
    var ix = LogWriters.indexOf(fn);
    if (ix >= 0) {
        LogWriters.splice(ix, 1);
    }
};

function log(level, component, fnOrString, extraData) {
    var configuredLevel = levelFor(component);
    if (level >= configuredLevel) {
        if (typeof(fnOrString) === 'function') {
            fnOrString = fnOrString();
        }
        fnOrString = fnOrString.toString();
        var levelName = Names[level];
        for (var eli = 0, len = LogWriters.length; eli < len; eli++) {
            LogWriters[eli](levelName, component, fnOrString, extraData);
        }
    }
}

function levelFor(component) {
    // We will walk up the chain and pick the first level we find,
    // which should always terminate at the RootLogger, but just in case you mess with us...
    var c = component, configuredLevel;
    while (c && !(configuredLevel = c.level)) {
        c = c.parent;
    }
    return Ranks[configuredLevel || RootLogger.level] || 0;
}

module.exports.levelFor = levelFor;
},{"manticore":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore/browser.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-paypalerror/build/index.js":[function(require,module,exports){
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _PayPalError = require('./src/PayPalError');

Object.defineProperty(exports, 'PayPalError', {
  enumerable: true,
  get: function get() {
    return _interopRequireDefault(_PayPalError).default;
  }
});

var _PayPalErrorInfo = require('./src/PayPalErrorInfo');

Object.defineProperty(exports, 'PayPalErrorInfo', {
  enumerable: true,
  get: function get() {
    return _interopRequireDefault(_PayPalErrorInfo).default;
  }
});

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
},{"./src/PayPalError":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-paypalerror/build/src/PayPalError.js","./src/PayPalErrorInfo":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-paypalerror/build/src/PayPalErrorInfo.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-paypalerror/build/src/PayPalError.js":[function(require,module,exports){
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

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; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

// SEE README.md for proper usage from JS
/**
 * A common base class for PayPal related errors which includes a debugId and code.
 * This id will be filled out if the error was generated from the PayPal servers.
 * @class
 * @property {string} domain The subsystem responsible for this error, in which the code
 *  should uniquely identify the type of error that has occurred
 * @property {string} code A non-localized code for this error
 * @property {string} message The explanation of the error
 * @property {string} debugId A server-generated identifier used by PayPal to
 *  help diagnose this error
 * @property {string} developerMessage A developer friendly, user unfriendly
 *  message for log statements to give you as much info as possible.
 */
var PayPalError = function () {

  /**
   * Native can't make these
   * @private
   */
  function PayPalError() {
    _classCallCheck(this, PayPalError);

    throw new Error('Do no construct PayPalError.');
  }

  /**
   * Equality comparison
   * @param {PayPalError} paypalError error object
   */


  _createClass(PayPalError, [{
    key: 'equals',
    value: function equals(paypalError) {
      return paypalError && this.domain === paypalError.domain && this.code === paypalError.code;
    }

    /**
     * Decorate an error to include code, domain and a localized message
     * @param {PayPalError} error the error to be decorated or null if a new error should be created
     * @param {PayPalErrorInfo} info the error info
     * @returns {PayPalError}
     */

  }, {
    key: 'withDevMessage',
    value: function withDevMessage(msg) {
      this.developerMessage = msg;
      return this;
    }
  }, {
    key: 'withDebugId',
    value: function withDebugId(id) {
      this.debugId = id;
      return this;
    }
  }], [{
    key: 'makeError',
    value: function makeError(error, info) {
      // TODO: localize the error message
      // let error  = new Error(getLocalizedErrorMessage(code, domain));
      var _error = error || new Error(info.message);
      _error.message = info.message || _error.message;
      _error.code = info.code || _error.code;
      _error.domain = info.domain || _error.domain;
      _error.debugId = info.debugId || _error.debugId;
      _error.developerMessage = info.developerMessage || _error.developerMessage;
      _error.withDevMessage = function (msg) {
        _error.developerMessage = msg;
        return _error;
      };
      _error.withDebugId = function (id) {
        _error.debugId = id;
        return _error;
      };
      _error.equals = function (err) {
        return err && err.domain === _error.domain && err.code === _error.code;
      };
      return _error;
    }
  }]);

  return PayPalError;
}();

exports.default = PayPalError;
},{}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-paypalerror/build/src/PayPalErrorInfo.js":[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

/**
 * A template class for all the properties of the error object
 * @class
 * @property {string} message The error message
 * @property {string} domain The subsystem responsible for this error, in which the code
 *  should uniquely identify the type of error that has occurred
 * @property {string} code A non-localized code for this error
 * @property {string} debugId A server-generated identifier used by PayPal to
 *  help diagnose this error
 * @property {string} developerMessage A developer friendly, user unfriendly
 *  message for log statements to give you as much info as possible.
 */
var PayPalErrorInfo = function PayPalErrorInfo() {
  _classCallCheck(this, PayPalErrorInfo);
};

exports.default = PayPalErrorInfo;
},{}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-util/build/index.js":[function(require,module,exports){
'use strict';

var _typeof2 = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _typeof = typeof Symbol === "function" && _typeof2(Symbol.iterator) === "symbol" ? function (obj) {
  return typeof obj === "undefined" ? "undefined" : _typeof2(obj);
} : function (obj) {
  return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj === "undefined" ? "undefined" : _typeof2(obj);
};

exports.getPropertyName = getPropertyName;
exports.extend = extend;
exports.assignSome = assignSome;
exports.assignExcept = assignExcept;
exports.reverseKeysAndValues = reverseKeysAndValues;
exports.clone = clone;
exports.deepToJSON = deepToJSON;
exports.callbackToPromise = callbackToPromise;
function getPropertyName(obj, propertyVal) {
  var getVal = function getVal(value) {
    for (var prop in obj) {
      if (obj.hasOwnProperty(prop)) {
        if (obj[prop] === value) {
          return prop;
        }
      }
    }
    return null;
  };

  if (Array.isArray(propertyVal)) {
    var result = [];
    var _iteratorNormalCompletion = true;
    var _didIteratorError = false;
    var _iteratorError = undefined;

    try {
      for (var _iterator = propertyVal[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
        var value = _step.value;

        var name = getVal(value);
        if (name) {
          result.push(name);
        }
      }
    } catch (err) {
      _didIteratorError = true;
      _iteratorError = err;
    } finally {
      try {
        if (!_iteratorNormalCompletion && _iterator.return) {
          _iterator.return();
        }
      } finally {
        if (_didIteratorError) {
          throw _iteratorError;
        }
      }
    }

    return result.join();
  }
  return getVal(propertyVal);
}

function extend(dest, src) {
  var overwriteExisting = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;

  for (var prop in src) {
    if (overwriteExisting) {
      dest[prop] = src[prop];
      continue;
    }

    if (!Object.prototype.hasOwnProperty.call(dest, prop)) {
      dest[prop] = src[prop];
    }
  }
  return dest;
}

function assignSome(dest, src, keys) {
  var _iteratorNormalCompletion2 = true;
  var _didIteratorError2 = false;
  var _iteratorError2 = undefined;

  try {
    for (var _iterator2 = keys[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
      var prop = _step2.value;

      if (src.hasOwnProperty(prop)) {
        dest[prop] = src[prop];
      }
    }
  } catch (err) {
    _didIteratorError2 = true;
    _iteratorError2 = err;
  } finally {
    try {
      if (!_iteratorNormalCompletion2 && _iterator2.return) {
        _iterator2.return();
      }
    } finally {
      if (_didIteratorError2) {
        throw _iteratorError2;
      }
    }
  }

  return dest;
}

function assignExcept(dest, src, keys) {
  for (var prop in src) {
    if (prop[0] !== '_' && src.hasOwnProperty(prop) && keys.indexOf(prop) < 0) {
      dest[prop] = src[prop];
    }
  }
  return dest;
}

function reverseKeysAndValues(obj) {
  if (!obj) {
    return obj;
  }
  var newObject = {};
  for (var key in obj) {
    if (obj.hasOwnProperty(key)) {
      newObject[obj[key]] = key;
    }
  }
  return newObject;
}

function clone(obj) {
  var copy = void 0;

  // Handle the 3 simple types, and null or undefined
  if (obj === null || (typeof obj === 'undefined' ? 'undefined' : _typeof(obj)) !== 'object') {
    return obj;
  }

  // Handle Date
  if (obj instanceof Date) {
    copy = new Date();
    copy.setTime(obj.getTime());
    return copy;
  }

  // Handle Array
  if (obj instanceof Array) {
    copy = [];
    for (var i = 0, len = obj.length; i < len; i++) {
      copy[i] = clone(obj[i]);
    }
    return copy;
  }

  // Handle Object
  if (obj instanceof Object) {
    copy = {};
    for (var attr in obj) {
      if (obj.hasOwnProperty(attr)) copy[attr] = clone(obj[attr]);
    }
    return copy;
  }

  throw new Error('Unable to copy obj! Its type isn\'t supported.');
}

// Like doing JSON.parse(JSON.stringify(obj)), but without the string
// serialization/deserialization overhead.
function deepToJSON(obj) {
  // Handle the 3 simple types, and null or undefined
  if (obj === null || (typeof obj === 'undefined' ? 'undefined' : _typeof(obj)) !== 'object') {
    return obj;
  }

  // Handle thing that has a toJSON method
  if (obj && typeof obj.toJSON === 'function') {
    return deepToJSON(obj.toJSON());
  }

  var retVal = void 0;

  // Handle Array
  if (obj instanceof Array) {
    retVal = [];
    for (var i = 0, len = obj.length; i < len; i++) {
      retVal[i] = deepToJSON(obj[i]);
    }
    return retVal;
  }

  // Handle Object
  if (obj instanceof Object) {
    retVal = {};
    for (var attr in obj) {
      if (obj.hasOwnProperty(attr)) retVal[attr] = deepToJSON(obj[attr]);
    }
    return retVal;
  }

  throw new Error('Unable to deepToJSON obj! Its type isn\'t supported.');
}

function callbackToPromise(method) {
  for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
    args[_key - 1] = arguments[_key];
  }

  return new Promise(function (resolve, reject) {
    return method.apply(undefined, args.concat([function (err, result) {
      if (err) {
        reject(err);
      } else {
        resolve(result);
      }
    }]));
  });
}

},{}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore/browser.js":[function(require,module,exports){
module.exports = manticore;
},{}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/md5/md5.js":[function(require,module,exports){
(function(){
  var crypt = require('crypt'),
      utf8 = require('charenc').utf8,
      isBuffer = require('is-buffer'),
      bin = require('charenc').bin,

  // The core
  md5 = function (message, options) {
    // Convert to byte array
    if (message.constructor == String)
      if (options && options.encoding === 'binary')
        message = bin.stringToBytes(message);
      else
        message = utf8.stringToBytes(message);
    else if (isBuffer(message))
      message = Array.prototype.slice.call(message, 0);
    else if (!Array.isArray(message))
      message = message.toString();
    // else, assume byte array already

    var m = crypt.bytesToWords(message),
        l = message.length * 8,
        a =  1732584193,
        b = -271733879,
        c = -1732584194,
        d =  271733878;

    // Swap endian
    for (var i = 0; i < m.length; i++) {
      m[i] = ((m[i] <<  8) | (m[i] >>> 24)) & 0x00FF00FF |
             ((m[i] << 24) | (m[i] >>>  8)) & 0xFF00FF00;
    }

    // Padding
    m[l >>> 5] |= 0x80 << (l % 32);
    m[(((l + 64) >>> 9) << 4) + 14] = l;

    // Method shortcuts
    var FF = md5._ff,
        GG = md5._gg,
        HH = md5._hh,
        II = md5._ii;

    for (var i = 0; i < m.length; i += 16) {

      var aa = a,
          bb = b,
          cc = c,
          dd = d;

      a = FF(a, b, c, d, m[i+ 0],  7, -680876936);
      d = FF(d, a, b, c, m[i+ 1], 12, -389564586);
      c = FF(c, d, a, b, m[i+ 2], 17,  606105819);
      b = FF(b, c, d, a, m[i+ 3], 22, -1044525330);
      a = FF(a, b, c, d, m[i+ 4],  7, -176418897);
      d = FF(d, a, b, c, m[i+ 5], 12,  1200080426);
      c = FF(c, d, a, b, m[i+ 6], 17, -1473231341);
      b = FF(b, c, d, a, m[i+ 7], 22, -45705983);
      a = FF(a, b, c, d, m[i+ 8],  7,  1770035416);
      d = FF(d, a, b, c, m[i+ 9], 12, -1958414417);
      c = FF(c, d, a, b, m[i+10], 17, -42063);
      b = FF(b, c, d, a, m[i+11], 22, -1990404162);
      a = FF(a, b, c, d, m[i+12],  7,  1804603682);
      d = FF(d, a, b, c, m[i+13], 12, -40341101);
      c = FF(c, d, a, b, m[i+14], 17, -1502002290);
      b = FF(b, c, d, a, m[i+15], 22,  1236535329);

      a = GG(a, b, c, d, m[i+ 1],  5, -165796510);
      d = GG(d, a, b, c, m[i+ 6],  9, -1069501632);
      c = GG(c, d, a, b, m[i+11], 14,  643717713);
      b = GG(b, c, d, a, m[i+ 0], 20, -373897302);
      a = GG(a, b, c, d, m[i+ 5],  5, -701558691);
      d = GG(d, a, b, c, m[i+10],  9,  38016083);
      c = GG(c, d, a, b, m[i+15], 14, -660478335);
      b = GG(b, c, d, a, m[i+ 4], 20, -405537848);
      a = GG(a, b, c, d, m[i+ 9],  5,  568446438);
      d = GG(d, a, b, c, m[i+14],  9, -1019803690);
      c = GG(c, d, a, b, m[i+ 3], 14, -187363961);
      b = GG(b, c, d, a, m[i+ 8], 20,  1163531501);
      a = GG(a, b, c, d, m[i+13],  5, -1444681467);
      d = GG(d, a, b, c, m[i+ 2],  9, -51403784);
      c = GG(c, d, a, b, m[i+ 7], 14,  1735328473);
      b = GG(b, c, d, a, m[i+12], 20, -1926607734);

      a = HH(a, b, c, d, m[i+ 5],  4, -378558);
      d = HH(d, a, b, c, m[i+ 8], 11, -2022574463);
      c = HH(c, d, a, b, m[i+11], 16,  1839030562);
      b = HH(b, c, d, a, m[i+14], 23, -35309556);
      a = HH(a, b, c, d, m[i+ 1],  4, -1530992060);
      d = HH(d, a, b, c, m[i+ 4], 11,  1272893353);
      c = HH(c, d, a, b, m[i+ 7], 16, -155497632);
      b = HH(b, c, d, a, m[i+10], 23, -1094730640);
      a = HH(a, b, c, d, m[i+13],  4,  681279174);
      d = HH(d, a, b, c, m[i+ 0], 11, -358537222);
      c = HH(c, d, a, b, m[i+ 3], 16, -722521979);
      b = HH(b, c, d, a, m[i+ 6], 23,  76029189);
      a = HH(a, b, c, d, m[i+ 9],  4, -640364487);
      d = HH(d, a, b, c, m[i+12], 11, -421815835);
      c = HH(c, d, a, b, m[i+15], 16,  530742520);
      b = HH(b, c, d, a, m[i+ 2], 23, -995338651);

      a = II(a, b, c, d, m[i+ 0],  6, -198630844);
      d = II(d, a, b, c, m[i+ 7], 10,  1126891415);
      c = II(c, d, a, b, m[i+14], 15, -1416354905);
      b = II(b, c, d, a, m[i+ 5], 21, -57434055);
      a = II(a, b, c, d, m[i+12],  6,  1700485571);
      d = II(d, a, b, c, m[i+ 3], 10, -1894986606);
      c = II(c, d, a, b, m[i+10], 15, -1051523);
      b = II(b, c, d, a, m[i+ 1], 21, -2054922799);
      a = II(a, b, c, d, m[i+ 8],  6,  1873313359);
      d = II(d, a, b, c, m[i+15], 10, -30611744);
      c = II(c, d, a, b, m[i+ 6], 15, -1560198380);
      b = II(b, c, d, a, m[i+13], 21,  1309151649);
      a = II(a, b, c, d, m[i+ 4],  6, -145523070);
      d = II(d, a, b, c, m[i+11], 10, -1120210379);
      c = II(c, d, a, b, m[i+ 2], 15,  718787259);
      b = II(b, c, d, a, m[i+ 9], 21, -343485551);

      a = (a + aa) >>> 0;
      b = (b + bb) >>> 0;
      c = (c + cc) >>> 0;
      d = (d + dd) >>> 0;
    }

    return crypt.endian([a, b, c, d]);
  };

  // Auxiliary functions
  md5._ff  = function (a, b, c, d, x, s, t) {
    var n = a + (b & c | ~b & d) + (x >>> 0) + t;
    return ((n << s) | (n >>> (32 - s))) + b;
  };
  md5._gg  = function (a, b, c, d, x, s, t) {
    var n = a + (b & d | c & ~d) + (x >>> 0) + t;
    return ((n << s) | (n >>> (32 - s))) + b;
  };
  md5._hh  = function (a, b, c, d, x, s, t) {
    var n = a + (b ^ c ^ d) + (x >>> 0) + t;
    return ((n << s) | (n >>> (32 - s))) + b;
  };
  md5._ii  = function (a, b, c, d, x, s, t) {
    var n = a + (c ^ (b | ~d)) + (x >>> 0) + t;
    return ((n << s) | (n >>> (32 - s))) + b;
  };

  // Package private blocksize
  md5._blocksize = 16;
  md5._digestsize = 16;

  module.exports = function (message, options) {
    if (message === undefined || message === null)
      throw new Error('Illegal argument ' + message);

    var digestbytes = crypt.wordsToBytes(md5(message, options));
    return options && options.asBytes ? digestbytes :
        options && options.asString ? bin.bytesToString(digestbytes) :
        crypt.bytesToHex(digestbytes);
  };

})();

},{"charenc":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/charenc/charenc.js","crypt":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/crypt/crypt.js","is-buffer":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/is-buffer/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/build/ConnectionFlow.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

var _retailPaymentDevice = require('retail-payment-device');

var _manticoreLog = require('manticore-log');

var _manticoreLog2 = _interopRequireDefault(_manticoreLog);

var _Flow = require('./common/Flow');

var _Flow2 = _interopRequireDefault(_Flow);

var _MiuraTags = require('./MiuraTags');

var _MiuraTags2 = _interopRequireDefault(_MiuraTags);

var _MiuraDeviceUpdate = require('./SoftwareUpdate/MiuraDeviceUpdate');

var _MiuraDeviceUpdate2 = _interopRequireDefault(_MiuraDeviceUpdate);

function _interopRequireDefault(obj) {
  return obj && obj.__esModule ? obj : { default: obj };
}

function _classCallCheck(instance, Constructor) {
  if (!(instance instanceof Constructor)) {
    throw new TypeError("Cannot call a class as a function");
  }
}

var Log = (0, _manticoreLog2.default)('paymentDevice.miura.connectionFlow');
var FullConnectValidityDurationMs = 8 * 60 * 60 * 1000;

var ConnectionFlow = function () {
  function ConnectionFlow(device) {
    _classCallCheck(this, ConnectionFlow);

    this.device = device;
  }

  ConnectionFlow.prototype.start = function start(callback) {
    var _this = this;

    var flow = new _Flow2.default(this, this._retrieveVersionInfo, this._displayReaderConnectingMessage, this._tryQuickConnect, this._setCardReaderToMerchant, this._getDeviceCapabilities, this._getDeviceConfig, this._queryBackendForSWModules, this._getP2PEStatus, this._getBatteryLevel);

    flow.name = 'Miura Connection';
    flow.on('completed', function (err) {
      if (err) {
        _this.device.display({ id: _retailPaymentDevice.PaymentDevice.Message.ConnectionFailed }, function () {
          callback(err);
        });
        return;
      }
      _this._readerConnected(callback);
    });
    flow.start();
  };

  ConnectionFlow.prototype._readerConnected = function _readerConnected(callback) {
    Log.debug('Completed connection sequence.');
    this.device.display({
      id: _retailPaymentDevice.PaymentDevice.Message.ReadyWithId,
      substitutions: { id: this.device.id },
      displaySystemIcons: true
    }, callback);
  };

  ConnectionFlow.prototype._setCardReaderToMerchant = function _setCardReaderToMerchant(flow) {
    this.device.setCardReaderToMerchant(this.device.serialNumber);
    flow.next();
  };

  ConnectionFlow.prototype._retrieveVersionInfo = function _retrieveVersionInfo(flow) {
    this.device.getFirmwareVersionInfo(function (e) {
      return flow.nextOrAbort(e);
    });
  };

  ConnectionFlow.prototype._displayReaderConnectingMessage = function _displayReaderConnectingMessage(flow) {
    this.device.display({ id: _retailPaymentDevice.PaymentDevice.Message.Connecting }, function () {
      return flow.next();
    });
  };

  ConnectionFlow.prototype._tryQuickConnect = function _tryQuickConnect(flow) {
    if (!this.device.fullConnectionExecutedOn) {
      flow.next();
      return;
    }

    // Allow quick connect for 8 hours
    var msSinceLastFullConnection = Date.now() - this.device.fullConnectionExecutedOn.getTime();
    if (msSinceLastFullConnection < FullConnectValidityDurationMs) {
      Log.info('Skipping the full connection flow. Device was previously fully connected ' + msSinceLastFullConnection + 'ms ago. Will not check for firmware updates');
      flow.completeFlow(); // Quit the execution by passing 'true' instead of error
      return;
    }

    Log.info('Redo a full connection as the device was previously fully connected ' + msSinceLastFullConnection + 'ms ago');
    this.device.fullConnectionExecutedOn = null;
    flow.next();
  };

  ConnectionFlow.prototype._getDeviceCapabilities = function _getDeviceCapabilities(flow) {
    var _this2 = this;

    this.device.terminal.Config.getDeviceCapabilities(function (e, devCaps) {
      if (devCaps && devCaps.caps) {
        _this2.device.capabilities = devCaps.caps;
        Log.debug(function () {
          return 'Device caps: ' + JSON.stringify(devCaps.caps, null, '\t');
        });
      }
      flow.nextOrAbort(e);
    });
  };

  ConnectionFlow.prototype._getDeviceConfig = function _getDeviceConfig(flow) {
    var _this3 = this;

    this.device.terminal.Config.getConfiguration(function (e, config) {
      var error = null;
      if (!e && !config.response.apdu.isSuccess) {
        error = _retailPaymentDevice.deviceError.dataRetrievalFailed.withDevMessage('Failed to get terminal configuration.');
      } else if (config) {
        _this3.device.swInfo = config.caps;
        Log.debug(function () {
          return 'Software Info: ' + JSON.stringify(_this3.device.swInfo, null, '\t');
        });
      }
      flow.nextOrAbort(error);
    });
  };

  ConnectionFlow.prototype._queryBackendForSWModules = function _queryBackendForSWModules(flow) {
    // Avoid rechecking for updates on same device during reconnects
    if (this.exSerial !== this.device.serialNumber || !this.serverSwInfo) {
      // We are just kicking off the fetch here, the result will be stored
      // on the flow. So fetchSWInfoFromServer is not really a "part" of the
      // flow.
      this.exSerial = this.device.serialNumber;
      this._fetchSWInfoFromServer(flow);
    } else {
      flow.next();
    }
  };

  ConnectionFlow.prototype._getP2PEStatus = function _getP2PEStatus(flow) {
    var _this4 = this;

    this.device.terminal.Config.getP2PEStatus(function (e, p2peStatus) {
      if (e) {
        flow.abortFlow(e);
        return;
      }
      var stat = p2peStatus.apdu.tlvs.find(_MiuraTags2.default.MiuraP2PEStatus);
      if (!stat) {
        var error = _retailPaymentDevice.deviceError.dataRetrievalFailed.withDevMessage('Unable to get encryption status for reader.');
        flow.abortFlow(error);
        return;
      }
      stat = stat.bytes[0];
      if (stat & 0x80) {
        _this4.device.p2pe = {
          error: _this4._p2peError(stat)
        };
      } else {
        _this4.device.p2pe = {
          init: !!(stat & 1),
          pin: !!(stat & 2),
          sred: !!(stat & 4)
        };
      }
      _this4.finishedP2PE = true;
      if (_this4.pendedUpdateInstruction) {
        _this4._checkP2PEWithUpdate(_this4.pendedUpdateInstruction, flow);
      } else {
        flow.next();
      }
    });
  };

  ConnectionFlow.prototype._getBatteryLevel = function _getBatteryLevel(flow) {
    var _this5 = this;

    this.device.getBatteryInfo(function (e, batteryInfo) {
      if (!e) {
        _this5.device.fullConnectionExecutedOn = new Date();
        Log.debug(function () {
          return 'Setting fullConnectionExecutedOn to ' + _this5.device.fullConnectionExecutedOn;
        });
        _this5.device.lastKnownBatteryInfo = batteryInfo;
      }
      flow.nextOrAbort(e);
    });
  };

  ConnectionFlow.prototype._checkP2PEWithUpdate = function _checkP2PEWithUpdate(modules, flow) {
    Log.debug('Checking P2PE with update instructions');
    if (_MiuraDeviceUpdate2.default.needsUpdate(this.device, modules)) {
      this.device.updates = modules;
      this.updateRequired = true;
      this._notifyReaderUpdateRequired();
    }
    flow.next();
  };

  ConnectionFlow.prototype._fetchSWInfoFromServer = function _fetchSWInfoFromServer(flow) {
    var _this6 = this;

    var body = this._generateUpdateRequest(this.device);
    this.device.app.getFirmwareUpdates(body, this.device.manufacturer, this.device.model, function (err, rz) {
      _this6.serverSwInfo = rz;
      Log.debug(function () {
        return 'Received firmware update response for this.device: ' + _this6.device;
      });
      if (err || !rz || !rz.body) {
        Log.error('Unable to retrieve firmware update information for ' + _this6.device.id + ', manufacturer=' + _this6.device.manufacturer + ', model=' + _this6.device.model + '. Error: ' + err);
        if (rz && rz.body) {
          Log.warn(JSON.stringify(rz.body, null, '\t'));
        }
        flow.next();
        return;
      }

      if (!_this6.finishedP2PE) {
        Log.debug('Pending update instruction until P2PE is complete.');
        _this6.pendedUpdateInstruction = rz.body && rz.body.modules;
        flow.next();
        return;
      }

      if (rz.statusCode === 304) {
        Log.debug(function () {
          return _this6.device.id + ' Software update not needed';
        });
        flow.next();
        return;
      }

      // TODO this is a bit squirrely because instr.body.phases could be invalid even if status code is !304
      _this6._checkP2PEWithUpdate(rz.body.modules, flow);
    });
  };

  ConnectionFlow.prototype._notifyReaderUpdateRequired = function _notifyReaderUpdateRequired() {
    Log.debug('notifying reader status');
    if (this.device.updates || this.device._isKeyInjectionRequired) {
      Log.info(this.device.id + ' needs update.\nKeyInjectionRequired: ' + this.device._isKeyInjectionRequired + '\nUpdates(Modules: ' + (this.device.updates ? this.device.updates.length : 0) + ')\n' + JSON.stringify(this.device.updates));
      this.device.updateRequired(new _MiuraDeviceUpdate2.default(this.device));
    }
  };

  ConnectionFlow.prototype._generateUpdateRequest = function _generateUpdateRequest(d) {
    var components = [{
      name: 'Miura_OS',
      version: d.os.id + '-' + d.os.ver
    }, {
      name: 'Miura_MPI',
      version: d.mpi.id + '-' + d.mpi.ver
    }];

    for (var k in d.swInfo) {
      if ({}.hasOwnProperty.call(d.swInfo, k)) {
        var ver = d.forceConfigUpdate ? '0.0' : d.swInfo[k];
        components.push({ name: k, version: ver });
      }
    }
    return { components: components };
  };

  ConnectionFlow.prototype._p2peError = function _p2peError(v) {
    switch (v) {
      case 0x81:
        return 'Root Certificate Error';
      case 0x82:
        return 'Product Certificate Error';
      case 0x83:
        return 'Terminal Certificate Error';
      case 0x84:
        return 'Key Signing Key Error';
      case 0x85:
        return 'Internal Error, Contact PayPal';
      default:
        return 'Unknown Error (' + v + ')';
    }
  };

  return ConnectionFlow;
}();

exports.default = ConnectionFlow;

},{"./MiuraTags":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/build/MiuraTags.js","./SoftwareUpdate/MiuraDeviceUpdate":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/build/SoftwareUpdate/MiuraDeviceUpdate.js","./common/Flow":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/build/common/Flow.js","manticore-log":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-log/index.js","retail-payment-device":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/build/MiuraDevice.js":[function(require,module,exports){
'use strict';

var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };

exports.__esModule = true;

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;if ("value" in descriptor) descriptor.writable = true;Object.defineProperty(target, descriptor.key, descriptor);
    }
  }return function (Constructor, protoProps, staticProps) {
    if (protoProps) defineProperties(Constructor.prototype, protoProps);if (staticProps) defineProperties(Constructor, staticProps);return Constructor;
  };
}();

var _manticoreUtil = require('manticore-util');

var Util = _interopRequireWildcard(_manticoreUtil);

var _paypalInvoicing = require('paypal-invoicing');

var _retailPaymentDevice = require('retail-payment-device');

var _manticoreLog = require('manticore-log');

var _manticoreLog2 = _interopRequireDefault(_manticoreLog);

var _tlvlib = require('tlvlib');

var _cardMetadataParser = require('./cardMetadataParser');

var _cardMetadataParser2 = _interopRequireDefault(_cardMetadataParser);

var _deviceState = require('./deviceState');

var _deviceState2 = _interopRequireDefault(_deviceState);

var _ConnectionFlow = require('./ConnectionFlow');

var _ConnectionFlow2 = _interopRequireDefault(_ConnectionFlow);

var _Terminal = require('./Terminal');

var _TerminalStatus = require('./messages/TerminalStatus');

var _TerminalStatus2 = _interopRequireDefault(_TerminalStatus);

var _MiuraTags = require('./MiuraTags');

var _MiuraTags2 = _interopRequireDefault(_MiuraTags);

var _CardStatus = require('./messages/CardStatus');

var _CardStatus2 = _interopRequireDefault(_CardStatus);

function _interopRequireDefault(obj) {
  return obj && obj.__esModule ? obj : { default: obj };
}

function _interopRequireWildcard(obj) {
  if (obj && obj.__esModule) {
    return obj;
  } else {
    var newObj = {};if (obj != null) {
      for (var key in obj) {
        if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];
      }
    }newObj.default = obj;return newObj;
  }
}

function _classCallCheck(instance, Constructor) {
  if (!(instance instanceof Constructor)) {
    throw new TypeError("Cannot call a class as a function");
  }
}

function _possibleConstructorReturn(self, call) {
  if (!self) {
    throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
  }return call && ((typeof call === 'undefined' ? 'undefined' : _typeof(call)) === "object" || typeof call === "function") ? call : self;
}

function _inherits(subClass, superClass) {
  if (typeof superClass !== "function" && superClass !== null) {
    throw new TypeError("Super expression must either be null or a function, not " + (typeof superClass === 'undefined' ? 'undefined' : _typeof(superClass)));
  }subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } });if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;
}

var DeviceMessageId = _retailPaymentDevice.PaymentDevice.Message;
var Log = (0, _manticoreLog2.default)('paymentDevice.miura');
var TerminalMessageId = _retailPaymentDevice.PaymentDevice.Message;

function _parseVersionInfo(id, ver) {
  var parts = ver && ver.match(/(\d+)-(\d+)/);
  var majorVer = parts && parseInt(parts[1], 10);
  var minorVer = parts && parseInt(parts[2], 10);

  return {
    id: id,
    ver: ver,
    majorVer: majorVer,
    minorVer: minorVer
  };
}

/**
 * Represents an EMV payment terminal manufactured by Miura for PayPal
 * @class
 * @protected
 */

var MiuraDevice = function (_PaymentDevice) {
  _inherits(MiuraDevice, _PaymentDevice);

  /**
   * Construct a new PaymentDevice given a native function capable of sending data to the device
   */
  function MiuraDevice(uniqueId, nativeInterface, appInterface, isUsb, hardwareAddress) {
    _classCallCheck(this, MiuraDevice);

    var _this = _possibleConstructorReturn(this, _PaymentDevice.call(this, uniqueId, nativeInterface, appInterface, isUsb, hardwareAddress));

    _this.manufacturer = _retailPaymentDevice.deviceManufacturer.miura;
    _this.terminal = new _Terminal.Terminal(function (buf, cb) {
      return _this.native.send(buf, cb);
    }, _this);
    _this.terminal.isUsb = isUsb;
    _this.terminal.on(_Terminal.TerminalEvent.deviceEvent, function (m) {
      return _this._deviceEvent(m);
    });
    _this.terminal.on(_Terminal.TerminalEvent.cardPresented, function (card) {
      var ffName = Util.getPropertyName(_retailPaymentDevice.FormFactor, card.formFactor);
      if (!_this.isFormFactorActive(card.formFactor)) {
        Log.warn('Reader not activated for \'' + ffName + '\'. Will ignore presented card event');
        return;
      }

      Log.debug(function () {
        return 'Card presented using form factor: \'' + ffName + '\'';
      });
      card.reader = _this;
      if (card.formFactor === _retailPaymentDevice.FormFactor.MagneticCardSwipe) {
        _this._inTransactionState = card && card.lastFourDigits;
        _this.emit(_retailPaymentDevice.PaymentDevice.Event.cardPresented, null, _retailPaymentDevice.CardPresentEvent.cardDataRead, _retailPaymentDevice.FormFactor.MagneticCardSwipe, { card: card });
        return;
      }

      if (card.formFactor === _retailPaymentDevice.FormFactor.Chip) {
        Log.debug(function () {
          return 'Card insert detected on ' + _this.id + '. Will read EMV data from presented card';
        });
        _this.cardInSlot = true;
        if (_this.cardInsertedHandler) {
          Log.debug(function () {
            return 'Invoke CardInsertHandler: ' + _this.context.id;
          });
          _this.cardInsertedHandler(new _retailPaymentDevice.CardInsertedHandler(function () {
            _this.emit(_retailPaymentDevice.PaymentDevice.Event.cardPresented, null, _retailPaymentDevice.CardPresentEvent.insertDetected, _retailPaymentDevice.FormFactor.Chip);
            Log.debug(function () {
              return 'Continue CardDataRead: ' + _this.context.id;
            });
            _this._readCardData(card, _this.context);
          }));
        } else {
          Log.debug(function () {
            return 'No card inserted handler was registered... Will continue to read card data for ' + _this.context.id;
          });
          _this.emit(_retailPaymentDevice.PaymentDevice.Event.cardPresented, null, _retailPaymentDevice.CardPresentEvent.insertDetected, _retailPaymentDevice.FormFactor.Chip);
          _this._readCardData(card, _this.context);
        }
      }
    });

    _this.terminal.on(_Terminal.TerminalEvent.cardRemoved, function () {
      _this.cardInSlot = false;
      _this.emit(_retailPaymentDevice.PaymentDevice.Event.cardRemoved);
    });
    _this.terminal.on(_Terminal.TerminalEvent.error, function (err, ff) {
      return _this.emit(_retailPaymentDevice.PaymentDevice.Event.cardPresented, err, _retailPaymentDevice.CardPresentEvent.cardDataRead, ff);
    });
    _this.model = _retailPaymentDevice.ReaderModel.M010;
    _this.type = _retailPaymentDevice.readerType.Emv;
    _this.connectionType = _retailPaymentDevice.readerConnectionType.Bluetooth;
    return _this;
  }

  MiuraDevice.prototype.listenForCardRemoval = function listenForCardRemoval(callback) {
    callback();
  };

  MiuraDevice.prototype.beginDeviceRemoved = function beginDeviceRemoved(callback) {
    this.native.removed(callback);
  };

  MiuraDevice.prototype.beginDeviceConnect = function beginDeviceConnect(callback) {
    var _this2 = this;

    if (this.native.isConnected()) {
      this.removeState(_deviceState2.default.hardResetting);
      Log.debug(function () {
        return 'Connect called, but ' + _this2.id + ' is already connected.';
      });
      callback();
      return;
    }
    Log.debug(function () {
      return 'Connecting to Miura device ' + _this2.id;
    });
    this.native.connect(function (error) {
      if (error) {
        callback(error);
        return;
      }
      _this2.removeState(_deviceState2.default.hardResetting);
      _this2.terminal.didConnect();
      new _ConnectionFlow2.default(_this2).start(callback);
    });
  };

  MiuraDevice.prototype.beginDeviceDisconnect = function beginDeviceDisconnect(callback) {
    var _this3 = this;

    if (!this.isConnected()) {
      Log.debug('Device already disconnected. Will not attempt to invoke native.disconnect');
      callback(null);
      return;
    }

    if (this.isUsb) {
      this.display({ id: DeviceMessageId.NotConnected }, function () {
        _this3.native.disconnect(callback);
      }, true);
    } else {
      this.native.disconnect(callback);
    }
  };

  MiuraDevice.prototype.getVersionInfo = function getVersionInfo() {
    var os = this.os ? this.os.id + '-' + this.os.ver : '';
    var mpi = this.mpi ? this.mpi.id + '-' + this.mpi.ver : '';
    return { os: os, mpi: mpi };
  };

  MiuraDevice.prototype.received = function received(data) {
    this.terminal.received(data);
  };

  MiuraDevice.prototype.display = function display(opt, callback) {
    if (!this.isConnected()) {
      if (callback) {
        callback(_retailPaymentDevice.deviceError.deviceNotConnected);
      }
      return;
    }

    if (this.model === _retailPaymentDevice.ReaderModel.M003) {
      if (callback) {
        callback();
        return;
      }
    }

    this.terminal.display(opt.id, opt.substitutions, callback, opt.displaySystemIcons);
  };

  MiuraDevice.prototype.displayAsync = function displayAsync(opt) {
    return regeneratorRuntime.async(function displayAsync$(_context) {
      while (1) {
        switch (_context.prev = _context.next) {
          case 0:
            if (this.isConnected()) {
              _context.next = 4;
              break;
            }

            throw _retailPaymentDevice.deviceError.deviceNotConnected;

          case 4:
            if (!(this.model === _retailPaymentDevice.ReaderModel.M003)) {
              _context.next = 6;
              break;
            }

            return _context.abrupt('return');

          case 6:
            _context.next = 8;
            return regeneratorRuntime.awrap(this.terminal.displayAsync(opt.id, opt.substitutions, opt.displaySystemIcons));

          case 8:
          case 'end':
            return _context.stop();
        }
      }
    }, null, this);
  };

  MiuraDevice.prototype.requestForTip = function requestForTip(invoice) {
    return regeneratorRuntime.async(function requestForTip$(_context2) {
      while (1) {
        switch (_context2.prev = _context2.next) {
          case 0:
            _context2.next = 2;
            return regeneratorRuntime.awrap(this._msgPrompts(_retailPaymentDevice.PaymentDevice.Message.RequestTip, invoice));

          case 2:
          case 'end':
            return _context2.stop();
        }
      }
    }, null, this);
  };

  MiuraDevice.prototype.confirmTip = function confirmTip(invoice) {
    return regeneratorRuntime.async(function confirmTip$(_context3) {
      while (1) {
        switch (_context3.prev = _context3.next) {
          case 0:
            _context3.next = 2;
            return regeneratorRuntime.awrap(this._msgPrompts(_retailPaymentDevice.PaymentDevice.Message.ConfirmTip, invoice));

          case 2:
          case 'end':
            return _context3.stop();
        }
      }
    }, null, this);
  };

  MiuraDevice.prototype.promptForTip = function promptForTip(amountBasedTip) {
    return regeneratorRuntime.async(function promptForTip$(_context4) {
      while (1) {
        switch (_context4.prev = _context4.next) {
          case 0:
            _context4.next = 2;
            return regeneratorRuntime.awrap(this.terminal.promptForTipEntry(amountBasedTip));

          case 2:
            return _context4.abrupt('return', _context4.sent);

          case 3:
          case 'end':
            return _context4.stop();
        }
      }
    }, null, this);
  };

  MiuraDevice.prototype.abortTipping = function abortTipping() {
    return regeneratorRuntime.async(function abortTipping$(_context5) {
      while (1) {
        switch (_context5.prev = _context5.next) {
          case 0:
            _context5.next = 2;
            return regeneratorRuntime.awrap(this.terminal.abortTransactionAsync());

          case 2:
          case 'end':
            return _context5.stop();
        }
      }
    }, null, this);
  };

  MiuraDevice.prototype._msgPrompts = function _msgPrompts(messageId, invoice) {
    return regeneratorRuntime.async(function _msgPrompts$(_context6) {
      while (1) {
        switch (_context6.prev = _context6.next) {
          case 0:
            _context6.next = 2;
            return regeneratorRuntime.awrap(this.terminal.registerForKeyboardEventsAsync(true));

          case 2:
            _context6.next = 4;
            return regeneratorRuntime.awrap(this.displayAsync({
              id: messageId,
              substitutions: { amount: _paypalInvoicing.Currency.format(invoice.currency, invoice.total) }
            }));

          case 4:
          case 'end':
            return _context6.stop();
        }
      }
    }, null, this);
  };

  MiuraDevice.prototype.doesHaveCapability = function doesHaveCapability(capability) {
    switch (capability) {
      case _retailPaymentDevice.deviceCapabilityType.display:
        return this.model === _retailPaymentDevice.ReaderModel.M010;
      case _retailPaymentDevice.deviceCapabilityType.contactless:
        return this.model === _retailPaymentDevice.ReaderModel.M010;
      default:
        return false;
    }
  };

  MiuraDevice.prototype.getFirmwareVersionInfo = function getFirmwareVersionInfo(callback) {
    var _this4 = this;

    this.terminal.softReset(function (e, rz) {
      if (e) {
        callback(e);
        return;
      }

      var serialNumberTag = rz.tlvs && rz.tlvs.find(_tlvlib.Tags.InterfaceDeviceSerialNumber);
      if (!serialNumberTag) {
        callback(_retailPaymentDevice.deviceError.dataRetrievalFailed.withDevMessage('Failed to get serial number from ' + _this4.id));
        return;
      }

      _this4.serialNumber = serialNumberTag.parse();
      var firstThree = _this4.serialNumber.substring(0, 3);
      if (firstThree === '130' || firstThree === '030') {
        _this4.model = _retailPaymentDevice.ReaderModel.M003;
      }

      for (var _iterator = rz.tlvs.values, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
        var _ref;

        if (_isArray) {
          if (_i >= _iterator.length) break;
          _ref = _iterator[_i++];
        } else {
          _i = _iterator.next();
          if (_i.done) break;
          _ref = _i.value;
        }

        var tlv = _ref;

        if (tlv.tagNumber === _MiuraTags2.default.MiuraSoftwareInformation.number) {
          _this4._readConfigPair(tlv);
        }
      }

      _this4.pre76 = _this4.os && (_this4.os.majorVer < 7 || _this4.os.majorVer === 7 && _this4.os.minorVer <= 5);
      Log.info('Version: ' + _this4.id + ' Serial #: ' + _this4.serialNumber + ' OS: ' + (_this4.os && _this4.os.id + ', ' + _this4.os.ver) + ' MPI: ' + (_this4.mpi && _this4.mpi.id + ', ' + _this4.mpi.ver) + ' pre76: ' + _this4.pre76);
      callback(null, { mpi: _this4.mpi, os: _this4.os });
    });
  };

  MiuraDevice.prototype.extractReaderLogs = function extractReaderLogs(callback) {
    Log.debug('Extracting log file from reader');
    this.terminal.Config.getLogFile(function (err, buff) {
      Log[err ? 'error' : 'debug'](function () {
        return 'Miura log getFile complete. err: ' + err + ' Logs: ' + buff;
      });
      callback(err);
    });
  };

  MiuraDevice.prototype.activateForPayment = function activateForPayment(context, formFactors, showPrompt) {
    var _this5 = this;

    if (this._inTransactionState) {
      Log.info('Transaction was previously activated/has not ended yet. Will ignore this activate call');
      return;
    }

    Log.debug(function () {
      return 'Activating \'' + _this5.id + '\' for formFactors: ' + formFactors + '. ' + context.id;
    });
    _PaymentDevice.prototype.activateForPayment.call(this, context, formFactors, showPrompt);
    var errCardEvents = void 0;
    var errKeyboardEvents = void 0;
    this.terminal.registerForCardEvents(true, function (err) {
      errCardEvents = err;
      if (errCardEvents) {
        Log.error('Failed to register for Miura card events: ' + errCardEvents.message);
        _PaymentDevice.prototype.deactivateFormFactors.call(_this5, [_retailPaymentDevice.FormFactor.Chip, _retailPaymentDevice.FormFactor.MagneticCardSwipe]);
        _this5.emit(_retailPaymentDevice.PaymentDevice.Event.cardPresented, errCardEvents, _retailPaymentDevice.CardPresentEvent.cardDataRead);
      } else {
        Log.debug(function () {
          return context.id + ' Registered for card events';
        });
      }
    });
    this.terminal.registerForKeyboardEvents(true, function (err) {
      errKeyboardEvents = err;
      if (errKeyboardEvents) {
        Log.error('Failed to register for Miura keyboard events: ' + errKeyboardEvents.message);
        _this5.emit(_retailPaymentDevice.PaymentDevice.Event.cardPresented, errKeyboardEvents, _retailPaymentDevice.CardPresentEvent.cardDataRead);
      } else {
        Log.debug(function () {
          return context.id + ' Registered for keyboard events';
        });
      }
    });

    var ff = new Set(formFactors);
    if (ff.has(_retailPaymentDevice.FormFactor.EmvCertifiedContactless)) {
      this._startContactlessTx(context);
      return;
    }

    if (!showPrompt) {
      return;
    }
    var messageId = void 0;
    if (ff.has(_retailPaymentDevice.FormFactor.MagneticCardSwipe) && ff.has(_retailPaymentDevice.FormFactor.Chip)) {
      messageId = TerminalMessageId.ReadyForInsertAndSwipePayment;
    } else if (ff.has(_retailPaymentDevice.FormFactor.MagneticCardSwipe)) {
      messageId = TerminalMessageId.ReadyForSwipePayment;
    } else if (ff.has(_retailPaymentDevice.FormFactor.Chip)) {
      messageId = TerminalMessageId.ReadyForInsertPayment;
    }

    if (!messageId) {
      return;
    }

    var invoice = context.invoice;
    var displayOpt = {
      id: messageId,
      substitutions: { amount: _paypalInvoicing.Currency.format(invoice.currency, invoice.total) }
    };
    this.display(displayOpt, function (err) {
      if (err) {
        Log.error('Unable to push message ' + messageId + ' to terminal');
      }
    });
  };

  MiuraDevice.prototype.selectPaymentApplication = function selectPaymentApplication(appId, card) {
    var _this6 = this;

    this.terminal.selectApplication(appId, function (err, rz) {
      if (err) {
        _this6.emit(_retailPaymentDevice.PaymentDevice.Event.cardPresented, err, _retailPaymentDevice.CardPresentEvent.cardDataRead, _retailPaymentDevice.FormFactor.Chip);
        return;
      }
      Log.debug(function () {
        return 'Received ICC response from Application select (formFactor: ' + Util.getPropertyName(_retailPaymentDevice.FormFactor, card.formFactor) + ') ' + rz;
      });
      var cardMetadata = (0, _cardMetadataParser2.default)(card.formFactor, rz);
      Util.extend(card, cardMetadata, true);
      Log.debug(function () {
        return 'Card object updated with emv response: ' + card;
      });
      _this6._inTransactionState = true;
      _this6.emit(_retailPaymentDevice.PaymentDevice.Event.cardPresented, null, _retailPaymentDevice.CardPresentEvent.cardDataRead, card.formFactor, { card: card });
    });
  };

  MiuraDevice.prototype.completeTransaction = function completeTransaction(authCode, callback) {
    var _this7 = this;

    if (!this.isConnected()) {
      if (callback) {
        callback(_retailPaymentDevice.deviceError.deviceNotConnected);
      }
      return;
    }
    this.terminal.continueTransaction(authCode, function (err, rz) {
      _this7._inTransactionState = false;
      if (callback) {
        callback(err, rz);
      }
    });
  };

  MiuraDevice.prototype.deactivateFormFactors = function deactivateFormFactors(formFactors, callback) {
    var _this8 = this;

    if (!formFactors || formFactors.length === 0) {
      if (callback) {
        callback();
      }
      return;
    }

    _PaymentDevice.prototype.deactivateFormFactors.call(this, formFactors);
    Log.debug(function () {
      return 'Deactivating form factors [' + Util.getPropertyName(_retailPaymentDevice.FormFactor, formFactors) + '] on \'' + _this8.id + '\'. Tx State: ' + _this8._inTransactionState;
    });
    if (this._inTransactionState) {
      this._inTransactionState = false;
      this.terminal.abortTransaction(function () {
        Log.debug(function () {
          return 'Aborted contactless tx on ' + _this8.id;
        });
      });
    } else {
      Log.debug(function () {
        return 'Device not in transaction state... Will not send abort to ' + _this8.id;
      });
    }

    var sFormFactors = new Set(formFactors);
    if (sFormFactors.has(_retailPaymentDevice.FormFactor.MagneticCardSwipe) || sFormFactors.has(_retailPaymentDevice.FormFactor.Chip)) {
      this.terminal.registerForCardEvents(false, function () {
        Log.debug(function () {
          return 'Deactivated swipe and chip on ' + _this8.id;
        });
      });
    }

    if (callback) {
      callback();
    }
  };

  MiuraDevice.prototype.abortTransaction = function abortTransaction(context, callback) {
    var _this9 = this;

    Log.debug(function () {
      return 'Aborting tx on \'' + _this9.id + '\'';
    });
    _PaymentDevice.prototype.abortTransaction.call(this, context);
    if (!this.isConnected()) {
      if (callback) {
        callback();
      }
    } else {
      this.deactivateFormFactors([_retailPaymentDevice.FormFactor.EmvCertifiedContactless], callback);
    }
  };

  MiuraDevice.prototype.postTransactionCleanup = function postTransactionCleanup(callback) {
    Log.debug('Soft-resetting the terminal as part of post-transaction cleanup');
    this.terminal.softReset(function (err) {
      callback(err);
    });
  };

  MiuraDevice.prototype.getBatteryInfo = function getBatteryInfo(callback) {
    if (this.hasState(_deviceState2.default.softwareUpdate)) {
      if (callback) {
        callback(_retailPaymentDevice.deviceError.cannotAcceptMessage);
      }
      return;
    }

    // Do not check if Device is connected as re-establishing a connection after software reset depends on pinging for
    // battery level at all times
    this.terminal.getBatteryLevel(function (err, batteryInfo) {
      if (err) {
        Log.error('Could not retrieve battery info. Error: ' + err);
      } else {
        Log.debug(function () {
          return 'Received battery information ' + batteryInfo;
        });
      }
      if (callback) {
        callback(err, batteryInfo);
      }
    });
  };

  /**
   * Returns true if the device is in a state to accept commands
   */

  MiuraDevice.prototype.canPushCommands = function canPushCommands() {
    var _this10 = this;

    if (!this.isConnected()) {
      Log.debug(function () {
        return 'Cannot push command to ' + _this10.id + ' as it is not connected';
      });
      return false;
    }

    if (this.hasState(_deviceState2.default.hardResetting)) {
      Log.debug(function () {
        return 'Cannot push command to ' + _this10.id + ' as it is in a hard reset state';
      });
      return false;
    }

    return true;
  };

  MiuraDevice.prototype._startContactlessTx = function _startContactlessTx(context) {
    var _this11 = this;

    var invoice = context.invoice;
    this._inTransactionState = true;
    var transactionType = context.type === _retailPaymentDevice.TransactionType.Sale || context.type === _retailPaymentDevice.TransactionType.Auth ? 0 : 20;
    var amount = context.isRefund() ? context.refundAmount : invoice.total;
    this.terminal.startContactlessTransaction(0, transactionType, _paypalInvoicing.Currency.toCents(invoice.currency, amount), _paypalInvoicing.Currency.getCurrency(invoice.currency).iso4217, function (err, clResult) {
      _this11._inTransactionState = false;
      if (err && err === _retailPaymentDevice.deviceError.paymentCancelled) {
        Log.debug(function () {
          return 'Contactless reader was deactivated on ' + _this11.id + '. Card reader is out of transaction state';
        });
        _this11.emit(_retailPaymentDevice.PaymentDevice.Event.contactlessReaderDeactivated, err);
        return;
      }

      if (err && (context.type === _retailPaymentDevice.TransactionType.Sale || context.type === _retailPaymentDevice.TransactionType.Auth || context.type === _retailPaymentDevice.TransactionType.Refund && err.code !== _retailPaymentDevice.deviceError.nfcNotAllowed.code)) {
        Log.debug(function () {
          return 'Error received from starting contactless tx ' + err;
        });
        // Essentially, in case of refunds, treat the decline as a success and move on.
        _this11.emit(_retailPaymentDevice.PaymentDevice.Event.cardPresented, err, _retailPaymentDevice.CardPresentEvent.cardDataRead, _retailPaymentDevice.FormFactor.EmvCertifiedContactless);
        return;
      }
      Log.debug(function () {
        return 'Received ICC response from card tap: ' + clResult;
      });
      var card = new _CardStatus2.default(clResult).getPresentedCard(_this11);
      Log.debug(function () {
        return 'Card object updated with emv response: ' + card;
      });
      _this11._inTransactionState = true;
      _this11.emit(_retailPaymentDevice.PaymentDevice.Event.cardPresented, null, _retailPaymentDevice.CardPresentEvent.cardDataRead, _retailPaymentDevice.FormFactor.EmvCertifiedContactless, { card: card });
    });
  };

  MiuraDevice.prototype._readCardData = function _readCardData(card, context) {
    var _this12 = this;

    var tt = _Terminal.MiuraTransactionType.SALE;
    var amount = context.invoice.total;
    // TODO not sure SALE is the right type for an auth from the terminal's perspective?
    if (context.type === _retailPaymentDevice.TransactionType.Refund) {
      tt = _Terminal.MiuraTransactionType.REFUND;
      amount = context.refundAmount;
    }

    this.terminal.startICCTransaction(0, tt, _paypalInvoicing.Currency.toCents(context.invoice.currency, amount).toString(), _paypalInvoicing.Currency.getCurrency(context.invoice.currency).iso4217, function (err, clResult) {
      if (err) {
        Log.error('Failed to start ICC transaction. Error: ' + err);
        var error = err;
        if (clResult && clResult.apdu && clResult.apdu.sw2 === 0x41) {
          error = _retailPaymentDevice.deviceError.cancelReadCardData;
        }
        _this12.emit(_retailPaymentDevice.PaymentDevice.Event.cardPresented, error, _retailPaymentDevice.CardPresentEvent.cardDataRead, _retailPaymentDevice.FormFactor.Chip);
        return;
      }

      if (clResult instanceof _retailPaymentDevice.AvailableApplications) {
        _this12._inTransactionState = true;
        _this12.emit(_retailPaymentDevice.PaymentDevice.Event.cardPresented, null, _retailPaymentDevice.CardPresentEvent.appSelectionRequired, _retailPaymentDevice.FormFactor.Chip, { card: card, availableApps: clResult });
        return;
      }
      Log.debug(function () {
        return 'Received ICC response from card insert: ' + clResult;
      });
      var cardMetadata = (0, _cardMetadataParser2.default)(card.formFactor, clResult);
      Util.extend(card, cardMetadata, true);
      Log.debug(function () {
        return 'Card object updated with emv response: ' + card;
      });
      if (clResult.apdu.template === 0xE3) {
        _this12.emit(_retailPaymentDevice.PaymentDevice.Event.cardPresented, null, _retailPaymentDevice.CardPresentEvent.cardDataRead, _retailPaymentDevice.FormFactor.Chip, {
          card: card,
          offlineApproval: true
        });
        return;
      }

      if (clResult.apdu.template === 0xE4) {
        _this12._inTransactionState = true;
        _this12.emit(_retailPaymentDevice.PaymentDevice.Event.cardPresented, null, _retailPaymentDevice.CardPresentEvent.cardDataRead, _retailPaymentDevice.FormFactor.Chip, { card: card });
        return;
      }

      Log.warn('Contact tx Response from device was not handled ' + clResult);
      _this12.emit(_retailPaymentDevice.PaymentDevice.Event.cardPresented, _retailPaymentDevice.deviceError.badEmvData, _retailPaymentDevice.CardPresentEvent.cardDataRead, _retailPaymentDevice.FormFactor.Chip);
    });
  };

  MiuraDevice.prototype._deviceEvent = function _deviceEvent(m) {
    if (m instanceof _TerminalStatus2.default) {
      if (m.changeType === _TerminalStatus2.default.Constants.PinEntryStateChange) {
        var pinEvent = new _retailPaymentDevice.PinEvent();
        pinEvent.digits = m.pinDigits;
        pinEvent.complete = m.pinComplete;
        pinEvent.correct = m.pinCorrect;
        pinEvent.isLastAttempt = m.lastPinAttempt;
        pinEvent.failureReason = m.pinFailureReason;
        this.emit(_retailPaymentDevice.PaymentDevice.Event.cardPresented, null, _retailPaymentDevice.CardPresentEvent.pinEvent, _retailPaymentDevice.FormFactor.Chip, pinEvent);
        return;
      }

      if (m.changeType === _TerminalStatus2.default.Constants.SeePhone) {
        this.app.display({ audio: { file: 'beep', playCount: 2 } }, function () {});
        return;
      }
    }

    // 'X' button was tapped
    if (m.keyCode === 0x1B) {
      Log.debug('X button on terminal was tapped. Will try to cancel an ongoing payment');
      this.emit(_retailPaymentDevice.PaymentDevice.Event.cancelRequested);
    } else if (m.keyCode === 0x0d) {
      Log.debug('OK button was tapped on the terminal.');
      this.emit(_retailPaymentDevice.PaymentDevice.Event.proceed);
    }
  };

  MiuraDevice.prototype._readConfigPair = function _readConfigPair(tlv) {
    var key = void 0;
    var val = true;
    for (var _iterator2 = tlv.parse().values, _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) {
      var _ref2;

      if (_isArray2) {
        if (_i2 >= _iterator2.length) break;
        _ref2 = _iterator2[_i2++];
      } else {
        _i2 = _iterator2.next();
        if (_i2.done) break;
        _ref2 = _i2.value;
      }

      var v = _ref2;

      if (v.tagNumber === _MiuraTags2.default.MiuraIdentifier.number) {
        key = v.parse();
      } else if (v.tagNumber === _MiuraTags2.default.MiuraVersionInformation.number) {
        val = v.parse();
      }
    }
    if (key.indexOf('-MPI') >= 0) {
      this.mpi = _parseVersionInfo(key, val);
    } else if (key.indexOf('OS') >= 0) {
      this.os = _parseVersionInfo(key, val);
    }
  };

  _createClass(MiuraDevice, [{
    key: 'formFactors',
    get: function get() {
      return this.terminal.formFactors;
    }
  }, {
    key: '_isKeyInjectionRequired',
    get: function get() {
      if (this.forceRki) {
        return true;
      }
      // TODO this may happen before the merchant is available, so we need to decide how to change ready events to handle this possibility
      // TODO this should be driven off a config somewhere (feature map)
      if (this.app.getMerchant() && this.app.getMerchant().country === 'AU') {
        return !(this.p2pe.pin && this.p2pe.sred);
      }
      return !(this.p2pe.pin || this.p2pe.sred);
    }
  }]);

  return MiuraDevice;
}(_retailPaymentDevice.PaymentDevice);

exports.default = MiuraDevice;

},{"./ConnectionFlow":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/build/ConnectionFlow.js","./MiuraTags":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/build/MiuraTags.js","./Terminal":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/build/Terminal.js","./cardMetadataParser":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/build/cardMetadataParser.js","./deviceState":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/build/deviceState.js","./messages/CardStatus":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/build/messages/CardStatus.js","./messages/TerminalStatus":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/build/messages/TerminalStatus.js","manticore-log":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-log/index.js","manticore-util":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-util/build/index.js","paypal-invoicing":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/index.js","retail-payment-device":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/index.js","tlvlib":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/tlvlib/build/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/build/MiuraTags.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

var _tlvlib = require('tlvlib');

var Tags = {
  MiuraFileLength: new _tlvlib.DefinedTag('MiuraFileLength', 0x80, _tlvlib.ValueFormat.Numeric),
  MiuraCommandData: new _tlvlib.DefinedTag('MiuraCommandData', 0xE0, _tlvlib.ValueFormat.TypeLengthValueList),
  MiuraConfigurationInformation: new _tlvlib.DefinedTag('MiuraConfigurationInformation', 0xED, _tlvlib.ValueFormat.TypeLengthValueList),
  MiuraSoftwareInformation: new _tlvlib.DefinedTag('MiuraSoftwareInformation', 0xEF, _tlvlib.ValueFormat.TypeLengthValueList),
  MiuraIdentifier: new _tlvlib.DefinedTag('MiuraIdentifier', 0xDF0D, _tlvlib.ValueFormat.Alpha),
  MiuraVersionInformation: new _tlvlib.DefinedTag('MiuraVersionInformation', 0xDF7F, _tlvlib.ValueFormat.Alpha),
  MiuraStateChangeReason: new _tlvlib.DefinedTag('MiuraStateChangeReason', 0xC3, _tlvlib.ValueFormat.Binary, 1),
  MiuraStateChangeText: new _tlvlib.DefinedTag('MiuraStateChangeText', 0xC4, _tlvlib.ValueFormat.Alpha),
  MiuraCardStatusInfo: new _tlvlib.DefinedTag('MiuraCardStatusInfo', 0x48, _tlvlib.ValueFormat.Binary, 2),
  MiuraSREDData: new _tlvlib.DefinedTag('MiuraSREDData', 0xdfae02, _tlvlib.ValueFormat.Binary),
  MiuraKSN: new _tlvlib.DefinedTag('MiuraKSN', 0xdfae03, _tlvlib.ValueFormat.Binary),
  MiuraMaskedICCTrack2: new _tlvlib.DefinedTag('MiuraMaskedICCTrack2', 0xdfae57, _tlvlib.ValueFormat.CompressedAlpha),
  MiuraMaskedPan: new _tlvlib.DefinedTag('MiuraMaskedPan', 0xdfae5a, _tlvlib.ValueFormat.AlphaNumeric),
  MiuraMaskedTrack2: new _tlvlib.DefinedTag('MiuraMaskedTrack2', 0xdfae22, _tlvlib.ValueFormat.Alpha),
  MiuraMaskedContactlessTrack2: new _tlvlib.DefinedTag('MiuraMaskedContactlessTrack2', 0xdfae6b, _tlvlib.ValueFormat.Alpha),
  MiuraKeyboardData: new _tlvlib.DefinedTag('MiuraKeyboardData', 0xdfa205, _tlvlib.ValueFormat.Binary, 1),
  MiuraNumericData: new _tlvlib.DefinedTag('MiuraNumericData', 0xdfa208, _tlvlib.ValueFormat.AlphaNumeric),
  MiuraCardholderVerificationStatus: new _tlvlib.DefinedTag('MiuraCardholderVerificationStatus', 0xdf28, _tlvlib.ValueFormat.Binary, 1),
  MiuraDigitsInPinBuffer: new _tlvlib.DefinedTag('MiuraDigitsInPinBuffer', 0xdfa101, _tlvlib.ValueFormat.Numeric),
  MiuraPinEntryStatus: new _tlvlib.DefinedTag('MiuraPinEntryStatus', 0xdfa102, _tlvlib.ValueFormat.Binary, 1),
  MiuraP2PEStatus: new _tlvlib.DefinedTag('MiuraP2PEStatus', 0xdfae01, _tlvlib.ValueFormat.Binary, 1),
  MiuraFileWriteOffset: new _tlvlib.DefinedTag('MiuraFileWriteOffset', 0xDFA301, _tlvlib.ValueFormat.Binary),
  MiuraFileWriteLength: new _tlvlib.DefinedTag('MiuraFileWriteLength', 0xDFA302, _tlvlib.ValueFormat.Binary),
  MiuraFileWriteTimeout: new _tlvlib.DefinedTag('MiuraFileWriteTimeout', 0xDFA303, _tlvlib.ValueFormat.Binary, 1),
  MiuraFileMD5: new _tlvlib.DefinedTag('MiuraFileMD5', 0xDFA304, _tlvlib.ValueFormat.Binary),
  MiuraContactlessType: new _tlvlib.DefinedTag('MiuraContactlessType', 0xdf30, _tlvlib.ValueFormat.Binary, 2),
  MiuraBatteryData: new _tlvlib.DefinedTag('MiuraBatteryData', 0xdfa209, _tlvlib.ValueFormat.Binary, 1),
  MiuraImageData: new _tlvlib.DefinedTag('MiuraImageData', 0xDFAC03, _tlvlib.ValueFormat.AlphaNumeric),
  MiuraTextData: new _tlvlib.DefinedTag('MiuraTextData', 0xDFAC02, _tlvlib.ValueFormat.AlphaNumeric),
  MiuraMediaCoordinates: new _tlvlib.DefinedTag('MiuraMediaCoordinates', 0xDFAC01, _tlvlib.ValueFormat.Numeric, 2)
}; /** DO NOT EDIT THIS FILE, IT IS AUTOMATICALLY GENERATED BY gulpfile.js **/
exports.default = Tags;

},{"tlvlib":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/tlvlib/build/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/build/Parser.js":[function(require,module,exports){
(function (Buffer){
'use strict';

var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };

exports.__esModule = true;
exports.MiuraParser = exports.ParserEvent = undefined;

var _retailPaymentDevice = require('retail-payment-device');

var _manticore = require('manticore');

var _manticore2 = _interopRequireDefault(_manticore);

var _events = require('events');

var _manticoreLog = require('manticore-log');

var _manticoreLog2 = _interopRequireDefault(_manticoreLog);

var _tlvlib = require('tlvlib');

function _interopRequireDefault(obj) {
  return obj && obj.__esModule ? obj : { default: obj };
}

function _classCallCheck(instance, Constructor) {
  if (!(instance instanceof Constructor)) {
    throw new TypeError("Cannot call a class as a function");
  }
}

function _possibleConstructorReturn(self, call) {
  if (!self) {
    throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
  }return call && ((typeof call === 'undefined' ? 'undefined' : _typeof(call)) === "object" || typeof call === "function") ? call : self;
}

function _inherits(subClass, superClass) {
  if (typeof superClass !== "function" && superClass !== null) {
    throw new TypeError("Super expression must either be null or a function, not " + (typeof superClass === 'undefined' ? 'undefined' : _typeof(superClass)));
  }subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } });if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;
} /* eslint-disable no-param-reassign */

var Log = (0, _manticoreLog2.default)('miura.parser');

var ParserEvent = exports.ParserEvent = {
  unsolicited: 'unsolicited',
  response: 'response'
};

function verifyLrc(buffer) {
  var lrc = 0;
  for (var i = 0; i < buffer.length - 1; i++) {
    lrc ^= buffer[i];
  }
  lrc &= 0xFF;
  if (lrc !== buffer[buffer.length - 1]) {
    Log.warn('LRC did not match. Expected ' + lrc.toString(16) + ', got ' + buffer[buffer.length - 1].toString(16) + '\n' + buffer.toString('hex'));
    throw _retailPaymentDevice.deviceError.dataValidationError.withDevMessage('Miura packet error checking failed');
  }
}

var MiuraParser = exports.MiuraParser = function (_EventEmitter) {
  _inherits(MiuraParser, _EventEmitter);

  function MiuraParser() {
    _classCallCheck(this, MiuraParser);

    var _this = _possibleConstructorReturn(this, _EventEmitter.call(this));

    _this.partial = null;
    return _this;
  }

  MiuraParser.prototype.reset = function reset() {
    this.partial = null;
  };

  MiuraParser.prototype.received = function received(data) {
    var raw = void 0;
    try {
      raw = Buffer.isBuffer(data) ? data : new Buffer(data, 'base64');
      if (this.incompletePacket) {
        raw = Buffer.concat([this.incompletePacket, raw]);
        delete this.incompletePacket;
      }
      if (raw.length < 3 || raw.length < raw[2] + 4) {
        this.incompletePacket = raw;
        Log.debug('Incomplete packet received.');
        return;
      }
      this._completePacket(raw);
    } catch (x) {
      Log.error('Failed processing Miura packet: ' + x.message + ', stack: ' + x.stack + ', ' + x);
      throw x;
    }
  };

  MiuraParser.prototype._emitAsync = function _emitAsync(event, data) {
    var _this2 = this;

    _manticore2.default.setTimeout(function () {
      _this2.emit(event, data);
    }, 0);
  };

  MiuraParser.prototype._completePacket = function _completePacket(raw) {
    var rz = null;
    try {
      rz = this._readResponse(raw);
    } catch (x) {
      Log.error(function () {
        return 'Failed to read terminal response: ' + x.message + '\n' + x.stack;
      });
    }
    if (!rz) {
      return; // No message here, likely a partial
    }
    Log.debug(function () {
      return 'Emitting ' + (rz.isUnsolicited ? 'UNSOLICITED' : 'RESPONSIVE') + ' template ' + (rz.apdu.template ? rz.apdu.template.toString(16) : '<empty>') + ' SW1: ' + rz.apdu.sw1.toString(16) + ' SW2: ' + rz.apdu.sw2.toString(16) + ' Raw: ' + rz.raw.toString('hex');
    });
    if (rz.isUnsolicited) {
      this._emitAsync(ParserEvent.unsolicited, rz);
    } else {
      this._emitAsync(ParserEvent.response, rz);
    }
  };

  MiuraParser.prototype._readResponse = function _readResponse(buffer) {
    buffer = this._validateBuffer(buffer);
    var isUnsolicited = false;
    if (buffer[1] === 0x40) {
      isUnsolicited = true;
    }

    if (buffer[1] === 1) {
      // Partial packet.
      this._processPartial(buffer);
      return null;
    }

    var merged = this._applyPartial(buffer[2], buffer);
    buffer = merged.buffer;
    var ret = new _retailPaymentDevice.CardReaderResponse(merged.buffer, merged.length, isUnsolicited);
    if (ret.length + 4 !== buffer.length) {
      Log.warn(function () {
        return 'Received response packet with non-matching length bytes. Expected ' + (ret.length + 4) + ', got ' + buffer.length;
      });
    }
    var rawBytes = isUnsolicited ? false : this.expectRawBytes;
    try {
      ret.apdu = new _tlvlib.ApduResponse(buffer, 3, ret.length, rawBytes);
    } catch (x) {
      Log.error('Failed to parse APDU from raw response: ' + buffer.toString('hex') + '\nError: ' + x.message);
    }
    return ret;
  };

  MiuraParser.prototype._processPartial = function _processPartial(buffer) {
    Log.debug(function () {
      return 'Received partial packet of ' + (buffer.length - 4) + ' bytes ' + buffer.toString('hex');
    });
    if (this.partial === null) {
      this.partial = [];
      this.partialLen = 0;
      this.partial.push(new Buffer('000000', 'hex')); // fake the preamble
    }
    this.partialLen += buffer[2];
    this.partial.push(buffer.slice(3, buffer.length - 1));
  };

  MiuraParser.prototype._applyPartial = function _applyPartial(length, buffer) {
    if (this.partial) {
      this.partial.push(buffer.slice(3, buffer.length - 1));
      this.partial.push(new Buffer('00', 'hex'));
      Log.debug(function () {
        return 'Final packet of partial ' + buffer.toString('hex');
      });
      buffer = Buffer.concat(this.partial);
      length += this.partialLen;
      Log.debug(function () {
        return 'Reassembled ' + buffer.length + ' bytes (' + length + ').';
      });
      this.partial = null;
      this.partialLen = 0;
    }

    return {
      buffer: buffer,
      length: length
    };
  };

  MiuraParser.prototype._validateBuffer = function _validateBuffer(buffer) {
    var _this3 = this;

    if (buffer[0] !== 0x01) {
      Log.warn(function () {
        return 'Received response packet with non-standard NAD byte: ' + buffer[0];
      });
    }
    if (buffer[1] !== 0x00 && buffer[1] !== 0x40 && buffer[1] !== 1) {
      Log.warn(function () {
        return 'Received response packet with non-standard PCB byte: ' + buffer[1];
      });
    }
    if (buffer.length > buffer[2] + 4) {
      // Overflow.
      var spill = buffer.slice(buffer[2] + 4, buffer.length);
      buffer = buffer.slice(0, buffer[2] + 4);
      _manticore2.default.setTimeout(function () {
        _this3.received(spill);
      }, 0);
    }
    verifyLrc(buffer);
    return buffer;
  };

  return MiuraParser;
}(_events.EventEmitter);

}).call(this,require("buffer").Buffer)
},{"buffer":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/buffer/index.js","events":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/events/events.js","manticore":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore/browser.js","manticore-log":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-log/index.js","retail-payment-device":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/index.js","tlvlib":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/tlvlib/build/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/build/SoftwareUpdate/MiuraDeviceUpdate.js":[function(require,module,exports){
(function (Buffer){
'use strict';

var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };

exports.__esModule = true;

var _retailPaymentDevice = require('retail-payment-device');

var _manticoreLog = require('manticore-log');

var _manticoreLog2 = _interopRequireDefault(_manticoreLog);

var _md = require('md5');

var _md2 = _interopRequireDefault(_md);

var _async = require('async');

var _async2 = _interopRequireDefault(_async);

var _manticore = require('manticore');

var _manticore2 = _interopRequireDefault(_manticore);

var _deviceState = require('../deviceState');

var _deviceState2 = _interopRequireDefault(_deviceState);

var _Flow = require('../common/Flow');

var _Flow2 = _interopRequireDefault(_Flow);

function _interopRequireDefault(obj) {
  return obj && obj.__esModule ? obj : { default: obj };
}

function _toConsumableArray(arr) {
  if (Array.isArray(arr)) {
    for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) {
      arr2[i] = arr[i];
    }return arr2;
  } else {
    return Array.from(arr);
  }
}

function _classCallCheck(instance, Constructor) {
  if (!(instance instanceof Constructor)) {
    throw new TypeError("Cannot call a class as a function");
  }
}

function _possibleConstructorReturn(self, call) {
  if (!self) {
    throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
  }return call && ((typeof call === 'undefined' ? 'undefined' : _typeof(call)) === "object" || typeof call === "function") ? call : self;
}

function _inherits(subClass, superClass) {
  if (typeof superClass !== "function" && superClass !== null) {
    throw new TypeError("Super expression must either be null or a function, not " + (typeof superClass === 'undefined' ? 'undefined' : _typeof(superClass)));
  }subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } });if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;
}

var Log = (0, _manticoreLog2.default)('paymentDevice.miura.firmwareUpdate');
var deviceMessageId = _retailPaymentDevice.PaymentDevice.Message;
var TerminalMessageId = _retailPaymentDevice.PaymentDevice.Message;
var IKSN_BUFFER = new Buffer('IKSN: ');
var blobStorage = 'B';
var TERMINAL_STREAM_TIMEOUT = 255;
var TERMINAL_CONNECTION_RETRY_LIMIT = 20;
var TERMINAL_CONNECTION_RETRY_TIMEOUT = 20000;
var TERMINAL_CONNECTION_DEFAULT_RETRY_TIMEOUT = 2500;
var MANTICORE_DEFAULT_SET_TIMEOUT = 5000;
var FILE_CHUNK_SIZE = 0x20000;
var maxAttempts = 2;

if (FILE_CHUNK_SIZE % 4) {
  throw new Error('FILE_CHUNK_SIZE MUST BE DIVISIBLE BY 4!!!');
}

var lastMiuraLogState = void 0;
var switchedOff = void 0;
var isProgressFileFetches = {};

/**
 * Shut off the Miura debug logs except our own component,
 * then reset them to where they were when done.
 * @param on
 */
function miuraLogs(on) {
  var exl = require('manticore-log')('paymentDevice.miuraDevice'); // eslint-disable-line global-require
  if (on && switchedOff) {
    switchedOff = false;
    if (lastMiuraLogState) {
      exl.Config.level = lastMiuraLogState;
    } else {
      delete exl.Config.level;
    }
    delete Log.Config.level;
    Log.debug('Re-enabled logs.');
  } else if (!on && !switchedOff) {
    Log.debug('Squelching Miura debug logs.');
    lastMiuraLogState = exl.Config.level;
    switchedOff = true;
    exl.Config.level = 'INFO';
    Log.Config.level = 'DEBUG';
  }
}

/**
 * While USB is not the default, make sure MPI-Dynamic has it
 * @param rz
 */
function fixMpiDynamic(rz) {
  var mpiDynamic = new Buffer(rz.body, 'base64').toString();
  if (!mpiDynamic.indexOf('[USB]')) {
    mpiDynamic = '[USB]\n\tdefault = serial\n' + mpiDynamic;
    rz.body = new Buffer(mpiDynamic).toString('base64');
  }
}

function getNameFromUrl(url) {
  var finalName = url.split('/');
  finalName = finalName[finalName.length - 1];
  return finalName;
}

function pushModules(requiredUrlArray, urls) {
  if (requiredUrlArray) {
    for (var _iterator = urls, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
      var _ref;

      if (_isArray) {
        if (_i >= _iterator.length) break;
        _ref = _iterator[_i++];
      } else {
        _i = _iterator.next();
        if (_i.done) break;
        _ref = _i.value;
      }

      var url = _ref;

      requiredUrlArray.push(url);
    }
  }
}

function getOne(url, cb) {
  var retryCount = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;

  _manticore2.default.getItem(url, blobStorage, function (error, item) {
    if (item) {
      Log.debug(function () {
        return 'Retrieved from CACHE ' + url;
      });
      _manticore2.default.setTimeout(function () {
        return cb(null, item);
      }, 0);
      return;
    }
    // If a fetch is already in progress, and we're not it, don't do it twice.
    if (retryCount === 0) {
      if (isProgressFileFetches[url]) {
        Log.debug(function () {
          return 'Waiting for existing fetch of ' + url;
        });
        isProgressFileFetches[url].push(cb);
        return;
      }
      isProgressFileFetches[url] = [cb];
    }
    Log.debug(function () {
      return 'Fetching firmware update file ' + url;
    });
    var start = new Date();
    _manticore2.default.http({
      url: url,
      format: 'binary'
    }, function (err, rz) {
      var timeElapsed = new Date() - start;
      var seconds = Math.round(timeElapsed % 60);
      if (err) {
        Log.error('Attempt ' + (retryCount || 0) + '/' + maxAttempts + '. Duration: ' + seconds + 's. Download failed for ' + url + ' with error: ' + err + ')');
      } else {
        Log.debug(function () {
          return 'Duration: ' + seconds + 's. Done with ' + url;
        });
      }
      if (!err && url.indexOf('MPI-Dynamic.cfg') > 0) {
        fixMpiDynamic(rz);
      }
      if (!err) {
        _manticore2.default.setItem(url, blobStorage, rz.body, null);
      } else if (retryCount < maxAttempts) {
        Log.warn(function () {
          return 'Fetch failed for ' + url + '. Starting retry #{retryCount+1}';
        });
        getOne(url, cb, (retryCount || 0) + 1);
        return;
      }
      for (var _iterator2 = isProgressFileFetches[url], _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) {
        var _ref2;

        if (_isArray2) {
          if (_i2 >= _iterator2.length) break;
          _ref2 = _iterator2[_i2++];
        } else {
          _i2 = _iterator2.next();
          if (_i2.done) break;
          _ref2 = _i2.value;
        }

        var callback = _ref2;

        callback(err, rz);
      }
      delete isProgressFileFetches[url];
    });
  });
}

function chunkItOut(options, callback, base64Offset, startTime, isRetry) {
  var actualStartTime = startTime || new Date().getTime();
  var actualBase64offset = base64Offset || 0;
  var binaryOffset = actualBase64offset * (3 / 4);
  if (options.file.length - actualBase64offset > FILE_CHUNK_SIZE) {
    var chunk = options.file.substring(actualBase64offset, actualBase64offset + FILE_CHUNK_SIZE);
    Log.debug(function () {
      return 'Pushing chunk of file: ' + options.name + ' ' + FILE_CHUNK_SIZE * (3 / 4) + '@' + binaryOffset + ' of ' + options.file.length * (3 / 4);
    });
    options.device.terminal.Config.streamBinary(chunk, binaryOffset, TERMINAL_STREAM_TIMEOUT, false, function (writeError, writeRz) {
      if (writeError || !writeRz.apdu.isSuccess) {
        if (isRetry) {
          Log.error('Aborting file send early.');
          if (writeRz) {
            Log.warn(writeRz.toString());
          }
          callback(writeError, writeRz);
        } else {
          Log.warn('Failed to push a chunk of file ' + options.name + '. Will retry. Response: ' + writeRz);
          // Give it a half a second to recover and try the same segment again
          _manticore2.default.setTimeout(function () {
            return chunkItOut(options, callback, actualBase64offset, binaryOffset, actualStartTime, true);
          }, 500);
        }
        return;
      }
      var progress = parseInt((options.done + actualBase64offset + FILE_CHUNK_SIZE) * (100 / options.total), 10);
      options.this.appAlert = options.device.app.display({
        title: _retailPaymentDevice.appMessage.SwUpdateInProgressWithDetails.title,
        message: {
          id: _retailPaymentDevice.appMessage.SwUpdateInProgressWithDetails.message,
          substitutions: { stage: options.stageId, progress: progress }
        },
        showActivity: true,
        replace: true
      });
      options.device.display({
        id: TerminalMessageId.SoftwareUpdateProgress,
        substitutions: {
          stage: options.stageId,
          progress: progress
        }
      }, function () {
        return chunkItOut(options, callback, actualBase64offset + FILE_CHUNK_SIZE, actualStartTime);
      });
    });
  } else {
    var _chunk = options.file.substring(actualBase64offset);
    Log.debug(function () {
      return 'Completing transfer of ' + options.name;
    });
    options.device.terminal.Config.streamBinary(_chunk, binaryOffset, TERMINAL_STREAM_TIMEOUT, false, callback);
  }
}

function errorOrFailure(error, response) {
  if (!error && !response.apdu.isSuccess) {
    return _retailPaymentDevice.deviceError.failureResponse.withDevMessage('Miura response indicates failure: 0x' + response.apdu.sw1.toString(16) + ' 0x' + response.apdu.sw2.toString(16));
  }
  return error;
}

var MiuraDeviceUpdate = function (_DeviceUpdate) {
  _inherits(MiuraDeviceUpdate, _DeviceUpdate);

  function MiuraDeviceUpdate(device) {
    _classCallCheck(this, MiuraDeviceUpdate);

    var _this = _possibleConstructorReturn(this, _DeviceUpdate.call(this, device));

    _this.files = {};
    _this.updates = {};
    return _this;
  }

  MiuraDeviceUpdate.prototype.beginDeviceUpdate = function beginDeviceUpdate(callback) {
    var _this2 = this;

    Log.info('Beginning SW Update on ' + this.device.id);
    this._hardResetNeeded = false;
    isProgressFileFetches = {};
    this.appAlert = this.device.app.display({
      title: _retailPaymentDevice.appMessage.SwUpdateInProgress.title,
      message: _retailPaymentDevice.appMessage.SwUpdateInProgress.message,
      showActivity: true
    });

    var updateSteps = [];
    if (this.device._isKeyInjectionRequired) {
      Log.debug('Key injection required');
      updateSteps.push(this.updateP2PE); // TODO Enable this
    }

    if (this.device.updates) {
      Log.debug('Found ' + this.device.updates.length + ' module updates');
      updateSteps.push(this.updateSWModules);
    }

    var flow = new _Flow2.default(this, updateSteps);
    flow.name = 'Firmware Update';
    flow.on('completed', function (err) {
      var endTime = new Date();
      var timeDiff = endTime - _this2.startTime;
      var seconds = Math.round(timeDiff % 60);
      if (err) {
        Log.error('SW Update on ' + _this2.device.id + ' failed with error: ' + err + '. Time taken: ' + seconds + 's');
      }
      Log.info('Firmware update completed on ' + _this2.device.id + '. Time taken: ' + seconds + 's'); // TODO Add total time taken
      if (_this2.appAlert) {
        _this2.appAlert.dismiss();
      }
      _this2.device.display({ id: TerminalMessageId.SoftwareUpdateComplete }, function () {});

      callback(err, !err);
    });
    this.startTime = new Date();
    flow.start();
  };

  MiuraDeviceUpdate.prototype.validateUpdateEligibility = function validateUpdateEligibility(callback) {
    var _this3 = this;

    var canUpdate = !(this.device.lastKnownBatteryInfo && this.device.lastKnownBatteryInfo.isLevelUpdateCritical);
    if (canUpdate) {
      callback();
      return;
    }
    this.device.display({ id: deviceMessageId.RechargeNow }, function () {
      _this3.appAlert = _this3.device.app.display({
        title: _retailPaymentDevice.appMessage.SwUpdateFailed.title,
        message: _retailPaymentDevice.appMessage.SwUpdateFailed.messageBatteryLow,
        cancel: _retailPaymentDevice.appMessage.SwUpdate.buttons.ok
      }, function (av) {
        av.dismiss();
        callback(_retailPaymentDevice.deviceError.lowOnBattery);
      });
    });
  };

  MiuraDeviceUpdate.prototype.updateP2PE = function updateP2PE(flow) {
    var p2peFlow = new _Flow2.default(this, this._displayInitMessage, this._initP2PE, this._disableLogs, this._getP2PEFile('initial_ksn', 'suggested-iksn.txt'), this._getP2PEFile('signed_product_signing_cert', 'prod-sign.crt'), this._getP2PEFile('signed_terminal_cert', 'terminal.crt'), this._getP2PEFile('signed_key_loading_cert', 'temp-keyload.crt'), this._enableLogs, this._displayFetchMessage, this._retrieveP2PEFilesFromServer, this._writeP2PEFilesToTerminal, this._importP2PEKeys, this._displayCompleteMessage);
    p2peFlow.name = 'P2PE Update Flow';
    p2peFlow.on('completed', function (err) {
      flow.nextOrAbort(err);
    });
    p2peFlow.start();
  };

  MiuraDeviceUpdate.prototype._disableLogs = function _disableLogs(flow) {
    Log.debug('Disabling miura logs');
    miuraLogs(false);
    flow.next(null);
  };

  MiuraDeviceUpdate.prototype._enableLogs = function _enableLogs(flow) {
    Log.debug('Enabling logs');
    miuraLogs(true);
    flow.next(null);
  };

  MiuraDeviceUpdate.prototype._displayInitMessage = function _displayInitMessage(flow) {
    this.appAlert = this.device.app.display({
      title: _retailPaymentDevice.appMessage.SwUpdateInitializing.title,
      message: _retailPaymentDevice.appMessage.SwUpdateInitializing.message,
      showActivity: true
    });
    this.device.display({
      id: TerminalMessageId.SoftwareUpdateProgress,
      substitutions: {
        stage: 'EncryptInit'
      }
    }, function (err) {
      flow.nextOrAbort(err);
    });
  };

  MiuraDeviceUpdate.prototype._displayFetchMessage = function _displayFetchMessage(flow) {
    Log.debug('Displaying Fetch message');
    this.appAlert = this.device.app.display({
      title: _retailPaymentDevice.appMessage.SwUpdateValidatingSecurityKeys.title,
      message: _retailPaymentDevice.appMessage.SwUpdateValidatingSecurityKeys.message,
      showActivity: true
    });
    this.device.display({
      id: TerminalMessageId.SoftwareUpdateProgress,
      substitutions: {
        stage: 'EncryptGet'
      }
    }, function (err) {
      flow.nextOrAbort(err);
    });
  };

  MiuraDeviceUpdate.prototype._displayCompleteMessage = function _displayCompleteMessage(flow) {
    Log.debug('Displaying complete message');
    this.appAlert = this.device.app.display({
      title: _retailPaymentDevice.appMessage.SwUpdateSecurityKeysInstalled.title,
      message: _retailPaymentDevice.appMessage.SwUpdateSecurityKeysInstalled.message,
      showActivity: true
    });
    this.device.display({
      id: TerminalMessageId.SoftwareUpdateProgress,
      substitutions: {
        stage: 'EncryptDone'
      }
    }, function (err) {
      flow.nextOrAbort(err);
    });
  };

  MiuraDeviceUpdate.prototype._initP2PE = function _initP2PE(flow) {
    Log.debug('Initializing P2PE on ' + this.device.id);
    if (this.device.p2pe.init) {
      Log.debug('P2PE already initialized');
      flow.next();
      return;
    }

    this.device.terminal.Config.initializeP2PE(function (err, rz) {
      var formattedErr = null;
      if (!err && !rz.apdu.isSuccess) {
        formattedErr = _retailPaymentDevice.deviceError.initializationFailed.withDevMessage('Failed to initialize device encryption keys.');
      }
      flow.nextOrAbort(formattedErr);
    });
  };

  MiuraDeviceUpdate.prototype._getP2PEFile = function _getP2PEFile(key, fileName) {
    var _this4 = this;

    return function (flow) {
      Log.debug(function () {
        return 'Retrieving file ' + fileName + ' from ' + _this4.device.id;
      });
      _this4.device.terminal.Config.getFile(fileName, function (err, fileContent) {
        if (err) {
          Log.error('Error on retrieving P2PE file ' + fileName + ' from ' + _this4.device.id + ':  ' + err);
          flow.abortFlow(err);
          return;
        }
        _this4.files[key] = fileContent.toString();
        flow.next();
      });
    };
  };

  MiuraDeviceUpdate.prototype._retrieveP2PEFilesFromServer = function _retrieveP2PEFilesFromServer(flow) {
    var _this5 = this;

    Log.debug('Retrieving keys from ' + this.device.id);
    this.files.initial_ksn = this.files.initial_ksn.replace(/\n/g, '').replace('IKSN: ', '');
    this.device.app.getRemoteCardReaderKeys(this.files, this.device.manufacturer, this.device.model, function (err, keyResponse) {
      Log.debug(function () {
        return 'Received RKI update response for this.device: ' + _this5.device;
      });
      if (err) {
        flow.abortFlow(err);
        return;
      }
      _this5.filesToWrite = [];
      _this5.fileWriteIndex = 0;
      for (var k in keyResponse.body) {
        if ({}.hasOwnProperty.call(keyResponse.body, k)) {
          _this5.filesToWrite.push(keyResponse.body[k]);
        }
      }
      Log.debug(function () {
        return 'RKI Files to write:\n' + JSON.stringify(_this5.filesToWrite);
      });
      flow.next();
    });
  };

  MiuraDeviceUpdate.prototype._writeP2PEFilesToTerminal = function _writeP2PEFilesToTerminal(flow) {
    var _this6 = this;

    if (this.filesToWrite.length > this.fileWriteIndex) {
      var f = this.filesToWrite[this.fileWriteIndex];
      this.device.terminal.Config.selectFile(f.filename, true, function (e) {
        if (e) {
          flow.abortFlow(e);
          return;
        }
        var data = new Buffer(f.content, f.type === 'BASE64' ? 'base64' : 'utf8');
        if (f.filename.indexOf('-iksn-') > 0 && (data.length < IKSN_BUFFER.length || !data.slice(0, IKSN_BUFFER.length).equals(IKSN_BUFFER))) {
          // The content must start with IKSN:
          data = Buffer.concat([IKSN_BUFFER, data], IKSN_BUFFER.length + data.length);
        }

        var dataMD5 = (0, _md2.default)(data);
        Log.debug(function () {
          return 'Sending file: ' + data.toString('hex') + ' \nMD5: ' + dataMD5;
        });
        _this6.device.terminal.Config.streamBinary(data, 0, 0xFF, dataMD5, function (writeError, writeResult) {
          if (writeError) {
            flow.abortFlow(writeError);
            return;
          }
          if (!writeResult.apdu.isSuccess) {
            flow.abortFlow(_retailPaymentDevice.deviceError.initializationFailed.withDevMessage('Failed to update encryption keys.'));
            return;
          }
          _this6.fileWriteIndex += 1;
          _this6._writeP2PEFilesToTerminal(flow);
        });
      });
    } else {
      flow.next();
    }
  };

  MiuraDeviceUpdate.prototype._importP2PEKeys = function _importP2PEKeys(flow) {
    Log.debug('Importing keys on ' + this.device.id);
    this.device.terminal.Config.importP2PE(function (err, rz) {
      var formattedErr = null;
      if (!err && !rz.apdu.isSuccess) {
        formattedErr = new Error(_retailPaymentDevice.deviceError.fileImportFailed.withDevMessage('Failed to import encryption keys.'));
      }
      flow.nextOrAbort(formattedErr);
    });
  };

  MiuraDeviceUpdate.prototype.updateSWModules = function updateSWModules(flow) {
    var moduleUpdateFlow = new _Flow2.default(this, this._gatherFiles, this._updateOs, this._hardResetCardReader, this._tryReconnect, this._updateMPI, this._hardResetCardReader, this._tryReconnect, this._updateConfig, this._hardResetCardReader, this._tryReconnect);

    moduleUpdateFlow.name = 'Software Module Update Flow';
    moduleUpdateFlow.on('completed', function (err) {
      flow.nextOrAbort(err);
    });
    moduleUpdateFlow.start();
  };

  MiuraDeviceUpdate.prototype._generateSteps = function _generateSteps(module) {
    var steps = [];
    if (module.urls) {
      for (var _iterator3 = module.urls, _isArray3 = Array.isArray(_iterator3), _i3 = 0, _iterator3 = _isArray3 ? _iterator3 : _iterator3[Symbol.iterator]();;) {
        var _ref3;

        if (_isArray3) {
          if (_i3 >= _iterator3.length) break;
          _ref3 = _iterator3[_i3++];
        } else {
          _i3 = _iterator3.next();
          if (_i3.done) break;
          _ref3 = _i3.value;
        }

        var url = _ref3;

        steps.push({
          name: getNameFromUrl(url),
          url: url,
          version: module.version,
          reload: module.reload
        });
      }
    }

    if (module.subcomponents) {
      for (var _iterator4 = module.subcomponents, _isArray4 = Array.isArray(_iterator4), _i4 = 0, _iterator4 = _isArray4 ? _iterator4 : _iterator4[Symbol.iterator]();;) {
        var _ref4;

        if (_isArray4) {
          if (_i4 >= _iterator4.length) break;
          _ref4 = _iterator4[_i4++];
        } else {
          _i4 = _iterator4.next();
          if (_i4.done) break;
          _ref4 = _i4.value;
        }

        var component = _ref4;

        steps.push.apply(steps, _toConsumableArray(this._generateSteps(component)));
      }
    }
    return steps;
  };

  MiuraDeviceUpdate.prototype._gatherFiles = function _gatherFiles(flow) {
    var _this7 = this;

    var _loop = function _loop() {
      if (_isArray5) {
        if (_i5 >= _iterator5.length) return 'break';
        _ref5 = _iterator5[_i5++];
      } else {
        _i5 = _iterator5.next();
        if (_i5.done) return 'break';
        _ref5 = _i5.value;
      }

      var u = _ref5;

      var steps = _this7._generateSteps(u);
      _this7.updates[u.name] = steps;
      Log.debug(function () {
        return 'Gathered update ' + u.name + '\n' + JSON.stringify(steps);
      });
    };

    for (var _iterator5 = this.device.updates, _isArray5 = Array.isArray(_iterator5), _i5 = 0, _iterator5 = _isArray5 ? _iterator5 : _iterator5[Symbol.iterator]();;) {
      var _ref5;

      var _ret = _loop();

      if (_ret === 'break') break;
    }
    this._fetchFiles(this.device, function (e) {
      Log.debug('Ready for software update.');
      flow.nextOrAbort(e);
    });
  };

  MiuraDeviceUpdate.prototype._fetchFiles = function _fetchFiles(device, callback) {
    var _this8 = this;

    var filesToFetch = [];
    var fetchCtr = 0;
    MiuraDeviceUpdate.needsUpdate(device, device.updates, filesToFetch);
    Log.debug(function () {
      return 'Preparing to download ' + filesToFetch.length + ' files';
    });
    _async2.default.eachSeries(filesToFetch, function (file, cb) {
      fetchCtr += 1;
      _this8.appAlert = _this8.device.app.display({
        title: _retailPaymentDevice.appMessage.SwUpdateDownloading.title,
        message: {
          id: _retailPaymentDevice.appMessage.SwUpdateDownloading.message,
          substitutions: { count: fetchCtr, total: filesToFetch.length }
        },
        showActivity: true
      });
      _this8.device.display({
        id: TerminalMessageId.SoftwareUpdateDownloading,
        substitutions: { count: fetchCtr, total: filesToFetch.length }
      }, function () {});
      getOne(file, cb);
    }, callback);
  };

  MiuraDeviceUpdate.needsUpdate = function needsUpdate(device, modules, requiredUrlArray) {
    var hasUpdate = false;
    for (var _iterator6 = modules, _isArray6 = Array.isArray(_iterator6), _i6 = 0, _iterator6 = _isArray6 ? _iterator6 : _iterator6[Symbol.iterator]();;) {
      var _ref6;

      if (_isArray6) {
        if (_i6 >= _iterator6.length) break;
        _ref6 = _iterator6[_i6++];
      } else {
        _i6 = _iterator6.next();
        if (_i6.done) break;
        _ref6 = _i6.value;
      }

      var module = _ref6;

      if (module.name === 'Miura_OS') {
        hasUpdate = true;
        Log.info(device.id + ' OS will be updated from ' + device.os.id + '-' + device.os.ver + ' to ' + module.version);
        pushModules(requiredUrlArray, module.urls);
      } else if (module.name === 'Miura_MPI') {
        hasUpdate = true;
        Log.info(device.id + ' MPI will be updated from ' + device.mpi.id + '-' + device.mpi.ver + ' to ' + module.version);
        pushModules(requiredUrlArray, module.urls);
      } else if (module.name === 'Miura_CONFIG' && module.subcomponents) {
        hasUpdate = true;
        Log.info(device.id + ' CFG will be updated with ' + module.subcomponents.length + ' sub components');
        for (var _iterator7 = module.subcomponents, _isArray7 = Array.isArray(_iterator7), _i7 = 0, _iterator7 = _isArray7 ? _iterator7 : _iterator7[Symbol.iterator]();;) {
          var _ref7;

          if (_isArray7) {
            if (_i7 >= _iterator7.length) break;
            _ref7 = _iterator7[_i7++];
          } else {
            _i7 = _iterator7.next();
            if (_i7.done) break;
            _ref7 = _i7.value;
          }

          var component = _ref7;

          pushModules(requiredUrlArray, component.urls);
        }
      }
    }
    if (!hasUpdate) {
      Log.debug(device.id + ' does not need an upgrade.');
    }
    return hasUpdate;
  };

  MiuraDeviceUpdate.prototype._sizeFiles = function _sizeFiles(steps, callback) {
    var _this9 = this;

    var size = 0;
    _async2.default.each(steps, function (step, cbFileFetched) {
      var url = step.url;
      _this9._getCachedFile(url, function (err, file) {
        if (file) {
          size += file.length;
        }

        cbFileFetched();
      });
    }, function () {
      return callback(size);
    });
  };

  MiuraDeviceUpdate.prototype._updateOs = function _updateOs(flow) {
    var osUpdates = this.updates.Miura_OS;
    if (!osUpdates || osUpdates.length === 0) {
      Log.debug('OS update not needed.');
      this._hardResetNeeded = false;
      flow.next();
      return;
    }
    this._hardResetNeeded = true;
    this._updateModules('OS', osUpdates, flow);
  };

  MiuraDeviceUpdate.prototype._updateMPI = function _updateMPI(flow) {
    var mpiUpdates = this.updates.Miura_MPI;
    if (!mpiUpdates || mpiUpdates.length === 0) {
      Log.debug('MPI update not needed.');
      this._hardResetNeeded = false;
      flow.next();
      return;
    }
    this._hardResetNeeded = true;
    this._updateModules('MPI', mpiUpdates, flow);
  };

  MiuraDeviceUpdate.prototype._updateConfig = function _updateConfig(flow) {
    var cfgUpdates = this.updates.Miura_CONFIG;
    if (!cfgUpdates || cfgUpdates.length === 0) {
      Log.debug('Config update not needed.');
      this._hardResetNeeded = false;
      flow.next();
      return;
    }
    this._hardResetNeeded = true;
    this._updateModules('Config', cfgUpdates, flow);
  };

  MiuraDeviceUpdate.prototype._updateModules = function _updateModules(stageId, steps, flow) {
    var _this10 = this;

    Log.info('Updating \'' + stageId + '\' with step(s)\n' + JSON.stringify(steps));
    this.appAlert = this.device.app.display({
      title: _retailPaymentDevice.appMessage.SwUpdateInProgressWithDetails.title,
      message: {
        id: _retailPaymentDevice.appMessage.SwUpdateInProgressWithDetails.message,
        substitutions: { stage: stageId, progress: 0 }
      },
      showActivity: true
    });

    this.device.display({
      id: TerminalMessageId.SoftwareUpdateProgress,
      substitutions: {
        stage: stageId,
        progress: '0'
      }
    }, function () {
      _this10._writeFiles(steps, stageId, flow);
    });
  };

  MiuraDeviceUpdate.prototype._writeFiles = function _writeFiles(steps, stageId, flow) {
    var _this11 = this;

    if (steps.length === 0) {
      Log.error('Attempting to write 0 files to device.');
      flow.next();
      return;
    }

    Log.info('Writing ' + steps.length + ' ' + stageId + ' firmware update file(s) to ' + this.device.id);
    var ix = 0;
    var totalSize = 0;
    var done = 0;
    var lastWasRetry = false;
    var writer = function writer() {
      var url = steps[ix].url;
      var name = steps[ix].name;
      Log.debug(function () {
        return 'Retrieving file ' + name + ' from ' + url;
      });
      _this11._getCachedFile(url, function (err, file) {
        if (err || !file) {
          flow.abortFlow(err || _retailPaymentDevice.deviceError.swUpdateFailed);
          return;
        }
        Log.info('Retrieved ' + name + ' size: ' + file.length + '. Will issue select file command');
        _this11.device.terminal.Config.selectFile(name, true, function (selError, selRz) {
          if (selError) {
            var formatterSelError = errorOrFailure(selError, selRz);
            Log.error('selectFile command returned an error : ' + formatterSelError);
            miuraLogs(true);
            flow.nextOrAbort(formatterSelError);
            return;
          }
          Log.info('Successfully selected ' + name + '. Will push it to card reader');
          miuraLogs(false);
          chunkItOut({
            this: _this11,
            device: _this11.device,
            file: file,
            name: name,
            total: totalSize,
            done: done,
            stageId: stageId
          }, function (writeError, writeResult) {
            if (writeError) {
              var formattedWriteError = errorOrFailure(writeError, writeResult);
              Log.error('Failed to write ' + steps[ix].url + ' to ' + name + ': ' + formattedWriteError.message + '. ' + (lastWasRetry ? 'Will not retry' : 'Will retry'));
              if (lastWasRetry) {
                miuraLogs(true);
                flow.nextOrAbort(formattedWriteError);
              } else {
                writer();
              }
              return;
            }

            lastWasRetry = false;
            done += file.length;
            ix += 1;
            if (ix >= steps.length) {
              miuraLogs(true);
              flow.nextOrAbort();
            } else {
              writer();
            }
          });
        });
      });
    };
    this._sizeFiles(steps, function (_sz) {
      totalSize = _sz;
      writer();
    });
  };

  MiuraDeviceUpdate.prototype._tryReconnect = function _tryReconnect(flow) {
    var _this12 = this;

    if (!this.awaitRestart) {
      flow.next();
      return;
    }

    Log.debug('Waiting for reconnect.');
    this.appAlert = this.device.app.display({
      title: _retailPaymentDevice.appMessage.SwUpdateReconnecting.title,
      message: _retailPaymentDevice.appMessage.SwUpdateReconnecting.message,
      showActivity: true
    });
    _manticore2.default.setTimeout(function () {
      _this12.device.needsRestart = true;
      _this12._retryConnection(TERMINAL_CONNECTION_RETRY_LIMIT, TERMINAL_CONNECTION_RETRY_TIMEOUT, function (e) {
        _this12.device.getFirmwareVersionInfo(function () {
          flow.nextOrAbort(e);
        });
      });
    }, MANTICORE_DEFAULT_SET_TIMEOUT);
    delete this.awaitRestart;
  };

  MiuraDeviceUpdate.prototype._hardResetCardReader = function _hardResetCardReader(flow) {
    var _this13 = this;

    if (!this._hardResetNeeded) {
      Log.debug('Will skip hard-reset as it is not needed');
      flow.next();
      return;
    }
    this.appAlert = this.device.app.display({
      title: _retailPaymentDevice.appMessage.SwUpdateRestarting.title,
      message: _retailPaymentDevice.appMessage.SwUpdateRestarting.message,
      showActivity: true
    });
    this.device.terminal.hardReset(function (resetErr) {
      _this13.awaitRestart = true;
      _this13.device.addState(_deviceState2.default.hardResetting);
      Log.debug('Device was hard-reset. Will disconnect from it');
      // Disconnect following a hard-reset is required for windows firmware updates to properly work
      _this13.device.forceDisconnect(function () {
        Log.debug('Device was disconnected');
        flow.nextOrAbort(resetErr);
      });
    });
  };

  MiuraDeviceUpdate.prototype._retryConnection = function _retryConnection(tryCount, waitTime, cb) {
    var _this14 = this;

    if (!this.device.needsRestart) {
      return;
    }
    miuraLogs(false);
    _manticore2.default.setTimeout(function () {
      Log.debug('Attempting connection with remaining retry attempts:  ' + tryCount);
      var oldRaw = _this14.device.rawConnect;
      _this14.device.rawConnect = true;
      if (_this14.device.needsRestart) {
        _this14.device.connect(function (e) {
          _this14.device.rawConnect = oldRaw;
          if (e) {
            Log.warn('Reconnect failed with error ' + e + '. Remaining retry attempts: ' + tryCount);
            var newCount = tryCount - 1;
            if (newCount <= 0) {
              miuraLogs(true);
              Log.debug('Giving up!');
              cb(e);
            } else {
              _this14._retryConnection(newCount, waitTime, cb);
            }
          } else {
            Log.info(_this14.device.id + ' was successfully connected after restart');
            _this14.appAlert = _this14.device.app.display({
              title: _retailPaymentDevice.appMessage.SwUpdateConnected.title,
              message: _retailPaymentDevice.appMessage.SwUpdateConnected.message,
              showActivity: true
            });
            miuraLogs(true);
            delete _this14.device.needsRestart;
            cb();
          }
        });
      }
    }, waitTime || TERMINAL_CONNECTION_DEFAULT_RETRY_TIMEOUT);
  };

  MiuraDeviceUpdate.prototype._getCachedFile = function _getCachedFile(url, cb) {
    _manticore2.default.getItem(url, blobStorage, function (e, file) {
      cb(file ? null : _retailPaymentDevice.deviceError.swUpdateFailed.withDevMessage('File with url: ' + url + ' was not found on the device'), file);
    });
  };

  return MiuraDeviceUpdate;
}(_retailPaymentDevice.DeviceUpdate);

exports.default = MiuraDeviceUpdate;

}).call(this,require("buffer").Buffer)
},{"../common/Flow":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/build/common/Flow.js","../deviceState":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/build/deviceState.js","async":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/async/lib/async.js","buffer":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/buffer/index.js","manticore":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore/browser.js","manticore-log":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-log/index.js","md5":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/md5/md5.js","retail-payment-device":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/build/Terminal.js":[function(require,module,exports){
(function (Buffer){
'use strict';

var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };

exports.__esModule = true;
exports.Terminal = exports.TerminalEvent = exports.MiuraTransactionType = undefined;

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;if ("value" in descriptor) descriptor.writable = true;Object.defineProperty(target, descriptor.key, descriptor);
    }
  }return function (Constructor, protoProps, staticProps) {
    if (protoProps) defineProperties(Constructor.prototype, protoProps);if (staticProps) defineProperties(Constructor, staticProps);return Constructor;
  };
}();

var _manticoreLog = require('manticore-log');

var _manticoreLog2 = _interopRequireDefault(_manticoreLog);

var _events = require('events');

var _tlvlib = require('tlvlib');

var _retailPaymentDevice = require('retail-payment-device');

var _MiuraTags = require('./MiuraTags');

var _MiuraTags2 = _interopRequireDefault(_MiuraTags);

var _Parser = require('./Parser');

var _Writer = require('./Writer');

var _BatteryStatus = require('./messages/BatteryStatus');

var _BatteryStatus2 = _interopRequireDefault(_BatteryStatus);

var _TerminalStatus = require('./messages/TerminalStatus');

var _TerminalStatus2 = _interopRequireDefault(_TerminalStatus);

var _CardStatus = require('./messages/CardStatus');

var _CardStatus2 = _interopRequireDefault(_CardStatus);

var _KeyStatus = require('./messages/KeyStatus');

var _KeyStatus2 = _interopRequireDefault(_KeyStatus);

var _TerminalConfig = require('./TerminalConfig');

var _TerminalConfig2 = _interopRequireDefault(_TerminalConfig);

var _TerminalDisplay = require('./TerminalDisplay');

var _TerminalDisplay2 = _interopRequireDefault(_TerminalDisplay);

function _interopRequireDefault(obj) {
  return obj && obj.__esModule ? obj : { default: obj };
}

function _classCallCheck(instance, Constructor) {
  if (!(instance instanceof Constructor)) {
    throw new TypeError("Cannot call a class as a function");
  }
}

function _possibleConstructorReturn(self, call) {
  if (!self) {
    throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
  }return call && ((typeof call === 'undefined' ? 'undefined' : _typeof(call)) === "object" || typeof call === "function") ? call : self;
}

function _inherits(subClass, superClass) {
  if (typeof superClass !== "function" && superClass !== null) {
    throw new TypeError("Super expression must either be null or a function, not " + (typeof superClass === 'undefined' ? 'undefined' : _typeof(superClass)));
  }subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } });if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;
}

var Log = (0, _manticoreLog2.default)('miura.terminal');

var imageMatcherRegex = void 0;

function startTxCommon(txSequenceNumber, txType, amount, currencyCode) {
  var e0Tags = new _tlvlib.TlvList();
  var now = new Date();
  e0Tags.add(_tlvlib.Tags.TransactionDate, now);
  e0Tags.add(_tlvlib.Tags.TransactionTime, now);
  e0Tags.add(_tlvlib.Tags.TransactionType, txType);

  e0Tags.add(_tlvlib.Tags.AmountAuthorized, _tlvlib.Tags.AmountAuthorized.format.toBytes(amount, 6));
  e0Tags.add(_tlvlib.Tags.TransactionCurrencyCode, currencyCode);
  return e0Tags;
}

function buildApps(dr, response) {
  var appId = void 0;
  var appLabel = void 0;
  for (var i = 0; i < response.tlvs.values.length; i++) {
    var t = response.tlvs.values[i];
    if (t.tag === _tlvlib.Tags.TerminalApplicationIdentifier) {
      if (appId) {
        dr.apps.push([appId, appLabel]);
        appLabel = null;
      }
      appId = t.parse();
    } else if (t.tag === _tlvlib.Tags.ApplicationLabel) {
      if (appLabel && appId) {
        dr.apps.push([appId, appLabel]);
        appId = null;
      }
      appLabel = t.parse();
    }
  }
  if (appId) {
    dr.apps.push([appId, appLabel]);
  }
}

var MiuraTransactionType = exports.MiuraTransactionType = {
  SALE: 0,
  REFUND: 20
};

var TerminalEvent = exports.TerminalEvent = {
  unsolicited: _Parser.ParserEvent.unsolicited,
  deviceEvent: 'deviceEvent',
  cardPresented: 'cardPresented',
  cardRemoved: 'cardRemoved',
  error: 'error',
  seePhone: 'seePhone'
};

var Terminal = exports.Terminal = function (_EventEmitter) {
  _inherits(Terminal, _EventEmitter);

  function Terminal(sendFn, reader) {
    _classCallCheck(this, Terminal);

    var _this = _possibleConstructorReturn(this, _EventEmitter.call(this));

    _this.reader = reader;
    _this.parser = new _Parser.MiuraParser();

    _this.parser.on(TerminalEvent.unsolicited, function (m) {
      _this._emitUnsolicited(m);
    });
    _this.writer = new _Writer.Writer(_this, sendFn);
    _this.Config = new _TerminalConfig2.default(_this);
    // TODO get real model number from somewhere...
    _this.displayController = new _TerminalDisplay2.default('M010');
    return _this;
  }

  Terminal.prototype.didConnect = function didConnect() {
    this.parser.reset();
  };

  Terminal.prototype.received = function received(data) {
    this.parser.received(data);
  };

  /**
   * Put one or more responders at the front of the chain
   * @param responders
   */

  Terminal.prototype.injectResponders = function injectResponders(responders) {
    this.writer.responders = responders.concat(this.writer.responders);
  };

  Terminal.prototype._emitUnsolicited = function _emitUnsolicited(rz) {
    this.emit(TerminalEvent.unsolicited, rz);
    var detailMessage = rz;
    var tmpl = rz.apdu.template;
    if (rz.apdu.template === 0xE6) {
      detailMessage = new _TerminalStatus2.default(rz);
    } else if (rz.apdu.template === 0xE1) {
      if (rz.tlvs && rz.tlvs.find(_MiuraTags2.default.MiuraCardStatusInfo)) {
        detailMessage = new _CardStatus2.default(rz);
        this._reflectCardStatus(detailMessage);
      } else if (rz.tlvs && rz.tlvs.find(_MiuraTags2.default.MiuraKeyboardData)) {
        detailMessage = new _KeyStatus2.default(rz);
      }
    }
    Log.debug(function () {
      return 'Unsolicited message: ' + detailMessage;
    });
    this.emit(TerminalEvent.deviceEvent, detailMessage);
    if (tmpl) {
      this.emit(TerminalEvent.deviceEvent + '.' + tmpl.toString(16), detailMessage);
    }
    if (detailMessage instanceof _CardStatus2.default && (detailMessage.magstripeFlags & 1) === 1) {
      Log.debug(function () {
        return 'EMV Card Swiped ' + rz.raw.toString('hex');
      });
      this.emit(TerminalEvent.cardPresented, detailMessage.getPresentedCard(this.reader));
    }
  };

  Terminal.prototype._reflectCardStatus = function _reflectCardStatus(cardStatus) {
    var _this2 = this;

    var old = this.cardStatus || _retailPaymentDevice.CardStatus.None;
    if ((cardStatus.chipFlags & 0x3) === 0x3) {
      this.cardStatus = _retailPaymentDevice.CardStatus.EmvCard;
    } else if ((cardStatus.chipFlags & 0x1) === 0x1) {
      this.cardStatus = _retailPaymentDevice.CardStatus.NonEmvCard;
    } else {
      this.cardStatus = _retailPaymentDevice.CardStatus.None;
    }
    // Handle EMV card action here, magstripe happens below for no good reason
    Log.debug(function () {
      return 'Previous card status ' + old + '. New Status ' + _this2.cardStatus;
    });
    if (old !== this.cardStatus && (this.cardStatus & 0x3) > 0 || this.cardStatus === _retailPaymentDevice.CardStatus.EmvCard) {
      var card = cardStatus.getPresentedCard(this.reader);
      if (card.failed && card.formFactor === _retailPaymentDevice.FormFactor.Chip) {
        this.emit(TerminalEvent.error, _retailPaymentDevice.deviceError.invalidChip, card.formFactor);
        return;
      }
      if (card) {
        this.emit(TerminalEvent.cardPresented, card);
      } else {
        Log.warn('card is null so emitting nothing here!!!');
      }
    } else if (old !== this.cardStatus && this.cardStatus === _retailPaymentDevice.CardStatus.None) {
      this.emit(TerminalEvent.cardRemoved);
    } else {
      Log.debug('Neither cardPresented nor cardRemoved emitted!');
    }
  };

  Terminal.prototype.display = function display(messageId, values, callback, displaySystemIcons) {
    var msg = this.displayController.formatMessage(messageId, values, displaySystemIcons);
    var mediaMsg = this._parseMedia(msg);
    if (!msg) {
      callback(_retailPaymentDevice.deviceError.dataValidationError.withDevMessage('Empty Message'));
      return;
    }

    if (mediaMsg) {
      this.displayImageAndText(mediaMsg.imageId, mediaMsg.msg, callback);
      return;
    }

    this.showMessage(msg, callback, displaySystemIcons);
  };

  Terminal.prototype.displayAsync = function displayAsync(messageId, values, displaySystemIcons) {
    var msg, mediaMsg;
    return regeneratorRuntime.async(function displayAsync$(_context) {
      while (1) {
        switch (_context.prev = _context.next) {
          case 0:
            msg = this.displayController.formatMessage(messageId, values);
            mediaMsg = this._parseMedia(msg);

            if (msg) {
              _context.next = 4;
              break;
            }

            throw _retailPaymentDevice.deviceError.dataValidationError;

          case 4:
            if (!mediaMsg) {
              _context.next = 8;
              break;
            }

            _context.next = 7;
            return regeneratorRuntime.awrap(this.displayImageAndTextAsync(mediaMsg.imageId, mediaMsg.msg));

          case 7:
            return _context.abrupt('return');

          case 8:
            _context.next = 10;
            return regeneratorRuntime.awrap(this.showMessageAsync(msg, displaySystemIcons));

          case 10:
          case 'end':
            return _context.stop();
        }
      }
    }, null, this);
  };

  Terminal.prototype._parseMedia = function _parseMedia(msg) {
    if (!imageMatcherRegex) {
      imageMatcherRegex = /\$image\((.+)\)(?:\n)*(.*)/;
    }

    var match = imageMatcherRegex.exec(msg);
    if (!match) {
      return null;
    }

    return {
      imageId: match[1],
      msg: match[2]
    };
  };

  Terminal.prototype.displayImage = function displayImage(imageId, callback) {
    var cmd = new _tlvlib.ApduCommand(0xD2, 0xD2);
    cmd.appendString(Terminal.Images[imageId]);
    this.writer.sendAndReceive('displayImage', cmd, callback);
  };

  Terminal.prototype.displayImageAndText = function displayImageAndText(image, msg, callback) {
    var xText = 0,
        yText = 50,
        xImage = 0,
        yImage = 0;

    var e0Tags = new _tlvlib.TlvList();

    // Display image related tags
    var imagePosition = [_MiuraTags2.default.MiuraMediaCoordinates.valueToBytes(xImage), _MiuraTags2.default.MiuraMediaCoordinates.valueToBytes(yImage)];
    e0Tags.add(_MiuraTags2.default.MiuraMediaCoordinates, Buffer.concat(imagePosition));
    e0Tags.add(_MiuraTags2.default.MiuraImageData, _MiuraTags2.default.MiuraImageData.valueToBytes(image));

    // Display text related tags
    var textPosition = [_MiuraTags2.default.MiuraMediaCoordinates.valueToBytes(xText), _MiuraTags2.default.MiuraMediaCoordinates.valueToBytes(yText)];

    e0Tags.add(_MiuraTags2.default.MiuraMediaCoordinates, Buffer.concat(textPosition));
    e0Tags.add(_MiuraTags2.default.MiuraTextData, _MiuraTags2.default.MiuraTextData.valueToBytes(msg));

    var e0 = new _tlvlib.TlvList();
    e0.add(_MiuraTags2.default.MiuraCommandData, e0Tags);
    var cmd = new _tlvlib.ApduCommand(0xD2, 0x20, 0x00, 0x80);
    cmd.appendBytes(e0.toBytes());
    this.writer.sendAndReceive('displayImageAndText', cmd, callback);
  };

  Terminal.prototype.displayImageAndTextAsync = function displayImageAndTextAsync(image, msg) {
    var xText, yText, xImage, yImage, e0Tags, imagePosition, textPosition, e0, cmd;
    return regeneratorRuntime.async(function displayImageAndTextAsync$(_context2) {
      while (1) {
        switch (_context2.prev = _context2.next) {
          case 0:
            // For now only confirm-tip is using this Method and
            // is good with [0, 10, 0, 0]
            xText = 0, yText = 10, xImage = 0, yImage = 0;
            e0Tags = new _tlvlib.TlvList();

            // Display image related tags

            imagePosition = [_MiuraTags2.default.MiuraMediaCoordinates.valueToBytes(xImage), _MiuraTags2.default.MiuraMediaCoordinates.valueToBytes(yImage)];

            e0Tags.add(_MiuraTags2.default.MiuraMediaCoordinates, Buffer.concat(imagePosition));
            e0Tags.add(_MiuraTags2.default.MiuraImageData, _MiuraTags2.default.MiuraImageData.valueToBytes(image));

            // Display text related tags
            textPosition = [_MiuraTags2.default.MiuraMediaCoordinates.valueToBytes(xText), _MiuraTags2.default.MiuraMediaCoordinates.valueToBytes(yText)];

            e0Tags.add(_MiuraTags2.default.MiuraMediaCoordinates, Buffer.concat(textPosition));
            e0Tags.add(_MiuraTags2.default.MiuraTextData, _MiuraTags2.default.MiuraTextData.valueToBytes(msg));

            e0 = new _tlvlib.TlvList();

            e0.add(_MiuraTags2.default.MiuraCommandData, e0Tags);
            cmd = new _tlvlib.ApduCommand(0xD2, 0x20, 0x00, 0x00);

            cmd.appendBytes(e0.toBytes());
            _context2.next = 14;
            return regeneratorRuntime.awrap(this.writer.sendAndReceiveP('displayImageAndTextAsync', cmd));

          case 14:
          case 'end':
            return _context2.stop();
        }
      }
    }, null, this);
  };

  // ////////////////////////////////////////////////////////////////////
  // Commands
  // ////////////////////////////////////////////////////////////////////


  Terminal.prototype.softReset = function softReset(callback) {
    this.writer.sendAndReceive('softReset', new _tlvlib.ApduCommand(0xD0, 0), callback);
  };

  Terminal.prototype.hardReset = function hardReset(callback) {
    this.writer.sendAndReceive('hardReset', new _tlvlib.ApduCommand(0xD0, 0, 0x01), callback);
  };

  Terminal.prototype.abortTransaction = function abortTransaction(callback) {
    this.writer.sendAndReceive('abortTransaction', new _tlvlib.ApduCommand(0xD0, 0xFF), callback);
  };

  Terminal.prototype.abortTransactionAsync = function abortTransactionAsync() {
    return regeneratorRuntime.async(function abortTransactionAsync$(_context3) {
      while (1) {
        switch (_context3.prev = _context3.next) {
          case 0:
            _context3.next = 2;
            return regeneratorRuntime.awrap(this.writer.sendAndReceiveP('abortTransactionAsync', new _tlvlib.ApduCommand(0xD0, 0xFF)));

          case 2:
          case 'end':
            return _context3.stop();
        }
      }
    }, null, this);
  };

  // Response check for acceptable templates
  // ignore=true processes the result for templates to be ignored.
  // ignore expects the response to have a template, but that is not in the acceptableTemplates
  // tag indicates the tag that should be present in the response


  Terminal.prototype.getResponseCheck = function getResponseCheck(templateList, checkDescription, ignore, tag) {
    var responseCheck = function responseCheck(rz) {
      var error = null;
      var mine = false;
      var responseTemplate = rz && rz.apdu && rz.apdu.template;
      var templateTypeText = ignore ? 'Ignored templates' : 'Acceptable Templates';
      var hasTag = true;
      if (tag) {
        hasTag = !!(rz && rz.tlvs && rz.tlvs.find(tag));
      }
      if (responseTemplate) {
        mine = templateList.indexOf(responseTemplate) !== -1; // acceptableTemplates contains responseTemplate
        mine = ignore ? !mine : mine;
        mine = mine && hasTag;
        Log.debug(function () {
          return 'getResponseCheck ' + checkDescription + '. This is a response with template 0x' + responseTemplate.toString(16) + '. ' + templateTypeText + ' = ' + templateList + '.' + (tag ? 'tag[' + tag.name + ']=' + hasTag + '.' : '') + ' Mine=' + mine;
        });
      } else {
        Log.debug(function () {
          return 'getResponseCheck ' + checkDescription + ' This is a response with no template. ' + templateTypeText + ' = ' + templateList + '. Mine=' + mine;
        });
      }
      return [error, mine];
    };
    return responseCheck;
  };

  Terminal.prototype.getBatteryLevel = function getBatteryLevel(callback) {
    var responseCheck = this.getResponseCheck([0xE1], 'getBatteryLevel', false, _MiuraTags2.default.MiuraBatteryData);
    this.writer.sendAndReceive('getBatteryLevel', new _tlvlib.ApduCommand(0xD0, 0x62), { responseCheck: responseCheck }, function (err, rz) {
      var batteryInfo = null;
      if (rz && rz.tlvs && rz.tlvs.find(_MiuraTags2.default.MiuraBatteryData)) {
        batteryInfo = new _BatteryStatus2.default(rz).batteryInfo;
      }
      if (callback) {
        callback(err, batteryInfo);
      }
    });
  };

  Terminal.prototype.disconnectUsb = function disconnectUsb(callback) {
    this.writer.sendAndReceive('disconnectUsb', new _tlvlib.ApduCommand(0xD0, 0xC0), callback);
  };

  /**
   * Determine whether card status events are sent to your application
   * @param yesEvents truthy to get events, false to turn them off
   * @param callback called when the message has been acknowledged
   */

  Terminal.prototype.registerForCardEvents = function registerForCardEvents(yesEvents, callback) {
    this.writer.sendAndReceive(yesEvents ? 'registerForCardEvents' : 'unRegisterForCardEvents', new _tlvlib.ApduCommand(0xD0, 0x60, yesEvents ? 0x0F : 0), { noResponse: true }, callback);
  };

  /**
   * Determine whether keyboard events are sent to your application
   * @param yesEvents truthy to get events, false to turn them off
   * @param callback called when the message has been acknowledged
   */

  Terminal.prototype.registerForKeyboardEvents = function registerForKeyboardEvents(yesEvents, callback) {
    this.writer.sendAndReceive(yesEvents ? 'registerForKeyboardEvents' : 'unRegisterForKeyboardEvents', new _tlvlib.ApduCommand(0xD0, 0x61, yesEvents ? 1 : 0), callback);
  };

  Terminal.prototype.registerForKeyboardEventsAsync = function registerForKeyboardEventsAsync(yesEvents) {
    return regeneratorRuntime.async(function registerForKeyboardEventsAsync$(_context4) {
      while (1) {
        switch (_context4.prev = _context4.next) {
          case 0:
            _context4.next = 2;
            return regeneratorRuntime.awrap(this.writer.sendAndReceiveP(yesEvents ? 'registerForKeyboardEvents' : 'unRegisterForKeyboardEvents', new _tlvlib.ApduCommand(0xD0, 0x61, yesEvents ? 1 : 0)));

          case 2:
          case 'end':
            return _context4.stop();
        }
      }
    }, null, this);
  };

  Terminal.prototype.showMessage = function showMessage(message, callback, displaySystemIcons) {
    var systemIconsDisplayByte = displaySystemIcons ? 0x01 : 0;
    var cmd = new _tlvlib.ApduCommand(0xD2, 0x01, systemIconsDisplayByte, 0x80);
    cmd.appendString(message);
    Log.debug(function () {
      return 'Displaying: \'' + message + '\' icons: ' + !!displaySystemIcons;
    });
    this.writer.sendAndReceive('displayMessage', cmd, callback);
  };

  Terminal.prototype.showMessageAsync = function showMessageAsync(message, displaySystemIcons) {
    var systemIconsDisplayByte, cmd;
    return regeneratorRuntime.async(function showMessageAsync$(_context5) {
      while (1) {
        switch (_context5.prev = _context5.next) {
          case 0:
            systemIconsDisplayByte = displaySystemIcons ? 0x01 : 0;
            cmd = new _tlvlib.ApduCommand(0xD2, 0x01, systemIconsDisplayByte, 0x80);

            cmd.appendString(message);
            _context5.next = 5;
            return regeneratorRuntime.awrap(this.writer.sendAndReceiveP('displayMessage', cmd));

          case 5:
          case 'end':
            return _context5.stop();
        }
      }
    }, null, this);
  };

  /*
   Prompts: (0-based)
   Please Select
   Enter/Entrez/Voer
   Server Port
   Amount?
   Gratuity?
   Enter Last 4 Digits
   (1) Credit Account
   (2) Cheque Account
   (3) Savings Account
   Enter Budget Period
   (1) Manual Login
   (2) Card Swipe Login
   Prompt index 0x000D
   Enter Expiry Date
   Enter CVV2
   CHQ     SAV     CR
   Enter Cashback Amount
   Enter Store Number
   Enter User ID
   Enter Table Number
   Enter Check Number
   Select Either
   (1) Table Number
   (2) Check Number
   (1) Sale
   (2) Refund
   as MMYY
   Enter Amount
   (1) Full Amount
   (2) Partial Amount
   Account
   Straight or Budget?
   (1) Straight
   (2) Budget
   Enter mobile number
   Enter ref number
   1) 5%          10% (2
   3) 15%         20% (4
   5) Enter Amount
   1) 10%         15% (2
   3) 20%         25% (4
   5) Enter TIP Amount
   Enter TIP Amount
   Prompt index 0x002C
   Enter Gratuity
   Enter TIP
   TIP?
   Prompt index 0x0030
   Enter Issue Number
   Enter Start Date
   Prompt index 0x0033
   Enter refund amount
   1) 5%          2) 10%
   3) 15%         4) 20%
   Prompt index 0x0037
   Please Enter
   Prompt index 0x0039
   Prompt index 0x003A
   Prompt index 0x003B
   Prompt index 0x003C
   Prompt index 0x003D
   Prompt index 0x003E
   Prompt index 0x003F
   Prompt index 0x0040
   Try Again
   Select Account
   Prompt index 0x0043
   Prompt index 0x0044
   Prompt index 0x0045
   Prompt index 0x0046
   Prompt index 0x0047
   Prompt index 0x0048
   Prompt index 0x0049
   Prompt index 0x004A
   Prompt index 0x004B
   Prompt index 0x004C
   Prompt index 0x004D
   Prompt index 0x004E
   Prompt index 0x004F
   Prompt index 0x0050
   Prompt index 0x0051
   Prompt index 0x0052
   Auth Code
   Prompt index 0x0054
   $Revision: Miura-1-1 $
   */

  Terminal.prototype.promptForNumericEntry = function promptForNumericEntry(options, callback) {
    this._numericPrompt(options).then(function (card) {
      callback(null, card);
    }).catch(function (error) {
      callback(error, null);
    });
  };

  Terminal.prototype._numericPrompt = function _numericPrompt(options) {
    var promptIndexes, numberFormat, numberToEdit, autoEnt, piBuf, numBuf, cmd, e0Tags, e0, data, numTlv;
    return regeneratorRuntime.async(function _numericPrompt$(_context6) {
      while (1) {
        switch (_context6.prev = _context6.next) {
          case 0:
            promptIndexes = void 0;
            numberFormat = void 0;
            numberToEdit = void 0;
            autoEnt = 0;

            if (options.entryType === _retailPaymentDevice.NumericEntryType.ExpirationDate) {
              promptIndexes = '000E001B0000';
              numberFormat = '0400';
              autoEnt = 1;
            } else if (options.entryType === _retailPaymentDevice.NumericEntryType.Cvv) {
              promptIndexes = '0000000F0000';
              numberFormat = '0500';
            }

            piBuf = new Buffer(promptIndexes, 'hex');
            numBuf = new Buffer(numberFormat, 'hex');

            if (!(piBuf.length !== 4 && piBuf.length !== 6)) {
              _context6.next = 9;
              break;
            }

            throw _retailPaymentDevice.deviceError.dataValidationError.withDevMessage('Prompt index array must be 4 or 6 hex bytes (8 or 12 characters) referencing the prompts.txt file.');

          case 9:
            if (!(numBuf.length !== 2)) {
              _context6.next = 11;
              break;
            }

            throw _retailPaymentDevice.deviceError.dataValidationError.withDevMessage('Number format must be 2 hex bytes (4 characters)');

          case 11:
            cmd = new _tlvlib.ApduCommand(0xD2, 4, autoEnt, 1);
            e0Tags = new _tlvlib.TlvList();

            e0Tags.add(0xDFA206, piBuf);
            e0Tags.add(0xDFA207, numBuf);
            if (numberToEdit) {
              e0Tags.add(0xDFA208, new Buffer(numberToEdit.toString(), 'utf8'));
            }
            e0 = new _tlvlib.TlvList();

            e0.add(0xE0, e0Tags.toBytes());
            cmd.appendBytes(e0.toBytes());
            _context6.next = 21;
            return regeneratorRuntime.awrap(this.writer.sendAndReceiveP('numericPrompt', cmd));

          case 21:
            data = _context6.sent;

            if (data.tlvs) {
              _context6.next = 24;
              break;
            }

            throw _retailPaymentDevice.deviceError.numericEntryFailed;

          case 24:
            numTlv = data.tlvs.find(_MiuraTags2.default.MiuraNumericData);
            return _context6.abrupt('return', numTlv.parse());

          case 26:
          case 'end':
            return _context6.stop();
        }
      }
    }, null, this);
  };

  /*
   Prompts:
   Please Enter
   Card Number
   Account Number
   Enter Card Number
   Enter Account Number
   $File: acc-data-prompts $
   $Revision: 1.00 $
   */

  Terminal.prototype.promptForSecureAccountNumber = function promptForSecureAccountNumber(options, callback) {
    this._securePrompt(options).then(function (card) {
      callback(null, card);
    }).catch(function (error) {
      callback(error, null);
    });
  };

  Terminal.prototype._securePrompt = function _securePrompt(options) {
    var piBuf, cmd, e0Tags, e0, data, numTlv, card, masked, mmyy;
    return regeneratorRuntime.async(function _securePrompt$(_context7) {
      while (1) {
        switch (_context7.prev = _context7.next) {
          case 0:
            piBuf = new Buffer('00000004', 'hex');

            if (!(piBuf.length !== 4 && piBuf.length !== 6)) {
              _context7.next = 3;
              break;
            }

            throw _retailPaymentDevice.deviceError.dataValidationError.withDevMessage('Prompt index array must be 4 or 6 hex bytes (8 or 12 characters) referencing the prompts.txt file.');

          case 3:
            cmd = new _tlvlib.ApduCommand(0xD2, 0x5A, 0, 1);
            e0Tags = new _tlvlib.TlvList();

            e0Tags.add(0xDFA206, piBuf);
            e0 = new _tlvlib.TlvList();

            e0.add(0xE0, e0Tags.toBytes());
            cmd.appendBytes(e0.toBytes());
            _context7.next = 11;
            return regeneratorRuntime.awrap(this.writer.sendAndReceiveP('securePrompt', cmd));

          case 11:
            data = _context7.sent;

            if (data.tlvs) {
              _context7.next = 14;
              break;
            }

            throw _retailPaymentDevice.deviceError.secureEntryFailed;

          case 14:
            if (data.apdu.isSuccess) {
              _context7.next = 16;
              break;
            }

            throw _retailPaymentDevice.deviceError.actionCancelled;

          case 16:
            numTlv = data.tlvs.find(_MiuraTags2.default.MiuraNumericData);
            card = new _retailPaymentDevice.ManuallyEnteredCard();

            card.formFactor = _retailPaymentDevice.FormFactor.SecureManualEntry;
            card.emvData = data.apdu.data.toString('hex');
            card.reader = this.reader;
            masked = numTlv.parse();

            card.cardIssuer = _retailPaymentDevice.CardDataUtil.getCardIssuerFromCardNumber(masked);
            card.lastFourDigits = masked.substring(masked.length - 4);
            Log.debug('Card number entry complete');

            if (!options.expiration) {
              _context7.next = 30;
              break;
            }

            _context7.next = 28;
            return regeneratorRuntime.awrap(this._numericPrompt({
              entryType: _retailPaymentDevice.NumericEntryType.ExpirationDate
            }));

          case 28:
            mmyy = _context7.sent;

            card.expiration = '' + mmyy.substring(2) + mmyy.substring(0, 2);

          case 30:
            if (!options.cvv) {
              _context7.next = 36;
              break;
            }

            _context7.t0 = card;
            _context7.next = 34;
            return regeneratorRuntime.awrap(this._numericPrompt({
              entryType: _retailPaymentDevice.NumericEntryType.Cvv
            }));

          case 34:
            _context7.t1 = _context7.sent;

            _context7.t0.setCvv.call(_context7.t0, _context7.t1);

          case 36:
            return _context7.abrupt('return', card);

          case 37:
          case 'end':
            return _context7.stop();
        }
      }
    }, null, this);
  };

  Terminal.prototype.promptForTipEntry = function promptForTipEntry(amountBasedTip) {
    return regeneratorRuntime.async(function promptForTipEntry$(_context8) {
      while (1) {
        switch (_context8.prev = _context8.next) {
          case 0:
            _context8.next = 2;
            return regeneratorRuntime.awrap(this._tipPrompt(amountBasedTip));

          case 2:
            return _context8.abrupt('return', _context8.sent);

          case 3:
          case 'end':
            return _context8.stop();
        }
      }
    }, null, this);
  };

  Terminal.prototype._tipPrompt = function _tipPrompt(amountBasedTip) {
    var tipCommandData, tipCommandData1, e0Tags, e0, cmd, data, numTlv;
    return regeneratorRuntime.async(function _tipPrompt$(_context9) {
      while (1) {
        switch (_context9.prev = _context9.next) {
          case 0:
            tipCommandData = new Buffer([0x00, 0x00, 0x00, 0x2C, 0x00, 0x00]);
            tipCommandData1 = new Buffer([0x06, 0x00]);

            if (amountBasedTip) {
              tipCommandData = new Buffer([0x00, 0x00, 0x00, 0x2B, 0x00, 0x00]);
              tipCommandData1 = new Buffer([0x06, 0x02]);
            }
            e0Tags = new _tlvlib.TlvList();

            e0Tags.add(0xDFA206, tipCommandData);
            e0Tags.add(0xDFA207, tipCommandData1);
            e0 = new _tlvlib.TlvList();

            e0.add(_MiuraTags2.default.MiuraCommandData, e0Tags.toBytes());
            cmd = new _tlvlib.ApduCommand(0xD2, 0x04, 0x00, 0x01);

            cmd.appendBytes(e0.toBytes());
            _context9.next = 12;
            return regeneratorRuntime.awrap(this.writer.sendAndReceiveP('tipPrompt', cmd));

          case 12:
            data = _context9.sent;

            if (data.tlvs) {
              _context9.next = 15;
              break;
            }

            throw _retailPaymentDevice.deviceError.tipEntryFailed;

          case 15:
            numTlv = data.tlvs.find(_MiuraTags2.default.MiuraNumericData);
            return _context9.abrupt('return', numTlv.parse());

          case 17:
          case 'end':
            return _context9.stop();
        }
      }
    }, null, this);
  };

  Terminal.prototype.promptForOnDevicePayment = function promptForOnDevicePayment() {
    return regeneratorRuntime.async(function promptForOnDevicePayment$(_context10) {
      while (1) {
        switch (_context10.prev = _context10.next) {
          case 0:
            _context10.next = 2;
            return regeneratorRuntime.awrap(this._onDevicePaymentPrompt());

          case 2:
            return _context10.abrupt('return', _context10.sent);

          case 3:
          case 'end':
            return _context10.stop();
        }
      }
    }, null, this);
  };

  Terminal.prototype._onDevicePaymentPrompt = function _onDevicePaymentPrompt() {
    var promptIndexes, numberFormat, e0Tags, e0, cmd, data, numTlv;
    return regeneratorRuntime.async(function _onDevicePaymentPrompt$(_context11) {
      while (1) {
        switch (_context11.prev = _context11.next) {
          case 0:
            promptIndexes = new Buffer([0x00, 0x00, 0x00, 0x1C, 0x00, 0x00]); // Enter Amount

            numberFormat = new Buffer([0x06, 0x02]);
            e0Tags = new _tlvlib.TlvList();

            e0Tags.add(0xDFA206, promptIndexes);
            e0Tags.add(0xDFA207, numberFormat);
            e0 = new _tlvlib.TlvList();

            e0.add(_MiuraTags2.default.MiuraCommandData, e0Tags.toBytes());
            cmd = new _tlvlib.ApduCommand(0xD2, 0x04, 0x00, 0x01);

            cmd.appendBytes(e0.toBytes());
            _context11.next = 11;
            return regeneratorRuntime.awrap(this.writer.sendAndReceiveP('onDevicePaymentPrompt', cmd));

          case 11:
            data = _context11.sent;

            if (data.tlvs) {
              _context11.next = 14;
              break;
            }

            throw _retailPaymentDevice.deviceError.generic;

          case 14:
            numTlv = data.tlvs.find(_MiuraTags2.default.MiuraNumericData);
            return _context11.abrupt('return', numTlv.parse());

          case 16:
          case 'end':
            return _context11.stop();
        }
      }
    }, null, this);
  };

  Terminal.prototype.startICCTransaction = function startICCTransaction(txSequenceNumber, txType, amount, currencyCode, callback) {
    var e0Tags = startTxCommon(txSequenceNumber, txType, amount, currencyCode);
    var e0 = new _tlvlib.TlvList();
    e0.add(_MiuraTags2.default.MiuraCommandData, e0Tags);
    var cmd = new _tlvlib.ApduCommand(0xDE, 0xD1);
    cmd.appendBytes(e0.toBytes());
    this.writer.sendAndReceive('startChipTx', cmd, function (err, response) {
      var error = err || Terminal.parseContactError(response);
      if (error) {
        callback(error, response);
        return;
      }

      if (response.apdu.template === 0xe2 && response.tlvs.find(_tlvlib.Tags.TerminalApplicationIdentifier)) {
        var dr = new _retailPaymentDevice.AvailableApplications(response);
        buildApps(dr, response);
        dr.apdu = response.apdu;
        callback(null, dr);
      } else {
        // TODO more specific response objects to allow other reader types
        callback(null, response);
      }
    });
  };

  Terminal.parseContactError = function parseContactError(response) {
    if (!response || !response.apdu) {
      return _retailPaymentDevice.deviceError.badEmvData;
    }

    var apdu = response.apdu;
    if (apdu.template === 0xE5) {
      return _retailPaymentDevice.deviceError.contactIssuer;
    }

    var errorMap = {
      0x41: _retailPaymentDevice.deviceError.paymentCancelled,
      0x23: _retailPaymentDevice.deviceError.smartCardNotInSlot,
      0x25: _retailPaymentDevice.deviceError.cardBlocked,
      0x28: _retailPaymentDevice.deviceError.mustSwipeCard
    };

    if (apdu.sw1 === 0x9f && errorMap[apdu.sw2]) {
      return errorMap[apdu.sw2];
    }

    return null;
  };

  Terminal.prototype.startContactlessTransaction = function startContactlessTransaction(txSequenceNumber, txType, amount, currencyCode, callback) {
    var e0Tags = startTxCommon(txSequenceNumber, txType, amount, currencyCode);
    var e0 = new _tlvlib.TlvList();
    e0.add(_MiuraTags2.default.MiuraCommandData, e0Tags);
    var cmd = new _tlvlib.ApduCommand(0xDE, 0xC1, 0x04, 0x00);
    cmd.appendBytes(e0.toBytes());

    var responseCheck = function responseCheck(rz) {
      var error = null;
      var mine = false;
      var acceptableTemplates = [0xE3, 0xE4, 0xE5];
      var responseTemplate = rz && rz.apdu && rz.apdu.template;

      if (rz && rz.apdu && rz.apdu.sw1 === 0x9f && rz.apdu.sw2 === 0xff) {
        error = _retailPaymentDevice.deviceError.cannotAcceptMessage;
      } else {
        mine = acceptableTemplates.indexOf(responseTemplate) !== -1 || Terminal.parseContactlessError(rz);
      }

      return [error, mine];
    };

    this.writer.sendAndReceive('startNFCtx', cmd, { responseCheck: responseCheck }, function (err, response) {
      var error = err || Terminal.parseContactlessError(response);
      callback(error, response);
    });
  };

  Terminal.parseContactlessError = function parseContactlessError(response) {
    if (!response || !response.apdu) {
      return _retailPaymentDevice.deviceError.badEmvData;
    }

    var apdu = response.apdu;
    if (apdu.template === 0xE5) {
      return _retailPaymentDevice.deviceError.nfcNotAllowed;
    }

    var errorMap = {
      0x41: _retailPaymentDevice.deviceError.paymentCancelled,
      0x42: _retailPaymentDevice.deviceError.nfcTimeout,
      0x43: _retailPaymentDevice.deviceError.contactlessPaymentAbortedByCardInsert,
      0x44: _retailPaymentDevice.deviceError.contactlessPaymentAbortedByCardSwipe,
      0xc1: _retailPaymentDevice.deviceError.nfcNotAllowed,
      0xc2: _retailPaymentDevice.deviceError.tryDifferentCard,
      0xc3: _retailPaymentDevice.deviceError.mustInsertCard,
      0xcf: _retailPaymentDevice.deviceError.hardwareError
    };

    if (apdu.sw1 === 0x9f && errorMap[apdu.sw2]) {
      return errorMap[apdu.sw2];
    }

    if (!apdu.isSuccess) {
      return _retailPaymentDevice.deviceError.generic;
    }

    return null;
  };

  Terminal.prototype.continueTransaction = function continueTransaction(authCode, callback) {
    // The authCode is in fact a TLV buffer. Not the best name from the server for this. So we
    // hand pack the message to the terminal.
    var cmd = new _tlvlib.ApduCommand(0xDE, 0xD2);
    cmd.expectNoBytes = true;
    var e0 = new _tlvlib.TlvList();
    e0.add(0xE0, new Buffer(authCode, 'hex'));
    cmd.appendBytes(e0.toBytes());
    this.writer.sendAndReceive('continueTx', cmd, function (err, rz) {
      var rzError = void 0;
      if (rz.apdu && (rz.apdu.template === 0XE5 || !rz.apdu.data || rz.apdu.sw1 === 0x9f)) {
        rzError = _retailPaymentDevice.deviceError.contactIssuer;
      }
      callback(rzError || err, rz);
    });
  };

  Terminal.prototype.selectApplication = function selectApplication(aid, callback) {
    var responseCheck = this.getResponseCheck([0xE1], 'selectApplication', true);
    var cmd = new _tlvlib.ApduCommand(0xDE, 0xD2);
    cmd.expectNoBytes = true;
    var e0Tags = new _tlvlib.TlvList();
    e0Tags.add(_tlvlib.Tags.TerminalApplicationIdentifier, aid);
    var e0 = new _tlvlib.TlvList();
    e0.add(0xE0, e0Tags.toBytes());
    cmd.appendBytes(e0.toBytes());
    this.writer.sendAndReceive('selectApp', cmd, { responseCheck: responseCheck }, callback);
  };

  _createClass(Terminal, [{
    key: 'formFactors',
    get: function get() {
      // until we know for sure, assume we can only handle chip
      return this.Config && this.Config.formFactors || [_retailPaymentDevice.FormFactor.Chip, _retailPaymentDevice.FormFactor.MagneticCardSwipe];
    }
  }]);

  return Terminal;
}(_events.EventEmitter);

}).call(this,require("buffer").Buffer)
},{"./MiuraTags":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/build/MiuraTags.js","./Parser":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/build/Parser.js","./TerminalConfig":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/build/TerminalConfig.js","./TerminalDisplay":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/build/TerminalDisplay.js","./Writer":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/build/Writer.js","./messages/BatteryStatus":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/build/messages/BatteryStatus.js","./messages/CardStatus":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/build/messages/CardStatus.js","./messages/KeyStatus":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/build/messages/KeyStatus.js","./messages/TerminalStatus":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/build/messages/TerminalStatus.js","buffer":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/buffer/index.js","events":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/events/events.js","manticore-log":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-log/index.js","retail-payment-device":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/index.js","tlvlib":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/tlvlib/build/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/build/TerminalConfig.js":[function(require,module,exports){
(function (Buffer){
'use strict';

exports.__esModule = true;

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;if ("value" in descriptor) descriptor.writable = true;Object.defineProperty(target, descriptor.key, descriptor);
    }
  }return function (Constructor, protoProps, staticProps) {
    if (protoProps) defineProperties(Constructor.prototype, protoProps);if (staticProps) defineProperties(Constructor, staticProps);return Constructor;
  };
}();

var _tlvlib = require('tlvlib');

var _retailPaymentDevice = require('retail-payment-device');

var _manticoreLog = require('manticore-log');

var _manticoreLog2 = _interopRequireDefault(_manticoreLog);

var _MiuraTags = require('./MiuraTags');

var _MiuraTags2 = _interopRequireDefault(_MiuraTags);

var _DeviceCaps = require('./messages/DeviceCaps');

var _DeviceCaps2 = _interopRequireDefault(_DeviceCaps);

var _Writer = require('./Writer');

function _interopRequireDefault(obj) {
  return obj && obj.__esModule ? obj : { default: obj };
}

function _classCallCheck(instance, Constructor) {
  if (!(instance instanceof Constructor)) {
    throw new TypeError("Cannot call a class as a function");
  }
}

var Log = (0, _manticoreLog2.default)('miura.terminal.config');

function numberToBuffer(number, lengthInBytes) {
  var buf = new Buffer(lengthInBytes);
  buf.writeUIntBE(number, 0, lengthInBytes);
  return buf;
}

/**
 * Terminal commands related to device configuration
 */

var TerminalConfig = function () {
  function TerminalConfig(device) {
    _classCallCheck(this, TerminalConfig);

    this.device = device;
    this.writer = device.writer;
  }

  TerminalConfig.prototype.removeLogs = function removeLogs(callback) {
    Log.debug('removeLogs');
    this.writer.sendAndReceive('removeLogs', new _tlvlib.ApduCommand(0xD0, 0xE1, 0x01), callback);
  };

  TerminalConfig.prototype.archiveLogs = function archiveLogs(callback) {
    Log.debug('archiveLogs');
    this.writer.sendAndReceive('archiveLogs', new _tlvlib.ApduCommand(0xD0, 0xE1), callback);
  };

  /**
   * Select a file on the terminal, such as mpi.log
   * @param file
   * @param truncate
   * @param callback
   */

  TerminalConfig.prototype.selectFile = function selectFile(file, truncate, callback) {
    var cmd = new _tlvlib.ApduCommand(0, 0xA4, truncate ? 1 : 0);
    cmd.appendString(file);
    Log.debug(function () {
      return 'Miura Sending selectFile (' + file + ') ApduCommand: ' + cmd;
    });
    this.writer.sendAndReceive('selectFile', cmd, callback);
  };

  TerminalConfig.prototype.readBinary = function readBinary(offset, len, callback) {
    var cmd = void 0;
    if (offset > 0x7FFF) {
      cmd = new _tlvlib.ApduCommand(0, 0xB0, 0x80 | offset >> 16 & 0x7F, offset >> 8 & 0xFF);
      cmd.appendBytes(new Buffer([offset & 0xFF]));
    } else {
      cmd = new _tlvlib.ApduCommand(0, 0xB0, offset >> 8 & 0x7F, offset & 0xFF);
    }
    cmd.le = len;
    this.writer.sendAndReceive('readBinary', cmd, { rawResponse: true }, callback);
  };

  TerminalConfig.prototype.getConfiguration = function getConfiguration(callback) {
    this.writer.sendAndReceive('getConfig', new _tlvlib.ApduCommand(0xD0, 1), function (e, r) {
      if (r) {
        callback(e, new _DeviceCaps2.default(r));
      } else {
        callback(e, r);
      }
    });
  };

  TerminalConfig.prototype.getDeviceCapabilities = function getDeviceCapabilities(callback) {
    var _this = this;

    this.writer.sendAndReceive('getDeviceCapabilities', new _tlvlib.ApduCommand(0xD0, 2), function (e, r) {
      var deviceCaps = null;
      if (r && r.apdu.isSuccess) {
        deviceCaps = new _DeviceCaps2.default(r);
        _this._factors = [];
        if (deviceCaps.caps.Smartcard) {
          _this._factors.push(_retailPaymentDevice.FormFactor.Chip);
        }
        if (deviceCaps.caps.Contactless) {
          _this._factors.push(_retailPaymentDevice.FormFactor.EmvCertifiedContactless);
        }
        if (deviceCaps.caps.Mag) {
          _this._factors.push(_retailPaymentDevice.FormFactor.MagneticCardSwipe);
        }
        if (deviceCaps.caps.Keyboard) {
          _this._factors.push(_retailPaymentDevice.FormFactor.SecureManualEntry);
        }
      } else {
        Log.debug('Miura device does not support getDeviceCapabilities - proceeding with default capabilities.');
      }
      callback(e, deviceCaps);
    });
  };

  TerminalConfig.prototype.getP2PEStatus = function getP2PEStatus(callback) {
    this.writer.sendAndReceive('getP2PEStatus', new _tlvlib.ApduCommand(0xEE, 0xE0), callback);
  };

  TerminalConfig.prototype.initializeP2PE = function initializeP2PE(callback) {
    this.writer.sendAndReceive('initializeP2PE', new _tlvlib.ApduCommand(0xEE, 0xE1), callback);
  };

  TerminalConfig.prototype.importP2PE = function importP2PE(callback) {
    this.writer.sendAndReceive('importP2PE', new _tlvlib.ApduCommand(0xEE, 0xE2), callback);
  };

  TerminalConfig.prototype.getLogFile = function getLogFile(callback) {
    var _this2 = this;

    Log.debug('getLogFile');
    this.archiveLogs(function (eAl) {
      if (eAl) {
        Log.error('Failed to archive Logs: ' + eAl.message + '\n' + eAl.stack);
        callback(eAl);
        return;
      }
      _this2.getFile('mpi.log', function (eGf, rGf) {
        if (eGf) {
          Log.error('Failed to get mpi.log: ' + eGf.message + '\n' + eGf.stack);
        }
        callback(eGf, rGf);
        // ToDo: Decide whether we want to remove after copying, as recommended by Miura docs?
      });
    });
  };

  TerminalConfig.prototype.getFile = function getFile(filename, callback) {
    var _this3 = this;

    this.selectFile(filename, 0, function (e, rz) {
      if (e || !rz.apdu.isSuccess) {
        callback(e || new Error('Could not select file ' + filename), null);
        return;
      }
      var lenVal = rz.tlvs.find(_MiuraTags2.default.MiuraFileLength);
      if (!lenVal || !lenVal.bytes) {
        callback(new Error('Empty or missing file length for ' + filename));
        return;
      }
      var len = lenVal.parse();
      Log.debug('Fetching ' + len + ' bytes of ' + filename);
      var offset = 0;
      var bufs = [];
      var reader = function reader() {
        _this3.readBinary(offset, 250, function (err, rzReadBinary) {
          if (err) {
            callback(err);
            return;
          }
          len -= rzReadBinary.apdu.data.length;
          offset += rzReadBinary.apdu.data.length;
          bufs.push(rzReadBinary.apdu.data);
          if (len > 0) {
            reader();
            return;
          }
          callback(null, Buffer.concat(bufs));
        });
      };
      reader();
    });
  };

  TerminalConfig.prototype.streamBinary = function streamBinary(data, offset, timeout, md5, callback) {
    var cmd = new _tlvlib.ApduCommand(0, 0xd7, md5 ? 1 : 0);
    var e0Tags = new _tlvlib.TlvList();
    var isBuffer = Buffer.isBuffer(data);
    var e0 = new _tlvlib.TlvList();
    // If it's not a buffer, it's a base64 string
    var dataLength = isBuffer ? data.length : (0, _Writer.base64ByteLength)(data);
    e0Tags.add(_MiuraTags2.default.MiuraFileWriteOffset, numberToBuffer(offset, 3));
    e0Tags.add(_MiuraTags2.default.MiuraFileWriteLength, numberToBuffer(dataLength, 3));
    e0Tags.add(_MiuraTags2.default.MiuraFileWriteTimeout, numberToBuffer(timeout, 1));
    e0.add(_MiuraTags2.default.MiuraCommandData, e0Tags);
    cmd.appendBytes(e0.toBytes());
    Log.debug(function () {
      return 'Miura sending binary stream of ' + dataLength + ' bytes with offset ' + offset;
    });

    this.writer.sendAndReceive('streamBinary', cmd, { additionalData: data }, function (error, result) {
      var md5Error = null;
      if (!error && md5 && result && result.tlvs) {
        var terminalMD5 = result.tlvs.find(_MiuraTags2.default.MiuraFileMD5);
        terminalMD5 = terminalMD5 && terminalMD5.bytes.toString('hex');
        Log.debug(function () {
          return 'Comparing md5s. \nSource: ' + md5 + ' \nDestination: ' + terminalMD5;
        });
        if (md5 !== terminalMD5) {
          md5Error = new Error('Mismatched MD5 after streaming binary!');
        }
      }

      if (callback) {
        callback(error || md5Error, result);
      }
    });
  };

  _createClass(TerminalConfig, [{
    key: 'formFactors',
    get: function get() {
      return this._factors;
    }
  }]);

  return TerminalConfig;
}();

exports.default = TerminalConfig;

}).call(this,require("buffer").Buffer)
},{"./MiuraTags":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/build/MiuraTags.js","./Writer":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/build/Writer.js","./messages/DeviceCaps":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/build/messages/DeviceCaps.js","buffer":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/buffer/index.js","manticore-log":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-log/index.js","retail-payment-device":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/index.js","tlvlib":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/tlvlib/build/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/build/TerminalDisplay.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

var _manticoreLog = require('manticore-log');

var _manticoreLog2 = _interopRequireDefault(_manticoreLog);

var _retailPaymentDevice = require('retail-payment-device');

var _l10nManticore = require('l10n-manticore');

var _l10nManticore2 = _interopRequireDefault(_l10nManticore);

var _en = require('./strings/m010/en');

var _en2 = _interopRequireDefault(_en);

function _interopRequireDefault(obj) {
  return obj && obj.__esModule ? obj : { default: obj };
}

function _classCallCheck(instance, Constructor) {
  if (!(instance instanceof Constructor)) {
    throw new TypeError("Cannot call a class as a function");
  }
}

var Message = _retailPaymentDevice.PaymentDevice.Message;
var Log = (0, _manticoreLog2.default)('miura.terminal.displayFormatter');

function centerLine(l, w) {
  if (l.length >= w - 1 || l.length === 0) {
    return l;
  }
  return Array(Math.floor((w - l.length) / 2) + 1).join(' ') + l;
}

var TerminalDisplay = function () {
  function TerminalDisplay(model) {
    _classCallCheck(this, TerminalDisplay);

    this.model = model;
    // This needs to be listed as ifs so that browserify picks up all the relevant files.
    if (model === 'M010') {
      this.lines = 4; // TODO this comes from somewhere in the configs?
      this.lineWidth = 21; // TODO this comes from somewhere in the configs?
      this.l10n = (0, _l10nManticore2.default)({ en: _en2.default });
    }
  }

  TerminalDisplay.prototype.formatMessage = function formatMessage(messageId, values, displaySystemIcons) {
    var verticallyCenter = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : true;

    var actualMessageId = messageId === Message.SoftwareUpdateProgress && values ? 'SwUpdate.' + values.stage : messageId;
    var formatted = this.l10n(actualMessageId, values);
    if (formatted !== actualMessageId) {
      return this.centerString(formatted.split('\n'), displaySystemIcons, verticallyCenter).join('\n');
    }
    Log.error('Could not format message with id: ' + messageId + ' values: ' + JSON.stringify(values));
    return '';
  };

  TerminalDisplay.prototype.centerString = function centerString(lineOrLines, displaySystemIcons, verticallyCenter) {
    var actualLines = lineOrLines;
    if (typeof lineOrLines === 'string') {
      if (!this.lines) {
        return [centerLine(lineOrLines, this.lineWidth)];
      }
      actualLines = [lineOrLines];
    }
    var newStrs = [];
    for (var _iterator = actualLines, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
      var _ref;

      if (_isArray) {
        if (_i >= _iterator.length) break;
        _ref = _iterator[_i++];
      } else {
        _i = _iterator.next();
        if (_i.done) break;
        _ref = _i.value;
      }

      var l = _ref;

      newStrs.push(centerLine(l, this.lineWidth));
    }

    if (!verticallyCenter) {
      return newStrs;
    }

    if (!displaySystemIcons && newStrs.length < this.lines) {
      newStrs.unshift('');
    }

    var lines = this.lines;
    while (lines && lines > newStrs.length + 1) {
      newStrs.unshift('');
      lines -= 1;
    }

    return newStrs;
  };

  return TerminalDisplay;
}();

exports.default = TerminalDisplay;

},{"./strings/m010/en":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/build/strings/m010/en.js","l10n-manticore":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/l10n-manticore/index.js","manticore-log":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-log/index.js","retail-payment-device":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/build/Writer.js":[function(require,module,exports){
(function (Buffer){
'use strict';

exports.__esModule = true;
exports.Writer = exports.CommandStatus = undefined;

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;if ("value" in descriptor) descriptor.writable = true;Object.defineProperty(target, descriptor.key, descriptor);
    }
  }return function (Constructor, protoProps, staticProps) {
    if (protoProps) defineProperties(Constructor.prototype, protoProps);if (staticProps) defineProperties(Constructor, staticProps);return Constructor;
  };
}();

exports.buildCommandBytes = buildCommandBytes;
exports.base64ByteLength = base64ByteLength;

var _manticoreLog = require('manticore-log');

var _manticoreLog2 = _interopRequireDefault(_manticoreLog);

var _manticore = require('manticore');

var _manticore2 = _interopRequireDefault(_manticore);

var _yaku = require('yaku');

var _yaku2 = _interopRequireDefault(_yaku);

var _retailPaymentDevice = require('retail-payment-device');

var _Parser = require('./Parser');

function _interopRequireDefault(obj) {
  return obj && obj.__esModule ? obj : { default: obj };
}

function _classCallCheck(instance, Constructor) {
  if (!(instance instanceof Constructor)) {
    throw new TypeError("Cannot call a class as a function");
  }
}

var Log = (0, _manticoreLog2.default)('miura.writer');

function buildCommandBytes(apdu) {
  var lrc = 0;
  var preamble = new Buffer(3);
  preamble.writeUInt8(1, 0); // NAD always 1
  lrc ^= 1;
  preamble.writeUInt8(0, 1); // PCB always 0
  var meat = apdu.toBytes();
  if (meat.length > 255) {
    throw _retailPaymentDevice.deviceError.dataValidationError.withDevMessage('Miura command is too long, max 255 bytes, got ' + meat.length);
  }
  preamble.writeUInt8(meat.length, 2);
  lrc ^= meat.length;
  for (var i = 0; i < meat.length; i++) {
    lrc ^= meat[i];
  }
  var epilogue = new Buffer(1);
  epilogue.writeUInt8(lrc & 0xFF, 0);
  return Buffer.concat([preamble, meat, epilogue]);
}

function base64ByteLength(str) {
  var rawLength = str.length * (3 / 4);
  if (str[str.length - 1] === '=') {
    rawLength -= 1;
  }
  if (str[str.length - 2] === '=') {
    rawLength -= 1;
  }
  return rawLength;
}

var CommandStatus = exports.CommandStatus = {
  Queued: 0,
  AwaitingResponse: 1
};

/**
 * A class to manage outbound messages to the Terminal and hook up appropriate callbacks with
 * terminal responses.
 * @class
 */

var Writer = exports.Writer = function () {
  function Writer(terminal, sendFn) {
    var _this = this;

    _classCallCheck(this, Writer);

    this._terminal = terminal;
    this._sendFn = sendFn;
    this._parser = this._terminal.parser;
    this._parser.on(_Parser.ParserEvent.response, function (r) {
      _this._responseHandler(r);
    });
    this._terminal.reader.on(_retailPaymentDevice.PaymentDevice.Event.disconnected, function () {
      return _this._deviceDisconnected();
    });
    this._requestQueue = [];
    this._requestCounter = 0;
    this._responseQueue = [];
  }

  Writer.prototype.sendAndReceiveP = function sendAndReceiveP(cmdName, apdu, opts) {
    var _this2 = this;

    return new _yaku2.default(function (accept, reject) {
      _this2.sendAndReceive(cmdName, apdu, opts, function (error, result) {
        if (error) {
          reject(error);
        } else {
          accept(result);
        }
      });
    });
  };

  /**
   * Send a command to Miura and invoke the callback with the response from the device
   * Options:
   *   additionalData: (Buffer/Base64 string) additional data that must be sent with the apdu
   *   noResponse: (Boolean) if true then the request is not expected to get a response from the reader
   *   rawResponse: (Boolean) if true the response is expected to be a stream of raw data rather than a message
   *   responseCheck: (Function (response) => [error, handled]) if this request would receive a response first the responseCheck is invoked. It should return true for handled if it wants to claim the response, false if it wants the next request to attempt to handle it, and an error if the an error should be communicated to the next response
   * @param cmdName - Name for the Apdu command. Primarily used for logging purposes
   * @param apdu The tlvlib.ApduCommand to send
   * @param opts - An object containing one/many/none of the options described above OR a function which is shorthand for sendAndReceive(apdu, null, opts)
   * @param callback - The callback function to invoke on receiving an error (if any) and response from the reader
   */
  /* eslint-disable no-param-reassign */

  Writer.prototype.sendAndReceive = function sendAndReceive(name, apdu, opts, callback) {
    var _this3 = this;

    if (typeof opts === 'function') {
      callback = opts;
      opts = {};
    }

    opts = opts || {};

    Log.debug(function () {
      return 'Queueing \'' + name + '(' + _this3._requestCounter + ')\' ' + apdu.toString(true);
    });
    var dataParts = [buildCommandBytes(apdu)];
    if (opts.additionalData) {
      dataParts.push(opts.additionalData);
    }

    var requestData = {
      name: name,
      dataParts: dataParts,
      callback: callback,
      noResponse: opts.noResponse,
      rawResponse: opts.rawResponse,
      responseCheck: opts.responseCheck,
      status: CommandStatus.Queued,
      ordinal: this._requestCounter
    };
    this._requestCounter += 1;
    this._requestQueue.push(requestData);
    this._sendNext();
  };
  /* eslint-enable no-param-reassign */

  /**
   * If we're not already sending a message send the next one. recursive to send all available messages asap
   * @private
   */

  Writer.prototype._sendNext = function _sendNext() {
    var _this4 = this;

    if (this.sending) {
      return;
    }

    var cmd = this._requestQueue.find(function (x) {
      return x.status === CommandStatus.Queued;
    });
    if (cmd) {
      cmd.status = CommandStatus.AwaitingResponse;
      this.sending = true;
      this._updateParserExpectations();
      this._send(cmd.dataParts, function (error) {
        if (error || cmd.noResponse) {
          if (error) {
            Log.error('_sendNext failure: ' + error + ' ' + error.message);
          }

          var cmdIndex = _this4._requestQueue.findIndex(function (e) {
            return e.ordinal === cmd.ordinal;
          });
          if (cmdIndex !== -1) {
            _this4._requestQueue.splice(cmdIndex, 1);
          }

          if (cmd.callback) {
            cmd.callback(error);
          }
        }
        _this4.sending = false;
        _this4._sendNext();
      });
    } else {
      Log.debug('No suitable message to send');
    }
  };

  /**
   * Communicate the given data to the terminal. Implements recursive throttling and chunking to accommodate shortcomings in the comm stack
   * @private
   */

  Writer.prototype._send = function _send(dataParts, callback) {
    var _this5 = this;

    var offset = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;

    if (!this._terminal.reader.canPushCommands()) {
      if (callback) {
        callback(_retailPaymentDevice.deviceError.cannotAcceptMessage);
      }
      return;
    }

    var data = dataParts[0];
    var isBuffer = Buffer.isBuffer(data);
    var dataLen = isBuffer ? data.length : base64ByteLength(data);
    var bytesToWrite = dataLen - offset;
    var throttle = this.throttleInfo && this.throttleInfo.pause || 0;
    bytesToWrite = this.throttleInfo && bytesToWrite > this.throttleInfo.size ? this.throttleInfo.size : bytesToWrite;

    Log.debug(function () {
      return 'Sending data part. Total length: ' + dataLen + '. Offset: ' + offset + '. Length to send: ' + bytesToWrite + '. Remaining parts: ' + dataParts.length;
    });
    var sendArgs = void 0;
    if (offset || bytesToWrite < dataLen) {
      if (isBuffer) {
        // It's a buffer, so don't bother making the sendFn do the substring of an overly long base64
        sendArgs = data.slice(offset, offset + bytesToWrite).toString('base64');
      } else {
        // It's base64, so leave it alone and let native pull it out
        sendArgs = {
          data: data,
          offset: offset,
          len: bytesToWrite
        };
      }
    } else {
      sendArgs = isBuffer ? data.toString('base64') : data;
    }

    this._sendFn(sendArgs, function (error) {
      if (error) {
        if (callback) {
          callback(error);
        }
      } else {
        var newOffset = offset + bytesToWrite;
        if (newOffset >= dataLen) {
          dataParts.shift();
          newOffset = 0;
        }

        if (!dataParts.length) {
          Log.debug('Successfully sent message.');
          if (callback) {
            callback();
          }
        } else {
          _manticore2.default.setTimeout(function () {
            _this5._send(dataParts, callback, newOffset);
          }, throttle);
        }
      }
    });
  };

  /**
   * @private
   */

  Writer.prototype._updateParserExpectations = function _updateParserExpectations() {
    var currentRequest = this._requestQueue.length && this._requestQueue[0];
    if (currentRequest && currentRequest.status === CommandStatus.AwaitingResponse) {
      this._parser.expectRawBytes = currentRequest.rawResponse;
    } else {
      this._parser.expectRawBytes = false;
    }
  };

  /**
   * Clean up after device disconnection
   * @private
   */

  Writer.prototype._deviceDisconnected = function _deviceDisconnected() {
    for (var _iterator = this._requestQueue, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
      var _ref;

      if (_isArray) {
        if (_i >= _iterator.length) break;
        _ref = _iterator[_i++];
      } else {
        _i = _iterator.next();
        if (_i.done) break;
        _ref = _i.value;
      }

      var request = _ref;

      if (request.callback) {
        request.callback(_retailPaymentDevice.deviceError.deviceNotConnected);
      }
    }

    this._requestQueue = [];
    this._responseQueue = [];
    this._updateParserExpectations();
  };

  /**
   * Add a response to the queue so we can be sure to handle it in the order it was received
   * @private
   */

  Writer.prototype._responseHandler = function _responseHandler(rz) {
    this._responseQueue.push(rz);
    this._handleNextResponse();
  };

  /**
   * If we are not handling a response and there is one to handle find the associated request and do the right thing
   * @private
   */

  Writer.prototype._handleNextResponse = function _handleNextResponse() {
    var _this6 = this;

    if (!this._handlingResponse && this._responseQueue.length) {
      this._handlingResponse = true;
      // Skip over responses that don't meet specified criteria of the earlier messages.
      var response = this._responseQueue.shift();
      var template = response.apdu && response.apdu.template ? response.apdu.template.toString(16) : '<empty>';
      var sw1 = response.apdu && response.apdu.sw1 && response.apdu.sw1.toString(16);
      var sw2 = response.apdu && response.apdu.sw2 && response.apdu.sw2.toString(16);
      var raw = response.raw && response.raw.toString('hex');
      var requestIndex = 0;
      var request = null;
      var error = null;
      var handled = false;
      // eslint-disable-next-line no-constant-condition
      while (1) {
        // These remaining outstanding requests and responses should eventually get to 0.
        Log.debug(function () {
          return 'Remaining unhandled responses: ' + _this6._responseQueue.length + '. Remaining outstanding requests: ' + _this6._requestQueue.length + '.';
        });
        if (this._requestQueue.length <= requestIndex || this._requestQueue[requestIndex].status !== CommandStatus.AwaitingResponse) {
          // For now, ignore unexpected responses.
          this._handlingResponse = false;
          Log.warn('Unexpected response. Response template ' + template + ' SW1: ' + sw1 + ' SW2: ' + sw2);
          this._responseQueue = [];
          break;
        }

        request = this._requestQueue[requestIndex];

        if (!error && request.responseCheck) {
          var _request$responseChec = request.responseCheck(response);

          error = _request$responseChec[0];
          handled = _request$responseChec[1];
        } else {
          handled = true;
        }

        if (handled) {
          this._requestQueue.splice(requestIndex, 1);
          if (request.callback) {
            try {
              Log.debug('Response will be handled by request \'' + request.name + '(' + request.ordinal + ')\'. Response template ' + template + ' SW1: ' + sw1 + ' SW2: ' + sw2 + ' Raw: ' + raw + '. Remaining requests: ' + this._requestQueue.length);
              request.callback(error, response);
            } catch (x) {
              Log.error('Error ' + x + ' executing callback ' + request.callback);
              throw x;
            }
          }
          this._updateParserExpectations();
          this._handlingResponse = false;
          this._handleNextResponse();
          break;
        } else {
          requestIndex += 1;
        }
      }
    }
  };

  _createClass(Writer, [{
    key: 'throttleInfo',
    get: function get() {
      return this._terminal && this._terminal.reader.throttleInfo;
    }
  }]);

  return Writer;
}();

}).call(this,require("buffer").Buffer)
},{"./Parser":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/build/Parser.js","buffer":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/buffer/index.js","manticore":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore/browser.js","manticore-log":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-log/index.js","retail-payment-device":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/index.js","yaku":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/yaku/lib/yaku.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/build/cardMetadataParser.js":[function(require,module,exports){
(function (Buffer){
'use strict';

exports.__esModule = true;
exports.default = parseCardMetadata;

var _manticoreLog = require('manticore-log');

var _manticoreLog2 = _interopRequireDefault(_manticoreLog);

var _retailPaymentDevice = require('retail-payment-device');

var _tlvlib = require('tlvlib');

var _MiuraTags = require('./MiuraTags');

var _MiuraTags2 = _interopRequireDefault(_MiuraTags);

function _interopRequireDefault(obj) {
  return obj && obj.__esModule ? obj : { default: obj };
}

var Log = (0, _manticoreLog2.default)('paymentDevice.miura.cardMetadataParser');
var swipeLastFourRegexMatcher = void 0;

function getLastFourFormEMVChipAndEMVContactlessBlob(responsePacket) {
  // Masked PAN is present in various different tags.. We need to parse one by one until we get what we need..
  var lastFourTLV = responsePacket.tlvs.find(_MiuraTags2.default.MiuraMaskedPan) || responsePacket.tlvs.find(_MiuraTags2.default.MiuraMaskedICCTrack2) || responsePacket.tlvs.find(_MiuraTags2.default.MiuraMaskedTrack2) || responsePacket.tlvs.find(_MiuraTags2.default.MiuraMaskedContactlessTrack2);

  // If we still don't find the TLV corresponding to masked pan then give up...
  if (!lastFourTLV) {
    Log.warn('Unable to find the any TLV corresponding to masked pan');
    return null;
  }

  var val = lastFourTLV.bytes.toString('hex');
  if (!val) {
    Log.warn('lastFourTLV: ' + lastFourTLV);
    return null;
  }

  // With this blob we get the masked pan as [first 6 digits]ffffff[last 4 digits]ff..
  var indexMatcher = 'ffff';
  var index = val.indexOf(indexMatcher);
  var lastFourStr = val.substring(index + indexMatcher.length);

  // Lets get rid of all f's until we hit valid numeric code..
  while (lastFourStr.length > 0 && lastFourStr.charAt(0) === 'f') {
    lastFourStr = lastFourStr.substring(1);
  }

  return lastFourStr.substring(0, 4);
}

function lastFourDigits(formFactor, responsePacket) {
  var match = void 0;
  var emvData = responsePacket.apdu.data.toString('hex');
  if (formFactor === _retailPaymentDevice.FormFactor.MagneticCardSwipe) {
    if (!swipeLastFourRegexMatcher) {
      swipeLastFourRegexMatcher = /(?:2a){2,}(?!2a)((.){8})(?=3d)/;
    }
    match = swipeLastFourRegexMatcher.exec(emvData);
    if (match && match[1]) {
      var lastFourContainingString = new Buffer(match[1], 'hex').toString('utf8');
      if (lastFourContainingString.length >= 4) {
        var lastFour = lastFourContainingString.substring(0, 4);
        Log.debug(function () {
          return 'Got last four digits of card as ' + lastFour;
        });
        return lastFour;
      }
    }
  }

  if (formFactor === _retailPaymentDevice.FormFactor.Chip || formFactor === _retailPaymentDevice.FormFactor.EmvCertifiedContactless) {
    var _lastFour = getLastFourFormEMVChipAndEMVContactlessBlob(responsePacket);
    if (_lastFour) {
      Log.debug(function () {
        return 'Got last four digits of card as ' + _lastFour;
      });
      return _lastFour;
    }
  }

  Log.warn('Unable to parse last four digits (formFactor: ' + formFactor + ')');
  return null;
}

function getCardIssuer(formFactor, responsePacket) {
  if (formFactor === _retailPaymentDevice.FormFactor.MagneticCardSwipe) {
    var emvData = responsePacket.apdu.data.toString('hex');
    var start = emvData.toString().lastIndexOf('3b');
    var end = emvData.lastIndexOf('2a');

    if (start > end) {
      start = emvData.slice(0, end).lastIndexOf('3b');
    }

    if (end < 0 || start < 0) {
      return null;
    }

    emvData = emvData.substring(start + 2, end);
    var cardNumber = new Buffer(emvData, 'hex').toString('utf8');
    return _retailPaymentDevice.CardDataUtil.getCardIssuerFromCardNumber(cardNumber);
  }

  if (formFactor === _retailPaymentDevice.FormFactor.Chip || formFactor === _retailPaymentDevice.FormFactor.EmvCertifiedContactless) {
    var appLabel = responsePacket.tlvs.find(_tlvlib.Tags.ApplicationLabel);
    var appLabelVal = appLabel ? appLabel.parse() : null;
    return _retailPaymentDevice.CardDataUtil.getCardIssuerFromEmvAppLabel(appLabelVal);
  }

  return null;
}

function isSignatureCvmRequired(formFactor, responsePacket) {
  var cvmStatus = responsePacket.tlvs.find(_MiuraTags2.default.MiuraCardholderVerificationStatus);
  Log.debug(function () {
    return 'Signature data from card: ' + (cvmStatus ? cvmStatus.parse() : null) + '(cvmStatus)';
  });
  if (!cvmStatus) {
    return true;
  }
  var val = cvmStatus.parse();
  if (!val) {
    return true;
  }

  val = val[0];
  if (formFactor === _retailPaymentDevice.FormFactor.Chip) {
    if (val === 1 || val === 2 || val === 4 || val === 0x1F) {
      return false;
    }
  } else if (val === 0 || val === 2 || val === 3) {
    return false;
  }
  return true;
}

function getCardHolderName(formFactor, responsePacket) {
  if (formFactor === _retailPaymentDevice.FormFactor.MagneticCardSwipe) {
    return null; // TODO
  }

  if (formFactor === _retailPaymentDevice.FormFactor.Chip || formFactor === _retailPaymentDevice.FormFactor.EmvCertifiedContactless) {
    var cardHolderName = responsePacket.tlvs.find(_tlvlib.Tags.CardholderName);
    return cardHolderName ? cardHolderName.parse() : null;
  }

  return null;
}

function parseCardMetadata(formFactor, deviceResponse) {
  var cardData = {};
  try {
    cardData = {
      lastFourDigits: lastFourDigits(formFactor, deviceResponse),
      cardIssuer: getCardIssuer(formFactor, deviceResponse),
      isSignatureRequired: isSignatureCvmRequired(formFactor, deviceResponse),
      cardholderName: getCardHolderName(formFactor, deviceResponse)
    };
    Log.debug(function () {
      return 'Parsed card metadata: ' + JSON.stringify(cardData);
    });
    cardData.emvData = deviceResponse;
  } catch (e) {
    Log.error('Unable to parse card metadata: ' + e + ' from : ' + deviceResponse);
  }
  return cardData;
}

}).call(this,require("buffer").Buffer)
},{"./MiuraTags":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/build/MiuraTags.js","buffer":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/buffer/index.js","manticore-log":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-log/index.js","retail-payment-device":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/index.js","tlvlib":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/tlvlib/build/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/build/common/Flow.js":[function(require,module,exports){
'use strict';

var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };

exports.__esModule = true;

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;if ("value" in descriptor) descriptor.writable = true;Object.defineProperty(target, descriptor.key, descriptor);
    }
  }return function (Constructor, protoProps, staticProps) {
    if (protoProps) defineProperties(Constructor.prototype, protoProps);if (staticProps) defineProperties(Constructor, staticProps);return Constructor;
  };
}();

var _manticoreLog = require('manticore-log');

var _manticoreLog2 = _interopRequireDefault(_manticoreLog);

var _events = require('events');

function _interopRequireDefault(obj) {
  return obj && obj.__esModule ? obj : { default: obj };
}

function _classCallCheck(instance, Constructor) {
  if (!(instance instanceof Constructor)) {
    throw new TypeError("Cannot call a class as a function");
  }
}

function _possibleConstructorReturn(self, call) {
  if (!self) {
    throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
  }return call && ((typeof call === 'undefined' ? 'undefined' : _typeof(call)) === "object" || typeof call === "function") ? call : self;
}

function _inherits(subClass, superClass) {
  if (typeof superClass !== "function" && superClass !== null) {
    throw new TypeError("Super expression must either be null or a function, not " + (typeof superClass === 'undefined' ? 'undefined' : _typeof(superClass)));
  }subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } });if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;
}

var FACADE = Symbol('facade');
var Log = (0, _manticoreLog2.default)('manticore-log');

// TODO Somehow reuse from retail-sdk/common/flow.js

/**
 * Present a protected view of the flow to a particular step so that it can't call the
 * true flow step after it is deactivated.
 */

var FlowFacade = function (_EventEmitter) {
  _inherits(FlowFacade, _EventEmitter);

  function FlowFacade(flow) {
    _classCallCheck(this, FlowFacade);

    var _this = _possibleConstructorReturn(this, _EventEmitter.call(this));

    _this.active = true;
    _this.flow = flow;
    return _this;
  }

  FlowFacade.prototype._prepareForChange = function _prepareForChange(noPush) {
    var f = this.flow;
    if (!noPush) {
      f.previousSteps.push(f.stepIndex);
    }
    if (f[FACADE]) {
      f[FACADE].active = false;
    }
    f[FACADE] = new FlowFacade(f);
  };

  FlowFacade.prototype._check = function _check() {
    if (!this.active) {
      Log.error('Flow step completion function called by inactive step ' + this.stepName + '!');
      this.flow.emit('flowError', new Error('Flow step completion function called by inactive step!'));
      return false;
    }
    return true;
  };

  FlowFacade.prototype._executeStep = function _executeStep(index) {
    var _this2 = this;

    var direction = index < this.flow.stepIndex ? 'regressing' : 'advancing';
    this.flow.stepIndex = index;
    var stepFn = this.flow.steps[index];
    Log.debug(function () {
      return 'Flow ' + direction + ' to ' + _this2.stepName;
    });

    try {
      stepFn.call(this.flow.owner, this.flow[FACADE]);
    } catch (e) {
      Log.error(this.stepName + ' execution returned an error: ' + e);
      this.flow[FACADE].abortFlow(e);
    }
  };

  /**
   * A flow step should call next to advance to the next step, or complete if it's the last
   */

  FlowFacade.prototype.next = function next() {
    if (!this._check()) {
      Log.debug('Flow::next called out of turn!');
      return;
    }
    var f = this.flow;
    if (f.stepIndex + 1 >= f.steps.length) {
      this.completeFlow();
      return;
    }
    f.emit('next', f.stepIndex);
    this._prepareForChange();
    this._executeStep(f.stepIndex + 1);
  };

  /**
   * A flow step should call back to end the current step and go back to the previous step
   * (or abort if you're the first)
   * TODO how do we continue to go back if the previous step was skipped?
   */

  FlowFacade.prototype.back = function back() {
    if (!this._check()) {
      Log.debug('Flow::back called out of turn!');
      return;
    }
    var f = this.flow;
    if (f.previousSteps.length === 0) {
      this.abortFlow();
      return;
    }
    f.emit('back', f.steps[f.stepIndex], f.steps[f.stepIndex - 1]);
    this._prepareForChange(true);
    this._executeStep(f.previousSteps.pop());
  };

  /**
   * Immediately complete the flow, firing the completed event
   */

  FlowFacade.prototype.completeFlow = function completeFlow() {
    var _this3 = this;

    if (!this._check()) {
      Log.debug('Flow::complete called out of turn!');
      return;
    }
    Log.debug(function () {
      return (_this3.flow.name || 'Anonymous') + ' Flow completed.';
    });
    var f = this.flow;
    this._prepareForChange();
    f.stepIndex = null;
    f[FACADE] = null;
    f.emit('completed', null, f.data);
  };

  /**
   * Immediately abort the flow, firing the aborted event
   */

  FlowFacade.prototype.abortFlow = function abortFlow(error) {
    if (!this._check()) {
      Log.debug('Flow::abortFlow called out of order!');
      return;
    }
    Log.debug((this.flow.name || 'Anonymous') + ' Flow aborted');
    var f = this.flow;
    if (error) {
      f.data.error = error;
    }
    f[FACADE].emit('aborted');
    this._prepareForChange();
    f.stepIndex = null;
    f[FACADE] = null;
    f.emit('completed', error, f.data);
  };

  FlowFacade.prototype.nextOrAbort = function nextOrAbort(error) {
    if (error) {
      this.abortFlow(error);
    } else {
      this.next();
    }
  };

  _createClass(FlowFacade, [{
    key: 'stepName',
    get: function get() {
      var fn = this.flow.steps[this.flow.stepIndex];
      return fn ? fn.fnName || fn.name : undefined;
    }
  }, {
    key: 'data',
    get: function get() {
      return this.flow.data;
    }
  }, {
    key: 'stepIndex',
    get: function get() {
      return this.flow.stepIndex;
    }
  }, {
    key: 'previousSteps',
    get: function get() {
      return this.flow.previousSteps;
    }
  }]);

  return FlowFacade;
}(_events.EventEmitter);

/**
 * A flow is a series of steps in order to complete a process. Each step may complete, cancel, go forward or back
 * in the process. In code, a flow is an array of functions. The functions take one argument - a flow controller -
 * which exposes methods to control the next step in the flow.
 *
 */

var Flow = function (_EventEmitter2) {
  _inherits(Flow, _EventEmitter2);

  /**
   * Construct a new flow with steps pass as individual arguments (each a function) OR
   * as a single array as the second argument.
   * Call start() after setting up appropriate event handlers.
   */
  function Flow(thisForSteps, allSteps) {
    _classCallCheck(this, Flow);

    var _this4 = _possibleConstructorReturn(this, _EventEmitter2.call(this));

    _this4.owner = thisForSteps;
    if (Array.isArray(allSteps)) {
      _this4.steps = allSteps;
    } else {
      _this4.steps = Array.prototype.slice.call(arguments, 1); // eslint-disable-line prefer-rest-params
    }

    /**
     * A grab bag of data that can be used to share information among steps
     * @type {object}
     */
    _this4.data = {};
    _this4[FACADE] = null;
    _this4.stepIndex = 0;
    _this4.previousSteps = [];
    return _this4;
  }

  Flow.prototype.start = function start() {
    this[FACADE] = new FlowFacade(this);
    this[FACADE]._executeStep(0);
    return this;
  };

  Flow.prototype.abortFlow = function abortFlow(error) {
    if (!this[FACADE]) {
      Log.error('Abort called on an inactive flow!');
      return;
    }
    this[FACADE].abortFlow(error);
  };

  return Flow;
}(_events.EventEmitter);

exports.default = Flow;

},{"events":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/events/events.js","manticore-log":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-log/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/build/deviceState.js":[function(require,module,exports){
"use strict";

exports.__esModule = true;
/**
 * Indicates the current state of the device
 */
var deviceState = {
  unknown: 0,
  softwareUpdate: 1,
  hardResetting: 2
};

exports.default = deviceState;

},{}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/build/index.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

var _MiuraDevice = require('./MiuraDevice');

Object.defineProperty(exports, 'default', {
  enumerable: true,
  get: function get() {
    return _interopRequireDefault(_MiuraDevice).default;
  }
});

function _interopRequireDefault(obj) {
  return obj && obj.__esModule ? obj : { default: obj };
}

},{"./MiuraDevice":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/build/MiuraDevice.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/build/messages/BatteryStatus.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

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;if ("value" in descriptor) descriptor.writable = true;Object.defineProperty(target, descriptor.key, descriptor);
    }
  }return function (Constructor, protoProps, staticProps) {
    if (protoProps) defineProperties(Constructor.prototype, protoProps);if (staticProps) defineProperties(Constructor, staticProps);return Constructor;
  };
}();

var _retailPaymentDevice = require('retail-payment-device');

function _classCallCheck(instance, Constructor) {
  if (!(instance instanceof Constructor)) {
    throw new TypeError("Cannot call a class as a function");
  }
}

var BatteryStatus = function () {
  function BatteryStatus(apduResponse) {
    _classCallCheck(this, BatteryStatus);

    this.response = apduResponse;
    for (var _iterator = this.response.tlvs.values, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
      var _ref;

      if (_isArray) {
        if (_i >= _iterator.length) break;
        _ref = _iterator[_i++];
      } else {
        _i = _iterator.next();
        if (_i.done) break;
        _ref = _i.value;
      }

      var v = _ref;

      if (v.tagNumber === 0xdfa209) {
        this._readStatus(v);
      } else if (v.tagNumber === 0xdfa20a) {
        this.batteryPercentage = v.bytes[0];
      }
    }
    this.measuredOn = new Date();
  }

  BatteryStatus.prototype._readStatus = function _readStatus(v) {
    switch (v.bytes[0]) {
      case 0:
        this.status = _retailPaymentDevice.batteryStatus.draining;
        this.connectedToPower = false;
        break;
      case 1:
        this.status = _retailPaymentDevice.batteryStatus.charging;
        this.connectedToPower = true;
        break;
      case 2:
        this.status = _retailPaymentDevice.batteryStatus.charged;
        this.connectedToPower = true;
        break;
      case 0xFF:
        this.status = _retailPaymentDevice.batteryStatus.drained;
        this.connectedToPower = false;
        break;
      default:
        this.status = _retailPaymentDevice.batteryStatus.unknown;
        this.connectedToPower = false;
        break;
    }
  };

  BatteryStatus.prototype.toString = function toString() {
    return 'Battery Status: ' + this.status + ' (' + this.batteryPercentage + '%), ConnectedToPower? ' + this.connectedToPower;
  };

  _createClass(BatteryStatus, [{
    key: 'batteryInfo',
    get: function get() {
      return new _retailPaymentDevice.BatteryInfo(this.batteryPercentage, this.connectedToPower, this.measuredOn, this.status);
    }
  }]);

  return BatteryStatus;
}();

exports.default = BatteryStatus;

},{"retail-payment-device":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/build/messages/CardStatus.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

var _retailPaymentDevice = require('retail-payment-device');

var _manticoreLog = require('manticore-log');

var _manticoreLog2 = _interopRequireDefault(_manticoreLog);

var _manticoreUtil = require('manticore-util');

var _cardMetadataParser = require('../cardMetadataParser');

var _cardMetadataParser2 = _interopRequireDefault(_cardMetadataParser);

function _interopRequireDefault(obj) {
  return obj && obj.__esModule ? obj : { default: obj };
}

function _classCallCheck(instance, Constructor) {
  if (!(instance instanceof Constructor)) {
    throw new TypeError("Cannot call a class as a function");
  }
}

var Log = (0, _manticoreLog2.default)('miura.cardStatus');

/**
 * Contain the details of card events on the Miura terminal such as insertion,
 * swipe, removal, etc.
 */

var CardStatus = function () {
  function CardStatus(miuraResponse) {
    _classCallCheck(this, CardStatus);

    this.response = miuraResponse;
    for (var _iterator = this.response.tlvs.values, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
      var _ref;

      if (_isArray) {
        if (_i >= _iterator.length) break;
        _ref = _iterator[_i++];
      } else {
        _i = _iterator.next();
        if (_i.done) break;
        _ref = _i.value;
      }

      var v = _ref;

      if (v.tagNumber === 0x48) {
        this.chipFlags = v.bytes[0];
        this.magstripeFlags = v.bytes[1];
      } else if (v.tagNumber === 0xdfae03) {
        this.ksn = v.parse();
      } else if (v.tagNumber === 0xdfae02) {
        this.sredData = v.parse();
      } else if (v.tagNumber === 0xdfae22) {
        this.maskedTrack2 = v.parse();
      } else if (v.tagNumber === 0x5f22) {
        this.track2 = v.parse();
      } else if (v.tagNumber === 0xdf30) {
        this.formFactor = _retailPaymentDevice.FormFactor.EmvCertifiedContactless;
        var contactlessMode = v.bytes[1];
        // Contactless MSD would be set to either 0 or 2
        this.emv = !(contactlessMode === 0 || contactlessMode === 2);
      }
    }
    this.p2pe = miuraResponse.apdu.data.slice(1).toString('hex');
  }

  CardStatus.prototype.getPresentedCard = function getPresentedCard(reader) {
    var card = void 0;
    if ((this.magstripeFlags & 0x1) === 0x1) {
      return this._magstripe(reader);
    } else if ((this.chipFlags & 0x3) === 0x3) {
      card = new _retailPaymentDevice.Card();
      card.formFactor = _retailPaymentDevice.FormFactor.Chip;
      card.reader = reader;
      Log.debug('EMV Card Inserted');
      return card;
    } else if ((this.chipFlags & 0x1) === 0x1) {
      card = new _retailPaymentDevice.Card();
      card.formFactor = _retailPaymentDevice.FormFactor.Chip;
      card.reader = reader;
      card.failed = true;
      Log.warn('EMV Chip Invalid');
      return card;
    } else if (this.formFactor === _retailPaymentDevice.FormFactor.EmvCertifiedContactless) {
      card = new _retailPaymentDevice.Card();
      card.formFactor = _retailPaymentDevice.FormFactor.EmvCertifiedContactless;
      card.emvData = this.response;
      card.reader = reader;
      card.failed = this.response.apdu.template === 0xE5;
      card.isContactlessMSD = !this.emv;
      (0, _manticoreUtil.extend)(card, (0, _cardMetadataParser2.default)(card.formFactor, this.response), true);
      return card;
    }
    return null;
  };

  CardStatus.prototype._magstripe = function _magstripe(reader) {
    var card = new _retailPaymentDevice.MagneticCard();
    var track = this.maskedTrack2 || this.track2;
    if (!track || !track.length) {
      Log.error('Missing card swipe data maskedTrack2:  \'' + this.maskedTrack2 + '\' track2: \'' + this.track2 + '\'');
      card.failed = true;
      return card;
    }
    var start = track.indexOf('=');
    var serviceCode = track.substring(start + 5, start + 6);

    card.formFactor = _retailPaymentDevice.FormFactor.MagneticCardSwipe;
    card.ksn = this.ksn ? this.ksn.toString('hex') : '';
    card.reader = reader;
    if (start < 6) {
      Log.error('Missing track2 = sentinel from card swipe data');
      card.failed = true;
      return card;
    }
    if (serviceCode === '2' || serviceCode === '6') {
      card.chipCard = true;
    }
    card.track2 = this.response.apdu.data.toString('hex');
    (0, _manticoreUtil.assignExcept)(card, (0, _cardMetadataParser2.default)(card.formFactor, this.response), 'isSignatureRequired');
    return card;
  };

  CardStatus.prototype.toString = function toString() {
    var parts = [this.response.toString(), '\nChip flags ', this.chipFlags.toString(16), ' Magstripe flags ', this.magstripeFlags.toString(16)];
    if (this.ksn) {
      parts.push('\nKSN: ');
      parts.push(this.ksn.toString('hex'));
    }
    if (this.track2) {
      parts.push('\nTrack 2: ');
      parts.push(this.track2.toString('hex'));
    }
    if (this.maskedTrack2) {
      parts.push('\nMasked Track 2: ');
      parts.push(this.maskedTrack2);
    }
    if (this.sredData) {
      parts.push('\nSRED: ');
      parts.push(this.sredData.toString('hex'));
    }
    return parts.join('');
  };

  return CardStatus;
}();

exports.default = CardStatus;

},{"../cardMetadataParser":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/build/cardMetadataParser.js","manticore-log":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-log/index.js","manticore-util":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-util/build/index.js","retail-payment-device":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/build/messages/DeviceCaps.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

var _MiuraTags = require('../MiuraTags');

var _MiuraTags2 = _interopRequireDefault(_MiuraTags);

function _interopRequireDefault(obj) {
  return obj && obj.__esModule ? obj : { default: obj };
}

function _classCallCheck(instance, Constructor) {
  if (!(instance instanceof Constructor)) {
    throw new TypeError("Cannot call a class as a function");
  }
}

var DeviceCaps = function () {
  function DeviceCaps(apduResponse) {
    _classCallCheck(this, DeviceCaps);

    this.response = apduResponse;
    this.caps = {};
    for (var _iterator = this.response.tlvs.values, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
      var _ref;

      if (_isArray) {
        if (_i >= _iterator.length) break;
        _ref = _iterator[_i++];
      } else {
        _i = _iterator.next();
        if (_i.done) break;
        _ref = _i.value;
      }

      var v = _ref;

      if (v.tagNumber === _MiuraTags2.default.MiuraConfigurationInformation.number) {
        this.readPair(v.parse());
      }
    }
  }

  DeviceCaps.prototype.readPair = function readPair(tlv) {
    var key = void 0;
    var val = true;
    for (var _iterator2 = tlv.values, _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) {
      var _ref2;

      if (_isArray2) {
        if (_i2 >= _iterator2.length) break;
        _ref2 = _iterator2[_i2++];
      } else {
        _i2 = _iterator2.next();
        if (_i2.done) break;
        _ref2 = _i2.value;
      }

      var v = _ref2;

      if (v.tagNumber === _MiuraTags2.default.MiuraIdentifier.number) {
        key = v.parse();
      } else if (v.tagNumber === _MiuraTags2.default.MiuraVersionInformation.number) {
        val = v.parse();
      }
    }
    if (key) {
      this.caps[key] = val;
    }
  };

  DeviceCaps.prototype.toString = function toString() {
    var parts = [this.response.toString(), '\nCapabilities: '];
    for (var _iterator3 = this.caps, _isArray3 = Array.isArray(_iterator3), _i3 = 0, _iterator3 = _isArray3 ? _iterator3 : _iterator3[Symbol.iterator]();;) {
      var _ref3;

      if (_isArray3) {
        if (_i3 >= _iterator3.length) break;
        _ref3 = _iterator3[_i3++];
      } else {
        _i3 = _iterator3.next();
        if (_i3.done) break;
        _ref3 = _i3.value;
      }

      var k = _ref3;

      parts.push('  ');
      parts.push(k);
      if (this.caps[k] && this.caps[k] !== true) {
        parts.push(': ');
        parts.push(this.caps[k]);
      }
    }
    return parts.join('');
  };

  return DeviceCaps;
}();

exports.default = DeviceCaps;

},{"../MiuraTags":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/build/MiuraTags.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/build/messages/KeyStatus.js":[function(require,module,exports){
"use strict";

exports.__esModule = true;

function _classCallCheck(instance, Constructor) {
  if (!(instance instanceof Constructor)) {
    throw new TypeError("Cannot call a class as a function");
  }
}

var KeyStatus = function () {
  function KeyStatus(miuraResponse) {
    _classCallCheck(this, KeyStatus);

    this.response = miuraResponse;
    for (var _iterator = this.response.tlvs.values, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
      var _ref;

      if (_isArray) {
        if (_i >= _iterator.length) break;
        _ref = _iterator[_i++];
      } else {
        _i = _iterator.next();
        if (_i.done) break;
        _ref = _i.value;
      }

      var v = _ref;

      if (v.tagNumber === 0xdfa205) {
        this.keyCode = v.bytes[0];
      }
    }
  }

  KeyStatus.prototype.toString = function toString() {
    return this.response.toString() + "\nKeyCode 0x" + this.keyCode.toString(16);
  };

  return KeyStatus;
}();

exports.default = KeyStatus;

},{}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/build/messages/TerminalStatus.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

var _manticoreLog = require('manticore-log');

var _manticoreLog2 = _interopRequireDefault(_manticoreLog);

var _MiuraTags = require('../MiuraTags');

var _MiuraTags2 = _interopRequireDefault(_MiuraTags);

function _interopRequireDefault(obj) {
  return obj && obj.__esModule ? obj : { default: obj };
}

function _classCallCheck(instance, Constructor) {
  if (!(instance instanceof Constructor)) {
    throw new TypeError("Cannot call a class as a function");
  }
}

var Log = (0, _manticoreLog2.default)('device.miura.terminalStatus');

var TerminalStatus = function () {
  function TerminalStatus(apduResponse) {
    var _this = this;

    _classCallCheck(this, TerminalStatus);

    this.response = apduResponse;
    if (this.response && this.response.tlvs && this.response.tlvs.values) {
      this.response.tlvs.values.forEach(function (v) {
        if (v.tag === _MiuraTags2.default.MiuraStateChangeReason) {
          _this.changeType = TerminalStatus._getTerminalStatus(v.bytes[0]);
        } else if (v.tag === _MiuraTags2.default.MiuraStateChangeText) {
          _this.description = v.parse();
        } else if (v.tag === _MiuraTags2.default.MiuraDigitsInPinBuffer) {
          _this.pinDigits = v.parse();
        } else if (v.tag === _MiuraTags2.default.MiuraPinEntryStatus) {
          var outcome = v.bytes[0];
          _this._readOutcome(outcome);
        }
      });
    }
  }

  TerminalStatus.prototype.toString = function toString() {
    var str = [this.response.toString() + '\nChange Type: ' + this.changeType + ' (' + this.description + ')'];
    if ({}.hasOwnProperty.call(this, 'pinDigits')) {
      str.push('\nPIN digits: ');
      str.push(this.pinDigits);
    }
    if ({}.hasOwnProperty.call(this, 'pinComplete')) {
      str.push('\nPIN entry complete.');
      if ({}.hasOwnProperty.call(this, 'pinCorrect')) {
        str.push('Correct? ' + (this.pinCorrect ? 'yes' : 'no'));
        if (!this.pinCorrect) {
          str.push('\nPIN failure reason: ');
          str.push(this.pinFailureReason);
        }
      }
      if (this.lastPinAttempt) {
        str.push('\n*** LAST PIN ATTEMPT ***');
      }
    }
    return str.join('');
  };

  TerminalStatus._getTerminalStatus = function _getTerminalStatus(byte0) {
    switch (byte0) {
      case 1:
        return TerminalStatus.Constants.PoweringOn;
      case 2:
        return TerminalStatus.Constants.PinEntryStateChange;
      case 3:
        return TerminalStatus.Constants.ApplicationSelection;
      case 0xA:
        return TerminalStatus.Constants.PoweringOff;
      case 0xB:
        return TerminalStatus.Constants.Rebooting;
      case 0xC:
        return TerminalStatus.Constants.MpiRestarting;
      case 0xc0:
        return TerminalStatus.Constants.SeePhone;
      default:
        Log.error('Received unknown terminal status tag (0xC3) value ' + byte0);
        return 'Unknown';
    }
  };

  TerminalStatus.prototype._readOutcome = function _readOutcome(outcome) {
    if (outcome === 1) {
      this.lastPinAttempt = true;
    } else if (outcome === 2) {
      this.pinCorrect = true;
      this.pinComplete = true;
    } else if (outcome === 3) {
      this.pinCorrect = false;
      this.pinComplete = true;
      this.pinFailureReason = 'Incorrect PIN';
    } else if (outcome === 4) {
      this.pinCorrect = false;
      this.pinComplete = true;
      this.pinFailureReason = 'Entry Error';
    } else if (outcome === 5) {
      this.pinComplete = true;
    }
  };

  return TerminalStatus;
}();

exports.default = TerminalStatus;

TerminalStatus.Constants = {
  PoweringOn: 'PoweringOn',
  PinEntryStateChange: 'PinEntryStateChange',
  ApplicationSelection: 'ApplicationSelection',
  PoweringOff: 'PoweringOff',
  Rebooting: 'Rebooting',
  MpiRestarting: 'MpiRestarting',
  SeePhone: 'SeePhone'
};

},{"../MiuraTags":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/build/MiuraTags.js","manticore-log":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-log/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/build/strings/m010/en.js":[function(require,module,exports){
'use strict';

/* eslint-disable no-template-curly-in-string */

module.exports = {
  Connecting: 'Connecting to\nApplication',
  ConnectionFailed: 'Connection Failed',
  NotConnected: 'Open the app on your\nphone or tablet.',
  Ready: 'Ready to accept\npayments.',
  ReadyWithId: 'Ready to accept\npayments.\n${id}',
  NotReady: 'Another reader is\nin use.',
  NfcTimeout: '${amount}\nTransaction timed out',
  GeneralNfcFallback: 'Unable to read card.\nInsert or swipe\ncard now or try\n a different card',
  TransactionCancelled: '${amount}\nTransaction cancelled',
  TransactionCancelledRemoveCard: '${amount}\nTransaction cancelled\nPlease remove card',
  ReadyForInsertAndSwipePayment: '$image(insertswipe.bmp)\n${amount}',
  ReadyForInsertPayment: '$image(Insert.bmp)\n${amount}',
  ReadyForSwipePayment: '$image(Swipe.bmp)\n${amount}',
  ContactIssuer: 'Please contact your\ncard issuer.',
  ContactIssuerRemoveCard: 'Please contact your\ncard issuer.\n Please remove card.',
  InvoiceTotal: '${amount}${footer}',
  RechargeNow: 'Recharge now.',
  AmountTooLow: 'Card minimum is\n${amount}',
  AmountTooLowRemoveCard: 'Card minimum is\n${amount}\n Please remove card.',
  AmountTooHigh: 'Card maximum is\n${amount}',
  AmountTooHighRemoveCard: 'Card maximum is\n${amount}\n Please remove card.',
  SwUpdate: {
    Complete: 'Software Update\nSuccessful',
    EncryptInit: 'Initializing\nDevice',
    EncryptGet: 'Validating\nSecurity\nKeys',
    EncryptDone: 'Security\nKeys\nInstalled',
    Required: 'Software Update\nRequired',
    OS: 'Updating OS\n${progress}%',
    MPI: 'Updating MPI\n${progress}%',
    Config: 'Updating\nConfiguration\n${progress}%',
    Failed: 'Software update\nfailed.',
    Downloading: 'Downloading updates\n${count}/${total}'
  },
  Processing: {
    Tap: 'Processing...',
    Contact: '${amount}\nDo not remove card.\nProcessing...',
    ContactPinOk: 'Do not remove card.\nProcessing...\nPIN OK',
    PinOk: 'Processing...\nPIN OK',
    QuickChip: 'You can remove card.\nTransaction Still Processing...'
  },
  Paid: {
    RemoveCard: '${amount} paid.\nPlease remove card.',
    Successful: '${amount} paid.\nThank you!',
    Failed: '${amount} \nPayment failed'
  },
  Refund: {
    RemoveCard: '${amount} refunded.\nPlease remove card.',
    Successful: '${amount} refunded.\nThank you!',
    CardMismatch: 'Card mismatch!',
    CardMismatchRemoveCard: 'Card mismatch!\nPlease remove card.',
    Failed: '${amount}\n Refund failed'
  },
  Declined: {
    BlockedCardInserted: 'Declined.\nPlease remove card.',
    UnableToReadNfcCard: 'Unable to read card.\nInsert, swipe, or\npress OK on the app\nand tap another card.',
    NfcDecline: 'Declined.\nRetry with\ninsert or swipe?',
    IncorrectPin: 'Incorrect PIN\nPlease try again.'
  },
  Signature: {
    Insert: 'Signature Required.\nDo not remove card.',
    NonEmv: '${amount} paid\nSignature Required.',
    Tap: 'Signature Required.',
    QuickChip: 'Signature Required.'
  },
  CompletingPayment: 'Completing payment...',
  TransactionCancelling: 'Cancelling...',
  RequestTip: '${amount} due\n\n Add a tip?\nX = No      \u2713 = Yes',
  ConfirmTip: '${amount}\nincludes tip\n\nConfirm amount?\nX = No      \u2713 = Yes'
};
/* eslint-enable no-template-curly-in-string */

},{}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/index.js":[function(require,module,exports){
'use strict';

var InvoicingFakeServer = null;
try {
  InvoicingFakeServer = require('./lib/InvoicingFakeServer').default;
} catch (x) {
  // Do nothing, fake server not available.
}

module.exports = {
  setupFakeServer: function setupFakeServer(fakeServer) {
    if (!InvoicingFakeServer || !InvoicingFakeServer.getFakeResponses) {
      throw new Error('Fake server module is not available.');
    }
    fakeServer.addFakeResponses(InvoicingFakeServer.getFakeResponses());
  },


  BaseService: require('./lib/BaseClasses/BaseService').default,
  InvoicingService: require('./lib/InvoicingService').default,
  Currency: require('./lib/Currency').default,
  InvoicePayment: require('./lib/Payment').default,
  InvoicePaymentTerm: require('./lib/PaymentTerm').default,
  InvoiceRefund: require('./lib/Refund').default,
  InvoiceCCInfo: require('./lib/CCInfo').default,
  InvoiceAddress: require('./lib/Address').default,
  InvoiceBillingInfo: require('./lib/BillingInfo').default,
  InvoiceMerchantInfo: require('./lib/MerchantInfo').default,
  InvoiceShippingInfo: require('./lib/ShippingInfo').default,
  InvoiceItem: require('./lib/Item').default,
  InvoiceNotification: require('./lib/Notification').default,
  InvoicingRequester: require('./lib/Requester').default,
  InvoiceActions: require('./lib/InvoiceActions').default,
  InvoiceAttachment: require('./lib/Attachment').default,
  Invoice: require('./lib/Invoice').default,
  InvoiceListRequest: require('./lib/InvoiceListRequest').default,
  InvoiceListResponse: require('./lib/InvoiceListResponse').default,
  InvoiceSearchRequest: require('./lib/SearchRequest').default,
  AccountSummary: require('./lib/AccountSummary').default,
  AccountSummarySection: require('./lib/AccountSummarySection').default,
  Countries: require('./lib/Countries').default,
  Country: require('./lib/Country').default,
  InvoiceEnums: require('./lib/InvoiceEnums').default,
  InvoiceCustomAmount: require('./lib/CustomAmount').default,

  $$: require('./lib/InvoiceBigNumber').$$
};
},{"./lib/AccountSummary":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/AccountSummary.js","./lib/AccountSummarySection":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/AccountSummarySection.js","./lib/Address":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/Address.js","./lib/Attachment":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/Attachment.js","./lib/BaseClasses/BaseService":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/BaseClasses/BaseService.js","./lib/BillingInfo":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/BillingInfo.js","./lib/CCInfo":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/CCInfo.js","./lib/Countries":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/Countries.js","./lib/Country":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/Country.js","./lib/Currency":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/Currency.js","./lib/CustomAmount":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/CustomAmount.js","./lib/Invoice":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/Invoice.js","./lib/InvoiceActions":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/InvoiceActions.js","./lib/InvoiceBigNumber":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/InvoiceBigNumber.js","./lib/InvoiceEnums":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/InvoiceEnums.js","./lib/InvoiceListRequest":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/InvoiceListRequest.js","./lib/InvoiceListResponse":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/InvoiceListResponse.js","./lib/InvoicingFakeServer":false,"./lib/InvoicingService":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/InvoicingService.js","./lib/Item":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/Item.js","./lib/MerchantInfo":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/MerchantInfo.js","./lib/Notification":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/Notification.js","./lib/Payment":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/Payment.js","./lib/PaymentTerm":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/PaymentTerm.js","./lib/Refund":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/Refund.js","./lib/Requester":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/Requester.js","./lib/SearchRequest":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/SearchRequest.js","./lib/ShippingInfo":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/ShippingInfo.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/AccountSummary.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

var _InvoiceEnums = require('./InvoiceEnums');

var _InvoiceEnums2 = _interopRequireDefault(_InvoiceEnums);

var _InvoiceBigNumber = require('./InvoiceBigNumber');

var _AccountSummarySection = require('./AccountSummarySection');

var _AccountSummarySection2 = _interopRequireDefault(_AccountSummarySection);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

/**
 * Account summary for current merchant
 * @class
 * @property {decimal} outstandingAmount outstanding amount on account
 * @property {AccountSummarySection} pastDueSection section summary
 *  containing past due invoice information
 * @property {AccountSummarySection} awaitingPaymentSection section
 *  summary containing awaiting invoice information
 * @property {AccountSummarySection} draftSection section summary
 *  containing draft invoice information
 * @property {AccountSummarySection} paidSection section summary
 *  containing paid invoice information
 */

var AccountSummary = function () {
  function AccountSummary(nonOverdueJson, overdueJson) {
    _classCallCheck(this, AccountSummary);

    this.pastDueSection = this.sectionFromSummaries(overdueJson.summaries);

    // The 'nonOverdueJson' actually includes overdue invoices.
    this.awaitingPaymentSection = this.sectionForStatuses([_InvoiceEnums2.default.Status.SENT, _InvoiceEnums2.default.Status.PARTIALLY_PAID, _InvoiceEnums2.default.Status.UNPAID], nonOverdueJson);

    this.draftSection = this.sectionForStatuses([_InvoiceEnums2.default.Status.DRAFT], nonOverdueJson);

    this.paidSection = this.sectionForStatuses([_InvoiceEnums2.default.Status.MARKED_AS_PAID, _InvoiceEnums2.default.Status.PAID], nonOverdueJson);

    this.outstandingAmount = this.awaitingPaymentSection.totalAmount;
  }

  // Given an array of invoice statuses and a JSON response from the summary endpoint, returns
  // an AccountSummarySection whose values are the sum of all the summaries whose statuses
  // are in the status array


  AccountSummary.prototype.sectionForStatuses = function sectionForStatuses(statuses, json) {
    return this.sectionFromSummaries(this.summariesForStatuses(statuses, json));
  };

  // Given an array of invoice statuses and a JSON response from the summary endpoint, returns an
  // array of the summaries whose statuses are in the status array


  AccountSummary.prototype.summariesForStatuses = function summariesForStatuses(statuses, json) {
    var retVal = [];
    for (var _iterator = json.summaries, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
      var _ref;

      if (_isArray) {
        if (_i >= _iterator.length) break;
        _ref = _iterator[_i++];
      } else {
        _i = _iterator.next();
        if (_i.done) break;
        _ref = _i.value;
      }

      var summary = _ref;

      if (statuses.indexOf(_InvoiceEnums2.default.Status[summary.status]) >= 0) {
        retVal.push(summary);
      }
    }
    return retVal;
  };

  // Given an array of summaries, sums all their values into an AccountSummarySection


  AccountSummary.prototype.sectionFromSummaries = function sectionFromSummaries(summaries) {
    var count = 0;
    var totalAmount = (0, _InvoiceBigNumber.$$)('0');
    var paidAmount = (0, _InvoiceBigNumber.$$)('0');
    var refundedAmount = (0, _InvoiceBigNumber.$$)('0');
    for (var _iterator2 = summaries, _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) {
      var _ref2;

      if (_isArray2) {
        if (_i2 >= _iterator2.length) break;
        _ref2 = _iterator2[_i2++];
      } else {
        _i2 = _iterator2.next();
        if (_i2.done) break;
        _ref2 = _i2.value;
      }

      var summary = _ref2;

      count += summary.count;
      if (summary.amount_summary && summary.amount_summary.length) {
        // TODO: the amount_summary array contains multiple summaries
        // grouped by currency codes. Right now we just take the first.
        // Weird stuff will happen if we actually get multiple currencies.
        var amountSummary = summary.amount_summary[0];
        if (amountSummary.total_amount) {
          totalAmount = totalAmount.add((0, _InvoiceBigNumber.$$)(amountSummary.total_amount.value));
        }
        if (amountSummary.paid_amount) {
          if (amountSummary.paid_amount.other) {
            paidAmount = paidAmount.add((0, _InvoiceBigNumber.$$)(amountSummary.paid_amount.other.value));
          }
          if (amountSummary.paid_amount.paypal) {
            paidAmount = paidAmount.add((0, _InvoiceBigNumber.$$)(amountSummary.paid_amount.paypal.value));
          }
        }
        if (amountSummary.refunded_amount) {
          if (amountSummary.refunded_amount.other) {
            refundedAmount = refundedAmount.add((0, _InvoiceBigNumber.$$)(amountSummary.refunded_amount.other.value));
          }
          if (amountSummary.refunded_amount.paypal) {
            refundedAmount = refundedAmount.add((0, _InvoiceBigNumber.$$)(amountSummary.refunded_amount.paypal.value));
          }
        }
      }
    }
    return new _AccountSummarySection2.default(count, totalAmount, paidAmount, refundedAmount);
  };

  AccountSummary.prototype.subtractSection = function subtractSection(section1, section2) {
    return new _AccountSummarySection2.default(section1.totalCount - section2.totalCount, section1.totalAmount.minus(section2.totalAmount), section1.paidAmount.minus(section2.paidAmount), section1.refundedAmount.minus(section2.refundedAmount));
  };

  return AccountSummary;
}();

exports.default = AccountSummary;
},{"./AccountSummarySection":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/AccountSummarySection.js","./InvoiceBigNumber":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/InvoiceBigNumber.js","./InvoiceEnums":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/InvoiceEnums.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/AccountSummarySection.js":[function(require,module,exports){
"use strict";

exports.__esModule = true;

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

/**
 * Account summary for current merchant
 * @class
 * @property {decimal} totalCount total count of invoices for section
 * @property {decimal} totalAmount total amount for section
 * @property {decimal} paidAmount paid amount for section
 * @property {decimal} refundedAmount refunded amount for section
 */

var AccountSummarySection = function AccountSummarySection(totalCount, totalAmount, paidAmount, refundedAmount) {
  _classCallCheck(this, AccountSummarySection);

  this.totalCount = totalCount;
  this.totalAmount = totalAmount;
  this.paidAmount = paidAmount;
  this.refundedAmount = refundedAmount;
};

exports.default = AccountSummarySection;
},{}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/Address.js":[function(require,module,exports){
"use strict";

exports.__esModule = true;

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

/**
 * Container for addresses used on various invoice entities
 * @class
 *
 * @property {string} line1 First line of the address @required
 * @property {string} line2 Second line of the address
 * @property {string} city City portion of the address
 * @property {string} state State, if applicable
 * @property {string} postalCode Postal Code
 * @property {string} country ISO two letter country code @required
 * @property {string} phone Phone number in E.123 format.
 * @property {bool} isPrimary
 * @property {string} addressee
 */

var InvoiceAddress = function () {
  function InvoiceAddress() {
    _classCallCheck(this, InvoiceAddress);
  }

  InvoiceAddress.prototype.readFromJson = function readFromJson(json) {
    if (json) {
      this.line1 = json.line1;
      if (!this.line1 && json.addressLine1) {
        this.line1 = json.addressLine1;
      }
      this.line2 = json.line2;
      if (!this.line2 && json.addressLine2) {
        this.line2 = json.addressLine2;
      }
      this.city = json.city;
      this.state = json.state;
      this.postalCode = json.postal_code;
      this.country = json.country_code;
      this.phone = json.phone;
      this.addressee = json.addressee_name;
      this.isPrimary = json.isPrimary;
    }
  };

  InvoiceAddress.prototype.toJSON = function toJSON() {
    var r = void 0;
    if (this.hasAnyValue()) {
      r = {};
      r.line1 = this.line1;
      r.line2 = this.line2;
      r.city = this.city;
      r.state = this.state;
      r.postal_code = this.postalCode;
      r.country_code = this.country;
      r.addressee = this.addressee;
      r.isPrimary = this.isPrimary;
      r.phone = this.phone;
    }
    return r;
  };

  /**
   * Check to see if this object has any value
   * @returns {bool}
   */


  InvoiceAddress.prototype.hasAnyValue = function hasAnyValue() {
    if (this.line1 || this.line2 || this.city || this.state || this.postalCode || this.country || this.addressee || this.phone) {
      return true;
    }
    return false;
  };

  return InvoiceAddress;
}();

exports.default = InvoiceAddress;
},{}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/Attachment.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

/**
 * Invoice attachment
 * @class
 * @property {string} name name of the attachment
 * @property {string} url url of the attachment
 */

var InvoiceAttachment = function () {
  function InvoiceAttachment() {
    _classCallCheck(this, InvoiceAttachment);
  }

  InvoiceAttachment.readFromJson = function readFromJson(json) {
    var a = new InvoiceAttachment();

    a.name = json.name;
    a.url = json.url;

    return a;
  };

  /**
   * workaround for known API issue, returns usable version of the URL
   * @returns {string} the usable url
   */


  InvoiceAttachment.prototype.usableURL = function usableURL() {
    var re = new RegExp('sig.*&');
    var section = this.url.match(re)[0];
    var newSection = section.split('/').join('.').split('+').join('-').replace('=&', '&');
    var newURL = this.url.replace(section, newSection);

    return newURL;
  };

  return InvoiceAttachment;
}();

exports.default = InvoiceAttachment;
},{}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/BaseClasses/BaseService.js":[function(require,module,exports){
"use strict";

exports.__esModule = true;

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

/**
 * @class
 */

var BaseService = function BaseService() {
  _classCallCheck(this, BaseService);
};

exports.default = BaseService;
},{}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/BillingInfo.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

var _Address = require('./Address');

var _Address2 = _interopRequireDefault(_Address);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

/**
 * Container for information about the payer or intended payer on an invoice
 * @class
 * @property {string} email The email address of the payer @required @length(1,260) @format(email)
 * @property {string} firstName The first name of the payer @length(,30)
 * @property {string} lastName The last name of the payer @length(,30)
 * @property {string} businessName The business name of the payer
 * @property {InvoiceAddress} address The address of the payer @length(,100)
 * @property {string} language Language of the email sent to the payer. Will
 *  only be used if payer doesn't have a PayPal account.
 * @property {string} additionalInfo Option to display additional information
 *  such as business hours. 40 characters max.
 * @property {string} notificationChannel Preferred notification channel of the
 *  payer. Email by default.
 * @property {string} countryCode Country code (in E.164 format). Assume length is n.
 * @property {string} nationalNumber In-country phone number (in E.164 format).
 *  Maximum (15 - n) digits
 */

var InvoiceBillingInfo = function () {
  function InvoiceBillingInfo() {
    _classCallCheck(this, InvoiceBillingInfo);

    this.address = new _Address2.default();
  }

  InvoiceBillingInfo.prototype.readFromJson = function readFromJson(json) {
    if (json) {
      this.address.readFromJson(json.address);
      this.firstName = json.first_name;
      this.lastName = json.last_name;
      this.businessName = json.business_name;
      this.email = json.email;
      this.language = json.language;
      this.additionalInfo = json.additional_info;
      this.notificationChannel = json.notification_channel;
      if (json.phone) {
        this.countryCode = json.phone.country_code;
        this.nationalNumber = json.phone.national_number;
      }
    }
  };

  InvoiceBillingInfo.prototype.toJSON = function toJSON() {
    var r = {};
    // If the address is empty, don't include it in the JSON.
    if (Object.keys(this.address).length) {
      r.address = this.address;
    }
    r.first_name = this.firstName;
    r.last_name = this.lastName;
    r.email = this.email;
    r.business_name = this.businessName;
    r.language = this.language;
    r.additional_info = this.additionalInfo;
    r.notification_channel = this.notificationChannel;

    if (this.nationalNumber) {
      r.phone = {};
      r.phone.country_code = this.countryCode;
      r.phone.national_number = this.nationalNumber;
    }

    return r;
  };

  /**
   * Check to see if this object has any value
   * @returns {bool}
   */


  InvoiceBillingInfo.prototype.hasAnyValue = function hasAnyValue() {
    if (this.email || this.firstName || this.lastName || this.businessName || this.address.hasAnyValue() || this.language || this.additionalInfo || this.notificationChannel || this.countryCode || this.nationalNumber) {
      return true;
    }
    return false;
  };

  return InvoiceBillingInfo;
}();

exports.default = InvoiceBillingInfo;
},{"./Address":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/Address.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/CCInfo.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

var _Address = require('./Address');

var _Address2 = _interopRequireDefault(_Address);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

/**
 * Container for information about a person CC'ed on an invoice
 * @class
 * @property {string} email The email address of the
 *  merchant @required @length(1,260) @format(email)
 * @property {string} firstName The first name of the merchant @length(,30)
 * @property {string} lastName The last name of the merchant @length(,30)
 * @property {InvoiceAddress} address The address of the merchant
 * @property {string} businessName The business name of the merchant
 * @property {string} phone The phone number of the merchant
 * @property {string} fax The fax number of the merchant
 * @property {string} website The URL of the merchant website @format{url}
 * @property {string} additionalInfo option to display additional info such as business hours
 **/

var InvoiceCCInfo = function () {
  function InvoiceCCInfo() {
    _classCallCheck(this, InvoiceCCInfo);

    this.address = new _Address2.default();
  }

  InvoiceCCInfo.fromJson = function fromJson(json) {
    var ccInfo = new InvoiceCCInfo();

    if (json) {
      ccInfo.address.readFromJson(json.address);
      ccInfo.firstName = json.first_name;
      ccInfo.lastName = json.last_name;
      ccInfo.businessName = json.business_name;
      ccInfo.email = json.email;
      ccInfo.phone = json.phone;
      ccInfo.fax = json.fax;
      ccInfo.website = json.website;
      ccInfo.additionalInfo = json.additional_info;
    }

    return ccInfo;
  };

  InvoiceCCInfo.prototype.toJSON = function toJSON() {
    var r = {};
    r.email = this.email;
    r.first_name = this.firstName;
    r.last_name = this.lastName;
    r.business_name = this.businessName;
    r.phone = this.phone;
    r.fax = this.fax;
    r.website = this.website;
    r.additional_info = this.additionalInfo;
    r.address = this.address;

    return r;
  };

  return InvoiceCCInfo;
}();

exports.default = InvoiceCCInfo;
},{"./Address":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/Address.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/Countries.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

var _Country = require('./Country');

var _Country2 = _interopRequireDefault(_Country);

var _CountryMap = require('./CountryMap');

var _CountryMap2 = _interopRequireDefault(_CountryMap);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

/**
 * @class
 *
 *
 */

var Countries = function () {
  function Countries() {
    _classCallCheck(this, Countries);
  }

  /**
   * @returns {[Country]}
   */

  Countries.countries = function countries() {
    if (!Countries._countries) {
      Countries._countries = [];
      for (var _iterator = Object.keys(_CountryMap2.default), _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
        var _ref;

        if (_isArray) {
          if (_i >= _iterator.length) break;
          _ref = _iterator[_i++];
        } else {
          _i = _iterator.next();
          if (_i.done) break;
          _ref = _i.value;
        }

        var countryCode = _ref;

        Countries._countries.push(new _Country2.default(countryCode, _CountryMap2.default[countryCode]));
      }
    }

    return Countries._countries;
  };

  /**
   * Given a country code, returns the full name of the country.
   * If there's no match, returns undefined.
   * @param {string} countryCode
   * @returns {string}
   */


  Countries.countryForCountryCode = function countryForCountryCode(countryCode) {
    if (!countryCode) {
      return undefined;
    }
    var upperCountryCode = countryCode.toUpperCase();

    for (var _iterator2 = this.countries(), _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) {
      var _ref2;

      if (_isArray2) {
        if (_i2 >= _iterator2.length) break;
        _ref2 = _iterator2[_i2++];
      } else {
        _i2 = _iterator2.next();
        if (_i2.done) break;
        _ref2 = _i2.value;
      }

      var country = _ref2;

      if (country.code === upperCountryCode) {
        if (country.name) {
          return country.name;
        }
      }
    }
    return undefined;
  };

  return Countries;
}();

exports.default = Countries;
},{"./Country":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/Country.js","./CountryMap":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/CountryMap.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/Country.js":[function(require,module,exports){
"use strict";

exports.__esModule = true;

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

/**
 * @class
 *
 * @property {string} code The code for a country @readonly
 * @property {string} name The name of a country @readonly
 */

var Country =
/**
 * Create a new country.
 * @constructor
 * @param {string} countryCode
 * @param {string} countryName
 */
function Country(countryCode, countryName) {
  _classCallCheck(this, Country);

  this.code = countryCode;
  this.name = countryName;
};

exports.default = Country;
},{}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/CountryMap.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;
exports.default = {
  AL: 'Albania',
  DZ: 'Algeria',
  AD: 'Andorra',
  AO: 'Angola',
  AI: 'Anguilla',
  AG: 'Antigua & Barbuda',
  AR: 'Argentina',
  AM: 'Armenia',
  AW: 'Aruba',
  AU: 'Australia',
  AT: 'Austria',
  AZ: 'Azerbaijan',
  BS: 'Bahamas',
  BH: 'Bahrain',
  BB: 'Barbados',
  BY: 'Belarus',
  BE: 'Belgium',
  BZ: 'Belize',
  BJ: 'Benin',
  BM: 'Bermuda',
  BT: 'Bhutan',
  BO: 'Bolivia',
  BA: 'Bosnia & Herzegovina',
  BW: 'Botswana',
  BR: 'Brazil',
  VG: 'British Virgin Islands',
  BN: 'Brunei',
  BG: 'Bulgaria',
  BF: 'Burkina Faso',
  BI: 'Burundi',
  KH: 'Cambodia',
  CM: 'Cameroon',
  CA: 'Canada',
  CV: 'Cape Verde',
  KY: 'Cayman Islands',
  TD: 'Chad',
  CL: 'Chile',
  CN: 'China',
  C2: 'China World Wide',
  CO: 'Colombia',
  KM: 'Comoros',
  CG: 'Congo - Brazzaville',
  CD: 'Congo - Kinshasa',
  CK: 'Cook Islands',
  CR: 'Costa Rica',
  CI: 'Côte d’Ivoire',
  HR: 'Croatia',
  CY: 'Cyprus',
  CZ: 'Czech Republic',
  DK: 'Denmark',
  DJ: 'Djibouti',
  DM: 'Dominica',
  DO: 'Dominican Republic',
  EC: 'Ecuador',
  EG: 'Egypt',
  SV: 'El Salvador',
  ER: 'Eritrea',
  EE: 'Estonia',
  ET: 'Ethiopia',
  FK: 'Falkland Islands',
  FO: 'Faroe Islands',
  FJ: 'Fiji',
  FI: 'Finland',
  FR: 'France',
  GF: 'French Guiana',
  PF: 'French Polynesia',
  GA: 'Gabon',
  GM: 'Gambia',
  GE: 'Georgia',
  DE: 'Germany',
  GI: 'Gibraltar',
  GR: 'Greece',
  GL: 'Greenland',
  GD: 'Grenada',
  GP: 'Guadeloupe',
  GT: 'Guatemala',
  GN: 'Guinea',
  GW: 'Guinea - Bissau',
  GY: 'Guyana',
  HN: 'Honduras',
  HK: 'Hong Kong SAR China',
  HU: 'Hungary',
  IS: 'Iceland',
  IN: 'India',
  ID: 'Indonesia',
  IE: 'Ireland',
  IL: 'Israel',
  IT: 'Italy',
  JM: 'Jamaica',
  JP: 'Japan',
  JO: 'Jordan',
  KZ: 'Kazakhstan',
  KE: 'Kenya',
  KI: 'Kiribati',
  KW: 'Kuwait',
  KG: 'Kyrgyzstan',
  LA: 'Laos',
  LV: 'Latvia',
  LS: 'Lesotho',
  LI: 'Liechtenstein',
  LT: 'Lithuania',
  LU: 'Luxembourg',
  MK: 'Macedonia',
  MG: 'Madagascar',
  MW: 'Malawi',
  MY: 'Malaysia',
  MV: 'Maldives',
  ML: 'Mali',
  MT: 'Malta',
  MH: 'Marshall Islands',
  MQ: 'Martinique',
  MR: 'Mauritania',
  MU: 'Mauritius',
  YT: 'Mayotte',
  MX: 'Mexico',
  FM: 'Micronesia',
  MD: 'Moldova',
  MC: 'Monaco',
  MN: 'Mongolia',
  ME: 'Montenegro',
  MS: 'Montserrat',
  MA: 'Morocco',
  MZ: 'Mozambique',
  NA: 'Namibia',
  NR: 'Nauru',
  NP: 'Nepal',
  NL: 'Netherlands',
  AN: 'Netherlands Antilles',
  NC: 'New Caledonia',
  NZ: 'New Zealand',
  NI: 'Nicaragua',
  NE: 'Niger',
  NG: 'Nigeria',
  NU: 'Niue',
  NF: 'Norfolk Island',
  NO: 'Norway',
  OM: 'Oman',
  PW: 'Palau',
  PA: 'Panama',
  PG: 'Papua New Guinea',
  PY: 'Paraguay',
  PE: 'Peru',
  PH: 'Philippines',
  PN: 'Pitcairn Islands',
  PL: 'Poland',
  PT: 'Portugal',
  QA: 'Qatar',
  RE: 'Réunion',
  RO: 'Romania',
  RU: 'Russia',
  RW: 'Rwanda',
  WS: 'Samoa',
  SM: 'San Marino',
  ST: 'São Tomé & Príncipe',
  SA: 'Saudi Arabia',
  SN: 'Senegal',
  RS: 'Serbia',
  SC: 'Seychelles',
  SL: 'Sierra Leone',
  SG: 'Singapore',
  SK: 'Slovakia',
  SI: 'Slovenia',
  SB: 'Solomon Islands',
  SO: 'Somalia',
  ZA: 'South Africa',
  KR: 'South Korea',
  ES: 'Spain',
  LK: 'Sri Lanka',
  SH: 'St. Helena',
  KN: 'St. Kitts & Nevis',
  LC: 'St. Lucia',
  PM: 'St. Pierre & Miquelon',
  VC: 'St. Vincent & Grenadines',
  SR: 'Suriname',
  SJ: 'Svalbard & Jan Mayen',
  SZ: 'Swaziland',
  SE: 'Sweden',
  CH: 'Switzerland',
  TW: 'Taiwan',
  TJ: 'Tajikistan',
  TZ: 'Tanzania',
  TH: 'Thailand',
  TG: 'Togo',
  TO: 'Tonga',
  TT: 'Trinidad & Tobago',
  TN: 'Tunisia',
  TR: 'Turkey',
  TM: 'Turkmenistan',
  TC: 'Turks & Caicos Islands',
  TV: 'Tuvalu',
  UG: 'Uganda',
  UA: 'Ukraine',
  AE: 'United Arab Emirates',
  GB: 'United Kingdom',
  US: 'United States',
  UY: 'Uruguay',
  VU: 'Vanuatu',
  VA: 'Vatican City',
  VE: 'Venezuela',
  VN: 'Vietnam',
  WF: 'Wallis & Futuna',
  YE: 'Yemen',
  ZM: 'Zambia',
  ZW: 'Zimbabwe'
};
},{}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/Currency.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

var _InvoiceBigNumber = require('./InvoiceBigNumber');

var _InvoiceBigNumber2 = _interopRequireDefault(_InvoiceBigNumber);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

var currencies = void 0;

var Currency = function () {
  function Currency(props) {
    _classCallCheck(this, Currency);

    this.decimals = props.decimals || 2;
    this.symbol = props.symbol || '$';
    this.roundMode = props.roundMode || _InvoiceBigNumber2.default.ROUND_HALF_UP;
    this.iso4217 = props.iso4217;
  }

  Currency.getCurrency = function getCurrency(currencyCode) {
    return currencies[currencyCode];
  };

  Currency.setCurrency = function setCurrency(currencyCode, currency) {
    currencies[currencyCode] = currency;
  };

  Currency.prototype.round = function round(amount) {
    return (0, _InvoiceBigNumber.$$)(amount).round(this.decimals, this.roundMode);
  };

  Currency.prototype.toCents = function toCents(amount) {
    return (0, _InvoiceBigNumber.$$)(10).pow(this.decimals).times(amount);
  };

  Currency.prototype.format = function format(amount) {
    return this.symbol + (0, _InvoiceBigNumber.$$)(amount).toFormat(this.decimals, this.roundMode);
  };

  Currency.round = function round(currency, amount) {
    return Currency.getCurrency(currency).round(amount);
  };

  Currency.toCents = function toCents(currency, amount) {
    return Currency.getCurrency(currency).toCents(amount);
  };

  Currency.format = function format(currency, amount) {
    return Currency.getCurrency(currency).format(amount);
  };

  return Currency;
}();

exports.default = Currency;


currencies = {
  AUD: new Currency({
    iso4217: 36
  }),
  GBP: new Currency({
    symbol: '£',
    iso4217: 826
  }),
  USD: new Currency({
    iso4217: 840
  }),
  HKD: new Currency({
    iso4217: 344,
    decimals: 1
  }),
  EUR: new Currency({
    symbol: '€',
    iso4217: 978
  }),
  CAD: new Currency({
    iso4217: 124
  })
};
},{"./InvoiceBigNumber":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/InvoiceBigNumber.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/CustomAmount.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

var _InvoiceBigNumber = require('./InvoiceBigNumber');

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

/**
 * Container for custom amounts on invoices
 * @class
 *
 * @property {string} label Custom amount label
 * @property {decimal} amount this is an amount object on the server
 *  which has a string for currency, and value
 */

var InvoiceCustomAmount = function () {
  function InvoiceCustomAmount() {
    _classCallCheck(this, InvoiceCustomAmount);
  }

  InvoiceCustomAmount.fromJSON = function fromJSON(json) {
    var customAmount = new InvoiceCustomAmount();
    if (json.label) {
      customAmount.label = json.label;
    }

    if (json.amount) {
      customAmount.amount = (0, _InvoiceBigNumber.$$)(json.amount.value);
    }

    return customAmount;
  };

  InvoiceCustomAmount.prototype.toJSON = function toJSON(currencyCode) {
    var r = {};
    if (this.amount) {
      r.amount = {
        currency: currencyCode,
        value: this.amount
      };
    }
    r.label = this.label;

    return r;
  };

  return InvoiceCustomAmount;
}();

exports.default = InvoiceCustomAmount;
},{"./InvoiceBigNumber":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/InvoiceBigNumber.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/Invoice.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

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; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

var _events = require('events');

var _deepEqual = require('deep-equal');

var _deepEqual2 = _interopRequireDefault(_deepEqual);

var _manticoreLog = require('manticore-log');

var _manticoreLog2 = _interopRequireDefault(_manticoreLog);

var _InvoiceBigNumber = require('./InvoiceBigNumber');

var _InvoiceBigNumber2 = _interopRequireDefault(_InvoiceBigNumber);

var _Currency = require('./Currency');

var _Currency2 = _interopRequireDefault(_Currency);

var _CustomAmount = require('./CustomAmount');

var _CustomAmount2 = _interopRequireDefault(_CustomAmount);

var _Item = require('./Item');

var _Item2 = _interopRequireDefault(_Item);

var _MerchantInfo = require('./MerchantInfo');

var _MerchantInfo2 = _interopRequireDefault(_MerchantInfo);

var _BillingInfo = require('./BillingInfo');

var _BillingInfo2 = _interopRequireDefault(_BillingInfo);

var _assert = require('assert');

var _assert2 = _interopRequireDefault(_assert);

var _manticoreUtil = require('manticore-util');

var _InvoicingUtil = require('./InvoicingUtil');

var _InvoicingUtil2 = _interopRequireDefault(_InvoicingUtil);

var _Requester = require('./Requester');

var _ShippingInfo = require('./ShippingInfo');

var _ShippingInfo2 = _interopRequireDefault(_ShippingInfo);

var _totalCalculator = require('./totalCalculator');

var _totalCalculator2 = _interopRequireDefault(_totalCalculator);

var _CCInfo = require('./CCInfo');

var _CCInfo2 = _interopRequireDefault(_CCInfo);

var _Payment = require('./Payment');

var _Payment2 = _interopRequireDefault(_Payment);

var _PaymentTerm = require('./PaymentTerm');

var _PaymentTerm2 = _interopRequireDefault(_PaymentTerm);

var _Refund = require('./Refund');

var _Refund2 = _interopRequireDefault(_Refund);

var _Attachment = require('./Attachment');

var _Attachment2 = _interopRequireDefault(_Attachment);

var _InvoiceEnums = require('./InvoiceEnums');

var _InvoiceEnums2 = _interopRequireDefault(_InvoiceEnums);

var _InvoiceMetaData = require('./InvoiceMetaData');

var _InvoiceMetaData2 = _interopRequireDefault(_InvoiceMetaData);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (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 } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var Log = (0, _manticoreLog2.default)('invoicing');

// TODO: talk about the different dates correctly

function statusFromServer(s) {
  if (!s) {
    return _InvoiceEnums2.default.Status.NEW;
  } else if (_InvoiceEnums2.default.Status[s]) {
    return _InvoiceEnums2.default.Status[s];
  }
  Log.warn('Received unknown server invoice status ' + s);
  return _InvoiceEnums2.default.Status.DRAFT;
}

/**
 * Invoice is the fundamental transaction record for retail payments.
 * It contains header data, such as buyer and seller information and
 * {@link InvoiceItem line items} with unit prices, quantities, etc.
 * @class
 *
 * @property {string} currency The currency for all amounts on this invoice @readonly
 * @property {Date} invoiceDate The date the invoice was 'enabled'. Can be set by user.
 * @property {string} payPalId The id assigned by PayPal for this invoice
 *  (if it has been saved to PayPal at some point) @readonly
 * @property {string} number The unique order number that can be assigned by you
 *  (you must ensure uniqueness) or automatically generated by PayPal
 * @property {Invoice.Status} status The current status of the invoice @readonly
 * @property {string} reference Reference data such as PO Number to be added to invoice.
 *  60 characters max.
 * @property {InvoiceMerchantInfo} merchantInfo Merchant email address and contact
 *  information (email defaults to a PayPal no-reply address)
 * @property {InvoiceBillingInfo} billingInfo Information about the payer or
 *  intended payer of the invoice
 * @property {InvoiceShippingInfo} shippingInfo The shipping address for this
 *  invoice (usually blank in retail use cases)
 * @property {bool} taxInclusive Prices for items on this invoice are INCLUSIVE
 *  of tax - defaults to false.
 * @property {bool} taxCalculatedAfterDiscount Taxes for line items are calculated
 *  after any discounts - defaults to false
 * @property {[InvoiceItem]} items The list of items on this invoice
 * @property {int} itemCount Get the number of items on this invoice @readonly
 * @property {InvoicePaymentTerm} paymentTerms Describes when payment is expected on the
 *  invoice (defaults to DueOnReceipt)
 * @property {decimal} gratuityAmount The amount of gratuity to be applied to the invoice, if any
 * @property {decimal} discountAmount Discount amount applied to the invoice
 * @property {decimal} minimumAmountDue Base object for all financial value related fields
 *  (balance, payment due, etc.)
 * @property {decimal} discountPercentage Discount percentage applied to the invoice
 * @property {string} note A note to the customer
 * @property {decimal} shippingAmount The shipping cost to be applied to the invoice, if any
 * @property {decimal} shippingTaxRate The shipping tax rate, as percent of the
 *  total shipping amount.
 * @property {string} shippingTaxName The name of the shipping tax.
 * @property {string} termsAndConditions General terms of the invoice. 4000 characters max.
 * @property {string} merchantMemo Bookkeeping memo that is private to the merchant.
 *  150 characters max.
 * @property {bool} isDirtyFromServer Has this invoice changed since the last time it was
 *  saved to the server? @readonly
 * @property {bool} hasDetails If false, this invoice doesn't know what items are in its item list.
 *  This can happen when only "summary" information has been fetched from the server
 *  (typically as the result of a search). You can get the total, but items and subtotals
 *  totals aren't available until you call getDetails. @readonly
 * @property {decimal} total The total amount due on the invoice @readonly
 * @property {decimal} subTotal The subtotal of the items on the invoice @readonly
 * @property {decimal} itemTax The total tax on the items (as opposed to the shipping tax,
 *  for example) @readonly
 * @property {decimal} totalDiscount The total amount of discounts applied to the invoice items
 *  and overall invoice @readonly
 * @property {object} taxBreakdown An associative array of tax rate names to the total tax on the
 *  invoice from that rate @readonly
 * @property {bool} allowPartialPayment Indicates if a partial payment is allowed over the invoice.
 *  defaults to false
 * @property {[InvoiceCCInfo]} CCInfo an array of CCInfo Email addresses which should be marked as
 *  Carbon Copy (CC) while the invoice is sent via email. Only email address under participant is
 *  currently supported.
 * @property {[InvoicePayment]} payments an array of payment objects @readonly
 * @property {[InvoiceRefund]} refunds an array of refund objects @readonly
 * @property {decimal} paidAmount payment/refund break up
 * @property {bool} paidAmountIsPayPal indicates whether or not the amount paid was done
 *  so via PayPal
 * @property {decimal} refundedAmount payment/refund break up
 * @property {bool} refundedAmountIsPayPal indicates whether or not the amount refunded
 *  was done so via PayPal
 * @property {string} uri URI of the invoice resource.
 * @property {string} logoURL Full URL of an external image to use as the logo.
 *  4000 characters max.
 * @property {string} additionalData Any miscellaneous invoice data. 4000 characters max.
 * @property {InvoiceCustomAmount} custom Custom amount applied on an invoice. If a label
 *  is included then the amount cannot be empty.
 * @property {InvoiceMetaData} metadata Audit information of the resource. @readonly
 * @property {bool} wasDeleted If true, this invoice was deleted from the server.
 * @property {[InvoiceAttachment]} attachments List of files attached to the invoice.
 * @property {string} templateID Unique identifier id of the template.
 *
 */

var Invoice = function (_EventEmitter) {
  _inherits(Invoice, _EventEmitter);

  // TODO should this constructor also take an object
  // and assume it's from the server? Doesn't really
  // need to be public so that argues not...
  /**
   * Create a new blank invoice.
   * @constructor
   * @param {string} currencyCode currency code identifying the currency for amounts on this invoice
   */

  function Invoice(currencyCode) {
    _classCallCheck(this, Invoice);

    var _this = _possibleConstructorReturn(this, _EventEmitter.call(this));

    _this.hasDetails = true;
    var useCurrencyCode = currencyCode;
    if (!currencyCode) {
      if (!Invoice.DefaultCurrency) {
        throw new Error(
        /* eslint max-len: 0 */
        'Creating an invoice without a specified currency requires Invoice.DefaultCurrency to be set.');
      }
      useCurrencyCode = Invoice.DefaultCurrency;
    }
    if (!_Currency2.default.getCurrency(useCurrencyCode)) {
      throw new Error('Unsupported currency: ' + useCurrencyCode);
    }
    _this.currency = useCurrencyCode;
    _this.merchantInfo = new _MerchantInfo2.default();
    _this.billingInfo = new _BillingInfo2.default();
    _this.shippingInfo = new _ShippingInfo2.default();
    _this.taxInclusive = false;
    _this.taxCalculatedAfterDiscount = false;
    _this.items = [];
    _this.allowPartialPayment = false;
    _this.CCInfo = [];
    _this.paymentTerms = new _PaymentTerm2.default();
    _this.status = _InvoiceEnums2.default.Status.NEW;

    if (Invoice.DefaultMerchant) {
      _this.merchantInfo.email = Invoice.DefaultMerchant.emailAddress;
      _this.merchantInfo.businessName = Invoice.DefaultMerchant.businessName;
      _this.merchantInfo.address = Invoice.DefaultMerchant.address;
      // TODO copy over more stuff.
    }
    return _this;
  }

  /**
   * Create a new invoice based on an existing invoice as a template.
   * @param {Invoice} invoice which is going to be copied
   * @returns {Invoice} the copy of the invoice
   */


  Invoice.withInvoice = function withInvoice(invoice) {
    (0, _assert2.default)(invoice.hasDetails, 'Can\'t use an invoice as a template if the details aren\'t loaded.');

    var i = new Invoice(invoice.currency);

    i.readJSON((0, _manticoreUtil.deepToJSON)(invoice), true);

    i.status = _InvoiceEnums2.default.Status.NEW;
    i.reference = undefined;
    i.number = undefined;
    i.payPalId = undefined;
    i.metadata = undefined;
    i.paymentTerms = new _PaymentTerm2.default();

    return i;
  };

  /**
   * Create a true copy of an invoice.
   * @returns {Invoice} the copy of the invoice
   */


  Invoice.prototype.copy = function copy() {
    var i = new Invoice(this.currency);
    i.readJSON((0, _manticoreUtil.deepToJSON)(this.toFullJSON()), true);
    i.wasDeleted = this.wasDeleted;
    return i;
  };

  Invoice.prototype.setCleanFromServer = function setCleanFromServer() {
    this._lastKnownServerValue = (0, _manticoreUtil.deepToJSON)(this);
  };

  // ********************************* ITEM LIST **********************************

  /**
   * Adds the specified item to the invoice. If there is an existing matching item
   * on the invoice, we will increment the quantity by the quantity argument.
   * You may pass a negative quantity value to decrement the quantity of an existing item.
   * @param {string} name The name of the item
   * @param {decimal} quantity The quantity of this item - up to three decimals
   * @param {decimal} unitPrice The price of 1 unit of this item
   * @param {string} itemId A unique identifier for this item - not currently
   *  saved to the server but used for local uniqueness such that one line item
   *  per itemId.detailId pair will be stored on an invoice
   * @param {string} detailId A secondary unique identifier (e.g. for item
   *  options or sizes, or to create multiple items on the same invoice
   *  with a single detailId)
   * @returns {InvoiceItem} the item actually stored on the invoice. If you want
   *  to set additional data on the item, you can use this item.
   */


  Invoice.prototype.addItem = function addItem(name, quantity, unitPrice, itemId, detailId) {
    var existing = this.findItem(itemId, detailId);
    if (existing) {
      existing.quantity = existing.quantity.plus(quantity);
      this._totalMayHaveChanged('itemUpdated');
      return existing;
    }
    var newItem = new _Item2.default(name, quantity, unitPrice, itemId, detailId || null);
    this.setupItemListeners(newItem);
    this.items.push(newItem);
    this._totalMayHaveChanged('itemAdded');
    return newItem;
  };

  Invoice.prototype.setupItemListeners = function setupItemListeners(item) {
    var _this2 = this;

    item.on('amountChanged', function () {
      return _this2._totalMayHaveChanged('itemAmountChanged');
    });
    item.on('taxRateChanged', function () {
      return _this2._totalMayHaveChanged('itemTaxRateChanged');
    });
    item.on('discountAmountChanged', function () {
      return _this2._totalMayHaveChanged('itemDiscountAmountChanged');
    });
    item.on('discountPercentageChanged', function () {
      return _this2._totalMayHaveChanged('itemDiscountPercentageChanged');
    });
  };

  /**
   * Remove all items on the invoice
   * @method
   */


  Invoice.prototype.removeAllItems = function removeAllItems() {
    this.items = [];
    this._totalMayHaveChanged('allItemsRemoved');
  };

  /**
   * Remove an item by instance
   * @param {InvoiceItem} item Instance of item to be removed
   * @returns {bool} true if the item was removed from the list
   */


  Invoice.prototype.removeItem = function removeItem(item) {
    if (!item) {
      return false;
    }

    var itemIndex = this.items.indexOf(item);
    if (itemIndex < 0) {
      return false;
    }

    this.items.splice(itemIndex, 1);
    this._totalMayHaveChanged('itemRemoved');
    return true;
  };

  /**
   * Find the InvoiceItem with the specified id and/or detailId
   * @param {string} itemId
   * @param {string} [detailId]
   * @returns {InvoiceItem} The existing item on the invoice, if any
   */


  Invoice.prototype.findItem = function findItem(itemId, detailId) {
    if (!itemId) {
      return null;
    }
    var _detailId = detailId || null;
    var _itemId = itemId;

    if (typeof itemId !== 'string') {
      _detailId = itemId.detailId;
      _itemId = itemId.itemId;
    }
    for (var _iterator = this.items, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
      var _ref;

      if (_isArray) {
        if (_i >= _iterator.length) break;
        _ref = _iterator[_i++];
      } else {
        _i = _iterator.next();
        if (_i.done) break;
        _ref = _i.value;
      }

      var candidate = _ref;

      if (candidate.itemId === _itemId && candidate.detailId === _detailId) {
        return candidate;
      }
    }
    return null;
  };

  /**
   * Get an item by 0-based index
   * @param {int} itemIndex 0-based index of item to retrieve.
   * @returns {InvoiceItem}
   */


  Invoice.prototype.getItem = function getItem(itemIndex) {
    return this.items[itemIndex];
  };

  // ********************************* TOTAL PROPERTIES **********************************

  Invoice.prototype.ensureTotals = function ensureTotals() {
    if (!this._cleanTotals) {
      (0, _totalCalculator2.default)(this);
      this._cleanTotals = true;
    }
  };

  Invoice.prototype._totalMayHaveChanged = function _totalMayHaveChanged(changeEvent, changeDetail) {
    var listeners = this.listeners(Invoice.Event.TotalChanged);
    // If a tree falls in the woods...
    if (listeners && listeners.length) {
      if (!this._total) {
        (0, _totalCalculator2.default)(this);
        this.emit(Invoice.Event.TotalChanged, changeEvent, changeDetail);
      } else {
        var curTotal = new _InvoiceBigNumber2.default(this._total);
        (0, _totalCalculator2.default)(this);
        if (!curTotal.equals(this._total)) {
          this.emit(Invoice.Event.TotalChanged, changeEvent, changeDetail);
        }
      }
    } else {
      this._cleanTotals = false;
    }
  };

  // ********************************* API CALLS **********************************

  /**
   * Update the full invoice from the server, based on its payPalId.
   * @param {Invoice~gotDetails} callback Called with an error
   */

  Invoice.prototype.getDetails = function getDetails(callback) {
    var _this3 = this;

    (0, _assert2.default)(this.payPalId, 'Can\'t get details of an invoice without an id.');
    (0, _assert2.default)(!this.wasDeleted, 'Can\'t get details on an invoice that was deleted.');

    (0, _Requester.request)({
      method: 'GET',
      op: 'invoices/' + this.payPalId
    }, function (error, response) {
      if (!error) {
        _this3.readJSON(response.body, true);
        _this3.setCleanFromServer();
      }
      if (callback) {
        callback(error);
      }
    });
  };

  /**
   * Save the invoice to the PayPal servers.
   * @param {Invoice~saved} callback Called with an error
   */


  Invoice.prototype.save = function save(callback) {
    var _this4 = this;

    (0, _assert2.default)(this.hasDetails, 'Can\'t save an invoice without details');
    (0, _assert2.default)(!this.wasDeleted, 'Can\'t save an invoice that was deleted.');
    if (!this.isDirtyFromServer) {
      if (callback) {
        callback();
      }
      return;
    }
    (0, _Requester.request)({
      // If this invoice has an ID, then it must already be on the server. If it is, update
      // the existing invoice instead of creating a new one.
      method: this.payPalId ? 'PUT' : 'POST',
      op: this.payPalId ? 'invoices/' + this.payPalId : 'invoices',
      body: JSON.stringify(this)
    }, function (error, invoiceResponse) {
      if (!error && invoiceResponse.body) {
        var rz = invoiceResponse.body;
        _this4.payPalId = _this4.payPalId || rz.id;
        _this4.number = _this4.number || rz.number;
        _this4.invoiceDate = _InvoicingUtil2.default.parseServerDateString(rz.invoice_date);
        _this4.status = statusFromServer(rz.status);
        _this4.setCleanFromServer();
      }
      if (callback) {
        callback(error);
      }
    });
  };

  /**
   * Send the invoice. It must have already been saved to the server.
   * @param {bool} shouldNotifyMerchant A flag indicating whether a
   *  copy of the notification has to be sent to the merchant
   * @param {Invoice~sent} callback Called with an error
   */


  Invoice.prototype.send = function send(shouldNotifyMerchant, callback) {
    var _this5 = this;

    // TODO: Once we track whether save is required, save here if it's required.
    (0, _assert2.default)(this.payPalId, 'Can\'t send an invoice without an id.');
    (0, _assert2.default)(!this.wasDeleted, 'Can\'t send an invoice that was deleted.');

    (0, _Requester.request)({
      method: 'POST',
      op: 'invoices/' + this.payPalId + '/send?notify_merchant=' + !!shouldNotifyMerchant
    }, function (error, response) {
      if (!error) {
        _this5.status = _InvoiceEnums2.default.Status.SENT;
      }
      if (callback) {
        callback(error, response);
      }
    });
  };

  /**
   * Delete the invoice from the server. It must have already been saved to the server.
   * @param {Invoice~deleted} callback Called with an error
   */


  Invoice.prototype.deleteFromServer = function deleteFromServer(callback) {
    var _this6 = this;

    (0, _assert2.default)(this.payPalId, 'Can\'t delete an invoice without an id.');
    (0, _assert2.default)(!this.wasDeleted, 'Can\'t delete an invoice that was deleted.');
    (0, _Requester.request)({
      method: 'DELETE',
      op: 'invoices/' + this.payPalId
    }, function (error, response) {
      if (!error) {
        _this6.status = _InvoiceEnums2.default.Status.NEW;
        _this6.wasDeleted = true;
      }
      if (callback) {
        callback(error, response);
      }
    });
  };

  /**
   * Send a reminder about this invoice to its intended recipient
   * @param {InvoiceNotification} notification
   * @param {Invoice~reminded} callback
   */


  Invoice.prototype.remind = function remind(notification, callback) {
    (0, _assert2.default)(this.payPalId, 'Can\'t remind an invoice without an id.');
    (0, _assert2.default)(notification.send_to_payer !== false, 'Can\'t send a reminder that doesn\'t go to the payer.');
    (0, _assert2.default)(!this.wasDeleted, 'Can\'t remind an invoice that was deleted.');
    (0, _Requester.request)({
      method: 'POST',
      op: 'invoices/' + this.payPalId + '/remind',
      body: JSON.stringify(notification)
    }, callback);
  };

  /**
   * Cancel this invoice
   * @param {InvoiceNotification} notification
   * @param {Invoice~cancelled} callback
   */


  Invoice.prototype.cancel = function cancel(notification, callback) {
    var _this7 = this;

    (0, _assert2.default)(this.payPalId, 'Can\'t cancel an invoice without an id.');
    (0, _assert2.default)(!this.wasDeleted, 'Can\'t cancel an invoice that was deleted.');

    (0, _Requester.request)({
      method: 'POST',
      op: 'invoices/' + this.payPalId + '/cancel',
      body: JSON.stringify(notification)
    }, function (error, response) {
      if (!error) {
        _this7.status = _InvoiceEnums2.default.Status.CANCELLED;
      }
      if (callback) {
        callback(error, response);
      }
    });
  };

  /**
   * @param {InvoicePayment} paymentInfo
   * @param {Invoice~paid} callback
   */


  Invoice.prototype.recordPayment = function recordPayment(paymentInfo, callback) {
    var _this8 = this;

    (0, _assert2.default)(this.payPalId, 'Can\'t record payment on an invoice without an id.');
    (0, _assert2.default)(paymentInfo, 'Can\'t record payment on an invoice without paymentInfo.');
    (0, _assert2.default)(!this.wasDeleted, 'Can\'t record payment on an invoice that was deleted.');

    paymentInfo.validate();
    (0, _Requester.request)({
      method: 'POST',
      op: 'invoices/' + this.payPalId + '/record-payment',
      body: JSON.stringify(paymentInfo)
    }, function (error, response) {
      if (!error) {
        if (paymentInfo.type === _InvoiceEnums2.default.PaymentType.EXTERNAL) {
          _this8.status = _InvoiceEnums2.default.Status.MARKED_AS_PAID;
        } else if (paymentInfo.type === _InvoiceEnums2.default.PaymentType.PAYPAL) {
          _this8.status = _InvoiceEnums2.default.Status.PAID;
        }
      }
      if (callback) {
        callback(error, response);
      }
    });
  };

  /**
   * @param {InvoiceRefund} refundInfo
   * @param {Invoice~paid} callback
   */


  Invoice.prototype.recordRefund = function recordRefund(refundInfo, callback) {
    var _this9 = this;

    (0, _assert2.default)(this.payPalId, 'Can\'t record refund on an invoice without an id.');
    (0, _assert2.default)(!this.wasDeleted, 'Can\'t record refund on an invoice that was deleted.');
    (0, _assert2.default)(this.status === _InvoiceEnums2.default.Status.MARKED_AS_PAID || this.status === _InvoiceEnums2.default.Status.PAID || this.status === _InvoiceEnums2.default.Status.PARTIALLY_REFUNDED, 'Can\'t record refund on an invoice that hasn\'t been paid yet.');
    (0, _assert2.default)(refundInfo, 'Can\'t record refund on an invoice without refundInfo.');

    (0, _Requester.request)({
      method: 'POST',
      op: 'invoices/' + this.payPalId + '/record-refund',
      body: JSON.stringify(refundInfo)
    }, function (error, response) {
      if (!error) {
        if (refundInfo.type === _InvoiceEnums2.default.PaymentType.EXTERNAL) {
          _this9.status = _InvoiceEnums2.default.Status.MARKED_AS_REFUNDED;
        } else if (refundInfo.type === _InvoiceEnums2.default.PaymentType.PAYPAL) {
          _this9.status = _InvoiceEnums2.default.Status.REFUNDED;
        }
      }
      if (callback) {
        callback(error, response);
      }
    });
  };

  // **************************** JSON PARSING AND SERIALIZATION *****************************

  Invoice.prototype.toJSON = function toJSON() {
    /* jshint maxcomplexity: false */
    var r = {};
    r.note = this.note;
    r.number = this.number;
    r.invoice_date = _InvoicingUtil2.default.toServerDateString(this.invoiceDate, false);
    r.merchant_info = this.merchantInfo;
    r.shipping_info = this.shippingInfo;
    r.billing_info = [this.billingInfo];
    r.tax_inclusive = this.taxInclusive;
    r.tax_calculated_after_discount = this.taxCalculatedAfterDiscount;
    r.allow_partial_payment = this.allowPartialPayment;
    r.uri = this.uri;
    r.logo_url = this.logoURL;
    r.additional_data = this.additionalData;
    r.attachments = this.attachments;
    r.template_id = this.templateID;

    this._CCInfoToJson(r);

    if (this.termsAndConditions) {
      r.terms = this.termsAndConditions.substring(0, 3999);
    }
    if (this.merchantMemo) {
      r.merchant_memo = this.merchantMemo.substring(0, 149);
    }

    this._shippingToJson(r);

    if (this.minimumAmountDue) {
      r.minimum_amount_due = {
        currency: this.currency,
        value: this.minimumAmountDue
      };
    }

    r.id = this.payPalId;
    if (this.status) {
      r.status = _InvoiceEnums2.default.Status.toString[this.status];
    }
    r.reference = this.reference;

    if (this.gratuityAmount) {
      r.gratuity = {
        currency: this.currency,
        value: this.gratuityAmount
      };
    }
    if (this.discountAmount || this.discountPercentage) {
      r.discount = this.discountObject();
    }
    if (this.paymentTerms.dueDate || this.paymentTerms.paymentTerms) {
      r.payment_term = this.paymentTerms.toJSONHack(r.invoice_date);
    }
    this._itemsToJson(r);

    if (this.custom) {
      r.custom = this.custom.toJSON(this.currency);
    }
    return r;
  };

  // Returns the full JSON, including readonly properties like payments
  // and refunds which should not be sent to the server.


  Invoice.prototype.toFullJSON = function toFullJSON() {
    var r = this.toJSON();
    r.payments = this.payments;
    r.refunds = this.refunds;

    if (this.paidAmount) {
      r.paid_amount = {};
      if (this.paidAmountIsPayPal) {
        r.paid_amount.paypal = {
          currency: this.currency,
          value: this.paidAmount
        };
      } else {
        r.paid_amount.other = {
          currency: this.currency,
          value: this.paidAmount
        };
      }
    }

    if (this.refundedAmount) {
      r.refunded_amount = {};
      if (this.refundedAmountIsPayPal) {
        r.refunded_amount.paypal = {
          currency: this.currency,
          value: this.refundedAmount
        };
      } else {
        r.refunded_amount.other = {
          currency: this.currency,
          value: this.refundedAmount
        };
      }
    }

    // Due to a server bug (see PaymentTerm.js), toJSON does a weird hack with the payment terms.
    // We don't want that in toFullJSON, so this overwrites it.
    // TODO: sto this once server is fixed.
    r.payment_term = this.paymentTerms;

    return r;
  };

  Invoice.prototype._shippingToJson = function _shippingToJson(r) {
    if (this.shippingAmount) {
      r.shipping_cost = {};

      r.shipping_cost.amount = {
        currency: this.currency,
        value: this.shippingAmount
      };
      if (this.shippingTaxRate && !this.shippingTaxRate.isZero()) {
        r.shipping_cost.tax = {
          name: this.shippingTaxName || 'Shipping Tax',
          percent: this.shippingTaxRate
        };
      }
    }
  };

  Invoice.prototype._itemsToJson = function _itemsToJson(r) {
    if (this.items && this.items.length) {
      r.items = [];
      for (var _iterator2 = this.items, _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) {
        var _ref2;

        if (_isArray2) {
          if (_i2 >= _iterator2.length) break;
          _ref2 = _iterator2[_i2++];
        } else {
          _i2 = _iterator2.next();
          if (_i2.done) break;
          _ref2 = _i2.value;
        }

        var i = _ref2;

        r.items.push(i.toJSON(this.currency));
      }
    }
  };

  Invoice.prototype._CCInfoToJson = function _CCInfoToJson(r) {
    if (this.CCInfo && this.CCInfo.length) {
      r.cc_info = [];
      for (var _iterator3 = this.CCInfo, _isArray3 = Array.isArray(_iterator3), _i3 = 0, _iterator3 = _isArray3 ? _iterator3 : _iterator3[Symbol.iterator]();;) {
        var _ref3;

        if (_isArray3) {
          if (_i3 >= _iterator3.length) break;
          _ref3 = _iterator3[_i3++];
        } else {
          _i3 = _iterator3.next();
          if (_i3.done) break;
          _ref3 = _i3.value;
        }

        var i = _ref3;

        r.cc_info.push(i.toJSON());
      }
    }
  };

  Invoice.prototype.discountObject = function discountObject() {
    var discount = {};
    if (this.discountAmount) {
      discount.amount = {};
      discount.amount.value = this.discountAmount;
      discount.amount.currency = this.currency;
    } else if (this.discountPercentage) {
      discount.percent = this.discountPercentage;
    }
    return discount;
  };

  /**
   * Construct an invoice from a server response
   * @param serverJSON
   * @param bool hasDetails
   * @private
   */


  Invoice.prototype.readJSON = function readJSON(serverJSON, hasDetails) {
    /* jshint maxcomplexity: false */

    this.invoiceDate = _InvoicingUtil2.default.parseServerDateString(serverJSON.invoice_date);
    this.status = statusFromServer(serverJSON.status);
    this.reference = serverJSON.reference;
    this.number = serverJSON.number;
    this.payPalId = serverJSON.id;
    this.note = serverJSON.note;
    this.merchantInfo.readFromJson(serverJSON.merchant_info);
    this.allowPartialPayment = serverJSON.allow_partial_payment;
    this.uri = serverJSON.uri;
    this.logoURL = serverJSON.logo_url;
    this.additionalData = serverJSON.additional_data;
    this.templateID = serverJSON.template_id;

    this.hasDetails = hasDetails;

    if (serverJSON.metadata) {
      this.metadata = _InvoiceMetaData2.default.fromJSON(serverJSON.metadata);
    }

    if (serverJSON.custom) {
      this.custom = _CustomAmount2.default.fromJSON(serverJSON.custom);
    }

    if (serverJSON.payments) {
      this.payments = [];
      for (var _iterator4 = serverJSON.payments, _isArray4 = Array.isArray(_iterator4), _i4 = 0, _iterator4 = _isArray4 ? _iterator4 : _iterator4[Symbol.iterator]();;) {
        var _ref4;

        if (_isArray4) {
          if (_i4 >= _iterator4.length) break;
          _ref4 = _iterator4[_i4++];
        } else {
          _i4 = _iterator4.next();
          if (_i4.done) break;
          _ref4 = _i4.value;
        }

        var payment = _ref4;

        this.payments.push(_Payment2.default.readFromJson(payment));
      }
    }
    if (serverJSON.refunds) {
      this.refunds = [];
      for (var _iterator5 = serverJSON.refunds, _isArray5 = Array.isArray(_iterator5), _i5 = 0, _iterator5 = _isArray5 ? _iterator5 : _iterator5[Symbol.iterator]();;) {
        var _ref5;

        if (_isArray5) {
          if (_i5 >= _iterator5.length) break;
          _ref5 = _iterator5[_i5++];
        } else {
          _i5 = _iterator5.next();
          if (_i5.done) break;
          _ref5 = _i5.value;
        }

        var refund = _ref5;

        this.refunds.push(_Refund2.default.readFromJson(refund));
      }
    }

    if (serverJSON.attachments) {
      this.attachments = [];
      for (var _iterator6 = serverJSON.attachments, _isArray6 = Array.isArray(_iterator6), _i6 = 0, _iterator6 = _isArray6 ? _iterator6 : _iterator6[Symbol.iterator]();;) {
        var _ref6;

        if (_isArray6) {
          if (_i6 >= _iterator6.length) break;
          _ref6 = _iterator6[_i6++];
        } else {
          _i6 = _iterator6.next();
          if (_i6.done) break;
          _ref6 = _i6.value;
        }

        var a = _ref6;

        this.attachments.push(_Attachment2.default.readFromJson(a));
      }
    }

    if (serverJSON.terms) {
      this.termsAndConditions = serverJSON.terms;
    }
    if (serverJSON.merchant_memo) {
      this.merchantMemo = serverJSON.merchant_memo;
    }
    if (serverJSON.shipping_cost) {
      this.shippingAmount = (0, _InvoiceBigNumber.$$)(serverJSON.shipping_cost.amount.value);
      if (serverJSON.shipping_cost.tax) {
        this.shippingTaxRate = (0, _InvoiceBigNumber.$$)(serverJSON.shipping_cost.tax.percent);
        if (serverJSON.shipping_cost.tax.name) {
          this.shippingTaxName = serverJSON.shipping_cost.tax.name;
        }
      }
    }
    if (serverJSON.minimum_amount_due) {
      this.minimumAmountDue = (0, _InvoiceBigNumber.$$)(serverJSON.minimum_amount_due.value);
    }
    if (serverJSON.refunded_amount) {
      if (serverJSON.refunded_amount.paypal) {
        this.refundedAmount = (0, _InvoiceBigNumber.$$)(serverJSON.refunded_amount.paypal.value);
        this.refundedAmountIsPayPal = true;
      } else if (serverJSON.refunded_amount.other) {
        this.refundedAmount = (0, _InvoiceBigNumber.$$)(serverJSON.refunded_amount.other.value);
        this.refundedAmountIsPayPal = false;
      }
    }
    if (serverJSON.paid_amount) {
      if (serverJSON.paid_amount.paypal) {
        this.paidAmount = (0, _InvoiceBigNumber.$$)(serverJSON.paid_amount.paypal.value);
        this.paidAmountIsPayPal = true;
      } else if (serverJSON.paid_amount.other) {
        this.paidAmount = (0, _InvoiceBigNumber.$$)(serverJSON.paid_amount.other.value);
        this.paidAmountIsPayPal = false;
      }
    }
    if (serverJSON.billing_info && serverJSON.billing_info.length) {
      this.billingInfo.readFromJson(serverJSON.billing_info[0]);
    }
    if (serverJSON.shipping_info) {
      this.shippingInfo.readFromJson(serverJSON.shipping_info);
    }
    if (serverJSON.cc_info) {
      this.CCInfo = [];
      for (var _iterator7 = serverJSON.cc_info, _isArray7 = Array.isArray(_iterator7), _i7 = 0, _iterator7 = _isArray7 ? _iterator7 : _iterator7[Symbol.iterator]();;) {
        var _ref7;

        if (_isArray7) {
          if (_i7 >= _iterator7.length) break;
          _ref7 = _iterator7[_i7++];
        } else {
          _i7 = _iterator7.next();
          if (_i7.done) break;
          _ref7 = _i7.value;
        }

        var ccinfo = _ref7;

        var invoiceCCInfo = _CCInfo2.default.fromJson(ccinfo);
        this.CCInfo.push(invoiceCCInfo);
      }
    }
    this.items = [];
    if (serverJSON.items) {
      for (var _iterator8 = serverJSON.items, _isArray8 = Array.isArray(_iterator8), _i8 = 0, _iterator8 = _isArray8 ? _iterator8 : _iterator8[Symbol.iterator]();;) {
        var _ref8;

        if (_isArray8) {
          if (_i8 >= _iterator8.length) break;
          _ref8 = _iterator8[_i8++];
        } else {
          _i8 = _iterator8.next();
          if (_i8.done) break;
          _ref8 = _i8.value;
        }

        var item = _ref8;

        var invoiceItem = _Item2.default.fromJson(item);
        this.setupItemListeners(invoiceItem);
        this.items.push(invoiceItem);
      }
    } else {
      this._total = serverJSON.total_amount ? (0, _InvoiceBigNumber.$$)(serverJSON.total_amount.value) : (0, _InvoiceBigNumber.$$)('0');
    }
    if (serverJSON.gratuity) {
      this.gratuityAmount = (0, _InvoiceBigNumber.$$)(serverJSON.gratuity.value);
    }
    this.paymentTerms = _PaymentTerm2.default.fromJson(serverJSON.payment_term);
    if (serverJSON.hasOwnProperty('tax_inclusive')) {
      this.taxInclusive = serverJSON.tax_inclusive;
    }
    if (serverJSON.hasOwnProperty('tax_calculated_after_discount')) {
      this.taxCalculatedAfterDiscount = serverJSON.tax_calculated_after_discount;
    }
    if (serverJSON.hasOwnProperty('discount')) {
      var discount = serverJSON.discount;
      if (discount.hasOwnProperty('percent')) {
        this.discountPercentage = (0, _InvoiceBigNumber.$$)(discount.percent);
      } else if (serverJSON.discount.hasOwnProperty('amount')) {
        this.discountAmount = (0, _InvoiceBigNumber.$$)(serverJSON.discount.amount.value);
      }
    }
  };

  Invoice.fromJson = function fromJson(serverJSON, hasDetails) {
    if (!serverJSON.total_amount) {
      throw new Error('Invoice JSON has no total_amount.');
    }
    var i = new Invoice(serverJSON.total_amount.currency);
    i.readJSON(serverJSON, hasDetails);
    return i;
  };

  _createClass(Invoice, [{
    key: 'isDirtyFromServer',
    get: function get() {
      return !this._lastKnownServerValue || !(0, _deepEqual2.default)(this._lastKnownServerValue, (0, _manticoreUtil.deepToJSON)(this));
    }
  }, {
    key: 'invoiceDate',
    set: function set(date) {
      this._invoiceDate = date;
    },
    get: function get() {
      return _InvoicingUtil2.default.getDateValue(this._invoiceDate);
    }
  }, {
    key: 'itemCount',
    get: function get() {
      return this.items.length;
    }
  }, {
    key: 'gratuityAmount',
    get: function get() {
      return this._gratuityAmount;
    },
    set: function set(value) {
      this._gratuityAmount = (0, _InvoiceBigNumber.$$)(value);
      this._totalMayHaveChanged('field', 'gratuityAmount');
    }
  }, {
    key: 'discountAmount',
    get: function get() {
      return this._discountAmount;
    },
    set: function set(value) {
      this._discountAmount = (0, _InvoiceBigNumber.$$)(value);
      this._totalMayHaveChanged('field', 'discountAmount');
    }
  }, {
    key: 'discountPercentage',
    get: function get() {
      return this._discountPercentage;
    },
    set: function set(value) {
      this._discountPercentage = (0, _InvoiceBigNumber.$$)(value);
      this._totalMayHaveChanged('field', 'discountPercentage');
    }
  }, {
    key: 'shippingAmount',
    get: function get() {
      return this._shippingAmount;
    },
    set: function set(value) {
      this._shippingAmount = (0, _InvoiceBigNumber.$$)(value);
      this._totalMayHaveChanged('field', 'shippingAmount');
    }
  }, {
    key: 'shippingTaxRate',
    get: function get() {
      return this._shippingTaxRate;
    },
    set: function set(value) {
      this._shippingTaxRate = (0, _InvoiceBigNumber.$$)(value);
      this._totalMayHaveChanged('field', 'shippingTaxRate');
    }
  }, {
    key: 'total',
    get: function get() {
      if (this.hasDetails) {
        this.ensureTotals();
      }
      return this._total;
    }
  }, {
    key: 'subTotal',
    get: function get() {
      (0, _assert2.default)(this.hasDetails, 'Can\'t calculate the subtotal without details');
      this.ensureTotals();
      return this._subTotal;
    }
  }, {
    key: 'itemTax',
    get: function get() {
      (0, _assert2.default)(this.hasDetails, 'Can\'t calculate the item tax without details');
      this.ensureTotals();
      return this._itemTax;
    }
  }, {
    key: 'totalDiscount',
    get: function get() {
      (0, _assert2.default)(this.hasDetails, 'Can\'t calculate the total discount without details');
      this.ensureTotals();
      return this._totalDiscount;
    }
  }, {
    key: 'taxBreakdown',
    get: function get() {
      (0, _assert2.default)(this.hasDetails, 'Can\'t calculate the tax breakdown without details');
      this.ensureTotals();
      return this._taxBreakdown;
    }
  }]);

  return Invoice;
}(_events.EventEmitter);

exports.default = Invoice;


Invoice.Event = {
  TotalChanged: 'totalChanged'
};

// Put any callback definitions before the module exports, and
// reference them in parameter definitions.

/**
 * @callback Invoice~gotDetails
 * @param {PayPalError} error The error that occurred, if any
 */

/**
 * After an attempt has been made to save your invoice to the PayPal servers,
 * the completion handler will be called with the error (if any, or null if not)
 * and the invoice object will be updated appropriately.
 * @callback Invoice~saved
 * @param {PayPalError} error The error that occurred, if any
 */

/**
 * After an attempt has been made to send your invoice, the completion handler
 * will be called with the error (if any, or null if not) and the invoice object
 * will be updated appropriately.
 * @callback Invoice~sent
 * @param {PayPalError} error The error that occurred, if any
 */

/**
 * @callback Invoice~deleted
 * @param {PayPalError} error The error that occurred, if any
 */

/**
 * @callback Invoice~reminded
 * @param {PayPalError} error The error that occurred, if any
 */

/**
 * @callback Invoice~cancelled
 * @param {PayPalError} error The error that occurred, if any
 */

/**
 * @callback Invoice~paid
 * @param {PayPalError} error The error that occurred, if any
 */

/**
 * @callback Invoice~refunded
 * @param {PayPalError} error The error that occurred, if any
 */
},{"./Attachment":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/Attachment.js","./BillingInfo":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/BillingInfo.js","./CCInfo":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/CCInfo.js","./Currency":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/Currency.js","./CustomAmount":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/CustomAmount.js","./InvoiceBigNumber":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/InvoiceBigNumber.js","./InvoiceEnums":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/InvoiceEnums.js","./InvoiceMetaData":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/InvoiceMetaData.js","./InvoicingUtil":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/InvoicingUtil.js","./Item":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/Item.js","./MerchantInfo":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/MerchantInfo.js","./Payment":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/Payment.js","./PaymentTerm":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/PaymentTerm.js","./Refund":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/Refund.js","./Requester":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/Requester.js","./ShippingInfo":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/ShippingInfo.js","./totalCalculator":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/totalCalculator.js","assert":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/assert/assert.js","deep-equal":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/deep-equal/index.js","events":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/events/events.js","manticore-log":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-log/index.js","manticore-util":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-util/build/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/InvoiceActions.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

var _InvoiceEnums = require('./InvoiceEnums');

var _InvoiceEnums2 = _interopRequireDefault(_InvoiceEnums);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

/**
 * @class
 */

var InvoiceActions = function () {
  function InvoiceActions() {
    _classCallCheck(this, InvoiceActions);
  }

  /**
   * @param {Invoice} invoice
   * @returns {[Invoice.Action]}
   */

  InvoiceActions.availableActions = function availableActions(invoice) {
    var a = _InvoiceEnums2.default.Action;
    switch (invoice.status) {
      case _InvoiceEnums2.default.Status.NEW:
        throw new Error('Actions are undefined for NEW invoices.');
      case _InvoiceEnums2.default.Status.DRAFT:
        return [a.Send, a.Edit, a.Delete, a.RecordPayment, a.Copy];
      case _InvoiceEnums2.default.Status.SENT:
      case _InvoiceEnums2.default.Status.PARTIALLY_PAID:
        return [a.Remind, a.RecordPayment, a.Call, a.Edit, a.Cancel, a.Copy];
      case _InvoiceEnums2.default.Status.PAID:
      case _InvoiceEnums2.default.Status.MARKED_AS_PAID:
      case _InvoiceEnums2.default.Status.PARTIALLY_REFUNDED:
        if (invoice.total === 0) {
          return [a.Call, a.Copy];
        }
        return [a.RecordRefund, a.Call, a.Copy];
      case _InvoiceEnums2.default.Status.CANCELLED:
      case _InvoiceEnums2.default.Status.REFUNDED:
      case _InvoiceEnums2.default.Status.MARKED_AS_REFUNDED:
        return [a.Call, a.Copy];
      case _InvoiceEnums2.default.Status.UNPAID:
        return [a.RecordPayment, a.Edit, a.Cancel, a.Copy];
      default:
        throw new Error('Unknown invoice status');
    }
  };

  return InvoiceActions;
}();

exports.default = InvoiceActions;
},{"./InvoiceEnums":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/InvoiceEnums.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/InvoiceBigNumber.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;
exports.$$ = $$;

var _bignumber = require('bignumber.js');

var _bignumber2 = _interopRequireDefault(_bignumber);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (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 } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var InvoiceBigNumber = function (_BN) {
  _inherits(InvoiceBigNumber, _BN);

  function InvoiceBigNumber() {
    _classCallCheck(this, InvoiceBigNumber);

    return _possibleConstructorReturn(this, _BN.apply(this, arguments));
  }

  InvoiceBigNumber.$$ = function $$(a) {
    return a ? new InvoiceBigNumber(a) : null;
  };

  InvoiceBigNumber.prototype.toJSON = function toJSON() {
    return this.toFixed(2);
  };

  return InvoiceBigNumber;
}(_bignumber2.default);

exports.default = InvoiceBigNumber;
function $$(a) {
  return InvoiceBigNumber.$$(a);
}
},{"bignumber.js":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/bignumber.js/bignumber.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/InvoiceEnums.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

var _manticoreUtil = require('manticore-util');

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

// This class is named Invoice for the sake of codegen

var Invoice = function Invoice() {
  _classCallCheck(this, Invoice);
};

/**
 * Valid invoice statuses
 * @enum {int}
 */


exports.default = Invoice;
Invoice.Status = {
  /**
   * The invoice has not been saved to the server
   */
  NEW: 0,
  /**
   * The invoice has been saved to the server
   */
  DRAFT: 1,
  /**
   * The invoice has been sent to the recipient(payer)
   */
  SENT: 2,
  /**
   * The invoice has been paid with a balance affecting instrument like PayPal or CC
   */
  PAID: 3,
  /**
   * The invoice has been marked as paid with a method outside PayPal
   */
  MARKED_AS_PAID: 4,
  /**
   * The invoice has been cancelled
   */
  CANCELLED: 5,
  /**
   * The invoice has been refunded from a balance affecting instrument
   */
  REFUNDED: 6,
  /**
   * The invoice has been partially refunded from a balance affecting instrument
   */
  PARTIALLY_REFUNDED: 7,
  /**
   * The invoice has been marked as refunded with a method outside PayPal
   */
  MARKED_AS_REFUNDED: 8,
  /**
   * The invoice has been partially paid
   */
  PARTIALLY_PAID: 9,
  /*
   * The invoice has been sent with no receipient
   */
  UNPAID: 10
};

Invoice.Status.toString = (0, _manticoreUtil.reverseKeysAndValues)(Invoice.Status);

/**
 * PayPal payment detail indicating whether payment was made in an invoicing flow via PayPal
 * or externally. In the case of the mark-as-paid API, payment type is EXTERNAL and this
 * is what is now supported. The PAYPAL value is provided for backward compatibility.
 * @enum {int}
 */
Invoice.PaymentType = {
  /**
   * The invoice hasn't been paid
   */
  NONE: 0,
  /**
   * The invoice was paid with an external (non-balance-affecting) source
   */
  EXTERNAL: 1,
  /**
   * The invoice was paid with an internal (balance-affecting) source
   */
  PAYPAL: 2
};

Invoice.PaymentType.toString = (0, _manticoreUtil.reverseKeysAndValues)(Invoice.PaymentType);

/**
 * Payment mode or method.
 * @enum {int}
 */
Invoice.PaymentMethod = {
  /**
   * None
   */
  NONE: 0,
  /**
   * Bank Transfer
   */
  BANK_TRANSFER: 1,
  /**
   * Cash
   */
  CASH: 2,
  /**
   * Check
   */
  CHECK: 3,
  /**
   * Credit Card
   */
  CREDIT_CARD: 4,
  /**
   * Debit Card
   */
  DEBIT_CARD: 5,
  /**
   * PayPal
   */
  PAYPAL: 6,
  /**
   * Wire Transfer
   */
  WIRE_TRANSFER: 7,
  /**
   * Other
   */
  OTHER: 8
};

Invoice.PaymentMethod.toString = (0, _manticoreUtil.reverseKeysAndValues)(Invoice.PaymentMethod);

/**
 * Invoice action
 * @enum {int}
 */
Invoice.Action = {
  /**
   * None
   */
  None: 0,
  /**
   * Delete
   */
  Delete: 1,
  /**
   * Send
   */
  Send: 2,
  /**
   * Remind
   */
  Remind: 3,
  /**
   * Record Payment
   */
  RecordPayment: 4,
  /**
   * Record Refund
   */
  RecordRefund: 5,
  /**
   * Copy
   */
  Copy: 6,
  /**
   * Edit
   */
  Edit: 7,
  /**
   * Call
   */
  Call: 8,
  /**
   * Cancel
   */
  Cancel: 9,
  /**
   * More
   */
  More: 10
};
},{"manticore-util":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-util/build/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/InvoiceListRequest.js":[function(require,module,exports){
"use strict";

exports.__esModule = true;

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

/**
 * @class
 * @property {int} startIndex A zero-relative index of the merchant's list of invoices
 * @property {int} pageSize The number of invoices to retrieve, beginning with the specified page
 * @property {bool} totalCountRequired Determines if the total count is returned.
 */

var InvoiceListRequest = function InvoiceListRequest() {
  _classCallCheck(this, InvoiceListRequest);

  this.startIndex = 0;
  this.pageSize = 20;
  this.totalCountRequired = true;
};

exports.default = InvoiceListRequest;
},{}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/InvoiceListResponse.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

var _Invoice = require('./Invoice');

var _Invoice2 = _interopRequireDefault(_Invoice);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

/**
 * @class
 * @property {[Invoice]} invoices All the invoices in the requested page of the invoice list
 * @property {int} totalCount The total number of invoices in the invoice list.
 *  May be 0 if totalCountRequired wasn't specified.
 * @property {bool} hasMore yes if this is not the last page of invoices
 */

var InvoiceListResponse = function () {
  function InvoiceListResponse() {
    _classCallCheck(this, InvoiceListResponse);
  }

  InvoiceListResponse.fromJSON = function fromJSON(json) {
    var r = new InvoiceListResponse();

    r.invoices = [];
    for (var _iterator = json.invoices, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
      var _ref;

      if (_isArray) {
        if (_i >= _iterator.length) break;
        _ref = _iterator[_i++];
      } else {
        _i = _iterator.next();
        if (_i.done) break;
        _ref = _i.value;
      }

      var invoiceJSON = _ref;

      var i = _Invoice2.default.fromJson(invoiceJSON, false);
      i.setCleanFromServer();
      r.invoices.push(i);
    }

    r.totalCount = json.total_count ? json.total_count : 0;

    return r;
  };

  return InvoiceListResponse;
}();

exports.default = InvoiceListResponse;
},{"./Invoice":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/Invoice.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/InvoiceMetaData.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

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; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

var _InvoicingUtil = require('./InvoicingUtil');

var _InvoicingUtil2 = _interopRequireDefault(_InvoicingUtil);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

/**
 * Invoice MetaData
 * @class
 * @property {Date} createdDate Date when the resource was created. @readonly
 * @property {string} createdBy Email address of the account that created the resource. @readonly
 * @property {Date} cancelledDate Date when the resource was cancelled. @readonly
 * @property {string} cancelledBy Actor who cancelled the resource. @readonly
 * @property {Date} lastUpdatedDate Date when the resource was last edited. @readonly
 * @property {string} lastUpdatedBy Email address of the account that last
 *  edited the resource. @readonly
 * @property {Date} firstSentDate Date when the resource was first sent. @readonly
 * @property {Date} lastSentDate Date when the resource was last sent. @readonly
 * @property {string} lastSentBy Email address of the account that last sent the resource. @readonly
 * @property {string} payerViewURL URL representing the payer's view of the invoice. @readonly
 */

var InvoiceMetaData = function () {
  function InvoiceMetaData() {
    _classCallCheck(this, InvoiceMetaData);
  }

  InvoiceMetaData.fromJSON = function fromJSON(json) {
    var m = new InvoiceMetaData();

    m.createdBy = json.created_by;
    m.cancelledBy = json.cancelled_by;
    m.lastUpdatedBy = json.last_updated_by;
    m.lastSentBy = json.last_sent_by;
    m.payerViewURL = json.payer_view_url;

    if (json.created_date) {
      m.createdDate = _InvoicingUtil2.default.parseServerDateString(json.created_date);
    }
    if (json.cancelled_date) {
      m.cancelledDate = _InvoicingUtil2.default.parseServerDateString(json.cancelled_date);
    }
    if (json.last_updated_date) {
      m.lastUpdatedDate = _InvoicingUtil2.default.parseServerDateString(json.last_updated_date);
    }
    if (json.first_sent_date) {
      m.firstSentDate = _InvoicingUtil2.default.parseServerDateString(json.first_sent_date);
    }
    if (json.last_sent_date) {
      m.lastSentDate = _InvoicingUtil2.default.parseServerDateString(json.last_sent_date);
    }
    return m;
  };

  _createClass(InvoiceMetaData, [{
    key: 'createdDate',
    set: function set(date) {
      this._createdDate = date;
    },
    get: function get() {
      return _InvoicingUtil2.default.getDateValue(this._createdDate);
    }
  }, {
    key: 'cancelledDate',
    set: function set(date) {
      this._cancelledDate = date;
    },
    get: function get() {
      return _InvoicingUtil2.default.getDateValue(this._cancelledDate);
    }
  }, {
    key: 'firstSentDate',
    set: function set(date) {
      this._firstSentDate = date;
    },
    get: function get() {
      return _InvoicingUtil2.default.getDateValue(this._firstSentDate);
    }
  }, {
    key: 'lastSentDate',
    set: function set(date) {
      this._lastSentDate = date;
    },
    get: function get() {
      return _InvoicingUtil2.default.getDateValue(this._lastSentDate);
    }
  }]);

  return InvoiceMetaData;
}();

exports.default = InvoiceMetaData;
},{"./InvoicingUtil":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/InvoicingUtil.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/InvoiceTemplatesResponse.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

var _Template = require('./Template');

var _Template2 = _interopRequireDefault(_Template);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

/**
 * @class
 * @property {InvoiceTemplate} defaultTemplate The default template
 * @property {[InvoiceTemplate]} templates array of all the templates
 */

var InvoiceTemplatesResponse = function () {
  function InvoiceTemplatesResponse() {
    _classCallCheck(this, InvoiceTemplatesResponse);

    this.templates = [];
  }

  InvoiceTemplatesResponse.fromJSON = function fromJSON(json) {
    var r = void 0;

    if (json.templates) {
      r = new InvoiceTemplatesResponse();

      for (var _iterator = json.templates, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
        var _ref;

        if (_isArray) {
          if (_i >= _iterator.length) break;
          _ref = _iterator[_i++];
        } else {
          _i = _iterator.next();
          if (_i.done) break;
          _ref = _i.value;
        }

        var t = _ref;

        if (t.template_data.currencyCode === undefined) {
          // defaulting to USD just as a temporary workaround so I can get
          // all the templates back because the canned ones don't come back
          // with a currency code
          t.template_data.currencyCode = 'USD';
        }

        var temp = _Template2.default.fromJSON(t);
        if (temp !== undefined) {
          r.templates.push(temp);
          if (temp.isDefault === true) {
            r.defaultTemplate = temp;
          }
        }
      }
    }

    return r;
  };

  return InvoiceTemplatesResponse;
}();

exports.default = InvoiceTemplatesResponse;
},{"./Template":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/Template.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/InvoicingService.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

var _BaseService2 = require('./BaseClasses/BaseService');

var _BaseService3 = _interopRequireDefault(_BaseService2);

var _Requester = require('./Requester');

var _InvoiceListResponse = require('./InvoiceListResponse');

var _InvoiceListResponse2 = _interopRequireDefault(_InvoiceListResponse);

var _InvoiceTemplatesResponse = require('./InvoiceTemplatesResponse');

var _InvoiceTemplatesResponse2 = _interopRequireDefault(_InvoiceTemplatesResponse);

var _AccountSummary = require('./AccountSummary');

var _AccountSummary2 = _interopRequireDefault(_AccountSummary);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (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 } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

/**
 * @class
 */

var InvoicingService = function (_BaseService) {
  _inherits(InvoicingService, _BaseService);

  function InvoicingService() {
    _classCallCheck(this, InvoicingService);

    return _possibleConstructorReturn(this, _BaseService.apply(this, arguments));
  }

  /**
   * @param {InvoiceListRequest} params
   * @param {InvoicingService~getInvoices} completionHandler The completion handler
   */

  InvoicingService.getInvoices = function getInvoices(params, completionHandler) {
    var si = params.startIndex;
    var pg = params.pageSize;
    var tot = params.totalCountRequired;

    (0, _Requester.request)({
      method: 'GET',
      op: 'invoices?page=' + si + '&page_size=' + pg + '&total_count_required=' + tot
    }, function (error, response) {
      if (error) {
        completionHandler(error);
      } else {
        var r = _InvoiceListResponse2.default.fromJSON(response.body);
        r.hasMore = params.startIndex + params.pageSize < r.totalCount;
        completionHandler(error, r);
      }
    });
  };

  /**
   * Search for a specific invoice or invoices by passing a search object that
   * specifies your * search criteria.
   * @param {InvoiceSearchRequest} params
   * @param {InvoicingService~searchInvoices} completionHandler The completion handler
   */


  InvoicingService.searchInvoices = function searchInvoices(params, completionHandler) {
    (0, _Requester.request)({
      method: 'POST',
      op: 'search',
      body: JSON.stringify(params)
    }, function (error, response) {
      if (error) {
        completionHandler(error);
      } else {
        var r = _InvoiceListResponse2.default.fromJSON(response.body);
        r.hasMore = params.startIndex + params.pageSize < r.totalCount;
        completionHandler(error, r);
      }
    });
  };

  /**
   * @param {InvoicingService~getNextInvoiceNumber} completionHandler The completion handler
   */


  InvoicingService.getNextInvoiceNumber = function getNextInvoiceNumber(completionHandler) {
    (0, _Requester.request)({
      method: 'POST',
      op: 'invoices/next-invoice-number'
    }, function (error, response) {
      if (error) {
        completionHandler(error);
      } else {
        var nextInvNum = response.body.number;
        completionHandler(error, nextInvNum);
      }
    });
  };

  /**
   * @param {InvoicingService~getAccountSummary} completionHandler The completion handler
   */


  InvoicingService.getAccountSummary = function getAccountSummary(completionHandler) {
    var _this2 = this;

    // TODO: Should we expose something closer to the actual API? Right now we're returning data
    // specifically for the PPB app.

    var firstError = void 0;
    var secondError = void 0;
    var firstResponse = void 0;
    var secondResponse = void 0;

    var maybeContinue = function maybeContinue() {
      if ((firstError || firstResponse) && (secondError || secondResponse)) {
        _this2.continueGetAccountSummary(firstError, firstResponse, secondError, secondResponse, completionHandler);
      }
    };

    (0, _Requester.request)({
      method: 'GET',
      op: 'summaries?overdue=false'
    }, function (error, response) {
      firstError = error;
      firstResponse = response;
      maybeContinue();
    });

    (0, _Requester.request)({
      method: 'GET',
      op: 'summaries?overdue=true'
    }, function (error, response) {
      secondError = error;
      secondResponse = response;
      maybeContinue();
    });
  };

  InvoicingService.continueGetAccountSummary = function continueGetAccountSummary(firstError, firstResponse, secondError, secondResponse, completionHandler) {
    var error = firstError || secondError;
    if (error) {
      completionHandler(error);
    }
    completionHandler(error, new _AccountSummary2.default(firstResponse.body, secondResponse.body));
  };

  /**
   * @param {InvoicingService~getTemplates} completionHandler The completion handler
   */


  InvoicingService.getTemplates = function getTemplates(completionHandler) {
    (0, _Requester.request)({
      method: 'GET',
      op: 'templates'
    }, function (error, response) {
      if (error) {
        completionHandler(error);
      } else {
        completionHandler(error, _InvoiceTemplatesResponse2.default.fromJSON(response.body));
      }
    });
  };

  return InvoicingService;
}(_BaseService3.default);

/**
 * @callback InvoicingService~getInvoices
 * @param {PayPalError} error The error that occurred, if any
 * @param {InvoiceListResponse} response The server response
 */

/**
 * @callback InvoicingService~searchInvoices
 * @param {PayPalError} error The error that occurred, if any
 * @param {InvoiceListResponse} response The server response
 */

/**
 * @callback InvoicingService~getAccountSummary
 * @param {PayPalError} error The error that occurred, if any
 * @param {AccountSummary} response The server response
 */

/**
 * @callback InvoicingService~getTemplates
 * @param {PayPalError} error The error that occurred, if any
 * @param {InvoiceTemplatesResponse} response The server response
 */

/**
 * @callback InvoicingService~getNextInvoiceNumber
 * @param {PayPalError} error The error that occurred, if any
 * @param {string} response The server response
 */


exports.default = InvoicingService;
},{"./AccountSummary":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/AccountSummary.js","./BaseClasses/BaseService":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/BaseClasses/BaseService.js","./InvoiceListResponse":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/InvoiceListResponse.js","./InvoiceTemplatesResponse":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/InvoiceTemplatesResponse.js","./Requester":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/Requester.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/InvoicingUtil.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

var _moment = require('moment');

var _moment2 = _interopRequireDefault(_moment);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

var InvoicingUtils = function () {
  function InvoicingUtils() {
    _classCallCheck(this, InvoicingUtils);
  }

  InvoicingUtils.parseServerDateString = function parseServerDateString(date) {
    if (!date) {
      return date;
    }
    // Sometimes the date string doesn't have a time. In that case, the first replace will add one.
    var _date = date.replace(/(\d{4}-\d{2}-\d{2}) (PST|PDT)/, '$1 23:59:59 $2');
    _date = _date.replace('PST', '-0800').replace('PDT', '-0700');
    return _moment2.default.parseZone(_date, 'YYYY-MM-DD hh:mm:ss Z');
  };

  InvoicingUtils.toServerDateString = function toServerDateString(date, shouldIncludeTime) {
    if (!date) {
      return date;
    }
    var _date = (0, _moment2.default)(date);
    // It's important that we render dates into PDT instead of PST.
    // If we receive a date in PDT and then render it into PST, we'll assume the incoming date is at
    // time 00:00:00, which then ends up being in the previous day PST. Going from PST->PDT, the
    // offset goes the other way, so the day remains the same.
    //
    // Also, some invoicing fields won't accept the hh:mm:ss timestamp,
    // but it's required for others.  So, we are required to make you specify whether
    // you want the time or not.
    //
    // All of this could have been avoided by choosing a non-ridiculous date format, but ¯\_(ツ)_/¯.

    if (shouldIncludeTime) {
      _date.utcOffset(-480);
      return _date.format('YYYY-MM-DD HH:mm:ss') + ' PST';
    }

    // This is a working solution for converting date into PST formats
    // The time stamp applied is PST/PDT EOD. This will set the correct date when parsed from server
    // See function parseServerDateString.
    var offset = _date.utcOffset();
    if (offset > -480) {
      _date.subtract(1, 'days');
    }
    return _date.format('YYYY-MM-DD') + ' PST';
  };

  InvoicingUtils.getDateValue = function getDateValue(date) {
    return date && date.constructor === (0, _moment2.default)().constructor ? date.toDate() : date;
  };

  return InvoicingUtils;
}();

exports.default = InvoicingUtils;
},{"moment":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/moment/moment.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/Item.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

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; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

var _InvoiceBigNumber = require('./InvoiceBigNumber');

var _events = require('events');

var _Currency = require('./Currency');

var _Currency2 = _interopRequireDefault(_Currency);

var _manticoreUtil = require('manticore-util');

var _InvoicingUtil = require('./InvoicingUtil');

var _InvoicingUtil2 = _interopRequireDefault(_InvoicingUtil);

var _deepEqual = require('deep-equal');

var _deepEqual2 = _interopRequireDefault(_deepEqual);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (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 } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var staticIdAllocator = 1;
var ZERO = (0, _InvoiceBigNumber.$$)(0);

// TODO refactor tax rates into a real object?

/**
 * A line item on an invoice. Can be positive, negative, or zero total/unit price.
 * See https://cms.paypal.com/cms_content/US/en_US/files/developer/PP_InvoicingAPIGuide.pdf
 * for details on field length restrictions and formats.
 * @class
 * @property {string} name The name of this item
 * @property {string} itemDescription A description for this line item
 * @property {decimal} quantity The quantity of this item - up to three decimals
 * @property {decimal} unitPrice The price of 1 unit of this item
 * @property {int} itemId A unique identifier for this item - not currently saved to the
 *  server but used for local uniqueness such that one line item per itemId.detailId pair
 *  will be stored on an invoice @readonly
 * @property {string} detailId A secondary unique identifier (e.g. for item options
 *  or sizes, or to create multiple items on the same invoice with a single detailId) @readonly
 * @property {string} taxName The name for the tax rate applied to this item, if any
 * @property {decimal} taxRate The tax rate to be applied to this item. If non-zero,
 *  the taxName must also be set.
 * @property {decimal} discountPercentage A percentage discount for this line item
 * @property {decimal} discountAmount A flat amount discount for this line item
 * @property {Date} date Date on which the item or service was provided
 * @property {string} imageURL Image url of the item. 4000 characters max.
 * @property {string} unitOfMeasure Unit of measure of the item being invoiced.
 *
 */

var InvoiceItem = function (_EventEmitter) {
  _inherits(InvoiceItem, _EventEmitter);

  /**
   * Create a new invoice item with the required information (detailId is optional).
   * @constructor
   * @private
   * @param {string} name The name of the item
   * @param {decimal} quantity The quantity of this item - up to three decimals
   * @param {decimal} unitPrice The price of 1 unit of this item
   * @param {string} itemId A unique identifier for this item - not currently saved
   *  to the server but used for local
   * uniqeuness such that one line item per itemId.detailId pair will be stored on an invoice
   * @param {string} detailId A secondary unique identifier (e.g. for item options
   *  or sizes, or to create multiple items on the same invoice with a single detailId)
   */

  function InvoiceItem(name, quantity, unitPrice, itemId, detailId) {
    _classCallCheck(this, InvoiceItem);

    var _this = _possibleConstructorReturn(this, _EventEmitter.call(this));

    _this.name = name;
    if (!quantity || !name || !unitPrice) {
      throw new Error('You must specify a quantity, name and unitPrice when adding an item.');
    }
    // The server can return item quantities with over 15 digits, in which case bignumber errors.
    // We don't really care about the 16th digit, so convert to a string so
    // bignumber doesn't complain.
    _this._quantity = (0, _InvoiceBigNumber.$$)(String(quantity));
    _this.unitPrice = (0, _InvoiceBigNumber.$$)(unitPrice || 0);
    _this.itemId = itemId || staticIdAllocator++;
    _this.detailId = detailId || null;
    return _this;
  }

  /**
   * Create a true copy of an item.
   * @returns {InvoiceItem} the copy of the item
   */


  InvoiceItem.prototype.copy = function copy() {
    var i = InvoiceItem.fromJson((0, _manticoreUtil.deepToJSON)(this.toJSON()));
    return i;
  };

  /**
   * Do simple math without discounts for this line item
   * @private
   */


  InvoiceItem.prototype.subtotalForInvoice = function subtotalForInvoice(invoice) {
    var itemPrice = this.quantity.times(this.unitPrice || ZERO);
    return _Currency2.default.round(invoice.currency, itemPrice);
  };

  /**
   * Do the simple math for this line item
   * @private
   */


  InvoiceItem.prototype.totalForInvoice = function totalForInvoice(invoice) {
    var itemPrice = this.subtotalForInvoice(invoice);
    if (this.discountPercentage) {
      var discount = _Currency2.default.round(invoice.currency, itemPrice.times(this.discountPercentage / 100));
      itemPrice = itemPrice.minus(discount);
    } else if (this.discountAmount) {
      itemPrice = itemPrice.minus(this.discountAmount);
    }
    return _Currency2.default.round(invoice.currency, itemPrice);
  };

  /**
   * Read the properties of this object from json, transforming to numbers where appropriate
   * @param json
   * @private
   */

  InvoiceItem.fromJson = function fromJson(json) {
    /* jshint maxcomplexity: false */
    var item = new InvoiceItem(json.name, json.quantity, json.unit_price.value, json.itemId || staticIdAllocator++, json.detailId);
    if (json.description) {
      item.itemDescription = json.description;
    }
    if (json.unit_price) {
      item.unitPrice = json.unit_price.value;
    }
    if (json.tax) {
      item.taxName = json.tax.name;
      item.taxRate = (0, _InvoiceBigNumber.$$)(json.tax.percent);
    }
    if (json.discount) {
      if (json.discount.amount) {
        item.discountAmount = (0, _InvoiceBigNumber.$$)(json.discount.amount.value);
      }
      if (json.discount.percent) {
        item.discountPercentage = (0, _InvoiceBigNumber.$$)(json.discount.percent);
      }
    }
    if (json.date) {
      item.date = _InvoicingUtil2.default.parseServerDateString(json.date);
    }

    item.imageURL = json.image_url;
    item.unitOfMeasure = json.unit_of_measure;

    return item;
  };

  InvoiceItem.prototype.toJSON = function toJSON(currency) {
    var json = {
      name: this.name,
      description: this.itemDescription,
      quantity: this.quantity.toNumber(),
      image_url: this.imageURL,
      unit_of_measure: this.unitOfMeasure
    };
    if (this.date) {
      json.date = _InvoicingUtil2.default.toServerDateString(this.date, false);
    }
    json.unit_price = {
      value: this.unitPrice,
      currency: currency
    };
    var tempDiscount = {};
    if (this.discountPercentage > 0) {
      tempDiscount.percent = this.discountPercentage;
    } else if (this.discountAmount > 0) {
      tempDiscount.amount = {
        value: this.discountAmount,
        currency: currency
      };
    }
    if (tempDiscount.amount || tempDiscount.percent) {
      json.discount = tempDiscount;
    }

    if (this.taxRate && this.taxName) {
      json.tax = {
        percent: this.taxRate,
        name: this.taxName
      };
    }
    return json;
  };

  /**
   * check if an item is equal to this
   * @param {InvoiceItem} item to which this one will be compared
   * @returns {bool} are they equal
   */


  InvoiceItem.prototype.isEqualToItem = function isEqualToItem(item) {
    return (0, _deepEqual2.default)((0, _manticoreUtil.deepToJSON)(this), (0, _manticoreUtil.deepToJSON)(item));
  };

  _createClass(InvoiceItem, [{
    key: 'quantity',
    get: function get() {
      return this._quantity;
    },
    set: function set(v) {
      this._quantity = (0, _InvoiceBigNumber.$$)(v);
      this.emit('amountChanged', 'quantity');
    }
  }, {
    key: 'taxRate',
    get: function get() {
      return this._taxRate;
    },
    set: function set(v) {
      this._taxRate = (0, _InvoiceBigNumber.$$)(v);
      this.emit('taxRateChanged');
      this.emit('changed');
    }
  }, {
    key: 'discountAmount',
    get: function get() {
      return this._discountAmount;
    },
    set: function set(v) {
      this._discountAmount = (0, _InvoiceBigNumber.$$)(v);
      this.emit('discountAmountChanged');
      this.emit('changed');
    }
  }, {
    key: 'discountPercentage',
    get: function get() {
      return this._discountPercentage;
    },
    set: function set(v) {
      this._discountPercentage = (0, _InvoiceBigNumber.$$)(v);
      this.emit('discountPercentageChanged');
      this.emit('changed');
    }
  }, {
    key: 'unitPrice',
    get: function get() {
      return this._unitPrice;
    },
    set: function set(v) {
      this._unitPrice = (0, _InvoiceBigNumber.$$)(v);
      this.emit('amountChanged', 'unitPrice');
    }
  }, {
    key: 'date',
    set: function set(date) {
      this._date = date;
    },
    get: function get() {
      return _InvoicingUtil2.default.getDateValue(this._date);
    }
  }]);

  return InvoiceItem;
}(_events.EventEmitter);

/**
 * The amount represented by this line item has changed.
 *
 * @event InvoiceItem#amountChanged
 * @param {string} field The field that has changed.
 */


exports.default = InvoiceItem;
},{"./Currency":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/Currency.js","./InvoiceBigNumber":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/InvoiceBigNumber.js","./InvoicingUtil":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/InvoicingUtil.js","deep-equal":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/deep-equal/index.js","events":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/events/events.js","manticore-util":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-util/build/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/MerchantInfo.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

var _Address = require('./Address');

var _Address2 = _interopRequireDefault(_Address);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

/**
 * Container for information about the merchant requesting payment on an invoice
 * @class
 * @property {string} email The email address of the
 *  merchant @required @length(1,260) @format(email)
 * @property {string} firstName The first name of the merchant @length(,30)
 * @property {string} lastName The last name of the merchant @length(,30)
 * @property {InvoiceAddress} address The address of the merchant
 * @property {string} businessName The business name of the merchant
 * @property {string} phone The phone number of the merchant
 * @property {string} fax The fax number of the merchant
 * @property {string} website The URL of the merchant website @format{url}
 * @property {string} taxId The tax identifier for the merchant
 * @property {string} additionalInfoLabel Option to provide a label to the
 *  additional_info field. 40 characters max.
 * @property {string} additionalInfo Option to display additional information
 *  such as business hours. 40 characters max.
 */

var InvoiceMerchantInfo = function () {
  function InvoiceMerchantInfo() {
    _classCallCheck(this, InvoiceMerchantInfo);

    this.address = new _Address2.default();
  }

  InvoiceMerchantInfo.prototype.readFromJson = function readFromJson(json) {
    if (json) {
      this.address.readFromJson(json.address);

      if (json.address) {
        this.address = new _Address2.default();
        this.address.readFromJson(json.address);
      }
      this.email = json.email;
      this.phone = json.phone;
      this.fax = json.fax;
      this.website = json.website;
      this.firstName = json.first_name;
      this.lastName = json.last_name;
      this.businessName = json.business_name;
      this.taxId = json.tax_id;
      this.additionalInfo = json.additional_info;
      this.additionalInfoLabel = json.additional_info_label;
    }
  };

  InvoiceMerchantInfo.prototype.toJSON = function toJSON() {
    var r = {};
    r.email = this.email;
    r.phone = this.phone;
    r.fax = this.fax;
    r.website = this.website;
    r.address = this.address;
    r.first_name = this.firstName;
    r.last_name = this.lastName;
    r.business_name = this.businessName;
    r.tax_id = this.taxId;
    r.additional_info = this.additionalInfo;
    r.additional_info_label = this.additionalInfoLabel;
    return r;
  };

  return InvoiceMerchantInfo;
}();

exports.default = InvoiceMerchantInfo;
},{"./Address":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/Address.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/Notification.js":[function(require,module,exports){
"use strict";

exports.__esModule = true;

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

/**
 * An Invoice notification
 * @class
 * @property {string} subject Subject of the notification
 * @property {string} note Note to the payer
 * @property {bool} shouldSendToMerchant A flag indicating whether a copy of the
 *  email has to be sent to the merchant
 * @property {bool} shouldSendToPayer A flag indicating whether a copy of the email
 *  has to be sent to the payer
 * @property {string} ccEmails If the invoice has CCs associated with it, this field
 *  can be used to specify only certain set of CC emails for which notification is sent.
 *
 */

var InvoiceNotification = function () {
  function InvoiceNotification(subject, note, shouldSendToMerchant, ccEmails, shouldSendToPayer) {
    _classCallCheck(this, InvoiceNotification);

    this.subject = subject;
    this.note = note;
    this.shouldSendToMerchant = shouldSendToMerchant;
    this.shouldSendToPayer = shouldSendToPayer;
    this.ccEmails = ccEmails;
  }

  InvoiceNotification.prototype.toJSON = function toJSON() {
    var json = {};
    json.subject = this.subject;
    json.note = this.note;
    json.send_to_merchant = this.shouldSendToMerchant;
    json.send_to_payer = this.shouldSendToPayer;
    json.cc_emails = this.ccEmails;
    return json;
  };

  return InvoiceNotification;
}();

exports.default = InvoiceNotification;
},{}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/Payment.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

var _assert = require('assert');

var _assert2 = _interopRequireDefault(_assert);

var _InvoiceEnums = require('./InvoiceEnums');

var _InvoiceEnums2 = _interopRequireDefault(_InvoiceEnums);

var _InvoicingUtil = require('./InvoicingUtil');

var _InvoicingUtil2 = _interopRequireDefault(_InvoicingUtil);

var _InvoiceBigNumber = require('./InvoiceBigNumber');

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

/**
 * Container for information about the payment on an invoice
 * @class
 * @property {Invoice.PaymentType} type PayPal payment detail indicating whether
 *  payment was made in an invoicing flow via PayPal or externally. @readonly
 * @property {string} transactionID PayPal payment transaction id. Mandatory
 *  field in case the type value is PAYPAL. @readonly
 * @property {string} transactionType type of the transaction @readonly
 * @property {Date} date date when the invoice was paid
 * @property {Invoice.PaymentMethod} method payment mode or method this is mandatory
 * @property {string} note optional note associated with the payment
 * @property {decimal} amount this is an amount object on the server which
 *  has a string for currency, and value
 * @property {string} currency used with the amount
 **/

var InvoicePayment = function () {
  function InvoicePayment() {
    _classCallCheck(this, InvoicePayment);

    this.type = _InvoiceEnums2.default.PaymentType.EXTERNAL;
    this.transactionId = undefined;
    this.transactionType = undefined;
    this.date = undefined;
    this.note = undefined;
    this.method = undefined;
    this.currency = undefined;
    this.amount = undefined;
  }

  InvoicePayment.readFromJson = function readFromJson(json) {
    var payment = new InvoicePayment();

    if (json) {
      payment.type = json.type;
      payment.transactionID = json.transaction_id;
      payment.transactionType = json.transaction_type;
      payment.date = _InvoicingUtil2.default.parseServerDateString(json.date);
      payment.method = json.method;
      payment.note = json.note;
    }

    if (json.amount) {
      payment.amount = (0, _InvoiceBigNumber.$$)(json.amount.value);
      payment.currency = json.amount.currency;
    }

    return payment;
  };

  InvoicePayment.prototype.toJSON = function toJSON() {
    var r = {};

    if (this.amount) {
      r.amount = {};
      r.amount = {
        currency: this.currency,
        value: this.amount
      };
    }

    r.method = _InvoiceEnums2.default.PaymentMethod.toString[this.method];
    r.date = _InvoicingUtil2.default.toServerDateString(this.date, true);
    r.note = this.note;

    return r;
  };

  // Assert if we know the server is going to reject this as the body of record-payment.


  InvoicePayment.prototype.validate = function validate() {
    if (!this.type) {
      (0, _assert2.default)(false, 'InvoicePaymentInfo must have a payment type.');
    }
    switch (this.type) {
      case _InvoiceEnums2.default.PaymentType.EXTERNAL:
        (0, _assert2.default)(this.method, 'InvoicePaymentInfo with payment type=EXTERNAL must have a method.');
        break;
      case _InvoiceEnums2.default.PaymentType.PAYPAL:
        (0, _assert2.default)(this.transactionId, 'InvoicePaymentInfo with payment type=PAYPAL must have a method.');
        throw new Error('The invoicing service doesn\'t currently support setting the payment type to PAYPAL :(.');
      default:
        throw new Error('Unknown payment type');
    }
  };

  return InvoicePayment;
}();

exports.default = InvoicePayment;
},{"./InvoiceBigNumber":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/InvoiceBigNumber.js","./InvoiceEnums":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/InvoiceEnums.js","./InvoicingUtil":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/InvoicingUtil.js","assert":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/assert/assert.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/PaymentTerm.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

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; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

var _manticoreUtil = require('manticore-util');

var _InvoicingUtil = require('./InvoicingUtil');

var _InvoicingUtil2 = _interopRequireDefault(_InvoicingUtil);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

/**
 * Contains information about the due date / payment terms of an invoice.
 * @class
 * @property {InvoicePaymentTerm.PaymentTerms} paymentTerms Describes when
 *  payment is expected on the invoice. Setting this to something truthy will clear dueDate.
 * @property {Date} dueDate A specific date on which payment is due. Setting this
 *  to something truthy will clear paymentTerms.
 **/

var InvoicePaymentTerm = function () {
  function InvoicePaymentTerm() {
    _classCallCheck(this, InvoicePaymentTerm);

    this.reset();
  }

  InvoicePaymentTerm.prototype.reset = function reset() {
    this._paymentTerms = InvoicePaymentTerm.PaymentTerms.NoPaymentTerms;
    this._dueDate = undefined;
  };

  InvoicePaymentTerm.fromJson = function fromJson(json) {
    var r = new InvoicePaymentTerm();
    if (json) {
      // Sometimes the server will send us a term_type AND a due_date. In this case, the due
      // date is just bogus, so setting the paymentTerms here will override it.
      r.dueDate = _InvoicingUtil2.default.parseServerDateString(json.due_date);
      r.paymentTerms = InvoicePaymentTerm.PaymentTerms.fromServer[json.term_type];
    } else {
      r.reset();
    }
    return r;
  };

  InvoicePaymentTerm.prototype.toJSON = function toJSON() {
    var r = {};

    if (this.dueDate) {
      r.due_date = _InvoicingUtil2.default.toServerDateString(this.dueDate, false);
    } else if (this.paymentTerms) {
      r.term_type = InvoicePaymentTerm.PaymentTerms.toServer[this.paymentTerms];
    }

    return r;
  };

  // There is a bug on the server where an invoice with the same invoice_date and due_date
  // will fail to validate. So, if those dates would be the same, use DUE_ON_RECEIPT instead.
  // TODO: stop this once the server is fixed.


  InvoicePaymentTerm.prototype.toJSONHack = function toJSONHack(invoiceDateString) {
    var r = this.toJSON();

    if (r.due_date === invoiceDateString) {
      r.due_date = undefined;
      var dor = InvoicePaymentTerm.PaymentTerms.DueOnReceipt;
      r.term_type = InvoicePaymentTerm.PaymentTerms.toServer[dor];
    }

    return r;
  };

  _createClass(InvoicePaymentTerm, [{
    key: 'paymentTerms',
    set: function set(t) {
      if (t) {
        this.reset();
      }
      this._paymentTerms = t;
    },
    get: function get() {
      return this._paymentTerms;
    }
  }, {
    key: 'dueDate',
    set: function set(d) {
      if (d) {
        this.reset();
      }
      this._dueDate = d;
    },
    get: function get() {
      return _InvoicingUtil2.default.getDateValue(this._dueDate);
    }
  }]);

  return InvoicePaymentTerm;
}();

/**
 * A payment term describes when payment is expected in relation to the date it is sent
 * @enum {int}
 */


exports.default = InvoicePaymentTerm;
InvoicePaymentTerm.PaymentTerms = {
  /**
   * The due date does not come from payment terms
   */
  NoPaymentTerms: 0,
  /**
   * The invoice is due immediately upon receipt of the invoice
   */
  DueOnReceipt: 1,
  /**
   * The payment is due 10 days after receipt of the invoice
   */
  Net10: 2,
  /**
   * The payment is due 15 days after receipt of the invoice
   */
  Net15: 3,
  /**
   * The payment is due 30 days after receipt of the invoice
   */
  Net30: 4,
  /**
   * The payment is due 45 days after receipt of the invoice
   */
  Net45: 5,
  /**
   * The payment is due 60 days after receipt of the invoice
   */
  Net60: 6,
  /**
   * The payment is due 90 days after receipt of the invoice
   */
  Net90: 7
};

InvoicePaymentTerm.PaymentTerms.fromServer = {
  DUE_ON_RECEIPT: InvoicePaymentTerm.PaymentTerms.DueOnReceipt,
  NET_10: InvoicePaymentTerm.PaymentTerms.Net10,
  NET_15: InvoicePaymentTerm.PaymentTerms.Net15,
  NET_30: InvoicePaymentTerm.PaymentTerms.Net30,
  NET_45: InvoicePaymentTerm.PaymentTerms.Net45,
  NET_60: InvoicePaymentTerm.PaymentTerms.Net60,
  NET_90: InvoicePaymentTerm.PaymentTerms.Net90
};

InvoicePaymentTerm.PaymentTerms.toServer = (0, _manticoreUtil.reverseKeysAndValues)(InvoicePaymentTerm.PaymentTerms.fromServer);
},{"./InvoicingUtil":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/InvoicingUtil.js","manticore-util":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-util/build/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/Refund.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

var _InvoiceBigNumber = require('./InvoiceBigNumber');

var _InvoiceEnums = require('./InvoiceEnums');

var _InvoiceEnums2 = _interopRequireDefault(_InvoiceEnums);

var _InvoicingUtil = require('./InvoicingUtil');

var _InvoicingUtil2 = _interopRequireDefault(_InvoicingUtil);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

/**
 * Container for information about a refund on an invoice
 * @class
 * @property {string} type PayPal refund type indicating whether refund was
 *  done in invoicing flow via PayPal or externally. @readonly
 * @property {Date} date date when the invoice was paid
 * @property {string} note optional note associated with the payment
 * @property {decimal} amount this is an amount object on the server which
 *  has a string for currency, and value
 * @property {string} currency used with the amount
 **/

var InvoiceRefund = function () {
  function InvoiceRefund() {
    _classCallCheck(this, InvoiceRefund);

    // Default payment type to EXTERNAL since it's the only one the server actually
    // supports right now.
    this.type = _InvoiceEnums2.default.PaymentType.EXTERNAL;
    this.date = undefined;
    this.note = undefined;
    this.currency = undefined;
    this.amount = undefined;
  }

  InvoiceRefund.readFromJson = function readFromJson(json) {
    var refund = new InvoiceRefund();

    if (json) {
      refund.type = json.type;
      refund.date = _InvoicingUtil2.default.parseServerDateString(json.date);
      refund.note = json.note;
    }
    if (json.amount) {
      refund.amount = (0, _InvoiceBigNumber.$$)(json.amount.value);
      refund.currency = json.amount.currency;
    }

    return refund;
  };

  InvoiceRefund.prototype.toJSON = function toJSON() {
    var r = {};
    if (this.amount) {
      r.amount = {};
      r.amount = {
        currency: this.currency,
        value: this.amount
      };
    }

    r.date = _InvoicingUtil2.default.toServerDateString(this.date, true);
    r.note = this.note;

    return r;
  };

  return InvoiceRefund;
}();

exports.default = InvoiceRefund;
},{"./InvoiceBigNumber":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/InvoiceBigNumber.js","./InvoiceEnums":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/InvoiceEnums.js","./InvoicingUtil":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/InvoicingUtil.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/Requester.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;
exports.request = request;

var _manticoreUtil = require('manticore-util');

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } // The main purpose of this file is to avoid a circular dependency between
// Invoice and InvoicingService, since Invoice needs to make requests and
// the service needs to construct Invoices based on server responses.


var InvoicingRequester = function () {
  function InvoicingRequester() {
    _classCallCheck(this, InvoicingRequester);
  }

  InvoicingRequester.request = function request(opts, cb) {
    if (!InvoicingRequester.api) {
      throw new Error('There is no service interface. Please set the InvoicingRequester.api property.');
    }

    InvoicingRequester.api.request((0, _manticoreUtil.extend)(opts, {
      service: 'invoicing',
      format: 'json',
      headers: { 'Content-Type': 'application/json' }
    }), function (error, response) {
      InvoicingRequester.decorateError(error);

      cb(error, response);
    });
  };

  InvoicingRequester.decorateError = function decorateError(error) {
    if (!error) {
      return;
    }

    var betterMessage = '';
    var firstFieldRegEx = /(.*?)\..*/;
    var lastFieldRegEx = /.*\.(.*)/;

    if (error.details && Array.isArray(error.details) && error.details.length > 0) {
      error.details.forEach(function (obj) {
        if (betterMessage.length) {
          betterMessage += ' ';
        }

        var firstMatches = obj.field.match(firstFieldRegEx);
        var cleanField = obj.field;

        if (Array.isArray(firstMatches) && firstMatches.length) {
          cleanField = firstMatches[1];
          // Get rid of "[0]" if it's there.
          cleanField = cleanField.replace(/(.*?)\[.*/, '$1');

          cleanField = cleanField.replace('_', ' ');

          // Capitalize first letter
          cleanField = cleanField.charAt(0).toUpperCase() + cleanField.slice(1);

          var lastMatches = obj.field.match(lastFieldRegEx);
          if (Array.isArray(lastMatches) && lastMatches.length) {
            cleanField = cleanField + ' ' + lastMatches[1];
          }
        } else {
          // Capitalize first letter
          cleanField = cleanField.charAt(0).toUpperCase() + cleanField.slice(1);
        }

        betterMessage = '' + betterMessage + cleanField + ' ' + obj.issue;
      });
    }

    // If there are details, overwrite the message.
    if (betterMessage.length) {
      error.message = betterMessage;
    }
  };

  return InvoicingRequester;
}();

exports.default = InvoicingRequester;
function request(opts, cb) {
  return InvoicingRequester.request(opts, cb);
}
},{"manticore-util":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-util/build/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/SearchRequest.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

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; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

var _InvoiceEnums = require('./InvoiceEnums');

var _InvoiceEnums2 = _interopRequireDefault(_InvoiceEnums);

var _InvoicingUtil = require('./InvoicingUtil');

var _InvoicingUtil2 = _interopRequireDefault(_InvoicingUtil);

var _InvoiceBigNumber = require('./InvoiceBigNumber');

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

/**
 * @class
 * @property {string} email Initial letters of the email address.
 * @property {string} recipientFirstName Initial letters of the recipient's first name.
 * @property {string} recipientLastName Initial letters of the recipient's last name.
 * @property {string} recipientBusinessName Initial letters of the recipient's business name.
 * @property {string} number The invoice number that appears on the invoice.
 * @property {decimal} lowerTotalAmount Base object for all financial value
 *  related fields (balance, payment due, etc.)
 * @property {decimal} upperTotalAmount Base object for all financial value
 *  related fields (balance, payment due, etc.)
 * @property {Date} startInvoiceDate Start invoice date.
 *  Date format yyyy-MM-dd z, as defined in ISO8601.
 * @property {Date} endInvoiceDate End invoice date.
 *  Date format yyyy-MM-dd z, as defined in ISO8601.
 * @property {Date} startDueDate Start invoice due date.
 *  Date format yyyy-MM-dd z, as defined in ISO8601.
 * @property {Date} endDueDate End invoice due date.
 *  Date format yyyy-MM-dd z, as defined in ISO8601.
 * @property {Date} startPaymentDate Start invoice payment date.
 *  Date format yyyy-MM-dd z, as defined in ISO8601.
 * @property {Date} endPaymentDate End invoice payment date.
 *  Date format yyyy-MM-dd z, as defined in ISO8601.
 * @property {Date} startCreationDate Start invoice creation date.
 *  Date format yyyy-MM-dd z, as defined in ISO8601.
 * @property {Date} endCreationDate End invoice creation date.
 *  Date format yyyy-MM-dd z, as defined in ISO8601.
 * @property {int} startIndex A zero-relative index of the merchant's list of invoices
 * @property {int} pageSize Page size of the search results.
 * @property {bool} totalCountRequired A flag indicating whether total
 *  count is required in the response.
 * @property {bool} archived A flag indicating whether search is on invoices archived by
 *  merchant. true - returns archived / false returns unarchived / null returns all.
 */

var InvoiceSearchRequest = function () {
  function InvoiceSearchRequest() {
    _classCallCheck(this, InvoiceSearchRequest);

    this.startIndex = 0;
    this.pageSize = 20;
    this.totalCountRequired = false;
    this._statuses = [];
  }

  InvoiceSearchRequest.prototype.toJSON = function toJSON() {
    var json = {};
    this.assignDatesToJSON(json);

    json.email = this.email;
    json.recipientFirstName = this.recipientFirstName;
    json.recipientLastName = this.recipientLastName;
    json.recipientBusinessName = this.recipientBusinessName;
    json.number = this.number;
    for (var _iterator = this._statuses, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
      var _ref;

      if (_isArray) {
        if (_i >= _iterator.length) break;
        _ref = _iterator[_i++];
      } else {
        _i = _iterator.next();
        if (_i.done) break;
        _ref = _i.value;
      }

      var status = _ref;

      if (!json.status) {
        json.status = [];
      }
      json.status.push(_InvoiceEnums2.default.Status.toString[status]);
    }
    json.lower_total_amount = this.lowerTotalAmount;
    json.upper_total_amount = this.upperTotalAmount;
    json.page = this.startIndex;
    json.page_size = this.pageSize;
    json.total_count_required = this.totalCountRequired;
    json.archived = this.archived;
    return json;
  };

  /**
   * Manticore doesn't support properties that are arrays of enum values, and it's complicated.
   * So instead of a property for the status array, we have this method.
   * @param {Invoice.Status} status
   */


  InvoiceSearchRequest.prototype.addStatus = function addStatus(status) {
    this._statuses.push(status);
  };

  // If you send a startXDate, the server requires you to send an endXDate.
  // The server also only accepts certain time ranges (e.g. after 1970), so
  // this method automatically sets the most-lenient available date if you're
  // missing one of a pair.


  InvoiceSearchRequest.prototype.assignDatesToJSON = function assignDatesToJSON(json) {
    var datePairs = [['startInvoiceDate', 'endInvoiceDate', 'start_invoice_date', 'end_invoice_date'], ['startDueDate', 'endDueDate', 'start_due_date', 'end_due_date'], ['startPaymentDate', 'endPaymentDate', 'start_payment_date', 'end_payment_date'], ['startCreationDate', 'endCreationDate', 'start_creation_date', 'end_creation_date']];
    for (var _iterator2 = datePairs, _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) {
      var _ref2;

      if (_isArray2) {
        if (_i2 >= _iterator2.length) break;
        _ref2 = _iterator2[_i2++];
      } else {
        _i2 = _iterator2.next();
        if (_i2.done) break;
        _ref2 = _i2.value;
      }

      var p = _ref2;

      if (this[p[0]] || this[p[1]]) {
        json[p[2]] = this[p[0]] ? _InvoicingUtil2.default.toServerDateString(this[p[0]], false) : '1970-01-01 PST';
        json[p[3]] = this[p[1]] ? _InvoicingUtil2.default.toServerDateString(this[p[1]], false) : '2100-01-01 PST';
      }
    }
  };

  _createClass(InvoiceSearchRequest, [{
    key: 'lowerTotalAmount',
    get: function get() {
      return this._lowerTotalAmount;
    },
    set: function set(val) {
      this._lowerTotalAmount = (0, _InvoiceBigNumber.$$)(val);
    }
  }, {
    key: 'upperTotalAmount',
    get: function get() {
      return this._upperTotalAmount;
    },
    set: function set(val) {
      this._upperTotalAmount = (0, _InvoiceBigNumber.$$)(val);
    }
  }]);

  return InvoiceSearchRequest;
}();

exports.default = InvoiceSearchRequest;
},{"./InvoiceBigNumber":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/InvoiceBigNumber.js","./InvoiceEnums":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/InvoiceEnums.js","./InvoicingUtil":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/InvoicingUtil.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/ShippingInfo.js":[function(require,module,exports){
'use strict';

var _Address = require('./Address');

var _Address2 = _interopRequireDefault(_Address);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

/**
 * Container for information about the merchant requesting payment on an invoice
 * @class
 * @property {string} email The email address of the
 *  merchant @required @length(1,260) @format(email)
 * @property {string} firstName The first name of the merchant @length(,30)
 * @property {string} lastName The last name of the merchant @length(,30)
 * @property {InvoiceAddress} address The address of the merchant
 * @property {string} businessName The business name of the merchant
 */

var InvoiceShippingInfo = function () {
  function InvoiceShippingInfo() {
    _classCallCheck(this, InvoiceShippingInfo);

    this.address = new _Address2.default();
  }

  InvoiceShippingInfo.prototype.readFromJson = function readFromJson(json) {
    if (json) {
      this.address.readFromJson(json.address);
      this.firstName = json.first_name;
      this.lastName = json.last_name;
      this.businessName = json.business_name;
    }
  };

  InvoiceShippingInfo.prototype.toJSON = function toJSON() {
    var r = {};
    // If the address is empty, don't include it in the JSON.
    if (Object.keys(this.address).length) {
      r.address = this.address;
    }
    r.first_name = this.firstName;
    r.last_name = this.lastName;
    r.business_name = this.businessName;

    return r;
  };

  /**
   * Check to see if this object has any value
   * @returns {bool}
   */


  InvoiceShippingInfo.prototype.hasAnyValue = function hasAnyValue() {
    if (this.email || this.firstName || this.lastName || this.businessName || this.address.hasAnyValue()) {
      return true;
    }
    return false;
  };

  return InvoiceShippingInfo;
}();

module.exports = InvoiceShippingInfo;
},{"./Address":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/Address.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/Template.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

var _Invoice2 = require('./Invoice');

var _Invoice3 = _interopRequireDefault(_Invoice2);

var _TemplateSettings = require('./TemplateSettings');

var _TemplateSettings2 = _interopRequireDefault(_TemplateSettings);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (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 } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

/**
 * Invoice template
 * @class
 * @extends Invoice
 * @property {bool} isDefault true if this is the default template
 * @property {bool} isCustom true if this is a custom template
 * @property {string} name name of the template
 * @property {string} unitOfMeasure unit of measure for the template,
 *  known values: AMOUNT, QUANTITY, HOURS
 * @property {InvoiceTemplateSettings} settings list of which fields are enabled/disabled
 */

var InvoiceTemplate = function (_Invoice) {
  _inherits(InvoiceTemplate, _Invoice);

  /**
   * Create a new blank invoice template.
   * @constructor
   * @param {string} currencyCode currency code identifying the currency for amounts on this invoice
   */

  function InvoiceTemplate(currencyCode) {
    _classCallCheck(this, InvoiceTemplate);

    return _possibleConstructorReturn(this, _Invoice.call(this, currencyCode));
  }

  InvoiceTemplate.fromJSON = function fromJSON(json) {
    if (json.template_data && json.template_data.currencyCode) {
      var t = new InvoiceTemplate(json.template_data.currencyCode);
      t.readJSON(json.template_data, true);
      t.templateID = json.template_id;
      t.isDefault = json.default;
      t.isCustom = json.custom;
      t.name = json.name;
      t.unitOfMeasure = json.unit_of_measure;
      t.settings = _TemplateSettings2.default.fromJSON(json.settings);

      if (!t.isCustom) {
        // the default templates come back with bogus merchant info that we don't want
        // so only tak the merchant info if its a custom/user-made template
        t.merchantInfo = undefined;
      }
      return t;
    }
    return undefined;
  };

  /**
   * Return an invoice with all the fields from the template but the invoice
   * number and paypalID of another invoice
   * @param {Invoice} invoice whose paypalID and number going to be copied
   * @returns {Invoice} the new version of the invoice
   */


  InvoiceTemplate.prototype.invoiceFromInvoice = function invoiceFromInvoice(invoice) {
    var i = this.copy();

    // clear all the template specific fields
    i.isDefault = undefined;
    i.isCustom = undefined;
    i.name = undefined;
    i.unitOfMeasure = undefined;
    i.settings = undefined;

    i.number = invoice.number;
    i.payPalId = invoice.payPalId;
    return i;
  };

  return InvoiceTemplate;
}(_Invoice3.default);

exports.default = InvoiceTemplate;
},{"./Invoice":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/Invoice.js","./TemplateSettings":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/TemplateSettings.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/TemplateSettings.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

var _assert = require('assert');

var _assert2 = _interopRequireDefault(_assert);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

/**
 * Invoice template settings
 * @class
 * @property {bool} shipping true if shipping is displayed
 * @property {bool} discount true if discount is displayed
 * @property {bool} custom true if custom is displayed
 * @property {bool} itemsDiscount true if itemsDiscount is displayed
 * @property {bool} itemsTax true if itemsTax is displayed
 * @property {bool} itemsQuantity true if itemsQuantity is displayed
 * @property {bool} itemsDescription true if itemsDescription is displayed
 * @property {bool} itemsDate true if itemsDate is displayed
 */

var InvoiceTemplateSettings = function () {
  function InvoiceTemplateSettings() {
    _classCallCheck(this, InvoiceTemplateSettings);

    this.shipping = true;
    this.discount = true;
    this.custom = true;
    this.itemsDiscount = true;
    this.itemsTax = true;
    this.itemsQuantity = true;
    this.itemsDescription = true;
    this.itemsDate = true;
  }

  InvoiceTemplateSettings.fromJSON = function fromJSON(json) {
    var s = new InvoiceTemplateSettings();

    for (var _iterator = json, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
      var _ref;

      if (_isArray) {
        if (_i >= _iterator.length) break;
        _ref = _iterator[_i++];
      } else {
        _i = _iterator.next();
        if (_i.done) break;
        _ref = _i.value;
      }

      var f = _ref;

      switch (f.field_name) {
        case 'shipping':
          s.shipping = s.isFieldShown(f);
          break;
        case 'discount':
          s.discount = s.isFieldShown(f);
          break;
        case 'custom':
          s.custom = s.isFieldShown(f);
          break;
        case 'items.discount':
          s.itemsDiscount = s.isFieldShown(f);
          break;
        case 'items.tax':
          s.itemsTax = s.isFieldShown(f);
          break;
        case 'items.quantity':
          s.itemsQuantity = s.isFieldShown(f);
          break;
        case 'items.description':
          s.itemsDescription = s.isFieldShown(f);
          break;
        case 'items.date':
          s.itemsDate = s.isFieldShown(f);
          break;
        default:
          (0, _assert2.default)('unknown field name: ' + f.field_name);
      }
    }
    return s;
  };

  InvoiceTemplateSettings.prototype.isFieldShown = function isFieldShown(field) {
    return field.display_preference.hidden !== true;
  };

  return InvoiceTemplateSettings;
}();

exports.default = InvoiceTemplateSettings;
},{"assert":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/assert/assert.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/totalCalculator.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

exports.default = function (invoice) {
  var it = new InvoiceTotals(invoice);
  it.calculate();
};

var _Currency = require('./Currency');

var _Currency2 = _interopRequireDefault(_Currency);

var _InvoiceBigNumber = require('./InvoiceBigNumber');

var _InvoiceBigNumber2 = _interopRequireDefault(_InvoiceBigNumber);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

var ZERO = new _InvoiceBigNumber2.default(0);
var ONE = new _InvoiceBigNumber2.default(1);

function nonZero(amt) {
  return amt && !ZERO.equals(amt);
}

function valOrZero(amt) {
  return amt || ZERO;
}

function compare(a, b) {
  if (a === b) {
    return 0;
  } else if (a < b) {
    return -1;
  }
  return 1;
}

var InvoiceTotals = function () {
  function InvoiceTotals(invoice) {
    _classCallCheck(this, InvoiceTotals);

    this.invoice = invoice;
  }

  InvoiceTotals.prototype.round = function round(amt) {
    return _Currency2.default.round(this.invoice.currency, amt);
  };

  InvoiceTotals.prototype.calculate = function calculate() {
    var invoice = this.invoice;
    var sortedItems = this.sortedInvoiceItems();
    var excludingDiscount = !(invoice.taxCalculatedAfterDiscount || invoice.taxInclusive);
    var subTotals = this.calculateItemSubtotals(sortedItems);
    invoice._subTotal = subTotals[0];
    invoice._subTotalWithItemDiscounts = subTotals[1];
    invoice._discountTotal = this.calculatePreTaxDiscountForItemSubtotal(invoice._subTotalWithItemDiscounts);
    if (invoice.taxCalculatedAfterDiscount) {
      var subWith = invoice._subTotalWithItemDiscounts;
      var dtot = invoice._discountTotal;
      invoice._taxBreakdown = this.calculateTaxesForItemsWithPreTaxDiscountTotal(sortedItems, dtot, subWith);
    } else {
      invoice._taxBreakdown = this.calculateTaxesForItemsWithDiscountAfterTax(sortedItems);
    }
    invoice._shippingTaxTotal = this.calculateShippingTax(invoice._taxBreakdown);
    invoice._itemTax = this.calculateTotalTaxFromTaxes(invoice._taxBreakdown);
    invoice._itemTax = (0, _InvoiceBigNumber.$$)(invoice._itemTax.minus(invoice._shippingTaxTotal));
    invoice._taxBreakdown = this.generateRoundedTaxDetailsFromTaxes(invoice._taxBreakdown);
    if (excludingDiscount) {
      invoice._discountTotal = this.calculateDiscountWithItemSubTotal(invoice._subTotal, invoice._itemTax);
    }
    if (this.invoice.custom) {
      invoice._customAmountTotal = this.invoice.custom.amount;
    }
    this.setDerivedTotals();
  };

  InvoiceTotals.prototype.sortedInvoiceItems = function sortedInvoiceItems() {
    // Sort the items so that the highest tax rate items are first just
    // so we have some logic to the application of pre-sales tax discounts.
    var copy = this.invoice.items.slice(0); // equivalent to array copy
    copy.sort(function (a, b) {
      if (!a.taxRate) {
        if (!b.taxRate) {
          return compare(a.name, b.name);
        }
        // a should go first
        return 1;
      }
      if (!b.taxRate) {
        // b should go first
        return -1;
      }
      if (b.taxRate.equals(a.taxRate)) {
        return compare(a.name, b.name);
      }
      return -1 * a.taxRate.comparedTo(b.taxRate);
    });
    return copy;
  };

  InvoiceTotals.prototype.generateRoundedTaxDetailsFromTaxes = function generateRoundedTaxDetailsFromTaxes(taxes) {
    var roundedTaxDetails = {};
    for (var key in taxes) {
      if (taxes.hasOwnProperty(key)) {
        roundedTaxDetails[key] = this.round(taxes[key]);
      }
    }
    return roundedTaxDetails;
  };

  InvoiceTotals.prototype.calculateTotalTaxFromTaxes = function calculateTotalTaxFromTaxes(taxes) {
    var itemTax = ZERO;
    for (var key in taxes) {
      if (taxes.hasOwnProperty(key)) {
        itemTax = itemTax.plus(taxes[key]);
      }
    }
    return itemTax;
  };

  InvoiceTotals.prototype.calculateTaxesForItemsWithPreTaxDiscountTotal = function calculateTaxesForItemsWithPreTaxDiscountTotal(items, discountTotal, itemSubTotal) {
    var taxes = {};
    for (var _iterator = items, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
      var _ref;

      if (_isArray) {
        if (_i >= _iterator.length) break;
        _ref = _iterator[_i++];
      } else {
        _i = _iterator.next();
        if (_i.done) break;
        _ref = _i.value;
      }

      var i = _ref;

      var itemDiscount = this.calculateItemDiscount(i, this.invoice);
      var itemContribution = i.totalForInvoice(this.invoice);
      if (nonZero(i.taxRate)) {
        var key = [i.taxName, ' (', i.taxRate.toString(), '%)'].join('');
        // Rounding is complicated. We have to match invoicing, and invoicing rounds per line item.
        var taxAmount = void 0;
        if (this.invoice.taxInclusive) {
          var itemTotal = itemContribution.plus(itemDiscount);
          var preTaxItemTotal = this.round(itemTotal.dividedBy(ONE.plus(i.taxRate.dividedBy(100))));
          taxAmount = preTaxItemTotal.times(i.taxRate.dividedBy(100));
        } else {
          var amountToBeTaxed = nonZero(discountTotal) ? itemContribution.minus(itemContribution.dividedBy(itemSubTotal).times(discountTotal)) : itemContribution;
          taxAmount = this.round(amountToBeTaxed.times(i.taxRate.dividedBy(100)));
        }
        if (taxAmount && !ZERO.equals(taxAmount)) {
          taxes[key] = (taxes[key] || ZERO).plus(taxAmount);
        }
      }
    }
    return taxes;
  };

  InvoiceTotals.prototype.calculateItemDiscount = function calculateItemDiscount(i, inv) {
    return (0, _InvoiceBigNumber.$$)(i.subtotalForInvoice(inv)).minus((0, _InvoiceBigNumber.$$)(i.totalForInvoice(inv)));
  };

  InvoiceTotals.prototype.calculateTaxesForItemsWithDiscountAfterTax = function calculateTaxesForItemsWithDiscountAfterTax(items) {
    var taxes = {};
    for (var _iterator2 = items, _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) {
      var _ref2;

      if (_isArray2) {
        if (_i2 >= _iterator2.length) break;
        _ref2 = _iterator2[_i2++];
      } else {
        _i2 = _iterator2.next();
        if (_i2.done) break;
        _ref2 = _i2.value;
      }

      var i = _ref2;

      var itemContribution = ZERO;
      if (nonZero(i.unitPrice)) {
        // In this mode (discounts after tax), even line item discounts
        // don't matter for tax calculations
        itemContribution = this.round(i.quantity.times(i.unitPrice));
      }
      if (nonZero(i.taxRate)) {
        var key = [i.taxName, ' (', i.taxRate.toString(), '%)'].join('');
        var taxAmount = void 0;
        if (this.invoice.taxInclusive) {
          var taxSub = itemContribution.dividedBy(ONE.plus(i.taxRate.dividedBy(100)));
          taxAmount = this.round(itemContribution.minus(taxSub));
        } else {
          taxAmount = this.round(itemContribution.times(i.taxRate.dividedBy(100)));
        }
        if (taxAmount && !ZERO.equals(taxAmount)) {
          taxes[key] = (taxes[key] || ZERO).plus(taxAmount);
        }
      }
    }
    return taxes;
  };

  InvoiceTotals.prototype.calculateShippingTax = function calculateShippingTax(taxes) {
    var invoice = this.invoice;
    if (nonZero(invoice.shippingTaxRate) && nonZero(invoice.shippingAmount)) {
      // Rounding is complicated. For best results, we're going to round at the "tax class" level.
      // If you have one tax rate, this means "order level." If you have as many tax rates as
      // line items, this means line level. The advantage is with this rounding I can display
      // valid tax per tax rate and have consistent totals.
      var key = [invoice.shippingTaxName || 'Shipping Tax', ' (', invoice.shippingTaxRate.toString(), '%)'].join('');
      var shippingTaxTotal = invoice.shippingAmount.times(invoice.shippingTaxRate.dividedBy(100));
      if (nonZero(shippingTaxTotal)) {
        taxes[key] = valOrZero(taxes[key]).plus(shippingTaxTotal);
      }
      return shippingTaxTotal;
    }
    return ZERO;
  };

  InvoiceTotals.prototype.calculateItemSubtotals = function calculateItemSubtotals(items) {
    var subtotalWithoutDiscount = ZERO;
    var subtotalWithDiscount = ZERO;
    for (var _iterator3 = items, _isArray3 = Array.isArray(_iterator3), _i3 = 0, _iterator3 = _isArray3 ? _iterator3 : _iterator3[Symbol.iterator]();;) {
      var _ref3;

      if (_isArray3) {
        if (_i3 >= _iterator3.length) break;
        _ref3 = _iterator3[_i3++];
      } else {
        _i3 = _iterator3.next();
        if (_i3.done) break;
        _ref3 = _i3.value;
      }

      var item = _ref3;

      subtotalWithoutDiscount = subtotalWithoutDiscount.plus(item.subtotalForInvoice(this.invoice));
      subtotalWithDiscount = subtotalWithDiscount.plus(item.totalForInvoice(this.invoice));
    }
    return [(0, _InvoiceBigNumber.$$)(subtotalWithoutDiscount), (0, _InvoiceBigNumber.$$)(subtotalWithDiscount)];
  };

  InvoiceTotals.prototype.calculateDiscountWithItemSubTotal = function calculateDiscountWithItemSubTotal(itemSubTotal) {
    if (nonZero(this.invoice.discountAmount)) {
      return this.invoice.discountAmount;
    } else if (nonZero(this.invoice.discountPercentage)) {
      return this.round(itemSubTotal.times(this.invoice.discountPercentage).dividedBy(100));
    }
    return ZERO;
  };

  InvoiceTotals.prototype.calculatePreTaxDiscountForItemSubtotal = function calculatePreTaxDiscountForItemSubtotal(subtotal) {
    if (nonZero(this.invoice.discountAmount)) {
      return (0, _InvoiceBigNumber.$$)(this.invoice.discountAmount);
    } else if (nonZero(this.invoice.discountPercentage)) {
      return this.round((0, _InvoiceBigNumber.$$)(this.invoice.discountPercentage).dividedBy(100).times(subtotal));
    }
    return ZERO;
  };

  /**
   * Once the component values of the total have been calculated, this is used to set
   * various derived totals such as the grand total. Rather than using properties, which
   * in theory won't work on all browsers, we just spend the cycles to do various additions
   * every time the invoice is recalculated.
   * @private
   */


  InvoiceTotals.prototype.setDerivedTotals = function setDerivedTotals() {
    var invoice = this.invoice;
    invoice._total = valOrZero(invoice._subTotalWithItemDiscounts).plus(valOrZero(invoice.gratuityAmount)).plus(valOrZero(invoice.shippingAmount));
    if (!invoice.taxInclusive) {
      invoice._total = invoice._total.plus(valOrZero(invoice._itemTax)).plus(valOrZero(invoice._shippingTaxTotal));
    }
    if (nonZero(invoice._discountTotal)) {
      invoice._total = invoice._total.minus(invoice._discountTotal);
    }
    if (nonZero(invoice._customAmountTotal)) {
      invoice._total = invoice._total.plus(invoice._customAmountTotal);
    }
    invoice._total = (0, _InvoiceBigNumber.$$)(invoice._total);
  };

  return InvoiceTotals;
}();
},{"./Currency":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/Currency.js","./InvoiceBigNumber":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/InvoiceBigNumber.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/tlvlib/build/index.js":[function(require,module,exports){
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});
var Tlv = exports.Tlv = require('./lib/Tlv').default;
var TlvList = exports.TlvList = require('./lib/TlvList').default;
var Tags = exports.Tags = require('./lib/Tags').default;
var ValueFormat = exports.ValueFormat = require('./lib/ValueFormat').default;
var DefinedTag = exports.DefinedTag = require('./lib/DefinedTag').default;
var ApduCommand = exports.ApduCommand = require('./lib/apdu/Command').default;
var ApduResponse = exports.ApduResponse = require('./lib/apdu/Response').default;
},{"./lib/DefinedTag":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/tlvlib/build/lib/DefinedTag.js","./lib/Tags":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/tlvlib/build/lib/Tags.js","./lib/Tlv":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/tlvlib/build/lib/Tlv.js","./lib/TlvList":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/tlvlib/build/lib/TlvList.js","./lib/ValueFormat":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/tlvlib/build/lib/ValueFormat.js","./lib/apdu/Command":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/tlvlib/build/lib/apdu/Command.js","./lib/apdu/Response":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/tlvlib/build/lib/apdu/Response.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/tlvlib/build/lib/DefinedTag.js":[function(require,module,exports){
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

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; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

var _ValueFormat = require('./ValueFormat');

var _ValueFormat2 = _interopRequireDefault(_ValueFormat);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

var allTags = {};
var tagsByName = {};

/**
 * A defined tag represents a TLV format tag with a known type and purpose.
 * Because the TLV format will accommodate any "tag id," not all TLVs encountered
 * in a message will have a matching DefinedTag
 * @class
 * @property {string} name The name of the tag @readOnly
 * @property {int} number The numeric 'index' of this tag @readOnly
 * @property {ValueFormat} format The format of values of this type @readOnly
 * @property {int} length (optional) the length of the value, if fixed @readOnly
 * @property {bool} addToKnownTags (optional) if ===false, do not add this to the
 *  tags for findTag/findTags.
 */

var DefinedTag = function () {
  function DefinedTag(name, number, format, length) {
    var addToKnownTags = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : true;

    _classCallCheck(this, DefinedTag);

    this.name = name;
    this.number = number;
    this.format = format;
    this.length = length;
    if (addToKnownTags !== false) {
      if (allTags[number]) {
        allTags[number].push(this);
      } else {
        allTags[number] = [this];
      }
      tagsByName[name] = this;
    }
  }

  _createClass(DefinedTag, [{
    key: 'valueFromBytes',
    value: function valueFromBytes(bytes) {
      return this.format ? this.format.fromBytes(bytes, this.length) : bytes;
    }
  }, {
    key: 'valueToBytes',
    value: function valueToBytes(value) {
      return this.format.toBytes(value, this.length);
    }
  }], [{
    key: 'findTags',
    value: function findTags(number) {
      if (allTags[number]) {
        return allTags[number];
      }
      return [new DefinedTag('UnknownTag', number, _ValueFormat2.default.Binary, null, false)];
    }
  }, {
    key: 'getTagsByName',
    value: function getTagsByName() {
      return tagsByName;
    }
  }, {
    key: 'findTag',
    value: function findTag(number) {
      return DefinedTag.findTags(number)[0];
    }
  }]);

  return DefinedTag;
}();

exports.default = DefinedTag;
},{"./ValueFormat":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/tlvlib/build/lib/ValueFormat.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/tlvlib/build/lib/Tags.js":[function(require,module,exports){
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.UnknownTag = exports.UnpredictableNumberAlternate = exports.UnpredictableNumber = exports.TransactionStatusInformation = exports.TransactionSequenceCounter = exports.TransactionType = exports.TransactionTime = exports.TransactionDate = exports.TransactionCurrencyCode = exports.Track2UnpredictableNumberAndAttackCounterPosition = exports.Track2NumberOfATCDigits = exports.Track2Cvc3Position = exports.Track2Cvc3 = exports.Track2 = exports.Track1UnpredictableNumberAndAttackCounterPosition = exports.Track1NumberOfATCDigits = exports.Track1Cvc3Position = exports.Track1Cvc3 = exports.Track1 = exports.TerminalVerificationResults = exports.TerminalType = exports.TerminalTransactionQualifiers = exports.TerminalIdentification = exports.TerminalCountryCode = exports.TerminalCapabilities = exports.TerminalApplicationIdentifier = exports.ServiceCode = exports.ProcessingDataObjectList = exports.MsdOffset = exports.MobileSupportIndicator = exports.LanguagePreference = exports.IssuerCountryCode = exports.IssuerCodeTableIndex = exports.IssuerApplicationData = exports.IssuerAuthenticationData = exports.InterfaceDeviceSerialNumber = exports.FciProprietaryData = exports.FciProprietaryTemplate = exports.DfNameRaw = exports.DfNameAscii = exports.CryptogramInformationData = exports.CardTransactionQualifiers = exports.CardholderVerificationMethodResults = exports.CardholderNameExtended = exports.CardholderName = exports.CardCvmLimit = exports.CardAuthenticationRelatedData = exports.AuthorizationResponseCode = exports.ApplicationVersionNumber = exports.ApplicationTransactionCounter = exports.ApplicationTemplate = exports.ApplicationPriorityIndicator = exports.ApplicationPreferredName = exports.ApplicationPanSequenceCode = exports.ApplicationLabel = exports.ApplicationInterchangeProfile = exports.ApplicationIdentifier = exports.ApplicationFileLocator = exports.ApplicationExpirationDate = exports.ApplicationCryptogram = exports.AmountOther = exports.AmountAuthorized = undefined;

var _DefinedTag = require('./DefinedTag');

var _DefinedTag2 = _interopRequireDefault(_DefinedTag);

var _ValueFormat = require('./ValueFormat');

var _ValueFormat2 = _interopRequireDefault(_ValueFormat);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

/**
 * DO NOT EDIT THIS FILE, IT IS AUTOMATICALLY GENERATED BY gulpfile.js
**/
var AmountAuthorized = exports.AmountAuthorized = new _DefinedTag2.default('AmountAuthorized', 0x9F02, _ValueFormat2.default.CompressedNumeric);
var AmountOther = exports.AmountOther = new _DefinedTag2.default('AmountOther', 0x9F03, _ValueFormat2.default.CompressedNumeric);
var ApplicationCryptogram = exports.ApplicationCryptogram = new _DefinedTag2.default('ApplicationCryptogram', 0x9f26, _ValueFormat2.default.Binary);
var ApplicationExpirationDate = exports.ApplicationExpirationDate = new _DefinedTag2.default('ApplicationExpirationDate', 0x5f24, _ValueFormat2.default.Date);
var ApplicationFileLocator = exports.ApplicationFileLocator = new _DefinedTag2.default('ApplicationFileLocator', 0x94, _ValueFormat2.default.Binary);
var ApplicationIdentifier = exports.ApplicationIdentifier = new _DefinedTag2.default('ApplicationIdentifier', 0x4F, _ValueFormat2.default.Binary);
var ApplicationInterchangeProfile = exports.ApplicationInterchangeProfile = new _DefinedTag2.default('ApplicationInterchangeProfile', 0x82, _ValueFormat2.default.Binary, 2);
var ApplicationLabel = exports.ApplicationLabel = new _DefinedTag2.default('ApplicationLabel', 0x50, _ValueFormat2.default.AlphaWithSpace);
var ApplicationPanSequenceCode = exports.ApplicationPanSequenceCode = new _DefinedTag2.default('ApplicationPanSequenceCode', 0x5f34, _ValueFormat2.default.Numeric, 2);
var ApplicationPreferredName = exports.ApplicationPreferredName = new _DefinedTag2.default('ApplicationPreferredName', 0x9f12, _ValueFormat2.default.AlphaWithSpace);
var ApplicationPriorityIndicator = exports.ApplicationPriorityIndicator = new _DefinedTag2.default('ApplicationPriorityIndicator', 0x87, _ValueFormat2.default.Binary, 1);
var ApplicationTemplate = exports.ApplicationTemplate = new _DefinedTag2.default('ApplicationTemplate', 0x61, _ValueFormat2.default.Tlv);
var ApplicationTransactionCounter = exports.ApplicationTransactionCounter = new _DefinedTag2.default('ApplicationTransactionCounter', 0x9F36, _ValueFormat2.default.Binary, 2);
var ApplicationVersionNumber = exports.ApplicationVersionNumber = new _DefinedTag2.default('ApplicationVersionNumber', 0x9F09, _ValueFormat2.default.Binary, 2);
var AuthorizationResponseCode = exports.AuthorizationResponseCode = new _DefinedTag2.default('AuthorizationResponseCode', 0x8A, _ValueFormat2.default.AlphaNumeric, 2);
var CardAuthenticationRelatedData = exports.CardAuthenticationRelatedData = new _DefinedTag2.default('CardAuthenticationRelatedData', 0x9F69, _ValueFormat2.default.Dol);
var CardCvmLimit = exports.CardCvmLimit = new _DefinedTag2.default('CardCvmLimit', 0x9f6b, _ValueFormat2.default.Binary);
var CardholderName = exports.CardholderName = new _DefinedTag2.default('CardholderName', 0x5F20, _ValueFormat2.default.AlphaWithSpace);
var CardholderNameExtended = exports.CardholderNameExtended = new _DefinedTag2.default('CardholderNameExtended', 0x9F0B, _ValueFormat2.default.AlphaWithSpace);
var CardholderVerificationMethodResults = exports.CardholderVerificationMethodResults = new _DefinedTag2.default('CardholderVerificationMethodResults', 0x9F34, _ValueFormat2.default.Binary);
var CardTransactionQualifiers = exports.CardTransactionQualifiers = new _DefinedTag2.default('CardTransactionQualifiers', 0x9F6C, _ValueFormat2.default.Binary, 2);
var CryptogramInformationData = exports.CryptogramInformationData = new _DefinedTag2.default('CryptogramInformationData', 0x9f27, _ValueFormat2.default.Binary, 1);
var DfNameAscii = exports.DfNameAscii = new _DefinedTag2.default('DfNameAscii', 0x84, _ValueFormat2.default.Alpha);
var DfNameRaw = exports.DfNameRaw = new _DefinedTag2.default('DfNameRaw', 0x84, _ValueFormat2.default.Binary);
var FciProprietaryTemplate = exports.FciProprietaryTemplate = new _DefinedTag2.default('FciProprietaryTemplate', 0xA5, _ValueFormat2.default.Tlv);
var FciProprietaryData = exports.FciProprietaryData = new _DefinedTag2.default('FciProprietaryData', 0xBF0C, _ValueFormat2.default.Tlv);
var InterfaceDeviceSerialNumber = exports.InterfaceDeviceSerialNumber = new _DefinedTag2.default('InterfaceDeviceSerialNumber', 0x9F1E, _ValueFormat2.default.AlphaNumeric);
var IssuerAuthenticationData = exports.IssuerAuthenticationData = new _DefinedTag2.default('IssuerAuthenticationData', 0x91, _ValueFormat2.default.Binary);
var IssuerApplicationData = exports.IssuerApplicationData = new _DefinedTag2.default('IssuerApplicationData', 0x9f10, _ValueFormat2.default.Binary);
var IssuerCodeTableIndex = exports.IssuerCodeTableIndex = new _DefinedTag2.default('IssuerCodeTableIndex', 0x9F11, _ValueFormat2.default.Numeric);
var IssuerCountryCode = exports.IssuerCountryCode = new _DefinedTag2.default('IssuerCountryCode', 0x5f28, _ValueFormat2.default.Numeric);
var LanguagePreference = exports.LanguagePreference = new _DefinedTag2.default('LanguagePreference', 0x5F2D, _ValueFormat2.default.Alpha);
var MobileSupportIndicator = exports.MobileSupportIndicator = new _DefinedTag2.default('MobileSupportIndicator', 0x9F7E, _ValueFormat2.default.Binary, 1);
var MsdOffset = exports.MsdOffset = new _DefinedTag2.default('MsdOffset', 0x9f67, _ValueFormat2.default.Binary);
var ProcessingDataObjectList = exports.ProcessingDataObjectList = new _DefinedTag2.default('ProcessingDataObjectList', 0x9F38, _ValueFormat2.default.Dol);
var ServiceCode = exports.ServiceCode = new _DefinedTag2.default('ServiceCode', 0x5f30, _ValueFormat2.default.Numeric);
var TerminalApplicationIdentifier = exports.TerminalApplicationIdentifier = new _DefinedTag2.default('TerminalApplicationIdentifier', 0x9f06, _ValueFormat2.default.Binary);
var TerminalCapabilities = exports.TerminalCapabilities = new _DefinedTag2.default('TerminalCapabilities', 0x9f33, _ValueFormat2.default.Binary);
var TerminalCountryCode = exports.TerminalCountryCode = new _DefinedTag2.default('TerminalCountryCode', 0x9F1A, _ValueFormat2.default.Numeric);
var TerminalIdentification = exports.TerminalIdentification = new _DefinedTag2.default('TerminalIdentification', 0x9F1C, _ValueFormat2.default.Alpha);
var TerminalTransactionQualifiers = exports.TerminalTransactionQualifiers = new _DefinedTag2.default('TerminalTransactionQualifiers', 0x9f66, _ValueFormat2.default.Binary);
var TerminalType = exports.TerminalType = new _DefinedTag2.default('TerminalType', 0x9f35, _ValueFormat2.default.Numeric);
var TerminalVerificationResults = exports.TerminalVerificationResults = new _DefinedTag2.default('TerminalVerificationResults', 0x95, _ValueFormat2.default.Binary);
var Track1 = exports.Track1 = new _DefinedTag2.default('Track1', 0x56, _ValueFormat2.default.Alpha);
var Track1Cvc3 = exports.Track1Cvc3 = new _DefinedTag2.default('Track1Cvc3', 0x9F60, _ValueFormat2.default.Binary, 2);
var Track1Cvc3Position = exports.Track1Cvc3Position = new _DefinedTag2.default('Track1Cvc3Position', 0x9F62, _ValueFormat2.default.Binary);
var Track1NumberOfATCDigits = exports.Track1NumberOfATCDigits = new _DefinedTag2.default('Track1NumberOfATCDigits', 0x9F64, _ValueFormat2.default.Binary, 1);
var Track1UnpredictableNumberAndAttackCounterPosition = exports.Track1UnpredictableNumberAndAttackCounterPosition = new _DefinedTag2.default('Track1UnpredictableNumberAndAttackCounterPosition', 0x9F63, _ValueFormat2.default.Binary);
var Track2 = exports.Track2 = new _DefinedTag2.default('Track2', 0x9F6B, _ValueFormat2.default.Numeric);
var Track2Cvc3 = exports.Track2Cvc3 = new _DefinedTag2.default('Track2Cvc3', 0x9F61, _ValueFormat2.default.Binary, 2);
var Track2Cvc3Position = exports.Track2Cvc3Position = new _DefinedTag2.default('Track2Cvc3Position', 0x9F65, _ValueFormat2.default.Binary);
var Track2NumberOfATCDigits = exports.Track2NumberOfATCDigits = new _DefinedTag2.default('Track2NumberOfATCDigits', 0x9F67, _ValueFormat2.default.Binary, 1);
var Track2UnpredictableNumberAndAttackCounterPosition = exports.Track2UnpredictableNumberAndAttackCounterPosition = new _DefinedTag2.default('Track2UnpredictableNumberAndAttackCounterPosition', 0x9F66, _ValueFormat2.default.Binary);
var TransactionCurrencyCode = exports.TransactionCurrencyCode = new _DefinedTag2.default('TransactionCurrencyCode', 0x5F2A, _ValueFormat2.default.CompressedNumeric, 2);
var TransactionDate = exports.TransactionDate = new _DefinedTag2.default('TransactionDate', 0x9A, _ValueFormat2.default.Date);
var TransactionTime = exports.TransactionTime = new _DefinedTag2.default('TransactionTime', 0x9F21, _ValueFormat2.default.Time);
var TransactionType = exports.TransactionType = new _DefinedTag2.default('TransactionType', 0x9C, _ValueFormat2.default.CompressedNumeric);
var TransactionSequenceCounter = exports.TransactionSequenceCounter = new _DefinedTag2.default('TransactionSequenceCounter', 0x9F41, _ValueFormat2.default.Numeric, 4);
var TransactionStatusInformation = exports.TransactionStatusInformation = new _DefinedTag2.default('TransactionStatusInformation', 0x9B, _ValueFormat2.default.Binary, 2);
var UnpredictableNumber = exports.UnpredictableNumber = new _DefinedTag2.default('UnpredictableNumber', 0x9f37, _ValueFormat2.default.Binary);
var UnpredictableNumberAlternate = exports.UnpredictableNumberAlternate = new _DefinedTag2.default('UnpredictableNumberAlternate', 0x9F6A, _ValueFormat2.default.Binary);
var UnknownTag = exports.UnknownTag = new _DefinedTag2.default('UnknownTag', 0x7FFFFFFF, _ValueFormat2.default.Binary);

exports.default = _DefinedTag2.default.getTagsByName();
},{"./DefinedTag":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/tlvlib/build/lib/DefinedTag.js","./ValueFormat":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/tlvlib/build/lib/ValueFormat.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/tlvlib/build/lib/Tlv.js":[function(require,module,exports){
(function (Buffer){
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

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; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

var _ber = require('./ber');

var _ber2 = _interopRequireDefault(_ber);

var _DefinedTag = require('./DefinedTag');

var _DefinedTag2 = _interopRequireDefault(_DefinedTag);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

/**
 * A single tag/length/value entry with binary data
 * @class
 * @property {DefinedTag} tag The "defined tag" for this TLV, if known
 * @property {int} tagNumber The raw tag number for this TLV
 * @property {Buffer} bytes The raw bytes of the TLV
 * @property {object} value The value as parsed by ValueFormat for the defined tag. You
 * must call parse() first before this is available
 */
var Tlv = function () {
  function Tlv(tagOrTagNumber, bytes) {
    _classCallCheck(this, Tlv);

    if (tagOrTagNumber instanceof _DefinedTag2.default) {
      this.tag = tagOrTagNumber;
      this.tagNumber = tagOrTagNumber.number;
    } else {
      this.tagNumber = tagOrTagNumber;
      this.tag = _DefinedTag2.default.findTag(tagOrTagNumber);
    }
    if (!Buffer.isBuffer(bytes)) {
      this.bytes = this.tag.valueToBytes(bytes);
    } else {
      this.bytes = bytes;
    }
  }

  _createClass(Tlv, [{
    key: 'parse',
    value: function parse() {
      if (!this.hasOwnProperty('value')) {
        this.value = this.tag.valueFromBytes(this.bytes);
      }
      return this.value;
    }
  }, {
    key: 'toBytes',
    value: function toBytes() {
      var parts = [_ber2.default.encodeTag(this.tagNumber), _ber2.default.encodeLength(this.bytes ? this.bytes.length : 0)];
      if (this.bytes) {
        parts.push(this.bytes);
      }
      return Buffer.concat(parts);
    }
  }, {
    key: 'toString',
    value: function toString(shouldParse) {
      var parts = ['  Tag 0x', this.tagNumber.toString(16)];
      if (this.tag && this.tag.name) {
        parts.push(' ');
        parts.push(this.tag.name);
      }
      parts.push(': ');
      if (this.value || shouldParse) {
        if (Buffer.isBuffer(this.parse())) {
          parts.push('0x');
          parts.push(this.value.toString('hex'));
        } else {
          parts.push(this.value.toString());
        }
      } else if (this.bytes) {
        parts.push('0x');
        parts.push(this.bytes.toString('hex'));
      } else {
        parts.push('<empty>');
      }
      return parts.join('');
    }
  }], [{
    key: 'readLength',
    value: function readLength(bytes, startPosition) {
      return _ber2.default.readLength(bytes, startPosition);
    }
  }]);

  return Tlv;
}();

exports.default = Tlv;
}).call(this,require("buffer").Buffer)
},{"./DefinedTag":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/tlvlib/build/lib/DefinedTag.js","./ber":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/tlvlib/build/lib/ber.js","buffer":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/buffer/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/tlvlib/build/lib/TlvList.js":[function(require,module,exports){
(function (Buffer){
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

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; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

var _Tlv = require('./Tlv');

var _Tlv2 = _interopRequireDefault(_Tlv);

var _DefinedTag = require('./DefinedTag');

var _DefinedTag2 = _interopRequireDefault(_DefinedTag);

var _ber = require('./ber');

var _ber2 = _interopRequireDefault(_ber);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function lengthCheck(index, start, length, message) {
  if (index > start + length) {
    throw new Error(message);
  }
}

var TlvList = function () {
  function TlvList(bufferOrNull, start, length) {
    _classCallCheck(this, TlvList);

    this.values = [];
    if (bufferOrNull) {
      this._parse(bufferOrNull, start, length);
    }
  }

  _createClass(TlvList, [{
    key: '_parse',
    value: function _parse(buffer) {
      var start = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
      var length = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : buffer.length - start;

      var index = start;
      while (index < start + length) {
        var tagData = _ber2.default.readTag(buffer, index);
        index += tagData.length;
        lengthCheck(index, start, length, 'Invalid TLV - tag ends buffer.');
        var lenData = _ber2.default.readLength(buffer, index);
        index += lenData.lengthOfEncoding;
        lengthCheck(index, start, length, 'Invalid TLV - tag value length ends buffer.');
        var value = void 0;
        if (lenData.lengthValue) {
          lengthCheck(index + lenData.lengthValue, start, length, 'Invalid TLV - value overruns buffer.');
          value = buffer.slice(index, index + lenData.lengthValue);
          index += lenData.lengthValue;
        }
        var tags = _DefinedTag2.default.findTags(tagData.number);
        var _iteratorNormalCompletion = true;
        var _didIteratorError = false;
        var _iteratorError = undefined;

        try {
          for (var _iterator = tags[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
            var t = _step.value;

            this.values.push(new _Tlv2.default(t, value));
          }
        } catch (err) {
          _didIteratorError = true;
          _iteratorError = err;
        } finally {
          try {
            if (!_iteratorNormalCompletion && _iterator.return) {
              _iterator.return();
            }
          } finally {
            if (_didIteratorError) {
              throw _iteratorError;
            }
          }
        }
      }
    }
  }, {
    key: 'add',
    value: function add(tlvOrTag, valueOrNull) {
      if (tlvOrTag instanceof _DefinedTag2.default) {
        this.values.push(new _Tlv2.default(tlvOrTag, valueOrNull));
      } else if (tlvOrTag instanceof _Tlv2.default) {
        this.values.push(tlvOrTag);
      } else if (!Buffer.isBuffer(valueOrNull)) {
        throw new Error('Add must be called with a tag and value, or a tag number and buffer.');
      } else {
        this.values.push(new _Tlv2.default(_DefinedTag2.default.findTag(tlvOrTag), valueOrNull));
      }
    }

    /**
     * Find a tag in the list of values.
     * @param tag
     * @param skip For multiple tags, pass a non-zero skip value
     * @returns {*}
     */

  }, {
    key: 'find',
    value: function find(tag, skip) {
      var toSkip = skip || 0;
      var findNumber = tag.number || tag;
      var _iteratorNormalCompletion2 = true;
      var _didIteratorError2 = false;
      var _iteratorError2 = undefined;

      try {
        for (var _iterator2 = this.values[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
          var tlv = _step2.value;

          if (tlv.tagNumber === findNumber) {
            if (toSkip > 0) {
              toSkip--;
            } else {
              return tlv;
            }
          }
        }
      } catch (err) {
        _didIteratorError2 = true;
        _iteratorError2 = err;
      } finally {
        try {
          if (!_iteratorNormalCompletion2 && _iterator2.return) {
            _iterator2.return();
          }
        } finally {
          if (_didIteratorError2) {
            throw _iteratorError2;
          }
        }
      }

      return null;
    }
  }, {
    key: 'toBytes',
    value: function toBytes() {
      // TODO this isn't right anymore...
      var parts = [];
      var _iteratorNormalCompletion3 = true;
      var _didIteratorError3 = false;
      var _iteratorError3 = undefined;

      try {
        for (var _iterator3 = this.values[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {
          var tlv = _step3.value;

          parts.push(tlv.toBytes());
        }
      } catch (err) {
        _didIteratorError3 = true;
        _iteratorError3 = err;
      } finally {
        try {
          if (!_iteratorNormalCompletion3 && _iterator3.return) {
            _iterator3.return();
          }
        } finally {
          if (_didIteratorError3) {
            throw _iteratorError3;
          }
        }
      }

      return Buffer.concat(parts);
    }
  }, {
    key: 'toString',
    value: function toString(shouldParse) {
      var parts = ['TLV:'];
      var _iteratorNormalCompletion4 = true;
      var _didIteratorError4 = false;
      var _iteratorError4 = undefined;

      try {
        for (var _iterator4 = this.values[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) {
          var tlv = _step4.value;

          if (Buffer.isBuffer(tlv)) {
            parts.push(tlv.toString('hex'));
          } else {
            parts.push(tlv.toString(shouldParse));
          }
        }
      } catch (err) {
        _didIteratorError4 = true;
        _iteratorError4 = err;
      } finally {
        try {
          if (!_iteratorNormalCompletion4 && _iterator4.return) {
            _iterator4.return();
          }
        } finally {
          if (_didIteratorError4) {
            throw _iteratorError4;
          }
        }
      }

      return parts.join('\n');
    }
  }, {
    key: 'length',
    get: function get() {
      return this.values.length;
    }
  }]);

  return TlvList;
}();

exports.default = TlvList;
}).call(this,require("buffer").Buffer)
},{"./DefinedTag":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/tlvlib/build/lib/DefinedTag.js","./Tlv":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/tlvlib/build/lib/Tlv.js","./ber":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/tlvlib/build/lib/ber.js","buffer":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/buffer/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/tlvlib/build/lib/ValueFormat.js":[function(require,module,exports){
(function (Buffer){
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});
// Delay load this one to avoid circular dependency
var TlvList = void 0;

function fromBytes(buf, len) {
  if (len && buf && buf.length !== len) {
    var b = new Buffer(len);
    buf.copy(b);
    return b;
  }
  return buf;
}

function toBytes(bytes, len) {
  if (len && (!bytes || bytes.length !== len)) {
    var b = new Buffer(len);
    if (bytes) {
      bytes.copy(b);
    }
    return b;
  }
  return bytes;
}

function fromUtf8(buf) {
  return buf.toString('utf8');
}

function toUtf8(val) {
  return new Buffer(val, 'utf8');
}

function toValidHexBytes(val, length) {
  if (Buffer.isBuffer(val)) {
    return val;
  }
  var strval = String(val);
  if (strval.length % 2 === 1) {
    strval = '0' + strval;
  }
  while (length && strval.length < length * 2) {
    strval = '00' + strval;
  }
  return new Buffer(strval, 'hex');
}

/**
 * Encoding/decoding utilities for Javascript to TLV type mapping
 */
exports.default = {
  Alpha: {
    fromBytes: fromUtf8,
    toBytes: toUtf8
  },
  AlphaNumeric: {
    fromBytes: fromUtf8,
    toBytes: toUtf8
  },
  AlphaWithSpace: {
    fromBytes: fromUtf8,
    toBytes: toUtf8
  },
  Binary: {
    fromBytes: fromBytes,
    toBytes: toBytes
  },
  Date: {
    // YYMMDD
    fromBytes: function fromBytes(buf) {
      if (buf.length < 3) {
        throw new Error('Invalid date format.');
      }
      var hex = buf.toString('hex');
      // y,m,d
      return new Date(2000 + parseInt(hex.substring(0, 2), 10), parseInt(hex.substring(2, 4) - 1, 10), parseInt(hex.substring(4, 6), 10));
    },
    toBytes: function toBytes(date) {
      var hexstr = [];
      [date.getFullYear() - 2000, date.getMonth() + 1, date.getDate()].forEach(function (v) {
        if (v < 10) {
          hexstr.push('0');
        }
        hexstr.push(String(v));
      });
      return new Buffer(hexstr.join(''), 'hex');
    }
  },
  Time: {
    // HHmmss
    fromBytes: function fromBytes(buf) {
      if (buf.length < 3) {
        throw new Error('Invalid time format.');
      }
      var hex = buf.toString('hex');
      // hr, min, ss
      return new Date(2000, 1, 1, parseInt(hex.substring(0, 2), 10), parseInt(hex.substring(2, 4), 10), parseInt(hex.substring(4, 6), 10));
    },
    toBytes: function toBytes(date) {
      var hexstr = [];
      [date.getHours(), date.getMinutes(), date.getSeconds()].forEach(function (v) {
        if (v < 10) {
          hexstr.push('0');
        }
        hexstr.push(String(v));
      });
      return new Buffer(hexstr.join(''), 'hex');
    }
  },
  // Otherwise known as BCD?
  CompressedNumeric: {
    fromBytes: function fromBytes(buf) {
      return parseInt(buf.toString('hex'), 10);
    },
    toBytes: toValidHexBytes
  },
  // 0-9A-F
  CompressedAlpha: {
    fromBytes: function fromBytes(buf) {
      return buf.toString('hex');
    },
    toBytes: toValidHexBytes
  },
  Numeric: {
    fromBytes: function fromBytes(buf) {
      var v = 0;
      for (var i = 0; i < buf.length; i++) {
        v = v << 8;
        v += buf[i];
      }
      return v;
    },
    toBytes: function toBytes(val) {
      var len = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 4;

      var buf = new Buffer(len);
      var remaining = val;
      for (var i = 0; i < len; i++) {
        buf[len - i - 1] = remaining & 0xFF;
        remaining = remaining >> 8;
      }
      return buf;
    }
  },
  TypeLengthValueList: {
    fromBytes: function fromBytes(buf) {
      if (!TlvList) {
        TlvList = require('./TlvList').default;
      }
      return new TlvList(buf);
    },
    toBytes: function toBytes(tlv) {
      return tlv.toBytes();
    }
  },
  DataObjectList: {}
};
}).call(this,require("buffer").Buffer)
},{"./TlvList":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/tlvlib/build/lib/TlvList.js","buffer":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/buffer/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/tlvlib/build/lib/apdu/Command.js":[function(require,module,exports){
(function (Buffer){
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

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; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

var ApduCommand = function () {
  /**
   * Create a new ApduCommand either from a data buffer (i.e. parse it)
   * or from command/instruction/p1/p2 with a blank buffer.
   * @param bufferOrCommandClass
   * @param instruction
   * @param p1
   * @param p2
   * @param data
   * @param le
   * @param longLength Uses 2 bytes to indicate length while converting to byte array
   */
  function ApduCommand(bufferOrCommandClass, instruction, p1, p2, data, le, longLength) {
    _classCallCheck(this, ApduCommand);

    var preambleByteSize = this.longLength ? 5 : 4;
    this.preamble = new Buffer(preambleByteSize);
    this.longLength = longLength;
    if (data) {
      if (Buffer.isBuffer(data)) {
        this.data = [data];
      } else {
        // Better be an array...
        this.data = data;
      }
    } else {
      this.data = null;
    }
    // This is the common case. Use expectNoBytes property to set it to null and not send the byte.
    this.le = 0;
    if (Buffer.isBuffer(bufferOrCommandClass)) {
      // Parse an Apdu Command
    } else {
      // Create a new Apdu Command
      this.commandClass = bufferOrCommandClass;
      this.instruction = instruction;
      this.p1 = p1 || 0;
      this.p2 = p2 || 0;
      if (le !== undefined) {
        this.le = le;
      }
    }
  }

  _createClass(ApduCommand, [{
    key: 'expectNoBytes',
    value: function expectNoBytes() {
      this.le = null;
    }
  }, {
    key: 'appendHex',
    value: function appendHex(hexString) {
      this.data = this.data || [];
      this.data.push(new Buffer(hexString, 'hex'));
    }
  }, {
    key: 'appendBytes',
    value: function appendBytes(buffer) {
      this.data = this.data || [];
      this.data.push(buffer);
    }
  }, {
    key: 'appendString',
    value: function appendString(utf8String) {
      this.data = this.data || [];
      this.data.push(new Buffer(utf8String, 'utf8'));
    }
  }, {
    key: 'toBytes',
    value: function toBytes() {
      var parts = [this.preamble];

      // https://en.wikipedia.org/wiki/Smart_card_application_protocol_data_unit
      var len = 0;
      if (this.data) {
        parts.push(null);
        this.data.forEach(function (p) {
          len += p.length;
          parts.push(p);
        });
        if (len > 65535) {
          throw new Error('ApduCommand buffer is too long');
        } else if (len > 255) {
          parts[1] = new Buffer([0, len >> 8, len & 0xFF]);
        } else {
          parts[1] = this.longLength ? new Buffer([0, len]) : new Buffer([len]);
        }
      }

      if (this.le !== null) {
        if (this.le > 65535) {
          throw new Error('Le value must be between 0 and 65535');
        } else if (this.le <= 256) {
          parts.push(new Buffer([this.le & 0xFF]));
        } else {
          if (parts.length === 1) {
            // In this case (case 2E from http://www.cardwerk.com/smartcards/smartcard_standard_ISO7816-4_5_basic_organizations.aspx#table4), we need a 0 byte for Lc
            parts.push(new Buffer([0]));
          }
          parts.push(new Buffer([this.le >> 8, this.le & 0xFF]));
        }
      }
      return Buffer.concat(parts);
    }
  }, {
    key: 'toString',
    value: function toString() {
      var parts = ['ApduCommand class 0x', this.commandClass.toString(16), ', instruction 0x', this.instruction.toString(16), ', P1 0x', this.p1.toString(16), ', P2 0x', this.p2.toString(16), '\n'];
      if (this.data && this.data.length) {
        var buf = Buffer.concat(this.data);
        parts.push(buf.length + ' bytes: ' + buf.toString('hex'));
      }
      return parts.join('');
    }
  }, {
    key: 'commandClass',
    get: function get() {
      return this.preamble[0];
    },
    set: function set(value) {
      this.preamble.writeUInt8(value, 0);
    }
  }, {
    key: 'instruction',
    get: function get() {
      return this.preamble[1];
    },
    set: function set(value) {
      this.preamble.writeUInt8(value, 1);
    }
  }, {
    key: 'p1',
    get: function get() {
      return this.preamble[2];
    },
    set: function set(value) {
      this.preamble.writeUInt8(value, 2);
    }
  }, {
    key: 'p2',
    get: function get() {
      return this.preamble[3];
    },
    set: function set(value) {
      this.preamble.writeUInt8(value, 3);
    }
  }]);

  return ApduCommand;
}();

exports.default = ApduCommand;
}).call(this,require("buffer").Buffer)
},{"buffer":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/buffer/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/tlvlib/build/lib/apdu/Response.js":[function(require,module,exports){
(function (Buffer){
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

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; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

var _ber = require('../ber');

var _ber2 = _interopRequireDefault(_ber);

var _TlvList = require('../TlvList');

var _TlvList2 = _interopRequireDefault(_TlvList);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

/**
 * An APDU response. The truth is this is a nonstandard implementation because we
 * assume the first byte is a "template identifier" as it is in Miura APDU responses,
 * and the rest of the payload is a tlv list. If you don't want that, just pad the
 * buffer with an extra byte at the beginning...
 */
var ApduResponse = function () {
  function ApduResponse(buffer) {
    var start = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
    var length = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : buffer.length - start;
    var isRaw = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;

    _classCallCheck(this, ApduResponse);

    if (Buffer.isBuffer(buffer)) {
      this.sw1 = buffer[start + length - 2];
      this.sw2 = buffer[start + length - 1];
      if (length === 2) {
        // Only a success value.
        return;
      }
      if (isRaw) {
        this.data = buffer.slice(start, start + length - 2);
      } else {
        this.template = buffer[start];
        var lenInfo = _ber2.default.readLength(buffer, start + 1);

        if (lenInfo.lengthValue !== length - 3 - lenInfo.lengthOfEncoding) {
          var buflen = length - 3 - lenInfo.lengthOfEncoding;
          var msg = 'Invalid ApduResponse length ' + lenInfo.lengthValue + ' vs buffer length ' + buflen;
          throw new Error(msg);
        }
        this.data = buffer.slice(start + 1 + lenInfo.lengthOfEncoding, start + length - 2);
      }
    } else if (buffer instanceof _TlvList2.default) {
      this._tlvs = buffer;
      this.data = buffer.toBytes();
      this.sw1 = 0x90;
      this.sw2 = 0;
    } else {
      // TODO create a blank response that can be added to
      throw new Error('You must provide a Buffer or TlvList to create an APDU response.');
    }
  }

  _createClass(ApduResponse, [{
    key: 'toString',
    value: function toString(shouldParse) {
      var parts = [];
      if (this.template) {
        parts.push('Template: 0x' + this.template.toString(16));
      }
      if (this.data) {
        parts.push('Data (' + this.data.length + ' bytes): 0x' + this.data.toString('hex'));
      }
      if (this._tlvs || shouldParse && this.tlvs) {
        parts.push(this.tlvs.toString(shouldParse));
      }
      parts.push('SW1: 0x' + this.sw1.toString(16) + ' SW2: 0x' + this.sw2.toString(16));
      return parts.join('\n');
    }
  }, {
    key: 'isSuccess',
    get: function get() {
      return this.sw1 === 0x90 && this.sw2 === 0;
    }
  }, {
    key: 'tlvs',
    get: function get() {
      if (!this._tlvs) {
        this._tlvs = new _TlvList2.default(this.data);
      }
      return this._tlvs;
    }
  }]);

  return ApduResponse;
}();

exports.default = ApduResponse;
}).call(this,{"isBuffer":require("../../../../../../is-buffer/index.js")})
},{"../../../../../../is-buffer/index.js":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/is-buffer/index.js","../TlvList":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/tlvlib/build/lib/TlvList.js","../ber":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/tlvlib/build/lib/ber.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/tlvlib/build/lib/ber.js":[function(require,module,exports){
(function (Buffer){
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = {
  /**
   * Read a tag from a buffer, including multi-byte tags
   * @param {Buffer} buffer The source buffer
   * @param startPosition The position at which to start reading the tag
   * @returns {{length: number, tag: Tag, rawTag: number}}
   */
  readTag: function readTag(buffer, startPosition) {
    var tag = {
      length: 1,
      number: 0
    };
    for (var index = startPosition; index < buffer.length; index++, tag.length++) {
      var t = buffer[index] & 0xff;
      tag.number = (tag.number << 8) + t;
      if (index === startPosition && (t & 0x1F) !== 0x1F) {
        break;
      } else if (index !== startPosition && (t & 0x80) === 0) {
        break;
      }
    }
    return tag;
  },

  /**
   * Return a binary representation of the tag
   * @param tagNumber either a numeric tag value or a DefinedTag object
   */
  encodeTag: function encodeTag(tag) {
    var tagNumber = tag.number || tag;
    var flipped = 0;
    var len = 0;
    while (tagNumber > 0) {
      len++;
      flipped = (flipped << 8) + (tagNumber & 0xFF);
      tagNumber = tagNumber >> 8;
    }
    var buf = new Buffer(len);
    var ix = 0;
    while (flipped > 0) {
      buf.writeUInt8(flipped & 0xFF, ix++);
      flipped = flipped >> 8;
    }
    return buf;
  },

  /**
   * Read a length value and return the value with the number of bytes used to encode
   * the value.
   * @param buffer
   * @param startPosition
   * @returns {{lengthOfEncoding: number, lengthValue: number}}
   */
  readLength: function readLength(buffer, startPosition) {
    var lenInfo = {
      lengthOfEncoding: 1,
      lengthValue: 0
    };
    var curPosition = startPosition;
    var first = buffer[curPosition++];
    if ((first & 0x80) === 0x80) {
      // Long form encoding
      var bytesOfLen = first & 0x7F;
      if (curPosition + bytesOfLen > buffer.length) {
        throw new Error('Malformed length value - not enough bytes.');
      }
      lenInfo.lengthOfEncoding = bytesOfLen + 1;
      for (var j = 0; j < bytesOfLen; j++) {
        lenInfo.lengthValue = (lenInfo.lengthValue << 8) + buffer[curPosition++];
      }
      if (lenInfo.lengthValue < 0) {
        throw new Error('Overflow in length value.');
      }
    } else {
      lenInfo.lengthValue = first;
    }
    return lenInfo;
  },

  /**
   * Return a binary representation of a length value
   * @param len
   * @returns {Buffer} buffer
   */
  encodeLength: function encodeLength(len) {
    if (len > 65535) {
      throw new Error('Invalid length for tlv format: ' + len);
    }
    var buf = void 0;
    if (len <= 127) {
      buf = new Buffer(1);
      buf.writeUInt8(len, 0);
    } else if (len > 0xFF) {
      // Three bytes total
      buf = new Buffer(3);
      buf.writeUInt8(0x82, 0);
      buf.writeUInt8(len >> 8 & 0xFF, 1);
      buf.writeUInt8(len & 0xFF, 2);
    } else {
      // Two bytes
      buf = new Buffer(2);
      buf.writeUInt8(0x81, 0);
      buf.writeUInt8(len & 0xFF, 1);
    }
    return buf;
  }
};
}).call(this,require("buffer").Buffer)
},{"buffer":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/buffer/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/moment/moment.js":[function(require,module,exports){
//! moment.js
//! version : 2.20.1
//! authors : Tim Wood, Iskren Chernev, Moment.js contributors
//! license : MIT
//! momentjs.com

;(function (global, factory) {
    typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
    typeof define === 'function' && define.amd ? define(factory) :
    global.moment = factory()
}(this, (function () { 'use strict';

var hookCallback;

function hooks () {
    return hookCallback.apply(null, arguments);
}

// This is done to register the method called with moment()
// without creating circular dependencies.
function setHookCallback (callback) {
    hookCallback = callback;
}

function isArray(input) {
    return input instanceof Array || Object.prototype.toString.call(input) === '[object Array]';
}

function isObject(input) {
    // IE8 will treat undefined and null as object if it wasn't for
    // input != null
    return input != null && Object.prototype.toString.call(input) === '[object Object]';
}

function isObjectEmpty(obj) {
    if (Object.getOwnPropertyNames) {
        return (Object.getOwnPropertyNames(obj).length === 0);
    } else {
        var k;
        for (k in obj) {
            if (obj.hasOwnProperty(k)) {
                return false;
            }
        }
        return true;
    }
}

function isUndefined(input) {
    return input === void 0;
}

function isNumber(input) {
    return typeof input === 'number' || Object.prototype.toString.call(input) === '[object Number]';
}

function isDate(input) {
    return input instanceof Date || Object.prototype.toString.call(input) === '[object Date]';
}

function map(arr, fn) {
    var res = [], i;
    for (i = 0; i < arr.length; ++i) {
        res.push(fn(arr[i], i));
    }
    return res;
}

function hasOwnProp(a, b) {
    return Object.prototype.hasOwnProperty.call(a, b);
}

function extend(a, b) {
    for (var i in b) {
        if (hasOwnProp(b, i)) {
            a[i] = b[i];
        }
    }

    if (hasOwnProp(b, 'toString')) {
        a.toString = b.toString;
    }

    if (hasOwnProp(b, 'valueOf')) {
        a.valueOf = b.valueOf;
    }

    return a;
}

function createUTC (input, format, locale, strict) {
    return createLocalOrUTC(input, format, locale, strict, true).utc();
}

function defaultParsingFlags() {
    // We need to deep clone this object.
    return {
        empty           : false,
        unusedTokens    : [],
        unusedInput     : [],
        overflow        : -2,
        charsLeftOver   : 0,
        nullInput       : false,
        invalidMonth    : null,
        invalidFormat   : false,
        userInvalidated : false,
        iso             : false,
        parsedDateParts : [],
        meridiem        : null,
        rfc2822         : false,
        weekdayMismatch : false
    };
}

function getParsingFlags(m) {
    if (m._pf == null) {
        m._pf = defaultParsingFlags();
    }
    return m._pf;
}

var some;
if (Array.prototype.some) {
    some = Array.prototype.some;
} else {
    some = function (fun) {
        var t = Object(this);
        var len = t.length >>> 0;

        for (var i = 0; i < len; i++) {
            if (i in t && fun.call(this, t[i], i, t)) {
                return true;
            }
        }

        return false;
    };
}

function isValid(m) {
    if (m._isValid == null) {
        var flags = getParsingFlags(m);
        var parsedParts = some.call(flags.parsedDateParts, function (i) {
            return i != null;
        });
        var isNowValid = !isNaN(m._d.getTime()) &&
            flags.overflow < 0 &&
            !flags.empty &&
            !flags.invalidMonth &&
            !flags.invalidWeekday &&
            !flags.weekdayMismatch &&
            !flags.nullInput &&
            !flags.invalidFormat &&
            !flags.userInvalidated &&
            (!flags.meridiem || (flags.meridiem && parsedParts));

        if (m._strict) {
            isNowValid = isNowValid &&
                flags.charsLeftOver === 0 &&
                flags.unusedTokens.length === 0 &&
                flags.bigHour === undefined;
        }

        if (Object.isFrozen == null || !Object.isFrozen(m)) {
            m._isValid = isNowValid;
        }
        else {
            return isNowValid;
        }
    }
    return m._isValid;
}

function createInvalid (flags) {
    var m = createUTC(NaN);
    if (flags != null) {
        extend(getParsingFlags(m), flags);
    }
    else {
        getParsingFlags(m).userInvalidated = true;
    }

    return m;
}

// Plugins that add properties should also add the key here (null value),
// so we can properly clone ourselves.
var momentProperties = hooks.momentProperties = [];

function copyConfig(to, from) {
    var i, prop, val;

    if (!isUndefined(from._isAMomentObject)) {
        to._isAMomentObject = from._isAMomentObject;
    }
    if (!isUndefined(from._i)) {
        to._i = from._i;
    }
    if (!isUndefined(from._f)) {
        to._f = from._f;
    }
    if (!isUndefined(from._l)) {
        to._l = from._l;
    }
    if (!isUndefined(from._strict)) {
        to._strict = from._strict;
    }
    if (!isUndefined(from._tzm)) {
        to._tzm = from._tzm;
    }
    if (!isUndefined(from._isUTC)) {
        to._isUTC = from._isUTC;
    }
    if (!isUndefined(from._offset)) {
        to._offset = from._offset;
    }
    if (!isUndefined(from._pf)) {
        to._pf = getParsingFlags(from);
    }
    if (!isUndefined(from._locale)) {
        to._locale = from._locale;
    }

    if (momentProperties.length > 0) {
        for (i = 0; i < momentProperties.length; i++) {
            prop = momentProperties[i];
            val = from[prop];
            if (!isUndefined(val)) {
                to[prop] = val;
            }
        }
    }

    return to;
}

var updateInProgress = false;

// Moment prototype object
function Moment(config) {
    copyConfig(this, config);
    this._d = new Date(config._d != null ? config._d.getTime() : NaN);
    if (!this.isValid()) {
        this._d = new Date(NaN);
    }
    // Prevent infinite loop in case updateOffset creates new moment
    // objects.
    if (updateInProgress === false) {
        updateInProgress = true;
        hooks.updateOffset(this);
        updateInProgress = false;
    }
}

function isMoment (obj) {
    return obj instanceof Moment || (obj != null && obj._isAMomentObject != null);
}

function absFloor (number) {
    if (number < 0) {
        // -0 -> 0
        return Math.ceil(number) || 0;
    } else {
        return Math.floor(number);
    }
}

function toInt(argumentForCoercion) {
    var coercedNumber = +argumentForCoercion,
        value = 0;

    if (coercedNumber !== 0 && isFinite(coercedNumber)) {
        value = absFloor(coercedNumber);
    }

    return value;
}

// compare two arrays, return the number of differences
function compareArrays(array1, array2, dontConvert) {
    var len = Math.min(array1.length, array2.length),
        lengthDiff = Math.abs(array1.length - array2.length),
        diffs = 0,
        i;
    for (i = 0; i < len; i++) {
        if ((dontConvert && array1[i] !== array2[i]) ||
            (!dontConvert && toInt(array1[i]) !== toInt(array2[i]))) {
            diffs++;
        }
    }
    return diffs + lengthDiff;
}

function warn(msg) {
    if (hooks.suppressDeprecationWarnings === false &&
            (typeof console !==  'undefined') && console.warn) {
        console.warn('Deprecation warning: ' + msg);
    }
}

function deprecate(msg, fn) {
    var firstTime = true;

    return extend(function () {
        if (hooks.deprecationHandler != null) {
            hooks.deprecationHandler(null, msg);
        }
        if (firstTime) {
            var args = [];
            var arg;
            for (var i = 0; i < arguments.length; i++) {
                arg = '';
                if (typeof arguments[i] === 'object') {
                    arg += '\n[' + i + '] ';
                    for (var key in arguments[0]) {
                        arg += key + ': ' + arguments[0][key] + ', ';
                    }
                    arg = arg.slice(0, -2); // Remove trailing comma and space
                } else {
                    arg = arguments[i];
                }
                args.push(arg);
            }
            warn(msg + '\nArguments: ' + Array.prototype.slice.call(args).join('') + '\n' + (new Error()).stack);
            firstTime = false;
        }
        return fn.apply(this, arguments);
    }, fn);
}

var deprecations = {};

function deprecateSimple(name, msg) {
    if (hooks.deprecationHandler != null) {
        hooks.deprecationHandler(name, msg);
    }
    if (!deprecations[name]) {
        warn(msg);
        deprecations[name] = true;
    }
}

hooks.suppressDeprecationWarnings = false;
hooks.deprecationHandler = null;

function isFunction(input) {
    return input instanceof Function || Object.prototype.toString.call(input) === '[object Function]';
}

function set (config) {
    var prop, i;
    for (i in config) {
        prop = config[i];
        if (isFunction(prop)) {
            this[i] = prop;
        } else {
            this['_' + i] = prop;
        }
    }
    this._config = config;
    // Lenient ordinal parsing accepts just a number in addition to
    // number + (possibly) stuff coming from _dayOfMonthOrdinalParse.
    // TODO: Remove "ordinalParse" fallback in next major release.
    this._dayOfMonthOrdinalParseLenient = new RegExp(
        (this._dayOfMonthOrdinalParse.source || this._ordinalParse.source) +
            '|' + (/\d{1,2}/).source);
}

function mergeConfigs(parentConfig, childConfig) {
    var res = extend({}, parentConfig), prop;
    for (prop in childConfig) {
        if (hasOwnProp(childConfig, prop)) {
            if (isObject(parentConfig[prop]) && isObject(childConfig[prop])) {
                res[prop] = {};
                extend(res[prop], parentConfig[prop]);
                extend(res[prop], childConfig[prop]);
            } else if (childConfig[prop] != null) {
                res[prop] = childConfig[prop];
            } else {
                delete res[prop];
            }
        }
    }
    for (prop in parentConfig) {
        if (hasOwnProp(parentConfig, prop) &&
                !hasOwnProp(childConfig, prop) &&
                isObject(parentConfig[prop])) {
            // make sure changes to properties don't modify parent config
            res[prop] = extend({}, res[prop]);
        }
    }
    return res;
}

function Locale(config) {
    if (config != null) {
        this.set(config);
    }
}

var keys;

if (Object.keys) {
    keys = Object.keys;
} else {
    keys = function (obj) {
        var i, res = [];
        for (i in obj) {
            if (hasOwnProp(obj, i)) {
                res.push(i);
            }
        }
        return res;
    };
}

var defaultCalendar = {
    sameDay : '[Today at] LT',
    nextDay : '[Tomorrow at] LT',
    nextWeek : 'dddd [at] LT',
    lastDay : '[Yesterday at] LT',
    lastWeek : '[Last] dddd [at] LT',
    sameElse : 'L'
};

function calendar (key, mom, now) {
    var output = this._calendar[key] || this._calendar['sameElse'];
    return isFunction(output) ? output.call(mom, now) : output;
}

var defaultLongDateFormat = {
    LTS  : 'h:mm:ss A',
    LT   : 'h:mm A',
    L    : 'MM/DD/YYYY',
    LL   : 'MMMM D, YYYY',
    LLL  : 'MMMM D, YYYY h:mm A',
    LLLL : 'dddd, MMMM D, YYYY h:mm A'
};

function longDateFormat (key) {
    var format = this._longDateFormat[key],
        formatUpper = this._longDateFormat[key.toUpperCase()];

    if (format || !formatUpper) {
        return format;
    }

    this._longDateFormat[key] = formatUpper.replace(/MMMM|MM|DD|dddd/g, function (val) {
        return val.slice(1);
    });

    return this._longDateFormat[key];
}

var defaultInvalidDate = 'Invalid date';

function invalidDate () {
    return this._invalidDate;
}

var defaultOrdinal = '%d';
var defaultDayOfMonthOrdinalParse = /\d{1,2}/;

function ordinal (number) {
    return this._ordinal.replace('%d', number);
}

var defaultRelativeTime = {
    future : 'in %s',
    past   : '%s ago',
    s  : 'a few seconds',
    ss : '%d seconds',
    m  : 'a minute',
    mm : '%d minutes',
    h  : 'an hour',
    hh : '%d hours',
    d  : 'a day',
    dd : '%d days',
    M  : 'a month',
    MM : '%d months',
    y  : 'a year',
    yy : '%d years'
};

function relativeTime (number, withoutSuffix, string, isFuture) {
    var output = this._relativeTime[string];
    return (isFunction(output)) ?
        output(number, withoutSuffix, string, isFuture) :
        output.replace(/%d/i, number);
}

function pastFuture (diff, output) {
    var format = this._relativeTime[diff > 0 ? 'future' : 'past'];
    return isFunction(format) ? format(output) : format.replace(/%s/i, output);
}

var aliases = {};

function addUnitAlias (unit, shorthand) {
    var lowerCase = unit.toLowerCase();
    aliases[lowerCase] = aliases[lowerCase + 's'] = aliases[shorthand] = unit;
}

function normalizeUnits(units) {
    return typeof units === 'string' ? aliases[units] || aliases[units.toLowerCase()] : undefined;
}

function normalizeObjectUnits(inputObject) {
    var normalizedInput = {},
        normalizedProp,
        prop;

    for (prop in inputObject) {
        if (hasOwnProp(inputObject, prop)) {
            normalizedProp = normalizeUnits(prop);
            if (normalizedProp) {
                normalizedInput[normalizedProp] = inputObject[prop];
            }
        }
    }

    return normalizedInput;
}

var priorities = {};

function addUnitPriority(unit, priority) {
    priorities[unit] = priority;
}

function getPrioritizedUnits(unitsObj) {
    var units = [];
    for (var u in unitsObj) {
        units.push({unit: u, priority: priorities[u]});
    }
    units.sort(function (a, b) {
        return a.priority - b.priority;
    });
    return units;
}

function zeroFill(number, targetLength, forceSign) {
    var absNumber = '' + Math.abs(number),
        zerosToFill = targetLength - absNumber.length,
        sign = number >= 0;
    return (sign ? (forceSign ? '+' : '') : '-') +
        Math.pow(10, Math.max(0, zerosToFill)).toString().substr(1) + absNumber;
}

var formattingTokens = /(\[[^\[]*\])|(\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g;

var localFormattingTokens = /(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g;

var formatFunctions = {};

var formatTokenFunctions = {};

// token:    'M'
// padded:   ['MM', 2]
// ordinal:  'Mo'
// callback: function () { this.month() + 1 }
function addFormatToken (token, padded, ordinal, callback) {
    var func = callback;
    if (typeof callback === 'string') {
        func = function () {
            return this[callback]();
        };
    }
    if (token) {
        formatTokenFunctions[token] = func;
    }
    if (padded) {
        formatTokenFunctions[padded[0]] = function () {
            return zeroFill(func.apply(this, arguments), padded[1], padded[2]);
        };
    }
    if (ordinal) {
        formatTokenFunctions[ordinal] = function () {
            return this.localeData().ordinal(func.apply(this, arguments), token);
        };
    }
}

function removeFormattingTokens(input) {
    if (input.match(/\[[\s\S]/)) {
        return input.replace(/^\[|\]$/g, '');
    }
    return input.replace(/\\/g, '');
}

function makeFormatFunction(format) {
    var array = format.match(formattingTokens), i, length;

    for (i = 0, length = array.length; i < length; i++) {
        if (formatTokenFunctions[array[i]]) {
            array[i] = formatTokenFunctions[array[i]];
        } else {
            array[i] = removeFormattingTokens(array[i]);
        }
    }

    return function (mom) {
        var output = '', i;
        for (i = 0; i < length; i++) {
            output += isFunction(array[i]) ? array[i].call(mom, format) : array[i];
        }
        return output;
    };
}

// format date using native date object
function formatMoment(m, format) {
    if (!m.isValid()) {
        return m.localeData().invalidDate();
    }

    format = expandFormat(format, m.localeData());
    formatFunctions[format] = formatFunctions[format] || makeFormatFunction(format);

    return formatFunctions[format](m);
}

function expandFormat(format, locale) {
    var i = 5;

    function replaceLongDateFormatTokens(input) {
        return locale.longDateFormat(input) || input;
    }

    localFormattingTokens.lastIndex = 0;
    while (i >= 0 && localFormattingTokens.test(format)) {
        format = format.replace(localFormattingTokens, replaceLongDateFormatTokens);
        localFormattingTokens.lastIndex = 0;
        i -= 1;
    }

    return format;
}

var match1         = /\d/;            //       0 - 9
var match2         = /\d\d/;          //      00 - 99
var match3         = /\d{3}/;         //     000 - 999
var match4         = /\d{4}/;         //    0000 - 9999
var match6         = /[+-]?\d{6}/;    // -999999 - 999999
var match1to2      = /\d\d?/;         //       0 - 99
var match3to4      = /\d\d\d\d?/;     //     999 - 9999
var match5to6      = /\d\d\d\d\d\d?/; //   99999 - 999999
var match1to3      = /\d{1,3}/;       //       0 - 999
var match1to4      = /\d{1,4}/;       //       0 - 9999
var match1to6      = /[+-]?\d{1,6}/;  // -999999 - 999999

var matchUnsigned  = /\d+/;           //       0 - inf
var matchSigned    = /[+-]?\d+/;      //    -inf - inf

var matchOffset    = /Z|[+-]\d\d:?\d\d/gi; // +00:00 -00:00 +0000 -0000 or Z
var matchShortOffset = /Z|[+-]\d\d(?::?\d\d)?/gi; // +00 -00 +00:00 -00:00 +0000 -0000 or Z

var matchTimestamp = /[+-]?\d+(\.\d{1,3})?/; // 123456789 123456789.123

// any word (or two) characters or numbers including two/three word month in arabic.
// includes scottish gaelic two word and hyphenated months
var matchWord = /[0-9]{0,256}['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFF07\uFF10-\uFFEF]{1,256}|[\u0600-\u06FF\/]{1,256}(\s*?[\u0600-\u06FF]{1,256}){1,2}/i;


var regexes = {};

function addRegexToken (token, regex, strictRegex) {
    regexes[token] = isFunction(regex) ? regex : function (isStrict, localeData) {
        return (isStrict && strictRegex) ? strictRegex : regex;
    };
}

function getParseRegexForToken (token, config) {
    if (!hasOwnProp(regexes, token)) {
        return new RegExp(unescapeFormat(token));
    }

    return regexes[token](config._strict, config._locale);
}

// Code from http://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript
function unescapeFormat(s) {
    return regexEscape(s.replace('\\', '').replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g, function (matched, p1, p2, p3, p4) {
        return p1 || p2 || p3 || p4;
    }));
}

function regexEscape(s) {
    return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
}

var tokens = {};

function addParseToken (token, callback) {
    var i, func = callback;
    if (typeof token === 'string') {
        token = [token];
    }
    if (isNumber(callback)) {
        func = function (input, array) {
            array[callback] = toInt(input);
        };
    }
    for (i = 0; i < token.length; i++) {
        tokens[token[i]] = func;
    }
}

function addWeekParseToken (token, callback) {
    addParseToken(token, function (input, array, config, token) {
        config._w = config._w || {};
        callback(input, config._w, config, token);
    });
}

function addTimeToArrayFromToken(token, input, config) {
    if (input != null && hasOwnProp(tokens, token)) {
        tokens[token](input, config._a, config, token);
    }
}

var YEAR = 0;
var MONTH = 1;
var DATE = 2;
var HOUR = 3;
var MINUTE = 4;
var SECOND = 5;
var MILLISECOND = 6;
var WEEK = 7;
var WEEKDAY = 8;

// FORMATTING

addFormatToken('Y', 0, 0, function () {
    var y = this.year();
    return y <= 9999 ? '' + y : '+' + y;
});

addFormatToken(0, ['YY', 2], 0, function () {
    return this.year() % 100;
});

addFormatToken(0, ['YYYY',   4],       0, 'year');
addFormatToken(0, ['YYYYY',  5],       0, 'year');
addFormatToken(0, ['YYYYYY', 6, true], 0, 'year');

// ALIASES

addUnitAlias('year', 'y');

// PRIORITIES

addUnitPriority('year', 1);

// PARSING

addRegexToken('Y',      matchSigned);
addRegexToken('YY',     match1to2, match2);
addRegexToken('YYYY',   match1to4, match4);
addRegexToken('YYYYY',  match1to6, match6);
addRegexToken('YYYYYY', match1to6, match6);

addParseToken(['YYYYY', 'YYYYYY'], YEAR);
addParseToken('YYYY', function (input, array) {
    array[YEAR] = input.length === 2 ? hooks.parseTwoDigitYear(input) : toInt(input);
});
addParseToken('YY', function (input, array) {
    array[YEAR] = hooks.parseTwoDigitYear(input);
});
addParseToken('Y', function (input, array) {
    array[YEAR] = parseInt(input, 10);
});

// HELPERS

function daysInYear(year) {
    return isLeapYear(year) ? 366 : 365;
}

function isLeapYear(year) {
    return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;
}

// HOOKS

hooks.parseTwoDigitYear = function (input) {
    return toInt(input) + (toInt(input) > 68 ? 1900 : 2000);
};

// MOMENTS

var getSetYear = makeGetSet('FullYear', true);

function getIsLeapYear () {
    return isLeapYear(this.year());
}

function makeGetSet (unit, keepTime) {
    return function (value) {
        if (value != null) {
            set$1(this, unit, value);
            hooks.updateOffset(this, keepTime);
            return this;
        } else {
            return get(this, unit);
        }
    };
}

function get (mom, unit) {
    return mom.isValid() ?
        mom._d['get' + (mom._isUTC ? 'UTC' : '') + unit]() : NaN;
}

function set$1 (mom, unit, value) {
    if (mom.isValid() && !isNaN(value)) {
        if (unit === 'FullYear' && isLeapYear(mom.year()) && mom.month() === 1 && mom.date() === 29) {
            mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value, mom.month(), daysInMonth(value, mom.month()));
        }
        else {
            mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value);
        }
    }
}

// MOMENTS

function stringGet (units) {
    units = normalizeUnits(units);
    if (isFunction(this[units])) {
        return this[units]();
    }
    return this;
}


function stringSet (units, value) {
    if (typeof units === 'object') {
        units = normalizeObjectUnits(units);
        var prioritized = getPrioritizedUnits(units);
        for (var i = 0; i < prioritized.length; i++) {
            this[prioritized[i].unit](units[prioritized[i].unit]);
        }
    } else {
        units = normalizeUnits(units);
        if (isFunction(this[units])) {
            return this[units](value);
        }
    }
    return this;
}

function mod(n, x) {
    return ((n % x) + x) % x;
}

var indexOf;

if (Array.prototype.indexOf) {
    indexOf = Array.prototype.indexOf;
} else {
    indexOf = function (o) {
        // I know
        var i;
        for (i = 0; i < this.length; ++i) {
            if (this[i] === o) {
                return i;
            }
        }
        return -1;
    };
}

function daysInMonth(year, month) {
    if (isNaN(year) || isNaN(month)) {
        return NaN;
    }
    var modMonth = mod(month, 12);
    year += (month - modMonth) / 12;
    return modMonth === 1 ? (isLeapYear(year) ? 29 : 28) : (31 - modMonth % 7 % 2);
}

// FORMATTING

addFormatToken('M', ['MM', 2], 'Mo', function () {
    return this.month() + 1;
});

addFormatToken('MMM', 0, 0, function (format) {
    return this.localeData().monthsShort(this, format);
});

addFormatToken('MMMM', 0, 0, function (format) {
    return this.localeData().months(this, format);
});

// ALIASES

addUnitAlias('month', 'M');

// PRIORITY

addUnitPriority('month', 8);

// PARSING

addRegexToken('M',    match1to2);
addRegexToken('MM',   match1to2, match2);
addRegexToken('MMM',  function (isStrict, locale) {
    return locale.monthsShortRegex(isStrict);
});
addRegexToken('MMMM', function (isStrict, locale) {
    return locale.monthsRegex(isStrict);
});

addParseToken(['M', 'MM'], function (input, array) {
    array[MONTH] = toInt(input) - 1;
});

addParseToken(['MMM', 'MMMM'], function (input, array, config, token) {
    var month = config._locale.monthsParse(input, token, config._strict);
    // if we didn't find a month name, mark the date as invalid.
    if (month != null) {
        array[MONTH] = month;
    } else {
        getParsingFlags(config).invalidMonth = input;
    }
});

// LOCALES

var MONTHS_IN_FORMAT = /D[oD]?(\[[^\[\]]*\]|\s)+MMMM?/;
var defaultLocaleMonths = 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_');
function localeMonths (m, format) {
    if (!m) {
        return isArray(this._months) ? this._months :
            this._months['standalone'];
    }
    return isArray(this._months) ? this._months[m.month()] :
        this._months[(this._months.isFormat || MONTHS_IN_FORMAT).test(format) ? 'format' : 'standalone'][m.month()];
}

var defaultLocaleMonthsShort = 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_');
function localeMonthsShort (m, format) {
    if (!m) {
        return isArray(this._monthsShort) ? this._monthsShort :
            this._monthsShort['standalone'];
    }
    return isArray(this._monthsShort) ? this._monthsShort[m.month()] :
        this._monthsShort[MONTHS_IN_FORMAT.test(format) ? 'format' : 'standalone'][m.month()];
}

function handleStrictParse(monthName, format, strict) {
    var i, ii, mom, llc = monthName.toLocaleLowerCase();
    if (!this._monthsParse) {
        // this is not used
        this._monthsParse = [];
        this._longMonthsParse = [];
        this._shortMonthsParse = [];
        for (i = 0; i < 12; ++i) {
            mom = createUTC([2000, i]);
            this._shortMonthsParse[i] = this.monthsShort(mom, '').toLocaleLowerCase();
            this._longMonthsParse[i] = this.months(mom, '').toLocaleLowerCase();
        }
    }

    if (strict) {
        if (format === 'MMM') {
            ii = indexOf.call(this._shortMonthsParse, llc);
            return ii !== -1 ? ii : null;
        } else {
            ii = indexOf.call(this._longMonthsParse, llc);
            return ii !== -1 ? ii : null;
        }
    } else {
        if (format === 'MMM') {
            ii = indexOf.call(this._shortMonthsParse, llc);
            if (ii !== -1) {
                return ii;
            }
            ii = indexOf.call(this._longMonthsParse, llc);
            return ii !== -1 ? ii : null;
        } else {
            ii = indexOf.call(this._longMonthsParse, llc);
            if (ii !== -1) {
                return ii;
            }
            ii = indexOf.call(this._shortMonthsParse, llc);
            return ii !== -1 ? ii : null;
        }
    }
}

function localeMonthsParse (monthName, format, strict) {
    var i, mom, regex;

    if (this._monthsParseExact) {
        return handleStrictParse.call(this, monthName, format, strict);
    }

    if (!this._monthsParse) {
        this._monthsParse = [];
        this._longMonthsParse = [];
        this._shortMonthsParse = [];
    }

    // TODO: add sorting
    // Sorting makes sure if one month (or abbr) is a prefix of another
    // see sorting in computeMonthsParse
    for (i = 0; i < 12; i++) {
        // make the regex if we don't have it already
        mom = createUTC([2000, i]);
        if (strict && !this._longMonthsParse[i]) {
            this._longMonthsParse[i] = new RegExp('^' + this.months(mom, '').replace('.', '') + '$', 'i');
            this._shortMonthsParse[i] = new RegExp('^' + this.monthsShort(mom, '').replace('.', '') + '$', 'i');
        }
        if (!strict && !this._monthsParse[i]) {
            regex = '^' + this.months(mom, '') + '|^' + this.monthsShort(mom, '');
            this._monthsParse[i] = new RegExp(regex.replace('.', ''), 'i');
        }
        // test the regex
        if (strict && format === 'MMMM' && this._longMonthsParse[i].test(monthName)) {
            return i;
        } else if (strict && format === 'MMM' && this._shortMonthsParse[i].test(monthName)) {
            return i;
        } else if (!strict && this._monthsParse[i].test(monthName)) {
            return i;
        }
    }
}

// MOMENTS

function setMonth (mom, value) {
    var dayOfMonth;

    if (!mom.isValid()) {
        // No op
        return mom;
    }

    if (typeof value === 'string') {
        if (/^\d+$/.test(value)) {
            value = toInt(value);
        } else {
            value = mom.localeData().monthsParse(value);
            // TODO: Another silent failure?
            if (!isNumber(value)) {
                return mom;
            }
        }
    }

    dayOfMonth = Math.min(mom.date(), daysInMonth(mom.year(), value));
    mom._d['set' + (mom._isUTC ? 'UTC' : '') + 'Month'](value, dayOfMonth);
    return mom;
}

function getSetMonth (value) {
    if (value != null) {
        setMonth(this, value);
        hooks.updateOffset(this, true);
        return this;
    } else {
        return get(this, 'Month');
    }
}

function getDaysInMonth () {
    return daysInMonth(this.year(), this.month());
}

var defaultMonthsShortRegex = matchWord;
function monthsShortRegex (isStrict) {
    if (this._monthsParseExact) {
        if (!hasOwnProp(this, '_monthsRegex')) {
            computeMonthsParse.call(this);
        }
        if (isStrict) {
            return this._monthsShortStrictRegex;
        } else {
            return this._monthsShortRegex;
        }
    } else {
        if (!hasOwnProp(this, '_monthsShortRegex')) {
            this._monthsShortRegex = defaultMonthsShortRegex;
        }
        return this._monthsShortStrictRegex && isStrict ?
            this._monthsShortStrictRegex : this._monthsShortRegex;
    }
}

var defaultMonthsRegex = matchWord;
function monthsRegex (isStrict) {
    if (this._monthsParseExact) {
        if (!hasOwnProp(this, '_monthsRegex')) {
            computeMonthsParse.call(this);
        }
        if (isStrict) {
            return this._monthsStrictRegex;
        } else {
            return this._monthsRegex;
        }
    } else {
        if (!hasOwnProp(this, '_monthsRegex')) {
            this._monthsRegex = defaultMonthsRegex;
        }
        return this._monthsStrictRegex && isStrict ?
            this._monthsStrictRegex : this._monthsRegex;
    }
}

function computeMonthsParse () {
    function cmpLenRev(a, b) {
        return b.length - a.length;
    }

    var shortPieces = [], longPieces = [], mixedPieces = [],
        i, mom;
    for (i = 0; i < 12; i++) {
        // make the regex if we don't have it already
        mom = createUTC([2000, i]);
        shortPieces.push(this.monthsShort(mom, ''));
        longPieces.push(this.months(mom, ''));
        mixedPieces.push(this.months(mom, ''));
        mixedPieces.push(this.monthsShort(mom, ''));
    }
    // Sorting makes sure if one month (or abbr) is a prefix of another it
    // will match the longer piece.
    shortPieces.sort(cmpLenRev);
    longPieces.sort(cmpLenRev);
    mixedPieces.sort(cmpLenRev);
    for (i = 0; i < 12; i++) {
        shortPieces[i] = regexEscape(shortPieces[i]);
        longPieces[i] = regexEscape(longPieces[i]);
    }
    for (i = 0; i < 24; i++) {
        mixedPieces[i] = regexEscape(mixedPieces[i]);
    }

    this._monthsRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');
    this._monthsShortRegex = this._monthsRegex;
    this._monthsStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i');
    this._monthsShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i');
}

function createDate (y, m, d, h, M, s, ms) {
    // can't just apply() to create a date:
    // https://stackoverflow.com/q/181348
    var date = new Date(y, m, d, h, M, s, ms);

    // the date constructor remaps years 0-99 to 1900-1999
    if (y < 100 && y >= 0 && isFinite(date.getFullYear())) {
        date.setFullYear(y);
    }
    return date;
}

function createUTCDate (y) {
    var date = new Date(Date.UTC.apply(null, arguments));

    // the Date.UTC function remaps years 0-99 to 1900-1999
    if (y < 100 && y >= 0 && isFinite(date.getUTCFullYear())) {
        date.setUTCFullYear(y);
    }
    return date;
}

// start-of-first-week - start-of-year
function firstWeekOffset(year, dow, doy) {
    var // first-week day -- which january is always in the first week (4 for iso, 1 for other)
        fwd = 7 + dow - doy,
        // first-week day local weekday -- which local weekday is fwd
        fwdlw = (7 + createUTCDate(year, 0, fwd).getUTCDay() - dow) % 7;

    return -fwdlw + fwd - 1;
}

// https://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday
function dayOfYearFromWeeks(year, week, weekday, dow, doy) {
    var localWeekday = (7 + weekday - dow) % 7,
        weekOffset = firstWeekOffset(year, dow, doy),
        dayOfYear = 1 + 7 * (week - 1) + localWeekday + weekOffset,
        resYear, resDayOfYear;

    if (dayOfYear <= 0) {
        resYear = year - 1;
        resDayOfYear = daysInYear(resYear) + dayOfYear;
    } else if (dayOfYear > daysInYear(year)) {
        resYear = year + 1;
        resDayOfYear = dayOfYear - daysInYear(year);
    } else {
        resYear = year;
        resDayOfYear = dayOfYear;
    }

    return {
        year: resYear,
        dayOfYear: resDayOfYear
    };
}

function weekOfYear(mom, dow, doy) {
    var weekOffset = firstWeekOffset(mom.year(), dow, doy),
        week = Math.floor((mom.dayOfYear() - weekOffset - 1) / 7) + 1,
        resWeek, resYear;

    if (week < 1) {
        resYear = mom.year() - 1;
        resWeek = week + weeksInYear(resYear, dow, doy);
    } else if (week > weeksInYear(mom.year(), dow, doy)) {
        resWeek = week - weeksInYear(mom.year(), dow, doy);
        resYear = mom.year() + 1;
    } else {
        resYear = mom.year();
        resWeek = week;
    }

    return {
        week: resWeek,
        year: resYear
    };
}

function weeksInYear(year, dow, doy) {
    var weekOffset = firstWeekOffset(year, dow, doy),
        weekOffsetNext = firstWeekOffset(year + 1, dow, doy);
    return (daysInYear(year) - weekOffset + weekOffsetNext) / 7;
}

// FORMATTING

addFormatToken('w', ['ww', 2], 'wo', 'week');
addFormatToken('W', ['WW', 2], 'Wo', 'isoWeek');

// ALIASES

addUnitAlias('week', 'w');
addUnitAlias('isoWeek', 'W');

// PRIORITIES

addUnitPriority('week', 5);
addUnitPriority('isoWeek', 5);

// PARSING

addRegexToken('w',  match1to2);
addRegexToken('ww', match1to2, match2);
addRegexToken('W',  match1to2);
addRegexToken('WW', match1to2, match2);

addWeekParseToken(['w', 'ww', 'W', 'WW'], function (input, week, config, token) {
    week[token.substr(0, 1)] = toInt(input);
});

// HELPERS

// LOCALES

function localeWeek (mom) {
    return weekOfYear(mom, this._week.dow, this._week.doy).week;
}

var defaultLocaleWeek = {
    dow : 0, // Sunday is the first day of the week.
    doy : 6  // The week that contains Jan 1st is the first week of the year.
};

function localeFirstDayOfWeek () {
    return this._week.dow;
}

function localeFirstDayOfYear () {
    return this._week.doy;
}

// MOMENTS

function getSetWeek (input) {
    var week = this.localeData().week(this);
    return input == null ? week : this.add((input - week) * 7, 'd');
}

function getSetISOWeek (input) {
    var week = weekOfYear(this, 1, 4).week;
    return input == null ? week : this.add((input - week) * 7, 'd');
}

// FORMATTING

addFormatToken('d', 0, 'do', 'day');

addFormatToken('dd', 0, 0, function (format) {
    return this.localeData().weekdaysMin(this, format);
});

addFormatToken('ddd', 0, 0, function (format) {
    return this.localeData().weekdaysShort(this, format);
});

addFormatToken('dddd', 0, 0, function (format) {
    return this.localeData().weekdays(this, format);
});

addFormatToken('e', 0, 0, 'weekday');
addFormatToken('E', 0, 0, 'isoWeekday');

// ALIASES

addUnitAlias('day', 'd');
addUnitAlias('weekday', 'e');
addUnitAlias('isoWeekday', 'E');

// PRIORITY
addUnitPriority('day', 11);
addUnitPriority('weekday', 11);
addUnitPriority('isoWeekday', 11);

// PARSING

addRegexToken('d',    match1to2);
addRegexToken('e',    match1to2);
addRegexToken('E',    match1to2);
addRegexToken('dd',   function (isStrict, locale) {
    return locale.weekdaysMinRegex(isStrict);
});
addRegexToken('ddd',   function (isStrict, locale) {
    return locale.weekdaysShortRegex(isStrict);
});
addRegexToken('dddd',   function (isStrict, locale) {
    return locale.weekdaysRegex(isStrict);
});

addWeekParseToken(['dd', 'ddd', 'dddd'], function (input, week, config, token) {
    var weekday = config._locale.weekdaysParse(input, token, config._strict);
    // if we didn't get a weekday name, mark the date as invalid
    if (weekday != null) {
        week.d = weekday;
    } else {
        getParsingFlags(config).invalidWeekday = input;
    }
});

addWeekParseToken(['d', 'e', 'E'], function (input, week, config, token) {
    week[token] = toInt(input);
});

// HELPERS

function parseWeekday(input, locale) {
    if (typeof input !== 'string') {
        return input;
    }

    if (!isNaN(input)) {
        return parseInt(input, 10);
    }

    input = locale.weekdaysParse(input);
    if (typeof input === 'number') {
        return input;
    }

    return null;
}

function parseIsoWeekday(input, locale) {
    if (typeof input === 'string') {
        return locale.weekdaysParse(input) % 7 || 7;
    }
    return isNaN(input) ? null : input;
}

// LOCALES

var defaultLocaleWeekdays = 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_');
function localeWeekdays (m, format) {
    if (!m) {
        return isArray(this._weekdays) ? this._weekdays :
            this._weekdays['standalone'];
    }
    return isArray(this._weekdays) ? this._weekdays[m.day()] :
        this._weekdays[this._weekdays.isFormat.test(format) ? 'format' : 'standalone'][m.day()];
}

var defaultLocaleWeekdaysShort = 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_');
function localeWeekdaysShort (m) {
    return (m) ? this._weekdaysShort[m.day()] : this._weekdaysShort;
}

var defaultLocaleWeekdaysMin = 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_');
function localeWeekdaysMin (m) {
    return (m) ? this._weekdaysMin[m.day()] : this._weekdaysMin;
}

function handleStrictParse$1(weekdayName, format, strict) {
    var i, ii, mom, llc = weekdayName.toLocaleLowerCase();
    if (!this._weekdaysParse) {
        this._weekdaysParse = [];
        this._shortWeekdaysParse = [];
        this._minWeekdaysParse = [];

        for (i = 0; i < 7; ++i) {
            mom = createUTC([2000, 1]).day(i);
            this._minWeekdaysParse[i] = this.weekdaysMin(mom, '').toLocaleLowerCase();
            this._shortWeekdaysParse[i] = this.weekdaysShort(mom, '').toLocaleLowerCase();
            this._weekdaysParse[i] = this.weekdays(mom, '').toLocaleLowerCase();
        }
    }

    if (strict) {
        if (format === 'dddd') {
            ii = indexOf.call(this._weekdaysParse, llc);
            return ii !== -1 ? ii : null;
        } else if (format === 'ddd') {
            ii = indexOf.call(this._shortWeekdaysParse, llc);
            return ii !== -1 ? ii : null;
        } else {
            ii = indexOf.call(this._minWeekdaysParse, llc);
            return ii !== -1 ? ii : null;
        }
    } else {
        if (format === 'dddd') {
            ii = indexOf.call(this._weekdaysParse, llc);
            if (ii !== -1) {
                return ii;
            }
            ii = indexOf.call(this._shortWeekdaysParse, llc);
            if (ii !== -1) {
                return ii;
            }
            ii = indexOf.call(this._minWeekdaysParse, llc);
            return ii !== -1 ? ii : null;
        } else if (format === 'ddd') {
            ii = indexOf.call(this._shortWeekdaysParse, llc);
            if (ii !== -1) {
                return ii;
            }
            ii = indexOf.call(this._weekdaysParse, llc);
            if (ii !== -1) {
                return ii;
            }
            ii = indexOf.call(this._minWeekdaysParse, llc);
            return ii !== -1 ? ii : null;
        } else {
            ii = indexOf.call(this._minWeekdaysParse, llc);
            if (ii !== -1) {
                return ii;
            }
            ii = indexOf.call(this._weekdaysParse, llc);
            if (ii !== -1) {
                return ii;
            }
            ii = indexOf.call(this._shortWeekdaysParse, llc);
            return ii !== -1 ? ii : null;
        }
    }
}

function localeWeekdaysParse (weekdayName, format, strict) {
    var i, mom, regex;

    if (this._weekdaysParseExact) {
        return handleStrictParse$1.call(this, weekdayName, format, strict);
    }

    if (!this._weekdaysParse) {
        this._weekdaysParse = [];
        this._minWeekdaysParse = [];
        this._shortWeekdaysParse = [];
        this._fullWeekdaysParse = [];
    }

    for (i = 0; i < 7; i++) {
        // make the regex if we don't have it already

        mom = createUTC([2000, 1]).day(i);
        if (strict && !this._fullWeekdaysParse[i]) {
            this._fullWeekdaysParse[i] = new RegExp('^' + this.weekdays(mom, '').replace('.', '\.?') + '$', 'i');
            this._shortWeekdaysParse[i] = new RegExp('^' + this.weekdaysShort(mom, '').replace('.', '\.?') + '$', 'i');
            this._minWeekdaysParse[i] = new RegExp('^' + this.weekdaysMin(mom, '').replace('.', '\.?') + '$', 'i');
        }
        if (!this._weekdaysParse[i]) {
            regex = '^' + this.weekdays(mom, '') + '|^' + this.weekdaysShort(mom, '') + '|^' + this.weekdaysMin(mom, '');
            this._weekdaysParse[i] = new RegExp(regex.replace('.', ''), 'i');
        }
        // test the regex
        if (strict && format === 'dddd' && this._fullWeekdaysParse[i].test(weekdayName)) {
            return i;
        } else if (strict && format === 'ddd' && this._shortWeekdaysParse[i].test(weekdayName)) {
            return i;
        } else if (strict && format === 'dd' && this._minWeekdaysParse[i].test(weekdayName)) {
            return i;
        } else if (!strict && this._weekdaysParse[i].test(weekdayName)) {
            return i;
        }
    }
}

// MOMENTS

function getSetDayOfWeek (input) {
    if (!this.isValid()) {
        return input != null ? this : NaN;
    }
    var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay();
    if (input != null) {
        input = parseWeekday(input, this.localeData());
        return this.add(input - day, 'd');
    } else {
        return day;
    }
}

function getSetLocaleDayOfWeek (input) {
    if (!this.isValid()) {
        return input != null ? this : NaN;
    }
    var weekday = (this.day() + 7 - this.localeData()._week.dow) % 7;
    return input == null ? weekday : this.add(input - weekday, 'd');
}

function getSetISODayOfWeek (input) {
    if (!this.isValid()) {
        return input != null ? this : NaN;
    }

    // behaves the same as moment#day except
    // as a getter, returns 7 instead of 0 (1-7 range instead of 0-6)
    // as a setter, sunday should belong to the previous week.

    if (input != null) {
        var weekday = parseIsoWeekday(input, this.localeData());
        return this.day(this.day() % 7 ? weekday : weekday - 7);
    } else {
        return this.day() || 7;
    }
}

var defaultWeekdaysRegex = matchWord;
function weekdaysRegex (isStrict) {
    if (this._weekdaysParseExact) {
        if (!hasOwnProp(this, '_weekdaysRegex')) {
            computeWeekdaysParse.call(this);
        }
        if (isStrict) {
            return this._weekdaysStrictRegex;
        } else {
            return this._weekdaysRegex;
        }
    } else {
        if (!hasOwnProp(this, '_weekdaysRegex')) {
            this._weekdaysRegex = defaultWeekdaysRegex;
        }
        return this._weekdaysStrictRegex && isStrict ?
            this._weekdaysStrictRegex : this._weekdaysRegex;
    }
}

var defaultWeekdaysShortRegex = matchWord;
function weekdaysShortRegex (isStrict) {
    if (this._weekdaysParseExact) {
        if (!hasOwnProp(this, '_weekdaysRegex')) {
            computeWeekdaysParse.call(this);
        }
        if (isStrict) {
            return this._weekdaysShortStrictRegex;
        } else {
            return this._weekdaysShortRegex;
        }
    } else {
        if (!hasOwnProp(this, '_weekdaysShortRegex')) {
            this._weekdaysShortRegex = defaultWeekdaysShortRegex;
        }
        return this._weekdaysShortStrictRegex && isStrict ?
            this._weekdaysShortStrictRegex : this._weekdaysShortRegex;
    }
}

var defaultWeekdaysMinRegex = matchWord;
function weekdaysMinRegex (isStrict) {
    if (this._weekdaysParseExact) {
        if (!hasOwnProp(this, '_weekdaysRegex')) {
            computeWeekdaysParse.call(this);
        }
        if (isStrict) {
            return this._weekdaysMinStrictRegex;
        } else {
            return this._weekdaysMinRegex;
        }
    } else {
        if (!hasOwnProp(this, '_weekdaysMinRegex')) {
            this._weekdaysMinRegex = defaultWeekdaysMinRegex;
        }
        return this._weekdaysMinStrictRegex && isStrict ?
            this._weekdaysMinStrictRegex : this._weekdaysMinRegex;
    }
}


function computeWeekdaysParse () {
    function cmpLenRev(a, b) {
        return b.length - a.length;
    }

    var minPieces = [], shortPieces = [], longPieces = [], mixedPieces = [],
        i, mom, minp, shortp, longp;
    for (i = 0; i < 7; i++) {
        // make the regex if we don't have it already
        mom = createUTC([2000, 1]).day(i);
        minp = this.weekdaysMin(mom, '');
        shortp = this.weekdaysShort(mom, '');
        longp = this.weekdays(mom, '');
        minPieces.push(minp);
        shortPieces.push(shortp);
        longPieces.push(longp);
        mixedPieces.push(minp);
        mixedPieces.push(shortp);
        mixedPieces.push(longp);
    }
    // Sorting makes sure if one weekday (or abbr) is a prefix of another it
    // will match the longer piece.
    minPieces.sort(cmpLenRev);
    shortPieces.sort(cmpLenRev);
    longPieces.sort(cmpLenRev);
    mixedPieces.sort(cmpLenRev);
    for (i = 0; i < 7; i++) {
        shortPieces[i] = regexEscape(shortPieces[i]);
        longPieces[i] = regexEscape(longPieces[i]);
        mixedPieces[i] = regexEscape(mixedPieces[i]);
    }

    this._weekdaysRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');
    this._weekdaysShortRegex = this._weekdaysRegex;
    this._weekdaysMinRegex = this._weekdaysRegex;

    this._weekdaysStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i');
    this._weekdaysShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i');
    this._weekdaysMinStrictRegex = new RegExp('^(' + minPieces.join('|') + ')', 'i');
}

// FORMATTING

function hFormat() {
    return this.hours() % 12 || 12;
}

function kFormat() {
    return this.hours() || 24;
}

addFormatToken('H', ['HH', 2], 0, 'hour');
addFormatToken('h', ['hh', 2], 0, hFormat);
addFormatToken('k', ['kk', 2], 0, kFormat);

addFormatToken('hmm', 0, 0, function () {
    return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2);
});

addFormatToken('hmmss', 0, 0, function () {
    return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2) +
        zeroFill(this.seconds(), 2);
});

addFormatToken('Hmm', 0, 0, function () {
    return '' + this.hours() + zeroFill(this.minutes(), 2);
});

addFormatToken('Hmmss', 0, 0, function () {
    return '' + this.hours() + zeroFill(this.minutes(), 2) +
        zeroFill(this.seconds(), 2);
});

function meridiem (token, lowercase) {
    addFormatToken(token, 0, 0, function () {
        return this.localeData().meridiem(this.hours(), this.minutes(), lowercase);
    });
}

meridiem('a', true);
meridiem('A', false);

// ALIASES

addUnitAlias('hour', 'h');

// PRIORITY
addUnitPriority('hour', 13);

// PARSING

function matchMeridiem (isStrict, locale) {
    return locale._meridiemParse;
}

addRegexToken('a',  matchMeridiem);
addRegexToken('A',  matchMeridiem);
addRegexToken('H',  match1to2);
addRegexToken('h',  match1to2);
addRegexToken('k',  match1to2);
addRegexToken('HH', match1to2, match2);
addRegexToken('hh', match1to2, match2);
addRegexToken('kk', match1to2, match2);

addRegexToken('hmm', match3to4);
addRegexToken('hmmss', match5to6);
addRegexToken('Hmm', match3to4);
addRegexToken('Hmmss', match5to6);

addParseToken(['H', 'HH'], HOUR);
addParseToken(['k', 'kk'], function (input, array, config) {
    var kInput = toInt(input);
    array[HOUR] = kInput === 24 ? 0 : kInput;
});
addParseToken(['a', 'A'], function (input, array, config) {
    config._isPm = config._locale.isPM(input);
    config._meridiem = input;
});
addParseToken(['h', 'hh'], function (input, array, config) {
    array[HOUR] = toInt(input);
    getParsingFlags(config).bigHour = true;
});
addParseToken('hmm', function (input, array, config) {
    var pos = input.length - 2;
    array[HOUR] = toInt(input.substr(0, pos));
    array[MINUTE] = toInt(input.substr(pos));
    getParsingFlags(config).bigHour = true;
});
addParseToken('hmmss', function (input, array, config) {
    var pos1 = input.length - 4;
    var pos2 = input.length - 2;
    array[HOUR] = toInt(input.substr(0, pos1));
    array[MINUTE] = toInt(input.substr(pos1, 2));
    array[SECOND] = toInt(input.substr(pos2));
    getParsingFlags(config).bigHour = true;
});
addParseToken('Hmm', function (input, array, config) {
    var pos = input.length - 2;
    array[HOUR] = toInt(input.substr(0, pos));
    array[MINUTE] = toInt(input.substr(pos));
});
addParseToken('Hmmss', function (input, array, config) {
    var pos1 = input.length - 4;
    var pos2 = input.length - 2;
    array[HOUR] = toInt(input.substr(0, pos1));
    array[MINUTE] = toInt(input.substr(pos1, 2));
    array[SECOND] = toInt(input.substr(pos2));
});

// LOCALES

function localeIsPM (input) {
    // IE8 Quirks Mode & IE7 Standards Mode do not allow accessing strings like arrays
    // Using charAt should be more compatible.
    return ((input + '').toLowerCase().charAt(0) === 'p');
}

var defaultLocaleMeridiemParse = /[ap]\.?m?\.?/i;
function localeMeridiem (hours, minutes, isLower) {
    if (hours > 11) {
        return isLower ? 'pm' : 'PM';
    } else {
        return isLower ? 'am' : 'AM';
    }
}


// MOMENTS

// Setting the hour should keep the time, because the user explicitly
// specified which hour he wants. So trying to maintain the same hour (in
// a new timezone) makes sense. Adding/subtracting hours does not follow
// this rule.
var getSetHour = makeGetSet('Hours', true);

// months
// week
// weekdays
// meridiem
var baseConfig = {
    calendar: defaultCalendar,
    longDateFormat: defaultLongDateFormat,
    invalidDate: defaultInvalidDate,
    ordinal: defaultOrdinal,
    dayOfMonthOrdinalParse: defaultDayOfMonthOrdinalParse,
    relativeTime: defaultRelativeTime,

    months: defaultLocaleMonths,
    monthsShort: defaultLocaleMonthsShort,

    week: defaultLocaleWeek,

    weekdays: defaultLocaleWeekdays,
    weekdaysMin: defaultLocaleWeekdaysMin,
    weekdaysShort: defaultLocaleWeekdaysShort,

    meridiemParse: defaultLocaleMeridiemParse
};

// internal storage for locale config files
var locales = {};
var localeFamilies = {};
var globalLocale;

function normalizeLocale(key) {
    return key ? key.toLowerCase().replace('_', '-') : key;
}

// pick the locale from the array
// try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each
// substring from most specific to least, but move to the next array item if it's a more specific variant than the current root
function chooseLocale(names) {
    var i = 0, j, next, locale, split;

    while (i < names.length) {
        split = normalizeLocale(names[i]).split('-');
        j = split.length;
        next = normalizeLocale(names[i + 1]);
        next = next ? next.split('-') : null;
        while (j > 0) {
            locale = loadLocale(split.slice(0, j).join('-'));
            if (locale) {
                return locale;
            }
            if (next && next.length >= j && compareArrays(split, next, true) >= j - 1) {
                //the next array item is better than a shallower substring of this one
                break;
            }
            j--;
        }
        i++;
    }
    return null;
}

function loadLocale(name) {
    var oldLocale = null;
    // TODO: Find a better way to register and load all the locales in Node
    if (!locales[name] && (typeof module !== 'undefined') &&
            module && module.exports) {
        try {
            oldLocale = globalLocale._abbr;
            var aliasedRequire = require;
            aliasedRequire('./locale/' + name);
            getSetGlobalLocale(oldLocale);
        } catch (e) {}
    }
    return locales[name];
}

// This function will load locale and then set the global locale.  If
// no arguments are passed in, it will simply return the current global
// locale key.
function getSetGlobalLocale (key, values) {
    var data;
    if (key) {
        if (isUndefined(values)) {
            data = getLocale(key);
        }
        else {
            data = defineLocale(key, values);
        }

        if (data) {
            // moment.duration._locale = moment._locale = data;
            globalLocale = data;
        }
    }

    return globalLocale._abbr;
}

function defineLocale (name, config) {
    if (config !== null) {
        var parentConfig = baseConfig;
        config.abbr = name;
        if (locales[name] != null) {
            deprecateSimple('defineLocaleOverride',
                    'use moment.updateLocale(localeName, config) to change ' +
                    'an existing locale. moment.defineLocale(localeName, ' +
                    'config) should only be used for creating a new locale ' +
                    'See http://momentjs.com/guides/#/warnings/define-locale/ for more info.');
            parentConfig = locales[name]._config;
        } else if (config.parentLocale != null) {
            if (locales[config.parentLocale] != null) {
                parentConfig = locales[config.parentLocale]._config;
            } else {
                if (!localeFamilies[config.parentLocale]) {
                    localeFamilies[config.parentLocale] = [];
                }
                localeFamilies[config.parentLocale].push({
                    name: name,
                    config: config
                });
                return null;
            }
        }
        locales[name] = new Locale(mergeConfigs(parentConfig, config));

        if (localeFamilies[name]) {
            localeFamilies[name].forEach(function (x) {
                defineLocale(x.name, x.config);
            });
        }

        // backwards compat for now: also set the locale
        // make sure we set the locale AFTER all child locales have been
        // created, so we won't end up with the child locale set.
        getSetGlobalLocale(name);


        return locales[name];
    } else {
        // useful for testing
        delete locales[name];
        return null;
    }
}

function updateLocale(name, config) {
    if (config != null) {
        var locale, tmpLocale, parentConfig = baseConfig;
        // MERGE
        tmpLocale = loadLocale(name);
        if (tmpLocale != null) {
            parentConfig = tmpLocale._config;
        }
        config = mergeConfigs(parentConfig, config);
        locale = new Locale(config);
        locale.parentLocale = locales[name];
        locales[name] = locale;

        // backwards compat for now: also set the locale
        getSetGlobalLocale(name);
    } else {
        // pass null for config to unupdate, useful for tests
        if (locales[name] != null) {
            if (locales[name].parentLocale != null) {
                locales[name] = locales[name].parentLocale;
            } else if (locales[name] != null) {
                delete locales[name];
            }
        }
    }
    return locales[name];
}

// returns locale data
function getLocale (key) {
    var locale;

    if (key && key._locale && key._locale._abbr) {
        key = key._locale._abbr;
    }

    if (!key) {
        return globalLocale;
    }

    if (!isArray(key)) {
        //short-circuit everything else
        locale = loadLocale(key);
        if (locale) {
            return locale;
        }
        key = [key];
    }

    return chooseLocale(key);
}

function listLocales() {
    return keys(locales);
}

function checkOverflow (m) {
    var overflow;
    var a = m._a;

    if (a && getParsingFlags(m).overflow === -2) {
        overflow =
            a[MONTH]       < 0 || a[MONTH]       > 11  ? MONTH :
            a[DATE]        < 1 || a[DATE]        > daysInMonth(a[YEAR], a[MONTH]) ? DATE :
            a[HOUR]        < 0 || a[HOUR]        > 24 || (a[HOUR] === 24 && (a[MINUTE] !== 0 || a[SECOND] !== 0 || a[MILLISECOND] !== 0)) ? HOUR :
            a[MINUTE]      < 0 || a[MINUTE]      > 59  ? MINUTE :
            a[SECOND]      < 0 || a[SECOND]      > 59  ? SECOND :
            a[MILLISECOND] < 0 || a[MILLISECOND] > 999 ? MILLISECOND :
            -1;

        if (getParsingFlags(m)._overflowDayOfYear && (overflow < YEAR || overflow > DATE)) {
            overflow = DATE;
        }
        if (getParsingFlags(m)._overflowWeeks && overflow === -1) {
            overflow = WEEK;
        }
        if (getParsingFlags(m)._overflowWeekday && overflow === -1) {
            overflow = WEEKDAY;
        }

        getParsingFlags(m).overflow = overflow;
    }

    return m;
}

// Pick the first defined of two or three arguments.
function defaults(a, b, c) {
    if (a != null) {
        return a;
    }
    if (b != null) {
        return b;
    }
    return c;
}

function currentDateArray(config) {
    // hooks is actually the exported moment object
    var nowValue = new Date(hooks.now());
    if (config._useUTC) {
        return [nowValue.getUTCFullYear(), nowValue.getUTCMonth(), nowValue.getUTCDate()];
    }
    return [nowValue.getFullYear(), nowValue.getMonth(), nowValue.getDate()];
}

// convert an array to a date.
// the array should mirror the parameters below
// note: all values past the year are optional and will default to the lowest possible value.
// [year, month, day , hour, minute, second, millisecond]
function configFromArray (config) {
    var i, date, input = [], currentDate, expectedWeekday, yearToUse;

    if (config._d) {
        return;
    }

    currentDate = currentDateArray(config);

    //compute day of the year from weeks and weekdays
    if (config._w && config._a[DATE] == null && config._a[MONTH] == null) {
        dayOfYearFromWeekInfo(config);
    }

    //if the day of the year is set, figure out what it is
    if (config._dayOfYear != null) {
        yearToUse = defaults(config._a[YEAR], currentDate[YEAR]);

        if (config._dayOfYear > daysInYear(yearToUse) || config._dayOfYear === 0) {
            getParsingFlags(config)._overflowDayOfYear = true;
        }

        date = createUTCDate(yearToUse, 0, config._dayOfYear);
        config._a[MONTH] = date.getUTCMonth();
        config._a[DATE] = date.getUTCDate();
    }

    // Default to current date.
    // * if no year, month, day of month are given, default to today
    // * if day of month is given, default month and year
    // * if month is given, default only year
    // * if year is given, don't default anything
    for (i = 0; i < 3 && config._a[i] == null; ++i) {
        config._a[i] = input[i] = currentDate[i];
    }

    // Zero out whatever was not defaulted, including time
    for (; i < 7; i++) {
        config._a[i] = input[i] = (config._a[i] == null) ? (i === 2 ? 1 : 0) : config._a[i];
    }

    // Check for 24:00:00.000
    if (config._a[HOUR] === 24 &&
            config._a[MINUTE] === 0 &&
            config._a[SECOND] === 0 &&
            config._a[MILLISECOND] === 0) {
        config._nextDay = true;
        config._a[HOUR] = 0;
    }

    config._d = (config._useUTC ? createUTCDate : createDate).apply(null, input);
    expectedWeekday = config._useUTC ? config._d.getUTCDay() : config._d.getDay();

    // Apply timezone offset from input. The actual utcOffset can be changed
    // with parseZone.
    if (config._tzm != null) {
        config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm);
    }

    if (config._nextDay) {
        config._a[HOUR] = 24;
    }

    // check for mismatching day of week
    if (config._w && typeof config._w.d !== 'undefined' && config._w.d !== expectedWeekday) {
        getParsingFlags(config).weekdayMismatch = true;
    }
}

function dayOfYearFromWeekInfo(config) {
    var w, weekYear, week, weekday, dow, doy, temp, weekdayOverflow;

    w = config._w;
    if (w.GG != null || w.W != null || w.E != null) {
        dow = 1;
        doy = 4;

        // TODO: We need to take the current isoWeekYear, but that depends on
        // how we interpret now (local, utc, fixed offset). So create
        // a now version of current config (take local/utc/offset flags, and
        // create now).
        weekYear = defaults(w.GG, config._a[YEAR], weekOfYear(createLocal(), 1, 4).year);
        week = defaults(w.W, 1);
        weekday = defaults(w.E, 1);
        if (weekday < 1 || weekday > 7) {
            weekdayOverflow = true;
        }
    } else {
        dow = config._locale._week.dow;
        doy = config._locale._week.doy;

        var curWeek = weekOfYear(createLocal(), dow, doy);

        weekYear = defaults(w.gg, config._a[YEAR], curWeek.year);

        // Default to current week.
        week = defaults(w.w, curWeek.week);

        if (w.d != null) {
            // weekday -- low day numbers are considered next week
            weekday = w.d;
            if (weekday < 0 || weekday > 6) {
                weekdayOverflow = true;
            }
        } else if (w.e != null) {
            // local weekday -- counting starts from begining of week
            weekday = w.e + dow;
            if (w.e < 0 || w.e > 6) {
                weekdayOverflow = true;
            }
        } else {
            // default to begining of week
            weekday = dow;
        }
    }
    if (week < 1 || week > weeksInYear(weekYear, dow, doy)) {
        getParsingFlags(config)._overflowWeeks = true;
    } else if (weekdayOverflow != null) {
        getParsingFlags(config)._overflowWeekday = true;
    } else {
        temp = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy);
        config._a[YEAR] = temp.year;
        config._dayOfYear = temp.dayOfYear;
    }
}

// iso 8601 regex
// 0000-00-00 0000-W00 or 0000-W00-0 + T + 00 or 00:00 or 00:00:00 or 00:00:00.000 + +00:00 or +0000 or +00)
var extendedIsoRegex = /^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/;
var basicIsoRegex = /^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/;

var tzRegex = /Z|[+-]\d\d(?::?\d\d)?/;

var isoDates = [
    ['YYYYYY-MM-DD', /[+-]\d{6}-\d\d-\d\d/],
    ['YYYY-MM-DD', /\d{4}-\d\d-\d\d/],
    ['GGGG-[W]WW-E', /\d{4}-W\d\d-\d/],
    ['GGGG-[W]WW', /\d{4}-W\d\d/, false],
    ['YYYY-DDD', /\d{4}-\d{3}/],
    ['YYYY-MM', /\d{4}-\d\d/, false],
    ['YYYYYYMMDD', /[+-]\d{10}/],
    ['YYYYMMDD', /\d{8}/],
    // YYYYMM is NOT allowed by the standard
    ['GGGG[W]WWE', /\d{4}W\d{3}/],
    ['GGGG[W]WW', /\d{4}W\d{2}/, false],
    ['YYYYDDD', /\d{7}/]
];

// iso time formats and regexes
var isoTimes = [
    ['HH:mm:ss.SSSS', /\d\d:\d\d:\d\d\.\d+/],
    ['HH:mm:ss,SSSS', /\d\d:\d\d:\d\d,\d+/],
    ['HH:mm:ss', /\d\d:\d\d:\d\d/],
    ['HH:mm', /\d\d:\d\d/],
    ['HHmmss.SSSS', /\d\d\d\d\d\d\.\d+/],
    ['HHmmss,SSSS', /\d\d\d\d\d\d,\d+/],
    ['HHmmss', /\d\d\d\d\d\d/],
    ['HHmm', /\d\d\d\d/],
    ['HH', /\d\d/]
];

var aspNetJsonRegex = /^\/?Date\((\-?\d+)/i;

// date from iso format
function configFromISO(config) {
    var i, l,
        string = config._i,
        match = extendedIsoRegex.exec(string) || basicIsoRegex.exec(string),
        allowTime, dateFormat, timeFormat, tzFormat;

    if (match) {
        getParsingFlags(config).iso = true;

        for (i = 0, l = isoDates.length; i < l; i++) {
            if (isoDates[i][1].exec(match[1])) {
                dateFormat = isoDates[i][0];
                allowTime = isoDates[i][2] !== false;
                break;
            }
        }
        if (dateFormat == null) {
            config._isValid = false;
            return;
        }
        if (match[3]) {
            for (i = 0, l = isoTimes.length; i < l; i++) {
                if (isoTimes[i][1].exec(match[3])) {
                    // match[2] should be 'T' or space
                    timeFormat = (match[2] || ' ') + isoTimes[i][0];
                    break;
                }
            }
            if (timeFormat == null) {
                config._isValid = false;
                return;
            }
        }
        if (!allowTime && timeFormat != null) {
            config._isValid = false;
            return;
        }
        if (match[4]) {
            if (tzRegex.exec(match[4])) {
                tzFormat = 'Z';
            } else {
                config._isValid = false;
                return;
            }
        }
        config._f = dateFormat + (timeFormat || '') + (tzFormat || '');
        configFromStringAndFormat(config);
    } else {
        config._isValid = false;
    }
}

// RFC 2822 regex: For details see https://tools.ietf.org/html/rfc2822#section-3.3
var rfc2822 = /^(?:(Mon|Tue|Wed|Thu|Fri|Sat|Sun),?\s)?(\d{1,2})\s(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s(\d{2,4})\s(\d\d):(\d\d)(?::(\d\d))?\s(?:(UT|GMT|[ECMP][SD]T)|([Zz])|([+-]\d{4}))$/;

function extractFromRFC2822Strings(yearStr, monthStr, dayStr, hourStr, minuteStr, secondStr) {
    var result = [
        untruncateYear(yearStr),
        defaultLocaleMonthsShort.indexOf(monthStr),
        parseInt(dayStr, 10),
        parseInt(hourStr, 10),
        parseInt(minuteStr, 10)
    ];

    if (secondStr) {
        result.push(parseInt(secondStr, 10));
    }

    return result;
}

function untruncateYear(yearStr) {
    var year = parseInt(yearStr, 10);
    if (year <= 49) {
        return 2000 + year;
    } else if (year <= 999) {
        return 1900 + year;
    }
    return year;
}

function preprocessRFC2822(s) {
    // Remove comments and folding whitespace and replace multiple-spaces with a single space
    return s.replace(/\([^)]*\)|[\n\t]/g, ' ').replace(/(\s\s+)/g, ' ').trim();
}

function checkWeekday(weekdayStr, parsedInput, config) {
    if (weekdayStr) {
        // TODO: Replace the vanilla JS Date object with an indepentent day-of-week check.
        var weekdayProvided = defaultLocaleWeekdaysShort.indexOf(weekdayStr),
            weekdayActual = new Date(parsedInput[0], parsedInput[1], parsedInput[2]).getDay();
        if (weekdayProvided !== weekdayActual) {
            getParsingFlags(config).weekdayMismatch = true;
            config._isValid = false;
            return false;
        }
    }
    return true;
}

var obsOffsets = {
    UT: 0,
    GMT: 0,
    EDT: -4 * 60,
    EST: -5 * 60,
    CDT: -5 * 60,
    CST: -6 * 60,
    MDT: -6 * 60,
    MST: -7 * 60,
    PDT: -7 * 60,
    PST: -8 * 60
};

function calculateOffset(obsOffset, militaryOffset, numOffset) {
    if (obsOffset) {
        return obsOffsets[obsOffset];
    } else if (militaryOffset) {
        // the only allowed military tz is Z
        return 0;
    } else {
        var hm = parseInt(numOffset, 10);
        var m = hm % 100, h = (hm - m) / 100;
        return h * 60 + m;
    }
}

// date and time from ref 2822 format
function configFromRFC2822(config) {
    var match = rfc2822.exec(preprocessRFC2822(config._i));
    if (match) {
        var parsedArray = extractFromRFC2822Strings(match[4], match[3], match[2], match[5], match[6], match[7]);
        if (!checkWeekday(match[1], parsedArray, config)) {
            return;
        }

        config._a = parsedArray;
        config._tzm = calculateOffset(match[8], match[9], match[10]);

        config._d = createUTCDate.apply(null, config._a);
        config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm);

        getParsingFlags(config).rfc2822 = true;
    } else {
        config._isValid = false;
    }
}

// date from iso format or fallback
function configFromString(config) {
    var matched = aspNetJsonRegex.exec(config._i);

    if (matched !== null) {
        config._d = new Date(+matched[1]);
        return;
    }

    configFromISO(config);
    if (config._isValid === false) {
        delete config._isValid;
    } else {
        return;
    }

    configFromRFC2822(config);
    if (config._isValid === false) {
        delete config._isValid;
    } else {
        return;
    }

    // Final attempt, use Input Fallback
    hooks.createFromInputFallback(config);
}

hooks.createFromInputFallback = deprecate(
    'value provided is not in a recognized RFC2822 or ISO format. moment construction falls back to js Date(), ' +
    'which is not reliable across all browsers and versions. Non RFC2822/ISO date formats are ' +
    'discouraged and will be removed in an upcoming major release. Please refer to ' +
    'http://momentjs.com/guides/#/warnings/js-date/ for more info.',
    function (config) {
        config._d = new Date(config._i + (config._useUTC ? ' UTC' : ''));
    }
);

// constant that refers to the ISO standard
hooks.ISO_8601 = function () {};

// constant that refers to the RFC 2822 form
hooks.RFC_2822 = function () {};

// date from string and format string
function configFromStringAndFormat(config) {
    // TODO: Move this to another part of the creation flow to prevent circular deps
    if (config._f === hooks.ISO_8601) {
        configFromISO(config);
        return;
    }
    if (config._f === hooks.RFC_2822) {
        configFromRFC2822(config);
        return;
    }
    config._a = [];
    getParsingFlags(config).empty = true;

    // This array is used to make a Date, either with `new Date` or `Date.UTC`
    var string = '' + config._i,
        i, parsedInput, tokens, token, skipped,
        stringLength = string.length,
        totalParsedInputLength = 0;

    tokens = expandFormat(config._f, config._locale).match(formattingTokens) || [];

    for (i = 0; i < tokens.length; i++) {
        token = tokens[i];
        parsedInput = (string.match(getParseRegexForToken(token, config)) || [])[0];
        // console.log('token', token, 'parsedInput', parsedInput,
        //         'regex', getParseRegexForToken(token, config));
        if (parsedInput) {
            skipped = string.substr(0, string.indexOf(parsedInput));
            if (skipped.length > 0) {
                getParsingFlags(config).unusedInput.push(skipped);
            }
            string = string.slice(string.indexOf(parsedInput) + parsedInput.length);
            totalParsedInputLength += parsedInput.length;
        }
        // don't parse if it's not a known token
        if (formatTokenFunctions[token]) {
            if (parsedInput) {
                getParsingFlags(config).empty = false;
            }
            else {
                getParsingFlags(config).unusedTokens.push(token);
            }
            addTimeToArrayFromToken(token, parsedInput, config);
        }
        else if (config._strict && !parsedInput) {
            getParsingFlags(config).unusedTokens.push(token);
        }
    }

    // add remaining unparsed input length to the string
    getParsingFlags(config).charsLeftOver = stringLength - totalParsedInputLength;
    if (string.length > 0) {
        getParsingFlags(config).unusedInput.push(string);
    }

    // clear _12h flag if hour is <= 12
    if (config._a[HOUR] <= 12 &&
        getParsingFlags(config).bigHour === true &&
        config._a[HOUR] > 0) {
        getParsingFlags(config).bigHour = undefined;
    }

    getParsingFlags(config).parsedDateParts = config._a.slice(0);
    getParsingFlags(config).meridiem = config._meridiem;
    // handle meridiem
    config._a[HOUR] = meridiemFixWrap(config._locale, config._a[HOUR], config._meridiem);

    configFromArray(config);
    checkOverflow(config);
}


function meridiemFixWrap (locale, hour, meridiem) {
    var isPm;

    if (meridiem == null) {
        // nothing to do
        return hour;
    }
    if (locale.meridiemHour != null) {
        return locale.meridiemHour(hour, meridiem);
    } else if (locale.isPM != null) {
        // Fallback
        isPm = locale.isPM(meridiem);
        if (isPm && hour < 12) {
            hour += 12;
        }
        if (!isPm && hour === 12) {
            hour = 0;
        }
        return hour;
    } else {
        // this is not supposed to happen
        return hour;
    }
}

// date from string and array of format strings
function configFromStringAndArray(config) {
    var tempConfig,
        bestMoment,

        scoreToBeat,
        i,
        currentScore;

    if (config._f.length === 0) {
        getParsingFlags(config).invalidFormat = true;
        config._d = new Date(NaN);
        return;
    }

    for (i = 0; i < config._f.length; i++) {
        currentScore = 0;
        tempConfig = copyConfig({}, config);
        if (config._useUTC != null) {
            tempConfig._useUTC = config._useUTC;
        }
        tempConfig._f = config._f[i];
        configFromStringAndFormat(tempConfig);

        if (!isValid(tempConfig)) {
            continue;
        }

        // if there is any input that was not parsed add a penalty for that format
        currentScore += getParsingFlags(tempConfig).charsLeftOver;

        //or tokens
        currentScore += getParsingFlags(tempConfig).unusedTokens.length * 10;

        getParsingFlags(tempConfig).score = currentScore;

        if (scoreToBeat == null || currentScore < scoreToBeat) {
            scoreToBeat = currentScore;
            bestMoment = tempConfig;
        }
    }

    extend(config, bestMoment || tempConfig);
}

function configFromObject(config) {
    if (config._d) {
        return;
    }

    var i = normalizeObjectUnits(config._i);
    config._a = map([i.year, i.month, i.day || i.date, i.hour, i.minute, i.second, i.millisecond], function (obj) {
        return obj && parseInt(obj, 10);
    });

    configFromArray(config);
}

function createFromConfig (config) {
    var res = new Moment(checkOverflow(prepareConfig(config)));
    if (res._nextDay) {
        // Adding is smart enough around DST
        res.add(1, 'd');
        res._nextDay = undefined;
    }

    return res;
}

function prepareConfig (config) {
    var input = config._i,
        format = config._f;

    config._locale = config._locale || getLocale(config._l);

    if (input === null || (format === undefined && input === '')) {
        return createInvalid({nullInput: true});
    }

    if (typeof input === 'string') {
        config._i = input = config._locale.preparse(input);
    }

    if (isMoment(input)) {
        return new Moment(checkOverflow(input));
    } else if (isDate(input)) {
        config._d = input;
    } else if (isArray(format)) {
        configFromStringAndArray(config);
    } else if (format) {
        configFromStringAndFormat(config);
    }  else {
        configFromInput(config);
    }

    if (!isValid(config)) {
        config._d = null;
    }

    return config;
}

function configFromInput(config) {
    var input = config._i;
    if (isUndefined(input)) {
        config._d = new Date(hooks.now());
    } else if (isDate(input)) {
        config._d = new Date(input.valueOf());
    } else if (typeof input === 'string') {
        configFromString(config);
    } else if (isArray(input)) {
        config._a = map(input.slice(0), function (obj) {
            return parseInt(obj, 10);
        });
        configFromArray(config);
    } else if (isObject(input)) {
        configFromObject(config);
    } else if (isNumber(input)) {
        // from milliseconds
        config._d = new Date(input);
    } else {
        hooks.createFromInputFallback(config);
    }
}

function createLocalOrUTC (input, format, locale, strict, isUTC) {
    var c = {};

    if (locale === true || locale === false) {
        strict = locale;
        locale = undefined;
    }

    if ((isObject(input) && isObjectEmpty(input)) ||
            (isArray(input) && input.length === 0)) {
        input = undefined;
    }
    // object construction must be done this way.
    // https://github.com/moment/moment/issues/1423
    c._isAMomentObject = true;
    c._useUTC = c._isUTC = isUTC;
    c._l = locale;
    c._i = input;
    c._f = format;
    c._strict = strict;

    return createFromConfig(c);
}

function createLocal (input, format, locale, strict) {
    return createLocalOrUTC(input, format, locale, strict, false);
}

var prototypeMin = deprecate(
    'moment().min is deprecated, use moment.max instead. http://momentjs.com/guides/#/warnings/min-max/',
    function () {
        var other = createLocal.apply(null, arguments);
        if (this.isValid() && other.isValid()) {
            return other < this ? this : other;
        } else {
            return createInvalid();
        }
    }
);

var prototypeMax = deprecate(
    'moment().max is deprecated, use moment.min instead. http://momentjs.com/guides/#/warnings/min-max/',
    function () {
        var other = createLocal.apply(null, arguments);
        if (this.isValid() && other.isValid()) {
            return other > this ? this : other;
        } else {
            return createInvalid();
        }
    }
);

// Pick a moment m from moments so that m[fn](other) is true for all
// other. This relies on the function fn to be transitive.
//
// moments should either be an array of moment objects or an array, whose
// first element is an array of moment objects.
function pickBy(fn, moments) {
    var res, i;
    if (moments.length === 1 && isArray(moments[0])) {
        moments = moments[0];
    }
    if (!moments.length) {
        return createLocal();
    }
    res = moments[0];
    for (i = 1; i < moments.length; ++i) {
        if (!moments[i].isValid() || moments[i][fn](res)) {
            res = moments[i];
        }
    }
    return res;
}

// TODO: Use [].sort instead?
function min () {
    var args = [].slice.call(arguments, 0);

    return pickBy('isBefore', args);
}

function max () {
    var args = [].slice.call(arguments, 0);

    return pickBy('isAfter', args);
}

var now = function () {
    return Date.now ? Date.now() : +(new Date());
};

var ordering = ['year', 'quarter', 'month', 'week', 'day', 'hour', 'minute', 'second', 'millisecond'];

function isDurationValid(m) {
    for (var key in m) {
        if (!(indexOf.call(ordering, key) !== -1 && (m[key] == null || !isNaN(m[key])))) {
            return false;
        }
    }

    var unitHasDecimal = false;
    for (var i = 0; i < ordering.length; ++i) {
        if (m[ordering[i]]) {
            if (unitHasDecimal) {
                return false; // only allow non-integers for smallest unit
            }
            if (parseFloat(m[ordering[i]]) !== toInt(m[ordering[i]])) {
                unitHasDecimal = true;
            }
        }
    }

    return true;
}

function isValid$1() {
    return this._isValid;
}

function createInvalid$1() {
    return createDuration(NaN);
}

function Duration (duration) {
    var normalizedInput = normalizeObjectUnits(duration),
        years = normalizedInput.year || 0,
        quarters = normalizedInput.quarter || 0,
        months = normalizedInput.month || 0,
        weeks = normalizedInput.week || 0,
        days = normalizedInput.day || 0,
        hours = normalizedInput.hour || 0,
        minutes = normalizedInput.minute || 0,
        seconds = normalizedInput.second || 0,
        milliseconds = normalizedInput.millisecond || 0;

    this._isValid = isDurationValid(normalizedInput);

    // representation for dateAddRemove
    this._milliseconds = +milliseconds +
        seconds * 1e3 + // 1000
        minutes * 6e4 + // 1000 * 60
        hours * 1000 * 60 * 60; //using 1000 * 60 * 60 instead of 36e5 to avoid floating point rounding errors https://github.com/moment/moment/issues/2978
    // Because of dateAddRemove treats 24 hours as different from a
    // day when working around DST, we need to store them separately
    this._days = +days +
        weeks * 7;
    // It is impossible to translate months into days without knowing
    // which months you are are talking about, so we have to store
    // it separately.
    this._months = +months +
        quarters * 3 +
        years * 12;

    this._data = {};

    this._locale = getLocale();

    this._bubble();
}

function isDuration (obj) {
    return obj instanceof Duration;
}

function absRound (number) {
    if (number < 0) {
        return Math.round(-1 * number) * -1;
    } else {
        return Math.round(number);
    }
}

// FORMATTING

function offset (token, separator) {
    addFormatToken(token, 0, 0, function () {
        var offset = this.utcOffset();
        var sign = '+';
        if (offset < 0) {
            offset = -offset;
            sign = '-';
        }
        return sign + zeroFill(~~(offset / 60), 2) + separator + zeroFill(~~(offset) % 60, 2);
    });
}

offset('Z', ':');
offset('ZZ', '');

// PARSING

addRegexToken('Z',  matchShortOffset);
addRegexToken('ZZ', matchShortOffset);
addParseToken(['Z', 'ZZ'], function (input, array, config) {
    config._useUTC = true;
    config._tzm = offsetFromString(matchShortOffset, input);
});

// HELPERS

// timezone chunker
// '+10:00' > ['10',  '00']
// '-1530'  > ['-15', '30']
var chunkOffset = /([\+\-]|\d\d)/gi;

function offsetFromString(matcher, string) {
    var matches = (string || '').match(matcher);

    if (matches === null) {
        return null;
    }

    var chunk   = matches[matches.length - 1] || [];
    var parts   = (chunk + '').match(chunkOffset) || ['-', 0, 0];
    var minutes = +(parts[1] * 60) + toInt(parts[2]);

    return minutes === 0 ?
      0 :
      parts[0] === '+' ? minutes : -minutes;
}

// Return a moment from input, that is local/utc/zone equivalent to model.
function cloneWithOffset(input, model) {
    var res, diff;
    if (model._isUTC) {
        res = model.clone();
        diff = (isMoment(input) || isDate(input) ? input.valueOf() : createLocal(input).valueOf()) - res.valueOf();
        // Use low-level api, because this fn is low-level api.
        res._d.setTime(res._d.valueOf() + diff);
        hooks.updateOffset(res, false);
        return res;
    } else {
        return createLocal(input).local();
    }
}

function getDateOffset (m) {
    // On Firefox.24 Date#getTimezoneOffset returns a floating point.
    // https://github.com/moment/moment/pull/1871
    return -Math.round(m._d.getTimezoneOffset() / 15) * 15;
}

// HOOKS

// This function will be called whenever a moment is mutated.
// It is intended to keep the offset in sync with the timezone.
hooks.updateOffset = function () {};

// MOMENTS

// keepLocalTime = true means only change the timezone, without
// affecting the local hour. So 5:31:26 +0300 --[utcOffset(2, true)]-->
// 5:31:26 +0200 It is possible that 5:31:26 doesn't exist with offset
// +0200, so we adjust the time as needed, to be valid.
//
// Keeping the time actually adds/subtracts (one hour)
// from the actual represented time. That is why we call updateOffset
// a second time. In case it wants us to change the offset again
// _changeInProgress == true case, then we have to adjust, because
// there is no such time in the given timezone.
function getSetOffset (input, keepLocalTime, keepMinutes) {
    var offset = this._offset || 0,
        localAdjust;
    if (!this.isValid()) {
        return input != null ? this : NaN;
    }
    if (input != null) {
        if (typeof input === 'string') {
            input = offsetFromString(matchShortOffset, input);
            if (input === null) {
                return this;
            }
        } else if (Math.abs(input) < 16 && !keepMinutes) {
            input = input * 60;
        }
        if (!this._isUTC && keepLocalTime) {
            localAdjust = getDateOffset(this);
        }
        this._offset = input;
        this._isUTC = true;
        if (localAdjust != null) {
            this.add(localAdjust, 'm');
        }
        if (offset !== input) {
            if (!keepLocalTime || this._changeInProgress) {
                addSubtract(this, createDuration(input - offset, 'm'), 1, false);
            } else if (!this._changeInProgress) {
                this._changeInProgress = true;
                hooks.updateOffset(this, true);
                this._changeInProgress = null;
            }
        }
        return this;
    } else {
        return this._isUTC ? offset : getDateOffset(this);
    }
}

function getSetZone (input, keepLocalTime) {
    if (input != null) {
        if (typeof input !== 'string') {
            input = -input;
        }

        this.utcOffset(input, keepLocalTime);

        return this;
    } else {
        return -this.utcOffset();
    }
}

function setOffsetToUTC (keepLocalTime) {
    return this.utcOffset(0, keepLocalTime);
}

function setOffsetToLocal (keepLocalTime) {
    if (this._isUTC) {
        this.utcOffset(0, keepLocalTime);
        this._isUTC = false;

        if (keepLocalTime) {
            this.subtract(getDateOffset(this), 'm');
        }
    }
    return this;
}

function setOffsetToParsedOffset () {
    if (this._tzm != null) {
        this.utcOffset(this._tzm, false, true);
    } else if (typeof this._i === 'string') {
        var tZone = offsetFromString(matchOffset, this._i);
        if (tZone != null) {
            this.utcOffset(tZone);
        }
        else {
            this.utcOffset(0, true);
        }
    }
    return this;
}

function hasAlignedHourOffset (input) {
    if (!this.isValid()) {
        return false;
    }
    input = input ? createLocal(input).utcOffset() : 0;

    return (this.utcOffset() - input) % 60 === 0;
}

function isDaylightSavingTime () {
    return (
        this.utcOffset() > this.clone().month(0).utcOffset() ||
        this.utcOffset() > this.clone().month(5).utcOffset()
    );
}

function isDaylightSavingTimeShifted () {
    if (!isUndefined(this._isDSTShifted)) {
        return this._isDSTShifted;
    }

    var c = {};

    copyConfig(c, this);
    c = prepareConfig(c);

    if (c._a) {
        var other = c._isUTC ? createUTC(c._a) : createLocal(c._a);
        this._isDSTShifted = this.isValid() &&
            compareArrays(c._a, other.toArray()) > 0;
    } else {
        this._isDSTShifted = false;
    }

    return this._isDSTShifted;
}

function isLocal () {
    return this.isValid() ? !this._isUTC : false;
}

function isUtcOffset () {
    return this.isValid() ? this._isUTC : false;
}

function isUtc () {
    return this.isValid() ? this._isUTC && this._offset === 0 : false;
}

// ASP.NET json date format regex
var aspNetRegex = /^(\-|\+)?(?:(\d*)[. ])?(\d+)\:(\d+)(?:\:(\d+)(\.\d*)?)?$/;

// from http://docs.closure-library.googlecode.com/git/closure_goog_date_date.js.source.html
// somewhat more in line with 4.4.3.2 2004 spec, but allows decimal anywhere
// and further modified to allow for strings containing both week and day
var isoRegex = /^(-|\+)?P(?:([-+]?[0-9,.]*)Y)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)W)?(?:([-+]?[0-9,.]*)D)?(?:T(?:([-+]?[0-9,.]*)H)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)S)?)?$/;

function createDuration (input, key) {
    var duration = input,
        // matching against regexp is expensive, do it on demand
        match = null,
        sign,
        ret,
        diffRes;

    if (isDuration(input)) {
        duration = {
            ms : input._milliseconds,
            d  : input._days,
            M  : input._months
        };
    } else if (isNumber(input)) {
        duration = {};
        if (key) {
            duration[key] = input;
        } else {
            duration.milliseconds = input;
        }
    } else if (!!(match = aspNetRegex.exec(input))) {
        sign = (match[1] === '-') ? -1 : 1;
        duration = {
            y  : 0,
            d  : toInt(match[DATE])                         * sign,
            h  : toInt(match[HOUR])                         * sign,
            m  : toInt(match[MINUTE])                       * sign,
            s  : toInt(match[SECOND])                       * sign,
            ms : toInt(absRound(match[MILLISECOND] * 1000)) * sign // the millisecond decimal point is included in the match
        };
    } else if (!!(match = isoRegex.exec(input))) {
        sign = (match[1] === '-') ? -1 : (match[1] === '+') ? 1 : 1;
        duration = {
            y : parseIso(match[2], sign),
            M : parseIso(match[3], sign),
            w : parseIso(match[4], sign),
            d : parseIso(match[5], sign),
            h : parseIso(match[6], sign),
            m : parseIso(match[7], sign),
            s : parseIso(match[8], sign)
        };
    } else if (duration == null) {// checks for null or undefined
        duration = {};
    } else if (typeof duration === 'object' && ('from' in duration || 'to' in duration)) {
        diffRes = momentsDifference(createLocal(duration.from), createLocal(duration.to));

        duration = {};
        duration.ms = diffRes.milliseconds;
        duration.M = diffRes.months;
    }

    ret = new Duration(duration);

    if (isDuration(input) && hasOwnProp(input, '_locale')) {
        ret._locale = input._locale;
    }

    return ret;
}

createDuration.fn = Duration.prototype;
createDuration.invalid = createInvalid$1;

function parseIso (inp, sign) {
    // We'd normally use ~~inp for this, but unfortunately it also
    // converts floats to ints.
    // inp may be undefined, so careful calling replace on it.
    var res = inp && parseFloat(inp.replace(',', '.'));
    // apply sign while we're at it
    return (isNaN(res) ? 0 : res) * sign;
}

function positiveMomentsDifference(base, other) {
    var res = {milliseconds: 0, months: 0};

    res.months = other.month() - base.month() +
        (other.year() - base.year()) * 12;
    if (base.clone().add(res.months, 'M').isAfter(other)) {
        --res.months;
    }

    res.milliseconds = +other - +(base.clone().add(res.months, 'M'));

    return res;
}

function momentsDifference(base, other) {
    var res;
    if (!(base.isValid() && other.isValid())) {
        return {milliseconds: 0, months: 0};
    }

    other = cloneWithOffset(other, base);
    if (base.isBefore(other)) {
        res = positiveMomentsDifference(base, other);
    } else {
        res = positiveMomentsDifference(other, base);
        res.milliseconds = -res.milliseconds;
        res.months = -res.months;
    }

    return res;
}

// TODO: remove 'name' arg after deprecation is removed
function createAdder(direction, name) {
    return function (val, period) {
        var dur, tmp;
        //invert the arguments, but complain about it
        if (period !== null && !isNaN(+period)) {
            deprecateSimple(name, 'moment().' + name  + '(period, number) is deprecated. Please use moment().' + name + '(number, period). ' +
            'See http://momentjs.com/guides/#/warnings/add-inverted-param/ for more info.');
            tmp = val; val = period; period = tmp;
        }

        val = typeof val === 'string' ? +val : val;
        dur = createDuration(val, period);
        addSubtract(this, dur, direction);
        return this;
    };
}

function addSubtract (mom, duration, isAdding, updateOffset) {
    var milliseconds = duration._milliseconds,
        days = absRound(duration._days),
        months = absRound(duration._months);

    if (!mom.isValid()) {
        // No op
        return;
    }

    updateOffset = updateOffset == null ? true : updateOffset;

    if (months) {
        setMonth(mom, get(mom, 'Month') + months * isAdding);
    }
    if (days) {
        set$1(mom, 'Date', get(mom, 'Date') + days * isAdding);
    }
    if (milliseconds) {
        mom._d.setTime(mom._d.valueOf() + milliseconds * isAdding);
    }
    if (updateOffset) {
        hooks.updateOffset(mom, days || months);
    }
}

var add      = createAdder(1, 'add');
var subtract = createAdder(-1, 'subtract');

function getCalendarFormat(myMoment, now) {
    var diff = myMoment.diff(now, 'days', true);
    return diff < -6 ? 'sameElse' :
            diff < -1 ? 'lastWeek' :
            diff < 0 ? 'lastDay' :
            diff < 1 ? 'sameDay' :
            diff < 2 ? 'nextDay' :
            diff < 7 ? 'nextWeek' : 'sameElse';
}

function calendar$1 (time, formats) {
    // We want to compare the start of today, vs this.
    // Getting start-of-today depends on whether we're local/utc/offset or not.
    var now = time || createLocal(),
        sod = cloneWithOffset(now, this).startOf('day'),
        format = hooks.calendarFormat(this, sod) || 'sameElse';

    var output = formats && (isFunction(formats[format]) ? formats[format].call(this, now) : formats[format]);

    return this.format(output || this.localeData().calendar(format, this, createLocal(now)));
}

function clone () {
    return new Moment(this);
}

function isAfter (input, units) {
    var localInput = isMoment(input) ? input : createLocal(input);
    if (!(this.isValid() && localInput.isValid())) {
        return false;
    }
    units = normalizeUnits(!isUndefined(units) ? units : 'millisecond');
    if (units === 'millisecond') {
        return this.valueOf() > localInput.valueOf();
    } else {
        return localInput.valueOf() < this.clone().startOf(units).valueOf();
    }
}

function isBefore (input, units) {
    var localInput = isMoment(input) ? input : createLocal(input);
    if (!(this.isValid() && localInput.isValid())) {
        return false;
    }
    units = normalizeUnits(!isUndefined(units) ? units : 'millisecond');
    if (units === 'millisecond') {
        return this.valueOf() < localInput.valueOf();
    } else {
        return this.clone().endOf(units).valueOf() < localInput.valueOf();
    }
}

function isBetween (from, to, units, inclusivity) {
    inclusivity = inclusivity || '()';
    return (inclusivity[0] === '(' ? this.isAfter(from, units) : !this.isBefore(from, units)) &&
        (inclusivity[1] === ')' ? this.isBefore(to, units) : !this.isAfter(to, units));
}

function isSame (input, units) {
    var localInput = isMoment(input) ? input : createLocal(input),
        inputMs;
    if (!(this.isValid() && localInput.isValid())) {
        return false;
    }
    units = normalizeUnits(units || 'millisecond');
    if (units === 'millisecond') {
        return this.valueOf() === localInput.valueOf();
    } else {
        inputMs = localInput.valueOf();
        return this.clone().startOf(units).valueOf() <= inputMs && inputMs <= this.clone().endOf(units).valueOf();
    }
}

function isSameOrAfter (input, units) {
    return this.isSame(input, units) || this.isAfter(input,units);
}

function isSameOrBefore (input, units) {
    return this.isSame(input, units) || this.isBefore(input,units);
}

function diff (input, units, asFloat) {
    var that,
        zoneDelta,
        delta, output;

    if (!this.isValid()) {
        return NaN;
    }

    that = cloneWithOffset(input, this);

    if (!that.isValid()) {
        return NaN;
    }

    zoneDelta = (that.utcOffset() - this.utcOffset()) * 6e4;

    units = normalizeUnits(units);

    switch (units) {
        case 'year': output = monthDiff(this, that) / 12; break;
        case 'month': output = monthDiff(this, that); break;
        case 'quarter': output = monthDiff(this, that) / 3; break;
        case 'second': output = (this - that) / 1e3; break; // 1000
        case 'minute': output = (this - that) / 6e4; break; // 1000 * 60
        case 'hour': output = (this - that) / 36e5; break; // 1000 * 60 * 60
        case 'day': output = (this - that - zoneDelta) / 864e5; break; // 1000 * 60 * 60 * 24, negate dst
        case 'week': output = (this - that - zoneDelta) / 6048e5; break; // 1000 * 60 * 60 * 24 * 7, negate dst
        default: output = this - that;
    }

    return asFloat ? output : absFloor(output);
}

function monthDiff (a, b) {
    // difference in months
    var wholeMonthDiff = ((b.year() - a.year()) * 12) + (b.month() - a.month()),
        // b is in (anchor - 1 month, anchor + 1 month)
        anchor = a.clone().add(wholeMonthDiff, 'months'),
        anchor2, adjust;

    if (b - anchor < 0) {
        anchor2 = a.clone().add(wholeMonthDiff - 1, 'months');
        // linear across the month
        adjust = (b - anchor) / (anchor - anchor2);
    } else {
        anchor2 = a.clone().add(wholeMonthDiff + 1, 'months');
        // linear across the month
        adjust = (b - anchor) / (anchor2 - anchor);
    }

    //check for negative zero, return zero if negative zero
    return -(wholeMonthDiff + adjust) || 0;
}

hooks.defaultFormat = 'YYYY-MM-DDTHH:mm:ssZ';
hooks.defaultFormatUtc = 'YYYY-MM-DDTHH:mm:ss[Z]';

function toString () {
    return this.clone().locale('en').format('ddd MMM DD YYYY HH:mm:ss [GMT]ZZ');
}

function toISOString(keepOffset) {
    if (!this.isValid()) {
        return null;
    }
    var utc = keepOffset !== true;
    var m = utc ? this.clone().utc() : this;
    if (m.year() < 0 || m.year() > 9999) {
        return formatMoment(m, utc ? 'YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]' : 'YYYYYY-MM-DD[T]HH:mm:ss.SSSZ');
    }
    if (isFunction(Date.prototype.toISOString)) {
        // native implementation is ~50x faster, use it when we can
        if (utc) {
            return this.toDate().toISOString();
        } else {
            return new Date(this._d.valueOf()).toISOString().replace('Z', formatMoment(m, 'Z'));
        }
    }
    return formatMoment(m, utc ? 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]' : 'YYYY-MM-DD[T]HH:mm:ss.SSSZ');
}

/**
 * Return a human readable representation of a moment that can
 * also be evaluated to get a new moment which is the same
 *
 * @link https://nodejs.org/dist/latest/docs/api/util.html#util_custom_inspect_function_on_objects
 */
function inspect () {
    if (!this.isValid()) {
        return 'moment.invalid(/* ' + this._i + ' */)';
    }
    var func = 'moment';
    var zone = '';
    if (!this.isLocal()) {
        func = this.utcOffset() === 0 ? 'moment.utc' : 'moment.parseZone';
        zone = 'Z';
    }
    var prefix = '[' + func + '("]';
    var year = (0 <= this.year() && this.year() <= 9999) ? 'YYYY' : 'YYYYYY';
    var datetime = '-MM-DD[T]HH:mm:ss.SSS';
    var suffix = zone + '[")]';

    return this.format(prefix + year + datetime + suffix);
}

function format (inputString) {
    if (!inputString) {
        inputString = this.isUtc() ? hooks.defaultFormatUtc : hooks.defaultFormat;
    }
    var output = formatMoment(this, inputString);
    return this.localeData().postformat(output);
}

function from (time, withoutSuffix) {
    if (this.isValid() &&
            ((isMoment(time) && time.isValid()) ||
             createLocal(time).isValid())) {
        return createDuration({to: this, from: time}).locale(this.locale()).humanize(!withoutSuffix);
    } else {
        return this.localeData().invalidDate();
    }
}

function fromNow (withoutSuffix) {
    return this.from(createLocal(), withoutSuffix);
}

function to (time, withoutSuffix) {
    if (this.isValid() &&
            ((isMoment(time) && time.isValid()) ||
             createLocal(time).isValid())) {
        return createDuration({from: this, to: time}).locale(this.locale()).humanize(!withoutSuffix);
    } else {
        return this.localeData().invalidDate();
    }
}

function toNow (withoutSuffix) {
    return this.to(createLocal(), withoutSuffix);
}

// If passed a locale key, it will set the locale for this
// instance.  Otherwise, it will return the locale configuration
// variables for this instance.
function locale (key) {
    var newLocaleData;

    if (key === undefined) {
        return this._locale._abbr;
    } else {
        newLocaleData = getLocale(key);
        if (newLocaleData != null) {
            this._locale = newLocaleData;
        }
        return this;
    }
}

var lang = deprecate(
    'moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.',
    function (key) {
        if (key === undefined) {
            return this.localeData();
        } else {
            return this.locale(key);
        }
    }
);

function localeData () {
    return this._locale;
}

function startOf (units) {
    units = normalizeUnits(units);
    // the following switch intentionally omits break keywords
    // to utilize falling through the cases.
    switch (units) {
        case 'year':
            this.month(0);
            /* falls through */
        case 'quarter':
        case 'month':
            this.date(1);
            /* falls through */
        case 'week':
        case 'isoWeek':
        case 'day':
        case 'date':
            this.hours(0);
            /* falls through */
        case 'hour':
            this.minutes(0);
            /* falls through */
        case 'minute':
            this.seconds(0);
            /* falls through */
        case 'second':
            this.milliseconds(0);
    }

    // weeks are a special case
    if (units === 'week') {
        this.weekday(0);
    }
    if (units === 'isoWeek') {
        this.isoWeekday(1);
    }

    // quarters are also special
    if (units === 'quarter') {
        this.month(Math.floor(this.month() / 3) * 3);
    }

    return this;
}

function endOf (units) {
    units = normalizeUnits(units);
    if (units === undefined || units === 'millisecond') {
        return this;
    }

    // 'date' is an alias for 'day', so it should be considered as such.
    if (units === 'date') {
        units = 'day';
    }

    return this.startOf(units).add(1, (units === 'isoWeek' ? 'week' : units)).subtract(1, 'ms');
}

function valueOf () {
    return this._d.valueOf() - ((this._offset || 0) * 60000);
}

function unix () {
    return Math.floor(this.valueOf() / 1000);
}

function toDate () {
    return new Date(this.valueOf());
}

function toArray () {
    var m = this;
    return [m.year(), m.month(), m.date(), m.hour(), m.minute(), m.second(), m.millisecond()];
}

function toObject () {
    var m = this;
    return {
        years: m.year(),
        months: m.month(),
        date: m.date(),
        hours: m.hours(),
        minutes: m.minutes(),
        seconds: m.seconds(),
        milliseconds: m.milliseconds()
    };
}

function toJSON () {
    // new Date(NaN).toJSON() === null
    return this.isValid() ? this.toISOString() : null;
}

function isValid$2 () {
    return isValid(this);
}

function parsingFlags () {
    return extend({}, getParsingFlags(this));
}

function invalidAt () {
    return getParsingFlags(this).overflow;
}

function creationData() {
    return {
        input: this._i,
        format: this._f,
        locale: this._locale,
        isUTC: this._isUTC,
        strict: this._strict
    };
}

// FORMATTING

addFormatToken(0, ['gg', 2], 0, function () {
    return this.weekYear() % 100;
});

addFormatToken(0, ['GG', 2], 0, function () {
    return this.isoWeekYear() % 100;
});

function addWeekYearFormatToken (token, getter) {
    addFormatToken(0, [token, token.length], 0, getter);
}

addWeekYearFormatToken('gggg',     'weekYear');
addWeekYearFormatToken('ggggg',    'weekYear');
addWeekYearFormatToken('GGGG',  'isoWeekYear');
addWeekYearFormatToken('GGGGG', 'isoWeekYear');

// ALIASES

addUnitAlias('weekYear', 'gg');
addUnitAlias('isoWeekYear', 'GG');

// PRIORITY

addUnitPriority('weekYear', 1);
addUnitPriority('isoWeekYear', 1);


// PARSING

addRegexToken('G',      matchSigned);
addRegexToken('g',      matchSigned);
addRegexToken('GG',     match1to2, match2);
addRegexToken('gg',     match1to2, match2);
addRegexToken('GGGG',   match1to4, match4);
addRegexToken('gggg',   match1to4, match4);
addRegexToken('GGGGG',  match1to6, match6);
addRegexToken('ggggg',  match1to6, match6);

addWeekParseToken(['gggg', 'ggggg', 'GGGG', 'GGGGG'], function (input, week, config, token) {
    week[token.substr(0, 2)] = toInt(input);
});

addWeekParseToken(['gg', 'GG'], function (input, week, config, token) {
    week[token] = hooks.parseTwoDigitYear(input);
});

// MOMENTS

function getSetWeekYear (input) {
    return getSetWeekYearHelper.call(this,
            input,
            this.week(),
            this.weekday(),
            this.localeData()._week.dow,
            this.localeData()._week.doy);
}

function getSetISOWeekYear (input) {
    return getSetWeekYearHelper.call(this,
            input, this.isoWeek(), this.isoWeekday(), 1, 4);
}

function getISOWeeksInYear () {
    return weeksInYear(this.year(), 1, 4);
}

function getWeeksInYear () {
    var weekInfo = this.localeData()._week;
    return weeksInYear(this.year(), weekInfo.dow, weekInfo.doy);
}

function getSetWeekYearHelper(input, week, weekday, dow, doy) {
    var weeksTarget;
    if (input == null) {
        return weekOfYear(this, dow, doy).year;
    } else {
        weeksTarget = weeksInYear(input, dow, doy);
        if (week > weeksTarget) {
            week = weeksTarget;
        }
        return setWeekAll.call(this, input, week, weekday, dow, doy);
    }
}

function setWeekAll(weekYear, week, weekday, dow, doy) {
    var dayOfYearData = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy),
        date = createUTCDate(dayOfYearData.year, 0, dayOfYearData.dayOfYear);

    this.year(date.getUTCFullYear());
    this.month(date.getUTCMonth());
    this.date(date.getUTCDate());
    return this;
}

// FORMATTING

addFormatToken('Q', 0, 'Qo', 'quarter');

// ALIASES

addUnitAlias('quarter', 'Q');

// PRIORITY

addUnitPriority('quarter', 7);

// PARSING

addRegexToken('Q', match1);
addParseToken('Q', function (input, array) {
    array[MONTH] = (toInt(input) - 1) * 3;
});

// MOMENTS

function getSetQuarter (input) {
    return input == null ? Math.ceil((this.month() + 1) / 3) : this.month((input - 1) * 3 + this.month() % 3);
}

// FORMATTING

addFormatToken('D', ['DD', 2], 'Do', 'date');

// ALIASES

addUnitAlias('date', 'D');

// PRIOROITY
addUnitPriority('date', 9);

// PARSING

addRegexToken('D',  match1to2);
addRegexToken('DD', match1to2, match2);
addRegexToken('Do', function (isStrict, locale) {
    // TODO: Remove "ordinalParse" fallback in next major release.
    return isStrict ?
      (locale._dayOfMonthOrdinalParse || locale._ordinalParse) :
      locale._dayOfMonthOrdinalParseLenient;
});

addParseToken(['D', 'DD'], DATE);
addParseToken('Do', function (input, array) {
    array[DATE] = toInt(input.match(match1to2)[0]);
});

// MOMENTS

var getSetDayOfMonth = makeGetSet('Date', true);

// FORMATTING

addFormatToken('DDD', ['DDDD', 3], 'DDDo', 'dayOfYear');

// ALIASES

addUnitAlias('dayOfYear', 'DDD');

// PRIORITY
addUnitPriority('dayOfYear', 4);

// PARSING

addRegexToken('DDD',  match1to3);
addRegexToken('DDDD', match3);
addParseToken(['DDD', 'DDDD'], function (input, array, config) {
    config._dayOfYear = toInt(input);
});

// HELPERS

// MOMENTS

function getSetDayOfYear (input) {
    var dayOfYear = Math.round((this.clone().startOf('day') - this.clone().startOf('year')) / 864e5) + 1;
    return input == null ? dayOfYear : this.add((input - dayOfYear), 'd');
}

// FORMATTING

addFormatToken('m', ['mm', 2], 0, 'minute');

// ALIASES

addUnitAlias('minute', 'm');

// PRIORITY

addUnitPriority('minute', 14);

// PARSING

addRegexToken('m',  match1to2);
addRegexToken('mm', match1to2, match2);
addParseToken(['m', 'mm'], MINUTE);

// MOMENTS

var getSetMinute = makeGetSet('Minutes', false);

// FORMATTING

addFormatToken('s', ['ss', 2], 0, 'second');

// ALIASES

addUnitAlias('second', 's');

// PRIORITY

addUnitPriority('second', 15);

// PARSING

addRegexToken('s',  match1to2);
addRegexToken('ss', match1to2, match2);
addParseToken(['s', 'ss'], SECOND);

// MOMENTS

var getSetSecond = makeGetSet('Seconds', false);

// FORMATTING

addFormatToken('S', 0, 0, function () {
    return ~~(this.millisecond() / 100);
});

addFormatToken(0, ['SS', 2], 0, function () {
    return ~~(this.millisecond() / 10);
});

addFormatToken(0, ['SSS', 3], 0, 'millisecond');
addFormatToken(0, ['SSSS', 4], 0, function () {
    return this.millisecond() * 10;
});
addFormatToken(0, ['SSSSS', 5], 0, function () {
    return this.millisecond() * 100;
});
addFormatToken(0, ['SSSSSS', 6], 0, function () {
    return this.millisecond() * 1000;
});
addFormatToken(0, ['SSSSSSS', 7], 0, function () {
    return this.millisecond() * 10000;
});
addFormatToken(0, ['SSSSSSSS', 8], 0, function () {
    return this.millisecond() * 100000;
});
addFormatToken(0, ['SSSSSSSSS', 9], 0, function () {
    return this.millisecond() * 1000000;
});


// ALIASES

addUnitAlias('millisecond', 'ms');

// PRIORITY

addUnitPriority('millisecond', 16);

// PARSING

addRegexToken('S',    match1to3, match1);
addRegexToken('SS',   match1to3, match2);
addRegexToken('SSS',  match1to3, match3);

var token;
for (token = 'SSSS'; token.length <= 9; token += 'S') {
    addRegexToken(token, matchUnsigned);
}

function parseMs(input, array) {
    array[MILLISECOND] = toInt(('0.' + input) * 1000);
}

for (token = 'S'; token.length <= 9; token += 'S') {
    addParseToken(token, parseMs);
}
// MOMENTS

var getSetMillisecond = makeGetSet('Milliseconds', false);

// FORMATTING

addFormatToken('z',  0, 0, 'zoneAbbr');
addFormatToken('zz', 0, 0, 'zoneName');

// MOMENTS

function getZoneAbbr () {
    return this._isUTC ? 'UTC' : '';
}

function getZoneName () {
    return this._isUTC ? 'Coordinated Universal Time' : '';
}

var proto = Moment.prototype;

proto.add               = add;
proto.calendar          = calendar$1;
proto.clone             = clone;
proto.diff              = diff;
proto.endOf             = endOf;
proto.format            = format;
proto.from              = from;
proto.fromNow           = fromNow;
proto.to                = to;
proto.toNow             = toNow;
proto.get               = stringGet;
proto.invalidAt         = invalidAt;
proto.isAfter           = isAfter;
proto.isBefore          = isBefore;
proto.isBetween         = isBetween;
proto.isSame            = isSame;
proto.isSameOrAfter     = isSameOrAfter;
proto.isSameOrBefore    = isSameOrBefore;
proto.isValid           = isValid$2;
proto.lang              = lang;
proto.locale            = locale;
proto.localeData        = localeData;
proto.max               = prototypeMax;
proto.min               = prototypeMin;
proto.parsingFlags      = parsingFlags;
proto.set               = stringSet;
proto.startOf           = startOf;
proto.subtract          = subtract;
proto.toArray           = toArray;
proto.toObject          = toObject;
proto.toDate            = toDate;
proto.toISOString       = toISOString;
proto.inspect           = inspect;
proto.toJSON            = toJSON;
proto.toString          = toString;
proto.unix              = unix;
proto.valueOf           = valueOf;
proto.creationData      = creationData;

// Year
proto.year       = getSetYear;
proto.isLeapYear = getIsLeapYear;

// Week Year
proto.weekYear    = getSetWeekYear;
proto.isoWeekYear = getSetISOWeekYear;

// Quarter
proto.quarter = proto.quarters = getSetQuarter;

// Month
proto.month       = getSetMonth;
proto.daysInMonth = getDaysInMonth;

// Week
proto.week           = proto.weeks        = getSetWeek;
proto.isoWeek        = proto.isoWeeks     = getSetISOWeek;
proto.weeksInYear    = getWeeksInYear;
proto.isoWeeksInYear = getISOWeeksInYear;

// Day
proto.date       = getSetDayOfMonth;
proto.day        = proto.days             = getSetDayOfWeek;
proto.weekday    = getSetLocaleDayOfWeek;
proto.isoWeekday = getSetISODayOfWeek;
proto.dayOfYear  = getSetDayOfYear;

// Hour
proto.hour = proto.hours = getSetHour;

// Minute
proto.minute = proto.minutes = getSetMinute;

// Second
proto.second = proto.seconds = getSetSecond;

// Millisecond
proto.millisecond = proto.milliseconds = getSetMillisecond;

// Offset
proto.utcOffset            = getSetOffset;
proto.utc                  = setOffsetToUTC;
proto.local                = setOffsetToLocal;
proto.parseZone            = setOffsetToParsedOffset;
proto.hasAlignedHourOffset = hasAlignedHourOffset;
proto.isDST                = isDaylightSavingTime;
proto.isLocal              = isLocal;
proto.isUtcOffset          = isUtcOffset;
proto.isUtc                = isUtc;
proto.isUTC                = isUtc;

// Timezone
proto.zoneAbbr = getZoneAbbr;
proto.zoneName = getZoneName;

// Deprecations
proto.dates  = deprecate('dates accessor is deprecated. Use date instead.', getSetDayOfMonth);
proto.months = deprecate('months accessor is deprecated. Use month instead', getSetMonth);
proto.years  = deprecate('years accessor is deprecated. Use year instead', getSetYear);
proto.zone   = deprecate('moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/', getSetZone);
proto.isDSTShifted = deprecate('isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information', isDaylightSavingTimeShifted);

function createUnix (input) {
    return createLocal(input * 1000);
}

function createInZone () {
    return createLocal.apply(null, arguments).parseZone();
}

function preParsePostFormat (string) {
    return string;
}

var proto$1 = Locale.prototype;

proto$1.calendar        = calendar;
proto$1.longDateFormat  = longDateFormat;
proto$1.invalidDate     = invalidDate;
proto$1.ordinal         = ordinal;
proto$1.preparse        = preParsePostFormat;
proto$1.postformat      = preParsePostFormat;
proto$1.relativeTime    = relativeTime;
proto$1.pastFuture      = pastFuture;
proto$1.set             = set;

// Month
proto$1.months            =        localeMonths;
proto$1.monthsShort       =        localeMonthsShort;
proto$1.monthsParse       =        localeMonthsParse;
proto$1.monthsRegex       = monthsRegex;
proto$1.monthsShortRegex  = monthsShortRegex;

// Week
proto$1.week = localeWeek;
proto$1.firstDayOfYear = localeFirstDayOfYear;
proto$1.firstDayOfWeek = localeFirstDayOfWeek;

// Day of Week
proto$1.weekdays       =        localeWeekdays;
proto$1.weekdaysMin    =        localeWeekdaysMin;
proto$1.weekdaysShort  =        localeWeekdaysShort;
proto$1.weekdaysParse  =        localeWeekdaysParse;

proto$1.weekdaysRegex       =        weekdaysRegex;
proto$1.weekdaysShortRegex  =        weekdaysShortRegex;
proto$1.weekdaysMinRegex    =        weekdaysMinRegex;

// Hours
proto$1.isPM = localeIsPM;
proto$1.meridiem = localeMeridiem;

function get$1 (format, index, field, setter) {
    var locale = getLocale();
    var utc = createUTC().set(setter, index);
    return locale[field](utc, format);
}

function listMonthsImpl (format, index, field) {
    if (isNumber(format)) {
        index = format;
        format = undefined;
    }

    format = format || '';

    if (index != null) {
        return get$1(format, index, field, 'month');
    }

    var i;
    var out = [];
    for (i = 0; i < 12; i++) {
        out[i] = get$1(format, i, field, 'month');
    }
    return out;
}

// ()
// (5)
// (fmt, 5)
// (fmt)
// (true)
// (true, 5)
// (true, fmt, 5)
// (true, fmt)
function listWeekdaysImpl (localeSorted, format, index, field) {
    if (typeof localeSorted === 'boolean') {
        if (isNumber(format)) {
            index = format;
            format = undefined;
        }

        format = format || '';
    } else {
        format = localeSorted;
        index = format;
        localeSorted = false;

        if (isNumber(format)) {
            index = format;
            format = undefined;
        }

        format = format || '';
    }

    var locale = getLocale(),
        shift = localeSorted ? locale._week.dow : 0;

    if (index != null) {
        return get$1(format, (index + shift) % 7, field, 'day');
    }

    var i;
    var out = [];
    for (i = 0; i < 7; i++) {
        out[i] = get$1(format, (i + shift) % 7, field, 'day');
    }
    return out;
}

function listMonths (format, index) {
    return listMonthsImpl(format, index, 'months');
}

function listMonthsShort (format, index) {
    return listMonthsImpl(format, index, 'monthsShort');
}

function listWeekdays (localeSorted, format, index) {
    return listWeekdaysImpl(localeSorted, format, index, 'weekdays');
}

function listWeekdaysShort (localeSorted, format, index) {
    return listWeekdaysImpl(localeSorted, format, index, 'weekdaysShort');
}

function listWeekdaysMin (localeSorted, format, index) {
    return listWeekdaysImpl(localeSorted, format, index, 'weekdaysMin');
}

getSetGlobalLocale('en', {
    dayOfMonthOrdinalParse: /\d{1,2}(th|st|nd|rd)/,
    ordinal : function (number) {
        var b = number % 10,
            output = (toInt(number % 100 / 10) === 1) ? 'th' :
            (b === 1) ? 'st' :
            (b === 2) ? 'nd' :
            (b === 3) ? 'rd' : 'th';
        return number + output;
    }
});

// Side effect imports
hooks.lang = deprecate('moment.lang is deprecated. Use moment.locale instead.', getSetGlobalLocale);
hooks.langData = deprecate('moment.langData is deprecated. Use moment.localeData instead.', getLocale);

var mathAbs = Math.abs;

function abs () {
    var data           = this._data;

    this._milliseconds = mathAbs(this._milliseconds);
    this._days         = mathAbs(this._days);
    this._months       = mathAbs(this._months);

    data.milliseconds  = mathAbs(data.milliseconds);
    data.seconds       = mathAbs(data.seconds);
    data.minutes       = mathAbs(data.minutes);
    data.hours         = mathAbs(data.hours);
    data.months        = mathAbs(data.months);
    data.years         = mathAbs(data.years);

    return this;
}

function addSubtract$1 (duration, input, value, direction) {
    var other = createDuration(input, value);

    duration._milliseconds += direction * other._milliseconds;
    duration._days         += direction * other._days;
    duration._months       += direction * other._months;

    return duration._bubble();
}

// supports only 2.0-style add(1, 's') or add(duration)
function add$1 (input, value) {
    return addSubtract$1(this, input, value, 1);
}

// supports only 2.0-style subtract(1, 's') or subtract(duration)
function subtract$1 (input, value) {
    return addSubtract$1(this, input, value, -1);
}

function absCeil (number) {
    if (number < 0) {
        return Math.floor(number);
    } else {
        return Math.ceil(number);
    }
}

function bubble () {
    var milliseconds = this._milliseconds;
    var days         = this._days;
    var months       = this._months;
    var data         = this._data;
    var seconds, minutes, hours, years, monthsFromDays;

    // if we have a mix of positive and negative values, bubble down first
    // check: https://github.com/moment/moment/issues/2166
    if (!((milliseconds >= 0 && days >= 0 && months >= 0) ||
            (milliseconds <= 0 && days <= 0 && months <= 0))) {
        milliseconds += absCeil(monthsToDays(months) + days) * 864e5;
        days = 0;
        months = 0;
    }

    // The following code bubbles up values, see the tests for
    // examples of what that means.
    data.milliseconds = milliseconds % 1000;

    seconds           = absFloor(milliseconds / 1000);
    data.seconds      = seconds % 60;

    minutes           = absFloor(seconds / 60);
    data.minutes      = minutes % 60;

    hours             = absFloor(minutes / 60);
    data.hours        = hours % 24;

    days += absFloor(hours / 24);

    // convert days to months
    monthsFromDays = absFloor(daysToMonths(days));
    months += monthsFromDays;
    days -= absCeil(monthsToDays(monthsFromDays));

    // 12 months -> 1 year
    years = absFloor(months / 12);
    months %= 12;

    data.days   = days;
    data.months = months;
    data.years  = years;

    return this;
}

function daysToMonths (days) {
    // 400 years have 146097 days (taking into account leap year rules)
    // 400 years have 12 months === 4800
    return days * 4800 / 146097;
}

function monthsToDays (months) {
    // the reverse of daysToMonths
    return months * 146097 / 4800;
}

function as (units) {
    if (!this.isValid()) {
        return NaN;
    }
    var days;
    var months;
    var milliseconds = this._milliseconds;

    units = normalizeUnits(units);

    if (units === 'month' || units === 'year') {
        days   = this._days   + milliseconds / 864e5;
        months = this._months + daysToMonths(days);
        return units === 'month' ? months : months / 12;
    } else {
        // handle milliseconds separately because of floating point math errors (issue #1867)
        days = this._days + Math.round(monthsToDays(this._months));
        switch (units) {
            case 'week'   : return days / 7     + milliseconds / 6048e5;
            case 'day'    : return days         + milliseconds / 864e5;
            case 'hour'   : return days * 24    + milliseconds / 36e5;
            case 'minute' : return days * 1440  + milliseconds / 6e4;
            case 'second' : return days * 86400 + milliseconds / 1000;
            // Math.floor prevents floating point math errors here
            case 'millisecond': return Math.floor(days * 864e5) + milliseconds;
            default: throw new Error('Unknown unit ' + units);
        }
    }
}

// TODO: Use this.as('ms')?
function valueOf$1 () {
    if (!this.isValid()) {
        return NaN;
    }
    return (
        this._milliseconds +
        this._days * 864e5 +
        (this._months % 12) * 2592e6 +
        toInt(this._months / 12) * 31536e6
    );
}

function makeAs (alias) {
    return function () {
        return this.as(alias);
    };
}

var asMilliseconds = makeAs('ms');
var asSeconds      = makeAs('s');
var asMinutes      = makeAs('m');
var asHours        = makeAs('h');
var asDays         = makeAs('d');
var asWeeks        = makeAs('w');
var asMonths       = makeAs('M');
var asYears        = makeAs('y');

function clone$1 () {
    return createDuration(this);
}

function get$2 (units) {
    units = normalizeUnits(units);
    return this.isValid() ? this[units + 's']() : NaN;
}

function makeGetter(name) {
    return function () {
        return this.isValid() ? this._data[name] : NaN;
    };
}

var milliseconds = makeGetter('milliseconds');
var seconds      = makeGetter('seconds');
var minutes      = makeGetter('minutes');
var hours        = makeGetter('hours');
var days         = makeGetter('days');
var months       = makeGetter('months');
var years        = makeGetter('years');

function weeks () {
    return absFloor(this.days() / 7);
}

var round = Math.round;
var thresholds = {
    ss: 44,         // a few seconds to seconds
    s : 45,         // seconds to minute
    m : 45,         // minutes to hour
    h : 22,         // hours to day
    d : 26,         // days to month
    M : 11          // months to year
};

// helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize
function substituteTimeAgo(string, number, withoutSuffix, isFuture, locale) {
    return locale.relativeTime(number || 1, !!withoutSuffix, string, isFuture);
}

function relativeTime$1 (posNegDuration, withoutSuffix, locale) {
    var duration = createDuration(posNegDuration).abs();
    var seconds  = round(duration.as('s'));
    var minutes  = round(duration.as('m'));
    var hours    = round(duration.as('h'));
    var days     = round(duration.as('d'));
    var months   = round(duration.as('M'));
    var years    = round(duration.as('y'));

    var a = seconds <= thresholds.ss && ['s', seconds]  ||
            seconds < thresholds.s   && ['ss', seconds] ||
            minutes <= 1             && ['m']           ||
            minutes < thresholds.m   && ['mm', minutes] ||
            hours   <= 1             && ['h']           ||
            hours   < thresholds.h   && ['hh', hours]   ||
            days    <= 1             && ['d']           ||
            days    < thresholds.d   && ['dd', days]    ||
            months  <= 1             && ['M']           ||
            months  < thresholds.M   && ['MM', months]  ||
            years   <= 1             && ['y']           || ['yy', years];

    a[2] = withoutSuffix;
    a[3] = +posNegDuration > 0;
    a[4] = locale;
    return substituteTimeAgo.apply(null, a);
}

// This function allows you to set the rounding function for relative time strings
function getSetRelativeTimeRounding (roundingFunction) {
    if (roundingFunction === undefined) {
        return round;
    }
    if (typeof(roundingFunction) === 'function') {
        round = roundingFunction;
        return true;
    }
    return false;
}

// This function allows you to set a threshold for relative time strings
function getSetRelativeTimeThreshold (threshold, limit) {
    if (thresholds[threshold] === undefined) {
        return false;
    }
    if (limit === undefined) {
        return thresholds[threshold];
    }
    thresholds[threshold] = limit;
    if (threshold === 's') {
        thresholds.ss = limit - 1;
    }
    return true;
}

function humanize (withSuffix) {
    if (!this.isValid()) {
        return this.localeData().invalidDate();
    }

    var locale = this.localeData();
    var output = relativeTime$1(this, !withSuffix, locale);

    if (withSuffix) {
        output = locale.pastFuture(+this, output);
    }

    return locale.postformat(output);
}

var abs$1 = Math.abs;

function sign(x) {
    return ((x > 0) - (x < 0)) || +x;
}

function toISOString$1() {
    // for ISO strings we do not use the normal bubbling rules:
    //  * milliseconds bubble up until they become hours
    //  * days do not bubble at all
    //  * months bubble up until they become years
    // This is because there is no context-free conversion between hours and days
    // (think of clock changes)
    // and also not between days and months (28-31 days per month)
    if (!this.isValid()) {
        return this.localeData().invalidDate();
    }

    var seconds = abs$1(this._milliseconds) / 1000;
    var days         = abs$1(this._days);
    var months       = abs$1(this._months);
    var minutes, hours, years;

    // 3600 seconds -> 60 minutes -> 1 hour
    minutes           = absFloor(seconds / 60);
    hours             = absFloor(minutes / 60);
    seconds %= 60;
    minutes %= 60;

    // 12 months -> 1 year
    years  = absFloor(months / 12);
    months %= 12;


    // inspired by https://github.com/dordille/moment-isoduration/blob/master/moment.isoduration.js
    var Y = years;
    var M = months;
    var D = days;
    var h = hours;
    var m = minutes;
    var s = seconds ? seconds.toFixed(3).replace(/\.?0+$/, '') : '';
    var total = this.asSeconds();

    if (!total) {
        // this is the same as C#'s (Noda) and python (isodate)...
        // but not other JS (goog.date)
        return 'P0D';
    }

    var totalSign = total < 0 ? '-' : '';
    var ymSign = sign(this._months) !== sign(total) ? '-' : '';
    var daysSign = sign(this._days) !== sign(total) ? '-' : '';
    var hmsSign = sign(this._milliseconds) !== sign(total) ? '-' : '';

    return totalSign + 'P' +
        (Y ? ymSign + Y + 'Y' : '') +
        (M ? ymSign + M + 'M' : '') +
        (D ? daysSign + D + 'D' : '') +
        ((h || m || s) ? 'T' : '') +
        (h ? hmsSign + h + 'H' : '') +
        (m ? hmsSign + m + 'M' : '') +
        (s ? hmsSign + s + 'S' : '');
}

var proto$2 = Duration.prototype;

proto$2.isValid        = isValid$1;
proto$2.abs            = abs;
proto$2.add            = add$1;
proto$2.subtract       = subtract$1;
proto$2.as             = as;
proto$2.asMilliseconds = asMilliseconds;
proto$2.asSeconds      = asSeconds;
proto$2.asMinutes      = asMinutes;
proto$2.asHours        = asHours;
proto$2.asDays         = asDays;
proto$2.asWeeks        = asWeeks;
proto$2.asMonths       = asMonths;
proto$2.asYears        = asYears;
proto$2.valueOf        = valueOf$1;
proto$2._bubble        = bubble;
proto$2.clone          = clone$1;
proto$2.get            = get$2;
proto$2.milliseconds   = milliseconds;
proto$2.seconds        = seconds;
proto$2.minutes        = minutes;
proto$2.hours          = hours;
proto$2.days           = days;
proto$2.weeks          = weeks;
proto$2.months         = months;
proto$2.years          = years;
proto$2.humanize       = humanize;
proto$2.toISOString    = toISOString$1;
proto$2.toString       = toISOString$1;
proto$2.toJSON         = toISOString$1;
proto$2.locale         = locale;
proto$2.localeData     = localeData;

// Deprecations
proto$2.toIsoString = deprecate('toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)', toISOString$1);
proto$2.lang = lang;

// Side effect imports

// FORMATTING

addFormatToken('X', 0, 0, 'unix');
addFormatToken('x', 0, 0, 'valueOf');

// PARSING

addRegexToken('x', matchSigned);
addRegexToken('X', matchTimestamp);
addParseToken('X', function (input, array, config) {
    config._d = new Date(parseFloat(input, 10) * 1000);
});
addParseToken('x', function (input, array, config) {
    config._d = new Date(toInt(input));
});

// Side effect imports


hooks.version = '2.20.1';

setHookCallback(createLocal);

hooks.fn                    = proto;
hooks.min                   = min;
hooks.max                   = max;
hooks.now                   = now;
hooks.utc                   = createUTC;
hooks.unix                  = createUnix;
hooks.months                = listMonths;
hooks.isDate                = isDate;
hooks.locale                = getSetGlobalLocale;
hooks.invalid               = createInvalid;
hooks.duration              = createDuration;
hooks.isMoment              = isMoment;
hooks.weekdays              = listWeekdays;
hooks.parseZone             = createInZone;
hooks.localeData            = getLocale;
hooks.isDuration            = isDuration;
hooks.monthsShort           = listMonthsShort;
hooks.weekdaysMin           = listWeekdaysMin;
hooks.defineLocale          = defineLocale;
hooks.updateLocale          = updateLocale;
hooks.locales               = listLocales;
hooks.weekdaysShort         = listWeekdaysShort;
hooks.normalizeUnits        = normalizeUnits;
hooks.relativeTimeRounding  = getSetRelativeTimeRounding;
hooks.relativeTimeThreshold = getSetRelativeTimeThreshold;
hooks.calendarFormat        = getCalendarFormat;
hooks.prototype             = proto;

// currently HTML5 input type only supports 24-hour formats
hooks.HTML5_FMT = {
    DATETIME_LOCAL: 'YYYY-MM-DDTHH:mm',             // <input type="datetime-local" />
    DATETIME_LOCAL_SECONDS: 'YYYY-MM-DDTHH:mm:ss',  // <input type="datetime-local" step="1" />
    DATETIME_LOCAL_MS: 'YYYY-MM-DDTHH:mm:ss.SSS',   // <input type="datetime-local" step="0.001" />
    DATE: 'YYYY-MM-DD',                             // <input type="date" />
    TIME: 'HH:mm',                                  // <input type="time" />
    TIME_SECONDS: 'HH:mm:ss',                       // <input type="time" step="1" />
    TIME_MS: 'HH:mm:ss.SSS',                        // <input type="time" step="0.001" />
    WEEK: 'YYYY-[W]WW',                             // <input type="week" />
    MONTH: 'YYYY-MM'                                // <input type="month" />
};

return hooks;

})));

},{}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/index.js":[function(require,module,exports){
'use strict';

var InvoicingFakeServer = null;
try {
  InvoicingFakeServer = require('./lib/InvoicingFakeServer').default;
} catch (x) {
  // Do nothing, fake server not available.
}

module.exports = {
  setupFakeServer: function setupFakeServer(fakeServer) {
    if (!InvoicingFakeServer || !InvoicingFakeServer.getFakeResponses) {
      throw new Error('Fake server module is not available.');
    }
    fakeServer.addFakeResponses(InvoicingFakeServer.getFakeResponses());
  },


  BaseService: require('./lib/BaseClasses/BaseService').default,
  InvoicingService: require('./lib/InvoicingService').default,
  Currency: require('./lib/Currency').default,
  InvoicePayment: require('./lib/Payment').default,
  InvoicePaymentTerm: require('./lib/PaymentTerm').default,
  InvoiceRefund: require('./lib/Refund').default,
  InvoiceCCInfo: require('./lib/CCInfo').default,
  InvoiceAddress: require('./lib/Address').default,
  InvoiceBillingInfo: require('./lib/BillingInfo').default,
  InvoiceMerchantInfo: require('./lib/MerchantInfo').default,
  InvoiceShippingInfo: require('./lib/ShippingInfo').default,
  InvoiceItem: require('./lib/Item').default,
  InvoiceNotification: require('./lib/Notification').default,
  InvoicingRequester: require('./lib/Requester').default,
  InvoiceActions: require('./lib/InvoiceActions').default,
  InvoiceAttachment: require('./lib/Attachment').default,
  Invoice: require('./lib/Invoice').default,
  InvoiceListRequest: require('./lib/InvoiceListRequest').default,
  InvoiceListResponse: require('./lib/InvoiceListResponse').default,
  InvoiceSearchRequest: require('./lib/SearchRequest').default,
  AccountSummary: require('./lib/AccountSummary').default,
  AccountSummarySection: require('./lib/AccountSummarySection').default,
  Countries: require('./lib/Countries').default,
  Country: require('./lib/Country').default,
  InvoiceEnums: require('./lib/InvoiceEnums').default,
  InvoiceCustomAmount: require('./lib/CustomAmount').default,
  InvoiceConstants: require('./lib/InvoiceConstants').default,
  InvoiceTemplate: require('./lib/Template').default,

  $$: require('./lib/InvoiceBigNumber').$$
};
},{"./lib/AccountSummary":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/AccountSummary.js","./lib/AccountSummarySection":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/AccountSummarySection.js","./lib/Address":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/Address.js","./lib/Attachment":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/Attachment.js","./lib/BaseClasses/BaseService":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/BaseClasses/BaseService.js","./lib/BillingInfo":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/BillingInfo.js","./lib/CCInfo":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/CCInfo.js","./lib/Countries":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/Countries.js","./lib/Country":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/Country.js","./lib/Currency":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/Currency.js","./lib/CustomAmount":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/CustomAmount.js","./lib/Invoice":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/Invoice.js","./lib/InvoiceActions":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/InvoiceActions.js","./lib/InvoiceBigNumber":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/InvoiceBigNumber.js","./lib/InvoiceConstants":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/InvoiceConstants.js","./lib/InvoiceEnums":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/InvoiceEnums.js","./lib/InvoiceListRequest":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/InvoiceListRequest.js","./lib/InvoiceListResponse":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/InvoiceListResponse.js","./lib/InvoicingFakeServer":false,"./lib/InvoicingService":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/InvoicingService.js","./lib/Item":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/Item.js","./lib/MerchantInfo":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/MerchantInfo.js","./lib/Notification":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/Notification.js","./lib/Payment":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/Payment.js","./lib/PaymentTerm":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/PaymentTerm.js","./lib/Refund":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/Refund.js","./lib/Requester":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/Requester.js","./lib/SearchRequest":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/SearchRequest.js","./lib/ShippingInfo":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/ShippingInfo.js","./lib/Template":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/Template.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/AccountSummary.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

var _InvoiceEnums = require('./InvoiceEnums');

var _InvoiceEnums2 = _interopRequireDefault(_InvoiceEnums);

var _InvoiceBigNumber = require('./InvoiceBigNumber');

var _AccountSummarySection = require('./AccountSummarySection');

var _AccountSummarySection2 = _interopRequireDefault(_AccountSummarySection);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

/**
 * Account summary for current merchant
 * @class
 * @property {decimal} outstandingAmount outstanding amount on account
 * @property {AccountSummarySection} pastDueSection section summary
 *  containing past due invoice information
 * @property {AccountSummarySection} awaitingPaymentSection section
 *  summary containing awaiting invoice information
 * @property {AccountSummarySection} draftSection section summary
 *  containing draft invoice information
 * @property {AccountSummarySection} paidSection section summary
 *  containing paid invoice information
 */
var AccountSummary = function () {
  function AccountSummary(nonOverdueJson, overdueJson) {
    _classCallCheck(this, AccountSummary);

    this.pastDueSection = this.sectionFromSummaries(overdueJson.summaries);

    // The 'nonOverdueJson' actually includes overdue invoices.
    this.awaitingPaymentSection = this.sectionForStatuses([_InvoiceEnums2.default.Status.SENT, _InvoiceEnums2.default.Status.PARTIALLY_PAID, _InvoiceEnums2.default.Status.UNPAID, _InvoiceEnums2.default.Status.SCHEDULED], nonOverdueJson);

    this.draftSection = this.sectionForStatuses([_InvoiceEnums2.default.Status.DRAFT], nonOverdueJson);

    this.paidSection = this.sectionForStatuses([_InvoiceEnums2.default.Status.MARKED_AS_PAID, _InvoiceEnums2.default.Status.PAID], nonOverdueJson);

    this.outstandingAmount = this.awaitingPaymentSection.totalAmount;
  }

  // Given an array of invoice statuses and a JSON response from the summary endpoint, returns
  // an AccountSummarySection whose values are the sum of all the summaries whose statuses
  // are in the status array


  AccountSummary.prototype.sectionForStatuses = function sectionForStatuses(statuses, json) {
    return this.sectionFromSummaries(this.summariesForStatuses(statuses, json));
  };

  // Given an array of invoice statuses and a JSON response from the summary endpoint, returns an
  // array of the summaries whose statuses are in the status array


  AccountSummary.prototype.summariesForStatuses = function summariesForStatuses(statuses, json) {
    var retVal = [];
    for (var _iterator = json.summaries, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
      var _ref;

      if (_isArray) {
        if (_i >= _iterator.length) break;
        _ref = _iterator[_i++];
      } else {
        _i = _iterator.next();
        if (_i.done) break;
        _ref = _i.value;
      }

      var summary = _ref;

      if (statuses.indexOf(_InvoiceEnums2.default.Status[summary.status]) >= 0) {
        retVal.push(summary);
      }
    }
    return retVal;
  };

  // Given an array of summaries, sums all their values into an AccountSummarySection


  AccountSummary.prototype.sectionFromSummaries = function sectionFromSummaries(summaries) {
    var count = 0;
    var totalAmount = (0, _InvoiceBigNumber.$$)('0');
    var paidAmount = (0, _InvoiceBigNumber.$$)('0');
    var refundedAmount = (0, _InvoiceBigNumber.$$)('0');
    for (var _iterator2 = summaries, _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) {
      var _ref2;

      if (_isArray2) {
        if (_i2 >= _iterator2.length) break;
        _ref2 = _iterator2[_i2++];
      } else {
        _i2 = _iterator2.next();
        if (_i2.done) break;
        _ref2 = _i2.value;
      }

      var summary = _ref2;

      count += summary.count;
      if (summary.amount_summary && summary.amount_summary.length) {
        // TODO: the amount_summary array contains multiple summaries
        // grouped by currency codes. Right now we just take the first.
        // Weird stuff will happen if we actually get multiple currencies.
        var amountSummary = summary.amount_summary[0];
        if (amountSummary.total_amount) {
          totalAmount = totalAmount.add((0, _InvoiceBigNumber.$$)(amountSummary.total_amount.value));
        }
        if (amountSummary.paid_amount) {
          if (amountSummary.paid_amount.other) {
            paidAmount = paidAmount.add((0, _InvoiceBigNumber.$$)(amountSummary.paid_amount.other.value));
          }
          if (amountSummary.paid_amount.paypal) {
            paidAmount = paidAmount.add((0, _InvoiceBigNumber.$$)(amountSummary.paid_amount.paypal.value));
          }
        }
        if (amountSummary.refunded_amount) {
          if (amountSummary.refunded_amount.other) {
            refundedAmount = refundedAmount.add((0, _InvoiceBigNumber.$$)(amountSummary.refunded_amount.other.value));
          }
          if (amountSummary.refunded_amount.paypal) {
            refundedAmount = refundedAmount.add((0, _InvoiceBigNumber.$$)(amountSummary.refunded_amount.paypal.value));
          }
        }
      }
    }
    return new _AccountSummarySection2.default(count, totalAmount, paidAmount, refundedAmount);
  };

  AccountSummary.prototype.subtractSection = function subtractSection(section1, section2) {
    return new _AccountSummarySection2.default(section1.totalCount - section2.totalCount, section1.totalAmount.minus(section2.totalAmount), section1.paidAmount.minus(section2.paidAmount), section1.refundedAmount.minus(section2.refundedAmount));
  };

  return AccountSummary;
}();

exports.default = AccountSummary;
},{"./AccountSummarySection":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/AccountSummarySection.js","./InvoiceBigNumber":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/InvoiceBigNumber.js","./InvoiceEnums":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/InvoiceEnums.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/AccountSummarySection.js":[function(require,module,exports){
"use strict";

exports.__esModule = true;

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

/**
 * Account summary for current merchant
 * @class
 * @property {decimal} totalCount total count of invoices for section
 * @property {decimal} totalAmount total amount for section
 * @property {decimal} paidAmount paid amount for section
 * @property {decimal} refundedAmount refunded amount for section
 */
var AccountSummarySection = function AccountSummarySection(totalCount, totalAmount, paidAmount, refundedAmount) {
  _classCallCheck(this, AccountSummarySection);

  this.totalCount = totalCount;
  this.totalAmount = totalAmount;
  this.paidAmount = paidAmount;
  this.refundedAmount = refundedAmount;
};

exports.default = AccountSummarySection;
},{}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/Address.js":[function(require,module,exports){
"use strict";

exports.__esModule = true;

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

/**
 * Container for addresses used on various invoice entities
 * @class
 *
 * @property {string} line1 First line of the address @required
 * @property {string} line2 Second line of the address
 * @property {string} city City portion of the address
 * @property {string} state State, if applicable
 * @property {string} postalCode Postal Code
 * @property {string} country ISO two letter country code @required
 * @property {string} phone Phone number in E.123 format.
 * @property {bool} isPrimary
 * @property {string} addressee
 */
var InvoiceAddress = function () {
  function InvoiceAddress() {
    _classCallCheck(this, InvoiceAddress);
  }

  InvoiceAddress.prototype.readFromJson = function readFromJson(json) {
    if (json) {
      this.line1 = json.line1;
      if (!this.line1 && json.addressLine1) {
        this.line1 = json.addressLine1;
      }
      this.line2 = json.line2;
      if (!this.line2 && json.addressLine2) {
        this.line2 = json.addressLine2;
      }
      this.city = json.city;
      this.state = json.state;
      this.postalCode = json.postal_code;
      this.country = json.country_code;
      this.phone = json.phone;
      this.addressee = json.addressee_name;
      this.isPrimary = json.isPrimary;
    }
  };

  InvoiceAddress.prototype.toJSON = function toJSON() {
    var r = void 0;
    if (this.hasAnyValue()) {
      r = {};
      r.line1 = this.line1;
      r.line2 = this.line2;
      r.city = this.city;
      r.state = this.state;
      r.postal_code = this.postalCode;
      r.country_code = this.country;
      r.addressee = this.addressee;
      r.isPrimary = this.isPrimary;
      r.phone = this.phone;
    }
    return r;
  };

  /**
   * Check to see if this object has any value
   * @returns {bool}
   */


  InvoiceAddress.prototype.hasAnyValue = function hasAnyValue() {
    if (this.line1 || this.line2 || this.city || this.state || this.postalCode || this.country || this.addressee || this.phone) {
      return true;
    }
    return false;
  };

  return InvoiceAddress;
}();

exports.default = InvoiceAddress;
},{}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/Attachment.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

/**
 * Invoice attachment
 * @class
 * @property {string} name name of the attachment
 * @property {string} url url of the attachment
 */
var InvoiceAttachment = function () {
  function InvoiceAttachment() {
    _classCallCheck(this, InvoiceAttachment);
  }

  InvoiceAttachment.readFromJson = function readFromJson(json) {
    var a = new InvoiceAttachment();

    a.name = json.name;
    a.url = json.url;

    return a;
  };

  InvoiceAttachment.prototype.toJSON = function toJSON() {
    var r = {};

    r.name = this.name;
    r.url = this.url;

    return r;
  };

  /**
   * workaround for known API issue, returns usable version of the URL
   * @returns {string} the usable url
   */


  InvoiceAttachment.prototype.usableURL = function usableURL() {
    var re = new RegExp('sig.*&');
    var section = this.url.match(re)[0];
    var newSection = section.split('/').join('.').split('+').join('-').replace('=&', '&');
    var newURL = this.url.replace(section, newSection);

    return newURL;
  };

  return InvoiceAttachment;
}();

exports.default = InvoiceAttachment;
},{}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/BaseClasses/BaseService.js":[function(require,module,exports){
"use strict";

exports.__esModule = true;

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

/**
 * @class
 */
var BaseService = function BaseService() {
  _classCallCheck(this, BaseService);
};

exports.default = BaseService;
},{}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/BillingInfo.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

var _Address = require('./Address');

var _Address2 = _interopRequireDefault(_Address);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

/**
 * Container for information about the payer or intended payer on an invoice
 * @class
 * @property {string} email The email address of the payer @required @length(1,260) @format(email)
 * @property {string} firstName The first name of the payer @length(,30)
 * @property {string} lastName The last name of the payer @length(,30)
 * @property {string} businessName The business name of the payer
 * @property {InvoiceAddress} address The address of the payer @length(,100)
 * @property {string} language Language of the email sent to the payer. Will
 *  only be used if payer doesn't have a PayPal account.
 * @property {string} additionalInfo Option to display additional information
 *  such as business hours. 40 characters max.
 * @property {string} notificationChannel Preferred notification channel of the
 *  payer. Email by default.
 * @property {string} countryCode Country code (in E.164 format). Assume length is n.
 * @property {string} nationalNumber In-country phone number (in E.164 format).
 *  Maximum (15 - n) digits
 */
var InvoiceBillingInfo = function () {
  function InvoiceBillingInfo() {
    _classCallCheck(this, InvoiceBillingInfo);

    this.address = new _Address2.default();
  }

  InvoiceBillingInfo.prototype.readFromJson = function readFromJson(json) {
    if (json) {
      this.address.readFromJson(json.address);
      this.firstName = json.first_name;
      this.lastName = json.last_name;
      this.businessName = json.business_name;
      this.email = json.email;
      this.language = json.language;
      this.additionalInfo = json.additional_info;
      this.notificationChannel = json.notification_channel;
      if (json.phone) {
        this.countryCode = json.phone.country_code;
        this.nationalNumber = json.phone.national_number;
      }
    }
  };

  InvoiceBillingInfo.prototype.toJSON = function toJSON() {
    var r = {};
    // If the address is empty, don't include it in the JSON.
    if (Object.keys(this.address).length) {
      r.address = this.address;
    }
    r.first_name = this.firstName;
    r.last_name = this.lastName;
    r.email = this.email;
    r.business_name = this.businessName;
    r.language = this.language;
    r.additional_info = this.additionalInfo;
    r.notification_channel = this.notificationChannel;

    if (this.nationalNumber) {
      r.phone = {};
      r.phone.country_code = this.countryCode;
      r.phone.national_number = this.nationalNumber;
    }

    return r;
  };

  /**
   * Check to see if this object has any value
   * @returns {bool}
   */


  InvoiceBillingInfo.prototype.hasAnyValue = function hasAnyValue() {
    if (this.email || this.firstName || this.lastName || this.businessName || this.address.hasAnyValue() || this.language || this.additionalInfo || this.notificationChannel || this.countryCode || this.nationalNumber) {
      return true;
    }
    return false;
  };

  return InvoiceBillingInfo;
}();

exports.default = InvoiceBillingInfo;
},{"./Address":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/Address.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/CCInfo.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

var _Address = require('./Address');

var _Address2 = _interopRequireDefault(_Address);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

/**
 * Container for information about a person CC'ed on an invoice
 * @class
 * @property {string} email The email address of the
 *  merchant @required @length(1,260) @format(email)
 * @property {string} firstName The first name of the merchant @length(,30)
 * @property {string} lastName The last name of the merchant @length(,30)
 * @property {InvoiceAddress} address The address of the merchant
 * @property {string} businessName The business name of the merchant
 * @property {string} phone The phone number of the merchant
 * @property {string} fax The fax number of the merchant
 * @property {string} website The URL of the merchant website @format{url}
 * @property {string} additionalInfo option to display additional info such as business hours
 **/
var InvoiceCCInfo = function () {
  function InvoiceCCInfo() {
    _classCallCheck(this, InvoiceCCInfo);

    this.address = new _Address2.default();
  }

  InvoiceCCInfo.fromJson = function fromJson(json) {
    var ccInfo = new InvoiceCCInfo();

    if (json) {
      ccInfo.address.readFromJson(json.address);
      ccInfo.firstName = json.first_name;
      ccInfo.lastName = json.last_name;
      ccInfo.businessName = json.business_name;
      ccInfo.email = json.email;
      ccInfo.phone = json.phone;
      ccInfo.fax = json.fax;
      ccInfo.website = json.website;
      ccInfo.additionalInfo = json.additional_info;
    }

    return ccInfo;
  };

  InvoiceCCInfo.prototype.toJSON = function toJSON() {
    var r = {};
    r.email = this.email;
    r.first_name = this.firstName;
    r.last_name = this.lastName;
    r.business_name = this.businessName;
    r.phone = this.phone;
    r.fax = this.fax;
    r.website = this.website;
    r.additional_info = this.additionalInfo;
    r.address = this.address;

    return r;
  };

  return InvoiceCCInfo;
}();

exports.default = InvoiceCCInfo;
},{"./Address":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/Address.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/Countries.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

var _Country = require('./Country');

var _Country2 = _interopRequireDefault(_Country);

var _CountryMap = require('./CountryMap');

var _CountryMap2 = _interopRequireDefault(_CountryMap);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

/**
 * @class
 *
 *
 */
var Countries = function () {
  function Countries() {
    _classCallCheck(this, Countries);
  }

  /**
   * @returns {[Country]}
   */
  Countries.countries = function countries() {
    if (!Countries._countries) {
      Countries._countries = [];
      for (var _iterator = Object.keys(_CountryMap2.default), _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
        var _ref;

        if (_isArray) {
          if (_i >= _iterator.length) break;
          _ref = _iterator[_i++];
        } else {
          _i = _iterator.next();
          if (_i.done) break;
          _ref = _i.value;
        }

        var countryCode = _ref;

        Countries._countries.push(new _Country2.default(countryCode, _CountryMap2.default[countryCode]));
      }
    }

    return Countries._countries;
  };

  /**
   * Given a country code, returns the full name of the country.
   * If there's no match, returns undefined.
   * @param {string} countryCode
   * @returns {string}
   */


  Countries.countryForCountryCode = function countryForCountryCode(countryCode) {
    if (!countryCode) {
      return undefined;
    }
    var upperCountryCode = countryCode.toUpperCase();

    for (var _iterator2 = this.countries(), _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) {
      var _ref2;

      if (_isArray2) {
        if (_i2 >= _iterator2.length) break;
        _ref2 = _iterator2[_i2++];
      } else {
        _i2 = _iterator2.next();
        if (_i2.done) break;
        _ref2 = _i2.value;
      }

      var country = _ref2;

      if (country.code === upperCountryCode) {
        if (country.name) {
          return country.name;
        }
      }
    }
    return undefined;
  };

  return Countries;
}();

exports.default = Countries;
},{"./Country":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/Country.js","./CountryMap":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/CountryMap.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/Country.js":[function(require,module,exports){
"use strict";

exports.__esModule = true;

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

/**
 * @class
 *
 * @property {string} code The code for a country @readonly
 * @property {string} name The name of a country @readonly
 */
var Country =
/**
 * Create a new country.
 * @constructor
 * @param {string} countryCode
 * @param {string} countryName
 */
function Country(countryCode, countryName) {
  _classCallCheck(this, Country);

  this.code = countryCode;
  this.name = countryName;
};

exports.default = Country;
},{}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/CountryMap.js":[function(require,module,exports){
arguments[4]["/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/CountryMap.js"][0].apply(exports,arguments)
},{}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/Currency.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

var _InvoiceBigNumber = require('./InvoiceBigNumber');

var _InvoiceBigNumber2 = _interopRequireDefault(_InvoiceBigNumber);

var _RoundingRules = require('./RoundingRules.js');

var _RoundingRules2 = _interopRequireDefault(_RoundingRules);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

var Currency = function () {
  function Currency() {
    _classCallCheck(this, Currency);
  }

  Currency.round = function round(currencyCode, amount) {
    var roundingPrecision = _RoundingRules2.default[currencyCode];
    return (0, _InvoiceBigNumber.$$)(amount).round(roundingPrecision, _InvoiceBigNumber2.default.ROUND_HALF_UP);
  };

  Currency.toCents = function toCents(currencyCode, amount) {
    var roundingPrecision = _RoundingRules2.default[currencyCode];
    return (0, _InvoiceBigNumber.$$)(10).pow(roundingPrecision).times(amount);
  };

  Currency.serverRound = function serverRound(currencyCode, amount) {
    var roundingPrecision = _RoundingRules2.default[currencyCode];
    return (0, _InvoiceBigNumber.IBN)((0, _InvoiceBigNumber.$$)(amount).round(roundingPrecision, _InvoiceBigNumber2.default.ROUND_HALF_UP), roundingPrecision, roundingPrecision !== 0);
  };

  return Currency;
}();

exports.default = Currency;
},{"./InvoiceBigNumber":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/InvoiceBigNumber.js","./RoundingRules.js":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/RoundingRules.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/CustomAmount.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

var _InvoiceBigNumber = require('./InvoiceBigNumber');

var _Currency = require('./Currency');

var _Currency2 = _interopRequireDefault(_Currency);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

/**
 * Container for custom amounts on invoices
 * @class
 *
 * @property {string} label Custom amount label
 * @property {decimal} amount this is an amount object on the server
 *  which has a string for currency, and value
 */
var InvoiceCustomAmount = function () {
  function InvoiceCustomAmount() {
    _classCallCheck(this, InvoiceCustomAmount);
  }

  InvoiceCustomAmount.fromJSON = function fromJSON(json) {
    var customAmount = new InvoiceCustomAmount();
    if (json.label) {
      customAmount.label = json.label;
    }

    if (json.amount) {
      customAmount.amount = (0, _InvoiceBigNumber.$$)(json.amount.value);
    }

    return customAmount;
  };

  InvoiceCustomAmount.prototype.toJSON = function toJSON(currencyCode) {
    var r = {};
    if (this.amount) {
      r.amount = {
        currency: currencyCode,
        value: _Currency2.default.serverRound(currencyCode, this.amount)
      };
    }
    r.label = this.label;

    return r;
  };

  return InvoiceCustomAmount;
}();

exports.default = InvoiceCustomAmount;
},{"./Currency":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/Currency.js","./InvoiceBigNumber":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/InvoiceBigNumber.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/Invoice.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

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; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

var _events = require('events');

var _deepEqual2 = require('deep-equal');

var _deepEqual3 = _interopRequireDefault(_deepEqual2);

var _manticoreLog = require('manticore-log');

var _manticoreLog2 = _interopRequireDefault(_manticoreLog);

var _InvoiceBigNumber = require('./InvoiceBigNumber');

var _Currency = require('./Currency');

var _Currency2 = _interopRequireDefault(_Currency);

var _CustomAmount = require('./CustomAmount');

var _CustomAmount2 = _interopRequireDefault(_CustomAmount);

var _Item = require('./Item');

var _Item2 = _interopRequireDefault(_Item);

var _MerchantInfo = require('./MerchantInfo');

var _MerchantInfo2 = _interopRequireDefault(_MerchantInfo);

var _BillingInfo = require('./BillingInfo');

var _BillingInfo2 = _interopRequireDefault(_BillingInfo);

var _assert = require('assert');

var _assert2 = _interopRequireDefault(_assert);

var _manticoreUtil = require('manticore-util');

var _InvoicingUtil = require('./InvoicingUtil');

var _InvoicingUtil2 = _interopRequireDefault(_InvoicingUtil);

var _Requester = require('./Requester');

var _ShippingInfo = require('./ShippingInfo');

var _ShippingInfo2 = _interopRequireDefault(_ShippingInfo);

var _InvoiceCalculator = require('./InvoiceCalculator');

var _InvoiceCalculator2 = _interopRequireDefault(_InvoiceCalculator);

var _CCInfo = require('./CCInfo');

var _CCInfo2 = _interopRequireDefault(_CCInfo);

var _Payment = require('./Payment');

var _Payment2 = _interopRequireDefault(_Payment);

var _PaymentTerm = require('./PaymentTerm');

var _PaymentTerm2 = _interopRequireDefault(_PaymentTerm);

var _Refund = require('./Refund');

var _Refund2 = _interopRequireDefault(_Refund);

var _Attachment = require('./Attachment');

var _Attachment2 = _interopRequireDefault(_Attachment);

var _InvoiceEnums = require('./InvoiceEnums');

var _InvoiceEnums2 = _interopRequireDefault(_InvoiceEnums);

var _InvoiceMetaData = require('./InvoiceMetaData');

var _InvoiceMetaData2 = _interopRequireDefault(_InvoiceMetaData);

var _InvoicingService = require('./InvoicingService');

var _InvoicingService2 = _interopRequireDefault(_InvoicingService);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (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 } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var Log = (0, _manticoreLog2.default)('invoicing');

// TODO: talk about the different dates correctly

function statusFromServer(s) {
  if (!s) {
    return _InvoiceEnums2.default.Status.NEW;
  } else if (_InvoiceEnums2.default.Status[s]) {
    return _InvoiceEnums2.default.Status[s];
  }
  Log.warn('Received unknown server invoice status ' + s);
  return _InvoiceEnums2.default.Status.DRAFT;
}

/**
 * Invoice is the fundamental transaction record for retail payments.
 * It contains header data, such as buyer and seller information and
 * {@link InvoiceItem line items} with unit prices, quantities, etc.
 * @class
 *
 * @property {string} currency The currency for all amounts on this invoice
 * @property {string} invoiceDate The date the invoice was 'enabled'. Can be set by user.
 * @property {string} payPalId The id assigned by PayPal for this invoice
 *  (if it has been saved to PayPal at some point) @readonly
 * @property {string} number The unique order number that can be assigned by you
 *  (you must ensure uniqueness) or automatically generated by PayPal
 * @property {Invoice.Status} status The current status of the invoice @readonly
 * @property {string} reference Reference data such as PO Number to be added to invoice.
 *  60 characters max.
 * @property {InvoiceMerchantInfo} merchantInfo Merchant email address and contact
 *  information (email defaults to a PayPal no-reply address)
 * @property {InvoiceBillingInfo} billingInfo Information about the payer or
 *  intended payer of the invoice
 * @property {InvoiceShippingInfo} shippingInfo The shipping address for this
 *  invoice (usually blank in retail use cases)
 * @property {bool} taxInclusive Prices for items on this invoice are INCLUSIVE
 *  of tax - defaults to false.
 * @property {bool} taxCalculatedAfterDiscount Taxes for line items are calculated
 *  after any discounts - defaults to false
 * @property {[InvoiceItem]} items The list of items on this invoice
 * @property {int} itemCount Get the number of items on this invoice @readonly
 * @property {InvoicePaymentTerm} paymentTerms Describes when payment is expected on the
 *  invoice (defaults to DueOnReceipt)
 * @property {decimal} gratuityAmount The amount of gratuity to be applied to the invoice, if any
 * @property {decimal} discountAmount Discount amount applied to the invoice
 * @property {decimal} minimumAmountDue Base object for all financial value related fields
 *  (balance, payment due, etc.)
 * @property {decimal} discountPercentage Discount percentage applied to the invoice
 * @property {string} note A note to the customer
 * @property {decimal} shippingAmount The shipping cost to be applied to the invoice, if any
 * @property {decimal} shippingTaxRate The shipping tax rate, as percent of the
 *  total shipping amount.
 * @property {string} shippingTaxName The name of the shipping tax.
 * @property {string} termsAndConditions General terms of the invoice. 4000 characters max.
 * @property {string} merchantMemo Bookkeeping memo that is private to the merchant.
 *  150 characters max.
 * @property {bool} isDirtyFromServer Has this invoice changed since the last time it was
 *  saved to the server? @readonly
 * @property {bool} hasDetails If false, this invoice doesn't know what items are in its item list.
 *  This can happen when only "summary" information has been fetched from the server
 *  (typically as the result of a search). You can get the total, but items and subtotals
 *  totals aren't available until you call getDetails. @readonly
 * @property {decimal} total The total amount due on the invoice @readonly
 * @property {decimal} subTotal The subtotal of the items on the invoice @readonly
 * @property {decimal} itemTax The total tax on the items (as opposed to the shipping tax,
 *  for example) @readonly
 * @property {decimal} itemDiscounts The total of all item discounts @readonly
 * @property {decimal} discountPrice The total dollar value of the invoice discount @readonly
 * @property {decimal} totalDiscount The total amount of discounts applied to the invoice items
 *  and overall invoice @readonly
 * @property {object} taxBreakdown An associative array of tax rate names to the total tax on the
 *  invoice from that rate @readonly
 * @property {bool} allowPartialPayment Indicates if a partial payment is allowed over the invoice.
 *  defaults to false
 * @property {[InvoiceCCInfo]} CCInfo an array of CCInfo Email addresses which should be marked as
 *  Carbon Copy (CC) while the invoice is sent via email. Only email address under participant is
 *  currently supported.
 * @property {[InvoicePayment]} payments an array of payment objects @readonly
 * @property {[InvoiceRefund]} refunds an array of refund objects @readonly
 * @property {decimal} paidAmount Total paid amount @readonly
 * @property {decimal} paidAmountPayPal The amount paid through PayPal @readonly
 * @property {decimal} paidAmountOther The amount paid through external means @readonly
 * @property {decimal} refundedAmount Total refunded amount @readonly
 * @property {decimal} refundedAmountPayPal The amount refunded through PayPal @readonly
 * @property {decimal} refundedAmountOther The amount refunded through external means @readonly
 * @property {decimal} remainingAmount The amount remaining on the invoice. @readonly
 * @property {decimal} amountPaidNet total payments net of any refunds. @readonly
 * @property {bool} hasBeenPaid If true, this invoice has been fully paid or marked as fully paid. Does not include partially paid. @readonly
 * @property {string} uri URI of the invoice resource.
 * @property {string} logoURL Full URL of an external image to use as the logo.
 *  4000 characters max. Non HTTPS URLs will be ignored when calling toJSON on this invoice.
 * @property {string} additionalData Any miscellaneous invoice data. 4000 characters max.
 * @property {InvoiceCustomAmount} custom Custom amount applied on an invoice. If a label
 *  is included then the amount cannot be empty.
 * @property {InvoiceMetaData} metadata Audit information of the resource. @readonly
 * @property {bool} wasDeleted If true, this invoice was deleted from the server.
 * @property {[InvoiceAttachment]} attachments List of files attached to the invoice.
 * @property {string} templateID Unique identifier id of the template.
 * @property {bool} isPastDue If true, this invoice is past due date. @readonly
 * @property {string} payerViewUrl url for the paypal view for share @readonly
 * @property {bool} allowTip Indicates if customers can tip against an invoice.
 * defaults to false
 */

var Invoice = function (_EventEmitter) {
  _inherits(Invoice, _EventEmitter);

  // TODO should this constructor also take an object
  // and assume it's from the server? Doesn't really
  // need to be public so that argues not...
  /**
   * Create a new blank invoice.
   * @constructor
   * @param {string} currencyCode currency code identifying the currency for amounts on this invoice
   */
  function Invoice(currencyCode) {
    _classCallCheck(this, Invoice);

    var _this = _possibleConstructorReturn(this, _EventEmitter.call(this));

    _this.hasDetails = true;
    var useCurrencyCode = currencyCode;
    if (!currencyCode) {
      if (!Invoice.DefaultCurrency) {
        throw new Error(
        /* eslint max-len: 0 */
        'Creating an invoice without a specified currency requires Invoice.DefaultCurrency to be set.');
      }
      useCurrencyCode = Invoice.DefaultCurrency;
    }
    if (!useCurrencyCode in Invoice.supportedCurrencies()) {
      throw new Error(
      /* eslint max-len: 0 */
      'Invalid currency code.');
    }
    _this.currency = useCurrencyCode;
    _this.merchantInfo = new _MerchantInfo2.default();
    _this.billingInfo = new _BillingInfo2.default();
    _this.shippingInfo = new _ShippingInfo2.default();
    _this.taxInclusive = false;
    _this.taxCalculatedAfterDiscount = false;
    _this.items = [];
    _this.payments = [];
    _this.allowPartialPayment = false;
    _this.CCInfo = [];
    _this.paymentTerms = new _PaymentTerm2.default();
    _this.status = _InvoiceEnums2.default.Status.NEW;
    _this._itemHandlers = {};
    _this.allowTip = false;
    if (Invoice.DefaultMerchant) {
      _this.merchantInfo.email = Invoice.DefaultMerchant.emailAddress;
      _this.merchantInfo.businessName = Invoice.DefaultMerchant.businessName;
      _this.merchantInfo.address = Invoice.DefaultMerchant.address;
      // TODO copy over more stuff.
    }
    return _this;
  }

  /**
   * Create a new invoice based on an existing invoice as a template.
   * @param {Invoice} invoice which is going to be copied
   * @returns {Invoice} the copy of the invoice
   */


  Invoice.withInvoice = function withInvoice(invoice) {
    (0, _assert2.default)(invoice.hasDetails, 'Can\'t use an invoice as a template if the details aren\'t loaded.');

    var i = new Invoice(invoice.currency);

    i.readJSON((0, _manticoreUtil.deepToJSON)(invoice), true);

    i.status = _InvoiceEnums2.default.Status.NEW;
    i.reference = undefined;
    i.number = undefined;
    i.payPalId = undefined;
    i.metadata = undefined;
    i.paymentTerms = invoice.paymentTerms || new _PaymentTerm2.default();
    i.invoiceDate = _InvoicingUtil2.default.toServerDateString(new Date(), false);

    return i;
  };

  /**
   * Create a true copy / duplicate of an invoice. This is named duplicate instead
   * of copy to avoid code gen issues on iOS
   * @returns {Invoice} the copy / duplicate of the invoice
   */


  Invoice.prototype.duplicate = function duplicate() {
    var i = new Invoice(this.currency);
    i.readJSON((0, _manticoreUtil.deepToJSON)(this.toFullJSON()), true);
    i.wasDeleted = this.wasDeleted;
    return i;
  };

  /**
   * Returns a list of currencies supported by the Invoicing API
   * @returns {[string]} an array of currency identifiers (i.e. "USD")
   */


  Invoice.supportedCurrencies = function supportedCurrencies() {
    return ['USD', 'AUD', 'BRL', 'GBP', 'CAD', 'CZK', 'DKK', 'EUR', 'HKD', 'HUF', 'ILS', 'JPY', 'MXN', 'TWD', 'NZD', 'NOK', 'PHP', 'PLN', 'RUB', 'SGD', 'SEK', 'CHF', 'THB'];
  };

  Invoice.prototype.setCleanFromServer = function setCleanFromServer() {
    this._lastKnownServerValue = (0, _manticoreUtil.deepToJSON)(this);
  };

  // ********************************* ATTACHMENTS **********************************
  /**
   * Adds the specified attachment to the invoice.
   * @param {InvoiceAttachment} attachment The attachment to add to the invoice.
   * @returns {[InvoiceAttachment]} The new list of attachments after adding the specified one.
   */


  Invoice.prototype.addAttachment = function addAttachment(attachment) {
    if (!this.attachments) {
      this.attachments = [];
    }

    this.attachments.push(attachment);
    return this.attachments;
  };

  /**
   * Remove an attachment by instance
   * @param {InvoiceAttachment} attachment Instance of attachment to be removed
   * @returns {bool} true if the attachment was removed from the list
   */


  Invoice.prototype.removeAttachment = function removeAttachment(attachment) {
    if (!attachment) {
      return false;
    }

    var index = this.attachments.indexOf(attachment);
    if (index < 0) {
      return false;
    }

    this.attachments.splice(index, 1);
    return true;
  };

  Invoice.prototype._addItemTotalChangedListener = function _addItemTotalChangedListener(item) {
    var _this2 = this;

    var handler = function handler(src) {
      _this2._emitTotalUpdated(src);
    };
    handler.inv = this;
    item.on(_Item2.default.event.priceMayHaveChanged, handler);
  };

  Invoice.prototype._removeItemTotalChangedListener = function _removeItemTotalChangedListener(item) {
    for (var _iterator = item.listeners(_Item2.default.event.priceMayHaveChanged), _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
      var _ref;

      if (_isArray) {
        if (_i >= _iterator.length) break;
        _ref = _iterator[_i++];
      } else {
        _i = _iterator.next();
        if (_i.done) break;
        _ref = _i.value;
      }

      var listener = _ref;

      if (listener.inv === this) {
        item.removeListener(_Item2.default.event.priceMayHaveChanged, listener);
      }
    }
  };

  Invoice.prototype._emitTotalUpdated = function _emitTotalUpdated(source) {
    _InvoicingUtil2.default.emitAsync(this, Invoice.event.totalMayHaveChanged, source);
  };

  // ********************************* ITEM LIST **********************************

  /**
   * Adds the specified item to the invoice. If there is an existing matching item
   * on the invoice, we will increment the quantity by the quantity argument.
   * You may pass a negative quantity value to decrement the quantity of an existing item.
   * @param {string} name The name of the item
   * @param {decimal} quantity The quantity of this item - up to three decimals
   * @param {decimal} unitPrice The price of 1 unit of this item
   * @param {int} itemId A unique identifier for this item - not currently
   *  saved to the server but used for local uniqueness such that one line item
   *  per itemId.detailId pair will be stored on an invoice
   * @param {string} detailId A secondary unique identifier (e.g. for item
   *  options or sizes, or to create multiple items on the same invoice
   *  with a single detailId)
   * @returns {InvoiceItem} the item actually stored on the invoice. If you want
   *  to set additional data on the item, you can use this item.
   */


  Invoice.prototype.addItem = function addItem(name, quantity, unitPrice, itemId, detailId) {
    var existing = this.findItem(itemId, detailId);
    if (existing) {
      existing.quantity = existing.quantity.plus(quantity);
      return existing;
    }
    var newItem = new _Item2.default(name, quantity, unitPrice, itemId, detailId || null);
    this.items.push(newItem);
    this._emitTotalUpdated('itemAdded');
    this._addItemTotalChangedListener(newItem);
    return newItem;
  };

  /**
   * Adds the specified item to the invoice. If there is an existing matching item
   * on the invoice, we will increment the quantity of the item.
   * @param {InvoiceItem} item The invoice item to be added
   * @returns {InvoiceItem} the item actually stored on the invoice. If you want
   *  to set additional data on the item, you can use this item.
   */


  Invoice.prototype.addInvoiceItem = function addInvoiceItem(item) {
    var existing = this.findItem(item.itemId, item.detailId);
    if (existing) {
      existing.quantity = existing.quantity.plus(item.quantity);
      return existing;
    }
    this.items.push(item);
    this._emitTotalUpdated('itemAdded');
    this._addItemTotalChangedListener(item);
    return item;
  };

  // ********************************* Equality **********************************

  /**
   * Checks for equality on all fields recursively
   * @param {Invoice} invoice Invoice to check equality on
   * @returns {bool} equality
   */


  Invoice.prototype.deepEqual = function deepEqual(invoice) {
    return (0, _deepEqual3.default)((0, _manticoreUtil.deepToJSON)(this.toFullJSON()), (0, _manticoreUtil.deepToJSON)(invoice.toFullJSON()));
  };

  /**
   * Remove all items on the invoice
   * @method
   */


  Invoice.prototype.removeAllItems = function removeAllItems() {
    if (this.items.length === 0) {
      return;
    }

    for (var _iterator2 = this.items, _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) {
      var _ref2;

      if (_isArray2) {
        if (_i2 >= _iterator2.length) break;
        _ref2 = _iterator2[_i2++];
      } else {
        _i2 = _iterator2.next();
        if (_i2.done) break;
        _ref2 = _i2.value;
      }

      var item = _ref2;

      this._removeItemTotalChangedListener(item);
    }
    this.items = [];
    this._emitTotalUpdated('itemRemoved');
  };

  /**
   * Remove an item by instance
   * @param {InvoiceItem} item Instance of item to be removed
   * @returns {bool} true if the item was removed from the list
   */


  Invoice.prototype.removeItem = function removeItem(item) {
    if (!item) {
      return false;
    }

    var itemIndex = this.items.indexOf(item);
    if (itemIndex < 0) {
      return false;
    }

    this.items.splice(itemIndex, 1);
    this._removeItemTotalChangedListener(item);
    this._emitTotalUpdated('itemRemoved');
    return true;
  };

  /**
   * Find the InvoiceItem with the specified id and/or detailId
   * @param {int} itemId
   * @param {string} [detailId]
   * @returns {InvoiceItem} The existing item on the invoice, if any
   */


  Invoice.prototype.findItem = function findItem(itemId, detailId) {
    if (!itemId) {
      return null;
    }
    var _detailId = detailId || null;
    var _itemId = itemId;

    if (typeof itemId !== 'string' && typeof itemId !== 'number') {
      _detailId = itemId.detailId;
      _itemId = itemId.itemId;
    }
    for (var _iterator3 = this.items, _isArray3 = Array.isArray(_iterator3), _i3 = 0, _iterator3 = _isArray3 ? _iterator3 : _iterator3[Symbol.iterator]();;) {
      var _ref3;

      if (_isArray3) {
        if (_i3 >= _iterator3.length) break;
        _ref3 = _iterator3[_i3++];
      } else {
        _i3 = _iterator3.next();
        if (_i3.done) break;
        _ref3 = _i3.value;
      }

      var candidate = _ref3;

      if (candidate.itemId === _itemId && candidate.detailId === _detailId) {
        return candidate;
      }
    }
    return null;
  };

  /**
   * Get an item by 0-based index
   * @param {int} itemIndex 0-based index of item to retrieve.
   * @returns {InvoiceItem}
   */


  Invoice.prototype.getItem = function getItem(itemIndex) {
    return this.items[itemIndex];
  };

  // ********************************* API CALLS **********************************

  /**
   * Update the full invoice from the server, based on its payPalId.
   * @param {Invoice~gotDetails} callback Called with an error
   */
  Invoice.prototype.getDetails = function getDetails(callback) {
    var _this3 = this;

    (0, _assert2.default)(this.payPalId, 'Can\'t get details of an invoice without an id.');
    (0, _assert2.default)(!this.wasDeleted, 'Can\'t get details on an invoice that was deleted.');

    _InvoicingService2.default.getInvoiceDetails(this.payPalId, function (error, details) {
      if (!error) {
        _this3.readJSON(details, true);
        _this3.setCleanFromServer();
      }
      if (callback) {
        callback(error);
      }
    });
  };

  /**
   * Save the invoice to the PayPal servers.
   * @param {Invoice~saved} callback Called with an error
   */


  Invoice.prototype.save = function save(callback) {
    var _this4 = this;

    (0, _assert2.default)(this.hasDetails, 'Can\'t save an invoice without details');
    (0, _assert2.default)(!this.wasDeleted, 'Can\'t save an invoice that was deleted.');
    if (!this.isDirtyFromServer) {
      if (callback) {
        callback();
      }
      return;
    }
    (0, _Requester.request)({
      // If this invoice has an ID, then it must already be on the server. If it is, update
      // the existing invoice instead of creating a new one.
      method: this.payPalId ? 'PUT' : 'POST',
      op: this.payPalId ? 'invoices/' + this.payPalId : 'invoices',
      body: JSON.stringify(this)
    }, function (error, invoiceResponse) {
      if (!error && invoiceResponse.body) {
        _this4.readJSON(invoiceResponse.body, true);
        _this4.setCleanFromServer();
      }
      if (callback) {
        callback(error);
      }
    });
  };

  /**
   * Send the invoice. It must have already been saved to the server.
   * @param {bool} shouldNotifyMerchant A flag indicating whether a
   *  copy of the notification has to be sent to the merchant
   * @param {Invoice~sent} callback Called with an error
   */


  Invoice.prototype.send = function send(shouldNotifyMerchant, callback) {
    var _this5 = this;

    // TODO: Once we track whether save is required, save here if it's required.
    (0, _assert2.default)(this.payPalId, 'Can\'t send an invoice without an id.');
    (0, _assert2.default)(!this.wasDeleted, 'Can\'t send an invoice that was deleted.');

    (0, _Requester.request)({
      method: 'POST',
      op: 'invoices/' + this.payPalId + '/send?notify_merchant=' + !!shouldNotifyMerchant
    }, function (error, response) {
      if (!error) {
        _this5.status = _InvoiceEnums2.default.Status.SENT;
      }
      if (callback) {
        callback(error, response);
      }
      // this will allow getIsPastDue to return correct result before refresh
      if (_this5.paymentTerms.paymentTerms === _PaymentTerm2.default.PaymentTerms.DueOnReceipt) {
        _this5.paymentTerms.dueDate = _InvoicingUtil2.default.toServerDateString(new Date(), false);
      }
    });
  };

  /**
   * Delete the invoice from the server. It must have already been saved to the server.
   * @param {Invoice~deleted} callback Called with an error
   */


  Invoice.prototype.deleteFromServer = function deleteFromServer(callback) {
    var _this6 = this;

    (0, _assert2.default)(this.payPalId, 'Can\'t delete an invoice without an id.');
    (0, _assert2.default)(!this.wasDeleted, 'Can\'t delete an invoice that was deleted.');
    (0, _Requester.request)({
      method: 'DELETE',
      op: 'invoices/' + this.payPalId
    }, function (error, response) {
      if (!error) {
        _this6.status = _InvoiceEnums2.default.Status.NEW;
        _this6.wasDeleted = true;
      }
      if (callback) {
        callback(error, response);
      }
    });
  };

  /**
   * Send a reminder about this invoice to its intended recipient
   * @param {InvoiceNotification} notification
   * @param {Invoice~reminded} callback
   */


  Invoice.prototype.remind = function remind(notification, callback) {
    (0, _assert2.default)(this.payPalId, 'Can\'t remind an invoice without an id.');
    (0, _assert2.default)(notification.send_to_payer !== false, 'Can\'t send a reminder that doesn\'t go to the payer.');
    (0, _assert2.default)(!this.wasDeleted, 'Can\'t remind an invoice that was deleted.');
    (0, _Requester.request)({
      method: 'POST',
      op: 'invoices/' + this.payPalId + '/remind',
      body: JSON.stringify(notification)
    }, callback);
  };

  /**
   * Cancel this invoice
   * @param {InvoiceNotification} notification
   * @param {Invoice~cancelled} callback
   */


  Invoice.prototype.cancel = function cancel(notification, callback) {
    var _this7 = this;

    (0, _assert2.default)(this.payPalId, 'Can\'t cancel an invoice without an id.');
    (0, _assert2.default)(!this.wasDeleted, 'Can\'t cancel an invoice that was deleted.');

    (0, _Requester.request)({
      method: 'POST',
      op: 'invoices/' + this.payPalId + '/cancel',
      body: JSON.stringify(notification)
    }, function (error, response) {
      if (!error) {
        _this7.status = _InvoiceEnums2.default.Status.CANCELLED;
      }
      if (callback) {
        callback(error, response);
      }
    });
  };

  /**
   * @param {InvoicePayment} paymentInfo
   * @param {Invoice~paid} callback
   */


  Invoice.prototype.recordPayment = function recordPayment(paymentInfo, callback) {
    var _this8 = this;

    (0, _assert2.default)(this.payPalId, 'Can\'t record payment on an invoice without an id.');
    (0, _assert2.default)(paymentInfo, 'Can\'t record payment on an invoice without paymentInfo.');
    (0, _assert2.default)(!this.wasDeleted, 'Can\'t record payment on an invoice that was deleted.');

    paymentInfo.validate();
    (0, _Requester.request)({
      method: 'POST',
      op: 'invoices/' + this.payPalId + '/record-payment',
      body: JSON.stringify(paymentInfo)
    }, function (error, response) {
      if (!error) {
        if (paymentInfo.type === _InvoiceEnums2.default.PaymentType.EXTERNAL) {
          if (!_this8.allowPartialPayment || paymentInfo.amount && _this8.equiv(_this8.remainingAmount, paymentInfo.amount)) {
            _this8.status = _InvoiceEnums2.default.Status.MARKED_AS_PAID;
          } else {
            _this8.status = _InvoiceEnums2.default.Status.PARTIALLY_PAID;
          }
        } else if (paymentInfo.type === _InvoiceEnums2.default.PaymentType.PAYPAL) {
          _this8.status = _InvoiceEnums2.default.Status.PAID;
        }
      }
      if (callback) {
        callback(error, response);
      }
    });
  };

  // check if the two amounts are equivalent


  Invoice.prototype.equiv = function equiv(a, b) {
    return _Currency2.default.round(this.currency, a).equals(_Currency2.default.round(this.currency, b));
  };

  /**
   * @param {InvoiceRefund} refundInfo
   * @param {Invoice~paid} callback
   */


  Invoice.prototype.recordRefund = function recordRefund(refundInfo, callback) {
    var _this9 = this;

    (0, _assert2.default)(this.payPalId, 'Can\'t record refund on an invoice without an id.');
    (0, _assert2.default)(!this.wasDeleted, 'Can\'t record refund on an invoice that was deleted.');
    (0, _assert2.default)(this.status === _InvoiceEnums2.default.Status.MARKED_AS_PAID || this.status === _InvoiceEnums2.default.Status.PAID || this.status === _InvoiceEnums2.default.Status.PARTIALLY_REFUNDED || this.status === _InvoiceEnums2.default.Status.PARTIALLY_PAID, 'Can\'t record refund on an invoice that hasn\'t been paid yet.');
    (0, _assert2.default)(refundInfo, 'Can\'t record refund on an invoice without refundInfo.');

    (0, _Requester.request)({
      method: 'POST',
      op: 'invoices/' + this.payPalId + '/record-refund',
      body: JSON.stringify(refundInfo)
    }, function (error, response) {
      if (!error) {
        _this9.updateStatusFromRefund(refundInfo.type);
      }
      if (callback) {
        callback(error, response);
      }
    });
  };

  Invoice.prototype.updateStatusFromRefund = function updateStatusFromRefund(refundType) {
    if (!this.remainingAmount.isZero()) {
      this.status = _InvoiceEnums2.default.Status.PARTIALLY_PAID;
    } else {
      if (refundType === _InvoiceEnums2.default.PaymentType.EXTERNAL) {
        this.status = _InvoiceEnums2.default.Status.MARKED_AS_REFUNDED;
      } else if (refundType === _InvoiceEnums2.default.PaymentType.PAYPAL) {
        this.status = _InvoiceEnums2.default.Status.REFUNDED;
      }
    }
  };

  // **************************** JSON PARSING AND SERIALIZATION *****************************

  Invoice.prototype.toJSON = function toJSON() {
    /* jshint maxcomplexity: false */
    var r = {};
    r.note = this.note;
    r.number = this.number;
    r.invoice_date = this.invoiceDate;
    r.merchant_info = this.merchantInfo;
    r.shipping_info = this.shippingInfo;
    r.billing_info = [this.billingInfo];
    r.tax_inclusive = this.taxInclusive;
    r.tax_calculated_after_discount = this.taxCalculatedAfterDiscount;
    r.allow_partial_payment = this.allowPartialPayment;
    r.allow_tip = this.allowTip;
    r.uri = this.uri;
    if (this.logoURL && this.logoURL.toLowerCase().indexOf('https://') === 0) {
      r.logo_url = this.logoURL;
    }
    r.additional_data = this.additionalData;
    this._attachmentsToJson(r);
    r.template_id = this.templateID;

    this._CCInfoToJson(r);

    if (this.termsAndConditions) {
      r.terms = this.termsAndConditions.substring(0, 4000);
    }
    if (this.merchantMemo) {
      r.merchant_memo = this.merchantMemo.substring(0, 150);
    }

    this._shippingToJson(r);

    if (this.minimumAmountDue) {
      r.minimum_amount_due = {
        currency: this.currency,
        value: _Currency2.default.serverRound(this.currency, this.minimumAmountDue)
      };
    }

    r.id = this.payPalId;
    if (this.status) {
      r.status = _InvoiceEnums2.default.Status.toString[this.status];
    }
    r.reference = this.reference;

    if (this.gratuityAmount) {
      r.gratuity = {
        currency: this.currency,
        value: _Currency2.default.serverRound(this.currency, this.gratuityAmount)
      };
    }
    var discount = this.discountObject();
    if (discount != null) {
      r.discount = discount;
    }
    if (this.paymentTerms.dueDate || this.paymentTerms.paymentTerms) {
      r.payment_term = this.paymentTerms.toJSONHack(r.invoice_date);
    }
    this._itemsToJson(r);

    if (this._custom) {
      r.custom = this._custom.toJSON(this.currency);
    }
    return r;
  };

  // Returns the full JSON, including readonly properties like payments
  // and refunds which should not be sent to the server.


  Invoice.prototype.toFullJSON = function toFullJSON() {
    var r = this.toJSON();
    r.payments = this.payments;
    r.refunds = this.refunds;
    if (this.paidAmount && !this.paidAmount.isZero()) {
      r.paid_amount = {};
      if (!this.paidAmountPayPal.isZero()) {
        r.paid_amount.paypal = {
          currency: this.currency,
          value: _Currency2.default.serverRound(this.currency, this.paidAmountPayPal)
        };
      }
      if (!this.paidAmountOther.isZero()) {
        r.paid_amount.other = {
          currency: this.currency,
          value: _Currency2.default.serverRound(this.currency, this.paidAmountOther)
        };
      }
    }

    if (this.refundedAmount && !this.refundedAmount.isZero()) {
      r.refunded_amount = {};
      if (!this.refundedAmountPayPal.isZero()) {
        r.refunded_amount.paypal = {
          currency: this.currency,
          value: _Currency2.default.serverRound(this.currency, this.refundedAmountPayPal)
        };
      }
      if (!this.refundedAmountOther.isZero()) {
        r.refunded_amount.other = {
          currency: this.currency,
          value: _Currency2.default.serverRound(this.currency, this.refundedAmountOther)
        };
      }
    }

    if (this.metadata) {
      r.metadata = _InvoiceMetaData2.default.toFullJSON(this.metadata);
    }

    // Due to a server bug (see PaymentTerm.js), toJSON does a weird hack with the payment terms.
    // We don't want that in toFullJSON, so this overwrites it.
    // TODO: sto this once server is fixed.
    r.payment_term = this.paymentTerms;

    return r;
  };

  Invoice.prototype._shippingToJson = function _shippingToJson(r) {
    if (this.shippingAmount) {
      r.shipping_cost = {};

      r.shipping_cost.amount = {
        currency: this.currency,
        value: _Currency2.default.serverRound(this.currency, this.shippingAmount)
      };
      if (this.shippingTaxRate && !this.shippingTaxRate.isZero()) {
        r.shipping_cost.tax = {
          name: this.shippingTaxName || 'Shipping Tax',
          percent: this.shippingTaxRate
        };
      }
    }
  };

  Invoice.prototype._itemsToJson = function _itemsToJson(r) {
    if (this.items && this.items.length) {
      r.items = [];
      for (var _iterator4 = this.items, _isArray4 = Array.isArray(_iterator4), _i4 = 0, _iterator4 = _isArray4 ? _iterator4 : _iterator4[Symbol.iterator]();;) {
        var _ref4;

        if (_isArray4) {
          if (_i4 >= _iterator4.length) break;
          _ref4 = _iterator4[_i4++];
        } else {
          _i4 = _iterator4.next();
          if (_i4.done) break;
          _ref4 = _i4.value;
        }

        var i = _ref4;

        r.items.push(i.toJSON(this.currency));
      }
    }
  };

  Invoice.prototype._attachmentsToJson = function _attachmentsToJson(r) {
    if (this.attachments && this.attachments.length) {
      r.attachments = [];
      for (var _iterator5 = this.attachments, _isArray5 = Array.isArray(_iterator5), _i5 = 0, _iterator5 = _isArray5 ? _iterator5 : _iterator5[Symbol.iterator]();;) {
        var _ref5;

        if (_isArray5) {
          if (_i5 >= _iterator5.length) break;
          _ref5 = _iterator5[_i5++];
        } else {
          _i5 = _iterator5.next();
          if (_i5.done) break;
          _ref5 = _i5.value;
        }

        var a = _ref5;

        r.attachments.push(a.toJSON());
      }
    }
  };

  Invoice.prototype._CCInfoToJson = function _CCInfoToJson(r) {
    if (this.CCInfo && this.CCInfo.length) {
      r.cc_info = [];
      for (var _iterator6 = this.CCInfo, _isArray6 = Array.isArray(_iterator6), _i6 = 0, _iterator6 = _isArray6 ? _iterator6 : _iterator6[Symbol.iterator]();;) {
        var _ref6;

        if (_isArray6) {
          if (_i6 >= _iterator6.length) break;
          _ref6 = _iterator6[_i6++];
        } else {
          _i6 = _iterator6.next();
          if (_i6.done) break;
          _ref6 = _i6.value;
        }

        var i = _ref6;

        r.cc_info.push(i.toJSON());
      }
    }
  };

  Invoice.prototype.discountObject = function discountObject() {
    var discount = {};
    if (this.discountAmount > 0) {
      discount.amount = {};
      discount.amount.value = _Currency2.default.serverRound(this.currency, this.discountAmount);
      discount.amount.currency = this.currency;
    } else if (this.discountPercentage > 0) {
      discount.percent = this.discountPercentage;
    } else {
      return null;
    }
    return discount;
  };

  /**
   * Construct an invoice from a server response
   * @param serverJSON
   * @param bool hasDetails
   * @private
   */


  Invoice.prototype.readJSON = function readJSON(serverJSON, hasDetails) {
    /* jshint maxcomplexity: false */

    this.invoiceDate = serverJSON.invoice_date;
    this.status = statusFromServer(serverJSON.status);
    this.reference = serverJSON.reference;
    this.number = serverJSON.number;
    this.payPalId = serverJSON.id;
    this.note = serverJSON.note;
    this.merchantInfo.readFromJson(serverJSON.merchant_info);
    this.uri = serverJSON.uri;
    this.logoURL = serverJSON.logo_url;
    this.additionalData = serverJSON.additional_data;
    this.templateID = serverJSON.template_id;

    this.hasDetails = hasDetails;

    if (serverJSON.allow_partial_payment !== undefined) {
      this.allowPartialPayment = serverJSON.allow_partial_payment;
    }

    if (serverJSON.allow_tip !== undefined) {
      this.allowTip = serverJSON.allow_tip;
    }

    if (serverJSON.metadata) {
      this.metadata = _InvoiceMetaData2.default.fromJSON(serverJSON.metadata);
    }

    if (serverJSON.custom) {
      this._custom = _CustomAmount2.default.fromJSON(serverJSON.custom);
    }

    if (serverJSON.payments) {
      this.payments = [];
      for (var _iterator7 = serverJSON.payments, _isArray7 = Array.isArray(_iterator7), _i7 = 0, _iterator7 = _isArray7 ? _iterator7 : _iterator7[Symbol.iterator]();;) {
        var _ref7;

        if (_isArray7) {
          if (_i7 >= _iterator7.length) break;
          _ref7 = _iterator7[_i7++];
        } else {
          _i7 = _iterator7.next();
          if (_i7.done) break;
          _ref7 = _i7.value;
        }

        var payment = _ref7;

        this.payments.push(_Payment2.default.readFromJson(payment));
      }
    }
    if (serverJSON.refunds) {
      this.refunds = [];
      for (var _iterator8 = serverJSON.refunds, _isArray8 = Array.isArray(_iterator8), _i8 = 0, _iterator8 = _isArray8 ? _iterator8 : _iterator8[Symbol.iterator]();;) {
        var _ref8;

        if (_isArray8) {
          if (_i8 >= _iterator8.length) break;
          _ref8 = _iterator8[_i8++];
        } else {
          _i8 = _iterator8.next();
          if (_i8.done) break;
          _ref8 = _i8.value;
        }

        var refund = _ref8;

        this.refunds.push(_Refund2.default.readFromJson(refund));
      }
    }

    if (serverJSON.attachments) {
      this.attachments = [];
      for (var _iterator9 = serverJSON.attachments, _isArray9 = Array.isArray(_iterator9), _i9 = 0, _iterator9 = _isArray9 ? _iterator9 : _iterator9[Symbol.iterator]();;) {
        var _ref9;

        if (_isArray9) {
          if (_i9 >= _iterator9.length) break;
          _ref9 = _iterator9[_i9++];
        } else {
          _i9 = _iterator9.next();
          if (_i9.done) break;
          _ref9 = _i9.value;
        }

        var a = _ref9;

        this.attachments.push(_Attachment2.default.readFromJson(a));
      }
    }

    if (serverJSON.terms) {
      this.termsAndConditions = serverJSON.terms;
    }
    if (serverJSON.merchant_memo) {
      this.merchantMemo = serverJSON.merchant_memo;
    }
    if (serverJSON.shipping_cost) {
      this.shippingAmount = (0, _InvoiceBigNumber.$$)(serverJSON.shipping_cost.amount.value);
      if (serverJSON.shipping_cost.tax) {
        this.shippingTaxRate = serverJSON.shipping_cost.tax.percent;
        if (serverJSON.shipping_cost.tax.name) {
          this.shippingTaxName = serverJSON.shipping_cost.tax.name;
        }
      }
    }
    if (serverJSON.minimum_amount_due) {
      this.minimumAmountDue = (0, _InvoiceBigNumber.$$)(serverJSON.minimum_amount_due.value);
    }
    if (serverJSON.refunded_amount) {
      this.refundedAmountPayPal = serverJSON.refunded_amount.paypal ? (0, _InvoiceBigNumber.$$)(serverJSON.refunded_amount.paypal.value) : _InvoiceCalculator.ZERO;
      this.refundedAmountOther = serverJSON.refunded_amount.other ? (0, _InvoiceBigNumber.$$)(serverJSON.refunded_amount.other.value) : _InvoiceCalculator.ZERO;
      this.refundedAmount = this.refundedAmountPayPal.plus(this.refundedAmountOther);
    }
    if (serverJSON.paid_amount) {
      this.paidAmountPayPal = serverJSON.paid_amount.paypal ? (0, _InvoiceBigNumber.$$)(serverJSON.paid_amount.paypal.value) : _InvoiceCalculator.ZERO;
      this.paidAmountOther = serverJSON.paid_amount.other ? (0, _InvoiceBigNumber.$$)(serverJSON.paid_amount.other.value) : _InvoiceCalculator.ZERO;
      this.paidAmount = this.paidAmountPayPal.plus(this.paidAmountOther);
    }
    if (serverJSON.billing_info && serverJSON.billing_info.length) {
      this.billingInfo.readFromJson(serverJSON.billing_info[0]);
    }
    if (serverJSON.shipping_info) {
      this.shippingInfo.readFromJson(serverJSON.shipping_info);
    }
    if (serverJSON.cc_info) {
      this.CCInfo = [];
      for (var _iterator10 = serverJSON.cc_info, _isArray10 = Array.isArray(_iterator10), _i10 = 0, _iterator10 = _isArray10 ? _iterator10 : _iterator10[Symbol.iterator]();;) {
        var _ref10;

        if (_isArray10) {
          if (_i10 >= _iterator10.length) break;
          _ref10 = _iterator10[_i10++];
        } else {
          _i10 = _iterator10.next();
          if (_i10.done) break;
          _ref10 = _i10.value;
        }

        var ccinfo = _ref10;

        var invoiceCCInfo = _CCInfo2.default.fromJson(ccinfo);
        this.CCInfo.push(invoiceCCInfo);
      }
    }
    if (serverJSON.gratuity) {
      this.gratuityAmount = (0, _InvoiceBigNumber.$$)(serverJSON.gratuity.value);
    }
    this.paymentTerms = _PaymentTerm2.default.fromJson(serverJSON.payment_term);

    if (serverJSON.hasOwnProperty('tax_inclusive')) {
      this.taxInclusive = serverJSON.tax_inclusive;
    }
    if (serverJSON.hasOwnProperty('tax_calculated_after_discount')) {
      this.taxCalculatedAfterDiscount = serverJSON.tax_calculated_after_discount;
    }
    if (serverJSON.hasOwnProperty('discount')) {
      var discount = serverJSON.discount;
      if (discount.hasOwnProperty('percent')) {
        this.discountPercentage = discount.percent;
      } else if (serverJSON.discount.hasOwnProperty('amount')) {
        this.discountAmount = (0, _InvoiceBigNumber.$$)(serverJSON.discount.amount.value);
      }
    }
    this.removeAllItems();
    if (serverJSON.items) {
      for (var _iterator11 = serverJSON.items, _isArray11 = Array.isArray(_iterator11), _i11 = 0, _iterator11 = _isArray11 ? _iterator11 : _iterator11[Symbol.iterator]();;) {
        var _ref11;

        if (_isArray11) {
          if (_i11 >= _iterator11.length) break;
          _ref11 = _iterator11[_i11++];
        } else {
          _i11 = _iterator11.next();
          if (_i11.done) break;
          _ref11 = _i11.value;
        }

        var item = _ref11;

        var invoiceItem = _Item2.default.fromJson(item);
        this.items.push(invoiceItem);
      }
    } else {
      this._totalFromServer = serverJSON.total_amount ? (0, _InvoiceBigNumber.$$)(serverJSON.total_amount.value) : (0, _InvoiceBigNumber.$$)('0');
    }
  };

  Invoice.fromJson = function fromJson(serverJSON, hasDetails) {
    if (!serverJSON.total_amount) {
      throw new Error('Invoice JSON has no total_amount.');
    }
    var i = new Invoice(serverJSON.total_amount.currency);
    i.readJSON(serverJSON, hasDetails);
    return i;
  };

  _createClass(Invoice, [{
    key: 'isDirtyFromServer',
    get: function get() {
      return !this._lastKnownServerValue || !(0, _deepEqual3.default)(this._lastKnownServerValue, (0, _manticoreUtil.deepToJSON)(this));
    }
  }, {
    key: 'isPastDue',
    get: function get() {
      return _InvoicingUtil2.default.isInvoicePastDue(this.status, this.paymentTerms, this.invoiceDate);
    }
  }, {
    key: 'payerViewUrl',
    get: function get() {
      if (this.metadata && this.metadata.payerViewURL) {
        return this.metadata.payerViewURL;
      } else if (this.payPalId) {
        return "https://www.paypal.com?cmd=_pay-inv&id=" + this.payPalId;
      } else {
        return nil;
      }
    }
  }, {
    key: 'currencyCode',
    set: function set(code) {
      if (code in Invoice.supportedCurrencies()) {
        this._currency = code;
      } else {
        throw new Error(
        /* eslint max-len: 0 */
        'Invalid currency code.');
      }
    },
    get: function get() {
      return this._currency;
    }
  }, {
    key: 'invoiceDate',
    set: function set(date) {
      this._invoiceDate = date;
    },
    get: function get() {
      return this._invoiceDate;
    }
  }, {
    key: 'itemCount',
    get: function get() {
      return this.items.length;
    }
  }, {
    key: 'gratuityAmount',
    get: function get() {
      return this._gratuityAmount;
    },
    set: function set(value) {
      this._gratuityAmount = (0, _InvoiceBigNumber.$$)(value);
      this._emitTotalUpdated('gratuityAmount');
    }
  }, {
    key: 'discountAmount',
    get: function get() {
      return this._discountAmount;
    },
    set: function set(value) {
      this._discountAmount = (0, _InvoiceBigNumber.$$)(value);
      this._discountPercentage = null;
      this._emitTotalUpdated('discountAmount');
    }
  }, {
    key: 'minimumAmountDue',
    get: function get() {
      return this._minimumAmountDue;
    },
    set: function set(value) {
      this._minimumAmountDue = (0, _InvoiceBigNumber.$$)(value);
    }
  }, {
    key: 'discountPercentage',
    get: function get() {
      return this._discountPercentage;
    },
    set: function set(value) {
      this._discountPercentage = (0, _InvoiceBigNumber.IBN)(value, _Item2.default.discountPercentageDecimalPrecision);
      this._discountAmount = null;
      this._emitTotalUpdated('discountPercentage');
    }
  }, {
    key: 'shippingAmount',
    get: function get() {
      return this._shippingAmount;
    },
    set: function set(value) {
      this._shippingAmount = (0, _InvoiceBigNumber.$$)(value);
      this._emitTotalUpdated('shippingAmount');
    }
  }, {
    key: 'shippingTaxRate',
    get: function get() {
      return this._shippingTaxRate;
    },
    set: function set(value) {
      this._shippingTaxRate = (0, _InvoiceBigNumber.IBN)(value, _Item2.default.taxDecimalPrecision);
      this._emitTotalUpdated('shippingTaxRate');
    }
  }, {
    key: 'custom',
    set: function set(value) {
      this._custom = value;
    },
    get: function get() {
      return this._custom;
    }

    // ********************************* TOTAL PROPERTIES **********************************

  }, {
    key: 'total',
    get: function get() {
      if (this.hasDetails) {
        return _InvoiceCalculator2.default.calculateTotal(this);
      } else {
        return this._totalFromServer;
      }
    }
  }, {
    key: 'subTotal',
    get: function get() {
      (0, _assert2.default)(this.hasDetails, 'Can\'t calculate the subtotal without details');
      return _InvoiceCalculator2.default.calculateSubtotal(this);
    }
  }, {
    key: 'itemTax',
    get: function get() {
      (0, _assert2.default)(this.hasDetails, 'Can\'t calculate the item tax without details');
      return _InvoiceCalculator2.default.calculateItemTaxTotal(this);
    }
  }, {
    key: 'itemDiscounts',
    get: function get() {
      (0, _assert2.default)(this.hasDetails, 'Can\'t calculate the total discount without details');
      return _InvoiceCalculator2.default.calculateItemDiscounts(this);
    }
  }, {
    key: 'discountPrice',
    get: function get() {
      (0, _assert2.default)(this.hasDetails, 'Can\'t calculate the discount price without details');
      return _InvoiceCalculator2.default.calculateDiscountPrice(this);
    }
  }, {
    key: 'totalDiscount',
    get: function get() {
      (0, _assert2.default)(this.hasDetails, 'Can\'t calculate the total discount without details');
      return _InvoiceCalculator2.default.calculateDiscountTotal(this);
    }
  }, {
    key: 'taxBreakdown',
    get: function get() {
      (0, _assert2.default)(this.hasDetails, 'Can\'t calculate the tax breakdown without details');
      return _InvoiceCalculator2.default.calculateTaxBreakdown(this);
    }
  }, {
    key: 'remainingAmount',
    get: function get() {
      var paid = this.paidAmount || _InvoiceCalculator.ZERO;
      return this.total.minus(paid);
    }
  }, {
    key: 'amountPaidNet',
    get: function get() {
      var paid = this.paidAmount || _InvoiceCalculator.ZERO;
      var refunded = this.refundedAmount || _InvoiceCalculator.ZERO;
      return paid.minus(refunded);
    }
  }, {
    key: 'hasBeenPaid',
    get: function get() {
      return this.status === _InvoiceEnums2.default.Status.MARKED_AS_PAID || this.status === _InvoiceEnums2.default.Status.PAID;
    }
  }]);

  return Invoice;
}(_events.EventEmitter);

// Put any callback definitions before the module exports, and
// reference them in parameter definitions.

/**
 * @callback Invoice~gotDetails
 * @param {PayPalError} error The error that occurred, if any
 */

/**
 * After an attempt has been made to save your invoice to the PayPal servers,
 * the completion handler will be called with the error (if any, or null if not)
 * and the invoice object will be updated appropriately.
 * @callback Invoice~saved
 * @param {PayPalError} error The error that occurred, if any
 */

/**
 * After an attempt has been made to send your invoice, the completion handler
 * will be called with the error (if any, or null if not) and the invoice object
 * will be updated appropriately.
 * @callback Invoice~sent
 * @param {PayPalError} error The error that occurred, if any
 */

/**
 * @callback Invoice~deleted
 * @param {PayPalError} error The error that occurred, if any
 */

/**
 * @callback Invoice~reminded
 * @param {PayPalError} error The error that occurred, if any
 */

/**
 * @callback Invoice~cancelled
 * @param {PayPalError} error The error that occurred, if any
 */

/**
 * @callback Invoice~paid
 * @param {PayPalError} error The error that occurred, if any
 */

/**
 * @callback Invoice~refunded
 * @param {PayPalError} error The error that occurred, if any
 */

exports.default = Invoice;
Invoice.event = {
  totalMayHaveChanged: 'TotalMayHaveChanged'
};
},{"./Attachment":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/Attachment.js","./BillingInfo":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/BillingInfo.js","./CCInfo":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/CCInfo.js","./Currency":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/Currency.js","./CustomAmount":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/CustomAmount.js","./InvoiceBigNumber":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/InvoiceBigNumber.js","./InvoiceCalculator":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/InvoiceCalculator.js","./InvoiceEnums":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/InvoiceEnums.js","./InvoiceMetaData":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/InvoiceMetaData.js","./InvoicingService":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/InvoicingService.js","./InvoicingUtil":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/InvoicingUtil.js","./Item":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/Item.js","./MerchantInfo":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/MerchantInfo.js","./Payment":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/Payment.js","./PaymentTerm":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/PaymentTerm.js","./Refund":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/Refund.js","./Requester":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/Requester.js","./ShippingInfo":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/ShippingInfo.js","assert":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/assert/assert.js","deep-equal":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/deep-equal/index.js","events":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/events/events.js","manticore-log":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-log/index.js","manticore-util":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-util/build/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/InvoiceActions.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

var _InvoiceEnums = require('./InvoiceEnums');

var _InvoiceEnums2 = _interopRequireDefault(_InvoiceEnums);

var _InvoiceCalculator = require('./InvoiceCalculator');

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

/**
 * @class
 */
var InvoiceActions = function () {
  function InvoiceActions() {
    _classCallCheck(this, InvoiceActions);
  }

  /**
   * @param {Invoice} invoice
   * @returns {[Invoice.Action]}
   */
  InvoiceActions.availableActions = function availableActions(invoice) {
    var a = _InvoiceEnums2.default.Action;
    var paid = invoice.paidAmountOther || _InvoiceCalculator.ZERO;
    var refunded = invoice.refundedAmountOther || _InvoiceCalculator.ZERO;
    var hasEmail = invoice.billingInfo !== undefined && invoice.billingInfo.email;
    var actions = void 0;
    switch (invoice.status) {
      case _InvoiceEnums2.default.Status.NEW:
        throw new Error('Actions are undefined for NEW invoices.');
      case _InvoiceEnums2.default.Status.DRAFT:
        actions = [a.Send, a.Edit, a.Delete, a.RecordPayment, a.Copy, a.Share];
        break;
      case _InvoiceEnums2.default.Status.SENT:
        actions = [a.Remind, a.RecordPayment, a.Edit, a.Cancel, a.Copy, a.Call, a.Share];
        break;
      case _InvoiceEnums2.default.Status.PARTIALLY_PAID:
        if (paid.minus(refunded).isZero()) {
          actions = [a.Remind, a.RecordPayment, a.Edit, a.Call, a.Copy, a.Share];
        } else {
          actions = [a.Remind, a.RecordPayment, a.RecordRefund, a.Edit, a.Call, a.Copy, a.Share];
        }
        break;
      case _InvoiceEnums2.default.Status.PAID:
      case _InvoiceEnums2.default.Status.MARKED_AS_PAID:
      case _InvoiceEnums2.default.Status.PARTIALLY_REFUNDED:
        if (invoice.total === 0 || paid.minus(refunded).isZero()) {
          actions = [a.Call, a.Copy, a.Share];
        } else {
          actions = [a.RecordRefund, a.Call, a.Copy, a.Share];
        }
        break;
      case _InvoiceEnums2.default.Status.CANCELLED:
      case _InvoiceEnums2.default.Status.REFUNDED:
      case _InvoiceEnums2.default.Status.MARKED_AS_REFUNDED:
        actions = [a.Call, a.Copy, a.Share];
        break;
      case _InvoiceEnums2.default.Status.UNPAID:
        actions = [a.RecordPayment, a.Edit, a.Cancel, a.Copy, a.Share];
        break;
      case _InvoiceEnums2.default.Status.PAYMENT_PENDING:
        actions = [a.Call, a.Copy, a.Share];
        break;
      case _InvoiceEnums2.default.Status.SCHEDULED:
        actions = [a.RecordPayment, a.Edit, a.Cancel, a.Copy, a.Call, a.Share, a.Delete];
        break;
      default:
        throw new Error('Unknown invoice status');
    }

    if (!hasEmail) {
      if (actions.indexOf(a.Call) != -1) {
        actions.splice(actions.indexOf(a.Call), 1);
      }

      if (actions.indexOf(a.Remind) != -1) {
        actions.splice(actions.indexOf(a.Remind), 1);
      }
    }

    return actions;
  };

  return InvoiceActions;
}();

exports.default = InvoiceActions;
},{"./InvoiceCalculator":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/InvoiceCalculator.js","./InvoiceEnums":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/InvoiceEnums.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/InvoiceBigNumber.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;
exports.$$ = $$;
exports.IBN = IBN;

var _bignumber = require('bignumber.js');

var _bignumber2 = _interopRequireDefault(_bignumber);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (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 } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var InvoiceBigNumber = function (_BN) {
  _inherits(InvoiceBigNumber, _BN);

  function InvoiceBigNumber() {
    _classCallCheck(this, InvoiceBigNumber);

    return _possibleConstructorReturn(this, _BN.apply(this, arguments));
  }

  InvoiceBigNumber.$$ = function $$(a) {
    var result = IBN(a, 2);
    if (result) {
      result.includeTrailingZeros = true;
    }
    return result;
  };

  InvoiceBigNumber.IBN = function IBN(a, decimalPrecision, includeTrailingZeros) {
    var result = a != undefined && a != null ? new InvoiceBigNumber(a) : null;
    if (result) {
      result.decimalPrecision = decimalPrecision;
      result.includeTrailingZeros = includeTrailingZeros;
    }
    return result;
  };

  InvoiceBigNumber.prototype.toJSON = function toJSON() {
    if (!this.includeTrailingZeros) {
      var num = new _bignumber2.default(this.toFixed(this.decimalPrecision));
      return num.toString();
    } else {
      return this.toFixed(this.decimalPrecision);
    }
  };

  InvoiceBigNumber.prototype.toNumber = function toNumber() {
    var num = new _bignumber2.default(this.toJSON());
    return num.toNumber();
  };

  return InvoiceBigNumber;
}(_bignumber2.default);

exports.default = InvoiceBigNumber;
function $$(a) {
  return InvoiceBigNumber.$$(a);
}

function IBN(a, decimalPrecision, includeTrailingZeros) {
  return InvoiceBigNumber.IBN(a, decimalPrecision, includeTrailingZeros);
}
},{"bignumber.js":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/bignumber.js/bignumber.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/InvoiceCalculator.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;
exports.ONE = exports.ZERO = undefined;

var _Currency = require('./Currency');

var _Currency2 = _interopRequireDefault(_Currency);

var _InvoiceBigNumber = require('./InvoiceBigNumber');

var _InvoiceBigNumber2 = _interopRequireDefault(_InvoiceBigNumber);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

var ZERO = exports.ZERO = new _InvoiceBigNumber2.default(0);
var ONE = exports.ONE = new _InvoiceBigNumber2.default(1);

function nonZero(amt) {
  return amt && !ZERO.equals(amt);
}

function valOrZero(amt) {
  return amt || ZERO;
}

function amtOrZero(val) {
  return val ? val['amount'] : ZERO;
}

function parseAmtOrZero(obj) {
  return obj ? JSON.parse(obj)['amount'] : ZERO;
}

// Calculates the total for the given item with an invoice-level discount included
function calculateItemTotalWithInvoiceDiscount(invoice, item) {
  var itemTotal = item.totalForInvoice(invoice);
  var discountShare = itemTotal.dividedBy(calculateItemTotals(invoice)).times(invoice.discountAmount);
  itemTotal = itemTotal.minus(discountShare);
  return itemTotal;
}

// Calculates the shipping tax for the given invoice
function calculateShippingTax(invoice) {
  var rate = invoice.shippingTaxRate;
  var amount = invoice.shippingAmount;
  var taxes = invoice.taxBreakdown;
  if (nonZero(rate) && nonZero(amount)) {
    var key = invoice.shippingTaxName;
    return parseAmtOrZero(taxes[key]);
  }
  return ZERO;
}

// Calculates the total for all items on the given invoice with discounts included
function calculateItemTotals(invoice) {
  var total = ZERO;
  for (var _iterator = invoice.items, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
    var _ref;

    if (_isArray) {
      if (_i >= _iterator.length) break;
      _ref = _iterator[_i++];
    } else {
      _i = _iterator.next();
      if (_i.done) break;
      _ref = _i.value;
    }

    var i = _ref;

    total = total.plus(i.totalForInvoice(invoice));
  }
  return (0, _InvoiceBigNumber.$$)(total);
}

var InvoiceCalculator = function () {
  function InvoiceCalculator() {
    _classCallCheck(this, InvoiceCalculator);
  }

  // Calculates the total amount discounted from all items on the given invoice
  InvoiceCalculator.calculateItemDiscounts = function calculateItemDiscounts(invoice) {
    var itemDiscounts = ZERO;
    for (var _iterator2 = invoice.items, _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) {
      var _ref2;

      if (_isArray2) {
        if (_i2 >= _iterator2.length) break;
        _ref2 = _iterator2[_i2++];
      } else {
        _i2 = _iterator2.next();
        if (_i2.done) break;
        _ref2 = _i2.value;
      }

      var item = _ref2;

      if (item.discountAmount) {
        itemDiscounts = itemDiscounts.plus(item.discountAmount);
      } else if (item.discountPercentage) {
        var itemSubTotal = item.subtotalForInvoice(invoice);
        var discount = _Currency2.default.round(invoice.currency, itemSubTotal.times(item.discountPercentage.dividedBy(100)));
        itemDiscounts = itemDiscounts.plus(discount);
      }
    }
    return (0, _InvoiceBigNumber.$$)(itemDiscounts);
  };

  // Calculates the subtotal for an invoice from it's list of items


  InvoiceCalculator.calculateSubtotal = function calculateSubtotal(invoice) {
    var subtotal = ZERO;
    for (var _iterator3 = invoice.items, _isArray3 = Array.isArray(_iterator3), _i3 = 0, _iterator3 = _isArray3 ? _iterator3 : _iterator3[Symbol.iterator]();;) {
      var _ref3;

      if (_isArray3) {
        if (_i3 >= _iterator3.length) break;
        _ref3 = _iterator3[_i3++];
      } else {
        _i3 = _iterator3.next();
        if (_i3.done) break;
        _ref3 = _i3.value;
      }

      var item = _ref3;

      subtotal = subtotal.plus(item.subtotalForInvoice(invoice));
    }
    return (0, _InvoiceBigNumber.$$)(subtotal);
  };

  // Calculates the discount price for an invoice


  InvoiceCalculator.calculateDiscountPrice = function calculateDiscountPrice(invoice) {
    var price = ZERO;
    if (invoice.discountAmount) {
      price = invoice.discountAmount;
    }
    if (invoice.discountPercentage) {
      price = invoice.subTotal.sub(invoice.itemDiscounts).mul(invoice.discountPercentage.div(100));
    }
    return _Currency2.default.round(invoice.currency, price);
  };

  // Calculates the tax breakdown for the given invoice, including all item taxes and the shipping tax (if present)


  InvoiceCalculator.calculateTaxBreakdown = function calculateTaxBreakdown(invoice) {
    var taxes = {};
    for (var _iterator4 = invoice.items, _isArray4 = Array.isArray(_iterator4), _i4 = 0, _iterator4 = _isArray4 ? _iterator4 : _iterator4[Symbol.iterator]();;) {
      var _ref4;

      if (_isArray4) {
        if (_i4 >= _iterator4.length) break;
        _ref4 = _iterator4[_i4++];
      } else {
        _i4 = _iterator4.next();
        if (_i4.done) break;
        _ref4 = _i4.value;
      }

      var item = _ref4;

      var amountToBeTaxed = void 0;
      if (invoice.taxCalculatedAfterDiscount) {
        if (invoice.discountAmount) {
          amountToBeTaxed = calculateItemTotalWithInvoiceDiscount(invoice, item);
        } else if (invoice.discountPercentage) {
          amountToBeTaxed = item.totalForInvoice(invoice).times(ONE.minus(invoice.discountPercentage.dividedBy(100)));
        } else {
          amountToBeTaxed = item.totalForInvoice(invoice);
        }
      } else {
        amountToBeTaxed = item.subtotalForInvoice(invoice);
      }
      if (nonZero(item.taxRate)) {
        var _tax = item.taxRate.dividedBy(100);
        var _key = item.taxName;
        if (invoice.taxInclusive) {
          amountToBeTaxed = _Currency2.default.round(invoice.currency, amountToBeTaxed.dividedBy(ONE.plus(_tax)));
        }
        var taxAmount = amountToBeTaxed.times(_tax);
        var roundedTax = _Currency2.default.round(invoice.currency, taxAmount);
        roundedTax = nonZero(roundedTax) ? roundedTax : (0, _InvoiceBigNumber.$$)(0.00);
        taxes[_key] = {
          'amount': _Currency2.default.round(invoice.currency, amtOrZero(taxes[_key]).plus(roundedTax)),
          'rate': item.taxRate.toString()
        };
      }
    }
    var rate = invoice.shippingTaxRate;
    var amount = invoice.shippingAmount;
    if (nonZero(rate) && nonZero(amount)) {
      var key = invoice.shippingTaxName;
      var total = amount.times(rate.dividedBy(100));
      taxes[key] = {
        'amount': _Currency2.default.round(invoice.currency, amtOrZero(taxes[key]).plus(total)),
        'rate': rate.toString()
      };
    }
    for (var tax in taxes) {
      taxes[tax] = JSON.stringify(taxes[tax]);
    }
    return taxes;
  };

  // Calculates the discount total for the given invoice from either an amount or a percentage


  InvoiceCalculator.calculateDiscountTotal = function calculateDiscountTotal(invoice) {
    if (nonZero(invoice.discountAmount)) {
      return (0, _InvoiceBigNumber.$$)(invoice.discountAmount);
    } else if (nonZero(invoice.discountPercentage)) {
      return _Currency2.default.round(invoice.currency, (0, _InvoiceBigNumber.$$)(invoice.discountPercentage).dividedBy(100).times(calculateItemTotals(invoice)));
    }
    return ZERO;
  };

  // Calculates the tax total for all items on the invoice based on the tax breakdown, not counting the shipping tax


  InvoiceCalculator.calculateItemTaxTotal = function calculateItemTaxTotal(invoice) {
    var taxes = invoice.taxBreakdown;
    var taxTotal = ZERO;
    for (var tax in taxes) {
      taxTotal = taxTotal.plus(parseAmtOrZero(taxes[tax]));
    }
    var shippingTax = calculateShippingTax(invoice);
    return nonZero(taxTotal) ? taxTotal.minus(shippingTax) : taxTotal;
  };

  // Calculates the grand total for the given invoice


  InvoiceCalculator.calculateTotal = function calculateTotal(invoice) {
    var taxTotal = invoice.taxInclusive ? ZERO : valOrZero(invoice.itemTax).plus(calculateShippingTax(invoice));
    var custom = invoice.custom ? invoice.custom.amount : ZERO;
    var total = valOrZero(invoice.subTotal).plus(valOrZero(invoice.gratuityAmount)).plus(valOrZero(invoice.shippingAmount)).plus(taxTotal).plus(custom).minus(valOrZero(invoice.totalDiscount)).minus(InvoiceCalculator.calculateItemDiscounts(invoice));
    return _Currency2.default.round(invoice.currency, total);
  };

  return InvoiceCalculator;
}();

exports.default = InvoiceCalculator;
},{"./Currency":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/Currency.js","./InvoiceBigNumber":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/InvoiceBigNumber.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/InvoiceConstants.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

var _bignumber = require('bignumber.js');

var _bignumber2 = _interopRequireDefault(_bignumber);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

/**
* Class for getting constants relating to invoice business logic.
* @class
*/
var InvoiceConstants = function () {
  function InvoiceConstants() {
    _classCallCheck(this, InvoiceConstants);
  }

  /**
  * The number of numbers allowed after the decimal point for tax rates, including item & shipping. 
  * @method
  * @returns {decimal}
  */
  InvoiceConstants.taxRateDecimalPrecision = function taxRateDecimalPrecision() {
    return new _bignumber2.default(5);
  };

  /**
  * The number of numbers allowed after the decimal point for discount rates. 
  * @method
  * @returns {decimal}
  */


  InvoiceConstants.discountPercentageDecimalPrecision = function discountPercentageDecimalPrecision() {
    return new _bignumber2.default(2);
  };

  /**
   * Character max for invoice number. 
   * @method
   * @returns {decimal}
   */


  InvoiceConstants.invoiceNumberMaxLength = function invoiceNumberMaxLength() {
    return new _bignumber2.default(25);
  };

  /**
  * Character max for invoice terms. 
  * @method
  * @returns {decimal}
  */


  InvoiceConstants.invoiceTermsMaxLength = function invoiceTermsMaxLength() {
    return new _bignumber2.default(4000);
  };

  /**
  * Character max for invoice note. 
  * @method
  * @returns {decimal}
  */


  InvoiceConstants.invoiceNoteMaxLength = function invoiceNoteMaxLength() {
    return new _bignumber2.default(4000);
  };

  /**
  * Character max for invoice merchant memo. 
  * @method
  * @returns {decimal}
  */


  InvoiceConstants.invoiceMerchantMemoMaxLength = function invoiceMerchantMemoMaxLength() {
    return new _bignumber2.default(150);
  };

  /**
  * Character max for invoice reference field. 
  * @method
  * @returns {decimal}
  */


  InvoiceConstants.invoiceReferenceMaxLength = function invoiceReferenceMaxLength() {
    return new _bignumber2.default(60);
  };

  /**
  * The number of numbers allowed after the decimal point for item quantity. 
  * @method
  * @returns {decimal}
  */


  InvoiceConstants.itemQuantityDecimalPrecision = function itemQuantityDecimalPrecision() {
    return new _bignumber2.default(5);
  };

  /**
  * The maximum quantity allowed to specify on an invoice, inclusive. 
  * @method
  * @returns {decimal}
  */


  InvoiceConstants.itemQuantityMax = function itemQuantityMax() {
    return new _bignumber2.default(1000);
  };

  /**
  * The minimum quantity allowed to specify on an invoice, inclusive. 
  * @method
  * @returns {decimal}
  */


  InvoiceConstants.itemQuantityMin = function itemQuantityMin() {
    return new _bignumber2.default(-1000);
  };

  /**
  * Character max for invoice item name. 
  * @method
  * @returns {decimal}
  */


  InvoiceConstants.itemNameMaxLength = function itemNameMaxLength() {
    return new _bignumber2.default(200);
  };

  /**
  * Character max for invoice item description. 
  * @method
  * @returns {decimal}
  */


  InvoiceConstants.itemDescriptionMaxLength = function itemDescriptionMaxLength() {
    return new _bignumber2.default(1000);
  };

  /**
  * Max value for invoice item price. 
  * @method
  * @returns {decimal}
  */


  InvoiceConstants.itemPriceMax = function itemPriceMax() {
    return new _bignumber2.default(999999.99);
  };
  /**
  * Max value for tax
  * @method
  * @returns {decimal}
  */


  InvoiceConstants.taxRateMaxValue = function taxRateMaxValue() {
    return new _bignumber2.default(99.99999);
  };

  return InvoiceConstants;
}();

exports.default = InvoiceConstants;
},{"bignumber.js":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/bignumber.js/bignumber.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/InvoiceEnums.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

var _manticoreUtil = require('manticore-util');

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

// This class is named Invoice for the sake of codegen
var Invoice = function Invoice() {
  _classCallCheck(this, Invoice);
};

/**
 * Valid invoice statuses
 * @enum {int}
 */


exports.default = Invoice;
Invoice.Status = {
  /**
   * The invoice has not been saved to the server
   */
  NEW: 0,
  /**
   * The invoice has been saved to the server
   */
  DRAFT: 1,
  /**
   * The invoice has been sent to the recipient(payer)
   */
  SENT: 2,
  /**
   * The invoice has been paid with a balance affecting instrument like PayPal or CC
   */
  PAID: 3,
  /**
   * The invoice has been marked as paid with a method outside PayPal
   */
  MARKED_AS_PAID: 4,
  /**
   * The invoice has been cancelled
   */
  CANCELLED: 5,
  /**
   * The invoice has been refunded from a balance affecting instrument
   */
  REFUNDED: 6,
  /**
   * The invoice has been partially refunded from a balance affecting instrument
   */
  PARTIALLY_REFUNDED: 7,
  /**
   * The invoice has been marked as refunded with a method outside PayPal
   */
  MARKED_AS_REFUNDED: 8,
  /**
   * The invoice has been partially paid
   */
  PARTIALLY_PAID: 9,
  /*
   * The invoice has been sent with no receipient
   */
  UNPAID: 10,
  /*
   * A payment has been made on 'the invoice, but the merchant is not verified and
   * is therefore unable to accept the payment
   */
  PAYMENT_PENDING: 11,
  /**
   * The invoice has been scheduled
   */
  SCHEDULED: 12,
  /*
   * We were unable to infer or map the status
   */
  UNKNOWN: 13

};

Invoice.Status.toString = (0, _manticoreUtil.reverseKeysAndValues)(Invoice.Status);

/**
 * PayPal payment detail indicating whether payment was made in an invoicing flow via PayPal
 * or externally. In the case of the mark-as-paid API, payment type is EXTERNAL and this
 * is what is now supported. The PAYPAL value is provided for backward compatibility.
 * @enum {int}
 */
Invoice.PaymentType = {
  /**
   * The invoice hasn't been paid
   */
  NONE: 0,
  /**
   * The invoice was paid with an external (non-balance-affecting) source
   */
  EXTERNAL: 1,
  /**
   * The invoice was paid with an internal (balance-affecting) source
   */
  PAYPAL: 2
};

Invoice.PaymentType.toString = (0, _manticoreUtil.reverseKeysAndValues)(Invoice.PaymentType);

/**
 * Payment mode or method.
 * @enum {int}
 */
Invoice.PaymentMethod = {
  /**
   * None
   */
  NONE: 0,
  /**
   * Bank Transfer
   */
  BANK_TRANSFER: 1,
  /**
   * Cash
   */
  CASH: 2,
  /**
   * Check
   */
  CHECK: 3,
  /**
   * Credit Card
   */
  CREDIT_CARD: 4,
  /**
   * Debit Card
   */
  DEBIT_CARD: 5,
  /**
   * PayPal
   */
  PAYPAL: 6,
  /**
   * Wire Transfer
   */
  WIRE_TRANSFER: 7,
  /**
   * Other
   */
  OTHER: 8
};

Invoice.PaymentMethod.toString = (0, _manticoreUtil.reverseKeysAndValues)(Invoice.PaymentMethod);

/**
 * Invoice action
 * @enum {int}
 */
Invoice.Action = {
  /**
   * None
   */
  None: 0,
  /**
   * Delete
   */
  Delete: 1,
  /**
   * Send
   */
  Send: 2,
  /**
   * Remind
   */
  Remind: 3,
  /**
   * Record Payment
   */
  RecordPayment: 4,
  /**
   * Record Refund
   */
  RecordRefund: 5,
  /**
   * Copy
   */
  Copy: 6,
  /**
   * Edit
   */
  Edit: 7,
  /**
   * Call
   */
  Call: 8,
  /**
   * Cancel
   */
  Cancel: 9,
  /**
   * More
   */
  More: 10,
  /**
   * Share
   */
  Share: 11,
  /**
   * View History
   */
  ViewHistory: 12,
  /**
   * View Invoice
   */
  ViewInvoice: 13
};
},{"manticore-util":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-util/build/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/InvoiceListRequest.js":[function(require,module,exports){
"use strict";

exports.__esModule = true;

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

/**
 * @class
 * @property {int} startIndex A zero-relative index of the merchant's list of invoices
 * @property {int} pageSize The number of invoices to retrieve, beginning with the specified page
 * @property {bool} totalCountRequired Determines if the total count is returned.
 */
var InvoiceListRequest = function InvoiceListRequest() {
  _classCallCheck(this, InvoiceListRequest);

  this.startIndex = 0;
  this.pageSize = 20;
  this.totalCountRequired = true;
};

exports.default = InvoiceListRequest;
},{}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/InvoiceListResponse.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

var _Invoice = require('./Invoice');

var _Invoice2 = _interopRequireDefault(_Invoice);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

/**
 * @class
 * @property {[Invoice]} invoices All the invoices in the requested page of the invoice list
 * @property {int} totalCount The total number of invoices in the invoice list.
 *  May be 0 if totalCountRequired wasn't specified.
 * @property {bool} hasMore yes if this is not the last page of invoices
 */
var InvoiceListResponse = function () {
  function InvoiceListResponse() {
    _classCallCheck(this, InvoiceListResponse);
  }

  InvoiceListResponse.fromJSON = function fromJSON(json) {
    var r = new InvoiceListResponse();

    r.invoices = [];
    if (json && json.invoices) {
      for (var _iterator = json.invoices, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
        var _ref;

        if (_isArray) {
          if (_i >= _iterator.length) break;
          _ref = _iterator[_i++];
        } else {
          _i = _iterator.next();
          if (_i.done) break;
          _ref = _i.value;
        }

        var invoiceJSON = _ref;

        var i = _Invoice2.default.fromJson(invoiceJSON, false);
        i.setCleanFromServer();
        r.invoices.push(i);
      }
    }

    r.totalCount = json && json.total_count ? json.total_count : 0;

    return r;
  };

  return InvoiceListResponse;
}();

exports.default = InvoiceListResponse;
},{"./Invoice":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/Invoice.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/InvoiceMetaData.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

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; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

var _InvoicingUtil = require('./InvoicingUtil');

var _InvoicingUtil2 = _interopRequireDefault(_InvoicingUtil);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

/**
 * Invoice MetaData
 * @class
 * @property {Date} createdDate Date when the resource was created. @readonly
 * @property {string} createdBy Email address of the account that created the resource. @readonly
 * @property {Date} cancelledDate Date when the resource was cancelled. @readonly
 * @property {string} cancelledBy Actor who cancelled the resource. @readonly
 * @property {Date} lastUpdatedDate Date when the resource was last edited. @readonly
 * @property {string} lastUpdatedBy Email address of the account that last
 *  edited the resource. @readonly
 * @property {Date} firstSentDate Date when the resource was first sent. @readonly
 * @property {Date} lastSentDate Date when the resource was last sent. @readonly
 * @property {string} lastSentBy Email address of the account that last sent the resource. @readonly
 * @property {string} payerViewURL URL representing the payer's view of the invoice. @readonly
 */
var InvoiceMetaData = function () {
  function InvoiceMetaData() {
    _classCallCheck(this, InvoiceMetaData);
  }

  InvoiceMetaData.fromJSON = function fromJSON(json) {
    var m = new InvoiceMetaData();

    m.createdBy = json.created_by;
    m.cancelledBy = json.cancelled_by;
    m.lastUpdatedBy = json.last_updated_by;
    m.lastSentBy = json.last_sent_by;
    m.payerViewURL = json.payer_view_url;

    if (json.created_date) {
      m.createdDate = _InvoicingUtil2.default.parseServerDateString(json.created_date);
    }
    if (json.cancelled_date) {
      m.cancelledDate = _InvoicingUtil2.default.parseServerDateString(json.cancelled_date);
    }
    if (json.last_updated_date) {
      m.lastUpdatedDate = _InvoicingUtil2.default.parseServerDateString(json.last_updated_date);
    }
    if (json.first_sent_date) {
      m.firstSentDate = _InvoicingUtil2.default.parseServerDateString(json.first_sent_date);
    }
    if (json.last_sent_date) {
      m.lastSentDate = _InvoicingUtil2.default.parseServerDateString(json.last_sent_date);
    }
    return m;
  };

  InvoiceMetaData.toFullJSON = function toFullJSON(metadata) {
    var r = {};

    r.created_by = metadata.createdBy;
    r.cancelled_by = metadata.cancelledBy;
    r.last_updated_by = metadata.lastUpdatedBy;
    r.last_sent_by = metadata.lastSentBy;
    r.payer_view_url = metadata.payerViewURL;

    if (metadata.createdDate) {
      r.created_date = _InvoicingUtil2.default.toServerDateString(metadata.createdDate, true);
    }
    if (metadata.cancelledDate) {
      r.cancelled_date = _InvoicingUtil2.default.toServerDateString(metadata.cancelledDate, true);
    }
    if (metadata.lastUpdatedDate) {
      r.last_updated_date = _InvoicingUtil2.default.toServerDateString(metadata.lastUpdatedDate, true);
    }
    if (metadata.firstSentDate) {
      r.first_sent_date = _InvoicingUtil2.default.toServerDateString(metadata.firstSentDate, true);
    }
    if (metadata.lastSentDate) {
      r.last_sent_date = _InvoicingUtil2.default.toServerDateString(metadata.lastSentDate, true);
    }
    return r;
  };

  _createClass(InvoiceMetaData, [{
    key: 'createdDate',
    set: function set(date) {
      this._createdDate = date;
    },
    get: function get() {
      return _InvoicingUtil2.default.getDateValue(this._createdDate);
    }
  }, {
    key: 'cancelledDate',
    set: function set(date) {
      this._cancelledDate = date;
    },
    get: function get() {
      return _InvoicingUtil2.default.getDateValue(this._cancelledDate);
    }
  }, {
    key: 'firstSentDate',
    set: function set(date) {
      this._firstSentDate = date;
    },
    get: function get() {
      return _InvoicingUtil2.default.getDateValue(this._firstSentDate);
    }
  }, {
    key: 'lastSentDate',
    set: function set(date) {
      this._lastSentDate = date;
    },
    get: function get() {
      return _InvoicingUtil2.default.getDateValue(this._lastSentDate);
    }
  }]);

  return InvoiceMetaData;
}();

exports.default = InvoiceMetaData;
},{"./InvoicingUtil":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/InvoicingUtil.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/InvoiceTemplatesResponse.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

var _Template = require('./Template');

var _Template2 = _interopRequireDefault(_Template);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

/**
 * @class
 * @property {InvoiceTemplate} defaultTemplate The default template
 * @property {[InvoiceTemplate]} templates array of all the templates
 */
var InvoiceTemplatesResponse = function () {
  function InvoiceTemplatesResponse() {
    _classCallCheck(this, InvoiceTemplatesResponse);

    this.templates = [];
  }

  InvoiceTemplatesResponse.fromJSON = function fromJSON(json) {
    var r = void 0;

    if (json && json.templates) {
      r = new InvoiceTemplatesResponse();

      for (var _iterator = json.templates, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
        var _ref;

        if (_isArray) {
          if (_i >= _iterator.length) break;
          _ref = _iterator[_i++];
        } else {
          _i = _iterator.next();
          if (_i.done) break;
          _ref = _i.value;
        }

        var t = _ref;

        var temp = _Template2.default.fromJSON(t);
        if (temp !== undefined) {
          r.templates.push(temp);
          if (temp.isDefault === true) {
            r.defaultTemplate = temp;
          }
        }
      }

      r.templates = _Template2.default.sortTemplates(r.templates);
    }

    return r;
  };

  return InvoiceTemplatesResponse;
}();

exports.default = InvoiceTemplatesResponse;
},{"./Template":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/Template.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/InvoicingService.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

var _BaseService2 = require('./BaseClasses/BaseService');

var _BaseService3 = _interopRequireDefault(_BaseService2);

var _Requester = require('./Requester');

var _InvoiceListResponse = require('./InvoiceListResponse');

var _InvoiceListResponse2 = _interopRequireDefault(_InvoiceListResponse);

var _InvoiceTemplatesResponse = require('./InvoiceTemplatesResponse');

var _InvoiceTemplatesResponse2 = _interopRequireDefault(_InvoiceTemplatesResponse);

var _Attachment = require('./Attachment');

var _Attachment2 = _interopRequireDefault(_Attachment);

var _Invoice = require('./Invoice');

var _Invoice2 = _interopRequireDefault(_Invoice);

var _AccountSummary = require('./AccountSummary');

var _AccountSummary2 = _interopRequireDefault(_AccountSummary);

var _InvoicingUtil = require('./InvoicingUtil');

var _InvoicingUtil2 = _interopRequireDefault(_InvoicingUtil);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (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 } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

/**
 * @class
 */
var InvoicingService = function (_BaseService) {
    _inherits(InvoicingService, _BaseService);

    function InvoicingService() {
        _classCallCheck(this, InvoicingService);

        return _possibleConstructorReturn(this, _BaseService.apply(this, arguments));
    }

    /**
     * @param {InvoiceListRequest} params
     * @param {InvoicingService~getInvoices} completionHandler The completion handler
     */
    InvoicingService.getInvoices = function getInvoices(params, completionHandler) {
        var si = params.startIndex,
            pg = params.pageSize,
            tot = params.totalCountRequired;

        (0, _Requester.request)({
            method: 'GET',
            op: 'invoices?page=' + si + '&page_size=' + pg + '&total_count_required=' + tot
        }, function (error, response) {
            if (error) {
                completionHandler(error);
            } else {
                var r = _InvoiceListResponse2.default.fromJSON(response.body);
                r.hasMore = params.startIndex + params.pageSize < r.totalCount;
                completionHandler(error, r);
            }
        });
    };

    /**
     * Search for a specific invoice or invoices by passing a search object that
     * specifies your * search criteria.
     * @param {InvoiceSearchRequest} params
     * @param {InvoicingService~searchInvoices} completionHandler The completion handler
     */


    InvoicingService.searchInvoices = function searchInvoices(params, completionHandler) {
        (0, _Requester.request)({
            method: 'POST',
            op: 'search',
            body: JSON.stringify(params)
        }, function (error, response) {
            if (error) {
                completionHandler(error);
            } else {
                var r = _InvoiceListResponse2.default.fromJSON(response.body);
                r.hasMore = params.startIndex + params.pageSize < r.totalCount;
                completionHandler(error, r);
            }
        });
    };

    /**
     * Load the details for a specific invoice given the invoice ID
     * @param {string} invoiceID
     * @param {InvoicingService~getInvoice} completionHandler The completion handler
     */


    InvoicingService.getInvoice = function getInvoice(invoiceID, completionHandler) {
        InvoicingService.getInvoiceDetails(invoiceID, function (error, details) {
            if (error) {
                completionHandler(error);
            } else {
                var invoice = _Invoice2.default.fromJson(details, true);
                invoice.setCleanFromServer();
                completionHandler(error, invoice);
            }
        });
    };

    //Completion handler should accept error and JSON


    InvoicingService.getInvoiceDetails = function getInvoiceDetails(invoiceID, completionHandler) {
        (0, _Requester.request)({
            method: 'GET',
            op: 'invoices/' + invoiceID
        }, function (error, response) {
            if (error) {
                completionHandler(error);
            } else {
                completionHandler(error, response.body);
            }
        });
    };

    /**
     * @param {InvoicingService~getNextInvoiceNumber} completionHandler The completion handler
     */


    InvoicingService.getNextInvoiceNumber = function getNextInvoiceNumber(completionHandler) {
        (0, _Requester.request)({
            method: 'POST',
            op: 'invoices/next-invoice-number'
        }, function (error, response) {
            if (error) {
                completionHandler(error);
            } else {
                var nextInvNum = response.body.number;
                completionHandler(error, nextInvNum);
            }
        });
    };

    /**
     * @param {InvoicingService~getAccountSummary} completionHandler The completion handler
     */


    InvoicingService.getAccountSummary = function getAccountSummary(completionHandler) {
        var _this2 = this;

        // TODO: Should we expose something closer to the actual API? Right now we're returning data
        // specifically for the PPB app.

        var firstError = void 0;
        var secondError = void 0;
        var firstResponse = void 0;
        var secondResponse = void 0;

        var maybeContinue = function maybeContinue() {
            if ((firstError || firstResponse) && (secondError || secondResponse)) {
                _this2.continueGetAccountSummary(firstError, firstResponse, secondError, secondResponse, completionHandler);
            }
        };

        (0, _Requester.request)({
            method: 'GET',
            op: 'summaries?overdue=false'
        }, function (error, response) {
            firstError = error;
            firstResponse = response;
            maybeContinue();
        });

        (0, _Requester.request)({
            method: 'GET',
            op: 'summaries?overdue=true'
        }, function (error, response) {
            secondError = error;
            secondResponse = response;
            maybeContinue();
        });
    };

    InvoicingService.continueGetAccountSummary = function continueGetAccountSummary(firstError, firstResponse, secondError, secondResponse, completionHandler) {
        var error = firstError || secondError;
        if (error) {
            completionHandler(error);
        }
        completionHandler(error, new _AccountSummary2.default(firstResponse.body, secondResponse.body));
    };

    /**
     * @param {InvoicingService~getTemplates} completionHandler The completion handler
     */


    InvoicingService.getTemplates = function getTemplates(completionHandler) {
        (0, _Requester.request)({
            method: 'GET',
            op: 'templates'
        }, function (error, response) {
            if (error) {
                completionHandler(error);
            } else {
                completionHandler(error, _InvoiceTemplatesResponse2.default.fromJSON(response.body));
            }
        });
    };

    /**
     * @param {string} fileHandle Native reference to the file
     * @param {string} contentType Content type of the file
     * @param {InvoicingService~uploadFile} completionHandler The completion handler
     * Supported types: image/png, image/jpg, image/jpeg, image/gif, application/xml, application/pdf, image/tiff, image/tif, image/bmp
     */


    InvoicingService.uploadFile = function uploadFile(fileHandle, contentType, completionHandler) {
        var _this3 = this;

        if (fileHandle === undefined || fileHandle === '') {
            var error = new Error('file handle must be defined');
            return completionHandler(error, undefined);
        }

        if (!_InvoicingUtil2.default.isFileUploadSupported(contentType)) {
            var _error = new Error('Unsupported MIME type');
            return completionHandler(_error, undefined);
        }

        var params = {
            contentType: contentType,
            name: 'file',
            value: fileHandle
        };
        (0, _Requester.request)({
            method: 'POST',
            op: 'files',
            headers: { 'Content-Type': 'multipart/form-data' },
            multiPartBody: params
        }, function (error, response) {
            if (error) {
                completionHandler(error);
            } else {
                var attachmentResponse = _this3.adaptUploadAttachmentResponse(response.body);
                completionHandler(error, _Attachment2.default.readFromJson(attachmentResponse));
            }
        });
    };

    InvoicingService.adaptUploadAttachmentResponse = function adaptUploadAttachmentResponse(response) {
        return {
            name: response.filename ? response.filename : undefined,
            url: response.id ? '&id=' + response.id : undefined
        };
    };

    return InvoicingService;
}(_BaseService3.default);

/**
 * @callback InvoicingService~getInvoices
 * @param {PayPalError} error The error that occurred, if any
 * @param {InvoiceListResponse} response The server response
 */

/**
 * @callback InvoicingService~searchInvoices
 * @param {PayPalError} error The error that occurred, if any
 * @param {InvoiceListResponse} response The server response
 */

/**
 * @callback InvoicingService~getInvoice
 * @param {PayPalError} error The error that occurred, if any
 * @param {Invoice} response The server response
 */

/**
 * @callback InvoicingService~getAccountSummary
 * @param {PayPalError} error The error that occurred, if any
 * @param {AccountSummary} response The server response
 */

/**
 * @callback InvoicingService~getTemplates
 * @param {PayPalError} error The error that occurred, if any
 * @param {InvoiceTemplatesResponse} response The server response
 */

/**
 * @callback InvoicingService~getNextInvoiceNumber
 * @param {PayPalError} error The error that occurred, if any
 * @param {string} response The server response
 */

/**
 * @callback InvoicingService~uploadFile
 * @param {PayPalError} error The error that occurred, if any
 * @param {InvoiceAttachment} response The server response
 */


exports.default = InvoicingService;
},{"./AccountSummary":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/AccountSummary.js","./Attachment":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/Attachment.js","./BaseClasses/BaseService":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/BaseClasses/BaseService.js","./Invoice":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/Invoice.js","./InvoiceListResponse":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/InvoiceListResponse.js","./InvoiceTemplatesResponse":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/InvoiceTemplatesResponse.js","./InvoicingUtil":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/InvoicingUtil.js","./Requester":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/Requester.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/InvoicingUtil.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

var _moment = require('moment');

var _moment2 = _interopRequireDefault(_moment);

var _manticore = require('manticore');

var _manticore2 = _interopRequireDefault(_manticore);

var _InvoiceEnums = require('./InvoiceEnums');

var _InvoiceEnums2 = _interopRequireDefault(_InvoiceEnums);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

var InvoicingUtils = function () {
  function InvoicingUtils() {
    _classCallCheck(this, InvoicingUtils);
  }

  InvoicingUtils.parseInvoicePaymentType = function parseInvoicePaymentType(type) {
    if (type && _InvoiceEnums2.default.PaymentType[type] !== undefined) {
      return _InvoiceEnums2.default.PaymentType[type];
    }

    return _InvoiceEnums2.default.PaymentType.NONE;
  };

  InvoicingUtils.parseInvoicePaymentMethod = function parseInvoicePaymentMethod(method) {
    if (method && _InvoiceEnums2.default.PaymentMethod[method] !== undefined) {
      return _InvoiceEnums2.default.PaymentMethod[method];
    }

    return _InvoiceEnums2.default.PaymentMethod.OTHER;
  };

  InvoicingUtils.isInvoicePastDue = function isInvoicePastDue(status, paymentTerms, sendDate) {
    if (!this.hasAwaitingPaymentStatus(status)) {
      return false;
    }

    if (!paymentTerms) {
      return false;
    }

    var today = new Date();
    today.setHours(0, 0, 0, 0);

    if (paymentTerms.paymentTerms) {
      var days = paymentTerms.daysForTerm;
      var dueDate = this.parseServerDateString(sendDate);
      dueDate.date(dueDate.date() + days);
      return dueDate.valueOf() < today.valueOf();
    } else if (paymentTerms.dueDate) {
      var dueDate = this.parseServerDateString(paymentTerms.dueDate);
      return dueDate.valueOf() < today.valueOf();
    } else {
      return false;
    }
  };

  InvoicingUtils.hasAwaitingPaymentStatus = function hasAwaitingPaymentStatus(status) {
    if (status === _InvoiceEnums2.default.Status.SENT || status === _InvoiceEnums2.default.Status.PARTIALLY_PAID || status === _InvoiceEnums2.default.Status.UNPAID || status === _InvoiceEnums2.default.Status.SCHEDULED) {
      return true;
    }
    return false;
  };

  InvoicingUtils.parseServerDateString = function parseServerDateString(date) {
    if (!date) {
      return date;
    }
    // Sometimes the date string doesn't have a time. In that case, the first replace will add one.
    var _date = date.replace(/(\d{4}-\d{2}-\d{2}) (PST|PDT)/, '$1 12:59:59 $2');
    _date = _date.replace('PST', '-0800').replace('PDT', '-0700');
    return _moment2.default.parseZone(_date, 'YYYY-MM-DD hh:mm:ss Z');
  };

  InvoicingUtils.toServerDateString = function toServerDateString(date, shouldIncludeTime) {
    if (!date) {
      return date;
    }
    var _date = (0, _moment2.default)(date);
    // It's important that we render dates into PDT instead of PST.
    // If we receive a date in PDT and then render it into PST, we'll assume the incoming date is at
    // time 00:00:00, which then ends up being in the previous day PST. Going from PST->PDT, the
    // offset goes the other way, so the day remains the same.
    //
    // Also, some invoicing fields won't accept the hh:mm:ss timestamp,
    // but it's required for others.  So, we are required to make you specify whether
    // you want the time or not.
    //
    // All of this could have been avoided by choosing a non-ridiculous date format, but ¯\_(ツ)_/¯.

    if (shouldIncludeTime) {
      _date.utcOffset(-420);
      return _date.format('YYYY-MM-DD HH:mm:ss') + ' PDT';
    }

    return _date.format('YYYY-MM-DD') + ' PDT';
  };

  InvoicingUtils.getDateValue = function getDateValue(date) {
    return date && date.constructor === (0, _moment2.default)().constructor ? date.toDate() : date;
  };

  InvoicingUtils.isFileUploadSupported = function isFileUploadSupported(contentType) {
    var supportedMimeTypes = ['image/png', 'image/jpg', 'image/jpeg', 'image/gif', 'application/xml', 'application/pdf', 'image/tiff', 'image/bmp'];
    return supportedMimeTypes.indexOf(contentType) !== -1;
  };

  InvoicingUtils.emitAsync = function emitAsync(emitter, eventName) {
    for (var _len = arguments.length, args = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
      args[_key - 2] = arguments[_key];
    }

    if (emitter.listenerCount && emitter.listenerCount(eventName) > 0) {
      _manticore2.default.setTimeout(function () {
        emitter.emit.apply(emitter, [eventName].concat(args));
      }, 0);
    }
  };

  return InvoicingUtils;
}();

exports.default = InvoicingUtils;
},{"./InvoiceEnums":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/InvoiceEnums.js","manticore":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore/browser.js","moment":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/node_modules/moment/moment.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/Item.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

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; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

var _events = require('events');

var _InvoiceBigNumber = require('./InvoiceBigNumber');

var _InvoiceConstants = require('./InvoiceConstants');

var _InvoiceConstants2 = _interopRequireDefault(_InvoiceConstants);

var _Currency = require('./Currency');

var _Currency2 = _interopRequireDefault(_Currency);

var _manticoreUtil = require('manticore-util');

var _InvoicingUtil = require('./InvoicingUtil');

var _InvoicingUtil2 = _interopRequireDefault(_InvoicingUtil);

var _deepEqual = require('deep-equal');

var _deepEqual2 = _interopRequireDefault(_deepEqual);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (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 } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var staticIdAllocator = 1;
var ZERO = (0, _InvoiceBigNumber.$$)(0);

// TODO refactor tax rates into a real object?

/**
 * A line item on an invoice. Can be positive, negative, or zero total/unit price.
 * See https://cms.paypal.com/cms_content/US/en_US/files/developer/PP_InvoicingAPIGuide.pdf
 * for details on field length restrictions and formats.
 * @class
 * @property {string} name The name of this item
 * @property {string} itemDescription A description for this line item
 * @property {decimal} quantity The quantity of this item - up to three decimals
 * @property {decimal} unitPrice The price of 1 unit of this item
 * @property {int} itemId A unique identifier for this item - not currently saved to the
 *  server but used for local uniqueness such that one line item per itemId.detailId pair
 *  will be stored on an invoice @readonly
 * @property {string} detailId A secondary unique identifier (e.g. for item options
 *  or sizes, or to create multiple items on the same invoice with a single detailId) @readonly
 * @property {string} taxName The name for the tax rate applied to this item, if any
 * @property {decimal} taxRate The tax rate to be applied to this item. If non-zero,
 *  the taxName must also be set.
 * @property {decimal} discountPercentage A percentage discount for this line item
 * @property {decimal} discountAmount A flat amount discount for this line item
 * @property {Date} date Date on which the item or service was provided
 * @property {string} imageURL Image url of the item. 4000 characters max.
 * @property {string} unitOfMeasure Unit of measure of the item being invoiced.
 *
 */

var InvoiceItem = function (_EventEmitter) {
  _inherits(InvoiceItem, _EventEmitter);

  /**
   * Create a new invoice item with the required information (detailId is optional).
   * @constructor
   * @private
   * @param {string} name The name of the item
   * @param {decimal} quantity The quantity of this item - up to three decimals
   * @param {decimal} unitPrice The price of 1 unit of this item
   * @param {int} itemId A unique identifier for this item - not currently saved
   *  to the server but used for local
   * uniqeuness such that one line item per itemId.detailId pair will be stored on an invoice
   * @param {string} detailId A secondary unique identifier (e.g. for item options
   *  or sizes, or to create multiple items on the same invoice with a single detailId)
   */
  function InvoiceItem(name, quantity, unitPrice, itemId, detailId) {
    _classCallCheck(this, InvoiceItem);

    var _this = _possibleConstructorReturn(this, _EventEmitter.call(this));

    _this.name = name;
    if (!quantity) {
      quantity = 0;
    }

    if (!unitPrice) {
      unitPrice = 0;
    }

    // The server can return item quantities with over 15 digits, in which case bignumber errors.
    // We don't really care about the 16th digit, so convert to a string so
    // bignumber doesn't complain.
    _this._quantity = (0, _InvoiceBigNumber.IBN)(String(quantity), _InvoiceConstants2.default.itemQuantityDecimalPrecision());
    _this.unitPrice = (0, _InvoiceBigNumber.$$)(unitPrice || 0);
    _this.itemId = itemId && itemId > 0 ? itemId : staticIdAllocator++;
    _this.detailId = detailId || null;
    return _this;
  }

  /**
   * Create a true copy / duplicate of an item. This is named duplicate instead
   * of copy to avoid code gen issues on iOS
   * @returns {InvoiceItem} the copy / duplicate of the item
   */


  InvoiceItem.prototype.duplicate = function duplicate() {
    return InvoiceItem.fromJson((0, _manticoreUtil.deepToJSON)(this.toJSON()));
  };

  /**
   * Returns a decimal for the discount amount for this item, regardless of if it's specified as an amount or percentage.
   * @returns {decimal} If there is a discount, the discount amount, either stored or calcualed from discount percentage. Else returns undefined.
   */


  InvoiceItem.prototype.discountAmountForDisplay = function discountAmountForDisplay() {
    if (this.discountAmount) {
      return this.discountAmount;
    } else if (this.discountPercentage) {
      if (this.quantity && this.unitPrice) {
        var itemPrice = this.quantity.times(this.unitPrice);
        var result = itemPrice.times(this.discountPercentage / 100);

        return result;
      } else {
        return new ZERO();
      }
    }
    return null;
  };

  /**
   * Do simple math without discounts for this line item
   * @private
   */


  InvoiceItem.prototype.subtotalForInvoice = function subtotalForInvoice(invoice) {
    var itemPrice = this.quantity.times(this.unitPrice || ZERO);
    return _Currency2.default.round(invoice.currency, itemPrice);
  };

  /**
   * Do the simple math for this line item
   * @private
   */


  InvoiceItem.prototype.totalForInvoice = function totalForInvoice(invoice) {
    var itemPrice = this.subtotalForInvoice(invoice);
    if (this.discountPercentage) {
      var discount = _Currency2.default.round(invoice.currency, itemPrice.times(this.discountPercentage / 100));
      itemPrice = itemPrice.minus(discount);
    } else if (this.discountAmount) {
      itemPrice = itemPrice.minus(this.discountAmount);
    }
    return _Currency2.default.round(invoice.currency, itemPrice);
  };

  InvoiceItem.prototype._emitPriceMayHaveChanged = function _emitPriceMayHaveChanged(source) {
    _InvoicingUtil2.default.emitAsync(this, InvoiceItem.event.priceMayHaveChanged, 'item.' + source);
  };

  /**
   * Read the properties of this object from json, transforming to numbers where appropriate
   * @param json
   * @private
   */
  InvoiceItem.fromJson = function fromJson(json) {
    /* jshint maxcomplexity: false */
    var item = new InvoiceItem(json.name, json.quantity, json.unit_price.value, json.itemId || staticIdAllocator++, json.detailId);
    if (json.description) {
      item.itemDescription = json.description;
    }
    if (json.unit_price) {
      item.unitPrice = json.unit_price.value;
    }
    if (json.tax) {
      item.taxName = json.tax.name;
      item.taxRate = (0, _InvoiceBigNumber.IBN)(json.tax.percent, _InvoiceConstants2.default.taxRateDecimalPrecision());
    }
    if (json.discount) {
      if (json.discount.amount) {
        item.discountAmount = (0, _InvoiceBigNumber.$$)(json.discount.amount.value);
      }
      if (json.discount.percent) {
        item.discountPercentage = (0, _InvoiceBigNumber.IBN)(json.discount.percent, _InvoiceConstants2.default.discountPercentageDecimalPrecision());
      }
    }
    if (json.date) {
      item.date = _InvoicingUtil2.default.parseServerDateString(json.date);
    }

    item.imageURL = json.image_url;
    item.unitOfMeasure = json.unit_of_measure;

    return item;
  };

  InvoiceItem.prototype.toJSON = function toJSON(currency) {
    var json = {
      name: this.name,
      description: this.itemDescription,
      quantity: this.quantity.toNumber(),
      image_url: this.imageURL,
      unit_of_measure: this.unitOfMeasure
    };
    if (this.date) {
      json.date = _InvoicingUtil2.default.toServerDateString(this.date, false);
    }
    json.unit_price = {
      value: _Currency2.default.serverRound(currency, this.unitPrice),
      currency: currency
    };
    var tempDiscount = {};
    if (this.discountPercentage > 0) {
      tempDiscount.percent = this.discountPercentage;
    } else if (this.discountAmount > 0) {
      tempDiscount.amount = {
        value: _Currency2.default.serverRound(currency, this.discountAmount),
        currency: currency
      };
    }
    if (tempDiscount.amount || tempDiscount.percent) {
      json.discount = tempDiscount;
    }

    if (this.taxRate && this.taxName) {
      json.tax = {
        percent: this.taxRate,
        name: this.taxName
      };
    }
    return json;
  };

  /**
   * check if an item is equal to this
   * @param {InvoiceItem} item to which this one will be compared
   * @returns {bool} are they equal
   */


  InvoiceItem.prototype.isEqualToItem = function isEqualToItem(item) {
    return (0, _deepEqual2.default)((0, _manticoreUtil.deepToJSON)(this), (0, _manticoreUtil.deepToJSON)(item));
  };

  _createClass(InvoiceItem, [{
    key: 'quantity',
    get: function get() {
      return this._quantity;
    },
    set: function set(v) {
      this._quantity = (0, _InvoiceBigNumber.IBN)(v, _InvoiceConstants2.default.itemQuantityDecimalPrecision());
      this._emitPriceMayHaveChanged('quantity');
    }
  }, {
    key: 'taxRate',
    get: function get() {
      return this._taxRate;
    },
    set: function set(v) {
      this._taxRate = (0, _InvoiceBigNumber.IBN)(v, _InvoiceConstants2.default.taxRateDecimalPrecision());
      this._emitPriceMayHaveChanged('taxRate');
    }
  }, {
    key: 'discountAmount',
    get: function get() {
      return this._discountAmount;
    },
    set: function set(v) {
      this._discountAmount = (0, _InvoiceBigNumber.$$)(v);
      this._emitPriceMayHaveChanged('discountAmount');
    }
  }, {
    key: 'discountPercentage',
    get: function get() {
      return this._discountPercentage;
    },
    set: function set(v) {
      this._discountPercentage = (0, _InvoiceBigNumber.IBN)(v, _InvoiceConstants2.default.discountPercentageDecimalPrecision());
      this._emitPriceMayHaveChanged('discountPercentage');
    }
  }, {
    key: 'unitPrice',
    get: function get() {
      return this._unitPrice;
    },
    set: function set(v) {
      this._unitPrice = (0, _InvoiceBigNumber.$$)(v);
      this._emitPriceMayHaveChanged('unitPrice');
    }
  }, {
    key: 'date',
    set: function set(date) {
      this._date = date;
    },
    get: function get() {
      return _InvoicingUtil2.default.getDateValue(this._date);
    }
  }]);

  return InvoiceItem;
}(_events.EventEmitter);

exports.default = InvoiceItem;


InvoiceItem.event = {
  priceMayHaveChanged: 'PriceMayHaveChanged'
};
},{"./Currency":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/Currency.js","./InvoiceBigNumber":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/InvoiceBigNumber.js","./InvoiceConstants":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/InvoiceConstants.js","./InvoicingUtil":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/InvoicingUtil.js","deep-equal":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/deep-equal/index.js","events":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/events/events.js","manticore-util":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-util/build/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/MerchantInfo.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

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; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

var _Address = require('./Address');

var _Address2 = _interopRequireDefault(_Address);

var _manticoreLog = require('manticore-log');

var _manticoreLog2 = _interopRequireDefault(_manticoreLog);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

var Log = (0, _manticoreLog2.default)('invoicing');

/**
 * Container for information about the merchant requesting payment on an invoice
 * @class
 * @property {string} email The email address of the
 *  merchant @required @length(1,260) @format(email)
 * @property {string} firstName The first name of the merchant @length(,30)
 * @property {string} lastName The last name of the merchant @length(,30)
 * @property {InvoiceAddress} address The address of the merchant
 * @property {string} businessName The business name of the merchant
 * @property {string} phone The phone number of the merchant
 * @property {string} fax The fax number of the merchant
 * @property {string} website The URL of the merchant website @format{url}
 * @property {string} taxId The tax identifier for the merchant
 * @property {string} additionalInfoLabel Option to provide a label to the
 *  additional_info field. 40 characters max.
 * @property {string} additionalInfo Option to display additional information
 *  such as business hours. 40 characters max.
 */

var InvoiceMerchantInfo = function () {
  function InvoiceMerchantInfo() {
    _classCallCheck(this, InvoiceMerchantInfo);

    this.address = new _Address2.default();
  }

  InvoiceMerchantInfo.prototype.readFromJson = function readFromJson(json) {
    if (json) {
      this.address.readFromJson(json.address);

      if (json.address) {
        this.address = new _Address2.default();
        this.address.readFromJson(json.address);
      }
      this.email = json.email;
      this.phoneDictionary = json.phone || {};
      this.fax = json.fax;
      this.website = json.website;
      this.firstName = json.first_name;
      this.lastName = json.last_name;
      this.businessName = json.business_name;
      this.taxId = json.tax_id;
      this.additionalInfo = json.additional_info;
      this.additionalInfoLabel = json.additional_info_label;
    }
  };

  InvoiceMerchantInfo.prototype.toJSON = function toJSON() {
    var r = {};
    r.email = this.email;

    if (this.phoneDictionary && this.phoneDictionary.hasOwnProperty("national_number")) {
      if (!this.phoneDictionary.hasOwnProperty("country_code")) {
        this.phoneDictionary.country_code = " ";
      }

      r.phone = this.phoneDictionary;
    }

    r.website = this.website;
    r.address = this.address;
    r.first_name = this.firstName;
    r.last_name = this.lastName;
    r.business_name = this.businessName;
    r.tax_id = this.taxId;
    r.additional_info = this.additionalInfo;
    r.additional_info_label = this.additionalInfoLabel;
    return r;
  };

  _createClass(InvoiceMerchantInfo, [{
    key: 'phone',
    get: function get() {
      return this.phoneDictionary.national_number;
    },
    set: function set(phone) {
      this.phoneDictionary.national_number = phone;
    }
  }]);

  return InvoiceMerchantInfo;
}();

exports.default = InvoiceMerchantInfo;
},{"./Address":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/Address.js","manticore-log":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-log/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/Notification.js":[function(require,module,exports){
"use strict";

exports.__esModule = true;

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

/**
 * An Invoice notification
 * @class
 * @property {string} subject Subject of the notification
 * @property {string} note Note to the payer
 * @property {bool} shouldSendToMerchant A flag indicating whether a copy of the
 *  email has to be sent to the merchant
 * @property {bool} shouldSendToPayer A flag indicating whether a copy of the email
 *  has to be sent to the payer
 * @property {string} ccEmails If the invoice has CCs associated with it, this field
 *  can be used to specify only certain set of CC emails for which notification is sent.
 *
 */
var InvoiceNotification = function () {
  function InvoiceNotification(subject, note, shouldSendToMerchant, ccEmails, shouldSendToPayer) {
    _classCallCheck(this, InvoiceNotification);

    this.subject = subject;
    this.note = note;
    this.shouldSendToMerchant = shouldSendToMerchant;
    this.shouldSendToPayer = shouldSendToPayer;
    this.ccEmails = ccEmails;
  }

  InvoiceNotification.prototype.toJSON = function toJSON() {
    var json = {};
    json.subject = this.subject;
    json.note = this.note;
    json.send_to_merchant = this.shouldSendToMerchant;
    json.send_to_payer = this.shouldSendToPayer;
    json.cc_emails = this.ccEmails;
    return json;
  };

  return InvoiceNotification;
}();

exports.default = InvoiceNotification;
},{}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/Payment.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

var _assert = require('assert');

var _assert2 = _interopRequireDefault(_assert);

var _InvoiceEnums = require('./InvoiceEnums');

var _InvoiceEnums2 = _interopRequireDefault(_InvoiceEnums);

var _InvoicingUtil = require('./InvoicingUtil');

var _InvoicingUtil2 = _interopRequireDefault(_InvoicingUtil);

var _InvoiceBigNumber = require('./InvoiceBigNumber');

var _Currency = require('./Currency');

var _Currency2 = _interopRequireDefault(_Currency);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

/**
 * Container for information about the payment on an invoice
 * @class
 * @property {Invoice.PaymentType} type PayPal payment detail indicating whether
 *  payment was made in an invoicing flow via PayPal or externally. @readonly
 * @property {string} transactionID PayPal payment transaction id. Mandatory
 *  field in case the type value is PAYPAL. @readonly
 * @property {string} transactionType type of the transaction @readonly
 * @property {Date} date date when the invoice was paid
 * @property {string} formattedDate date, formatted in MMM, D YYYY format
 * @property {Invoice.PaymentMethod} method payment mode or method this is mandatory
 * @property {string} note optional note associated with the payment
 * @property {decimal} amount this is an amount object on the server which
 *  has a string for currency, and value
 * @property {string} currency used with the amount
 **/
var InvoicePayment = function () {
  function InvoicePayment() {
    _classCallCheck(this, InvoicePayment);

    this.type = _InvoiceEnums2.default.PaymentType.EXTERNAL;
    this.transactionId = undefined;
    this.transactionType = undefined;
    this.date = undefined;
    this.formattedDate = undefined;
    this.note = undefined;
    this.method = undefined;
    this.currency = undefined;
    this.amount = undefined;
  }

  InvoicePayment.readFromJson = function readFromJson(json) {
    var payment = new InvoicePayment();

    if (json) {
      payment.type = _InvoicingUtil2.default.parseInvoicePaymentType(json.type);
      payment.transactionID = json.transaction_id;
      payment.transactionType = json.transaction_type;
      payment.date = _InvoicingUtil2.default.parseServerDateString(json.date);
      payment.formattedDate = payment.date ? payment.date.format('MMM D, YYYY') : undefined;
      payment.method = _InvoicingUtil2.default.parseInvoicePaymentMethod(json.method);
      payment.note = json.note;
    }

    if (json.amount) {
      payment.amount = (0, _InvoiceBigNumber.$$)(json.amount.value);
      payment.currency = json.amount.currency;
    }

    return payment;
  };

  InvoicePayment.prototype.toJSON = function toJSON() {
    var r = {};

    if (this.amount) {
      r.amount = {};
      r.amount = {
        currency: this.currency,
        value: _Currency2.default.serverRound(this.currency, this.amount)
      };
    }

    r.method = _InvoiceEnums2.default.PaymentMethod.toString[this.method];
    r.date = _InvoicingUtil2.default.toServerDateString(this.date, true);
    r.formattedDate = this.formattedDate;
    r.note = this.note;

    return r;
  };

  // Assert if we know the server is going to reject this as the body of record-payment.


  InvoicePayment.prototype.validate = function validate() {
    if (!this.type) {
      (0, _assert2.default)(false, 'InvoicePaymentInfo must have a payment type.');
    }
    switch (this.type) {
      case _InvoiceEnums2.default.PaymentType.EXTERNAL:
        (0, _assert2.default)(this.method, 'InvoicePaymentInfo with payment type=EXTERNAL must have a method.');
        break;
      case _InvoiceEnums2.default.PaymentType.PAYPAL:
        (0, _assert2.default)(this.transactionId, 'InvoicePaymentInfo with payment type=PAYPAL must have a method.');
        throw new Error('The invoicing service doesn\'t currently support setting the payment type to PAYPAL :(.');
      default:
        throw new Error('Unknown payment type');
    }
  };

  return InvoicePayment;
}();

exports.default = InvoicePayment;
},{"./Currency":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/Currency.js","./InvoiceBigNumber":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/InvoiceBigNumber.js","./InvoiceEnums":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/InvoiceEnums.js","./InvoicingUtil":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/InvoicingUtil.js","assert":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/assert/assert.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/PaymentTerm.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

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; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

var _manticoreUtil = require('manticore-util');

var _InvoicingUtil = require('./InvoicingUtil');

var _InvoicingUtil2 = _interopRequireDefault(_InvoicingUtil);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

/**
 * Contains information about the due date / payment terms of an invoice.
 * @class
 * @property {InvoicePaymentTerm.PaymentTerms} paymentTerms Describes when
 *  payment is expected on the invoice. Setting this to something truthy will clear dueDate.
 * @property {string} dueDate A specific date on which payment is due. Setting this
 *  to something truthy will clear paymentTerms.
 * @property {int} daysForTerm the number of days from the invoice start date
 * that this term is valid for
 **/
var InvoicePaymentTerm = function () {
  function InvoicePaymentTerm() {
    _classCallCheck(this, InvoicePaymentTerm);

    this.reset();
  }

  InvoicePaymentTerm.prototype.reset = function reset() {
    this._paymentTerms = InvoicePaymentTerm.PaymentTerms.NoPaymentTerms;
    this._dueDate = undefined;
  };

  InvoicePaymentTerm.fromJson = function fromJson(json) {
    var r = new InvoicePaymentTerm();
    if (json) {
      // Sometimes the server will send us a term_type AND a due_date. In this case, the due
      // date is just bogus, so setting the paymentTerms second here will override it.
      r.dueDate = json.due_date;
      r.paymentTerms = InvoicePaymentTerm.PaymentTerms.fromServer[json.term_type];
    } else {
      r.reset();
    }
    return r;
  };

  InvoicePaymentTerm.prototype.toJSON = function toJSON() {
    var r = {};

    if (this.dueDate) {
      r.due_date = this.dueDate;
    } else if (this.paymentTerms) {
      r.term_type = InvoicePaymentTerm.PaymentTerms.toServer[this.paymentTerms];
    }

    return r;
  };

  // There is a bug on the server where an invoice with the same invoice_date and due_date
  // will fail to validate. So, if those dates would be the same, use DUE_ON_RECEIPT instead.
  // TODO: stop this once the server is fixed.


  InvoicePaymentTerm.prototype.toJSONHack = function toJSONHack(invoiceDateString) {
    var r = this.toJSON();
    if (r.due_date !== undefined && r.due_date === invoiceDateString) {
      r.due_date = undefined;
      var dor = InvoicePaymentTerm.PaymentTerms.DueOnReceipt;
      r.term_type = InvoicePaymentTerm.PaymentTerms.toServer[dor];
    }

    return r;
  };

  _createClass(InvoicePaymentTerm, [{
    key: 'paymentTerms',
    set: function set(t) {
      if (t || t === InvoicePaymentTerm.PaymentTerms.NoPaymentTerms) {
        this.reset();
      }
      this._paymentTerms = t;
    },
    get: function get() {
      return this._paymentTerms;
    }
  }, {
    key: 'dueDate',
    set: function set(d) {
      if (d) {
        this.reset();
      }
      this._dueDate = d;
    },
    get: function get() {
      return this._dueDate;
    }
  }, {
    key: 'daysForTerm',
    get: function get() {
      switch (this._paymentTerms) {
        case (InvoicePaymentTerm.PaymentTerms.NoPaymentTerms, InvoicePaymentTerm.PaymentTerms.DueOnReceipt):
          return 0;
        case InvoicePaymentTerm.PaymentTerms.Net10:
          return 10;
        case InvoicePaymentTerm.PaymentTerms.Net15:
          return 15;
        case InvoicePaymentTerm.PaymentTerms.Net30:
          return 30;
        case InvoicePaymentTerm.PaymentTerms.Net45:
          return 45;
        case InvoicePaymentTerm.PaymentTerms.Net60:
          return 60;
        case InvoicePaymentTerm.PaymentTerms.Net90:
          return 90;
      }
      return 0;
    }
  }]);

  return InvoicePaymentTerm;
}();

/**
 * A payment term describes when payment is expected in relation to the date it is sent
 * @enum {int}
 */


exports.default = InvoicePaymentTerm;
InvoicePaymentTerm.PaymentTerms = {
  /**
   * The due date does not come from payment terms
   */
  NoPaymentTerms: 0,
  /**
   * The invoice is due immediately upon receipt of the invoice
   */
  DueOnReceipt: 1,
  /**
   * The payment is due 10 days after receipt of the invoice
   */
  Net10: 2,
  /**
   * The payment is due 15 days after receipt of the invoice
   */
  Net15: 3,
  /**
   * The payment is due 30 days after receipt of the invoice
   */
  Net30: 4,
  /**
   * The payment is due 45 days after receipt of the invoice
   */
  Net45: 5,
  /**
   * The payment is due 60 days after receipt of the invoice
   */
  Net60: 6,
  /**
   * The payment is due 90 days after receipt of the invoice
   */
  Net90: 7
};

InvoicePaymentTerm.PaymentTerms.fromServer = {
  DUE_ON_RECEIPT: InvoicePaymentTerm.PaymentTerms.DueOnReceipt,
  NET_10: InvoicePaymentTerm.PaymentTerms.Net10,
  NET_15: InvoicePaymentTerm.PaymentTerms.Net15,
  NET_30: InvoicePaymentTerm.PaymentTerms.Net30,
  NET_45: InvoicePaymentTerm.PaymentTerms.Net45,
  NET_60: InvoicePaymentTerm.PaymentTerms.Net60,
  NET_90: InvoicePaymentTerm.PaymentTerms.Net90
};

InvoicePaymentTerm.PaymentTerms.toServer = (0, _manticoreUtil.reverseKeysAndValues)(InvoicePaymentTerm.PaymentTerms.fromServer);
},{"./InvoicingUtil":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/InvoicingUtil.js","manticore-util":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-util/build/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/Refund.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

var _InvoiceBigNumber = require('./InvoiceBigNumber');

var _InvoiceEnums = require('./InvoiceEnums');

var _InvoiceEnums2 = _interopRequireDefault(_InvoiceEnums);

var _InvoicingUtil = require('./InvoicingUtil');

var _InvoicingUtil2 = _interopRequireDefault(_InvoicingUtil);

var _Currency = require('./Currency');

var _Currency2 = _interopRequireDefault(_Currency);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

/**
 * Container for information about a refund on an invoice
 * @class
 * @property {string} type PayPal refund type indicating whether refund was
 *  done in invoicing flow via PayPal or externally. @readonly
 * @property {Date} date date when the invoice was paid
 * @property {string} note optional note associated with the payment
 * @property {decimal} amount this is an amount object on the server which
 *  has a string for currency, and value
 * @property {string} currency used with the amount
 * @property {string} transactionID PayPal refund transaction id. Mandatory
 *  field in case the type value is PAYPAL. @readonly
 **/
var InvoiceRefund = function () {
  function InvoiceRefund() {
    _classCallCheck(this, InvoiceRefund);

    // Default payment type to EXTERNAL since it's the only one the server actually
    // supports right now.
    this.type = _InvoiceEnums2.default.PaymentType.EXTERNAL;
    this.date = undefined;
    this.note = undefined;
    this.currency = undefined;
    this.amount = undefined;
    this.transactionID = undefined;
  }

  InvoiceRefund.readFromJson = function readFromJson(json) {
    var refund = new InvoiceRefund();

    if (json) {
      refund.type = json.type;
      refund.date = _InvoicingUtil2.default.parseServerDateString(json.date);
      refund.note = json.note;
      refund.transactionID = json.transaction_id;
    }
    if (json.amount) {
      refund.amount = (0, _InvoiceBigNumber.$$)(json.amount.value);
      refund.currency = json.amount.currency;
    }

    return refund;
  };

  InvoiceRefund.prototype.toJSON = function toJSON() {
    var r = {};
    if (this.amount) {
      r.amount = {};
      r.amount = {
        currency: this.currency,
        value: _Currency2.default.serverRound(this.currency, this.amount)
      };
    }

    r.date = _InvoicingUtil2.default.toServerDateString(this.date, true);
    r.note = this.note;

    return r;
  };

  return InvoiceRefund;
}();

exports.default = InvoiceRefund;
},{"./Currency":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/Currency.js","./InvoiceBigNumber":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/InvoiceBigNumber.js","./InvoiceEnums":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/InvoiceEnums.js","./InvoicingUtil":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/InvoicingUtil.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/Requester.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;
exports.request = request;

var _manticoreUtil = require('manticore-util');

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } // The main purpose of this file is to avoid a circular dependency between
// Invoice and InvoicingService, since Invoice needs to make requests and
// the service needs to construct Invoices based on server responses.


var InvoicingRequester = function () {
  function InvoicingRequester() {
    _classCallCheck(this, InvoicingRequester);
  }

  InvoicingRequester.request = function request(opts, cb) {
    if (!InvoicingRequester.api) {
      throw new Error('There is no service interface. Please set the InvoicingRequester.api property.');
    }

    InvoicingRequester.api.request((0, _manticoreUtil.extend)(opts, {
      service: 'invoicing',
      format: 'json',
      headers: { 'Content-Type': 'application/json' }
    }), function (err, response) {
      // this is copied directly paypal-business-app/lib/ServiceInterface.js
      // b/c of the fantastic architecture of manticore and trying to be too smart w/errors
      if (err && !(err instanceof Error)) {
        var error = new Error(err.body.message);
        error.code = err.body.name;
        // Sometimes errors from invoicing just don't have a debugId in the body. Oh well.
        error.debugId = err.body.debug_id || err.debug_id;
        if (err.body.details) {
          error.details = err.body.details;
        }
        error.status = err.body.status;
        cb(error, response);
      } else {
        cb(err, response);
      }
    });
  };

  return InvoicingRequester;
}();

exports.default = InvoicingRequester;
function request(opts, cb) {
  return InvoicingRequester.request(opts, cb);
}
},{"manticore-util":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-util/build/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/RoundingRules.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;
exports.default = {
  'SHP': 2,
  'EUR': 2,
  'AED': 2,
  'AFN': 0,
  'XCD': 2,
  'ALL': 0,
  'AMD': 0,
  'AOA': 2,
  'ARS': 2,
  'USD': 2,
  'AUD': 2,
  'AWG': 2,
  'AZN': 2,
  'BAM': 2,
  'BBD': 2,
  'BDT': 2,
  'XOF': 0,
  'BGN': 2,
  'BHD': 3,
  'BIF': 0,
  'BMD': 2,
  'BND': 2,
  'BOB': 2,
  'BRL': 2,
  'BSD': 2,
  'INR': 2,
  'BTN': 2,
  'NOK': 2,
  'BWP': 2,
  'BYR': 0,
  'BZD': 2,
  'CAD': 2,
  'CDF': 2,
  'XAF': 0,
  'CHF': 2,
  'NZD': 2,
  'CLP': 0,
  'CNY': 2,
  'COP': 0,
  'CRC': 0,
  'CUP': 2,
  'CUC': 2,
  'CVE': 2,
  'ANG': 2,
  'CZK': 0,
  'DJF': 0,
  'DKK': 2,
  'DOP': 2,
  'DZD': 2,
  'EGP': 2,
  'MAD': 2,
  'ERN': 2,
  'ETB': 2,
  'FJD': 2,
  'FKP': 2,
  'GBP': 2,
  'GEL': 2,
  'GHS': 2,
  'GIP': 2,
  'GMD': 2,
  'GNF': 0,
  'GTQ': 2,
  'GYD': 0,
  'HKD': 2,
  'HNL': 2,
  'HRK': 2,
  'HTG': 2,
  'HUF': 0,
  'IDR': 0,
  'ILS': 2,
  'IQD': 0,
  'IRR': 0,
  'ISK': 0,
  'JMD': 2,
  'JOD': 3,
  'JPY': 0,
  'KES': 2,
  'KGS': 2,
  'KHR': 2,
  'KMF': 0,
  'KPW': 0,
  'KRW': 0,
  'KWD': 3,
  'KYD': 2,
  'KZT': 2,
  'LAK': 0,
  'LBP': 0,
  'LKR': 2,
  'LRD': 2,
  'ZAR': 2,
  'LSL': 2,
  'LYD': 3,
  'MDL': 2,
  'MGA': 0,
  'MKD': 2,
  'MMK': 0,
  'MNT': 0,
  'MOP': 2,
  'MRO': 0,
  'MUR': 0,
  'MVR': 2,
  'MWK': 2,
  'MXN': 2,
  'MYR': 2,
  'MZN': 2,
  'NAD': 2,
  'XPF': 0,
  'NGN': 2,
  'NIO': 2,
  'NPR': 2,
  'OMR': 3,
  'PAB': 2,
  'PEN': 2,
  'PGK': 2,
  'PHP': 2,
  'PKR': 0,
  'PLN': 2,
  'PYG': 0,
  'QAR': 2,
  'RON': 2,
  'RSD': 0,
  'RUB': 2,
  'RWF': 0,
  'SAR': 2,
  'SBD': 2,
  'SCR': 2,
  'SDG': 2,
  'SEK': 2,
  'SGD': 2,
  'SLL': 0,
  'SOS': 0,
  'SRD': 2,
  'SSP': 2,
  'STD': 0,
  'SYP': 0,
  'SZL': 2,
  'THB': 2,
  'TJS': 2,
  'TMT': 2,
  'TND': 3,
  'TOP': 2,
  'TRY': 2,
  'TTD': 2,
  'TWD': 0,
  'TZS': 0,
  'UAH': 2,
  'UGX': 0,
  'UYU': 2,
  'UZS': 0,
  'VEF': 2,
  'VND': 0,
  'VUV': 0,
  'WST': 2,
  'YER': 0,
  'ZMW': 2
};
},{}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/SearchRequest.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

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; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

var _InvoiceEnums = require('./InvoiceEnums');

var _InvoiceEnums2 = _interopRequireDefault(_InvoiceEnums);

var _InvoicingUtil = require('./InvoicingUtil');

var _InvoicingUtil2 = _interopRequireDefault(_InvoicingUtil);

var _InvoiceBigNumber = require('./InvoiceBigNumber');

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

/**
 * @class
 * @property {string} email Initial letters of the email address.
 * @property {string} recipientFirstName Initial letters of the recipient's first name.
 * @property {string} recipientLastName Initial letters of the recipient's last name.
 * @property {string} recipientBusinessName Initial letters of the recipient's business name.
 * @property {string} number The invoice number that appears on the invoice.
 * @property {decimal} lowerTotalAmount Base object for all financial value
 *  related fields (balance, payment due, etc.)
 * @property {decimal} upperTotalAmount Base object for all financial value
 *  related fields (balance, payment due, etc.)
 * @property {Date} startInvoiceDate Start invoice date.
 *  Date format yyyy-MM-dd z, as defined in ISO8601.
 * @property {Date} endInvoiceDate End invoice date.
 *  Date format yyyy-MM-dd z, as defined in ISO8601.
 * @property {Date} startDueDate Start invoice due date.
 *  Date format yyyy-MM-dd z, as defined in ISO8601.
 * @property {Date} endDueDate End invoice due date.
 *  Date format yyyy-MM-dd z, as defined in ISO8601.
 * @property {Date} startPaymentDate Start invoice payment date.
 *  Date format yyyy-MM-dd z, as defined in ISO8601.
 * @property {Date} endPaymentDate End invoice payment date.
 *  Date format yyyy-MM-dd z, as defined in ISO8601.
 * @property {Date} startCreationDate Start invoice creation date.
 *  Date format yyyy-MM-dd z, as defined in ISO8601.
 * @property {Date} endCreationDate End invoice creation date.
 *  Date format yyyy-MM-dd z, as defined in ISO8601.
 * @property {int} startIndex A zero-relative index of the merchant's list of invoices
 * @property {int} pageSize Page size of the search results.
 * @property {bool} totalCountRequired A flag indicating whether total
 *  count is required in the response.
 * @property {bool} archived A flag indicating whether search is on invoices archived by
 *  merchant. true - returns archived / false returns unarchived / null returns all.
 */
var InvoiceSearchRequest = function () {
  function InvoiceSearchRequest() {
    _classCallCheck(this, InvoiceSearchRequest);

    this.startIndex = 0;
    this.pageSize = 20;
    this.totalCountRequired = false;
    this._statuses = [];
  }

  InvoiceSearchRequest.prototype.toJSON = function toJSON() {
    var json = {};
    this.assignDatesToJSON(json);

    json.email = this.email;
    json.recipientFirstName = this.recipientFirstName;
    json.recipientLastName = this.recipientLastName;
    json.recipientBusinessName = this.recipientBusinessName;
    json.number = this.number;
    for (var _iterator = this._statuses, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
      var _ref;

      if (_isArray) {
        if (_i >= _iterator.length) break;
        _ref = _iterator[_i++];
      } else {
        _i = _iterator.next();
        if (_i.done) break;
        _ref = _i.value;
      }

      var status = _ref;

      if (!json.status) {
        json.status = [];
      }
      json.status.push(_InvoiceEnums2.default.Status.toString[status]);
    }
    json.lower_total_amount = this.lowerTotalAmount;
    json.upper_total_amount = this.upperTotalAmount;
    json.page = this.startIndex;
    json.page_size = this.pageSize;
    json.total_count_required = this.totalCountRequired;
    json.archived = this.archived;
    return json;
  };

  /**
   * Manticore doesn't support properties that are arrays of enum values, and it's complicated.
   * So instead of a property for the status array, we have this method.
   * @param {Invoice.Status} status
   */


  InvoiceSearchRequest.prototype.addStatus = function addStatus(status) {
    this._statuses.push(status);
  };

  // If you send a startXDate, the server requires you to send an endXDate.
  // The server also only accepts certain time ranges (e.g. after 1970), so
  // this method automatically sets the most-lenient available date if you're
  // missing one of a pair.


  InvoiceSearchRequest.prototype.assignDatesToJSON = function assignDatesToJSON(json) {
    var datePairs = [['startInvoiceDate', 'endInvoiceDate', 'start_invoice_date', 'end_invoice_date'], ['startDueDate', 'endDueDate', 'start_due_date', 'end_due_date'], ['startPaymentDate', 'endPaymentDate', 'start_payment_date', 'end_payment_date'], ['startCreationDate', 'endCreationDate', 'start_creation_date', 'end_creation_date']];
    for (var _iterator2 = datePairs, _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) {
      var _ref2;

      if (_isArray2) {
        if (_i2 >= _iterator2.length) break;
        _ref2 = _iterator2[_i2++];
      } else {
        _i2 = _iterator2.next();
        if (_i2.done) break;
        _ref2 = _i2.value;
      }

      var p = _ref2;

      if (this[p[0]] || this[p[1]]) {
        json[p[2]] = this[p[0]] ? _InvoicingUtil2.default.toServerDateString(this[p[0]], false) : '1970-01-01 PST';
        json[p[3]] = this[p[1]] ? _InvoicingUtil2.default.toServerDateString(this[p[1]], false) : '2100-01-01 PST';
      }
    }
  };

  _createClass(InvoiceSearchRequest, [{
    key: 'lowerTotalAmount',
    get: function get() {
      return this._lowerTotalAmount;
    },
    set: function set(val) {
      this._lowerTotalAmount = (0, _InvoiceBigNumber.$$)(val);
    }
  }, {
    key: 'upperTotalAmount',
    get: function get() {
      return this._upperTotalAmount;
    },
    set: function set(val) {
      this._upperTotalAmount = (0, _InvoiceBigNumber.$$)(val);
    }
  }]);

  return InvoiceSearchRequest;
}();

exports.default = InvoiceSearchRequest;
},{"./InvoiceBigNumber":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/InvoiceBigNumber.js","./InvoiceEnums":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/InvoiceEnums.js","./InvoicingUtil":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/InvoicingUtil.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/ShippingInfo.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

var _Address = require('./Address');

var _Address2 = _interopRequireDefault(_Address);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

/**
 * Container for information about the merchant requesting payment on an invoice
 * @class
 * @property {string} email The email address of the
 *  merchant @required @length(1,260) @format(email)
 * @property {string} firstName The first name of the merchant @length(,30)
 * @property {string} lastName The last name of the merchant @length(,30)
 * @property {InvoiceAddress} address The address of the merchant
 * @property {string} businessName The business name of the merchant
 */
var InvoiceShippingInfo = function () {
  function InvoiceShippingInfo() {
    _classCallCheck(this, InvoiceShippingInfo);

    this.address = new _Address2.default();
  }

  InvoiceShippingInfo.prototype.readFromJson = function readFromJson(json) {
    if (json) {
      this.address.readFromJson(json.address);
      this.email = json.email;
      this.firstName = json.first_name;
      this.lastName = json.last_name;
      this.businessName = json.business_name;
    }
  };

  InvoiceShippingInfo.prototype.toJSON = function toJSON() {
    var r = {};
    // If the address is empty, don't include it in the JSON.
    if (Object.keys(this.address).length) {
      r.address = this.address;
    }
    r.email = this.email;
    r.first_name = this.firstName;
    r.last_name = this.lastName;
    r.business_name = this.businessName;

    return r;
  };

  /**
   * Check to see if this object has any value
   * @returns {bool}
   */


  InvoiceShippingInfo.prototype.hasAnyValue = function hasAnyValue() {
    if (this.email || this.firstName || this.lastName || this.businessName || this.address.hasAnyValue()) {
      return true;
    }
    return false;
  };

  return InvoiceShippingInfo;
}();

exports.default = InvoiceShippingInfo;
},{"./Address":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/Address.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/Template.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

var _Invoice2 = require('./Invoice');

var _Invoice3 = _interopRequireDefault(_Invoice2);

var _TemplateSettings = require('./TemplateSettings');

var _TemplateSettings2 = _interopRequireDefault(_TemplateSettings);

var _PaymentTerm = require('./PaymentTerm.js');

var _PaymentTerm2 = _interopRequireDefault(_PaymentTerm);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (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 } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

/**
 * Invoice template
 * @class
 * @extends Invoice
 * @property {bool} isDefault true if this is the default template
 * @property {bool} isCustom true if this is a custom template
 * @property {string} name name of the template
 * @property {string} unitOfMeasure unit of measure for the template,
 *  known values: AMOUNT, QUANTITY, HOURS
 * @property {InvoiceTemplateSettings} settings list of which fields are enabled/disabled
 */
var InvoiceTemplate = function (_Invoice) {
  _inherits(InvoiceTemplate, _Invoice);

  /**
   * Create a new blank invoice template.
   * @constructor
   * @param {string} currencyCode currency code identifying the currency for amounts on this invoice
   */
  function InvoiceTemplate(currencyCode) {
    _classCallCheck(this, InvoiceTemplate);

    return _possibleConstructorReturn(this, _Invoice.call(this, currencyCode));
  }

  InvoiceTemplate.fromJSON = function fromJSON(json) {
    if (json.template_data && json.template_data.currencyCode) {
      var t = new InvoiceTemplate(json.template_data.currencyCode);
      t.readJSON(json.template_data, true);
      t.templateID = json.template_id;
      t.isDefault = json.default;
      t.isCustom = json.custom;
      t.name = json.name;
      t.unitOfMeasure = json.unit_of_measure;
      t.settings = _TemplateSettings2.default.fromJSON(json.settings);

      if (!t.isCustom) {
        t.paymentTerms = new _PaymentTerm2.default();
        t.paymentTerms.paymentTerms = _PaymentTerm2.default.PaymentTerms.DueOnReceipt;
        t.paymentTerms.dueDate = null;
      }
      return t;
    }
    return undefined;
  };

  /**
   * Return an invoice with all the fields from the template but the invoice
   * number and paypalID of another invoice
   * @param {Invoice} invoice whose paypalID and number going to be copied
   * @returns {Invoice} the new version of the invoice
   */


  InvoiceTemplate.prototype.invoiceFromInvoice = function invoiceFromInvoice(invoice) {
    var i = this.duplicate();

    // clear all the template specific fields
    i.isDefault = undefined;
    i.isCustom = undefined;
    i.name = undefined;
    i.unitOfMeasure = undefined;
    i.settings = undefined;

    i.number = invoice.number;
    i.payPalId = invoice.payPalId;
    return i;
  };

  // Given an array of InvoiceTemplate objects, return an array of the objects sorted by name


  InvoiceTemplate.sortTemplates = function sortTemplates(templates) {
    var r = templates;
    r.sort(function (a, b) {
      return a.name.localeCompare(b.name);
    });
    return r;
  };

  return InvoiceTemplate;
}(_Invoice3.default);

exports.default = InvoiceTemplate;
},{"./Invoice":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/Invoice.js","./PaymentTerm.js":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/PaymentTerm.js","./TemplateSettings":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/TemplateSettings.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/build/lib/TemplateSettings.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

var _assert = require('assert');

var _assert2 = _interopRequireDefault(_assert);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

/**
 * Invoice template settings
 * @class
 * @property {bool} shipping true if shipping is displayed
 * @property {bool} discount true if discount is displayed
 * @property {bool} custom true if custom is displayed
 * @property {bool} itemsDiscount true if itemsDiscount is displayed
 * @property {bool} itemsTax true if itemsTax is displayed
 * @property {bool} itemsQuantity true if itemsQuantity is displayed
 * @property {bool} itemsDescription true if itemsDescription is displayed
 * @property {bool} itemsDate true if itemsDate is displayed
 */
var InvoiceTemplateSettings = function () {
  function InvoiceTemplateSettings() {
    _classCallCheck(this, InvoiceTemplateSettings);

    this.shipping = true;
    this.discount = true;
    this.custom = true;
    this.itemsDiscount = true;
    this.itemsTax = true;
    this.itemsQuantity = true;
    this.itemsDescription = true;
    this.itemsDate = true;
  }

  InvoiceTemplateSettings.fromJSON = function fromJSON(json) {
    var s = new InvoiceTemplateSettings();

    for (var _iterator = json, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
      var _ref;

      if (_isArray) {
        if (_i >= _iterator.length) break;
        _ref = _iterator[_i++];
      } else {
        _i = _iterator.next();
        if (_i.done) break;
        _ref = _i.value;
      }

      var f = _ref;

      switch (f.field_name) {
        case 'shipping':
          s.shipping = s.isFieldShown(f);
          break;
        case 'discount':
          s.discount = s.isFieldShown(f);
          break;
        case 'custom':
          s.custom = s.isFieldShown(f);
          break;
        case 'items.discount':
          s.itemsDiscount = s.isFieldShown(f);
          break;
        case 'items.tax':
          s.itemsTax = s.isFieldShown(f);
          break;
        case 'items.quantity':
          s.itemsQuantity = s.isFieldShown(f);
          break;
        case 'items.description':
          s.itemsDescription = s.isFieldShown(f);
          break;
        case 'items.date':
          s.itemsDate = s.isFieldShown(f);
          break;
        default:
          (0, _assert2.default)('unknown field name: ' + f.field_name);
      }
    }
    return s;
  };

  InvoiceTemplateSettings.prototype.isFieldShown = function isFieldShown(field) {
    return field.display_preference.hidden !== true;
  };

  return InvoiceTemplateSettings;
}();

exports.default = InvoiceTemplateSettings;
},{"assert":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/assert/assert.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypal-invoicing/node_modules/moment/moment.js":[function(require,module,exports){
//! moment.js
//! version : 2.15.0
//! authors : Tim Wood, Iskren Chernev, Moment.js contributors
//! license : MIT
//! momentjs.com

;(function (global, factory) {
    typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
    typeof define === 'function' && define.amd ? define(factory) :
    global.moment = factory()
}(this, function () { 'use strict';

    var hookCallback;

    function utils_hooks__hooks () {
        return hookCallback.apply(null, arguments);
    }

    // This is done to register the method called with moment()
    // without creating circular dependencies.
    function setHookCallback (callback) {
        hookCallback = callback;
    }

    function isArray(input) {
        return input instanceof Array || Object.prototype.toString.call(input) === '[object Array]';
    }

    function isObject(input) {
        // IE8 will treat undefined and null as object if it wasn't for
        // input != null
        return input != null && Object.prototype.toString.call(input) === '[object Object]';
    }

    function isObjectEmpty(obj) {
        var k;
        for (k in obj) {
            // even if its not own property I'd still call it non-empty
            return false;
        }
        return true;
    }

    function isDate(input) {
        return input instanceof Date || Object.prototype.toString.call(input) === '[object Date]';
    }

    function map(arr, fn) {
        var res = [], i;
        for (i = 0; i < arr.length; ++i) {
            res.push(fn(arr[i], i));
        }
        return res;
    }

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function extend(a, b) {
        for (var i in b) {
            if (hasOwnProp(b, i)) {
                a[i] = b[i];
            }
        }

        if (hasOwnProp(b, 'toString')) {
            a.toString = b.toString;
        }

        if (hasOwnProp(b, 'valueOf')) {
            a.valueOf = b.valueOf;
        }

        return a;
    }

    function create_utc__createUTC (input, format, locale, strict) {
        return createLocalOrUTC(input, format, locale, strict, true).utc();
    }

    function defaultParsingFlags() {
        // We need to deep clone this object.
        return {
            empty           : false,
            unusedTokens    : [],
            unusedInput     : [],
            overflow        : -2,
            charsLeftOver   : 0,
            nullInput       : false,
            invalidMonth    : null,
            invalidFormat   : false,
            userInvalidated : false,
            iso             : false,
            parsedDateParts : [],
            meridiem        : null
        };
    }

    function getParsingFlags(m) {
        if (m._pf == null) {
            m._pf = defaultParsingFlags();
        }
        return m._pf;
    }

    var some;
    if (Array.prototype.some) {
        some = Array.prototype.some;
    } else {
        some = function (fun) {
            var t = Object(this);
            var len = t.length >>> 0;

            for (var i = 0; i < len; i++) {
                if (i in t && fun.call(this, t[i], i, t)) {
                    return true;
                }
            }

            return false;
        };
    }

    function valid__isValid(m) {
        if (m._isValid == null) {
            var flags = getParsingFlags(m);
            var parsedParts = some.call(flags.parsedDateParts, function (i) {
                return i != null;
            });
            var isNowValid = !isNaN(m._d.getTime()) &&
                flags.overflow < 0 &&
                !flags.empty &&
                !flags.invalidMonth &&
                !flags.invalidWeekday &&
                !flags.nullInput &&
                !flags.invalidFormat &&
                !flags.userInvalidated &&
                (!flags.meridiem || (flags.meridiem && parsedParts));

            if (m._strict) {
                isNowValid = isNowValid &&
                    flags.charsLeftOver === 0 &&
                    flags.unusedTokens.length === 0 &&
                    flags.bigHour === undefined;
            }

            if (Object.isFrozen == null || !Object.isFrozen(m)) {
                m._isValid = isNowValid;
            }
            else {
                return isNowValid;
            }
        }
        return m._isValid;
    }

    function valid__createInvalid (flags) {
        var m = create_utc__createUTC(NaN);
        if (flags != null) {
            extend(getParsingFlags(m), flags);
        }
        else {
            getParsingFlags(m).userInvalidated = true;
        }

        return m;
    }

    function isUndefined(input) {
        return input === void 0;
    }

    // Plugins that add properties should also add the key here (null value),
    // so we can properly clone ourselves.
    var momentProperties = utils_hooks__hooks.momentProperties = [];

    function copyConfig(to, from) {
        var i, prop, val;

        if (!isUndefined(from._isAMomentObject)) {
            to._isAMomentObject = from._isAMomentObject;
        }
        if (!isUndefined(from._i)) {
            to._i = from._i;
        }
        if (!isUndefined(from._f)) {
            to._f = from._f;
        }
        if (!isUndefined(from._l)) {
            to._l = from._l;
        }
        if (!isUndefined(from._strict)) {
            to._strict = from._strict;
        }
        if (!isUndefined(from._tzm)) {
            to._tzm = from._tzm;
        }
        if (!isUndefined(from._isUTC)) {
            to._isUTC = from._isUTC;
        }
        if (!isUndefined(from._offset)) {
            to._offset = from._offset;
        }
        if (!isUndefined(from._pf)) {
            to._pf = getParsingFlags(from);
        }
        if (!isUndefined(from._locale)) {
            to._locale = from._locale;
        }

        if (momentProperties.length > 0) {
            for (i in momentProperties) {
                prop = momentProperties[i];
                val = from[prop];
                if (!isUndefined(val)) {
                    to[prop] = val;
                }
            }
        }

        return to;
    }

    var updateInProgress = false;

    // Moment prototype object
    function Moment(config) {
        copyConfig(this, config);
        this._d = new Date(config._d != null ? config._d.getTime() : NaN);
        // Prevent infinite loop in case updateOffset creates new moment
        // objects.
        if (updateInProgress === false) {
            updateInProgress = true;
            utils_hooks__hooks.updateOffset(this);
            updateInProgress = false;
        }
    }

    function isMoment (obj) {
        return obj instanceof Moment || (obj != null && obj._isAMomentObject != null);
    }

    function absFloor (number) {
        if (number < 0) {
            // -0 -> 0
            return Math.ceil(number) || 0;
        } else {
            return Math.floor(number);
        }
    }

    function toInt(argumentForCoercion) {
        var coercedNumber = +argumentForCoercion,
            value = 0;

        if (coercedNumber !== 0 && isFinite(coercedNumber)) {
            value = absFloor(coercedNumber);
        }

        return value;
    }

    // compare two arrays, return the number of differences
    function compareArrays(array1, array2, dontConvert) {
        var len = Math.min(array1.length, array2.length),
            lengthDiff = Math.abs(array1.length - array2.length),
            diffs = 0,
            i;
        for (i = 0; i < len; i++) {
            if ((dontConvert && array1[i] !== array2[i]) ||
                (!dontConvert && toInt(array1[i]) !== toInt(array2[i]))) {
                diffs++;
            }
        }
        return diffs + lengthDiff;
    }

    function warn(msg) {
        if (utils_hooks__hooks.suppressDeprecationWarnings === false &&
                (typeof console !==  'undefined') && console.warn) {
            console.warn('Deprecation warning: ' + msg);
        }
    }

    function deprecate(msg, fn) {
        var firstTime = true;

        return extend(function () {
            if (utils_hooks__hooks.deprecationHandler != null) {
                utils_hooks__hooks.deprecationHandler(null, msg);
            }
            if (firstTime) {
                var args = [];
                var arg;
                for (var i = 0; i < arguments.length; i++) {
                    arg = '';
                    if (typeof arguments[i] === 'object') {
                        arg += '\n[' + i + '] ';
                        for (var key in arguments[0]) {
                            arg += key + ': ' + arguments[0][key] + ', ';
                        }
                        arg = arg.slice(0, -2); // Remove trailing comma and space
                    } else {
                        arg = arguments[i];
                    }
                    args.push(arg);
                }
                warn(msg + '\nArguments: ' + Array.prototype.slice.call(args).join('') + '\n' + (new Error()).stack);
                firstTime = false;
            }
            return fn.apply(this, arguments);
        }, fn);
    }

    var deprecations = {};

    function deprecateSimple(name, msg) {
        if (utils_hooks__hooks.deprecationHandler != null) {
            utils_hooks__hooks.deprecationHandler(name, msg);
        }
        if (!deprecations[name]) {
            warn(msg);
            deprecations[name] = true;
        }
    }

    utils_hooks__hooks.suppressDeprecationWarnings = false;
    utils_hooks__hooks.deprecationHandler = null;

    function isFunction(input) {
        return input instanceof Function || Object.prototype.toString.call(input) === '[object Function]';
    }

    function locale_set__set (config) {
        var prop, i;
        for (i in config) {
            prop = config[i];
            if (isFunction(prop)) {
                this[i] = prop;
            } else {
                this['_' + i] = prop;
            }
        }
        this._config = config;
        // Lenient ordinal parsing accepts just a number in addition to
        // number + (possibly) stuff coming from _ordinalParseLenient.
        this._ordinalParseLenient = new RegExp(this._ordinalParse.source + '|' + (/\d{1,2}/).source);
    }

    function mergeConfigs(parentConfig, childConfig) {
        var res = extend({}, parentConfig), prop;
        for (prop in childConfig) {
            if (hasOwnProp(childConfig, prop)) {
                if (isObject(parentConfig[prop]) && isObject(childConfig[prop])) {
                    res[prop] = {};
                    extend(res[prop], parentConfig[prop]);
                    extend(res[prop], childConfig[prop]);
                } else if (childConfig[prop] != null) {
                    res[prop] = childConfig[prop];
                } else {
                    delete res[prop];
                }
            }
        }
        for (prop in parentConfig) {
            if (hasOwnProp(parentConfig, prop) &&
                    !hasOwnProp(childConfig, prop) &&
                    isObject(parentConfig[prop])) {
                // make sure changes to properties don't modify parent config
                res[prop] = extend({}, res[prop]);
            }
        }
        return res;
    }

    function Locale(config) {
        if (config != null) {
            this.set(config);
        }
    }

    var keys;

    if (Object.keys) {
        keys = Object.keys;
    } else {
        keys = function (obj) {
            var i, res = [];
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        };
    }

    var defaultCalendar = {
        sameDay : '[Today at] LT',
        nextDay : '[Tomorrow at] LT',
        nextWeek : 'dddd [at] LT',
        lastDay : '[Yesterday at] LT',
        lastWeek : '[Last] dddd [at] LT',
        sameElse : 'L'
    };

    function locale_calendar__calendar (key, mom, now) {
        var output = this._calendar[key] || this._calendar['sameElse'];
        return isFunction(output) ? output.call(mom, now) : output;
    }

    var defaultLongDateFormat = {
        LTS  : 'h:mm:ss A',
        LT   : 'h:mm A',
        L    : 'MM/DD/YYYY',
        LL   : 'MMMM D, YYYY',
        LLL  : 'MMMM D, YYYY h:mm A',
        LLLL : 'dddd, MMMM D, YYYY h:mm A'
    };

    function longDateFormat (key) {
        var format = this._longDateFormat[key],
            formatUpper = this._longDateFormat[key.toUpperCase()];

        if (format || !formatUpper) {
            return format;
        }

        this._longDateFormat[key] = formatUpper.replace(/MMMM|MM|DD|dddd/g, function (val) {
            return val.slice(1);
        });

        return this._longDateFormat[key];
    }

    var defaultInvalidDate = 'Invalid date';

    function invalidDate () {
        return this._invalidDate;
    }

    var defaultOrdinal = '%d';
    var defaultOrdinalParse = /\d{1,2}/;

    function ordinal (number) {
        return this._ordinal.replace('%d', number);
    }

    var defaultRelativeTime = {
        future : 'in %s',
        past   : '%s ago',
        s  : 'a few seconds',
        m  : 'a minute',
        mm : '%d minutes',
        h  : 'an hour',
        hh : '%d hours',
        d  : 'a day',
        dd : '%d days',
        M  : 'a month',
        MM : '%d months',
        y  : 'a year',
        yy : '%d years'
    };

    function relative__relativeTime (number, withoutSuffix, string, isFuture) {
        var output = this._relativeTime[string];
        return (isFunction(output)) ?
            output(number, withoutSuffix, string, isFuture) :
            output.replace(/%d/i, number);
    }

    function pastFuture (diff, output) {
        var format = this._relativeTime[diff > 0 ? 'future' : 'past'];
        return isFunction(format) ? format(output) : format.replace(/%s/i, output);
    }

    var aliases = {};

    function addUnitAlias (unit, shorthand) {
        var lowerCase = unit.toLowerCase();
        aliases[lowerCase] = aliases[lowerCase + 's'] = aliases[shorthand] = unit;
    }

    function normalizeUnits(units) {
        return typeof units === 'string' ? aliases[units] || aliases[units.toLowerCase()] : undefined;
    }

    function normalizeObjectUnits(inputObject) {
        var normalizedInput = {},
            normalizedProp,
            prop;

        for (prop in inputObject) {
            if (hasOwnProp(inputObject, prop)) {
                normalizedProp = normalizeUnits(prop);
                if (normalizedProp) {
                    normalizedInput[normalizedProp] = inputObject[prop];
                }
            }
        }

        return normalizedInput;
    }

    var priorities = {};

    function addUnitPriority(unit, priority) {
        priorities[unit] = priority;
    }

    function getPrioritizedUnits(unitsObj) {
        var units = [];
        for (var u in unitsObj) {
            units.push({unit: u, priority: priorities[u]});
        }
        units.sort(function (a, b) {
            return a.priority - b.priority;
        });
        return units;
    }

    function makeGetSet (unit, keepTime) {
        return function (value) {
            if (value != null) {
                get_set__set(this, unit, value);
                utils_hooks__hooks.updateOffset(this, keepTime);
                return this;
            } else {
                return get_set__get(this, unit);
            }
        };
    }

    function get_set__get (mom, unit) {
        return mom.isValid() ?
            mom._d['get' + (mom._isUTC ? 'UTC' : '') + unit]() : NaN;
    }

    function get_set__set (mom, unit, value) {
        if (mom.isValid()) {
            mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value);
        }
    }

    // MOMENTS

    function stringGet (units) {
        units = normalizeUnits(units);
        if (isFunction(this[units])) {
            return this[units]();
        }
        return this;
    }


    function stringSet (units, value) {
        if (typeof units === 'object') {
            units = normalizeObjectUnits(units);
            var prioritized = getPrioritizedUnits(units);
            for (var i = 0; i < prioritized.length; i++) {
                this[prioritized[i].unit](units[prioritized[i].unit]);
            }
        } else {
            units = normalizeUnits(units);
            if (isFunction(this[units])) {
                return this[units](value);
            }
        }
        return this;
    }

    function zeroFill(number, targetLength, forceSign) {
        var absNumber = '' + Math.abs(number),
            zerosToFill = targetLength - absNumber.length,
            sign = number >= 0;
        return (sign ? (forceSign ? '+' : '') : '-') +
            Math.pow(10, Math.max(0, zerosToFill)).toString().substr(1) + absNumber;
    }

    var formattingTokens = /(\[[^\[]*\])|(\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g;

    var localFormattingTokens = /(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g;

    var formatFunctions = {};

    var formatTokenFunctions = {};

    // token:    'M'
    // padded:   ['MM', 2]
    // ordinal:  'Mo'
    // callback: function () { this.month() + 1 }
    function addFormatToken (token, padded, ordinal, callback) {
        var func = callback;
        if (typeof callback === 'string') {
            func = function () {
                return this[callback]();
            };
        }
        if (token) {
            formatTokenFunctions[token] = func;
        }
        if (padded) {
            formatTokenFunctions[padded[0]] = function () {
                return zeroFill(func.apply(this, arguments), padded[1], padded[2]);
            };
        }
        if (ordinal) {
            formatTokenFunctions[ordinal] = function () {
                return this.localeData().ordinal(func.apply(this, arguments), token);
            };
        }
    }

    function removeFormattingTokens(input) {
        if (input.match(/\[[\s\S]/)) {
            return input.replace(/^\[|\]$/g, '');
        }
        return input.replace(/\\/g, '');
    }

    function makeFormatFunction(format) {
        var array = format.match(formattingTokens), i, length;

        for (i = 0, length = array.length; i < length; i++) {
            if (formatTokenFunctions[array[i]]) {
                array[i] = formatTokenFunctions[array[i]];
            } else {
                array[i] = removeFormattingTokens(array[i]);
            }
        }

        return function (mom) {
            var output = '', i;
            for (i = 0; i < length; i++) {
                output += array[i] instanceof Function ? array[i].call(mom, format) : array[i];
            }
            return output;
        };
    }

    // format date using native date object
    function formatMoment(m, format) {
        if (!m.isValid()) {
            return m.localeData().invalidDate();
        }

        format = expandFormat(format, m.localeData());
        formatFunctions[format] = formatFunctions[format] || makeFormatFunction(format);

        return formatFunctions[format](m);
    }

    function expandFormat(format, locale) {
        var i = 5;

        function replaceLongDateFormatTokens(input) {
            return locale.longDateFormat(input) || input;
        }

        localFormattingTokens.lastIndex = 0;
        while (i >= 0 && localFormattingTokens.test(format)) {
            format = format.replace(localFormattingTokens, replaceLongDateFormatTokens);
            localFormattingTokens.lastIndex = 0;
            i -= 1;
        }

        return format;
    }

    var match1         = /\d/;            //       0 - 9
    var match2         = /\d\d/;          //      00 - 99
    var match3         = /\d{3}/;         //     000 - 999
    var match4         = /\d{4}/;         //    0000 - 9999
    var match6         = /[+-]?\d{6}/;    // -999999 - 999999
    var match1to2      = /\d\d?/;         //       0 - 99
    var match3to4      = /\d\d\d\d?/;     //     999 - 9999
    var match5to6      = /\d\d\d\d\d\d?/; //   99999 - 999999
    var match1to3      = /\d{1,3}/;       //       0 - 999
    var match1to4      = /\d{1,4}/;       //       0 - 9999
    var match1to6      = /[+-]?\d{1,6}/;  // -999999 - 999999

    var matchUnsigned  = /\d+/;           //       0 - inf
    var matchSigned    = /[+-]?\d+/;      //    -inf - inf

    var matchOffset    = /Z|[+-]\d\d:?\d\d/gi; // +00:00 -00:00 +0000 -0000 or Z
    var matchShortOffset = /Z|[+-]\d\d(?::?\d\d)?/gi; // +00 -00 +00:00 -00:00 +0000 -0000 or Z

    var matchTimestamp = /[+-]?\d+(\.\d{1,3})?/; // 123456789 123456789.123

    // any word (or two) characters or numbers including two/three word month in arabic.
    // includes scottish gaelic two word and hyphenated months
    var matchWord = /[0-9]*['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+|[\u0600-\u06FF\/]+(\s*?[\u0600-\u06FF]+){1,2}/i;


    var regexes = {};

    function addRegexToken (token, regex, strictRegex) {
        regexes[token] = isFunction(regex) ? regex : function (isStrict, localeData) {
            return (isStrict && strictRegex) ? strictRegex : regex;
        };
    }

    function getParseRegexForToken (token, config) {
        if (!hasOwnProp(regexes, token)) {
            return new RegExp(unescapeFormat(token));
        }

        return regexes[token](config._strict, config._locale);
    }

    // Code from http://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript
    function unescapeFormat(s) {
        return regexEscape(s.replace('\\', '').replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g, function (matched, p1, p2, p3, p4) {
            return p1 || p2 || p3 || p4;
        }));
    }

    function regexEscape(s) {
        return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
    }

    var tokens = {};

    function addParseToken (token, callback) {
        var i, func = callback;
        if (typeof token === 'string') {
            token = [token];
        }
        if (typeof callback === 'number') {
            func = function (input, array) {
                array[callback] = toInt(input);
            };
        }
        for (i = 0; i < token.length; i++) {
            tokens[token[i]] = func;
        }
    }

    function addWeekParseToken (token, callback) {
        addParseToken(token, function (input, array, config, token) {
            config._w = config._w || {};
            callback(input, config._w, config, token);
        });
    }

    function addTimeToArrayFromToken(token, input, config) {
        if (input != null && hasOwnProp(tokens, token)) {
            tokens[token](input, config._a, config, token);
        }
    }

    var YEAR = 0;
    var MONTH = 1;
    var DATE = 2;
    var HOUR = 3;
    var MINUTE = 4;
    var SECOND = 5;
    var MILLISECOND = 6;
    var WEEK = 7;
    var WEEKDAY = 8;

    var indexOf;

    if (Array.prototype.indexOf) {
        indexOf = Array.prototype.indexOf;
    } else {
        indexOf = function (o) {
            // I know
            var i;
            for (i = 0; i < this.length; ++i) {
                if (this[i] === o) {
                    return i;
                }
            }
            return -1;
        };
    }

    function daysInMonth(year, month) {
        return new Date(Date.UTC(year, month + 1, 0)).getUTCDate();
    }

    // FORMATTING

    addFormatToken('M', ['MM', 2], 'Mo', function () {
        return this.month() + 1;
    });

    addFormatToken('MMM', 0, 0, function (format) {
        return this.localeData().monthsShort(this, format);
    });

    addFormatToken('MMMM', 0, 0, function (format) {
        return this.localeData().months(this, format);
    });

    // ALIASES

    addUnitAlias('month', 'M');

    // PRIORITY

    addUnitPriority('month', 8);

    // PARSING

    addRegexToken('M',    match1to2);
    addRegexToken('MM',   match1to2, match2);
    addRegexToken('MMM',  function (isStrict, locale) {
        return locale.monthsShortRegex(isStrict);
    });
    addRegexToken('MMMM', function (isStrict, locale) {
        return locale.monthsRegex(isStrict);
    });

    addParseToken(['M', 'MM'], function (input, array) {
        array[MONTH] = toInt(input) - 1;
    });

    addParseToken(['MMM', 'MMMM'], function (input, array, config, token) {
        var month = config._locale.monthsParse(input, token, config._strict);
        // if we didn't find a month name, mark the date as invalid.
        if (month != null) {
            array[MONTH] = month;
        } else {
            getParsingFlags(config).invalidMonth = input;
        }
    });

    // LOCALES

    var MONTHS_IN_FORMAT = /D[oD]?(\[[^\[\]]*\]|\s+)+MMMM?/;
    var defaultLocaleMonths = 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_');
    function localeMonths (m, format) {
        if (!m) {
            return this._months;
        }
        return isArray(this._months) ? this._months[m.month()] :
            this._months[(this._months.isFormat || MONTHS_IN_FORMAT).test(format) ? 'format' : 'standalone'][m.month()];
    }

    var defaultLocaleMonthsShort = 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_');
    function localeMonthsShort (m, format) {
        if (!m) {
            return this._monthsShort;
        }
        return isArray(this._monthsShort) ? this._monthsShort[m.month()] :
            this._monthsShort[MONTHS_IN_FORMAT.test(format) ? 'format' : 'standalone'][m.month()];
    }

    function units_month__handleStrictParse(monthName, format, strict) {
        var i, ii, mom, llc = monthName.toLocaleLowerCase();
        if (!this._monthsParse) {
            // this is not used
            this._monthsParse = [];
            this._longMonthsParse = [];
            this._shortMonthsParse = [];
            for (i = 0; i < 12; ++i) {
                mom = create_utc__createUTC([2000, i]);
                this._shortMonthsParse[i] = this.monthsShort(mom, '').toLocaleLowerCase();
                this._longMonthsParse[i] = this.months(mom, '').toLocaleLowerCase();
            }
        }

        if (strict) {
            if (format === 'MMM') {
                ii = indexOf.call(this._shortMonthsParse, llc);
                return ii !== -1 ? ii : null;
            } else {
                ii = indexOf.call(this._longMonthsParse, llc);
                return ii !== -1 ? ii : null;
            }
        } else {
            if (format === 'MMM') {
                ii = indexOf.call(this._shortMonthsParse, llc);
                if (ii !== -1) {
                    return ii;
                }
                ii = indexOf.call(this._longMonthsParse, llc);
                return ii !== -1 ? ii : null;
            } else {
                ii = indexOf.call(this._longMonthsParse, llc);
                if (ii !== -1) {
                    return ii;
                }
                ii = indexOf.call(this._shortMonthsParse, llc);
                return ii !== -1 ? ii : null;
            }
        }
    }

    function localeMonthsParse (monthName, format, strict) {
        var i, mom, regex;

        if (this._monthsParseExact) {
            return units_month__handleStrictParse.call(this, monthName, format, strict);
        }

        if (!this._monthsParse) {
            this._monthsParse = [];
            this._longMonthsParse = [];
            this._shortMonthsParse = [];
        }

        // TODO: add sorting
        // Sorting makes sure if one month (or abbr) is a prefix of another
        // see sorting in computeMonthsParse
        for (i = 0; i < 12; i++) {
            // make the regex if we don't have it already
            mom = create_utc__createUTC([2000, i]);
            if (strict && !this._longMonthsParse[i]) {
                this._longMonthsParse[i] = new RegExp('^' + this.months(mom, '').replace('.', '') + '$', 'i');
                this._shortMonthsParse[i] = new RegExp('^' + this.monthsShort(mom, '').replace('.', '') + '$', 'i');
            }
            if (!strict && !this._monthsParse[i]) {
                regex = '^' + this.months(mom, '') + '|^' + this.monthsShort(mom, '');
                this._monthsParse[i] = new RegExp(regex.replace('.', ''), 'i');
            }
            // test the regex
            if (strict && format === 'MMMM' && this._longMonthsParse[i].test(monthName)) {
                return i;
            } else if (strict && format === 'MMM' && this._shortMonthsParse[i].test(monthName)) {
                return i;
            } else if (!strict && this._monthsParse[i].test(monthName)) {
                return i;
            }
        }
    }

    // MOMENTS

    function setMonth (mom, value) {
        var dayOfMonth;

        if (!mom.isValid()) {
            // No op
            return mom;
        }

        if (typeof value === 'string') {
            if (/^\d+$/.test(value)) {
                value = toInt(value);
            } else {
                value = mom.localeData().monthsParse(value);
                // TODO: Another silent failure?
                if (typeof value !== 'number') {
                    return mom;
                }
            }
        }

        dayOfMonth = Math.min(mom.date(), daysInMonth(mom.year(), value));
        mom._d['set' + (mom._isUTC ? 'UTC' : '') + 'Month'](value, dayOfMonth);
        return mom;
    }

    function getSetMonth (value) {
        if (value != null) {
            setMonth(this, value);
            utils_hooks__hooks.updateOffset(this, true);
            return this;
        } else {
            return get_set__get(this, 'Month');
        }
    }

    function getDaysInMonth () {
        return daysInMonth(this.year(), this.month());
    }

    var defaultMonthsShortRegex = matchWord;
    function monthsShortRegex (isStrict) {
        if (this._monthsParseExact) {
            if (!hasOwnProp(this, '_monthsRegex')) {
                computeMonthsParse.call(this);
            }
            if (isStrict) {
                return this._monthsShortStrictRegex;
            } else {
                return this._monthsShortRegex;
            }
        } else {
            if (!hasOwnProp(this, '_monthsShortRegex')) {
                this._monthsShortRegex = defaultMonthsShortRegex;
            }
            return this._monthsShortStrictRegex && isStrict ?
                this._monthsShortStrictRegex : this._monthsShortRegex;
        }
    }

    var defaultMonthsRegex = matchWord;
    function monthsRegex (isStrict) {
        if (this._monthsParseExact) {
            if (!hasOwnProp(this, '_monthsRegex')) {
                computeMonthsParse.call(this);
            }
            if (isStrict) {
                return this._monthsStrictRegex;
            } else {
                return this._monthsRegex;
            }
        } else {
            if (!hasOwnProp(this, '_monthsRegex')) {
                this._monthsRegex = defaultMonthsRegex;
            }
            return this._monthsStrictRegex && isStrict ?
                this._monthsStrictRegex : this._monthsRegex;
        }
    }

    function computeMonthsParse () {
        function cmpLenRev(a, b) {
            return b.length - a.length;
        }

        var shortPieces = [], longPieces = [], mixedPieces = [],
            i, mom;
        for (i = 0; i < 12; i++) {
            // make the regex if we don't have it already
            mom = create_utc__createUTC([2000, i]);
            shortPieces.push(this.monthsShort(mom, ''));
            longPieces.push(this.months(mom, ''));
            mixedPieces.push(this.months(mom, ''));
            mixedPieces.push(this.monthsShort(mom, ''));
        }
        // Sorting makes sure if one month (or abbr) is a prefix of another it
        // will match the longer piece.
        shortPieces.sort(cmpLenRev);
        longPieces.sort(cmpLenRev);
        mixedPieces.sort(cmpLenRev);
        for (i = 0; i < 12; i++) {
            shortPieces[i] = regexEscape(shortPieces[i]);
            longPieces[i] = regexEscape(longPieces[i]);
        }
        for (i = 0; i < 24; i++) {
            mixedPieces[i] = regexEscape(mixedPieces[i]);
        }

        this._monthsRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');
        this._monthsShortRegex = this._monthsRegex;
        this._monthsStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i');
        this._monthsShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i');
    }

    // FORMATTING

    addFormatToken('Y', 0, 0, function () {
        var y = this.year();
        return y <= 9999 ? '' + y : '+' + y;
    });

    addFormatToken(0, ['YY', 2], 0, function () {
        return this.year() % 100;
    });

    addFormatToken(0, ['YYYY',   4],       0, 'year');
    addFormatToken(0, ['YYYYY',  5],       0, 'year');
    addFormatToken(0, ['YYYYYY', 6, true], 0, 'year');

    // ALIASES

    addUnitAlias('year', 'y');

    // PRIORITIES

    addUnitPriority('year', 1);

    // PARSING

    addRegexToken('Y',      matchSigned);
    addRegexToken('YY',     match1to2, match2);
    addRegexToken('YYYY',   match1to4, match4);
    addRegexToken('YYYYY',  match1to6, match6);
    addRegexToken('YYYYYY', match1to6, match6);

    addParseToken(['YYYYY', 'YYYYYY'], YEAR);
    addParseToken('YYYY', function (input, array) {
        array[YEAR] = input.length === 2 ? utils_hooks__hooks.parseTwoDigitYear(input) : toInt(input);
    });
    addParseToken('YY', function (input, array) {
        array[YEAR] = utils_hooks__hooks.parseTwoDigitYear(input);
    });
    addParseToken('Y', function (input, array) {
        array[YEAR] = parseInt(input, 10);
    });

    // HELPERS

    function daysInYear(year) {
        return isLeapYear(year) ? 366 : 365;
    }

    function isLeapYear(year) {
        return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;
    }

    // HOOKS

    utils_hooks__hooks.parseTwoDigitYear = function (input) {
        return toInt(input) + (toInt(input) > 68 ? 1900 : 2000);
    };

    // MOMENTS

    var getSetYear = makeGetSet('FullYear', true);

    function getIsLeapYear () {
        return isLeapYear(this.year());
    }

    function createDate (y, m, d, h, M, s, ms) {
        //can't just apply() to create a date:
        //http://stackoverflow.com/questions/181348/instantiating-a-javascript-object-by-calling-prototype-constructor-apply
        var date = new Date(y, m, d, h, M, s, ms);

        //the date constructor remaps years 0-99 to 1900-1999
        if (y < 100 && y >= 0 && isFinite(date.getFullYear())) {
            date.setFullYear(y);
        }
        return date;
    }

    function createUTCDate (y) {
        var date = new Date(Date.UTC.apply(null, arguments));

        //the Date.UTC function remaps years 0-99 to 1900-1999
        if (y < 100 && y >= 0 && isFinite(date.getUTCFullYear())) {
            date.setUTCFullYear(y);
        }
        return date;
    }

    // start-of-first-week - start-of-year
    function firstWeekOffset(year, dow, doy) {
        var // first-week day -- which january is always in the first week (4 for iso, 1 for other)
            fwd = 7 + dow - doy,
            // first-week day local weekday -- which local weekday is fwd
            fwdlw = (7 + createUTCDate(year, 0, fwd).getUTCDay() - dow) % 7;

        return -fwdlw + fwd - 1;
    }

    //http://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday
    function dayOfYearFromWeeks(year, week, weekday, dow, doy) {
        var localWeekday = (7 + weekday - dow) % 7,
            weekOffset = firstWeekOffset(year, dow, doy),
            dayOfYear = 1 + 7 * (week - 1) + localWeekday + weekOffset,
            resYear, resDayOfYear;

        if (dayOfYear <= 0) {
            resYear = year - 1;
            resDayOfYear = daysInYear(resYear) + dayOfYear;
        } else if (dayOfYear > daysInYear(year)) {
            resYear = year + 1;
            resDayOfYear = dayOfYear - daysInYear(year);
        } else {
            resYear = year;
            resDayOfYear = dayOfYear;
        }

        return {
            year: resYear,
            dayOfYear: resDayOfYear
        };
    }

    function weekOfYear(mom, dow, doy) {
        var weekOffset = firstWeekOffset(mom.year(), dow, doy),
            week = Math.floor((mom.dayOfYear() - weekOffset - 1) / 7) + 1,
            resWeek, resYear;

        if (week < 1) {
            resYear = mom.year() - 1;
            resWeek = week + weeksInYear(resYear, dow, doy);
        } else if (week > weeksInYear(mom.year(), dow, doy)) {
            resWeek = week - weeksInYear(mom.year(), dow, doy);
            resYear = mom.year() + 1;
        } else {
            resYear = mom.year();
            resWeek = week;
        }

        return {
            week: resWeek,
            year: resYear
        };
    }

    function weeksInYear(year, dow, doy) {
        var weekOffset = firstWeekOffset(year, dow, doy),
            weekOffsetNext = firstWeekOffset(year + 1, dow, doy);
        return (daysInYear(year) - weekOffset + weekOffsetNext) / 7;
    }

    // FORMATTING

    addFormatToken('w', ['ww', 2], 'wo', 'week');
    addFormatToken('W', ['WW', 2], 'Wo', 'isoWeek');

    // ALIASES

    addUnitAlias('week', 'w');
    addUnitAlias('isoWeek', 'W');

    // PRIORITIES

    addUnitPriority('week', 5);
    addUnitPriority('isoWeek', 5);

    // PARSING

    addRegexToken('w',  match1to2);
    addRegexToken('ww', match1to2, match2);
    addRegexToken('W',  match1to2);
    addRegexToken('WW', match1to2, match2);

    addWeekParseToken(['w', 'ww', 'W', 'WW'], function (input, week, config, token) {
        week[token.substr(0, 1)] = toInt(input);
    });

    // HELPERS

    // LOCALES

    function localeWeek (mom) {
        return weekOfYear(mom, this._week.dow, this._week.doy).week;
    }

    var defaultLocaleWeek = {
        dow : 0, // Sunday is the first day of the week.
        doy : 6  // The week that contains Jan 1st is the first week of the year.
    };

    function localeFirstDayOfWeek () {
        return this._week.dow;
    }

    function localeFirstDayOfYear () {
        return this._week.doy;
    }

    // MOMENTS

    function getSetWeek (input) {
        var week = this.localeData().week(this);
        return input == null ? week : this.add((input - week) * 7, 'd');
    }

    function getSetISOWeek (input) {
        var week = weekOfYear(this, 1, 4).week;
        return input == null ? week : this.add((input - week) * 7, 'd');
    }

    // FORMATTING

    addFormatToken('d', 0, 'do', 'day');

    addFormatToken('dd', 0, 0, function (format) {
        return this.localeData().weekdaysMin(this, format);
    });

    addFormatToken('ddd', 0, 0, function (format) {
        return this.localeData().weekdaysShort(this, format);
    });

    addFormatToken('dddd', 0, 0, function (format) {
        return this.localeData().weekdays(this, format);
    });

    addFormatToken('e', 0, 0, 'weekday');
    addFormatToken('E', 0, 0, 'isoWeekday');

    // ALIASES

    addUnitAlias('day', 'd');
    addUnitAlias('weekday', 'e');
    addUnitAlias('isoWeekday', 'E');

    // PRIORITY
    addUnitPriority('day', 11);
    addUnitPriority('weekday', 11);
    addUnitPriority('isoWeekday', 11);

    // PARSING

    addRegexToken('d',    match1to2);
    addRegexToken('e',    match1to2);
    addRegexToken('E',    match1to2);
    addRegexToken('dd',   function (isStrict, locale) {
        return locale.weekdaysMinRegex(isStrict);
    });
    addRegexToken('ddd',   function (isStrict, locale) {
        return locale.weekdaysShortRegex(isStrict);
    });
    addRegexToken('dddd',   function (isStrict, locale) {
        return locale.weekdaysRegex(isStrict);
    });

    addWeekParseToken(['dd', 'ddd', 'dddd'], function (input, week, config, token) {
        var weekday = config._locale.weekdaysParse(input, token, config._strict);
        // if we didn't get a weekday name, mark the date as invalid
        if (weekday != null) {
            week.d = weekday;
        } else {
            getParsingFlags(config).invalidWeekday = input;
        }
    });

    addWeekParseToken(['d', 'e', 'E'], function (input, week, config, token) {
        week[token] = toInt(input);
    });

    // HELPERS

    function parseWeekday(input, locale) {
        if (typeof input !== 'string') {
            return input;
        }

        if (!isNaN(input)) {
            return parseInt(input, 10);
        }

        input = locale.weekdaysParse(input);
        if (typeof input === 'number') {
            return input;
        }

        return null;
    }

    function parseIsoWeekday(input, locale) {
        if (typeof input === 'string') {
            return locale.weekdaysParse(input) % 7 || 7;
        }
        return isNaN(input) ? null : input;
    }

    // LOCALES

    var defaultLocaleWeekdays = 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_');
    function localeWeekdays (m, format) {
        if (!m) {
            return this._weekdays;
        }
        return isArray(this._weekdays) ? this._weekdays[m.day()] :
            this._weekdays[this._weekdays.isFormat.test(format) ? 'format' : 'standalone'][m.day()];
    }

    var defaultLocaleWeekdaysShort = 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_');
    function localeWeekdaysShort (m) {
        return (m) ? this._weekdaysShort[m.day()] : this._weekdaysShort;
    }

    var defaultLocaleWeekdaysMin = 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_');
    function localeWeekdaysMin (m) {
        return (m) ? this._weekdaysMin[m.day()] : this._weekdaysMin;
    }

    function day_of_week__handleStrictParse(weekdayName, format, strict) {
        var i, ii, mom, llc = weekdayName.toLocaleLowerCase();
        if (!this._weekdaysParse) {
            this._weekdaysParse = [];
            this._shortWeekdaysParse = [];
            this._minWeekdaysParse = [];

            for (i = 0; i < 7; ++i) {
                mom = create_utc__createUTC([2000, 1]).day(i);
                this._minWeekdaysParse[i] = this.weekdaysMin(mom, '').toLocaleLowerCase();
                this._shortWeekdaysParse[i] = this.weekdaysShort(mom, '').toLocaleLowerCase();
                this._weekdaysParse[i] = this.weekdays(mom, '').toLocaleLowerCase();
            }
        }

        if (strict) {
            if (format === 'dddd') {
                ii = indexOf.call(this._weekdaysParse, llc);
                return ii !== -1 ? ii : null;
            } else if (format === 'ddd') {
                ii = indexOf.call(this._shortWeekdaysParse, llc);
                return ii !== -1 ? ii : null;
            } else {
                ii = indexOf.call(this._minWeekdaysParse, llc);
                return ii !== -1 ? ii : null;
            }
        } else {
            if (format === 'dddd') {
                ii = indexOf.call(this._weekdaysParse, llc);
                if (ii !== -1) {
                    return ii;
                }
                ii = indexOf.call(this._shortWeekdaysParse, llc);
                if (ii !== -1) {
                    return ii;
                }
                ii = indexOf.call(this._minWeekdaysParse, llc);
                return ii !== -1 ? ii : null;
            } else if (format === 'ddd') {
                ii = indexOf.call(this._shortWeekdaysParse, llc);
                if (ii !== -1) {
                    return ii;
                }
                ii = indexOf.call(this._weekdaysParse, llc);
                if (ii !== -1) {
                    return ii;
                }
                ii = indexOf.call(this._minWeekdaysParse, llc);
                return ii !== -1 ? ii : null;
            } else {
                ii = indexOf.call(this._minWeekdaysParse, llc);
                if (ii !== -1) {
                    return ii;
                }
                ii = indexOf.call(this._weekdaysParse, llc);
                if (ii !== -1) {
                    return ii;
                }
                ii = indexOf.call(this._shortWeekdaysParse, llc);
                return ii !== -1 ? ii : null;
            }
        }
    }

    function localeWeekdaysParse (weekdayName, format, strict) {
        var i, mom, regex;

        if (this._weekdaysParseExact) {
            return day_of_week__handleStrictParse.call(this, weekdayName, format, strict);
        }

        if (!this._weekdaysParse) {
            this._weekdaysParse = [];
            this._minWeekdaysParse = [];
            this._shortWeekdaysParse = [];
            this._fullWeekdaysParse = [];
        }

        for (i = 0; i < 7; i++) {
            // make the regex if we don't have it already

            mom = create_utc__createUTC([2000, 1]).day(i);
            if (strict && !this._fullWeekdaysParse[i]) {
                this._fullWeekdaysParse[i] = new RegExp('^' + this.weekdays(mom, '').replace('.', '\.?') + '$', 'i');
                this._shortWeekdaysParse[i] = new RegExp('^' + this.weekdaysShort(mom, '').replace('.', '\.?') + '$', 'i');
                this._minWeekdaysParse[i] = new RegExp('^' + this.weekdaysMin(mom, '').replace('.', '\.?') + '$', 'i');
            }
            if (!this._weekdaysParse[i]) {
                regex = '^' + this.weekdays(mom, '') + '|^' + this.weekdaysShort(mom, '') + '|^' + this.weekdaysMin(mom, '');
                this._weekdaysParse[i] = new RegExp(regex.replace('.', ''), 'i');
            }
            // test the regex
            if (strict && format === 'dddd' && this._fullWeekdaysParse[i].test(weekdayName)) {
                return i;
            } else if (strict && format === 'ddd' && this._shortWeekdaysParse[i].test(weekdayName)) {
                return i;
            } else if (strict && format === 'dd' && this._minWeekdaysParse[i].test(weekdayName)) {
                return i;
            } else if (!strict && this._weekdaysParse[i].test(weekdayName)) {
                return i;
            }
        }
    }

    // MOMENTS

    function getSetDayOfWeek (input) {
        if (!this.isValid()) {
            return input != null ? this : NaN;
        }
        var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay();
        if (input != null) {
            input = parseWeekday(input, this.localeData());
            return this.add(input - day, 'd');
        } else {
            return day;
        }
    }

    function getSetLocaleDayOfWeek (input) {
        if (!this.isValid()) {
            return input != null ? this : NaN;
        }
        var weekday = (this.day() + 7 - this.localeData()._week.dow) % 7;
        return input == null ? weekday : this.add(input - weekday, 'd');
    }

    function getSetISODayOfWeek (input) {
        if (!this.isValid()) {
            return input != null ? this : NaN;
        }

        // behaves the same as moment#day except
        // as a getter, returns 7 instead of 0 (1-7 range instead of 0-6)
        // as a setter, sunday should belong to the previous week.

        if (input != null) {
            var weekday = parseIsoWeekday(input, this.localeData());
            return this.day(this.day() % 7 ? weekday : weekday - 7);
        } else {
            return this.day() || 7;
        }
    }

    var defaultWeekdaysRegex = matchWord;
    function weekdaysRegex (isStrict) {
        if (this._weekdaysParseExact) {
            if (!hasOwnProp(this, '_weekdaysRegex')) {
                computeWeekdaysParse.call(this);
            }
            if (isStrict) {
                return this._weekdaysStrictRegex;
            } else {
                return this._weekdaysRegex;
            }
        } else {
            if (!hasOwnProp(this, '_weekdaysRegex')) {
                this._weekdaysRegex = defaultWeekdaysRegex;
            }
            return this._weekdaysStrictRegex && isStrict ?
                this._weekdaysStrictRegex : this._weekdaysRegex;
        }
    }

    var defaultWeekdaysShortRegex = matchWord;
    function weekdaysShortRegex (isStrict) {
        if (this._weekdaysParseExact) {
            if (!hasOwnProp(this, '_weekdaysRegex')) {
                computeWeekdaysParse.call(this);
            }
            if (isStrict) {
                return this._weekdaysShortStrictRegex;
            } else {
                return this._weekdaysShortRegex;
            }
        } else {
            if (!hasOwnProp(this, '_weekdaysShortRegex')) {
                this._weekdaysShortRegex = defaultWeekdaysShortRegex;
            }
            return this._weekdaysShortStrictRegex && isStrict ?
                this._weekdaysShortStrictRegex : this._weekdaysShortRegex;
        }
    }

    var defaultWeekdaysMinRegex = matchWord;
    function weekdaysMinRegex (isStrict) {
        if (this._weekdaysParseExact) {
            if (!hasOwnProp(this, '_weekdaysRegex')) {
                computeWeekdaysParse.call(this);
            }
            if (isStrict) {
                return this._weekdaysMinStrictRegex;
            } else {
                return this._weekdaysMinRegex;
            }
        } else {
            if (!hasOwnProp(this, '_weekdaysMinRegex')) {
                this._weekdaysMinRegex = defaultWeekdaysMinRegex;
            }
            return this._weekdaysMinStrictRegex && isStrict ?
                this._weekdaysMinStrictRegex : this._weekdaysMinRegex;
        }
    }


    function computeWeekdaysParse () {
        function cmpLenRev(a, b) {
            return b.length - a.length;
        }

        var minPieces = [], shortPieces = [], longPieces = [], mixedPieces = [],
            i, mom, minp, shortp, longp;
        for (i = 0; i < 7; i++) {
            // make the regex if we don't have it already
            mom = create_utc__createUTC([2000, 1]).day(i);
            minp = this.weekdaysMin(mom, '');
            shortp = this.weekdaysShort(mom, '');
            longp = this.weekdays(mom, '');
            minPieces.push(minp);
            shortPieces.push(shortp);
            longPieces.push(longp);
            mixedPieces.push(minp);
            mixedPieces.push(shortp);
            mixedPieces.push(longp);
        }
        // Sorting makes sure if one weekday (or abbr) is a prefix of another it
        // will match the longer piece.
        minPieces.sort(cmpLenRev);
        shortPieces.sort(cmpLenRev);
        longPieces.sort(cmpLenRev);
        mixedPieces.sort(cmpLenRev);
        for (i = 0; i < 7; i++) {
            shortPieces[i] = regexEscape(shortPieces[i]);
            longPieces[i] = regexEscape(longPieces[i]);
            mixedPieces[i] = regexEscape(mixedPieces[i]);
        }

        this._weekdaysRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');
        this._weekdaysShortRegex = this._weekdaysRegex;
        this._weekdaysMinRegex = this._weekdaysRegex;

        this._weekdaysStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i');
        this._weekdaysShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i');
        this._weekdaysMinStrictRegex = new RegExp('^(' + minPieces.join('|') + ')', 'i');
    }

    // FORMATTING

    function hFormat() {
        return this.hours() % 12 || 12;
    }

    function kFormat() {
        return this.hours() || 24;
    }

    addFormatToken('H', ['HH', 2], 0, 'hour');
    addFormatToken('h', ['hh', 2], 0, hFormat);
    addFormatToken('k', ['kk', 2], 0, kFormat);

    addFormatToken('hmm', 0, 0, function () {
        return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2);
    });

    addFormatToken('hmmss', 0, 0, function () {
        return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2) +
            zeroFill(this.seconds(), 2);
    });

    addFormatToken('Hmm', 0, 0, function () {
        return '' + this.hours() + zeroFill(this.minutes(), 2);
    });

    addFormatToken('Hmmss', 0, 0, function () {
        return '' + this.hours() + zeroFill(this.minutes(), 2) +
            zeroFill(this.seconds(), 2);
    });

    function meridiem (token, lowercase) {
        addFormatToken(token, 0, 0, function () {
            return this.localeData().meridiem(this.hours(), this.minutes(), lowercase);
        });
    }

    meridiem('a', true);
    meridiem('A', false);

    // ALIASES

    addUnitAlias('hour', 'h');

    // PRIORITY
    addUnitPriority('hour', 13);

    // PARSING

    function matchMeridiem (isStrict, locale) {
        return locale._meridiemParse;
    }

    addRegexToken('a',  matchMeridiem);
    addRegexToken('A',  matchMeridiem);
    addRegexToken('H',  match1to2);
    addRegexToken('h',  match1to2);
    addRegexToken('HH', match1to2, match2);
    addRegexToken('hh', match1to2, match2);

    addRegexToken('hmm', match3to4);
    addRegexToken('hmmss', match5to6);
    addRegexToken('Hmm', match3to4);
    addRegexToken('Hmmss', match5to6);

    addParseToken(['H', 'HH'], HOUR);
    addParseToken(['a', 'A'], function (input, array, config) {
        config._isPm = config._locale.isPM(input);
        config._meridiem = input;
    });
    addParseToken(['h', 'hh'], function (input, array, config) {
        array[HOUR] = toInt(input);
        getParsingFlags(config).bigHour = true;
    });
    addParseToken('hmm', function (input, array, config) {
        var pos = input.length - 2;
        array[HOUR] = toInt(input.substr(0, pos));
        array[MINUTE] = toInt(input.substr(pos));
        getParsingFlags(config).bigHour = true;
    });
    addParseToken('hmmss', function (input, array, config) {
        var pos1 = input.length - 4;
        var pos2 = input.length - 2;
        array[HOUR] = toInt(input.substr(0, pos1));
        array[MINUTE] = toInt(input.substr(pos1, 2));
        array[SECOND] = toInt(input.substr(pos2));
        getParsingFlags(config).bigHour = true;
    });
    addParseToken('Hmm', function (input, array, config) {
        var pos = input.length - 2;
        array[HOUR] = toInt(input.substr(0, pos));
        array[MINUTE] = toInt(input.substr(pos));
    });
    addParseToken('Hmmss', function (input, array, config) {
        var pos1 = input.length - 4;
        var pos2 = input.length - 2;
        array[HOUR] = toInt(input.substr(0, pos1));
        array[MINUTE] = toInt(input.substr(pos1, 2));
        array[SECOND] = toInt(input.substr(pos2));
    });

    // LOCALES

    function localeIsPM (input) {
        // IE8 Quirks Mode & IE7 Standards Mode do not allow accessing strings like arrays
        // Using charAt should be more compatible.
        return ((input + '').toLowerCase().charAt(0) === 'p');
    }

    var defaultLocaleMeridiemParse = /[ap]\.?m?\.?/i;
    function localeMeridiem (hours, minutes, isLower) {
        if (hours > 11) {
            return isLower ? 'pm' : 'PM';
        } else {
            return isLower ? 'am' : 'AM';
        }
    }


    // MOMENTS

    // Setting the hour should keep the time, because the user explicitly
    // specified which hour he wants. So trying to maintain the same hour (in
    // a new timezone) makes sense. Adding/subtracting hours does not follow
    // this rule.
    var getSetHour = makeGetSet('Hours', true);

    var baseConfig = {
        calendar: defaultCalendar,
        longDateFormat: defaultLongDateFormat,
        invalidDate: defaultInvalidDate,
        ordinal: defaultOrdinal,
        ordinalParse: defaultOrdinalParse,
        relativeTime: defaultRelativeTime,

        months: defaultLocaleMonths,
        monthsShort: defaultLocaleMonthsShort,

        week: defaultLocaleWeek,

        weekdays: defaultLocaleWeekdays,
        weekdaysMin: defaultLocaleWeekdaysMin,
        weekdaysShort: defaultLocaleWeekdaysShort,

        meridiemParse: defaultLocaleMeridiemParse
    };

    // internal storage for locale config files
    var locales = {};
    var globalLocale;

    function normalizeLocale(key) {
        return key ? key.toLowerCase().replace('_', '-') : key;
    }

    // pick the locale from the array
    // try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each
    // substring from most specific to least, but move to the next array item if it's a more specific variant than the current root
    function chooseLocale(names) {
        var i = 0, j, next, locale, split;

        while (i < names.length) {
            split = normalizeLocale(names[i]).split('-');
            j = split.length;
            next = normalizeLocale(names[i + 1]);
            next = next ? next.split('-') : null;
            while (j > 0) {
                locale = loadLocale(split.slice(0, j).join('-'));
                if (locale) {
                    return locale;
                }
                if (next && next.length >= j && compareArrays(split, next, true) >= j - 1) {
                    //the next array item is better than a shallower substring of this one
                    break;
                }
                j--;
            }
            i++;
        }
        return null;
    }

    function loadLocale(name) {
        var oldLocale = null;
        // TODO: Find a better way to register and load all the locales in Node
        if (!locales[name] && (typeof module !== 'undefined') &&
                module && module.require) {
            try {
                oldLocale = globalLocale._abbr;
                module.require('./locale/' + name);
                // because defineLocale currently also sets the global locale, we
                // want to undo that for lazy loaded locales
                locale_locales__getSetGlobalLocale(oldLocale);
            } catch (e) { }
        }
        return locales[name];
    }

    // This function will load locale and then set the global locale.  If
    // no arguments are passed in, it will simply return the current global
    // locale key.
    function locale_locales__getSetGlobalLocale (key, values) {
        var data;
        if (key) {
            if (isUndefined(values)) {
                data = locale_locales__getLocale(key);
            }
            else {
                data = defineLocale(key, values);
            }

            if (data) {
                // moment.duration._locale = moment._locale = data;
                globalLocale = data;
            }
        }

        return globalLocale._abbr;
    }

    function defineLocale (name, config) {
        if (config !== null) {
            var parentConfig = baseConfig;
            config.abbr = name;
            if (locales[name] != null) {
                deprecateSimple('defineLocaleOverride',
                        'use moment.updateLocale(localeName, config) to change ' +
                        'an existing locale. moment.defineLocale(localeName, ' +
                        'config) should only be used for creating a new locale ' +
                        'See http://momentjs.com/guides/#/warnings/define-locale/ for more info.');
                parentConfig = locales[name]._config;
            } else if (config.parentLocale != null) {
                if (locales[config.parentLocale] != null) {
                    parentConfig = locales[config.parentLocale]._config;
                } else {
                    // treat as if there is no base config
                    deprecateSimple('parentLocaleUndefined',
                            'specified parentLocale is not defined yet. See http://momentjs.com/guides/#/warnings/parent-locale/');
                }
            }
            locales[name] = new Locale(mergeConfigs(parentConfig, config));

            // backwards compat for now: also set the locale
            locale_locales__getSetGlobalLocale(name);

            return locales[name];
        } else {
            // useful for testing
            delete locales[name];
            return null;
        }
    }

    function updateLocale(name, config) {
        if (config != null) {
            var locale, parentConfig = baseConfig;
            // MERGE
            if (locales[name] != null) {
                parentConfig = locales[name]._config;
            }
            config = mergeConfigs(parentConfig, config);
            locale = new Locale(config);
            locale.parentLocale = locales[name];
            locales[name] = locale;

            // backwards compat for now: also set the locale
            locale_locales__getSetGlobalLocale(name);
        } else {
            // pass null for config to unupdate, useful for tests
            if (locales[name] != null) {
                if (locales[name].parentLocale != null) {
                    locales[name] = locales[name].parentLocale;
                } else if (locales[name] != null) {
                    delete locales[name];
                }
            }
        }
        return locales[name];
    }

    // returns locale data
    function locale_locales__getLocale (key) {
        var locale;

        if (key && key._locale && key._locale._abbr) {
            key = key._locale._abbr;
        }

        if (!key) {
            return globalLocale;
        }

        if (!isArray(key)) {
            //short-circuit everything else
            locale = loadLocale(key);
            if (locale) {
                return locale;
            }
            key = [key];
        }

        return chooseLocale(key);
    }

    function locale_locales__listLocales() {
        return keys(locales);
    }

    function checkOverflow (m) {
        var overflow;
        var a = m._a;

        if (a && getParsingFlags(m).overflow === -2) {
            overflow =
                a[MONTH]       < 0 || a[MONTH]       > 11  ? MONTH :
                a[DATE]        < 1 || a[DATE]        > daysInMonth(a[YEAR], a[MONTH]) ? DATE :
                a[HOUR]        < 0 || a[HOUR]        > 24 || (a[HOUR] === 24 && (a[MINUTE] !== 0 || a[SECOND] !== 0 || a[MILLISECOND] !== 0)) ? HOUR :
                a[MINUTE]      < 0 || a[MINUTE]      > 59  ? MINUTE :
                a[SECOND]      < 0 || a[SECOND]      > 59  ? SECOND :
                a[MILLISECOND] < 0 || a[MILLISECOND] > 999 ? MILLISECOND :
                -1;

            if (getParsingFlags(m)._overflowDayOfYear && (overflow < YEAR || overflow > DATE)) {
                overflow = DATE;
            }
            if (getParsingFlags(m)._overflowWeeks && overflow === -1) {
                overflow = WEEK;
            }
            if (getParsingFlags(m)._overflowWeekday && overflow === -1) {
                overflow = WEEKDAY;
            }

            getParsingFlags(m).overflow = overflow;
        }

        return m;
    }

    // iso 8601 regex
    // 0000-00-00 0000-W00 or 0000-W00-0 + T + 00 or 00:00 or 00:00:00 or 00:00:00.000 + +00:00 or +0000 or +00)
    var extendedIsoRegex = /^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?/;
    var basicIsoRegex = /^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?/;

    var tzRegex = /Z|[+-]\d\d(?::?\d\d)?/;

    var isoDates = [
        ['YYYYYY-MM-DD', /[+-]\d{6}-\d\d-\d\d/],
        ['YYYY-MM-DD', /\d{4}-\d\d-\d\d/],
        ['GGGG-[W]WW-E', /\d{4}-W\d\d-\d/],
        ['GGGG-[W]WW', /\d{4}-W\d\d/, false],
        ['YYYY-DDD', /\d{4}-\d{3}/],
        ['YYYY-MM', /\d{4}-\d\d/, false],
        ['YYYYYYMMDD', /[+-]\d{10}/],
        ['YYYYMMDD', /\d{8}/],
        // YYYYMM is NOT allowed by the standard
        ['GGGG[W]WWE', /\d{4}W\d{3}/],
        ['GGGG[W]WW', /\d{4}W\d{2}/, false],
        ['YYYYDDD', /\d{7}/]
    ];

    // iso time formats and regexes
    var isoTimes = [
        ['HH:mm:ss.SSSS', /\d\d:\d\d:\d\d\.\d+/],
        ['HH:mm:ss,SSSS', /\d\d:\d\d:\d\d,\d+/],
        ['HH:mm:ss', /\d\d:\d\d:\d\d/],
        ['HH:mm', /\d\d:\d\d/],
        ['HHmmss.SSSS', /\d\d\d\d\d\d\.\d+/],
        ['HHmmss,SSSS', /\d\d\d\d\d\d,\d+/],
        ['HHmmss', /\d\d\d\d\d\d/],
        ['HHmm', /\d\d\d\d/],
        ['HH', /\d\d/]
    ];

    var aspNetJsonRegex = /^\/?Date\((\-?\d+)/i;

    // date from iso format
    function configFromISO(config) {
        var i, l,
            string = config._i,
            match = extendedIsoRegex.exec(string) || basicIsoRegex.exec(string),
            allowTime, dateFormat, timeFormat, tzFormat;

        if (match) {
            getParsingFlags(config).iso = true;

            for (i = 0, l = isoDates.length; i < l; i++) {
                if (isoDates[i][1].exec(match[1])) {
                    dateFormat = isoDates[i][0];
                    allowTime = isoDates[i][2] !== false;
                    break;
                }
            }
            if (dateFormat == null) {
                config._isValid = false;
                return;
            }
            if (match[3]) {
                for (i = 0, l = isoTimes.length; i < l; i++) {
                    if (isoTimes[i][1].exec(match[3])) {
                        // match[2] should be 'T' or space
                        timeFormat = (match[2] || ' ') + isoTimes[i][0];
                        break;
                    }
                }
                if (timeFormat == null) {
                    config._isValid = false;
                    return;
                }
            }
            if (!allowTime && timeFormat != null) {
                config._isValid = false;
                return;
            }
            if (match[4]) {
                if (tzRegex.exec(match[4])) {
                    tzFormat = 'Z';
                } else {
                    config._isValid = false;
                    return;
                }
            }
            config._f = dateFormat + (timeFormat || '') + (tzFormat || '');
            configFromStringAndFormat(config);
        } else {
            config._isValid = false;
        }
    }

    // date from iso format or fallback
    function configFromString(config) {
        var matched = aspNetJsonRegex.exec(config._i);

        if (matched !== null) {
            config._d = new Date(+matched[1]);
            return;
        }

        configFromISO(config);
        if (config._isValid === false) {
            delete config._isValid;
            utils_hooks__hooks.createFromInputFallback(config);
        }
    }

    utils_hooks__hooks.createFromInputFallback = deprecate(
        'value provided is not in a recognized ISO format. moment construction falls back to js Date(), ' +
        'which is not reliable across all browsers and versions. Non ISO date formats are ' +
        'discouraged and will be removed in an upcoming major release. Please refer to ' +
        'http://momentjs.com/guides/#/warnings/js-date/ for more info.',
        function (config) {
            config._d = new Date(config._i + (config._useUTC ? ' UTC' : ''));
        }
    );

    // Pick the first defined of two or three arguments.
    function defaults(a, b, c) {
        if (a != null) {
            return a;
        }
        if (b != null) {
            return b;
        }
        return c;
    }

    function currentDateArray(config) {
        // hooks is actually the exported moment object
        var nowValue = new Date(utils_hooks__hooks.now());
        if (config._useUTC) {
            return [nowValue.getUTCFullYear(), nowValue.getUTCMonth(), nowValue.getUTCDate()];
        }
        return [nowValue.getFullYear(), nowValue.getMonth(), nowValue.getDate()];
    }

    // convert an array to a date.
    // the array should mirror the parameters below
    // note: all values past the year are optional and will default to the lowest possible value.
    // [year, month, day , hour, minute, second, millisecond]
    function configFromArray (config) {
        var i, date, input = [], currentDate, yearToUse;

        if (config._d) {
            return;
        }

        currentDate = currentDateArray(config);

        //compute day of the year from weeks and weekdays
        if (config._w && config._a[DATE] == null && config._a[MONTH] == null) {
            dayOfYearFromWeekInfo(config);
        }

        //if the day of the year is set, figure out what it is
        if (config._dayOfYear) {
            yearToUse = defaults(config._a[YEAR], currentDate[YEAR]);

            if (config._dayOfYear > daysInYear(yearToUse)) {
                getParsingFlags(config)._overflowDayOfYear = true;
            }

            date = createUTCDate(yearToUse, 0, config._dayOfYear);
            config._a[MONTH] = date.getUTCMonth();
            config._a[DATE] = date.getUTCDate();
        }

        // Default to current date.
        // * if no year, month, day of month are given, default to today
        // * if day of month is given, default month and year
        // * if month is given, default only year
        // * if year is given, don't default anything
        for (i = 0; i < 3 && config._a[i] == null; ++i) {
            config._a[i] = input[i] = currentDate[i];
        }

        // Zero out whatever was not defaulted, including time
        for (; i < 7; i++) {
            config._a[i] = input[i] = (config._a[i] == null) ? (i === 2 ? 1 : 0) : config._a[i];
        }

        // Check for 24:00:00.000
        if (config._a[HOUR] === 24 &&
                config._a[MINUTE] === 0 &&
                config._a[SECOND] === 0 &&
                config._a[MILLISECOND] === 0) {
            config._nextDay = true;
            config._a[HOUR] = 0;
        }

        config._d = (config._useUTC ? createUTCDate : createDate).apply(null, input);
        // Apply timezone offset from input. The actual utcOffset can be changed
        // with parseZone.
        if (config._tzm != null) {
            config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm);
        }

        if (config._nextDay) {
            config._a[HOUR] = 24;
        }
    }

    function dayOfYearFromWeekInfo(config) {
        var w, weekYear, week, weekday, dow, doy, temp, weekdayOverflow;

        w = config._w;
        if (w.GG != null || w.W != null || w.E != null) {
            dow = 1;
            doy = 4;

            // TODO: We need to take the current isoWeekYear, but that depends on
            // how we interpret now (local, utc, fixed offset). So create
            // a now version of current config (take local/utc/offset flags, and
            // create now).
            weekYear = defaults(w.GG, config._a[YEAR], weekOfYear(local__createLocal(), 1, 4).year);
            week = defaults(w.W, 1);
            weekday = defaults(w.E, 1);
            if (weekday < 1 || weekday > 7) {
                weekdayOverflow = true;
            }
        } else {
            dow = config._locale._week.dow;
            doy = config._locale._week.doy;

            weekYear = defaults(w.gg, config._a[YEAR], weekOfYear(local__createLocal(), dow, doy).year);
            week = defaults(w.w, 1);

            if (w.d != null) {
                // weekday -- low day numbers are considered next week
                weekday = w.d;
                if (weekday < 0 || weekday > 6) {
                    weekdayOverflow = true;
                }
            } else if (w.e != null) {
                // local weekday -- counting starts from begining of week
                weekday = w.e + dow;
                if (w.e < 0 || w.e > 6) {
                    weekdayOverflow = true;
                }
            } else {
                // default to begining of week
                weekday = dow;
            }
        }
        if (week < 1 || week > weeksInYear(weekYear, dow, doy)) {
            getParsingFlags(config)._overflowWeeks = true;
        } else if (weekdayOverflow != null) {
            getParsingFlags(config)._overflowWeekday = true;
        } else {
            temp = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy);
            config._a[YEAR] = temp.year;
            config._dayOfYear = temp.dayOfYear;
        }
    }

    // constant that refers to the ISO standard
    utils_hooks__hooks.ISO_8601 = function () {};

    // date from string and format string
    function configFromStringAndFormat(config) {
        // TODO: Move this to another part of the creation flow to prevent circular deps
        if (config._f === utils_hooks__hooks.ISO_8601) {
            configFromISO(config);
            return;
        }

        config._a = [];
        getParsingFlags(config).empty = true;

        // This array is used to make a Date, either with `new Date` or `Date.UTC`
        var string = '' + config._i,
            i, parsedInput, tokens, token, skipped,
            stringLength = string.length,
            totalParsedInputLength = 0;

        tokens = expandFormat(config._f, config._locale).match(formattingTokens) || [];

        for (i = 0; i < tokens.length; i++) {
            token = tokens[i];
            parsedInput = (string.match(getParseRegexForToken(token, config)) || [])[0];
            // console.log('token', token, 'parsedInput', parsedInput,
            //         'regex', getParseRegexForToken(token, config));
            if (parsedInput) {
                skipped = string.substr(0, string.indexOf(parsedInput));
                if (skipped.length > 0) {
                    getParsingFlags(config).unusedInput.push(skipped);
                }
                string = string.slice(string.indexOf(parsedInput) + parsedInput.length);
                totalParsedInputLength += parsedInput.length;
            }
            // don't parse if it's not a known token
            if (formatTokenFunctions[token]) {
                if (parsedInput) {
                    getParsingFlags(config).empty = false;
                }
                else {
                    getParsingFlags(config).unusedTokens.push(token);
                }
                addTimeToArrayFromToken(token, parsedInput, config);
            }
            else if (config._strict && !parsedInput) {
                getParsingFlags(config).unusedTokens.push(token);
            }
        }

        // add remaining unparsed input length to the string
        getParsingFlags(config).charsLeftOver = stringLength - totalParsedInputLength;
        if (string.length > 0) {
            getParsingFlags(config).unusedInput.push(string);
        }

        // clear _12h flag if hour is <= 12
        if (config._a[HOUR] <= 12 &&
            getParsingFlags(config).bigHour === true &&
            config._a[HOUR] > 0) {
            getParsingFlags(config).bigHour = undefined;
        }

        getParsingFlags(config).parsedDateParts = config._a.slice(0);
        getParsingFlags(config).meridiem = config._meridiem;
        // handle meridiem
        config._a[HOUR] = meridiemFixWrap(config._locale, config._a[HOUR], config._meridiem);

        configFromArray(config);
        checkOverflow(config);
    }


    function meridiemFixWrap (locale, hour, meridiem) {
        var isPm;

        if (meridiem == null) {
            // nothing to do
            return hour;
        }
        if (locale.meridiemHour != null) {
            return locale.meridiemHour(hour, meridiem);
        } else if (locale.isPM != null) {
            // Fallback
            isPm = locale.isPM(meridiem);
            if (isPm && hour < 12) {
                hour += 12;
            }
            if (!isPm && hour === 12) {
                hour = 0;
            }
            return hour;
        } else {
            // this is not supposed to happen
            return hour;
        }
    }

    // date from string and array of format strings
    function configFromStringAndArray(config) {
        var tempConfig,
            bestMoment,

            scoreToBeat,
            i,
            currentScore;

        if (config._f.length === 0) {
            getParsingFlags(config).invalidFormat = true;
            config._d = new Date(NaN);
            return;
        }

        for (i = 0; i < config._f.length; i++) {
            currentScore = 0;
            tempConfig = copyConfig({}, config);
            if (config._useUTC != null) {
                tempConfig._useUTC = config._useUTC;
            }
            tempConfig._f = config._f[i];
            configFromStringAndFormat(tempConfig);

            if (!valid__isValid(tempConfig)) {
                continue;
            }

            // if there is any input that was not parsed add a penalty for that format
            currentScore += getParsingFlags(tempConfig).charsLeftOver;

            //or tokens
            currentScore += getParsingFlags(tempConfig).unusedTokens.length * 10;

            getParsingFlags(tempConfig).score = currentScore;

            if (scoreToBeat == null || currentScore < scoreToBeat) {
                scoreToBeat = currentScore;
                bestMoment = tempConfig;
            }
        }

        extend(config, bestMoment || tempConfig);
    }

    function configFromObject(config) {
        if (config._d) {
            return;
        }

        var i = normalizeObjectUnits(config._i);
        config._a = map([i.year, i.month, i.day || i.date, i.hour, i.minute, i.second, i.millisecond], function (obj) {
            return obj && parseInt(obj, 10);
        });

        configFromArray(config);
    }

    function createFromConfig (config) {
        var res = new Moment(checkOverflow(prepareConfig(config)));
        if (res._nextDay) {
            // Adding is smart enough around DST
            res.add(1, 'd');
            res._nextDay = undefined;
        }

        return res;
    }

    function prepareConfig (config) {
        var input = config._i,
            format = config._f;

        config._locale = config._locale || locale_locales__getLocale(config._l);

        if (input === null || (format === undefined && input === '')) {
            return valid__createInvalid({nullInput: true});
        }

        if (typeof input === 'string') {
            config._i = input = config._locale.preparse(input);
        }

        if (isMoment(input)) {
            return new Moment(checkOverflow(input));
        } else if (isArray(format)) {
            configFromStringAndArray(config);
        } else if (isDate(input)) {
            config._d = input;
        } else if (format) {
            configFromStringAndFormat(config);
        }  else {
            configFromInput(config);
        }

        if (!valid__isValid(config)) {
            config._d = null;
        }

        return config;
    }

    function configFromInput(config) {
        var input = config._i;
        if (input === undefined) {
            config._d = new Date(utils_hooks__hooks.now());
        } else if (isDate(input)) {
            config._d = new Date(input.valueOf());
        } else if (typeof input === 'string') {
            configFromString(config);
        } else if (isArray(input)) {
            config._a = map(input.slice(0), function (obj) {
                return parseInt(obj, 10);
            });
            configFromArray(config);
        } else if (typeof(input) === 'object') {
            configFromObject(config);
        } else if (typeof(input) === 'number') {
            // from milliseconds
            config._d = new Date(input);
        } else {
            utils_hooks__hooks.createFromInputFallback(config);
        }
    }

    function createLocalOrUTC (input, format, locale, strict, isUTC) {
        var c = {};

        if (typeof(locale) === 'boolean') {
            strict = locale;
            locale = undefined;
        }

        if ((isObject(input) && isObjectEmpty(input)) ||
                (isArray(input) && input.length === 0)) {
            input = undefined;
        }
        // object construction must be done this way.
        // https://github.com/moment/moment/issues/1423
        c._isAMomentObject = true;
        c._useUTC = c._isUTC = isUTC;
        c._l = locale;
        c._i = input;
        c._f = format;
        c._strict = strict;

        return createFromConfig(c);
    }

    function local__createLocal (input, format, locale, strict) {
        return createLocalOrUTC(input, format, locale, strict, false);
    }

    var prototypeMin = deprecate(
        'moment().min is deprecated, use moment.max instead. http://momentjs.com/guides/#/warnings/min-max/',
        function () {
            var other = local__createLocal.apply(null, arguments);
            if (this.isValid() && other.isValid()) {
                return other < this ? this : other;
            } else {
                return valid__createInvalid();
            }
        }
    );

    var prototypeMax = deprecate(
        'moment().max is deprecated, use moment.min instead. http://momentjs.com/guides/#/warnings/min-max/',
        function () {
            var other = local__createLocal.apply(null, arguments);
            if (this.isValid() && other.isValid()) {
                return other > this ? this : other;
            } else {
                return valid__createInvalid();
            }
        }
    );

    // Pick a moment m from moments so that m[fn](other) is true for all
    // other. This relies on the function fn to be transitive.
    //
    // moments should either be an array of moment objects or an array, whose
    // first element is an array of moment objects.
    function pickBy(fn, moments) {
        var res, i;
        if (moments.length === 1 && isArray(moments[0])) {
            moments = moments[0];
        }
        if (!moments.length) {
            return local__createLocal();
        }
        res = moments[0];
        for (i = 1; i < moments.length; ++i) {
            if (!moments[i].isValid() || moments[i][fn](res)) {
                res = moments[i];
            }
        }
        return res;
    }

    // TODO: Use [].sort instead?
    function min () {
        var args = [].slice.call(arguments, 0);

        return pickBy('isBefore', args);
    }

    function max () {
        var args = [].slice.call(arguments, 0);

        return pickBy('isAfter', args);
    }

    var now = function () {
        return Date.now ? Date.now() : +(new Date());
    };

    function Duration (duration) {
        var normalizedInput = normalizeObjectUnits(duration),
            years = normalizedInput.year || 0,
            quarters = normalizedInput.quarter || 0,
            months = normalizedInput.month || 0,
            weeks = normalizedInput.week || 0,
            days = normalizedInput.day || 0,
            hours = normalizedInput.hour || 0,
            minutes = normalizedInput.minute || 0,
            seconds = normalizedInput.second || 0,
            milliseconds = normalizedInput.millisecond || 0;

        // representation for dateAddRemove
        this._milliseconds = +milliseconds +
            seconds * 1e3 + // 1000
            minutes * 6e4 + // 1000 * 60
            hours * 1000 * 60 * 60; //using 1000 * 60 * 60 instead of 36e5 to avoid floating point rounding errors https://github.com/moment/moment/issues/2978
        // Because of dateAddRemove treats 24 hours as different from a
        // day when working around DST, we need to store them separately
        this._days = +days +
            weeks * 7;
        // It is impossible translate months into days without knowing
        // which months you are are talking about, so we have to store
        // it separately.
        this._months = +months +
            quarters * 3 +
            years * 12;

        this._data = {};

        this._locale = locale_locales__getLocale();

        this._bubble();
    }

    function isDuration (obj) {
        return obj instanceof Duration;
    }

    function absRound (number) {
        if (number < 0) {
            return Math.round(-1 * number) * -1;
        } else {
            return Math.round(number);
        }
    }

    // FORMATTING

    function offset (token, separator) {
        addFormatToken(token, 0, 0, function () {
            var offset = this.utcOffset();
            var sign = '+';
            if (offset < 0) {
                offset = -offset;
                sign = '-';
            }
            return sign + zeroFill(~~(offset / 60), 2) + separator + zeroFill(~~(offset) % 60, 2);
        });
    }

    offset('Z', ':');
    offset('ZZ', '');

    // PARSING

    addRegexToken('Z',  matchShortOffset);
    addRegexToken('ZZ', matchShortOffset);
    addParseToken(['Z', 'ZZ'], function (input, array, config) {
        config._useUTC = true;
        config._tzm = offsetFromString(matchShortOffset, input);
    });

    // HELPERS

    // timezone chunker
    // '+10:00' > ['10',  '00']
    // '-1530'  > ['-15', '30']
    var chunkOffset = /([\+\-]|\d\d)/gi;

    function offsetFromString(matcher, string) {
        var matches = ((string || '').match(matcher) || []);
        var chunk   = matches[matches.length - 1] || [];
        var parts   = (chunk + '').match(chunkOffset) || ['-', 0, 0];
        var minutes = +(parts[1] * 60) + toInt(parts[2]);

        return parts[0] === '+' ? minutes : -minutes;
    }

    // Return a moment from input, that is local/utc/zone equivalent to model.
    function cloneWithOffset(input, model) {
        var res, diff;
        if (model._isUTC) {
            res = model.clone();
            diff = (isMoment(input) || isDate(input) ? input.valueOf() : local__createLocal(input).valueOf()) - res.valueOf();
            // Use low-level api, because this fn is low-level api.
            res._d.setTime(res._d.valueOf() + diff);
            utils_hooks__hooks.updateOffset(res, false);
            return res;
        } else {
            return local__createLocal(input).local();
        }
    }

    function getDateOffset (m) {
        // On Firefox.24 Date#getTimezoneOffset returns a floating point.
        // https://github.com/moment/moment/pull/1871
        return -Math.round(m._d.getTimezoneOffset() / 15) * 15;
    }

    // HOOKS

    // This function will be called whenever a moment is mutated.
    // It is intended to keep the offset in sync with the timezone.
    utils_hooks__hooks.updateOffset = function () {};

    // MOMENTS

    // keepLocalTime = true means only change the timezone, without
    // affecting the local hour. So 5:31:26 +0300 --[utcOffset(2, true)]-->
    // 5:31:26 +0200 It is possible that 5:31:26 doesn't exist with offset
    // +0200, so we adjust the time as needed, to be valid.
    //
    // Keeping the time actually adds/subtracts (one hour)
    // from the actual represented time. That is why we call updateOffset
    // a second time. In case it wants us to change the offset again
    // _changeInProgress == true case, then we have to adjust, because
    // there is no such time in the given timezone.
    function getSetOffset (input, keepLocalTime) {
        var offset = this._offset || 0,
            localAdjust;
        if (!this.isValid()) {
            return input != null ? this : NaN;
        }
        if (input != null) {
            if (typeof input === 'string') {
                input = offsetFromString(matchShortOffset, input);
            } else if (Math.abs(input) < 16) {
                input = input * 60;
            }
            if (!this._isUTC && keepLocalTime) {
                localAdjust = getDateOffset(this);
            }
            this._offset = input;
            this._isUTC = true;
            if (localAdjust != null) {
                this.add(localAdjust, 'm');
            }
            if (offset !== input) {
                if (!keepLocalTime || this._changeInProgress) {
                    add_subtract__addSubtract(this, create__createDuration(input - offset, 'm'), 1, false);
                } else if (!this._changeInProgress) {
                    this._changeInProgress = true;
                    utils_hooks__hooks.updateOffset(this, true);
                    this._changeInProgress = null;
                }
            }
            return this;
        } else {
            return this._isUTC ? offset : getDateOffset(this);
        }
    }

    function getSetZone (input, keepLocalTime) {
        if (input != null) {
            if (typeof input !== 'string') {
                input = -input;
            }

            this.utcOffset(input, keepLocalTime);

            return this;
        } else {
            return -this.utcOffset();
        }
    }

    function setOffsetToUTC (keepLocalTime) {
        return this.utcOffset(0, keepLocalTime);
    }

    function setOffsetToLocal (keepLocalTime) {
        if (this._isUTC) {
            this.utcOffset(0, keepLocalTime);
            this._isUTC = false;

            if (keepLocalTime) {
                this.subtract(getDateOffset(this), 'm');
            }
        }
        return this;
    }

    function setOffsetToParsedOffset () {
        if (this._tzm) {
            this.utcOffset(this._tzm);
        } else if (typeof this._i === 'string') {
            var tZone = offsetFromString(matchOffset, this._i);

            if (tZone === 0) {
                this.utcOffset(0, true);
            } else {
                this.utcOffset(offsetFromString(matchOffset, this._i));
            }
        }
        return this;
    }

    function hasAlignedHourOffset (input) {
        if (!this.isValid()) {
            return false;
        }
        input = input ? local__createLocal(input).utcOffset() : 0;

        return (this.utcOffset() - input) % 60 === 0;
    }

    function isDaylightSavingTime () {
        return (
            this.utcOffset() > this.clone().month(0).utcOffset() ||
            this.utcOffset() > this.clone().month(5).utcOffset()
        );
    }

    function isDaylightSavingTimeShifted () {
        if (!isUndefined(this._isDSTShifted)) {
            return this._isDSTShifted;
        }

        var c = {};

        copyConfig(c, this);
        c = prepareConfig(c);

        if (c._a) {
            var other = c._isUTC ? create_utc__createUTC(c._a) : local__createLocal(c._a);
            this._isDSTShifted = this.isValid() &&
                compareArrays(c._a, other.toArray()) > 0;
        } else {
            this._isDSTShifted = false;
        }

        return this._isDSTShifted;
    }

    function isLocal () {
        return this.isValid() ? !this._isUTC : false;
    }

    function isUtcOffset () {
        return this.isValid() ? this._isUTC : false;
    }

    function isUtc () {
        return this.isValid() ? this._isUTC && this._offset === 0 : false;
    }

    // ASP.NET json date format regex
    var aspNetRegex = /^(\-)?(?:(\d*)[. ])?(\d+)\:(\d+)(?:\:(\d+)(\.\d*)?)?$/;

    // from http://docs.closure-library.googlecode.com/git/closure_goog_date_date.js.source.html
    // somewhat more in line with 4.4.3.2 2004 spec, but allows decimal anywhere
    // and further modified to allow for strings containing both week and day
    var isoRegex = /^(-)?P(?:(-?[0-9,.]*)Y)?(?:(-?[0-9,.]*)M)?(?:(-?[0-9,.]*)W)?(?:(-?[0-9,.]*)D)?(?:T(?:(-?[0-9,.]*)H)?(?:(-?[0-9,.]*)M)?(?:(-?[0-9,.]*)S)?)?$/;

    function create__createDuration (input, key) {
        var duration = input,
            // matching against regexp is expensive, do it on demand
            match = null,
            sign,
            ret,
            diffRes;

        if (isDuration(input)) {
            duration = {
                ms : input._milliseconds,
                d  : input._days,
                M  : input._months
            };
        } else if (typeof input === 'number') {
            duration = {};
            if (key) {
                duration[key] = input;
            } else {
                duration.milliseconds = input;
            }
        } else if (!!(match = aspNetRegex.exec(input))) {
            sign = (match[1] === '-') ? -1 : 1;
            duration = {
                y  : 0,
                d  : toInt(match[DATE])                         * sign,
                h  : toInt(match[HOUR])                         * sign,
                m  : toInt(match[MINUTE])                       * sign,
                s  : toInt(match[SECOND])                       * sign,
                ms : toInt(absRound(match[MILLISECOND] * 1000)) * sign // the millisecond decimal point is included in the match
            };
        } else if (!!(match = isoRegex.exec(input))) {
            sign = (match[1] === '-') ? -1 : 1;
            duration = {
                y : parseIso(match[2], sign),
                M : parseIso(match[3], sign),
                w : parseIso(match[4], sign),
                d : parseIso(match[5], sign),
                h : parseIso(match[6], sign),
                m : parseIso(match[7], sign),
                s : parseIso(match[8], sign)
            };
        } else if (duration == null) {// checks for null or undefined
            duration = {};
        } else if (typeof duration === 'object' && ('from' in duration || 'to' in duration)) {
            diffRes = momentsDifference(local__createLocal(duration.from), local__createLocal(duration.to));

            duration = {};
            duration.ms = diffRes.milliseconds;
            duration.M = diffRes.months;
        }

        ret = new Duration(duration);

        if (isDuration(input) && hasOwnProp(input, '_locale')) {
            ret._locale = input._locale;
        }

        return ret;
    }

    create__createDuration.fn = Duration.prototype;

    function parseIso (inp, sign) {
        // We'd normally use ~~inp for this, but unfortunately it also
        // converts floats to ints.
        // inp may be undefined, so careful calling replace on it.
        var res = inp && parseFloat(inp.replace(',', '.'));
        // apply sign while we're at it
        return (isNaN(res) ? 0 : res) * sign;
    }

    function positiveMomentsDifference(base, other) {
        var res = {milliseconds: 0, months: 0};

        res.months = other.month() - base.month() +
            (other.year() - base.year()) * 12;
        if (base.clone().add(res.months, 'M').isAfter(other)) {
            --res.months;
        }

        res.milliseconds = +other - +(base.clone().add(res.months, 'M'));

        return res;
    }

    function momentsDifference(base, other) {
        var res;
        if (!(base.isValid() && other.isValid())) {
            return {milliseconds: 0, months: 0};
        }

        other = cloneWithOffset(other, base);
        if (base.isBefore(other)) {
            res = positiveMomentsDifference(base, other);
        } else {
            res = positiveMomentsDifference(other, base);
            res.milliseconds = -res.milliseconds;
            res.months = -res.months;
        }

        return res;
    }

    // TODO: remove 'name' arg after deprecation is removed
    function createAdder(direction, name) {
        return function (val, period) {
            var dur, tmp;
            //invert the arguments, but complain about it
            if (period !== null && !isNaN(+period)) {
                deprecateSimple(name, 'moment().' + name  + '(period, number) is deprecated. Please use moment().' + name + '(number, period). ' +
                'See http://momentjs.com/guides/#/warnings/add-inverted-param/ for more info.');
                tmp = val; val = period; period = tmp;
            }

            val = typeof val === 'string' ? +val : val;
            dur = create__createDuration(val, period);
            add_subtract__addSubtract(this, dur, direction);
            return this;
        };
    }

    function add_subtract__addSubtract (mom, duration, isAdding, updateOffset) {
        var milliseconds = duration._milliseconds,
            days = absRound(duration._days),
            months = absRound(duration._months);

        if (!mom.isValid()) {
            // No op
            return;
        }

        updateOffset = updateOffset == null ? true : updateOffset;

        if (milliseconds) {
            mom._d.setTime(mom._d.valueOf() + milliseconds * isAdding);
        }
        if (days) {
            get_set__set(mom, 'Date', get_set__get(mom, 'Date') + days * isAdding);
        }
        if (months) {
            setMonth(mom, get_set__get(mom, 'Month') + months * isAdding);
        }
        if (updateOffset) {
            utils_hooks__hooks.updateOffset(mom, days || months);
        }
    }

    var add_subtract__add      = createAdder(1, 'add');
    var add_subtract__subtract = createAdder(-1, 'subtract');

    function getCalendarFormat(myMoment, now) {
        var diff = myMoment.diff(now, 'days', true);
        return diff < -6 ? 'sameElse' :
                diff < -1 ? 'lastWeek' :
                diff < 0 ? 'lastDay' :
                diff < 1 ? 'sameDay' :
                diff < 2 ? 'nextDay' :
                diff < 7 ? 'nextWeek' : 'sameElse';
    }

    function moment_calendar__calendar (time, formats) {
        // We want to compare the start of today, vs this.
        // Getting start-of-today depends on whether we're local/utc/offset or not.
        var now = time || local__createLocal(),
            sod = cloneWithOffset(now, this).startOf('day'),
            format = utils_hooks__hooks.calendarFormat(this, sod) || 'sameElse';

        var output = formats && (isFunction(formats[format]) ? formats[format].call(this, now) : formats[format]);

        return this.format(output || this.localeData().calendar(format, this, local__createLocal(now)));
    }

    function clone () {
        return new Moment(this);
    }

    function isAfter (input, units) {
        var localInput = isMoment(input) ? input : local__createLocal(input);
        if (!(this.isValid() && localInput.isValid())) {
            return false;
        }
        units = normalizeUnits(!isUndefined(units) ? units : 'millisecond');
        if (units === 'millisecond') {
            return this.valueOf() > localInput.valueOf();
        } else {
            return localInput.valueOf() < this.clone().startOf(units).valueOf();
        }
    }

    function isBefore (input, units) {
        var localInput = isMoment(input) ? input : local__createLocal(input);
        if (!(this.isValid() && localInput.isValid())) {
            return false;
        }
        units = normalizeUnits(!isUndefined(units) ? units : 'millisecond');
        if (units === 'millisecond') {
            return this.valueOf() < localInput.valueOf();
        } else {
            return this.clone().endOf(units).valueOf() < localInput.valueOf();
        }
    }

    function isBetween (from, to, units, inclusivity) {
        inclusivity = inclusivity || '()';
        return (inclusivity[0] === '(' ? this.isAfter(from, units) : !this.isBefore(from, units)) &&
            (inclusivity[1] === ')' ? this.isBefore(to, units) : !this.isAfter(to, units));
    }

    function isSame (input, units) {
        var localInput = isMoment(input) ? input : local__createLocal(input),
            inputMs;
        if (!(this.isValid() && localInput.isValid())) {
            return false;
        }
        units = normalizeUnits(units || 'millisecond');
        if (units === 'millisecond') {
            return this.valueOf() === localInput.valueOf();
        } else {
            inputMs = localInput.valueOf();
            return this.clone().startOf(units).valueOf() <= inputMs && inputMs <= this.clone().endOf(units).valueOf();
        }
    }

    function isSameOrAfter (input, units) {
        return this.isSame(input, units) || this.isAfter(input,units);
    }

    function isSameOrBefore (input, units) {
        return this.isSame(input, units) || this.isBefore(input,units);
    }

    function diff (input, units, asFloat) {
        var that,
            zoneDelta,
            delta, output;

        if (!this.isValid()) {
            return NaN;
        }

        that = cloneWithOffset(input, this);

        if (!that.isValid()) {
            return NaN;
        }

        zoneDelta = (that.utcOffset() - this.utcOffset()) * 6e4;

        units = normalizeUnits(units);

        if (units === 'year' || units === 'month' || units === 'quarter') {
            output = monthDiff(this, that);
            if (units === 'quarter') {
                output = output / 3;
            } else if (units === 'year') {
                output = output / 12;
            }
        } else {
            delta = this - that;
            output = units === 'second' ? delta / 1e3 : // 1000
                units === 'minute' ? delta / 6e4 : // 1000 * 60
                units === 'hour' ? delta / 36e5 : // 1000 * 60 * 60
                units === 'day' ? (delta - zoneDelta) / 864e5 : // 1000 * 60 * 60 * 24, negate dst
                units === 'week' ? (delta - zoneDelta) / 6048e5 : // 1000 * 60 * 60 * 24 * 7, negate dst
                delta;
        }
        return asFloat ? output : absFloor(output);
    }

    function monthDiff (a, b) {
        // difference in months
        var wholeMonthDiff = ((b.year() - a.year()) * 12) + (b.month() - a.month()),
            // b is in (anchor - 1 month, anchor + 1 month)
            anchor = a.clone().add(wholeMonthDiff, 'months'),
            anchor2, adjust;

        if (b - anchor < 0) {
            anchor2 = a.clone().add(wholeMonthDiff - 1, 'months');
            // linear across the month
            adjust = (b - anchor) / (anchor - anchor2);
        } else {
            anchor2 = a.clone().add(wholeMonthDiff + 1, 'months');
            // linear across the month
            adjust = (b - anchor) / (anchor2 - anchor);
        }

        //check for negative zero, return zero if negative zero
        return -(wholeMonthDiff + adjust) || 0;
    }

    utils_hooks__hooks.defaultFormat = 'YYYY-MM-DDTHH:mm:ssZ';
    utils_hooks__hooks.defaultFormatUtc = 'YYYY-MM-DDTHH:mm:ss[Z]';

    function toString () {
        return this.clone().locale('en').format('ddd MMM DD YYYY HH:mm:ss [GMT]ZZ');
    }

    function moment_format__toISOString () {
        var m = this.clone().utc();
        if (0 < m.year() && m.year() <= 9999) {
            if (isFunction(Date.prototype.toISOString)) {
                // native implementation is ~50x faster, use it when we can
                return this.toDate().toISOString();
            } else {
                return formatMoment(m, 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]');
            }
        } else {
            return formatMoment(m, 'YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]');
        }
    }

    function format (inputString) {
        if (!inputString) {
            inputString = this.isUtc() ? utils_hooks__hooks.defaultFormatUtc : utils_hooks__hooks.defaultFormat;
        }
        var output = formatMoment(this, inputString);
        return this.localeData().postformat(output);
    }

    function from (time, withoutSuffix) {
        if (this.isValid() &&
                ((isMoment(time) && time.isValid()) ||
                 local__createLocal(time).isValid())) {
            return create__createDuration({to: this, from: time}).locale(this.locale()).humanize(!withoutSuffix);
        } else {
            return this.localeData().invalidDate();
        }
    }

    function fromNow (withoutSuffix) {
        return this.from(local__createLocal(), withoutSuffix);
    }

    function to (time, withoutSuffix) {
        if (this.isValid() &&
                ((isMoment(time) && time.isValid()) ||
                 local__createLocal(time).isValid())) {
            return create__createDuration({from: this, to: time}).locale(this.locale()).humanize(!withoutSuffix);
        } else {
            return this.localeData().invalidDate();
        }
    }

    function toNow (withoutSuffix) {
        return this.to(local__createLocal(), withoutSuffix);
    }

    // If passed a locale key, it will set the locale for this
    // instance.  Otherwise, it will return the locale configuration
    // variables for this instance.
    function locale (key) {
        var newLocaleData;

        if (key === undefined) {
            return this._locale._abbr;
        } else {
            newLocaleData = locale_locales__getLocale(key);
            if (newLocaleData != null) {
                this._locale = newLocaleData;
            }
            return this;
        }
    }

    var lang = deprecate(
        'moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.',
        function (key) {
            if (key === undefined) {
                return this.localeData();
            } else {
                return this.locale(key);
            }
        }
    );

    function localeData () {
        return this._locale;
    }

    function startOf (units) {
        units = normalizeUnits(units);
        // the following switch intentionally omits break keywords
        // to utilize falling through the cases.
        switch (units) {
            case 'year':
                this.month(0);
                /* falls through */
            case 'quarter':
            case 'month':
                this.date(1);
                /* falls through */
            case 'week':
            case 'isoWeek':
            case 'day':
            case 'date':
                this.hours(0);
                /* falls through */
            case 'hour':
                this.minutes(0);
                /* falls through */
            case 'minute':
                this.seconds(0);
                /* falls through */
            case 'second':
                this.milliseconds(0);
        }

        // weeks are a special case
        if (units === 'week') {
            this.weekday(0);
        }
        if (units === 'isoWeek') {
            this.isoWeekday(1);
        }

        // quarters are also special
        if (units === 'quarter') {
            this.month(Math.floor(this.month() / 3) * 3);
        }

        return this;
    }

    function endOf (units) {
        units = normalizeUnits(units);
        if (units === undefined || units === 'millisecond') {
            return this;
        }

        // 'date' is an alias for 'day', so it should be considered as such.
        if (units === 'date') {
            units = 'day';
        }

        return this.startOf(units).add(1, (units === 'isoWeek' ? 'week' : units)).subtract(1, 'ms');
    }

    function to_type__valueOf () {
        return this._d.valueOf() - ((this._offset || 0) * 60000);
    }

    function unix () {
        return Math.floor(this.valueOf() / 1000);
    }

    function toDate () {
        return new Date(this.valueOf());
    }

    function toArray () {
        var m = this;
        return [m.year(), m.month(), m.date(), m.hour(), m.minute(), m.second(), m.millisecond()];
    }

    function toObject () {
        var m = this;
        return {
            years: m.year(),
            months: m.month(),
            date: m.date(),
            hours: m.hours(),
            minutes: m.minutes(),
            seconds: m.seconds(),
            milliseconds: m.milliseconds()
        };
    }

    function toJSON () {
        // new Date(NaN).toJSON() === null
        return this.isValid() ? this.toISOString() : null;
    }

    function moment_valid__isValid () {
        return valid__isValid(this);
    }

    function parsingFlags () {
        return extend({}, getParsingFlags(this));
    }

    function invalidAt () {
        return getParsingFlags(this).overflow;
    }

    function creationData() {
        return {
            input: this._i,
            format: this._f,
            locale: this._locale,
            isUTC: this._isUTC,
            strict: this._strict
        };
    }

    // FORMATTING

    addFormatToken(0, ['gg', 2], 0, function () {
        return this.weekYear() % 100;
    });

    addFormatToken(0, ['GG', 2], 0, function () {
        return this.isoWeekYear() % 100;
    });

    function addWeekYearFormatToken (token, getter) {
        addFormatToken(0, [token, token.length], 0, getter);
    }

    addWeekYearFormatToken('gggg',     'weekYear');
    addWeekYearFormatToken('ggggg',    'weekYear');
    addWeekYearFormatToken('GGGG',  'isoWeekYear');
    addWeekYearFormatToken('GGGGG', 'isoWeekYear');

    // ALIASES

    addUnitAlias('weekYear', 'gg');
    addUnitAlias('isoWeekYear', 'GG');

    // PRIORITY

    addUnitPriority('weekYear', 1);
    addUnitPriority('isoWeekYear', 1);


    // PARSING

    addRegexToken('G',      matchSigned);
    addRegexToken('g',      matchSigned);
    addRegexToken('GG',     match1to2, match2);
    addRegexToken('gg',     match1to2, match2);
    addRegexToken('GGGG',   match1to4, match4);
    addRegexToken('gggg',   match1to4, match4);
    addRegexToken('GGGGG',  match1to6, match6);
    addRegexToken('ggggg',  match1to6, match6);

    addWeekParseToken(['gggg', 'ggggg', 'GGGG', 'GGGGG'], function (input, week, config, token) {
        week[token.substr(0, 2)] = toInt(input);
    });

    addWeekParseToken(['gg', 'GG'], function (input, week, config, token) {
        week[token] = utils_hooks__hooks.parseTwoDigitYear(input);
    });

    // MOMENTS

    function getSetWeekYear (input) {
        return getSetWeekYearHelper.call(this,
                input,
                this.week(),
                this.weekday(),
                this.localeData()._week.dow,
                this.localeData()._week.doy);
    }

    function getSetISOWeekYear (input) {
        return getSetWeekYearHelper.call(this,
                input, this.isoWeek(), this.isoWeekday(), 1, 4);
    }

    function getISOWeeksInYear () {
        return weeksInYear(this.year(), 1, 4);
    }

    function getWeeksInYear () {
        var weekInfo = this.localeData()._week;
        return weeksInYear(this.year(), weekInfo.dow, weekInfo.doy);
    }

    function getSetWeekYearHelper(input, week, weekday, dow, doy) {
        var weeksTarget;
        if (input == null) {
            return weekOfYear(this, dow, doy).year;
        } else {
            weeksTarget = weeksInYear(input, dow, doy);
            if (week > weeksTarget) {
                week = weeksTarget;
            }
            return setWeekAll.call(this, input, week, weekday, dow, doy);
        }
    }

    function setWeekAll(weekYear, week, weekday, dow, doy) {
        var dayOfYearData = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy),
            date = createUTCDate(dayOfYearData.year, 0, dayOfYearData.dayOfYear);

        this.year(date.getUTCFullYear());
        this.month(date.getUTCMonth());
        this.date(date.getUTCDate());
        return this;
    }

    // FORMATTING

    addFormatToken('Q', 0, 'Qo', 'quarter');

    // ALIASES

    addUnitAlias('quarter', 'Q');

    // PRIORITY

    addUnitPriority('quarter', 7);

    // PARSING

    addRegexToken('Q', match1);
    addParseToken('Q', function (input, array) {
        array[MONTH] = (toInt(input) - 1) * 3;
    });

    // MOMENTS

    function getSetQuarter (input) {
        return input == null ? Math.ceil((this.month() + 1) / 3) : this.month((input - 1) * 3 + this.month() % 3);
    }

    // FORMATTING

    addFormatToken('D', ['DD', 2], 'Do', 'date');

    // ALIASES

    addUnitAlias('date', 'D');

    // PRIOROITY
    addUnitPriority('date', 9);

    // PARSING

    addRegexToken('D',  match1to2);
    addRegexToken('DD', match1to2, match2);
    addRegexToken('Do', function (isStrict, locale) {
        return isStrict ? locale._ordinalParse : locale._ordinalParseLenient;
    });

    addParseToken(['D', 'DD'], DATE);
    addParseToken('Do', function (input, array) {
        array[DATE] = toInt(input.match(match1to2)[0], 10);
    });

    // MOMENTS

    var getSetDayOfMonth = makeGetSet('Date', true);

    // FORMATTING

    addFormatToken('DDD', ['DDDD', 3], 'DDDo', 'dayOfYear');

    // ALIASES

    addUnitAlias('dayOfYear', 'DDD');

    // PRIORITY
    addUnitPriority('dayOfYear', 4);

    // PARSING

    addRegexToken('DDD',  match1to3);
    addRegexToken('DDDD', match3);
    addParseToken(['DDD', 'DDDD'], function (input, array, config) {
        config._dayOfYear = toInt(input);
    });

    // HELPERS

    // MOMENTS

    function getSetDayOfYear (input) {
        var dayOfYear = Math.round((this.clone().startOf('day') - this.clone().startOf('year')) / 864e5) + 1;
        return input == null ? dayOfYear : this.add((input - dayOfYear), 'd');
    }

    // FORMATTING

    addFormatToken('m', ['mm', 2], 0, 'minute');

    // ALIASES

    addUnitAlias('minute', 'm');

    // PRIORITY

    addUnitPriority('minute', 14);

    // PARSING

    addRegexToken('m',  match1to2);
    addRegexToken('mm', match1to2, match2);
    addParseToken(['m', 'mm'], MINUTE);

    // MOMENTS

    var getSetMinute = makeGetSet('Minutes', false);

    // FORMATTING

    addFormatToken('s', ['ss', 2], 0, 'second');

    // ALIASES

    addUnitAlias('second', 's');

    // PRIORITY

    addUnitPriority('second', 15);

    // PARSING

    addRegexToken('s',  match1to2);
    addRegexToken('ss', match1to2, match2);
    addParseToken(['s', 'ss'], SECOND);

    // MOMENTS

    var getSetSecond = makeGetSet('Seconds', false);

    // FORMATTING

    addFormatToken('S', 0, 0, function () {
        return ~~(this.millisecond() / 100);
    });

    addFormatToken(0, ['SS', 2], 0, function () {
        return ~~(this.millisecond() / 10);
    });

    addFormatToken(0, ['SSS', 3], 0, 'millisecond');
    addFormatToken(0, ['SSSS', 4], 0, function () {
        return this.millisecond() * 10;
    });
    addFormatToken(0, ['SSSSS', 5], 0, function () {
        return this.millisecond() * 100;
    });
    addFormatToken(0, ['SSSSSS', 6], 0, function () {
        return this.millisecond() * 1000;
    });
    addFormatToken(0, ['SSSSSSS', 7], 0, function () {
        return this.millisecond() * 10000;
    });
    addFormatToken(0, ['SSSSSSSS', 8], 0, function () {
        return this.millisecond() * 100000;
    });
    addFormatToken(0, ['SSSSSSSSS', 9], 0, function () {
        return this.millisecond() * 1000000;
    });


    // ALIASES

    addUnitAlias('millisecond', 'ms');

    // PRIORITY

    addUnitPriority('millisecond', 16);

    // PARSING

    addRegexToken('S',    match1to3, match1);
    addRegexToken('SS',   match1to3, match2);
    addRegexToken('SSS',  match1to3, match3);

    var token;
    for (token = 'SSSS'; token.length <= 9; token += 'S') {
        addRegexToken(token, matchUnsigned);
    }

    function parseMs(input, array) {
        array[MILLISECOND] = toInt(('0.' + input) * 1000);
    }

    for (token = 'S'; token.length <= 9; token += 'S') {
        addParseToken(token, parseMs);
    }
    // MOMENTS

    var getSetMillisecond = makeGetSet('Milliseconds', false);

    // FORMATTING

    addFormatToken('z',  0, 0, 'zoneAbbr');
    addFormatToken('zz', 0, 0, 'zoneName');

    // MOMENTS

    function getZoneAbbr () {
        return this._isUTC ? 'UTC' : '';
    }

    function getZoneName () {
        return this._isUTC ? 'Coordinated Universal Time' : '';
    }

    var momentPrototype__proto = Moment.prototype;

    momentPrototype__proto.add               = add_subtract__add;
    momentPrototype__proto.calendar          = moment_calendar__calendar;
    momentPrototype__proto.clone             = clone;
    momentPrototype__proto.diff              = diff;
    momentPrototype__proto.endOf             = endOf;
    momentPrototype__proto.format            = format;
    momentPrototype__proto.from              = from;
    momentPrototype__proto.fromNow           = fromNow;
    momentPrototype__proto.to                = to;
    momentPrototype__proto.toNow             = toNow;
    momentPrototype__proto.get               = stringGet;
    momentPrototype__proto.invalidAt         = invalidAt;
    momentPrototype__proto.isAfter           = isAfter;
    momentPrototype__proto.isBefore          = isBefore;
    momentPrototype__proto.isBetween         = isBetween;
    momentPrototype__proto.isSame            = isSame;
    momentPrototype__proto.isSameOrAfter     = isSameOrAfter;
    momentPrototype__proto.isSameOrBefore    = isSameOrBefore;
    momentPrototype__proto.isValid           = moment_valid__isValid;
    momentPrototype__proto.lang              = lang;
    momentPrototype__proto.locale            = locale;
    momentPrototype__proto.localeData        = localeData;
    momentPrototype__proto.max               = prototypeMax;
    momentPrototype__proto.min               = prototypeMin;
    momentPrototype__proto.parsingFlags      = parsingFlags;
    momentPrototype__proto.set               = stringSet;
    momentPrototype__proto.startOf           = startOf;
    momentPrototype__proto.subtract          = add_subtract__subtract;
    momentPrototype__proto.toArray           = toArray;
    momentPrototype__proto.toObject          = toObject;
    momentPrototype__proto.toDate            = toDate;
    momentPrototype__proto.toISOString       = moment_format__toISOString;
    momentPrototype__proto.toJSON            = toJSON;
    momentPrototype__proto.toString          = toString;
    momentPrototype__proto.unix              = unix;
    momentPrototype__proto.valueOf           = to_type__valueOf;
    momentPrototype__proto.creationData      = creationData;

    // Year
    momentPrototype__proto.year       = getSetYear;
    momentPrototype__proto.isLeapYear = getIsLeapYear;

    // Week Year
    momentPrototype__proto.weekYear    = getSetWeekYear;
    momentPrototype__proto.isoWeekYear = getSetISOWeekYear;

    // Quarter
    momentPrototype__proto.quarter = momentPrototype__proto.quarters = getSetQuarter;

    // Month
    momentPrototype__proto.month       = getSetMonth;
    momentPrototype__proto.daysInMonth = getDaysInMonth;

    // Week
    momentPrototype__proto.week           = momentPrototype__proto.weeks        = getSetWeek;
    momentPrototype__proto.isoWeek        = momentPrototype__proto.isoWeeks     = getSetISOWeek;
    momentPrototype__proto.weeksInYear    = getWeeksInYear;
    momentPrototype__proto.isoWeeksInYear = getISOWeeksInYear;

    // Day
    momentPrototype__proto.date       = getSetDayOfMonth;
    momentPrototype__proto.day        = momentPrototype__proto.days             = getSetDayOfWeek;
    momentPrototype__proto.weekday    = getSetLocaleDayOfWeek;
    momentPrototype__proto.isoWeekday = getSetISODayOfWeek;
    momentPrototype__proto.dayOfYear  = getSetDayOfYear;

    // Hour
    momentPrototype__proto.hour = momentPrototype__proto.hours = getSetHour;

    // Minute
    momentPrototype__proto.minute = momentPrototype__proto.minutes = getSetMinute;

    // Second
    momentPrototype__proto.second = momentPrototype__proto.seconds = getSetSecond;

    // Millisecond
    momentPrototype__proto.millisecond = momentPrototype__proto.milliseconds = getSetMillisecond;

    // Offset
    momentPrototype__proto.utcOffset            = getSetOffset;
    momentPrototype__proto.utc                  = setOffsetToUTC;
    momentPrototype__proto.local                = setOffsetToLocal;
    momentPrototype__proto.parseZone            = setOffsetToParsedOffset;
    momentPrototype__proto.hasAlignedHourOffset = hasAlignedHourOffset;
    momentPrototype__proto.isDST                = isDaylightSavingTime;
    momentPrototype__proto.isLocal              = isLocal;
    momentPrototype__proto.isUtcOffset          = isUtcOffset;
    momentPrototype__proto.isUtc                = isUtc;
    momentPrototype__proto.isUTC                = isUtc;

    // Timezone
    momentPrototype__proto.zoneAbbr = getZoneAbbr;
    momentPrototype__proto.zoneName = getZoneName;

    // Deprecations
    momentPrototype__proto.dates  = deprecate('dates accessor is deprecated. Use date instead.', getSetDayOfMonth);
    momentPrototype__proto.months = deprecate('months accessor is deprecated. Use month instead', getSetMonth);
    momentPrototype__proto.years  = deprecate('years accessor is deprecated. Use year instead', getSetYear);
    momentPrototype__proto.zone   = deprecate('moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/', getSetZone);
    momentPrototype__proto.isDSTShifted = deprecate('isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information', isDaylightSavingTimeShifted);

    var momentPrototype = momentPrototype__proto;

    function moment__createUnix (input) {
        return local__createLocal(input * 1000);
    }

    function moment__createInZone () {
        return local__createLocal.apply(null, arguments).parseZone();
    }

    function preParsePostFormat (string) {
        return string;
    }

    var prototype__proto = Locale.prototype;

    prototype__proto.calendar        = locale_calendar__calendar;
    prototype__proto.longDateFormat  = longDateFormat;
    prototype__proto.invalidDate     = invalidDate;
    prototype__proto.ordinal         = ordinal;
    prototype__proto.preparse        = preParsePostFormat;
    prototype__proto.postformat      = preParsePostFormat;
    prototype__proto.relativeTime    = relative__relativeTime;
    prototype__proto.pastFuture      = pastFuture;
    prototype__proto.set             = locale_set__set;

    // Month
    prototype__proto.months            =        localeMonths;
    prototype__proto.monthsShort       =        localeMonthsShort;
    prototype__proto.monthsParse       =        localeMonthsParse;
    prototype__proto.monthsRegex       = monthsRegex;
    prototype__proto.monthsShortRegex  = monthsShortRegex;

    // Week
    prototype__proto.week = localeWeek;
    prototype__proto.firstDayOfYear = localeFirstDayOfYear;
    prototype__proto.firstDayOfWeek = localeFirstDayOfWeek;

    // Day of Week
    prototype__proto.weekdays       =        localeWeekdays;
    prototype__proto.weekdaysMin    =        localeWeekdaysMin;
    prototype__proto.weekdaysShort  =        localeWeekdaysShort;
    prototype__proto.weekdaysParse  =        localeWeekdaysParse;

    prototype__proto.weekdaysRegex       =        weekdaysRegex;
    prototype__proto.weekdaysShortRegex  =        weekdaysShortRegex;
    prototype__proto.weekdaysMinRegex    =        weekdaysMinRegex;

    // Hours
    prototype__proto.isPM = localeIsPM;
    prototype__proto.meridiem = localeMeridiem;

    function lists__get (format, index, field, setter) {
        var locale = locale_locales__getLocale();
        var utc = create_utc__createUTC().set(setter, index);
        return locale[field](utc, format);
    }

    function listMonthsImpl (format, index, field) {
        if (typeof format === 'number') {
            index = format;
            format = undefined;
        }

        format = format || '';

        if (index != null) {
            return lists__get(format, index, field, 'month');
        }

        var i;
        var out = [];
        for (i = 0; i < 12; i++) {
            out[i] = lists__get(format, i, field, 'month');
        }
        return out;
    }

    // ()
    // (5)
    // (fmt, 5)
    // (fmt)
    // (true)
    // (true, 5)
    // (true, fmt, 5)
    // (true, fmt)
    function listWeekdaysImpl (localeSorted, format, index, field) {
        if (typeof localeSorted === 'boolean') {
            if (typeof format === 'number') {
                index = format;
                format = undefined;
            }

            format = format || '';
        } else {
            format = localeSorted;
            index = format;
            localeSorted = false;

            if (typeof format === 'number') {
                index = format;
                format = undefined;
            }

            format = format || '';
        }

        var locale = locale_locales__getLocale(),
            shift = localeSorted ? locale._week.dow : 0;

        if (index != null) {
            return lists__get(format, (index + shift) % 7, field, 'day');
        }

        var i;
        var out = [];
        for (i = 0; i < 7; i++) {
            out[i] = lists__get(format, (i + shift) % 7, field, 'day');
        }
        return out;
    }

    function lists__listMonths (format, index) {
        return listMonthsImpl(format, index, 'months');
    }

    function lists__listMonthsShort (format, index) {
        return listMonthsImpl(format, index, 'monthsShort');
    }

    function lists__listWeekdays (localeSorted, format, index) {
        return listWeekdaysImpl(localeSorted, format, index, 'weekdays');
    }

    function lists__listWeekdaysShort (localeSorted, format, index) {
        return listWeekdaysImpl(localeSorted, format, index, 'weekdaysShort');
    }

    function lists__listWeekdaysMin (localeSorted, format, index) {
        return listWeekdaysImpl(localeSorted, format, index, 'weekdaysMin');
    }

    locale_locales__getSetGlobalLocale('en', {
        ordinalParse: /\d{1,2}(th|st|nd|rd)/,
        ordinal : function (number) {
            var b = number % 10,
                output = (toInt(number % 100 / 10) === 1) ? 'th' :
                (b === 1) ? 'st' :
                (b === 2) ? 'nd' :
                (b === 3) ? 'rd' : 'th';
            return number + output;
        }
    });

    // Side effect imports
    utils_hooks__hooks.lang = deprecate('moment.lang is deprecated. Use moment.locale instead.', locale_locales__getSetGlobalLocale);
    utils_hooks__hooks.langData = deprecate('moment.langData is deprecated. Use moment.localeData instead.', locale_locales__getLocale);

    var mathAbs = Math.abs;

    function duration_abs__abs () {
        var data           = this._data;

        this._milliseconds = mathAbs(this._milliseconds);
        this._days         = mathAbs(this._days);
        this._months       = mathAbs(this._months);

        data.milliseconds  = mathAbs(data.milliseconds);
        data.seconds       = mathAbs(data.seconds);
        data.minutes       = mathAbs(data.minutes);
        data.hours         = mathAbs(data.hours);
        data.months        = mathAbs(data.months);
        data.years         = mathAbs(data.years);

        return this;
    }

    function duration_add_subtract__addSubtract (duration, input, value, direction) {
        var other = create__createDuration(input, value);

        duration._milliseconds += direction * other._milliseconds;
        duration._days         += direction * other._days;
        duration._months       += direction * other._months;

        return duration._bubble();
    }

    // supports only 2.0-style add(1, 's') or add(duration)
    function duration_add_subtract__add (input, value) {
        return duration_add_subtract__addSubtract(this, input, value, 1);
    }

    // supports only 2.0-style subtract(1, 's') or subtract(duration)
    function duration_add_subtract__subtract (input, value) {
        return duration_add_subtract__addSubtract(this, input, value, -1);
    }

    function absCeil (number) {
        if (number < 0) {
            return Math.floor(number);
        } else {
            return Math.ceil(number);
        }
    }

    function bubble () {
        var milliseconds = this._milliseconds;
        var days         = this._days;
        var months       = this._months;
        var data         = this._data;
        var seconds, minutes, hours, years, monthsFromDays;

        // if we have a mix of positive and negative values, bubble down first
        // check: https://github.com/moment/moment/issues/2166
        if (!((milliseconds >= 0 && days >= 0 && months >= 0) ||
                (milliseconds <= 0 && days <= 0 && months <= 0))) {
            milliseconds += absCeil(monthsToDays(months) + days) * 864e5;
            days = 0;
            months = 0;
        }

        // The following code bubbles up values, see the tests for
        // examples of what that means.
        data.milliseconds = milliseconds % 1000;

        seconds           = absFloor(milliseconds / 1000);
        data.seconds      = seconds % 60;

        minutes           = absFloor(seconds / 60);
        data.minutes      = minutes % 60;

        hours             = absFloor(minutes / 60);
        data.hours        = hours % 24;

        days += absFloor(hours / 24);

        // convert days to months
        monthsFromDays = absFloor(daysToMonths(days));
        months += monthsFromDays;
        days -= absCeil(monthsToDays(monthsFromDays));

        // 12 months -> 1 year
        years = absFloor(months / 12);
        months %= 12;

        data.days   = days;
        data.months = months;
        data.years  = years;

        return this;
    }

    function daysToMonths (days) {
        // 400 years have 146097 days (taking into account leap year rules)
        // 400 years have 12 months === 4800
        return days * 4800 / 146097;
    }

    function monthsToDays (months) {
        // the reverse of daysToMonths
        return months * 146097 / 4800;
    }

    function as (units) {
        var days;
        var months;
        var milliseconds = this._milliseconds;

        units = normalizeUnits(units);

        if (units === 'month' || units === 'year') {
            days   = this._days   + milliseconds / 864e5;
            months = this._months + daysToMonths(days);
            return units === 'month' ? months : months / 12;
        } else {
            // handle milliseconds separately because of floating point math errors (issue #1867)
            days = this._days + Math.round(monthsToDays(this._months));
            switch (units) {
                case 'week'   : return days / 7     + milliseconds / 6048e5;
                case 'day'    : return days         + milliseconds / 864e5;
                case 'hour'   : return days * 24    + milliseconds / 36e5;
                case 'minute' : return days * 1440  + milliseconds / 6e4;
                case 'second' : return days * 86400 + milliseconds / 1000;
                // Math.floor prevents floating point math errors here
                case 'millisecond': return Math.floor(days * 864e5) + milliseconds;
                default: throw new Error('Unknown unit ' + units);
            }
        }
    }

    // TODO: Use this.as('ms')?
    function duration_as__valueOf () {
        return (
            this._milliseconds +
            this._days * 864e5 +
            (this._months % 12) * 2592e6 +
            toInt(this._months / 12) * 31536e6
        );
    }

    function makeAs (alias) {
        return function () {
            return this.as(alias);
        };
    }

    var asMilliseconds = makeAs('ms');
    var asSeconds      = makeAs('s');
    var asMinutes      = makeAs('m');
    var asHours        = makeAs('h');
    var asDays         = makeAs('d');
    var asWeeks        = makeAs('w');
    var asMonths       = makeAs('M');
    var asYears        = makeAs('y');

    function duration_get__get (units) {
        units = normalizeUnits(units);
        return this[units + 's']();
    }

    function makeGetter(name) {
        return function () {
            return this._data[name];
        };
    }

    var milliseconds = makeGetter('milliseconds');
    var seconds      = makeGetter('seconds');
    var minutes      = makeGetter('minutes');
    var hours        = makeGetter('hours');
    var days         = makeGetter('days');
    var months       = makeGetter('months');
    var years        = makeGetter('years');

    function weeks () {
        return absFloor(this.days() / 7);
    }

    var round = Math.round;
    var thresholds = {
        s: 45,  // seconds to minute
        m: 45,  // minutes to hour
        h: 22,  // hours to day
        d: 26,  // days to month
        M: 11   // months to year
    };

    // helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize
    function substituteTimeAgo(string, number, withoutSuffix, isFuture, locale) {
        return locale.relativeTime(number || 1, !!withoutSuffix, string, isFuture);
    }

    function duration_humanize__relativeTime (posNegDuration, withoutSuffix, locale) {
        var duration = create__createDuration(posNegDuration).abs();
        var seconds  = round(duration.as('s'));
        var minutes  = round(duration.as('m'));
        var hours    = round(duration.as('h'));
        var days     = round(duration.as('d'));
        var months   = round(duration.as('M'));
        var years    = round(duration.as('y'));

        var a = seconds < thresholds.s && ['s', seconds]  ||
                minutes <= 1           && ['m']           ||
                minutes < thresholds.m && ['mm', minutes] ||
                hours   <= 1           && ['h']           ||
                hours   < thresholds.h && ['hh', hours]   ||
                days    <= 1           && ['d']           ||
                days    < thresholds.d && ['dd', days]    ||
                months  <= 1           && ['M']           ||
                months  < thresholds.M && ['MM', months]  ||
                years   <= 1           && ['y']           || ['yy', years];

        a[2] = withoutSuffix;
        a[3] = +posNegDuration > 0;
        a[4] = locale;
        return substituteTimeAgo.apply(null, a);
    }

    // This function allows you to set the rounding function for relative time strings
    function duration_humanize__getSetRelativeTimeRounding (roundingFunction) {
        if (roundingFunction === undefined) {
            return round;
        }
        if (typeof(roundingFunction) === 'function') {
            round = roundingFunction;
            return true;
        }
        return false;
    }

    // This function allows you to set a threshold for relative time strings
    function duration_humanize__getSetRelativeTimeThreshold (threshold, limit) {
        if (thresholds[threshold] === undefined) {
            return false;
        }
        if (limit === undefined) {
            return thresholds[threshold];
        }
        thresholds[threshold] = limit;
        return true;
    }

    function humanize (withSuffix) {
        var locale = this.localeData();
        var output = duration_humanize__relativeTime(this, !withSuffix, locale);

        if (withSuffix) {
            output = locale.pastFuture(+this, output);
        }

        return locale.postformat(output);
    }

    var iso_string__abs = Math.abs;

    function iso_string__toISOString() {
        // for ISO strings we do not use the normal bubbling rules:
        //  * milliseconds bubble up until they become hours
        //  * days do not bubble at all
        //  * months bubble up until they become years
        // This is because there is no context-free conversion between hours and days
        // (think of clock changes)
        // and also not between days and months (28-31 days per month)
        var seconds = iso_string__abs(this._milliseconds) / 1000;
        var days         = iso_string__abs(this._days);
        var months       = iso_string__abs(this._months);
        var minutes, hours, years;

        // 3600 seconds -> 60 minutes -> 1 hour
        minutes           = absFloor(seconds / 60);
        hours             = absFloor(minutes / 60);
        seconds %= 60;
        minutes %= 60;

        // 12 months -> 1 year
        years  = absFloor(months / 12);
        months %= 12;


        // inspired by https://github.com/dordille/moment-isoduration/blob/master/moment.isoduration.js
        var Y = years;
        var M = months;
        var D = days;
        var h = hours;
        var m = minutes;
        var s = seconds;
        var total = this.asSeconds();

        if (!total) {
            // this is the same as C#'s (Noda) and python (isodate)...
            // but not other JS (goog.date)
            return 'P0D';
        }

        return (total < 0 ? '-' : '') +
            'P' +
            (Y ? Y + 'Y' : '') +
            (M ? M + 'M' : '') +
            (D ? D + 'D' : '') +
            ((h || m || s) ? 'T' : '') +
            (h ? h + 'H' : '') +
            (m ? m + 'M' : '') +
            (s ? s + 'S' : '');
    }

    var duration_prototype__proto = Duration.prototype;

    duration_prototype__proto.abs            = duration_abs__abs;
    duration_prototype__proto.add            = duration_add_subtract__add;
    duration_prototype__proto.subtract       = duration_add_subtract__subtract;
    duration_prototype__proto.as             = as;
    duration_prototype__proto.asMilliseconds = asMilliseconds;
    duration_prototype__proto.asSeconds      = asSeconds;
    duration_prototype__proto.asMinutes      = asMinutes;
    duration_prototype__proto.asHours        = asHours;
    duration_prototype__proto.asDays         = asDays;
    duration_prototype__proto.asWeeks        = asWeeks;
    duration_prototype__proto.asMonths       = asMonths;
    duration_prototype__proto.asYears        = asYears;
    duration_prototype__proto.valueOf        = duration_as__valueOf;
    duration_prototype__proto._bubble        = bubble;
    duration_prototype__proto.get            = duration_get__get;
    duration_prototype__proto.milliseconds   = milliseconds;
    duration_prototype__proto.seconds        = seconds;
    duration_prototype__proto.minutes        = minutes;
    duration_prototype__proto.hours          = hours;
    duration_prototype__proto.days           = days;
    duration_prototype__proto.weeks          = weeks;
    duration_prototype__proto.months         = months;
    duration_prototype__proto.years          = years;
    duration_prototype__proto.humanize       = humanize;
    duration_prototype__proto.toISOString    = iso_string__toISOString;
    duration_prototype__proto.toString       = iso_string__toISOString;
    duration_prototype__proto.toJSON         = iso_string__toISOString;
    duration_prototype__proto.locale         = locale;
    duration_prototype__proto.localeData     = localeData;

    // Deprecations
    duration_prototype__proto.toIsoString = deprecate('toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)', iso_string__toISOString);
    duration_prototype__proto.lang = lang;

    // Side effect imports

    // FORMATTING

    addFormatToken('X', 0, 0, 'unix');
    addFormatToken('x', 0, 0, 'valueOf');

    // PARSING

    addRegexToken('x', matchSigned);
    addRegexToken('X', matchTimestamp);
    addParseToken('X', function (input, array, config) {
        config._d = new Date(parseFloat(input, 10) * 1000);
    });
    addParseToken('x', function (input, array, config) {
        config._d = new Date(toInt(input));
    });

    // Side effect imports


    utils_hooks__hooks.version = '2.15.0';

    setHookCallback(local__createLocal);

    utils_hooks__hooks.fn                    = momentPrototype;
    utils_hooks__hooks.min                   = min;
    utils_hooks__hooks.max                   = max;
    utils_hooks__hooks.now                   = now;
    utils_hooks__hooks.utc                   = create_utc__createUTC;
    utils_hooks__hooks.unix                  = moment__createUnix;
    utils_hooks__hooks.months                = lists__listMonths;
    utils_hooks__hooks.isDate                = isDate;
    utils_hooks__hooks.locale                = locale_locales__getSetGlobalLocale;
    utils_hooks__hooks.invalid               = valid__createInvalid;
    utils_hooks__hooks.duration              = create__createDuration;
    utils_hooks__hooks.isMoment              = isMoment;
    utils_hooks__hooks.weekdays              = lists__listWeekdays;
    utils_hooks__hooks.parseZone             = moment__createInZone;
    utils_hooks__hooks.localeData            = locale_locales__getLocale;
    utils_hooks__hooks.isDuration            = isDuration;
    utils_hooks__hooks.monthsShort           = lists__listMonthsShort;
    utils_hooks__hooks.weekdaysMin           = lists__listWeekdaysMin;
    utils_hooks__hooks.defineLocale          = defineLocale;
    utils_hooks__hooks.updateLocale          = updateLocale;
    utils_hooks__hooks.locales               = locale_locales__listLocales;
    utils_hooks__hooks.weekdaysShort         = lists__listWeekdaysShort;
    utils_hooks__hooks.normalizeUnits        = normalizeUnits;
    utils_hooks__hooks.relativeTimeRounding = duration_humanize__getSetRelativeTimeRounding;
    utils_hooks__hooks.relativeTimeThreshold = duration_humanize__getSetRelativeTimeThreshold;
    utils_hooks__hooks.calendarFormat        = getCalendarFormat;
    utils_hooks__hooks.prototype             = momentPrototype;

    var _moment = utils_hooks__hooks;

    return _moment;

}));
},{}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypalrest-manticore/build/index.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

var _PayPalREST = require('./src/PayPalREST');

Object.defineProperty(exports, 'PayPalREST', {
  enumerable: true,
  get: function get() {
    return _interopRequireDefault(_PayPalREST).default;
  }
});

var _restError = require('./src/restError');

Object.defineProperty(exports, 'restError', {
  enumerable: true,
  get: function get() {
    return _restError.restError;
  }
});
Object.defineProperty(exports, 'paypalRestErrorDomain', {
  enumerable: true,
  get: function get() {
    return _restError.paypalRestErrorDomain;
  }
});

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
},{"./src/PayPalREST":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypalrest-manticore/build/src/PayPalREST.js","./src/restError":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypalrest-manticore/build/src/restError.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypalrest-manticore/build/src/PayPalREST.js":[function(require,module,exports){
(function (Buffer){
'use strict';

exports.__esModule = true;

var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };

var _manticore = require('manticore');

var _manticore2 = _interopRequireDefault(_manticore);

var _manticoreLog = require('manticore-log');

var _manticoreLog2 = _interopRequireDefault(_manticoreLog);

var _restError = require('./restError');

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } /* eslint-disable no-param-reassign */

var Log = (0, _manticoreLog2.default)('paypalRest');

/**
 * An object that manages network calls to authenticated PayPal services. It will automatically refresh
 * expired access tokens and retry as appropriate. It also provides a "url resolution" infrastructure
 * to let callers specify services and operations to be intepreted in the context of an environment
 * to generate a URL for a service call rather than just hand coding all the service endpoints.
 * @class
 */

var PayPalREST = function () {

  /**
   * Construct a PayPalREST object from a "token blob" format which contains
   * an environment specifier, access token, and refresh url (typically)
   * @param {string} token The token blob usually from a mid tier server
   */
  PayPalREST.fromToken = function fromToken(token) {
    var parsedToken = void 0;
    try {
      if (token && token[0] === '{') {
        parsedToken = JSON.parse(token);
      } else {
        var parts = (token || '').split(':', 2);
        if (parts.length !== 2) {
          throw new Error('Invalid token presented (off by ' + (parts.length - 2) + ')');
        }
        var unpacked = new Buffer(parts[1], 'base64');
        var infoArray = JSON.parse(unpacked.toString('utf8'));
        parsedToken = {
          env: parts[0],
          access_token: infoArray[0],
          expires_in: infoArray[1],
          refresh_url: infoArray[2]
        };
        if (!infoArray[2] && parts[0] !== 'live' && infoArray.length >= 5) {
          parsedToken.app = {
            auth: infoArray[4]
          };
          parsedToken.rt = infoArray[3];
        }
      }
      var api = new PayPalREST(parsedToken.access_token, parsedToken.refresh_url, parsedToken.expires_in);
      api.env = parsedToken.env;
      if (parsedToken.app && parsedToken.rt) {
        api.app = parsedToken.app;
        api.rt = parsedToken.rt;
      }
      return api;
    } catch (x) {
      Log.error('Could not read token: ' + x.message + '\n' + x.stack);
      throw _restError.restError.invalidToken.withDevMessage(x.message);
    }
  };

  /**
   * Build a REST interface with access token, refresh url and optional expiration time
   * @constructor
   * @param {string} accessToken The access token
   * @param {string} refreshUrl The URL to hit to refresh the token
   * @param {string} expiresIn An optional time offset (from now, in msec) when the access token will expire
   */


  function PayPalREST(accessToken, refreshUrl, expiresIn) {
    var _this = this;

    _classCallCheck(this, PayPalREST);

    this.resolvers = {
      token: function token(self, opts) {
        if (_this.env === PayPalREST.Env.LIVE) {
          return 'https://api.paypal.com/v1/oauth2/' + opts.op;
        } else if (_this.env === PayPalREST.Env.SANDBOX) {
          return 'https://api.sandbox.paypal.com/v1/oauth2/' + opts.op;
        } else if (_this.env === PayPalREST.Env.MSMASTER) {
          return 'https://www.msmaster.qa.paypal.com/v1/oauth2/' + opts.op;
        }
        return 'https://www.' + _this.env + '.stage.paypal.com:11888/v1/oauth2/' + opts.op;
      },
      invoicing: function invoicing(self, opts) {
        if (_this.env === PayPalREST.Env.LIVE) {
          return 'https://api.paypal.com/v1/invoicing/' + opts.op;
        } else if (_this.env === PayPalREST.Env.SANDBOX) {
          return 'https://api.sandbox.paypal.com/v1/invoicing/' + opts.op;
        } else if (_this.env === PayPalREST.Env.MSMASTER) {
          return 'https://www.msmaster.qa.paypal.com/v1/invoicing/' + opts.op;
        }
        return 'https://www.' + _this.env + '.stage.paypal.com:11888/v1/invoicing/' + opts.op;
      },
      contactserv: function contactserv(self, opts) {
        if (_this.env === PayPalREST.Env.LIVE) {
          return 'https://api.paypal.com/v1/customer/contacts/' + opts.op;
        } else if (_this.env === PayPalREST.Env.SANDBOX) {
          return 'https://api.sandbox.paypal.com/v1/customer/contacts/' + opts.op;
        } else if (_this.env === PayPalREST.Env.MSMASTER) {
          return 'https://www.msmaster.qa.paypal.com/v1/customer/contacts/' + opts.op;
        }
        return 'https://www.' + _this.env + '.stage.paypal.com:11888/v1/customer/contacts/' + opts.op;
      }
    };
    this.env = PayPalREST.Env.LIVE;
    this.cbs = [];
    this.at = accessToken;
    this.refreshUrl = refreshUrl;
    this.exp = expiresIn;
  }

  /**
   * Add a resolver for a given service
   * @param {string} service The name of the service this resolver will resolve.
   * @param {PayPalRest#serviceResolver} fn The function that will be called to get the URL for the operation
   */


  PayPalREST.prototype.addResolver = function addResolver(service, fn) {
    this.resolvers[service] = fn;
  };

  /**
   * Injects Device Information if provided by the manticore object
   * @param {object} options The options on the request, in which you typically
   */


  PayPalREST.prototype.injectDeviceInfo = function injectDeviceInfo(options) {
    if (_manticore2.default.deviceInfo && _manticore2.default.deviceInfo() != null) {
      var deviceInfo = _manticore2.default.deviceInfo();

      if (typeof deviceInfo === 'string') {
        options.headers['X-PAYPAL-REQUEST-SOURCE'] = deviceInfo;
      } else if (Array.isArray(deviceInfo)) {
        options.headers['X-PAYPAL-REQUEST-SOURCE'] = deviceInfo.join('_');
      } else if ((typeof deviceInfo === 'undefined' ? 'undefined' : _typeof(deviceInfo)) === 'object') {
        for (var key in deviceInfo) {
          // Don't overwrite existing keys
          if (!(key in options.headers)) {
            options.headers[key] = deviceInfo[key];
          }
        }
      }
    }
  };

  PayPalREST.prototype.request = function request(options, callback) {
    var _this2 = this;

    if (!options) {
      var error = _restError.restError.invalidRequest.withDevMessage('Request options was empty');
      Log.error('Empty options: ' + error.stack);
      callback(error, null);
      return;
    }

    if (!options.url) {
      if (!options.service || !this.resolvers[options.service]) {
        var opError = _restError.restError.invalidRequest.withDevMessage('Options has no url and no resolvable service.');
        Log.error('Bad options: ' + opError.stack);
        callback(opError, null);
        return;
      }
      options.url = this.resolvers[options.service](this, options);
    }

    if (!this.at && !this.refreshUrl) {
      callback(_restError.restError.invalidCompositeToken.withDevMessage('The access token is invalid and does not include an access token or refresh url'), null);
      return;
    }
    if (!this.at) {
      // Refresh right away
      this.refresh(function (refreshError) {
        if (refreshError) {
          callback(refreshError, null);
          return;
        }
        _this2.request(options, callback);
      });
      return;
    }

    options.headers = options.headers || {};
    options.headers.Authorization = 'Bearer ' + this.at;

    this.injectDeviceInfo(options);

    var start = new Date().getTime();
    _manticore2.default.http(options, function (error, response) {
      try {
        var end = new Date().getTime();
        var elapsed = end - start;
        Log.debug(function () {
          return (options.method || 'GET') + ' ' + options.url + ' (' + elapsed + 'ms): ' + (response ? response.statusCode : error);
        });
        if (error) {
          Log.error('Authenticated request error: ' + error.message + '\n' + error.stack);
          Log.debug(function () {
            return 'Erred request: ' + JSON.stringify(options) + '\nresponse: ' + JSON.stringify(response);
          });
          callback(error, null);
          return;
        }
        var needsRefresh = response && (response.statusCode === 401 || response.statusCode === 403) && !options._tried;
        if (needsRefresh) {
          Log.debug(function () {
            return 'Authorization error - Request: ' + JSON.stringify(options) + '\nresponse: ' + JSON.stringify(response);
          });
          if (_this2._canRefreshToken()) {
            options._tried = true;
            _this2.refresh(function (refreshError) {
              if (refreshError) {
                callback(refreshError, null);
                return;
              }
              _this2.request(options, callback);
            });
          } else {
            Log.warn('Token expired and token refresh information not provided for ' + options.url);
            var e = _restError.restError.unauthorized.withDevMessage('Merchant token had no "refreshUrl" property, cannot refresh access token.');
            callback(e, response);
          }
          return;
        }
        if (options.format === 'json' && !options.rawError) {
          if (response && response.body) {
            if (response.body.errorCode) {
              // HereApi style errors
              error = (0, _restError.payPalError)(response.body.errorCode, response.body.message, response.body.correlationId);
            } else if (response.statusCode && response.statusCode >= 300) {
              // PlatformApiServ style errors
              var message = response.body.message;
              var code = response.body.name || response.statusCode;
              var debugId = PayPalREST.getPlatformapiservDebugId(response);
              error = (0, _restError.payPalError)(code, message, debugId);
              if (response.body.details) {
                error.details = response.body.details;
              }
            }
          }
          if (response.statusCode >= 400 && !error) {
            // Handle the case where the server returned a failing HTTP status, but no error in the body.
            error = (0, _restError.payPalError)(response.statusCode);
          }
          if (error) {
            error.domain = options.service;
            PayPalREST.generateDevMessage(error);
            Log.error('Received error (' + error.developerMessage + ')');
          }
        }
      } catch (x) {
        Log.error('Merchant request failure: ' + (x.message || x) + '\n' + x.stack);
        error = x;
      }
      if (callback) {
        callback(error, response);
      }
    });
  };

  PayPalREST.prototype._canRefreshToken = function _canRefreshToken() {
    return this.refreshUrl || this.rt && this.app;
  };

  PayPalREST.prototype.refresh = function refresh(callback) {
    var _this3 = this;

    if (this.cbs.length) {
      this.cbs.push(callback);
      return;
    }
    this.cbs.push(callback);

    if (!this.refreshUrl && this.rt && this.app) {
      Log.debug('Attempting a direct token refresh');
      var rqBody = 'grant_type=refresh_token&response_type=token&refresh_token=' + encodeURIComponent(this.rt);
      _manticore2.default.http({
        url: this.resolvers.token(this, { op: 'token' }),
        headers: {
          Authorization: 'Basic ' + this.app.auth,
          'Content-Type': 'application/x-www-form-urlencoded'
        },
        method: 'POST',
        format: 'json',
        body: rqBody,
        timeout: 15000
      }, function (e, rz) {
        if (rz && rz.body && rz.body.access_token) {
          _this3.at = rz.body.access_token;
          Log.debug('Successfully refreshed token.');
        } else if (!e) {
          Log.error('Invalid response from token refresh');
          e = _restError.restError.unauthorized.withDevMessage('Invalid response from token refresh');
        }
        if (e) {
          var rzDesc = JSON.stringify(rz || {});
          Log.error('Failed to directly refresh token: ' + e.message + ': ' + rzDesc);
        }
        for (var _iterator = _this3.cbs, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
          var _ref;

          if (_isArray) {
            if (_i >= _iterator.length) break;
            _ref = _iterator[_i++];
          } else {
            _i = _iterator.next();
            if (_i.done) break;
            _ref = _i.value;
          }

          var cb = _ref;

          try {
            cb(e);
          } catch (x) {
            Log.warn('Error executing callback function ' + x.message);
          }
        }
        _this3.cbs = [];
      });
      return;
    }

    Log.debug('Attempting a token refresh');
    _manticore2.default.http({
      url: this.refreshUrl,
      format: 'json'
    }, function (error, rz) {
      if (rz && rz.body && rz.body.access_token) {
        _this3.at = rz.body.access_token;
        _this3.refreshUrl = rz.body.refresh_url || _this3.refreshUrl;
        Log.debug('Successfully refreshed token.');
      } else if (!error) {
        error = _restError.restError.unauthorized.withDevMessage('Invalid response from refreshUrl');
      }
      if (error) {
        var rzDesc = JSON.stringify(rz || {});
        Log.error('Failed to refresh token: ' + error.message + ': ' + rzDesc);
      }
      for (var _iterator2 = _this3.cbs, _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) {
        var _ref2;

        if (_isArray2) {
          if (_i2 >= _iterator2.length) break;
          _ref2 = _iterator2[_i2++];
        } else {
          _i2 = _iterator2.next();
          if (_i2.done) break;
          _ref2 = _i2.value;
        }

        var cb = _ref2;

        try {
          cb(error);
        } catch (x) {
          Log.warn('Error executing callback function ' + x.message);
        }
      }
      _this3.cbs = [];
    });
  };

  PayPalREST.getPlatformapiservDebugId = function getPlatformapiservDebugId(response) {
    var headers = response.headers;
    if (response.body.debug_id) {
      return response.body.debug_id;
    } else if (headers.debug_id) {
      return headers.debug_id;
    }
    return headers['correlation-id'] || headers['CORRELATION-ID'];
  };

  PayPalREST.generateDevMessage = function generateDevMessage(error) {
    if (!error) {
      return error;
    }

    var devMessage = '';
    function appendToDevMessage(key, str) {
      if (devMessage.length) {
        devMessage += ', ';
      }
      devMessage += key + ': ';
      if (str && str.length) {
        devMessage += str;
      }
    }

    appendToDevMessage('domain', error.domain);
    appendToDevMessage('code', error.code);
    appendToDevMessage('message', error.message);
    appendToDevMessage('debugId', error.debugId);

    var details = '';
    if (error.details && Array.isArray(error.details) && error.details.length > 0) {
      error.details.forEach(function (obj) {
        if (details.length) {
          details += ' ';
        }
        details += obj.field + ' ' + obj.issue;
      });
    }
    appendToDevMessage('details', details);
    error.developerMessage = devMessage;
    return error;
  };

  return PayPalREST;
}();

/**
 * Enum for the main environments
 */


exports.default = PayPalREST;
PayPalREST.Env = {
  LIVE: 'live',
  SANDBOX: 'sandbox',
  MSMASTER: 'msmaster'
};

/**
 * Called when an operation needs to be resolved to a URL.
 * @callback TransactionContext~serviceResolver
 * @param {PayPalREST} api The API which is attempting to make the request
 * @param {object} options The options on the request, in which you typically only need to see op (meaning operation)
 */

/* eslint-enable no-param-reassign */
}).call(this,require("buffer").Buffer)
},{"./restError":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypalrest-manticore/build/src/restError.js","buffer":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/buffer/index.js","manticore":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore/browser.js","manticore-log":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-log/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/paypalrest-manticore/build/src/restError.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;
exports.paypalRestErrorDomain = exports.restError = undefined;
exports.payPalError = payPalError;

var _manticorePaypalerror = require('manticore-paypalerror');

var domain = 'PayPalRest';

function payPalError(code, message, debugId) {
  var errorInfo = new _manticorePaypalerror.PayPalErrorInfo();
  errorInfo.code = code.toString();
  errorInfo.domain = domain;
  errorInfo.message = message;
  errorInfo.debugId = debugId;
  return _manticorePaypalerror.PayPalError.makeError(null, errorInfo);
}

var restError = exports.restError = {
  invalidToken: payPalError(0, 'Invalid token'),
  invalidRequest: payPalError(1, 'Invalid request'),
  invalidCompositeToken: payPalError(2, 'Invalid composite token provided'),
  unauthorized: payPalError(401, 'Request not authorized')
};

exports.paypalRestErrorDomain = domain;
},{"manticore-paypalerror":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-paypalerror/build/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/process/browser.js":[function(require,module,exports){
// shim for using process in browser
var process = module.exports = {};

// cached from whatever global is present so that test runners that stub it
// don't break things.  But we need to wrap it in a try catch in case it is
// wrapped in strict mode code which doesn't define any globals.  It's inside a
// function because try/catches deoptimize in certain engines.

var cachedSetTimeout;
var cachedClearTimeout;

function defaultSetTimout() {
    throw new Error('setTimeout has not been defined');
}
function defaultClearTimeout () {
    throw new Error('clearTimeout has not been defined');
}
(function () {
    try {
        if (typeof setTimeout === 'function') {
            cachedSetTimeout = setTimeout;
        } else {
            cachedSetTimeout = defaultSetTimout;
        }
    } catch (e) {
        cachedSetTimeout = defaultSetTimout;
    }
    try {
        if (typeof clearTimeout === 'function') {
            cachedClearTimeout = clearTimeout;
        } else {
            cachedClearTimeout = defaultClearTimeout;
        }
    } catch (e) {
        cachedClearTimeout = defaultClearTimeout;
    }
} ())
function runTimeout(fun) {
    if (cachedSetTimeout === setTimeout) {
        //normal enviroments in sane situations
        return setTimeout(fun, 0);
    }
    // if setTimeout wasn't available but was latter defined
    if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {
        cachedSetTimeout = setTimeout;
        return setTimeout(fun, 0);
    }
    try {
        // when when somebody has screwed with setTimeout but no I.E. maddness
        return cachedSetTimeout(fun, 0);
    } catch(e){
        try {
            // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
            return cachedSetTimeout.call(null, fun, 0);
        } catch(e){
            // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error
            return cachedSetTimeout.call(this, fun, 0);
        }
    }


}
function runClearTimeout(marker) {
    if (cachedClearTimeout === clearTimeout) {
        //normal enviroments in sane situations
        return clearTimeout(marker);
    }
    // if clearTimeout wasn't available but was latter defined
    if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {
        cachedClearTimeout = clearTimeout;
        return clearTimeout(marker);
    }
    try {
        // when when somebody has screwed with setTimeout but no I.E. maddness
        return cachedClearTimeout(marker);
    } catch (e){
        try {
            // When we are in I.E. but the script has been evaled so I.E. doesn't  trust the global object when called normally
            return cachedClearTimeout.call(null, marker);
        } catch (e){
            // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.
            // Some versions of I.E. have different rules for clearTimeout vs setTimeout
            return cachedClearTimeout.call(this, marker);
        }
    }



}
var queue = [];
var draining = false;
var currentQueue;
var queueIndex = -1;

function cleanUpNextTick() {
    if (!draining || !currentQueue) {
        return;
    }
    draining = false;
    if (currentQueue.length) {
        queue = currentQueue.concat(queue);
    } else {
        queueIndex = -1;
    }
    if (queue.length) {
        drainQueue();
    }
}

function drainQueue() {
    if (draining) {
        return;
    }
    var timeout = runTimeout(cleanUpNextTick);
    draining = true;

    var len = queue.length;
    while(len) {
        currentQueue = queue;
        queue = [];
        while (++queueIndex < len) {
            if (currentQueue) {
                currentQueue[queueIndex].run();
            }
        }
        queueIndex = -1;
        len = queue.length;
    }
    currentQueue = null;
    draining = false;
    runClearTimeout(timeout);
}

process.nextTick = function (fun) {
    var args = new Array(arguments.length - 1);
    if (arguments.length > 1) {
        for (var i = 1; i < arguments.length; i++) {
            args[i - 1] = arguments[i];
        }
    }
    queue.push(new Item(fun, args));
    if (queue.length === 1 && !draining) {
        runTimeout(drainQueue);
    }
};

// v8 likes predictible objects
function Item(fun, array) {
    this.fun = fun;
    this.array = array;
}
Item.prototype.run = function () {
    this.fun.apply(null, this.array);
};
process.title = 'browser';
process.browser = true;
process.env = {};
process.argv = [];
process.version = ''; // empty string to avoid regexp issues
process.versions = {};

function noop() {}

process.on = noop;
process.addListener = noop;
process.once = noop;
process.off = noop;
process.removeListener = noop;
process.removeAllListeners = noop;
process.emit = noop;
process.prependListener = noop;
process.prependOnceListener = noop;

process.listeners = function (name) { return [] }

process.binding = function (name) {
    throw new Error('process.binding is not supported');
};

process.cwd = function () { return '/' };
process.chdir = function (dir) {
    throw new Error('process.chdir is not supported');
};
process.umask = function() { return 0; };

},{}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/qs/lib/formats.js":[function(require,module,exports){
'use strict';

var replace = String.prototype.replace;
var percentTwenties = /%20/g;

module.exports = {
    'default': 'RFC3986',
    formatters: {
        RFC1738: function (value) {
            return replace.call(value, percentTwenties, '+');
        },
        RFC3986: function (value) {
            return value;
        }
    },
    RFC1738: 'RFC1738',
    RFC3986: 'RFC3986'
};

},{}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/qs/lib/stringify.js":[function(require,module,exports){
'use strict';

var utils = require('./utils');
var formats = require('./formats');

var arrayPrefixGenerators = {
    brackets: function brackets(prefix) { // eslint-disable-line func-name-matching
        return prefix + '[]';
    },
    indices: function indices(prefix, key) { // eslint-disable-line func-name-matching
        return prefix + '[' + key + ']';
    },
    repeat: function repeat(prefix) { // eslint-disable-line func-name-matching
        return prefix;
    }
};

var toISO = Date.prototype.toISOString;

var defaults = {
    delimiter: '&',
    encode: true,
    encoder: utils.encode,
    encodeValuesOnly: false,
    serializeDate: function serializeDate(date) { // eslint-disable-line func-name-matching
        return toISO.call(date);
    },
    skipNulls: false,
    strictNullHandling: false
};

var stringify = function stringify( // eslint-disable-line func-name-matching
    object,
    prefix,
    generateArrayPrefix,
    strictNullHandling,
    skipNulls,
    encoder,
    filter,
    sort,
    allowDots,
    serializeDate,
    formatter,
    encodeValuesOnly
) {
    var obj = object;
    if (typeof filter === 'function') {
        obj = filter(prefix, obj);
    } else if (obj instanceof Date) {
        obj = serializeDate(obj);
    } else if (obj === null) {
        if (strictNullHandling) {
            return encoder && !encodeValuesOnly ? encoder(prefix, defaults.encoder) : prefix;
        }

        obj = '';
    }

    if (typeof obj === 'string' || typeof obj === 'number' || typeof obj === 'boolean' || utils.isBuffer(obj)) {
        if (encoder) {
            var keyValue = encodeValuesOnly ? prefix : encoder(prefix, defaults.encoder);
            return [formatter(keyValue) + '=' + formatter(encoder(obj, defaults.encoder))];
        }
        return [formatter(prefix) + '=' + formatter(String(obj))];
    }

    var values = [];

    if (typeof obj === 'undefined') {
        return values;
    }

    var objKeys;
    if (Array.isArray(filter)) {
        objKeys = filter;
    } else {
        var keys = Object.keys(obj);
        objKeys = sort ? keys.sort(sort) : keys;
    }

    for (var i = 0; i < objKeys.length; ++i) {
        var key = objKeys[i];

        if (skipNulls && obj[key] === null) {
            continue;
        }

        if (Array.isArray(obj)) {
            values = values.concat(stringify(
                obj[key],
                generateArrayPrefix(prefix, key),
                generateArrayPrefix,
                strictNullHandling,
                skipNulls,
                encoder,
                filter,
                sort,
                allowDots,
                serializeDate,
                formatter,
                encodeValuesOnly
            ));
        } else {
            values = values.concat(stringify(
                obj[key],
                prefix + (allowDots ? '.' + key : '[' + key + ']'),
                generateArrayPrefix,
                strictNullHandling,
                skipNulls,
                encoder,
                filter,
                sort,
                allowDots,
                serializeDate,
                formatter,
                encodeValuesOnly
            ));
        }
    }

    return values;
};

module.exports = function (object, opts) {
    var obj = object;
    var options = opts ? utils.assign({}, opts) : {};

    if (options.encoder !== null && options.encoder !== undefined && typeof options.encoder !== 'function') {
        throw new TypeError('Encoder has to be a function.');
    }

    var delimiter = typeof options.delimiter === 'undefined' ? defaults.delimiter : options.delimiter;
    var strictNullHandling = typeof options.strictNullHandling === 'boolean' ? options.strictNullHandling : defaults.strictNullHandling;
    var skipNulls = typeof options.skipNulls === 'boolean' ? options.skipNulls : defaults.skipNulls;
    var encode = typeof options.encode === 'boolean' ? options.encode : defaults.encode;
    var encoder = typeof options.encoder === 'function' ? options.encoder : defaults.encoder;
    var sort = typeof options.sort === 'function' ? options.sort : null;
    var allowDots = typeof options.allowDots === 'undefined' ? false : options.allowDots;
    var serializeDate = typeof options.serializeDate === 'function' ? options.serializeDate : defaults.serializeDate;
    var encodeValuesOnly = typeof options.encodeValuesOnly === 'boolean' ? options.encodeValuesOnly : defaults.encodeValuesOnly;
    if (typeof options.format === 'undefined') {
        options.format = formats['default'];
    } else if (!Object.prototype.hasOwnProperty.call(formats.formatters, options.format)) {
        throw new TypeError('Unknown format option provided.');
    }
    var formatter = formats.formatters[options.format];
    var objKeys;
    var filter;

    if (typeof options.filter === 'function') {
        filter = options.filter;
        obj = filter('', obj);
    } else if (Array.isArray(options.filter)) {
        filter = options.filter;
        objKeys = filter;
    }

    var keys = [];

    if (typeof obj !== 'object' || obj === null) {
        return '';
    }

    var arrayFormat;
    if (options.arrayFormat in arrayPrefixGenerators) {
        arrayFormat = options.arrayFormat;
    } else if ('indices' in options) {
        arrayFormat = options.indices ? 'indices' : 'repeat';
    } else {
        arrayFormat = 'indices';
    }

    var generateArrayPrefix = arrayPrefixGenerators[arrayFormat];

    if (!objKeys) {
        objKeys = Object.keys(obj);
    }

    if (sort) {
        objKeys.sort(sort);
    }

    for (var i = 0; i < objKeys.length; ++i) {
        var key = objKeys[i];

        if (skipNulls && obj[key] === null) {
            continue;
        }

        keys = keys.concat(stringify(
            obj[key],
            key,
            generateArrayPrefix,
            strictNullHandling,
            skipNulls,
            encode ? encoder : null,
            filter,
            sort,
            allowDots,
            serializeDate,
            formatter,
            encodeValuesOnly
        ));
    }

    var joined = keys.join(delimiter);
    var prefix = options.addQueryPrefix === true ? '?' : '';

    return joined.length > 0 ? prefix + joined : '';
};

},{"./formats":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/qs/lib/formats.js","./utils":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/qs/lib/utils.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/qs/lib/utils.js":[function(require,module,exports){
'use strict';

var has = Object.prototype.hasOwnProperty;

var hexTable = (function () {
    var array = [];
    for (var i = 0; i < 256; ++i) {
        array.push('%' + ((i < 16 ? '0' : '') + i.toString(16)).toUpperCase());
    }

    return array;
}());

var compactQueue = function compactQueue(queue) {
    var obj;

    while (queue.length) {
        var item = queue.pop();
        obj = item.obj[item.prop];

        if (Array.isArray(obj)) {
            var compacted = [];

            for (var j = 0; j < obj.length; ++j) {
                if (typeof obj[j] !== 'undefined') {
                    compacted.push(obj[j]);
                }
            }

            item.obj[item.prop] = compacted;
        }
    }

    return obj;
};

exports.arrayToObject = function arrayToObject(source, options) {
    var obj = options && options.plainObjects ? Object.create(null) : {};
    for (var i = 0; i < source.length; ++i) {
        if (typeof source[i] !== 'undefined') {
            obj[i] = source[i];
        }
    }

    return obj;
};

exports.merge = function merge(target, source, options) {
    if (!source) {
        return target;
    }

    if (typeof source !== 'object') {
        if (Array.isArray(target)) {
            target.push(source);
        } else if (typeof target === 'object') {
            if (options.plainObjects || options.allowPrototypes || !has.call(Object.prototype, source)) {
                target[source] = true;
            }
        } else {
            return [target, source];
        }

        return target;
    }

    if (typeof target !== 'object') {
        return [target].concat(source);
    }

    var mergeTarget = target;
    if (Array.isArray(target) && !Array.isArray(source)) {
        mergeTarget = exports.arrayToObject(target, options);
    }

    if (Array.isArray(target) && Array.isArray(source)) {
        source.forEach(function (item, i) {
            if (has.call(target, i)) {
                if (target[i] && typeof target[i] === 'object') {
                    target[i] = exports.merge(target[i], item, options);
                } else {
                    target.push(item);
                }
            } else {
                target[i] = item;
            }
        });
        return target;
    }

    return Object.keys(source).reduce(function (acc, key) {
        var value = source[key];

        if (has.call(acc, key)) {
            acc[key] = exports.merge(acc[key], value, options);
        } else {
            acc[key] = value;
        }
        return acc;
    }, mergeTarget);
};

exports.assign = function assignSingleSource(target, source) {
    return Object.keys(source).reduce(function (acc, key) {
        acc[key] = source[key];
        return acc;
    }, target);
};

exports.decode = function (str) {
    try {
        return decodeURIComponent(str.replace(/\+/g, ' '));
    } catch (e) {
        return str;
    }
};

exports.encode = function encode(str) {
    // This code was originally written by Brian White (mscdex) for the io.js core querystring library.
    // It has been adapted here for stricter adherence to RFC 3986
    if (str.length === 0) {
        return str;
    }

    var string = typeof str === 'string' ? str : String(str);

    var out = '';
    for (var i = 0; i < string.length; ++i) {
        var c = string.charCodeAt(i);

        if (
            c === 0x2D // -
            || c === 0x2E // .
            || c === 0x5F // _
            || c === 0x7E // ~
            || (c >= 0x30 && c <= 0x39) // 0-9
            || (c >= 0x41 && c <= 0x5A) // a-z
            || (c >= 0x61 && c <= 0x7A) // A-Z
        ) {
            out += string.charAt(i);
            continue;
        }

        if (c < 0x80) {
            out = out + hexTable[c];
            continue;
        }

        if (c < 0x800) {
            out = out + (hexTable[0xC0 | (c >> 6)] + hexTable[0x80 | (c & 0x3F)]);
            continue;
        }

        if (c < 0xD800 || c >= 0xE000) {
            out = out + (hexTable[0xE0 | (c >> 12)] + hexTable[0x80 | ((c >> 6) & 0x3F)] + hexTable[0x80 | (c & 0x3F)]);
            continue;
        }

        i += 1;
        c = 0x10000 + (((c & 0x3FF) << 10) | (string.charCodeAt(i) & 0x3FF));
        out += hexTable[0xF0 | (c >> 18)]
            + hexTable[0x80 | ((c >> 12) & 0x3F)]
            + hexTable[0x80 | ((c >> 6) & 0x3F)]
            + hexTable[0x80 | (c & 0x3F)];
    }

    return out;
};

exports.compact = function compact(value) {
    var queue = [{ obj: { o: value }, prop: 'o' }];
    var refs = [];

    for (var i = 0; i < queue.length; ++i) {
        var item = queue[i];
        var obj = item.obj[item.prop];

        var keys = Object.keys(obj);
        for (var j = 0; j < keys.length; ++j) {
            var key = keys[j];
            var val = obj[key];
            if (typeof val === 'object' && val !== null && refs.indexOf(val) === -1) {
                queue.push({ obj: obj, prop: key });
                refs.push(val);
            }
        }
    }

    return compactQueue(queue);
};

exports.isRegExp = function isRegExp(obj) {
    return Object.prototype.toString.call(obj) === '[object RegExp]';
};

exports.isBuffer = function isBuffer(obj) {
    if (obj === null || typeof obj === 'undefined') {
        return false;
    }

    return !!(obj.constructor && obj.constructor.isBuffer && obj.constructor.isBuffer(obj));
};

},{}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-page-tracker/build/index.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

var _Tracker = require('./src/Tracker');

Object.defineProperty(exports, 'Tracker', {
  enumerable: true,
  get: function get() {
    return _interopRequireDefault(_Tracker).default;
  }
});

var _Page = require('./src/Page');

Object.defineProperty(exports, 'pageId', {
  enumerable: true,
  get: function get() {
    return _Page.pageId;
  }
});
Object.defineProperty(exports, 'Page', {
  enumerable: true,
  get: function get() {
    return _Page.Page;
  }
});
Object.defineProperty(exports, 'pages', {
  enumerable: true,
  get: function get() {
    return _Page.pages;
  }
});
Object.defineProperty(exports, 'action', {
  enumerable: true,
  get: function get() {
    return _Page.action;
  }
});

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
},{"./src/Page":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-page-tracker/build/src/Page.js","./src/Tracker":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-page-tracker/build/src/Tracker.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-page-tracker/build/src/Page.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

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; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

var pageId = exports.pageId = {
  transaction: 'Transaction',
  emv: 'EMV',
  swipe: 'Swipe',
  cashOrCheck: 'CashOrCheck',
  keyIn: 'KeyIn',
  payment: 'Payment',
  refund: 'Refund',
  cancelled: 'Cancelled',
  noThanks: 'NoThanks',
  custom: 'Custom',
  failed: 'Failed',
  complete: 'Completed',
  decline: 'Decline',
  receipt: 'Receipt',
  required: 'Required',
  sms: 'SMS',
  email: 'Email',
  signature: 'Signature',
  settings: 'Settings',
  swUpdate: 'SwUpdate',
  downloading: 'Downloading',
  rki: 'RKI',
  config: 'Config',
  os: 'OS',
  mpi: 'MPI',
  reboot: 'Reboot',
  retry: 'Retry'
};

/**
 * Class to represent a Page object intended for page tracking observers
 * @class
 * @property {string} name Full name for the page in delimited format @readonly
 * @property {string} action Most recent user action that was performed @readonly
 * @property {Page} parent Parent to the current page @readonly
 */

var Page = exports.Page = function () {
  /**
   * Build the page object
   * @param {string} id Id of the page
   * @param {Page} parent Parent to current page
   * @private
   */
  function Page(id, parent) {
    _classCallCheck(this, Page);

    this._id = id;
    this._parent = parent;
  }

  Page.prototype.withAction = function withAction(action) {
    this._action = action;
    return this;
  };

  _createClass(Page, [{
    key: 'name',
    get: function get() {
      var parentName = '';
      if (this._parent) {
        parentName = this._parent.name + ':';
      }
      return '' + parentName + this._id;
    }
  }, {
    key: 'parent',
    get: function get() {
      return this._parent;
    }
  }, {
    key: 'action',
    get: function get() {
      return this._action;
    },
    set: function set(value) {
      this._action = value;
    }
  }]);

  return Page;
}();

var transaction = new Page(pageId.transaction, null);
var emv = new Page(pageId.emv, transaction);
var swipe = new Page(pageId.swipe, transaction);
var payment = new Page(pageId.payment, null);
var keyIn = new Page(pageId.keyIn, payment);
var cashOrCheck = new Page(pageId.cashOrCheck, payment);
var paymentComplete = new Page(pageId.complete, payment);
var paymentCancelled = new Page(pageId.cancelled, payment);
var paymentDecline = new Page(pageId.decline, payment);
var refund = new Page(pageId.refund, null);
var refundComplete = new Page(pageId.complete, refund);
var refundCancelled = new Page(pageId.cancelled, refund);
var refundDecline = new Page(pageId.decline, refund);
var paymentReceipt = new Page(pageId.receipt, payment);
var refundReceipt = new Page(pageId.receipt, refund);
var paymentReceiptSms = new Page(pageId.sms, paymentReceipt);
var paymentReceiptEmail = new Page(pageId.email, paymentReceipt);
var paymentReceiptNoThanks = new Page(pageId.noThanks, paymentReceipt);
var paymentReceiptCustom = new Page(pageId.custom, paymentReceipt);
var refundReceiptSms = new Page(pageId.sms, refundReceipt);
var refundReceiptEmail = new Page(pageId.email, refundReceipt);
var refundReceiptNoThanks = new Page(pageId.noThanks, refundReceipt);
var refundReceiptCustom = new Page(pageId.custom, refundReceipt);
var signature = new Page(pageId.signature, null);
var settings = new Page(pageId.settings, null);
var swUpdate = new Page(pageId.swUpdate, settings);
var swUpdateRetry = new Page(pageId.retry, swUpdate);
var swUpdateReboot = new Page(pageId.reboot, swUpdate);
var swUpdateComplete = new Page(pageId.complete, swUpdate);
var swUpdateFailed = new Page(pageId.failed, swUpdate);
var rki = new Page(pageId.rki, swUpdate);
var rkiRequired = new Page(pageId.required, rki);
var rkiCompleted = new Page(pageId.complete, rki);
var rkiFailed = new Page(pageId.failed, rki);
var os = new Page(pageId.os, swUpdate);
var osRequired = new Page(pageId.required, os);
var osCompleted = new Page(pageId.complete, os);
var osFailed = new Page(pageId.failed, os);
var mpi = new Page(pageId.mpi, swUpdate);
var mpiRequired = new Page(pageId.required, mpi);
var mpiCompleted = new Page(pageId.complete, mpi);
var mpiFailed = new Page(pageId.failed, mpi);
var config = new Page(pageId.config, swUpdate);
var configRequired = new Page(pageId.required, config);
var configCompleted = new Page(pageId.complete, config);
var configFailed = new Page(pageId.failed, config);

var pages = exports.pages = {
  transaction: transaction,
  emv: emv,
  swipe: swipe,
  keyIn: keyIn,
  cashOrCheck: cashOrCheck,
  payment: payment,
  paymentComplete: paymentComplete,
  paymentCancelled: paymentCancelled,
  paymentDecline: paymentDecline,
  refund: refund,
  refundComplete: refundComplete,
  refundCancelled: refundCancelled,
  refundDecline: refundDecline,
  paymentReceipt: paymentReceipt,
  refundReceipt: refundReceipt,
  paymentReceiptSms: paymentReceiptSms,
  paymentReceiptEmail: paymentReceiptEmail,
  paymentReceiptNoThanks: paymentReceiptNoThanks,
  paymentReceiptCustom: paymentReceiptCustom,
  refundReceiptSms: refundReceiptSms,
  refundReceiptEmail: refundReceiptEmail,
  refundReceiptNoThanks: refundReceiptNoThanks,
  refundReceiptCustom: refundReceiptCustom,
  signature: signature,
  settings: settings,
  swUpdate: swUpdate,
  swUpdateRetry: swUpdateRetry,
  swUpdateReboot: swUpdateReboot,
  swUpdateComplete: swUpdateComplete,
  swUpdateFailed: swUpdateFailed,
  rkiRequired: rkiRequired,
  rkiCompleted: rkiCompleted,
  rkiFailed: rkiFailed,
  osRequired: osRequired,
  osCompleted: osCompleted,
  osFailed: osFailed,
  mpiRequired: mpiRequired,
  mpiCompleted: mpiCompleted,
  mpiFailed: mpiFailed,
  configRequired: configRequired,
  configCompleted: configCompleted,
  configFailed: configFailed
};

var action = exports.action = {
  cancel: 'cancel',
  acquire: 'acquire',
  dismiss: 'dismiss'
};
},{}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-page-tracker/build/src/Tracker.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

var _events = require('events');

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

var Tracker = function () {
  function Tracker() {
    _classCallCheck(this, Tracker);
  }

  /**
   * @param {Error} err Error (if any)
   * @param {Page} page Page that is viewed
   */
  Tracker.publishPageView = function publishPageView(err, page) {
    Tracker.events.emit('pageViewed', err, page);
  };

  return Tracker;
}();

exports.default = Tracker;


Tracker.events = new _events.EventEmitter();
},{"events":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/events/events.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/BatteryInfo.js":[function(require,module,exports){
"use strict";

exports.__esModule = true;

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; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

/**
 * BatteryInfo class contains information about the health of the device battery
 * and the instant it was measured
 * @class
 * @property {int} percentage The level of battery in percentage
 * @property {bool} isCharging Indicates if the device battery is connected to power
 * @property {bool} isLevelCritical Indicates that the device battery is at Critical or less and not charging
 * @property {bool} isLevelUpdateCritical Indicates that the device battery is at UpdateCritical or less and not charging
 * @property {Date} measuredOn The time the battery information was retrieved
 * @property {batteryStatus} status Status of the battery
 */
var BatteryInfo = function () {
  /**
   * Create a new Battery info object
   * @param {int} percentage The level of battery in percentage @readonly
   * @param {bool} isCharging Boolean indicating whether the battery is charging or not @readonly
   * @param {Date} measuredOn Time stamp at which the battery measurement was received @readonly
   * @param {batteryStatus} status Battery status
   */
  function BatteryInfo(percentage, isCharging, measuredOn, status) {
    _classCallCheck(this, BatteryInfo);

    this._percentage = parseInt(percentage, 10);
    this._isCharging = isCharging;
    this._measuredOn = measuredOn;
    this._status = status;
  }

  BatteryInfo.prototype.toString = function toString() {
    /* eslint max-len: "off" */
    return "Battery Info: Percentage: " + this.percentage + ", isCharging: " + this.isCharging + ", level: " + this.level + ", measuredOn: " + this.measuredOn;
  };

  _createClass(BatteryInfo, [{
    key: "percentage",
    get: function get() {
      return this._percentage;
    }
  }, {
    key: "isCharging",
    get: function get() {
      return this._isCharging;
    }
  }, {
    key: "isLevelUpdateCritical",
    get: function get() {
      return !this.isCharging && this._percentage <= 20;
    }
  }, {
    key: "isLevelCritical",
    get: function get() {
      return !this.isCharging && this._percentage <= 15;
    }
  }, {
    key: "measuredOn",
    get: function get() {
      return this._measuredOn;
    }
  }, {
    key: "status",
    get: function get() {
      return this._status;
    }
  }]);

  return BatteryInfo;
}();

exports.default = BatteryInfo;
},{}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/CardDataUtil.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

var _manticoreLog = require('manticore-log');

var _manticoreLog2 = _interopRequireDefault(_manticoreLog);

var _CardIssuer = require('./CardIssuer');

var _CardIssuer2 = _interopRequireDefault(_CardIssuer);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

var digitsOnlyRegexMatcher = null;
var Log = (0, _manticoreLog2.default)('card-issuer');

var CardDataUtil = function () {
  function CardDataUtil() {
    _classCallCheck(this, CardDataUtil);
  }

  /**
   * Identify card issuer from the value of Application label TLV Tag
   * @param emvAppLabel string Application label TLV tag value
   * @returns {CardIssuer|int}
   */
  CardDataUtil.getCardIssuerFromEmvAppLabel = function getCardIssuerFromEmvAppLabel(emvAppLabel) {
    if (!emvAppLabel) {
      return _CardIssuer2.default.Unknown;
    }

    var appLabel = emvAppLabel.toUpperCase();
    if (appLabel.includes('VISA')) {
      return _CardIssuer2.default.Visa;
    }

    if (appLabel.includes('MASTERCARD')) {
      return _CardIssuer2.default.MasterCard;
    }

    if (appLabel.includes('MAESTRO')) {
      return _CardIssuer2.default.Maestro;
    }

    if (appLabel.includes('AMERICAN')) {
      return _CardIssuer2.default.Amex;
    }

    if (appLabel.includes('DISCOVER')) {
      return _CardIssuer2.default.Discover;
    }

    if (appLabel.includes('PAYPAL')) {
      return _CardIssuer2.default.PayPal;
    }

    Log.warn('Unable to parse Card issuer from Application Label: ' + emvAppLabel);
    return _CardIssuer2.default.Unknown;
  };

  /**
   * Identify card issuer from the card number
   * @param cardNumberInfo string
   * @returns {CardIssuer|int}
   */


  CardDataUtil.getCardIssuerFromCardNumber = function getCardIssuerFromCardNumber(cardNumberInfo) {
    if (!digitsOnlyRegexMatcher) {
      digitsOnlyRegexMatcher = /\D+/;
    }
    var cardNumber = cardNumberInfo.replace(digitsOnlyRegexMatcher, '');

    // Visa
    if (cardNumber.length > 0 && cardNumber[0] === CardDataUtil._controlNumber.Visa) {
      return _CardIssuer2.default.Visa;
    }

    // MasterCard
    if (cardNumber.length >= 2) {
      var firstTwo = parseInt(cardNumber.substr(0, 2), 10);
      if (firstTwo > 50 && firstTwo < 56) {
        return _CardIssuer2.default.MasterCard;
      }
    }

    // Maestro
    if (cardNumber.length >= 2) {
      var cn = cardNumber.substr(0, 2);
      if (cn === CardDataUtil._controlNumber.Maestro1 || cn === CardDataUtil._controlNumber.Maestro2) {
        return _CardIssuer2.default.Maestro;
      }
    }

    // Amex
    if (cardNumber.length >= 2) {
      var _cn = cardNumber.substr(0, 2);
      if (_cn === CardDataUtil._controlNumber.Amex1 || _cn === CardDataUtil._controlNumber.Amex2) {
        return _CardIssuer2.default.Amex;
      }
    }

    // Discover
    if (cardNumber.length >= 4 && cardNumber.substr(0, 4) === CardDataUtil._controlNumber.Discover1) {
      return _CardIssuer2.default.Discover;
    }

    if (cardNumber.length >= 2 && cardNumber.substr(0, 2) === CardDataUtil._controlNumber.Discover2) {
      return _CardIssuer2.default.Discover;
    }

    // PayPal
    if (cardNumber.length >= 2 && cardNumber.substr(0, 2) === CardDataUtil._controlNumber.PayPal) {
      return _CardIssuer2.default.PayPal;
    }

    return _CardIssuer2.default.Unknown;
  };

  /**
   * Get the display name for card issuer
   * @param cardIssuer
   * @returns {string}
   */


  CardDataUtil.getCardIssuerDisplayName = function getCardIssuerDisplayName(cardIssuer) {
    for (var issuerName in _CardIssuer2.default) {
      if ({}.hasOwnProperty.call(_CardIssuer2.default, issuerName) && typeof _CardIssuer2.default !== 'function' && _CardIssuer2.default[issuerName] === cardIssuer) {
        return issuerName;
      }
    }
    return null;
  };

  return CardDataUtil;
}();

/**
 * Card issuer control numbers
 */


exports.default = CardDataUtil;
CardDataUtil._controlNumber = {
  Visa: '4',
  MasterCard: '5',
  Amex1: '34',
  Amex2: '37',
  Discover1: '6011',
  Discover2: '65',
  PayPal: '62',
  Maestro1: '67',
  Maestro2: '50'
};
},{"./CardIssuer":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/CardIssuer.js","manticore-log":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-log/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/CardInsertedHandler.js":[function(require,module,exports){
"use strict";

exports.__esModule = true;

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

/**
 * When card insert is detected during a transaction, the registered listener with be invoked with this handler method
 * @class
 */
var CardInsertedHandler = function () {
  function CardInsertedHandler(cb) {
    _classCallCheck(this, CardInsertedHandler);

    this._cb = cb;
  }

  /**
   * Continue to read EMV data from inserted card
   */


  CardInsertedHandler.prototype.continueWithCardDataRead = function continueWithCardDataRead() {
    this._cb();
  };

  /**
   * Dismiss any SDK UI Dialog that would be displayed at the time this handler is invoked
   */


  CardInsertedHandler.prototype.dismissSDKUIPrompt = function dismissSDKUIPrompt() {};

  return CardInsertedHandler;
}();

exports.default = CardInsertedHandler;
},{}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/CardIssuer.js":[function(require,module,exports){
"use strict";

exports.__esModule = true;
/**
 * Issuer of the card that was presented to the SDK
 * @enum {int}
 */
var CardIssuer = {
  /**
   * Unknown card issuer
   */
  Unknown: 0,

  /**
   * Visa credit/prepaid
   */
  Visa: 1,

  /**
   * Master card
   */
  MasterCard: 2,

  /**
   * Maestro
   */
  Maestro: 3,

  /**
   * American Express
   */
  Amex: 4,

  /**
   * Discover
   */
  Discover: 5,

  /**
   * PayPal
   */
  PayPal: 6
};

exports.default = CardIssuer;
},{}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/CardReader.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

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; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

var _events = require('events');

var _TransactionType = require('./TransactionType');

var _TransactionType2 = _interopRequireDefault(_TransactionType);

var _FormFactor = require('./FormFactor');

var _FormFactor2 = _interopRequireDefault(_FormFactor);

var _BatteryInfo = require('./BatteryInfo');

var _BatteryInfo2 = _interopRequireDefault(_BatteryInfo);

var _CardIssuer = require('./CardIssuer');

var _CardIssuer2 = _interopRequireDefault(_CardIssuer);

var _NumericEntryType = require('./NumericEntryType');

var _NumericEntryType2 = _interopRequireDefault(_NumericEntryType);

var _appMessage = require('./appMessage');

var _appMessage2 = _interopRequireDefault(_appMessage);

var _SecureEntryOptions = require('./SecureEntryOptions');

var _SecureEntryOptions2 = _interopRequireDefault(_SecureEntryOptions);

var _NumericEntryOptions = require('./NumericEntryOptions');

var _NumericEntryOptions2 = _interopRequireDefault(_NumericEntryOptions);

var _DeviceUpdate = require('./DeviceUpdate');

var _DeviceUpdate2 = _interopRequireDefault(_DeviceUpdate);

var _CardPresentEvent = require('./Messages/CardPresentEvent');

var _CardPresentEvent2 = _interopRequireDefault(_CardPresentEvent);

var _PinEvent = require('./Messages/PinEvent');

var _PinEvent2 = _interopRequireDefault(_PinEvent);

var _Card = require('./Messages/Card');

var _Card2 = _interopRequireDefault(_Card);

var _AvailableApplications = require('./Messages/AvailableApplications');

var _AvailableApplications2 = _interopRequireDefault(_AvailableApplications);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (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 } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /* eslint-disable no-unused-vars */

/**
 * The Card Reader interface lists the functions that needs to be implemented by a payment device in order to fully
 * integrate with PayPal Here SDK. This interface is partially implemented by the {PaymentDevice} class and any new
 * payment device that is provisioned should inherit {PaymentDevice} and not {CardReader}
 * @class
 * @property {CardReader~appInterface} app Interface to app components
 * @property {CardReader~nativeInterface} native Interface to native components
 * @property {boolean} isUsb Indicates if the card reader is connected over USB
 * @property {string} serialNumber Unique serial number of the card reader
 * @property {DeviceUpdate} pendingUpdate Pending software update for the card reader (if any)
 * @property {BatteryInfo} batteryInfo Most recent battery information of the card reader
 */
var CardReader = function (_EventEmitter) {
  _inherits(CardReader, _EventEmitter);

  function CardReader() {
    _classCallCheck(this, CardReader);

    return _possibleConstructorReturn(this, _EventEmitter.apply(this, arguments));
  }

  /**
   * Start the device removing process.
   * @method
   * @param {CardReader~callback} callback A callback function that should be invoked on completion of removed flow.
   */
  CardReader.prototype.beginDeviceRemoved = function beginDeviceRemoved(callback) {
    throw new Error('Subclass must implement this method');
  };

  /**
   * Start the device pairing/connection process. After a successful connection, the device should be
   * ready to take payments
   * @method
   * @param {CardReader~callback} callback A callback function that should be invoked on completion of connection flow.
   */


  CardReader.prototype.beginDeviceConnect = function beginDeviceConnect(callback) {
    throw new Error('Subclass must implement this method');
  };

  /**
   * Disconnect the card reader. The device should no longer be able to take payments after a successful disconnect
   * @param {CardReader~callback} callback A callback function that will be invoked on completion of disconnection flow.
   */


  CardReader.prototype.beginDeviceDisconnect = function beginDeviceDisconnect(callback) {
    throw new Error('Subclass must implement this method');
  };

  /**
   * Get supported formFactors for this device
   * @return {[FormFactor]} List of payment form factors supported by the card reader
   */


  /**
   * Receive data stream from the card reader
   * @param {Object} data from the reader in some device specific format
   */
  CardReader.prototype.received = function received(data) {
    throw new Error('Subclass must implement this method');
  };

  /**
   * Display a predefined message on the terminal, if supported
   * @param {CardReader~readerDisplayArgs} opt Message display options
   * @param {CardReader~callback} callback Callback function to invoke after the message is displayed
   */


  CardReader.prototype.display = function display(opt, callback) {
    throw new Error('Subclass must implement this method');
  };

  /**
   * Retrieve the firmware version information on the reader
    * @param {CardReader~getVersionCallback} callback Callback function that is called with the reader firmware version information.
   */


  CardReader.prototype.getFirmwareVersionInfo = function getFirmwareVersionInfo(callback) {
    throw new Error('Subclass must implement this method');
  };

  /**
   * Retrieve operations logs from the card reader
   * @param {CardReader~deviceLogsCallback} callback A callback to invoke after the logs are extracted. Invoked with {Error, string}
   */


  CardReader.prototype.extractReaderLogs = function extractReaderLogs(callback) {
    throw new Error('Subclass must implement this method');
  };

  /**
   * Activate the card reader to take payment. {CardReader#cardPresented} event should be emitted after the card was
   * presented. Based on the type of card that was presented, this event can be invoked more than once. For e.g., for pin present
   * transactions, more than one event will be emitted for PIN presented status change followed by card data read event.
   * The card reader should also emit {PaymentDevice.Message.Cancelled} & {PaymentDevice.Message.CancelRequested} events
   * for cancellations and cancel requests that are initiated from the card reader. For e.g. pressing cancel button from
   * the card reader during an active payment
   * Note: Should invoke super.activateForPayment while extending from Abstract {PaymentDevice} class that implements this interface
   * @param {TransactionContext} context Transaction context
   * @param {[FormFactor]} formFactors List of form factors to enable for this transaction
   * @param {bool} showPrompt true to display a prompt on the card reader's display (depends on hardware support)
   */


  CardReader.prototype.activateForPayment = function activateForPayment(context, formFactors, showPrompt) {
    throw new Error('Subclass must implement this method');
  };

  /**
   * Select payment application from the presented card. {CardPresentEvent#cardDataRead} event should be emitted after the
   * application is selected
   * @param {string} appId Id of the selected Application
   * @param {Card} card The card that was presented
   */


  CardReader.prototype.selectPaymentApplication = function selectPaymentApplication(appId, card) {
    throw new Error('Subclass must implement this method');
  };

  /**
   * Complete an ongoing transaction by pushing the auth code to the reader
   * @param {string} authCode The auth-code from the payments API that needs to be pushed to the reader
   * @param {CardReader~callback} callback Callback function to invoke after completing the transaction
   */


  CardReader.prototype.completeTransaction = function completeTransaction(authCode, callback) {
    throw new Error('Subclass must implement this method');
  };

  /**
   * Deactivate an active transaction. Can be called anytime after from activating card reader and before completing the payment.
   * {PaymentDevice.Event.cancelled} event should be emitted after the transaction is cancelled
   * Note: Should invoke super.abortTransaction while extending from Abstract {PaymentDevice} class that implements this interface
   * @param {TransactionContext} context Transaction context
   * @param {CardReader~callback} callback Callback function to invoke after the the reader is deactivated
   */


  CardReader.prototype.abortTransaction = function abortTransaction(context, callback) {
    throw new Error('Subclass must implement this method');
  };

  /**
   * Deactivate contactless reader
   * @param {[FormFactor]} formFactors Form factors to deactivate
   * @param {CardReader~callback} callback
   */


  CardReader.prototype.deactivateFormFactors = function deactivateFormFactors(formFactors, callback) {
    throw new Error('Subclass must implement this method');
  };

  /**
   * Begin listen for card removal events
   * @param {CardReader~callback} callback
   */


  CardReader.prototype.listenForCardRemoval = function listenForCardRemoval(callback) {
    throw new Error('Subclass must implement this method');
  };

  /**
   * This function will be invoked after completion of a transaction (for both successful and declined transactions) and
   * before beginning a subsequent transaction. A post transaction action (like soft resetting the card reader state
   * in-between transactions) should be performed here
   * @param {CardReader~callback} callback
   */


  CardReader.prototype.postTransactionCleanup = function postTransactionCleanup(callback) {
    throw new Error('Subclass must implement this method');
  };

  /**
   * Retrieve battery information from the reader
   * @param {CardReader~batteryInfo} callback Callback function to invoke after retrieving the battery info
   */


  CardReader.prototype.getBatteryInfo = function getBatteryInfo(callback) {
    throw new Error('Subclass must implement this method');
  };

  /**
   * Prompt for a non-secure amount or numeric value to be entered.
   * @param {NumericEntryOptions} options Options governing numeric entry
   * @param {NumericEntryOptions~amountEntered} callback Called when the attempt completes
   */


  CardReader.prototype.promptForNumericEntry = function promptForNumericEntry(options, callback) {
    throw new Error('Subclass must implement this method');
  };

  /**
   * Get a secure Personal Account Number (PAN) from the device
   * @param {SecureEntryOptions} options
   * @param {SecureEntryOptions~secureEntry} callback
   */


  CardReader.prototype.promptForSecureAccountNumber = function promptForSecureAccountNumber(options, callback) {
    throw new Error('Subclass must implement this method');
  };

  /**
   * Gets the device version information
   * @method
   * @returns {object} Returns key-value pair of version type and value.
   */


  CardReader.prototype.getVersionInfo = function getVersionInfo() {
    throw new Error('Subclass must implement this method');
  };

  _createClass(CardReader, [{
    key: 'formFactors',
    get: function get() {
      throw new Error('Subclass must implement this method');
    }
  }]);

  return CardReader;
}(_events.EventEmitter);

/**
 * @callback CardReader~callback
 * @param {Error} error Error object if any
 */

/**
 * @callback CardReader~getVersionCallback
 * @param {Error} error Error object if any
 * @param {[Object.<string, string>]} versionInfo Version information in
 * { component_1_VersionName:value, component_2_VersionName:value, ... } format
 * @param {function} versionInfo.toString Version information that will be displayed to the user
 */

/**
 * @callback CardReader~deviceLogsCallback
 * @param {Error} error Error object if any
 * @param {string} logs Device logs
 */

/**
 * @callback CardReader~batteryInfo
 * @param {Error} error Error object if any
 * @param {BatteryInfo} batteryInfo Battery information from the card reader
 */

/**
 * @callback CardReader~swUpdateUrlCallback
 * @param {Error} error Error object if any
 * @param {string} logs URL to retrieve software update instructions
 */

/**
 * @typedef {function} CardReader~getSwUpdateUrl
 * @param {string} deviceManufacturer Manufacturer of the device e.g., miura
 * @param {string} deviceModel Model of the device e.g., m010
 * @param {CardReader~swUpdateUrlCallback} callback
 */

/**
 * The interface to App. This is also an event emitter that could be subscribed for events like 'merchantInitialized'
 * @typedef {Object} CardReader~appInterface
 * @property {CardReader~appDisplay} display Update the App UI
 * @property {CardReader~getSwUpdateUrl} getSwUpdateUrl Get the URL to retrieve software update instructions for the card reader
 * @property {Object} getMerchant Returns the merchant account that is currently active
 */

/**
 * Connect the card reader over Bluetooth, USB or audiojack to the physical device on which the SDK is running. The SDK should be
 * able to send and receive data from the card reader after a successful connection
 * @typedef {function} CardReader~nativeConnect
 * @param {CardReader~callback}
 */

/**
 * Disconnect a card reader (previously connected over Bluetooth, USB or audiojack) from the device on which the SDK is
 * running. The card reader should not respond to data requests from the SDK after a successful disconnect
 * @typedef {function} CardReader~nativeDisconnect
 * @param {CardReader~callback}
 */

/**
 * Send a stream of data to a connected card reader
 * @typedef {function} CardReader~nativeSend
 * @param {Object} data Data to be streamed in a format specific to the reader
 * @param {CardReader~callback}
 */

/**
 * @typedef {Object} CardReader~nativeInterface
 * @property {function} isConnected Indicates if the card reader is connected to the device
 * @property {CardReader~nativeConnect} connect Establish a connection with the card reader
 * @property {CardReader~nativeDisconnect} disconnect Disconnect a card reader
 * @property {CardReader~nativeSend} send Send a stream of data to a connected card reader
 */

/**
 * @typedef {function} CardReader~appDisplay
 * @param {CardReader~appDisplayArgs} args Alert configuration options
 * @param {CardReader~appDisplayCallback} Callback invoked when user takes action
 * @returns {AlertViewHandle} alert Handle to the alert view
 */

/**
 * @typedef {Object} CardReader~appDisplayArgs
 * @property {appMessage} id Id of the message to be displayed
 * @property {Object} substitutions Substitution values for string literals
 * @property {boolean} showActivity Show a progress bar
 */

/**
 * @callback CardReader~appDisplayCallback
 * @param {AlertViewHandle} alert Handle to the alert view
 * @param {index} index Index to the button that was clicked
 */

/**
 * @typedef {Object} AlertViewHandle
 * @param {function} dismiss Dismiss the alert view
 * @param {function} setTitle Set the title on the alert view
 * @param {function} setMessage Set the message on the alert view
 */

/**
 * @typedef {Object} TransactionContext
 * @property {TransactionType} type Transaction type
 * @property {Invoice} invoice The invoice for this transaction
 */

/**
 * @typedef {Object} Invoice
 * @property {number} total The total amount due on invoice
 * @property {string} currency The currency for all amounts on this invoice
 */

/**
 * @typedef {Object} CardReader~readerDisplayArgs
 * @property {PaymentDevice.Message} id The message to display
 * @property {Object} substitutions values to replace in the string
 * @property {boolean} displaySystemIcons Show/Hide system status icon row on the card reader display
 */

/**
 * A card was presented to the card reader,
 * @event CardReader#cardPresented
 * @param {Error} error Error object (if any)
 * @param {CardPresentEvent} type The type of card present event
 * @param {FormFactor} formFactor Form factor by which the card was presented
 * @param {CardReader~CardData|PinEvent|AvailableApplications} result
 */

/**
 * @typedef {Object} CardReader~CardData
 * @property {Card} card Presented card
 * @property {boolean} approvedOffline Indicates if transaction was approved offline
 */

/* eslint-enable no-unused-vars */


exports.default = CardReader;
},{"./BatteryInfo":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/BatteryInfo.js","./CardIssuer":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/CardIssuer.js","./DeviceUpdate":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/DeviceUpdate.js","./FormFactor":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/FormFactor.js","./Messages/AvailableApplications":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/Messages/AvailableApplications.js","./Messages/Card":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/Messages/Card.js","./Messages/CardPresentEvent":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/Messages/CardPresentEvent.js","./Messages/PinEvent":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/Messages/PinEvent.js","./NumericEntryOptions":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/NumericEntryOptions.js","./NumericEntryType":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/NumericEntryType.js","./SecureEntryOptions":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/SecureEntryOptions.js","./TransactionType":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/TransactionType.js","./appMessage":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/appMessage.js","events":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/events/events.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/CardStatus.js":[function(require,module,exports){
"use strict";

exports.__esModule = true;
/**
 * The current status of the contact based card reader
 * @enum {int}
 */
var CardStatus = {
  /**
   * There is no card inserted in the reader.
   */
  None: 0,
  /**
   * A card is inserted in the reader but it is not EMV
   */
  NonEmvCard: 1,
  /**
   * An EMV card is inserted in the reader
   */
  EmvCard: 3
};

exports.default = CardStatus;
},{}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/DeviceUpdate.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

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; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

var _events = require('events');

var _manticore = require('manticore');

var _manticore2 = _interopRequireDefault(_manticore);

var _manticoreLog = require('manticore-log');

var _manticoreLog2 = _interopRequireDefault(_manticoreLog);

var _appMessage = require('./appMessage');

var _appMessage2 = _interopRequireDefault(_appMessage);

var _paymentDeviceError = require('./paymentDeviceError');

var _deviceState = require('./deviceState');

var _deviceState2 = _interopRequireDefault(_deviceState);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (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 } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var Log = (0, _manticoreLog2.default)('paymentDevice.deviceUpdate');

/**
 * A device update object is passed to your application via the PaymentDevice#updateRequired event and is capable
 * of applying an update to a device.
 * @class
 * @property {bool} isRequired Whether the update is required before taking further transactions using the device
 * @property {bool} wasInstalled Indicates if the update was installed
 * @property {bool} updateInProgress True if software update is in progress @readonly
 */

var DeviceUpdate = function (_EventEmitter) {
  _inherits(DeviceUpdate, _EventEmitter);

  /**
   * Nobody can make me but Javascript
   * @private
   * @constructor
   * @param {PaymentDevice} device
   */
  function DeviceUpdate(device) {
    _classCallCheck(this, DeviceUpdate);

    var _this = _possibleConstructorReturn(this, _EventEmitter.call(this));

    _this.isRequired = true;
    _this.wasInstalled = false;
    _this.device = device;
    _this._firmwareUpdateCallbacks = [];
    return _this;
  }

  /**
   * Determines if a software update is in progress
   * @private
   */


  /**
   * Display a prompt to the merchant offering the opportunity to upgrade the payment device, and optionally
   * update the device. Call the callback with completion status when the upgrade is complete or cancelled.
   * @param {DeviceUpdate~completed} callback Called upon success or failure of the update attempt.
   */
  DeviceUpdate.prototype.offer = function offer(callback) {
    var _this2 = this;

    if (this.device.pendingUpdate && this.device.pendingUpdate !== this) {
      // If someone else is in charge of the update, let them handle it
      // This can happen if new info comes from the server in the intervening time.
      this.device.pendingUpdate.offer(callback);
      return;
    }

    // The validation callback allows DeviceUpdate handle the responsibility of success
    // And the responsibility to check for implementation specific validations is moved to the implementation
    var validateCallback = function validateCallback(error) {
      if (error) {
        Log.error('Device validation for SW Update check failed with error: ' + error + '. Cannot do SW Update');
        callback(error, false);
      } else {
        _this2.device.app.display({
          title: _this2.isRequired ? _appMessage2.default.SwUpdateRequired.title : _appMessage2.default.SwUpdateOptional.title,
          message: _this2.isRequired ? _appMessage2.default.SwUpdateRequired.message : _appMessage2.default.SwUpdateOptional.message,
          cancel: _appMessage2.default.SwUpdate.buttons.notNow,
          buttons: [_appMessage2.default.SwUpdate.buttons.updateNow]
        }, function (alertView, index) {
          alertView.dismiss();
          if (index === 0) {
            _this2.begin(callback);
            return;
          }
          callback(_paymentDeviceError.deviceError.swUpdateFailed, false);
        });
      }
    };
    this.validateUpdateEligibility(validateCallback);
  };

  DeviceUpdate.prototype._shiftAndInvokeUpdateCallbacks = function _shiftAndInvokeUpdateCallbacks(error, wasDeviceUpgraded) {
    var _this3 = this;

    var _loop = function _loop() {
      var cb = _this3._firmwareUpdateCallbacks.shift();
      _manticore2.default.setTimeout(function () {
        if (cb) {
          cb(error, wasDeviceUpgraded);
        }
      }, 0);
    };

    while (this._firmwareUpdateCallbacks.length > 0) {
      _loop();
    }
  };

  /**
   * Begin the software update.
   * @param {DeviceUpdate~completed} callback Called upon success or failure of the update attempt.
   */


  DeviceUpdate.prototype.begin = function begin(callback) {
    var _this4 = this;

    if (callback) {
      this._firmwareUpdateCallbacks.push(callback);
    }

    if (this.updateInProgress) {
      Log.debug(function () {
        return 'Firmware update is already in progress for ' + _this4.device.id + '. Will queue the callback';
      });
      return;
    }

    this.device.stopPollForBattery();

    this.device.addState(_deviceState2.default.softwareUpdate);

    this.beginDeviceUpdate(function (err, deviceUpgraded) {
      _this4.device.removeState(_deviceState2.default.softwareUpdate);
      if (err) {
        Log.error('Software update failed with Error: ' + err);
        _this4.device.app.display({
          title: _appMessage2.default.SwUpdateFailed.title,
          message: _appMessage2.default.SwUpdateFailed.message,
          buttons: [_appMessage2.default.SwUpdate.buttons.retry, _appMessage2.default.SwUpdate.buttons.notNow]
        }, function (a, ix) {
          a.dismiss();
          if (ix === 0) {
            _this4.begin(null);
          } else {
            _this4._shiftAndInvokeUpdateCallbacks(err, deviceUpgraded);
          }
        });
        return;
      }

      _this4.device.app.display({
        title: _appMessage2.default.SwUpdateSuccessful.title,
        message: _appMessage2.default.SwUpdateSuccessful.message,
        buttons: [_appMessage2.default.SwUpdate.buttons.ok]
      }, function (a) {
        var PaymentDevice = require('./PaymentDevice').default; // eslint-disable-line global-require
        a.dismiss();
        _this4.wasInstalled = true;
        Log.info('SW Update successfully completed on ' + _this4.device.id);
        _this4.device.startPollForBattery();
        _this4.device.display({
          id: PaymentDevice.Message.ReadyWithId,
          substitutions: { id: _this4.device.id },
          displaySystemIcons: true
        }, function () {});
        _this4._shiftAndInvokeUpdateCallbacks(err, deviceUpgraded);
      });
    });
  };

  /**
   * Actual implementation of software update
   * @param {DeviceUpdate~completed} callback Called upon success or failure of the update attempt.
   * @private
   */


  DeviceUpdate.prototype.beginDeviceUpdate = function beginDeviceUpdate(callback) {
    // eslint-disable-line no-unused-vars
    throw new Error('Subclass must implement this method');
  };

  /**
   * Check device-specific conditions for update such as battery level.
   */


  DeviceUpdate.prototype.validateUpdateEligibility = function validateUpdateEligibility(callback) {
    // The default implementation assumes no error
    callback();
  };

  _createClass(DeviceUpdate, [{
    key: 'updateInProgress',
    get: function get() {
      return this.device.hasState(_deviceState2.default.softwareUpdate);
    }
  }]);

  return DeviceUpdate;
}(_events.EventEmitter);

/**
 * Called when either the software update completed, failed, or was canceled. (To detect the user having chosen
 * not to update, check that the error is null but deviceUpgraded is false.
 * @callback DeviceUpdate~completed
 * @param {error} error The error that caused the update to fail, if any
 * @param {bool} deviceUpgraded True if the device has been successfully updated.
 */

/**
 * Payment device connected via USB needs to be unplugged and plugged back to the USB port for the software
 * update to complete
 * @event DeviceUpdate#reconnectReader
 * @param {int} waitTime The duration within which the device needs to be reconnected
 */


exports.default = DeviceUpdate;
},{"./PaymentDevice":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/PaymentDevice.js","./appMessage":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/appMessage.js","./deviceState":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/deviceState.js","./paymentDeviceError":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/paymentDeviceError.js","events":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/events/events.js","manticore":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore/browser.js","manticore-log":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-log/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/FormFactor.js":[function(require,module,exports){
"use strict";

exports.__esModule = true;
// TODO The naming convention is not correct! Use camelCase for constants and it's properties

/**
 * A payment form factor describes the process used by the consumer to
 * communicate payment credentials to the merchant.
 * @enum {int}
 */
var FormFactor = {
  /**
   * This value is returned if a given merchant and payment device share no
   * common accepted form factors.
   */
  None: 0,
  /**
   * The consumer (or merchant) swipes the consumer's magnetic card through a
   * magnetic card reader
   */
  MagneticCardSwipe: 1,
  /**
   * The consumer dips a card with a smart chip into a smart card reader (e.g. EMV Chip&PIN)
   */
  Chip: 2,
  /**
   * An EMV-certified contactless card is presented and read by an
   * EMV-certified contactless reader
   */
  EmvCertifiedContactless: 3,
  /**
   * A terminal capable of collecting and encrypting a manually entered
   * account number (aka PAN) was used to collect some or all of the
   * necessary information
   */
  SecureManualEntry: 4,
  /**
   * Unencrypted card number entered manually from an App/Terminal
   */
  ManualCardEntry: 5
};

exports.default = FormFactor;
},{}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/MagneticCard.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

var _manticoreLog = require('manticore-log');

var _manticoreLog2 = _interopRequireDefault(_manticoreLog);

var _Card2 = require('./Messages/Card');

var _Card3 = _interopRequireDefault(_Card2);

var _FormFactor = require('./FormFactor');

var _FormFactor2 = _interopRequireDefault(_FormFactor);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (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 } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var Log = (0, _manticoreLog2.default)('payment');

/**
 * Information about a card presented to the PayPal Retail SDK
 * @class
 * @extends Card
 * @property {string} pan The personal account number (usually masked)
 * @property {string} expiration The expiration date (YYMM)
 * @property {string} track1 Encrypted track1 data if available
 * @property {string} track2 Encrypted track2 data if available
 * @property {string} track3 Encrypted track3 data if available
 * @property {string} firstName Cardholder first name
 * @property {string} lastName Cardholder last name
 * @property {string} middleInitial Cardholder middle name
 * @property {string} ksn Key serial number of the reader used to interpret the track data
 */

var MagneticCard = function (_Card) {
  _inherits(MagneticCard, _Card);

  function MagneticCard() {
    _classCallCheck(this, MagneticCard);

    var _this = _possibleConstructorReturn(this, _Card.call(this));

    _this.nativeClass = 'MagneticCard';
    _this.formFactor = _FormFactor2.default.MagneticCardSwipe;
    return _this;
  }

  MagneticCard.prototype.parseName = function parseName(name) {
    Log.debug('Not parsing ' + name);
  };

  return MagneticCard;
}(_Card3.default);

exports.default = MagneticCard;
},{"./FormFactor":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/FormFactor.js","./Messages/Card":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/Messages/Card.js","manticore-log":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-log/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/MagneticReaderDevice.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

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; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

var _manticoreLog = require('manticore-log');

var _manticoreLog2 = _interopRequireDefault(_manticoreLog);

var _PaymentDevice2 = require('./PaymentDevice');

var _PaymentDevice3 = _interopRequireDefault(_PaymentDevice2);

var _FormFactor = require('./FormFactor');

var _FormFactor2 = _interopRequireDefault(_FormFactor);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (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 } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var Log = (0, _manticoreLog2.default)('payment');

/**
 * Represents a magnetic card reader with limited capabilities.
 * @class
 * @protected
 */

var MagneticReaderDevice = function (_PaymentDevice) {
  _inherits(MagneticReaderDevice, _PaymentDevice);

  function MagneticReaderDevice(uniqueName, native) {
    _classCallCheck(this, MagneticReaderDevice);

    // Connect to the reader and get details
    var _this = _possibleConstructorReturn(this, _PaymentDevice.call(this, uniqueName, native));

    _this.connect(function () {
      if (!_this.isActivated) {
        _this.disconnect();
      }
    });
    return _this;
  }

  MagneticReaderDevice.prototype.connect = function connect(callback) {
    var _this2 = this;

    if (this.native.isConnected()) {
      Log.debug(function () {
        return 'Connect called, but ' + _this2.id + ' is already connected.';
      });
      if (callback) {
        callback();
      }
    }
    Log.debug(function () {
      return 'Connecting to Magnetic Reader ' + _this2.id;
    });
    this.native.connect(function (error) {
      Log.debug(function () {
        return 'Connected to Magnetic Reader ' + _this2.id;
      });
      if (callback) {
        callback(error);
      }
    });
  };

  MagneticReaderDevice.prototype.disconnect = function disconnect(callback) {
    this.native.disconnect(callback);
  };

  /**
   * Data has been received from the device
   * @param {object} event
   */


  MagneticReaderDevice.prototype.received = function received(event) {
    if (event && event.type === 'start') {
      // Swipe started
    } else if (event && event.type === 'fail') {
      // Swipe failed
    } else if (event.formFactor) {
      if (!event.reader) {
        event.reader = this;
      }
      this.emit('cardPresented', event);
    }
  };

  _createClass(MagneticReaderDevice, [{
    key: 'formFactors',
    get: function get() {
      return [_FormFactor2.default.MagneticCardSwipe];
    }
  }]);

  return MagneticReaderDevice;
}(_PaymentDevice3.default);

exports.default = MagneticReaderDevice;
},{"./FormFactor":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/FormFactor.js","./PaymentDevice":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/PaymentDevice.js","manticore-log":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-log/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/ManuallyEnteredCard.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

var _manticoreLog = require('manticore-log');

var _manticoreLog2 = _interopRequireDefault(_manticoreLog);

var _Card2 = require('./Messages/Card');

var _Card3 = _interopRequireDefault(_Card2);

var _FormFactor = require('./FormFactor');

var _FormFactor2 = _interopRequireDefault(_FormFactor);

var _cardError = require('./cardError');

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (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 } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var regExDate = /^(1[0-2]|0[1-9])([0-9]{4})$/;
var Log = (0, _manticoreLog2.default)('card.manuallyEnteredCard');

/**
 * Certain regions support manual entry of credit card numbers. The retail SDK requires
 * that you use an EMV certified terminal to gather an encrypted PAN and when doing so,
 * an object of type ManuallyEnteredCard would be returned, which can be presented to
 * the backend services to collect payment
 * @class
 * @extends Card
 */

var ManuallyEnteredCard = function (_Card) {
  _inherits(ManuallyEnteredCard, _Card);

  /**
   * Create a new instance of Manually Entered card for key-in payments
   * @constructor
   */
  function ManuallyEnteredCard() {
    _classCallCheck(this, ManuallyEnteredCard);

    var _this = _possibleConstructorReturn(this, _Card.call(this));

    _this.formFactor = _FormFactor2.default.ManualCardEntry;
    return _this;
  }

  /**
   * cardNumber Number of the provided card
   * @param {string} value
   */


  ManuallyEnteredCard.prototype.setCardNumber = function setCardNumber(value) {
    this._cardNumber = value;
  };

  /**
   * cardNumber Number of the provided card
   * @returns {string}
   */


  ManuallyEnteredCard.prototype.getCardNumber = function getCardNumber() {
    return this._cardNumber;
  };

  /**
   * The CVV on the card for payment. E.g. 131
   * @param {string} value
   */


  ManuallyEnteredCard.prototype.setCVV = function setCVV(value) {
    this._cvv = value;
  };

  /**
   * The CVV on the card for payment. E.g. 131
   * @returns {string}
   */


  ManuallyEnteredCard.prototype.getCVV = function getCVV() {
    return this._cvv;
  };

  /**
   * Primary account holder's billing postal code
   * @param {string} value
   */


  ManuallyEnteredCard.prototype.setPostalCode = function setPostalCode(value) {
    this._postalCode = value;
  };

  /**
   * Primary account holder's billing postal code
   * @returns {string}
   */


  ManuallyEnteredCard.prototype.getPostalCode = function getPostalCode() {
    return this._postalCode;
  };

  /**
   * Set the card expiration date in (MMYYYY) format. E.g. 092019 for Sep, 2019
   * @param {string} date Date in MMYYYY format
   */


  ManuallyEnteredCard.prototype.setExpiration = function setExpiration(date) {
    var match = regExDate.exec(date);
    if (!match) {
      Log.error('Invalid expiration date ' + date + ' was provided which is not in format MMYYYY');
      throw _cardError.cardError.invalidExpiryDate;
    }
    this._expiration = date;
  };

  /**
   * Get the card expiration date in MMYYYY format
   * @returns {string} Card expiration date
   */


  ManuallyEnteredCard.prototype.getExpiration = function getExpiration() {
    return this._expiration;
  };

  ManuallyEnteredCard.prototype.toJSON = function toJSON() {
    var jsonVal = _Card.prototype.toJSON.call(this);
    jsonVal.cardNumber = this.getCardNumber();
    jsonVal.expiration = this.getExpiration();
    jsonVal.postalCode = this.getPostalCode();
    jsonVal.cvv = !!this.getCVV();
    return jsonVal;
  };

  ManuallyEnteredCard.prototype.toString = function toString() {
    return JSON.stringify(this.toJSON());
  };

  return ManuallyEnteredCard;
}(_Card3.default);

exports.default = ManuallyEnteredCard;
},{"./FormFactor":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/FormFactor.js","./Messages/Card":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/Messages/Card.js","./cardError":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/cardError.js","manticore-log":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-log/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/Messages/AvailableApplications.js":[function(require,module,exports){
"use strict";

exports.__esModule = true;

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

/**
 * User needs to select an Application in order to proceed with a transaction
 * @property {Object} deviceResponse The raw response from the device
 * @property {Object} apps An array of [id,name] pairs identifying applications to pick from
 */
var AvailableApplications = function () {
  function AvailableApplications(deviceResponse) {
    _classCallCheck(this, AvailableApplications);

    this.deviceResponse = deviceResponse;
    this.apps = [];
  }

  AvailableApplications.prototype.toString = function toString() {
    return "AvailableApplications: " + this.apps.length + " apps\nRaw Response: " + this.deviceResponse.toString();
  };

  return AvailableApplications;
}();

exports.default = AvailableApplications;
},{}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/Messages/Card.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

var _moment = require('moment');

var _moment2 = _interopRequireDefault(_moment);

var _FormFactor = require('../FormFactor');

var _FormFactor2 = _interopRequireDefault(_FormFactor);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

/**
 * Information about a card presented to the PayPal Retail SDK
 * @class
 * @property {FormFactor} formFactor The process used by consumer to present the card @readonly
 * @property {bool} failed The presentation failed and this event is simply a notice of failure @readonly
 * @property {PaymentDevice} reader The device used to read the card @readonly
 * @property {string} timestamp A server-compatible formatted time for when this
 *  presentation occurred @readonly
 * @property {string} lastFourDigits Last four digits of the presented card @readonly
 * @property {CardIssuer} cardIssuer Issuer of the card that was presented to the SDK @readonly
 * @property {string} cardholderName Name of consumer who owns the presented card @readonly
 * @property {bool} pinPresent Indicates if pin was entered after presenting the card @readonly
 * @property {bool} isContactlessMSD Indicates if a contactless MSD card was presented @readonly
 * @property {bool} isSignatureRequired true if given the card and the context in which it
 *  was presented, a signature is required. @readonly
 */
var Card = function () {
  function Card() {
    _classCallCheck(this, Card);

    this.timestamp = (0, _moment2.default)().format();
    this.isSignatureRequired = false;
    this.isContactlessMSD = false;
    this.pinPresent = false;
    this.failed = false;
    this.chipCard = false;
    this.isMSRFallbackAllowed = false;
  }

  /**
   * Indicates if the presented card is EMV
   * @returns {bool} true if EMV card was presented
   */


  Card.prototype.isEmv = function isEmv() {
    return (this.formFactor === _FormFactor2.default.Chip || this.formFactor === _FormFactor2.default.EmvCertifiedContactless) && !this.isContactlessMSD;
  };

  Card.prototype.toJSON = function toJSON() {
    return {
      timestamp: this.timestamp,
      isSignatureRequired: this.isSignatureRequired,
      isContactlessMSD: this.isContactlessMSD,
      pinPresent: this.pinPresent,
      failed: this.failed,
      formFactor: this.formFactor,
      lastFourDigits: this.lastFourDigits,
      cardIssuer: this.cardIssuer,
      cardholderName: this.cardholderName,
      chipCard: this.chipCard,
      isMSRFallbackAllowed: this.isMSRFallbackAllowed
    };
  };

  Card.prototype.toString = function toString() {
    return JSON.stringify(this.toJSON());
  };

  return Card;
}();

exports.default = Card;
},{"../FormFactor":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/FormFactor.js","moment":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/moment/moment.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/Messages/CardPresentEvent.js":[function(require,module,exports){
"use strict";

exports.__esModule = true;
/**
 * The list of events that could be generated after a card is presented
 * @type {{cardDataRead: number, pinEvent: number, selectApplication: number}}
 */
var CardPresentEvent = {
  /**
   * EMV/Swipe data was read from the presented card
   */
  cardDataRead: 0,
  /**
   * PIN event
   */
  pinEvent: 1,
  /**
   * User needs to select an application before taking payment
   */
  appSelectionRequired: 2,
  /**
   * Card insert was detected, but EMV data was not read yet
   */
  insertDetected: 4
};

exports.default = CardPresentEvent;
},{}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/Messages/CardReaderResponse.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

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; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

/**
 * Card reader response including an APDU
 * @property {Buffer} raw The raw bytes of the response @readonly
 * @property {int} length The length of the data element of the response @readonly
 * @property {boolean} isUnsolicited Indicates if the response from card reader was unsolicited
 * @property {ApduResponse} apdu APDU response from card reader
 */
var CardReaderResponse = function () {
  function CardReaderResponse(buffer, length, isUnsolicited) {
    _classCallCheck(this, CardReaderResponse);

    this._raw = buffer;
    this._length = length;
    this._isUnsolicited = isUnsolicited;
  }

  CardReaderResponse.prototype.toString = function toString(shouldParse) {
    var str = ['<----\nCard reader response: ', this.apdu ? this.apdu.toString(shouldParse) : 'blank', '\n'];
    str.push('---->');
    return str.join('');
  };

  _createClass(CardReaderResponse, [{
    key: 'raw',
    get: function get() {
      return this._raw;
    }
  }, {
    key: 'length',
    get: function get() {
      return this._length;
    }
  }, {
    key: 'apdu',
    set: function set(val) {
      this._apdu = val;
    },
    get: function get() {
      return this._apdu;
    }
  }, {
    key: 'isUnsolicited',
    get: function get() {
      return this._isUnsolicited;
    }
  }, {
    key: 'tlvs',
    get: function get() {
      return this.apdu ? this.apdu.tlvs : null;
    }
  }]);

  return CardReaderResponse;
}();

exports.default = CardReaderResponse;
},{}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/Messages/DeviceStatus.js":[function(require,module,exports){
"use strict";

exports.__esModule = true;

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

/**
 * Information about a card presented to the PayPal Retail SDK
 * @class
 * @property {bool} isReady true if the device is ready for transaction @readonly
 * @property {error} error Reason (if any) for device unavailability  @readonly
 */
var DeviceStatus = function DeviceStatus() {
  _classCallCheck(this, DeviceStatus);
};

exports.default = DeviceStatus;
},{}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/Messages/PinEvent.js":[function(require,module,exports){
"use strict";

exports.__esModule = true;

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

/**
 * Details about a change in status of PIN entry or validation
 * @property {bool} completed Whether PIN entry has completed
 * @property {bool} correct Whether the PIN is correct
 * @property {bool} isLastAttempt Whether this PIN attempt is the last
 *  attempt before a potential card lockout
 * @property {int} digits Number of digits entered
 * @property {string} failureReason The failure reason, if any
 */
var PinEvent = function PinEvent() {
  _classCallCheck(this, PinEvent);
};

exports.default = PinEvent;
},{}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/NumericEntryOptions.js":[function(require,module,exports){
"use strict";

exports.__esModule = true;

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

/**
 * Options for asking for numeric entry on the EMV terminal. Because this is typically
 * a PIN entry device, you can't just display any message and get numeric entry
 * (e.g. "ENTER PIN" and then get the raw PIN). These options control and indicate
 * what you can ask for.
 * @class
 * @property {NumericEntryType} entryType The overall type of numeric entry desired
 * @property {string} editValue The existing amount to edit, if any
 */
var NumericEntryOptions = function NumericEntryOptions() {
  _classCallCheck(this, NumericEntryOptions);
};

/**
 * Called after a request for amount entry (via promptForAmountEntry) completes.
 * @callback NumericEntryOptions~amountEntered
 * @param {error} error The error encountered - namely cancellation or lack of terminal support
 * @param {string} amount The amount entered
 */


exports.default = NumericEntryOptions;
},{}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/NumericEntryType.js":[function(require,module,exports){
"use strict";

exports.__esModule = true;
/**
 * When you wish to get a numeric value from the device, you must specify precisely
 * which type of number you're asking for so that prompts and formats can be selected.
 * @enum {int}
 */
var NumericEntryType = {
  /**
   * A tip amount, in the local currency
   */
  GratuityAmount: 1,
  /**
   * A tip amount as a percentage of the current transaction total
   */
  GratuityPercentage: 2,
  /**
   * A mobile phone number
   */
  MobileNumber: 3,
  /**
   * Expiration date
   */
  ExpirationDate: 4,
  /**
   * Cardholder verification value
   */
  Cvv: 5
};

exports.default = NumericEntryType;
},{}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/PaymentDevice.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

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; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

var _manticoreLog = require('manticore-log');

var _manticoreLog2 = _interopRequireDefault(_manticoreLog);

var _events = require('events');

var _manticore = require('manticore');

var _manticore2 = _interopRequireDefault(_manticore);

var _manticoreUtil = require('manticore-util');

var _CardReader2 = require('./CardReader');

var _CardReader3 = _interopRequireDefault(_CardReader2);

var _FormFactor = require('./FormFactor');

var _FormFactor2 = _interopRequireDefault(_FormFactor);

var _DeviceStatus = require('./Messages/DeviceStatus');

var _DeviceStatus2 = _interopRequireDefault(_DeviceStatus);

var _readerInformation = require('./readerInformation');

var _paymentDeviceError = require('./paymentDeviceError');

var _deviceState = require('./deviceState');

var _deviceState2 = _interopRequireDefault(_deviceState);

var _ReaderModel = require('./ReaderModel');

var _ReaderModel2 = _interopRequireDefault(_ReaderModel);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (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 } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var Log = (0, _manticoreLog2.default)('paymentDevice');

var secureBlobStorage = 'E';
var itemKeyMerchantCardReaders = 'merchant-card-readers';
var msDefaultMaxConnectionDuration = 30000;

/*
 * The native application is responsible for discovering and communicating
 * with these devices. You are responsible for providing a native object which
 * implements connect/disconnect/isConnected/send functions and calls
 * received(bytes/events) on this object as appropriate.
 */

/**
 * A payment device represents the abstract concept of something that can read
 * payment information from a customer. This includes card swipe readers, EMV
 * readers, barcode scanners, biometric devices we don't have yet, and DNA
 * sequencers. Ok, not so much that last bit.
 *
 * @class
 * @property {string} id A unique identifier for the device @readonly
 * @property {string} address Hardware address of this device
 * @property {string} name A friendly name for the device @readonly
 * @property {string} manufacturer The manufacturer of the card reader @readonly
 * @property {ReaderModel} model The model of the card reader @readonly
 * @property {string} serialNumber The serial number of the device, if available @readonly
 * @property {BatteryInfo} lastKnownBatteryInfo Status of the device battery @readonly
 * @property {bool} activated shows if the device has any active transaction @readonly
 * @property {[FormFactor]} formFactors The payment form factors
 *  this device can support @readonly
 * @property {DeviceUpdate} pendingUpdate Any pending software update for
 *  this device, or null if the device is current
 *  @property {readerType} type Indicates the type of reader @readonly
 *  @property {readerConnectionType} connectionType Indicates the connection channel of the reader @readonly
 *  @property {bool} cardInSlot Indicates whether a card is inserted within the reader at this moment @readonly
 *
 */

var PaymentDevice = function (_CardReader) {
  _inherits(PaymentDevice, _CardReader);

  /**
   * Construct a new PaymentDevice given native functions capable of sending
   *  data, connect, disconnect and retrieve connection status from the reader
   * @param {string} uniqueId A unique identifier for this device, usually including
   *  type and serial number
   * @param {Object} native Interface to native components
   * @param {Object} app Interface to app components
   * @param {bool} isUsb
   * @param {string} hardwareAddress Hardware address of the connected
   * @private
   */
  function PaymentDevice(uniqueId, native, app, isUsb, hardwareAddress) {
    _classCallCheck(this, PaymentDevice);

    var _this = _possibleConstructorReturn(this, _CardReader.call(this, uniqueId, native));

    _this.id = uniqueId;
    _this.address = hardwareAddress;
    _this.native = native;
    _this.app = app;
    _this.cardPresented = false;
    _this.isUsb = isUsb;
    _this.type = _readerInformation.readerType.Unknown;
    _this.connectionType = _readerInformation.readerConnectionType.Unknown;
    _this.cardInsertedHandler = null;
    _this._connectionCallbacks = [];
    _this.cardInSlot = false;
    _this._sEventNames = new Set();
    _this._sActiveFormFactors = new Set();
    _this.setMaxListeners(30);
    _this.model = _ReaderModel2.default.Unknown;
    Log.debug(function () {
      return 'Create PaymentDevice with id: ' + uniqueId + ', address: ' + hardwareAddress + ', isUSB: ' + isUsb + ', native: ' + !!native + ', app: ' + !!app;
    });
    return _this;
  }

  PaymentDevice.prototype._getCardReaderId = function _getCardReaderId(serialNumber) {
    return this.model + '-' + serialNumber;
  };

  // TODO Un-comment this (& related test cases) when US917612 is unblocked


  PaymentDevice.prototype.setCardReaderToMerchant = function setCardReaderToMerchant(serialNumber) {
    var _this2 = this;

    if (!serialNumber) {
      Log.warn('Cannot assign card reader \'' + this.id + '\' with serial number ' + serialNumber + ' to merchant as serial number was not defined');
      return;
    }
    this.serialNumber = serialNumber;
    var merchant = this.app.getMerchant();
    if (!merchant || !merchant.emailAddress) {
      Log.warn('setCardReader> Cannot assign card reader \'' + this.id + '\' with serial number ' + serialNumber + ' to merchant as merchant or their email Address was not set');
      return;
    }

    Log.debug(function () {
      return 'Assigning \'' + _this2.id + '\' with serial number \'' + serialNumber + '\' to merchant with business name \'' + merchant.businessName + '\' and email \'' + merchant.emailAddress + '\'';
    });
    _manticore2.default.getItem(itemKeyMerchantCardReaders, secureBlobStorage, function (err, pref) {
      Log.debug(function () {
        return 'setCardReader> Received saved merchant pref: \'' + JSON.stringify(pref) + '\'. Error: ' + JSON.stringify(err);
      });
      var doRequest = false;
      var savedPref = void 0;
      if (!pref) {
        doRequest = true;
      } else {
        savedPref = JSON.parse(pref);
        if (savedPref.emailAddress !== merchant.emailAddress) {
          doRequest = true;
        } else {
          var readers = savedPref.readers || [];
          if (readers.indexOf(_this2._getCardReaderId(serialNumber)) < 0) {
            doRequest = true;
          }
        }
      }

      if (!doRequest) {
        Log.debug(function () {
          return 'setCardReader> Skip setting serial number \'' + serialNumber + '\' as it was previously assigned. ' + JSON.stringify(savedPref);
        });
        return;
      }

      var body = {
        asset: {
          status: 'ENABLED',
          serial: serialNumber,
          batch: _this2.model,
          family: _this2.manufacturer
        }
      };
      merchant.request({
        service: 'devices',
        op: 'assets',
        format: 'json',
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(body)
      }, function (errRz, rz) {
        if (errRz) {
          Log.warn('setCardReader> ' + _this2.id + ' Failed to assign asset to merchant\nRequest: ' + JSON.stringify(body) + '\nError: ' + JSON.stringify(errRz) + '\nResponse:' + JSON.stringify(rz));
        } else {
          Log.info('setCardReader> Assigned \'' + _this2.id + '\' with serial number \'' + serialNumber + '\' to merchant with business name \'' + merchant.businessName + '\'');
          Log.debug(function () {
            return 'setCardReader> Response from assigning \'' + _this2.id + '\' with serial # \'' + serialNumber + '\' to \'' + merchant.businessName + '\' was ' + JSON.stringify(rz);
          });

          var newPref = savedPref || {};
          newPref.emailAddress = merchant.emailAddress;
          newPref.readers = newPref.readers || [];
          newPref.readers.push(_this2._getCardReaderId(serialNumber));
          Log.debug(function () {
            return 'setCardReader> Updating merchant preference from \'' + JSON.stringify(savedPref) + '\' to \'' + JSON.stringify(newPref) + '\'';
          });
          _manticore2.default.setItem(itemKeyMerchantCardReaders, secureBlobStorage, JSON.stringify(newPref), function (errSet, path) {
            if (errSet) {
              Log.error(function () {
                return 'setCardReader> Could not save data ' + JSON.stringify(newPref) + ' to device due to error ' + JSON.stringify(errSet);
              });
            }
            Log.debug(function () {
              return 'setCardReader> Saved \'' + _this2.id + '\' merchant pref to ' + path;
            });
          });
        }
      });
    });
  };

  /**
   * Extract logs from the device.
   * @method
   * @param {PaymentDevice~deviceLogs} callback Called when the logs are extracted
   */


  PaymentDevice.prototype.extractReaderLogs = function extractReaderLogs(callback) {
    callback(new Error('Not implemented'));
  };

  PaymentDevice.prototype.equals = function equals(id, manufacturer) {
    return this.id === id && this.manufacturer === manufacturer;
  };

  /**
   * Called internally when a new device has been discovered to register the device
   * and notify listeners of the new device.
   * @private
   */


  PaymentDevice.discovered = function discovered(pd) {
    for (var _iterator = PaymentDevice.devices, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
      var _ref;

      if (_isArray) {
        if (_i >= _iterator.length) break;
        _ref = _iterator[_i++];
      } else {
        _i = _iterator.next();
        if (_i.done) break;
        _ref = _i.value;
      }

      var device = _ref;

      if (device.equals(pd.id, pd.manufacturer)) {
        Log.info(pd + ' was previously discovered... Will not emit device discovered event');
        return false;
      }
    }
    PaymentDevice.devices.push(pd);
    Log.info('Discovered device ' + pd + '... Existing devices: ' + JSON.stringify(PaymentDevice.devices));
    PaymentDevice.Events.emit('deviceDiscovered', pd);
    return true;
  };

  /**
   * Remove listeners for all events
   * @private
   */


  PaymentDevice.prototype.removeAllCardReaderListeners = function removeAllCardReaderListeners() {
    var _this3 = this;

    var _loop = function _loop() {
      if (_isArray2) {
        if (_i2 >= _iterator2.length) return 'break';
        _ref2 = _iterator2[_i2++];
      } else {
        _i2 = _iterator2.next();
        if (_i2.done) return 'break';
        _ref2 = _i2.value;
      }

      var name = _ref2;

      Log.debug(function () {
        return _this3.id + ' Removing ' + _this3.listenerCount(name) + ' listeners for \'' + name + '\' event';
      });
      _this3.removeAllListeners(name);
    };

    for (var _iterator2 = this._sEventNames.values(), _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) {
      var _ref2;

      var _ret = _loop();

      if (_ret === 'break') break;
    }
    Log.info(this.id + ' Removed device from cache and dropped listeners from ' + this._sEventNames.size + ' events. Remaining devices: ' + PaymentDevice.devices.length);
    this._sEventNames.clear();
  };

  /**
   * Called internally (by native) when the device has been removed from the system
   * @private
   */


  PaymentDevice.prototype.removed = function removed() {
    var _this4 = this;

    Log.info('removed() ' + this.id + ' was removed');
    this.connectionInProgress = false;
    this._sActiveFormFactors.clear();
    Log.debug(function () {
      return _this4.id + ' Cleared all active form factors as part of removed()';
    });
    if (this.isConnected()) {
      Log.debug(function () {
        return 'removed() ' + _this4.id + ' was connected... Will disconnect it first';
      });
      this.disconnect();
    }
    var ix = PaymentDevice.devices.indexOf(this);
    if (ix >= 0) {
      if (!this._isFirmwareUpdateInProgress) {
        PaymentDevice.devices.splice(ix, 1);
      } else {
        Log.info('removed() Will not remove ' + this.id + ' from cache as Firmware update is in progress');
      }
    }
    this.beginDeviceRemoved(function (err) {
      if (err) {
        Log.warn(_this4.id + ' remove failed with error ' + err);
      } else {
        Log.debug(function () {
          return _this4.id + ' was successfully removed';
        });
        if (!_this4._isFirmwareUpdateInProgress) {
          _this4.emit(PaymentDevice.Event.deviceRemoved, _this4);
          _this4.removeAllCardReaderListeners();
        }
      }
    });
  };

  /**
   * Called internally when connection has been verified, but the device must
   * be updated before being ready
   * @private
   */


  PaymentDevice.prototype.updateRequired = function updateRequired(update) {
    var _this5 = this;

    Log.debug(this.id + ' needs an update.');
    this.pendingUpdate = update;
    if (this.isReady) {
      this.emit(PaymentDevice.Event.updateRequired, update);
    } else {
      Log.debug('Update ' + this.id + ' requires an update, but the card reader is not ready. Will emit updateRequired event once device is connected');
      this.once(PaymentDevice.Event.connected, function () {
        return _this5.emit(PaymentDevice.Event.updateRequired, update);
      });
    }
  };

  PaymentDevice.prototype.activateForPayment = function activateForPayment(context, formFactors, showPrompt) {
    var _this6 = this;

    // eslint-disable-line no-unused-vars
    for (var _iterator3 = formFactors, _isArray3 = Array.isArray(_iterator3), _i3 = 0, _iterator3 = _isArray3 ? _iterator3 : _iterator3[Symbol.iterator]();;) {
      var _ref3;

      if (_isArray3) {
        if (_i3 >= _iterator3.length) break;
        _ref3 = _iterator3[_i3++];
      } else {
        _i3 = _iterator3.next();
        if (_i3.done) break;
        _ref3 = _i3.value;
      }

      var ff = _ref3;

      this._sActiveFormFactors.add(ff);
    }
    this.context = context;
    Log.debug(function () {
      return _this6.id + ' activated for \'' + context.id + '\' and formFactors \'' + (0, _manticoreUtil.getPropertyName)(_FormFactor2.default, formFactors) + '\'. All active formFactors: ' + (0, _manticoreUtil.getPropertyName)(_FormFactor2.default, [].concat(_toConsumableArray(_this6._sActiveFormFactors)));
    });
  };

  PaymentDevice.prototype.deactivateFormFactors = function deactivateFormFactors(formFactors, callback) {
    var _this7 = this;

    for (var _iterator4 = formFactors, _isArray4 = Array.isArray(_iterator4), _i4 = 0, _iterator4 = _isArray4 ? _iterator4 : _iterator4[Symbol.iterator]();;) {
      var _ref4;

      if (_isArray4) {
        if (_i4 >= _iterator4.length) break;
        _ref4 = _iterator4[_i4++];
      } else {
        _i4 = _iterator4.next();
        if (_i4.done) break;
        _ref4 = _i4.value;
      }

      var ff = _ref4;

      this._sActiveFormFactors.delete(ff);
    }
    Log.debug(function () {
      return _this7.id + ' Removed active formFactors \'' + (0, _manticoreUtil.getPropertyName)(_FormFactor2.default, formFactors) + '\'. Remaining active: ' + (0, _manticoreUtil.getPropertyName)(_FormFactor2.default, [].concat(_toConsumableArray(_this7._sActiveFormFactors)));
    });
    if (callback) {
      callback();
    }
  };

  PaymentDevice.prototype.getSetOfActiveFormFactors = function getSetOfActiveFormFactors() {
    return new Set(this._sActiveFormFactors); // Create shallow copy to make it immutable from outside
  };

  /**
   * Returns true if any form factor is active
   * @private
   */


  PaymentDevice.prototype.isFormFactorActive = function isFormFactorActive(formFactor) {
    return this._sActiveFormFactors.has(formFactor);
  };

  PaymentDevice.prototype.abortTransaction = function abortTransaction(context, callback) {
    var _this8 = this;

    Log.debug(function () {
      return 'Aborted transaction on ' + _this8.id;
    });
    this.cardPresented = false;
    this._sActiveFormFactors.clear();
    Log.debug(function () {
      return _this8.id + ' Cleared all active form factors as part of abortTransaction()';
    });
    if (callback) {
      callback();
    }
  };

  PaymentDevice.prototype.postTransactionCleanup = function postTransactionCleanup(callback) {
    if (callback) {
      callback();
    }
  };

  PaymentDevice.prototype._checkAndDismissAlerts = function _checkAndDismissAlerts(alertToDismiss, showPrompt) {
    if (alertToDismiss && showPrompt) {
      alertToDismiss.dismiss();
    }
  };

  PaymentDevice.prototype._shiftAndInvokeConnectionCallback = function _shiftAndInvokeConnectionCallback(err) {
    var _this9 = this;

    Log.debug(function () {
      return _this9.id + ' Invoking ' + _this9._connectionCallbacks.length + ' connection callback handlers';
    });

    var _loop2 = function _loop2() {
      var cb = _this9._connectionCallbacks.shift();
      _manticore2.default.setTimeout(function () {
        if (cb) {
          cb(err);
        }
      }, 0);
    };

    while (this._connectionCallbacks.length > 0) {
      _loop2();
    }
    this.connectionInProgress = false;
  };

  PaymentDevice.prototype.waitForCardRemoval = function waitForCardRemoval(cb) {
    var _this10 = this;

    if (!this.cardInSlot || !this.isConnected()) {
      Log.debug(function () {
        return 'Will not wait for card removal as card is not in slot. cardInSlot: ' + _this10.cardInSlot + ' connected: ' + _this10.isConnected();
      });
      cb();
      return;
    }

    var cardRemovedHandler = function cardRemovedHandler(err) {
      _this10.removeListener(PaymentDevice.Event.disconnected, cardRemovedHandler);
      _this10.removeListener(PaymentDevice.Event.cardRemoved, cardRemovedHandler);
      cb(err);
    };

    this.listenForCardRemoval(function (err) {
      if (err) {
        Log.warn('Will not listen for card removal events due to error ' + err);
        cardRemovedHandler(err);
      }
    });

    this.once(PaymentDevice.Event.disconnected, cardRemovedHandler);
    this.once(PaymentDevice.Event.cardRemoved, cardRemovedHandler);
  };

  /**
   * Connect to this device. A device connected event will be emitted once the device is connected
   * @method
   * @param {PaymentDevice~connect} callback Callback with connection status
   */


  PaymentDevice.prototype.connect = function connect(callback) {
    var _this11 = this;

    if (callback) {
      this._connectionCallbacks.push(callback);
    }

    if (!this._isFirmwareUpdateInProgress && this.connectionInProgress) {
      Log.debug(function () {
        return 'Connection already in progress for ' + _this11.id + '. Will not re-connect, but queue the callback';
      });
      return;
    }

    var future = _manticore2.default.setTimeout(function () {
      Log.info('Connection to ' + _this11.id + ' timed-out after waiting for ' + PaymentDevice.ConnectionTimeOut + 'ms. Will force a disconnect');
      _this11.forceDisconnect(function () {
        Log.info('Forced a disconnect on ' + _this11.id + ' due to connection timeout');
        var err = _paymentDeviceError.deviceError.generic.withDevMessage('Connection timed out');
        _this11.emit(PaymentDevice.Event.connectionError, err);
        _this11._shiftAndInvokeConnectionCallback(err);
      });
    }, PaymentDevice.ConnectionTimeOut);

    this.isReady = false;
    var connectionStart = new Date().getTime();
    this.connectionInProgress = true;
    this._sActiveFormFactors.clear(); // Assumption is that a reconnection clears resets the device state and drops all activated form factors
    Log.debug(function () {
      return _this11.id + ' Cleared all active form factors as part of connect()';
    });
    this.beginDeviceConnect(function (err) {
      var timeElapsed = new Date().getTime() - connectionStart;
      future.cancel();
      if (err) {
        Log.error('Connection with ' + _this11.id + ' (Duration: ' + timeElapsed + 'ms) failed with error ' + JSON.stringify(err));
        if (!_this11._isFirmwareUpdateInProgress) {
          _this11.emit(PaymentDevice.Event.connectionError, err);
        }
        _this11.connectionInProgress = false;
        _this11._shiftAndInvokeConnectionCallback(err);
      } else {
        Log.info('Successfully connected to ' + _this11.id + '. Duration: ' + timeElapsed + 'ms');
        _this11.onConnected();
        _this11._shiftAndInvokeConnectionCallback();
      }
    });
  };

  /**
   * Called internally when connection sequence with this device was complete.
   * The device will be ready to be used if payments if the connection was verified
   * with no errors
   * @private
   */


  PaymentDevice.prototype.onConnected = function onConnected() {
    var _this12 = this;

    Log.debug(function () {
      return _this12.id + ' is ready.';
    });
    this.isReady = true;
    if (!this._isFirmwareUpdateInProgress) {
      this.emit(PaymentDevice.Event.connected);
    }
    this.startPollForBattery();
  };

  /**
   * Query card reader for battery information
   * @param {PaymentDevice~batteryInfo} cb Callback with battery information
   */


  PaymentDevice.prototype.retrieveBatteryInfo = function retrieveBatteryInfo(cb) {
    var _this13 = this;

    this.getBatteryInfo(function (err, batteryInfo) {
      if (err) {
        Log.error('Error retrieving battery info: ' + err);
      } else {
        _this13.lastKnownBatteryInfo = batteryInfo;
        Log.debug(function () {
          return 'Received battery info for ' + _this13.id + ': ' + batteryInfo;
        });
      }
      cb(err, batteryInfo);
    });
  };

  PaymentDevice.prototype._continuallyPollForBattery = function _continuallyPollForBattery() {
    var _this14 = this;

    if (!this.isReady || !this.pollForBattery) {
      return;
    }
    this.getBatteryInfo(function (err, batteryInfo) {
      _this14.lastKnownBatteryInfo = batteryInfo;
      if (_this14.lastKnownBatteryInfo) {
        _this14.emit(PaymentDevice.Event.batteryStatusUpdate, _this14.lastKnownBatteryInfo);
      }

      // TODO - Make the polling smarter (e.g. You could poll less frequently when the battery level is almost full)
      if (_this14.isReady && _this14.pollForBattery) {
        _manticore2.default.setTimeout(function () {
          return _this14._continuallyPollForBattery.call(_this14);
        }, 30 * 1000);
      }
    });
  };

  PaymentDevice.prototype.startPollForBattery = function startPollForBattery() {
    Log.debug('startPollForBattery');
    if (!this.pollForBattery) {
      this.pollForBattery = true;
      this._continuallyPollForBattery();
    }
  };

  PaymentDevice.prototype.stopPollForBattery = function stopPollForBattery() {
    this.pollForBattery = false;
    Log.debug('stopPollForBattery');
  };

  /**
   * Force a card reader disconnect without performing any state validations. Should only be used in scenarios like
   * firmware update, device resets, etc. For all other cases, please use disconnect() API
   * @param callback Called when the disconnection attempt is complete
   * @private
   */
  PaymentDevice.prototype.forceDisconnect = function forceDisconnect(callback) {
    var _this15 = this;

    this._sActiveFormFactors.clear();
    Log.debug(function () {
      return _this15.id + ' Cleared all active form factors as part of disconnect()';
    });
    this.beginDeviceDisconnect(function (err) {
      if (err) {
        Log.warn(' ' + _this15.id + ' disconnect failed with error ' + err);
      } else {
        Log.debug(function () {
          return _this15.id + ' was successfully disconnected';
        });
        _this15.connectionInProgress = false;
        _this15.onDisconnected(null);
      }
      if (callback) {
        callback(err);
      }
    });
  };

  /**
   * Disconnect from the device.
   * @method
   * @param {PaymentDevice~disconnect} callback Called when the disconnection attempt is complete
   */


  PaymentDevice.prototype.disconnect = function disconnect(callback) {
    if (this.context && this.context.isPaymentInRetryOrProgress() || this._isFirmwareUpdateInProgress) {
      Log.debug('Device has an active transaction or firmware update is in progress. ' + 'Will not attempt to invoke native.disconnect');
      if (callback) {
        callback(_paymentDeviceError.deviceError.actionCannotBeCompleted);
      }
    } else {
      this.forceDisconnect(callback);
    }
  };

  /**
   * Gets the device version information
   * @method
   * @returns {object} Returns key-value pair of version type and value.
   */


  PaymentDevice.prototype.getVersionInfo = function getVersionInfo() {
    return {}; // Sub classes should override this
  };

  /**
   * Inform the Javascript class that the device has been disconnected.
   * @param {error} error Any error that caused disconnect
   * @private
   */


  PaymentDevice.prototype.onDisconnected = function onDisconnected(error) {
    var _this16 = this;

    Log.warn(function () {
      return 'Device ' + _this16.id + ' was disconnected with error message=' + (error && error.message) + ',code=' + (error && error.code) + ',' + JSON.stringify(error);
    });
    this.isReady = false;
    this.stopPollForBattery();
    if (!this._isFirmwareUpdateInProgress) {
      this.emit(PaymentDevice.Event.disconnected, error);
    }
  };

  /**
   * Attempt to cleanup any ties to native objects
   * @method
   * @private
   */


  PaymentDevice.prototype.destroy = function destroy() {
    this.native = null;
  };

  PaymentDevice.prototype.once = function once(eventName, listener) {
    listener.id = Math.floor(Math.random() * 10000000000000);
    _CardReader.prototype.once.call(this, eventName, listener);
  };

  PaymentDevice.prototype.on = function on(eventName, listener) {
    var _this17 = this;

    listener.id = listener.id || Math.floor(Math.random() * 10000000000000);
    _CardReader.prototype.on.call(this, eventName, listener);
    this._sEventNames.add(eventName);
    Log.debug(function () {
      return _this17.id + ' Added listener \'' + listener.id + '\' for \'' + eventName + '\'. ListenerCount: ' + _this17.listenerCount(eventName);
    });
  };

  PaymentDevice.prototype.removeListener = function removeListener(eventName, listener) {
    var _this18 = this;

    _CardReader.prototype.removeListener.call(this, eventName, listener);
    Log.debug(function () {
      return _this18.id + ' removeListener invoked on listener: \'' + (listener ? listener.id : 'null') + '\' for event:\'' + eventName + '\'';
    });
  };

  PaymentDevice.prototype.emit = function emit(eventName) {
    var _CardReader$prototype,
        _this19 = this;

    var _loop3 = function _loop3() {
      if (_isArray5) {
        if (_i5 >= _iterator5.length) return 'break';
        _ref5 = _iterator5[_i5++];
      } else {
        _i5 = _iterator5.next();
        if (_i5.done) return 'break';
        _ref5 = _i5.value;
      }

      var listener = _ref5;

      Log.debug(function () {
        return _this19.id + ' Emitting ' + eventName + ' to listener \'' + listener.id + '\'';
      });
    };

    for (var _iterator5 = this.listeners(eventName), _isArray5 = Array.isArray(_iterator5), _i5 = 0, _iterator5 = _isArray5 ? _iterator5 : _iterator5[Symbol.iterator]();;) {
      var _ref5;

      var _ret3 = _loop3();

      if (_ret3 === 'break') break;
    }

    for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
      args[_key - 1] = arguments[_key];
    }

    (_CardReader$prototype = _CardReader.prototype.emit).call.apply(_CardReader$prototype, [this, eventName].concat(args));
  };

  PaymentDevice.prototype.addState = function addState(state) {
    Log.debug('Adding state \'' + (0, _manticoreUtil.getPropertyName)(_deviceState2.default, state) + '\'');
    this.state |= state;
  };

  PaymentDevice.prototype.removeState = function removeState(state) {
    Log.debug('Removing device state \'' + (0, _manticoreUtil.getPropertyName)(_deviceState2.default, state) + '\'');
    this.state &= ~state;
  };

  PaymentDevice.prototype.hasState = function hasState(state) {
    return (this.state & state) === state;
  };

  /**
   * Return true if this device is connected
   * @method
   * @returns {bool} true if the device is currently connected
   */


  PaymentDevice.prototype.isConnected = function isConnected() {
    return this.native.isConnected();
  };

  /**
   * Indicates if the device is ready for transaction
   * @returns {DeviceStatus} deviceStatus
   */


  PaymentDevice.prototype.isReadyForTransaction = function isReadyForTransaction() {
    var status = new _DeviceStatus2.default();
    status.isReady = false;
    if (!this.isConnected()) {
      status.error = _paymentDeviceError.deviceError.deviceNotConnected;
    } else if (!this.isReady) {
      status.error = _paymentDeviceError.deviceError.notFunctional;
    } else if (this.isUpdateRequired()) {
      status.error = _paymentDeviceError.deviceError.swUpdatePending;
    } else if (this.lastKnownBatteryInfo && this.lastKnownBatteryInfo.isLevelCritical) {
      status.error = _paymentDeviceError.deviceError.lowOnBattery;
    } else {
      status.isReady = true;
      status.error = null;
    }
    return status;
  };

  PaymentDevice.prototype.isUpdateRequired = function isUpdateRequired() {
    return this.pendingUpdate && this.pendingUpdate.isRequired && !this.pendingUpdate.wasInstalled;
  };

  /**
   * Return true if this device has the requested capability
   * @method
   * @param {deviceCapabilityType} capability the enum type to check if the device has it
   * @returns {bool} true if the device supporting the capability
   */


  PaymentDevice.prototype.doesHaveCapability = function doesHaveCapability(capability) {
    // eslint-disable-line no-unused-vars
    return false;
  };

  /**
   * Display a predefined message on the terminal, if supported
   * @param {CardReader~readerDisplayArgs} opt Message display options
   * @param {function} callback Called when the message has been displayed, with any error
   * @private
   */


  PaymentDevice.prototype.display = function display(opt, callback) {
    // No-op by default, no error
    callback(null);
  };

  /**
   * Prompt for a non-secure amount or numeric value to be entered.
   * @param {NumericEntryOptions} options Options governing numeric entry
   * @param {NumericEntryOptions~amountEntered} callback Called when the attempt completes
   * @private
   */


  PaymentDevice.prototype.promptForNumericEntry = function promptForNumericEntry(options, callback) {
    // No-op by default, no error
    callback(null);
  };

  /**
   * Get a secure Personal Account Number (PAN) from the device
   * @param {SecureEntryOptions} options
   * @param {SecureEntryOptions~secureEntry} callback
   * @private
   */


  PaymentDevice.prototype.promptForSecureAccountNumber = function promptForSecureAccountNumber(options, callback) {
    // No-op by default, no error
    callback(null);
  };

  /**
   * Look at an accessory connection and decide if we support it. Will differ a bit
   * on different platforms
   * @private
   * @method
   * @param {object} info
   */
  PaymentDevice.isSupported = function isSupported(info) {
    if (info.protocols.indexOf('com.paypal.here.reader') >= 0) {
      return 'MiuraDevice';
    }
    return null;
  };

  PaymentDevice.prototype.toJSON = function toJSON() {
    return {
      id: this.id,
      name: this.name,
      manufacturer: this.manufacturer,
      model: this.model,
      serialNumber: this.serialNumber
    };
  };

  PaymentDevice.prototype.toString = function toString() {
    return JSON.stringify(this.toJSON());
  };

  _createClass(PaymentDevice, [{
    key: 'isActivated',
    get: function get() {
      return this._sActiveFormFactors.size > 0;
    }
  }, {
    key: '_isFirmwareUpdateInProgress',
    get: function get() {
      return this.pendingUpdate && this.pendingUpdate.updateInProgress;
    }
  }, {
    key: 'invoice',
    get: function get() {
      return this.context ? this.context.invoice : null;
    }
  }]);

  return PaymentDevice;
}(_CardReader3.default);

exports.default = PaymentDevice;


PaymentDevice.devices = [];

PaymentDevice.Event = {
  connected: 'connected',
  connectionError: 'connectionError',
  disconnected: 'disconnected',
  updateRequired: 'updateRequired',
  cardRemoved: 'cardRemoved',
  cardPresented: 'cardPresented',
  cancelled: 'cancelled',
  cancelRequested: 'cancelRequested',
  error: 'error',
  batteryStatusUpdate: 'batteryStatusUpdate',
  proceed: 'proceed',
  selected: 'selected',
  contactlessReaderDeactivated: 'contactlessReaderDeactivated',
  deviceRemoved: 'deviceRemoved'
};

/**
 * Indicates the maximum number of payment retries that are allowed per payment error event
 * @type {{InvalidChip: number}}
 * @private
 */
PaymentDevice.constant = {
  InvalidChipRetryCount: 2
};

/**
 * List of Auth codes that could be sent to the terminal in order to complete the transaction.
 * @type {{TrxnFailureAuthCode: string, TrxnSuccessAuthCode: string, NoNetworkAuthCode: string}}
 * @private
 */
PaymentDevice.authCode = {
  TransactionFailure: '8A023035',
  TransactionSuccess: '8A023030',
  NoNetwork: '8A025A33'
};

/**
 * The reader is now connected and ready.
 * @event PaymentDevice#connected
 */

/**
 * The reader is now selected and active to be used.
 * @event PaymentDevice#selected
 */

/**
 * The connection attempt with the reader failed
 * @event PaymentDevice#connectionError
 * @param {error} error Any error that caused the connection failure
 */

/**
 * The reader is now disconnected.
 * @event PaymentDevice#disconnected
 * @param {error} error Any error that caused the disconnect
 */

/**
 * A software update is required for the reader.
 * @event PaymentDevice#updateRequired
 * @param {DeviceUpdate} update The update that should or must be applied
 */

/**
 * The battery status has been updated
 * @event PaymentDevice#batteryStatusUpdate
 * @param {BatteryInfo} batteryInfo the latest battery info
 */

/**
 * The battery status has been updated
 * @callback PaymentDevice~batteryInfo
 * @param {error} error Any error in retrieving battery info
 * @param {BatteryInfo} batteryInfo the latest battery info
 */

/**
 * A card has been removed (generally from an EMV reader, where the card
 * stays in the reader for some time)
 * @event PaymentDevice#cardRemoved
 */

/**
 * Depending on your region and the buyer payment type, this can mean a magnetic card
 * was swiped, an EMV card was
 * inserted, or an NFC card/device was tapped.
 * @event PaymentDevice#cardPresented
 * @param {Card} card Information about the card.
 */

/**
 * @callback PaymentDevice~connect
 * @param {error} error Error (if any) that caused the action to fail
 */

/**
 * @callback PaymentDevice~disconnect
 * @param {error} error Error (if any) that caused the action to fail
 */

/**
 * @callback PaymentDevice~deviceLogs
 * @param {error} error Error (if any) that caused the action to fail
 */

// Used to fire the "global" deviceAdded event
PaymentDevice.Events = new _events.EventEmitter();

PaymentDevice.Message = {
  Connecting: 'Connecting',
  ConnectionFailed: 'ConnectionFailed',
  RefundFailed: 'Refund.Failed',
  PaymentFailed: 'Paid.Failed',
  NotConnected: 'NotConnected',
  OrderInProgress: 'Order.InProgress',
  WaitForPayment: 'Order.Ready',
  ProcessingContact: 'Processing.Contact',
  PaidRemoveCard: 'Paid.RemoveCard',
  QuickChip: 'Processing.QuickChip',
  Paid: 'Paid.Successful',
  RefundRemoveCard: 'Refund.RemoveCard',
  Refund: 'Refund.Successful',
  RefundCardMismatch: 'Refund.CardMismatch',
  RefundCardMismatchRemoveCard: 'Refund.CardMismatchRemoveCard',
  Processing: 'Processing.Tap',
  ProcessingContactWithPin: 'Processing.ContactPinOk',
  ProcessingWithPin: 'Processing.PinOk',
  Complete: 'Complete',
  SignContact: 'Sign.Contact',
  SignTap: 'Sign.Tap',
  SoftwareUpdateRequired: 'SwUpdate.Required',
  SoftwareUpdateComplete: 'SwUpdate.Complete',
  SoftwareUpdateAvailable: 'SwUpdate.Available',
  SoftwareUpdateProgress: 'SwUpdate.Progress',
  SoftwareUpdateFailed: 'SwUpdate.Failed',
  SoftwareUpdateDownloading: 'SwUpdate.Downloading',
  Ready: 'Ready',
  ReadyWithId: 'ReadyWithId',
  NotReady: 'NotReady',
  NfcTimeOut: 'NfcTimeout',
  GeneralNfcFallback: 'GeneralNfcFallback',
  TransactionCancelled: 'TransactionCancelled',
  TransactionCancelledRemoveCard: 'TransactionCancelledRemoveCard',
  TransactionCancelling: 'TransactionCancelling',
  UnableToReadNfcCard: 'Declined.UnableToReadNfcCard',
  InvalidChipCard: 'Declined.InvalidChipCard',
  BlockedCardInserted: 'Declined.BlockedCardInserted',
  NfcDecline: 'Declined.NfcDecline',
  IncorrectPin: 'Declined.IncorrectPin',
  ContactIssuer: 'ContactIssuer',
  ContactIssuerRemoveCard: 'ContactIssuerRemoveCard',
  RechargeNow: 'RechargeNow',
  ReadyForInsertAndSwipePayment: 'ReadyForInsertAndSwipePayment',
  ReadyForInsertPayment: 'ReadyForInsertPayment',
  ReadyForSwipePayment: 'ReadyForSwipePayment',
  SignatureForInsert: 'Signature.Insert',
  SignatureForInsertQCCR: 'Signature.QuickChip',
  SignatureForTap: 'Signature.Tap',
  SignatureForNonEmv: 'Signature.NonEmv',
  InvoiceTotal: 'InvoiceTotal',
  AmountTooLow: 'AmountTooLow',
  AmountTooLowRemoveCard: 'AmountTooLowRemoveCard',
  AmountTooHigh: 'AmountTooHigh',
  AmountTooHighRemoveCard: 'AmountTooHighRemoveCard',
  CompletingPayment: 'CompletingPayment',
  RequestTip: 'RequestTip',
  ConfirmTip: 'ConfirmTip'
};

PaymentDevice.ConnectionTimeOut = msDefaultMaxConnectionDuration;
},{"./CardReader":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/CardReader.js","./FormFactor":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/FormFactor.js","./Messages/DeviceStatus":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/Messages/DeviceStatus.js","./ReaderModel":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/ReaderModel.js","./deviceState":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/deviceState.js","./paymentDeviceError":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/paymentDeviceError.js","./readerInformation":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/readerInformation.js","events":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/events/events.js","manticore":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore/browser.js","manticore-log":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-log/index.js","manticore-util":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-util/build/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/ReaderModel.js":[function(require,module,exports){
"use strict";

exports.__esModule = true;
/**
 * Card reader model
 * @enum {int}
 */
var ReaderModel = {
  /**
   * Card reader model is not known
   */
  Unknown: 0,
  /**
   * ROAM Audio reader
   */
  Swiper: 1,
  /**
   * Miura M003
   */
  M003: 2,
  /**
   * Miura M010
   */
  M010: 3,
  /**
   * Ingenico MOBY 3000
   */
  Moby3000: 4,
  /**
   * Ingenico RP 450
   */
  RP450: 5
};

exports.default = ReaderModel;
},{}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/SecureEntryOptions.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

var _ManuallyEnteredCard = require('./ManuallyEnteredCard');

var _ManuallyEnteredCard2 = _interopRequireDefault(_ManuallyEnteredCard);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } /* eslint-disable no-unused-vars */

/**
 * SecureEntryOptions specify which values you would like the SDK
 * to gather from the terminal and which you would like to just gather
 * on your own
 * @class
 * @property {bool} cvv true to gather the CVV value on terminal, false to skip that
 * @property {bool} expiration true to gather expiration month and year on terminal
 */
var SecureEntryOptions = function SecureEntryOptions() {
  _classCallCheck(this, SecureEntryOptions);
};

/**
 * Called after a request to secure account number entry
 * @callback SecureEntryOptions~secureEntry
 * @param {error} error The error encountered - namely cancellation or lack of terminal support
 * @param {ManuallyEnteredCard} card The card object representing the information entered.
 *  You may still need to gather more information such as CVV and/or expiration date
 */

/* eslint-enable no-unused-vars */


exports.default = SecureEntryOptions;
},{"./ManuallyEnteredCard":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/ManuallyEnteredCard.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/TransactionType.js":[function(require,module,exports){
"use strict";

exports.__esModule = true;

/**
 * A transaction context is created for a certain operation - sale
 * (meaning auth+capture), auth or refund.
 * @enum {int}
 */
var TransactionType = {
  /**
   * An attempt to complete a transfer of funds between merchant and customer
   */
  Sale: 0,
  /**
   * An attempt to get authorization of funds for later capture
   */
  Auth: 1,
  /**
   * An attempt to return the entire amount of the remaining paid amount of an invoice
   */
  Refund: 2,
  /**
   * An attempt to return a partial amount of the remaining paid amount of an invoice
   */
  PartialRefund: 3
};

exports.default = TransactionType;
},{}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/appMessage.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;
/**
 * Enum for messages that should be displayed on App side
 * @enum {string}
 */
var appMessage = {
  /**
   * SW Update is initializing
   */
  SwUpdateInitializing: {
    title: 'SwUpgrade.Updating.Title',
    message: 'SwUpgrade.Initializing'
  },

  /**
   * Reconnecting during SW Update
   */
  SwUpdateReconnecting: {
    title: 'SwUpgrade.Updating.Title',
    message: 'SwUpgrade.Reconnecting'
  },

  /**
   * Restart instruction during SW Update
   */
  SwUpdateRestartInstruction: {
    title: 'SwUpgrade.RestartInstruction.Title',
    message: 'SwUpgrade.RestartInstruction.Msg'
  },

  /**
   * Connected to card reader
   */
  SwUpdateConnected: {
    title: 'SwUpgrade.Updating.Title',
    message: 'SwUpgrade.Connected'
  },

  SwUpdate: {
    buttons: {
      notNow: 'SwUpgrade.Buttons.NotNow',
      ok: 'SwUpgrade.Buttons.Ok',
      updateNow: 'SwUpgrade.Buttons.UpdateNow',
      retry: 'SwUpgrade.Buttons.Retry'
    }
  },

  SwUpdateFailed: {
    title: 'SwUpgrade.Failed.Title',
    message: 'SwUpgrade.Failed.Msg',
    messageBatteryLow: 'SwUpgrade.Failed.BatteryLow'
  },

  SwUpdateSuccessful: {
    title: 'SwUpgrade.Success.Title',
    message: 'SwUpgrade.Success.Msg'
  },

  /**
   * SW Update is required
   */
  SwUpdateRequired: {
    title: 'SwUpgrade.Required.Title',
    message: 'SwUpgrade.Required.Msg'
  },

  /**
   * SW Update is optional
   */
  SwUpdateOptional: {
    title: 'SwUpgrade.Optional.Title',
    message: 'SwUpgrade.Optional.Msg'
  },

  /**
   * SW Update is in progress
   */
  SwUpdateInProgress: {
    title: 'SwUpgrade.Updating.Title',
    message: 'SwUpgrade.Updating.Msg'
  },

  /**
   * SW Update download in progress
   */
  SwUpdateDownloading: {
    title: 'SwUpgrade.Updating.Title',
    message: 'SwUpgrade.Downloading'
  },

  SwUpdateInProgressWithDetails: {
    title: 'SwUpgrade.Updating.Title',
    message: 'SwUpgrade.UpdatingWithDetails'
  },

  /**
   * SW Update is validating security keys
   */
  SwUpdateValidatingSecurityKeys: {
    title: 'SwUpgrade.Updating.Title',
    message: 'SwUpgrade.ValidatingSecurityKeys'
  },

  /**
   * Security keys were installed
   */
  SwUpdateSecurityKeysInstalled: {
    title: 'SwUpgrade.Updating.Title',
    message: 'SwUpgrade.SecurityKeysInstalled'
  },

  /**
   * Security keys were installed
   */
  SwUpdateRestarting: {
    title: 'SwUpgrade.Updating.Title',
    message: 'SwUpgrade.Restarting'
  },

  /**
   * Card insert was not successful due to incorrect insert or broken chip. Prompt user to retry card insert or swipe
   */
  UnsuccessfulInsert: {
    title: 'Tx.Alert.UnsuccessfulInsert.Title',
    message: 'Tx.Alert.UnsuccessfulInsert.Msg'
  },

  /**
   * Card reader can only take swipe payments
   */
  ReadyForSwipeOnly: {
    title: 'Tx.Alert.ReadyForSwipeOnly.Title',
    message: 'Tx.Alert.ReadyForSwipeOnly.Msg',
    cancel: 'Cancel',
    imageIcon: 'img_emv_swipe'
  },

  /**
   * Connecting to reader
   */
  ConnectingToDevice: {
    title: 'Device.Connecting.Title'
  },
  RetryConnectingToDevice: {
    title: 'Device.RetryConnecting.Title',
    message: 'Device.RetryConnecting.Message',
    buttons: ['Device.RetryConnecting.Buttons.Retry'],
    cancel: 'Device.RetryConnecting.Buttons.NotNow'
  },
  ConnectingToDeviceFailed: {
    title: 'Device.ConnectingFailed.Title',
    cancel: 'Device.ConnectingFailed.Buttons.Cancel'
  },
  LowBattery: {
    title: 'Tx.Alert.LowBattery.Title',
    message: 'Tx.Alert.LowBattery.Msg',
    cancel: 'OK'
  }
};

exports.default = appMessage;
},{}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/batteryStatus.js":[function(require,module,exports){
"use strict";

exports.__esModule = true;
/**
 * Battery status
 * @enum {int}
 */
var batteryStatus = {
  /**
   * Battery status not known
   */
  unknown: 0,
  /**
   * Battery is draining an not connected to power
   */
  draining: 1,
  /**
   * Battery is fully drained
   */
  drained: 2,
  /**
   * Battery is charging
   */
  charging: 3,
  /**
   * Battery is fully charged
   */
  charged: 4
};

exports.default = batteryStatus;
},{}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/cardError.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;
exports.cardErrorDomain = exports.cardError = undefined;

var _paymentDeviceError = require('./paymentDeviceError');

var domain = 'Card';

var cardError = exports.cardError = {
  invalidExpiryDate: Object.freeze((0, _paymentDeviceError.payPalError)(domain, 0, 'Expiry date should be in MMYYYY format'))
};

exports.cardErrorDomain = domain;
},{"./paymentDeviceError":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/paymentDeviceError.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/deviceCapabilityType.js":[function(require,module,exports){
"use strict";

exports.__esModule = true;
/**
 * The device capability types
 * @enum {int}
 */
var deviceCapabilityType = {
  /**
   * no capability
   */
  none: 0,
  /**
   * Device has the display
   */
  display: 1,
  /**
   * Device has the keyboard
   */
  keyboard: 2,
  /**
   * Device has the secure entry
   */
  secureEntry: 3,
  /**
   * Device supports contactless payments
   */
  contactless: 4
};

exports.default = deviceCapabilityType;
},{}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/deviceManufacturer.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;
var deviceManufacturer = {
  miura: 'MIURA',
  ingenico: 'INGENICO',
  bbpos: 'BBPOS',
  roam: 'ROAM'
};

exports.default = deviceManufacturer;
},{}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/deviceState.js":[function(require,module,exports){
"use strict";

exports.__esModule = true;
/**
 * Indicates the current state of the device
 */
var deviceState = {
  unknown: 0,
  softwareUpdate: 1,
  hardResetting: 2
};

exports.default = deviceState;
},{}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/index.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;

var _CardReader = require('./CardReader');

Object.defineProperty(exports, 'CardReader', {
  enumerable: true,
  get: function get() {
    return _interopRequireDefault(_CardReader).default;
  }
});

var _NumericEntryOptions = require('./NumericEntryOptions');

Object.defineProperty(exports, 'NumericEntryOptions', {
  enumerable: true,
  get: function get() {
    return _interopRequireDefault(_NumericEntryOptions).default;
  }
});

var _NumericEntryType = require('./NumericEntryType');

Object.defineProperty(exports, 'NumericEntryType', {
  enumerable: true,
  get: function get() {
    return _interopRequireDefault(_NumericEntryType).default;
  }
});

var _SecureEntryOptions = require('./SecureEntryOptions');

Object.defineProperty(exports, 'SecureEntryOptions', {
  enumerable: true,
  get: function get() {
    return _interopRequireDefault(_SecureEntryOptions).default;
  }
});

var _PaymentDevice = require('./PaymentDevice');

Object.defineProperty(exports, 'PaymentDevice', {
  enumerable: true,
  get: function get() {
    return _interopRequireDefault(_PaymentDevice).default;
  }
});

var _BatteryInfo = require('./BatteryInfo');

Object.defineProperty(exports, 'BatteryInfo', {
  enumerable: true,
  get: function get() {
    return _interopRequireDefault(_BatteryInfo).default;
  }
});

var _batteryStatus = require('./batteryStatus');

Object.defineProperty(exports, 'batteryStatus', {
  enumerable: true,
  get: function get() {
    return _interopRequireDefault(_batteryStatus).default;
  }
});

var _MagneticCard = require('./MagneticCard');

Object.defineProperty(exports, 'MagneticCard', {
  enumerable: true,
  get: function get() {
    return _interopRequireDefault(_MagneticCard).default;
  }
});

var _ManuallyEnteredCard = require('./ManuallyEnteredCard');

Object.defineProperty(exports, 'ManuallyEnteredCard', {
  enumerable: true,
  get: function get() {
    return _interopRequireDefault(_ManuallyEnteredCard).default;
  }
});

var _CardDataUtil = require('./CardDataUtil');

Object.defineProperty(exports, 'CardDataUtil', {
  enumerable: true,
  get: function get() {
    return _interopRequireDefault(_CardDataUtil).default;
  }
});

var _MagneticReaderDevice = require('./MagneticReaderDevice');

Object.defineProperty(exports, 'MagneticReaderDevice', {
  enumerable: true,
  get: function get() {
    return _interopRequireDefault(_MagneticReaderDevice).default;
  }
});

var _paymentDeviceError = require('./paymentDeviceError');

Object.defineProperty(exports, 'deviceError', {
  enumerable: true,
  get: function get() {
    return _paymentDeviceError.deviceError;
  }
});
Object.defineProperty(exports, 'deviceErrorDomain', {
  enumerable: true,
  get: function get() {
    return _paymentDeviceError.deviceErrorDomain;
  }
});

var _cardError = require('./cardError');

Object.defineProperty(exports, 'cardError', {
  enumerable: true,
  get: function get() {
    return _cardError.cardError;
  }
});
Object.defineProperty(exports, 'cardErrorDomain', {
  enumerable: true,
  get: function get() {
    return _cardError.cardErrorDomain;
  }
});

var _CardStatus = require('./CardStatus');

Object.defineProperty(exports, 'CardStatus', {
  enumerable: true,
  get: function get() {
    return _interopRequireDefault(_CardStatus).default;
  }
});

var _CardIssuer = require('./CardIssuer');

Object.defineProperty(exports, 'CardIssuer', {
  enumerable: true,
  get: function get() {
    return _interopRequireDefault(_CardIssuer).default;
  }
});

var _FormFactor = require('./FormFactor');

Object.defineProperty(exports, 'FormFactor', {
  enumerable: true,
  get: function get() {
    return _interopRequireDefault(_FormFactor).default;
  }
});

var _TransactionType = require('./TransactionType');

Object.defineProperty(exports, 'TransactionType', {
  enumerable: true,
  get: function get() {
    return _interopRequireDefault(_TransactionType).default;
  }
});

var _deviceCapabilityType = require('./deviceCapabilityType');

Object.defineProperty(exports, 'deviceCapabilityType', {
  enumerable: true,
  get: function get() {
    return _interopRequireDefault(_deviceCapabilityType).default;
  }
});

var _DeviceUpdate = require('./DeviceUpdate');

Object.defineProperty(exports, 'DeviceUpdate', {
  enumerable: true,
  get: function get() {
    return _interopRequireDefault(_DeviceUpdate).default;
  }
});

var _appMessage = require('./appMessage');

Object.defineProperty(exports, 'appMessage', {
  enumerable: true,
  get: function get() {
    return _interopRequireDefault(_appMessage).default;
  }
});

var _CardPresentEvent = require('./Messages/CardPresentEvent');

Object.defineProperty(exports, 'CardPresentEvent', {
  enumerable: true,
  get: function get() {
    return _interopRequireDefault(_CardPresentEvent).default;
  }
});

var _Card = require('./Messages/Card');

Object.defineProperty(exports, 'Card', {
  enumerable: true,
  get: function get() {
    return _interopRequireDefault(_Card).default;
  }
});

var _AvailableApplications = require('./Messages/AvailableApplications');

Object.defineProperty(exports, 'AvailableApplications', {
  enumerable: true,
  get: function get() {
    return _interopRequireDefault(_AvailableApplications).default;
  }
});

var _PinEvent = require('./Messages/PinEvent');

Object.defineProperty(exports, 'PinEvent', {
  enumerable: true,
  get: function get() {
    return _interopRequireDefault(_PinEvent).default;
  }
});

var _CardReaderResponse = require('./Messages/CardReaderResponse');

Object.defineProperty(exports, 'CardReaderResponse', {
  enumerable: true,
  get: function get() {
    return _interopRequireDefault(_CardReaderResponse).default;
  }
});

var _readerInformation = require('./readerInformation');

Object.defineProperty(exports, 'readerType', {
  enumerable: true,
  get: function get() {
    return _readerInformation.readerType;
  }
});
Object.defineProperty(exports, 'readerConnectionType', {
  enumerable: true,
  get: function get() {
    return _readerInformation.readerConnectionType;
  }
});

var _CardInsertedHandler = require('./CardInsertedHandler');

Object.defineProperty(exports, 'CardInsertedHandler', {
  enumerable: true,
  get: function get() {
    return _interopRequireDefault(_CardInsertedHandler).default;
  }
});

var _DeviceStatus = require('./Messages/DeviceStatus');

Object.defineProperty(exports, 'DeviceStatus', {
  enumerable: true,
  get: function get() {
    return _interopRequireDefault(_DeviceStatus).default;
  }
});

var _deviceManufacturer = require('./deviceManufacturer');

Object.defineProperty(exports, 'deviceManufacturer', {
  enumerable: true,
  get: function get() {
    return _interopRequireDefault(_deviceManufacturer).default;
  }
});

var _ReaderModel = require('./ReaderModel');

Object.defineProperty(exports, 'ReaderModel', {
  enumerable: true,
  get: function get() {
    return _interopRequireDefault(_ReaderModel).default;
  }
});

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
},{"./BatteryInfo":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/BatteryInfo.js","./CardDataUtil":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/CardDataUtil.js","./CardInsertedHandler":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/CardInsertedHandler.js","./CardIssuer":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/CardIssuer.js","./CardReader":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/CardReader.js","./CardStatus":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/CardStatus.js","./DeviceUpdate":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/DeviceUpdate.js","./FormFactor":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/FormFactor.js","./MagneticCard":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/MagneticCard.js","./MagneticReaderDevice":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/MagneticReaderDevice.js","./ManuallyEnteredCard":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/ManuallyEnteredCard.js","./Messages/AvailableApplications":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/Messages/AvailableApplications.js","./Messages/Card":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/Messages/Card.js","./Messages/CardPresentEvent":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/Messages/CardPresentEvent.js","./Messages/CardReaderResponse":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/Messages/CardReaderResponse.js","./Messages/DeviceStatus":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/Messages/DeviceStatus.js","./Messages/PinEvent":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/Messages/PinEvent.js","./NumericEntryOptions":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/NumericEntryOptions.js","./NumericEntryType":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/NumericEntryType.js","./PaymentDevice":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/PaymentDevice.js","./ReaderModel":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/ReaderModel.js","./SecureEntryOptions":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/SecureEntryOptions.js","./TransactionType":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/TransactionType.js","./appMessage":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/appMessage.js","./batteryStatus":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/batteryStatus.js","./cardError":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/cardError.js","./deviceCapabilityType":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/deviceCapabilityType.js","./deviceManufacturer":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/deviceManufacturer.js","./paymentDeviceError":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/paymentDeviceError.js","./readerInformation":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/readerInformation.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/paymentDeviceError.js":[function(require,module,exports){
'use strict';

exports.__esModule = true;
exports.deviceErrorDomain = exports.deviceError = undefined;
exports.payPalError = payPalError;

var _manticorePaypalerror = require('manticore-paypalerror');

var domain = 'PaymentDevice';

function payPalError(errDomain, code, message) {
  var errorInfo = new _manticorePaypalerror.PayPalErrorInfo();
  errorInfo.code = code.toString();
  errorInfo.domain = errDomain;
  errorInfo.message = message;
  return _manticorePaypalerror.PayPalError.makeError(null, errorInfo);
}

/**
 * All payment device errors belong here
 */
var deviceError = exports.deviceError = {
  generic: payPalError(domain, 0, 'Generic error'),
  nfcTimeout: payPalError(domain, 1, 'Contactless reader timed out waiting for payment presentation'),
  nfcNotAllowed: payPalError(domain, 2, 'Contactless payment not allowed on this card'),
  tryDifferentCard: payPalError(domain, 3, 'Try different card'),
  mustInsertCard: payPalError(domain, 4, 'Must insert presented card'),
  mustSwipeCard: payPalError(domain, 5, 'Must swipe presented card'),
  hardwareError: payPalError(domain, 6, 'Hardware error'),
  cardBlocked: payPalError(domain, 7, 'Presented card is blocked'),
  contactIssuer: payPalError(domain, 8, 'Payment was declined. Contact issuer'),
  invalidChip: payPalError(domain, 9, 'Chip is invalid'),
  cannotSwipeChipCard: payPalError(domain, 10, 'Cannot swipe a chip card'),
  smartCardNotInSlot: payPalError(domain, 11, 'Card not in slot'),
  paymentCancelled: payPalError(domain, 12, 'Payment was cancelled'),
  contactlessPaymentAbortedByCardInsert: payPalError(domain, 13, 'Contactless payment was aborted by card insert'),
  contactlessPaymentAbortedByCardSwipe: payPalError(domain, 14, 'Contactless payment was aborted by card swipe'),
  badEmvData: payPalError(domain, 15, 'Bad EMV data'),
  deviceNotConnected: payPalError(domain, 16, 'Device not connected'),
  cannotAcceptMessage: payPalError(domain, 17, 'Device cannot accept messages in its current state'),
  actionCancelled: payPalError(domain, 18, 'Action was cancelled'),
  secureEntryFailed: payPalError(domain, 19, 'Secure entry failed'),
  numericEntryFailed: payPalError(domain, 20, 'Numeric entry failed'),
  dataValidationError: payPalError(domain, 21, 'Data validation error'),
  unexpectedResponse: payPalError(domain, 22, 'Received unexpected response'),
  failureResponse: payPalError(domain, 23, 'Received failure response'),
  dataRetrievalFailed: payPalError(domain, 24, 'Failed to retrieve expected data'),
  lowOnBattery: payPalError(domain, 25, 'Battery Low'),
  fileNotFound: payPalError(domain, 26, 'Unable to retrieve the file from the device'),
  fileImportFailed: payPalError(domain, 27, 'File import failed'),
  initializationFailed: payPalError(domain, 28, 'Device initialization failed'),
  tipEntryFailed: payPalError(domain, 29, 'Tip entry failed'),
  swUpdateFailed: payPalError(domain, 30, 'Software Update Failed'),
  notFunctional: payPalError(domain, 31, 'Device not functional at this moment'),
  swUpdatePending: payPalError(domain, 32, 'Software update is pending'),
  cancelReadCardData: payPalError(domain, 33, 'Cancel reading card data'),
  cardReaderNotAvailable: payPalError(domain, 34, 'Card reader not available for connection'),
  corruptFirmware: payPalError(domain, 35, 'Downloaded firmware file was corrupt'),
  unexpectedRequest: payPalError(domain, 36, 'Received unexpected request'),
  actionCannotBeCompleted: payPalError(domain, 37, 'Could not complete requested action'),
  lastActiveReaderNotFound: payPalError(domain, 38, 'Received unexpected request')
};

exports.deviceErrorDomain = domain;
},{"manticore-paypalerror":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/manticore-paypalerror/build/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/retail-payment-device/build/readerInformation.js":[function(require,module,exports){
"use strict";

exports.__esModule = true;
/**
 * Indicates the type synonymous to the payment acceptance method.
 * @enum {int}
 */
var readerType = exports.readerType = {
  /**
   * When the SDK failed to determine the type.
   */
  Unknown: 0,
  /**
   * When the SDK detects a reader capable of supporting only the Magstripe cards.
   */
  Magstripe: 1,
  /**
   * When the SDK detects a reader capable of supporting Magstripe, Chip and Contactless (optional) cards.
   */
  Emv: 2
};

/**
 * Indicates the channel through which the reader is connected.
 * @enum {int}
 */
var readerConnectionType = exports.readerConnectionType = {
  /**
   * When the SDK failed to determine the connection channel.
   */
  Unknown: 0,
  /**
   * When the SDK detects a reader connected to the audio jack.
   */
  AudioJack: 1,
  /**
   * When the SDK detects a reader connected via bluetooth.
   */
  Bluetooth: 2,
  /**
   * When the SDK detects a reader connected via dock port.
   */
  DockPort: 3
};
},{}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/tlvlib/build/index.js":[function(require,module,exports){
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});
var Tlv = exports.Tlv = require('./lib/Tlv').default;
var TlvList = exports.TlvList = require('./lib/TlvList').default;
var Tags = exports.Tags = require('./lib/Tags').default;
var ValueFormat = exports.ValueFormat = require('./lib/ValueFormat').default;
var DefinedTag = exports.DefinedTag = require('./lib/DefinedTag').default;
var ApduCommand = exports.ApduCommand = require('./lib/apdu/Command').default;
var ApduResponse = exports.ApduResponse = require('./lib/apdu/Response').default;
var Ber = exports.Ber = require('./lib/ber').default;
},{"./lib/DefinedTag":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/tlvlib/build/lib/DefinedTag.js","./lib/Tags":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/tlvlib/build/lib/Tags.js","./lib/Tlv":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/tlvlib/build/lib/Tlv.js","./lib/TlvList":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/tlvlib/build/lib/TlvList.js","./lib/ValueFormat":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/tlvlib/build/lib/ValueFormat.js","./lib/apdu/Command":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/tlvlib/build/lib/apdu/Command.js","./lib/apdu/Response":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/tlvlib/build/lib/apdu/Response.js","./lib/ber":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/tlvlib/build/lib/ber.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/tlvlib/build/lib/DefinedTag.js":[function(require,module,exports){
arguments[4]["/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/tlvlib/build/lib/DefinedTag.js"][0].apply(exports,arguments)
},{"./ValueFormat":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/tlvlib/build/lib/ValueFormat.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/tlvlib/build/lib/Tags.js":[function(require,module,exports){
arguments[4]["/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/tlvlib/build/lib/Tags.js"][0].apply(exports,arguments)
},{"./DefinedTag":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/tlvlib/build/lib/DefinedTag.js","./ValueFormat":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/tlvlib/build/lib/ValueFormat.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/tlvlib/build/lib/Tlv.js":[function(require,module,exports){
arguments[4]["/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/tlvlib/build/lib/Tlv.js"][0].apply(exports,arguments)
},{"./DefinedTag":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/tlvlib/build/lib/DefinedTag.js","./ber":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/tlvlib/build/lib/ber.js","buffer":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/buffer/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/tlvlib/build/lib/TlvList.js":[function(require,module,exports){
(function (Buffer){
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

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; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

var _Tlv = require('./Tlv');

var _Tlv2 = _interopRequireDefault(_Tlv);

var _DefinedTag = require('./DefinedTag');

var _DefinedTag2 = _interopRequireDefault(_DefinedTag);

var _ber = require('./ber');

var _ber2 = _interopRequireDefault(_ber);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function lengthCheck(index, start, length, message) {
  if (index > start + length) {
    throw new Error(message);
  }
}

var TlvList = function () {
  function TlvList(bufferOrNull, start, length) {
    _classCallCheck(this, TlvList);

    this.values = [];
    if (bufferOrNull) {
      this._parse(bufferOrNull, start, length);
    }
  }

  _createClass(TlvList, [{
    key: '_parse',
    value: function _parse(buffer) {
      var start = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
      var length = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : buffer.length - start;

      var index = start;
      while (index < start + length) {
        var tagData = _ber2.default.readTag(buffer, index);
        var tagStart = index;
        index += tagData.length;
        lengthCheck(index, start, length, 'Invalid TLV - tag ends buffer.');
        var lenData = _ber2.default.readLength(buffer, index);
        index += lenData.lengthOfEncoding;
        lengthCheck(index, start, length, 'Invalid TLV - tag value length ends buffer.');
        var value = void 0;
        if (lenData.lengthValue) {
          lengthCheck(index + lenData.lengthValue, start, length, 'Invalid TLV - value overruns buffer.');
          value = buffer.slice(index, index + lenData.lengthValue);
          index += lenData.lengthValue;
        }
        var tagEnd = index;
        if (!value) {
          continue;
        }
        var tags = _DefinedTag2.default.findTags(tagData.number);
        var _iteratorNormalCompletion = true;
        var _didIteratorError = false;
        var _iteratorError = undefined;

        try {
          for (var _iterator = tags[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
            var t = _step.value;

            var tlv = new _Tlv2.default(t, value);
            tlv.buffStart = tagStart;
            tlv.buffEnd = tagEnd;
            this.values.push(tlv);
          }
        } catch (err) {
          _didIteratorError = true;
          _iteratorError = err;
        } finally {
          try {
            if (!_iteratorNormalCompletion && _iterator.return) {
              _iterator.return();
            }
          } finally {
            if (_didIteratorError) {
              throw _iteratorError;
            }
          }
        }
      }
    }
  }, {
    key: 'add',
    value: function add(tlvOrTag, valueOrNull) {
      if (tlvOrTag instanceof _DefinedTag2.default) {
        this.values.push(new _Tlv2.default(tlvOrTag, valueOrNull));
      } else if (tlvOrTag instanceof _Tlv2.default) {
        this.values.push(tlvOrTag);
      } else if (!Buffer.isBuffer(valueOrNull)) {
        throw new Error('Add must be called with a tag and value, or a tag number and buffer.');
      } else {
        this.values.push(new _Tlv2.default(_DefinedTag2.default.findTag(tlvOrTag), valueOrNull));
      }
    }

    /**
     * Find a tag in the list of values.
     * @param tag
     * @param skip For multiple tags, pass a non-zero skip value
     * @returns {*}
     */

  }, {
    key: 'find',
    value: function find(tag, skip) {
      var toSkip = skip || 0;
      var findNumber = tag.number || tag;
      var _iteratorNormalCompletion2 = true;
      var _didIteratorError2 = false;
      var _iteratorError2 = undefined;

      try {
        for (var _iterator2 = this.values[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
          var tlv = _step2.value;

          if (tlv.tagNumber === findNumber) {
            if (toSkip > 0) {
              toSkip--;
            } else {
              return tlv;
            }
          }
        }
      } catch (err) {
        _didIteratorError2 = true;
        _iteratorError2 = err;
      } finally {
        try {
          if (!_iteratorNormalCompletion2 && _iterator2.return) {
            _iterator2.return();
          }
        } finally {
          if (_didIteratorError2) {
            throw _iteratorError2;
          }
        }
      }

      return null;
    }
  }, {
    key: 'toBytes',
    value: function toBytes() {
      // TODO this isn't right anymore...
      var parts = [];
      var _iteratorNormalCompletion3 = true;
      var _didIteratorError3 = false;
      var _iteratorError3 = undefined;

      try {
        for (var _iterator3 = this.values[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {
          var tlv = _step3.value;

          parts.push(tlv.toBytes());
        }
      } catch (err) {
        _didIteratorError3 = true;
        _iteratorError3 = err;
      } finally {
        try {
          if (!_iteratorNormalCompletion3 && _iterator3.return) {
            _iterator3.return();
          }
        } finally {
          if (_didIteratorError3) {
            throw _iteratorError3;
          }
        }
      }

      return Buffer.concat(parts);
    }
  }, {
    key: 'toString',
    value: function toString(shouldParse) {
      var parts = ['TLV:'];
      var _iteratorNormalCompletion4 = true;
      var _didIteratorError4 = false;
      var _iteratorError4 = undefined;

      try {
        for (var _iterator4 = this.values[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) {
          var tlv = _step4.value;

          if (Buffer.isBuffer(tlv)) {
            parts.push(tlv.toString('hex'));
          } else {
            parts.push(tlv.toString(shouldParse));
          }
        }
      } catch (err) {
        _didIteratorError4 = true;
        _iteratorError4 = err;
      } finally {
        try {
          if (!_iteratorNormalCompletion4 && _iterator4.return) {
            _iterator4.return();
          }
        } finally {
          if (_didIteratorError4) {
            throw _iteratorError4;
          }
        }
      }

      return parts.join('\n');
    }
  }, {
    key: 'length',
    get: function get() {
      return this.values.length;
    }
  }]);

  return TlvList;
}();

exports.default = TlvList;
}).call(this,require("buffer").Buffer)
},{"./DefinedTag":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/tlvlib/build/lib/DefinedTag.js","./Tlv":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/tlvlib/build/lib/Tlv.js","./ber":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/tlvlib/build/lib/ber.js","buffer":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/buffer/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/tlvlib/build/lib/ValueFormat.js":[function(require,module,exports){
arguments[4]["/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/tlvlib/build/lib/ValueFormat.js"][0].apply(exports,arguments)
},{"./TlvList":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/tlvlib/build/lib/TlvList.js","buffer":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/buffer/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/tlvlib/build/lib/apdu/Command.js":[function(require,module,exports){
(function (Buffer){
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

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; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

var ApduCommand = function () {
  /**
   * Create a new ApduCommand either from a data buffer (i.e. parse it)
   * or from command/instruction/p1/p2 with a blank buffer.
   * @param bufferOrCommandClass
   * @param instruction
   * @param p1
   * @param p2
   * @param data
   * @param le
   * @param longLength Uses 2 bytes to indicate length while converting to byte array
   */
  function ApduCommand(bufferOrCommandClass, instruction, p1, p2, data, le, longLength) {
    _classCallCheck(this, ApduCommand);

    var preambleByteSize = this.longLength ? 5 : 4;
    this.preamble = new Buffer(preambleByteSize);
    this.longLength = longLength;
    if (data) {
      if (Buffer.isBuffer(data)) {
        this.data = [data];
      } else {
        // Better be an array...
        this.data = data;
      }
    } else {
      this.data = null;
    }
    // This is the common case. Use expectNoBytes property to set it to null and not send the byte.
    this.le = 0;
    if (Buffer.isBuffer(bufferOrCommandClass)) {
      // Parse an Apdu Command
    } else {
      // Create a new Apdu Command
      this.commandClass = bufferOrCommandClass;
      this.instruction = instruction;
      this.p1 = p1 || 0;
      this.p2 = p2 || 0;
      if (le !== undefined) {
        this.le = le;
      }
    }
  }

  _createClass(ApduCommand, [{
    key: 'expectNoBytes',
    value: function expectNoBytes() {
      this.le = null;
    }
  }, {
    key: 'appendHex',
    value: function appendHex(hexString) {
      this.data = this.data || [];
      this.data.push(new Buffer(hexString, 'hex'));
    }
  }, {
    key: 'appendBytes',
    value: function appendBytes(buffer) {
      this.data = this.data || [];
      this.data.push(buffer);
    }
  }, {
    key: 'appendString',
    value: function appendString(utf8String) {
      this.data = this.data || [];
      this.data.push(new Buffer(utf8String, 'utf8'));
    }
  }, {
    key: 'toBytes',
    value: function toBytes() {
      var parts = [this.preamble];

      // https://en.wikipedia.org/wiki/Smart_card_application_protocol_data_unit
      var len = 0;
      if (this.data) {
        parts.push(null);
        this.data.forEach(function (p) {
          len += p.length;
          parts.push(p);
        });
        if (len > 65535) {
          throw new Error('ApduCommand buffer is too long');
        } else if (len > 255) {
          parts[1] = new Buffer([len >> 8, len & 0xFF]);
        } else {
          parts[1] = this.longLength ? new Buffer([0, len]) : new Buffer([len]);
        }
      }

      if (this.le !== null) {
        if (this.le > 65535) {
          throw new Error('Le value must be between 0 and 65535');
        } else if (this.le <= 256) {
          parts.push(new Buffer([this.le & 0xFF]));
        } else {
          if (parts.length === 1) {
            // In this case (case 2E from http://www.cardwerk.com/smartcards/smartcard_standard_ISO7816-4_5_basic_organizations.aspx#table4), we need a 0 byte for Lc
            parts.push(new Buffer([0]));
          }
          parts.push(new Buffer([this.le >> 8, this.le & 0xFF]));
        }
      }
      return Buffer.concat(parts);
    }
  }, {
    key: 'toString',
    value: function toString() {
      var parts = ['ApduCommand class 0x', this.commandClass.toString(16), ', instruction 0x', this.instruction.toString(16), ', P1 0x', this.p1.toString(16), ', P2 0x', this.p2.toString(16), '\n'];
      if (this.data && this.data.length) {
        var buf = Buffer.concat(this.data);
        parts.push(buf.length + ' bytes: ' + buf.toString('hex'));
      }
      return parts.join('');
    }
  }, {
    key: 'commandClass',
    get: function get() {
      return this.preamble[0];
    },
    set: function set(value) {
      this.preamble.writeUInt8(value, 0);
    }
  }, {
    key: 'instruction',
    get: function get() {
      return this.preamble[1];
    },
    set: function set(value) {
      this.preamble.writeUInt8(value, 1);
    }
  }, {
    key: 'p1',
    get: function get() {
      return this.preamble[2];
    },
    set: function set(value) {
      this.preamble.writeUInt8(value, 2);
    }
  }, {
    key: 'p2',
    get: function get() {
      return this.preamble[3];
    },
    set: function set(value) {
      this.preamble.writeUInt8(value, 3);
    }
  }]);

  return ApduCommand;
}();

exports.default = ApduCommand;
}).call(this,require("buffer").Buffer)
},{"buffer":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/buffer/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/tlvlib/build/lib/apdu/Response.js":[function(require,module,exports){
(function (Buffer){
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

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; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

var _ber = require('../ber');

var _ber2 = _interopRequireDefault(_ber);

var _TlvList = require('../TlvList');

var _TlvList2 = _interopRequireDefault(_TlvList);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

/**
 * An APDU response. The truth is this is a nonstandard implementation because we
 * assume the first byte is a "template identifier" as it is in Miura APDU responses,
 * and the rest of the payload is a tlv list. If you don't want that, just pad the
 * buffer with an extra byte at the beginning...
 */
var ApduResponse = function () {
  function ApduResponse(buffer) {
    var start = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
    var length = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : buffer.length - start;
    var isRaw = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;

    _classCallCheck(this, ApduResponse);

    if (Buffer.isBuffer(buffer)) {
      this.sw1 = buffer[start + length - 2];
      this.sw2 = buffer[start + length - 1];
      if (length === 2) {
        // Only a success value.
        return;
      }
      if (isRaw) {
        this.data = buffer.slice(start, start + length - 2);
      } else {
        this.template = buffer[start];
        var lenInfo = _ber2.default.readLength(buffer, start + 1);

        if (lenInfo.lengthValue !== length - 3 - lenInfo.lengthOfEncoding) {
          var buflen = length - 3 - lenInfo.lengthOfEncoding;
          var msg = 'Invalid ApduResponse length ' + lenInfo.lengthValue + ' vs buffer length ' + buflen;
          throw new Error(msg);
        }
        this.data = buffer.slice(start + 1 + lenInfo.lengthOfEncoding, start + length - 2);
      }
    } else if (buffer instanceof _TlvList2.default) {
      this._tlvs = buffer;
      this.data = buffer.toBytes();
      this.sw1 = 0x90;
      this.sw2 = 0;
    } else {
      // TODO create a blank response that can be added to
      throw new Error('You must provide a Buffer or TlvList to create an APDU response.');
    }
  }

  _createClass(ApduResponse, [{
    key: 'toString',
    value: function toString(shouldParse) {
      var parts = [];
      if (this.template) {
        parts.push('Template: 0x' + this.template.toString(16));
      }
      if (this.data) {
        parts.push('Data (' + this.data.length + ' bytes): 0x' + this.data.toString('hex'));
      }
      if (this._tlvs || shouldParse && this.tlvs) {
        parts.push(this.tlvs.toString(shouldParse));
      }
      parts.push('SW1: 0x' + this.sw1.toString(16) + ' SW2: 0x' + this.sw2.toString(16));
      return parts.join('\n');
    }
  }, {
    key: 'isSuccess',
    get: function get() {
      return this.sw1 === 0x90 && this.sw2 === 0;
    }
  }, {
    key: 'tlvs',
    get: function get() {
      if (!this._tlvs) {
        this._tlvs = new _TlvList2.default(this.data);
      }
      return this._tlvs;
    }
  }]);

  return ApduResponse;
}();

exports.default = ApduResponse;
}).call(this,{"isBuffer":require("../../../../is-buffer/index.js")})
},{"../../../../is-buffer/index.js":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/is-buffer/index.js","../TlvList":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/tlvlib/build/lib/TlvList.js","../ber":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/tlvlib/build/lib/ber.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/tlvlib/build/lib/ber.js":[function(require,module,exports){
arguments[4]["/Users/aravidas/Documents/Git/retail-sdk/node_modules/miura-emv/node_modules/tlvlib/build/lib/ber.js"][0].apply(exports,arguments)
},{"buffer":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/buffer/index.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/util/node_modules/inherits/inherits_browser.js":[function(require,module,exports){
if (typeof Object.create === 'function') {
  // implementation from standard node.js 'util' module
  module.exports = function inherits(ctor, superCtor) {
    ctor.super_ = superCtor
    ctor.prototype = Object.create(superCtor.prototype, {
      constructor: {
        value: ctor,
        enumerable: false,
        writable: true,
        configurable: true
      }
    });
  };
} else {
  // old school shim for old browsers
  module.exports = function inherits(ctor, superCtor) {
    ctor.super_ = superCtor
    var TempCtor = function () {}
    TempCtor.prototype = superCtor.prototype
    ctor.prototype = new TempCtor()
    ctor.prototype.constructor = ctor
  }
}

},{}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/util/support/isBufferBrowser.js":[function(require,module,exports){
module.exports = function isBuffer(arg) {
  return arg && typeof arg === 'object'
    && typeof arg.copy === 'function'
    && typeof arg.fill === 'function'
    && typeof arg.readUInt8 === 'function';
}
},{}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/util/util.js":[function(require,module,exports){
(function (process,global){
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.

var formatRegExp = /%[sdj%]/g;
exports.format = function(f) {
  if (!isString(f)) {
    var objects = [];
    for (var i = 0; i < arguments.length; i++) {
      objects.push(inspect(arguments[i]));
    }
    return objects.join(' ');
  }

  var i = 1;
  var args = arguments;
  var len = args.length;
  var str = String(f).replace(formatRegExp, function(x) {
    if (x === '%%') return '%';
    if (i >= len) return x;
    switch (x) {
      case '%s': return String(args[i++]);
      case '%d': return Number(args[i++]);
      case '%j':
        try {
          return JSON.stringify(args[i++]);
        } catch (_) {
          return '[Circular]';
        }
      default:
        return x;
    }
  });
  for (var x = args[i]; i < len; x = args[++i]) {
    if (isNull(x) || !isObject(x)) {
      str += ' ' + x;
    } else {
      str += ' ' + inspect(x);
    }
  }
  return str;
};


// Mark that a method should not be used.
// Returns a modified function which warns once by default.
// If --no-deprecation is set, then it is a no-op.
exports.deprecate = function(fn, msg) {
  // Allow for deprecating things in the process of starting up.
  if (isUndefined(global.process)) {
    return function() {
      return exports.deprecate(fn, msg).apply(this, arguments);
    };
  }

  if (process.noDeprecation === true) {
    return fn;
  }

  var warned = false;
  function deprecated() {
    if (!warned) {
      if (process.throwDeprecation) {
        throw new Error(msg);
      } else if (process.traceDeprecation) {
        console.trace(msg);
      } else {
        console.error(msg);
      }
      warned = true;
    }
    return fn.apply(this, arguments);
  }

  return deprecated;
};


var debugs = {};
var debugEnviron;
exports.debuglog = function(set) {
  if (isUndefined(debugEnviron))
    debugEnviron = process.env.NODE_DEBUG || '';
  set = set.toUpperCase();
  if (!debugs[set]) {
    if (new RegExp('\\b' + set + '\\b', 'i').test(debugEnviron)) {
      var pid = process.pid;
      debugs[set] = function() {
        var msg = exports.format.apply(exports, arguments);
        console.error('%s %d: %s', set, pid, msg);
      };
    } else {
      debugs[set] = function() {};
    }
  }
  return debugs[set];
};


/**
 * Echos the value of a value. Trys to print the value out
 * in the best way possible given the different types.
 *
 * @param {Object} obj The object to print out.
 * @param {Object} opts Optional options object that alters the output.
 */
/* legacy: obj, showHidden, depth, colors*/
function inspect(obj, opts) {
  // default options
  var ctx = {
    seen: [],
    stylize: stylizeNoColor
  };
  // legacy...
  if (arguments.length >= 3) ctx.depth = arguments[2];
  if (arguments.length >= 4) ctx.colors = arguments[3];
  if (isBoolean(opts)) {
    // legacy...
    ctx.showHidden = opts;
  } else if (opts) {
    // got an "options" object
    exports._extend(ctx, opts);
  }
  // set default options
  if (isUndefined(ctx.showHidden)) ctx.showHidden = false;
  if (isUndefined(ctx.depth)) ctx.depth = 2;
  if (isUndefined(ctx.colors)) ctx.colors = false;
  if (isUndefined(ctx.customInspect)) ctx.customInspect = true;
  if (ctx.colors) ctx.stylize = stylizeWithColor;
  return formatValue(ctx, obj, ctx.depth);
}
exports.inspect = inspect;


// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics
inspect.colors = {
  'bold' : [1, 22],
  'italic' : [3, 23],
  'underline' : [4, 24],
  'inverse' : [7, 27],
  'white' : [37, 39],
  'grey' : [90, 39],
  'black' : [30, 39],
  'blue' : [34, 39],
  'cyan' : [36, 39],
  'green' : [32, 39],
  'magenta' : [35, 39],
  'red' : [31, 39],
  'yellow' : [33, 39]
};

// Don't use 'blue' not visible on cmd.exe
inspect.styles = {
  'special': 'cyan',
  'number': 'yellow',
  'boolean': 'yellow',
  'undefined': 'grey',
  'null': 'bold',
  'string': 'green',
  'date': 'magenta',
  // "name": intentionally not styling
  'regexp': 'red'
};


function stylizeWithColor(str, styleType) {
  var style = inspect.styles[styleType];

  if (style) {
    return '\u001b[' + inspect.colors[style][0] + 'm' + str +
           '\u001b[' + inspect.colors[style][1] + 'm';
  } else {
    return str;
  }
}


function stylizeNoColor(str, styleType) {
  return str;
}


function arrayToHash(array) {
  var hash = {};

  array.forEach(function(val, idx) {
    hash[val] = true;
  });

  return hash;
}


function formatValue(ctx, value, recurseTimes) {
  // Provide a hook for user-specified inspect functions.
  // Check that value is an object with an inspect function on it
  if (ctx.customInspect &&
      value &&
      isFunction(value.inspect) &&
      // Filter out the util module, it's inspect function is special
      value.inspect !== exports.inspect &&
      // Also filter out any prototype objects using the circular check.
      !(value.constructor && value.constructor.prototype === value)) {
    var ret = value.inspect(recurseTimes, ctx);
    if (!isString(ret)) {
      ret = formatValue(ctx, ret, recurseTimes);
    }
    return ret;
  }

  // Primitive types cannot have properties
  var primitive = formatPrimitive(ctx, value);
  if (primitive) {
    return primitive;
  }

  // Look up the keys of the object.
  var keys = Object.keys(value);
  var visibleKeys = arrayToHash(keys);

  if (ctx.showHidden) {
    keys = Object.getOwnPropertyNames(value);
  }

  // IE doesn't make error fields non-enumerable
  // http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx
  if (isError(value)
      && (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) {
    return formatError(value);
  }

  // Some type of object without properties can be shortcutted.
  if (keys.length === 0) {
    if (isFunction(value)) {
      var name = value.name ? ': ' + value.name : '';
      return ctx.stylize('[Function' + name + ']', 'special');
    }
    if (isRegExp(value)) {
      return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
    }
    if (isDate(value)) {
      return ctx.stylize(Date.prototype.toString.call(value), 'date');
    }
    if (isError(value)) {
      return formatError(value);
    }
  }

  var base = '', array = false, braces = ['{', '}'];

  // Make Array say that they are Array
  if (isArray(value)) {
    array = true;
    braces = ['[', ']'];
  }

  // Make functions say that they are functions
  if (isFunction(value)) {
    var n = value.name ? ': ' + value.name : '';
    base = ' [Function' + n + ']';
  }

  // Make RegExps say that they are RegExps
  if (isRegExp(value)) {
    base = ' ' + RegExp.prototype.toString.call(value);
  }

  // Make dates with properties first say the date
  if (isDate(value)) {
    base = ' ' + Date.prototype.toUTCString.call(value);
  }

  // Make error with message first say the error
  if (isError(value)) {
    base = ' ' + formatError(value);
  }

  if (keys.length === 0 && (!array || value.length == 0)) {
    return braces[0] + base + braces[1];
  }

  if (recurseTimes < 0) {
    if (isRegExp(value)) {
      return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
    } else {
      return ctx.stylize('[Object]', 'special');
    }
  }

  ctx.seen.push(value);

  var output;
  if (array) {
    output = formatArray(ctx, value, recurseTimes, visibleKeys, keys);
  } else {
    output = keys.map(function(key) {
      return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array);
    });
  }

  ctx.seen.pop();

  return reduceToSingleString(output, base, braces);
}


function formatPrimitive(ctx, value) {
  if (isUndefined(value))
    return ctx.stylize('undefined', 'undefined');
  if (isString(value)) {
    var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '')
                                             .replace(/'/g, "\\'")
                                             .replace(/\\"/g, '"') + '\'';
    return ctx.stylize(simple, 'string');
  }
  if (isNumber(value))
    return ctx.stylize('' + value, 'number');
  if (isBoolean(value))
    return ctx.stylize('' + value, 'boolean');
  // For some reason typeof null is "object", so special case here.
  if (isNull(value))
    return ctx.stylize('null', 'null');
}


function formatError(value) {
  return '[' + Error.prototype.toString.call(value) + ']';
}


function formatArray(ctx, value, recurseTimes, visibleKeys, keys) {
  var output = [];
  for (var i = 0, l = value.length; i < l; ++i) {
    if (hasOwnProperty(value, String(i))) {
      output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
          String(i), true));
    } else {
      output.push('');
    }
  }
  keys.forEach(function(key) {
    if (!key.match(/^\d+$/)) {
      output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
          key, true));
    }
  });
  return output;
}


function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) {
  var name, str, desc;
  desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] };
  if (desc.get) {
    if (desc.set) {
      str = ctx.stylize('[Getter/Setter]', 'special');
    } else {
      str = ctx.stylize('[Getter]', 'special');
    }
  } else {
    if (desc.set) {
      str = ctx.stylize('[Setter]', 'special');
    }
  }
  if (!hasOwnProperty(visibleKeys, key)) {
    name = '[' + key + ']';
  }
  if (!str) {
    if (ctx.seen.indexOf(desc.value) < 0) {
      if (isNull(recurseTimes)) {
        str = formatValue(ctx, desc.value, null);
      } else {
        str = formatValue(ctx, desc.value, recurseTimes - 1);
      }
      if (str.indexOf('\n') > -1) {
        if (array) {
          str = str.split('\n').map(function(line) {
            return '  ' + line;
          }).join('\n').substr(2);
        } else {
          str = '\n' + str.split('\n').map(function(line) {
            return '   ' + line;
          }).join('\n');
        }
      }
    } else {
      str = ctx.stylize('[Circular]', 'special');
    }
  }
  if (isUndefined(name)) {
    if (array && key.match(/^\d+$/)) {
      return str;
    }
    name = JSON.stringify('' + key);
    if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) {
      name = name.substr(1, name.length - 2);
      name = ctx.stylize(name, 'name');
    } else {
      name = name.replace(/'/g, "\\'")
                 .replace(/\\"/g, '"')
                 .replace(/(^"|"$)/g, "'");
      name = ctx.stylize(name, 'string');
    }
  }

  return name + ': ' + str;
}


function reduceToSingleString(output, base, braces) {
  var numLinesEst = 0;
  var length = output.reduce(function(prev, cur) {
    numLinesEst++;
    if (cur.indexOf('\n') >= 0) numLinesEst++;
    return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1;
  }, 0);

  if (length > 60) {
    return braces[0] +
           (base === '' ? '' : base + '\n ') +
           ' ' +
           output.join(',\n  ') +
           ' ' +
           braces[1];
  }

  return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1];
}


// NOTE: These type checking functions intentionally don't use `instanceof`
// because it is fragile and can be easily faked with `Object.create()`.
function isArray(ar) {
  return Array.isArray(ar);
}
exports.isArray = isArray;

function isBoolean(arg) {
  return typeof arg === 'boolean';
}
exports.isBoolean = isBoolean;

function isNull(arg) {
  return arg === null;
}
exports.isNull = isNull;

function isNullOrUndefined(arg) {
  return arg == null;
}
exports.isNullOrUndefined = isNullOrUndefined;

function isNumber(arg) {
  return typeof arg === 'number';
}
exports.isNumber = isNumber;

function isString(arg) {
  return typeof arg === 'string';
}
exports.isString = isString;

function isSymbol(arg) {
  return typeof arg === 'symbol';
}
exports.isSymbol = isSymbol;

function isUndefined(arg) {
  return arg === void 0;
}
exports.isUndefined = isUndefined;

function isRegExp(re) {
  return isObject(re) && objectToString(re) === '[object RegExp]';
}
exports.isRegExp = isRegExp;

function isObject(arg) {
  return typeof arg === 'object' && arg !== null;
}
exports.isObject = isObject;

function isDate(d) {
  return isObject(d) && objectToString(d) === '[object Date]';
}
exports.isDate = isDate;

function isError(e) {
  return isObject(e) &&
      (objectToString(e) === '[object Error]' || e instanceof Error);
}
exports.isError = isError;

function isFunction(arg) {
  return typeof arg === 'function';
}
exports.isFunction = isFunction;

function isPrimitive(arg) {
  return arg === null ||
         typeof arg === 'boolean' ||
         typeof arg === 'number' ||
         typeof arg === 'string' ||
         typeof arg === 'symbol' ||  // ES6 symbol
         typeof arg === 'undefined';
}
exports.isPrimitive = isPrimitive;

exports.isBuffer = require('./support/isBuffer');

function objectToString(o) {
  return Object.prototype.toString.call(o);
}


function pad(n) {
  return n < 10 ? '0' + n.toString(10) : n.toString(10);
}


var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep',
              'Oct', 'Nov', 'Dec'];

// 26 Feb 16:19:34
function timestamp() {
  var d = new Date();
  var time = [pad(d.getHours()),
              pad(d.getMinutes()),
              pad(d.getSeconds())].join(':');
  return [d.getDate(), months[d.getMonth()], time].join(' ');
}


// log is just a thin wrapper to console.log that prepends a timestamp
exports.log = function() {
  console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments));
};


/**
 * Inherit the prototype methods from one constructor into another.
 *
 * The Function.prototype.inherits from lang.js rewritten as a standalone
 * function (not on Function.prototype). NOTE: If this file is to be loaded
 * during bootstrapping this function needs to be rewritten using some native
 * functions as prototype setup using normal JavaScript does not work as
 * expected during bootstrapping (see mirror.js in r114903).
 *
 * @param {function} ctor Constructor function which needs to inherit the
 *     prototype.
 * @param {function} superCtor Constructor function to inherit prototype from.
 */
exports.inherits = require('inherits');

exports._extend = function(origin, add) {
  // Don't do anything if add isn't an object
  if (!add || !isObject(add)) return origin;

  var keys = Object.keys(add);
  var i = keys.length;
  while (i--) {
    origin[keys[i]] = add[keys[i]];
  }
  return origin;
};

function hasOwnProperty(obj, prop) {
  return Object.prototype.hasOwnProperty.call(obj, prop);
}

}).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
},{"./support/isBuffer":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/util/support/isBufferBrowser.js","_process":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/process/browser.js","inherits":"/Users/aravidas/Documents/Git/retail-sdk/node_modules/util/node_modules/inherits/inherits_browser.js"}],"/Users/aravidas/Documents/Git/retail-sdk/node_modules/yaku/lib/yaku.js":[function(require,module,exports){
(function (global){
/*
 Yaku v0.13.8
 (c) 2015 Yad Smood. http://ysmood.org
 License MIT
*/
(function () {
    "use strict";

    var $undefined
    , $null = null
    , root = typeof global === "object" ? global : window
    , isLongStackTrace = false
    , process = root.process
    , Arr = Array
    , Err = Error

    , $rejected = 0
    , $resolved = 1
    , $pending = 2

    , $Symbol = "Symbol"
    , $iterator = "iterator"
    , $return = "return"

    , $unhandled = "_uh"
    , $promiseTrace = "_pt"
    , $settlerTrace = "_st"

    , $invalidThis = "Invalid this"
    , $invalidArgument = "Invalid argument"
    , $fromPrevious = "\nFrom previous "
    , $promiseCircularChain = "Chaining cycle detected for promise"
    , $unhandledRejectionMsg = "Uncaught (in promise)"
    , $rejectionHandled = "rejectionHandled"
    , $unhandledRejection = "unhandledRejection"

    , $tryCatchFn
    , $tryCatchThis
    , $tryErr = { e: $null }
    , $noop = function () {}
    ;

    /**
     * This class follows the [Promises/A+](https://promisesaplus.com) and
     * [ES6](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-promise-objects) spec
     * with some extra helpers.
     * @param  {Function} executor Function object with two arguments resolve, reject.
     * The first argument fulfills the promise, the second argument rejects it.
     * We can call these functions, once our operation is completed.
     */
    var Yaku = module.exports = function Promise (executor) {
        var self = this,
            err;

        // "this._s" is the internal state of: pending, resolved or rejected
        // "this._v" is the internal value

        if (!isObject(self) || self._s !== $undefined)
            throw genTypeError($invalidThis);

        self._s = $pending;

        if (isLongStackTrace) self[$promiseTrace] = genTraceInfo();

        if (executor !== $noop) {
            if (!isFunction(executor))
                throw genTypeError($invalidArgument);

            err = genTryCatcher(executor)(
                genSettler(self, $resolved),
                genSettler(self, $rejected)
            );

            if (err === $tryErr)
                settlePromise(self, $rejected, err.e);
        }
    };

    Yaku["default"] = Yaku;

    extendPrototype(Yaku, {
        /**
         * Appends fulfillment and rejection handlers to the promise,
         * and returns a new promise resolving to the return value of the called handler.
         * @param  {Function} onFulfilled Optional. Called when the Promise is resolved.
         * @param  {Function} onRejected  Optional. Called when the Promise is rejected.
         * @return {Yaku} It will return a new Yaku which will resolve or reject after
         * @example
         * the current Promise.
         * ```js
         * var Promise = require('yaku');
         * var p = Promise.resolve(10);
         *
         * p.then((v) => {
         *     console.log(v);
         * });
         * ```
         */
        then: function then (onFulfilled, onRejected) {
            return addHandler(
                this,
                newCapablePromise(Yaku.speciesConstructor(this, Yaku)),
                onFulfilled,
                onRejected
            );
        },

        /**
         * The `catch()` method returns a Promise and deals with rejected cases only.
         * It behaves the same as calling `Promise.prototype.then(undefined, onRejected)`.
         * @param  {Function} onRejected A Function called when the Promise is rejected.
         * This function has one argument, the rejection reason.
         * @return {Yaku} A Promise that deals with rejected cases only.
         * @example
         * ```js
         * var Promise = require('yaku');
         * var p = Promise.reject(new Error("ERR"));
         *
         * p['catch']((v) => {
         *     console.log(v);
         * });
         * ```
         */
        "catch": function (onRejected) {
            return this.then($undefined, onRejected);
        },

        // The number of current promises that attach to this Yaku instance.
        _pCount: 0,

        // The parent Yaku.
        _pre: $null,

        // A unique type flag, it helps different versions of Yaku know each other.
        _Yaku: 1
    });

    /**
     * The `Promise.resolve(value)` method returns a Promise object that is resolved with the given value.
     * If the value is a thenable (i.e. has a then method), the returned promise will "follow" that thenable,
     * adopting its eventual state; otherwise the returned promise will be fulfilled with the value.
     * @param  {Any} value Argument to be resolved by this Promise.
     * Can also be a Promise or a thenable to resolve.
     * @return {Yaku}
     * @example
     * ```js
     * var Promise = require('yaku');
     * var p = Promise.resolve(10);
     * ```
     */
    Yaku.resolve = function resolve (val) {
        return isYaku(val) ? val : settleWithX(newCapablePromise(this), val);
    };

    /**
     * The `Promise.reject(reason)` method returns a Promise object that is rejected with the given reason.
     * @param  {Any} reason Reason why this Promise rejected.
     * @return {Yaku}
     * @example
     * ```js
     * var Promise = require('yaku');
     * var p = Promise.reject(new Error("ERR"));
     * ```
     */
    Yaku.reject = function reject (reason) {
        return settlePromise(newCapablePromise(this), $rejected, reason);
    };

    /**
     * The `Promise.race(iterable)` method returns a promise that resolves or rejects
     * as soon as one of the promises in the iterable resolves or rejects,
     * with the value or reason from that promise.
     * @param  {iterable} iterable An iterable object, such as an Array.
     * @return {Yaku} The race function returns a Promise that is settled
     * the same way as the first passed promise to settle.
     * It resolves or rejects, whichever happens first.
     * @example
     * ```js
     * var Promise = require('yaku');
     * Promise.race([
     *     123,
     *     Promise.resolve(0)
     * ])
     * .then((value) => {
     *     console.log(value); // => 123
     * });
     * ```
     */
    Yaku.race = function race (iterable) {
        var self = this
        , p = newCapablePromise(self)

        , resolve = function (val) {
            settlePromise(p, $resolved, val);
        }

        , reject = function (val) {
            settlePromise(p, $rejected, val);
        }

        , ret = genTryCatcher(each)(iterable, function (v) {
            self.resolve(v).then(resolve, reject);
        });

        if (ret === $tryErr) return self.reject(ret.e);

        return p;
    };

    /**
     * The `Promise.all(iterable)` method returns a promise that resolves when
     * all of the promises in the iterable argument have resolved.
     *
     * The result is passed as an array of values from all the promises.
     * If something passed in the iterable array is not a promise,
     * it's converted to one by Promise.resolve. If any of the passed in promises rejects,
     * the all Promise immediately rejects with the value of the promise that rejected,
     * discarding all the other promises whether or not they have resolved.
     * @param  {iterable} iterable An iterable object, such as an Array.
     * @return {Yaku}
     * @example
     * ```js
     * var Promise = require('yaku');
     * Promise.all([
     *     123,
     *     Promise.resolve(0)
     * ])
     * .then((values) => {
     *     console.log(values); // => [123, 0]
     * });
     * ```
     * @example
     * Use with iterable.
     * ```js
     * var Promise = require('yaku');
     * Promise.all((function * () {
     *     yield 10;
     *     yield new Promise(function (r) { setTimeout(r, 1000, "OK") });
     * })())
     * .then((values) => {
     *     console.log(values); // => [123, 0]
     * });
     * ```
     */
    Yaku.all = function all (iterable) {
        var self = this
        , p1 = newCapablePromise(self)
        , res = []
        , ret
        ;

        function reject (reason) {
            settlePromise(p1, $rejected, reason);
        }

        ret = genTryCatcher(each)(iterable, function (item, i) {
            self.resolve(item).then(function (value) {
                res[i] = value;
                if (!--ret) settlePromise(p1, $resolved, res);
            }, reject);
        });

        if (ret === $tryErr) return self.reject(ret.e);

        if (!ret) settlePromise(p1, $resolved, []);

        return p1;
    };

    /**
     * The ES6 Symbol object that Yaku should use, by default it will use the
     * global one.
     * @type {Object}
     * @example
     * ```js
     * var core = require("core-js/library");
     * var Promise = require("yaku");
     * Promise.Symbol = core.Symbol;
     * ```
     */
    Yaku.Symbol = root[$Symbol] || {};

    /**
     * Use this api to custom the species behavior.
     * https://tc39.github.io/ecma262/#sec-speciesconstructor
     * @param {Any} O The current this object.
     * @param {Function} defaultConstructor
     */
    Yaku.speciesConstructor = function (O, D) {
        var C = O.constructor;

        return C ? (C[Yaku[$Symbol].species] || C) : D;
    };

    /**
     * Catch all possibly unhandled rejections. If you want to use specific
     * format to display the error stack, overwrite it.
     * If it is set, auto `console.error` unhandled rejection will be disabled.
     * @param {Any} reason The rejection reason.
     * @param {Yaku} p The promise that was rejected.
     * @example
     * ```js
     * var Promise = require('yaku');
     * Promise.onUnhandledRejection = (reason) => {
     *     console.error(reason);
     * };
     *
     * // The console will log an unhandled rejection error message.
     * Promise.reject('my reason');
     *
     * // The below won't log the unhandled rejection error message.
     * Promise.reject('v').catch(() => {});
     * ```
     */
    Yaku.unhandledRejection = function (reason, p) {
        var con = root.console;
        if (con) {
            con.error($unhandledRejectionMsg, genStackInfo(reason, p));
        }
    };

    /**
     * Emitted whenever a Promise was rejected and an error handler was
     * attached to it (for example with .catch()) later than after an event loop turn.
     * @param {Any} reason The rejection reason.
     * @param {Yaku} p The promise that was rejected.
     */
    Yaku.rejectionHandled = $noop;

    /**
     * It is used to enable the long stack trace.
     * Once it is enabled, it can't be reverted.
     * While it is very helpful in development and testing environments,
     * it is not recommended to use it in production. It will slow down your
     * application and waste your memory.
     * @example
     * ```js
     * var Promise = require('yaku');
     * Promise.enableLongStackTrace();
     * ```
     */
    Yaku.enableLongStackTrace = function () {
        isLongStackTrace = true;
    };

    /**
     * Only Node has `process.nextTick` function. For browser there are
     * so many ways to polyfill it. Yaku won't do it for you, instead you
     * can choose what you prefer. For example, this project
     * [setImmediate](https://github.com/YuzuJS/setImmediate).
     * By default, Yaku will use `process.nextTick` on Node, `setTimeout` on browser.
     * @type {Function}
     * @example
     * ```js
     * var Promise = require('yaku');
     * Promise.nextTick = fn => window.setImmediate(fn);
     * ```
     * @example
     * You can even use sync resolution if you really know what you are doing.
     * ```js
     * var Promise = require('yaku');
     * Promise.nextTick = fn => fn();
     * ```
     */
    Yaku.nextTick = process ?
        process.nextTick :
        function (fn) { setTimeout(fn); };

    // ********************** Private **********************

    Yaku._Yaku = 1;

    /**
     * All static variable name will begin with `$`. Such as `$rejected`.
     * @private
     */

    // ******************************* Utils ********************************

    function extendPrototype (src, target) {
        for (var k in target) {
            src.prototype[k] = target[k];
        }
        return src;
    }

    function isObject (obj) {
        return typeof obj === "object";
    }

    function isFunction (obj) {
        return typeof obj === "function";
    }

    function isInstanceOf (a, b) {
        return a instanceof b;
    }

    function isError (obj) {
        return isInstanceOf(obj, Err);
    }

    function ensureType (obj, fn, msg) {
        if (!fn(obj)) throw genTypeError(msg);
    }

    /**
     * Wrap a function into a try-catch.
     * @private
     * @return {Any | $tryErr}
     */
    function tryCatcher () {
        try {
            return $tryCatchFn.apply($tryCatchThis, arguments);
        } catch (e) {
            $tryErr.e = e;
            return $tryErr;
        }
    }

    /**
     * Generate a try-catch wrapped function.
     * @private
     * @param  {Function} fn
     * @return {Function}
     */
    function genTryCatcher (fn, self) {
        $tryCatchFn = fn;
        $tryCatchThis = self;
        return tryCatcher;
    }

    /**
     * Generate a scheduler.
     * @private
     * @param  {Integer}  initQueueSize
     * @param  {Function} fn `(Yaku, Value) ->` The schedule handler.
     * @return {Function} `(Yaku, Value) ->` The scheduler.
     */
    function genScheduler (initQueueSize, fn) {
        /**
         * All async promise will be scheduled in
         * here, so that they can be execute on the next tick.
         * @private
         */
        var fnQueue = Arr(initQueueSize)
        , fnQueueLen = 0;

        /**
         * Run all queued functions.
         * @private
         */
        function flush () {
            var i = 0;
            while (i < fnQueueLen) {
                fn(fnQueue[i], fnQueue[i + 1]);
                fnQueue[i++] = $undefined;
                fnQueue[i++] = $undefined;
            }

            fnQueueLen = 0;
            if (fnQueue.length > initQueueSize) fnQueue.length = initQueueSize;
        }

        return function (v, arg) {
            fnQueue[fnQueueLen++] = v;
            fnQueue[fnQueueLen++] = arg;

            if (fnQueueLen === 2) Yaku.nextTick(flush);
        };
    }

    /**
     * Generate a iterator
     * @param  {Any} obj
     * @private
     * @return {Object || TypeError}
     */
    function each (iterable, fn) {
        var len
        , i = 0
        , iter
        , item
        , ret
        ;

        if (!iterable) throw genTypeError($invalidArgument);

        var gen = iterable[Yaku[$Symbol][$iterator]];
        if (isFunction(gen))
            iter = gen.call(iterable);
        else if (isFunction(iterable.next))
            iter = iterable;
        else if (isInstanceOf(iterable, Arr)) {
            len = iterable.length;
            while (i < len) {
                fn(iterable[i], i++);
            }
            return i;
        } else
            throw genTypeError($invalidArgument);

        while (!(item = iter.next()).done) {
            ret = genTryCatcher(fn)(item.value, i++);
            if (ret === $tryErr) {
                if (isFunction(iter[$return])) iter[$return]();
                throw ret.e;
            }
        }

        return i;
    }

    /**
     * Generate type error object.
     * @private
     * @param  {String} msg
     * @return {TypeError}
     */
    function genTypeError (msg) {
        return new TypeError(msg);
    }

    function genTraceInfo (noTitle) {
        return (noTitle ? "" : $fromPrevious) + (new Err().stack || "");
    }


    // *************************** Promise Helpers ****************************

    /**
     * Resolve the value returned by onFulfilled or onRejected.
     * @private
     * @param {Yaku} p1
     * @param {Yaku} p2
     */
    var scheduleHandler = genScheduler(999, function (p1, p2) {
        var x, handler;

        // 2.2.2
        // 2.2.3
        handler = p1._s ? p2._onFulfilled : p2._onRejected;

        // 2.2.7.3
        // 2.2.7.4
        if (handler === $undefined) {
            settlePromise(p2, p1._s, p1._v);
            return;
        }

        // 2.2.7.1
        x = genTryCatcher(callHanler)(handler, p1._v);
        if (x === $tryErr) {
            // 2.2.7.2
            settlePromise(p2, $rejected, x.e);
            return;
        }

        settleWithX(p2, x);
    });

    var scheduleUnhandledRejection = genScheduler(9, function (p) {
        if (!hashOnRejected(p)) {
            p[$unhandled] = 1;
            emitEvent($unhandledRejection, p);
        }
    });

    function emitEvent (name, p) {
        var browserEventName = "on" + name.toLowerCase()
            , browserHandler = root[browserEventName];

        if (process && process.listeners(name).length)
            name === $unhandledRejection ?
                process.emit(name, p._v, p) : process.emit(name, p);
        else if (browserHandler)
            browserHandler({ reason: p._v, promise: p });
        else
            Yaku[name](p._v, p);
    }

    function isYaku (val) { return val && val._Yaku; }

    function newCapablePromise (Constructor) {
        if (isYaku(Constructor)) return new Constructor($noop);

        var p, r, j;
        p = new Constructor(function (resolve, reject) {
            if (p) throw genTypeError();

            r = resolve;
            j = reject;
        });

        ensureType(r, isFunction);
        ensureType(j, isFunction);

        return p;
    }

    /**
     * It will produce a settlePromise function to user.
     * Such as the resolve and reject in this `new Yaku (resolve, reject) ->`.
     * @private
     * @param  {Yaku} self
     * @param  {Integer} state The value is one of `$pending`, `$resolved` or `$rejected`.
     * @return {Function} `(value) -> undefined` A resolve or reject function.
     */
    function genSettler (self, state) {
        return function (value) {
            if (isLongStackTrace)
                self[$settlerTrace] = genTraceInfo(true);

            if (state === $resolved)
                settleWithX(self, value);
            else
                settlePromise(self, state, value);
        };
    }

    /**
     * Link the promise1 to the promise2.
     * @private
     * @param {Yaku} p1
     * @param {Yaku} p2
     * @param {Function} onFulfilled
     * @param {Function} onRejected
     */
    function addHandler (p1, p2, onFulfilled, onRejected) {
        // 2.2.1
        if (isFunction(onFulfilled))
            p2._onFulfilled = onFulfilled;
        if (isFunction(onRejected)) {
            if (p1[$unhandled]) emitEvent($rejectionHandled, p1);

            p2._onRejected = onRejected;
        }

        if (isLongStackTrace) p2._pre = p1;
        p1[p1._pCount++] = p2;

        // 2.2.6
        if (p1._s !== $pending)
            scheduleHandler(p1, p2);

        // 2.2.7
        return p2;
    }

    // iterate tree
    function hashOnRejected (node) {
        // A node shouldn't be checked twice.
        if (node._umark)
            return true;
        else
            node._umark = true;

        var i = 0
        , len = node._pCount
        , child;

        while (i < len) {
            child = node[i++];
            if (child._onRejected || hashOnRejected(child)) return true;
        }
    }

    function genStackInfo (reason, p) {
        var stackInfo = [];

        function trim (str) { return str.replace(/^\s+|\s+$/g, ""); }

        function push (trace) {
            return stackInfo.push(trim(trace));
        }

        if (isLongStackTrace && p[$promiseTrace]) {
            if (p[$settlerTrace])
                push(p[$settlerTrace]);

            // Hope you guys could understand how the back trace works.
            // We only have to iterate through the tree from the bottom to root.
            (function iter (node) {
                if (node) {
                    iter(node._next);
                    push(node[$promiseTrace]);
                    iter(node._pre);
                }
            })(p);
        }

        return (isError(reason) ? reason.stack : reason)
            + ("\n" + stackInfo.join("\n")).replace(/^.+\/node_modules\/yaku\/.+\n?/mg, "");
    }

    function callHanler (handler, value) {
        // 2.2.5
        return handler(value);
    }

    /**
     * Resolve or reject a promise.
     * @private
     * @param  {Yaku} p
     * @param  {Integer} state
     * @param  {Any} value
     */
    function settlePromise (p, state, value) {
        var i = 0
        , len = p._pCount
        , p2;

        // 2.1.2
        // 2.1.3
        if (p._s === $pending) {
            // 2.1.1.1
            p._s = state;
            p._v = value;

            if (state === $rejected) {
                if (isLongStackTrace && isError(value)) {
                    value.longStack = genStackInfo(value, p);
                }

                scheduleUnhandledRejection(p);
            }

            // 2.2.4
            while (i < len) {
                p2 = p[i++];

                if (p2._s !== $pending) continue;

                scheduleHandler(p, p2);
            }
        }

        return p;
    }

    /**
     * Resolve or reject promise with value x. The x can also be a thenable.
     * @private
     * @param {Yaku} p
     * @param {Any | Thenable} x A normal value or a thenable.
     */
    function settleWithX (p, x) {
        // 2.3.1
        if (x === p && x) {
            settlePromise(p, $rejected, genTypeError($promiseCircularChain));
            return p;
        }

        // 2.3.2
        // 2.3.3
        if (x !== $null && (isFunction(x) || isObject(x))) {
            // 2.3.2.1
            var xthen = genTryCatcher(getThen)(x);

            if (xthen === $tryErr) {
                // 2.3.3.2
                settlePromise(p, $rejected, xthen.e);
                return p;
            }

            if (isFunction(xthen)) {
                if (isLongStackTrace && isYaku(x))
                    p._next = x;

                // Fix https://bugs.chromium.org/p/v8/issues/detail?id=4162
                if (isYaku(x))
                    settleXthen(p, x, xthen);
                else
                    Yaku.nextTick(function () {
                        settleXthen(p, x, xthen);
                    });
            } else
                // 2.3.3.4
                settlePromise(p, $resolved, x);
        } else
            // 2.3.4
            settlePromise(p, $resolved, x);

        return p;
    }

    /**
     * Try to get a promise's then method.
     * @private
     * @param  {Thenable} x
     * @return {Function}
     */
    function getThen (x) { return x.then; }

    /**
     * Resolve then with its promise.
     * @private
     * @param  {Yaku} p
     * @param  {Thenable} x
     * @param  {Function} xthen
     */
    function settleXthen (p, x, xthen) {
        // 2.3.3.3
        var err = genTryCatcher(xthen, x)(function (y) {
            // 2.3.3.3.3
            if (x) {
                x = $null;

                // 2.3.3.3.1
                settleWithX(p, y);
            }
        }, function (r) {
            // 2.3.3.3.3
            if (x) {
                x = $null;

                // 2.3.3.3.2
                settlePromise(p, $rejected, r);
            }
        });

        // 2.3.3.3.4.1
        if (err === $tryErr && x) {
            // 2.3.3.3.4.2
            settlePromise(p, $rejected, err.e);
            x = $null;
        }
    }

})();

}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
},{}],"/Users/aravidas/Documents/Git/retail-sdk/package.json":[function(require,module,exports){
module.exports={
  "name": "retail-sdk",
  "version": "3.0.4",
  "description": "A cross platform sdk for applications using PayPal Retail services, such as card acceptance and checkin",
  "main": "index.js",
  "pre-commit": [
    "lint"
  ],
  "pre-push": [
    "test"
  ],
  "scripts": {
    "test": "npm run test2 && npm run test1",
    "test1": "mocha --timeout 10000 --require test/testSetup --recursive ./test/mocha/**",
    "test2": "tape --require ./test/testSetup test/tape/* | tap-diff",
    "ci-test": "JUNIT_REPORT_PATH=report.xml JUNIT_REPORT_STACK=1 mocha --timeout 5000 --require test/testSetup --reporter mocha-jenkins-reporter \"test/**/*.js\"",
    "ci-cover": "istanbul cover _mocha -- --timeout 5000 --require test/testSetup --reporter tap \"test/**/*.js\" > test.tap && istanbul report clover",
    "ci-lint": "eslint js",
    "lint": "eslint js test/tape",
    "code-gen": "gulp develop"
  },
  "repository": {
    "type": "git",
    "url": "git@github.paypal.com:RetailSDK-NewGen/retail-sdk.git"
  },
  "keywords": [
    "retail",
    "paypal_here",
    "emv",
    "sdk"
  ],
  "publishConfig": {
    "registry": "http://npm.paypal.com"
  },
  "author": "PayPal",
  "license": "UNLICENSED",
  "dependencies": {
    "async": "^1.5.0",
    "babel-regenerator-runtime": "^6.5.0",
    "babelify": "^7.2.0",
    "bignumber.js": "2.3.0",
    "browserify": "^13.0.0",
    "commander": "^2.7.1",
    "core-js": "^2.1.0",
    "dustjs-helpers": "^1.6.2",
    "dustjs-linkedin": "^2.6.2",
    "es6-template-strings": "^2.0.0",
    "folderify": "git://github.com/GriffinSchneider/folderify.git#d70cfae87fcafa0de48a370837a73ac5b0e6d9d9",
    "fs-extra": "^0.26.0",
    "glob": "^7.0.0",
    "gulp": "^3.9.0",
    "gulp-concat": "^2.6.0",
    "gulp-jshint": "^1.10.0",
    "gulp-rename": "^1.2.2",
    "gulp-sourcemaps": "^1.5.1",
    "jshint": "2.8.0",
    "l10n-manticore": "^1.0.3",
    "lodash": "^3.6.0",
    "machina": "^2.0.0",
    "manticore": "^1.3.0",
    "manticore-browser": "^1.0.0",
    "manticore-log": "^2.0.0",
    "manticore-paypalerror": "^3.2.0",
    "manticore-util": "^2.4.0",
    "md5": "^2.0.0",
    "miura-emv": "^17.0.1",
    "moment": "^2.9.0",
    "nocycle": "^1.1.0",
    "paypal-invoicing": "^10.0.1",
    "paypalrest-manticore": "^4.3.1",
    "qs": "^6.0.0",
    "readline-sync": "^1.0.0",
    "retail-page-tracker": "^1.4.0",
    "retail-payment-device": "^27.2.0",
    "rimraf": "^2.4.0",
    "tlvlib": "3.5.0",
    "uglifyify": "^3.0.1",
    "vinyl-transform": "^1.0.0",
    "wreck": "^5.4.0",
    "yaku": "^0.13.8"
  },
  "devDependencies": {
    "babel-cli": "^6.3.17",
    "babel-core": "^6.2.1",
    "babel-eslint": "^7.0.0",
    "babel-plugin-syntax-async-functions": "^6.1.18",
    "babel-plugin-transform-es2015-spread": "^6.6.5",
    "babel-plugin-transform-regenerator": "^6.6.0",
    "babel-polyfill": "^6.2.0",
    "babel-preset-es2015": "^6.1.18",
    "babel-preset-es2015-loose": "^7.0.0",
    "babel-register": "^6.7.2",
    "bluebird": "^3.1.1",
    "chai": "^3.1.0",
    "eslint": "3.19.0",
    "eslint-config-airbnb-base": "^9.0.0",
    "eslint-plugin-import": "^2.0.1",
    "eslint-plugin-react": "^4.2.1",
    "estraverse-fb": "^1.3.1",
    "gulp": "^3.9.0",
    "gulp-base64-encode": "^1.0.1",
    "gulp-jshint": "^1.11.1",
    "gulp-run": "^1.7.1",
    "istanbul": "^0.3.15",
    "manticore-gen": "4.1.0",
    "mocha": "^2.2.4",
    "mocha-jenkins-reporter": "^0.1.8",
    "mockery": "^1.4.0",
    "pre-commit": "^1.1.3",
    "pre-push": "^0.1.1",
    "proxyquire": "^1.7.10",
    "sinon": "^1.17.4",
    "sinon-chai": "^2.8.0",
    "stream-browserify": "^2.0.1",
    "tap-diff": "^0.1.1",
    "tape": "^4.2.2"
  }
}

},{}],"/Users/aravidas/Documents/Git/retail-sdk/resources/feature-map.json":[function(require,module,exports){
module.exports={
  "VERSION":"1.0",
  "US":{
    "MCC_CODES":{
      "4121":"*",
      "5812":"*",
      "5813":"*",
      "5814":"*",
      "7230":"*",
      "7298":"*",
      "4411":"*",
      "7519":"*",
      "7011":"*",
      "7512":"*"
    },
    "CONTACTLESS_LIMIT":"10000"
  },
  "GB":{
    "CONTACTLESS_LIMIT":"20"
  },
  "AU":{
    "CONTACTLESS_LIMIT":"*"
  }
}
},{}]},{},["/Users/aravidas/Documents/Git/retail-sdk/js/debug.js","/Users/aravidas/Documents/Git/retail-sdk/js/index.js"]);
