// 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(){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}return e})()({"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/common/retailSDKUtil.js","manticore":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore/browser.js","manticore-log":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-log/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/resources/feature-map.json","./CachedServerFile":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/common/CachedServerFile.js","manticore-log":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-log/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/oauth2/token/' + op;
  } else if (service === 'payments') {
    return 'https://' + host + '.paypal.com/v1/payments/' + op;
  } else if (service === 'activities') {
    return 'https://' + host + '.paypal.com/v1/activities/' + 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 {string} payerId The payer id 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! @readonly
 * @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.invalidMerchantUserInfo, 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.invalidMerchantStatusInfo, null);
        return;
      }
      _this6.status = status;
      _this6.logglyAccessToken = status.logglyAccessToken;
      _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);
    // TODO add payer_id back after we have added the scope for all existing and future partners
    // && userInfo.payer_id);
  };

  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.invalidMerchantUserInfo;
    }
    if (!this._validateStatus(merchantData.status)) {
      throw _sdkErrors.merchant.invalidMerchantStatusInfo;
    }

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

    _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: 'payerId',
    get: function get() {
      return this.userInfo ? this.userInfo.payer_id : 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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/common/Features.js","./sdkErrors":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/common/sdkErrors.js","async":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/async/lib/async.js","bignumber.js":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/bignumber.js/bignumber.js","events":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/events/events.js","manticore-log":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-log/index.js","paypal-invoicing":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypal-invoicing/build/index.js","paypalrest-manticore":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypalrest-manticore/build/index.js","retail-page-tracker":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-page-tracker/build/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/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 = // eslint-disable-line import/prefer-default-export
/**
 * @constructor
 */
exports.NetworkResponse = function NetworkResponse() {
  _classCallCheck(this, NetworkResponse);
};

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

},{}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/common/NetworkHandler/NetworkRequest.js","manticore":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore/browser.js","manticore-log":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-log/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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.dname;
    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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-log/index.js","paypal-invoicing":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypal-invoicing/build/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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
 * @property {string} currency Currency for the Merchant
 * @property {string} environment Environment- live or sandbox
 */
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,
      currency: this.currency,
      environment: this.environment
    };
  };

  return SdkEnvironmentInfo;
}();

},{}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-log/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/common/Merchant.js","../common/retailSDKUtil":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/common/retailSDKUtil.js","manticore":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore/browser.js","manticore-log":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-log/index.js","qs/lib/stringify":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/qs/lib/stringify.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/events/events.js","manticore-log":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-log/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/events/events.js","manticore-log":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-log/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/common/localized/en.js","./localized/jp":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/common/localized/jp.js","l10n-manticore":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/l10n-manticore/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/common/l10n.js","../transaction/PaymentType":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/transaction/PaymentType.js","./sdkErrors":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/common/sdkErrors.js","bignumber.js":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/bignumber.js/bignumber.js","manticore":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore/browser.js","manticore-log":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-log/index.js","manticore-util":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-util/build/index.js","moment":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/moment/moment.js","paypal-invoicing":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypal-invoicing/build/index.js","retail-payment-device":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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'),
  notSupported: payPalError(domain.transaction, 25, 'Current operation not supported'),
  captureValidationFailed: payPalError(domain.transaction, 26, 'Validation failed for payment capture'),
  authRetrieveValidationFailed: payPalError(domain.transaction, 27, 'Validation failed for retrieving list of authorized transactions'),
  invalidInvoiceItem: payPalError(domain.transaction, 28, 'Not allowed to have an invalid item in the invoice item list')
};

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.'),
  invalidMerchantUserInfo: payPalError(domain.merchant, 7, 'Failed to load required merchant user information'),
  invalidMerchantStatusInfo: payPalError(domain.merchant, 8, 'Failed to load required merchant status information'),
  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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-paypalerror/build/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/debug.js":[function(require,module,exports){
'use strict';

var m = require('manticore');

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

},{"manticore":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore/browser.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/common/flowAsync.js","manticore-log":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-log/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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;
    }
    if (err.code === _sdkErrors.network.networkOffline.code) {
      if (data.alert) {
        data.alert.dismiss();
      }
      this.completeTransaction(data, _PaymentErrorHandler2.default.action.abort);
      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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/common/Merchant.js","../common/TokenExpirationHandler":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/common/TokenExpirationHandler.js","../common/cal":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/common/cal.js","../common/flow":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/common/flow.js","../common/sdkErrors":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/common/sdkErrors.js","./PaymentErrorHandler":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/flows/PaymentErrorHandler.js","./messageHelper":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/flows/messageHelper.js","manticore-log":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-log/index.js","manticore-util":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-util/build/index.js","paypalrest-manticore":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypalrest-manticore/build/index.js","retail-payment-device":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/flows/CaptureHandler.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-unused-vars */
/**
 * @class
 */
var CaptureHandler = function () {
  function CaptureHandler() {
    _classCallCheck(this, CaptureHandler);
  }

  /**
   * To capture the authorization
   * @param {decimal} gratuityAmount
   * @param {string} signature
   */
  CaptureHandler.prototype.doCapture = function doCapture(gratuityAmount, signature) {};

  /**
   * To void the authorization
   */


  CaptureHandler.prototype.doVoid = function doVoid() {};

  return CaptureHandler;
}();

exports.default = CaptureHandler;

},{}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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', [function doCapture(flow) {
      if (context.captureHandler && context.type === _retailPaymentDevice.TransactionType.Auth) {
        context.captureHandler(flow);
      } else {
        flow.next();
      }
    }, 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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/flows/BaseTransactionFlow.js","./messageHelper":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/flows/messageHelper.js","./steps/FinalizePaymentStep":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/flows/steps/FinalizePaymentStep.js","./steps/MerchantTakePaymentStep":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/flows/steps/MerchantTakePaymentStep.js","./steps/ReceiptStep":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/flows/steps/ReceiptStep.js","./steps/RemoveCardStep":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/flows/steps/RemoveCardStep.js","./steps/SignatureStep":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/flows/steps/SignatureStep.js","./steps/UpdateInvoicePaymentStep":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/flows/steps/UpdateInvoicePaymentStep.js","manticore-log":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-log/index.js","retail-payment-device":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/common/flow.js","./steps/ReceiptStep":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/flows/steps/ReceiptStep.js","manticore-log":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-log/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/common/TokenExpirationHandler.js","../common/flow":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/common/flow.js","../common/l10n":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/common/l10n.js","../common/retailSDKUtil":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/common/retailSDKUtil.js","./messageHelper":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/flows/messageHelper.js","./steps/ReceiptStep":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/flows/steps/ReceiptStep.js","manticore-log":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-log/index.js","manticore-util":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-util/build/index.js","paypalrest-manticore":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypalrest-manticore/build/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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) {
      if (_this.context.charityEnabled) {
        cb(action.abort);
      } else {
        _this._nfcPaymentDeclineErrorHandler(pd, function (performAction) {
          if (performAction === PaymentErrorHandler.action.retryWithInsertOrSwipe) {
            cb(performAction);
          } else {
            cb(action.offlineDecline);
          }
        });
      }
    }, _nfcHandlersForDevice[_retailPaymentDevice.deviceError.tryDifferentCard.code] = function (pd, cb) {
      if (_this.context.charityEnabled) {
        cb(action.abort);
      } else {
        _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) {
      if (_this.context.charityEnabled) {
        cb(action.abort);
      } else {
        _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) {
      if (_this.context.charityEnabled) {
        cb(PaymentErrorHandler.action.abort);
      } else {
        _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) {
    if (this.context.charityEnabled) {
      cb(action);
      return;
    }

    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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/common/Merchant.js","../common/l10n":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/common/l10n.js","../common/sdkErrors":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/common/sdkErrors.js","../transaction/transactionStates":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/transaction/transactionStates.js","./messageHelper":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/flows/messageHelper.js","manticore":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore/browser.js","manticore-log":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-log/index.js","manticore-util":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-util/build/index.js","retail-payment-device":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/flows/BaseTransactionFlow.js","./messageHelper":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/flows/messageHelper.js","./steps/MerchantTakePaymentStep":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/flows/steps/MerchantTakePaymentStep.js","./steps/ReceiptStep":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/flows/steps/ReceiptStep.js","./steps/UpdateInvoicePaymentStep":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/flows/steps/UpdateInvoicePaymentStep.js","manticore-log":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-log/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/flows/BaseTransactionFlow.js","./messageHelper":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/flows/messageHelper.js","./steps/FinalizePaymentStep":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/flows/steps/FinalizePaymentStep.js","./steps/MerchantTakePaymentStep":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/flows/steps/MerchantTakePaymentStep.js","./steps/QuickChipStep":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/flows/steps/QuickChipStep.js","./steps/ReceiptStep":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/flows/steps/ReceiptStep.js","./steps/SignatureStep":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/flows/steps/SignatureStep.js","./steps/UpdateInvoicePaymentStep":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/flows/steps/UpdateInvoicePaymentStep.js","manticore-log":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-log/index.js","retail-payment-device":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/common/l10n.js","./BaseFlowAsync":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/flows/BaseFlowAsync.js","manticore":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore/browser.js","manticore-log":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-log/index.js","retail-payment-device":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/common/l10n.js","../common/retailSDKUtil":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/common/retailSDKUtil.js","manticore":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore/browser.js","retail-payment-device":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/flows/BaseTransactionFlow.js","./messageHelper":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/flows/messageHelper.js","./steps/CheckRefundEligibilityStep":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/flows/steps/CheckRefundEligibilityStep.js","./steps/IssueRefundStep":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/flows/steps/IssueRefundStep.js","./steps/ReceiptStep":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/flows/steps/ReceiptStep.js","./steps/RemoveCardStep":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/flows/steps/RemoveCardStep.js","./steps/UpdateInvoicePaymentStep":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/flows/steps/UpdateInvoicePaymentStep.js","manticore-log":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-log/index.js","retail-payment-device":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/common/Merchant.js","../../common/retailSDKUtil":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/common/retailSDKUtil.js","../../common/sdkErrors":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/common/sdkErrors.js","./FlowStep":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/flows/steps/FlowStep.js","manticore-log":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-log/index.js","moment":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/moment/moment.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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;
      }

      // During the auth flow the MFT response doesn't have the payer info. It only comes as part of MTP response.
      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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/common/Merchant.js","../../common/sdkErrors":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/common/sdkErrors.js","./FlowStep":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/flows/steps/FlowStep.js","manticore-log":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-log/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/common/Merchant.js","../../common/l10n":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/common/l10n.js","../../common/sdkErrors":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/common/sdkErrors.js","../../transaction/TransactionRecord":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/transaction/TransactionRecord.js","./FlowStep":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/flows/steps/FlowStep.js","manticore-log":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-log/index.js","paypal-invoicing":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypal-invoicing/build/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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;
      if (err && err.code && err.code === _sdkErrors.network.networkOffline.code) {
        mtpError = _sdkErrors.network.networkOffline;
      }
      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(),
        postalCode: this.instrument.getPostalCode()
      };
    }
    return request;
  };

  return MerchantTakePaymentStep;
}(_FlowStep3.default);

exports.default = MerchantTakePaymentStep;

},{"../../common/Merchant":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/common/Merchant.js","../../common/retailSDKUtil":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/common/retailSDKUtil.js","../../common/sdkErrors":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/common/sdkErrors.js","../../transaction/PaymentType":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/transaction/PaymentType.js","../../transaction/TransactionRecord":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/transaction/TransactionRecord.js","./FlowStep":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/flows/steps/FlowStep.js","manticore":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore/browser.js","manticore-log":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-log/index.js","manticore-util":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-util/build/index.js","moment":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/moment/moment.js","retail-payment-device":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/flows/messageHelper.js","./FlowStep":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/flows/steps/FlowStep.js","manticore-log":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-log/index.js","retail-payment-device":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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 (!flow.data.tx) {
      Log.error('Lost me transaction data!');
    }

    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);

    Log.debug('Logging viewContent');
    Log.debug(JSON.stringify(flow.data, null, 4));
    Log.debug(JSON.stringify(viewContent, null, 4));

    if (this.context.skipReceipt) {
      flow.next();
      return;
    }

    _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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/common/Merchant.js","../../common/l10n":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/common/l10n.js","../../common/retailSDKUtil":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/common/retailSDKUtil.js","../../transaction/ReceiptDestination":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/transaction/ReceiptDestination.js","../../transaction/ReceiptViewContent":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/transaction/ReceiptViewContent.js","./FlowStep":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/flows/steps/FlowStep.js","manticore":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore/browser.js","manticore-log":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-log/index.js","retail-page-tracker":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-page-tracker/build/index.js","retail-payment-device":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/flows/messageHelper.js","./FlowStep":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/flows/steps/FlowStep.js","retail-payment-device":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/transaction/SignatureReceiver.js","../../transaction/transactionEvent":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/transaction/transactionEvent.js","../messageHelper":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/flows/messageHelper.js","./FlowStep":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/flows/steps/FlowStep.js","manticore-log":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-log/index.js","retail-payment-device":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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);
      if (flow.data.tx) {
        flow.data.tx.paymentMethod = stubPayment.method;
      }
      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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/common/retailSDKUtil.js","./FlowStep":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/flows/steps/FlowStep.js","moment":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/moment/moment.js","paypal-invoicing":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypal-invoicing/build/index.js","retail-payment-device":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/index.js":[function(require,module,exports){
(function (global){
'use strict';

/* eslint-disable global-require */

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');
}

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(require('paypal-invoicing'));
  m.export(require('manticore-paypalerror'));
  m.export(require('./common/RetailInvoice'));
  m.export(require('./common/NetworkHandler/NetworkResponse'));
  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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/common/NetworkHandler/NetworkResponse.js","./common/RetailInvoice":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/common/RetailInvoice.js","./common/SdkEnvironmentInfo":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/common/SdkEnvironmentInfo.js","./paymentDevice/index":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/paymentDevice/index.js","./sdk":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/sdk.js","./transaction/index":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/transaction/index.js","babel-regenerator-runtime":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/babel-regenerator-runtime/runtime.js","core-js/es6/set":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/es6/set.js","core-js/es6/symbol":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/es6/symbol.js","core-js/fn/array/find":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/fn/array/find.js","core-js/fn/array/find-index":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/fn/array/find-index.js","core-js/fn/array/from":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/fn/array/from.js","core-js/fn/array/of":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/fn/array/of.js","core-js/fn/object/is":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/fn/object/is.js","core-js/fn/string/includes":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/fn/string/includes.js","core-js/fn/symbol/iterator":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/fn/symbol/iterator.js","manticore":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore/browser.js","manticore-log":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-log/index.js","manticore-paypalerror":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-paypalerror/build/index.js","paypal-invoicing":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypal-invoicing/build/index.js","retail-payment-device":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/index.js","yaku":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/yaku/lib/yaku.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/buffer/index.js","manticore-log":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-log/index.js","retail-payment-device":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/flows/BaseFlowAsync.js","./SoftwareUpdate/IngenicoDeviceUpdate":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/ingenico-emv/SoftwareUpdate/IngenicoDeviceUpdate.js","async":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/async/lib/async.js","buffer":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/buffer/index.js","manticore-log":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-log/index.js","manticore-util":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-util/build/index.js","retail-payment-device":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/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 || context.type === _retailPaymentDevice.TransactionType.Auth ? 0 : 20;

      var handleResponse = function handleResponse(err, response) {
        if (err && (context.type === _retailPaymentDevice.TransactionType.Sale || context.type === _retailPaymentDevice.TransactionType.Auth || 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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/common/sdkErrors.js","./CardStatus":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/ingenico-emv/CardStatus.js","./ConnectionFlow":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/ingenico-emv/ConnectionFlow.js","./Terminal":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/ingenico-emv/Terminal.js","./eventType":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/ingenico-emv/eventType.js","./ingenicoReaderError":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/ingenico-emv/ingenicoReaderError.js","manticore-log":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-log/index.js","manticore-util":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-util/build/index.js","retail-payment-device":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/tlvlib/build/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/ingenico-emv/TransactionDataResponse.js","buffer":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/buffer/index.js","manticore-log":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-log/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/common/flow.js","../../common/retailSDKUtil":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/common/retailSDKUtil.js","async":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/async/lib/async.js","manticore":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore/browser.js","manticore-log":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-log/index.js","manticore-util":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-util/build/index.js","moment":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/moment/moment.js","retail-payment-device":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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;

    if (!ffSet.size) {
      Log.warn('startTransaction command invoked with empty form factors list. Will default to Chip & Swipe to avoid transaction cancels');
      ffSet.add(_retailPaymentDevice.FormFactor.MagneticCardSwipe);
      ffSet.add(_retailPaymentDevice.FormFactor.Chip);
    }

    // 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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/ingenico-emv/IngenicoCommand.js","./IngenicoTags":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/ingenico-emv/IngenicoTags.js","./Parser":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/ingenico-emv/Parser.js","./Writer":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/ingenico-emv/Writer.js","./eventType":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/ingenico-emv/eventType.js","./ingenico_config.json":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/ingenico-emv/ingenico_config.json","async":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/async/lib/async.js","buffer":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/buffer/index.js","events":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/events/events.js","manticore":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore/browser.js","manticore-log":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-log/index.js","manticore-util":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-util/build/index.js","moment":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/moment/moment.js","paypal-invoicing":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypal-invoicing/build/index.js","retail-payment-device":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/index.js","tlvlib":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/tlvlib/build/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-log/index.js","retail-payment-device":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/index.js","tlvlib":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/tlvlib/build/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/ingenico-emv/IngenicoCommand.js","events":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/events/events.js","machina":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/machina/lib/machina.js","manticore":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore/browser.js","manticore-log":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-log/index.js","retail-payment-device":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/ingenico-emv/IngenicoDevice.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-log/index.js","retail-payment-device":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/events/events.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/common/Merchant.js","../common/l10n":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/common/l10n.js","../common/retailSDKUtil":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/common/retailSDKUtil.js","../common/sdkErrors":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/common/sdkErrors.js","../ingenico-emv/IngenicoDevice":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/ingenico-emv/IngenicoDevice.js","./RoamSwiperDevice":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/paymentDevice/RoamSwiperDevice.js","manticore":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore/browser.js","manticore-log":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-log/index.js","miura-emv":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/build/index.js","retail-payment-device":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/common/l10n.js","../common/retailSDKUtil":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/common/retailSDKUtil.js","../transaction/DeviceManager":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/transaction/DeviceManager.js","./DeviceConnectorOptions":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/paymentDevice/DeviceConnectorOptions.js","manticore":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore/browser.js","manticore-log":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-log/index.js","retail-payment-device":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/events/events.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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();

    if (cb) {
      Log.debug(function () {
        return 'searchAndConnect with a new a callback.';
      });
      this._searchAndConnectCallback = cb;
    } else {
      Log.debug('searchAndConnect without a callback. Using previous callback');
    }

    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) {
          // setTimeout to ensure that we invoke this callback asynchronously if createAndConnect returns immediately
          _manticore2.default.setTimeout(function () {
            _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);
            _this5._invokeSearchAndConnectCallback(null, pd);
          }, 0);
        });
      };

      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);
          _this5._invokeSearchAndConnectCallback(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;
          }
        }

        _this5._invokeSearchAndConnectCallback(_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(_this5._searchAndConnectCallback);
      } 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._invokeSearchAndConnectCallback = function _invokeSearchAndConnectCallback(error, pd) {
    if (this._searchAndConnectCallback) {
      this._searchAndConnectCallback(error, pd);
      this._searchAndConnectCallback = null;
    }
  };

  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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/common/l10n.js","../common/retailSDKUtil":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/common/retailSDKUtil.js","../common/sdkErrors":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/common/sdkErrors.js","./CardReaderScanAndDiscoverOptions":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/paymentDevice/CardReaderScanAndDiscoverOptions.js","./DeviceConnector":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/paymentDevice/DeviceConnector.js","./DiscoveredCardReader":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/paymentDevice/DiscoveredCardReader.js","events":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/events/events.js","manticore":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore/browser.js","manticore-log":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-log/index.js","retail-payment-device":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/paymentDevice/CardReaderDisplayController.js","./displayPriority":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/paymentDevice/displayPriority.js","manticore":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore/browser.js","manticore-log":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-log/index.js","retail-payment-device":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/buffer/index.js","manticore-log":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-log/index.js","retail-payment-device":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-log/index.js","retail-payment-device":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/buffer/index.js","manticore-log":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-log/index.js","retail-payment-device":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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);
      if (!this.serialNumber && cardInfo.secureData && cardInfo.secureData.ksn && cardInfo.secureData.ksn.length > 6) {
        // if serialNumber does not exist, update it here using ksn.
        this.serialNumber = cardInfo.secureData.ksn.substring(0, cardInfo.secureData.ksn.length - 6);
      }
      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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/paymentDevice/RoamSwiper/CardStatus.js","./RoamSwiper/Parser":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/paymentDevice/RoamSwiper/Parser.js","manticore-log":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-log/index.js","retail-payment-device":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/ingenico-emv/index.js","./CardReaderScanAndDiscoverOptions":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/paymentDevice/CardReaderScanAndDiscoverOptions.js","./DeviceBuilder":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/paymentDevice/DeviceBuilder.js","./DeviceScanner":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/paymentDevice/DeviceScanner.js","./DiscoveredCardReader":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/paymentDevice/DiscoveredCardReader.js","./MagtekRawUsbReaderDevice":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/paymentDevice/MagtekRawUsbReaderDevice.js","./RoamSwiperDevice":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/paymentDevice/RoamSwiperDevice.js","miura-emv":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/build/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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);
  };

  /**
   * SDK Version
   * @returns {string} version
   */


  SDK.prototype.getSdkVersion = function getSdkVersion() {
    return _package2.default.version;
  };

  /*
   * 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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/package.json","./common/Features":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/common/Features.js","./common/Merchant":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/common/Merchant.js","./common/NetworkHandler/networkInterceptor":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/common/NetworkHandler/networkInterceptor.js","./common/cal":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/common/cal.js","./common/logLevel":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/common/logLevel.js","./common/sdkErrors":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/common/sdkErrors.js","./paymentDevice/CardReaderDisplayController":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/paymentDevice/CardReaderDisplayController.js","./transaction/DeviceManager":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/transaction/DeviceManager.js","./transaction/TransactionContext":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/transaction/TransactionContext.js","./transaction/TransactionManager":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/transaction/TransactionManager.js","buffer":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/buffer/index.js","events":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/events/events.js","manticore":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore/browser.js","manticore-log":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-log/index.js","retail-page-tracker":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-page-tracker/build/index.js","retail-payment-device":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/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 () {
  /**
   * Create an authorized transaction
   * @constructor
   * @param {string} authorizationId the authorizationId to be captured.
   * @param {string} invoiceId the invoice id associated with the authorization.
   * @param {string} currency the currency in which authorization was placed.
   */
  function AuthorizedTransaction(authorizationId, invoiceId, currency) {
    _classCallCheck(this, AuthorizedTransaction);

    this.authorizationId = authorizationId;
    this.invoiceId = invoiceId;
    this.currency = currency;
  }

  AuthorizedTransaction.fromJSON = function fromJSON(response) {
    var auth = new AuthorizedTransaction(response.id, response.extension.invoice_number, response.gross.currency_code);
    auth.timeCreated = (0, _moment2.default)(response.time_created).toDate();
    auth.authorizedAmount = (0, _paypalInvoicing.$$)(response.gross.value);
    auth.status = response.status;
    return auth;
  };

  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, null, callback);
  };

  /**
   * Capture this authorized transaction
   * @nativeName captureTransaction
   * @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} base64SignatureJpeg The signature as a base64 encoded JPEG image. Try to keep it under 100k
   * @param {AuthorizedTransaction~captureComplete} callback
   */


  AuthorizedTransaction.prototype.captureTransactionWithSig = function captureTransactionWithSig(totalAmount, gratuityAmount, base64SignatureJpeg, callback) {
    (0, _captureManager2.default)(this.authorizationId, this.invoiceId, totalAmount, gratuityAmount, this.currency, base64SignatureJpeg, 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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/transaction/captureManager.js","./voidManager":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/transaction/voidManager.js","moment":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/moment/moment.js","paypal-invoicing":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypal-invoicing/build/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/common/l10n.js","../common/retailSDKUtil":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/common/retailSDKUtil.js","../common/sdkErrors":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/common/sdkErrors.js","../flows/PaymentErrorHandler":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/flows/PaymentErrorHandler.js","../flows/messageHelper":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/flows/messageHelper.js","./transactionEvent":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/transaction/transactionEvent.js","manticore":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore/browser.js","manticore-log":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-log/index.js","manticore-util":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-util/build/index.js","retail-payment-device":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/index.js","tlvlib":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/tlvlib/build/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/common/Merchant.js","../common/retailSDKUtil":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/common/retailSDKUtil.js","../common/sdkErrors":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/common/sdkErrors.js","../flows/messageHelper":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/flows/messageHelper.js","../paymentDevice/DeviceSelector":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/paymentDevice/DeviceSelector.js","./CardPresentedHandler":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/transaction/CardPresentedHandler.js","./InvoiceSynchronizer":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/transaction/InvoiceSynchronizer.js","events":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/events/events.js","manticore-log":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-log/index.js","manticore-util":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-util/build/index.js","paypal-invoicing":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypal-invoicing/build/index.js","retail-payment-device":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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 if (callback) {
      callback(_sdkErrors.sdk.cardReaderScannerNotInitialized, null);
    }
  };

  /**
   * Show a list of connected credit card readers.
   * If there is more than 1 devices. Select one of them to use it
   * for transaction.
   */


  DeviceManager.prototype.searchAndConnectWithoutCallback = function searchAndConnectWithoutCallback() {
    this.searchAndConnect(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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/common/sdkErrors.js","../paymentDevice/DeviceConnector":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/paymentDevice/DeviceConnector.js","../paymentDevice/DeviceScanner":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/paymentDevice/DeviceScanner.js","../paymentDevice/DeviceSelector":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/paymentDevice/DeviceSelector.js","manticore-log":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-log/index.js","retail-payment-device":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/common/retailSDKUtil.js","../paymentDevice/CardReaderDisplayController":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/paymentDevice/CardReaderDisplayController.js","../paymentDevice/displayPriority":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/paymentDevice/displayPriority.js","./transactionEvent":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/transaction/transactionEvent.js","events":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/events/events.js","manticore":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore/browser.js","manticore-log":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-log/index.js","paypal-invoicing":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypal-invoicing/build/index.js","retail-payment-device":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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 @readonly
 * @property {string} receiptPreferenceToken A token used to send receipts and save/use previously used email address or phone number @readonly
 * @property {string} maskedEmail An email address previously used for this payment instrument, with portions masked for privacy @readonly
 * @property {string} maskedPhone A masked phone number previously used for this payment instrument @readonly
 */
var Payer = function Payer(response) {
  _classCallCheck(this, Payer);

  if (response) {
    util.assignSome(this, response, ['customerId', 'receiptPreferenceToken', 'maskedEmail', 'maskedPhone']);
  }
};

exports.default = Payer;

},{"manticore-util":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-util/build/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/common/l10n.js","../common/retailSDKUtil":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/common/retailSDKUtil.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/common/l10n.js","../common/sdkErrors":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/common/sdkErrors.js","../flows/messageHelper":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/flows/messageHelper.js","../transaction/transactionEvent":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/transaction/transactionEvent.js","events":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/events/events.js","manticore":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore/browser.js","retail-page-tracker":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-page-tracker/build/index.js","retail-payment-device":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/transaction/TransactionBeginOptions.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"); } }

/**
 * 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 {string} tag Reserved for restricted use
 */
var TransactionBeginOptions = function () {
  /**
   * Create transaction options object
   * @constructor
   */
  function TransactionBeginOptions() {
    _classCallCheck(this, TransactionBeginOptions);

    this.showPromptInCardReader = true;
    this.showPromptInApp = true;
    this.quickChipEnabled = false;
  }

  TransactionBeginOptions.prototype.toJSON = function toJSON() {
    return {
      showPromptInCardReader: this.showPromptInCardReader,
      showPromptInApp: this.showPromptInApp,
      preferredFormFactors: this.preferredFormFactors,
      tippingOnReaderEnabled: this.tippingOnReaderEnabled,
      amountBasedTipping: this.amountBasedTipping,
      isAuthCapture: this.isAuthCapture,
      tag: this.tag
    };
  };

  TransactionBeginOptions.prototype.toString = function toString() {
    return JSON.stringify(this);
  };

  _createClass(TransactionBeginOptions, [{
    key: 'charityEnabled',
    get: function get() {
      return this.tag && this.tag.includes('charityEnabled');
    }
  }, {
    key: 'skipReceipt',
    get: function get() {
      return this.tag && this.tag.includes('skipReceipt');
    }
  }, {
    key: 'showReceiptForAuth',
    get: function get() {
      return this.tag && this.tag.includes('showReceiptForAuth');
    }
  }]);

  return TransactionBeginOptions;
}();

exports.default = TransactionBeginOptions;

},{}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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');

var _CaptureHandler = require('../flows/CaptureHandler');

var _CaptureHandler2 = _interopRequireDefault(_CaptureHandler);

var _captureManager = require('./captureManager');

var _captureManager2 = _interopRequireDefault(_captureManager);

var _voidManager = require('./voidManager');

var _voidManager2 = _interopRequireDefault(_voidManager);

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.getTransactionManager().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 (enable on-reader tipping
 * , specify transaction options, etc). When you're ready to proceed with the payment flow,
 * call beginPayment()
 * @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 {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 payment 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;

    if (!this._isInvoiceItemValid()) {
      this.end(_sdkErrors.transaction.invalidInvoiceItem);
      return this;
    }
    // TODO - Remove me after AUTH/CAPTURE is certified for UK & AU
    if (options.isAuthCapture && _Merchant2.default.active.country !== 'US') {
      this.end(_sdkErrors.transaction.notSupported.withDevMessage('Auth/Capture not supported for merchant country \'' + _Merchant2.default.active.country + '\''));
      return 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.type !== _retailPaymentDevice.TransactionType.Auth) {
      this.end(_sdkErrors.transaction.invoiceStatusMismatch);
      return this;
    }

    if (options.isAuthCapture) {
      this.type = _retailPaymentDevice.TransactionType.Auth;
    } else {
      this.type = _retailPaymentDevice.TransactionType.Sale;
    }

    // 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);
    this.paymentOptions = options;
    if (!options.tippingOnReaderEnabled && this.isInvoiceAmountInvalidForCardReaderTransaction()) {
      options.showPromptInCardReader = false;
      options.showPromptInApp = false;
      if (!this.charityEnabled) {
        options.preferredFormFactors = [_retailPaymentDevice.FormFactor.MagneticCardSwipe, _retailPaymentDevice.FormFactor.Chip];
      }
    }

    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;
          if (!_this4.charityEnabled) {
            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: this.deviceController.getApprovedFormFactors(options.preferredFormFactors)
      });
    }

    return this;
  };

  TransactionContext.prototype._isInvoiceItemValid = function _isInvoiceItemValid() {
    for (var _iterator = this.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 item = _ref;

      if (item.unitPrice < 0 || item.taxRate < 0 || item.quantity < 0) {
        Log.error('Invoice item has negative value: ' + JSON.stringify(item, null, 4));
        return false;
      }
    }
    return true;
  };

  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) {
    return this.beginRefundWithTag(cardPresent, amount);
  };

  /**
   * Begin the flow to issue a refund on the current invoice.
   * @nativeName beginRefund
   * @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
   * @param {string} refundTag Reserved for restricted use
   * @returns {TransactionContext} Returns this object just to make chaining easier
   */


  TransactionContext.prototype.beginRefundWithTag = function beginRefundWithTag(cardPresent, amount, refundTag) {
    var _this6 = this;

    if (this.type !== _retailPaymentDevice.TransactionType.Refund) {
      this.end(_sdkErrors.transaction.invoiceStatusMismatch);
      return this;
    }

    this.refundSkipReceipt = refundTag && refundTag.includes('skipReceipt');

    _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 (_isArray2) {
        if (_i2 >= _iterator2.length) return 'break';
        _ref2 = _iterator2[_i2++];
      } else {
        _i2 = _iterator2.next();
        if (_i2.done) return 'break';
        _ref2 = _i2.value;
      }

      var ff = _ref2;

      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 _iterator2 = preferredFormFactors, _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) {
      var _ref2;

      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 currency=' + this.invoice.currency + ', total=' + this.invoice.total + ', 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
   * @private
   * @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
   */


  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) {
        if (!_this9.skipReceipt) {
          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 _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;

        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('Completed transaction for paymentFailedAmountIn' + this.invoice.currency + ' \'' + this.invoice.total + '\', error:' + JSON.stringify(error) + ' ' + this.id + ', charityEnabled: ' + this.charityEnabled + ', skipReceipt: ' + this.skipReceipt + ', isRefund: ' + this.isRefund());
    } else {
      Log.info('Successfully completed transaction for paymentAmountIn' + this.invoice.currency + ' \'' + this.invoice.total + '\', activeDevices:' + this.deviceController.activeDevices.size + ', charityEnabled: ' + this.charityEnabled + ', skipReceipt: ' + this.skipReceipt + ', isRefund: ' + this.isRefund());
    }
    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 or 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 (_isArray4) {
        if (_i4 >= _iterator4.length) return 'break';
        _ref4 = _iterator4[_i4++];
      } else {
        _i4 = _iterator4.next();
        if (_i4.done) return 'break';
        _ref4 = _i4.value;
      }

      var listener = _ref4;

      Log.debug(function () {
        return '   ' + _this14.id + ' Emitting to \'' + listener.id + '\' listener';
      });
    };

    for (var _iterator4 = this.listeners(eventName), _isArray4 = Array.isArray(_iterator4), _i4 = 0, _iterator4 = _isArray4 ? _iterator4 : _iterator4[Symbol.iterator]();;) {
      var _ref4;

      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 _iterator5 = this.listeners(event), _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 l = _ref5;

          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) {
      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;
      initializationForFlow();
      var _CCFlow = require('./../flows/CreditCardFlow').default; // eslint-disable-line global-require
      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;
    });
  };

  /**
   * @param {TransactionContext~onAuthComplete} captureHandler
   */


  TransactionContext.prototype.setCaptureHandler = function setCaptureHandler(onAuthComplete) {
    var _this26 = this;

    if (!onAuthComplete) {
      this.captureHandler = null;
      return;
    }
    var handler = function handler(flow) {
      Log.debug(function () {
        return 'Invoking capture handler ' + handler.id + ' for ' + _this26.id;
      });
      var invoice = _this26.invoice;
      var txRecord = flow.data.tx;
      var voidAuth = function voidAuth(flowVoidAuth) {
        (0, _voidManager2.default)(txRecord.transactionNumber, function () {
          flowVoidAuth.next();
        });
      };
      var captureHandler = new _CaptureHandler2.default();
      captureHandler.doCapture = function (gratuityAmount, signature) {
        messageHelper.showSimpleMessage((0, _l10n2.default)('EMV.Processing'), null, true, flow.data);
        var cb = function cb(error, captureId) {
          if (error) {
            flow.data.error = error;
            voidAuth(flow);
          } else {
            flow.data.tx.captureId = captureId;
            flow.next();
          }
        };
        Log.debug('doCapture called');
        (0, _captureManager2.default)(txRecord.transactionNumber, txRecord.invoiceId, invoice.total, gratuityAmount, invoice.currency, signature, cb);
      };
      captureHandler.doVoid = function () {
        Log.debug('doVoid called');
        // Manually adding the error codes so that the UpdateInvoicePaymentStep treats this as txn being cancelled.
        flow.data.error = flow.data.error || {};
        flow.data.error.code = _sdkErrors.transaction.customerCancel.code;
        flow.data.error.domain = _sdkErrors.domain.transaction;
        voidAuth(flow);
      };
      onAuthComplete(flow.data.error, flow.data.error ? null : captureHandler, flow.data.error ? null : flow.data.tx);
    };

    handler.id = 'captureHandled-' + (0, _retailSDKUtil.getRandomId)();
    this.captureHandler = handler;
    Log.debug(function () {
      return 'Set capture handler to ' + handler.id + ' for ' + _this26.id;
    });
  };

  /**
   * Provide a handler to get notified when card was presented and emv/magstripe data was read.
   * TransactionContext.continueWithCard should be invoked to continue the payment
   * @param {TransactionContext~cardPresented} cardPresentedHandler
   */


  TransactionContext.prototype.setCardPresentedHandler = function setCardPresentedHandler(cardPresentedHandler) {
    var _this27 = this;

    if (!cardPresentedHandler) {
      this.cardPresentedHandler = null;
      return;
    }
    var handler = function handler(card) {
      Log.debug(function () {
        return 'Invoking card PRESENTED handler ' + handler.id + ' for ' + _this27.id;
      });
      cardPresentedHandler(card);
    };
    handler.id = 'cardPresented-' + (0, _retailSDKUtil.getRandomId)();
    this.cardPresentedHandler = handler;
    Log.debug(function () {
      return 'Set card presented handler to ' + handler.id + ' for ' + _this27.id;
    });
  };

  /**
   * Provide a handler to get notified once transaction is complete
   * @param {TransactionContext~transactionCompleted} completedHandler
   */


  TransactionContext.prototype.setCompletedHandler = function setCompletedHandler(completedHandler) {
    var _this28 = this;

    if (!completedHandler) {
      this.completedHandler = null;
      return;
    }
    var handler = function handler(err, txRecord) {
      Log.debug(function () {
        return 'Invoking COMPLETION handler ' + handler.id + ' for ' + _this28.id;
      });
      completedHandler(err, txRecord);
    };
    handler.id = 'completed-' + (0, _retailSDKUtil.getRandomId)();
    this.completedHandler = handler;
    Log.debug(function () {
      return 'Set completed handler to ' + handler.id + ' for ' + _this28.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 _this29 = 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 ' + _this29.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 ' + _this29.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;
    }

    /**
     * check if charity flag is enabled in the payment options
     * @private
     */

  }, {
    key: 'charityEnabled',
    get: function get() {
      return this.paymentOptions && this.paymentOptions.charityEnabled;
    }

    /**
     * Check if Receipt should be sent for Authorization flow
     * @private
     */

  }, {
    key: 'skipReceiptForAuth',
    get: function get() {
      return this.type === _retailPaymentDevice.TransactionType.Auth && this.paymentOptions && !this.paymentOptions.showReceiptForAuth;
    }

    /**
     * check if skip receipt flag is enabled in the payment options
     * @private
     */

  }, {
    key: 'skipReceipt',
    get: function get() {
      var _this30 = this;

      var skip = this.charityEnabled || this.refundSkipReceipt || this.paymentOptions && this.paymentOptions.skipReceipt || this.skipReceiptForAuth;

      if (skip) {
        Log.debug(function () {
          return 'Skip receipt for transaction ' + _this30.id + '. charityEnabled: ' + _this30.charityEnabled + ' refundSkipReceipt: ' + _this30.refundSkipReceipt;
        });
      }
      return skip;
    }
  }]);

  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.
 */

/**
 * Indicates that the card data was read. 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
 */

/**
 * Called when EMV card inserted was detected. This occurs before card data read.
 * @callback TransactionContext~cardInsertedHandler
 * @param {CardInsertedHandler} cardInsertedHandler Call continue to read EMV data from inserted chip card
 */

/**
 * @callback TransactionContext~onAuthComplete
 * @param {error} Error if any
 * @param {CaptureHandler} captureHandler doCapture to capture, doVoid to void
 * @param {TransactionRecord} record The transaction record for successful transactions
 *  and failed transactions that reached PayPal. @readonly
 */

/**
 * 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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/common/Merchant.js","../common/l10n":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/common/l10n.js","../common/retailSDKUtil":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/common/retailSDKUtil.js","../common/sdkErrors":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/common/sdkErrors.js","../flows/CaptureHandler":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/flows/CaptureHandler.js","../flows/OfferReceiptFlow":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/flows/OfferReceiptFlow.js","../flows/OfflineDeclineFlow":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/flows/OfflineDeclineFlow.js","../flows/PaymentErrorHandler":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/flows/PaymentErrorHandler.js","../flows/messageHelper":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/flows/messageHelper.js","../paymentDevice/DeviceSelector":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/paymentDevice/DeviceSelector.js","./../flows/CreditCardFlow":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/flows/CreditCardFlow.js","./../flows/PaymentFlow":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/flows/PaymentFlow.js","./../flows/QuickChipCreditCardFlow":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/flows/QuickChipCreditCardFlow.js","./../flows/ReaderTippingFlow":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/flows/ReaderTippingFlow.js","./../flows/refundFlow":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/flows/refundFlow.js","./DeviceController":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/transaction/DeviceController.js","./PaymentType":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/transaction/PaymentType.js","./TransactionStateManager":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/transaction/TransactionStateManager.js","./captureManager":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/transaction/captureManager.js","./transactionEvent":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/transaction/transactionEvent.js","./transactionStates":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/transaction/transactionStates.js","./voidManager":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/transaction/voidManager.js","async":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/async/lib/async.js","events":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/events/events.js","manticore":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore/browser.js","manticore-log":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-log/index.js","manticore-util":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-util/build/index.js","paypal-invoicing":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypal-invoicing/build/index.js","retail-page-tracker":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-page-tracker/build/index.js","retail-payment-device":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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 _AuthorizedTransaction = require('./AuthorizedTransaction');

var _AuthorizedTransaction2 = _interopRequireDefault(_AuthorizedTransaction);

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.'), null);
      return;
    }

    var auth = new _AuthorizedTransaction2.default(authorizationId, invoiceId, currency);
    auth.captureTransaction(totalAmount, gratuityAmount, callback);
  };

  /**
   * Capture a previously authorized transaction.
   * @nativeName captureAuthorization
   * @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 {string} base64SignatureJpeg The signature as a base64 encoded JPEG image. Try to keep it under 100k
   * @param {TransactionManager~captureAuthorizedTransaction} callback
   */


  TransactionManager.prototype.captureAuthorizationWithSig = function captureAuthorizationWithSig(authorizationId, invoiceId, totalAmount, gratuityAmount, currency, base64SignatureJpeg, 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);
      return;
    }

    var auth = new _AuthorizedTransaction2.default(authorizationId, invoiceId, currency);
    auth.captureTransactionWithSig(totalAmount, gratuityAmount, base64SignatureJpeg, 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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/common/Merchant.js","../common/RetailInvoice":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/common/RetailInvoice.js","../common/sdkErrors":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/common/sdkErrors.js","./AuthorizedTransaction":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/transaction/AuthorizedTransaction.js","./TransactionContext":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/transaction/TransactionContext.js","./authManager":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/transaction/authManager.js","./voidManager":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/transaction/voidManager.js","manticore-log":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-log/index.js","paypal-invoicing":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypal-invoicing/build/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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 _lodash = require('lodash');

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 {Invoice.PaymentMethod} paymentMethod The payment method used for this payment
 * @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
 * @property {string} captureId The reference id for the captured authorization @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 (!_lodash._.isEmpty(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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/transaction/Payer.js","./ReceiptDestination":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/transaction/ReceiptDestination.js","lodash":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/lodash/index.js","manticore-util":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-util/build/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/paymentDevice/DeviceSelector.js","./transactionStates":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/transaction/transactionStates.js","manticore-log":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-log/index.js","manticore-util":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-util/build/index.js","retail-payment-device":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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.transaction.authRetrieveValidationFailed;
      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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/common/retailSDKUtil.js","../common/sdkErrors":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/common/sdkErrors.js","./AuthStatus":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/transaction/AuthStatus.js","./authorizedTransactionsRetriever":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/transaction/authorizedTransactionsRetriever.js","manticore-log":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-log/index.js","moment":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/moment/moment.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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 = _AuthorizedTransaction2.default.fromJSON(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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/common/Merchant.js","../common/sdkErrors":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/common/sdkErrors.js","./AuthorizedTransaction":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/transaction/AuthorizedTransaction.js","manticore-log":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-log/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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, signature, 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.transaction.captureValidationFailed;
    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
  };

  if (gratuityAmount) {
    requestBody.gratuity = {
      currency: currency,
      value: gratuityAmountInDecimal.toFixed(2)
    };
  }

  if (signature) {
    requestBody.signature = signature;
  }

  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), null);
    } else {
      Log.info('Successfully captured auth id: ' + authorizationId + '. Response: ' + JSON.stringify(response, null, 4));
      callback(null, response.body.id);
    }
  });
}

},{"../common/Merchant":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/common/Merchant.js","../common/sdkErrors":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/common/sdkErrors.js","manticore-log":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-log/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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 _AuthorizedTransaction = require('./AuthorizedTransaction');

var _AuthorizedTransaction2 = _interopRequireDefault(_AuthorizedTransaction);

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,
  AuthorizedTransaction: _AuthorizedTransaction2.default
};

},{"./AuthorizedTransaction":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/transaction/AuthorizedTransaction.js","./Payer":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/transaction/Payer.js","./ReceiptDestination":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/transaction/ReceiptDestination.js","./TransactionBeginOptions":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/transaction/TransactionBeginOptions.js","./TransactionRecord":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/transaction/TransactionRecord.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/common/Merchant.js","../common/sdkErrors":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/common/sdkErrors.js","manticore-log":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-log/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/util/util.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/process/browser.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/process/browser.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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
}

// Support decoding URL-safe base64 strings, as Node.js does.
// See: https://en.wikipedia.org/wiki/Base64#URL_applications
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) & 0xFF0000) + ((uint8[i + 1] << 8) & 0xFF00) + (uint8[i + 2] & 0xFF)
    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/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/base64-js/index.js","ieee754":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/ieee754/index.js","isarray":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/isarray/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_core.js","../modules/es6.object.to-string":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/es6.object.to-string.js","../modules/es6.set":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/es6.set.js","../modules/es6.string.iterator":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/es6.string.iterator.js","../modules/web.dom.iterable":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/web.dom.iterable.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_core.js","../modules/es6.object.to-string":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/es6.object.to-string.js","../modules/es6.symbol":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/es6.symbol.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_core.js","../../modules/es6.array.find-index":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/es6.array.find-index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_core.js","../../modules/es6.array.find":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/es6.array.find.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_core.js","../../modules/es6.array.from":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/es6.array.from.js","../../modules/es6.string.iterator":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/es6.string.iterator.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_core.js","../../modules/es6.array.of":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/es6.array.of.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_core.js","../../modules/es6.object.is":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/es6.object.is.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_core.js","../../modules/es6.string.includes":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/es6.string.includes.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_wks-ext.js","../../modules/es6.string.iterator":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/es6.string.iterator.js","../../modules/web.dom.iterable":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/web.dom.iterable.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_hide.js","./_wks":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_wks.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_is-object.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_to-absolute-index.js","./_to-iobject":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_to-iobject.js","./_to-length":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_to-length.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_array-species-create.js","./_ctx":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_ctx.js","./_iobject":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_iobject.js","./_to-length":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_to-length.js","./_to-object":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_to-object.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_is-array.js","./_is-object":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_is-object.js","./_wks":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_wks.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_array-species-constructor.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_cof.js","./_wks":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_wks.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_an-instance.js","./_ctx":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_ctx.js","./_descriptors":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_descriptors.js","./_for-of":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_for-of.js","./_iter-define":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_iter-define.js","./_iter-step":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_iter-step.js","./_meta":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_meta.js","./_object-create":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_object-create.js","./_object-dp":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_object-dp.js","./_redefine-all":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_redefine-all.js","./_set-species":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_set-species.js","./_validate-collection":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_validate-collection.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_an-instance.js","./_export":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_export.js","./_fails":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_fails.js","./_for-of":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_for-of.js","./_global":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_global.js","./_inherit-if-required":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_inherit-if-required.js","./_is-object":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_is-object.js","./_iter-detect":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_iter-detect.js","./_meta":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_meta.js","./_redefine":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_redefine.js","./_redefine-all":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_redefine-all.js","./_set-to-string-tag":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_set-to-string-tag.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_core.js":[function(require,module,exports){
var core = module.exports = { version: '2.5.5' };
if (typeof __e == 'number') __e = core; // eslint-disable-line no-undef

},{}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_object-dp.js","./_property-desc":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_property-desc.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_a-function.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_fails.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_global.js","./_is-object":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_is-object.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_object-gops.js","./_object-keys":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_object-keys.js","./_object-pie":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_object-pie.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_core.js","./_ctx":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_ctx.js","./_global":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_global.js","./_hide":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_hide.js","./_redefine":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_redefine.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_wks.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_an-object.js","./_ctx":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_ctx.js","./_is-array-iter":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_is-array-iter.js","./_iter-call":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_iter-call.js","./_to-length":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_to-length.js","./core.get-iterator-method":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/core.get-iterator-method.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_descriptors.js","./_object-dp":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_object-dp.js","./_property-desc":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_property-desc.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_global.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_descriptors.js","./_dom-create":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_dom-create.js","./_fails":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_fails.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_is-object.js","./_set-proto":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_set-proto.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_cof.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_iterators.js","./_wks":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_wks.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_cof.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_cof.js","./_is-object":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_is-object.js","./_wks":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_wks.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_an-object.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_hide.js","./_object-create":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_object-create.js","./_property-desc":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_property-desc.js","./_set-to-string-tag":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_set-to-string-tag.js","./_wks":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_wks.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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 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 = $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 && typeof IteratorPrototype[ITERATOR] != 'function') 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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_export.js","./_hide":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_hide.js","./_iter-create":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_iter-create.js","./_iterators":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_iterators.js","./_library":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_library.js","./_object-gpo":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_object-gpo.js","./_redefine":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_redefine.js","./_set-to-string-tag":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_set-to-string-tag.js","./_wks":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_wks.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_wks.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_iterators.js":[function(require,module,exports){
module.exports = {};

},{}],"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_library.js":[function(require,module,exports){
module.exports = false;

},{}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_fails.js","./_has":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_has.js","./_is-object":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_is-object.js","./_object-dp":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_object-dp.js","./_uid":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_uid.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_an-object.js","./_dom-create":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_dom-create.js","./_enum-bug-keys":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_enum-bug-keys.js","./_html":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_html.js","./_object-dps":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_object-dps.js","./_shared-key":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_shared-key.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_an-object.js","./_descriptors":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_descriptors.js","./_ie8-dom-define":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_ie8-dom-define.js","./_to-primitive":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_to-primitive.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_an-object.js","./_descriptors":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_descriptors.js","./_object-dp":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_object-dp.js","./_object-keys":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_object-keys.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_descriptors.js","./_has":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_has.js","./_ie8-dom-define":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_ie8-dom-define.js","./_object-pie":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_object-pie.js","./_property-desc":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_property-desc.js","./_to-iobject":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_to-iobject.js","./_to-primitive":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_to-primitive.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_object-gopn.js","./_to-iobject":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_to-iobject.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_enum-bug-keys.js","./_object-keys-internal":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_object-keys-internal.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_object-gops.js":[function(require,module,exports){
exports.f = Object.getOwnPropertySymbols;

},{}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_has.js","./_shared-key":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_shared-key.js","./_to-object":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_to-object.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_array-includes.js","./_has":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_has.js","./_shared-key":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_shared-key.js","./_to-iobject":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_to-iobject.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_enum-bug-keys.js","./_object-keys-internal":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_object-keys-internal.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_object-pie.js":[function(require,module,exports){
exports.f = {}.propertyIsEnumerable;

},{}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_redefine.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_core.js","./_global":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_global.js","./_has":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_has.js","./_hide":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_hide.js","./_uid":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_uid.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_an-object.js","./_ctx":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_ctx.js","./_is-object":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_is-object.js","./_object-gopd":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_object-gopd.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_descriptors.js","./_global":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_global.js","./_object-dp":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_object-dp.js","./_wks":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_wks.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_has.js","./_object-dp":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_object-dp.js","./_wks":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_wks.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_shared.js","./_uid":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_uid.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_global.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_defined.js","./_to-integer":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_to-integer.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_defined.js","./_is-regexp":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_is-regexp.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_to-integer.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_defined.js","./_iobject":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_iobject.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_to-integer.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_defined.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_is-object.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_is-object.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_core.js","./_global":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_global.js","./_library":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_library.js","./_object-dp":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_object-dp.js","./_wks-ext":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_wks-ext.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_wks-ext.js":[function(require,module,exports){
exports.f = require('./_wks');

},{"./_wks":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_wks.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_global.js","./_shared":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_shared.js","./_uid":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_uid.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_classof.js","./_core":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_core.js","./_iterators":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_iterators.js","./_wks":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_wks.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_add-to-unscopables.js","./_array-methods":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_array-methods.js","./_export":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_export.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_add-to-unscopables.js","./_array-methods":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_array-methods.js","./_export":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_export.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_create-property.js","./_ctx":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_ctx.js","./_export":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_export.js","./_is-array-iter":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_is-array-iter.js","./_iter-call":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_iter-call.js","./_iter-detect":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_iter-detect.js","./_to-length":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_to-length.js","./_to-object":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_to-object.js","./core.get-iterator-method":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/core.get-iterator-method.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_add-to-unscopables.js","./_iter-define":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_iter-define.js","./_iter-step":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_iter-step.js","./_iterators":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_iterators.js","./_to-iobject":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_to-iobject.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_create-property.js","./_export":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_export.js","./_fails":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_fails.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_export.js","./_same-value":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_same-value.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_classof.js","./_redefine":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_redefine.js","./_wks":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_wks.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_collection.js","./_collection-strong":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_collection-strong.js","./_validate-collection":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_validate-collection.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_export.js","./_fails-is-regexp":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_fails-is-regexp.js","./_string-context":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_string-context.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_iter-define.js","./_string-at":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_string-at.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_an-object.js","./_descriptors":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_descriptors.js","./_enum-keys":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_enum-keys.js","./_export":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_export.js","./_fails":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_fails.js","./_global":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_global.js","./_has":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_has.js","./_hide":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_hide.js","./_is-array":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_is-array.js","./_is-object":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_is-object.js","./_library":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_library.js","./_meta":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_meta.js","./_object-create":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_object-create.js","./_object-dp":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_object-dp.js","./_object-gopd":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_object-gopd.js","./_object-gopn":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_object-gopn.js","./_object-gopn-ext":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_object-gopn-ext.js","./_object-gops":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_object-gops.js","./_object-keys":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_object-keys.js","./_object-pie":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_object-pie.js","./_property-desc":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_property-desc.js","./_redefine":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_redefine.js","./_set-to-string-tag":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_set-to-string-tag.js","./_shared":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_shared.js","./_to-iobject":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_to-iobject.js","./_to-primitive":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_to-primitive.js","./_uid":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_uid.js","./_wks":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_wks.js","./_wks-define":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_wks-define.js","./_wks-ext":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_wks-ext.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_global.js","./_hide":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_hide.js","./_iterators":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_iterators.js","./_object-keys":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_object-keys.js","./_redefine":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_redefine.js","./_wks":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/_wks.js","./es6.array.iterator":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/core-js/modules/es6.array.iterator.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/deep-equal/lib/is_arguments.js","./lib/keys.js":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/deep-equal/lib/keys.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/l10n-manticore/node_modules/es6-template-strings/compile.js","manticore-log":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-log/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/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.2
 *  * 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 ) );
			}.bind( 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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/lodash/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore/browser.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-paypalerror/build/src/PayPalError.js","./src/PayPalErrorInfo":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-paypalerror/build/src/PayPalErrorInfo.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore/browser.js":[function(require,module,exports){
module.exports = manticore;
},{}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/charenc/charenc.js","crypt":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/crypt/crypt.js","is-buffer":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/is-buffer/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/build/MiuraTags.js","./SoftwareUpdate/MiuraDeviceUpdate":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/build/SoftwareUpdate/MiuraDeviceUpdate.js","./common/Flow":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/build/common/Flow.js","manticore-log":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-log/index.js","retail-payment-device":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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;
    } else if (context.quickChipEnabled && context.invoice.total.equals(0)) {
      // SEND $1 to Start Quick Chip Txn
      amount = 1;
    }

    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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/build/ConnectionFlow.js","./MiuraTags":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/build/MiuraTags.js","./Terminal":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/build/Terminal.js","./cardMetadataParser":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/build/cardMetadataParser.js","./deviceState":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/build/deviceState.js","./messages/CardStatus":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/build/messages/CardStatus.js","./messages/TerminalStatus":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/build/messages/TerminalStatus.js","manticore-log":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-log/index.js","manticore-util":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-util/build/index.js","paypal-invoicing":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/index.js","retail-payment-device":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/index.js","tlvlib":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/tlvlib/build/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/tlvlib/build/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/buffer/index.js","events":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/events/events.js","manticore":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore/browser.js","manticore-log":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-log/index.js","retail-payment-device":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/index.js","tlvlib":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/tlvlib/build/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/build/common/Flow.js","../deviceState":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/build/deviceState.js","async":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/async/lib/async.js","buffer":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/buffer/index.js","manticore":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore/browser.js","manticore-log":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-log/index.js","md5":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/md5/md5.js","retail-payment-device":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/build/MiuraTags.js","./Parser":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/build/Parser.js","./TerminalConfig":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/build/TerminalConfig.js","./TerminalDisplay":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/build/TerminalDisplay.js","./Writer":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/build/Writer.js","./messages/BatteryStatus":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/build/messages/BatteryStatus.js","./messages/CardStatus":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/build/messages/CardStatus.js","./messages/KeyStatus":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/build/messages/KeyStatus.js","./messages/TerminalStatus":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/build/messages/TerminalStatus.js","buffer":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/buffer/index.js","events":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/events/events.js","manticore-log":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-log/index.js","retail-payment-device":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/index.js","tlvlib":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/tlvlib/build/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/build/MiuraTags.js","./Writer":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/build/Writer.js","./messages/DeviceCaps":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/build/messages/DeviceCaps.js","buffer":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/buffer/index.js","manticore-log":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-log/index.js","retail-payment-device":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/index.js","tlvlib":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/tlvlib/build/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/build/strings/m010/en.js","l10n-manticore":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/l10n-manticore/index.js","manticore-log":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-log/index.js","retail-payment-device":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/build/Parser.js","buffer":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/buffer/index.js","manticore":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore/browser.js","manticore-log":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-log/index.js","retail-payment-device":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/index.js","yaku":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/yaku/lib/yaku.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/build/MiuraTags.js","buffer":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/buffer/index.js","manticore-log":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-log/index.js","retail-payment-device":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/index.js","tlvlib":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/tlvlib/build/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/events/events.js","manticore-log":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-log/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/build/MiuraDevice.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/build/cardMetadataParser.js","manticore-log":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-log/index.js","manticore-util":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-util/build/index.js","retail-payment-device":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/build/MiuraTags.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/build/MiuraTags.js","manticore-log":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-log/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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: {
    RemoveCard: 'Remove Card',
    Processing: 'Processing...',
    Signature: 'Signature Required'
  },
  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'
  },
  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/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/AccountSummary.js","./lib/AccountSummarySection":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/AccountSummarySection.js","./lib/Address":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/Address.js","./lib/Attachment":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/Attachment.js","./lib/BaseClasses/BaseService":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/BaseClasses/BaseService.js","./lib/BillingInfo":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/BillingInfo.js","./lib/CCInfo":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/CCInfo.js","./lib/Countries":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/Countries.js","./lib/Country":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/Country.js","./lib/Currency":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/Currency.js","./lib/CustomAmount":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/CustomAmount.js","./lib/Invoice":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/Invoice.js","./lib/InvoiceActions":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/InvoiceActions.js","./lib/InvoiceBigNumber":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/InvoiceBigNumber.js","./lib/InvoiceEnums":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/InvoiceEnums.js","./lib/InvoiceListRequest":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/InvoiceListRequest.js","./lib/InvoiceListResponse":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/InvoiceListResponse.js","./lib/InvoicingFakeServer":false,"./lib/InvoicingService":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/InvoicingService.js","./lib/Item":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/Item.js","./lib/MerchantInfo":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/MerchantInfo.js","./lib/Notification":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/Notification.js","./lib/Payment":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/Payment.js","./lib/PaymentTerm":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/PaymentTerm.js","./lib/Refund":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/Refund.js","./lib/Requester":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/Requester.js","./lib/SearchRequest":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/SearchRequest.js","./lib/ShippingInfo":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/ShippingInfo.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/AccountSummarySection.js","./InvoiceBigNumber":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/InvoiceBigNumber.js","./InvoiceEnums":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/InvoiceEnums.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/Address.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/Address.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/Country.js","./CountryMap":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/CountryMap.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/InvoiceBigNumber.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/InvoiceBigNumber.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/Attachment.js","./BillingInfo":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/BillingInfo.js","./CCInfo":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/CCInfo.js","./Currency":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/Currency.js","./CustomAmount":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/CustomAmount.js","./InvoiceBigNumber":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/InvoiceBigNumber.js","./InvoiceEnums":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/InvoiceEnums.js","./InvoiceMetaData":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/InvoiceMetaData.js","./InvoicingUtil":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/InvoicingUtil.js","./Item":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/Item.js","./MerchantInfo":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/MerchantInfo.js","./Payment":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/Payment.js","./PaymentTerm":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/PaymentTerm.js","./Refund":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/Refund.js","./Requester":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/Requester.js","./ShippingInfo":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/ShippingInfo.js","./totalCalculator":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/totalCalculator.js","assert":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/assert/assert.js","deep-equal":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/deep-equal/index.js","events":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/events/events.js","manticore-log":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-log/index.js","manticore-util":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-util/build/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/InvoiceEnums.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/bignumber.js/bignumber.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-util/build/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/Invoice.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/InvoicingUtil.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/Template.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/AccountSummary.js","./BaseClasses/BaseService":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/BaseClasses/BaseService.js","./InvoiceListResponse":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/InvoiceListResponse.js","./InvoiceTemplatesResponse":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/InvoiceTemplatesResponse.js","./Requester":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/Requester.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/moment/moment.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/Currency.js","./InvoiceBigNumber":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/InvoiceBigNumber.js","./InvoicingUtil":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/InvoicingUtil.js","deep-equal":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/deep-equal/index.js","events":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/events/events.js","manticore-util":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-util/build/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/Address.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/InvoiceBigNumber.js","./InvoiceEnums":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/InvoiceEnums.js","./InvoicingUtil":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/InvoicingUtil.js","assert":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/assert/assert.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/InvoicingUtil.js","manticore-util":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-util/build/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/InvoiceBigNumber.js","./InvoiceEnums":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/InvoiceEnums.js","./InvoicingUtil":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/InvoicingUtil.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-util/build/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/InvoiceBigNumber.js","./InvoiceEnums":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/InvoiceEnums.js","./InvoicingUtil":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/InvoicingUtil.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/Address.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/Invoice.js","./TemplateSettings":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/TemplateSettings.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/assert/assert.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/Currency.js","./InvoiceBigNumber":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/InvoiceBigNumber.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/tlvlib/build/lib/DefinedTag.js","./lib/Tags":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/tlvlib/build/lib/Tags.js","./lib/Tlv":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/tlvlib/build/lib/Tlv.js","./lib/TlvList":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/tlvlib/build/lib/TlvList.js","./lib/ValueFormat":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/tlvlib/build/lib/ValueFormat.js","./lib/apdu/Command":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/tlvlib/build/lib/apdu/Command.js","./lib/apdu/Response":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/tlvlib/build/lib/apdu/Response.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/tlvlib/build/lib/ValueFormat.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/tlvlib/build/lib/DefinedTag.js","./ValueFormat":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/tlvlib/build/lib/ValueFormat.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/tlvlib/build/lib/DefinedTag.js","./ber":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/tlvlib/build/lib/ber.js","buffer":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/buffer/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/tlvlib/build/lib/DefinedTag.js","./Tlv":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/tlvlib/build/lib/Tlv.js","./ber":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/tlvlib/build/lib/ber.js","buffer":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/buffer/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/tlvlib/build/lib/TlvList.js","buffer":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/buffer/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/buffer/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/is-buffer/index.js","../TlvList":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/tlvlib/build/lib/TlvList.js","../ber":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/tlvlib/build/lib/ber.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/buffer/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/moment/moment.js":[function(require,module,exports){
//! moment.js

;(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 they want. 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,
        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 globalLocale;
    }

    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;
            }
            else {
                if ((typeof console !==  'undefined') && console.warn) {
                    //warn user if arguments are passed but the locale could not be set
                    console.warn('Locale ' + key +  ' not found. Did you forget to load it?');
                }
            }
        }

        return globalLocale._abbr;
    }

    function defineLocale (name, config) {
        if (config !== null) {
            var locale, 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 {
                    locale = loadLocale(config.parentLocale);
                    if (locale != null) {
                        parentConfig = locale._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,
            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.valueOf() + this.utcOffset() * 60 * 1000).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;
    proto.year       = getSetYear;
    proto.isLeapYear = getIsLeapYear;
    proto.weekYear    = getSetWeekYear;
    proto.isoWeekYear = getSetISOWeekYear;
    proto.quarter = proto.quarters = getSetQuarter;
    proto.month       = getSetMonth;
    proto.daysInMonth = getDaysInMonth;
    proto.week           = proto.weeks        = getSetWeek;
    proto.isoWeek        = proto.isoWeeks     = getSetISOWeek;
    proto.weeksInYear    = getWeeksInYear;
    proto.isoWeeksInYear = getISOWeeksInYear;
    proto.date       = getSetDayOfMonth;
    proto.day        = proto.days             = getSetDayOfWeek;
    proto.weekday    = getSetLocaleDayOfWeek;
    proto.isoWeekday = getSetISODayOfWeek;
    proto.dayOfYear  = getSetDayOfYear;
    proto.hour = proto.hours = getSetHour;
    proto.minute = proto.minutes = getSetMinute;
    proto.second = proto.seconds = getSetSecond;
    proto.millisecond = proto.milliseconds = getSetMillisecond;
    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;
    proto.zoneAbbr = getZoneAbbr;
    proto.zoneName = getZoneName;
    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;

    proto$1.months            =        localeMonths;
    proto$1.monthsShort       =        localeMonthsShort;
    proto$1.monthsParse       =        localeMonthsParse;
    proto$1.monthsRegex       = monthsRegex;
    proto$1.monthsShortRegex  = monthsShortRegex;
    proto$1.week = localeWeek;
    proto$1.firstDayOfYear = localeFirstDayOfYear;
    proto$1.firstDayOfWeek = localeFirstDayOfWeek;

    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;

    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;

    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.22.0';

    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/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypal-invoicing/build/lib/AccountSummary.js","./lib/AccountSummarySection":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypal-invoicing/build/lib/AccountSummarySection.js","./lib/Address":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypal-invoicing/build/lib/Address.js","./lib/Attachment":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypal-invoicing/build/lib/Attachment.js","./lib/BaseClasses/BaseService":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypal-invoicing/build/lib/BaseClasses/BaseService.js","./lib/BillingInfo":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypal-invoicing/build/lib/BillingInfo.js","./lib/CCInfo":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypal-invoicing/build/lib/CCInfo.js","./lib/Countries":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypal-invoicing/build/lib/Countries.js","./lib/Country":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypal-invoicing/build/lib/Country.js","./lib/Currency":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypal-invoicing/build/lib/Currency.js","./lib/CustomAmount":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypal-invoicing/build/lib/CustomAmount.js","./lib/Invoice":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypal-invoicing/build/lib/Invoice.js","./lib/InvoiceActions":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypal-invoicing/build/lib/InvoiceActions.js","./lib/InvoiceBigNumber":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypal-invoicing/build/lib/InvoiceBigNumber.js","./lib/InvoiceConstants":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypal-invoicing/build/lib/InvoiceConstants.js","./lib/InvoiceEnums":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypal-invoicing/build/lib/InvoiceEnums.js","./lib/InvoiceListRequest":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypal-invoicing/build/lib/InvoiceListRequest.js","./lib/InvoiceListResponse":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypal-invoicing/build/lib/InvoiceListResponse.js","./lib/InvoicingFakeServer":false,"./lib/InvoicingService":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypal-invoicing/build/lib/InvoicingService.js","./lib/Item":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypal-invoicing/build/lib/Item.js","./lib/MerchantInfo":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypal-invoicing/build/lib/MerchantInfo.js","./lib/Notification":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypal-invoicing/build/lib/Notification.js","./lib/Payment":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypal-invoicing/build/lib/Payment.js","./lib/PaymentTerm":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypal-invoicing/build/lib/PaymentTerm.js","./lib/Refund":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypal-invoicing/build/lib/Refund.js","./lib/Requester":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypal-invoicing/build/lib/Requester.js","./lib/SearchRequest":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypal-invoicing/build/lib/SearchRequest.js","./lib/ShippingInfo":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypal-invoicing/build/lib/ShippingInfo.js","./lib/Template":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypal-invoicing/build/lib/Template.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypal-invoicing/build/lib/AccountSummarySection.js","./InvoiceBigNumber":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypal-invoicing/build/lib/InvoiceBigNumber.js","./InvoiceEnums":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypal-invoicing/build/lib/InvoiceEnums.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypal-invoicing/build/lib/Address.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypal-invoicing/build/lib/Address.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypal-invoicing/build/lib/Country.js","./CountryMap":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypal-invoicing/build/lib/CountryMap.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypal-invoicing/build/lib/CountryMap.js":[function(require,module,exports){
arguments[4]["/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/paypal-invoicing/build/lib/CountryMap.js"][0].apply(exports,arguments)
},{}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypal-invoicing/build/lib/InvoiceBigNumber.js","./RoundingRules.js":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypal-invoicing/build/lib/RoundingRules.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypal-invoicing/build/lib/Currency.js","./InvoiceBigNumber":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypal-invoicing/build/lib/InvoiceBigNumber.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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 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, default to not sending update emails.
    if (this.payPalId) {
      this.update(false, false, callback);
      return;
    }
    if (!this.isDirtyFromServer) {
      if (callback) {
        callback();
      }
      return;
    }
    (0, _Requester.request)({
      method: 'POST',
      op: 'invoices',
      body: JSON.stringify(this)
    }, function (error, invoiceResponse) {
      if (!error && invoiceResponse.body) {
        _this4.readJSON(invoiceResponse.body, true);
        _this4.setCleanFromServer();
      }
      if (callback) {
        callback(error);
      }
    });
  };

  /**
   * Update the invoice on the PayPal servers.
   * @param {bool} shouldNotifyMerchant A flag indicating whether a
   *  copy of the notification has to be sent to the merchant
   * @param {bool} shouldNotifyCustomer A flag indicating whether a
   *  copy of the notification has to be sent to the customer
   * @param {Invoice~saved} callback Called with an error
   */


  Invoice.prototype.update = function update(shouldNotifyMerchant, shouldNotifyCustomer, callback) {
    var _this5 = 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.');
    (0, _assert2.default)(this.payPalId, 'Can\'t update an invoice that hasn\'t been saved');
    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: 'PUT',
      op: 'invoices/' + this.payPalId + '?notify_merchant=' + !!shouldNotifyMerchant + '&notify_customer=' + !!shouldNotifyCustomer,
      body: JSON.stringify(this)
    }, function (error, invoiceResponse) {
      if (!error && invoiceResponse.body) {
        _this5.readJSON(invoiceResponse.body, true);
        _this5.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 _this6 = 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) {
        _this6.status = _InvoiceEnums2.default.Status.SENT;
      }
      if (callback) {
        callback(error, response);
      }
      // this will allow getIsPastDue to return correct result before refresh
      if (_this6.paymentTerms.paymentTerms === _PaymentTerm2.default.PaymentTerms.DueOnReceipt) {
        _this6.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 _this7 = 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) {
        _this7.status = _InvoiceEnums2.default.Status.NEW;
        _this7.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 _this8 = 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) {
        _this8.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 _this9 = 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 (!_this9.allowPartialPayment || paymentInfo.amount && _this9.equiv(_this9.remainingAmount, paymentInfo.amount)) {
            _this9.status = _InvoiceEnums2.default.Status.MARKED_AS_PAID;
          } else {
            _this9.status = _InvoiceEnums2.default.Status.PARTIALLY_PAID;
          }
        } else if (paymentInfo.type === _InvoiceEnums2.default.PaymentType.PAYPAL) {
          _this9.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 _this10 = 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) {
        _this10.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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypal-invoicing/build/lib/Attachment.js","./BillingInfo":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypal-invoicing/build/lib/BillingInfo.js","./CCInfo":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypal-invoicing/build/lib/CCInfo.js","./Currency":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypal-invoicing/build/lib/Currency.js","./CustomAmount":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypal-invoicing/build/lib/CustomAmount.js","./InvoiceBigNumber":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypal-invoicing/build/lib/InvoiceBigNumber.js","./InvoiceCalculator":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypal-invoicing/build/lib/InvoiceCalculator.js","./InvoiceEnums":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypal-invoicing/build/lib/InvoiceEnums.js","./InvoiceMetaData":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypal-invoicing/build/lib/InvoiceMetaData.js","./InvoicingService":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypal-invoicing/build/lib/InvoicingService.js","./InvoicingUtil":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypal-invoicing/build/lib/InvoicingUtil.js","./Item":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypal-invoicing/build/lib/Item.js","./MerchantInfo":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypal-invoicing/build/lib/MerchantInfo.js","./Payment":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypal-invoicing/build/lib/Payment.js","./PaymentTerm":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypal-invoicing/build/lib/PaymentTerm.js","./Refund":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypal-invoicing/build/lib/Refund.js","./Requester":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypal-invoicing/build/lib/Requester.js","./ShippingInfo":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypal-invoicing/build/lib/ShippingInfo.js","assert":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/assert/assert.js","deep-equal":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/deep-equal/index.js","events":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/events/events.js","manticore-log":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-log/index.js","manticore-util":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-util/build/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypal-invoicing/build/lib/InvoiceCalculator.js","./InvoiceEnums":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypal-invoicing/build/lib/InvoiceEnums.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/bignumber.js/bignumber.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypal-invoicing/build/lib/Currency.js","./InvoiceBigNumber":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypal-invoicing/build/lib/InvoiceBigNumber.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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(10000);
  };

  /**
  * The minimum quantity allowed to specify on an invoice, inclusive. 
  * @method
  * @returns {decimal}
  */


  InvoiceConstants.itemQuantityMin = function itemQuantityMin() {
    return new _bignumber2.default(-10000);
  };

  /**
  * 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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/bignumber.js/bignumber.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-util/build/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypal-invoicing/build/lib/Invoice.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypal-invoicing/build/lib/InvoicingUtil.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypal-invoicing/build/lib/Template.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypal-invoicing/build/lib/AccountSummary.js","./Attachment":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypal-invoicing/build/lib/Attachment.js","./BaseClasses/BaseService":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypal-invoicing/build/lib/BaseClasses/BaseService.js","./Invoice":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypal-invoicing/build/lib/Invoice.js","./InvoiceListResponse":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypal-invoicing/build/lib/InvoiceListResponse.js","./InvoiceTemplatesResponse":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypal-invoicing/build/lib/InvoiceTemplatesResponse.js","./InvoicingUtil":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypal-invoicing/build/lib/InvoicingUtil.js","./Requester":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypal-invoicing/build/lib/Requester.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypal-invoicing/build/lib/InvoiceEnums.js","manticore":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore/browser.js","moment":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypal-invoicing/node_modules/moment/moment.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypal-invoicing/build/lib/Currency.js","./InvoiceBigNumber":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypal-invoicing/build/lib/InvoiceBigNumber.js","./InvoiceConstants":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypal-invoicing/build/lib/InvoiceConstants.js","./InvoicingUtil":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypal-invoicing/build/lib/InvoicingUtil.js","deep-equal":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/deep-equal/index.js","events":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/events/events.js","manticore-util":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-util/build/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypal-invoicing/build/lib/Address.js","manticore-log":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-log/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypal-invoicing/build/lib/Currency.js","./InvoiceBigNumber":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypal-invoicing/build/lib/InvoiceBigNumber.js","./InvoiceEnums":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypal-invoicing/build/lib/InvoiceEnums.js","./InvoicingUtil":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypal-invoicing/build/lib/InvoicingUtil.js","assert":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/assert/assert.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypal-invoicing/build/lib/InvoicingUtil.js","manticore-util":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-util/build/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypal-invoicing/build/lib/Currency.js","./InvoiceBigNumber":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypal-invoicing/build/lib/InvoiceBigNumber.js","./InvoiceEnums":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypal-invoicing/build/lib/InvoiceEnums.js","./InvoicingUtil":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypal-invoicing/build/lib/InvoicingUtil.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-util/build/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypal-invoicing/build/lib/InvoiceBigNumber.js","./InvoiceEnums":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypal-invoicing/build/lib/InvoiceEnums.js","./InvoicingUtil":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypal-invoicing/build/lib/InvoicingUtil.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypal-invoicing/build/lib/Address.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypal-invoicing/build/lib/Invoice.js","./PaymentTerm.js":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypal-invoicing/build/lib/PaymentTerm.js","./TemplateSettings":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypal-invoicing/build/lib/TemplateSettings.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/assert/assert.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypalrest-manticore/build/src/PayPalREST.js","./src/restError":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypalrest-manticore/build/src/restError.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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) {
          if (!error.domain) {
            error.domain = _restError.paypalRestErrorDomain;
          }
          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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/paypalrest-manticore/build/src/restError.js","buffer":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/buffer/index.js","manticore":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore/browser.js","manticore-log":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-log/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-paypalerror/build/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/qs/lib/formats.js","./utils":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/qs/lib/utils.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-page-tracker/build/src/Page.js","./src/Tracker":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-page-tracker/build/src/Tracker.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/events/events.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/CardIssuer.js","manticore-log":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-log/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/BatteryInfo.js","./CardIssuer":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/CardIssuer.js","./DeviceUpdate":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/DeviceUpdate.js","./FormFactor":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/FormFactor.js","./Messages/AvailableApplications":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/Messages/AvailableApplications.js","./Messages/Card":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/Messages/Card.js","./Messages/CardPresentEvent":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/Messages/CardPresentEvent.js","./Messages/PinEvent":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/Messages/PinEvent.js","./NumericEntryOptions":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/NumericEntryOptions.js","./NumericEntryType":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/NumericEntryType.js","./SecureEntryOptions":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/SecureEntryOptions.js","./TransactionType":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/TransactionType.js","./appMessage":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/appMessage.js","events":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/events/events.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/PaymentDevice.js","./appMessage":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/appMessage.js","./deviceState":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/deviceState.js","./paymentDeviceError":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/paymentDeviceError.js","events":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/events/events.js","manticore":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore/browser.js","manticore-log":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-log/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/FormFactor.js","./Messages/Card":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/Messages/Card.js","manticore-log":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-log/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/FormFactor.js","./PaymentDevice":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/PaymentDevice.js","manticore-log":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-log/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/FormFactor.js","./Messages/Card":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/Messages/Card.js","./cardError":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/cardError.js","manticore-log":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-log/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/FormFactor.js","moment":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/moment/moment.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/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',
  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',
  SignatureForTap: 'Signature.Tap',
  SignatureForNonEmv: 'Signature.NonEmv',
  InvoiceTotal: 'InvoiceTotal',
  AmountTooLow: 'AmountTooLow',
  AmountTooLowRemoveCard: 'AmountTooLowRemoveCard',
  AmountTooHigh: 'AmountTooHigh',
  AmountTooHighRemoveCard: 'AmountTooHighRemoveCard',
  CompletingPayment: 'CompletingPayment',
  RequestTip: 'RequestTip',
  ConfirmTip: 'ConfirmTip',
  QuickChip: {
    RemoveCard: 'QuickChip.RemoveCard',
    Processing: 'QuickChip.Processing',
    Signature: 'QuickChip.Signature'
  }
};

PaymentDevice.ConnectionTimeOut = msDefaultMaxConnectionDuration;
},{"./CardReader":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/CardReader.js","./FormFactor":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/FormFactor.js","./Messages/DeviceStatus":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/Messages/DeviceStatus.js","./ReaderModel":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/ReaderModel.js","./deviceState":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/deviceState.js","./paymentDeviceError":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/paymentDeviceError.js","./readerInformation":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/readerInformation.js","events":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/events/events.js","manticore":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore/browser.js","manticore-log":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-log/index.js","manticore-util":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-util/build/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/ManuallyEnteredCard.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/paymentDeviceError.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/BatteryInfo.js","./CardDataUtil":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/CardDataUtil.js","./CardInsertedHandler":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/CardInsertedHandler.js","./CardIssuer":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/CardIssuer.js","./CardReader":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/CardReader.js","./CardStatus":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/CardStatus.js","./DeviceUpdate":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/DeviceUpdate.js","./FormFactor":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/FormFactor.js","./MagneticCard":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/MagneticCard.js","./MagneticReaderDevice":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/MagneticReaderDevice.js","./ManuallyEnteredCard":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/ManuallyEnteredCard.js","./Messages/AvailableApplications":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/Messages/AvailableApplications.js","./Messages/Card":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/Messages/Card.js","./Messages/CardPresentEvent":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/Messages/CardPresentEvent.js","./Messages/CardReaderResponse":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/Messages/CardReaderResponse.js","./Messages/DeviceStatus":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/Messages/DeviceStatus.js","./Messages/PinEvent":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/Messages/PinEvent.js","./NumericEntryOptions":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/NumericEntryOptions.js","./NumericEntryType":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/NumericEntryType.js","./PaymentDevice":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/PaymentDevice.js","./ReaderModel":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/ReaderModel.js","./SecureEntryOptions":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/SecureEntryOptions.js","./TransactionType":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/TransactionType.js","./appMessage":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/appMessage.js","./batteryStatus":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/batteryStatus.js","./cardError":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/cardError.js","./deviceCapabilityType":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/deviceCapabilityType.js","./deviceManufacturer":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/deviceManufacturer.js","./paymentDeviceError":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/paymentDeviceError.js","./readerInformation":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/retail-payment-device/build/readerInformation.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/manticore-paypalerror/build/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/tlvlib/build/lib/DefinedTag.js","./lib/Tags":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/tlvlib/build/lib/Tags.js","./lib/Tlv":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/tlvlib/build/lib/Tlv.js","./lib/TlvList":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/tlvlib/build/lib/TlvList.js","./lib/ValueFormat":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/tlvlib/build/lib/ValueFormat.js","./lib/apdu/Command":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/tlvlib/build/lib/apdu/Command.js","./lib/apdu/Response":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/tlvlib/build/lib/apdu/Response.js","./lib/ber":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/tlvlib/build/lib/ber.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/tlvlib/build/lib/DefinedTag.js":[function(require,module,exports){
arguments[4]["/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/tlvlib/build/lib/DefinedTag.js"][0].apply(exports,arguments)
},{"./ValueFormat":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/tlvlib/build/lib/ValueFormat.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/tlvlib/build/lib/Tags.js":[function(require,module,exports){
arguments[4]["/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/tlvlib/build/lib/Tags.js"][0].apply(exports,arguments)
},{"./DefinedTag":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/tlvlib/build/lib/DefinedTag.js","./ValueFormat":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/tlvlib/build/lib/ValueFormat.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/tlvlib/build/lib/Tlv.js":[function(require,module,exports){
arguments[4]["/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/tlvlib/build/lib/Tlv.js"][0].apply(exports,arguments)
},{"./DefinedTag":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/tlvlib/build/lib/DefinedTag.js","./ber":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/tlvlib/build/lib/ber.js","buffer":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/buffer/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/tlvlib/build/lib/DefinedTag.js","./Tlv":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/tlvlib/build/lib/Tlv.js","./ber":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/tlvlib/build/lib/ber.js","buffer":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/buffer/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/tlvlib/build/lib/ValueFormat.js":[function(require,module,exports){
arguments[4]["/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/tlvlib/build/lib/ValueFormat.js"][0].apply(exports,arguments)
},{"./TlvList":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/tlvlib/build/lib/TlvList.js","buffer":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/buffer/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/buffer/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/is-buffer/index.js","../TlvList":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/tlvlib/build/lib/TlvList.js","../ber":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/tlvlib/build/lib/ber.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/tlvlib/build/lib/ber.js":[function(require,module,exports){
arguments[4]["/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/miura-emv/node_modules/tlvlib/build/lib/ber.js"][0].apply(exports,arguments)
},{"buffer":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/buffer/index.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/util/support/isBufferBrowser.js","_process":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/process/browser.js","inherits":"/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/node_modules/util/node_modules/inherits/inherits_browser.js"}],"/Users/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/package.json":[function(require,module,exports){
module.exports={
  "name": "retail-sdk",
  "version": "2.0.1",
  "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.2",
    "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.2.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/muozdemir/Documents/SandBox/RetailSDK/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/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/debug.js","/Users/muozdemir/Documents/SandBox/RetailSDK/retail-sdk/js/index.js"]);
